Page MenuHomeFreeBSD

No OneTemporary

This file is larger than 256 KB, so syntax highlighting was skipped.
diff --git a/crypto/openssh/.depend b/crypto/openssh/.depend
index fca83a67c970..5226523aa2ad 100644
--- a/crypto/openssh/.depend
+++ b/crypto/openssh/.depend
@@ -1,183 +1,179 @@
# Automatically generated by makedepend.
# Run "make depend" to rebuild.
# DO NOT DELETE
addr.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h addr.h
addrmatch.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h addr.h match.h log.h ssherr.h
atomicio.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h atomicio.h
audit-bsm.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
audit-linux.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
audit.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
auth-bsdauth.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
auth-krb5.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h ssh.h packet.h openbsd-compat/sys-queue.h dispatch.h log.h ssherr.h sshbuf.h sshkey.h misc.h servconf.h uidswap.h hostfile.h auth.h auth-pam.h audit.h loginrec.h
auth-options.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/sys-queue.h xmalloc.h ssherr.h log.h sshbuf.h misc.h sshkey.h match.h ssh2.h auth-options.h
auth-pam.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
auth-passwd.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h packet.h openbsd-compat/sys-queue.h dispatch.h sshbuf.h ssherr.h log.h misc.h servconf.h sshkey.h hostfile.h auth.h auth-pam.h audit.h loginrec.h auth-options.h
auth-rhosts.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h packet.h openbsd-compat/sys-queue.h dispatch.h uidswap.h pathnames.h log.h ssherr.h misc.h xmalloc.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-pubkeyfile.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-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 log.h ssherr.h misc.h compat.h sshkey.h digest.h hostfile.h auth.h auth-pam.h audit.h loginrec.h auth-options.h authfile.h match.h
auth2.o: digest.h
auth2.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h atomicio.h xmalloc.h ssh2.h packet.h openbsd-compat/sys-queue.h dispatch.h log.h ssherr.h sshbuf.h misc.h servconf.h compat.h sshkey.h hostfile.h auth.h auth-pam.h audit.h loginrec.h pathnames.h monitor_wrap.h
authfd.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h ssh.h sshbuf.h sshkey.h authfd.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h compat.h log.h ssherr.h atomicio.h misc.h
authfile.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h ssh.h log.h ssherr.h authfile.h misc.h atomicio.h sshkey.h sshbuf.h krl.h
bitmap.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h bitmap.h
canohost.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h packet.h openbsd-compat/sys-queue.h dispatch.h log.h ssherr.h canohost.h misc.h
chacha.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h chacha.h
channels.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/sys-queue.h xmalloc.h ssh.h ssh2.h ssherr.h sshbuf.h packet.h dispatch.h log.h misc.h channels.h compat.h canohost.h sshkey.h authfd.h pathnames.h match.h
cipher-aes.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/openssl-compat.h
cipher-aesctr.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h cipher-aesctr.h rijndael.h
cipher-chachapoly-libcrypto.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
cipher-chachapoly.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h ssherr.h sshbuf.h cipher-chachapoly.h chacha.h poly1305.h
cipher.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-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
+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
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 misc.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
misc.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h misc.h log.h ssherr.h ssh.h sshbuf.h
moduli.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
monitor.o: chacha.h poly1305.h cipher-aesctr.h rijndael.h kex.h mac.h crypto_api.h dh.h packet.h dispatch.h auth-options.h sshpty.h channels.h session.h sshlogin.h canohost.h log.h ssherr.h misc.h servconf.h monitor.h monitor_wrap.h monitor_fdpass.h compat.h ssh2.h authfd.h match.h sk-api.h
monitor.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ./openbsd-compat/sys-tree.h openbsd-compat/sys-queue.h openbsd-compat/openssl-compat.h atomicio.h xmalloc.h ssh.h sshkey.h sshbuf.h hostfile.h auth.h auth-pam.h audit.h loginrec.h cipher.h cipher-chachapoly.h
monitor_fdpass.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h ssherr.h monitor_fdpass.h
monitor_wrap.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/sys-queue.h xmalloc.h ssh.h sshbuf.h sshkey.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h kex.h mac.h crypto_api.h hostfile.h auth.h auth-pam.h audit.h
monitor_wrap.o: loginrec.h auth-options.h packet.h dispatch.h log.h ssherr.h monitor.h monitor_wrap.h atomicio.h monitor_fdpass.h misc.h channels.h session.h servconf.h
msg.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h sshbuf.h ssherr.h log.h atomicio.h msg.h misc.h
mux.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/sys-queue.h xmalloc.h log.h ssherr.h ssh.h ssh2.h pathnames.h misc.h match.h sshbuf.h channels.h msg.h packet.h dispatch.h monitor_fdpass.h sshpty.h sshkey.h readconf.h clientloop.h
nchan.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/sys-queue.h ssh2.h sshbuf.h ssherr.h packet.h dispatch.h channels.h compat.h log.h
packet.o: channels.h ssh.h packet.h dispatch.h sshbuf.h
packet.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/sys-queue.h xmalloc.h compat.h ssh2.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h sshkey.h kex.h mac.h crypto_api.h digest.h log.h ssherr.h canohost.h misc.h
platform-misc.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
platform-pledge.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
platform-tracing.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h ssherr.h
platform.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h ssherr.h misc.h servconf.h openbsd-compat/sys-queue.h sshkey.h hostfile.h auth.h auth-pam.h audit.h loginrec.h
poly1305.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h poly1305.h
progressmeter.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h progressmeter.h atomicio.h misc.h utf8.h
readconf.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/glob.h xmalloc.h ssh.h ssherr.h compat.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h pathnames.h log.h sshkey.h misc.h readconf.h match.h kex.h mac.h crypto_api.h
readconf.o: uidswap.h myproposal.h digest.h
readpass.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h misc.h pathnames.h log.h ssherr.h ssh.h uidswap.h
rijndael.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h rijndael.h
sandbox-capsicum.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
sandbox-darwin.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
sandbox-null.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
sandbox-pledge.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
sandbox-rlimit.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
sandbox-seccomp-filter.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
sandbox-solaris.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
sandbox-systrace.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
-sc25519.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h sc25519.h crypto_api.h
scp.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/glob.h xmalloc.h ssh.h atomicio.h pathnames.h log.h ssherr.h misc.h progressmeter.h utf8.h sftp.h sftp-common.h sftp-client.h
servconf.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/glob.h openbsd-compat/sys-queue.h xmalloc.h ssh.h log.h ssherr.h sshbuf.h misc.h servconf.h compat.h pathnames.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h sshkey.h
servconf.o: kex.h mac.h crypto_api.h match.h channels.h groupaccess.h canohost.h packet.h dispatch.h hostfile.h auth.h auth-pam.h audit.h loginrec.h myproposal.h digest.h
serverloop.o: cipher-aesctr.h rijndael.h kex.h mac.h crypto_api.h hostfile.h auth.h auth-pam.h audit.h loginrec.h session.h auth-options.h serverloop.h
serverloop.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/sys-queue.h xmalloc.h packet.h dispatch.h sshbuf.h log.h ssherr.h misc.h servconf.h canohost.h sshpty.h channels.h compat.h ssh2.h sshkey.h cipher.h cipher-chachapoly.h chacha.h poly1305.h
session.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/sys-queue.h xmalloc.h ssh.h ssh2.h sshpty.h packet.h dispatch.h sshbuf.h ssherr.h match.h uidswap.h compat.h channels.h sshkey.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h
session.o: rijndael.h hostfile.h auth.h auth-pam.h audit.h loginrec.h auth-options.h authfd.h pathnames.h log.h misc.h servconf.h sshlogin.h serverloop.h canohost.h session.h kex.h mac.h crypto_api.h monitor_wrap.h sftp.h atomicio.h
sftp-client.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/sys-queue.h xmalloc.h ssherr.h sshbuf.h log.h atomicio.h progressmeter.h misc.h utf8.h sftp.h sftp-common.h sftp-client.h openbsd-compat/glob.h
sftp-common.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h ssherr.h sshbuf.h log.h misc.h sftp.h sftp-common.h
sftp-glob.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h sftp.h sftp-common.h sftp-client.h openbsd-compat/glob.h
sftp-realpath.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
sftp-server-main.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h ssherr.h sftp.h misc.h xmalloc.h
sftp-server.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h atomicio.h xmalloc.h sshbuf.h ssherr.h log.h misc.h match.h uidswap.h sftp.h sftp-common.h
sftp-usergroup.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-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 log.h ssherr.h xmalloc.h sftp-common.h sftp-client.h openbsd-compat/glob.h sftp-usergroup.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 sftp-usergroup.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 hostfile.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 myproposal.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-keyscan.o: ssherr.h atomicio.h misc.h hostfile.h ssh_api.h ssh2.h dns.h addr.h
ssh-keysign.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h log.h ssherr.h sshkey.h ssh.h ssh2.h misc.h sshbuf.h authfile.h msg.h canohost.h pathnames.h readconf.h uidswap.h
ssh-pkcs11-client.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
ssh-pkcs11-helper.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/sys-queue.h xmalloc.h sshbuf.h log.h ssherr.h misc.h sshkey.h authfd.h ssh-pkcs11.h
ssh-pkcs11.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h ssherr.h sshkey.h
ssh-rsa.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
ssh-sk-client.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h ssherr.h sshbuf.h sshkey.h msg.h digest.h pathnames.h ssh-sk.h misc.h
ssh-sk-helper.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h log.h ssherr.h sshkey.h authfd.h misc.h sshbuf.h msg.h uidswap.h ssh-sk.h
ssh-sk.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
ssh-xmss.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
ssh.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/openssl-compat.h openbsd-compat/sys-queue.h xmalloc.h ssh.h ssh2.h canohost.h compat.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h packet.h dispatch.h sshbuf.h channels.h
ssh.o: sshkey.h authfd.h authfile.h pathnames.h clientloop.h log.h ssherr.h misc.h readconf.h sshconnect.h kex.h mac.h crypto_api.h sshpty.h match.h msg.h version.h myproposal.h utf8.h
ssh_api.o: authfile.h misc.h version.h myproposal.h sshbuf.h openbsd-compat/openssl-compat.h
ssh_api.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ssh_api.h openbsd-compat/sys-queue.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h sshkey.h kex.h mac.h crypto_api.h ssh.h ssh2.h packet.h dispatch.h compat.h log.h ssherr.h
sshbuf-getput-basic.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ssherr.h sshbuf.h
sshbuf-getput-crypto.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
sshbuf-io.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ssherr.h sshbuf.h atomicio.h
sshbuf-misc.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ssherr.h sshbuf.h
sshbuf.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ssherr.h sshbuf.h misc.h
sshconnect.o: authfd.h kex.h mac.h crypto_api.h
sshconnect.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h hostfile.h ssh.h sshbuf.h packet.h openbsd-compat/sys-queue.h dispatch.h compat.h sshkey.h sshconnect.h log.h ssherr.h misc.h readconf.h atomicio.h dns.h monitor_fdpass.h ssh2.h version.h authfile.h
sshconnect2.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/sys-queue.h xmalloc.h ssh.h ssh2.h sshbuf.h packet.h dispatch.h compat.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h sshkey.h kex.h mac.h crypto_api.h
sshconnect2.o: myproposal.h sshconnect.h authfile.h dh.h authfd.h log.h ssherr.h misc.h readconf.h match.h canohost.h msg.h pathnames.h uidswap.h hostfile.h utf8.h ssh-sk.h sk-api.h
sshd.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ./openbsd-compat/sys-tree.h openbsd-compat/sys-queue.h xmalloc.h ssh.h ssh2.h sshpty.h packet.h dispatch.h log.h ssherr.h sshbuf.h misc.h match.h servconf.h uidswap.h compat.h cipher.h cipher-chachapoly.h chacha.h
sshd.o: poly1305.h cipher-aesctr.h rijndael.h digest.h sshkey.h kex.h mac.h crypto_api.h myproposal.h authfile.h pathnames.h atomicio.h canohost.h hostfile.h auth.h auth-pam.h audit.h loginrec.h authfd.h msg.h channels.h session.h monitor.h monitor_wrap.h ssh-sandbox.h auth-options.h version.h sk-api.h srclimit.h dh.h
ssherr.o: ssherr.h
sshkey-xmss.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
sshkey.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h crypto_api.h ssh2.h ssherr.h misc.h sshbuf.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h digest.h sshkey.h match.h ssh-sk.h openbsd-compat/openssl-compat.h
sshlogin.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h sshlogin.h ssherr.h loginrec.h log.h sshbuf.h misc.h servconf.h openbsd-compat/sys-queue.h
sshpty.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h sshpty.h log.h ssherr.h misc.h
sshsig.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h authfd.h authfile.h log.h ssherr.h misc.h sshbuf.h sshsig.h sshkey.h match.h digest.h
sshtty.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h sshpty.h
ttymodes.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h packet.h openbsd-compat/sys-queue.h dispatch.h log.h ssherr.h compat.h sshbuf.h ttymodes.h
uidswap.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h ssherr.h uidswap.h xmalloc.h
umac.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h umac.h misc.h rijndael.h
umac128.o: umac.c includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h umac.h misc.h rijndael.h
utf8.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h utf8.h
-verify.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h crypto_api.h
xmalloc.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h log.h ssherr.h
xmss_commons.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
xmss_fast.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
xmss_hash.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
xmss_hash_address.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
xmss_wots.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
diff --git a/crypto/openssh/.github/ci-status.md b/crypto/openssh/.github/ci-status.md
index 0ad8bf5aaf44..d13bbfa8c038 100644
--- a/crypto/openssh/.github/ci-status.md
+++ b/crypto/openssh/.github/ci-status.md
@@ -1,4 +1,10 @@
-[![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)
+master :
+[![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?query=branch:master)
+[![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?query=branch:master)
+[![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?query=branch:master)
+[![CIFuzz](https://github.com/openssh/openssh-portable/actions/workflows/cifuzz.yml/badge.svg)](https://github.com/openssh/openssh-portable/actions/workflows/cifuzz.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)
+
+9.1 :
+[![C/C++ CI](https://github.com/openssh/openssh-portable/actions/workflows/c-cpp.yml/badge.svg?branch=V_9_1)](https://github.com/openssh/openssh-portable/actions/workflows/c-cpp.yml?query=branch:V_9_1)
+[![C/C++ CI self-hosted](https://github.com/openssh/openssh-portable-selfhosted/actions/workflows/selfhosted.yml/badge.svg?branch=V_9_1)](https://github.com/openssh/openssh-portable-selfhosted/actions/workflows/selfhosted.yml?query=branch:V_9_1)
diff --git a/crypto/openssh/.github/configs b/crypto/openssh/.github/configs
index 6bf1ab27f0ca..bdd5ddbdfaf0 100755
--- a/crypto/openssh/.github/configs
+++ b/crypto/openssh/.github/configs
@@ -1,290 +1,313 @@
#!/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
+if [ "$config" = "" ]; then
+ config="default"
+fi
unset CC CFLAGS CPPFLAGS LDFLAGS LTESTS SUDO
-TEST_TARGET="tests"
+TEST_TARGET="tests compat-tests"
LTESTS=""
SKIP_LTESTS=""
SUDO=sudo # run with sudo by default
TEST_SSH_UNSAFE_PERMISSIONS=1
# Stop on first test failure to minimize logs
TEST_SSH_FAIL_FATAL=yes
CONFIGFLAGS=""
LIBCRYPTOFLAGS=""
case "$config" in
default|sol64)
;;
c89)
CC="gcc"
CFLAGS="-Wall -std=c89 -pedantic -Werror=vla"
CONFIGFLAGS="--without-zlib"
LIBCRYPTOFLAGS="--without-openssl"
TEST_TARGET=t-exec
;;
cygwin-release)
# See https://cygwin.com/git/?p=git/cygwin-packages/openssh.git;a=blob;f=openssh.cygport;hb=HEAD
CONFIGFLAGS="--with-xauth=/usr/bin/xauth --with-security-key-builtin"
CONFIGFLAGS="$CONFIGFLAGS --with-kerberos5=/usr --with-libedit --disable-strip"
;;
clang-12-Werror)
CC="clang-12"
# clang's implicit-fallthrough requires that the code be annotated with
# __attribute__((fallthrough)) and does not understand /* FALLTHROUGH */
CFLAGS="-Wall -Wextra -O2 -Wno-error=implicit-fallthrough -Wno-error=unused-parameter"
CONFIGFLAGS="--with-pam --with-Werror"
;;
*-sanitize-*)
case "$config" in
gcc-*)
CC=gcc
;;
clang-*)
# Find the newest available version of clang
for i in `seq 10 99`; do
clang="`which clang-$i 2>/dev/null`"
[ -x "$clang" ] && CC="$clang"
done
;;
esac
# Put Sanitizer logs in regress dir.
SANLOGS=`pwd`/regress
# - We replace chroot with chdir so that the sanitizer in the preauth
# privsep process can read /proc.
# - clang does not recognizes explicit_bzero so we use bzero
# (see https://github.com/google/sanitizers/issues/1507
# - openssl and zlib trip ASAN.
# - sp_pwdp returned by getspnam trips ASAN, hence disabling shadow.
case "$config" in
*-sanitize-address)
CFLAGS="-fsanitize=address -fno-omit-frame-pointer"
LDFLAGS="-fsanitize=address"
CPPFLAGS='-Dchroot=chdir -Dexplicit_bzero=bzero -D_FORTIFY_SOURCE=0 -DASAN_OPTIONS=\"detect_leaks=0:log_path='$SANLOGS'/asan.log\"'
CONFIGFLAGS=""
TEST_TARGET="t-exec"
;;
clang-sanitize-memory)
CFLAGS="-fsanitize=memory -fsanitize-memory-track-origins -fno-omit-frame-pointer"
LDFLAGS="-fsanitize=memory"
CPPFLAGS='-Dchroot=chdir -Dexplicit_bzero=bzero -DMSAN_OPTIONS=\"log_path='$SANLOGS'/msan.log\"'
CONFIGFLAGS="--without-openssl --without-zlib --without-shadow"
TEST_TARGET="t-exec"
;;
*-sanitize-undefined)
CFLAGS="-fsanitize=undefined"
LDFLAGS="-fsanitize=undefined"
;;
*)
echo unknown sanitize option;
exit 1;;
esac
features="--disable-security-key --disable-pkcs11"
hardening="--without-sandbox --without-hardening --without-stackprotect"
privsep="--with-privsep-user=root"
CONFIGFLAGS="$CONFIGFLAGS $features $hardening $privsep"
# Because we hobble chroot we can't test it.
SKIP_LTESTS=sftp-chroot
;;
gcc-11-Werror)
CC="gcc"
# -Wnoformat-truncation in gcc 7.3.1 20180130 fails on fmt_scaled
CFLAGS="-Wall -Wextra -O2 -Wno-format-truncation -Wimplicit-fallthrough=4 -Wno-unused-parameter"
CONFIGFLAGS="--with-pam --with-Werror"
;;
clang*|gcc*)
CC="$config"
;;
kitchensink)
CONFIGFLAGS="--with-kerberos5 --with-libedit --with-pam"
CONFIGFLAGS="${CONFIGFLAGS} --with-security-key-builtin --with-selinux"
- CONFIGFLAGS="${CONFIGFLAGS} --with-cflags=-DSK_DEBUG"
+ CFLAGS="-DSK_DEBUG -DSANDBOX_SECCOMP_FILTER_DEBUG"
;;
hardenedmalloc)
CONFIGFLAGS="--with-ldflags=-lhardened_malloc"
;;
tcmalloc)
CONFIGFLAGS="--with-ldflags=-ltcmalloc"
;;
krb5|heimdal)
CONFIGFLAGS="--with-kerberos5"
;;
libedit)
CONFIGFLAGS="--with-libedit"
;;
musl)
CC="musl-gcc"
CONFIGFLAGS="--without-zlib"
LIBCRYPTOFLAGS="--without-openssl"
TEST_TARGET="t-exec"
;;
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,"
+ # OpenSSL 1.1.1 specifically has a bug in its RNG that breaks reexec
+ # fallback. See https://bugzilla.mindrot.org/show_bug.cgi?id=3483
+ if [ "$config" = "openssl-1.1.1" ]; then
+ SKIP_LTESTS="reexec"
+ fi
;;
selinux)
CONFIGFLAGS="--with-selinux"
;;
sk)
CONFIGFLAGS="--with-security-key-builtin"
;;
without-openssl)
LIBCRYPTOFLAGS="--without-openssl"
TEST_TARGET=t-exec
;;
- valgrind-[1-4]|valgrind-unit)
+ valgrind-[1-5]|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 try-ciphers"
+ # by github so split into separate tests.
+ tests2="integrity try-ciphers"
tests3="krl forward-control sshsig agent-restrict kextype sftp"
tests4="cert-userkey cert-hostkey kextype sftp-perm keygen-comment percent"
+ tests5="rekey"
case "$config" in
valgrind-1)
- # All tests except agent-timeout (which is flaky under valgrind)
+ # All tests except agent-timeout (which is flaky under valgrind),
+ # connection-timeout (which doesn't work since it's so slow)
# and hostbased (since valgrind won't let ssh exec keysign).
# Slow ones are run separately to increase parallelism.
- SKIP_LTESTS="agent-timeout hostbased ${tests2} ${tests3} ${tests4}"
+ SKIP_LTESTS="agent-timeout connection-timeout hostbased"
+ SKIP_LTESTS="$SKIP_LTESTS ${tests2} ${tests3} ${tests4} ${tests5}"
;;
valgrind-2)
LTESTS="${tests2}"
;;
valgrind-3)
LTESTS="${tests3}"
;;
valgrind-4)
LTESTS="${tests4}"
;;
+ valgrind-5)
+ LTESTS="${tests5}"
+ ;;
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
aix*)
# These are slow real or virtual machines so skip the slowest tests
# (which tend to be thw ones that transfer lots of data) so that the
# test run does not time out.
# The agent-restrict test fails due to some quoting issue when run
# with sh or ksh so specify bash for now.
TEST_TARGET="t-exec TEST_SHELL=bash"
SKIP_LTESTS="rekey sftp"
;;
+ debian-riscv64)
+ # This machine is fairly slow, so skip the unit tests.
+ TEST_TARGET="t-exec"
+ ;;
dfly58*|dfly60*)
# scp 3-way connection hangs on these so skip until sorted.
SKIP_LTESTS=scp3
;;
fbsd6)
# Native linker is not great with PIC so OpenSSL is built w/out.
CONFIGFLAGS="${CONFIGFLAGS} --disable-security-key"
;;
hurd)
SKIP_LTESTS="forwarding multiplex proxy-connect hostkey-agent agent-ptrace"
;;
minix3)
LIBCRYPTOFLAGS="--without-openssl --disable-security-key"
# Minix does not have a loopback interface so we have to skip any
# test that relies on one.
# Also, Minix seems to be very limited in the number of select()
# calls that can be operating concurrently, so prune additional tests for that.
- T="addrmatch agent-restrict brokenkeys cfgmatch cfgmatchlisten cfgparse connect
- connect-uri exit-status forward-control forwarding hostkey-agent
- key-options keyscan knownhosts-command login-timeout multiplex
+ T="addrmatch agent-restrict brokenkeys cfgmatch cfgmatchlisten cfgparse
+ connect connect-uri exit-status forwarding hostkey-agent
+ key-options keyscan knownhosts-command login-timeout
reconfigure reexec rekey scp scp-uri scp3 sftp sftp-badcmds
sftp-batch sftp-cmds sftp-glob sftp-perm sftp-uri stderr-data
transfer"
+ # Unix domain sockets don't work quite like we expect, so also skip any tests
+ # that use multiplexing.
+ T="$T connection-timeout dynamic-forward forward-control multiplex"
SKIP_LTESTS="$(echo $T)"
TEST_TARGET=t-exec
SUDO=""
;;
nbsd4)
# System compiler will ICE on some files with fstack-protector
# SHA256 functions in sha2.h conflict with OpenSSL's breaking sk-dummy
CONFIGFLAGS="${CONFIGFLAGS} --without-hardening --disable-security-key"
;;
openwrt-*)
CONFIGFLAGS="${CONFIGFLAGS} --without-openssl --without-zlib"
TEST_TARGET="t-exec"
;;
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
case "`./config.guess`" in
*cygwin)
SUDO=""
+ # Don't run compat tests on cygwin as they don't currently compile.
+ TEST_TARGET="tests"
;;
*-darwin*)
# Unless specified otherwise, build without OpenSSL on Mac OS since
# modern versions don't ship with libcrypto.
LIBCRYPTOFLAGS="--without-openssl"
TEST_TARGET=t-exec
;;
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 CPPFLAGS LDFLAGS LTESTS SUDO
export TEST_TARGET TEST_SSH_UNSAFE_PERMISSIONS TEST_SSH_FAIL_FATAL
diff --git a/crypto/openssh/.github/setup_ci.sh b/crypto/openssh/.github/setup_ci.sh
index 044c4d1292b1..e4480e614f31 100755
--- a/crypto/openssh/.github/setup_ci.sh
+++ b/crypto/openssh/.github/setup_ci.sh
@@ -1,188 +1,201 @@
#!/bin/sh
PACKAGES=""
. .github/configs $@
case "`./config.guess`" in
*cygwin)
PACKAGER=setup
echo Setting CYGWIN sustem environment variable.
setx CYGWIN "binmode"
chmod -R go-rw /cygdrive/d/a
umask 077
PACKAGES="$PACKAGES,autoconf,automake,cygwin-devel,gcc-core"
PACKAGES="$PACKAGES,make,openssl-devel,zlib-devel"
;;
*-darwin*)
PACKAGER=brew
brew install automake
exit 0
;;
*)
PACKAGER=apt
esac
TARGETS=$@
INSTALL_FIDO_PPA="no"
export DEBIAN_FRONTEND=noninteractive
#echo "Setting up for '$TARGETS'"
set -ex
if [ -x "`which lsb_release 2>&1`" ]; then
lsb_release -a
fi
# Ubuntu 22.04 defaults to private home dirs which prevent the
# agent-getpeerid test from running ssh-add as nobody. See
# https://github.com/actions/runner-images/issues/6106
if [ ! -z "$SUDO" ] && ! "$SUDO" -u nobody test -x ~; then
echo ~ is not executable by nobody, adding perms.
chmod go+x ~
fi
if [ "${TARGETS}" = "kitchensink" ]; then
TARGETS="krb5 libedit pam sk selinux"
fi
for flag in $CONFIGFLAGS; do
case "$flag" in
--with-pam) TARGETS="${TARGETS} pam" ;;
--with-libedit) TARGETS="${TARGETS} libedit" ;;
esac
done
for TARGET in $TARGETS; do
case $TARGET in
default|without-openssl|without-zlib|c89)
# nothing to do
;;
clang-sanitize*)
PACKAGES="$PACKAGES clang-12"
;;
cygwin-release)
PACKAGES="$PACKAGES libcrypt-devel libfido2-devel libkrb5-devel"
;;
gcc-sanitize*)
;;
clang-*|gcc-*)
compiler=$(echo $TARGET | sed 's/-Werror//')
PACKAGES="$PACKAGES $compiler"
;;
krb5)
PACKAGES="$PACKAGES libkrb5-dev"
;;
heimdal)
PACKAGES="$PACKAGES heimdal-dev"
;;
libedit)
case "$PACKAGER" in
setup) PACKAGES="$PACKAGES libedit-devel" ;;
apt) PACKAGES="$PACKAGES libedit-dev" ;;
esac
;;
*pam)
PACKAGES="$PACKAGES libpam0g-dev"
;;
sk)
INSTALL_FIDO_PPA="yes"
PACKAGES="$PACKAGES libfido2-dev libu2f-host-dev libcbor-dev"
;;
selinux)
PACKAGES="$PACKAGES libselinux1-dev selinux-policy-dev"
;;
hardenedmalloc)
INSTALL_HARDENED_MALLOC=yes
;;
musl)
PACKAGES="$PACKAGES musl-tools"
;;
tcmalloc)
PACKAGES="$PACKAGES libgoogle-perftools-dev"
;;
openssl-noec)
INSTALL_OPENSSL=OpenSSL_1_1_1k
SSLCONFOPTS="no-ec"
;;
openssl-*)
INSTALL_OPENSSL=$(echo ${TARGET} | cut -f2 -d-)
case ${INSTALL_OPENSSL} in
1.1.1_stable) INSTALL_OPENSSL="OpenSSL_1_1_1-stable" ;;
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="$(echo ${TARGET} | cut -f2 -d-)" ;;
esac
PACKAGES="${PACKAGES} putty-tools"
;;
valgrind*)
PACKAGES="$PACKAGES valgrind"
;;
*) echo "Invalid option '${TARGET}'"
exit 1
;;
esac
done
if [ "yes" = "$INSTALL_FIDO_PPA" ]; then
sudo apt update -qq
sudo apt install -qy software-properties-common
sudo apt-add-repository -y ppa:yubico/stable
fi
-if [ "x" != "x$PACKAGES" ]; then
+tries=3
+while [ ! -z "$PACKAGES" ] && [ "$tries" -gt "0" ]; do
case "$PACKAGER" in
apt)
sudo apt update -qq
- sudo apt install -qy $PACKAGES
+ if sudo apt install -qy $PACKAGES; then
+ PACKAGES=""
+ fi
;;
setup)
- /cygdrive/c/setup.exe -q -P `echo "$PACKAGES" | tr ' ' ,`
+ if /cygdrive/c/setup.exe -q -P `echo "$PACKAGES" | tr ' ' ,`; then
+ PACKAGES=""
+ fi
;;
esac
+ if [ ! -z "$PACKAGES" ]; then
+ sleep 90
+ fi
+ tries=$(($tries - 1))
+done
+if [ ! -z "$PACKAGES" ]; then
+ echo "Package installation failed."
+ exit 1
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 out/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
if [ "${INSTALL_LIBRESSL}" = "master" ]; 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)
else
LIBRESSL_URLBASE=https://cdn.openbsd.org/pub/OpenBSD/LibreSSL
(cd ${HOME} &&
wget ${LIBRESSL_URLBASE}/libressl-${INSTALL_LIBRESSL}.tar.gz &&
tar xfz libressl-${INSTALL_LIBRESSL}.tar.gz &&
cd libressl-${INSTALL_LIBRESSL} &&
./configure --prefix=/opt/libressl && make -j2 && sudo make install)
fi
fi
diff --git a/crypto/openssh/.github/workflows/c-cpp.yml b/crypto/openssh/.github/workflows/c-cpp.yml
index 3cd1188fc572..e6ea49550f71 100644
--- a/crypto/openssh/.github/workflows/c-cpp.yml
+++ b/crypto/openssh/.github/workflows/c-cpp.yml
@@ -1,122 +1,125 @@
name: C/C++ CI
on:
push:
- branches: [ master, ci, V_9_0 ]
- paths: [ '**.c', '**.h', '**.m4', '**.sh', '.github/**', 'Makefile.in', 'configure.ac' ]
+ paths: [ '**.c', '**.h', '**.m4', '**.sh', '.github/**', '**/Makefile.in', 'configure.ac' ]
pull_request:
- branches: [ master ]
- paths: [ '**.c', '**.h', '**.m4', '**.sh', '.github/**', 'Makefile.in', 'configure.ac' ]
+ paths: [ '**.c', '**.h', '**.m4', '**.sh', '.github/**', '**/Makefile.in', 'configure.ac' ]
jobs:
ci:
if: github.repository != 'openssh/openssh-portable-selfhosted'
strategy:
fail-fast: false
matrix:
# First we test all OSes in the default configuration.
- os: [ubuntu-20.04, ubuntu-22.04, macos-11, macos-12, windows-2019, windows-2022]
- configs: [default]
+ target: [ubuntu-20.04, ubuntu-22.04, macos-11, macos-12, windows-2019, windows-2022]
+ config: [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: windows-2019, configs: cygwin-release }
- - { os: windows-2022, configs: cygwin-release }
- - { 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: clang-6.0 }
- - { os: ubuntu-20.04, configs: clang-8 }
- - { os: ubuntu-20.04, configs: clang-9 }
- - { os: ubuntu-20.04, configs: clang-10 }
- - { os: ubuntu-20.04, configs: clang-11 }
- - { os: ubuntu-20.04, configs: clang-12-Werror }
- - { os: ubuntu-20.04, configs: clang-sanitize-address }
- - { os: ubuntu-20.04, configs: clang-sanitize-undefined }
- - { os: ubuntu-20.04, configs: gcc-sanitize-address }
- - { os: ubuntu-20.04, configs: gcc-sanitize-undefined }
- - { os: ubuntu-20.04, configs: gcc-7 }
- - { os: ubuntu-20.04, configs: gcc-8 }
- - { os: ubuntu-20.04, configs: gcc-10 }
- - { os: ubuntu-20.04, configs: gcc-11-Werror }
- - { os: ubuntu-20.04, configs: pam }
- - { os: ubuntu-20.04, configs: kitchensink }
- - { os: ubuntu-20.04, configs: hardenedmalloc }
- - { os: ubuntu-20.04, configs: tcmalloc }
- - { os: ubuntu-20.04, configs: musl }
- - { 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.6 }
- - { os: ubuntu-latest, configs: libressl-3.3.6 }
- - { os: ubuntu-latest, configs: libressl-3.4.3 }
- - { os: ubuntu-latest, configs: libressl-3.5.3 }
- - { 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-latest, configs: openssl-1.1.1n }
- - { os: ubuntu-latest, configs: openssl-1.1.1p }
- - { os: ubuntu-latest, configs: openssl-3.0.0 }
- - { os: ubuntu-latest, configs: openssl-3.0.5 }
- - { os: ubuntu-latest, configs: openssl-1.1.1_stable } # stable branch
- - { os: ubuntu-latest, configs: openssl-3.0 } # stable branch
- - { os: ubuntu-22.04, configs: pam }
- - { os: ubuntu-22.04, configs: krb5 }
- - { os: ubuntu-22.04, configs: heimdal }
- - { os: ubuntu-22.04, configs: libedit }
- - { os: ubuntu-22.04, configs: sk }
- - { os: ubuntu-22.04, configs: selinux }
- - { os: ubuntu-22.04, configs: kitchensink }
- - { os: ubuntu-22.04, configs: without-openssl }
- - { os: macos-11, configs: pam }
- - { os: macos-12, configs: pam }
- runs-on: ${{ matrix.os }}
+ - { target: windows-2019, config: cygwin-release }
+ - { target: windows-2022, config: cygwin-release }
+ - { target: ubuntu-20.04, config: valgrind-1 }
+ - { target: ubuntu-20.04, config: valgrind-2 }
+ - { target: ubuntu-20.04, config: valgrind-3 }
+ - { target: ubuntu-20.04, config: valgrind-4 }
+ - { target: ubuntu-20.04, config: valgrind-5 }
+ - { target: ubuntu-20.04, config: valgrind-unit }
+ - { target: ubuntu-20.04, config: c89 }
+ - { target: ubuntu-20.04, config: clang-6.0 }
+ - { target: ubuntu-20.04, config: clang-8 }
+ - { target: ubuntu-20.04, config: clang-9 }
+ - { target: ubuntu-20.04, config: clang-10 }
+ - { target: ubuntu-20.04, config: clang-11 }
+ - { target: ubuntu-20.04, config: clang-12-Werror }
+ - { target: ubuntu-20.04, config: clang-sanitize-address }
+ - { target: ubuntu-20.04, config: clang-sanitize-undefined }
+ - { target: ubuntu-20.04, config: gcc-sanitize-address }
+ - { target: ubuntu-20.04, config: gcc-sanitize-undefined }
+ - { target: ubuntu-20.04, config: gcc-7 }
+ - { target: ubuntu-20.04, config: gcc-8 }
+ - { target: ubuntu-20.04, config: gcc-10 }
+ - { target: ubuntu-20.04, config: gcc-11-Werror }
+ - { target: ubuntu-20.04, config: pam }
+ - { target: ubuntu-20.04, config: kitchensink }
+ - { target: ubuntu-20.04, config: hardenedmalloc }
+ - { target: ubuntu-20.04, config: tcmalloc }
+ - { target: ubuntu-20.04, config: musl }
+ - { target: ubuntu-latest, config: libressl-master }
+ - { target: ubuntu-latest, config: libressl-2.2.9 }
+ - { target: ubuntu-latest, config: libressl-2.8.3 }
+ - { target: ubuntu-latest, config: libressl-3.0.2 }
+ - { target: ubuntu-latest, config: libressl-3.2.6 }
+ - { target: ubuntu-latest, config: libressl-3.3.6 }
+ - { target: ubuntu-latest, config: libressl-3.4.3 }
+ - { target: ubuntu-latest, config: libressl-3.5.3 }
+ - { target: ubuntu-latest, config: libressl-3.6.1 }
+ - { target: ubuntu-latest, config: libressl-3.7.0 }
+ - { target: ubuntu-latest, config: openssl-master }
+ - { target: ubuntu-latest, config: openssl-noec }
+ - { target: ubuntu-latest, config: openssl-1.0.1 }
+ - { target: ubuntu-latest, config: openssl-1.0.1u }
+ - { target: ubuntu-latest, config: openssl-1.0.2u }
+ - { target: ubuntu-latest, config: openssl-1.1.0h }
+ - { target: ubuntu-latest, config: openssl-1.1.1 }
+ - { target: ubuntu-latest, config: openssl-1.1.1k }
+ - { target: ubuntu-latest, config: openssl-1.1.1n }
+ - { target: ubuntu-latest, config: openssl-1.1.1q }
+ - { target: ubuntu-latest, config: openssl-1.1.1s }
+ - { target: ubuntu-latest, config: openssl-3.0.0 }
+ - { target: ubuntu-latest, config: openssl-3.0.5 }
+ - { target: ubuntu-latest, config: openssl-3.0.7 }
+ - { target: ubuntu-latest, config: openssl-1.1.1_stable }
+ - { target: ubuntu-latest, config: openssl-3.0 } # stable branch
+ - { target: ubuntu-22.04, config: pam }
+ - { target: ubuntu-22.04, config: krb5 }
+ - { target: ubuntu-22.04, config: heimdal }
+ - { target: ubuntu-22.04, config: libedit }
+ - { target: ubuntu-22.04, config: sk }
+ - { target: ubuntu-22.04, config: selinux }
+ - { target: ubuntu-22.04, config: kitchensink }
+ - { target: ubuntu-22.04, config: without-openssl }
+ - { target: macos-11, config: pam }
+ - { target: macos-12, config: pam }
+ runs-on: ${{ matrix.target }}
steps:
- name: set cygwin git params
- if: ${{ startsWith(matrix.os, 'windows') }}
+ if: ${{ startsWith(matrix.target, 'windows') }}
run: git config --global core.autocrlf input
- name: install cygwin
- if: ${{ startsWith(matrix.os, 'windows') }}
+ if: ${{ startsWith(matrix.target, 'windows') }}
uses: cygwin/cygwin-install-action@master
- - uses: actions/checkout@v2
+ - uses: actions/checkout@main
- name: setup CI system
- run: sh ./.github/setup_ci.sh ${{ matrix.configs }}
+ run: sh ./.github/setup_ci.sh ${{ matrix.config }}
- name: autoreconf
run: sh -c autoreconf
- name: configure
- run: sh ./.github/configure.sh ${{ matrix.configs }}
+ run: sh ./.github/configure.sh ${{ matrix.config }}
- name: save config
- uses: actions/upload-artifact@v2
+ uses: actions/upload-artifact@main
with:
- name: ${{ matrix.os }}-${{ matrix.configs }}-config
+ name: ${{ matrix.target }}-${{ matrix.config }}-config
path: config.h
- name: make clean
run: make clean
- name: make
run: make -j2
- name: make tests
- run: sh ./.github/run_test.sh ${{ matrix.configs }}
+ run: sh ./.github/run_test.sh ${{ matrix.config }}
env:
TEST_SSH_UNSAFE_PERMISSIONS: 1
TEST_SSH_HOSTBASED_AUTH: yes
- name: save logs
if: failure()
- uses: actions/upload-artifact@v2
+ uses: actions/upload-artifact@main
with:
- name: ${{ matrix.os }}-${{ matrix.configs }}-logs
+ name: ${{ matrix.target }}-${{ matrix.config }}-logs
path: |
config.h
config.log
regress/*.log
regress/valgrind-out/
regress/asan.log.*
regress/msan.log.*
diff --git a/crypto/openssh/.github/workflows/cifuzz.yml b/crypto/openssh/.github/workflows/cifuzz.yml
new file mode 100644
index 000000000000..7ca8c4719b61
--- /dev/null
+++ b/crypto/openssh/.github/workflows/cifuzz.yml
@@ -0,0 +1,32 @@
+name: CIFuzz
+on:
+ push:
+ paths: [ '**.c', '**.h', '**.m4', '**.sh', '.github/**', '**/Makefile.in', 'configure.ac' ]
+ pull_request:
+ paths: [ '**.c', '**.h', '**.m4', '**.sh', '.github/**', '**/Makefile.in', 'configure.ac' ]
+
+jobs:
+ Fuzzing:
+ if: github.repository != 'openssh/openssh-portable-selfhosted'
+ runs-on: ubuntu-latest
+ steps:
+ - name: Build Fuzzers
+ id: build
+ uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master
+ with:
+ oss-fuzz-project-name: 'openssh'
+ dry-run: false
+ language: c++
+ - name: Run Fuzzers
+ uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master
+ with:
+ oss-fuzz-project-name: 'openssh'
+ fuzz-seconds: 600
+ dry-run: false
+ language: c++
+ - name: Upload Crash
+ uses: actions/upload-artifact@main
+ if: failure() && steps.build.outcome == 'success'
+ with:
+ name: artifacts
+ path: ./out/artifacts
diff --git a/crypto/openssh/.github/workflows/selfhosted.yml b/crypto/openssh/.github/workflows/selfhosted.yml
index c4bd1d9b24f7..50bc9fffb723 100644
--- a/crypto/openssh/.github/workflows/selfhosted.yml
+++ b/crypto/openssh/.github/workflows/selfhosted.yml
@@ -1,108 +1,116 @@
name: C/C++ CI self-hosted
on:
push:
- branches: [ master, ci, V_9_0 ]
- paths: [ '**.c', '**.h', '**.m4', '**.sh', '.github/**', 'Makefile.in', 'configure.ac' ]
+ paths: [ '**.c', '**.h', '**.m4', '**.sh', '.github/**', '**/Makefile.in', 'configure.ac' ]
jobs:
selfhosted:
if: github.repository == 'openssh/openssh-portable-selfhosted'
- runs-on: ${{ matrix.os }}
+ runs-on: ${{ matrix.host }}
+ timeout-minutes: 600
env:
- TARGET_HOST: ${{ matrix.os }}
+ HOST: ${{ matrix.host }}
+ TARGET_HOST: ${{ matrix.target }}
+ TARGET_CONFIG: ${{ matrix.config }}
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.
+ # default config. "target" corresponds to a label associated with the
+ # worker. The default is an ephemeral VM running under libvirt.
matrix:
- os:
- - aix51
- - ARM
- - ARM64
+ target:
- alpine
- debian-i386
- - debian-riscv64
- dfly30
- dfly48
- dfly58
- dfly60
+ - dfly62
- fbsd10
- fbsd12
- fbsd13
- # - hurd
- minix3
- # - nbsd2
- nbsd3
- nbsd4
- nbsd8
- nbsd9
- obsd51
- obsd67
- obsd69
- obsd70
- obsdsnap
+ - obsdsnap-i386
- openindiana
- - openwrt-mips
- - openwrt-mipsel
- # - rocky84
- sol10
- sol11
- - win10
- configs:
+ config:
- default
- # Then we include any extra configs we want to test for specific VMs.
+ host:
+ - libvirt
include:
- - { os: ARM64, configs: pam }
- - { os: debian-i386, configs: pam }
- - { os: dfly30, configs: without-openssl}
- - { os: dfly48, configs: pam }
- - { os: dfly58, configs: pam }
- - { os: dfly60, 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 }
- - { os: win10, configs: cygwin-release }
+ # Then we include extra libvirt test configs.
+ - { target: aix51, config: default, host: libvirt }
+ - { target: debian-i386, config: pam, host: libvirt }
+ - { target: dfly30, config: without-openssl, host: libvirt}
+ - { target: dfly48, config: pam ,host: libvirt }
+ - { target: dfly58, config: pam, host: libvirt }
+ - { target: dfly60, config: pam, host: libvirt }
+ - { target: dfly62, config: pam, host: libvirt }
+ - { target: fbsd10, config: pam, host: libvirt }
+ - { target: fbsd12, config: pam, host: libvirt }
+ - { target: fbsd13, config: pam, host: libvirt }
+ - { target: nbsd8, config: pam, host: libvirt }
+ - { target: nbsd9, config: pam, host: libvirt }
+ - { target: openindiana, config: pam, host: libvirt }
+ - { target: sol10, config: pam, host: libvirt }
+ - { target: sol11, config: pam-krb5, host: libvirt }
+ - { target: sol11, config: sol64, host: libvirt }
+ # VMs with persistent disks that have their own runner.
+ - { target: win10, config: default, host: win10 }
+ - { target: win10, config: cygwin-release, host: win10 }
+ # Physical hosts, with either native runners or remote via ssh.
+ - { target: ARM, config: default, host: ARM }
+ - { target: ARM64, config: default, host: ARM64 }
+ - { target: ARM64, config: pam, host: ARM64 }
+ - { target: debian-riscv64, config: default, host: debian-riscv64 }
+ - { target: openwrt-mips, config: default, host: openwrt-mips }
+ - { target: openwrt-mipsel, config: default, host: openwrt-mipsel }
steps:
- name: shutdown VM if running
run: vmshutdown
- - uses: actions/checkout@v2
+ working-directory: ${{ runner.temp }}
+ - uses: actions/checkout@main
- name: autoreconf
run: autoreconf
- name: startup VM
run: vmstartup
+ working-directory: ${{ runner.temp }}
- name: configure
- run: vmrun ./.github/configure.sh ${{ matrix.configs }}
+ run: vmrun ./.github/configure.sh ${{ matrix.config }}
- name: save config
- uses: actions/upload-artifact@v2
+ uses: actions/upload-artifact@main
with:
- name: ${{ matrix.os }}-${{ matrix.configs }}-config
+ name: ${{ matrix.target }}-${{ matrix.config }}-config
path: config.h
- name: make clean
run: vmrun make clean
- name: make
run: vmrun make
- name: make tests
- run: vmrun ./.github/run_test.sh ${{ matrix.configs }}
+ run: vmrun ./.github/run_test.sh ${{ matrix.config }}
timeout-minutes: 600
- name: save logs
if: failure()
- uses: actions/upload-artifact@v2
+ uses: actions/upload-artifact@main
with:
- name: ${{ matrix.os }}-${{ matrix.configs }}-logs
+ name: ${{ matrix.target }}-${{ matrix.config }}-logs
path: |
config.h
config.log
regress/*.log
regress/valgrind-out/
- name: shutdown VM
if: always()
run: vmshutdown
+ working-directory: ${{ runner.temp }}
diff --git a/crypto/openssh/.github/workflows/upstream.yml b/crypto/openssh/.github/workflows/upstream.yml
index 3cec069ede74..1e2c2acb7ac0 100644
--- a/crypto/openssh/.github/workflows/upstream.yml
+++ b/crypto/openssh/.github/workflows/upstream.yml
@@ -1,47 +1,52 @@
name: Upstream self-hosted
on:
push:
- branches: [ master, ci ]
+ branches: [ master ]
paths: [ '**.c', '**.h', '.github/**' ]
jobs:
selfhosted:
if: github.repository == 'openssh/openssh-portable-selfhosted'
- runs-on: ${{ matrix.os }}
+ runs-on: 'libvirt'
env:
- TARGET_HOST: ${{ matrix.os }}
+ HOST: 'libvirt'
+ TARGET_HOST: ${{ matrix.target }}
+ TARGET_CONFIG: ${{ matrix.config }}
strategy:
fail-fast: false
matrix:
- os: [ obsdsnap, obsdsnap-i386 ]
- configs: [ default, without-openssl, ubsan ]
+ target: [ obsdsnap, obsdsnap-i386 ]
+ config: [ default, without-openssl, ubsan ]
steps:
- - uses: actions/checkout@v2
- name: shutdown VM if running
run: vmshutdown
+ working-directory: ${{ runner.temp }}
+ - uses: actions/checkout@main
- name: startup VM
run: vmstartup
+ working-directory: ${{ runner.temp }}
- 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 && cd /usr/src/regress/usr.bin/ssh && make obj && make clean"
+ run: vmrun "cd /usr/src/usr.bin/ssh && make obj && make clean && cd /usr/src/regress/usr.bin/ssh && make obj && make clean && sudo chmod -R g-w /usr/src /usr/obj"
- name: make
- run: vmrun "cd /usr/src/usr.bin/ssh && case ${{ matrix.configs }} in without-openssl) make OPENSSL=no;; ubsan) make DEBUG='-fsanitize-minimal-runtime -fsanitize=undefined';; *) make; esac"
+ run: vmrun "cd /usr/src/usr.bin/ssh && case ${{ matrix.config }} in without-openssl) make OPENSSL=no;; ubsan) make DEBUG='-fsanitize-minimal-runtime -fsanitize=undefined';; *) make; esac"
- 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 && case ${{ matrix.configs }} in without-openssl) make OPENSSL=no;; ubsan) make DEBUG='-fsanitize-minimal-runtime -fsanitize=undefined';; *) make; esac"
+ run: vmrun "cd /usr/src/regress/usr.bin/ssh && case ${{ matrix.config }} in without-openssl) make OPENSSL=no;; ubsan) make DEBUG='-fsanitize-minimal-runtime -fsanitize=undefined';; *) make; esac"
env:
SUDO: sudo
timeout-minutes: 300
- name: save logs
if: failure()
- uses: actions/upload-artifact@v2
+ uses: actions/upload-artifact@main
with:
- name: ${{ matrix.os }}-${{ matrix.configs }}-logs
+ name: ${{ matrix.target }}-${{ matrix.config }}-logs
path: |
- /usr/obj/regress/usr.bin/ssh/*.log
+ /usr/obj/regress/usr.bin/ssh/obj/*.log
- name: shutdown VM
if: always()
run: vmshutdown
+ working-directory: ${{ runner.temp }}
diff --git a/crypto/openssh/.skipped-commit-ids b/crypto/openssh/.skipped-commit-ids
index b639678939dd..59e80518acf2 100644
--- a/crypto/openssh/.skipped-commit-ids
+++ b/crypto/openssh/.skipped-commit-ids
@@ -1,53 +1,55 @@
5317f294d63a876bfc861e19773b1575f96f027d remove libssh from makefiles
a337e886a49f96701ccbc4832bed086a68abfa85 Makefile changes
f2c9feb26963615c4fece921906cf72e248b61ee more Makefile
fa728823ba21c4b45212750e1d3a4b2086fd1a62 more Makefile refactoring
1de0e85522051eb2ffa00437e1885e9d7b3e0c2e moduli update
814b2f670df75759e1581ecef530980b2b3d7e0f remove redundant make defs
04431e8e7872f49a2129bf080a6b73c19d576d40 moduli update
c07772f58028fda683ee6abd41c73da3ff70d403 moduli update
db6375fc302e3bdf07d96430c63c991b2c2bd3ff moduli update
5ea3d63ab972691f43e9087ab5fd8376d48e898f uuencode.c Makefile accident
99dd10e72c04e93849981d43d64c946619efa474 include sshbuf-misc.c
9e1c23476bb845f3cf3d15d9032da3ed0cb2fcf5 sshbuf-misc.c in regress
569f08445c27124ec7c7f6c0268d844ec56ac061 Makefile tweaks for !openssl
58ec755be4e51978ecfee73539090eb68652a987 moduli update
4bd5551b306df55379afe17d841207990eb773bf Makefile.inc
14806a59353152f843eb349e618abbf6f4dd3ada Makefile.inc
8ea4455a2d9364a0a04f9e4a2cbfa4c9fcefe77e Makefile.inc
d9b910e412d139141b072a905e66714870c38ac0 Makefile.inc
7b7b619c1452a459310b0cf4391c5757c6bdbc0f moduli update
5010ff08f7ad92082e87dde098b20f5c24921a8f moduli regen script update
3bcae7a754db3fc5ad3cab63dd46774edb35b8ae moduli regen script update
52ff0e3205036147b2499889353ac082e505ea54 moduli update
07b5031e9f49f2b69ac5e85b8da4fc9e393992a0 Makefile.inc
cc12a9029833d222043aecd252d654965c351a69 moduli-gen Makefile
7ac6c252d2a5be8fbad4c66d9d35db507c9dac5b moduli update
6b52cd2b637f3d29ef543f0ce532a2bce6d86af5 makefile change
f9a0726d957cf10692a231996a1f34e7f9cdfeb0 moduli update
+1e0a2692b7e20b126dda60bf04999d1d30d959d8 sshd relinking makefile changes
+e1dc11143f83082e3154d6094f9136d0dc2637ad more relinking makefile tweaks
Old upstream tree:
321065a95a7ccebdd5fd08482a1e19afbf524e35 Update DH groups
d4f699a421504df35254cf1c6f1a7c304fb907ca Remove 1k bit groups
aafe246655b53b52bc32c8a24002bc262f4230f7 Remove intermediate moduli
8fa9cd1dee3c3339ae329cf20fb591db6d605120 put back SSH1 for 6.9
f31327a48dd4103333cc53315ec53fe65ed8a17a Generate new moduli
edbfde98c40007b7752a4ac106095e060c25c1ef Regen moduli
052fd565e3ff2d8cec3bc957d1788f50c827f8e2 Switch to tame-based sandbox
7cf73737f357492776223da1c09179fa6ba74660 Remove moduli <2k
180d84674be1344e45a63990d60349988187c1ae Update moduli
f6ae971186ba68d066cd102e57d5b0b2c211a5ee systrace is dead.
96c5054e3e1f170c6276902d5bc65bb3b87a2603 remove DEBUGLIBS from Makefile
6da9a37f74aef9f9cc639004345ad893cad582d8 Update moduli file
77bcb50e47b68c7209c7f0a5a020d73761e5143b unset REGRESS_FAIL_EARLY
38c2133817cbcae75c88c63599ac54228f0fa384 Change COMPILER_VERSION tests
30c20180c87cbc99fa1020489fe7fd8245b6420c resync integrity.sh shell
1e6b51ddf767cbad0a4e63eb08026c127e654308 integrity.sh reliability
fe5b31f69a60d47171836911f144acff77810217 Makefile.inc bits
5781670c0578fe89663c9085ed3ba477cf7e7913 Delete sshconnect1.c
ea80f445e819719ccdcb237022cacfac990fdc5c Makefile.inc warning flags
b92c93266d8234d493857bb822260dacf4366157 moduli-gen.sh tweak
b25bf747544265b39af74fe0716dc8d9f5b63b95 Updated moduli
1bd41cba06a7752de4df304305a8153ebfb6b0ac rsa.[ch] already removed
e39b3902fe1d6c4a7ba6a3c58e072219f3c1e604 Makefile changes
diff --git a/crypto/openssh/ChangeLog b/crypto/openssh/ChangeLog
index 02e11b023ca0..4251831a1732 100644
--- a/crypto/openssh/ChangeLog
+++ b/crypto/openssh/ChangeLog
@@ -1,11314 +1,11196 @@
-commit 0ffb46f2ee2ffcc4daf45ee679e484da8fcf338c
+commit 6dfb65de949cdd0a5d198edee9a118f265924f33
Author: Damien Miller <djm@mindrot.org>
-Date: Tue Oct 4 01:51:42 2022 +1100
+Date: Thu Feb 2 23:21:54 2023 +1100
- update .depend
+ crank versions in RPM specs
-commit 657e676ff696c7bb787bffb0e249ea1be3b474e1
+commit d07cfb11a0ca574eb68a3931d8c46fbe862a2021
Author: Damien Miller <djm@mindrot.org>
-Date: Tue Oct 4 01:45:52 2022 +1100
+Date: Thu Feb 2 23:21:45 2023 +1100
- update release notes URL
+ update version in README
-commit f059da2b29840c0f048448809c317ce2ae014da7
+commit 9fe207565b4ab0fe5d1ac5bb85e39188d96fb214
Author: Damien Miller <djm@mindrot.org>
-Date: Tue Oct 4 01:45:41 2022 +1100
+Date: Thu Feb 2 23:17:49 2023 +1100
- crank versions in RPM spec files
+ adapt compat_kex_proposal() test to portable
-commit b51f3f172d87cbdb80ca4eb7b2149e56a7647557
+commit 903c556b938fff2d7bff8da2cc460254430963c5
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Sep 26 22:18:40 2022 +0000
+Date: Thu Feb 2 12:12:52 2023 +0000
- upstream: openssh-9.1
+ upstream: test compat_kex_proposal(); by dtucker@
- OpenBSD-Commit-ID: 5a467b2ee81da01a86adf1ad93b62b1728494e56
+ OpenBSD-Regress-ID: 0e404ee264db546f9fdbf53390689ab5f8d38bf2
-commit 4cf8d0c0f3030f594a238bab21a0695735515487
+commit 405fba71962dec8409c0c962408e09049e5624b5
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Wed Sep 21 22:26:50 2022 +0000
+Date: Thu Jan 19 07:53:45 2023 +0000
- upstream: Fix typo. From AlexanderStohr via github PR#343.
+ upstream: Check if we can copy sshd or need to use sudo to do so
- OpenBSD-Commit-ID: a134c9b4039e48803fc6a87f955b0f4a03181497
+ during reexec test. Skip test if neither can work. Patch from anton@, tweaks
+ from me.
+
+ OpenBSD-Regress-ID: 731b96ae74d02d5744e1f1a8e51d09877ffd9b6d
-commit 8179fed3264d5919899900ed8881d5f9bb57ca33
+commit b2a2a8f69fd7737ea17dc044353c514f2f962f35
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Sep 19 21:39:16 2022 +0000
+Date: Thu Feb 2 12:10:22 2023 +0000
- upstream: add RequiredRSASize to the list of keywords accepted by
+ upstream: openssh-9.2
- -o; spotted by jmc@
+ OpenBSD-Commit-ID: f7389f32413c74d6e2055f05cf65e7082de03923
+
+commit 12da7823336434a403f25c7cc0c2c6aed0737a35
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Feb 2 12:10:05 2023 +0000
+
+ upstream: fix double-free caused by compat_kex_proposal(); bz3522
- OpenBSD-Commit-ID: fe871408cf6f9d3699afeda876f8adbac86a035e
+ by dtucker@, ok me
+
+ OpenBSD-Commit-ID: 2bfc37cd2d41f67dad64c17a64cf2cd3806a5c80
-commit 5f954929e9f173dd1e279e07d0e8b14fa845814d
-Author: Damien Miller <djm@mindrot.org>
-Date: Mon Sep 19 20:59:34 2022 +1000
+commit 79efd95ab5ff99f4cb3a955e2d713b3f54fb807e
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Feb 1 17:17:26 2023 +1100
- no need for glob.h here
+ Skip connection-timeout test on minix3.
- it also causes portability problems
+ Minix 3's Unix domain sockets don't seem to work the way we expect, so
+ skip connection-timeout test on that platform. While there, group
+ together all similarly skipped tests and explicitly comment.
-commit 03d94a47207d58b3db37eba4f87eb6ae5a63168a
+commit 6b508c4e039619842bcf5a16f8a6b08dd6bec44a
Author: Damien Miller <djm@mindrot.org>
-Date: Mon Sep 19 20:59:04 2022 +1000
+Date: Wed Feb 1 12:12:05 2023 +1100
- avoid Wuninitialized false positive in gcc-12ish
+ fix libfido2 detection without pkg-config
+
+ Place libfido2 before additional libraries (that it may depend upon)
+ and not after. bz3530 from James Zhang; ok dtucker@
-commit 9d952529113831fb3071ab6e408d2726fd72e771
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Sep 19 10:46:00 2022 +0000
+commit 358e300fed5e6def233a2c06326e51e20ebed621
+Author: deraadt@openbsd.org <deraadt@openbsd.org>
+Date: Wed Jan 18 20:56:36 2023 +0000
- upstream: use users-groups-by-id@openssh.com sftp-server extension
-
- (when available) to fill in user/group names for directory listings.
- Implement a client-side cache of see uid/gid=>user/group names. ok markus@
+ upstream: delete useless dependency
- OpenBSD-Commit-ID: f239aeeadfa925a37ceee36ee8b256b8ccf4466e
+ OpenBSD-Commit-ID: e1dc11143f83082e3154d6094f9136d0dc2637ad
-commit 8ff680368b0bccf88ae85d4c99de69387fbad7a6
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Sep 19 10:43:12 2022 +0000
+commit a4cb9be1b021b511e281ee55c356f964487d9e82
+Author: deraadt@openbsd.org <deraadt@openbsd.org>
+Date: Wed Jan 18 20:43:15 2023 +0000
- upstream: sftp client library support for
+ upstream: Create and install sshd random relink kit.
- users-groups-by-id@openssh.com; ok markus@
+ ../Makefile.inc and Makfile are concatenated for reuse, which hopefully won't
+ be too fragile, we'll see if we need a different approach. The resulting sshd
+ binary is tested with the new sshd -V option before installation. As the
+ binary layout is now semi-unknown (meaning relative, fixed, and gadget
+ offsets are not precisely known), change the filesystem permissions to 511 to
+ prevent what I call "logged in BROP". I have ideas for improving this further
+ but this is a first step ok djm
- OpenBSD-Commit-ID: ddb2f33a2da6349a9a89a8b5bcb9ca7c999394de
+ OpenBSD-Commit-ID: 1e0a2692b7e20b126dda60bf04999d1d30d959d8
-commit 488f6e1c582212c2374a4bf8cd1b703d2e70fb8b
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Sep 19 10:41:58 2022 +0000
+commit bc7de6f91a9a0ae2f148a9d31a4027d441a51999
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Wed Jan 18 06:55:32 2023 +0000
- upstream: extend sftp-common.c:extend ls_file() to support supplied
-
- user/group names; ok markus@
+ upstream: tweak previous; ok djm
- OpenBSD-Commit-ID: c70c70498b1fdcf158531117e405b6245863bfb0
+ OpenBSD-Commit-ID: df71ce4180c58202dfdc1d92626cfe900b91b7c3
-commit 74b77f7497dba3a58315c8f308883de448078057
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Sep 19 10:40:52 2022 +0000
+commit a20b7e999773e6333c8aa9b0a7fa41966e63b037
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Tue Jan 31 19:35:44 2023 +1100
- upstream: sftp-server(8): add a "users-groups-by-id@openssh.com"
-
- extension request that allows the client to obtain user/group names that
- correspond to a set of uids/gids.
-
- Will be used to make directory listings more useful and consistent
- in sftp(1).
+ Skip connection-timeout test under Valgrind.
- ok markus@
-
- OpenBSD-Commit-ID: 7ebabde0bcb95ef949c4840fe89e697e30df47d3
+ Valgrind slows things down so much that the timeout test fails. Skip
+ this test until we figure out if we can make it work.
-commit 231a346c0c67cc7ca098360f9a554fa7d4f1eddb
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Sep 19 08:49:50 2022 +0000
+commit c3ffb54b4fc5e608206037921db6ccbc2f5ab25f
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Jan 25 21:58:40 2023 +1100
- upstream: better debugging for connect_next()
+ Skip connection-timeout when missing FD passing.
- OpenBSD-Commit-ID: d16a307a0711499c971807f324484ed3a6036640
+ This tests uses multiplexing which uses file descriptor passing, so
+ skip it if we don't have that. Fixes test failures on Cygwin.
-commit 1875042c52a3b950ae5963c9ca3774a4cc7f0380
+commit 35253af01d8c0ab444c8377402121816e71c71f5
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Sep 17 10:34:29 2022 +0000
+Date: Wed Jan 18 02:00:10 2023 +0000
- upstream: Add RequiredRSASize for sshd(8); RSA keys that fall
+ upstream: when restoring non-blocking mode to stdio fds, restore
- beneath this limit will be ignored for user and host-based authentication.
+ exactly the flags that ssh started with and don't just clobber them with
+ zero, as this could also remove the append flag from the set;
- Feedback deraadt@ ok markus@
+ bz3523; ok dtucker@
- OpenBSD-Commit-ID: 187931dfc19d51873df5930a04f2d972adf1f7f1
+ OpenBSD-Commit-ID: 1336b03e881db7564a4b66014eb24c5230e9a0c0
-commit 54b333d12e55e6560b328c737d514ff3511f1afd
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Sep 17 10:33:18 2022 +0000
+commit 7d17ea151c0b2519f023bd9cc7f141128833ac47
+Author: millert@openbsd.org <millert@openbsd.org>
+Date: Wed Jan 18 01:50:21 2023 +0000
- upstream: add a RequiredRSASize for checking RSA key length in
-
- ssh(1). User authentication keys that fall beneath this limit will be
- ignored. If a host presents a host key beneath this limit then the connection
- will be terminated (unfortunately there are no fallbacks in the protocol for
- host authentication).
+ upstream: Add a -V (version) option to sshd like the ssh client
- feedback deraadt, Dmitry Belyavskiy; ok markus@
+ has. OK markus@ deraadt@
- OpenBSD-Commit-ID: 430e339b2a79fa9ecc63f2837b06fdd88a7da13a
+ OpenBSD-Commit-ID: abe990ec3e636fb040132aab8cbbede98f0c413e
-commit 07d8771bacfefbcfb37fa8a6dc6103bcc097e0ab
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Sep 17 10:30:45 2022 +0000
+commit 62360feb7f08f2a4c6fc36f3b3449309203c42c9
+Author: millert@openbsd.org <millert@openbsd.org>
+Date: Tue Jan 17 18:52:44 2023 +0000
- upstream: Add a sshkey_check_rsa_length() call for checking the
+ upstream: For "ssh -V" always exit 0, there is no need to check opt
- length of an RSA key; ok markus@
+ again. This was missed when the fallthrough in the switch case above it was
+ removed. OK deraadt@
- OpenBSD-Commit-ID: de77cd5b11594297eda82edc594b0d32b8535134
+ OpenBSD-Commit-ID: 5583e5d8f6d62a8a4215cfa95a69932f344c8120
-commit 3991a0cf947cf3ae0f0373bcec5a90e86a7152f5
+commit 12492c0abf1eb415d08a897cc1d8b9e789888230
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Sep 17 10:11:29 2022 +0000
+Date: Tue Jan 17 10:15:10 2023 +0000
- upstream: actually hook up restrict_websafe; the command-line flag
+ upstream: also check that an active session inhibits
- was never actually used. Spotted by Matthew Garrett
+ UnusedConnectionTimeout idea markus@
- OpenBSD-Commit-ID: 0b363518ac4c2819dbaa3dfad4028633ab9cdff1
+ OpenBSD-Regress-ID: 55c0fb61f3bf9e092b0a53f9041d3d2012f14003
-commit 30b2a7e4291fb9e357f80a237931ff008d686d3b
+commit cef2593c33ac46a58238ff998818754eabdf64ff
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Sep 16 06:55:37 2022 +0000
+Date: Tue Jan 17 10:02:34 2023 +0000
- upstream: correct error value
+ upstream: regression test for UnusedConnectionTimeout
- OpenBSD-Commit-ID: 780efcbad76281f11f14b2a5ff04eb6db3dfdad4
+ OpenBSD-Regress-ID: 7f29001374a68e71e5e078f69e4520cf4bcca084
-commit ac1ec9545947d9f9657259f55d04cb49d3a94c8a
+commit aff9493a89c71d6a080419b49ac64eead9730491
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Sep 16 03:33:14 2022 +0000
+Date: Mon Jan 16 04:11:29 2023 +0000
- upstream: sftp: Be a bit more clever about completions
-
- There are commands (e.g. "get" or "put") that accept two
- arguments, a local path and a remote path. However, the way
- current completion is written doesn't take this distinction into
- account and always completes remote or local paths.
-
- By expanding CMD struct and "cmds" array this distinction can be
- reflected and with small adjustment to completer code the correct
- path can be completed.
+ upstream: unbreak test: cannot access shell positional parameters
- By Michal Privoznik, ok dtucker@
+ past $9 without wrapping the position in braces (i.e. need ${10}, etc.)
- OpenBSD-Commit-ID: 1396d921c4eb1befd531f5c4a8ab47e7a74b610b
+ OpenBSD-Regress-ID: 3750ec98d5d409ce6a93406fedde6f220d2ea2ac
-commit 590db83384f9d99fc51c84505792d26d1ef60df9
+commit 0293c19807f83141cdf33b443154459f9ee471f6
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Sep 16 03:13:34 2022 +0000
+Date: Tue Jan 17 09:44:48 2023 +0000
- upstream: sftp: Don't attempt to complete arguments for
+ upstream: Add a sshd_config UnusedConnectionTimeout option to terminate
- non-existent commands
+ client connections that have no open channels for some length of time. This
+ complements the recently-added ChannelTimeout option that terminates inactive
+ channels after a timeout.
- If user entered a non-existent command (e.g. because they made a
- typo) there is no point in trying to complete its arguments. Skip
- calling complete_match() if that's the case.
+ ok markus@
- From Michal Privoznik
+ OpenBSD-Commit-ID: ca983be74c0350364c11f8ba3bd692f6f24f5da9
+
+commit 8ec2e3123802d2beeca06c1644b0b647f6d36dab
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sun Jan 15 23:35:10 2023 +0000
+
+ upstream: adapt to ed25519 changes in src/usr.bin/ssh
- OpenBSD-Commit-ID: cf39c811a68cde2aeb98fc85addea4000ef6b07a
+ OpenBSD-Regress-ID: 4b3e7ba7ee486ae8a0b4790f8112eded2bb7dcd5
-commit ff9809fdfd1d9a91067bb14a77d176002edb153c
+commit 9fbbfeca1ce4c7ec0001c827bbf4189a3ba0964b
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Sep 14 00:14:37 2022 +0000
+Date: Sun Jan 15 23:05:32 2023 +0000
- upstream: sk_enroll: never drop SSH_SK_USER_VERIFICATION_REQD flag
+ upstream: update OpenSSH's Ed25519 code to the last version of SUPERCOP
- from response
+ (20221122) and change the import approach to the same one we use for
+ Streamlined NTRUPrime: use a shell script to extract the bits we need from
+ SUPERCOP, make some minor adjustments and squish them all into a single file.
- Now that all FIDO signing calls attempt first without PIN and then
- fall back to trying PIN only if that attempt fails, we can remove the
- hack^wtrick that removed the UV flag from the keys returned during
- enroll.
+ ok tb@ tobhe@
- By Corinna Vinschen
+ OpenBSD-Commit-ID: 1bc0fd624cb6af440905b8ba74ac7c03311b8e3b
+
+commit 6283f4bd83eee714d0f5fc55802eff836b06fea8
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat Jan 14 22:02:44 2023 +1100
+
+ Allow writev is seccomp sandbox.
- OpenBSD-Commit-ID: 684517608c8491503bf80cd175425f0178d91d7f
+ This seems to be used by recent glibcs at least in some configurations.
+ From bz#3512, ok djm@
-commit 940dc10729cb5a95b7ee82c10184e2b9621c8a1d
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Sep 14 00:13:13 2022 +0000
+commit 923c3f437f439cfca238fba37e97a7041782f615
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Sat Jan 14 10:05:54 2023 +0000
- upstream: a little extra debugging
+ upstream: Shell syntax fix. From ren mingshuai vi github PR#369.
- OpenBSD-Commit-ID: edf1601c1d0905f6da4c713f4d9cecc7d1c0295a
+ OpenBSD-Regress-ID: 6696b2eeefe128099fc3d7ea9f23252cc35156f9
-commit 4b5f91cb959358141181b934156513fcb8a6c1e3
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Sep 14 00:02:03 2022 +0000
+commit 4d87a00f704e0365e11c3c38b170c1275ec461fc
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Sat Jan 14 09:57:08 2023 +0000
- upstream: ssh-agent: attempt FIDO key signing without PIN and use
+ upstream: Instead of skipping the all-tokens test if we don't have
- the error to determine whether a PIN is required and prompt only if
- necessary. from Corinna Vinschen
+ OpenSSL (since we use it to compute the hash), put the hash at the end and
+ just omit it if we don't have it. Prompted by bz#3521.
- OpenBSD-Commit-ID: dd6be6a0b7148608e834ee737c3479b3270b00dd
+ OpenBSD-Regress-ID: c79ecba64250ed3b6417294b6c965e6b12ca5eea
-commit 113523bf0bc33600b07ebb083572c8c346b6fdf4
+commit b05406d6f93b8c8ec11ec8b27e7c76cc7a5a55fb
Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Sun Sep 11 06:38:11 2022 +0000
+Date: Fri Jan 13 07:13:40 2023 +0000
- upstream: .Li -> .Vt where appropriate; from josiah frentsos,
+ upstream: fix double phrase in previous;
- tweaked by schwarze
-
- ok schwarze
+ OpenBSD-Commit-ID: 671e6c8dc5e9230518b2bbfa143daaa88adc66c2
+
+commit 40564812b659c530eb1f4b62d09e85612aef3107
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Jan 13 03:16:29 2023 +0000
+
+ upstream: Document "UserKnownHostsFile none". ok djm@
- OpenBSD-Commit-ID: 565046e3ce68b46c2f440a93d67c2a92726de8ed
+ OpenBSD-Commit-ID: f695742d39e34ecdcc3c861c3739a84648a4bce5
-commit 86af013b56cecb5ee58ae0bd9d495cd586fc5918
-Author: jsg@openbsd.org <jsg@openbsd.org>
-Date: Sat Sep 10 08:50:53 2022 +0000
+commit d03e245e034019a37388f6f5f893ce848ab6d2e2
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Jan 13 23:02:34 2023 +1100
- upstream: fix repeated words ok miod@ jmc@
+ Retry package installation 3 times.
- OpenBSD-Commit-ID: 6765daefe26a6b648cc15cadbbe337596af709b7
+ When setting up the CI environment, retry package installation 3 times
+ before going up. Should help prevent spurious failures during
+ infrastructure issues.
-commit 0ba39b93b326a7d5dfab776cc9b9d326161a9b16
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Sep 9 03:31:42 2022 +0000
+commit 625f6bc39840167dafb3bf5b6a3e18503ac986e8
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Jan 13 04:47:34 2023 +0000
- upstream: notifier_complete(NULL, ...) is a noop, so no need to test
+ upstream: Move scp path setting to a helper function. The previous
- that ctx!=NULL; from Corinna Vinschen
+ commit to add scp to the test sshd's path causes the t-envpass test to fail
+ when the test scp is given using a fully qualified path. Put this in a
+ helper function and only call it from the scp tests.
- OpenBSD-Commit-ID: ade2f2e9cc519d01a586800c25621d910bce384a
+ OpenBSD-Regress-ID: 7533dc1c4265c1de716abb062957994195b36df4
-commit be197635329feb839865fdc738e34e24afd1fca8
-Author: Sam James <sam@gentoo.org>
-Date: Thu Sep 8 02:49:29 2022 +0100
+commit 6e6f88647042b3cde54a628545c2f5fb656a9327
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Jan 13 04:23:00 2023 +0000
- openbsd-compat/bsd-asprintf: add <stdio.h> include for vsnprintf
+ upstream: Add scp's path to test sshd's PATH.
- Fixes the following build failure with Clang 15 on musl:
- ```
- bsd-asprintf.c:51:8: error: call to undeclared library function 'vsnprintf' with type 'int (char *, unsigned long, const char *, struct __va_list_tag *)'; ISO C99 and laterclang -O2 -pipe -fdiagnostics-color=always -frecord-gcc-switches -pipe -Wunknown-warning-option -Qunused-arguments -Wall -Wpointer-arith -Wuninitialized -Wsign-compare -Wformat-security -Wsizeof-pointer-memaccess -Wno-pointer-sign -Wno-unused-result -Wmisleading-indentation -Wbitwise-instead-of-logical -fno-strict-aliasing -mretpoline -ftrapv -fzero-call-used-regs=all -fno-builtin-memset -fstack-protector-strong -fPIE -I. -I. -D_XOPEN_SOURCE=600 -D_BSD_SOURCE -D_DEFAULT_SOURCE -DSSHDIR=\"/etc/ssh\" -D_PATH_SSH_PROGRAM=\"/usr/bin/ssh\" -D_PATH_SSH_ASKPASS_DEFAULT=\"/usr/lib/misc/ssh-askpass\" -D_PATH_SFTP_SERVER=\"/usr/lib/misc/sftp-server\" -D_PATH_SSH_KEY_SIGN=\"/usr/lib/misc/ssh-keysign\" -D_PATH_SSH_PKCS11_HELPER=\"/usr/lib/misc/ssh-pkcs11-helper\" -D_PATH_SSH_SK_HELPER=\"/usr/lib/misc/ssh-sk-helper\" -D_PATH_SSH_PIDDIR=\"/run\" -D_PATH_PRIVSEP_CHROOT_DIR=\"/var/empty\" -DHAVE_CONFIG_H -c cipher-aes.c -o cipher-aes.o
- do not support
- implicit function declarations [-Wimplicit-function-declaration]
- ret = vsnprintf(string, INIT_SZ, fmt, ap2);
- ^
- bsd-asprintf.c:51:8: note: include the header <stdio.h> or explicitly provide a declaration for 'vsnprintf'
- 1 error generated.
- ```
+ If the scp we're testing is fully qualified (eg it's not in the system
+ PATH) then add its path to the under-test sshd's PATH so we can find
+ it. Prompted by bz#3518.
+
+ OpenBSD-Regress-ID: 7df4f5a0be3aa135495b7e5a6719d3cbc26cc4c0
-commit 6cb6f660bb35f77a0456dd2581ddf39c29398a5e
+commit 8a5e99a70fcf9b022a8aa175ebf6a71f58511da3
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Sep 2 16:43:27 2022 +1000
+Date: Fri Jan 13 15:49:48 2023 +1100
- Remove DEF_WEAK, it's already in defines.h.
+ Remove skipping test when scp not in path.
+
+ An upcoming change renders this obsolete by adding scp's path to the
+ test sshd's PATH, and removing this first will make the subsequent sync
+ easier.
-commit ce39e7d8b70c4726defde5d3bc4cb7d40d131153
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Sep 2 14:28:14 2022 +1000
+commit 41f36dd896c8fb8337d403fcf476762986976e9d
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Jan 13 02:58:20 2023 +0000
- Resync arc4random with OpenBSD.
+ upstream: Add a "Host" line to the output of ssh -G showing the
- This brings us up to current, including djm's random-reseeding change,
- as prompted by logan at cyberstorm.mu in bz#3467. It brings the
- platform-specific hooks from LibreSSL Portable, simplified to match our
- use case. ok djm@.
+ original host arg. Inspired by patch from vincent at bernat.ch via bz#3343,
+ ok djm@
+
+ OpenBSD-Commit-ID: 59c0f60a222113a44d0650cd394376e3beecc883
-commit beaddde26f30e2195b8aa4f3193970e140e17305
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Sep 2 14:20:04 2022 +1000
+commit f673b49f3be3eb51074fbb8a405beb6cd0f7d93e
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Jan 13 02:44:02 2023 +0000
- Move OPENBSD ORIGINAL marker.
+ upstream: avoid printf("%s", NULL) if using ssh
- Putting this after the copyright statement (which doesn't change)
- instead of before the version identifier (which does) prevents merge
- conflicts when resyncing changes.
+ -oUserKnownHostsFile=none and a hostkey in one of the system known hosts file
+ changes; ok dtucker@
+
+ OpenBSD-Commit-ID: 7ca87614bfc6da491315536a7f2301434a9fe614
-commit c83e467ead67a8cb48ef4bec8085d6fb880a2ff4
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Sep 2 14:17:28 2022 +1000
+commit 93fc7c576563e3d88a1dc019dd213f65607784cc
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Jan 11 05:39:38 2023 +0000
- Remove arc4random_uniform from arc4random.c
+ upstream: clamp the minimum buffer lengths and number of inflight
- This was previously moved into its own file (matching OpenBSD) which
- prematurely committed in commit 73541f2.
+ requests too
+
+ OpenBSD-Commit-ID: c4965f62fa0ba850940fd66ae3f60cf516bbcd56
-commit 5f45c2395c60865e59fa44152ff1d003a128c5bc
+commit 48bf234322e639d279c5a28435eae50155e9b514
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Sep 2 04:20:02 2022 +0000
+Date: Wed Jan 11 05:36:50 2023 +0000
- upstream: sk-usbhid: fix key_lookup() on tokens with built-in UV
+ upstream: ignore bogus upload/download buffer lengths in the limits
- explicitly test whether the token performs built-in UV (e.g. biometric
- tokens) and enable UV in that case. From Pedro Martelletto via GHPR#388
+ extension
- OpenBSD-Commit-ID: 007eb7e387d27cf3029ab06b88224e03eca62ccd
+ OpenBSD-Commit-ID: c5b023e0954693ba9a5376e4280c739b5db575f8
-commit 03277a4aa49b80af541a3e691f264c0c0d8f9cec
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Aug 31 20:26:30 2022 +1000
+commit 36b00d31833ca74cb0f7c7d8eda1bde55700f929
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Jan 11 02:13:52 2023 +0000
- Move sftp from valgrind-2 to 3 to rebalance.
+ upstream: remove whitespace at EOL from code extracted from SUPERCOP
+
+ OpenBSD-Commit-ID: 1ec524ff2fbb9387d731601437c82008f35a60f4
-commit fcf5365da69c516817321ba89c3a91df98d098df
+commit d888de06c5e4d7dbf2f2b85f2b5bf028c570cf78
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Aug 31 02:56:40 2022 +0000
+Date: Wed Jan 11 00:51:27 2023 +0000
- upstream: whitespace
+ upstream: rewrite this test to use a multiplexed ssh session so we can
- OpenBSD-Commit-ID: c2bcbf93610d3d62ed206cdf9bf9ff98c6aaf232
+ control its lifecycle without risk of race conditions; fixes some of the
+ Github integration tests for openssh-portable
+
+ OpenBSD-Regress-ID: 5451cad59ba0d43ae9eeda48ec80f54405fee969
-commit e60136a3d7a223dd8e84ba8a6895bc3142360993
+commit 4bcc737a35fdd9cc4af7423d6c23dfd0c7ef4786
Author: Damien Miller <djm@mindrot.org>
-Date: Mon Aug 29 13:27:45 2022 +1000
+Date: Wed Jan 11 11:45:17 2023 +1100
- additional keys
+ remove buffer len workaround for NetBSD 4.x
+
+ Switching to from pipes to a socketpair for communicating with the
+ ssh process avoids the (kernel bug?) problem.
-commit 2b02dcb505288c462d1b5dd1ac04e603d01340eb
+commit f5154d2aac3e6a32a1b13dec23a701a087850cdc
Author: Damien Miller <djm@mindrot.org>
-Date: Mon Aug 29 13:23:43 2022 +1000
+Date: Wed Jan 11 11:44:19 2023 +1100
- cross-sign allowed_signers with PGP key
+ add back use of pipes in scp.c under USE_PIPES
- Provides continuity of trust from legacy PGP release key to
- the SSHSIG signing keys that we will use henceforth for git
- signing.
+ This matches sftp.c which prefers socketpair but uses pipes on
+ some older platforms.
-commit 51b345f177ae981b8755f6bdf8358b1cc5e83d67
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Aug 27 21:49:27 2022 +1000
+commit eec737b59cf13841de46134967a206607000acd4
+Author: millert@openbsd.org <millert@openbsd.org>
+Date: Tue Jan 10 23:22:15 2023 +0000
- Add libcrypt-devel to cygwin-release deps.
+ upstream: Switch scp from using pipes to a socketpair for
- Based on feedback from vinschen at redhat.com.
-
-commit 9f81736cf16dd8dda1c8942f1973a5f80b8cd78c
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Aug 27 09:37:40 2022 +1000
-
- Add Windows 2022 test targets.
+ communication with it's ssh sub-processes. We no longer need to reserve two
+ descriptors to ensure that we don't end up using fd 0-2 unexpectedly, that is
+ handled by sanitise_stdfd() in main(). Based on an original diff from djm@.
+ OK deraadt@ djm@
+
+ OpenBSD-Commit-ID: b80c372faac462471e955ddeab9480d668a2e48d
-commit 85e1a69243f12be8520438ad6a3cfdc0b7fcbb2d
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Aug 26 16:26:06 2022 +1000
+commit d213d126a4a343abd3a1eb13687d39c1891fe5c8
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Fri Jan 6 08:44:11 2023 +0000
- Add cygwin-release test target.
+ upstream: tweak previous; ok djm
- This also moves the cygwin package install from the workflow file to
- setup_ci.sh so that we can install different sets of Cygwin packages
- for different test configs.
+ OpenBSD-Commit-ID: 229c493452766d70a78b0f02f6ff9894f9028858
-commit 92382dbe8bf9ea1225b16858f9b9b208c15c7e8d
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Aug 26 08:16:27 2022 +0000
+commit 4a5590a5ee47b7dfd49773e9fdba48ad3089fe64
+Author: Damien Miller <djm@mindrot.org>
+Date: Mon Jan 9 16:33:56 2023 +1100
- upstream: whitespace
+ try to improve logging for dynamic-forward test
- OpenBSD-Commit-ID: a5d015efbfd228dc598ffdef612d2da3a579e5d8
+ previously the logs from the ssh used to exercise the forwarding
+ channel would clobber the logs from the ssh actually doing the
+ forwarding
-commit 70a5de0a50e84d7250eb4e4537f765599f64c4af
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Aug 26 08:12:56 2022 +0000
+commit 715bc25dcfccf9fb2bee820155fe071d01a618db
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat Jan 7 23:24:50 2023 +1100
- upstream: whitespace
+ Skip dynamic-forward test on minix3.
- OpenBSD-Commit-ID: d297e4387935d4aef091c5e9432578c2e513f538
+ This test relies on loopback addresses which minix does not have.
+ Previously the test would not run at all since it also doesn't have
+ netcat, but now we use our own netcat it tries and fails.
-commit 3a683a19fd116ea15ebf8aa13d02646cceb302a9
+commit dd1249bd5c45128a908395c61b26996a70f82205
Author: Damien Miller <djm@mindrot.org>
-Date: Fri Aug 26 14:23:55 2022 +1000
-
- initial list of allowed signers
+Date: Sun Jan 8 12:08:59 2023 +1100
-commit 6851f4b8c3fc1b3e1114c56106e4dc31369c8513
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Aug 19 17:22:18 2022 +1000
-
- Install Cygwin packages based on OS not config.
+ don't test IPv6 addresses if platform lacks support
-commit f96480906893ed93665df8cdf9065865c51c1475
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Aug 19 06:07:47 2022 +0000
+commit d77fc611a62f2dfee0b654c31a50a814b13310dd
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Jan 6 12:33:33 2023 +0000
- upstream: attemp FIDO key signing without PIN and use the error
+ upstream: When OpenSSL is not available, skip parts of percent test
- code returned to fall back only if necessary. Avoids PIN prompts for FIDO
- tokens that don't require them; part of GHPR#302
+ that require it. Based on github pr#368 from ren mingshuai.
- OpenBSD-Commit-ID: 4f752aaf9f2e7c28bcaaf3d4f8fc290131bd038e
+ OpenBSD-Regress-ID: 49a375b2cf61ccb95b52e75e2e025cd10988ebb2
-commit 5453333b5d28e313284cb9aae82899704103f98d
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Aug 19 05:53:28 2022 +0000
+commit 1cd2aac312af9172f1b5cb06c2e1cd090abb83cf
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat Jan 7 23:01:11 2023 +1100
- upstream: remove incorrect check that can break enrolling a
-
- resident key (introduced in r1.40)
+ Use our own netcat for dynamic-forward test.
- OpenBSD-Commit-ID: 4cab364d518470e29e624af3d3f9ffa9c92b6f01
+ That way we can be surer about its behaviour rather than trying to
+ second-guess the behaviour of various netcat implementations.
-commit ff89b1bed80721295555bd083b173247a9c0484e
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Aug 19 04:02:46 2022 +0000
+commit 26cab41c05d7b0859d2a1ea5b6ed253d91848a80
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat Jan 7 14:30:43 2023 +1100
- upstream: Strictly enforce the maximum allowed SSH2 banner size in
-
- ssh-keyscan and prevent a one-byte buffer overflow. Patch from Qualys, ok
- djm@
+ Use autoconf to find openssl binary.
- OpenBSD-Commit-ID: 6ae664f9f4db6e8a0589425f74cd0bbf3aeef4e4
+ It's possible to install an OpenSSL in a path not in the system's
+ default library search path. OpenSSH can still use this (eg if you
+ specify an rpath) but the openssl binary there may not work. If one is
+ available on the system path just use that.
-commit 1b470b9036639cef4f32fb303bb35ea0b711178d
+commit 5532e010a0eeb6aa264396514f9aed7948471538
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Aug 19 15:18:09 2022 +1000
+Date: Sat Jan 7 10:34:18 2023 +1100
- Fix cygwin conditional steps.
+ Check openssl_bin path is executable before using.
-commit fd6ee741ab16714b7035d60aca924123ba28135a
+commit 5d7b16cff48598d5908db970bfdc9ff9326142c8
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Aug 19 15:12:57 2022 +1000
+Date: Fri Jan 6 23:19:07 2023 +1100
- Add a bit more debug output.
+ Set OPENSSL_BIN from OpenSSL directory.
-commit a9305c4c739f4d91a3d3a92c0b6d4949404a36c5
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Aug 12 15:08:47 2022 +1000
+commit 344a0e8240eaf08da5d46a5e3a9ecad6e4f64c35
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Jan 6 08:50:33 2023 +0000
- Add Cygwin (on windows-2019) test target.
+ upstream: Save debug logs from ssh for debugging purposes.
- In addition to installing the requisite Cygwin packages, we also need to
- explicitly invoke "sh" for steps that run other scripts since the runner
- environment doesn't understand #! paths.
+ OpenBSD-Regress-ID: 109e40b06de1c006a3b8e0d8745b790b2c5870a0
-commit 5062ad48814b06162511c4f5924a33d97b6b2566
+commit e1ef172646f7f49c80807eea90225ef5e0be55a8
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Aug 19 03:06:30 2022 +0000
+Date: Fri Jan 6 08:07:39 2023 +0000
- upstream: double free() in error path; from Eusgor via GHPR333
+ upstream: regression test for ChannelTimeout
- OpenBSD-Commit-ID: 39f35e16ba878c8d02b4d01d8826d9b321be26d4
+ OpenBSD-Regress-ID: 280bfbefcfa415428ad744e43f69a8dede8ad685
-commit 5a5c580b48fc6006bdfa731fc2f6d4945c2c0e4e
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Aug 18 21:36:39 2022 +1000
+commit 2393ea8daf25853459eb07a528d7577688847777
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Jan 6 07:18:18 2023 +0000
- Check for perms to run agent-getpeereid test.
+ upstream: fix typo in verbose logging
- Ubuntu 22.04 defaults to private home dirs which prevents "nobody"
- running ssh-add during the agent-getpeereid test. Check for this and
- add the necessary permissions.
+ OpenBSD-Regress-ID: 0497cdb66e003b2f50ed77291a9104fba2e017e9
-commit cd06a76b7ccc706e2bb4f1cc4aa9e9796a28a812
+commit 161a5378a3cc2e7aa3f9674cb7f4686ae6ce9586
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Jan 6 02:59:50 2023 +0000
+
+ upstream: unit tests for misc.c:ptimeout_* API
+
+ OpenBSD-Regress-ID: 01f8fb12d08e5aaadd4bd4e71f456b6588be9a94
+
+commit 018d671d78145f03d6f07ae9d64d51321da70325
+Author: tb@openbsd.org <tb@openbsd.org>
+Date: Wed Jan 4 22:48:57 2023 +0000
+
+ upstream: Copy bytes from the_banana[] rather than banana()
+
+ Fixes test failure due to segfault seen on arm64 with xonly snap.
+
+ ok djm
+
+ OpenBSD-Regress-ID: 86e2aa4bbd1dff1bc4ebb2969c0d6474485be046
+
+commit ab6bb69e251faa8b24f81b25c72ec0120f20cad4
Author: Damien Miller <djm@mindrot.org>
-Date: Wed Aug 17 16:04:16 2022 +1000
+Date: Fri Jan 6 19:13:36 2023 +1100
- on Cygwin, prefer WinHello FIDO device
+ unbreak scp on NetBSD 4.x
- If no FIDO device was explictly specified, then prefer the
- windows://hello FIDO device. An exception to this is when
- probing resident FIDO keys, in which case hardware FIDO
- devices are preferred.
+ e555d5cad5 effectively increased the default copy buffer size for SFTP
+ transfers. This caused NetBSD 4.x to hang during the "copy local file to
+ remote file in place" scp.sh regression test.
+
+ This puts back the original 32KB copy buffer size until we can properly
+ figure out why.
+
+ lots of debugging assistance from dtucker@
-commit 47f72f534ac5cc2cd3027675a3df7b00a8f77575
+commit 2d1ff2b9431393ad99ef496d5e3b9dd0d4f5ac8c
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Aug 17 06:01:57 2022 +0000
+Date: Fri Jan 6 02:47:18 2023 +0000
- upstream: add an extra flag to sk_probe() to indicate whether we're
+ upstream: Implement channel inactivity timeouts
- probing for a FIDO resident key or not. Unused here, but will make like
- easier for portable
+ This adds a sshd_config ChannelTimeouts directive that allows channels that
+ have not seen traffic in a configurable interval to be automatically closed.
+ Different timeouts may be applied to session, X11, agent and TCP forwarding
+ channels.
- OpenBSD-Commit-ID: 432c8ff70e270378df9dbceb9bdeaa5b43b5a832
+ Note: this only affects channels over an opened SSH connection and not
+ the connection itself. Most clients close the connection when their channels
+ go away, with a notable exception being ssh(1) in multiplexing mode.
+
+ ok markus dtucker
+
+ OpenBSD-Commit-ID: ae8bba3ed9d9f95ff2e2dc8dcadfa36b48e6c0b8
-commit edb0bcb3c79b16031dc87a8e57aecc3c4a3414f0
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Tue Aug 16 20:24:08 2022 +0000
+commit 0e34348d0bc0b1522f75d6212a53d6d1d1367980
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Jan 6 02:42:34 2023 +0000
- upstream: use .Cm for "sign"; from josiah frentsos
+ upstream: Add channel_set_xtype()
- OpenBSD-Commit-ID: 7f80a53d54857ac6ae49ea6ad93c5bd12231d1e4
+ This sets an "extended" channel type after channel creation (e.g.
+ "session:subsystem:sftp") that will be used for setting channel inactivity
+ timeouts.
+
+ ok markus dtucker
+
+ OpenBSD-Commit-ID: 42564aa92345045b4a74300528f960416a15d4ca
-commit cccb011e130cbbac538b1689d10e4a067298df8b
-Author: Corinna Vinschen <vinschen@redhat.com>
-Date: Thu Aug 11 20:19:35 2022 +0200
+commit ceedf09b2977f3a756c759a6e7eb8f8e9db86a18
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Jan 6 02:41:49 2023 +0000
- Revert "check_sk_options: add temporary WinHello workaround"
+ upstream: tweak channel ctype names
- Cygwin now comes with libfido2 1.11.0, so this workaround
- isn't required anymore.
+ These are now used by sshd_config:ChannelTimeouts to specify timeouts by
+ channel type, so force them all to use a similar format without whitespace.
- This reverts commit 242c044ab111a37aad3b0775727c36a4c5f0102c.
+ ok dtucker markus
- Signed-off-by: Corinna Vinschen <vinschen@redhat.com>
+ OpenBSD-Commit-ID: 66834765bb4ae14f96d2bb981ac98a7dae361b65
-commit 9468cd7cf9d989dfa2ac20e2a0268ba6e93bfa5a
-Author: Corinna Vinschen <vinschen@redhat.com>
-Date: Thu Aug 11 20:18:17 2022 +0200
+commit c60438158ad4b2f83d8504257aba1be7d0b0bb4b
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Jan 6 02:39:59 2023 +0000
- fido_dev_is_winhello: return 0, not "false"
+ upstream: Add channel_force_close()
- "false" is not used anywhere in OpenSSH, so return 0 like
- everywhere else.
+ This will forcibly close an open channel by simulating read/write errors,
+ draining the IO buffers and calling the detach function.
- Signed-off-by: Corinna Vinschen <vinschen@redhat.com>
+ Previously the detach function was only ever called during channel garbage
+ collection, but there was no way to signal the user of a channel (e.g.
+ session.c) that its channel was being closed deliberately (vs. by the
+ usual state-machine logic). So this adds an extra "force" argument to the
+ channel cleanup callback to indicate this condition.
+
+ ok markus dtucker
+
+ OpenBSD-Commit-ID: 23052707a42bdc62fda2508636e624afd466324b
-commit 730a80609472ee0451c99482d75c9c41f3ebc42d
+commit d478cdc7ad6edd4b1bcd1e86fb2f23194ff33d5a
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Aug 12 05:20:28 2022 +0000
+Date: Fri Jan 6 02:38:23 2023 +0000
- upstream: sftp-server: support home-directory request
+ upstream: replace manual poll/ppoll timeout math with ptimeout API
- Add support to the sftp-server for the home-directory extension defined
- in draft-ietf-secsh-filexfer-extensions-00. This overlaps a bit with the
- existing expand-path@openssh.com, but uses a more official protocol name,
- and so is a bit more likely to be implemented by non-OpenSSH clients.
+ feedback markus / ok markus dtucker
- From Mike Frysinger, ok dtucker@
+ OpenBSD-Commit-ID: c5ec4f2d52684cdb788cd9cbc1bcf89464014be2
+
+commit 4adf3817a24efe99b06e62630577d683c7cd8065
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Jan 6 02:37:04 2023 +0000
+
+ upstream: add ptimeout API for keeping track of poll/ppoll
- OpenBSD-Commit-ID: bfc580d05cc0c817831ae7ecbac4a481c23566ab
+ timeouts; ok dtucker markus
+
+ OpenBSD-Commit-ID: 3335268ca135b3ec15a947547d7cfbb8ff929ead
-commit 5e820bf79ce3ce99ef7e98b0ab642b0a0a4f396c
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Aug 12 14:56:55 2022 +1000
+commit 8c7c69d32375d2f3ce9da0109c9bffc560842316
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Jan 5 05:49:13 2023 +0000
- Replace deprecated ubuntu-18.04 runners with 22.04
+ upstream: suppress "Connection closed" message when in quiet mode
+
+ OpenBSD-Commit-ID: 8a3ab7176764da55f60bfacfeae9b82d84e3908f
-commit 87b0d9c1b789d3ff958ec45df2ac912e24461bae
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Aug 11 22:48:23 2022 +1000
+commit 845ceecea2ac311b0c267f9ecbd34862e1876fc6
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Jan 2 07:03:57 2023 +0000
- Add a timegm implementation from Heimdal via Samba.
+ upstream: regression test for PermitRemoteOpen
- Fixes build on (at least Solaris 10).
+ OpenBSD-Regress-ID: 8271aafbf5c21950cd5bf966f08e585cebfe630c
-commit d0c4fa58594577994921b593f10037c5282597ca
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Aug 11 14:23:58 2022 +1000
+commit b3daa8dc582348d6ab8150bc1e571b7aa08c5388
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Jan 2 07:03:30 2023 +0000
- Rerun tests if any .github config file changes.
+ upstream: fix bug in PermitRemoteOpen which caused it to ignore its
+
+ first argument unless it was one of the special keywords "any" or "none".
+
+ Reported by Georges Chaudy in bz3515; ok dtucker@
+
+ OpenBSD-Commit-ID: c5678a39f1ff79993d5ae3cfac5746a4ae148ea5
-commit 113fe6c77ab43769fc61e953d07cb619fd7ea54b
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Aug 11 13:33:51 2022 +1000
+commit 0872663a7be0301bcc3d49acdbc9b740a3d972d4
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Mon Dec 26 19:16:03 2022 +0000
- Skip hostbased during Valgrind tests.
+ upstream: spelling fixes; from paul tagliamonte amendments to his
- Valgrind doesn't let ssh exec ssh-keysign (because it's setuid) so skip
- it during the Valgrind based tests.
+ diff are noted on tech
- See https://bugs.kde.org/show_bug.cgi?id=119404 for a discussion of this
- (ironically there the problematic binary was ssh(1) back when it could
- still be setuid).
+ OpenBSD-Commit-ID: d776dd03d0b882ca9c83b84f6b384f6f9bd7de4a
-commit b98a42afb69d60891eb0488935990df6ee571c4d
+commit 797da2812a71785b34890bb6eb44767a7d09cd34
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Aug 11 01:57:50 2022 +0000
+Date: Fri Dec 16 07:13:22 2022 +0000
- upstream: add some tests for parse_absolute_time(), including cases
+ upstream: Mention that scp uses the SFTP protocol and remove
- where it is forced to the UTC timezone. bz3468 ok dtucker
+ reference to legacy flag. Spotted by, feedback and ok jmc@
- OpenBSD-Regress-ID: ea07ca31c2f3847a38df028ca632763ae44e8759
+ OpenBSD-Commit-ID: 9dfe04966f52e941966b46c7a2972147f95281b3
-commit ec1ddb72a146fd66d18df9cd423517453a5d8044
+commit 93f2ce8c050a7a2a628646c00b40b9b53fef93ef
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Aug 11 01:56:51 2022 +0000
+Date: Fri Dec 16 06:56:47 2022 +0000
- upstream: allow certificate validity intervals, sshsig verification
+ upstream: Clear signal mask early in main(); sshd may have been
- times and authorized_keys expiry-time options to accept dates in the UTC time
- zone in addition to the default of interpreting them in the system time zone.
- YYYYMMDD and YYMMDDHHMM[SS] dates/times will be interpreted as UTC if
- suffixed with a 'Z' character.
+ started with one or more signals masked (sigprocmask(2) is not cleared
+ on fork/exec) and this could interfere with various things, e.g. the
+ login grace timer.
- Also allow certificate validity intervals to be specified in raw
- seconds-since-epoch as hex value, e.g. -V 0x1234:0x4567890. This
- is intended for use by regress tests and other tools that call
- ssh-keygen as part of a CA workflow.
+ Execution environments that fail to clear the signal mask before running
+ sshd are clearly broken, but apparently they do exist.
- bz3468 ok dtucker
+ Reported by Sreedhar Balasubramanian; ok dtucker@
- OpenBSD-Commit-ID: 454db1cdffa9fa346aea5211223a2ce0588dfe13
+ OpenBSD-Commit-ID: 77078c0b1c53c780269fc0c416f121d05e3010ae
-commit 4df246ec75751da7eb925e1880498300d8bda187
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Aug 11 10:23:55 2022 +1000
+commit 4acfaabfae41badb9d334a2ee88c5c6ad041c0d5
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Fri Dec 16 06:52:48 2022 +0000
- Fix conditional for running hostbased tests.
+ upstream: add -X to usage();
+
+ OpenBSD-Commit-ID: 1bdc3df7de11d766587b0428318336dbffe4a9d0
-commit 2580916e48721802220c61ce9e0df1297c00bc07
-Author: Damien Miller <djm@mindrot.org>
-Date: Thu Aug 11 08:58:28 2022 +1000
+commit e555d5cad5afae7d5ef2bbc02ca591178fe16fed
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Dec 16 03:40:03 2022 +0000
- fix SANDBOX_SECCOMP_FILTER_DEBUG
+ upstream: add a -X option to both scp(1) and sftp(1) to allow
+
+ control over some SFTP protocol knobs: the copy buffer length and
+ the number of inflight requests, both of which are used during
+ upload/download.
+
+ Previously these could be controlled in sftp(1) using the -b/-R options.
+ This makes them available in both SFTP protocol clients using the same
+ option character sequence.
+
+ ok dtucker@
+
+ OpenBSD-Commit-ID: 27502bffc589776f5da1f31df8cb51abe9a15f1c
-commit fdbd5bf507fc271ff813714fab8a72ff2c6cb5ca
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Aug 10 17:35:52 2022 +1000
+commit 5a7a7acab2f466dc1d7467b5d05d35268c3137aa
+Author: deraadt@openbsd.org <deraadt@openbsd.org>
+Date: Thu Dec 15 18:20:39 2022 +0000
- Test hostbased auth on github runners.
+ upstream: The idiomatic way of coping with signed char vs unsigned
+
+ char (which did not come from stdio read functions) in the presence of
+ ctype macros, is to always cast to (unsigned char). casting to (int)
+ for a "macro" which is documented to take int, is weird. And sadly wrong,
+ because of the sing extension risk.. same diff from florian
+
+ OpenBSD-Commit-ID: 65b9a49a68e22ff3a0ebd593f363e9f22dd73fea
-commit 7e2f51940ba48a1c0fae1107801ea643fa83c971
+commit b0b58222c7cc62efd8212c4fb65a545f58ebb22d
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Aug 10 17:25:24 2022 +1000
+Date: Mon Dec 19 18:49:51 2022 +1100
- Rename our getentropy to prevent possible loops.
+ Simply handling of SSH_CONNECTION PAM env var.
- Since arc4random seeds from getentropy, and we use OpenSSL for that
- if enabled, there's the possibility that if we build on a system that
- does not have getentropy then run on a system that does have it, then
- OpenSSL could end up calling our getentropy and getting stuck in a loop.
- Pointed out by deraadt@, ok djm@
+ Prompted by bz#3508: there's no need to cache the value of
+ sshpam_conninfo so remove the global. While there, add check of
+ return value from pam_putenv. ok djm@
-commit 7a01f61be8d0aca0e975e7417f26371495fe7674
+commit ed8444572ae684fdb892f97bae342c6cb6456f04
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Mon Aug 8 12:17:04 2022 +1000
+Date: Mon Dec 19 18:42:34 2022 +1100
- Actually put HAVE_STDINT_H around the stdint.h.
+ Add tests for LibreSSL 3.7.0 and OpenSSL 1.1.1s.
-commit 73541f29f0b50480da6c20dceb7a7191bd8ea7d3
+commit abb9a8aaddfcacbd12641f6e4f203da0fa85a287
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Mon Aug 8 10:30:34 2022 +1000
+Date: Sun Dec 18 21:36:25 2022 +1100
- Give unused param a name.
-
- Fixes builds on platforms that do have fido2 but don't have
- fido_dev_is_winhello.
-
-commit 2a108c0ea960381bd9b14ee0d84e818a23df4482
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Aug 5 05:01:40 2022 +0000
-
- upstream: don't prompt for FIDO passphrase before attempting to enroll
-
- the credential, just let the enroll operating fail and we'll attempt to get a
- PIN anyway. Might avoid some unneccessary PIN prompts.
-
- Part of GHPR#302 from Corinna Vinschen; ok dtucker@
-
- OpenBSD-Commit-ID: bd5342ffc353ee37d39617906867c305564d1ce2
+ Use sudo when resetting perms on directories.
-commit 2886975c0ad9244e60dc5e4be34fde3aa573a4b5
-Author: Corinna Vinschen <vinschen@redhat.com>
-Date: Fri Feb 11 14:33:41 2022 +0100
+commit 2f5664c5908d84697cbe91302d5d5c4d83cb2121
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sun Dec 18 21:19:33 2022 +1100
- sk_sign: set FIDO2 uv attribute explicitely for WinHello
-
- WinHello via libfido2 performs user verification by default.
- However, if we stick to that, there's no way to differentiate
- between keys created with or without "-O verify-required".
- Set FIDO2 uv attribute explicitely to FIDO_OPT_FALSE, then check
- if user verification has been requested.
+ Set group perms on regress dir.
- Signed-off-by: Corinna Vinschen <vinschen@redhat.com>
+ This ensures that the tests don't fail due to StrictMode checks.
-commit 242c044ab111a37aad3b0775727c36a4c5f0102c
-Author: Corinna Vinschen <vinschen@redhat.com>
-Date: Tue Feb 15 11:28:08 2022 +0100
+commit 137196300fc1540affadde880210f02ba6cb4abf
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sun Dec 18 21:13:42 2022 +1100
- check_sk_options: add temporary WinHello workaround
-
- Up to libfido 1.10.0, WinHello advertises "clientPin" rather
- than "uv" capability. This is fixed in 1.11.0. For the time
- being, workaround it here.
-
- Signed-off-by: Corinna Vinschen <vinschen@redhat.com>
+ Fetch regress logs from obj dir.
-commit 78774c08cc4b4997382975b0f414a86e06b6780c
-Author: Corinna Vinschen <vinschen@redhat.com>
-Date: Thu Feb 10 18:19:29 2022 +0100
+commit 5f93c4836527d9fda05de8944a1c7b4a205080c7
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Tue Dec 13 20:59:54 2022 +1100
- compat code for fido_dev_is_winhello()
-
- Signed-off-by: Corinna Vinschen <vinschen@redhat.com>
+ obsdsnap test VMs runs-on libvirt too.
-commit 3d3a932a019aedfb891e0779bb4990cd5008a390
+commit 8386886fb1ab7fda73069fb0db1dbe0e5a52f758
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Aug 5 13:12:27 2022 +1000
+Date: Tue Dec 13 20:55:37 2022 +1100
- Factor out getrnd() and rename to getentropy().
-
- Factor out the arc4random seeding into its own file and change the
- interface to match getentropy. Use native getentropy if available.
- This will make it easier to resync OpenBSD changes to arc4random.
- Prompted by bz#3467, ok djm@.
+ Run upstream obsdsnap tests on ephemeral runners.
-commit 9385d277b787403be9dfcb229cf372202496d2f3
+commit b6e01459b55ece85d7f296b2bc719d1841e1009e
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Aug 4 18:55:48 2022 +1000
+Date: Tue Dec 13 20:48:56 2022 +1100
- Include CHANNEL and FIDO2 libs in configure output
+ Move obsdsnap test VMs to ephemeral runners.
-commit 141535b904b6fba01724444f38193a8599201f82
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Aug 1 11:09:26 2022 +0000
+commit ea6fdf9a1aa71a411f7db218a986392c4fb55693
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Dec 9 18:00:21 2022 +1100
- upstream: avoid double-free in error path introduced in r1.70; report
-
- and fix based on GHPR#332 by v-rzh ok dtucker@
+ use calloc for allocating arc4random structs
- OpenBSD-Commit-ID: 3d21aa127b1f37cfc5bdc21461db369a663a951f
+ ok dtucker
-commit dba7099ffcba3ca07b3946f017ba6a4c3158d9b1
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Jul 27 18:40:12 2022 +1000
+commit 4403b62f5548e91389cb3339d26a9d0c4bb07b34
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Dec 9 00:22:29 2022 +0000
- Remove deprecated MacOS 10.15 runners.
+ upstream: Warn if no host keys for hostbased auth can be loaded.
+
+ OpenBSD-Commit-ID: 2a0a13132000cf8d3593133c1b49768aa3c95977
-commit 722a56439aa5972c830e4a9a724cf52aff4a950a
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Jul 27 18:31:14 2022 +1000
+commit a6183e25e3f1842e21999fe88bc40bb99b121dc3
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Dec 9 00:17:40 2022 +0000
- Move stale-configure check as early as possible.
+ upstream: Add server debugging for hostbased auth.
- We added a check in Makefile to catch the case where configure needs to
- be rebuilt, however this did not happen until a build was attempted in
- which case all of the work done by configure was wasted. Move this check
- to the start of configure to catch it as early as possible. ok djm@
+ auth_debug_add queues messages about the auth process which is sent to
+ the client after successful authentication. This also sends those to
+ the server debug log to aid in debugging. From bz#3507, ok djm@
+
+ OpenBSD-Commit-ID: 46ff67518cccf9caf47e06393e2a121ee5aa258a
-commit 099d6b56288b421ba38531d26dc1bd6bb685e311
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Jul 22 10:47:19 2022 +1000
+commit b85c3581c16aaf6e83b9a797c80705a56b1f312e
+Author: cheloha@openbsd.org <cheloha@openbsd.org>
+Date: Sun Dec 4 23:50:49 2022 +0000
- Move libcrypto into CHANNELLIBS.
+ upstream: remove '?' from getopt(3) loops
- This will result in sftp, sftp-server and scp no longer being linked
- against libcrypto. ok djm@
+ userspace: remove vestigial '?' cases from top-level getopt(3) loops
+
+ getopt(3) returns '?' when it encounters a flag not present in the in
+ the optstring or if a flag is missing its option argument. We can
+ handle this case with the "default" failure case with no loss of
+ legibility. Hence, remove all the redundant "case '?':" lines.
+
+ Prompted by dlg@. With help from dlg@ and millert@.
+
+ Link: https://marc.info/?l=openbsd-tech&m=167011979726449&w=2
+
+ ok naddy@ millert@ dlg@
+
+ OpenBSD-Commit-ID: b2f89346538ce4f5b33ab8011a23e0626a67e66e
-commit 1bdf86725b77733bb5f17c54888b88a10b2f6538
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Jul 22 10:45:47 2022 +1000
+commit 9a067e8d28a2249fd73f004961e30c113ee85e5d
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Wed Dec 7 11:45:43 2022 +0000
- Remove seed_rng calls from scp, sftp, sftp-server.
+ upstream: Fix comment typo.
- These binaries don't use OpenSSL's random functions. The next step
- will be to stop linking them against libcrypto. ok djm@
+ OpenBSD-Regress-ID: 3b04faced6511bb5e74648c6a4ef4bf2c4decf03
-commit d73f77b8cb9b422f1ac4facee7890aa10ff2bc21
+commit ce3c3e78ce45d68a82c7c8dc89895f297a67f225
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Jul 22 09:51:51 2022 +1000
+Date: Wed Dec 7 18:58:25 2022 +1100
- Group libcrypto and PRNGD checks together.
-
- They're related more than the libcrypt or libiaf checks which are
- currently between them. ok djm@
+ Add SANDBOX_DEBUG to the kitchensink test build.
-commit f117e372b3f42f2fbdb0a578d063b2609ab58e1f
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Jul 22 09:24:45 2022 +1000
+commit bc234605fa3eb10f56bf0d74c8ecb0d91ada9d05
+Author: Damien Miller <djm@mindrot.org>
+Date: Wed Dec 7 18:38:25 2022 +1100
- Do not link scp, sftp and sftp-server w/ zlib.
+ disable SANDBOX_SECCOMP_FILTER_DEBUG
- Some of our binaries (eg sftp, sftp-server, scp) do not interact with
- the channels code and thus do use libraries such as zlib and libcrypto
- although they are linked with them. This adds a CHANNELLIBS and starts
- by moving zlib into it, which means the aformentioned binaries are no
- longer linked against zlib. ok djm@
+ It was mistakenly enabled in 2580916e4872
+
+ Reported by Peter sec-openssh-com.22.fichtner AT 0sg.net
-commit 800c2483e68db38bd1566ff69677124be974aceb
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Mon Jul 25 21:49:04 2022 +1000
+commit b087c5cfa011b27992e01589314fec830266f99d
+Author: Rose <83477269+AtariDreams@users.noreply.github.com>
+Date: Tue Nov 29 15:12:54 2022 -0500
- Remove workarounds for OpenSSL missing AES-CTR.
+ Update autotools
- We have some compatibility hacks that were added to support OpenSSL
- versions that do not support AES CTR mode. Since that time, however,
- the minimum OpenSSL version that we support has moved to 1.0.1 which
- *does* have CTR, so this is no longer needed. ok djm@
+ Regenerate config files using latest autotools
-commit b7c56b65c12f51fe0dbae798d19c8f58224a5d95
+commit d63f5494978a185c7421d492b9c2f6f05bb54138
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Mon Jul 25 21:43:00 2022 +1000
+Date: Tue Dec 6 12:22:36 2022 +1100
- Remove workarounds for OpenSSL missing AES-GCM.
-
- We have some compatibility hacks that were added to support OpenSSL
- versions that do not support AES GCM mode. Since that time, however,
- the minimum OpenSSL version that we support has moved to 1.0.1 which
- *does* have GCM, so this is no longer needed. ok djm@
+ Fix typo in comment. Spotted by tim@
-commit 5a4a9f7a968fbf92cc1eac519c65638e79ae9f1f
+commit 73dcca12115aa12ed0d123b914d473c384e52651
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Mon Jul 25 07:12:45 2022 +0000
+Date: Sun Dec 4 11:03:11 2022 +0000
- upstream: Restore missing "!" in TEST_SSH_ELAPSED_TIMES test.
+ upstream: Remove duplicate includes.
- OpenBSD-Regress-ID: 38783f9676ec348c5a792caecee9a16e354b37b0
+ Patch from AtariDreams via github PR#364.
+
+ OpenBSD-Commit-ID: b9186638a05cb8b56ef7c0de521922b6723644ea
-commit 0ff886be132299386cc29d87c2aa16ff68a1aa08
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Sun Jul 24 23:29:10 2022 +0000
+commit 3cec15543010bc8d6997d896b1717a650afb7e92
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Dec 2 04:40:27 2022 +0000
- upstream: Test TEST_SSH_ELAPSED_TIMES for empty string not
+ upstream: make struct sshbuf private
- executable. No-op on most platforms but should prevent warnings in -portable
- on systems that don't have 'date %s'.
+ and remove an unused field; ok dtucker
- OpenBSD-Regress-ID: e39d79867b8065e33d0c5926fa1a31f85659d2a4
+ OpenBSD-Commit-ID: c7a3d77c0b8c153d463398606a8d57569186a0c3
-commit f69319ad8ad1dd50f90bbcf5912e11cc8ed3e037
+commit 5796bf8ca9535f9fa7d01829a540d2550e05c860
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Jul 23 14:38:22 2022 +1000
+Date: Fri Dec 2 11:43:36 2022 +1100
- Convert "have_prog" function into "which".
+ Restore ssh-agent permissions on exit.
- "which" and its behaviour is not standardized, so convert the existing
- have_prog function into "which" so we can rely on it being available
- and what its semantics are. Add a have_prog wrapper that maintains the
- existing behaviour.
+ ...enough that subsequent builds can overwrite ssh-agent if necessary.
-commit ea7ecc2c3ae39fdf5c6ad97b7bc0b47a98847f43
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Jul 23 14:36:38 2022 +1000
+commit ccf5a13868cbb4659107458cac1e017c98abcbda
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Thu Dec 1 02:22:13 2022 +0000
- Skip scp3 test if there's no scp on remote path.
+ upstream: Clean up ssh-add and ssh-agent logs.
- scp -3 ends up using the scp that's in the remote path and will fail if
- one is not available. Based on a patch from rapier at psc.edu.
+ OpenBSD-Regress-ID: 9eda8e4c3714d7f943ab2e73ed58a233bd29cd2c
-commit c46f6fed419167c1671e4227459e108036c760f8
-Author: Damien Miller <djm@mindrot.org>
-Date: Wed Jul 20 13:39:14 2022 +1000
+commit 7a8b40cf6a5eda80173140cc6750a6db8412fa87
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Thu Dec 1 02:19:29 2022 +0000
- crank SSH_SK_VERSION_MAJOR in sk-dummy.so
+ upstream: Log output of ssh-agent and ssh-add
+
+ This should make debugging easier.
+
+ OpenBSD-Regress-ID: 5974b02651f428d7e1079b41304c498ca7e306c8
-commit f208e3b9ffb5ee76cf9c95df7ff967adc7f51c7d
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Jul 20 03:33:22 2022 +0000
+commit 4a1805d532616233dd6072e5cd273b96dd3062e6
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Tue Nov 29 22:41:14 2022 +0000
- upstream: ssh-keygen: fix touch prompt, pin retries;
-
- part of GHPR329 from Pedro Martelletto
+ upstream: Add void to client_repledge args to fix compiler warning. ok djm@
- OpenBSD-Commit-ID: 75d1005bd2ef8f29fa834c90d2684e73556fffe8
+ OpenBSD-Commit-ID: 7e964a641ce4a0a0a11f047953b29929d7a4b866
-commit 8638a2ce7e90c8a51d9af3143404282126c524f8
+commit 815c4704930aa449edf6e812e99d69e9ffd31f01
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Jul 20 03:31:42 2022 +0000
+Date: Mon Nov 28 01:38:22 2022 +0000
- upstream: sk-usbhid: preserve error code returned by key_lookup()
+ upstream: tighten pledge(2) after session establishment
- it conveys useful information, such as the supplied pin being wrong.
-
- Part of GHPR329 from Pedro Martelletto
+ feedback, ok & testing in snaps deraadt@
- OpenBSD-Commit-ID: c0647eb9290f793add363d81378439b273756c1b
+ OpenBSD-Commit-ID: aecf4d49d28586dfbcc74328d9333398fef9eb58
-commit 9ab929ca2d820520327b41929372bcb9e261534c
+commit f7cebbbf407d772ed71403d314343766782fe540
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Jul 20 03:29:14 2022 +0000
+Date: Mon Nov 28 01:37:36 2022 +0000
- upstream: when enrolling a resident key on a security token, check
-
- if a credential with matching application and user ID strings already exists.
- if so, prompt the user for confirmation before overwriting the credential.
+ upstream: New EnableEscapeCommandline ssh_config(5) option
- patch from Pedro Martelletto via GHPR329
+ This option (default "no") controls whether the ~C escape is available.
+ Turning it off by default means we will soon be able to use a stricter
+ default pledge(2) in the client.
- NB. cranks SSH_SK_VERSION_MAJOR, so any third-party FIDO middleware
- implementations will need to adjust
+ feedback deraadt@ dtucker@; tested in snaps for a while
- OpenBSD-Commit-ID: e45e9f1bf2b2f32d9850669e7a8dbd64acc5fca4
+ OpenBSD-Commit-ID: 7e277595d60acb8263118dcb66554472257b387a
-commit 5bcfc788b38d5b64e4c347bdc04bd9a01bbc36da
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Jul 20 03:13:04 2022 +0000
+commit d323f7ecf52e3d4ec1f4939bf31693e02f891dca
+Author: mbuhl@openbsd.org <mbuhl@openbsd.org>
+Date: Fri Nov 18 19:47:40 2022 +0000
- upstream: pull passphrase reading and confirmation into a separate
+ upstream: In channel_request_remote_forwarding the parameters for
- function so it can be used for FIDO2 PINs; no functional change
+ permission_set_add are leaked as they are also duplicated in the call. Found
+ by CodeChecker. ok djm
- OpenBSD-Commit-ID: bf34f76b8283cc1d3f54633e0d4f13613d87bb2f
+ OpenBSD-Commit-ID: 4aef50fa9be7c0b138188814c8fe3dccc196f61e
-commit eb679e2959bdb15454eb94751930eb4c9110da94
+commit 62cc33e6eed847aafdc29e34aa69e9bd82a0ee16
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Jul 15 21:31:48 2022 +1000
+Date: Wed Nov 30 11:23:11 2022 +1100
- Move vmshutdown to first step.
+ Use -fzero-call-used-regs=used on clang 15.
- If a previous run on a physical runner has failed to clean up, the next
- run will fail because it'll try to check out the code to a broken
- directory mount. Make cleanup the first step.
+ clang 15 seems to have a problem with -fzero-call-used-reg=all which
+ causes spurious "incorrect signature" failures with ED25519. On those
+ versions, use -fzero-call-used-regs=used instead. (We may add exceptions
+ later if specific versions prove to be OK). Also move the GCC version
+ check to match.
+
+ Initial investigation by Daniel Pouzzner (douzzer at mega nu), workaround
+ suggested by Bill Wendling (morbo at google com). bz#3475, ok djm@
-commit 46b91b70ff3cb9c147e2875ef5dc609fd64c0c96
+commit f84b9cffd52c9c5c359a54a1929f9948e803ab1d
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Jul 15 20:25:27 2022 +1000
+Date: Mon Nov 28 21:09:28 2022 +1100
- Rename bbone test target to ARM.
+ Skip unit tests on slow riscv64 hardware.
-commit 751d22cdeffed9fe921db78eedc32a29f9e80510
+commit 9f2747e0bed3faca92679eae69aef10c95dc82f5
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Jul 15 13:37:29 2022 +1000
+Date: Sun Nov 27 15:26:22 2022 +1100
- Add AUDIT_ARCH_PPC to supported seccomp arches.
+ Rework how selfhosted tests interact with runners.
- Patch from dries.deschout at dodeco.eu.
+ Previously there was one runner per test target (mostly VMs). This had
+ a few limitations:
+ - multiple tests that ran on the same target (eg multiple build
+ configs) were serialized on availability or that runner.
+ - it needed manual balancing of VMs over host machines.
+
+ To address this, make VMs that use ephemeral disks (ie most of them)
+ all use a pool of runners with the "libvirt" label. This requires that
+ we distinguish between "host" and "target" for those. Native runners
+ and VMs with persistent disks (eg the constantly-updated snapshot ones)
+ specify the same host and target.
+
+ This should improve test throughput.
-commit a061792a6e8d235fc40a9b5d4c22a1762bb75a7b
+commit d664ddaec87bdc7385be8ef7f1337793e1679d48
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Jul 14 19:20:24 2022 +1000
+Date: Sun Nov 27 12:19:37 2022 +1100
- Remove unintended changes.
+ Run vmstartup from temp dir.
- I inadvertently included a couple of local changes with the OpenSSL
- 3.0.4 change. Revert, anything that should be there will be committed
- separately.
+ This will allow us to create ephemeral disk images per-runner.
-commit 527cb43fa1b4e55df661feabbac51b8e608b6519
+commit 0fa16e952b1fc1c4cf65e3dd138b0e87003e2e45
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Jul 14 11:22:08 2022 +1000
+Date: Sun Nov 27 12:14:00 2022 +1100
- Return ERANGE from getcwd() if buffer size is 1.
-
- If getcwd() is supplied a buffer size of exactly 1 and a path of "/", it
- could result in a nul byte being written out of array bounds. POSIX says
- it should return ERANGE if the path will not fit in the available buffer
- (with terminating nul). 1 byte cannot fit any possible path with its nul,
- so immediately return ERANGE in that case.
+ Make "config" in matrix singular and pass in env.
- OpenSSH never uses getcwd() with this buffer size, and all current
- (and even quite old) platforms that we are currently known to work
- on have a native getcwd() so this code is not used on those anyway.
- Reported by Qualys, ok djm@
+ This will allow the startup scripts to adapt their behaviour based on
+ the type and config.
-commit 36857fefd8849c4b0e877cfd9d1eb22f79b76650
+commit e8857043af54809187be1e8b06749db61112899f
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Jul 14 10:02:35 2022 +1000
+Date: Sun Nov 27 11:42:22 2022 +1100
- Split README.platform into its own line.
-
- README.platform has general platform-specific information, having it
- following text about FIDO2 on the same line could imply that it only
- has information about FIDO2.
+ Add "libvirt" label to dfly30.
-commit 00a496c6c14f2d41f2a9365714d494dd5f3aac9f
+commit 9775473d84902dc37753686cd10ae71fbe67efda
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Jul 14 09:56:01 2022 +1000
+Date: Sun Nov 27 09:28:20 2022 +1100
- Clarify README.md text.
+ Rename "os" in matrix to "target".
- Clarify the text about the implications of building without OpenSSL, and
- prefix the "configure --help" example command with a "./" so it's likely
- to work as-is in more shells. From bz#3461.
+ This is in preparation to distinguish this from the host that the runner
+ runs on in case where they are separate (eg VMs).
-commit f40b52f21fbc52eb513279168a49d3285c65256c
+commit 04fd00ceff39f4544ced6f5342060abe584835d0
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Tue Jul 12 19:48:44 2022 +1000
+Date: Sun Nov 27 09:23:04 2022 +1100
- Remove special casing of crypt().
+ Remove unused self-hosted test targets.
+
+commit c9d9fcad2a11c1cd1550a541f44091d65f0b5584
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sun Nov 27 09:16:15 2022 +1100
+
+ Remove explicit "default" test config argument.
- Configure goes to some lengths to pick crypt() from either libcrypt
- or OpenSSL's libcrypto because they can more or less featureful (eg
- supporting md5-style passwords).
-
- OpenSSL removed its crypt() interface in 2002:
- https://github.com/openssl/openssl/commit/69deec58 so these hijinks
- should no longer be necessary. This also only links sshd with libcrypt
- which is the only thing that needs it. ok djm@
-
-commit 76f4e48631d7b09fb243b47d7b393d100d3741b7
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Jul 13 13:17:47 2022 +1000
-
- Only refuse to use OpenSSL 3.0.4 on x86_64.
-
- The potential RCE only impacts x86_64, so only refuse to use it if we're
- targetting a potentially impacted architecture. ok djm@
+ Not specifying the test config implicitly selects default args.
-commit e75bbc1d88491fa85e61b2cc8783d4bbd00cd131
+commit 15a01cf15f396f87c6d221c5a6af98331c818962
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Tue Jul 12 14:37:15 2022 +1000
+Date: Wed Nov 23 13:18:54 2022 +1100
- Capture stderr output from configure.
+ Add fallback for old platforms w/out MAP_ANON.
-commit d9eaea4bea6271bcee6a2b9428f1271faf2d033b
+commit 6b9bbbfe8b26db6e9a30a7e08c223e85421aed98
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Tue Jul 12 12:54:49 2022 +1000
+Date: Wed Nov 23 13:09:11 2022 +1100
- Refuse to use OpenSSL 3.0.4 due to potential RCE.
+ If we haven't found it yet, recheck for sys/stat.h.
- OpenSSL has a potential RCE in its RSA implementation (CVE-2022-2274)
- so refuse to use that specific version.
+ On some very old platforms, sys/stat.h needs sys/types.h, however
+ autoconf 2.71's AC_CHECK_INCLUDES_DEFAULT checks for them in the
+ opposite order, which in combination with modern autoconf's
+ "present but cannot be compiled" behaviour causes it to not be
+ detected.
-commit fb2f3a61bf3d28fff285524535f7ffcd177c9235
+commit 8926956f22639132a9f2433fcd25224e01b900f5
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Tue Jul 12 12:54:24 2022 +1000
+Date: Fri Nov 11 11:25:37 2022 +1100
- Move unset to before we set anything.
+ Add dfly62 test target.
-commit c483a5c0fb8e8b8915fad85c5f6113386a4341ca
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Jul 6 11:52:54 2022 +1000
+commit 650de7ecd3567b5a5dbf16dd1eb598bd8c20bca8
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Thu Nov 10 23:03:10 2022 +0000
- Test against openssl-3.0.5.
+ upstream: Handle dynamic remote port forwarding in escape commandline's
+
+ -R processing. bz#3499, ok djm@
+
+ OpenBSD-Commit-ID: 194ee4cfe7ed0e2b8ad0727f493c798a50454208
-commit 669a56bcfe73f8b985f2bba476ba834d55253acf
+commit 5372db7e7985ba2c00f20fdff8942145ca99e033
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Tue Jul 5 18:35:53 2022 +1000
+Date: Thu Nov 10 12:44:51 2022 +1100
- Update sanitizer test targets:
+ Remove seed passing over reexec.
- - remove clang-sanitize-memory for now. It takes so long that the test
- times out.
- - add gcc sanitize-address and sanitize-undefined test targets.
+ This was added for the benefit of platforms using ssh-rand-helper to
+ prevent a delay on each connection as sshd reseeded itself.
+
+ ssh-random-helper is long gone, and since the re-exec happens before the
+ chroot the re-execed sshd can reseed itself normally. ok djm@
-commit 48cc68b69118b3ce8d07fd4f82e00d58667d5379
+commit ca98d3f8c64cfc51af81e1b01c36a919d5947ec2
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Tue Jul 5 16:23:28 2022 +1000
+Date: Wed Nov 9 20:59:20 2022 +1100
- Add GCC address sanitizer build/test.
+ Skip reexec test on OpenSSL 1.1.1 specifically.
+
+ OpenSSL 1.1.1 has a bug in its RNG that breaks reexec fallback, so skip
+ that test. See bz#3483 for details.
-commit 55c60bdd39b82457e92efa77da8d16cfa6a49391
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Tue Jul 5 12:02:33 2022 +1000
+commit 5ec4ebc2548e5f7f1b55b2a5cef5b67bdca8146f
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Wed Nov 9 09:04:12 2022 +0000
- Move sanitizer logs into regress for collection.
+ upstream: Fix typo in fatal error message.
+
+ Patch from vapier at chromium.org.
+
+ OpenBSD-Commit-ID: 8a0c164a6a25eef0eedfc30df95bfa27644e35cf
-commit 35ef2b3b6ef198f8574904a45780487ec2f17858
+commit e6abafe9a6d809422d3432b95b3f9747b0acaa71
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Mon Jul 4 09:10:31 2022 +0000
+Date: Wed Nov 9 09:01:52 2022 +0000
- upstream: Add TEST_REGRESS_CACHE_DIR.
+ upstream: Remove errant colon and simplify format
- If set, it is used to cache regress test names that have succeeded and
- skip those on a re-run.
+ string in error messages. Patch from vapier at chromium.org.
- OpenBSD-Regress-ID: a7570dd29a58df59f2cca647c3c2ec989b49f247
+ OpenBSD-Commit-ID: fc28466ebc7b74e0072331947a89bdd239c160d3
-commit 7394ed80c4de8b228a43c8956cf2fa1b9c6b2622
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sun Jul 3 21:46:44 2022 +1000
+commit db2027a687516f87c3fb141e87154bb3d8a7807c
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Nov 9 01:37:44 2022 +0000
- Add clang sanitizer tests.
+ upstream: rename client_global_hostkeys_private_confirm() to
+
+ client_global_hostkeys_prove_confirm(), as it handles the
+ "hostkeys-prove00@openssh.com" message; no functional change
+
+ OpenBSD-Commit-ID: 31e09bd3cca6eed26855b88fb8beed18e9bd026d
-commit bfce0e66b6017a9bfab450b9dc7d4b16f90de817
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sun Jul 3 18:14:09 2022 +1000
+commit 1c2be7c2004cf1abcd172fee9fe3eab57cd4c426
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Nov 9 00:15:59 2022 +0000
- Skip all rlimit tests when sandboxing disabled.
+ upstream: typo in comment
- The rlimit tests can hang when being run with some compiler sanitizers
- so skip all of them if sandbox=no.
+ OpenBSD-Commit-ID: 39c58f41e0f32d1ff31731fa6f5bbbc3ad25084a
-commit 6208d611520f9ea94d5369f9da404b709930029d
+commit cf1a9852d7fc93e4abc4168aed09529a57427cdc
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sun Jul 3 17:54:49 2022 +1000
+Date: Wed Nov 9 09:23:47 2022 +1100
- Move checks for pollfd.fd and nfds_t.
+ Defer seed_rng until after closefrom call.
- Move the checks for struct pollfd.fd and nfds_t to before the sandboxing
- checks. This groups all the sandbox checks together so we can skip them
- all when sandboxing is disabled.
+ seed_rng will initialize OpenSSL, and some engine providers (eg Intel's
+ QAT) will open descriptors for their own use. bz#3483, patch from
+ joel.d.schuetze at intel.com, ok djm@
-commit 322964f8f2e9c321e77ebae1e4d2cd0ccc5c5a0b
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Jul 1 05:08:23 2022 +0000
+commit dffa64480163fbf76af7e4fb62c26bb0dd6642aa
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Nov 9 08:27:47 2022 +1100
- upstream: Remove leftover line.
+ Fix comment text. From emaste at freebsd.org.
+
+commit d9df5689c29823ab830ec4f54c83c6cc3c0077ad
+Author: Pierre Ossman <ossman@cendio.se>
+Date: Wed Jul 6 13:52:10 2022 +0200
+
+ Avoid assuming layout of fd_set
- Remove extra line leftover from merge conflict. ok djm@
+ POSIX doesn't specify the internal layout of the fd_set object, so let's
+ not assume it is just a bit mask. This increases compatibility with
+ systems that have a different layout.
- OpenBSD-Commit-ID: 460e2290875d7ae64971a7e669c244b1d1c0ae2e
+ The assumption is also worthless as we already refuse to use file
+ descriptors over FD_SETSIZE anyway. Meaning that the default size of
+ fd_set is quite sufficient.
-commit 7ec81daad0e03a64e8d91c5590960c48c1a899a3
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jul 1 04:45:50 2022 +0000
+commit 419aa8a312e8d8f491933ca3d5933e602cb05aae
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Tue Nov 8 12:42:52 2022 +1100
- upstream: use consistent field names (s/char/byte)
+ Shutdown any VM before trying to check out repo.
- in format description
+ In the case where the previous run did not clean up, the checkout will
+ fail as it'll leave a stale mount.
+
+commit a32c07cbb78f65d8527642b96474a83b413f8108
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Tue Nov 8 11:33:25 2022 +1100
+
+ Run vm startup and shutdown from runner temp dir.
- OpenBSD-Commit-ID: 3de33572733ee7fcfd7db33d37db23d2280254f0
+ Should work even if the github workspace dir is on a stale sshfs mount.
-commit 32e82a392d9f263485effdd606ff5862d289a4a0
+commit 2b40a7dfcdb8e616155b9504145aa52b271455aa
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Jul 1 13:55:19 2022 +1000
+Date: Tue Nov 8 11:03:31 2022 +1100
- Skip select+rlimit check if sandboxing is disabled
+ Add valrind-5 test here too.
+
+commit 2ea03d1f6d0a05ee2b63ed2dc0f2d54f1e4655a1
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Tue Nov 8 09:21:10 2022 +1100
+
+ Update checkout and upload actions.
- It's not needed in that case, and the test can fail when being built
- with some compiler memory sanitizer flags. bz#3441
+ Update actions/checkout and actions/upload-artifact to main branch for
+ compatibility with node.js v16.
-commit 4be7184ebe2a2ccef175983517a35ee06766e1b4
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jul 1 03:52:57 2022 +0000
+commit 4e316ff0f18a118232bb9ac6512ee62773a9e8ea
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Tue Nov 8 09:17:04 2022 +1100
- upstream: bump up loglevel from debug to info when unable to open
+ Split out rekey test since it runs the longest.
+
+commit 21625a6424258a92a96a3bb73ae6aabc5ed8a6b4
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Mon Nov 7 10:09:28 2022 +0000
+
+ upstream: The IdentityFile option in ssh_config can also be used to
- authorized keys/principals file for errno != ENOENT; bz2042 ok dtucker
+ specify a public key file, as documented in ssh.1 for the -i option. Document
+ this also for IdentityFile in ssh_config.5, for documentation completeness.
+ From laalsaas at systemli.org via portable github PR#352, ok jmc@ djm@
- OpenBSD-Commit-ID: e79aa550d91ade6a80f081bda689da24c086d66b
+ OpenBSD-Commit-ID: 2f943be9f96e60ef81a9a4faa25b009999f9883b
-commit 6c31ba10e97b6953c4f325f526f3e846dfea647a
+commit 747691604d3325ed2b62bad85b6fd8563ad32f6c
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Jul 1 03:39:44 2022 +0000
+Date: Mon Nov 7 10:05:38 2022 +0000
- upstream: Don't leak the strings allocated by order_hostkeyalgs()
-
- and list_hostkey_types() that are passed to compat_pkalg_proposal(). Part of
- github PR#324 from ZoltanFridrich, ok djm@
+ upstream: Remove some set but otherwise unused variables, spotted
- This is a roll-forward of the previous rollback now that the required
- changes in compat.c have been done.
+ in -portable by clang 16's -Wunused-but-set-variable. ok djm@
- OpenBSD-Commit-ID: c7cd93730b3b9f53cdad3ae32462922834ef73eb
+ OpenBSD-Commit-ID: 3d943ddf2369b38fbf89f5f19728e7dc1daf3982
-commit 486c4dc3b83b4b67d663fb0fa62bc24138ec3946
+commit 1d78d25653805aefc7a8dd9d86cd7359ada3823c
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Jul 1 03:35:45 2022 +0000
+Date: Mon Nov 7 10:02:59 2022 +0000
- upstream: Always return allocated strings from the kex filtering so
+ upstream: Check for and disallow MaxStartups values less than or
- that we can free them later. Fix one leak in compat_kex_proposal. Based on
- github PR#324 from ZoltanFridrich with some simplications by me. ok djm@
+ equal to zero during config parsing, rather than faling later at runtime.
+ bz#3489, ok djm@
- OpenBSD-Commit-ID: 9171616da3307612d0ede086fd511142f91246e4
+ OpenBSD-Commit-ID: d79c2b7a8601eb9be493629a91245d761154308b
-commit 96faa0de6c673a2ce84736eba37fc9fb723d9e5c
+commit a00f59a645072e5f5a8d207af15916a7b23e2642
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jul 1 00:36:30 2022 +0000
+Date: Mon Nov 7 04:04:40 2022 +0000
- upstream: ignore SIGPIPE earlier in main(), specifically before
+ upstream: fix parsing of hex cert expiry time; was checking whether the
- muxclient() which performs operations that could cause one; Reported by Noam
- Lewis via bz3454, ok dtucker@
+ start time began with "0x", not the expiry time.
- OpenBSD-Commit-ID: 63d8e13276869eebac6d7a05d5a96307f9026e47
+ from Ed Maste
+
+ OpenBSD-Commit-ID: 6269242c3e1a130b47c92cfca4d661df15f05739
-commit 33efac790f6b09d54894ba6c3e17dfb08b6fc7e1
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Tue Jun 28 06:09:14 2022 +0000
+commit f58acaf8c7315483f4ac87d46a1aa2142a713cd8
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Nov 7 15:10:59 2022 +1100
- upstream: reflect the update to -D arg name in usage();
-
- OpenBSD-Commit-ID: abdcde4f92b1ef094ae44210ee99d3b0155aad9c
+ Fix merge conflict.
-commit c71a1442d02f0a3586109dfe2cb366de36dee08e
+commit 162e5741020a8d996c0c12b988b118e71ed728e6
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Jun 29 18:28:47 2022 +1000
+Date: Mon Nov 7 15:04:33 2022 +1100
- Update OpenSSL tests to the most recent releases.
+ Branch-specific links for master status badges.
-commit 2a822f29300b2de7335fbff65f0b187a0c582304
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Jun 27 21:41:55 2022 +0000
+commit e4b7c12ab24579312aa3ed38ce7041a439ec2d56
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Nov 7 14:46:38 2022 +1100
- upstream: allow arguments to sftp -D option, e.g. sftp -D
-
- "/usr/libexec/sftp-server -el debug3"
-
- ok markus@
+ Add CIFuzz status badge.
+
+commit b496b9f831acd1e5bcd875e26e797488beef494a
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Nov 7 14:45:16 2022 +1100
+
+ Do not run CIFuzz on selfhosted tree.
- OpenBSD-Commit-ID: 5a002b9f3a7aef2731fc0ffa9c921cf15f38ecce
+ We already run it on the regular tree, no need to double up.
-commit 2369a2810187e08f2af5d58b343956062fb96ee8
+commit 2138b1c4ddb300129a41a5104627b0d561184c7b
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Nov 7 14:41:58 2022 +1100
+
+ Whitespace change to trigger CIFuzz workflow.
+
+commit 4670b97ef87c7b0f21283c9b07c7191be88dda05
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Nov 7 14:34:04 2022 +1100
+
+ Run cifuzz workflow on the actions as regular CI.
+
+commit 79391e66ce851ace1baf3c6a35e83a23f08ec2ba
+Author: David Korczynski <david@adalogics.com>
+Date: Tue Nov 30 11:45:20 2021 +0000
+
+ Add CIFuzz integration
+
+commit c1893364a0be243270014d7d34362a8101d55112
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Jun 24 10:45:06 2022 +0000
+Date: Mon Nov 7 02:21:22 2022 +0000
- upstream: Roll back previous KEX changes as they aren't safe until
-
- compat_pkalg_proposal and friends always allocate their returned strings.
- Reported by Qualys.
+ upstream: Import regenerated moduli.
- OpenBSD-Commit-ID: 1c7a88a0d5033f42f88ab9bec58ef1cf72c81ad0
+ OpenBSD-Commit-ID: b0e54ee4d703bd6929bbc624068666a7a42ecb1f
-commit 646686136c34c2dbf6a01296dfaa9ebee029386d
+commit 5c3f18fb994ef27e685b205ee2351851b80fdbd1
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Jun 24 04:37:00 2022 +0000
+Date: Mon Nov 7 01:53:01 2022 +0000
- upstream: Don't leak the strings allocated by order_hostkeyalgs()
+ upstream: Fix typo. From pablomh via -portable github PR#344.
- and list_hostkey_types() that are passed to compat_pkalg_proposal(). Part of
- github PR#324 from ZoltanFridrich, ok djm@
-
- OpenBSD-Commit-ID: b2f6e5f60f2bba293b831654328a8a0035ef4a1b
+ OpenBSD-Commit-ID: d056ee2e73691dc3ecdb44a6de68e6b88cd93827
-commit 193c6d8d905dde836b628fc07a7b9cf2d347e2a3
+commit e1c6fcc142066417c9832e634463faa3dd5d116c
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Jun 25 12:16:15 2022 +1000
+Date: Mon Nov 7 12:46:58 2022 +1100
- Zero out LIBFIDO2 when SK support not usable.
-
- Prevents us from trying to link them into ssh-sk-helper and failing to
- build.
+ Link to branch-specific queries for V_9_1 status.
-commit 40f5d849d25c60b4ae21261e78484d435f5cfd51
+commit 4f4a5fad6d8892c3f8ee9cd81ec7de6458210c9f
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Jun 25 11:47:28 2022 +1000
+Date: Sun Nov 6 10:55:59 2022 +1100
- Disable SK support if FIDO libs not found.
+ Use "prohibit-password" in -portable comments.
+
+ "without-password" is the deprecated alias for "prohibit-password",
+ so we should reference the latter. From emaste at freebsd.org.
-commit 5fd922ade1b25880fe8a8249f5c0385e413108f9
-Author: Damien Miller <djm@mindrot.org>
-Date: Fri Jun 24 14:43:54 2022 +1000
+commit 0f7e1eba55259ec037f515000b4c4afbf446230a
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sun Nov 6 10:50:01 2022 +1100
- fix broken case statement in previous
+ Fix tracing disable on FreeBSD.
+
+ Some versions of FreeBSD do not support using id 0 to refer to the
+ current pid for procctl, so pass getpid() explicitly. From
+ emaste at freebsd.org.
-commit f51423bdaf0008d46b6af082bcfd7a22a87375f0
-Author: Damien Miller <djm@mindrot.org>
-Date: Fri Jun 24 14:40:42 2022 +1000
+commit 32fddb982fd61b11a2f218a115975a87ab126d43
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Nov 7 10:39:01 2022 +1100
- request 1.1x API compatibility for OpenSSL >=3.x
+ Fix setres*id checks to work with clang-16.
- idea/patch from Pedro Martelletto via GHPR#322; ok dtucker@
+ glibc has the prototypes for setresuid and setresgid behind _GNU_SOURCE,
+ and clang 16 will error out on implicit function definitions, so add
+ _GNU_SOURCE and the required headers to the configure checks. From
+ sam at @gentoo.org via bz#3497.
-commit 455cee8d6c2e4c48c5af9faead3599c49948411e
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jun 24 04:27:14 2022 +0000
+commit 12af712d116f42164bcfa56db901d06e4fa27199
+Author: Sam James <sam@gentoo.org>
+Date: Sun Nov 6 04:52:38 2022 +0000
- upstream: make it clear that RekeyLimit applies to both transmitted
+ configure.ac: Fix -Wstrict-prototypes
- and received data. GHPR#328 from Jan Pazdziora
+ Clang 16 now warns on this and it'll be removed in C23, so let's
+ just be future proof. It also reduces noise when doing general
+ Clang 16 porting work (which is a big job as it is). github PR#355.
- OpenBSD-Commit-ID: d180a905fec9ff418a75c07bb96ea41c9308c3f9
+ Signed-off-by: Sam James <sam@gentoo.org>
-commit 17904f05802988d0bb9ed3c8d1d37411e8f459c3
-Author: tobhe@openbsd.org <tobhe@openbsd.org>
-Date: Tue Jun 21 14:52:13 2022 +0000
+commit 40b0a5eb6e3edfa2886b60c09c7803353b0cc7f5
+Author: Sam James <sam@gentoo.org>
+Date: Sun Nov 6 04:47:35 2022 +0000
- upstream: Make sure not to fclose() the same fd twice in case of an
-
- error.
+ configure.ac: Add <pty.h> include for openpty
- ok dtucker@
+ Another Clang 16ish fix (which makes -Wimplicit-function-declaration
+ an error by default). github PR#355.
- OpenBSD-Commit-ID: e384c4e05d5521e7866b3d53ca59acd2a86eef99
+ See: 2efd71da49b9cfeab7987058cf5919e473ff466b
+ See: be197635329feb839865fdc738e34e24afd1fca8
-commit f29d6cf98c25bf044079032d22c1a57c63ab9d8e
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Sat Jun 18 02:17:16 2022 +0000
+commit 6b17e128879ec6cc32ca2c28b5d894b4aa72e32d
+Author: Rochdi Nassah <rochdinassah.1998@gmail.com>
+Date: Fri Oct 28 01:26:31 2022 +0100
- upstream: Don't attempt to fprintf a null identity comment. From
-
- Martin Vahlensieck via tech@.
-
- OpenBSD-Commit-ID: 4c54d20a8e8e4e9912c38a7b4ef5bfc5ca2e05c2
+ Fix broken zlib link.
-commit ad1762173bb38716a106e8979806149fd0f2753e
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Jun 17 01:00:03 2022 +0000
+commit 99500df246ccb736ddbdd04160dcc82165d81a77
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Nov 4 16:59:26 2022 +1100
- upstream: Log an error if pipe() fails while accepting a
-
- connection. bz#3447, from vincent-openssh at vinc17 net, ok djm@
+ Don't run openbsd-compat tests on Cygwin.
- OpenBSD-Commit-ID: 9d59f19872b94900a5c79da2d57850241ac5df94
+ Add "compat-tests" to the default TEST_TARGET so we can override as
+ necessary. Override TEST_TARGET for Cygwin as the tests don't currently
+ compile there.
-commit 9c59e7486cc8691401228b43b96a3edbb06e0412
-Author: Damien Miller <djm@mindrot.org>
-Date: Fri Jun 24 14:20:43 2022 +1000
+commit 3cae9f92a31897409666aa1e6f696f779759332b
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Nov 3 21:59:20 2022 +0000
- automatically enable built-in FIDO support
+ upstream: replace recently-added valid_domain() check for hostnames
- If libfido2 is found and usable, then enable the built-in
- security key support unless --without-security-key-builtin
- was requested.
+ going to known_hosts with a more relaxed check for bad characters; previous
+ commit broke address literals. Reported by/feedback from florian@
- ok dtucker@
+ OpenBSD-Commit-ID: 10b86dc6a4b206adaa0c11b58b6d5933898d43e0
-commit 7d25b37fb2a5ff4dadabcbdac6087a97479434f5
-Author: Damien Miller <djm@mindrot.org>
-Date: Fri Jun 24 13:46:39 2022 +1000
+commit 9655217231c9056200bea7ae2dffcc9c0c3eb265
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Nov 3 23:07:50 2022 +1100
- fix possible NULL deref when built without FIDO
+ Rerun tests on changes to Makefile.in in any dir.
+
+commit 3500f0405a3ab16b59a26f3508c4257a3fc3bce6
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Nov 3 23:04:08 2022 +1100
+
+ Link libssh into compat tests.
- Analysis/fix from kircher in bz3443; ok dtucker@
+ The cygwin compat code uses xmalloc, so add libssh.a so pick up that.
-commit f5ba85daddfc2da6a8dab6038269e02c0695be44
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Jun 15 16:08:25 2022 +0000
+commit ec59effcf65b8a4c85d47ff5a271123259dd0ab8
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Nov 3 21:44:23 2022 +1100
- upstream: make sure that UseDNS hostname lookup happens in the monitor
-
- and not in the pledge(2)'d unprivileged process; fixes regression caused by
- recent refactoring spotted by henning@
-
- OpenBSD-Commit-ID: a089870b95101cd8881a2dff65b2f1627d13e88d
+ Fix compat regress to work with non-GNU make.
-commit acb2059febaddd71ee06c2ebf63dcf211d9ab9f2
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jun 3 04:47:21 2022 +0000
+commit 73550a218e7dfbbd599534cbf856309bc924f6fd
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Nov 3 13:41:16 2022 +1100
- upstream: move auth_openprincipals() and auth_openkeyfile() over to
-
- auth2-pubkeyfile.c too; they make more sense there.
+ Increase selfhosted job timeout.
- OpenBSD-Commit-ID: 9970d99f900e1117fdaab13e9e910a621b7c60ee
+ The default job timeout of 360 (6h) is not enough to complete the
+ regress tests for some of the slow VMs depending on the load on the host.
+ Increase to 600 (10h).
-commit 3d9b0845f34510111cc693bb99a667662ca50cd8
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jun 3 04:31:54 2022 +0000
+commit db97d8d0b90c6ce52b94b153d6f8f5f7d3b11777
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Nov 3 10:00:43 2022 +1100
- upstream: test setenv in both client and server, test first-match-wins
-
- too
-
- OpenBSD-Regress-ID: 4c8804f9db38a02db480b9923317457b377fe34b
+ Only run opensslver tests if built with OpenSSL.
-commit 22e1a3a71ad6d108ff0c5f07f93c3fcbd30f8b40
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jun 3 04:30:46 2022 +0000
+commit ba053709638dff2f6603df0c1f340352261d63ea
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Nov 2 14:16:04 2022 +1100
- upstream: Make SetEnv directives first-match-wins in both
-
- sshd_config and sshd_config; previously if the same name was reused then the
- last would win (which is the opposite to how the config is supposed to work).
-
- While there, make the ssh_config parsing more like sshd_config.
-
- bz3438, ok dtucker
-
- OpenBSD-Commit-ID: 797909c1e0262c0d00e09280459d7ab00f18273b
+ Add tests for OpenSSL 3.0.7 and LibreSSL 3.6.1.
-commit 38ed6c57e9e592c08e020fa6e82b45b4e1040970
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Jun 3 04:00:15 2022 +0000
+commit edd24101c7e17d1a8f6576e1aaf62233b47ad6f5
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Nov 3 08:17:39 2022 +1100
- upstream: Add missing *-sk types to ssh-keyscan manpage. From
+ Run compat regress tests too.
+
+commit fe88d67e7599b0bc73f6e4524add28d743e7f977
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Nov 3 08:14:05 2022 +1100
+
+ Compat tests need libcrypto.
- skazi0 via github PR#294.
+ This was moved to CHANNELLIBS during the libs refactor. Spotted by
+ rapier at psc.edu.
+
+commit 96b519726b7944eee3c23a54eee3d5c031ba1533
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Nov 3 04:24:39 2022 +1100
+
+ Include time.h when defining timegm.
- OpenBSD-Commit-ID: fda2c869cdb871f3c90a89fb3f985370bb5d25c0
+ Fixes build on some platforms eg recent AIX.
-commit ea97ec98c41ec2b755dfab459347db674ff9a5de
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Jun 3 03:21:09 2022 +0000
+commit da6038bd5cd55eb212eb2aec1fc8ae79bbf76156
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Tue Nov 1 19:10:30 2022 +1100
- upstream: Add period at end of "not known by any other names"
+ Always use compat getentropy.
- message. github PR#320 from jschauma, ok djm@
+ Have it call native getentropy and fall back as required. Should fix
+ issues of platforms where libc has getentropy but it is not implemented
+ in the kernel. Based on github PR#354 from simsergey.
+
+commit 5ebe18cab6be3247b44c807ac145164010465b82
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Nov 2 10:51:48 2022 +1100
+
+ Check for sockaddr_in.sin_len.
- OpenBSD-Commit-ID: bd60809803c4bfd3ebb7c5c4d918b10e275266f2
+ If found, set SOCK_HAS_LEN which is used in addr.c. Should fix keyscan
+ tests on platforms with this (eg old NetBSD).
-commit 88e376fcd67478ad1660d94bc73ab348ac9f4527
+commit a1febadf426536612c2734168d409147c392e7cf
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Jun 3 03:17:42 2022 +0000
+Date: Sun Oct 30 18:42:07 2022 +0000
- upstream: ssh-keygen -A: do not generate DSA keys by default.
+ upstream: Use variable for diff options
- Based on github PR#303 from jsegitz with man page text from jmc@, ok markus@
- djm@
+ instead of unconditionally specifying "-rN". This will make life easier
+ in -portable where not all diff's understand -N.
- OpenBSD-Commit-ID: 5c4c57bdd7063ff03381cfb6696659dd3f9f5b9f
+ OpenBSD-Regress-ID: 8b8a407115546be1c6d72d350b1e4f1f960d3cd3
-commit 6b3fb624675082a1e5aa615d1b8479873d8b5731
-Author: naddy@openbsd.org <naddy@openbsd.org>
-Date: Tue May 31 14:05:12 2022 +0000
+commit f6d3ed9a8a9280cbb68d6a499850cfe810e92bd0
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Oct 31 05:13:02 2022 +1100
- upstream: ssh-keygen: implement "verify-required" certificate option.
+ OpenSSL dev branch is 302 not 320.
- This was already documented when support for user-verified FIDO
- keys was added, but the ssh-keygen(1) code was missing.
+ While there, also accept 301 which it shat it was previously.
+
+commit 25c8a2bbcc10c493d27faea57c42a6bf13fa51f2
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Oct 28 02:47:04 2022 +0000
+
+ upstream: put sshkey_check_rsa_length() back in sshkey.c to unbreak
- ok djm@
+ OPENSSL=no builds
- OpenBSD-Commit-ID: f660f973391b593fea4b7b25913c9a15c3eb8a06
+ OpenBSD-Commit-ID: 99eec58abe382ecd14b14043b195ee1babb9cf6e
-commit b7f86ffc301be105bba9a3e0618b6fab3ae379bd
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Sat May 28 05:57:56 2022 +0000
+commit 1192588546c29ceec10775125f396555ea71850f
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Oct 28 02:29:34 2022 +0000
- upstream: keywords ref ssh_config.5;
+ upstream: allow ssh-keyscan(1) to accept CIDR address ranges, e.g.
- from caspar schutijser
+ ssh-keyscan 192.168.0.0/24
- OpenBSD-Commit-ID: f146a19d7d5c9374c3b9c520da43b2732d7d1a4e
+ If a CIDR range is passed, then it will be expanded to all possible
+ addresses in the range including the all-0s and all-1s addresses.
+
+ bz#976 feedback/ok markus@
+
+ OpenBSD-Commit-ID: ce6c5211f936ac0053fd4a2ddb415277931e6c4b
-commit dc7bc52372f2744fa39191577be5306ee57aacd4
+commit 64af4209309461c79c39eda2d13f9d77816c6398
Author: Damien Miller <djm@mindrot.org>
-Date: Mon May 30 09:29:09 2022 +1000
-
- fix some bugs in the fuzzer
-
-commit 1781f507c113667613351c19898efaf1e311a865
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri May 27 18:19:48 2022 +1000
-
- Test against OpenSSL 1.1.1o and 3.0.3.
-
-commit c53906e0c59e569691b4095d3e8db79cf78fa058
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri May 27 18:18:31 2022 +1000
+Date: Fri Oct 28 12:54:35 2022 +1100
- Test against LibreSSL 3.5.3.
+ fix merge botch
-commit 9b3ad432ad2f19319bcc089370e356c6315d682f
-Author: Damien Miller <djm@mindrot.org>
-Date: Fri May 27 17:00:43 2022 +1000
+commit 27267642699342412964aa785b98afd69d952c88
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Oct 28 00:44:44 2022 +0000
- fuzzer for authorized_keys parsing
+ upstream: refactor sshkey_private_deserialize
- mostly redundant to authopt_fuzz, but it's sensitive code so IMO it
- makes sense to test this layer too
+ feedback/ok markus@
+
+ OpenBSD-Commit-ID: f5ca6932fdaf840a5e8250becb38315a29b5fc9f
-commit c83d8c4d6f3ccceef84d46de107f6b71cda06359
+commit 2519a7077a9332f70935e5242ba91ee670ed6b87
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri May 27 05:02:46 2022 +0000
+Date: Fri Oct 28 00:44:17 2022 +0000
- upstream: split the low-level file handling functions out from
+ upstream: refactor sshkey_private_serialize_opt()
- auth2-pubkey.c
+ feedback/ok markus@
- Put them in a new auth2-pubkeyfile.c to make it easier to refer to them
- (e.g. in unit/fuzz tests) without having to refer to everything else
- pubkey auth brings in.
+ OpenBSD-Commit-ID: 61e0fe989897901294efe7c3b6d670cefaf44cbd
+
+commit 11a768adf98371fe4e43f3b06014024c033385d5
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Oct 28 00:43:30 2022 +0000
+
+ upstream: refactor certify
- ok dtucker@
+ feedback/ok markus@
- OpenBSD-Commit-ID: 3fdca2c61ad97dc1b8d4a7346816f83dc4ce2217
+ OpenBSD-Commit-ID: 35d742992e223eaca3537e6fb3d3002c08eed4f6
-commit 3b0b142d2a0767d8cd838e2f3aefde8a0aaa41e1
+commit 3fbc58bb249d967cc43ebdc554f6781bb73d4a58
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri May 27 05:01:25 2022 +0000
+Date: Fri Oct 28 00:43:08 2022 +0000
- upstream: refactor authorized_keys/principals handling
-
- remove "struct ssh *" from arguments - this was only used to pass the
- remote host/address. These can be passed in instead and the resulting
- code is less tightly coupled to ssh_api.[ch]
+ upstream: refactor sshkey_sign() and sshkey_verify()
- ok dtucker@
+ feedback/ok markus@
- OpenBSD-Commit-ID: 9d4373d013edc4cc4b5c21a599e1837ac31dda0d
+ OpenBSD-Commit-ID: 368e662c128c99d05cc043b1308d2b6c71a4d3cc
-commit 2c334fd36f80cb91cc42e4b978b10aa35e0df236
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri May 27 04:29:40 2022 +0000
+commit a1deb6cdbbe6afaab74ecb08fcb62db5739267be
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Oct 28 00:41:52 2022 +0000
- upstream: f sshpkt functions fail, then password is not cleared
+ upstream: refactor sshkey_from_blob_internal()
- with freezero. Unconditionally call freezero to guarantee that password is
- removed from RAM.
-
- From tobias@ and c3h2_ctf via github PR#286, ok djm@
+ feedback/ok markus@
- OpenBSD-Commit-ID: 6b093619c9515328e25b0f8093779c52402c89cd
+ OpenBSD-Commit-ID: 1f46c0cbb8060ee9666a02749594ad6658c8e283
-commit 5d3a77f4c5ae774c6796387266503f52c7cdc7c2
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri May 27 04:27:49 2022 +0000
+commit 7d00799c935271ce89300494c5677190779f6453
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Oct 28 00:41:17 2022 +0000
- upstream: Avoid kill with -1 argument. The out_ctx label can be
-
- reached before fork has been called. If this happens, then kill -1 would be
- called, sending SIGTERM to all processes reachable by the current process.
+ upstream: refactor sshkey_from_private()
- From tobias@ and c3h2_ctf via github PR#286, ok djm@
+ feedback/ok markus@
- OpenBSD-Commit-ID: 6277af1207d81202f5daffdccfeeaed4c763b1a8
+ OpenBSD-Commit-ID: e5dbe7a3545930c50f70ee75c867a1e08b382b53
-commit 533b31cd08e4b97f455466f91c36915e2924c15a
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri May 27 04:13:24 2022 +0000
+commit 262647c2e920492ca57f1b9320d74f4a0f6e482b
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Oct 28 00:39:29 2022 +0000
- upstream: Note that ProxyJump also accepts the same tokens as
+ upstream: factor out key generation
- ProxyCommand. From pallxk via github PR#305.
+ feedback/ok markus@
- OpenBSD-Commit-ID: 7115ac351b129205f1f1ffa6bbfd62abd76be7c5
+ OpenBSD-Commit-ID: 5b4211bff4de8d9adb84bc72857a8c42c44e7ceb
-commit 9d8c80f8a304babe61ca28f2e3fb5eb6dc9c39bf
+commit 401c74e7dc15eab60540653d2f94d9306a927bab
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed May 25 06:03:44 2022 +0000
+Date: Fri Oct 28 00:38:58 2022 +0000
- upstream: revert previous; it was broken (spotted by Theo)
+ upstream: refactor and simplify sshkey_read()
- OpenBSD-Commit-ID: 457c79afaca2f89ec2606405c1059b98b30d8b0d
+ feedback/ok markus@
+
+ OpenBSD-Commit-ID: 0d93b7a56e31cd06a8bb0d2191d084ce254b0971
-commit 9e0d02ef7ce88b67643bfb1c2272c9f5f04cc680
+commit 591fed94e66a016acf87f4b7cd416ce812f2abe8
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed May 25 00:31:13 2022 +0000
+Date: Fri Oct 28 00:37:24 2022 +0000
- upstream: make SSHBUF_DBG/SSHBUF_TELL (off by default and only enabled
+ upstream: factor out public key serialization
- via #define) dump to stderr rather than stdout
+ feedback/ok markus@
- OpenBSD-Commit-ID: 10298513ee32db8390aecb0397d782d68cb14318
+ OpenBSD-Commit-ID: a3570c4b97290c5662890aea7328d87f55939033
-commit 2487163630f28be28b7e2396b4bd6511b98f1d3e
-Author: Tim Rice <tim@multitalents.net>
-Date: Tue May 24 10:21:25 2022 -0700
+commit 1e78844ae2b2dc01ba735d5ae740904c57e13685
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Oct 28 00:36:31 2022 +0000
- configure.ac: Add missing AC_DEFINE for caph_cache_tzdata test causing
- HAVE_CAPH_CACHE_TZDATA to be missing from config.h.in.
- Spotted by Bryan Drewery
+ upstream: factor out sshkey_equal_public()
+
+ feedback/ok markus@
+
+ OpenBSD-Commit-ID: 1368ba114cb37732fe6ec3d89c7e6d27ea6fdc94
-commit bedb93415b60db3dfd704a3d525e82adb14a2481
+commit 25de1c01a8b9a2c8ab9b1da22444a03e89c982de
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun May 15 23:48:07 2022 +0000
+Date: Fri Oct 28 00:35:40 2022 +0000
- upstream: regress test for in-place transfers and clobbering larger
+ upstream: begin big refactor of sshkey
- files with smaller ones; would have caught last regression in scp(1)
+ Move keytype data and some of the type-specific code (allocation,
+ cleanup, etc) out into each key type's implementation. Subsequent
+ commits will move more, with the goal of having each key-*.c file
+ owning as much of its keytype's implementation as possible.
- OpenBSD-Regress-ID: 19de4e88dd3a4f7e5c1618c9be3c32415bd93bc2
+ lots of feedback + ok markus@
+
+ OpenBSD-Commit-ID: 0f2b4334f73914344e9e5b3d33522d41762a57ec
-commit b4f0d719c2548cb74da509fb65f384dada4ebd37
-Author: anton@openbsd.org <anton@openbsd.org>
-Date: Fri Apr 22 05:08:43 2022 +0000
+commit 445363433ba20b8a3e655b113858c836da46a1cb
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Oct 24 22:43:36 2022 +0000
- upstream: Only run agent-ptrace.sh if gdb is available as all
+ upstream: Be more paranoid with host/domain names coming from the
- architectures do not ship with gdb.
+ never write a name with bad characters to a known_hosts file.
- OpenBSD-Regress-ID: ec53e928803e6b87f9ac142d38888ca79a45348d
+ reported by David Leadbeater, ok deraadt@
+
+ OpenBSD-Commit-ID: ba9b25fa8b5490b49398471e0c9657b0cbc7a5ad
-commit 9b73345f80255a7f3048026462f2c0c6a241eeac
+commit 7190154de2c9fe135f0cc1ad349cb2fa45152b89
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun May 15 23:47:21 2022 +0000
+Date: Mon Oct 24 21:52:50 2022 +0000
- upstream: fix in-place copies; r1.163 incorrectly skipped truncation in
+ upstream: regress test for unmatched glob characters; fails before
- all cases, not just at the start of a transfer. This could cause overwrites
- of larger files to leave junk at the end. Spotted by tb@
+ previous commit but passes now. bz3488; prodded by dtucker@
- OpenBSD-Commit-ID: b189f19cd68119548c8e24e39c79f61e115bf92c
+ OpenBSD-Regress-ID: 0cc5cc9ea4a6fd170dc61b9212f15badaafb3bbd
-commit 56a0697fe079ff3e1ba30a2d5c26b5e45f7b71f8
+commit a4821a592456c3add3cd325db433110cdaaa3e5c
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri May 13 06:31:50 2022 +0000
+Date: Mon Oct 24 21:51:55 2022 +0000
- upstream: arrange for scp, when in sftp mode, to not ftruncate(3) files
+ upstream: when scp(1) is using the SFTP protocol for transport (the
- early
+ default), better match scp/rcp's handling of globs that don't match the
+ globbed characters but do match literally (e.g. trying to transfer
+ "foo.[1]").
- previous behavious of unconditionally truncating the destination file
- would cause "scp ~/foo localhost:" and "scp localhost:foo ~/" to
- delete all the contents of their destination.
+ Previously scp(1) in SFTP mode would not match these pathnames but
+ legacy scp/rcp mode would.
- spotted by solene@ sthen@, also bz3431; ok dtucker@
+ Reported by Michael Yagliyan in bz3488; ok dtucker@
- OpenBSD-Commit-ID: ca39fdd39e0ec1466b9666f15cbcfddea6aaa179
+ OpenBSD-Commit-ID: d8a3773f53015ba811fddba7473769a2fd343e11
-commit fbcef70c2832712f027bccea1aa9bc4b4103da93
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Mon May 9 08:25:27 2022 +0000
+commit 18376847b8043ba967eabbe23692ef74c9a3fddc
+Author: jsg@openbsd.org <jsg@openbsd.org>
+Date: Thu Oct 13 09:09:28 2022 +0000
- upstream: Remove errant apostrophe. From haruyama at queen-ml org.
+ upstream: use correct type with sizeof ok djm@
- OpenBSD-Commit-ID: dc6b294567cb84b384ad6ced9ca469f2bbf0bd10
+ OpenBSD-Commit-ID: d6c882c2e8a42ff831a5b3cbc2c961ecb2dd6143
-commit 0086a286ea6bbd11ca9b664ac3bb12b27443d6eb
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon May 9 03:09:53 2022 +0000
+commit 4a4883664d6b4e9e4e459a8cdc16bd8d4b735de9
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Fri Oct 7 06:00:58 2022 +0000
- upstream: Allow existing -U (use agent) flag to work with "-Y sign"
+ upstream: ssh-agent.1: - use Nm not Xr for self-ref - while here,
- operations, where it will be interpreted to require that the private keys is
- hosted in an agent; bz3429, suggested by Adam Szkoda; ok dtucker@
+ wrap a long line
- OpenBSD-Commit-ID: a7bc69873b99c32c42c7628ed9ea91565ba08c2f
+ ssh-agent.c:
+ - add -O to usage()
+
+ OpenBSD-Commit-ID: 855dac4695cef22e96d69c53436496bc408ca389
-commit cb010744cc98f651b1029bb09efa986eb54e4ccf
+commit 9fd2441113fce2a83fc7470968c3b27809cc7f10
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun May 8 22:58:35 2022 +0000
+Date: Fri Oct 7 04:06:26 2022 +0000
- upstream: improve error message when 'ssh-keygen -Y sign' is unable to
+ upstream: document "-O no-restrict-websafe"; spotted by Ross L
- load a private key; bz3429, reported by Adam Szkoda ok dtucker@
+ Richardson
- OpenBSD-Commit-ID: bb57b285e67bea536ef81b1055467be2fc380e74
+ OpenBSD-Commit-ID: fe9eaa50237693a14ebe5b5614bf32a02145fe8b
-commit aa61fc82c63d309a90c22ca74fb1da6c6f4372fd
-Author: Tobias Heider <me@tobhe.de>
-Date: Mon May 9 02:00:01 2022 +0200
+commit 614252b05d70f798a0929b1cd3d213030ad4d007
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Tue Oct 18 06:29:16 2022 +1100
- Remove duplicate bcrypt_pbkdf.o from Makefile
-
- bcrypt_pbkdf.o is duplicated in the openbsd-compat Makefile's object
- file list.
+ OpenSSL dev branch now identifies as 3.2.0.
-commit deb506d00da8d11fb04c1e7b9b1e1cc379c1705c
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun May 8 22:32:36 2022 +0000
+commit 195e5a65fd793a738ea8451ebfdd1919db5aff3e
+Author: Damien Miller <djm@mindrot.org>
+Date: Mon Oct 17 09:41:47 2022 +1100
- upstream: When performing operations that glob(3) a remote path, ensure
-
- that the implicit working directory used to construct that path escapes
- glob(3) characters.
+ revert c64b62338b4 and guard POLL* defines instead
- This prevents glob characters from being processed in places they
- shouldn't, e.g. "cd /tmp/a*/", "get *.txt" should have the get operation
- treat the path "/tmp/a*" literally and not attempt to expand it.
+ c64b62338b4 broke OSX builds, which do have poll.h but lack ppoll(2)
+ Spotted by dtucker
+
+commit bc2e480d99613bd59720edae244d1764636544c4
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Oct 14 14:52:22 2022 +1100
+
+ undef _get{short,long} before redefining
+
+commit 5eb796a369c64f18d55a6ae9b1fa9b35eea237fb
+Author: Harmen Stoppels <harmenstoppels@gmail.com>
+Date: Thu Oct 13 16:08:46 2022 +0200
+
+ Fix snprintf configure test for clang 15
- Reported by Lusia Kundel; ok markus@
+ Clang 15 -Wimplicit-int defaults to an error in C99 mode and above.
+ A handful of tests have "main(..." and not "int main(..." which caused
+ the tests to produce incorrect results.
+
+commit c64b62338b46ffa08839f05f21ad69fa6234dc17
+Author: Damien Miller <djm@mindrot.org>
+Date: Mon Oct 10 12:32:43 2022 +1100
+
+ skip bsd-poll.h if poll.h found; ok dtucker
+
+commit 5ee2b8ccfcf4b606f450eb0ff2305e311f68b0be
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Oct 6 22:42:37 2022 +0000
+
+ upstream: honour user's umask if it is more restrictive then the ssh
- OpenBSD-Commit-ID: 4f647f58482cbad3d58b1eab7f6a1691433deeef
+ default (022); based on patch from Alex Henrie, ok dtucker@ deraadt@
+
+ OpenBSD-Commit-ID: fe1b9e15fc9a4f49fc338e848ce14d8727abe82d
-commit f38cf74f20b5da113cfa823afd5bfb5c6ba65f3d
+commit a75cffc2700cebd3e2dd9093f7f7388d2be95cb7
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri May 6 14:50:18 2022 +1000
+Date: Fri Oct 7 03:54:56 2022 +1100
- Also retest OpenBSD upstream on .yml changes.
+ Add LibreSSL 3.6.0 to test suite.
+
+ While there, bump OpenSSL to latest 1.1.1q release.
-commit f87a132800ba3710ab130d703448a31ef1128d77
+commit fcc0f0c0e96a30076683fea9a7c9eedc72931742
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri May 6 14:46:09 2022 +1000
+Date: Thu Oct 6 21:18:16 2022 +1100
- Note that, for now, we need variadic macros.
+ Add 9.1 branch to CI status page.
-commit 217b518e0f7c52c4b909e935141a55344c61e644
+commit ef211eee63821d894a8bf81f22bfba9f6899d0fe
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri May 6 14:39:34 2022 +1000
+Date: Tue Oct 4 23:20:23 2022 +1100
- Add ubsan minimal testcase on OpenBSD.
+ Test commits to all branches of portable.
- As suggested by djm@.
+ Only test OpenBSD upstream on commits to master since that's what it
+ tracks.
-commit 457dce2cfef6a48f5442591cd8b21c7e8cba13f8
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu May 5 01:04:14 2022 +0000
+commit fe646de03cafb6593ff4e4954bca9ec4b4b753a8
+Author: Damien Miller <djm@mindrot.org>
+Date: Wed Oct 5 03:47:26 2022 +1100
- upstream: sshkey_unshield_private() contains a exact duplicate of
-
- the code in private2_check_padding(). Pull private2_check_padding() up so the
- code can be reused. From Martin Vahlensieck, ok deraadt@
-
- OpenBSD-Commit-ID: 876884c3f0e62e8fd8d1594bab06900f971c9c85
+ whitespace at EOL
-commit 0e44db4d9cb313e68a59a44d27884af66c02356e
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu May 5 00:56:58 2022 +0000
+commit a6e1852d10c63a830196e82168dadd957aaf28ec
+Author: Damien Miller <djm@mindrot.org>
+Date: Wed Oct 5 03:40:01 2022 +1100
- upstream: channel_new no longer frees remote_name. So update the
-
- comment accordingly. As remote_name is not modified, it can be const as
- well. From Martin Vahlensieck
-
- OpenBSD-Commit-ID: e4e10dc8dc9f40c166ea5a8e991942bedc75a76a
+ mention libfido2 autodetection
-commit 37b62fd5caf19c85a48241535277cefff65adace
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu May 5 00:55:11 2022 +0000
+commit 7360c2c206f33d309edbaf64036c96fadf74d640
+Author: Damien Miller <djm@mindrot.org>
+Date: Wed Oct 5 03:37:36 2022 +1100
- upstream: mux.c: mark argument as const; from Martin Vahlensieck
+ remove mention of --with-security-key-builtin
- OpenBSD-Commit-ID: 69a1a93a55986c7c2ad9f733c093b46a47184341
+ it is enabled by default when libfido2 is installed
-commit f4e67c0ad259b4cf10177277a5827fa5545bac53
-Author: markus@openbsd.org <markus@openbsd.org>
-Date: Wed May 4 07:31:22 2022 +0000
+commit 0ffb46f2ee2ffcc4daf45ee679e484da8fcf338c
+Author: Damien Miller <djm@mindrot.org>
+Date: Tue Oct 4 01:51:42 2022 +1100
- upstream: make sure stdout is non-blocking; ok djm@
-
- OpenBSD-Commit-ID: 64940fffbd1b882eda2d7c8c7a43c79368309c0d
+ update .depend
-commit e5c036d2092c00bef395e9161dc5ce42d4be9565
-Author: florian@openbsd.org <florian@openbsd.org>
-Date: Tue May 3 07:42:27 2022 +0000
+commit 657e676ff696c7bb787bffb0e249ea1be3b474e1
+Author: Damien Miller <djm@mindrot.org>
+Date: Tue Oct 4 01:45:52 2022 +1100
- upstream: Add FIDO AUTHENTICATOR section and explain a bit how FIDO
-
- works. The wording came mostly from the 8.2 OpenSSH release notes, addapted
- to fit the man page. Then move the -O bits into the new section as is already
- done for CERTIFICATES and MODULI GENERATION. Finally we can explain the
- trade-offs of resident keys. While here, consistently refer to the FIDO
- thingies as "FIDO authenticators", not "FIDO tokens".
-
- input & OK jmc, naddy
-
- OpenBSD-Commit-ID: dd98748d7644df048f78dcf793b3b63db9ab1d25
+ update release notes URL
-commit 575771bf79bef7127be6aaccddc46031ea15529e
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Mon May 2 05:40:37 2022 +0000
+commit f059da2b29840c0f048448809c317ce2ae014da7
+Author: Damien Miller <djm@mindrot.org>
+Date: Tue Oct 4 01:45:41 2022 +1100
- upstream: remove an obsolete rsa1 format example from an example;
-
- from megan batty
- ok djm
-
- OpenBSD-Commit-ID: db2c89879c29bf083df996bd830abfb1e70d62bf
+ crank versions in RPM spec files
-commit 0bc6b4c8f04e292577bdb44d5dc6b630d3448087
+commit b51f3f172d87cbdb80ca4eb7b2149e56a7647557
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun May 1 23:20:30 2022 +0000
+Date: Mon Sep 26 22:18:40 2022 +0000
- upstream: fix some integer overflows in sieve_large() that show up when
+ upstream: openssh-9.1
- trying to generate modp groups > 16k bits. Reported via GHPR#306 by Bertram
- Felgenhauer, but fixed in a different way. feedback/ok tb@
+ OpenBSD-Commit-ID: 5a467b2ee81da01a86adf1ad93b62b1728494e56
+
+commit 4cf8d0c0f3030f594a238bab21a0695735515487
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Wed Sep 21 22:26:50 2022 +0000
+
+ upstream: Fix typo. From AlexanderStohr via github PR#343.
- OpenBSD-Commit-ID: 81cbc6dd3a21c57bd6fadea10e44afe37bca558e
+ OpenBSD-Commit-ID: a134c9b4039e48803fc6a87f955b0f4a03181497
-commit a45615cb172bc827e21ec76750de39dfb30ecc05
+commit 8179fed3264d5919899900ed8881d5f9bb57ca33
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Apr 29 04:55:07 2022 +0000
+Date: Mon Sep 19 21:39:16 2022 +0000
- upstream: be stricter in which characters will be accepted in
+ upstream: add RequiredRSASize to the list of keywords accepted by
- specifying a mask length; allow only 0-9. From khaleesicodes via GHPR#278; ok
- dtucker@
+ -o; spotted by jmc@
- OpenBSD-Commit-ID: e267746c047ea86665cdeccef795a8a56082eeb2
-
-commit 4835544d2dd31de6ffc7dba59f92093aea98155b
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Apr 30 10:56:41 2022 +1000
-
- Add Mac OS X 12 test target.
+ OpenBSD-Commit-ID: fe871408cf6f9d3699afeda876f8adbac86a035e
-commit 97a6a8b8c1f2da09712d0e72d0ef800e4edd34cd
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Apr 29 18:27:34 2022 +1000
+commit 5f954929e9f173dd1e279e07d0e8b14fa845814d
+Author: Damien Miller <djm@mindrot.org>
+Date: Mon Sep 19 20:59:34 2022 +1000
- Only run tests when source files change.
+ no need for glob.h here
- Also run tests on changes to V_9_0 branch.
+ it also causes portability problems
-commit 6d0392b9ff4b50a56ac5685d1b9392e2cd432ca3
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Apr 29 18:22:34 2022 +1000
+commit 03d94a47207d58b3db37eba4f87eb6ae5a63168a
+Author: Damien Miller <djm@mindrot.org>
+Date: Mon Sep 19 20:59:04 2022 +1000
- Remove now-empty int32_minmax.inc.
+ avoid Wuninitialized false positive in gcc-12ish
-commit af59463553b5ad52d3b42c4455ee3c5600158bb7
+commit 9d952529113831fb3071ab6e408d2726fd72e771
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Apr 29 03:24:30 2022 +0000
+Date: Mon Sep 19 10:46:00 2022 +0000
- upstream: mention that the helpers are used by ssh(1), ssh-agent(1)
+ upstream: use users-groups-by-id@openssh.com sftp-server extension
- and ssh-keygen(1). Previously only ssh(1) was mentioned. From Pedro
- Martelletto
+ (when available) to fill in user/group names for directory listings.
+ Implement a client-side cache of see uid/gid=>user/group names. ok markus@
- OpenBSD-Commit-ID: 30f880f989d4b329589c1c404315685960a5f153
+ OpenBSD-Commit-ID: f239aeeadfa925a37ceee36ee8b256b8ccf4466e
-commit 3e26b3a6eebcee27be177207cc0846fb844b7a56
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Apr 29 03:16:48 2022 +0000
+commit 8ff680368b0bccf88ae85d4c99de69387fbad7a6
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Sep 19 10:43:12 2022 +0000
- upstream: Don't leak SK device. Patch from Pedro Martelletto via
+ upstream: sftp client library support for
- github PR#316. ok djm@
+ users-groups-by-id@openssh.com; ok markus@
- OpenBSD-Commit-ID: 17d11327545022e727d95fd08b213171c5a4585d
+ OpenBSD-Commit-ID: ddb2f33a2da6349a9a89a8b5bcb9ca7c999394de
-commit 247082b5013f0d4fcae8f97453f2a2f01bcda811
+commit 488f6e1c582212c2374a4bf8cd1b703d2e70fb8b
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Apr 29 03:13:32 2022 +0000
+Date: Mon Sep 19 10:41:58 2022 +0000
- upstream: fix memleak on session-bind path; from Pedro Martelletto, ok
+ upstream: extend sftp-common.c:extend ls_file() to support supplied
- dtucker@
+ user/group names; ok markus@
- OpenBSD-Commit-ID: e85899a26ba402b4c0717b531317e8fc258f0a7e
+ OpenBSD-Commit-ID: c70c70498b1fdcf158531117e405b6245863bfb0
-commit e05522008092ceb86a87bdd4ad7878424315db89
+commit 74b77f7497dba3a58315c8f308883de448078057
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Apr 28 02:53:31 2022 +0000
+Date: Mon Sep 19 10:40:52 2022 +0000
- upstream: avoid printing hash algorithm twice; from lucas AT sexy.is
+ upstream: sftp-server(8): add a "users-groups-by-id@openssh.com"
- OpenBSD-Commit-ID: 9d24671e10a84141b7c504396cabad600e47a941
+ extension request that allows the client to obtain user/group names that
+ correspond to a set of uids/gids.
+
+ Will be used to make directory listings more useful and consistent
+ in sftp(1).
+
+ ok markus@
+
+ OpenBSD-Commit-ID: 7ebabde0bcb95ef949c4840fe89e697e30df47d3
-commit 0979e29356915261d69a9517a1e0aaade7c9fc75
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Wed Apr 27 11:08:55 2022 +0000
+commit 231a346c0c67cc7ca098360f9a554fa7d4f1eddb
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Sep 19 08:49:50 2022 +0000
- upstream: Add authfd path to debug output. ok markus@
+ upstream: better debugging for connect_next()
- OpenBSD-Commit-ID: f735a17d1a6f2bee63bfc609d76ef8db8c090890
+ OpenBSD-Commit-ID: d16a307a0711499c971807f324484ed3a6036640
-commit 67b7c784769c74fd4d6b147d91e17e1ac1a8a96d
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Tue Apr 26 07:41:44 2022 +0000
+commit 1875042c52a3b950ae5963c9ca3774a4cc7f0380
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Sep 17 10:34:29 2022 +0000
- upstream: Check sshauthopt_new() for NULL. bz#3425, from
+ upstream: Add RequiredRSASize for sshd(8); RSA keys that fall
- tessgauthier at microsoft.com. ok djm@
+ beneath this limit will be ignored for user and host-based authentication.
- OpenBSD-Commit-ID: af0315bc3e44aa406daa7e0ae7c2d719a974483f
+ Feedback deraadt@ ok markus@
+
+ OpenBSD-Commit-ID: 187931dfc19d51873df5930a04f2d972adf1f7f1
-commit d571314d14b919fbd7c84a61f9bf2065fc0a6841
-Author: millert@openbsd.org <millert@openbsd.org>
-Date: Wed Apr 20 16:00:25 2022 +0000
+commit 54b333d12e55e6560b328c737d514ff3511f1afd
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Sep 17 10:33:18 2022 +0000
- upstream: Remove unnecessary includes: openssl/hmac.h and
+ upstream: add a RequiredRSASize for checking RSA key length in
- openssl/evp.h. From Martin Vahlensieck.
+ ssh(1). User authentication keys that fall beneath this limit will be
+ ignored. If a host presents a host key beneath this limit then the connection
+ will be terminated (unfortunately there are no fallbacks in the protocol for
+ host authentication).
- OpenBSD-Commit-ID: a6debb5fb0c8a44e43e8d5ca7cc70ad2f3ea31c3
+ feedback deraadt, Dmitry Belyavskiy; ok markus@
+
+ OpenBSD-Commit-ID: 430e339b2a79fa9ecc63f2837b06fdd88a7da13a
-commit da8dddf8cc1f2516ff894b8183e83a7c5ba3ef80
-Author: millert@openbsd.org <millert@openbsd.org>
-Date: Wed Apr 20 15:59:18 2022 +0000
+commit 07d8771bacfefbcfb37fa8a6dc6103bcc097e0ab
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Sep 17 10:30:45 2022 +0000
- upstream: Add missing includes of stdlib.h and stdint.h. We need
+ upstream: Add a sshkey_check_rsa_length() call for checking the
- stdlib.h for malloc(3) and stdint.h for SIZE_MAX. Unlike the other xmss
- files, ssh-xmss.c does not include xmss_commons.h so ssh-xmss.c must include
- those headers itself. From Martin Vahlensieck
+ length of an RSA key; ok markus@
- OpenBSD-Commit-ID: 70e28a9818cee3da1be2ef6503d4b396dd421e6b
+ OpenBSD-Commit-ID: de77cd5b11594297eda82edc594b0d32b8535134
-commit fe9d87a6800a7a33be08f4d5ab662a758055ced2
-Author: millert@openbsd.org <millert@openbsd.org>
-Date: Wed Apr 20 15:56:49 2022 +0000
+commit 3991a0cf947cf3ae0f0373bcec5a90e86a7152f5
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Sep 17 10:11:29 2022 +0000
- upstream: Avoid an unnecessary xstrdup in rm_env() when matching
+ upstream: actually hook up restrict_websafe; the command-line flag
- patterns. Since match_pattern() doesn't modify its arguments (they are
- const), there is no need to make an extra copy of the strings in
- options->send_env. From Martin Vahlensieck
+ was never actually used. Spotted by Matthew Garrett
- OpenBSD-Commit-ID: 2c9db31e3f4d3403b49642c64ee048b2a0a39351
-
-commit 7bf2eb958fbb551e7d61e75c176bb3200383285d
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Tue Apr 26 23:30:59 2022 +1000
-
- Add debian-riscv64 test target.
-
-commit 3913c935523902482974c4c503bcff20bd850a6a
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Mon Apr 25 17:20:06 2022 +1000
-
- Update OpenSSL and LibreSSL versions in tests.
+ OpenBSD-Commit-ID: 0b363518ac4c2819dbaa3dfad4028633ab9cdff1
-commit dcd8dca29bcdb193ff6be35b96fc55e6e30d37d9
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Apr 23 20:40:28 2022 +1000
+commit 30b2a7e4291fb9e357f80a237931ff008d686d3b
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Sep 16 06:55:37 2022 +0000
- Include stdlib.h for free() prototype.
+ upstream: correct error value
- ... which is used inside the CUSTOM_SYS_AUTH_GET_LASTLOGIN_MSG block.
+ OpenBSD-Commit-ID: 780efcbad76281f11f14b2a5ff04eb6db3dfdad4
-commit 4cc05de568e1c3edd7834ff3bd9d8214eb34861b
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Apr 23 20:17:26 2022 +1000
+commit ac1ec9545947d9f9657259f55d04cb49d3a94c8a
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Sep 16 03:33:14 2022 +0000
- Cache timezone data in capsicum sandbox.
+ upstream: sftp: Be a bit more clever about completions
- From emaste at freebsd.org, originally part of FreeBSD commit r339216
- / fc3c19a9 with autoconf bits added by me.
-
-commit c31404426d212e2964ff9e5e58e1d0fce3d83f27
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Thu Apr 21 01:36:46 2022 +0000
-
- upstream: It looks like we can't completely avoid
+ There are commands (e.g. "get" or "put") that accept two
+ arguments, a local path and a remote path. However, the way
+ current completion is written doesn't take this distinction into
+ account and always completes remote or local paths.
- waiting for processes to exit so retrieve the pid via controlmaster and
- use that.
+ By expanding CMD struct and "cmds" array this distinction can be
+ reflected and with small adjustment to completer code the correct
+ path can be completed.
- OpenBSD-Regress-ID: 8246f00f22b14e49d2ff1744c94897ead33d457b
+ By Michal Privoznik, ok dtucker@
+
+ OpenBSD-Commit-ID: 1396d921c4eb1befd531f5c4a8ab47e7a74b610b
-commit d19b21afab5c8e2f3df6bd8aee9766bdad3d8c58
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Wed Apr 20 13:25:55 2022 +0000
+commit 590db83384f9d99fc51c84505792d26d1ef60df9
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Sep 16 03:13:34 2022 +0000
- upstream: Use ssh -f and ControlPersist ..
+ upstream: sftp: Don't attempt to complete arguments for
- to start up test forwards and ssh -O stop to shut them down intead of
- sleep loops. This speeds up the test by an order of magnitude.
+ non-existent commands
- OpenBSD-Regress-ID: eb3db5f805100919b092a3b2579c611fba3e83e7
+ If user entered a non-existent command (e.g. because they made a
+ typo) there is no point in trying to complete its arguments. Skip
+ calling complete_match() if that's the case.
+
+ From Michal Privoznik
+
+ OpenBSD-Commit-ID: cf39c811a68cde2aeb98fc85addea4000ef6b07a
-commit 5f76286a126721fa005de6edf3d1c7a265555f19
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Wed Apr 20 05:24:13 2022 +0000
+commit ff9809fdfd1d9a91067bb14a77d176002edb153c
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Sep 14 00:14:37 2022 +0000
- upstream: Simplify forward-control test.
+ upstream: sk_enroll: never drop SSH_SK_USER_VERIFICATION_REQD flag
- Since we no longer need to support SSH1 we don't need to run shell
- commands on the other end of the connection and can use ssh -N instead.
- This also makes the test less racy.
+ from response
- OpenBSD-Regress-ID: 32e94ce272820cc398f30b848b2b0f080d10302c
+ Now that all FIDO signing calls attempt first without PIN and then
+ fall back to trying PIN only if that attempt fails, we can remove the
+ hack^wtrick that removed the UV flag from the keys returned during
+ enroll.
+
+ By Corinna Vinschen
+
+ OpenBSD-Commit-ID: 684517608c8491503bf80cd175425f0178d91d7f
-commit 687bbf23572d8bdf25cbbcdf8ac583514e1ba710
+commit 940dc10729cb5a95b7ee82c10184e2b9621c8a1d
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Mar 31 03:07:33 2022 +0000
+Date: Wed Sep 14 00:13:13 2022 +0000
- upstream: regression test for sftp cp command
+ upstream: a little extra debugging
- OpenBSD-Regress-ID: c96bea9edde3a384b254785e7f9b2b24a81cdf82
+ OpenBSD-Commit-ID: edf1601c1d0905f6da4c713f4d9cecc7d1c0295a
-commit f1233f19a6a9fe58f52946f50df4772f5b136761
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Wed Apr 20 01:13:47 2022 +0000
+commit 4b5f91cb959358141181b934156513fcb8a6c1e3
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Sep 14 00:02:03 2022 +0000
- upstream: Import regenerated moduli
+ upstream: ssh-agent: attempt FIDO key signing without PIN and use
- OpenBSD-Commit-ID: f9a0726d957cf10692a231996a1f34e7f9cdfeb0
+ the error to determine whether a PIN is required and prompt only if
+ necessary. from Corinna Vinschen
+
+ OpenBSD-Commit-ID: dd6be6a0b7148608e834ee737c3479b3270b00dd
-commit fec014785de198b9a325d1b94e324bb958c5fe7b
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Apr 20 04:19:11 2022 +0000
+commit 113523bf0bc33600b07ebb083572c8c346b6fdf4
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Sun Sep 11 06:38:11 2022 +0000
- upstream: Try to continue running local I/O for channels in state
+ upstream: .Li -> .Vt where appropriate; from josiah frentsos,
- OPEN during SSH transport rekeying. The most visible benefit is that it
- should make ~-escapes work in the client (e.g. to exit) if the connection
- happened to have stalled during a rekey event. Based work by and ok dtucker@
+ tweaked by schwarze
- OpenBSD-Commit-ID: a66e8f254e92edd4ce09c9f750883ec8f1ea5f45
+ ok schwarze
+
+ OpenBSD-Commit-ID: 565046e3ce68b46c2f440a93d67c2a92726de8ed
-commit e68154b0d4f0f5085a050ea896955da1b1be6e30
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Wed Apr 20 01:13:47 2022 +0000
+commit 86af013b56cecb5ee58ae0bd9d495cd586fc5918
+Author: jsg@openbsd.org <jsg@openbsd.org>
+Date: Sat Sep 10 08:50:53 2022 +0000
- upstream: Import regenerated moduli
+ upstream: fix repeated words ok miod@ jmc@
- OpenBSD-Commit-ID: f9a0726d957cf10692a231996a1f34e7f9cdfeb0
+ OpenBSD-Commit-ID: 6765daefe26a6b648cc15cadbbe337596af709b7
-commit 69928b106d8f0fa15b88cf3850d992ed81c44ae0
-Author: tj@openbsd.org <tj@openbsd.org>
-Date: Sat Apr 16 00:22:31 2022 +0000
+commit 0ba39b93b326a7d5dfab776cc9b9d326161a9b16
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Sep 9 03:31:42 2022 +0000
- upstream: list the correct version number
+ upstream: notifier_complete(NULL, ...) is a noop, so no need to test
- for when usage of the sftp protocol became default and fix a typo
- from ed maste
+ that ctx!=NULL; from Corinna Vinschen
- OpenBSD-Commit-ID: 24e1795ed2283fdeacf16413c2f07503bcdebb31
+ OpenBSD-Commit-ID: ade2f2e9cc519d01a586800c25621d910bce384a
-commit 21042a05c0b304c16f655efeec97438249d2e2cc
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Tue Apr 12 05:09:49 2022 +0000
+commit be197635329feb839865fdc738e34e24afd1fca8
+Author: Sam James <sam@gentoo.org>
+Date: Thu Sep 8 02:49:29 2022 +0100
- upstream: Correct path for system known hosts file in description
-
- of IgnoreUserKnownHosts. Patch from Martin Vahlensieck via tech@
+ openbsd-compat/bsd-asprintf: add <stdio.h> include for vsnprintf
- OpenBSD-Commit-ID: 9b7784f054fa5aa4d63cb36bd563889477127215
+ Fixes the following build failure with Clang 15 on musl:
+ ```
+ bsd-asprintf.c:51:8: error: call to undeclared library function 'vsnprintf' with type 'int (char *, unsigned long, const char *, struct __va_list_tag *)'; ISO C99 and laterclang -O2 -pipe -fdiagnostics-color=always -frecord-gcc-switches -pipe -Wunknown-warning-option -Qunused-arguments -Wall -Wpointer-arith -Wuninitialized -Wsign-compare -Wformat-security -Wsizeof-pointer-memaccess -Wno-pointer-sign -Wno-unused-result -Wmisleading-indentation -Wbitwise-instead-of-logical -fno-strict-aliasing -mretpoline -ftrapv -fzero-call-used-regs=all -fno-builtin-memset -fstack-protector-strong -fPIE -I. -I. -D_XOPEN_SOURCE=600 -D_BSD_SOURCE -D_DEFAULT_SOURCE -DSSHDIR=\"/etc/ssh\" -D_PATH_SSH_PROGRAM=\"/usr/bin/ssh\" -D_PATH_SSH_ASKPASS_DEFAULT=\"/usr/lib/misc/ssh-askpass\" -D_PATH_SFTP_SERVER=\"/usr/lib/misc/sftp-server\" -D_PATH_SSH_KEY_SIGN=\"/usr/lib/misc/ssh-keysign\" -D_PATH_SSH_PKCS11_HELPER=\"/usr/lib/misc/ssh-pkcs11-helper\" -D_PATH_SSH_SK_HELPER=\"/usr/lib/misc/ssh-sk-helper\" -D_PATH_SSH_PIDDIR=\"/run\" -D_PATH_PRIVSEP_CHROOT_DIR=\"/var/empty\" -DHAVE_CONFIG_H -c cipher-aes.c -o cipher-aes.o
+ do not support
+ implicit function declarations [-Wimplicit-function-declaration]
+ ret = vsnprintf(string, INIT_SZ, fmt, ap2);
+ ^
+ bsd-asprintf.c:51:8: note: include the header <stdio.h> or explicitly provide a declaration for 'vsnprintf'
+ 1 error generated.
+ ```
-commit 53f4aff60a7c1a08a23917bd47496f8901c471f5
+commit 6cb6f660bb35f77a0456dd2581ddf39c29398a5e
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Apr 16 14:33:20 2022 +1000
+Date: Fri Sep 2 16:43:27 2022 +1000
- Resync moduli.5 with upstream.
-
- 1.18: remove duplicate publication year; carsten dot kunze at arcor dot de
- 1.19: ssh-keygen's -G/-T have been replaced with -M generate/screen.
+ Remove DEF_WEAK, it's already in defines.h.
-commit d2b888762b9844eb0d8eb59909cdf5af5159f810
+commit ce39e7d8b70c4726defde5d3bc4cb7d40d131153
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Apr 16 14:31:13 2022 +1000
+Date: Fri Sep 2 14:28:14 2022 +1000
- Retire fbsd6 test VM.
+ Resync arc4random with OpenBSD.
- It's long since out of support, relatively slow (it's i686) and the
- compiler has trouble with PIE.
+ This brings us up to current, including djm's random-reseeding change,
+ as prompted by logan at cyberstorm.mu in bz#3467. It brings the
+ platform-specific hooks from LibreSSL Portable, simplified to match our
+ use case. ok djm@.
-commit cd1f70009860a154b51230d367c55ea5f9a4504e
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Apr 11 22:52:08 2022 +0000
+commit beaddde26f30e2195b8aa4f3193970e140e17305
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Sep 2 14:20:04 2022 +1000
- upstream: clear io_want/io_ready flags at start of poll() cycle;
-
- avoids plausible spin during rekeying if channel io_want flags are reused
- across cycles. ok markus@ deraadt@
+ Move OPENBSD ORIGINAL marker.
- OpenBSD-Commit-ID: 91034f855b7c73cd2591657c49ac30f10322b967
+ Putting this after the copyright statement (which doesn't change)
+ instead of before the version identifier (which does) prevents merge
+ conflicts when resyncing changes.
-commit aa1920302778273f7f94c2091319aba199068ca0
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Apr 8 05:43:39 2022 +0000
+commit c83e467ead67a8cb48ef4bec8085d6fb880a2ff4
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Sep 2 14:17:28 2022 +1000
- upstream: Note that curve25519-sha256 was later published in
-
- RFC8731. ok djm@
+ Remove arc4random_uniform from arc4random.c
- OpenBSD-Commit-ID: 2ac2b5d642d4cf5918eaec8653cad9a4460b2743
+ This was previously moved into its own file (matching OpenBSD) which
+ prematurely committed in commit 73541f2.
-commit 4673fa8f2be983f2f88d5afd754adb1a2a39ec9e
+commit 5f45c2395c60865e59fa44152ff1d003a128c5bc
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Apr 8 04:40:40 2022 +0000
+Date: Fri Sep 2 04:20:02 2022 +0000
- upstream: two defensive changes from Tobias Stoeckmann via GHPR287
-
- enforce stricter invarient for sshbuf_set_parent() - never allow
- a buffer to have a previously-set parent changed.
+ upstream: sk-usbhid: fix key_lookup() on tokens with built-in UV
- In sshbuf_reset(), if the reallocation fails, then zero the entire
- buffer and not the (potentially smaller) default initial alloc size.
+ explicitly test whether the token performs built-in UV (e.g. biometric
+ tokens) and enable UV in that case. From Pedro Martelletto via GHPR#388
- OpenBSD-Commit-ID: 14583203aa5d50ad38d2e209ae10abaf8955e6a9
+ OpenBSD-Commit-ID: 007eb7e387d27cf3029ab06b88224e03eca62ccd
-commit 26eef015e2d2254375e13afaaf753b78932b1bf5
-Author: Damien Miller <djm@mindrot.org>
-Date: Mon Apr 11 16:07:09 2022 +1000
+commit 03277a4aa49b80af541a3e691f264c0c0d8f9cec
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Aug 31 20:26:30 2022 +1000
- Revert "update build-aux files to match autoconf-2.71"
-
- This reverts commit 0a8ca39fac6ad19096b6c263436f8b2dd51606f2.
-
- It turns out that the checked-in copies of these files are actually newer
- than autoconf-2.71's copies, so this was effectively a downgrade.
- Spotted by Bo Anderson via github
+ Move sftp from valgrind-2 to 3 to rebalance.
-commit 0a8ca39fac6ad19096b6c263436f8b2dd51606f2
-Author: Damien Miller <djm@mindrot.org>
-Date: Fri Apr 8 14:48:58 2022 +1000
+commit fcf5365da69c516817321ba89c3a91df98d098df
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Aug 31 02:56:40 2022 +0000
- update build-aux files to match autoconf-2.71
+ upstream: whitespace
- i.e. config.guess, config.sub and install-sh
+ OpenBSD-Commit-ID: c2bcbf93610d3d62ed206cdf9bf9ff98c6aaf232
-commit 94eb6858efecc1b4f02d8a6bd35e149f55c814c8
+commit e60136a3d7a223dd8e84ba8a6895bc3142360993
Author: Damien Miller <djm@mindrot.org>
-Date: Wed Apr 6 10:47:48 2022 +1000
+Date: Mon Aug 29 13:27:45 2022 +1000
- update version numbers for release
+ additional keys
-commit 8e4a8eadf4fe74e65e6492f34250f8cf7d67e8da
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Apr 4 22:45:25 2022 +0000
+commit 2b02dcb505288c462d1b5dd1ac04e603d01340eb
+Author: Damien Miller <djm@mindrot.org>
+Date: Mon Aug 29 13:23:43 2022 +1000
- upstream: openssh-9.0
+ cross-sign allowed_signers with PGP key
- OpenBSD-Commit-ID: 0dfb461188f4513ec024c1534da8c1ce14c20b64
+ Provides continuity of trust from legacy PGP release key to
+ the SSHSIG signing keys that we will use henceforth for git
+ signing.
-commit a9f23ea2e3227f406880c2634d066f6f50fa5eaa
-Author: naddy@openbsd.org <naddy@openbsd.org>
-Date: Thu Mar 31 17:58:44 2022 +0000
+commit 51b345f177ae981b8755f6bdf8358b1cc5e83d67
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat Aug 27 21:49:27 2022 +1000
- upstream: ssh: document sntrup761x25519-sha512@openssh.com as
-
- default KEX
+ Add libcrypt-devel to cygwin-release deps.
- OpenBSD-Commit-ID: 12545bfa10bcbf552d04d9d9520d0f4e98b0e171
+ Based on feedback from vinschen at redhat.com.
-commit 9ec2713d122af79d66ebb9c1d6d9ae8621a8945f
-Author: naddy@openbsd.org <naddy@openbsd.org>
-Date: Thu Mar 31 17:27:27 2022 +0000
+commit 9f81736cf16dd8dda1c8942f1973a5f80b8cd78c
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat Aug 27 09:37:40 2022 +1000
- upstream: man pages: add missing commas between subordinate and
-
- main clauses
+ Add Windows 2022 test targets.
+
+commit 85e1a69243f12be8520438ad6a3cfdc0b7fcbb2d
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Aug 26 16:26:06 2022 +1000
+
+ Add cygwin-release test target.
- jmc@ dislikes a comma before "then" in a conditional, so leave those
- untouched.
+ This also moves the cygwin package install from the workflow file to
+ setup_ci.sh so that we can install different sets of Cygwin packages
+ for different test configs.
+
+commit 92382dbe8bf9ea1225b16858f9b9b208c15c7e8d
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Aug 26 08:16:27 2022 +0000
+
+ upstream: whitespace
- ok jmc@
+ OpenBSD-Commit-ID: a5d015efbfd228dc598ffdef612d2da3a579e5d8
+
+commit 70a5de0a50e84d7250eb4e4537f765599f64c4af
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Aug 26 08:12:56 2022 +0000
+
+ upstream: whitespace
- OpenBSD-Commit-ID: 9520801729bebcb3c9fe43ad7f9776ab4dd05ea3
+ OpenBSD-Commit-ID: d297e4387935d4aef091c5e9432578c2e513f538
-commit 3741df98ffaaff92b474ee70d8ef276b5882f85a
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Mon Apr 4 23:52:11 2022 +1000
+commit 3a683a19fd116ea15ebf8aa13d02646cceb302a9
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Aug 26 14:23:55 2022 +1000
- Disable security key on fbsd6 test host.
+ initial list of allowed signers
-commit 32c12236f27ae83bfe6d2983b67c9bc67a83a417
+commit 6851f4b8c3fc1b3e1114c56106e4dc31369c8513
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Mon Apr 4 15:16:51 2022 +1000
+Date: Fri Aug 19 17:22:18 2022 +1000
- Specify TEST_SHELL=bash on AIX.
+ Install Cygwin packages based on OS not config.
+
+commit f96480906893ed93665df8cdf9065865c51c1475
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Aug 19 06:07:47 2022 +0000
+
+ upstream: attemp FIDO key signing without PIN and use the error
- The system shells cause the agent-restrict test to fail due to some
- quoting so explicitly specify bash until we can get configure to
- autmatically work around that.
+ code returned to fall back only if necessary. Avoids PIN prompts for FIDO
+ tokens that don't require them; part of GHPR#302
+
+ OpenBSD-Commit-ID: 4f752aaf9f2e7c28bcaaf3d4f8fc290131bd038e
-commit 90452c8b69d065b7c7c285ff78b81418a75bcd76
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Apr 1 23:38:44 2022 +1100
+commit 5453333b5d28e313284cb9aae82899704103f98d
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Aug 19 05:53:28 2022 +0000
- Only return events from ppoll that were requested.
+ upstream: remove incorrect check that can break enrolling a
- If the underlying system's select() returns bits that were not in the
- request set, our ppoll() implementation can return revents for events
- not requested, which can apparently cause a hang. Only return revents
- for activity in the requested event set. bz#3416, analysis and fix by
- yaroslav.kuzmin at vmssoftware com, ok djm@
+ resident key (introduced in r1.40)
+
+ OpenBSD-Commit-ID: 4cab364d518470e29e624af3d3f9ffa9c92b6f01
-commit 6c49eb5fabc56f4865164ed818aa5112d09c31a8
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Apr 1 23:21:40 2022 +1100
+commit ff89b1bed80721295555bd083b173247a9c0484e
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Aug 19 04:02:46 2022 +0000
- Only run regression tests on slow VMs.
+ upstream: Strictly enforce the maximum allowed SSH2 banner size in
+
+ ssh-keyscan and prevent a one-byte buffer overflow. Patch from Qualys, ok
+ djm@
+
+ OpenBSD-Commit-ID: 6ae664f9f4db6e8a0589425f74cd0bbf3aeef4e4
-commit f67e47903977b42cb6abcd5565a61bd7293e4dc3
+commit 1b470b9036639cef4f32fb303bb35ea0b711178d
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Apr 1 23:21:06 2022 +1100
+Date: Fri Aug 19 15:18:09 2022 +1000
- Increase test timeout to allow slow VMs to finish
+ Fix cygwin conditional steps.
-commit 02488c1b54065ddc4f25835dbd2618b2a2fe21f5
+commit fd6ee741ab16714b7035d60aca924123ba28135a
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Apr 1 16:27:38 2022 +1100
+Date: Fri Aug 19 15:12:57 2022 +1000
- Use bash or ksh if available for SH in Makefile.
+ Add a bit more debug output.
-commit 34c7018c316af4773e432066de28d0ef9d0888cd
+commit a9305c4c739f4d91a3d3a92c0b6d4949404a36c5
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Apr 1 14:56:54 2022 +1100
+Date: Fri Aug 12 15:08:47 2022 +1000
- Set Makefile SHELL as determined by configure.
+ Add Cygwin (on windows-2019) test target.
- This should improve compatibility for users with non-POSIX shells. If
- using Makefile.in directly (eg make -f Makefile.in distprep) then SHELL
- will need to be specified on the command line (along with MANFMT in that
- particular case). ok djm@
+ In addition to installing the requisite Cygwin packages, we also need to
+ explicitly invoke "sh" for steps that run other scripts since the runner
+ environment doesn't understand #! paths.
-commit 5b054d76402faab38c48377efd112426469553a0
+commit 5062ad48814b06162511c4f5924a33d97b6b2566
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Aug 19 03:06:30 2022 +0000
+
+ upstream: double free() in error path; from Eusgor via GHPR333
+
+ OpenBSD-Commit-ID: 39f35e16ba878c8d02b4d01d8826d9b321be26d4
+
+commit 5a5c580b48fc6006bdfa731fc2f6d4945c2c0e4e
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Apr 1 13:16:47 2022 +1100
+Date: Thu Aug 18 21:36:39 2022 +1000
- Skip slow tests on (very) slow test targets.
+ Check for perms to run agent-getpeereid test.
+
+ Ubuntu 22.04 defaults to private home dirs which prevents "nobody"
+ running ssh-add during the agent-getpeereid test. Check for this and
+ add the necessary permissions.
-commit b275818065b31a865142c48c2acf6a7c1655c542
+commit cd06a76b7ccc706e2bb4f1cc4aa9e9796a28a812
Author: Damien Miller <djm@mindrot.org>
-Date: Thu Mar 31 14:11:36 2022 +1100
+Date: Wed Aug 17 16:04:16 2022 +1000
- depend
+ on Cygwin, prefer WinHello FIDO device
+
+ If no FIDO device was explictly specified, then prefer the
+ windows://hello FIDO device. An exception to this is when
+ probing resident FIDO keys, in which case hardware FIDO
+ devices are preferred.
-commit 3fa539c3ffaabd6211995512d33e29150f88c5c5
+commit 47f72f534ac5cc2cd3027675a3df7b00a8f77575
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Mar 31 03:07:03 2022 +0000
+Date: Wed Aug 17 06:01:57 2022 +0000
- upstream: add a sftp client "cp" command that supports server-side
+ upstream: add an extra flag to sk_probe() to indicate whether we're
- copying of files. Useful for this task and for testing the copy-data
- extension. Patch from Mike Frysinger; ok dtucker@
+ probing for a FIDO resident key or not. Unused here, but will make like
+ easier for portable
- OpenBSD-Commit-ID: 1bb1b950af0d49f0d5425b1f267e197aa1b57444
+ OpenBSD-Commit-ID: 432c8ff70e270378df9dbceb9bdeaa5b43b5a832
-commit 7988bfc4b701c4b3fe9b36c8561a3d1c5d4c9a74
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Mar 31 03:05:49 2022 +0000
+commit edb0bcb3c79b16031dc87a8e57aecc3c4a3414f0
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Tue Aug 16 20:24:08 2022 +0000
- upstream: add support for the "corp-data" protocol extension to
-
- allow server-side copies to be performed without having to go via the client.
- Patch by Mike Frysinger, ok dtucker@
+ upstream: use .Cm for "sign"; from josiah frentsos
- OpenBSD-Commit-ID: 00aa510940fedd66dab1843b58682de4eb7156d5
+ OpenBSD-Commit-ID: 7f80a53d54857ac6ae49ea6ad93c5bd12231d1e4
-commit 32dc1c29a4ac9c592ddfef0a4895eb36c1f567ba
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Mar 30 21:13:23 2022 +0000
+commit cccb011e130cbbac538b1689d10e4a067298df8b
+Author: Corinna Vinschen <vinschen@redhat.com>
+Date: Thu Aug 11 20:19:35 2022 +0200
- upstream: select post-quantum KEX
+ Revert "check_sk_options: add temporary WinHello workaround"
- sntrup761x25519-sha512@openssh.com as the default; ok markus@
+ Cygwin now comes with libfido2 1.11.0, so this workaround
+ isn't required anymore.
- OpenBSD-Commit-ID: f02d99cbfce22dffec2e2ab1b60905fbddf48fb9
+ This reverts commit 242c044ab111a37aad3b0775727c36a4c5f0102c.
+
+ Signed-off-by: Corinna Vinschen <vinschen@redhat.com>
-commit d6556de1db0822c76ba2745cf5c097d9472adf7c
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Mar 30 21:10:25 2022 +0000
+commit 9468cd7cf9d989dfa2ac20e2a0268ba6e93bfa5a
+Author: Corinna Vinschen <vinschen@redhat.com>
+Date: Thu Aug 11 20:18:17 2022 +0200
- upstream: fix poll() spin when a channel's output fd closes without
+ fido_dev_is_winhello: return 0, not "false"
- data in the channel buffer. Introduce more exact packing of channel fds into
- the pollfd array. fixes bz3405 and bz3411; ok deraadt@ markus@
+ "false" is not used anywhere in OpenSSH, so return 0 like
+ everywhere else.
- OpenBSD-Commit-ID: 06740737849c9047785622ad5d472cb6a3907d10
+ Signed-off-by: Corinna Vinschen <vinschen@redhat.com>
-commit 8a74a96d25ca4d32fbf298f6c0ac5a148501777d
+commit 730a80609472ee0451c99482d75c9c41f3ebc42d
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Mar 30 04:33:09 2022 +0000
+Date: Fri Aug 12 05:20:28 2022 +0000
- upstream: ssh is almost out of getopt() characters; note the
-
- remaining remaining available ones in a comment
+ upstream: sftp-server: support home-directory request
- OpenBSD-Commit-ID: 48d38cef59d6bc8e84c6c066f6d601875d3253fd
-
-commit 6d4fc51adb9d8a42f67b5474f02f877422379de6
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Mar 30 04:27:51 2022 +0000
-
- upstream: avoid NULL deref via ssh-keygen -Y find-principals.
+ Add support to the sftp-server for the home-directory extension defined
+ in draft-ietf-secsh-filexfer-extensions-00. This overlaps a bit with the
+ existing expand-path@openssh.com, but uses a more official protocol name,
+ and so is a bit more likely to be implemented by non-OpenSSH clients.
- bz3409, reported by Mateusz Adamowski
+ From Mike Frysinger, ok dtucker@
- OpenBSD-Commit-ID: a3b2c02438052ee858e0ee18e5a288586b5df2c5
+ OpenBSD-Commit-ID: bfc580d05cc0c817831ae7ecbac4a481c23566ab
-commit e937514920335b92b543fd9be79cd6481d1eb0b6
+commit 5e820bf79ce3ce99ef7e98b0ab642b0a0a4f396c
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Mon Mar 28 17:51:03 2022 +1100
+Date: Fri Aug 12 14:56:55 2022 +1000
- Add AIX 5.1 test target.
+ Replace deprecated ubuntu-18.04 runners with 22.04
-commit 4bbe815ba974b4fd89cc3fc3e3ef1be847a0befe
+commit 87b0d9c1b789d3ff958ec45df2ac912e24461bae
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Mar 26 22:01:31 2022 +1100
+Date: Thu Aug 11 22:48:23 2022 +1000
- Drop leading "v" from release version identifier.
+ Add a timegm implementation from Heimdal via Samba.
- It's present in the git tags but not in the release tarball names.
- Also drop extra "/" from URL path.
+ Fixes build on (at least Solaris 10).
-commit f5cdd3b3c275dffaebfca91df782dca29975e9ac
+commit d0c4fa58594577994921b593f10037c5282597ca
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Mar 26 16:28:04 2022 +1100
+Date: Thu Aug 11 14:23:58 2022 +1000
- Use tarballs when testing LibreSSL releases.
+ Rerun tests if any .github config file changes.
+
+commit 113fe6c77ab43769fc61e953d07cb619fd7ea54b
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Aug 11 13:33:51 2022 +1000
+
+ Skip hostbased during Valgrind tests.
- This means they'll still work when the combination of -portable and
- openbsd github repos no longer match.
+ Valgrind doesn't let ssh exec ssh-keysign (because it's setuid) so skip
+ it during the Valgrind based tests.
+
+ See https://bugs.kde.org/show_bug.cgi?id=119404 for a discussion of this
+ (ironically there the problematic binary was ssh(1) back when it could
+ still be setuid).
-commit 24dc37d198f35a7cf71bf4d5384363c7ef4209d4
+commit b98a42afb69d60891eb0488935990df6ee571c4d
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Aug 11 01:57:50 2022 +0000
+
+ upstream: add some tests for parse_absolute_time(), including cases
+
+ where it is forced to the UTC timezone. bz3468 ok dtucker
+
+ OpenBSD-Regress-ID: ea07ca31c2f3847a38df028ca632763ae44e8759
+
+commit ec1ddb72a146fd66d18df9cd423517453a5d8044
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Aug 11 01:56:51 2022 +0000
+
+ upstream: allow certificate validity intervals, sshsig verification
+
+ times and authorized_keys expiry-time options to accept dates in the UTC time
+ zone in addition to the default of interpreting them in the system time zone.
+ YYYYMMDD and YYMMDDHHMM[SS] dates/times will be interpreted as UTC if
+ suffixed with a 'Z' character.
+
+ Also allow certificate validity intervals to be specified in raw
+ seconds-since-epoch as hex value, e.g. -V 0x1234:0x4567890. This
+ is intended for use by regress tests and other tools that call
+ ssh-keygen as part of a CA workflow.
+
+ bz3468 ok dtucker
+
+ OpenBSD-Commit-ID: 454db1cdffa9fa346aea5211223a2ce0588dfe13
+
+commit 4df246ec75751da7eb925e1880498300d8bda187
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Mar 26 15:02:45 2022 +1100
+Date: Thu Aug 11 10:23:55 2022 +1000
- Remove now-unused passwd variable.
+ Fix conditional for running hostbased tests.
-commit 5b467ceef2c356f0a77f5e8ab4eb0fac367e4d24
+commit 2580916e48721802220c61ce9e0df1297c00bc07
+Author: Damien Miller <djm@mindrot.org>
+Date: Thu Aug 11 08:58:28 2022 +1000
+
+ fix SANDBOX_SECCOMP_FILTER_DEBUG
+
+commit fdbd5bf507fc271ff813714fab8a72ff2c6cb5ca
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Mar 26 13:15:44 2022 +1100
+Date: Wed Aug 10 17:35:52 2022 +1000
- Missing semicolon.
+ Test hostbased auth on github runners.
-commit 2923d026e55998133c0f6e5186dca2a3c0fa5ff5
+commit 7e2f51940ba48a1c0fae1107801ea643fa83c971
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Mar 26 12:49:50 2022 +1100
+Date: Wed Aug 10 17:25:24 2022 +1000
- Factor out platform-specific locked account check.
+ Rename our getentropy to prevent possible loops.
- Also fixes an incorrect free on platforms with both libiaf and shadow
- passwords (probably only Unixware). Prompted by github PR#284,
- originally from @c3h2_ctf and stoeckmann@.
+ Since arc4random seeds from getentropy, and we use OpenSSL for that
+ if enabled, there's the possibility that if we build on a system that
+ does not have getentropy then run on a system that does have it, then
+ OpenSSL could end up calling our getentropy and getting stuck in a loop.
+ Pointed out by deraadt@, ok djm@
-commit d23efe4b12886ffe416be10bc0a7da6ca8aa72d1
+commit 7a01f61be8d0aca0e975e7417f26371495fe7674
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Mar 26 08:13:46 2022 +1100
+Date: Mon Aug 8 12:17:04 2022 +1000
- Add OpenWRT mips and mipsel test targets.
+ Actually put HAVE_STDINT_H around the stdint.h.
-commit 16ea8b85838dd7a4dbeba4e51ac4f43fd68b1e5b
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Mar 20 08:52:17 2022 +0000
+commit 73541f29f0b50480da6c20dceb7a7191bd8ea7d3
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Aug 8 10:30:34 2022 +1000
- upstream: don't leak argument list; bz3404, reported by Balu
-
- Gajjala ok dtucker@
+ Give unused param a name.
- OpenBSD-Commit-ID: fddc32d74e5dd5cff1a49ddd6297b0867eae56a6
+ Fixes builds on platforms that do have fido2 but don't have
+ fido_dev_is_winhello.
-commit a72bde294fe0518c9a44ba63864093a1ef2425e3
+commit 2a108c0ea960381bd9b14ee0d84e818a23df4482
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Mar 20 08:51:21 2022 +0000
+Date: Fri Aug 5 05:01:40 2022 +0000
- upstream: make addargs() and replacearg() a little more robust and
-
- improve error reporting
+ upstream: don't prompt for FIDO passphrase before attempting to enroll
- make freeargs(NULL) a noop like the other free functions
+ the credential, just let the enroll operating fail and we'll attempt to get a
+ PIN anyway. Might avoid some unneccessary PIN prompts.
- ok dtucker as part of bz3403
+ Part of GHPR#302 from Corinna Vinschen; ok dtucker@
- OpenBSD-Commit-ID: 15f86da83176978b4d1d288caa24c766dfa2983d
+ OpenBSD-Commit-ID: bd5342ffc353ee37d39617906867c305564d1ce2
-commit 731087d2619fa7f01e675b23f57af10d745e8af2
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Mar 18 04:04:11 2022 +0000
+commit 2886975c0ad9244e60dc5e4be34fde3aa573a4b5
+Author: Corinna Vinschen <vinschen@redhat.com>
+Date: Fri Feb 11 14:33:41 2022 +0100
- upstream: don't try to resolve ListenAddress directives in the sshd
+ sk_sign: set FIDO2 uv attribute explicitely for WinHello
- re-exec path - we're never going to use the result and if the operation fails
- then it can prevent connections from being accepted. Reported by Aaron
- Poffenberger; with / ok dtucker@
+ WinHello via libfido2 performs user verification by default.
+ However, if we stick to that, there's no way to differentiate
+ between keys created with or without "-O verify-required".
+ Set FIDO2 uv attribute explicitely to FIDO_OPT_FALSE, then check
+ if user verification has been requested.
- OpenBSD-Commit-ID: 44c53a43909a328e2f5ab26070fdef3594eded60
+ Signed-off-by: Corinna Vinschen <vinschen@redhat.com>
-commit 1c83c082128694ddd11ac05fdf31d70312ff1763
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Mar 18 02:50:21 2022 +0000
+commit 242c044ab111a37aad3b0775727c36a4c5f0102c
+Author: Corinna Vinschen <vinschen@redhat.com>
+Date: Tue Feb 15 11:28:08 2022 +0100
- upstream: remove blank line
+ check_sk_options: add temporary WinHello workaround
- OpenBSD-Commit-ID: d5e0182965b2fbfb03ad5f256d1a1ce5706bcddf
+ Up to libfido 1.10.0, WinHello advertises "clientPin" rather
+ than "uv" capability. This is fixed in 1.11.0. For the time
+ being, workaround it here.
+
+ Signed-off-by: Corinna Vinschen <vinschen@redhat.com>
-commit 807be68684da7a1fe969c399ddce2fafb7997dcb
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Mar 18 02:32:22 2022 +0000
+commit 78774c08cc4b4997382975b0f414a86e06b6780c
+Author: Corinna Vinschen <vinschen@redhat.com>
+Date: Thu Feb 10 18:19:29 2022 +0100
- upstream: helpful comment
+ compat code for fido_dev_is_winhello()
- OpenBSD-Commit-ID: e3315a45cb04e7feeb614d76ec80a9fe4ca0e8c7
+ Signed-off-by: Corinna Vinschen <vinschen@redhat.com>
-commit a0b5816f8f1f645acdf74f7bc11b34455ec30bac
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Mar 18 02:31:25 2022 +0000
+commit 3d3a932a019aedfb891e0779bb4990cd5008a390
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Aug 5 13:12:27 2022 +1000
- upstream: ssh-keygen -Y check-novalidate requires namespace or SEGV
-
- will ensue. Patch from Mateusz Adamowski via GHPR#307
+ Factor out getrnd() and rename to getentropy().
- OpenBSD-Commit-ID: 99e8ec38f9feb38bce6de240335be34aedeba5fd
+ Factor out the arc4random seeding into its own file and change the
+ interface to match getentropy. Use native getentropy if available.
+ This will make it easier to resync OpenBSD changes to arc4random.
+ Prompted by bz#3467, ok djm@.
-commit 5a252d54a63be30d5ba4be76210942d754a531c0
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Mar 15 05:27:37 2022 +0000
+commit 9385d277b787403be9dfcb229cf372202496d2f3
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Aug 4 18:55:48 2022 +1000
- upstream: improve DEBUG_CHANNEL_POLL debugging message
-
- OpenBSD-Commit-ID: 2275eb7bc4707d019b1a0194b9c92c0b78da848f
+ Include CHANNEL and FIDO2 libs in configure output
-commit ce324cf58ba2840e31afeb996935800780c8fa4b
-Author: cheloha@openbsd.org <cheloha@openbsd.org>
-Date: Sun Mar 13 23:27:54 2022 +0000
+commit 141535b904b6fba01724444f38193a8599201f82
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Aug 1 11:09:26 2022 +0000
- upstream: ssh: xstrdup(): use memcpy(3)
-
- Copying the given string into the buffer with strlcpy(3) confers no
- benefit in this context because we have already determined the
- string's length with strlen(3) in order to allocate that buffer.
-
- Thread: https://marc.info/?l=openbsd-tech&m=164687525802691&w=2
+ upstream: avoid double-free in error path introduced in r1.70; report
- ok dtucker@ millert@
+ and fix based on GHPR#332 by v-rzh ok dtucker@
- OpenBSD-Commit-ID: f8bfc082e36e2d2dc4e1feece02fe274155ca11a
+ OpenBSD-Commit-ID: 3d21aa127b1f37cfc5bdc21461db369a663a951f
-commit 2893c5e764557f48f9d6a929e224ed49c59545db
+commit dba7099ffcba3ca07b3946f017ba6a4c3158d9b1
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Mar 11 18:43:58 2022 +1100
+Date: Wed Jul 27 18:40:12 2022 +1000
- Resync fmt_scaled. with OpenBSD.
-
- Fixes underflow reported in bz#3401.
+ Remove deprecated MacOS 10.15 runners.
-commit 5ae31a0fdd27855af29f48ff027491629fff5979
+commit 722a56439aa5972c830e4a9a724cf52aff4a950a
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Mar 9 09:41:56 2022 +1100
+Date: Wed Jul 27 18:31:14 2022 +1000
- Provide killpg implementation.
+ Move stale-configure check as early as possible.
- Based on github PR#301 for Tandem NonStop.
+ We added a check in Makefile to catch the case where configure needs to
+ be rebuilt, however this did not happen until a build was attempted in
+ which case all of the work done by configure was wasted. Move this check
+ to the start of configure to catch it as early as possible. ok djm@
-commit c41c84b439f4cd74d4fe44298a4b4037ddd7d2ae
+commit 099d6b56288b421ba38531d26dc1bd6bb685e311
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Mar 9 09:29:30 2022 +1100
+Date: Fri Jul 22 10:47:19 2022 +1000
- Check for missing ftruncate prototype.
+ Move libcrypto into CHANNELLIBS.
- From github PR#301 in conjunction with rsbeckerca.
-
-commit 8cf5275452a950869cb90eeac7d220b01f77b12e
+ This will result in sftp, sftp-server and scp no longer being linked
+ against libcrypto. ok djm@
+
+commit 1bdf86725b77733bb5f17c54888b88a10b2f6538
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Tue Mar 8 20:04:06 2022 +1100
+Date: Fri Jul 22 10:45:47 2022 +1000
- Default to not using sandbox when cross compiling.
+ Remove seed_rng calls from scp, sftp, sftp-server.
- On most systems poll(2) does not work when the number of FDs is reduced
- with setrlimit, so assume it doesn't when cross compiling and we can't
- run the test. bz#3398.
+ These binaries don't use OpenSSL's random functions. The next step
+ will be to stop linking them against libcrypto. ok djm@
-commit 379b30120da53d7c84aa8299c26b18c51c2a0dac
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Mar 1 01:59:19 2022 +0000
+commit d73f77b8cb9b422f1ac4facee7890aa10ff2bc21
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Jul 22 09:51:51 2022 +1000
- upstream: pack pollfd array before server_accept_loop() ppoll()
-
- call, and terminate sshd if ppoll() returns errno==EINVAL
-
- avoids spin in ppoll when MaxStartups > RLIMIT_NOFILE, reported by
- Daniel Micay
+ Group libcrypto and PRNGD checks together.
- feedback/ok deraadt
+ They're related more than the libcrypt or libiaf checks which are
+ currently between them. ok djm@
+
+commit f117e372b3f42f2fbdb0a578d063b2609ab58e1f
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Jul 22 09:24:45 2022 +1000
+
+ Do not link scp, sftp and sftp-server w/ zlib.
- OpenBSD-Commit-ID: dbab1c24993ac977ec24d83283b8b7528f7c2c15
+ Some of our binaries (eg sftp, sftp-server, scp) do not interact with
+ the channels code and thus do use libraries such as zlib and libcrypto
+ although they are linked with them. This adds a CHANNELLIBS and starts
+ by moving zlib into it, which means the aformentioned binaries are no
+ longer linked against zlib. ok djm@
-commit eceafbe0bdbbd9bd2f3cf024ccb350666a9934dd
-Author: naddy@openbsd.org <naddy@openbsd.org>
-Date: Sun Feb 27 01:33:59 2022 +0000
+commit 800c2483e68db38bd1566ff69677124be974aceb
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Jul 25 21:49:04 2022 +1000
- upstream: include rejected signature algorithm in error message and
+ Remove workarounds for OpenSSL missing AES-CTR.
- not the (useless) key type; ok djm@
+ We have some compatibility hacks that were added to support OpenSSL
+ versions that do not support AES CTR mode. Since that time, however,
+ the minimum OpenSSL version that we support has moved to 1.0.1 which
+ *does* have CTR, so this is no longer needed. ok djm@
+
+commit b7c56b65c12f51fe0dbae798d19c8f58224a5d95
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Jul 25 21:43:00 2022 +1000
+
+ Remove workarounds for OpenSSL missing AES-GCM.
- OpenBSD-Commit-ID: d0c0f552a4d9161203e07e95d58a76eb602a76ff
+ We have some compatibility hacks that were added to support OpenSSL
+ versions that do not support AES GCM mode. Since that time, however,
+ the minimum OpenSSL version that we support has moved to 1.0.1 which
+ *does* have GCM, so this is no longer needed. ok djm@
-commit f2f3269423618a83157e18902385e720f9776007
+commit 5a4a9f7a968fbf92cc1eac519c65638e79ae9f1f
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Feb 25 09:46:24 2022 +0000
+Date: Mon Jul 25 07:12:45 2022 +0000
- upstream: Remove the char * casts from arguments to do_lstat,
-
- do_readdir and do_stat paths since the underlying functions now take a const
- char *. Patch from vapier at gentoo.org.
+ upstream: Restore missing "!" in TEST_SSH_ELAPSED_TIMES test.
- OpenBSD-Commit-ID: 9e4d964dbfb0ed683a2a2900711b88e7f1c0297b
+ OpenBSD-Regress-ID: 38783f9676ec348c5a792caecee9a16e354b37b0
-commit 4a66dac052c5ff5047161853f36904607649e4f9
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Feb 25 02:09:27 2022 +0000
+commit 0ff886be132299386cc29d87c2aa16ff68a1aa08
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Sun Jul 24 23:29:10 2022 +0000
- upstream: save an unneccessary alloc/free, based on patch from
+ upstream: Test TEST_SSH_ELAPSED_TIMES for empty string not
- Martin Vahlensieck; ok dtucker@
+ executable. No-op on most platforms but should prevent warnings in -portable
+ on systems that don't have 'date %s'.
- OpenBSD-Commit-ID: 90ffbf1f837e509742f2c31a1fbf2c0fd376fd5f
-
-commit 6f117cb151efe138ac57bdd8e26165f350328f5f
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Tue Mar 1 09:02:06 2022 +1100
-
- Remove unused ivbits argument from chacha_keysetup
+ OpenBSD-Regress-ID: e39d79867b8065e33d0c5926fa1a31f85659d2a4
-commit 15974235dd528aeab0ec67fb92a0a1d733f62be2
+commit f69319ad8ad1dd50f90bbcf5912e11cc8ed3e037
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Tue Mar 1 09:00:20 2022 +1100
+Date: Sat Jul 23 14:38:22 2022 +1000
- Add OPENBSD ORIGINAL marker.
+ Convert "have_prog" function into "which".
+
+ "which" and its behaviour is not standardized, so convert the existing
+ have_prog function into "which" so we can rely on it being available
+ and what its semantics are. Add a have_prog wrapper that maintains the
+ existing behaviour.
-commit f2ff669347d320532e7c1b63cdf5c62f46e73150
+commit ea7ecc2c3ae39fdf5c6ad97b7bc0b47a98847f43
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Mon Feb 28 22:21:36 2022 +1100
+Date: Sat Jul 23 14:36:38 2022 +1000
- No unused param warnings for clang-12 and gcc-11.
+ Skip scp3 test if there's no scp on remote path.
- These have too many false positives in -Werror tests on the github CI
- since we often provide empty stub functions for functionality not needed
- for particular configurations.
+ scp -3 ends up using the scp that's in the remote path and will fail if
+ one is not available. Based on a patch from rapier at psc.edu.
-commit 96558ecd87adac62efa9a2b5479f686ab86b0be1
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Feb 26 14:10:41 2022 +1100
+commit c46f6fed419167c1671e4227459e108036c760f8
+Author: Damien Miller <djm@mindrot.org>
+Date: Wed Jul 20 13:39:14 2022 +1000
- Add debian-i386 test target.
+ crank SSH_SK_VERSION_MAJOR in sk-dummy.so
-commit 284b6e5394652d519e31782e3b3cdfd7b21d1a81
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Feb 26 14:06:14 2022 +1100
+commit f208e3b9ffb5ee76cf9c95df7ff967adc7f51c7d
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Jul 20 03:33:22 2022 +0000
- Allow ppoll_time64 in seccomp sandbox.
+ upstream: ssh-keygen: fix touch prompt, pin retries;
- Should fix sandbox violations on (some? at least i386 and armhf) 32bit
- Linux platforms. Patch from chutzpahu at gentoo.org and cjwatson at
- debian.org via bz#3396.
+ part of GHPR329 from Pedro Martelletto
+
+ OpenBSD-Commit-ID: 75d1005bd2ef8f29fa834c90d2684e73556fffe8
-commit 0132056efabc5edb85c3c7105d2fb6dee41843c6
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Feb 25 19:47:48 2022 +1100
+commit 8638a2ce7e90c8a51d9af3143404282126c524f8
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Jul 20 03:31:42 2022 +0000
- Improve handling of _getshort and _getlong.
+ upstream: sk-usbhid: preserve error code returned by key_lookup()
- If the system native ones are exactly as required then use them,
- otherwise use the local versions mapped to another name to prevent
- name collisions.
+ it conveys useful information, such as the supplied pin being wrong.
+
+ Part of GHPR329 from Pedro Martelletto
+
+ OpenBSD-Commit-ID: c0647eb9290f793add363d81378439b273756c1b
-commit 8e206e0dd6b9f757b07979e48f53ad5bf9b7b52b
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Feb 25 15:14:22 2022 +1100
+commit 9ab929ca2d820520327b41929372bcb9e261534c
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Jul 20 03:29:14 2022 +0000
- Constify utimes in compat library to match specs.
+ upstream: when enrolling a resident key on a security token, check
- Patch from vapier at chromium.org.
+ if a credential with matching application and user ID strings already exists.
+ if so, prompt the user for confirmation before overwriting the credential.
+
+ patch from Pedro Martelletto via GHPR329
+
+ NB. cranks SSH_SK_VERSION_MAJOR, so any third-party FIDO middleware
+ implementations will need to adjust
+
+ OpenBSD-Commit-ID: e45e9f1bf2b2f32d9850669e7a8dbd64acc5fca4
-commit 1b2920e3b63db2eddebeec7330ffe8b723055573
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Feb 25 13:50:56 2022 +1100
+commit 5bcfc788b38d5b64e4c347bdc04bd9a01bbc36da
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Jul 20 03:13:04 2022 +0000
- ANSIfy getshort and getlong.
+ upstream: pull passphrase reading and confirmation into a separate
- These functions appear to have come from OpenBSD's lib/libc/net/res_comp.c
- which made this change in 2005.
+ function so it can be used for FIDO2 PINs; no functional change
+
+ OpenBSD-Commit-ID: bf34f76b8283cc1d3f54633e0d4f13613d87bb2f
-commit 54a86f4f6e1c43a2ca2be23ef799ab8910d4af70
+commit eb679e2959bdb15454eb94751930eb4c9110da94
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Feb 25 13:23:04 2022 +1100
+Date: Fri Jul 15 21:31:48 2022 +1000
- Use PICFLAG instead of hard coding -fPIC.
+ Move vmshutdown to first step.
+
+ If a previous run on a physical runner has failed to clean up, the next
+ run will fail because it'll try to check out the code to a broken
+ directory mount. Make cleanup the first step.
-commit 3016ba47035ac3561aabd48e2be70167fe157d6a
+commit 46b91b70ff3cb9c147e2875ef5dc609fd64c0c96
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Feb 25 11:37:11 2022 +1100
+Date: Fri Jul 15 20:25:27 2022 +1000
- Add tests for latest releases of {Libre,Open}SSL.
+ Rename bbone test target to ARM.
-commit f107467179428a0e3ea9e4aa9738ac12ff02822d
-Author: Colin Watson <cjwatson@debian.org>
-Date: Thu Feb 24 16:04:18 2022 +0000
+commit 751d22cdeffed9fe921db78eedc32a29f9e80510
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Jul 15 13:37:29 2022 +1000
- Improve detection of -fzero-call-used-regs=all support
+ Add AUDIT_ARCH_PPC to supported seccomp arches.
- GCC doesn't tell us whether this option is supported unless it runs into
- the situation where it would need to emit corresponding code.
+ Patch from dries.deschout at dodeco.eu.
-commit 3383b2cac0e9275bc93c4b4760e6e048f537e1d6
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Feb 23 21:21:49 2022 +0000
+commit a061792a6e8d235fc40a9b5d4c22a1762bb75a7b
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Jul 14 19:20:24 2022 +1000
- upstream: free(3) wants stdlib.h
+ Remove unintended changes.
- OpenBSD-Commit-ID: 227a8c70a95b4428c49e46863c9ef4bd318a3b8a
+ I inadvertently included a couple of local changes with the OpenSSL
+ 3.0.4 change. Revert, anything that should be there will be committed
+ separately.
-commit a4537e79ab4ac6db4493c5158744b9ebde5efcb0
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Feb 23 21:21:16 2022 +0000
+commit 527cb43fa1b4e55df661feabbac51b8e608b6519
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Jul 14 11:22:08 2022 +1000
- upstream: put back the scp manpage changes for SFTP mode too
+ Return ERANGE from getcwd() if buffer size is 1.
- OpenBSD-Commit-ID: 05dc53921f927e1b5e5694e1f3aa314549f2e768
+ If getcwd() is supplied a buffer size of exactly 1 and a path of "/", it
+ could result in a nul byte being written out of array bounds. POSIX says
+ it should return ERANGE if the path will not fit in the available buffer
+ (with terminating nul). 1 byte cannot fit any possible path with its nul,
+ so immediately return ERANGE in that case.
+
+ OpenSSH never uses getcwd() with this buffer size, and all current
+ (and even quite old) platforms that we are currently known to work
+ on have a native getcwd() so this code is not used on those anyway.
+ Reported by Qualys, ok djm@
-commit 449bcb8403adfb9724805d02a51aea76046de185
-Author: deraadt@openbsd.org <deraadt@openbsd.org>
-Date: Wed Feb 23 19:01:00 2022 +0000
+commit 36857fefd8849c4b0e877cfd9d1eb22f79b76650
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Jul 14 10:02:35 2022 +1000
- upstream: and we go back to testing sftp-scp after the 8.9
-
- release...
+ Split README.platform into its own line.
- OpenBSD-Commit-ID: a80440168258adca543a4607b871327a279c569c
-
-commit 166456cedad3962b83b848b1e9caf80794831f0f
-Author: Damien Miller <djm@mindrot.org>
-Date: Wed Feb 23 22:31:11 2022 +1100
-
- makedepend
+ README.platform has general platform-specific information, having it
+ following text about FIDO2 on the same line could imply that it only
+ has information about FIDO2.
-commit 32ebaa0dbca5d0bb86e384e72bebc153f48413e4
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Feb 23 11:18:13 2022 +0000
+commit 00a496c6c14f2d41f2a9365714d494dd5f3aac9f
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Jul 14 09:56:01 2022 +1000
- upstream: avoid integer overflow of auth attempts (harmless, caught
-
- by monitor)
+ Clarify README.md text.
- OpenBSD-Commit-ID: 488ad570b003b21e0cd9e7a00349cfc1003b4d86
+ Clarify the text about the implications of building without OpenSSL, and
+ prefix the "configure --help" example command with a "./" so it's likely
+ to work as-is in more shells. From bz#3461.
-commit 6e0258c64c901753df695e06498b26f9f4812ea6
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Feb 23 11:17:10 2022 +0000
+commit f40b52f21fbc52eb513279168a49d3285c65256c
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Tue Jul 12 19:48:44 2022 +1000
- upstream: randomise the password used in fakepw
+ Remove special casing of crypt().
- OpenBSD-Commit-ID: 34e159f73b1fbf0a924a9c042d8d61edde293947
+ Configure goes to some lengths to pick crypt() from either libcrypt
+ or OpenSSL's libcrypto because they can more or less featureful (eg
+ supporting md5-style passwords).
+
+ OpenSSL removed its crypt() interface in 2002:
+ https://github.com/openssl/openssl/commit/69deec58 so these hijinks
+ should no longer be necessary. This also only links sshd with libcrypt
+ which is the only thing that needs it. ok djm@
-commit bf114d6f0a9df0b8369823d9a0daa6c72b0c4cc9
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Feb 23 11:15:57 2022 +0000
+commit 76f4e48631d7b09fb243b47d7b393d100d3741b7
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Jul 13 13:17:47 2022 +1000
- upstream: use asprintf to construct .rhosts paths
+ Only refuse to use OpenSSL 3.0.4 on x86_64.
- OpenBSD-Commit-ID: 8286e8d3d2c6ff916ff13d041d1713073f738a8b
+ The potential RCE only impacts x86_64, so only refuse to use it if we're
+ targetting a potentially impacted architecture. ok djm@
-commit c07e154fbdc7285e9ec54e78d8a31f7325d43537
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Feb 23 11:07:09 2022 +0000
+commit e75bbc1d88491fa85e61b2cc8783d4bbd00cd131
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Tue Jul 12 14:37:15 2022 +1000
- upstream: openssh-8.9
-
- OpenBSD-Commit-ID: 5c5f791c87c483cdab6d9266b43acdd9ca7bde0e
+ Capture stderr output from configure.
-commit bc16667b4a1c3cad7029304853c143a32ae04bd4
+commit d9eaea4bea6271bcee6a2b9428f1271faf2d033b
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Tue Feb 22 15:29:22 2022 +1100
+Date: Tue Jul 12 12:54:49 2022 +1000
- Extend select+rlimit sanbox test to include poll.
-
- POSIX specifies that poll() shall fail if "nfds argument is greater
- than {OPEN_MAX}". The setrlimit sandbox sets this to effectively zero
- so this causes poll() to fail in the preauth privsep process.
+ Refuse to use OpenSSL 3.0.4 due to potential RCE.
- This is likely the underlying cause for the previously observed similar
- behaviour of select() on plaforms where it is implement in userspace on
- top of poll().
+ OpenSSL has a potential RCE in its RSA implementation (CVE-2022-2274)
+ so refuse to use that specific version.
-commit 6520c488de95366be031d49287ed243620399e23
+commit fb2f3a61bf3d28fff285524535f7ffcd177c9235
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Tue Feb 22 13:08:59 2022 +1100
+Date: Tue Jul 12 12:54:24 2022 +1000
- Add Alpine Linux test VM.
+ Move unset to before we set anything.
-commit a4b325a3fc82d11e0f5d61f62e7fde29415f7afb
+commit c483a5c0fb8e8b8915fad85c5f6113386a4341ca
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Tue Feb 22 12:27:07 2022 +1100
+Date: Wed Jul 6 11:52:54 2022 +1000
- Include sys/param.h if present.
-
- Needed for howmany() on MUSL systems such as Alpine.
+ Test against openssl-3.0.5.
-commit 5a102e9cb287a43bd7dfe594b775a89a8e94697c
+commit 669a56bcfe73f8b985f2bba476ba834d55253acf
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Tue Feb 22 12:25:52 2022 +1100
+Date: Tue Jul 5 18:35:53 2022 +1000
- Only include sys/poll.h if we don't have poll.h.
+ Update sanitizer test targets:
- Prevents warnings on MUSL based systems such as Alpine.
+ - remove clang-sanitize-memory for now. It takes so long that the test
+ times out.
+ - add gcc sanitize-address and sanitize-undefined test targets.
-commit 7c0d4ce911d5c58b6166b2db754a4e91f352adf5
-Author: Damien Miller <djm@mindrot.org>
-Date: Tue Feb 22 11:14:51 2022 +1100
+commit 48cc68b69118b3ce8d07fd4f82e00d58667d5379
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Tue Jul 5 16:23:28 2022 +1000
- disable agent-restrict test on minix3
-
- Minix seems to have a platform-wide limit on the number of
- select(2) syscalls that can be concurrently issued. This test
- seems to exceed this limit.
-
- Refer to:
-
- https://github.com/Stichting-MINIX-Research-Foundation/minix/blob/R3.3.0/minix/servers/vfs/select.c#L114
- https://github.com/Stichting-MINIX-Research-Foundation/minix/blob/R3.3.0/minix/servers/vfs/select.c#L30-L31
+ Add GCC address sanitizer build/test.
-commit 81d33d8e3cf7ea5ce3a5653c6102b623e019428a
+commit 55c60bdd39b82457e92efa77da8d16cfa6a49391
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Mon Feb 21 21:27:20 2022 +1100
+Date: Tue Jul 5 12:02:33 2022 +1000
- Skip agent-getpeereid when running as root.
+ Move sanitizer logs into regress for collection.
-commit fbd772570a25436a33924d91c164d2b24021f010
+commit 35ef2b3b6ef198f8574904a45780487ec2f17858
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Sun Feb 20 03:47:26 2022 +0000
+Date: Mon Jul 4 09:10:31 2022 +0000
- upstream: Aproximate realpath on the expected output by deduping
+ upstream: Add TEST_REGRESS_CACHE_DIR.
- leading slashes. Fixes test failure when user's home dir is / which is
- possible in some portable configurations.
+ If set, it is used to cache regress test names that have succeeded and
+ skip those on a re-run.
- OpenBSD-Regress-ID: 53b8c53734f8893806961475c7106397f98d9f63
+ OpenBSD-Regress-ID: a7570dd29a58df59f2cca647c3c2ec989b49f247
-commit 336685d223a59f893faeedf0a562e053fd84058e
+commit 7394ed80c4de8b228a43c8956cf2fa1b9c6b2622
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sun Feb 20 13:30:52 2022 +1100
+Date: Sun Jul 3 21:46:44 2022 +1000
- Really move DSA to end of list.
+ Add clang sanitizer tests.
+
+commit bfce0e66b6017a9bfab450b9dc7d4b16f90de817
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sun Jul 3 18:14:09 2022 +1000
+
+ Skip all rlimit tests when sandboxing disabled.
- In commit ad16a84e syncing from OpenBSD, RSA was accidentally moved to
- the end of the list instead of DSA. Spotted by andrew at fyfe.gb.net.
+ The rlimit tests can hang when being run with some compiler sanitizers
+ so skip all of them if sandbox=no.
-commit 63bf4f49ed2fdf2da6f97136c9df0c8168546eb3
+commit 6208d611520f9ea94d5369f9da404b709930029d
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Feb 18 12:12:21 2022 +1100
+Date: Sun Jul 3 17:54:49 2022 +1000
- Add test configs for MUSL C library.
+ Move checks for pollfd.fd and nfds_t.
+
+ Move the checks for struct pollfd.fd and nfds_t to before the sandboxing
+ checks. This groups all the sandbox checks together so we can skip them
+ all when sandboxing is disabled.
-commit f7fc6a43f1173e8b2c38770bf6cee485a562d03b
-Author: Damien Miller <djm@mindrot.org>
-Date: Thu Feb 17 22:54:19 2022 +1100
+commit 322964f8f2e9c321e77ebae1e4d2cd0ccc5c5a0b
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Jul 1 05:08:23 2022 +0000
- minix needs BROKEN_POLL too; chokes on /dev/null
+ upstream: Remove leftover line.
+
+ Remove extra line leftover from merge conflict. ok djm@
+
+ OpenBSD-Commit-ID: 460e2290875d7ae64971a7e669c244b1d1c0ae2e
-commit 667fec5d4fe4406745750a32f69b5d2e1a75e94b
+commit 7ec81daad0e03a64e8d91c5590960c48c1a899a3
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Feb 17 10:58:27 2022 +0000
+Date: Fri Jul 1 04:45:50 2022 +0000
- upstream: check for EINTR/EAGAIN failures in the rfd fast-path; caught
+ upstream: use consistent field names (s/char/byte)
- by dtucker's minix3 vm :) ok dtucker@
+ in format description
- OpenBSD-Commit-ID: 2e2c895a3e82ef347aa6694394a76a438be91361
+ OpenBSD-Commit-ID: 3de33572733ee7fcfd7db33d37db23d2280254f0
-commit 41417dbda9fb55a0af49a8236e3ef9d50d862644
+commit 32e82a392d9f263485effdd606ff5862d289a4a0
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Feb 17 22:05:29 2022 +1100
-
- Comment hurd test, the VM is currently broken.
-
-commit b2aee35a1f0dc798339b3fcf96136da71b7e3f6d
-Author: Damien Miller <djm@mindrot.org>
-Date: Thu Feb 17 21:15:16 2022 +1100
+Date: Fri Jul 1 13:55:19 2022 +1000
- find sk-dummy.so when build_dir != src_dir
+ Skip select+rlimit check if sandboxing is disabled
- spotted by Corinna Vinschen; feedback & ok dtucker@
-
-commit 62a2d4e50b2e89f2ef04576931895d5139a5d037
-Author: Damien Miller <djm@mindrot.org>
-Date: Wed Feb 16 16:26:17 2022 +1100
-
- update versions in preparation for 8.9 release
+ It's not needed in that case, and the test can fail when being built
+ with some compiler memory sanitizer flags. bz#3441
-commit dd6d3dded721ac653ea73c017325e5bfeeec837f
+commit 4be7184ebe2a2ccef175983517a35ee06766e1b4
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Feb 15 05:13:36 2022 +0000
+Date: Fri Jul 1 03:52:57 2022 +0000
- upstream: document the unbound/host-bound options to
+ upstream: bump up loglevel from debug to info when unable to open
- PubkeyAuthentication; spotted by HARUYAMA Seigo
+ authorized keys/principals file for errno != ENOENT; bz2042 ok dtucker
- OpenBSD-Commit-ID: 298f681b66a9ecd498f0700082c7a6c46e948981
+ OpenBSD-Commit-ID: e79aa550d91ade6a80f081bda689da24c086d66b
-commit df93529dd727fdf2fb290700cd4f1adb0c3c084b
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Mon Feb 14 14:19:40 2022 +1100
+commit 6c31ba10e97b6953c4f325f526f3e846dfea647a
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Jul 1 03:39:44 2022 +0000
- Test if sshd accidentally acquires controlling tty
+ upstream: Don't leak the strings allocated by order_hostkeyalgs()
- When SSHD_ACQUIRES_CTTY is defined, test for the problematic behaviour
- in the STREAMS code before activating the workaround. ok djm@
+ and list_hostkey_types() that are passed to compat_pkalg_proposal(). Part of
+ github PR#324 from ZoltanFridrich, ok djm@
+
+ This is a roll-forward of the previous rollback now that the required
+ changes in compat.c have been done.
+
+ OpenBSD-Commit-ID: c7cd93730b3b9f53cdad3ae32462922834ef73eb
-commit 766176cfdbfd7ec38bb6118dde6e4daa0df34888
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Feb 12 10:24:56 2022 +1100
+commit 486c4dc3b83b4b67d663fb0fa62bc24138ec3946
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Jul 1 03:35:45 2022 +0000
- Add cygwin-release test config.
+ upstream: Always return allocated strings from the kex filtering so
- This tests the flags used to build the cygwin release binaries.
+ that we can free them later. Fix one leak in compat_kex_proposal. Based on
+ github PR#324 from ZoltanFridrich with some simplications by me. ok djm@
+
+ OpenBSD-Commit-ID: 9171616da3307612d0ede086fd511142f91246e4
-commit b30698662b862f5397116d23688aac0764e0886e
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Feb 11 21:00:35 2022 +1100
+commit 96faa0de6c673a2ce84736eba37fc9fb723d9e5c
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Jul 1 00:36:30 2022 +0000
- Move SSHD_ACQUIRES_CTTY workaround into compat.
+ upstream: ignore SIGPIPE earlier in main(), specifically before
- On some (most? all?) SysV based systems with STREAMS based ptys,
- sshd could acquire a controlling terminal during pty setup when
- it pushed the "ptem" module, due to what is probably a bug in
- the STREAMS driver that's old enough to vote. Because it was the
- privileged sshd's controlling terminal, it was not available for
- the user's session, which ended up without one. This is known to
- affect at least Solaris <=10, derivatives such as OpenIndiana and
- several other SysV systems. See bz#245 for the backstory.
-
- In the we past worked around that by not calling setsid in the
- privileged sshd child, which meant it was not a session or process
- group leader. This solved controlling terminal problem because sshd
- was not eligble to acquire one, but had other side effects such as
- not cleaning up helper subprocesses in the SIGALRM handler since it
- was not PG leader. Recent cleanups in the signal handler uncovered
- this, resulting in the LoginGraceTime timer not cleaning up privsep
- unprivileged processes.
-
- This change moves the workaround into the STREAMS pty allocation code,
- by allocating a sacrificial pty to act as sshd's controlling terminal
- before allocating user ptys, so those are still available for users'
- sessions.
-
- On the down side:
- - this will waste a pty per ssh connection on affected platforms.
-
- On the up side:
- - it makes the process group behaviour consistent between platforms.
-
- - it puts the workaround nearest the code that actually causes the
- problem and competely out of the mainline code.
-
- - the workaround is only activated if you use the STREAMS code. If,
- say, Solaris 11 has the bug but also a working openpty() it doesn't
- matter that we defined SSHD_ACQUIRES_CTTY.
-
- - the workaround is only activated when the fist pty is allocated,
- ie in the post-auth privsep monitor. This means there's no risk
- of fd leaks to the unprivileged processes, and there's no effect on
- sessions that do not allocate a pty.
+ muxclient() which performs operations that could cause one; Reported by Noam
+ Lewis via bz3454, ok dtucker@
- Based on analysis and work by djm@, ok djm@
+ OpenBSD-Commit-ID: 63d8e13276869eebac6d7a05d5a96307f9026e47
-commit cd00b48cf10f3565936a418c1e6d7e48b5c36140
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Feb 11 20:09:32 2022 +1100
+commit 33efac790f6b09d54894ba6c3e17dfb08b6fc7e1
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Tue Jun 28 06:09:14 2022 +0000
- Simplify handling of --with-ssl-dir.
+ upstream: reflect the update to -D arg name in usage();
- ok djm@
+ OpenBSD-Commit-ID: abdcde4f92b1ef094ae44210ee99d3b0155aad9c
-commit ea13fc830fc0e0dce2459f1fab2ec5099f73bdf0
+commit c71a1442d02f0a3586109dfe2cb366de36dee08e
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Feb 11 13:39:29 2022 +1100
+Date: Wed Jun 29 18:28:47 2022 +1000
- Stop testing OpenBSD HEAD on 6.9 and 7.0.
+ Update OpenSSL tests to the most recent releases.
+
+commit 2a822f29300b2de7335fbff65f0b187a0c582304
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Jun 27 21:41:55 2022 +0000
+
+ upstream: allow arguments to sftp -D option, e.g. sftp -D
- HEAD is not guaranteed to work on previous stable branches, and at the
- moment is broken due to libfido API changes.
+ "/usr/libexec/sftp-server -el debug3"
+
+ ok markus@
+
+ OpenBSD-Commit-ID: 5a002b9f3a7aef2731fc0ffa9c921cf15f38ecce
-commit 50b9e4a4514697ffb9592200e722de6b427cb9ff
+commit 2369a2810187e08f2af5d58b343956062fb96ee8
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Feb 11 00:43:56 2022 +0000
+Date: Fri Jun 24 10:45:06 2022 +0000
- upstream: Always initialize delim before passing to hpdelim2 which
+ upstream: Roll back previous KEX changes as they aren't safe until
- might not set it. Found by the Valgrind tests on github, ok deraadt@
+ compat_pkalg_proposal and friends always allocate their returned strings.
+ Reported by Qualys.
- OpenBSD-Commit-ID: c830c0db185ca43beff3f41c19943c724b4f636d
+ OpenBSD-Commit-ID: 1c7a88a0d5033f42f88ab9bec58ef1cf72c81ad0
-commit 6ee53064f476cf163acd5521da45b11b7c57321b
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Feb 11 10:03:06 2022 +1100
+commit 646686136c34c2dbf6a01296dfaa9ebee029386d
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Jun 24 04:37:00 2022 +0000
- Fix helper include path and remove excess code.
+ upstream: Don't leak the strings allocated by order_hostkeyalgs()
- Looks like test_hpdelim.c was imported twice into the same file.
- Spotted by kevin.brott at gmail com and chris at cataclysmal org.
+ and list_hostkey_types() that are passed to compat_pkalg_proposal(). Part of
+ github PR#324 from ZoltanFridrich, ok djm@
+
+ OpenBSD-Commit-ID: b2f6e5f60f2bba293b831654328a8a0035ef4a1b
-commit 9fa63a19f68bc87452d3cf5c577cafad2921b7a4
+commit 193c6d8d905dde836b628fc07a7b9cf2d347e2a3
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Feb 10 23:27:02 2022 +1100
+Date: Sat Jun 25 12:16:15 2022 +1000
- Put poll.h inside ifdef.
+ Zero out LIBFIDO2 when SK support not usable.
+
+ Prevents us from trying to link them into ssh-sk-helper and failing to
+ build.
-commit 3ac00dfeb54b252c15dcbf1971582e9e3b946de6
+commit 40f5d849d25c60b4ae21261e78484d435f5cfd51
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Feb 10 22:17:31 2022 +1100
+Date: Sat Jun 25 11:47:28 2022 +1000
- We now support POLLPRI so actually define it.
+ Disable SK support if FIDO libs not found.
-commit 25bd659cc72268f2858c5415740c442ee950049f
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Sun Feb 6 22:58:33 2022 +0000
+commit 5fd922ade1b25880fe8a8249f5c0385e413108f9
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Jun 24 14:43:54 2022 +1000
- upstream: Add test for empty hostname with port.
-
- OpenBSD-Regress-ID: e19e89d3c432b68997667efea44cf015bbe2a7e3
+ fix broken case statement in previous
-commit a29af853cff41c0635f0378c00fe91bf9c91dea4
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Feb 4 07:53:44 2022 +0000
+commit f51423bdaf0008d46b6af082bcfd7a22a87375f0
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Jun 24 14:40:42 2022 +1000
- upstream: Add unit tests for hpdelim.
+ request 1.1x API compatibility for OpenSSL >=3.x
- OpenBSD-Regress-ID: be97b85c19895e6a1ce13c639765a3b48fd95018
+ idea/patch from Pedro Martelletto via GHPR#322; ok dtucker@
-commit 9699151b039ecc5fad9ac6c6c02e9afdbd26f15f
+commit 455cee8d6c2e4c48c5af9faead3599c49948411e
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Feb 10 04:12:38 2022 +0000
+Date: Fri Jun 24 04:27:14 2022 +0000
- upstream: revert for imminent OpenSSH release, which wil ship with
-
- scp in RCP mode.
-
- > revision 1.106
- > date: 2021/10/15 14:46:46; author: deraadt; state: Exp; lines: +13 -9; commitid: w5n9B2RE38tFfggl;
- > openbsd 7.0 release shipped with the (hopefully last) scp that uses RCP
- > protocol for copying. Let's get back to testing the SFTP protocol.
+ upstream: make it clear that RekeyLimit applies to both transmitted
- This will be put back once the OpenSSH release is done.
+ and received data. GHPR#328 from Jan Pazdziora
- OpenBSD-Commit-ID: 0c725481a78210aceecff1537322c0b2df03e768
+ OpenBSD-Commit-ID: d180a905fec9ff418a75c07bb96ea41c9308c3f9
-commit 45279abceb37c3cbfac8ba36dde8b2c8cdd63d32
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Tue Feb 8 08:59:12 2022 +0000
+commit 17904f05802988d0bb9ed3c8d1d37411e8f459c3
+Author: tobhe@openbsd.org <tobhe@openbsd.org>
+Date: Tue Jun 21 14:52:13 2022 +0000
- upstream: Switch hpdelim interface to accept only ":" as delimiter.
+ upstream: Make sure not to fclose() the same fd twice in case of an
- Historicallly, hpdelim accepted ":" or "/" as a port delimiter between
- hosts (or addresses) and ports. These days most of the uses for "/"
- are no longer accepted, so there are several places where it checks the
- delimiter to disallow it. Make hpdelim accept only ":" and use hpdelim2
- in the other cases. ok djm@
+ error.
- OpenBSD-Commit-ID: 7e6420bd1be87590b6840973f5ad5305804e3102
-
-commit a1bcbf04a7c2d81944141db7ecd0ba292d175a66
-Author: pedro martelletto <pedro@yubico.com>
-Date: Mon Feb 7 09:09:59 2022 +0100
-
- fix typos in previous
-
-commit 56192518e329b39f063487bc2dc4d796f791eca0
-Author: Damien Miller <djm@mindrot.org>
-Date: Mon Feb 7 12:53:47 2022 +1100
-
- compat code for fido_assert_set_clientdata()
+ ok dtucker@
+
+ OpenBSD-Commit-ID: e384c4e05d5521e7866b3d53ca59acd2a86eef99
-commit d6b5aa08fdcf9b527f8b8f932432941d5b76b7ab
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Feb 7 01:25:12 2022 +0000
+commit f29d6cf98c25bf044079032d22c1a57c63ab9d8e
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Sat Jun 18 02:17:16 2022 +0000
- upstream: use libfido2 1.8.0+ fido_assert_set_clientdata() instead
+ upstream: Don't attempt to fprintf a null identity comment. From
- of manually hashing data outselves. Saves a fair bit of code and makes life
- easier for some -portable platforms.
+ Martin Vahlensieck via tech@.
- OpenBSD-Commit-ID: 351dfaaa5ab1ee928c0e623041fca28078cff0e0
+ OpenBSD-Commit-ID: 4c54d20a8e8e4e9912c38a7b4ef5bfc5ca2e05c2
-commit 86cc93fd3c26b2e0c7663c6394995fb04ebfbf3b
-Author: jsg@openbsd.org <jsg@openbsd.org>
-Date: Sun Feb 6 00:29:03 2022 +0000
+commit ad1762173bb38716a106e8979806149fd0f2753e
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Jun 17 01:00:03 2022 +0000
- upstream: remove please from manual pages ok jmc@ sthen@ millert@
+ upstream: Log an error if pipe() fails while accepting a
- OpenBSD-Commit-ID: 6543acb00f4f38a23472538e1685c013ca1a99aa
+ connection. bz#3447, from vincent-openssh at vinc17 net, ok djm@
+
+ OpenBSD-Commit-ID: 9d59f19872b94900a5c79da2d57850241ac5df94
-commit ad16a84e64a8cf1c69c63de3fb9008320a37009c
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Feb 4 02:49:17 2022 +0000
+commit 9c59e7486cc8691401228b43b96a3edbb06e0412
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Jun 24 14:20:43 2022 +1000
- upstream: Since they are deprecated, move DSA to the end of the
+ automatically enable built-in FIDO support
- default list of public keys so that they will be tried last. From github
- PR#295 from "ProBackup-nl", ok djm@
+ If libfido2 is found and usable, then enable the built-in
+ security key support unless --without-security-key-builtin
+ was requested.
- OpenBSD-Commit-ID: 7e5d575cf4971d4e2de92e0b6d6efaba53598bf0
+ ok dtucker@
-commit 253de42753de85dde266e061b6fec12ca6589f7d
+commit 7d25b37fb2a5ff4dadabcbdac6087a97479434f5
Author: Damien Miller <djm@mindrot.org>
-Date: Wed Feb 2 16:52:07 2022 +1100
+Date: Fri Jun 24 13:46:39 2022 +1000
- portable-specific string array constification
+ fix possible NULL deref when built without FIDO
- from Mike Frysinger
+ Analysis/fix from kircher in bz3443; ok dtucker@
-commit dfdcc2220cf359c492d5d34eb723370e8bd8a19e
+commit f5ba85daddfc2da6a8dab6038269e02c0695be44
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Feb 1 23:37:15 2022 +0000
+Date: Wed Jun 15 16:08:25 2022 +0000
- upstream: test 'ssh-keygen -Y find-principals' with wildcard
+ upstream: make sure that UseDNS hostname lookup happens in the monitor
- principals; from Fabian Stelzer
+ and not in the pledge(2)'d unprivileged process; fixes regression caused by
+ recent refactoring spotted by henning@
- OpenBSD-Regress-ID: fbe4da5f0032e7ab496527a5bf0010fd700f8f40
+ OpenBSD-Commit-ID: a089870b95101cd8881a2dff65b2f1627d13e88d
-commit 968e508967ef42480cebad8cf3172465883baa77
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Jan 21 02:54:41 2022 +0000
+commit acb2059febaddd71ee06c2ebf63dcf211d9ab9f2
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Jun 3 04:47:21 2022 +0000
- upstream: Enable all supported ciphers and macs in the server
+ upstream: move auth_openprincipals() and auth_openkeyfile() over to
- before trying to benchmark them. Increase the data file size to get more
- signal.
+ auth2-pubkeyfile.c too; they make more sense there.
- OpenBSD-Regress-ID: dc3697d9f7defdfc51c608782c8e750128e46eb6
+ OpenBSD-Commit-ID: 9970d99f900e1117fdaab13e9e910a621b7c60ee
-commit 15b7199a1fd37eff4c695e09d573f3db9f4274b7
+commit 3d9b0845f34510111cc693bb99a667662ca50cd8
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Feb 1 23:34:47 2022 +0000
+Date: Fri Jun 3 04:31:54 2022 +0000
- upstream: allow 'ssh-keygen -Y find-principals' to match wildcard
+ upstream: test setenv in both client and server, test first-match-wins
- principals in allowed_signers files; from Fabian Stelzer
+ too
- OpenBSD-Commit-ID: 1e970b9c025b80717dddff5018fe5e6f470c5098
+ OpenBSD-Regress-ID: 4c8804f9db38a02db480b9923317457b377fe34b
-commit 541667fe6dc26d7881e55f0bb3a4baa6f3171645
+commit 22e1a3a71ad6d108ff0c5f07f93c3fcbd30f8b40
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Feb 1 23:32:51 2022 +0000
+Date: Fri Jun 3 04:30:46 2022 +0000
- upstream: mark const string array contents const too, i.e. static
+ upstream: Make SetEnv directives first-match-wins in both
- const char *array => static const char * const array from Mike Frysinger
+ sshd_config and sshd_config; previously if the same name was reused then the
+ last would win (which is the opposite to how the config is supposed to work).
- OpenBSD-Commit-ID: a664e31ea6a795d7c81153274a5f47b22bdc9bc1
-
-commit 8cfa73f8a2bde4c98773f33f974c650bdb40dd3c
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Feb 1 23:11:11 2022 +0000
-
- upstream: better match legacy scp behaviour: show un-expanded paths
+ While there, make the ssh_config parsing more like sshd_config.
- in error messages. Spotted by and ok tb@
+ bz3438, ok dtucker
- OpenBSD-Commit-ID: 866c8ffac5bd7d38ecbfc3357c8adfa58af637b7
+ OpenBSD-Commit-ID: 797909c1e0262c0d00e09280459d7ab00f18273b
-commit 4e62c13ab419b4b224c8bc6a761e91fcf048012d
+commit 38ed6c57e9e592c08e020fa6e82b45b4e1040970
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Tue Feb 1 07:57:32 2022 +0000
+Date: Fri Jun 3 04:00:15 2022 +0000
- upstream: Remove explicit kill of privsep preauth child's PID in
+ upstream: Add missing *-sk types to ssh-keyscan manpage. From
- SIGALRM handler. It's no longer needed since the child will get terminated by
- the SIGTERM to the process group that cleans up any auth helpers, it
- simplifies the signal handler and removes the risk of a race when updating
- the PID. Based on analysis by HerrSpace in github PR#289, ok djm@
+ skazi0 via github PR#294.
- OpenBSD-Commit-ID: 2be1ffa28b4051ad9e33bb4371e2ec8a31d6d663
+ OpenBSD-Commit-ID: fda2c869cdb871f3c90a89fb3f985370bb5d25c0
-commit 2a7ccd2ec4022917b745af7186f514f365b7ebe9
-Author: guenther@openbsd.org <guenther@openbsd.org>
-Date: Fri Jan 28 06:18:42 2022 +0000
+commit ea97ec98c41ec2b755dfab459347db674ff9a5de
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Jun 3 03:21:09 2022 +0000
- upstream: When it's the possessive of 'it', it's spelled "its",
+ upstream: Add period at end of "not known by any other names"
- without the apostrophe.
+ message. github PR#320 from jschauma, ok djm@
- OpenBSD-Commit-ID: fb6ab9c65bd31de831da1eb4631ddac018c5fae7
+ OpenBSD-Commit-ID: bd60809803c4bfd3ebb7c5c4d918b10e275266f2
-commit 8a0848cdd3b25c049332cd56034186b7853ae754
-Author: Alex James <theracermaster@gmail.com>
-Date: Sun Jan 30 16:13:36 2022 -0600
+commit 88e376fcd67478ad1660d94bc73ab348ac9f4527
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Jun 3 03:17:42 2022 +0000
- sandbox-seccomp-filter: allow gettid
+ upstream: ssh-keygen -A: do not generate DSA keys by default.
- Some allocators (such as Scudo) use gettid while tracing allocations [1].
- Allow gettid in preauth to prevent sshd from crashing with Scudo.
+ Based on github PR#303 from jsegitz with man page text from jmc@, ok markus@
+ djm@
- [1]: https://github.com/llvm/llvm-project/blob/llvmorg-13.0.0/compiler-rt/lib/gwp_asan/common.cpp#L46
+ OpenBSD-Commit-ID: 5c4c57bdd7063ff03381cfb6696659dd3f9f5b9f
-commit b30d32159dc3c7052f4bfdf36357996c905af739
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Jan 22 00:49:34 2022 +0000
+commit 6b3fb624675082a1e5aa615d1b8479873d8b5731
+Author: naddy@openbsd.org <naddy@openbsd.org>
+Date: Tue May 31 14:05:12 2022 +0000
- upstream: add a ssh_packet_process_read() function that reads from
-
- a fd directly into the transport input buffer.
-
- Use this in the client and server mainloops to avoid unnecessary
- copying. It also lets us use a more greedy read size without penalty.
+ upstream: ssh-keygen: implement "verify-required" certificate option.
- Yields a 2-3% performance gain on cipher-speed.sh (in a fairly
- unscientific test tbf)
+ This was already documented when support for user-verified FIDO
+ keys was added, but the ssh-keygen(1) code was missing.
- feedback dtucker@ ok markus@
+ ok djm@
- OpenBSD-Commit-ID: df4112125bf79d8e38e79a77113e1b373078e632
+ OpenBSD-Commit-ID: f660f973391b593fea4b7b25913c9a15c3eb8a06
-commit a1a8efeaaa9cccb15cdc0a2bd7c347a149a3a7e3
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Jan 22 00:45:31 2022 +0000
+commit b7f86ffc301be105bba9a3e0618b6fab3ae379bd
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Sat May 28 05:57:56 2022 +0000
- upstream: Use sshbuf_read() to read directly into the channel input
+ upstream: keywords ref ssh_config.5;
- buffer rather than into a stack buffer that needs to be copied again;
- Improves performance by about 1% on cipher-speed.sh feedback dtucker@ ok
- markus@
+ from caspar schutijser
- OpenBSD-Commit-ID: bf5e6e3c821ac3546dc8241d8a94e70d47716572
+ OpenBSD-Commit-ID: f146a19d7d5c9374c3b9c520da43b2732d7d1a4e
-commit 29a76994e21623a1f84d68ebb9dc5a3c909fa3a7
+commit dc7bc52372f2744fa39191577be5306ee57aacd4
Author: Damien Miller <djm@mindrot.org>
-Date: Tue Jan 25 11:52:34 2022 +1100
+Date: Mon May 30 09:29:09 2022 +1000
- depend
+ fix some bugs in the fuzzer
-commit 754e0d5c7712296a7a3a83ace863812604c7bc4f
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Jan 22 00:43:43 2022 +0000
+commit 1781f507c113667613351c19898efaf1e311a865
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri May 27 18:19:48 2022 +1000
- upstream: Add a sshbuf_read() that attempts to read(2) directly in
-
- to a sshbuf; ok markus@
+ Test against OpenSSL 1.1.1o and 3.0.3.
+
+commit c53906e0c59e569691b4095d3e8db79cf78fa058
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri May 27 18:18:31 2022 +1000
+
+ Test against LibreSSL 3.5.3.
+
+commit 9b3ad432ad2f19319bcc089370e356c6315d682f
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri May 27 17:00:43 2022 +1000
+
+ fuzzer for authorized_keys parsing
- OpenBSD-Commit-ID: 2d8f249040a4279f3bc23c018947384de8d4a45b
+ mostly redundant to authopt_fuzz, but it's sensitive code so IMO it
+ makes sense to test this layer too
-commit c7964fb9829d9ae2ece8b51a76e4a02e8449338d
+commit c83d8c4d6f3ccceef84d46de107f6b71cda06359
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jan 21 07:04:19 2022 +0000
+Date: Fri May 27 05:02:46 2022 +0000
- upstream: add a helper for writing an error message to the
+ upstream: split the low-level file handling functions out from
- stderr_buf and setting quit_pending; no functional change but saves a bunch
- of boilerplate
+ auth2-pubkey.c
- OpenBSD-Commit-ID: 0747657cad6b9eabd514a6732adad537568e232d
+ Put them in a new auth2-pubkeyfile.c to make it easier to refer to them
+ (e.g. in unit/fuzz tests) without having to refer to everything else
+ pubkey auth brings in.
+
+ ok dtucker@
+
+ OpenBSD-Commit-ID: 3fdca2c61ad97dc1b8d4a7346816f83dc4ce2217
-commit d23b4f7fdb1bd87e2cd7a9ae7c198ae99d347916
+commit 3b0b142d2a0767d8cd838e2f3aefde8a0aaa41e1
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jan 21 06:58:06 2022 +0000
+Date: Fri May 27 05:01:25 2022 +0000
- upstream: correct comment and use local variable instead of long
+ upstream: refactor authorized_keys/principals handling
- indirection; spotted by dtucker@
+ remove "struct ssh *" from arguments - this was only used to pass the
+ remote host/address. These can be passed in instead and the resulting
+ code is less tightly coupled to ssh_api.[ch]
- OpenBSD-Commit-ID: 5f65f5f69db2b7d80a0a81b08f390a63f8845965
+ ok dtucker@
+
+ OpenBSD-Commit-ID: 9d4373d013edc4cc4b5c21a599e1837ac31dda0d
-commit d069b020a02b6e3935080204ee44d233e8158ebb
-Author: deraadt@openbsd.org <deraadt@openbsd.org>
-Date: Fri Jan 21 00:53:40 2022 +0000
+commit 2c334fd36f80cb91cc42e4b978b10aa35e0df236
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri May 27 04:29:40 2022 +0000
- upstream: When poll(2) returns -1, for some error conditions
+ upstream: f sshpkt functions fail, then password is not cleared
- pfd[].revents is not cleared. There are subtle errors in various programs.
- In this particular case, the program should error out. ok djm millert
+ with freezero. Unconditionally call freezero to guarantee that password is
+ removed from RAM.
- OpenBSD-Commit-ID: 00f839b16861f7fb2adcf122e95e8a82fa6a375c
+ From tobias@ and c3h2_ctf via github PR#286, ok djm@
+
+ OpenBSD-Commit-ID: 6b093619c9515328e25b0f8093779c52402c89cd
-commit e204b34337a965feb439826157c191919fd9ecf8
-Author: Damien Miller <djm@mindrot.org>
-Date: Sat Jan 22 11:38:21 2022 +1100
+commit 5d3a77f4c5ae774c6796387266503f52c7cdc7c2
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri May 27 04:27:49 2022 +0000
- restore tty force-read hack
+ upstream: Avoid kill with -1 argument. The out_ctx label can be
- This portable-specific hack fixes a hang on exit for ttyful sessions
- on Linux and some SysVish Unix variants. It was accidentally disabled
- in commit 5c79952dfe1a (a precursor to the mainloop poll(2) conversion).
+ reached before fork has been called. If this happens, then kill -1 would be
+ called, sending SIGTERM to all processes reachable by the current process.
- Spotted by John in bz3383
+ From tobias@ and c3h2_ctf via github PR#286, ok djm@
+
+ OpenBSD-Commit-ID: 6277af1207d81202f5daffdccfeeaed4c763b1a8
-commit 68085066b6bad43643b43f5957fcc5fd34782ccd
-Author: Corinna Vinschen <vinschen@redhat.com>
-Date: Fri Jan 21 03:22:56 2022 +1100
+commit 533b31cd08e4b97f455466f91c36915e2924c15a
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri May 27 04:13:24 2022 +0000
- Fix signedness bug in Cygwin code
+ upstream: Note that ProxyJump also accepts the same tokens as
- The Cygwin-specific pattern match code has a bug. It checks
- the size_t value returned by mbstowcs for being < 0. The right
- thing to do is to check against (size_t) -1. Fix that.
+ ProxyCommand. From pallxk via github PR#305.
- Signed-off-by: Corinna Vinschen <vinschen@redhat.com>
+ OpenBSD-Commit-ID: 7115ac351b129205f1f1ffa6bbfd62abd76be7c5
-commit 2e5cfed513e84444483baf1d8b31c40072b05103
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Jan 20 13:26:27 2022 +1100
+commit 9d8c80f8a304babe61ca28f2e3fb5eb6dc9c39bf
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed May 25 06:03:44 2022 +0000
- Improve compatibility of early exit trap handling.
+ upstream: revert previous; it was broken (spotted by Theo)
- Dash (as used by the github runners) has some differences in its trap
- builtin:
- - it doesn't have -p (which is fine, that's not in posix).
- - it doesn't work in a subshell (which turns out to be in compliance
- with posix, which means bash isn't).
- - it doesn't work in a pipeline, ie "trap|cat" produces no output.
-
-commit 3fe6800b6027add478e648934cbb29d684e51943
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Jan 20 00:49:57 2022 +1100
-
- Move more tests out of valgrind-1 runner.
+ OpenBSD-Commit-ID: 457c79afaca2f89ec2606405c1059b98b30d8b0d
-commit 20da6ed136dd76e6a0b229ca3036ef9c7c7ef798
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Jan 19 15:37:39 2022 +1100
+commit 9e0d02ef7ce88b67643bfb1c2272c9f5f04cc680
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed May 25 00:31:13 2022 +0000
- Invoke EXIT handler early when using Valgrind.
+ upstream: make SSHBUF_DBG/SSHBUF_TELL (off by default and only enabled
- When using Valgrind, we need to wait for all invoked programs to
- complete before checking their valgrind logs. Some tests, notably
- agent-restrict, set an EXIT trap handler to clean up things like
- ssh-agent, but those do not get invoked until test-exec.sh exits.
- This causes the Valgrind wait to deadlock, so if present invoke
- the EXIT handler before checking the Valgrind logs.
+ via #define) dump to stderr rather than stdout
+
+ OpenBSD-Commit-ID: 10298513ee32db8390aecb0397d782d68cb14318
-commit ad2e0580c87b0714cf166bca9d926a95ddeee1c8
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Tue Jan 18 12:55:21 2022 +1100
+commit 2487163630f28be28b7e2396b4bd6511b98f1d3e
+Author: Tim Rice <tim@multitalents.net>
+Date: Tue May 24 10:21:25 2022 -0700
- Remove line leftover from upstream sync.
+ configure.ac: Add missing AC_DEFINE for caph_cache_tzdata test causing
+ HAVE_CAPH_CACHE_TZDATA to be missing from config.h.in.
+ Spotted by Bryan Drewery
-commit d1051c0f11a6b749027e26bbeb61b07df4b67e15
+commit bedb93415b60db3dfd704a3d525e82adb14a2481
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Jan 17 22:56:04 2022 +0000
+Date: Sun May 15 23:48:07 2022 +0000
- upstream: when decompressing zlib compressed packets, use
-
- Z_SYNC_FLUSH instead of Z_PARTIAL_FLUSH as the latter is not actually
- specified as a valid mode for inflate(). There should be no practical change
- in behaviour as the compression side ensures a flush that should make all
- data available to the receiver in all cases.
+ upstream: regress test for in-place transfers and clobbering larger
- repoted by lamm AT ibm.com via bz3372; ok markus
+ files with smaller ones; would have caught last regression in scp(1)
- OpenBSD-Commit-ID: 67cfc1fa8261feae6d2cc0c554711c97867cc81b
+ OpenBSD-Regress-ID: 19de4e88dd3a4f7e5c1618c9be3c32415bd93bc2
-commit d5981b1883746b1ae178a46229c26b53af99e37a
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Jan 17 21:41:04 2022 +0000
+commit b4f0d719c2548cb74da509fb65f384dada4ebd37
+Author: anton@openbsd.org <anton@openbsd.org>
+Date: Fri Apr 22 05:08:43 2022 +0000
- upstream: make most of the sftp errors more idiomatic, following
+ upstream: Only run agent-ptrace.sh if gdb is available as all
- the general form of "[local/remote] operation path: error message"; ok markus
+ architectures do not ship with gdb.
- OpenBSD-Commit-ID: 61364cd5f3a9fecaf8d63b4c38a42c0c91f8b571
+ OpenBSD-Regress-ID: ec53e928803e6b87f9ac142d38888ca79a45348d
-commit ac7c9ec894ed0825d04ef69c55babb49bab1d32e
+commit 9b73345f80255a7f3048026462f2c0c6a241eeac
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Jan 17 21:39:51 2022 +0000
+Date: Sun May 15 23:47:21 2022 +0000
- upstream: when transferring multiple files in SFTP mode, create the
+ upstream: fix in-place copies; r1.163 incorrectly skipped truncation in
- destination directory if it doesn't already exist to match olde-scp(1)
- behaviour. noticed by deraadt@ ok markus@
+ all cases, not just at the start of a transfer. This could cause overwrites
+ of larger files to leave junk at the end. Spotted by tb@
- OpenBSD-Commit-ID: cf44dfa231d4112f697c24ff39d7ecf2e6311407
+ OpenBSD-Commit-ID: b189f19cd68119548c8e24e39c79f61e115bf92c
-commit 39d17e189f8e72c34c722579d8d4e701fa5132da
+commit 56a0697fe079ff3e1ba30a2d5c26b5e45f7b71f8
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jan 14 03:43:48 2022 +0000
+Date: Fri May 13 06:31:50 2022 +0000
- upstream: allow pin-required FIDO keys to be added to ssh-agent(1).
+ upstream: arrange for scp, when in sftp mode, to not ftruncate(3) files
- ssh-askpass will be used to request the PIN at authentication time.
+ early
- From Pedro Martelletto, ok djm
+ previous behavious of unconditionally truncating the destination file
+ would cause "scp ~/foo localhost:" and "scp localhost:foo ~/" to
+ delete all the contents of their destination.
- OpenBSD-Commit-ID: de8189fcd35b45f632484864523c1655550e2950
+ spotted by solene@ sthen@, also bz3431; ok dtucker@
+
+ OpenBSD-Commit-ID: ca39fdd39e0ec1466b9666f15cbcfddea6aaa179
-commit 52423f64e13db2bdc31a51b32e999cb1bfcf1263
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jan 14 03:35:10 2022 +0000
+commit fbcef70c2832712f027bccea1aa9bc4b4103da93
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Mon May 9 08:25:27 2022 +0000
- upstream: ssh-sk: free a resident key's user id
-
- From Pedro Martelletto; ok dtucker & me
+ upstream: Remove errant apostrophe. From haruyama at queen-ml org.
- OpenBSD-Commit-ID: 47be40d602b7a6458c4c71114df9b53d149fc2e9
+ OpenBSD-Commit-ID: dc6b294567cb84b384ad6ced9ca469f2bbf0bd10
-commit 014e2f147a2788bfb3cc58d1b170dcf2bf2ee493
+commit 0086a286ea6bbd11ca9b664ac3bb12b27443d6eb
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jan 14 03:34:00 2022 +0000
+Date: Mon May 9 03:09:53 2022 +0000
- upstream: sshsk_load_resident: don't preallocate resp
-
- resp is allocated by client_converse(), at which point we lose
- the original pointer.
+ upstream: Allow existing -U (use agent) flag to work with "-Y sign"
- From Pedro Martelletto; ok dtucker & me
+ operations, where it will be interpreted to require that the private keys is
+ hosted in an agent; bz3429, suggested by Adam Szkoda; ok dtucker@
- OpenBSD-Commit-ID: 1f1b5ea3282017d6584dfed4f8370dc1db1f44b1
+ OpenBSD-Commit-ID: a7bc69873b99c32c42c7628ed9ea91565ba08c2f
-commit c88265f207dfe0e8bdbaf9f0eda63ed6b33781cf
+commit cb010744cc98f651b1029bb09efa986eb54e4ccf
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jan 14 03:32:52 2022 +0000
+Date: Sun May 8 22:58:35 2022 +0000
- upstream: sshsk_sign: trim call to sshkey_fingerprint()
+ upstream: improve error message when 'ssh-keygen -Y sign' is unable to
- the resulting fingerprint doesn't appear to be used for anything,
- and we end up leaking it.
+ load a private key; bz3429, reported by Adam Szkoda ok dtucker@
- from Pedro Martelletto; ok dtucker & me
+ OpenBSD-Commit-ID: bb57b285e67bea536ef81b1055467be2fc380e74
+
+commit aa61fc82c63d309a90c22ca74fb1da6c6f4372fd
+Author: Tobias Heider <me@tobhe.de>
+Date: Mon May 9 02:00:01 2022 +0200
+
+ Remove duplicate bcrypt_pbkdf.o from Makefile
- OpenBSD-Commit-ID: 5625cf6c68f082bc2cbbd348e69a3ed731d2f9b7
+ bcrypt_pbkdf.o is duplicated in the openbsd-compat Makefile's object
+ file list.
-commit 1cd1b2eac39661b849d5a4b4b56363e22bb5f61e
+commit deb506d00da8d11fb04c1e7b9b1e1cc379c1705c
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jan 14 03:31:52 2022 +0000
+Date: Sun May 8 22:32:36 2022 +0000
- upstream: use status error message to communicate ~user expansion
+ upstream: When performing operations that glob(3) a remote path, ensure
- failures; provides better experience for scp in sftp mode, where ~user paths
- are more likely to be used; spotted jsg, feedback jsg & deraadt ok jsg &
- markus
+ that the implicit working directory used to construct that path escapes
+ glob(3) characters.
- (forgot to include this file in previous commit)
+ This prevents glob characters from being processed in places they
+ shouldn't, e.g. "cd /tmp/a*/", "get *.txt" should have the get operation
+ treat the path "/tmp/a*" literally and not attempt to expand it.
- OpenBSD-Commit-ID: d37cc4c8c861ce48cd6ea9899e96aaac3476847b
+ Reported by Lusia Kundel; ok markus@
+
+ OpenBSD-Commit-ID: 4f647f58482cbad3d58b1eab7f6a1691433deeef
-commit a1d42a6ce0398da3833bedf374ef2571af7fea50
-Author: Damien Miller <djm@mindrot.org>
-Date: Fri Jan 14 13:49:32 2022 +1100
+commit f38cf74f20b5da113cfa823afd5bfb5c6ba65f3d
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri May 6 14:50:18 2022 +1000
- fix edge case in poll(2) wrapper
-
- Correct handling of select(2) exceptfds. These should only be consulted
- for POLLPRI flagged pfds and not unconditionally converted to POLLERR.
-
- with and ok dtucker@
+ Also retest OpenBSD upstream on .yml changes.
-commit 976b9588b4b5babcaceec4767a241c11a67a5ccb
+commit f87a132800ba3710ab130d703448a31ef1128d77
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Jan 14 13:46:35 2022 +1100
+Date: Fri May 6 14:46:09 2022 +1000
- Wrap OpenSSL includes in unit tests in ifdef.
-
- Fixes unit test on systems that do not have OpenSSL headers installed.
+ Note that, for now, we need variadic macros.
-commit c171879374b2e8b07157503f5639ed0bce59ce89
+commit 217b518e0f7c52c4b909e935141a55344c61e644
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Jan 13 15:53:33 2022 +1100
+Date: Fri May 6 14:39:34 2022 +1000
- Remove sort wrapper.
+ Add ubsan minimal testcase on OpenBSD.
- agent-restrict now takes care of this itself.
+ As suggested by djm@.
-commit 9cc2654403f1a686bb26c07a6ac790edf334cef5
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Thu Jan 13 04:53:16 2022 +0000
+commit 457dce2cfef6a48f5442591cd8b21c7e8cba13f8
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu May 5 01:04:14 2022 +0000
- upstream: Set LC_ALL in both local and remote shells so that sorted
+ upstream: sshkey_unshield_private() contains a exact duplicate of
- output matches regardless of what the user's shell sets it to. ok djm@
+ the code in private2_check_padding(). Pull private2_check_padding() up so the
+ code can be reused. From Martin Vahlensieck, ok deraadt@
- OpenBSD-Regress-ID: 4e97dd69a68b05872033175a4c2315345d01837f
+ OpenBSD-Commit-ID: 876884c3f0e62e8fd8d1594bab06900f971c9c85
-commit 7a75f748cb2dd2f771bf70ea72698aa027996ab1
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Thu Jan 13 04:22:10 2022 +0000
+commit 0e44db4d9cb313e68a59a44d27884af66c02356e
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu May 5 00:56:58 2022 +0000
- upstream: Avoid %'s in commands (not used in OpenBSD, but used in
+ upstream: channel_new no longer frees remote_name. So update the
- -portable's Valgrind test) being interpretted as printf format strings.
+ comment accordingly. As remote_name is not modified, it can be const as
+ well. From Martin Vahlensieck
- OpenBSD-Regress-ID: dc8655db27ac4acd2c386c4681bf42a10d80b043
-
-commit 6c435bd4994d71442192001483a1cdb846e5ffcd
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Jan 12 16:58:13 2022 +1100
-
- Stop on first test failure to minimize logs.
+ OpenBSD-Commit-ID: e4e10dc8dc9f40c166ea5a8e991942bedc75a76a
-commit 4bc2ba6095620a4484b708ece12842afd8c7685b
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Wed Jan 12 07:18:37 2022 +0000
+commit 37b62fd5caf19c85a48241535277cefff65adace
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu May 5 00:55:11 2022 +0000
- upstream: Use egrep when searching for an anchored string.
+ upstream: mux.c: mark argument as const; from Martin Vahlensieck
- OpenBSD-Regress-ID: dd114a2ac27ac4b06f9e4a586d3f6320c54aeeb4
+ OpenBSD-Commit-ID: 69a1a93a55986c7c2ad9f733c093b46a47184341
-commit 6bf2efa2679da1e8e60731f41677b2081dedae2c
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Jan 12 18:25:06 2022 +1100
+commit f4e67c0ad259b4cf10177277a5827fa5545bac53
+Author: markus@openbsd.org <markus@openbsd.org>
+Date: Wed May 4 07:31:22 2022 +0000
- Add "rev" command replacement if needed.
+ upstream: make sure stdout is non-blocking; ok djm@
+
+ OpenBSD-Commit-ID: 64940fffbd1b882eda2d7c8c7a43c79368309c0d
-commit 72bcd7993dadaf967bb3d8564ee31cbf38132b5d
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Wed Jan 12 03:30:32 2022 +0000
+commit e5c036d2092c00bef395e9161dc5ce42d4be9565
+Author: florian@openbsd.org <florian@openbsd.org>
+Date: Tue May 3 07:42:27 2022 +0000
- upstream: Don't log NULL hostname in restricted agent code,
+ upstream: Add FIDO AUTHENTICATOR section and explain a bit how FIDO
- printf("%s", NULL) is not safe on all platforms. with & ok djm
+ works. The wording came mostly from the 8.2 OpenSSH release notes, addapted
+ to fit the man page. Then move the -O bits into the new section as is already
+ done for CERTIFICATES and MODULI GENERATION. Finally we can explain the
+ trade-offs of resident keys. While here, consistently refer to the FIDO
+ thingies as "FIDO authenticators", not "FIDO tokens".
- OpenBSD-Commit-ID: faf10cdae4adde00cdd668cd1f6e05d0a0e32a02
+ input & OK jmc, naddy
+
+ OpenBSD-Commit-ID: dd98748d7644df048f78dcf793b3b63db9ab1d25
-commit acabefe3f8fb58c867c99fed9bbf84dfa1771727
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Jan 11 22:33:16 2022 +0000
+commit 575771bf79bef7127be6aaccddc46031ea15529e
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Mon May 2 05:40:37 2022 +0000
- upstream: remove hardcoded domain and use window.location.host, so this
+ upstream: remove an obsolete rsa1 format example from an example;
- can be run anywhere
+ from megan batty
+ ok djm
- OpenBSD-Regress-ID: 2ac2ade3b6227d9c547351d3ccdfe671e62b7f92
+ OpenBSD-Commit-ID: db2c89879c29bf083df996bd830abfb1e70d62bf
-commit 96da0946e44f34adc0397eb7caa6ec35a3e79891
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Tue Jan 11 02:56:19 2022 +0000
+commit 0bc6b4c8f04e292577bdb44d5dc6b630d3448087
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sun May 1 23:20:30 2022 +0000
- upstream: "void" functions should not return anything. From Tim Rice
+ upstream: fix some integer overflows in sieve_large() that show up when
- via -portable.
+ trying to generate modp groups > 16k bits. Reported via GHPR#306 by Bertram
+ Felgenhauer, but fixed in a different way. feedback/ok tb@
- OpenBSD-Commit-ID: ce6616304f4c9881b46413e616b226c306830e2a
+ OpenBSD-Commit-ID: 81cbc6dd3a21c57bd6fadea10e44afe37bca558e
-commit a882a09722c9f086c9edb65d0c4022fd965ec1ed
+commit a45615cb172bc827e21ec76750de39dfb30ecc05
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Jan 11 01:26:47 2022 +0000
+Date: Fri Apr 29 04:55:07 2022 +0000
- upstream: suppress "Connection to xxx closed" messages at LogLevel >=
+ upstream: be stricter in which characters will be accepted in
- error bz3378; ok dtucker@
+ specifying a mask length; allow only 0-9. From khaleesicodes via GHPR#278; ok
+ dtucker@
- OpenBSD-Commit-ID: d5bf457d5d2eb927b81d0663f45248a31028265c
+ OpenBSD-Commit-ID: e267746c047ea86665cdeccef795a8a56082eeb2
-commit 61a1a6af22e17fc94999a5d1294f27346e6c4668
-Author: Damien Miller <djm@mindrot.org>
-Date: Wed Jan 12 08:57:49 2022 +1100
-
- OS X poll(2) is broken; use compat replacement
-
- Darwin's poll(2) implementation is broken. For character-special
- devices like /dev/null, it returns POLLNVAL when polled with
- POLLIN.
-
- Apparently this is Apple bug 3710161, which is AFAIK not public,
- but a websearch will find other OSS projects rediscovering it
- periodically since it was first identified in 2005 (!!)
-
-commit 613a6545fc5a9542753b503cbe5906538a640b60
+commit 4835544d2dd31de6ffc7dba59f92093aea98155b
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Tue Jan 11 20:56:01 2022 +1100
+Date: Sat Apr 30 10:56:41 2022 +1000
- libhardended_malloc.so moved into out dir.
+ Add Mac OS X 12 test target.
-commit 61761340be5e11046556623f8f5412b236cefa95
-Author: Tim Rice <tim@multitalents.net>
-Date: Mon Jan 10 11:07:04 2022 -0800
+commit 97a6a8b8c1f2da09712d0e72d0ef800e4edd34cd
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Apr 29 18:27:34 2022 +1000
- Make USL compilers happy
- UX:acomp: ERROR: "sftp-server.c", line 567: void function cannot return value
+ Only run tests when source files change.
+
+ Also run tests on changes to V_9_0 branch.
-commit 3ef403f351e80a59b6f7e9d43cb82c181855483c
+commit 6d0392b9ff4b50a56ac5685d1b9392e2cd432ca3
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Mon Jan 10 21:07:38 2022 +1100
+Date: Fri Apr 29 18:22:34 2022 +1000
- Add wrapper for "sort" to set LC_ALL=C.
-
- Found by djm, this should make sorts stable and reduce test flakiness.
+ Remove now-empty int32_minmax.inc.
-commit bd69e29f5716090181dbe0b8272eb7eab1a383bb
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Sat Jan 8 07:55:26 2022 +0000
+commit af59463553b5ad52d3b42c4455ee3c5600158bb7
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Apr 29 03:24:30 2022 +0000
- upstream: Remove errant "set -x" left over from debugging.
+ upstream: mention that the helpers are used by ssh(1), ssh-agent(1)
- OpenBSD-Regress-ID: cd989268e034264cec5df97be7581549032c87dc
+ and ssh-keygen(1). Previously only ssh(1) was mentioned. From Pedro
+ Martelletto
+
+ OpenBSD-Commit-ID: 30f880f989d4b329589c1c404315685960a5f153
-commit 1a7c88e26fd673813dc5f61c4ac278564845e004
+commit 3e26b3a6eebcee27be177207cc0846fb844b7a56
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Sat Jan 8 07:01:13 2022 +0000
+Date: Fri Apr 29 03:16:48 2022 +0000
- upstream: Enable all supported hostkey algorithms (but no others).
+ upstream: Don't leak SK device. Patch from Pedro Martelletto via
- Allows hostbased test to pass when built without OpenSSL.
+ github PR#316. ok djm@
- OpenBSD-Regress-ID: 5ddd677a68b672517e1e78460dc6ca2ccc0a9562
+ OpenBSD-Commit-ID: 17d11327545022e727d95fd08b213171c5a4585d
-commit 12b457c2a42ff271e7967d9bedd068cebb048db9
+commit 247082b5013f0d4fcae8f97453f2a2f01bcda811
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Jan 8 07:37:32 2022 +0000
+Date: Fri Apr 29 03:13:32 2022 +0000
- upstream: use status error message to communicate ~user expansion
+ upstream: fix memleak on session-bind path; from Pedro Martelletto, ok
- failures; provides better experience for scp in sftp mode, where ~user paths
- are more likely to be used; spotted jsg, feedback jsg & deraadt ok jsg &
- markus
+ dtucker@
- OpenBSD-Commit-ID: fc610ce00ca0cdc2ecdabbd49ce7cb82033f905f
+ OpenBSD-Commit-ID: e85899a26ba402b4c0717b531317e8fc258f0a7e
-commit 63670d4e9030bcee490d5a9cce561373ac5b3b23
+commit e05522008092ceb86a87bdd4ad7878424315db89
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Jan 8 07:36:11 2022 +0000
+Date: Thu Apr 28 02:53:31 2022 +0000
- upstream: fix some corner-case bugs in scp sftp-mode handling of
-
- ~-prefixed paths; spotted by jsg; feedback jsg & deraadt, ok jsg & markus
+ upstream: avoid printing hash algorithm twice; from lucas AT sexy.is
- OpenBSD-Commit-ID: d1697dbaaa9f0f5649d69be897eab25c7d37c222
+ OpenBSD-Commit-ID: 9d24671e10a84141b7c504396cabad600e47a941
-commit e14940bbec57fc7d3ce0644dbefa35f5a8ec97d0
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Jan 8 07:34:57 2022 +0000
+commit 0979e29356915261d69a9517a1e0aaade7c9fc75
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Wed Apr 27 11:08:55 2022 +0000
- upstream: more idiomatic error messages; spotted by jsg & deraadt
-
- ok jsg & markus
+ upstream: Add authfd path to debug output. ok markus@
- OpenBSD-Commit-ID: 43618c692f3951747b4151c477c7df22afe2bcc8
+ OpenBSD-Commit-ID: f735a17d1a6f2bee63bfc609d76ef8db8c090890
-commit 9acddcd5918c623f7ebf454520ffe946a8f15e90
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Jan 8 07:33:54 2022 +0000
+commit 67b7c784769c74fd4d6b147d91e17e1ac1a8a96d
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Tue Apr 26 07:41:44 2022 +0000
- upstream: add a variant of send_status() that allows overriding the
+ upstream: Check sshauthopt_new() for NULL. bz#3425, from
- default, generic error message. feedback/ok markus & jsg
+ tessgauthier at microsoft.com. ok djm@
- OpenBSD-Commit-ID: 81f251e975d759994131b717ee7c0b439659c40f
+ OpenBSD-Commit-ID: af0315bc3e44aa406daa7e0ae7c2d719a974483f
-commit 961411337719d4cd78f1ab33e4ac549f3fa22f50
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Jan 8 07:32:45 2022 +0000
+commit d571314d14b919fbd7c84a61f9bf2065fc0a6841
+Author: millert@openbsd.org <millert@openbsd.org>
+Date: Wed Apr 20 16:00:25 2022 +0000
- upstream: refactor tilde_expand_filename() and make it handle ~user
+ upstream: Remove unnecessary includes: openssl/hmac.h and
- paths with no trailing slash; feedback/ok markus and jsg
+ openssl/evp.h. From Martin Vahlensieck.
- OpenBSD-Commit-ID: a2ab365598a902f0f14ba6a4f8fb2d07a9b5d51d
+ OpenBSD-Commit-ID: a6debb5fb0c8a44e43e8d5ca7cc70ad2f3ea31c3
-commit dc38236ab6827dec575064cac65c8e7035768773
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Thu Jan 6 22:14:25 2022 +0000
+commit da8dddf8cc1f2516ff894b8183e83a7c5ba3ef80
+Author: millert@openbsd.org <millert@openbsd.org>
+Date: Wed Apr 20 15:59:18 2022 +0000
- upstream: Don't explicitly set HostbasedAuthentication in
+ upstream: Add missing includes of stdlib.h and stdint.h. We need
- sshd_config. It defaults to "no", and not explicitly setting it allows us to
- enable it for the (optional) hostbased test.
+ stdlib.h for malloc(3) and stdint.h for SIZE_MAX. Unlike the other xmss
+ files, ssh-xmss.c does not include xmss_commons.h so ssh-xmss.c must include
+ those headers itself. From Martin Vahlensieck
- OpenBSD-Regress-ID: aa8e3548eb5793721641d26e56c29f363b767c0c
+ OpenBSD-Commit-ID: 70e28a9818cee3da1be2ef6503d4b396dd421e6b
-commit e12d912ddf1c873cb72e5de9a197afbe0b6622d2
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Thu Jan 6 21:46:56 2022 +0000
+commit fe9d87a6800a7a33be08f4d5ab662a758055ced2
+Author: millert@openbsd.org <millert@openbsd.org>
+Date: Wed Apr 20 15:56:49 2022 +0000
- upstream: Add test for hostbased auth. It requires some external
+ upstream: Avoid an unnecessary xstrdup in rm_env() when matching
- setup (see comments at the top) and thus is disabled unless
- TEST_SSH_HOSTBASED_AUTH and SUDO are set.
+ patterns. Since match_pattern() doesn't modify its arguments (they are
+ const), there is no need to make an extra copy of the strings in
+ options->send_env. From Martin Vahlensieck
- OpenBSD-Regress-ID: 3ec8ba3750c5b595fc63e7845d13483065a4827a
+ OpenBSD-Commit-ID: 2c9db31e3f4d3403b49642c64ee048b2a0a39351
-commit a48533a8da6a0f4f05ecd055dc8048047e53569e
-Author: Damien Miller <djm@mindrot.org>
-Date: Fri Jan 7 09:24:26 2022 +1100
+commit 7bf2eb958fbb551e7d61e75c176bb3200383285d
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Tue Apr 26 23:30:59 2022 +1000
- depend
+ Add debian-riscv64 test target.
-commit d9dbb5d9a0326e252d3c7bc13beb9c2434f59409
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Jan 6 22:06:51 2022 +0000
+commit 3913c935523902482974c4c503bcff20bd850a6a
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Apr 25 17:20:06 2022 +1000
- upstream: allow hostbased auth to select RSA keys when only
-
- RSA/SHA2 are configured (this is the default case); ok markus@
-
- OpenBSD-Commit-ID: 411c18c7bde40c60cc6dfb7017968577b4d4a827
+ Update OpenSSL and LibreSSL versions in tests.
-commit fdb1d58d0d3888b042e5a500f6ce524486aaf782
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Jan 6 22:05:42 2022 +0000
+commit dcd8dca29bcdb193ff6be35b96fc55e6e30d37d9
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat Apr 23 20:40:28 2022 +1000
- upstream: add a helper function to match a key type to a list of
-
- signature algorithms. RSA keys can make signatures with multiple algorithms,
- so some special handling is required. ok markus@
+ Include stdlib.h for free() prototype.
- OpenBSD-Commit-ID: 03b41b2bda06fa4cd9c84cef6095033b9e49b6ff
+ ... which is used inside the CUSTOM_SYS_AUTH_GET_LASTLOGIN_MSG block.
-commit 11e8c4309a5086a45fbbbc87d0af5323c6152914
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Jan 6 22:04:20 2022 +0000
+commit 4cc05de568e1c3edd7834ff3bd9d8214eb34861b
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat Apr 23 20:17:26 2022 +1000
- upstream: log some details on hostkeys that ssh loads for
-
- hostbased authn ok markus@
+ Cache timezone data in capsicum sandbox.
- OpenBSD-Commit-ID: da17061fa1f0e58cb31b88478a40643e18233e38
+ From emaste at freebsd.org, originally part of FreeBSD commit r339216
+ / fc3c19a9 with autoconf bits added by me.
-commit c6706f661739514a34125aa3136532a958929510
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Jan 6 22:03:59 2022 +0000
+commit c31404426d212e2964ff9e5e58e1d0fce3d83f27
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Thu Apr 21 01:36:46 2022 +0000
- upstream: log signature algorithm during verification by monitor;
+ upstream: It looks like we can't completely avoid
- ok markus
+ waiting for processes to exit so retrieve the pid via controlmaster and
+ use that.
- OpenBSD-Commit-ID: 02b92bb42c4d4bf05a051702a56eb915151d9ecc
+ OpenBSD-Regress-ID: 8246f00f22b14e49d2ff1744c94897ead33d457b
-commit 8832402bd500d1661ccc80a476fd563335ef6cdc
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Jan 6 22:02:52 2022 +0000
+commit d19b21afab5c8e2f3df6bd8aee9766bdad3d8c58
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Wed Apr 20 13:25:55 2022 +0000
- upstream: piece of UpdateHostkeys client strictification: when
+ upstream: Use ssh -f and ControlPersist ..
- updating known_hosts with new keys, ignore NULL keys (forgot to include in
- prior commit)
+ to start up test forwards and ssh -O stop to shut them down intead of
+ sleep loops. This speeds up the test by an order of magnitude.
- OpenBSD-Commit-ID: 49d2eda6379490e1ceec40c3b670b973f63dea08
+ OpenBSD-Regress-ID: eb3db5f805100919b092a3b2579c611fba3e83e7
-commit c2d9ced1da0276961d86690b3bd7ebdaca7fdbf7
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Jan 6 22:01:14 2022 +0000
+commit 5f76286a126721fa005de6edf3d1c7a265555f19
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Wed Apr 20 05:24:13 2022 +0000
- upstream: include rejected signature algorithm in error message
+ upstream: Simplify forward-control test.
- and not the (useless) key type; ok markus
+ Since we no longer need to support SSH1 we don't need to run shell
+ commands on the other end of the connection and can use ssh -N instead.
+ This also makes the test less racy.
- OpenBSD-Commit-ID: 4180b5ec7ab347b43f84e00b1972515296dab023
+ OpenBSD-Regress-ID: 32e94ce272820cc398f30b848b2b0f080d10302c
-commit 7aa7b096cf2bafe2777085abdeed5ce00581f641
+commit 687bbf23572d8bdf25cbbcdf8ac583514e1ba710
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Jan 6 22:00:18 2022 +0000
+Date: Thu Mar 31 03:07:33 2022 +0000
- upstream: make ssh-keysign use the requested signature algorithm
+ upstream: regression test for sftp cp command
- and not the default for the keytype. Part of unbreaking hostbased auth for
- RSA/SHA2 keys. ok markus@
+ OpenBSD-Regress-ID: c96bea9edde3a384b254785e7f9b2b24a81cdf82
+
+commit f1233f19a6a9fe58f52946f50df4772f5b136761
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Wed Apr 20 01:13:47 2022 +0000
+
+ upstream: Import regenerated moduli
- OpenBSD-Commit-ID: b5639a14462948970da3a8020dc06f9a80ecccdc
+ OpenBSD-Commit-ID: f9a0726d957cf10692a231996a1f34e7f9cdfeb0
-commit 291721bc7c840d113a49518f3fca70e86248b8e8
+commit fec014785de198b9a325d1b94e324bb958c5fe7b
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Jan 6 21:57:28 2022 +0000
+Date: Wed Apr 20 04:19:11 2022 +0000
- upstream: stricter UpdateHostkey signature verification logic on
-
- the client- side. Require RSA/SHA2 signatures for RSA hostkeys except when
- RSA/SHA1 was explicitly negotiated during initial KEX; bz3375
+ upstream: Try to continue running local I/O for channels in state
- ok markus@
+ OPEN during SSH transport rekeying. The most visible benefit is that it
+ should make ~-escapes work in the client (e.g. to exit) if the connection
+ happened to have stalled during a rekey event. Based work by and ok dtucker@
- OpenBSD-Commit-ID: 46e75e8dfa2c813781805b842580dcfbd888cf29
+ OpenBSD-Commit-ID: a66e8f254e92edd4ce09c9f750883ec8f1ea5f45
-commit 0fa33683223c76289470a954404047bc762be84c
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Jan 6 21:55:23 2022 +0000
+commit e68154b0d4f0f5085a050ea896955da1b1be6e30
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Wed Apr 20 01:13:47 2022 +0000
- upstream: Fix signature algorithm selection logic for
-
- UpdateHostkeys on the server side. The previous code tried to prefer RSA/SHA2
- for hostkey proofs of RSA keys, but missed some cases. This will use RSA/SHA2
- signatures for RSA keys if the client proposed these algorithms in initial
- KEX. bz3375
-
- Mostly by Dmitry Belyavskiy with some tweaks by me.
-
- ok markus@
+ upstream: Import regenerated moduli
- OpenBSD-Commit-ID: c17ba0c3236340d2c6a248158ebed042ac6a8029
+ OpenBSD-Commit-ID: f9a0726d957cf10692a231996a1f34e7f9cdfeb0
-commit 17877bc81db3846e6e7d4cfb124d966bb9c9296b
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Jan 6 21:48:38 2022 +0000
+commit 69928b106d8f0fa15b88cf3850d992ed81c44ae0
+Author: tj@openbsd.org <tj@openbsd.org>
+Date: Sat Apr 16 00:22:31 2022 +0000
- upstream: convert ssh, sshd mainloops from select() to poll();
+ upstream: list the correct version number
- feedback & ok deraadt@ and markus@ has been in snaps for a few months
+ for when usage of the sftp protocol became default and fix a typo
+ from ed maste
- OpenBSD-Commit-ID: a77e16a667d5b194dcdb3b76308b8bba7fa7239c
+ OpenBSD-Commit-ID: 24e1795ed2283fdeacf16413c2f07503bcdebb31
-commit 5c79952dfe1aa36105c93b3f383ce9be04dee384
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Jan 6 21:46:23 2022 +0000
+commit 21042a05c0b304c16f655efeec97438249d2e2cc
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Tue Apr 12 05:09:49 2022 +0000
- upstream: prepare for conversion of ssh, sshd mainloop from
+ upstream: Correct path for system known hosts file in description
- select() to poll() by moving FD_SET construction out of channel handlers into
- separate functions. ok markus
+ of IgnoreUserKnownHosts. Patch from Martin Vahlensieck via tech@
- OpenBSD-Commit-ID: 937fbf2a4de12b19fb9d5168424e206124807027
+ OpenBSD-Commit-ID: 9b7784f054fa5aa4d63cb36bd563889477127215
-commit 24c5187edfef4651a625b7d5d692c8c7e794f71f
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Jan 5 21:54:37 2022 +0000
+commit 53f4aff60a7c1a08a23917bd47496f8901c471f5
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat Apr 16 14:33:20 2022 +1000
- upstream: add a comment so I don't make this mistake again
+ Resync moduli.5 with upstream.
- OpenBSD-Commit-ID: 69c7f2362f9de913bb29b6318580c5a1b52c921e
+ 1.18: remove duplicate publication year; carsten dot kunze at arcor dot de
+ 1.19: ssh-keygen's -G/-T have been replaced with -M generate/screen.
-commit 7369900441929058263a17f56aa67e05ff7ec628
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Jan 5 21:50:00 2022 +0000
+commit d2b888762b9844eb0d8eb59909cdf5af5159f810
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat Apr 16 14:31:13 2022 +1000
- upstream: fix cut-and-pasto in error message
+ Retire fbsd6 test VM.
- OpenBSD-Commit-ID: 4cc5c619e4b456cd2e9bb760d17e3a9c84659198
+ It's long since out of support, relatively slow (it's i686) and the
+ compiler has trouble with PIE.
-commit 294c11b1c7d56d3fb61e329603a782315ed70c62
+commit cd1f70009860a154b51230d367c55ea5f9a4504e
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Jan 5 08:25:05 2022 +0000
+Date: Mon Apr 11 22:52:08 2022 +0000
- upstream: select all RSA hostkey algorithms for UpdateHostkeys tests,
+ upstream: clear io_want/io_ready flags at start of poll() cycle;
- not just RSA-SHA1
+ avoids plausible spin during rekeying if channel io_want flags are reused
+ across cycles. ok markus@ deraadt@
- OpenBSD-Regress-ID: b40e62b65863f2702a0c10aca583b2fe76772bd8
+ OpenBSD-Commit-ID: 91034f855b7c73cd2591657c49ac30f10322b967
-commit 2ea1108c30e3edb6f872dfc1e6da10b041ddf2c0
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Jan 5 04:56:15 2022 +0000
+commit aa1920302778273f7f94c2091319aba199068ca0
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Apr 8 05:43:39 2022 +0000
- upstream: regress test both sshsig message hash algorithms, possible
+ upstream: Note that curve25519-sha256 was later published in
- now because the algorithm is controllable via the CLI
+ RFC8731. ok djm@
- OpenBSD-Regress-ID: 0196fa87acc3544b2b4fd98de844a571cb09a39f
+ OpenBSD-Commit-ID: 2ac2b5d642d4cf5918eaec8653cad9a4460b2743
-commit 2327c306b5d4a2b7e71178e5a4d139af9902c2b0
+commit 4673fa8f2be983f2f88d5afd754adb1a2a39ec9e
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Jan 5 04:50:11 2022 +0000
+Date: Fri Apr 8 04:40:40 2022 +0000
- upstream: allow selection of hash at sshsig signing time; code
+ upstream: two defensive changes from Tobias Stoeckmann via GHPR287
- already supported either sha512 (default) or sha256, but plumbing wasn't
- there mostly by Linus Nordberg
+ enforce stricter invarient for sshbuf_set_parent() - never allow
+ a buffer to have a previously-set parent changed.
- OpenBSD-Commit-ID: 1b536404b9da74a84b3a1c8d0b05fd564cdc96cd
+ In sshbuf_reset(), if the reallocation fails, then zero the entire
+ buffer and not the (potentially smaller) default initial alloc size.
+
+ OpenBSD-Commit-ID: 14583203aa5d50ad38d2e209ae10abaf8955e6a9
-commit 56e941d0a00d6d8bae88317717d5e1b7395c9529
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Jan 5 04:27:54 2022 +0000
+commit 26eef015e2d2254375e13afaaf753b78932b1bf5
+Author: Damien Miller <djm@mindrot.org>
+Date: Mon Apr 11 16:07:09 2022 +1000
- upstream: add missing -O option to usage() for ssh-keygen -Y sign;
+ Revert "update build-aux files to match autoconf-2.71"
- from Linus Nordberg
+ This reverts commit 0a8ca39fac6ad19096b6c263436f8b2dd51606f2.
- OpenBSD-Commit-ID: 4e78feb4aa830727ab76bb2e3d940440ae1d7af0
+ It turns out that the checked-in copies of these files are actually newer
+ than autoconf-2.71's copies, so this was effectively a downgrade.
+ Spotted by Bo Anderson via github
-commit 141a14ec9b0924709c98df2dd8013bde5d8d12c7
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Jan 5 04:27:01 2022 +0000
+commit 0a8ca39fac6ad19096b6c263436f8b2dd51606f2
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Apr 8 14:48:58 2022 +1000
- upstream: move sig_process_opts() to before sig_sign(); no
-
- functional code change
+ update build-aux files to match autoconf-2.71
- OpenBSD-Commit-ID: da02d61f5464f72b4e8b299f83e93c3b657932f9
+ i.e. config.guess, config.sub and install-sh
-commit 37a14249ec993599a9051731e4fb0ac5e976aec1
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Jan 5 04:10:39 2022 +0000
+commit 94eb6858efecc1b4f02d8a6bd35e149f55c814c8
+Author: Damien Miller <djm@mindrot.org>
+Date: Wed Apr 6 10:47:48 2022 +1000
- upstream: regression test for find-principals NULL deref; from Fabian
-
- Stelzer
-
- OpenBSD-Regress-ID: f845a8632a5a7d5ae26978004c93e796270fd3e5
+ update version numbers for release
-commit eb1f042142fdaba93f6c9560cf6c91ae25f6884a
+commit 8e4a8eadf4fe74e65e6492f34250f8cf7d67e8da
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Jan 5 04:02:42 2022 +0000
+Date: Mon Apr 4 22:45:25 2022 +0000
- upstream: NULL deref when using find-principals when matching an
-
- allowed_signers line that contains a namespace restriction, but no
- restriction specified on the command-line; report and fix from Fabian Stelzer
+ upstream: openssh-9.0
- OpenBSD-Commit-ID: 4a201b86afb668c908d1a559c6af456a61f4b145
+ OpenBSD-Commit-ID: 0dfb461188f4513ec024c1534da8c1ce14c20b64
-commit 8f3b18030579f395eca2181da31a5f945af12a59
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Tue Jan 4 08:38:53 2022 +0000
+commit a9f23ea2e3227f406880c2634d066f6f50fa5eaa
+Author: naddy@openbsd.org <naddy@openbsd.org>
+Date: Thu Mar 31 17:58:44 2022 +0000
- upstream: Log command invocation while debugging.
+ upstream: ssh: document sntrup761x25519-sha512@openssh.com as
- This will aid in manually reproducing failing commands.
+ default KEX
- OpenBSD-Regress-ID: b4aba8d5ac5675ceebeeeefa3261ce344e67333a
+ OpenBSD-Commit-ID: 12545bfa10bcbf552d04d9d9520d0f4e98b0e171
-commit bbf285164df535f0d38c36237f007551bbdae27f
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sun Dec 26 10:31:15 2021 +1100
+commit 9ec2713d122af79d66ebb9c1d6d9ae8621a8945f
+Author: naddy@openbsd.org <naddy@openbsd.org>
+Date: Thu Mar 31 17:27:27 2022 +0000
- Always save config.h as build artifact.
+ upstream: man pages: add missing commas between subordinate and
- Should allow better comparison between failing and succeeding test
- platforms.
+ main clauses
+
+ jmc@ dislikes a comma before "then" in a conditional, so leave those
+ untouched.
+
+ ok jmc@
+
+ OpenBSD-Commit-ID: 9520801729bebcb3c9fe43ad7f9776ab4dd05ea3
-commit 03bd4ed0db699687c5cd83405d26f81d2dc28d22
+commit 3741df98ffaaff92b474ee70d8ef276b5882f85a
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Dec 25 16:42:51 2021 +1100
+Date: Mon Apr 4 23:52:11 2022 +1000
- Add OpenBSD 7.0 target. Retire 6.8.
+ Disable security key on fbsd6 test host.
-commit c45a752f0de611afd87755c2887c8a24816d08ee
-Author: jsg@openbsd.org <jsg@openbsd.org>
-Date: Sat Jan 1 05:55:06 2022 +0000
+commit 32c12236f27ae83bfe6d2983b67c9bc67a83a417
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Apr 4 15:16:51 2022 +1000
- upstream: spelling
+ Specify TEST_SHELL=bash on AIX.
- OpenBSD-Commit-ID: c63e43087a64d0727af13409c708938e05147b62
+ The system shells cause the agent-restrict test to fail due to some
+ quoting so explicitly specify bash until we can get configure to
+ autmatically work around that.
-commit c672f83a89a756564db0d3af9934ba0e1cf8fa3e
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Jan 4 07:20:33 2022 +0000
+commit 90452c8b69d065b7c7c285ff78b81418a75bcd76
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Apr 1 23:38:44 2022 +1100
- upstream: unbreak test: was picking up system ssh-add instead of the
-
- one supposedly being tested. Spotted by dtucker and using his VM zoo (which
- includes some systems old enough to lack ed25519 key support)
+ Only return events from ppoll that were requested.
- OpenBSD-Regress-ID: 7976eb3df11cc2ca3af91030a6a8c0cef1590bb5
+ If the underlying system's select() returns bits that were not in the
+ request set, our ppoll() implementation can return revents for events
+ not requested, which can apparently cause a hang. Only return revents
+ for activity in the requested event set. bz#3416, analysis and fix by
+ yaroslav.kuzmin at vmssoftware com, ok djm@
-commit a23698c3082ffe661abed14b020eac9b0c25eb9f
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Jan 1 04:18:06 2022 +0000
+commit 6c49eb5fabc56f4865164ed818aa5112d09c31a8
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Apr 1 23:21:40 2022 +1100
- upstream: fix memleak in process_extension(); oss-fuzz issue #42719
-
- OpenBSD-Commit-ID: d8d49f840162fb7b8949e3a5adb8107444b6de1e
+ Only run regression tests on slow VMs.
-commit cb885178f36b83d0f14cfe9f345d2068103feed0
-Author: jsg@openbsd.org <jsg@openbsd.org>
-Date: Sat Jan 1 01:55:30 2022 +0000
+commit f67e47903977b42cb6abcd5565a61bd7293e4dc3
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Apr 1 23:21:06 2022 +1100
- upstream: spelling ok dtucker@
-
- OpenBSD-Commit-ID: bfc7ba74c22c928de2e257328b3f1274a3dfdf19
+ Increase test timeout to allow slow VMs to finish
-commit 6b977f8080a32c5b3cbb9edb634b9d5789fb79be
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Dec 26 23:34:41 2021 +0000
+commit 02488c1b54065ddc4f25835dbd2618b2a2fe21f5
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Apr 1 16:27:38 2022 +1100
- upstream: split method list search functionality from
-
- authmethod_lookup() into a separate authmethod_byname(), for cases where we
- don't need to check whether a method is enabled, etc.
-
- use this to fix the "none" authentication method regression reported
- by Nam Nguyen via bugs@
-
- ok deraadt@
-
- OpenBSD-Commit-ID: 8cd188dc3a83aa8abe5b7693e762975cd8ea8a17
-
-commit 0074aa2c8d605ee7587279a22cdad4270b4ddd07
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Wed Dec 22 06:56:41 2021 +0000
-
- upstream: sort -H and -h in SYNOPSIS/usage(); tweak the -H text;
-
- ok djm
-
- OpenBSD-Commit-ID: 90721643e41e9e09deb5b776aaa0443456ab0965
+ Use bash or ksh if available for SH in Makefile.
-commit 1c9853a68b2319f2e5f929179735e8fbb9988a67
+commit 34c7018c316af4773e432066de28d0ef9d0888cd
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Dec 22 19:33:10 2021 +1100
+Date: Fri Apr 1 14:56:54 2022 +1100
- Use SHA.*_HMAC_BLOCK_SIZE if needed.
+ Set Makefile SHELL as determined by configure.
- If the platform has a native SHA2, does not define SHA.*_BLOCK_LENGTH
- but does define SHA.*_HMAC_BLOCK_SIZE (eg Solaris) then use the latter.
- Should fix --without-openssl build on Solaris.
+ This should improve compatibility for users with non-POSIX shells. If
+ using Makefile.in directly (eg make -f Makefile.in distprep) then SHELL
+ will need to be specified on the command line (along with MANFMT in that
+ particular case). ok djm@
-commit 715c892f0a5295b391ae92c26ef4d6a86ea96e8e
-Author: Damien Miller <djm@mindrot.org>
-Date: Wed Dec 22 09:02:50 2021 +1100
+commit 5b054d76402faab38c48377efd112426469553a0
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Apr 1 13:16:47 2022 +1100
- remove sys/param.h in -portable, after upstream
+ Skip slow tests on (very) slow test targets.
-commit 7a7c69d8b4022b1e5c0afb169c416af8ce70f3e8
+commit b275818065b31a865142c48c2acf6a7c1655c542
Author: Damien Miller <djm@mindrot.org>
-Date: Mon Dec 20 13:05:20 2021 +1100
+Date: Thu Mar 31 14:11:36 2022 +1100
- add agent-restrict.sh file, missed in last commit
+ depend
-commit f539136ca51a4976644db5d0be8158cc1914c72a
+commit 3fa539c3ffaabd6211995512d33e29150f88c5c5
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Dec 19 22:20:12 2021 +0000
+Date: Thu Mar 31 03:07:03 2022 +0000
- upstream: regression test for destination restrictions in ssh-agent
+ upstream: add a sftp client "cp" command that supports server-side
- OpenBSD-Regress-ID: 3c799d91e736b1753b4a42d80c42fc40de5ad33d
-
-commit 6e4980eb8ef94c04874a79dd380c3f568e8416d6
-Author: anton@openbsd.org <anton@openbsd.org>
-Date: Sat Dec 18 06:53:59 2021 +0000
-
- upstream: Make use of ntests variable, pointed out by clang 13.
+ copying of files. Useful for this task and for testing the copy-data
+ extension. Patch from Mike Frysinger; ok dtucker@
- OpenBSD-Regress-ID: 4241a3d21bdfa1630ed429b6d4fee51038d1be72
+ OpenBSD-Commit-ID: 1bb1b950af0d49f0d5425b1f267e197aa1b57444
-commit 3eead8158393b697f663ec4301e3c7b6f24580b1
-Author: deraadt@openbsd.org <deraadt@openbsd.org>
-Date: Tue Dec 14 21:25:27 2021 +0000
+commit 7988bfc4b701c4b3fe9b36c8561a3d1c5d4c9a74
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Mar 31 03:05:49 2022 +0000
- upstream: sys/param.h cleanup, mostly using MINIMUM() and
+ upstream: add support for the "corp-data" protocol extension to
- <limits.h> ok dtucker
+ allow server-side copies to be performed without having to go via the client.
+ Patch by Mike Frysinger, ok dtucker@
- OpenBSD-Regress-ID: 172a4c45d3bcf92fa6cdf6c4b9db3f1b3abe4db0
+ OpenBSD-Commit-ID: 00aa510940fedd66dab1843b58682de4eb7156d5
-commit 266678e19eb0e86fdf865b431b6e172e7a95bf48
+commit 32dc1c29a4ac9c592ddfef0a4895eb36c1f567ba
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Dec 19 22:15:42 2021 +0000
+Date: Wed Mar 30 21:13:23 2022 +0000
- upstream: document host-bound publickey authentication
+ upstream: select post-quantum KEX
- OpenBSD-Commit-ID: ea6ed91779a81f06d961e30ecc49316b3d71961b
+ sntrup761x25519-sha512@openssh.com as the default; ok markus@
+
+ OpenBSD-Commit-ID: f02d99cbfce22dffec2e2ab1b60905fbddf48fb9
-commit 3d00024b3b156aa9bbd05d105f1deb9cb088f6f7
+commit d6556de1db0822c76ba2745cf5c097d9472adf7c
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Dec 19 22:15:21 2021 +0000
+Date: Wed Mar 30 21:10:25 2022 +0000
- upstream: document agent protocol extensions
+ upstream: fix poll() spin when a channel's output fd closes without
- OpenBSD-Commit-ID: 09e8bb391bbaf24c409b75a4af44e0cac65405a7
+ data in the channel buffer. Introduce more exact packing of channel fds into
+ the pollfd array. fixes bz3405 and bz3411; ok deraadt@ markus@
+
+ OpenBSD-Commit-ID: 06740737849c9047785622ad5d472cb6a3907d10
-commit c385abf76511451bcba78568167b1cd9e90587d5
+commit 8a74a96d25ca4d32fbf298f6c0ac5a148501777d
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Dec 19 22:14:47 2021 +0000
+Date: Wed Mar 30 04:33:09 2022 +0000
- upstream: PubkeyAuthentication=yes|no|unbound|host-bound
-
- Allow control over which pubkey methods are used. Added out of
- concern that some hardware devices may have difficulty signing
- the longer pubkey authentication challenges. This provides a
- way for them to disable the extension. It's also handy for
- testing.
+ upstream: ssh is almost out of getopt() characters; note the
- feedback / ok markus@
+ remaining remaining available ones in a comment
- OpenBSD-Commit-ID: ee52580db95c355cf6d563ba89974c210e603b1a
+ OpenBSD-Commit-ID: 48d38cef59d6bc8e84c6c066f6d601875d3253fd
-commit 34b1e9cc7654f41cd4c5b1cc290b999dcf6579bb
+commit 6d4fc51adb9d8a42f67b5474f02f877422379de6
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Dec 19 22:14:12 2021 +0000
+Date: Wed Mar 30 04:27:51 2022 +0000
- upstream: document destination-constrained keys
+ upstream: avoid NULL deref via ssh-keygen -Y find-principals.
- feedback / ok markus@
+ bz3409, reported by Mateusz Adamowski
- OpenBSD-Commit-ID: cd8c526c77268f6d91c06adbee66b014d22d672e
+ OpenBSD-Commit-ID: a3b2c02438052ee858e0ee18e5a288586b5df2c5
-commit a6d7677c4abcfba268053e5867f2acabe3aa371b
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Dec 19 22:13:55 2021 +0000
+commit e937514920335b92b543fd9be79cd6481d1eb0b6
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Mar 28 17:51:03 2022 +1100
- upstream: Use hostkey parsed from hostbound userauth request
-
- Require host-bound userauth requests for forwarded SSH connections.
+ Add AIX 5.1 test target.
+
+commit 4bbe815ba974b4fd89cc3fc3e3ef1be847a0befe
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat Mar 26 22:01:31 2022 +1100
+
+ Drop leading "v" from release version identifier.
- The hostkey parsed from the host-bound userauth request is now checked
- against the most recently bound session ID / hostkey on the agent socket
- and the signature refused if they do not match.
+ It's present in the git tags but not in the release tarball names.
+ Also drop extra "/" from URL path.
+
+commit f5cdd3b3c275dffaebfca91df782dca29975e9ac
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat Mar 26 16:28:04 2022 +1100
+
+ Use tarballs when testing LibreSSL releases.
- ok markus@
+ This means they'll still work when the combination of -portable and
+ openbsd github repos no longer match.
+
+commit 24dc37d198f35a7cf71bf4d5384363c7ef4209d4
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat Mar 26 15:02:45 2022 +1100
+
+ Remove now-unused passwd variable.
+
+commit 5b467ceef2c356f0a77f5e8ab4eb0fac367e4d24
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat Mar 26 13:15:44 2022 +1100
+
+ Missing semicolon.
+
+commit 2923d026e55998133c0f6e5186dca2a3c0fa5ff5
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat Mar 26 12:49:50 2022 +1100
+
+ Factor out platform-specific locked account check.
- OpenBSD-Commit-ID: d69877c9a3bd8d1189a5dbdeceefa432044dae02
+ Also fixes an incorrect free on platforms with both libiaf and shadow
+ passwords (probably only Unixware). Prompted by github PR#284,
+ originally from @c3h2_ctf and stoeckmann@.
-commit baaff0ff4357cc5a079621ba6e2d7e247b765061
+commit d23efe4b12886ffe416be10bc0a7da6ca8aa72d1
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat Mar 26 08:13:46 2022 +1100
+
+ Add OpenWRT mips and mipsel test targets.
+
+commit 16ea8b85838dd7a4dbeba4e51ac4f43fd68b1e5b
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Dec 19 22:13:33 2021 +0000
+Date: Sun Mar 20 08:52:17 2022 +0000
- upstream: agent support for parsing hostkey-bound signatures
-
- Allow parse_userauth_request() to work with blobs from
- publickey-hostbound-v00@openssh.com userauth attempts.
-
- Extract hostkey from these blobs.
+ upstream: don't leak argument list; bz3404, reported by Balu
- ok markus@
+ Gajjala ok dtucker@
- OpenBSD-Commit-ID: 81c064255634c1109477dc65c3e983581d336df8
+ OpenBSD-Commit-ID: fddc32d74e5dd5cff1a49ddd6297b0867eae56a6
-commit 3e16365a79cdeb2d758cf1da6051b1c5266ceed7
+commit a72bde294fe0518c9a44ba63864093a1ef2425e3
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Dec 19 22:13:12 2021 +0000
+Date: Sun Mar 20 08:51:21 2022 +0000
- upstream: EXT_INFO negotiation of hostbound pubkey auth
+ upstream: make addargs() and replacearg() a little more robust and
- the EXT_INFO packet gets a new publickey-hostbound@openssh.com to
- advertise the hostbound public key method.
+ improve error reporting
- Client side support to parse this feature flag and set the kex->flags
- indicator if the expected version is offered (currently "0").
+ make freeargs(NULL) a noop like the other free functions
- ok markus@
+ ok dtucker as part of bz3403
- OpenBSD-Commit-ID: 4cdb2ca5017ec1ed7a9d33bda95c1d6a97b583b0
+ OpenBSD-Commit-ID: 15f86da83176978b4d1d288caa24c766dfa2983d
-commit 94ae0c6f0e35903b695e033bf4beacea1d376bb1
+commit 731087d2619fa7f01e675b23f57af10d745e8af2
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Dec 19 22:12:54 2021 +0000
+Date: Fri Mar 18 04:04:11 2022 +0000
- upstream: client side of host-bound pubkey authentication
-
- Add kex->flags member to enable the publickey-hostbound-v00@openssh.com
- authentication method.
-
- Use the new hostbound method in client if the kex->flags flag was set,
- and include the inital KEX hostkey in the userauth request.
-
- Note: nothing in kex.c actually sets the new flag yet
+ upstream: don't try to resolve ListenAddress directives in the sshd
- ok markus@
+ re-exec path - we're never going to use the result and if the operation fails
+ then it can prevent connections from being accepted. Reported by Aaron
+ Poffenberger; with / ok dtucker@
- OpenBSD-Commit-ID: 5a6fce8c6c8a77a80ee1526dc467d91036a5910d
+ OpenBSD-Commit-ID: 44c53a43909a328e2f5ab26070fdef3594eded60
-commit 288fd0218dbfdcb05d9fbd1885904bed9b6d42e6
+commit 1c83c082128694ddd11ac05fdf31d70312ff1763
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Dec 19 22:12:30 2021 +0000
+Date: Fri Mar 18 02:50:21 2022 +0000
- upstream: sshd side of hostbound public key auth
-
- This is identical to the standard "publickey" method, but it also includes
- the initial server hostkey in the message signed by the client.
-
- feedback / ok markus@
+ upstream: remove blank line
- OpenBSD-Commit-ID: 7ea01bb7238a560c1bfb426fda0c10a8aac07862
+ OpenBSD-Commit-ID: d5e0182965b2fbfb03ad5f256d1a1ce5706bcddf
-commit dbb339f015c33d63484261d140c84ad875a9e548
+commit 807be68684da7a1fe969c399ddce2fafb7997dcb
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Dec 19 22:12:07 2021 +0000
+Date: Fri Mar 18 02:32:22 2022 +0000
- upstream: prepare for multiple names for authmethods
+ upstream: helpful comment
- allow authentication methods to have one additional name beyond their
- primary name.
-
- allow lookup by this synonym
-
- Use primary name for authentication decisions, e.g. for
- PermitRootLogin=publickey
-
- Pass actual invoked name to the authmethods, so they can tell whether they
- were requested via the their primary name or synonym.
-
- ok markus@
-
- OpenBSD-Commit-ID: 9e613fcb44b8168823195602ed3d09ffd7994559
+ OpenBSD-Commit-ID: e3315a45cb04e7feeb614d76ec80a9fe4ca0e8c7
-commit 39f00dcf44915f20684160f0a88d3ef8a3278351
+commit a0b5816f8f1f645acdf74f7bc11b34455ec30bac
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Dec 19 22:11:39 2021 +0000
+Date: Fri Mar 18 02:31:25 2022 +0000
- upstream: ssh-agent side of destination constraints
-
- Gives ssh-agent the ability to parse restrict-destination-v00@openssh.com
- constraints and to apply them to keys.
-
- Check constraints against the hostkeys recorded for a SocketEntry when
- attempting a signature, adding, listing or deleting keys. Note that
- the "delete all keys" request will remove constrained keys regardless of
- location.
+ upstream: ssh-keygen -Y check-novalidate requires namespace or SEGV
- feedback Jann Horn & markus@
- ok markus@
+ will ensue. Patch from Mateusz Adamowski via GHPR#307
- OpenBSD-Commit-ID: 84a7fb81106c2d609a6ac17469436df16d196319
+ OpenBSD-Commit-ID: 99e8ec38f9feb38bce6de240335be34aedeba5fd
-commit ce943912df812c573a33d00bf9e5435b7fcca3f7
+commit 5a252d54a63be30d5ba4be76210942d754a531c0
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Dec 19 22:11:06 2021 +0000
+Date: Tue Mar 15 05:27:37 2022 +0000
- upstream: ssh-add side of destination constraints
-
- Have ssh-add accept a list of "destination constraints" that allow
- restricting where keys may be used in conjunction with a ssh-agent/ssh
- that supports session ID/hostkey binding.
-
- Constraints are specified as either "[user@]host-pattern" or
- "host-pattern>[user@]host-pattern".
-
- The first form permits a key to be used to authenticate as the
- specified user to the specified host.
-
- The second form permits a key that has previously been permitted
- for use at a host to be available via a forwarded agent to an
- additional host.
-
- For example, constraining a key with "user1@host_a" and
- "host_a>host_b". Would permit authentication as "user1" at
- "host_a", and allow the key to be available on an agent forwarded
- to "host_a" only for authentication to "host_b". The key would not
- be visible on agent forwarded to other hosts or usable for
- authentication there.
-
- Internally, destination constraints use host keys to identify hosts.
- The host patterns are used to obtain lists of host keys for that
- destination that are communicated to the agent. The user/hostkeys are
- encoded using a new restrict-destination-v00@openssh.com key
- constraint.
-
- host keys are looked up in the default client user/system known_hosts
- files. It is possible to override this set on the command-line.
-
- feedback Jann Horn & markus@
- ok markus@
+ upstream: improve DEBUG_CHANNEL_POLL debugging message
- OpenBSD-Commit-ID: 6b52cd2b637f3d29ef543f0ce532a2bce6d86af5
+ OpenBSD-Commit-ID: 2275eb7bc4707d019b1a0194b9c92c0b78da848f
-commit 5e950d765727ee0b20fc3d2cbb0c790b21ac2425
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Dec 19 22:10:24 2021 +0000
+commit ce324cf58ba2840e31afeb996935800780c8fa4b
+Author: cheloha@openbsd.org <cheloha@openbsd.org>
+Date: Sun Mar 13 23:27:54 2022 +0000
- upstream: ssh-add side of destination constraints
-
- Have ssh-add accept a list of "destination constraints" that allow
- restricting where keys may be used in conjunction with a ssh-agent/ssh
- that supports session ID/hostkey binding.
+ upstream: ssh: xstrdup(): use memcpy(3)
- Constraints are specified as either "[user@]host-pattern" or
- "host-pattern>[user@]host-pattern".
+ Copying the given string into the buffer with strlcpy(3) confers no
+ benefit in this context because we have already determined the
+ string's length with strlen(3) in order to allocate that buffer.
- The first form permits a key to be used to authenticate as the
- specified user to the specified host.
+ Thread: https://marc.info/?l=openbsd-tech&m=164687525802691&w=2
- The second form permits a key that has previously been permitted
- for use at a host to be available via a forwarded agent to an
- additional host.
+ ok dtucker@ millert@
- For example, constraining a key with "user1@host_a" and
- "host_a>host_b". Would permit authentication as "user1" at
- "host_a", and allow the key to be available on an agent forwarded
- to "host_a" only for authentication to "host_b". The key would not
- be visible on agent forwarded to other hosts or usable for
- authentication there.
+ OpenBSD-Commit-ID: f8bfc082e36e2d2dc4e1feece02fe274155ca11a
+
+commit 2893c5e764557f48f9d6a929e224ed49c59545db
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Mar 11 18:43:58 2022 +1100
+
+ Resync fmt_scaled. with OpenBSD.
- Internally, destination constraints use host keys to identify hosts.
- The host patterns are used to obtain lists of host keys for that
- destination that are communicated to the agent. The user/hostkeys are
- encoded using a new restrict-destination-v00@openssh.com key
- constraint.
+ Fixes underflow reported in bz#3401.
+
+commit 5ae31a0fdd27855af29f48ff027491629fff5979
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Mar 9 09:41:56 2022 +1100
+
+ Provide killpg implementation.
- host keys are looked up in the default client user/system known_hosts
- files. It is possible to override this set on the command-line.
+ Based on github PR#301 for Tandem NonStop.
+
+commit c41c84b439f4cd74d4fe44298a4b4037ddd7d2ae
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Mar 9 09:29:30 2022 +1100
+
+ Check for missing ftruncate prototype.
- feedback Jann Horn & markus@
- ok markus@
+ From github PR#301 in conjunction with rsbeckerca.
+
+commit 8cf5275452a950869cb90eeac7d220b01f77b12e
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Tue Mar 8 20:04:06 2022 +1100
+
+ Default to not using sandbox when cross compiling.
- OpenBSD-Commit-ID: ef47fa9ec0e3c2a82e30d37ef616e245df73163e
+ On most systems poll(2) does not work when the number of FDs is reduced
+ with setrlimit, so assume it doesn't when cross compiling and we can't
+ run the test. bz#3398.
-commit 4c1e3ce85e183a9d0c955c88589fed18e4d6a058
+commit 379b30120da53d7c84aa8299c26b18c51c2a0dac
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Dec 19 22:09:23 2021 +0000
+Date: Tue Mar 1 01:59:19 2022 +0000
- upstream: ssh-agent side of binding
+ upstream: pack pollfd array before server_accept_loop() ppoll()
- record session ID/hostkey/forwarding status for each active socket.
+ call, and terminate sshd if ppoll() returns errno==EINVAL
- Attempt to parse data-to-be-signed at signature request time and extract
- session ID from the blob if it is a pubkey userauth request.
+ avoids spin in ppoll when MaxStartups > RLIMIT_NOFILE, reported by
+ Daniel Micay
- ok markus@
+ feedback/ok deraadt
- OpenBSD-Commit-ID: a80fd41e292b18b67508362129e9fed549abd318
+ OpenBSD-Commit-ID: dbab1c24993ac977ec24d83283b8b7528f7c2c15
-commit e9497ecf73f3c16667288bce48d4e3d7e746fea1
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Dec 19 22:08:48 2021 +0000
+commit eceafbe0bdbbd9bd2f3cf024ccb350666a9934dd
+Author: naddy@openbsd.org <naddy@openbsd.org>
+Date: Sun Feb 27 01:33:59 2022 +0000
- upstream: ssh client side of binding
-
- send session ID, hostkey, signature and a flag indicating whether the
- agent connection is being forwarded to ssh agent each time a connection
- is opened via a new "session-bind@openssh.com" agent extension.
+ upstream: include rejected signature algorithm in error message and
- ok markus@
+ not the (useless) key type; ok djm@
- OpenBSD-Commit-ID: 2f154844fe13167d3ab063f830d7455fcaa99135
+ OpenBSD-Commit-ID: d0c0f552a4d9161203e07e95d58a76eb602a76ff
-commit b42c61d6840d16ef392ed0f365e8c000734669aa
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Dec 19 22:08:06 2021 +0000
+commit f2f3269423618a83157e18902385e720f9776007
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Feb 25 09:46:24 2022 +0000
- upstream: Record session ID, host key and sig at intital KEX
-
- These will be used later for agent session ID / hostkey binding
+ upstream: Remove the char * casts from arguments to do_lstat,
- ok markus@
+ do_readdir and do_stat paths since the underlying functions now take a const
+ char *. Patch from vapier at gentoo.org.
- OpenBSD-Commit-ID: a9af29e33772b18e3e867c6fa8ab35e1694a81fe
+ OpenBSD-Commit-ID: 9e4d964dbfb0ed683a2a2900711b88e7f1c0297b
-commit 26ca33d186473d58a32d812e19273ce078b6ffff
+commit 4a66dac052c5ff5047161853f36904607649e4f9
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Dec 7 22:06:45 2021 +0000
+Date: Fri Feb 25 02:09:27 2022 +0000
- upstream: better error message for FIDO keys when we can't match
+ upstream: save an unneccessary alloc/free, based on patch from
- them to a token
+ Martin Vahlensieck; ok dtucker@
- OpenBSD-Commit-ID: 58255c2a1980088f4ed144db67d879ada2607650
+ OpenBSD-Commit-ID: 90ffbf1f837e509742f2c31a1fbf2c0fd376fd5f
-commit adb0ea006d7668190f0c42aafe3a2864d352e34a
+commit 6f117cb151efe138ac57bdd8e26165f350328f5f
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Dec 15 10:50:33 2021 +1100
+Date: Tue Mar 1 09:02:06 2022 +1100
- Correct value for IPTOS_DSCP_LE.
-
- It needs to allow for the preceeding two ECN bits. From daisuke.higashi
- at gmail.com via OpenSSH bz#3373, ok claudio@, job@, djm@.
+ Remove unused ivbits argument from chacha_keysetup
-commit 3dafd3fe220bd9046f11fcf5191a79ec8800819f
+commit 15974235dd528aeab0ec67fb92a0a1d733f62be2
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Dec 10 11:57:30 2021 +1100
+Date: Tue Mar 1 09:00:20 2022 +1100
- Increase timeout for test step.
+ Add OPENBSD ORIGINAL marker.
-commit 5aefb05cd5b843e975b191d6ebb7ddf8de35c112
+commit f2ff669347d320532e7c1b63cdf5c62f46e73150
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Dec 10 10:27:27 2021 +1100
+Date: Mon Feb 28 22:21:36 2022 +1100
- Update the list of tests that don't work on Minix.
+ No unused param warnings for clang-12 and gcc-11.
- While there, remove CC (configure will now find clang) and make the test
- list easier to update via cut and paste.
+ These have too many false positives in -Werror tests on the github CI
+ since we often provide empty stub functions for functionality not needed
+ for particular configurations.
-commit 1c09bb1b2e207d091cec299c49416c23d24a1b31
+commit 96558ecd87adac62efa9a2b5479f686ab86b0be1
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Dec 10 10:12:57 2021 +1100
+Date: Sat Feb 26 14:10:41 2022 +1100
- Add minix host tuple.
-
- Define SETEUID_BREAKS_SETUID for it which should make privsep work.
+ Add debian-i386 test target.
-commit a2188579032cf080213a78255373263466cb90cc
-Author: jsg@openbsd.org <jsg@openbsd.org>
-Date: Sun Dec 5 12:28:27 2021 +0000
+commit 284b6e5394652d519e31782e3b3cdfd7b21d1a81
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat Feb 26 14:06:14 2022 +1100
- upstream: fix unintended sizeof pointer in debug path ok markus@
+ Allow ppoll_time64 in seccomp sandbox.
- OpenBSD-Commit-ID: b9c0481ffc0cd801e0840e342e6a282a85aac93c
+ Should fix sandbox violations on (some? at least i386 and armhf) 32bit
+ Linux platforms. Patch from chutzpahu at gentoo.org and cjwatson at
+ debian.org via bz#3396.
-commit da40355234068c82f1a36196f2d18dd2d81aaafd
-Author: naddy@openbsd.org <naddy@openbsd.org>
-Date: Sat Dec 4 00:05:39 2021 +0000
+commit 0132056efabc5edb85c3c7105d2fb6dee41843c6
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Feb 25 19:47:48 2022 +1100
- upstream: RSA/SHA-1 is not used by default anymore on the server
+ Improve handling of _getshort and _getlong.
- OpenBSD-Commit-ID: 64abef6cfc3e53088225f6b8a1dcd86d52dc8353
+ If the system native ones are exactly as required then use them,
+ otherwise use the local versions mapped to another name to prevent
+ name collisions.
-commit e9c71498a083a8b502aa831ea931ce294228eda0
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Dec 2 23:45:36 2021 +0000
+commit 8e206e0dd6b9f757b07979e48f53ad5bf9b7b52b
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Feb 25 15:14:22 2022 +1100
- upstream: hash full host:port when asked to hash output, fixes hashes
-
- for non- default ports. bz3367 ok dtucker@
+ Constify utimes in compat library to match specs.
- OpenBSD-Commit-ID: 096021cc847da7318ac408742f2d0813ebe9aa73
+ Patch from vapier at chromium.org.
-commit b5601202145a03106012c22cb8980bcac2949f0b
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Dec 2 23:23:13 2021 +0000
+commit 1b2920e3b63db2eddebeec7330ffe8b723055573
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Feb 25 13:50:56 2022 +1100
- upstream: improve the testing of credentials against inserted FIDO
-
- keys a little more: ask the token whether a particular key belongs to it in
- cases where the token support on-token user- verification (e.g. biometrics)
- rather than just assuming that it will accept it.
-
- Will reduce spurious "Confirm user presence" notifications for key
- handles that relate to FIDO keys that are not currently inserted in at
- least some cases.
-
- Motivated by bz3366; by Pedro Martelletto
+ ANSIfy getshort and getlong.
- OpenBSD-Commit-ID: ffac7f3215842397800e1ae2e20229671a55a63d
+ These functions appear to have come from OpenBSD's lib/libc/net/res_comp.c
+ which made this change in 2005.
-commit ca709e27c41c90f4565b17282c48dca7756e083c
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Dec 2 22:40:05 2021 +0000
+commit 54a86f4f6e1c43a2ca2be23ef799ab8910d4af70
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Feb 25 13:23:04 2022 +1100
- upstream: move check_sk_options() up so we can use it earlier
-
- OpenBSD-Commit-ID: 67fe98ba1c846d22035279782c4664c1865763b4
+ Use PICFLAG instead of hard coding -fPIC.
-commit b711bc01a7ec76bb6a285730990cbce9b8ca5773
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Thu Dec 2 22:35:05 2021 +0000
+commit 3016ba47035ac3561aabd48e2be70167fe157d6a
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Feb 25 11:37:11 2022 +1100
- upstream: ssh-rsa is no longer in the default for
-
- PubkeyAcceptedAlgorithms.
-
- OpenBSD-Commit-ID: 34a9e1bc30966fdcc922934ae00f09f2596cd73c
+ Add tests for latest releases of {Libre,Open}SSL.
-commit dc91ceea33cd4a9f05be953e8d8062f732db5c8a
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Dec 2 02:44:44 2021 +0000
+commit f107467179428a0e3ea9e4aa9738ac12ff02822d
+Author: Colin Watson <cjwatson@debian.org>
+Date: Thu Feb 24 16:04:18 2022 +0000
- upstream: don't put the tty into raw mode when SessionType=none, avoids
-
- ^c being unable to kill such a session. bz3360; ok dtucker@
+ Improve detection of -fzero-call-used-regs=all support
- OpenBSD-Commit-ID: 83960c433052303b643b4c380ae2f799ac896f65
+ GCC doesn't tell us whether this option is supported unless it runs into
+ the situation where it would need to emit corresponding code.
-commit e6e7d2654a13ba10141da7b42ea683ea4eeb1f38
-Author: Damien Miller <djm@mindrot.org>
-Date: Mon Nov 29 14:11:03 2021 +1100
+commit 3383b2cac0e9275bc93c4b4760e6e048f537e1d6
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Feb 23 21:21:49 2022 +0000
- previous commit broke bcrypt_pbkdf()
+ upstream: free(3) wants stdlib.h
- Accidentally reverted part of the conversion to use SHA512 from SUPERCOP
- instead of OpenBSD-style libc SHA512.
+ OpenBSD-Commit-ID: 227a8c70a95b4428c49e46863c9ef4bd318a3b8a
-commit c0459588b8d00b73e506c6095958ecfe62a4a7ba
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Mon Nov 29 14:03:19 2021 +1100
+commit a4537e79ab4ac6db4493c5158744b9ebde5efcb0
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Feb 23 21:21:16 2022 +0000
- Fix typo in Neils' name.
+ upstream: put back the scp manpage changes for SFTP mode too
+
+ OpenBSD-Commit-ID: 05dc53921f927e1b5e5694e1f3aa314549f2e768
-commit 158bf854e2a22cf09064305f4a4e442670562685
-Author: Damien Miller <djm@mindrot.org>
-Date: Mon Nov 29 12:30:22 2021 +1100
+commit 449bcb8403adfb9724805d02a51aea76046de185
+Author: deraadt@openbsd.org <deraadt@openbsd.org>
+Date: Wed Feb 23 19:01:00 2022 +0000
- sync bcrypt-related files with OpenBSD
+ upstream: and we go back to testing sftp-scp after the 8.9
- The main change is that Niels Provos kindly agreed to rescind the
- BSD license advertising clause, shifting them to the 3-term BSD
- license.
+ release...
- This was the last thing in OpenSSH that used the advertising clause.
+ OpenBSD-Commit-ID: a80440168258adca543a4607b871327a279c569c
-commit e8976d92a42883ff6b8991438f07df60c2c0d82d
+commit 166456cedad3962b83b848b1e9caf80794831f0f
Author: Damien Miller <djm@mindrot.org>
-Date: Mon Nov 29 12:29:29 2021 +1100
+Date: Wed Feb 23 22:31:11 2022 +1100
- depend
+ makedepend
-commit 8249afeec013e557fe7491a72ca3285de03e25b1
+commit 32ebaa0dbca5d0bb86e384e72bebc153f48413e4
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Nov 28 07:21:26 2021 +0000
+Date: Wed Feb 23 11:18:13 2022 +0000
- upstream: sshsig: return "key not found" when searching empty files
+ upstream: avoid integer overflow of auth attempts (harmless, caught
- rather than "internal error"
+ by monitor)
- OpenBSD-Commit-ID: e2ccae554c78d7a7cd33fc5d217f35be7e2507ed
+ OpenBSD-Commit-ID: 488ad570b003b21e0cd9e7a00349cfc1003b4d86
-commit 9e3227d4dbb5ad9c9091b4c14982cab4bba87b4d
+commit 6e0258c64c901753df695e06498b26f9f4812ea6
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Nov 28 07:15:10 2021 +0000
+Date: Wed Feb 23 11:17:10 2022 +0000
- upstream: ssh-keygen -Y match-principals doesn't accept any -O
-
- options at present, so don't say otherwise in SYNOPSIS; spotted jmc@
+ upstream: randomise the password used in fakepw
- OpenBSD-Commit-ID: 9cc43a18f4091010741930b48b3db2f2e4f1d35c
+ OpenBSD-Commit-ID: 34e159f73b1fbf0a924a9c042d8d61edde293947
-commit 56db1f4a4cf5039fc3b42e84c4b16291fdff32b1
+commit bf114d6f0a9df0b8369823d9a0daa6c72b0c4cc9
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Nov 28 07:14:29 2021 +0000
+Date: Wed Feb 23 11:15:57 2022 +0000
- upstream: fix indenting in last commit
+ upstream: use asprintf to construct .rhosts paths
- OpenBSD-Commit-ID: 8b9ba989815d0dec1fdf5427a4a4b58eb9cac4d2
+ OpenBSD-Commit-ID: 8286e8d3d2c6ff916ff13d041d1713073f738a8b
-commit 50bea24a9a9bdebad327c76e700def3261f5694e
+commit c07e154fbdc7285e9ec54e78d8a31f7325d43537
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Nov 28 07:10:18 2021 +0000
+Date: Wed Feb 23 11:07:09 2022 +0000
- upstream: missing initialisation for oerrno
+ upstream: openssh-8.9
- OpenBSD-Commit-ID: 05d646bba238080259bec821c831a6f0b48d2a95
+ OpenBSD-Commit-ID: 5c5f791c87c483cdab6d9266b43acdd9ca7bde0e
-commit 5a0f4619041d09cd29f3a08da41db5040372bdd1
+commit bc16667b4a1c3cad7029304853c143a32ae04bd4
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sun Nov 28 15:31:37 2021 +1100
+Date: Tue Feb 22 15:29:22 2022 +1100
- Correct ifdef to activate poll() only if needed.
+ Extend select+rlimit sanbox test to include poll.
+
+ POSIX specifies that poll() shall fail if "nfds argument is greater
+ than {OPEN_MAX}". The setrlimit sandbox sets this to effectively zero
+ so this causes poll() to fail in the preauth privsep process.
+
+ This is likely the underlying cause for the previously observed similar
+ behaviour of select() on plaforms where it is implement in userspace on
+ top of poll().
-commit d4035c81a71237f690edd7eda32bef7d63fd9528
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Nov 27 07:23:35 2021 +0000
+commit 6520c488de95366be031d49287ed243620399e23
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Tue Feb 22 13:08:59 2022 +1100
- upstream: whitespac e
-
- OpenBSD-Regress-ID: b9511d41568056bda489e13524390167889908f8
+ Add Alpine Linux test VM.
-commit a443491e6782ef0f5a8bb87a5536c8ee4ff233a1
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Nov 27 07:20:58 2021 +0000
+commit a4b325a3fc82d11e0f5d61f62e7fde29415f7afb
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Tue Feb 22 12:27:07 2022 +1100
- upstream: regression test for match-principals. Mostly by Fabian
-
- Stelzer
+ Include sys/param.h if present.
- OpenBSD-Regress-ID: ced0bec89af90935103438986bbbc4ad1df9cfa7
+ Needed for howmany() on MUSL systems such as Alpine.
-commit 78230b3ec8cbabc1e7de68732dc5cbd4837c6675
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Nov 27 07:14:46 2021 +0000
+commit 5a102e9cb287a43bd7dfe594b775a89a8e94697c
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Tue Feb 22 12:25:52 2022 +1100
- upstream: Add ssh-keygen -Y match-principals operation to perform
+ Only include sys/poll.h if we don't have poll.h.
- matching of principals names against an allowed signers file.
+ Prevents warnings on MUSL based systems such as Alpine.
+
+commit 7c0d4ce911d5c58b6166b2db754a4e91f352adf5
+Author: Damien Miller <djm@mindrot.org>
+Date: Tue Feb 22 11:14:51 2022 +1100
+
+ disable agent-restrict test on minix3
- Requested by and mostly written by Fabian Stelzer, towards a TOFU
- model for SSH signatures in git. Some tweaks by me.
+ Minix seems to have a platform-wide limit on the number of
+ select(2) syscalls that can be concurrently issued. This test
+ seems to exceed this limit.
- "doesn't bother me" deraadt@
+ Refer to:
- OpenBSD-Commit-ID: 8d1b71f5a4127bc5e10a880c8ea6053394465247
+ https://github.com/Stichting-MINIX-Research-Foundation/minix/blob/R3.3.0/minix/servers/vfs/select.c#L114
+ https://github.com/Stichting-MINIX-Research-Foundation/minix/blob/R3.3.0/minix/servers/vfs/select.c#L30-L31
-commit 15db86611baaafb24c40632784dabf82e3ddb1a7
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Nov 25 23:02:24 2021 +0000
+commit 81d33d8e3cf7ea5ce3a5653c6102b623e019428a
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Feb 21 21:27:20 2022 +1100
- upstream: debug("func: ...") -> debug_f("...")
-
- OpenBSD-Commit-ID: d58494dc05c985326a895adfbe16fbd5bcc54347
+ Skip agent-getpeereid when running as root.
-commit b7ffbb17e37f59249c31f1ff59d6c5d80888f689
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Nov 19 18:53:46 2021 +1100
+commit fbd772570a25436a33924d91c164d2b24021f010
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Sun Feb 20 03:47:26 2022 +0000
- Allow for fd = -1 in compat ppoll overflow check.
+ upstream: Aproximate realpath on the expected output by deduping
- Fixes tests on at least FreeBSD 6, possibly others.
+ leading slashes. Fixes test failure when user's home dir is / which is
+ possible in some portable configurations.
+
+ OpenBSD-Regress-ID: 53b8c53734f8893806961475c7106397f98d9f63
-commit 04b172da5b96a51b0d55c905b423ababff9f4e0b
+commit 336685d223a59f893faeedf0a562e053fd84058e
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Nov 19 16:01:51 2021 +1100
+Date: Sun Feb 20 13:30:52 2022 +1100
- Don't auto-enable Capsicum sandbox on FreeBSD 9/10.
+ Really move DSA to end of list.
- Since we changed from select() to ppoll() tests have been failing.
- This seems to be because FreeBSD 10 (and presumably 9) do not allow
- ppoll() in the privsep process and sshd will fail with "Not permitted in
- capability mode". Setting CAP_EVENT on the FDs doesn't help, but weirdly,
- poll() works without that. Those versions are EOL so this situation is
- unlikely to change.
+ In commit ad16a84e syncing from OpenBSD, RSA was accidentally moved to
+ the end of the list instead of DSA. Spotted by andrew at fyfe.gb.net.
-commit a823f39986e7b879f26412e64c15630e1cfa0dc5
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Nov 18 03:53:48 2021 +0000
+commit 63bf4f49ed2fdf2da6f97136c9df0c8168546eb3
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Feb 18 12:12:21 2022 +1100
- upstream: regression test for ssh-keygen -Y find-principals fix; from
-
- Fabian Stelzer ok djm markus
-
- OpenBSD-Regress-ID: 34fe4088854c1a2eb4c0c51cc4676ba24096bac4
-
-commit 199c4df66c0e39dd5c3333b162af274678c0501d
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Nov 18 21:32:11 2021 +0000
-
- upstream: less confusing debug message; bz#3365
-
- OpenBSD-Commit-ID: 836268d3642c2cdc84d39b98d65837f5241e4a50
+ Add test configs for MUSL C library.
-commit 97f9b6e61316c97a32dad94b7a37daa9b5f6b836
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Nov 18 21:11:01 2021 +0000
+commit f7fc6a43f1173e8b2c38770bf6cee485a562d03b
+Author: Damien Miller <djm@mindrot.org>
+Date: Thu Feb 17 22:54:19 2022 +1100
- upstream: avoid xmalloc(0) for PKCS#11 keyid for ECDSA keys (we
-
- already did this for RSA keys). Avoids fatal errors for PKCS#11 libraries
- that return empty keyid, e.g. Microchip ATECC608B "cryptoauthlib"; bz#3364
-
- OpenBSD-Commit-ID: 054d4dc1d6a99a2e6f8eebc48207b534057c154d
+ minix needs BROKEN_POLL too; chokes on /dev/null
-commit c74aa0eb73bd1edf79947d92d9c618fc3424c4a6
+commit 667fec5d4fe4406745750a32f69b5d2e1a75e94b
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Nov 18 03:50:41 2021 +0000
+Date: Thu Feb 17 10:58:27 2022 +0000
- upstream: ssh-keygen -Y find-principals was verifying key validity
-
- when using ca certs but not with simple key lifetimes within the allowed
- signers file.
-
- Since it returns the first keys principal it finds this could
- result in a principal with an expired key even though a valid
- one is just below.
+ upstream: check for EINTR/EAGAIN failures in the rfd fast-path; caught
- patch from Fabian Stelzer; feedback/ok djm markus
+ by dtucker's minix3 vm :) ok dtucker@
- OpenBSD-Commit-ID: b108ed0a76b813226baf683ab468dc1cc79e0905
+ OpenBSD-Commit-ID: 2e2c895a3e82ef347aa6694394a76a438be91361
-commit d902d728dfd81622454260e23bc09d5e5a9a795e
+commit 41417dbda9fb55a0af49a8236e3ef9d50d862644
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Nov 18 23:44:07 2021 +1100
+Date: Thu Feb 17 22:05:29 2022 +1100
- Correct calculation of tv_nsec in poll().
+ Comment hurd test, the VM is currently broken.
-commit 21dd5a9a3fb35e8299a1fbcf8d506f1f6b752b85
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Nov 18 23:11:37 2021 +1100
+commit b2aee35a1f0dc798339b3fcf96136da71b7e3f6d
+Author: Damien Miller <djm@mindrot.org>
+Date: Thu Feb 17 21:15:16 2022 +1100
- Add compat implementation of ppoll using pselect.
+ find sk-dummy.so when build_dir != src_dir
+
+ spotted by Corinna Vinschen; feedback & ok dtucker@
-commit b544ce1ad4afb7ee2b09f714aa63efffc73fa93a
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Nov 18 23:05:34 2021 +1100
+commit 62a2d4e50b2e89f2ef04576931895d5139a5d037
+Author: Damien Miller <djm@mindrot.org>
+Date: Wed Feb 16 16:26:17 2022 +1100
- Put poll.h inside ifdef HAVE_POLL_H.
+ update versions in preparation for 8.9 release
-commit 875408270c5a7dd69ed5449e5d85bd7120c88f70
+commit dd6d3dded721ac653ea73c017325e5bfeeec837f
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Nov 18 03:31:44 2021 +0000
+Date: Tue Feb 15 05:13:36 2022 +0000
- upstream: check for POLLHUP wherever we check for POLLIN
+ upstream: document the unbound/host-bound options to
- OpenBSD-Commit-ID: 6aa6f3ec6b17c3bd9bfec672a917f003a76d93e5
+ PubkeyAuthentication; spotted by HARUYAMA Seigo
+
+ OpenBSD-Commit-ID: 298f681b66a9ecd498f0700082c7a6c46e948981
-commit 36b5e37030d35bbaa18ba56825b1af55971d18a0
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Nov 18 03:07:59 2021 +0000
+commit df93529dd727fdf2fb290700cd4f1adb0c3c084b
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Feb 14 14:19:40 2022 +1100
- upstream: fd leak in sshd listen loop error path; from Gleb
-
- Smirnoff
+ Test if sshd accidentally acquires controlling tty
- OpenBSD-Commit-ID: a7a2be27a690a74bf2381bc16cea38e265657412
+ When SSHD_ACQUIRES_CTTY is defined, test for the problematic behaviour
+ in the STREAMS code before activating the workaround. ok djm@
-commit b99498d0c93f1edd04857b318308a66b28316bd8
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Nov 18 03:07:20 2021 +0000
+commit 766176cfdbfd7ec38bb6118dde6e4daa0df34888
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat Feb 12 10:24:56 2022 +1100
- upstream: check for POLLHUP as well as POLLIN in sshd listen loop;
-
- ok deraadt millert
+ Add cygwin-release test config.
- OpenBSD-Commit-ID: a4f1244c5a9c2b08dac4f3b1dc22e9d1dc60c587
+ This tests the flags used to build the cygwin release binaries.
-commit 1f3055d788e8cf80851eb1728b535d57eb0dba6a
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Nov 18 03:06:03 2021 +0000
+commit b30698662b862f5397116d23688aac0764e0886e
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Feb 11 21:00:35 2022 +1100
- upstream: check for POLLHUP as well as POLLIN, handle transient IO
+ Move SSHD_ACQUIRES_CTTY workaround into compat.
- errors as well as half-close on the output side; ok deraadt millert
+ On some (most? all?) SysV based systems with STREAMS based ptys,
+ sshd could acquire a controlling terminal during pty setup when
+ it pushed the "ptem" module, due to what is probably a bug in
+ the STREAMS driver that's old enough to vote. Because it was the
+ privileged sshd's controlling terminal, it was not available for
+ the user's session, which ended up without one. This is known to
+ affect at least Solaris <=10, derivatives such as OpenIndiana and
+ several other SysV systems. See bz#245 for the backstory.
- OpenBSD-Commit-ID: de5c5b9939a37476d256328cbb96305bdecf511e
-
-commit 9778a15fa6dbdac6a95bf15865c2688b4bd6944e
-Author: Damien Miller <djm@mindrot.org>
-Date: Thu Nov 18 10:16:55 2021 +1100
-
- adjust seccomp filter for select->poll conversion
+ In the we past worked around that by not calling setsid in the
+ privileged sshd child, which meant it was not a session or process
+ group leader. This solved controlling terminal problem because sshd
+ was not eligble to acquire one, but had other side effects such as
+ not cleaning up helper subprocesses in the SIGALRM handler since it
+ was not PG leader. Recent cleanups in the signal handler uncovered
+ this, resulting in the LoginGraceTime timer not cleaning up privsep
+ unprivileged processes.
- Needed to add ppoll syscall but also to relax the fallback rlimit
- sandbox. Linux poll() fails with EINVAL if npfds > RLIMIT_NOFILE,
- so we have to allow a single fd in the rlimit.
+ This change moves the workaround into the STREAMS pty allocation code,
+ by allocating a sacrificial pty to act as sshd's controlling terminal
+ before allocating user ptys, so those are still available for users'
+ sessions.
+
+ On the down side:
+ - this will waste a pty per ssh connection on affected platforms.
+
+ On the up side:
+ - it makes the process group behaviour consistent between platforms.
+
+ - it puts the workaround nearest the code that actually causes the
+ problem and competely out of the mainline code.
+
+ - the workaround is only activated if you use the STREAMS code. If,
+ say, Solaris 11 has the bug but also a working openpty() it doesn't
+ matter that we defined SSHD_ACQUIRES_CTTY.
+
+ - the workaround is only activated when the fist pty is allocated,
+ ie in the post-auth privsep monitor. This means there's no risk
+ of fd leaks to the unprivileged processes, and there's no effect on
+ sessions that do not allocate a pty.
+
+ Based on analysis and work by djm@, ok djm@
-commit fcd8d895bbb849c64f0aed934e3303d37f696f5d
-Author: Damien Miller <djm@mindrot.org>
-Date: Thu Nov 18 10:16:44 2021 +1100
+commit cd00b48cf10f3565936a418c1e6d7e48b5c36140
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Feb 11 20:09:32 2022 +1100
- update depends
+ Simplify handling of --with-ssl-dir.
+
+ ok djm@
-commit 76292787a1e93e668f10e36b4bf59ce0ae28e156
-Author: Damien Miller <djm@mindrot.org>
-Date: Thu Nov 18 09:26:20 2021 +1100
+commit ea13fc830fc0e0dce2459f1fab2ec5099f73bdf0
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Feb 11 13:39:29 2022 +1100
- compat for timespecsub() and friends
+ Stop testing OpenBSD HEAD on 6.9 and 7.0.
+
+ HEAD is not guaranteed to work on previous stable branches, and at the
+ moment is broken due to libfido API changes.
-commit fd7e7de4ddb4399c7e929b44f2bbfc118eddfcf8
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Nov 17 21:06:39 2021 +0000
+commit 50b9e4a4514697ffb9592200e722de6b427cb9ff
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Feb 11 00:43:56 2022 +0000
- upstream: set num_listen_socks to 0 on close-all instead of -1,
+ upstream: Always initialize delim before passing to hpdelim2 which
- which interferes with the new poll()-based listen loop; spotted and debugged
- by anton@+deraadt@
+ might not set it. Found by the Valgrind tests on github, ok deraadt@
- OpenBSD-Commit-ID: f7ab8ab124f615a2e0c45fee14c38d2f2abbabbd
+ OpenBSD-Commit-ID: c830c0db185ca43beff3f41c19943c724b4f636d
-commit fd9343579afac30a971f06643a669733d9acb407
-Author: deraadt@openbsd.org <deraadt@openbsd.org>
-Date: Sun Nov 14 18:47:43 2021 +0000
+commit 6ee53064f476cf163acd5521da45b11b7c57321b
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Feb 11 10:03:06 2022 +1100
- upstream: use ppoll() instead of pselect() with djm
+ Fix helper include path and remove excess code.
- OpenBSD-Commit-ID: 980f87c9564d5d2ad55722b7a6f44f21284cd215
+ Looks like test_hpdelim.c was imported twice into the same file.
+ Spotted by kevin.brott at gmail com and chris at cataclysmal org.
-commit 092d29b232ef1a19609a5316ed7e4d896bb2e696
-Author: deraadt@openbsd.org <deraadt@openbsd.org>
-Date: Sun Nov 14 06:15:36 2021 +0000
+commit 9fa63a19f68bc87452d3cf5c577cafad2921b7a4
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Feb 10 23:27:02 2022 +1100
- upstream: match .events with .fd better
-
- OpenBSD-Commit-ID: 77eef212ca0add905949532af390164489c5984b
+ Put poll.h inside ifdef.
-commit 8d642c9a90fa4ed5a3effd785fb3591e14de00cd
-Author: deraadt@openbsd.org <deraadt@openbsd.org>
-Date: Sun Nov 14 03:25:10 2021 +0000
+commit 3ac00dfeb54b252c15dcbf1971582e9e3b946de6
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Feb 10 22:17:31 2022 +1100
- upstream: convert select() to poll() ok djm
-
- OpenBSD-Commit-ID: b53e4940ff10dd24f8d16e8db8ef1970015d7ead
+ We now support POLLPRI so actually define it.
-commit 6582a31c388968f4073af2bd8621880735c3d42b
-Author: deraadt@openbsd.org <deraadt@openbsd.org>
-Date: Sat Nov 13 21:14:13 2021 +0000
+commit 25bd659cc72268f2858c5415740c442ee950049f
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Sun Feb 6 22:58:33 2022 +0000
- upstream: replace select() with ppoll(), including converting
-
- timeval's to timespec's to make things easier. back and forth and ok; djm
+ upstream: Add test for empty hostname with port.
- OpenBSD-Commit-ID: 89d3b23c60875da919e7820f9de6213286ffbec9
+ OpenBSD-Regress-ID: e19e89d3c432b68997667efea44cf015bbe2a7e3
-commit 7c025c005550c86a40200a2bcdd355d09413d61a
-Author: deraadt@openbsd.org <deraadt@openbsd.org>
-Date: Sat Nov 13 17:26:13 2021 +0000
+commit a29af853cff41c0635f0378c00fe91bf9c91dea4
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Feb 4 07:53:44 2022 +0000
- upstream: It really looks like pledge "stdio dns" is possible
-
- earlier. Discussed with mestre
+ upstream: Add unit tests for hpdelim.
- OpenBSD-Commit-ID: 610873de63a593e0ac7bbbcb7a0f2894d36f4c01
+ OpenBSD-Regress-ID: be97b85c19895e6a1ce13c639765a3b48fd95018
-commit 06acb04c20ee483fe4757bd12aec870cc4bb1076
-Author: deraadt@openbsd.org <deraadt@openbsd.org>
-Date: Fri Nov 12 05:23:49 2021 +0000
+commit 9699151b039ecc5fad9ac6c6c02e9afdbd26f15f
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Feb 10 04:12:38 2022 +0000
- upstream: aggressively pre-fill the pollfd array with fd=-1
+ upstream: revert for imminent OpenSSH release, which wil ship with
- OpenBSD-Commit-ID: c2a525de8f83c1a04405bd79122c424140552a5b
+ scp in RCP mode.
+
+ > revision 1.106
+ > date: 2021/10/15 14:46:46; author: deraadt; state: Exp; lines: +13 -9; commitid: w5n9B2RE38tFfggl;
+ > openbsd 7.0 release shipped with the (hopefully last) scp that uses RCP
+ > protocol for copying. Let's get back to testing the SFTP protocol.
+
+ This will be put back once the OpenSSH release is done.
+
+ OpenBSD-Commit-ID: 0c725481a78210aceecff1537322c0b2df03e768
-commit 7eec76793dec06e8f06b6cf71f9473141c69d109
-Author: deraadt@openbsd.org <deraadt@openbsd.org>
-Date: Thu Nov 11 15:32:32 2021 +0000
+commit 45279abceb37c3cbfac8ba36dde8b2c8cdd63d32
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Tue Feb 8 08:59:12 2022 +0000
- upstream: Convert from select() to ppoll(). Along the way, I
+ upstream: Switch hpdelim interface to accept only ":" as delimiter.
- observed that the select() code was using exceptfds incorrectly.. ok millert
+ Historicallly, hpdelim accepted ":" or "/" as a port delimiter between
+ hosts (or addresses) and ports. These days most of the uses for "/"
+ are no longer accepted, so there are several places where it checks the
+ delimiter to disallow it. Make hpdelim accept only ":" and use hpdelim2
+ in the other cases. ok djm@
- OpenBSD-Commit-ID: 548e05bfc31b2af02319eb3d051286d4128dec96
+ OpenBSD-Commit-ID: 7e6420bd1be87590b6840973f5ad5305804e3102
-commit e665ed2d0c24fe11d5470ce72fa1e187377d3fc4
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Nov 12 22:55:27 2021 +1100
+commit a1bcbf04a7c2d81944141db7ecd0ba292d175a66
+Author: pedro martelletto <pedro@yubico.com>
+Date: Mon Feb 7 09:09:59 2022 +0100
- Switch from LibreSSL 3.4.0 to 3.4.1.
-
- The LibreSSL 3.4.0 release has an OPENBSD_BRANCH that points to
- "master" and that branch no longer has the files LibreSSL expects
- and thus it will no longer build, breaking the test.
+ fix typos in previous
-commit 21b6b5a06c8c53c548d25e6074c5240e88e2ef34
+commit 56192518e329b39f063487bc2dc4d796f791eca0
+Author: Damien Miller <djm@mindrot.org>
+Date: Mon Feb 7 12:53:47 2022 +1100
+
+ compat code for fido_assert_set_clientdata()
+
+commit d6b5aa08fdcf9b527f8b8f932432941d5b76b7ab
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Nov 10 06:29:25 2021 +0000
+Date: Mon Feb 7 01:25:12 2022 +0000
- upstream: add the sntrup761x25519-sha512@openssh.com hybrid
-
- ECDH/x25519 + Streamlined NTRU Prime post-quantum KEX to the default
- KEXAlgorithms list (after the ECDH methods but before the prime-group DH
- ones).
+ upstream: use libfido2 1.8.0+ fido_assert_set_clientdata() instead
- ok markus@
+ of manually hashing data outselves. Saves a fair bit of code and makes life
+ easier for some -portable platforms.
- OpenBSD-Commit-ID: 22b77e27a04e497a10e22f138107579652854210
+ OpenBSD-Commit-ID: 351dfaaa5ab1ee928c0e623041fca28078cff0e0
-commit 239da797cbf07a640d7b1ea02d3f99ace3ef792d
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Nov 10 06:25:08 2021 +0000
+commit 86cc93fd3c26b2e0c7663c6394995fb04ebfbf3b
+Author: jsg@openbsd.org <jsg@openbsd.org>
+Date: Sun Feb 6 00:29:03 2022 +0000
- upstream: fix ssh-keysign for KEX algorithms that use SHA384/512
-
- exchange hashes; feedback/ok markus@
+ upstream: remove please from manual pages ok jmc@ sthen@ millert@
- OpenBSD-Commit-ID: 09a8fda1c081f5de1e3128df64f28b7bdadee239
+ OpenBSD-Commit-ID: 6543acb00f4f38a23472538e1685c013ca1a99aa
-commit 6997a592ecb1013df0c6d7f8df3e6517827aef11
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Nov 8 21:32:49 2021 +0000
+commit ad16a84e64a8cf1c69c63de3fb9008320a37009c
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Feb 4 02:49:17 2022 +0000
- upstream: improve error message when trying to expand a ~user path
+ upstream: Since they are deprecated, move DSA to the end of the
- for a user that doesn't exist; better matches what the shell does
+ default list of public keys so that they will be tried last. From github
+ PR#295 from "ProBackup-nl", ok djm@
- ok deraadt@
+ OpenBSD-Commit-ID: 7e5d575cf4971d4e2de92e0b6d6efaba53598bf0
+
+commit 253de42753de85dde266e061b6fec12ca6589f7d
+Author: Damien Miller <djm@mindrot.org>
+Date: Wed Feb 2 16:52:07 2022 +1100
+
+ portable-specific string array constification
- OpenBSD-Commit-ID: 1ddefa3c3a78b69ce13d1b8f67bc9f2cefd23ad6
+ from Mike Frysinger
-commit 10b899a15c88eb40eb5f73cd0fa84ef0966f79c9
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Nov 10 12:34:25 2021 +1100
+commit dfdcc2220cf359c492d5d34eb723370e8bd8a19e
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Feb 1 23:37:15 2022 +0000
- Don't trust closefrom() on Linux.
+ upstream: test 'ssh-keygen -Y find-principals' with wildcard
- glibc's closefrom implementation does not work in a chroot when the kernel
- does not have close_range. It tries to read from /proc/self/fd and when
- that fails dies with an assertion of sorts. Instead, call close_range
- ourselves from our compat code and fall back if that fails. bz#3349,
- with william.wilson at canonical.com and fweimer at redhat.com.
+ principals; from Fabian Stelzer
+
+ OpenBSD-Regress-ID: fbe4da5f0032e7ab496527a5bf0010fd700f8f40
-commit eb1f63195a9a38b519536a5b398d9939261ec081
+commit 968e508967ef42480cebad8cf3172465883baa77
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Sat Nov 6 10:13:39 2021 +0000
+Date: Fri Jan 21 02:54:41 2022 +0000
- upstream: Plug a couple of minor mem leaks. From beldmit at
+ upstream: Enable all supported ciphers and macs in the server
- gmail.com via github PR#283, ok markus@
+ before trying to benchmark them. Increase the data file size to get more
+ signal.
- OpenBSD-Commit-ID: ec1fa7d305d46226861c3ca6fb9c9beb2ada2892
+ OpenBSD-Regress-ID: dc3697d9f7defdfc51c608782c8e750128e46eb6
-commit e4f501bf1d3b53f1cc23d9521fd7c5163307b760
+commit 15b7199a1fd37eff4c695e09d573f3db9f4274b7
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Nov 5 03:10:58 2021 +0000
+Date: Tue Feb 1 23:34:47 2022 +0000
- upstream: move cert_filter_principals() to earlier in the file for
+ upstream: allow 'ssh-keygen -Y find-principals' to match wildcard
- reuse; no code change
+ principals in allowed_signers files; from Fabian Stelzer
- OpenBSD-Commit-ID: 598fa9528b656b2f38bcc3cf5b6f3869a8c115cf
+ OpenBSD-Commit-ID: 1e970b9c025b80717dddff5018fe5e6f470c5098
-commit 59c60f96fee321c7f38f00372826d37f289534af
-Author: deraadt@openbsd.org <deraadt@openbsd.org>
-Date: Wed Nov 3 22:00:56 2021 +0000
+commit 541667fe6dc26d7881e55f0bb3a4baa6f3171645
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Feb 1 23:32:51 2022 +0000
- upstream: Many downstreams expect ssh to compile as non-C99...
+ upstream: mark const string array contents const too, i.e. static
- OpenBSD-Commit-ID: e6aa3e08bda68e5fb838fc8a49b1d2dfc38ee783
-
-commit 7a78fe63b0b28ef7231913dfefe9d08f9bc41c61
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Nov 6 21:07:03 2021 +1100
-
- Skip getline() on HP-UX 10.x.
+ const char *array => static const char * const array from Mike Frysinger
- HP-UX 10.x has a getline() implementation in libc that does not behave
- as we expect so don't use it. With correction from Thorsten Glaser and
- typo fix from Larkin Nickle.
-
-commit 343ae252ebb35c6ecae26b447bf1551a7666720e
-Author: Damien Miller <djm@mindrot.org>
-Date: Wed Nov 3 12:08:21 2021 +1100
-
- basic SECURITY.md (refers people to the website)
+ OpenBSD-Commit-ID: a664e31ea6a795d7c81153274a5f47b22bdc9bc1
-commit ed45a0168638319e0a710633f6085b96b9cec656
+commit 8cfa73f8a2bde4c98773f33f974c650bdb40dd3c
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Nov 2 22:57:27 2021 +0000
+Date: Tue Feb 1 23:11:11 2022 +0000
- upstream: crank SSH_SK_VERSION_MAJOR to match recent change in
+ upstream: better match legacy scp behaviour: show un-expanded paths
- usr/bin/ssh
+ in error messages. Spotted by and ok tb@
- OpenBSD-Regress-ID: 113d181c7e3305e138db9b688cdb8b0a0019e552
+ OpenBSD-Commit-ID: 866c8ffac5bd7d38ecbfc3357c8adfa58af637b7
-commit f3c34df860c4c1ebddacb973954e58167d9dbade
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Nov 2 22:56:40 2021 +0000
+commit 4e62c13ab419b4b224c8bc6a761e91fcf048012d
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Tue Feb 1 07:57:32 2022 +0000
- upstream: Better handle FIDO keys on tokens that provide user
+ upstream: Remove explicit kill of privsep preauth child's PID in
- verification (UV) on the device itself, including biometric keys.
+ SIGALRM handler. It's no longer needed since the child will get terminated by
+ the SIGTERM to the process group that cleans up any auth helpers, it
+ simplifies the signal handler and removes the risk of a race when updating
+ the PID. Based on analysis by HerrSpace in github PR#289, ok djm@
- Query the token during key creation to determine whether it supports
- on-token UV and, if so, clear the SSH_SK_USER_VERIFICATION_REQD flag
- in the key so that ssh(1) doesn't automatically prompty for PIN later.
+ OpenBSD-Commit-ID: 2be1ffa28b4051ad9e33bb4371e2ec8a31d6d663
+
+commit 2a7ccd2ec4022917b745af7186f514f365b7ebe9
+Author: guenther@openbsd.org <guenther@openbsd.org>
+Date: Fri Jan 28 06:18:42 2022 +0000
+
+ upstream: When it's the possessive of 'it', it's spelled "its",
- When making signatures with the key, query the token's capabilities
- again and check whether the token is able (right now) to perform user-
- verification without a PIN. If it is then the PIN prompt is bypassed
- and user verification delegated to the token. If not (e.g. the token
- is biometric capable, but no biometric are enrolled), then fall back
- to user verification via the usual PIN prompt.
+ without the apostrophe.
- Work by Pedro Martelletto; ok myself and markus@
+ OpenBSD-Commit-ID: fb6ab9c65bd31de831da1eb4631ddac018c5fae7
+
+commit 8a0848cdd3b25c049332cd56034186b7853ae754
+Author: Alex James <theracermaster@gmail.com>
+Date: Sun Jan 30 16:13:36 2022 -0600
+
+ sandbox-seccomp-filter: allow gettid
- NB. cranks SSH_SK_VERSION_MAJOR
+ Some allocators (such as Scudo) use gettid while tracing allocations [1].
+ Allow gettid in preauth to prevent sshd from crashing with Scudo.
- OpenBSD-Commit-ID: e318a8c258d9833a0b7eb0236cdb68b5143b2f27
+ [1]: https://github.com/llvm/llvm-project/blob/llvmorg-13.0.0/compiler-rt/lib/gwp_asan/common.cpp#L46
-commit 0328a081f38c09d2d4d650e94461a47fb5eef536
+commit b30d32159dc3c7052f4bfdf36357996c905af739
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Oct 29 03:03:06 2021 +0000
+Date: Sat Jan 22 00:49:34 2022 +0000
- upstream: sshsig: add tests for signing key validity and
+ upstream: add a ssh_packet_process_read() function that reads from
- find-principals
+ a fd directly into the transport input buffer.
- - adds generic find-principals tests (this command had none before)
- - tests certs with a timeboxed validity both with and without a
- restriced lifetime for the CA
- - test for a revoked CA cert
+ Use this in the client and server mainloops to avoid unnecessary
+ copying. It also lets us use a more greedy read size without penalty.
- by Fabian Stelzer
+ Yields a 2-3% performance gain on cipher-speed.sh (in a fairly
+ unscientific test tbf)
- OpenBSD-Regress-ID: 9704b2c6df5b8ccfbdf2c06c5431f5f8cad280c9
-
-commit ccd358e1e25e25c13f0825996283cbf7a1647a3b
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Oct 29 02:48:19 2021 +0000
-
- upstream: avoid signedness warning; spotted in -portable
+ feedback dtucker@ ok markus@
- OpenBSD-Regress-ID: 4cacc126086487c0ea7f3d86b42dec458cf0d0c6
+ OpenBSD-Commit-ID: df4112125bf79d8e38e79a77113e1b373078e632
-commit 2741f52beb11490d7033a25e56ed0496f0c78006
+commit a1a8efeaaa9cccb15cdc0a2bd7c347a149a3a7e3
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Oct 29 03:20:46 2021 +0000
+Date: Sat Jan 22 00:45:31 2022 +0000
- upstream: ssh-keygen: make verify-time argument parsing optional
+ upstream: Use sshbuf_read() to read directly into the channel input
- From Fabian Stelzer
+ buffer rather than into a stack buffer that needs to be copied again;
+ Improves performance by about 1% on cipher-speed.sh feedback dtucker@ ok
+ markus@
- OpenBSD-Commit-ID: 1ff35e4c366a45a073663df90381be6a8ef4d370
+ OpenBSD-Commit-ID: bf5e6e3c821ac3546dc8241d8a94e70d47716572
-commit a1217d363b88b32cfe54c4f02c6c1cf4bdefdd23
+commit 29a76994e21623a1f84d68ebb9dc5a3c909fa3a7
Author: Damien Miller <djm@mindrot.org>
-Date: Fri Oct 29 13:48:34 2021 +1100
+Date: Tue Jan 25 11:52:34 2022 +1100
- unbreak fuzz harness for recent changes
+ depend
-commit 68e522ed8183587c9367fa3842c5b75f64f3d12b
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Oct 29 13:32:24 2021 +1100
-
- Use -Wbitwise-instead-of-logical if supported.
-
-commit be28b23012aa3fa323be7ec84863cf238927c078
-Author: Damien Miller <djm@mindrot.org>
-Date: Thu Oct 28 16:24:53 2021 +1100
+commit 754e0d5c7712296a7a3a83ace863812604c7bc4f
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Jan 22 00:43:43 2022 +0000
- use -Wmisleading-indentation cflag if available
+ upstream: Add a sshbuf_read() that attempts to read(2) directly in
- ok dtucker@
-
-commit 2e6f5f24dd2f9217f4ab8b737ed428d5d5278f91
-Author: Damien Miller <djm@mindrot.org>
-Date: Thu Oct 28 16:24:44 2021 +1100
-
- depend
+ to a sshbuf; ok markus@
+
+ OpenBSD-Commit-ID: 2d8f249040a4279f3bc23c018947384de8d4a45b
-commit a5ab4882348d26addc9830a44e053238dfa2cb58
-Author: Damien Miller <djm@mindrot.org>
-Date: Thu May 6 10:08:30 2021 +1000
+commit c7964fb9829d9ae2ece8b51a76e4a02e8449338d
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Jan 21 07:04:19 2022 +0000
- remove built-in support for md5crypt()
+ upstream: add a helper for writing an error message to the
- Users of MD5-hashed password should arrange for ./configure to link
- against libxcrypt or similar. Though it would be better to avoid use
- of MD5 password hashing entirely, it's arguably worse than DEScrypt.
+ stderr_buf and setting quit_pending; no functional change but saves a bunch
+ of boilerplate
- feedback and ok dtucker@
+ OpenBSD-Commit-ID: 0747657cad6b9eabd514a6732adad537568e232d
-commit c5de1fffa6328b8246b87da28fa9df05813f76a3
+commit d23b4f7fdb1bd87e2cd7a9ae7c198ae99d347916
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Oct 28 02:55:30 2021 +0000
+Date: Fri Jan 21 06:58:06 2022 +0000
- upstream: increment SSH_SK_VERSION_MAJOR to match last change
+ upstream: correct comment and use local variable instead of long
- OpenBSD-Regress-ID: 17873814d1cbda97f49c8528d7b5ac9cadf6ddc0
+ indirection; spotted by dtucker@
+
+ OpenBSD-Commit-ID: 5f65f5f69db2b7d80a0a81b08f390a63f8845965
-commit 0001d04e55802d5bd9d6dece1081a99aa4ba2828
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Oct 28 02:54:18 2021 +0000
+commit d069b020a02b6e3935080204ee44d233e8158ebb
+Author: deraadt@openbsd.org <deraadt@openbsd.org>
+Date: Fri Jan 21 00:53:40 2022 +0000
- upstream: When downloading resident keys from a FIDO token, pass
-
- back the user ID that was used when the key was created and append it to the
- filename the key is written to (if it is not the default).
+ upstream: When poll(2) returns -1, for some error conditions
- Avoids keys being clobbered if the user created multiple
- resident keys with the same application string but different
- user IDs.
+ pfd[].revents is not cleared. There are subtle errors in various programs.
+ In this particular case, the program should error out. ok djm millert
- feedback Pedro Martelletto; ok markus
+ OpenBSD-Commit-ID: 00f839b16861f7fb2adcf122e95e8a82fa6a375c
+
+commit e204b34337a965feb439826157c191919fd9ecf8
+Author: Damien Miller <djm@mindrot.org>
+Date: Sat Jan 22 11:38:21 2022 +1100
+
+ restore tty force-read hack
- NB. increments SSH_SK_VERSION_MAJOR
+ This portable-specific hack fixes a hang on exit for ttyful sessions
+ on Linux and some SysVish Unix variants. It was accidentally disabled
+ in commit 5c79952dfe1a (a precursor to the mainloop poll(2) conversion).
- OpenBSD-Commit-ID: dbd658b5950f583106d945641a634bc6562dd3a3
+ Spotted by John in bz3383
-commit d4bed5445646e605c383a4374fa962e23bf9e3a3
-Author: deraadt@openbsd.org <deraadt@openbsd.org>
-Date: Sun Oct 24 21:24:17 2021 +0000
+commit 68085066b6bad43643b43f5957fcc5fd34782ccd
+Author: Corinna Vinschen <vinschen@redhat.com>
+Date: Fri Jan 21 03:22:56 2022 +1100
- upstream: For open/openat, if the flags parameter does not contain
+ Fix signedness bug in Cygwin code
- O_CREAT, the 3rd (variadic) mode_t parameter is irrelevant. Many developers
- in the past have passed mode_t (0, 044, 0644, or such), which might lead
- future people to copy this broken idiom, and perhaps even believe this
- parameter has some meaning or implication or application. Delete them all.
- This comes out of a conversation where tb@ noticed that a strange (but
- intentional) pledge behaviour is to always knock-out high-bits from mode_t on
- a number of system calls as a safety factor, and his bewilderment that this
- appeared to be happening against valid modes (at least visually), but no
- sorry, they are all irrelevant junk. They could all be 0xdeafbeef. ok
- millert
+ The Cygwin-specific pattern match code has a bug. It checks
+ the size_t value returned by mbstowcs for being < 0. The right
+ thing to do is to check against (size_t) -1. Fix that.
- OpenBSD-Commit-ID: 503d11633497115688c0c6952686524f01f53121
+ Signed-off-by: Corinna Vinschen <vinschen@redhat.com>
-commit d575cf44895104e0fcb0629920fb645207218129
+commit 2e5cfed513e84444483baf1d8b31c40072b05103
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Oct 22 23:27:41 2021 +1100
+Date: Thu Jan 20 13:26:27 2022 +1100
- kitchensink test target now needs krb5.
+ Improve compatibility of early exit trap handling.
+
+ Dash (as used by the github runners) has some differences in its trap
+ builtin:
+ - it doesn't have -p (which is fine, that's not in posix).
+ - it doesn't work in a subshell (which turns out to be in compliance
+ with posix, which means bash isn't).
+ - it doesn't work in a pipeline, ie "trap|cat" produces no output.
-commit 4ae39cada214e955bcfd3448ff28f0ed18886706
+commit 3fe6800b6027add478e648934cbb29d684e51943
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Oct 22 22:54:33 2021 +1100
+Date: Thu Jan 20 00:49:57 2022 +1100
- Test both MIT KRB5 and Heimdal.
+ Move more tests out of valgrind-1 runner.
-commit 22b2681d88619e5247dc53c9f112058a7e248d48
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Oct 22 10:51:57 2021 +0000
+commit 20da6ed136dd76e6a0b229ca3036ef9c7c7ef798
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Jan 19 15:37:39 2022 +1100
- upstream: Plug mem addrinfo mem leaks.
-
- Prevent mem leaks in the (unlikely) event that getaddrinfo returns
- no addresses. ALso, remove an unneeded NULL check in addr_ntop. From
- khaleesicodes via github PR#281, ok deraadt@
+ Invoke EXIT handler early when using Valgrind.
- OpenBSD-Commit-ID: e8a5afc686376637c355c5f7e122dc4b080b9c1a
+ When using Valgrind, we need to wait for all invoked programs to
+ complete before checking their valgrind logs. Some tests, notably
+ agent-restrict, set an EXIT trap handler to clean up things like
+ ssh-agent, but those do not get invoked until test-exec.sh exits.
+ This causes the Valgrind wait to deadlock, so if present invoke
+ the EXIT handler before checking the Valgrind logs.
-commit 27c8c343b610263f83ac2328735feeb881c6c92f
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Oct 22 09:22:04 2021 +0000
+commit ad2e0580c87b0714cf166bca9d926a95ddeee1c8
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Tue Jan 18 12:55:21 2022 +1100
- upstream: Remove unnecessary semicolons
-
- ... in case statements. From khaleesicodes via github PR#280.
-
- OpenBSD-Commit-ID: e1e89360b65775cff83e77ce040b342015caf4ed
+ Remove line leftover from upstream sync.
-commit e7eb73b8d1fe1008d92433ea949491ce654bfaba
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Oct 22 09:19:34 2021 +0000
+commit d1051c0f11a6b749027e26bbeb61b07df4b67e15
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Jan 17 22:56:04 2022 +0000
- upstream: Fix typos in comments.
+ upstream: when decompressing zlib compressed packets, use
- From khaleesicodes via github PR#280.
+ Z_SYNC_FLUSH instead of Z_PARTIAL_FLUSH as the latter is not actually
+ specified as a valid mode for inflate(). There should be no practical change
+ in behaviour as the compression side ensures a flush that should make all
+ data available to the receiver in all cases.
- OpenBSD-Commit-ID: 26fdd83652c40f098bf7c685e8ebb9eb72cc45fc
+ repoted by lamm AT ibm.com via bz3372; ok markus
+
+ OpenBSD-Commit-ID: 67cfc1fa8261feae6d2cc0c554711c97867cc81b
-commit 052a9d8494175e24312daa6c132665e58c17fe6e
-Author: deraadt@openbsd.org <deraadt@openbsd.org>
-Date: Fri Oct 15 14:46:46 2021 +0000
+commit d5981b1883746b1ae178a46229c26b53af99e37a
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Jan 17 21:41:04 2022 +0000
- upstream: switch scp(1) back to sftp protocol.
+ upstream: make most of the sftp errors more idiomatic, following
- openbsd 7.0 release shipped with the (hopefully last) scp that uses RCP
- protocol for copying. Let's get back to testing the SFTP protocol.
+ the general form of "[local/remote] operation path: error message"; ok markus
- OpenBSD-Commit-ID: 9eaa35d95fd547b78b0a043b3f518e135f151f30
+ OpenBSD-Commit-ID: 61364cd5f3a9fecaf8d63b4c38a42c0c91f8b571
-commit a07664646bf6d293f5bbd45a5de54f3c36bb85da
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Oct 22 14:00:05 2021 +1100
+commit ac7c9ec894ed0825d04ef69c55babb49bab1d32e
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Jan 17 21:39:51 2022 +0000
- Source configs script so setup_ci can use settings
+ upstream: when transferring multiple files in SFTP mode, create the
+
+ destination directory if it doesn't already exist to match olde-scp(1)
+ behaviour. noticed by deraadt@ ok markus@
+
+ OpenBSD-Commit-ID: cf44dfa231d4112f697c24ff39d7ecf2e6311407
-commit 34df52c201c6b47e5a46b50c215e4d98a8bf6587
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Oct 22 09:42:14 2021 +1100
+commit 39d17e189f8e72c34c722579d8d4e701fa5132da
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Jan 14 03:43:48 2022 +0000
- Install libedit and pam based on config flags.
+ upstream: allow pin-required FIDO keys to be added to ssh-agent(1).
+
+ ssh-askpass will be used to request the PIN at authentication time.
+
+ From Pedro Martelletto, ok djm
+
+ OpenBSD-Commit-ID: de8189fcd35b45f632484864523c1655550e2950
-commit 8c626cc563e8d21d844d06f9971a9ee01de6aa2a
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Oct 21 16:53:39 2021 +1100
+commit 52423f64e13db2bdc31a51b32e999cb1bfcf1263
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Jan 14 03:35:10 2022 +0000
- Don't use 'here string", it's not POSIX.
+ upstream: ssh-sk: free a resident key's user id
+
+ From Pedro Martelletto; ok dtucker & me
+
+ OpenBSD-Commit-ID: 47be40d602b7a6458c4c71114df9b53d149fc2e9
-commit 086a4b5977472aefa3de918b88efad0faf83b2b1
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Oct 21 15:33:27 2021 +1100
+commit 014e2f147a2788bfb3cc58d1b170dcf2bf2ee493
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Jan 14 03:34:00 2022 +0000
- Remove -Werror from compiler package to install.
+ upstream: sshsk_load_resident: don't preallocate resp
+
+ resp is allocated by client_converse(), at which point we lose
+ the original pointer.
+
+ From Pedro Martelletto; ok dtucker & me
+
+ OpenBSD-Commit-ID: 1f1b5ea3282017d6584dfed4f8370dc1db1f44b1
-commit 5a7a4687507d057f9b5e7497f3d3f82e64753c02
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Oct 21 15:00:53 2021 +1100
+commit c88265f207dfe0e8bdbaf9f0eda63ed6b33781cf
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Jan 14 03:32:52 2022 +0000
- Build with -Werror on most recent gcc and clang.
+ upstream: sshsk_sign: trim call to sshkey_fingerprint()
+
+ the resulting fingerprint doesn't appear to be used for anything,
+ and we end up leaking it.
+
+ from Pedro Martelletto; ok dtucker & me
+
+ OpenBSD-Commit-ID: 5625cf6c68f082bc2cbbd348e69a3ed731d2f9b7
-commit 4d2cbdb525d673acf941d48a7044fcf03125611a
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Oct 15 12:59:06 2021 +1100
+commit 1cd1b2eac39661b849d5a4b4b56363e22bb5f61e
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Jan 14 03:31:52 2022 +0000
- Include string.h and stdio.h for strerror.
-
-commit fff13aaa262b7b3ec83ed21e29674cbf331780a7
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Oct 15 12:43:36 2021 +1100
-
- Include error reason if trace disabling fails.
-
-commit d4b38144c02f3faa5271e5fb35df93507e06f1b4
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Tue Oct 12 22:55:51 2021 +1100
-
- Add tcmalloc test target.
+ upstream: use status error message to communicate ~user expansion
+
+ failures; provides better experience for scp in sftp mode, where ~user paths
+ are more likely to be used; spotted jsg, feedback jsg & deraadt ok jsg &
+ markus
+
+ (forgot to include this file in previous commit)
+
+ OpenBSD-Commit-ID: d37cc4c8c861ce48cd6ea9899e96aaac3476847b
-commit 002d65b0a30063c6e49bf8a53e709d8d5a0d45c1
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Sat Oct 9 10:52:42 2021 +0000
+commit a1d42a6ce0398da3833bedf374ef2571af7fea50
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Jan 14 13:49:32 2022 +1100
- upstream: Document that CASignatureAlgorithms, ExposeAuthInfo and
+ fix edge case in poll(2) wrapper
- PubkeyAuthOptions can be used in a Match block. Patch from eehakkin via
- github PR#277.
+ Correct handling of select(2) exceptfds. These should only be consulted
+ for POLLPRI flagged pfds and not unconditionally converted to POLLERR.
- OpenBSD-Commit-ID: c0a63f5f52e918645967ac022b28392da4b866aa
+ with and ok dtucker@
-commit 40bd3709dddaae3a1b6113748bec3faa6a607531
+commit 976b9588b4b5babcaceec4767a241c11a67a5ccb
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Oct 7 15:55:49 2021 +1100
+Date: Fri Jan 14 13:46:35 2022 +1100
- Skip SK unit tests when built without security-key
+ Wrap OpenSSL includes in unit tests in ifdef.
+
+ Fixes unit test on systems that do not have OpenSSL headers installed.
-commit 482f73be10f10b93f818df19fcc8a912c0c371fc
+commit c171879374b2e8b07157503f5639ed0bce59ce89
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Oct 7 15:55:04 2021 +1100
+Date: Thu Jan 13 15:53:33 2022 +1100
- Include relevant env vars on command line.
+ Remove sort wrapper.
- Makes it easier to reproduce a build by cut/pasting the configure line.
+ agent-restrict now takes care of this itself.
-commit ef5916b8acd9b1d2f39fad4951dae03b00dbe390
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Oct 7 14:28:02 2021 +1100
+commit 9cc2654403f1a686bb26c07a6ac790edf334cef5
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Thu Jan 13 04:53:16 2022 +0000
- Only enable sk-* key types if ENABLE_SK is defined
+ upstream: Set LC_ALL in both local and remote shells so that sorted
+
+ output matches regardless of what the user's shell sets it to. ok djm@
+
+ OpenBSD-Regress-ID: 4e97dd69a68b05872033175a4c2315345d01837f
-commit 52d4232b493a9858fe616e28a8bbcc89afa2ad4d
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Oct 6 18:14:37 2021 +1100
+commit 7a75f748cb2dd2f771bf70ea72698aa027996ab1
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Thu Jan 13 04:22:10 2022 +0000
- Disable security key on minix3.
+ upstream: Avoid %'s in commands (not used in OpenBSD, but used in
- The test doesn't work so disable.
+ -portable's Valgrind test) being interpretted as printf format strings.
+
+ OpenBSD-Regress-ID: dc8655db27ac4acd2c386c4681bf42a10d80b043
-commit 7cd062c3a29669b8d7dc2a97e6575f4dcb7d35a2
+commit 6c435bd4994d71442192001483a1cdb846e5ffcd
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Oct 6 17:45:28 2021 +1100
+Date: Wed Jan 12 16:58:13 2022 +1100
- Add USE_LIBC_SHA2 for (at least) NetBSD 9.
+ Stop on first test failure to minimize logs.
-commit 639c440f6c3c2a8216a5eb9455ef13bf4204089c
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Oct 6 17:09:31 2021 +1100
+commit 4bc2ba6095620a4484b708ece12842afd8c7685b
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Wed Jan 12 07:18:37 2022 +0000
- Define OPENSSL_NO_SHA including OpenSSL from test.
+ upstream: Use egrep when searching for an anchored string.
- We don't use SHA256 from OpenSSL in the sk-dummy module and the
- definitions can conflict with system sha2.h (eg on NetBSD) so define
- OPENSSL_NO_SHA so we don't attempt to redefine them.
+ OpenBSD-Regress-ID: dd114a2ac27ac4b06f9e4a586d3f6320c54aeeb4
-commit 8f4be526a338d06624f146fa26007bb9dd3a4f7b
+commit 6bf2efa2679da1e8e60731f41677b2081dedae2c
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Oct 6 15:40:58 2021 +1100
-
- Disable security key on NetBSD4 test.
-
- sk-dummy used for the security key test includes both sha2.h and OpenSSL
- causing the definitions conflict so disable security key support on this
- platform.
-
-commit 3b353ae58aa07a1cbbeb1da3ace21fc0dcccd66a
-Author: Damien Miller <djm@mindrot.org>
-Date: Wed Oct 6 15:07:01 2021 +1100
+Date: Wed Jan 12 18:25:06 2022 +1100
- clean regress/misc/sk-dummy in cleandir target
+ Add "rev" command replacement if needed.
-commit 57680a2ab43518c5ccbd8242c40482106cde6ac1
+commit 72bcd7993dadaf967bb3d8564ee31cbf38132b5d
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Sat Oct 2 03:17:01 2021 +0000
+Date: Wed Jan 12 03:30:32 2022 +0000
- upstream: Dynamically allocate encoded HashKnownHosts and free as
+ upstream: Don't log NULL hostname in restricted agent code,
- appropriate. Saves 1k of static storage and prevents snprintf "possible
- truncation" warnings from newer compilers (although in this case it's false
- positive since the actual sizes are limited by the output size of the SHA1).
- ok djm@
+ printf("%s", NULL) is not safe on all platforms. with & ok djm
- OpenBSD-Commit-ID: e254ae723f7e3dce352c7d5abc4b6d87faf61bf4
+ OpenBSD-Commit-ID: faf10cdae4adde00cdd668cd1f6e05d0a0e32a02
-commit e3e62deb549fde215b777d95276c304f84bf00c6
+commit acabefe3f8fb58c867c99fed9bbf84dfa1771727
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Oct 6 03:35:13 2021 +0000
+Date: Tue Jan 11 22:33:16 2022 +0000
- upstream: use libc SHA256 functions; make this work when compiled
+ upstream: remove hardcoded domain and use window.location.host, so this
- !WITH_OPENSSL
+ can be run anywhere
- OpenBSD-Regress-ID: fda0764c1097cd42f979ace29b07eb3481259890
+ OpenBSD-Regress-ID: 2ac2ade3b6227d9c547351d3ccdfe671e62b7f92
-commit 12937d867019469ebce83c2ff614cdc6688fc2d8
+commit 96da0946e44f34adc0397eb7caa6ec35a3e79891
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Oct 1 05:20:20 2021 +0000
+Date: Tue Jan 11 02:56:19 2022 +0000
- upstream: Add test for ssh hashed known_hosts handling.
+ upstream: "void" functions should not return anything. From Tim Rice
- OpenBSD-Regress-ID: bcef3b3cd5a1ad9899327b4b2183de2541aaf9cf
-
-commit 5a37cc118f464416d08cd0291a9b1611d8de9943
-Author: Damien Miller <djm@mindrot.org>
-Date: Wed Oct 6 13:16:21 2021 +1100
-
- fix broken OPENSSL_HAS_ECC test
+ via -portable.
- spotted by dtucker
+ OpenBSD-Commit-ID: ce6616304f4c9881b46413e616b226c306830e2a
-commit 16a25414f303cd6790eb967aeb962040e32c9c7a
-Author: Damien Miller <djm@mindrot.org>
-Date: Fri Oct 1 22:40:06 2021 +1000
+commit a882a09722c9f086c9edb65d0c4022fd965ec1ed
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Jan 11 01:26:47 2022 +0000
- make sk-dummy.so work without libcrypto installed
+ upstream: suppress "Connection to xxx closed" messages at LogLevel >=
+
+ error bz3378; ok dtucker@
+
+ OpenBSD-Commit-ID: d5bf457d5d2eb927b81d0663f45248a31028265c
-commit dee22129bbc61e25b1003adfa2bc584c5406ef2d
+commit 61a1a6af22e17fc94999a5d1294f27346e6c4668
Author: Damien Miller <djm@mindrot.org>
-Date: Fri Oct 1 16:35:49 2021 +1000
+Date: Wed Jan 12 08:57:49 2022 +1100
- make OPENSSL_HAS_ECC checks more thorough
+ OS X poll(2) is broken; use compat replacement
- ok dtucker
+ Darwin's poll(2) implementation is broken. For character-special
+ devices like /dev/null, it returns POLLNVAL when polled with
+ POLLIN.
+
+ Apparently this is Apple bug 3710161, which is AFAIK not public,
+ but a websearch will find other OSS projects rediscovering it
+ periodically since it was first identified in 2005 (!!)
-commit 872595572b6c9a584ed754165e8b7c4c9e7e1d61
-Author: Damien Miller <djm@mindrot.org>
-Date: Fri Oct 1 16:35:05 2021 +1000
+commit 613a6545fc5a9542753b503cbe5906538a640b60
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Tue Jan 11 20:56:01 2022 +1100
- fix FIDO key support for !OPENSSL_HAS_ECC case
-
- ok dtucker
+ libhardended_malloc.so moved into out dir.
-commit 489741dc68366940d369ac670b210b4834a6c272
-Author: Damien Miller <djm@mindrot.org>
-Date: Fri Oct 1 14:51:37 2021 +1000
+commit 61761340be5e11046556623f8f5412b236cefa95
+Author: Tim Rice <tim@multitalents.net>
+Date: Mon Jan 10 11:07:04 2022 -0800
- enable security key support for --without-openssl
+ Make USL compilers happy
+ UX:acomp: ERROR: "sftp-server.c", line 567: void function cannot return value
-commit c978565c8589acfe4ea37ab5099d39c84158c713
-Author: Damien Miller <djm@mindrot.org>
-Date: Fri Oct 1 13:27:50 2021 +1000
+commit 3ef403f351e80a59b6f7e9d43cb82c181855483c
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Jan 10 21:07:38 2022 +1100
- need stdlib.h for free(3)
+ Add wrapper for "sort" to set LC_ALL=C.
+
+ Found by djm, this should make sorts stable and reduce test flakiness.
-commit 76a398edfb51951b2d65d522d7b02c72304db300
+commit bd69e29f5716090181dbe0b8272eb7eab1a383bb
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Thu Sep 30 05:26:26 2021 +0000
+Date: Sat Jan 8 07:55:26 2022 +0000
- upstream: Fix up whitespace left by previous
-
- change removing privsep. No other changes.
+ upstream: Remove errant "set -x" left over from debugging.
- OpenBSD-Regress-ID: 87adec225d8afaee4d6a91b2b71203f52bf14b15
+ OpenBSD-Regress-ID: cd989268e034264cec5df97be7581549032c87dc
-commit ddcb53b7a7b29be65d57562302b2d5f41733e8dd
+commit 1a7c88e26fd673813dc5f61c4ac278564845e004
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Thu Sep 30 05:20:08 2021 +0000
+Date: Sat Jan 8 07:01:13 2022 +0000
- upstream: Remove references to privsep.
+ upstream: Enable all supported hostkey algorithms (but no others).
- This removes several do..while loops but does not change the
- indentation of the now-shallower loops, which will be done in a separate
- whitespace-only commit to keep changes of style and substance separate.
+ Allows hostbased test to pass when built without OpenSSL.
- OpenBSD-Regress-ID: 4bed1a0249df7b4a87c965066ce689e79472a8f7
+ OpenBSD-Regress-ID: 5ddd677a68b672517e1e78460dc6ca2ccc0a9562
-commit ece2fbe486164860de8df3f8b943cccca3085eff
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Thu Sep 30 04:22:50 2021 +0000
+commit 12b457c2a42ff271e7967d9bedd068cebb048db9
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Jan 8 07:37:32 2022 +0000
- upstream: Use "skip" instead of "fatal"
+ upstream: use status error message to communicate ~user expansion
- if SUDO isn't set for the *-command tests. This means running "make tests"
- without SUDO set will perform all of the tests that it can instead of
- failing on the ones it cannot run.
+ failures; provides better experience for scp in sftp mode, where ~user paths
+ are more likely to be used; spotted jsg, feedback jsg & deraadt ok jsg &
+ markus
- OpenBSD-Regress-ID: bd4dbbb02f34b2e8c890558ad4a696248def763a
+ OpenBSD-Commit-ID: fc610ce00ca0cdc2ecdabbd49ce7cb82033f905f
-commit bb754b470c360e787a99fb4e88e2668198e97b41
+commit 63670d4e9030bcee490d5a9cce561373ac5b3b23
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Oct 1 04:50:36 2021 +0000
+Date: Sat Jan 8 07:36:11 2022 +0000
- upstream: unbreak FIDO sk-ed25519 key enrollment for OPENSSL=no builds;
+ upstream: fix some corner-case bugs in scp sftp-mode handling of
- ok dtucker@
+ ~-prefixed paths; spotted by jsg; feedback jsg & deraadt, ok jsg & markus
- OpenBSD-Commit-ID: 6323a5241728626cbb2bf0452cf6a5bcbd7ff709
-
-commit 207648d7a6415dc915260ca75850404dbf9f0a0b
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Sep 29 20:03:58 2021 +1000
+ OpenBSD-Commit-ID: d1697dbaaa9f0f5649d69be897eab25c7d37c222
- Include stdlib.h for arc4random_uniform prototype.
-
-commit 696aadc854582c164d5fc04933d2f3e212dc0e06
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Sep 29 20:00:30 2021 +1000
-
- Look for clang after cc and gcc.
-
-commit a3c6375555026d85dbf811fab566b9f76f196144
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Sep 29 19:30:59 2021 +1000
-
- Use backticks instead of $(..) for portability.
-
- Older shells (eg /bin/sh on Solaris 10) don't support $() syntax.
-
-commit 958aaa0387133d51f84fe9c8f30bca03025f2867
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Sep 29 18:53:32 2021 +1000
-
- Skip file-based tests by default on Mac OS.
-
- The file-based tests need OpenSSL so skip them.
-
-commit 55c8bdf6e9afb0f9fa8e4f10c25c7f0081b48fd0
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Sep 29 18:42:47 2021 +1000
-
- Build without OpenSSL on Mac OS.
-
- Modern versions don't ship enough libcrypto to build against.
-
-commit c9172193ea975415facf0afb356d87df21535f88
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Sep 29 18:33:38 2021 +1000
+commit e14940bbec57fc7d3ce0644dbefa35f5a8ec97d0
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Jan 8 07:34:57 2022 +0000
- Remove TEST_SSH_ECC.
+ upstream: more idiomatic error messages; spotted by jsg & deraadt
- Convert the only remaining user of it to runtime detection using ssh -Q.
-
-commit 5e6d28b7874b0deae95d2c68947c45212d32e599
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Sep 29 17:48:09 2021 +1000
-
- Split c89 test openssl setting out.
-
-commit c4ac7f98e230e83c015678dc958b1ffe828564ad
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Sep 29 17:40:50 2021 +1000
-
- Expand TEST_SHELL consistently with other vars.
-
-commit cfe5f7b0eb7621bfb0a756222de0431315c2ab8b
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Sep 29 17:26:50 2021 +1000
-
- Replace `pwd` with make variable in regress cmd.
-
-commit 899be59da5fbc3372444bd0fbe74af48313bed33
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Sep 29 17:14:33 2021 +1000
-
- Get BUILDDIR from autoconf.
+ ok jsg & markus
- Use this to replace `pwd`s in regress test command line.
-
-commit c8d92d3d4f7d560146f2f936156ec4dac3fc5811
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Sep 29 13:28:56 2021 +1000
-
- Add make clean step to tests.
-
-commit 360fb41ef8359619ab90b0d131c914494e55d3dd
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Sep 29 11:36:13 2021 +1000
-
- Test all available clang and gcc versions.
+ OpenBSD-Commit-ID: 43618c692f3951747b4151c477c7df22afe2bcc8
-commit 4fb49899d7da22952d35a4bc4c9bdb2311087893
+commit 9acddcd5918c623f7ebf454520ffe946a8f15e90
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Sep 29 01:32:21 2021 +0000
+Date: Sat Jan 8 07:33:54 2022 +0000
- upstream: Test certificate hostkeys held in ssh-agent too. Would have
-
- caught regression fixed in sshd r1.575
+ upstream: add a variant of send_status() that allows overriding the
- ok markus@
+ default, generic error message. feedback/ok markus & jsg
- OpenBSD-Regress-ID: 1f164d7bd89f83762db823eec4ddf2d2556145ed
+ OpenBSD-Commit-ID: 81f251e975d759994131b717ee7c0b439659c40f
-commit ce4854e12e749a05646e5775e9deb8cfaf49a755
+commit 961411337719d4cd78f1ab33e4ac549f3fa22f50
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Sep 29 01:33:32 2021 +0000
+Date: Sat Jan 8 07:32:45 2022 +0000
- upstream: add some debug output showing how many key file/command lines
+ upstream: refactor tilde_expand_filename() and make it handle ~user
- were processed. Useful to see whether a file or command actually has keys
- present
+ paths with no trailing slash; feedback/ok markus and jsg
- OpenBSD-Commit-ID: 0bd9ff94e84e03a22df8e6c12f6074a95d27f23c
+ OpenBSD-Commit-ID: a2ab365598a902f0f14ba6a4f8fb2d07a9b5d51d
-commit 15abdd523501c349b703d9a27e2bb4252ad921ef
+commit dc38236ab6827dec575064cac65c8e7035768773
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Tue Sep 28 11:14:50 2021 +0000
+Date: Thu Jan 6 22:14:25 2022 +0000
- upstream: Make prototype for rijndaelEncrypt match function
+ upstream: Don't explicitly set HostbasedAuthentication in
- including the bounds. Fixes error in portable where GCC>=11 takes notice of
- the bounds. ok deraadt@
+ sshd_config. It defaults to "no", and not explicitly setting it allows us to
+ enable it for the (optional) hostbased test.
- OpenBSD-Commit-ID: cdd2f05fd1549e1786a70871e513cf9e9cf099a6
+ OpenBSD-Regress-ID: aa8e3548eb5793721641d26e56c29f363b767c0c
-commit d1d29ea1d1ef1a1a54b209f062ec1dcc8399cf03
+commit e12d912ddf1c873cb72e5de9a197afbe0b6622d2
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Tue Sep 28 11:10:05 2021 +0000
+Date: Thu Jan 6 21:46:56 2022 +0000
- upstream: Import regenerated moduli.
+ upstream: Add test for hostbased auth. It requires some external
- OpenBSD-Commit-ID: 4bec5db13b736b64b06a0fca704cbecc2874c8e1
-
-commit 39f2111b1d5f00206446257377dcce58cc72369f
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Sep 29 10:53:55 2021 +1000
-
- Add new compiler hardening flags.
+ setup (see comments at the top) and thus is disabled unless
+ TEST_SSH_HOSTBASED_AUTH and SUDO are set.
- Add -fzero-call-used-regs and -ftrivial-auto-var-init to the list of
- compiler hardening flags that configure checks for. These are supported
- by clang and gcc, and make ROP gadgets less useful and mitigate
- stack-based infoleaks respectively. ok djm@
+ OpenBSD-Regress-ID: 3ec8ba3750c5b595fc63e7845d13483065a4827a
-commit bf944e3794eff5413f2df1ef37cddf96918c6bde
+commit a48533a8da6a0f4f05ecd055dc8048047e53569e
Author: Damien Miller <djm@mindrot.org>
-Date: Mon Sep 27 00:03:19 2021 +1000
+Date: Fri Jan 7 09:24:26 2022 +1100
- initgroups needs grp.h
+ depend
-commit 8c5b5655149bd76ea21026d7fe73ab387dbc3bc7
+commit d9dbb5d9a0326e252d3c7bc13beb9c2434f59409
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Sep 26 14:01:11 2021 +0000
+Date: Thu Jan 6 22:06:51 2022 +0000
- upstream: openssh-8.8
+ upstream: allow hostbased auth to select RSA keys when only
- OpenBSD-Commit-ID: 12357794602ac979eb7312a1fb190c453f492ec4
+ RSA/SHA2 are configured (this is the default case); ok markus@
+
+ OpenBSD-Commit-ID: 411c18c7bde40c60cc6dfb7017968577b4d4a827
-commit f3cbe43e28fe71427d41cfe3a17125b972710455
+commit fdb1d58d0d3888b042e5a500f6ce524486aaf782
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Sep 26 14:01:03 2021 +0000
+Date: Thu Jan 6 22:05:42 2022 +0000
- upstream: need initgroups() before setresgid(); reported by anton@,
+ upstream: add a helper function to match a key type to a list of
- ok deraadt@
+ signature algorithms. RSA keys can make signatures with multiple algorithms,
+ so some special handling is required. ok markus@
- OpenBSD-Commit-ID: 6aa003ee658b316960d94078f2a16edbc25087ce
-
-commit 8acaff41f7518be40774c626334157b1b1c5583c
-Author: Damien Miller <djm@mindrot.org>
-Date: Sun Sep 26 22:16:36 2021 +1000
-
- update version numbers for release
+ OpenBSD-Commit-ID: 03b41b2bda06fa4cd9c84cef6095033b9e49b6ff
-commit d39039ddc0010baa91c70a0fa0753a2699bbf435
-Author: kn@openbsd.org <kn@openbsd.org>
-Date: Sat Sep 25 09:40:33 2021 +0000
+commit 11e8c4309a5086a45fbbbc87d0af5323c6152914
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Jan 6 22:04:20 2022 +0000
- upstream: RSA/SHA-1 is not used by default anymore
+ upstream: log some details on hostkeys that ssh loads for
- OK dtucker deraadt djm
+ hostbased authn ok markus@
- OpenBSD-Commit-ID: 055c51a221c3f099dd75c95362f902da1b8678c6
+ OpenBSD-Commit-ID: da17061fa1f0e58cb31b88478a40643e18233e38
-commit 9b2ee74e3aa8c461eb5552a6ebf260449bb06f7e
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Sep 24 11:08:03 2021 +1000
+commit c6706f661739514a34125aa3136532a958929510
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Jan 6 22:03:59 2022 +0000
- Move the fgrep replacement to hostkey-rotate.sh.
+ upstream: log signature algorithm during verification by monitor;
- The fgrep replacement for buggy greps doesn't work in the sftp-glob test
- so move it to just where we know it's needed.
-
-commit f7039541570d4b66d76e6f574544db176d8d5c02
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Sep 24 08:04:14 2021 +1000
-
- Replacement function for buggy fgrep.
+ ok markus
- GNU (f)grep <=2.18, as shipped by FreeBSD<=12 and NetBSD<=9 will
- occasionally fail to find ssh host keys in the hostkey-rotate test.
- If we have those versions, use awk instead.
-
-commit f6a660e5bf28a01962af87568e118a2d2e79eaa0
-Author: David Manouchehri <david.manouchehri@riseup.net>
-Date: Thu Sep 23 17:03:18 2021 -0400
-
- Don't prompt for yes/no questions.
+ OpenBSD-Commit-ID: 02b92bb42c4d4bf05a051702a56eb915151d9ecc
-commit 7ed1a3117c09f8c3f1add35aad77d3ebe1b85b4d
+commit 8832402bd500d1661ccc80a476fd563335ef6cdc
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Sep 20 06:53:56 2021 +0000
+Date: Thu Jan 6 22:02:52 2022 +0000
- upstream: fix missing -s in SYNOPSYS and usage() as well as a
+ upstream: piece of UpdateHostkeys client strictification: when
- capitalisation mistake; spotted by jmc@
+ updating known_hosts with new keys, ignore NULL keys (forgot to include in
+ prior commit)
- OpenBSD-Commit-ID: 0ed8ee085c7503c60578941d8b45f3a61d4c9710
+ OpenBSD-Commit-ID: 49d2eda6379490e1ceec40c3b670b973f63dea08
-commit 8c07170135dde82a26886b600a8bf6fb290b633d
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Mon Sep 20 04:02:13 2021 +0000
+commit c2d9ced1da0276961d86690b3bd7ebdaca7fdbf7
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Jan 6 22:01:14 2022 +0000
- upstream: Fix "Allocated port" debug message
+ upstream: include rejected signature algorithm in error message
- for unix domain sockets. From peder.stray at gmail.com via github PR#272,
- ok deraadt@
+ and not the (useless) key type; ok markus
- OpenBSD-Commit-ID: 8d5ef3fbdcdd29ebb0792b5022a4942db03f017e
+ OpenBSD-Commit-ID: 4180b5ec7ab347b43f84e00b1972515296dab023
-commit 277d3c6adfb128b4129db08e3d65195d94b55fe7
+commit 7aa7b096cf2bafe2777085abdeed5ce00581f641
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Sep 20 01:55:42 2021 +0000
+Date: Thu Jan 6 22:00:18 2022 +0000
- upstream: Switch scp back to use the old protocol by default, ahead of
+ upstream: make ssh-keysign use the requested signature algorithm
- release. We'll wait a little longer for people to pick up sftp-server(8) that
- supports the extension that scp needs for ~user paths to continue working in
- SFTP protocol mode. Discussed with deraadt@
+ and not the default for the keytype. Part of unbreaking hostbased auth for
+ RSA/SHA2 keys. ok markus@
- OpenBSD-Commit-ID: f281f603a705fba317ff076e7b11bcf2df941871
+ OpenBSD-Commit-ID: b5639a14462948970da3a8020dc06f9a80ecccdc
-commit ace19b34cc15bea3482be90450c1ed0cd0dd0669
+commit 291721bc7c840d113a49518f3fca70e86248b8e8
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Sep 18 02:03:25 2021 +0000
+Date: Thu Jan 6 21:57:28 2022 +0000
- upstream: better error message for ~user failures when the
+ upstream: stricter UpdateHostkey signature verification logic on
- sftp-server lacks the expand-path extension; ok deraadt@
+ the client- side. Require RSA/SHA2 signatures for RSA hostkeys except when
+ RSA/SHA1 was explicitly negotiated during initial KEX; bz3375
- OpenBSD-Commit-ID: 9c1d965d389411f7e86f0a445158bf09b8f9e4bc
+ ok markus@
+
+ OpenBSD-Commit-ID: 46e75e8dfa2c813781805b842580dcfbd888cf29
-commit 6b1238ba971ee722a310d95037b498ede5539c03
+commit 0fa33683223c76289470a954404047bc762be84c
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Sep 16 15:22:22 2021 +0000
+Date: Thu Jan 6 21:55:23 2022 +0000
- upstream: make some more scp-in-SFTP mode better match Unix idioms
-
- suggested by deraadt@
+ upstream: Fix signature algorithm selection logic for
- OpenBSD-Commit-ID: 0f2439404ed4cf0b0be8bf49a1ee734836e1ac87
-
-commit e694f8ac4409931e67d08ac44ed251b20b10a957
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Sep 16 15:11:19 2021 +0000
-
- upstream: allow log_stderr==2 to prefix log messages with argv[0]
+ UpdateHostkeys on the server side. The previous code tried to prefer RSA/SHA2
+ for hostkey proofs of RSA keys, but missed some cases. This will use RSA/SHA2
+ signatures for RSA keys if the client proposed these algorithms in initial
+ KEX. bz3375
- use this to make scp's SFTP mode error messages more scp-like
+ Mostly by Dmitry Belyavskiy with some tweaks by me.
- prompted by and ok deraadt@
+ ok markus@
- OpenBSD-Commit-ID: 0e821dbde423fc2280e47414bdc22aaa5b4e0733
-
-commit 8a7a06ee505cb833e613f74a07392e9296286c30
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Sep 17 13:03:31 2021 +1000
-
- Test against LibreSSL 3.2.6, 3.3.4, 3.4.0.
+ OpenBSD-Commit-ID: c17ba0c3236340d2c6a248158ebed042ac6a8029
-commit c25c84074a47f700dd6534995b4af4b456927150
+commit 17877bc81db3846e6e7d4cfb124d966bb9c9296b
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Sep 16 05:36:03 2021 +0000
+Date: Thu Jan 6 21:48:38 2022 +0000
- upstream: missing space character in ssh -G output broke the
+ upstream: convert ssh, sshd mainloops from select() to poll();
- t-sshcfgparse regression test; spotted by anton@
+ feedback & ok deraadt@ and markus@ has been in snaps for a few months
- OpenBSD-Commit-ID: bcc36fae2f233caac4baa8e58482da4aa350eed0
+ OpenBSD-Commit-ID: a77e16a667d5b194dcdb3b76308b8bba7fa7239c
-commit a4bee1934bf5e5575fea486628f4123d6a29dff8
+commit 5c79952dfe1aa36105c93b3f383ce9be04dee384
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Sep 15 06:56:01 2021 +0000
+Date: Thu Jan 6 21:46:23 2022 +0000
- upstream: allow CanonicalizePermittedCNAMEs=none in ssh_config; ok
+ upstream: prepare for conversion of ssh, sshd mainloop from
- markus@
+ select() to poll() by moving FD_SET construction out of channel handlers into
+ separate functions. ok markus
- OpenBSD-Commit-ID: 668a82ba8e56d731b26ffc5703213bfe071df623
+ OpenBSD-Commit-ID: 937fbf2a4de12b19fb9d5168424e206124807027
-commit d0fffc88c8fe90c1815c6f4097bc8cbcabc0f3dd
-Author: mbuhl@openbsd.org <mbuhl@openbsd.org>
-Date: Tue Sep 14 11:04:21 2021 +0000
+commit 24c5187edfef4651a625b7d5d692c8c7e794f71f
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Jan 5 21:54:37 2022 +0000
- upstream: put back the mux_ctx memleak fix for SSH_CHANNEL_MUX_CLIENT
-
- OK mfriedl@
+ upstream: add a comment so I don't make this mistake again
- OpenBSD-Commit-ID: 1aba1da828956cacaadb81a637338734697d9798
+ OpenBSD-Commit-ID: 69c7f2362f9de913bb29b6318580c5a1b52c921e
-commit 19b3d846f06697c85957ab79a63454f57f8e22d6
-Author: schwarze@openbsd.org <schwarze@openbsd.org>
-Date: Sat Sep 11 09:05:50 2021 +0000
+commit 7369900441929058263a17f56aa67e05ff7ec628
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Jan 5 21:50:00 2022 +0000
- upstream: Do not ignore SIGINT while waiting for input if editline(3)
-
- is not used. Instead, in non-interactive mode, exit sftp(1), like for other
- serious errors. As pointed out by dtucker@, when compiled without editline(3)
- support in portable OpenSSH, the el == NULL branch is also used for
- interactive mode. In that case, discard the input line and provide a fresh
- prompt to the user just like in the case where editline(3) is used. OK djm@
+ upstream: fix cut-and-pasto in error message
- OpenBSD-Commit-ID: 7d06f4d3ebba62115527fafacf38370d09dfb393
+ OpenBSD-Commit-ID: 4cc5c619e4b456cd2e9bb760d17e3a9c84659198
-commit ba61123eef9c6356d438c90c1199a57a0d7bcb0a
+commit 294c11b1c7d56d3fb61e329603a782315ed70c62
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Sep 11 00:40:24 2021 +0000
+Date: Wed Jan 5 08:25:05 2022 +0000
- upstream: when using SFTP protocol, continue transferring files after a
+ upstream: select all RSA hostkey algorithms for UpdateHostkeys tests,
- transfer error occurs. This matches original scp/rcp behaviour. ok dtucker@
+ not just RSA-SHA1
- OpenBSD-Commit-ID: dfe4558d71dd09707e9b5d6e7d2e53b793da69fa
+ OpenBSD-Regress-ID: b40e62b65863f2702a0c10aca583b2fe76772bd8
-commit b0ec59a708b493c6f3940336b1a537bcb64dd2a7
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Sep 10 11:38:38 2021 +0000
+commit 2ea1108c30e3edb6f872dfc1e6da10b041ddf2c0
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Jan 5 04:56:15 2022 +0000
- upstream: Document that non-interactive commands are run via the user's
+ upstream: regress test both sshsig message hash algorithms, possible
- shell using the -c flag. ok jmc@
+ now because the algorithm is controllable via the CLI
- OpenBSD-Commit-ID: 4f0d912077732eead10423afd1acf4fc0ceec477
+ OpenBSD-Regress-ID: 0196fa87acc3544b2b4fd98de844a571cb09a39f
-commit 66a658b5d9e009ea11f8a0ca6e69c7feb2d851ea
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Sep 10 10:26:02 2021 +0000
+commit 2327c306b5d4a2b7e71178e5a4d139af9902c2b0
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Jan 5 04:50:11 2022 +0000
- upstream: Document behaviour of arguments following non-interactive
+ upstream: allow selection of hash at sshsig signing time; code
- commands. Prompted by github PR#139 from EvanTheB, feedback & ok djm@ jmc@
+ already supported either sha512 (default) or sha256, but plumbing wasn't
+ there mostly by Linus Nordberg
- OpenBSD-Commit-ID: fc758d1fe0471dfab4304fcad6cd4ecc3d79162a
+ OpenBSD-Commit-ID: 1b536404b9da74a84b3a1c8d0b05fd564cdc96cd
-commit 1d47e28e407d1f95fdf8f799be23f48dcfa5206b
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Sep 10 07:11:11 2021 +0000
+commit 56e941d0a00d6d8bae88317717d5e1b7395c9529
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Jan 5 04:27:54 2022 +0000
- upstream: Clarify which file's attributes -p preserves, and that
+ upstream: add missing -O option to usage() for ssh-keygen -Y sign;
- it's specifically the file mode bits. bz#3340 from calestyo at scientia.net,
- ok djm@ jmc@
+ from Linus Nordberg
- OpenBSD-Commit-ID: f09e6098ed1c4be00c730873049825f8ee7cb884
+ OpenBSD-Commit-ID: 4e78feb4aa830727ab76bb2e3d940440ae1d7af0
-commit b344db7a413478e4c21e4cadba4a970ad3e6128a
+commit 141a14ec9b0924709c98df2dd8013bde5d8d12c7
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Sep 10 05:46:09 2021 +0000
+Date: Wed Jan 5 04:27:01 2022 +0000
- upstream: openssh-7.4 was incorrectly listed twice; spotted by
+ upstream: move sig_process_opts() to before sig_sign(); no
- Dmitry Belyavskiy, ok dtucker@
+ functional code change
- OpenBSD-Commit-ID: 4b823ae448f6e899927ce7b04225ac9e489f58ef
+ OpenBSD-Commit-ID: da02d61f5464f72b4e8b299f83e93c3b657932f9
-commit 9136d6239ad7a4a293e0418a49b69e70c76d58b8
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Thu Sep 9 06:17:39 2021 +0000
+commit 37a14249ec993599a9051731e4fb0ac5e976aec1
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Jan 5 04:10:39 2022 +0000
- upstream: - move CAVEATS to its correct order - use the term
-
- "legacy" protocol rather than "original", as the latter made the text
- misleading - uppercase SCP
-
- ok djm
+ upstream: regression test for find-principals NULL deref; from Fabian
- OpenBSD-Commit-ID: 8479255746d5fa76a358ee59e7340fecf4245ff0
-
-commit 2d678c5e3bdc2f5c99f7af5122e9d054925d560d
-Author: David Carlier <devnexen@gmail.com>
-Date: Wed Sep 8 19:49:54 2021 +0100
-
- Disable tracing on FreeBSD using procctl.
+ Stelzer
- Placed at the start of platform_disable_tracing() to prevent declaration
- after code errors from strict C89 compilers (in the unlikely event that
- more than one method is enabled).
+ OpenBSD-Regress-ID: f845a8632a5a7d5ae26978004c93e796270fd3e5
-commit 73050fa38fb36ae3326d768b574806352b97002d
+commit eb1f042142fdaba93f6c9560cf6c91ae25f6884a
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Sep 8 23:31:39 2021 +0000
+Date: Wed Jan 5 04:02:42 2022 +0000
- upstream: Use the SFTP protocol by default. The original scp/rcp
+ upstream: NULL deref when using find-principals when matching an
- protocol remains available via the -O flag.
+ allowed_signers line that contains a namespace restriction, but no
+ restriction specified on the command-line; report and fix from Fabian Stelzer
- Note that ~user/ prefixed paths in SFTP mode require a protocol extension
- that was first shipped in OpenSSH 8.7.
+ OpenBSD-Commit-ID: 4a201b86afb668c908d1a559c6af456a61f4b145
+
+commit 8f3b18030579f395eca2181da31a5f945af12a59
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Tue Jan 4 08:38:53 2022 +0000
+
+ upstream: Log command invocation while debugging.
- ok deraadt, after baking in snaps for a while without incident
+ This will aid in manually reproducing failing commands.
- OpenBSD-Commit-ID: 23588976e28c281ff5988da0848cb821fec9213c
+ OpenBSD-Regress-ID: b4aba8d5ac5675ceebeeeefa3261ce344e67333a
-commit c4565e69ffa2485cff715aa842ea7a350296bfb6
+commit bbf285164df535f0d38c36237f007551bbdae27f
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Sep 8 21:09:49 2021 +1000
+Date: Sun Dec 26 10:31:15 2021 +1100
- Really fix test on OpenSSL 1.1.1 stable.
+ Always save config.h as build artifact.
+
+ Should allow better comparison between failing and succeeding test
+ platforms.
-commit 79f1bb5f56cef3ae9276207316345b8309248478
+commit 03bd4ed0db699687c5cd83405d26f81d2dc28d22
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Sep 8 18:51:39 2021 +1000
+Date: Sat Dec 25 16:42:51 2021 +1100
- Correct OpenSSL 1.1.1 stable identifier.
+ Add OpenBSD 7.0 target. Retire 6.8.
-commit b6255593ed5ccbe5e7d3d4b26b2ad31ad4afc232
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Sep 8 18:39:44 2021 +1000
+commit c45a752f0de611afd87755c2887c8a24816d08ee
+Author: jsg@openbsd.org <jsg@openbsd.org>
+Date: Sat Jan 1 05:55:06 2022 +0000
- Increment nfds when coming from startup_pipe.
+ upstream: spelling
- If we have to increase nfds because startup_pipe[0] is above any of the
- descriptors passed in the fd_sets, we also need to add 1 to nfds since
- select takes highest FD number plus one. bz#3345 from yaroslav.kuzmin
- at vmssoftware.com.
-
-commit a3e92a6794817df6012ac8546aea19652cc91b61
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Sep 8 13:45:10 2021 +1000
-
- Tests for OpenSSL 3.0.0 release & 1.1.1 branch.
+ OpenBSD-Commit-ID: c63e43087a64d0727af13409c708938e05147b62
-commit 4afe431da98ec1cf6a2933fe5658f4fd68dee9e2
+commit c672f83a89a756564db0d3af9934ba0e1cf8fa3e
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Sep 8 03:23:44 2021 +0000
+Date: Tue Jan 4 07:20:33 2022 +0000
- upstream: correct my mistake in previous fix; spotted by halex
+ upstream: unbreak test: was picking up system ssh-add instead of the
- OpenBSD-Commit-ID: 3cc62d92e3f70006bf02468fc146bfc36fffa183
+ one supposedly being tested. Spotted by dtucker and using his VM zoo (which
+ includes some systems old enough to lack ed25519 key support)
+
+ OpenBSD-Regress-ID: 7976eb3df11cc2ca3af91030a6a8c0cef1590bb5
-commit ca0e455b9331213ff9505a21b94c38e34faa2bba
+commit a23698c3082ffe661abed14b020eac9b0c25eb9f
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Sep 7 06:03:51 2021 +0000
+Date: Sat Jan 1 04:18:06 2022 +0000
- upstream: avoid NULL deref in -Y find-principals. Report and fix
-
- from Carlo Marcelo Arenas Belón
- MIME-Version: 1.0
- Content-Type: text/plain; charset=UTF-8
- Content-Transfer-Encoding: 8bit
+ upstream: fix memleak in process_extension(); oss-fuzz issue #42719
- OpenBSD-Commit-ID: 6238486f8ecc888d6ccafcd9ad99e621bb41f1e0
+ OpenBSD-Commit-ID: d8d49f840162fb7b8949e3a5adb8107444b6de1e
-commit 37616807f150fb46610bbd5031c31af4857ad1e9
-Author: millert@openbsd.org <millert@openbsd.org>
-Date: Mon Sep 6 00:36:01 2021 +0000
+commit cb885178f36b83d0f14cfe9f345d2068103feed0
+Author: jsg@openbsd.org <jsg@openbsd.org>
+Date: Sat Jan 1 01:55:30 2022 +0000
- upstream: revision 1.381 neglected to remove
-
- sChallengeResponseAuthentication from the enum. Noticed by
- christos@zoulas.com. OK dtucker@
+ upstream: spelling ok dtucker@
- OpenBSD-Commit-ID: b533283a4dd6d04a867da411a4c7a8fbc90e34ff
+ OpenBSD-Commit-ID: bfc7ba74c22c928de2e257328b3f1274a3dfdf19
-commit 7acb3578cdfec0b3d34501408071f7a96c1684ea
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sun Sep 5 20:45:42 2021 +1000
+commit 6b977f8080a32c5b3cbb9edb634b9d5789fb79be
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sun Dec 26 23:34:41 2021 +0000
- Correct version_num for OpenSSL dev branch.
+ upstream: split method list search functionality from
+
+ authmethod_lookup() into a separate authmethod_byname(), for cases where we
+ don't need to check whether a method is enabled, etc.
+
+ use this to fix the "none" authentication method regression reported
+ by Nam Nguyen via bugs@
+
+ ok deraadt@
+
+ OpenBSD-Commit-ID: 8cd188dc3a83aa8abe5b7693e762975cd8ea8a17
-commit 65bb01111320dfd0d25e21e1fd4d3f2b77532669
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sun Sep 5 19:37:39 2021 +1000
+commit 0074aa2c8d605ee7587279a22cdad4270b4ddd07
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Wed Dec 22 06:56:41 2021 +0000
- Test against OpenSSL 3 branch as well as dev.
+ upstream: sort -H and -h in SYNOPSIS/usage(); tweak the -H text;
- Now that OpenSSL development has moved to 3.1, test against the most
- recent version of the openssl-3.0 branch too.
+ ok djm
+
+ OpenBSD-Commit-ID: 90721643e41e9e09deb5b776aaa0443456ab0965
-commit 864ed0d5e04a503b97202c776b7cf3f163f3eeaa
+commit 1c9853a68b2319f2e5f929179735e8fbb9988a67
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sun Sep 5 19:33:22 2021 +1000
-
- OpenSSL development is now 3.1.*
-
-commit a60209a586a928f92ab323bf23bd07f57093342e
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Sep 3 07:43:23 2021 +0000
+Date: Wed Dec 22 19:33:10 2021 +1100
- upstream: Use .Cm instead of .Dq in StrictHostKeyChecking list for
-
- consistency. Patch from scop via github PR#257, ok jmc@
+ Use SHA.*_HMAC_BLOCK_SIZE if needed.
- OpenBSD-Commit-ID: 3652a91564570779431802c31224fb4a9cf39872
+ If the platform has a native SHA2, does not define SHA.*_BLOCK_LENGTH
+ but does define SHA.*_HMAC_BLOCK_SIZE (eg Solaris) then use the latter.
+ Should fix --without-openssl build on Solaris.
-commit 8d1d9eb6de37331e872700e9e399a3190cca1242
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Sep 3 07:27:03 2021 +0000
+commit 715c892f0a5295b391ae92c26ef4d6a86ea96e8e
+Author: Damien Miller <djm@mindrot.org>
+Date: Wed Dec 22 09:02:50 2021 +1100
- upstream: Mention using ssh -i for specifying the public key file
-
- in the case where the private key is loaded into ssh-agent but is not present
- locally. Based on patch from rafork via github PR#215, ok jmc@
-
- OpenBSD-Commit-ID: 2282e83b0ff78d2efbe705883b67240745fa5bb2
+ remove sys/param.h in -portable, after upstream
-commit eb4362e5e3aa7ac26138b11e44d8c191910aff64
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Sep 3 05:25:50 2021 +0000
+commit 7a7c69d8b4022b1e5c0afb169c416af8ce70f3e8
+Author: Damien Miller <djm@mindrot.org>
+Date: Mon Dec 20 13:05:20 2021 +1100
- upstream: Refer to KEX "algorithms" instead of "methods" to match
-
- other references and improve consistency. Patch from scop via github PR#241,
- ok djm@
-
- OpenBSD-Commit-ID: 840bc94ff6861b28d8603c8e8c16499bfb65e32c
+ add agent-restrict.sh file, missed in last commit
-commit b3318946ce5725da43c4bf7eeea1b73129c47d2a
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Sep 3 05:12:25 2021 +0000
+commit f539136ca51a4976644db5d0be8158cc1914c72a
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sun Dec 19 22:20:12 2021 +0000
- upstream: Remove redundant attrib_clear in upload_dir_internal.
-
- The subsequent call to stat_to_attrib clears the struct as its first step
- anyway. From pmeinhardt via github PR#220, ok djm@
+ upstream: regression test for destination restrictions in ssh-agent
- OpenBSD-Commit-ID: f5234fc6d7425b607e179acb3383f21716f3029e
+ OpenBSD-Regress-ID: 3c799d91e736b1753b4a42d80c42fc40de5ad33d
-commit 7cc3fe28896e653956a6a2eed0a25d551b83a029
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Sep 3 04:11:13 2021 +0000
+commit 6e4980eb8ef94c04874a79dd380c3f568e8416d6
+Author: anton@openbsd.org <anton@openbsd.org>
+Date: Sat Dec 18 06:53:59 2021 +0000
- upstream: Add test for client termination status on signal.
-
- Based on patch from Alexxz via github PR#235 with some tweaks, to
- match patch in bz#3281.
+ upstream: Make use of ntests variable, pointed out by clang 13.
- OpenBSD-Regress-ID: d87c7446fb8b5f8b45894fbbd6875df326e729e2
+ OpenBSD-Regress-ID: 4241a3d21bdfa1630ed429b6d4fee51038d1be72
-commit 5428b0d239f6b516c81d1dd15aa9fe9e60af75d4
+commit 3eead8158393b697f663ec4301e3c7b6f24580b1
Author: deraadt@openbsd.org <deraadt@openbsd.org>
-Date: Thu Sep 2 21:03:54 2021 +0000
+Date: Tue Dec 14 21:25:27 2021 +0000
- upstream: sys/param.h is not needed for any visible reason
+ upstream: sys/param.h cleanup, mostly using MINIMUM() and
- OpenBSD-Commit-ID: 8bdea2d0c75692e4c5777670ac039d4b01c1f368
+ <limits.h> ok dtucker
+
+ OpenBSD-Regress-ID: 172a4c45d3bcf92fa6cdf6c4b9db3f1b3abe4db0
-commit 1ff38f34b4c4545eb28106629cafa1e0496bc726
-Author: Shchelkunov Artem <a.shchelkunov@ideco.ru>
-Date: Wed Aug 11 18:07:58 2021 +0500
+commit 266678e19eb0e86fdf865b431b6e172e7a95bf48
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sun Dec 19 22:15:42 2021 +0000
- Fix memory leak in error path.
+ upstream: document host-bound publickey authentication
- *info is allocated via xstrdup but was leaked in the PAM_AUTH_ERR path.
- From github PR#266.
+ OpenBSD-Commit-ID: ea6ed91779a81f06d961e30ecc49316b3d71961b
-commit cb37e2f0c0ca4fef844ed7edc5d0e3b7d0e83f6a
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Wed Sep 1 03:16:06 2021 +0000
+commit 3d00024b3b156aa9bbd05d105f1deb9cb088f6f7
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sun Dec 19 22:15:21 2021 +0000
- upstream: Fix ssh-rsa fallback for old PuTTY interop tests.
+ upstream: document agent protocol extensions
- OpenBSD-Regress-ID: a19ac929da604843a5b5f0f48d2c0eb6e0773d37
+ OpenBSD-Commit-ID: 09e8bb391bbaf24c409b75a4af44e0cac65405a7
-commit 8b02ef0f28dc24cda8cbcd8b7eb02bda8f8bbe59
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Wed Sep 1 00:50:27 2021 +0000
+commit c385abf76511451bcba78568167b1cd9e90587d5
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sun Dec 19 22:14:47 2021 +0000
- upstream: Add a function to skip remaining tests.
+ upstream: PubkeyAuthentication=yes|no|unbound|host-bound
- Many tests skip tests for various reasons but not in a consistent way and
- don't always clean up, so add that and switch the tests that do that over.
+ Allow control over which pubkey methods are used. Added out of
+ concern that some hardware devices may have difficulty signing
+ the longer pubkey authentication challenges. This provides a
+ way for them to disable the extension. It's also handy for
+ testing.
- OpenBSD-Regress-ID: 72d2ec90a3ee8849486956a808811734281af735
+ feedback / ok markus@
+
+ OpenBSD-Commit-ID: ee52580db95c355cf6d563ba89974c210e603b1a
-commit d486845c07324c04240f1674ac513985bd356f66
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Tue Aug 31 07:13:59 2021 +0000
+commit 34b1e9cc7654f41cd4c5b1cc290b999dcf6579bb
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sun Dec 19 22:14:12 2021 +0000
- upstream: Specify path to PuTTY keys.
+ upstream: document destination-constrained keys
- Portable needs this and it makes no difference on OpenBSD, so resync
- them. (Id sync only, Portable already had this.)
+ feedback / ok markus@
- OpenBSD-Regress-ID: 33f6f66744455886d148527af8368811e4264162
+ OpenBSD-Commit-ID: cd8c526c77268f6d91c06adbee66b014d22d672e
-commit d22b299115e27606e846b23490746f69fdd4fb38
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Tue Aug 31 06:13:23 2021 +0000
+commit a6d7677c4abcfba268053e5867f2acabe3aa371b
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sun Dec 19 22:13:55 2021 +0000
- upstream: Better compat tests with old PuTTY.
+ upstream: Use hostkey parsed from hostbound userauth request
- When running PuTTY interop tests and using a PuTTY version older than
- 0.76, re-enable the ssh-rsa host key algorithm (the 256 and 512 variants
- of RSA were added some time between 0.73 and 0.76).
+ Require host-bound userauth requests for forwarded SSH connections.
- OpenBSD-Regress-ID: e6138d6987aa705fa1e4f216db0bb386e1ff38e1
-
-commit 87ad70d605c3e39c9b8aa275db27120d7cc09b77
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Tue Aug 31 17:04:50 2021 +1000
-
- Resync PuTTY interop tests.
+ The hostkey parsed from the host-bound userauth request is now checked
+ against the most recently bound session ID / hostkey on the agent socket
+ and the signature refused if they do not match.
- Resync behaviour when REGRESS_INTEROP_PUTTY is not set with OpenBSD.
+ ok markus@
+
+ OpenBSD-Commit-ID: d69877c9a3bd8d1189a5dbdeceefa432044dae02
-commit e47b82a7bf51021afac218bf59a3be121827653d
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Tue Aug 31 01:25:27 2021 +0000
+commit baaff0ff4357cc5a079621ba6e2d7e247b765061
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sun Dec 19 22:13:33 2021 +0000
- upstream: Specify hostkeyalgorithms in SSHFP test.
+ upstream: agent support for parsing hostkey-bound signatures
- Specify host key algorithms in sshd's default set for the SSHFP test,
- from djm@. Make the reason for when the test is skipped a bit clearer.
+ Allow parse_userauth_request() to work with blobs from
+ publickey-hostbound-v00@openssh.com userauth attempts.
- OpenBSD-Regress-ID: 4f923dfc761480d5411de17ea6f0b30de3e32cea
+ Extract hostkey from these blobs.
+
+ ok markus@
+
+ OpenBSD-Commit-ID: 81c064255634c1109477dc65c3e983581d336df8
-commit 7db3e0a9e8477c018757b59ee955f7372c0b55fb
+commit 3e16365a79cdeb2d758cf1da6051b1c5266ceed7
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Aug 30 01:15:45 2021 +0000
+Date: Sun Dec 19 22:13:12 2021 +0000
- upstream: adapt to RSA/SHA1 deprectation
+ upstream: EXT_INFO negotiation of hostbound pubkey auth
- OpenBSD-Regress-ID: 952397c39a22722880e4de9d1c50bb1a14f907bb
+ the EXT_INFO packet gets a new publickey-hostbound@openssh.com to
+ advertise the hostbound public key method.
+
+ Client side support to parse this feature flag and set the kex->flags
+ indicator if the expected version is offered (currently "0").
+
+ ok markus@
+
+ OpenBSD-Commit-ID: 4cdb2ca5017ec1ed7a9d33bda95c1d6a97b583b0
-commit 2344750250247111a6c3c6a4fe84ed583a61cc11
+commit 94ae0c6f0e35903b695e033bf4beacea1d376bb1
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Aug 29 23:53:10 2021 +0000
+Date: Sun Dec 19 22:12:54 2021 +0000
- upstream: After years of forewarning, disable the RSA/SHA-1
+ upstream: client side of host-bound pubkey authentication
- signature algorithm by default. It is feasible to create colliding SHA1
- hashes, so we need to deprecate its use.
+ Add kex->flags member to enable the publickey-hostbound-v00@openssh.com
+ authentication method.
- RSA/SHA-256/512 remains available and will be transparently selected
- instead of RSA/SHA1 for most SSH servers released in the last five+
- years. There is no need to regenerate RSA keys.
+ Use the new hostbound method in client if the kex->flags flag was set,
+ and include the inital KEX hostkey in the userauth request.
- The use of RSA/SHA1 can be re-enabled by adding "ssh-rsa" to the
- PubkeyAcceptedAlgorithms directives on the client and server.
+ Note: nothing in kex.c actually sets the new flag yet
- ok dtucker deraadt
+ ok markus@
- OpenBSD-Commit-ID: 189bcc4789c7254e09e23734bdd5def8354ff1d5
+ OpenBSD-Commit-ID: 5a6fce8c6c8a77a80ee1526dc467d91036a5910d
-commit 56c4455d3b54b7d481c77c82115c830b9c8ce328
+commit 288fd0218dbfdcb05d9fbd1885904bed9b6d42e6
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Aug 29 23:44:07 2021 +0000
+Date: Sun Dec 19 22:12:30 2021 +0000
- upstream: wrap at 80 columns
+ upstream: sshd side of hostbound public key auth
- OpenBSD-Commit-ID: 47ca2286d6b52a9747f34da16d742879e1a37bf0
-
-commit 95401eea8503943449f712e5f3de52fc0bc612c5
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Aug 20 18:14:13 2021 +1000
-
- Replace shell function with ssh-keygen -A.
+ This is identical to the standard "publickey" method, but it also includes
+ the initial server hostkey in the message signed by the client.
- Prevents the init script in the SysV package from trying (and failing)
- to generate unsupported key types. Remove now-unused COMMENT_OUT_ECC.
- ok tim@
-
-commit d83ec9ed995a76ed1d5c65cf10b447222ec86131
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Aug 20 15:39:05 2021 +1000
-
- Remove obsolete Redhat PAM config and init script.
-
-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
+ feedback / ok markus@
+
+ OpenBSD-Commit-ID: 7ea01bb7238a560c1bfb426fda0c10a8aac07862
-commit feee2384ab8d694c770b7750cfa76a512bdf8246
+commit dbb339f015c33d63484261d140c84ad875a9e548
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Aug 20 03:22:55 2021 +0000
+Date: Sun Dec 19 22:12:07 2021 +0000
- upstream: openssh-8.7
+ upstream: prepare for multiple names for authmethods
- OpenBSD-Commit-ID: 8769dff0fd76ae3193d77bf83b439adee0f300cd
+ allow authentication methods to have one additional name beyond their
+ primary name.
+
+ allow lookup by this synonym
+
+ Use primary name for authentication decisions, e.g. for
+ PermitRootLogin=publickey
+
+ Pass actual invoked name to the authmethods, so they can tell whether they
+ were requested via the their primary name or synonym.
+
+ ok markus@
+
+ OpenBSD-Commit-ID: 9e613fcb44b8168823195602ed3d09ffd7994559
-commit 9a2ed62173cc551b2b5f479460bb015b19499de8
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Aug 20 10:48:13 2021 +1000
+commit 39f00dcf44915f20684160f0a88d3ef8a3278351
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sun Dec 19 22:11:39 2021 +0000
- Also check pid in pselect_notify_setup.
+ upstream: ssh-agent side of destination constraints
- Spotted by djm@.
+ Gives ssh-agent the ability to parse restrict-destination-v00@openssh.com
+ constraints and to apply them to keys.
+
+ Check constraints against the hostkeys recorded for a SocketEntry when
+ attempting a signature, adding, listing or deleting keys. Note that
+ the "delete all keys" request will remove constrained keys regardless of
+ location.
+
+ feedback Jann Horn & markus@
+ ok markus@
+
+ OpenBSD-Commit-ID: 84a7fb81106c2d609a6ac17469436df16d196319
-commit deaadcb93ca15d4f38aa38fb340156077792ce87
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Aug 20 08:39:33 2021 +1000
+commit ce943912df812c573a33d00bf9e5435b7fcca3f7
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sun Dec 19 22:11:06 2021 +0000
- Prefix pselect functions to clarify debug messages
+ upstream: ssh-add side of destination constraints
+
+ Have ssh-add accept a list of "destination constraints" that allow
+ restricting where keys may be used in conjunction with a ssh-agent/ssh
+ that supports session ID/hostkey binding.
+
+ Constraints are specified as either "[user@]host-pattern" or
+ "host-pattern>[user@]host-pattern".
+
+ The first form permits a key to be used to authenticate as the
+ specified user to the specified host.
+
+ The second form permits a key that has previously been permitted
+ for use at a host to be available via a forwarded agent to an
+ additional host.
+
+ For example, constraining a key with "user1@host_a" and
+ "host_a>host_b". Would permit authentication as "user1" at
+ "host_a", and allow the key to be available on an agent forwarded
+ to "host_a" only for authentication to "host_b". The key would not
+ be visible on agent forwarded to other hosts or usable for
+ authentication there.
+
+ Internally, destination constraints use host keys to identify hosts.
+ The host patterns are used to obtain lists of host keys for that
+ destination that are communicated to the agent. The user/hostkeys are
+ encoded using a new restrict-destination-v00@openssh.com key
+ constraint.
+
+ host keys are looked up in the default client user/system known_hosts
+ files. It is possible to override this set on the command-line.
+
+ feedback Jann Horn & markus@
+ ok markus@
+
+ OpenBSD-Commit-ID: 6b52cd2b637f3d29ef543f0ce532a2bce6d86af5
-commit 10e45654cff221ca60fd35ee069df67208fcf415
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Aug 20 08:30:42 2021 +1000
+commit 5e950d765727ee0b20fc3d2cbb0c790b21ac2425
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sun Dec 19 22:10:24 2021 +0000
- Fix race in pselect replacement code.
+ upstream: ssh-add side of destination constraints
- 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.
+ Have ssh-add accept a list of "destination constraints" that allow
+ restricting where keys may be used in conjunction with a ssh-agent/ssh
+ that supports session ID/hostkey binding.
- 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.
+ Constraints are specified as either "[user@]host-pattern" or
+ "host-pattern>[user@]host-pattern".
+
+ The first form permits a key to be used to authenticate as the
+ specified user to the specified host.
+
+ The second form permits a key that has previously been permitted
+ for use at a host to be available via a forwarded agent to an
+ additional host.
+
+ For example, constraining a key with "user1@host_a" and
+ "host_a>host_b". Would permit authentication as "user1" at
+ "host_a", and allow the key to be available on an agent forwarded
+ to "host_a" only for authentication to "host_b". The key would not
+ be visible on agent forwarded to other hosts or usable for
+ authentication there.
+
+ Internally, destination constraints use host keys to identify hosts.
+ The host patterns are used to obtain lists of host keys for that
+ destination that are communicated to the agent. The user/hostkeys are
+ encoded using a new restrict-destination-v00@openssh.com key
+ constraint.
+
+ host keys are looked up in the default client user/system known_hosts
+ files. It is possible to override this set on the command-line.
+
+ feedback Jann Horn & markus@
+ ok markus@
+
+ OpenBSD-Commit-ID: ef47fa9ec0e3c2a82e30d37ef616e245df73163e
-commit 464ba22f1e38d25402e5ec79a9b8d34a32df5a3f
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Aug 18 12:51:30 2021 +1000
+commit 4c1e3ce85e183a9d0c955c88589fed18e4d6a058
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sun Dec 19 22:09:23 2021 +0000
- Check compiler for c99 declarations after code.
+ upstream: ssh-agent side of binding
- The sntrup761 reference code contains c99-style declarations after code
- so don't try to build that if the compiler doesn't support it.
+ record session ID/hostkey/forwarding status for each active socket.
+
+ Attempt to parse data-to-be-signed at signature request time and extract
+ session ID from the blob if it is a pubkey userauth request.
+
+ ok markus@
+
+ OpenBSD-Commit-ID: a80fd41e292b18b67508362129e9fed549abd318
-commit 7d878679a4b155a359d32104ff473f789501748d
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Tue Aug 17 15:12:04 2021 +1000
+commit e9497ecf73f3c16667288bce48d4e3d7e746fea1
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sun Dec 19 22:08:48 2021 +0000
- Remove trailing backslash on regress-unit-binaries
+ upstream: ssh client side of binding
+
+ send session ID, hostkey, signature and a flag indicating whether the
+ agent connection is being forwarded to ssh agent each time a connection
+ is opened via a new "session-bind@openssh.com" agent extension.
+
+ ok markus@
+
+ OpenBSD-Commit-ID: 2f154844fe13167d3ab063f830d7455fcaa99135
-commit b71b2508f17c68c5d9dbbe537686d81cedb9a781
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Tue Aug 17 07:59:27 2021 +1000
+commit b42c61d6840d16ef392ed0f365e8c000734669aa
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sun Dec 19 22:08:06 2021 +0000
- Put stdint.h inside HAVE_STDINT_H.
+ upstream: Record session ID, host key and sig at intital KEX
- From Tom G. Christensen.
+ These will be used later for agent session ID / hostkey binding
+
+ ok markus@
+
+ OpenBSD-Commit-ID: a9af29e33772b18e3e867c6fa8ab35e1694a81fe
-commit 6a24567a29bd7b4ab64e1afad859ea845cbc6b8c
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Mon Aug 16 14:13:02 2021 +1000
+commit 26ca33d186473d58a32d812e19273ce078b6ffff
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Dec 7 22:06:45 2021 +0000
- Improve github test driver script.
+ upstream: better error message for FIDO keys when we can't match
- - 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).
+ them to a token
+
+ OpenBSD-Commit-ID: 58255c2a1980088f4ed144db67d879ada2607650
-commit b467cf13705f59ed348b620722ac098fe31879b7
+commit adb0ea006d7668190f0c42aafe3a2864d352e34a
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Mon Aug 16 11:32:23 2021 +1000
+Date: Wed Dec 15 10:50:33 2021 +1100
- Remove deprecated ubuntu-16.04 test targets.
+ Correct value for IPTOS_DSCP_LE.
- Github has deprecated ubuntu-16.04 and it will be removed on 20
- September.
+ It needs to allow for the preceeding two ECN bits. From daisuke.higashi
+ at gmail.com via OpenSSH bz#3373, ok claudio@, job@, djm@.
-commit 20e6eefcdf78394f05e453d456c1212ffaa6b6a4
+commit 3dafd3fe220bd9046f11fcf5191a79ec8800819f
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sun Aug 15 23:25:26 2021 +1000
+Date: Fri Dec 10 11:57:30 2021 +1100
- Skip agent ptrace test on hurd.
+ Increase timeout for test step.
-commit 7c9115bbbf958fbf85259a061c1122e2d046aabf
+commit 5aefb05cd5b843e975b191d6ebb7ddf8de35c112
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sun Aug 15 19:37:22 2021 +1000
+Date: Fri Dec 10 10:27:27 2021 +1100
- Add hurd test target.
+ Update the list of tests that don't work on Minix.
+
+ While there, remove CC (configure will now find clang) and make the test
+ list easier to update via cut and paste.
-commit 7909a566f6c6a78fcd30708dc49f4e4f9bb80ce3
+commit 1c09bb1b2e207d091cec299c49416c23d24a1b31
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
+Date: Fri Dec 10 10:12:57 2021 +1100
- 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.
+ Add minix host tuple.
+
+ Define SETEUID_BREAKS_SETUID for it which should make privsep work.
-commit e50635640f79920d9375e0155cb3f4adb870eee5
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Aug 13 13:21:00 2021 +1000
+commit a2188579032cf080213a78255373263466cb90cc
+Author: jsg@openbsd.org <jsg@openbsd.org>
+Date: Sun Dec 5 12:28:27 2021 +0000
- Test OpenSSH from OpenBSD head on 6.8 and 6.9.
+ upstream: fix unintended sizeof pointer in debug path ok markus@
+
+ OpenBSD-Commit-ID: b9c0481ffc0cd801e0840e342e6a282a85aac93c
-commit e0ba38861c490c680117b7fe0a1d61a181cd00e7
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Aug 13 13:00:14 2021 +1000
+commit da40355234068c82f1a36196f2d18dd2d81aaafd
+Author: naddy@openbsd.org <naddy@openbsd.org>
+Date: Sat Dec 4 00:05:39 2021 +0000
- Skip scp3 test on dragonfly 58 and 60.
+ upstream: RSA/SHA-1 is not used by default anymore on the server
- The tests hang, so skip until we figure them out.
+ OpenBSD-Commit-ID: 64abef6cfc3e53088225f6b8a1dcd86d52dc8353
-commit dcce2a2bcf007bf817a2fb0dce3db83fa9201e92
+commit e9c71498a083a8b502aa831ea931ce294228eda0
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Aug 12 23:59:25 2021 +0000
+Date: Thu Dec 2 23:45:36 2021 +0000
- upstream: mention that CASignatureAlgorithms accepts +/- similarly to
+ upstream: hash full host:port when asked to hash output, fixes hashes
- the other algorithm list directives; ok jmc bz#3335
+ for non- default ports. bz3367 ok dtucker@
- OpenBSD-Commit-ID: 0d46b53995817052c78e2dce9dbd133963b073d9
+ OpenBSD-Commit-ID: 096021cc847da7318ac408742f2d0813ebe9aa73
-commit 090a82486e5d7a8f7f16613d67e66a673a40367f
-Author: schwarze@openbsd.org <schwarze@openbsd.org>
-Date: Thu Aug 12 09:59:00 2021 +0000
+commit b5601202145a03106012c22cb8980bcac2949f0b
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Dec 2 23:23:13 2021 +0000
- upstream: In the editline(3) branch of the sftp(1) event loop,
+ upstream: improve the testing of credentials against inserted FIDO
- 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.
+ keys a little more: ask the token whether a particular key belongs to it in
+ cases where the token support on-token user- verification (e.g. biometrics)
+ rather than just assuming that it will accept it.
- 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.
+ Will reduce spurious "Confirm user presence" notifications for key
+ handles that relate to FIDO keys that are not currently inserted in at
+ least some cases.
- OK dtucker@ deraadt@
+ Motivated by bz3366; by Pedro Martelletto
- OpenBSD-Commit-ID: 8025115a773f52e9bb562eaab37ea2e021cc7299
+ OpenBSD-Commit-ID: ffac7f3215842397800e1ae2e20229671a55a63d
-commit e1371e4f58404d6411d9f95eb774b444cea06a26
-Author: naddy@openbsd.org <naddy@openbsd.org>
-Date: Wed Aug 11 14:07:54 2021 +0000
+commit ca709e27c41c90f4565b17282c48dca7756e083c
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Dec 2 22:40:05 2021 +0000
- upstream: scp: tweak man page and error message for -3 by default
+ upstream: move check_sk_options() up so we can use it earlier
- Now that the -3 option is enabled by default, flip the documentation
- and error message logic from "requires -3" to "blocked by -R".
+ OpenBSD-Commit-ID: 67fe98ba1c846d22035279782c4664c1865763b4
+
+commit b711bc01a7ec76bb6a285730990cbce9b8ca5773
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Thu Dec 2 22:35:05 2021 +0000
+
+ upstream: ssh-rsa is no longer in the default for
- ok djm@
+ PubkeyAcceptedAlgorithms.
- OpenBSD-Commit-ID: a872592118444fb3acda5267b2a8c3d4c4252020
+ OpenBSD-Commit-ID: 34a9e1bc30966fdcc922934ae00f09f2596cd73c
-commit 49f46f6d77328a3d10a758522b670a3e8c2235e7
-Author: naddy@openbsd.org <naddy@openbsd.org>
-Date: Wed Aug 11 14:05:19 2021 +0000
+commit dc91ceea33cd4a9f05be953e8d8062f732db5c8a
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Dec 2 02:44:44 2021 +0000
- upstream: scp: do not spawn ssh with two -s flags for
+ upstream: don't put the tty into raw mode when SessionType=none, avoids
- remote-to-remote copies
+ ^c being unable to kill such a session. bz3360; ok dtucker@
- 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.
+ OpenBSD-Commit-ID: 83960c433052303b643b4c380ae2f799ac896f65
+
+commit e6e7d2654a13ba10141da7b42ea683ea4eeb1f38
+Author: Damien Miller <djm@mindrot.org>
+Date: Mon Nov 29 14:11:03 2021 +1100
+
+ previous commit broke bcrypt_pbkdf()
- ok djm@
+ Accidentally reverted part of the conversion to use SHA512 from SUPERCOP
+ instead of OpenBSD-style libc SHA512.
+
+commit c0459588b8d00b73e506c6095958ecfe62a4a7ba
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Nov 29 14:03:19 2021 +1100
+
+ Fix typo in Neils' name.
+
+commit 158bf854e2a22cf09064305f4a4e442670562685
+Author: Damien Miller <djm@mindrot.org>
+Date: Mon Nov 29 12:30:22 2021 +1100
+
+ sync bcrypt-related files with OpenBSD
- OpenBSD-Commit-ID: 25df69759f323661d31b2e1e790faa22e27966c1
+ The main change is that Niels Provos kindly agreed to rescind the
+ BSD license advertising clause, shifting them to the 3-term BSD
+ license.
+
+ This was the last thing in OpenSSH that used the advertising clause.
-commit 2a2cd00783e1da45ee730b7f453408af1358ef5b
+commit e8976d92a42883ff6b8991438f07df60c2c0d82d
+Author: Damien Miller <djm@mindrot.org>
+Date: Mon Nov 29 12:29:29 2021 +1100
+
+ depend
+
+commit 8249afeec013e557fe7491a72ca3285de03e25b1
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Aug 11 08:55:04 2021 +0000
+Date: Sun Nov 28 07:21:26 2021 +0000
- upstream: test -Oprint-pubkey
+ upstream: sshsig: return "key not found" when searching empty files
- OpenBSD-Regress-ID: 3d51afb6d1f287975fb6fddd7a2c00a3bc5094e0
+ rather than "internal error"
+
+ OpenBSD-Commit-ID: e2ccae554c78d7a7cd33fc5d217f35be7e2507ed
-commit b9f4635ea5bc33ed5ebbacf332d79bae463b0f54
+commit 9e3227d4dbb5ad9c9091b4c14982cab4bba87b4d
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Aug 11 08:54:17 2021 +0000
+Date: Sun Nov 28 07:15:10 2021 +0000
- upstream: when verifying sshsig signatures, support an option
+ upstream: ssh-keygen -Y match-principals doesn't accept any -O
- (-Oprint-pubkey) to dump the full public key to stdout; based on patch from
- Fabian Stelzer; ok markus@
+ options at present, so don't say otherwise in SYNOPSIS; spotted jmc@
- OpenBSD-Commit-ID: 0598000e5b9adfb45d42afa76ff80daaa12fc3e2
+ OpenBSD-Commit-ID: 9cc43a18f4091010741930b48b3db2f2e4f1d35c
-commit 750c1a45ba4e8ad63793d49418a0780e77947b9b
+commit 56db1f4a4cf5039fc3b42e84c4b16291fdff32b1
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Aug 11 05:21:32 2021 +0000
+Date: Sun Nov 28 07:14:29 2021 +0000
- upstream: oops, missed one more %p
+ upstream: fix indenting in last commit
- OpenBSD-Commit-ID: e7e62818d1564cc5cd9086eaf7a51cbd1a9701eb
+ OpenBSD-Commit-ID: 8b9ba989815d0dec1fdf5427a4a4b58eb9cac4d2
-commit b5aa27b69ab2e1c13ac2b5ad3f8f7d389bad7489
+commit 50bea24a9a9bdebad327c76e700def3261f5694e
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Aug 11 05:20:17 2021 +0000
+Date: Sun Nov 28 07:10:18 2021 +0000
- upstream: remove a bunch of %p in format strings; leftovers of
-
- debuggings past. prompted by Michael Forney, ok dtucker@
+ upstream: missing initialisation for oerrno
- OpenBSD-Commit-ID: 4853a0d6c9cecaba9ecfcc19066e52d3a8dcb2ac
+ OpenBSD-Commit-ID: 05d646bba238080259bec821c831a6f0b48d2a95
-commit 419aa01123db5ff5dbc68b2376ef23b222862338
+commit 5a0f4619041d09cd29f3a08da41db5040372bdd1
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Aug 11 09:21:09 2021 +1000
+Date: Sun Nov 28 15:31:37 2021 +1100
- 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.
+ Correct ifdef to activate poll() only if needed.
-commit 931f592f26239154eea3eb35a086585897b1a185
+commit d4035c81a71237f690edd7eda32bef7d63fd9528
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Aug 10 03:35:45 2021 +0000
+Date: Sat Nov 27 07:23:35 2021 +0000
- upstream: adapt to scp -M flag change; make scp3.sh test SFTP mode too
+ upstream: whitespac e
- OpenBSD-Regress-ID: 43fea26704a0f0b962b53c1fabcb68179638f9c0
+ OpenBSD-Regress-ID: b9511d41568056bda489e13524390167889908f8
-commit 391ca67fb978252c48d20c910553f803f988bd37
+commit a443491e6782ef0f5a8bb87a5536c8ee4ff233a1
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Aug 10 03:33:34 2021 +0000
+Date: Sat Nov 27 07:20:58 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!).
+ upstream: regression test for match-principals. Mostly by Fabian
- prompted by/feedback from deraadt@
+ Stelzer
- OpenBSD-Commit-ID: 92ad72cc6f0023c9be9e316d8b30eb6d8d749cfc
+ OpenBSD-Regress-ID: ced0bec89af90935103438986bbbc4ad1df9cfa7
-commit bfdd4b722f124a4fa9173d20dd64dd0fc69856be
+commit 78230b3ec8cbabc1e7de68732dc5cbd4837c6675
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Aug 9 23:56:36 2021 +0000
+Date: Sat Nov 27 07:14:46 2021 +0000
- upstream: make scp -3 the default for remote-to-remote copies. It
+ upstream: Add ssh-keygen -Y match-principals operation to perform
- provides a much better and more intuitive user experience and doesn't require
- exposing credentials to the source host.
+ matching of principals names against an allowed signers file.
- thanks naddy@ for catching the missing argument in usage()
+ Requested by and mostly written by Fabian Stelzer, towards a TOFU
+ model for SSH signatures in git. Some tweaks by me.
- "Yes please!" - markus@
- "makes a lot of sense" - deraadt@
- "the right thing to do" - dtucker@
+ "doesn't bother me" deraadt@
- OpenBSD-Commit-ID: d0d2af5f0965c5192ba5b2fa461c9f9b130e5dd9
+ OpenBSD-Commit-ID: 8d1b71f5a4127bc5e10a880c8ea6053394465247
-commit 2f7a3b51cef689ad9e93d0c6c17db5a194eb5555
+commit 15db86611baaafb24c40632784dabf82e3ddb1a7
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Aug 9 23:49:31 2021 +0000
+Date: Thu Nov 25 23:02:24 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@
+ upstream: debug("func: ...") -> debug_f("...")
- OpenBSD-Commit-ID: 46639d382ea99546a4914b545fa7b00fa1be5566
+ OpenBSD-Commit-ID: d58494dc05c985326a895adfbe16fbd5bcc54347
-commit 2ab864010e0a93c5dd95116fb5ceaf430e2fc23c
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Aug 9 23:47:44 2021 +0000
+commit b7ffbb17e37f59249c31f1ff59d6c5d80888f689
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Nov 19 18:53:46 2021 +1100
- 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@
+ Allow for fd = -1 in compat ppoll overflow check.
- OpenBSD-Commit-ID: 7d794def9e4de348e1e777f6030fc9bafdfff392
+ Fixes tests on at least FreeBSD 6, possibly others.
-commit 41b019ac067f1d1f7d99914d0ffee4d2a547c3d8
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Aug 9 23:44:32 2021 +0000
+commit 04b172da5b96a51b0d55c905b423ababff9f4e0b
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Nov 19 16:01:51 2021 +1100
- 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@
+ Don't auto-enable Capsicum sandbox on FreeBSD 9/10.
- OpenBSD-Commit-ID: 263a071f14555c045fd03132a8fb6cbd983df00d
-
-commit b4b3f3da6cdceb3fd168b5fab69d11fba73bd0ae
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Aug 9 07:21:01 2021 +0000
+ Since we changed from select() to ppoll() tests have been failing.
+ This seems to be because FreeBSD 10 (and presumably 9) do not allow
+ ppoll() in the privsep process and sshd will fail with "Not permitted in
+ capability mode". Setting CAP_EVENT on the FDs doesn't help, but weirdly,
+ poll() works without that. Those versions are EOL so this situation is
+ unlikely to change.
- 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@
+commit a823f39986e7b879f26412e64c15630e1cfa0dc5
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Nov 18 03:53:48 2021 +0000
+
+ upstream: regression test for ssh-keygen -Y find-principals fix; from
- (this was originally committed as r1.223 along with unrelated stuff that
- I rolled back in r1.224)
+ Fabian Stelzer ok djm markus
- OpenBSD-Commit-ID: 1261fd667ad918484889ed3d7aec074f3956a74b
+ OpenBSD-Regress-ID: 34fe4088854c1a2eb4c0c51cc4676ba24096bac4
-commit 2ae7771749e0b4cecb107f9d4860bec16c3f4245
+commit 199c4df66c0e39dd5c3333b162af274678c0501d
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Aug 9 07:19:12 2021 +0000
+Date: Thu Nov 18 21:32:11 2021 +0000
- upstream: rever r1.223 - I accidentally committed unrelated changes
+ upstream: less confusing debug message; bz#3365
- OpenBSD-Commit-ID: fb73f3865b2647a27dd94db73d6589506a9625f9
+ OpenBSD-Commit-ID: 836268d3642c2cdc84d39b98d65837f5241e4a50
-commit 986abe94d481a1e82a01747360bd767b96b41eda
+commit 97f9b6e61316c97a32dad94b7a37daa9b5f6b836
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Aug 9 07:16:09 2021 +0000
+Date: Thu Nov 18 21:11:01 2021 +0000
- upstream: show only the final path component in the progress meter;
+ upstream: avoid xmalloc(0) for PKCS#11 keyid for ECDSA keys (we
- more useful with long paths (that may truncate) and better matches
- traditional scp behaviour; spotted by naddy@ ok deraadt@
+ already did this for RSA keys). Avoids fatal errors for PKCS#11 libraries
+ that return empty keyid, e.g. Microchip ATECC608B "cryptoauthlib"; bz#3364
- OpenBSD-Commit-ID: 26b544d0074f03ebb8a3ebce42317d8d7ee291a3
+ OpenBSD-Commit-ID: 054d4dc1d6a99a2e6f8eebc48207b534057c154d
-commit 2b67932bb3176dee4fd447af4368789e04a82b93
+commit c74aa0eb73bd1edf79947d92d9c618fc3424c4a6
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Aug 9 07:13:54 2021 +0000
+Date: Thu Nov 18 03:50:41 2021 +0000
- upstream: on fatal errors, make scp wait for ssh connection before
+ upstream: ssh-keygen -Y find-principals was verifying key validity
- exiting avoids LogLevel=verbose (or greater) messages from ssh appearing
- after scp has returned exited and control has returned to the shell; ok
- markus@
+ when using ca certs but not with simple key lifetimes within the allowed
+ signers file.
- 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
+ Since it returns the first keys principal it finds this could
+ result in a principal with an expired key even though a valid
+ one is just below.
- from goetze at dovetail.com, ok djm@ deraadt@
+ patch from Fabian Stelzer; feedback/ok djm markus
- OpenBSD-Commit-ID: 760320dac1c3b26904284ba417a7d63fccc5e742
+ OpenBSD-Commit-ID: b108ed0a76b813226baf683ab468dc1cc79e0905
-commit 86b4cb3a884846b358305aad17a6ef53045fa41f
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Sun Aug 8 08:27:28 2021 +0000
+commit d902d728dfd81622454260e23bc09d5e5a9a795e
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Nov 18 23:44:07 2021 +1100
- upstream: Although it's POSIX, not all shells used in Portable support
-
- the implicit 'in "$@"' after 'for i'.
-
- OpenBSD-Regress-ID: 3c9aec6bca4868f85d2742b6ba5223fce110bdbc
+ Correct calculation of tv_nsec in poll().
-commit f2ccf6c9f395923695f22345e626dfd691227aaf
+commit 21dd5a9a3fb35e8299a1fbcf8d506f1f6b752b85
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sun Aug 8 17:39:56 2021 +1000
+Date: Thu Nov 18 23:11:37 2021 +1100
- 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.
+ Add compat implementation of ppoll using pselect.
-commit 71b0eb997e220b0fc9331635af409ad84979f2af
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Sun Aug 8 07:27:52 2021 +0000
+commit b544ce1ad4afb7ee2b09f714aa63efffc73fa93a
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Nov 18 23:05:34 2021 +1100
- 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.
+ Put poll.h inside ifdef HAVE_POLL_H.
+
+commit 875408270c5a7dd69ed5449e5d85bd7120c88f70
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Nov 18 03:31:44 2021 +0000
+
+ upstream: check for POLLHUP wherever we check for POLLIN
- OpenBSD-Regress-ID: 87cd603eb6db58c9b430bf90adacb7f90864429b
+ OpenBSD-Commit-ID: 6aa6f3ec6b17c3bd9bfec672a917f003a76d93e5
-commit f0aca2706c710a0da1a4be705f825a807cd15400
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Sun Aug 8 06:38:33 2021 +0000
+commit 36b5e37030d35bbaa18ba56825b1af55971d18a0
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Nov 18 03:07:59 2021 +0000
- upstream: Drop -q in ssh-log-wrapper.sh to preserve logs.
+ upstream: fd leak in sshd listen loop error path; from Gleb
- 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.
+ Smirnoff
- OpenBSD-Regress-ID: e2c97d3c964bda33a751374c56f65cdb29755b75
+ OpenBSD-Commit-ID: a7a2be27a690a74bf2381bc16cea38e265657412
-commit cf27810a649c5cfae60f8ce66eeb25caa53b13bc
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Sat Aug 7 01:57:08 2021 +0000
+commit b99498d0c93f1edd04857b318308a66b28316bd8
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Nov 18 03:07:20 2021 +0000
- upstream: Fix prototype mismatch for do_cmd. ok djm@
+ upstream: check for POLLHUP as well as POLLIN in sshd listen loop;
- OpenBSD-Commit-ID: 1c1598bb5237a7ae0be99152f185e0071163714d
+ ok deraadt millert
+
+ OpenBSD-Commit-ID: a4f1244c5a9c2b08dac4f3b1dc22e9d1dc60c587
-commit 85de69f64665245786e28c81ab01fe18b0e2a149
+commit 1f3055d788e8cf80851eb1728b535d57eb0dba6a
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Aug 7 01:55:01 2021 +0000
+Date: Thu Nov 18 03:06:03 2021 +0000
- upstream: sftp-client.c needs poll.h
+ upstream: check for POLLHUP as well as POLLIN, handle transient IO
- remove unused variable
+ errors as well as half-close on the output side; ok deraadt millert
- OpenBSD-Commit-ID: 233ac6c012cd23af62f237167a661db391055a16
+ OpenBSD-Commit-ID: de5c5b9939a37476d256328cbb96305bdecf511e
-commit 397c4d72e50023af5fe3aee5cc2ad407a6eb1073
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Aug 7 11:30:57 2021 +1000
+commit 9778a15fa6dbdac6a95bf15865c2688b4bd6944e
+Author: Damien Miller <djm@mindrot.org>
+Date: Thu Nov 18 10:16:55 2021 +1100
- Include poll.h and friends for struct pollfd.
+ adjust seccomp filter for select->poll conversion
+
+ Needed to add ppoll syscall but also to relax the fallback rlimit
+ sandbox. Linux poll() fails with EINVAL if npfds > RLIMIT_NOFILE,
+ so we have to allow a single fd in the rlimit.
-commit a9e2c533195f28627f205682482d9da384c4c52e
+commit fcd8d895bbb849c64f0aed934e3303d37f696f5d
+Author: Damien Miller <djm@mindrot.org>
+Date: Thu Nov 18 10:16:44 2021 +1100
+
+ update depends
+
+commit 76292787a1e93e668f10e36b4bf59ce0ae28e156
+Author: Damien Miller <djm@mindrot.org>
+Date: Thu Nov 18 09:26:20 2021 +1100
+
+ compat for timespecsub() and friends
+
+commit fd7e7de4ddb4399c7e929b44f2bbfc118eddfcf8
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Aug 7 00:14:17 2021 +0000
+Date: Wed Nov 17 21:06:39 2021 +0000
- upstream: do_upload() used a near-identical structure for
-
- tracking expected status replies from the server to what do_download() was
- using.
+ upstream: set num_listen_socks to 0 on close-all instead of -1,
- Refactor it to use the same structure and factor out some common
- code into helper functions.
+ which interferes with the new poll()-based listen loop; spotted and debugged
+ by anton@+deraadt@
- OpenBSD-Commit-ID: 0c167df8ab6df4a5292c32421922b0cf379e9054
+ OpenBSD-Commit-ID: f7ab8ab124f615a2e0c45fee14c38d2f2abbabbd
-commit 7b1cbcb7599d9f6a3bbad79d412604aa1203b5ee
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Aug 7 00:12:09 2021 +0000
+commit fd9343579afac30a971f06643a669733d9acb407
+Author: deraadt@openbsd.org <deraadt@openbsd.org>
+Date: Sun Nov 14 18:47:43 2021 +0000
- upstream: make scp(1) in SFTP mode follow symlinks like
-
- traditional scp(1) ok markus@
+ upstream: use ppoll() instead of pselect() with djm
- OpenBSD-Commit-ID: 97255e55be37e8e26605e4ba1e69f9781765d231
+ OpenBSD-Commit-ID: 980f87c9564d5d2ad55722b7a6f44f21284cd215
-commit 133b44e500422df68c9c25c3b6de35c0263132f1
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Aug 7 00:10:49 2021 +0000
+commit 092d29b232ef1a19609a5316ed7e4d896bb2e696
+Author: deraadt@openbsd.org <deraadt@openbsd.org>
+Date: Sun Nov 14 06:15:36 2021 +0000
- upstream: fix incorrect directory permissions on scp -3
+ upstream: match .events with .fd better
- transfers; ok markus@
+ OpenBSD-Commit-ID: 77eef212ca0add905949532af390164489c5984b
+
+commit 8d642c9a90fa4ed5a3effd785fb3591e14de00cd
+Author: deraadt@openbsd.org <deraadt@openbsd.org>
+Date: Sun Nov 14 03:25:10 2021 +0000
+
+ upstream: convert select() to poll() ok djm
- OpenBSD-Commit-ID: 64b2abaa5635a2be65ee2e77688ad9bcebf576c2
+ OpenBSD-Commit-ID: b53e4940ff10dd24f8d16e8db8ef1970015d7ead
-commit 98b59244ca10e62ff67a420856770cb700164f59
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Aug 7 00:09:57 2021 +0000
+commit 6582a31c388968f4073af2bd8621880735c3d42b
+Author: deraadt@openbsd.org <deraadt@openbsd.org>
+Date: Sat Nov 13 21:14:13 2021 +0000
- upstream: a bit more debugging of file attributes being
+ upstream: replace select() with ppoll(), including converting
- sent/received over the wire
+ timeval's to timespec's to make things easier. back and forth and ok; djm
- OpenBSD-Commit-ID: f68c4e207b08ef95200a8b2de499d422808e089b
+ OpenBSD-Commit-ID: 89d3b23c60875da919e7820f9de6213286ffbec9
-commit c677e65365d6f460c084e41e0c4807bb8a9cf601
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Aug 7 00:08:52 2021 +0000
+commit 7c025c005550c86a40200a2bcdd355d09413d61a
+Author: deraadt@openbsd.org <deraadt@openbsd.org>
+Date: Sat Nov 13 17:26:13 2021 +0000
- upstream: make scp(1) in SFTP mode output better match original
+ upstream: It really looks like pledge "stdio dns" is possible
- scp(1) by suppressing "Retrieving [path]" lines that were emitted to support
- the interactive sftp(1) client. ok markus@
+ earlier. Discussed with mestre
- OpenBSD-Commit-ID: 06be293df5f156a18f366079be2f33fa68001acc
+ OpenBSD-Commit-ID: 610873de63a593e0ac7bbbcb7a0f2894d36f4c01
-commit 48cd39b7a4e5e7c25101c6d1179f98fe544835cd
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Aug 7 00:07:18 2021 +0000
+commit 06acb04c20ee483fe4757bd12aec870cc4bb1076
+Author: deraadt@openbsd.org <deraadt@openbsd.org>
+Date: Fri Nov 12 05:23:49 2021 +0000
- upstream: factor out a structure duplicated between downloading
-
- and crossloading; ok markus@
+ upstream: aggressively pre-fill the pollfd array with fd=-1
- OpenBSD-Commit-ID: 96eede24d520569232086a129febe342e4765d39
+ OpenBSD-Commit-ID: c2a525de8f83c1a04405bd79122c424140552a5b
-commit 318c06bb04ee21a0cfa6b6022a201eacaa53f388
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Aug 7 00:06:30 2021 +0000
+commit 7eec76793dec06e8f06b6cf71f9473141c69d109
+Author: deraadt@openbsd.org <deraadt@openbsd.org>
+Date: Thu Nov 11 15:32:32 2021 +0000
- upstream: use sftp_client crossloading to implement scp -3
+ upstream: Convert from select() to ppoll(). Along the way, I
- feedback/ok markus@
+ observed that the select() code was using exceptfds incorrectly.. ok millert
+
+ OpenBSD-Commit-ID: 548e05bfc31b2af02319eb3d051286d4128dec96
+
+commit e665ed2d0c24fe11d5470ce72fa1e187377d3fc4
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Nov 12 22:55:27 2021 +1100
+
+ Switch from LibreSSL 3.4.0 to 3.4.1.
- OpenBSD-Commit-ID: 7db4c0086cfc12afc9cfb71d4c2fd3c7e9416ee9
+ The LibreSSL 3.4.0 release has an OPENBSD_BRANCH that points to
+ "master" and that branch no longer has the files LibreSSL expects
+ and thus it will no longer build, breaking the test.
-commit de7115b373ba0be3861c65de9b606a3e0e9d29a3
+commit 21b6b5a06c8c53c548d25e6074c5240e88e2ef34
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Aug 7 00:02:41 2021 +0000
+Date: Wed Nov 10 06:29:25 2021 +0000
- upstream: support for "cross"-loading files/directories, i.e.
+ upstream: add the sntrup761x25519-sha512@openssh.com hybrid
- downloading from one SFTP server while simultaneously uploading to another.
+ ECDH/x25519 + Streamlined NTRU Prime post-quantum KEX to the default
+ KEXAlgorithms list (after the ECDH methods but before the prime-group DH
+ ones).
- feedback & ok markus@
+ ok markus@
- OpenBSD-Commit-ID: 3982878e29d8df0fa4ddc502f5ff6126ac714235
+ OpenBSD-Commit-ID: 22b77e27a04e497a10e22f138107579652854210
-commit a50bd0367ff2063bbc70a387740a2aa6914de094
+commit 239da797cbf07a640d7b1ea02d3f99ace3ef792d
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Aug 7 00:01:29 2021 +0000
+Date: Wed Nov 10 06:25:08 2021 +0000
- upstream: factor our SSH2_FXP_OPEN calls into their own function;
+ upstream: fix ssh-keysign for KEX algorithms that use SHA384/512
- "looks fine" markus@
+ exchange hashes; feedback/ok markus@
- OpenBSD-Commit-ID: d3dea2153f08855c6d9dacc01973248944adeffb
+ OpenBSD-Commit-ID: 09a8fda1c081f5de1e3128df64f28b7bdadee239
-commit e3c0ba05873cf3d3f7d19d595667a251026b2d84
+commit 6997a592ecb1013df0c6d7f8df3e6517827aef11
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Aug 7 00:00:33 2021 +0000
+Date: Mon Nov 8 21:32:49 2021 +0000
- upstream: prepare for scp -3 implemented via sftp
+ upstream: improve error message when trying to expand a ~user path
- 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.
+ for a user that doesn't exist; better matches what the shell does
- POSIX does not require diff to have -N, so compare in both directions
- with just -r, which should catch missing files in either directory.
+ ok deraadt@
- OpenBSD-Regress-ID: 0e2ec8594556a6f369ed5a0a90c6806419b845f7
+ OpenBSD-Commit-ID: 1ddefa3c3a78b69ce13d1b8f67bc9f2cefd23ad6
-commit d247a73ce27b460138599648d9c637c6f2b77605
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Aug 4 21:28:00 2021 +0000
+commit 10b899a15c88eb40eb5f73cd0fa84ef0966f79c9
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Nov 10 12:34:25 2021 +1100
- upstream: regression test for scp -3
+ Don't trust closefrom() on Linux.
- OpenBSD-Regress-ID: b44375d125c827754a1f722ec6b6b75b634de05d
+ glibc's closefrom implementation does not work in a chroot when the kernel
+ does not have close_range. It tries to read from /proc/self/fd and when
+ that fails dies with an assertion of sorts. Instead, call close_range
+ ourselves from our compat code and fall back if that fails. bz#3349,
+ with william.wilson at canonical.com and fweimer at redhat.com.
-commit 35c8e41a6f6d8ad76f8d1cd81ac2ea23d0d993b2
+commit eb1f63195a9a38b519536a5b398d9939261ec081
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Aug 6 05:04:42 2021 +0000
+Date: Sat Nov 6 10:13:39 2021 +0000
- upstream: Document "ProxyJump none". bz#3334.
+ upstream: Plug a couple of minor mem leaks. From beldmit at
- OpenBSD-Commit-ID: f78cc6f55731f2cd35c3a41d5352ac1ee419eba7
+ gmail.com via github PR#283, ok markus@
+
+ OpenBSD-Commit-ID: ec1fa7d305d46226861c3ca6fb9c9beb2ada2892
-commit 911ec6411821bda535d09778df7503b92f0eafab
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Wed Aug 4 01:34:55 2021 +0000
+commit e4f501bf1d3b53f1cc23d9521fd7c5163307b760
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Nov 5 03:10:58 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.
+ upstream: move cert_filter_principals() to earlier in the file for
- Pinpointed by the -portable Valgrind regress test. ok djm@ deraadt@
+ reuse; no code change
- OpenBSD-Commit-ID: 750f3c19bd4440e4210e30dd5d7367386e833374
+ OpenBSD-Commit-ID: 598fa9528b656b2f38bcc3cf5b6f3869a8c115cf
-commit 6df1fecb5d3e51f3a8027a74885c3a44f6cbfcbd
-Author: Damien Miller <djm@mindrot.org>
-Date: Wed Aug 4 11:05:11 2021 +1000
+commit 59c60f96fee321c7f38f00372826d37f289534af
+Author: deraadt@openbsd.org <deraadt@openbsd.org>
+Date: Wed Nov 3 22:00:56 2021 +0000
- use openbsd-compat glob.h is required
+ upstream: Many downstreams expect ssh to compile as non-C99...
+
+ OpenBSD-Commit-ID: e6aa3e08bda68e5fb838fc8a49b1d2dfc38ee783
-commit 9ebd1828881dfc9014a344587934a5ce7db6fa1b
+commit 7a78fe63b0b28ef7231913dfefe9d08f9bc41c61
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Tue Aug 3 21:03:23 2021 +1000
+Date: Sat Nov 6 21:07:03 2021 +1100
- Missing space between macro arg and punctuation.
+ Skip getline() on HP-UX 10.x.
- From jmc@
+ HP-UX 10.x has a getline() implementation in libc that does not behave
+ as we expect so don't use it. With correction from Thorsten Glaser and
+ typo fix from Larkin Nickle.
-commit 0fd3f62eddc7cf54dcc9053be6f58998f3eb926a
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Tue Aug 3 21:02:33 2021 +1000
+commit 343ae252ebb35c6ecae26b447bf1551a7666720e
+Author: Damien Miller <djm@mindrot.org>
+Date: Wed Nov 3 12:08:21 2021 +1100
- Avoid lines >80 chars. From jmc@
+ basic SECURITY.md (refers people to the website)
-commit af5d8094d8b755e1daaf2e20ff1dc252800b4c9b
+commit ed45a0168638319e0a710633f6085b96b9cec656
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Aug 3 01:05:24 2021 +0000
+Date: Tue Nov 2 22:57:27 2021 +0000
- upstream: regression tests for scp SFTP protocol support; mostly by
+ upstream: crank SSH_SK_VERSION_MAJOR to match recent change in
- Jakub Jelen in GHPR#194 ok markus
+ usr/bin/ssh
- OpenBSD-Regress-ID: 36f1458525bcb111741ec8547eaf58b13cddc715
+ OpenBSD-Regress-ID: 113d181c7e3305e138db9b688cdb8b0a0019e552
-commit e4673b7f67ae7740131a4ecea29a846593049a91
-Author: anton@openbsd.org <anton@openbsd.org>
-Date: Thu Jul 29 15:34:09 2021 +0000
+commit f3c34df860c4c1ebddacb973954e58167d9dbade
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Nov 2 22:56:40 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.
+ upstream: Better handle FIDO keys on tokens that provide user
- ok dtucker@
+ verification (UV) on the device itself, including biometric keys.
- 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
+ Query the token during key creation to determine whether it supports
+ on-token UV and, if so, clear the SSH_SK_USER_VERIFICATION_REQD flag
+ in the key so that ssh(1) doesn't automatically prompty for PIN later.
- scp, via a new "-M sftp" option. Marked as experimental for now.
+ When making signatures with the key, query the token's capabilities
+ again and check whether the token is able (right now) to perform user-
+ verification without a PIN. If it is then the PIN prompt is bypassed
+ and user verification delegated to the token. If not (e.g. the token
+ is biometric capable, but no biometric are enrolled), then fall back
+ to user verification via the usual PIN prompt.
- Some corner-cases exist, in particular there is no attempt to
- provide bug-compatibility with scp's weird "double shell" quoting
- rules.
+ Work by Pedro Martelletto; ok myself and markus@
- Mostly by Jakub Jelen in GHPR#194 with some tweaks by me. ok markus@
- Thanks jmc@ for improving the scp.1 bits.
+ NB. cranks SSH_SK_VERSION_MAJOR
- OpenBSD-Commit-ID: 6ce4c9157ff17b650ace571c9f7793d92874051c
+ OpenBSD-Commit-ID: e318a8c258d9833a0b7eb0236cdb68b5143b2f27
-commit dd533c7ab79d61a7796b77b64bd81b098e0d7f9f
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Fri Jul 30 14:28:13 2021 +0000
+commit 0328a081f38c09d2d4d650e94461a47fb5eef536
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Oct 29 03:03:06 2021 +0000
- upstream: fix a formatting error and add some Xr; from debian at
+ upstream: sshsig: add tests for signing key validity and
- helgefjell de
+ find-principals
- removed references to rlogin etc. as no longer relevant;
- suggested by djm
+ - adds generic find-principals tests (this command had none before)
+ - tests certs with a timeboxed validity both with and without a
+ restriced lifetime for the CA
+ - test for a revoked CA cert
- ok djm dtucker
+ by Fabian Stelzer
- OpenBSD-Commit-ID: 3c431c303068d3aec5bb18573a0bd5e0cd77c5ae
+ OpenBSD-Regress-ID: 9704b2c6df5b8ccfbdf2c06c5431f5f8cad280c9
-commit c7cd347a8823819411222c1e10a0d26747d0fd5c
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Fri Jul 30 14:25:01 2021 +0000
+commit ccd358e1e25e25c13f0825996283cbf7a1647a3b
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Oct 29 02:48:19 2021 +0000
- upstream: fix a formatting error and mark up known_hosts
+ upstream: avoid signedness warning; spotted in -portable
- consistently; issues reported by debian at helgefjell de
+ OpenBSD-Regress-ID: 4cacc126086487c0ea7f3d86b42dec458cf0d0c6
+
+commit 2741f52beb11490d7033a25e56ed0496f0c78006
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Oct 29 03:20:46 2021 +0000
+
+ upstream: ssh-keygen: make verify-time argument parsing optional
- ok djm dtucker
+ From Fabian Stelzer
- OpenBSD-Commit-ID: a1fd8d21dc77f507685443832df0c9700481b0ce
+ OpenBSD-Commit-ID: 1ff35e4c366a45a073663df90381be6a8ef4d370
-commit 4455aec2e4fc90f64ae4fc47e78ebc9c18721738
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Wed Jul 28 05:57:42 2021 +0000
+commit a1217d363b88b32cfe54c4f02c6c1cf4bdefdd23
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Oct 29 13:48:34 2021 +1100
- upstream: no need to talk about version 2 with the -Q option, so
+ unbreak fuzz harness for recent changes
+
+commit 68e522ed8183587c9367fa3842c5b75f64f3d12b
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Oct 29 13:32:24 2021 +1100
+
+ Use -Wbitwise-instead-of-logical if supported.
+
+commit be28b23012aa3fa323be7ec84863cf238927c078
+Author: Damien Miller <djm@mindrot.org>
+Date: Thu Oct 28 16:24:53 2021 +1100
+
+ use -Wmisleading-indentation cflag if available
- rewrite the text to read better;
+ ok dtucker@
+
+commit 2e6f5f24dd2f9217f4ab8b737ed428d5d5278f91
+Author: Damien Miller <djm@mindrot.org>
+Date: Thu Oct 28 16:24:44 2021 +1100
+
+ depend
+
+commit a5ab4882348d26addc9830a44e053238dfa2cb58
+Author: Damien Miller <djm@mindrot.org>
+Date: Thu May 6 10:08:30 2021 +1000
+
+ remove built-in support for md5crypt()
- issue reported by debian at helgefjell de
- ok djm dtucker
+ Users of MD5-hashed password should arrange for ./configure to link
+ against libxcrypt or similar. Though it would be better to avoid use
+ of MD5 password hashing entirely, it's arguably worse than DEScrypt.
- OpenBSD-Commit-ID: 59fe2e8219c37906740ad062e0fdaea487dbe9cf
+ feedback and ok dtucker@
-commit bec429338e9b30d2c7668060e82608286a8a4777
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Tue Jul 27 14:28:46 2021 +0000
+commit c5de1fffa6328b8246b87da28fa9df05813f76a3
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Oct 28 02:55:30 2021 +0000
- upstream: word fix; reported by debian at helgefjell de
+ upstream: increment SSH_SK_VERSION_MAJOR to match last change
- OpenBSD-Commit-ID: 0c6fd22142422a25343c5bd1a618f31618f41ece
+ OpenBSD-Regress-ID: 17873814d1cbda97f49c8528d7b5ac9cadf6ddc0
-commit efad4deb5a1f1cf79ebefd63c6625059060bfbe1
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Tue Jul 27 14:14:25 2021 +0000
+commit 0001d04e55802d5bd9d6dece1081a99aa4ba2828
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Oct 28 02:54:18 2021 +0000
- upstream: standardise the grammar in the options list; issue
+ upstream: When downloading resident keys from a FIDO token, pass
- reported by debian at helgefjell de
+ back the user ID that was used when the key was created and append it to the
+ filename the key is written to (if it is not the default).
- ok dtucker djm
+ Avoids keys being clobbered if the user created multiple
+ resident keys with the same application string but different
+ user IDs.
- 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.
+ feedback Pedro Martelletto; ok markus
- Prevents an unused variable warning on platforms that have setenv but
- not unsetenv.
+ NB. increments SSH_SK_VERSION_MAJOR
+
+ OpenBSD-Commit-ID: dbd658b5950f583106d945641a634bc6562dd3a3
-commit a1f78e08bdb3eaa88603ba3c6e01de7c8671e28a
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Mon Jul 26 12:45:30 2021 +1000
+commit d4bed5445646e605c383a4374fa962e23bf9e3a3
+Author: deraadt@openbsd.org <deraadt@openbsd.org>
+Date: Sun Oct 24 21:24:17 2021 +0000
- Move SUDO to "make test" command line.
+ upstream: For open/openat, if the flags parameter does not contain
- Environment variables don't get passed by vmrun, so move to command
- line.
+ O_CREAT, the 3rd (variadic) mode_t parameter is irrelevant. Many developers
+ in the past have passed mode_t (0, 044, 0644, or such), which might lead
+ future people to copy this broken idiom, and perhaps even believe this
+ parameter has some meaning or implication or application. Delete them all.
+ This comes out of a conversation where tb@ noticed that a strange (but
+ intentional) pledge behaviour is to always knock-out high-bits from mode_t on
+ a number of system calls as a safety factor, and his bewilderment that this
+ appeared to be happening against valid modes (at least visually), but no
+ sorry, they are all irrelevant junk. They could all be 0xdeafbeef. ok
+ millert
+
+ OpenBSD-Commit-ID: 503d11633497115688c0c6952686524f01f53121
-commit 02e624273b9c78a49a01239159b8c09b8409b1a0
+commit d575cf44895104e0fcb0629920fb645207218129
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sun Jul 25 23:26:36 2021 +1000
+Date: Fri Oct 22 23:27:41 2021 +1100
- Set SUDO for tests and cleanup.
+ kitchensink test target now needs krb5.
-commit 460ae5d93051bab70239ad823dd784822d58baad
+commit 4ae39cada214e955bcfd3448ff28f0ed18886706
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sun Jul 25 22:37:55 2021 +1000
+Date: Fri Oct 22 22:54:33 2021 +1100
- Pass OPENSSL=no to make tests too.
+ Test both MIT KRB5 and Heimdal.
-commit b398f499c68d74ebe3298b73757cf3f36e14e0cb
+commit 22b2681d88619e5247dc53c9f112058a7e248d48
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Sun Jul 25 12:27:37 2021 +0000
+Date: Fri Oct 22 10:51:57 2021 +0000
- upstream: Skip unit and makefile-based key conversion tests when
+ upstream: Plug mem addrinfo mem leaks.
- we're building with OPENSSL=no.
+ Prevent mem leaks in the (unlikely) event that getaddrinfo returns
+ no addresses. ALso, remove an unneeded NULL check in addr_ntop. From
+ khaleesicodes via github PR#281, ok deraadt@
- OpenBSD-Regress-ID: 20455ed9a977c93f846059d1fcb48e29e2c8d732
+ OpenBSD-Commit-ID: e8a5afc686376637c355c5f7e122dc4b080b9c1a
-commit 727ce36c8c5941bde99216d27109405907caae4f
+commit 27c8c343b610263f83ac2328735feeb881c6c92f
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Sun Jul 25 12:13:03 2021 +0000
+Date: Fri Oct 22 09:22:04 2021 +0000
- upstream: Replace OPENSSL as the variable that points to the
+ upstream: Remove unnecessary semicolons
- 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.
+ ... in case statements. From khaleesicodes via github PR#280.
- OpenBSD-Regress-ID: 2d788fade3264d7803e5b54cae8875963f688c4e
+ OpenBSD-Commit-ID: e1e89360b65775cff83e77ce040b342015caf4ed
-commit 55e17101a9075f6a63af724261c5744809dcb95c
+commit e7eb73b8d1fe1008d92433ea949491ce654bfaba
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Sat Jul 24 02:57:28 2021 +0000
+Date: Fri Oct 22 09:19:34 2021 +0000
- upstream: Skip RFC4716 format import and export tests when built
+ upstream: Fix typos in comments.
- without OpenSSL.
+ From khaleesicodes via github PR#280.
- OpenBSD-Regress-ID: d2c2d5d38c1acc2b88cc99cfe00a2eb8bb39dfa4
+ OpenBSD-Commit-ID: 26fdd83652c40f098bf7c685e8ebb9eb72cc45fc
-commit f5ccb5895d39cd627ad9e7b2c671d2587616100d
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Sat Jul 24 02:51:14 2021 +0000
+commit 052a9d8494175e24312daa6c132665e58c17fe6e
+Author: deraadt@openbsd.org <deraadt@openbsd.org>
+Date: Fri Oct 15 14:46:46 2021 +0000
- upstream: Don't omit ssh-keygen -y from usage when built without
+ upstream: switch scp(1) back to sftp protocol.
- OpenSSL. It is actually available, albeit only for ed25519 keys.
+ openbsd 7.0 release shipped with the (hopefully last) scp that uses RCP
+ protocol for copying. Let's get back to testing the SFTP protocol.
- OpenBSD-Commit-ID: 7a254c33d0e6a55c30c6b016a8d298d3cb7a7674
+ OpenBSD-Commit-ID: 9eaa35d95fd547b78b0a043b3f518e135f151f30
-commit 819d57ac23469f1f03baa8feb38ddefbada90fdc
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Sat Jul 24 02:08:13 2021 +0000
+commit a07664646bf6d293f5bbd45a5de54f3c36bb85da
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Oct 22 14:00:05 2021 +1100
- 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
+ Source configs script so setup_ci can use settings
-commit b6673b1d2ee90b4690ee84f634efe40225423c38
+commit 34df52c201c6b47e5a46b50c215e4d98a8bf6587
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Jul 24 13:02:51 2021 +1000
+Date: Fri Oct 22 09:42:14 2021 +1100
- Test OpenBSD upstream with and without OpenSSL.
+ Install libedit and pam based on config flags.
-commit 9d38074b5453c1abbdf888e80828c278d3b886ac
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Jul 24 01:54:23 2021 +0000
+commit 8c626cc563e8d21d844d06f9971a9ee01de6aa2a
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Oct 21 16:53:39 2021 +1100
- upstream: test for first-match-wins in authorized_keys environment=
-
- options
-
- OpenBSD-Regress-ID: 1517c90276fe84b5dc5821c59f88877fcc34c0e8
+ Don't use 'here string", it's not POSIX.
-commit 2b76f1dd19787e784711ea297ad8fc938b4484fd
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Jul 23 05:53:02 2021 +0000
+commit 086a4b5977472aefa3de918b88efad0faf83b2b1
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Oct 21 15:33:27 2021 +1100
- upstream: Simplify keygen-convert by using $SSH_KEYTYPES directly.
-
- OpenBSD-Regress-ID: cdbe408ec3671ea9ee9b55651ee551370d2a4108
+ Remove -Werror from compiler package to install.
-commit 7d64a9fb587ba9592f027f7a2264226c713d6579
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Jul 24 01:55:19 2021 +0000
+commit 5a7a4687507d057f9b5e7497f3d3f82e64753c02
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Oct 21 15:00:53 2021 +1100
- upstream: don't leak environment= variable when it is not the first
-
- match
-
- OpenBSD-Commit-ID: 7fbdc3dfe0032deaf003fd937eeb4d434ee4efe0
+ Build with -Werror on most recent gcc and clang.
-commit db2130e2340bf923e41c791aa9cd27b9e926042c
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Fri Jul 23 06:01:17 2021 +0000
+commit 4d2cbdb525d673acf941d48a7044fcf03125611a
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Oct 15 12:59:06 2021 +1100
- upstream: punctuation;
-
- OpenBSD-Commit-ID: 64be152e378c45975073ab1c07e0db7eddd15806
+ Include string.h and stdio.h for strerror.
-commit 03190d10980c6fc9124e988cb2df13101f266507
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jul 23 05:56:47 2021 +0000
+commit fff13aaa262b7b3ec83ed21e29674cbf331780a7
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Oct 15 12:43:36 2021 +1100
- 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
+ Include error reason if trace disabling fails.
-commit 1653ece6832b2b304d46866b262d5f69880a9ec7
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Jul 23 05:07:16 2021 +0000
+commit d4b38144c02f3faa5271e5fb35df93507e06f1b4
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Tue Oct 12 22:55:51 2021 +1100
- upstream: Test conversion of ed25519 and ecdsa keys too.
-
- OpenBSD-Regress-ID: 3676d2d00e58e0d6d37f2878f108cc2b83bbe4bb
+ Add tcmalloc test target.
-commit 8b7af02dcf9d2b738787efd27da7ffda9859bed2
+commit 002d65b0a30063c6e49bf8a53e709d8d5a0d45c1
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Jul 23 04:56:21 2021 +0000
+Date: Sat Oct 9 10:52:42 2021 +0000
- upstream: Add test for exporting pubkey from a passphrase-protected
+ upstream: Document that CASignatureAlgorithms, ExposeAuthInfo and
- private key.
+ PubkeyAuthOptions can be used in a Match block. Patch from eehakkin via
+ github PR#277.
- OpenBSD-Regress-ID: da99d93e7b235fbd5b5aaa01efc411225e6ba8ac
+ OpenBSD-Commit-ID: c0a63f5f52e918645967ac022b28392da4b866aa
-commit 441095d4a3e5048fe3c87a6c5db5bc3383d767fb
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jul 23 03:54:55 2021 +0000
+commit 40bd3709dddaae3a1b6113748bec3faa6a607531
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Oct 7 15:55:49 2021 +1100
- upstream: regression test for time-limited signature keys
+ Skip SK unit tests when built without security-key
+
+commit 482f73be10f10b93f818df19fcc8a912c0c371fc
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Oct 7 15:55:04 2021 +1100
+
+ Include relevant env vars on command line.
- OpenBSD-Regress-ID: 2a6f3bd900dbee0a3c96f1ff23e032c93ab392bc
+ Makes it easier to reproduce a build by cut/pasting the configure line.
+
+commit ef5916b8acd9b1d2f39fad4951dae03b00dbe390
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Oct 7 14:28:02 2021 +1100
+
+ Only enable sk-* key types if ENABLE_SK is defined
+
+commit 52d4232b493a9858fe616e28a8bbcc89afa2ad4d
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Oct 6 18:14:37 2021 +1100
+
+ Disable security key on minix3.
+
+ The test doesn't work so disable.
+
+commit 7cd062c3a29669b8d7dc2a97e6575f4dcb7d35a2
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Oct 6 17:45:28 2021 +1100
+
+ Add USE_LIBC_SHA2 for (at least) NetBSD 9.
-commit 9e1882ef6489a7dd16b6d7794af96629cae61a53
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jul 23 05:24:02 2021 +0000
+commit 639c440f6c3c2a8216a5eb9455ef13bf4204089c
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Oct 6 17:09:31 2021 +1100
- upstream: note successful authentication method in final "Authenticated
-
- to ..." message and partial auth success messages (all at LogLevel=verbose)
- ok dtucker@
+ Define OPENSSL_NO_SHA including OpenSSL from test.
- OpenBSD-Commit-ID: 06834b89ceb89f8f16c5321d368a66c08f441984
+ We don't use SHA256 from OpenSSL in the sk-dummy module and the
+ definitions can conflict with system sha2.h (eg on NetBSD) so define
+ OPENSSL_NO_SHA so we don't attempt to redefine them.
-commit a917e973a1b90b40ff1e950df083364b48fc6c78
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jul 23 04:04:52 2021 +0000
+commit 8f4be526a338d06624f146fa26007bb9dd3a4f7b
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Oct 6 15:40:58 2021 +1100
- upstream: Add a ForkAfterAuthentication ssh_config(5) counterpart
-
- to the ssh(1) -f flag. Last part of GHPR231 from Volker Diels-Grabsch. ok
- dtucker
+ Disable security key on NetBSD4 test.
- OpenBSD-Commit-ID: b18aeda12efdebe2093d55263c90fe4ea0bce0d3
+ sk-dummy used for the security key test includes both sha2.h and OpenSSL
+ causing the definitions conflict so disable security key support on this
+ platform.
-commit e0c5088f1c96a145eb6ea1dee438010da78f9ef5
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jul 23 04:00:59 2021 +0000
+commit 3b353ae58aa07a1cbbeb1da3ace21fc0dcccd66a
+Author: Damien Miller <djm@mindrot.org>
+Date: Wed Oct 6 15:07:01 2021 +1100
- 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
+ clean regress/misc/sk-dummy in cleandir target
-commit e3957e21ffdc119d6d04c0b1686f8e2fe052f5ea
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jul 23 03:57:20 2021 +0000
+commit 57680a2ab43518c5ccbd8242c40482106cde6ac1
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Sat Oct 2 03:17:01 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).
+ upstream: Dynamically allocate encoded HashKnownHosts and free as
- feedback and ok dtucker@
+ appropriate. Saves 1k of static storage and prevents snprintf "possible
+ truncation" warnings from newer compilers (although in this case it's false
+ positive since the actual sizes are limited by the output size of the SHA1).
+ ok djm@
- OpenBSD-Commit-ID: 01f63fc10dcd995e7aed9c378ad879161af83121
+ OpenBSD-Commit-ID: e254ae723f7e3dce352c7d5abc4b6d87faf61bf4
-commit d0bb1ce731762c55acb95817df4d5fab526c7ecd
+commit e3e62deb549fde215b777d95276c304f84bf00c6
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jul 23 03:37:52 2021 +0000
+Date: Wed Oct 6 03:35:13 2021 +0000
- upstream: Let allowed signers files used by ssh-keygen(1)
+ upstream: use libc SHA256 functions; make this work when compiled
- 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@
+ !WITH_OPENSSL
- OpenBSD-Commit-ID: 3e2c67b7dcd94f0610194d1e8e4907829a40cf31
+ OpenBSD-Regress-ID: fda0764c1097cd42f979ace29b07eb3481259890
-commit 44142068dc7ef783d135e91ff954e754d2ed432e
+commit 12937d867019469ebce83c2ff614cdc6688fc2d8
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Mon Jul 19 08:48:33 2021 +0000
+Date: Fri Oct 1 05:20:20 2021 +0000
- upstream: Use SUDO when setting up hostkey.
+ upstream: Add test for ssh hashed known_hosts handling.
- OpenBSD-Regress-ID: 990cf4481cab8dad62e90818a9b4b36c533851a7
+ OpenBSD-Regress-ID: bcef3b3cd5a1ad9899327b4b2183de2541aaf9cf
-commit 6b67f3f1d1d187597e54a139cc7785c0acebd9a2
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Mon Jul 19 05:08:54 2021 +0000
+commit 5a37cc118f464416d08cd0291a9b1611d8de9943
+Author: Damien Miller <djm@mindrot.org>
+Date: Wed Oct 6 13:16:21 2021 +1100
- upstream: Increase time margin for rekey tests. Should help
-
- reliability on very heavily loaded hosts.
+ fix broken OPENSSL_HAS_ECC test
- OpenBSD-Regress-ID: 4c28a0fce3ea89ebde441d7091464176e9730533
+ spotted by dtucker
-commit 7953e1bfce9e76bec41c1331a29bc6cff9d416b8
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Mon Jul 19 13:47:51 2021 +1000
+commit 16a25414f303cd6790eb967aeb962040e32c9c7a
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Oct 1 22:40:06 2021 +1000
- Add sshfp-connect.sh file missed in previous.
+ make sk-dummy.so work without libcrypto installed
-commit b75a80fa8369864916d4c93a50576155cad4df03
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Mon Jul 19 03:13:28 2021 +0000
+commit dee22129bbc61e25b1003adfa2bc584c5406ef2d
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Oct 1 16:35:49 2021 +1000
- 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@.
+ make OPENSSL_HAS_ECC checks more thorough
- OpenBSD-Commit-ID: 0a6a0a476eb7f9dfe8fe2c05a1a395e3e9b22ee4
+ ok dtucker
-commit 1cc1fd095393663cd72ddac927d82c6384c622ba
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Mon Jul 19 02:21:50 2021 +0000
+commit 872595572b6c9a584ed754165e8b7c4c9e7e1d61
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Oct 1 16:35:05 2021 +1000
- upstream: Id sync only, -portable already has this.
-
- Put dh_set_moduli_file call inside ifdef WITH_OPENSSL. Fixes
- build with OPENSSL=no.
+ fix FIDO key support for !OPENSSL_HAS_ECC case
- OpenBSD-Commit-ID: af54abbebfb12bcde6219a44d544e18204defb15
+ ok dtucker
-commit 33abbe2f4153f5ca5c874582f6a7cc91ae167485
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Mon Jul 19 02:46:34 2021 +0000
+commit 489741dc68366940d369ac670b210b4834a6c272
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Oct 1 14:51:37 2021 +1000
- 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
+ enable security key support for --without-openssl
-commit f0cd000d8e3afeb0416dce1c711c3d7c28d89bdd
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Mon Jul 19 02:29:28 2021 +0000
+commit c978565c8589acfe4ea37ab5099d39c84158c713
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Oct 1 13:27:50 2021 +1000
- 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
+ need stdlib.h for free(3)
-commit 0075511e27e5394faa28edca02bfbf13b9a6693e
+commit 76a398edfb51951b2d65d522d7b02c72304db300
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Mon Jul 19 00:16:26 2021 +0000
+Date: Thu Sep 30 05:26:26 2021 +0000
- upstream: Group keygen tests together.
+ upstream: Fix up whitespace left by previous
- OpenBSD-Regress-ID: 07e2d25c527bb44f03b7c329d893a1f2d6c5c40c
+ change removing privsep. No other changes.
+
+ OpenBSD-Regress-ID: 87adec225d8afaee4d6a91b2b71203f52bf14b15
-commit 034828820c7e62652e7c48f9ee6b67fb7ba6fa26
+commit ddcb53b7a7b29be65d57562302b2d5f41733e8dd
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Sun Jul 18 23:10:10 2021 +0000
+Date: Thu Sep 30 05:20:08 2021 +0000
- upstream: Add test for ssh-keygen printing of SSHFP records.
+ upstream: Remove references to privsep.
- 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
+ This removes several do..while loops but does not change the
+ indentation of the now-shallower loops, which will be done in a separate
+ whitespace-only commit to keep changes of style and substance separate.
- OpenBSD-Commit-ID: 4f5186b1466656762dae37d3e569438d900c350d
+ OpenBSD-Regress-ID: 4bed1a0249df7b4a87c965066ce689e79472a8f7
-commit 43ec991a782791d0b3f42898cd789f99a07bfaa4
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Jul 17 00:36:53 2021 +0000
+commit ece2fbe486164860de8df3f8b943cccca3085eff
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Thu Sep 30 04:22:50 2021 +0000
- upstream: fix sftp on ControlPersist connections, broken by recent
+ upstream: Use "skip" instead of "fatal"
- SessionType change; spotted by sthen@
+ if SUDO isn't set for the *-command tests. This means running "make tests"
+ without SUDO set will perform all of the tests that it can instead of
+ failing on the ones it cannot run.
- OpenBSD-Commit-ID: 4c5ddc5698790ae6ff50d2a4f8f832f0eeeaa234
+ OpenBSD-Regress-ID: bd4dbbb02f34b2e8c890558ad4a696248def763a
-commit 073f45c236550f158c9a94003e4611c07dea5279
+commit bb754b470c360e787a99fb4e88e2668198e97b41
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jul 16 09:00:23 2021 +0000
+Date: Fri Oct 1 04:50:36 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@
+ upstream: unbreak FIDO sk-ed25519 key enrollment for OPENSSL=no builds;
- 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
+ ok dtucker@
- OpenBSD-Commit-ID: c7dd0b39e942b1caf4976a0b1cf0fed33d05418c
+ OpenBSD-Commit-ID: 6323a5241728626cbb2bf0452cf6a5bcbd7ff709
-commit 8aa2f9aeb56506dca996d68ab90ab9c0bebd7ec3
+commit 207648d7a6415dc915260ca75850404dbf9f0a0b
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Jul 14 11:26:50 2021 +1000
+Date: Wed Sep 29 20:03:58 2021 +1000
- Make whitespace consistent.
+ Include stdlib.h for arc4random_uniform prototype.
-commit 4f4297ee9b8a39f4dfd243a74c5f51f9e7a05723
+commit 696aadc854582c164d5fc04933d2f3e212dc0e06
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Jul 14 11:26:12 2021 +1000
+Date: Wed Sep 29 20:00:30 2021 +1000
- Add ARM64 Linux self-hosted runner.
+ Look for clang after cc and gcc.
-commit eda8909d1b0a85b9c3804a04d03ec6738fd9dc7f
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Jul 13 23:48:36 2021 +0000
+commit a3c6375555026d85dbf811fab566b9f76f196144
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Sep 29 19:30:59 2021 +1000
- 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@
+ Use backticks instead of $(..) for portability.
- OpenBSD-Commit-ID: 726ee931dd4c5cc7f1d7a187b26f41257f9a2d12
+ Older shells (eg /bin/sh on Solaris 10) don't support $() syntax.
-commit 7ae69f2628e338ba6e0eae7ee8a63bcf8fea7538
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Jul 12 02:12:22 2021 +0000
+commit 958aaa0387133d51f84fe9c8f30bca03025f2867
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Sep 29 18:53:32 2021 +1000
- upstream: fix some broken tests; clean up output
+ Skip file-based tests by default on Mac OS.
- OpenBSD-Regress-ID: 1d5038edb511dc4ce1622344c1e724626a253566
+ The file-based tests need OpenSSL so skip them.
-commit f5fc6a4c3404bbf65c21ca6361853b33d78aa87e
+commit 55c8bdf6e9afb0f9fa8e4f10c25c7f0081b48fd0
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Mon Jul 12 18:00:05 2021 +1000
+Date: Wed Sep 29 18:42:47 2021 +1000
- Add configure-time detection for SSH_TIME_T_MAX.
+ Build without OpenSSL on Mac OS.
- 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.
+ Modern versions don't ship enough libcrypto to build against.
-commit fd2d06ae4442820429d634c0a8bae11c8e40c174
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Mon Jul 12 06:22:57 2021 +0000
+commit c9172193ea975415facf0afb356d87df21535f88
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Sep 29 18:33:38 2021 +1000
- 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@.
+ Remove TEST_SSH_ECC.
- OpenBSD-Commit-ID: 835936f6837c86504b07cabb596b613600cf0f6e
+ Convert the only remaining user of it to runtime detection using ssh -Q.
-commit 6c29b387cd64a57b0ec8ae7d2c8d02789d88fcc3
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Mon Jul 12 06:08:57 2021 +0000
+commit 5e6d28b7874b0deae95d2c68947c45212d32e599
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Sep 29 17:48:09 2021 +1000
- upstream: Use existing format_absolute_time() function when
-
- printing cert validity instead of doing it inline. Part of bz#3329.
-
- OpenBSD-Commit-ID: a13d4e3c4f59644c23745eb02a09b2a4e717c00c
+ Split c89 test openssl setting out.
-commit 99981d5f8bfa383791afea03f6bce8454e96e323
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jul 9 09:55:56 2021 +0000
+commit c4ac7f98e230e83c015678dc958b1ffe828564ad
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Sep 29 17:40:50 2021 +1000
- upstream: silence redundant error message; reported by Fabian Stelzer
-
- OpenBSD-Commit-ID: 9349a703016579a60557dafd03af2fe1d44e6aa2
+ Expand TEST_SHELL consistently with other vars.
-commit e86097813419b49d5bff5c4b51d1c3a5d4d2d804
-Author: John Ericson <John.Ericson@Obsidian.Systems>
-Date: Sat Dec 26 11:40:49 2020 -0500
+commit cfe5f7b0eb7621bfb0a756222de0431315c2ab8b
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Sep 29 17:26:50 2021 +1000
- Re-indent krb5 section after pkg-config addition.
+ Replace `pwd` with make variable in regress cmd.
-commit 32dd2daa56c294e40ff7efea482c9eac536d8cbb
-Author: John Ericson <John.Ericson@Obsidian.Systems>
-Date: Sat Dec 26 11:40:49 2020 -0500
+commit 899be59da5fbc3372444bd0fbe74af48313bed33
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Sep 29 17:14:33 2021 +1000
- Support finding Kerberos via pkg-config
+ Get BUILDDIR from autoconf.
- This makes cross compilation easier.
+ Use this to replace `pwd`s in regress test command line.
-commit def7a72234d7e4f684d72d33a0f7229f9eee0aa4
+commit c8d92d3d4f7d560146f2f936156ec4dac3fc5811
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Jul 9 14:34:06 2021 +1000
+Date: Wed Sep 29 13:28:56 2021 +1000
- Update comments about EGD to include prngd.
+ Add make clean step to tests.
-commit b5d23150b4e3368f4983fd169d432c07afeee45a
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Mon Jul 5 01:21:07 2021 +0000
+commit 360fb41ef8359619ab90b0d131c914494e55d3dd
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Sep 29 11:36:13 2021 +1000
- upstream: Fix a couple of whitespace things. Portable already has
-
- these so this removes two diffs between the two.
-
- OpenBSD-Commit-ID: 769f017ebafd8e741e337b3e9e89eb5ac73c9c56
+ Test all available clang and gcc versions.
-commit 8f57be9f279b8e905f9883066aa633c7e67b31cf
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Mon Jul 5 01:16:46 2021 +0000
+commit 4fb49899d7da22952d35a4bc4c9bdb2311087893
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Sep 29 01:32:21 2021 +0000
- upstream: Order includes as per style(9). Portable already has
-
- these so this removes a handful of diffs between the two.
+ upstream: Test certificate hostkeys held in ssh-agent too. Would have
- 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
+ caught regression fixed in sshd r1.575
- RhostsRSAAuthentication. ok djm@
+ ok markus@
- OpenBSD-Commit-ID: 3d864bfbd99a1d4429a58e301688f3be464827a9
+ OpenBSD-Regress-ID: 1f164d7bd89f83762db823eec4ddf2d2556145ed
-commit b67eb12f013c5441bb4f0893a97533582ad4eb13
+commit ce4854e12e749a05646e5775e9deb8cfaf49a755
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Jul 5 00:25:42 2021 +0000
+Date: Wed Sep 29 01:33:32 2021 +0000
- upstream: allow spaces to appear in usernames for local to remote,
+ upstream: add some debug output showing how many key file/command lines
- and scp -3 remote to remote copies. with & ok dtucker bz#1164
+ were processed. Useful to see whether a file or command actually has keys
+ present
- OpenBSD-Commit-ID: e9b550f3a85ffbb079b6720833da31317901d6dd
+ OpenBSD-Commit-ID: 0bd9ff94e84e03a22df8e6c12f6074a95d27f23c
-commit 8c4ef0943e574f614fc7c6c7e427fd81ee64ab87
+commit 15abdd523501c349b703d9a27e2bb4252ad921ef
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Jul 2 07:20:44 2021 +0000
+Date: Tue Sep 28 11:14:50 2021 +0000
- upstream: Remove obsolete comments about SSHv1 auth methods. ok
+ upstream: Make prototype for rijndaelEncrypt match function
- djm@
+ including the bounds. Fixes error in portable where GCC>=11 takes notice of
+ the bounds. ok deraadt@
- OpenBSD-Commit-ID: 6060f70966f362d8eb4bec3da2f6c4712fbfb98f
+ OpenBSD-Commit-ID: cdd2f05fd1549e1786a70871e513cf9e9cf099a6
-commit 88908c9b61bcb99f16e8d398fc41e2b3b4be2003
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Jul 3 23:00:19 2021 +1000
+commit d1d29ea1d1ef1a1a54b209f062ec1dcc8399cf03
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Tue Sep 28 11:10:05 2021 +0000
- Remove reference to ChallengeResponse.
+ upstream: Import regenerated moduli.
- challenge_response_authentication was removed from the struct, keeping
- kbd_interactive_authentication.
+ OpenBSD-Commit-ID: 4bec5db13b736b64b06a0fca704cbecc2874c8e1
-commit 321874416d610ad2158ce6112f094a4862c2e37f
+commit 39f2111b1d5f00206446257377dcce58cc72369f
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Jul 3 20:38:09 2021 +1000
+Date: Wed Sep 29 10:53:55 2021 +1000
- Move signal.h up include order to match upstream.
+ Add new compiler hardening flags.
+
+ Add -fzero-call-used-regs and -ftrivial-auto-var-init to the list of
+ compiler hardening flags that configure checks for. These are supported
+ by clang and gcc, and make ROP gadgets less useful and mitigate
+ stack-based infoleaks respectively. ok djm@
-commit 4fa83e2d0e32c2dd758653e0359984bbf1334f32
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Jul 3 20:36:06 2021 +1000
+commit bf944e3794eff5413f2df1ef37cddf96918c6bde
+Author: Damien Miller <djm@mindrot.org>
+Date: Mon Sep 27 00:03:19 2021 +1000
- Remove old OpenBSD version marker.
-
- Looks like an accidental leftover from a sync.
+ initgroups needs grp.h
-commit 9d5e31f55d5f3899b72645bac41a932d298ad73b
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Jul 3 20:34:19 2021 +1000
+commit 8c5b5655149bd76ea21026d7fe73ab387dbc3bc7
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sun Sep 26 14:01:11 2021 +0000
- Remove duplicate error on error path.
+ upstream: openssh-8.8
- There's an extra error() call on the listen error path, it looks like
- its removal was missed during an upstream sync.
+ OpenBSD-Commit-ID: 12357794602ac979eb7312a1fb190c453f492ec4
-commit 888c459925c7478ce22ff206c9ac1fb812a40caf
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Jul 3 20:32:46 2021 +1000
+commit f3cbe43e28fe71427d41cfe3a17125b972710455
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sun Sep 26 14:01:03 2021 +0000
- Remove some whitespace not in upstream.
+ upstream: need initgroups() before setresgid(); reported by anton@,
- Reduces diff vs OpenBSD by a small amount.
+ ok deraadt@
+
+ OpenBSD-Commit-ID: 6aa003ee658b316960d94078f2a16edbc25087ce
-commit 4d2d4d47a18d93f3e0a91a241a6fdb545bbf7dc2
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Jul 3 19:27:43 2021 +1000
+commit 8acaff41f7518be40774c626334157b1b1c5583c
+Author: Damien Miller <djm@mindrot.org>
+Date: Sun Sep 26 22:16:36 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.
+ update version numbers for release
-commit 53237ac789183946dac6dcb8838bc3b6b9b43be1
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Jul 3 19:23:28 2021 +1000
+commit d39039ddc0010baa91c70a0fa0753a2699bbf435
+Author: kn@openbsd.org <kn@openbsd.org>
+Date: Sat Sep 25 09:40:33 2021 +0000
- Sync remaining ChallengeResponse removal.
+ upstream: RSA/SHA-1 is not used by default anymore
- These were omitted from commit 88868fd131.
+ OK dtucker deraadt djm
+
+ OpenBSD-Commit-ID: 055c51a221c3f099dd75c95362f902da1b8678c6
-commit 2c9e4b319f7e98744b188b0f58859d431def343b
+commit 9b2ee74e3aa8c461eb5552a6ebf260449bb06f7e
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Jul 3 19:17:31 2021 +1000
+Date: Fri Sep 24 11:08:03 2021 +1000
- Disable rocky84 to figure out why agent test fails
+ Move the fgrep replacement to hostkey-rotate.sh.
+
+ The fgrep replacement for buggy greps doesn't work in the sftp-glob test
+ so move it to just where we know it's needed.
-commit bfe19197a92b7916f64a121fbd3c179abf15e218
+commit f7039541570d4b66d76e6f574544db176d8d5c02
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Jul 2 15:43:28 2021 +1000
+Date: Fri Sep 24 08:04:14 2021 +1000
- Remove now-unused SSHv1 enums.
+ Replacement function for buggy fgrep.
- sRhostsRSAAuthentication and sRSAAuthentication are protocol 1 options
- and are no longer used.
+ GNU (f)grep <=2.18, as shipped by FreeBSD<=12 and NetBSD<=9 will
+ occasionally fail to find ssh host keys in the hostkey-rotate test.
+ If we have those versions, use awk instead.
-commit c73b02d92d72458a5312bd098f32ce88868fd131
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Jul 2 05:11:20 2021 +0000
+commit f6a660e5bf28a01962af87568e118a2d2e79eaa0
+Author: David Manouchehri <david.manouchehri@riseup.net>
+Date: Thu Sep 23 17:03:18 2021 -0400
- 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
+ Don't prompt for yes/no questions.
-commit f841fc9c8c7568a3b5d84a4cc0cefacb7dbc16b9
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Jul 2 15:20:32 2021 +1000
+commit 7ed1a3117c09f8c3f1add35aad77d3ebe1b85b4d
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Sep 20 06:53:56 2021 +0000
- Fix ifdefs around get_random_bytes_prngd.
+ upstream: fix missing -s in SYNOPSYS and usage() as well as a
+
+ capitalisation mistake; spotted by jmc@
- get_random_bytes_prngd() is used if either of PRNGD_PORT or PRNGD_SOCKET
- are defined, so adjust ifdef accordingly.
+ OpenBSD-Commit-ID: 0ed8ee085c7503c60578941d8b45f3a61d4c9710
-commit 0767627cf66574484b9c0834500b42ea04fe528a
-Author: Damien Miller <djm@mindrot.org>
-Date: Fri Jul 2 14:30:23 2021 +1000
+commit 8c07170135dde82a26886b600a8bf6fb290b633d
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Mon Sep 20 04:02:13 2021 +0000
- wrap get_random_bytes_prngd() in ifdef
+ upstream: Fix "Allocated port" debug message
- avoid unused static function warning
+ for unix domain sockets. From peder.stray at gmail.com via github PR#272,
+ ok deraadt@
+
+ OpenBSD-Commit-ID: 8d5ef3fbdcdd29ebb0792b5022a4942db03f017e
-commit f93fdc4de158386efe1116bd44c5b3f4a7a82c25
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Mon Jun 28 13:06:37 2021 +1000
+commit 277d3c6adfb128b4129db08e3d65195d94b55fe7
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Sep 20 01:55:42 2021 +0000
- Add rocky84 test target.
+ upstream: Switch scp back to use the old protocol by default, ahead of
+
+ release. We'll wait a little longer for people to pick up sftp-server(8) that
+ supports the extension that scp needs for ~user paths to continue working in
+ SFTP protocol mode. Discussed with deraadt@
+
+ OpenBSD-Commit-ID: f281f603a705fba317ff076e7b11bcf2df941871
-commit d443006c0ddfa7f6a5bd9c0ae92036f3d5f2fa3b
+commit ace19b34cc15bea3482be90450c1ed0cd0dd0669
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jun 25 06:30:22 2021 +0000
+Date: Sat Sep 18 02:03:25 2021 +0000
- upstream: fix decoding of X.509 subject name; from Leif Thuresson
+ upstream: better error message for ~user failures when the
- via bz3327 ok markus@
+ sftp-server lacks the expand-path extension; ok deraadt@
- OpenBSD-Commit-ID: 0ea2e28f39750dd388b7e317bc43dd997a217ae8
+ OpenBSD-Commit-ID: 9c1d965d389411f7e86f0a445158bf09b8f9e4bc
-commit 2a5704ec142202d387fda2d6872fd4715ab81347
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Jun 25 06:20:39 2021 +0000
+commit 6b1238ba971ee722a310d95037b498ede5539c03
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Sep 16 15:22:22 2021 +0000
- upstream: Use better language to refer to the user. From l1ving
+ upstream: make some more scp-in-SFTP mode better match Unix idioms
- via github PR#250, ok jmc@
+ suggested by deraadt@
- OpenBSD-Commit-ID: 07ca3526626996613e128aeddf7748c93c4d6bbf
+ OpenBSD-Commit-ID: 0f2439404ed4cf0b0be8bf49a1ee734836e1ac87
-commit 4bdf7a04797a0ea1c431a9d54588417c29177d19
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Jun 25 03:38:17 2021 +0000
+commit e694f8ac4409931e67d08ac44ed251b20b10a957
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Sep 16 15:11:19 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.
+ upstream: allow log_stderr==2 to prefix log messages with argv[0]
- In -portable, for platforms that do not have pselect the kludge is still
- there but is hidden behind a pselect interface.
+ use this to make scp's SFTP mode error messages more scp-like
- Based on other changes for bz#2158, ok djm@
+ prompted by and ok deraadt@
- OpenBSD-Commit-ID: 202c85de0b3bdf1744fe53529a05404c5480d813
+ OpenBSD-Commit-ID: 0e821dbde423fc2280e47414bdc22aaa5b4e0733
-commit c9f7bba2e6f70b7ac1f5ea190d890cb5162ce127
+commit 8a7a06ee505cb833e613f74a07392e9296286c30
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Jun 25 15:08:18 2021 +1000
+Date: Fri Sep 17 13:03:31 2021 +1000
- Move closefrom() to before first malloc.
+ Test against LibreSSL 3.2.6, 3.3.4, 3.4.0.
+
+commit c25c84074a47f700dd6534995b4af4b456927150
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Sep 16 05:36:03 2021 +0000
+
+ upstream: missing space character in ssh -G output broke the
- 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@
+ t-sshcfgparse regression test; spotted by anton@
+
+ OpenBSD-Commit-ID: bcc36fae2f233caac4baa8e58482da4aa350eed0
-commit 7ebfe4e439853b88997c9cfc2ff703408a1cca92
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Jun 18 20:41:45 2021 +1000
+commit a4bee1934bf5e5575fea486628f4123d6a29dff8
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Sep 15 06:56:01 2021 +0000
- Put second -lssh in link line for sftp-server.
+ upstream: allow CanonicalizePermittedCNAMEs=none in ssh_config; ok
- 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.
+ markus@
+
+ OpenBSD-Commit-ID: 668a82ba8e56d731b26ffc5703213bfe071df623
-commit e409d7966785cfd9f5970e66a820685c42169717
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Jun 18 18:34:08 2021 +1000
+commit d0fffc88c8fe90c1815c6f4097bc8cbcabc0f3dd
+Author: mbuhl@openbsd.org <mbuhl@openbsd.org>
+Date: Tue Sep 14 11:04:21 2021 +0000
- Try EGD/PRNGD if random device fails.
+ upstream: put back the mux_ctx memleak fix for SSH_CHANNEL_MUX_CLIENT
- When built --without-openssl, try EGD/PRGGD (if configured) as a last
- resort before failing.
+ OK mfriedl@
+
+ OpenBSD-Commit-ID: 1aba1da828956cacaadb81a637338734697d9798
-commit e43a898043faa3a965dbaa1193cc60e0b479033d
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Jun 18 18:32:51 2021 +1000
+commit 19b3d846f06697c85957ab79a63454f57f8e22d6
+Author: schwarze@openbsd.org <schwarze@openbsd.org>
+Date: Sat Sep 11 09:05:50 2021 +0000
- Split EGD/PRNGD interface into its own file.
+ upstream: Do not ignore SIGINT while waiting for input if editline(3)
- This will allow us to use it when building --without-openssl.
+ is not used. Instead, in non-interactive mode, exit sftp(1), like for other
+ serious errors. As pointed out by dtucker@, when compiled without editline(3)
+ support in portable OpenSSH, the el == NULL branch is also used for
+ interactive mode. In that case, discard the input line and provide a fresh
+ prompt to the user just like in the case where editline(3) is used. OK djm@
+
+ OpenBSD-Commit-ID: 7d06f4d3ebba62115527fafacf38370d09dfb393
-commit acb2887a769a1b1912cfd7067f3ce04fad240260
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Jun 17 21:03:19 2021 +1000
+commit ba61123eef9c6356d438c90c1199a57a0d7bcb0a
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Sep 11 00:40:24 2021 +0000
- Handle GIDs > 2^31 in getgrouplist.
+ upstream: when using SFTP protocol, continue transferring files after a
- 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.
+ transfer error occurs. This matches original scp/rcp behaviour. ok dtucker@
+
+ OpenBSD-Commit-ID: dfe4558d71dd09707e9b5d6e7d2e53b793da69fa
-commit 31fac20c941126281b527605b73bff30a8f02edd
+commit b0ec59a708b493c6f3940336b1a537bcb64dd2a7
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Thu Jun 10 09:46:28 2021 +0000
+Date: Fri Sep 10 11:38:38 2021 +0000
- upstream: Use $SUDO when reading sshd's pidfile here too.
+ upstream: Document that non-interactive commands are run via the user's
- OpenBSD-Regress-ID: 6bfb0d455d493f24839034a629c5306f84dbd409
+ shell using the -c flag. ok jmc@
+
+ OpenBSD-Commit-ID: 4f0d912077732eead10423afd1acf4fc0ceec477
-commit a3a58acffc8cc527f8fc6729486d34e4c3d27643
+commit 66a658b5d9e009ea11f8a0ca6e69c7feb2d851ea
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Thu Jun 10 09:43:51 2021 +0000
+Date: Fri Sep 10 10:26:02 2021 +0000
- upstream: Use $SUDO when reading sshd's pidfile in case it was
+ upstream: Document behaviour of arguments following non-interactive
- created with a very restrictive umask. This resyncs with -portable.
+ commands. Prompted by github PR#139 from EvanTheB, feedback & ok djm@ jmc@
- OpenBSD-Regress-ID: 07fd2af06df759d4f64b82c59094accca1076a5d
+ OpenBSD-Commit-ID: fc758d1fe0471dfab4304fcad6cd4ecc3d79162a
-commit 249ad4ae51cd3bc235e75a4846eccdf8b1416611
+commit 1d47e28e407d1f95fdf8f799be23f48dcfa5206b
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Thu Jun 10 09:37:59 2021 +0000
+Date: Fri Sep 10 07:11:11 2021 +0000
- upstream: Set umask when creating hostkeys to prevent excessive
+ upstream: Clarify which file's attributes -p preserves, and that
- permissions warning.
+ it's specifically the file mode bits. bz#3340 from calestyo at scientia.net,
+ ok djm@ jmc@
- OpenBSD-Regress-ID: 382841db0ee28dfef7f7bffbd511803e1b8ab0ef
+ OpenBSD-Commit-ID: f09e6098ed1c4be00c730873049825f8ee7cb884
-commit 9d0892153c005cc65897e9372b01fa66fcbe2842
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Thu Jun 10 03:45:31 2021 +0000
+commit b344db7a413478e4c21e4cadba4a970ad3e6128a
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Sep 10 05:46:09 2021 +0000
- upstream: Add regress test for SIGHUP restart
+ upstream: openssh-7.4 was incorrectly listed twice; spotted by
- while handling active and unauthenticated clients. Should catch anything
- similar to the pselect bug just fixed in sshd.c.
+ Dmitry Belyavskiy, ok dtucker@
- OpenBSD-Regress-ID: 3b3c19b5e75e43af1ebcb9586875b3ae3a4cac73
+ OpenBSD-Commit-ID: 4b823ae448f6e899927ce7b04225ac9e489f58ef
-commit 73f6f191f44440ca3049b9d3c8e5401d10b55097
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Thu Jun 10 03:14:14 2021 +0000
+commit 9136d6239ad7a4a293e0418a49b69e70c76d58b8
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Thu Sep 9 06:17:39 2021 +0000
- upstream: Continue accept loop when pselect
+ upstream: - move CAVEATS to its correct order - use the term
- 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@
+ "legacy" protocol rather than "original", as the latter made the text
+ misleading - uppercase SCP
- OpenBSD-Commit-ID: 0243c1c5544fca0974dae92cd4079543a3fceaa0
+ ok djm
+
+ OpenBSD-Commit-ID: 8479255746d5fa76a358ee59e7340fecf4245ff0
-commit c785c0ae134a8e8b5c82b2193f64c632a98159e4
+commit 2d678c5e3bdc2f5c99f7af5122e9d054925d560d
+Author: David Carlier <devnexen@gmail.com>
+Date: Wed Sep 8 19:49:54 2021 +0100
+
+ Disable tracing on FreeBSD using procctl.
+
+ Placed at the start of platform_disable_tracing() to prevent declaration
+ after code errors from strict C89 compilers (in the unlikely event that
+ more than one method is enabled).
+
+commit 73050fa38fb36ae3326d768b574806352b97002d
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Jun 8 22:30:27 2021 +0000
+Date: Wed Sep 8 23:31:39 2021 +0000
- upstream: test that UserKnownHostsFile correctly accepts multiple
+ upstream: Use the SFTP protocol by default. The original scp/rcp
- arguments; would have caught readconf.c r1.356 regression
+ protocol remains available via the -O flag.
- OpenBSD-Regress-ID: 71ca54e66c2a0211b04999263e56390b1f323a6a
+ Note that ~user/ prefixed paths in SFTP mode require a protocol extension
+ that was first shipped in OpenSSH 8.7.
+
+ ok deraadt, after baking in snaps for a while without incident
+
+ OpenBSD-Commit-ID: 23588976e28c281ff5988da0848cb821fec9213c
-commit 1a6f6b08e62c78906a3032e8d9a83e721c84574e
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Jun 8 22:06:12 2021 +0000
+commit c4565e69ffa2485cff715aa842ea7a350296bfb6
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Sep 8 21:09:49 2021 +1000
+
+ Really fix test on OpenSSL 1.1.1 stable.
+
+commit 79f1bb5f56cef3ae9276207316345b8309248478
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Sep 8 18:51:39 2021 +1000
+
+ Correct OpenSSL 1.1.1 stable identifier.
+
+commit b6255593ed5ccbe5e7d3d4b26b2ad31ad4afc232
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Sep 8 18:39:44 2021 +1000
- 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@
+ Increment nfds when coming from startup_pipe.
- OpenBSD-Commit-ID: 7cbf182f7449bf1cb7c5b4452667dc2b41170d6d
+ If we have to increase nfds because startup_pipe[0] is above any of the
+ descriptors passed in the fd_sets, we also need to add 1 to nfds since
+ select takes highest FD number plus one. bz#3345 from yaroslav.kuzmin
+ at vmssoftware.com.
-commit 78e30af3e2b2dd540a341cc827c6b98dd8b0a6de
+commit a3e92a6794817df6012ac8546aea19652cc91b61
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Sep 8 13:45:10 2021 +1000
+
+ Tests for OpenSSL 3.0.0 release & 1.1.1 branch.
+
+commit 4afe431da98ec1cf6a2933fe5658f4fd68dee9e2
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Jun 8 07:40:12 2021 +0000
+Date: Wed Sep 8 03:23:44 2021 +0000
- upstream: test argv_split() optional termination on comments
+ upstream: correct my mistake in previous fix; spotted by halex
- OpenBSD-Regress-ID: 9fd1c4a27a409897437c010cfd79c54b639a059c
+ OpenBSD-Commit-ID: 3cc62d92e3f70006bf02468fc146bfc36fffa183
-commit a023138957ea2becf1c7f93fcc42b0aaac6f2b03
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Tue Jun 8 07:05:27 2021 +0000
+commit ca0e455b9331213ff9505a21b94c38e34faa2bba
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Sep 7 06:03:51 2021 +0000
- upstream: Add testcases from bz#3319 for IPQoS and TunnelDevice
+ upstream: avoid NULL deref in -Y find-principals. Report and fix
- being overridden on the command line.
+ from Carlo Marcelo Arenas Belón
+ MIME-Version: 1.0
+ Content-Type: text/plain; charset=UTF-8
+ Content-Transfer-Encoding: 8bit
- OpenBSD-Regress-ID: 801674d5d2d02abd58274a78cab2711f11de14a8
+ OpenBSD-Commit-ID: 6238486f8ecc888d6ccafcd9ad99e621bb41f1e0
-commit 660cea10b2cdc11f13ba99c89b1bbb368a4d9ff2
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Jun 8 06:52:43 2021 +0000
+commit 37616807f150fb46610bbd5031c31af4857ad1e9
+Author: millert@openbsd.org <millert@openbsd.org>
+Date: Mon Sep 6 00:36:01 2021 +0000
- upstream: sprinkle some "# comment" at end of configuration lines
+ upstream: revision 1.381 neglected to remove
- to test comment handling
+ sChallengeResponseAuthentication from the enum. Noticed by
+ christos@zoulas.com. OK dtucker@
- OpenBSD-Regress-ID: cb82fbf40bda5c257a9f742c63b1798e5a8fdda7
+ OpenBSD-Commit-ID: b533283a4dd6d04a867da411a4c7a8fbc90e34ff
-commit acc9c32dcb6def6c7d3688bceb4c0e59bd26b411
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Jun 8 06:51:47 2021 +0000
+commit 7acb3578cdfec0b3d34501408071f7a96c1684ea
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sun Sep 5 20:45:42 2021 +1000
- upstream: more descriptive failure message
-
- OpenBSD-Regress-ID: 5300f6faf1d9e99c0cd10827b51756c5510e3509
+ Correct version_num for OpenSSL dev branch.
-commit ce04dd4eae23d1c9cf7c424a702f48ee78573bc1
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Jun 7 01:16:34 2021 +0000
+commit 65bb01111320dfd0d25e21e1fd4d3f2b77532669
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sun Sep 5 19:37:39 2021 +1000
- upstream: test AuthenticationMethods inside a Match block as well
-
- as in the main config section
+ Test against OpenSSL 3 branch as well as dev.
- OpenBSD-Regress-ID: ebe0a686621b7cb8bb003ac520975279c28747f7
+ Now that OpenSSL development has moved to 3.1, test against the most
+ recent version of the openssl-3.0 branch too.
-commit 9018bd821fca17e26e92f7a7e51d9b24cd62f2db
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Jun 7 00:00:50 2021 +0000
+commit 864ed0d5e04a503b97202c776b7cf3f163f3eeaa
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sun Sep 5 19:33:22 2021 +1000
- 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
+ OpenSSL development is now 3.1.*
-commit a10f929d1ce80640129fc5b6bc1acd9bf689169e
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Jun 8 07:09:42 2021 +0000
+commit a60209a586a928f92ab323bf23bd07f57093342e
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Sep 3 07:43:23 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@
+ upstream: Use .Cm instead of .Dq in StrictHostKeyChecking list for
- tested in snaps for the last five or so days - thanks Theo and those who
- caught bugs
+ consistency. Patch from scop via github PR#257, ok jmc@
- OpenBSD-Commit-ID: 9c4305631d20c2d194661504ce11e1f68b20d93e
+ OpenBSD-Commit-ID: 3652a91564570779431802c31224fb4a9cf39872
-commit ea9e45c89a4822d74a9d97fef8480707d584da4d
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Jun 8 07:07:15 2021 +0000
+commit 8d1d9eb6de37331e872700e9e399a3190cca1242
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Sep 3 07:27:03 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@
+ upstream: Mention using ssh -i for specifying the public key file
- tested in snaps for the last five or so days - thanks Theo and those who
- caught bugs
+ in the case where the private key is loaded into ssh-agent but is not present
+ locally. Based on patch from rafork via github PR#215, ok jmc@
- OpenBSD-Commit-ID: dc72fd12af9d5398f4d9e159d671f9269c5b14d5
+ OpenBSD-Commit-ID: 2282e83b0ff78d2efbe705883b67240745fa5bb2
-commit d786424986c04d1d375f231fda177c8408e05c3e
+commit eb4362e5e3aa7ac26138b11e44d8c191910aff64
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Tue Jun 8 07:02:46 2021 +0000
+Date: Fri Sep 3 05:25:50 2021 +0000
- upstream: Check if IPQoS or TunnelDevice are already set before
+ upstream: Refer to KEX "algorithms" instead of "methods" to match
- overriding. Prevents values in config files from overriding values supplied
- on the command line. bz#3319, ok markus.
+ other references and improve consistency. Patch from scop via github PR#241,
+ ok djm@
- OpenBSD-Commit-ID: f3b08b898c324debb9195e6865d8999406938f74
+ OpenBSD-Commit-ID: 840bc94ff6861b28d8603c8e8c16499bfb65e32c
-commit aae4b4d3585b9f944d7dbd3c9e5ba0006c55e457
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Jun 8 06:54:40 2021 +0000
+commit b3318946ce5725da43c4bf7eeea1b73129c47d2a
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Sep 3 05:12:25 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.
+ upstream: Remove redundant attrib_clear in upload_dir_internal.
- ok markus@ as part of a larger diff; tested in snaps
+ The subsequent call to stat_to_attrib clears the struct as its first step
+ anyway. From pmeinhardt via github PR#220, ok djm@
- 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.
+ OpenBSD-Commit-ID: f5234fc6d7425b607e179acb3383f21716f3029e
-commit d45b9c63f947ec5ec314696e70281f6afddc0ac3
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Jun 7 03:38:38 2021 +0000
+commit 7cc3fe28896e653956a6a2eed0a25d551b83a029
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Sep 3 04:11:13 2021 +0000
- upstream: fix debug message when finding a private key to match a
+ upstream: Add test for client termination status on signal.
- 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
+ Based on patch from Alexxz via github PR#235 with some tweaks, to
+ match patch in bz#3281.
- OpenBSD-Commit-ID: d5af3be66d0f22c371dc1fe6195e774a18b2327b
+ OpenBSD-Regress-ID: d87c7446fb8b5f8b45894fbbd6875df326e729e2
-commit 530739d42f6102668aecd699be0ce59815c1eceb
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Jun 6 11:34:16 2021 +0000
+commit 5428b0d239f6b516c81d1dd15aa9fe9e60af75d4
+Author: deraadt@openbsd.org <deraadt@openbsd.org>
+Date: Thu Sep 2 21:03:54 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@
+ upstream: sys/param.h is not needed for any visible reason
- OpenBSD-Commit-ID: 25f5bf70003126d19162862d9eb380bf34bac22a
+ OpenBSD-Commit-ID: 8bdea2d0c75692e4c5777670ac039d4b01c1f368
-commit 4265215d7300901fd7097061c7517688ade82f8e
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Jun 6 03:40:39 2021 +0000
+commit 1ff38f34b4c4545eb28106629cafa1e0496bc726
+Author: Shchelkunov Artem <a.shchelkunov@ideco.ru>
+Date: Wed Aug 11 18:07:58 2021 +0500
- 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
+ Fix memory leak in error path.
- OpenBSD-Commit-ID: d6d0b7351d5d44c45f3daaa26efac65847a564f7
+ *info is allocated via xstrdup but was leaked in the PAM_AUTH_ERR path.
+ From github PR#266.
-commit bda270d7fb8522d43c21a79a4b02a052d7c64de8
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Jun 6 03:17:02 2021 +0000
+commit cb37e2f0c0ca4fef844ed7edc5d0e3b7d0e83f6a
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Wed Sep 1 03:16:06 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
+ upstream: Fix ssh-rsa fallback for old PuTTY interop tests.
- OpenBSD-Commit-ID: bd9d1839c41811616ede4da467e25746fcd9b967
+ OpenBSD-Regress-ID: a19ac929da604843a5b5f0f48d2c0eb6e0773d37
-commit d345d5811afdc2d6923019b653cdd93c4cc95f76
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Jun 6 03:15:39 2021 +0000
+commit 8b02ef0f28dc24cda8cbcd8b7eb02bda8f8bbe59
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Wed Sep 1 00:50:27 2021 +0000
- upstream: the limits@openssh.com extension was incorrectly marked
+ upstream: Add a function to skip remaining tests.
- as an operation that writes to the filesystem, which made it unavailable in
- sftp-server read-only mode. Spotted by Hector Martin via bz3318
+ Many tests skip tests for various reasons but not in a consistent way and
+ don't always clean up, so add that and switch the tests that do that over.
- OpenBSD-Commit-ID: f054465230787e37516c4b57098fc7975e00f067
+ OpenBSD-Regress-ID: 72d2ec90a3ee8849486956a808811734281af735
-commit 2b71010d9b43d7b8c9ec1bf010beb00d98fa765a
-Author: naddy@openbsd.org <naddy@openbsd.org>
-Date: Sat Jun 5 13:47:00 2021 +0000
+commit d486845c07324c04240f1674ac513985bd356f66
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Tue Aug 31 07:13:59 2021 +0000
- upstream: PROTOCOL.certkeys: update reference from IETF draft to
-
- RFC
+ upstream: Specify path to PuTTY keys.
- Also fix some typos.
- ok djm@
+ Portable needs this and it makes no difference on OpenBSD, so resync
+ them. (Id sync only, Portable already had this.)
- OpenBSD-Commit-ID: 5e855b6c5a22b5b13f8ffa3897a868e40d349b44
+ OpenBSD-Regress-ID: 33f6f66744455886d148527af8368811e4264162
-commit aa99b2d9a3e45b943196914e8d8bf086646fdb54
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Jun 4 23:41:29 2021 +1000
+commit d22b299115e27606e846b23490746f69fdd4fb38
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Tue Aug 31 06:13:23 2021 +0000
- Clear notify_pipe from readset if present.
+ upstream: Better compat tests with old PuTTY.
- Prevents leaking an implementation detail to the caller.
+ When running PuTTY interop tests and using a PuTTY version older than
+ 0.76, re-enable the ssh-rsa host key algorithm (the 256 and 512 variants
+ of RSA were added some time between 0.73 and 0.76).
+
+ OpenBSD-Regress-ID: e6138d6987aa705fa1e4f216db0bb386e1ff38e1
-commit 6de8dadf6b4d0627d35bca0667ca44b1d61c2c6b
+commit 87ad70d605c3e39c9b8aa275db27120d7cc09b77
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Jun 4 23:24:25 2021 +1000
+Date: Tue Aug 31 17:04:50 2021 +1000
- space->tabs.
+ Resync PuTTY interop tests.
+
+ Resync behaviour when REGRESS_INTEROP_PUTTY is not set with OpenBSD.
-commit c8677065070ee34c05c7582a9c2f58d8642e552d
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Jun 4 18:39:48 2021 +1000
+commit e47b82a7bf51021afac218bf59a3be121827653d
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Tue Aug 31 01:25:27 2021 +0000
- Add pselect implementation for platforms without.
+ upstream: Specify hostkeyalgorithms in SSHFP test.
- 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.
+ Specify host key algorithms in sshd's default set for the SSHFP test,
+ from djm@. Make the reason for when the test is skipped a bit clearer.
- 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.
+ OpenBSD-Regress-ID: 4f923dfc761480d5411de17ea6f0b30de3e32cea
-commit 7cd7f302d3a072748299f362f9e241d81fcecd26
-Author: Vincent Brillault <vincent.brillault@cern.ch>
-Date: Sun May 24 09:15:06 2020 +0200
+commit 7db3e0a9e8477c018757b59ee955f7372c0b55fb
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Aug 30 01:15:45 2021 +0000
- auth_log: dont log partial successes as failures
+ upstream: adapt to RSA/SHA1 deprectation
- 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.
+ OpenBSD-Regress-ID: 952397c39a22722880e4de9d1c50bb1a14f907bb
-commit e7606919180661edc7f698e6a1b4ef2cfb363ebf
+commit 2344750250247111a6c3c6a4fe84ed583a61cc11
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jun 4 06:19:07 2021 +0000
+Date: Sun Aug 29 23:53:10 2021 +0000
- upstream: The RB_GENERATE_STATIC(3) macro expands to a series of
+ upstream: After years of forewarning, disable the RSA/SHA-1
- function definitions and not a statement, so there should be no semicolon
- following them. Patch from Michael Forney
+ signature algorithm by default. It is feasible to create colliding SHA1
+ hashes, so we need to deprecate its use.
- 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
+ RSA/SHA-256/512 remains available and will be transparently selected
+ instead of RSA/SHA1 for most SSH servers released in the last five+
+ years. There is no need to regenerate RSA keys.
- stuff, de-wrapping the example lines and better aligning the examples with
- common usage and FAQs; ok jmc
+ The use of RSA/SHA1 can be re-enabled by adding "ssh-rsa" to the
+ PubkeyAcceptedAlgorithms directives on the client and server.
- OpenBSD-Commit-ID: d59f1c9281f828148e2a2e49eb9629266803b75c
+ ok dtucker deraadt
+
+ OpenBSD-Commit-ID: 189bcc4789c7254e09e23734bdd5def8354ff1d5
-commit d9cb35bbec5f623589d7c58fc094817b33030f35
+commit 56c4455d3b54b7d481c77c82115c830b9c8ce328
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jun 4 05:10:03 2021 +0000
+Date: Sun Aug 29 23:44:07 2021 +0000
- upstream: adjust SetEnv description to clarify $TERM handling
+ upstream: wrap at 80 columns
- OpenBSD-Commit-ID: 8b8cc0124856bc1094949d55615e5c44390bcb22
+ OpenBSD-Commit-ID: 47ca2286d6b52a9747f34da16d742879e1a37bf0
-commit 771f57a8626709f2ad207058efd68fbf30d31553
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Jun 4 05:09:08 2021 +0000
+commit 95401eea8503943449f712e5f3de52fc0bc612c5
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Aug 20 18:14:13 2021 +1000
- 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@
+ Replace shell function with ssh-keygen -A.
- OpenBSD-Commit-ID: bf85bf880fd78e00d7478657644fcda97b9a936f
+ Prevents the init script in the SysV package from trying (and failing)
+ to generate unsupported key types. Remove now-unused COMMENT_OUT_ECC.
+ ok tim@
-commit f64f8c00d158acc1359b8a096835849b23aa2e86
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jun 4 05:02:40 2021 +0000
+commit d83ec9ed995a76ed1d5c65cf10b447222ec86131
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Aug 20 15:39:05 2021 +1000
- 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
+ Remove obsolete Redhat PAM config and init script.
-commit 60107677dc0ce1e93c61f23c433ad54687fcd9f5
+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 Jun 4 04:02:21 2021 +0000
+Date: Fri Aug 20 03:22:55 2021 +0000
- upstream: correct extension name "no-presence-required" =>
-
- "no-touch-required"
-
- document "verify-required" option
+ upstream: openssh-8.7
- OpenBSD-Commit-ID: 1879ff4062cf61d79b515e433aff0bf49a6c55c5
+ OpenBSD-Commit-ID: 8769dff0fd76ae3193d77bf83b439adee0f300cd
-commit ecc186e46e3e30f27539b4311366dfda502f0a08
+commit 9a2ed62173cc551b2b5f479460bb015b19499de8
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Jun 2 13:54:11 2021 +1000
+Date: Fri Aug 20 10:48:13 2021 +1000
- Retire fbsd7 test target.
+ Also check pid in pselect_notify_setup.
- 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.
+ Spotted by djm@.
-commit 5de0867b822ec48b5eec9abde0f5f95d1d646546
+commit deaadcb93ca15d4f38aa38fb340156077792ce87
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Jun 2 11:21:40 2021 +1000
+Date: Fri Aug 20 08:39:33 2021 +1000
- Check for $OPENSSL in md5 fallback too.
+ Prefix pselect functions to clarify debug messages
-commit 1db69d1b6542f8419c04cee7fd523a4a11004be2
+commit 10e45654cff221ca60fd35ee069df67208fcf415
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
+Date: Fri Aug 20 08:30:42 2021 +1000
- upstream: Merge back shell portability changes
+ Fix race in pselect replacement code.
- bringing it back in sync with -portable.
+ 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.
- OpenBSD-Regress-ID: c07905ba931e66ad7d849b87b7d19648007175d1
+ 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 9d482295c9f073e84d75af46b720a1c0f7ec2867
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Tue Jun 1 23:56:20 2021 +0000
+commit 464ba22f1e38d25402e5ec79a9b8d34a32df5a3f
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Aug 18 12:51:30 2021 +1000
- 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.
+ Check compiler for c99 declarations after code.
- OpenBSD-Regress-ID: c49dcd6aa7602a8606b7afa192196ca1fa65de16
+ 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 07660b3c99f8ea74ddf4a440e55c16c9f7fb3dd1
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Mon May 24 10:25:18 2021 +0000
+commit 7d878679a4b155a359d32104ff473f789501748d
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Tue Aug 17 15:12:04 2021 +1000
- upstream: Find openssl binary via environment variable. This
+ 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.
- allows overriding if necessary (eg in -portable where we're testing against a
- specific version of OpenSSL).
+ 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.
- OpenBSD-Regress-ID: 491f39cae9e762c71aa4bf045803d077139815c5
+ - 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 1a4d1da9188d7c88f646b61f0d6a3b34f47c5439
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri May 21 04:03:47 2021 +0000
+commit b467cf13705f59ed348b620722ac098fe31879b7
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Aug 16 11:32:23 2021 +1000
- upstream: fix memleak in test
+ Remove deprecated ubuntu-16.04 test targets.
- OpenBSD-Regress-ID: 5e529d0982aa04666604936df43242e97a7a6f81
+ Github has deprecated ubuntu-16.04 and it will be removed on 20
+ September.
-commit 60455a5d98065a73ec9a1f303345856bbd49aecc
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri May 21 03:59:01 2021 +0000
+commit 20e6eefcdf78394f05e453d456c1212ffaa6b6a4
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sun Aug 15 23:25:26 2021 +1000
- upstream: also check contents of remaining string
-
- OpenBSD-Regress-ID: d526fa07253f4eebbc7d6205a0ab3d491ec71a28
+ Skip agent ptrace test on hurd.
-commit 39f6cd207851d7b67ca46903bfce4a9f615b5b1c
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri May 21 03:48:07 2021 +0000
+commit 7c9115bbbf958fbf85259a061c1122e2d046aabf
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sun Aug 15 19:37:22 2021 +1000
- upstream: unit test for misc.c:strdelim() that mostly servces to
-
- highlight its inconsistencies
-
- OpenBSD-Regress-ID: 8d2bf970fcc01ccc6e36a5065f89b9c7fa934195
+ Add hurd test target.
-commit 7a3a1dd2c7d4461962acbcc0ebee9445ba892be0
+commit 7909a566f6c6a78fcd30708dc49f4e4f9bb80ce3
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu May 27 21:23:15 2021 +1000
+Date: Sun Aug 15 12:45:10 2021 +1000
- Put minix3 config in the host-specific block.
+ Skip scp3 tests on all dfly58 and 60 configs.
-commit 59a194825f12fff8a7f75d91bf751ea17645711b
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon May 31 06:48:42 2021 +0000
+commit e65198e52cb03534e8c846d1bca74c310b1526de
+Author: Tim Rice <tim@multitalents.net>
+Date: Sat Aug 14 13:08:07 2021 -0700
- 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
+ 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 eb68e669bc8ab968d4cca5bf1357baca7136a826
+commit e50635640f79920d9375e0155cb3f4adb870eee5
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu May 27 21:14:15 2021 +1000
+Date: Fri Aug 13 13:21:00 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.
+ Test OpenSSH from OpenBSD head on 6.8 and 6.9.
-commit 2063af71422501b65c7a92a5e14c0e6a3799ed89
+commit e0ba38861c490c680117b7fe0a1d61a181cd00e7
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu May 27 21:13:38 2021 +1000
+Date: Fri Aug 13 13:00:14 2021 +1000
- Add minix3 test target.
+ Skip scp3 test on dragonfly 58 and 60.
+
+ The tests hang, so skip until we figure them out.
-commit 2e1efcfd9f94352ca5f4b6958af8a454f8cf48cd
+commit dcce2a2bcf007bf817a2fb0dce3db83fa9201e92
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed May 26 01:47:24 2021 +0000
+Date: Thu Aug 12 23:59:25 2021 +0000
- upstream: fix SEGV in UpdateHostkeys debug() message, triggered
+ upstream: mention that CASignatureAlgorithms accepts +/- similarly to
- when the update removed more host keys than remain present. Fix tested by
- reporter James Cook, via bugs@
+ the other algorithm list directives; ok jmc bz#3335
- OpenBSD-Commit-ID: 44f641f6ee02bb957f0c1d150495b60cf7b869d3
+ OpenBSD-Commit-ID: 0d46b53995817052c78e2dce9dbd133963b073d9
-commit 9acd76e6e4d2b519773e7119c33cf77f09534909
-Author: naddy@openbsd.org <naddy@openbsd.org>
-Date: Sun May 23 18:22:57 2021 +0000
+commit 090a82486e5d7a8f7f16613d67e66a673a40367f
+Author: schwarze@openbsd.org <schwarze@openbsd.org>
+Date: Thu Aug 12 09:59:00 2021 +0000
- upstream: ssh: The client configuration keyword is
+ upstream: In the editline(3) branch of the sftp(1) event loop,
- "hostbasedacceptedalgorithms"
+ 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.
- This fixes a mistake that slipped in when "HostbasedKeyTypes" was
- renamed to "HostbasedAcceptedAlgorithms".
+ 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.
- Bug report by zack@philomathiclife.com
+ OK dtucker@ deraadt@
- OpenBSD-Commit-ID: d745a7e8e50b2589fc56877f322ea204bc784f38
+ OpenBSD-Commit-ID: 8025115a773f52e9bb562eaab37ea2e021cc7299
-commit 078a0e60c92700da4c536c93c007257828ccd05b
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Tue May 25 11:40:47 2021 +1000
+commit e1371e4f58404d6411d9f95eb774b444cea06a26
+Author: naddy@openbsd.org <naddy@openbsd.org>
+Date: Wed Aug 11 14:07:54 2021 +0000
- Rename README.md to ci-status.md.
+ upstream: scp: tweak man page and error message for -3 by default
- 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.
+ 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 7be4ac813662f68e89f23c50de058a49aa32f7e4
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed May 19 01:24:05 2021 +0000
+commit 49f46f6d77328a3d10a758522b670a3e8c2235e7
+Author: naddy@openbsd.org <naddy@openbsd.org>
+Date: Wed Aug 11 14:05:19 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.
+ upstream: scp: do not spawn ssh with two -s flags for
- > $ 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
+ remote-to-remote copies
- This restores the blocking status for fds 0,1,2 (stdio) before ssh(1)
- abandons/closes them.
+ 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.
- This was reported as bz3280 and GHPR246; ok dtucker@
+ ok djm@
- OpenBSD-Commit-ID: 8cc67346f05aa85a598bddf2383fcfcc3aae61ce
+ OpenBSD-Commit-ID: 25df69759f323661d31b2e1e790faa22e27966c1
-commit c4902e1a653c67fea850ec99c7537f358904c0af
+commit 2a2cd00783e1da45ee730b7f453408af1358ef5b
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon May 17 11:43:16 2021 +0000
+Date: Wed Aug 11 08:55:04 2021 +0000
- upstream: fix breakage of -W forwaring introduced in 1.554; reported by
-
- naddy@ and sthen@, ok sthen@
+ upstream: test -Oprint-pubkey
- OpenBSD-Commit-ID: f72558e643a26dc4150cff6e5097b5502f6c85fd
+ OpenBSD-Regress-ID: 3d51afb6d1f287975fb6fddd7a2c00a3bc5094e0
-commit afea01381ad1fcea1543b133040f75f7542257e6
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Mon May 17 07:22:45 2021 +0000
+commit b9f4635ea5bc33ed5ebbacf332d79bae463b0f54
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Aug 11 08:54:17 2021 +0000
- upstream: Regenerate moduli.
+ upstream: when verifying sshsig signatures, support an option
- 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
+ (-Oprint-pubkey) to dump the full public key to stdout; based on patch from
+ Fabian Stelzer; ok markus@
- Reported by Luke Dashjr
+ OpenBSD-Commit-ID: 0598000e5b9adfb45d42afa76ff80daaa12fc3e2
-commit 5953c143008259d87342fb5155bd0b8835ba88e5
+commit 750c1a45ba4e8ad63793d49418a0780e77947b9b
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri May 14 05:20:32 2021 +0000
+Date: Wed Aug 11 05:21:32 2021 +0000
- upstream: fix previous: test saved no_shell_flag, not the one that just
-
- got clobbered
+ upstream: oops, missed one more %p
- OpenBSD-Commit-ID: b8deace085d9d941b2d02f810243b9c302e5355d
+ OpenBSD-Commit-ID: e7e62818d1564cc5cd9086eaf7a51cbd1a9701eb
-commit 1e9fa55f4dc4b334651d569d3448aaa3841f736f
+commit b5aa27b69ab2e1c13ac2b5ad3f8f7d389bad7489
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri May 14 03:09:48 2021 +0000
+Date: Wed Aug 11 05:20:17 2021 +0000
- upstream: Fix ssh started with ControlPersist incorrectly executing a
+ upstream: remove a bunch of %p in format strings; leftovers of
- shell when the -N (no shell) option was specified. bz3290 reported by Richard
- Schwab; patch from markus@ ok me
+ debuggings past. prompted by Michael Forney, ok dtucker@
- OpenBSD-Commit-ID: ea1ea4af16a95687302f7690bdbe36a6aabf87e1
+ OpenBSD-Commit-ID: 4853a0d6c9cecaba9ecfcc19066e52d3a8dcb2ac
-commit d1320c492f655d8f5baef8c93899d79dded217a5
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Wed May 12 11:34:30 2021 +0000
+commit 419aa01123db5ff5dbc68b2376ef23b222862338
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Aug 11 09:21:09 2021 +1000
- upstream: Clarify language about moduli. While both ends of the
+ Add includes.h to compat tests.
- 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@
+ 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-Commit-ID: f0c18cc8e79c2fbf537a432a9070ed94e96a622a
+ OpenBSD-Regress-ID: 43fea26704a0f0b962b53c1fabcb68179638f9c0
-commit d3cc4d650ce3e59f3e370b101778b0e8f1c02c4d
+commit 391ca67fb978252c48d20c910553f803f988bd37
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri May 7 04:11:51 2021 +0000
+Date: Tue Aug 10 03:33:34 2021 +0000
- upstream: include pid in LogVerbose spam
+ upstream: Prepare for a future where scp(1) uses the SFTP protocol by
- OpenBSD-Commit-ID: aacb86f96ee90c7cb84ec27452374285f89a7f00
+ 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 e3c032333be5fdbbaf2751f6f478e044922b4ec4
+commit bfdd4b722f124a4fa9173d20dd64dd0fc69856be
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri May 7 03:09:38 2021 +0000
+Date: Mon Aug 9 23:56:36 2021 +0000
- upstream: don't sigdie() in signal handler in privsep child process;
+ upstream: make scp -3 the default for remote-to-remote copies. It
- this can end up causing sandbox violations per bz3286; ok dtucker@
+ 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: a7f40b2141dca4287920da68ede812bff7ccfdda
+ OpenBSD-Commit-ID: d0d2af5f0965c5192ba5b2fa461c9f9b130e5dd9
-commit a4039724a3f2abac810735fc95cf9114a3856049
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri May 7 09:23:40 2021 +0000
+commit 2f7a3b51cef689ad9e93d0c6c17db5a194eb5555
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Aug 9 23:49:31 2021 +0000
- upstream: Increase ConnectionAttempts from 4 to 10 as the tests
+ upstream: make scp in SFTP mode try to use relative paths as much
- occasionally time out on heavily loaded hosts.
+ as possible. Previosuly, it would try to make relative and ~/-rooted paths
+ absolute before requesting transfers.
- OpenBSD-Regress-ID: 29a8cdef354fc9da471a301f7f65184770434f3a
+ prompted by and much discussion deraadt@
+ ok markus@
+
+ OpenBSD-Commit-ID: 46639d382ea99546a4914b545fa7b00fa1be5566
-commit c0d7e36e979fa3cdb60f5dcb6ac9ad3fd018543b
+commit 2ab864010e0a93c5dd95116fb5ceaf430e2fc23c
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri May 7 02:26:55 2021 +0000
+Date: Mon Aug 9 23:47:44 2021 +0000
- upstream: dump out a usable private key string too; inspired by Tyson
+ upstream: SFTP protocol extension to allow the server to expand
- Whitehead
+ ~-prefixed paths, in particular ~user ones. Allows scp in sftp mode to accept
+ these paths, like scp in rcp mode does.
- OpenBSD-Regress-ID: 65572d5333801cb2f650ebc778cbdc955e372058
+ prompted by and much discussion deraadt@
+ ok markus@
+
+ OpenBSD-Commit-ID: 7d794def9e4de348e1e777f6030fc9bafdfff392
-commit 24fee8973abdf1c521cd2c0047d89e86d9c3fc38
+commit 41b019ac067f1d1f7d99914d0ffee4d2a547c3d8
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri May 7 02:29:40 2021 +0000
+Date: Mon Aug 9 23:44:32 2021 +0000
- upstream: correct mistake in spec - the private key blobs are encoded
+ upstream: when scp is in SFTP mode, try to deal better with ~
- verbatim and not as strings (i.e. no 4-byte length header)
+ prefixed paths. ~user paths aren't supported, but ~/ paths will be accepted
+ and prefixed with the SFTP server starting directory (more to come)
- OpenBSD-Commit-ID: 3606b5d443d72118c5b76c4af6dd87a5d5a4f837
+ prompted by and discussed with deraadt@
+ ok markus@
+
+ OpenBSD-Commit-ID: 263a071f14555c045fd03132a8fb6cbd983df00d
-commit f43859159cc62396ad5d080f0b1f2635a67dac02
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Tue May 4 22:53:52 2021 +0000
+commit b4b3f3da6cdceb3fd168b5fab69d11fba73bd0ae
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Aug 9 07:21:01 2021 +0000
- upstream: Don't pass NULL as a string in debugging as it does not work
+ upstream: on fatal errors, make scp wait for ssh connection before
- on some platforms in -portable. ok djm@
+ 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: 937c892c99aa3c9c272a8ed78fa7c2aba3a44fc9
+ (this was originally committed as r1.223 along with unrelated stuff that
+ I rolled back in r1.224)
+
+ OpenBSD-Commit-ID: 1261fd667ad918484889ed3d7aec074f3956a74b
-commit ac31aa3c6341905935e75f0539cf4a61bbe99779
+commit 2ae7771749e0b4cecb107f9d4860bec16c3f4245
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon May 3 00:16:45 2021 +0000
+Date: Mon Aug 9 07:19:12 2021 +0000
- upstream: more debugging for UpdateHostKeys signature failures
+ upstream: rever r1.223 - I accidentally committed unrelated changes
- OpenBSD-Commit-ID: 1ee95f03875e1725df15d5e4bea3e73493d57d36
+ OpenBSD-Commit-ID: fb73f3865b2647a27dd94db73d6589506a9625f9
-commit 8e32e97e788e0676ce83018a742203614df6a2b3
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat May 1 20:07:47 2021 +1000
+commit 986abe94d481a1e82a01747360bd767b96b41eda
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Aug 9 07:16:09 2021 +0000
- Add obsd69 test target.
+ 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 f06893063597c5bb9d9e93f851c4070e77d2fba9
+commit 2b67932bb3176dee4fd447af4368789e04a82b93
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Apr 30 04:29:53 2021 +0000
+Date: Mon Aug 9 07:13:54 2021 +0000
- upstream: a little debugging in the main mux process for status
+ upstream: on fatal errors, make scp wait for ssh connection before
- confirmation failures in multiplexed sessions
+ 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: 6e27b87c95176107597035424e1439c3232bcb49
+ OpenBSD-Commit-ID: ef9dab5ef5ae54a6a4c3b15d380568e94263456c
-commit e65cf00da6bc31e5f54603b7feb7252dc018c033
+commit 724eb900ace30661d45db2ba01d0f924d95ecccb
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Apr 30 04:02:52 2021 +0000
+Date: Sun Aug 8 08:49:09 2021 +0000
- upstream: Remove now-unused skey function prototypes leftover from
+ upstream: xstrdup environment variable used by ForwardAgent. bz#3328
- skey removal.
+ from goetze at dovetail.com, ok djm@ deraadt@
- OpenBSD-Commit-ID: 2fc36d519fd37c6f10ce74854c628561555a94c3
+ OpenBSD-Commit-ID: 760320dac1c3b26904284ba417a7d63fccc5e742
-commit ae5f9b0d5c8126214244ee6b35aae29c21028133
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Apr 29 13:01:50 2021 +1000
+commit 86b4cb3a884846b358305aad17a6ef53045fa41f
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Sun Aug 8 08:27:28 2021 +0000
- Wrap sntrup761x25519 inside ifdef.
+ upstream: Although it's POSIX, not all shells used in Portable support
- 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.
+ the implicit 'in "$@"' after 'for i'.
- 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.
+ OpenBSD-Regress-ID: 3c9aec6bca4868f85d2742b6ba5223fce110bdbc
-commit 9f79e80dc40965c2e73164531250b83b176c1eea
+commit f2ccf6c9f395923695f22345e626dfd691227aaf
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Tue Apr 27 12:24:10 2021 +1000
+Date: Sun Aug 8 17:39:56 2021 +1000
- Always build OpenSSL shared.
+ Move portable specific settings down.
- This is the default for current versions but we need it to test against
- earlier versions.
+ 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 b3cc9fbdff2782eca79e33e02ac22450dc63bce9
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Tue Apr 27 09:18:02 2021 +1000
+commit 71b0eb997e220b0fc9331635af409ad84979f2af
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Sun Aug 8 07:27:52 2021 +0000
- Fix custom OpenSSL tests.
+ upstream: Move setting of USER further down the startup In portable
- 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.
+ 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 29e194a752359ebf85bf7fce100f23a0477fc4de
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Mon Apr 26 14:49:59 2021 +1000
+commit f0aca2706c710a0da1a4be705f825a807cd15400
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Sun Aug 8 06:38:33 2021 +0000
- Ensure we can still build with C89.
+ 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 a38016d369d21df5d35f761f2b67e175e132ba22
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Mon Apr 26 14:29:03 2021 +1000
+commit cf27810a649c5cfae60f8ce66eeb25caa53b13bc
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Sat Aug 7 01:57:08 2021 +0000
- Interop test agains PuTTY.
+ upstream: Fix prototype mismatch for do_cmd. ok djm@
+
+ OpenBSD-Commit-ID: 1c1598bb5237a7ae0be99152f185e0071163714d
-commit 095b0307a77be8803768857cc6c0963fa52ed85b
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Mon Apr 26 14:02:03 2021 +1000
+commit 85de69f64665245786e28c81ab01fe18b0e2a149
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Aug 7 01:55:01 2021 +0000
- Support testing against arbitary libcrytpo vers.
+ upstream: sftp-client.c needs poll.h
- Add tests against various LibreSSL and OpenSSL versions.
+ remove unused variable
+
+ OpenBSD-Commit-ID: 233ac6c012cd23af62f237167a661db391055a16
-commit b16082aa110fa7128ece2a9037ff420c4a285317
+commit 397c4d72e50023af5fe3aee5cc2ad407a6eb1073
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Mon Apr 26 13:35:44 2021 +1000
+Date: Sat Aug 7 11:30:57 2021 +1000
- Add fbsd10 test target.
+ Include poll.h and friends for struct pollfd.
-commit 2c805f16b24ea37cc051c6018fcb05defab6e57a
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sun Apr 25 14:15:02 2021 +1000
+commit a9e2c533195f28627f205682482d9da384c4c52e
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Aug 7 00:14:17 2021 +0000
- Disable compiler hardening on nbsd4.
+ upstream: do_upload() used a near-identical structure for
- 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.
+ 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 d1aed05bd2e4ae70f359a394dc60a2d96b88f78c
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Apr 24 22:03:46 2021 +1000
+commit 7b1cbcb7599d9f6a3bbad79d412604aa1203b5ee
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Aug 7 00:12:09 2021 +0000
- Comment out nbsd2 test target for now.
+ upstream: make scp(1) in SFTP mode follow symlinks like
+
+ traditional scp(1) ok markus@
+
+ OpenBSD-Commit-ID: 97255e55be37e8e26605e4ba1e69f9781765d231
-commit a6b4ec94e5bd5a8a18cd2c9942d829d2e5698837
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Apr 24 17:52:24 2021 +1000
+commit 133b44e500422df68c9c25c3b6de35c0263132f1
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Aug 7 00:10:49 2021 +0000
- Add OPENBSD ORIGINAL marker.
+ upstream: fix incorrect directory permissions on scp -3
+
+ transfers; ok markus@
+
+ OpenBSD-Commit-ID: 64b2abaa5635a2be65ee2e77688ad9bcebf576c2
-commit 3737c9f66ee590255546c4b637b6d2be669a11eb
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Apr 23 19:49:46 2021 +1000
+commit 98b59244ca10e62ff67a420856770cb700164f59
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Aug 7 00:09:57 2021 +0000
- Replace "==" (a bashism) with "=".
+ upstream: a bit more debugging of file attributes being
+
+ sent/received over the wire
+
+ OpenBSD-Commit-ID: f68c4e207b08ef95200a8b2de499d422808e089b
-commit a116b6f5be17a1dd345b7d54bf8aa3779a28a0df
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Apr 23 16:34:48 2021 +1000
+commit c677e65365d6f460c084e41e0c4807bb8a9cf601
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Aug 7 00:08:52 2021 +0000
- Add nbsd2 test target.
+ 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 196bf2a9bb771f45d9b0429cee7d325962233c44
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Apr 23 14:54:10 2021 +1000
+commit 48cd39b7a4e5e7c25101c6d1179f98fe544835cd
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Aug 7 00:07:18 2021 +0000
- Add obsd68 test target.
+ upstream: factor out a structure duplicated between downloading
+
+ and crossloading; ok markus@
+
+ OpenBSD-Commit-ID: 96eede24d520569232086a129febe342e4765d39
-commit e3ba6574ed69e8b7af725cf5e8a9edaac04ff077
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Apr 23 14:53:32 2021 +1000
+commit 318c06bb04ee21a0cfa6b6022a201eacaa53f388
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Aug 7 00:06:30 2021 +0000
- Remove dependency on bash.
+ upstream: use sftp_client crossloading to implement scp -3
+
+ feedback/ok markus@
+
+ OpenBSD-Commit-ID: 7db4c0086cfc12afc9cfb71d4c2fd3c7e9416ee9
-commit db1f9ab8feb838aee9f5b99c6fd3f211355dfdcf
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Apr 23 14:41:13 2021 +1000
+commit de7115b373ba0be3861c65de9b606a3e0e9d29a3
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Aug 7 00:02:41 2021 +0000
- Add obsd67 test target.
+ 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 c039a6bf79192fe1daa9ddcc7c87dd98e258ae7c
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Apr 23 11:08:23 2021 +1000
+commit a50bd0367ff2063bbc70a387740a2aa6914de094
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Aug 7 00:01:29 2021 +0000
- Re-add macos-11.0 test target.
+ upstream: factor our SSH2_FXP_OPEN calls into their own function;
+
+ "looks fine" markus@
+
+ OpenBSD-Commit-ID: d3dea2153f08855c6d9dacc01973248944adeffb
-commit a6db3a47b56adb76870d59225ffb90a65bc4daf2
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Apr 23 10:28:28 2021 +1000
+commit e3c0ba05873cf3d3f7d19d595667a251026b2d84
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Aug 7 00:00:33 2021 +0000
- Add openindiana test target.
+ upstream: prepare for scp -3 implemented via sftp
+
+ OpenBSD-Commit-ID: 194aac0dd87cb175334b71c2a30623a5ad55bb44
-commit 3fe7e73b025c07eda46d78049f1da8ed7dfc0c69
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Apr 23 10:26:35 2021 +1000
+commit 395d8fbdb094497211e1461cf0e2f80af5617e0a
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Aug 6 09:00:18 2021 +0000
- Test krb5 on Solaris 11 too.
+ 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 f57fbfe5eb02df1a91f1a237c4d27165afd87c13
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Apr 22 22:27:26 2021 +1000
+commit d247a73ce27b460138599648d9c637c6f2b77605
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Aug 4 21:28:00 2021 +0000
- Don't always set SUDO.
+ upstream: regression test for scp -3
- Rely on sourcing configs to set as appropriate.
+ OpenBSD-Regress-ID: b44375d125c827754a1f722ec6b6b75b634de05d
-commit e428f29402fb6ac140b52f8f12e06ece7bb104a0
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Apr 22 22:26:08 2021 +1000
+commit 35c8e41a6f6d8ad76f8d1cd81ac2ea23d0d993b2
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Aug 6 05:04:42 2021 +0000
- Remove now-unused 2nd arg to configs.
+ upstream: Document "ProxyJump none". bz#3334.
+
+ OpenBSD-Commit-ID: f78cc6f55731f2cd35c3a41d5352ac1ee419eba7
-commit cb4ff640d79b3c736879582139778f016bbb2cd7
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Apr 21 01:08:04 2021 +1000
+commit 911ec6411821bda535d09778df7503b92f0eafab
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Wed Aug 4 01:34:55 2021 +0000
- Add win10 test target.
+ 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 4457837238072836b2fa3107d603aac809624983
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Tue Apr 20 23:31:29 2021 +1000
+commit 6df1fecb5d3e51f3a8027a74885c3a44f6cbfcbd
+Author: Damien Miller <djm@mindrot.org>
+Date: Wed Aug 4 11:05:11 2021 +1000
- Add nbsd8 test target.
+ use openbsd-compat glob.h is required
-commit bd4fba22e14da2fa196009010aabec5a8ba9dd42
+commit 9ebd1828881dfc9014a344587934a5ce7db6fa1b
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Apr 17 09:55:47 2021 +1000
+Date: Tue Aug 3 21:03:23 2021 +1000
- Add obsd51 target.
+ Missing space between macro arg and punctuation.
+
+ From jmc@
-commit 9403d0e805c77a5741ea8c3281bbe92558c2f125
+commit 0fd3f62eddc7cf54dcc9053be6f58998f3eb926a
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Apr 16 18:14:25 2021 +1000
+Date: Tue Aug 3 21:02:33 2021 +1000
- Add fbsd13 target.
+ Avoid lines >80 chars. From jmc@
-commit e86968280e358e62649d268d41f698d64d0dc9fa
-Author: Damien Miller <djm@mindrot.org>
-Date: Fri Apr 16 13:55:25 2021 +1000
+commit af5d8094d8b755e1daaf2e20ff1dc252800b4c9b
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Aug 3 01:05:24 2021 +0000
- depend
+ upstream: regression tests for scp SFTP protocol support; mostly by
+
+ Jakub Jelen in GHPR#194 ok markus
+
+ OpenBSD-Regress-ID: 36f1458525bcb111741ec8547eaf58b13cddc715
-commit 2fb25ca11e8b281363a2a2a4dec4c497a1475d9a
-Author: Damien Miller <djm@mindrot.org>
-Date: Fri Apr 16 13:53:02 2021 +1000
+commit e4673b7f67ae7740131a4ecea29a846593049a91
+Author: anton@openbsd.org <anton@openbsd.org>
+Date: Thu Jul 29 15:34:09 2021 +0000
- crank version in README and RPM spec files
+ 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 b2b60ebab0cb77b5bc02d364d72e13db882f33ae
+commit 197e29f1cca190d767c4b2b63a662f9a9e5da0b3
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Apr 16 03:42:00 2021 +0000
+Date: Mon Aug 2 23:38:27 2021 +0000
- upstream: openssh-8.6
+ upstream: support for using the SFTP protocol for file transfers in
- OpenBSD-Commit-ID: b5f3e133c846127ec114812248bc17eff07c3e19
+ 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 faf2b86a46c9281d237bcdec18c99e94a4eb820a
-Author: markus@openbsd.org <markus@openbsd.org>
-Date: Thu Apr 15 16:24:31 2021 +0000
+commit dd533c7ab79d61a7796b77b64bd81b098e0d7f9f
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Fri Jul 30 14:28:13 2021 +0000
- upstream: do not pass file/func to monitor; noted by Ilja van Sprundel;
+ 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@
+ ok djm dtucker
- OpenBSD-Commit-ID: 85ae5c063845c410283cbdce685515dcd19479fa
+ OpenBSD-Commit-ID: a1fd8d21dc77f507685443832df0c9700481b0ce
-commit 2dc328023f60212cd29504fc05d849133ae47355
-Author: Damien Miller <djm@mindrot.org>
-Date: Wed Apr 14 11:42:55 2021 +1000
+commit 4455aec2e4fc90f64ae4fc47e78ebc9c18721738
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Wed Jul 28 05:57:42 2021 +0000
- sshd don't exit on transient read errors
+ upstream: no need to talk about version 2 with the -Q option, so
- 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
+ rewrite the text to read better;
+
+ issue reported by debian at helgefjell de
+ ok djm dtucker
+
+ OpenBSD-Commit-ID: 59fe2e8219c37906740ad062e0fdaea487dbe9cf
-commit d5d6b7d76d171a2e6861609dcd92e714ee62ad88
-Author: Damien Miller <djm@mindrot.org>
-Date: Sat Apr 10 18:45:00 2021 +1000
+commit bec429338e9b30d2c7668060e82608286a8a4777
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Tue Jul 27 14:28:46 2021 +0000
- perform report_failed_grab() inline
+ upstream: word fix; reported by debian at helgefjell de
+
+ OpenBSD-Commit-ID: 0c6fd22142422a25343c5bd1a618f31618f41ece
-commit ea996ce2d023aa3c6d31125e2c3ebda1cb42db8c
-Author: Damien Miller <djm@mindrot.org>
-Date: Sat Apr 10 18:22:57 2021 +1000
+commit efad4deb5a1f1cf79ebefd63c6625059060bfbe1
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Tue Jul 27 14:14:25 2021 +0000
- dedicated gnome-ssk-askpass3 source
+ upstream: standardise the grammar in the options list; issue
- 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.
+ reported by debian at helgefjell de
- 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.
+ ok dtucker djm
- 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
+ OpenBSD-Commit-ID: 7ac15575045d82f4b205a42cc7d5207fe4c3f8e6
-commit bfa5405da05d906ffd58216eb77c4375b62d64c2
+commit 1e11fb24066f3fc259ee30db3dbb2a3127e05956
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Apr 8 15:18:15 2021 +1000
+Date: Mon Aug 2 18:56:29 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.
+ Check for RLIMIT_NOFILE before trying to use it.
-commit 1f189181f3ea09a9b08aa866f78843fec800874f
+commit 0f494236b49fb48c1ef33669f14822ca4f3ce2f4
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Apr 8 15:17:19 2021 +1000
+Date: Tue Jul 27 17:45:34 2021 +1000
- Pass OBJ to unit test make invocation.
+ lastenv is only used in setenv.
- At least the Valgrind unit tests uses $OBJ.
+ Prevents an unused variable warning on platforms that have setenv but
+ not unsetenv.
-commit f42b550c281d28bd19e9dd6ce65069164f3482b0
+commit a1f78e08bdb3eaa88603ba3c6e01de7c8671e28a
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Apr 8 14:20:12 2021 +1000
+Date: Mon Jul 26 12:45:30 2021 +1000
- Add pattern for valgrind-unit.
+ Move SUDO to "make test" command line.
+
+ Environment variables don't get passed by vmrun, so move to command
+ line.
-commit 19e534462710e98737478fd9c44768b50c27c4c6
+commit 02e624273b9c78a49a01239159b8c09b8409b1a0
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Apr 8 13:31:08 2021 +1000
+Date: Sun Jul 25 23:26:36 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.
+ Set SUDO for tests and cleanup.
-commit 80032102d05e866dc2a48a5caf760cf42c2e090e
+commit 460ae5d93051bab70239ad823dd784822d58baad
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Apr 8 13:25:57 2021 +1000
+Date: Sun Jul 25 22:37:55 2021 +1000
- ifdef out MIN and MAX.
+ 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
- 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.
+ we're building with OPENSSL=no.
+
+ OpenBSD-Regress-ID: 20455ed9a977c93f846059d1fcb48e29e2c8d732
-commit d1bd184046bc310c405f45da3614a1dc5b3e521a
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Apr 7 10:23:51 2021 +1000
+commit 727ce36c8c5941bde99216d27109405907caae4f
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Sun Jul 25 12:13:03 2021 +0000
- Remove only use of warn().
+ upstream: Replace OPENSSL as the variable that points to the
- 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.
+ 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 fea8f4b1aa85026ad5aee5ad8e1599a8d5141fe0
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Apr 7 10:18:32 2021 +1000
+commit 55e17101a9075f6a63af724261c5744809dcb95c
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Sat Jul 24 02:57:28 2021 +0000
- Move make_tmpdir() into portable-specific area.
+ upstream: Skip RFC4716 format import and export tests when built
- Reduces diff vs OpenBSD and makes it more likely diffs will apply
- cleanly.
+ without OpenSSL.
+
+ OpenBSD-Regress-ID: d2c2d5d38c1acc2b88cc99cfe00a2eb8bb39dfa4
-commit 13e5fa2acffd26e754c6ee1d070d0afd035d4cb7
+commit f5ccb5895d39cd627ad9e7b2c671d2587616100d
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Tue Apr 6 23:57:56 2021 +0000
+Date: Sat Jul 24 02:51:14 2021 +0000
- upstream: Add TEST_SSH_ELAPSED_TIMES environment variable to print the
+ upstream: Don't omit ssh-keygen -y from usage when built without
- elapsed time in seconds of each test. This depends on "date +%s" which is
- not specified by POSIX but is commonly implemented.
+ OpenSSL. It is actually available, albeit only for ed25519 keys.
- OpenBSD-Regress-ID: ec3c8c19ff49b2192116a0a646ee7c9b944e8a9c
+ OpenBSD-Commit-ID: 7a254c33d0e6a55c30c6b016a8d298d3cb7a7674
-commit ef4f46ab4387bb863b471bad124d46e8d911a79a
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Apr 7 09:59:15 2021 +1000
+commit 819d57ac23469f1f03baa8feb38ddefbada90fdc
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Sat Jul 24 02:08:13 2021 +0000
- Move the TEST_SSH_PORT section down a bit.
+ upstream: Exclude key conversion options from usage when built
- This groups the portable-specific changes together and makes it a
- little more likely that patches will apply cleanly.
+ 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 3674e33fa70dfa1fe69b345bf576113af7b7be11
+commit b6673b1d2ee90b4690ee84f634efe40225423c38
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Apr 7 10:05:10 2021 +1000
+Date: Sat Jul 24 13:02:51 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.
+ Test OpenBSD upstream with and without OpenSSL.
-commit 961af266b861e30fce1e26170ee0dbb5bf591f29
+commit 9d38074b5453c1abbdf888e80828c278d3b886ac
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Apr 6 23:24:30 2021 +0000
+Date: Sat Jul 24 01:54:23 2021 +0000
- upstream: include "ssherr.h" not <ssherr.h>; from Balu Gajjala via
+ upstream: test for first-match-wins in authorized_keys environment=
- bz#3292
+ options
- 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
+ OpenBSD-Regress-ID: 1517c90276fe84b5dc5821c59f88877fcc34c0e8
-commit f283a6c2e0a9bd9369e18462acd00be56fbe5b0d
-Author: Damien Miller <djm@mindrot.org>
-Date: Wed Apr 7 08:20:35 2021 +1000
+commit 2b76f1dd19787e784711ea297ad8fc938b4484fd
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Jul 23 05:53:02 2021 +0000
- wrap getrlimit call in HAVE_GETRLIMIT; bz3291
+ upstream: Simplify keygen-convert by using $SSH_KEYTYPES directly.
+
+ OpenBSD-Regress-ID: cdbe408ec3671ea9ee9b55651ee551370d2a4108
-commit 679bdc4a5c9244f427a7aee9c14b0a0ed086da1f
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Tue Apr 6 09:07:33 2021 +0000
+commit 7d64a9fb587ba9592f027f7a2264226c713d6579
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Jul 24 01:55:19 2021 +0000
- upstream: Don't check return value of unsetenv(). It's part of the
+ upstream: don't leak environment= variable when it is not the first
- 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.
+ match
- OpenBSD-Regress-ID: 24f08543ee3cdebc404f2951f3e388cc82b844a1
+ OpenBSD-Commit-ID: 7fbdc3dfe0032deaf003fd937eeb4d434ee4efe0
-commit 320af2f3de6333aa123f1b088eca146a245e968a
+commit db2130e2340bf923e41c791aa9cd27b9e926042c
Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Sun Apr 4 11:36:56 2021 +0000
+Date: Fri Jul 23 06:01:17 2021 +0000
- upstream: remove stray inserts; from matthias schmidt
+ upstream: punctuation;
- OpenBSD-Commit-ID: 2c36ebdc54e14bbf1daad70c6a05479a073d5c63
+ OpenBSD-Commit-ID: 64be152e378c45975073ab1c07e0db7eddd15806
-commit 801f710953b24dd2f21939171c622eac77c7484d
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Sun Apr 4 06:11:24 2021 +0000
+commit 03190d10980c6fc9124e988cb2df13101f266507
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Jul 23 05:56:47 2021 +0000
- upstream: missing comma; from kawashima james
+ upstream: mention in comment that read_passphrase(..., RP_ALLOW_STDIN)
- OpenBSD-Commit-ID: 31cec6bf26c6db4ffefc8a070715ebef274e68ea
+ will try to use askpass first. bz3314
+
+ convert a couple of debug() -> debug_f() while here
+
+ OpenBSD-Commit-ID: c7e812aebc28fcc5db06d4710e0f73613dee545c
-commit b3ca08cb174266884d44ec710a84cd64c12414ea
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Mon Apr 5 23:46:42 2021 +1000
+commit 1653ece6832b2b304d46866b262d5f69880a9ec7
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Jul 23 05:07:16 2021 +0000
- Install libcbor with libfido2.
+ upstream: Test conversion of ed25519 and ecdsa keys too.
+
+ OpenBSD-Regress-ID: 3676d2d00e58e0d6d37f2878f108cc2b83bbe4bb
-commit f3ca8af87a4c32ada660da12ae95cf03d190c083
-Author: Damien Miller <djm@mindrot.org>
-Date: Sat Apr 3 18:21:08 2021 +1100
+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
- enable authopt and misc unit tests
+ upstream: regression test for time-limited signature keys
- Neither were wired into the build, both required some build
- adaptations for -portable
+ OpenBSD-Regress-ID: 2a6f3bd900dbee0a3c96f1ff23e032c93ab392bc
-commit dc1b45841fb97e3d7f655ddbcfef3839735cae5f
+commit 9e1882ef6489a7dd16b6d7794af96629cae61a53
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Apr 3 06:58:30 2021 +0000
+Date: Fri Jul 23 05:24:02 2021 +0000
- upstream: typos in comments; GHPR#180 from Vill
+ upstream: note successful authentication method in final "Authenticated
- =?UTF-8?q?e=20Skytt=C3=A4?=
- MIME-Version: 1.0
- Content-Type: text/plain; charset=UTF-8
- Content-Transfer-Encoding: 8bit
+ to ..." message and partial auth success messages (all at LogLevel=verbose)
+ ok dtucker@
- OpenBSD-Commit-ID: 93c732381ae0e2b680c79e67c40c1814b7ceed2c
+ OpenBSD-Commit-ID: 06834b89ceb89f8f16c5321d368a66c08f441984
-commit 53ea05e09b04fd7b6dea66b42b34d65fe61b9636
+commit a917e973a1b90b40ff1e950df083364b48fc6c78
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Apr 3 06:55:52 2021 +0000
+Date: Fri Jul 23 04:04:52 2021 +0000
- upstream: sync CASignatureAlgorithms lists with reality. GHPR#174 from
+ upstream: Add a ForkAfterAuthentication ssh_config(5) counterpart
- Matt Hazinski
+ to the ssh(1) -f flag. Last part of GHPR231 from Volker Diels-Grabsch. ok
+ dtucker
- OpenBSD-Commit-ID: f05e4ca54d7e67b90fe58fe1bdb1d2a37e0e2696
+ OpenBSD-Commit-ID: b18aeda12efdebe2093d55263c90fe4ea0bce0d3
-commit 57ed647ee07bb883a2f2264231bcd1df6a5b9392
-Author: Damien Miller <djm@mindrot.org>
-Date: Sat Apr 3 17:47:37 2021 +1100
+commit e0c5088f1c96a145eb6ea1dee438010da78f9ef5
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Jul 23 04:00:59 2021 +0000
- polish whitespace for portable files
+ 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 31d8d231eb9377df474746a822d380c5d68d7ad6
+commit e3957e21ffdc119d6d04c0b1686f8e2fe052f5ea
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Apr 3 06:18:40 2021 +0000
+Date: Fri Jul 23 03:57:20 2021 +0000
- upstream: highly polished whitespace, mostly fixing spaces-for-tab
+ upstream: make authorized_keys environment="..." directives
- and bad indentation on continuation lines. Prompted by GHPR#185
+ first-match-wins and more strictly limit their maximum number; prompted by
+ OOM reported by OSS-fuzz (35470).
- OpenBSD-Commit-ID: e5c81f0cbdcc6144df1ce468ec1bac366d8ad6e9
+ feedback and ok dtucker@
+
+ OpenBSD-Commit-ID: 01f63fc10dcd995e7aed9c378ad879161af83121
-commit 34afde5c73b5570d6f8cce9b49993b23b77bfb86
+commit d0bb1ce731762c55acb95817df4d5fab526c7ecd
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Apr 3 05:54:14 2021 +0000
+Date: Fri Jul 23 03:37:52 2021 +0000
- upstream: whitespace (tab after space)
+ upstream: Let allowed signers files used by ssh-keygen(1)
- OpenBSD-Commit-ID: 0e2b3f7674e985d3f7c27ff5028e690ba1c2efd4
+ 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 7cd262c1c5a08cc7f4f30e3cab108ef089d0a57b
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Apr 3 16:59:10 2021 +1100
+commit 44142068dc7ef783d135e91ff954e754d2ed432e
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Mon Jul 19 08:48:33 2021 +0000
- Save config.h and config.log on failure too.
+ upstream: Use SUDO when setting up hostkey.
+
+ OpenBSD-Regress-ID: 990cf4481cab8dad62e90818a9b4b36c533851a7
-commit 460aee9298f365357e9fd26851c22e0dca51fd6a
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Apr 3 05:46:41 2021 +0000
+commit 6b67f3f1d1d187597e54a139cc7785c0acebd9a2
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Mon Jul 19 05:08:54 2021 +0000
- upstream: fix incorrect plural; from Ville Skyt
+ upstream: Increase time margin for rekey tests. Should help
- =?UTF-8?q?t=C3=A4=20via=20GHPR#181?=
- MIME-Version: 1.0
- Content-Type: text/plain; charset=UTF-8
- Content-Transfer-Encoding: 8bit
+ reliability on very heavily loaded hosts.
- OpenBSD-Commit-ID: 92f31754c6296d8f403d7c293e09dc27292d22c9
+ OpenBSD-Regress-ID: 4c28a0fce3ea89ebde441d7091464176e9730533
-commit 082804c14e548cada75c81003a3c68ee098138ee
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Apr 3 05:40:39 2021 +0000
+commit 7953e1bfce9e76bec41c1331a29bc6cff9d416b8
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Jul 19 13:47:51 2021 +1000
- 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.
+ 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
- From Adithya Baglody via GHPR#234; ok markus
+ 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: f8e770e03b416ee9a58f9762e162add900f832b6
+ OpenBSD-Commit-ID: 0a6a0a476eb7f9dfe8fe2c05a1a395e3e9b22ee4
-commit 464ebc82aa926dd132ec75a0b064574ef375675e
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Apr 3 05:28:43 2021 +0000
+commit 1cc1fd095393663cd72ddac927d82c6384c622ba
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Mon Jul 19 02:21:50 2021 +0000
- upstream: unused variable
+ upstream: Id sync only, -portable already has this.
- OpenBSD-Commit-ID: 85f6a394c8e0f60d15ecddda75176f112007b205
+ Put dh_set_moduli_file call inside ifdef WITH_OPENSSL. Fixes
+ build with OPENSSL=no.
+
+ OpenBSD-Commit-ID: af54abbebfb12bcde6219a44d544e18204defb15
-commit dc3c0be8208c488e64a8bcb7d9efad98514e0ffb
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Apr 3 05:21:46 2021 +0000
+commit 33abbe2f4153f5ca5c874582f6a7cc91ae167485
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Mon Jul 19 02:46:34 2021 +0000
- upstream: Fix two problems in string->argv conversion: 1) multiple
+ upstream: Add test for host key verification via SSHFP records. This
- 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
+ requires some external setup to operate so is disabled by default (see
+ comments in sshfp-connect.sh).
- A unit test for these cases has already been committed
+ 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
- prompted by and based on GHPR#223 by Eero Häkkinen; ok markus@
+ RSA SSHFP export if we have RSA functionality compiled in.
- OpenBSD-Commit-ID: d7ef27abb4eeeaf6e167e9312e4abe9e89faf1e4
+ OpenBSD-Regress-ID: b4ff5181b8c9a5862e7f0ecdd96108622333a9af
-commit f75bcbba58a08c670727ece5e3f8812125969799
-Author: Damien Miller <djm@mindrot.org>
-Date: Sat Apr 3 16:22:48 2021 +1100
+commit 0075511e27e5394faa28edca02bfbf13b9a6693e
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Mon Jul 19 00:16:26 2021 +0000
- missing bits from 259d648e
+ upstream: Group keygen tests together.
+
+ OpenBSD-Regress-ID: 07e2d25c527bb44f03b7c329d893a1f2d6c5c40c
-commit 4cbc4a722873d9b68cb5496304dc050d7168df78
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Mar 31 21:59:26 2021 +0000
+commit 034828820c7e62652e7c48f9ee6b67fb7ba6fa26
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Sun Jul 18 23:10:10 2021 +0000
- upstream: cannot effectively test posix-rename extension after
-
- changes in feature advertisment.
+ upstream: Add test for ssh-keygen printing of SSHFP records.
- OpenBSD-Regress-ID: 5e390bf88d379162aaa81b60ed86b34cb0c54d29
+ OpenBSD-Regress-ID: fde9566b56eeb980e149bbe157a884838507c46b
-commit 259d648e63e82ade4fe2c2c73c8b67fe57d9d049
+commit 52c3b6985ef1d5dadb4c4fe212f8b3a78ca96812
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Mar 19 04:23:50 2021 +0000
+Date: Sat Jul 17 00:38:11 2021 +0000
- upstream: add a test for misc.c:argv_split(), currently fails
+ upstream: wrap some long lines
- OpenBSD-Regress-ID: ad6b96d6ebeb9643b698b3575bdd6f78bb144200
+ OpenBSD-Commit-ID: 4f5186b1466656762dae37d3e569438d900c350d
-commit 473ddfc2d6b602cb2d1d897e0e5c204de145cd9a
+commit 43ec991a782791d0b3f42898cd789f99a07bfaa4
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Mar 19 03:25:01 2021 +0000
+Date: Sat Jul 17 00:36:53 2021 +0000
- upstream: split
+ upstream: fix sftp on ControlPersist connections, broken by recent
- OpenBSD-Regress-ID: f6c03c0e4c58b3b9e04b161757b8c10dc8378c34
+ SessionType change; spotted by sthen@
+
+ OpenBSD-Commit-ID: 4c5ddc5698790ae6ff50d2a4f8f832f0eeeaa234
-commit 1339800fef8d0dfbfeabff71b34670105bcfddd2
+commit 073f45c236550f158c9a94003e4611c07dea5279
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Mar 31 22:16:34 2021 +0000
+Date: Fri Jul 16 09:00:23 2021 +0000
- upstream: Use new limits@openssh.com protocol extension to let the
+ upstream: Explicitly check for and start time-based rekeying in 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.
+ client and server mainloops.
- In practice (and assuming upgraded sftp/sftp-server at each end), this
- increases the download buffer 32->64KiB and the upload buffer
- 32->255KiB.
+ 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.
- Patches from Mike Frysinger; ok dtucker@
+ ok markus@
- OpenBSD-Commit-ID: ebd61c80d85b951b794164acc4b2f2fd8e88606c
+ OpenBSD-Commit-ID: 4356cf50d7900f3df0a8f2117d9e07c91b9ff987
-commit 6653c61202d104e59c8e741329fcc567f7bc36b8
+commit ef7c4e52d5d840607f9ca3a302a4cbb81053eccf
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Wed Jul 14 06:46:38 2021 +0000
+
+ upstream: reorder SessionType; ok djm
+
+ OpenBSD-Commit-ID: c7dd0b39e942b1caf4976a0b1cf0fed33d05418c
+
+commit 8aa2f9aeb56506dca996d68ab90ab9c0bebd7ec3
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Jul 14 11:26:50 2021 +1000
+
+ Make whitespace consistent.
+
+commit 4f4297ee9b8a39f4dfd243a74c5f51f9e7a05723
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Jul 14 11:26:12 2021 +1000
+
+ Add ARM64 Linux self-hosted runner.
+
+commit eda8909d1b0a85b9c3804a04d03ec6738fd9dc7f
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Mar 31 21:58:07 2021 +0000
+Date: Tue Jul 13 23:48:36 2021 +0000
- upstream: do not advertise protocol extensions that have been
+ upstream: add a SessionType directive to ssh_config, allowing the
- disallowed by the command-line options (e.g. -p/-P/-R); ok dtucker@
+ 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-Commit-ID: 3a8a76b3f5131741aca4b41bfab8d101c9926205
+ OpenBSD-Regress-ID: 1d5038edb511dc4ce1622344c1e724626a253566
-commit 71241fc05db4bbb11bb29340b44b92e2575373d8
-Author: Damien Miller <djm@mindrot.org>
-Date: Mon Mar 29 15:14:25 2021 +1100
+commit f5fc6a4c3404bbf65c21ca6361853b33d78aa87e
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Jul 12 18:00:05 2021 +1000
- gnome-ssh-askpass3 is a valid target here
+ 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 8a9520836e71830f4fccca066dba73fea3d16bda
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Mar 19 02:22:34 2021 +0000
+commit fd2d06ae4442820429d634c0a8bae11c8e40c174
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Mon Jul 12 06:22:57 2021 +0000
- upstream: return non-zero exit status when killed by signal; bz#3281 ok
+ upstream: Make limit for time_t test unconditional in the
- dtucker@
+ 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: 117b31cf3c807993077b596bd730c24da9e9b816
+ OpenBSD-Commit-ID: 835936f6837c86504b07cabb596b613600cf0f6e
-commit 1269b8a686bf1254b03cd38af78167a04aa6ec88
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Mar 19 02:18:28 2021 +0000
+commit 6c29b387cd64a57b0ec8ae7d2c8d02789d88fcc3
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Mon Jul 12 06:08:57 2021 +0000
- upstream: increase maximum SSH2_FXP_READ to match the maximum
+ upstream: Use existing format_absolute_time() function when
- 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@
+ printing cert validity instead of doing it inline. Part of bz#3329.
- OpenBSD-Commit-ID: 4e67d60d81bde7b84a742b4ee5a34001bdf80d9c
+ OpenBSD-Commit-ID: a13d4e3c4f59644c23745eb02a09b2a4e717c00c
-commit 860b67604416640e8db14f365adc3f840aebcb1f
+commit 99981d5f8bfa383791afea03f6bce8454e96e323
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Mar 16 06:15:43 2021 +0000
+Date: Fri Jul 9 09:55:56 2021 +0000
- upstream: don't let logging clobber errno before use
+ upstream: silence redundant error message; reported by Fabian Stelzer
- OpenBSD-Commit-ID: ce6cca370005c270c277c51c111bb6911e1680ec
+ OpenBSD-Commit-ID: 9349a703016579a60557dafd03af2fe1d44e6aa2
-commit 5ca8a9216559349c56e09039c4335636fd85c241
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Mar 13 14:40:43 2021 +1100
+commit e86097813419b49d5bff5c4b51d1c3a5d4d2d804
+Author: John Ericson <John.Ericson@Obsidian.Systems>
+Date: Sat Dec 26 11:40:49 2020 -0500
- Only call dh_set_moduli_file if using OpenSSL.
-
- Fixes link failure when configuring --without-openssl since dh.c is not
- linked in.
+ Re-indent krb5 section after pkg-config addition.
-commit 867a7dcf003c51d5a83f83565771a35f0d9530ac
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Mar 13 13:52:53 2021 +1100
+commit 32dd2daa56c294e40ff7efea482c9eac536d8cbb
+Author: John Ericson <John.Ericson@Obsidian.Systems>
+Date: Sat Dec 26 11:40:49 2020 -0500
- Don't install moduli during tests.
+ Support finding Kerberos via pkg-config
- 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.
+ This makes cross compilation easier.
-commit 0c054538fccf92b4a028008321d3711107bee6d5
+commit def7a72234d7e4f684d72d33a0f7229f9eee0aa4
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
+Date: Fri Jul 9 14:34:06 2021 +1000
- upstream: spelling
-
- OpenBSD-Commit-ID: 478bc3db04f62f1048ed6e1765400f3ab325e60f
+ Update comments about EGD to include prngd.
-commit 88057eb6df912abf2678ea5c846d9d9cbc92752c
+commit b5d23150b4e3368f4983fd169d432c07afeee45a
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Mar 12 04:08:19 2021 +0000
+Date: Mon Jul 5 01:21:07 2021 +0000
- upstream: Add ModuliFile keyword to sshd_config to specify the
+ upstream: Fix a couple of whitespace things. Portable already has
- 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@
+ these so this removes two diffs between the two.
- OpenBSD-Commit-ID: 8df99d60b14ecaaa28f3469d01fc7f56bff49f66
+ OpenBSD-Commit-ID: 769f017ebafd8e741e337b3e9e89eb5ac73c9c56
-commit f07519a2af96109325b5a48b1af18b57601074ca
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Mar 12 03:43:40 2021 +0000
+commit 8f57be9f279b8e905f9883066aa633c7e67b31cf
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Mon Jul 5 01:16:46 2021 +0000
- upstream: pwcopy() struct passwd that we're going to reuse across a
+ upstream: Order includes as per style(9). Portable already has
- bunch of library calls; bz3273 ok dtucker@
+ these so this removes a handful of diffs between the two.
- OpenBSD-Commit-ID: b6eafa977b2e44607b1b121f5de855107809b762
+ OpenBSD-Commit-ID: 8bd7452d809b199c19bfc49511a798f414eb4a77
-commit 69d6d4b0c8a88d3d1288415605f36e2df61a2f12
+commit b75624f8733b3ed9e240f86cac5d4a39dae11848
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Wed Mar 10 06:32:27 2021 +0000
+Date: Mon Jul 5 00:50:25 2021 +0000
- upstream: Import regenerated moduli file.
+ upstream: Remove comment referencing now-removed
- OpenBSD-Commit-ID: 7ac6c252d2a5be8fbad4c66d9d35db507c9dac5b
+ RhostsRSAAuthentication. ok djm@
+
+ OpenBSD-Commit-ID: 3d864bfbd99a1d4429a58e301688f3be464827a9
-commit e5895e8ecfac65086ea6b34d0d168409a66a15e1
+commit b67eb12f013c5441bb4f0893a97533582ad4eb13
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Mar 10 04:58:45 2021 +0000
+Date: Mon Jul 5 00:25:42 2021 +0000
- upstream: no need to reset buffer after send_msg() as that is done
+ upstream: allow spaces to appear in usernames for local to remote,
- for us; patch from Mike Frysinger
+ and scp -3 remote to remote copies. with & ok dtucker bz#1164
- OpenBSD-Commit-ID: 565516495ff8362a38231e0f1a087b8ae66da59c
+ OpenBSD-Commit-ID: e9b550f3a85ffbb079b6720833da31317901d6dd
-commit 721948e67488767df0fa0db71ff2578ee2bb9210
+commit 8c4ef0943e574f614fc7c6c7e427fd81ee64ab87
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Sat Mar 13 01:52:16 2021 +0000
+Date: Fri Jul 2 07:20:44 2021 +0000
- upstream: Add TEST_SSH_MODULI_FILE variable to allow overriding of the
+ upstream: Remove obsolete comments about SSHv1 auth methods. ok
- moduli file used during the test run.
+ djm@
- OpenBSD-Regress-ID: be10f785263120edb64fc87db0e0d6570a10220a
+ OpenBSD-Commit-ID: 6060f70966f362d8eb4bec3da2f6c4712fbfb98f
-commit 82fef71e20ffef425b932bec26f5bc46aa1ed41c
+commit 88908c9b61bcb99f16e8d398fc41e2b3b4be2003
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Mar 12 15:58:57 2021 +1100
+Date: Sat Jul 3 23:00:19 2021 +1000
- Allow (but return EACCES) fstatat64 in sandbox.
+ Remove reference to ChallengeResponse.
- This is apparently used in some configurations of OpenSSL when glibc
- has getrandom(). bz#3276, patch from Kris Karas, ok djm@
+ challenge_response_authentication was removed from the struct, keeping
+ kbd_interactive_authentication.
-commit 1cd67ee15ce3d192ab51be22bc4872a6a7a4b6d9
+commit 321874416d610ad2158ce6112f094a4862c2e37f
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Mar 12 13:16:10 2021 +1100
+Date: Sat Jul 3 20:38:09 2021 +1000
- 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.
+ Move signal.h up include order to match upstream.
-commit 2421a567a8862fe5102a4e7d60003ebffd1313dd
+commit 4fa83e2d0e32c2dd758653e0359984bbf1334f32
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Mar 10 17:41:21 2021 +1100
+Date: Sat Jul 3 20:36:06 2021 +1000
- Import regenerated moduli file.
+ Remove old OpenBSD version marker.
+
+ Looks like an accidental leftover from a sync.
-commit e99080c05d9d48dbbdb022538533d53ae1bd567d
-Author: millert@openbsd.org <millert@openbsd.org>
-Date: Sat Mar 6 20:36:31 2021 +0000
+commit 9d5e31f55d5f3899b72645bac41a932d298ad73b
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat Jul 3 20:34:19 2021 +1000
- upstream: Fix PRINT macro, the suffix param to sshlog() was missing.
+ Remove duplicate error on error path.
- Also remove redundant __func__ prefix from PRINT calls as the macro already
- adds __FILE__, __func__ and __LINE__. From Christos Zoulas. OK dtucker@
+ 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.
- OpenBSD-Commit-ID: 01fdfa9c5541151b5461d9d7d6ca186a3413d949
+ Reduces diff vs OpenBSD by a small amount.
-commit 160db17fc678ceb5e3fd4a7e006cc73866f484aa
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Mar 3 22:41:49 2021 +0000
+commit 4d2d4d47a18d93f3e0a91a241a6fdb545bbf7dc2
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat Jul 3 19:27:43 2021 +1000
- upstream: don't sshbuf_get_u32() into an enum; reported by goetze
+ Replace remaining references to ChallengeResponse.
- AT dovetail.com via bz3269
+ 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.
- OpenBSD-Commit-ID: 99a30a8f1df9bd72be54e21eee5c56a0f050921a
+ These were omitted from commit 88868fd131.
-commit cffd033817a5aa388764b6661855dcdaabab0588
-Author: sthen@openbsd.org <sthen@openbsd.org>
-Date: Wed Mar 3 21:40:16 2021 +0000
+commit 2c9e4b319f7e98744b188b0f58859d431def343b
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat Jul 3 19:17:31 2021 +1000
- upstream: typo in other_hostkeys_message() display output, ok djm
+ 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.
- OpenBSD-Commit-ID: 276f58afc97b6f5826e0be58380b737603dbf5f5
+ sRhostsRSAAuthentication and sRSAAuthentication are protocol 1 options
+ and are no longer used.
-commit 7fe141b96b13bd7dc67ca985e14d55b9bd8a03fd
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Mar 3 08:42:52 2021 +0000
+commit c73b02d92d72458a5312bd098f32ce88868fd131
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Jul 2 05:11:20 2021 +0000
- upstream: needs FILE*; from Mike Frysinger
+ upstream: Remove references to ChallengeResponseAuthentication in
- OpenBSD-Commit-ID: dddb3aa9cb5792eeeaa37a1af67b5a3f25ded41d
+ 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 d2afd717e62d76bb41ab5f3ab4ce6f885c8edc98
-Author: Damien Miller <djm@mindrot.org>
-Date: Tue Mar 2 21:31:47 2021 +1100
+commit f841fc9c8c7568a3b5d84a4cc0cefacb7dbc16b9
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Jul 2 15:20:32 2021 +1000
- update depend
+ 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 f0c4eddf7cf224ebcac1f07ac8afdb30c6e9fe0a
+commit 0767627cf66574484b9c0834500b42ea04fe528a
Author: Damien Miller <djm@mindrot.org>
-Date: Tue Mar 2 21:30:14 2021 +1100
+Date: Fri Jul 2 14:30:23 2021 +1000
- update relnotes URL
+ wrap get_random_bytes_prngd() in ifdef
+
+ avoid unused static function warning
-commit 67a8bb7fe62a381634db4c261720092e7d514a3d
-Author: Damien Miller <djm@mindrot.org>
-Date: Tue Mar 2 21:29:54 2021 +1100
+commit f93fdc4de158386efe1116bd44c5b3f4a7a82c25
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Jun 28 13:06:37 2021 +1000
- update RPM spec version numbers
+ Add rocky84 test target.
-commit 0a4b23b11b9a4e6eec332dd5c6ab2ac6f62aa164
+commit d443006c0ddfa7f6a5bd9c0ae92036f3d5f2fa3b
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Mar 2 01:48:18 2021 +0000
+Date: Fri Jun 25 06:30:22 2021 +0000
- upstream: openssh-8.5
+ upstream: fix decoding of X.509 subject name; from Leif Thuresson
- 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.
+ via bz3327 ok markus@
+
+ OpenBSD-Commit-ID: 0ea2e28f39750dd388b7e317bc43dd997a217ae8
-commit 85ff2a564ce838f8690050081176c1de1fb33116
+commit 2a5704ec142202d387fda2d6872fd4715ab81347
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Sun Feb 28 22:56:30 2021 +0000
+Date: Fri Jun 25 06:20:39 2021 +0000
- upstream: Add %k to list of keywords. From
+ upstream: Use better language to refer to the user. From l1ving
- =?UTF-8?q?=20Eero=20H=C3=A4kkinenvia=20bz#3267?=
- MIME-Version: 1.0
- Content-Type: text/plain; charset=UTF-8
- Content-Transfer-Encoding: 8bit
+ via github PR#250, ok jmc@
- OpenBSD-Commit-ID: 9c87f39a048cee2a7d1c8bab951b2f716256865e
+ OpenBSD-Commit-ID: 07ca3526626996613e128aeddf7748c93c4d6bbf
-commit e774bac35933e71f924f4301786e7fb5bbe1422f
+commit 4bdf7a04797a0ea1c431a9d54588417c29177d19
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Sun Feb 28 01:50:47 2021 +0000
+Date: Fri Jun 25 03:38:17 2021 +0000
- upstream: Do not try to reset signal handler for signal 0 in
+ upstream: Replace SIGCHLD/notify_pipe kludge with pselect.
- subprocess. Prevents spurious debug message. ok djm@
+ 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.
- OpenBSD-Commit-ID: 7f9785e292dcf304457566ad4637effd27ad1d46
+ 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 351c5dbbd74ce300c4f058112f9731c867c6e225
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Feb 27 23:42:37 2021 +0000
+commit c9f7bba2e6f70b7ac1f5ea190d890cb5162ce127
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Jun 25 15:08:18 2021 +1000
- upstream: fix alphabetic ordering of options; spotted by Iain Morgan
+ Move closefrom() to before first malloc.
- OpenBSD-Commit-ID: f955fec617d74af0feb5b275831a9fee813d7ad5
+ 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 0d1c9dbe578597f8d45d3ac7690df10d32d743e5
+commit 7ebfe4e439853b88997c9cfc2ff703408a1cca92
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Feb 27 12:25:25 2021 +1100
+Date: Fri Jun 18 20:41:45 2021 +1000
- zlib is now optional.
+ 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 b7c6ee7b437d9adfd19ef49d6c0f19f13f26f9b3
-Author: Jeffrey H. Johnson <61629094+johnsonjh@users.noreply.github.com>
-Date: Sat Feb 27 01:04:58 2021 +0000
+commit e409d7966785cfd9f5970e66a820685c42169717
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Jun 18 18:34:08 2021 +1000
- Fix punctuatio and typo in README.md.
+ Try EGD/PRNGD if random device fails.
- Some very minor fixes, missing 's' and punctuation.
+ When built --without-openssl, try EGD/PRGGD (if configured) as a last
+ resort before failing.
-commit 6248b86074804983e8f7a2058856a516dbfe2924
-Author: Damien Miller <djm@mindrot.org>
-Date: Fri Feb 26 16:45:50 2021 +1100
+commit e43a898043faa3a965dbaa1193cc60e0b479033d
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Jun 18 18:32:51 2021 +1000
- Revert "ssh: optional bind interface if bind address specified."
-
- This reverts commit 5a878a71a3528c2626aa1d331934fd964782d41c.
+ Split EGD/PRNGD interface into its own file.
- Apologies - I accidentally pushed this.
+ This will allow us to use it when building --without-openssl.
-commit 493339a940b13be6071629c3c2dd5a3b6fc17023
-Author: Damien Miller <djm@mindrot.org>
-Date: Fri Feb 26 15:45:38 2021 +1100
+commit acb2887a769a1b1912cfd7067f3ce04fad240260
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Jun 17 21:03:19 2021 +1000
- detech BSD libc hash functions in libbsd / libmd
+ Handle GIDs > 2^31 in getgrouplist.
- 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@
+ 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 5a878a71a3528c2626aa1d331934fd964782d41c
-Author: Dmitrii Turlupov <dturlupov@factor-ts.ru>
-Date: Thu Feb 4 16:27:31 2021 +0300
+commit 31fac20c941126281b527605b73bff30a8f02edd
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Thu Jun 10 09:46:28 2021 +0000
- ssh: optional bind interface if bind address specified.
+ upstream: Use $SUDO when reading sshd's pidfile here too.
- Allows the -b and -B options to be used together.
- For example, when the interface is in the VRF.
+ OpenBSD-Regress-ID: 6bfb0d455d493f24839034a629c5306f84dbd409
-commit 1fe4d70df94d3bcc2b35fd57cad6b5fc4b2d7b16
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Feb 26 04:18:42 2021 +0000
+commit a3a58acffc8cc527f8fc6729486d34e4c3d27643
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Thu Jun 10 09:43:51 2021 +0000
- upstream: remove this KEX fuzzer; it's awkward to use and doesn't play
+ upstream: Use $SUDO when reading sshd's pidfile in case it was
- nice with popular fuzzing drivers like libfuzzer. AFAIK nobody has used it
- but me.
+ created with a very restrictive umask. This resyncs with -portable.
- OpenBSD-Regress-ID: cad919522b3ce90c147c95abaf81b0492ac296c9
+ OpenBSD-Regress-ID: 07fd2af06df759d4f64b82c59094accca1076a5d
-commit 24a3a67bd7421740d08803b84bd784e764107928
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Feb 26 11:49:19 2021 +1100
+commit 249ad4ae51cd3bc235e75a4846eccdf8b1416611
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Thu Jun 10 09:37:59 2021 +0000
- Remove macos-11.00 PAM test target too.
+ upstream: Set umask when creating hostkeys to prevent excessive
- These are failing apparently due to some kind of infrastructure problem,
- making it look like every commit is busted.
+ permissions warning.
+
+ OpenBSD-Regress-ID: 382841db0ee28dfef7f7bffbd511803e1b8ab0ef
-commit 473201783f732ca8b0ec528b56aa55fa0d8cf717
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Feb 26 00:16:58 2021 +0000
+commit 9d0892153c005cc65897e9372b01fa66fcbe2842
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Thu Jun 10 03:45:31 2021 +0000
- upstream: a bit more debugging behind #ifdef DEBUG_SK
+ upstream: Add regress test for SIGHUP restart
- OpenBSD-Commit-ID: d9fbce14945721061cb322f0084c2165d33d1993
+ while handling active and unauthenticated clients. Should catch anything
+ similar to the pselect bug just fixed in sshd.c.
+
+ OpenBSD-Regress-ID: 3b3c19b5e75e43af1ebcb9586875b3ae3a4cac73
-commit fd9fa76a344118fe1ef10b9a6c9e85d39599e9a8
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Feb 26 01:15:10 2021 +1100
+commit 73f6f191f44440ca3049b9d3c8e5401d10b55097
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Thu Jun 10 03:14:14 2021 +0000
- Remove macos-11.0 from the test target list.
+ upstream: Continue accept loop when pselect
- It has been consistently failing for the past few days with a github
- actions internal error.
+ 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 476ac8e9d33dbf96ef97aab812b8d7089d0cdc24
-Author: Philip Hands <phil@hands.com>
-Date: Wed Feb 24 23:43:16 2021 +0100
+commit c785c0ae134a8e8b5c82b2193f64c632a98159e4
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Jun 8 22:30:27 2021 +0000
- tidy the $INSTALLKEY_SH code layout a little
+ upstream: test that UserKnownHostsFile correctly accepts multiple
- SSH-Copy-ID-Upstream: 78178aa5017222773e4c23d9001391eeaeca8983
+ arguments; would have caught readconf.c r1.356 regression
+
+ OpenBSD-Regress-ID: 71ca54e66c2a0211b04999263e56390b1f323a6a
-commit 983e05ef3b81329d76d6a802b39ad0d1f637c06c
-Author: Jakub Jelen <jjelen@redhat.com>
-Date: Tue Sep 29 10:02:45 2020 +0000
+commit 1a6f6b08e62c78906a3032e8d9a83e721c84574e
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Jun 8 22:06:12 2021 +0000
- if unable to add a missing newline, fail
+ upstream: fix regression in r1.356: for ssh_config options that
- SSH-Copy-ID-Upstream: 76b25e18f55499ea9edb4c4d6dc4a80bebc36d95
+ accepted multiple string arguments, ssh was only recording the first.
+ Reported by Lucas via bugs@
+
+ OpenBSD-Commit-ID: 7cbf182f7449bf1cb7c5b4452667dc2b41170d6d
-commit 3594b3b015f6014591da88ba71bf6ff010be7411
-Author: Philip Hands <phil@hands.com>
-Date: Tue Oct 13 14:12:58 2020 +0200
+commit 78e30af3e2b2dd540a341cc827c6b98dd8b0a6de
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Jun 8 07:40:12 2021 +0000
- use $AUTH_KEY_DIR, now that we have it
+ upstream: test argv_split() optional termination on comments
- since that was a change made since jjelen's commit was written
+ 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
- also, quote the variables
+ being overridden on the command line.
- SSH-Copy-ID-Upstream: 588cd8e5cbf95f3443d92b9ab27c5d73ceaf6616
+ OpenBSD-Regress-ID: 801674d5d2d02abd58274a78cab2711f11de14a8
-commit 333e25f7bc43cee6e36f766e39dad6f9918b318c
-Author: Jakub Jelen <jjelen@redhat.com>
-Date: Tue Sep 29 10:00:01 2020 +0000
+commit 660cea10b2cdc11f13ba99c89b1bbb368a4d9ff2
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Jun 8 06:52:43 2021 +0000
- restorecon the correct directory
+ upstream: sprinkle some "# comment" at end of configuration lines
- if using different path for authorized_keys file
+ to test comment handling
- SSH-Copy-ID-Upstream: 791a3df47b48412c726bff6f7b1d190721e65d51
+ OpenBSD-Regress-ID: cb82fbf40bda5c257a9f742c63b1798e5a8fdda7
-commit 9beeab8a37a49a9e3ffb1972fff6621ee5bd7a71
+commit acc9c32dcb6def6c7d3688bceb4c0e59bd26b411
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Feb 25 03:27:34 2021 +0000
+Date: Tue Jun 8 06:51:47 2021 +0000
- upstream: s/PubkeyAcceptedKeyTypes/PubkeyAcceptedAlgorithms/
+ upstream: more descriptive failure message
- OpenBSD-Regress-ID: 3dbc005fa29f69dc23d97e433b6dffed6fe7cb69
+ OpenBSD-Regress-ID: 5300f6faf1d9e99c0cd10827b51756c5510e3509
-commit 2dd9870c16ddbd83740adeead5030d6840288c8f
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Wed Feb 24 23:12:35 2021 +0000
+commit ce04dd4eae23d1c9cf7c424a702f48ee78573bc1
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Jun 7 01:16:34 2021 +0000
- upstream: Rename pubkeyacceptedkeytypes to pubkeyacceptedalgorithms in
+ upstream: test AuthenticationMethods inside a Match block as well
- test to match change to config-dump output.
+ as in the main config section
- OpenBSD-Regress-ID: 74c9a4ad50306be873d032819d5e55c24eb74d5d
+ OpenBSD-Regress-ID: ebe0a686621b7cb8bb003ac520975279c28747f7
-commit b9225c3a1c3f5827e31d5d64a71b8e0504a25619
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Wed Feb 24 01:18:08 2021 +0000
+commit 9018bd821fca17e26e92f7a7e51d9b24cd62f2db
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Jun 7 00:00:50 2021 +0000
- upstream: Put obsolete aliases for hostbasedalgorithms and
+ upstream: prepare for stricter sshd_config parsing that will refuse
- pubkeyacceptedalgorithms after their current names so that the config-dump
- mode finds and uses the current names. Spotted by Phil Pennock.
+ 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-Commit-ID: 5dd10e93cccfaff3aaaa09060c917adff04a9b15
+ OpenBSD-Regress-ID: ef65463fcbc0bd044e27f3fe400ea56eb4b8f650
-commit 8b8b60542d6652b2c91e0ef9e9cc81bcb65e6b42
+commit a10f929d1ce80640129fc5b6bc1acd9bf689169e
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Feb 23 21:55:08 2021 +0000
+Date: Tue Jun 8 07:09:42 2021 +0000
- upstream: lots more s/key types/signature algorithms/ mostly in
+ upstream: switch sshd_config parsing to argv_split()
- HostbasedAcceptedAlgorithms and HostKeyAlgorithms; prompted by Jakub Jelen
+ 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.
- OpenBSD-Commit-ID: 3f719de4385b1a89e4323b2549c66aae050129cb
+ 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 0aeb508aaabc4818970c90831e3d21843c3c6d09
+commit ea9e45c89a4822d74a9d97fef8480707d584da4d
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Feb 23 21:50:18 2021 +0000
+Date: Tue Jun 8 07:07:15 2021 +0000
- upstream: Correct reference to signature algorithms as keys; from
+ upstream: Switch ssh_config parsing to use argv_split()
- Jakub Jelen
+ This fixes a couple of problems with the previous tokeniser,
+ strdelim()
- 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.
+ 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 ffcdd3d90e74176b3bb22937ad1f65a6c1cd3f9d
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Mon Feb 22 08:09:27 2021 +1100
+commit d786424986c04d1d375f231fda177c8408e05c3e
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Tue Jun 8 07:02:46 2021 +0000
- Valgrind test: split and move up list.
+ upstream: Check if IPQoS or TunnelDevice are already set before
- 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.
+ overriding. Prevents values in config files from overriding values supplied
+ on the command line. bz#3319, ok markus.
+
+ OpenBSD-Commit-ID: f3b08b898c324debb9195e6865d8999406938f74
-commit c3b1636770785cc2830dedd0f22ef7d3d3491d6d
+commit aae4b4d3585b9f944d7dbd3c9e5ba0006c55e457
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Feb 23 00:05:31 2021 +0000
+Date: Tue Jun 8 06:54:40 2021 +0000
- upstream: warn when the user specifies a ForwardAgent path that does
+ upstream: Allow argv_split() to optionally terminate tokenisation
- not exist and exit if ExitOnForwardFailure is set; bz3264
+ when it encounters an unquoted comment.
- OpenBSD-Commit-ID: 72f7875865e723e464c71bf8692e83110699bf26
+ 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 5fcb0514949d61aadaf4a89cf16eb78fb47491ec
+commit da9f9acaac5bab95dca642b48e0c8182b246ab69
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Feb 20 13:34:02 2021 +1100
+Date: Mon Jun 7 19:19:23 2021 +1000
- 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.
+ Save logs on failure for upstream test
-commit bb0b9bf45396c19486080d3eb0a159f94de7e6ba
+commit 76883c60161e5f3808787085a27a8c37f8cc4e08
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Feb 20 13:06:25 2021 +1100
+Date: Mon Jun 7 14:36:32 2021 +1000
- Upload valgrind logs on failure.
+ Add obsdsnap-i386 upstream test target.
-commit ebb3b75e974cb241c6b9b9f5881b09c7bd32b651
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Feb 19 22:18:50 2021 +1100
+commit d45b9c63f947ec5ec314696e70281f6afddc0ac3
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Jun 7 03:38:38 2021 +0000
- Rename "vm" to "os" in selfhosted to match c-cpp.
+ upstream: fix debug message when finding a private key to match a
- Should make it easier to share code or maybe merge at some point.
+ 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 76c0be0fe0465cb2b975dbd409f8d38b55e55bcb
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Feb 19 22:15:22 2021 +1100
+commit 530739d42f6102668aecd699be0ce59815c1eceb
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sun Jun 6 11:34:16 2021 +0000
- Upload regress failure logs in c-cpp too.
+ 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 8751b6c3136f5225c40f41bbf29aa29e15795f6e
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Feb 19 22:13:36 2021 +1100
+commit 4265215d7300901fd7097061c7517688ade82f8e
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sun Jun 6 03:40:39 2021 +0000
- Comment out Solaris 64bit PAM build...
+ upstream: Client-side workaround for a bug in OpenSSH 7.4: this release
- until I can figure out why it's failing.
+ 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 e9f6d563c06886b277c6b9abafa99fa80726dc48
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Feb 19 10:20:17 2021 +1100
+commit bda270d7fb8522d43c21a79a4b02a052d7c64de8
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sun Jun 6 03:17:02 2021 +0000
- Actually run Valgrind tests.
+ 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 41d232e226624f1a81c17091c36b44c9010aae62
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Feb 19 10:16:56 2021 +1100
+commit d345d5811afdc2d6923019b653cdd93c4cc95f76
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sun Jun 6 03:15:39 2021 +0000
- Add test against Valgrind.
+ 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 e6528d91f12fba05f0ea64224091c9d0f38bdf1d
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Feb 18 16:30:01 2021 +1100
+commit 2b71010d9b43d7b8c9ec1bf010beb00d98fa765a
+Author: naddy@openbsd.org <naddy@openbsd.org>
+Date: Sat Jun 5 13:47:00 2021 +0000
- Add fbsd12 test target.
+ upstream: PROTOCOL.certkeys: update reference from IETF draft to
+
+ RFC
+
+ Also fix some typos.
+ ok djm@
+
+ OpenBSD-Commit-ID: 5e855b6c5a22b5b13f8ffa3897a868e40d349b44
-commit 6506cb2798d98ff03a7cc06567c392a81f540680
+commit aa99b2d9a3e45b943196914e8d8bf086646fdb54
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Feb 18 15:21:13 2021 +1100
+Date: Fri Jun 4 23:41:29 2021 +1000
- Remove unused arg.
+ Clear notify_pipe from readset if present.
+
+ Prevents leaking an implementation detail to the caller.
-commit 93c31a623973b0fad508214593aab6ca94b11dcb
+commit 6de8dadf6b4d0627d35bca0667ca44b1d61c2c6b
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Feb 18 14:54:07 2021 +1100
+Date: Fri Jun 4 23:24:25 2021 +1000
- Add DEBUG_SK to kitchensink builds.
+ space->tabs.
-commit 65085740d3574eeb3289d592f042df62c2689bb0
+commit c8677065070ee34c05c7582a9c2f58d8642e552d
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
+Date: Fri Jun 4 18:39:48 2021 +1000
- upstream: Fix the hostkeys rotation extension documentation
+ Add pselect implementation for platforms without.
- The documentation was lacking the needed want-reply field in the initial
- global request.
+ 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.
- https://github.com/openssh/openssh-portable/pull/218 by dbussink
+ 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
- OpenBSD-Commit-ID: 051824fd78edf6d647a0b9ac011bf88e28775054
+ 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 34c5ef6e2d06d9f0e20cb04a9aebf67a6f96609a
+commit e7606919180661edc7f698e6a1b4ef2cfb363ebf
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Feb 18 02:15:07 2021 +0000
+Date: Fri Jun 4 06:19:07 2021 +0000
- upstream: make names in function prototypes match those in
+ upstream: The RB_GENERATE_STATIC(3) macro expands to a series of
- definition from https://github.com/openssh/openssh-portable/pull/225 by
- ZenithalHourlyRate
+ function definitions and not a statement, so there should be no semicolon
+ following them. Patch from Michael Forney
- OpenBSD-Commit-ID: 7c736307bf3f2c7cb24d6f82f244eee959485acd
+ OpenBSD-Commit-ID: c975dd180580f0bdc0a4d5b7d41ab1f5e9b7bedd
-commit 88e3d4de31ab4f14cac658e9e0c512043b15b146
+commit c298c4da574ab92df2f051561aeb3e106b0ec954
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Feb 18 02:13:58 2021 +0000
+Date: Fri Jun 4 05:59:18 2021 +0000
- upstream: unbreak SK_DEBUG builds
+ upstream: rework authorized_keys example section, removing irrelevant
- from https://github.com/openssh/openssh-portable/pull/225 by
- ZenithalHourlyRate
+ stuff, de-wrapping the example lines and better aligning the examples with
+ common usage and FAQs; ok jmc
- OpenBSD-Commit-ID: 28d7259ce1b04d025411464decfa2f1a097b43eb
+ OpenBSD-Commit-ID: d59f1c9281f828148e2a2e49eb9629266803b75c
-commit 788cbc5b74a53956ba9fff11e1ca506271a3597f
+commit d9cb35bbec5f623589d7c58fc094817b33030f35
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Feb 18 00:30:17 2021 +0000
+Date: Fri Jun 4 05:10:03 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@
+ upstream: adjust SetEnv description to clarify $TERM handling
- OpenBSD-Commit-ID: f96293221e5aa24102d9bf30e4f4ef04d5f4fb51
+ OpenBSD-Commit-ID: 8b8cc0124856bc1094949d55615e5c44390bcb22
-commit 324449a68d510720d0e4dfcc8e9e5a702fe6a48f
-Author: Damien Miller <djm@mindrot.org>
-Date: Thu Feb 18 12:06:25 2021 +1100
+commit 771f57a8626709f2ad207058efd68fbf30d31553
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Jun 4 05:09:08 2021 +0000
- support OpenSSL 3.x cipher IV API change
+ upstream: Switch the listening select loop from select() to
- OpenSSL renamed the "get current CIPHER_CTX" IV operation in 3.x.
- This uses the new name if available.
+ 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.
- https://github.com/openssl/openssl/issues/13411
+ 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@
- bz#3238 ok dtucker@
+ OpenBSD-Commit-ID: bf85bf880fd78e00d7478657644fcda97b9a936f
-commit 845fe9811c047063d935eca89188ed55c993626b
-Author: Damien Miller <djm@mindrot.org>
-Date: Thu Feb 18 11:25:38 2021 +1100
+commit f64f8c00d158acc1359b8a096835849b23aa2e86
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Jun 4 05:02:40 2021 +0000
- prefer login_getpwclass() to login_getclass()
+ upstream: allow ssh_config SetEnv to override $TERM, which is otherwise
- 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.
+ 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@
- 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.
+ OpenBSD-Commit-ID: 38b1ef4d5bc159c7d9d589d05e3017433e2d5758
-commit f060c2bc85d59d111fa18a12eb3872ee4b9f7e97
-Author: Damien Miller <djm@mindrot.org>
-Date: Thu Feb 18 10:33:58 2021 +1100
+commit 60107677dc0ce1e93c61f23c433ad54687fcd9f5
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Jun 4 04:02:21 2021 +0000
- don't free string returned by login_getcapstr(3)
+ upstream: correct extension name "no-presence-required" =>
- OpenBSD and NetBSD require the caller to free strings returned
- bu the login_* functions, but FreeBSD requires that callers don't.
+ "no-touch-required"
- Fortunately in this case, we can harmlessly leak as the process is
- about to exec the shell/command.
+ document "verify-required" option
- 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.
+ OpenBSD-Commit-ID: 1879ff4062cf61d79b515e433aff0bf49a6c55c5
-commit 1c293868e4b4e8e74e3ea15b8dff90f6b089967a
+commit ecc186e46e3e30f27539b4311366dfda502f0a08
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Feb 18 10:05:03 2021 +1100
+Date: Wed Jun 2 13:54:11 2021 +1000
- Always intall moduli.
+ Retire fbsd7 test target.
- Allows us to run tests without falling back to a fixed modulus. Ensure that
- the directory exists.
+ 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 5c8f41ad100601ec2fdcbccdfe92890c31f81bbe
+commit 5de0867b822ec48b5eec9abde0f5f95d1d646546
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Feb 18 09:59:09 2021 +1100
+Date: Wed Jun 2 11:21:40 2021 +1000
- Quote SSHD_CONFOPTS in case it contains spaces.
+ Check for $OPENSSL in md5 fallback too.
-commit 4653116c1f5384ea7006e6396d9b53c33d218975
+commit 1db69d1b6542f8419c04cee7fd523a4a11004be2
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Feb 18 09:51:18 2021 +1100
+Date: Wed Jun 2 11:17:54 2021 +1000
- Fix labels on targets (dots vs underscores).
+ Add dfly60 target.
-commit 4512047f57ca3c6e8cd68f0cc69be59e98b25287
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Feb 17 21:47:48 2021 +1100
+commit a3f2dd955f1c19cad387a139f0e719af346ca6ef
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Wed Jun 2 00:17:45 2021 +0000
- More compact representation of config matrix.
+ upstream: Merge back shell portability changes
+
+ bringing it back in sync with -portable.
+
+ OpenBSD-Regress-ID: c07905ba931e66ad7d849b87b7d19648007175d1
-commit 0406cd09f05c2e419b113dd4c0eac8bc34ec915b
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Feb 17 21:19:18 2021 +1100
+commit 9d482295c9f073e84d75af46b720a1c0f7ec2867
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Tue Jun 1 23:56:20 2021 +0000
- Skip unit tests on hosted VMs to speed things up.
+ 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 4582612e6147d766c336198c498740242fb8f1ec
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Feb 17 20:21:29 2021 +1100
+commit 07660b3c99f8ea74ddf4a440e55c16c9f7fb3dd1
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Mon May 24 10:25:18 2021 +0000
- Merge macos and ubuntu tests.
+ 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 09f4b84654b71099559492e9aed5e1a38bf24815
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Feb 17 18:41:30 2021 +1100
+commit 1a4d1da9188d7c88f646b61f0d6a3b34f47c5439
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri May 21 04:03:47 2021 +0000
- Convert most github hosted tests to new config structure.
+ upstream: fix memleak in test
+
+ OpenBSD-Regress-ID: 5e529d0982aa04666604936df43242e97a7a6f81
-commit 65380ff7e054be1454e5ab4fd7bb9c66f8fcbaa9
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Feb 17 18:27:36 2021 +1100
+commit 60455a5d98065a73ec9a1f303345856bbd49aecc
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri May 21 03:59:01 2021 +0000
- Only run selfhosted tests from selfhosted repo.
+ upstream: also check contents of remaining string
+
+ OpenBSD-Regress-ID: d526fa07253f4eebbc7d6205a0ab3d491ec71a28
-commit f031366535650b88248ed7dbf23033afdf466240
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Jan 15 14:11:43 2021 +1100
+commit 39f6cd207851d7b67ca46903bfce4a9f615b5b1c
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri May 21 03:48:07 2021 +0000
- 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.
+ upstream: unit test for misc.c:strdelim() that mostly servces to
- 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.
+ highlight its inconsistencies
- [0] https://docs.github.com/en/actions/hosting-your-own-runners/about-self-hosted-runners#self-hosted-runner-security-with-public-repositories
+ OpenBSD-Regress-ID: 8d2bf970fcc01ccc6e36a5065f89b9c7fa934195
-commit 64bbd7444d658ef7ee14a7ea5ccc7f5810279ee7
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Wed Feb 17 03:59:00 2021 +0000
+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: Make sure puttygen is new enough to successfully run the
+ upstream: Hash challenge supplied by client during FIDO key enrollment
- PuTTY interop tests, otherwise skip them.
+ prior to passing it to libfido2, which does expect a hash.
- 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
+ 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).
- with SOCKS ok djm@, dtucker@
+ ok markus@
- OpenBSD-Commit-ID: 64fe7b6360acc4ea56aa61b66498b5ecc0a96a7c
+ OpenBSD-Commit-ID: b8d5363a6a7ca3b23dc28f3ca69470472959f2b5
-commit b696858a7f9db72a83d02cb6edaca4b30a91b386
-Author: markus@openbsd.org <markus@openbsd.org>
-Date: Mon Feb 15 20:36:35 2021 +0000
+commit eb68e669bc8ab968d4cca5bf1357baca7136a826
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu May 27 21:14:15 2021 +1000
- upstream: factor out opt_array_append; ok djm@
+ Include login_cap.h for login_getpwclass override.
- OpenBSD-Commit-ID: 571bc5dd35f99c5cf9de6aaeac428b168218e74a
+ On minix3, login_getpwclass is __RENAME'ed to __login_getpwclass50 so
+ without this the include overriding login_getpwclass causes a compile
+ error.
-commit ad74fc127cc45567e170e8c6dfa2cfd9767324ec
-Author: dlg@openbsd.org <dlg@openbsd.org>
-Date: Mon Feb 15 11:09:22 2021 +0000
+commit 2063af71422501b65c7a92a5e14c0e6a3799ed89
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu May 27 21:13:38 2021 +1000
- upstream: ProxyJump takes "none" to disable processing like
-
- ProxyCommand does
-
- ok djm@ jmc@
-
- OpenBSD-Commit-ID: 941a2399da2193356bdc30b879d6e1692f18b6d3
+ Add minix3 test target.
-commit 16eacdb016ccf38dd9959c78edd3a6282513aa53
+commit 2e1efcfd9f94352ca5f4b6958af8a454f8cf48cd
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Feb 12 03:49:09 2021 +0000
+Date: Wed May 26 01:47:24 2021 +0000
- upstream: sftp: add missing lsetstat@openssh.com documentation
+ upstream: fix SEGV in UpdateHostkeys debug() message, triggered
- patch from Mike Frysinger
+ when the update removed more host keys than remain present. Fix tested by
+ reporter James Cook, via bugs@
- OpenBSD-Commit-ID: 9c114db88d505864075bfe7888b7c8745549715b
+ OpenBSD-Commit-ID: 44f641f6ee02bb957f0c1d150495b60cf7b869d3
-commit e04fd6dde16de1cdc5a4d9946397ff60d96568db
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Feb 12 03:14:18 2021 +0000
+commit 9acd76e6e4d2b519773e7119c33cf77f09534909
+Author: naddy@openbsd.org <naddy@openbsd.org>
+Date: Sun May 23 18:22:57 2021 +0000
- upstream: factor SSH_AGENT_CONSTRAIN_EXTENSION parsing into its own
+ upstream: ssh: The client configuration keyword is
- function and remove an unused variable; ok dtucker@
+ "hostbasedacceptedalgorithms"
- 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 fixes a mistake that slipped in when "HostbasedKeyTypes" was
+ renamed to "HostbasedAcceptedAlgorithms".
- 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.
+ Bug report by zack@philomathiclife.com
+
+ OpenBSD-Commit-ID: d745a7e8e50b2589fc56877f322ea204bc784f38
-commit f88a7a431212a16e572ecabd559e632f369c363e
+commit 078a0e60c92700da4c536c93c007257828ccd05b
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Feb 6 09:37:01 2021 +1100
+Date: Tue May 25 11:40:47 2021 +1000
- Add a hostname function for systems that don't have it.
+ Rename README.md to ci-status.md.
- 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.
+ 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 5e385a71ef2317856f37c91a98658eb12eb5a89c
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Feb 5 22:03:40 2021 +0000
+commit 7be4ac813662f68e89f23c50de058a49aa32f7e4
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed May 19 01:24:05 2021 +0000
- upstream: Roll back the hostname->uname change in rev 1.10. It turns
+ upstream: restore blocking status on stdio fds before close
- 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.
+ 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.
- OpenBSD-Regress-ID: 827a707d6201d5a8e196a8c28aec1d2c76c52341
+ > $ 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 b446c214279de50ed8388e54897eb1be5281c894
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Feb 5 06:01:58 2021 +0000
+commit c4902e1a653c67fea850ec99c7537f358904c0af
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon May 17 11:43:16 2021 +0000
- upstream: hostname is not specified by POSIX but uname -n is, so use
+ upstream: fix breakage of -W forwaring introduced in 1.554; reported by
- the latter for portability. Patch from Geert Hendrickx via github PR#208.
+ naddy@ and sthen@, ok sthen@
- OpenBSD-Regress-ID: d6a79c7c4d141a0d05ade4a042eb57dddbce89f3
+ OpenBSD-Commit-ID: f72558e643a26dc4150cff6e5097b5502f6c85fd
-commit 1cb6ce98d658e5fbdae025a3bd65793980e3b5d9
-Author: David Carlier <devnexen@gmail.com>
-Date: Sat Nov 21 12:22:23 2020 +0000
+commit afea01381ad1fcea1543b133040f75f7542257e6
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Mon May 17 07:22:45 2021 +0000
- Using explicit_memset for the explicit_bzero compatibility layer.
+ upstream: Regenerate moduli.
- Favoriting the native implementation in this case.
+ OpenBSD-Commit-ID: 83c93a2a07c584c347ac6114d6329b18ce515557
-commit 2e0beff67def2120f4b051b1016d7fbf84823e78
-Author: Luca Weiss <luca@z3ntu.xyz>
-Date: Sun Nov 8 14:19:23 2020 +0100
+commit be2866d6207b090615ff083c9ef212b603816a56
+Author: Damien Miller <djm@mindrot.org>
+Date: Mon May 17 09:40:23 2021 +1000
- Deny (non-fatal) statx in preauth privsep child.
+ Handle Android libc returning NULL pw->pw_passwd
+
+ Reported by Luke Dashjr
-commit a35d3e911e193a652bd09eed40907e3e165b0a7b
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Feb 5 02:20:23 2021 +0000
+commit 5953c143008259d87342fb5155bd0b8835ba88e5
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri May 14 05:20:32 2021 +0000
- upstream: Remove debug message from sigchld handler. While this
+ upstream: fix previous: test saved no_shell_flag, not the one that just
- works on OpenBSD it can cause problems on other platforms. From kircherlike
- at outlook.com via bz#3259, ok djm@
+ got clobbered
- OpenBSD-Commit-ID: 3e241d7ac1ee77e3de3651780b5dc47b283a7668
+ OpenBSD-Commit-ID: b8deace085d9d941b2d02f810243b9c302e5355d
-commit 69338ab46afe9e3dfb7762ad65351d854077c998
+commit 1e9fa55f4dc4b334651d569d3448aaa3841f736f
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Feb 2 22:36:59 2021 +0000
+Date: Fri May 14 03:09:48 2021 +0000
- upstream: whitespace
+ upstream: Fix ssh started with ControlPersist incorrectly executing a
- OpenBSD-Commit-ID: 544bb092e03fcbecb420196cd0f70af13ea868ad
+ shell when the -N (no shell) option was specified. bz3290 reported by Richard
+ Schwab; patch from markus@ ok me
+
+ OpenBSD-Commit-ID: ea1ea4af16a95687302f7690bdbe36a6aabf87e1
-commit f71219a01d8f71c4b3ed7e456337a84ddba1653e
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Feb 2 22:36:46 2021 +0000
+commit d1320c492f655d8f5baef8c93899d79dded217a5
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Wed May 12 11:34:30 2021 +0000
- upstream: fix memleaks in private key deserialisation; enforce more
+ upstream: Clarify language about moduli. While both ends of the
- consistency between redundant fields in private key certificate and private
- key body; ok markus@
+ 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: dec344e414d47f0a7adc13aecf3760fe58101240
+ OpenBSD-Commit-ID: f0c18cc8e79c2fbf537a432a9070ed94e96a622a
-commit 3287790e78bf5b53c4a3cafb67bb5aa03e3910f0
+commit d3cc4d650ce3e59f3e370b101778b0e8f1c02c4d
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Feb 2 22:35:14 2021 +0000
+Date: Fri May 7 04:11:51 2021 +0000
- upstream: memleak on error path; ok markus@
+ upstream: include pid in LogVerbose spam
- OpenBSD-Commit-ID: 2091a36d6ca3980c81891a6c4bdc544e63cb13a8
+ OpenBSD-Commit-ID: aacb86f96ee90c7cb84ec27452374285f89a7f00
-commit 3dd0c64e08f1bba21d71996d635c7256c8c139d1
+commit e3c032333be5fdbbaf2751f6f478e044922b4ec4
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Jan 31 22:55:29 2021 +0000
+Date: Fri May 7 03:09:38 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).
+ upstream: don't sigdie() in signal handler in privsep child process;
- ok markus@
+ this can end up causing sandbox violations per bz3286; ok dtucker@
- OpenBSD-Commit-ID: 87331c715c095b587d5c88724694cdeb701c9def
+ OpenBSD-Commit-ID: a7f40b2141dca4287920da68ede812bff7ccfdda
-commit 7a92a324a2e351fabd0ba8ef9b434d3b12d54ee3
+commit a4039724a3f2abac810735fc95cf9114a3856049
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Sun Jan 31 10:50:10 2021 +0000
+Date: Fri May 7 09:23:40 2021 +0000
- upstream: Set linesize returned by getline to zero when freeing and
+ upstream: Increase ConnectionAttempts from 4 to 10 as the tests
- NULLing the returned string. OpenBSD's getline handles this just fine, but
- some implementations used by -portable do not. ok djm@
+ occasionally time out on heavily loaded hosts.
- OpenBSD-Commit-ID: 4d7bd5169d3397654247db9655cc69a9908d165c
+ OpenBSD-Regress-ID: 29a8cdef354fc9da471a301f7f65184770434f3a
-commit a5dfc5bae8c16e2a7caf564758d812c7672480b5
-Author: Damien Miller <djm@mindrot.org>
-Date: Sat Jan 30 16:32:29 2021 +1100
+commit c0d7e36e979fa3cdb60f5dcb6ac9ad3fd018543b
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri May 7 02:26:55 2021 +0000
- allow a fuzz case to contain more than one request
+ upstream: dump out a usable private key string too; inspired by Tyson
- 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
+ Whitehead
- might make life a little easier for the fuzzer, e.g. it can now
- produce valid (multi-request) messages by smashing two cases together.
+ OpenBSD-Regress-ID: 65572d5333801cb2f650ebc778cbdc955e372058
-commit de613f2713d2dfcd3b03c00e5558a40997f52712
-Author: Damien Miller <djm@mindrot.org>
-Date: Sat Jan 30 12:03:30 2021 +1100
+commit 24fee8973abdf1c521cd2c0047d89e86d9c3fc38
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri May 7 02:29:40 2021 +0000
- ssh-agent fuzzer
+ 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 7e96c877bcb2fb645355a687b8cb7347987c1c58
-Author: Damien Miller <djm@mindrot.org>
-Date: Sat Jan 30 12:02:46 2021 +1100
+commit f43859159cc62396ad5d080f0b1f2635a67dac02
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Tue May 4 22:53:52 2021 +0000
- move keys out of kex_fuzz.cc into separate header
+ upstream: Don't pass NULL as a string in debugging as it does not work
+
+ on some platforms in -portable. ok djm@
- add certificates and missing key types
+ OpenBSD-Commit-ID: 937c892c99aa3c9c272a8ed78fa7c2aba3a44fc9
-commit 76f46d75664fdaa1112739ca523ff85ee4eb52b4
-Author: Damien Miller <djm@mindrot.org>
-Date: Sat Jan 30 12:02:10 2021 +1100
+commit ac31aa3c6341905935e75f0539cf4a61bbe99779
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon May 3 00:16:45 2021 +0000
- some fixed test data (mostly keys) for fuzzing
+ upstream: more debugging for UpdateHostKeys signature failures
+
+ OpenBSD-Commit-ID: 1ee95f03875e1725df15d5e4bea3e73493d57d36
-commit 7c2e3d6de1f2edb0c8b4725b4c2b56360e032b19
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Jan 30 00:56:38 2021 +0000
+commit 8e32e97e788e0676ce83018a742203614df6a2b3
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat May 1 20:07:47 2021 +1000
- 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
+ Add obsd69 test target.
-commit 1a4b92758690faa12f49079dd3b72567f909466d
+commit f06893063597c5bb9d9e93f851c4070e77d2fba9
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jan 29 06:29:46 2021 +0000
+Date: Fri Apr 30 04:29:53 2021 +0000
- upstream: fix the values of enum sock_type
+ upstream: a little debugging in the main mux process for status
+
+ confirmation failures in multiplexed sessions
- OpenBSD-Commit-ID: 18d048f4dbfbb159ff500cfc2700b8fb1407facd
+ OpenBSD-Commit-ID: 6e27b87c95176107597035424e1439c3232bcb49
-commit 8afaa7d7918419d3da6c0477b83db2159879cb33
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jan 29 06:28:10 2021 +0000
+commit e65cf00da6bc31e5f54603b7feb7252dc018c033
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Apr 30 04:02:52 2021 +0000
- upstream: give typedef'd struct a struct name; makes the fuzzer I'm
+ upstream: Remove now-unused skey function prototypes leftover from
- writing a bit easier
+ skey removal.
- 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
+ OpenBSD-Commit-ID: 2fc36d519fd37c6f10ce74854c628561555a94c3
-commit 3d59e88c0e42182c3749b446ccd9027933c84be4
+commit ae5f9b0d5c8126214244ee6b35aae29c21028133
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Jan 28 20:55:16 2021 +1100
+Date: Thu Apr 29 13:01:50 2021 +1000
- make with -j2 to use available CPUs.
+ Wrap sntrup761x25519 inside ifdef.
+
+ From balu.gajjala at gmail.com via bz#3306.
-commit 66dd9ddb5d2ea8c407908c8e8468c9d6e71db05b
+commit 70a8dc138a6480f85065cdb239915ad4b7f928cf
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Thu Jan 28 14:31:01 2021 +1100
+Date: Wed Apr 28 14:44:07 2021 +1000
- Add test against openssl head and libressl head.
+ Add status badges for Actions-based tests.
-commit 237dbb34e24b6b7ea888d54bda4d17da0a0fd0fa
+commit 40b59024cc3365815381474cdf4fe423102e391b
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
+Date: Wed Apr 28 12:22:11 2021 +1000
- upstream: fix leak: was double allocating kex->session_id buffer
-
- OpenBSD-Commit-ID: 3765f4cc3ae1df874dba9102a3588ba7b48b8183
+ Add obsdsnap (OpenBSD snapshot) test target.
-commit 1134a48cdcef8e7363b9f6c73ebdd24405066738
-Author: Damien Miller <djm@mindrot.org>
-Date: Thu Jan 28 08:57:31 2021 +1100
+commit e627067ec8ef9ae8e7a638f4dbac91d52dee3e6d
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Apr 28 11:35:28 2021 +1000
- correct kex name in disabled code
+ Add test building upstream OpenBSD source.
-commit 67f47f1965abafc1830a287761125c2f4790857e
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Jan 27 10:15:08 2021 +0000
+commit 1b8108ebd12fc4ed0fb39ef94c5ba122558ac373
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Tue Apr 27 14:22:20 2021 +1000
- upstream: this needs kex.h now
+ Test against OpenSSL 1.1.0h instead of 1.1.0g.
- OpenBSD-Commit-ID: c5a42166c5aa002197217421a971e48be7cb5d41
+ 1.1.0g requires a perl glob module that's not installed by default.
-commit 39be3dc209f28f9c1ebfeba42adde8963b01e1cd
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Jan 27 10:05:28 2021 +0000
+commit 9bc20efd39ce8525be33df3ee009f5a4564224f1
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Tue Apr 27 12:37:59 2021 +1000
- 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
+ Use the default VM type for libcrypto ver tests.
-commit 4ca6a1fac328477c642329676d6469dba59019a3
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Jan 27 09:26:53 2021 +0000
+commit 9f79e80dc40965c2e73164531250b83b176c1eea
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Tue Apr 27 12:24:10 2021 +1000
- upstream: remove global variable used to stash compat flags and use the
-
- purpose-built ssh->compat variable instead; feedback/ok markus@
+ Always build OpenSSL shared.
- OpenBSD-Commit-ID: 7c4f200e112dae6bcf99f5bae1a5629288378a06
+ This is the default for current versions but we need it to test against
+ earlier versions.
-commit bba229b6f3328171f5e3ae85de443002523c0452
+commit b3cc9fbdff2782eca79e33e02ac22450dc63bce9
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Jan 27 12:34:07 2021 +1100
+Date: Tue Apr 27 09:18:02 2021 +1000
- Install moduli file before tests.
+ Fix custom OpenSSL tests.
- Reduces warnings during test runs.
+ 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 1b83185593a90a73860a503d753a95ca6d726c00
+commit 77532609874a99a19e3e2eb2d1b7fa93aef963bb
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Jan 27 11:58:26 2021 +1100
+Date: Mon Apr 26 17:18:25 2021 +1000
- Run one test with -Werror to catch warnings.
+ Export CC and CFLAGS for c89 test.
-commit d1532d90074b212054d5fd965f833231b09982f5
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Wed Jan 27 00:37:26 2021 +0000
+commit 33f62dfbe865f4de77980ab88774bf1eb5e4e040
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Apr 26 17:13:44 2021 +1000
- upstream: Logical not bitwise or. ok djm@
-
- OpenBSD-Commit-ID: d4dc855cf04951b93c45caa383e1ac9af0a3b0e5
+ Add c89 here too.
-commit 507b448a2465a53ab03a88acbc71cc51b48ca6ac
-Author: naddy@openbsd.org <naddy@openbsd.org>
-Date: Tue Jan 26 15:40:17 2021 +0000
+commit da9d59f526fce58e11cba49cd8eb011dc0bf5677
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Apr 26 15:34:23 2021 +1000
- upstream: move HostbasedAcceptedAlgorithms to the right place in
-
- alphabetical order
-
- OpenBSD-Commit-ID: d766820d33dd874d944c14b0638239adb522c7ec
+ Add test against OpenSSL w/out ECC.
-commit e26c980778b228bdd42b8353cc70101cf49b731b
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Tue Jan 26 11:25:01 2021 +0000
+commit 29e194a752359ebf85bf7fce100f23a0477fc4de
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Apr 26 14:49:59 2021 +1000
- upstream: Remove unused variables leftover from refactoring. ok
-
- djm@
-
- OpenBSD-Commit-ID: 8b3ad58bff828fcf874e54b2fc27a4cf1d9505e8
+ Ensure we can still build with C89.
-commit e9f78d6b06fc323bba1890b2dc3b8423138fb35c
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Tue Jan 26 05:32:21 2021 +0000
+commit a38016d369d21df5d35f761f2b67e175e132ba22
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Apr 26 14:29:03 2021 +1000
- 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
+ Interop test agains PuTTY.
-commit 48d0d7a4dd31154c4208ec39029d60646192f978
+commit 095b0307a77be8803768857cc6c0963fa52ed85b
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Tue Jan 26 14:48:07 2021 +1100
+Date: Mon Apr 26 14:02:03 2021 +1000
- 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.
+ Support testing against arbitary libcrytpo vers.
- This should allow OpenSSH to build with a plain C89 compiler again.
- Spotted by tim@, ok djm@.
+ Add tests against various LibreSSL and OpenSSL versions.
-commit 37c70ea8d4f3664a88141bcdf0bf7a16bd5fd1ac
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Jan 26 00:54:49 2021 +0000
+commit b16082aa110fa7128ece2a9037ff420c4a285317
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Apr 26 13:35:44 2021 +1000
- 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
+ Add fbsd10 test target.
-commit e0e8bee8024fa9e31974244d14f03d799e5c0775
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Jan 26 00:53:31 2021 +0000
+commit 2c805f16b24ea37cc051c6018fcb05defab6e57a
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sun Apr 25 14:15:02 2021 +1000
- 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@
+ Disable compiler hardening on nbsd4.
- OpenBSD-Commit-ID: 29006515617d1aa2d8b85cd2bf667e849146477e
+ The system compiler supports -fstack-protector-all, but using it will
+ result in an internal compiler error on some files.
-commit dfe18a295542c169ffde8533b3d7fe42088e2de7
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Jan 26 00:51:30 2021 +0000
+commit 6a5d39305649da5dff1934ee54292ee0cebd579d
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sun Apr 25 13:01:34 2021 +1000
- upstream: make struct hostkeys public; I have no idea why I made it
-
- opaque originally.
-
- ok markus@
-
- OpenBSD-Commit-ID: e50780b34d4bbe628d69b2405b024dd749d982f3
+ Add nbsd3, nbsd4 and nbsd9 test targets.
-commit 3b44f2513cae89c920e8fe927b9bc910a1c8c65a
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Jan 26 00:49:30 2021 +0000
+commit d1aed05bd2e4ae70f359a394dc60a2d96b88f78c
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat Apr 24 22:03:46 2021 +1000
- 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
+ Comment out nbsd2 test target for now.
-commit 1fe16fd61bb53944ec510882acc0491abd66ff76
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Jan 26 00:47:47 2021 +0000
+commit a6b4ec94e5bd5a8a18cd2c9942d829d2e5698837
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat Apr 24 17:52:24 2021 +1000
- 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
+ Add OPENBSD ORIGINAL marker.
-commit cb7b22ea20a01332c81c0ddcb3555ad50de9cce2
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Jan 26 00:46:17 2021 +0000
+commit 3737c9f66ee590255546c4b637b6d2be669a11eb
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Apr 23 19:49:46 2021 +1000
- 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
+ Replace "==" (a bashism) with "=".
-commit d1e578afe7cd48140ad6e92a453f9b035363fd7f
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Jan 25 06:00:17 2021 +0000
+commit a116b6f5be17a1dd345b7d54bf8aa3779a28a0df
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Apr 23 16:34:48 2021 +1000
- 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
+ Add nbsd2 test target.
-commit 95eca1e195a3b41baa1a725c2c5af8a09d885e4b
+commit 196bf2a9bb771f45d9b0429cee7d325962233c44
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sat Jan 23 18:26:05 2021 +1100
+Date: Fri Apr 23 14:54:10 2021 +1000
- 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.
+ Add obsd68 test target.
-commit 6ffdcdda128045226dda7fbb3956407978028a1e
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Mon Jan 18 11:43:34 2021 +0000
+commit e3ba6574ed69e8b7af725cf5e8a9edaac04ff077
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Apr 23 14:53:32 2021 +1000
- upstream: Fix long->int for convtime tests here too. Spotted by
-
- tobhe@.
-
- OpenBSD-Regress-ID: a87094f5863312d00938afba771d25f788c849d0
+ Remove dependency on bash.
-commit b55b7565f15327d82ad7acbddafa90b658c5f0af
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Jan 22 02:46:40 2021 +0000
+commit db1f9ab8feb838aee9f5b99c6fd3f211355dfdcf
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Apr 23 14:41:13 2021 +1000
- upstream: PubkeyAcceptedKeyTypes->PubkeyAcceptedAlgorithms
-
- here too.
-
- OpenBSD-Commit-ID: 3b64a640f8ce8c21d9314da9df7ce2420eefde3a
+ Add obsd67 test target.
-commit ee9c0da8035b3168e8e57c1dedc2d1b0daf00eec
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Jan 22 02:44:58 2021 +0000
+commit c039a6bf79192fe1daa9ddcc7c87dd98e258ae7c
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Apr 23 11:08:23 2021 +1000
- 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
+ Re-add macos-11.0 test target.
-commit a8e798feabe36d02de292bcfd274712cae1d8d17
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Jan 15 02:58:11 2021 +0000
+commit a6db3a47b56adb76870d59225ffb90a65bc4daf2
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Apr 23 10:28:28 2021 +1000
- 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
+ Add openindiana test target.
-commit 9bde1a420626da5007bf7ab499fa2159b9eddf72
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Jan 15 04:31:25 2021 +0000
+commit 3fe7e73b025c07eda46d78049f1da8ed7dfc0c69
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Apr 23 10:26:35 2021 +1000
- 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
+ Test krb5 on Solaris 11 too.
-commit 02da325f10b214219eae2bb1bc2d3bf0c2f13f9f
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Jan 15 02:58:11 2021 +0000
+commit f57fbfe5eb02df1a91f1a237c4d27165afd87c13
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Apr 22 22:27:26 2021 +1000
- 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@
+ Don't always set SUDO.
- OpenBSD-Commit-ID: 01dc0475f1484ac2f47facdfcf9221f9472145de
+ Rely on sourcing configs to set as appropriate.
-commit 5339ab369c225b40bc64d5ec3374f5c91b3ad609
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Jan 15 02:32:41 2021 +0000
+commit e428f29402fb6ac140b52f8f12e06ece7bb104a0
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Apr 22 22:26:08 2021 +1000
- 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
+ Remove now-unused 2nd arg to configs.
-commit a164862dfa863b54b7897f66e1dd75437f086c11
-Author: rob@openbsd.org <rob@openbsd.org>
-Date: Thu Jan 14 19:45:06 2021 +0000
+commit cb4ff640d79b3c736879582139778f016bbb2cd7
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Apr 21 01:08:04 2021 +1000
- upstream: Minor grammatical correction.
-
- OK jmc@
-
- OpenBSD-Commit-ID: de0fad0581e212b2750751e479b79c18ff8cac02
+ Add win10 test target.
-commit 8635e7df7e3a3fbb4a4f6cd5a7202883b2506087
+commit 4457837238072836b2fa3107d603aac809624983
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Jan 13 18:00:57 2021 +1100
+Date: Tue Apr 20 23:31:29 2021 +1000
- Merge Mac OS X targets into a single config.
+ Add nbsd8 test target.
-commit ac112ade990585c511048ed4edaf2d9fc92b61f0
+commit bd4fba22e14da2fa196009010aabec5a8ba9dd42
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Tue Jan 12 19:22:47 2021 +1100
+Date: Sat Apr 17 09:55:47 2021 +1000
- Add Mac OS X test targets.
+ Add obsd51 target.
-commit 1050109b4b2884bf50fd1b3aa084c7fd0a42ae90
-Author: anatasluo <luolongjuna@gmail.com>
-Date: Mon Jan 11 13:51:39 2021 +0000
+commit 9403d0e805c77a5741ea8c3281bbe92558c2f125
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Apr 16 18:14:25 2021 +1000
- Remove duplicated declaration in fatal.c .
+ Add fbsd13 target.
-commit 7d0f8a3369579dfe398536eb4e3da7bc15da9599
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Mon Jan 11 04:48:22 2021 +0000
+commit e86968280e358e62649d268d41f698d64d0dc9fa
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Apr 16 13:55:25 2021 +1000
- upstream: Correct spelling of persourcenetblocksize in config-dump
-
- mode.
-
- OpenBSD-Commit-ID: ecdc49e2b6bde6b6b0e52163d621831f6ac7b13d
+ depend
-commit ba328bd7a6774f30daaf90b83f1933cc4afc866c
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Sat Jan 9 12:31:46 2021 +0000
+commit 2fb25ca11e8b281363a2a2a4dec4c497a1475d9a
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Apr 16 13:53:02 2021 +1000
- upstream: Adjust kexfuzz to addr.c/addrmatch.c split.
-
- OpenBSD-Regress-ID: 1d8d23bb548078020be2fb52c4c643efb190f0eb
+ crank version in README and RPM spec files
-commit b08ef25552443e94c0857d5e3806dd019ccc55d7
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Sat Jan 9 12:24:30 2021 +0000
+commit b2b60ebab0cb77b5bc02d364d72e13db882f33ae
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Apr 16 03:42:00 2021 +0000
- upstream: Update unittests for addr.c/addrmatch.c split.
+ upstream: openssh-8.6
- OpenBSD-Regress-ID: de2b415fb7af084a91c6ef147a90482d8f771eef
+ OpenBSD-Commit-ID: b5f3e133c846127ec114812248bc17eff07c3e19
-commit 6d30673fedec2d251f4962c526fd0451f70c4d97
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Mon Jan 11 02:12:57 2021 +0000
+commit faf2b86a46c9281d237bcdec18c99e94a4eb820a
+Author: markus@openbsd.org <markus@openbsd.org>
+Date: Thu Apr 15 16:24:31 2021 +0000
- upstream: Change convtime() from returning long to returning int.
+ upstream: do not pass file/func to monitor; noted by Ilja van Sprundel;
- 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@
+ ok djm@
- OpenBSD-Commit-ID: 8fc932683d6b4660d52f50911d62bd6639c5db31
+ OpenBSD-Commit-ID: 85ae5c063845c410283cbdce685515dcd19479fa
-commit 7a57adb8b07b2ad0aead4b2e09ee18edc04d0481
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Sat Jan 9 12:51:12 2021 +0000
+commit 2dc328023f60212cd29504fc05d849133ae47355
+Author: Damien Miller <djm@mindrot.org>
+Date: Wed Apr 14 11:42:55 2021 +1000
- upstream: add a comma to previous;
+ sshd don't exit on transient read errors
- OpenBSD-Commit-ID: 9139433701c0aa86a0d3a6c7afe10d1c9c2e0869
+ 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 3a923129534b007c2e24176a8655dec74eca9c46
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Sat Jan 9 12:10:02 2021 +0000
+commit d5d6b7d76d171a2e6861609dcd92e714ee62ad88
+Author: Damien Miller <djm@mindrot.org>
+Date: Sat Apr 10 18:45:00 2021 +1000
- upstream: Add PerSourceMaxStartups and PerSourceNetBlockSize
-
- options which provide more fine grained MaxStartups limits. Man page help
- jmc@, feedback & ok djm@
-
- OpenBSD-Commit-ID: e2f68664e3d02c0895b35aa751c48a2af622047b
+ perform report_failed_grab() inline
-commit d9a2bc71693ea27461a78110005d5a2d8b0c6a50
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Sat Jan 9 11:58:50 2021 +0000
+commit ea996ce2d023aa3c6d31125e2c3ebda1cb42db8c
+Author: Damien Miller <djm@mindrot.org>
+Date: Sat Apr 10 18:22:57 2021 +1000
- upstream: Move address handling functions out into their own file
+ 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.
- 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).
+ This branches gnome-ssk-askpass2.c => gnome-ssk-askpass3.c and
+ makes the changes to use the gdk_seat_grab() instead of grabbing
+ mouse/focus separately via GDK.
- OpenBSD-Commit-ID: e3e7d9ccc6c9b82e25cfef0ec83598e8e2327cbf
+ 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 b744914fcb76d70761f1b667de95841b3fc80a56
+commit bfa5405da05d906ffd58216eb77c4375b62d64c2
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
+Date: Thu Apr 8 15:18:15 2021 +1000
- 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@
+ Ensure valgrind-out exists.
- OpenBSD-Commit-ID: 0db98413e82074f78c7d46784b1286d08aee78f0
+ Normally the regress tests would create it, but running the unit tests
+ on their own would fail because the directory did not exist.
-commit 309b642e1442961b5e57701f095bcd4acd2bfb5f
+commit 1f189181f3ea09a9b08aa866f78843fec800874f
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Jan 8 15:50:41 2021 +1100
+Date: Thu Apr 8 15:17:19 2021 +1000
- Run tests with sudo for better coverage.
+ Pass OBJ to unit test make invocation.
+
+ At least the Valgrind unit tests uses $OBJ.
-commit c336644351fa3c715a08b7a292e309e72792e71e
+commit f42b550c281d28bd19e9dd6ce65069164f3482b0
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Jan 8 14:26:32 2021 +1100
+Date: Thu Apr 8 14:20:12 2021 +1000
- Add Ubuntu 16.04 and 20.04 test targets.
+ Add pattern for valgrind-unit.
-commit 4c7af01f9dcc1606dec033e7665a042cb0d8ec52
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jan 8 02:57:24 2021 +0000
+commit 19e534462710e98737478fd9c44768b50c27c4c6
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Apr 8 13:31:08 2021 +1000
- 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@
+ Run unit tests under valgrind.
- OpenBSD-Commit-ID: 176db8518933d6a5bbf81a2e3cf62447158dc878
+ 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 64ddd0fe68c4a7acf99b78624f8af45e919cd317
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jan 8 02:44:14 2021 +0000
+commit 80032102d05e866dc2a48a5caf760cf42c2e090e
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Apr 8 13:25:57 2021 +1000
- 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.
+ ifdef out MIN and MAX.
- OpenBSD-Commit-ID: 65b5e9f18bb0d10573868c3516de6e5170adb163
+ 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 599df78f3008cf78af21f8977be3e1dd085f8e2e
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Jan 8 02:33:13 2021 +0000
+commit d1bd184046bc310c405f45da3614a1dc5b3e521a
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Apr 7 10:23:51 2021 +1000
- 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@
+ Remove only use of warn().
- OpenBSD-Commit-ID: 7b9d0cf3acd5a3c1091da8afe00c904d38cf5783
+ 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 16448ff529affda7e2a15ee7c3200793abde0759
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Jan 8 02:19:24 2021 +0000
+commit fea8f4b1aa85026ad5aee5ad8e1599a8d5141fe0
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Apr 7 10:18:32 2021 +1000
- upstream: mention that DisableForwarding is valid in a sshd_config
-
- Match block reported by Fredrik Eriksson in bz3239
+ Move make_tmpdir() into portable-specific area.
- OpenBSD-Commit-ID: 3a71c3d84b597f5e43e4b40d5232797daf0993f6
+ Reduces diff vs OpenBSD and makes it more likely diffs will apply
+ cleanly.
-commit 91bac5e95b1b0debf9b2b4f05c20dcfa96b368b9
+commit 13e5fa2acffd26e754c6ee1d070d0afd035d4cb7
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Mon Jan 4 21:58:58 2021 +0000
+Date: Tue Apr 6 23:57:56 2021 +0000
- upstream: estructure sntrup761.sh to process all files in a single
+ upstream: Add TEST_SSH_ELAPSED_TIMES environment variable to print the
- list, which will make it easier to reorder. Re-inline int32_MINMAX. ok
- tobhe@
+ elapsed time in seconds of each test. This depends on "date +%s" which is
+ not specified by POSIX but is commonly implemented.
- OpenBSD-Commit-ID: d145c6c19b08bb93c9e14bfaa7af589d90f144c0
+ OpenBSD-Regress-ID: ec3c8c19ff49b2192116a0a646ee7c9b944e8a9c
-commit 4d96a3ebab2224f17e639a15078e03be1ad3736d
-Author: tobhe@openbsd.org <tobhe@openbsd.org>
-Date: Sun Jan 3 18:05:21 2021 +0000
+commit ef4f46ab4387bb863b471bad124d46e8d911a79a
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Apr 7 09:59:15 2021 +1000
- upstream: Prevent redefinition of `crypto_int32' error with gcc3.
-
- Fixes compilation on luna88k.
-
- Feedback millert@
- Found by and ok aoyama@
+ Move the TEST_SSH_PORT section down a bit.
- OpenBSD-Commit-ID: f305ddfe575a26cc53431af3fde3f4aeebed9ba6
+ This groups the portable-specific changes together and makes it a
+ little more likely that patches will apply cleanly.
-commit a23954eeb930ccc8a66a2710153730769dba31b6
+commit 3674e33fa70dfa1fe69b345bf576113af7b7be11
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Jan 1 22:00:49 2021 +1100
+Date: Wed Apr 7 10:05:10 2021 +1000
- Undef int32 after sort routines.
+ Further split Valgrind tests.
- 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
+ Even split in two, the Valgrind tests take by far the longest to run,
+ so split them four ways to further increase parallelism.
-commit 3d999be7b987c848feda718cfcfcdc005ddf670d
-Author: tobhe@openbsd.org <tobhe@openbsd.org>
-Date: Wed Dec 30 14:13:28 2020 +0000
+commit 961af266b861e30fce1e26170ee0dbb5bf591f29
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Apr 6 23:24:30 2021 +0000
- upstream: Use int64_t for intermediate values in int32_MINMAX to
-
- prevent signed 32-bit integer overflow.
+ upstream: include "ssherr.h" not <ssherr.h>; from Balu Gajjala via
- Found by and ok djm@
- ok markus@
+ bz#3292
- OpenBSD-Commit-ID: 4f0704768e34cf45fdd792bac4011c6971881bb3
+ OpenBSD-Commit-ID: e9535cd9966eb2e69e73d1ede1f44905c30310bd
-commit 5c1953bf98732da5a76c706714ac066dbfa015ac
+commit e7d0a285dbdd65d8df16123ad90f15e91862f959
Author: Damien Miller <djm@mindrot.org>
-Date: Tue Dec 29 12:40:54 2020 +1100
+Date: Wed Apr 7 08:50:38 2021 +1000
- adapt KEX fuzzer to PQ kex change
+ wrap struct rlimit in HAVE_GETRLIMIT too
-commit 659864fe81dbc57eeed3769c462679d83e026640
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Dec 29 01:02:15 2020 +0000
+commit f283a6c2e0a9bd9369e18462acd00be56fbe5b0d
+Author: Damien Miller <djm@mindrot.org>
+Date: Wed Apr 7 08:20:35 2021 +1000
- 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
+ wrap getrlimit call in HAVE_GETRLIMIT; bz3291
-commit 2c71cec020219d69df84055c59eba5799a1233ec
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Dec 29 00:59:15 2020 +0000
+commit 679bdc4a5c9244f427a7aee9c14b0a0ed086da1f
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Tue Apr 6 09:07:33 2021 +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
+ upstream: Don't check return value of unsetenv(). It's part of the
- (note this both the updated method and the one that it replaced are
- disabled by default)
+ 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-Commit-ID: 2bf582b772d81ee24e911bb6f4b2aecfd39338ae
+ OpenBSD-Regress-ID: 24f08543ee3cdebc404f2951f3e388cc82b844a1
-commit 09d070ccc3574ae0d7947d212ed53c7268ef7e1f
+commit 320af2f3de6333aa123f1b088eca146a245e968a
Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Tue Dec 22 07:40:26 2020 +0000
+Date: Sun Apr 4 11:36:56 2021 +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;
+ upstream: remove stray inserts; from matthias schmidt
- ok djm
+ 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: aba31ebea03f38f8d218857f7ce16a500c3e4aff
+ OpenBSD-Commit-ID: 31cec6bf26c6db4ffefc8a070715ebef274e68ea
-commit 931c93389a80e32272712459b1102d303844453d
-Author: Damien Miller <djm@mindrot.org>
-Date: Tue Dec 22 19:43:55 2020 +1100
+commit b3ca08cb174266884d44ec710a84cd64c12414ea
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Apr 5 23:46:42 2021 +1000
- whitespace at EOL
+ Install libcbor with libfido2.
-commit 397b1c4d393f97427283a4717e9015a2bd31b8a5
+commit f3ca8af87a4c32ada660da12ae95cf03d190c083
Author: Damien Miller <djm@mindrot.org>
-Date: Tue Dec 22 19:42:37 2020 +1100
+Date: Sat Apr 3 18:21:08 2021 +1100
- whitespace at EOL
+ enable authopt and misc unit tests
+
+ Neither were wired into the build, both required some build
+ adaptations for -portable
-commit 33fa3ac547e5349ca34681cce6727b2f933dff0a
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Tue Dec 22 19:21:26 2020 +1100
+commit dc1b45841fb97e3d7f655ddbcfef3839735cae5f
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Apr 3 06:58:30 2021 +0000
- Improve AIX text.
+ 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 0f2e21c9dca89598b694932b5b05848380a23ec0
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Tue Dec 22 18:56:54 2020 +1100
+commit 53ea05e09b04fd7b6dea66b42b34d65fe61b9636
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Apr 3 06:55:52 2021 +0000
- Include stdio.h for FILE in misc.h.
+ upstream: sync CASignatureAlgorithms lists with reality. GHPR#174 from
- Fixes build on at least OpenBSD.
+ Matt Hazinski
+
+ OpenBSD-Commit-ID: f05e4ca54d7e67b90fe58fe1bdb1d2a37e0e2696
-commit 3e9811e57b57ee66b0f70d99d7258da3153b0e8a
+commit 57ed647ee07bb883a2f2264231bcd1df6a5b9392
Author: Damien Miller <djm@mindrot.org>
-Date: Tue Dec 22 18:31:50 2020 +1100
+Date: Sat Apr 3 17:47:37 2021 +1100
- ensure $LOGNAME is set in tests
+ polish whitespace for portable files
-commit 3eb647cbb34d87a063aa7714256c6e56103fffda
+commit 31d8d231eb9377df474746a822d380c5d68d7ad6
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Dec 22 06:47:24 2020 +0000
+Date: Sat Apr 3 06:18:40 2021 +0000
- upstream: more detail for failing tests
+ upstream: highly polished whitespace, mostly fixing spaces-for-tab
+
+ and bad indentation on continuation lines. Prompted by GHPR#185
- OpenBSD-Regress-ID: c68c0e5a521cad7e7f68e54c54ebf86d6c10ee1d
+ OpenBSD-Commit-ID: e5c81f0cbdcc6144df1ce468ec1bac366d8ad6e9
-commit 2873f19570d4d8758be24dbf78332be9a779009b
+commit 34afde5c73b5570d6f8cce9b49993b23b77bfb86
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Dec 22 06:03:36 2020 +0000
+Date: Sat Apr 3 05:54:14 2021 +0000
- upstream: regress test for KnownHostsCommand
+ upstream: whitespace (tab after space)
- OpenBSD-Regress-ID: ffc77464320b6dabdcfa0a72e0df02659233a38a
+ OpenBSD-Commit-ID: 0e2b3f7674e985d3f7c27ff5028e690ba1c2efd4
-commit 0121aa87bab9ad2365de2d07f2832b56d5ff9871
-Author: tb@openbsd.org <tb@openbsd.org>
-Date: Tue Dec 22 03:05:31 2020 +0000
+commit 7cd262c1c5a08cc7f4f30e3cab108ef089d0a57b
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat Apr 3 16:59:10 2021 +1100
- upstream: Remove lines accidentally left behind in the ProxyJump
-
- parsing fix r1.345.
-
- ok djm
-
- OpenBSD-Commit-ID: fe767c108c8117bea33767b080ff62eef2c55f5c
+ Save config.h and config.log on failure too.
-commit da4bf0db942b5f0278f33238b86235e5813d7a5a
+commit 460aee9298f365357e9fd26851c22e0dca51fd6a
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Dec 22 00:15:22 2020 +0000
+Date: Sat Apr 3 05:46:41 2021 +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).
+ upstream: fix incorrect plural; from Ville Skyt
- ok markus@
+ =?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: 2433cff4fb323918ae968da6ff38feb99b4d33d0
+ OpenBSD-Commit-ID: 92f31754c6296d8f403d7c293e09dc27292d22c9
-commit a34e14a5a0071de2036826a00197ce38c8b4ba8b
+commit 082804c14e548cada75c81003a3c68ee098138ee
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Dec 22 00:12:22 2020 +0000
+Date: Sat Apr 3 05:40:39 2021 +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@
+ upstream: ensure that pkcs11_del_provider() is called before exit -
- 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
+ some PKCS#11 providers get upset if C_Initialize is not matched with
+ C_Finalize.
- cipher was removed.
+ From Adithya Baglody via GHPR#234; ok markus
- OpenBSD-Regress-ID: aa93cddb4ecd9bc21446a79008a1a53050e64f17
+ OpenBSD-Commit-ID: f8e770e03b416ee9a58f9762e162add900f832b6
-commit 03e93c753d7c223063ad8acaf9a30aa511e5f931
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Mon Dec 21 11:09:32 2020 +0000
+commit 464ebc82aa926dd132ec75a0b064574ef375675e
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Apr 3 05:28:43 2021 +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@
+ upstream: unused variable
- OpenBSD-Commit-ID: fb460acc18290a998fd70910b19c29b4e4f199ad
+ OpenBSD-Commit-ID: 85f6a394c8e0f60d15ecddda75176f112007b205
-commit a11ca015879eab941add8c6bdaaec7d41107c6f5
+commit dc3c0be8208c488e64a8bcb7d9efad98514e0ffb
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Dec 21 09:19:53 2020 +0000
+Date: Sat Apr 3 05:21:46 2021 +0000
- upstream: properly fix ProxyJump parsing; Thanks to tb@ for
+ 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
- pointing out my error (parse_ssh_uri() can return -1/0/1, that I missed).
- Reported by Raf Czlonka via bugs@
+ A unit test for these cases has already been committed
- ok tb@
+ prompted by and based on GHPR#223 by Eero Häkkinen; ok markus@
- OpenBSD-Commit-ID: a2991a3794bcaf1ca2b025212cce11cdb5f6b7d6
+ OpenBSD-Commit-ID: d7ef27abb4eeeaf6e167e9312e4abe9e89faf1e4
-commit d97fb879724f1670bf55d9adfea7278a93c33ae2
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Dec 21 01:31:06 2020 +0000
+commit f75bcbba58a08c670727ece5e3f8812125969799
+Author: Damien Miller <djm@mindrot.org>
+Date: Sat Apr 3 16:22:48 2021 +1100
- upstream: adapt to API change in hostkeys_foreach()/load_hostkeys()
-
- OpenBSD-Regress-ID: dcb468514f32da49a446372453497dc6eeafdbf3
+ missing bits from 259d648e
-commit bf7eb3c266b7fd4ddda108fcf72b860af2af6406
+commit 4cbc4a722873d9b68cb5496304dc050d7168df78
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Oct 16 14:02:24 2020 +0000
+Date: Wed Mar 31 21:59:26 2021 +0000
- upstream: few more things needs match.c and addrmatch.c now that
+ upstream: cannot effectively test posix-rename extension after
- log.c calls match_pattern_list()
+ changes in feature advertisment.
- 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.
+ OpenBSD-Regress-ID: 5e390bf88d379162aaa81b60ed86b34cb0c54d29
-commit 0f504f592d15d8047e466eb7453067a6880992a8
+commit 259d648e63e82ade4fe2c2c73c8b67fe57d9d049
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Dec 20 23:40:19 2020 +0000
+Date: Fri Mar 19 04:23:50 2021 +0000
- upstream: plumb ssh_conn_info through to sshconnect.c; feedback/ok
-
- markus@
+ upstream: add a test for misc.c:argv_split(), currently fails
- OpenBSD-Commit-ID: e8d14a09cda3f1dc55df08f8a4889beff74e68b0
+ OpenBSD-Regress-ID: ad6b96d6ebeb9643b698b3575bdd6f78bb144200
-commit 729b05f59ded35483acef90a6f88aa03eae33b29
+commit 473ddfc2d6b602cb2d1d897e0e5c204de145cd9a
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Dec 20 23:38:00 2020 +0000
+Date: Fri Mar 19 03:25:01 2021 +0000
- upstream: allow UserKnownHostsFile=none; feedback and ok markus@
+ upstream: split
- OpenBSD-Commit-ID: c46d515eac94a35a1d50d5fd71c4b1ca53334b48
+ OpenBSD-Regress-ID: f6c03c0e4c58b3b9e04b161757b8c10dc8378c34
-commit b4c7cd1185c5dc0593d47eafcc1a34fda569dd1d
+commit 1339800fef8d0dfbfeabff71b34670105bcfddd2
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Dec 20 23:36:51 2020 +0000
+Date: Wed Mar 31 22:16:34 2021 +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.
+ upstream: Use new limits@openssh.com protocol extension to let the
- Original load_hostkeys() and hostkeys_foreach() are implemented using
- these new interfaces.
+ client select good limits based on what the server supports. Split the
+ download and upload buffer sizes to allow them to be chosen independently.
- 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().
+ In practice (and assuming upgraded sftp/sftp-server at each end), this
+ increases the download buffer 32->64KiB and the upload buffer
+ 32->255KiB.
- ok markus@
+ Patches from Mike Frysinger; ok dtucker@
- OpenBSD-Commit-ID: 6ff6db13ec9ee4edfa658b2c38baad0f505d8c20
+ OpenBSD-Commit-ID: ebd61c80d85b951b794164acc4b2f2fd8e88606c
-commit 06fbb386bed666581095cb9cbc7a900e02bfe1b7
-Author: tobhe@openbsd.org <tobhe@openbsd.org>
-Date: Sat Dec 19 22:09:21 2020 +0000
+commit 6653c61202d104e59c8e741329fcc567f7bc36b8
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Mar 31 21:58:07 2021 +0000
- upstream: Print client kem key with correct length.
+ upstream: do not advertise protocol extensions that have been
- ok markus@
+ disallowed by the command-line options (e.g. -p/-P/-R); ok dtucker@
- OpenBSD-Commit-ID: 91689e14a4fc6c270e265a32d1c8faba63a45755
+ OpenBSD-Commit-ID: 3a8a76b3f5131741aca4b41bfab8d101c9926205
-commit 0ebead6593e2441e4af2735bbe2cd097607cd0d3
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Dec 17 23:28:50 2020 +0000
+commit 71241fc05db4bbb11bb29340b44b92e2575373d8
+Author: Damien Miller <djm@mindrot.org>
+Date: Mon Mar 29 15:14:25 2021 +1100
- upstream: fix possible error("%s", NULL) on error paths
-
- OpenBSD-Commit-ID: 0b3833c2cb985453ecca1d76803ebb8f3b736a11
+ gnome-ssh-askpass3 is a valid target here
-commit d060bc7f6e6244f001e658208f53e3e2ecbbd382
+commit 8a9520836e71830f4fccca066dba73fea3d16bda
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Dec 17 23:26:11 2020 +0000
+Date: Fri Mar 19 02:22:34 2021 +0000
- upstream: refactor client percent_expand() argument passing;
+ upstream: return non-zero exit status when killed by signal; bz#3281 ok
- consolidate the common arguments into a single struct and pass that around
- instead of using a bunch of globals. ok markus@
+ dtucker@
- OpenBSD-Commit-ID: 035e6d7ca9145ad504f6af5a021943f1958cd19b
+ OpenBSD-Commit-ID: 117b31cf3c807993077b596bd730c24da9e9b816
-commit 43026da035cd266db37df1f723d5575056150744
+commit 1269b8a686bf1254b03cd38af78167a04aa6ec88
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Dec 17 23:10:27 2020 +0000
+Date: Fri Mar 19 02:18:28 2021 +0000
- upstream: prepare readconf.c for fuzzing; remove fatal calls and
+ upstream: increase maximum SSH2_FXP_READ to match the maximum
- fix some (one-off) memory leaks; ok markus@
+ 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: 91c6aec57b0e7aae9190de188e9fe8933aad5ec5
+ OpenBSD-Commit-ID: 4e67d60d81bde7b84a742b4ee5a34001bdf80d9c
-commit bef92346c4a808f33216e54d6f4948f9df2ad7c1
+commit 860b67604416640e8db14f365adc3f840aebcb1f
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Dec 14 03:13:12 2020 +0000
+Date: Tue Mar 16 06:15:43 2021 +0000
- upstream: use _PATH_SSH_USER_DIR instead of hardcoded .ssh in path
+ upstream: don't let logging clobber errno before use
- OpenBSD-Commit-ID: 5c1048468813107baa872f5ee33ba51623630e01
+ OpenBSD-Commit-ID: ce6cca370005c270c277c51c111bb6911e1680ec
-commit a5ab499bd2644b4026596fc2cb24a744fa310666
-Author: Damien Miller <djm@mindrot.org>
-Date: Fri Dec 4 14:01:27 2020 +1100
+commit 5ca8a9216559349c56e09039c4335636fd85c241
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat Mar 13 14:40:43 2021 +1100
- basic KEX fuzzer; adapted from Markus' unittest
+ Only call dh_set_moduli_file if using OpenSSL.
+
+ Fixes link failure when configuring --without-openssl since dh.c is not
+ linked in.
-commit 021ff33e383c77b11badd60cec5b141a3e3fa532
-Author: Damien Miller <djm@mindrot.org>
-Date: Fri Dec 4 13:57:43 2020 +1100
+commit 867a7dcf003c51d5a83f83565771a35f0d9530ac
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat Mar 13 13:52:53 2021 +1100
- use options that work with recent clang
+ 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 e4d1a0b40add800b6e9352b40c2223e44acc3a45
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Dec 4 02:41:10 2020 +0000
+commit 0c054538fccf92b4a028008321d3711107bee6d5
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat Mar 13 13:51:26 2021 +1100
- upstream: shuffle a few utility functions into sftp-client.c; from
-
- Jakub Jelen
+ Point TEST_SSH_MODULI_FILE at our own moduli.
- OpenBSD-Commit-ID: fdeb1aae1f6149b193f12cd2af158f948c514a2a
+ This will allow the test to run without requiring a moduli file
+ installed at the configured default path.
-commit ace12dc64f8e3a2496ca48d36b53cb3c0a090755
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Dec 4 02:29:56 2020 +0000
+commit 4d48219c72ab0c71238806f057f0e9630b7dd25c
+Author: jsg@openbsd.org <jsg@openbsd.org>
+Date: Fri Mar 12 05:18:01 2021 +0000
- upstream: make ssh_free(NULL) a no-op
+ upstream: spelling
- OpenBSD-Commit-ID: 42cb285d94789cefe6608db89c63040ab0a80fa0
+ OpenBSD-Commit-ID: 478bc3db04f62f1048ed6e1765400f3ab325e60f
-commit 3b98b6e27f8a122dbfda9966b1afeb3e371cce91
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Dec 4 02:29:25 2020 +0000
+commit 88057eb6df912abf2678ea5c846d9d9cbc92752c
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Mar 12 04:08:19 2021 +0000
- upstream: memleak of DH public bignum; found with libfuzzer
+ 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: 0e913b542c3764b100b1571fdb0d0e5cc086fe97
+ OpenBSD-Commit-ID: 8df99d60b14ecaaa28f3469d01fc7f56bff49f66
-commit 553b90feedd7da5b90901d73005f86705456d686
+commit f07519a2af96109325b5a48b1af18b57601074ca
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Dec 4 02:27:57 2020 +0000
+Date: Fri Mar 12 03:43:40 2021 +0000
- upstream: fix minor memleak of kex->hostkey_alg on rekex
+ upstream: pwcopy() struct passwd that we're going to reuse across a
+
+ bunch of library calls; bz3273 ok dtucker@
- OpenBSD-Commit-ID: 2c3969c74966d4ccdfeff5e5f0df0791919aef50
+ OpenBSD-Commit-ID: b6eafa977b2e44607b1b121f5de855107809b762
-commit ac0364b85e66eb53da2f9618f699ba6bd195ceea
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Dec 4 02:27:08 2020 +0000
+commit 69d6d4b0c8a88d3d1288415605f36e2df61a2f12
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Wed Mar 10 06:32:27 2021 +0000
- upstream: typos: s/hex/kex/ in error messages
+ upstream: Import regenerated moduli file.
- OpenBSD-Commit-ID: 43a026c9571dd779ec148de1829cf5a6b6651905
+ OpenBSD-Commit-ID: 7ac6c252d2a5be8fbad4c66d9d35db507c9dac5b
-commit ee22db7c5885a1d90219202c0695bc621aa0409b
+commit e5895e8ecfac65086ea6b34d0d168409a66a15e1
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Dec 4 02:25:13 2020 +0000
+Date: Wed Mar 10 04:58:45 2021 +0000
- upstream: make program name be const
+ upstream: no need to reset buffer after send_msg() as that is done
+
+ for us; patch from Mike Frysinger
- OpenBSD-Commit-ID: ece25680ec637fdf20502721ccb0276691df5384
+ OpenBSD-Commit-ID: 565516495ff8362a38231e0f1a087b8ae66da59c
-commit 2bcbf679de838bb77a8bd7fa18e100df471a679c
+commit 721948e67488767df0fa0db71ff2578ee2bb9210
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Mon Nov 30 05:36:39 2020 +0000
+Date: Sat Mar 13 01:52:16 2021 +0000
- upstream: Ignore comments at the end of config lines in ssh_config,
+ upstream: Add TEST_SSH_MODULI_FILE variable to allow overriding of the
- similar to what we already do for sshd_config. bz#2320, with & ok djm@
+ moduli file used during the test run.
- OpenBSD-Commit-ID: bdbf9fc5bc72b1a14266f5f61723ed57307a6db4
+ OpenBSD-Regress-ID: be10f785263120edb64fc87db0e0d6570a10220a
-commit b755264e7d3cdf1de34e18df1af4efaa76a3c015
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Sat Nov 28 12:52:32 2020 +0000
+commit 82fef71e20ffef425b932bec26f5bc46aa1ed41c
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Mar 12 15:58:57 2021 +1100
- upstream: Include cipher.h for declaration of cipher_by_name.
+ Allow (but return EACCES) fstatat64 in sandbox.
- OpenBSD-Commit-ID: ddfebbca03ca0e14e00bbad9d35f94b99655d032
+ This is apparently used in some configurations of OpenSSL when glibc
+ has getrandom(). bz#3276, patch from Kris Karas, ok djm@
-commit 022def7bd16c3426a95e25f57cb259d54468341c
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Nov 28 03:27:59 2020 +0000
+commit 1cd67ee15ce3d192ab51be22bc4872a6a7a4b6d9
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Mar 12 13:16:10 2021 +1100
- upstream: check result of strchr() against NULL rather than
-
- searched-for characters; from zhongjubin@huawei.com
+ Move generic includes outside of ifdef.
- OpenBSD-Commit-ID: e6f57de1d4a4d25f8db2d44e8d58d847e247a4fe
+ 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 57bf03f0217554afb8980f6697a7a0b88658d0a9
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Nov 27 10:12:30 2020 +0000
+commit 2421a567a8862fe5102a4e7d60003ebffd1313dd
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Mar 10 17:41:21 2021 +1100
- 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
+ Import regenerated moduli file.
-commit 33313ebc1c7135085676db62189e3520341d6b73
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Nov 27 00:49:58 2020 +0000
+commit e99080c05d9d48dbbdb022538533d53ae1bd567d
+Author: millert@openbsd.org <millert@openbsd.org>
+Date: Sat Mar 6 20:36:31 2021 +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.
+ upstream: Fix PRINT macro, the suffix param to sshlog() was missing.
- ok dtucker@
+ 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: f31ab10d9233363a6d2c9996007083ba43a093f1
+ OpenBSD-Commit-ID: 01fdfa9c5541151b5461d9d7d6ca186a3413d949
-commit b2bcec13f17ce9174238a704e91d52203e916432
+commit 160db17fc678ceb5e3fd4a7e006cc73866f484aa
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Nov 27 00:37:10 2020 +0000
+Date: Wed Mar 3 22:41:49 2021 +0000
- upstream: clean up passing of struct passwd from monitor to preauth
+ upstream: don't sshbuf_get_u32() into an enum; reported by goetze
- privsep process. No longer copy entire struct w/ pointer addresses, but pass
- remaining scalar fields explicitly,
+ AT dovetail.com via bz3269
- Prompted by Yuichiro NAITO, feedback Thorsten Glaser; ok dtucker@
+ 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: 9925df75a56732c43f3663e70dd15ff413ab3e53
+ OpenBSD-Commit-ID: 276f58afc97b6f5826e0be58380b737603dbf5f5
-commit 19af04e2231155d513e24fdc81fbec2217ae36a6
+commit 7fe141b96b13bd7dc67ca985e14d55b9bd8a03fd
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Nov 22 22:38:26 2020 +0000
+Date: Wed Mar 3 08:42:52 2021 +0000
- upstream: when loading PKCS#11 keys, include the key fingerprints
-
- and provider/slot information in debug output.
+ upstream: needs FILE*; from Mike Frysinger
- OpenBSD-Commit-ID: 969a089575d0166a9a364a9901bb6a8d9b8a1431
+ 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 9b9465ea856e15b9e9890b4ecb4110d7106e7766
+commit 0a4b23b11b9a4e6eec332dd5c6ab2ac6f62aa164
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Nov 22 22:37:11 2020 +0000
+Date: Tue Mar 2 01:48:18 2021 +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@
+ upstream: openssh-8.5
- OpenBSD-Commit-ID: 2d5ce4a83dbcf44e340a572e361decad8aab7bad
+ OpenBSD-Commit-ID: 185e85d60fe042b8f8fa1ef29d4ef637bdf397d6
-commit 637017a7dd3281d3f2df804993cc27c30dbfda47
+commit de3866383b6720ad4cad83be76fe4c8aa111a249
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Nov 25 17:38:46 2020 +1100
+Date: Mon Mar 1 21:13:24 2021 +1100
- Use "=" not "==" in string test.
-
- POSIX says "=" is string comparison and some shells (eg HP-UX) will
- complain about "==".
+ Only upload config logs if configure fails.
-commit 9880f3480f9768897f3b8e714d5317fb993bc5b3
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Nov 20 17:16:51 2020 +1100
+commit 85ff2a564ce838f8690050081176c1de1fb33116
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Sun Feb 28 22:56:30 2021 +0000
- Restore correct flags during localtime_r check.
+ 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
- We were restoring the wrong thing CPPFLAGS (we used CFLAGS) for any
- platform that doesn't have localtime_r.
+ OpenBSD-Commit-ID: 9c87f39a048cee2a7d1c8bab951b2f716256865e
-commit 41935882f4e82de60dbd6e033eabe79e1b963518
+commit e774bac35933e71f924f4301786e7fb5bbe1422f
Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Nov 20 03:16:56 2020 +0000
+Date: Sun Feb 28 01:50:47 2021 +0000
- upstream: When doing an sftp recursive upload or download of a
+ upstream: Do not try to reset signal handler for signal 0 in
- 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@
+ subprocess. Prevents spurious debug message. ok djm@
- OpenBSD-Commit-ID: a82606212f2796e31f0e1af94a63355a7ad5d903
+ OpenBSD-Commit-ID: 7f9785e292dcf304457566ad4637effd27ad1d46
-commit 0f90440ca70abab947acbd77795e9f130967956c
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Nov 20 13:37:54 2020 +1100
+commit 351c5dbbd74ce300c4f058112f9731c867c6e225
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sat Feb 27 23:42:37 2021 +0000
- Add new pselect6_time64 syscall on ARM.
+ upstream: fix alphabetic ordering of options; spotted by Iain Morgan
- This is apparently needed on armhfp/armv7hl. bz#3232, patch from
- jjelen at redhat.com.
+ OpenBSD-Commit-ID: f955fec617d74af0feb5b275831a9fee813d7ad5
-commit 3a7c46c72b6a1f643b1fc3589cd20d8320c3d9e1
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Nov 20 02:14:16 2020 +0000
+commit 0d1c9dbe578597f8d45d3ac7690df10d32d743e5
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat Feb 27 12:25:25 2021 +1100
- 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
+ zlib is now optional.
-commit 076cb616b87d1ea1d292973fcd0ba38c08ea6832
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Thu Nov 19 23:05:05 2020 +0000
+commit b7c6ee7b437d9adfd19ef49d6c0f19f13f26f9b3
+Author: Jeffrey H. Johnson <61629094+johnsonjh@users.noreply.github.com>
+Date: Sat Feb 27 01:04:58 2021 +0000
- upstream: draft-ietf-secsh-architecture is now RFC4251.
+ Fix punctuatio and typo in README.md.
- OpenBSD-Commit-ID: cb0bb58c2711fb5ed519507659be1dcf179ed403
+ Some very minor fixes, missing 's' and punctuation.
-commit 85cceda21f1471548e04111aefe2c4943131c1c8
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Tue Nov 17 11:23:58 2020 +0000
+commit 6248b86074804983e8f7a2058856a516dbfe2924
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Feb 26 16:45:50 2021 +1100
- upstream: Specify that the KDF function is bcrypt. Based on github
+ Revert "ssh: optional bind interface if bind address specified."
- PR#214 from rafork, ok markus@, mdoc correction jmc@
+ This reverts commit 5a878a71a3528c2626aa1d331934fd964782d41c.
- OpenBSD-Commit-ID: d8f2853e7edbcd483f31b50da77ab80ffa18b4ef
+ Apologies - I accidentally pushed this.
-commit 5b9720f9adbd70ba5a994f407fe07a7d016d8d65
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Nov 15 22:34:58 2020 +0000
+commit 493339a940b13be6071629c3c2dd5a3b6fc17023
+Author: Damien Miller <djm@mindrot.org>
+Date: Fri Feb 26 15:45:38 2021 +1100
- upstream: revert r1.341; it breaks ProxyJump; reported by sthen@
+ detech BSD libc hash functions in libbsd / libmd
- OpenBSD-Commit-ID: 6ac2f945b26cb86d936eed338f77861d6da8356a
+ 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 04088725ec9c44880c01799b588cd4ba47b3e8bc
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Nov 13 07:30:44 2020 +0000
+commit 5a878a71a3528c2626aa1d331934fd964782d41c
+Author: Dmitrii Turlupov <dturlupov@factor-ts.ru>
+Date: Thu Feb 4 16:27:31 2021 +0300
- upstream: scrub keyboard-interactive authentication prompts coming
-
- from the server through asmprintf() prior to display; suggested by and ok
- dtucker@
+ ssh: optional bind interface if bind address specified.
- OpenBSD-Commit-ID: 31fe93367645c37fbfe4691596bf6cf1e3972a58
+ Allows the -b and -B options to be used together.
+ For example, when the interface is in the VRF.
-commit 5442b491d0ee4bb82f6341ad0ee620ef3947f8c5
+commit 1fe4d70df94d3bcc2b35fd57cad6b5fc4b2d7b16
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Nov 13 04:53:12 2020 +0000
+Date: Fri Feb 26 04:18:42 2021 +0000
- upstream: prefix keyboard interactive prompts with (user@host) to
+ upstream: remove this KEX fuzzer; it's awkward to use and doesn't play
- make it easier to determine which connection they are associated with in
- cases like scp -3, ProxyJump, etc. bz#3224 ok dtucker
+ nice with popular fuzzing drivers like libfuzzer. AFAIK nobody has used it
+ but me.
- OpenBSD-Commit-ID: 67e6189b04b46c867662f8a6759cf3ecb5f59170
+ OpenBSD-Regress-ID: cad919522b3ce90c147c95abaf81b0492ac296c9
-commit 2992e4e7014ac1047062acfdbbf6feb156fef616
+commit 24a3a67bd7421740d08803b84bd784e764107928
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Nov 13 17:56:11 2020 +1100
+Date: Fri Feb 26 11:49:19 2021 +1100
- Remove use of TIME_WITH_SYS_TIME.
+ Remove macos-11.00 PAM test target too.
- 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.
+ These are failing apparently due to some kind of infrastructure problem,
+ making it look like every commit is busted.
-commit e3f27006f15abacb7e89fda3f5e9a0bd420b7e38
-Author: Damien Miller <djm@mindrot.org>
-Date: Fri Nov 13 14:20:43 2020 +1100
+commit 473201783f732ca8b0ec528b56aa55fa0d8cf717
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Feb 26 00:16:58 2021 +0000
- Revert "detect Linux/X32 systems"
-
- This reverts commit 5b56bd0affea7b02b540bdbc4d1d271b0e4fc885.
+ upstream: a bit more debugging behind #ifdef DEBUG_SK
- The approach used was incorrect; discussion in bz#3085
+ OpenBSD-Commit-ID: d9fbce14945721061cb322f0084c2165d33d1993
-commit e51dc7fab61df36e43f3bc64b673f88d388cab91
-Author: Damien Miller <djm@mindrot.org>
-Date: Fri Nov 13 13:22:15 2020 +1100
+commit fd9fa76a344118fe1ef10b9a6c9e85d39599e9a8
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Feb 26 01:15:10 2021 +1100
- SELinux has deprecated security_context_t
+ Remove macos-11.0 from the test target list.
- (it was only ever a char* anyway)
+ It has been consistently failing for the past few days with a github
+ actions internal error.
-commit b79add37d118276d67f3899987b9f0629c9449c3
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Nov 13 13:43:30 2020 +1100
+commit 476ac8e9d33dbf96ef97aab812b8d7089d0cdc24
+Author: Philip Hands <phil@hands.com>
+Date: Wed Feb 24 23:43:16 2021 +0100
- Remove obsolete AC_HEADER_TIME macro.
+ tidy the $INSTALLKEY_SH code layout a little
- 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.
+ SSH-Copy-ID-Upstream: 78178aa5017222773e4c23d9001391eeaeca8983
-commit d5d05cdb3d4efd4a618aa52caab5bec73097c163
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Nov 12 22:56:00 2020 +0000
+commit 983e05ef3b81329d76d6a802b39ad0d1f637c06c
+Author: Jakub Jelen <jjelen@redhat.com>
+Date: Tue Sep 29 10:02:45 2020 +0000
- upstream: when prompting the user to accept a new hostkey, display
+ if unable to add a missing newline, fail
- any other host names/addresses already associated with the key. E.g.
+ 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
- > 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])?
+ since that was a change made since jjelen's commit was written
- feedback and ok markus@
+ also, quote the variables
- OpenBSD-Commit-ID: f6f58a77b49f1368b5883b3a1f776447cfcc7ef4
+ SSH-Copy-ID-Upstream: 588cd8e5cbf95f3443d92b9ab27c5d73ceaf6616
-commit 819b44e8b9af6ce18d3ec7505b9f461bf7991a1f
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Thu Nov 12 22:38:57 2020 +0000
+commit 333e25f7bc43cee6e36f766e39dad6f9918b318c
+Author: Jakub Jelen <jjelen@redhat.com>
+Date: Tue Sep 29 10:00:01 2020 +0000
- upstream: Prevent integer overflow when ridiculously large
+ restorecon the correct directory
- ConnectTimeout is specified, capping the effective value (for most platforms)
- at 24 days. bz#3229, ok djm@
+ if using different path for authorized_keys file
- OpenBSD-Commit-ID: 62d4c4b7b87d111045f8e9f28b5b532d17ac5bc0
+ SSH-Copy-ID-Upstream: 791a3df47b48412c726bff6f7b1d190721e65d51
-commit add926dd1bbe3c4db06e27cab8ab0f9a3d00a0c2
+commit 9beeab8a37a49a9e3ffb1972fff6621ee5bd7a71
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Nov 11 05:22:32 2020 +0000
+Date: Thu Feb 25 03:27:34 2021 +0000
- upstream: fix logic error that broke URI parsing in ProxyJump
-
- directives; ok dtucker@
+ upstream: s/PubkeyAcceptedKeyTypes/PubkeyAcceptedAlgorithms/
- OpenBSD-Commit-ID: 96d48839b1704882a0e9a77898f5e14b2d222705
+ OpenBSD-Regress-ID: 3dbc005fa29f69dc23d97e433b6dffed6fe7cb69
-commit 4340dd43928dfe746cb7e75fe920b63c0d909a9a
-Author: claudio@openbsd.org <claudio@openbsd.org>
-Date: Tue Nov 10 07:46:20 2020 +0000
+commit 2dd9870c16ddbd83740adeead5030d6840288c8f
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Wed Feb 24 23:12:35 2021 +0000
- upstream: Free the previously allocated msg buffer after writing it
+ upstream: Rename pubkeyacceptedkeytypes to pubkeyacceptedalgorithms in
- out. OK djm@
+ test to match change to config-dump output.
- OpenBSD-Commit-ID: 18c055870fc75e4cb9f926c86c7543e2e21d7fa4
+ OpenBSD-Regress-ID: 74c9a4ad50306be873d032819d5e55c24eb74d5d
-commit fcf429a4c69d30d8725612a55b37181594da8ddf
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Nov 11 12:30:46 2020 +1100
+commit b9225c3a1c3f5827e31d5d64a71b8e0504a25619
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Wed Feb 24 01:18:08 2021 +0000
- Prevent excessively long username going to PAM.
+ upstream: Put obsolete aliases for hostbasedalgorithms and
- 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.
+ pubkeyacceptedalgorithms after their current names so that the config-dump
+ mode finds and uses the current names. Spotted by Phil Pennock.
- Based on github PR#212 from Mike Scott but implemented slightly
- differently. ok tim@ djm@
+ OpenBSD-Commit-ID: 5dd10e93cccfaff3aaaa09060c917adff04a9b15
-commit 10dce8ff68ef615362cfcab0c0cc33ce524e7682
+commit 8b8b60542d6652b2c91e0ef9e9cc81bcb65e6b42
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Nov 8 23:19:03 2020 +0000
+Date: Tue Feb 23 21:55:08 2021 +0000
- upstream: unbreak; missing NULL check
+ upstream: lots more s/key types/signature algorithms/ mostly in
+
+ HostbasedAcceptedAlgorithms and HostKeyAlgorithms; prompted by Jakub Jelen
- OpenBSD-Commit-ID: 6613dfab488123f454d348ef496824476b8c11c0
+ OpenBSD-Commit-ID: 3f719de4385b1a89e4323b2549c66aae050129cb
-commit d5a0cd4fc430c8eda213a4010a612d4778867cd9
+commit 0aeb508aaabc4818970c90831e3d21843c3c6d09
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Nov 8 22:37:24 2020 +0000
+Date: Tue Feb 23 21:50:18 2021 +0000
- upstream: when requesting a security key touch on stderr, inform the
+ upstream: Correct reference to signature algorithms as keys; from
- user once the touch has been recorded; requested by claudio@ ok markus@
+ Jakub Jelen
- OpenBSD-Commit-ID: 3b76ee444490e546b9ea7f879e4092ee0d256233
+ OpenBSD-Commit-ID: 36f7ecee86fc811aa0f8e21e7a872eee044b4be5
-commit 292bcb2479deb27204e3ff796539c003975a5f7a
+commit f186a020f2ba5f9c462a23293750e29ba0a746b1
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Mon Nov 9 00:33:35 2020 +1100
+Date: Tue Feb 23 16:05:22 2021 +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.
+ Add a couple more test VMs.
-commit 71693251b7cbb7dd89aaac18815147124732d0d3
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Sun Nov 8 12:10:20 2020 +0000
+commit ffcdd3d90e74176b3bb22937ad1f65a6c1cd3f9d
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Feb 22 08:09:27 2021 +1100
- upstream: Add a comment documenting the source of the moduli group
-
- sizes.
+ Valgrind test: split and move up list.
- OpenBSD-Commit-ID: aec0725ce607630caaa62682624c6763b350391c
+ 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 4d94b031ff88b015f0db57e140f481bff7ae1a91
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Sun Nov 8 11:46:12 2020 +0000
+commit c3b1636770785cc2830dedd0f22ef7d3d3491d6d
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Feb 23 00:05:31 2021 +0000
- upstream: Replace WITH_OPENSSL ifdefs in log calls with a macro.
+ upstream: warn when the user specifies a ForwardAgent path that does
- 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@
+ not exist and exit if ExitOnForwardFailure is set; bz3264
- OpenBSD-Commit-ID: cc12a9029833d222043aecd252d654965c351a69
+ OpenBSD-Commit-ID: 72f7875865e723e464c71bf8692e83110699bf26
-commit 6d2564b94e51184eb0b73b97d13a36ad50b4f810
+commit 5fcb0514949d61aadaf4a89cf16eb78fb47491ec
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Nov 6 17:11:16 2020 +1100
+Date: Sat Feb 20 13:34:02 2021 +1100
- Fix function body for variadic macro test.
+ Disable rlimit sandbox, doesn't work with valgrind
- AC_LANG_PROGRAM puts its second argument inside main() so we don't need
- to do it ourselves.
+ Only run regress tests, runing unit tests as well makes it run longer
+ than allowed y github.
-commit 586f9bd2f5980e12f8cf0d3c2a761fa63175da52
+commit bb0b9bf45396c19486080d3eb0a159f94de7e6ba
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Nov 6 16:53:24 2020 +1100
+Date: Sat Feb 20 13:06:25 2021 +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@
+ Upload valgrind logs on failure.
-commit a019e353df04de1b2ca78d91b39c393256044ad7
+commit ebb3b75e974cb241c6b9b9f5881b09c7bd32b651
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Nov 6 13:56:41 2020 +1100
+Date: Fri Feb 19 22:18:50 2021 +1100
- Replace AC_TRY_COMPILE obsoleted in autoconf 2.70.
+ Rename "vm" to "os" in selfhosted to match c-cpp.
- Replace with the equivalent AC_COMPILE_IFELSE.
+ Should make it easier to share code or maybe merge at some point.
-commit 771b7795c0ef6a2fb43b4c6c66b615c2085cb9cd
+commit 76c0be0fe0465cb2b975dbd409f8d38b55e55bcb
Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Nov 6 13:55:33 2020 +1100
+Date: Fri Feb 19 22:15:22 2021 +1100
- Move AC_PROG_CC_C99 to immediately afer AC_PROG_CC.
-
- This puts the related C version selection output in the same place.
+ Upload regress failure logs in c-cpp too.
-commit e5591161f21ab493c6284a85ac3c0710ad94998f
+commit 8751b6c3136f5225c40f41bbf29aa29e15795f6e
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
+Date: Fri Feb 19 22:13:36 2021 +1100
- upstream: fold consecutive '*' wildcards to mitigate combinatorial
-
- explosion of recursive searches; ok dtucker
+ Comment out Solaris 64bit PAM build...
- OpenBSD-Commit-ID: d18bcb39c40fb8a1ab61153db987e7d11dd3792b
+ until I can figure out why it's failing.
-commit 7d680448db5858dc76307663f78d0b8d3c2b4a3d
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Oct 30 01:50:07 2020 +0000
+commit e9f6d563c06886b277c6b9abafa99fa80726dc48
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Feb 19 10:20:17 2021 +1100
- upstream: print reason in fatal error message when
-
- kex_assemble_namelist() fails
-
- OpenBSD-Commit-ID: a9975ee8db6c98d6f32233d88051b2077ca63dab
+ Actually run Valgrind tests.
-commit 95d1109fec7e89ad21f2a97e92bde1305d32a353
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Oct 29 03:13:06 2020 +0000
+commit 41d232e226624f1a81c17091c36b44c9010aae62
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Feb 19 10:16:56 2021 +1100
- upstream: fix sshd_config SetEnv directive inside Match blocks; part of
-
- github PR#201 from github user manuelm
-
- OpenBSD-Commit-ID: 9772e3748abff3ad65ae8fc43d026ed569b1d2bc
+ Add test against Valgrind.
-commit b12b835dc022ba161afe68348e05a83dfbcb1515
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Oct 29 03:01:18 2020 +0000
+commit e6528d91f12fba05f0ea64224091c9d0f38bdf1d
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Feb 18 16:30:01 2021 +1100
- upstream: fix type of nid in type_bits_valid(); github PR#202 from
-
- github user thingsconnected
-
- OpenBSD-Commit-ID: 769d2b040dec7ab32d323daf54b854dd5dcb5485
+ Add fbsd12 test target.
-commit 1a14c13147618144d1798c36a588397ba9008fcc
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Oct 29 02:52:43 2020 +0000
+commit 6506cb2798d98ff03a7cc06567c392a81f540680
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Feb 18 15:21:13 2021 +1100
- upstream: whitespace; no code change
-
- OpenBSD-Commit-ID: efefc1c47e880887bdee8cd2127ca93177eaad79
+ Remove unused arg.
-commit 815209abfdd2991fb92ad7d2e33374916cdcbcf4
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Oct 29 02:47:23 2020 +0000
+commit 93c31a623973b0fad508214593aab6ca94b11dcb
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Feb 18 14:54:07 2021 +1100
- 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
+ Add DEBUG_SK to kitchensink builds.
-commit a575cf44e59a65506c67bddb62a712208a7a279c
-Author: Duncan Eastoe <duncan.eastoe@att.com>
-Date: Wed Oct 21 10:11:10 2020 +0100
+commit 65085740d3574eeb3289d592f042df62c2689bb0
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Feb 18 14:53:14 2021 +1100
- session.c: use "denylist" terminology
-
- Follow upstream (6d755706a0059eb9e2d63517f288b75cbc3b4701) language
- improvements in this portable-specific code.
+ Add bbone test target (arm32).
-commit 33267feaffd5d98aa56d2f0b3a99ec352effe938
-Author: Damien Miller <djm@mindrot.org>
-Date: Tue Oct 27 16:46:31 2020 +1100
+commit 63238f5aed66148b8d6ca7bd5fb347d624200155
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Feb 18 02:49:35 2021 +0000
- Remove checks for strict POSIX mkdtemp()
+ upstream: Fix the hostkeys rotation extension documentation
- 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 documentation was lacking the needed want-reply field in the initial
+ global request.
- the manpage-l10n project via bz#3223. feedback deraadt@, ok jmc@
+ https://github.com/openssh/openssh-portable/pull/218 by dbussink
- OpenBSD-Commit-ID: ab83af0daf18369244a72daaec6c4a58a9eb7e2c
+ OpenBSD-Commit-ID: 051824fd78edf6d647a0b9ac011bf88e28775054
-commit eab2888cfc6cc4e2ef24bd017da9835a0f365f3f
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Mon Oct 19 22:49:23 2020 +0000
+commit 34c5ef6e2d06d9f0e20cb04a9aebf67a6f96609a
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Feb 18 02:15:07 2021 +0000
- upstream: Adapt XMSS to new logging infrastructure. With markus@, ok
+ upstream: make names in function prototypes match those in
- djm@.
+ definition from https://github.com/openssh/openssh-portable/pull/225 by
+ ZenithalHourlyRate
- OpenBSD-Commit-ID: 9c35ec3aa0f710e4e3325187ceff4fa3791686de
+ OpenBSD-Commit-ID: 7c736307bf3f2c7cb24d6f82f244eee959485acd
-commit f7bd11e4941620991f3e727cd0131b01f0311a58
+commit 88e3d4de31ab4f14cac658e9e0c512043b15b146
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Oct 19 08:07:08 2020 +0000
+Date: Thu Feb 18 02:13:58 2021 +0000
- upstream: fix SEGV on fatal() errors spotted by dtucker@
+ upstream: unbreak SK_DEBUG builds
- 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.
+ from https://github.com/openssh/openssh-portable/pull/225 by
+ ZenithalHourlyRate
- Caught by the PAM -Werror tinderbox build.
+ OpenBSD-Commit-ID: 28d7259ce1b04d025411464decfa2f1a097b43eb
-commit 816036f142ecd284c12bb3685ae316a68d2ef190
+commit 788cbc5b74a53956ba9fff11e1ca506271a3597f
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Oct 18 11:32:01 2020 +0000
+Date: Thu Feb 18 00:30:17 2021 +0000
- upstream: use the new variant log macros instead of prepending
+ 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.
- __func__ and appending ssh_err(r) manually; ok markus@
+ Patch from Mike Frysinger; ok dtucker@
- OpenBSD-Commit-ID: 1f14b80bcfa85414b2a1a6ff714fb5362687ace8
+ OpenBSD-Commit-ID: f96293221e5aa24102d9bf30e4f4ef04d5f4fb51
-commit 9e2c4f64224f68fb84c49b5182e449f94b0dc985
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Oct 18 11:21:59 2020 +0000
+commit 324449a68d510720d0e4dfcc8e9e5a702fe6a48f
+Author: Damien Miller <djm@mindrot.org>
+Date: Thu Feb 18 12:06:25 2021 +1100
- upstream: variants of the log methods that append a ssherr.h string
+ support OpenSSL 3.x cipher IV API change
- from a supplied error code; ok markus@
+ OpenSSL renamed the "get current CIPHER_CTX" IV operation in 3.x.
+ This uses the new name if available.
- 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@
+ https://github.com/openssl/openssl/issues/13411
- OpenBSD-Commit-ID: 0c529d06e902c5d1a6b231e1bec6157f76dc67c9
+ bz#3238 ok dtucker@
-commit 9cac1db52e6c4961c447910fe02cd68a3b2f9460
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Oct 18 11:13:45 2020 +0000
+commit 845fe9811c047063d935eca89188ed55c993626b
+Author: Damien Miller <djm@mindrot.org>
+Date: Thu Feb 18 11:25:38 2021 +1100
- upstream: add some variant log.h calls that prepend the calling
+ prefer login_getpwclass() to login_getclass()
- function name; ok markus@
+ FreeBSD has login_getpwclass() that does some special magic for
+ UID=0. Prefer this to login_getclass() as its easier to emulate
+ the former with the latter.
- OpenBSD-Commit-ID: 4be1b2e2455b271ddb7457bc195c5367644f4e48
+ Based on FreeBSD PR 37416 via Ed Maste; ok dtucker@
-commit d55dfed34ef6ef1f028d552a90d5f3dba8dd6f7b
-Author: Damien Miller <djm@mindrot.org>
-Date: Sat Oct 17 22:55:24 2020 +1100
+commit d0763c8d566119cce84d9806e419badf20444b02
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Feb 18 10:45:27 2021 +1100
- missing header
+ Fixing quoting for installing moduli on target guest.
-commit 999d7cb79a3a73d92a6dfbf174c33da0d984c7a2
-Author: Damien Miller <djm@mindrot.org>
-Date: Sat Oct 17 22:47:52 2020 +1100
+commit b3afc243bc820f323a09e3218e9ec8a30a3c1933
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Feb 18 10:27:16 2021 +1100
- sync regress/misc/sk-dummy/fatal.c
+ Install moduli on target not host.
-commit 3554b4afa38b3483a3302f1be18eaa6f843bb260
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Oct 17 01:28:20 2020 +0000
+commit f060c2bc85d59d111fa18a12eb3872ee4b9f7e97
+Author: Damien Miller <djm@mindrot.org>
+Date: Thu Feb 18 10:33:58 2021 +1100
- upstream: make the log functions that exit (sshlogdie(),
+ don't free string returned by login_getcapstr(3)
- sshfatal(), etc) have identical signatures. Makes things a bit more
- consistent...
+ 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.
- OpenBSD-Commit-ID: bd0ae124733389d7c0042e135c71ee9091362eb9
+ From https://reviews.freebsd.org/D28617 via Ed Maste; ok dtucker@
-commit 616029a85ad7529b24bb8c4631d9607c0d6e7afe
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Fri Oct 16 14:34:33 2020 +0000
+commit bc9b0c25703215501da28aa7a6539f96c0fa656f
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Feb 18 10:10:00 2021 +1100
- upstream: add space between macro arg and punctuation;
-
- OpenBSD-Commit-ID: bb81e2ed5a77832fe62ab30a915ae67cda57633e
+ Skip unit tests on sol11 to speed things up.
-commit f812a36cee5727147bc897d34ab9af068dd4561e
-Author: Damien Miller <djm@mindrot.org>
-Date: Sat Oct 17 12:03:34 2020 +1100
+commit 161873035c12cc22211fc73d07170ade47746bc5
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Feb 18 10:09:27 2021 +1100
- check for and require a C99 capable compiler
+ 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.
- recent logging changes use __VA_ARGS__.
+ Allows us to run tests without falling back to a fixed modulus. Ensure that
+ the directory exists.
-commit f9ea6515202b59a1e2d5b885cafc1b12eff33016
-Author: Damien Miller <djm@mindrot.org>
-Date: Sat Oct 17 11:51:20 2020 +1100
+commit 5c8f41ad100601ec2fdcbccdfe92890c31f81bbe
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Feb 18 09:59:09 2021 +1100
- logging is now macros, remove function pointers
+ Quote SSHD_CONFOPTS in case it contains spaces.
-commit 0f938f998626e8359324f803157cd7c9f8f403e2
-Author: Damien Miller <djm@mindrot.org>
-Date: Sat Oct 17 11:42:26 2020 +1100
+commit 4653116c1f5384ea7006e6396d9b53c33d218975
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Feb 18 09:51:18 2021 +1100
- adapt sk-dummy's fatal implementation to changes
+ Fix labels on targets (dots vs underscores).
-commit afbd9ec9e2dbad04834ce7ce53e58740434f32a5
-Author: Damien Miller <djm@mindrot.org>
-Date: Sat Oct 17 11:33:13 2020 +1100
+commit 4512047f57ca3c6e8cd68f0cc69be59e98b25287
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Feb 17 21:47:48 2021 +1100
- fix netcat build problem
+ More compact representation of config matrix.
-commit 793b583d097381730adaf6f68bed3c343139a013
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Oct 16 13:26:13 2020 +0000
+commit 0406cd09f05c2e419b113dd4c0eac8bc34ec915b
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Feb 17 21:19:18 2021 +1100
- upstream: LogVerbose keyword for ssh and sshd
-
- Allows forcing maximum debug logging by file/function/line pattern-
- lists.
-
- ok markus@
-
- OpenBSD-Commit-ID: c294c25732d1b4fe7e345cb3e044df00531a6356
+ Skip unit tests on hosted VMs to speed things up.
-commit 752250caabda3dd24635503c4cd689b32a650794
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Oct 16 13:24:45 2020 +0000
+commit 4582612e6147d766c336198c498740242fb8f1ec
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Feb 17 20:21:29 2021 +1100
- 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
+ Merge macos and ubuntu tests.
-commit acadbb3402b70f72f14d9a6930ad41be97c2f9dc
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Oct 16 02:37:12 2020 +0000
+commit 09f4b84654b71099559492e9aed5e1a38bf24815
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Feb 17 18:41:30 2021 +1100
- upstream: use do_log2 instead of function pointers to different log
-
- functions
-
- OpenBSD-Commit-ID: 88077b826d348c58352a6b394755520f4e484480
+ Convert most github hosted tests to new config structure.
-commit 95b0bcfd1531d59e056ae8af27bb741391f26ab0
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Oct 14 00:55:17 2020 +0000
+commit 65380ff7e054be1454e5ab4fd7bb9c66f8fcbaa9
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Wed Feb 17 18:27:36 2021 +1100
- 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
+ Only run selfhosted tests from selfhosted repo.
-commit a336ce8c2c55547cc00e0070a18c55f30bb53fb6
-Author: kn@openbsd.org <kn@openbsd.org>
-Date: Mon Oct 12 08:36:36 2020 +0000
+commit f031366535650b88248ed7dbf23033afdf466240
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Jan 15 14:11:43 2021 +1100
- upstream: Zap unused family parameter from ssh_connect_direct()
-
- sshconnect.c r1.241 from 2013 made it unused; found while reading code.
+ Add self-hosted runners for VMs of other platforms.
- OK djm
+ 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).
- 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()
+ 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.
- 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.
+ 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.
- 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
+ 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.
- SSH-Copy-ID-Upstream: 42aeb1cc53d3f7f6e78edc210fb121fda0834914
+ [0] https://docs.github.com/en/actions/hosting-your-own-runners/about-self-hosted-runners#self-hosted-runner-security-with-public-repositories
-commit f7c3a39b016dd77709ecbf18da8282f967b86cd7
-Author: Philip Hands <phil@hands.com>
-Date: Sat Oct 3 21:45:16 2020 +0200
+commit 64bbd7444d658ef7ee14a7ea5ccc7f5810279ee7
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Wed Feb 17 03:59:00 2021 +0000
- shellcheck tidyage
+ upstream: Make sure puttygen is new enough to successfully run the
- 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
+ PuTTY interop tests, otherwise skip them.
- SSH-Copy-ID-Upstream: 2d8b22d96c105d87743ffe8874887b06f8989b93
+ OpenBSD-Regress-ID: 34565bb50b8aec58331ed02a5e9e0a9a929bef51
-commit a9c9e91a82bc1a2cf801b4e3ef27a941dbd27717
-Author: Philip Hands <phil@hands.com>
-Date: Wed Sep 16 16:13:30 2020 +0200
+commit da0a9afcc446a30ca49dd216612c41ac3cb1f2d4
+Author: markus@openbsd.org <markus@openbsd.org>
+Date: Mon Feb 15 20:43:15 2021 +0000
- add -s flag: to install keys via SFTP
-
- This is prompted by:
-
- https://bugzilla.mindrot.org/show_bug.cgi?id=3201
+ upstream: ssh: add PermitRemoteOpen for remote dynamic forwarding
- Thanks go to Matthias Blümel for the idea, and the helpful patch, from
- which this patch grew.
+ with SOCKS ok djm@, dtucker@
- SSH-Copy-ID-Upstream: f7c76dc64427cd20287a6868f672423b62057614
+ OpenBSD-Commit-ID: 64fe7b6360acc4ea56aa61b66498b5ecc0a96a7c
-commit f92424970c02b78852ff149378c7f2616ada4ccf
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Oct 11 22:14:38 2020 +0000
+commit b696858a7f9db72a83d02cb6edaca4b30a91b386
+Author: markus@openbsd.org <markus@openbsd.org>
+Date: Mon Feb 15 20:36:35 2021 +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@
+ upstream: factor out opt_array_append; ok djm@
- OpenBSD-Commit-ID: 6444a705ba504c3c8ccddccd8d1b94aa33bd11c1
+ OpenBSD-Commit-ID: 571bc5dd35f99c5cf9de6aaeac428b168218e74a
-commit d98f14b5328922ae3085e07007d820c4f655b57a
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Oct 11 22:13:37 2020 +0000
+commit ad74fc127cc45567e170e8c6dfa2cfd9767324ec
+Author: dlg@openbsd.org <dlg@openbsd.org>
+Date: Mon Feb 15 11:09:22 2021 +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.
+ upstream: ProxyJump takes "none" to disable processing like
- Make sure this works with HashKnownHosts too, which requires maintaining
- a list of entry-types seen across the whole file for each key.
+ ProxyCommand does
- ok markus@
+ ok djm@ jmc@
- OpenBSD-Commit-ID: 374dc263103f6b343d9671f87dbf81ffd0d6abdd
+ OpenBSD-Commit-ID: 941a2399da2193356bdc30b879d6e1692f18b6d3
-commit af5941ae9b013aac12585e84c4cf494f3728982f
+commit 16eacdb016ccf38dd9959c78edd3a6282513aa53
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Oct 11 22:12:44 2020 +0000
+Date: Fri Feb 12 03:49:09 2021 +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.
+ upstream: sftp: add missing lsetstat@openssh.com documentation
- ok markus@
+ patch from Mike Frysinger
- OpenBSD-Commit-ID: e434828191fb5f3877d4887c218682825aa59820
+ OpenBSD-Commit-ID: 9c114db88d505864075bfe7888b7c8745549715b
-commit 6247812c76f70b2245f3c23f5074665b3d436cae
+commit e04fd6dde16de1cdc5a4d9946397ff60d96568db
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Oct 8 01:15:16 2020 +0000
+Date: Fri Feb 12 03:14:18 2021 +0000
- upstream: don't misdetect comma-separated hostkey names as wildcards;
+ upstream: factor SSH_AGENT_CONSTRAIN_EXTENSION parsing into its own
- spotted by naddy@
+ function and remove an unused variable; ok dtucker@
- 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
+ OpenBSD-Commit-ID: e1a938657fbf7ef0ba5e73b30365734a0cc96559
-commit 3205eaa3f8883a34fa4559ddef6c90d1067c5cce
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Oct 8 00:31:05 2020 +0000
+commit 1bb130ed34721d46452529d094d9bbf045607d79
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Feb 11 10:18:05 2021 +1100
- upstream: clarify conditions for UpdateHostkeys
+ Add __NR_futex_time64 to seccomp sandbox.
- OpenBSD-Commit-ID: 9cba714cf6aeed769f998ccbe8c483077a618e27
+ 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 e8dfca9bfeff05de87160407fb3e6a5717fa3dcb
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Oct 7 06:38:16 2020 +0000
+commit f88a7a431212a16e572ecabd559e632f369c363e
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat Feb 6 09:37:01 2021 +1100
- upstream: remove GlobalKnownHostsFile for this test after
-
- UpdateHostkeys change
+ Add a hostname function for systems that don't have it.
- OpenBSD-Regress-ID: a940ad79d59343319613ba8fc46b6ef24aa3f8e1
+ 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 4aa2717d7517cff4bc423a6cfba3a2defb055aea
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Oct 7 02:26:28 2020 +0000
+commit 5e385a71ef2317856f37c91a98658eb12eb5a89c
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Feb 5 22:03:40 2021 +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.
+ upstream: Roll back the hostname->uname change in rev 1.10. It turns
- reminded by Mark D. Baushke; ok markus@
+ out uname -n doesn't do what we need for some platforms in portable, so we'll
+ fix the original problem (that some other platforms don't have hostname at
+ all) by providing wrapper function to implement it.
- OpenBSD-Commit-ID: 98b524f121f4252309dd21becd8c4cacb0c6042a
+ OpenBSD-Regress-ID: 827a707d6201d5a8e196a8c28aec1d2c76c52341
-commit 04c06d04475f1f673e9d9743710d194453fe3888
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Oct 7 02:25:43 2020 +0000
+commit b446c214279de50ed8388e54897eb1be5281c894
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Feb 5 06:01:58 2021 +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.
+ upstream: hostname is not specified by POSIX but uname -n is, so use
- reported by matthieu@ ok markus@
+ the latter for portability. Patch from Geert Hendrickx via github PR#208.
- OpenBSD-Commit-ID: a654a8290bd1c930aac509e8158cf85e42e49cb7
+ OpenBSD-Regress-ID: d6a79c7c4d141a0d05ade4a042eb57dddbce89f3
-commit b70e33711291f3081702133175a41cccafc0212a
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Oct 7 02:24:51 2020 +0000
+commit 1cb6ce98d658e5fbdae025a3bd65793980e3b5d9
+Author: David Carlier <devnexen@gmail.com>
+Date: Sat Nov 21 12:22:23 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@
+ Using explicit_memset for the explicit_bzero compatibility layer.
- OpenBSD-Commit-ID: eabb771a6add676c398d38a143a1aff5f04abbb9
+ Favoriting the native implementation in this case.
-commit aa623142e426ca1ab9db77b06dcc9b1b70bd102b
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Oct 7 02:22:23 2020 +0000
+commit 2e0beff67def2120f4b051b1016d7fbf84823e78
+Author: Luca Weiss <luca@z3ntu.xyz>
+Date: Sun Nov 8 14:19:23 2020 +0100
- 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
+ Deny (non-fatal) statx in preauth privsep child.
-commit f4f14e023cafee1cd9ebe4bb0db4029e6e1fafac
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Oct 7 02:20:35 2020 +0000
+commit a35d3e911e193a652bd09eed40907e3e165b0a7b
+Author: dtucker@openbsd.org <dtucker@openbsd.org>
+Date: Fri Feb 5 02:20:23 2021 +0000
- upstream: simply disable UpdateHostkeys when a certificate
-
- successfully authenticated the host; simpler than the complicated plumbing
- via kex->flags we have now.
+ upstream: Remove debug message from sigchld handler. While this
- ok markus@
+ works on OpenBSD it can cause problems on other platforms. From kircherlike
+ at outlook.com via bz#3259, ok djm@
- OpenBSD-Commit-ID: 80e39644eed75717d563a7f177e8117a0e14f42c
+ OpenBSD-Commit-ID: 3e241d7ac1ee77e3de3651780b5dc47b283a7668
-commit e79957e877db42c4c68fabcf6ecff2268e53acb5
+commit 69338ab46afe9e3dfb7762ad65351d854077c998
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
+Date: Tue Feb 2 22:36:59 2021 +0000
- upstream: Agent protocol draft is now at rev 4. ok djm@
+ upstream: whitespace
- OpenBSD-Commit-ID: 8c01ea3aae48aab45e01b7421b0fca2dad5e7837
+ OpenBSD-Commit-ID: 544bb092e03fcbecb420196cd0f70af13ea868ad
-commit af889a40ffc113af9105c03d7b32131eb4372d50
+commit f71219a01d8f71c4b3ed7e456337a84ddba1653e
Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Oct 4 09:45:01 2020 +0000
+Date: Tue Feb 2 22:36:46 2021 +0000
- upstream: when ordering host key algorithms in the client, consider
+ upstream: fix memleaks in private key deserialisation; enforce more
- the ECDSA key subtype; ok markus@
+ consistency between redundant fields in private key certificate and private
+ key body; ok markus@
- OpenBSD-Commit-ID: 3097686f853c61ff61772ea35f8b699931392ece
+ OpenBSD-Commit-ID: dec344e414d47f0a7adc13aecf3760fe58101240
-commit 2d39fc9f7e039351daa3d6aead1538ac29258add
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Sun Oct 4 03:04:02 2020 +0000
+commit 3287790e78bf5b53c4a3cafb67bb5aa03e3910f0
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Feb 2 22:35:14 2021 +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@
+ upstream: memleak on error path; ok markus@
- OpenBSD-Commit-ID: 373b7bbf1f15ae482d39567ce30d18b51c9229b5
+ OpenBSD-Commit-ID: 2091a36d6ca3980c81891a6c4bdc544e63cb13a8
diff --git a/crypto/openssh/INSTALL b/crypto/openssh/INSTALL
index 1c9abb1c3a86..77b56a9bb734 100644
--- a/crypto/openssh/INSTALL
+++ b/crypto/openssh/INSTALL
@@ -1,297 +1,297 @@
1. Prerequisites
----------------
A C compiler. Any C89 or better compiler that supports variadic macros
should work. Where supported, configure will attempt to enable the
compiler's run-time integrity checking options. Some notes about
specific compilers:
- clang: -ftrapv and -sanitize=integer require the compiler-rt runtime
(CC=clang LDFLAGS=--rtlib=compiler-rt ./configure)
To support Privilege Separation (which is now required) you will need
to create the user, group and directory used by sshd for privilege
separation. See README.privsep for details.
The remaining items are optional.
A working installation of zlib:
Zlib 1.1.4 or 1.2.1.2 or greater (earlier 1.2.x versions have problems):
-http://www.gzip.org/zlib/
+https://zlib.net/
libcrypto from either of LibreSSL or OpenSSL. Building without libcrypto
is supported but severely restricts the available ciphers and algorithms.
- LibreSSL (https://www.libressl.org/)
- OpenSSL (https://www.openssl.org) with any of the following versions:
- 1.0.x >= 1.0.1 or 1.1.0 >= 1.1.0g or any 1.1.1
Note that due to a bug in EVP_CipherInit OpenSSL 1.1 versions prior to
1.1.0g can't be used.
LibreSSL/OpenSSL should be compiled as a position-independent library
(i.e. -fPIC, eg by configuring OpenSSL as "./config [options] -fPIC"
or LibreSSL as "CFLAGS=-fPIC ./configure") otherwise OpenSSH will not
be able to link with it. If you must use a non-position-independent
libcrypto, then you may need to configure OpenSSH --without-pie.
If you build either from source, running the OpenSSL self-test ("make
tests") or the LibreSSL equivalent ("make check") and ensuring that all
tests pass is strongly recommended.
NB. If you operating system supports /dev/random, you should configure
libcrypto (LibreSSL/OpenSSL) to use it. OpenSSH relies on libcrypto's
direct support of /dev/random, or failing that, either prngd or egd.
PRNGD:
If your system lacks kernel-based random collection, the use of Lutz
Jaenicke's PRNGd is recommended. It requires that libcrypto be configured
to support it.
http://prngd.sourceforge.net/
EGD:
The Entropy Gathering Daemon (EGD) supports the same interface as prngd.
It also supported only if libcrypto is configured to support it.
http://egd.sourceforge.net/
PAM:
OpenSSH can utilise Pluggable Authentication Modules (PAM) if your
system supports it. PAM is standard most Linux distributions, Solaris,
HP-UX 11, AIX >= 5.2, FreeBSD, NetBSD and Mac OS X.
Information about the various PAM implementations are available:
Solaris PAM: http://www.sun.com/software/solaris/pam/
Linux PAM: http://www.kernel.org/pub/linux/libs/pam/
OpenPAM: http://www.openpam.org/
If you wish to build the GNOME passphrase requester, you will need the GNOME
libraries and headers.
GNOME:
http://www.gnome.org/
Alternatively, Jim Knoble <jmknoble@pobox.com> has written an excellent X11
passphrase requester. This is maintained separately at:
http://www.jmknoble.net/software/x11-ssh-askpass/
TCP Wrappers:
If you wish to use the TCP wrappers functionality you will need at least
tcpd.h and libwrap.a, either in the standard include and library paths,
or in the directory specified by --with-tcp-wrappers. Version 7.6 is
known to work.
http://ftp.porcupine.org/pub/security/index.html
LibEdit:
sftp supports command-line editing via NetBSD's libedit. If your platform
has it available natively you can use that, alternatively you might try
these multi-platform ports:
http://www.thrysoee.dk/editline/
http://sourceforge.net/projects/libedit/
LDNS:
LDNS is a DNS BSD-licensed resolver library which supports DNSSEC.
http://nlnetlabs.nl/projects/ldns/
Autoconf:
If you modify configure.ac or configure doesn't exist (eg if you checked
the code out of git yourself) then you will need autoconf-2.69 and
automake-1.16.1 to rebuild the automatically generated files by running
"autoreconf". Earlier versions may also work but this is not guaranteed.
http://www.gnu.org/software/autoconf/
http://www.gnu.org/software/automake/
Basic Security Module (BSM):
Native BSM support is known to exist in Solaris from at least 2.5.1,
FreeBSD 6.1 and OS X. Alternatively, you may use the OpenBSM
implementation (http://www.openbsm.org).
makedepend:
https://www.x.org/archive/individual/util/
If you are making significant changes to the code you may need to rebuild
the dependency (.depend) file using "make depend", which requires the
"makedepend" tool from the X11 distribution.
libfido2:
libfido2 allows the use of hardware security keys over USB. libfido2
in turn depends on libcbor. libfido2 >= 1.5.0 is strongly recommended.
Limited functionality is possible with earlier libfido2 versions.
https://github.com/Yubico/libfido2
https://github.com/pjk/libcbor
2. Building / Installation
--------------------------
To install OpenSSH with default options:
./configure
make
make install
This will install the OpenSSH binaries in /usr/local/bin, configuration files
in /usr/local/etc, the server in /usr/local/sbin, etc. To specify a different
installation prefix, use the --prefix option to configure:
./configure --prefix=/opt
make
make install
Will install OpenSSH in /opt/{bin,etc,lib,sbin}. You can also override
specific paths, for example:
./configure --prefix=/opt --sysconfdir=/etc/ssh
make
make install
This will install the binaries in /opt/{bin,lib,sbin}, but will place the
configuration files in /etc/ssh.
If you are using PAM, you may need to manually install a PAM control
file as "/etc/pam.d/sshd" (or wherever your system prefers to keep
them). Note that the service name used to start PAM is __progname,
which is the basename of the path of your sshd (e.g., the service name
for /usr/sbin/osshd will be osshd). If you have renamed your sshd
executable, your PAM configuration may need to be modified.
A generic PAM configuration is included as "contrib/sshd.pam.generic",
you may need to edit it before using it on your system. If you are
using a recent version of Red Hat Linux, the config file in
contrib/redhat/sshd.pam should be more useful. Failure to install a
valid PAM file may result in an inability to use password
authentication. On HP-UX 11 and Solaris, the standard /etc/pam.conf
configuration will work with sshd (sshd will match the other service
name).
There are a few other options to the configure script:
--with-audit=[module] enable additional auditing via the specified module.
Currently, drivers for "debug" (additional info via syslog) and "bsm"
(Sun's Basic Security Module) are supported.
--with-pam enables PAM support. If PAM support is compiled in, it must
also be enabled in sshd_config (refer to the UsePAM directive).
--with-prngd-socket=/some/file allows you to enable EGD or PRNGD
support and to specify a PRNGd socket. Use this if your Unix lacks
/dev/random.
--with-prngd-port=portnum allows you to enable EGD or PRNGD support
and to specify a EGD localhost TCP port. Use this if your Unix lacks
/dev/random.
--with-lastlog=FILE will specify the location of the lastlog file.
./configure searches a few locations for lastlog, but may not find
it if lastlog is installed in a different place.
--without-lastlog will disable lastlog support entirely.
--with-osfsia, --without-osfsia will enable or disable OSF1's Security
Integration Architecture. The default for OSF1 machines is enable.
--with-tcp-wrappers will enable TCP Wrappers (/etc/hosts.allow|deny)
support.
--with-utmpx enables utmpx support. utmpx support is automatic for
some platforms.
--without-shadow disables shadow password support.
--with-ipaddr-display forces the use of a numeric IP address in the
$DISPLAY environment variable. Some broken systems need this.
--with-default-path=PATH allows you to specify a default $PATH for sessions
started by sshd. This replaces the standard path entirely.
--with-pid-dir=PATH specifies the directory in which the sshd.pid file is
created.
--with-xauth=PATH specifies the location of the xauth binary
--with-ssl-dir=DIR allows you to specify where your Libre/OpenSSL
libraries are installed.
--with-ssl-engine enables Libre/OpenSSL's (hardware) ENGINE support
--without-openssl builds without using OpenSSL. Only a subset of ciphers
and algorithms are supported in this configuration.
--without-zlib builds without zlib. This disables the Compression option.
--with-4in6 Check for IPv4 in IPv6 mapped addresses and convert them to
real (AF_INET) IPv4 addresses. Works around some quirks on Linux.
If you need to pass special options to the compiler or linker, you
can specify these as environment variables before running ./configure.
For example:
CC="/usr/foo/cc" CFLAGS="-O" LDFLAGS="-s" LIBS="-lrubbish" ./configure
3. Configuration
----------------
The runtime configuration files are installed by in ${prefix}/etc or
whatever you specified as your --sysconfdir (/usr/local/etc by default).
The default configuration should be instantly usable, though you should
review it to ensure that it matches your security requirements.
To generate a host key, run "make host-key". Alternately you can do so
manually using the following commands:
ssh-keygen -t [type] -f /etc/ssh/ssh_host_key -N ""
for each of the types you wish to generate (rsa, dsa or ecdsa) or
ssh-keygen -A
to generate keys for all supported types.
Replacing /etc/ssh with the correct path to the configuration directory.
(${prefix}/etc or whatever you specified with --sysconfdir during
configuration).
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.
4. (Optional) Send survey
-------------------------
$ make survey
[check the contents of the file "survey" to ensure there's no information
that you consider sensitive]
$ make send-survey
This will send configuration information for the currently configured
host to a survey address. This will help determine which configurations
are actually in use, and what valid combinations of configure options
exist. The raw data is available only to the OpenSSH developers, however
summary data may be published.
5. Problems?
------------
If you experience problems compiling, installing or running OpenSSH,
please refer to the "reporting bugs" section of the webpage at
https://www.openssh.com/
diff --git a/crypto/openssh/Makefile.in b/crypto/openssh/Makefile.in
index 5dde2baa079c..c0ebfa041525 100644
--- a/crypto/openssh/Makefile.in
+++ b/crypto/openssh/Makefile.in
@@ -1,777 +1,780 @@
SHELL=@SH@
AUTORECONF=autoreconf
prefix=@prefix@
exec_prefix=@exec_prefix@
bindir=@bindir@
sbindir=@sbindir@
libexecdir=@libexecdir@
datadir=@datadir@
datarootdir=@datarootdir@
mandir=@mandir@
mansubdir=@mansubdir@
sysconfdir=@sysconfdir@
piddir=@piddir@
srcdir=@srcdir@
top_srcdir=@top_srcdir@
abs_top_srcdir=@abs_top_srcdir@
abs_top_builddir=@abs_top_builddir@
DESTDIR=
VPATH=@srcdir@
SSH_PROGRAM=@bindir@/ssh
ASKPASS_PROGRAM=$(libexecdir)/ssh-askpass
SFTP_SERVER=$(libexecdir)/sftp-server
SSH_KEYSIGN=$(libexecdir)/ssh-keysign
SSH_PKCS11_HELPER=$(libexecdir)/ssh-pkcs11-helper
SSH_SK_HELPER=$(libexecdir)/ssh-sk-helper
PRIVSEP_PATH=@PRIVSEP_PATH@
SSH_PRIVSEP_USER=@SSH_PRIVSEP_USER@
STRIP_OPT=@STRIP_OPT@
TEST_SHELL=@TEST_SHELL@
BUILDDIR=@abs_top_builddir@
PATHS= -DSSHDIR=\"$(sysconfdir)\" \
-D_PATH_SSH_PROGRAM=\"$(SSH_PROGRAM)\" \
-D_PATH_SSH_ASKPASS_DEFAULT=\"$(ASKPASS_PROGRAM)\" \
-D_PATH_SFTP_SERVER=\"$(SFTP_SERVER)\" \
-D_PATH_SSH_KEY_SIGN=\"$(SSH_KEYSIGN)\" \
-D_PATH_SSH_PKCS11_HELPER=\"$(SSH_PKCS11_HELPER)\" \
-D_PATH_SSH_SK_HELPER=\"$(SSH_SK_HELPER)\" \
-D_PATH_SSH_PIDDIR=\"$(piddir)\" \
-D_PATH_PRIVSEP_CHROOT_DIR=\"$(PRIVSEP_PATH)\"
CC=@CC@
LD=@LD@
CFLAGS=@CFLAGS@
CFLAGS_NOPIE=@CFLAGS_NOPIE@
CPPFLAGS=-I. -I$(srcdir) @CPPFLAGS@ $(PATHS) @DEFS@
PICFLAG=@PICFLAG@
LIBS=@LIBS@
CHANNELLIBS=@CHANNELLIBS@
K5LIBS=@K5LIBS@
GSSLIBS=@GSSLIBS@
SSHDLIBS=@SSHDLIBS@
LIBEDIT=@LIBEDIT@
LIBFIDO2=@LIBFIDO2@
AR=@AR@
AWK=@AWK@
RANLIB=@RANLIB@
INSTALL=@INSTALL@
SED=@SED@
XAUTH_PATH=@XAUTH_PATH@
LDFLAGS=-L. -Lopenbsd-compat/ @LDFLAGS@
LDFLAGS_NOPIE=-L. -Lopenbsd-compat/ @LDFLAGS_NOPIE@
EXEEXT=@EXEEXT@
MANFMT=@MANFMT@
MKDIR_P=@MKDIR_P@
.SUFFIXES: .lo
TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-sk-helper$(EXEEXT)
XMSS_OBJS=\
ssh-xmss.o \
sshkey-xmss.o \
xmss_commons.o \
xmss_fast.o \
xmss_hash.o \
xmss_hash_address.o \
xmss_wots.o
LIBOPENSSH_OBJS=\
ssh_api.o \
ssherr.o \
sshbuf.o \
sshkey.o \
sshbuf-getput-basic.o \
sshbuf-misc.o \
sshbuf-getput-crypto.o \
krl.o \
bitmap.o \
${XMSS_OBJS}
LIBSSH_OBJS=${LIBOPENSSH_OBJS} \
authfd.o authfile.o \
canohost.o channels.o cipher.o cipher-aes.o cipher-aesctr.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 addr.o addrmatch.o \
atomicio.o dispatch.o mac.o misc.o utf8.o \
monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-ecdsa-sk.o \
ssh-ed25519-sk.o ssh-rsa.o dh.o \
msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \
ssh-pkcs11.o smult_curve25519_ref.o \
poly1305.o chacha.o cipher-chachapoly.o cipher-chachapoly-libcrypto.o \
ssh-ed25519.o digest-openssl.o digest-libc.o \
- hmac.o sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o \
+ hmac.o ed25519.o hash.o \
kex.o kexdh.o kexgex.o kexecdh.o kexc25519.o \
kexgexc.o kexgexs.o \
kexsntrup761x25519.o sntrup761.o kexgen.o \
sftp-realpath.o platform-pledge.o platform-tracing.o platform-misc.o \
sshbuf-io.o
SKOBJS= ssh-sk-client.o
SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \
sshconnect.o sshconnect2.o mux.o $(SKOBJS)
SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o \
audit.o audit-bsm.o audit-linux.o platform.o \
sshpty.o sshlogin.o servconf.o serverloop.o \
auth.o auth2.o auth-options.o session.o \
auth2-chall.o groupaccess.o \
auth-bsdauth.o auth2-hostbased.o auth2-kbdint.o \
auth2-none.o auth2-passwd.o auth2-pubkey.o auth2-pubkeyfile.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 \
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)
SFTP_CLIENT_OBJS=sftp-common.o sftp-client.o sftp-glob.o
SCP_OBJS= scp.o progressmeter.o $(SFTP_CLIENT_OBJS)
SSHADD_OBJS= ssh-add.o $(SKOBJS)
SSHAGENT_OBJS= ssh-agent.o ssh-pkcs11-client.o $(SKOBJS)
SSHKEYGEN_OBJS= ssh-keygen.o sshsig.o $(SKOBJS)
SSHKEYSIGN_OBJS=ssh-keysign.o readconf.o uidswap.o $(SKOBJS)
P11HELPER_OBJS= ssh-pkcs11-helper.o ssh-pkcs11.o $(SKOBJS)
SKHELPER_OBJS= ssh-sk-helper.o ssh-sk.o sk-usbhid.o
SSHKEYSCAN_OBJS=ssh-keyscan.o $(SKOBJS)
SFTPSERVER_OBJS=sftp-common.o sftp-server.o sftp-server-main.o
SFTP_OBJS= sftp.o sftp-usergroup.o progressmeter.o $(SFTP_CLIENT_OBJS)
MANPAGES = moduli.5.out scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out ssh-keysign.8.out ssh-pkcs11-helper.8.out ssh-sk-helper.8.out sshd_config.5.out ssh_config.5.out
MANPAGES_IN = moduli.5 scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-keysign.8 ssh-pkcs11-helper.8 ssh-sk-helper.8 sshd_config.5 ssh_config.5
MANTYPE = @MANTYPE@
CONFIGFILES=sshd_config.out ssh_config.out moduli.out
CONFIGFILES_IN=sshd_config ssh_config moduli
PATHSUBS = \
-e 's|/etc/ssh/ssh_config|$(sysconfdir)/ssh_config|g' \
-e 's|/etc/ssh/ssh_known_hosts|$(sysconfdir)/ssh_known_hosts|g' \
-e 's|/etc/ssh/sshd_config|$(sysconfdir)/sshd_config|g' \
-e 's|/usr/libexec|$(libexecdir)|g' \
-e 's|/etc/shosts.equiv|$(sysconfdir)/shosts.equiv|g' \
-e 's|/etc/ssh/ssh_host_key|$(sysconfdir)/ssh_host_key|g' \
-e 's|/etc/ssh/ssh_host_ecdsa_key|$(sysconfdir)/ssh_host_ecdsa_key|g' \
-e 's|/etc/ssh/ssh_host_dsa_key|$(sysconfdir)/ssh_host_dsa_key|g' \
-e 's|/etc/ssh/ssh_host_rsa_key|$(sysconfdir)/ssh_host_rsa_key|g' \
-e 's|/etc/ssh/ssh_host_ed25519_key|$(sysconfdir)/ssh_host_ed25519_key|g' \
-e 's|/var/run/sshd.pid|$(piddir)/sshd.pid|g' \
-e 's|/etc/moduli|$(sysconfdir)/moduli|g' \
-e 's|/etc/ssh/moduli|$(sysconfdir)/moduli|g' \
-e 's|/etc/ssh/sshrc|$(sysconfdir)/sshrc|g' \
-e 's|/usr/X11R6/bin/xauth|$(XAUTH_PATH)|g' \
-e 's|/var/empty|$(PRIVSEP_PATH)|g' \
-e 's|/usr/bin:/bin:/usr/sbin:/sbin|@user_path@|g'
FIXPATHSCMD = $(SED) $(PATHSUBS)
FIXALGORITHMSCMD= $(SHELL) $(srcdir)/fixalgorithms $(SED) \
@UNSUPPORTED_ALGORITHMS@
all: $(CONFIGFILES) $(MANPAGES) $(TARGETS)
$(LIBSSH_OBJS): Makefile.in config.h
$(SSHOBJS): Makefile.in config.h
$(SSHDOBJS): Makefile.in config.h
.c.o:
$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@
LIBCOMPAT=openbsd-compat/libopenbsd-compat.a
$(LIBCOMPAT): always
(cd openbsd-compat && $(MAKE))
always:
libssh.a: $(LIBSSH_OBJS)
$(AR) rv $@ $(LIBSSH_OBJS)
$(RANLIB) $@
ssh$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHOBJS)
$(LD) -o $@ $(SSHOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) $(GSSLIBS) $(CHANNELLIBS)
sshd$(EXEEXT): libssh.a $(LIBCOMPAT) $(SSHDOBJS)
$(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) $(CHANNELLIBS)
scp$(EXEEXT): $(LIBCOMPAT) libssh.a $(SCP_OBJS)
$(LD) -o $@ $(SCP_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
ssh-add$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHADD_OBJS)
$(LD) -o $@ $(SSHADD_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) $(CHANNELLIBS)
ssh-agent$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHAGENT_OBJS)
$(LD) -o $@ $(SSHAGENT_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) $(CHANNELLIBS)
ssh-keygen$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHKEYGEN_OBJS)
$(LD) -o $@ $(SSHKEYGEN_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) $(CHANNELLIBS)
ssh-keysign$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHKEYSIGN_OBJS)
$(LD) -o $@ $(SSHKEYSIGN_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) $(CHANNELLIBS)
ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT) libssh.a $(P11HELPER_OBJS)
$(LD) -o $@ $(P11HELPER_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) $(CHANNELLIBS)
ssh-sk-helper$(EXEEXT): $(LIBCOMPAT) libssh.a $(SKHELPER_OBJS)
$(LD) -o $@ $(SKHELPER_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) $(LIBFIDO2) $(CHANNELLIBS)
ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHKEYSCAN_OBJS)
$(LD) -o $@ $(SSHKEYSCAN_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) $(CHANNELLIBS)
sftp-server$(EXEEXT): $(LIBCOMPAT) libssh.a $(SFTPSERVER_OBJS)
$(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)
# test driver for the loginrec code - not built by default
logintest: logintest.o $(LIBCOMPAT) libssh.a loginrec.o
$(LD) -o $@ logintest.o $(LDFLAGS) loginrec.o -lopenbsd-compat -lssh $(LIBS)
$(MANPAGES): $(MANPAGES_IN)
if test "$(MANTYPE)" = "cat"; then \
manpage=$(srcdir)/`echo $@ | sed 's/\.[1-9]\.out$$/\.0/'`; \
else \
manpage=$(srcdir)/`echo $@ | sed 's/\.out$$//'`; \
fi; \
if test "$(MANTYPE)" = "man"; then \
$(FIXPATHSCMD) $${manpage} | $(FIXALGORITHMSCMD) | \
$(AWK) -f $(srcdir)/mdoc2man.awk > $@; \
else \
$(FIXPATHSCMD) $${manpage} | $(FIXALGORITHMSCMD) > $@; \
fi
$(CONFIGFILES): $(CONFIGFILES_IN)
conffile=`echo $@ | sed 's/.out$$//'`; \
$(FIXPATHSCMD) $(srcdir)/$${conffile} > $@
# fake rule to stop make trying to compile moduli.o into a binary "moduli.o"
moduli:
echo
clean: regressclean
rm -f *.o *.lo *.a $(TARGETS) logintest config.cache config.log
rm -f *.out core survey
rm -f regress/check-perm$(EXEEXT)
rm -f regress/mkdtemp$(EXEEXT)
rm -f regress/unittests/test_helper/*.a
rm -f regress/unittests/test_helper/*.o
rm -f regress/unittests/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
rm -f regress/unittests/conversion/test_conversion$(EXEEXT)
rm -f regress/unittests/hostkeys/*.o
rm -f regress/unittests/hostkeys/test_hostkeys$(EXEEXT)
rm -f regress/unittests/kex/*.o
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/sk-dummy/*.o
rm -f regress/misc/sk-dummy/*.lo
rm -f regress/misc/sk-dummy/sk-dummy.so
(cd openbsd-compat && $(MAKE) clean)
distclean: regressclean
rm -f *.o *.a $(TARGETS) logintest config.cache config.log
rm -f *.out core opensshd.init openssh.xml
rm -f Makefile buildpkg.sh config.h config.status
rm -f survey.sh openbsd-compat/regress/Makefile *~
rm -rf autom4te.cache
rm -f regress/check-perm
rm -f regress/mkdtemp
rm -f regress/unittests/test_helper/*.a
rm -f regress/unittests/test_helper/*.o
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
rm -f regress/unittests/conversion/test_conversion
rm -f regress/unittests/hostkeys/*.o
rm -f regress/unittests/hostkeys/test_hostkeys
rm -f regress/unittests/kex/*.o
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/sk-dummy/*.o
rm -f regress/misc/sk-dummy/*.lo
rm -f regress/misc/sk-dummy/sk-dummy.so
(cd openbsd-compat && $(MAKE) distclean)
if test -d pkg ; then \
rm -fr pkg ; \
fi
veryclean: distclean
rm -f configure config.h.in *.0
cleandir: veryclean
mrproper: veryclean
realclean: veryclean
catman-do:
@for f in $(MANPAGES_IN) ; do \
base=`echo $$f | sed 's/\..*$$//'` ; \
echo "$$f -> $$base.0" ; \
$(MANFMT) $$f | cat -v | sed -e 's/.\^H//g' \
>$$base.0 ; \
done
depend: depend-rebuild
rm -f .depend.bak
depend-rebuild:
mv .depend .depend.old
rm -f config.h .depend
touch config.h .depend
makedepend -w1000 -Y. -f .depend *.c 2>/dev/null
(echo '# Automatically generated by makedepend.'; \
echo '# Run "make depend" to rebuild.'; sort .depend ) >.depend.tmp
mv .depend.tmp .depend
rm -f .depend.bak
mv .depend.old .depend.bak
rm -f config.h
depend-check: depend-rebuild
cmp .depend .depend.bak || (echo .depend stale && exit 1)
distprep: catman-do depend-check
$(AUTORECONF)
-rm -rf autom4te.cache .depend.bak
install: $(CONFIGFILES) $(MANPAGES) $(TARGETS) install-files install-sysconf host-key check-config
install-nokeys: $(CONFIGFILES) $(MANPAGES) $(TARGETS) install-files install-sysconf
install-nosysconf: $(CONFIGFILES) $(MANPAGES) $(TARGETS) install-files
check-config:
-$(DESTDIR)$(sbindir)/sshd -t -f $(DESTDIR)$(sysconfdir)/sshd_config
install-files:
$(MKDIR_P) $(DESTDIR)$(bindir)
$(MKDIR_P) $(DESTDIR)$(sbindir)
$(MKDIR_P) $(DESTDIR)$(mandir)/$(mansubdir)1
$(MKDIR_P) $(DESTDIR)$(mandir)/$(mansubdir)5
$(MKDIR_P) $(DESTDIR)$(mandir)/$(mansubdir)8
$(MKDIR_P) $(DESTDIR)$(libexecdir)
$(MKDIR_P) -m 0755 $(DESTDIR)$(PRIVSEP_PATH)
$(INSTALL) -m 0755 $(STRIP_OPT) ssh$(EXEEXT) $(DESTDIR)$(bindir)/ssh$(EXEEXT)
$(INSTALL) -m 0755 $(STRIP_OPT) scp$(EXEEXT) $(DESTDIR)$(bindir)/scp$(EXEEXT)
$(INSTALL) -m 0755 $(STRIP_OPT) ssh-add$(EXEEXT) $(DESTDIR)$(bindir)/ssh-add$(EXEEXT)
$(INSTALL) -m 0755 $(STRIP_OPT) ssh-agent$(EXEEXT) $(DESTDIR)$(bindir)/ssh-agent$(EXEEXT)
$(INSTALL) -m 0755 $(STRIP_OPT) ssh-keygen$(EXEEXT) $(DESTDIR)$(bindir)/ssh-keygen$(EXEEXT)
$(INSTALL) -m 0755 $(STRIP_OPT) ssh-keyscan$(EXEEXT) $(DESTDIR)$(bindir)/ssh-keyscan$(EXEEXT)
$(INSTALL) -m 0755 $(STRIP_OPT) sshd$(EXEEXT) $(DESTDIR)$(sbindir)/sshd$(EXEEXT)
$(INSTALL) -m 4711 $(STRIP_OPT) ssh-keysign$(EXEEXT) $(DESTDIR)$(SSH_KEYSIGN)$(EXEEXT)
$(INSTALL) -m 0755 $(STRIP_OPT) ssh-pkcs11-helper$(EXEEXT) $(DESTDIR)$(SSH_PKCS11_HELPER)$(EXEEXT)
$(INSTALL) -m 0755 $(STRIP_OPT) ssh-sk-helper$(EXEEXT) $(DESTDIR)$(SSH_SK_HELPER)$(EXEEXT)
$(INSTALL) -m 0755 $(STRIP_OPT) sftp$(EXEEXT) $(DESTDIR)$(bindir)/sftp$(EXEEXT)
$(INSTALL) -m 0755 $(STRIP_OPT) sftp-server$(EXEEXT) $(DESTDIR)$(SFTP_SERVER)$(EXEEXT)
$(INSTALL) -m 644 ssh.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1
$(INSTALL) -m 644 scp.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/scp.1
$(INSTALL) -m 644 ssh-add.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-add.1
$(INSTALL) -m 644 ssh-agent.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-agent.1
$(INSTALL) -m 644 ssh-keygen.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-keygen.1
$(INSTALL) -m 644 ssh-keyscan.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-keyscan.1
$(INSTALL) -m 644 moduli.5.out $(DESTDIR)$(mandir)/$(mansubdir)5/moduli.5
$(INSTALL) -m 644 sshd_config.5.out $(DESTDIR)$(mandir)/$(mansubdir)5/sshd_config.5
$(INSTALL) -m 644 ssh_config.5.out $(DESTDIR)$(mandir)/$(mansubdir)5/ssh_config.5
$(INSTALL) -m 644 sshd.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/sshd.8
$(INSTALL) -m 644 sftp.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/sftp.1
$(INSTALL) -m 644 sftp-server.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/sftp-server.8
$(INSTALL) -m 644 ssh-keysign.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-keysign.8
$(INSTALL) -m 644 ssh-pkcs11-helper.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-pkcs11-helper.8
$(INSTALL) -m 644 ssh-sk-helper.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-sk-helper.8
install-sysconf:
$(MKDIR_P) $(DESTDIR)$(sysconfdir)
@if [ ! -f $(DESTDIR)$(sysconfdir)/ssh_config ]; then \
$(INSTALL) -m 644 ssh_config.out $(DESTDIR)$(sysconfdir)/ssh_config; \
else \
echo "$(DESTDIR)$(sysconfdir)/ssh_config already exists, install will not overwrite"; \
fi
@if [ ! -f $(DESTDIR)$(sysconfdir)/sshd_config ]; then \
$(INSTALL) -m 644 sshd_config.out $(DESTDIR)$(sysconfdir)/sshd_config; \
else \
echo "$(DESTDIR)$(sysconfdir)/sshd_config already exists, install will not overwrite"; \
fi
@if [ ! -f $(DESTDIR)$(sysconfdir)/moduli ]; then \
if [ -f $(DESTDIR)$(sysconfdir)/primes ]; then \
echo "moving $(DESTDIR)$(sysconfdir)/primes to $(DESTDIR)$(sysconfdir)/moduli"; \
mv "$(DESTDIR)$(sysconfdir)/primes" "$(DESTDIR)$(sysconfdir)/moduli"; \
else \
$(INSTALL) -m 644 moduli.out $(DESTDIR)$(sysconfdir)/moduli; \
fi ; \
else \
echo "$(DESTDIR)$(sysconfdir)/moduli already exists, install will not overwrite"; \
fi
host-key: ssh-keygen$(EXEEXT)
@if [ -z "$(DESTDIR)" ] ; then \
./ssh-keygen -A; \
fi
host-key-force: ssh-keygen$(EXEEXT) ssh$(EXEEXT)
./ssh-keygen -t dsa -f $(DESTDIR)$(sysconfdir)/ssh_host_dsa_key -N ""
./ssh-keygen -t rsa -f $(DESTDIR)$(sysconfdir)/ssh_host_rsa_key -N ""
./ssh-keygen -t ed25519 -f $(DESTDIR)$(sysconfdir)/ssh_host_ed25519_key -N ""
if ./ssh -Q key | grep ecdsa >/dev/null ; then \
./ssh-keygen -t ecdsa -f $(DESTDIR)$(sysconfdir)/ssh_host_ecdsa_key -N ""; \
fi
uninstallall: uninstall
-rm -f $(DESTDIR)$(sysconfdir)/ssh_config
-rm -f $(DESTDIR)$(sysconfdir)/sshd_config
-rmdir $(DESTDIR)$(sysconfdir)
-rmdir $(DESTDIR)$(bindir)
-rmdir $(DESTDIR)$(sbindir)
-rmdir $(DESTDIR)$(mandir)/$(mansubdir)1
-rmdir $(DESTDIR)$(mandir)/$(mansubdir)8
-rmdir $(DESTDIR)$(mandir)
-rmdir $(DESTDIR)$(libexecdir)
uninstall:
-rm -f $(DESTDIR)$(bindir)/ssh$(EXEEXT)
-rm -f $(DESTDIR)$(bindir)/scp$(EXEEXT)
-rm -f $(DESTDIR)$(bindir)/ssh-add$(EXEEXT)
-rm -f $(DESTDIR)$(bindir)/ssh-agent$(EXEEXT)
-rm -f $(DESTDIR)$(bindir)/ssh-keygen$(EXEEXT)
-rm -f $(DESTDIR)$(bindir)/ssh-keyscan$(EXEEXT)
-rm -f $(DESTDIR)$(bindir)/sftp$(EXEEXT)
-rm -f $(DESTDIR)$(sbindir)/sshd$(EXEEXT)
-rm -r $(DESTDIR)$(SFTP_SERVER)$(EXEEXT)
-rm -f $(DESTDIR)$(SSH_KEYSIGN)$(EXEEXT)
-rm -f $(DESTDIR)$(SSH_PKCS11_HELPER)$(EXEEXT)
-rm -f $(DESTDIR)$(SSH_SK_HELPER)$(EXEEXT)
-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1
-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/scp.1
-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-add.1
-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-agent.1
-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-keygen.1
-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/sftp.1
-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-keyscan.1
-rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/sshd.8
-rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/sftp-server.8
-rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-keysign.8
-rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-pkcs11-helper.8
-rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-sk-helper.8
regress-prep:
$(MKDIR_P) `pwd`/regress/unittests/test_helper
$(MKDIR_P) `pwd`/regress/unittests/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/sk-dummy
[ -f `pwd`/regress/Makefile ] || \
ln -s `cd $(srcdir) && pwd`/regress/Makefile `pwd`/regress/Makefile
REGRESSLIBS=libssh.a $(LIBCOMPAT)
TESTLIBS=$(LIBS) $(CHANNELLIBS)
regress/modpipe$(EXEEXT): $(srcdir)/regress/modpipe.c $(REGRESSLIBS)
$(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $(srcdir)/regress/modpipe.c \
$(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(TESTLIBS)
regress/setuid-allowed$(EXEEXT): $(srcdir)/regress/setuid-allowed.c $(REGRESSLIBS)
$(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $(srcdir)/regress/setuid-allowed.c \
$(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(TESTLIBS)
regress/netcat$(EXEEXT): $(srcdir)/regress/netcat.c $(REGRESSLIBS)
$(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $(srcdir)/regress/netcat.c \
$(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(TESTLIBS)
regress/check-perm$(EXEEXT): $(srcdir)/regress/check-perm.c $(REGRESSLIBS)
$(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $(srcdir)/regress/check-perm.c \
$(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(TESTLIBS)
regress/mkdtemp$(EXEEXT): $(srcdir)/regress/mkdtemp.c $(REGRESSLIBS)
$(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $(srcdir)/regress/mkdtemp.c \
$(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(TESTLIBS)
UNITTESTS_TEST_HELPER_OBJS=\
regress/unittests/test_helper/test_helper.o \
regress/unittests/test_helper/fuzz.o
regress/unittests/test_helper/libtest_helper.a: ${UNITTESTS_TEST_HELPER_OBJS}
$(AR) rv $@ $(UNITTESTS_TEST_HELPER_OBJS)
$(RANLIB) $@
UNITTESTS_TEST_SSHBUF_OBJS=\
regress/unittests/sshbuf/tests.o \
regress/unittests/sshbuf/test_sshbuf.o \
regress/unittests/sshbuf/test_sshbuf_getput_basic.o \
regress/unittests/sshbuf/test_sshbuf_getput_crypto.o \
regress/unittests/sshbuf/test_sshbuf_misc.o \
regress/unittests/sshbuf/test_sshbuf_fuzz.o \
regress/unittests/sshbuf/test_sshbuf_getput_fuzz.o \
regress/unittests/sshbuf/test_sshbuf_fixed.o
regress/unittests/sshbuf/test_sshbuf$(EXEEXT): ${UNITTESTS_TEST_SSHBUF_OBJS} \
regress/unittests/test_helper/libtest_helper.a libssh.a
$(LD) -o $@ $(LDFLAGS) $(UNITTESTS_TEST_SSHBUF_OBJS) \
regress/unittests/test_helper/libtest_helper.a \
-lssh -lopenbsd-compat -lssh -lopenbsd-compat $(TESTLIBS)
UNITTESTS_TEST_SSHKEY_OBJS=\
regress/unittests/sshkey/test_fuzz.o \
regress/unittests/sshkey/tests.o \
regress/unittests/sshkey/common.o \
regress/unittests/sshkey/test_file.o \
regress/unittests/sshkey/test_sshkey.o \
$(SKOBJS)
regress/unittests/sshkey/test_sshkey$(EXEEXT): ${UNITTESTS_TEST_SSHKEY_OBJS} \
regress/unittests/test_helper/libtest_helper.a libssh.a
$(LD) -o $@ $(LDFLAGS) $(UNITTESTS_TEST_SSHKEY_OBJS) \
regress/unittests/test_helper/libtest_helper.a \
-lssh -lopenbsd-compat -lssh -lopenbsd-compat $(TESTLIBS)
UNITTESTS_TEST_SSHSIG_OBJS=\
sshsig.o \
regress/unittests/sshsig/tests.o \
$(SKOBJS)
regress/unittests/sshsig/test_sshsig$(EXEEXT): ${UNITTESTS_TEST_SSHSIG_OBJS} \
regress/unittests/test_helper/libtest_helper.a libssh.a
$(LD) -o $@ $(LDFLAGS) $(UNITTESTS_TEST_SSHSIG_OBJS) \
regress/unittests/test_helper/libtest_helper.a \
-lssh -lopenbsd-compat -lssh -lopenbsd-compat $(TESTLIBS)
UNITTESTS_TEST_BITMAP_OBJS=\
regress/unittests/bitmap/tests.o
regress/unittests/bitmap/test_bitmap$(EXEEXT): ${UNITTESTS_TEST_BITMAP_OBJS} \
regress/unittests/test_helper/libtest_helper.a libssh.a
$(LD) -o $@ $(LDFLAGS) $(UNITTESTS_TEST_BITMAP_OBJS) \
regress/unittests/test_helper/libtest_helper.a \
-lssh -lopenbsd-compat -lssh -lopenbsd-compat $(TESTLIBS)
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 $(TESTLIBS)
UNITTESTS_TEST_CONVERSION_OBJS=\
regress/unittests/conversion/tests.o
regress/unittests/conversion/test_conversion$(EXEEXT): \
${UNITTESTS_TEST_CONVERSION_OBJS} \
regress/unittests/test_helper/libtest_helper.a libssh.a
$(LD) -o $@ $(LDFLAGS) $(UNITTESTS_TEST_CONVERSION_OBJS) \
regress/unittests/test_helper/libtest_helper.a \
-lssh -lopenbsd-compat -lssh -lopenbsd-compat $(TESTLIBS)
UNITTESTS_TEST_KEX_OBJS=\
regress/unittests/kex/tests.o \
regress/unittests/kex/test_kex.o \
+ regress/unittests/kex/test_proposal.o \
$(SKOBJS)
regress/unittests/kex/test_kex$(EXEEXT): ${UNITTESTS_TEST_KEX_OBJS} \
regress/unittests/test_helper/libtest_helper.a libssh.a
$(LD) -o $@ $(LDFLAGS) $(UNITTESTS_TEST_KEX_OBJS) \
regress/unittests/test_helper/libtest_helper.a \
-lssh -lopenbsd-compat -lssh -lopenbsd-compat $(TESTLIBS)
UNITTESTS_TEST_HOSTKEYS_OBJS=\
regress/unittests/hostkeys/tests.o \
regress/unittests/hostkeys/test_iterate.o \
$(SKOBJS)
regress/unittests/hostkeys/test_hostkeys$(EXEEXT): \
${UNITTESTS_TEST_HOSTKEYS_OBJS} \
regress/unittests/test_helper/libtest_helper.a libssh.a
$(LD) -o $@ $(LDFLAGS) $(UNITTESTS_TEST_HOSTKEYS_OBJS) \
regress/unittests/test_helper/libtest_helper.a \
-lssh -lopenbsd-compat -lssh -lopenbsd-compat $(TESTLIBS)
UNITTESTS_TEST_MATCH_OBJS=\
regress/unittests/match/tests.o
regress/unittests/match/test_match$(EXEEXT): \
${UNITTESTS_TEST_MATCH_OBJS} \
regress/unittests/test_helper/libtest_helper.a libssh.a
$(LD) -o $@ $(LDFLAGS) $(UNITTESTS_TEST_MATCH_OBJS) \
regress/unittests/test_helper/libtest_helper.a \
-lssh -lopenbsd-compat -lssh -lopenbsd-compat $(TESTLIBS)
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_hpdelim.o
+ regress/unittests/misc/test_hpdelim.o \
+ regress/unittests/misc/test_ptimeout.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 $(TESTLIBS)
UNITTESTS_TEST_UTF8_OBJS=\
regress/unittests/utf8/tests.o
regress/unittests/utf8/test_utf8$(EXEEXT): \
${UNITTESTS_TEST_UTF8_OBJS} \
regress/unittests/test_helper/libtest_helper.a libssh.a
$(LD) -o $@ $(LDFLAGS) $(UNITTESTS_TEST_UTF8_OBJS) \
regress/unittests/test_helper/libtest_helper.a \
-lssh -lopenbsd-compat -lssh -lopenbsd-compat $(TESTLIBS)
# These all need to be compiled -fPIC, so they are treated differently.
SK_DUMMY_OBJS=\
regress/misc/sk-dummy/sk-dummy.lo \
regress/misc/sk-dummy/fatal.lo \
- ed25519.lo hash.lo ge25519.lo fe25519.lo sc25519.lo verify.lo
+ ed25519.lo hash.lo
SK_DUMMY_LIBRARY=@SK_DUMMY_LIBRARY@
.c.lo: Makefile.in config.h
$(CC) $(CFLAGS_NOPIE) $(PICFLAG) $(CPPFLAGS) -c $< -o $@
regress/misc/sk-dummy/sk-dummy.so: $(SK_DUMMY_OBJS)
$(CC) $(CFLAGS) $(CPPFLAGS) $(PICFLAG) -shared -o $@ $(SK_DUMMY_OBJS) \
-L. -Lopenbsd-compat -lopenbsd-compat $(LDFLAGS_NOPIE) $(TESTLIBS)
regress-binaries: regress-prep $(LIBCOMPAT) \
regress/modpipe$(EXEEXT) \
regress/setuid-allowed$(EXEEXT) \
regress/netcat$(EXEEXT) \
regress/check-perm$(EXEEXT) \
regress/mkdtemp$(EXEEXT) \
$(SK_DUMMY_LIBRARY)
regress-unit-binaries: regress-prep $(REGRESSLIBS) \
regress/unittests/authopt/test_authopt$(EXEEXT) \
regress/unittests/bitmap/test_bitmap$(EXEEXT) \
regress/unittests/conversion/test_conversion$(EXEEXT) \
regress/unittests/hostkeys/test_hostkeys$(EXEEXT) \
regress/unittests/kex/test_kex$(EXEEXT) \
regress/unittests/match/test_match$(EXEEXT) \
regress/unittests/misc/test_misc$(EXEEXT) \
regress/unittests/sshbuf/test_sshbuf$(EXEEXT) \
regress/unittests/sshkey/test_sshkey$(EXEEXT) \
regress/unittests/sshsig/test_sshsig$(EXEEXT) \
regress/unittests/utf8/test_utf8$(EXEEXT)
tests: file-tests t-exec interop-tests unit
echo all tests passed
unit: regress-unit-binaries
cd $(srcdir)/regress || exit $$?; \
$(MAKE) \
.CURDIR="$(abs_top_srcdir)/regress" \
.OBJDIR="$(BUILDDIR)/regress" \
OBJ="$(BUILDDIR)/regress" \
$@ && echo $@ tests passed
interop-tests t-exec file-tests: regress-prep regress-binaries $(TARGETS)
cd $(srcdir)/regress || exit $$?; \
EGREP='@EGREP@' \
+ OPENSSL_BIN='@OPENSSL_BIN@' \
$(MAKE) \
.CURDIR="$(abs_top_srcdir)/regress" \
.OBJDIR="$(BUILDDIR)/regress" \
BUILDDIR="$(BUILDDIR)" \
OBJ="$(BUILDDIR)/regress" \
PATH="$(BUILDDIR):$${PATH}" \
TEST_ENV=MALLOC_OPTIONS="@TEST_MALLOC_OPTIONS@" \
TEST_MALLOC_OPTIONS="@TEST_MALLOC_OPTIONS@" \
TEST_SSH_SCP="$(BUILDDIR)/scp" \
TEST_SSH_SSH="$(BUILDDIR)/ssh" \
TEST_SSH_SSHD="$(BUILDDIR)/sshd" \
TEST_SSH_SSHAGENT="$(BUILDDIR)/ssh-agent" \
TEST_SSH_SSHADD="$(BUILDDIR)/ssh-add" \
TEST_SSH_SSHKEYGEN="$(BUILDDIR)/ssh-keygen" \
TEST_SSH_SSHPKCS11HELPER="$(BUILDDIR)/ssh-pkcs11-helper" \
TEST_SSH_SSHKEYSCAN="$(BUILDDIR)/ssh-keyscan" \
TEST_SSH_SFTP="$(BUILDDIR)/sftp" \
TEST_SSH_PKCS11_HELPER="$(BUILDDIR)/ssh-pkcs11-helper" \
TEST_SSH_SK_HELPER="$(BUILDDIR)/ssh-sk-helper" \
TEST_SSH_SFTPSERVER="$(BUILDDIR)/sftp-server" \
TEST_SSH_MODULI_FILE="$(abs_top_srcdir)/moduli" \
TEST_SSH_PLINK="plink" \
TEST_SSH_PUTTYGEN="puttygen" \
TEST_SSH_CONCH="conch" \
TEST_SSH_IPV6="@TEST_SSH_IPV6@" \
TEST_SSH_UTF8="@TEST_SSH_UTF8@" \
TEST_SHELL="$(TEST_SHELL)" \
EXEEXT="$(EXEEXT)" \
$@ && echo all $@ passed
compat-tests: $(LIBCOMPAT)
(cd openbsd-compat/regress && $(MAKE))
regressclean:
if [ -f regress/Makefile ] && [ -r regress/Makefile ]; then \
(cd regress && $(MAKE) clean) \
fi
survey: survey.sh ssh
@$(SHELL) ./survey.sh > survey
@echo 'The survey results have been placed in the file "survey" in the'
@echo 'current directory. Please review the file then send with'
@echo '"make send-survey".'
send-survey: survey
mail portable-survey@mindrot.org <survey
package: $(CONFIGFILES) $(MANPAGES) $(TARGETS)
if [ "@MAKE_PACKAGE_SUPPORTED@" = yes ]; then \
sh buildpkg.sh; \
fi
# @DEPEND@
diff --git a/crypto/openssh/PROTOCOL b/crypto/openssh/PROTOCOL
index 685f90fa8569..27804d0cadbd 100644
--- a/crypto/openssh/PROTOCOL
+++ b/crypto/openssh/PROTOCOL
@@ -1,715 +1,715 @@
This documents OpenSSH's deviations and extensions to the published SSH
protocol.
Note that OpenSSH's sftp and sftp-server implement revision 3 of the SSH
filexfer protocol described in:
https://www.openssh.com/txt/draft-ietf-secsh-filexfer-02.txt
Newer versions of the draft will not be supported, though some features
are individually implemented as extensions described below.
The protocol used by OpenSSH's ssh-agent is described in the file
PROTOCOL.agent
1. Transport protocol changes
1.1. transport: Protocol 2 MAC algorithm "umac-64@openssh.com"
This is a new transport-layer MAC method using the UMAC algorithm
(rfc4418). This method is identical to the "umac-64" method documented
in:
https://www.openssh.com/txt/draft-miller-secsh-umac-01.txt
1.2. transport: Protocol 2 compression algorithm "zlib@openssh.com"
This transport-layer compression method uses the zlib compression
algorithm (identical to the "zlib" method in rfc4253), but delays the
start of compression until after authentication has completed. This
avoids exposing compression code to attacks from unauthenticated users.
The method is documented in:
https://www.openssh.com/txt/draft-miller-secsh-compression-delayed-00.txt
1.3. transport: New public key algorithms "ssh-rsa-cert-v01@openssh.com",
"ssh-dsa-cert-v01@openssh.com",
"ecdsa-sha2-nistp256-cert-v01@openssh.com",
"ecdsa-sha2-nistp384-cert-v01@openssh.com" and
"ecdsa-sha2-nistp521-cert-v01@openssh.com"
OpenSSH introduces new public key algorithms to support certificate
authentication for users and host keys. These methods are documented
in the file PROTOCOL.certkeys
1.4. transport: Elliptic Curve cryptography
OpenSSH supports ECC key exchange and public key authentication as
specified in RFC5656. Only the ecdsa-sha2-nistp256, ecdsa-sha2-nistp384
and ecdsa-sha2-nistp521 curves over GF(p) are supported. Elliptic
curve points encoded using point compression are NOT accepted or
generated.
1.5 transport: Protocol 2 Encrypt-then-MAC MAC algorithms
OpenSSH supports MAC algorithms, whose names contain "-etm", that
perform the calculations in a different order to that defined in RFC
4253. These variants use the so-called "encrypt then MAC" ordering,
calculating the MAC over the packet ciphertext rather than the
plaintext. This ordering closes a security flaw in the SSH transport
protocol, where decryption of unauthenticated ciphertext provided a
"decryption oracle" that could, in conjunction with cipher flaws, reveal
session plaintext.
Specifically, the "-etm" MAC algorithms modify the transport protocol
to calculate the MAC over the packet ciphertext and to send the packet
length unencrypted. This is necessary for the transport to obtain the
length of the packet and location of the MAC tag so that it may be
verified without decrypting unauthenticated data.
As such, the MAC covers:
mac = MAC(key, sequence_number || packet_length || encrypted_packet)
where "packet_length" is encoded as a uint32 and "encrypted_packet"
contains:
byte padding_length
byte[n1] payload; n1 = packet_length - padding_length - 1
byte[n2] random padding; n2 = padding_length
1.6 transport: AES-GCM
OpenSSH supports the AES-GCM algorithm as specified in RFC 5647.
Because of problems with the specification of the key exchange
the behaviour of OpenSSH differs from the RFC as follows:
AES-GCM is only negotiated as the cipher algorithms
"aes128-gcm@openssh.com" or "aes256-gcm@openssh.com" and never as
an MAC algorithm. Additionally, if AES-GCM is selected as the cipher
the exchanged MAC algorithms are ignored and there doesn't have to be
a matching MAC.
1.7 transport: chacha20-poly1305@openssh.com authenticated encryption
OpenSSH supports authenticated encryption using ChaCha20 and Poly1305
as described in PROTOCOL.chacha20poly1305.
1.8 transport: curve25519-sha256@libssh.org key exchange algorithm
OpenSSH supports the use of ECDH in Curve25519 for key exchange as
described at:
http://git.libssh.org/users/aris/libssh.git/plain/doc/curve25519-sha256@libssh.org.txt?h=curve25519
This is identical to curve25519-sha256 as later published in RFC8731.
2. Connection protocol changes
2.1. connection: Channel write close extension "eow@openssh.com"
The SSH connection protocol (rfc4254) provides the SSH_MSG_CHANNEL_EOF
message to allow an endpoint to signal its peer that it will send no
more data over a channel. Unfortunately, there is no symmetric way for
an endpoint to request that its peer should cease sending data to it
while still keeping the channel open for the endpoint to send data to
the peer.
This is desirable, since it saves the transmission of data that would
otherwise need to be discarded and it allows an endpoint to signal local
processes of the condition, e.g. by closing the corresponding file
descriptor.
OpenSSH implements a channel extension message to perform this
signalling: "eow@openssh.com" (End Of Write). This message is sent by
an endpoint when the local output of a session channel is closed or
experiences a write error. The message is formatted as follows:
byte SSH_MSG_CHANNEL_REQUEST
uint32 recipient channel
string "eow@openssh.com"
boolean FALSE
On receiving this message, the peer SHOULD cease sending data of
the channel and MAY signal the process from which the channel data
originates (e.g. by closing its read file descriptor).
As with the symmetric SSH_MSG_CHANNEL_EOF message, the channel does
remain open after a "eow@openssh.com" has been sent and more data may
still be sent in the other direction. This message does not consume
window space and may be sent even if no window space is available.
NB. due to certain broken SSH implementations aborting upon receipt
of this message (in contravention of RFC4254 section 5.4), this
message is only sent to OpenSSH peers (identified by banner).
Other SSH implementations may be listed to receive this message
upon request.
2.2. connection: disallow additional sessions extension
"no-more-sessions@openssh.com"
Most SSH connections will only ever request a single session, but a
attacker may abuse a running ssh client to surreptitiously open
additional sessions under their control. OpenSSH provides a global
request "no-more-sessions@openssh.com" to mitigate this attack.
When an OpenSSH client expects that it will never open another session
(i.e. it has been started with connection multiplexing disabled), it
will send the following global request:
byte SSH_MSG_GLOBAL_REQUEST
string "no-more-sessions@openssh.com"
char want-reply
On receipt of such a message, an OpenSSH server will refuse to open
future channels of type "session" and instead immediately abort the
connection.
Note that this is not a general defence against compromised clients
(that is impossible), but it thwarts a simple attack.
NB. due to certain broken SSH implementations aborting upon receipt
of this message, the no-more-sessions request is only sent to OpenSSH
servers (identified by banner). Other SSH implementations may be
listed to receive this message upon request.
2.3. connection: Tunnel forward extension "tun@openssh.com"
OpenSSH supports layer 2 and layer 3 tunnelling via the "tun@openssh.com"
channel type. This channel type supports forwarding of network packets
with datagram boundaries intact between endpoints equipped with
interfaces like the BSD tun(4) device. Tunnel forwarding channels are
requested by the client with the following packet:
byte SSH_MSG_CHANNEL_OPEN
string "tun@openssh.com"
uint32 sender channel
uint32 initial window size
uint32 maximum packet size
uint32 tunnel mode
uint32 remote unit number
The "tunnel mode" parameter specifies whether the tunnel should forward
layer 2 frames or layer 3 packets. It may take one of the following values:
SSH_TUNMODE_POINTOPOINT 1 /* layer 3 packets */
SSH_TUNMODE_ETHERNET 2 /* layer 2 frames */
The "tunnel unit number" specifies the remote interface number, or may
be 0x7fffffff to allow the server to automatically choose an interface. A
server that is not willing to open a client-specified unit should refuse
the request with a SSH_MSG_CHANNEL_OPEN_FAILURE error. On successful
open, the server should reply with SSH_MSG_CHANNEL_OPEN_SUCCESS.
Once established the client and server may exchange packet or frames
over the tunnel channel by encapsulating them in SSH protocol strings
and sending them as channel data. This ensures that packet boundaries
are kept intact. Specifically, packets are transmitted using normal
SSH_MSG_CHANNEL_DATA packets:
byte SSH_MSG_CHANNEL_DATA
uint32 recipient channel
string data
The contents of the "data" field for layer 3 packets is:
uint32 packet length
uint32 address family
byte[packet length - 4] packet data
The "address family" field identifies the type of packet in the message.
It may be one of:
SSH_TUN_AF_INET 2 /* IPv4 */
SSH_TUN_AF_INET6 24 /* IPv6 */
The "packet data" field consists of the IPv4/IPv6 datagram itself
without any link layer header.
The contents of the "data" field for layer 2 packets is:
uint32 packet length
byte[packet length] frame
The "frame" field contains an IEEE 802.3 Ethernet frame, including
header.
2.4. connection: Unix domain socket forwarding
OpenSSH supports local and remote Unix domain socket forwarding
using the "streamlocal" extension. Forwarding is initiated as per
TCP sockets but with a single path instead of a host and port.
Similar to direct-tcpip, direct-streamlocal is sent by the client
to request that the server make a connection to a Unix domain socket.
byte SSH_MSG_CHANNEL_OPEN
string "direct-streamlocal@openssh.com"
uint32 sender channel
uint32 initial window size
uint32 maximum packet size
string socket path
string reserved
uint32 reserved
Similar to forwarded-tcpip, forwarded-streamlocal is sent by the
server when the client has previously send the server a streamlocal-forward
GLOBAL_REQUEST.
byte SSH_MSG_CHANNEL_OPEN
string "forwarded-streamlocal@openssh.com"
uint32 sender channel
uint32 initial window size
uint32 maximum packet size
string socket path
string reserved for future use
The reserved field is not currently defined and is ignored on the
remote end. It is intended to be used in the future to pass
information about the socket file, such as ownership and mode.
The client currently sends the empty string for this field.
Similar to tcpip-forward, streamlocal-forward is sent by the client
to request remote forwarding of a Unix domain socket.
byte SSH2_MSG_GLOBAL_REQUEST
string "streamlocal-forward@openssh.com"
boolean TRUE
string socket path
Similar to cancel-tcpip-forward, cancel-streamlocal-forward is sent
by the client cancel the forwarding of a Unix domain socket.
byte SSH2_MSG_GLOBAL_REQUEST
string "cancel-streamlocal-forward@openssh.com"
boolean FALSE
string socket path
2.5. connection: hostkey update and rotation "hostkeys-00@openssh.com"
and "hostkeys-prove-00@openssh.com"
OpenSSH supports a protocol extension allowing a server to inform
a client of all its protocol v.2 host keys after user-authentication
has completed.
byte SSH_MSG_GLOBAL_REQUEST
string "hostkeys-00@openssh.com"
char 0 /* want-reply */
string[] hostkeys
Upon receiving this message, a client should check which of the
supplied host keys are present in known_hosts.
Note that the server may send key types that the client does not
support. The client should disregard such keys if they are received.
If the client identifies any keys that are not present for the host,
it should send a "hostkeys-prove@openssh.com" message to request the
server prove ownership of the private half of the key.
byte SSH_MSG_GLOBAL_REQUEST
string "hostkeys-prove-00@openssh.com"
char 1 /* want-reply */
string[] hostkeys
When a server receives this message, it should generate a signature
using each requested key over the following:
string "hostkeys-prove-00@openssh.com"
string session identifier
string hostkey
These signatures should be included in the reply, in the order matching
the hostkeys in the request:
byte SSH_MSG_REQUEST_SUCCESS
string[] signatures
When the client receives this reply (and not a failure), it should
validate the signatures and may update its known_hosts file, adding keys
that it has not seen before and deleting keys for the server host that
are no longer offered.
These extensions let a client learn key types that it had not previously
encountered, thereby allowing it to potentially upgrade from weaker
key algorithms to better ones. It also supports graceful key rotation:
a server may offer multiple keys of the same type for a period (to
give clients an opportunity to learn them using this extension) before
removing the deprecated key from those offered.
2.6. connection: SIGINFO support for "signal" channel request
The SSH channels protocol (RFC4254 section 6.9) supports sending a
signal to a session attached to a channel. OpenSSH supports one
extension signal "INFO@openssh.com" that allows sending SIGINFO on
BSD-derived systems.
3. Authentication protocol changes
3.1. Host-bound public key authentication
This is trivial change to the traditional "publickey" authentication
method. The authentication request is identical to the original method
but for the name and one additional field:
byte SSH2_MSG_USERAUTH_REQUEST
string username
string "ssh-connection"
string "publickey-hostbound-v00@openssh.com"
bool has_signature
string pkalg
string public key
string server host key
Because the entire SSH2_MSG_USERAUTH_REQUEST message is included in
the signed data, this ensures that a binding between the destination
user, the server identity and the session identifier is visible to the
signer. OpenSSH uses this binding via signed data to implement per-key
restrictions in ssh-agent.
A server may advertise this method using the SSH2_MSG_EXT_INFO
mechanism (RFC8308), with the following message:
string "publickey-hostbound@openssh.com"
string "0" (version)
Clients should prefer host-bound authentication when advertised by
server.
4. SFTP protocol changes
4.1. sftp: Reversal of arguments to SSH_FXP_SYMLINK
When OpenSSH's sftp-server was implemented, the order of the arguments
to the SSH_FXP_SYMLINK method was inadvertently reversed. Unfortunately,
the reversal was not noticed until the server was widely deployed. Since
fixing this to follow the specification would cause incompatibility, the
current order was retained. For correct operation, clients should send
SSH_FXP_SYMLINK as follows:
uint32 id
string targetpath
string linkpath
4.2. sftp: Server extension announcement in SSH_FXP_VERSION
OpenSSH's sftp-server lists the extensions it supports using the
standard extension announcement mechanism in the SSH_FXP_VERSION server
hello packet:
uint32 3 /* protocol version */
string ext1-name
string ext1-version
string ext2-name
string ext2-version
...
string extN-name
string extN-version
Each extension reports its integer version number as an ASCII encoded
string, e.g. "1". The version will be incremented if the extension is
ever changed in an incompatible way. The server MAY advertise the same
extension with multiple versions (though this is unlikely). Clients MUST
check the version number before attempting to use the extension.
4.3. sftp: Extension request "posix-rename@openssh.com"
This operation provides a rename operation with POSIX semantics, which
are different to those provided by the standard SSH_FXP_RENAME in
draft-ietf-secsh-filexfer-02.txt. This request is implemented as a
SSH_FXP_EXTENDED request with the following format:
uint32 id
string "posix-rename@openssh.com"
string oldpath
string newpath
On receiving this request the server will perform the POSIX operation
rename(oldpath, newpath) and will respond with a SSH_FXP_STATUS message.
This extension is advertised in the SSH_FXP_VERSION hello with version
"1".
4.4. sftp: Extension requests "statvfs@openssh.com" and
"fstatvfs@openssh.com"
These requests correspond to the statvfs and fstatvfs POSIX system
interfaces. The "statvfs@openssh.com" request operates on an explicit
pathname, and is formatted as follows:
uint32 id
string "statvfs@openssh.com"
string path
The "fstatvfs@openssh.com" operates on an open file handle:
uint32 id
string "fstatvfs@openssh.com"
string handle
These requests return a SSH_FXP_STATUS reply on failure. On success they
return the following SSH_FXP_EXTENDED_REPLY reply:
uint32 id
uint64 f_bsize /* file system block size */
uint64 f_frsize /* fundamental fs block size */
uint64 f_blocks /* number of blocks (unit f_frsize) */
uint64 f_bfree /* free blocks in file system */
uint64 f_bavail /* free blocks for non-root */
uint64 f_files /* total file inodes */
uint64 f_ffree /* free file inodes */
uint64 f_favail /* free file inodes for to non-root */
uint64 f_fsid /* file system id */
uint64 f_flag /* bit mask of f_flag values */
uint64 f_namemax /* maximum filename length */
The values of the f_flag bitmask are as follows:
#define SSH_FXE_STATVFS_ST_RDONLY 0x1 /* read-only */
#define SSH_FXE_STATVFS_ST_NOSUID 0x2 /* no setuid */
Both the "statvfs@openssh.com" and "fstatvfs@openssh.com" extensions are
advertised in the SSH_FXP_VERSION hello with version "2".
4.5. sftp: Extension request "hardlink@openssh.com"
This request is for creating a hard link to a regular file. This
request is implemented as a SSH_FXP_EXTENDED request with the
following format:
uint32 id
string "hardlink@openssh.com"
string oldpath
string newpath
On receiving this request the server will perform the operation
link(oldpath, newpath) and will respond with a SSH_FXP_STATUS message.
This extension is advertised in the SSH_FXP_VERSION hello with version
"1".
4.6. sftp: Extension request "fsync@openssh.com"
This request asks the server to call fsync(2) on an open file handle.
uint32 id
string "fsync@openssh.com"
string handle
On receiving this request, a server will call fsync(handle_fd) and will
respond with a SSH_FXP_STATUS message.
This extension is advertised in the SSH_FXP_VERSION hello with version
"1".
4.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".
4.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".
4.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.10. sftp: Extension request "copy-data"
This request asks the server to copy data from one open file handle and
write it to a different open file handle. This avoids needing to transfer
the data across the network twice (a download followed by an upload).
byte SSH_FXP_EXTENDED
uint32 id
string "copy-data"
string read-from-handle
uint64 read-from-offset
uint64 read-data-length
string write-to-handle
uint64 write-to-offset
The server will copy read-data-length bytes starting from
read-from-offset from the read-from-handle and write them to
write-to-handle starting from write-to-offset, and then respond with a
SSH_FXP_STATUS message.
It's equivalent to issuing a series of SSH_FXP_READ requests on
read-from-handle and a series of requests of SSH_FXP_WRITE on
write-to-handle.
If read-from-handle and write-to-handle are the same, the server will
fail the request and respond with a SSH_FX_INVALID_PARAMETER message.
If read-data-length is 0, then the server will read data from the
read-from-handle until EOF is reached.
This extension is advertised in the SSH_FXP_VERSION hello with version
"1".
This request is identical to the "copy-data" request documented in:
https://tools.ietf.org/html/draft-ietf-secsh-filexfer-extensions-00#section-7
4.11. sftp: Extension request "home-directory"
This request asks the server to expand the specified user's home directory.
An empty username implies the current user. This can be used by the client
to expand ~/ type paths locally.
byte SSH_FXP_EXTENDED
uint32 id
string "home-directory"
string username
This extension is advertised in the SSH_FXP_VERSION hello with version
"1".
This provides similar information as the "expand-path@openssh.com" extension.
This request is identical to the "home-directory" request documented in:
https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-extensions-00#section-5
4.12. sftp: Extension request "users-groups-by-id@openssh.com"
-This request asks the server to returns user and/or group names that
+This request asks the server to return user and/or group names that
correspond to one or more IDs (e.g. as returned from a SSH_FXP_STAT
request). This may be used by the client to provide usernames in
directory listings.
byte SSH_FXP_EXTENDED
uint32 id
string "users-groups-by-id@openssh.com"
string uids
string gids
Where "uids" and "gids" consists of one or more integer user or group
identifiers:
uint32 id-0
...
The server will reply with a SSH_FXP_EXTENDED_REPLY:
byte SSH_FXP_EXTENDED_REPLY
string usernames
string groupnames
Where "username" and "groupnames" consists of names in identical request
order to "uids" and "gids" respectively:
string name-0
...
If a name cannot be identified for a given user or group ID, an empty
string will be returned in its place.
It is acceptable for either "uids" or "gids" to be an empty set, in
which case the respective "usernames" or "groupnames" list will also
be empty.
This extension is advertised in the SSH_FXP_VERSION hello with version
"1".
5. Miscellaneous changes
5.1 Public key format
OpenSSH public keys, as generated by ssh-keygen(1) and appearing in
authorized_keys files, are formatted as a single line of text consisting
of the public key algorithm name followed by a base64-encoded key blob.
The public key blob (before base64 encoding) is the same format used for
the encoding of public keys sent on the wire: as described in RFC4253
section 6.6 for RSA and DSA keys, RFC5656 section 3.1 for ECDSA keys
and the "New public key formats" section of PROTOCOL.certkeys for the
OpenSSH certificate formats.
5.2 Private key format
OpenSSH private keys, as generated by ssh-keygen(1) use the format
described in PROTOCOL.key by default. As a legacy option, PEM format
(RFC7468) private keys are also supported for RSA, DSA and ECDSA keys
and were the default format before OpenSSH 7.8.
5.3 KRL format
OpenSSH supports a compact format for Key Revocation Lists (KRLs). This
format is described in the PROTOCOL.krl file.
5.4 Connection multiplexing
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.
5.5. Agent protocol extensions
OpenSSH extends the usual agent protocol. These changes are documented
in the PROTOCOL.agent file.
-$OpenBSD: PROTOCOL,v 1.47 2022/09/19 10:40:52 djm Exp $
+$OpenBSD: PROTOCOL,v 1.48 2022/11/07 01:53:01 dtucker Exp $
diff --git a/crypto/openssh/README b/crypto/openssh/README
index 0d3416f573c5..89bcddd9e4fc 100644
--- a/crypto/openssh/README
+++ b/crypto/openssh/README
@@ -1,52 +1,52 @@
-See https://www.openssh.com/releasenotes.html#9.1p1 for the release notes.
+See https://www.openssh.com/releasenotes.html#9.2p1 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
patch/pull-request management.
This is the port of OpenBSD's excellent OpenSSH[0] to Linux and other
Unices.
OpenSSH is based on the last free version of Tatu Ylonen's sample
implementation with all patent-encumbered algorithms removed (to
external libraries), all known security bugs fixed, new features
reintroduced and many other clean-ups. OpenSSH has been created by
Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, Theo de Raadt,
and Dug Song. It has a homepage at https://www.openssh.com/
This port consists of the re-introduction of autoconf support, PAM
support, EGD/PRNGD support and replacements for OpenBSD library
functions that are (regrettably) absent from other unices. This port
has been best tested on AIX, Cygwin, HP-UX, Linux, MacOS/X,
FreeBSD, NetBSD, OpenBSD, OpenServer, Solaris and UnixWare.
This version actively tracks changes in the OpenBSD CVS repository.
The PAM support is now more functional than the popular packages of
commercial ssh-1.2.x. It checks "account" and "session" modules for
all logins, not just when using password authentication.
There is now several mailing lists for this port of OpenSSH. Please
refer to https://www.openssh.com/list.html for details on how to join.
Please send bug reports and patches to https://bugzilla.mindrot.org or
the mailing list openssh-unix-dev@mindrot.org. To mitigate spam, the
list only allows posting from subscribed addresses. Code contribution
are welcomed, but please follow the OpenBSD style guidelines[1].
Please refer to the INSTALL document for information on dependencies and
how to install OpenSSH on your system.
Damien Miller <djm@mindrot.org>
Miscellania -
This version of OpenSSH is based upon code retrieved from the OpenBSD CVS
repository which in turn was based on the last free sample implementation
released by Tatu Ylonen.
References -
[0] https://www.openssh.com/
[1] https://man.openbsd.org/style.9
diff --git a/crypto/openssh/README.md b/crypto/openssh/README.md
index 04e3a5198a91..3da933817989 100644
--- a/crypto/openssh/README.md
+++ b/crypto/openssh/README.md
@@ -1,86 +1,85 @@
# Portable OpenSSH
[![C/C++ CI](https://github.com/openssh/openssh-portable/actions/workflows/c-cpp.yml/badge.svg)](https://github.com/openssh/openssh-portable/actions/workflows/c-cpp.yml)
[![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/openssh.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:openssh)
OpenSSH is a complete implementation of the SSH protocol (version 2) for secure remote login, command execution and file transfer. It includes a client ``ssh`` and server ``sshd``, file transfer utilities ``scp`` and ``sftp`` as well as tools for key generation (``ssh-keygen``), run-time key storage (``ssh-agent``) and a number of supporting programs.
This is a port of OpenBSD's [OpenSSH](https://openssh.com) to most Unix-like operating systems, including Linux, OS X and Cygwin. Portable OpenSSH polyfills OpenBSD APIs that are not available elsewhere, adds sshd sandboxing for more operating systems and includes support for OS-native authentication and auditing (e.g. using PAM).
## Documentation
The official documentation for OpenSSH are the man pages for each tool:
* [ssh(1)](https://man.openbsd.org/ssh.1)
* [sshd(8)](https://man.openbsd.org/sshd.8)
* [ssh-keygen(1)](https://man.openbsd.org/ssh-keygen.1)
* [ssh-agent(1)](https://man.openbsd.org/ssh-agent.1)
* [scp(1)](https://man.openbsd.org/scp.1)
* [sftp(1)](https://man.openbsd.org/sftp.1)
* [ssh-keyscan(8)](https://man.openbsd.org/ssh-keyscan.8)
* [sftp-server(8)](https://man.openbsd.org/sftp-server.8)
## Stable Releases
Stable release tarballs are available from a number of [download mirrors](https://www.openssh.com/portable.html#downloads). We recommend the use of a stable release for most users. Please read the [release notes](https://www.openssh.com/releasenotes.html) for details of recent changes and potential incompatibilities.
## Building Portable OpenSSH
### Dependencies
Portable OpenSSH is built using autoconf and make. It requires a working C compiler, standard library and headers.
``libcrypto`` from either [LibreSSL](https://www.libressl.org/) or [OpenSSL](https://www.openssl.org) may also be used. OpenSSH may be built without either of these, but the resulting binaries will have only a subset of the cryptographic algorithms normally available.
[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.
+FIDO security token support needs [libfido2](https://github.com/Yubico/libfido2) and its dependencies and will be enabled automatically if they are found.
In addition, certain platforms and build-time options may require additional dependencies; see README.platform for details about your platform.
### Building a release
Releases include a pre-built copy of the ``configure`` script and may be built using:
```
tar zxvf openssh-X.YpZ.tar.gz
cd openssh
./configure # [options]
make && make tests
```
See the [Build-time Customisation](#build-time-customisation) section below for configure options. If you plan on installing OpenSSH to your system, then you will usually want to specify destination paths.
### Building from git
If building from git, you'll need [autoconf](https://www.gnu.org/software/autoconf/) installed to build the ``configure`` script. The following commands will check out and build portable OpenSSH from git:
```
git clone https://github.com/openssh/openssh-portable # or https://anongit.mindrot.org/openssh.git
cd openssh-portable
autoreconf
./configure
make && make tests
```
### Build-time Customisation
There are many build-time customisation options available. All Autoconf destination path flags (e.g. ``--prefix``) are supported (and are usually required if you want to install OpenSSH).
For a full list of available flags, run ``./configure --help`` but a few of the more frequently-used ones are described below. Some of these flags will require additional libraries and/or headers be installed.
Flag | Meaning
--- | ---
``--with-pam`` | Enable [PAM](https://en.wikipedia.org/wiki/Pluggable_authentication_module) support. [OpenPAM](https://www.openpam.org/), [Linux PAM](http://www.linux-pam.org/) and Solaris PAM are supported.
``--with-libedit`` | Enable [libedit](https://www.thrysoee.dk/editline/) support for sftp.
``--with-kerberos5`` | Enable Kerberos/GSSAPI support. Both [Heimdal](https://www.h5l.org/) and [MIT](https://web.mit.edu/kerberos/) Kerberos implementations are supported.
``--with-selinux`` | Enable [SELinux](https://en.wikipedia.org/wiki/Security-Enhanced_Linux) support.
-``--with-security-key-builtin`` | Include built-in support for U2F/FIDO2 security keys. This requires [libfido2](https://github.com/Yubico/libfido2) be installed.
## Development
Portable OpenSSH development is discussed on the [openssh-unix-dev mailing list](https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev) ([archive mirror](https://marc.info/?l=openssh-unix-dev)). Bugs and feature requests are tracked on our [Bugzilla](https://bugzilla.mindrot.org/).
## Reporting bugs
_Non-security_ bugs may be reported to the developers via [Bugzilla](https://bugzilla.mindrot.org/) or via the mailing list above. Security bugs should be reported to [openssh@openssh.com](mailto:openssh.openssh.com).
diff --git a/crypto/openssh/aclocal.m4 b/crypto/openssh/aclocal.m4
index 9d85d34d4772..5a19d278477f 100644
--- a/crypto/openssh/aclocal.m4
+++ b/crypto/openssh/aclocal.m4
@@ -1,15 +1,15 @@
-# generated automatically by aclocal 1.16.3 -*- Autoconf -*-
+# generated automatically by aclocal 1.16.5 -*- Autoconf -*-
-# Copyright (C) 1996-2020 Free Software Foundation, Inc.
+# Copyright (C) 1996-2021 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
m4_include([m4/openssh.m4])
diff --git a/crypto/openssh/addr.c b/crypto/openssh/addr.c
index abf3e3d97818..db9ab7ac1d8d 100644
--- a/crypto/openssh/addr.c
+++ b/crypto/openssh/addr.c
@@ -1,435 +1,506 @@
-/* $OpenBSD: addr.c,v 1.5 2022/04/29 04:55:07 djm Exp $ */
+/* $OpenBSD: addr.c,v 1.6 2022/10/28 02:29:34 djm 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_or(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:
+ 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;
}
}
+/* Increment the specified address. Note, does not do overflow checking */
+void
+addr_increment(struct xaddr *a)
+{
+ int i;
+ uint32_t n;
+
+ switch (a->af) {
+ case AF_INET:
+ a->v4.s_addr = htonl(ntohl(a->v4.s_addr) + 1);
+ break;
+ case AF_INET6:
+ for (i = 0; i < 4; i++) {
+ /* Increment with carry */
+ n = ntohl(a->addr32[3 - i]) + 1;
+ a->addr32[3 - i] = htonl(n);
+ if (n != 0)
+ break;
+ }
+ break;
+ }
+}
+
/*
* Test whether host portion of address 'a', as determined by 'masklen'
* is all zeros.
* Returns 0 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);
}
+#if 0
+int
+addr_host_to_all0s(struct xaddr *a, u_int masklen)
+{
+ struct xaddr tmp_mask;
+
+ if (addr_netmask(a->af, masklen, &tmp_mask) == -1)
+ return (-1);
+ if (addr_and(a, a, &tmp_mask) == -1)
+ return (-1);
+ return (0);
+}
+#endif
+
+int
+addr_host_to_all1s(struct xaddr *a, u_int masklen)
+{
+ struct xaddr tmp_mask;
+
+ if (addr_hostmask(a->af, masklen, &tmp_mask) == -1)
+ return (-1);
+ if (addr_or(a, a, &tmp_mask) == -1)
+ return (-1);
+ return (0);
+}
+
/*
* 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)
return -1;
if (ai->ai_addr == NULL) {
freeaddrinfo(ai);
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)
return -1;
if (ai->ai_addr == NULL) {
freeaddrinfo(ai);
return -1;
}
if (sa != NULL) {
if (slen < ai->ai_addrlen) {
freeaddrinfo(ai);
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 (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' || *mp > '9' || *cp != '\0' || masklen > 128)
return -1;
}
if (addr_pton(addrbuf, &tmp) == -1)
return -1;
if (mp == NULL)
masklen = addr_unicast_masklen(tmp.af);
if (masklen_valid(tmp.af, masklen) == -1)
return -2;
if (addr_host_is_all0s(&tmp, masklen) != 0)
return -2;
if (n != NULL)
memcpy(n, &tmp, sizeof(*n));
if (l != NULL)
*l = masklen;
return 0;
}
int
addr_netmatch(const struct xaddr *host, const struct xaddr *net, u_int masklen)
{
struct xaddr tmp_mask, tmp_result;
if (host->af != net->af)
return -1;
if (addr_netmask(host->af, masklen, &tmp_mask) == -1)
return -1;
if (addr_and(&tmp_result, host, &tmp_mask) == -1)
return -1;
return addr_cmp(&tmp_result, net);
}
diff --git a/crypto/openssh/addr.h b/crypto/openssh/addr.h
index 5eff02628592..180e9fdc6449 100644
--- a/crypto/openssh/addr.h
+++ b/crypto/openssh/addr.h
@@ -1,60 +1,64 @@
/*
* 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_or(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_host_to_all0s(struct xaddr *a, u_int masklen);
+int addr_host_to_all1s(struct xaddr *a, u_int masklen);
int addr_netmatch(const struct xaddr *host, const struct xaddr *net,
u_int masklen);
+void addr_increment(struct xaddr *a);
#endif /* _ADDR_H */
diff --git a/crypto/openssh/auth-pam.c b/crypto/openssh/auth-pam.c
index 81c19fb7c458..008466f7bd82 100644
--- a/crypto/openssh/auth-pam.c
+++ b/crypto/openssh/auth-pam.c
@@ -1,1400 +1,1406 @@
/*-
* Copyright (c) 2002 Networks Associates Technology, Inc.
* All rights reserved.
*
* This software was developed for the FreeBSD Project by ThinkSec AS and
* NAI Labs, the Security Research Division of Network Associates, Inc.
* under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the
* DARPA CHATS research program.
*
* 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 AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* Copyright (c) 2003,2004 Damien Miller <djm@mindrot.org>
* Copyright (c) 2003,2004 Darren Tucker <dtucker@zip.com.au>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* Based on FreeBSD: src/crypto/openssh/auth2-pam-freebsd.c,v 1.11 2003/03/31 13:48:18 des */
#include "includes.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <errno.h>
#include <signal.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#ifdef USE_PAM
#if defined(HAVE_SECURITY_PAM_APPL_H)
#include <security/pam_appl.h>
#elif defined (HAVE_PAM_PAM_APPL_H)
#include <pam/pam_appl.h>
#endif
#if !defined(SSHD_PAM_SERVICE)
extern char *__progname;
# define SSHD_PAM_SERVICE __progname
#endif
/* OpenGroup RFC86.0 and XSSO specify no "const" on arguments */
#ifdef PAM_SUN_CODEBASE
# define sshpam_const /* Solaris, HP-UX, SunOS */
#else
# define sshpam_const const /* LinuxPAM, OpenPAM, AIX */
#endif
/* Ambiguity in spec: is it an array of pointers or a pointer to an array? */
#ifdef PAM_SUN_CODEBASE
# define PAM_MSG_MEMBER(msg, n, member) ((*(msg))[(n)].member)
#else
# define PAM_MSG_MEMBER(msg, n, member) ((msg)[(n)]->member)
#endif
#include "xmalloc.h"
#include "sshbuf.h"
#include "ssherr.h"
#include "hostfile.h"
#include "auth.h"
#include "auth-pam.h"
#include "canohost.h"
#include "log.h"
#include "msg.h"
#include "packet.h"
#include "misc.h"
#include "servconf.h"
#include "ssh2.h"
#include "auth-options.h"
#include "misc.h"
#ifdef GSSAPI
#include "ssh-gss.h"
#endif
#include "monitor_wrap.h"
#include "blacklist_client.h"
extern ServerOptions options;
extern struct sshbuf *loginmsg;
extern u_int utmp_len;
/* so we don't silently change behaviour */
#ifdef USE_POSIX_THREADS
# error "USE_POSIX_THREADS replaced by UNSUPPORTED_POSIX_THREADS_HACK"
#endif
/*
* Formerly known as USE_POSIX_THREADS, using this is completely unsupported
* and generally a bad idea. Use at own risk and do not expect support if
* this breaks.
*/
#ifdef UNSUPPORTED_POSIX_THREADS_HACK
#include <pthread.h>
/*
* Avoid namespace clash when *not* using pthreads for systems *with*
* pthreads, which unconditionally define pthread_t via sys/types.h
* (e.g. Linux)
*/
typedef pthread_t sp_pthread_t;
#else
typedef pid_t sp_pthread_t;
#define pthread_exit fake_pthread_exit
#define pthread_create fake_pthread_create
#define pthread_cancel fake_pthread_cancel
#define pthread_join fake_pthread_join
#endif
struct pam_ctxt {
sp_pthread_t pam_thread;
int pam_psock;
int pam_csock;
int pam_done;
};
static void sshpam_free_ctx(void *);
static struct pam_ctxt *cleanup_ctxt;
#ifndef UNSUPPORTED_POSIX_THREADS_HACK
/*
* Simulate threads with processes.
*/
static int sshpam_thread_status = -1;
static sshsig_t sshpam_oldsig;
static void
sshpam_sigchld_handler(int sig)
{
ssh_signal(SIGCHLD, SIG_DFL);
if (cleanup_ctxt == NULL)
return; /* handler called after PAM cleanup, shouldn't happen */
if (waitpid(cleanup_ctxt->pam_thread, &sshpam_thread_status, WNOHANG)
<= 0) {
/* PAM thread has not exitted, privsep slave must have */
kill(cleanup_ctxt->pam_thread, SIGTERM);
while (waitpid(cleanup_ctxt->pam_thread,
&sshpam_thread_status, 0) == -1) {
if (errno == EINTR)
continue;
return;
}
}
if (WIFSIGNALED(sshpam_thread_status) &&
WTERMSIG(sshpam_thread_status) == SIGTERM)
return; /* terminated by pthread_cancel */
if (!WIFEXITED(sshpam_thread_status))
sigdie("PAM: authentication thread exited unexpectedly");
if (WEXITSTATUS(sshpam_thread_status) != 0)
sigdie("PAM: authentication thread exited uncleanly");
}
/* ARGSUSED */
static void
pthread_exit(void *value)
{
_exit(0);
}
/* ARGSUSED */
static int
pthread_create(sp_pthread_t *thread, const void *attr,
void *(*thread_start)(void *), void *arg)
{
pid_t pid;
struct pam_ctxt *ctx = arg;
sshpam_thread_status = -1;
switch ((pid = fork())) {
case -1:
error("fork(): %s", strerror(errno));
return errno;
case 0:
close(ctx->pam_psock);
ctx->pam_psock = -1;
thread_start(arg);
_exit(1);
default:
*thread = pid;
close(ctx->pam_csock);
ctx->pam_csock = -1;
sshpam_oldsig = ssh_signal(SIGCHLD, sshpam_sigchld_handler);
return (0);
}
}
static int
pthread_cancel(sp_pthread_t thread)
{
ssh_signal(SIGCHLD, sshpam_oldsig);
return (kill(thread, SIGTERM));
}
/* ARGSUSED */
static int
pthread_join(sp_pthread_t thread, void **value)
{
int status;
if (sshpam_thread_status != -1)
return (sshpam_thread_status);
ssh_signal(SIGCHLD, sshpam_oldsig);
while (waitpid(thread, &status, 0) == -1) {
if (errno == EINTR)
continue;
fatal("%s: waitpid: %s", __func__, strerror(errno));
}
return (status);
}
#endif
static pam_handle_t *sshpam_handle = NULL;
static int sshpam_err = 0;
static int sshpam_authenticated = 0;
static int sshpam_session_open = 0;
static int sshpam_cred_established = 0;
static int sshpam_account_status = -1;
static int sshpam_maxtries_reached = 0;
static char **sshpam_env = NULL;
static Authctxt *sshpam_authctxt = NULL;
static const char *sshpam_password = NULL;
static char *sshpam_rhost = NULL;
static char *sshpam_laddr = NULL;
-static char *sshpam_conninfo = NULL;
/* Some PAM implementations don't implement this */
#ifndef HAVE_PAM_GETENVLIST
static char **
pam_getenvlist(pam_handle_t *pamh)
{
/*
* XXX - If necessary, we can still support environment passing
* for platforms without pam_getenvlist by searching for known
* env vars (e.g. KRB5CCNAME) from the PAM environment.
*/
return NULL;
}
#endif
#ifndef HAVE_PAM_PUTENV
static int
pam_putenv(pam_handle_t *pamh, const char *name_value)
{
return PAM_SUCCESS;
}
#endif /* HAVE_PAM_PUTENV */
/*
* Some platforms, notably Solaris, do not enforce password complexity
* rules during pam_chauthtok() if the real uid of the calling process
* is 0, on the assumption that it's being called by "passwd" run by root.
* This wraps pam_chauthtok and sets/restore the real uid so PAM will do
* the right thing.
*/
#ifdef SSHPAM_CHAUTHTOK_NEEDS_RUID
static int
sshpam_chauthtok_ruid(pam_handle_t *pamh, int flags)
{
int result;
if (sshpam_authctxt == NULL)
fatal("PAM: sshpam_authctxt not initialized");
if (setreuid(sshpam_authctxt->pw->pw_uid, -1) == -1)
fatal("%s: setreuid failed: %s", __func__, strerror(errno));
result = pam_chauthtok(pamh, flags);
if (setreuid(0, -1) == -1)
fatal("%s: setreuid failed: %s", __func__, strerror(errno));
return result;
}
# define pam_chauthtok(a,b) (sshpam_chauthtok_ruid((a), (b)))
#endif
static void
sshpam_password_change_required(int reqd)
{
extern struct sshauthopt *auth_opts;
static int saved_port, saved_agent, saved_x11;
debug3("%s %d", __func__, reqd);
if (sshpam_authctxt == NULL)
fatal("%s: PAM authctxt not initialized", __func__);
sshpam_authctxt->force_pwchange = reqd;
if (reqd) {
saved_port = auth_opts->permit_port_forwarding_flag;
saved_agent = auth_opts->permit_agent_forwarding_flag;
saved_x11 = auth_opts->permit_x11_forwarding_flag;
auth_opts->permit_port_forwarding_flag = 0;
auth_opts->permit_agent_forwarding_flag = 0;
auth_opts->permit_x11_forwarding_flag = 0;
} else {
if (saved_port)
auth_opts->permit_port_forwarding_flag = saved_port;
if (saved_agent)
auth_opts->permit_agent_forwarding_flag = saved_agent;
if (saved_x11)
auth_opts->permit_x11_forwarding_flag = saved_x11;
}
}
/* Import regular and PAM environment from subprocess */
static void
import_environments(struct sshbuf *b)
{
char *env;
u_int n, i, num_env;
int r;
debug3("PAM: %s entering", __func__);
#ifndef UNSUPPORTED_POSIX_THREADS_HACK
/* Import variables set by do_pam_account */
if ((r = sshbuf_get_u32(b, &n)) != 0)
fatal("%s: buffer error: %s", __func__, ssh_err(r));
if (n > INT_MAX)
fatal("%s: invalid PAM account status %u", __func__, n);
sshpam_account_status = (int)n;
if ((r = sshbuf_get_u32(b, &n)) != 0)
fatal("%s: buffer error: %s", __func__, ssh_err(r));
sshpam_password_change_required(n != 0);
/* Import environment from subprocess */
if ((r = sshbuf_get_u32(b, &num_env)) != 0)
fatal("%s: buffer error: %s", __func__, ssh_err(r));
if (num_env > 1024)
fatal("%s: received %u environment variables, expected <= 1024",
__func__, num_env);
sshpam_env = xcalloc(num_env + 1, sizeof(*sshpam_env));
debug3("PAM: num env strings %d", num_env);
for(i = 0; i < num_env; i++) {
if ((r = sshbuf_get_cstring(b, &(sshpam_env[i]), NULL)) != 0)
fatal("%s: buffer error: %s", __func__, ssh_err(r));
}
sshpam_env[num_env] = NULL;
/* Import PAM environment from subprocess */
if ((r = sshbuf_get_u32(b, &num_env)) != 0)
fatal("%s: buffer error: %s", __func__, ssh_err(r));
debug("PAM: num PAM env strings %d", num_env);
for (i = 0; i < num_env; i++) {
if ((r = sshbuf_get_cstring(b, &env, NULL)) != 0)
fatal("%s: buffer error: %s", __func__, ssh_err(r));
/* Errors are not fatal here */
if ((r = pam_putenv(sshpam_handle, env)) != PAM_SUCCESS) {
error("PAM: pam_putenv: %s",
pam_strerror(sshpam_handle, r));
}
/*
* XXX this possibly leaks env because it is not documented
* what pam_putenv() does with it. Does it copy it? Does it
* take ownweship? We don't know, so it's safest just to leak.
*/
}
#endif
}
/*
* Conversation function for authentication thread.
*/
static int
sshpam_thread_conv(int n, sshpam_const struct pam_message **msg,
struct pam_response **resp, void *data)
{
struct sshbuf *buffer;
struct pam_ctxt *ctxt;
struct pam_response *reply;
int r, i;
u_char status;
debug3("PAM: %s entering, %d messages", __func__, n);
*resp = NULL;
if (data == NULL) {
error("PAM: conversation function passed a null context");
return (PAM_CONV_ERR);
}
ctxt = data;
if (n <= 0 || n > PAM_MAX_NUM_MSG)
return (PAM_CONV_ERR);
if ((reply = calloc(n, sizeof(*reply))) == NULL)
return PAM_CONV_ERR;
if ((buffer = sshbuf_new()) == NULL) {
free(reply);
return PAM_CONV_ERR;
}
for (i = 0; i < n; ++i) {
switch (PAM_MSG_MEMBER(msg, i, msg_style)) {
case PAM_PROMPT_ECHO_OFF:
case PAM_PROMPT_ECHO_ON:
if ((r = sshbuf_put_cstring(buffer,
PAM_MSG_MEMBER(msg, i, msg))) != 0)
fatal("%s: buffer error: %s",
__func__, ssh_err(r));
if (ssh_msg_send(ctxt->pam_csock,
PAM_MSG_MEMBER(msg, i, msg_style), buffer) == -1)
goto fail;
if (ssh_msg_recv(ctxt->pam_csock, buffer) == -1)
goto fail;
if ((r = sshbuf_get_u8(buffer, &status)) != 0)
fatal("%s: buffer error: %s",
__func__, ssh_err(r));
if (status != PAM_AUTHTOK)
goto fail;
if ((r = sshbuf_get_cstring(buffer,
&reply[i].resp, NULL)) != 0)
fatal("%s: buffer error: %s",
__func__, ssh_err(r));
break;
case PAM_ERROR_MSG:
case PAM_TEXT_INFO:
if ((r = sshbuf_put_cstring(buffer,
PAM_MSG_MEMBER(msg, i, msg))) != 0)
fatal("%s: buffer error: %s",
__func__, ssh_err(r));
if (ssh_msg_send(ctxt->pam_csock,
PAM_MSG_MEMBER(msg, i, msg_style), buffer) == -1)
goto fail;
break;
default:
goto fail;
}
sshbuf_reset(buffer);
}
sshbuf_free(buffer);
*resp = reply;
return (PAM_SUCCESS);
fail:
for(i = 0; i < n; i++) {
free(reply[i].resp);
}
free(reply);
sshbuf_free(buffer);
return (PAM_CONV_ERR);
}
/*
* Authentication thread.
*/
static void *
sshpam_thread(void *ctxtp)
{
struct pam_ctxt *ctxt = ctxtp;
struct sshbuf *buffer = NULL;
struct pam_conv sshpam_conv;
int r, flags = (options.permit_empty_passwd == 0 ?
PAM_DISALLOW_NULL_AUTHTOK : 0);
#ifndef UNSUPPORTED_POSIX_THREADS_HACK
extern char **environ;
char **env_from_pam;
u_int i;
const char *pam_user;
const char **ptr_pam_user = &pam_user;
char *tz = getenv("TZ");
sshpam_err = pam_get_item(sshpam_handle, PAM_USER,
(sshpam_const void **)ptr_pam_user);
if (sshpam_err != PAM_SUCCESS)
goto auth_fail;
environ[0] = NULL;
if (tz != NULL)
if (setenv("TZ", tz, 1) == -1)
error("PAM: could not set TZ environment: %s",
strerror(errno));
if (sshpam_authctxt != NULL) {
setproctitle("%s [pam]",
sshpam_authctxt->valid ? pam_user : "unknown");
}
#endif
sshpam_conv.conv = sshpam_thread_conv;
sshpam_conv.appdata_ptr = ctxt;
if (sshpam_authctxt == NULL)
fatal("%s: PAM authctxt not initialized", __func__);
if ((buffer = sshbuf_new()) == NULL)
fatal("%s: sshbuf_new failed", __func__);
sshpam_err = pam_set_item(sshpam_handle, PAM_CONV,
(const void *)&sshpam_conv);
if (sshpam_err != PAM_SUCCESS)
goto auth_fail;
sshpam_err = pam_authenticate(sshpam_handle, flags);
if (sshpam_err == PAM_MAXTRIES)
sshpam_set_maxtries_reached(1);
if (sshpam_err != PAM_SUCCESS)
goto auth_fail;
if (!do_pam_account()) {
sshpam_err = PAM_ACCT_EXPIRED;
goto auth_fail;
}
if (sshpam_authctxt->force_pwchange) {
sshpam_err = pam_chauthtok(sshpam_handle,
PAM_CHANGE_EXPIRED_AUTHTOK);
if (sshpam_err != PAM_SUCCESS)
goto auth_fail;
sshpam_password_change_required(0);
}
if ((r = sshbuf_put_cstring(buffer, "OK")) != 0)
fatal("%s: buffer error: %s", __func__, ssh_err(r));
#ifndef UNSUPPORTED_POSIX_THREADS_HACK
/* Export variables set by do_pam_account */
if ((r = sshbuf_put_u32(buffer, sshpam_account_status)) != 0 ||
(r = sshbuf_put_u32(buffer, sshpam_authctxt->force_pwchange)) != 0)
fatal("%s: buffer error: %s", __func__, ssh_err(r));
/* Export any environment strings set in child */
for (i = 0; environ[i] != NULL; i++) {
/* Count */
if (i > INT_MAX)
fatal("%s: too many environment strings", __func__);
}
if ((r = sshbuf_put_u32(buffer, i)) != 0)
fatal("%s: buffer error: %s", __func__, ssh_err(r));
for (i = 0; environ[i] != NULL; i++) {
if ((r = sshbuf_put_cstring(buffer, environ[i])) != 0)
fatal("%s: buffer error: %s", __func__, ssh_err(r));
}
/* Export any environment strings set by PAM in child */
env_from_pam = pam_getenvlist(sshpam_handle);
for (i = 0; env_from_pam != NULL && env_from_pam[i] != NULL; i++) {
/* Count */
if (i > INT_MAX)
fatal("%s: too many PAM environment strings", __func__);
}
if ((r = sshbuf_put_u32(buffer, i)) != 0)
fatal("%s: buffer error: %s", __func__, ssh_err(r));
for (i = 0; env_from_pam != NULL && env_from_pam[i] != NULL; i++) {
if ((r = sshbuf_put_cstring(buffer, env_from_pam[i])) != 0)
fatal("%s: buffer error: %s", __func__, ssh_err(r));
}
#endif /* UNSUPPORTED_POSIX_THREADS_HACK */
/* XXX - can't do much about an error here */
ssh_msg_send(ctxt->pam_csock, sshpam_err, buffer);
sshbuf_free(buffer);
pthread_exit(NULL);
auth_fail:
if ((r = sshbuf_put_cstring(buffer,
pam_strerror(sshpam_handle, sshpam_err))) != 0)
fatal("%s: buffer error: %s", __func__, ssh_err(r));
/* XXX - can't do much about an error here */
if (sshpam_err == PAM_ACCT_EXPIRED)
ssh_msg_send(ctxt->pam_csock, PAM_ACCT_EXPIRED, buffer);
else if (sshpam_maxtries_reached)
ssh_msg_send(ctxt->pam_csock, PAM_MAXTRIES, buffer);
else
ssh_msg_send(ctxt->pam_csock, PAM_AUTH_ERR, buffer);
sshbuf_free(buffer);
pthread_exit(NULL);
return (NULL); /* Avoid warning for non-pthread case */
}
void
sshpam_thread_cleanup(void)
{
struct pam_ctxt *ctxt = cleanup_ctxt;
debug3("PAM: %s entering", __func__);
if (ctxt != NULL && ctxt->pam_thread != 0) {
pthread_cancel(ctxt->pam_thread);
pthread_join(ctxt->pam_thread, NULL);
close(ctxt->pam_psock);
close(ctxt->pam_csock);
memset(ctxt, 0, sizeof(*ctxt));
cleanup_ctxt = NULL;
}
}
static int
sshpam_null_conv(int n, sshpam_const struct pam_message **msg,
struct pam_response **resp, void *data)
{
debug3("PAM: %s entering, %d messages", __func__, n);
return (PAM_CONV_ERR);
}
static struct pam_conv null_conv = { sshpam_null_conv, NULL };
static int
sshpam_store_conv(int n, sshpam_const struct pam_message **msg,
struct pam_response **resp, void *data)
{
struct pam_response *reply;
int r, i;
debug3("PAM: %s called with %d messages", __func__, n);
*resp = NULL;
if (n <= 0 || n > PAM_MAX_NUM_MSG)
return (PAM_CONV_ERR);
if ((reply = calloc(n, sizeof(*reply))) == NULL)
return (PAM_CONV_ERR);
for (i = 0; i < n; ++i) {
switch (PAM_MSG_MEMBER(msg, i, msg_style)) {
case PAM_ERROR_MSG:
case PAM_TEXT_INFO:
if ((r = sshbuf_putf(loginmsg, "%s\n",
PAM_MSG_MEMBER(msg, i, msg))) != 0)
fatal("%s: buffer error: %s",
__func__, ssh_err(r));
reply[i].resp_retcode = PAM_SUCCESS;
break;
default:
goto fail;
}
}
*resp = reply;
return (PAM_SUCCESS);
fail:
for(i = 0; i < n; i++) {
free(reply[i].resp);
}
free(reply);
return (PAM_CONV_ERR);
}
static struct pam_conv store_conv = { sshpam_store_conv, NULL };
void
sshpam_cleanup(void)
{
if (sshpam_handle == NULL || (use_privsep && !mm_is_monitor()))
return;
debug("PAM: cleanup");
pam_set_item(sshpam_handle, PAM_CONV, (const void *)&null_conv);
if (sshpam_session_open) {
debug("PAM: closing session");
pam_close_session(sshpam_handle, PAM_SILENT);
sshpam_session_open = 0;
}
if (sshpam_cred_established) {
debug("PAM: deleting credentials");
pam_setcred(sshpam_handle, PAM_DELETE_CRED);
sshpam_cred_established = 0;
}
sshpam_authenticated = 0;
pam_end(sshpam_handle, sshpam_err);
sshpam_handle = NULL;
}
static int
sshpam_init(struct ssh *ssh, Authctxt *authctxt)
{
const char *pam_user, *user = authctxt->user;
const char **ptr_pam_user = &pam_user;
+ int r;
#if defined(PAM_SUN_CODEBASE) && defined(PAM_MAX_RESP_SIZE)
/* Protect buggy PAM implementations from excessively long usernames */
if (strlen(user) >= PAM_MAX_RESP_SIZE)
fatal("Username too long from %s port %d",
ssh_remote_ipaddr(ssh), ssh_remote_port(ssh));
#endif
if (sshpam_handle == NULL) {
if (ssh == NULL) {
fatal("%s: called initially with no "
"packet context", __func__);
}
} if (sshpam_handle != NULL) {
/* We already have a PAM context; check if the user matches */
sshpam_err = pam_get_item(sshpam_handle,
PAM_USER, (sshpam_const void **)ptr_pam_user);
if (sshpam_err == PAM_SUCCESS && strcmp(user, pam_user) == 0)
return (0);
pam_end(sshpam_handle, sshpam_err);
sshpam_handle = NULL;
}
debug("PAM: initializing for \"%s\"", user);
sshpam_err =
pam_start(SSHD_PAM_SERVICE, user, &store_conv, &sshpam_handle);
sshpam_authctxt = authctxt;
if (sshpam_err != PAM_SUCCESS) {
pam_end(sshpam_handle, sshpam_err);
sshpam_handle = NULL;
return (-1);
}
if (ssh != NULL && sshpam_rhost == NULL) {
/*
* We need to cache these as we don't have packet context
* during the kbdint flow.
*/
sshpam_rhost = xstrdup(auth_get_canonical_hostname(ssh,
options.use_dns));
sshpam_laddr = get_local_ipaddr(
ssh_packet_get_connection_in(ssh));
- xasprintf(&sshpam_conninfo, "SSH_CONNECTION=%.50s %d %.50s %d",
- ssh_remote_ipaddr(ssh), ssh_remote_port(ssh),
- sshpam_laddr, ssh_local_port(ssh));
}
if (sshpam_rhost != NULL) {
debug("PAM: setting PAM_RHOST to \"%s\"", sshpam_rhost);
sshpam_err = pam_set_item(sshpam_handle, PAM_RHOST,
sshpam_rhost);
if (sshpam_err != PAM_SUCCESS) {
pam_end(sshpam_handle, sshpam_err);
sshpam_handle = NULL;
return (-1);
}
+ }
+ if (ssh != NULL && sshpam_laddr != NULL) {
+ char *conninfo;
+
/* Put SSH_CONNECTION in the PAM environment too */
- pam_putenv(sshpam_handle, sshpam_conninfo);
+ xasprintf(&conninfo, "SSH_CONNECTION=%.50s %d %.50s %d",
+ ssh_remote_ipaddr(ssh), ssh_remote_port(ssh),
+ sshpam_laddr, ssh_local_port(ssh));
+ if ((r = pam_putenv(sshpam_handle, conninfo)) != PAM_SUCCESS)
+ logit("pam_putenv: %s", pam_strerror(sshpam_handle, r));
+ free(conninfo);
}
#ifdef PAM_TTY_KLUDGE
/*
* Some silly PAM modules (e.g. pam_time) require a TTY to operate.
* sshd doesn't set the tty until too late in the auth process and
* may not even set one (for tty-less connections)
*/
debug("PAM: setting PAM_TTY to \"ssh\"");
sshpam_err = pam_set_item(sshpam_handle, PAM_TTY, "ssh");
if (sshpam_err != PAM_SUCCESS) {
pam_end(sshpam_handle, sshpam_err);
sshpam_handle = NULL;
return (-1);
}
#endif
return (0);
}
static void
expose_authinfo(const char *caller)
{
char *auth_info;
/*
* Expose authentication information to PAM.
* The environment variable is versioned. Please increment the
* version suffix if the format of session_info changes.
*/
if (sshpam_authctxt->session_info == NULL)
auth_info = xstrdup("");
else if ((auth_info = sshbuf_dup_string(
sshpam_authctxt->session_info)) == NULL)
fatal("%s: sshbuf_dup_string failed", __func__);
debug2("%s: auth information in SSH_AUTH_INFO_0", caller);
do_pam_putenv("SSH_AUTH_INFO_0", auth_info);
free(auth_info);
}
static void *
sshpam_init_ctx(Authctxt *authctxt)
{
struct pam_ctxt *ctxt;
int result, socks[2];
debug3("PAM: %s entering", __func__);
/*
* Refuse to start if we don't have PAM enabled or do_pam_account
* has previously failed.
*/
if (!options.use_pam || sshpam_account_status == 0)
return NULL;
/* Initialize PAM */
if (sshpam_init(NULL, authctxt) == -1) {
error("PAM: initialization failed");
return (NULL);
}
expose_authinfo(__func__);
ctxt = xcalloc(1, sizeof *ctxt);
/* Start the authentication thread */
if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, socks) == -1) {
error("PAM: failed create sockets: %s", strerror(errno));
free(ctxt);
return (NULL);
}
ctxt->pam_psock = socks[0];
ctxt->pam_csock = socks[1];
result = pthread_create(&ctxt->pam_thread, NULL, sshpam_thread, ctxt);
if (result != 0) {
error("PAM: failed to start authentication thread: %s",
strerror(result));
close(socks[0]);
close(socks[1]);
free(ctxt);
return (NULL);
}
cleanup_ctxt = ctxt;
return (ctxt);
}
static int
sshpam_query(void *ctx, char **name, char **info,
u_int *num, char ***prompts, u_int **echo_on)
{
struct sshbuf *buffer;
struct pam_ctxt *ctxt = ctx;
size_t plen;
u_char type;
char *msg;
size_t len, mlen;
int r;
debug3("PAM: %s entering", __func__);
if ((buffer = sshbuf_new()) == NULL)
fatal("%s: sshbuf_new failed", __func__);
*name = xstrdup("");
*info = xstrdup("");
*prompts = xmalloc(sizeof(char *));
**prompts = NULL;
plen = 0;
*echo_on = xmalloc(sizeof(u_int));
while (ssh_msg_recv(ctxt->pam_psock, buffer) == 0) {
if ((r = sshbuf_get_u8(buffer, &type)) != 0 ||
(r = sshbuf_get_cstring(buffer, &msg, &mlen)) != 0)
fatal("%s: buffer error: %s", __func__, ssh_err(r));
switch (type) {
case PAM_PROMPT_ECHO_ON:
case PAM_PROMPT_ECHO_OFF:
*num = 1;
len = plen + mlen + 1;
**prompts = xreallocarray(**prompts, 1, len);
strlcpy(**prompts + plen, msg, len - plen);
plen += mlen;
**echo_on = (type == PAM_PROMPT_ECHO_ON);
free(msg);
sshbuf_free(buffer);
return (0);
case PAM_ERROR_MSG:
case PAM_TEXT_INFO:
/* accumulate messages */
len = plen + mlen + 2;
**prompts = xreallocarray(**prompts, 1, len);
strlcpy(**prompts + plen, msg, len - plen);
plen += mlen;
strlcat(**prompts + plen, "\n", len - plen);
plen++;
free(msg);
break;
case PAM_ACCT_EXPIRED:
case PAM_MAXTRIES:
if (type == PAM_ACCT_EXPIRED)
sshpam_account_status = 0;
if (type == PAM_MAXTRIES)
sshpam_set_maxtries_reached(1);
/* FALLTHROUGH */
case PAM_AUTH_ERR:
debug3("PAM: %s", pam_strerror(sshpam_handle, type));
if (**prompts != NULL && strlen(**prompts) != 0) {
free(*info);
*info = **prompts;
**prompts = NULL;
*num = 0;
**echo_on = 0;
ctxt->pam_done = -1;
free(msg);
sshbuf_free(buffer);
return 0;
}
/* FALLTHROUGH */
case PAM_SUCCESS:
if (**prompts != NULL) {
/* drain any accumulated messages */
debug("PAM: %s", **prompts);
if ((r = sshbuf_put(loginmsg, **prompts,
strlen(**prompts))) != 0)
fatal("%s: buffer error: %s",
__func__, ssh_err(r));
free(**prompts);
**prompts = NULL;
}
if (type == PAM_SUCCESS) {
if (!sshpam_authctxt->valid ||
(sshpam_authctxt->pw->pw_uid == 0 &&
options.permit_root_login != PERMIT_YES))
fatal("Internal error: PAM auth "
"succeeded when it should have "
"failed");
import_environments(buffer);
*num = 0;
**echo_on = 0;
ctxt->pam_done = 1;
free(msg);
sshbuf_free(buffer);
return (0);
}
BLACKLIST_NOTIFY(NULL, BLACKLIST_BAD_USER,
sshpam_authctxt->user);
error("PAM: %s for %s%.100s from %.100s", msg,
sshpam_authctxt->valid ? "" : "illegal user ",
sshpam_authctxt->user, sshpam_rhost);
/* FALLTHROUGH */
default:
*num = 0;
**echo_on = 0;
free(msg);
ctxt->pam_done = -1;
sshbuf_free(buffer);
return (-1);
}
}
sshbuf_free(buffer);
return (-1);
}
/*
* Returns a junk password of identical length to that the user supplied.
* Used to mitigate timing attacks against crypt(3)/PAM stacks that
* vary processing time in proportion to password length.
*/
static char *
fake_password(const char *wire_password)
{
const char junk[] = "\b\n\r\177INCORRECT";
char *ret = NULL;
size_t i, l = wire_password != NULL ? strlen(wire_password) : 0;
if (l >= INT_MAX)
fatal("%s: password length too long: %zu", __func__, l);
ret = malloc(l + 1);
if (ret == NULL)
return NULL;
for (i = 0; i < l; i++)
ret[i] = junk[i % (sizeof(junk) - 1)];
ret[i] = '\0';
return ret;
}
/* XXX - see also comment in auth-chall.c:verify_response */
static int
sshpam_respond(void *ctx, u_int num, char **resp)
{
struct sshbuf *buffer;
struct pam_ctxt *ctxt = ctx;
char *fake;
int r;
debug2("PAM: %s entering, %u responses", __func__, num);
switch (ctxt->pam_done) {
case 1:
sshpam_authenticated = 1;
return (0);
case 0:
break;
default:
return (-1);
}
if (num != 1) {
error("PAM: expected one response, got %u", num);
return (-1);
}
if ((buffer = sshbuf_new()) == NULL)
fatal("%s: sshbuf_new failed", __func__);
if (sshpam_authctxt->valid &&
(sshpam_authctxt->pw->pw_uid != 0 ||
options.permit_root_login == PERMIT_YES)) {
if ((r = sshbuf_put_cstring(buffer, *resp)) != 0)
fatal("%s: buffer error: %s", __func__, ssh_err(r));
} else {
fake = fake_password(*resp);
if ((r = sshbuf_put_cstring(buffer, fake)) != 0)
fatal("%s: buffer error: %s", __func__, ssh_err(r));
free(fake);
}
if (ssh_msg_send(ctxt->pam_psock, PAM_AUTHTOK, buffer) == -1) {
sshbuf_free(buffer);
return (-1);
}
sshbuf_free(buffer);
return (1);
}
static void
sshpam_free_ctx(void *ctxtp)
{
struct pam_ctxt *ctxt = ctxtp;
debug3("PAM: %s entering", __func__);
sshpam_thread_cleanup();
free(ctxt);
/*
* We don't call sshpam_cleanup() here because we may need the PAM
* handle at a later stage, e.g. when setting up a session. It's
* still on the cleanup list, so pam_end() *will* be called before
* the server process terminates.
*/
}
KbdintDevice sshpam_device = {
"pam",
sshpam_init_ctx,
sshpam_query,
sshpam_respond,
sshpam_free_ctx
};
KbdintDevice mm_sshpam_device = {
"pam",
mm_sshpam_init_ctx,
mm_sshpam_query,
mm_sshpam_respond,
mm_sshpam_free_ctx
};
/*
* This replaces auth-pam.c
*/
void
start_pam(struct ssh *ssh)
{
Authctxt *authctxt = (Authctxt *)ssh->authctxt;
if (!options.use_pam)
fatal("PAM: initialisation requested when UsePAM=no");
if (sshpam_init(ssh, authctxt) == -1)
fatal("PAM: initialisation failed");
}
void
finish_pam(void)
{
sshpam_cleanup();
}
u_int
do_pam_account(void)
{
debug("%s: called", __func__);
if (sshpam_account_status != -1)
return (sshpam_account_status);
expose_authinfo(__func__);
sshpam_err = pam_acct_mgmt(sshpam_handle, 0);
debug3("PAM: %s pam_acct_mgmt = %d (%s)", __func__, sshpam_err,
pam_strerror(sshpam_handle, sshpam_err));
if (sshpam_err != PAM_SUCCESS && sshpam_err != PAM_NEW_AUTHTOK_REQD) {
sshpam_account_status = 0;
return (sshpam_account_status);
}
if (sshpam_err == PAM_NEW_AUTHTOK_REQD)
sshpam_password_change_required(1);
sshpam_account_status = 1;
return (sshpam_account_status);
}
void
do_pam_setcred(int init)
{
sshpam_err = pam_set_item(sshpam_handle, PAM_CONV,
(const void *)&store_conv);
if (sshpam_err != PAM_SUCCESS)
fatal("PAM: failed to set PAM_CONV: %s",
pam_strerror(sshpam_handle, sshpam_err));
if (init) {
debug("PAM: establishing credentials");
sshpam_err = pam_setcred(sshpam_handle, PAM_ESTABLISH_CRED);
} else {
debug("PAM: reinitializing credentials");
sshpam_err = pam_setcred(sshpam_handle, PAM_REINITIALIZE_CRED);
}
if (sshpam_err == PAM_SUCCESS) {
sshpam_cred_established = 1;
return;
}
if (sshpam_authenticated)
fatal("PAM: pam_setcred(): %s",
pam_strerror(sshpam_handle, sshpam_err));
else
debug("PAM: pam_setcred(): %s",
pam_strerror(sshpam_handle, sshpam_err));
}
static int
sshpam_tty_conv(int n, sshpam_const struct pam_message **msg,
struct pam_response **resp, void *data)
{
char input[PAM_MAX_MSG_SIZE];
struct pam_response *reply;
int i;
debug3("PAM: %s called with %d messages", __func__, n);
*resp = NULL;
if (n <= 0 || n > PAM_MAX_NUM_MSG || !isatty(STDIN_FILENO))
return (PAM_CONV_ERR);
if ((reply = calloc(n, sizeof(*reply))) == NULL)
return (PAM_CONV_ERR);
for (i = 0; i < n; ++i) {
switch (PAM_MSG_MEMBER(msg, i, msg_style)) {
case PAM_PROMPT_ECHO_OFF:
reply[i].resp =
read_passphrase(PAM_MSG_MEMBER(msg, i, msg),
RP_ALLOW_STDIN);
reply[i].resp_retcode = PAM_SUCCESS;
break;
case PAM_PROMPT_ECHO_ON:
fprintf(stderr, "%s\n", PAM_MSG_MEMBER(msg, i, msg));
if (fgets(input, sizeof input, stdin) == NULL)
input[0] = '\0';
if ((reply[i].resp = strdup(input)) == NULL)
goto fail;
reply[i].resp_retcode = PAM_SUCCESS;
break;
case PAM_ERROR_MSG:
case PAM_TEXT_INFO:
fprintf(stderr, "%s\n", PAM_MSG_MEMBER(msg, i, msg));
reply[i].resp_retcode = PAM_SUCCESS;
break;
default:
goto fail;
}
}
*resp = reply;
return (PAM_SUCCESS);
fail:
for(i = 0; i < n; i++) {
free(reply[i].resp);
}
free(reply);
return (PAM_CONV_ERR);
}
static struct pam_conv tty_conv = { sshpam_tty_conv, NULL };
/*
* XXX this should be done in the authentication phase, but ssh1 doesn't
* support that
*/
void
do_pam_chauthtok(void)
{
if (use_privsep)
fatal("Password expired (unable to change with privsep)");
sshpam_err = pam_set_item(sshpam_handle, PAM_CONV,
(const void *)&tty_conv);
if (sshpam_err != PAM_SUCCESS)
fatal("PAM: failed to set PAM_CONV: %s",
pam_strerror(sshpam_handle, sshpam_err));
debug("PAM: changing password");
sshpam_err = pam_chauthtok(sshpam_handle, PAM_CHANGE_EXPIRED_AUTHTOK);
if (sshpam_err != PAM_SUCCESS)
fatal("PAM: pam_chauthtok(): %s",
pam_strerror(sshpam_handle, sshpam_err));
}
void
do_pam_session(struct ssh *ssh)
{
debug3("PAM: opening session");
expose_authinfo(__func__);
sshpam_err = pam_set_item(sshpam_handle, PAM_CONV,
(const void *)&store_conv);
if (sshpam_err != PAM_SUCCESS)
fatal("PAM: failed to set PAM_CONV: %s",
pam_strerror(sshpam_handle, sshpam_err));
sshpam_err = pam_open_session(sshpam_handle, 0);
if (sshpam_err == PAM_SUCCESS)
sshpam_session_open = 1;
else {
sshpam_session_open = 0;
auth_restrict_session(ssh);
error("PAM: pam_open_session(): %s",
pam_strerror(sshpam_handle, sshpam_err));
}
}
int
is_pam_session_open(void)
{
return sshpam_session_open;
}
/*
* Set a PAM environment string. We need to do this so that the session
* modules can handle things like Kerberos/GSI credentials that appear
* during the ssh authentication process.
*/
int
do_pam_putenv(char *name, char *value)
{
int ret = 1;
char *compound;
size_t len;
len = strlen(name) + strlen(value) + 2;
compound = xmalloc(len);
snprintf(compound, len, "%s=%s", name, value);
ret = pam_putenv(sshpam_handle, compound);
free(compound);
return (ret);
}
char **
fetch_pam_child_environment(void)
{
return sshpam_env;
}
char **
fetch_pam_environment(void)
{
return (pam_getenvlist(sshpam_handle));
}
void
free_pam_environment(char **env)
{
char **envp;
if (env == NULL)
return;
for (envp = env; *envp; envp++)
free(*envp);
free(env);
}
/*
* "Blind" conversation function for password authentication. Assumes that
* echo-off prompts are for the password and stores messages for later
* display.
*/
static int
sshpam_passwd_conv(int n, sshpam_const struct pam_message **msg,
struct pam_response **resp, void *data)
{
struct pam_response *reply;
int r, i;
size_t len;
debug3("PAM: %s called with %d messages", __func__, n);
*resp = NULL;
if (n <= 0 || n > PAM_MAX_NUM_MSG)
return (PAM_CONV_ERR);
if ((reply = calloc(n, sizeof(*reply))) == NULL)
return (PAM_CONV_ERR);
for (i = 0; i < n; ++i) {
switch (PAM_MSG_MEMBER(msg, i, msg_style)) {
case PAM_PROMPT_ECHO_OFF:
if (sshpam_password == NULL)
goto fail;
if ((reply[i].resp = strdup(sshpam_password)) == NULL)
goto fail;
reply[i].resp_retcode = PAM_SUCCESS;
break;
case PAM_ERROR_MSG:
case PAM_TEXT_INFO:
len = strlen(PAM_MSG_MEMBER(msg, i, msg));
if (len > 0) {
if ((r = sshbuf_putf(loginmsg, "%s\n",
PAM_MSG_MEMBER(msg, i, msg))) != 0)
fatal("%s: buffer error: %s",
__func__, ssh_err(r));
}
if ((reply[i].resp = strdup("")) == NULL)
goto fail;
reply[i].resp_retcode = PAM_SUCCESS;
break;
default:
goto fail;
}
}
*resp = reply;
return (PAM_SUCCESS);
fail:
for(i = 0; i < n; i++) {
free(reply[i].resp);
}
free(reply);
return (PAM_CONV_ERR);
}
static struct pam_conv passwd_conv = { sshpam_passwd_conv, NULL };
/*
* Attempt password authentication via PAM
*/
int
sshpam_auth_passwd(Authctxt *authctxt, const char *password)
{
int flags = (options.permit_empty_passwd == 0 ?
PAM_DISALLOW_NULL_AUTHTOK : 0);
char *fake = NULL;
if (!options.use_pam || sshpam_handle == NULL)
fatal("PAM: %s called when PAM disabled or failed to "
"initialise.", __func__);
sshpam_password = password;
sshpam_authctxt = authctxt;
/*
* If the user logging in is invalid, or is root but is not permitted
* by PermitRootLogin, use an invalid password to prevent leaking
* information via timing (eg if the PAM config has a delay on fail).
*/
if (!authctxt->valid || (authctxt->pw->pw_uid == 0 &&
options.permit_root_login != PERMIT_YES))
sshpam_password = fake = fake_password(password);
sshpam_err = pam_set_item(sshpam_handle, PAM_CONV,
(const void *)&passwd_conv);
if (sshpam_err != PAM_SUCCESS)
fatal("PAM: %s: failed to set PAM_CONV: %s", __func__,
pam_strerror(sshpam_handle, sshpam_err));
sshpam_err = pam_authenticate(sshpam_handle, flags);
sshpam_password = NULL;
free(fake);
if (sshpam_err == PAM_MAXTRIES)
sshpam_set_maxtries_reached(1);
if (sshpam_err == PAM_SUCCESS && authctxt->valid) {
debug("PAM: password authentication accepted for %.100s",
authctxt->user);
return 1;
} else {
debug("PAM: password authentication failed for %.100s: %s",
authctxt->valid ? authctxt->user : "an illegal user",
pam_strerror(sshpam_handle, sshpam_err));
return 0;
}
}
int
sshpam_get_maxtries_reached(void)
{
return sshpam_maxtries_reached;
}
void
sshpam_set_maxtries_reached(int reached)
{
if (reached == 0 || sshpam_maxtries_reached)
return;
sshpam_maxtries_reached = 1;
options.password_authentication = 0;
options.kbd_interactive_authentication = 0;
}
#endif /* USE_PAM */
diff --git a/crypto/openssh/auth-rhosts.c b/crypto/openssh/auth-rhosts.c
index 4fc9252a6b61..56724677a9e2 100644
--- a/crypto/openssh/auth-rhosts.c
+++ b/crypto/openssh/auth-rhosts.c
@@ -1,336 +1,338 @@
-/* $OpenBSD: auth-rhosts.c,v 1.56 2022/02/23 21:21:49 djm Exp $ */
+/* $OpenBSD: auth-rhosts.c,v 1.57 2022/12/09 00:17:40 dtucker Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
* Rhosts authentication. This file contains code to check whether to admit
* the login based on rhosts authentication. This file also processes
* /etc/hosts.equiv.
*
* As far as I am concerned, the code I have written for this software
* can be used freely for any purpose. Any derived versions of this
* software must be clearly marked as such, and if the derived work is
* incompatible with the protocol description in the RFC file, it must be
* called by a name other than "ssh" or "Secure Shell".
*/
#include "includes.h"
#include <sys/types.h>
#include <sys/stat.h>
+#include <errno.h>
#include <fcntl.h>
#ifdef HAVE_NETGROUP_H
# include <netgroup.h>
#endif
#include <pwd.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <stdlib.h>
#include <unistd.h>
#include "packet.h"
#include "uidswap.h"
#include "pathnames.h"
#include "log.h"
#include "misc.h"
#include "xmalloc.h"
#include "sshbuf.h"
#include "sshkey.h"
#include "servconf.h"
#include "canohost.h"
#include "hostfile.h"
#include "auth.h"
/* import */
extern ServerOptions options;
extern int use_privsep;
/*
* This function processes an rhosts-style file (.rhosts, .shosts, or
* /etc/hosts.equiv). This returns true if authentication can be granted
* based on the file, and returns zero otherwise.
*/
static int
check_rhosts_file(const char *filename, const char *hostname,
const char *ipaddr, const char *client_user,
const char *server_user)
{
FILE *f;
#define RBUFLN 1024
char buf[RBUFLN];/* Must not be larger than host, user, dummy below. */
int fd;
struct stat st;
/* Open the .rhosts file, deny if unreadable */
if ((fd = open(filename, O_RDONLY|O_NONBLOCK)) == -1)
return 0;
if (fstat(fd, &st) == -1) {
close(fd);
return 0;
}
if (!S_ISREG(st.st_mode)) {
logit("User %s hosts file %s is not a regular file",
server_user, filename);
close(fd);
return 0;
}
unset_nonblock(fd);
if ((f = fdopen(fd, "r")) == NULL) {
close(fd);
return 0;
}
while (fgets(buf, sizeof(buf), f)) {
/* All three must have length >= buf to avoid overflows. */
char hostbuf[RBUFLN], userbuf[RBUFLN], dummy[RBUFLN];
char *host, *user, *cp;
int negated;
for (cp = buf; *cp == ' ' || *cp == '\t'; cp++)
;
if (*cp == '#' || *cp == '\n' || !*cp)
continue;
/*
* NO_PLUS is supported at least on OSF/1. We skip it (we
* don't ever support the plus syntax).
*/
if (strncmp(cp, "NO_PLUS", 7) == 0)
continue;
/*
* This should be safe because each buffer is as big as the
* whole string, and thus cannot be overwritten.
*/
switch (sscanf(buf, "%1023s %1023s %1023s", hostbuf, userbuf,
dummy)) {
case 0:
auth_debug_add("Found empty line in %.100s.", filename);
continue;
case 1:
/* Host name only. */
strlcpy(userbuf, server_user, sizeof(userbuf));
break;
case 2:
/* Got both host and user name. */
break;
case 3:
auth_debug_add("Found garbage in %.100s.", filename);
continue;
default:
/* Weird... */
continue;
}
host = hostbuf;
user = userbuf;
negated = 0;
/* Process negated host names, or positive netgroups. */
if (host[0] == '-') {
negated = 1;
host++;
} else if (host[0] == '+')
host++;
if (user[0] == '-') {
negated = 1;
user++;
} else if (user[0] == '+')
user++;
/* Check for empty host/user names (particularly '+'). */
if (!host[0] || !user[0]) {
/* We come here if either was '+' or '-'. */
auth_debug_add("Ignoring wild host/user names "
"in %.100s.", filename);
continue;
}
/* Verify that host name matches. */
if (host[0] == '@') {
if (!innetgr(host + 1, hostname, NULL, NULL) &&
!innetgr(host + 1, ipaddr, NULL, NULL))
continue;
} else if (strcasecmp(host, hostname) &&
strcmp(host, ipaddr) != 0)
continue; /* Different hostname. */
/* Verify that user name matches. */
if (user[0] == '@') {
if (!innetgr(user + 1, NULL, client_user, NULL))
continue;
} else if (strcmp(user, client_user) != 0)
continue; /* Different username. */
/* Found the user and host. */
fclose(f);
/* If the entry was negated, deny access. */
if (negated) {
auth_debug_add("Matched negative entry in %.100s.",
filename);
return 0;
}
/* Accept authentication. */
return 1;
}
/* Authentication using this file denied. */
fclose(f);
return 0;
}
/*
* Tries to authenticate the user using the .shosts or .rhosts file. Returns
* true if authentication succeeds. If ignore_rhosts is true, only
* /etc/hosts.equiv will be considered (.rhosts and .shosts are ignored).
*/
int
auth_rhosts2(struct passwd *pw, const char *client_user, const char *hostname,
const char *ipaddr)
{
char *path = NULL;
struct stat st;
static const char * const rhosts_files[] = {".shosts", ".rhosts", NULL};
u_int rhosts_file_index;
int r;
debug2_f("clientuser %s hostname %s ipaddr %s",
client_user, hostname, ipaddr);
/* Switch to the user's uid. */
temporarily_use_uid(pw);
/*
* Quick check: if the user has no .shosts or .rhosts files and
* no system hosts.equiv/shosts.equiv files exist then return
* failure immediately without doing costly lookups from name
* servers.
*/
for (rhosts_file_index = 0; rhosts_files[rhosts_file_index];
rhosts_file_index++) {
/* Check users .rhosts or .shosts. */
xasprintf(&path, "%s/%s",
pw->pw_dir, rhosts_files[rhosts_file_index]);
r = stat(path, &st);
free(path);
if (r >= 0)
break;
}
/* Switch back to privileged uid. */
restore_uid();
/*
* Deny if The user has no .shosts or .rhosts file and there
* are no system-wide files.
*/
if (!rhosts_files[rhosts_file_index] &&
stat(_PATH_RHOSTS_EQUIV, &st) == -1 &&
stat(_PATH_SSH_HOSTS_EQUIV, &st) == -1) {
debug3_f("no hosts access files exist");
return 0;
}
/*
* If not logging in as superuser, try /etc/hosts.equiv and
* shosts.equiv.
*/
if (pw->pw_uid == 0)
debug3_f("root user, ignoring system hosts files");
else {
if (check_rhosts_file(_PATH_RHOSTS_EQUIV, hostname, ipaddr,
client_user, pw->pw_name)) {
auth_debug_add("Accepted for %.100s [%.100s] by "
"/etc/hosts.equiv.", hostname, ipaddr);
return 1;
}
if (check_rhosts_file(_PATH_SSH_HOSTS_EQUIV, hostname, ipaddr,
client_user, pw->pw_name)) {
auth_debug_add("Accepted for %.100s [%.100s] by "
"%.100s.", hostname, ipaddr, _PATH_SSH_HOSTS_EQUIV);
return 1;
}
}
/*
* Check that the home directory is owned by root or the user, and is
* not group or world writable.
*/
if (stat(pw->pw_dir, &st) == -1) {
logit("Rhosts authentication refused for %.100s: "
"no home directory %.200s", pw->pw_name, pw->pw_dir);
auth_debug_add("Rhosts authentication refused for %.100s: "
"no home directory %.200s", pw->pw_name, pw->pw_dir);
return 0;
}
if (options.strict_modes &&
((st.st_uid != 0 && st.st_uid != pw->pw_uid) ||
(st.st_mode & 022) != 0)) {
logit("Rhosts authentication refused for %.100s: "
"bad ownership or modes for home directory.", pw->pw_name);
auth_debug_add("Rhosts authentication refused for %.100s: "
"bad ownership or modes for home directory.", pw->pw_name);
return 0;
}
/* Temporarily use the user's uid. */
temporarily_use_uid(pw);
/* Check all .rhosts files (currently .shosts and .rhosts). */
for (rhosts_file_index = 0; rhosts_files[rhosts_file_index];
rhosts_file_index++) {
/* Check users .rhosts or .shosts. */
xasprintf(&path, "%s/%s",
pw->pw_dir, rhosts_files[rhosts_file_index]);
if (stat(path, &st) == -1) {
+ debug3_f("stat %s: %s", path, strerror(errno));
free(path);
continue;
}
/*
* Make sure that the file is either owned by the user or by
* root, and make sure it is not writable by anyone but the
* owner. This is to help avoid novices accidentally
* allowing access to their account by anyone.
*/
if (options.strict_modes &&
((st.st_uid != 0 && st.st_uid != pw->pw_uid) ||
(st.st_mode & 022) != 0)) {
logit("Rhosts authentication refused for %.100s: "
"bad modes for %.200s", pw->pw_name, path);
auth_debug_add("Bad file modes for %.200s", path);
free(path);
continue;
}
/*
* Check if we have been configured to ignore .rhosts
* and .shosts files.
*/
if (options.ignore_rhosts == IGNORE_RHOSTS_YES ||
(options.ignore_rhosts == IGNORE_RHOSTS_SHOSTS &&
strcmp(rhosts_files[rhosts_file_index], ".shosts") != 0)) {
auth_debug_add("Server has been configured to "
"ignore %.100s.", rhosts_files[rhosts_file_index]);
free(path);
continue;
}
/* Check if authentication is permitted by the file. */
if (check_rhosts_file(path, hostname, ipaddr,
client_user, pw->pw_name)) {
auth_debug_add("Accepted by %.100s.",
rhosts_files[rhosts_file_index]);
/* Restore the privileged uid. */
restore_uid();
auth_debug_add("Accepted host %s ip %s client_user "
"%s server_user %s", hostname, ipaddr,
client_user, pw->pw_name);
free(path);
return 1;
}
free(path);
}
/* Restore the privileged uid. */
restore_uid();
return 0;
}
diff --git a/crypto/openssh/auth.c b/crypto/openssh/auth.c
index 3e6b75c7bc62..93610963f3b3 100644
--- a/crypto/openssh/auth.c
+++ b/crypto/openssh/auth.c
@@ -1,881 +1,880 @@
-/* $OpenBSD: auth.c,v 1.158 2022/06/03 04:47:21 djm Exp $ */
+/* $OpenBSD: auth.c,v 1.159 2022/12/09 00:17:40 dtucker Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "includes.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#ifdef HAVE_PATHS_H
# include <paths.h>
#endif
#include <pwd.h>
#ifdef HAVE_LOGIN_H
#include <login.h>
#endif
#ifdef USE_SHADOW
#include <shadow.h>
#endif
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <limits.h>
#include <netdb.h>
#include <time.h>
#include "xmalloc.h"
#include "match.h"
#include "groupaccess.h"
#include "log.h"
#include "sshbuf.h"
#include "misc.h"
#include "servconf.h"
#include "sshkey.h"
#include "hostfile.h"
#include "auth.h"
#include "auth-options.h"
#include "canohost.h"
#include "uidswap.h"
#include "packet.h"
#include "loginrec.h"
#ifdef GSSAPI
#include "ssh-gss.h"
#endif
#include "authfile.h"
#include "monitor_wrap.h"
#include "ssherr.h"
#include "compat.h"
#include "channels.h"
#include "blacklist_client.h"
/* import */
extern ServerOptions options;
extern struct include_list includes;
extern int use_privsep;
extern struct sshbuf *loginmsg;
extern struct passwd *privsep_pw;
extern struct sshauthopt *auth_opts;
/* Debugging messages */
static struct sshbuf *auth_debug;
/*
* Check if the user is allowed to log in via ssh. If user is listed
* in DenyUsers or one of user's groups is listed in DenyGroups, false
* will be returned. If AllowUsers isn't empty and user isn't listed
* there, or if AllowGroups isn't empty and one of user's groups isn't
* listed there, false will be returned.
* If the user's shell is not executable, false will be returned.
* Otherwise true is returned.
*/
int
allowed_user(struct ssh *ssh, struct passwd * pw)
{
struct stat st;
const char *hostname = NULL, *ipaddr = NULL;
u_int i;
int r;
/* Shouldn't be called if pw is NULL, but better safe than sorry... */
if (!pw || !pw->pw_name)
return 0;
if (!options.use_pam && platform_locked_account(pw)) {
logit("User %.100s not allowed because account is locked",
pw->pw_name);
return 0;
}
/*
* Deny if shell does not exist or is not executable unless we
* are chrooting.
*/
if (options.chroot_directory == NULL ||
strcasecmp(options.chroot_directory, "none") == 0) {
char *shell = xstrdup((pw->pw_shell[0] == '\0') ?
_PATH_BSHELL : pw->pw_shell); /* empty = /bin/sh */
if (stat(shell, &st) == -1) {
logit("User %.100s not allowed because shell %.100s "
"does not exist", pw->pw_name, shell);
free(shell);
return 0;
}
if (S_ISREG(st.st_mode) == 0 ||
(st.st_mode & (S_IXOTH|S_IXUSR|S_IXGRP)) == 0) {
logit("User %.100s not allowed because shell %.100s "
"is not executable", pw->pw_name, shell);
free(shell);
return 0;
}
free(shell);
}
if (options.num_deny_users > 0 || options.num_allow_users > 0 ||
options.num_deny_groups > 0 || options.num_allow_groups > 0) {
hostname = auth_get_canonical_hostname(ssh, options.use_dns);
ipaddr = ssh_remote_ipaddr(ssh);
}
/* Return false if user is listed in DenyUsers */
if (options.num_deny_users > 0) {
for (i = 0; i < options.num_deny_users; i++) {
r = match_user(pw->pw_name, hostname, ipaddr,
options.deny_users[i]);
if (r < 0) {
fatal("Invalid DenyUsers pattern \"%.100s\"",
options.deny_users[i]);
} else if (r != 0) {
logit("User %.100s from %.100s not allowed "
"because listed in DenyUsers",
pw->pw_name, hostname);
return 0;
}
}
}
/* Return false if AllowUsers isn't empty and user isn't listed there */
if (options.num_allow_users > 0) {
for (i = 0; i < options.num_allow_users; i++) {
r = match_user(pw->pw_name, hostname, ipaddr,
options.allow_users[i]);
if (r < 0) {
fatal("Invalid AllowUsers pattern \"%.100s\"",
options.allow_users[i]);
} else if (r == 1)
break;
}
/* i < options.num_allow_users iff we break for loop */
if (i >= options.num_allow_users) {
logit("User %.100s from %.100s not allowed because "
"not listed in AllowUsers", pw->pw_name, hostname);
return 0;
}
}
if (options.num_deny_groups > 0 || options.num_allow_groups > 0) {
/* Get the user's group access list (primary and supplementary) */
if (ga_init(pw->pw_name, pw->pw_gid) == 0) {
logit("User %.100s from %.100s not allowed because "
"not in any group", pw->pw_name, hostname);
return 0;
}
/* Return false if one of user's groups is listed in DenyGroups */
if (options.num_deny_groups > 0)
if (ga_match(options.deny_groups,
options.num_deny_groups)) {
ga_free();
logit("User %.100s from %.100s not allowed "
"because a group is listed in DenyGroups",
pw->pw_name, hostname);
return 0;
}
/*
* Return false if AllowGroups isn't empty and one of user's groups
* isn't listed there
*/
if (options.num_allow_groups > 0)
if (!ga_match(options.allow_groups,
options.num_allow_groups)) {
ga_free();
logit("User %.100s from %.100s not allowed "
"because none of user's groups are listed "
"in AllowGroups", pw->pw_name, hostname);
return 0;
}
ga_free();
}
#ifdef CUSTOM_SYS_AUTH_ALLOWED_USER
if (!sys_auth_allowed_user(pw, loginmsg))
return 0;
#endif
/* We found no reason not to let this user try to log on... */
return 1;
}
/*
* Formats any key left in authctxt->auth_method_key for inclusion in
* auth_log()'s message. Also includes authxtct->auth_method_info if present.
*/
static char *
format_method_key(Authctxt *authctxt)
{
const struct sshkey *key = authctxt->auth_method_key;
const char *methinfo = authctxt->auth_method_info;
char *fp, *cafp, *ret = NULL;
if (key == NULL)
return NULL;
if (sshkey_is_cert(key)) {
fp = sshkey_fingerprint(key,
options.fingerprint_hash, SSH_FP_DEFAULT);
cafp = sshkey_fingerprint(key->cert->signature_key,
options.fingerprint_hash, SSH_FP_DEFAULT);
xasprintf(&ret, "%s %s ID %s (serial %llu) CA %s %s%s%s",
sshkey_type(key), fp == NULL ? "(null)" : fp,
key->cert->key_id,
(unsigned long long)key->cert->serial,
sshkey_type(key->cert->signature_key),
cafp == NULL ? "(null)" : cafp,
methinfo == NULL ? "" : ", ",
methinfo == NULL ? "" : methinfo);
free(fp);
free(cafp);
} else {
fp = sshkey_fingerprint(key, options.fingerprint_hash,
SSH_FP_DEFAULT);
xasprintf(&ret, "%s %s%s%s", sshkey_type(key),
fp == NULL ? "(null)" : fp,
methinfo == NULL ? "" : ", ",
methinfo == NULL ? "" : methinfo);
free(fp);
}
return ret;
}
void
auth_log(struct ssh *ssh, int authenticated, int partial,
const char *method, const char *submethod)
{
Authctxt *authctxt = (Authctxt *)ssh->authctxt;
int level = SYSLOG_LEVEL_VERBOSE;
const char *authmsg;
char *extra = NULL;
if (use_privsep && !mm_is_monitor() && !authctxt->postponed)
return;
/* Raise logging level */
if (authenticated == 1 ||
!authctxt->valid ||
authctxt->failures >= options.max_authtries / 2 ||
strcmp(method, "password") == 0)
level = SYSLOG_LEVEL_INFO;
if (authctxt->postponed)
authmsg = "Postponed";
else if (partial)
authmsg = "Partial";
else {
authmsg = authenticated ? "Accepted" : "Failed";
if (authenticated)
BLACKLIST_NOTIFY(ssh, BLACKLIST_AUTH_OK, "ssh");
}
if ((extra = format_method_key(authctxt)) == NULL) {
if (authctxt->auth_method_info != NULL)
extra = xstrdup(authctxt->auth_method_info);
}
do_log2(level, "%s %s%s%s for %s%.100s from %.200s port %d ssh2%s%s",
authmsg,
method,
submethod != NULL ? "/" : "", submethod == NULL ? "" : submethod,
authctxt->valid ? "" : "invalid user ",
authctxt->user,
ssh_remote_ipaddr(ssh),
ssh_remote_port(ssh),
extra != NULL ? ": " : "",
extra != NULL ? extra : "");
free(extra);
#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
}
void
auth_maxtries_exceeded(struct ssh *ssh)
{
Authctxt *authctxt = (Authctxt *)ssh->authctxt;
error("maximum authentication attempts exceeded for "
"%s%.100s from %.200s port %d ssh2",
authctxt->valid ? "" : "invalid user ",
authctxt->user,
ssh_remote_ipaddr(ssh),
ssh_remote_port(ssh));
ssh_packet_disconnect(ssh, "Too many authentication failures");
/* NOTREACHED */
}
/*
* Check whether root logins are disallowed.
*/
int
auth_root_allowed(struct ssh *ssh, const char *method)
{
switch (options.permit_root_login) {
case PERMIT_YES:
return 1;
case PERMIT_NO_PASSWD:
if (strcmp(method, "publickey") == 0 ||
strcmp(method, "hostbased") == 0 ||
strcmp(method, "gssapi-with-mic") == 0)
return 1;
break;
case PERMIT_FORCED_ONLY:
if (auth_opts->force_command != NULL) {
logit("Root login accepted for forced command.");
return 1;
}
break;
}
logit("ROOT LOGIN REFUSED FROM %.200s port %d",
ssh_remote_ipaddr(ssh), ssh_remote_port(ssh));
return 0;
}
/*
* Given a template and a passwd structure, build a filename
* by substituting % tokenised options. Currently, %% becomes '%',
* %h becomes the home directory and %u the username.
*
* This returns a buffer allocated by xmalloc.
*/
char *
expand_authorized_keys(const char *filename, struct passwd *pw)
{
char *file, uidstr[32], ret[PATH_MAX];
int i;
snprintf(uidstr, sizeof(uidstr), "%llu",
(unsigned long long)pw->pw_uid);
file = percent_expand(filename, "h", pw->pw_dir,
"u", pw->pw_name, "U", uidstr, (char *)NULL);
/*
* Ensure that filename starts anchored. If not, be backward
* compatible and prepend the '%h/'
*/
if (path_absolute(file))
return (file);
i = snprintf(ret, sizeof(ret), "%s/%s", pw->pw_dir, file);
if (i < 0 || (size_t)i >= sizeof(ret))
fatal("expand_authorized_keys: path too long");
free(file);
return (xstrdup(ret));
}
char *
authorized_principals_file(struct passwd *pw)
{
if (options.authorized_principals_file == NULL)
return NULL;
return expand_authorized_keys(options.authorized_principals_file, pw);
}
/* return ok if key exists in sysfile or userfile */
HostStatus
check_key_in_hostfiles(struct passwd *pw, struct sshkey *key, const char *host,
const char *sysfile, const char *userfile)
{
char *user_hostfile;
struct stat st;
HostStatus host_status;
struct hostkeys *hostkeys;
const struct hostkey_entry *found;
hostkeys = init_hostkeys();
load_hostkeys(hostkeys, host, sysfile, 0);
if (userfile != NULL) {
user_hostfile = tilde_expand_filename(userfile, pw->pw_uid);
if (options.strict_modes &&
(stat(user_hostfile, &st) == 0) &&
((st.st_uid != 0 && st.st_uid != pw->pw_uid) ||
(st.st_mode & 022) != 0)) {
logit("Authentication refused for %.100s: "
"bad owner or modes for %.200s",
pw->pw_name, user_hostfile);
auth_debug_add("Ignored %.200s: bad ownership or modes",
user_hostfile);
} else {
temporarily_use_uid(pw);
load_hostkeys(hostkeys, host, user_hostfile, 0);
restore_uid();
}
free(user_hostfile);
}
host_status = check_key_in_hostkeys(hostkeys, key, &found);
if (host_status == HOST_REVOKED)
error("WARNING: revoked key for %s attempted authentication",
host);
else if (host_status == HOST_OK)
debug_f("key for %s found at %s:%ld",
found->host, found->file, found->line);
else
debug_f("key for host %s not found", host);
free_hostkeys(hostkeys);
return host_status;
}
struct passwd *
getpwnamallow(struct ssh *ssh, const char *user)
{
#ifdef HAVE_LOGIN_CAP
extern login_cap_t *lc;
#ifdef HAVE_AUTH_HOSTOK
const char *from_host, *from_ip;
#endif
#ifdef BSD_AUTH
auth_session_t *as;
#endif
#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)
aix_setauthdb(user);
#endif
pw = getpwnam(user);
#if defined(_AIX) && defined(HAVE_SETAUTHDB)
aix_restoreauthdb();
#endif
if (pw == NULL) {
BLACKLIST_NOTIFY(ssh, BLACKLIST_BAD_USER, user);
logit("Invalid user %.100s from %.100s port %d",
user, ssh_remote_ipaddr(ssh), ssh_remote_port(ssh));
#ifdef CUSTOM_FAILED_LOGIN
record_failed_login(ssh, user,
auth_get_canonical_hostname(ssh, options.use_dns), "ssh");
#endif
#ifdef SSH_AUDIT_EVENTS
audit_event(ssh, SSH_INVALID_USER);
#endif /* SSH_AUDIT_EVENTS */
return (NULL);
}
if (!allowed_user(ssh, pw))
return (NULL);
#ifdef HAVE_LOGIN_CAP
if ((lc = login_getpwclass(pw)) == NULL) {
debug("unable to get login class: %s", user);
return (NULL);
}
#ifdef HAVE_AUTH_HOSTOK
from_host = auth_get_canonical_hostname(ssh, options.use_dns);
from_ip = ssh_remote_ipaddr(ssh);
if (!auth_hostok(lc, from_host, from_ip)) {
debug("Denied connection for %.200s from %.200s [%.200s].",
pw->pw_name, from_host, from_ip);
return (NULL);
}
#endif /* HAVE_AUTH_HOSTOK */
#ifdef HAVE_AUTH_TIMEOK
if (!auth_timeok(lc, time(NULL))) {
debug("LOGIN %.200s REFUSED (TIME)", pw->pw_name);
return (NULL);
}
#endif /* HAVE_AUTH_TIMEOK */
#ifdef BSD_AUTH
if ((as = auth_open()) == NULL || auth_setpwd(as, pw) != 0 ||
auth_approval(as, lc, pw->pw_name, "ssh") <= 0) {
debug("Approval failure for %s", user);
pw = NULL;
}
if (as != NULL)
auth_close(as);
#endif
#endif
if (pw != NULL)
return (pwcopy(pw));
return (NULL);
}
/* Returns 1 if key is revoked by revoked_keys_file, 0 otherwise */
int
auth_key_is_revoked(struct sshkey *key)
{
char *fp = NULL;
int r;
if (options.revoked_keys_file == NULL)
return 0;
if ((fp = sshkey_fingerprint(key, options.fingerprint_hash,
SSH_FP_DEFAULT)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
error_fr(r, "fingerprint key");
goto out;
}
r = sshkey_check_revoked(key, options.revoked_keys_file);
switch (r) {
case 0:
break; /* not revoked */
case SSH_ERR_KEY_REVOKED:
error("Authentication key %s %s revoked by file %s",
sshkey_type(key), fp, options.revoked_keys_file);
goto out;
default:
error_r(r, "Error checking authentication key %s %s in "
"revoked keys file %s", sshkey_type(key), fp,
options.revoked_keys_file);
goto out;
}
/* Success */
r = 0;
out:
free(fp);
return r == 0 ? 0 : 1;
}
void
auth_debug_add(const char *fmt,...)
{
char buf[1024];
va_list args;
int r;
- if (auth_debug == NULL)
- return;
-
va_start(args, fmt);
vsnprintf(buf, sizeof(buf), fmt, args);
va_end(args);
- if ((r = sshbuf_put_cstring(auth_debug, buf)) != 0)
- fatal_fr(r, "sshbuf_put_cstring");
+ debug3("%s", buf);
+ if (auth_debug != NULL)
+ if ((r = sshbuf_put_cstring(auth_debug, buf)) != 0)
+ fatal_fr(r, "sshbuf_put_cstring");
}
void
auth_debug_send(struct ssh *ssh)
{
char *msg;
int r;
if (auth_debug == NULL)
return;
while (sshbuf_len(auth_debug) != 0) {
if ((r = sshbuf_get_cstring(auth_debug, &msg, NULL)) != 0)
fatal_fr(r, "sshbuf_get_cstring");
ssh_packet_send_debug(ssh, "%s", msg);
free(msg);
}
}
void
auth_debug_reset(void)
{
if (auth_debug != NULL)
sshbuf_reset(auth_debug);
else if ((auth_debug = sshbuf_new()) == NULL)
fatal_f("sshbuf_new failed");
}
struct passwd *
fakepw(void)
{
static int done = 0;
static struct passwd fake;
const char hashchars[] = "./ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz0123456789"; /* from bcrypt.c */
char *cp;
if (done)
return (&fake);
memset(&fake, 0, sizeof(fake));
fake.pw_name = "NOUSER";
fake.pw_passwd = xstrdup("$2a$10$"
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
for (cp = fake.pw_passwd + 7; *cp != '\0'; cp++)
*cp = hashchars[arc4random_uniform(sizeof(hashchars) - 1)];
#ifdef HAVE_STRUCT_PASSWD_PW_GECOS
fake.pw_gecos = "NOUSER";
#endif
fake.pw_uid = privsep_pw == NULL ? (uid_t)-1 : privsep_pw->pw_uid;
fake.pw_gid = privsep_pw == NULL ? (gid_t)-1 : privsep_pw->pw_gid;
#ifdef HAVE_STRUCT_PASSWD_PW_CLASS
fake.pw_class = "";
#endif
fake.pw_dir = "/nonexist";
fake.pw_shell = "/nonexist";
done = 1;
return (&fake);
}
/*
* Returns the remote DNS hostname as a string. The returned string must not
* 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 based on conflation of hostnames and IP addresses.
*/
static char *
remote_hostname(struct ssh *ssh)
{
struct sockaddr_storage from;
socklen_t fromlen;
struct addrinfo hints, *ai, *aitop;
char name[NI_MAXHOST], ntop2[NI_MAXHOST];
const char *ntop = ssh_remote_ipaddr(ssh);
/* Get IP address of client. */
fromlen = sizeof(from);
memset(&from, 0, sizeof(from));
if (getpeername(ssh_packet_get_connection_in(ssh),
(struct sockaddr *)&from, &fromlen) == -1) {
debug("getpeername failed: %.100s", strerror(errno));
return xstrdup(ntop);
}
ipv64_normalise_mapped(&from, &fromlen);
if (from.ss_family == AF_INET6)
fromlen = sizeof(struct sockaddr_in6);
debug3("Trying to reverse map address %.100s.", ntop);
/* Map the IP address to a host name. */
if (getnameinfo((struct sockaddr *)&from, fromlen, name, sizeof(name),
NULL, 0, NI_NAMEREQD) != 0) {
/* Host name not found. Use ip address. */
return xstrdup(ntop);
}
/*
* if reverse lookup result looks like a numeric hostname,
* someone is trying to trick us by PTR record like following:
* 1.1.1.10.in-addr.arpa. IN PTR 2.3.4.5
*/
memset(&hints, 0, sizeof(hints));
hints.ai_socktype = SOCK_DGRAM; /*dummy*/
hints.ai_flags = AI_NUMERICHOST;
if (getaddrinfo(name, NULL, &hints, &ai) == 0) {
logit("Nasty PTR record \"%s\" is set up for %s, ignoring",
name, ntop);
freeaddrinfo(ai);
return xstrdup(ntop);
}
/* Names are stored in lowercase. */
lowercase(name);
/*
* Map it back to an IP address and check that the given
* address actually is an address of this host. This is
* necessary because anyone with access to a name server can
* define arbitrary names for an IP address. Mapping from
* name to IP address can be trusted better (but can still be
* fooled if the intruder has access to the name server of
* the domain).
*/
memset(&hints, 0, sizeof(hints));
hints.ai_family = from.ss_family;
hints.ai_socktype = SOCK_STREAM;
if (getaddrinfo(name, NULL, &hints, &aitop) != 0) {
logit("reverse mapping checking getaddrinfo for %.700s "
"[%s] failed.", name, ntop);
return xstrdup(ntop);
}
/* Look for the address from the list of addresses. */
for (ai = aitop; ai; ai = ai->ai_next) {
if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop2,
sizeof(ntop2), NULL, 0, NI_NUMERICHOST) == 0 &&
(strcmp(ntop, ntop2) == 0))
break;
}
freeaddrinfo(aitop);
/* If we reached the end of the list, the address was not there. */
if (ai == NULL) {
/* Address not found for the host name. */
logit("Address %.100s maps to %.600s, but this does not "
"map back to the address.", ntop, name);
return xstrdup(ntop);
}
return xstrdup(name);
}
/*
* Return the canonical name of the host in the other side of the current
* connection. The host name is cached, so it is efficient to call this
* several times.
*/
const char *
auth_get_canonical_hostname(struct ssh *ssh, int use_dns)
{
static char *dnsname;
if (!use_dns)
return ssh_remote_ipaddr(ssh);
else if (dnsname != NULL)
return dnsname;
else {
dnsname = remote_hostname(ssh);
return dnsname;
}
}
/* These functions link key/cert options to the auth framework */
/* Log sshauthopt options locally and (optionally) for remote transmission */
void
auth_log_authopts(const char *loc, const struct sshauthopt *opts, int do_remote)
{
int do_env = options.permit_user_env && opts->nenv > 0;
int do_permitopen = opts->npermitopen > 0 &&
(options.allow_tcp_forwarding & FORWARD_LOCAL) != 0;
int do_permitlisten = opts->npermitlisten > 0 &&
(options.allow_tcp_forwarding & FORWARD_REMOTE) != 0;
size_t i;
char msg[1024], buf[64];
snprintf(buf, sizeof(buf), "%d", opts->force_tun_device);
/* Try to keep this alphabetically sorted */
snprintf(msg, sizeof(msg), "key options:%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
opts->permit_agent_forwarding_flag ? " agent-forwarding" : "",
opts->force_command == NULL ? "" : " command",
do_env ? " environment" : "",
opts->valid_before == 0 ? "" : "expires",
opts->no_require_user_presence ? " no-touch-required" : "",
do_permitopen ? " permitopen" : "",
do_permitlisten ? " permitlisten" : "",
opts->permit_port_forwarding_flag ? " port-forwarding" : "",
opts->cert_principals == NULL ? "" : " principals",
opts->permit_pty_flag ? " pty" : "",
opts->require_verify ? " uv" : "",
opts->force_tun_device == -1 ? "" : " tun=",
opts->force_tun_device == -1 ? "" : buf,
opts->permit_user_rc ? " user-rc" : "",
opts->permit_x11_forwarding_flag ? " x11-forwarding" : "");
debug("%s: %s", loc, msg);
if (do_remote)
auth_debug_add("%s: %s", loc, msg);
if (options.permit_user_env) {
for (i = 0; i < opts->nenv; i++) {
debug("%s: environment: %s", loc, opts->env[i]);
if (do_remote) {
auth_debug_add("%s: environment: %s",
loc, opts->env[i]);
}
}
}
/* Go into a little more details for the local logs. */
if (opts->valid_before != 0) {
format_absolute_time(opts->valid_before, buf, sizeof(buf));
debug("%s: expires at %s", loc, buf);
}
if (opts->cert_principals != NULL) {
debug("%s: authorized principals: \"%s\"",
loc, opts->cert_principals);
}
if (opts->force_command != NULL)
debug("%s: forced command: \"%s\"", loc, opts->force_command);
if (do_permitopen) {
for (i = 0; i < opts->npermitopen; i++) {
debug("%s: permitted open: %s",
loc, opts->permitopen[i]);
}
}
if (do_permitlisten) {
for (i = 0; i < opts->npermitlisten; i++) {
debug("%s: permitted listen: %s",
loc, opts->permitlisten[i]);
}
}
}
/* Activate a new set of key/cert options; merging with what is there. */
int
auth_activate_options(struct ssh *ssh, struct sshauthopt *opts)
{
struct sshauthopt *old = auth_opts;
const char *emsg = NULL;
debug_f("setting new authentication options");
if ((auth_opts = sshauthopt_merge(old, opts, &emsg)) == NULL) {
error("Inconsistent authentication options: %s", emsg);
return -1;
}
return 0;
}
/* Disable forwarding, etc for the session */
void
auth_restrict_session(struct ssh *ssh)
{
struct sshauthopt *restricted;
debug_f("restricting session");
/* A blank sshauthopt defaults to permitting nothing */
if ((restricted = sshauthopt_new()) == NULL)
fatal_f("sshauthopt_new failed");
restricted->permit_pty_flag = 1;
restricted->restricted = 1;
if (auth_activate_options(ssh, restricted) != 0)
fatal_f("failed to restrict session");
sshauthopt_free(restricted);
}
diff --git a/crypto/openssh/channels.c b/crypto/openssh/channels.c
index e75a0cf9b509..0d26358cc65e 100644
--- a/crypto/openssh/channels.c
+++ b/crypto/openssh/channels.c
@@ -1,5143 +1,5271 @@
-/* $OpenBSD: channels.c,v 1.420 2022/09/19 08:49:50 djm Exp $ */
+/* $OpenBSD: channels.c,v 1.427 2023/01/18 02:00:10 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
* This file contains functions for generic socket connection forwarding.
* There is also code for initiating connection forwarding for X11 connections,
* arbitrary tcp/ip connections, and the authentication agent connection.
*
* As far as I am concerned, the code I have written for this software
* can be used freely for any purpose. Any derived versions of this
* software must be clearly marked as such, and if the derived work is
* incompatible with the protocol description in the RFC file, it must be
* called by a name other than "ssh" or "Secure Shell".
*
* SSH2 support added by Markus Friedl.
* Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved.
* Copyright (c) 1999 Dug Song. All rights reserved.
* Copyright (c) 1999 Theo de Raadt. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "includes.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/un.h>
#include <sys/socket.h>
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
#endif
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <netdb.h>
#ifdef HAVE_POLL_H
#include <poll.h>
#endif
#include <stdarg.h>
#ifdef HAVE_STDINT_H
# include <stdint.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include "openbsd-compat/sys-queue.h"
#include "xmalloc.h"
#include "ssh.h"
#include "ssh2.h"
#include "ssherr.h"
#include "sshbuf.h"
#include "packet.h"
#include "log.h"
#include "misc.h"
#include "channels.h"
#include "compat.h"
#include "canohost.h"
#include "sshkey.h"
#include "authfd.h"
#include "pathnames.h"
#include "match.h"
/* XXX remove once we're satisfied there's no lurking bugs */
/* #define DEBUG_CHANNEL_POLL 1 */
/* -- agent forwarding */
#define NUM_SOCKS 10
/* -- tcp forwarding */
/* special-case port number meaning allow any port */
#define FWD_PERMIT_ANY_PORT 0
/* special-case wildcard meaning allow any host */
#define FWD_PERMIT_ANY_HOST "*"
/* -- X11 forwarding */
/* Maximum number of fake X11 displays to try. */
#define MAX_DISPLAYS 1000
/* Per-channel callback for pre/post IO actions */
typedef void chan_fn(struct ssh *, Channel *c);
/*
* Data structure for storing which hosts are permitted for forward requests.
* The local sides of any remote forwards are stored in this array to prevent
* a corrupt remote server from accessing arbitrary TCP/IP ports on our local
* network (which might be behind a firewall).
*/
/* XXX: streamlocal wants a path instead of host:port */
/* Overload host_to_connect; we could just make this match Forward */
/* XXX - can we use listen_host instead of listen_path? */
struct permission {
char *host_to_connect; /* Connect to 'host'. */
int port_to_connect; /* Connect to 'port'. */
char *listen_host; /* Remote side should listen address. */
char *listen_path; /* Remote side should listen path. */
int listen_port; /* Remote side should listen port. */
Channel *downstream; /* Downstream mux*/
};
/*
* Stores the forwarding permission state for a single direction (local or
* remote).
*/
struct permission_set {
/*
* List of all local permitted host/port pairs to allow for the
* user.
*/
u_int num_permitted_user;
struct permission *permitted_user;
/*
* List of all permitted host/port pairs to allow for the admin.
*/
u_int num_permitted_admin;
struct permission *permitted_admin;
/*
* If this is true, all opens/listens are permitted. This is the
* case on the server on which we have to trust the client anyway,
* and the user could do anything after logging in.
*/
int all_permitted;
};
+/* Used to record timeouts per channel type */
+struct ssh_channel_timeout {
+ char *type_pattern;
+ u_int timeout_secs;
+};
+
/* Master structure for channels state */
struct ssh_channels {
/*
* Pointer to an array containing all allocated channels. The array
* is dynamically extended as needed.
*/
Channel **channels;
/*
* Size of the channel array. All slots of the array must always be
* initialized (at least the type field); unused slots set to NULL
*/
u_int channels_alloc;
/*
* 'channel_pre*' are called just before IO to add any bits
* relevant to channels in the c->io_want bitmasks.
*
* 'channel_post*': perform any appropriate operations for
* channels which have c->io_ready events pending.
*/
chan_fn **channel_pre;
chan_fn **channel_post;
/* -- tcp forwarding */
struct permission_set local_perms;
struct permission_set remote_perms;
/* -- X11 forwarding */
/* Saved X11 local (client) display. */
char *x11_saved_display;
/* Saved X11 authentication protocol name. */
char *x11_saved_proto;
/* Saved X11 authentication data. This is the real data. */
char *x11_saved_data;
u_int x11_saved_data_len;
/* Deadline after which all X11 connections are refused */
u_int x11_refuse_time;
/*
* Fake X11 authentication data. This is what the server will be
* sending us; we should replace any occurrences of this by the
* real data.
*/
u_char *x11_fake_data;
u_int x11_fake_data_len;
/* AF_UNSPEC or AF_INET or AF_INET6 */
int IPv4or6;
+
+ /* Channel timeouts by type */
+ struct ssh_channel_timeout *timeouts;
+ size_t ntimeouts;
};
/* helper */
static void port_open_helper(struct ssh *ssh, Channel *c, char *rtype);
static const char *channel_rfwd_bind_host(const char *listen_host);
/* non-blocking connect helpers */
static int connect_next(struct channel_connect *);
static void channel_connect_ctx_free(struct channel_connect *);
static Channel *rdynamic_connect_prepare(struct ssh *, char *, char *);
static int rdynamic_connect_finish(struct ssh *, Channel *);
/* Setup helper */
static void channel_handler_init(struct ssh_channels *sc);
/* -- channel core */
void
channel_init_channels(struct ssh *ssh)
{
struct ssh_channels *sc;
if ((sc = calloc(1, sizeof(*sc))) == NULL)
fatal_f("allocation failed");
sc->channels_alloc = 10;
sc->channels = xcalloc(sc->channels_alloc, sizeof(*sc->channels));
sc->IPv4or6 = AF_UNSPEC;
channel_handler_init(sc);
ssh->chanctxt = sc;
}
Channel *
channel_by_id(struct ssh *ssh, int id)
{
Channel *c;
if (id < 0 || (u_int)id >= ssh->chanctxt->channels_alloc) {
logit_f("%d: bad id", id);
return NULL;
}
c = ssh->chanctxt->channels[id];
if (c == NULL) {
logit_f("%d: bad id: channel free", id);
return NULL;
}
return c;
}
Channel *
channel_by_remote_id(struct ssh *ssh, u_int remote_id)
{
Channel *c;
u_int i;
for (i = 0; i < ssh->chanctxt->channels_alloc; i++) {
c = ssh->chanctxt->channels[i];
if (c != NULL && c->have_remote_id && c->remote_id == remote_id)
return c;
}
return NULL;
}
/*
* Returns the channel if it is allowed to receive protocol messages.
* Private channels, like listening sockets, may not receive messages.
*/
Channel *
channel_lookup(struct ssh *ssh, int id)
{
Channel *c;
if ((c = channel_by_id(ssh, id)) == NULL)
return NULL;
switch (c->type) {
case SSH_CHANNEL_X11_OPEN:
case SSH_CHANNEL_LARVAL:
case SSH_CHANNEL_CONNECTING:
case SSH_CHANNEL_DYNAMIC:
case SSH_CHANNEL_RDYNAMIC_OPEN:
case SSH_CHANNEL_RDYNAMIC_FINISH:
case SSH_CHANNEL_OPENING:
case SSH_CHANNEL_OPEN:
case SSH_CHANNEL_ABANDONED:
case SSH_CHANNEL_MUX_PROXY:
return c;
}
logit("Non-public channel %d, type %d.", id, c->type);
return NULL;
}
+/*
+ * Add a timeout for open channels whose c->ctype (or c->xctype if it is set)
+ * match type_pattern.
+ */
+void
+channel_add_timeout(struct ssh *ssh, const char *type_pattern,
+ u_int timeout_secs)
+{
+ struct ssh_channels *sc = ssh->chanctxt;
+
+ debug2_f("channel type \"%s\" timeout %u seconds",
+ type_pattern, timeout_secs);
+ sc->timeouts = xrecallocarray(sc->timeouts, sc->ntimeouts,
+ sc->ntimeouts + 1, sizeof(*sc->timeouts));
+ sc->timeouts[sc->ntimeouts].type_pattern = xstrdup(type_pattern);
+ sc->timeouts[sc->ntimeouts].timeout_secs = timeout_secs;
+ sc->ntimeouts++;
+}
+
+/* Clears all previously-added channel timeouts */
+void
+channel_clear_timeouts(struct ssh *ssh)
+{
+ struct ssh_channels *sc = ssh->chanctxt;
+ size_t i;
+
+ debug3_f("clearing");
+ for (i = 0; i < sc->ntimeouts; i++)
+ free(sc->timeouts[i].type_pattern);
+ free(sc->timeouts);
+ sc->timeouts = NULL;
+ sc->ntimeouts = 0;
+}
+
+static u_int
+lookup_timeout(struct ssh *ssh, const char *type)
+{
+ struct ssh_channels *sc = ssh->chanctxt;
+ size_t i;
+
+ for (i = 0; i < sc->ntimeouts; i++) {
+ if (match_pattern(type, sc->timeouts[i].type_pattern))
+ return sc->timeouts[i].timeout_secs;
+ }
+
+ return 0;
+}
+
+/*
+ * Sets "extended type" of a channel; used by session layer to add additional
+ * information about channel types (e.g. shell, login, subsystem) that can then
+ * be used to select timeouts.
+ * Will reset c->inactive_deadline as a side-effect.
+ */
+void
+channel_set_xtype(struct ssh *ssh, int id, const char *xctype)
+{
+ Channel *c;
+
+ if ((c = channel_by_id(ssh, id)) == NULL)
+ fatal_f("missing channel %d", id);
+ if (c->xctype != NULL)
+ free(c->xctype);
+ c->xctype = xstrdup(xctype);
+ /* Type has changed, so look up inactivity deadline again */
+ c->inactive_deadline = lookup_timeout(ssh, c->xctype);
+ debug2_f("labeled channel %d as %s (inactive timeout %u)", id, xctype,
+ c->inactive_deadline);
+}
+
/*
* Register filedescriptors for a channel, used when allocating a channel or
* when the channel consumer/producer is ready, e.g. shell exec'd
*/
static void
channel_register_fds(struct ssh *ssh, Channel *c, int rfd, int wfd, int efd,
int extusage, int nonblock, int is_tty)
{
int val;
if (rfd != -1)
fcntl(rfd, F_SETFD, FD_CLOEXEC);
if (wfd != -1 && wfd != rfd)
fcntl(wfd, F_SETFD, FD_CLOEXEC);
if (efd != -1 && efd != rfd && efd != wfd)
fcntl(efd, F_SETFD, FD_CLOEXEC);
c->rfd = rfd;
c->wfd = wfd;
c->sock = (rfd == wfd) ? rfd : -1;
c->efd = efd;
c->extended_usage = extusage;
if ((c->isatty = is_tty) != 0)
debug2("channel %d: rfd %d isatty", c->self, c->rfd);
#ifdef _AIX
/* XXX: Later AIX versions can't push as much data to tty */
c->wfd_isatty = is_tty || isatty(c->wfd);
#endif
/* enable nonblocking mode */
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) &&
(val = fcntl(rfd, F_GETFL)) != -1 && !(val & O_NONBLOCK)) {
+ c->restore_flags[0] = val;
c->restore_block |= CHANNEL_RESTORE_RFD;
set_nonblock(rfd);
}
if (wfd != -1 && !isatty(wfd) &&
(val = fcntl(wfd, F_GETFL)) != -1 && !(val & O_NONBLOCK)) {
+ c->restore_flags[1] = val;
c->restore_block |= CHANNEL_RESTORE_WFD;
set_nonblock(wfd);
}
if (efd != -1 && !isatty(efd) &&
(val = fcntl(efd, F_GETFL)) != -1 && !(val & O_NONBLOCK)) {
+ c->restore_flags[2] = val;
c->restore_block |= CHANNEL_RESTORE_EFD;
set_nonblock(efd);
}
} else if (nonblock) {
if (rfd != -1)
set_nonblock(rfd);
if (wfd != -1)
set_nonblock(wfd);
if (efd != -1)
set_nonblock(efd);
}
}
/*
* Allocate a new channel object and set its type and socket.
*/
Channel *
channel_new(struct ssh *ssh, char *ctype, int type, int rfd, int wfd, int efd,
u_int window, u_int maxpack, int extusage, const char *remote_name,
int nonblock)
{
struct ssh_channels *sc = ssh->chanctxt;
u_int i, found = 0;
Channel *c;
int r;
/* Try to find a free slot where to put the new channel. */
for (i = 0; i < sc->channels_alloc; i++) {
if (sc->channels[i] == NULL) {
/* Found a free slot. */
found = i;
break;
}
}
if (i >= sc->channels_alloc) {
/*
* There are no free slots. Take last+1 slot and expand
* the array.
*/
found = sc->channels_alloc;
if (sc->channels_alloc > CHANNELS_MAX_CHANNELS)
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;
debug2("channel: expanding %d", sc->channels_alloc);
}
/* Initialize and return new channel. */
c = sc->channels[found] = xcalloc(1, sizeof(Channel));
if ((c->input = sshbuf_new()) == NULL ||
(c->output = sshbuf_new()) == NULL ||
(c->extended = sshbuf_new()) == NULL)
fatal_f("sshbuf_new failed");
if ((r = sshbuf_set_max_size(c->input, CHAN_INPUT_MAX)) != 0)
fatal_fr(r, "sshbuf_set_max_size");
c->ostate = CHAN_OUTPUT_OPEN;
c->istate = CHAN_INPUT_OPEN;
channel_register_fds(ssh, c, rfd, wfd, efd, extusage, nonblock, 0);
c->self = found;
c->type = type;
c->ctype = ctype;
c->local_window = window;
c->local_window_max = window;
c->local_maxpacket = maxpack;
c->remote_name = xstrdup(remote_name);
c->ctl_chan = -1;
c->delayed = 1; /* prevent call to channel_post handler */
+ c->inactive_deadline = lookup_timeout(ssh, c->ctype);
TAILQ_INIT(&c->status_confirms);
- debug("channel %d: new [%s]", found, remote_name);
+ debug("channel %d: new %s [%s] (inactive timeout: %u)",
+ found, c->ctype, remote_name, c->inactive_deadline);
return c;
}
int
channel_close_fd(struct ssh *ssh, Channel *c, int *fdp)
{
int ret, fd = *fdp;
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 */
+ /* restore blocking */
+ if (*fdp == c->rfd &&
+ (c->restore_block & CHANNEL_RESTORE_RFD) != 0)
+ (void)fcntl(*fdp, F_SETFL, c->restore_flags[0]);
+ else if (*fdp == c->wfd &&
+ (c->restore_block & CHANNEL_RESTORE_WFD) != 0)
+ (void)fcntl(*fdp, F_SETFL, c->restore_flags[1]);
+ else if (*fdp == c->efd &&
+ (c->restore_block & CHANNEL_RESTORE_EFD) != 0)
+ (void)fcntl(*fdp, F_SETFL, c->restore_flags[2]);
if (*fdp == c->rfd) {
c->io_want &= ~SSH_CHAN_IO_RFD;
c->io_ready &= ~SSH_CHAN_IO_RFD;
c->rfd = -1;
c->pfds[0] = -1;
}
if (*fdp == c->wfd) {
c->io_want &= ~SSH_CHAN_IO_WFD;
c->io_ready &= ~SSH_CHAN_IO_WFD;
c->wfd = -1;
c->pfds[1] = -1;
}
if (*fdp == c->efd) {
c->io_want &= ~SSH_CHAN_IO_EFD;
c->io_ready &= ~SSH_CHAN_IO_EFD;
c->efd = -1;
c->pfds[2] = -1;
}
if (*fdp == c->sock) {
c->io_want &= ~SSH_CHAN_IO_SOCK;
c->io_ready &= ~SSH_CHAN_IO_SOCK;
c->sock = -1;
c->pfds[3] = -1;
}
ret = close(fd);
*fdp = -1; /* probably redundant */
return ret;
}
/* Close all channel fd/socket. */
static void
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, &c->sock);
if (rfd != sock)
channel_close_fd(ssh, c, &c->rfd);
if (wfd != sock && wfd != rfd)
channel_close_fd(ssh, c, &c->wfd);
if (efd != sock && efd != rfd && efd != wfd)
channel_close_fd(ssh, c, &c->efd);
}
static void
fwd_perm_clear(struct permission *perm)
{
free(perm->host_to_connect);
free(perm->listen_host);
free(perm->listen_path);
memset(perm, 0, sizeof(*perm));
}
/* Returns an printable name for the specified forwarding permission list */
static const char *
fwd_ident(int who, int where)
{
if (who == FORWARD_ADM) {
if (where == FORWARD_LOCAL)
return "admin local";
else if (where == FORWARD_REMOTE)
return "admin remote";
} else if (who == FORWARD_USER) {
if (where == FORWARD_LOCAL)
return "user local";
else if (where == FORWARD_REMOTE)
return "user remote";
}
fatal("Unknown forward permission list %d/%d", who, where);
}
/* Returns the forwarding permission list for the specified direction */
static struct permission_set *
permission_set_get(struct ssh *ssh, int where)
{
struct ssh_channels *sc = ssh->chanctxt;
switch (where) {
case FORWARD_LOCAL:
return &sc->local_perms;
break;
case FORWARD_REMOTE:
return &sc->remote_perms;
break;
default:
fatal_f("invalid forwarding direction %d", where);
}
}
/* Returns pointers to the specified forwarding list and its element count */
static void
permission_set_get_array(struct ssh *ssh, int who, int where,
struct permission ***permpp, u_int **npermpp)
{
struct permission_set *pset = permission_set_get(ssh, where);
switch (who) {
case FORWARD_USER:
*permpp = &pset->permitted_user;
*npermpp = &pset->num_permitted_user;
break;
case FORWARD_ADM:
*permpp = &pset->permitted_admin;
*npermpp = &pset->num_permitted_admin;
break;
default:
fatal_f("invalid forwarding client %d", who);
}
}
/* Adds an entry to the specified forwarding list */
static int
permission_set_add(struct ssh *ssh, int who, int where,
const char *host_to_connect, int port_to_connect,
const char *listen_host, const char *listen_path, int listen_port,
Channel *downstream)
{
struct permission **permp;
u_int n, *npermp;
permission_set_get_array(ssh, who, where, &permp, &npermp);
if (*npermp >= INT_MAX)
fatal_f("%s overflow", fwd_ident(who, where));
*permp = xrecallocarray(*permp, *npermp, *npermp + 1, sizeof(**permp));
n = (*npermp)++;
#define MAYBE_DUP(s) ((s == NULL) ? NULL : xstrdup(s))
(*permp)[n].host_to_connect = MAYBE_DUP(host_to_connect);
(*permp)[n].port_to_connect = port_to_connect;
(*permp)[n].listen_host = MAYBE_DUP(listen_host);
(*permp)[n].listen_path = MAYBE_DUP(listen_path);
(*permp)[n].listen_port = listen_port;
(*permp)[n].downstream = downstream;
#undef MAYBE_DUP
return (int)n;
}
static void
mux_remove_remote_forwardings(struct ssh *ssh, Channel *c)
{
struct ssh_channels *sc = ssh->chanctxt;
struct permission_set *pset = &sc->local_perms;
struct permission *perm;
int r;
u_int i;
for (i = 0; i < pset->num_permitted_user; i++) {
perm = &pset->permitted_user[i];
if (perm->downstream != c)
continue;
/* cancel on the server, since mux client is gone */
debug("channel %d: cleanup remote forward for %s:%u",
c->self, perm->listen_host, perm->listen_port);
if ((r = sshpkt_start(ssh, SSH2_MSG_GLOBAL_REQUEST)) != 0 ||
(r = sshpkt_put_cstring(ssh,
"cancel-tcpip-forward")) != 0 ||
(r = sshpkt_put_u8(ssh, 0)) != 0 ||
(r = sshpkt_put_cstring(ssh,
channel_rfwd_bind_host(perm->listen_host))) != 0 ||
(r = sshpkt_put_u32(ssh, perm->listen_port)) != 0 ||
(r = sshpkt_send(ssh)) != 0) {
fatal_fr(r, "channel %i", c->self);
}
fwd_perm_clear(perm); /* unregister */
}
}
/* Free the channel and close its fd/socket. */
void
channel_free(struct ssh *ssh, Channel *c)
{
struct ssh_channels *sc = ssh->chanctxt;
char *s;
u_int i, n;
Channel *other;
struct channel_confirm *cc;
for (n = 0, i = 0; i < sc->channels_alloc; i++) {
if ((other = sc->channels[i]) == NULL)
continue;
n++;
/* detach from mux client and prepare for closing */
if (c->type == SSH_CHANNEL_MUX_CLIENT &&
other->type == SSH_CHANNEL_MUX_PROXY &&
other->mux_ctx == c) {
other->mux_ctx = NULL;
other->type = SSH_CHANNEL_OPEN;
other->istate = CHAN_INPUT_CLOSED;
other->ostate = CHAN_OUTPUT_CLOSED;
}
}
debug("channel %d: free: %s, nchannels %u", c->self,
c->remote_name ? c->remote_name : "???", n);
if (c->type == SSH_CHANNEL_MUX_CLIENT) {
mux_remove_remote_forwardings(ssh, c);
free(c->mux_ctx);
c->mux_ctx = NULL;
} else if (c->type == SSH_CHANNEL_MUX_LISTENER) {
free(c->mux_ctx);
c->mux_ctx = NULL;
}
if (log_level_get() >= SYSLOG_LEVEL_DEBUG3) {
s = channel_open_message(ssh);
debug3("channel %d: status: %s", c->self, s);
free(s);
}
channel_close_fds(ssh, c);
sshbuf_free(c->input);
sshbuf_free(c->output);
sshbuf_free(c->extended);
c->input = c->output = c->extended = NULL;
free(c->remote_name);
c->remote_name = NULL;
free(c->path);
c->path = NULL;
free(c->listening_addr);
c->listening_addr = NULL;
+ free(c->xctype);
+ c->xctype = NULL;
while ((cc = TAILQ_FIRST(&c->status_confirms)) != NULL) {
if (cc->abandon_cb != NULL)
cc->abandon_cb(ssh, c, cc->ctx);
TAILQ_REMOVE(&c->status_confirms, cc, entry);
freezero(cc, sizeof(*cc));
}
if (c->filter_cleanup != NULL && c->filter_ctx != NULL)
c->filter_cleanup(ssh, c->self, c->filter_ctx);
sc->channels[c->self] = NULL;
freezero(c, sizeof(*c));
}
void
channel_free_all(struct ssh *ssh)
{
u_int i;
struct ssh_channels *sc = ssh->chanctxt;
for (i = 0; i < sc->channels_alloc; i++)
if (sc->channels[i] != NULL)
channel_free(ssh, sc->channels[i]);
free(sc->channels);
sc->channels = NULL;
sc->channels_alloc = 0;
free(sc->x11_saved_display);
sc->x11_saved_display = NULL;
free(sc->x11_saved_proto);
sc->x11_saved_proto = NULL;
free(sc->x11_saved_data);
sc->x11_saved_data = NULL;
sc->x11_saved_data_len = 0;
free(sc->x11_fake_data);
sc->x11_fake_data = NULL;
sc->x11_fake_data_len = 0;
}
/*
* Closes the sockets/fds of all channels. This is used to close extra file
* descriptors after a fork.
*/
void
channel_close_all(struct ssh *ssh)
{
u_int i;
for (i = 0; i < ssh->chanctxt->channels_alloc; i++)
if (ssh->chanctxt->channels[i] != NULL)
channel_close_fds(ssh, ssh->chanctxt->channels[i]);
}
/*
* Stop listening to channels.
*/
void
channel_stop_listening(struct ssh *ssh)
{
u_int i;
Channel *c;
for (i = 0; i < ssh->chanctxt->channels_alloc; i++) {
c = ssh->chanctxt->channels[i];
if (c != NULL) {
switch (c->type) {
case SSH_CHANNEL_AUTH_SOCKET:
case SSH_CHANNEL_PORT_LISTENER:
case SSH_CHANNEL_RPORT_LISTENER:
case SSH_CHANNEL_X11_LISTENER:
case SSH_CHANNEL_UNIX_LISTENER:
case SSH_CHANNEL_RUNIX_LISTENER:
channel_close_fd(ssh, c, &c->sock);
channel_free(ssh, c);
break;
}
}
}
}
/*
* Returns true if no channel has too much buffered data, and false if one or
* more channel is overfull.
*/
int
channel_not_very_much_buffered_data(struct ssh *ssh)
{
u_int i;
u_int maxsize = ssh_packet_get_maxsize(ssh);
Channel *c;
for (i = 0; i < ssh->chanctxt->channels_alloc; i++) {
c = ssh->chanctxt->channels[i];
if (c == NULL || c->type != SSH_CHANNEL_OPEN)
continue;
if (sshbuf_len(c->output) > maxsize) {
debug2("channel %d: big output buffer %zu > %u",
c->self, sshbuf_len(c->output), maxsize);
return 0;
}
}
return 1;
}
/* Returns true if any channel is still open. */
int
channel_still_open(struct ssh *ssh)
{
u_int i;
Channel *c;
for (i = 0; i < ssh->chanctxt->channels_alloc; i++) {
c = ssh->chanctxt->channels[i];
if (c == NULL)
continue;
switch (c->type) {
case SSH_CHANNEL_X11_LISTENER:
case SSH_CHANNEL_PORT_LISTENER:
case SSH_CHANNEL_RPORT_LISTENER:
case SSH_CHANNEL_MUX_LISTENER:
case SSH_CHANNEL_CLOSED:
case SSH_CHANNEL_AUTH_SOCKET:
case SSH_CHANNEL_DYNAMIC:
case SSH_CHANNEL_RDYNAMIC_OPEN:
case SSH_CHANNEL_CONNECTING:
case SSH_CHANNEL_ZOMBIE:
case SSH_CHANNEL_ABANDONED:
case SSH_CHANNEL_UNIX_LISTENER:
case SSH_CHANNEL_RUNIX_LISTENER:
continue;
case SSH_CHANNEL_LARVAL:
continue;
case SSH_CHANNEL_OPENING:
case SSH_CHANNEL_OPEN:
case SSH_CHANNEL_RDYNAMIC_FINISH:
case SSH_CHANNEL_X11_OPEN:
case SSH_CHANNEL_MUX_CLIENT:
case SSH_CHANNEL_MUX_PROXY:
return 1;
default:
fatal_f("bad channel type %d", c->type);
/* NOTREACHED */
}
}
return 0;
}
/* Returns the id of an open channel suitable for keepaliving */
int
channel_find_open(struct ssh *ssh)
{
u_int i;
Channel *c;
for (i = 0; i < ssh->chanctxt->channels_alloc; i++) {
c = ssh->chanctxt->channels[i];
if (c == NULL || !c->have_remote_id)
continue;
switch (c->type) {
case SSH_CHANNEL_CLOSED:
case SSH_CHANNEL_DYNAMIC:
case SSH_CHANNEL_RDYNAMIC_OPEN:
case SSH_CHANNEL_RDYNAMIC_FINISH:
case SSH_CHANNEL_X11_LISTENER:
case SSH_CHANNEL_PORT_LISTENER:
case SSH_CHANNEL_RPORT_LISTENER:
case SSH_CHANNEL_MUX_LISTENER:
case SSH_CHANNEL_MUX_CLIENT:
case SSH_CHANNEL_MUX_PROXY:
case SSH_CHANNEL_OPENING:
case SSH_CHANNEL_CONNECTING:
case SSH_CHANNEL_ZOMBIE:
case SSH_CHANNEL_ABANDONED:
case SSH_CHANNEL_UNIX_LISTENER:
case SSH_CHANNEL_RUNIX_LISTENER:
continue;
case SSH_CHANNEL_LARVAL:
case SSH_CHANNEL_AUTH_SOCKET:
case SSH_CHANNEL_OPEN:
case SSH_CHANNEL_X11_OPEN:
return i;
default:
fatal_f("bad channel type %d", c->type);
/* NOTREACHED */
}
}
return -1;
}
/* Returns the state of the channel's extended usage flag */
const char *
channel_format_extended_usage(const Channel *c)
{
if (c->efd == -1)
return "closed";
switch (c->extended_usage) {
case CHAN_EXTENDED_WRITE:
return "write";
case CHAN_EXTENDED_READ:
return "read";
case CHAN_EXTENDED_IGNORE:
return "ignore";
default:
return "UNKNOWN";
}
}
static char *
channel_format_status(const Channel *c)
{
char *ret = NULL;
- xasprintf(&ret, "t%d %s%u i%u/%zu o%u/%zu e[%s]/%zu "
+ xasprintf(&ret, "t%d [%s] %s%u i%u/%zu o%u/%zu e[%s]/%zu "
"fd %d/%d/%d sock %d cc %d io 0x%02x/0x%02x",
- c->type,
+ c->type, c->xctype != NULL ? c->xctype : c->ctype,
c->have_remote_id ? "r" : "nr", c->remote_id,
c->istate, sshbuf_len(c->input),
c->ostate, sshbuf_len(c->output),
channel_format_extended_usage(c), sshbuf_len(c->extended),
c->rfd, c->wfd, c->efd, c->sock, c->ctl_chan,
c->io_want, c->io_ready);
return ret;
}
/*
* Returns a message describing the currently open forwarded connections,
* suitable for sending to the client. The message contains crlf pairs for
* newlines.
*/
char *
channel_open_message(struct ssh *ssh)
{
struct sshbuf *buf;
Channel *c;
u_int i;
int r;
char *cp, *ret;
if ((buf = sshbuf_new()) == NULL)
fatal_f("sshbuf_new");
if ((r = sshbuf_putf(buf,
"The following connections are open:\r\n")) != 0)
fatal_fr(r, "sshbuf_putf");
for (i = 0; i < ssh->chanctxt->channels_alloc; i++) {
c = ssh->chanctxt->channels[i];
if (c == NULL)
continue;
switch (c->type) {
case SSH_CHANNEL_X11_LISTENER:
case SSH_CHANNEL_PORT_LISTENER:
case SSH_CHANNEL_RPORT_LISTENER:
case SSH_CHANNEL_CLOSED:
case SSH_CHANNEL_AUTH_SOCKET:
case SSH_CHANNEL_ZOMBIE:
case SSH_CHANNEL_ABANDONED:
case SSH_CHANNEL_MUX_LISTENER:
case SSH_CHANNEL_UNIX_LISTENER:
case SSH_CHANNEL_RUNIX_LISTENER:
continue;
case SSH_CHANNEL_LARVAL:
case SSH_CHANNEL_OPENING:
case SSH_CHANNEL_CONNECTING:
case SSH_CHANNEL_DYNAMIC:
case SSH_CHANNEL_RDYNAMIC_OPEN:
case SSH_CHANNEL_RDYNAMIC_FINISH:
case SSH_CHANNEL_OPEN:
case SSH_CHANNEL_X11_OPEN:
case SSH_CHANNEL_MUX_PROXY:
case SSH_CHANNEL_MUX_CLIENT:
cp = channel_format_status(c);
if ((r = sshbuf_putf(buf, " #%d %.300s (%s)\r\n",
c->self, c->remote_name, cp)) != 0) {
free(cp);
fatal_fr(r, "sshbuf_putf");
}
free(cp);
continue;
default:
fatal_f("bad channel type %d", c->type);
/* NOTREACHED */
}
}
if ((ret = sshbuf_dup_string(buf)) == NULL)
fatal_f("sshbuf_dup_string");
sshbuf_free(buf);
return ret;
}
static void
open_preamble(struct ssh *ssh, const char *where, Channel *c, const char *type)
{
int r;
if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_OPEN)) != 0 ||
(r = sshpkt_put_cstring(ssh, type)) != 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_r(r, "%s: channel %i: open", where, c->self);
}
}
void
channel_send_open(struct ssh *ssh, int id)
{
Channel *c = channel_lookup(ssh, id);
int r;
if (c == NULL) {
logit("channel_send_open: %d: bad id", id);
return;
}
debug2("channel %d: send open", id);
open_preamble(ssh, __func__, c, c->ctype);
if ((r = sshpkt_send(ssh)) != 0)
fatal_fr(r, "channel %i", c->self);
}
void
channel_request_start(struct ssh *ssh, int id, char *service, int wantconfirm)
{
Channel *c = channel_lookup(ssh, id);
int r;
if (c == NULL) {
logit_f("%d: unknown channel id", id);
return;
}
if (!c->have_remote_id)
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_fr(r, "channel %i", c->self);
}
}
void
channel_register_status_confirm(struct ssh *ssh, int id,
channel_confirm_cb *cb, channel_confirm_abandon_cb *abandon_cb, void *ctx)
{
struct channel_confirm *cc;
Channel *c;
if ((c = channel_lookup(ssh, id)) == NULL)
fatal_f("%d: bad id", id);
cc = xcalloc(1, sizeof(*cc));
cc->cb = cb;
cc->abandon_cb = abandon_cb;
cc->ctx = ctx;
TAILQ_INSERT_TAIL(&c->status_confirms, cc, entry);
}
void
channel_register_open_confirm(struct ssh *ssh, int id,
channel_open_fn *fn, void *ctx)
{
Channel *c = channel_lookup(ssh, id);
if (c == NULL) {
logit_f("%d: bad id", id);
return;
}
c->open_confirm = fn;
c->open_confirm_ctx = ctx;
}
void
channel_register_cleanup(struct ssh *ssh, int id,
channel_callback_fn *fn, int do_close)
{
Channel *c = channel_by_id(ssh, id);
if (c == NULL) {
logit_f("%d: bad id", id);
return;
}
c->detach_user = fn;
c->detach_close = do_close;
}
void
channel_cancel_cleanup(struct ssh *ssh, int id)
{
Channel *c = channel_by_id(ssh, id);
if (c == NULL) {
logit_f("%d: bad id", id);
return;
}
c->detach_user = NULL;
c->detach_close = 0;
}
void
channel_register_filter(struct ssh *ssh, int id, channel_infilter_fn *ifn,
channel_outfilter_fn *ofn, channel_filter_cleanup_fn *cfn, void *ctx)
{
Channel *c = channel_lookup(ssh, id);
if (c == NULL) {
logit_f("%d: bad id", id);
return;
}
c->input_filter = ifn;
c->output_filter = ofn;
c->filter_ctx = ctx;
c->filter_cleanup = cfn;
}
void
channel_set_fds(struct ssh *ssh, int id, int rfd, int wfd, int efd,
int extusage, int nonblock, int is_tty, u_int window_max)
{
Channel *c = channel_lookup(ssh, id);
int r;
if (c == NULL || c->type != SSH_CHANNEL_LARVAL)
fatal("channel_activate for non-larval channel %d.", id);
if (!c->have_remote_id)
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;
+ c->lastused = monotime();
c->local_window = c->local_window_max = window_max;
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_window)) != 0 ||
(r = sshpkt_send(ssh)) != 0)
fatal_fr(r, "channel %i", c->self);
}
static void
channel_pre_listener(struct ssh *ssh, Channel *c)
{
c->io_want = SSH_CHAN_IO_SOCK_R;
}
static void
channel_pre_connecting(struct ssh *ssh, Channel *c)
{
debug3("channel %d: waiting for connection", c->self);
c->io_want = SSH_CHAN_IO_SOCK_W;
}
static void
channel_pre_open(struct ssh *ssh, Channel *c)
{
c->io_want = 0;
if (c->istate == CHAN_INPUT_OPEN &&
c->remote_window > 0 &&
sshbuf_len(c->input) < c->remote_window &&
sshbuf_check_reserve(c->input, CHAN_RBUF) == 0)
c->io_want |= SSH_CHAN_IO_RFD;
if (c->ostate == CHAN_OUTPUT_OPEN ||
c->ostate == CHAN_OUTPUT_WAIT_DRAIN) {
if (sshbuf_len(c->output) > 0) {
c->io_want |= SSH_CHAN_IO_WFD;
} else if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN) {
if (CHANNEL_EFD_OUTPUT_ACTIVE(c))
debug2("channel %d: "
"obuf_empty delayed efd %d/(%zu)", c->self,
c->efd, sshbuf_len(c->extended));
else
chan_obuf_empty(ssh, c);
}
}
/** XXX check close conditions, too */
if (c->efd != -1 && !(c->istate == CHAN_INPUT_CLOSED &&
c->ostate == CHAN_OUTPUT_CLOSED)) {
if (c->extended_usage == CHAN_EXTENDED_WRITE &&
sshbuf_len(c->extended) > 0)
c->io_want |= SSH_CHAN_IO_EFD_W;
else if (c->efd != -1 && !(c->flags & CHAN_EOF_SENT) &&
(c->extended_usage == CHAN_EXTENDED_READ ||
c->extended_usage == CHAN_EXTENDED_IGNORE) &&
sshbuf_len(c->extended) < c->remote_window)
c->io_want |= SSH_CHAN_IO_EFD_R;
}
/* XXX: What about efd? races? */
}
/*
* This is a special state for X11 authentication spoofing. An opened X11
* connection (when authentication spoofing is being done) remains in this
* state until the first packet has been completely read. The authentication
* data in that packet is then substituted by the real data if it matches the
* fake data, and the channel is put into normal mode.
* XXX All this happens at the client side.
* Returns: 0 = need more data, -1 = wrong cookie, 1 = ok
*/
static int
x11_open_helper(struct ssh *ssh, struct sshbuf *b)
{
struct ssh_channels *sc = ssh->chanctxt;
u_char *ucp;
u_int proto_len, data_len;
/* Is this being called after the refusal deadline? */
if (sc->x11_refuse_time != 0 &&
(u_int)monotime() >= sc->x11_refuse_time) {
verbose("Rejected X11 connection after ForwardX11Timeout "
"expired");
return -1;
}
/* Check if the fixed size part of the packet is in buffer. */
if (sshbuf_len(b) < 12)
return 0;
/* Parse the lengths of variable-length fields. */
ucp = sshbuf_mutable_ptr(b);
if (ucp[0] == 0x42) { /* Byte order MSB first. */
proto_len = 256 * ucp[6] + ucp[7];
data_len = 256 * ucp[8] + ucp[9];
} else if (ucp[0] == 0x6c) { /* Byte order LSB first. */
proto_len = ucp[6] + 256 * ucp[7];
data_len = ucp[8] + 256 * ucp[9];
} else {
debug2("Initial X11 packet contains bad byte order byte: 0x%x",
ucp[0]);
return -1;
}
/* Check if the whole packet is in buffer. */
if (sshbuf_len(b) <
12 + ((proto_len + 3) & ~3) + ((data_len + 3) & ~3))
return 0;
/* Check if authentication protocol matches. */
if (proto_len != strlen(sc->x11_saved_proto) ||
memcmp(ucp + 12, sc->x11_saved_proto, proto_len) != 0) {
debug2("X11 connection uses different authentication protocol.");
return -1;
}
/* Check if authentication data matches our fake data. */
if (data_len != sc->x11_fake_data_len ||
timingsafe_bcmp(ucp + 12 + ((proto_len + 3) & ~3),
sc->x11_fake_data, sc->x11_fake_data_len) != 0) {
debug2("X11 auth data does not match fake data.");
return -1;
}
/* Check fake data length */
if (sc->x11_fake_data_len != sc->x11_saved_data_len) {
error("X11 fake_data_len %d != saved_data_len %d",
sc->x11_fake_data_len, sc->x11_saved_data_len);
return -1;
}
/*
* Received authentication protocol and data match
* our fake data. Substitute the fake data with real
* data.
*/
memcpy(ucp + 12 + ((proto_len + 3) & ~3),
sc->x11_saved_data, sc->x11_saved_data_len);
return 1;
}
+void
+channel_force_close(struct ssh *ssh, Channel *c, int abandon)
+{
+ debug3_f("channel %d: forcibly closing", c->self);
+ if (c->istate == CHAN_INPUT_OPEN)
+ chan_read_failed(ssh, c);
+ if (c->istate == CHAN_INPUT_WAIT_DRAIN) {
+ sshbuf_reset(c->input);
+ chan_ibuf_empty(ssh, c);
+ }
+ if (c->ostate == CHAN_OUTPUT_OPEN ||
+ c->ostate == CHAN_OUTPUT_WAIT_DRAIN) {
+ sshbuf_reset(c->output);
+ chan_write_failed(ssh, c);
+ }
+ if (c->detach_user)
+ c->detach_user(ssh, c->self, 1, NULL);
+ if (c->efd != -1)
+ channel_close_fd(ssh, c, &c->efd);
+ if (abandon)
+ c->type = SSH_CHANNEL_ABANDONED;
+ /* exempt from inactivity timeouts */
+ c->inactive_deadline = 0;
+ c->lastused = 0;
+}
+
static void
channel_pre_x11_open(struct ssh *ssh, Channel *c)
{
int ret = x11_open_helper(ssh, c->output);
/* c->force_drain = 1; */
if (ret == 1) {
c->type = SSH_CHANNEL_OPEN;
+ c->lastused = monotime();
channel_pre_open(ssh, c);
} else if (ret == -1) {
- logit("X11 connection rejected because of wrong authentication.");
+ logit("X11 connection rejected because of wrong "
+ "authentication.");
debug2("X11 rejected %d i%d/o%d",
c->self, c->istate, c->ostate);
- chan_read_failed(ssh, c);
- sshbuf_reset(c->input);
- chan_ibuf_empty(ssh, c);
- sshbuf_reset(c->output);
- chan_write_failed(ssh, c);
- debug2("X11 closed %d i%d/o%d", c->self, c->istate, c->ostate);
+ channel_force_close(ssh, c, 0);
}
}
static void
channel_pre_mux_client(struct ssh *ssh, Channel *c)
{
c->io_want = 0;
if (c->istate == CHAN_INPUT_OPEN && !c->mux_pause &&
sshbuf_check_reserve(c->input, CHAN_RBUF) == 0)
c->io_want |= SSH_CHAN_IO_RFD;
if (c->istate == CHAN_INPUT_WAIT_DRAIN) {
/* clear buffer immediately (discard any partial packet) */
sshbuf_reset(c->input);
chan_ibuf_empty(ssh, c);
/* Start output drain. XXX just kill chan? */
chan_rcvd_oclose(ssh, c);
}
if (c->ostate == CHAN_OUTPUT_OPEN ||
c->ostate == CHAN_OUTPUT_WAIT_DRAIN) {
if (sshbuf_len(c->output) > 0)
c->io_want |= SSH_CHAN_IO_WFD;
else if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN)
chan_obuf_empty(ssh, c);
}
}
/* try to decode a socks4 header */
static int
channel_decode_socks4(Channel *c, struct sshbuf *input, struct sshbuf *output)
{
const u_char *p;
char *host;
u_int len, have, i, found, need;
char username[256];
struct {
u_int8_t version;
u_int8_t command;
u_int16_t dest_port;
struct in_addr dest_addr;
} s4_req, s4_rsp;
int r;
debug2("channel %d: decode socks4", c->self);
have = sshbuf_len(input);
len = sizeof(s4_req);
if (have < len)
return 0;
p = sshbuf_ptr(input);
need = 1;
/* SOCKS4A uses an invalid IP address 0.0.0.x */
if (p[4] == 0 && p[5] == 0 && p[6] == 0 && p[7] != 0) {
debug2("channel %d: socks4a request", c->self);
/* ... and needs an extra string (the hostname) */
need = 2;
}
/* Check for terminating NUL on the string(s) */
for (found = 0, i = len; i < have; i++) {
if (p[i] == '\0') {
found++;
if (found == need)
break;
}
if (i > 1024) {
/* the peer is probably sending garbage */
debug("channel %d: decode socks4: too long",
c->self);
return -1;
}
}
if (found < need)
return 0;
if ((r = sshbuf_get(input, &s4_req.version, 1)) != 0 ||
(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_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: 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_fr(r, "channel %d: consume", c->self);
free(c->path);
c->path = NULL;
if (need == 1) { /* SOCKS4: one string */
host = inet_ntoa(s4_req.dest_addr);
c->path = xstrdup(host);
} else { /* SOCKS4A: two strings */
have = sshbuf_len(input);
p = sshbuf_ptr(input);
if (memchr(p, '\0', have) == NULL) {
error("channel %d: decode socks4a: host not nul "
"terminated", c->self);
return -1;
}
len = strlen(p);
debug2("channel %d: decode socks4a: host %s/%d",
c->self, p, len);
len++; /* trailing '\0' */
if (len > NI_MAXHOST) {
error("channel %d: hostname \"%.100s\" too long",
c->self, p);
return -1;
}
c->path = xstrdup(p);
if ((r = sshbuf_consume(input, len)) != 0)
fatal_fr(r, "channel %d: consume", c->self);
}
c->host_port = ntohs(s4_req.dest_port);
debug2("channel %d: dynamic request: socks4 host %s port %u command %u",
c->self, c->path, c->host_port, s4_req.command);
if (s4_req.command != 1) {
debug("channel %d: cannot handle: %s cn %d",
c->self, need == 1 ? "SOCKS4" : "SOCKS4A", s4_req.command);
return -1;
}
s4_rsp.version = 0; /* vn: 0 for reply */
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_fr(r, "channel %d: append reply", c->self);
return 1;
}
/* try to decode a socks5 header */
#define SSH_SOCKS5_AUTHDONE 0x1000
#define SSH_SOCKS5_NOAUTH 0x00
#define SSH_SOCKS5_IPV4 0x01
#define SSH_SOCKS5_DOMAIN 0x03
#define SSH_SOCKS5_IPV6 0x04
#define SSH_SOCKS5_CONNECT 0x01
#define SSH_SOCKS5_SUCCESS 0x00
static int
channel_decode_socks5(Channel *c, struct sshbuf *input, struct sshbuf *output)
{
/* XXX use get/put_u8 instead of trusting struct padding */
struct {
u_int8_t version;
u_int8_t command;
u_int8_t reserved;
u_int8_t atyp;
} s5_req, s5_rsp;
u_int16_t dest_port;
char dest_addr[255+1], ntop[INET6_ADDRSTRLEN];
const u_char *p;
u_int have, need, i, found, nmethods, addrlen, af;
int r;
debug2("channel %d: decode socks5", c->self);
p = sshbuf_ptr(input);
if (p[0] != 0x05)
return -1;
have = sshbuf_len(input);
if (!(c->flags & SSH_SOCKS5_AUTHDONE)) {
/* format: ver | nmethods | methods */
if (have < 2)
return 0;
nmethods = p[1];
if (have < nmethods + 2)
return 0;
/* look for method: "NO AUTHENTICATION REQUIRED" */
for (found = 0, i = 2; i < nmethods + 2; i++) {
if (p[i] == SSH_SOCKS5_NOAUTH) {
found = 1;
break;
}
}
if (!found) {
debug("channel %d: method SSH_SOCKS5_NOAUTH not found",
c->self);
return -1;
}
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_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 */
}
debug2("channel %d: socks5 post auth", c->self);
if (have < sizeof(s5_req)+1)
return 0; /* need more */
memcpy(&s5_req, p, sizeof(s5_req));
if (s5_req.version != 0x05 ||
s5_req.command != SSH_SOCKS5_CONNECT ||
s5_req.reserved != 0x00) {
debug2("channel %d: only socks5 connect supported", c->self);
return -1;
}
switch (s5_req.atyp){
case SSH_SOCKS5_IPV4:
addrlen = 4;
af = AF_INET;
break;
case SSH_SOCKS5_DOMAIN:
addrlen = p[sizeof(s5_req)];
af = -1;
break;
case SSH_SOCKS5_IPV6:
addrlen = 16;
af = AF_INET6;
break;
default:
debug2("channel %d: bad socks5 atyp %d", c->self, s5_req.atyp);
return -1;
}
need = sizeof(s5_req) + addrlen + 2;
if (s5_req.atyp == SSH_SOCKS5_DOMAIN)
need++;
if (have < need)
return 0;
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_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_r(r, "channel %d: parse addr/port", c->self);
return -1;
}
dest_addr[addrlen] = '\0';
free(c->path);
c->path = NULL;
if (s5_req.atyp == SSH_SOCKS5_DOMAIN) {
if (addrlen >= NI_MAXHOST) {
error("channel %d: dynamic request: socks5 hostname "
"\"%.100s\" too long", c->self, dest_addr);
return -1;
}
c->path = xstrdup(dest_addr);
} else {
if (inet_ntop(af, dest_addr, ntop, sizeof(ntop)) == NULL)
return -1;
c->path = xstrdup(ntop);
}
c->host_port = ntohs(dest_port);
debug2("channel %d: dynamic request: socks5 host %s port %u command %u",
c->self, c->path, c->host_port, s5_req.command);
s5_rsp.version = 0x05;
s5_rsp.command = SSH_SOCKS5_SUCCESS;
s5_rsp.reserved = 0; /* ignored */
s5_rsp.atyp = SSH_SOCKS5_IPV4;
dest_port = 0; /* ignored */
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_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, int nonblock)
{
Channel *c;
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);
c->path = xstrdup(host_to_connect);
c->host_port = port_to_connect;
c->listening_port = 0;
c->force_drain = 1;
channel_register_fds(ssh, c, in, out, -1, 0, 1, 0);
port_open_helper(ssh, c, "direct-tcpip");
return c;
}
/* dynamic port forwarding */
static void
channel_pre_dynamic(struct ssh *ssh, Channel *c)
{
const u_char *p;
u_int have;
int ret;
c->io_want = 0;
have = sshbuf_len(c->input);
debug2("channel %d: pre_dynamic: have %d", c->self, have);
/* sshbuf_dump(c->input, stderr); */
/* check if the fixed size part of the packet is in buffer. */
if (have < 3) {
/* need more */
c->io_want |= SSH_CHAN_IO_RFD;
return;
}
/* try to guess the protocol */
p = sshbuf_ptr(c->input);
/* XXX sshbuf_peek_u8? */
switch (p[0]) {
case 0x04:
ret = channel_decode_socks4(c, c->input, c->output);
break;
case 0x05:
ret = channel_decode_socks5(c, c->input, c->output);
break;
default:
ret = -1;
break;
}
if (ret < 0) {
chan_mark_dead(ssh, c);
} else if (ret == 0) {
debug2("channel %d: pre_dynamic: need more", c->self);
/* need more */
c->io_want |= SSH_CHAN_IO_RFD;
if (sshbuf_len(c->output))
c->io_want |= SSH_CHAN_IO_WFD;
} else {
/* switch to the next state */
c->type = SSH_CHANNEL_OPENING;
port_open_helper(ssh, c, "direct-tcpip");
}
}
/* simulate read-error */
static void
rdynamic_close(struct ssh *ssh, Channel *c)
{
c->type = SSH_CHANNEL_OPEN;
- chan_read_failed(ssh, c);
- sshbuf_reset(c->input);
- chan_ibuf_empty(ssh, c);
- sshbuf_reset(c->output);
- chan_write_failed(ssh, c);
+ channel_force_close(ssh, c, 0);
}
/* reverse dynamic port forwarding */
static void
channel_before_prepare_io_rdynamic(struct ssh *ssh, Channel *c)
{
const u_char *p;
u_int have, len;
int r, ret;
have = sshbuf_len(c->output);
debug2("channel %d: pre_rdynamic: have %d", c->self, have);
/* sshbuf_dump(c->output, stderr); */
/* EOF received */
if (c->flags & CHAN_EOF_RCVD) {
if ((r = sshbuf_consume(c->output, have)) != 0)
fatal_fr(r, "channel %d: consume", c->self);
rdynamic_close(ssh, c);
return;
}
/* check if the fixed size part of the packet is in buffer. */
if (have < 3)
return;
/* try to guess the protocol */
p = sshbuf_ptr(c->output);
switch (p[0]) {
case 0x04:
/* switch input/output for reverse forwarding */
ret = channel_decode_socks4(c, c->output, c->input);
break;
case 0x05:
ret = channel_decode_socks5(c, c->output, c->input);
break;
default:
ret = -1;
break;
}
if (ret < 0) {
rdynamic_close(ssh, c);
} else if (ret == 0) {
debug2("channel %d: pre_rdynamic: need more", c->self);
/* send socks request to peer */
len = sshbuf_len(c->input);
if (len > 0 && len < c->remote_window) {
if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_DATA)) != 0 ||
(r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
(r = sshpkt_put_stringb(ssh, c->input)) != 0 ||
(r = sshpkt_send(ssh)) != 0) {
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) {
/* the connect failed */
rdynamic_close(ssh, c);
}
}
/* This is our fake X11 server socket. */
static void
channel_post_x11_listener(struct ssh *ssh, Channel *c)
{
Channel *nc;
struct sockaddr_storage addr;
int r, newsock, oerrno, remote_port;
socklen_t addrlen;
char buf[16384], *remote_ipaddr;
if ((c->io_ready & SSH_CHAN_IO_SOCK_R) == 0)
return;
debug("X11 connection requested.");
addrlen = sizeof(addr);
newsock = accept(c->sock, (struct sockaddr *)&addr, &addrlen);
if (c->single_connection) {
oerrno = errno;
debug2("single_connection: closing X11 listener.");
channel_close_fd(ssh, c, &c->sock);
chan_mark_dead(ssh, c);
errno = oerrno;
}
if (newsock == -1) {
if (errno != EINTR && errno != EWOULDBLOCK &&
errno != ECONNABORTED)
error("accept: %.100s", strerror(errno));
if (errno == EMFILE || errno == ENFILE)
c->notbefore = monotime() + 1;
return;
}
set_nodelay(newsock);
remote_ipaddr = get_peer_ipaddr(newsock);
remote_port = get_peer_port(newsock);
snprintf(buf, sizeof buf, "X11 connection from %.200s port %d",
remote_ipaddr, remote_port);
- nc = channel_new(ssh, "accepted x11 socket",
+ nc = channel_new(ssh, "x11-connection",
SSH_CHANNEL_OPENING, newsock, newsock, -1,
c->local_window_max, c->local_maxpacket, 0, buf, 1);
open_preamble(ssh, __func__, nc, "x11");
if ((r = sshpkt_put_cstring(ssh, remote_ipaddr)) != 0 ||
(r = sshpkt_put_u32(ssh, remote_port)) != 0) {
fatal_fr(r, "channel %i: reply", c->self);
}
if ((r = sshpkt_send(ssh)) != 0)
fatal_fr(r, "channel %i: send", c->self);
free(remote_ipaddr);
}
static void
port_open_helper(struct ssh *ssh, Channel *c, char *rtype)
{
char *local_ipaddr = get_local_ipaddr(c->sock);
int local_port = c->sock == -1 ? 65536 : get_local_port(c->sock);
char *remote_ipaddr = get_peer_ipaddr(c->sock);
int remote_port = get_peer_port(c->sock);
int r;
if (remote_port == -1) {
/* Fake addr/port to appease peers that validate it (Tectia) */
free(remote_ipaddr);
remote_ipaddr = xstrdup("127.0.0.1");
remote_port = 65535;
}
free(c->remote_name);
xasprintf(&c->remote_name,
"%s: listening port %d for %.100s port %d, "
"connect from %.200s port %d to %.100s port %d",
rtype, c->listening_port, c->path, c->host_port,
remote_ipaddr, remote_port, local_ipaddr, local_port);
open_preamble(ssh, __func__, c, 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_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_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_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_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_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_fr(r, "channel %i: reply", c->self);
}
if ((r = sshpkt_send(ssh)) != 0)
fatal_fr(r, "channel %i: send", c->self);
free(remote_ipaddr);
free(local_ipaddr);
}
void
channel_set_x11_refuse_time(struct ssh *ssh, u_int refuse_time)
{
ssh->chanctxt->x11_refuse_time = refuse_time;
}
/*
* This socket is listening for connections to a forwarded TCP/IP port.
*/
static void
channel_post_port_listener(struct ssh *ssh, Channel *c)
{
Channel *nc;
struct sockaddr_storage addr;
int newsock, nextstate;
socklen_t addrlen;
char *rtype;
if ((c->io_ready & SSH_CHAN_IO_SOCK_R) == 0)
return;
debug("Connection to port %d forwarding to %.100s port %d requested.",
c->listening_port, c->path, c->host_port);
if (c->type == SSH_CHANNEL_RPORT_LISTENER) {
nextstate = SSH_CHANNEL_OPENING;
rtype = "forwarded-tcpip";
} else if (c->type == SSH_CHANNEL_RUNIX_LISTENER) {
nextstate = SSH_CHANNEL_OPENING;
rtype = "forwarded-streamlocal@openssh.com";
} else if (c->host_port == PORT_STREAMLOCAL) {
nextstate = SSH_CHANNEL_OPENING;
rtype = "direct-streamlocal@openssh.com";
} else if (c->host_port == 0) {
nextstate = SSH_CHANNEL_DYNAMIC;
rtype = "dynamic-tcpip";
} else {
nextstate = SSH_CHANNEL_OPENING;
rtype = "direct-tcpip";
}
addrlen = sizeof(addr);
newsock = accept(c->sock, (struct sockaddr *)&addr, &addrlen);
if (newsock == -1) {
if (errno != EINTR && errno != EWOULDBLOCK &&
errno != ECONNABORTED)
error("accept: %.100s", strerror(errno));
if (errno == EMFILE || errno == ENFILE)
c->notbefore = monotime() + 1;
return;
}
if (c->host_port != PORT_STREAMLOCAL)
set_nodelay(newsock);
nc = channel_new(ssh, rtype, nextstate, newsock, newsock, -1,
c->local_window_max, c->local_maxpacket, 0, rtype, 1);
nc->listening_port = c->listening_port;
nc->host_port = c->host_port;
if (c->path != NULL)
nc->path = xstrdup(c->path);
if (nextstate != SSH_CHANNEL_DYNAMIC)
port_open_helper(ssh, nc, rtype);
}
/*
* This is the authentication agent socket listening for connections from
* clients.
*/
static void
channel_post_auth_listener(struct ssh *ssh, Channel *c)
{
Channel *nc;
int r, newsock;
struct sockaddr_storage addr;
socklen_t addrlen;
if ((c->io_ready & SSH_CHAN_IO_SOCK_R) == 0)
return;
addrlen = sizeof(addr);
newsock = accept(c->sock, (struct sockaddr *)&addr, &addrlen);
if (newsock == -1) {
error("accept from auth socket: %.100s", strerror(errno));
if (errno == EMFILE || errno == ENFILE)
c->notbefore = monotime() + 1;
return;
}
- nc = channel_new(ssh, "accepted auth socket",
+ nc = channel_new(ssh, "agent-connection",
SSH_CHANNEL_OPENING, newsock, newsock, -1,
c->local_window_max, c->local_maxpacket,
0, "accepted auth socket", 1);
open_preamble(ssh, __func__, nc, "auth-agent@openssh.com");
if ((r = sshpkt_send(ssh)) != 0)
fatal_fr(r, "channel %i", c->self);
}
static void
channel_post_connecting(struct ssh *ssh, Channel *c)
{
int err = 0, sock, isopen, r;
socklen_t sz = sizeof(err);
if ((c->io_ready & SSH_CHAN_IO_SOCK_W) == 0)
return;
if (!c->have_remote_id)
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) {
err = errno;
error("getsockopt SO_ERROR failed");
}
if (err == 0) {
debug("channel %d: connected to %s port %d",
c->self, c->connect_ctx.host, c->connect_ctx.port);
channel_connect_ctx_free(&c->connect_ctx);
c->type = SSH_CHANNEL_OPEN;
+ c->lastused = monotime();
if (isopen) {
/* no message necessary */
} else {
if ((r = sshpkt_start(ssh,
SSH2_MSG_CHANNEL_OPEN_CONFIRMATION)) != 0 ||
(r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
(r = sshpkt_put_u32(ssh, c->self)) != 0 ||
(r = sshpkt_put_u32(ssh, c->local_window)) != 0 ||
(r = sshpkt_put_u32(ssh, c->local_maxpacket)) != 0 ||
(r = sshpkt_send(ssh)) != 0)
fatal_fr(r, "channel %i open confirm", c->self);
}
} else {
debug("channel %d: connection failed: %s",
c->self, strerror(err));
/* Try next address, if any */
if ((sock = connect_next(&c->connect_ctx)) > 0) {
close(c->sock);
c->sock = c->rfd = c->wfd = sock;
return;
}
/* Exhausted all addresses */
error("connect_to %.100s port %d: failed.",
c->connect_ctx.host, c->connect_ctx.port);
channel_connect_ctx_free(&c->connect_ctx);
if (isopen) {
rdynamic_close(ssh, c);
} else {
if ((r = sshpkt_start(ssh,
SSH2_MSG_CHANNEL_OPEN_FAILURE)) != 0 ||
(r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
(r = sshpkt_put_u32(ssh,
SSH2_OPEN_CONNECT_FAILED)) != 0 ||
(r = sshpkt_put_cstring(ssh, strerror(err))) != 0 ||
(r = sshpkt_put_cstring(ssh, "")) != 0 ||
(r = sshpkt_send(ssh)) != 0)
fatal_fr(r, "channel %i: failure", c->self);
chan_mark_dead(ssh, c);
}
}
}
static int
channel_handle_rfd(struct ssh *ssh, Channel *c)
{
char buf[CHAN_RBUF];
ssize_t len;
int r, force;
- size_t have, avail, maxlen = CHANNEL_MAX_READ;
+ size_t nr = 0, have, avail, maxlen = CHANNEL_MAX_READ;
int pty_zeroread = 0;
#ifdef PTY_ZEROREAD
/* Bug on AIX: read(1) can return 0 for a non-closed fd */
pty_zeroread = c->isatty;
#endif
force = c->isatty && c->detach_close && c->istate != CHAN_INPUT_CLOSED;
if (!force && (c->io_ready & SSH_CHAN_IO_RFD) == 0)
return 1;
if ((avail = sshbuf_avail(c->input)) == 0)
return 1; /* Shouldn't happen */
/*
* For "simple" channels (i.e. not datagram or filtered), we can
* read directly to the channel buffer.
*/
if (!pty_zeroread && c->input_filter == NULL && !c->datagram) {
/* Only OPEN channels have valid rwin */
if (c->type == SSH_CHANNEL_OPEN) {
if ((have = sshbuf_len(c->input)) >= c->remote_window)
return 1; /* shouldn't happen */
if (maxlen > c->remote_window - have)
maxlen = c->remote_window - have;
}
if (maxlen > avail)
maxlen = avail;
- if ((r = sshbuf_read(c->rfd, c->input, maxlen, NULL)) != 0) {
+ if ((r = sshbuf_read(c->rfd, c->input, maxlen, &nr)) != 0) {
if (errno == EINTR || (!force &&
(errno == EAGAIN || errno == EWOULDBLOCK)))
return 1;
debug2("channel %d: read failed rfd %d maxlen %zu: %s",
c->self, c->rfd, maxlen, ssh_err(r));
goto rfail;
}
+ if (nr != 0)
+ c->lastused = monotime();
return 1;
}
errno = 0;
len = read(c->rfd, buf, sizeof(buf));
/* fixup AIX zero-length read with errno set to look more like errors */
if (pty_zeroread && len == 0 && errno != 0)
len = -1;
if (len == -1 && (errno == EINTR ||
((errno == EAGAIN || errno == EWOULDBLOCK) && !force)))
return 1;
if (len < 0 || (!pty_zeroread && len == 0)) {
debug2("channel %d: read<=0 rfd %d len %zd: %s",
c->self, c->rfd, len,
len == 0 ? "closed" : strerror(errno));
rfail:
if (c->type != SSH_CHANNEL_OPEN) {
debug2("channel %d: not open", c->self);
chan_mark_dead(ssh, c);
return -1;
} else {
chan_read_failed(ssh, c);
}
return -1;
}
+ c->lastused = monotime();
if (c->input_filter != NULL) {
if (c->input_filter(ssh, c, buf, len) == -1) {
debug2("channel %d: filter stops", c->self);
chan_read_failed(ssh, c);
}
} else if (c->datagram) {
if ((r = sshbuf_put_string(c->input, buf, len)) != 0)
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;
}
static int
channel_handle_wfd(struct ssh *ssh, Channel *c)
{
struct termios tio;
u_char *data = NULL, *buf; /* XXX const; need filter API change */
size_t dlen, olen = 0;
int r, len;
if ((c->io_ready & SSH_CHAN_IO_WFD) == 0)
return 1;
if (sshbuf_len(c->output) == 0)
return 1;
/* Send buffered output data to the socket. */
olen = sshbuf_len(c->output);
if (c->output_filter != NULL) {
if ((buf = c->output_filter(ssh, c, &data, &dlen)) == NULL) {
debug2("channel %d: filter stops", c->self);
if (c->type != SSH_CHANNEL_OPEN)
chan_mark_dead(ssh, c);
else
chan_write_failed(ssh, c);
return -1;
}
} else if (c->datagram) {
if ((r = sshbuf_get_string(c->output, &data, &dlen)) != 0)
fatal_fr(r, "channel %i: get datagram", c->self);
buf = data;
} else {
buf = data = sshbuf_mutable_ptr(c->output);
dlen = sshbuf_len(c->output);
}
if (c->datagram) {
/* ignore truncated writes, datagrams might get lost */
len = write(c->wfd, buf, dlen);
free(data);
if (len == -1 && (errno == EINTR || errno == EAGAIN ||
errno == EWOULDBLOCK))
return 1;
if (len <= 0)
goto write_fail;
goto out;
}
#ifdef _AIX
/* XXX: Later AIX versions can't push as much data to tty */
if (c->wfd_isatty)
dlen = MINIMUM(dlen, 8*1024);
#endif
len = write(c->wfd, buf, dlen);
if (len == -1 &&
(errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK))
return 1;
if (len <= 0) {
write_fail:
if (c->type != SSH_CHANNEL_OPEN) {
debug2("channel %d: not open", c->self);
chan_mark_dead(ssh, c);
return -1;
} else {
chan_write_failed(ssh, c);
}
return -1;
}
+ c->lastused = monotime();
#ifndef BROKEN_TCGETATTR_ICANON
if (c->isatty && dlen >= 1 && buf[0] != '\r') {
if (tcgetattr(c->wfd, &tio) == 0 &&
!(tio.c_lflag & ECHO) && (tio.c_lflag & ICANON)) {
/*
* Simulate echo to reduce the impact of
* traffic analysis. We need to match the
* size of a SSH2_MSG_CHANNEL_DATA message
* (4 byte channel id + buf)
*/
if ((r = sshpkt_msg_ignore(ssh, 4+len)) != 0 ||
(r = sshpkt_send(ssh)) != 0)
fatal_fr(r, "channel %i: ignore", c->self);
}
}
#endif /* BROKEN_TCGETATTR_ICANON */
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);
return 1;
}
static int
channel_handle_efd_write(struct ssh *ssh, Channel *c)
{
int r;
ssize_t len;
if ((c->io_ready & SSH_CHAN_IO_EFD_W) == 0)
return 1;
if (sshbuf_len(c->extended) == 0)
return 1;
len = write(c->efd, sshbuf_ptr(c->extended),
sshbuf_len(c->extended));
debug2("channel %d: written %zd to efd %d", c->self, len, c->efd);
if (len == -1 && (errno == EINTR || errno == EAGAIN ||
errno == EWOULDBLOCK))
return 1;
if (len <= 0) {
debug2("channel %d: closing write-efd %d", c->self, c->efd);
channel_close_fd(ssh, c, &c->efd);
} else {
if ((r = sshbuf_consume(c->extended, len)) != 0)
fatal_fr(r, "channel %i: consume", c->self);
c->local_consumed += len;
+ c->lastused = monotime();
}
return 1;
}
static int
channel_handle_efd_read(struct ssh *ssh, Channel *c)
{
char buf[CHAN_RBUF];
ssize_t len;
int r, force;
force = c->isatty && c->detach_close && c->istate != CHAN_INPUT_CLOSED;
if (!force && (c->io_ready & SSH_CHAN_IO_EFD_R) == 0)
return 1;
len = read(c->efd, buf, sizeof(buf));
debug2("channel %d: read %zd from efd %d", c->self, len, c->efd);
if (len == -1 && (errno == EINTR || ((errno == EAGAIN ||
errno == EWOULDBLOCK) && !force)))
return 1;
if (len <= 0) {
debug2("channel %d: closing read-efd %d", c->self, c->efd);
channel_close_fd(ssh, c, &c->efd);
- } else if (c->extended_usage == CHAN_EXTENDED_IGNORE)
+ return 1;
+ }
+ c->lastused = monotime();
+ 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;
}
static int
channel_handle_efd(struct ssh *ssh, Channel *c)
{
if (c->efd == -1)
return 1;
/** XXX handle drain efd, too */
if (c->extended_usage == CHAN_EXTENDED_WRITE)
return channel_handle_efd_write(ssh, c);
else if (c->extended_usage == CHAN_EXTENDED_READ ||
c->extended_usage == CHAN_EXTENDED_IGNORE)
return channel_handle_efd_read(ssh, c);
return 1;
}
static int
channel_check_window(struct ssh *ssh, Channel *c)
{
int r;
if (c->type == SSH_CHANNEL_OPEN &&
!(c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD)) &&
((c->local_window_max - c->local_window >
c->local_maxpacket*3) ||
c->local_window < c->local_window_max/2) &&
c->local_consumed > 0) {
if (!c->have_remote_id)
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_fr(r, "channel %i", c->self);
}
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;
}
return 1;
}
static void
channel_post_open(struct ssh *ssh, Channel *c)
{
channel_handle_rfd(ssh, c);
channel_handle_wfd(ssh, c);
channel_handle_efd(ssh, c);
channel_check_window(ssh, c);
}
static u_int
read_mux(struct ssh *ssh, Channel *c, u_int need)
{
char buf[CHAN_RBUF];
ssize_t len;
u_int rlen;
int r;
if (sshbuf_len(c->input) < need) {
rlen = need - sshbuf_len(c->input);
len = read(c->rfd, buf, MINIMUM(rlen, CHAN_RBUF));
if (len == -1 && (errno == EINTR || errno == EAGAIN))
return sshbuf_len(c->input);
if (len <= 0) {
debug2("channel %d: ctl read<=0 rfd %d len %zd",
c->self, c->rfd, len);
chan_read_failed(ssh, c);
return 0;
} else if ((r = sshbuf_put(c->input, buf, len)) != 0)
fatal_fr(r, "channel %i: append", c->self);
}
return sshbuf_len(c->input);
}
static void
channel_post_mux_client_read(struct ssh *ssh, Channel *c)
{
u_int need;
if ((c->io_ready & SSH_CHAN_IO_RFD) == 0)
return;
if (c->istate != CHAN_INPUT_OPEN && c->istate != CHAN_INPUT_WAIT_DRAIN)
return;
if (c->mux_pause)
return;
/*
* Don't not read past the precise end of packets to
* avoid disrupting fd passing.
*/
if (read_mux(ssh, c, 4) < 4) /* read header */
return;
/* XXX sshbuf_peek_u32 */
need = PEEK_U32(sshbuf_ptr(c->input));
#define CHANNEL_MUX_MAX_PACKET (256 * 1024)
if (need > CHANNEL_MUX_MAX_PACKET) {
debug2("channel %d: packet too big %u > %u",
c->self, CHANNEL_MUX_MAX_PACKET, need);
chan_rcvd_oclose(ssh, c);
return;
}
if (read_mux(ssh, c, need + 4) < need + 4) /* read body */
return;
if (c->mux_rcb(ssh, c) != 0) {
debug("channel %d: mux_rcb failed", c->self);
chan_mark_dead(ssh, c);
return;
}
}
static void
channel_post_mux_client_write(struct ssh *ssh, Channel *c)
{
ssize_t len;
int r;
if ((c->io_ready & SSH_CHAN_IO_WFD) == 0)
return;
if (sshbuf_len(c->output) == 0)
return;
len = write(c->wfd, sshbuf_ptr(c->output), sshbuf_len(c->output));
if (len == -1 && (errno == EINTR || errno == EAGAIN))
return;
if (len <= 0) {
chan_mark_dead(ssh, c);
return;
}
if ((r = sshbuf_consume(c->output, len)) != 0)
fatal_fr(r, "channel %i: consume", c->self);
}
static void
channel_post_mux_client(struct ssh *ssh, Channel *c)
{
channel_post_mux_client_read(ssh, c);
channel_post_mux_client_write(ssh, c);
}
static void
channel_post_mux_listener(struct ssh *ssh, Channel *c)
{
Channel *nc;
struct sockaddr_storage addr;
socklen_t addrlen;
int newsock;
uid_t euid;
gid_t egid;
if ((c->io_ready & SSH_CHAN_IO_SOCK_R) == 0)
return;
debug("multiplexing control connection");
/*
* Accept connection on control socket
*/
memset(&addr, 0, sizeof(addr));
addrlen = sizeof(addr);
if ((newsock = accept(c->sock, (struct sockaddr*)&addr,
&addrlen)) == -1) {
error_f("accept: %s", strerror(errno));
if (errno == EMFILE || errno == ENFILE)
c->notbefore = monotime() + 1;
return;
}
if (getpeereid(newsock, &euid, &egid) == -1) {
error_f("getpeereid failed: %s", strerror(errno));
close(newsock);
return;
}
if ((euid != 0) && (getuid() != euid)) {
error("multiplex uid mismatch: peer euid %u != uid %u",
(u_int)euid, (u_int)getuid());
close(newsock);
return;
}
- nc = channel_new(ssh, "multiplex client", SSH_CHANNEL_MUX_CLIENT,
+ nc = channel_new(ssh, "mux-control", SSH_CHANNEL_MUX_CLIENT,
newsock, newsock, -1, c->local_window_max,
c->local_maxpacket, 0, "mux-control", 1);
nc->mux_rcb = c->mux_rcb;
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 */
nc->flags |= CHAN_LOCAL;
}
static void
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_f("allocation failed");
pre[SSH_CHANNEL_OPEN] = &channel_pre_open;
pre[SSH_CHANNEL_X11_OPEN] = &channel_pre_x11_open;
pre[SSH_CHANNEL_PORT_LISTENER] = &channel_pre_listener;
pre[SSH_CHANNEL_RPORT_LISTENER] = &channel_pre_listener;
pre[SSH_CHANNEL_UNIX_LISTENER] = &channel_pre_listener;
pre[SSH_CHANNEL_RUNIX_LISTENER] = &channel_pre_listener;
pre[SSH_CHANNEL_X11_LISTENER] = &channel_pre_listener;
pre[SSH_CHANNEL_AUTH_SOCKET] = &channel_pre_listener;
pre[SSH_CHANNEL_CONNECTING] = &channel_pre_connecting;
pre[SSH_CHANNEL_DYNAMIC] = &channel_pre_dynamic;
pre[SSH_CHANNEL_RDYNAMIC_FINISH] = &channel_pre_connecting;
pre[SSH_CHANNEL_MUX_LISTENER] = &channel_pre_listener;
pre[SSH_CHANNEL_MUX_CLIENT] = &channel_pre_mux_client;
post[SSH_CHANNEL_OPEN] = &channel_post_open;
post[SSH_CHANNEL_PORT_LISTENER] = &channel_post_port_listener;
post[SSH_CHANNEL_RPORT_LISTENER] = &channel_post_port_listener;
post[SSH_CHANNEL_UNIX_LISTENER] = &channel_post_port_listener;
post[SSH_CHANNEL_RUNIX_LISTENER] = &channel_post_port_listener;
post[SSH_CHANNEL_X11_LISTENER] = &channel_post_x11_listener;
post[SSH_CHANNEL_AUTH_SOCKET] = &channel_post_auth_listener;
post[SSH_CHANNEL_CONNECTING] = &channel_post_connecting;
post[SSH_CHANNEL_DYNAMIC] = &channel_post_open;
post[SSH_CHANNEL_RDYNAMIC_FINISH] = &channel_post_connecting;
post[SSH_CHANNEL_MUX_LISTENER] = &channel_post_mux_listener;
post[SSH_CHANNEL_MUX_CLIENT] = &channel_post_mux_client;
sc->channel_pre = pre;
sc->channel_post = post;
}
/* gc dead channels */
static void
channel_garbage_collect(struct ssh *ssh, Channel *c)
{
if (c == NULL)
return;
if (c->detach_user != NULL) {
if (!chan_is_dead(ssh, c, c->detach_close))
return;
debug2("channel %d: gc: notify user", c->self);
- c->detach_user(ssh, c->self, NULL);
+ c->detach_user(ssh, c->self, 0, NULL);
/* if we still have a callback */
if (c->detach_user != NULL)
return;
debug2("channel %d: gc: user detached", c->self);
}
if (!chan_is_dead(ssh, c, 1))
return;
debug2("channel %d: garbage collecting", c->self);
channel_free(ssh, c);
}
enum channel_table { CHAN_PRE, CHAN_POST };
static void
-channel_handler(struct ssh *ssh, int table, time_t *unpause_secs)
+channel_handler(struct ssh *ssh, int table, struct timespec *timeout)
{
struct ssh_channels *sc = ssh->chanctxt;
chan_fn **ftab = table == CHAN_PRE ? sc->channel_pre : sc->channel_post;
u_int i, oalloc;
Channel *c;
time_t now;
now = monotime();
- if (unpause_secs != NULL)
- *unpause_secs = 0;
for (i = 0, oalloc = sc->channels_alloc; i < oalloc; i++) {
c = sc->channels[i];
if (c == NULL)
continue;
/* Try to keep IO going while rekeying */
if (ssh_packet_is_rekeying(ssh) && c->type != SSH_CHANNEL_OPEN)
continue;
if (c->delayed) {
if (table == CHAN_PRE)
c->delayed = 0;
else
continue;
}
if (ftab[c->type] != NULL) {
- /*
- * Run handlers that are not paused.
- */
- if (c->notbefore <= now)
+ if (table == CHAN_PRE &&
+ c->type == SSH_CHANNEL_OPEN &&
+ c->inactive_deadline != 0 && c->lastused != 0 &&
+ now >= c->lastused + c->inactive_deadline) {
+ /* channel closed for inactivity */
+ verbose("channel %d: closing after %u seconds "
+ "of inactivity", c->self,
+ c->inactive_deadline);
+ channel_force_close(ssh, c, 1);
+ } else if (c->notbefore <= now) {
+ /* Run handlers that are not paused. */
(*ftab[c->type])(ssh, c);
- else if (unpause_secs != NULL) {
+ /* inactivity timeouts must interrupt poll() */
+ if (timeout != NULL &&
+ c->type == SSH_CHANNEL_OPEN &&
+ c->lastused != 0 &&
+ c->inactive_deadline != 0) {
+ ptimeout_deadline_monotime(timeout,
+ c->lastused + c->inactive_deadline);
+ }
+ } else if (timeout != NULL) {
/*
- * Collect the time that the earliest
- * channel comes off pause.
+ * Arrange for poll() wakeup when channel pause
+ * timer expires.
*/
- debug3_f("chan %d: skip for %d more "
- "seconds", c->self,
- (int)(c->notbefore - now));
- if (*unpause_secs == 0 ||
- (c->notbefore - now) < *unpause_secs)
- *unpause_secs = c->notbefore - now;
+ ptimeout_deadline_monotime(timeout,
+ c->notbefore);
}
}
channel_garbage_collect(ssh, c);
}
- if (unpause_secs != NULL && *unpause_secs != 0)
- debug3_f("first channel unpauses in %d seconds",
- (int)*unpause_secs);
}
/*
* Create sockets before preparing IO.
* This is necessary for things that need to happen after reading
* the network-input but need to be completed before IO event setup, e.g.
* because they may create new channels.
*/
static void
channel_before_prepare_io(struct ssh *ssh)
{
struct ssh_channels *sc = ssh->chanctxt;
Channel *c;
u_int i, oalloc;
for (i = 0, oalloc = sc->channels_alloc; i < oalloc; i++) {
c = sc->channels[i];
if (c == NULL)
continue;
if (c->type == SSH_CHANNEL_RDYNAMIC_OPEN)
channel_before_prepare_io_rdynamic(ssh, c);
}
}
static void
dump_channel_poll(const char *func, const char *what, Channel *c,
u_int pollfd_offset, struct pollfd *pfd)
{
#ifdef DEBUG_CHANNEL_POLL
debug3("%s: channel %d: %s r%d w%d e%d s%d c->pfds [ %d %d %d %d ] "
"io_want 0x%02x io_ready 0x%02x pfd[%u].fd=%d "
"pfd.ev 0x%02x pfd.rev 0x%02x", func, c->self, what,
c->rfd, c->wfd, c->efd, c->sock,
c->pfds[0], c->pfds[1], c->pfds[2], c->pfds[3],
c->io_want, c->io_ready,
pollfd_offset, pfd->fd, pfd->events, pfd->revents);
#endif
}
/* Prepare pollfd entries for a single channel */
static void
channel_prepare_pollfd(Channel *c, u_int *next_pollfd,
struct pollfd *pfd, u_int npfd)
{
u_int ev, p = *next_pollfd;
if (c == NULL)
return;
if (p + 4 > npfd) {
/* Shouldn't happen */
fatal_f("channel %d: bad pfd offset %u (max %u)",
c->self, p, npfd);
}
c->pfds[0] = c->pfds[1] = c->pfds[2] = c->pfds[3] = -1;
/*
* prepare c->rfd
*
* This is a special case, since c->rfd might be the same as
* c->wfd, c->efd and/or c->sock. Handle those here if they want
* IO too.
*/
if (c->rfd != -1) {
ev = 0;
if ((c->io_want & SSH_CHAN_IO_RFD) != 0)
ev |= POLLIN;
/* rfd == wfd */
if (c->wfd == c->rfd) {
if ((c->io_want & SSH_CHAN_IO_WFD) != 0)
ev |= POLLOUT;
}
/* rfd == efd */
if (c->efd == c->rfd) {
if ((c->io_want & SSH_CHAN_IO_EFD_R) != 0)
ev |= POLLIN;
if ((c->io_want & SSH_CHAN_IO_EFD_W) != 0)
ev |= POLLOUT;
}
/* rfd == sock */
if (c->sock == c->rfd) {
if ((c->io_want & SSH_CHAN_IO_SOCK_R) != 0)
ev |= POLLIN;
if ((c->io_want & SSH_CHAN_IO_SOCK_W) != 0)
ev |= POLLOUT;
}
/* Pack a pfd entry if any event armed for this fd */
if (ev != 0) {
c->pfds[0] = p;
pfd[p].fd = c->rfd;
pfd[p].events = ev;
dump_channel_poll(__func__, "rfd", c, p, &pfd[p]);
p++;
}
}
/* prepare c->wfd if wanting IO and not already handled above */
if (c->wfd != -1 && c->rfd != c->wfd) {
ev = 0;
if ((c->io_want & SSH_CHAN_IO_WFD))
ev |= POLLOUT;
/* Pack a pfd entry if any event armed for this fd */
if (ev != 0) {
c->pfds[1] = p;
pfd[p].fd = c->wfd;
pfd[p].events = ev;
dump_channel_poll(__func__, "wfd", c, p, &pfd[p]);
p++;
}
}
/* prepare c->efd if wanting IO and not already handled above */
if (c->efd != -1 && c->rfd != c->efd) {
ev = 0;
if ((c->io_want & SSH_CHAN_IO_EFD_R) != 0)
ev |= POLLIN;
if ((c->io_want & SSH_CHAN_IO_EFD_W) != 0)
ev |= POLLOUT;
/* Pack a pfd entry if any event armed for this fd */
if (ev != 0) {
c->pfds[2] = p;
pfd[p].fd = c->efd;
pfd[p].events = ev;
dump_channel_poll(__func__, "efd", c, p, &pfd[p]);
p++;
}
}
/* prepare c->sock if wanting IO and not already handled above */
if (c->sock != -1 && c->rfd != c->sock) {
ev = 0;
if ((c->io_want & SSH_CHAN_IO_SOCK_R) != 0)
ev |= POLLIN;
if ((c->io_want & SSH_CHAN_IO_SOCK_W) != 0)
ev |= POLLOUT;
/* Pack a pfd entry if any event armed for this fd */
if (ev != 0) {
c->pfds[3] = p;
pfd[p].fd = c->sock;
pfd[p].events = 0;
dump_channel_poll(__func__, "sock", c, p, &pfd[p]);
p++;
}
}
*next_pollfd = p;
}
/* * Allocate/prepare poll structure */
void
channel_prepare_poll(struct ssh *ssh, struct pollfd **pfdp, u_int *npfd_allocp,
- u_int *npfd_activep, u_int npfd_reserved, time_t *minwait_secs)
+ u_int *npfd_activep, u_int npfd_reserved, struct timespec *timeout)
{
struct ssh_channels *sc = ssh->chanctxt;
u_int i, oalloc, p, npfd = npfd_reserved;
channel_before_prepare_io(ssh); /* might create a new channel */
/* clear out I/O flags from last poll */
for (i = 0; i < sc->channels_alloc; i++) {
if (sc->channels[i] == NULL)
continue;
sc->channels[i]->io_want = sc->channels[i]->io_ready = 0;
}
/* Allocate 4x pollfd for each channel (rfd, wfd, efd, sock) */
if (sc->channels_alloc >= (INT_MAX / 4) - npfd_reserved)
fatal_f("too many channels"); /* shouldn't happen */
npfd += sc->channels_alloc * 4;
if (npfd > *npfd_allocp) {
*pfdp = xrecallocarray(*pfdp, *npfd_allocp,
npfd, sizeof(**pfdp));
*npfd_allocp = npfd;
}
*npfd_activep = npfd_reserved;
oalloc = sc->channels_alloc;
- channel_handler(ssh, CHAN_PRE, minwait_secs);
+ channel_handler(ssh, CHAN_PRE, timeout);
if (oalloc != sc->channels_alloc) {
/* shouldn't happen */
fatal_f("channels_alloc changed during CHAN_PRE "
"(was %u, now %u)", oalloc, sc->channels_alloc);
}
/* Prepare pollfd */
p = npfd_reserved;
for (i = 0; i < sc->channels_alloc; i++)
channel_prepare_pollfd(sc->channels[i], &p, *pfdp, npfd);
*npfd_activep = p;
}
static void
fd_ready(Channel *c, int p, struct pollfd *pfds, u_int npfd, int fd,
const char *what, u_int revents_mask, u_int ready)
{
struct pollfd *pfd = &pfds[p];
if (fd == -1)
return;
if (p == -1 || (u_int)p >= npfd)
fatal_f("channel %d: bad pfd %d (max %u)", c->self, p, npfd);
dump_channel_poll(__func__, what, c, p, pfd);
if (pfd->fd != fd) {
fatal("channel %d: inconsistent %s fd=%d pollfd[%u].fd %d "
"r%d w%d e%d s%d", c->self, what, fd, p, pfd->fd,
c->rfd, c->wfd, c->efd, c->sock);
}
if ((pfd->revents & POLLNVAL) != 0) {
fatal("channel %d: invalid %s pollfd[%u].fd %d r%d w%d e%d s%d",
c->self, what, p, pfd->fd, c->rfd, c->wfd, c->efd, c->sock);
}
if ((pfd->revents & (revents_mask|POLLHUP|POLLERR)) != 0)
c->io_ready |= ready & c->io_want;
}
/*
* After poll, perform any appropriate operations for channels which have
* events pending.
*/
void
channel_after_poll(struct ssh *ssh, struct pollfd *pfd, u_int npfd)
{
struct ssh_channels *sc = ssh->chanctxt;
u_int i;
int p;
Channel *c;
#ifdef DEBUG_CHANNEL_POLL
for (p = 0; p < (int)npfd; p++) {
if (pfd[p].revents == 0)
continue;
debug_f("pfd[%u].fd %d rev 0x%04x",
p, pfd[p].fd, pfd[p].revents);
}
#endif
/* Convert pollfd into c->io_ready */
for (i = 0; i < sc->channels_alloc; i++) {
c = sc->channels[i];
if (c == NULL)
continue;
/* if rfd is shared with efd/sock then wfd should be too */
if (c->rfd != -1 && c->wfd != -1 && c->rfd != c->wfd &&
(c->rfd == c->efd || c->rfd == c->sock)) {
/* Shouldn't happen */
fatal_f("channel %d: unexpected fds r%d w%d e%d s%d",
c->self, c->rfd, c->wfd, c->efd, c->sock);
}
c->io_ready = 0;
/* rfd, potentially shared with wfd, efd and sock */
if (c->rfd != -1 && (p = c->pfds[0]) != -1) {
fd_ready(c, p, pfd, npfd, c->rfd,
"rfd", POLLIN, SSH_CHAN_IO_RFD);
if (c->rfd == c->wfd) {
fd_ready(c, p, pfd, npfd, c->wfd,
"wfd/r", POLLOUT, SSH_CHAN_IO_WFD);
}
if (c->rfd == c->efd) {
fd_ready(c, p, pfd, npfd, c->efd,
"efdr/r", POLLIN, SSH_CHAN_IO_EFD_R);
fd_ready(c, p, pfd, npfd, c->efd,
"efdw/r", POLLOUT, SSH_CHAN_IO_EFD_W);
}
if (c->rfd == c->sock) {
fd_ready(c, p, pfd, npfd, c->sock,
"sockr/r", POLLIN, SSH_CHAN_IO_SOCK_R);
fd_ready(c, p, pfd, npfd, c->sock,
"sockw/r", POLLOUT, SSH_CHAN_IO_SOCK_W);
}
dump_channel_poll(__func__, "rfd", c, p, pfd);
}
/* wfd */
if (c->wfd != -1 && c->wfd != c->rfd &&
(p = c->pfds[1]) != -1) {
fd_ready(c, p, pfd, npfd, c->wfd,
"wfd", POLLOUT, SSH_CHAN_IO_WFD);
dump_channel_poll(__func__, "wfd", c, p, pfd);
}
/* efd */
if (c->efd != -1 && c->efd != c->rfd &&
(p = c->pfds[2]) != -1) {
fd_ready(c, p, pfd, npfd, c->efd,
"efdr", POLLIN, SSH_CHAN_IO_EFD_R);
fd_ready(c, p, pfd, npfd, c->efd,
"efdw", POLLOUT, SSH_CHAN_IO_EFD_W);
dump_channel_poll(__func__, "efd", c, p, pfd);
}
/* sock */
if (c->sock != -1 && c->sock != c->rfd &&
(p = c->pfds[3]) != -1) {
fd_ready(c, p, pfd, npfd, c->sock,
"sockr", POLLIN, SSH_CHAN_IO_SOCK_R);
fd_ready(c, p, pfd, npfd, c->sock,
"sockw", POLLOUT, SSH_CHAN_IO_SOCK_W);
dump_channel_poll(__func__, "sock", c, p, pfd);
}
}
channel_handler(ssh, CHAN_POST, NULL);
}
/*
* Enqueue data for channels with open or draining c->input.
*/
static void
channel_output_poll_input_open(struct ssh *ssh, Channel *c)
{
size_t len, plen;
const u_char *pkt;
int r;
if ((len = sshbuf_len(c->input)) == 0) {
if (c->istate == CHAN_INPUT_WAIT_DRAIN) {
/*
* input-buffer is empty and read-socket shutdown:
* tell peer, that we will not send more data:
* send IEOF.
* hack for extended data: delay EOF if EFD still
* in use.
*/
if (CHANNEL_EFD_INPUT_ACTIVE(c))
debug2("channel %d: "
"ibuf_empty delayed efd %d/(%zu)",
c->self, c->efd, sshbuf_len(c->extended));
else
chan_ibuf_empty(ssh, c);
}
return;
}
if (!c->have_remote_id)
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_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
* backpressure at read time? (i.e. read + discard)
*/
if (plen > c->remote_window || plen > c->remote_maxpacket) {
debug("channel %d: datagram too big", c->self);
return;
}
/* Enqueue it */
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_fr(r, "channel %i: send datagram", c->self);
c->remote_window -= plen;
return;
}
/* Enqueue packet for buffered data. */
if (len > c->remote_window)
len = c->remote_window;
if (len > c->remote_maxpacket)
len = c->remote_maxpacket;
if (len == 0)
return;
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_fr(r, "channel %i: send data", c->self);
if ((r = sshbuf_consume(c->input, len)) != 0)
fatal_fr(r, "channel %i: consume", c->self);
c->remote_window -= len;
}
/*
* Enqueue data for channels with open c->extended in read mode.
*/
static void
channel_output_poll_extended_read(struct ssh *ssh, Channel *c)
{
size_t len;
int r;
if ((len = sshbuf_len(c->extended)) == 0)
return;
debug2("channel %d: rwin %u elen %zu euse %d", c->self,
c->remote_window, sshbuf_len(c->extended), c->extended_usage);
if (len > c->remote_window)
len = c->remote_window;
if (len > c->remote_maxpacket)
len = c->remote_maxpacket;
if (len == 0)
return;
if (!c->have_remote_id)
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_fr(r, "channel %i: data", c->self);
if ((r = sshbuf_consume(c->extended, len)) != 0)
fatal_fr(r, "channel %i: consume", c->self);
c->remote_window -= len;
debug2("channel %d: sent ext data %zu", c->self, len);
}
/* If there is data to send to the connection, enqueue some of it now. */
void
channel_output_poll(struct ssh *ssh)
{
struct ssh_channels *sc = ssh->chanctxt;
Channel *c;
u_int i;
for (i = 0; i < sc->channels_alloc; i++) {
c = sc->channels[i];
if (c == NULL)
continue;
/*
* We are only interested in channels that can have buffered
* incoming data.
*/
if (c->type != SSH_CHANNEL_OPEN)
continue;
if ((c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD))) {
/* XXX is this true? */
debug3("channel %d: will not send data after close",
c->self);
continue;
}
/* Get the amount of buffered data for this channel. */
if (c->istate == CHAN_INPUT_OPEN ||
c->istate == CHAN_INPUT_WAIT_DRAIN)
channel_output_poll_input_open(ssh, c);
/* Send extended data, i.e. stderr */
if (!(c->flags & CHAN_EOF_SENT) &&
c->extended_usage == CHAN_EXTENDED_READ)
channel_output_poll_extended_read(ssh, c);
}
}
/* -- mux proxy support */
/*
* When multiplexing channel messages for mux clients we have to deal
* with downstream messages from the mux client and upstream messages
* from the ssh server:
* 1) Handling downstream messages is straightforward and happens
* in channel_proxy_downstream():
* - We forward all messages (mostly) unmodified to the server.
* - However, in order to route messages from upstream to the correct
* downstream client, we have to replace the channel IDs used by the
* mux clients with a unique channel ID because the mux clients might
* use conflicting channel IDs.
* - so we inspect and change both SSH2_MSG_CHANNEL_OPEN and
* SSH2_MSG_CHANNEL_OPEN_CONFIRMATION messages, create a local
* SSH_CHANNEL_MUX_PROXY channel and replace the mux clients ID
* with the newly allocated channel ID.
* 2) Upstream messages are received by matching SSH_CHANNEL_MUX_PROXY
* channels and processed by channel_proxy_upstream(). The local channel ID
* is then translated back to the original mux client ID.
* 3) In both cases we need to keep track of matching SSH2_MSG_CHANNEL_CLOSE
* messages so we can clean up SSH_CHANNEL_MUX_PROXY channels.
* 4) The SSH_CHANNEL_MUX_PROXY channels also need to closed when the
* downstream mux client are removed.
* 5) Handling SSH2_MSG_CHANNEL_OPEN messages from the upstream server
* requires more work, because they are not addressed to a specific
* channel. E.g. client_request_forwarded_tcpip() needs to figure
* out whether the request is addressed to the local client or a
* specific downstream client based on the listen-address/port.
* 6) Agent and X11-Forwarding have a similar problem and are currently
* not supported as the matching session/channel cannot be identified
* easily.
*/
/*
* receive packets from downstream mux clients:
* channel callback fired on read from mux client, creates
* SSH_CHANNEL_MUX_PROXY channels and translates channel IDs
* on channel creation.
*/
int
channel_proxy_downstream(struct ssh *ssh, Channel *downstream)
{
Channel *c = NULL;
struct sshbuf *original = NULL, *modified = NULL;
const u_char *cp;
char *ctype = NULL, *listen_host = NULL;
u_char type;
size_t have;
int ret = -1, r;
u_int id, remote_id, listen_port;
/* sshbuf_dump(downstream->input, stderr); */
if ((r = sshbuf_get_string_direct(downstream->input, &cp, &have))
!= 0) {
error_fr(r, "parse");
return -1;
}
if (have < 2) {
error_f("short message");
return -1;
}
type = cp[1];
/* skip padlen + type */
cp += 2;
have -= 2;
if (ssh_packet_log_type(type))
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_f("alloc");
goto out;
}
if ((r = sshbuf_get_cstring(original, &ctype, NULL)) != 0 ||
(r = sshbuf_get_u32(original, &id)) != 0) {
error_fr(r, "parse");
goto out;
}
- c = channel_new(ssh, "mux proxy", SSH_CHANNEL_MUX_PROXY,
+ c = channel_new(ssh, "mux-proxy", SSH_CHANNEL_MUX_PROXY,
-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_fr(r, "compose");
channel_free(ssh, c);
goto out;
}
break;
case SSH2_MSG_CHANNEL_OPEN_CONFIRMATION:
/*
* Almost the same as SSH2_MSG_CHANNEL_OPEN, except then we
* need to parse 'remote_id' instead of 'ctype'.
*/
if ((original = sshbuf_from(cp, have)) == NULL ||
(modified = sshbuf_new()) == NULL) {
error_f("alloc");
goto out;
}
if ((r = sshbuf_get_u32(original, &remote_id)) != 0 ||
(r = sshbuf_get_u32(original, &id)) != 0) {
error_fr(r, "parse");
goto out;
}
- c = channel_new(ssh, "mux proxy", SSH_CHANNEL_MUX_PROXY,
+ c = channel_new(ssh, "mux-proxy", SSH_CHANNEL_MUX_PROXY,
-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;
c->have_remote_id = 1;
if ((r = sshbuf_put_u32(modified, remote_id)) != 0 ||
(r = sshbuf_put_u32(modified, c->self)) != 0 ||
(r = sshbuf_putb(modified, original)) != 0) {
error_fr(r, "compose");
channel_free(ssh, c);
goto out;
}
break;
case SSH2_MSG_GLOBAL_REQUEST:
if ((original = sshbuf_from(cp, have)) == NULL) {
error_f("alloc");
goto out;
}
if ((r = sshbuf_get_cstring(original, &ctype, NULL)) != 0) {
error_fr(r, "parse");
goto out;
}
if (strcmp(ctype, "tcpip-forward") != 0) {
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_fr(r, "parse");
goto out;
}
if (listen_port > 65535) {
error_f("tcpip-forward for %s: bad port %u",
listen_host, listen_port);
goto out;
}
/* Record that connection to this host/port is permitted. */
permission_set_add(ssh, FORWARD_USER, FORWARD_LOCAL, "<mux>", -1,
listen_host, NULL, (int)listen_port, downstream);
listen_host = NULL;
break;
case SSH2_MSG_CHANNEL_CLOSE:
if (have < 4)
break;
remote_id = PEEK_U32(cp);
if ((c = channel_by_remote_id(ssh, remote_id)) != NULL) {
if (c->flags & CHAN_CLOSE_RCVD)
channel_free(ssh, c);
else
c->flags |= CHAN_CLOSE_SENT;
}
break;
}
if (modified) {
if ((r = sshpkt_start(ssh, type)) != 0 ||
(r = sshpkt_putb(ssh, modified)) != 0 ||
(r = sshpkt_send(ssh)) != 0) {
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_fr(r, "send");
goto out;
}
}
ret = 0;
out:
free(ctype);
free(listen_host);
sshbuf_free(original);
sshbuf_free(modified);
return ret;
}
/*
* receive packets from upstream server and de-multiplex packets
* to correct downstream:
* implemented as a helper for channel input handlers,
* replaces local (proxy) channel ID with downstream channel ID.
*/
int
channel_proxy_upstream(Channel *c, int type, u_int32_t seq, struct ssh *ssh)
{
struct sshbuf *b = NULL;
Channel *downstream;
const u_char *cp = NULL;
size_t len;
int r;
/*
* When receiving packets from the peer we need to check whether we
* need to forward the packets to the mux client. In this case we
* restore the original channel id and keep track of CLOSE messages,
* so we can cleanup the channel.
*/
if (c == NULL || c->type != SSH_CHANNEL_MUX_PROXY)
return 0;
if ((downstream = c->mux_ctx) == NULL)
return 0;
switch (type) {
case SSH2_MSG_CHANNEL_CLOSE:
case SSH2_MSG_CHANNEL_DATA:
case SSH2_MSG_CHANNEL_EOF:
case SSH2_MSG_CHANNEL_EXTENDED_DATA:
case SSH2_MSG_CHANNEL_OPEN_CONFIRMATION:
case SSH2_MSG_CHANNEL_OPEN_FAILURE:
case SSH2_MSG_CHANNEL_WINDOW_ADJUST:
case SSH2_MSG_CHANNEL_SUCCESS:
case SSH2_MSG_CHANNEL_FAILURE:
case SSH2_MSG_CHANNEL_REQUEST:
break;
default:
debug2_f("channel %u: unsupported type %u", c->self, type);
return 0;
}
if ((b = sshbuf_new()) == NULL) {
error_f("alloc reply");
goto out;
}
/* get remaining payload (after id) */
cp = sshpkt_ptr(ssh, &len);
if (cp == NULL) {
error_f("no packet");
goto out;
}
/* translate id and send to muxclient */
if ((r = sshbuf_put_u8(b, 0)) != 0 || /* padlen */
(r = sshbuf_put_u8(b, type)) != 0 ||
(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_fr(r, "compose muxclient");
goto out;
}
/* sshbuf_dump(b, stderr); */
if (ssh_packet_log_type(type))
debug3_f("channel %u: up->down: type %u", c->self, type);
out:
/* update state */
switch (type) {
case SSH2_MSG_CHANNEL_OPEN_CONFIRMATION:
/* record remote_id for SSH2_MSG_CHANNEL_CLOSE */
if (cp && len > 4) {
c->remote_id = PEEK_U32(cp);
c->have_remote_id = 1;
}
break;
case SSH2_MSG_CHANNEL_CLOSE:
if (c->flags & CHAN_CLOSE_SENT)
channel_free(ssh, c);
else
c->flags |= CHAN_CLOSE_RCVD;
break;
}
sshbuf_free(b);
return 1;
}
/* -- protocol input */
/* Parse a channel ID from the current packet */
static int
channel_parse_id(struct ssh *ssh, const char *where, const char *what)
{
u_int32_t id;
int r;
if ((r = sshpkt_get_u32(ssh, &id)) != 0) {
error_r(r, "%s: parse id", where);
ssh_packet_disconnect(ssh, "Invalid %s message", what);
}
if (id > INT_MAX) {
error_r(r, "%s: bad channel id %u", where, id);
ssh_packet_disconnect(ssh, "Invalid %s channel id", what);
}
return (int)id;
}
/* Lookup a channel from an ID in the current packet */
static Channel *
channel_from_packet_id(struct ssh *ssh, const char *where, const char *what)
{
int id = channel_parse_id(ssh, where, what);
Channel *c;
if ((c = channel_lookup(ssh, id)) == NULL) {
ssh_packet_disconnect(ssh,
"%s packet referred to nonexistent channel %d", what, id);
}
return c;
}
int
channel_input_data(int type, u_int32_t seq, struct ssh *ssh)
{
const u_char *data;
size_t data_len, win_len;
Channel *c = channel_from_packet_id(ssh, __func__, "data");
int r;
if (channel_proxy_upstream(c, type, seq, ssh))
return 0;
/* Ignore any data for non-open channels (might happen on close) */
if (c->type != SSH_CHANNEL_OPEN &&
c->type != SSH_CHANNEL_RDYNAMIC_OPEN &&
c->type != SSH_CHANNEL_RDYNAMIC_FINISH &&
c->type != SSH_CHANNEL_X11_OPEN)
return 0;
/* Get the data. */
if ((r = sshpkt_get_string_direct(ssh, &data, &data_len)) != 0 ||
(r = sshpkt_get_end(ssh)) != 0)
fatal_fr(r, "channel %i: get data", c->self);
win_len = data_len;
if (c->datagram)
win_len += 4; /* string length header */
/*
* The sending side reduces its window as it sends data, so we
* must 'fake' consumption of the data in order to ensure that window
* updates are sent back. Otherwise the connection might deadlock.
*/
if (c->ostate != CHAN_OUTPUT_OPEN) {
c->local_window -= win_len;
c->local_consumed += win_len;
return 0;
}
if (win_len > c->local_maxpacket) {
logit("channel %d: rcvd big packet %zu, maxpack %u",
c->self, win_len, c->local_maxpacket);
return 0;
}
if (win_len > c->local_window) {
logit("channel %d: rcvd too much data %zu, win %u",
c->self, win_len, c->local_window);
return 0;
}
c->local_window -= win_len;
if (c->datagram) {
if ((r = sshbuf_put_string(c->output, data, data_len)) != 0)
fatal_fr(r, "channel %i: append datagram", c->self);
} else if ((r = sshbuf_put(c->output, data, data_len)) != 0)
fatal_fr(r, "channel %i: append data", c->self);
return 0;
}
int
channel_input_extended_data(int type, u_int32_t seq, struct ssh *ssh)
{
const u_char *data;
size_t data_len;
u_int32_t tcode;
Channel *c = channel_from_packet_id(ssh, __func__, "extended data");
int r;
if (channel_proxy_upstream(c, type, seq, ssh))
return 0;
if (c->type != SSH_CHANNEL_OPEN) {
logit("channel %d: ext data for non open", c->self);
return 0;
}
if (c->flags & CHAN_EOF_RCVD) {
if (ssh->compat & SSH_BUG_EXTEOF)
debug("channel %d: accepting ext data after eof",
c->self);
else
ssh_packet_disconnect(ssh, "Received extended_data "
"after EOF on channel %d.", c->self);
}
if ((r = sshpkt_get_u32(ssh, &tcode)) != 0) {
error_fr(r, "parse tcode");
ssh_packet_disconnect(ssh, "Invalid extended_data message");
}
if (c->efd == -1 ||
c->extended_usage != CHAN_EXTENDED_WRITE ||
tcode != SSH2_EXTENDED_DATA_STDERR) {
logit("channel %d: bad ext data", c->self);
return 0;
}
if ((r = sshpkt_get_string_direct(ssh, &data, &data_len)) != 0 ||
(r = sshpkt_get_end(ssh)) != 0) {
error_fr(r, "parse data");
ssh_packet_disconnect(ssh, "Invalid extended_data message");
}
if (data_len > c->local_window) {
logit("channel %d: rcvd too much extended_data %zu, win %u",
c->self, data_len, c->local_window);
return 0;
}
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_fr(r, "append");
c->local_window -= data_len;
return 0;
}
int
channel_input_ieof(int type, u_int32_t seq, struct ssh *ssh)
{
Channel *c = channel_from_packet_id(ssh, __func__, "ieof");
int r;
if ((r = sshpkt_get_end(ssh)) != 0) {
error_fr(r, "parse data");
ssh_packet_disconnect(ssh, "Invalid ieof message");
}
if (channel_proxy_upstream(c, type, seq, ssh))
return 0;
chan_rcvd_ieof(ssh, c);
/* XXX force input close */
if (c->force_drain && c->istate == CHAN_INPUT_OPEN) {
debug("channel %d: FORCE input drain", c->self);
c->istate = CHAN_INPUT_WAIT_DRAIN;
if (sshbuf_len(c->input) == 0)
chan_ibuf_empty(ssh, c);
}
return 0;
}
int
channel_input_oclose(int type, u_int32_t seq, struct ssh *ssh)
{
Channel *c = channel_from_packet_id(ssh, __func__, "oclose");
int r;
if (channel_proxy_upstream(c, type, seq, ssh))
return 0;
if ((r = sshpkt_get_end(ssh)) != 0) {
error_fr(r, "parse data");
ssh_packet_disconnect(ssh, "Invalid oclose message");
}
chan_rcvd_oclose(ssh, c);
return 0;
}
int
channel_input_open_confirmation(int type, u_int32_t seq, struct ssh *ssh)
{
Channel *c = channel_from_packet_id(ssh, __func__, "open confirmation");
u_int32_t remote_window, remote_maxpacket;
int r;
if (channel_proxy_upstream(c, type, seq, ssh))
return 0;
if (c->type != SSH_CHANNEL_OPENING)
ssh_packet_disconnect(ssh, "Received open confirmation for "
"non-opening channel %d.", c->self);
/*
* Record the remote channel number and mark that the channel
* is now open.
*/
if ((r = sshpkt_get_u32(ssh, &c->remote_id)) != 0 ||
(r = sshpkt_get_u32(ssh, &remote_window)) != 0 ||
(r = sshpkt_get_u32(ssh, &remote_maxpacket)) != 0 ||
(r = sshpkt_get_end(ssh)) != 0) {
error_fr(r, "window/maxpacket");
ssh_packet_disconnect(ssh, "Invalid open confirmation message");
}
c->have_remote_id = 1;
c->remote_window = remote_window;
c->remote_maxpacket = remote_maxpacket;
c->type = SSH_CHANNEL_OPEN;
if (c->open_confirm) {
debug2_f("channel %d: callback start", c->self);
c->open_confirm(ssh, c->self, 1, c->open_confirm_ctx);
debug2_f("channel %d: callback done", c->self);
}
+ c->lastused = monotime();
debug2("channel %d: open confirm rwindow %u rmax %u", c->self,
c->remote_window, c->remote_maxpacket);
return 0;
}
static char *
reason2txt(int reason)
{
switch (reason) {
case SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED:
return "administratively prohibited";
case SSH2_OPEN_CONNECT_FAILED:
return "connect failed";
case SSH2_OPEN_UNKNOWN_CHANNEL_TYPE:
return "unknown channel type";
case SSH2_OPEN_RESOURCE_SHORTAGE:
return "resource shortage";
}
return "unknown reason";
}
int
channel_input_open_failure(int type, u_int32_t seq, struct ssh *ssh)
{
Channel *c = channel_from_packet_id(ssh, __func__, "open failure");
u_int32_t reason;
char *msg = NULL;
int r;
if (channel_proxy_upstream(c, type, seq, ssh))
return 0;
if (c->type != SSH_CHANNEL_OPENING)
ssh_packet_disconnect(ssh, "Received open failure for "
"non-opening channel %d.", c->self);
if ((r = sshpkt_get_u32(ssh, &reason)) != 0) {
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_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_f("channel %d: callback start", c->self);
c->open_confirm(ssh, c->self, 0, c->open_confirm_ctx);
debug2_f("channel %d: callback done", c->self);
}
/* Schedule the channel for cleanup/deletion. */
chan_mark_dead(ssh, c);
return 0;
}
int
channel_input_window_adjust(int type, u_int32_t seq, struct ssh *ssh)
{
int id = channel_parse_id(ssh, __func__, "window adjust");
Channel *c;
u_int32_t adjust;
u_int new_rwin;
int r;
if ((c = channel_lookup(ssh, id)) == NULL) {
logit("Received window adjust for non-open channel %d.", id);
return 0;
}
if (channel_proxy_upstream(c, type, seq, ssh))
return 0;
if ((r = sshpkt_get_u32(ssh, &adjust)) != 0 ||
(r = sshpkt_get_end(ssh)) != 0) {
error_fr(r, "parse adjust");
ssh_packet_disconnect(ssh, "Invalid window adjust message");
}
debug2("channel %d: rcvd adjust %u", c->self, adjust);
if ((new_rwin = c->remote_window + adjust) < c->remote_window) {
fatal("channel %d: adjust %u overflows remote window %u",
c->self, adjust, c->remote_window);
}
c->remote_window = new_rwin;
return 0;
}
int
channel_input_status_confirm(int type, u_int32_t seq, struct ssh *ssh)
{
int id = channel_parse_id(ssh, __func__, "status confirm");
Channel *c;
struct channel_confirm *cc;
/* Reset keepalive timeout */
ssh_packet_set_alive_timeouts(ssh, 0);
debug2_f("type %d id %d", type, id);
if ((c = channel_lookup(ssh, id)) == NULL) {
logit_f("%d: unknown", id);
return 0;
}
if (channel_proxy_upstream(c, type, seq, ssh))
return 0;
if (sshpkt_get_end(ssh) != 0)
ssh_packet_disconnect(ssh, "Invalid status confirm message");
if ((cc = TAILQ_FIRST(&c->status_confirms)) == NULL)
return 0;
cc->cb(ssh, type, c, cc->ctx);
TAILQ_REMOVE(&c->status_confirms, cc, entry);
freezero(cc, sizeof(*cc));
return 0;
}
/* -- tcp forwarding */
void
channel_set_af(struct ssh *ssh, int af)
{
ssh->chanctxt->IPv4or6 = af;
}
/*
* Determine whether or not a port forward listens to loopback, the
* specified address or wildcard. On the client, a specified bind
* address will always override gateway_ports. On the server, a
* gateway_ports of 1 (``yes'') will override the client's specification
* and force a wildcard bind, whereas a value of 2 (``clientspecified'')
* will bind to whatever address the client asked for.
*
* Special-case listen_addrs are:
*
* "0.0.0.0" -> wildcard v4/v6 if SSH_OLD_FORWARD_ADDR
* "" (empty string), "*" -> wildcard v4/v6
* "localhost" -> loopback v4/v6
* "127.0.0.1" / "::1" -> accepted even if gateway_ports isn't set
*/
static const char *
channel_fwd_bind_addr(struct ssh *ssh, const char *listen_addr, int *wildcardp,
int is_client, struct ForwardOptions *fwd_opts)
{
const char *addr = NULL;
int wildcard = 0;
if (listen_addr == NULL) {
/* No address specified: default to gateway_ports setting */
if (fwd_opts->gateway_ports)
wildcard = 1;
} else if (fwd_opts->gateway_ports || is_client) {
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)) {
wildcard = 1;
/*
* Notify client if they requested a specific listen
* address and it was overridden.
*/
if (*listen_addr != '\0' &&
strcmp(listen_addr, "0.0.0.0") != 0 &&
strcmp(listen_addr, "*") != 0) {
ssh_packet_send_debug(ssh,
"Forwarding listen address "
"\"%s\" overridden by server "
"GatewayPorts", listen_addr);
}
} else if (strcmp(listen_addr, "localhost") != 0 ||
strcmp(listen_addr, "127.0.0.1") == 0 ||
strcmp(listen_addr, "::1") == 0) {
/*
* Accept explicit localhost address when
* GatewayPorts=yes. The "localhost" hostname is
* deliberately skipped here so it will listen on all
* available local address families.
*/
addr = listen_addr;
}
} else if (strcmp(listen_addr, "127.0.0.1") == 0 ||
strcmp(listen_addr, "::1") == 0) {
/*
* If a specific IPv4/IPv6 localhost address has been
* requested then accept it even if gateway_ports is in
* effect. This allows the client to prefer IPv4 or IPv6.
*/
addr = listen_addr;
}
if (wildcardp != NULL)
*wildcardp = wildcard;
return addr;
}
static int
channel_setup_fwd_listener_tcpip(struct ssh *ssh, int type,
struct Forward *fwd, int *allocated_listen_port,
struct ForwardOptions *fwd_opts)
{
Channel *c;
int sock, r, success = 0, wildcard = 0, is_client;
struct addrinfo hints, *ai, *aitop;
const char *host, *addr;
char ntop[NI_MAXHOST], strport[NI_MAXSERV];
in_port_t *lport_p;
is_client = (type == SSH_CHANNEL_PORT_LISTENER);
if (is_client && fwd->connect_path != NULL) {
host = fwd->connect_path;
} else {
host = (type == SSH_CHANNEL_RPORT_LISTENER) ?
fwd->listen_host : fwd->connect_host;
if (host == NULL) {
error("No forward host name.");
return 0;
}
if (strlen(host) >= NI_MAXHOST) {
error("Forward host name too long.");
return 0;
}
}
/* 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_f("type %d wildcard %d addr %s", type, wildcard,
(addr == NULL) ? "NULL" : addr);
/*
* getaddrinfo returns a loopback address if the hostname is
* set to NULL and hints.ai_flags is not AI_PASSIVE
*/
memset(&hints, 0, sizeof(hints));
hints.ai_family = ssh->chanctxt->IPv4or6;
hints.ai_flags = wildcard ? AI_PASSIVE : 0;
hints.ai_socktype = SOCK_STREAM;
snprintf(strport, sizeof strport, "%d", fwd->listen_port);
if ((r = getaddrinfo(addr, strport, &hints, &aitop)) != 0) {
if (addr == NULL) {
/* This really shouldn't happen */
ssh_packet_disconnect(ssh, "getaddrinfo: fatal error: %s",
ssh_gai_strerror(r));
} else {
error_f("getaddrinfo(%.64s): %s", addr,
ssh_gai_strerror(r));
}
return 0;
}
if (allocated_listen_port != NULL)
*allocated_listen_port = 0;
for (ai = aitop; ai; ai = ai->ai_next) {
switch (ai->ai_family) {
case AF_INET:
lport_p = &((struct sockaddr_in *)ai->ai_addr)->
sin_port;
break;
case AF_INET6:
lport_p = &((struct sockaddr_in6 *)ai->ai_addr)->
sin6_port;
break;
default:
continue;
}
/*
* If allocating a port for -R forwards, then use the
* same port for all address families.
*/
if (type == SSH_CHANNEL_RPORT_LISTENER &&
fwd->listen_port == 0 && allocated_listen_port != NULL &&
*allocated_listen_port > 0)
*lport_p = htons(*allocated_listen_port);
if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop, sizeof(ntop),
strport, sizeof(strport),
NI_NUMERICHOST|NI_NUMERICSERV) != 0) {
error_f("getnameinfo failed");
continue;
}
/* Create a port to listen for the host. */
sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
if (sock == -1) {
/* this is no error since kernel may not support ipv6 */
verbose("socket [%s]:%s: %.100s", ntop, strport,
strerror(errno));
continue;
}
set_reuseaddr(sock);
if (ai->ai_family == AF_INET6)
sock_set_v6only(sock);
debug("Local forwarding listening on %s port %s.",
ntop, strport);
/* Bind the socket to the address. */
if (bind(sock, ai->ai_addr, ai->ai_addrlen) == -1) {
/*
* address can be in if use ipv6 address is
* already bound
*/
if (!ai->ai_next)
error("bind [%s]:%s: %.100s",
ntop, strport, strerror(errno));
else
verbose("bind [%s]:%s: %.100s",
ntop, strport, strerror(errno));
close(sock);
continue;
}
/* Start listening for connections on the socket. */
if (listen(sock, SSH_LISTEN_BACKLOG) == -1) {
error("listen [%s]:%s: %.100s", ntop, strport,
strerror(errno));
close(sock);
continue;
}
/*
* fwd->listen_port == 0 requests a dynamically allocated port -
* record what we got.
*/
if (type == SSH_CHANNEL_RPORT_LISTENER &&
fwd->listen_port == 0 &&
allocated_listen_port != NULL &&
*allocated_listen_port == 0) {
*allocated_listen_port = get_local_port(sock);
debug("Allocated listen port %d",
*allocated_listen_port);
}
/* Allocate a channel number for the socket. */
- c = channel_new(ssh, "port listener", type, sock, sock, -1,
+ c = channel_new(ssh, "port-listener", type, sock, sock, -1,
CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,
0, "port listener", 1);
c->path = xstrdup(host);
c->host_port = fwd->connect_port;
c->listening_addr = addr == NULL ? NULL : xstrdup(addr);
if (fwd->listen_port == 0 && allocated_listen_port != NULL &&
!(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_f("cannot listen to port: %d", fwd->listen_port);
freeaddrinfo(aitop);
return success;
}
static int
channel_setup_fwd_listener_streamlocal(struct ssh *ssh, int type,
struct Forward *fwd, struct ForwardOptions *fwd_opts)
{
struct sockaddr_un sunaddr;
const char *path;
Channel *c;
int port, sock;
mode_t omask;
switch (type) {
case SSH_CHANNEL_UNIX_LISTENER:
if (fwd->connect_path != NULL) {
if (strlen(fwd->connect_path) > sizeof(sunaddr.sun_path)) {
error("Local connecting path too long: %s",
fwd->connect_path);
return 0;
}
path = fwd->connect_path;
port = PORT_STREAMLOCAL;
} else {
if (fwd->connect_host == NULL) {
error("No forward host name.");
return 0;
}
if (strlen(fwd->connect_host) >= NI_MAXHOST) {
error("Forward host name too long.");
return 0;
}
path = fwd->connect_host;
port = fwd->connect_port;
}
break;
case SSH_CHANNEL_RUNIX_LISTENER:
path = fwd->listen_path;
port = PORT_STREAMLOCAL;
break;
default:
error_f("unexpected channel type %d", type);
return 0;
}
if (fwd->listen_path == NULL) {
error("No forward path name.");
return 0;
}
if (strlen(fwd->listen_path) > sizeof(sunaddr.sun_path)) {
error("Local listening path too long: %s", fwd->listen_path);
return 0;
}
debug3_f("type %d path %s", type, fwd->listen_path);
/* Start a Unix domain listener. */
omask = umask(fwd_opts->streamlocal_bind_mask);
sock = unix_listener(fwd->listen_path, SSH_LISTEN_BACKLOG,
fwd_opts->streamlocal_bind_unlink);
umask(omask);
if (sock < 0)
return 0;
debug("Local forwarding listening on path %s.", fwd->listen_path);
/* Allocate a channel number for the socket. */
- c = channel_new(ssh, "unix listener", type, sock, sock, -1,
+ c = channel_new(ssh, "unix-listener", type, sock, sock, -1,
CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,
0, "unix listener", 1);
c->path = xstrdup(path);
c->host_port = port;
c->listening_port = PORT_STREAMLOCAL;
c->listening_addr = xstrdup(fwd->listen_path);
return 1;
}
static int
channel_cancel_rport_listener_tcpip(struct ssh *ssh,
const char *host, u_short port)
{
u_int i;
int found = 0;
for (i = 0; i < ssh->chanctxt->channels_alloc; i++) {
Channel *c = ssh->chanctxt->channels[i];
if (c == NULL || c->type != SSH_CHANNEL_RPORT_LISTENER)
continue;
if (strcmp(c->path, host) == 0 && c->listening_port == port) {
debug2_f("close channel %d", i);
channel_free(ssh, c);
found = 1;
}
}
return found;
}
static int
channel_cancel_rport_listener_streamlocal(struct ssh *ssh, const char *path)
{
u_int i;
int found = 0;
for (i = 0; i < ssh->chanctxt->channels_alloc; i++) {
Channel *c = ssh->chanctxt->channels[i];
if (c == NULL || c->type != SSH_CHANNEL_RUNIX_LISTENER)
continue;
if (c->path == NULL)
continue;
if (strcmp(c->path, path) == 0) {
debug2_f("close channel %d", i);
channel_free(ssh, c);
found = 1;
}
}
return found;
}
int
channel_cancel_rport_listener(struct ssh *ssh, struct Forward *fwd)
{
if (fwd->listen_path != NULL) {
return channel_cancel_rport_listener_streamlocal(ssh,
fwd->listen_path);
} else {
return channel_cancel_rport_listener_tcpip(ssh,
fwd->listen_host, fwd->listen_port);
}
}
static int
channel_cancel_lport_listener_tcpip(struct ssh *ssh,
const char *lhost, u_short lport, int cport,
struct ForwardOptions *fwd_opts)
{
u_int i;
int found = 0;
const char *addr = channel_fwd_bind_addr(ssh, lhost, NULL, 1, fwd_opts);
for (i = 0; i < ssh->chanctxt->channels_alloc; i++) {
Channel *c = ssh->chanctxt->channels[i];
if (c == NULL || c->type != SSH_CHANNEL_PORT_LISTENER)
continue;
if (c->listening_port != lport)
continue;
if (cport == CHANNEL_CANCEL_PORT_STATIC) {
/* skip dynamic forwardings */
if (c->host_port == 0)
continue;
} else {
if (c->host_port != cport)
continue;
}
if ((c->listening_addr == NULL && addr != NULL) ||
(c->listening_addr != NULL && addr == NULL))
continue;
if (addr == NULL || strcmp(c->listening_addr, addr) == 0) {
debug2_f("close channel %d", i);
channel_free(ssh, c);
found = 1;
}
}
return found;
}
static int
channel_cancel_lport_listener_streamlocal(struct ssh *ssh, const char *path)
{
u_int i;
int found = 0;
if (path == NULL) {
error_f("no path specified.");
return 0;
}
for (i = 0; i < ssh->chanctxt->channels_alloc; i++) {
Channel *c = ssh->chanctxt->channels[i];
if (c == NULL || c->type != SSH_CHANNEL_UNIX_LISTENER)
continue;
if (c->listening_addr == NULL)
continue;
if (strcmp(c->listening_addr, path) == 0) {
debug2_f("close channel %d", i);
channel_free(ssh, c);
found = 1;
}
}
return found;
}
int
channel_cancel_lport_listener(struct ssh *ssh,
struct Forward *fwd, int cport, struct ForwardOptions *fwd_opts)
{
if (fwd->listen_path != NULL) {
return channel_cancel_lport_listener_streamlocal(ssh,
fwd->listen_path);
} else {
return channel_cancel_lport_listener_tcpip(ssh,
fwd->listen_host, fwd->listen_port, cport, fwd_opts);
}
}
/* protocol local port fwd, used by ssh */
int
channel_setup_local_fwd_listener(struct ssh *ssh,
struct Forward *fwd, struct ForwardOptions *fwd_opts)
{
if (fwd->listen_path != NULL) {
return channel_setup_fwd_listener_streamlocal(ssh,
SSH_CHANNEL_UNIX_LISTENER, fwd, fwd_opts);
} else {
return channel_setup_fwd_listener_tcpip(ssh,
SSH_CHANNEL_PORT_LISTENER, fwd, NULL, fwd_opts);
}
}
/* Matches a remote forwarding permission against a requested forwarding */
static int
remote_open_match(struct permission *allowed_open, struct Forward *fwd)
{
int ret;
char *lhost;
/* XXX add ACLs for streamlocal */
if (fwd->listen_path != NULL)
return 1;
if (fwd->listen_host == NULL || allowed_open->listen_host == NULL)
return 0;
if (allowed_open->listen_port != FWD_PERMIT_ANY_PORT &&
allowed_open->listen_port != fwd->listen_port)
return 0;
/* Match hostnames case-insensitively */
lhost = xstrdup(fwd->listen_host);
lowercase(lhost);
ret = match_pattern(lhost, allowed_open->listen_host);
free(lhost);
return ret;
}
/* Checks whether a requested remote forwarding is permitted */
static int
check_rfwd_permission(struct ssh *ssh, struct Forward *fwd)
{
struct ssh_channels *sc = ssh->chanctxt;
struct permission_set *pset = &sc->remote_perms;
u_int i, permit, permit_adm = 1;
struct permission *perm;
/* XXX apply GatewayPorts override before checking? */
permit = pset->all_permitted;
if (!permit) {
for (i = 0; i < pset->num_permitted_user; i++) {
perm = &pset->permitted_user[i];
if (remote_open_match(perm, fwd)) {
permit = 1;
break;
}
}
}
if (pset->num_permitted_admin > 0) {
permit_adm = 0;
for (i = 0; i < pset->num_permitted_admin; i++) {
perm = &pset->permitted_admin[i];
if (remote_open_match(perm, fwd)) {
permit_adm = 1;
break;
}
}
}
return permit && permit_adm;
}
/* protocol v2 remote port fwd, used by sshd */
int
channel_setup_remote_fwd_listener(struct ssh *ssh, struct Forward *fwd,
int *allocated_listen_port, struct ForwardOptions *fwd_opts)
{
if (!check_rfwd_permission(ssh, fwd)) {
ssh_packet_send_debug(ssh, "port forwarding refused");
if (fwd->listen_path != NULL)
/* XXX always allowed, see remote_open_match() */
logit("Received request from %.100s port %d to "
"remote forward to path \"%.100s\", "
"but the request was denied.",
ssh_remote_ipaddr(ssh), ssh_remote_port(ssh),
fwd->listen_path);
else if(fwd->listen_host != NULL)
logit("Received request from %.100s port %d to "
"remote forward to host %.100s port %d, "
"but the request was denied.",
ssh_remote_ipaddr(ssh), ssh_remote_port(ssh),
fwd->listen_host, fwd->listen_port );
else
logit("Received request from %.100s port %d to remote "
"forward, but the request was denied.",
ssh_remote_ipaddr(ssh), ssh_remote_port(ssh));
return 0;
}
if (fwd->listen_path != NULL) {
return channel_setup_fwd_listener_streamlocal(ssh,
SSH_CHANNEL_RUNIX_LISTENER, fwd, fwd_opts);
} else {
return channel_setup_fwd_listener_tcpip(ssh,
SSH_CHANNEL_RPORT_LISTENER, fwd, allocated_listen_port,
fwd_opts);
}
}
/*
* Translate the requested rfwd listen host to something usable for
* this server.
*/
static const char *
channel_rfwd_bind_host(const char *listen_host)
{
if (listen_host == NULL) {
return "localhost";
} else if (*listen_host == '\0' || strcmp(listen_host, "*") == 0) {
return "";
} else
return listen_host;
}
/*
* Initiate forwarding of connections to port "port" on remote host through
* the secure channel to host:port from local side.
* Returns handle (index) for updating the dynamic listen port with
* channel_update_permission().
*/
int
channel_request_remote_forwarding(struct ssh *ssh, struct Forward *fwd)
{
int r, success = 0, idx = -1;
- char *host_to_connect, *listen_host, *listen_path;
+ const char *host_to_connect, *listen_host, *listen_path;
int port_to_connect, listen_port;
/* Send the forward request to the remote side. */
if (fwd->listen_path != NULL) {
if ((r = sshpkt_start(ssh, SSH2_MSG_GLOBAL_REQUEST)) != 0 ||
(r = sshpkt_put_cstring(ssh,
"streamlocal-forward@openssh.com")) != 0 ||
(r = sshpkt_put_u8(ssh, 1)) != 0 || /* want reply */
(r = sshpkt_put_cstring(ssh, fwd->listen_path)) != 0 ||
(r = sshpkt_send(ssh)) != 0 ||
(r = ssh_packet_write_wait(ssh)) != 0)
fatal_fr(r, "request streamlocal");
} else {
if ((r = sshpkt_start(ssh, SSH2_MSG_GLOBAL_REQUEST)) != 0 ||
(r = sshpkt_put_cstring(ssh, "tcpip-forward")) != 0 ||
(r = sshpkt_put_u8(ssh, 1)) != 0 || /* want reply */
(r = sshpkt_put_cstring(ssh,
channel_rfwd_bind_host(fwd->listen_host))) != 0 ||
(r = sshpkt_put_u32(ssh, fwd->listen_port)) != 0 ||
(r = sshpkt_send(ssh)) != 0 ||
(r = ssh_packet_write_wait(ssh)) != 0)
fatal_fr(r, "request tcpip-forward");
}
/* Assume that server accepts the request */
success = 1;
if (success) {
/* Record that connection to this host/port is permitted. */
host_to_connect = listen_host = listen_path = NULL;
port_to_connect = listen_port = 0;
if (fwd->connect_path != NULL) {
- host_to_connect = xstrdup(fwd->connect_path);
+ host_to_connect = fwd->connect_path;
port_to_connect = PORT_STREAMLOCAL;
} else {
- host_to_connect = xstrdup(fwd->connect_host);
+ host_to_connect = fwd->connect_host;
port_to_connect = fwd->connect_port;
}
if (fwd->listen_path != NULL) {
- listen_path = xstrdup(fwd->listen_path);
+ listen_path = fwd->listen_path;
listen_port = PORT_STREAMLOCAL;
} else {
- if (fwd->listen_host != NULL)
- listen_host = xstrdup(fwd->listen_host);
+ listen_host = fwd->listen_host;
listen_port = fwd->listen_port;
}
idx = permission_set_add(ssh, FORWARD_USER, FORWARD_LOCAL,
host_to_connect, port_to_connect,
listen_host, listen_path, listen_port, NULL);
}
return idx;
}
static int
open_match(struct permission *allowed_open, const char *requestedhost,
int requestedport)
{
if (allowed_open->host_to_connect == NULL)
return 0;
if (allowed_open->port_to_connect != FWD_PERMIT_ANY_PORT &&
allowed_open->port_to_connect != requestedport)
return 0;
if (strcmp(allowed_open->host_to_connect, FWD_PERMIT_ANY_HOST) != 0 &&
strcmp(allowed_open->host_to_connect, requestedhost) != 0)
return 0;
return 1;
}
/*
* Note that in the listen host/port case
* we don't support FWD_PERMIT_ANY_PORT and
* need to translate between the configured-host (listen_host)
* and what we've sent to the remote server (channel_rfwd_bind_host)
*/
static int
open_listen_match_tcpip(struct permission *allowed_open,
const char *requestedhost, u_short requestedport, int translate)
{
const char *allowed_host;
if (allowed_open->host_to_connect == NULL)
return 0;
if (allowed_open->listen_port != requestedport)
return 0;
if (!translate && allowed_open->listen_host == NULL &&
requestedhost == NULL)
return 1;
allowed_host = translate ?
channel_rfwd_bind_host(allowed_open->listen_host) :
allowed_open->listen_host;
if (allowed_host == NULL || requestedhost == NULL ||
strcmp(allowed_host, requestedhost) != 0)
return 0;
return 1;
}
static int
open_listen_match_streamlocal(struct permission *allowed_open,
const char *requestedpath)
{
if (allowed_open->host_to_connect == NULL)
return 0;
if (allowed_open->listen_port != PORT_STREAMLOCAL)
return 0;
if (allowed_open->listen_path == NULL ||
strcmp(allowed_open->listen_path, requestedpath) != 0)
return 0;
return 1;
}
/*
* Request cancellation of remote forwarding of connection host:port from
* local side.
*/
static int
channel_request_rforward_cancel_tcpip(struct ssh *ssh,
const char *host, u_short port)
{
struct ssh_channels *sc = ssh->chanctxt;
struct permission_set *pset = &sc->local_perms;
int r;
u_int i;
struct permission *perm = NULL;
for (i = 0; i < pset->num_permitted_user; i++) {
perm = &pset->permitted_user[i];
if (open_listen_match_tcpip(perm, host, port, 0))
break;
perm = NULL;
}
if (perm == NULL) {
debug_f("requested forward not found");
return -1;
}
if ((r = sshpkt_start(ssh, SSH2_MSG_GLOBAL_REQUEST)) != 0 ||
(r = sshpkt_put_cstring(ssh, "cancel-tcpip-forward")) != 0 ||
(r = sshpkt_put_u8(ssh, 0)) != 0 || /* want reply */
(r = sshpkt_put_cstring(ssh, channel_rfwd_bind_host(host))) != 0 ||
(r = sshpkt_put_u32(ssh, port)) != 0 ||
(r = sshpkt_send(ssh)) != 0)
fatal_fr(r, "send cancel");
fwd_perm_clear(perm); /* unregister */
return 0;
}
/*
* Request cancellation of remote forwarding of Unix domain socket
* path from local side.
*/
static int
channel_request_rforward_cancel_streamlocal(struct ssh *ssh, const char *path)
{
struct ssh_channels *sc = ssh->chanctxt;
struct permission_set *pset = &sc->local_perms;
int r;
u_int i;
struct permission *perm = NULL;
for (i = 0; i < pset->num_permitted_user; i++) {
perm = &pset->permitted_user[i];
if (open_listen_match_streamlocal(perm, path))
break;
perm = NULL;
}
if (perm == NULL) {
debug_f("requested forward not found");
return -1;
}
if ((r = sshpkt_start(ssh, SSH2_MSG_GLOBAL_REQUEST)) != 0 ||
(r = sshpkt_put_cstring(ssh,
"cancel-streamlocal-forward@openssh.com")) != 0 ||
(r = sshpkt_put_u8(ssh, 0)) != 0 || /* want reply */
(r = sshpkt_put_cstring(ssh, path)) != 0 ||
(r = sshpkt_send(ssh)) != 0)
fatal_fr(r, "send cancel");
fwd_perm_clear(perm); /* unregister */
return 0;
}
/*
* Request cancellation of remote forwarding of a connection from local side.
*/
int
channel_request_rforward_cancel(struct ssh *ssh, struct Forward *fwd)
{
if (fwd->listen_path != NULL) {
return channel_request_rforward_cancel_streamlocal(ssh,
fwd->listen_path);
} else {
return channel_request_rforward_cancel_tcpip(ssh,
fwd->listen_host,
fwd->listen_port ? fwd->listen_port : fwd->allocated_port);
}
}
/*
* Permits opening to any host/port if permitted_user[] is empty. This is
* usually called by the server, because the user could connect to any port
* anyway, and the server has no way to know but to trust the client anyway.
*/
void
channel_permit_all(struct ssh *ssh, int where)
{
struct permission_set *pset = permission_set_get(ssh, where);
if (pset->num_permitted_user == 0)
pset->all_permitted = 1;
}
/*
* Permit the specified host/port for forwarding.
*/
void
channel_add_permission(struct ssh *ssh, int who, int where,
char *host, int port)
{
int local = where == FORWARD_LOCAL;
struct permission_set *pset = permission_set_get(ssh, where);
debug("allow %s forwarding to host %s port %d",
fwd_ident(who, where), host, port);
/*
* Remote forwards set listen_host/port, local forwards set
* host/port_to_connect.
*/
permission_set_add(ssh, who, where,
local ? host : 0, local ? port : 0,
local ? NULL : host, NULL, local ? 0 : port, NULL);
pset->all_permitted = 0;
}
/*
* Administratively disable forwarding.
*/
void
channel_disable_admin(struct ssh *ssh, int where)
{
channel_clear_permission(ssh, FORWARD_ADM, where);
permission_set_add(ssh, FORWARD_ADM, where,
NULL, 0, NULL, NULL, 0, NULL);
}
/*
* Clear a list of permitted opens.
*/
void
channel_clear_permission(struct ssh *ssh, int who, int where)
{
struct permission **permp;
u_int *npermp;
permission_set_get_array(ssh, who, where, &permp, &npermp);
*permp = xrecallocarray(*permp, *npermp, 0, sizeof(**permp));
*npermp = 0;
}
/*
* Update the listen port for a dynamic remote forward, after
* the actual 'newport' has been allocated. If 'newport' < 0 is
* passed then they entry will be invalidated.
*/
void
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_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",
newport > 0 ? "Updating" : "Removing",
newport,
pset->permitted_user[idx].host_to_connect,
pset->permitted_user[idx].port_to_connect);
if (newport <= 0)
fwd_perm_clear(&pset->permitted_user[idx]);
else {
pset->permitted_user[idx].listen_port =
(ssh->compat & SSH_BUG_DYNAMIC_RPORT) ? 0 : newport;
}
}
/* returns port number, FWD_PERMIT_ANY_PORT or -1 on error */
int
permitopen_port(const char *p)
{
int port;
if (strcmp(p, "*") == 0)
return FWD_PERMIT_ANY_PORT;
if ((port = a2port(p)) > 0)
return port;
return -1;
}
/* Try to start non-blocking connect to next host in cctx list */
static int
connect_next(struct channel_connect *cctx)
{
int sock, saved_errno;
struct sockaddr_un *sunaddr;
char ntop[NI_MAXHOST];
char strport[MAXIMUM(NI_MAXSERV, sizeof(sunaddr->sun_path))];
for (; cctx->ai; cctx->ai = cctx->ai->ai_next) {
switch (cctx->ai->ai_family) {
case AF_UNIX:
/* unix:pathname instead of host:port */
sunaddr = (struct sockaddr_un *)cctx->ai->ai_addr;
strlcpy(ntop, "unix", sizeof(ntop));
strlcpy(strport, sunaddr->sun_path, sizeof(strport));
break;
case AF_INET:
case AF_INET6:
if (getnameinfo(cctx->ai->ai_addr, cctx->ai->ai_addrlen,
ntop, sizeof(ntop), strport, sizeof(strport),
NI_NUMERICHOST|NI_NUMERICSERV) != 0) {
error_f("getnameinfo failed");
continue;
}
break;
default:
continue;
}
debug_f("start for host %.100s ([%.100s]:%s)",
cctx->host, ntop, strport);
if ((sock = socket(cctx->ai->ai_family, cctx->ai->ai_socktype,
cctx->ai->ai_protocol)) == -1) {
if (cctx->ai->ai_next == NULL)
error("socket: %.100s", strerror(errno));
else
verbose("socket: %.100s", strerror(errno));
continue;
}
if (set_nonblock(sock) == -1)
fatal_f("set_nonblock(%d)", sock);
if (connect(sock, cctx->ai->ai_addr,
cctx->ai->ai_addrlen) == -1 && errno != EINPROGRESS) {
debug_f("host %.100s ([%.100s]:%s): %.100s",
cctx->host, ntop, strport, strerror(errno));
saved_errno = errno;
close(sock);
errno = saved_errno;
continue; /* fail -- try next */
}
if (cctx->ai->ai_family != AF_UNIX)
set_nodelay(sock);
debug_f("connect host %.100s ([%.100s]:%s) in progress, fd=%d",
cctx->host, ntop, strport, sock);
cctx->ai = cctx->ai->ai_next;
return sock;
}
return -1;
}
static void
channel_connect_ctx_free(struct channel_connect *cctx)
{
free(cctx->host);
if (cctx->aitop) {
if (cctx->aitop->ai_family == AF_UNIX)
free(cctx->aitop);
else
freeaddrinfo(cctx->aitop);
}
memset(cctx, 0, sizeof(*cctx));
}
/*
* Return connecting socket to remote host:port or local socket path,
* passing back the failure reason if appropriate.
*/
static int
connect_to_helper(struct ssh *ssh, const char *name, int port, int socktype,
char *ctype, char *rname, struct channel_connect *cctx,
int *reason, const char **errmsg)
{
struct addrinfo hints;
int gaierr;
int sock = -1;
char strport[NI_MAXSERV];
if (port == PORT_STREAMLOCAL) {
struct sockaddr_un *sunaddr;
struct addrinfo *ai;
if (strlen(name) > sizeof(sunaddr->sun_path)) {
error("%.100s: %.100s", name, strerror(ENAMETOOLONG));
return -1;
}
/*
* Fake up a struct addrinfo for AF_UNIX connections.
* channel_connect_ctx_free() must check ai_family
* and use free() not freeaddirinfo() for AF_UNIX.
*/
ai = xmalloc(sizeof(*ai) + sizeof(*sunaddr));
memset(ai, 0, sizeof(*ai) + sizeof(*sunaddr));
ai->ai_addr = (struct sockaddr *)(ai + 1);
ai->ai_addrlen = sizeof(*sunaddr);
ai->ai_family = AF_UNIX;
ai->ai_socktype = socktype;
ai->ai_protocol = PF_UNSPEC;
sunaddr = (struct sockaddr_un *)ai->ai_addr;
sunaddr->sun_family = AF_UNIX;
strlcpy(sunaddr->sun_path, name, sizeof(sunaddr->sun_path));
cctx->aitop = ai;
} else {
memset(&hints, 0, sizeof(hints));
hints.ai_family = ssh->chanctxt->IPv4or6;
hints.ai_socktype = socktype;
snprintf(strport, sizeof strport, "%d", port);
if ((gaierr = getaddrinfo(name, strport, &hints, &cctx->aitop))
!= 0) {
if (errmsg != NULL)
*errmsg = ssh_gai_strerror(gaierr);
if (reason != NULL)
*reason = SSH2_OPEN_CONNECT_FAILED;
error("connect_to %.100s: unknown host (%s)", name,
ssh_gai_strerror(gaierr));
return -1;
}
}
cctx->host = xstrdup(name);
cctx->port = port;
cctx->ai = cctx->aitop;
if ((sock = connect_next(cctx)) == -1) {
error("connect to %.100s port %d failed: %s",
name, port, strerror(errno));
return -1;
}
return sock;
}
/* Return CONNECTING channel to remote host:port or local socket path */
static Channel *
connect_to(struct ssh *ssh, const char *host, int port,
char *ctype, char *rname)
{
struct channel_connect cctx;
Channel *c;
int sock;
memset(&cctx, 0, sizeof(cctx));
sock = connect_to_helper(ssh, host, port, SOCK_STREAM, ctype, rname,
&cctx, NULL, NULL);
if (sock == -1) {
channel_connect_ctx_free(&cctx);
return NULL;
}
c = channel_new(ssh, ctype, SSH_CHANNEL_CONNECTING, sock, sock, -1,
CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, rname, 1);
c->host_port = port;
c->path = xstrdup(host);
c->connect_ctx = cctx;
return c;
}
/*
* returns either the newly connected channel or the downstream channel
* that needs to deal with this connection.
*/
Channel *
channel_connect_by_listen_address(struct ssh *ssh, const char *listen_host,
u_short listen_port, char *ctype, char *rname)
{
struct ssh_channels *sc = ssh->chanctxt;
struct permission_set *pset = &sc->local_perms;
u_int i;
struct permission *perm;
for (i = 0; i < pset->num_permitted_user; i++) {
perm = &pset->permitted_user[i];
if (open_listen_match_tcpip(perm,
listen_host, listen_port, 1)) {
if (perm->downstream)
return perm->downstream;
if (perm->port_to_connect == 0)
return rdynamic_connect_prepare(ssh,
ctype, rname);
return connect_to(ssh,
perm->host_to_connect, perm->port_to_connect,
ctype, rname);
}
}
error("WARNING: Server requests forwarding for unknown listen_port %d",
listen_port);
return NULL;
}
Channel *
channel_connect_by_listen_path(struct ssh *ssh, const char *path,
char *ctype, char *rname)
{
struct ssh_channels *sc = ssh->chanctxt;
struct permission_set *pset = &sc->local_perms;
u_int i;
struct permission *perm;
for (i = 0; i < pset->num_permitted_user; i++) {
perm = &pset->permitted_user[i];
if (open_listen_match_streamlocal(perm, path)) {
return connect_to(ssh,
perm->host_to_connect, perm->port_to_connect,
ctype, rname);
}
}
error("WARNING: Server requests forwarding for unknown path %.100s",
path);
return NULL;
}
/* Check if connecting to that port is permitted and connect. */
Channel *
channel_connect_to_port(struct ssh *ssh, const char *host, u_short port,
char *ctype, char *rname, int *reason, const char **errmsg)
{
struct ssh_channels *sc = ssh->chanctxt;
struct permission_set *pset = &sc->local_perms;
struct channel_connect cctx;
Channel *c;
u_int i, permit, permit_adm = 1;
int sock;
struct permission *perm;
permit = pset->all_permitted;
if (!permit) {
for (i = 0; i < pset->num_permitted_user; i++) {
perm = &pset->permitted_user[i];
if (open_match(perm, host, port)) {
permit = 1;
break;
}
}
}
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, host, port)) {
permit_adm = 1;
break;
}
}
}
if (!permit || !permit_adm) {
logit("Received request from %.100s port %d to connect to "
"host %.100s port %d, but the request was denied.",
ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), host, port);
if (reason != NULL)
*reason = SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED;
return NULL;
}
memset(&cctx, 0, sizeof(cctx));
sock = connect_to_helper(ssh, host, port, SOCK_STREAM, ctype, rname,
&cctx, reason, errmsg);
if (sock == -1) {
channel_connect_ctx_free(&cctx);
return NULL;
}
c = channel_new(ssh, ctype, SSH_CHANNEL_CONNECTING, sock, sock, -1,
CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, rname, 1);
c->host_port = port;
c->path = xstrdup(host);
c->connect_ctx = cctx;
return c;
}
/* Check if connecting to that path is permitted and connect. */
Channel *
channel_connect_to_path(struct ssh *ssh, const char *path,
char *ctype, char *rname)
{
struct ssh_channels *sc = ssh->chanctxt;
struct permission_set *pset = &sc->local_perms;
u_int i, permit, permit_adm = 1;
struct permission *perm;
permit = pset->all_permitted;
if (!permit) {
for (i = 0; i < pset->num_permitted_user; i++) {
perm = &pset->permitted_user[i];
if (open_match(perm, path, PORT_STREAMLOCAL)) {
permit = 1;
break;
}
}
}
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, path, PORT_STREAMLOCAL)) {
permit_adm = 1;
break;
}
}
}
if (!permit || !permit_adm) {
logit("Received request to connect to path %.100s, "
"but the request was denied.", path);
return NULL;
}
return connect_to(ssh, path, PORT_STREAMLOCAL, ctype, rname);
}
void
channel_send_window_changes(struct ssh *ssh)
{
struct ssh_channels *sc = ssh->chanctxt;
struct winsize ws;
int r;
u_int i;
for (i = 0; i < sc->channels_alloc; i++) {
if (sc->channels[i] == NULL || !sc->channels[i]->client_tty ||
sc->channels[i]->type != SSH_CHANNEL_OPEN)
continue;
if (ioctl(sc->channels[i]->rfd, TIOCGWINSZ, &ws) == -1)
continue;
channel_request_start(ssh, i, "window-change", 0);
if ((r = sshpkt_put_u32(ssh, (u_int)ws.ws_col)) != 0 ||
(r = sshpkt_put_u32(ssh, (u_int)ws.ws_row)) != 0 ||
(r = sshpkt_put_u32(ssh, (u_int)ws.ws_xpixel)) != 0 ||
(r = sshpkt_put_u32(ssh, (u_int)ws.ws_ypixel)) != 0 ||
(r = sshpkt_send(ssh)) != 0)
fatal_fr(r, "channel %u; send window-change", i);
}
}
/* Return RDYNAMIC_OPEN channel: channel allows SOCKS, but is not connected */
static Channel *
rdynamic_connect_prepare(struct ssh *ssh, char *ctype, char *rname)
{
Channel *c;
int r;
c = channel_new(ssh, ctype, SSH_CHANNEL_RDYNAMIC_OPEN, -1, -1, -1,
CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, rname, 1);
c->host_port = 0;
c->path = NULL;
/*
* We need to open the channel before we have a FD,
* so that we can get SOCKS header from peer.
*/
if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION)) != 0 ||
(r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
(r = sshpkt_put_u32(ssh, c->self)) != 0 ||
(r = sshpkt_put_u32(ssh, c->local_window)) != 0 ||
(r = sshpkt_put_u32(ssh, c->local_maxpacket)) != 0)
fatal_fr(r, "channel %i; confirm", c->self);
return c;
}
/* Return CONNECTING socket to remote host:port or local socket path */
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);
if (sock == -1)
channel_connect_ctx_free(&cctx);
else {
/* similar to SSH_CHANNEL_CONNECTING but we've already sent the open */
c->type = SSH_CHANNEL_RDYNAMIC_FINISH;
c->connect_ctx = cctx;
channel_register_fds(ssh, c, sock, sock, -1, 0, 1, 0);
}
return sock;
}
/* -- X11 forwarding */
/*
* Creates an internet domain socket for listening for X11 connections.
* Returns 0 and a suitable display number for the DISPLAY variable
* stored in display_numberp , or -1 if an error occurs.
*/
int
x11_create_display_inet(struct ssh *ssh, int x11_display_offset,
int x11_use_localhost, int single_connection,
u_int *display_numberp, int **chanids)
{
Channel *nc = NULL;
int display_number, sock;
u_short port;
struct addrinfo hints, *ai, *aitop;
char strport[NI_MAXSERV];
int gaierr, n, num_socks = 0, socks[NUM_SOCKS];
if (chanids == NULL)
return -1;
for (display_number = x11_display_offset;
display_number < MAX_DISPLAYS;
display_number++) {
port = 6000 + display_number;
memset(&hints, 0, sizeof(hints));
hints.ai_family = ssh->chanctxt->IPv4or6;
hints.ai_flags = x11_use_localhost ? 0: AI_PASSIVE;
hints.ai_socktype = SOCK_STREAM;
snprintf(strport, sizeof strport, "%d", port);
if ((gaierr = getaddrinfo(NULL, strport,
&hints, &aitop)) != 0) {
error("getaddrinfo: %.100s", ssh_gai_strerror(gaierr));
return -1;
}
for (ai = aitop; ai; ai = ai->ai_next) {
if (ai->ai_family != AF_INET &&
ai->ai_family != AF_INET6)
continue;
sock = socket(ai->ai_family, ai->ai_socktype,
ai->ai_protocol);
if (sock == -1) {
if ((errno != EINVAL) && (errno != EAFNOSUPPORT)
#ifdef EPFNOSUPPORT
&& (errno != EPFNOSUPPORT)
#endif
) {
error("socket: %.100s", strerror(errno));
freeaddrinfo(aitop);
return -1;
} else {
debug("x11_create_display_inet: Socket family %d not supported",
ai->ai_family);
continue;
}
}
if (ai->ai_family == AF_INET6)
sock_set_v6only(sock);
if (x11_use_localhost)
set_reuseaddr(sock);
if (bind(sock, ai->ai_addr, ai->ai_addrlen) == -1) {
debug2_f("bind port %d: %.100s", port,
strerror(errno));
close(sock);
for (n = 0; n < num_socks; n++)
close(socks[n]);
num_socks = 0;
break;
}
socks[num_socks++] = sock;
if (num_socks == NUM_SOCKS)
break;
}
freeaddrinfo(aitop);
if (num_socks > 0)
break;
}
if (display_number >= MAX_DISPLAYS) {
error("Failed to allocate internet-domain X11 display socket.");
return -1;
}
/* Start listening for connections on the socket. */
for (n = 0; n < num_socks; n++) {
sock = socks[n];
if (listen(sock, SSH_LISTEN_BACKLOG) == -1) {
error("listen: %.100s", strerror(errno));
close(sock);
return -1;
}
}
/* Allocate a channel for each socket. */
*chanids = xcalloc(num_socks + 1, sizeof(**chanids));
for (n = 0; n < num_socks; n++) {
sock = socks[n];
- nc = channel_new(ssh, "x11 listener",
+ nc = channel_new(ssh, "x11-listener",
SSH_CHANNEL_X11_LISTENER, sock, sock, -1,
CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT,
0, "X11 inet listener", 1);
nc->single_connection = single_connection;
(*chanids)[n] = nc->self;
}
(*chanids)[n] = -1;
/* Return the display number for the DISPLAY environment variable. */
*display_numberp = display_number;
return 0;
}
static int
connect_local_xsocket_path(const char *pathname)
{
int sock;
struct sockaddr_un addr;
sock = socket(AF_UNIX, SOCK_STREAM, 0);
if (sock == -1)
error("socket: %.100s", strerror(errno));
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
strlcpy(addr.sun_path, pathname, sizeof addr.sun_path);
if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == 0)
return sock;
close(sock);
error("connect %.100s: %.100s", addr.sun_path, strerror(errno));
return -1;
}
static int
connect_local_xsocket(u_int dnr)
{
char buf[1024];
snprintf(buf, sizeof buf, _PATH_UNIX_X, dnr);
return connect_local_xsocket_path(buf);
}
#ifdef __APPLE__
static int
is_path_to_xsocket(const char *display, char *path, size_t pathlen)
{
struct stat sbuf;
if (strlcpy(path, display, pathlen) >= pathlen) {
error("%s: display path too long", __func__);
return 0;
}
if (display[0] != '/')
return 0;
if (stat(path, &sbuf) == 0) {
return 1;
} else {
char *dot = strrchr(path, '.');
if (dot != NULL) {
*dot = '\0';
if (stat(path, &sbuf) == 0) {
return 1;
}
}
}
return 0;
}
#endif
int
x11_connect_display(struct ssh *ssh)
{
u_int display_number;
const char *display;
char buf[1024], *cp;
struct addrinfo hints, *ai, *aitop;
char strport[NI_MAXSERV];
int gaierr, sock = 0;
/* Try to open a socket for the local X server. */
display = getenv("DISPLAY");
if (!display) {
error("DISPLAY not set.");
return -1;
}
/*
* Now we decode the value of the DISPLAY variable and make a
* connection to the real X server.
*/
#ifdef __APPLE__
/* Check if display is a path to a socket (as set by launchd). */
{
char path[PATH_MAX];
if (is_path_to_xsocket(display, path, sizeof(path))) {
debug("x11_connect_display: $DISPLAY is launchd");
/* Create a socket. */
sock = connect_local_xsocket_path(path);
if (sock < 0)
return -1;
/* OK, we now have a connection to the display. */
return sock;
}
}
#endif
/*
* Check if it is a unix domain socket. Unix domain displays are in
* one of the following formats: unix:d[.s], :d[.s], ::d[.s]
*/
if (strncmp(display, "unix:", 5) == 0 ||
display[0] == ':') {
/* Connect to the unix domain socket. */
if (sscanf(strrchr(display, ':') + 1, "%u",
&display_number) != 1) {
error("Could not parse display number from DISPLAY: "
"%.100s", display);
return -1;
}
/* Create a socket. */
sock = connect_local_xsocket(display_number);
if (sock < 0)
return -1;
/* OK, we now have a connection to the display. */
return sock;
}
/*
* Connect to an inet socket. The DISPLAY value is supposedly
* hostname:d[.s], where hostname may also be numeric IP address.
*/
strlcpy(buf, display, sizeof(buf));
cp = strchr(buf, ':');
if (!cp) {
error("Could not find ':' in DISPLAY: %.100s", display);
return -1;
}
*cp = 0;
/*
* buf now contains the host name. But first we parse the
* display number.
*/
if (sscanf(cp + 1, "%u", &display_number) != 1) {
error("Could not parse display number from DISPLAY: %.100s",
display);
return -1;
}
/* Look up the host address */
memset(&hints, 0, sizeof(hints));
hints.ai_family = ssh->chanctxt->IPv4or6;
hints.ai_socktype = SOCK_STREAM;
snprintf(strport, sizeof strport, "%u", 6000 + display_number);
if ((gaierr = getaddrinfo(buf, strport, &hints, &aitop)) != 0) {
error("%.100s: unknown host. (%s)", buf,
ssh_gai_strerror(gaierr));
return -1;
}
for (ai = aitop; ai; ai = ai->ai_next) {
/* Create a socket. */
sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
if (sock == -1) {
debug2("socket: %.100s", strerror(errno));
continue;
}
/* Connect it to the display. */
if (connect(sock, ai->ai_addr, ai->ai_addrlen) == -1) {
debug2("connect %.100s port %u: %.100s", buf,
6000 + display_number, strerror(errno));
close(sock);
continue;
}
/* Success */
break;
}
freeaddrinfo(aitop);
if (!ai) {
error("connect %.100s port %u: %.100s", buf,
6000 + display_number, strerror(errno));
return -1;
}
set_nodelay(sock);
return sock;
}
/*
* Requests forwarding of X11 connections, generates fake authentication
* data, and enables authentication spoofing.
* This should be called in the client only.
*/
void
x11_request_forwarding_with_spoofing(struct ssh *ssh, int client_session_id,
const char *disp, const char *proto, const char *data, int want_reply)
{
struct ssh_channels *sc = ssh->chanctxt;
u_int data_len = (u_int) strlen(data) / 2;
u_int i, value;
const char *cp;
char *new_data;
int r, screen_number;
if (sc->x11_saved_display == NULL)
sc->x11_saved_display = xstrdup(disp);
else if (strcmp(disp, sc->x11_saved_display) != 0) {
error("x11_request_forwarding_with_spoofing: different "
"$DISPLAY already forwarded");
return;
}
cp = strchr(disp, ':');
if (cp)
cp = strchr(cp, '.');
if (cp)
screen_number = (u_int)strtonum(cp + 1, 0, 400, NULL);
else
screen_number = 0;
if (sc->x11_saved_proto == NULL) {
/* Save protocol name. */
sc->x11_saved_proto = xstrdup(proto);
/* 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) {
fatal("x11_request_forwarding: bad "
"authentication data: %.100s", data);
}
sc->x11_saved_data[i] = value;
}
sc->x11_saved_data_len = data_len;
/* Generate fake data of the same length. */
sc->x11_fake_data = xmalloc(data_len);
arc4random_buf(sc->x11_fake_data, data_len);
sc->x11_fake_data_len = data_len;
}
/* Convert the fake data into hex. */
new_data = tohex(sc->x11_fake_data, data_len);
/* Send the request packet. */
channel_request_start(ssh, client_session_id, "x11-req", want_reply);
if ((r = sshpkt_put_u8(ssh, 0)) != 0 || /* bool: single connection */
(r = sshpkt_put_cstring(ssh, proto)) != 0 ||
(r = sshpkt_put_cstring(ssh, new_data)) != 0 ||
(r = sshpkt_put_u32(ssh, screen_number)) != 0 ||
(r = sshpkt_send(ssh)) != 0 ||
(r = ssh_packet_write_wait(ssh)) != 0)
fatal_fr(r, "send x11-req");
free(new_data);
}
diff --git a/crypto/openssh/channels.h b/crypto/openssh/channels.h
index 828c1b61b443..101843a06d15 100644
--- a/crypto/openssh/channels.h
+++ b/crypto/openssh/channels.h
@@ -1,383 +1,399 @@
-/* $OpenBSD: channels.h,v 1.143 2022/05/05 00:56:58 djm Exp $ */
+/* $OpenBSD: channels.h,v 1.148 2023/01/18 02:00:10 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
*
* As far as I am concerned, the code I have written for this software
* can be used freely for any purpose. Any derived versions of this
* software must be clearly marked as such, and if the derived work is
* incompatible with the protocol description in the RFC file, it must be
* called by a name other than "ssh" or "Secure Shell".
*/
/*
* Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef CHANNEL_H
#define CHANNEL_H
/* Definitions for channel types. */
#define SSH_CHANNEL_X11_LISTENER 1 /* Listening for inet X11 conn. */
#define SSH_CHANNEL_PORT_LISTENER 2 /* Listening on a port. */
#define SSH_CHANNEL_OPENING 3 /* waiting for confirmation */
#define SSH_CHANNEL_OPEN 4 /* normal open two-way channel */
#define SSH_CHANNEL_CLOSED 5 /* waiting for close confirmation */
#define SSH_CHANNEL_AUTH_SOCKET 6 /* authentication socket */
#define SSH_CHANNEL_X11_OPEN 7 /* reading first X11 packet */
#define SSH_CHANNEL_LARVAL 10 /* larval session */
#define SSH_CHANNEL_RPORT_LISTENER 11 /* Listening to a R-style port */
#define SSH_CHANNEL_CONNECTING 12
#define SSH_CHANNEL_DYNAMIC 13
#define SSH_CHANNEL_ZOMBIE 14 /* Almost dead. */
#define SSH_CHANNEL_MUX_LISTENER 15 /* Listener for mux conn. */
#define SSH_CHANNEL_MUX_CLIENT 16 /* Conn. to mux client */
#define SSH_CHANNEL_ABANDONED 17 /* Abandoned session, eg mux */
#define SSH_CHANNEL_UNIX_LISTENER 18 /* Listening on a domain socket. */
#define SSH_CHANNEL_RUNIX_LISTENER 19 /* Listening to a R-style domain socket. */
#define SSH_CHANNEL_MUX_PROXY 20 /* proxy channel for mux-client */
#define SSH_CHANNEL_RDYNAMIC_OPEN 21 /* reverse SOCKS, parsing request */
#define SSH_CHANNEL_RDYNAMIC_FINISH 22 /* reverse SOCKS, finishing connect */
#define SSH_CHANNEL_MAX_TYPE 23
#define CHANNEL_CANCEL_PORT_STATIC -1
/* nonblocking flags for channel_new */
#define CHANNEL_NONBLOCK_LEAVE 0 /* don't modify non-blocking state */
#define CHANNEL_NONBLOCK_SET 1 /* set non-blocking state */
#define CHANNEL_NONBLOCK_STDIO 2 /* set non-blocking and restore on close */
/* c->restore_block mask flags */
#define CHANNEL_RESTORE_RFD 0x01
#define CHANNEL_RESTORE_WFD 0x02
#define CHANNEL_RESTORE_EFD 0x04
/* TCP forwarding */
#define FORWARD_DENY 0
#define FORWARD_REMOTE (1)
#define FORWARD_LOCAL (1<<1)
#define FORWARD_ALLOW (FORWARD_REMOTE|FORWARD_LOCAL)
#define FORWARD_ADM 0x100
#define FORWARD_USER 0x101
struct ssh;
struct Channel;
typedef struct Channel Channel;
struct fwd_perm_list;
typedef void channel_open_fn(struct ssh *, int, int, void *);
-typedef void channel_callback_fn(struct ssh *, int, void *);
+typedef void channel_callback_fn(struct ssh *, int, int, void *);
typedef int channel_infilter_fn(struct ssh *, struct Channel *, char *, int);
typedef void channel_filter_cleanup_fn(struct ssh *, int, void *);
typedef u_char *channel_outfilter_fn(struct ssh *, struct Channel *,
u_char **, size_t *);
/* Channel success/failure callbacks */
typedef void channel_confirm_cb(struct ssh *, int, struct Channel *, void *);
typedef void channel_confirm_abandon_cb(struct ssh *, struct Channel *, void *);
struct channel_confirm {
TAILQ_ENTRY(channel_confirm) entry;
channel_confirm_cb *cb;
channel_confirm_abandon_cb *abandon_cb;
void *ctx;
};
TAILQ_HEAD(channel_confirms, channel_confirm);
/* Context for non-blocking connects */
struct channel_connect {
char *host;
int port;
struct addrinfo *ai, *aitop;
};
/* Callbacks for mux channels back into client-specific code */
typedef int mux_callback_fn(struct ssh *, struct Channel *);
/*
* NB. channel IDs on the wire and in c->remote_id are uint32, but local
* channel IDs (e.g. c->self) only ever use the int32 subset of this range,
* because we use local channel ID -1 for housekeeping. Remote channels have
* a dedicated "have_remote_id" flag to indicate their validity.
*/
struct Channel {
int type; /* channel type/state */
int self; /* my own channel identifier */
uint32_t remote_id; /* channel identifier for remote peer */
int have_remote_id; /* non-zero if remote_id is valid */
u_int istate; /* input from channel (state of receive half) */
u_int ostate; /* output to channel (state of transmit half) */
int flags; /* close sent/rcvd */
int rfd; /* read fd */
int wfd; /* write fd */
int efd; /* extended fd */
int sock; /* sock fd */
u_int io_want; /* bitmask of SSH_CHAN_IO_* */
u_int io_ready; /* bitmask of SSH_CHAN_IO_* */
int pfds[4]; /* pollfd entries for rfd/wfd/efd/sock */
int ctl_chan; /* control channel (multiplexed connections) */
int isatty; /* rfd is a tty */
#ifdef _AIX
int wfd_isatty; /* wfd is a tty */
#endif
int client_tty; /* (client) TTY has been requested */
int force_drain; /* force close on iEOF */
time_t notbefore; /* Pause IO until deadline (time_t) */
int delayed; /* post-IO handlers for newly created
* channels are delayed until the first call
* to a matching pre-IO handler.
* this way post-IO handlers are not
* accidentally called if a FD gets reused */
int restore_block; /* fd mask to restore blocking status */
+ int restore_flags[3];/* flags to restore */
struct sshbuf *input; /* data read from socket, to be sent over
* encrypted connection */
struct sshbuf *output; /* data received over encrypted connection for
* send on socket */
struct sshbuf *extended;
char *path;
/* path for unix domain sockets, or host name for forwards */
int listening_port; /* port being listened for forwards */
char *listening_addr; /* addr being listened for forwards */
int host_port; /* remote port to connect for forwards */
char *remote_name; /* remote hostname */
u_int remote_window;
u_int remote_maxpacket;
u_int local_window;
u_int local_window_max;
u_int local_consumed;
u_int local_maxpacket;
int extended_usage;
int single_connection;
- char *ctype; /* type */
+ char *ctype; /* const type - NB. not freed on channel_free */
+ char *xctype; /* extended type */
/* callback */
channel_open_fn *open_confirm;
void *open_confirm_ctx;
channel_callback_fn *detach_user;
int detach_close;
struct channel_confirms status_confirms;
/* filter */
channel_infilter_fn *input_filter;
channel_outfilter_fn *output_filter;
void *filter_ctx;
channel_filter_cleanup_fn *filter_cleanup;
/* keep boundaries */
int datagram;
/* non-blocking connect */
/* XXX make this a pointer so the structure can be opaque */
struct channel_connect connect_ctx;
/* multiplexing protocol hook, called for each packet received */
mux_callback_fn *mux_rcb;
void *mux_ctx;
int mux_pause;
int mux_downstream_id;
+
+ /* Inactivity timeouts */
+
+ /* Last traffic seen for OPEN channels */
+ time_t lastused;
+ /* Inactivity timeout deadline in seconds (0 = no timeout) */
+ u_int inactive_deadline;
};
#define CHAN_EXTENDED_IGNORE 0
#define CHAN_EXTENDED_READ 1
#define CHAN_EXTENDED_WRITE 2
/* default window/packet sizes for tcp/x11-fwd-channel */
#define CHAN_SES_PACKET_DEFAULT (32*1024)
#define CHAN_SES_WINDOW_DEFAULT (64*CHAN_SES_PACKET_DEFAULT)
#define CHAN_TCP_PACKET_DEFAULT (32*1024)
#define CHAN_TCP_WINDOW_DEFAULT (64*CHAN_TCP_PACKET_DEFAULT)
#define CHAN_X11_PACKET_DEFAULT (16*1024)
#define CHAN_X11_WINDOW_DEFAULT (4*CHAN_X11_PACKET_DEFAULT)
/* possible input states */
#define CHAN_INPUT_OPEN 0
#define CHAN_INPUT_WAIT_DRAIN 1
#define CHAN_INPUT_WAIT_OCLOSE 2
#define CHAN_INPUT_CLOSED 3
/* possible output states */
#define CHAN_OUTPUT_OPEN 0
#define CHAN_OUTPUT_WAIT_DRAIN 1
#define CHAN_OUTPUT_WAIT_IEOF 2
#define CHAN_OUTPUT_CLOSED 3
#define CHAN_CLOSE_SENT 0x01
#define CHAN_CLOSE_RCVD 0x02
#define CHAN_EOF_SENT 0x04
#define CHAN_EOF_RCVD 0x08
#define CHAN_LOCAL 0x10
/* file descriptor events */
#define SSH_CHAN_IO_RFD 0x01
#define SSH_CHAN_IO_WFD 0x02
#define SSH_CHAN_IO_EFD_R 0x04
#define SSH_CHAN_IO_EFD_W 0x08
#define SSH_CHAN_IO_EFD (SSH_CHAN_IO_EFD_R|SSH_CHAN_IO_EFD_W)
#define SSH_CHAN_IO_SOCK_R 0x10
#define SSH_CHAN_IO_SOCK_W 0x20
#define SSH_CHAN_IO_SOCK (SSH_CHAN_IO_SOCK_R|SSH_CHAN_IO_SOCK_W)
/* Read buffer size */
#define CHAN_RBUF (16*1024)
/* Maximum size for direct reads to buffers */
#define CHANNEL_MAX_READ CHAN_SES_PACKET_DEFAULT
/* Maximum channel input buffer size */
#define CHAN_INPUT_MAX (16*1024*1024)
/* Hard limit on number of channels */
#define CHANNELS_MAX_CHANNELS (16*1024)
/* check whether 'efd' is still in use */
#define CHANNEL_EFD_INPUT_ACTIVE(c) \
(c->extended_usage == CHAN_EXTENDED_READ && \
(c->efd != -1 || \
sshbuf_len(c->extended) > 0))
#define CHANNEL_EFD_OUTPUT_ACTIVE(c) \
(c->extended_usage == CHAN_EXTENDED_WRITE && \
c->efd != -1 && (!(c->flags & (CHAN_EOF_RCVD|CHAN_CLOSE_RCVD)) || \
sshbuf_len(c->extended) > 0))
/* Add channel management structures to SSH transport instance */
void channel_init_channels(struct ssh *ssh);
/* channel management */
Channel *channel_by_id(struct ssh *, int);
Channel *channel_by_remote_id(struct ssh *, u_int);
Channel *channel_lookup(struct ssh *, int);
Channel *channel_new(struct ssh *, char *, int, int, int, int,
u_int, u_int, int, const char *, int);
void channel_set_fds(struct ssh *, int, int, int, int, int,
int, int, u_int);
void channel_free(struct ssh *, Channel *);
void channel_free_all(struct ssh *);
void channel_stop_listening(struct ssh *);
+void channel_force_close(struct ssh *, Channel *, int);
+void channel_set_xtype(struct ssh *, int, const char *);
void channel_send_open(struct ssh *, int);
void channel_request_start(struct ssh *, int, char *, int);
void channel_register_cleanup(struct ssh *, int,
channel_callback_fn *, int);
void channel_register_open_confirm(struct ssh *, int,
channel_open_fn *, void *);
void channel_register_filter(struct ssh *, int, channel_infilter_fn *,
channel_outfilter_fn *, channel_filter_cleanup_fn *, void *);
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 *, Channel *, int *);
void channel_send_window_changes(struct ssh *);
+/* channel inactivity timeouts */
+void channel_add_timeout(struct ssh *, const char *, u_int);
+void channel_clear_timeouts(struct ssh *);
+
/* mux proxy support */
int channel_proxy_downstream(struct ssh *, Channel *mc);
int channel_proxy_upstream(Channel *, int, u_int32_t, struct ssh *);
/* protocol handler */
int channel_input_data(int, u_int32_t, struct ssh *);
int channel_input_extended_data(int, u_int32_t, struct ssh *);
int channel_input_ieof(int, u_int32_t, struct ssh *);
int channel_input_oclose(int, u_int32_t, struct ssh *);
int channel_input_open_confirmation(int, u_int32_t, struct ssh *);
int channel_input_open_failure(int, u_int32_t, struct ssh *);
int channel_input_port_open(int, u_int32_t, struct ssh *);
int channel_input_window_adjust(int, u_int32_t, struct ssh *);
int channel_input_status_confirm(int, u_int32_t, struct ssh *);
/* file descriptor handling (read/write) */
struct pollfd;
+struct timespec;
void channel_prepare_poll(struct ssh *, struct pollfd **,
- u_int *, u_int *, u_int, time_t *);
+ u_int *, u_int *, u_int, struct timespec *);
void channel_after_poll(struct ssh *, struct pollfd *, u_int);
void channel_output_poll(struct ssh *);
int channel_not_very_much_buffered_data(struct ssh *);
void channel_close_all(struct ssh *);
int channel_still_open(struct ssh *);
const char *channel_format_extended_usage(const Channel *);
char *channel_open_message(struct ssh *);
int channel_find_open(struct ssh *);
/* tcp forwarding */
struct Forward;
struct ForwardOptions;
void channel_set_af(struct ssh *, int af);
void channel_permit_all(struct ssh *, int);
void channel_add_permission(struct ssh *, int, int, char *, int);
void channel_clear_permission(struct ssh *, int, int);
void channel_disable_admin(struct ssh *, int);
void channel_update_permission(struct ssh *, int, int);
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, 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 *,
char *, char *);
int channel_request_remote_forwarding(struct ssh *, struct Forward *);
int channel_setup_local_fwd_listener(struct ssh *, struct Forward *,
struct ForwardOptions *);
int channel_request_rforward_cancel(struct ssh *, struct Forward *);
int channel_setup_remote_fwd_listener(struct ssh *, struct Forward *,
int *, struct ForwardOptions *);
int channel_cancel_rport_listener(struct ssh *, struct Forward *);
int channel_cancel_lport_listener(struct ssh *, struct Forward *,
int, struct ForwardOptions *);
int permitopen_port(const char *);
/* x11 forwarding */
void channel_set_x11_refuse_time(struct ssh *, u_int);
int x11_connect_display(struct ssh *);
int x11_create_display_inet(struct ssh *, int, int, int, u_int *, int **);
void x11_request_forwarding_with_spoofing(struct ssh *, int,
const char *, const char *, const char *, int);
/* channel close */
int chan_is_dead(struct ssh *, Channel *, int);
void chan_mark_dead(struct ssh *, Channel *);
/* channel events */
void chan_rcvd_oclose(struct ssh *, Channel *);
void chan_rcvd_eow(struct ssh *, Channel *);
void chan_read_failed(struct ssh *, Channel *);
void chan_ibuf_empty(struct ssh *, Channel *);
void chan_rcvd_ieof(struct ssh *, Channel *);
void chan_write_failed(struct ssh *, Channel *);
void chan_obuf_empty(struct ssh *, Channel *);
#endif
diff --git a/crypto/openssh/clientloop.c b/crypto/openssh/clientloop.c
index 0050f3eb6faa..fef9efc6cc3a 100644
--- a/crypto/openssh/clientloop.c
+++ b/crypto/openssh/clientloop.c
@@ -1,2625 +1,2698 @@
-/* $OpenBSD: clientloop.c,v 1.380 2022/06/03 04:30:46 djm Exp $ */
+/* $OpenBSD: clientloop.c,v 1.387 2023/01/06 02:39:59 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
* The main loop for the interactive session (client side).
*
* As far as I am concerned, the code I have written for this software
* can be used freely for any purpose. Any derived versions of this
* software must be clearly marked as such, and if the derived work is
* incompatible with the protocol description in the RFC file, it must be
* called by a name other than "ssh" or "Secure Shell".
*
*
* Copyright (c) 1999 Theo de Raadt. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
* SSH2 support added by Markus Friedl.
* Copyright (c) 1999, 2000, 2001 Markus Friedl. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "includes.h"
#include <sys/types.h>
#include <sys/ioctl.h>
#ifdef HAVE_SYS_STAT_H
# include <sys/stat.h>
#endif
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
#endif
#include <sys/socket.h>
#include <ctype.h>
#include <errno.h>
#ifdef HAVE_PATHS_H
#include <paths.h>
#endif
#ifdef HAVE_POLL_H
#include <poll.h>
#endif
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <termios.h>
#include <pwd.h>
#include <unistd.h>
#include <limits.h>
#include "openbsd-compat/sys-queue.h"
#include "xmalloc.h"
#include "ssh.h"
#include "ssh2.h"
#include "packet.h"
#include "sshbuf.h"
#include "compat.h"
#include "channels.h"
#include "dispatch.h"
#include "sshkey.h"
#include "cipher.h"
#include "kex.h"
#include "myproposal.h"
#include "log.h"
#include "misc.h"
#include "readconf.h"
#include "clientloop.h"
#include "sshconnect.h"
#include "authfd.h"
#include "atomicio.h"
#include "sshpty.h"
#include "match.h"
#include "msg.h"
#include "ssherr.h"
#include "hostfile.h"
/* Permitted RSA signature algorithms for UpdateHostkeys proofs */
#define HOSTKEY_PROOF_RSA_ALGS "rsa-sha2-512,rsa-sha2-256"
/* import options */
extern Options options;
/* Control socket */
extern int muxserver_sock; /* XXX use mux_client_cleanup() instead */
/*
* Name of the host we are connecting to. This is the name given on the
* command line, or the Hostname specified for the user-supplied name in a
* configuration file.
*/
extern char *host;
/*
* If this field is not NULL, the ForwardAgent socket is this path and different
* instead of SSH_AUTH_SOCK.
*/
extern char *forward_agent_sock_path;
/*
* Flag to indicate that we have received a window change signal which has
* not yet been processed. This will cause a message indicating the new
* window size to be sent to the server a little later. This is volatile
* because this is updated in a signal handler.
*/
static volatile sig_atomic_t received_window_change_signal = 0;
static volatile sig_atomic_t received_signal = 0;
/* Time when backgrounded control master using ControlPersist should exit */
static time_t control_persist_exit_time = 0;
/* Common data for the client loop code. */
volatile sig_atomic_t quit_pending; /* Set non-zero to quit the loop. */
static int last_was_cr; /* Last character was a newline. */
static int exit_status; /* Used to store the command exit status. */
static struct sshbuf *stderr_buffer; /* Used for final exit message. */
static int connection_in; /* Connection to server (input). */
static int connection_out; /* Connection to server (output). */
static int need_rekeying; /* Set to non-zero if rekeying is requested. */
static int session_closed; /* In SSH2: login session closed. */
static u_int x11_refuse_time; /* If >0, refuse x11 opens after this time. */
static time_t server_alive_time; /* Time to do server_alive_check */
+static int hostkeys_update_complete;
+static int session_setup_complete;
static void client_init_dispatch(struct ssh *ssh);
int session_ident = -1;
/* Track escape per proto2 channel */
struct escape_filter_ctx {
int escape_pending;
int escape_char;
};
/* Context for channel confirmation replies */
struct channel_reply_ctx {
const char *request_type;
int id;
enum confirm_action action;
};
/* Global request success/failure callbacks */
/* XXX move to struct ssh? */
struct global_confirm {
TAILQ_ENTRY(global_confirm) entry;
global_confirm_cb *cb;
void *ctx;
int ref_count;
};
TAILQ_HEAD(global_confirms, global_confirm);
static struct global_confirms global_confirms =
TAILQ_HEAD_INITIALIZER(global_confirms);
void ssh_process_session2_setup(int, int, int, struct sshbuf *);
static void quit_message(const char *fmt, ...)
__attribute__((__format__ (printf, 1, 2)));
static void
quit_message(const char *fmt, ...)
{
char *msg;
va_list args;
int r;
va_start(args, fmt);
xvasprintf(&msg, fmt, args);
va_end(args);
if ((r = sshbuf_putf(stderr_buffer, "%s\r\n", msg)) != 0)
fatal_fr(r, "sshbuf_putf");
quit_pending = 1;
}
/*
* Signal handler for the window change signal (SIGWINCH). This just sets a
* flag indicating that the window has changed.
*/
/*ARGSUSED */
static void
window_change_handler(int sig)
{
received_window_change_signal = 1;
}
/*
* Signal handler for signals that cause the program to terminate. These
* signals must be trapped to restore terminal modes.
*/
/*ARGSUSED */
static void
signal_handler(int sig)
{
received_signal = sig;
quit_pending = 1;
}
/*
* Sets control_persist_exit_time to the absolute time when the
* backgrounded control master should exit due to expiry of the
* ControlPersist timeout. Sets it to 0 if we are not a backgrounded
* control master process, or if there is no ControlPersist timeout.
*/
static void
set_control_persist_exit_time(struct ssh *ssh)
{
if (muxserver_sock == -1 || !options.control_persist
|| options.control_persist_timeout == 0) {
/* not using a ControlPersist timeout */
control_persist_exit_time = 0;
} else if (channel_still_open(ssh)) {
/* some client connections are still open */
if (control_persist_exit_time > 0)
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_f("schedule exit in %d seconds",
options.control_persist_timeout);
}
/* else we are already counting down to the timeout */
}
#define SSH_X11_VALID_DISPLAY_CHARS ":/.-_"
static int
client_x11_display_valid(const char *display)
{
size_t i, dlen;
if (display == NULL)
return 0;
dlen = strlen(display);
for (i = 0; i < dlen; i++) {
if (!isalnum((u_char)display[i]) &&
strchr(SSH_X11_VALID_DISPLAY_CHARS, display[i]) == NULL) {
debug("Invalid character '%c' in DISPLAY", display[i]);
return 0;
}
}
return 1;
}
#define SSH_X11_PROTO "MIT-MAGIC-COOKIE-1"
#define X11_TIMEOUT_SLACK 60
int
client_x11_get_proto(struct ssh *ssh, const char *display,
const char *xauth_path, u_int trusted, u_int timeout,
char **_proto, char **_data)
{
char *cmd, line[512], xdisplay[512];
char xauthfile[PATH_MAX], xauthdir[PATH_MAX];
static char proto[512], data[512];
FILE *f;
int got_data = 0, generated = 0, do_unlink = 0, r;
struct stat st;
u_int now, x11_timeout_real;
*_proto = proto;
*_data = data;
proto[0] = data[0] = xauthfile[0] = xauthdir[0] = '\0';
if (!client_x11_display_valid(display)) {
if (display != NULL)
logit("DISPLAY \"%s\" invalid; disabling X11 forwarding",
display);
return -1;
}
if (xauth_path != NULL && stat(xauth_path, &st) == -1) {
debug("No xauth program.");
xauth_path = NULL;
}
if (xauth_path != NULL) {
/*
* Handle FamilyLocal case where $DISPLAY does
* not match an authorization entry. For this we
* just try "xauth list unix:displaynum.screennum".
* XXX: "localhost" match to determine FamilyLocal
* is not perfect.
*/
if (strncmp(display, "localhost:", 10) == 0) {
if ((r = snprintf(xdisplay, sizeof(xdisplay), "unix:%s",
display + 10)) < 0 ||
(size_t)r >= sizeof(xdisplay)) {
error_f("display name too long");
return -1;
}
display = xdisplay;
}
if (trusted == 0) {
/*
* Generate an untrusted X11 auth cookie.
*
* The authentication cookie should briefly outlive
* ssh's willingness to forward X11 connections to
* avoid nasty fail-open behaviour in the X server.
*/
mktemp_proto(xauthdir, sizeof(xauthdir));
if (mkdtemp(xauthdir) == NULL) {
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_f("xauthfile path too long");
rmdir(xauthdir);
return -1;
}
if (timeout == 0) {
/* auth doesn't time out */
xasprintf(&cmd, "%s -f %s generate %s %s "
"untrusted 2>%s",
xauth_path, xauthfile, display,
SSH_X11_PROTO, _PATH_DEVNULL);
} else {
/* Add some slack to requested expiry */
if (timeout < UINT_MAX - X11_TIMEOUT_SLACK)
x11_timeout_real = timeout +
X11_TIMEOUT_SLACK;
else {
/* Don't overflow on long timeouts */
x11_timeout_real = UINT_MAX;
}
xasprintf(&cmd, "%s -f %s generate %s %s "
"untrusted timeout %u 2>%s",
xauth_path, xauthfile, display,
SSH_X11_PROTO, x11_timeout_real,
_PATH_DEVNULL);
}
debug2_f("xauth command: %s", cmd);
if (timeout != 0 && x11_refuse_time == 0) {
now = monotime() + 1;
if (UINT_MAX - timeout < now)
x11_refuse_time = UINT_MAX;
else
x11_refuse_time = now + timeout;
channel_set_x11_refuse_time(ssh,
x11_refuse_time);
}
if (system(cmd) == 0)
generated = 1;
free(cmd);
}
/*
* When in untrusted mode, we read the cookie only if it was
* successfully generated as an untrusted one in the step
* above.
*/
if (trusted || generated) {
xasprintf(&cmd,
"%s %s%s list %s 2>" _PATH_DEVNULL,
xauth_path,
generated ? "-f " : "" ,
generated ? xauthfile : "",
display);
debug2("x11_get_proto: %s", cmd);
f = popen(cmd, "r");
if (f && fgets(line, sizeof(line), f) &&
sscanf(line, "%*s %511s %511s", proto, data) == 2)
got_data = 1;
if (f)
pclose(f);
free(cmd);
}
}
if (do_unlink) {
unlink(xauthfile);
rmdir(xauthdir);
}
/* Don't fall back to fake X11 data for untrusted forwarding */
if (!trusted && !got_data) {
error("Warning: untrusted X11 forwarding setup failed: "
"xauth key data not generated");
return -1;
}
/*
* If we didn't get authentication data, just make up some
* data. The forwarding code will check the validity of the
* response anyway, and substitute this data. The X11
* server, however, will ignore this fake data and use
* whatever authentication mechanisms it was using otherwise
* for the local connection.
*/
if (!got_data) {
u_int8_t rnd[16];
u_int i;
logit("Warning: No xauth data; "
"using fake authentication data for X11 forwarding.");
strlcpy(proto, SSH_X11_PROTO, sizeof proto);
arc4random_buf(rnd, sizeof(rnd));
for (i = 0; i < sizeof(rnd); i++) {
snprintf(data + 2 * i, sizeof data - 2 * i, "%02x",
rnd[i]);
}
}
return 0;
}
/*
* Checks if the client window has changed, and sends a packet about it to
* the server if so. The actual change is detected elsewhere (by a software
* interrupt on Unix); this just checks the flag and sends a message if
* appropriate.
*/
static void
client_check_window_change(struct ssh *ssh)
{
if (!received_window_change_signal)
return;
received_window_change_signal = 0;
debug2_f("changed");
channel_send_window_changes(ssh);
}
static int
client_global_request_reply(int type, u_int32_t seq, struct ssh *ssh)
{
struct global_confirm *gc;
if ((gc = TAILQ_FIRST(&global_confirms)) == NULL)
return 0;
if (gc->cb != NULL)
gc->cb(ssh, type, seq, gc->ctx);
if (--gc->ref_count <= 0) {
TAILQ_REMOVE(&global_confirms, gc, entry);
freezero(gc, sizeof(*gc));
}
ssh_packet_set_alive_timeouts(ssh, 0);
return 0;
}
static void
schedule_server_alive_check(void)
{
if (options.server_alive_interval > 0)
server_alive_time = monotime() + options.server_alive_interval;
}
static void
server_alive_check(struct ssh *ssh)
{
int r;
if (ssh_packet_inc_alive_timeouts(ssh) > options.server_alive_count_max) {
logit("Timeout, server %s not responding.", host);
cleanup_exit(255);
}
if ((r = sshpkt_start(ssh, SSH2_MSG_GLOBAL_REQUEST)) != 0 ||
(r = sshpkt_put_cstring(ssh, "keepalive@openssh.com")) != 0 ||
(r = sshpkt_put_u8(ssh, 1)) != 0 || /* boolean: want reply */
(r = sshpkt_send(ssh)) != 0)
fatal_fr(r, "send packet");
/* Insert an empty placeholder to maintain ordering */
client_register_global_confirm(NULL, NULL);
schedule_server_alive_check();
}
/*
* Waits until the client can do something (some data becomes available on
* one of the file descriptors).
*/
static void
client_wait_until_can_do_something(struct ssh *ssh, struct pollfd **pfdp,
u_int *npfd_allocp, u_int *npfd_activep, int rekeying,
int *conn_in_readyp, int *conn_out_readyp)
{
- int timeout_secs, pollwait;
- time_t minwait_secs = 0, now = monotime();
+ struct timespec timeout;
int ret;
u_int p;
*conn_in_readyp = *conn_out_readyp = 0;
/* Prepare channel poll. First two pollfd entries are reserved */
- channel_prepare_poll(ssh, pfdp, npfd_allocp, npfd_activep, 2,
- &minwait_secs);
+ ptimeout_init(&timeout);
+ channel_prepare_poll(ssh, pfdp, npfd_allocp, npfd_activep, 2, &timeout);
if (*npfd_activep < 2)
fatal_f("bad npfd %u", *npfd_activep); /* shouldn't happen */
/* channel_prepare_poll could have closed the last channel */
if (session_closed && !channel_still_open(ssh) &&
!ssh_packet_have_data_to_write(ssh)) {
/* clear events since we did not call poll() */
for (p = 0; p < *npfd_activep; p++)
(*pfdp)[p].revents = 0;
return;
}
/* Monitor server connection on reserved pollfd entries */
(*pfdp)[0].fd = connection_in;
(*pfdp)[0].events = POLLIN;
(*pfdp)[1].fd = connection_out;
(*pfdp)[1].events = ssh_packet_have_data_to_write(ssh) ? POLLOUT : 0;
/*
* Wait for something to happen. This will suspend the process until
* some polled descriptor can be read, written, or has some other
* event pending, or a timeout expires.
*/
-
- timeout_secs = INT_MAX; /* we use INT_MAX to mean no timeout */
+ set_control_persist_exit_time(ssh);
+ if (control_persist_exit_time > 0)
+ ptimeout_deadline_monotime(&timeout, control_persist_exit_time);
if (options.server_alive_interval > 0)
- timeout_secs = MAXIMUM(server_alive_time - now, 0);
- if (options.rekey_interval > 0 && !rekeying)
- timeout_secs = MINIMUM(timeout_secs,
+ ptimeout_deadline_monotime(&timeout, server_alive_time);
+ if (options.rekey_interval > 0 && !rekeying) {
+ ptimeout_deadline_sec(&timeout,
ssh_packet_get_rekey_timeout(ssh));
- set_control_persist_exit_time(ssh);
- if (control_persist_exit_time > 0) {
- timeout_secs = MINIMUM(timeout_secs,
- control_persist_exit_time - now);
- if (timeout_secs < 0)
- timeout_secs = 0;
- }
- if (minwait_secs != 0)
- timeout_secs = MINIMUM(timeout_secs, (int)minwait_secs);
- if (timeout_secs == INT_MAX)
- pollwait = -1;
- else if (timeout_secs >= INT_MAX / 1000)
- pollwait = INT_MAX;
- else
- pollwait = timeout_secs * 1000;
+ }
- ret = poll(*pfdp, *npfd_activep, pollwait);
+ ret = poll(*pfdp, *npfd_activep, ptimeout_get_ms(&timeout));
if (ret == -1) {
/*
* We have to clear the events because we return.
* We have to return, because the mainloop checks for the flags
* set by the signal handlers.
*/
for (p = 0; p < *npfd_activep; p++)
(*pfdp)[p].revents = 0;
if (errno == EINTR)
return;
/* Note: we might still have data in the buffers. */
quit_message("poll: %s", strerror(errno));
return;
}
*conn_in_readyp = (*pfdp)[0].revents != 0;
*conn_out_readyp = (*pfdp)[1].revents != 0;
if (options.server_alive_interval > 0 && !*conn_in_readyp &&
monotime() >= server_alive_time) {
/*
* ServerAlive check is needed. We can't rely on the poll
* timing out since traffic on the client side such as port
* forwards can keep waking it up.
*/
server_alive_check(ssh);
}
}
static void
client_suspend_self(struct sshbuf *bin, struct sshbuf *bout, struct sshbuf *berr)
{
/* Flush stdout and stderr buffers. */
if (sshbuf_len(bout) > 0)
atomicio(vwrite, fileno(stdout), sshbuf_mutable_ptr(bout),
sshbuf_len(bout));
if (sshbuf_len(berr) > 0)
atomicio(vwrite, fileno(stderr), sshbuf_mutable_ptr(berr),
sshbuf_len(berr));
leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE);
sshbuf_reset(bin);
sshbuf_reset(bout);
sshbuf_reset(berr);
/* Send the suspend signal to the program itself. */
kill(getpid(), SIGTSTP);
/* Reset window sizes in case they have changed */
received_window_change_signal = 1;
enter_raw_mode(options.request_tty == REQUEST_TTY_FORCE);
}
static void
client_process_net_input(struct ssh *ssh)
{
int r;
/*
* Read input from the server, and add any such data to the buffer of
* the packet subsystem.
*/
schedule_server_alive_check();
if ((r = ssh_packet_process_read(ssh, connection_in)) == 0)
return; /* success */
if (r == SSH_ERR_SYSTEM_ERROR) {
if (errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK)
return;
if (errno == EPIPE) {
quit_message("Connection to %s closed by remote host.",
host);
return;
}
}
quit_message("Read from remote host %s: %s", host, ssh_err(r));
}
static void
client_status_confirm(struct ssh *ssh, int type, Channel *c, void *ctx)
{
struct channel_reply_ctx *cr = (struct channel_reply_ctx *)ctx;
char errmsg[256];
int r, tochan;
/*
* If a TTY was explicitly requested, then a failure to allocate
* one is fatal.
*/
if (cr->action == CONFIRM_TTY &&
(options.request_tty == REQUEST_TTY_FORCE ||
options.request_tty == REQUEST_TTY_YES))
cr->action = CONFIRM_CLOSE;
/* XXX suppress on mux _client_ quietmode */
tochan = options.log_level >= SYSLOG_LEVEL_ERROR &&
c->ctl_chan != -1 && c->extended_usage == CHAN_EXTENDED_WRITE;
if (type == SSH2_MSG_CHANNEL_SUCCESS) {
debug2("%s request accepted on channel %d",
cr->request_type, c->self);
} else if (type == SSH2_MSG_CHANNEL_FAILURE) {
if (tochan) {
snprintf(errmsg, sizeof(errmsg),
"%s request failed\r\n", cr->request_type);
} else {
snprintf(errmsg, sizeof(errmsg),
"%s request failed on channel %d",
cr->request_type, c->self);
}
/* If error occurred on primary session channel, then exit */
if (cr->action == CONFIRM_CLOSE && c->self == session_ident)
fatal("%s", errmsg);
/*
* If error occurred on mux client, append to
* 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_fr(r, "sshbuf_put");
} else
error("%s", errmsg);
if (cr->action == CONFIRM_TTY) {
/*
* If a TTY allocation error occurred, then arrange
* for the correct TTY to leave raw mode.
*/
if (c->self == session_ident)
leave_raw_mode(0);
else
mux_tty_alloc_failed(ssh, c);
} else if (cr->action == CONFIRM_CLOSE) {
chan_read_failed(ssh, c);
chan_write_failed(ssh, c);
}
}
free(cr);
}
static void
client_abandon_status_confirm(struct ssh *ssh, Channel *c, void *ctx)
{
free(ctx);
}
void
client_expect_confirm(struct ssh *ssh, int id, const char *request,
enum confirm_action action)
{
struct channel_reply_ctx *cr = xcalloc(1, sizeof(*cr));
cr->request_type = request;
cr->action = action;
channel_register_status_confirm(ssh, id, client_status_confirm,
client_abandon_status_confirm, cr);
}
void
client_register_global_confirm(global_confirm_cb *cb, void *ctx)
{
struct global_confirm *gc, *last_gc;
/* Coalesce identical callbacks */
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_f("last_gc->ref_count = %d",
last_gc->ref_count);
return;
}
gc = xcalloc(1, sizeof(*gc));
gc->cb = cb;
gc->ctx = ctx;
gc->ref_count = 1;
TAILQ_INSERT_TAIL(&global_confirms, gc, entry);
}
+/*
+ * Returns non-zero if the client is able to handle a hostkeys-00@openssh.com
+ * hostkey update request.
+ */
+static int
+can_update_hostkeys(void)
+{
+ if (hostkeys_update_complete)
+ return 0;
+ if (options.update_hostkeys == SSH_UPDATE_HOSTKEYS_ASK &&
+ options.batch_mode)
+ return 0; /* won't ask in batchmode, so don't even try */
+ if (!options.update_hostkeys || options.num_user_hostfiles <= 0)
+ return 0;
+ return 1;
+}
+
+static void
+client_repledge(void)
+{
+ debug3_f("enter");
+
+ /* Might be able to tighten pledge now that session is established */
+ if (options.control_master || options.control_path != NULL ||
+ options.forward_x11 || options.fork_after_authentication ||
+ can_update_hostkeys() ||
+ (session_ident != -1 && !session_setup_complete)) {
+ /* Can't tighten */
+ return;
+ }
+ /*
+ * LocalCommand and UpdateHostkeys have finished, so can get rid of
+ * filesystem.
+ *
+ * XXX protocol allows a server can to change hostkeys during the
+ * connection at rekey time that could trigger a hostkeys update
+ * but AFAIK no implementations support this. Could improve by
+ * forcing known_hosts to be read-only or via unveil(2).
+ */
+ if (options.num_local_forwards != 0 ||
+ options.num_remote_forwards != 0 ||
+ options.num_permitted_remote_opens != 0 ||
+ options.enable_escape_commandline != 0) {
+ /* rfwd needs inet */
+ debug("pledge: network");
+ if (pledge("stdio unix inet dns proc tty", NULL) == -1)
+ fatal_f("pledge(): %s", strerror(errno));
+ } else if (options.forward_agent != 0) {
+ /* agent forwarding needs to open $SSH_AUTH_SOCK at will */
+ debug("pledge: agent");
+ if (pledge("stdio unix proc tty", NULL) == -1)
+ fatal_f("pledge(): %s", strerror(errno));
+ } else {
+ debug("pledge: fork");
+ if (pledge("stdio proc tty", NULL) == -1)
+ fatal_f("pledge(): %s", strerror(errno));
+ }
+ /* XXX further things to do:
+ *
+ * - might be able to get rid of proc if we kill ~^Z
+ * - ssh -N (no session)
+ * - stdio forwarding
+ * - sessions without tty
+ */
+}
+
static void
process_cmdline(struct ssh *ssh)
{
void (*handler)(int);
char *s, *cmd;
int ok, delete = 0, local = 0, remote = 0, dynamic = 0;
struct Forward fwd;
memset(&fwd, 0, sizeof(fwd));
leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE);
handler = ssh_signal(SIGINT, SIG_IGN);
cmd = s = read_passphrase("\r\nssh> ", RP_ECHO);
if (s == NULL)
goto out;
while (isspace((u_char)*s))
s++;
if (*s == '-')
s++; /* Skip cmdline '-', if any */
if (*s == '\0')
goto out;
if (*s == 'h' || *s == 'H' || *s == '?') {
logit("Commands:");
logit(" -L[bind_address:]port:host:hostport "
"Request local forward");
logit(" -R[bind_address:]port:host:hostport "
"Request remote forward");
logit(" -D[bind_address:]port "
"Request dynamic forward");
logit(" -KL[bind_address:]port "
"Cancel local forward");
logit(" -KR[bind_address:]port "
"Cancel remote forward");
logit(" -KD[bind_address:]port "
"Cancel dynamic forward");
if (!options.permit_local_command)
goto out;
logit(" !args "
"Execute local command");
goto out;
}
if (*s == '!' && options.permit_local_command) {
s++;
ssh_local_cmd(s);
goto out;
}
if (*s == 'K') {
delete = 1;
s++;
}
if (*s == 'L')
local = 1;
else if (*s == 'R')
remote = 1;
else if (*s == 'D')
dynamic = 1;
else {
logit("Invalid command.");
goto out;
}
while (isspace((u_char)*++s))
;
/* XXX update list of forwards in options */
if (delete) {
/* We pass 1 for dynamicfwd to restrict to 1 or 2 fields. */
if (!parse_forward(&fwd, s, 1, 0)) {
logit("Bad forwarding close specification.");
goto out;
}
if (remote)
ok = channel_request_rforward_cancel(ssh, &fwd) == 0;
else if (dynamic)
ok = channel_cancel_lport_listener(ssh, &fwd,
0, &options.fwd_opts) > 0;
else
ok = channel_cancel_lport_listener(ssh, &fwd,
CHANNEL_CANCEL_PORT_STATIC,
&options.fwd_opts) > 0;
if (!ok) {
logit("Unknown port forwarding.");
goto out;
}
logit("Canceled forwarding.");
} else {
- if (!parse_forward(&fwd, s, dynamic, remote)) {
- logit("Bad forwarding specification.");
+ /* -R specs can be both dynamic or not, so check both. */
+ if (remote) {
+ if (!parse_forward(&fwd, s, 0, remote) &&
+ !parse_forward(&fwd, s, 1, remote)) {
+ logit("Bad remote forwarding specification.");
+ goto out;
+ }
+ } else if (!parse_forward(&fwd, s, dynamic, remote)) {
+ logit("Bad local forwarding specification.");
goto out;
}
if (local || dynamic) {
if (!channel_setup_local_fwd_listener(ssh, &fwd,
&options.fwd_opts)) {
logit("Port forwarding failed.");
goto out;
}
} else {
if (channel_request_remote_forwarding(ssh, &fwd) < 0) {
logit("Port forwarding failed.");
goto out;
}
}
logit("Forwarding port.");
}
out:
ssh_signal(SIGINT, handler);
enter_raw_mode(options.request_tty == REQUEST_TTY_FORCE);
free(cmd);
free(fwd.listen_host);
free(fwd.listen_path);
free(fwd.connect_host);
free(fwd.connect_path);
}
/* reasons to suppress output of an escape command in help output */
#define SUPPRESS_NEVER 0 /* never suppress, always show */
#define SUPPRESS_MUXCLIENT 1 /* don't show in mux client sessions */
#define SUPPRESS_MUXMASTER 2 /* don't show in mux master sessions */
#define SUPPRESS_SYSLOG 4 /* don't show when logging to syslog */
+#define SUPPRESS_NOCMDLINE 8 /* don't show when cmdline disabled*/
struct escape_help_text {
const char *cmd;
const char *text;
unsigned int flags;
};
static struct escape_help_text esc_txt[] = {
{".", "terminate session", SUPPRESS_MUXMASTER},
{".", "terminate connection (and any multiplexed sessions)",
SUPPRESS_MUXCLIENT},
{"B", "send a BREAK to the remote system", SUPPRESS_NEVER},
- {"C", "open a command line", SUPPRESS_MUXCLIENT},
+ {"C", "open a command line", SUPPRESS_MUXCLIENT|SUPPRESS_NOCMDLINE},
{"R", "request rekey", SUPPRESS_NEVER},
{"V/v", "decrease/increase verbosity (LogLevel)", SUPPRESS_MUXCLIENT},
{"^Z", "suspend ssh", SUPPRESS_MUXCLIENT},
{"#", "list forwarded connections", SUPPRESS_NEVER},
{"&", "background ssh (when waiting for connections to terminate)",
SUPPRESS_MUXCLIENT},
{"?", "this message", SUPPRESS_NEVER},
};
static void
print_escape_help(struct sshbuf *b, int escape_char, int mux_client,
int using_stderr)
{
unsigned int i, suppress_flags;
int r;
if ((r = sshbuf_putf(b,
"%c?\r\nSupported escape sequences:\r\n", escape_char)) != 0)
fatal_fr(r, "sshbuf_putf");
suppress_flags =
(mux_client ? SUPPRESS_MUXCLIENT : 0) |
(mux_client ? 0 : SUPPRESS_MUXMASTER) |
- (using_stderr ? 0 : SUPPRESS_SYSLOG);
+ (using_stderr ? 0 : SUPPRESS_SYSLOG) |
+ (options.enable_escape_commandline == 0 ? SUPPRESS_NOCMDLINE : 0);
for (i = 0; i < sizeof(esc_txt)/sizeof(esc_txt[0]); i++) {
if (esc_txt[i].flags & suppress_flags)
continue;
if ((r = sshbuf_putf(b, " %c%-3s - %s\r\n",
escape_char, esc_txt[i].cmd, esc_txt[i].text)) != 0)
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_fr(r, "sshbuf_putf");
}
/*
* Process the characters one by one.
*/
static int
process_escapes(struct ssh *ssh, Channel *c,
struct sshbuf *bin, struct sshbuf *bout, struct sshbuf *berr,
char *buf, int len)
{
pid_t pid;
int r, bytes = 0;
u_int i;
u_char ch;
char *s;
struct escape_filter_ctx *efc = c->filter_ctx == NULL ?
NULL : (struct escape_filter_ctx *)c->filter_ctx;
if (c->filter_ctx == NULL)
return 0;
if (len <= 0)
return (0);
for (i = 0; i < (u_int)len; i++) {
/* Get one character at a time. */
ch = buf[i];
if (efc->escape_pending) {
/* We have previously seen an escape character. */
/* Clear the flag now. */
efc->escape_pending = 0;
/* Process the escaped character. */
switch (ch) {
case '.':
/* Terminate the connection. */
if ((r = sshbuf_putf(berr, "%c.\r\n",
efc->escape_char)) != 0)
fatal_fr(r, "sshbuf_putf");
if (c && c->ctl_chan != -1) {
- chan_read_failed(ssh, c);
- chan_write_failed(ssh, c);
- if (c->detach_user) {
- c->detach_user(ssh,
- c->self, NULL);
- }
- c->type = SSH_CHANNEL_ABANDONED;
- sshbuf_reset(c->input);
- chan_ibuf_empty(ssh, c);
+ channel_force_close(ssh, c, 1);
return 0;
} else
quit_pending = 1;
return -1;
case 'Z' - 64:
/* XXX support this for mux clients */
if (c && c->ctl_chan != -1) {
char b[16];
noescape:
if (ch == 'Z' - 64)
snprintf(b, sizeof b, "^Z");
else
snprintf(b, sizeof b, "%c", ch);
if ((r = sshbuf_putf(berr,
"%c%s escape not available to "
"multiplexed sessions\r\n",
efc->escape_char, b)) != 0)
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_fr(r, "sshbuf_putf");
/* Restore terminal modes and suspend. */
client_suspend_self(bin, bout, berr);
/* We have been continued. */
continue;
case 'B':
if ((r = sshbuf_putf(berr,
"%cB\r\n", efc->escape_char)) != 0)
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_fr(r, "send packet");
continue;
case 'R':
if (ssh->compat & SSH_BUG_NOREKEY)
logit("Server does not "
"support re-keying");
else
need_rekeying = 1;
continue;
case 'V':
/* FALLTHROUGH */
case 'v':
if (c && c->ctl_chan != -1)
goto noescape;
if (!log_is_on_stderr()) {
if ((r = sshbuf_putf(berr,
"%c%c [Logging to syslog]\r\n",
efc->escape_char, ch)) != 0)
fatal_fr(r, "sshbuf_putf");
continue;
}
if (ch == 'V' && options.log_level >
SYSLOG_LEVEL_QUIET)
log_change_level(--options.log_level);
if (ch == 'v' && options.log_level <
SYSLOG_LEVEL_DEBUG3)
log_change_level(++options.log_level);
if ((r = sshbuf_putf(berr,
"%c%c [LogLevel %s]\r\n",
efc->escape_char, ch,
log_level_name(options.log_level))) != 0)
fatal_fr(r, "sshbuf_putf");
continue;
case '&':
if (c && c->ctl_chan != -1)
goto noescape;
/*
* Detach the program (continue to serve
* connections, but put in background and no
* more new connections).
*/
/* Restore tty modes. */
leave_raw_mode(
options.request_tty == REQUEST_TTY_FORCE);
/* Stop listening for new connections. */
channel_stop_listening(ssh);
if ((r = sshbuf_putf(berr, "%c& "
"[backgrounded]\n", efc->escape_char)) != 0)
fatal_fr(r, "sshbuf_putf");
/* Fork into background. */
pid = fork();
if (pid == -1) {
error("fork: %.100s", strerror(errno));
continue;
}
if (pid != 0) { /* This is the parent. */
/* The parent just exits. */
exit(0);
}
/* The child continues serving connections. */
/* fake EOF on stdin */
if ((r = sshbuf_put_u8(bin, 4)) != 0)
fatal_fr(r, "sshbuf_put_u8");
return -1;
case '?':
print_escape_help(berr, efc->escape_char,
(c && c->ctl_chan != -1),
log_is_on_stderr());
continue;
case '#':
if ((r = sshbuf_putf(berr, "%c#\r\n",
efc->escape_char)) != 0)
fatal_fr(r, "sshbuf_putf");
s = channel_open_message(ssh);
if ((r = sshbuf_put(berr, s, strlen(s))) != 0)
fatal_fr(r, "sshbuf_put");
free(s);
continue;
case 'C':
if (c && c->ctl_chan != -1)
goto noescape;
+ if (options.enable_escape_commandline == 0) {
+ if ((r = sshbuf_putf(berr,
+ "commandline disabled\r\n")) != 0)
+ fatal_fr(r, "sshbuf_putf");
+ continue;
+ }
process_cmdline(ssh);
continue;
default:
if (ch != efc->escape_char) {
if ((r = sshbuf_put_u8(bin,
efc->escape_char)) != 0)
fatal_fr(r, "sshbuf_put_u8");
bytes++;
}
/* Escaped characters fall through here */
break;
}
} else {
/*
* The previous character was not an escape char.
* Check if this is an escape.
*/
if (last_was_cr && ch == efc->escape_char) {
/*
* It is. Set the flag and continue to
* next character.
*/
efc->escape_pending = 1;
continue;
}
}
/*
* Normal character. Record whether it was a newline,
* and append it to the buffer.
*/
last_was_cr = (ch == '\r' || ch == '\n');
if ((r = sshbuf_put_u8(bin, ch)) != 0)
fatal_fr(r, "sshbuf_put_u8");
bytes++;
}
return bytes;
}
/*
* Get packets from the connection input buffer, and process them as long as
* there are packets available.
*
* Any unknown packets received during the actual
* session cause the session to terminate. This is
* intended to make debugging easier since no
* confirmations are sent. Any compatible protocol
* extensions must be negotiated during the
* preparatory phase.
*/
static void
client_process_buffered_input_packets(struct ssh *ssh)
{
ssh_dispatch_run_fatal(ssh, DISPATCH_NONBLOCK, &quit_pending);
}
/* scan buf[] for '~' before sending data to the peer */
/* Helper: allocate a new escape_filter_ctx and fill in its escape char */
void *
client_new_escape_filter_ctx(int escape_char)
{
struct escape_filter_ctx *ret;
ret = xcalloc(1, sizeof(*ret));
ret->escape_pending = 0;
ret->escape_char = escape_char;
return (void *)ret;
}
/* Free the escape filter context on channel free */
void
client_filter_cleanup(struct ssh *ssh, int cid, void *ctx)
{
free(ctx);
}
int
client_simple_escape_filter(struct ssh *ssh, Channel *c, char *buf, int len)
{
if (c->extended_usage != CHAN_EXTENDED_WRITE)
return 0;
return process_escapes(ssh, c, c->input, c->output, c->extended,
buf, len);
}
static void
-client_channel_closed(struct ssh *ssh, int id, void *arg)
+client_channel_closed(struct ssh *ssh, int id, int force, void *arg)
{
channel_cancel_cleanup(ssh, id);
session_closed = 1;
leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE);
}
/*
* Implements the interactive session with the server. This is called after
* the user has been authenticated, and a command has been started on the
* remote host. If escape_char != SSH_ESCAPECHAR_NONE, it is the character
* used as an escape character for terminating or suspending the session.
*/
int
client_loop(struct ssh *ssh, int have_pty, int escape_char_arg,
int ssh2_chan_id)
{
struct pollfd *pfd = NULL;
u_int npfd_alloc = 0, npfd_active = 0;
double start_time, total_time;
int r, len;
u_int64_t ibytes, obytes;
int conn_in_ready, conn_out_ready;
debug("Entering interactive session.");
+ session_ident = ssh2_chan_id;
if (options.control_master &&
!option_clear_or_none(options.control_path)) {
debug("pledge: id");
if (pledge("stdio rpath wpath cpath unix inet dns recvfd sendfd proc exec id tty",
NULL) == -1)
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_f("pledge(): %s", strerror(errno));
} else if (options.update_hostkeys) {
debug("pledge: filesystem");
if (pledge("stdio rpath wpath cpath unix inet dns proc tty",
NULL) == -1)
fatal_f("pledge(): %s", strerror(errno));
} else if (!option_clear_or_none(options.proxy_command) ||
options.fork_after_authentication) {
debug("pledge: proc");
if (pledge("stdio cpath unix inet dns proc tty", NULL) == -1)
fatal_f("pledge(): %s", strerror(errno));
} else {
debug("pledge: network");
if (pledge("stdio unix inet dns proc tty", NULL) == -1)
fatal_f("pledge(): %s", strerror(errno));
}
+ /* might be able to tighten now */
+ client_repledge();
+
start_time = monotime_double();
/* Initialize variables. */
last_was_cr = 1;
exit_status = -1;
connection_in = ssh_packet_get_connection_in(ssh);
connection_out = ssh_packet_get_connection_out(ssh);
quit_pending = 0;
/* Initialize buffer. */
if ((stderr_buffer = sshbuf_new()) == NULL)
fatal_f("sshbuf_new failed");
client_init_dispatch(ssh);
/*
* Set signal handlers, (e.g. to restore non-blocking mode)
* but don't overwrite SIG_IGN, matches behaviour from rsh(1)
*/
if (ssh_signal(SIGHUP, SIG_IGN) != SIG_IGN)
ssh_signal(SIGHUP, signal_handler);
if (ssh_signal(SIGINT, SIG_IGN) != SIG_IGN)
ssh_signal(SIGINT, signal_handler);
if (ssh_signal(SIGQUIT, SIG_IGN) != SIG_IGN)
ssh_signal(SIGQUIT, signal_handler);
if (ssh_signal(SIGTERM, SIG_IGN) != SIG_IGN)
ssh_signal(SIGTERM, signal_handler);
ssh_signal(SIGWINCH, window_change_handler);
if (have_pty)
enter_raw_mode(options.request_tty == REQUEST_TTY_FORCE);
- session_ident = ssh2_chan_id;
if (session_ident != -1) {
if (escape_char_arg != SSH_ESCAPECHAR_NONE) {
channel_register_filter(ssh, session_ident,
client_simple_escape_filter, NULL,
client_filter_cleanup,
client_new_escape_filter_ctx(
escape_char_arg));
}
channel_register_cleanup(ssh, session_ident,
client_channel_closed, 0);
}
schedule_server_alive_check();
/* Main loop of the client for the interactive session mode. */
while (!quit_pending) {
/* Process buffered packets sent by the server. */
client_process_buffered_input_packets(ssh);
if (session_closed && !channel_still_open(ssh))
break;
if (ssh_packet_is_rekeying(ssh)) {
debug("rekeying in progress");
} else if (need_rekeying) {
/* manual rekey request */
debug("need rekeying");
if ((r = kex_start_rekex(ssh)) != 0)
fatal_fr(r, "kex_start_rekex");
need_rekeying = 0;
} else {
/*
* Make packets from buffered channel data, and
* enqueue them for sending to the server.
*/
if (ssh_packet_not_very_much_data_to_write(ssh))
channel_output_poll(ssh);
/*
* Check if the window size has changed, and buffer a
* message about it to the server if so.
*/
client_check_window_change(ssh);
if (quit_pending)
break;
}
/*
* Wait until we have something to do (something becomes
* available on one of the descriptors).
*/
client_wait_until_can_do_something(ssh, &pfd, &npfd_alloc,
&npfd_active, ssh_packet_is_rekeying(ssh),
&conn_in_ready, &conn_out_ready);
if (quit_pending)
break;
/* Do channel operations. */
channel_after_poll(ssh, pfd, npfd_active);
/* Buffer input from the connection. */
if (conn_in_ready)
client_process_net_input(ssh);
if (quit_pending)
break;
/* A timeout may have triggered rekeying */
if ((r = ssh_packet_check_rekey(ssh)) != 0)
fatal_fr(r, "cannot start rekeying");
/*
* Send as much buffered packet data as possible to the
* sender.
*/
if (conn_out_ready) {
if ((r = ssh_packet_write_poll(ssh)) != 0) {
sshpkt_fatal(ssh, r,
"%s: ssh_packet_write_poll", __func__);
}
}
/*
* If we are a backgrounded control master, and the
* timeout has expired without any active client
* connections, then quit.
*/
if (control_persist_exit_time > 0) {
if (monotime() >= control_persist_exit_time) {
debug("ControlPersist timeout expired");
break;
}
}
}
free(pfd);
/* Terminate the session. */
/* Stop watching for window change. */
ssh_signal(SIGWINCH, SIG_DFL);
if ((r = sshpkt_start(ssh, SSH2_MSG_DISCONNECT)) != 0 ||
(r = sshpkt_put_u32(ssh, SSH2_DISCONNECT_BY_APPLICATION)) != 0 ||
(r = sshpkt_put_cstring(ssh, "disconnected by user")) != 0 ||
(r = sshpkt_put_cstring(ssh, "")) != 0 || /* language tag */
(r = sshpkt_send(ssh)) != 0 ||
(r = ssh_packet_write_wait(ssh)) != 0)
fatal_fr(r, "send disconnect");
channel_free_all(ssh);
if (have_pty)
leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE);
/*
* 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 (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(255);
}
/*
* In interactive mode (with pseudo tty) display a message indicating
* that the connection has been closed.
*/
if (have_pty && options.log_level >= SYSLOG_LEVEL_INFO)
quit_message("Connection to %s closed.", host);
/* Output any buffered data for stderr. */
if (sshbuf_len(stderr_buffer) > 0) {
len = atomicio(vwrite, fileno(stderr),
(u_char *)sshbuf_ptr(stderr_buffer),
sshbuf_len(stderr_buffer));
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_fr(r, "sshbuf_consume");
}
/* Clear and free any buffers. */
sshbuf_free(stderr_buffer);
/* Report bytes transferred, and transfer rates. */
total_time = monotime_double() - start_time;
ssh_packet_get_bytes(ssh, &ibytes, &obytes);
verbose("Transferred: sent %llu, received %llu bytes, in %.1f seconds",
(unsigned long long)obytes, (unsigned long long)ibytes, total_time);
if (total_time > 0)
verbose("Bytes per second: sent %.1f, received %.1f",
obytes / total_time, ibytes / total_time);
/* Return the exit status of the program. */
debug("Exit status %d", exit_status);
return exit_status;
}
/*********/
static Channel *
client_request_forwarded_tcpip(struct ssh *ssh, const char *request_type,
int rchan, u_int rwindow, u_int rmaxpack)
{
Channel *c = NULL;
struct sshbuf *b = NULL;
char *listen_address, *originator_address;
u_int listen_port, originator_port;
int r;
/* Get rest of the packet */
if ((r = sshpkt_get_cstring(ssh, &listen_address, NULL)) != 0 ||
(r = sshpkt_get_u32(ssh, &listen_port)) != 0 ||
(r = sshpkt_get_cstring(ssh, &originator_address, NULL)) != 0 ||
(r = sshpkt_get_u32(ssh, &originator_port)) != 0 ||
(r = sshpkt_get_end(ssh)) != 0)
fatal_fr(r, "parse packet");
debug_f("listen %s port %d, originator %s port %d",
listen_address, listen_port, originator_address, originator_port);
if (listen_port > 0xffff)
error_f("invalid listen port");
else if (originator_port > 0xffff)
error_f("invalid originator port");
else {
c = channel_connect_by_listen_address(ssh,
listen_address, listen_port, "forwarded-tcpip",
originator_address);
}
if (c != NULL && c->type == SSH_CHANNEL_MUX_CLIENT) {
if ((b = sshbuf_new()) == NULL) {
error_f("alloc reply");
goto out;
}
/* reconstruct and send to muxclient */
if ((r = sshbuf_put_u8(b, 0)) != 0 || /* padlen */
(r = sshbuf_put_u8(b, SSH2_MSG_CHANNEL_OPEN)) != 0 ||
(r = sshbuf_put_cstring(b, request_type)) != 0 ||
(r = sshbuf_put_u32(b, rchan)) != 0 ||
(r = sshbuf_put_u32(b, rwindow)) != 0 ||
(r = sshbuf_put_u32(b, rmaxpack)) != 0 ||
(r = sshbuf_put_cstring(b, listen_address)) != 0 ||
(r = sshbuf_put_u32(b, listen_port)) != 0 ||
(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_fr(r, "compose for muxclient");
goto out;
}
}
out:
sshbuf_free(b);
free(originator_address);
free(listen_address);
return c;
}
static Channel *
client_request_forwarded_streamlocal(struct ssh *ssh,
const char *request_type, int rchan)
{
Channel *c = NULL;
char *listen_path;
int r;
/* Get the remote path. */
if ((r = sshpkt_get_cstring(ssh, &listen_path, NULL)) != 0 ||
(r = sshpkt_get_string(ssh, NULL, NULL)) != 0 || /* reserved */
(r = sshpkt_get_end(ssh)) != 0)
fatal_fr(r, "parse packet");
debug_f("request: %s", listen_path);
c = channel_connect_by_listen_path(ssh, listen_path,
"forwarded-streamlocal@openssh.com", "forwarded-streamlocal");
free(listen_path);
return c;
}
static Channel *
client_request_x11(struct ssh *ssh, const char *request_type, int rchan)
{
Channel *c = NULL;
char *originator;
u_int originator_port;
int r, sock;
if (!options.forward_x11) {
error("Warning: ssh server tried X11 forwarding.");
error("Warning: this is probably a break-in attempt by a "
"malicious server.");
return NULL;
}
if (x11_refuse_time != 0 && (u_int)monotime() >= x11_refuse_time) {
verbose("Rejected X11 connection after ForwardX11Timeout "
"expired");
return NULL;
}
if ((r = sshpkt_get_cstring(ssh, &originator, NULL)) != 0 ||
(r = sshpkt_get_u32(ssh, &originator_port)) != 0 ||
(r = sshpkt_get_end(ssh)) != 0)
fatal_fr(r, "parse packet");
/* XXX check permission */
/* XXX range check originator port? */
debug("client_request_x11: request from %s %u", originator,
originator_port);
free(originator);
sock = x11_connect_display(ssh);
if (sock < 0)
return NULL;
c = channel_new(ssh, "x11",
SSH_CHANNEL_X11_OPEN, sock, sock, -1,
CHAN_TCP_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, 0, "x11", 1);
c->force_drain = 1;
return c;
}
static Channel *
client_request_agent(struct ssh *ssh, const char *request_type, int rchan)
{
Channel *c = NULL;
int r, sock;
if (!options.forward_agent) {
error("Warning: ssh server tried agent forwarding.");
error("Warning: this is probably a break-in attempt by a "
"malicious server.");
return NULL;
}
if (forward_agent_sock_path == NULL) {
r = ssh_get_authentication_socket(&sock);
} else {
r = ssh_get_authentication_socket_path(forward_agent_sock_path, &sock);
}
if (r != 0) {
if (r != SSH_ERR_AGENT_NOT_PRESENT)
debug_fr(r, "ssh_get_authentication_socket");
return NULL;
}
if ((r = ssh_agent_bind_hostkey(sock, ssh->kex->initial_hostkey,
ssh->kex->session_id, ssh->kex->initial_sig, 1)) == 0)
debug_f("bound agent to hostkey");
else
debug2_fr(r, "ssh_agent_bind_hostkey");
c = channel_new(ssh, "authentication agent connection",
SSH_CHANNEL_OPEN, sock, sock, -1,
CHAN_X11_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0,
"authentication agent connection", 1);
c->force_drain = 1;
return c;
}
char *
client_request_tun_fwd(struct ssh *ssh, int tun_mode,
int local_tun, int remote_tun, channel_open_fn *cb, void *cbctx)
{
Channel *c;
int r, fd;
char *ifname = NULL;
if (tun_mode == SSH_TUNMODE_NO)
return 0;
debug("Requesting tun unit %d in mode %d", local_tun, tun_mode);
/* Open local tunnel device */
if ((fd = tun_open(local_tun, tun_mode, &ifname)) == -1) {
error("Tunnel device open failed.");
return NULL;
}
debug("Tunnel forwarding using interface %s", ifname);
c = channel_new(ssh, "tun", SSH_CHANNEL_OPENING, fd, fd, -1,
CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1);
c->datagram = 1;
#if defined(SSH_TUN_FILTER)
if (options.tun_open == SSH_TUNMODE_POINTOPOINT)
channel_register_filter(ssh, c->self, sys_tun_infilter,
sys_tun_outfilter, NULL, NULL);
#endif
if (cb != NULL)
channel_register_open_confirm(ssh, c->self, cb, cbctx);
if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_OPEN)) != 0 ||
(r = sshpkt_put_cstring(ssh, "tun@openssh.com")) != 0 ||
(r = sshpkt_put_u32(ssh, c->self)) != 0 ||
(r = sshpkt_put_u32(ssh, c->local_window_max)) != 0 ||
(r = sshpkt_put_u32(ssh, c->local_maxpacket)) != 0 ||
(r = sshpkt_put_u32(ssh, tun_mode)) != 0 ||
(r = sshpkt_put_u32(ssh, remote_tun)) != 0 ||
(r = sshpkt_send(ssh)) != 0)
sshpkt_fatal(ssh, r, "%s: send reply", __func__);
return ifname;
}
/* XXXX move to generic input handler */
static int
client_input_channel_open(int type, u_int32_t seq, struct ssh *ssh)
{
Channel *c = NULL;
char *ctype = NULL;
int r;
u_int rchan;
size_t len;
u_int rmaxpack, rwindow;
if ((r = sshpkt_get_cstring(ssh, &ctype, &len)) != 0 ||
(r = sshpkt_get_u32(ssh, &rchan)) != 0 ||
(r = sshpkt_get_u32(ssh, &rwindow)) != 0 ||
(r = sshpkt_get_u32(ssh, &rmaxpack)) != 0)
goto out;
debug("client_input_channel_open: ctype %s rchan %d win %d max %d",
ctype, rchan, rwindow, rmaxpack);
if (strcmp(ctype, "forwarded-tcpip") == 0) {
c = client_request_forwarded_tcpip(ssh, ctype, rchan, rwindow,
rmaxpack);
} else if (strcmp(ctype, "forwarded-streamlocal@openssh.com") == 0) {
c = client_request_forwarded_streamlocal(ssh, ctype, rchan);
} else if (strcmp(ctype, "x11") == 0) {
c = client_request_x11(ssh, ctype, rchan);
} else if (strcmp(ctype, "auth-agent@openssh.com") == 0) {
c = client_request_agent(ssh, ctype, rchan);
}
if (c != NULL && c->type == SSH_CHANNEL_MUX_CLIENT) {
debug3("proxied to downstream: %s", ctype);
} else if (c != NULL) {
debug("confirm %s", ctype);
c->remote_id = rchan;
c->have_remote_id = 1;
c->remote_window = rwindow;
c->remote_maxpacket = rmaxpack;
if (c->type != SSH_CHANNEL_CONNECTING) {
if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION)) != 0 ||
(r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
(r = sshpkt_put_u32(ssh, c->self)) != 0 ||
(r = sshpkt_put_u32(ssh, c->local_window)) != 0 ||
(r = sshpkt_put_u32(ssh, c->local_maxpacket)) != 0 ||
(r = sshpkt_send(ssh)) != 0)
sshpkt_fatal(ssh, r, "%s: send reply", __func__);
}
} else {
debug("failure %s", ctype);
if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_OPEN_FAILURE)) != 0 ||
(r = sshpkt_put_u32(ssh, rchan)) != 0 ||
(r = sshpkt_put_u32(ssh, SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED)) != 0 ||
(r = sshpkt_put_cstring(ssh, "open failed")) != 0 ||
(r = sshpkt_put_cstring(ssh, "")) != 0 ||
(r = sshpkt_send(ssh)) != 0)
sshpkt_fatal(ssh, r, "%s: send failure", __func__);
}
r = 0;
out:
free(ctype);
return r;
}
static int
client_input_channel_req(int type, u_int32_t seq, struct ssh *ssh)
{
Channel *c = NULL;
char *rtype = NULL;
u_char reply;
u_int id, exitval;
int r, success = 0;
if ((r = sshpkt_get_u32(ssh, &id)) != 0)
return r;
if (id <= INT_MAX)
c = channel_lookup(ssh, id);
if (channel_proxy_upstream(c, type, seq, ssh))
return 0;
if ((r = sshpkt_get_cstring(ssh, &rtype, NULL)) != 0 ||
(r = sshpkt_get_u8(ssh, &reply)) != 0)
goto out;
debug("client_input_channel_req: channel %u rtype %s reply %d",
id, rtype, reply);
if (c == NULL) {
error("client_input_channel_req: channel %d: "
"unknown channel", id);
} else if (strcmp(rtype, "eow@openssh.com") == 0) {
if ((r = sshpkt_get_end(ssh)) != 0)
goto out;
chan_rcvd_eow(ssh, c);
} else if (strcmp(rtype, "exit-status") == 0) {
if ((r = sshpkt_get_u32(ssh, &exitval)) != 0)
goto out;
if (c->ctl_chan != -1) {
mux_exit_message(ssh, c, exitval);
success = 1;
} else if ((int)id == session_ident) {
/* Record exit value of local session */
success = 1;
exit_status = exitval;
} else {
/* Probably for a mux channel that has already closed */
debug_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_f("channel %d: no remote_id", c->self);
if ((r = sshpkt_start(ssh, success ?
SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE)) != 0 ||
(r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
(r = sshpkt_send(ssh)) != 0)
sshpkt_fatal(ssh, r, "%s: send failure", __func__);
}
r = 0;
out:
free(rtype);
return r;
}
struct hostkeys_update_ctx {
/* The hostname and (optionally) IP address string for the server */
char *host_str, *ip_str;
/*
* Keys received from the server and a flag for each indicating
* whether they already exist in known_hosts.
* keys_match is filled in by hostkeys_find() and later (for new
- * keys) by client_global_hostkeys_private_confirm().
+ * keys) by client_global_hostkeys_prove_confirm().
*/
struct sshkey **keys;
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
* from the server (i.e. scheduled to be deleted).
* Filled in by hostkeys_find().
*/
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
hostkeys_update_ctx_free(struct hostkeys_update_ctx *ctx)
{
size_t i;
if (ctx == NULL)
return;
for (i = 0; i < ctx->nkeys; i++)
sshkey_free(ctx->keys[i]);
free(ctx->keys);
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);
free(ctx->host_str);
free(ctx->ip_str);
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)
{
struct hostkeys_update_ctx *ctx = (struct hostkeys_update_ctx *)_ctx;
size_t i;
struct sshkey **tmp;
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;
}
/* 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_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_f("recallocarray failed nold = %zu", ctx->nold);
ctx->old_keys = tmp;
ctx->old_keys[ctx->nold++] = l->key;
l->key = NULL;
return 0;
}
/* callback to search for ctx->old_keys in known_hosts under other names */
static int
hostkeys_check_old(struct hostkey_foreach_line *l, void *_ctx)
{
struct hostkeys_update_ctx *ctx = (struct hostkeys_update_ctx *)_ctx;
size_t i;
int hashed;
/* only care about lines that *don't* match the active host spec */
if (l->status == HKF_STATUS_MATCHED || l->key == NULL)
return 0;
hashed = l->match & (HKF_MATCH_HOST_HASHED|HKF_MATCH_IP_HASHED);
for (i = 0; i < ctx->nold; i++) {
if (!sshkey_equal(l->key, ctx->old_keys[i]))
continue;
debug3_f("found deprecated %s key at %s:%ld as %s",
sshkey_ssh_name(ctx->old_keys[i]), l->path, l->linenum,
hashed ? "[HASHED]" : l->hosts);
ctx->old_key_seen = 1;
break;
}
return 0;
}
/*
* Check known_hosts files for deprecated keys under other names. Returns 0
* on success or -1 on failure. Updates ctx->old_key_seen if deprecated keys
* exist under names other than the active hostname/IP.
*/
static int
check_old_keys_othernames(struct hostkeys_update_ctx *ctx)
{
size_t i;
int r;
debug2_f("checking for %zu deprecated keys", ctx->nold);
for (i = 0; i < options.num_user_hostfiles; i++) {
debug3_f("searching %s for %s / %s",
options.user_hostfiles[i], ctx->host_str,
ctx->ip_str ? ctx->ip_str : "(none)");
if ((r = hostkeys_foreach(options.user_hostfiles[i],
hostkeys_check_old, ctx, ctx->host_str, ctx->ip_str,
HKF_WANT_PARSE_KEY, 0)) != 0) {
if (r == SSH_ERR_SYSTEM_ERROR && errno == ENOENT) {
debug_f("hostkeys file %s does not exist",
options.user_hostfiles[i]);
continue;
}
error_fr(r, "hostkeys_foreach failed for %s",
options.user_hostfiles[i]);
return -1;
}
}
return 0;
}
static void
hostkey_change_preamble(LogLevel loglevel)
{
do_log2(loglevel, "The server has updated its host keys.");
do_log2(loglevel, "These changes were verified by the server's "
"existing trusted key.");
}
static void
update_known_hosts(struct hostkeys_update_ctx *ctx)
{
int r, was_raw = 0, first = 1;
int asking = options.update_hostkeys == SSH_UPDATE_HOSTKEYS_ASK;
LogLevel loglevel = asking ? SYSLOG_LEVEL_INFO : SYSLOG_LEVEL_VERBOSE;
char *fp, *response;
size_t i;
struct stat sb;
for (i = 0; i < ctx->nkeys; i++) {
if (!ctx->keys_verified[i])
continue;
if ((fp = sshkey_fingerprint(ctx->keys[i],
options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL)
fatal_f("sshkey_fingerprint failed");
if (first && asking)
hostkey_change_preamble(loglevel);
do_log2(loglevel, "Learned new hostkey: %s %s",
sshkey_type(ctx->keys[i]), fp);
first = 0;
free(fp);
}
for (i = 0; i < ctx->nold; i++) {
if ((fp = sshkey_fingerprint(ctx->old_keys[i],
options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL)
fatal_f("sshkey_fingerprint failed");
if (first && asking)
hostkey_change_preamble(loglevel);
do_log2(loglevel, "Deprecating obsolete hostkey: %s %s",
sshkey_type(ctx->old_keys[i]), fp);
first = 0;
free(fp);
}
if (options.update_hostkeys == SSH_UPDATE_HOSTKEYS_ASK) {
if (get_saved_tio() != NULL) {
leave_raw_mode(1);
was_raw = 1;
}
response = NULL;
for (i = 0; !quit_pending && i < 3; i++) {
free(response);
response = read_passphrase("Accept updated hostkeys? "
"(yes/no): ", RP_ECHO);
if (strcasecmp(response, "yes") == 0)
break;
else if (quit_pending || response == NULL ||
strcasecmp(response, "no") == 0) {
options.update_hostkeys = 0;
break;
} else {
do_log2(loglevel, "Please enter "
"\"yes\" or \"no\"");
}
}
if (quit_pending || i >= 3 || response == NULL)
options.update_hostkeys = 0;
free(response);
if (was_raw)
enter_raw_mode(1);
}
if (options.update_hostkeys == 0)
return;
/*
* Now that all the keys are verified, we can go ahead and replace
* them in known_hosts (assuming SSH_UPDATE_HOSTKEYS_ASK didn't
* cancel the operation).
*/
for (i = 0; i < options.num_user_hostfiles; i++) {
/*
* NB. keys are only added to hostfiles[0], for the rest we
* just delete the hostname entries.
*/
if (stat(options.user_hostfiles[i], &sb) != 0) {
if (errno == ENOENT) {
debug_f("known hosts file %s does not "
"exist", options.user_hostfiles[i]);
} else {
error_f("known hosts file %s "
"inaccessible: %s",
options.user_hostfiles[i], strerror(errno));
}
continue;
}
if ((r = hostfile_replace_entries(options.user_hostfiles[i],
ctx->host_str, ctx->ip_str,
i == 0 ? ctx->keys : NULL, i == 0 ? ctx->nkeys : 0,
options.hash_known_hosts, 0,
options.fingerprint_hash)) != 0) {
error_fr(r, "hostfile_replace_entries failed for %s",
options.user_hostfiles[i]);
}
}
}
static void
-client_global_hostkeys_private_confirm(struct ssh *ssh, int type,
+client_global_hostkeys_prove_confirm(struct ssh *ssh, int type,
u_int32_t seq, void *_ctx)
{
struct hostkeys_update_ctx *ctx = (struct hostkeys_update_ctx *)_ctx;
size_t i, ndone;
struct sshbuf *signdata;
int r, plaintype;
const u_char *sig;
const char *rsa_kexalg = NULL;
char *alg = NULL;
size_t siglen;
if (ctx->nnew == 0)
fatal_f("ctx->nnew == 0"); /* sanity */
if (type != SSH2_MSG_REQUEST_SUCCESS) {
error("Server failed to confirm ownership of "
"private host keys");
hostkeys_update_ctx_free(ctx);
return;
}
if (sshkey_type_plain(sshkey_type_from_name(
ssh->kex->hostkey_alg)) == KEY_RSA)
rsa_kexalg = ssh->kex->hostkey_alg;
if ((signdata = sshbuf_new()) == NULL)
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_match[i] == 0.
*/
for (ndone = i = 0; i < ctx->nkeys; i++) {
if (ctx->keys_match[i])
continue;
plaintype = sshkey_type_plain(ctx->keys[i]->type);
/* 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_stringb(signdata,
ssh->kex->session_id)) != 0 ||
(r = sshkey_puts(ctx->keys[i], signdata)) != 0)
fatal_fr(r, "compose signdata");
/* Extract and verify signature */
if ((r = sshpkt_get_string_direct(ssh, &sig, &siglen)) != 0) {
error_fr(r, "parse sig");
goto out;
}
if ((r = sshkey_get_sigtype(sig, siglen, &alg)) != 0) {
error_fr(r, "server gave unintelligible signature "
"for %s key %zu", sshkey_type(ctx->keys[i]), i);
goto out;
}
/*
* Special case for RSA keys: if a RSA hostkey was negotiated,
* then use its signature type for verification of RSA hostkey
* proofs. Otherwise, accept only RSA-SHA256/512 signatures.
*/
if (plaintype == KEY_RSA && rsa_kexalg == NULL &&
match_pattern_list(alg, HOSTKEY_PROOF_RSA_ALGS, 0) != 1) {
debug_f("server used untrusted RSA signature algorithm "
"%s for key %zu, disregarding", alg, i);
free(alg);
/* zap the key from the list */
sshkey_free(ctx->keys[i]);
ctx->keys[i] = NULL;
ndone++;
continue;
}
debug3_f("verify %s key %zu using sigalg %s",
sshkey_type(ctx->keys[i]), i, alg);
free(alg);
if ((r = sshkey_verify(ctx->keys[i], sig, siglen,
sshbuf_ptr(signdata), sshbuf_len(signdata),
plaintype == KEY_RSA ? rsa_kexalg : NULL, 0, NULL)) != 0) {
error_fr(r, "server gave bad signature for %s key %zu",
sshkey_type(ctx->keys[i]), i);
goto out;
}
/* Key is good. Mark it as 'seen' */
ctx->keys_verified[i] = 1;
ndone++;
}
/* Shouldn't happen */
if (ndone != ctx->nnew)
fatal_f("ndone != ctx->nnew (%zu / %zu)", ndone, ctx->nnew);
if ((r = sshpkt_get_end(ssh)) != 0) {
error_f("protocol error");
goto out;
}
/* Make the edits to known_hosts */
update_known_hosts(ctx);
out:
hostkeys_update_ctx_free(ctx);
+ hostkeys_update_complete = 1;
+ client_repledge();
}
/*
* Returns non-zero if the key is accepted by HostkeyAlgorithms.
* Made slightly less trivial by the multiple RSA signature algorithm names.
*/
static int
key_accepted_by_hostkeyalgs(const struct sshkey *key)
{
const char *ktype = sshkey_ssh_name(key);
const char *hostkeyalgs = options.hostkeyalgorithms;
if (key == NULL || key->type == KEY_UNSPEC)
return 0;
if (key->type == KEY_RSA &&
(match_pattern_list("rsa-sha2-256", hostkeyalgs, 0) == 1 ||
match_pattern_list("rsa-sha2-512", hostkeyalgs, 0) == 1))
return 1;
return match_pattern_list(ktype, hostkeyalgs, 0) == 1;
}
/*
* Handle hostkeys-00@openssh.com global request to inform the client of all
* the server's hostkeys. The keys are checked against the user's
* HostkeyAlgorithms preference before they are accepted.
*/
static int
client_input_hostkeys(struct ssh *ssh)
{
const u_char *blob = NULL;
size_t i, len = 0;
struct sshbuf *buf = NULL;
struct sshkey *key = NULL, **tmp;
- int r;
+ int r, prove_sent = 0;
char *fp;
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_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 */
- if (!options.update_hostkeys || options.num_user_hostfiles <= 0)
+ if (!can_update_hostkeys())
return 1;
+ hostkeys_seen = 1;
ctx = xcalloc(1, sizeof(*ctx));
while (ssh_packet_remaining(ssh) > 0) {
sshkey_free(key);
key = NULL;
if ((r = sshpkt_get_string_direct(ssh, &blob, &len)) != 0) {
error_fr(r, "parse key");
goto out;
}
if ((r = sshkey_from_blob(blob, len, &key)) != 0) {
do_log2_fr(r, r == SSH_ERR_KEY_TYPE_UNKNOWN ?
SYSLOG_LEVEL_DEBUG1 : SYSLOG_LEVEL_ERROR,
"convert key");
continue;
}
fp = sshkey_fingerprint(key, options.fingerprint_hash,
SSH_FP_DEFAULT);
debug3_f("received %s key %s", sshkey_type(key), fp);
free(fp);
if (!key_accepted_by_hostkeyalgs(key)) {
debug3_f("%s key not permitted by "
"HostkeyAlgorithms", sshkey_ssh_name(key));
continue;
}
/* Skip certs */
if (sshkey_is_cert(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_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_f("recallocarray failed nkeys = %zu",
ctx->nkeys);
ctx->keys = tmp;
ctx->keys[ctx->nkeys++] = key;
key = NULL;
}
if (ctx->nkeys == 0) {
debug_f("server sent no hostkeys");
goto out;
}
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,
options.port, &ctx->host_str,
options.check_host_ip ? &ctx->ip_str : NULL);
/* Find which keys we already know about. */
for (i = 0; i < options.num_user_hostfiles; i++) {
debug_f("searching %s for %s / %s",
options.user_hostfiles[i], ctx->host_str,
ctx->ip_str ? ctx->ip_str : "(none)");
if ((r = hostkeys_foreach(options.user_hostfiles[i],
hostkeys_find, ctx, ctx->host_str, ctx->ip_str,
HKF_WANT_PARSE_KEY, 0)) != 0) {
if (r == SSH_ERR_SYSTEM_ERROR && errno == ENOENT) {
debug_f("hostkeys file %s does not exist",
options.user_hostfiles[i]);
continue;
}
error_fr(r, "hostkeys_foreach failed for %s",
options.user_hostfiles[i]);
goto out;
}
}
/* Figure out if we have any new keys to add */
ctx->nnew = 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_match[i] == 0)
ctx->nnew++;
if ((ctx->keys_match[i] & want) != want)
ctx->nincomplete++;
}
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) {
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 some keys to remove or fix matching for.
* We can proceed to do this without requiring a fresh proof
* from the server.
*/
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);
+ client_global_hostkeys_prove_confirm, ctx);
ctx = NULL; /* will be freed in callback */
+ prove_sent = 1;
/* Success */
out:
hostkeys_update_ctx_free(ctx);
sshkey_free(key);
sshbuf_free(buf);
+ if (!prove_sent) {
+ /* UpdateHostkeys handling completed */
+ hostkeys_update_complete = 1;
+ client_repledge();
+ }
/*
* NB. Return success for all cases. The server doesn't need to know
* what the client does with its hosts file.
*/
return 1;
}
static int
client_input_global_request(int type, u_int32_t seq, struct ssh *ssh)
{
char *rtype;
u_char want_reply;
int r, success = 0;
if ((r = sshpkt_get_cstring(ssh, &rtype, NULL)) != 0 ||
(r = sshpkt_get_u8(ssh, &want_reply)) != 0)
goto out;
debug("client_input_global_request: rtype %s want_reply %d",
rtype, want_reply);
if (strcmp(rtype, "hostkeys-00@openssh.com") == 0)
success = client_input_hostkeys(ssh);
if (want_reply) {
if ((r = sshpkt_start(ssh, success ? SSH2_MSG_REQUEST_SUCCESS :
SSH2_MSG_REQUEST_FAILURE)) != 0 ||
(r = sshpkt_send(ssh)) != 0 ||
(r = ssh_packet_write_wait(ssh)) != 0)
goto out;
}
r = 0;
out:
free(rtype);
return 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,
char **env)
{
size_t i, j, len;
int matched, r;
char *name, *val;
Channel *c = NULL;
debug2_f("id %d", id);
if ((c = channel_lookup(ssh, id)) == NULL)
fatal_f("channel %d: unknown channel", id);
ssh_packet_set_interactive(ssh, want_tty,
options.ip_qos_interactive, options.ip_qos_bulk);
if (want_tty) {
struct winsize ws;
/* Store window size in the packet. */
if (ioctl(in_fd, TIOCGWINSZ, &ws) == -1)
memset(&ws, 0, sizeof(ws));
channel_request_start(ssh, id, "pty-req", 1);
client_expect_confirm(ssh, id, "PTY allocation", CONFIRM_TTY);
if ((r = sshpkt_put_cstring(ssh, term != NULL ? term : ""))
!= 0 ||
(r = sshpkt_put_u32(ssh, (u_int)ws.ws_col)) != 0 ||
(r = sshpkt_put_u32(ssh, (u_int)ws.ws_row)) != 0 ||
(r = sshpkt_put_u32(ssh, (u_int)ws.ws_xpixel)) != 0 ||
(r = sshpkt_put_u32(ssh, (u_int)ws.ws_ypixel)) != 0)
fatal_fr(r, "build pty-req");
if (tiop == NULL)
tiop = get_saved_tio();
ssh_tty_make_modes(ssh, -1, tiop);
if ((r = sshpkt_send(ssh)) != 0)
fatal_fr(r, "send pty-req");
/* XXX wait for reply */
c->client_tty = 1;
}
/* Transfer any environment variables from client to server */
if (options.num_send_env != 0 && env != NULL) {
debug("Sending environment.");
for (i = 0; env[i] != NULL; i++) {
/* Split */
name = xstrdup(env[i]);
if ((val = strchr(name, '=')) == NULL) {
free(name);
continue;
}
*val++ = '\0';
matched = 0;
for (j = 0; j < options.num_send_env; j++) {
if (match_pattern(name, options.send_env[j])) {
matched = 1;
break;
}
}
if (!matched) {
debug3("Ignored env %s", name);
free(name);
continue;
}
client_send_env(ssh, id, name, val);
free(name);
}
}
for (i = 0; i < options.num_setenv; i++) {
/* Split */
name = xstrdup(options.setenv[i]);
if ((val = strchr(name, '=')) == NULL) {
free(name);
continue;
}
*val++ = '\0';
client_send_env(ssh, id, name, val);
free(name);
}
len = sshbuf_len(cmd);
if (len > 0) {
if (len > 900)
len = 900;
if (want_subsystem) {
debug("Sending subsystem: %.*s",
(int)len, (const u_char*)sshbuf_ptr(cmd));
channel_request_start(ssh, id, "subsystem", 1);
client_expect_confirm(ssh, id, "subsystem",
CONFIRM_CLOSE);
} else {
debug("Sending command: %.*s",
(int)len, (const u_char*)sshbuf_ptr(cmd));
channel_request_start(ssh, id, "exec", 1);
client_expect_confirm(ssh, id, "exec", CONFIRM_CLOSE);
}
if ((r = sshpkt_put_stringb(ssh, cmd)) != 0 ||
(r = sshpkt_send(ssh)) != 0)
fatal_fr(r, "send command");
} else {
channel_request_start(ssh, id, "shell", 1);
client_expect_confirm(ssh, id, "shell", CONFIRM_CLOSE);
if ((r = sshpkt_send(ssh)) != 0)
fatal_fr(r, "send shell");
}
+
+ session_setup_complete = 1;
+ client_repledge();
}
static void
client_init_dispatch(struct ssh *ssh)
{
ssh_dispatch_init(ssh, &dispatch_protocol_error);
ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_CLOSE, &channel_input_oclose);
ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_DATA, &channel_input_data);
ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_EOF, &channel_input_ieof);
ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_EXTENDED_DATA, &channel_input_extended_data);
ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_OPEN, &client_input_channel_open);
ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation);
ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure);
ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_REQUEST, &client_input_channel_req);
ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_WINDOW_ADJUST, &channel_input_window_adjust);
ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_SUCCESS, &channel_input_status_confirm);
ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_FAILURE, &channel_input_status_confirm);
ssh_dispatch_set(ssh, SSH2_MSG_GLOBAL_REQUEST, &client_input_global_request);
/* rekeying */
ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, &kex_input_kexinit);
/* global request reply messages */
ssh_dispatch_set(ssh, SSH2_MSG_REQUEST_FAILURE, &client_global_request_reply);
ssh_dispatch_set(ssh, SSH2_MSG_REQUEST_SUCCESS, &client_global_request_reply);
}
void
client_stop_mux(void)
{
if (options.control_path != NULL && muxserver_sock != -1)
unlink(options.control_path);
/*
* 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 || options.session_type == SESSION_TYPE_NONE) {
session_closed = 1;
setproctitle("[stopped mux]");
}
}
/* client specific fatal cleanup */
void
cleanup_exit(int i)
{
leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE);
if (options.control_path != NULL && muxserver_sock != -1)
unlink(options.control_path);
ssh_kill_proxy_command();
_exit(i);
}
diff --git a/crypto/openssh/config.guess b/crypto/openssh/config.guess
index 11fda528bc7b..980b02083815 100755
--- a/crypto/openssh/config.guess
+++ b/crypto/openssh/config.guess
@@ -1,1674 +1,1774 @@
#! /bin/sh
# Attempt to guess a canonical system name.
-# Copyright 1992-2020 Free Software Foundation, Inc.
+# Copyright 1992-2022 Free Software Foundation, Inc.
-timestamp='2020-04-26'
+# shellcheck disable=SC2006,SC2268 # see below for rationale
+
+timestamp='2022-09-17'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
+# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <https://www.gnu.org/licenses/>.
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that
# program. This Exception is an additional permission under section 7
# of the GNU General Public License, version 3 ("GPLv3").
#
# Originally written by Per Bothner; maintained since 2000 by Ben Elliston.
#
# You can get the latest version of this script from:
-# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
+# https://git.savannah.gnu.org/cgit/config.git/plain/config.guess
#
# Please send patches to <config-patches@gnu.org>.
+# The "shellcheck disable" line above the timestamp inhibits complaints
+# about features and limitations of the classic Bourne shell that were
+# superseded or lifted in POSIX. However, this script identifies a wide
+# variety of pre-POSIX systems that do not have POSIX shells at all, and
+# even some reasonably current systems (Solaris 10 as case-in-point) still
+# have a pre-POSIX /bin/sh.
+
+
me=`echo "$0" | sed -e 's,.*/,,'`
usage="\
Usage: $0 [OPTION]
Output the configuration name of the system \`$me' is run on.
Options:
-h, --help print this help, then exit
-t, --time-stamp print date of last modification, then exit
-v, --version print version number, then exit
Report bugs and patches to <config-patches@gnu.org>."
version="\
GNU config.guess ($timestamp)
Originally written by Per Bothner.
-Copyright 1992-2020 Free Software Foundation, Inc.
+Copyright 1992-2022 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
help="
Try \`$me --help' for more information."
# Parse command line
while test $# -gt 0 ; do
case $1 in
--time-stamp | --time* | -t )
echo "$timestamp" ; exit ;;
--version | -v )
echo "$version" ; exit ;;
--help | --h* | -h )
echo "$usage"; exit ;;
-- ) # Stop option processing
shift; break ;;
- ) # Use stdin as input.
break ;;
-* )
echo "$me: invalid option $1$help" >&2
exit 1 ;;
* )
break ;;
esac
done
if test $# != 0; then
echo "$me: too many arguments$help" >&2
exit 1
fi
+# Just in case it came from the environment.
+GUESS=
+
# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
# compiler to aid in system detection is discouraged as it requires
# temporary files to be created and, as you can see below, it is a
# headache to deal with in a portable fashion.
# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
# use `HOST_CC' if defined, but it is deprecated.
# Portable tmp directory creation inspired by the Autoconf team.
tmp=
# shellcheck disable=SC2172
trap 'test -z "$tmp" || rm -fr "$tmp"' 0 1 2 13 15
set_cc_for_build() {
# prevent multiple calls if $tmp is already set
test "$tmp" && return 0
: "${TMPDIR=/tmp}"
- # shellcheck disable=SC2039
+ # shellcheck disable=SC2039,SC3028
{ tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
{ test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } ||
{ tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } ||
{ echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; }
dummy=$tmp/dummy
case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in
,,) echo "int x;" > "$dummy.c"
for driver in cc gcc c89 c99 ; do
if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then
- CC_FOR_BUILD="$driver"
+ CC_FOR_BUILD=$driver
break
fi
done
if test x"$CC_FOR_BUILD" = x ; then
CC_FOR_BUILD=no_compiler_found
fi
;;
,,*) CC_FOR_BUILD=$CC ;;
,*,*) CC_FOR_BUILD=$HOST_CC ;;
esac
}
# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
# (ghazi@noc.rutgers.edu 1994-08-24)
if test -f /.attbin/uname ; then
PATH=$PATH:/.attbin ; export PATH
fi
UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
-UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
-case "$UNAME_SYSTEM" in
+case $UNAME_SYSTEM in
Linux|GNU|GNU/*)
- # If the system lacks a compiler, then just pick glibc.
- # We could probably try harder.
- LIBC=gnu
+ LIBC=unknown
set_cc_for_build
cat <<-EOF > "$dummy.c"
#include <features.h>
#if defined(__UCLIBC__)
LIBC=uclibc
#elif defined(__dietlibc__)
LIBC=dietlibc
- #else
+ #elif defined(__GLIBC__)
LIBC=gnu
+ #else
+ #include <stdarg.h>
+ /* First heuristic to detect musl libc. */
+ #ifdef __DEFINED_va_list
+ LIBC=musl
+ #endif
#endif
EOF
- eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`"
+ cc_set_libc=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`
+ eval "$cc_set_libc"
- # If ldd exists, use it to detect musl libc.
- if command -v ldd >/dev/null && \
- ldd --version 2>&1 | grep -q ^musl
- then
- LIBC=musl
+ # Second heuristic to detect musl libc.
+ if [ "$LIBC" = unknown ] &&
+ command -v ldd >/dev/null &&
+ ldd --version 2>&1 | grep -q ^musl; then
+ LIBC=musl
+ fi
+
+ # If the system lacks a compiler, then just pick glibc.
+ # We could probably try harder.
+ if [ "$LIBC" = unknown ]; then
+ LIBC=gnu
fi
;;
esac
# Note: order is significant - the case branches are not exclusive.
-case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
+case $UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION in
*:NetBSD:*:*)
# NetBSD (nbsd) targets should (where applicable) match one or
# more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
# *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
# switched to ELF, *-*-netbsd* would select the old
# object file format. This provides both forward
# compatibility and a consistent mechanism for selecting the
# object file format.
#
# Note: NetBSD doesn't particularly care about the vendor
# portion of the name. We always set it to "unknown".
- sysctl="sysctl -n hw.machine_arch"
UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \
- "/sbin/$sysctl" 2>/dev/null || \
- "/usr/sbin/$sysctl" 2>/dev/null || \
+ /sbin/sysctl -n hw.machine_arch 2>/dev/null || \
+ /usr/sbin/sysctl -n hw.machine_arch 2>/dev/null || \
echo unknown)`
- case "$UNAME_MACHINE_ARCH" in
+ case $UNAME_MACHINE_ARCH in
+ aarch64eb) machine=aarch64_be-unknown ;;
armeb) machine=armeb-unknown ;;
arm*) machine=arm-unknown ;;
sh3el) machine=shl-unknown ;;
sh3eb) machine=sh-unknown ;;
sh5el) machine=sh5le-unknown ;;
earmv*)
arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'`
endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'`
- machine="${arch}${endian}"-unknown
+ machine=${arch}${endian}-unknown
;;
- *) machine="$UNAME_MACHINE_ARCH"-unknown ;;
+ *) machine=$UNAME_MACHINE_ARCH-unknown ;;
esac
# The Operating System including object format, if it has switched
# to ELF recently (or will in the future) and ABI.
- case "$UNAME_MACHINE_ARCH" in
+ case $UNAME_MACHINE_ARCH in
earm*)
os=netbsdelf
;;
arm*|i386|m68k|ns32k|sh3*|sparc|vax)
set_cc_for_build
if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ELF__
then
# Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
# Return netbsd for either. FIX?
os=netbsd
else
os=netbsdelf
fi
;;
*)
os=netbsd
;;
esac
# Determine ABI tags.
- case "$UNAME_MACHINE_ARCH" in
+ case $UNAME_MACHINE_ARCH in
earm*)
expr='s/^earmv[0-9]/-eabi/;s/eb$//'
abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"`
;;
esac
# The OS release
# Debian GNU/NetBSD machines have a different userland, and
# thus, need a distinct triplet. However, they do not need
# kernel version information, so it can be replaced with a
# suitable tag, in the style of linux-gnu.
- case "$UNAME_VERSION" in
+ case $UNAME_VERSION in
Debian*)
release='-gnu'
;;
*)
release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2`
;;
esac
# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
# contains redundant information, the shorter form:
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
- echo "$machine-${os}${release}${abi-}"
- exit ;;
+ GUESS=$machine-${os}${release}${abi-}
+ ;;
*:Bitrig:*:*)
UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
- echo "$UNAME_MACHINE_ARCH"-unknown-bitrig"$UNAME_RELEASE"
- exit ;;
+ GUESS=$UNAME_MACHINE_ARCH-unknown-bitrig$UNAME_RELEASE
+ ;;
*:OpenBSD:*:*)
UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
- echo "$UNAME_MACHINE_ARCH"-unknown-openbsd"$UNAME_RELEASE"
- exit ;;
+ GUESS=$UNAME_MACHINE_ARCH-unknown-openbsd$UNAME_RELEASE
+ ;;
+ *:SecBSD:*:*)
+ UNAME_MACHINE_ARCH=`arch | sed 's/SecBSD.//'`
+ GUESS=$UNAME_MACHINE_ARCH-unknown-secbsd$UNAME_RELEASE
+ ;;
*:LibertyBSD:*:*)
UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'`
- echo "$UNAME_MACHINE_ARCH"-unknown-libertybsd"$UNAME_RELEASE"
- exit ;;
+ GUESS=$UNAME_MACHINE_ARCH-unknown-libertybsd$UNAME_RELEASE
+ ;;
*:MidnightBSD:*:*)
- echo "$UNAME_MACHINE"-unknown-midnightbsd"$UNAME_RELEASE"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-midnightbsd$UNAME_RELEASE
+ ;;
*:ekkoBSD:*:*)
- echo "$UNAME_MACHINE"-unknown-ekkobsd"$UNAME_RELEASE"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-ekkobsd$UNAME_RELEASE
+ ;;
*:SolidBSD:*:*)
- echo "$UNAME_MACHINE"-unknown-solidbsd"$UNAME_RELEASE"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-solidbsd$UNAME_RELEASE
+ ;;
*:OS108:*:*)
- echo "$UNAME_MACHINE"-unknown-os108_"$UNAME_RELEASE"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-os108_$UNAME_RELEASE
+ ;;
macppc:MirBSD:*:*)
- echo powerpc-unknown-mirbsd"$UNAME_RELEASE"
- exit ;;
+ GUESS=powerpc-unknown-mirbsd$UNAME_RELEASE
+ ;;
*:MirBSD:*:*)
- echo "$UNAME_MACHINE"-unknown-mirbsd"$UNAME_RELEASE"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-mirbsd$UNAME_RELEASE
+ ;;
*:Sortix:*:*)
- echo "$UNAME_MACHINE"-unknown-sortix
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-sortix
+ ;;
*:Twizzler:*:*)
- echo "$UNAME_MACHINE"-unknown-twizzler
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-twizzler
+ ;;
*:Redox:*:*)
- echo "$UNAME_MACHINE"-unknown-redox
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-redox
+ ;;
mips:OSF1:*.*)
- echo mips-dec-osf1
- exit ;;
+ GUESS=mips-dec-osf1
+ ;;
alpha:OSF1:*:*)
+ # Reset EXIT trap before exiting to avoid spurious non-zero exit code.
+ trap '' 0
case $UNAME_RELEASE in
*4.0)
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
;;
*5.*)
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
;;
esac
# According to Compaq, /usr/sbin/psrinfo has been available on
# OSF/1 and Tru64 systems produced since 1995. I hope that
# covers most systems running today. This code pipes the CPU
# types through head -n 1, so we only detect the type of CPU 0.
ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`
- case "$ALPHA_CPU_TYPE" in
+ case $ALPHA_CPU_TYPE in
"EV4 (21064)")
UNAME_MACHINE=alpha ;;
"EV4.5 (21064)")
UNAME_MACHINE=alpha ;;
"LCA4 (21066/21068)")
UNAME_MACHINE=alpha ;;
"EV5 (21164)")
UNAME_MACHINE=alphaev5 ;;
"EV5.6 (21164A)")
UNAME_MACHINE=alphaev56 ;;
"EV5.6 (21164PC)")
UNAME_MACHINE=alphapca56 ;;
"EV5.7 (21164PC)")
UNAME_MACHINE=alphapca57 ;;
"EV6 (21264)")
UNAME_MACHINE=alphaev6 ;;
"EV6.7 (21264A)")
UNAME_MACHINE=alphaev67 ;;
"EV6.8CB (21264C)")
UNAME_MACHINE=alphaev68 ;;
"EV6.8AL (21264B)")
UNAME_MACHINE=alphaev68 ;;
"EV6.8CX (21264D)")
UNAME_MACHINE=alphaev68 ;;
"EV6.9A (21264/EV69A)")
UNAME_MACHINE=alphaev69 ;;
"EV7 (21364)")
UNAME_MACHINE=alphaev7 ;;
"EV7.9 (21364A)")
UNAME_MACHINE=alphaev79 ;;
esac
# A Pn.n version is a patched version.
# A Vn.n version is a released version.
# A Tn.n version is a released field test version.
# A Xn.n version is an unreleased experimental baselevel.
# 1.2 uses "1.2" for uname -r.
- echo "$UNAME_MACHINE"-dec-osf"`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`"
- # Reset EXIT trap before exiting to avoid spurious non-zero exit code.
- exitcode=$?
- trap '' 0
- exit $exitcode ;;
+ OSF_REL=`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
+ GUESS=$UNAME_MACHINE-dec-osf$OSF_REL
+ ;;
Amiga*:UNIX_System_V:4.0:*)
- echo m68k-unknown-sysv4
- exit ;;
+ GUESS=m68k-unknown-sysv4
+ ;;
*:[Aa]miga[Oo][Ss]:*:*)
- echo "$UNAME_MACHINE"-unknown-amigaos
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-amigaos
+ ;;
*:[Mm]orph[Oo][Ss]:*:*)
- echo "$UNAME_MACHINE"-unknown-morphos
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-morphos
+ ;;
*:OS/390:*:*)
- echo i370-ibm-openedition
- exit ;;
+ GUESS=i370-ibm-openedition
+ ;;
*:z/VM:*:*)
- echo s390-ibm-zvmoe
- exit ;;
+ GUESS=s390-ibm-zvmoe
+ ;;
*:OS400:*:*)
- echo powerpc-ibm-os400
- exit ;;
+ GUESS=powerpc-ibm-os400
+ ;;
arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
- echo arm-acorn-riscix"$UNAME_RELEASE"
- exit ;;
+ GUESS=arm-acorn-riscix$UNAME_RELEASE
+ ;;
arm*:riscos:*:*|arm*:RISCOS:*:*)
- echo arm-unknown-riscos
- exit ;;
+ GUESS=arm-unknown-riscos
+ ;;
SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
- echo hppa1.1-hitachi-hiuxmpp
- exit ;;
+ GUESS=hppa1.1-hitachi-hiuxmpp
+ ;;
Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
- if test "`(/bin/universe) 2>/dev/null`" = att ; then
- echo pyramid-pyramid-sysv3
- else
- echo pyramid-pyramid-bsd
- fi
- exit ;;
+ case `(/bin/universe) 2>/dev/null` in
+ att) GUESS=pyramid-pyramid-sysv3 ;;
+ *) GUESS=pyramid-pyramid-bsd ;;
+ esac
+ ;;
NILE*:*:*:dcosx)
- echo pyramid-pyramid-svr4
- exit ;;
+ GUESS=pyramid-pyramid-svr4
+ ;;
DRS?6000:unix:4.0:6*)
- echo sparc-icl-nx6
- exit ;;
+ GUESS=sparc-icl-nx6
+ ;;
DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
case `/usr/bin/uname -p` in
- sparc) echo sparc-icl-nx7; exit ;;
- esac ;;
+ sparc) GUESS=sparc-icl-nx7 ;;
+ esac
+ ;;
s390x:SunOS:*:*)
- echo "$UNAME_MACHINE"-ibm-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`"
- exit ;;
+ SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
+ GUESS=$UNAME_MACHINE-ibm-solaris2$SUN_REL
+ ;;
sun4H:SunOS:5.*:*)
- echo sparc-hal-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`"
- exit ;;
+ SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
+ GUESS=sparc-hal-solaris2$SUN_REL
+ ;;
sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
- echo sparc-sun-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`"
- exit ;;
+ SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
+ GUESS=sparc-sun-solaris2$SUN_REL
+ ;;
i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
- echo i386-pc-auroraux"$UNAME_RELEASE"
- exit ;;
+ GUESS=i386-pc-auroraux$UNAME_RELEASE
+ ;;
i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
set_cc_for_build
SUN_ARCH=i386
# If there is a compiler, see if it is configured for 64-bit objects.
# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
# This test works for both compilers.
- if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
+ if test "$CC_FOR_BUILD" != no_compiler_found; then
if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
- (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
+ (CCOPTS="" $CC_FOR_BUILD -m64 -E - 2>/dev/null) | \
grep IS_64BIT_ARCH >/dev/null
then
SUN_ARCH=x86_64
fi
fi
- echo "$SUN_ARCH"-pc-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`"
- exit ;;
+ SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
+ GUESS=$SUN_ARCH-pc-solaris2$SUN_REL
+ ;;
sun4*:SunOS:6*:*)
# According to config.sub, this is the proper way to canonicalize
# SunOS6. Hard to guess exactly what SunOS6 will be like, but
# it's likely to be more like Solaris than SunOS4.
- echo sparc-sun-solaris3"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`"
- exit ;;
+ SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
+ GUESS=sparc-sun-solaris3$SUN_REL
+ ;;
sun4*:SunOS:*:*)
- case "`/usr/bin/arch -k`" in
+ case `/usr/bin/arch -k` in
Series*|S4*)
UNAME_RELEASE=`uname -v`
;;
esac
# Japanese Language versions have a version number like `4.1.3-JL'.
- echo sparc-sun-sunos"`echo "$UNAME_RELEASE"|sed -e 's/-/_/'`"
- exit ;;
+ SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/'`
+ GUESS=sparc-sun-sunos$SUN_REL
+ ;;
sun3*:SunOS:*:*)
- echo m68k-sun-sunos"$UNAME_RELEASE"
- exit ;;
+ GUESS=m68k-sun-sunos$UNAME_RELEASE
+ ;;
sun*:*:4.2BSD:*)
UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3
- case "`/bin/arch`" in
+ case `/bin/arch` in
sun3)
- echo m68k-sun-sunos"$UNAME_RELEASE"
+ GUESS=m68k-sun-sunos$UNAME_RELEASE
;;
sun4)
- echo sparc-sun-sunos"$UNAME_RELEASE"
+ GUESS=sparc-sun-sunos$UNAME_RELEASE
;;
esac
- exit ;;
+ ;;
aushp:SunOS:*:*)
- echo sparc-auspex-sunos"$UNAME_RELEASE"
- exit ;;
+ GUESS=sparc-auspex-sunos$UNAME_RELEASE
+ ;;
# The situation for MiNT is a little confusing. The machine name
# can be virtually everything (everything which is not
# "atarist" or "atariste" at least should have a processor
# > m68000). The system name ranges from "MiNT" over "FreeMiNT"
# to the lowercase version "mint" (or "freemint"). Finally
# the system name "TOS" denotes a system which is actually not
# MiNT. But MiNT is downward compatible to TOS, so this should
# be no problem.
atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
- echo m68k-atari-mint"$UNAME_RELEASE"
- exit ;;
+ GUESS=m68k-atari-mint$UNAME_RELEASE
+ ;;
atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
- echo m68k-atari-mint"$UNAME_RELEASE"
- exit ;;
+ GUESS=m68k-atari-mint$UNAME_RELEASE
+ ;;
*falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
- echo m68k-atari-mint"$UNAME_RELEASE"
- exit ;;
+ GUESS=m68k-atari-mint$UNAME_RELEASE
+ ;;
milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
- echo m68k-milan-mint"$UNAME_RELEASE"
- exit ;;
+ GUESS=m68k-milan-mint$UNAME_RELEASE
+ ;;
hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
- echo m68k-hades-mint"$UNAME_RELEASE"
- exit ;;
+ GUESS=m68k-hades-mint$UNAME_RELEASE
+ ;;
*:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
- echo m68k-unknown-mint"$UNAME_RELEASE"
- exit ;;
+ GUESS=m68k-unknown-mint$UNAME_RELEASE
+ ;;
m68k:machten:*:*)
- echo m68k-apple-machten"$UNAME_RELEASE"
- exit ;;
+ GUESS=m68k-apple-machten$UNAME_RELEASE
+ ;;
powerpc:machten:*:*)
- echo powerpc-apple-machten"$UNAME_RELEASE"
- exit ;;
+ GUESS=powerpc-apple-machten$UNAME_RELEASE
+ ;;
RISC*:Mach:*:*)
- echo mips-dec-mach_bsd4.3
- exit ;;
+ GUESS=mips-dec-mach_bsd4.3
+ ;;
RISC*:ULTRIX:*:*)
- echo mips-dec-ultrix"$UNAME_RELEASE"
- exit ;;
+ GUESS=mips-dec-ultrix$UNAME_RELEASE
+ ;;
VAX*:ULTRIX*:*:*)
- echo vax-dec-ultrix"$UNAME_RELEASE"
- exit ;;
+ GUESS=vax-dec-ultrix$UNAME_RELEASE
+ ;;
2020:CLIX:*:* | 2430:CLIX:*:*)
- echo clipper-intergraph-clix"$UNAME_RELEASE"
- exit ;;
+ GUESS=clipper-intergraph-clix$UNAME_RELEASE
+ ;;
mips:*:*:UMIPS | mips:*:*:RISCos)
set_cc_for_build
sed 's/^ //' << EOF > "$dummy.c"
#ifdef __cplusplus
#include <stdio.h> /* for printf() prototype */
int main (int argc, char *argv[]) {
#else
int main (argc, argv) int argc; char *argv[]; {
#endif
#if defined (host_mips) && defined (MIPSEB)
#if defined (SYSTYPE_SYSV)
printf ("mips-mips-riscos%ssysv\\n", argv[1]); exit (0);
#endif
#if defined (SYSTYPE_SVR4)
printf ("mips-mips-riscos%ssvr4\\n", argv[1]); exit (0);
#endif
#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
printf ("mips-mips-riscos%sbsd\\n", argv[1]); exit (0);
#endif
#endif
exit (-1);
}
EOF
$CC_FOR_BUILD -o "$dummy" "$dummy.c" &&
dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` &&
SYSTEM_NAME=`"$dummy" "$dummyarg"` &&
{ echo "$SYSTEM_NAME"; exit; }
- echo mips-mips-riscos"$UNAME_RELEASE"
- exit ;;
+ GUESS=mips-mips-riscos$UNAME_RELEASE
+ ;;
Motorola:PowerMAX_OS:*:*)
- echo powerpc-motorola-powermax
- exit ;;
+ GUESS=powerpc-motorola-powermax
+ ;;
Motorola:*:4.3:PL8-*)
- echo powerpc-harris-powermax
- exit ;;
+ GUESS=powerpc-harris-powermax
+ ;;
Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
- echo powerpc-harris-powermax
- exit ;;
+ GUESS=powerpc-harris-powermax
+ ;;
Night_Hawk:Power_UNIX:*:*)
- echo powerpc-harris-powerunix
- exit ;;
+ GUESS=powerpc-harris-powerunix
+ ;;
m88k:CX/UX:7*:*)
- echo m88k-harris-cxux7
- exit ;;
+ GUESS=m88k-harris-cxux7
+ ;;
m88k:*:4*:R4*)
- echo m88k-motorola-sysv4
- exit ;;
+ GUESS=m88k-motorola-sysv4
+ ;;
m88k:*:3*:R3*)
- echo m88k-motorola-sysv3
- exit ;;
+ GUESS=m88k-motorola-sysv3
+ ;;
AViiON:dgux:*:*)
# DG/UX returns AViiON for all architectures
UNAME_PROCESSOR=`/usr/bin/uname -p`
- if [ "$UNAME_PROCESSOR" = mc88100 ] || [ "$UNAME_PROCESSOR" = mc88110 ]
+ if test "$UNAME_PROCESSOR" = mc88100 || test "$UNAME_PROCESSOR" = mc88110
then
- if [ "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx ] || \
- [ "$TARGET_BINARY_INTERFACE"x = x ]
+ if test "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx || \
+ test "$TARGET_BINARY_INTERFACE"x = x
then
- echo m88k-dg-dgux"$UNAME_RELEASE"
+ GUESS=m88k-dg-dgux$UNAME_RELEASE
else
- echo m88k-dg-dguxbcs"$UNAME_RELEASE"
+ GUESS=m88k-dg-dguxbcs$UNAME_RELEASE
fi
else
- echo i586-dg-dgux"$UNAME_RELEASE"
+ GUESS=i586-dg-dgux$UNAME_RELEASE
fi
- exit ;;
+ ;;
M88*:DolphinOS:*:*) # DolphinOS (SVR3)
- echo m88k-dolphin-sysv3
- exit ;;
+ GUESS=m88k-dolphin-sysv3
+ ;;
M88*:*:R3*:*)
# Delta 88k system running SVR3
- echo m88k-motorola-sysv3
- exit ;;
+ GUESS=m88k-motorola-sysv3
+ ;;
XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
- echo m88k-tektronix-sysv3
- exit ;;
+ GUESS=m88k-tektronix-sysv3
+ ;;
Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
- echo m68k-tektronix-bsd
- exit ;;
+ GUESS=m68k-tektronix-bsd
+ ;;
*:IRIX*:*:*)
- echo mips-sgi-irix"`echo "$UNAME_RELEASE"|sed -e 's/-/_/g'`"
- exit ;;
+ IRIX_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/g'`
+ GUESS=mips-sgi-irix$IRIX_REL
+ ;;
????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
- echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
- exit ;; # Note that: echo "'`uname -s`'" gives 'AIX '
+ GUESS=romp-ibm-aix # uname -m gives an 8 hex-code CPU id
+ ;; # Note that: echo "'`uname -s`'" gives 'AIX '
i*86:AIX:*:*)
- echo i386-ibm-aix
- exit ;;
+ GUESS=i386-ibm-aix
+ ;;
ia64:AIX:*:*)
- if [ -x /usr/bin/oslevel ] ; then
+ if test -x /usr/bin/oslevel ; then
IBM_REV=`/usr/bin/oslevel`
else
- IBM_REV="$UNAME_VERSION.$UNAME_RELEASE"
+ IBM_REV=$UNAME_VERSION.$UNAME_RELEASE
fi
- echo "$UNAME_MACHINE"-ibm-aix"$IBM_REV"
- exit ;;
+ GUESS=$UNAME_MACHINE-ibm-aix$IBM_REV
+ ;;
*:AIX:2:3)
if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
set_cc_for_build
sed 's/^ //' << EOF > "$dummy.c"
#include <sys/systemcfg.h>
main()
{
if (!__power_pc())
exit(1);
puts("powerpc-ibm-aix3.2.5");
exit(0);
}
EOF
if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"`
then
- echo "$SYSTEM_NAME"
+ GUESS=$SYSTEM_NAME
else
- echo rs6000-ibm-aix3.2.5
+ GUESS=rs6000-ibm-aix3.2.5
fi
elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
- echo rs6000-ibm-aix3.2.4
+ GUESS=rs6000-ibm-aix3.2.4
else
- echo rs6000-ibm-aix3.2
+ GUESS=rs6000-ibm-aix3.2
fi
- exit ;;
+ ;;
*:AIX:*:[4567])
IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then
IBM_ARCH=rs6000
else
IBM_ARCH=powerpc
fi
- if [ -x /usr/bin/lslpp ] ; then
- IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc |
+ if test -x /usr/bin/lslpp ; then
+ IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | \
awk -F: '{ print $3 }' | sed s/[0-9]*$/0/`
else
- IBM_REV="$UNAME_VERSION.$UNAME_RELEASE"
+ IBM_REV=$UNAME_VERSION.$UNAME_RELEASE
fi
- echo "$IBM_ARCH"-ibm-aix"$IBM_REV"
- exit ;;
+ GUESS=$IBM_ARCH-ibm-aix$IBM_REV
+ ;;
*:AIX:*:*)
- echo rs6000-ibm-aix
- exit ;;
+ GUESS=rs6000-ibm-aix
+ ;;
ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*)
- echo romp-ibm-bsd4.4
- exit ;;
+ GUESS=romp-ibm-bsd4.4
+ ;;
ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
- echo romp-ibm-bsd"$UNAME_RELEASE" # 4.3 with uname added to
- exit ;; # report: romp-ibm BSD 4.3
+ GUESS=romp-ibm-bsd$UNAME_RELEASE # 4.3 with uname added to
+ ;; # report: romp-ibm BSD 4.3
*:BOSX:*:*)
- echo rs6000-bull-bosx
- exit ;;
+ GUESS=rs6000-bull-bosx
+ ;;
DPX/2?00:B.O.S.:*:*)
- echo m68k-bull-sysv3
- exit ;;
+ GUESS=m68k-bull-sysv3
+ ;;
9000/[34]??:4.3bsd:1.*:*)
- echo m68k-hp-bsd
- exit ;;
+ GUESS=m68k-hp-bsd
+ ;;
hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
- echo m68k-hp-bsd4.4
- exit ;;
+ GUESS=m68k-hp-bsd4.4
+ ;;
9000/[34678]??:HP-UX:*:*)
- HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'`
- case "$UNAME_MACHINE" in
+ HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'`
+ case $UNAME_MACHINE in
9000/31?) HP_ARCH=m68000 ;;
9000/[34]??) HP_ARCH=m68k ;;
9000/[678][0-9][0-9])
- if [ -x /usr/bin/getconf ]; then
+ if test -x /usr/bin/getconf; then
sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
- case "$sc_cpu_version" in
+ case $sc_cpu_version in
523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0
528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1
532) # CPU_PA_RISC2_0
- case "$sc_kernel_bits" in
+ case $sc_kernel_bits in
32) HP_ARCH=hppa2.0n ;;
64) HP_ARCH=hppa2.0w ;;
'') HP_ARCH=hppa2.0 ;; # HP-UX 10.20
esac ;;
esac
fi
- if [ "$HP_ARCH" = "" ]; then
+ if test "$HP_ARCH" = ""; then
set_cc_for_build
sed 's/^ //' << EOF > "$dummy.c"
#define _HPUX_SOURCE
#include <stdlib.h>
#include <unistd.h>
int main ()
{
#if defined(_SC_KERNEL_BITS)
long bits = sysconf(_SC_KERNEL_BITS);
#endif
long cpu = sysconf (_SC_CPU_VERSION);
switch (cpu)
{
case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
case CPU_PA_RISC2_0:
#if defined(_SC_KERNEL_BITS)
switch (bits)
{
case 64: puts ("hppa2.0w"); break;
case 32: puts ("hppa2.0n"); break;
default: puts ("hppa2.0"); break;
} break;
#else /* !defined(_SC_KERNEL_BITS) */
puts ("hppa2.0"); break;
#endif
default: puts ("hppa1.0"); break;
}
exit (0);
}
EOF
(CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"`
test -z "$HP_ARCH" && HP_ARCH=hppa
fi ;;
esac
- if [ "$HP_ARCH" = hppa2.0w ]
+ if test "$HP_ARCH" = hppa2.0w
then
set_cc_for_build
# hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
# 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler
# generating 64-bit code. GNU and HP use different nomenclature:
#
# $ CC_FOR_BUILD=cc ./config.guess
# => hppa2.0w-hp-hpux11.23
# $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
# => hppa64-hp-hpux11.23
if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) |
grep -q __LP64__
then
HP_ARCH=hppa2.0w
else
HP_ARCH=hppa64
fi
fi
- echo "$HP_ARCH"-hp-hpux"$HPUX_REV"
- exit ;;
+ GUESS=$HP_ARCH-hp-hpux$HPUX_REV
+ ;;
ia64:HP-UX:*:*)
- HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'`
- echo ia64-hp-hpux"$HPUX_REV"
- exit ;;
+ HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'`
+ GUESS=ia64-hp-hpux$HPUX_REV
+ ;;
3050*:HI-UX:*:*)
set_cc_for_build
sed 's/^ //' << EOF > "$dummy.c"
#include <unistd.h>
int
main ()
{
long cpu = sysconf (_SC_CPU_VERSION);
/* The order matters, because CPU_IS_HP_MC68K erroneously returns
true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
results, however. */
if (CPU_IS_PA_RISC (cpu))
{
switch (cpu)
{
case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
default: puts ("hppa-hitachi-hiuxwe2"); break;
}
}
else if (CPU_IS_HP_MC68K (cpu))
puts ("m68k-hitachi-hiuxwe2");
else puts ("unknown-hitachi-hiuxwe2");
exit (0);
}
EOF
$CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` &&
{ echo "$SYSTEM_NAME"; exit; }
- echo unknown-hitachi-hiuxwe2
- exit ;;
+ GUESS=unknown-hitachi-hiuxwe2
+ ;;
9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*)
- echo hppa1.1-hp-bsd
- exit ;;
+ GUESS=hppa1.1-hp-bsd
+ ;;
9000/8??:4.3bsd:*:*)
- echo hppa1.0-hp-bsd
- exit ;;
+ GUESS=hppa1.0-hp-bsd
+ ;;
*9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
- echo hppa1.0-hp-mpeix
- exit ;;
+ GUESS=hppa1.0-hp-mpeix
+ ;;
hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*)
- echo hppa1.1-hp-osf
- exit ;;
+ GUESS=hppa1.1-hp-osf
+ ;;
hp8??:OSF1:*:*)
- echo hppa1.0-hp-osf
- exit ;;
+ GUESS=hppa1.0-hp-osf
+ ;;
i*86:OSF1:*:*)
- if [ -x /usr/sbin/sysversion ] ; then
- echo "$UNAME_MACHINE"-unknown-osf1mk
+ if test -x /usr/sbin/sysversion ; then
+ GUESS=$UNAME_MACHINE-unknown-osf1mk
else
- echo "$UNAME_MACHINE"-unknown-osf1
+ GUESS=$UNAME_MACHINE-unknown-osf1
fi
- exit ;;
+ ;;
parisc*:Lites*:*:*)
- echo hppa1.1-hp-lites
- exit ;;
+ GUESS=hppa1.1-hp-lites
+ ;;
C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
- echo c1-convex-bsd
- exit ;;
+ GUESS=c1-convex-bsd
+ ;;
C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
if getsysinfo -f scalar_acc
then echo c32-convex-bsd
else echo c2-convex-bsd
fi
exit ;;
C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
- echo c34-convex-bsd
- exit ;;
+ GUESS=c34-convex-bsd
+ ;;
C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
- echo c38-convex-bsd
- exit ;;
+ GUESS=c38-convex-bsd
+ ;;
C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
- echo c4-convex-bsd
- exit ;;
+ GUESS=c4-convex-bsd
+ ;;
CRAY*Y-MP:*:*:*)
- echo ymp-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
- exit ;;
+ CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'`
+ GUESS=ymp-cray-unicos$CRAY_REL
+ ;;
CRAY*[A-Z]90:*:*:*)
echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \
| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
-e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
-e 's/\.[^.]*$/.X/'
exit ;;
CRAY*TS:*:*:*)
- echo t90-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
- exit ;;
+ CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'`
+ GUESS=t90-cray-unicos$CRAY_REL
+ ;;
CRAY*T3E:*:*:*)
- echo alphaev5-cray-unicosmk"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
- exit ;;
+ CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'`
+ GUESS=alphaev5-cray-unicosmk$CRAY_REL
+ ;;
CRAY*SV1:*:*:*)
- echo sv1-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
- exit ;;
+ CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'`
+ GUESS=sv1-cray-unicos$CRAY_REL
+ ;;
*:UNICOS/mp:*:*)
- echo craynv-cray-unicosmp"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
- exit ;;
+ CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'`
+ GUESS=craynv-cray-unicosmp$CRAY_REL
+ ;;
F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'`
- echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
- exit ;;
+ GUESS=${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}
+ ;;
5000:UNIX_System_V:4.*:*)
FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'`
- echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
- exit ;;
+ GUESS=sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}
+ ;;
i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
- echo "$UNAME_MACHINE"-pc-bsdi"$UNAME_RELEASE"
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-bsdi$UNAME_RELEASE
+ ;;
sparc*:BSD/OS:*:*)
- echo sparc-unknown-bsdi"$UNAME_RELEASE"
- exit ;;
+ GUESS=sparc-unknown-bsdi$UNAME_RELEASE
+ ;;
*:BSD/OS:*:*)
- echo "$UNAME_MACHINE"-unknown-bsdi"$UNAME_RELEASE"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-bsdi$UNAME_RELEASE
+ ;;
arm:FreeBSD:*:*)
UNAME_PROCESSOR=`uname -p`
set_cc_for_build
if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ARM_PCS_VFP
then
- echo "${UNAME_PROCESSOR}"-unknown-freebsd"`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`"-gnueabi
+ FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`
+ GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabi
else
- echo "${UNAME_PROCESSOR}"-unknown-freebsd"`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`"-gnueabihf
+ FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`
+ GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabihf
fi
- exit ;;
+ ;;
*:FreeBSD:*:*)
UNAME_PROCESSOR=`/usr/bin/uname -p`
- case "$UNAME_PROCESSOR" in
+ case $UNAME_PROCESSOR in
amd64)
UNAME_PROCESSOR=x86_64 ;;
i386)
UNAME_PROCESSOR=i586 ;;
esac
- echo "$UNAME_PROCESSOR"-unknown-freebsd"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`"
- exit ;;
+ FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`
+ GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL
+ ;;
i*:CYGWIN*:*)
- echo "$UNAME_MACHINE"-pc-cygwin
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-cygwin
+ ;;
*:MINGW64*:*)
- echo "$UNAME_MACHINE"-pc-mingw64
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-mingw64
+ ;;
*:MINGW*:*)
- echo "$UNAME_MACHINE"-pc-mingw32
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-mingw32
+ ;;
*:MSYS*:*)
- echo "$UNAME_MACHINE"-pc-msys
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-msys
+ ;;
i*:PW*:*)
- echo "$UNAME_MACHINE"-pc-pw32
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-pw32
+ ;;
+ *:SerenityOS:*:*)
+ GUESS=$UNAME_MACHINE-pc-serenity
+ ;;
*:Interix*:*)
- case "$UNAME_MACHINE" in
+ case $UNAME_MACHINE in
x86)
- echo i586-pc-interix"$UNAME_RELEASE"
- exit ;;
+ GUESS=i586-pc-interix$UNAME_RELEASE
+ ;;
authenticamd | genuineintel | EM64T)
- echo x86_64-unknown-interix"$UNAME_RELEASE"
- exit ;;
+ GUESS=x86_64-unknown-interix$UNAME_RELEASE
+ ;;
IA64)
- echo ia64-unknown-interix"$UNAME_RELEASE"
- exit ;;
+ GUESS=ia64-unknown-interix$UNAME_RELEASE
+ ;;
esac ;;
i*:UWIN*:*)
- echo "$UNAME_MACHINE"-pc-uwin
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-uwin
+ ;;
amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
- echo x86_64-pc-cygwin
- exit ;;
+ GUESS=x86_64-pc-cygwin
+ ;;
prep*:SunOS:5.*:*)
- echo powerpcle-unknown-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`"
- exit ;;
+ SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
+ GUESS=powerpcle-unknown-solaris2$SUN_REL
+ ;;
*:GNU:*:*)
# the GNU system
- echo "`echo "$UNAME_MACHINE"|sed -e 's,[-/].*$,,'`-unknown-$LIBC`echo "$UNAME_RELEASE"|sed -e 's,/.*$,,'`"
- exit ;;
+ GNU_ARCH=`echo "$UNAME_MACHINE" | sed -e 's,[-/].*$,,'`
+ GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's,/.*$,,'`
+ GUESS=$GNU_ARCH-unknown-$LIBC$GNU_REL
+ ;;
*:GNU/*:*:*)
# other systems with GNU libc and userland
- echo "$UNAME_MACHINE-unknown-`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`-$LIBC"
- exit ;;
+ GNU_SYS=`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"`
+ GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`
+ GUESS=$UNAME_MACHINE-unknown-$GNU_SYS$GNU_REL-$LIBC
+ ;;
+ x86_64:[Mm]anagarm:*:*|i?86:[Mm]anagarm:*:*)
+ GUESS="$UNAME_MACHINE-pc-managarm-mlibc"
+ ;;
+ *:[Mm]anagarm:*:*)
+ GUESS="$UNAME_MACHINE-unknown-managarm-mlibc"
+ ;;
*:Minix:*:*)
- echo "$UNAME_MACHINE"-unknown-minix
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-minix
+ ;;
aarch64:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
aarch64_be:Linux:*:*)
UNAME_MACHINE=aarch64_be
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
alpha:Linux:*:*)
case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' /proc/cpuinfo 2>/dev/null` in
EV5) UNAME_MACHINE=alphaev5 ;;
EV56) UNAME_MACHINE=alphaev56 ;;
PCA56) UNAME_MACHINE=alphapca56 ;;
PCA57) UNAME_MACHINE=alphapca56 ;;
EV6) UNAME_MACHINE=alphaev6 ;;
EV67) UNAME_MACHINE=alphaev67 ;;
EV68*) UNAME_MACHINE=alphaev68 ;;
esac
objdump --private-headers /bin/sh | grep -q ld.so.1
if test "$?" = 0 ; then LIBC=gnulibc1 ; fi
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
- arc:Linux:*:* | arceb:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
+ arc:Linux:*:* | arceb:Linux:*:* | arc32:Linux:*:* | arc64:Linux:*:*)
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
arm*:Linux:*:*)
set_cc_for_build
if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ARM_EABI__
then
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
else
if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ARM_PCS_VFP
then
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabi
+ GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabi
else
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabihf
+ GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabihf
fi
fi
- exit ;;
+ ;;
avr32*:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
cris:Linux:*:*)
- echo "$UNAME_MACHINE"-axis-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-axis-linux-$LIBC
+ ;;
crisv32:Linux:*:*)
- echo "$UNAME_MACHINE"-axis-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-axis-linux-$LIBC
+ ;;
e2k:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
frv:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
hexagon:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
i*86:Linux:*:*)
- echo "$UNAME_MACHINE"-pc-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-linux-$LIBC
+ ;;
ia64:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
k1om:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
+ loongarch32:Linux:*:* | loongarch64:Linux:*:*)
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
m32r*:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
m68*:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
mips:Linux:*:* | mips64:Linux:*:*)
set_cc_for_build
IS_GLIBC=0
test x"${LIBC}" = xgnu && IS_GLIBC=1
sed 's/^ //' << EOF > "$dummy.c"
#undef CPU
#undef mips
#undef mipsel
#undef mips64
#undef mips64el
#if ${IS_GLIBC} && defined(_ABI64)
LIBCABI=gnuabi64
#else
#if ${IS_GLIBC} && defined(_ABIN32)
LIBCABI=gnuabin32
#else
LIBCABI=${LIBC}
#endif
#endif
#if ${IS_GLIBC} && defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6
CPU=mipsisa64r6
#else
#if ${IS_GLIBC} && !defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6
CPU=mipsisa32r6
#else
#if defined(__mips64)
CPU=mips64
#else
CPU=mips
#endif
#endif
#endif
#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
MIPS_ENDIAN=el
#else
#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
MIPS_ENDIAN=
#else
MIPS_ENDIAN=
#endif
#endif
EOF
- eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI'`"
+ cc_set_vars=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI'`
+ eval "$cc_set_vars"
test "x$CPU" != x && { echo "$CPU${MIPS_ENDIAN}-unknown-linux-$LIBCABI"; exit; }
;;
mips64el:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
openrisc*:Linux:*:*)
- echo or1k-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=or1k-unknown-linux-$LIBC
+ ;;
or32:Linux:*:* | or1k*:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
padre:Linux:*:*)
- echo sparc-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=sparc-unknown-linux-$LIBC
+ ;;
parisc64:Linux:*:* | hppa64:Linux:*:*)
- echo hppa64-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=hppa64-unknown-linux-$LIBC
+ ;;
parisc:Linux:*:* | hppa:Linux:*:*)
# Look for CPU level
case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
- PA7*) echo hppa1.1-unknown-linux-"$LIBC" ;;
- PA8*) echo hppa2.0-unknown-linux-"$LIBC" ;;
- *) echo hppa-unknown-linux-"$LIBC" ;;
+ PA7*) GUESS=hppa1.1-unknown-linux-$LIBC ;;
+ PA8*) GUESS=hppa2.0-unknown-linux-$LIBC ;;
+ *) GUESS=hppa-unknown-linux-$LIBC ;;
esac
- exit ;;
+ ;;
ppc64:Linux:*:*)
- echo powerpc64-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=powerpc64-unknown-linux-$LIBC
+ ;;
ppc:Linux:*:*)
- echo powerpc-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=powerpc-unknown-linux-$LIBC
+ ;;
ppc64le:Linux:*:*)
- echo powerpc64le-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=powerpc64le-unknown-linux-$LIBC
+ ;;
ppcle:Linux:*:*)
- echo powerpcle-unknown-linux-"$LIBC"
- exit ;;
- riscv32:Linux:*:* | riscv64:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=powerpcle-unknown-linux-$LIBC
+ ;;
+ riscv32:Linux:*:* | riscv32be:Linux:*:* | riscv64:Linux:*:* | riscv64be:Linux:*:*)
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
s390:Linux:*:* | s390x:Linux:*:*)
- echo "$UNAME_MACHINE"-ibm-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-ibm-linux-$LIBC
+ ;;
sh64*:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
sh*:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
sparc:Linux:*:* | sparc64:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
tile*:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
vax:Linux:*:*)
- echo "$UNAME_MACHINE"-dec-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-dec-linux-$LIBC
+ ;;
x86_64:Linux:*:*)
- echo "$UNAME_MACHINE"-pc-linux-"$LIBC"
- exit ;;
+ set_cc_for_build
+ CPU=$UNAME_MACHINE
+ LIBCABI=$LIBC
+ if test "$CC_FOR_BUILD" != no_compiler_found; then
+ ABI=64
+ sed 's/^ //' << EOF > "$dummy.c"
+ #ifdef __i386__
+ ABI=x86
+ #else
+ #ifdef __ILP32__
+ ABI=x32
+ #endif
+ #endif
+EOF
+ cc_set_abi=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^ABI' | sed 's, ,,g'`
+ eval "$cc_set_abi"
+ case $ABI in
+ x86) CPU=i686 ;;
+ x32) LIBCABI=${LIBC}x32 ;;
+ esac
+ fi
+ GUESS=$CPU-pc-linux-$LIBCABI
+ ;;
xtensa*:Linux:*:*)
- echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+ ;;
i*86:DYNIX/ptx:4*:*)
# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
# earlier versions are messed up and put the nodename in both
# sysname and nodename.
- echo i386-sequent-sysv4
- exit ;;
+ GUESS=i386-sequent-sysv4
+ ;;
i*86:UNIX_SV:4.2MP:2.*)
# Unixware is an offshoot of SVR4, but it has its own version
# number series starting with 2...
# I am not positive that other SVR4 systems won't match this,
# I just have to hope. -- rms.
# Use sysv4.2uw... so that sysv4* matches it.
- echo "$UNAME_MACHINE"-pc-sysv4.2uw"$UNAME_VERSION"
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-sysv4.2uw$UNAME_VERSION
+ ;;
i*86:OS/2:*:*)
# If we were able to find `uname', then EMX Unix compatibility
# is probably installed.
- echo "$UNAME_MACHINE"-pc-os2-emx
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-os2-emx
+ ;;
i*86:XTS-300:*:STOP)
- echo "$UNAME_MACHINE"-unknown-stop
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-stop
+ ;;
i*86:atheos:*:*)
- echo "$UNAME_MACHINE"-unknown-atheos
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-atheos
+ ;;
i*86:syllable:*:*)
- echo "$UNAME_MACHINE"-pc-syllable
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-syllable
+ ;;
i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
- echo i386-unknown-lynxos"$UNAME_RELEASE"
- exit ;;
+ GUESS=i386-unknown-lynxos$UNAME_RELEASE
+ ;;
i*86:*DOS:*:*)
- echo "$UNAME_MACHINE"-pc-msdosdjgpp
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-msdosdjgpp
+ ;;
i*86:*:4.*:*)
UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'`
if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
- echo "$UNAME_MACHINE"-univel-sysv"$UNAME_REL"
+ GUESS=$UNAME_MACHINE-univel-sysv$UNAME_REL
else
- echo "$UNAME_MACHINE"-pc-sysv"$UNAME_REL"
+ GUESS=$UNAME_MACHINE-pc-sysv$UNAME_REL
fi
- exit ;;
+ ;;
i*86:*:5:[678]*)
# UnixWare 7.x, OpenUNIX and OpenServer 6.
case `/bin/uname -X | grep "^Machine"` in
*486*) UNAME_MACHINE=i486 ;;
*Pentium) UNAME_MACHINE=i586 ;;
*Pent*|*Celeron) UNAME_MACHINE=i686 ;;
esac
- echo "$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+ ;;
i*86:*:3.2:*)
if test -f /usr/options/cb.name; then
UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
- echo "$UNAME_MACHINE"-pc-isc"$UNAME_REL"
+ GUESS=$UNAME_MACHINE-pc-isc$UNAME_REL
elif /bin/uname -X 2>/dev/null >/dev/null ; then
UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
(/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
&& UNAME_MACHINE=i586
(/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
&& UNAME_MACHINE=i686
(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
&& UNAME_MACHINE=i686
- echo "$UNAME_MACHINE"-pc-sco"$UNAME_REL"
+ GUESS=$UNAME_MACHINE-pc-sco$UNAME_REL
else
- echo "$UNAME_MACHINE"-pc-sysv32
+ GUESS=$UNAME_MACHINE-pc-sysv32
fi
- exit ;;
+ ;;
pc:*:*:*)
# Left here for compatibility:
# uname -m prints for DJGPP always 'pc', but it prints nothing about
# the processor, so we play safe by assuming i586.
# Note: whatever this is, it MUST be the same as what config.sub
# prints for the "djgpp" host, or else GDB configure will decide that
# this is a cross-build.
- echo i586-pc-msdosdjgpp
- exit ;;
+ GUESS=i586-pc-msdosdjgpp
+ ;;
Intel:Mach:3*:*)
- echo i386-pc-mach3
- exit ;;
+ GUESS=i386-pc-mach3
+ ;;
paragon:*:*:*)
- echo i860-intel-osf1
- exit ;;
+ GUESS=i860-intel-osf1
+ ;;
i860:*:4.*:*) # i860-SVR4
if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
- echo i860-stardent-sysv"$UNAME_RELEASE" # Stardent Vistra i860-SVR4
+ GUESS=i860-stardent-sysv$UNAME_RELEASE # Stardent Vistra i860-SVR4
else # Add other i860-SVR4 vendors below as they are discovered.
- echo i860-unknown-sysv"$UNAME_RELEASE" # Unknown i860-SVR4
+ GUESS=i860-unknown-sysv$UNAME_RELEASE # Unknown i860-SVR4
fi
- exit ;;
+ ;;
mini*:CTIX:SYS*5:*)
# "miniframe"
- echo m68010-convergent-sysv
- exit ;;
+ GUESS=m68010-convergent-sysv
+ ;;
mc68k:UNIX:SYSTEM5:3.51m)
- echo m68k-convergent-sysv
- exit ;;
+ GUESS=m68k-convergent-sysv
+ ;;
M680?0:D-NIX:5.3:*)
- echo m68k-diab-dnix
- exit ;;
+ GUESS=m68k-diab-dnix
+ ;;
M68*:*:R3V[5678]*:*)
test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
OS_REL=''
test -r /etc/.relid \
&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
&& { echo i486-ncr-sysv4.3"$OS_REL"; exit; }
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
&& { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;;
3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
&& { echo i486-ncr-sysv4; exit; } ;;
NCR*:*:4.2:* | MPRAS*:*:4.2:*)
OS_REL='.3'
test -r /etc/.relid \
&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
&& { echo i486-ncr-sysv4.3"$OS_REL"; exit; }
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
&& { echo i586-ncr-sysv4.3"$OS_REL"; exit; }
/bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
&& { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;;
m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
- echo m68k-unknown-lynxos"$UNAME_RELEASE"
- exit ;;
+ GUESS=m68k-unknown-lynxos$UNAME_RELEASE
+ ;;
mc68030:UNIX_System_V:4.*:*)
- echo m68k-atari-sysv4
- exit ;;
+ GUESS=m68k-atari-sysv4
+ ;;
TSUNAMI:LynxOS:2.*:*)
- echo sparc-unknown-lynxos"$UNAME_RELEASE"
- exit ;;
+ GUESS=sparc-unknown-lynxos$UNAME_RELEASE
+ ;;
rs6000:LynxOS:2.*:*)
- echo rs6000-unknown-lynxos"$UNAME_RELEASE"
- exit ;;
+ GUESS=rs6000-unknown-lynxos$UNAME_RELEASE
+ ;;
PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
- echo powerpc-unknown-lynxos"$UNAME_RELEASE"
- exit ;;
+ GUESS=powerpc-unknown-lynxos$UNAME_RELEASE
+ ;;
SM[BE]S:UNIX_SV:*:*)
- echo mips-dde-sysv"$UNAME_RELEASE"
- exit ;;
+ GUESS=mips-dde-sysv$UNAME_RELEASE
+ ;;
RM*:ReliantUNIX-*:*:*)
- echo mips-sni-sysv4
- exit ;;
+ GUESS=mips-sni-sysv4
+ ;;
RM*:SINIX-*:*:*)
- echo mips-sni-sysv4
- exit ;;
+ GUESS=mips-sni-sysv4
+ ;;
*:SINIX-*:*:*)
if uname -p 2>/dev/null >/dev/null ; then
UNAME_MACHINE=`(uname -p) 2>/dev/null`
- echo "$UNAME_MACHINE"-sni-sysv4
+ GUESS=$UNAME_MACHINE-sni-sysv4
else
- echo ns32k-sni-sysv
+ GUESS=ns32k-sni-sysv
fi
- exit ;;
+ ;;
PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
# says <Richard.M.Bartel@ccMail.Census.GOV>
- echo i586-unisys-sysv4
- exit ;;
+ GUESS=i586-unisys-sysv4
+ ;;
*:UNIX_System_V:4*:FTX*)
# From Gerald Hewes <hewes@openmarket.com>.
# How about differentiating between stratus architectures? -djm
- echo hppa1.1-stratus-sysv4
- exit ;;
+ GUESS=hppa1.1-stratus-sysv4
+ ;;
*:*:*:FTX*)
# From seanf@swdc.stratus.com.
- echo i860-stratus-sysv4
- exit ;;
+ GUESS=i860-stratus-sysv4
+ ;;
i*86:VOS:*:*)
# From Paul.Green@stratus.com.
- echo "$UNAME_MACHINE"-stratus-vos
- exit ;;
+ GUESS=$UNAME_MACHINE-stratus-vos
+ ;;
*:VOS:*:*)
# From Paul.Green@stratus.com.
- echo hppa1.1-stratus-vos
- exit ;;
+ GUESS=hppa1.1-stratus-vos
+ ;;
mc68*:A/UX:*:*)
- echo m68k-apple-aux"$UNAME_RELEASE"
- exit ;;
+ GUESS=m68k-apple-aux$UNAME_RELEASE
+ ;;
news*:NEWS-OS:6*:*)
- echo mips-sony-newsos6
- exit ;;
+ GUESS=mips-sony-newsos6
+ ;;
R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
- if [ -d /usr/nec ]; then
- echo mips-nec-sysv"$UNAME_RELEASE"
+ if test -d /usr/nec; then
+ GUESS=mips-nec-sysv$UNAME_RELEASE
else
- echo mips-unknown-sysv"$UNAME_RELEASE"
+ GUESS=mips-unknown-sysv$UNAME_RELEASE
fi
- exit ;;
+ ;;
BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
- echo powerpc-be-beos
- exit ;;
+ GUESS=powerpc-be-beos
+ ;;
BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
- echo powerpc-apple-beos
- exit ;;
+ GUESS=powerpc-apple-beos
+ ;;
BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
- echo i586-pc-beos
- exit ;;
+ GUESS=i586-pc-beos
+ ;;
BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
- echo i586-pc-haiku
- exit ;;
- x86_64:Haiku:*:*)
- echo x86_64-unknown-haiku
- exit ;;
+ GUESS=i586-pc-haiku
+ ;;
+ ppc:Haiku:*:*) # Haiku running on Apple PowerPC
+ GUESS=powerpc-apple-haiku
+ ;;
+ *:Haiku:*:*) # Haiku modern gcc (not bound by BeOS compat)
+ GUESS=$UNAME_MACHINE-unknown-haiku
+ ;;
SX-4:SUPER-UX:*:*)
- echo sx4-nec-superux"$UNAME_RELEASE"
- exit ;;
+ GUESS=sx4-nec-superux$UNAME_RELEASE
+ ;;
SX-5:SUPER-UX:*:*)
- echo sx5-nec-superux"$UNAME_RELEASE"
- exit ;;
+ GUESS=sx5-nec-superux$UNAME_RELEASE
+ ;;
SX-6:SUPER-UX:*:*)
- echo sx6-nec-superux"$UNAME_RELEASE"
- exit ;;
+ GUESS=sx6-nec-superux$UNAME_RELEASE
+ ;;
SX-7:SUPER-UX:*:*)
- echo sx7-nec-superux"$UNAME_RELEASE"
- exit ;;
+ GUESS=sx7-nec-superux$UNAME_RELEASE
+ ;;
SX-8:SUPER-UX:*:*)
- echo sx8-nec-superux"$UNAME_RELEASE"
- exit ;;
+ GUESS=sx8-nec-superux$UNAME_RELEASE
+ ;;
SX-8R:SUPER-UX:*:*)
- echo sx8r-nec-superux"$UNAME_RELEASE"
- exit ;;
+ GUESS=sx8r-nec-superux$UNAME_RELEASE
+ ;;
SX-ACE:SUPER-UX:*:*)
- echo sxace-nec-superux"$UNAME_RELEASE"
- exit ;;
+ GUESS=sxace-nec-superux$UNAME_RELEASE
+ ;;
Power*:Rhapsody:*:*)
- echo powerpc-apple-rhapsody"$UNAME_RELEASE"
- exit ;;
+ GUESS=powerpc-apple-rhapsody$UNAME_RELEASE
+ ;;
*:Rhapsody:*:*)
- echo "$UNAME_MACHINE"-apple-rhapsody"$UNAME_RELEASE"
- exit ;;
+ GUESS=$UNAME_MACHINE-apple-rhapsody$UNAME_RELEASE
+ ;;
+ arm64:Darwin:*:*)
+ GUESS=aarch64-apple-darwin$UNAME_RELEASE
+ ;;
*:Darwin:*:*)
UNAME_PROCESSOR=`uname -p`
case $UNAME_PROCESSOR in
unknown) UNAME_PROCESSOR=powerpc ;;
esac
if command -v xcode-select > /dev/null 2> /dev/null && \
! xcode-select --print-path > /dev/null 2> /dev/null ; then
# Avoid executing cc if there is no toolchain installed as
# cc will be a stub that puts up a graphical alert
# prompting the user to install developer tools.
CC_FOR_BUILD=no_compiler_found
else
set_cc_for_build
fi
- if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
+ if test "$CC_FOR_BUILD" != no_compiler_found; then
if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
(CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
grep IS_64BIT_ARCH >/dev/null
then
case $UNAME_PROCESSOR in
i386) UNAME_PROCESSOR=x86_64 ;;
powerpc) UNAME_PROCESSOR=powerpc64 ;;
esac
fi
# On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc
if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \
(CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
grep IS_PPC >/dev/null
then
UNAME_PROCESSOR=powerpc
fi
elif test "$UNAME_PROCESSOR" = i386 ; then
# uname -m returns i386 or x86_64
UNAME_PROCESSOR=$UNAME_MACHINE
fi
- echo "$UNAME_PROCESSOR"-apple-darwin"$UNAME_RELEASE"
- exit ;;
+ GUESS=$UNAME_PROCESSOR-apple-darwin$UNAME_RELEASE
+ ;;
*:procnto*:*:* | *:QNX:[0123456789]*:*)
UNAME_PROCESSOR=`uname -p`
if test "$UNAME_PROCESSOR" = x86; then
UNAME_PROCESSOR=i386
UNAME_MACHINE=pc
fi
- echo "$UNAME_PROCESSOR"-"$UNAME_MACHINE"-nto-qnx"$UNAME_RELEASE"
- exit ;;
+ GUESS=$UNAME_PROCESSOR-$UNAME_MACHINE-nto-qnx$UNAME_RELEASE
+ ;;
*:QNX:*:4*)
- echo i386-pc-qnx
- exit ;;
+ GUESS=i386-pc-qnx
+ ;;
NEO-*:NONSTOP_KERNEL:*:*)
- echo neo-tandem-nsk"$UNAME_RELEASE"
- exit ;;
+ GUESS=neo-tandem-nsk$UNAME_RELEASE
+ ;;
NSE-*:NONSTOP_KERNEL:*:*)
- echo nse-tandem-nsk"$UNAME_RELEASE"
- exit ;;
+ GUESS=nse-tandem-nsk$UNAME_RELEASE
+ ;;
NSR-*:NONSTOP_KERNEL:*:*)
- echo nsr-tandem-nsk"$UNAME_RELEASE"
- exit ;;
+ GUESS=nsr-tandem-nsk$UNAME_RELEASE
+ ;;
NSV-*:NONSTOP_KERNEL:*:*)
- echo nsv-tandem-nsk"$UNAME_RELEASE"
- exit ;;
+ GUESS=nsv-tandem-nsk$UNAME_RELEASE
+ ;;
NSX-*:NONSTOP_KERNEL:*:*)
- echo nsx-tandem-nsk"$UNAME_RELEASE"
- exit ;;
+ GUESS=nsx-tandem-nsk$UNAME_RELEASE
+ ;;
*:NonStop-UX:*:*)
- echo mips-compaq-nonstopux
- exit ;;
+ GUESS=mips-compaq-nonstopux
+ ;;
BS2000:POSIX*:*:*)
- echo bs2000-siemens-sysv
- exit ;;
+ GUESS=bs2000-siemens-sysv
+ ;;
DS/*:UNIX_System_V:*:*)
- echo "$UNAME_MACHINE"-"$UNAME_SYSTEM"-"$UNAME_RELEASE"
- exit ;;
+ GUESS=$UNAME_MACHINE-$UNAME_SYSTEM-$UNAME_RELEASE
+ ;;
*:Plan9:*:*)
# "uname -m" is not consistent, so use $cputype instead. 386
# is converted to i386 for consistency with other x86
# operating systems.
- # shellcheck disable=SC2154
- if test "$cputype" = 386; then
+ if test "${cputype-}" = 386; then
UNAME_MACHINE=i386
- else
- UNAME_MACHINE="$cputype"
+ elif test "x${cputype-}" != x; then
+ UNAME_MACHINE=$cputype
fi
- echo "$UNAME_MACHINE"-unknown-plan9
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-plan9
+ ;;
*:TOPS-10:*:*)
- echo pdp10-unknown-tops10
- exit ;;
+ GUESS=pdp10-unknown-tops10
+ ;;
*:TENEX:*:*)
- echo pdp10-unknown-tenex
- exit ;;
+ GUESS=pdp10-unknown-tenex
+ ;;
KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
- echo pdp10-dec-tops20
- exit ;;
+ GUESS=pdp10-dec-tops20
+ ;;
XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
- echo pdp10-xkl-tops20
- exit ;;
+ GUESS=pdp10-xkl-tops20
+ ;;
*:TOPS-20:*:*)
- echo pdp10-unknown-tops20
- exit ;;
+ GUESS=pdp10-unknown-tops20
+ ;;
*:ITS:*:*)
- echo pdp10-unknown-its
- exit ;;
+ GUESS=pdp10-unknown-its
+ ;;
SEI:*:*:SEIUX)
- echo mips-sei-seiux"$UNAME_RELEASE"
- exit ;;
+ GUESS=mips-sei-seiux$UNAME_RELEASE
+ ;;
*:DragonFly:*:*)
- echo "$UNAME_MACHINE"-unknown-dragonfly"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`"
- exit ;;
+ DRAGONFLY_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`
+ GUESS=$UNAME_MACHINE-unknown-dragonfly$DRAGONFLY_REL
+ ;;
*:*VMS:*:*)
UNAME_MACHINE=`(uname -p) 2>/dev/null`
- case "$UNAME_MACHINE" in
- A*) echo alpha-dec-vms ; exit ;;
- I*) echo ia64-dec-vms ; exit ;;
- V*) echo vax-dec-vms ; exit ;;
+ case $UNAME_MACHINE in
+ A*) GUESS=alpha-dec-vms ;;
+ I*) GUESS=ia64-dec-vms ;;
+ V*) GUESS=vax-dec-vms ;;
esac ;;
*:XENIX:*:SysV)
- echo i386-pc-xenix
- exit ;;
+ GUESS=i386-pc-xenix
+ ;;
i*86:skyos:*:*)
- echo "$UNAME_MACHINE"-pc-skyos"`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'`"
- exit ;;
+ SKYOS_REL=`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'`
+ GUESS=$UNAME_MACHINE-pc-skyos$SKYOS_REL
+ ;;
i*86:rdos:*:*)
- echo "$UNAME_MACHINE"-pc-rdos
- exit ;;
- i*86:AROS:*:*)
- echo "$UNAME_MACHINE"-pc-aros
- exit ;;
+ GUESS=$UNAME_MACHINE-pc-rdos
+ ;;
+ i*86:Fiwix:*:*)
+ GUESS=$UNAME_MACHINE-pc-fiwix
+ ;;
+ *:AROS:*:*)
+ GUESS=$UNAME_MACHINE-unknown-aros
+ ;;
x86_64:VMkernel:*:*)
- echo "$UNAME_MACHINE"-unknown-esx
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-esx
+ ;;
amd64:Isilon\ OneFS:*:*)
- echo x86_64-unknown-onefs
- exit ;;
+ GUESS=x86_64-unknown-onefs
+ ;;
*:Unleashed:*:*)
- echo "$UNAME_MACHINE"-unknown-unleashed"$UNAME_RELEASE"
- exit ;;
+ GUESS=$UNAME_MACHINE-unknown-unleashed$UNAME_RELEASE
+ ;;
esac
+# Do we have a guess based on uname results?
+if test "x$GUESS" != x; then
+ echo "$GUESS"
+ exit
+fi
+
# No uname command or uname output not recognized.
set_cc_for_build
cat > "$dummy.c" <<EOF
#ifdef _SEQUENT_
#include <sys/types.h>
#include <sys/utsname.h>
#endif
#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__)
#if defined (vax) || defined (__vax) || defined (__vax__) || defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__)
#include <signal.h>
#if defined(_SIZE_T_) || defined(SIGLOST)
#include <sys/utsname.h>
#endif
#endif
#endif
main ()
{
#if defined (sony)
#if defined (MIPSEB)
/* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
I don't know.... */
printf ("mips-sony-bsd\n"); exit (0);
#else
#include <sys/param.h>
printf ("m68k-sony-newsos%s\n",
#ifdef NEWSOS4
"4"
#else
""
#endif
); exit (0);
#endif
#endif
#if defined (NeXT)
#if !defined (__ARCHITECTURE__)
#define __ARCHITECTURE__ "m68k"
#endif
int version;
version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
if (version < 4)
printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
else
printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
exit (0);
#endif
#if defined (MULTIMAX) || defined (n16)
#if defined (UMAXV)
printf ("ns32k-encore-sysv\n"); exit (0);
#else
#if defined (CMU)
printf ("ns32k-encore-mach\n"); exit (0);
#else
printf ("ns32k-encore-bsd\n"); exit (0);
#endif
#endif
#endif
#if defined (__386BSD__)
printf ("i386-pc-bsd\n"); exit (0);
#endif
#if defined (sequent)
#if defined (i386)
printf ("i386-sequent-dynix\n"); exit (0);
#endif
#if defined (ns32000)
printf ("ns32k-sequent-dynix\n"); exit (0);
#endif
#endif
#if defined (_SEQUENT_)
struct utsname un;
uname(&un);
if (strncmp(un.version, "V2", 2) == 0) {
printf ("i386-sequent-ptx2\n"); exit (0);
}
if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
printf ("i386-sequent-ptx1\n"); exit (0);
}
printf ("i386-sequent-ptx\n"); exit (0);
#endif
#if defined (vax)
#if !defined (ultrix)
#include <sys/param.h>
#if defined (BSD)
#if BSD == 43
printf ("vax-dec-bsd4.3\n"); exit (0);
#else
#if BSD == 199006
printf ("vax-dec-bsd4.3reno\n"); exit (0);
#else
printf ("vax-dec-bsd\n"); exit (0);
#endif
#endif
#else
printf ("vax-dec-bsd\n"); exit (0);
#endif
#else
#if defined(_SIZE_T_) || defined(SIGLOST)
struct utsname un;
uname (&un);
printf ("vax-dec-ultrix%s\n", un.release); exit (0);
#else
printf ("vax-dec-ultrix\n"); exit (0);
#endif
#endif
#endif
#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__)
#if defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__)
#if defined(_SIZE_T_) || defined(SIGLOST)
struct utsname *un;
uname (&un);
printf ("mips-dec-ultrix%s\n", un.release); exit (0);
#else
printf ("mips-dec-ultrix\n"); exit (0);
#endif
#endif
#endif
#if defined (alliant) && defined (i860)
printf ("i860-alliant-bsd\n"); exit (0);
#endif
exit (1);
}
EOF
-$CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=`$dummy` &&
+$CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=`"$dummy"` &&
{ echo "$SYSTEM_NAME"; exit; }
# Apollos put the system type in the environment.
test -d /usr/apollo && { echo "$ISP-apollo-$SYSTYPE"; exit; }
echo "$0: unable to guess system type" >&2
-case "$UNAME_MACHINE:$UNAME_SYSTEM" in
+case $UNAME_MACHINE:$UNAME_SYSTEM in
mips:Linux | mips64:Linux)
# If we got here on MIPS GNU/Linux, output extra information.
cat >&2 <<EOF
NOTE: MIPS GNU/Linux systems require a C compiler to fully recognize
the system type. Please install a C compiler and try again.
EOF
;;
esac
cat >&2 <<EOF
This script (version $timestamp), has failed to recognize the
operating system you are using. If your script is old, overwrite *all*
copies of config.guess and config.sub with the latest versions from:
- https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
+ https://git.savannah.gnu.org/cgit/config.git/plain/config.guess
and
- https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
+ https://git.savannah.gnu.org/cgit/config.git/plain/config.sub
EOF
-year=`echo $timestamp | sed 's,-.*,,'`
+our_year=`echo $timestamp | sed 's,-.*,,'`
+thisyear=`date +%Y`
# shellcheck disable=SC2003
-if test "`expr "\`date +%Y\`" - "$year"`" -lt 3 ; then
+script_age=`expr "$thisyear" - "$our_year"`
+if test "$script_age" -lt 3 ; then
cat >&2 <<EOF
If $0 has already been updated, send the following data and any
information you think might be pertinent to config-patches@gnu.org to
provide the necessary information to handle your system.
config.guess timestamp = $timestamp
uname -m = `(uname -m) 2>/dev/null || echo unknown`
uname -r = `(uname -r) 2>/dev/null || echo unknown`
uname -s = `(uname -s) 2>/dev/null || echo unknown`
uname -v = `(uname -v) 2>/dev/null || echo unknown`
/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
/bin/uname -X = `(/bin/uname -X) 2>/dev/null`
hostinfo = `(hostinfo) 2>/dev/null`
/bin/universe = `(/bin/universe) 2>/dev/null`
/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null`
/bin/arch = `(/bin/arch) 2>/dev/null`
/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null`
/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
UNAME_MACHINE = "$UNAME_MACHINE"
UNAME_RELEASE = "$UNAME_RELEASE"
UNAME_SYSTEM = "$UNAME_SYSTEM"
UNAME_VERSION = "$UNAME_VERSION"
EOF
fi
exit 1
# Local variables:
# eval: (add-hook 'before-save-hook 'time-stamp)
# time-stamp-start: "timestamp='"
# time-stamp-format: "%:y-%02m-%02d"
# time-stamp-end: "'"
# End:
diff --git a/crypto/openssh/config.h b/crypto/openssh/config.h
index e267ba122719..5c8728058c99 100644
--- a/crypto/openssh/config.h
+++ b/crypto/openssh/config.h
@@ -1,2129 +1,2132 @@
/* config.h. Generated from config.h.in by configure. */
/* config.h.in. Generated from configure.ac by autoheader. */
/* Define if building universal (internal helper macro) */
/* #undef AC_APPLE_UNIVERSAL_BUILD */
/* Define if you have a getaddrinfo that fails for the all-zeros IPv6 address
*/
/* #undef AIX_GETNAMEINFO_HACK */
/* Define if your AIX loginfailed() function takes 4 arguments (AIX >= 5.2) */
/* #undef AIX_LOGINFAILED_4ARG */
/* System only supports IPv4 audit records */
/* #undef AU_IPv4 */
/* Define if your resolver libs need this for getrrsetbyname */
/* #undef BIND_8_COMPAT */
/* The system has incomplete BSM API */
/* #undef BROKEN_BSM_API */
/* broken in chroots on older kernels */
/* #undef BROKEN_CLOSEFROM */
/* Define if cmsg_type is not passed correctly */
/* #undef BROKEN_CMSG_TYPE */
/* getaddrinfo is broken (if present) */
/* #undef BROKEN_GETADDRINFO */
/* getgroups(0,NULL) will return -1 */
/* #undef BROKEN_GETGROUPS */
/* getline is not what we expect */
/* #undef BROKEN_GETLINE */
/* FreeBSD glob does not do what we need */
#define BROKEN_GLOB 1
/* Define if you system's inet_ntoa is busted (e.g. Irix gcc issue) */
/* #undef BROKEN_INET_NTOA */
/* Define if your struct dirent expects you to allocate extra space for d_name
*/
/* #undef BROKEN_ONE_BYTE_DIRENT_D_NAME */
/* System poll(2) implementation is broken */
/* #undef BROKEN_POLL */
/* Can't do comparisons on readv */
/* #undef BROKEN_READV_COMPARISON */
/* NetBSD read function is sometimes redirected, breaking atomicio comparisons
against it */
/* #undef BROKEN_READ_COMPARISON */
/* Needed for NeXT */
/* #undef BROKEN_SAVED_UIDS */
/* Define if your setregid() is broken */
/* #undef BROKEN_SETREGID */
/* Define if your setresgid() is broken */
/* #undef BROKEN_SETRESGID */
/* Define if your setresuid() is broken */
/* #undef BROKEN_SETRESUID */
/* Define if your setreuid() is broken */
/* #undef BROKEN_SETREUID */
/* LynxOS has broken setvbuf() implementation */
/* #undef BROKEN_SETVBUF */
/* QNX shadow support is broken */
/* #undef BROKEN_SHADOW_EXPIRE */
/* Define if your snprintf is busted */
/* #undef BROKEN_SNPRINTF */
/* strndup broken, see APAR IY61211 */
/* #undef BROKEN_STRNDUP */
/* strnlen broken, see APAR IY62551 */
/* #undef BROKEN_STRNLEN */
/* strnvis detected broken */
#define BROKEN_STRNVIS 1
/* tcgetattr with ICANON may hang */
/* #undef BROKEN_TCGETATTR_ICANON */
/* updwtmpx is broken (if present) */
/* #undef BROKEN_UPDWTMPX */
/* Define if you have BSD auth support */
/* #undef BSD_AUTH */
/* Define if you want to specify the path to your lastlog file */
/* #undef CONF_LASTLOG_FILE */
/* Define if you want to specify the path to your utmp file */
/* #undef CONF_UTMP_FILE */
/* Define if you want to specify the path to your wtmpx file */
/* #undef CONF_WTMPX_FILE */
/* Define if you want to specify the path to your wtmp file */
/* #undef CONF_WTMP_FILE */
/* Need to call setpgrp as root */
/* #undef DISABLE_FD_PASSING */
/* Define if you don't want to use lastlog */
#define DISABLE_LASTLOG 1
/* Define if you don't want to use your system's login() call */
/* #undef DISABLE_LOGIN */
/* Define if you don't want to use pututline() etc. to write [uw]tmp */
/* #undef DISABLE_PUTUTLINE */
/* Define if you don't want to use pututxline() etc. to write [uw]tmpx */
/* #undef DISABLE_PUTUTXLINE */
/* Define if you want to disable shadow passwords */
/* #undef DISABLE_SHADOW */
/* Define if you don't want to use utmp */
#define DISABLE_UTMP 1
/* Define if you don't want to use utmpx */
/* #undef DISABLE_UTMPX */
/* Define if you don't want to use wtmp */
#define DISABLE_WTMP 1
/* Define if you don't want to use wtmpx */
#define DISABLE_WTMPX 1
/* Enable for PKCS#11 support */
#define ENABLE_PKCS11 /**/
/* Enable for U2F/FIDO support */
#define ENABLE_SK /**/
/* Enable for built-in U2F/FIDO support */
/* #undef ENABLE_SK_INTERNAL */
/* define if fflush(NULL) does not work */
/* #undef FFLUSH_NULL_BUG */
/* File names may not contain backslash characters */
/* #undef FILESYSTEM_NO_BACKSLASH */
/* fsid_t has member val */
/* #undef FSID_HAS_VAL */
/* fsid_t has member __val */
/* #undef FSID_HAS___VAL */
/* getpgrp takes one arg */
#define GETPGRP_VOID 1
/* Conflicting defs for getspnam */
/* #undef GETSPNAM_CONFLICTING_DEFS */
/* Define if your system glob() function has the GLOB_ALTDIRFUNC extension */
#define GLOB_HAS_ALTDIRFUNC 1
/* Define if your system glob() function has gl_matchc options in glob_t */
#define GLOB_HAS_GL_MATCHC 1
/* Define if your system glob() function has gl_statv options in glob_t */
/* #undef GLOB_HAS_GL_STATV */
/* Define this if you want GSSAPI support in the version 2 protocol */
/* #undef GSSAPI */
/* Define if you want to use shadow password expire field */
/* #undef HAS_SHADOW_EXPIRE */
/* Define if your system uses access rights style file descriptor passing */
/* #undef HAVE_ACCRIGHTS_IN_MSGHDR */
/* Define if you have ut_addr in utmp.h */
/* #undef HAVE_ADDR_IN_UTMP */
/* Define if you have ut_addr in utmpx.h */
/* #undef HAVE_ADDR_IN_UTMPX */
/* Define if you have ut_addr_v6 in utmp.h */
/* #undef HAVE_ADDR_V6_IN_UTMP */
/* Define if you have ut_addr_v6 in utmpx.h */
/* #undef HAVE_ADDR_V6_IN_UTMPX */
/* Define to 1 if you have the `arc4random' function. */
#define HAVE_ARC4RANDOM 1
/* Define to 1 if you have the `arc4random_buf' function. */
#define HAVE_ARC4RANDOM_BUF 1
/* Define to 1 if you have the `arc4random_stir' function. */
/* #undef HAVE_ARC4RANDOM_STIR */
/* Define to 1 if you have the `arc4random_uniform' function. */
#define HAVE_ARC4RANDOM_UNIFORM 1
/* Define to 1 if you have the `asprintf' function. */
#define HAVE_ASPRINTF 1
/* OpenBSD's gcc has bounded */
/* #undef HAVE_ATTRIBUTE__BOUNDED__ */
/* Have attribute nonnull */
#define HAVE_ATTRIBUTE__NONNULL__ 1
/* OpenBSD's gcc has sentinel */
/* #undef HAVE_ATTRIBUTE__SENTINEL__ */
/* Define to 1 if you have the `aug_get_machine' function. */
/* #undef HAVE_AUG_GET_MACHINE */
/* Define to 1 if you have the `auth_hostok' function. */
#define HAVE_AUTH_HOSTOK 1
/* Define to 1 if you have the `auth_timeok' function. */
#define HAVE_AUTH_TIMEOK 1
/* Define to 1 if you have the `b64_ntop' function. */
/* #undef HAVE_B64_NTOP */
/* Define to 1 if you have the `b64_pton' function. */
/* #undef HAVE_B64_PTON */
/* Define if you have the basename function. */
#define HAVE_BASENAME 1
/* Define to 1 if you have the `bcopy' function. */
#define HAVE_BCOPY 1
/* Define to 1 if you have the `bcrypt_pbkdf' function. */
/* #undef HAVE_BCRYPT_PBKDF */
/* Define to 1 if you have the `bindresvport_sa' function. */
#define HAVE_BINDRESVPORT_SA 1
/* Define to 1 if you have the `blf_enc' function. */
/* #undef HAVE_BLF_ENC */
/* Define to 1 if you have the <blf.h> header file. */
/* #undef HAVE_BLF_H */
/* Define to 1 if you have the `Blowfish_expand0state' function. */
/* #undef HAVE_BLOWFISH_EXPAND0STATE */
/* Define to 1 if you have the `Blowfish_expandstate' function. */
/* #undef HAVE_BLOWFISH_EXPANDSTATE */
/* Define to 1 if you have the `Blowfish_initstate' function. */
/* #undef HAVE_BLOWFISH_INITSTATE */
/* Define to 1 if you have the `Blowfish_stream2word' function. */
/* #undef HAVE_BLOWFISH_STREAM2WORD */
/* Define to 1 if you have the `BN_is_prime_ex' function. */
#define HAVE_BN_IS_PRIME_EX 1
/* Define to 1 if you have the <bsd/libutil.h> header file. */
/* #undef HAVE_BSD_LIBUTIL_H */
/* Define to 1 if you have the <bsm/audit.h> header file. */
/* #undef HAVE_BSM_AUDIT_H */
/* Define to 1 if you have the <bstring.h> header file. */
/* #undef HAVE_BSTRING_H */
/* Define to 1 if you have the `bzero' function. */
#define HAVE_BZERO 1
/* calloc(0, x) returns NULL */
#define HAVE_CALLOC 1
/* Define if you have caph_cache_tzdata */
#define HAVE_CAPH_CACHE_TZDATA 1
/* Define to 1 if you have the <capsicum_helpers.h> header file. */
#define HAVE_CAPSICUM_HELPERS_H 1
/* Define to 1 if you have the `cap_rights_limit' function. */
#define HAVE_CAP_RIGHTS_LIMIT 1
/* Define to 1 if you have the `clock' function. */
#define HAVE_CLOCK 1
/* Have clock_gettime */
#define HAVE_CLOCK_GETTIME 1
/* define if you have clock_t data type */
#define HAVE_CLOCK_T 1
/* Define to 1 if you have the `closefrom' function. */
#define HAVE_CLOSEFROM 1
/* Define to 1 if you have the `close_range' function. */
#define HAVE_CLOSE_RANGE 1
/* Define if gai_strerror() returns const char * */
#define HAVE_CONST_GAI_STRERROR_PROTO 1
/* Define if your system uses ancillary data style file descriptor passing */
#define HAVE_CONTROL_IN_MSGHDR 1
/* Define to 1 if you have the `crypt' function. */
#define HAVE_CRYPT 1
/* Define to 1 if you have the <crypto/sha2.h> header file. */
/* #undef HAVE_CRYPTO_SHA2_H */
/* Define to 1 if you have the <crypt.h> header file. */
/* #undef HAVE_CRYPT_H */
/* Define if you are on Cygwin */
/* #undef HAVE_CYGWIN */
/* Define if your libraries define daemon() */
#define HAVE_DAEMON 1
/* Define to 1 if you have the declaration of `AI_NUMERICSERV', and to 0 if
you don't. */
#define HAVE_DECL_AI_NUMERICSERV 1
/* Define to 1 if you have the declaration of `authenticate', and to 0 if you
don't. */
/* #undef HAVE_DECL_AUTHENTICATE */
/* Define to 1 if you have the declaration of `bzero', and to 0 if you don't.
*/
#define HAVE_DECL_BZERO 1
/* Define to 1 if you have the declaration of `ftruncate', and to 0 if you
don't. */
#define HAVE_DECL_FTRUNCATE 1
/* Define to 1 if you have the declaration of `getentropy', and to 0 if you
don't. */
#define HAVE_DECL_GETENTROPY 1
/* Define to 1 if you have the declaration of `getpeereid', and to 0 if you
don't. */
#define HAVE_DECL_GETPEEREID 1
/* Define to 1 if you have the declaration of `GLOB_NOMATCH', and to 0 if you
don't. */
#define HAVE_DECL_GLOB_NOMATCH 1
/* Define to 1 if you have the declaration of `GSS_C_NT_HOSTBASED_SERVICE',
and to 0 if you don't. */
/* #undef HAVE_DECL_GSS_C_NT_HOSTBASED_SERVICE */
/* Define to 1 if you have the declaration of `howmany', and to 0 if you
don't. */
#define HAVE_DECL_HOWMANY 1
/* Define to 1 if you have the declaration of `h_errno', and to 0 if you
don't. */
#define HAVE_DECL_H_ERRNO 1
/* Define to 1 if you have the declaration of `loginfailed', and to 0 if you
don't. */
/* #undef HAVE_DECL_LOGINFAILED */
/* Define to 1 if you have the declaration of `loginrestrictions', and to 0 if
you don't. */
/* #undef HAVE_DECL_LOGINRESTRICTIONS */
/* Define to 1 if you have the declaration of `loginsuccess', and to 0 if you
don't. */
/* #undef HAVE_DECL_LOGINSUCCESS */
/* Define to 1 if you have the declaration of `MAXSYMLINKS', and to 0 if you
don't. */
#define HAVE_DECL_MAXSYMLINKS 1
/* Define to 1 if you have the declaration of `memmem', and to 0 if you don't.
*/
#define HAVE_DECL_MEMMEM 1
/* Define to 1 if you have the declaration of `NFDBITS', and to 0 if you
don't. */
#define HAVE_DECL_NFDBITS 1
/* Define to 1 if you have the declaration of `offsetof', and to 0 if you
don't. */
#define HAVE_DECL_OFFSETOF 1
/* Define to 1 if you have the declaration of `O_NONBLOCK', and to 0 if you
don't. */
#define HAVE_DECL_O_NONBLOCK 1
/* Define to 1 if you have the declaration of `passwdexpired', and to 0 if you
don't. */
/* #undef HAVE_DECL_PASSWDEXPIRED */
/* Define to 1 if you have the declaration of `readv', and to 0 if you don't.
*/
#define HAVE_DECL_READV 1
/* Define to 1 if you have the declaration of `setauthdb', and to 0 if you
don't. */
/* #undef HAVE_DECL_SETAUTHDB */
/* Define to 1 if you have the declaration of `SHUT_RD', and to 0 if you
don't. */
#define HAVE_DECL_SHUT_RD 1
/* Define to 1 if you have the declaration of `UINT32_MAX', and to 0 if you
don't. */
#define HAVE_DECL_UINT32_MAX 1
/* Define to 1 if you have the declaration of `writev', and to 0 if you don't.
*/
#define HAVE_DECL_WRITEV 1
/* Define to 1 if you have the declaration of `_getlong', and to 0 if you
don't. */
#define HAVE_DECL__GETLONG 0
/* Define to 1 if you have the declaration of `_getshort', and to 0 if you
don't. */
#define HAVE_DECL__GETSHORT 0
/* Define to 1 if you have the `DES_crypt' function. */
#define HAVE_DES_CRYPT 1
/* Define if you have /dev/ptmx */
/* #undef HAVE_DEV_PTMX */
/* Define if you have /dev/ptc */
/* #undef HAVE_DEV_PTS_AND_PTC */
/* Define to 1 if you have the `DH_get0_key' function. */
#define HAVE_DH_GET0_KEY 1
/* Define to 1 if you have the `DH_get0_pqg' function. */
#define HAVE_DH_GET0_PQG 1
/* Define to 1 if you have the `DH_set0_key' function. */
#define HAVE_DH_SET0_KEY 1
/* Define to 1 if you have the `DH_set0_pqg' function. */
#define HAVE_DH_SET0_PQG 1
/* Define to 1 if you have the `DH_set_length' function. */
#define HAVE_DH_SET_LENGTH 1
/* Define to 1 if you have the <dirent.h> header file. */
#define HAVE_DIRENT_H 1
/* Define to 1 if you have the `dirfd' function. */
#define HAVE_DIRFD 1
/* Define to 1 if you have the `dirname' function. */
#define HAVE_DIRNAME 1
/* Define to 1 if you have the `dlopen' function. */
#define HAVE_DLOPEN 1
/* Define to 1 if you have the `DSA_generate_parameters_ex' function. */
#define HAVE_DSA_GENERATE_PARAMETERS_EX 1
/* Define to 1 if you have the `DSA_get0_key' function. */
#define HAVE_DSA_GET0_KEY 1
/* Define to 1 if you have the `DSA_get0_pqg' function. */
#define HAVE_DSA_GET0_PQG 1
/* Define to 1 if you have the `DSA_set0_key' function. */
#define HAVE_DSA_SET0_KEY 1
/* Define to 1 if you have the `DSA_set0_pqg' function. */
#define HAVE_DSA_SET0_PQG 1
/* Define to 1 if you have the `DSA_SIG_get0' function. */
#define HAVE_DSA_SIG_GET0 1
/* Define to 1 if you have the `DSA_SIG_set0' function. */
#define HAVE_DSA_SIG_SET0 1
/* Define to 1 if you have the `ECDSA_SIG_get0' function. */
#define HAVE_ECDSA_SIG_GET0 1
/* Define to 1 if you have the `ECDSA_SIG_set0' function. */
#define HAVE_ECDSA_SIG_SET0 1
/* Define to 1 if you have the `EC_KEY_METHOD_new' function. */
#define HAVE_EC_KEY_METHOD_NEW 1
/* Define to 1 if you have the <elf.h> header file. */
#define HAVE_ELF_H 1
/* Define to 1 if you have the `endgrent' function. */
#define HAVE_ENDGRENT 1
/* Define to 1 if you have the <endian.h> header file. */
/* #undef HAVE_ENDIAN_H */
/* Define to 1 if you have the `endutent' function. */
/* #undef HAVE_ENDUTENT */
/* Define to 1 if you have the `endutxent' function. */
#define HAVE_ENDUTXENT 1
/* Define to 1 if you have the `err' function. */
#define HAVE_ERR 1
/* Define to 1 if you have the `errx' function. */
#define HAVE_ERRX 1
/* Define to 1 if you have the <err.h> header file. */
#define HAVE_ERR_H 1
/* Define if your system has /etc/default/login */
/* #undef HAVE_ETC_DEFAULT_LOGIN */
/* Define to 1 if you have the `EVP_chacha20' function. */
#define HAVE_EVP_CHACHA20 1
/* Define to 1 if you have the `EVP_CIPHER_CTX_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. */
#define HAVE_EVP_CIPHER_CTX_IV 1
/* Define to 1 if you have the `EVP_CIPHER_CTX_iv_noconst' function. */
#define HAVE_EVP_CIPHER_CTX_IV_NOCONST 1
/* Define to 1 if you have the `EVP_CIPHER_CTX_set_iv' function. */
/* #undef HAVE_EVP_CIPHER_CTX_SET_IV */
/* Define to 1 if you have the `EVP_DigestFinal_ex' function. */
#define HAVE_EVP_DIGESTFINAL_EX 1
/* Define to 1 if you have the `EVP_DigestInit_ex' function. */
#define HAVE_EVP_DIGESTINIT_EX 1
/* Define to 1 if you have the `EVP_MD_CTX_cleanup' function. */
/* #undef HAVE_EVP_MD_CTX_CLEANUP */
/* Define to 1 if you have the `EVP_MD_CTX_copy_ex' function. */
#define HAVE_EVP_MD_CTX_COPY_EX 1
/* Define to 1 if you have the `EVP_MD_CTX_free' function. */
#define HAVE_EVP_MD_CTX_FREE 1
/* Define to 1 if you have the `EVP_MD_CTX_init' function. */
/* #undef HAVE_EVP_MD_CTX_INIT */
/* Define to 1 if you have the `EVP_MD_CTX_new' function. */
#define HAVE_EVP_MD_CTX_NEW 1
/* Define to 1 if you have the `EVP_PKEY_get0_RSA' function. */
#define HAVE_EVP_PKEY_GET0_RSA 1
/* Define to 1 if you have the `EVP_sha256' function. */
#define HAVE_EVP_SHA256 1
/* Define to 1 if you have the `EVP_sha384' function. */
#define HAVE_EVP_SHA384 1
/* Define to 1 if you have the `EVP_sha512' function. */
#define HAVE_EVP_SHA512 1
/* Define if you have ut_exit in utmp.h */
/* #undef HAVE_EXIT_IN_UTMP */
/* Define to 1 if you have the `explicit_bzero' function. */
#define HAVE_EXPLICIT_BZERO 1
/* Define to 1 if you have the `explicit_memset' function. */
/* #undef HAVE_EXPLICIT_MEMSET */
/* Define to 1 if you have the `fchmod' function. */
#define HAVE_FCHMOD 1
/* Define to 1 if you have the `fchmodat' function. */
#define HAVE_FCHMODAT 1
/* Define to 1 if you have the `fchown' function. */
#define HAVE_FCHOWN 1
/* Define to 1 if you have the `fchownat' function. */
#define HAVE_FCHOWNAT 1
/* Use F_CLOSEM fcntl for closefrom */
/* #undef HAVE_FCNTL_CLOSEM */
/* Define to 1 if you have the <fcntl.h> header file. */
#define HAVE_FCNTL_H 1
/* Define to 1 if the system has the type `fd_mask'. */
#define HAVE_FD_MASK 1
/* Define to 1 if you have the <features.h> header file. */
/* #undef HAVE_FEATURES_H */
/* Define to 1 if you have the `fido_assert_set_clientdata' function. */
/* #undef HAVE_FIDO_ASSERT_SET_CLIENTDATA */
/* Define to 1 if you have the `fido_cred_prot' function. */
/* #undef HAVE_FIDO_CRED_PROT */
/* Define to 1 if you have the `fido_cred_set_clientdata' function. */
/* #undef HAVE_FIDO_CRED_SET_CLIENTDATA */
/* Define to 1 if you have the `fido_cred_set_prot' function. */
/* #undef HAVE_FIDO_CRED_SET_PROT */
/* Define to 1 if you have the `fido_dev_get_touch_begin' function. */
/* #undef HAVE_FIDO_DEV_GET_TOUCH_BEGIN */
/* Define to 1 if you have the `fido_dev_get_touch_status' function. */
/* #undef HAVE_FIDO_DEV_GET_TOUCH_STATUS */
/* Define to 1 if you have the `fido_dev_is_winhello' function. */
/* #undef HAVE_FIDO_DEV_IS_WINHELLO */
/* Define to 1 if you have the `fido_dev_supports_cred_prot' function. */
/* #undef HAVE_FIDO_DEV_SUPPORTS_CRED_PROT */
/* Define to 1 if you have the <floatingpoint.h> header file. */
#define HAVE_FLOATINGPOINT_H 1
/* Define to 1 if you have the `flock' function. */
#define HAVE_FLOCK 1
/* Define to 1 if you have the `fmt_scaled' function. */
/* #undef HAVE_FMT_SCALED */
/* Define to 1 if you have the `fnmatch' function. */
#define HAVE_FNMATCH 1
/* Define to 1 if you have the <fnmatch.h> header file. */
#define HAVE_FNMATCH_H 1
/* Define to 1 if you have the `freeaddrinfo' function. */
#define HAVE_FREEADDRINFO 1
/* Define to 1 if you have the `freezero' function. */
/* #undef HAVE_FREEZERO */
/* Define to 1 if the system has the type `fsblkcnt_t'. */
#define HAVE_FSBLKCNT_T 1
/* Define to 1 if the system has the type `fsfilcnt_t'. */
#define HAVE_FSFILCNT_T 1
/* Define to 1 if you have the `fstatfs' function. */
#define HAVE_FSTATFS 1
/* Define to 1 if you have the `fstatvfs' function. */
#define HAVE_FSTATVFS 1
/* Define to 1 if you have the `futimes' function. */
#define HAVE_FUTIMES 1
/* Define to 1 if you have the `gai_strerror' function. */
#define HAVE_GAI_STRERROR 1
/* Define to 1 if you have the `getaddrinfo' function. */
#define HAVE_GETADDRINFO 1
/* Define to 1 if you have the `getaudit' function. */
/* #undef HAVE_GETAUDIT */
/* Define to 1 if you have the `getaudit_addr' function. */
/* #undef HAVE_GETAUDIT_ADDR */
/* Define to 1 if you have the `getcwd' function. */
#define HAVE_GETCWD 1
/* Define to 1 if you have the `getentropy' function. */
#define HAVE_GETENTROPY 1
/* Define to 1 if you have the `getgrouplist' function. */
#define HAVE_GETGROUPLIST 1
/* Define to 1 if you have the `getgrset' function. */
/* #undef HAVE_GETGRSET */
/* Define to 1 if you have the `getlastlogxbyname' function. */
/* #undef HAVE_GETLASTLOGXBYNAME */
/* Define to 1 if you have the `getline' function. */
#define HAVE_GETLINE 1
/* Define to 1 if you have the `getluid' function. */
/* #undef HAVE_GETLUID */
/* Define to 1 if you have the `getnameinfo' function. */
#define HAVE_GETNAMEINFO 1
/* Define to 1 if you have the `getopt' function. */
#define HAVE_GETOPT 1
/* Define to 1 if you have the <getopt.h> header file. */
#define HAVE_GETOPT_H 1
/* Define if your getopt(3) defines and uses optreset */
#define HAVE_GETOPT_OPTRESET 1
/* Define if your libraries define getpagesize() */
#define HAVE_GETPAGESIZE 1
/* Define to 1 if you have the `getpeereid' function. */
#define HAVE_GETPEEREID 1
/* Define to 1 if you have the `getpeerucred' function. */
/* #undef HAVE_GETPEERUCRED */
/* Define to 1 if you have the `getpgid' function. */
#define HAVE_GETPGID 1
/* Define to 1 if you have the `getpgrp' function. */
#define HAVE_GETPGRP 1
/* Define to 1 if you have the `getpwanam' function. */
/* #undef HAVE_GETPWANAM */
/* Define to 1 if you have the `getrandom' function. */
#define HAVE_GETRANDOM 1
/* Define to 1 if you have the `getrlimit' function. */
#define HAVE_GETRLIMIT 1
/* Define if getrrsetbyname() exists */
/* #undef HAVE_GETRRSETBYNAME */
/* Define to 1 if you have the `getseuserbyname' function. */
/* #undef HAVE_GETSEUSERBYNAME */
/* Define to 1 if you have the `getsid' function. */
#define HAVE_GETSID 1
/* Define to 1 if you have the `gettimeofday' function. */
#define HAVE_GETTIMEOFDAY 1
/* Define to 1 if you have the `getttyent' function. */
#define HAVE_GETTTYENT 1
/* Define to 1 if you have the `getutent' function. */
/* #undef HAVE_GETUTENT */
/* Define to 1 if you have the `getutid' function. */
/* #undef HAVE_GETUTID */
/* Define to 1 if you have the `getutline' function. */
/* #undef HAVE_GETUTLINE */
/* Define to 1 if you have the `getutxent' function. */
#define HAVE_GETUTXENT 1
/* Define to 1 if you have the `getutxid' function. */
#define HAVE_GETUTXID 1
/* Define to 1 if you have the `getutxline' function. */
#define HAVE_GETUTXLINE 1
/* Define to 1 if you have the `getutxuser' function. */
#define HAVE_GETUTXUSER 1
/* Define to 1 if you have the `get_default_context_with_level' function. */
/* #undef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL */
/* Define to 1 if you have the `glob' function. */
#define HAVE_GLOB 1
/* Define to 1 if you have the <glob.h> header file. */
#define HAVE_GLOB_H 1
/* Define to 1 if you have the `group_from_gid' function. */
#define HAVE_GROUP_FROM_GID 1
/* Define to 1 if you have the <gssapi_generic.h> header file. */
/* #undef HAVE_GSSAPI_GENERIC_H */
/* Define to 1 if you have the <gssapi/gssapi_generic.h> header file. */
/* #undef HAVE_GSSAPI_GSSAPI_GENERIC_H */
/* Define to 1 if you have the <gssapi/gssapi.h> header file. */
/* #undef HAVE_GSSAPI_GSSAPI_H */
/* Define to 1 if you have the <gssapi/gssapi_krb5.h> header file. */
/* #undef HAVE_GSSAPI_GSSAPI_KRB5_H */
/* Define to 1 if you have the <gssapi.h> header file. */
/* #undef HAVE_GSSAPI_H */
/* Define to 1 if you have the <gssapi_krb5.h> header file. */
/* #undef HAVE_GSSAPI_KRB5_H */
/* Define if HEADER.ad exists in arpa/nameser.h */
#define HAVE_HEADER_AD 1
/* Define to 1 if you have the `HMAC_CTX_init' function. */
/* #undef HAVE_HMAC_CTX_INIT */
/* Define if you have ut_host in utmp.h */
/* #undef HAVE_HOST_IN_UTMP */
/* Define if you have ut_host in utmpx.h */
#define HAVE_HOST_IN_UTMPX 1
/* Define to 1 if you have the <iaf.h> header file. */
/* #undef HAVE_IAF_H */
/* Define to 1 if you have the <ia.h> header file. */
/* #undef HAVE_IA_H */
/* Define if you have ut_id in utmp.h */
/* #undef HAVE_ID_IN_UTMP */
/* Define if you have ut_id in utmpx.h */
#define HAVE_ID_IN_UTMPX 1
/* Define to 1 if you have the <ifaddrs.h> header file. */
#define HAVE_IFADDRS_H 1
/* Define to 1 if you have the `inet_aton' function. */
#define HAVE_INET_ATON 1
/* Define to 1 if you have the `inet_ntoa' function. */
#define HAVE_INET_NTOA 1
/* Define to 1 if you have the `inet_ntop' function. */
#define HAVE_INET_NTOP 1
/* Define to 1 if you have the `innetgr' function. */
#define HAVE_INNETGR 1
/* define if you have int64_t data type */
#define HAVE_INT64_T 1
/* Define to 1 if the system has the type `intmax_t'. */
#define HAVE_INTMAX_T 1
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* define if you have intxx_t data type */
#define HAVE_INTXX_T 1
/* Define to 1 if the system has the type `in_addr_t'. */
#define HAVE_IN_ADDR_T 1
/* Define to 1 if the system has the type `in_port_t'. */
#define HAVE_IN_PORT_T 1
/* Define if you have isblank(3C). */
#define HAVE_ISBLANK 1
/* Define to 1 if you have the `killpg' function. */
#define HAVE_KILLPG 1
/* Define to 1 if you have the `krb5_cc_new_unique' function. */
/* #undef HAVE_KRB5_CC_NEW_UNIQUE */
/* Define to 1 if you have the `krb5_free_error_message' function. */
/* #undef HAVE_KRB5_FREE_ERROR_MESSAGE */
/* Define to 1 if you have the `krb5_get_error_message' function. */
/* #undef HAVE_KRB5_GET_ERROR_MESSAGE */
/* Define to 1 if you have the <langinfo.h> header file. */
#define HAVE_LANGINFO_H 1
/* Define to 1 if you have the <lastlog.h> header file. */
/* #undef HAVE_LASTLOG_H */
/* Define if you want ldns support */
/* #undef HAVE_LDNS */
/* Define to 1 if you have the <libaudit.h> header file. */
/* #undef HAVE_LIBAUDIT_H */
/* Define to 1 if you have the `bsm' library (-lbsm). */
/* #undef HAVE_LIBBSM */
/* Define to 1 if you have the `dl' library (-ldl). */
#define HAVE_LIBDL 1
/* Define to 1 if you have the <libgen.h> header file. */
#define HAVE_LIBGEN_H 1
/* Define if system has libiaf that supports set_id */
/* #undef HAVE_LIBIAF */
/* Define to 1 if you have the `network' library (-lnetwork). */
/* #undef HAVE_LIBNETWORK */
/* Define to 1 if you have the `pam' library (-lpam). */
#define HAVE_LIBPAM 1
/* Define to 1 if you have the <libproc.h> header file. */
/* #undef HAVE_LIBPROC_H */
/* Define to 1 if you have the `socket' library (-lsocket). */
/* #undef HAVE_LIBSOCKET */
/* Define to 1 if you have the <libutil.h> header file. */
#define HAVE_LIBUTIL_H 1
/* Define to 1 if you have the `xnet' library (-lxnet). */
/* #undef HAVE_LIBXNET */
/* Define to 1 if you have the `z' library (-lz). */
#define HAVE_LIBZ 1
/* Define to 1 if you have the <limits.h> header file. */
#define HAVE_LIMITS_H 1
/* Define to 1 if you have the <linux/audit.h> header file. */
/* #undef HAVE_LINUX_AUDIT_H */
/* Define to 1 if you have the <linux/filter.h> header file. */
/* #undef HAVE_LINUX_FILTER_H */
/* Define to 1 if you have the <linux/if_tun.h> header file. */
/* #undef HAVE_LINUX_IF_TUN_H */
/* Define to 1 if you have the <linux/seccomp.h> header file. */
/* #undef HAVE_LINUX_SECCOMP_H */
/* Define to 1 if you have the `llabs' function. */
#define HAVE_LLABS 1
/* Define to 1 if you have the <locale.h> header file. */
#define HAVE_LOCALE_H 1
/* Define to 1 if you have the `localtime_r' function. */
#define HAVE_LOCALTIME_R 1
/* Define to 1 if you have the `login' function. */
/* #undef HAVE_LOGIN */
/* Define to 1 if you have the <login_cap.h> header file. */
#define HAVE_LOGIN_CAP_H 1
/* Define to 1 if you have the `login_getcapbool' function. */
#define HAVE_LOGIN_GETCAPBOOL 1
/* Define to 1 if you have the `login_getpwclass' function. */
#define HAVE_LOGIN_GETPWCLASS 1
/* Define to 1 if you have the <login.h> header file. */
/* #undef HAVE_LOGIN_H */
/* Define to 1 if you have the `logout' function. */
/* #undef HAVE_LOGOUT */
/* Define to 1 if you have the `logwtmp' function. */
/* #undef HAVE_LOGWTMP */
/* Define to 1 if the system has the type `long double'. */
#define HAVE_LONG_DOUBLE 1
/* Define to 1 if the system has the type `long long'. */
#define HAVE_LONG_LONG 1
/* Define to 1 if you have the <maillock.h> header file. */
/* #undef HAVE_MAILLOCK_H */
/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
to 0 otherwise. */
#define HAVE_MALLOC 1
/* Define to 1 if you have the `mblen' function. */
#define HAVE_MBLEN 1
/* Define to 1 if you have the `mbtowc' function. */
#define HAVE_MBTOWC 1
/* Define to 1 if you have the `memmem' function. */
#define HAVE_MEMMEM 1
/* Define to 1 if you have the `memmove' function. */
#define HAVE_MEMMOVE 1
/* Define to 1 if you have the `memset_s' function. */
#define HAVE_MEMSET_S 1
/* Define to 1 if you have the `mkdtemp' function. */
#define HAVE_MKDTEMP 1
/* define if you have mode_t data type */
#define HAVE_MODE_T 1
/* Some systems put nanosleep outside of libc */
#define HAVE_NANOSLEEP 1
/* Define to 1 if you have the <ndir.h> header file. */
/* #undef HAVE_NDIR_H */
/* Define to 1 if you have the <netdb.h> header file. */
#define HAVE_NETDB_H 1
/* Define to 1 if you have the <netgroup.h> header file. */
/* #undef HAVE_NETGROUP_H */
/* Define to 1 if you have the <net/if_tun.h> header file. */
#define HAVE_NET_IF_TUN_H 1
/* Define to 1 if you have the <net/route.h> header file. */
#define HAVE_NET_ROUTE_H 1
/* Define if you are on NeXT */
/* #undef HAVE_NEXT */
/* Define to 1 if the system has the type `nfds_t'. */
#define HAVE_NFDS_T 1
/* Define to 1 if you have the `ngetaddrinfo' function. */
/* #undef HAVE_NGETADDRINFO */
/* Define to 1 if you have the `nl_langinfo' function. */
#define HAVE_NL_LANGINFO 1
/* Define to 1 if you have the `nsleep' function. */
/* #undef HAVE_NSLEEP */
/* Define to 1 if you have the `ogetaddrinfo' function. */
/* #undef HAVE_OGETADDRINFO */
/* Define if you have an old version of PAM which takes only one argument to
pam_strerror */
/* #undef HAVE_OLD_PAM */
/* Define to 1 if you have the `openlog_r' function. */
/* #undef HAVE_OPENLOG_R */
/* Define to 1 if you have the `openpty' function. */
#define HAVE_OPENPTY 1
/* as a macro */
#define HAVE_OPENSSL_ADD_ALL_ALGORITHMS 1
/* Define to 1 if you have the `OPENSSL_init_crypto' function. */
#define HAVE_OPENSSL_INIT_CRYPTO 1
/* Define to 1 if you have the `OpenSSL_version' function. */
#define HAVE_OPENSSL_VERSION 1
/* Define to 1 if you have the `OpenSSL_version_num' function. */
#define HAVE_OPENSSL_VERSION_NUM 1
/* Define if you have Digital Unix Security Integration Architecture */
/* #undef HAVE_OSF_SIA */
/* Define to 1 if you have the `pam_getenvlist' function. */
#define HAVE_PAM_GETENVLIST 1
/* Define to 1 if you have the <pam/pam_appl.h> header file. */
/* #undef HAVE_PAM_PAM_APPL_H */
/* Define to 1 if you have the `pam_putenv' function. */
#define HAVE_PAM_PUTENV 1
/* Define to 1 if you have the <paths.h> header file. */
#define HAVE_PATHS_H 1
/* Define if you have ut_pid in utmp.h */
/* #undef HAVE_PID_IN_UTMP */
/* define if you have pid_t data type */
#define HAVE_PID_T 1
/* Define to 1 if you have the `pledge' function. */
/* #undef HAVE_PLEDGE */
/* Define to 1 if you have the `poll' function. */
#define HAVE_POLL 1
/* Define to 1 if you have the <poll.h> header file. */
#define HAVE_POLL_H 1
/* Define to 1 if you have the `ppoll' function. */
#define HAVE_PPOLL 1
/* Define to 1 if you have the `prctl' function. */
/* #undef HAVE_PRCTL */
/* Define to 1 if you have the `priv_basicset' function. */
/* #undef HAVE_PRIV_BASICSET */
/* Define to 1 if you have the <priv.h> header file. */
/* #undef HAVE_PRIV_H */
/* Define to 1 if you have the `procctl' function. */
#define HAVE_PROCCTL 1
/* Define if you have /proc/$pid/fd */
/* #undef HAVE_PROC_PID */
/* Define to 1 if you have the `proc_pidinfo' function. */
/* #undef HAVE_PROC_PIDINFO */
/* Define to 1 if you have the `pselect' function. */
#define HAVE_PSELECT 1
/* Define to 1 if you have the `pstat' function. */
/* #undef HAVE_PSTAT */
/* Define to 1 if you have the <pty.h> header file. */
/* #undef HAVE_PTY_H */
/* Define to 1 if you have the `pututline' function. */
/* #undef HAVE_PUTUTLINE */
/* Define to 1 if you have the `pututxline' function. */
#define HAVE_PUTUTXLINE 1
/* Define to 1 if you have the `raise' function. */
#define HAVE_RAISE 1
/* Define to 1 if you have the `readpassphrase' function. */
#define HAVE_READPASSPHRASE 1
/* Define to 1 if you have the <readpassphrase.h> header file. */
#define HAVE_READPASSPHRASE_H 1
/* Define to 1 if your system has a GNU libc compatible `realloc' function,
and to 0 otherwise. */
#define HAVE_REALLOC 1
/* Define to 1 if you have the `reallocarray' function. */
#define HAVE_REALLOCARRAY 1
/* Define to 1 if you have the `realpath' function. */
#define HAVE_REALPATH 1
/* Define to 1 if you have the `recallocarray' function. */
/* #undef HAVE_RECALLOCARRAY */
/* Define to 1 if you have the `recvmsg' function. */
#define HAVE_RECVMSG 1
/* sys/resource.h has RLIMIT_NPROC */
#define HAVE_RLIMIT_NPROC /**/
/* Define to 1 if you have the <rpc/types.h> header file. */
#define HAVE_RPC_TYPES_H 1
/* Define to 1 if you have the `rresvport_af' function. */
#define HAVE_RRESVPORT_AF 1
/* Define to 1 if you have the `RSA_generate_key_ex' function. */
#define HAVE_RSA_GENERATE_KEY_EX 1
/* Define to 1 if you have the `RSA_get0_crt_params' function. */
#define HAVE_RSA_GET0_CRT_PARAMS 1
/* Define to 1 if you have the `RSA_get0_factors' function. */
#define HAVE_RSA_GET0_FACTORS 1
/* Define to 1 if you have the `RSA_get0_key' function. */
#define HAVE_RSA_GET0_KEY 1
/* Define to 1 if you have the `RSA_get_default_method' function. */
#define HAVE_RSA_GET_DEFAULT_METHOD 1
/* Define to 1 if you have the `RSA_meth_dup' function. */
#define HAVE_RSA_METH_DUP 1
/* Define to 1 if you have the `RSA_meth_free' function. */
#define HAVE_RSA_METH_FREE 1
/* Define to 1 if you have the `RSA_meth_get_finish' function. */
#define HAVE_RSA_METH_GET_FINISH 1
/* Define to 1 if you have the `RSA_meth_set1_name' function. */
#define HAVE_RSA_METH_SET1_NAME 1
/* Define to 1 if you have the `RSA_meth_set_finish' function. */
#define HAVE_RSA_METH_SET_FINISH 1
/* Define to 1 if you have the `RSA_meth_set_priv_dec' function. */
#define HAVE_RSA_METH_SET_PRIV_DEC 1
/* Define to 1 if you have the `RSA_meth_set_priv_enc' function. */
#define HAVE_RSA_METH_SET_PRIV_ENC 1
/* Define to 1 if you have the `RSA_set0_crt_params' function. */
#define HAVE_RSA_SET0_CRT_PARAMS 1
/* Define to 1 if you have the `RSA_set0_factors' function. */
#define HAVE_RSA_SET0_FACTORS 1
/* Define to 1 if you have the `RSA_set0_key' function. */
#define HAVE_RSA_SET0_KEY 1
/* Define to 1 if you have the <sandbox.h> header file. */
/* #undef HAVE_SANDBOX_H */
/* Define to 1 if you have the `sandbox_init' function. */
/* #undef HAVE_SANDBOX_INIT */
/* define if you have sa_family_t data type */
#define HAVE_SA_FAMILY_T 1
/* Define to 1 if you have the `scan_scaled' function. */
/* #undef HAVE_SCAN_SCALED */
/* Define if you have SecureWare-based protected password database */
/* #undef HAVE_SECUREWARE */
/* Define to 1 if you have the <security/pam_appl.h> header file. */
#define HAVE_SECURITY_PAM_APPL_H 1
/* Define to 1 if you have the `sendmsg' function. */
#define HAVE_SENDMSG 1
/* Define to 1 if you have the `setauthdb' function. */
/* #undef HAVE_SETAUTHDB */
/* Define to 1 if you have the `setdtablesize' function. */
/* #undef HAVE_SETDTABLESIZE */
/* Define to 1 if you have the `setegid' function. */
#define HAVE_SETEGID 1
/* Define to 1 if you have the `setenv' function. */
#define HAVE_SETENV 1
/* Define to 1 if you have the `seteuid' function. */
#define HAVE_SETEUID 1
/* Define to 1 if you have the `setgroupent' function. */
#define HAVE_SETGROUPENT 1
/* Define to 1 if you have the `setgroups' function. */
#define HAVE_SETGROUPS 1
/* Define to 1 if you have the `setlinebuf' function. */
#define HAVE_SETLINEBUF 1
/* Define to 1 if you have the `setlogin' function. */
#define HAVE_SETLOGIN 1
/* Define to 1 if you have the `setluid' function. */
/* #undef HAVE_SETLUID */
/* Define to 1 if you have the `setpassent' function. */
#define HAVE_SETPASSENT 1
/* Define to 1 if you have the `setpcred' function. */
/* #undef HAVE_SETPCRED */
/* Define to 1 if you have the `setpflags' function. */
/* #undef HAVE_SETPFLAGS */
/* Define to 1 if you have the `setppriv' function. */
/* #undef HAVE_SETPPRIV */
/* Define to 1 if you have the `setproctitle' function. */
#define HAVE_SETPROCTITLE 1
/* Define to 1 if you have the `setregid' function. */
#define HAVE_SETREGID 1
/* Define to 1 if you have the `setresgid' function. */
#define HAVE_SETRESGID 1
/* Define to 1 if you have the `setresuid' function. */
#define HAVE_SETRESUID 1
/* Define to 1 if you have the `setreuid' function. */
#define HAVE_SETREUID 1
/* Define to 1 if you have the `setrlimit' function. */
#define HAVE_SETRLIMIT 1
/* Define to 1 if you have the `setsid' function. */
#define HAVE_SETSID 1
/* Define to 1 if you have the `setutent' function. */
/* #undef HAVE_SETUTENT */
/* Define to 1 if you have the `setutxdb' function. */
#define HAVE_SETUTXDB 1
/* Define to 1 if you have the `setutxent' function. */
#define HAVE_SETUTXENT 1
/* Define to 1 if you have the `setvbuf' function. */
#define HAVE_SETVBUF 1
/* Define to 1 if you have the `set_id' function. */
/* #undef HAVE_SET_ID */
/* Define to 1 if you have the `SHA256Update' function. */
/* #undef HAVE_SHA256UPDATE */
/* Define to 1 if you have the <sha2.h> header file. */
/* #undef HAVE_SHA2_H */
/* Define to 1 if you have the `SHA384Update' function. */
/* #undef HAVE_SHA384UPDATE */
/* Define to 1 if you have the `SHA512Update' function. */
/* #undef HAVE_SHA512UPDATE */
/* Define to 1 if you have the <shadow.h> header file. */
/* #undef HAVE_SHADOW_H */
/* Define to 1 if you have the `sigaction' function. */
#define HAVE_SIGACTION 1
/* Define to 1 if the system has the type `sighandler_t'. */
/* #undef HAVE_SIGHANDLER_T */
/* Define to 1 if you have the `sigvec' function. */
#define HAVE_SIGVEC 1
/* Define to 1 if the system has the type `sig_atomic_t'. */
#define HAVE_SIG_ATOMIC_T 1
/* define if you have size_t data type */
#define HAVE_SIZE_T 1
/* Define to 1 if you have the `snprintf' function. */
#define HAVE_SNPRINTF 1
/* Define to 1 if you have the `socketpair' function. */
#define HAVE_SOCKETPAIR 1
/* Have PEERCRED socket option */
/* #undef HAVE_SO_PEERCRED */
/* define if you have ssize_t data type */
#define HAVE_SSIZE_T 1
/* Fields in struct sockaddr_storage */
#define HAVE_SS_FAMILY_IN_SS 1
/* Define if you have ut_ss in utmpx.h */
/* #undef HAVE_SS_IN_UTMPX */
/* Define to 1 if you have the `statfs' function. */
#define HAVE_STATFS 1
/* Define to 1 if you have the `statvfs' function. */
#define HAVE_STATVFS 1
/* Define to 1 if you have the <stddef.h> header file. */
#define HAVE_STDDEF_H 1
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdio.h> header file. */
#define HAVE_STDIO_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the `strcasestr' function. */
#define HAVE_STRCASESTR 1
/* Define to 1 if you have the `strdup' function. */
#define HAVE_STRDUP 1
/* Define to 1 if you have the `strerror' function. */
#define HAVE_STRERROR 1
/* Define to 1 if you have the `strftime' function. */
#define HAVE_STRFTIME 1
/* Define to 1 if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the `strlcat' function. */
#define HAVE_STRLCAT 1
/* Define to 1 if you have the `strlcpy' function. */
#define HAVE_STRLCPY 1
/* Define to 1 if you have the `strmode' function. */
#define HAVE_STRMODE 1
/* Define to 1 if you have the `strndup' function. */
#define HAVE_STRNDUP 1
/* Define to 1 if you have the `strnlen' function. */
#define HAVE_STRNLEN 1
/* Define to 1 if you have the `strnvis' function. */
#define HAVE_STRNVIS 1
/* Define to 1 if you have the `strptime' function. */
#define HAVE_STRPTIME 1
/* Define to 1 if you have the `strsep' function. */
#define HAVE_STRSEP 1
/* Define to 1 if you have the `strsignal' function. */
#define HAVE_STRSIGNAL 1
/* Define to 1 if you have the `strtoll' function. */
#define HAVE_STRTOLL 1
/* Define to 1 if you have the `strtonum' function. */
#define HAVE_STRTONUM 1
/* Define to 1 if you have the `strtoul' function. */
#define HAVE_STRTOUL 1
/* Define to 1 if you have the `strtoull' function. */
#define HAVE_STRTOULL 1
/* define if you have struct addrinfo data type */
#define HAVE_STRUCT_ADDRINFO 1
/* define if you have struct in6_addr data type */
#define HAVE_STRUCT_IN6_ADDR 1
/* Define to 1 if `pw_change' is a member of `struct passwd'. */
#define HAVE_STRUCT_PASSWD_PW_CHANGE 1
/* Define to 1 if `pw_class' is a member of `struct passwd'. */
#define HAVE_STRUCT_PASSWD_PW_CLASS 1
/* Define to 1 if `pw_expire' is a member of `struct passwd'. */
#define HAVE_STRUCT_PASSWD_PW_EXPIRE 1
/* Define to 1 if `pw_gecos' is a member of `struct passwd'. */
#define HAVE_STRUCT_PASSWD_PW_GECOS 1
/* Define to 1 if `fd' is a member of `struct pollfd'. */
#define HAVE_STRUCT_POLLFD_FD 1
/* define if you have struct sockaddr_in6 data type */
#define HAVE_STRUCT_SOCKADDR_IN6 1
/* Define to 1 if `sin6_scope_id' is a member of `struct sockaddr_in6'. */
#define HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID 1
/* define if you have struct sockaddr_storage data type */
#define HAVE_STRUCT_SOCKADDR_STORAGE 1
/* Define to 1 if `f_files' is a member of `struct statfs'. */
#define HAVE_STRUCT_STATFS_F_FILES 1
/* Define to 1 if `f_flags' is a member of `struct statfs'. */
#define HAVE_STRUCT_STATFS_F_FLAGS 1
/* Define to 1 if `st_blksize' is a member of `struct stat'. */
#define HAVE_STRUCT_STAT_ST_BLKSIZE 1
/* Define to 1 if `st_mtim' is a member of `struct stat'. */
#define HAVE_STRUCT_STAT_ST_MTIM 1
/* Define to 1 if `st_mtime' is a member of `struct stat'. */
#define HAVE_STRUCT_STAT_ST_MTIME 1
/* define if you have struct timespec */
#define HAVE_STRUCT_TIMESPEC 1
/* define if you have struct timeval */
#define HAVE_STRUCT_TIMEVAL 1
/* Define to 1 if you have the `swap32' function. */
/* #undef HAVE_SWAP32 */
/* Define to 1 if you have the `sysconf' function. */
#define HAVE_SYSCONF 1
/* Define if you have syslen in utmpx.h */
/* #undef HAVE_SYSLEN_IN_UTMPX */
/* Define to 1 if you have the <sys/audit.h> header file. */
/* #undef HAVE_SYS_AUDIT_H */
/* Define to 1 if you have the <sys/bitypes.h> header file. */
/* #undef HAVE_SYS_BITYPES_H */
/* Define to 1 if you have the <sys/bsdtty.h> header file. */
/* #undef HAVE_SYS_BSDTTY_H */
/* Define to 1 if you have the <sys/byteorder.h> header file. */
/* #undef HAVE_SYS_BYTEORDER_H */
/* Define to 1 if you have the <sys/capsicum.h> header file. */
#define HAVE_SYS_CAPSICUM_H 1
/* Define to 1 if you have the <sys/cdefs.h> header file. */
#define HAVE_SYS_CDEFS_H 1
/* Define to 1 if you have the <sys/dir.h> header file. */
#define HAVE_SYS_DIR_H 1
/* Define if your system defines sys_errlist[] */
#define HAVE_SYS_ERRLIST 1
/* Define to 1 if you have the <sys/file.h> header file. */
#define HAVE_SYS_FILE_H 1
/* Define to 1 if you have the <sys/label.h> header file. */
/* #undef HAVE_SYS_LABEL_H */
/* Define to 1 if you have the <sys/mman.h> header file. */
#define HAVE_SYS_MMAN_H 1
/* Define to 1 if you have the <sys/mount.h> header file. */
#define HAVE_SYS_MOUNT_H 1
/* Define to 1 if you have the <sys/ndir.h> header file. */
/* #undef HAVE_SYS_NDIR_H */
/* Define if your system defines sys_nerr */
/* #undef HAVE_SYS_NERR */
/* Define to 1 if you have the <sys/param.h> header file. */
#define HAVE_SYS_PARAM_H 1
/* Define to 1 if you have the <sys/poll.h> header file. */
#define HAVE_SYS_POLL_H 1
/* Define to 1 if you have the <sys/prctl.h> header file. */
/* #undef HAVE_SYS_PRCTL_H */
/* Define to 1 if you have the <sys/procctl.h> header file. */
#define HAVE_SYS_PROCCTL_H 1
/* Define to 1 if you have the <sys/pstat.h> header file. */
/* #undef HAVE_SYS_PSTAT_H */
/* Define to 1 if you have the <sys/ptms.h> header file. */
/* #undef HAVE_SYS_PTMS_H */
/* Define to 1 if you have the <sys/ptrace.h> header file. */
#define HAVE_SYS_PTRACE_H 1
/* Define to 1 if you have the <sys/random.h> header file. */
#define HAVE_SYS_RANDOM_H 1
/* Define to 1 if you have the <sys/select.h> header file. */
#define HAVE_SYS_SELECT_H 1
/* Define to 1 if you have the <sys/statvfs.h> header file. */
#define HAVE_SYS_STATVFS_H 1
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/stream.h> header file. */
/* #undef HAVE_SYS_STREAM_H */
/* Define to 1 if you have the <sys/stropts.h> header file. */
/* #undef HAVE_SYS_STROPTS_H */
/* Define to 1 if you have the <sys/strtio.h> header file. */
/* #undef HAVE_SYS_STRTIO_H */
/* Define to 1 if you have the <sys/sysctl.h> header file. */
#define HAVE_SYS_SYSCTL_H 1
/* Force use of sys/syslog.h on Ultrix */
/* #undef HAVE_SYS_SYSLOG_H */
/* Define to 1 if you have the <sys/sysmacros.h> header file. */
/* #undef HAVE_SYS_SYSMACROS_H */
/* Define to 1 if you have the <sys/timers.h> header file. */
#define HAVE_SYS_TIMERS_H 1
/* Define to 1 if you have the <sys/time.h> header file. */
#define HAVE_SYS_TIME_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <sys/un.h> header file. */
#define HAVE_SYS_UN_H 1
/* Define to 1 if you have the <sys/vfs.h> header file. */
/* #undef HAVE_SYS_VFS_H */
/* Define to 1 if you have the `tcgetpgrp' function. */
#define HAVE_TCGETPGRP 1
/* Define to 1 if you have the `tcsendbreak' function. */
#define HAVE_TCSENDBREAK 1
/* Define to 1 if you have the `time' function. */
#define HAVE_TIME 1
/* Define to 1 if you have the `timegm' function. */
#define HAVE_TIMEGM 1
/* Define to 1 if you have the <time.h> header file. */
#define HAVE_TIME_H 1
/* Define if you have ut_time in utmp.h */
/* #undef HAVE_TIME_IN_UTMP */
/* Define if you have ut_time in utmpx.h */
/* #undef HAVE_TIME_IN_UTMPX */
/* Define to 1 if you have the `timingsafe_bcmp' function. */
#define HAVE_TIMINGSAFE_BCMP 1
/* Define to 1 if you have the <tmpdir.h> header file. */
/* #undef HAVE_TMPDIR_H */
/* Define to 1 if you have the `truncate' function. */
#define HAVE_TRUNCATE 1
/* Define to 1 if you have the <ttyent.h> header file. */
#define HAVE_TTYENT_H 1
/* Define if you have ut_tv in utmp.h */
/* #undef HAVE_TV_IN_UTMP */
/* Define if you have ut_tv in utmpx.h */
#define HAVE_TV_IN_UTMPX 1
/* Define if you have ut_type in utmp.h */
/* #undef HAVE_TYPE_IN_UTMP */
/* Define if you have ut_type in utmpx.h */
#define HAVE_TYPE_IN_UTMPX 1
/* Define to 1 if you have the <ucred.h> header file. */
/* #undef HAVE_UCRED_H */
/* Define to 1 if the system has the type `uintmax_t'. */
#define HAVE_UINTMAX_T 1
/* define if you have uintxx_t data type */
#define HAVE_UINTXX_T 1
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Define to 1 if you have the `unsetenv' function. */
#define HAVE_UNSETENV 1
/* Define to 1 if the system has the type `unsigned long long'. */
#define HAVE_UNSIGNED_LONG_LONG 1
/* Define to 1 if you have the `updwtmp' function. */
/* #undef HAVE_UPDWTMP */
/* Define to 1 if you have the `updwtmpx' function. */
/* #undef HAVE_UPDWTMPX */
/* Define to 1 if you have the <usersec.h> header file. */
/* #undef HAVE_USERSEC_H */
/* Define to 1 if you have the `user_from_uid' function. */
#define HAVE_USER_FROM_UID 1
/* Define to 1 if you have the `usleep' function. */
#define HAVE_USLEEP 1
/* Define to 1 if you have the <util.h> header file. */
/* #undef HAVE_UTIL_H */
/* Define to 1 if you have the `utimensat' function. */
#define HAVE_UTIMENSAT 1
/* Define to 1 if you have the `utimes' function. */
#define HAVE_UTIMES 1
/* Define to 1 if you have the <utime.h> header file. */
#define HAVE_UTIME_H 1
/* Define to 1 if you have the `utmpname' function. */
/* #undef HAVE_UTMPNAME */
/* Define to 1 if you have the `utmpxname' function. */
/* #undef HAVE_UTMPXNAME */
/* Define to 1 if you have the <utmpx.h> header file. */
#define HAVE_UTMPX_H 1
/* Define to 1 if you have the <utmp.h> header file. */
/* #undef HAVE_UTMP_H */
/* define if you have u_char data type */
#define HAVE_U_CHAR 1
/* define if you have u_int data type */
#define HAVE_U_INT 1
/* define if you have u_int64_t data type */
#define HAVE_U_INT64_T 1
/* define if you have u_intxx_t data type */
#define HAVE_U_INTXX_T 1
/* Define to 1 if you have the `vasprintf' function. */
#define HAVE_VASPRINTF 1
/* Define if va_copy exists */
#define HAVE_VA_COPY 1
/* Define to 1 if you have the <vis.h> header file. */
#define HAVE_VIS_H 1
/* Define to 1 if you have the `vsnprintf' function. */
#define HAVE_VSNPRINTF 1
/* Define to 1 if you have the `waitpid' function. */
#define HAVE_WAITPID 1
/* Define to 1 if you have the `warn' function. */
#define HAVE_WARN 1
/* Define to 1 if you have the <wchar.h> header file. */
#define HAVE_WCHAR_H 1
/* Define to 1 if you have the `wcwidth' function. */
#define HAVE_WCWIDTH 1
/* Define to 1 if you have the `_getlong' function. */
#define HAVE__GETLONG 1
/* Define to 1 if you have the `_getpty' function. */
/* #undef HAVE__GETPTY */
/* Define to 1 if you have the `_getshort' function. */
#define HAVE__GETSHORT 1
/* Define if you have struct __res_state _res as an extern */
#define HAVE__RES_EXTERN 1
/* Define to 1 if you have the `__b64_ntop' function. */
#define HAVE___B64_NTOP 1
/* Define to 1 if you have the `__b64_pton' function. */
#define HAVE___B64_PTON 1
/* Define if compiler implements __FUNCTION__ */
#define HAVE___FUNCTION__ 1
/* Define if libc defines __progname */
#define HAVE___PROGNAME 1
/* Fields in struct sockaddr_storage */
/* #undef HAVE___SS_FAMILY_IN_SS */
/* Define if __va_copy exists */
#define HAVE___VA_COPY 1
/* Define if compiler implements __func__ */
#define HAVE___func__ 1
/* Define this if you are using the Heimdal version of Kerberos V5 */
/* #undef HEIMDAL */
/* Define if you need to use IP address instead of hostname in $DISPLAY */
/* #undef IPADDR_IN_DISPLAY */
/* Detect IPv4 in IPv6 mapped addresses and treat as IPv4 */
/* #undef IPV4_IN_IPV6 */
/* Define if your system choked on IP TOS setting */
/* #undef IP_TOS_IS_BROKEN */
/* Define if you want Kerberos 5 support */
/* #undef KRB5 */
/* Define if pututxline updates lastlog too */
/* #undef LASTLOG_WRITE_PUTUTXLINE */
/* Define if you want TCP Wrappers support */
/* #undef LIBWRAP */
/* Define to whatever link() returns for "not supported" if it doesn't return
EOPNOTSUPP. */
/* #undef LINK_OPNOTSUPP_ERRNO */
/* Adjust Linux out-of-memory killer */
/* #undef LINUX_OOM_ADJUST */
/* max value of long long calculated by configure */
/* #undef LLONG_MAX */
/* min value of long long calculated by configure */
/* #undef LLONG_MIN */
/* Account locked with pw(1) */
#define LOCKED_PASSWD_PREFIX "*LOCKED*"
/* String used in /etc/passwd to denote locked account */
/* #undef LOCKED_PASSWD_STRING */
/* String used in /etc/passwd to denote locked account */
/* #undef LOCKED_PASSWD_SUBSTR */
/* Some systems need a utmpx entry for /bin/login to work */
/* #undef LOGIN_NEEDS_UTMPX */
/* Set this to your mail directory if you do not have _PATH_MAILDIR */
/* #undef MAIL_DIRECTORY */
/* Need setpgrp to for controlling tty */
/* #undef NEED_SETPGRP */
/* compiler does not accept __attribute__ on prototype args */
/* #undef NO_ATTRIBUTE_ON_PROTOTYPE_ARGS */
/* compiler does not accept __attribute__ on return types */
/* #undef NO_ATTRIBUTE_ON_RETURN_TYPE */
/* SA_RESTARTed signals do no interrupt select */
/* #undef NO_SA_RESTART */
/* Define to disable UID restoration test */
/* #undef NO_UID_RESTORATION_TEST */
/* Define if X11 doesn't support AF_UNIX sockets on that system */
/* #undef NO_X11_UNIX_SOCKETS */
/* Define if EVP_DigestUpdate returns void */
/* #undef OPENSSL_EVP_DIGESTUPDATE_VOID */
/* OpenSSL has ECC */
#define OPENSSL_HAS_ECC 1
/* libcrypto has NID_X9_62_prime256v1 */
#define OPENSSL_HAS_NISTP256 1
/* libcrypto has NID_secp384r1 */
#define OPENSSL_HAS_NISTP384 1
/* libcrypto has NID_secp521r1 */
#define OPENSSL_HAS_NISTP521 1
/* libcrypto is missing AES 192 and 256 bit functions */
/* #undef OPENSSL_LOBOTOMISED_AES */
/* Define if you want the OpenSSL internally seeded PRNG only */
#define OPENSSL_PRNG_ONLY 1
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "openssh-unix-dev@mindrot.org"
/* Define to the full name of this package. */
#define PACKAGE_NAME "OpenSSH"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "OpenSSH Portable"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "openssh"
/* Define to the home page for this package. */
#define PACKAGE_URL ""
/* Define to the version of this package. */
#define PACKAGE_VERSION "Portable"
/* Define if you are using Solaris-derived PAM which passes pam_messages to
the conversation function with an extra level of indirection */
/* #undef PAM_SUN_CODEBASE */
/* Work around problematic Linux PAM modules handling of PAM_TTY */
/* #undef PAM_TTY_KLUDGE */
/* must supply username to passwd */
/* #undef PASSWD_NEEDS_USERNAME */
/* System dirs owned by bin (uid 2) */
/* #undef PLATFORM_SYS_DIR_UID */
/* Port number of PRNGD/EGD random number socket */
/* #undef PRNGD_PORT */
/* Location of PRNGD/EGD random number socket */
/* #undef PRNGD_SOCKET */
/* read(1) can return 0 for a non-closed fd */
/* #undef PTY_ZEROREAD */
/* Sandbox using capsicum */
#define SANDBOX_CAPSICUM 1
/* Sandbox using Darwin sandbox_init(3) */
/* #undef SANDBOX_DARWIN */
/* no privsep sandboxing */
/* #undef SANDBOX_NULL */
/* Sandbox using pledge(2) */
/* #undef SANDBOX_PLEDGE */
/* Sandbox using setrlimit(2) */
/* #undef SANDBOX_RLIMIT */
/* Sandbox using seccomp filter */
/* #undef SANDBOX_SECCOMP_FILTER */
/* setrlimit RLIMIT_FSIZE works */
/* #undef SANDBOX_SKIP_RLIMIT_FSIZE */
/* define if setrlimit RLIMIT_NOFILE breaks things */
#define SANDBOX_SKIP_RLIMIT_NOFILE 1
/* Sandbox using Solaris/Illumos privileges */
/* #undef SANDBOX_SOLARIS */
/* Sandbox using systrace(4) */
/* #undef SANDBOX_SYSTRACE */
/* Specify the system call convention in use */
/* #undef SECCOMP_AUDIT_ARCH */
/* Define if your platform breaks doing a seteuid before a setuid */
/* #undef SETEUID_BREAKS_SETUID */
/* The size of `int', as computed by sizeof. */
#define SIZEOF_INT 4
/* The size of `long int', as computed by sizeof. */
#define SIZEOF_LONG_INT 8
/* The size of `long long int', as computed by sizeof. */
#define SIZEOF_LONG_LONG_INT 8
/* The size of `short int', as computed by sizeof. */
#define SIZEOF_SHORT_INT 2
/* The size of `time_t', as computed by sizeof. */
#ifdef __i386__
#define SIZEOF_TIME_T 4
#else
#define SIZEOF_TIME_T 8
#endif
/* Define as const if snprintf() can declare const char *fmt */
#define SNPRINTF_CONST const
+/* sockaddr_in has sin_len */
+#define SOCK_HAS_LEN 1
+
/* Define to a Set Process Title type if your system is supported by
bsd-setproctitle.c */
/* #undef SPT_TYPE */
/* Define if sshd somehow reacquires a controlling TTY after setsid() */
/* #undef SSHD_ACQUIRES_CTTY */
/* sshd PAM service name */
/* #undef SSHD_PAM_SERVICE */
/* Define if pam_chauthtok wants real uid set to the unpriv'ed user */
/* #undef SSHPAM_CHAUTHTOK_NEEDS_RUID */
/* Use audit debugging module */
/* #undef SSH_AUDIT_EVENTS */
/* Windows is sensitive to read buffer size */
/* #undef SSH_IOBUFSZ */
/* non-privileged user for privilege separation */
#define SSH_PRIVSEP_USER "sshd"
/* Use tunnel device compatibility to OpenBSD */
/* #undef SSH_TUN_COMPAT_AF */
/* Open tunnel devices the FreeBSD way */
#define SSH_TUN_FREEBSD 1
/* Open tunnel devices the Linux tun/tap way */
/* #undef SSH_TUN_LINUX */
/* No layer 2 tunnel support */
/* #undef SSH_TUN_NO_L2 */
/* Open tunnel devices the OpenBSD way */
/* #undef SSH_TUN_OPENBSD */
/* Prepend the address family to IP tunnel traffic */
/* #undef SSH_TUN_PREPEND_AF */
/* Define to 1 if all of the C90 standard headers exist (not just the ones
required in a freestanding environment). This macro is provided for
backward compatibility; new code need not use it. */
#define STDC_HEADERS 1
/* Define if you want a different $PATH for the superuser */
/* #undef SUPERUSER_PATH */
/* syslog_r function is safe to use in in a signal handler */
/* #undef SYSLOG_R_SAFE_IN_SIGHAND */
/* Support routing domains using Linux VRF */
/* #undef SYS_RDOMAIN_LINUX */
/* Support passwords > 8 chars */
/* #undef UNIXWARE_LONG_PASSWORDS */
/* Specify default $PATH */
/* #undef USER_PATH */
/* Define this if you want to use libkafs' AFS support */
/* #undef USE_AFS */
/* Use BSM audit module */
/* #undef USE_BSM_AUDIT */
/* Use btmp to log bad logins */
/* #undef USE_BTMP */
/* Use libedit for sftp */
#define USE_LIBEDIT 1
/* Use Linux audit module */
/* #undef USE_LINUX_AUDIT */
/* Enable OpenSSL engine support */
#define USE_OPENSSL_ENGINE 1
/* Define if you want to enable PAM support */
#define USE_PAM 1
/* Use PIPES instead of a socketpair() */
/* #undef USE_PIPES */
/* Define if you have Solaris privileges */
/* #undef USE_SOLARIS_PRIVS */
/* Define if you have Solaris process contracts */
/* #undef USE_SOLARIS_PROCESS_CONTRACTS */
/* Define if you have Solaris projects */
/* #undef USE_SOLARIS_PROJECTS */
/* compiler variable declarations after code */
#define VARIABLE_DECLARATION_AFTER_CODE 1
/* compiler supports variable length arrays */
#define VARIABLE_LENGTH_ARRAYS 1
/* Define if you shouldn't strip 'tty' from your ttyname in [uw]tmp */
/* #undef WITH_ABBREV_NO_TTY */
/* Define if you want to enable AIX4's authenticate function */
/* #undef WITH_AIXAUTHENTICATE */
/* Define if you have/want arrays (cluster-wide session management, not C
arrays) */
/* #undef WITH_IRIX_ARRAY */
/* Define if you want IRIX audit trails */
/* #undef WITH_IRIX_AUDIT */
/* Define if you want IRIX kernel jobs */
/* #undef WITH_IRIX_JOBS */
/* Define if you want IRIX project management */
/* #undef WITH_IRIX_PROJECT */
/* use libcrypto for cryptography */
#define WITH_OPENSSL 1
/* Define if you want SELinux support. */
/* #undef WITH_SELINUX */
/* Enable zlib */
#define WITH_ZLIB 1
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
significant byte first (like Motorola and SPARC, unlike Intel). */
#if defined AC_APPLE_UNIVERSAL_BUILD
# if defined __BIG_ENDIAN__
# define WORDS_BIGENDIAN 1
# endif
#else
# ifndef WORDS_BIGENDIAN
/* # undef WORDS_BIGENDIAN */
# endif
#endif
/* Define if xauth is found in your path */
#define XAUTH_PATH "/usr/local/bin/xauth"
/* Number of bits in a file offset, on hosts where this is settable. */
/* #undef _FILE_OFFSET_BITS */
/* Define for large files, on AIX-style hosts. */
/* #undef _LARGE_FILES */
/* log for bad login attempts */
/* #undef _PATH_BTMP */
/* Full path of your "passwd" program */
#define _PATH_PASSWD_PROG "/usr/bin/passwd"
/* Specify location of ssh.pid */
#define _PATH_SSH_PIDDIR "/var/run"
/* Define if we don't have struct __res_state in resolv.h */
/* #undef __res_state */
/* Define to rpl_calloc if the replacement function should be used. */
/* #undef calloc */
/* Define to `__inline__' or `__inline' if that's what the C compiler
calls it, or to nothing if 'inline' is not supported under any name. */
#ifndef __cplusplus
/* #undef inline */
#endif
/* Define to rpl_malloc if the replacement function should be used. */
/* #undef malloc */
/* Define to rpl_realloc if the replacement function should be used. */
/* #undef realloc */
/* type to use in place of socklen_t if not defined */
/* #undef socklen_t */
diff --git a/crypto/openssh/config.sub b/crypto/openssh/config.sub
index 973a2980ac3a..baf1512b3c03 100755
--- a/crypto/openssh/config.sub
+++ b/crypto/openssh/config.sub
@@ -1,1793 +1,1907 @@
#! /bin/sh
# Configuration validation subroutine script.
-# Copyright 1992-2020 Free Software Foundation, Inc.
+# Copyright 1992-2022 Free Software Foundation, Inc.
-timestamp='2020-05-04'
+# shellcheck disable=SC2006,SC2268 # see below for rationale
+
+timestamp='2022-09-17'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
+# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <https://www.gnu.org/licenses/>.
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that
# program. This Exception is an additional permission under section 7
# of the GNU General Public License, version 3 ("GPLv3").
# Please send patches to <config-patches@gnu.org>.
#
# Configuration subroutine to validate and canonicalize a configuration type.
# Supply the specified configuration type as an argument.
# If it is invalid, we print an error message on stderr and exit with code 1.
# Otherwise, we print the canonical config type on stdout and succeed.
# You can get the latest version of this script from:
-# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
+# https://git.savannah.gnu.org/cgit/config.git/plain/config.sub
# This file is supposed to be the same for all GNU packages
# and recognize all the CPU types, system types and aliases
# that are meaningful with *any* GNU software.
# Each package is responsible for reporting which valid configurations
# it does not support. The user should be able to distinguish
# a failure to support a valid configuration from a meaningless
# configuration.
# The goal of this file is to map all the various variations of a given
# machine specification into a single specification in the form:
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
# or in some cases, the newer four-part form:
# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
# It is wrong to echo any other type of specification.
+# The "shellcheck disable" line above the timestamp inhibits complaints
+# about features and limitations of the classic Bourne shell that were
+# superseded or lifted in POSIX. However, this script identifies a wide
+# variety of pre-POSIX systems that do not have POSIX shells at all, and
+# even some reasonably current systems (Solaris 10 as case-in-point) still
+# have a pre-POSIX /bin/sh.
+
me=`echo "$0" | sed -e 's,.*/,,'`
usage="\
Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS
Canonicalize a configuration name.
Options:
-h, --help print this help, then exit
-t, --time-stamp print date of last modification, then exit
-v, --version print version number, then exit
Report bugs and patches to <config-patches@gnu.org>."
version="\
GNU config.sub ($timestamp)
-Copyright 1992-2020 Free Software Foundation, Inc.
+Copyright 1992-2022 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
help="
Try \`$me --help' for more information."
# Parse command line
while test $# -gt 0 ; do
case $1 in
--time-stamp | --time* | -t )
echo "$timestamp" ; exit ;;
--version | -v )
echo "$version" ; exit ;;
--help | --h* | -h )
echo "$usage"; exit ;;
-- ) # Stop option processing
shift; break ;;
- ) # Use stdin as input.
break ;;
-* )
echo "$me: invalid option $1$help" >&2
exit 1 ;;
*local*)
# First pass through any local machine types.
echo "$1"
exit ;;
* )
break ;;
esac
done
case $# in
0) echo "$me: missing argument$help" >&2
exit 1;;
1) ;;
*) echo "$me: too many arguments$help" >&2
exit 1;;
esac
# Split fields of configuration type
# shellcheck disable=SC2162
+saved_IFS=$IFS
IFS="-" read field1 field2 field3 field4 <<EOF
$1
EOF
+IFS=$saved_IFS
# Separate into logical components for further validation
case $1 in
*-*-*-*-*)
echo Invalid configuration \`"$1"\': more than four components >&2
exit 1
;;
*-*-*-*)
basic_machine=$field1-$field2
- os=$field3-$field4
+ basic_os=$field3-$field4
;;
*-*-*)
# Ambiguous whether COMPANY is present, or skipped and KERNEL-OS is two
# parts
maybe_os=$field2-$field3
case $maybe_os in
- nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc \
- | linux-newlib* | linux-musl* | linux-uclibc* | uclinux-uclibc* \
+ nto-qnx* | linux-* | uclinux-uclibc* \
| uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \
| netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \
- | storm-chaos* | os2-emx* | rtmk-nova*)
+ | storm-chaos* | os2-emx* | rtmk-nova* | managarm-*)
basic_machine=$field1
- os=$maybe_os
+ basic_os=$maybe_os
;;
android-linux)
basic_machine=$field1-unknown
- os=linux-android
+ basic_os=linux-android
;;
*)
basic_machine=$field1-$field2
- os=$field3
+ basic_os=$field3
;;
esac
;;
*-*)
# A lone config we happen to match not fitting any pattern
case $field1-$field2 in
decstation-3100)
basic_machine=mips-dec
- os=
+ basic_os=
;;
*-*)
# Second component is usually, but not always the OS
case $field2 in
# Prevent following clause from handling this valid os
sun*os*)
basic_machine=$field1
- os=$field2
+ basic_os=$field2
+ ;;
+ zephyr*)
+ basic_machine=$field1-unknown
+ basic_os=$field2
;;
# Manufacturers
dec* | mips* | sequent* | encore* | pc533* | sgi* | sony* \
| att* | 7300* | 3300* | delta* | motorola* | sun[234]* \
| unicom* | ibm* | next | hp | isi* | apollo | altos* \
| convergent* | ncr* | news | 32* | 3600* | 3100* \
| hitachi* | c[123]* | convex* | sun | crds | omron* | dg \
| ultra | tti* | harris | dolphin | highlevel | gould \
| cbm | ns | masscomp | apple | axis | knuth | cray \
| microblaze* | sim | cisco \
| oki | wec | wrs | winbond)
basic_machine=$field1-$field2
- os=
+ basic_os=
;;
*)
basic_machine=$field1
- os=$field2
+ basic_os=$field2
;;
esac
;;
esac
;;
*)
# Convert single-component short-hands not valid as part of
# multi-component configurations.
case $field1 in
386bsd)
basic_machine=i386-pc
- os=bsd
+ basic_os=bsd
;;
a29khif)
basic_machine=a29k-amd
- os=udi
+ basic_os=udi
;;
adobe68k)
basic_machine=m68010-adobe
- os=scout
+ basic_os=scout
;;
alliant)
basic_machine=fx80-alliant
- os=
+ basic_os=
;;
altos | altos3068)
basic_machine=m68k-altos
- os=
+ basic_os=
;;
am29k)
basic_machine=a29k-none
- os=bsd
+ basic_os=bsd
;;
amdahl)
basic_machine=580-amdahl
- os=sysv
+ basic_os=sysv
;;
amiga)
basic_machine=m68k-unknown
- os=
+ basic_os=
;;
amigaos | amigados)
basic_machine=m68k-unknown
- os=amigaos
+ basic_os=amigaos
;;
amigaunix | amix)
basic_machine=m68k-unknown
- os=sysv4
+ basic_os=sysv4
;;
apollo68)
basic_machine=m68k-apollo
- os=sysv
+ basic_os=sysv
;;
apollo68bsd)
basic_machine=m68k-apollo
- os=bsd
+ basic_os=bsd
;;
aros)
basic_machine=i386-pc
- os=aros
+ basic_os=aros
;;
aux)
basic_machine=m68k-apple
- os=aux
+ basic_os=aux
;;
balance)
basic_machine=ns32k-sequent
- os=dynix
+ basic_os=dynix
;;
blackfin)
basic_machine=bfin-unknown
- os=linux
+ basic_os=linux
;;
cegcc)
basic_machine=arm-unknown
- os=cegcc
+ basic_os=cegcc
;;
convex-c1)
basic_machine=c1-convex
- os=bsd
+ basic_os=bsd
;;
convex-c2)
basic_machine=c2-convex
- os=bsd
+ basic_os=bsd
;;
convex-c32)
basic_machine=c32-convex
- os=bsd
+ basic_os=bsd
;;
convex-c34)
basic_machine=c34-convex
- os=bsd
+ basic_os=bsd
;;
convex-c38)
basic_machine=c38-convex
- os=bsd
+ basic_os=bsd
;;
cray)
basic_machine=j90-cray
- os=unicos
+ basic_os=unicos
;;
crds | unos)
basic_machine=m68k-crds
- os=
+ basic_os=
;;
da30)
basic_machine=m68k-da30
- os=
+ basic_os=
;;
decstation | pmax | pmin | dec3100 | decstatn)
basic_machine=mips-dec
- os=
+ basic_os=
;;
delta88)
basic_machine=m88k-motorola
- os=sysv3
+ basic_os=sysv3
;;
dicos)
basic_machine=i686-pc
- os=dicos
+ basic_os=dicos
;;
djgpp)
basic_machine=i586-pc
- os=msdosdjgpp
+ basic_os=msdosdjgpp
;;
ebmon29k)
basic_machine=a29k-amd
- os=ebmon
+ basic_os=ebmon
;;
es1800 | OSE68k | ose68k | ose | OSE)
basic_machine=m68k-ericsson
- os=ose
+ basic_os=ose
;;
gmicro)
basic_machine=tron-gmicro
- os=sysv
+ basic_os=sysv
;;
go32)
basic_machine=i386-pc
- os=go32
+ basic_os=go32
;;
h8300hms)
basic_machine=h8300-hitachi
- os=hms
+ basic_os=hms
;;
h8300xray)
basic_machine=h8300-hitachi
- os=xray
+ basic_os=xray
;;
h8500hms)
basic_machine=h8500-hitachi
- os=hms
+ basic_os=hms
;;
harris)
basic_machine=m88k-harris
- os=sysv3
+ basic_os=sysv3
;;
hp300 | hp300hpux)
basic_machine=m68k-hp
- os=hpux
+ basic_os=hpux
;;
hp300bsd)
basic_machine=m68k-hp
- os=bsd
+ basic_os=bsd
;;
hppaosf)
basic_machine=hppa1.1-hp
- os=osf
+ basic_os=osf
;;
hppro)
basic_machine=hppa1.1-hp
- os=proelf
+ basic_os=proelf
;;
i386mach)
basic_machine=i386-mach
- os=mach
+ basic_os=mach
;;
isi68 | isi)
basic_machine=m68k-isi
- os=sysv
+ basic_os=sysv
;;
m68knommu)
basic_machine=m68k-unknown
- os=linux
+ basic_os=linux
;;
magnum | m3230)
basic_machine=mips-mips
- os=sysv
+ basic_os=sysv
;;
merlin)
basic_machine=ns32k-utek
- os=sysv
+ basic_os=sysv
;;
mingw64)
basic_machine=x86_64-pc
- os=mingw64
+ basic_os=mingw64
;;
mingw32)
basic_machine=i686-pc
- os=mingw32
+ basic_os=mingw32
;;
mingw32ce)
basic_machine=arm-unknown
- os=mingw32ce
+ basic_os=mingw32ce
;;
monitor)
basic_machine=m68k-rom68k
- os=coff
+ basic_os=coff
;;
morphos)
basic_machine=powerpc-unknown
- os=morphos
+ basic_os=morphos
;;
moxiebox)
basic_machine=moxie-unknown
- os=moxiebox
+ basic_os=moxiebox
;;
msdos)
basic_machine=i386-pc
- os=msdos
+ basic_os=msdos
;;
msys)
basic_machine=i686-pc
- os=msys
+ basic_os=msys
;;
mvs)
basic_machine=i370-ibm
- os=mvs
+ basic_os=mvs
;;
nacl)
basic_machine=le32-unknown
- os=nacl
+ basic_os=nacl
;;
ncr3000)
basic_machine=i486-ncr
- os=sysv4
+ basic_os=sysv4
;;
netbsd386)
basic_machine=i386-pc
- os=netbsd
+ basic_os=netbsd
;;
netwinder)
basic_machine=armv4l-rebel
- os=linux
+ basic_os=linux
;;
news | news700 | news800 | news900)
basic_machine=m68k-sony
- os=newsos
+ basic_os=newsos
;;
news1000)
basic_machine=m68030-sony
- os=newsos
+ basic_os=newsos
;;
necv70)
basic_machine=v70-nec
- os=sysv
+ basic_os=sysv
;;
nh3000)
basic_machine=m68k-harris
- os=cxux
+ basic_os=cxux
;;
nh[45]000)
basic_machine=m88k-harris
- os=cxux
+ basic_os=cxux
;;
nindy960)
basic_machine=i960-intel
- os=nindy
+ basic_os=nindy
;;
mon960)
basic_machine=i960-intel
- os=mon960
+ basic_os=mon960
;;
nonstopux)
basic_machine=mips-compaq
- os=nonstopux
+ basic_os=nonstopux
;;
os400)
basic_machine=powerpc-ibm
- os=os400
+ basic_os=os400
;;
OSE68000 | ose68000)
basic_machine=m68000-ericsson
- os=ose
+ basic_os=ose
;;
os68k)
basic_machine=m68k-none
- os=os68k
+ basic_os=os68k
;;
paragon)
basic_machine=i860-intel
- os=osf
+ basic_os=osf
;;
parisc)
basic_machine=hppa-unknown
- os=linux
+ basic_os=linux
+ ;;
+ psp)
+ basic_machine=mipsallegrexel-sony
+ basic_os=psp
;;
pw32)
basic_machine=i586-unknown
- os=pw32
+ basic_os=pw32
;;
rdos | rdos64)
basic_machine=x86_64-pc
- os=rdos
+ basic_os=rdos
;;
rdos32)
basic_machine=i386-pc
- os=rdos
+ basic_os=rdos
;;
rom68k)
basic_machine=m68k-rom68k
- os=coff
+ basic_os=coff
;;
sa29200)
basic_machine=a29k-amd
- os=udi
+ basic_os=udi
;;
sei)
basic_machine=mips-sei
- os=seiux
+ basic_os=seiux
;;
sequent)
basic_machine=i386-sequent
- os=
+ basic_os=
;;
sps7)
basic_machine=m68k-bull
- os=sysv2
+ basic_os=sysv2
;;
st2000)
basic_machine=m68k-tandem
- os=
+ basic_os=
;;
stratus)
basic_machine=i860-stratus
- os=sysv4
+ basic_os=sysv4
;;
sun2)
basic_machine=m68000-sun
- os=
+ basic_os=
;;
sun2os3)
basic_machine=m68000-sun
- os=sunos3
+ basic_os=sunos3
;;
sun2os4)
basic_machine=m68000-sun
- os=sunos4
+ basic_os=sunos4
;;
sun3)
basic_machine=m68k-sun
- os=
+ basic_os=
;;
sun3os3)
basic_machine=m68k-sun
- os=sunos3
+ basic_os=sunos3
;;
sun3os4)
basic_machine=m68k-sun
- os=sunos4
+ basic_os=sunos4
;;
sun4)
basic_machine=sparc-sun
- os=
+ basic_os=
;;
sun4os3)
basic_machine=sparc-sun
- os=sunos3
+ basic_os=sunos3
;;
sun4os4)
basic_machine=sparc-sun
- os=sunos4
+ basic_os=sunos4
;;
sun4sol2)
basic_machine=sparc-sun
- os=solaris2
+ basic_os=solaris2
;;
sun386 | sun386i | roadrunner)
basic_machine=i386-sun
- os=
+ basic_os=
;;
sv1)
basic_machine=sv1-cray
- os=unicos
+ basic_os=unicos
;;
symmetry)
basic_machine=i386-sequent
- os=dynix
+ basic_os=dynix
;;
t3e)
basic_machine=alphaev5-cray
- os=unicos
+ basic_os=unicos
;;
t90)
basic_machine=t90-cray
- os=unicos
+ basic_os=unicos
;;
toad1)
basic_machine=pdp10-xkl
- os=tops20
+ basic_os=tops20
;;
tpf)
basic_machine=s390x-ibm
- os=tpf
+ basic_os=tpf
;;
udi29k)
basic_machine=a29k-amd
- os=udi
+ basic_os=udi
;;
ultra3)
basic_machine=a29k-nyu
- os=sym1
+ basic_os=sym1
;;
v810 | necv810)
basic_machine=v810-nec
- os=none
+ basic_os=none
;;
vaxv)
basic_machine=vax-dec
- os=sysv
+ basic_os=sysv
;;
vms)
basic_machine=vax-dec
- os=vms
+ basic_os=vms
;;
vsta)
basic_machine=i386-pc
- os=vsta
+ basic_os=vsta
;;
vxworks960)
basic_machine=i960-wrs
- os=vxworks
+ basic_os=vxworks
;;
vxworks68)
basic_machine=m68k-wrs
- os=vxworks
+ basic_os=vxworks
;;
vxworks29k)
basic_machine=a29k-wrs
- os=vxworks
+ basic_os=vxworks
;;
xbox)
basic_machine=i686-pc
- os=mingw32
+ basic_os=mingw32
;;
ymp)
basic_machine=ymp-cray
- os=unicos
+ basic_os=unicos
;;
*)
basic_machine=$1
- os=
+ basic_os=
;;
esac
;;
esac
# Decode 1-component or ad-hoc basic machines
case $basic_machine in
# Here we handle the default manufacturer of certain CPU types. It is in
# some cases the only manufacturer, in others, it is the most popular.
w89k)
cpu=hppa1.1
vendor=winbond
;;
op50n)
cpu=hppa1.1
vendor=oki
;;
op60c)
cpu=hppa1.1
vendor=oki
;;
ibm*)
cpu=i370
vendor=ibm
;;
orion105)
cpu=clipper
vendor=highlevel
;;
mac | mpw | mac-mpw)
cpu=m68k
vendor=apple
;;
pmac | pmac-mpw)
cpu=powerpc
vendor=apple
;;
# Recognize the various machine names and aliases which stand
# for a CPU type and a company and sometimes even an OS.
3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
cpu=m68000
vendor=att
;;
3b*)
cpu=we32k
vendor=att
;;
bluegene*)
cpu=powerpc
vendor=ibm
- os=cnk
+ basic_os=cnk
;;
decsystem10* | dec10*)
cpu=pdp10
vendor=dec
- os=tops10
+ basic_os=tops10
;;
decsystem20* | dec20*)
cpu=pdp10
vendor=dec
- os=tops20
+ basic_os=tops20
;;
delta | 3300 | motorola-3300 | motorola-delta \
| 3300-motorola | delta-motorola)
cpu=m68k
vendor=motorola
;;
dpx2*)
cpu=m68k
vendor=bull
- os=sysv3
+ basic_os=sysv3
;;
encore | umax | mmax)
cpu=ns32k
vendor=encore
;;
elxsi)
cpu=elxsi
vendor=elxsi
- os=${os:-bsd}
+ basic_os=${basic_os:-bsd}
;;
fx2800)
cpu=i860
vendor=alliant
;;
genix)
cpu=ns32k
vendor=ns
;;
h3050r* | hiux*)
cpu=hppa1.1
vendor=hitachi
- os=hiuxwe2
+ basic_os=hiuxwe2
;;
hp3k9[0-9][0-9] | hp9[0-9][0-9])
cpu=hppa1.0
vendor=hp
;;
hp9k2[0-9][0-9] | hp9k31[0-9])
cpu=m68000
vendor=hp
;;
hp9k3[2-9][0-9])
cpu=m68k
vendor=hp
;;
hp9k6[0-9][0-9] | hp6[0-9][0-9])
cpu=hppa1.0
vendor=hp
;;
hp9k7[0-79][0-9] | hp7[0-79][0-9])
cpu=hppa1.1
vendor=hp
;;
hp9k78[0-9] | hp78[0-9])
# FIXME: really hppa2.0-hp
cpu=hppa1.1
vendor=hp
;;
hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
# FIXME: really hppa2.0-hp
cpu=hppa1.1
vendor=hp
;;
hp9k8[0-9][13679] | hp8[0-9][13679])
cpu=hppa1.1
vendor=hp
;;
hp9k8[0-9][0-9] | hp8[0-9][0-9])
cpu=hppa1.0
vendor=hp
;;
i*86v32)
cpu=`echo "$1" | sed -e 's/86.*/86/'`
vendor=pc
- os=sysv32
+ basic_os=sysv32
;;
i*86v4*)
cpu=`echo "$1" | sed -e 's/86.*/86/'`
vendor=pc
- os=sysv4
+ basic_os=sysv4
;;
i*86v)
cpu=`echo "$1" | sed -e 's/86.*/86/'`
vendor=pc
- os=sysv
+ basic_os=sysv
;;
i*86sol2)
cpu=`echo "$1" | sed -e 's/86.*/86/'`
vendor=pc
- os=solaris2
+ basic_os=solaris2
;;
j90 | j90-cray)
cpu=j90
vendor=cray
- os=${os:-unicos}
+ basic_os=${basic_os:-unicos}
;;
iris | iris4d)
cpu=mips
vendor=sgi
- case $os in
+ case $basic_os in
irix*)
;;
*)
- os=irix4
+ basic_os=irix4
;;
esac
;;
miniframe)
cpu=m68000
vendor=convergent
;;
*mint | mint[0-9]* | *MiNT | *MiNT[0-9]*)
cpu=m68k
vendor=atari
- os=mint
+ basic_os=mint
;;
news-3600 | risc-news)
cpu=mips
vendor=sony
- os=newsos
+ basic_os=newsos
;;
next | m*-next)
cpu=m68k
vendor=next
- case $os in
+ case $basic_os in
openstep*)
;;
nextstep*)
;;
ns2*)
- os=nextstep2
+ basic_os=nextstep2
;;
*)
- os=nextstep3
+ basic_os=nextstep3
;;
esac
;;
np1)
cpu=np1
vendor=gould
;;
op50n-* | op60c-*)
cpu=hppa1.1
vendor=oki
- os=proelf
+ basic_os=proelf
;;
pa-hitachi)
cpu=hppa1.1
vendor=hitachi
- os=hiuxwe2
+ basic_os=hiuxwe2
;;
pbd)
cpu=sparc
vendor=tti
;;
pbb)
cpu=m68k
vendor=tti
;;
pc532)
cpu=ns32k
vendor=pc532
;;
pn)
cpu=pn
vendor=gould
;;
power)
cpu=power
vendor=ibm
;;
ps2)
cpu=i386
vendor=ibm
;;
rm[46]00)
cpu=mips
vendor=siemens
;;
rtpc | rtpc-*)
cpu=romp
vendor=ibm
;;
sde)
cpu=mipsisa32
vendor=sde
- os=${os:-elf}
+ basic_os=${basic_os:-elf}
;;
simso-wrs)
cpu=sparclite
vendor=wrs
- os=vxworks
+ basic_os=vxworks
;;
tower | tower-32)
cpu=m68k
vendor=ncr
;;
vpp*|vx|vx-*)
cpu=f301
vendor=fujitsu
;;
w65)
cpu=w65
vendor=wdc
;;
w89k-*)
cpu=hppa1.1
vendor=winbond
- os=proelf
+ basic_os=proelf
;;
none)
cpu=none
vendor=none
;;
leon|leon[3-9])
cpu=sparc
vendor=$basic_machine
;;
leon-*|leon[3-9]-*)
cpu=sparc
vendor=`echo "$basic_machine" | sed 's/-.*//'`
;;
*-*)
# shellcheck disable=SC2162
+ saved_IFS=$IFS
IFS="-" read cpu vendor <<EOF
$basic_machine
EOF
+ IFS=$saved_IFS
;;
# We use `pc' rather than `unknown'
# because (1) that's what they normally are, and
# (2) the word "unknown" tends to confuse beginning users.
i*86 | x86_64)
cpu=$basic_machine
vendor=pc
;;
# These rules are duplicated from below for sake of the special case above;
# i.e. things that normalized to x86 arches should also default to "pc"
pc98)
cpu=i386
vendor=pc
;;
x64 | amd64)
cpu=x86_64
vendor=pc
;;
# Recognize the basic CPU types without company name.
*)
cpu=$basic_machine
vendor=unknown
;;
esac
unset -v basic_machine
# Decode basic machines in the full and proper CPU-Company form.
case $cpu-$vendor in
# Here we handle the default manufacturer of certain CPU types in canonical form. It is in
# some cases the only manufacturer, in others, it is the most popular.
craynv-unknown)
vendor=cray
- os=${os:-unicosmp}
+ basic_os=${basic_os:-unicosmp}
;;
c90-unknown | c90-cray)
vendor=cray
- os=${os:-unicos}
+ basic_os=${Basic_os:-unicos}
;;
fx80-unknown)
vendor=alliant
;;
romp-unknown)
vendor=ibm
;;
mmix-unknown)
vendor=knuth
;;
microblaze-unknown | microblazeel-unknown)
vendor=xilinx
;;
rs6000-unknown)
vendor=ibm
;;
vax-unknown)
vendor=dec
;;
pdp11-unknown)
vendor=dec
;;
we32k-unknown)
vendor=att
;;
cydra-unknown)
vendor=cydrome
;;
i370-ibm*)
vendor=ibm
;;
orion-unknown)
vendor=highlevel
;;
xps-unknown | xps100-unknown)
cpu=xps100
vendor=honeywell
;;
# Here we normalize CPU types with a missing or matching vendor
+ armh-unknown | armh-alt)
+ cpu=armv7l
+ vendor=alt
+ basic_os=${basic_os:-linux-gnueabihf}
+ ;;
dpx20-unknown | dpx20-bull)
cpu=rs6000
vendor=bull
- os=${os:-bosx}
+ basic_os=${basic_os:-bosx}
;;
# Here we normalize CPU types irrespective of the vendor
amd64-*)
cpu=x86_64
;;
blackfin-*)
cpu=bfin
- os=linux
+ basic_os=linux
;;
c54x-*)
cpu=tic54x
;;
c55x-*)
cpu=tic55x
;;
c6x-*)
cpu=tic6x
;;
e500v[12]-*)
cpu=powerpc
- os=$os"spe"
+ basic_os=${basic_os}"spe"
;;
mips3*-*)
cpu=mips64
;;
ms1-*)
cpu=mt
;;
m68knommu-*)
cpu=m68k
- os=linux
+ basic_os=linux
;;
m9s12z-* | m68hcs12z-* | hcs12z-* | s12z-*)
cpu=s12z
;;
openrisc-*)
cpu=or32
;;
parisc-*)
cpu=hppa
- os=linux
+ basic_os=linux
;;
pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
cpu=i586
;;
pentiumpro-* | p6-* | 6x86-* | athlon-* | athalon_*-*)
cpu=i686
;;
pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
cpu=i686
;;
pentium4-*)
cpu=i786
;;
pc98-*)
cpu=i386
;;
ppc-* | ppcbe-*)
cpu=powerpc
;;
ppcle-* | powerpclittle-*)
cpu=powerpcle
;;
ppc64-*)
cpu=powerpc64
;;
ppc64le-* | powerpc64little-*)
cpu=powerpc64le
;;
sb1-*)
cpu=mipsisa64sb1
;;
sb1el-*)
cpu=mipsisa64sb1el
;;
sh5e[lb]-*)
cpu=`echo "$cpu" | sed 's/^\(sh.\)e\(.\)$/\1\2e/'`
;;
spur-*)
cpu=spur
;;
strongarm-* | thumb-*)
cpu=arm
;;
tx39-*)
cpu=mipstx39
;;
tx39el-*)
cpu=mipstx39el
;;
x64-*)
cpu=x86_64
;;
xscale-* | xscalee[bl]-*)
cpu=`echo "$cpu" | sed 's/^xscale/arm/'`
;;
+ arm64-* | aarch64le-*)
+ cpu=aarch64
+ ;;
# Recognize the canonical CPU Types that limit and/or modify the
# company names they are paired with.
cr16-*)
- os=${os:-elf}
+ basic_os=${basic_os:-elf}
;;
crisv32-* | etraxfs*-*)
cpu=crisv32
vendor=axis
;;
cris-* | etrax*-*)
cpu=cris
vendor=axis
;;
crx-*)
- os=${os:-elf}
+ basic_os=${basic_os:-elf}
;;
neo-tandem)
cpu=neo
vendor=tandem
;;
nse-tandem)
cpu=nse
vendor=tandem
;;
nsr-tandem)
cpu=nsr
vendor=tandem
;;
nsv-tandem)
cpu=nsv
vendor=tandem
;;
nsx-tandem)
cpu=nsx
vendor=tandem
;;
- s390-*)
- cpu=s390
- vendor=ibm
- ;;
- s390x-*)
- cpu=s390x
- vendor=ibm
+ mipsallegrexel-sony)
+ cpu=mipsallegrexel
+ vendor=sony
;;
tile*-*)
- os=${os:-linux-gnu}
+ basic_os=${basic_os:-linux-gnu}
;;
*)
# Recognize the canonical CPU types that are allowed with any
# company name.
case $cpu in
1750a | 580 \
| a29k \
| aarch64 | aarch64_be \
| abacus \
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] \
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] \
| alphapca5[67] | alpha64pca5[67] \
| am33_2.0 \
| amdgcn \
- | arc | arceb \
- | arm | arm[lb]e | arme[lb] | armv* \
+ | arc | arceb | arc32 | arc64 \
+ | arm | arm[lb]e | arme[lb] | armv* \
| avr | avr32 \
| asmjs \
| ba \
| be32 | be64 \
| bfin | bpf | bs2000 \
| c[123]* | c30 | [cjt]90 | c4x \
| c8051 | clipper | craynv | csky | cydra \
| d10v | d30v | dlx | dsp16xx \
| e2k | elxsi | epiphany \
| f30[01] | f700 | fido | fr30 | frv | ft32 | fx80 \
| h8300 | h8500 \
| hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
| hexagon \
| i370 | i*86 | i860 | i960 | ia16 | ia64 \
| ip2k | iq2000 \
| k1om \
| le32 | le64 \
| lm32 \
+ | loongarch32 | loongarch64 \
| m32c | m32r | m32rle \
| m5200 | m68000 | m680[012346]0 | m68360 | m683?2 | m68k \
| m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x \
| m88110 | m88k | maxq | mb | mcore | mep | metag \
| microblaze | microblazeel \
| mips | mipsbe | mipseb | mipsel | mipsle \
| mips16 \
| mips64 | mips64eb | mips64el \
| mips64octeon | mips64octeonel \
| mips64orion | mips64orionel \
| mips64r5900 | mips64r5900el \
| mips64vr | mips64vrel \
| mips64vr4100 | mips64vr4100el \
| mips64vr4300 | mips64vr4300el \
| mips64vr5000 | mips64vr5000el \
| mips64vr5900 | mips64vr5900el \
| mipsisa32 | mipsisa32el \
| mipsisa32r2 | mipsisa32r2el \
+ | mipsisa32r3 | mipsisa32r3el \
+ | mipsisa32r5 | mipsisa32r5el \
| mipsisa32r6 | mipsisa32r6el \
| mipsisa64 | mipsisa64el \
| mipsisa64r2 | mipsisa64r2el \
+ | mipsisa64r3 | mipsisa64r3el \
+ | mipsisa64r5 | mipsisa64r5el \
| mipsisa64r6 | mipsisa64r6el \
| mipsisa64sb1 | mipsisa64sb1el \
| mipsisa64sr71k | mipsisa64sr71kel \
| mipsr5900 | mipsr5900el \
| mipstx39 | mipstx39el \
| mmix \
| mn10200 | mn10300 \
| moxie \
| mt \
| msp430 \
| nds32 | nds32le | nds32be \
| nfp \
| nios | nios2 | nios2eb | nios2el \
| none | np1 | ns16k | ns32k | nvptx \
| open8 \
| or1k* \
| or32 \
| orion \
| picochip \
| pdp10 | pdp11 | pj | pjl | pn | power \
| powerpc | powerpc64 | powerpc64le | powerpcle | powerpcspe \
| pru \
| pyramid \
- | riscv | riscv32 | riscv64 \
+ | riscv | riscv32 | riscv32be | riscv64 | riscv64be \
| rl78 | romp | rs6000 | rx \
+ | s390 | s390x \
| score \
| sh | shl \
| sh[1234] | sh[24]a | sh[24]ae[lb] | sh[23]e | she[lb] | sh[lb]e \
| sh[1234]e[lb] | sh[12345][lb]e | sh[23]ele | sh64 | sh64le \
| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet \
| sparclite \
| sparcv8 | sparcv9 | sparcv9b | sparcv9v | sv1 | sx* \
| spu \
| tahoe \
+ | thumbv7* \
| tic30 | tic4x | tic54x | tic55x | tic6x | tic80 \
| tron \
| ubicom32 \
| v70 | v850 | v850e | v850e1 | v850es | v850e2 | v850e2v3 \
| vax \
| visium \
| w65 \
| wasm32 | wasm64 \
| we32k \
| x86 | x86_64 | xc16x | xgate | xps100 \
| xstormy16 | xtensa* \
| ymp \
| z8k | z80)
;;
*)
echo Invalid configuration \`"$1"\': machine \`"$cpu-$vendor"\' not recognized 1>&2
exit 1
;;
esac
;;
esac
# Here we canonicalize certain aliases for manufacturers.
case $vendor in
digital*)
vendor=dec
;;
commodore*)
vendor=cbm
;;
*)
;;
esac
# Decode manufacturer-specific aliases for certain operating systems.
-if [ x$os != x ]
+if test x$basic_os != x
then
+
+# First recognize some ad-hoc cases, or perhaps split kernel-os, or else just
+# set os.
+case $basic_os in
+ gnu/linux*)
+ kernel=linux
+ os=`echo "$basic_os" | sed -e 's|gnu/linux|gnu|'`
+ ;;
+ os2-emx)
+ kernel=os2
+ os=`echo "$basic_os" | sed -e 's|os2-emx|emx|'`
+ ;;
+ nto-qnx*)
+ kernel=nto
+ os=`echo "$basic_os" | sed -e 's|nto-qnx|qnx|'`
+ ;;
+ *-*)
+ # shellcheck disable=SC2162
+ saved_IFS=$IFS
+ IFS="-" read kernel os <<EOF
+$basic_os
+EOF
+ IFS=$saved_IFS
+ ;;
+ # Default OS when just kernel was specified
+ nto*)
+ kernel=nto
+ os=`echo "$basic_os" | sed -e 's|nto|qnx|'`
+ ;;
+ linux*)
+ kernel=linux
+ os=`echo "$basic_os" | sed -e 's|linux|gnu|'`
+ ;;
+ managarm*)
+ kernel=managarm
+ os=`echo "$basic_os" | sed -e 's|managarm|mlibc|'`
+ ;;
+ *)
+ kernel=
+ os=$basic_os
+ ;;
+esac
+
+# Now, normalize the OS (knowing we just have one component, it's not a kernel,
+# etc.)
case $os in
# First match some system type aliases that might get confused
# with valid system types.
# solaris* is a basic system type, with this one exception.
auroraux)
os=auroraux
;;
bluegene*)
os=cnk
;;
solaris1 | solaris1.*)
- os=`echo $os | sed -e 's|solaris1|sunos4|'`
+ os=`echo "$os" | sed -e 's|solaris1|sunos4|'`
;;
solaris)
os=solaris2
;;
unixware*)
os=sysv4.2uw
;;
- gnu/linux*)
- os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
- ;;
# es1800 is here to avoid being matched by es* (a different OS)
es1800*)
os=ose
;;
# Some version numbers need modification
chorusos*)
os=chorusos
;;
isc)
os=isc2.2
;;
sco6)
os=sco5v6
;;
sco5)
os=sco3.2v5
;;
sco4)
os=sco3.2v4
;;
sco3.2.[4-9]*)
- os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
- ;;
- sco3.2v[4-9]* | sco5v6*)
- # Don't forget version if it is 3.2v4 or newer.
+ os=`echo "$os" | sed -e 's/sco3.2./sco3.2v/'`
;;
- scout)
+ sco*v* | scout)
# Don't match below
;;
sco*)
os=sco3.2v2
;;
psos*)
os=psos
;;
- # Now accept the basic system types.
- # The portable systems comes first.
- # Each alternative MUST end in a * to match a version number.
- # sysv* is not here because it comes later, after sysvr4.
- gnu* | bsd* | mach* | minix* | genix* | ultrix* | irix* \
- | *vms* | esix* | aix* | cnk* | sunos | sunos[34]*\
- | hpux* | unos* | osf* | luna* | dgux* | auroraux* | solaris* \
- | sym* | kopensolaris* | plan9* \
- | amigaos* | amigados* | msdos* | newsos* | unicos* | aof* \
- | aos* | aros* | cloudabi* | sortix* | twizzler* \
- | nindy* | vxsim* | vxworks* | ebmon* | hms* | mvs* \
- | clix* | riscos* | uniplus* | iris* | isc* | rtu* | xenix* \
- | knetbsd* | mirbsd* | netbsd* \
- | bitrig* | openbsd* | solidbsd* | libertybsd* | os108* \
- | ekkobsd* | kfreebsd* | freebsd* | riscix* | lynxos* \
- | bosx* | nextstep* | cxux* | aout* | elf* | oabi* \
- | ptx* | coff* | ecoff* | winnt* | domain* | vsta* \
- | udi* | eabi* | lites* | ieee* | go32* | aux* | hcos* \
- | chorusrdb* | cegcc* | glidix* \
- | cygwin* | msys* | pe* | moss* | proelf* | rtems* \
- | midipix* | mingw32* | mingw64* | linux-gnu* | linux-android* \
- | linux-newlib* | linux-musl* | linux-uclibc* \
- | uxpv* | beos* | mpeix* | udk* | moxiebox* \
- | interix* | uwin* | mks* | rhapsody* | darwin* \
- | openstep* | oskit* | conix* | pw32* | nonstopux* \
- | storm-chaos* | tops10* | tenex* | tops20* | its* \
- | os2* | vos* | palmos* | uclinux* | nucleus* \
- | morphos* | superux* | rtmk* | windiss* \
- | powermax* | dnix* | nx6 | nx7 | sei* | dragonfly* \
- | skyos* | haiku* | rdos* | toppers* | drops* | es* \
- | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \
- | midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \
- | nsk* | powerunix* | genode*)
- # Remember, each alternative MUST END IN *, to match a version number.
- ;;
qnx*)
- case $cpu in
- x86 | i*86)
- ;;
- *)
- os=nto-$os
- ;;
- esac
+ os=qnx
;;
hiux*)
os=hiuxwe2
;;
- nto-qnx*)
- ;;
- nto*)
- os=`echo $os | sed -e 's|nto|nto-qnx|'`
- ;;
- sim | xray | os68k* | v88r* \
- | windows* | osx | abug | netware* | os9* \
- | macos* | mpw* | magic* | mmixware* | mon960* | lnews*)
- ;;
- linux-dietlibc)
- os=linux-dietlibc
- ;;
- linux*)
- os=`echo $os | sed -e 's|linux|linux-gnu|'`
- ;;
lynx*178)
os=lynxos178
;;
lynx*5)
os=lynxos5
;;
+ lynxos*)
+ # don't get caught up in next wildcard
+ ;;
lynx*)
os=lynxos
;;
- mac*)
+ mac[0-9]*)
os=`echo "$os" | sed -e 's|mac|macos|'`
;;
opened*)
os=openedition
;;
os400*)
os=os400
;;
sunos5*)
os=`echo "$os" | sed -e 's|sunos5|solaris2|'`
;;
sunos6*)
os=`echo "$os" | sed -e 's|sunos6|solaris3|'`
;;
wince*)
os=wince
;;
utek*)
os=bsd
;;
dynix*)
os=bsd
;;
acis*)
os=aos
;;
atheos*)
os=atheos
;;
syllable*)
os=syllable
;;
386bsd)
os=bsd
;;
ctix* | uts*)
os=sysv
;;
nova*)
os=rtmk-nova
;;
ns2)
os=nextstep2
;;
# Preserve the version number of sinix5.
sinix5.*)
- os=`echo $os | sed -e 's|sinix|sysv|'`
+ os=`echo "$os" | sed -e 's|sinix|sysv|'`
;;
sinix*)
os=sysv4
;;
tpf*)
os=tpf
;;
triton*)
os=sysv3
;;
oss*)
os=sysv3
;;
svr4*)
os=sysv4
;;
svr3)
os=sysv3
;;
sysvr4)
os=sysv4
;;
- # This must come after sysvr4.
- sysv*)
- ;;
ose*)
os=ose
;;
*mint | mint[0-9]* | *MiNT | MiNT[0-9]*)
os=mint
;;
- zvmoe)
- os=zvmoe
- ;;
dicos*)
os=dicos
;;
pikeos*)
# Until real need of OS specific support for
# particular features comes up, bare metal
# configurations are quite functional.
case $cpu in
arm*)
os=eabi
;;
*)
os=elf
;;
esac
;;
- nacl*)
- ;;
- ios)
- ;;
- none)
- ;;
- *-eabi)
- ;;
*)
- echo Invalid configuration \`"$1"\': system \`"$os"\' not recognized 1>&2
- exit 1
+ # No normalization, but not necessarily accepted, that comes below.
;;
esac
+
else
# Here we handle the default operating systems that come with various machines.
# The value should be what the vendor currently ships out the door with their
# machine or put another way, the most popular os provided with the machine.
# Note that if you're going to try to match "-MANUFACTURER" here (say,
# "-sun"), then you have to tell the case statement up towards the top
# that MANUFACTURER isn't an operating system. Otherwise, code above
# will signal an error saying that MANUFACTURER isn't an operating
# system, and we'll never get to this point.
+kernel=
case $cpu-$vendor in
score-*)
os=elf
;;
spu-*)
os=elf
;;
*-acorn)
os=riscix1.2
;;
arm*-rebel)
- os=linux
+ kernel=linux
+ os=gnu
;;
arm*-semi)
os=aout
;;
c4x-* | tic4x-*)
os=coff
;;
c8051-*)
os=elf
;;
clipper-intergraph)
os=clix
;;
hexagon-*)
os=elf
;;
tic54x-*)
os=coff
;;
tic55x-*)
os=coff
;;
tic6x-*)
os=coff
;;
# This must come before the *-dec entry.
pdp10-*)
os=tops20
;;
pdp11-*)
os=none
;;
*-dec | vax-*)
os=ultrix4.2
;;
m68*-apollo)
os=domain
;;
i386-sun)
os=sunos4.0.2
;;
m68000-sun)
os=sunos3
;;
m68*-cisco)
os=aout
;;
mep-*)
os=elf
;;
mips*-cisco)
os=elf
;;
mips*-*)
os=elf
;;
or32-*)
os=coff
;;
*-tti) # must be before sparc entry or we get the wrong os.
os=sysv3
;;
sparc-* | *-sun)
os=sunos4.1.1
;;
pru-*)
os=elf
;;
*-be)
os=beos
;;
*-ibm)
os=aix
;;
*-knuth)
os=mmixware
;;
*-wec)
os=proelf
;;
*-winbond)
os=proelf
;;
*-oki)
os=proelf
;;
*-hp)
os=hpux
;;
*-hitachi)
os=hiux
;;
i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
os=sysv
;;
*-cbm)
os=amigaos
;;
*-dg)
os=dgux
;;
*-dolphin)
os=sysv3
;;
m68k-ccur)
os=rtu
;;
m88k-omron*)
os=luna
;;
*-next)
os=nextstep
;;
*-sequent)
os=ptx
;;
*-crds)
os=unos
;;
*-ns)
os=genix
;;
i370-*)
os=mvs
;;
*-gould)
os=sysv
;;
*-highlevel)
os=bsd
;;
*-encore)
os=bsd
;;
*-sgi)
os=irix
;;
*-siemens)
os=sysv4
;;
*-masscomp)
os=rtu
;;
f30[01]-fujitsu | f700-fujitsu)
os=uxpv
;;
*-rom68k)
os=coff
;;
*-*bug)
os=coff
;;
*-apple)
os=macos
;;
*-atari*)
os=mint
;;
*-wrs)
os=vxworks
;;
*)
os=none
;;
esac
+
fi
+# Now, validate our (potentially fixed-up) OS.
+case $os in
+ # Sometimes we do "kernel-libc", so those need to count as OSes.
+ musl* | newlib* | relibc* | uclibc*)
+ ;;
+ # Likewise for "kernel-abi"
+ eabi* | gnueabi*)
+ ;;
+ # VxWorks passes extra cpu info in the 4th filed.
+ simlinux | simwindows | spe)
+ ;;
+ # Now accept the basic system types.
+ # The portable systems comes first.
+ # Each alternative MUST end in a * to match a version number.
+ gnu* | android* | bsd* | mach* | minix* | genix* | ultrix* | irix* \
+ | *vms* | esix* | aix* | cnk* | sunos | sunos[34]* \
+ | hpux* | unos* | osf* | luna* | dgux* | auroraux* | solaris* \
+ | sym* | plan9* | psp* | sim* | xray* | os68k* | v88r* \
+ | hiux* | abug | nacl* | netware* | windows* \
+ | os9* | macos* | osx* | ios* \
+ | mpw* | magic* | mmixware* | mon960* | lnews* \
+ | amigaos* | amigados* | msdos* | newsos* | unicos* | aof* \
+ | aos* | aros* | cloudabi* | sortix* | twizzler* \
+ | nindy* | vxsim* | vxworks* | ebmon* | hms* | mvs* \
+ | clix* | riscos* | uniplus* | iris* | isc* | rtu* | xenix* \
+ | mirbsd* | netbsd* | dicos* | openedition* | ose* \
+ | bitrig* | openbsd* | secbsd* | solidbsd* | libertybsd* | os108* \
+ | ekkobsd* | freebsd* | riscix* | lynxos* | os400* \
+ | bosx* | nextstep* | cxux* | aout* | elf* | oabi* \
+ | ptx* | coff* | ecoff* | winnt* | domain* | vsta* \
+ | udi* | lites* | ieee* | go32* | aux* | hcos* \
+ | chorusrdb* | cegcc* | glidix* | serenity* \
+ | cygwin* | msys* | pe* | moss* | proelf* | rtems* \
+ | midipix* | mingw32* | mingw64* | mint* \
+ | uxpv* | beos* | mpeix* | udk* | moxiebox* \
+ | interix* | uwin* | mks* | rhapsody* | darwin* \
+ | openstep* | oskit* | conix* | pw32* | nonstopux* \
+ | storm-chaos* | tops10* | tenex* | tops20* | its* \
+ | os2* | vos* | palmos* | uclinux* | nucleus* | morphos* \
+ | scout* | superux* | sysv* | rtmk* | tpf* | windiss* \
+ | powermax* | dnix* | nx6 | nx7 | sei* | dragonfly* \
+ | skyos* | haiku* | rdos* | toppers* | drops* | es* \
+ | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \
+ | midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \
+ | nsk* | powerunix* | genode* | zvmoe* | qnx* | emx* | zephyr* \
+ | fiwix* | mlibc* )
+ ;;
+ # This one is extra strict with allowed versions
+ sco3.2v2 | sco3.2v[4-9]* | sco5v6*)
+ # Don't forget version if it is 3.2v4 or newer.
+ ;;
+ none)
+ ;;
+ kernel* )
+ # Restricted further below
+ ;;
+ *)
+ echo Invalid configuration \`"$1"\': OS \`"$os"\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+
+# As a final step for OS-related things, validate the OS-kernel combination
+# (given a valid OS), if there is a kernel.
+case $kernel-$os in
+ linux-gnu* | linux-dietlibc* | linux-android* | linux-newlib* \
+ | linux-musl* | linux-relibc* | linux-uclibc* | linux-mlibc* )
+ ;;
+ uclinux-uclibc* )
+ ;;
+ managarm-mlibc* | managarm-kernel* )
+ ;;
+ -dietlibc* | -newlib* | -musl* | -relibc* | -uclibc* | -mlibc* )
+ # These are just libc implementations, not actual OSes, and thus
+ # require a kernel.
+ echo "Invalid configuration \`$1': libc \`$os' needs explicit kernel." 1>&2
+ exit 1
+ ;;
+ -kernel* )
+ echo "Invalid configuration \`$1': \`$os' needs explicit kernel." 1>&2
+ exit 1
+ ;;
+ *-kernel* )
+ echo "Invalid configuration \`$1': \`$kernel' does not support \`$os'." 1>&2
+ exit 1
+ ;;
+ kfreebsd*-gnu* | kopensolaris*-gnu*)
+ ;;
+ vxworks-simlinux | vxworks-simwindows | vxworks-spe)
+ ;;
+ nto-qnx*)
+ ;;
+ os2-emx)
+ ;;
+ *-eabi* | *-gnueabi*)
+ ;;
+ -*)
+ # Blank kernel with real OS is always fine.
+ ;;
+ *-*)
+ echo "Invalid configuration \`$1': Kernel \`$kernel' not known to work with OS \`$os'." 1>&2
+ exit 1
+ ;;
+esac
+
# Here we handle the case where we know the os, and the CPU type, but not the
# manufacturer. We pick the logical manufacturer.
case $vendor in
unknown)
- case $os in
- riscix*)
+ case $cpu-$os in
+ *-riscix*)
vendor=acorn
;;
- sunos*)
+ *-sunos*)
vendor=sun
;;
- cnk*|-aix*)
+ *-cnk* | *-aix*)
vendor=ibm
;;
- beos*)
+ *-beos*)
vendor=be
;;
- hpux*)
+ *-hpux*)
vendor=hp
;;
- mpeix*)
+ *-mpeix*)
vendor=hp
;;
- hiux*)
+ *-hiux*)
vendor=hitachi
;;
- unos*)
+ *-unos*)
vendor=crds
;;
- dgux*)
+ *-dgux*)
vendor=dg
;;
- luna*)
+ *-luna*)
vendor=omron
;;
- genix*)
+ *-genix*)
vendor=ns
;;
- clix*)
+ *-clix*)
vendor=intergraph
;;
- mvs* | opened*)
+ *-mvs* | *-opened*)
+ vendor=ibm
+ ;;
+ *-os400*)
vendor=ibm
;;
- os400*)
+ s390-* | s390x-*)
vendor=ibm
;;
- ptx*)
+ *-ptx*)
vendor=sequent
;;
- tpf*)
+ *-tpf*)
vendor=ibm
;;
- vxsim* | vxworks* | windiss*)
+ *-vxsim* | *-vxworks* | *-windiss*)
vendor=wrs
;;
- aux*)
+ *-aux*)
vendor=apple
;;
- hms*)
+ *-hms*)
vendor=hitachi
;;
- mpw* | macos*)
+ *-mpw* | *-macos*)
vendor=apple
;;
- *mint | mint[0-9]* | *MiNT | MiNT[0-9]*)
+ *-*mint | *-mint[0-9]* | *-*MiNT | *-MiNT[0-9]*)
vendor=atari
;;
- vos*)
+ *-vos*)
vendor=stratus
;;
esac
;;
esac
-echo "$cpu-$vendor-$os"
+echo "$cpu-$vendor-${kernel:+$kernel-}$os"
exit
# Local variables:
# eval: (add-hook 'before-save-hook 'time-stamp)
# time-stamp-start: "timestamp='"
# time-stamp-format: "%:y-%02m-%02d"
# time-stamp-end: "'"
# End:
diff --git a/crypto/openssh/configure.ac b/crypto/openssh/configure.ac
index 56da82b81756..c5060c59ddf4 100644
--- a/crypto/openssh/configure.ac
+++ b/crypto/openssh/configure.ac
@@ -1,5709 +1,5749 @@
#
# Copyright (c) 1999-2004 Damien Miller
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
AC_INIT([OpenSSH], [Portable], [openssh-unix-dev@mindrot.org])
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_SRCDIR([ssh.c])
# Check for stale configure as early as possible.
for i in $srcdir/configure.ac $srcdir/m4/*.m4; do
if test "$i" -nt "$srcdir/configure"; then
AC_MSG_ERROR([$i newer than configure, run autoreconf])
fi
done
AC_LANG([C])
AC_CONFIG_HEADERS([config.h])
AC_PROG_CC([cc gcc clang])
# 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
# Checks for programs.
AC_PROG_AWK
AC_PROG_CPP
AC_PROG_RANLIB
AC_PROG_INSTALL
AC_PROG_EGREP
AC_PROG_MKDIR_P
AC_CHECK_TOOLS([AR], [ar])
AC_PATH_PROG([CAT], [cat])
AC_PATH_PROG([KILL], [kill])
AC_PATH_PROG([SED], [sed])
AC_PATH_PROG([TEST_MINUS_S_SH], [bash])
AC_PATH_PROG([TEST_MINUS_S_SH], [ksh])
AC_PATH_PROG([TEST_MINUS_S_SH], [sh])
AC_PATH_PROG([SH], [bash])
AC_PATH_PROG([SH], [ksh])
AC_PATH_PROG([SH], [sh])
AC_PATH_PROG([GROFF], [groff])
AC_PATH_PROG([NROFF], [nroff awf])
AC_PATH_PROG([MANDOC], [mandoc])
AC_PATH_TOOL([PKGCONFIG], [pkg-config], [no])
AC_SUBST([TEST_SHELL], [sh])
dnl select manpage formatter to be used to build "cat" format pages.
if test "x$MANDOC" != "x" ; then
MANFMT="$MANDOC"
elif test "x$NROFF" != "x" ; then
MANFMT="$NROFF -mandoc"
elif test "x$GROFF" != "x" ; then
MANFMT="$GROFF -mandoc -Tascii"
else
AC_MSG_WARN([no manpage formatter found])
MANFMT="false"
fi
AC_SUBST([MANFMT])
dnl for buildpkg.sh
AC_PATH_PROG([PATH_GROUPADD_PROG], [groupadd], [groupadd],
[/usr/sbin${PATH_SEPARATOR}/etc])
AC_PATH_PROG([PATH_USERADD_PROG], [useradd], [useradd],
[/usr/sbin${PATH_SEPARATOR}/etc])
AC_CHECK_PROG([MAKE_PACKAGE_SUPPORTED], [pkgmk], [yes], [no])
if test -x /sbin/sh; then
AC_SUBST([STARTUP_SCRIPT_SHELL], [/sbin/sh])
else
AC_SUBST([STARTUP_SCRIPT_SHELL], [/bin/sh])
fi
# System features
AC_SYS_LARGEFILE
if test -z "$AR" ; then
AC_MSG_ERROR([*** 'ar' missing, please install or fix your \$PATH ***])
fi
AC_PATH_PROG([PATH_PASSWD_PROG], [passwd])
if test ! -z "$PATH_PASSWD_PROG" ; then
AC_DEFINE_UNQUOTED([_PATH_PASSWD_PROG], ["$PATH_PASSWD_PROG"],
[Full path of your "passwd" program])
fi
dnl Since autoconf doesn't support it very well, we no longer allow users to
dnl override LD, however keeping the hook here for now in case there's a use
dnl use case we overlooked and someone needs to re-enable it. Unless a good
dnl reason is found we'll be removing this in future.
LD="$CC"
AC_SUBST([LD])
AC_C_INLINE
AC_CHECK_DECL([LLONG_MAX], [have_llong_max=1], , [#include <limits.h>])
AC_CHECK_DECL([LONG_LONG_MAX], [have_long_long_max=1], , [#include <limits.h>])
AC_CHECK_DECL([SYSTR_POLICY_KILL], [have_systr_policy_kill=1], , [
#include <sys/types.h>
#include <sys/param.h>
#include <dev/systrace.h>
])
AC_CHECK_DECL([RLIMIT_NPROC],
[AC_DEFINE([HAVE_RLIMIT_NPROC], [], [sys/resource.h has RLIMIT_NPROC])], , [
#include <sys/types.h>
#include <sys/resource.h>
])
AC_CHECK_DECL([PR_SET_NO_NEW_PRIVS], [have_linux_no_new_privs=1], , [
#include <sys/types.h>
#include <linux/prctl.h>
])
openssl=yes
+openssl_bin=openssl
AC_ARG_WITH([openssl],
[ --without-openssl Disable use of OpenSSL; use only limited internal crypto **EXPERIMENTAL** ],
[ if test "x$withval" = "xno" ; then
openssl=no
+ openssl_bin=""
fi
]
)
AC_MSG_CHECKING([whether OpenSSL will be used for cryptography])
if test "x$openssl" = "xyes" ; then
AC_MSG_RESULT([yes])
AC_DEFINE_UNQUOTED([WITH_OPENSSL], [1], [use libcrypto for cryptography])
else
AC_MSG_RESULT([no])
fi
use_stack_protector=1
use_toolchain_hardening=1
AC_ARG_WITH([stackprotect],
[ --without-stackprotect Don't use compiler's stack protection], [
if test "x$withval" = "xno"; then
use_stack_protector=0
fi ])
AC_ARG_WITH([hardening],
[ --without-hardening Don't use toolchain hardening flags], [
if test "x$withval" = "xno"; then
use_toolchain_hardening=0
fi ])
# We use -Werror for the tests only so that we catch warnings like "this is
# on by default" for things like -fPIE.
AC_MSG_CHECKING([if $CC supports -Werror])
saved_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -Werror"
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[int main(void) { return 0; }]])],
[ AC_MSG_RESULT([yes])
WERROR="-Werror"],
[ AC_MSG_RESULT([no])
WERROR="" ]
)
CFLAGS="$saved_CFLAGS"
if test "$GCC" = "yes" || test "$GCC" = "egcs"; then
+ AC_MSG_CHECKING([gcc version])
+ GCC_VER=`$CC -v 2>&1 | $AWK '/gcc version /{print $3}'`
+ case "$GCC_VER" in
+ 1.*) no_attrib_nonnull=1 ;;
+ 2.8* | 2.9*)
+ no_attrib_nonnull=1
+ ;;
+ 2.*) no_attrib_nonnull=1 ;;
+ *) ;;
+ esac
+ AC_MSG_RESULT([$GCC_VER])
+
+ AC_MSG_CHECKING([clang version])
+ CLANG_VER=`$CC -v 2>&1 | $AWK '/clang version /{print $3}'`
+ AC_MSG_RESULT([$CLANG_VER])
+
OSSH_CHECK_CFLAG_COMPILE([-pipe])
OSSH_CHECK_CFLAG_COMPILE([-Wunknown-warning-option])
OSSH_CHECK_CFLAG_COMPILE([-Wno-error=format-truncation])
OSSH_CHECK_CFLAG_COMPILE([-Qunused-arguments])
OSSH_CHECK_CFLAG_COMPILE([-Wall])
OSSH_CHECK_CFLAG_COMPILE([-Wextra])
OSSH_CHECK_CFLAG_COMPILE([-Wpointer-arith])
OSSH_CHECK_CFLAG_COMPILE([-Wuninitialized])
OSSH_CHECK_CFLAG_COMPILE([-Wsign-compare])
OSSH_CHECK_CFLAG_COMPILE([-Wformat-security])
OSSH_CHECK_CFLAG_COMPILE([-Wsizeof-pointer-memaccess])
OSSH_CHECK_CFLAG_COMPILE([-Wpointer-sign], [-Wno-pointer-sign])
OSSH_CHECK_CFLAG_COMPILE([-Wunused-parameter], [-Wno-unused-parameter])
OSSH_CHECK_CFLAG_COMPILE([-Wunused-result], [-Wno-unused-result])
OSSH_CHECK_CFLAG_COMPILE([-Wimplicit-fallthrough])
OSSH_CHECK_CFLAG_COMPILE([-Wmisleading-indentation])
OSSH_CHECK_CFLAG_COMPILE([-Wbitwise-instead-of-logical])
OSSH_CHECK_CFLAG_COMPILE([-fno-strict-aliasing])
if test "x$use_toolchain_hardening" = "x1"; then
OSSH_CHECK_CFLAG_COMPILE([-mretpoline]) # clang
OSSH_CHECK_LDFLAG_LINK([-Wl,-z,retpolineplt])
OSSH_CHECK_CFLAG_COMPILE([-D_FORTIFY_SOURCE=2])
OSSH_CHECK_LDFLAG_LINK([-Wl,-z,relro])
OSSH_CHECK_LDFLAG_LINK([-Wl,-z,now])
OSSH_CHECK_LDFLAG_LINK([-Wl,-z,noexecstack])
# NB. -ftrapv expects certain support functions to be present in
# the compiler library (libgcc or similar) to detect integer operations
# that can overflow. We must check that the result of enabling it
# actually links. The test program compiled/linked includes a number
# of integer operations that should exercise this.
OSSH_CHECK_CFLAG_LINK([-ftrapv])
- OSSH_CHECK_CFLAG_COMPILE([-fzero-call-used-regs=all])
+ # clang 15 seems to have a bug in -fzero-call-used-regs=all. See
+ # https://bugzilla.mindrot.org/show_bug.cgi?id=3475 and
+ # https://github.com/llvm/llvm-project/issues/59242
+ case "$CLANG_VER" in
+ 15.*) OSSH_CHECK_CFLAG_COMPILE([-fzero-call-used-regs=used]) ;;
+ *) OSSH_CHECK_CFLAG_COMPILE([-fzero-call-used-regs=all]) ;;
+ esac
OSSH_CHECK_CFLAG_COMPILE([-ftrivial-auto-var-init=zero])
fi
- AC_MSG_CHECKING([gcc version])
- GCC_VER=`$CC -v 2>&1 | $AWK '/gcc version /{print $3}'`
- case $GCC_VER in
- 1.*) no_attrib_nonnull=1 ;;
- 2.8* | 2.9*)
- no_attrib_nonnull=1
- ;;
- 2.*) no_attrib_nonnull=1 ;;
- *) ;;
- esac
- AC_MSG_RESULT([$GCC_VER])
AC_MSG_CHECKING([if $CC accepts -fno-builtin-memset])
saved_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -fno-builtin-memset"
AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include <string.h> ]],
[[ char b[10]; memset(b, 0, sizeof(b)); ]])],
[ AC_MSG_RESULT([yes]) ],
[ AC_MSG_RESULT([no])
CFLAGS="$saved_CFLAGS" ]
)
# -fstack-protector-all doesn't always work for some GCC versions
# and/or platforms, so we test if we can. If it's not supported
# on a given platform gcc will emit a warning so we use -Werror.
if test "x$use_stack_protector" = "x1"; then
for t in -fstack-protector-strong -fstack-protector-all \
-fstack-protector; do
AC_MSG_CHECKING([if $CC supports $t])
saved_CFLAGS="$CFLAGS"
saved_LDFLAGS="$LDFLAGS"
CFLAGS="$CFLAGS $t -Werror"
LDFLAGS="$LDFLAGS $t -Werror"
AC_LINK_IFELSE(
[AC_LANG_PROGRAM([[
#include <stdio.h>
int func (int t) {char b[100]; snprintf(b,sizeof b,"%d",t); return t;}
]],
[[
char x[256];
snprintf(x, sizeof(x), "XXX%d", func(1));
]])],
[ AC_MSG_RESULT([yes])
CFLAGS="$saved_CFLAGS $t"
LDFLAGS="$saved_LDFLAGS $t"
AC_MSG_CHECKING([if $t works])
AC_RUN_IFELSE(
[AC_LANG_PROGRAM([[
#include <stdio.h>
int func (int t) {char b[100]; snprintf(b,sizeof b,"%d",t); return t;}
]],
[[
char x[256];
snprintf(x, sizeof(x), "XXX%d", func(1));
]])],
[ AC_MSG_RESULT([yes])
break ],
[ AC_MSG_RESULT([no]) ],
[ AC_MSG_WARN([cross compiling: cannot test])
break ]
)
],
[ AC_MSG_RESULT([no]) ]
)
CFLAGS="$saved_CFLAGS"
LDFLAGS="$saved_LDFLAGS"
done
fi
if test -z "$have_llong_max"; then
# retry LLONG_MAX with -std=gnu99, needed on some Linuxes
unset ac_cv_have_decl_LLONG_MAX
saved_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -std=gnu99"
AC_CHECK_DECL([LLONG_MAX],
[have_llong_max=1],
[CFLAGS="$saved_CFLAGS"],
[#include <limits.h>]
)
fi
fi
AC_MSG_CHECKING([if compiler allows __attribute__ on return types])
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM([[
#include <stdlib.h>
__attribute__((__unused__)) static void foo(void){return;}]],
[[ exit(0); ]])],
[ AC_MSG_RESULT([yes]) ],
[ AC_MSG_RESULT([no])
AC_DEFINE(NO_ATTRIBUTE_ON_RETURN_TYPE, 1,
[compiler does not accept __attribute__ on return types]) ]
)
AC_MSG_CHECKING([if compiler allows __attribute__ prototype args])
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM([[
#include <stdlib.h>
typedef void foo(const char *, ...) __attribute__((format(printf, 1, 2)));]],
[[ exit(0); ]])],
[ AC_MSG_RESULT([yes]) ],
[ AC_MSG_RESULT([no])
AC_DEFINE(NO_ATTRIBUTE_ON_PROTOTYPE_ARGS, 1,
[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
AC_ARG_WITH([rpath],
[ --without-rpath Disable auto-added -R linker paths],
[
if test "x$withval" = "xno" ; then
rpath_opt=""
elif test "x$withval" = "xyes" ; then
rpath_opt="-R"
else
rpath_opt="$withval"
fi
]
)
# Allow user to specify flags
AC_ARG_WITH([cflags],
[ --with-cflags Specify additional flags to pass to compiler],
[
if test -n "$withval" && test "x$withval" != "xno" && \
test "x${withval}" != "xyes"; then
CFLAGS="$CFLAGS $withval"
fi
]
)
AC_ARG_WITH([cflags-after],
[ --with-cflags-after Specify additional flags to pass to compiler after configure],
[
if test -n "$withval" && test "x$withval" != "xno" && \
test "x${withval}" != "xyes"; then
CFLAGS_AFTER="$withval"
fi
]
)
AC_ARG_WITH([cppflags],
[ --with-cppflags Specify additional flags to pass to preprocessor] ,
[
if test -n "$withval" && test "x$withval" != "xno" && \
test "x${withval}" != "xyes"; then
CPPFLAGS="$CPPFLAGS $withval"
fi
]
)
AC_ARG_WITH([ldflags],
[ --with-ldflags Specify additional flags to pass to linker],
[
if test -n "$withval" && test "x$withval" != "xno" && \
test "x${withval}" != "xyes"; then
LDFLAGS="$LDFLAGS $withval"
fi
]
)
AC_ARG_WITH([ldflags-after],
[ --with-ldflags-after Specify additional flags to pass to linker after configure],
[
if test -n "$withval" && test "x$withval" != "xno" && \
test "x${withval}" != "xyes"; then
LDFLAGS_AFTER="$withval"
fi
]
)
AC_ARG_WITH([libs],
[ --with-libs Specify additional libraries to link with],
[
if test -n "$withval" && test "x$withval" != "xno" && \
test "x${withval}" != "xyes"; then
LIBS="$LIBS $withval"
fi
]
)
AC_ARG_WITH([Werror],
[ --with-Werror Build main code with -Werror],
[
if test -n "$withval" && test "x$withval" != "xno"; then
werror_flags="-Werror"
if test "x${withval}" != "xyes"; then
werror_flags="$withval"
fi
fi
]
)
+dnl On some old platforms, sys/stat.h requires sys/types.h, but autoconf-2.71's
+dnl AC_CHECK_INCLUDES_DEFAULT checks for them in the opposite order. If we
+dnl haven't detected it, recheck.
+if test "x$ac_cv_header_sys_stat_h" != "xyes"; then
+ unset ac_cv_header_sys_stat_h
+ AC_CHECK_HEADERS([sys/stat.h])
+fi
+
AC_CHECK_HEADERS([ \
blf.h \
bstring.h \
crypt.h \
crypto/sha2.h \
dirent.h \
endian.h \
elf.h \
err.h \
features.h \
fcntl.h \
floatingpoint.h \
fnmatch.h \
getopt.h \
glob.h \
ia.h \
iaf.h \
ifaddrs.h \
inttypes.h \
langinfo.h \
limits.h \
locale.h \
login.h \
maillock.h \
ndir.h \
net/if_tun.h \
netdb.h \
netgroup.h \
pam/pam_appl.h \
paths.h \
poll.h \
pty.h \
readpassphrase.h \
rpc/types.h \
security/pam_appl.h \
sha2.h \
shadow.h \
stddef.h \
stdint.h \
string.h \
strings.h \
sys/bitypes.h \
sys/byteorder.h \
sys/bsdtty.h \
sys/cdefs.h \
sys/dir.h \
sys/file.h \
sys/mman.h \
sys/label.h \
sys/ndir.h \
sys/param.h \
sys/poll.h \
sys/prctl.h \
sys/procctl.h \
sys/pstat.h \
sys/ptrace.h \
sys/random.h \
sys/select.h \
- sys/stat.h \
sys/stream.h \
sys/stropts.h \
sys/strtio.h \
sys/statvfs.h \
sys/sysmacros.h \
sys/time.h \
sys/timers.h \
sys/vfs.h \
time.h \
tmpdir.h \
ttyent.h \
ucred.h \
unistd.h \
usersec.h \
util.h \
utime.h \
utmp.h \
utmpx.h \
vis.h \
wchar.h \
])
# On some platforms (eg SunOS4) sys/audit.h requires sys/[time|types|label.h]
# to be included first.
AC_CHECK_HEADERS([sys/audit.h], [], [], [
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
#endif
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#ifdef HAVE_SYS_LABEL_H
# include <sys/label.h>
#endif
])
# sys/capsicum.h requires sys/types.h
AC_CHECK_HEADERS([sys/capsicum.h capsicum_helpers.h], [], [], [
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
])
AC_MSG_CHECKING([for caph_cache_tzdata])
AC_LINK_IFELSE(
[AC_LANG_PROGRAM([[ #include <capsicum_helpers.h> ]],
[[caph_cache_tzdata();]])],
[
AC_MSG_RESULT([yes])
AC_DEFINE([HAVE_CAPH_CACHE_TZDATA], [1],
[Define if you have caph_cache_tzdata])
],
[ AC_MSG_RESULT([no]) ]
)
# net/route.h requires sys/socket.h and sys/types.h.
# sys/sysctl.h also requires sys/param.h
AC_CHECK_HEADERS([net/route.h sys/sysctl.h], [], [], [
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#include <sys/param.h>
#include <sys/socket.h>
])
# lastlog.h requires sys/time.h to be included first on Solaris
AC_CHECK_HEADERS([lastlog.h], [], [], [
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
#endif
])
# sys/ptms.h requires sys/stream.h to be included first on Solaris
AC_CHECK_HEADERS([sys/ptms.h], [], [], [
#ifdef HAVE_SYS_STREAM_H
# include <sys/stream.h>
#endif
])
# login_cap.h requires sys/types.h on NetBSD
AC_CHECK_HEADERS([login_cap.h], [], [], [
#include <sys/types.h>
])
# older BSDs need sys/param.h before sys/mount.h
AC_CHECK_HEADERS([sys/mount.h], [], [], [
#include <sys/param.h>
])
# Android requires sys/socket.h to be included before sys/un.h
AC_CHECK_HEADERS([sys/un.h], [], [], [
#include <sys/types.h>
#include <sys/socket.h>
])
# Messages for features tested for in target-specific section
SIA_MSG="no"
SPC_MSG="no"
SP_MSG="no"
SPP_MSG="no"
# Support for Solaris/Illumos privileges (this test is used by both
# the --with-solaris-privs option and --with-sandbox=solaris).
SOLARIS_PRIVS="no"
# Check for some target-specific stuff
case "$host" in
*-*-aix*)
# Some versions of VAC won't allow macro redefinitions at
# -qlanglevel=ansi, and autoconf 2.60 sometimes insists on using that
# particularly with older versions of vac or xlc.
# It also throws errors about null macro arguments, but these are
# not fatal.
AC_MSG_CHECKING([if compiler allows macro redefinitions])
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM([[
#define testmacro foo
#define testmacro bar]],
[[ exit(0); ]])],
[ AC_MSG_RESULT([yes]) ],
[ AC_MSG_RESULT([no])
CC="`echo $CC | sed 's/-qlanglvl\=ansi//g'`"
CFLAGS="`echo $CFLAGS | sed 's/-qlanglvl\=ansi//g'`"
CPPFLAGS="`echo $CPPFLAGS | sed 's/-qlanglvl\=ansi//g'`"
]
)
AC_MSG_CHECKING([how to specify blibpath for linker ($LD)])
if (test -z "$blibpath"); then
blibpath="/usr/lib:/lib"
fi
saved_LDFLAGS="$LDFLAGS"
if test "$GCC" = "yes"; then
flags="-Wl,-blibpath: -Wl,-rpath, -blibpath:"
else
flags="-blibpath: -Wl,-blibpath: -Wl,-rpath,"
fi
for tryflags in $flags ;do
if (test -z "$blibflags"); then
LDFLAGS="$saved_LDFLAGS $tryflags$blibpath"
AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
[blibflags=$tryflags], [])
fi
done
if (test -z "$blibflags"); then
AC_MSG_RESULT([not found])
AC_MSG_ERROR([*** must be able to specify blibpath on AIX - check config.log])
else
AC_MSG_RESULT([$blibflags])
fi
LDFLAGS="$saved_LDFLAGS"
dnl Check for authenticate. Might be in libs.a on older AIXes
AC_CHECK_FUNC([authenticate], [AC_DEFINE([WITH_AIXAUTHENTICATE], [1],
[Define if you want to enable AIX4's authenticate function])],
[AC_CHECK_LIB([s], [authenticate],
[ AC_DEFINE([WITH_AIXAUTHENTICATE])
LIBS="$LIBS -ls"
])
])
dnl Check for various auth function declarations in headers.
AC_CHECK_DECLS([authenticate, loginrestrictions, loginsuccess,
passwdexpired, setauthdb], , , [#include <usersec.h>])
dnl Check if loginfailed is declared and takes 4 arguments (AIX >= 5.2)
AC_CHECK_DECLS([loginfailed],
[AC_MSG_CHECKING([if loginfailed takes 4 arguments])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <usersec.h> ]],
[[ (void)loginfailed("user","host","tty",0); ]])],
[AC_MSG_RESULT([yes])
AC_DEFINE([AIX_LOGINFAILED_4ARG], [1],
[Define if your AIX loginfailed() function
takes 4 arguments (AIX >= 5.2)])], [AC_MSG_RESULT([no])
])],
[],
[#include <usersec.h>]
)
AC_CHECK_FUNCS([getgrset setauthdb])
AC_CHECK_DECL([F_CLOSEM],
AC_DEFINE([HAVE_FCNTL_CLOSEM], [1], [Use F_CLOSEM fcntl for closefrom]),
[],
[ #include <limits.h>
#include <fcntl.h> ]
)
check_for_aix_broken_getaddrinfo=1
AC_DEFINE([SETEUID_BREAKS_SETUID], [1],
[Define if your platform breaks doing a seteuid before a setuid])
AC_DEFINE([BROKEN_SETREUID], [1], [Define if your setreuid() is broken])
AC_DEFINE([BROKEN_SETREGID], [1], [Define if your setregid() is broken])
dnl AIX handles lastlog as part of its login message
AC_DEFINE([DISABLE_LASTLOG], [1], [Define if you don't want to use lastlog])
AC_DEFINE([LOGIN_NEEDS_UTMPX], [1],
[Some systems need a utmpx entry for /bin/login to work])
AC_DEFINE([SPT_TYPE], [SPT_REUSEARGV],
[Define to a Set Process Title type if your system is
supported by bsd-setproctitle.c])
AC_DEFINE([SSHPAM_CHAUTHTOK_NEEDS_RUID], [1],
[AIX 5.2 and 5.3 (and presumably newer) require this])
AC_DEFINE([PTY_ZEROREAD], [1], [read(1) can return 0 for a non-closed fd])
AC_DEFINE([PLATFORM_SYS_DIR_UID], 2, [System dirs owned by bin (uid 2)])
AC_DEFINE([BROKEN_STRNDUP], 1, [strndup broken, see APAR IY61211])
AC_DEFINE([BROKEN_STRNLEN], 1, [strnlen broken, see APAR IY62551])
;;
*-*-android*)
AC_DEFINE([DISABLE_UTMP], [1], [Define if you don't want to use utmp])
AC_DEFINE([DISABLE_WTMP], [1], [Define if you don't want to use wtmp])
;;
*-*-cygwin*)
LIBS="$LIBS /usr/lib/textreadmode.o"
AC_DEFINE([HAVE_CYGWIN], [1], [Define if you are on Cygwin])
AC_DEFINE([USE_PIPES], [1], [Use PIPES instead of a socketpair()])
AC_DEFINE([NO_UID_RESTORATION_TEST], [1],
[Define to disable UID restoration test])
AC_DEFINE([DISABLE_SHADOW], [1],
[Define if you want to disable shadow passwords])
AC_DEFINE([NO_X11_UNIX_SOCKETS], [1],
[Define if X11 doesn't support AF_UNIX sockets on that system])
AC_DEFINE([DISABLE_FD_PASSING], [1],
[Define if your platform needs to skip post auth
file descriptor passing])
AC_DEFINE([SSH_IOBUFSZ], [65535], [Windows is sensitive to read buffer size])
AC_DEFINE([FILESYSTEM_NO_BACKSLASH], [1], [File names may not contain backslash characters])
# Cygwin defines optargs, optargs as declspec(dllimport) for historical
# reasons which cause compile warnings, so we disable those warnings.
OSSH_CHECK_CFLAG_COMPILE([-Wno-attributes])
;;
*-*-dgux*)
AC_DEFINE([IP_TOS_IS_BROKEN], [1],
[Define if your system choked on IP TOS setting])
AC_DEFINE([SETEUID_BREAKS_SETUID])
AC_DEFINE([BROKEN_SETREUID])
AC_DEFINE([BROKEN_SETREGID])
;;
*-*-darwin*)
use_pie=auto
AC_MSG_CHECKING([if we have working getaddrinfo])
AC_RUN_IFELSE([AC_LANG_SOURCE([[
#include <mach-o/dyld.h>
#include <stdlib.h>
-main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16))
+int main(void) { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16))
exit(0);
else
exit(1);
}
]])],
[AC_MSG_RESULT([working])],
[AC_MSG_RESULT([buggy])
AC_DEFINE([BROKEN_GETADDRINFO], [1],
[getaddrinfo is broken (if present)])
],
[AC_MSG_RESULT([assume it is working])])
AC_DEFINE([SETEUID_BREAKS_SETUID])
AC_DEFINE([BROKEN_SETREUID])
AC_DEFINE([BROKEN_SETREGID])
AC_DEFINE([BROKEN_GLOB], [1], [OS X glob does not do what we expect])
AC_DEFINE_UNQUOTED([BIND_8_COMPAT], [1],
[Define if your resolver libs need this for getrrsetbyname])
AC_DEFINE([SSH_TUN_FREEBSD], [1], [Open tunnel devices the FreeBSD way])
AC_DEFINE([SSH_TUN_COMPAT_AF], [1],
[Use tunnel device compatibility to OpenBSD])
AC_DEFINE([SSH_TUN_PREPEND_AF], [1],
[Prepend the address family to IP tunnel traffic])
m4_pattern_allow([AU_IPv])
AC_CHECK_DECL([AU_IPv4], [],
AC_DEFINE([AU_IPv4], [0], [System only supports IPv4 audit records])
[#include <bsm/audit.h>]
AC_DEFINE([LASTLOG_WRITE_PUTUTXLINE], [1],
[Define if pututxline updates lastlog too])
)
AC_DEFINE([SPT_TYPE], [SPT_REUSEARGV],
[Define to a Set Process Title type if your system is
supported by bsd-setproctitle.c])
AC_CHECK_FUNCS([sandbox_init])
AC_CHECK_HEADERS([sandbox.h])
AC_CHECK_LIB([sandbox], [sandbox_apply], [
SSHDLIBS="$SSHDLIBS -lsandbox"
])
# proc_pidinfo()-based closefrom() replacement.
AC_CHECK_HEADERS([libproc.h])
AC_CHECK_FUNCS([proc_pidinfo])
# poll(2) is broken for character-special devices (at least).
# cf. Apple bug 3710161 (not public, but searchable)
AC_DEFINE([BROKEN_POLL], [1],
[System poll(2) implementation is broken])
;;
*-*-dragonfly*)
SSHDLIBS="$SSHDLIBS"
TEST_MALLOC_OPTIONS="AFGJPRX"
;;
*-*-haiku*)
LIBS="$LIBS -lbsd "
CFLAGS="$CFLAGS -D_BSD_SOURCE"
AC_CHECK_LIB([network], [socket])
AC_DEFINE([HAVE_U_INT64_T])
AC_DEFINE([DISABLE_UTMPX], [1], [no utmpx])
MANTYPE=man
;;
*-*-hpux*)
# first we define all of the options common to all HP-UX releases
CPPFLAGS="$CPPFLAGS -D_HPUX_SOURCE -D_XOPEN_SOURCE -D_XOPEN_SOURCE_EXTENDED=1"
IPADDR_IN_DISPLAY=yes
AC_DEFINE([USE_PIPES])
AC_DEFINE([LOGIN_NEEDS_UTMPX])
AC_DEFINE([LOCKED_PASSWD_STRING], ["*"],
[String used in /etc/passwd to denote locked account])
AC_DEFINE([SPT_TYPE], [SPT_PSTAT])
AC_DEFINE([PLATFORM_SYS_DIR_UID], 2, [System dirs owned by bin (uid 2)])
maildir="/var/mail"
LIBS="$LIBS -lsec"
AC_CHECK_LIB([xnet], [t_error], ,
[AC_MSG_ERROR([*** -lxnet needed on HP-UX - check config.log ***])])
# next, we define all of the options specific to major releases
case "$host" in
*-*-hpux10*)
if test -z "$GCC"; then
CFLAGS="$CFLAGS -Ae"
fi
AC_DEFINE([BROKEN_GETLINE], [1], [getline is not what we expect])
;;
*-*-hpux11*)
AC_DEFINE([PAM_SUN_CODEBASE], [1],
[Define if you are using Solaris-derived PAM which
passes pam_messages to the conversation function
with an extra level of indirection])
AC_DEFINE([DISABLE_UTMP], [1],
[Define if you don't want to use utmp])
AC_DEFINE([USE_BTMP], [1], [Use btmp to log bad logins])
check_for_hpux_broken_getaddrinfo=1
check_for_conflicting_getspnam=1
;;
esac
# lastly, we define options specific to minor releases
case "$host" in
*-*-hpux10.26)
AC_DEFINE([HAVE_SECUREWARE], [1],
[Define if you have SecureWare-based
protected password database])
disable_ptmx_check=yes
LIBS="$LIBS -lsecpw"
;;
esac
;;
*-*-irix5*)
PATH="$PATH:/usr/etc"
AC_DEFINE([BROKEN_INET_NTOA], [1],
[Define if you system's inet_ntoa is busted
(e.g. Irix gcc issue)])
AC_DEFINE([SETEUID_BREAKS_SETUID])
AC_DEFINE([BROKEN_SETREUID])
AC_DEFINE([BROKEN_SETREGID])
AC_DEFINE([WITH_ABBREV_NO_TTY], [1],
[Define if you shouldn't strip 'tty' from your
ttyname in [uw]tmp])
AC_DEFINE([LOCKED_PASSWD_STRING], ["*LK*"])
;;
*-*-irix6*)
PATH="$PATH:/usr/etc"
AC_DEFINE([WITH_IRIX_ARRAY], [1],
[Define if you have/want arrays
(cluster-wide session management, not C arrays)])
AC_DEFINE([WITH_IRIX_PROJECT], [1],
[Define if you want IRIX project management])
AC_DEFINE([WITH_IRIX_AUDIT], [1],
[Define if you want IRIX audit trails])
AC_CHECK_FUNC([jlimit_startjob], [AC_DEFINE([WITH_IRIX_JOBS], [1],
[Define if you want IRIX kernel jobs])])
AC_DEFINE([BROKEN_INET_NTOA])
AC_DEFINE([SETEUID_BREAKS_SETUID])
AC_DEFINE([BROKEN_SETREUID])
AC_DEFINE([BROKEN_SETREGID])
AC_DEFINE([BROKEN_UPDWTMPX], [1], [updwtmpx is broken (if present)])
AC_DEFINE([WITH_ABBREV_NO_TTY])
AC_DEFINE([LOCKED_PASSWD_STRING], ["*LK*"])
;;
*-*-k*bsd*-gnu | *-*-kopensolaris*-gnu)
AC_DEFINE([PAM_TTY_KLUDGE])
AC_DEFINE([LOCKED_PASSWD_PREFIX], ["!"])
AC_DEFINE([SPT_TYPE], [SPT_REUSEARGV])
AC_DEFINE([_PATH_BTMP], ["/var/log/btmp"], [log for bad login attempts])
AC_DEFINE([USE_BTMP], [1], [Use btmp to log bad logins])
;;
*-*-linux*)
no_dev_ptmx=1
use_pie=auto
check_for_openpty_ctty_bug=1
dnl Target SUSv3/POSIX.1-2001 plus BSD specifics.
dnl _DEFAULT_SOURCE is the new name for _BSD_SOURCE
- CPPFLAGS="$CPPFLAGS -D_XOPEN_SOURCE=600 -D_BSD_SOURCE -D_DEFAULT_SOURCE"
+ dnl _GNU_SOURCE is needed for setres*id prototypes.
+ CPPFLAGS="$CPPFLAGS -D_XOPEN_SOURCE=600 -D_BSD_SOURCE -D_DEFAULT_SOURCE -D_GNU_SOURCE"
AC_DEFINE([BROKEN_CLOSEFROM], [1], [broken in chroots on older kernels])
AC_DEFINE([PAM_TTY_KLUDGE], [1],
[Work around problematic Linux PAM modules handling of PAM_TTY])
AC_DEFINE([LOCKED_PASSWD_PREFIX], ["!"],
[String used in /etc/passwd to denote locked account])
AC_DEFINE([SPT_TYPE], [SPT_REUSEARGV])
AC_DEFINE([LINK_OPNOTSUPP_ERRNO], [EPERM],
[Define to whatever link() returns for "not supported"
if it doesn't return EOPNOTSUPP.])
AC_DEFINE([_PATH_BTMP], ["/var/log/btmp"], [log for bad login attempts])
AC_DEFINE([USE_BTMP])
AC_DEFINE([LINUX_OOM_ADJUST], [1], [Adjust Linux out-of-memory killer])
inet6_default_4in6=yes
case `uname -r` in
1.*|2.0.*)
AC_DEFINE([BROKEN_CMSG_TYPE], [1],
[Define if cmsg_type is not passed correctly])
;;
esac
# tun(4) forwarding compat code
AC_CHECK_HEADERS([linux/if_tun.h])
if test "x$ac_cv_header_linux_if_tun_h" = "xyes" ; then
AC_DEFINE([SSH_TUN_LINUX], [1],
[Open tunnel devices the Linux tun/tap way])
AC_DEFINE([SSH_TUN_COMPAT_AF], [1],
[Use tunnel device compatibility to OpenBSD])
AC_DEFINE([SSH_TUN_PREPEND_AF], [1],
[Prepend the address family to IP tunnel traffic])
fi
AC_CHECK_HEADER([linux/if.h],
AC_DEFINE([SYS_RDOMAIN_LINUX], [1],
[Support routing domains using Linux VRF]), [], [
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
])
AC_CHECK_HEADERS([linux/seccomp.h linux/filter.h linux/audit.h], [],
[], [#include <linux/types.h>])
# Obtain MIPS ABI
case "$host" in
mips*)
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#if _MIPS_SIM != _ABIO32
#error
#endif
]])],[mips_abi="o32"],[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#if _MIPS_SIM != _ABIN32
#error
#endif
]])],[mips_abi="n32"],[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#if _MIPS_SIM != _ABI64
#error
#endif
]])],[mips_abi="n64"],[AC_MSG_ERROR([unknown MIPS ABI])
])
])
])
;;
esac
AC_MSG_CHECKING([for seccomp architecture])
seccomp_audit_arch=
case "$host" in
x86_64-*)
seccomp_audit_arch=AUDIT_ARCH_X86_64
;;
i*86-*)
seccomp_audit_arch=AUDIT_ARCH_I386
;;
arm*-*)
seccomp_audit_arch=AUDIT_ARCH_ARM
;;
aarch64*-*)
seccomp_audit_arch=AUDIT_ARCH_AARCH64
;;
s390x-*)
seccomp_audit_arch=AUDIT_ARCH_S390X
;;
s390-*)
seccomp_audit_arch=AUDIT_ARCH_S390
;;
powerpc-*)
seccomp_audit_arch=AUDIT_ARCH_PPC
;;
powerpc64-*)
seccomp_audit_arch=AUDIT_ARCH_PPC64
;;
powerpc64le-*)
seccomp_audit_arch=AUDIT_ARCH_PPC64LE
;;
mips-*)
seccomp_audit_arch=AUDIT_ARCH_MIPS
;;
mipsel-*)
seccomp_audit_arch=AUDIT_ARCH_MIPSEL
;;
mips64-*)
case "$mips_abi" in
"n32")
seccomp_audit_arch=AUDIT_ARCH_MIPS64N32
;;
"n64")
seccomp_audit_arch=AUDIT_ARCH_MIPS64
;;
esac
;;
mips64el-*)
case "$mips_abi" in
"n32")
seccomp_audit_arch=AUDIT_ARCH_MIPSEL64N32
;;
"n64")
seccomp_audit_arch=AUDIT_ARCH_MIPSEL64
;;
esac
;;
riscv64-*)
seccomp_audit_arch=AUDIT_ARCH_RISCV64
;;
esac
if test "x$seccomp_audit_arch" != "x" ; then
AC_MSG_RESULT(["$seccomp_audit_arch"])
AC_DEFINE_UNQUOTED([SECCOMP_AUDIT_ARCH], [$seccomp_audit_arch],
[Specify the system call convention in use])
else
AC_MSG_RESULT([architecture not supported])
fi
;;
*-*-minix)
AC_DEFINE([SETEUID_BREAKS_SETUID])
# poll(2) seems to choke on /dev/null; "Bad file descriptor"
AC_DEFINE([BROKEN_POLL], [1],
[System poll(2) implementation is broken])
;;
mips-sony-bsd|mips-sony-newsos4)
AC_DEFINE([NEED_SETPGRP], [1], [Need setpgrp to acquire controlling tty])
SONY=1
;;
*-*-netbsd*)
if test "x$withval" != "xno" ; then
rpath_opt="-R"
fi
CPPFLAGS="$CPPFLAGS -D_OPENBSD_SOURCE"
AC_DEFINE([SSH_TUN_FREEBSD], [1], [Open tunnel devices the FreeBSD way])
AC_CHECK_HEADER([net/if_tap.h], ,
AC_DEFINE([SSH_TUN_NO_L2], [1], [No layer 2 tunnel support]))
AC_DEFINE([SSH_TUN_PREPEND_AF], [1],
[Prepend the address family to IP tunnel traffic])
TEST_MALLOC_OPTIONS="AJRX"
AC_DEFINE([BROKEN_READ_COMPARISON], [1],
[NetBSD read function is sometimes redirected, breaking atomicio comparisons against it])
;;
*-*-freebsd*)
AC_DEFINE([LOCKED_PASSWD_PREFIX], ["*LOCKED*"], [Account locked with pw(1)])
AC_DEFINE([SSH_TUN_FREEBSD], [1], [Open tunnel devices the FreeBSD way])
AC_CHECK_HEADER([net/if_tap.h], ,
AC_DEFINE([SSH_TUN_NO_L2], [1], [No layer 2 tunnel support]))
AC_DEFINE([BROKEN_GLOB], [1], [FreeBSD glob does not do what we need])
TEST_MALLOC_OPTIONS="AJRX"
# Preauth crypto occasionally uses file descriptors for crypto offload
# and will crash if they cannot be opened.
AC_DEFINE([SANDBOX_SKIP_RLIMIT_NOFILE], [1],
[define if setrlimit RLIMIT_NOFILE breaks things])
case "$host" in
*-*-freebsd9.*|*-*-freebsd10.*)
# Capsicum on 9 and 10 do not allow ppoll() so don't auto-enable.
disable_capsicum=yes
esac
;;
*-*-bsdi*)
AC_DEFINE([SETEUID_BREAKS_SETUID])
AC_DEFINE([BROKEN_SETREUID])
AC_DEFINE([BROKEN_SETREGID])
;;
*-next-*)
conf_lastlog_location="/usr/adm/lastlog"
conf_utmp_location=/etc/utmp
conf_wtmp_location=/usr/adm/wtmp
maildir=/usr/spool/mail
AC_DEFINE([HAVE_NEXT], [1], [Define if you are on NeXT])
AC_DEFINE([USE_PIPES])
AC_DEFINE([BROKEN_SAVED_UIDS], [1], [Needed for NeXT])
;;
*-*-openbsd*)
use_pie=auto
AC_DEFINE([HAVE_ATTRIBUTE__SENTINEL__], [1], [OpenBSD's gcc has sentinel])
AC_DEFINE([HAVE_ATTRIBUTE__BOUNDED__], [1], [OpenBSD's gcc has bounded])
AC_DEFINE([SSH_TUN_OPENBSD], [1], [Open tunnel devices the OpenBSD way])
AC_DEFINE([SYSLOG_R_SAFE_IN_SIGHAND], [1],
[syslog_r function is safe to use in in a signal handler])
TEST_MALLOC_OPTIONS="AFGJPRX"
;;
*-*-solaris*)
if test "x$withval" != "xno" ; then
rpath_opt="-R"
fi
AC_DEFINE([PAM_SUN_CODEBASE])
AC_DEFINE([LOGIN_NEEDS_UTMPX])
AC_DEFINE([PAM_TTY_KLUDGE])
AC_DEFINE([SSHPAM_CHAUTHTOK_NEEDS_RUID], [1],
[Define if pam_chauthtok wants real uid set
to the unpriv'ed user])
AC_DEFINE([LOCKED_PASSWD_STRING], ["*LK*"])
# Pushing STREAMS modules will cause sshd to acquire a controlling tty.
AC_DEFINE([SSHD_ACQUIRES_CTTY], [1],
[Define if sshd somehow reacquires a controlling TTY
after setsid()])
AC_DEFINE([PASSWD_NEEDS_USERNAME], [1], [must supply username to passwd
in case the name is longer than 8 chars])
AC_DEFINE([BROKEN_TCGETATTR_ICANON], [1], [tcgetattr with ICANON may hang])
external_path_file=/etc/default/login
# hardwire lastlog location (can't detect it on some versions)
conf_lastlog_location="/var/adm/lastlog"
AC_MSG_CHECKING([for obsolete utmp and wtmp in solaris2.x])
sol2ver=`echo "$host"| sed -e 's/.*[[0-9]]\.//'`
if test "$sol2ver" -ge 8; then
AC_MSG_RESULT([yes])
AC_DEFINE([DISABLE_UTMP])
AC_DEFINE([DISABLE_WTMP], [1],
[Define if you don't want to use wtmp])
else
AC_MSG_RESULT([no])
fi
AC_CHECK_FUNCS([setpflags])
AC_CHECK_FUNCS([setppriv])
AC_CHECK_FUNCS([priv_basicset])
AC_CHECK_HEADERS([priv.h])
AC_ARG_WITH([solaris-contracts],
[ --with-solaris-contracts Enable Solaris process contracts (experimental)],
[
AC_CHECK_LIB([contract], [ct_tmpl_activate],
[ AC_DEFINE([USE_SOLARIS_PROCESS_CONTRACTS], [1],
[Define if you have Solaris process contracts])
LIBS="$LIBS -lcontract"
SPC_MSG="yes" ], )
],
)
AC_ARG_WITH([solaris-projects],
[ --with-solaris-projects Enable Solaris projects (experimental)],
[
AC_CHECK_LIB([project], [setproject],
[ AC_DEFINE([USE_SOLARIS_PROJECTS], [1],
[Define if you have Solaris projects])
LIBS="$LIBS -lproject"
SP_MSG="yes" ], )
],
)
AC_ARG_WITH([solaris-privs],
[ --with-solaris-privs Enable Solaris/Illumos privileges (experimental)],
[
AC_MSG_CHECKING([for Solaris/Illumos privilege support])
if test "x$ac_cv_func_setppriv" = "xyes" -a \
"x$ac_cv_header_priv_h" = "xyes" ; then
SOLARIS_PRIVS=yes
AC_MSG_RESULT([found])
AC_DEFINE([NO_UID_RESTORATION_TEST], [1],
[Define to disable UID restoration test])
AC_DEFINE([USE_SOLARIS_PRIVS], [1],
[Define if you have Solaris privileges])
SPP_MSG="yes"
else
AC_MSG_RESULT([not found])
AC_MSG_ERROR([*** must have support for Solaris privileges to use --with-solaris-privs])
fi
],
)
TEST_SHELL=$SHELL # let configure find us a capable shell
;;
*-*-sunos4*)
CPPFLAGS="$CPPFLAGS -DSUNOS4"
AC_CHECK_FUNCS([getpwanam])
AC_DEFINE([PAM_SUN_CODEBASE])
conf_utmp_location=/etc/utmp
conf_wtmp_location=/var/adm/wtmp
conf_lastlog_location=/var/adm/lastlog
AC_DEFINE([USE_PIPES])
AC_DEFINE([DISABLE_UTMPX], [1], [no utmpx])
;;
*-ncr-sysv*)
LIBS="$LIBS -lc89"
AC_DEFINE([USE_PIPES])
AC_DEFINE([SSHD_ACQUIRES_CTTY])
AC_DEFINE([SETEUID_BREAKS_SETUID])
AC_DEFINE([BROKEN_SETREUID])
AC_DEFINE([BROKEN_SETREGID])
;;
*-sni-sysv*)
# /usr/ucblib MUST NOT be searched on ReliantUNIX
AC_CHECK_LIB([dl], [dlsym], ,)
# -lresolv needs to be at the end of LIBS or DNS lookups break
AC_CHECK_LIB([resolv], [res_query], [ LIBS="$LIBS -lresolv" ])
IPADDR_IN_DISPLAY=yes
AC_DEFINE([USE_PIPES])
AC_DEFINE([IP_TOS_IS_BROKEN])
AC_DEFINE([SETEUID_BREAKS_SETUID])
AC_DEFINE([BROKEN_SETREUID])
AC_DEFINE([BROKEN_SETREGID])
AC_DEFINE([SSHD_ACQUIRES_CTTY])
external_path_file=/etc/default/login
# /usr/ucblib/libucb.a no longer needed on ReliantUNIX
# Attention: always take care to bind libsocket and libnsl before libc,
# otherwise you will find lots of "SIOCGPGRP errno 22" on syslog
;;
# UnixWare 1.x, UnixWare 2.x, and others based on code from Univel.
*-*-sysv4.2*)
AC_DEFINE([USE_PIPES])
AC_DEFINE([SETEUID_BREAKS_SETUID])
AC_DEFINE([BROKEN_SETREUID])
AC_DEFINE([BROKEN_SETREGID])
AC_DEFINE([PASSWD_NEEDS_USERNAME], [1], [must supply username to passwd])
AC_DEFINE([LOCKED_PASSWD_STRING], ["*LK*"])
TEST_SHELL=$SHELL # let configure find us a capable shell
;;
# UnixWare 7.x, OpenUNIX 8
*-*-sysv5*)
CPPFLAGS="$CPPFLAGS -Dvsnprintf=_xvsnprintf -Dsnprintf=_xsnprintf"
AC_DEFINE([UNIXWARE_LONG_PASSWORDS], [1], [Support passwords > 8 chars])
AC_DEFINE([USE_PIPES])
AC_DEFINE([SETEUID_BREAKS_SETUID])
AC_DEFINE([BROKEN_GETADDRINFO])
AC_DEFINE([BROKEN_SETREUID])
AC_DEFINE([BROKEN_SETREGID])
AC_DEFINE([PASSWD_NEEDS_USERNAME])
AC_DEFINE([BROKEN_TCGETATTR_ICANON])
TEST_SHELL=$SHELL # let configure find us a capable shell
case "$host" in
*-*-sysv5SCO_SV*) # SCO OpenServer 6.x
maildir=/var/spool/mail
AC_DEFINE([BROKEN_UPDWTMPX])
AC_CHECK_LIB([prot], [getluid], [ LIBS="$LIBS -lprot"
AC_CHECK_FUNCS([getluid setluid], , , [-lprot])
], , )
;;
*) AC_DEFINE([LOCKED_PASSWD_STRING], ["*LK*"])
;;
esac
;;
*-*-sysv*)
;;
# SCO UNIX and OEM versions of SCO UNIX
*-*-sco3.2v4*)
AC_MSG_ERROR("This Platform is no longer supported.")
;;
# SCO OpenServer 5.x
*-*-sco3.2v5*)
if test -z "$GCC"; then
CFLAGS="$CFLAGS -belf"
fi
LIBS="$LIBS -lprot -lx -ltinfo -lm"
no_dev_ptmx=1
AC_DEFINE([USE_PIPES])
AC_DEFINE([HAVE_SECUREWARE])
AC_DEFINE([DISABLE_SHADOW])
AC_DEFINE([DISABLE_FD_PASSING])
AC_DEFINE([SETEUID_BREAKS_SETUID])
AC_DEFINE([BROKEN_GETADDRINFO])
AC_DEFINE([BROKEN_SETREUID])
AC_DEFINE([BROKEN_SETREGID])
AC_DEFINE([WITH_ABBREV_NO_TTY])
AC_DEFINE([BROKEN_UPDWTMPX])
AC_DEFINE([PASSWD_NEEDS_USERNAME])
AC_CHECK_FUNCS([getluid setluid])
MANTYPE=man
TEST_SHELL=$SHELL # let configure find us a capable shell
SKIP_DISABLE_LASTLOG_DEFINE=yes
;;
*-dec-osf*)
AC_MSG_CHECKING([for Digital Unix SIA])
no_osfsia=""
AC_ARG_WITH([osfsia],
[ --with-osfsia Enable Digital Unix SIA],
[
if test "x$withval" = "xno" ; then
AC_MSG_RESULT([disabled])
no_osfsia=1
fi
],
)
if test -z "$no_osfsia" ; then
if test -f /etc/sia/matrix.conf; then
AC_MSG_RESULT([yes])
AC_DEFINE([HAVE_OSF_SIA], [1],
[Define if you have Digital Unix Security
Integration Architecture])
AC_DEFINE([DISABLE_LOGIN], [1],
[Define if you don't want to use your
system's login() call])
AC_DEFINE([DISABLE_FD_PASSING])
LIBS="$LIBS -lsecurity -ldb -lm -laud"
SIA_MSG="yes"
else
AC_MSG_RESULT([no])
AC_DEFINE([LOCKED_PASSWD_SUBSTR], ["Nologin"],
[String used in /etc/passwd to denote locked account])
fi
fi
AC_DEFINE([BROKEN_GETADDRINFO])
AC_DEFINE([SETEUID_BREAKS_SETUID])
AC_DEFINE([BROKEN_SETREUID])
AC_DEFINE([BROKEN_SETREGID])
AC_DEFINE([BROKEN_READV_COMPARISON], [1], [Can't do comparisons on readv])
;;
*-*-nto-qnx*)
AC_DEFINE([USE_PIPES])
AC_DEFINE([NO_X11_UNIX_SOCKETS])
AC_DEFINE([DISABLE_LASTLOG])
AC_DEFINE([SSHD_ACQUIRES_CTTY])
AC_DEFINE([BROKEN_SHADOW_EXPIRE], [1], [QNX shadow support is broken])
enable_etc_default_login=no # has incompatible /etc/default/login
case "$host" in
*-*-nto-qnx6*)
AC_DEFINE([DISABLE_FD_PASSING])
;;
esac
;;
*-*-ultrix*)
AC_DEFINE([BROKEN_GETGROUPS], [1], [getgroups(0,NULL) will return -1])
AC_DEFINE([NEED_SETPGRP], [1], [Need setpgrp to for controlling tty])
AC_DEFINE([HAVE_SYS_SYSLOG_H], [1], [Force use of sys/syslog.h on Ultrix])
AC_DEFINE([DISABLE_UTMPX], [1], [Disable utmpx])
# DISABLE_FD_PASSING so that we call setpgrp as root, otherwise we
# don't get a controlling tty.
AC_DEFINE([DISABLE_FD_PASSING], [1], [Need to call setpgrp as root])
# On Ultrix some headers are not protected against multiple includes,
# so we create wrappers and put it where the compiler will find it.
AC_MSG_WARN([creating compat wrappers for headers])
mkdir -p netinet
for header in netinet/ip.h netdb.h resolv.h; do
name=`echo $header | tr 'a-z/.' 'A-Z__'`
cat >$header <<EOD
#ifndef _SSH_COMPAT_${name}
#define _SSH_COMPAT_${name}
#include "/usr/include/${header}"
#endif
EOD
done
;;
*-*-lynxos)
CFLAGS="$CFLAGS -D__NO_INCLUDE_WARN__"
AC_DEFINE([BROKEN_SETVBUF], [1],
[LynxOS has broken setvbuf() implementation])
;;
esac
AC_MSG_CHECKING([compiler and flags for sanity])
AC_RUN_IFELSE([AC_LANG_PROGRAM([[ #include <stdlib.h> ]], [[ exit(0); ]])],
[ AC_MSG_RESULT([yes]) ],
[
AC_MSG_RESULT([no])
AC_MSG_ERROR([*** compiler cannot create working executables, check config.log ***])
],
[ AC_MSG_WARN([cross compiling: not checking compiler sanity]) ]
)
dnl Checks for header files.
# Checks for libraries.
AC_CHECK_FUNC([setsockopt], , [AC_CHECK_LIB([socket], [setsockopt])])
dnl IRIX and Solaris 2.5.1 have dirname() in libgen
AC_CHECK_FUNCS([dirname], [AC_CHECK_HEADERS([libgen.h])] , [
AC_CHECK_LIB([gen], [dirname], [
AC_CACHE_CHECK([for broken dirname],
ac_cv_have_broken_dirname, [
save_LIBS="$LIBS"
LIBS="$LIBS -lgen"
AC_RUN_IFELSE(
[AC_LANG_SOURCE([[
#include <libgen.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char **argv) {
char *s, buf[32];
strncpy(buf,"/etc", 32);
s = dirname(buf);
if (!s || strncmp(s, "/", 32) != 0) {
exit(1);
} else {
exit(0);
}
}
]])],
[ ac_cv_have_broken_dirname="no" ],
[ ac_cv_have_broken_dirname="yes" ],
[ ac_cv_have_broken_dirname="no" ],
)
LIBS="$save_LIBS"
])
if test "x$ac_cv_have_broken_dirname" = "xno" ; then
LIBS="$LIBS -lgen"
AC_DEFINE([HAVE_DIRNAME])
AC_CHECK_HEADERS([libgen.h])
fi
])
])
AC_CHECK_FUNC([getspnam], ,
[AC_CHECK_LIB([gen], [getspnam], [LIBS="$LIBS -lgen"])])
AC_SEARCH_LIBS([basename], [gen], [AC_DEFINE([HAVE_BASENAME], [1],
[Define if you have the basename function.])])
dnl zlib defaults to enabled
zlib=yes
AC_ARG_WITH([zlib],
[ --with-zlib=PATH Use zlib in PATH],
[ if test "x$withval" = "xno" ; then
zlib=no
elif test "x$withval" != "xyes"; then
if test -d "$withval/lib"; then
if test -n "${rpath_opt}"; then
LDFLAGS="-L${withval}/lib ${rpath_opt}${withval}/lib ${LDFLAGS}"
else
LDFLAGS="-L${withval}/lib ${LDFLAGS}"
fi
else
if test -n "${rpath_opt}"; then
LDFLAGS="-L${withval} ${rpath_opt}${withval} ${LDFLAGS}"
else
LDFLAGS="-L${withval} ${LDFLAGS}"
fi
fi
if test -d "$withval/include"; then
CPPFLAGS="-I${withval}/include ${CPPFLAGS}"
else
CPPFLAGS="-I${withval} ${CPPFLAGS}"
fi
fi ]
)
# These libraries are needed for anything that links in the channel code.
CHANNELLIBS=""
AC_MSG_CHECKING([for zlib])
if test "x${zlib}" = "xno"; then
AC_MSG_RESULT([no])
else
saved_LIBS="$LIBS"
CHANNELLIBS="$CHANNELLIBS -lz"
AC_MSG_RESULT([yes])
AC_DEFINE([WITH_ZLIB], [1], [Enable zlib])
AC_CHECK_HEADER([zlib.h], ,[AC_MSG_ERROR([*** zlib.h missing - please install first or check config.log ***])])
AC_CHECK_LIB([z], [deflate], [],
[
saved_CPPFLAGS="$CPPFLAGS"
saved_LDFLAGS="$LDFLAGS"
dnl Check default zlib install dir
if test -n "${rpath_opt}"; then
LDFLAGS="-L/usr/local/lib ${rpath_opt}/usr/local/lib ${saved_LDFLAGS}"
else
LDFLAGS="-L/usr/local/lib ${saved_LDFLAGS}"
fi
CPPFLAGS="-I/usr/local/include ${saved_CPPFLAGS}"
AC_TRY_LINK_FUNC([deflate], [AC_DEFINE([HAVE_LIBZ])],
[
AC_MSG_ERROR([*** zlib missing - please install first or check config.log ***])
]
)
]
)
AC_ARG_WITH([zlib-version-check],
[ --without-zlib-version-check Disable zlib version check],
[ if test "x$withval" = "xno" ; then
zlib_check_nonfatal=1
fi
]
)
AC_MSG_CHECKING([for possibly buggy zlib])
AC_RUN_IFELSE([AC_LANG_PROGRAM([[
#include <stdio.h>
#include <stdlib.h>
#include <zlib.h>
]],
[[
int a=0, b=0, c=0, d=0, n, v;
n = sscanf(ZLIB_VERSION, "%d.%d.%d.%d", &a, &b, &c, &d);
if (n != 3 && n != 4)
exit(1);
v = a*1000000 + b*10000 + c*100 + d;
fprintf(stderr, "found zlib version %s (%d)\n", ZLIB_VERSION, v);
/* 1.1.4 is OK */
if (a == 1 && b == 1 && c >= 4)
exit(0);
/* 1.2.3 and up are OK */
if (v >= 1020300)
exit(0);
exit(2);
]])],
AC_MSG_RESULT([no]),
[ AC_MSG_RESULT([yes])
if test -z "$zlib_check_nonfatal" ; then
AC_MSG_ERROR([*** zlib too old - check config.log ***
Your reported zlib version has known security problems. It's possible your
vendor has fixed these problems without changing the version number. If you
are sure this is the case, you can disable the check by running
"./configure --without-zlib-version-check".
If you are in doubt, upgrade zlib to version 1.2.3 or greater.
See http://www.gzip.org/zlib/ for details.])
else
AC_MSG_WARN([zlib version may have security problems])
fi
],
[ AC_MSG_WARN([cross compiling: not checking zlib version]) ]
)
LIBS="$saved_LIBS"
fi
dnl UnixWare 2.x
AC_CHECK_FUNC([strcasecmp],
[], [ AC_CHECK_LIB([resolv], [strcasecmp], [LIBS="$LIBS -lresolv"]) ]
)
AC_CHECK_FUNCS([utimes],
[], [ AC_CHECK_LIB([c89], [utimes], [AC_DEFINE([HAVE_UTIMES])
LIBS="$LIBS -lc89"]) ]
)
dnl Checks for libutil functions
AC_CHECK_HEADERS([bsd/libutil.h libutil.h])
AC_SEARCH_LIBS([fmt_scaled], [util bsd])
AC_SEARCH_LIBS([scan_scaled], [util bsd])
AC_SEARCH_LIBS([login], [util bsd])
AC_SEARCH_LIBS([logout], [util bsd])
AC_SEARCH_LIBS([logwtmp], [util bsd])
AC_SEARCH_LIBS([openpty], [util bsd])
AC_SEARCH_LIBS([updwtmp], [util bsd])
AC_CHECK_FUNCS([fmt_scaled scan_scaled login logout openpty updwtmp logwtmp])
# On some platforms, inet_ntop and gethostbyname may be found in libresolv
# or libnsl.
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
AC_FUNC_MALLOC
AC_FUNC_REALLOC
# autoconf doesn't have AC_FUNC_CALLOC so fake it if malloc returns NULL;
AC_MSG_CHECKING([if calloc(0, N) returns non-null])
AC_RUN_IFELSE(
[AC_LANG_PROGRAM(
[[ #include <stdlib.h> ]],
[[ void *p = calloc(0, 1); exit(p == NULL); ]]
)],
[ func_calloc_0_nonnull=yes ],
[ func_calloc_0_nonnull=no ],
[ AC_MSG_WARN([cross compiling: assuming same as malloc])
func_calloc_0_nonnull="$ac_cv_func_malloc_0_nonnull"]
)
AC_MSG_RESULT([$func_calloc_0_nonnull])
if test "x$func_calloc_0_nonnull" = "xyes"; then
AC_DEFINE(HAVE_CALLOC, 1, [calloc(0, x) returns non-null])
else
AC_DEFINE(HAVE_CALLOC, 0, [calloc(0, x) returns NULL])
AC_DEFINE(calloc, rpl_calloc,
[Define to rpl_calloc if the replacement function should be used.])
fi
# Check for ALTDIRFUNC glob() extension
AC_MSG_CHECKING([for GLOB_ALTDIRFUNC support])
AC_EGREP_CPP([FOUNDIT],
[
#include <glob.h>
#ifdef GLOB_ALTDIRFUNC
FOUNDIT
#endif
],
[
AC_DEFINE([GLOB_HAS_ALTDIRFUNC], [1],
[Define if your system glob() function has
the GLOB_ALTDIRFUNC extension])
AC_MSG_RESULT([yes])
],
[
AC_MSG_RESULT([no])
]
)
# Check for g.gl_matchc glob() extension
AC_MSG_CHECKING([for gl_matchc field in glob_t])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <glob.h> ]],
[[ glob_t g; g.gl_matchc = 1; ]])],
[
AC_DEFINE([GLOB_HAS_GL_MATCHC], [1],
[Define if your system glob() function has
gl_matchc options in glob_t])
AC_MSG_RESULT([yes])
], [
AC_MSG_RESULT([no])
])
# Check for g.gl_statv glob() extension
AC_MSG_CHECKING([for gl_statv and GLOB_KEEPSTAT extensions for glob])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <glob.h> ]], [[
#ifndef GLOB_KEEPSTAT
#error "glob does not support GLOB_KEEPSTAT extension"
#endif
glob_t g;
g.gl_statv = NULL;
]])],
[
AC_DEFINE([GLOB_HAS_GL_STATV], [1],
[Define if your system glob() function has
gl_statv options in glob_t])
AC_MSG_RESULT([yes])
], [
AC_MSG_RESULT([no])
])
AC_CHECK_DECLS([GLOB_NOMATCH], , , [#include <glob.h>])
AC_CHECK_DECL([VIS_ALL], ,
AC_DEFINE(BROKEN_STRNVIS, 1, [missing VIS_ALL]), [#include <vis.h>])
AC_MSG_CHECKING([whether struct dirent allocates space for d_name])
AC_RUN_IFELSE(
[AC_LANG_PROGRAM([[
#include <sys/types.h>
#include <dirent.h>
#include <stdlib.h>
]],
[[
struct dirent d;
exit(sizeof(d.d_name)<=sizeof(char));
]])],
[AC_MSG_RESULT([yes])],
[
AC_MSG_RESULT([no])
AC_DEFINE([BROKEN_ONE_BYTE_DIRENT_D_NAME], [1],
[Define if your struct dirent expects you to
allocate extra space for d_name])
],
[
AC_MSG_WARN([cross compiling: assuming BROKEN_ONE_BYTE_DIRENT_D_NAME])
AC_DEFINE([BROKEN_ONE_BYTE_DIRENT_D_NAME])
]
)
AC_MSG_CHECKING([for /proc/pid/fd directory])
if test -d "/proc/$$/fd" ; then
AC_DEFINE([HAVE_PROC_PID], [1], [Define if you have /proc/$pid/fd])
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])
fi
# Check whether user wants TCP wrappers support
TCPW_MSG="no"
AC_ARG_WITH([tcp-wrappers],
[ --with-tcp-wrappers[[=PATH]] Enable tcpwrappers support (optionally in PATH)],
[
if test "x$withval" != "xno" ; then
saved_LIBS="$LIBS"
saved_LDFLAGS="$LDFLAGS"
saved_CPPFLAGS="$CPPFLAGS"
if test -n "${withval}" && \
test "x${withval}" != "xyes"; then
if test -d "${withval}/lib"; then
if test -n "${need_dash_r}"; then
LDFLAGS="-L${withval}/lib -R${withval}/lib ${LDFLAGS}"
else
LDFLAGS="-L${withval}/lib ${LDFLAGS}"
fi
else
if test -n "${need_dash_r}"; then
LDFLAGS="-L${withval} -R${withval} ${LDFLAGS}"
else
LDFLAGS="-L${withval} ${LDFLAGS}"
fi
fi
if test -d "${withval}/include"; then
CPPFLAGS="-I${withval}/include ${CPPFLAGS}"
else
CPPFLAGS="-I${withval} ${CPPFLAGS}"
fi
fi
LIBS="-lwrap $LIBS"
AC_MSG_CHECKING([for libwrap])
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <tcpd.h>
int deny_severity = 0, allow_severity = 0;
]], [[
hosts_access(0);
]])], [
AC_MSG_RESULT([yes])
AC_DEFINE([LIBWRAP], [1],
[Define if you want
TCP Wrappers support])
SSHDLIBS="$SSHDLIBS -lwrap"
TCPW_MSG="yes"
], [
AC_MSG_ERROR([*** libwrap missing])
])
LIBS="$saved_LIBS"
fi
]
)
# Check whether user wants to use ldns
LDNS_MSG="no"
AC_ARG_WITH(ldns,
[ --with-ldns[[=PATH]] Use ldns for DNSSEC support (optionally in PATH)],
[
ldns=""
if test "x$withval" = "xyes" ; then
AC_PATH_TOOL([LDNSCONFIG], [ldns-config], [no])
if test "x$LDNSCONFIG" = "xno"; then
LIBS="-lldns $LIBS"
ldns=yes
else
LIBS="$LIBS `$LDNSCONFIG --libs`"
CPPFLAGS="$CPPFLAGS `$LDNSCONFIG --cflags`"
ldns=yes
fi
elif test "x$withval" != "xno" ; then
CPPFLAGS="$CPPFLAGS -I${withval}/include"
LDFLAGS="$LDFLAGS -L${withval}/lib"
LIBS="-lldns $LIBS"
ldns=yes
fi
# Verify that it works.
if test "x$ldns" = "xyes" ; then
AC_DEFINE(HAVE_LDNS, 1, [Define if you want ldns support])
LDNS_MSG="yes"
AC_MSG_CHECKING([for ldns support])
AC_LINK_IFELSE(
[AC_LANG_SOURCE([[
#include <stdio.h>
#include <stdlib.h>
#ifdef HAVE_STDINT_H
# include <stdint.h>
#endif
#include <ldns/ldns.h>
-int main() { ldns_status status = ldns_verify_trusted(NULL, NULL, NULL, NULL); status=LDNS_STATUS_OK; exit(0); }
+int main(void) { ldns_status status = ldns_verify_trusted(NULL, NULL, NULL, NULL); status=LDNS_STATUS_OK; exit(0); }
]])
],
[AC_MSG_RESULT(yes)],
[
AC_MSG_RESULT(no)
AC_MSG_ERROR([** Incomplete or missing ldns libraries.])
])
fi
])
# Check whether user wants libedit support
LIBEDIT_MSG="no"
AC_ARG_WITH([libedit],
[ --with-libedit[[=PATH]] Enable libedit support for sftp],
[ if test "x$withval" != "xno" ; then
if test "x$withval" = "xyes" ; then
if test "x$PKGCONFIG" != "xno"; then
AC_MSG_CHECKING([if $PKGCONFIG knows about libedit])
if "$PKGCONFIG" libedit; then
AC_MSG_RESULT([yes])
use_pkgconfig_for_libedit=yes
else
AC_MSG_RESULT([no])
fi
fi
else
CPPFLAGS="$CPPFLAGS -I${withval}/include"
if test -n "${rpath_opt}"; then
LDFLAGS="-L${withval}/lib ${rpath_opt}${withval}/lib ${LDFLAGS}"
else
LDFLAGS="-L${withval}/lib ${LDFLAGS}"
fi
fi
if test "x$use_pkgconfig_for_libedit" = "xyes"; then
LIBEDIT=`$PKGCONFIG --libs libedit`
CPPFLAGS="$CPPFLAGS `$PKGCONFIG --cflags libedit`"
else
LIBEDIT="-ledit -lcurses"
fi
OTHERLIBS=`echo $LIBEDIT | sed 's/-ledit//'`
AC_CHECK_LIB([edit], [el_init],
[ AC_DEFINE([USE_LIBEDIT], [1], [Use libedit for sftp])
LIBEDIT_MSG="yes"
AC_SUBST([LIBEDIT])
],
[ AC_MSG_ERROR([libedit not found]) ],
[ $OTHERLIBS ]
)
AC_MSG_CHECKING([if libedit version is compatible])
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM([[
#include <histedit.h>
#include <stdlib.h>
]],
[[
int i = H_SETSIZE;
el_init("", NULL, NULL, NULL);
exit(0);
]])],
[ AC_MSG_RESULT([yes]) ],
[ AC_MSG_RESULT([no])
AC_MSG_ERROR([libedit version is not compatible]) ]
)
fi ]
)
AUDIT_MODULE=none
AC_ARG_WITH([audit],
[ --with-audit=module Enable audit support (modules=debug,bsm,linux)],
[
AC_MSG_CHECKING([for supported audit module])
case "$withval" in
bsm)
AC_MSG_RESULT([bsm])
AUDIT_MODULE=bsm
dnl Checks for headers, libs and functions
AC_CHECK_HEADERS([bsm/audit.h], [],
[AC_MSG_ERROR([BSM enabled and bsm/audit.h not found])],
[
#ifdef HAVE_TIME_H
# include <time.h>
#endif
]
)
AC_CHECK_LIB([bsm], [getaudit], [],
[AC_MSG_ERROR([BSM enabled and required library not found])])
AC_CHECK_FUNCS([getaudit], [],
[AC_MSG_ERROR([BSM enabled and required function not found])])
# These are optional
AC_CHECK_FUNCS([getaudit_addr aug_get_machine])
AC_DEFINE([USE_BSM_AUDIT], [1], [Use BSM audit module])
if test "$sol2ver" -ge 11; then
SSHDLIBS="$SSHDLIBS -lscf"
AC_DEFINE([BROKEN_BSM_API], [1],
[The system has incomplete BSM API])
fi
;;
linux)
AC_MSG_RESULT([linux])
AUDIT_MODULE=linux
dnl Checks for headers, libs and functions
AC_CHECK_HEADERS([libaudit.h])
SSHDLIBS="$SSHDLIBS -laudit"
AC_DEFINE([USE_LINUX_AUDIT], [1], [Use Linux audit module])
;;
debug)
AUDIT_MODULE=debug
AC_MSG_RESULT([debug])
AC_DEFINE([SSH_AUDIT_EVENTS], [1], [Use audit debugging module])
;;
no)
AC_MSG_RESULT([no])
;;
*)
AC_MSG_ERROR([Unknown audit module $withval])
;;
esac ]
)
AC_ARG_WITH([pie],
[ --with-pie Build Position Independent Executables if possible], [
if test "x$withval" = "xno"; then
use_pie=no
fi
if test "x$withval" = "xyes"; then
use_pie=yes
fi
]
)
if test "x$use_pie" = "x"; then
use_pie=no
fi
if test "x$use_toolchain_hardening" != "x1" && test "x$use_pie" = "xauto"; then
# Turn off automatic PIE when toolchain hardening is off.
use_pie=no
fi
if test "x$use_pie" = "xauto"; then
# Automatic PIE requires gcc >= 4.x
AC_MSG_CHECKING([for gcc >= 4.x])
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
#if !defined(__GNUC__) || __GNUC__ < 4
#error gcc is too old
#endif
]])],
[ AC_MSG_RESULT([yes]) ],
[ AC_MSG_RESULT([no])
use_pie=no ]
)
fi
if test "x$use_pie" != "xno"; then
SAVED_CFLAGS="$CFLAGS"
SAVED_LDFLAGS="$LDFLAGS"
OSSH_CHECK_CFLAG_COMPILE([-fPIE])
OSSH_CHECK_LDFLAG_LINK([-pie])
# We use both -fPIE and -pie or neither.
AC_MSG_CHECKING([whether both -fPIE and -pie are supported])
if echo "x $CFLAGS" | grep ' -fPIE' >/dev/null 2>&1 && \
echo "x $LDFLAGS" | grep ' -pie' >/dev/null 2>&1 ; then
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])
CFLAGS="$SAVED_CFLAGS"
LDFLAGS="$SAVED_LDFLAGS"
fi
fi
AC_MSG_CHECKING([whether -fPIC is accepted])
SAVED_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -fPIC"
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM( [[ #include <stdlib.h> ]], [[ exit(0); ]] )],
[AC_MSG_RESULT([yes])
PICFLAG="-fPIC"; ],
[AC_MSG_RESULT([no])
PICFLAG=""; ])
CFLAGS="$SAVED_CFLAGS"
AC_SUBST([PICFLAG])
dnl Checks for library functions. Please keep in alphabetical order
AC_CHECK_FUNCS([ \
auth_hostok \
auth_timeok \
Blowfish_initstate \
Blowfish_expandstate \
Blowfish_expand0state \
Blowfish_stream2word \
SHA256Update \
SHA384Update \
SHA512Update \
asprintf \
b64_ntop \
__b64_ntop \
b64_pton \
__b64_pton \
bcopy \
bcrypt_pbkdf \
bindresvport_sa \
blf_enc \
bzero \
cap_rights_limit \
clock \
closefrom \
close_range \
dirfd \
endgrent \
err \
errx \
explicit_bzero \
explicit_memset \
fchmod \
fchmodat \
fchown \
fchownat \
flock \
fnmatch \
freeaddrinfo \
freezero \
fstatfs \
fstatvfs \
futimes \
getaddrinfo \
getcwd \
getentropy \
getgrouplist \
getline \
getnameinfo \
getopt \
getpagesize \
getpeereid \
getpeerucred \
getpgid \
_getpty \
getrlimit \
getrandom \
getsid \
getttyent \
glob \
group_from_gid \
inet_aton \
inet_ntoa \
inet_ntop \
innetgr \
killpg \
llabs \
localtime_r \
login_getcapbool \
login_getpwclass \
memmem \
memmove \
memset_s \
mkdtemp \
ngetaddrinfo \
nsleep \
ogetaddrinfo \
openlog_r \
pledge \
poll \
ppoll \
prctl \
procctl \
pselect \
pstat \
raise \
readpassphrase \
reallocarray \
realpath \
recvmsg \
recallocarray \
rresvport_af \
sendmsg \
setdtablesize \
setegid \
setenv \
seteuid \
setgroupent \
setgroups \
setlinebuf \
setlogin \
setpassent\
setpcred \
setproctitle \
setregid \
setreuid \
setrlimit \
setsid \
setvbuf \
sigaction \
sigvec \
snprintf \
socketpair \
statfs \
statvfs \
strcasestr \
strdup \
strerror \
strlcat \
strlcpy \
strmode \
strndup \
strnlen \
strnvis \
strptime \
strsignal \
strtonum \
strtoll \
strtoul \
strtoull \
swap32 \
sysconf \
tcgetpgrp \
timegm \
timingsafe_bcmp \
truncate \
unsetenv \
updwtmpx \
utimensat \
user_from_uid \
usleep \
vasprintf \
vsnprintf \
waitpid \
warn \
])
AC_CHECK_DECLS([bzero, memmem])
dnl Wide character support.
AC_CHECK_FUNCS([mblen mbtowc nl_langinfo wcwidth])
TEST_SSH_UTF8=${TEST_SSH_UTF8:=yes}
AC_MSG_CHECKING([for utf8 locale support])
AC_RUN_IFELSE(
[AC_LANG_PROGRAM([[
#include <locale.h>
#include <stdlib.h>
]], [[
char *loc = setlocale(LC_CTYPE, "en_US.UTF-8");
if (loc != NULL)
exit(0);
exit(1);
]])],
AC_MSG_RESULT(yes),
[AC_MSG_RESULT(no)
TEST_SSH_UTF8=no],
AC_MSG_WARN([cross compiling: assuming yes])
)
AC_LINK_IFELSE(
[AC_LANG_PROGRAM(
[[ #include <ctype.h> ]],
[[ return (isblank('a')); ]])],
[AC_DEFINE([HAVE_ISBLANK], [1], [Define if you have isblank(3C).])
])
disable_pkcs11=
AC_ARG_ENABLE([pkcs11],
[ --disable-pkcs11 disable PKCS#11 support code [no]],
[
if test "x$enableval" = "xno" ; then
disable_pkcs11=1
fi
]
)
disable_sk=
AC_ARG_ENABLE([security-key],
[ --disable-security-key disable U2F/FIDO support code [no]],
[
if test "x$enableval" = "xno" ; then
disable_sk=1
fi
]
)
enable_sk_internal=
AC_ARG_WITH([security-key-builtin],
[ --with-security-key-builtin include builtin U2F/FIDO support],
[ enable_sk_internal=$withval ]
)
AC_SEARCH_LIBS([dlopen], [dl])
AC_CHECK_FUNCS([dlopen])
AC_CHECK_DECL([RTLD_NOW], [], [], [#include <dlfcn.h>])
# IRIX has a const char return value for gai_strerror()
AC_CHECK_FUNCS([gai_strerror], [
AC_DEFINE([HAVE_GAI_STRERROR])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
const char *gai_strerror(int);
]], [[
char *str;
str = gai_strerror(0);
]])], [
AC_DEFINE([HAVE_CONST_GAI_STRERROR_PROTO], [1],
[Define if gai_strerror() returns const char *])], [])])
AC_SEARCH_LIBS([nanosleep], [rt posix4], [AC_DEFINE([HAVE_NANOSLEEP], [1],
[Some systems put nanosleep outside of libc])])
AC_SEARCH_LIBS([clock_gettime], [rt],
[AC_DEFINE([HAVE_CLOCK_GETTIME], [1], [Have clock_gettime])])
dnl check if we need -D_REENTRANT for localtime_r declaration.
AC_CHECK_DECL([localtime_r], [],
[ saved_CPPFLAGS="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS -D_REENTRANT"
unset ac_cv_have_decl_localtime_r
AC_CHECK_DECL([localtime_r], [],
[ CPPFLAGS="$saved_CPPFLAGS" ],
[ #include <time.h> ]
)
],
[ #include <time.h> ]
)
dnl Make sure prototypes are defined for these before using them.
AC_CHECK_DECL([strsep],
[AC_CHECK_FUNCS([strsep])],
[],
[
#ifdef HAVE_STRING_H
# include <string.h>
#endif
])
dnl tcsendbreak might be a macro
AC_CHECK_DECL([tcsendbreak],
[AC_DEFINE([HAVE_TCSENDBREAK])],
[AC_CHECK_FUNCS([tcsendbreak])],
[#include <termios.h>]
)
AC_CHECK_DECLS([h_errno], , ,[#include <netdb.h>])
AC_CHECK_DECLS([SHUT_RD, getpeereid], , ,
[
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
])
AC_CHECK_DECLS([O_NONBLOCK], , ,
[
#include <sys/types.h>
#ifdef HAVE_SYS_STAT_H
# include <sys/stat.h>
#endif
#ifdef HAVE_FCNTL_H
# include <fcntl.h>
#endif
])
AC_CHECK_DECLS([ftruncate, getentropy], , ,
[
#include <sys/types.h>
#include <unistd.h>
])
AC_CHECK_DECLS([readv, writev], , , [
#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>
])
AC_CHECK_DECLS([MAXSYMLINKS], , , [
#include <sys/param.h>
])
AC_CHECK_DECLS([offsetof], , , [
#include <stddef.h>
])
# extra bits for select(2)
AC_CHECK_DECLS([howmany, NFDBITS], [], [], [[
#include <sys/param.h>
#include <sys/types.h>
#ifdef HAVE_SYS_SYSMACROS_H
#include <sys/sysmacros.h>
#endif
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
]])
AC_CHECK_TYPES([fd_mask], [], [], [[
#include <sys/param.h>
#include <sys/types.h>
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
]])
AC_CHECK_FUNCS([setresuid], [
dnl Some platorms have setresuid that isn't implemented, test for this
AC_MSG_CHECKING([if setresuid seems to work])
AC_RUN_IFELSE(
[AC_LANG_PROGRAM([[
-#include <stdlib.h>
#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
]], [[
errno=0;
setresuid(0,0,0);
if (errno==ENOSYS)
exit(1);
else
exit(0);
]])],
[AC_MSG_RESULT([yes])],
[AC_DEFINE([BROKEN_SETRESUID], [1],
[Define if your setresuid() is broken])
AC_MSG_RESULT([not implemented])],
[AC_MSG_WARN([cross compiling: not checking setresuid])]
)
])
AC_CHECK_FUNCS([setresgid], [
dnl Some platorms have setresgid that isn't implemented, test for this
AC_MSG_CHECKING([if setresgid seems to work])
AC_RUN_IFELSE(
[AC_LANG_PROGRAM([[
-#include <stdlib.h>
#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
]], [[
errno=0;
setresgid(0,0,0);
if (errno==ENOSYS)
exit(1);
else
exit(0);
]])],
[AC_MSG_RESULT([yes])],
[AC_DEFINE([BROKEN_SETRESGID], [1],
[Define if your setresgid() is broken])
AC_MSG_RESULT([not implemented])],
[AC_MSG_WARN([cross compiling: not checking setresuid])]
)
])
AC_MSG_CHECKING([for working fflush(NULL)])
AC_RUN_IFELSE(
[AC_LANG_PROGRAM([[
#include <stdio.h>
#include <stdlib.h>
]],
[[fflush(NULL); exit(0);]])],
AC_MSG_RESULT([yes]),
[AC_MSG_RESULT([no])
AC_DEFINE([FFLUSH_NULL_BUG], [1],
[define if fflush(NULL) does not work])],
AC_MSG_WARN([cross compiling: assuming working])
)
dnl Checks for time functions
AC_CHECK_FUNCS([gettimeofday time])
dnl Checks for utmp functions
AC_CHECK_FUNCS([endutent getutent getutid getutline pututline setutent])
AC_CHECK_FUNCS([utmpname])
dnl Checks for utmpx functions
AC_CHECK_FUNCS([endutxent getutxent getutxid getutxline getutxuser pututxline])
AC_CHECK_FUNCS([setutxdb setutxent utmpxname])
dnl Checks for lastlog functions
AC_CHECK_FUNCS([getlastlogxbyname])
AC_CHECK_FUNC([daemon],
[AC_DEFINE([HAVE_DAEMON], [1], [Define if your libraries define daemon()])],
[AC_CHECK_LIB([bsd], [daemon],
[LIBS="$LIBS -lbsd"; AC_DEFINE([HAVE_DAEMON])])]
)
AC_CHECK_FUNC([getpagesize],
[AC_DEFINE([HAVE_GETPAGESIZE], [1],
[Define if your libraries define getpagesize()])],
[AC_CHECK_LIB([ucb], [getpagesize],
[LIBS="$LIBS -lucb"; AC_DEFINE([HAVE_GETPAGESIZE])])]
)
# Check for broken snprintf
if test "x$ac_cv_func_snprintf" = "xyes" ; then
AC_MSG_CHECKING([whether snprintf correctly terminates long strings])
AC_RUN_IFELSE(
[AC_LANG_PROGRAM([[
#include <stdio.h>
#include <stdlib.h>
]],
[[
char b[5];
snprintf(b,5,"123456789");
exit(b[4]!='\0');
]])],
[AC_MSG_RESULT([yes])],
[
AC_MSG_RESULT([no])
AC_DEFINE([BROKEN_SNPRINTF], [1],
[Define if your snprintf is busted])
AC_MSG_WARN([****** Your snprintf() function is broken, complain to your vendor])
],
[ AC_MSG_WARN([cross compiling: Assuming working snprintf()]) ]
)
fi
if test "x$ac_cv_func_snprintf" = "xyes" ; then
AC_MSG_CHECKING([whether snprintf understands %zu])
AC_RUN_IFELSE(
[AC_LANG_PROGRAM([[
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
]],
[[
size_t a = 1, b = 2;
char z[128];
snprintf(z, sizeof z, "%zu%zu", a, b);
exit(strcmp(z, "12"));
]])],
[AC_MSG_RESULT([yes])],
[
AC_MSG_RESULT([no])
AC_DEFINE([BROKEN_SNPRINTF], [1],
[snprintf does not understand %zu])
],
[ AC_MSG_WARN([cross compiling: Assuming working snprintf()]) ]
)
fi
# We depend on vsnprintf returning the right thing on overflow: the
# number of characters it tried to create (as per SUSv3)
if test "x$ac_cv_func_vsnprintf" = "xyes" ; then
AC_MSG_CHECKING([whether vsnprintf returns correct values on overflow])
AC_RUN_IFELSE(
[AC_LANG_PROGRAM([[
#include <sys/types.h>
#include <stdio.h>
#include <stdarg.h>
int x_snprintf(char *str, size_t count, const char *fmt, ...)
{
size_t ret;
va_list ap;
va_start(ap, fmt);
ret = vsnprintf(str, count, fmt, ap);
va_end(ap);
return ret;
}
]], [[
char x[1];
if (x_snprintf(x, 1, "%s %d", "hello", 12345) != 11)
return 1;
if (x_snprintf(NULL, 0, "%s %d", "hello", 12345) != 11)
return 1;
return 0;
]])],
[AC_MSG_RESULT([yes])],
[
AC_MSG_RESULT([no])
AC_DEFINE([BROKEN_SNPRINTF], [1],
[Define if your snprintf is busted])
AC_MSG_WARN([****** Your vsnprintf() function is broken, complain to your vendor])
],
[ AC_MSG_WARN([cross compiling: Assuming working vsnprintf()]) ]
)
fi
# On systems where [v]snprintf is broken, but is declared in stdio,
# check that the fmt argument is const char * or just char *.
# This is only useful for when BROKEN_SNPRINTF
AC_MSG_CHECKING([whether snprintf can declare const char *fmt])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <stdio.h>
int snprintf(char *a, size_t b, const char *c, ...) { return 0; }
]], [[
snprintf(0, 0, 0);
]])],
[AC_MSG_RESULT([yes])
AC_DEFINE([SNPRINTF_CONST], [const],
[Define as const if snprintf() can declare const char *fmt])],
[AC_MSG_RESULT([no])
AC_DEFINE([SNPRINTF_CONST], [/* not const */])])
# Check for missing getpeereid (or equiv) support
NO_PEERCHECK=""
if test "x$ac_cv_func_getpeereid" != "xyes" -a "x$ac_cv_func_getpeerucred" != "xyes"; then
AC_MSG_CHECKING([whether system supports SO_PEERCRED getsockopt])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <sys/types.h>
#include <sys/socket.h>]], [[int i = SO_PEERCRED;]])],
[ AC_MSG_RESULT([yes])
AC_DEFINE([HAVE_SO_PEERCRED], [1], [Have PEERCRED socket option])
], [AC_MSG_RESULT([no])
NO_PEERCHECK=1
])
fi
dnl make sure that openpty does not reacquire controlling terminal
if test ! -z "$check_for_openpty_ctty_bug"; then
AC_MSG_CHECKING([if openpty correctly handles controlling tty])
AC_RUN_IFELSE(
[AC_LANG_PROGRAM([[
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
+#ifdef HAVE_PTY_H
+# include <pty.h>
+#endif
#include <sys/fcntl.h>
#include <sys/types.h>
#include <sys/wait.h>
]], [[
pid_t pid;
int fd, ptyfd, ttyfd, status;
pid = fork();
if (pid < 0) { /* failed */
exit(1);
} else if (pid > 0) { /* parent */
waitpid(pid, &status, 0);
if (WIFEXITED(status))
exit(WEXITSTATUS(status));
else
exit(2);
} else { /* child */
close(0); close(1); close(2);
setsid();
openpty(&ptyfd, &ttyfd, NULL, NULL, NULL);
fd = open("/dev/tty", O_RDWR | O_NOCTTY);
if (fd >= 0)
exit(3); /* Acquired ctty: broken */
else
exit(0); /* Did not acquire ctty: OK */
}
]])],
[
AC_MSG_RESULT([yes])
],
[
AC_MSG_RESULT([no])
AC_DEFINE([SSHD_ACQUIRES_CTTY])
],
[
AC_MSG_RESULT([cross-compiling, assuming yes])
]
)
fi
if test "x$ac_cv_func_getaddrinfo" = "xyes" && \
test "x$check_for_hpux_broken_getaddrinfo" = "x1"; then
AC_MSG_CHECKING([if getaddrinfo seems to work])
AC_RUN_IFELSE(
[AC_LANG_PROGRAM([[
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netdb.h>
#include <errno.h>
#include <netinet/in.h>
#define TEST_PORT "2222"
]], [[
int err, sock;
struct addrinfo *gai_ai, *ai, hints;
char ntop[NI_MAXHOST], strport[NI_MAXSERV], *name = NULL;
memset(&hints, 0, sizeof(hints));
hints.ai_family = PF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;
err = getaddrinfo(name, TEST_PORT, &hints, &gai_ai);
if (err != 0) {
fprintf(stderr, "getaddrinfo failed (%s)", gai_strerror(err));
exit(1);
}
for (ai = gai_ai; ai != NULL; ai = ai->ai_next) {
if (ai->ai_family != AF_INET6)
continue;
err = getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop,
sizeof(ntop), strport, sizeof(strport),
NI_NUMERICHOST|NI_NUMERICSERV);
if (err != 0) {
if (err == EAI_SYSTEM)
perror("getnameinfo EAI_SYSTEM");
else
fprintf(stderr, "getnameinfo failed: %s\n",
gai_strerror(err));
exit(2);
}
sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
if (sock < 0)
perror("socket");
if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) {
if (errno == EBADF)
exit(3);
}
}
exit(0);
]])],
[
AC_MSG_RESULT([yes])
],
[
AC_MSG_RESULT([no])
AC_DEFINE([BROKEN_GETADDRINFO])
],
[
AC_MSG_RESULT([cross-compiling, assuming yes])
]
)
fi
if test "x$ac_cv_func_getaddrinfo" = "xyes" && \
test "x$check_for_aix_broken_getaddrinfo" = "x1"; then
AC_MSG_CHECKING([if getaddrinfo seems to work])
AC_RUN_IFELSE(
[AC_LANG_PROGRAM([[
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netdb.h>
#include <errno.h>
#include <netinet/in.h>
#define TEST_PORT "2222"
]], [[
int err, sock;
struct addrinfo *gai_ai, *ai, hints;
char ntop[NI_MAXHOST], strport[NI_MAXSERV], *name = NULL;
memset(&hints, 0, sizeof(hints));
hints.ai_family = PF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;
err = getaddrinfo(name, TEST_PORT, &hints, &gai_ai);
if (err != 0) {
fprintf(stderr, "getaddrinfo failed (%s)", gai_strerror(err));
exit(1);
}
for (ai = gai_ai; ai != NULL; ai = ai->ai_next) {
if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
continue;
err = getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop,
sizeof(ntop), strport, sizeof(strport),
NI_NUMERICHOST|NI_NUMERICSERV);
if (ai->ai_family == AF_INET && err != 0) {
perror("getnameinfo");
exit(2);
}
}
exit(0);
]])],
[
AC_MSG_RESULT([yes])
AC_DEFINE([AIX_GETNAMEINFO_HACK], [1],
[Define if you have a getaddrinfo that fails
for the all-zeros IPv6 address])
],
[
AC_MSG_RESULT([no])
AC_DEFINE([BROKEN_GETADDRINFO])
],
[
AC_MSG_RESULT([cross-compiling, assuming no])
]
)
fi
if test "x$ac_cv_func_getaddrinfo" = "xyes"; then
AC_CHECK_DECLS(AI_NUMERICSERV, , ,
[#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>])
fi
if test "x$check_for_conflicting_getspnam" = "x1"; then
AC_MSG_CHECKING([for conflicting getspnam in shadow.h])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <shadow.h>
#include <stdlib.h>
]],
[[ exit(0); ]])],
[
AC_MSG_RESULT([no])
],
[
AC_MSG_RESULT([yes])
AC_DEFINE([GETSPNAM_CONFLICTING_DEFS], [1],
[Conflicting defs for getspnam])
]
)
fi
dnl NetBSD added an strnvis and unfortunately made it incompatible with the
dnl existing one in OpenBSD and Linux's libbsd (the former having existed
dnl for over ten years). Despite this incompatibility being reported during
dnl development (see http://gnats.netbsd.org/44977) they still shipped it.
dnl Even more unfortunately FreeBSD and later MacOS picked up this incompatible
dnl implementation. Try to detect this mess, and assume the only safe option
dnl if we're cross compiling.
dnl
dnl OpenBSD, 2001: strnvis(char *dst, const char *src, size_t dlen, int flag);
dnl NetBSD: 2012, strnvis(char *dst, size_t dlen, const char *src, int flag);
if test "x$ac_cv_func_strnvis" = "xyes"; then
AC_MSG_CHECKING([for working strnvis])
AC_RUN_IFELSE(
[AC_LANG_PROGRAM([[
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <vis.h>
static void sighandler(int sig) { _exit(1); }
]], [[
char dst[16];
signal(SIGSEGV, sighandler);
if (strnvis(dst, "src", 4, 0) && strcmp(dst, "src") == 0)
exit(0);
exit(1)
]])],
[AC_MSG_RESULT([yes])],
[AC_MSG_RESULT([no])
AC_DEFINE([BROKEN_STRNVIS], [1], [strnvis detected broken])],
[AC_MSG_WARN([cross compiling: assuming broken])
AC_DEFINE([BROKEN_STRNVIS], [1], [strnvis assumed broken])]
)
fi
AC_MSG_CHECKING([if SA_RESTARTed signals interrupt select()])
AC_RUN_IFELSE(
[AC_LANG_PROGRAM([[
#ifdef HAVE_SYS_SELECT
# include <sys/select.h>
#endif
#include <sys/types.h>
#include <sys/time.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
static void sighandler(int sig) { }
]], [[
int r;
pid_t pid;
struct sigaction sa;
sa.sa_handler = sighandler;
sa.sa_flags = SA_RESTART;
(void)sigaction(SIGTERM, &sa, NULL);
if ((pid = fork()) == 0) { /* child */
pid = getppid();
sleep(1);
kill(pid, SIGTERM);
sleep(1);
if (getppid() == pid) /* if parent did not exit, shoot it */
kill(pid, SIGKILL);
exit(0);
} else { /* parent */
r = select(0, NULL, NULL, NULL, NULL);
}
exit(r == -1 ? 0 : 1);
]])],
[AC_MSG_RESULT([yes])],
[AC_MSG_RESULT([no])
AC_DEFINE([NO_SA_RESTART], [1],
[SA_RESTARTed signals do no interrupt select])],
[AC_MSG_WARN([cross compiling: assuming yes])]
)
AC_CHECK_FUNCS([getpgrp],[
AC_MSG_CHECKING([if getpgrp accepts zero args])
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM([[$ac_includes_default]], [[ getpgrp(); ]])],
[ AC_MSG_RESULT([yes])
AC_DEFINE([GETPGRP_VOID], [1], [getpgrp takes zero args])],
[ AC_MSG_RESULT([no])
AC_DEFINE([GETPGRP_VOID], [0], [getpgrp takes one arg])]
)
])
# Search for OpenSSL
saved_CPPFLAGS="$CPPFLAGS"
saved_LDFLAGS="$LDFLAGS"
+openssl_bin_PATH="$PATH"
AC_ARG_WITH([ssl-dir],
[ --with-ssl-dir=PATH Specify path to OpenSSL installation ],
[
if test "x$openssl" = "xno" ; then
AC_MSG_ERROR([cannot use --with-ssl-dir when OpenSSL disabled])
fi
if test "x$withval" != "xno" ; then
case "$withval" in
# Relative paths
./*|../*) withval="`pwd`/$withval"
esac
if test -d "$withval/lib"; then
libcrypto_path="${withval}/lib"
elif test -d "$withval/lib64"; then
libcrypto_path="$withval/lib64"
else
# Built but not installed
libcrypto_path="${withval}"
fi
if test -n "${rpath_opt}"; then
LDFLAGS="-L${libcrypto_path} ${rpath_opt}${libcrypto_path} ${LDFLAGS}"
else
LDFLAGS="-L${libcrypto_path} ${LDFLAGS}"
fi
if test -d "$withval/include"; then
CPPFLAGS="-I${withval}/include ${CPPFLAGS}"
else
CPPFLAGS="-I${withval} ${CPPFLAGS}"
fi
+ openssl_bin_PATH="${PATH}${PATH_SEPARATOR}${withval}/bin${PATH_SEPARATOR}${withval}/apps"
fi
]
)
+AC_PATH_PROGS([openssl_bin], openssl, [], [$openssl_bin_PATH])
+AC_SUBST(OPENSSL_BIN, [${openssl_bin}])
AC_ARG_WITH([openssl-header-check],
[ --without-openssl-header-check Disable OpenSSL version consistency check],
[
if test "x$withval" = "xno" ; then
openssl_check_nonfatal=1
fi
]
)
openssl_engine=no
AC_ARG_WITH([ssl-engine],
[ --with-ssl-engine Enable OpenSSL (hardware) ENGINE support ],
[
if test "x$withval" != "xno" ; then
if test "x$openssl" = "xno" ; then
AC_MSG_ERROR([cannot use --with-ssl-engine when OpenSSL disabled])
fi
openssl_engine=yes
fi
]
)
nocrypto_saved_LIBS="$LIBS"
if test "x$openssl" = "xyes" ; then
LIBS="-lcrypto $LIBS"
CHANNELLIBS="-lcrypto $CHANNELLIBS"
AC_TRY_LINK_FUNC([RAND_add], ,
[AC_MSG_ERROR([*** working libcrypto not found, check config.log])])
AC_CHECK_HEADER([openssl/opensslv.h], ,
[AC_MSG_ERROR([*** OpenSSL headers missing - please install first or check config.log ***])])
# Determine OpenSSL header version
AC_MSG_CHECKING([OpenSSL header version])
AC_RUN_IFELSE(
[AC_LANG_PROGRAM([[
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <openssl/opensslv.h>
#define DATA "conftest.sslincver"
]], [[
FILE *fd;
int rc;
fd = fopen(DATA,"w");
if(fd == NULL)
exit(1);
if ((rc = fprintf(fd, "%08lx (%s)\n",
(unsigned long)OPENSSL_VERSION_NUMBER,
OPENSSL_VERSION_TEXT)) < 0)
exit(1);
exit(0);
]])],
[
ssl_header_ver=`cat conftest.sslincver`
AC_MSG_RESULT([$ssl_header_ver])
],
[
AC_MSG_RESULT([not found])
AC_MSG_ERROR([OpenSSL version header not found.])
],
[
AC_MSG_WARN([cross compiling: not checking])
]
)
# Determining OpenSSL library version is version dependent.
AC_CHECK_FUNCS([OpenSSL_version OpenSSL_version_num])
# Determine OpenSSL library version
AC_MSG_CHECKING([OpenSSL library version])
AC_RUN_IFELSE(
[AC_LANG_PROGRAM([[
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/opensslv.h>
#include <openssl/crypto.h>
#define DATA "conftest.ssllibver"
]], [[
FILE *fd;
int rc;
fd = fopen(DATA,"w");
if(fd == NULL)
exit(1);
#ifndef OPENSSL_VERSION
# define OPENSSL_VERSION SSLEAY_VERSION
#endif
#ifndef HAVE_OPENSSL_VERSION
# define OpenSSL_version SSLeay_version
#endif
#ifndef HAVE_OPENSSL_VERSION_NUM
# define OpenSSL_version_num SSLeay
#endif
if ((rc = fprintf(fd, "%08lx (%s)\n",
(unsigned long)OpenSSL_version_num(),
OpenSSL_version(OPENSSL_VERSION))) < 0)
exit(1);
exit(0);
]])],
[
ssl_library_ver=`cat conftest.ssllibver`
# Check version is supported.
case "$ssl_library_ver" in
10000*|0*)
AC_MSG_ERROR([OpenSSL >= 1.0.1 required (have "$ssl_library_ver")])
;;
100*) ;; # 1.0.x
101000[[0123456]]*)
# https://github.com/openssl/openssl/pull/4613
AC_MSG_ERROR([OpenSSL 1.1.x versions prior to 1.1.0g have a bug that breaks their use with OpenSSH (have "$ssl_library_ver")])
;;
101*) ;; # 1.1.x
200*) ;; # LibreSSL
300*)
# OpenSSL 3; we use the 1.1x API
CPPFLAGS="$CPPFLAGS -DOPENSSL_API_COMPAT=0x10100000L"
;;
- 301*)
+ 301*|302*)
# OpenSSL development branch; request 1.1x API
CPPFLAGS="$CPPFLAGS -DOPENSSL_API_COMPAT=0x10100000L"
;;
*)
AC_MSG_ERROR([Unknown/unsupported OpenSSL version ("$ssl_library_ver")])
;;
esac
AC_MSG_RESULT([$ssl_library_ver])
],
[
AC_MSG_RESULT([not found])
AC_MSG_ERROR([OpenSSL library not found.])
],
[
AC_MSG_WARN([cross compiling: not checking])
]
)
case "$host" in
x86_64-*)
case "$ssl_library_ver" in
3000004*)
AC_MSG_ERROR([OpenSSL 3.0.4 has a potential RCE in its RSA implementation (CVE-2022-2274)])
;;
esac
esac
# Sanity check OpenSSL headers
AC_MSG_CHECKING([whether OpenSSL's headers match the library])
AC_RUN_IFELSE(
[AC_LANG_PROGRAM([[
#include <stdlib.h>
#include <string.h>
#include <openssl/opensslv.h>
#include <openssl/crypto.h>
]], [[
#ifndef HAVE_OPENSSL_VERSION_NUM
# define OpenSSL_version_num SSLeay
#endif
exit(OpenSSL_version_num() == OPENSSL_VERSION_NUMBER ? 0 : 1);
]])],
[
AC_MSG_RESULT([yes])
],
[
AC_MSG_RESULT([no])
if test "x$openssl_check_nonfatal" = "x"; then
AC_MSG_ERROR([Your OpenSSL headers do not match your
library. Check config.log for details.
If you are sure your installation is consistent, you can disable the check
by running "./configure --without-openssl-header-check".
Also see contrib/findssl.sh for help identifying header/library mismatches.
])
else
AC_MSG_WARN([Your OpenSSL headers do not match your
library. Check config.log for details.
Also see contrib/findssl.sh for help identifying header/library mismatches.])
fi
],
[
AC_MSG_WARN([cross compiling: not checking])
]
)
AC_MSG_CHECKING([if programs using OpenSSL functions will link])
AC_LINK_IFELSE(
[AC_LANG_PROGRAM([[ #include <openssl/err.h> ]],
[[ ERR_load_crypto_strings(); ]])],
[
AC_MSG_RESULT([yes])
],
[
AC_MSG_RESULT([no])
LIBS="$LIBS -ldl"
AC_MSG_CHECKING([if programs using OpenSSL need -ldl])
AC_LINK_IFELSE(
[AC_LANG_PROGRAM([[ #include <openssl/err.h> ]],
[[ ERR_load_crypto_strings(); ]])],
[
AC_MSG_RESULT([yes])
CHANNELLIBS="$CHANNELLIBS -ldl"
],
[
AC_MSG_RESULT([no])
]
)
]
)
AC_CHECK_FUNCS([ \
BN_is_prime_ex \
DES_crypt \
DSA_generate_parameters_ex \
EVP_DigestFinal_ex \
EVP_DigestInit_ex \
EVP_MD_CTX_cleanup \
EVP_MD_CTX_copy_ex \
EVP_MD_CTX_init \
HMAC_CTX_init \
RSA_generate_key_ex \
RSA_get_default_method \
])
# OpenSSL_add_all_algorithms may be a macro.
AC_CHECK_FUNC(OpenSSL_add_all_algorithms,
AC_DEFINE(HAVE_OPENSSL_ADD_ALL_ALGORITHMS, 1, [as a function]),
AC_CHECK_DECL(OpenSSL_add_all_algorithms,
AC_DEFINE(HAVE_OPENSSL_ADD_ALL_ALGORITHMS, 1, [as a macro]), ,
[[#include <openssl/evp.h>]]
)
)
# LibreSSL/OpenSSL 1.1x API
AC_CHECK_FUNCS([ \
OPENSSL_init_crypto \
DH_get0_key \
DH_get0_pqg \
DH_set0_key \
DH_set_length \
DH_set0_pqg \
DSA_get0_key \
DSA_get0_pqg \
DSA_set0_key \
DSA_set0_pqg \
DSA_SIG_get0 \
DSA_SIG_set0 \
ECDSA_SIG_get0 \
ECDSA_SIG_set0 \
EVP_CIPHER_CTX_iv \
EVP_CIPHER_CTX_iv_noconst \
EVP_CIPHER_CTX_get_iv \
EVP_CIPHER_CTX_get_updated_iv \
EVP_CIPHER_CTX_set_iv \
RSA_get0_crt_params \
RSA_get0_factors \
RSA_get0_key \
RSA_set0_crt_params \
RSA_set0_factors \
RSA_set0_key \
RSA_meth_free \
RSA_meth_dup \
RSA_meth_set1_name \
RSA_meth_get_finish \
RSA_meth_set_priv_enc \
RSA_meth_set_priv_dec \
RSA_meth_set_finish \
EVP_PKEY_get0_RSA \
EVP_MD_CTX_new \
EVP_MD_CTX_free \
EVP_chacha20 \
])
if test "x$openssl_engine" = "xyes" ; then
AC_MSG_CHECKING([for OpenSSL ENGINE support])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <openssl/engine.h>
]], [[
ENGINE_load_builtin_engines();
ENGINE_register_all_complete();
]])],
[ AC_MSG_RESULT([yes])
AC_DEFINE([USE_OPENSSL_ENGINE], [1],
[Enable OpenSSL engine support])
], [ AC_MSG_ERROR([OpenSSL ENGINE support not found])
])
fi
# Check for OpenSSL without EVP_aes_{192,256}_cbc
AC_MSG_CHECKING([whether OpenSSL has crippled AES support])
AC_LINK_IFELSE(
[AC_LANG_PROGRAM([[
#include <stdlib.h>
#include <string.h>
#include <openssl/evp.h>
]], [[
exit(EVP_aes_192_cbc() == NULL || EVP_aes_256_cbc() == NULL);
]])],
[
AC_MSG_RESULT([no])
],
[
AC_MSG_RESULT([yes])
AC_DEFINE([OPENSSL_LOBOTOMISED_AES], [1],
[libcrypto is missing AES 192 and 256 bit functions])
]
)
AC_MSG_CHECKING([if EVP_DigestUpdate returns an int])
AC_LINK_IFELSE(
[AC_LANG_PROGRAM([[
#include <stdlib.h>
#include <string.h>
#include <openssl/evp.h>
]], [[
if(EVP_DigestUpdate(NULL, NULL,0))
exit(0);
]])],
[
AC_MSG_RESULT([yes])
],
[
AC_MSG_RESULT([no])
AC_DEFINE([OPENSSL_EVP_DIGESTUPDATE_VOID], [1],
[Define if EVP_DigestUpdate returns void])
]
)
# Check for SHA256, SHA384 and SHA512 support in OpenSSL
AC_CHECK_FUNCS([EVP_sha256 EVP_sha384 EVP_sha512])
# Check complete ECC support in OpenSSL
AC_MSG_CHECKING([whether OpenSSL has NID_X9_62_prime256v1])
AC_LINK_IFELSE(
[AC_LANG_PROGRAM([[
#include <openssl/ec.h>
#include <openssl/ecdh.h>
#include <openssl/ecdsa.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/opensslv.h>
]], [[
EC_KEY *e = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
const EVP_MD *m = EVP_sha256(); /* We need this too */
]])],
[ AC_MSG_RESULT([yes])
enable_nistp256=1 ],
[ AC_MSG_RESULT([no]) ]
)
AC_MSG_CHECKING([whether OpenSSL has NID_secp384r1])
AC_LINK_IFELSE(
[AC_LANG_PROGRAM([[
#include <openssl/ec.h>
#include <openssl/ecdh.h>
#include <openssl/ecdsa.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/opensslv.h>
]], [[
EC_KEY *e = EC_KEY_new_by_curve_name(NID_secp384r1);
const EVP_MD *m = EVP_sha384(); /* We need this too */
]])],
[ AC_MSG_RESULT([yes])
enable_nistp384=1 ],
[ AC_MSG_RESULT([no]) ]
)
AC_MSG_CHECKING([whether OpenSSL has NID_secp521r1])
AC_LINK_IFELSE(
[AC_LANG_PROGRAM([[
#include <openssl/ec.h>
#include <openssl/ecdh.h>
#include <openssl/ecdsa.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/opensslv.h>
]], [[
EC_KEY *e = EC_KEY_new_by_curve_name(NID_secp521r1);
const EVP_MD *m = EVP_sha512(); /* We need this too */
]])],
[ AC_MSG_RESULT([yes])
AC_MSG_CHECKING([if OpenSSL's NID_secp521r1 is functional])
AC_RUN_IFELSE(
[AC_LANG_PROGRAM([[
#include <stdlib.h>
#include <openssl/ec.h>
#include <openssl/ecdh.h>
#include <openssl/ecdsa.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/opensslv.h>
]],[[
EC_KEY *e = EC_KEY_new_by_curve_name(NID_secp521r1);
const EVP_MD *m = EVP_sha512(); /* We need this too */
exit(e == NULL || m == NULL);
]])],
[ AC_MSG_RESULT([yes])
enable_nistp521=1 ],
[ AC_MSG_RESULT([no]) ],
[ AC_MSG_WARN([cross-compiling: assuming yes])
enable_nistp521=1 ]
)],
AC_MSG_RESULT([no])
)
if test x$enable_nistp256 = x1 || test x$enable_nistp384 = x1 || \
test x$enable_nistp521 = x1; then
AC_DEFINE(OPENSSL_HAS_ECC, [1], [OpenSSL has ECC])
AC_CHECK_FUNCS([EC_KEY_METHOD_new])
openssl_ecc=yes
else
openssl_ecc=no
fi
if test x$enable_nistp256 = x1; then
AC_DEFINE([OPENSSL_HAS_NISTP256], [1],
[libcrypto has NID_X9_62_prime256v1])
else
unsupported_algorithms="$unsupported_algorithms \
ecdsa-sha2-nistp256 \
ecdh-sha2-nistp256 \
ecdsa-sha2-nistp256-cert-v01@openssh.com"
fi
if test x$enable_nistp384 = x1; then
AC_DEFINE([OPENSSL_HAS_NISTP384], [1], [libcrypto has NID_secp384r1])
else
unsupported_algorithms="$unsupported_algorithms \
ecdsa-sha2-nistp384 \
ecdh-sha2-nistp384 \
ecdsa-sha2-nistp384-cert-v01@openssh.com"
fi
if test x$enable_nistp521 = x1; then
AC_DEFINE([OPENSSL_HAS_NISTP521], [1], [libcrypto has NID_secp521r1])
else
unsupported_algorithms="$unsupported_algorithms \
ecdh-sha2-nistp521 \
ecdsa-sha2-nistp521 \
ecdsa-sha2-nistp521-cert-v01@openssh.com"
fi
fi
# PKCS11/U2F depend on OpenSSL and dlopen().
enable_pkcs11=yes
enable_sk=yes
if test "x$openssl" != "xyes" ; then
enable_pkcs11="disabled; missing libcrypto"
fi
if test "x$ac_cv_func_dlopen" != "xyes" ; then
enable_pkcs11="disabled; missing dlopen(3)"
enable_sk="disabled; missing dlopen(3)"
fi
if test "x$ac_cv_have_decl_RTLD_NOW" != "xyes" ; then
enable_pkcs11="disabled; missing RTLD_NOW"
enable_sk="disabled; missing RTLD_NOW"
fi
if test ! -z "$disable_pkcs11" ; then
enable_pkcs11="disabled by user"
fi
if test ! -z "$disable_sk" ; then
enable_sk="disabled by user"
fi
AC_MSG_CHECKING([whether to enable PKCS11])
if test "x$enable_pkcs11" = "xyes" ; then
AC_DEFINE([ENABLE_PKCS11], [], [Enable for PKCS#11 support])
fi
AC_MSG_RESULT([$enable_pkcs11])
AC_MSG_CHECKING([whether to enable U2F])
if test "x$enable_sk" = "xyes" ; then
AC_DEFINE([ENABLE_SK], [], [Enable for U2F/FIDO support])
AC_SUBST(SK_DUMMY_LIBRARY, [regress/misc/sk-dummy/sk-dummy.so])
else
# Do not try to build sk-dummy library.
AC_SUBST(SK_DUMMY_LIBRARY, [""])
fi
AC_MSG_RESULT([$enable_sk])
# Now check for built-in security key support.
if test "x$enable_sk" = "xyes" -a "x$enable_sk_internal" != "xno" ; then
use_pkgconfig_for_libfido2=
if test "x$PKGCONFIG" != "xno"; then
AC_MSG_CHECKING([if $PKGCONFIG knows about libfido2])
if "$PKGCONFIG" libfido2; then
AC_MSG_RESULT([yes])
use_pkgconfig_for_libfido2=yes
else
AC_MSG_RESULT([no])
fi
fi
if test "x$use_pkgconfig_for_libfido2" = "xyes"; then
LIBFIDO2=`$PKGCONFIG --libs libfido2`
CPPFLAGS="$CPPFLAGS `$PKGCONFIG --cflags libfido2`"
else
LIBFIDO2="-lprivatefido2 -lprivatecbor"
fi
OTHERLIBS=`echo $LIBFIDO2 | sed 's/-lfido2//'`
fido2_error=
AC_CHECK_LIB([privatefido2], [fido_init],
[ ],
[ fido2_error="missing/unusable libfido2" ],
[ $OTHERLIBS ]
)
AC_CHECK_HEADER([fido.h], [],
[ fido2_error="missing fido.h from libfido2" ])
AC_CHECK_HEADER([fido/credman.h], [],
[ fido2_error="missing fido/credman.h from libfido2" ],
[ #include <fido.h> ]
)
AC_MSG_CHECKING([for usable libfido2 installation])
if test ! -z "$fido2_error" ; then
AC_MSG_RESULT([$fido2_error])
if test "x$enable_sk_internal" = "xyes" ; then
AC_MSG_ERROR([No usable libfido2 library/headers found])
fi
LIBFIDO2=""
else
AC_MSG_RESULT([yes])
AC_SUBST([LIBFIDO2])
AC_DEFINE([ENABLE_SK_INTERNAL], [],
[Enable for built-in U2F/FIDO support])
enable_sk="built-in"
saved_LIBS="$LIBS"
- LIBS="$LIBS $LIBFIDO2"
+ LIBS="$LIBFIDO2 $LIBS"
AC_CHECK_FUNCS([ \
fido_assert_set_clientdata \
fido_cred_prot \
fido_cred_set_prot \
fido_cred_set_clientdata \
fido_dev_get_touch_begin \
fido_dev_get_touch_status \
fido_dev_supports_cred_prot \
fido_dev_is_winhello \
])
LIBS="$saved_LIBS"
fi
fi
AC_CHECK_FUNCS([ \
arc4random \
arc4random_buf \
arc4random_stir \
arc4random_uniform \
])
### Configure cryptographic random number support
# Check whether OpenSSL seeds itself
if test "x$openssl" = "xyes" ; then
AC_MSG_CHECKING([whether OpenSSL's PRNG is internally seeded])
AC_RUN_IFELSE(
[AC_LANG_PROGRAM([[
#include <stdlib.h>
#include <string.h>
#include <openssl/rand.h>
]], [[
exit(RAND_status() == 1 ? 0 : 1);
]])],
[
OPENSSL_SEEDS_ITSELF=yes
AC_MSG_RESULT([yes])
],
[
AC_MSG_RESULT([no])
],
[
AC_MSG_WARN([cross compiling: assuming yes])
# This is safe, since we will fatal() at runtime if
# OpenSSL is not seeded correctly.
OPENSSL_SEEDS_ITSELF=yes
]
)
fi
# PRNGD TCP socket
AC_ARG_WITH([prngd-port],
[ --with-prngd-port=PORT read entropy from PRNGD/EGD TCP localhost:PORT],
[
case "$withval" in
no)
withval=""
;;
[[0-9]]*)
;;
*)
AC_MSG_ERROR([You must specify a numeric port number for --with-prngd-port])
;;
esac
if test ! -z "$withval" ; then
PRNGD_PORT="$withval"
AC_DEFINE_UNQUOTED([PRNGD_PORT], [$PRNGD_PORT],
[Port number of PRNGD/EGD random number socket])
fi
]
)
# PRNGD Unix domain socket
AC_ARG_WITH([prngd-socket],
[ --with-prngd-socket=FILE read entropy from PRNGD/EGD socket FILE (default=/var/run/egd-pool)],
[
case "$withval" in
yes)
withval="/var/run/egd-pool"
;;
no)
withval=""
;;
/*)
;;
*)
AC_MSG_ERROR([You must specify an absolute path to the entropy socket])
;;
esac
if test ! -z "$withval" ; then
if test ! -z "$PRNGD_PORT" ; then
AC_MSG_ERROR([You may not specify both a PRNGD/EGD port and socket])
fi
if test ! -r "$withval" ; then
AC_MSG_WARN([Entropy socket is not readable])
fi
PRNGD_SOCKET="$withval"
AC_DEFINE_UNQUOTED([PRNGD_SOCKET], ["$PRNGD_SOCKET"],
[Location of PRNGD/EGD random number socket])
fi
],
[
# Check for existing socket only if we don't have a random device already
if test "x$OPENSSL_SEEDS_ITSELF" != "xyes" ; then
AC_MSG_CHECKING([for PRNGD/EGD socket])
# Insert other locations here
for sock in /var/run/egd-pool /dev/egd-pool /etc/entropy; do
if test -r $sock && $TEST_MINUS_S_SH -c "test -S $sock -o -p $sock" ; then
PRNGD_SOCKET="$sock"
AC_DEFINE_UNQUOTED([PRNGD_SOCKET], ["$PRNGD_SOCKET"])
break;
fi
done
if test ! -z "$PRNGD_SOCKET" ; then
AC_MSG_RESULT([$PRNGD_SOCKET])
else
AC_MSG_RESULT([not found])
fi
fi
]
)
# Which randomness source do we use?
if test ! -z "$PRNGD_PORT" ; then
RAND_MSG="PRNGd port $PRNGD_PORT"
elif test ! -z "$PRNGD_SOCKET" ; then
RAND_MSG="PRNGd socket $PRNGD_SOCKET"
elif test ! -z "$OPENSSL_SEEDS_ITSELF" ; then
AC_DEFINE([OPENSSL_PRNG_ONLY], [1],
[Define if you want the OpenSSL internally seeded PRNG only])
RAND_MSG="OpenSSL internal ONLY"
elif test "x$openssl" = "xno" ; then
AC_MSG_WARN([OpenSSH will use /dev/urandom as a source of random numbers. It will fail if this device is not supported or accessible])
else
AC_MSG_ERROR([OpenSSH has no source of random numbers. Please configure OpenSSL with an entropy source or re-run configure using one of the --with-prngd-port or --with-prngd-socket options])
fi
LIBS="$nocrypto_saved_LIBS"
saved_LIBS="$LIBS"
AC_CHECK_LIB([iaf], [ia_openinfo], [
LIBS="$LIBS -liaf"
AC_CHECK_FUNCS([set_id], [SSHDLIBS="$SSHDLIBS -liaf"
AC_DEFINE([HAVE_LIBIAF], [1],
[Define if system has libiaf that supports set_id])
])
])
LIBS="$saved_LIBS"
# Check for crypt() in libcrypt. If we have it, we only need it for sshd.
saved_LIBS="$LIBS"
AC_CHECK_LIB([crypt], [crypt], [
LIBS="-lcrypt $LIBS"
SSHDLIBS="-lcrypt $SSHDLIBS"
])
AC_CHECK_FUNCS([crypt])
LIBS="$saved_LIBS"
# Check for PAM libs
PAM_MSG="no"
AC_ARG_WITH([pam],
[ --with-pam Enable PAM support ],
[
if test "x$withval" != "xno" ; then
if test "x$ac_cv_header_security_pam_appl_h" != "xyes" && \
test "x$ac_cv_header_pam_pam_appl_h" != "xyes" ; then
AC_MSG_ERROR([PAM headers not found])
fi
saved_LIBS="$LIBS"
AC_CHECK_LIB([dl], [dlopen], , )
AC_CHECK_LIB([pam], [pam_set_item], , [AC_MSG_ERROR([*** libpam missing])])
AC_CHECK_FUNCS([pam_getenvlist])
AC_CHECK_FUNCS([pam_putenv])
LIBS="$saved_LIBS"
PAM_MSG="yes"
SSHDLIBS="$SSHDLIBS -lpam"
AC_DEFINE([USE_PAM], [1],
[Define if you want to enable PAM support])
if test $ac_cv_lib_dl_dlopen = yes; then
case "$LIBS" in
*-ldl*)
# libdl already in LIBS
;;
*)
SSHDLIBS="$SSHDLIBS -ldl"
;;
esac
fi
fi
]
)
AC_ARG_WITH([pam-service],
[ --with-pam-service=name Specify PAM service name ],
[
if test "x$withval" != "xno" && \
test "x$withval" != "xyes" ; then
AC_DEFINE_UNQUOTED([SSHD_PAM_SERVICE],
["$withval"], [sshd PAM service name])
fi
]
)
# Check for older PAM
if test "x$PAM_MSG" = "xyes" ; then
# Check PAM strerror arguments (old PAM)
AC_MSG_CHECKING([whether pam_strerror takes only one argument])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <stdlib.h>
#if defined(HAVE_SECURITY_PAM_APPL_H)
#include <security/pam_appl.h>
#elif defined (HAVE_PAM_PAM_APPL_H)
#include <pam/pam_appl.h>
#endif
]], [[
(void)pam_strerror((pam_handle_t *)NULL, -1);
]])], [AC_MSG_RESULT([no])], [
AC_DEFINE([HAVE_OLD_PAM], [1],
[Define if you have an old version of PAM
which takes only one argument to pam_strerror])
AC_MSG_RESULT([yes])
PAM_MSG="yes (old library)"
])
fi
case "$host" in
*-*-cygwin*)
SSH_PRIVSEP_USER=CYGWIN_SSH_PRIVSEP_USER
;;
*)
SSH_PRIVSEP_USER=sshd
;;
esac
AC_ARG_WITH([privsep-user],
[ --with-privsep-user=user Specify non-privileged user for privilege separation],
[
if test -n "$withval" && test "x$withval" != "xno" && \
test "x${withval}" != "xyes"; then
SSH_PRIVSEP_USER=$withval
fi
]
)
if test "x$SSH_PRIVSEP_USER" = "xCYGWIN_SSH_PRIVSEP_USER" ; then
AC_DEFINE_UNQUOTED([SSH_PRIVSEP_USER], [CYGWIN_SSH_PRIVSEP_USER],
[Cygwin function to fetch non-privileged user for privilege separation])
else
AC_DEFINE_UNQUOTED([SSH_PRIVSEP_USER], ["$SSH_PRIVSEP_USER"],
[non-privileged user for privilege separation])
fi
AC_SUBST([SSH_PRIVSEP_USER])
if test "x$have_linux_no_new_privs" = "x1" ; then
AC_CHECK_DECL([SECCOMP_MODE_FILTER], [have_seccomp_filter=1], , [
#include <sys/types.h>
#include <linux/seccomp.h>
])
fi
if test "x$have_seccomp_filter" = "x1" ; then
AC_MSG_CHECKING([kernel for seccomp_filter support])
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
#include <errno.h>
#include <elf.h>
#include <linux/audit.h>
#include <linux/seccomp.h>
#include <stdlib.h>
#include <sys/prctl.h>
]],
[[ int i = $seccomp_audit_arch;
errno = 0;
prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, NULL, 0, 0);
exit(errno == EFAULT ? 0 : 1); ]])],
[ AC_MSG_RESULT([yes]) ], [
AC_MSG_RESULT([no])
# Disable seccomp filter as a target
have_seccomp_filter=0
]
)
fi
AC_CHECK_MEMBERS([struct pollfd.fd], [], [], [[
#include <sys/types.h>
#ifdef HAVE_POLL_H
#include <poll.h>
#endif
#ifdef HAVE_SYS_POLL_H
#include <sys/poll.h>
#endif
]])
AC_CHECK_TYPES([nfds_t], , , [
#include <sys/types.h>
#ifdef HAVE_POLL_H
#include <poll.h>
#endif
#ifdef HAVE_SYS_POLL_H
#include <sys/poll.h>
#endif
])
# Decide which sandbox style to use
sandbox_arg=""
AC_ARG_WITH([sandbox],
[ --with-sandbox=style Specify privilege separation sandbox (no, capsicum, darwin, rlimit, seccomp_filter, systrace, pledge)],
[
if test "x$withval" = "xyes" ; then
sandbox_arg=""
else
sandbox_arg="$withval"
fi
]
)
if test "x$sandbox_arg" != "xno"; then
# POSIX specifies that poll() "shall fail with EINVAL if the nfds argument
# is greater than OPEN_MAX". On some platforms that includes implementions
# of select in userspace on top of poll() so check both work with rlimit
# NOFILES so check that both work before enabling the rlimit sandbox.
AC_MSG_CHECKING([if select and/or poll works with descriptor rlimit])
AC_RUN_IFELSE(
[AC_LANG_PROGRAM([[
#include <sys/types.h>
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
#endif
#include <sys/resource.h>
#ifdef HAVE_SYS_SELECT_H
# include <sys/select.h>
#endif
#ifdef HAVE_POLL_H
# include <poll.h>
#elif HAVE_SYS_POLL_H
# include <sys/poll.h>
#endif
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
]],[[
struct rlimit rl_zero;
int fd, r;
fd_set fds;
struct timeval tv;
#ifdef HAVE_POLL
struct pollfd pfd;
#endif
fd = open("/dev/null", O_RDONLY);
FD_ZERO(&fds);
FD_SET(fd, &fds);
rl_zero.rlim_cur = rl_zero.rlim_max = 0;
setrlimit(RLIMIT_FSIZE, &rl_zero);
setrlimit(RLIMIT_NOFILE, &rl_zero);
tv.tv_sec = 1;
tv.tv_usec = 0;
r = select(fd+1, &fds, NULL, NULL, &tv);
if (r == -1)
exit(1);
#ifdef HAVE_POLL
pfd.fd = fd;
pfd.events = POLLIN;
r = poll(&pfd, 1, 1);
if (r == -1)
exit(2);
#endif
exit(0);
]])],
[AC_MSG_RESULT([yes])
select_works_with_rlimit=yes],
[AC_MSG_RESULT([no])
select_works_with_rlimit=no],
[AC_MSG_WARN([cross compiling: assuming no])
select_works_with_rlimit=no]
)
AC_MSG_CHECKING([if setrlimit(RLIMIT_NOFILE,{0,0}) works])
AC_RUN_IFELSE(
[AC_LANG_PROGRAM([[
#include <sys/types.h>
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
#endif
#include <sys/resource.h>
#include <errno.h>
#include <stdlib.h>
]],[[
struct rlimit rl_zero;
int r;
rl_zero.rlim_cur = rl_zero.rlim_max = 0;
r = setrlimit(RLIMIT_NOFILE, &rl_zero);
exit (r == -1 ? 1 : 0);
]])],
[AC_MSG_RESULT([yes])
rlimit_nofile_zero_works=yes],
[AC_MSG_RESULT([no])
rlimit_nofile_zero_works=no],
[AC_MSG_WARN([cross compiling: assuming yes])
rlimit_nofile_zero_works=yes]
)
AC_MSG_CHECKING([if setrlimit RLIMIT_FSIZE works])
AC_RUN_IFELSE(
[AC_LANG_PROGRAM([[
#include <sys/types.h>
#include <sys/resource.h>
#include <stdlib.h>
]],[[
struct rlimit rl_zero;
rl_zero.rlim_cur = rl_zero.rlim_max = 0;
exit(setrlimit(RLIMIT_FSIZE, &rl_zero) != 0);
]])],
[AC_MSG_RESULT([yes])],
[AC_MSG_RESULT([no])
AC_DEFINE(SANDBOX_SKIP_RLIMIT_FSIZE, 1,
[setrlimit RLIMIT_FSIZE works])],
[AC_MSG_WARN([cross compiling: assuming yes])]
)
fi
if test "x$sandbox_arg" = "xpledge" || \
( test -z "$sandbox_arg" && test "x$ac_cv_func_pledge" = "xyes" ) ; then
test "x$ac_cv_func_pledge" != "xyes" && \
AC_MSG_ERROR([pledge sandbox requires pledge(2) support])
SANDBOX_STYLE="pledge"
AC_DEFINE([SANDBOX_PLEDGE], [1], [Sandbox using pledge(2)])
elif test "x$sandbox_arg" = "xsystrace" || \
( test -z "$sandbox_arg" && test "x$have_systr_policy_kill" = "x1" ) ; then
test "x$have_systr_policy_kill" != "x1" && \
AC_MSG_ERROR([systrace sandbox requires systrace headers and SYSTR_POLICY_KILL support])
SANDBOX_STYLE="systrace"
AC_DEFINE([SANDBOX_SYSTRACE], [1], [Sandbox using systrace(4)])
elif test "x$sandbox_arg" = "xdarwin" || \
( test -z "$sandbox_arg" && test "x$ac_cv_func_sandbox_init" = "xyes" && \
test "x$ac_cv_header_sandbox_h" = "xyes") ; then
test "x$ac_cv_func_sandbox_init" != "xyes" -o \
"x$ac_cv_header_sandbox_h" != "xyes" && \
AC_MSG_ERROR([Darwin seatbelt sandbox requires sandbox.h and sandbox_init function])
SANDBOX_STYLE="darwin"
AC_DEFINE([SANDBOX_DARWIN], [1], [Sandbox using Darwin sandbox_init(3)])
elif test "x$sandbox_arg" = "xseccomp_filter" || \
( test -z "$sandbox_arg" && \
test "x$have_seccomp_filter" = "x1" && \
test "x$ac_cv_header_elf_h" = "xyes" && \
test "x$ac_cv_header_linux_audit_h" = "xyes" && \
test "x$ac_cv_header_linux_filter_h" = "xyes" && \
test "x$seccomp_audit_arch" != "x" && \
test "x$have_linux_no_new_privs" = "x1" && \
test "x$ac_cv_func_prctl" = "xyes" ) ; then
test "x$seccomp_audit_arch" = "x" && \
AC_MSG_ERROR([seccomp_filter sandbox not supported on $host])
test "x$have_linux_no_new_privs" != "x1" && \
AC_MSG_ERROR([seccomp_filter sandbox requires PR_SET_NO_NEW_PRIVS])
test "x$have_seccomp_filter" != "x1" && \
AC_MSG_ERROR([seccomp_filter sandbox requires seccomp headers])
test "x$ac_cv_func_prctl" != "xyes" && \
AC_MSG_ERROR([seccomp_filter sandbox requires prctl function])
SANDBOX_STYLE="seccomp_filter"
AC_DEFINE([SANDBOX_SECCOMP_FILTER], [1], [Sandbox using seccomp filter])
elif test "x$sandbox_arg" = "xcapsicum" || \
( test -z "$sandbox_arg" && \
test "x$disable_capsicum" != "xyes" && \
test "x$ac_cv_header_sys_capsicum_h" = "xyes" && \
test "x$ac_cv_func_cap_rights_limit" = "xyes") ; then
test "x$ac_cv_header_sys_capsicum_h" != "xyes" && \
AC_MSG_ERROR([capsicum sandbox requires sys/capsicum.h header])
test "x$ac_cv_func_cap_rights_limit" != "xyes" && \
AC_MSG_ERROR([capsicum sandbox requires cap_rights_limit function])
SANDBOX_STYLE="capsicum"
AC_DEFINE([SANDBOX_CAPSICUM], [1], [Sandbox using capsicum])
elif test "x$sandbox_arg" = "xrlimit" || \
( test -z "$sandbox_arg" && test "x$ac_cv_func_setrlimit" = "xyes" && \
test "x$select_works_with_rlimit" = "xyes" && \
test "x$rlimit_nofile_zero_works" = "xyes" ) ; then
test "x$ac_cv_func_setrlimit" != "xyes" && \
AC_MSG_ERROR([rlimit sandbox requires setrlimit function])
test "x$select_works_with_rlimit" != "xyes" && \
AC_MSG_ERROR([rlimit sandbox requires select to work with rlimit])
SANDBOX_STYLE="rlimit"
AC_DEFINE([SANDBOX_RLIMIT], [1], [Sandbox using setrlimit(2)])
elif test "x$sandbox_arg" = "xsolaris" || \
( test -z "$sandbox_arg" && test "x$SOLARIS_PRIVS" = "xyes" ) ; then
SANDBOX_STYLE="solaris"
AC_DEFINE([SANDBOX_SOLARIS], [1], [Sandbox using Solaris/Illumos privileges])
elif test -z "$sandbox_arg" || test "x$sandbox_arg" = "xno" || \
test "x$sandbox_arg" = "xnone" || test "x$sandbox_arg" = "xnull" ; then
SANDBOX_STYLE="none"
AC_DEFINE([SANDBOX_NULL], [1], [no privsep sandboxing])
else
AC_MSG_ERROR([unsupported --with-sandbox])
fi
# Cheap hack to ensure NEWS-OS libraries are arranged right.
if test ! -z "$SONY" ; then
LIBS="$LIBS -liberty";
fi
# Check for long long datatypes
AC_CHECK_TYPES([long long, unsigned long long, long double])
# Check datatype sizes
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
ac_cv_sizeof_long_long_int=0
fi
# compute LLONG_MIN and LLONG_MAX if we don't know them.
if test -z "$have_llong_max" && test -z "$have_long_long_max"; then
AC_MSG_CHECKING([for max value of long long])
AC_RUN_IFELSE(
[AC_LANG_PROGRAM([[
#include <stdio.h>
#include <stdlib.h>
/* Why is this so damn hard? */
#ifdef __GNUC__
# undef __GNUC__
#endif
#define __USE_ISOC99
#include <limits.h>
#define DATA "conftest.llminmax"
#define my_abs(a) ((a) < 0 ? ((a) * -1) : (a))
/*
* printf in libc on some platforms (eg old Tru64) does not understand %lld so
* we do this the hard way.
*/
static int
fprint_ll(FILE *f, long long n)
{
unsigned int i;
int l[sizeof(long long) * 8];
if (n < 0)
if (fprintf(f, "-") < 0)
return -1;
for (i = 0; n != 0; i++) {
l[i] = my_abs(n % 10);
n /= 10;
}
do {
if (fprintf(f, "%d", l[--i]) < 0)
return -1;
} while (i != 0);
if (fprintf(f, " ") < 0)
return -1;
return 0;
}
]], [[
FILE *f;
long long i, llmin, llmax = 0;
if((f = fopen(DATA,"w")) == NULL)
exit(1);
#if defined(LLONG_MIN) && defined(LLONG_MAX)
fprintf(stderr, "Using system header for LLONG_MIN and LLONG_MAX\n");
llmin = LLONG_MIN;
llmax = LLONG_MAX;
#else
fprintf(stderr, "Calculating LLONG_MIN and LLONG_MAX\n");
/* This will work on one's complement and two's complement */
for (i = 1; i > llmax; i <<= 1, i++)
llmax = i;
llmin = llmax + 1LL; /* wrap */
#endif
/* Sanity check */
if (llmin + 1 < llmin || llmin - 1 < llmin || llmax + 1 > llmax
|| llmax - 1 > llmax || llmin == llmax || llmin == 0
|| llmax == 0 || llmax < LONG_MAX || llmin > LONG_MIN) {
fprintf(f, "unknown unknown\n");
exit(2);
}
if (fprint_ll(f, llmin) < 0)
exit(3);
if (fprint_ll(f, llmax) < 0)
exit(4);
if (fclose(f) < 0)
exit(5);
exit(0);
]])],
[
llong_min=`$AWK '{print $1}' conftest.llminmax`
llong_max=`$AWK '{print $2}' conftest.llminmax`
AC_MSG_RESULT([$llong_max])
AC_DEFINE_UNQUOTED([LLONG_MAX], [${llong_max}LL],
[max value of long long calculated by configure])
AC_MSG_CHECKING([for min value of long long])
AC_MSG_RESULT([$llong_min])
AC_DEFINE_UNQUOTED([LLONG_MIN], [${llong_min}LL],
[min value of long long calculated by configure])
],
[
AC_MSG_RESULT([not found])
],
[
AC_MSG_WARN([cross compiling: not checking])
]
)
fi
AC_CHECK_DECLS([UINT32_MAX], , , [[
#ifdef HAVE_SYS_LIMITS_H
# include <sys/limits.h>
#endif
#ifdef HAVE_LIMITS_H
# include <limits.h>
#endif
#ifdef HAVE_STDINT_H
# include <stdint.h>
#endif
]])
# More checks for data types
AC_CACHE_CHECK([for u_int type], ac_cv_have_u_int, [
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <sys/types.h> ]],
[[ u_int a; a = 1;]])],
[ ac_cv_have_u_int="yes" ], [ ac_cv_have_u_int="no"
])
])
if test "x$ac_cv_have_u_int" = "xyes" ; then
AC_DEFINE([HAVE_U_INT], [1], [define if you have u_int data type])
have_u_int=1
fi
AC_CACHE_CHECK([for intXX_t types], ac_cv_have_intxx_t, [
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <sys/types.h> ]],
[[ int8_t a; int16_t b; int32_t c; a = b = c = 1;]])],
[ ac_cv_have_intxx_t="yes" ], [ ac_cv_have_intxx_t="no"
])
])
if test "x$ac_cv_have_intxx_t" = "xyes" ; then
AC_DEFINE([HAVE_INTXX_T], [1], [define if you have intxx_t data type])
have_intxx_t=1
fi
if (test -z "$have_intxx_t" && \
test "x$ac_cv_header_stdint_h" = "xyes")
then
AC_MSG_CHECKING([for intXX_t types in stdint.h])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <stdint.h> ]],
[[ int8_t a; int16_t b; int32_t c; a = b = c = 1;]])],
[
AC_DEFINE([HAVE_INTXX_T])
AC_MSG_RESULT([yes])
], [ AC_MSG_RESULT([no])
])
fi
AC_CACHE_CHECK([for int64_t type], ac_cv_have_int64_t, [
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <sys/types.h>
#ifdef HAVE_STDINT_H
# include <stdint.h>
#endif
#include <sys/socket.h>
#ifdef HAVE_SYS_BITYPES_H
# include <sys/bitypes.h>
#endif
]], [[
int64_t a; a = 1;
]])],
[ ac_cv_have_int64_t="yes" ], [ ac_cv_have_int64_t="no"
])
])
if test "x$ac_cv_have_int64_t" = "xyes" ; then
AC_DEFINE([HAVE_INT64_T], [1], [define if you have int64_t data type])
fi
AC_CACHE_CHECK([for u_intXX_t types], ac_cv_have_u_intxx_t, [
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <sys/types.h> ]],
[[ u_int8_t a; u_int16_t b; u_int32_t c; a = b = c = 1;]])],
[ ac_cv_have_u_intxx_t="yes" ], [ ac_cv_have_u_intxx_t="no"
])
])
if test "x$ac_cv_have_u_intxx_t" = "xyes" ; then
AC_DEFINE([HAVE_U_INTXX_T], [1], [define if you have u_intxx_t data type])
have_u_intxx_t=1
fi
if test -z "$have_u_intxx_t" ; then
AC_MSG_CHECKING([for u_intXX_t types in sys/socket.h])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <sys/socket.h> ]],
[[ u_int8_t a; u_int16_t b; u_int32_t c; a = b = c = 1;]])],
[
AC_DEFINE([HAVE_U_INTXX_T])
AC_MSG_RESULT([yes])
], [ AC_MSG_RESULT([no])
])
fi
AC_CACHE_CHECK([for u_int64_t types], ac_cv_have_u_int64_t, [
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <sys/types.h> ]],
[[ u_int64_t a; a = 1;]])],
[ ac_cv_have_u_int64_t="yes" ], [ ac_cv_have_u_int64_t="no"
])
])
if test "x$ac_cv_have_u_int64_t" = "xyes" ; then
AC_DEFINE([HAVE_U_INT64_T], [1], [define if you have u_int64_t data type])
have_u_int64_t=1
fi
if (test -z "$have_u_int64_t" && \
test "x$ac_cv_header_sys_bitypes_h" = "xyes")
then
AC_MSG_CHECKING([for u_int64_t type in sys/bitypes.h])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <sys/bitypes.h> ]],
[[ u_int64_t a; a = 1]])],
[
AC_DEFINE([HAVE_U_INT64_T])
AC_MSG_RESULT([yes])
], [ AC_MSG_RESULT([no])
])
fi
if test -z "$have_u_intxx_t" ; then
AC_CACHE_CHECK([for uintXX_t types], ac_cv_have_uintxx_t, [
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <sys/types.h>
]], [[
uint8_t a;
uint16_t b;
uint32_t c;
a = b = c = 1;
]])],
[ ac_cv_have_uintxx_t="yes" ], [ ac_cv_have_uintxx_t="no"
])
])
if test "x$ac_cv_have_uintxx_t" = "xyes" ; then
AC_DEFINE([HAVE_UINTXX_T], [1],
[define if you have uintxx_t data type])
fi
fi
if (test -z "$have_uintxx_t" && \
test "x$ac_cv_header_stdint_h" = "xyes")
then
AC_MSG_CHECKING([for uintXX_t types in stdint.h])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <stdint.h> ]],
[[ uint8_t a; uint16_t b; uint32_t c; a = b = c = 1;]])],
[
AC_DEFINE([HAVE_UINTXX_T])
AC_MSG_RESULT([yes])
], [ AC_MSG_RESULT([no])
])
fi
if (test -z "$have_uintxx_t" && \
test "x$ac_cv_header_inttypes_h" = "xyes")
then
AC_MSG_CHECKING([for uintXX_t types in inttypes.h])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <inttypes.h> ]],
[[ uint8_t a; uint16_t b; uint32_t c; a = b = c = 1;]])],
[
AC_DEFINE([HAVE_UINTXX_T])
AC_MSG_RESULT([yes])
], [ AC_MSG_RESULT([no])
])
fi
if (test -z "$have_u_intxx_t" || test -z "$have_intxx_t" && \
test "x$ac_cv_header_sys_bitypes_h" = "xyes")
then
AC_MSG_CHECKING([for intXX_t and u_intXX_t types in sys/bitypes.h])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <sys/bitypes.h>
]], [[
int8_t a; int16_t b; int32_t c;
u_int8_t e; u_int16_t f; u_int32_t g;
a = b = c = e = f = g = 1;
]])],
[
AC_DEFINE([HAVE_U_INTXX_T])
AC_DEFINE([HAVE_INTXX_T])
AC_MSG_RESULT([yes])
], [AC_MSG_RESULT([no])
])
fi
AC_CACHE_CHECK([for u_char], ac_cv_have_u_char, [
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <sys/types.h> ]],
[[ u_char foo; foo = 125; ]])],
[ ac_cv_have_u_char="yes" ], [ ac_cv_have_u_char="no"
])
])
if test "x$ac_cv_have_u_char" = "xyes" ; then
AC_DEFINE([HAVE_U_CHAR], [1], [define if you have u_char data type])
fi
AC_CHECK_TYPES([intmax_t, uintmax_t], , , [
#include <sys/types.h>
#ifdef HAVE_STDINT_H
# include <stdint.h>
#endif
])
TYPE_SOCKLEN_T
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
#include <sys/bitypes.h>
#endif
#ifdef HAVE_SYS_STATFS_H
#include <sys/statfs.h>
#endif
#ifdef HAVE_SYS_STATVFS_H
#include <sys/statvfs.h>
#endif
])
AC_CHECK_MEMBERS([struct statfs.f_files, struct statfs.f_flags], [], [], [[
#include <sys/param.h>
#include <sys/types.h>
#ifdef HAVE_SYS_BITYPES_H
#include <sys/bitypes.h>
#endif
#ifdef HAVE_SYS_STATFS_H
#include <sys/statfs.h>
#endif
#ifdef HAVE_SYS_STATVFS_H
#include <sys/statvfs.h>
#endif
#ifdef HAVE_SYS_VFS_H
#include <sys/vfs.h>
#endif
#ifdef HAVE_SYS_MOUNT_H
#include <sys/mount.h>
#endif
]])
AC_CHECK_TYPES([in_addr_t, in_port_t], , ,
[#include <sys/types.h>
#include <netinet/in.h>])
AC_CACHE_CHECK([for size_t], ac_cv_have_size_t, [
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <sys/types.h> ]],
[[ size_t foo; foo = 1235; ]])],
[ ac_cv_have_size_t="yes" ], [ ac_cv_have_size_t="no"
])
])
if test "x$ac_cv_have_size_t" = "xyes" ; then
AC_DEFINE([HAVE_SIZE_T], [1], [define if you have size_t data type])
fi
AC_CACHE_CHECK([for ssize_t], ac_cv_have_ssize_t, [
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <sys/types.h> ]],
[[ ssize_t foo; foo = 1235; ]])],
[ ac_cv_have_ssize_t="yes" ], [ ac_cv_have_ssize_t="no"
])
])
if test "x$ac_cv_have_ssize_t" = "xyes" ; then
AC_DEFINE([HAVE_SSIZE_T], [1], [define if you have ssize_t data type])
fi
AC_CACHE_CHECK([for clock_t], ac_cv_have_clock_t, [
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <time.h> ]],
[[ clock_t foo; foo = 1235; ]])],
[ ac_cv_have_clock_t="yes" ], [ ac_cv_have_clock_t="no"
])
])
if test "x$ac_cv_have_clock_t" = "xyes" ; then
AC_DEFINE([HAVE_CLOCK_T], [1], [define if you have clock_t data type])
fi
AC_CACHE_CHECK([for sa_family_t], ac_cv_have_sa_family_t, [
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <sys/types.h>
#include <sys/socket.h>
]], [[ sa_family_t foo; foo = 1235; ]])],
[ ac_cv_have_sa_family_t="yes" ],
[ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
]], [[ sa_family_t foo; foo = 1235; ]])],
[ ac_cv_have_sa_family_t="yes" ],
[ ac_cv_have_sa_family_t="no" ]
)
])
])
if test "x$ac_cv_have_sa_family_t" = "xyes" ; then
AC_DEFINE([HAVE_SA_FAMILY_T], [1],
[define if you have sa_family_t data type])
fi
AC_CACHE_CHECK([for pid_t], ac_cv_have_pid_t, [
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <sys/types.h> ]],
[[ pid_t foo; foo = 1235; ]])],
[ ac_cv_have_pid_t="yes" ], [ ac_cv_have_pid_t="no"
])
])
if test "x$ac_cv_have_pid_t" = "xyes" ; then
AC_DEFINE([HAVE_PID_T], [1], [define if you have pid_t data type])
fi
AC_CACHE_CHECK([for mode_t], ac_cv_have_mode_t, [
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <sys/types.h> ]],
[[ mode_t foo; foo = 1235; ]])],
[ ac_cv_have_mode_t="yes" ], [ ac_cv_have_mode_t="no"
])
])
if test "x$ac_cv_have_mode_t" = "xyes" ; then
AC_DEFINE([HAVE_MODE_T], [1], [define if you have mode_t data type])
fi
AC_CACHE_CHECK([for struct sockaddr_storage], ac_cv_have_struct_sockaddr_storage, [
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <sys/types.h>
#include <sys/socket.h>
]], [[ struct sockaddr_storage s; ]])],
[ ac_cv_have_struct_sockaddr_storage="yes" ],
[ ac_cv_have_struct_sockaddr_storage="no"
])
])
if test "x$ac_cv_have_struct_sockaddr_storage" = "xyes" ; then
AC_DEFINE([HAVE_STRUCT_SOCKADDR_STORAGE], [1],
[define if you have struct sockaddr_storage data type])
fi
AC_CACHE_CHECK([for struct sockaddr_in6], ac_cv_have_struct_sockaddr_in6, [
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <sys/types.h>
#include <netinet/in.h>
]], [[ struct sockaddr_in6 s; s.sin6_family = 0; ]])],
[ ac_cv_have_struct_sockaddr_in6="yes" ],
[ ac_cv_have_struct_sockaddr_in6="no"
])
])
if test "x$ac_cv_have_struct_sockaddr_in6" = "xyes" ; then
AC_DEFINE([HAVE_STRUCT_SOCKADDR_IN6], [1],
[define if you have struct sockaddr_in6 data type])
fi
AC_CACHE_CHECK([for struct in6_addr], ac_cv_have_struct_in6_addr, [
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <sys/types.h>
#include <netinet/in.h>
]], [[ struct in6_addr s; s.s6_addr[0] = 0; ]])],
[ ac_cv_have_struct_in6_addr="yes" ],
[ ac_cv_have_struct_in6_addr="no"
])
])
if test "x$ac_cv_have_struct_in6_addr" = "xyes" ; then
AC_DEFINE([HAVE_STRUCT_IN6_ADDR], [1],
[define if you have struct in6_addr data type])
dnl Now check for sin6_scope_id
AC_CHECK_MEMBERS([struct sockaddr_in6.sin6_scope_id], , ,
[
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#include <netinet/in.h>
])
fi
AC_CACHE_CHECK([for struct addrinfo], ac_cv_have_struct_addrinfo, [
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
]], [[ struct addrinfo s; s.ai_flags = AI_PASSIVE; ]])],
[ ac_cv_have_struct_addrinfo="yes" ],
[ ac_cv_have_struct_addrinfo="no"
])
])
if test "x$ac_cv_have_struct_addrinfo" = "xyes" ; then
AC_DEFINE([HAVE_STRUCT_ADDRINFO], [1],
[define if you have struct addrinfo data type])
fi
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;]])],
[ ac_cv_have_struct_timeval="yes" ],
[ ac_cv_have_struct_timeval="no"
])
])
if test "x$ac_cv_have_struct_timeval" = "xyes" ; then
AC_DEFINE([HAVE_STRUCT_TIMEVAL], [1], [define if you have struct timeval])
have_struct_timeval=1
fi
AC_CACHE_CHECK([for struct timespec], ac_cv_have_struct_timespec, [
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
#endif
#ifdef HAVE_TIME_H
# include <time.h>
#endif
]],
[[ struct timespec ts; ts.tv_sec = 1;]])],
[ ac_cv_have_struct_timespec="yes" ],
[ ac_cv_have_struct_timespec="no"
])
])
if test "x$ac_cv_have_struct_timespec" = "xyes" ; then
AC_DEFINE([HAVE_STRUCT_TIMESPEC], [1], [define if you have struct timespec])
have_struct_timespec=1
fi
# We need int64_t or else certain parts of the compile will fail.
if test "x$ac_cv_have_int64_t" = "xno" && \
test "x$ac_cv_sizeof_long_int" != "x8" && \
test "x$ac_cv_sizeof_long_long_int" = "x0" ; then
echo "OpenSSH requires int64_t support. Contact your vendor or install"
echo "an alternative compiler (I.E., GCC) before continuing."
echo ""
exit 1;
else
dnl test snprintf (broken on SCO w/gcc)
AC_RUN_IFELSE(
[AC_LANG_SOURCE([[
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_SNPRINTF
-main()
+int main(void)
{
char buf[50];
char expected_out[50];
int mazsize = 50 ;
#if (SIZEOF_LONG_INT == 8)
long int num = 0x7fffffffffffffff;
#else
long long num = 0x7fffffffffffffffll;
#endif
strcpy(expected_out, "9223372036854775807");
snprintf(buf, mazsize, "%lld", num);
if(strcmp(buf, expected_out) != 0)
exit(1);
exit(0);
}
#else
-main() { exit(0); }
+int main(void) { exit(0); }
#endif
]])], [ true ], [ AC_DEFINE([BROKEN_SNPRINTF]) ],
AC_MSG_WARN([cross compiling: Assuming working snprintf()])
)
fi
dnl Checks for structure members
OSSH_CHECK_HEADER_FOR_FIELD([ut_host], [utmp.h], [HAVE_HOST_IN_UTMP])
OSSH_CHECK_HEADER_FOR_FIELD([ut_host], [utmpx.h], [HAVE_HOST_IN_UTMPX])
OSSH_CHECK_HEADER_FOR_FIELD([syslen], [utmpx.h], [HAVE_SYSLEN_IN_UTMPX])
OSSH_CHECK_HEADER_FOR_FIELD([ut_pid], [utmp.h], [HAVE_PID_IN_UTMP])
OSSH_CHECK_HEADER_FOR_FIELD([ut_type], [utmp.h], [HAVE_TYPE_IN_UTMP])
OSSH_CHECK_HEADER_FOR_FIELD([ut_type], [utmpx.h], [HAVE_TYPE_IN_UTMPX])
OSSH_CHECK_HEADER_FOR_FIELD([ut_tv], [utmp.h], [HAVE_TV_IN_UTMP])
OSSH_CHECK_HEADER_FOR_FIELD([ut_id], [utmp.h], [HAVE_ID_IN_UTMP])
OSSH_CHECK_HEADER_FOR_FIELD([ut_id], [utmpx.h], [HAVE_ID_IN_UTMPX])
OSSH_CHECK_HEADER_FOR_FIELD([ut_addr], [utmp.h], [HAVE_ADDR_IN_UTMP])
OSSH_CHECK_HEADER_FOR_FIELD([ut_addr], [utmpx.h], [HAVE_ADDR_IN_UTMPX])
OSSH_CHECK_HEADER_FOR_FIELD([ut_addr_v6], [utmp.h], [HAVE_ADDR_V6_IN_UTMP])
OSSH_CHECK_HEADER_FOR_FIELD([ut_addr_v6], [utmpx.h], [HAVE_ADDR_V6_IN_UTMPX])
OSSH_CHECK_HEADER_FOR_FIELD([ut_exit], [utmp.h], [HAVE_EXIT_IN_UTMP])
OSSH_CHECK_HEADER_FOR_FIELD([ut_time], [utmp.h], [HAVE_TIME_IN_UTMP])
OSSH_CHECK_HEADER_FOR_FIELD([ut_time], [utmpx.h], [HAVE_TIME_IN_UTMPX])
OSSH_CHECK_HEADER_FOR_FIELD([ut_tv], [utmpx.h], [HAVE_TV_IN_UTMPX])
OSSH_CHECK_HEADER_FOR_FIELD([ut_ss], [utmpx.h], [HAVE_SS_IN_UTMPX])
AC_CHECK_MEMBERS([struct stat.st_blksize])
AC_CHECK_MEMBERS([struct stat.st_mtim])
AC_CHECK_MEMBERS([struct stat.st_mtime])
AC_CHECK_MEMBERS([struct passwd.pw_gecos, struct passwd.pw_class,
struct passwd.pw_change, struct passwd.pw_expire],
[], [], [[
#include <sys/types.h>
#include <pwd.h>
]])
AC_CHECK_MEMBER([struct __res_state.retrans], [], [AC_DEFINE([__res_state], [state],
[Define if we don't have struct __res_state in resolv.h])],
[[
#include <stdio.h>
#if HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#include <netinet/in.h>
#include <arpa/nameser.h>
#include <resolv.h>
]])
+AC_CHECK_MEMBER([struct sockaddr_in.sin_len],
+ [AC_DEFINE([SOCK_HAS_LEN], [1], [sockaddr_in has sin_len])],
+ [],
+ [AC_LANG_SOURCE([[
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+ ]])]
+)
+
AC_CACHE_CHECK([for ss_family field in struct sockaddr_storage],
ac_cv_have_ss_family_in_struct_ss, [
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <sys/types.h>
#include <sys/socket.h>
]], [[ struct sockaddr_storage s; s.ss_family = 1; ]])],
[ ac_cv_have_ss_family_in_struct_ss="yes" ],
[ ac_cv_have_ss_family_in_struct_ss="no" ])
])
if test "x$ac_cv_have_ss_family_in_struct_ss" = "xyes" ; then
AC_DEFINE([HAVE_SS_FAMILY_IN_SS], [1], [Fields in struct sockaddr_storage])
fi
AC_CACHE_CHECK([for __ss_family field in struct sockaddr_storage],
ac_cv_have___ss_family_in_struct_ss, [
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <sys/types.h>
#include <sys/socket.h>
]], [[ struct sockaddr_storage s; s.__ss_family = 1; ]])],
[ ac_cv_have___ss_family_in_struct_ss="yes" ],
[ ac_cv_have___ss_family_in_struct_ss="no"
])
])
if test "x$ac_cv_have___ss_family_in_struct_ss" = "xyes" ; then
AC_DEFINE([HAVE___SS_FAMILY_IN_SS], [1],
[Fields in struct sockaddr_storage])
fi
dnl make sure we're using the real structure members and not defines
AC_CACHE_CHECK([for msg_accrights field in struct msghdr],
ac_cv_have_accrights_in_msghdr, [
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/uio.h>
#include <stdlib.h>
]], [[
#ifdef msg_accrights
#error "msg_accrights is a macro"
exit(1);
#endif
struct msghdr m;
m.msg_accrights = 0;
exit(0);
]])],
[ ac_cv_have_accrights_in_msghdr="yes" ],
[ ac_cv_have_accrights_in_msghdr="no" ]
)
])
if test "x$ac_cv_have_accrights_in_msghdr" = "xyes" ; then
AC_DEFINE([HAVE_ACCRIGHTS_IN_MSGHDR], [1],
[Define if your system uses access rights style
file descriptor passing])
fi
AC_MSG_CHECKING([if struct statvfs.f_fsid is integral type])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <sys/param.h>
#include <sys/stat.h>
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
#endif
#ifdef HAVE_SYS_MOUNT_H
#include <sys/mount.h>
#endif
#ifdef HAVE_SYS_STATVFS_H
#include <sys/statvfs.h>
#endif
]], [[ struct statvfs s; s.f_fsid = 0; ]])],
[ AC_MSG_RESULT([yes]) ],
[ AC_MSG_RESULT([no])
AC_MSG_CHECKING([if fsid_t has member val])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <sys/types.h>
#include <sys/statvfs.h>
]], [[ fsid_t t; t.val[0] = 0; ]])],
[ AC_MSG_RESULT([yes])
AC_DEFINE([FSID_HAS_VAL], [1], [fsid_t has member val]) ],
[ AC_MSG_RESULT([no]) ])
AC_MSG_CHECKING([if f_fsid has member __val])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <sys/types.h>
#include <sys/statvfs.h>
]], [[ fsid_t t; t.__val[0] = 0; ]])],
[ AC_MSG_RESULT([yes])
AC_DEFINE([FSID_HAS___VAL], [1], [fsid_t has member __val]) ],
[ AC_MSG_RESULT([no]) ])
])
AC_CACHE_CHECK([for msg_control field in struct msghdr],
ac_cv_have_control_in_msghdr, [
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/uio.h>
#include <stdlib.h>
]], [[
#ifdef msg_control
#error "msg_control is a macro"
exit(1);
#endif
struct msghdr m;
m.msg_control = 0;
exit(0);
]])],
[ ac_cv_have_control_in_msghdr="yes" ],
[ ac_cv_have_control_in_msghdr="no" ]
)
])
if test "x$ac_cv_have_control_in_msghdr" = "xyes" ; then
AC_DEFINE([HAVE_CONTROL_IN_MSGHDR], [1],
[Define if your system uses ancillary data style
file descriptor passing])
fi
AC_CACHE_CHECK([if libc defines __progname], ac_cv_libc_defines___progname, [
AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include <stdio.h> ]],
[[ extern char *__progname; printf("%s", __progname); ]])],
[ ac_cv_libc_defines___progname="yes" ],
[ ac_cv_libc_defines___progname="no"
])
])
if test "x$ac_cv_libc_defines___progname" = "xyes" ; then
AC_DEFINE([HAVE___PROGNAME], [1], [Define if libc defines __progname])
fi
AC_CACHE_CHECK([whether $CC implements __FUNCTION__], ac_cv_cc_implements___FUNCTION__, [
AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include <stdio.h> ]],
[[ printf("%s", __FUNCTION__); ]])],
[ ac_cv_cc_implements___FUNCTION__="yes" ],
[ ac_cv_cc_implements___FUNCTION__="no"
])
])
if test "x$ac_cv_cc_implements___FUNCTION__" = "xyes" ; then
AC_DEFINE([HAVE___FUNCTION__], [1],
[Define if compiler implements __FUNCTION__])
fi
AC_CACHE_CHECK([whether $CC implements __func__], ac_cv_cc_implements___func__, [
AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include <stdio.h> ]],
[[ printf("%s", __func__); ]])],
[ ac_cv_cc_implements___func__="yes" ],
[ ac_cv_cc_implements___func__="no"
])
])
if test "x$ac_cv_cc_implements___func__" = "xyes" ; then
AC_DEFINE([HAVE___func__], [1], [Define if compiler implements __func__])
fi
AC_CACHE_CHECK([whether va_copy exists], ac_cv_have_va_copy, [
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
#include <stdarg.h>
va_list x,y;
]], [[ va_copy(x,y); ]])],
[ ac_cv_have_va_copy="yes" ],
[ ac_cv_have_va_copy="no"
])
])
if test "x$ac_cv_have_va_copy" = "xyes" ; then
AC_DEFINE([HAVE_VA_COPY], [1], [Define if va_copy exists])
fi
AC_CACHE_CHECK([whether __va_copy exists], ac_cv_have___va_copy, [
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
#include <stdarg.h>
va_list x,y;
]], [[ __va_copy(x,y); ]])],
[ ac_cv_have___va_copy="yes" ], [ ac_cv_have___va_copy="no"
])
])
if test "x$ac_cv_have___va_copy" = "xyes" ; then
AC_DEFINE([HAVE___VA_COPY], [1], [Define if __va_copy exists])
fi
AC_CACHE_CHECK([whether getopt has optreset support],
ac_cv_have_getopt_optreset, [
AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include <getopt.h> ]],
[[ extern int optreset; optreset = 0; ]])],
[ ac_cv_have_getopt_optreset="yes" ],
[ ac_cv_have_getopt_optreset="no"
])
])
if test "x$ac_cv_have_getopt_optreset" = "xyes" ; then
AC_DEFINE([HAVE_GETOPT_OPTRESET], [1],
[Define if your getopt(3) defines and uses optreset])
fi
AC_CACHE_CHECK([if libc defines sys_errlist], ac_cv_libc_defines_sys_errlist, [
AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include <stdio.h> ]],
[[ extern const char *const sys_errlist[]; printf("%s", sys_errlist[0]);]])],
[ ac_cv_libc_defines_sys_errlist="yes" ],
[ ac_cv_libc_defines_sys_errlist="no"
])
])
if test "x$ac_cv_libc_defines_sys_errlist" = "xyes" ; then
AC_DEFINE([HAVE_SYS_ERRLIST], [1],
[Define if your system defines sys_errlist[]])
fi
AC_CACHE_CHECK([if libc defines sys_nerr], ac_cv_libc_defines_sys_nerr, [
AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include <stdio.h> ]],
[[ extern int sys_nerr; printf("%i", sys_nerr);]])],
[ ac_cv_libc_defines_sys_nerr="yes" ],
[ ac_cv_libc_defines_sys_nerr="no"
])
])
if test "x$ac_cv_libc_defines_sys_nerr" = "xyes" ; then
AC_DEFINE([HAVE_SYS_NERR], [1], [Define if your system defines sys_nerr])
fi
# Check libraries needed by DNS fingerprint support
AC_SEARCH_LIBS([getrrsetbyname], [resolv],
[AC_DEFINE([HAVE_GETRRSETBYNAME], [1],
[Define if getrrsetbyname() exists])],
[
# Needed by our getrrsetbyname()
AC_SEARCH_LIBS([res_query], [resolv])
AC_SEARCH_LIBS([dn_expand], [resolv])
AC_MSG_CHECKING([if res_query will link])
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/nameser.h>
#include <netdb.h>
#include <resolv.h>
]], [[
res_query (0, 0, 0, 0, 0);
]])],
AC_MSG_RESULT([yes]),
[AC_MSG_RESULT([no])
saved_LIBS="$LIBS"
LIBS="$LIBS -lresolv"
AC_MSG_CHECKING([for res_query in -lresolv])
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/nameser.h>
#include <netdb.h>
#include <resolv.h>
]], [[
res_query (0, 0, 0, 0, 0);
]])],
[AC_MSG_RESULT([yes])],
[LIBS="$saved_LIBS"
AC_MSG_RESULT([no])])
])
AC_CHECK_FUNCS([_getshort _getlong])
AC_CHECK_DECLS([_getshort, _getlong], , ,
[#include <sys/types.h>
#include <arpa/nameser.h>])
AC_CHECK_MEMBER([HEADER.ad],
[AC_DEFINE([HAVE_HEADER_AD], [1],
[Define if HEADER.ad exists in arpa/nameser.h])], ,
[#include <arpa/nameser.h>])
])
AC_MSG_CHECKING([if struct __res_state _res is an extern])
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
#include <stdio.h>
#if HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#include <netinet/in.h>
#include <arpa/nameser.h>
#include <resolv.h>
extern struct __res_state _res;
]], [[
struct __res_state *volatile p = &_res; /* force resolution of _res */
return 0;
]],)],
[AC_MSG_RESULT([yes])
AC_DEFINE([HAVE__RES_EXTERN], [1],
[Define if you have struct __res_state _res as an extern])
],
[ AC_MSG_RESULT([no]) ]
)
# Check whether user wants SELinux support
SELINUX_MSG="no"
LIBSELINUX=""
AC_ARG_WITH([selinux],
[ --with-selinux Enable SELinux support],
[ if test "x$withval" != "xno" ; then
save_LIBS="$LIBS"
AC_DEFINE([WITH_SELINUX], [1],
[Define if you want SELinux support.])
SELINUX_MSG="yes"
AC_CHECK_HEADER([selinux/selinux.h], ,
AC_MSG_ERROR([SELinux support requires selinux.h header]))
AC_CHECK_LIB([selinux], [setexeccon],
[ LIBSELINUX="-lselinux"
LIBS="$LIBS -lselinux"
],
AC_MSG_ERROR([SELinux support requires libselinux library]))
AC_CHECK_FUNCS([getseuserbyname get_default_context_with_level])
LIBS="$save_LIBS $LIBSELINUX"
fi ]
)
AC_SUBST([SSHDLIBS])
# Check whether user wants Kerberos 5 support
KRB5_MSG="no"
AC_ARG_WITH([kerberos5],
[ --with-kerberos5=PATH Enable Kerberos 5 support],
[ if test "x$withval" != "xno" ; then
if test "x$withval" = "xyes" ; then
KRB5ROOT="/usr/local"
else
KRB5ROOT=${withval}
fi
AC_DEFINE([KRB5], [1], [Define if you want Kerberos 5 support])
KRB5_MSG="yes"
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 "$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="`$PKGCONFIG --cflags krb5-gssapi`"
GSSLIBS="`$PKGCONFIG --libs krb5-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], [1],
[Define this if you are using the Heimdal
version of Kerberos V5]) ],
[AC_MSG_RESULT([no])
])
else
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], [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_DEFINE([GSSAPI])
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])
)
]
)
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"
fi
if test ! -z "$blibpath" ; then
blibpath="$blibpath:${KRB5ROOT}/lib"
fi
AC_CHECK_HEADERS([gssapi.h gssapi/gssapi.h])
AC_CHECK_HEADERS([gssapi_krb5.h gssapi/gssapi_krb5.h])
AC_CHECK_HEADERS([gssapi_generic.h gssapi/gssapi_generic.h])
AC_SEARCH_LIBS([k_hasafs], [kafs], [AC_DEFINE([USE_AFS], [1],
[Define this if you want to use libkafs' AFS support])])
AC_CHECK_DECLS([GSS_C_NT_HOSTBASED_SERVICE], [], [], [[
#ifdef HAVE_GSSAPI_H
# include <gssapi.h>
#elif defined(HAVE_GSSAPI_GSSAPI_H)
# include <gssapi/gssapi.h>
#endif
#ifdef HAVE_GSSAPI_GENERIC_H
# include <gssapi_generic.h>
#elif defined(HAVE_GSSAPI_GSSAPI_GENERIC_H)
# include <gssapi/gssapi_generic.h>
#endif
]])
saved_LIBS="$LIBS"
LIBS="$LIBS $K5LIBS"
AC_CHECK_FUNCS([krb5_cc_new_unique krb5_get_error_message krb5_free_error_message])
LIBS="$saved_LIBS"
fi
]
)
AC_SUBST([GSSLIBS])
AC_SUBST([K5LIBS])
AC_SUBST([CHANNELLIBS])
# Looking for programs, paths and files
PRIVSEP_PATH=/var/empty
AC_ARG_WITH([privsep-path],
[ --with-privsep-path=xxx Path for privilege separation chroot (default=/var/empty)],
[
if test -n "$withval" && test "x$withval" != "xno" && \
test "x${withval}" != "xyes"; then
PRIVSEP_PATH=$withval
fi
]
)
AC_SUBST([PRIVSEP_PATH])
AC_ARG_WITH([xauth],
[ --with-xauth=PATH Specify path to xauth program ],
[
if test -n "$withval" && test "x$withval" != "xno" && \
test "x${withval}" != "xyes"; then
xauth_path=$withval
fi
],
[
TestPath="$PATH"
TestPath="${TestPath}${PATH_SEPARATOR}/usr/X/bin"
TestPath="${TestPath}${PATH_SEPARATOR}/usr/bin/X11"
TestPath="${TestPath}${PATH_SEPARATOR}/usr/X11R6/bin"
TestPath="${TestPath}${PATH_SEPARATOR}/usr/openwin/bin"
AC_PATH_PROG([xauth_path], [xauth], , [$TestPath])
if (test ! -z "$xauth_path" && test -x "/usr/openwin/bin/xauth") ; then
xauth_path="/usr/openwin/bin/xauth"
fi
]
)
STRIP_OPT=-s
AC_ARG_ENABLE([strip],
[ --disable-strip Disable calling strip(1) on install],
[
if test "x$enableval" = "xno" ; then
STRIP_OPT=
fi
]
)
AC_SUBST([STRIP_OPT])
if test -z "$xauth_path" ; then
XAUTH_PATH="undefined"
AC_SUBST([XAUTH_PATH])
else
AC_DEFINE_UNQUOTED([XAUTH_PATH], ["$xauth_path"],
[Define if xauth is found in your path])
XAUTH_PATH=$xauth_path
AC_SUBST([XAUTH_PATH])
fi
dnl # --with-maildir=/path/to/mail gets top priority.
dnl # if maildir is set in the platform case statement above we use that.
dnl # Otherwise we run a program to get the dir from system headers.
dnl # We first look for _PATH_MAILDIR then MAILDIR then _PATH_MAIL
dnl # If we find _PATH_MAILDIR we do nothing because that is what
dnl # session.c expects anyway. Otherwise we set to the value found
dnl # stripping any trailing slash. If for some strage reason our program
dnl # does not find what it needs, we default to /var/spool/mail.
# Check for mail directory
AC_ARG_WITH([maildir],
[ --with-maildir=/path/to/mail Specify your system mail directory],
[
if test "X$withval" != X && test "x$withval" != xno && \
test "x${withval}" != xyes; then
AC_DEFINE_UNQUOTED([MAIL_DIRECTORY], ["$withval"],
[Set this to your mail directory if you do not have _PATH_MAILDIR])
fi
],[
if test "X$maildir" != "X"; then
AC_DEFINE_UNQUOTED([MAIL_DIRECTORY], ["$maildir"])
else
AC_MSG_CHECKING([Discovering system mail directory])
AC_RUN_IFELSE(
[AC_LANG_PROGRAM([[
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_PATHS_H
#include <paths.h>
#endif
#ifdef HAVE_MAILLOCK_H
#include <maillock.h>
#endif
#define DATA "conftest.maildir"
]], [[
FILE *fd;
int rc;
fd = fopen(DATA,"w");
if(fd == NULL)
exit(1);
#if defined (_PATH_MAILDIR)
if ((rc = fprintf(fd ,"_PATH_MAILDIR:%s\n", _PATH_MAILDIR)) <0)
exit(1);
#elif defined (MAILDIR)
if ((rc = fprintf(fd ,"MAILDIR:%s\n", MAILDIR)) <0)
exit(1);
#elif defined (_PATH_MAIL)
if ((rc = fprintf(fd ,"_PATH_MAIL:%s\n", _PATH_MAIL)) <0)
exit(1);
#else
exit (2);
#endif
exit(0);
]])],
[
maildir_what=`awk -F: '{print $1}' conftest.maildir`
maildir=`awk -F: '{print $2}' conftest.maildir \
| sed 's|/$||'`
AC_MSG_RESULT([Using: $maildir from $maildir_what])
if test "x$maildir_what" != "x_PATH_MAILDIR"; then
AC_DEFINE_UNQUOTED([MAIL_DIRECTORY], ["$maildir"])
fi
],
[
if test "X$ac_status" = "X2";then
# our test program didn't find it. Default to /var/spool/mail
AC_MSG_RESULT([Using: default value of /var/spool/mail])
AC_DEFINE_UNQUOTED([MAIL_DIRECTORY], ["/var/spool/mail"])
else
AC_MSG_RESULT([*** not found ***])
fi
],
[
AC_MSG_WARN([cross compiling: use --with-maildir=/path/to/mail])
]
)
fi
]
) # maildir
if test ! -z "$cross_compiling" && test "x$cross_compiling" = "xyes"; then
AC_MSG_WARN([cross compiling: Disabling /dev/ptmx test])
disable_ptmx_check=yes
fi
if test -z "$no_dev_ptmx" ; then
if test "x$disable_ptmx_check" != "xyes" ; then
AC_CHECK_FILE(["/dev/ptmx"],
[
AC_DEFINE_UNQUOTED([HAVE_DEV_PTMX], [1],
[Define if you have /dev/ptmx])
have_dev_ptmx=1
]
)
fi
fi
if test ! -z "$cross_compiling" && test "x$cross_compiling" != "xyes"; then
AC_CHECK_FILE(["/dev/ptc"],
[
AC_DEFINE_UNQUOTED([HAVE_DEV_PTS_AND_PTC], [1],
[Define if you have /dev/ptc])
have_dev_ptc=1
]
)
else
AC_MSG_WARN([cross compiling: Disabling /dev/ptc test])
fi
# Options from here on. Some of these are preset by platform above
AC_ARG_WITH([mantype],
[ --with-mantype=man|cat|doc Set man page type],
[
case "$withval" in
man|cat|doc)
MANTYPE=$withval
;;
*)
AC_MSG_ERROR([invalid man type: $withval])
;;
esac
]
)
if test -z "$MANTYPE"; then
if ${MANDOC} ${srcdir}/ssh.1 >/dev/null 2>&1; then
MANTYPE=doc
elif ${NROFF} -mdoc ${srcdir}/ssh.1 >/dev/null 2>&1; then
MANTYPE=doc
elif ${NROFF} -man ${srcdir}/ssh.1 >/dev/null 2>&1; then
MANTYPE=man
else
MANTYPE=cat
fi
fi
AC_SUBST([MANTYPE])
if test "$MANTYPE" = "doc"; then
mansubdir=man;
else
mansubdir=$MANTYPE;
fi
AC_SUBST([mansubdir])
# Whether to disable shadow password support
AC_ARG_WITH([shadow],
[ --without-shadow Disable shadow password support],
[
if test "x$withval" = "xno" ; then
AC_DEFINE([DISABLE_SHADOW])
disable_shadow=yes
fi
]
)
if test -z "$disable_shadow" ; then
AC_MSG_CHECKING([if the systems has expire shadow information])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <sys/types.h>
#include <shadow.h>
struct spwd sp;
]], [[ sp.sp_expire = sp.sp_lstchg = sp.sp_inact = 0; ]])],
[ sp_expire_available=yes ], [
])
if test "x$sp_expire_available" = "xyes" ; then
AC_MSG_RESULT([yes])
AC_DEFINE([HAS_SHADOW_EXPIRE], [1],
[Define if you want to use shadow password expire field])
else
AC_MSG_RESULT([no])
fi
fi
# Use ip address instead of hostname in $DISPLAY
if test ! -z "$IPADDR_IN_DISPLAY" ; then
DISPLAY_HACK_MSG="yes"
AC_DEFINE([IPADDR_IN_DISPLAY], [1],
[Define if you need to use IP address
instead of hostname in $DISPLAY])
else
DISPLAY_HACK_MSG="no"
AC_ARG_WITH([ipaddr-display],
[ --with-ipaddr-display Use ip address instead of hostname in $DISPLAY],
[
if test "x$withval" != "xno" ; then
AC_DEFINE([IPADDR_IN_DISPLAY])
DISPLAY_HACK_MSG="yes"
fi
]
)
fi
# check for /etc/default/login and use it if present.
AC_ARG_ENABLE([etc-default-login],
[ --disable-etc-default-login Disable using PATH from /etc/default/login [no]],
[ if test "x$enableval" = "xno"; then
AC_MSG_NOTICE([/etc/default/login handling disabled])
etc_default_login=no
else
etc_default_login=yes
fi ],
[ if test ! -z "$cross_compiling" && test "x$cross_compiling" = "xyes";
then
AC_MSG_WARN([cross compiling: not checking /etc/default/login])
etc_default_login=no
else
etc_default_login=yes
fi ]
)
if test "x$etc_default_login" != "xno"; then
AC_CHECK_FILE(["/etc/default/login"],
[ external_path_file=/etc/default/login ])
if test "x$external_path_file" = "x/etc/default/login"; then
AC_DEFINE([HAVE_ETC_DEFAULT_LOGIN], [1],
[Define if your system has /etc/default/login])
fi
fi
dnl BSD systems use /etc/login.conf so --with-default-path= has no effect
if test $ac_cv_func_login_getcapbool = "yes" && \
test $ac_cv_header_login_cap_h = "yes" ; then
external_path_file=/etc/login.conf
fi
# Whether to mess with the default path
SERVER_PATH_MSG="(default)"
AC_ARG_WITH([default-path],
[ --with-default-path= Specify default $PATH environment for server],
[
if test "x$external_path_file" = "x/etc/login.conf" ; then
AC_MSG_WARN([
--with-default-path=PATH has no effect on this system.
Edit /etc/login.conf instead.])
elif test "x$withval" != "xno" ; then
if test ! -z "$external_path_file" ; then
AC_MSG_WARN([
--with-default-path=PATH will only be used if PATH is not defined in
$external_path_file .])
fi
user_path="$withval"
SERVER_PATH_MSG="$withval"
fi
],
[ if test "x$external_path_file" = "x/etc/login.conf" ; then
AC_MSG_WARN([Make sure the path to scp is in /etc/login.conf])
else
if test ! -z "$external_path_file" ; then
AC_MSG_WARN([
If PATH is defined in $external_path_file, ensure the path to scp is included,
otherwise scp will not work.])
fi
AC_RUN_IFELSE(
[AC_LANG_PROGRAM([[
/* find out what STDPATH is */
#include <stdio.h>
#include <stdlib.h>
#ifdef HAVE_PATHS_H
# include <paths.h>
#endif
#ifndef _PATH_STDPATH
# ifdef _PATH_USERPATH /* Irix */
# define _PATH_STDPATH _PATH_USERPATH
# else
# define _PATH_STDPATH "/usr/bin:/bin:/usr/sbin:/sbin"
# endif
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define DATA "conftest.stdpath"
]], [[
FILE *fd;
int rc;
fd = fopen(DATA,"w");
if(fd == NULL)
exit(1);
if ((rc = fprintf(fd,"%s", _PATH_STDPATH)) < 0)
exit(1);
exit(0);
]])],
[ user_path=`cat conftest.stdpath` ],
[ user_path="/usr/bin:/bin:/usr/sbin:/sbin" ],
[ user_path="/usr/bin:/bin:/usr/sbin:/sbin" ]
)
# make sure $bindir is in USER_PATH so scp will work
t_bindir="${bindir}"
while echo "${t_bindir}" | egrep '\$\{|NONE/' >/dev/null 2>&1; do
t_bindir=`eval echo ${t_bindir}`
case $t_bindir in
NONE/*) t_bindir=`echo $t_bindir | sed "s~NONE~$prefix~"` ;;
esac
case $t_bindir in
NONE/*) t_bindir=`echo $t_bindir | sed "s~NONE~$ac_default_prefix~"` ;;
esac
done
echo $user_path | grep ":$t_bindir" > /dev/null 2>&1
if test $? -ne 0 ; then
echo $user_path | grep "^$t_bindir" > /dev/null 2>&1
if test $? -ne 0 ; then
user_path=$user_path:$t_bindir
AC_MSG_RESULT([Adding $t_bindir to USER_PATH so scp will work])
fi
fi
fi ]
)
if test "x$external_path_file" != "x/etc/login.conf" ; then
AC_DEFINE_UNQUOTED([USER_PATH], ["$user_path"], [Specify default $PATH])
AC_SUBST([user_path])
fi
# Set superuser path separately to user path
AC_ARG_WITH([superuser-path],
[ --with-superuser-path= Specify different path for super-user],
[
if test -n "$withval" && test "x$withval" != "xno" && \
test "x${withval}" != "xyes"; then
AC_DEFINE_UNQUOTED([SUPERUSER_PATH], ["$withval"],
[Define if you want a different $PATH
for the superuser])
superuser_path=$withval
fi
]
)
AC_MSG_CHECKING([if we need to convert IPv4 in IPv6-mapped addresses])
IPV4_IN6_HACK_MSG="no"
AC_ARG_WITH(4in6,
[ --with-4in6 Check for and convert IPv4 in IPv6 mapped addresses],
[
if test "x$withval" != "xno" ; then
AC_MSG_RESULT([yes])
AC_DEFINE([IPV4_IN_IPV6], [1],
[Detect IPv4 in IPv6 mapped addresses
and treat as IPv4])
IPV4_IN6_HACK_MSG="yes"
else
AC_MSG_RESULT([no])
fi
], [
if test "x$inet6_default_4in6" = "xyes"; then
AC_MSG_RESULT([yes (default)])
AC_DEFINE([IPV4_IN_IPV6])
IPV4_IN6_HACK_MSG="yes"
else
AC_MSG_RESULT([no (default)])
fi
]
)
# Whether to enable BSD auth support
BSD_AUTH_MSG=no
AC_ARG_WITH([bsd-auth],
[ --with-bsd-auth Enable BSD auth support],
[
if test "x$withval" != "xno" ; then
AC_DEFINE([BSD_AUTH], [1],
[Define if you have BSD auth support])
BSD_AUTH_MSG=yes
fi
]
)
# Where to place sshd.pid
piddir=/var/run
# make sure the directory exists
if test ! -d $piddir ; then
piddir=`eval echo ${sysconfdir}`
case $piddir in
NONE/*) piddir=`echo $piddir | sed "s~NONE~$ac_default_prefix~"` ;;
esac
fi
AC_ARG_WITH([pid-dir],
[ --with-pid-dir=PATH Specify location of sshd.pid file],
[
if test -n "$withval" && test "x$withval" != "xno" && \
test "x${withval}" != "xyes"; then
piddir=$withval
if test ! -d $piddir ; then
AC_MSG_WARN([** no $piddir directory on this system **])
fi
fi
]
)
AC_DEFINE_UNQUOTED([_PATH_SSH_PIDDIR], ["$piddir"],
[Specify location of ssh.pid])
AC_SUBST([piddir])
dnl allow user to disable some login recording features
AC_ARG_ENABLE([lastlog],
[ --disable-lastlog disable use of lastlog even if detected [no]],
[
if test "x$enableval" = "xno" ; then
AC_DEFINE([DISABLE_LASTLOG])
fi
]
)
AC_ARG_ENABLE([utmp],
[ --disable-utmp disable use of utmp even if detected [no]],
[
if test "x$enableval" = "xno" ; then
AC_DEFINE([DISABLE_UTMP])
fi
]
)
AC_ARG_ENABLE([utmpx],
[ --disable-utmpx disable use of utmpx even if detected [no]],
[
if test "x$enableval" = "xno" ; then
AC_DEFINE([DISABLE_UTMPX], [1],
[Define if you don't want to use utmpx])
fi
]
)
AC_ARG_ENABLE([wtmp],
[ --disable-wtmp disable use of wtmp even if detected [no]],
[
if test "x$enableval" = "xno" ; then
AC_DEFINE([DISABLE_WTMP])
fi
]
)
AC_ARG_ENABLE([wtmpx],
[ --disable-wtmpx disable use of wtmpx even if detected [no]],
[
if test "x$enableval" = "xno" ; then
AC_DEFINE([DISABLE_WTMPX], [1],
[Define if you don't want to use wtmpx])
fi
]
)
AC_ARG_ENABLE([libutil],
[ --disable-libutil disable use of libutil (login() etc.) [no]],
[
if test "x$enableval" = "xno" ; then
AC_DEFINE([DISABLE_LOGIN])
fi
]
)
AC_ARG_ENABLE([pututline],
[ --disable-pututline disable use of pututline() etc. ([uw]tmp) [no]],
[
if test "x$enableval" = "xno" ; then
AC_DEFINE([DISABLE_PUTUTLINE], [1],
[Define if you don't want to use pututline()
etc. to write [uw]tmp])
fi
]
)
AC_ARG_ENABLE([pututxline],
[ --disable-pututxline disable use of pututxline() etc. ([uw]tmpx) [no]],
[
if test "x$enableval" = "xno" ; then
AC_DEFINE([DISABLE_PUTUTXLINE], [1],
[Define if you don't want to use pututxline()
etc. to write [uw]tmpx])
fi
]
)
AC_ARG_WITH([lastlog],
[ --with-lastlog=FILE|DIR specify lastlog location [common locations]],
[
if test "x$withval" = "xno" ; then
AC_DEFINE([DISABLE_LASTLOG])
elif test -n "$withval" && test "x${withval}" != "xyes"; then
conf_lastlog_location=$withval
fi
]
)
dnl lastlog, [uw]tmpx? detection
dnl NOTE: set the paths in the platform section to avoid the
dnl need for command-line parameters
dnl lastlog and [uw]tmp are subject to a file search if all else fails
dnl lastlog detection
dnl NOTE: the code itself will detect if lastlog is a directory
AC_MSG_CHECKING([if your system defines LASTLOG_FILE])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <sys/types.h>
#include <utmp.h>
#ifdef HAVE_LASTLOG_H
# include <lastlog.h>
#endif
#ifdef HAVE_PATHS_H
# include <paths.h>
#endif
#ifdef HAVE_LOGIN_H
# include <login.h>
#endif
]], [[ char *lastlog = LASTLOG_FILE; ]])],
[ AC_MSG_RESULT([yes]) ],
[
AC_MSG_RESULT([no])
AC_MSG_CHECKING([if your system defines _PATH_LASTLOG])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <sys/types.h>
#include <utmp.h>
#ifdef HAVE_LASTLOG_H
# include <lastlog.h>
#endif
#ifdef HAVE_PATHS_H
# include <paths.h>
#endif
]], [[ char *lastlog = _PATH_LASTLOG; ]])],
[ AC_MSG_RESULT([yes]) ],
[
AC_MSG_RESULT([no])
system_lastlog_path=no
])
])
if test -z "$conf_lastlog_location"; then
if test x"$system_lastlog_path" = x"no" ; then
for f in /var/log/lastlog /usr/adm/lastlog /var/adm/lastlog /etc/security/lastlog ; do
if (test -d "$f" || test -f "$f") ; then
conf_lastlog_location=$f
fi
done
if test -z "$conf_lastlog_location"; then
AC_MSG_WARN([** Cannot find lastlog **])
dnl Don't define DISABLE_LASTLOG - that means we don't try wtmp/wtmpx
fi
fi
fi
if test -n "$conf_lastlog_location"; then
AC_DEFINE_UNQUOTED([CONF_LASTLOG_FILE], ["$conf_lastlog_location"],
[Define if you want to specify the path to your lastlog file])
fi
dnl utmp detection
AC_MSG_CHECKING([if your system defines UTMP_FILE])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <sys/types.h>
#include <utmp.h>
#ifdef HAVE_PATHS_H
# include <paths.h>
#endif
]], [[ char *utmp = UTMP_FILE; ]])],
[ AC_MSG_RESULT([yes]) ],
[ AC_MSG_RESULT([no])
system_utmp_path=no
])
if test -z "$conf_utmp_location"; then
if test x"$system_utmp_path" = x"no" ; then
for f in /etc/utmp /usr/adm/utmp /var/run/utmp; do
if test -f $f ; then
conf_utmp_location=$f
fi
done
if test -z "$conf_utmp_location"; then
AC_DEFINE([DISABLE_UTMP])
fi
fi
fi
if test -n "$conf_utmp_location"; then
AC_DEFINE_UNQUOTED([CONF_UTMP_FILE], ["$conf_utmp_location"],
[Define if you want to specify the path to your utmp file])
fi
dnl wtmp detection
AC_MSG_CHECKING([if your system defines WTMP_FILE])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <sys/types.h>
#include <utmp.h>
#ifdef HAVE_PATHS_H
# include <paths.h>
#endif
]], [[ char *wtmp = WTMP_FILE; ]])],
[ AC_MSG_RESULT([yes]) ],
[ AC_MSG_RESULT([no])
system_wtmp_path=no
])
if test -z "$conf_wtmp_location"; then
if test x"$system_wtmp_path" = x"no" ; then
for f in /usr/adm/wtmp /var/log/wtmp; do
if test -f $f ; then
conf_wtmp_location=$f
fi
done
if test -z "$conf_wtmp_location"; then
AC_DEFINE([DISABLE_WTMP])
fi
fi
fi
if test -n "$conf_wtmp_location"; then
AC_DEFINE_UNQUOTED([CONF_WTMP_FILE], ["$conf_wtmp_location"],
[Define if you want to specify the path to your wtmp file])
fi
dnl wtmpx detection
AC_MSG_CHECKING([if your system defines WTMPX_FILE])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <sys/types.h>
#include <utmp.h>
#ifdef HAVE_UTMPX_H
#include <utmpx.h>
#endif
#ifdef HAVE_PATHS_H
# include <paths.h>
#endif
]], [[ char *wtmpx = WTMPX_FILE; ]])],
[ AC_MSG_RESULT([yes]) ],
[ AC_MSG_RESULT([no])
system_wtmpx_path=no
])
if test -z "$conf_wtmpx_location"; then
if test x"$system_wtmpx_path" = x"no" ; then
AC_DEFINE([DISABLE_WTMPX])
fi
else
AC_DEFINE_UNQUOTED([CONF_WTMPX_FILE], ["$conf_wtmpx_location"],
[Define if you want to specify the path to your wtmpx file])
fi
if test ! -z "$blibpath" ; then
LDFLAGS="$LDFLAGS $blibflags$blibpath"
AC_MSG_WARN([Please check and edit blibpath in LDFLAGS in Makefile])
fi
AC_CHECK_MEMBER([struct lastlog.ll_line], [], [
if test x$SKIP_DISABLE_LASTLOG_DEFINE != "xyes" ; then
AC_DEFINE([DISABLE_LASTLOG])
fi
], [
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_UTMP_H
#include <utmp.h>
#endif
#ifdef HAVE_UTMPX_H
#include <utmpx.h>
#endif
#ifdef HAVE_LASTLOG_H
#include <lastlog.h>
#endif
])
AC_CHECK_MEMBER([struct utmp.ut_line], [], [
AC_DEFINE([DISABLE_UTMP])
AC_DEFINE([DISABLE_WTMP])
], [
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_UTMP_H
#include <utmp.h>
#endif
#ifdef HAVE_UTMPX_H
#include <utmpx.h>
#endif
#ifdef HAVE_LASTLOG_H
#include <lastlog.h>
#endif
])
dnl Adding -Werror to CFLAGS early prevents configure tests from running.
dnl Add now.
CFLAGS="$CFLAGS $werror_flags"
if test "x$ac_cv_func_getaddrinfo" != "xyes" ; then
TEST_SSH_IPV6=no
else
TEST_SSH_IPV6=yes
fi
AC_CHECK_DECL([BROKEN_GETADDRINFO], [TEST_SSH_IPV6=no])
AC_SUBST([TEST_SSH_IPV6], [$TEST_SSH_IPV6])
AC_SUBST([TEST_SSH_UTF8], [$TEST_SSH_UTF8])
AC_SUBST([TEST_MALLOC_OPTIONS], [$TEST_MALLOC_OPTIONS])
AC_SUBST([UNSUPPORTED_ALGORITHMS], [$unsupported_algorithms])
AC_SUBST([DEPEND], [$(cat $srcdir/.depend)])
CFLAGS="${CFLAGS} ${CFLAGS_AFTER}"
LDFLAGS="${LDFLAGS} ${LDFLAGS_AFTER}"
# Make a copy of CFLAGS/LDFLAGS without PIE options.
LDFLAGS_NOPIE=`echo "$LDFLAGS" | sed 's/ -pie//'`
CFLAGS_NOPIE=`echo "$CFLAGS" | sed 's/ -fPIE//'`
AC_SUBST([LDFLAGS_NOPIE])
AC_SUBST([CFLAGS_NOPIE])
AC_EXEEXT
AC_CONFIG_FILES([Makefile buildpkg.sh opensshd.init openssh.xml \
openbsd-compat/Makefile openbsd-compat/regress/Makefile \
survey.sh])
AC_OUTPUT
# Print summary of options
# Someone please show me a better way :)
A=`eval echo ${prefix}` ; A=`eval echo ${A}`
B=`eval echo ${bindir}` ; B=`eval echo ${B}`
C=`eval echo ${sbindir}` ; C=`eval echo ${C}`
D=`eval echo ${sysconfdir}` ; D=`eval echo ${D}`
E=`eval echo ${libexecdir}/ssh-askpass` ; E=`eval echo ${E}`
F=`eval echo ${mandir}/${mansubdir}X` ; F=`eval echo ${F}`
G=`eval echo ${piddir}` ; G=`eval echo ${G}`
H=`eval echo ${PRIVSEP_PATH}` ; H=`eval echo ${H}`
I=`eval echo ${user_path}` ; I=`eval echo ${I}`
J=`eval echo ${superuser_path}` ; J=`eval echo ${J}`
echo ""
echo "OpenSSH has been configured with the following options:"
echo " User binaries: $B"
echo " System binaries: $C"
echo " Configuration files: $D"
echo " Askpass program: $E"
echo " Manual pages: $F"
echo " PID file: $G"
echo " Privilege separation chroot path: $H"
if test "x$external_path_file" = "x/etc/login.conf" ; then
echo " At runtime, sshd will use the path defined in $external_path_file"
echo " Make sure the path to scp is present, otherwise scp will not work"
else
echo " sshd default user PATH: $I"
if test ! -z "$external_path_file"; then
echo " (If PATH is set in $external_path_file it will be used instead. If"
echo " used, ensure the path to scp is present, otherwise scp will not work.)"
fi
fi
if test ! -z "$superuser_path" ; then
echo " sshd superuser user PATH: $J"
fi
echo " Manpage format: $MANTYPE"
echo " PAM support: $PAM_MSG"
echo " OSF SIA support: $SIA_MSG"
echo " KerberosV support: $KRB5_MSG"
echo " SELinux support: $SELINUX_MSG"
echo " TCP Wrappers support: $TCPW_MSG"
echo " libedit support: $LIBEDIT_MSG"
echo " libldns support: $LDNS_MSG"
echo " Solaris process contract support: $SPC_MSG"
echo " Solaris project support: $SP_MSG"
echo " Solaris privilege support: $SPP_MSG"
echo " IP address in \$DISPLAY hack: $DISPLAY_HACK_MSG"
echo " Translate v4 in v6 hack: $IPV4_IN6_HACK_MSG"
echo " BSD Auth support: $BSD_AUTH_MSG"
echo " Random number source: $RAND_MSG"
echo " Privsep sandbox style: $SANDBOX_STYLE"
echo " PKCS#11 support: $enable_pkcs11"
echo " U2F/FIDO support: $enable_sk"
echo ""
echo " Host: ${host}"
echo " Compiler: ${CC}"
echo " Compiler flags: ${CFLAGS}"
echo "Preprocessor flags: ${CPPFLAGS}"
echo " Linker flags: ${LDFLAGS}"
echo " Libraries: ${LIBS}"
if test ! -z "${CHANNELLIBS}"; then
echo " +for channels: ${CHANNELLIBS}"
fi
if test ! -z "${LIBFIDO2}"; then
echo " +for FIDO2: ${LIBFIDO2}"
fi
if test ! -z "${SSHDLIBS}"; then
echo " +for sshd: ${SSHDLIBS}"
fi
echo ""
if test "x$MAKE_PACKAGE_SUPPORTED" = "xyes" ; then
echo "SVR4 style packages are supported with \"make package\""
echo ""
fi
if test "x$PAM_MSG" = "xyes" ; then
echo "PAM is enabled. You may need to install a PAM control file "
echo "for sshd, otherwise password authentication may fail. "
echo "Example PAM control files can be found in the contrib/ "
echo "subdirectory"
echo ""
fi
if test ! -z "$NO_PEERCHECK" ; then
echo "WARNING: the operating system that you are using does not"
echo "appear to support getpeereid(), getpeerucred() or the"
echo "SO_PEERCRED getsockopt() option. These facilities are used to"
echo "enforce security checks to prevent unauthorised connections to"
echo "ssh-agent. Their absence increases the risk that a malicious"
echo "user can connect to your agent."
echo ""
fi
if test "$AUDIT_MODULE" = "bsm" ; then
echo "WARNING: BSM audit support is currently considered EXPERIMENTAL."
echo "See the Solaris section in README.platform for details."
fi
diff --git a/crypto/openssh/contrib/redhat/openssh.spec b/crypto/openssh/contrib/redhat/openssh.spec
index 124afccd1dcb..423079a03c78 100644
--- a/crypto/openssh/contrib/redhat/openssh.spec
+++ b/crypto/openssh/contrib/redhat/openssh.spec
@@ -1,850 +1,850 @@
-%global ver 9.1p1
+%global ver 9.2p1
%global rel 1%{?dist}
# OpenSSH privilege separation requires a user & group ID
%global sshd_uid 74
%global sshd_gid 74
# Version of ssh-askpass
%global aversion 1.2.4.1
# Do we want to disable building of x11-askpass? (1=yes 0=no)
%global no_x11_askpass 0
# Do we want to disable building of gnome-askpass? (1=yes 0=no)
%global no_gnome_askpass 0
# Do we want to link against a static libcrypto? (1=yes 0=no)
%global static_libcrypto 0
# Do we want smartcard support (1=yes 0=no)
%global scard 0
# Use GTK2 instead of GNOME in gnome-ssh-askpass
%global gtk2 1
# Use build6x options for older RHEL builds
# RHEL 7 not yet supported
%if 0%{?rhel} > 6
%global build6x 0
%else
%global build6x 1
%endif
%if 0%{?fedora} >= 26
%global compat_openssl 1
%else
%global compat_openssl 0
%endif
# Do we want kerberos5 support (1=yes 0=no)
%global kerberos5 1
# Reserve options to override askpass settings with:
# rpm -ba|--rebuild --define 'skip_xxx 1'
%{?skip_x11_askpass:%global no_x11_askpass 1}
%{?skip_gnome_askpass:%global no_gnome_askpass 1}
# Add option to build without GTK2 for older platforms with only GTK+.
# RedHat <= 7.2 and Red Hat Advanced Server 2.1 are examples.
# rpm -ba|--rebuild --define 'no_gtk2 1'
%{?no_gtk2:%global gtk2 0}
# Is this a build for RHL 6.x or earlier?
%{?build_6x:%global build6x 1}
# If this is RHL 6.x, the default configuration has sysconfdir in /usr/etc.
%if %{build6x}
%global _sysconfdir /etc
%endif
# Options for static OpenSSL link:
# rpm -ba|--rebuild --define "static_openssl 1"
%{?static_openssl:%global static_libcrypto 1}
# Options for Smartcard support: (needs libsectok and openssl-engine)
# rpm -ba|--rebuild --define "smartcard 1"
%{?smartcard:%global scard 1}
# Is this a build for the rescue CD (without PAM)? (1=yes 0=no)
%global rescue 0
%{?build_rescue:%global rescue 1}
# Turn off some stuff for resuce builds
%if %{rescue}
%global kerberos5 0
%endif
Summary: The OpenSSH implementation of SSH protocol version 2.
Name: openssh
Version: %{ver}
%if %{rescue}
Release: %{rel}rescue
%else
Release: %{rel}
%endif
URL: https://www.openssh.com/portable.html
Source0: https://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-%{version}.tar.gz
Source1: http://www.jmknoble.net/software/x11-ssh-askpass/x11-ssh-askpass-%{aversion}.tar.gz
License: BSD
Group: Applications/Internet
BuildRoot: %{_tmppath}/%{name}-%{version}-buildroot
Obsoletes: ssh
%if %{build6x}
PreReq: initscripts >= 5.00
%else
Requires: initscripts >= 5.20
%endif
BuildRequires: perl
%if %{compat_openssl}
BuildRequires: compat-openssl10-devel
%else
BuildRequires: openssl-devel >= 1.0.1
BuildRequires: openssl-devel < 1.1
%endif
BuildRequires: /bin/login
%if ! %{build6x}
BuildRequires: glibc-devel, pam
%else
BuildRequires: /usr/include/security/pam_appl.h
%endif
%if ! %{no_x11_askpass}
BuildRequires: /usr/include/X11/Xlib.h
# Xt development tools
BuildRequires: libXt-devel
# Provides xmkmf
BuildRequires: imake
# Rely on relatively recent gtk
BuildRequires: gtk2-devel
%endif
%if ! %{no_gnome_askpass}
BuildRequires: pkgconfig
%endif
%if %{kerberos5}
BuildRequires: krb5-devel
BuildRequires: krb5-libs
%endif
%package clients
Summary: OpenSSH clients.
Requires: openssh = %{version}-%{release}
Group: Applications/Internet
Obsoletes: ssh-clients
%package server
Summary: The OpenSSH server daemon.
Group: System Environment/Daemons
Obsoletes: ssh-server
Requires: openssh = %{version}-%{release}, chkconfig >= 0.9
%if ! %{build6x}
Requires: /etc/pam.d/system-auth
%endif
%package askpass
Summary: A passphrase dialog for OpenSSH and X.
Group: Applications/Internet
Requires: openssh = %{version}-%{release}
Obsoletes: ssh-extras
%package askpass-gnome
Summary: A passphrase dialog for OpenSSH, X, and GNOME.
Group: Applications/Internet
Requires: openssh = %{version}-%{release}
Obsoletes: ssh-extras
%description
SSH (Secure SHell) is a program for logging into and executing
commands on a remote machine. SSH is intended to replace rlogin and
rsh, and to provide secure encrypted communications between two
untrusted hosts over an insecure network. X11 connections and
arbitrary TCP/IP ports can also be forwarded over the secure channel.
OpenSSH is OpenBSD's version of the last free version of SSH, bringing
it up to date in terms of security and features, as well as removing
all patented algorithms to separate libraries.
This package includes the core files necessary for both the OpenSSH
client and server. To make this package useful, you should also
install openssh-clients, openssh-server, or both.
%description clients
OpenSSH is a free version of SSH (Secure SHell), a program for logging
into and executing commands on a remote machine. This package includes
the clients necessary to make encrypted connections to SSH servers.
You'll also need to install the openssh package on OpenSSH clients.
%description server
OpenSSH is a free version of SSH (Secure SHell), a program for logging
into and executing commands on a remote machine. This package contains
the secure shell daemon (sshd). The sshd daemon allows SSH clients to
securely connect to your SSH server. You also need to have the openssh
package installed.
%description askpass
OpenSSH is a free version of SSH (Secure SHell), a program for logging
into and executing commands on a remote machine. This package contains
an X11 passphrase dialog for OpenSSH.
%description askpass-gnome
OpenSSH is a free version of SSH (Secure SHell), a program for logging
into and executing commands on a remote machine. This package contains
an X11 passphrase dialog for OpenSSH and the GNOME GUI desktop
environment.
%prep
%if ! %{no_x11_askpass}
%setup -q -a 1
%else
%setup -q
%endif
%build
%if %{rescue}
CFLAGS="$RPM_OPT_FLAGS -Os"; export CFLAGS
%endif
%configure \
--sysconfdir=%{_sysconfdir}/ssh \
--libexecdir=%{_libexecdir}/openssh \
--datadir=%{_datadir}/openssh \
--with-default-path=/usr/local/bin:/bin:/usr/bin \
--with-superuser-path=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin \
--with-privsep-path=%{_var}/empty/sshd \
--mandir=%{_mandir} \
--with-mantype=man \
--disable-strip \
%if %{scard}
--with-smartcard \
%endif
%if %{rescue}
--without-pam \
%else
--with-pam \
%endif
%if %{kerberos5}
--with-kerberos5=$K5DIR \
%endif
%if %{static_libcrypto}
perl -pi -e "s|-lcrypto|%{_libdir}/libcrypto.a|g" Makefile
%endif
make
%if ! %{no_x11_askpass}
pushd x11-ssh-askpass-%{aversion}
%configure --libexecdir=%{_libexecdir}/openssh
xmkmf -a
make
popd
%endif
# Define a variable to toggle gnome1/gtk2 building. This is necessary
# because RPM doesn't handle nested %if statements.
%if %{gtk2}
gtk2=yes
%else
gtk2=no
%endif
%if ! %{no_gnome_askpass}
pushd contrib
if [ $gtk2 = yes ] ; then
make gnome-ssh-askpass2
mv gnome-ssh-askpass2 gnome-ssh-askpass
else
make gnome-ssh-askpass1
mv gnome-ssh-askpass1 gnome-ssh-askpass
fi
popd
%endif
%install
rm -rf $RPM_BUILD_ROOT
mkdir -p -m755 $RPM_BUILD_ROOT%{_sysconfdir}/ssh
mkdir -p -m755 $RPM_BUILD_ROOT%{_libexecdir}/openssh
mkdir -p -m755 $RPM_BUILD_ROOT%{_var}/empty/sshd
make install DESTDIR=$RPM_BUILD_ROOT
install -d $RPM_BUILD_ROOT/etc/pam.d/
install -d $RPM_BUILD_ROOT/etc/rc.d/init.d
install -d $RPM_BUILD_ROOT%{_libexecdir}/openssh
%if %{build6x}
install -m644 contrib/redhat/sshd.pam.old $RPM_BUILD_ROOT/etc/pam.d/sshd
%else
install -m644 contrib/redhat/sshd.pam $RPM_BUILD_ROOT/etc/pam.d/sshd
%endif
install -m755 contrib/redhat/sshd.init $RPM_BUILD_ROOT/etc/rc.d/init.d/sshd
%if ! %{no_x11_askpass}
install x11-ssh-askpass-%{aversion}/x11-ssh-askpass $RPM_BUILD_ROOT%{_libexecdir}/openssh/x11-ssh-askpass
ln -s x11-ssh-askpass $RPM_BUILD_ROOT%{_libexecdir}/openssh/ssh-askpass
%endif
%if ! %{no_gnome_askpass}
install contrib/gnome-ssh-askpass $RPM_BUILD_ROOT%{_libexecdir}/openssh/gnome-ssh-askpass
%endif
%if ! %{scard}
rm -f $RPM_BUILD_ROOT/usr/share/openssh/Ssh.bin
%endif
%if ! %{no_gnome_askpass}
install -m 755 -d $RPM_BUILD_ROOT%{_sysconfdir}/profile.d/
install -m 755 contrib/redhat/gnome-ssh-askpass.csh $RPM_BUILD_ROOT%{_sysconfdir}/profile.d/
install -m 755 contrib/redhat/gnome-ssh-askpass.sh $RPM_BUILD_ROOT%{_sysconfdir}/profile.d/
%endif
perl -pi -e "s|$RPM_BUILD_ROOT||g" $RPM_BUILD_ROOT%{_mandir}/man*/*
%clean
rm -rf $RPM_BUILD_ROOT
%triggerun server -- ssh-server
if [ "$1" != 0 -a -r /var/run/sshd.pid ] ; then
touch /var/run/sshd.restart
fi
%triggerun server -- openssh-server < 2.5.0p1
# Count the number of HostKey and HostDsaKey statements we have.
gawk 'BEGIN {IGNORECASE=1}
/^hostkey/ || /^hostdsakey/ {sawhostkey = sawhostkey + 1}
END {exit sawhostkey}' /etc/ssh/sshd_config
# And if we only found one, we know the client was relying on the old default
# behavior, which loaded the the SSH2 DSA host key when HostDsaKey wasn't
# specified. Now that HostKey is used for both SSH1 and SSH2 keys, specifying
# one nullifies the default, which would have loaded both.
if [ $? -eq 1 ] ; then
echo HostKey /etc/ssh/ssh_host_rsa_key >> /etc/ssh/sshd_config
echo HostKey /etc/ssh/ssh_host_dsa_key >> /etc/ssh/sshd_config
fi
%triggerpostun server -- ssh-server
if [ "$1" != 0 ] ; then
/sbin/chkconfig --add sshd
if test -f /var/run/sshd.restart ; then
rm -f /var/run/sshd.restart
/sbin/service sshd start > /dev/null 2>&1 || :
fi
fi
%pre server
%{_sbindir}/groupadd -r -g %{sshd_gid} sshd 2>/dev/null || :
%{_sbindir}/useradd -d /var/empty/sshd -s /bin/false -u %{sshd_uid} \
-g sshd -M -r sshd 2>/dev/null || :
%post server
/sbin/chkconfig --add sshd
%postun server
/sbin/service sshd condrestart > /dev/null 2>&1 || :
%preun server
if [ "$1" = 0 ]
then
/sbin/service sshd stop > /dev/null 2>&1 || :
/sbin/chkconfig --del sshd
fi
%files
%defattr(-,root,root)
%doc CREDITS ChangeLog INSTALL LICENCE OVERVIEW README* PROTOCOL* TODO
%attr(0755,root,root) %{_bindir}/scp
%attr(0644,root,root) %{_mandir}/man1/scp.1*
%attr(0755,root,root) %dir %{_sysconfdir}/ssh
%attr(0600,root,root) %config(noreplace) %{_sysconfdir}/ssh/moduli
%if ! %{rescue}
%attr(0755,root,root) %{_bindir}/ssh-keygen
%attr(0644,root,root) %{_mandir}/man1/ssh-keygen.1*
%attr(0755,root,root) %dir %{_libexecdir}/openssh
%attr(4711,root,root) %{_libexecdir}/openssh/ssh-keysign
%attr(0755,root,root) %{_libexecdir}/openssh/ssh-pkcs11-helper
%attr(0755,root,root) %{_libexecdir}/openssh/ssh-sk-helper
%attr(0644,root,root) %{_mandir}/man8/ssh-keysign.8*
%attr(0644,root,root) %{_mandir}/man8/ssh-pkcs11-helper.8*
%attr(0644,root,root) %{_mandir}/man8/ssh-sk-helper.8*
%endif
%if %{scard}
%attr(0755,root,root) %dir %{_datadir}/openssh
%attr(0644,root,root) %{_datadir}/openssh/Ssh.bin
%endif
%files clients
%defattr(-,root,root)
%attr(0755,root,root) %{_bindir}/ssh
%attr(0644,root,root) %{_mandir}/man1/ssh.1*
%attr(0644,root,root) %{_mandir}/man5/ssh_config.5*
%attr(0644,root,root) %config(noreplace) %{_sysconfdir}/ssh/ssh_config
%if ! %{rescue}
%attr(2755,root,nobody) %{_bindir}/ssh-agent
%attr(0755,root,root) %{_bindir}/ssh-add
%attr(0755,root,root) %{_bindir}/ssh-keyscan
%attr(0755,root,root) %{_bindir}/sftp
%attr(0644,root,root) %{_mandir}/man1/ssh-agent.1*
%attr(0644,root,root) %{_mandir}/man1/ssh-add.1*
%attr(0644,root,root) %{_mandir}/man1/ssh-keyscan.1*
%attr(0644,root,root) %{_mandir}/man1/sftp.1*
%endif
%if ! %{rescue}
%files server
%defattr(-,root,root)
%dir %attr(0111,root,root) %{_var}/empty/sshd
%attr(0755,root,root) %{_sbindir}/sshd
%attr(0755,root,root) %{_libexecdir}/openssh/sftp-server
%attr(0644,root,root) %{_mandir}/man8/sshd.8*
%attr(0644,root,root) %{_mandir}/man5/moduli.5*
%attr(0644,root,root) %{_mandir}/man5/sshd_config.5*
%attr(0644,root,root) %{_mandir}/man8/sftp-server.8*
%attr(0755,root,root) %dir %{_sysconfdir}/ssh
%attr(0600,root,root) %config(noreplace) %{_sysconfdir}/ssh/sshd_config
%attr(0600,root,root) %config(noreplace) /etc/pam.d/sshd
%attr(0755,root,root) %config /etc/rc.d/init.d/sshd
%endif
%if ! %{no_x11_askpass}
%files askpass
%defattr(-,root,root)
%doc x11-ssh-askpass-%{aversion}/README
%doc x11-ssh-askpass-%{aversion}/ChangeLog
%doc x11-ssh-askpass-%{aversion}/SshAskpass*.ad
%{_libexecdir}/openssh/ssh-askpass
%attr(0755,root,root) %{_libexecdir}/openssh/x11-ssh-askpass
%endif
%if ! %{no_gnome_askpass}
%files askpass-gnome
%defattr(-,root,root)
%attr(0755,root,root) %config %{_sysconfdir}/profile.d/gnome-ssh-askpass.*
%attr(0755,root,root) %{_libexecdir}/openssh/gnome-ssh-askpass
%endif
%changelog
* Thu Oct 28 2021 Damien Miller <djm@mindrot.org>
- Remove remaining traces of --with-md5-passwords
* Mon Jul 20 2020 Damien Miller <djm@mindrot.org>
- Add ssh-sk-helper and corresponding manual page.
* Sat Feb 10 2018 Darren Tucker <dtucker@dtucker.net>
- Update openssl-devel dependency to match current requirements.
- Handle Fedora >=6 openssl 1.0 compat libs.
- Remove SSH1 from description.
- Don't strip binaries at build time so that debuginfo package can be
created.
* Sun Nov 16 2014 Nico Kadel-Garcia <nakdel@gmail.com>
- Add '--mandir' and '--with-mantype' for RHEL 5 compatibility
- Add 'dist' option to 'ver' so package names reflect OS at build time
- Always include x11-ssh-askpass tarball in SRPM
- Add openssh-x11-aspass BuildRequires for libXT-devel, imake, gtk2-devel
- Discard 'K5DIR' reporting, not usable inside 'mock' for RHEL 5 compatibility
- Discard obsolete '--with-rsh' configure option
- Update openssl-devel dependency to 0.9.8f, as found in autoconf
* Wed Jul 14 2010 Tim Rice <tim@multitalents.net>
- test for skip_x11_askpass (line 77) should have been for no_x11_askpass
* Mon Jun 2 2003 Damien Miller <djm@mindrot.org>
- Remove noip6 option. This may be controlled at run-time in client config
file using new AddressFamily directive
* Mon May 12 2003 Damien Miller <djm@mindrot.org>
- Don't install profile.d scripts when not building with GNOME/GTK askpass
(patch from bet@rahul.net)
* Tue Oct 01 2002 Damien Miller <djm@mindrot.org>
- Install ssh-agent setgid nobody to prevent ptrace() key theft attacks
* Mon Sep 30 2002 Damien Miller <djm@mindrot.org>
- Use contrib/ Makefile for building askpass programs
* Fri Jun 21 2002 Damien Miller <djm@mindrot.org>
- Merge in spec changes from seba@iq.pl (Sebastian Pachuta)
- Add new {ssh,sshd}_config.5 manpages
- Add new ssh-keysign program and remove setuid from ssh client
* Fri May 10 2002 Damien Miller <djm@mindrot.org>
- Merge in spec changes from RedHat, reorgansie a little
- Add Privsep user, group and directory
* Thu Mar 7 2002 Nalin Dahyabhai <nalin@redhat.com> 3.1p1-2
- bump and grind (through the build system)
* Thu Mar 7 2002 Nalin Dahyabhai <nalin@redhat.com> 3.1p1-1
- require sharutils for building (mindrot #137)
- require db1-devel only when building for 6.x (#55105), which probably won't
work anyway (3.1 requires OpenSSL 0.9.6 to build), but what the heck
- require pam-devel by file (not by package name) again
- add Markus's patch to compile with OpenSSL 0.9.5a (from
http://bugzilla.mindrot.org/show_bug.cgi?id=141) and apply it if we're
building for 6.x
* Thu Mar 7 2002 Nalin Dahyabhai <nalin@redhat.com> 3.1p1-0
- update to 3.1p1
* Tue Mar 5 2002 Nalin Dahyabhai <nalin@redhat.com> SNAP-20020305
- update to SNAP-20020305
- drop debug patch, fixed upstream
* Wed Feb 20 2002 Nalin Dahyabhai <nalin@redhat.com> SNAP-20020220
- update to SNAP-20020220 for testing purposes (you've been warned, if there's
anything to be warned about, gss patches won't apply, I don't mind)
* Wed Feb 13 2002 Nalin Dahyabhai <nalin@redhat.com> 3.0.2p1-3
- add patches from Simon Wilkinson and Nicolas Williams for GSSAPI key
exchange, authentication, and named key support
* Wed Jan 23 2002 Nalin Dahyabhai <nalin@redhat.com> 3.0.2p1-2
- remove dependency on db1-devel, which has just been swallowed up whole
by gnome-libs-devel
* Sat Dec 29 2001 Nalin Dahyabhai <nalin@redhat.com>
- adjust build dependencies so that build6x actually works right (fix
from Hugo van der Kooij)
* Tue Dec 4 2001 Nalin Dahyabhai <nalin@redhat.com> 3.0.2p1-1
- update to 3.0.2p1
* Fri Nov 16 2001 Nalin Dahyabhai <nalin@redhat.com> 3.0.1p1-1
- update to 3.0.1p1
* Tue Nov 13 2001 Nalin Dahyabhai <nalin@redhat.com>
- update to current CVS (not for use in distribution)
* Thu Nov 8 2001 Nalin Dahyabhai <nalin@redhat.com> 3.0p1-1
- merge some of Damien Miller <djm@mindrot.org> changes from the upstream
3.0p1 spec file and init script
* Wed Nov 7 2001 Nalin Dahyabhai <nalin@redhat.com>
- update to 3.0p1
- update to x11-ssh-askpass 1.2.4.1
- change build dependency on a file from pam-devel to the pam-devel package
- replace primes with moduli
* Thu Sep 27 2001 Nalin Dahyabhai <nalin@redhat.com> 2.9p2-9
- incorporate fix from Markus Friedl's advisory for IP-based authorization bugs
* Thu Sep 13 2001 Bernhard Rosenkraenzer <bero@redhat.com> 2.9p2-8
- Merge changes to rescue build from current sysadmin survival cd
* Thu Sep 6 2001 Nalin Dahyabhai <nalin@redhat.com> 2.9p2-7
- fix scp's server's reporting of file sizes, and build with the proper
preprocessor define to get large-file capable open(), stat(), etc.
(sftp has been doing this correctly all along) (#51827)
- configure without --with-ipv4-default on RHL 7.x and newer (#45987,#52247)
- pull cvs patch to fix support for /etc/nologin for non-PAM logins (#47298)
- mark profile.d scriptlets as config files (#42337)
- refer to Jason Stone's mail for zsh workaround for exit-hanging quasi-bug
- change a couple of log() statements to debug() statements (#50751)
- pull cvs patch to add -t flag to sshd (#28611)
- clear fd_sets correctly (one bit per FD, not one byte per FD) (#43221)
* Mon Aug 20 2001 Nalin Dahyabhai <nalin@redhat.com> 2.9p2-6
- add db1-devel as a BuildPrerequisite (noted by Hans Ecke)
* Thu Aug 16 2001 Nalin Dahyabhai <nalin@redhat.com>
- pull cvs patch to fix remote port forwarding with protocol 2
* Thu Aug 9 2001 Nalin Dahyabhai <nalin@redhat.com>
- pull cvs patch to add session initialization to no-pty sessions
- pull cvs patch to not cut off challengeresponse auth needlessly
- refuse to do X11 forwarding if xauth isn't there, handy if you enable
it by default on a system that doesn't have X installed (#49263)
* Wed Aug 8 2001 Nalin Dahyabhai <nalin@redhat.com>
- don't apply patches to code we don't intend to build (spotted by Matt Galgoci)
* Mon Aug 6 2001 Nalin Dahyabhai <nalin@redhat.com>
- pass OPTIONS correctly to initlog (#50151)
* Wed Jul 25 2001 Nalin Dahyabhai <nalin@redhat.com>
- switch to x11-ssh-askpass 1.2.2
* Wed Jul 11 2001 Nalin Dahyabhai <nalin@redhat.com>
- rebuild in new environment
* Mon Jun 25 2001 Nalin Dahyabhai <nalin@redhat.com>
- disable the gssapi patch
* Mon Jun 18 2001 Nalin Dahyabhai <nalin@redhat.com>
- update to 2.9p2
- refresh to a new version of the gssapi patch
* Thu Jun 7 2001 Nalin Dahyabhai <nalin@redhat.com>
- change Copyright: BSD to License: BSD
- add Markus Friedl's unverified patch for the cookie file deletion problem
so that we can verify it
- drop patch to check if xauth is present (was folded into cookie patch)
- don't apply gssapi patches for the errata candidate
- clear supplemental groups list at startup
* Fri May 25 2001 Nalin Dahyabhai <nalin@redhat.com>
- fix an error parsing the new default sshd_config
- add a fix from Markus Friedl (via openssh-unix-dev) for ssh-keygen not
dealing with comments right
* Thu May 24 2001 Nalin Dahyabhai <nalin@redhat.com>
- add in Simon Wilkinson's GSSAPI patch to give it some testing in-house,
to be removed before the next beta cycle because it's a big departure
from the upstream version
* Thu May 3 2001 Nalin Dahyabhai <nalin@redhat.com>
- finish marking strings in the init script for translation
- modify init script to source /etc/sysconfig/sshd and pass $OPTIONS to sshd
at startup (change merged from openssh.com init script, originally by
Pekka Savola)
- refuse to do X11 forwarding if xauth isn't there, handy if you enable
it by default on a system that doesn't have X installed
* Wed May 2 2001 Nalin Dahyabhai <nalin@redhat.com>
- update to 2.9
- drop various patches that came from or went upstream or to or from CVS
* Wed Apr 18 2001 Nalin Dahyabhai <nalin@redhat.com>
- only require initscripts 5.00 on 6.2 (reported by Peter Bieringer)
* Sun Apr 8 2001 Preston Brown <pbrown@redhat.com>
- remove explicit openssl requirement, fixes builddistro issue
- make initscript stop() function wait until sshd really dead to avoid
races in condrestart
* Mon Apr 2 2001 Nalin Dahyabhai <nalin@redhat.com>
- mention that challengereponse supports PAM, so disabling password doesn't
limit users to pubkey and rsa auth (#34378)
- bypass the daemon() function in the init script and call initlog directly,
because daemon() won't start a daemon it detects is already running (like
open connections)
- require the version of openssl we had when we were built
* Fri Mar 23 2001 Nalin Dahyabhai <nalin@redhat.com>
- make do_pam_setcred() smart enough to know when to establish creds and
when to reinitialize them
- add in a couple of other fixes from Damien for inclusion in the errata
* Thu Mar 22 2001 Nalin Dahyabhai <nalin@redhat.com>
- update to 2.5.2p2
- call setcred() again after initgroups, because the "creds" could actually
be group memberships
* Tue Mar 20 2001 Nalin Dahyabhai <nalin@redhat.com>
- update to 2.5.2p1 (includes endianness fixes in the rijndael implementation)
- don't enable challenge-response by default until we find a way to not
have too many userauth requests (we may make up to six pubkey and up to
three password attempts as it is)
- remove build dependency on rsh to match openssh.com's packages more closely
* Sat Mar 3 2001 Nalin Dahyabhai <nalin@redhat.com>
- remove dependency on openssl -- would need to be too precise
* Fri Mar 2 2001 Nalin Dahyabhai <nalin@redhat.com>
- rebuild in new environment
* Mon Feb 26 2001 Nalin Dahyabhai <nalin@redhat.com>
- Revert the patch to move pam_open_session.
- Init script and spec file changes from Pekka Savola. (#28750)
- Patch sftp to recognize '-o protocol' arguments. (#29540)
* Thu Feb 22 2001 Nalin Dahyabhai <nalin@redhat.com>
- Chuck the closing patch.
- Add a trigger to add host keys for protocol 2 to the config file, now that
configuration file syntax requires us to specify it with HostKey if we
specify any other HostKey values, which we do.
* Tue Feb 20 2001 Nalin Dahyabhai <nalin@redhat.com>
- Redo patch to move pam_open_session after the server setuid()s to the user.
- Rework the nopam patch to use be picked up by autoconf.
* Mon Feb 19 2001 Nalin Dahyabhai <nalin@redhat.com>
- Update for 2.5.1p1.
- Add init script mods from Pekka Savola.
- Tweak the init script to match the CVS contrib script more closely.
- Redo patch to ssh-add to try to adding both identity and id_dsa to also try
adding id_rsa.
* Fri Feb 16 2001 Nalin Dahyabhai <nalin@redhat.com>
- Update for 2.5.0p1.
- Use $RPM_OPT_FLAGS instead of -O when building gnome-ssh-askpass
- Resync with parts of Damien Miller's openssh.spec from CVS, including
update of x11 askpass to 1.2.0.
- Only require openssl (don't prereq) because we generate keys in the init
script now.
* Tue Feb 13 2001 Nalin Dahyabhai <nalin@redhat.com>
- Don't open a PAM session until we've forked and become the user (#25690).
- Apply Andrew Bartlett's patch for letting pam_authenticate() know which
host the user is attempting a login from.
- Resync with parts of Damien Miller's openssh.spec from CVS.
- Don't expose KbdInt responses in debug messages (from CVS).
- Detect and handle errors in rsa_{public,private}_decrypt (from CVS).
* Wed Feb 7 2001 Trond Eivind Glomsrxd <teg@redhat.com>
- i18n-tweak to initscript.
* Tue Jan 23 2001 Nalin Dahyabhai <nalin@redhat.com>
- More gettextizing.
- Close all files after going into daemon mode (needs more testing).
- Extract patch from CVS to handle auth banners (in the client).
- Extract patch from CVS to handle compat weirdness.
* Fri Jan 19 2001 Nalin Dahyabhai <nalin@redhat.com>
- Finish with the gettextizing.
* Thu Jan 18 2001 Nalin Dahyabhai <nalin@redhat.com>
- Fix a bug in auth2-pam.c (#23877)
- Gettextize the init script.
* Wed Dec 20 2000 Nalin Dahyabhai <nalin@redhat.com>
- Incorporate a switch for using PAM configs for 6.x, just in case.
* Tue Dec 5 2000 Nalin Dahyabhai <nalin@redhat.com>
- Incorporate Bero's changes for a build specifically for rescue CDs.
* Wed Nov 29 2000 Nalin Dahyabhai <nalin@redhat.com>
- Don't treat pam_setcred() failure as fatal unless pam_authenticate() has
succeeded, to allow public-key authentication after a failure with "none"
authentication. (#21268)
* Tue Nov 28 2000 Nalin Dahyabhai <nalin@redhat.com>
- Update to x11-askpass 1.1.1. (#21301)
- Don't second-guess fixpaths, which causes paths to get fixed twice. (#21290)
* Mon Nov 27 2000 Nalin Dahyabhai <nalin@redhat.com>
- Merge multiple PAM text messages into subsequent prompts when possible when
doing keyboard-interactive authentication.
* Sun Nov 26 2000 Nalin Dahyabhai <nalin@redhat.com>
- Disable the built-in MD5 password support. We're using PAM.
- Take a crack at doing keyboard-interactive authentication with PAM, and
enable use of it in the default client configuration so that the client
will try it when the server disallows password authentication.
- Build with debugging flags. Build root policies strip all binaries anyway.
* Tue Nov 21 2000 Nalin Dahyabhai <nalin@redhat.com>
- Use DESTDIR instead of %%makeinstall.
- Remove /usr/X11R6/bin from the path-fixing patch.
* Mon Nov 20 2000 Nalin Dahyabhai <nalin@redhat.com>
- Add the primes file from the latest snapshot to the main package (#20884).
- Add the dev package to the prereq list (#19984).
- Remove the default path and mimic login's behavior in the server itself.
* Fri Nov 17 2000 Nalin Dahyabhai <nalin@redhat.com>
- Resync with conditional options in Damien Miller's .spec file for an errata.
- Change libexecdir from %%{_libexecdir}/ssh to %%{_libexecdir}/openssh.
* Tue Nov 7 2000 Nalin Dahyabhai <nalin@redhat.com>
- Update to OpenSSH 2.3.0p1.
- Update to x11-askpass 1.1.0.
- Enable keyboard-interactive authentication.
* Mon Oct 30 2000 Nalin Dahyabhai <nalin@redhat.com>
- Update to ssh-askpass-x11 1.0.3.
- Change authentication related messages to be private (#19966).
* Tue Oct 10 2000 Nalin Dahyabhai <nalin@redhat.com>
- Patch ssh-keygen to be able to list signatures for DSA public key files
it generates.
* Thu Oct 5 2000 Nalin Dahyabhai <nalin@redhat.com>
- Add BuildRequires on /usr/include/security/pam_appl.h to be sure we always
build PAM authentication in.
- Try setting SSH_ASKPASS if gnome-ssh-askpass is installed.
- Clean out no-longer-used patches.
- Patch ssh-add to try to add both identity and id_dsa, and to error only
when neither exists.
* Mon Oct 2 2000 Nalin Dahyabhai <nalin@redhat.com>
- Update x11-askpass to 1.0.2. (#17835)
- Add BuildRequiress for /bin/login and /usr/bin/rsh so that configure will
always find them in the right place. (#17909)
- Set the default path to be the same as the one supplied by /bin/login, but
add /usr/X11R6/bin. (#17909)
- Try to handle obsoletion of ssh-server more cleanly. Package names
are different, but init script name isn't. (#17865)
* Wed Sep 6 2000 Nalin Dahyabhai <nalin@redhat.com>
- Update to 2.2.0p1. (#17835)
- Tweak the init script to allow proper restarting. (#18023)
* Wed Aug 23 2000 Nalin Dahyabhai <nalin@redhat.com>
- Update to 20000823 snapshot.
- Change subpackage requirements from %%{version} to %%{version}-%%{release}
- Back out the pipe patch.
* Mon Jul 17 2000 Nalin Dahyabhai <nalin@redhat.com>
- Update to 2.1.1p4, which includes fixes for config file parsing problems.
- Move the init script back.
- Add Damien's quick fix for wackiness.
* Wed Jul 12 2000 Nalin Dahyabhai <nalin@redhat.com>
- Update to 2.1.1p3, which includes fixes for X11 forwarding and strtok().
* Thu Jul 6 2000 Nalin Dahyabhai <nalin@redhat.com>
- Move condrestart to server postun.
- Move key generation to init script.
- Actually use the right patch for moving the key generation to the init script.
- Clean up the init script a bit.
* Wed Jul 5 2000 Nalin Dahyabhai <nalin@redhat.com>
- Fix X11 forwarding, from mail post by Chan Shih-Ping Richard.
* Sun Jul 2 2000 Nalin Dahyabhai <nalin@redhat.com>
- Update to 2.1.1p2.
- Use of strtok() considered harmful.
* Sat Jul 1 2000 Nalin Dahyabhai <nalin@redhat.com>
- Get the build root out of the man pages.
* Thu Jun 29 2000 Nalin Dahyabhai <nalin@redhat.com>
- Add and use condrestart support in the init script.
- Add newer initscripts as a prereq.
* Tue Jun 27 2000 Nalin Dahyabhai <nalin@redhat.com>
- Build in new environment (release 2)
- Move -clients subpackage to Applications/Internet group
* Fri Jun 9 2000 Nalin Dahyabhai <nalin@redhat.com>
- Update to 2.2.1p1
* Sat Jun 3 2000 Nalin Dahyabhai <nalin@redhat.com>
- Patch to build with neither RSA nor RSAref.
- Miscellaneous FHS-compliance tweaks.
- Fix for possibly-compressed man pages.
* Wed Mar 15 2000 Damien Miller <djm@ibs.com.au>
- Updated for new location
- Updated for new gnome-ssh-askpass build
* Sun Dec 26 1999 Damien Miller <djm@mindrot.org>
- Added Jim Knoble's <jmknoble@pobox.com> askpass
* Mon Nov 15 1999 Damien Miller <djm@mindrot.org>
- Split subpackages further based on patch from jim knoble <jmknoble@pobox.com>
* Sat Nov 13 1999 Damien Miller <djm@mindrot.org>
- Added 'Obsoletes' directives
* Tue Nov 09 1999 Damien Miller <djm@ibs.com.au>
- Use make install
- Subpackages
* Mon Nov 08 1999 Damien Miller <djm@ibs.com.au>
- Added links for slogin
- Fixed perms on manpages
* Sat Oct 30 1999 Damien Miller <djm@ibs.com.au>
- Renamed init script
* Fri Oct 29 1999 Damien Miller <djm@ibs.com.au>
- Back to old binary names
* Thu Oct 28 1999 Damien Miller <djm@ibs.com.au>
- Use autoconf
- New binary names
* Wed Oct 27 1999 Damien Miller <djm@ibs.com.au>
- Initial RPMification, based on Jan "Yenya" Kasprzak's <kas@fi.muni.cz> spec.
diff --git a/crypto/openssh/contrib/suse/openssh.spec b/crypto/openssh/contrib/suse/openssh.spec
index 32bd8c189b87..e533ed542ce1 100644
--- a/crypto/openssh/contrib/suse/openssh.spec
+++ b/crypto/openssh/contrib/suse/openssh.spec
@@ -1,245 +1,245 @@
# Default values for additional components
%define build_x11_askpass 1
# Define the UID/GID to use for privilege separation
%define sshd_gid 65
%define sshd_uid 71
# The version of x11-ssh-askpass to use
%define xversion 1.2.4.1
# Allow the ability to override defaults with -D skip_xxx=1
%{?skip_x11_askpass:%define build_x11_askpass 0}
Summary: OpenSSH, a free Secure Shell (SSH) protocol implementation
Name: openssh
-Version: 9.1p1
+Version: 9.2p1
URL: https://www.openssh.com/
Release: 1
Source0: openssh-%{version}.tar.gz
Source1: x11-ssh-askpass-%{xversion}.tar.gz
License: BSD
Group: Productivity/Networking/SSH
BuildRoot: %{_tmppath}/openssh-%{version}-buildroot
PreReq: openssl
Obsoletes: ssh
Provides: ssh
#
# (Build[ing] Prereq[uisites] only work for RPM 2.95 and newer.)
# building prerequisites -- stuff for
# OpenSSL (openssl-devel),
# and Gnome (glibdev, gtkdev, and gnlibsd)
#
BuildPrereq: openssl
BuildPrereq: zlib-devel
#BuildPrereq: glibdev
#BuildPrereq: gtkdev
#BuildPrereq: gnlibsd
%package askpass
Summary: A passphrase dialog for OpenSSH and the X window System.
Group: Productivity/Networking/SSH
Requires: openssh = %{version}
Obsoletes: ssh-extras
Provides: openssh:${_libdir}/ssh/ssh-askpass
%if %{build_x11_askpass}
BuildPrereq: XFree86-devel
%endif
%description
Ssh (Secure Shell) is a program for logging into a remote machine and for
executing commands in a remote machine. It is intended to replace
rlogin and rsh, and provide secure encrypted communications between
two untrusted hosts over an insecure network. X11 connections and
arbitrary TCP/IP ports can also be forwarded over the secure channel.
OpenSSH is OpenBSD's rework of the last free version of SSH, bringing it
up to date in terms of security and features, as well as removing all
patented algorithms to separate libraries (OpenSSL).
This package includes all files necessary for both the OpenSSH
client and server.
%description askpass
Ssh (Secure Shell) is a program for logging into a remote machine and for
executing commands in a remote machine. It is intended to replace
rlogin and rsh, and provide secure encrypted communications between
two untrusted hosts over an insecure network. X11 connections and
arbitrary TCP/IP ports can also be forwarded over the secure channel.
OpenSSH is OpenBSD's rework of the last free version of SSH, bringing it
up to date in terms of security and features, as well as removing all
patented algorithms to separate libraries (OpenSSL).
This package contains an X Window System passphrase dialog for OpenSSH.
%changelog
* Mon Jul 20 2020 Damien Miller <djm@mindrto.org>
- Add ssh-sk-helper and corresponding manual page.
* Wed Oct 26 2005 Iain Morgan <imorgan@nas.nasa.gov>
- Removed accidental inclusion of --without-zlib-version-check
* Tue Oct 25 2005 Iain Morgan <imorgan@nas.nasa.gov>
- Overhaul to deal with newer versions of SuSE and OpenSSH
* Mon Jun 12 2000 Damien Miller <djm@mindrot.org>
- Glob manpages to catch compressed files
* Wed Mar 15 2000 Damien Miller <djm@ibs.com.au>
- Updated for new location
- Updated for new gnome-ssh-askpass build
* Sun Dec 26 1999 Chris Saia <csaia@wtower.com>
- Made symlink to gnome-ssh-askpass called ssh-askpass
* Wed Nov 24 1999 Chris Saia <csaia@wtower.com>
- Removed patches that included /etc/pam.d/sshd, /sbin/init.d/rc.sshd, and
/var/adm/fillup-templates/rc.config.sshd, since Damien merged these into
his released tarfile
- Changed permissions on ssh_config in the install procedure to 644 from 600
even though it was correct in the %files section and thus right in the RPMs
- Postinstall script for the server now only prints "Generating SSH host
key..." if we need to actually do this, in order to eliminate a confusing
message if an SSH host key is already in place
- Marked all manual pages as %doc(umentation)
* Mon Nov 22 1999 Chris Saia <csaia@wtower.com>
- Added flag to configure daemon with TCP Wrappers support
- Added building prerequisites (works in RPM 3.0 and newer)
* Thu Nov 18 1999 Chris Saia <csaia@wtower.com>
- Made this package correct for SuSE.
- Changed instances of pam_pwdb.so to pam_unix.so, since it works more properly
with SuSE, and lib_pwdb.so isn't installed by default.
* Mon Nov 15 1999 Damien Miller <djm@mindrot.org>
- Split subpackages further based on patch from jim knoble <jmknoble@pobox.com>
* Sat Nov 13 1999 Damien Miller <djm@mindrot.org>
- Added 'Obsoletes' directives
* Tue Nov 09 1999 Damien Miller <djm@ibs.com.au>
- Use make install
- Subpackages
* Mon Nov 08 1999 Damien Miller <djm@ibs.com.au>
- Added links for slogin
- Fixed perms on manpages
* Sat Oct 30 1999 Damien Miller <djm@ibs.com.au>
- Renamed init script
* Fri Oct 29 1999 Damien Miller <djm@ibs.com.au>
- Back to old binary names
* Thu Oct 28 1999 Damien Miller <djm@ibs.com.au>
- Use autoconf
- New binary names
* Wed Oct 27 1999 Damien Miller <djm@ibs.com.au>
- Initial RPMification, based on Jan "Yenya" Kasprzak's <kas@fi.muni.cz> spec.
%prep
%if %{build_x11_askpass}
%setup -q -a 1
%else
%setup -q
%endif
%build
CFLAGS="$RPM_OPT_FLAGS" \
%configure --prefix=/usr \
--sysconfdir=%{_sysconfdir}/ssh \
--mandir=%{_mandir} \
--with-privsep-path=/var/lib/empty \
--with-pam \
--libexecdir=%{_libdir}/ssh
make
%if %{build_x11_askpass}
cd x11-ssh-askpass-%{xversion}
%configure --mandir=/usr/X11R6/man \
--libexecdir=%{_libdir}/ssh
xmkmf -a
make
cd ..
%endif
%install
rm -rf $RPM_BUILD_ROOT
make install DESTDIR=$RPM_BUILD_ROOT/
install -d $RPM_BUILD_ROOT/etc/pam.d/
install -d $RPM_BUILD_ROOT/etc/init.d/
install -d $RPM_BUILD_ROOT/var/adm/fillup-templates
install -m644 contrib/sshd.pam.generic $RPM_BUILD_ROOT/etc/pam.d/sshd
install -m744 contrib/suse/rc.sshd $RPM_BUILD_ROOT/etc/init.d/sshd
install -m744 contrib/suse/sysconfig.ssh \
$RPM_BUILD_ROOT/var/adm/fillup-templates
%if %{build_x11_askpass}
cd x11-ssh-askpass-%{xversion}
make install install.man BINDIR=%{_libdir}/ssh DESTDIR=$RPM_BUILD_ROOT/
rm -f $RPM_BUILD_ROOT/usr/share/Ssh.bin
%endif
%clean
rm -rf $RPM_BUILD_ROOT
%pre
/usr/sbin/groupadd -g %{sshd_gid} -o -r sshd 2> /dev/null || :
/usr/sbin/useradd -r -o -g sshd -u %{sshd_uid} -s /bin/false -c "SSH Privilege Separation User" -d /var/lib/sshd sshd 2> /dev/null || :
%post
/usr/bin/ssh-keygen -A
%{fillup_and_insserv -n -y ssh sshd}
%run_permissions
%verifyscript
%verify_permissions -e /etc/ssh/sshd_config -e /etc/ssh/ssh_config -e /usr/bin/ssh
%preun
%stop_on_removal sshd
%postun
%restart_on_update sshd
%{insserv_cleanup}
%files
%defattr(-,root,root)
%doc ChangeLog OVERVIEW README* PROTOCOL*
%doc TODO CREDITS LICENCE
%attr(0755,root,root) %dir %{_sysconfdir}/ssh
%attr(0644,root,root) %config(noreplace) %{_sysconfdir}/ssh/ssh_config
%attr(0600,root,root) %config(noreplace) %{_sysconfdir}/ssh/sshd_config
%attr(0600,root,root) %config(noreplace) %{_sysconfdir}/ssh/moduli
%attr(0644,root,root) %config(noreplace) /etc/pam.d/sshd
%attr(0755,root,root) %config /etc/init.d/sshd
%attr(0755,root,root) %{_bindir}/ssh-keygen
%attr(0755,root,root) %{_bindir}/scp
%attr(0755,root,root) %{_bindir}/ssh
%attr(0755,root,root) %{_bindir}/ssh-agent
%attr(0755,root,root) %{_bindir}/ssh-add
%attr(0755,root,root) %{_bindir}/ssh-keyscan
%attr(0755,root,root) %{_bindir}/sftp
%attr(0755,root,root) %{_sbindir}/sshd
%attr(0755,root,root) %dir %{_libdir}/ssh
%attr(0755,root,root) %{_libdir}/ssh/sftp-server
%attr(4711,root,root) %{_libdir}/ssh/ssh-keysign
%attr(0755,root,root) %{_libdir}/ssh/ssh-pkcs11-helper
%attr(0755,root,root) %{_libdir}/ssh/ssh-sk-helper
%attr(0644,root,root) %doc %{_mandir}/man1/scp.1*
%attr(0644,root,root) %doc %{_mandir}/man1/sftp.1*
%attr(0644,root,root) %doc %{_mandir}/man1/ssh.1*
%attr(0644,root,root) %doc %{_mandir}/man1/ssh-add.1*
%attr(0644,root,root) %doc %{_mandir}/man1/ssh-agent.1*
%attr(0644,root,root) %doc %{_mandir}/man1/ssh-keygen.1*
%attr(0644,root,root) %doc %{_mandir}/man1/ssh-keyscan.1*
%attr(0644,root,root) %doc %{_mandir}/man5/moduli.5*
%attr(0644,root,root) %doc %{_mandir}/man5/ssh_config.5*
%attr(0644,root,root) %doc %{_mandir}/man5/sshd_config.5*
%attr(0644,root,root) %doc %{_mandir}/man8/sftp-server.8*
%attr(0644,root,root) %doc %{_mandir}/man8/ssh-keysign.8*
%attr(0644,root,root) %doc %{_mandir}/man8/ssh-pkcs11-helper.8*
%attr(0644,root,root) %doc %{_mandir}/man8/ssh-sk-helper.8*
%attr(0644,root,root) %doc %{_mandir}/man8/sshd.8*
%attr(0644,root,root) /var/adm/fillup-templates/sysconfig.ssh
%if %{build_x11_askpass}
%files askpass
%defattr(-,root,root)
%doc x11-ssh-askpass-%{xversion}/README
%doc x11-ssh-askpass-%{xversion}/ChangeLog
%doc x11-ssh-askpass-%{xversion}/SshAskpass*.ad
%attr(0755,root,root) %{_libdir}/ssh/ssh-askpass
%attr(0755,root,root) %{_libdir}/ssh/x11-ssh-askpass
%attr(0644,root,root) %doc /usr/X11R6/man/man1/ssh-askpass.1x*
%attr(0644,root,root) %doc /usr/X11R6/man/man1/x11-ssh-askpass.1x*
%attr(0644,root,root) %config /usr/X11R6/lib/X11/app-defaults/SshAskpass
%endif
diff --git a/crypto/openssh/crypto_api.h b/crypto/openssh/crypto_api.h
index 5c3d97eaa401..5d552ef02370 100644
--- a/crypto/openssh/crypto_api.h
+++ b/crypto/openssh/crypto_api.h
@@ -1,58 +1,56 @@
-/* $OpenBSD: crypto_api.h,v 1.7 2021/01/08 02:33:13 dtucker Exp $ */
+/* $OpenBSD: crypto_api.h,v 1.8 2023/01/15 23:05:32 djm Exp $ */
/*
* Assembled from generated headers and source files by Markus Friedl.
* Placed in the public domain.
*/
#ifndef crypto_api_h
#define crypto_api_h
#include "includes.h"
#ifdef HAVE_STDINT_H
# include <stdint.h>
#endif
#include <stdlib.h>
typedef int8_t crypto_int8;
typedef uint8_t crypto_uint8;
typedef int16_t crypto_int16;
typedef uint16_t crypto_uint16;
typedef int32_t crypto_int32;
typedef uint32_t crypto_uint32;
typedef int64_t crypto_int64;
typedef uint64_t crypto_uint64;
#define randombytes(buf, buf_len) arc4random_buf((buf), (buf_len))
#define small_random32() arc4random()
#define crypto_hash_sha512_BYTES 64U
int crypto_hash_sha512(unsigned char *, const unsigned char *,
unsigned long long);
-int crypto_verify_32(const unsigned char *, const unsigned char *);
-
#define crypto_sign_ed25519_SECRETKEYBYTES 64U
#define crypto_sign_ed25519_PUBLICKEYBYTES 32U
#define crypto_sign_ed25519_BYTES 64U
int crypto_sign_ed25519(unsigned char *, unsigned long long *,
const unsigned char *, unsigned long long, const unsigned char *);
int crypto_sign_ed25519_open(unsigned char *, unsigned long long *,
const unsigned char *, unsigned long long, const unsigned char *);
int crypto_sign_ed25519_keypair(unsigned char *, unsigned char *);
#define crypto_kem_sntrup761_PUBLICKEYBYTES 1158
#define crypto_kem_sntrup761_SECRETKEYBYTES 1763
#define crypto_kem_sntrup761_CIPHERTEXTBYTES 1039
#define crypto_kem_sntrup761_BYTES 32
int crypto_kem_sntrup761_enc(unsigned char *cstr, unsigned char *k,
const unsigned char *pk);
int crypto_kem_sntrup761_dec(unsigned char *k,
const unsigned char *cstr, const unsigned char *sk);
int crypto_kem_sntrup761_keypair(unsigned char *pk, unsigned char *sk);
#endif /* crypto_api_h */
diff --git a/crypto/openssh/ed25519.c b/crypto/openssh/ed25519.c
index 767ec24d6df5..0e167ae1f6bc 100644
--- a/crypto/openssh/ed25519.c
+++ b/crypto/openssh/ed25519.c
@@ -1,144 +1,2030 @@
-/* $OpenBSD: ed25519.c,v 1.3 2013/12/09 11:03:45 markus Exp $ */
+/* $OpenBSD: ed25519.c,v 1.4 2023/01/15 23:05:32 djm Exp $ */
/*
- * Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange,
- * Peter Schwabe, Bo-Yin Yang.
- * Copied from supercop-20130419/crypto_sign/ed25519/ref/ed25519.c
+ * Public Domain, Authors:
+ * - Daniel J. Bernstein
+ * - Niels Duif
+ * - Tanja Lange
+ * - lead: Peter Schwabe
+ * - Bo-Yin Yang
*/
#include "includes.h"
+
+#include <string.h>
+
#include "crypto_api.h"
-#include "ge25519.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-20221122/crypto_verify/32/ref/verify.c */
-static void get_hram(unsigned char *hram, const unsigned char *sm, const unsigned char *pk, unsigned char *playground, unsigned long long smlen)
+static int crypto_verify_32(const unsigned char *x,const unsigned char *y)
{
- unsigned long long i;
+ unsigned int differentbits = 0;
+#define F(i) differentbits |= x[i] ^ y[i];
+ F(0)
+ F(1)
+ F(2)
+ F(3)
+ F(4)
+ F(5)
+ F(6)
+ F(7)
+ F(8)
+ F(9)
+ F(10)
+ F(11)
+ F(12)
+ F(13)
+ F(14)
+ F(15)
+ F(16)
+ F(17)
+ F(18)
+ F(19)
+ F(20)
+ F(21)
+ F(22)
+ F(23)
+ F(24)
+ F(25)
+ F(26)
+ F(27)
+ F(28)
+ F(29)
+ F(30)
+ F(31)
+ return (1 & ((differentbits - 1) >> 8)) - 1;
+}
+/* from supercop-20221122/crypto_sign/ed25519/ref/fe25519.h */
+#ifndef FE25519_H
+#define FE25519_H
+
- for (i = 0;i < 32;++i) playground[i] = sm[i];
- for (i = 32;i < 64;++i) playground[i] = pk[i-32];
- for (i = 64;i < smlen;++i) playground[i] = sm[i];
+#define fe25519 crypto_sign_ed25519_ref_fe25519
+#define fe25519_freeze crypto_sign_ed25519_ref_fe25519_freeze
+#define fe25519_unpack crypto_sign_ed25519_ref_fe25519_unpack
+#define fe25519_pack crypto_sign_ed25519_ref_fe25519_pack
+#define fe25519_iszero crypto_sign_ed25519_ref_fe25519_iszero
+#define fe25519_iseq_vartime crypto_sign_ed25519_ref_fe25519_iseq_vartime
+#define fe25519_cmov crypto_sign_ed25519_ref_fe25519_cmov
+#define fe25519_setone crypto_sign_ed25519_ref_fe25519_setone
+#define fe25519_setzero crypto_sign_ed25519_ref_fe25519_setzero
+#define fe25519_neg crypto_sign_ed25519_ref_fe25519_neg
+#define fe25519_getparity crypto_sign_ed25519_ref_fe25519_getparity
+#define fe25519_add crypto_sign_ed25519_ref_fe25519_add
+#define fe25519_sub crypto_sign_ed25519_ref_fe25519_sub
+#define fe25519_mul crypto_sign_ed25519_ref_fe25519_mul
+#define fe25519_square crypto_sign_ed25519_ref_fe25519_square
+#define fe25519_invert crypto_sign_ed25519_ref_fe25519_invert
+#define fe25519_pow2523 crypto_sign_ed25519_ref_fe25519_pow2523
- crypto_hash_sha512(hram,playground,smlen);
+typedef struct
+{
+ crypto_uint32 v[32];
}
+fe25519;
+static void fe25519_freeze(fe25519 *r);
-int crypto_sign_ed25519_keypair(
- unsigned char *pk,
- unsigned char *sk
- )
+static void fe25519_unpack(fe25519 *r, const unsigned char x[32]);
+
+static void fe25519_pack(unsigned char r[32], const fe25519 *x);
+
+static int fe25519_iszero(const fe25519 *x);
+
+static int fe25519_iseq_vartime(const fe25519 *x, const fe25519 *y);
+
+static void fe25519_cmov(fe25519 *r, const fe25519 *x, unsigned char b);
+
+static void fe25519_setone(fe25519 *r);
+
+static void fe25519_setzero(fe25519 *r);
+
+static void fe25519_neg(fe25519 *r, const fe25519 *x);
+
+unsigned char fe25519_getparity(const fe25519 *x);
+
+static void fe25519_add(fe25519 *r, const fe25519 *x, const fe25519 *y);
+
+static void fe25519_sub(fe25519 *r, const fe25519 *x, const fe25519 *y);
+
+static void fe25519_mul(fe25519 *r, const fe25519 *x, const fe25519 *y);
+
+static void fe25519_square(fe25519 *r, const fe25519 *x);
+
+static void fe25519_invert(fe25519 *r, const fe25519 *x);
+
+static void fe25519_pow2523(fe25519 *r, const fe25519 *x);
+
+#endif
+/* from supercop-20221122/crypto_sign/ed25519/ref/fe25519.c */
+#define WINDOWSIZE 1 /* Should be 1,2, or 4 */
+#define WINDOWMASK ((1<<WINDOWSIZE)-1)
+
+
+static crypto_uint32 fe25519_equal(crypto_uint32 a,crypto_uint32 b) /* 16-bit inputs */
+{
+ crypto_uint32 x = a ^ b; /* 0: yes; 1..65535: no */
+ x -= 1; /* 4294967295: yes; 0..65534: no */
+ x >>= 31; /* 1: yes; 0: no */
+ return x;
+}
+
+static crypto_uint32 ge(crypto_uint32 a,crypto_uint32 b) /* 16-bit inputs */
+{
+ unsigned int x = a;
+ x -= (unsigned int) b; /* 0..65535: yes; 4294901761..4294967295: no */
+ x >>= 31; /* 0: yes; 1: no */
+ x ^= 1; /* 1: yes; 0: no */
+ return x;
+}
+
+static crypto_uint32 times19(crypto_uint32 a)
+{
+ return (a << 4) + (a << 1) + a;
+}
+
+static crypto_uint32 times38(crypto_uint32 a)
+{
+ return (a << 5) + (a << 2) + (a << 1);
+}
+
+static void fe25519_reduce_add_sub(fe25519 *r)
{
+ crypto_uint32 t;
+ int i,rep;
+
+ for(rep=0;rep<4;rep++)
+ {
+ t = r->v[31] >> 7;
+ r->v[31] &= 127;
+ t = times19(t);
+ r->v[0] += t;
+ for(i=0;i<31;i++)
+ {
+ t = r->v[i] >> 8;
+ r->v[i+1] += t;
+ r->v[i] &= 255;
+ }
+ }
+}
+
+static void reduce_mul(fe25519 *r)
+{
+ crypto_uint32 t;
+ int i,rep;
+
+ for(rep=0;rep<2;rep++)
+ {
+ t = r->v[31] >> 7;
+ r->v[31] &= 127;
+ t = times19(t);
+ r->v[0] += t;
+ for(i=0;i<31;i++)
+ {
+ t = r->v[i] >> 8;
+ r->v[i+1] += t;
+ r->v[i] &= 255;
+ }
+ }
+}
+
+/* reduction modulo 2^255-19 */
+static void fe25519_freeze(fe25519 *r)
+{
+ int i;
+ crypto_uint32 m = fe25519_equal(r->v[31],127);
+ for(i=30;i>0;i--)
+ m &= fe25519_equal(r->v[i],255);
+ m &= ge(r->v[0],237);
+
+ m = -m;
+
+ r->v[31] -= m&127;
+ for(i=30;i>0;i--)
+ r->v[i] -= m&255;
+ r->v[0] -= m&237;
+}
+
+static void fe25519_unpack(fe25519 *r, const unsigned char x[32])
+{
+ int i;
+ for(i=0;i<32;i++) r->v[i] = x[i];
+ r->v[31] &= 127;
+}
+
+/* Assumes input x being reduced below 2^255 */
+static void fe25519_pack(unsigned char r[32], const fe25519 *x)
+{
+ int i;
+ fe25519 y = *x;
+ fe25519_freeze(&y);
+ for(i=0;i<32;i++)
+ r[i] = y.v[i];
+}
+
+static int fe25519_iszero(const fe25519 *x)
+{
+ int i;
+ int r;
+ fe25519 t = *x;
+ fe25519_freeze(&t);
+ r = fe25519_equal(t.v[0],0);
+ for(i=1;i<32;i++)
+ r &= fe25519_equal(t.v[i],0);
+ return r;
+}
+
+static int fe25519_iseq_vartime(const fe25519 *x, const fe25519 *y)
+{
+ int i;
+ fe25519 t1 = *x;
+ fe25519 t2 = *y;
+ fe25519_freeze(&t1);
+ fe25519_freeze(&t2);
+ for(i=0;i<32;i++)
+ if(t1.v[i] != t2.v[i]) return 0;
+ return 1;
+}
+
+static void fe25519_cmov(fe25519 *r, const fe25519 *x, unsigned char b)
+{
+ int i;
+ crypto_uint32 mask = b;
+ mask = -mask;
+ for(i=0;i<32;i++) r->v[i] ^= mask & (x->v[i] ^ r->v[i]);
+}
+
+unsigned char fe25519_getparity(const fe25519 *x)
+{
+ fe25519 t = *x;
+ fe25519_freeze(&t);
+ return t.v[0] & 1;
+}
+
+static void fe25519_setone(fe25519 *r)
+{
+ int i;
+ r->v[0] = 1;
+ for(i=1;i<32;i++) r->v[i]=0;
+}
+
+static void fe25519_setzero(fe25519 *r)
+{
+ int i;
+ for(i=0;i<32;i++) r->v[i]=0;
+}
+
+static void fe25519_neg(fe25519 *r, const fe25519 *x)
+{
+ fe25519 t;
+ int i;
+ for(i=0;i<32;i++) t.v[i]=x->v[i];
+ fe25519_setzero(r);
+ fe25519_sub(r, r, &t);
+}
+
+static void fe25519_add(fe25519 *r, const fe25519 *x, const fe25519 *y)
+{
+ int i;
+ for(i=0;i<32;i++) r->v[i] = x->v[i] + y->v[i];
+ fe25519_reduce_add_sub(r);
+}
+
+static void fe25519_sub(fe25519 *r, const fe25519 *x, const fe25519 *y)
+{
+ int i;
+ crypto_uint32 t[32];
+ t[0] = x->v[0] + 0x1da;
+ t[31] = x->v[31] + 0xfe;
+ for(i=1;i<31;i++) t[i] = x->v[i] + 0x1fe;
+ for(i=0;i<32;i++) r->v[i] = t[i] - y->v[i];
+ fe25519_reduce_add_sub(r);
+}
+
+static void fe25519_mul(fe25519 *r, const fe25519 *x, const fe25519 *y)
+{
+ int i,j;
+ crypto_uint32 t[63];
+ for(i=0;i<63;i++)t[i] = 0;
+
+ for(i=0;i<32;i++)
+ for(j=0;j<32;j++)
+ t[i+j] += x->v[i] * y->v[j];
+
+ for(i=32;i<63;i++)
+ r->v[i-32] = t[i-32] + times38(t[i]);
+ r->v[31] = t[31]; /* result now in r[0]...r[31] */
+
+ reduce_mul(r);
+}
+
+static void fe25519_square(fe25519 *r, const fe25519 *x)
+{
+ fe25519_mul(r, x, x);
+}
+
+static void fe25519_invert(fe25519 *r, const fe25519 *x)
+{
+ fe25519 z2;
+ fe25519 z9;
+ fe25519 z11;
+ fe25519 z2_5_0;
+ fe25519 z2_10_0;
+ fe25519 z2_20_0;
+ fe25519 z2_50_0;
+ fe25519 z2_100_0;
+ fe25519 t0;
+ fe25519 t1;
+ int i;
+
+ /* 2 */ fe25519_square(&z2,x);
+ /* 4 */ fe25519_square(&t1,&z2);
+ /* 8 */ fe25519_square(&t0,&t1);
+ /* 9 */ fe25519_mul(&z9,&t0,x);
+ /* 11 */ fe25519_mul(&z11,&z9,&z2);
+ /* 22 */ fe25519_square(&t0,&z11);
+ /* 2^5 - 2^0 = 31 */ fe25519_mul(&z2_5_0,&t0,&z9);
+
+ /* 2^6 - 2^1 */ fe25519_square(&t0,&z2_5_0);
+ /* 2^7 - 2^2 */ fe25519_square(&t1,&t0);
+ /* 2^8 - 2^3 */ fe25519_square(&t0,&t1);
+ /* 2^9 - 2^4 */ fe25519_square(&t1,&t0);
+ /* 2^10 - 2^5 */ fe25519_square(&t0,&t1);
+ /* 2^10 - 2^0 */ fe25519_mul(&z2_10_0,&t0,&z2_5_0);
+
+ /* 2^11 - 2^1 */ fe25519_square(&t0,&z2_10_0);
+ /* 2^12 - 2^2 */ fe25519_square(&t1,&t0);
+ /* 2^20 - 2^10 */ for (i = 2;i < 10;i += 2) { fe25519_square(&t0,&t1); fe25519_square(&t1,&t0); }
+ /* 2^20 - 2^0 */ fe25519_mul(&z2_20_0,&t1,&z2_10_0);
+
+ /* 2^21 - 2^1 */ fe25519_square(&t0,&z2_20_0);
+ /* 2^22 - 2^2 */ fe25519_square(&t1,&t0);
+ /* 2^40 - 2^20 */ for (i = 2;i < 20;i += 2) { fe25519_square(&t0,&t1); fe25519_square(&t1,&t0); }
+ /* 2^40 - 2^0 */ fe25519_mul(&t0,&t1,&z2_20_0);
+
+ /* 2^41 - 2^1 */ fe25519_square(&t1,&t0);
+ /* 2^42 - 2^2 */ fe25519_square(&t0,&t1);
+ /* 2^50 - 2^10 */ for (i = 2;i < 10;i += 2) { fe25519_square(&t1,&t0); fe25519_square(&t0,&t1); }
+ /* 2^50 - 2^0 */ fe25519_mul(&z2_50_0,&t0,&z2_10_0);
+
+ /* 2^51 - 2^1 */ fe25519_square(&t0,&z2_50_0);
+ /* 2^52 - 2^2 */ fe25519_square(&t1,&t0);
+ /* 2^100 - 2^50 */ for (i = 2;i < 50;i += 2) { fe25519_square(&t0,&t1); fe25519_square(&t1,&t0); }
+ /* 2^100 - 2^0 */ fe25519_mul(&z2_100_0,&t1,&z2_50_0);
+
+ /* 2^101 - 2^1 */ fe25519_square(&t1,&z2_100_0);
+ /* 2^102 - 2^2 */ fe25519_square(&t0,&t1);
+ /* 2^200 - 2^100 */ for (i = 2;i < 100;i += 2) { fe25519_square(&t1,&t0); fe25519_square(&t0,&t1); }
+ /* 2^200 - 2^0 */ fe25519_mul(&t1,&t0,&z2_100_0);
+
+ /* 2^201 - 2^1 */ fe25519_square(&t0,&t1);
+ /* 2^202 - 2^2 */ fe25519_square(&t1,&t0);
+ /* 2^250 - 2^50 */ for (i = 2;i < 50;i += 2) { fe25519_square(&t0,&t1); fe25519_square(&t1,&t0); }
+ /* 2^250 - 2^0 */ fe25519_mul(&t0,&t1,&z2_50_0);
+
+ /* 2^251 - 2^1 */ fe25519_square(&t1,&t0);
+ /* 2^252 - 2^2 */ fe25519_square(&t0,&t1);
+ /* 2^253 - 2^3 */ fe25519_square(&t1,&t0);
+ /* 2^254 - 2^4 */ fe25519_square(&t0,&t1);
+ /* 2^255 - 2^5 */ fe25519_square(&t1,&t0);
+ /* 2^255 - 21 */ fe25519_mul(r,&t1,&z11);
+}
+
+static void fe25519_pow2523(fe25519 *r, const fe25519 *x)
+{
+ fe25519 z2;
+ fe25519 z9;
+ fe25519 z11;
+ fe25519 z2_5_0;
+ fe25519 z2_10_0;
+ fe25519 z2_20_0;
+ fe25519 z2_50_0;
+ fe25519 z2_100_0;
+ fe25519 t;
+ int i;
+
+ /* 2 */ fe25519_square(&z2,x);
+ /* 4 */ fe25519_square(&t,&z2);
+ /* 8 */ fe25519_square(&t,&t);
+ /* 9 */ fe25519_mul(&z9,&t,x);
+ /* 11 */ fe25519_mul(&z11,&z9,&z2);
+ /* 22 */ fe25519_square(&t,&z11);
+ /* 2^5 - 2^0 = 31 */ fe25519_mul(&z2_5_0,&t,&z9);
+
+ /* 2^6 - 2^1 */ fe25519_square(&t,&z2_5_0);
+ /* 2^10 - 2^5 */ for (i = 1;i < 5;i++) { fe25519_square(&t,&t); }
+ /* 2^10 - 2^0 */ fe25519_mul(&z2_10_0,&t,&z2_5_0);
+
+ /* 2^11 - 2^1 */ fe25519_square(&t,&z2_10_0);
+ /* 2^20 - 2^10 */ for (i = 1;i < 10;i++) { fe25519_square(&t,&t); }
+ /* 2^20 - 2^0 */ fe25519_mul(&z2_20_0,&t,&z2_10_0);
+
+ /* 2^21 - 2^1 */ fe25519_square(&t,&z2_20_0);
+ /* 2^40 - 2^20 */ for (i = 1;i < 20;i++) { fe25519_square(&t,&t); }
+ /* 2^40 - 2^0 */ fe25519_mul(&t,&t,&z2_20_0);
+
+ /* 2^41 - 2^1 */ fe25519_square(&t,&t);
+ /* 2^50 - 2^10 */ for (i = 1;i < 10;i++) { fe25519_square(&t,&t); }
+ /* 2^50 - 2^0 */ fe25519_mul(&z2_50_0,&t,&z2_10_0);
+
+ /* 2^51 - 2^1 */ fe25519_square(&t,&z2_50_0);
+ /* 2^100 - 2^50 */ for (i = 1;i < 50;i++) { fe25519_square(&t,&t); }
+ /* 2^100 - 2^0 */ fe25519_mul(&z2_100_0,&t,&z2_50_0);
+
+ /* 2^101 - 2^1 */ fe25519_square(&t,&z2_100_0);
+ /* 2^200 - 2^100 */ for (i = 1;i < 100;i++) { fe25519_square(&t,&t); }
+ /* 2^200 - 2^0 */ fe25519_mul(&t,&t,&z2_100_0);
+
+ /* 2^201 - 2^1 */ fe25519_square(&t,&t);
+ /* 2^250 - 2^50 */ for (i = 1;i < 50;i++) { fe25519_square(&t,&t); }
+ /* 2^250 - 2^0 */ fe25519_mul(&t,&t,&z2_50_0);
+
+ /* 2^251 - 2^1 */ fe25519_square(&t,&t);
+ /* 2^252 - 2^2 */ fe25519_square(&t,&t);
+ /* 2^252 - 3 */ fe25519_mul(r,&t,x);
+}
+/* from supercop-20221122/crypto_sign/ed25519/ref/sc25519.h */
+#ifndef SC25519_H
+#define SC25519_H
+
+
+#define sc25519 crypto_sign_ed25519_ref_sc25519
+#define shortsc25519 crypto_sign_ed25519_ref_shortsc25519
+#define sc25519_from32bytes crypto_sign_ed25519_ref_sc25519_from32bytes
+#define sc25519_from64bytes crypto_sign_ed25519_ref_sc25519_from64bytes
+#define sc25519_to32bytes crypto_sign_ed25519_ref_sc25519_to32bytes
+#define sc25519_add crypto_sign_ed25519_ref_sc25519_add
+#define sc25519_mul crypto_sign_ed25519_ref_sc25519_mul
+#define sc25519_window3 crypto_sign_ed25519_ref_sc25519_window3
+#define sc25519_2interleave2 crypto_sign_ed25519_ref_sc25519_2interleave2
+
+typedef struct
+{
+ crypto_uint32 v[32];
+}
+sc25519;
+
+typedef struct
+{
+ crypto_uint32 v[16];
+}
+shortsc25519;
+
+static void sc25519_from32bytes(sc25519 *r, const unsigned char x[32]);
+
+
+static void sc25519_from64bytes(sc25519 *r, const unsigned char x[64]);
+
+
+static void sc25519_to32bytes(unsigned char r[32], const sc25519 *x);
+
+
+
+
+static void sc25519_add(sc25519 *r, const sc25519 *x, const sc25519 *y);
+
+
+static void sc25519_mul(sc25519 *r, const sc25519 *x, const sc25519 *y);
+
+
+/* Convert s into a representation of the form \sum_{i=0}^{84}r[i]2^3
+ * with r[i] in {-4,...,3}
+ */
+static void sc25519_window3(signed char r[85], const sc25519 *s);
+
+/* Convert s into a representation of the form \sum_{i=0}^{50}r[i]2^5
+ * with r[i] in {-16,...,15}
+ */
+
+static void sc25519_2interleave2(unsigned char r[127], const sc25519 *s1, const sc25519 *s2);
+
+#endif
+/* from supercop-20221122/crypto_sign/ed25519/ref/sc25519.c */
+
+/*Arithmetic modulo the group order m = 2^252 + 27742317777372353535851937790883648493 = 7237005577332262213973186563042994240857116359379907606001950938285454250989 */
+
+static const crypto_uint32 sc25519_m[32] = {0xED, 0xD3, 0xF5, 0x5C, 0x1A, 0x63, 0x12, 0x58, 0xD6, 0x9C, 0xF7, 0xA2, 0xDE, 0xF9, 0xDE, 0x14,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
+
+static const crypto_uint32 sc25519_mu[33] = {0x1B, 0x13, 0x2C, 0x0A, 0xA3, 0xE5, 0x9C, 0xED, 0xA7, 0x29, 0x63, 0x08, 0x5D, 0x21, 0x06, 0x21,
+ 0xEB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F};
+
+static crypto_uint32 lt(crypto_uint32 a,crypto_uint32 b) /* 16-bit inputs */
+{
+ unsigned int x = a;
+ x -= (unsigned int) b; /* 0..65535: no; 4294901761..4294967295: yes */
+ x >>= 31; /* 0: no; 1: yes */
+ return x;
+}
+
+/* Reduce coefficients of r before calling sc25519_reduce_add_sub */
+static void sc25519_reduce_add_sub(sc25519 *r)
+{
+ crypto_uint32 pb = 0;
+ crypto_uint32 b;
+ crypto_uint32 mask;
+ int i;
+ unsigned char t[32];
+
+ for(i=0;i<32;i++)
+ {
+ pb += sc25519_m[i];
+ b = lt(r->v[i],pb);
+ t[i] = r->v[i]-pb+(b<<8);
+ pb = b;
+ }
+ mask = b - 1;
+ for(i=0;i<32;i++)
+ r->v[i] ^= mask & (r->v[i] ^ t[i]);
+}
+
+/* Reduce coefficients of x before calling barrett_reduce */
+static void barrett_reduce(sc25519 *r, const crypto_uint32 x[64])
+{
+ /* See HAC, Alg. 14.42 */
+ int i,j;
+ crypto_uint32 q2[66];
+ crypto_uint32 *q3 = q2 + 33;
+ crypto_uint32 r1[33];
+ crypto_uint32 r2[33];
+ crypto_uint32 carry;
+ crypto_uint32 pb = 0;
+ crypto_uint32 b;
+
+ for (i = 0;i < 66;++i) q2[i] = 0;
+ for (i = 0;i < 33;++i) r2[i] = 0;
+
+ for(i=0;i<33;i++)
+ for(j=0;j<33;j++)
+ if(i+j >= 31) q2[i+j] += sc25519_mu[i]*x[j+31];
+ carry = q2[31] >> 8;
+ q2[32] += carry;
+ carry = q2[32] >> 8;
+ q2[33] += carry;
+
+ for(i=0;i<33;i++)r1[i] = x[i];
+ for(i=0;i<32;i++)
+ for(j=0;j<33;j++)
+ if(i+j < 33) r2[i+j] += sc25519_m[i]*q3[j];
+
+ for(i=0;i<32;i++)
+ {
+ carry = r2[i] >> 8;
+ r2[i+1] += carry;
+ r2[i] &= 0xff;
+ }
+
+ for(i=0;i<32;i++)
+ {
+ pb += r2[i];
+ b = lt(r1[i],pb);
+ r->v[i] = r1[i]-pb+(b<<8);
+ pb = b;
+ }
+
+ /* XXX: Can it really happen that r<0?, See HAC, Alg 14.42, Step 3
+ * If so: Handle it here!
+ */
+
+ sc25519_reduce_add_sub(r);
+ sc25519_reduce_add_sub(r);
+}
+
+static void sc25519_from32bytes(sc25519 *r, const unsigned char x[32])
+{
+ int i;
+ crypto_uint32 t[64];
+ for(i=0;i<32;i++) t[i] = x[i];
+ for(i=32;i<64;++i) t[i] = 0;
+ barrett_reduce(r, t);
+}
+
+
+static void sc25519_from64bytes(sc25519 *r, const unsigned char x[64])
+{
+ int i;
+ crypto_uint32 t[64];
+ for(i=0;i<64;i++) t[i] = x[i];
+ barrett_reduce(r, t);
+}
+
+
+static void sc25519_to32bytes(unsigned char r[32], const sc25519 *x)
+{
+ int i;
+ for(i=0;i<32;i++) r[i] = x->v[i];
+}
+
+
+
+
+static void sc25519_add(sc25519 *r, const sc25519 *x, const sc25519 *y)
+{
+ int i, carry;
+ for(i=0;i<32;i++) r->v[i] = x->v[i] + y->v[i];
+ for(i=0;i<31;i++)
+ {
+ carry = r->v[i] >> 8;
+ r->v[i+1] += carry;
+ r->v[i] &= 0xff;
+ }
+ sc25519_reduce_add_sub(r);
+}
+
+
+static void sc25519_mul(sc25519 *r, const sc25519 *x, const sc25519 *y)
+{
+ int i,j,carry;
+ crypto_uint32 t[64];
+ for(i=0;i<64;i++)t[i] = 0;
+
+ for(i=0;i<32;i++)
+ for(j=0;j<32;j++)
+ t[i+j] += x->v[i] * y->v[j];
+
+ /* Reduce coefficients */
+ for(i=0;i<63;i++)
+ {
+ carry = t[i] >> 8;
+ t[i+1] += carry;
+ t[i] &= 0xff;
+ }
+
+ barrett_reduce(r, t);
+}
+
+
+static void sc25519_window3(signed char r[85], const sc25519 *s)
+{
+ char carry;
+ int i;
+ for(i=0;i<10;i++)
+ {
+ r[8*i+0] = s->v[3*i+0] & 7;
+ r[8*i+1] = (s->v[3*i+0] >> 3) & 7;
+ r[8*i+2] = (s->v[3*i+0] >> 6) & 7;
+ r[8*i+2] ^= (s->v[3*i+1] << 2) & 7;
+ r[8*i+3] = (s->v[3*i+1] >> 1) & 7;
+ r[8*i+4] = (s->v[3*i+1] >> 4) & 7;
+ r[8*i+5] = (s->v[3*i+1] >> 7) & 7;
+ r[8*i+5] ^= (s->v[3*i+2] << 1) & 7;
+ r[8*i+6] = (s->v[3*i+2] >> 2) & 7;
+ r[8*i+7] = (s->v[3*i+2] >> 5) & 7;
+ }
+ r[8*i+0] = s->v[3*i+0] & 7;
+ r[8*i+1] = (s->v[3*i+0] >> 3) & 7;
+ r[8*i+2] = (s->v[3*i+0] >> 6) & 7;
+ r[8*i+2] ^= (s->v[3*i+1] << 2) & 7;
+ r[8*i+3] = (s->v[3*i+1] >> 1) & 7;
+ r[8*i+4] = (s->v[3*i+1] >> 4) & 7;
+
+ /* Making it signed */
+ carry = 0;
+ for(i=0;i<84;i++)
+ {
+ r[i] += carry;
+ r[i+1] += r[i] >> 3;
+ r[i] &= 7;
+ carry = r[i] >> 2;
+ r[i] -= carry<<3;
+ }
+ r[84] += carry;
+}
+
+
+static void sc25519_2interleave2(unsigned char r[127], const sc25519 *s1, const sc25519 *s2)
+{
+ int i;
+ for(i=0;i<31;i++)
+ {
+ r[4*i] = ( s1->v[i] & 3) ^ (( s2->v[i] & 3) << 2);
+ r[4*i+1] = ((s1->v[i] >> 2) & 3) ^ (((s2->v[i] >> 2) & 3) << 2);
+ r[4*i+2] = ((s1->v[i] >> 4) & 3) ^ (((s2->v[i] >> 4) & 3) << 2);
+ r[4*i+3] = ((s1->v[i] >> 6) & 3) ^ (((s2->v[i] >> 6) & 3) << 2);
+ }
+ r[124] = ( s1->v[31] & 3) ^ (( s2->v[31] & 3) << 2);
+ r[125] = ((s1->v[31] >> 2) & 3) ^ (((s2->v[31] >> 2) & 3) << 2);
+ r[126] = ((s1->v[31] >> 4) & 3) ^ (((s2->v[31] >> 4) & 3) << 2);
+}
+/* from supercop-20221122/crypto_sign/ed25519/ref/ge25519.h */
+#ifndef GE25519_H
+#define GE25519_H
+
+
+#define ge25519 crypto_sign_ed25519_ref_ge25519
+#define ge25519_base crypto_sign_ed25519_ref_ge25519_base
+#define ge25519_unpackneg_vartime crypto_sign_ed25519_ref_unpackneg_vartime
+#define ge25519_pack crypto_sign_ed25519_ref_pack
+#define ge25519_isneutral_vartime crypto_sign_ed25519_ref_isneutral_vartime
+#define ge25519_double_scalarmult_vartime crypto_sign_ed25519_ref_double_scalarmult_vartime
+#define ge25519_scalarmult_base crypto_sign_ed25519_ref_scalarmult_base
+
+typedef struct
+{
+ fe25519 x;
+ fe25519 y;
+ fe25519 z;
+ fe25519 t;
+} ge25519;
+
+const ge25519 ge25519_base;
+
+int ge25519_unpackneg_vartime(ge25519 *r, const unsigned char p[32]);
+
+static void ge25519_pack(unsigned char r[32], const ge25519 *p);
+
+int ge25519_isneutral_vartime(const ge25519 *p);
+
+static void ge25519_double_scalarmult_vartime(ge25519 *r, const ge25519 *p1, const sc25519 *s1, const ge25519 *p2, const sc25519 *s2);
+
+static void ge25519_scalarmult_base(ge25519 *r, const sc25519 *s);
+
+#endif
+/* from supercop-20221122/crypto_sign/ed25519/ref/ge25519.c */
+
+/*
+ * Arithmetic on the twisted Edwards curve -x^2 + y^2 = 1 + dx^2y^2
+ * with d = -(121665/121666) = 37095705934669439343138083508754565189542113879843219016388785533085940283555
+ * Base point: (15112221349535400772501151409588531511454012693041857206046113283949847762202,46316835694926478169428394003475163141307993866256225615783033603165251855960);
+ */
+
+/* d */
+static const fe25519 ge25519_ecd = {{0xA3, 0x78, 0x59, 0x13, 0xCA, 0x4D, 0xEB, 0x75, 0xAB, 0xD8, 0x41, 0x41, 0x4D, 0x0A, 0x70, 0x00,
+ 0x98, 0xE8, 0x79, 0x77, 0x79, 0x40, 0xC7, 0x8C, 0x73, 0xFE, 0x6F, 0x2B, 0xEE, 0x6C, 0x03, 0x52}};
+/* 2*d */
+static const fe25519 ge25519_ec2d = {{0x59, 0xF1, 0xB2, 0x26, 0x94, 0x9B, 0xD6, 0xEB, 0x56, 0xB1, 0x83, 0x82, 0x9A, 0x14, 0xE0, 0x00,
+ 0x30, 0xD1, 0xF3, 0xEE, 0xF2, 0x80, 0x8E, 0x19, 0xE7, 0xFC, 0xDF, 0x56, 0xDC, 0xD9, 0x06, 0x24}};
+/* sqrt(-1) */
+static const fe25519 ge25519_sqrtm1 = {{0xB0, 0xA0, 0x0E, 0x4A, 0x27, 0x1B, 0xEE, 0xC4, 0x78, 0xE4, 0x2F, 0xAD, 0x06, 0x18, 0x43, 0x2F,
+ 0xA7, 0xD7, 0xFB, 0x3D, 0x99, 0x00, 0x4D, 0x2B, 0x0B, 0xDF, 0xC1, 0x4F, 0x80, 0x24, 0x83, 0x2B}};
+
+#define ge25519_p3 ge25519
+
+typedef struct
+{
+ fe25519 x;
+ fe25519 z;
+ fe25519 y;
+ fe25519 t;
+} ge25519_p1p1;
+
+typedef struct
+{
+ fe25519 x;
+ fe25519 y;
+ fe25519 z;
+} ge25519_p2;
+
+typedef struct
+{
+ fe25519 x;
+ fe25519 y;
+} ge25519_aff;
+
+
+/* Packed coordinates of the base point */
+const ge25519 ge25519_base = {{{0x1A, 0xD5, 0x25, 0x8F, 0x60, 0x2D, 0x56, 0xC9, 0xB2, 0xA7, 0x25, 0x95, 0x60, 0xC7, 0x2C, 0x69,
+ 0x5C, 0xDC, 0xD6, 0xFD, 0x31, 0xE2, 0xA4, 0xC0, 0xFE, 0x53, 0x6E, 0xCD, 0xD3, 0x36, 0x69, 0x21}},
+ {{0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
+ 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0xA3, 0xDD, 0xB7, 0xA5, 0xB3, 0x8A, 0xDE, 0x6D, 0xF5, 0x52, 0x51, 0x77, 0x80, 0x9F, 0xF0, 0x20,
+ 0x7D, 0xE3, 0xAB, 0x64, 0x8E, 0x4E, 0xEA, 0x66, 0x65, 0x76, 0x8B, 0xD7, 0x0F, 0x5F, 0x87, 0x67}}};
+
+/* Multiples of the base point in affine representation */
+static const ge25519_aff ge25519_base_multiples_affine[425] = {
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x1a, 0xd5, 0x25, 0x8f, 0x60, 0x2d, 0x56, 0xc9, 0xb2, 0xa7, 0x25, 0x95, 0x60, 0xc7, 0x2c, 0x69, 0x5c, 0xdc, 0xd6, 0xfd, 0x31, 0xe2, 0xa4, 0xc0, 0xfe, 0x53, 0x6e, 0xcd, 0xd3, 0x36, 0x69, 0x21}} ,
+ {{0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66}}},
+{{{0x0e, 0xce, 0x43, 0x28, 0x4e, 0xa1, 0xc5, 0x83, 0x5f, 0xa4, 0xd7, 0x15, 0x45, 0x8e, 0x0d, 0x08, 0xac, 0xe7, 0x33, 0x18, 0x7d, 0x3b, 0x04, 0x3d, 0x6c, 0x04, 0x5a, 0x9f, 0x4c, 0x38, 0xab, 0x36}} ,
+ {{0xc9, 0xa3, 0xf8, 0x6a, 0xae, 0x46, 0x5f, 0x0e, 0x56, 0x51, 0x38, 0x64, 0x51, 0x0f, 0x39, 0x97, 0x56, 0x1f, 0xa2, 0xc9, 0xe8, 0x5e, 0xa2, 0x1d, 0xc2, 0x29, 0x23, 0x09, 0xf3, 0xcd, 0x60, 0x22}}},
+{{{0x5c, 0xe2, 0xf8, 0xd3, 0x5f, 0x48, 0x62, 0xac, 0x86, 0x48, 0x62, 0x81, 0x19, 0x98, 0x43, 0x63, 0x3a, 0xc8, 0xda, 0x3e, 0x74, 0xae, 0xf4, 0x1f, 0x49, 0x8f, 0x92, 0x22, 0x4a, 0x9c, 0xae, 0x67}} ,
+ {{0xd4, 0xb4, 0xf5, 0x78, 0x48, 0x68, 0xc3, 0x02, 0x04, 0x03, 0x24, 0x67, 0x17, 0xec, 0x16, 0x9f, 0xf7, 0x9e, 0x26, 0x60, 0x8e, 0xa1, 0x26, 0xa1, 0xab, 0x69, 0xee, 0x77, 0xd1, 0xb1, 0x67, 0x12}}},
+{{{0x70, 0xf8, 0xc9, 0xc4, 0x57, 0xa6, 0x3a, 0x49, 0x47, 0x15, 0xce, 0x93, 0xc1, 0x9e, 0x73, 0x1a, 0xf9, 0x20, 0x35, 0x7a, 0xb8, 0xd4, 0x25, 0x83, 0x46, 0xf1, 0xcf, 0x56, 0xdb, 0xa8, 0x3d, 0x20}} ,
+ {{0x2f, 0x11, 0x32, 0xca, 0x61, 0xab, 0x38, 0xdf, 0xf0, 0x0f, 0x2f, 0xea, 0x32, 0x28, 0xf2, 0x4c, 0x6c, 0x71, 0xd5, 0x80, 0x85, 0xb8, 0x0e, 0x47, 0xe1, 0x95, 0x15, 0xcb, 0x27, 0xe8, 0xd0, 0x47}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0xc8, 0x84, 0xa5, 0x08, 0xbc, 0xfd, 0x87, 0x3b, 0x99, 0x8b, 0x69, 0x80, 0x7b, 0xc6, 0x3a, 0xeb, 0x93, 0xcf, 0x4e, 0xf8, 0x5c, 0x2d, 0x86, 0x42, 0xb6, 0x71, 0xd7, 0x97, 0x5f, 0xe1, 0x42, 0x67}} ,
+ {{0xb4, 0xb9, 0x37, 0xfc, 0xa9, 0x5b, 0x2f, 0x1e, 0x93, 0xe4, 0x1e, 0x62, 0xfc, 0x3c, 0x78, 0x81, 0x8f, 0xf3, 0x8a, 0x66, 0x09, 0x6f, 0xad, 0x6e, 0x79, 0x73, 0xe5, 0xc9, 0x00, 0x06, 0xd3, 0x21}}},
+{{{0xf8, 0xf9, 0x28, 0x6c, 0x6d, 0x59, 0xb2, 0x59, 0x74, 0x23, 0xbf, 0xe7, 0x33, 0x8d, 0x57, 0x09, 0x91, 0x9c, 0x24, 0x08, 0x15, 0x2b, 0xe2, 0xb8, 0xee, 0x3a, 0xe5, 0x27, 0x06, 0x86, 0xa4, 0x23}} ,
+ {{0xeb, 0x27, 0x67, 0xc1, 0x37, 0xab, 0x7a, 0xd8, 0x27, 0x9c, 0x07, 0x8e, 0xff, 0x11, 0x6a, 0xb0, 0x78, 0x6e, 0xad, 0x3a, 0x2e, 0x0f, 0x98, 0x9f, 0x72, 0xc3, 0x7f, 0x82, 0xf2, 0x96, 0x96, 0x70}}},
+{{{0x81, 0x6b, 0x88, 0xe8, 0x1e, 0xc7, 0x77, 0x96, 0x0e, 0xa1, 0xa9, 0x52, 0xe0, 0xd8, 0x0e, 0x61, 0x9e, 0x79, 0x2d, 0x95, 0x9c, 0x8d, 0x96, 0xe0, 0x06, 0x40, 0x5d, 0x87, 0x28, 0x5f, 0x98, 0x70}} ,
+ {{0xf1, 0x79, 0x7b, 0xed, 0x4f, 0x44, 0xb2, 0xe7, 0x08, 0x0d, 0xc2, 0x08, 0x12, 0xd2, 0x9f, 0xdf, 0xcd, 0x93, 0x20, 0x8a, 0xcf, 0x33, 0xca, 0x6d, 0x89, 0xb9, 0x77, 0xc8, 0x93, 0x1b, 0x4e, 0x60}}},
+{{{0x26, 0x4f, 0x7e, 0x97, 0xf6, 0x40, 0xdd, 0x4f, 0xfc, 0x52, 0x78, 0xf9, 0x90, 0x31, 0x03, 0xe6, 0x7d, 0x56, 0x39, 0x0b, 0x1d, 0x56, 0x82, 0x85, 0xf9, 0x1a, 0x42, 0x17, 0x69, 0x6c, 0xcf, 0x39}} ,
+ {{0x69, 0xd2, 0x06, 0x3a, 0x4f, 0x39, 0x2d, 0xf9, 0x38, 0x40, 0x8c, 0x4c, 0xe7, 0x05, 0x12, 0xb4, 0x78, 0x8b, 0xf8, 0xc0, 0xec, 0x93, 0xde, 0x7a, 0x6b, 0xce, 0x2c, 0xe1, 0x0e, 0xa9, 0x34, 0x44}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x0b, 0xa4, 0x3c, 0xb0, 0x0f, 0x7a, 0x51, 0xf1, 0x78, 0xd6, 0xd9, 0x6a, 0xfd, 0x46, 0xe8, 0xb8, 0xa8, 0x79, 0x1d, 0x87, 0xf9, 0x90, 0xf2, 0x9c, 0x13, 0x29, 0xf8, 0x0b, 0x20, 0x64, 0xfa, 0x05}} ,
+ {{0x26, 0x09, 0xda, 0x17, 0xaf, 0x95, 0xd6, 0xfb, 0x6a, 0x19, 0x0d, 0x6e, 0x5e, 0x12, 0xf1, 0x99, 0x4c, 0xaa, 0xa8, 0x6f, 0x79, 0x86, 0xf4, 0x72, 0x28, 0x00, 0x26, 0xf9, 0xea, 0x9e, 0x19, 0x3d}}},
+{{{0x87, 0xdd, 0xcf, 0xf0, 0x5b, 0x49, 0xa2, 0x5d, 0x40, 0x7a, 0x23, 0x26, 0xa4, 0x7a, 0x83, 0x8a, 0xb7, 0x8b, 0xd2, 0x1a, 0xbf, 0xea, 0x02, 0x24, 0x08, 0x5f, 0x7b, 0xa9, 0xb1, 0xbe, 0x9d, 0x37}} ,
+ {{0xfc, 0x86, 0x4b, 0x08, 0xee, 0xe7, 0xa0, 0xfd, 0x21, 0x45, 0x09, 0x34, 0xc1, 0x61, 0x32, 0x23, 0xfc, 0x9b, 0x55, 0x48, 0x53, 0x99, 0xf7, 0x63, 0xd0, 0x99, 0xce, 0x01, 0xe0, 0x9f, 0xeb, 0x28}}},
+{{{0x47, 0xfc, 0xab, 0x5a, 0x17, 0xf0, 0x85, 0x56, 0x3a, 0x30, 0x86, 0x20, 0x28, 0x4b, 0x8e, 0x44, 0x74, 0x3a, 0x6e, 0x02, 0xf1, 0x32, 0x8f, 0x9f, 0x3f, 0x08, 0x35, 0xe9, 0xca, 0x16, 0x5f, 0x6e}} ,
+ {{0x1c, 0x59, 0x1c, 0x65, 0x5d, 0x34, 0xa4, 0x09, 0xcd, 0x13, 0x9c, 0x70, 0x7d, 0xb1, 0x2a, 0xc5, 0x88, 0xaf, 0x0b, 0x60, 0xc7, 0x9f, 0x34, 0x8d, 0xd6, 0xb7, 0x7f, 0xea, 0x78, 0x65, 0x8d, 0x77}}},
+{{{0x56, 0xa5, 0xc2, 0x0c, 0xdd, 0xbc, 0xb8, 0x20, 0x6d, 0x57, 0x61, 0xb5, 0xfb, 0x78, 0xb5, 0xd4, 0x49, 0x54, 0x90, 0x26, 0xc1, 0xcb, 0xe9, 0xe6, 0xbf, 0xec, 0x1d, 0x4e, 0xed, 0x07, 0x7e, 0x5e}} ,
+ {{0xc7, 0xf6, 0x6c, 0x56, 0x31, 0x20, 0x14, 0x0e, 0xa8, 0xd9, 0x27, 0xc1, 0x9a, 0x3d, 0x1b, 0x7d, 0x0e, 0x26, 0xd3, 0x81, 0xaa, 0xeb, 0xf5, 0x6b, 0x79, 0x02, 0xf1, 0x51, 0x5c, 0x75, 0x55, 0x0f}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x0a, 0x34, 0xcd, 0x82, 0x3c, 0x33, 0x09, 0x54, 0xd2, 0x61, 0x39, 0x30, 0x9b, 0xfd, 0xef, 0x21, 0x26, 0xd4, 0x70, 0xfa, 0xee, 0xf9, 0x31, 0x33, 0x73, 0x84, 0xd0, 0xb3, 0x81, 0xbf, 0xec, 0x2e}} ,
+ {{0xe8, 0x93, 0x8b, 0x00, 0x64, 0xf7, 0x9c, 0xb8, 0x74, 0xe0, 0xe6, 0x49, 0x48, 0x4d, 0x4d, 0x48, 0xb6, 0x19, 0xa1, 0x40, 0xb7, 0xd9, 0x32, 0x41, 0x7c, 0x82, 0x37, 0xa1, 0x2d, 0xdc, 0xd2, 0x54}}},
+{{{0x68, 0x2b, 0x4a, 0x5b, 0xd5, 0xc7, 0x51, 0x91, 0x1d, 0xe1, 0x2a, 0x4b, 0xc4, 0x47, 0xf1, 0xbc, 0x7a, 0xb3, 0xcb, 0xc8, 0xb6, 0x7c, 0xac, 0x90, 0x05, 0xfd, 0xf3, 0xf9, 0x52, 0x3a, 0x11, 0x6b}} ,
+ {{0x3d, 0xc1, 0x27, 0xf3, 0x59, 0x43, 0x95, 0x90, 0xc5, 0x96, 0x79, 0xf5, 0xf4, 0x95, 0x65, 0x29, 0x06, 0x9c, 0x51, 0x05, 0x18, 0xda, 0xb8, 0x2e, 0x79, 0x7e, 0x69, 0x59, 0x71, 0x01, 0xeb, 0x1a}}},
+{{{0x15, 0x06, 0x49, 0xb6, 0x8a, 0x3c, 0xea, 0x2f, 0x34, 0x20, 0x14, 0xc3, 0xaa, 0xd6, 0xaf, 0x2c, 0x3e, 0xbd, 0x65, 0x20, 0xe2, 0x4d, 0x4b, 0x3b, 0xeb, 0x9f, 0x4a, 0xc3, 0xad, 0xa4, 0x3b, 0x60}} ,
+ {{0xbc, 0x58, 0xe6, 0xc0, 0x95, 0x2a, 0x2a, 0x81, 0x9a, 0x7a, 0xf3, 0xd2, 0x06, 0xbe, 0x48, 0xbc, 0x0c, 0xc5, 0x46, 0xe0, 0x6a, 0xd4, 0xac, 0x0f, 0xd9, 0xcc, 0x82, 0x34, 0x2c, 0xaf, 0xdb, 0x1f}}},
+{{{0xf7, 0x17, 0x13, 0xbd, 0xfb, 0xbc, 0xd2, 0xec, 0x45, 0xb3, 0x15, 0x31, 0xe9, 0xaf, 0x82, 0x84, 0x3d, 0x28, 0xc6, 0xfc, 0x11, 0xf5, 0x41, 0xb5, 0x8b, 0xd3, 0x12, 0x76, 0x52, 0xe7, 0x1a, 0x3c}} ,
+ {{0x4e, 0x36, 0x11, 0x07, 0xa2, 0x15, 0x20, 0x51, 0xc4, 0x2a, 0xc3, 0x62, 0x8b, 0x5e, 0x7f, 0xa6, 0x0f, 0xf9, 0x45, 0x85, 0x6c, 0x11, 0x86, 0xb7, 0x7e, 0xe5, 0xd7, 0xf9, 0xc3, 0x91, 0x1c, 0x05}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0xea, 0xd6, 0xde, 0x29, 0x3a, 0x00, 0xb9, 0x02, 0x59, 0xcb, 0x26, 0xc4, 0xba, 0x99, 0xb1, 0x97, 0x2f, 0x8e, 0x00, 0x92, 0x26, 0x4f, 0x52, 0xeb, 0x47, 0x1b, 0x89, 0x8b, 0x24, 0xc0, 0x13, 0x7d}} ,
+ {{0xd5, 0x20, 0x5b, 0x80, 0xa6, 0x80, 0x20, 0x95, 0xc3, 0xe9, 0x9f, 0x8e, 0x87, 0x9e, 0x1e, 0x9e, 0x7a, 0xc7, 0xcc, 0x75, 0x6c, 0xa5, 0xf1, 0x91, 0x1a, 0xa8, 0x01, 0x2c, 0xab, 0x76, 0xa9, 0x59}}},
+{{{0xde, 0xc9, 0xb1, 0x31, 0x10, 0x16, 0xaa, 0x35, 0x14, 0x6a, 0xd4, 0xb5, 0x34, 0x82, 0x71, 0xd2, 0x4a, 0x5d, 0x9a, 0x1f, 0x53, 0x26, 0x3c, 0xe5, 0x8e, 0x8d, 0x33, 0x7f, 0xff, 0xa9, 0xd5, 0x17}} ,
+ {{0x89, 0xaf, 0xf6, 0xa4, 0x64, 0xd5, 0x10, 0xe0, 0x1d, 0xad, 0xef, 0x44, 0xbd, 0xda, 0x83, 0xac, 0x7a, 0xa8, 0xf0, 0x1c, 0x07, 0xf9, 0xc3, 0x43, 0x6c, 0x3f, 0xb7, 0xd3, 0x87, 0x22, 0x02, 0x73}}},
+{{{0x64, 0x1d, 0x49, 0x13, 0x2f, 0x71, 0xec, 0x69, 0x87, 0xd0, 0x42, 0xee, 0x13, 0xec, 0xe3, 0xed, 0x56, 0x7b, 0xbf, 0xbd, 0x8c, 0x2f, 0x7d, 0x7b, 0x9d, 0x28, 0xec, 0x8e, 0x76, 0x2f, 0x6f, 0x08}} ,
+ {{0x22, 0xf5, 0x5f, 0x4d, 0x15, 0xef, 0xfc, 0x4e, 0x57, 0x03, 0x36, 0x89, 0xf0, 0xeb, 0x5b, 0x91, 0xd6, 0xe2, 0xca, 0x01, 0xa5, 0xee, 0x52, 0xec, 0xa0, 0x3c, 0x8f, 0x33, 0x90, 0x5a, 0x94, 0x72}}},
+{{{0x8a, 0x4b, 0xe7, 0x38, 0xbc, 0xda, 0xc2, 0xb0, 0x85, 0xe1, 0x4a, 0xfe, 0x2d, 0x44, 0x84, 0xcb, 0x20, 0x6b, 0x2d, 0xbf, 0x11, 0x9c, 0xd7, 0xbe, 0xd3, 0x3e, 0x5f, 0xbf, 0x68, 0xbc, 0xa8, 0x07}} ,
+ {{0x01, 0x89, 0x28, 0x22, 0x6a, 0x78, 0xaa, 0x29, 0x03, 0xc8, 0x74, 0x95, 0x03, 0x3e, 0xdc, 0xbd, 0x07, 0x13, 0xa8, 0xa2, 0x20, 0x2d, 0xb3, 0x18, 0x70, 0x42, 0xfd, 0x7a, 0xc4, 0xd7, 0x49, 0x72}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x02, 0xff, 0x32, 0x2b, 0x5c, 0x93, 0x54, 0x32, 0xe8, 0x57, 0x54, 0x1a, 0x8b, 0x33, 0x60, 0x65, 0xd3, 0x67, 0xa4, 0xc1, 0x26, 0xc4, 0xa4, 0x34, 0x1f, 0x9b, 0xa7, 0xa9, 0xf4, 0xd9, 0x4f, 0x5b}} ,
+ {{0x46, 0x8d, 0xb0, 0x33, 0x54, 0x26, 0x5b, 0x68, 0xdf, 0xbb, 0xc5, 0xec, 0xc2, 0xf9, 0x3c, 0x5a, 0x37, 0xc1, 0x8e, 0x27, 0x47, 0xaa, 0x49, 0x5a, 0xf8, 0xfb, 0x68, 0x04, 0x23, 0xd1, 0xeb, 0x40}}},
+{{{0x65, 0xa5, 0x11, 0x84, 0x8a, 0x67, 0x9d, 0x9e, 0xd1, 0x44, 0x68, 0x7a, 0x34, 0xe1, 0x9f, 0xa3, 0x54, 0xcd, 0x07, 0xca, 0x79, 0x1f, 0x54, 0x2f, 0x13, 0x70, 0x4e, 0xee, 0xa2, 0xfa, 0xe7, 0x5d}} ,
+ {{0x36, 0xec, 0x54, 0xf8, 0xce, 0xe4, 0x85, 0xdf, 0xf6, 0x6f, 0x1d, 0x90, 0x08, 0xbc, 0xe8, 0xc0, 0x92, 0x2d, 0x43, 0x6b, 0x92, 0xa9, 0x8e, 0xab, 0x0a, 0x2e, 0x1c, 0x1e, 0x64, 0x23, 0x9f, 0x2c}}},
+{{{0xa7, 0xd6, 0x2e, 0xd5, 0xcc, 0xd4, 0xcb, 0x5a, 0x3b, 0xa7, 0xf9, 0x46, 0x03, 0x1d, 0xad, 0x2b, 0x34, 0x31, 0x90, 0x00, 0x46, 0x08, 0x82, 0x14, 0xc4, 0xe0, 0x9c, 0xf0, 0xe3, 0x55, 0x43, 0x31}} ,
+ {{0x60, 0xd6, 0xdd, 0x78, 0xe6, 0xd4, 0x22, 0x42, 0x1f, 0x00, 0xf9, 0xb1, 0x6a, 0x63, 0xe2, 0x92, 0x59, 0xd1, 0x1a, 0xb7, 0x00, 0x54, 0x29, 0xc9, 0xc1, 0xf6, 0x6f, 0x7a, 0xc5, 0x3c, 0x5f, 0x65}}},
+{{{0x27, 0x4f, 0xd0, 0x72, 0xb1, 0x11, 0x14, 0x27, 0x15, 0x94, 0x48, 0x81, 0x7e, 0x74, 0xd8, 0x32, 0xd5, 0xd1, 0x11, 0x28, 0x60, 0x63, 0x36, 0x32, 0x37, 0xb5, 0x13, 0x1c, 0xa0, 0x37, 0xe3, 0x74}} ,
+ {{0xf1, 0x25, 0x4e, 0x11, 0x96, 0x67, 0xe6, 0x1c, 0xc2, 0xb2, 0x53, 0xe2, 0xda, 0x85, 0xee, 0xb2, 0x9f, 0x59, 0xf3, 0xba, 0xbd, 0xfa, 0xcf, 0x6e, 0xf9, 0xda, 0xa4, 0xb3, 0x02, 0x8f, 0x64, 0x08}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x34, 0x94, 0xf2, 0x64, 0x54, 0x47, 0x37, 0x07, 0x40, 0x8a, 0x20, 0xba, 0x4a, 0x55, 0xd7, 0x3f, 0x47, 0xba, 0x25, 0x23, 0x14, 0xb0, 0x2c, 0xe8, 0x55, 0xa8, 0xa6, 0xef, 0x51, 0xbd, 0x6f, 0x6a}} ,
+ {{0x71, 0xd6, 0x16, 0x76, 0xb2, 0x06, 0xea, 0x79, 0xf5, 0xc4, 0xc3, 0x52, 0x7e, 0x61, 0xd1, 0xe1, 0xad, 0x70, 0x78, 0x1d, 0x16, 0x11, 0xf8, 0x7c, 0x2b, 0xfc, 0x55, 0x9f, 0x52, 0xf8, 0xf5, 0x16}}},
+{{{0x34, 0x96, 0x9a, 0xf6, 0xc5, 0xe0, 0x14, 0x03, 0x24, 0x0e, 0x4c, 0xad, 0x9e, 0x9a, 0x70, 0x23, 0x96, 0xb2, 0xf1, 0x2e, 0x9d, 0xc3, 0x32, 0x9b, 0x54, 0xa5, 0x73, 0xde, 0x88, 0xb1, 0x3e, 0x24}} ,
+ {{0xf6, 0xe2, 0x4c, 0x1f, 0x5b, 0xb2, 0xaf, 0x82, 0xa5, 0xcf, 0x81, 0x10, 0x04, 0xef, 0xdb, 0xa2, 0xcc, 0x24, 0xb2, 0x7e, 0x0b, 0x7a, 0xeb, 0x01, 0xd8, 0x52, 0xf4, 0x51, 0x89, 0x29, 0x79, 0x37}}},
+{{{0x74, 0xde, 0x12, 0xf3, 0x68, 0xb7, 0x66, 0xc3, 0xee, 0x68, 0xdc, 0x81, 0xb5, 0x55, 0x99, 0xab, 0xd9, 0x28, 0x63, 0x6d, 0x8b, 0x40, 0x69, 0x75, 0x6c, 0xcd, 0x5c, 0x2a, 0x7e, 0x32, 0x7b, 0x29}} ,
+ {{0x02, 0xcc, 0x22, 0x74, 0x4d, 0x19, 0x07, 0xc0, 0xda, 0xb5, 0x76, 0x51, 0x2a, 0xaa, 0xa6, 0x0a, 0x5f, 0x26, 0xd4, 0xbc, 0xaf, 0x48, 0x88, 0x7f, 0x02, 0xbc, 0xf2, 0xe1, 0xcf, 0xe9, 0xdd, 0x15}}},
+{{{0xed, 0xb5, 0x9a, 0x8c, 0x9a, 0xdd, 0x27, 0xf4, 0x7f, 0x47, 0xd9, 0x52, 0xa7, 0xcd, 0x65, 0xa5, 0x31, 0x22, 0xed, 0xa6, 0x63, 0x5b, 0x80, 0x4a, 0xad, 0x4d, 0xed, 0xbf, 0xee, 0x49, 0xb3, 0x06}} ,
+ {{0xf8, 0x64, 0x8b, 0x60, 0x90, 0xe9, 0xde, 0x44, 0x77, 0xb9, 0x07, 0x36, 0x32, 0xc2, 0x50, 0xf5, 0x65, 0xdf, 0x48, 0x4c, 0x37, 0xaa, 0x68, 0xab, 0x9a, 0x1f, 0x3e, 0xff, 0x89, 0x92, 0xa0, 0x07}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x7d, 0x4f, 0x9c, 0x19, 0xc0, 0x4a, 0x31, 0xec, 0xf9, 0xaa, 0xeb, 0xb2, 0x16, 0x9c, 0xa3, 0x66, 0x5f, 0xd1, 0xd4, 0xed, 0xb8, 0x92, 0x1c, 0xab, 0xda, 0xea, 0xd9, 0x57, 0xdf, 0x4c, 0x2a, 0x48}} ,
+ {{0x4b, 0xb0, 0x4e, 0x6e, 0x11, 0x3b, 0x51, 0xbd, 0x6a, 0xfd, 0xe4, 0x25, 0xa5, 0x5f, 0x11, 0x3f, 0x98, 0x92, 0x51, 0x14, 0xc6, 0x5f, 0x3c, 0x0b, 0xa8, 0xf7, 0xc2, 0x81, 0x43, 0xde, 0x91, 0x73}}},
+{{{0x3c, 0x8f, 0x9f, 0x33, 0x2a, 0x1f, 0x43, 0x33, 0x8f, 0x68, 0xff, 0x1f, 0x3d, 0x73, 0x6b, 0xbf, 0x68, 0xcc, 0x7d, 0x13, 0x6c, 0x24, 0x4b, 0xcc, 0x4d, 0x24, 0x0d, 0xfe, 0xde, 0x86, 0xad, 0x3b}} ,
+ {{0x79, 0x51, 0x81, 0x01, 0xdc, 0x73, 0x53, 0xe0, 0x6e, 0x9b, 0xea, 0x68, 0x3f, 0x5c, 0x14, 0x84, 0x53, 0x8d, 0x4b, 0xc0, 0x9f, 0x9f, 0x89, 0x2b, 0x8c, 0xba, 0x86, 0xfa, 0xf2, 0xcd, 0xe3, 0x2d}}},
+{{{0x06, 0xf9, 0x29, 0x5a, 0xdb, 0x3d, 0x84, 0x52, 0xab, 0xcc, 0x6b, 0x60, 0x9d, 0xb7, 0x4a, 0x0e, 0x36, 0x63, 0x91, 0xad, 0xa0, 0x95, 0xb0, 0x97, 0x89, 0x4e, 0xcf, 0x7d, 0x3c, 0xe5, 0x7c, 0x28}} ,
+ {{0x2e, 0x69, 0x98, 0xfd, 0xc6, 0xbd, 0xcc, 0xca, 0xdf, 0x9a, 0x44, 0x7e, 0x9d, 0xca, 0x89, 0x6d, 0xbf, 0x27, 0xc2, 0xf8, 0xcd, 0x46, 0x00, 0x2b, 0xb5, 0x58, 0x4e, 0xb7, 0x89, 0x09, 0xe9, 0x2d}}},
+{{{0x54, 0xbe, 0x75, 0xcb, 0x05, 0xb0, 0x54, 0xb7, 0xe7, 0x26, 0x86, 0x4a, 0xfc, 0x19, 0xcf, 0x27, 0x46, 0xd4, 0x22, 0x96, 0x5a, 0x11, 0xe8, 0xd5, 0x1b, 0xed, 0x71, 0xc5, 0x5d, 0xc8, 0xaf, 0x45}} ,
+ {{0x40, 0x7b, 0x77, 0x57, 0x49, 0x9e, 0x80, 0x39, 0x23, 0xee, 0x81, 0x0b, 0x22, 0xcf, 0xdb, 0x7a, 0x2f, 0x14, 0xb8, 0x57, 0x8f, 0xa1, 0x39, 0x1e, 0x77, 0xfc, 0x0b, 0xa6, 0xbf, 0x8a, 0x0c, 0x6c}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x77, 0x3a, 0xd4, 0xd8, 0x27, 0xcf, 0xe8, 0xa1, 0x72, 0x9d, 0xca, 0xdd, 0x0d, 0x96, 0xda, 0x79, 0xed, 0x56, 0x42, 0x15, 0x60, 0xc7, 0x1c, 0x6b, 0x26, 0x30, 0xf6, 0x6a, 0x95, 0x67, 0xf3, 0x0a}} ,
+ {{0xc5, 0x08, 0xa4, 0x2b, 0x2f, 0xbd, 0x31, 0x81, 0x2a, 0xa6, 0xb6, 0xe4, 0x00, 0x91, 0xda, 0x3d, 0xb2, 0xb0, 0x96, 0xce, 0x8a, 0xd2, 0x8d, 0x70, 0xb3, 0xd3, 0x34, 0x01, 0x90, 0x8d, 0x10, 0x21}}},
+{{{0x33, 0x0d, 0xe7, 0xba, 0x4f, 0x07, 0xdf, 0x8d, 0xea, 0x7d, 0xa0, 0xc5, 0xd6, 0xb1, 0xb0, 0xe5, 0x57, 0x1b, 0x5b, 0xf5, 0x45, 0x13, 0x14, 0x64, 0x5a, 0xeb, 0x5c, 0xfc, 0x54, 0x01, 0x76, 0x2b}} ,
+ {{0x02, 0x0c, 0xc2, 0xaf, 0x96, 0x36, 0xfe, 0x4a, 0xe2, 0x54, 0x20, 0x6a, 0xeb, 0xb2, 0x9f, 0x62, 0xd7, 0xce, 0xa2, 0x3f, 0x20, 0x11, 0x34, 0x37, 0xe0, 0x42, 0xed, 0x6f, 0xf9, 0x1a, 0xc8, 0x7d}}},
+{{{0xd8, 0xb9, 0x11, 0xe8, 0x36, 0x3f, 0x42, 0xc1, 0xca, 0xdc, 0xd3, 0xf1, 0xc8, 0x23, 0x3d, 0x4f, 0x51, 0x7b, 0x9d, 0x8d, 0xd8, 0xe4, 0xa0, 0xaa, 0xf3, 0x04, 0xd6, 0x11, 0x93, 0xc8, 0x35, 0x45}} ,
+ {{0x61, 0x36, 0xd6, 0x08, 0x90, 0xbf, 0xa7, 0x7a, 0x97, 0x6c, 0x0f, 0x84, 0xd5, 0x33, 0x2d, 0x37, 0xc9, 0x6a, 0x80, 0x90, 0x3d, 0x0a, 0xa2, 0xaa, 0xe1, 0xb8, 0x84, 0xba, 0x61, 0x36, 0xdd, 0x69}}},
+{{{0x6b, 0xdb, 0x5b, 0x9c, 0xc6, 0x92, 0xbc, 0x23, 0xaf, 0xc5, 0xb8, 0x75, 0xf8, 0x42, 0xfa, 0xd6, 0xb6, 0x84, 0x94, 0x63, 0x98, 0x93, 0x48, 0x78, 0x38, 0xcd, 0xbb, 0x18, 0x34, 0xc3, 0xdb, 0x67}} ,
+ {{0x96, 0xf3, 0x3a, 0x09, 0x56, 0xb0, 0x6f, 0x7c, 0x51, 0x1e, 0x1b, 0x39, 0x48, 0xea, 0xc9, 0x0c, 0x25, 0xa2, 0x7a, 0xca, 0xe7, 0x92, 0xfc, 0x59, 0x30, 0xa3, 0x89, 0x85, 0xdf, 0x6f, 0x43, 0x38}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x79, 0x84, 0x44, 0x19, 0xbd, 0xe9, 0x54, 0xc4, 0xc0, 0x6e, 0x2a, 0xa8, 0xa8, 0x9b, 0x43, 0xd5, 0x71, 0x22, 0x5f, 0xdc, 0x01, 0xfa, 0xdf, 0xb3, 0xb8, 0x47, 0x4b, 0x0a, 0xa5, 0x44, 0xea, 0x29}} ,
+ {{0x05, 0x90, 0x50, 0xaf, 0x63, 0x5f, 0x9d, 0x9e, 0xe1, 0x9d, 0x38, 0x97, 0x1f, 0x6c, 0xac, 0x30, 0x46, 0xb2, 0x6a, 0x19, 0xd1, 0x4b, 0xdb, 0xbb, 0x8c, 0xda, 0x2e, 0xab, 0xc8, 0x5a, 0x77, 0x6c}}},
+{{{0x2b, 0xbe, 0xaf, 0xa1, 0x6d, 0x2f, 0x0b, 0xb1, 0x8f, 0xe3, 0xe0, 0x38, 0xcd, 0x0b, 0x41, 0x1b, 0x4a, 0x15, 0x07, 0xf3, 0x6f, 0xdc, 0xb8, 0xe9, 0xde, 0xb2, 0xa3, 0x40, 0x01, 0xa6, 0x45, 0x1e}} ,
+ {{0x76, 0x0a, 0xda, 0x8d, 0x2c, 0x07, 0x3f, 0x89, 0x7d, 0x04, 0xad, 0x43, 0x50, 0x6e, 0xd2, 0x47, 0xcb, 0x8a, 0xe6, 0x85, 0x1a, 0x24, 0xf3, 0xd2, 0x60, 0xfd, 0xdf, 0x73, 0xa4, 0x0d, 0x73, 0x0e}}},
+{{{0xfd, 0x67, 0x6b, 0x71, 0x9b, 0x81, 0x53, 0x39, 0x39, 0xf4, 0xb8, 0xd5, 0xc3, 0x30, 0x9b, 0x3b, 0x7c, 0xa3, 0xf0, 0xd0, 0x84, 0x21, 0xd6, 0xbf, 0xb7, 0x4c, 0x87, 0x13, 0x45, 0x2d, 0xa7, 0x55}} ,
+ {{0x5d, 0x04, 0xb3, 0x40, 0x28, 0x95, 0x2d, 0x30, 0x83, 0xec, 0x5e, 0xe4, 0xff, 0x75, 0xfe, 0x79, 0x26, 0x9d, 0x1d, 0x36, 0xcd, 0x0a, 0x15, 0xd2, 0x24, 0x14, 0x77, 0x71, 0xd7, 0x8a, 0x1b, 0x04}}},
+{{{0x5d, 0x93, 0xc9, 0xbe, 0xaa, 0x90, 0xcd, 0x9b, 0xfb, 0x73, 0x7e, 0xb0, 0x64, 0x98, 0x57, 0x44, 0x42, 0x41, 0xb1, 0xaf, 0xea, 0xc1, 0xc3, 0x22, 0xff, 0x60, 0x46, 0xcb, 0x61, 0x81, 0x70, 0x61}} ,
+ {{0x0d, 0x82, 0xb9, 0xfe, 0x21, 0xcd, 0xc4, 0xf5, 0x98, 0x0c, 0x4e, 0x72, 0xee, 0x87, 0x49, 0xf8, 0xa1, 0x95, 0xdf, 0x8f, 0x2d, 0xbd, 0x21, 0x06, 0x7c, 0x15, 0xe8, 0x12, 0x6d, 0x93, 0xd6, 0x38}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x91, 0xf7, 0x51, 0xd9, 0xef, 0x7d, 0x42, 0x01, 0x13, 0xe9, 0xb8, 0x7f, 0xa6, 0x49, 0x17, 0x64, 0x21, 0x80, 0x83, 0x2c, 0x63, 0x4c, 0x60, 0x09, 0x59, 0x91, 0x92, 0x77, 0x39, 0x51, 0xf4, 0x48}} ,
+ {{0x60, 0xd5, 0x22, 0x83, 0x08, 0x2f, 0xff, 0x99, 0x3e, 0x69, 0x6d, 0x88, 0xda, 0xe7, 0x5b, 0x52, 0x26, 0x31, 0x2a, 0xe5, 0x89, 0xde, 0x68, 0x90, 0xb6, 0x22, 0x5a, 0xbd, 0xd3, 0x85, 0x53, 0x31}}},
+{{{0xd8, 0xce, 0xdc, 0xf9, 0x3c, 0x4b, 0xa2, 0x1d, 0x2c, 0x2f, 0x36, 0xbe, 0x7a, 0xfc, 0xcd, 0xbc, 0xdc, 0xf9, 0x30, 0xbd, 0xff, 0x05, 0xc7, 0xe4, 0x8e, 0x17, 0x62, 0xf8, 0x4d, 0xa0, 0x56, 0x79}} ,
+ {{0x82, 0xe7, 0xf6, 0xba, 0x53, 0x84, 0x0a, 0xa3, 0x34, 0xff, 0x3c, 0xa3, 0x6a, 0xa1, 0x37, 0xea, 0xdd, 0xb6, 0x95, 0xb3, 0x78, 0x19, 0x76, 0x1e, 0x55, 0x2f, 0x77, 0x2e, 0x7f, 0xc1, 0xea, 0x5e}}},
+{{{0x83, 0xe1, 0x6e, 0xa9, 0x07, 0x33, 0x3e, 0x83, 0xff, 0xcb, 0x1c, 0x9f, 0xb1, 0xa3, 0xb4, 0xc9, 0xe1, 0x07, 0x97, 0xff, 0xf8, 0x23, 0x8f, 0xce, 0x40, 0xfd, 0x2e, 0x5e, 0xdb, 0x16, 0x43, 0x2d}} ,
+ {{0xba, 0x38, 0x02, 0xf7, 0x81, 0x43, 0x83, 0xa3, 0x20, 0x4f, 0x01, 0x3b, 0x8a, 0x04, 0x38, 0x31, 0xc6, 0x0f, 0xc8, 0xdf, 0xd7, 0xfa, 0x2f, 0x88, 0x3f, 0xfc, 0x0c, 0x76, 0xc4, 0xa6, 0x45, 0x72}}},
+{{{0xbb, 0x0c, 0xbc, 0x6a, 0xa4, 0x97, 0x17, 0x93, 0x2d, 0x6f, 0xde, 0x72, 0x10, 0x1c, 0x08, 0x2c, 0x0f, 0x80, 0x32, 0x68, 0x27, 0xd4, 0xab, 0xdd, 0xc5, 0x58, 0x61, 0x13, 0x6d, 0x11, 0x1e, 0x4d}} ,
+ {{0x1a, 0xb9, 0xc9, 0x10, 0xfb, 0x1e, 0x4e, 0xf4, 0x84, 0x4b, 0x8a, 0x5e, 0x7b, 0x4b, 0xe8, 0x43, 0x8c, 0x8f, 0x00, 0xb5, 0x54, 0x13, 0xc5, 0x5c, 0xb6, 0x35, 0x4e, 0x9d, 0xe4, 0x5b, 0x41, 0x6d}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x15, 0x7d, 0x12, 0x48, 0x82, 0x14, 0x42, 0xcd, 0x32, 0xd4, 0x4b, 0xc1, 0x72, 0x61, 0x2a, 0x8c, 0xec, 0xe2, 0xf8, 0x24, 0x45, 0x94, 0xe3, 0xbe, 0xdd, 0x67, 0xa8, 0x77, 0x5a, 0xae, 0x5b, 0x4b}} ,
+ {{0xcb, 0x77, 0x9a, 0x20, 0xde, 0xb8, 0x23, 0xd9, 0xa0, 0x0f, 0x8c, 0x7b, 0xa5, 0xcb, 0xae, 0xb6, 0xec, 0x42, 0x67, 0x0e, 0x58, 0xa4, 0x75, 0x98, 0x21, 0x71, 0x84, 0xb3, 0xe0, 0x76, 0x94, 0x73}}},
+{{{0xdf, 0xfc, 0x69, 0x28, 0x23, 0x3f, 0x5b, 0xf8, 0x3b, 0x24, 0x37, 0xf3, 0x1d, 0xd5, 0x22, 0x6b, 0xd0, 0x98, 0xa8, 0x6c, 0xcf, 0xff, 0x06, 0xe1, 0x13, 0xdf, 0xb9, 0xc1, 0x0c, 0xa9, 0xbf, 0x33}} ,
+ {{0xd9, 0x81, 0xda, 0xb2, 0x4f, 0x82, 0x9d, 0x43, 0x81, 0x09, 0xf1, 0xd2, 0x01, 0xef, 0xac, 0xf4, 0x2d, 0x7d, 0x01, 0x09, 0xf1, 0xff, 0xa5, 0x9f, 0xe5, 0xca, 0x27, 0x63, 0xdb, 0x20, 0xb1, 0x53}}},
+{{{0x67, 0x02, 0xe8, 0xad, 0xa9, 0x34, 0xd4, 0xf0, 0x15, 0x81, 0xaa, 0xc7, 0x4d, 0x87, 0x94, 0xea, 0x75, 0xe7, 0x4c, 0x94, 0x04, 0x0e, 0x69, 0x87, 0xe7, 0x51, 0x91, 0x10, 0x03, 0xc7, 0xbe, 0x56}} ,
+ {{0x32, 0xfb, 0x86, 0xec, 0x33, 0x6b, 0x2e, 0x51, 0x2b, 0xc8, 0xfa, 0x6c, 0x70, 0x47, 0x7e, 0xce, 0x05, 0x0c, 0x71, 0xf3, 0xb4, 0x56, 0xa6, 0xdc, 0xcc, 0x78, 0x07, 0x75, 0xd0, 0xdd, 0xb2, 0x6a}}},
+{{{0xc6, 0xef, 0xb9, 0xc0, 0x2b, 0x22, 0x08, 0x1e, 0x71, 0x70, 0xb3, 0x35, 0x9c, 0x7a, 0x01, 0x92, 0x44, 0x9a, 0xf6, 0xb0, 0x58, 0x95, 0xc1, 0x9b, 0x02, 0xed, 0x2d, 0x7c, 0x34, 0x29, 0x49, 0x44}} ,
+ {{0x45, 0x62, 0x1d, 0x2e, 0xff, 0x2a, 0x1c, 0x21, 0xa4, 0x25, 0x7b, 0x0d, 0x8c, 0x15, 0x39, 0xfc, 0x8f, 0x7c, 0xa5, 0x7d, 0x1e, 0x25, 0xa3, 0x45, 0xd6, 0xab, 0xbd, 0xcb, 0xc5, 0x5e, 0x78, 0x77}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0xd0, 0xd3, 0x42, 0xed, 0x1d, 0x00, 0x3c, 0x15, 0x2c, 0x9c, 0x77, 0x81, 0xd2, 0x73, 0xd1, 0x06, 0xd5, 0xc4, 0x7f, 0x94, 0xbb, 0x92, 0x2d, 0x2c, 0x4b, 0x45, 0x4b, 0xe9, 0x2a, 0x89, 0x6b, 0x2b}} ,
+ {{0xd2, 0x0c, 0x88, 0xc5, 0x48, 0x4d, 0xea, 0x0d, 0x4a, 0xc9, 0x52, 0x6a, 0x61, 0x79, 0xe9, 0x76, 0xf3, 0x85, 0x52, 0x5c, 0x1b, 0x2c, 0xe1, 0xd6, 0xc4, 0x0f, 0x18, 0x0e, 0x4e, 0xf6, 0x1c, 0x7f}}},
+{{{0xb4, 0x04, 0x2e, 0x42, 0xcb, 0x1f, 0x2b, 0x11, 0x51, 0x7b, 0x08, 0xac, 0xaa, 0x3e, 0x9e, 0x52, 0x60, 0xb7, 0xc2, 0x61, 0x57, 0x8c, 0x84, 0xd5, 0x18, 0xa6, 0x19, 0xfc, 0xb7, 0x75, 0x91, 0x1b}} ,
+ {{0xe8, 0x68, 0xca, 0x44, 0xc8, 0x38, 0x38, 0xcc, 0x53, 0x0a, 0x32, 0x35, 0xcc, 0x52, 0xcb, 0x0e, 0xf7, 0xc5, 0xe7, 0xec, 0x3d, 0x85, 0xcc, 0x58, 0xe2, 0x17, 0x47, 0xff, 0x9f, 0xa5, 0x30, 0x17}}},
+{{{0xe3, 0xae, 0xc8, 0xc1, 0x71, 0x75, 0x31, 0x00, 0x37, 0x41, 0x5c, 0x0e, 0x39, 0xda, 0x73, 0xa0, 0xc7, 0x97, 0x36, 0x6c, 0x5b, 0xf2, 0xee, 0x64, 0x0a, 0x3d, 0x89, 0x1e, 0x1d, 0x49, 0x8c, 0x37}} ,
+ {{0x4c, 0xe6, 0xb0, 0xc1, 0xa5, 0x2a, 0x82, 0x09, 0x08, 0xad, 0x79, 0x9c, 0x56, 0xf6, 0xf9, 0xc1, 0xd7, 0x7c, 0x39, 0x7f, 0x93, 0xca, 0x11, 0x55, 0xbf, 0x07, 0x1b, 0x82, 0x29, 0x69, 0x95, 0x5c}}},
+{{{0x87, 0xee, 0xa6, 0x56, 0x9e, 0xc2, 0x9a, 0x56, 0x24, 0x42, 0x85, 0x4d, 0x98, 0x31, 0x1e, 0x60, 0x4d, 0x87, 0x85, 0x04, 0xae, 0x46, 0x12, 0xf9, 0x8e, 0x7f, 0xe4, 0x7f, 0xf6, 0x1c, 0x37, 0x01}} ,
+ {{0x73, 0x4c, 0xb6, 0xc5, 0xc4, 0xe9, 0x6c, 0x85, 0x48, 0x4a, 0x5a, 0xac, 0xd9, 0x1f, 0x43, 0xf8, 0x62, 0x5b, 0xee, 0x98, 0x2a, 0x33, 0x8e, 0x79, 0xce, 0x61, 0x06, 0x35, 0xd8, 0xd7, 0xca, 0x71}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x72, 0xd3, 0xae, 0xa6, 0xca, 0x8f, 0xcd, 0xcc, 0x78, 0x8e, 0x19, 0x4d, 0xa7, 0xd2, 0x27, 0xe9, 0xa4, 0x3c, 0x16, 0x5b, 0x84, 0x80, 0xf9, 0xd0, 0xcc, 0x6a, 0x1e, 0xca, 0x1e, 0x67, 0xbd, 0x63}} ,
+ {{0x7b, 0x6e, 0x2a, 0xd2, 0x87, 0x48, 0xff, 0xa1, 0xca, 0xe9, 0x15, 0x85, 0xdc, 0xdb, 0x2c, 0x39, 0x12, 0x91, 0xa9, 0x20, 0xaa, 0x4f, 0x29, 0xf4, 0x15, 0x7a, 0xd2, 0xf5, 0x32, 0xcc, 0x60, 0x04}}},
+{{{0xe5, 0x10, 0x47, 0x3b, 0xfa, 0x90, 0xfc, 0x30, 0xb5, 0xea, 0x6f, 0x56, 0x8f, 0xfb, 0x0e, 0xa7, 0x3b, 0xc8, 0xb2, 0xff, 0x02, 0x7a, 0x33, 0x94, 0x93, 0x2a, 0x03, 0xe0, 0x96, 0x3a, 0x6c, 0x0f}} ,
+ {{0x5a, 0x63, 0x67, 0xe1, 0x9b, 0x47, 0x78, 0x9f, 0x38, 0x79, 0xac, 0x97, 0x66, 0x1d, 0x5e, 0x51, 0xee, 0x24, 0x42, 0xe8, 0x58, 0x4b, 0x8a, 0x03, 0x75, 0x86, 0x37, 0x86, 0xe2, 0x97, 0x4e, 0x3d}}},
+{{{0x3f, 0x75, 0x8e, 0xb4, 0xff, 0xd8, 0xdd, 0xd6, 0x37, 0x57, 0x9d, 0x6d, 0x3b, 0xbd, 0xd5, 0x60, 0x88, 0x65, 0x9a, 0xb9, 0x4a, 0x68, 0x84, 0xa2, 0x67, 0xdd, 0x17, 0x25, 0x97, 0x04, 0x8b, 0x5e}} ,
+ {{0xbb, 0x40, 0x5e, 0xbc, 0x16, 0x92, 0x05, 0xc4, 0xc0, 0x4e, 0x72, 0x90, 0x0e, 0xab, 0xcf, 0x8a, 0xed, 0xef, 0xb9, 0x2d, 0x3b, 0xf8, 0x43, 0x5b, 0xba, 0x2d, 0xeb, 0x2f, 0x52, 0xd2, 0xd1, 0x5a}}},
+{{{0x40, 0xb4, 0xab, 0xe6, 0xad, 0x9f, 0x46, 0x69, 0x4a, 0xb3, 0x8e, 0xaa, 0xea, 0x9c, 0x8a, 0x20, 0x16, 0x5d, 0x8c, 0x13, 0xbd, 0xf6, 0x1d, 0xc5, 0x24, 0xbd, 0x90, 0x2a, 0x1c, 0xc7, 0x13, 0x3b}} ,
+ {{0x54, 0xdc, 0x16, 0x0d, 0x18, 0xbe, 0x35, 0x64, 0x61, 0x52, 0x02, 0x80, 0xaf, 0x05, 0xf7, 0xa6, 0x42, 0xd3, 0x8f, 0x2e, 0x79, 0x26, 0xa8, 0xbb, 0xb2, 0x17, 0x48, 0xb2, 0x7a, 0x0a, 0x89, 0x14}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x20, 0xa8, 0x88, 0xe3, 0x91, 0xc0, 0x6e, 0xbb, 0x8a, 0x27, 0x82, 0x51, 0x83, 0xb2, 0x28, 0xa9, 0x83, 0xeb, 0xa6, 0xa9, 0x4d, 0x17, 0x59, 0x22, 0x54, 0x00, 0x50, 0x45, 0xcb, 0x48, 0x4b, 0x18}} ,
+ {{0x33, 0x7c, 0xe7, 0x26, 0xba, 0x4d, 0x32, 0xfe, 0x53, 0xf4, 0xfa, 0x83, 0xe3, 0xa5, 0x79, 0x66, 0x73, 0xef, 0x80, 0x23, 0x68, 0xc2, 0x60, 0xdd, 0xa9, 0x33, 0xdc, 0x03, 0x7a, 0xe0, 0xe0, 0x3e}}},
+{{{0x34, 0x5c, 0x13, 0xfb, 0xc0, 0xe3, 0x78, 0x2b, 0x54, 0x58, 0x22, 0x9b, 0x76, 0x81, 0x7f, 0x93, 0x9c, 0x25, 0x3c, 0xd2, 0xe9, 0x96, 0x21, 0x26, 0x08, 0xf5, 0xed, 0x95, 0x11, 0xae, 0x04, 0x5a}} ,
+ {{0xb9, 0xe8, 0xc5, 0x12, 0x97, 0x1f, 0x83, 0xfe, 0x3e, 0x94, 0x99, 0xd4, 0x2d, 0xf9, 0x52, 0x59, 0x5c, 0x82, 0xa6, 0xf0, 0x75, 0x7e, 0xe8, 0xec, 0xcc, 0xac, 0x18, 0x21, 0x09, 0x67, 0x66, 0x67}}},
+{{{0xb3, 0x40, 0x29, 0xd1, 0xcb, 0x1b, 0x08, 0x9e, 0x9c, 0xb7, 0x53, 0xb9, 0x3b, 0x71, 0x08, 0x95, 0x12, 0x1a, 0x58, 0xaf, 0x7e, 0x82, 0x52, 0x43, 0x4f, 0x11, 0x39, 0xf4, 0x93, 0x1a, 0x26, 0x05}} ,
+ {{0x6e, 0x44, 0xa3, 0xf9, 0x64, 0xaf, 0xe7, 0x6d, 0x7d, 0xdf, 0x1e, 0xac, 0x04, 0xea, 0x3b, 0x5f, 0x9b, 0xe8, 0x24, 0x9d, 0x0e, 0xe5, 0x2e, 0x3e, 0xdf, 0xa9, 0xf7, 0xd4, 0x50, 0x71, 0xf0, 0x78}}},
+{{{0x3e, 0xa8, 0x38, 0xc2, 0x57, 0x56, 0x42, 0x9a, 0xb1, 0xe2, 0xf8, 0x45, 0xaa, 0x11, 0x48, 0x5f, 0x17, 0xc4, 0x54, 0x27, 0xdc, 0x5d, 0xaa, 0xdd, 0x41, 0xbc, 0xdf, 0x81, 0xb9, 0x53, 0xee, 0x52}} ,
+ {{0xc3, 0xf1, 0xa7, 0x6d, 0xb3, 0x5f, 0x92, 0x6f, 0xcc, 0x91, 0xb8, 0x95, 0x05, 0xdf, 0x3c, 0x64, 0x57, 0x39, 0x61, 0x51, 0xad, 0x8c, 0x38, 0x7b, 0xc8, 0xde, 0x00, 0x34, 0xbe, 0xa1, 0xb0, 0x7e}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x25, 0x24, 0x1d, 0x8a, 0x67, 0x20, 0xee, 0x42, 0xeb, 0x38, 0xed, 0x0b, 0x8b, 0xcd, 0x46, 0x9d, 0x5e, 0x6b, 0x1e, 0x24, 0x9d, 0x12, 0x05, 0x1a, 0xcc, 0x05, 0x4e, 0x92, 0x38, 0xe1, 0x1f, 0x50}} ,
+ {{0x4e, 0xee, 0x1c, 0x91, 0xe6, 0x11, 0xbd, 0x8e, 0x55, 0x1a, 0x18, 0x75, 0x66, 0xaf, 0x4d, 0x7b, 0x0f, 0xae, 0x6d, 0x85, 0xca, 0x82, 0x58, 0x21, 0x9c, 0x18, 0xe0, 0xed, 0xec, 0x22, 0x80, 0x2f}}},
+{{{0x68, 0x3b, 0x0a, 0x39, 0x1d, 0x6a, 0x15, 0x57, 0xfc, 0xf0, 0x63, 0x54, 0xdb, 0x39, 0xdb, 0xe8, 0x5c, 0x64, 0xff, 0xa0, 0x09, 0x4f, 0x3b, 0xb7, 0x32, 0x60, 0x99, 0x94, 0xfd, 0x94, 0x82, 0x2d}} ,
+ {{0x24, 0xf6, 0x5a, 0x44, 0xf1, 0x55, 0x2c, 0xdb, 0xea, 0x7c, 0x84, 0x7c, 0x01, 0xac, 0xe3, 0xfd, 0xc9, 0x27, 0xc1, 0x5a, 0xb9, 0xde, 0x4f, 0x5a, 0x90, 0xdd, 0xc6, 0x67, 0xaa, 0x6f, 0x8a, 0x3a}}},
+{{{0x78, 0x52, 0x87, 0xc9, 0x97, 0x63, 0xb1, 0xdd, 0x54, 0x5f, 0xc1, 0xf8, 0xf1, 0x06, 0xa6, 0xa8, 0xa3, 0x88, 0x82, 0xd4, 0xcb, 0xa6, 0x19, 0xdd, 0xd1, 0x11, 0x87, 0x08, 0x17, 0x4c, 0x37, 0x2a}} ,
+ {{0xa1, 0x0c, 0xf3, 0x08, 0x43, 0xd9, 0x24, 0x1e, 0x83, 0xa7, 0xdf, 0x91, 0xca, 0xbd, 0x69, 0x47, 0x8d, 0x1b, 0xe2, 0xb9, 0x4e, 0xb5, 0xe1, 0x76, 0xb3, 0x1c, 0x93, 0x03, 0xce, 0x5f, 0xb3, 0x5a}}},
+{{{0x1d, 0xda, 0xe4, 0x61, 0x03, 0x50, 0xa9, 0x8b, 0x68, 0x18, 0xef, 0xb2, 0x1c, 0x84, 0x3b, 0xa2, 0x44, 0x95, 0xa3, 0x04, 0x3b, 0xd6, 0x99, 0x00, 0xaf, 0x76, 0x42, 0x67, 0x02, 0x7d, 0x85, 0x56}} ,
+ {{0xce, 0x72, 0x0e, 0x29, 0x84, 0xb2, 0x7d, 0xd2, 0x45, 0xbe, 0x57, 0x06, 0xed, 0x7f, 0xcf, 0xed, 0xcd, 0xef, 0x19, 0xd6, 0xbc, 0x15, 0x79, 0x64, 0xd2, 0x18, 0xe3, 0x20, 0x67, 0x3a, 0x54, 0x0b}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x52, 0xfd, 0x04, 0xc5, 0xfb, 0x99, 0xe7, 0xe8, 0xfb, 0x8c, 0xe1, 0x42, 0x03, 0xef, 0x9d, 0xd9, 0x9e, 0x4d, 0xf7, 0x80, 0xcf, 0x2e, 0xcc, 0x9b, 0x45, 0xc9, 0x7b, 0x7a, 0xbc, 0x37, 0xa8, 0x52}} ,
+ {{0x96, 0x11, 0x41, 0x8a, 0x47, 0x91, 0xfe, 0xb6, 0xda, 0x7a, 0x54, 0x63, 0xd1, 0x14, 0x35, 0x05, 0x86, 0x8c, 0xa9, 0x36, 0x3f, 0xf2, 0x85, 0x54, 0x4e, 0x92, 0xd8, 0x85, 0x01, 0x46, 0xd6, 0x50}}},
+{{{0x53, 0xcd, 0xf3, 0x86, 0x40, 0xe6, 0x39, 0x42, 0x95, 0xd6, 0xcb, 0x45, 0x1a, 0x20, 0xc8, 0x45, 0x4b, 0x32, 0x69, 0x04, 0xb1, 0xaf, 0x20, 0x46, 0xc7, 0x6b, 0x23, 0x5b, 0x69, 0xee, 0x30, 0x3f}} ,
+ {{0x70, 0x83, 0x47, 0xc0, 0xdb, 0x55, 0x08, 0xa8, 0x7b, 0x18, 0x6d, 0xf5, 0x04, 0x5a, 0x20, 0x0c, 0x4a, 0x8c, 0x60, 0xae, 0xae, 0x0f, 0x64, 0x55, 0x55, 0x2e, 0xd5, 0x1d, 0x53, 0x31, 0x42, 0x41}}},
+{{{0xca, 0xfc, 0x88, 0x6b, 0x96, 0x78, 0x0a, 0x8b, 0x83, 0xdc, 0xbc, 0xaf, 0x40, 0xb6, 0x8d, 0x7f, 0xef, 0xb4, 0xd1, 0x3f, 0xcc, 0xa2, 0x74, 0xc9, 0xc2, 0x92, 0x55, 0x00, 0xab, 0xdb, 0xbf, 0x4f}} ,
+ {{0x93, 0x1c, 0x06, 0x2d, 0x66, 0x65, 0x02, 0xa4, 0x97, 0x18, 0xfd, 0x00, 0xe7, 0xab, 0x03, 0xec, 0xce, 0xc1, 0xbf, 0x37, 0xf8, 0x13, 0x53, 0xa5, 0xe5, 0x0c, 0x3a, 0xa8, 0x55, 0xb9, 0xff, 0x68}}},
+{{{0xe4, 0xe6, 0x6d, 0x30, 0x7d, 0x30, 0x35, 0xc2, 0x78, 0x87, 0xf9, 0xfc, 0x6b, 0x5a, 0xc3, 0xb7, 0x65, 0xd8, 0x2e, 0xc7, 0xa5, 0x0c, 0xc6, 0xdc, 0x12, 0xaa, 0xd6, 0x4f, 0xc5, 0x38, 0xbc, 0x0e}} ,
+ {{0xe2, 0x3c, 0x76, 0x86, 0x38, 0xf2, 0x7b, 0x2c, 0x16, 0x78, 0x8d, 0xf5, 0xa4, 0x15, 0xda, 0xdb, 0x26, 0x85, 0xa0, 0x56, 0xdd, 0x1d, 0xe3, 0xb3, 0xfd, 0x40, 0xef, 0xf2, 0xd9, 0xa1, 0xb3, 0x04}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0xdb, 0x49, 0x0e, 0xe6, 0x58, 0x10, 0x7a, 0x52, 0xda, 0xb5, 0x7d, 0x37, 0x6a, 0x3e, 0xa1, 0x78, 0xce, 0xc7, 0x1c, 0x24, 0x23, 0xdb, 0x7d, 0xfb, 0x8c, 0x8d, 0xdc, 0x30, 0x67, 0x69, 0x75, 0x3b}} ,
+ {{0xa9, 0xea, 0x6d, 0x16, 0x16, 0x60, 0xf4, 0x60, 0x87, 0x19, 0x44, 0x8c, 0x4a, 0x8b, 0x3e, 0xfb, 0x16, 0x00, 0x00, 0x54, 0xa6, 0x9e, 0x9f, 0xef, 0xcf, 0xd9, 0xd2, 0x4c, 0x74, 0x31, 0xd0, 0x34}}},
+{{{0xa4, 0xeb, 0x04, 0xa4, 0x8c, 0x8f, 0x71, 0x27, 0x95, 0x85, 0x5d, 0x55, 0x4b, 0xb1, 0x26, 0x26, 0xc8, 0xae, 0x6a, 0x7d, 0xa2, 0x21, 0xca, 0xce, 0x38, 0xab, 0x0f, 0xd0, 0xd5, 0x2b, 0x6b, 0x00}} ,
+ {{0xe5, 0x67, 0x0c, 0xf1, 0x3a, 0x9a, 0xea, 0x09, 0x39, 0xef, 0xd1, 0x30, 0xbc, 0x33, 0xba, 0xb1, 0x6a, 0xc5, 0x27, 0x08, 0x7f, 0x54, 0x80, 0x3d, 0xab, 0xf6, 0x15, 0x7a, 0xc2, 0x40, 0x73, 0x72}}},
+{{{0x84, 0x56, 0x82, 0xb6, 0x12, 0x70, 0x7f, 0xf7, 0xf0, 0xbd, 0x5b, 0xa9, 0xd5, 0xc5, 0x5f, 0x59, 0xbf, 0x7f, 0xb3, 0x55, 0x22, 0x02, 0xc9, 0x44, 0x55, 0x87, 0x8f, 0x96, 0x98, 0x64, 0x6d, 0x15}} ,
+ {{0xb0, 0x8b, 0xaa, 0x1e, 0xec, 0xc7, 0xa5, 0x8f, 0x1f, 0x92, 0x04, 0xc6, 0x05, 0xf6, 0xdf, 0xa1, 0xcc, 0x1f, 0x81, 0xf5, 0x0e, 0x9c, 0x57, 0xdc, 0xe3, 0xbb, 0x06, 0x87, 0x1e, 0xfe, 0x23, 0x6c}}},
+{{{0xd8, 0x2b, 0x5b, 0x16, 0xea, 0x20, 0xf1, 0xd3, 0x68, 0x8f, 0xae, 0x5b, 0xd0, 0xa9, 0x1a, 0x19, 0xa8, 0x36, 0xfb, 0x2b, 0x57, 0x88, 0x7d, 0x90, 0xd5, 0xa6, 0xf3, 0xdc, 0x38, 0x89, 0x4e, 0x1f}} ,
+ {{0xcc, 0x19, 0xda, 0x9b, 0x3b, 0x43, 0x48, 0x21, 0x2e, 0x23, 0x4d, 0x3d, 0xae, 0xf8, 0x8c, 0xfc, 0xdd, 0xa6, 0x74, 0x37, 0x65, 0xca, 0xee, 0x1a, 0x19, 0x8e, 0x9f, 0x64, 0x6f, 0x0c, 0x8b, 0x5a}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x25, 0xb9, 0xc2, 0xf0, 0x72, 0xb8, 0x15, 0x16, 0xcc, 0x8d, 0x3c, 0x6f, 0x25, 0xed, 0xf4, 0x46, 0x2e, 0x0c, 0x60, 0x0f, 0xe2, 0x84, 0x34, 0x55, 0x89, 0x59, 0x34, 0x1b, 0xf5, 0x8d, 0xfe, 0x08}} ,
+ {{0xf8, 0xab, 0x93, 0xbc, 0x44, 0xba, 0x1b, 0x75, 0x4b, 0x49, 0x6f, 0xd0, 0x54, 0x2e, 0x63, 0xba, 0xb5, 0xea, 0xed, 0x32, 0x14, 0xc9, 0x94, 0xd8, 0xc5, 0xce, 0xf4, 0x10, 0x68, 0xe0, 0x38, 0x27}}},
+{{{0x74, 0x1c, 0x14, 0x9b, 0xd4, 0x64, 0x61, 0x71, 0x5a, 0xb6, 0x21, 0x33, 0x4f, 0xf7, 0x8e, 0xba, 0xa5, 0x48, 0x9a, 0xc7, 0xfa, 0x9a, 0xf0, 0xb4, 0x62, 0xad, 0xf2, 0x5e, 0xcc, 0x03, 0x24, 0x1a}} ,
+ {{0xf5, 0x76, 0xfd, 0xe4, 0xaf, 0xb9, 0x03, 0x59, 0xce, 0x63, 0xd2, 0x3b, 0x1f, 0xcd, 0x21, 0x0c, 0xad, 0x44, 0xa5, 0x97, 0xac, 0x80, 0x11, 0x02, 0x9b, 0x0c, 0xe5, 0x8b, 0xcd, 0xfb, 0x79, 0x77}}},
+{{{0x15, 0xbe, 0x9a, 0x0d, 0xba, 0x38, 0x72, 0x20, 0x8a, 0xf5, 0xbe, 0x59, 0x93, 0x79, 0xb7, 0xf6, 0x6a, 0x0c, 0x38, 0x27, 0x1a, 0x60, 0xf4, 0x86, 0x3b, 0xab, 0x5a, 0x00, 0xa0, 0xce, 0x21, 0x7d}} ,
+ {{0x6c, 0xba, 0x14, 0xc5, 0xea, 0x12, 0x9e, 0x2e, 0x82, 0x63, 0xce, 0x9b, 0x4a, 0xe7, 0x1d, 0xec, 0xf1, 0x2e, 0x51, 0x1c, 0xf4, 0xd0, 0x69, 0x15, 0x42, 0x9d, 0xa3, 0x3f, 0x0e, 0xbf, 0xe9, 0x5c}}},
+{{{0xe4, 0x0d, 0xf4, 0xbd, 0xee, 0x31, 0x10, 0xed, 0xcb, 0x12, 0x86, 0xad, 0xd4, 0x2f, 0x90, 0x37, 0x32, 0xc3, 0x0b, 0x73, 0xec, 0x97, 0x85, 0xa4, 0x01, 0x1c, 0x76, 0x35, 0xfe, 0x75, 0xdd, 0x71}} ,
+ {{0x11, 0xa4, 0x88, 0x9f, 0x3e, 0x53, 0x69, 0x3b, 0x1b, 0xe0, 0xf7, 0xba, 0x9b, 0xad, 0x4e, 0x81, 0x5f, 0xb5, 0x5c, 0xae, 0xbe, 0x67, 0x86, 0x37, 0x34, 0x8e, 0x07, 0x32, 0x45, 0x4a, 0x67, 0x39}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x90, 0x70, 0x58, 0x20, 0x03, 0x1e, 0x67, 0xb2, 0xc8, 0x9b, 0x58, 0xc5, 0xb1, 0xeb, 0x2d, 0x4a, 0xde, 0x82, 0x8c, 0xf2, 0xd2, 0x14, 0xb8, 0x70, 0x61, 0x4e, 0x73, 0xd6, 0x0b, 0x6b, 0x0d, 0x30}} ,
+ {{0x81, 0xfc, 0x55, 0x5c, 0xbf, 0xa7, 0xc4, 0xbd, 0xe2, 0xf0, 0x4b, 0x8f, 0xe9, 0x7d, 0x99, 0xfa, 0xd3, 0xab, 0xbc, 0xc7, 0x83, 0x2b, 0x04, 0x7f, 0x0c, 0x19, 0x43, 0x03, 0x3d, 0x07, 0xca, 0x40}}},
+{{{0xf9, 0xc8, 0xbe, 0x8c, 0x16, 0x81, 0x39, 0x96, 0xf6, 0x17, 0x58, 0xc8, 0x30, 0x58, 0xfb, 0xc2, 0x03, 0x45, 0xd2, 0x52, 0x76, 0xe0, 0x6a, 0x26, 0x28, 0x5c, 0x88, 0x59, 0x6a, 0x5a, 0x54, 0x42}} ,
+ {{0x07, 0xb5, 0x2e, 0x2c, 0x67, 0x15, 0x9b, 0xfb, 0x83, 0x69, 0x1e, 0x0f, 0xda, 0xd6, 0x29, 0xb1, 0x60, 0xe0, 0xb2, 0xba, 0x69, 0xa2, 0x9e, 0xbd, 0xbd, 0xe0, 0x1c, 0xbd, 0xcd, 0x06, 0x64, 0x70}}},
+{{{0x41, 0xfa, 0x8c, 0xe1, 0x89, 0x8f, 0x27, 0xc8, 0x25, 0x8f, 0x6f, 0x5f, 0x55, 0xf8, 0xde, 0x95, 0x6d, 0x2f, 0x75, 0x16, 0x2b, 0x4e, 0x44, 0xfd, 0x86, 0x6e, 0xe9, 0x70, 0x39, 0x76, 0x97, 0x7e}} ,
+ {{0x17, 0x62, 0x6b, 0x14, 0xa1, 0x7c, 0xd0, 0x79, 0x6e, 0xd8, 0x8a, 0xa5, 0x6d, 0x8c, 0x93, 0xd2, 0x3f, 0xec, 0x44, 0x8d, 0x6e, 0x91, 0x01, 0x8c, 0x8f, 0xee, 0x01, 0x8f, 0xc0, 0xb4, 0x85, 0x0e}}},
+{{{0x02, 0x3a, 0x70, 0x41, 0xe4, 0x11, 0x57, 0x23, 0xac, 0xe6, 0xfc, 0x54, 0x7e, 0xcd, 0xd7, 0x22, 0xcb, 0x76, 0x9f, 0x20, 0xce, 0xa0, 0x73, 0x76, 0x51, 0x3b, 0xa4, 0xf8, 0xe3, 0x62, 0x12, 0x6c}} ,
+ {{0x7f, 0x00, 0x9c, 0x26, 0x0d, 0x6f, 0x48, 0x7f, 0x3a, 0x01, 0xed, 0xc5, 0x96, 0xb0, 0x1f, 0x4f, 0xa8, 0x02, 0x62, 0x27, 0x8a, 0x50, 0x8d, 0x9a, 0x8b, 0x52, 0x0f, 0x1e, 0xcf, 0x41, 0x38, 0x19}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0xf5, 0x6c, 0xd4, 0x2f, 0x0f, 0x69, 0x0f, 0x87, 0x3f, 0x61, 0x65, 0x1e, 0x35, 0x34, 0x85, 0xba, 0x02, 0x30, 0xac, 0x25, 0x3d, 0xe2, 0x62, 0xf1, 0xcc, 0xe9, 0x1b, 0xc2, 0xef, 0x6a, 0x42, 0x57}} ,
+ {{0x34, 0x1f, 0x2e, 0xac, 0xd1, 0xc7, 0x04, 0x52, 0x32, 0x66, 0xb2, 0x33, 0x73, 0x21, 0x34, 0x54, 0xf7, 0x71, 0xed, 0x06, 0xb0, 0xff, 0xa6, 0x59, 0x6f, 0x8a, 0x4e, 0xfb, 0x02, 0xb0, 0x45, 0x6b}}},
+{{{0xf5, 0x48, 0x0b, 0x03, 0xc5, 0x22, 0x7d, 0x80, 0x08, 0x53, 0xfe, 0x32, 0xb1, 0xa1, 0x8a, 0x74, 0x6f, 0xbd, 0x3f, 0x85, 0xf4, 0xcf, 0xf5, 0x60, 0xaf, 0x41, 0x7e, 0x3e, 0x46, 0xa3, 0x5a, 0x20}} ,
+ {{0xaa, 0x35, 0x87, 0x44, 0x63, 0x66, 0x97, 0xf8, 0x6e, 0x55, 0x0c, 0x04, 0x3e, 0x35, 0x50, 0xbf, 0x93, 0x69, 0xd2, 0x8b, 0x05, 0x55, 0x99, 0xbe, 0xe2, 0x53, 0x61, 0xec, 0xe8, 0x08, 0x0b, 0x32}}},
+{{{0xb3, 0x10, 0x45, 0x02, 0x69, 0x59, 0x2e, 0x97, 0xd9, 0x64, 0xf8, 0xdb, 0x25, 0x80, 0xdc, 0xc4, 0xd5, 0x62, 0x3c, 0xed, 0x65, 0x91, 0xad, 0xd1, 0x57, 0x81, 0x94, 0xaa, 0xa1, 0x29, 0xfc, 0x68}} ,
+ {{0xdd, 0xb5, 0x7d, 0xab, 0x5a, 0x21, 0x41, 0x53, 0xbb, 0x17, 0x79, 0x0d, 0xd1, 0xa8, 0x0c, 0x0c, 0x20, 0x88, 0x09, 0xe9, 0x84, 0xe8, 0x25, 0x11, 0x67, 0x7a, 0x8b, 0x1a, 0xe4, 0x5d, 0xe1, 0x5d}}},
+{{{0x37, 0xea, 0xfe, 0x65, 0x3b, 0x25, 0xe8, 0xe1, 0xc2, 0xc5, 0x02, 0xa4, 0xbe, 0x98, 0x0a, 0x2b, 0x61, 0xc1, 0x9b, 0xe2, 0xd5, 0x92, 0xe6, 0x9e, 0x7d, 0x1f, 0xca, 0x43, 0x88, 0x8b, 0x2c, 0x59}} ,
+ {{0xe0, 0xb5, 0x00, 0x1d, 0x2a, 0x6f, 0xaf, 0x79, 0x86, 0x2f, 0xa6, 0x5a, 0x93, 0xd1, 0xfe, 0xae, 0x3a, 0xee, 0xdb, 0x7c, 0x61, 0xbe, 0x7c, 0x01, 0xf9, 0xfe, 0x52, 0xdc, 0xd8, 0x52, 0xa3, 0x42}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x22, 0xaf, 0x13, 0x37, 0xbd, 0x37, 0x71, 0xac, 0x04, 0x46, 0x63, 0xac, 0xa4, 0x77, 0xed, 0x25, 0x38, 0xe0, 0x15, 0xa8, 0x64, 0x00, 0x0d, 0xce, 0x51, 0x01, 0xa9, 0xbc, 0x0f, 0x03, 0x1c, 0x04}} ,
+ {{0x89, 0xf9, 0x80, 0x07, 0xcf, 0x3f, 0xb3, 0xe9, 0xe7, 0x45, 0x44, 0x3d, 0x2a, 0x7c, 0xe9, 0xe4, 0x16, 0x5c, 0x5e, 0x65, 0x1c, 0xc7, 0x7d, 0xc6, 0x7a, 0xfb, 0x43, 0xee, 0x25, 0x76, 0x46, 0x72}}},
+{{{0x02, 0xa2, 0xed, 0xf4, 0x8f, 0x6b, 0x0b, 0x3e, 0xeb, 0x35, 0x1a, 0xd5, 0x7e, 0xdb, 0x78, 0x00, 0x96, 0x8a, 0xa0, 0xb4, 0xcf, 0x60, 0x4b, 0xd4, 0xd5, 0xf9, 0x2d, 0xbf, 0x88, 0xbd, 0x22, 0x62}} ,
+ {{0x13, 0x53, 0xe4, 0x82, 0x57, 0xfa, 0x1e, 0x8f, 0x06, 0x2b, 0x90, 0xba, 0x08, 0xb6, 0x10, 0x54, 0x4f, 0x7c, 0x1b, 0x26, 0xed, 0xda, 0x6b, 0xdd, 0x25, 0xd0, 0x4e, 0xea, 0x42, 0xbb, 0x25, 0x03}}},
+{{{0x51, 0x16, 0x50, 0x7c, 0xd5, 0x5d, 0xf6, 0x99, 0xe8, 0x77, 0x72, 0x4e, 0xfa, 0x62, 0xcb, 0x76, 0x75, 0x0c, 0xe2, 0x71, 0x98, 0x92, 0xd5, 0xfa, 0x45, 0xdf, 0x5c, 0x6f, 0x1e, 0x9e, 0x28, 0x69}} ,
+ {{0x0d, 0xac, 0x66, 0x6d, 0xc3, 0x8b, 0xba, 0x16, 0xb5, 0xe2, 0xa0, 0x0d, 0x0c, 0xbd, 0xa4, 0x8e, 0x18, 0x6c, 0xf2, 0xdc, 0xf9, 0xdc, 0x4a, 0x86, 0x25, 0x95, 0x14, 0xcb, 0xd8, 0x1a, 0x04, 0x0f}}},
+{{{0x97, 0xa5, 0xdb, 0x8b, 0x2d, 0xaa, 0x42, 0x11, 0x09, 0xf2, 0x93, 0xbb, 0xd9, 0x06, 0x84, 0x4e, 0x11, 0xa8, 0xa0, 0x25, 0x2b, 0xa6, 0x5f, 0xae, 0xc4, 0xb4, 0x4c, 0xc8, 0xab, 0xc7, 0x3b, 0x02}} ,
+ {{0xee, 0xc9, 0x29, 0x0f, 0xdf, 0x11, 0x85, 0xed, 0xce, 0x0d, 0x62, 0x2c, 0x8f, 0x4b, 0xf9, 0x04, 0xe9, 0x06, 0x72, 0x1d, 0x37, 0x20, 0x50, 0xc9, 0x14, 0xeb, 0xec, 0x39, 0xa7, 0x97, 0x2b, 0x4d}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x69, 0xd1, 0x39, 0xbd, 0xfb, 0x33, 0xbe, 0xc4, 0xf0, 0x5c, 0xef, 0xf0, 0x56, 0x68, 0xfc, 0x97, 0x47, 0xc8, 0x72, 0xb6, 0x53, 0xa4, 0x0a, 0x98, 0xa5, 0xb4, 0x37, 0x71, 0xcf, 0x66, 0x50, 0x6d}} ,
+ {{0x17, 0xa4, 0x19, 0x52, 0x11, 0x47, 0xb3, 0x5c, 0x5b, 0xa9, 0x2e, 0x22, 0xb4, 0x00, 0x52, 0xf9, 0x57, 0x18, 0xb8, 0xbe, 0x5a, 0xe3, 0xab, 0x83, 0xc8, 0x87, 0x0a, 0x2a, 0xd8, 0x8c, 0xbb, 0x54}}},
+{{{0xa9, 0x62, 0x93, 0x85, 0xbe, 0xe8, 0x73, 0x4a, 0x0e, 0xb0, 0xb5, 0x2d, 0x94, 0x50, 0xaa, 0xd3, 0xb2, 0xea, 0x9d, 0x62, 0x76, 0x3b, 0x07, 0x34, 0x4e, 0x2d, 0x70, 0xc8, 0x9a, 0x15, 0x66, 0x6b}} ,
+ {{0xc5, 0x96, 0xca, 0xc8, 0x22, 0x1a, 0xee, 0x5f, 0xe7, 0x31, 0x60, 0x22, 0x83, 0x08, 0x63, 0xce, 0xb9, 0x32, 0x44, 0x58, 0x5d, 0x3a, 0x9b, 0xe4, 0x04, 0xd5, 0xef, 0x38, 0xef, 0x4b, 0xdd, 0x19}}},
+{{{0x4d, 0xc2, 0x17, 0x75, 0xa1, 0x68, 0xcd, 0xc3, 0xc6, 0x03, 0x44, 0xe3, 0x78, 0x09, 0x91, 0x47, 0x3f, 0x0f, 0xe4, 0x92, 0x58, 0xfa, 0x7d, 0x1f, 0x20, 0x94, 0x58, 0x5e, 0xbc, 0x19, 0x02, 0x6f}} ,
+ {{0x20, 0xd6, 0xd8, 0x91, 0x54, 0xa7, 0xf3, 0x20, 0x4b, 0x34, 0x06, 0xfa, 0x30, 0xc8, 0x6f, 0x14, 0x10, 0x65, 0x74, 0x13, 0x4e, 0xf0, 0x69, 0x26, 0xce, 0xcf, 0x90, 0xf4, 0xd0, 0xc5, 0xc8, 0x64}}},
+{{{0x26, 0xa2, 0x50, 0x02, 0x24, 0x72, 0xf1, 0xf0, 0x4e, 0x2d, 0x93, 0xd5, 0x08, 0xe7, 0xae, 0x38, 0xf7, 0x18, 0xa5, 0x32, 0x34, 0xc2, 0xf0, 0xa6, 0xec, 0xb9, 0x61, 0x7b, 0x64, 0x99, 0xac, 0x71}} ,
+ {{0x25, 0xcf, 0x74, 0x55, 0x1b, 0xaa, 0xa9, 0x38, 0x41, 0x40, 0xd5, 0x95, 0x95, 0xab, 0x1c, 0x5e, 0xbc, 0x41, 0x7e, 0x14, 0x30, 0xbe, 0x13, 0x89, 0xf4, 0xe5, 0xeb, 0x28, 0xc0, 0xc2, 0x96, 0x3a}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x2b, 0x77, 0x45, 0xec, 0x67, 0x76, 0x32, 0x4c, 0xb9, 0xdf, 0x25, 0x32, 0x6b, 0xcb, 0xe7, 0x14, 0x61, 0x43, 0xee, 0xba, 0x9b, 0x71, 0xef, 0xd2, 0x48, 0x65, 0xbb, 0x1b, 0x8a, 0x13, 0x1b, 0x22}} ,
+ {{0x84, 0xad, 0x0c, 0x18, 0x38, 0x5a, 0xba, 0xd0, 0x98, 0x59, 0xbf, 0x37, 0xb0, 0x4f, 0x97, 0x60, 0x20, 0xb3, 0x9b, 0x97, 0xf6, 0x08, 0x6c, 0xa4, 0xff, 0xfb, 0xb7, 0xfa, 0x95, 0xb2, 0x51, 0x79}}},
+{{{0x28, 0x5c, 0x3f, 0xdb, 0x6b, 0x18, 0x3b, 0x5c, 0xd1, 0x04, 0x28, 0xde, 0x85, 0x52, 0x31, 0xb5, 0xbb, 0xf6, 0xa9, 0xed, 0xbe, 0x28, 0x4f, 0xb3, 0x7e, 0x05, 0x6a, 0xdb, 0x95, 0x0d, 0x1b, 0x1c}} ,
+ {{0xd5, 0xc5, 0xc3, 0x9a, 0x0a, 0xd0, 0x31, 0x3e, 0x07, 0x36, 0x8e, 0xc0, 0x8a, 0x62, 0xb1, 0xca, 0xd6, 0x0e, 0x1e, 0x9d, 0xef, 0xab, 0x98, 0x4d, 0xbb, 0x6c, 0x05, 0xe0, 0xe4, 0x5d, 0xbd, 0x57}}},
+{{{0xcc, 0x21, 0x27, 0xce, 0xfd, 0xa9, 0x94, 0x8e, 0xe1, 0xab, 0x49, 0xe0, 0x46, 0x26, 0xa1, 0xa8, 0x8c, 0xa1, 0x99, 0x1d, 0xb4, 0x27, 0x6d, 0x2d, 0xc8, 0x39, 0x30, 0x5e, 0x37, 0x52, 0xc4, 0x6e}} ,
+ {{0xa9, 0x85, 0xf4, 0xe7, 0xb0, 0x15, 0x33, 0x84, 0x1b, 0x14, 0x1a, 0x02, 0xd9, 0x3b, 0xad, 0x0f, 0x43, 0x6c, 0xea, 0x3e, 0x0f, 0x7e, 0xda, 0xdd, 0x6b, 0x4c, 0x7f, 0x6e, 0xd4, 0x6b, 0xbf, 0x0f}}},
+{{{0x47, 0x9f, 0x7c, 0x56, 0x7c, 0x43, 0x91, 0x1c, 0xbb, 0x4e, 0x72, 0x3e, 0x64, 0xab, 0xa0, 0xa0, 0xdf, 0xb4, 0xd8, 0x87, 0x3a, 0xbd, 0xa8, 0x48, 0xc9, 0xb8, 0xef, 0x2e, 0xad, 0x6f, 0x84, 0x4f}} ,
+ {{0x2d, 0x2d, 0xf0, 0x1b, 0x7e, 0x2a, 0x6c, 0xf8, 0xa9, 0x6a, 0xe1, 0xf0, 0x99, 0xa1, 0x67, 0x9a, 0xd4, 0x13, 0xca, 0xca, 0xba, 0x27, 0x92, 0xaa, 0xa1, 0x5d, 0x50, 0xde, 0xcc, 0x40, 0x26, 0x0a}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x9f, 0x3e, 0xf2, 0xb2, 0x90, 0xce, 0xdb, 0x64, 0x3e, 0x03, 0xdd, 0x37, 0x36, 0x54, 0x70, 0x76, 0x24, 0xb5, 0x69, 0x03, 0xfc, 0xa0, 0x2b, 0x74, 0xb2, 0x05, 0x0e, 0xcc, 0xd8, 0x1f, 0x6a, 0x1f}} ,
+ {{0x19, 0x5e, 0x60, 0x69, 0x58, 0x86, 0xa0, 0x31, 0xbd, 0x32, 0xe9, 0x2c, 0x5c, 0xd2, 0x85, 0xba, 0x40, 0x64, 0xa8, 0x74, 0xf8, 0x0e, 0x1c, 0xb3, 0xa9, 0x69, 0xe8, 0x1e, 0x40, 0x64, 0x99, 0x77}}},
+{{{0x6c, 0x32, 0x4f, 0xfd, 0xbb, 0x5c, 0xbb, 0x8d, 0x64, 0x66, 0x4a, 0x71, 0x1f, 0x79, 0xa3, 0xad, 0x8d, 0xf9, 0xd4, 0xec, 0xcf, 0x67, 0x70, 0xfa, 0x05, 0x4a, 0x0f, 0x6e, 0xaf, 0x87, 0x0a, 0x6f}} ,
+ {{0xc6, 0x36, 0x6e, 0x6c, 0x8c, 0x24, 0x09, 0x60, 0xbe, 0x26, 0xd2, 0x4c, 0x5e, 0x17, 0xca, 0x5f, 0x1d, 0xcc, 0x87, 0xe8, 0x42, 0x6a, 0xcb, 0xcb, 0x7d, 0x92, 0x05, 0x35, 0x81, 0x13, 0x60, 0x6b}}},
+{{{0xf4, 0x15, 0xcd, 0x0f, 0x0a, 0xaf, 0x4e, 0x6b, 0x51, 0xfd, 0x14, 0xc4, 0x2e, 0x13, 0x86, 0x74, 0x44, 0xcb, 0x66, 0x6b, 0xb6, 0x9d, 0x74, 0x56, 0x32, 0xac, 0x8d, 0x8e, 0x8c, 0x8c, 0x8c, 0x39}} ,
+ {{0xca, 0x59, 0x74, 0x1a, 0x11, 0xef, 0x6d, 0xf7, 0x39, 0x5c, 0x3b, 0x1f, 0xfa, 0xe3, 0x40, 0x41, 0x23, 0x9e, 0xf6, 0xd1, 0x21, 0xa2, 0xbf, 0xad, 0x65, 0x42, 0x6b, 0x59, 0x8a, 0xe8, 0xc5, 0x7f}}},
+{{{0x64, 0x05, 0x7a, 0x84, 0x4a, 0x13, 0xc3, 0xf6, 0xb0, 0x6e, 0x9a, 0x6b, 0x53, 0x6b, 0x32, 0xda, 0xd9, 0x74, 0x75, 0xc4, 0xba, 0x64, 0x3d, 0x3b, 0x08, 0xdd, 0x10, 0x46, 0xef, 0xc7, 0x90, 0x1f}} ,
+ {{0x7b, 0x2f, 0x3a, 0xce, 0xc8, 0xa1, 0x79, 0x3c, 0x30, 0x12, 0x44, 0x28, 0xf6, 0xbc, 0xff, 0xfd, 0xf4, 0xc0, 0x97, 0xb0, 0xcc, 0xc3, 0x13, 0x7a, 0xb9, 0x9a, 0x16, 0xe4, 0xcb, 0x4c, 0x34, 0x63}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x07, 0x4e, 0xd3, 0x2d, 0x09, 0x33, 0x0e, 0xd2, 0x0d, 0xbe, 0x3e, 0xe7, 0xe4, 0xaa, 0xb7, 0x00, 0x8b, 0xe8, 0xad, 0xaa, 0x7a, 0x8d, 0x34, 0x28, 0xa9, 0x81, 0x94, 0xc5, 0xe7, 0x42, 0xac, 0x47}} ,
+ {{0x24, 0x89, 0x7a, 0x8f, 0xb5, 0x9b, 0xf0, 0xc2, 0x03, 0x64, 0xd0, 0x1e, 0xf5, 0xa4, 0xb2, 0xf3, 0x74, 0xe9, 0x1a, 0x16, 0xfd, 0xcb, 0x15, 0xea, 0xeb, 0x10, 0x6c, 0x35, 0xd1, 0xc1, 0xa6, 0x28}}},
+{{{0xcc, 0xd5, 0x39, 0xfc, 0xa5, 0xa4, 0xad, 0x32, 0x15, 0xce, 0x19, 0xe8, 0x34, 0x2b, 0x1c, 0x60, 0x91, 0xfc, 0x05, 0xa9, 0xb3, 0xdc, 0x80, 0x29, 0xc4, 0x20, 0x79, 0x06, 0x39, 0xc0, 0xe2, 0x22}} ,
+ {{0xbb, 0xa8, 0xe1, 0x89, 0x70, 0x57, 0x18, 0x54, 0x3c, 0xf6, 0x0d, 0x82, 0x12, 0x05, 0x87, 0x96, 0x06, 0x39, 0xe3, 0xf8, 0xb3, 0x95, 0xe5, 0xd7, 0x26, 0xbf, 0x09, 0x5a, 0x94, 0xf9, 0x1c, 0x63}}},
+{{{0x2b, 0x8c, 0x2d, 0x9a, 0x8b, 0x84, 0xf2, 0x56, 0xfb, 0xad, 0x2e, 0x7f, 0xb7, 0xfc, 0x30, 0xe1, 0x35, 0x89, 0xba, 0x4d, 0xa8, 0x6d, 0xce, 0x8c, 0x8b, 0x30, 0xe0, 0xda, 0x29, 0x18, 0x11, 0x17}} ,
+ {{0x19, 0xa6, 0x5a, 0x65, 0x93, 0xc3, 0xb5, 0x31, 0x22, 0x4f, 0xf3, 0xf6, 0x0f, 0xeb, 0x28, 0xc3, 0x7c, 0xeb, 0xce, 0x86, 0xec, 0x67, 0x76, 0x6e, 0x35, 0x45, 0x7b, 0xd8, 0x6b, 0x92, 0x01, 0x65}}},
+{{{0x3d, 0xd5, 0x9a, 0x64, 0x73, 0x36, 0xb1, 0xd6, 0x86, 0x98, 0x42, 0x3f, 0x8a, 0xf1, 0xc7, 0xf5, 0x42, 0xa8, 0x9c, 0x52, 0xa8, 0xdc, 0xf9, 0x24, 0x3f, 0x4a, 0xa1, 0xa4, 0x5b, 0xe8, 0x62, 0x1a}} ,
+ {{0xc5, 0xbd, 0xc8, 0x14, 0xd5, 0x0d, 0xeb, 0xe1, 0xa5, 0xe6, 0x83, 0x11, 0x09, 0x00, 0x1d, 0x55, 0x83, 0x51, 0x7e, 0x75, 0x00, 0x81, 0xb9, 0xcb, 0xd8, 0xc5, 0xe5, 0xa1, 0xd9, 0x17, 0x6d, 0x1f}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0xea, 0xf9, 0xe4, 0xe9, 0xe1, 0x52, 0x3f, 0x51, 0x19, 0x0d, 0xdd, 0xd9, 0x9d, 0x93, 0x31, 0x87, 0x23, 0x09, 0xd5, 0x83, 0xeb, 0x92, 0x09, 0x76, 0x6e, 0xe3, 0xf8, 0xc0, 0xa2, 0x66, 0xb5, 0x36}} ,
+ {{0x3a, 0xbb, 0x39, 0xed, 0x32, 0x02, 0xe7, 0x43, 0x7a, 0x38, 0x14, 0x84, 0xe3, 0x44, 0xd2, 0x5e, 0x94, 0xdd, 0x78, 0x89, 0x55, 0x4c, 0x73, 0x9e, 0xe1, 0xe4, 0x3e, 0x43, 0xd0, 0x4a, 0xde, 0x1b}}},
+{{{0xb2, 0xe7, 0x8f, 0xe3, 0xa3, 0xc5, 0xcb, 0x72, 0xee, 0x79, 0x41, 0xf8, 0xdf, 0xee, 0x65, 0xc5, 0x45, 0x77, 0x27, 0x3c, 0xbd, 0x58, 0xd3, 0x75, 0xe2, 0x04, 0x4b, 0xbb, 0x65, 0xf3, 0xc8, 0x0f}} ,
+ {{0x24, 0x7b, 0x93, 0x34, 0xb5, 0xe2, 0x74, 0x48, 0xcd, 0xa0, 0x0b, 0x92, 0x97, 0x66, 0x39, 0xf4, 0xb0, 0xe2, 0x5d, 0x39, 0x6a, 0x5b, 0x45, 0x17, 0x78, 0x1e, 0xdb, 0x91, 0x81, 0x1c, 0xf9, 0x16}}},
+{{{0x16, 0xdf, 0xd1, 0x5a, 0xd5, 0xe9, 0x4e, 0x58, 0x95, 0x93, 0x5f, 0x51, 0x09, 0xc3, 0x2a, 0xc9, 0xd4, 0x55, 0x48, 0x79, 0xa4, 0xa3, 0xb2, 0xc3, 0x62, 0xaa, 0x8c, 0xe8, 0xad, 0x47, 0x39, 0x1b}} ,
+ {{0x46, 0xda, 0x9e, 0x51, 0x3a, 0xe6, 0xd1, 0xa6, 0xbb, 0x4d, 0x7b, 0x08, 0xbe, 0x8c, 0xd5, 0xf3, 0x3f, 0xfd, 0xf7, 0x44, 0x80, 0x2d, 0x53, 0x4b, 0xd0, 0x87, 0x68, 0xc1, 0xb5, 0xd8, 0xf7, 0x07}}},
+{{{0xf4, 0x10, 0x46, 0xbe, 0xb7, 0xd2, 0xd1, 0xce, 0x5e, 0x76, 0xa2, 0xd7, 0x03, 0xdc, 0xe4, 0x81, 0x5a, 0xf6, 0x3c, 0xde, 0xae, 0x7a, 0x9d, 0x21, 0x34, 0xa5, 0xf6, 0xa9, 0x73, 0xe2, 0x8d, 0x60}} ,
+ {{0xfa, 0x44, 0x71, 0xf6, 0x41, 0xd8, 0xc6, 0x58, 0x13, 0x37, 0xeb, 0x84, 0x0f, 0x96, 0xc7, 0xdc, 0xc8, 0xa9, 0x7a, 0x83, 0xb2, 0x2f, 0x31, 0xb1, 0x1a, 0xd8, 0x98, 0x3f, 0x11, 0xd0, 0x31, 0x3b}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x81, 0xd5, 0x34, 0x16, 0x01, 0xa3, 0x93, 0xea, 0x52, 0x94, 0xec, 0x93, 0xb7, 0x81, 0x11, 0x2d, 0x58, 0xf9, 0xb5, 0x0a, 0xaa, 0x4f, 0xf6, 0x2e, 0x3f, 0x36, 0xbf, 0x33, 0x5a, 0xe7, 0xd1, 0x08}} ,
+ {{0x1a, 0xcf, 0x42, 0xae, 0xcc, 0xb5, 0x77, 0x39, 0xc4, 0x5b, 0x5b, 0xd0, 0x26, 0x59, 0x27, 0xd0, 0x55, 0x71, 0x12, 0x9d, 0x88, 0x3d, 0x9c, 0xea, 0x41, 0x6a, 0xf0, 0x50, 0x93, 0x93, 0xdd, 0x47}}},
+{{{0x6f, 0xc9, 0x51, 0x6d, 0x1c, 0xaa, 0xf5, 0xa5, 0x90, 0x3f, 0x14, 0xe2, 0x6e, 0x8e, 0x64, 0xfd, 0xac, 0xe0, 0x4e, 0x22, 0xe5, 0xc1, 0xbc, 0x29, 0x0a, 0x6a, 0x9e, 0xa1, 0x60, 0xcb, 0x2f, 0x0b}} ,
+ {{0xdc, 0x39, 0x32, 0xf3, 0xa1, 0x44, 0xe9, 0xc5, 0xc3, 0x78, 0xfb, 0x95, 0x47, 0x34, 0x35, 0x34, 0xe8, 0x25, 0xde, 0x93, 0xc6, 0xb4, 0x76, 0x6d, 0x86, 0x13, 0xc6, 0xe9, 0x68, 0xb5, 0x01, 0x63}}},
+{{{0x1f, 0x9a, 0x52, 0x64, 0x97, 0xd9, 0x1c, 0x08, 0x51, 0x6f, 0x26, 0x9d, 0xaa, 0x93, 0x33, 0x43, 0xfa, 0x77, 0xe9, 0x62, 0x9b, 0x5d, 0x18, 0x75, 0xeb, 0x78, 0xf7, 0x87, 0x8f, 0x41, 0xb4, 0x4d}} ,
+ {{0x13, 0xa8, 0x82, 0x3e, 0xe9, 0x13, 0xad, 0xeb, 0x01, 0xca, 0xcf, 0xda, 0xcd, 0xf7, 0x6c, 0xc7, 0x7a, 0xdc, 0x1e, 0x6e, 0xc8, 0x4e, 0x55, 0x62, 0x80, 0xea, 0x78, 0x0c, 0x86, 0xb9, 0x40, 0x51}}},
+{{{0x27, 0xae, 0xd3, 0x0d, 0x4c, 0x8f, 0x34, 0xea, 0x7d, 0x3c, 0xe5, 0x8a, 0xcf, 0x5b, 0x92, 0xd8, 0x30, 0x16, 0xb4, 0xa3, 0x75, 0xff, 0xeb, 0x27, 0xc8, 0x5c, 0x6c, 0xc2, 0xee, 0x6c, 0x21, 0x0b}} ,
+ {{0xc3, 0xba, 0x12, 0x53, 0x2a, 0xaa, 0x77, 0xad, 0x19, 0x78, 0x55, 0x8a, 0x2e, 0x60, 0x87, 0xc2, 0x6e, 0x91, 0x38, 0x91, 0x3f, 0x7a, 0xc5, 0x24, 0x8f, 0x51, 0xc5, 0xde, 0xb0, 0x53, 0x30, 0x56}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x02, 0xfe, 0x54, 0x12, 0x18, 0xca, 0x7d, 0xa5, 0x68, 0x43, 0xa3, 0x6d, 0x14, 0x2a, 0x6a, 0xa5, 0x8e, 0x32, 0xe7, 0x63, 0x4f, 0xe3, 0xc6, 0x44, 0x3e, 0xab, 0x63, 0xca, 0x17, 0x86, 0x74, 0x3f}} ,
+ {{0x1e, 0x64, 0xc1, 0x7d, 0x52, 0xdc, 0x13, 0x5a, 0xa1, 0x9c, 0x4e, 0xee, 0x99, 0x28, 0xbb, 0x4c, 0xee, 0xac, 0xa9, 0x1b, 0x89, 0xa2, 0x38, 0x39, 0x7b, 0xc4, 0x0f, 0x42, 0xe6, 0x89, 0xed, 0x0f}}},
+{{{0xf3, 0x3c, 0x8c, 0x80, 0x83, 0x10, 0x8a, 0x37, 0x50, 0x9c, 0xb4, 0xdf, 0x3f, 0x8c, 0xf7, 0x23, 0x07, 0xd6, 0xff, 0xa0, 0x82, 0x6c, 0x75, 0x3b, 0xe4, 0xb5, 0xbb, 0xe4, 0xe6, 0x50, 0xf0, 0x08}} ,
+ {{0x62, 0xee, 0x75, 0x48, 0x92, 0x33, 0xf2, 0xf4, 0xad, 0x15, 0x7a, 0xa1, 0x01, 0x46, 0xa9, 0x32, 0x06, 0x88, 0xb6, 0x36, 0x47, 0x35, 0xb9, 0xb4, 0x42, 0x85, 0x76, 0xf0, 0x48, 0x00, 0x90, 0x38}}},
+{{{0x51, 0x15, 0x9d, 0xc3, 0x95, 0xd1, 0x39, 0xbb, 0x64, 0x9d, 0x15, 0x81, 0xc1, 0x68, 0xd0, 0xb6, 0xa4, 0x2c, 0x7d, 0x5e, 0x02, 0x39, 0x00, 0xe0, 0x3b, 0xa4, 0xcc, 0xca, 0x1d, 0x81, 0x24, 0x10}} ,
+ {{0xe7, 0x29, 0xf9, 0x37, 0xd9, 0x46, 0x5a, 0xcd, 0x70, 0xfe, 0x4d, 0x5b, 0xbf, 0xa5, 0xcf, 0x91, 0xf4, 0xef, 0xee, 0x8a, 0x29, 0xd0, 0xe7, 0xc4, 0x25, 0x92, 0x8a, 0xff, 0x36, 0xfc, 0xe4, 0x49}}},
+{{{0xbd, 0x00, 0xb9, 0x04, 0x7d, 0x35, 0xfc, 0xeb, 0xd0, 0x0b, 0x05, 0x32, 0x52, 0x7a, 0x89, 0x24, 0x75, 0x50, 0xe1, 0x63, 0x02, 0x82, 0x8e, 0xe7, 0x85, 0x0c, 0xf2, 0x56, 0x44, 0x37, 0x83, 0x25}} ,
+ {{0x8f, 0xa1, 0xce, 0xcb, 0x60, 0xda, 0x12, 0x02, 0x1e, 0x29, 0x39, 0x2a, 0x03, 0xb7, 0xeb, 0x77, 0x40, 0xea, 0xc9, 0x2b, 0x2c, 0xd5, 0x7d, 0x7e, 0x2c, 0xc7, 0x5a, 0xfd, 0xff, 0xc4, 0xd1, 0x62}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x1d, 0x88, 0x98, 0x5b, 0x4e, 0xfc, 0x41, 0x24, 0x05, 0xe6, 0x50, 0x2b, 0xae, 0x96, 0x51, 0xd9, 0x6b, 0x72, 0xb2, 0x33, 0x42, 0x98, 0x68, 0xbb, 0x10, 0x5a, 0x7a, 0x8c, 0x9d, 0x07, 0xb4, 0x05}} ,
+ {{0x2f, 0x61, 0x9f, 0xd7, 0xa8, 0x3f, 0x83, 0x8c, 0x10, 0x69, 0x90, 0xe6, 0xcf, 0xd2, 0x63, 0xa3, 0xe4, 0x54, 0x7e, 0xe5, 0x69, 0x13, 0x1c, 0x90, 0x57, 0xaa, 0xe9, 0x53, 0x22, 0x43, 0x29, 0x23}}},
+{{{0xe5, 0x1c, 0xf8, 0x0a, 0xfd, 0x2d, 0x7e, 0xf5, 0xf5, 0x70, 0x7d, 0x41, 0x6b, 0x11, 0xfe, 0xbe, 0x99, 0xd1, 0x55, 0x29, 0x31, 0xbf, 0xc0, 0x97, 0x6c, 0xd5, 0x35, 0xcc, 0x5e, 0x8b, 0xd9, 0x69}} ,
+ {{0x8e, 0x4e, 0x9f, 0x25, 0xf8, 0x81, 0x54, 0x2d, 0x0e, 0xd5, 0x54, 0x81, 0x9b, 0xa6, 0x92, 0xce, 0x4b, 0xe9, 0x8f, 0x24, 0x3b, 0xca, 0xe0, 0x44, 0xab, 0x36, 0xfe, 0xfb, 0x87, 0xd4, 0x26, 0x3e}}},
+{{{0x0f, 0x93, 0x9c, 0x11, 0xe7, 0xdb, 0xf1, 0xf0, 0x85, 0x43, 0x28, 0x15, 0x37, 0xdd, 0xde, 0x27, 0xdf, 0xad, 0x3e, 0x49, 0x4f, 0xe0, 0x5b, 0xf6, 0x80, 0x59, 0x15, 0x3c, 0x85, 0xb7, 0x3e, 0x12}} ,
+ {{0xf5, 0xff, 0xcc, 0xf0, 0xb4, 0x12, 0x03, 0x5f, 0xc9, 0x84, 0xcb, 0x1d, 0x17, 0xe0, 0xbc, 0xcc, 0x03, 0x62, 0xa9, 0x8b, 0x94, 0xa6, 0xaa, 0x18, 0xcb, 0x27, 0x8d, 0x49, 0xa6, 0x17, 0x15, 0x07}}},
+{{{0xd9, 0xb6, 0xd4, 0x9d, 0xd4, 0x6a, 0xaf, 0x70, 0x07, 0x2c, 0x10, 0x9e, 0xbd, 0x11, 0xad, 0xe4, 0x26, 0x33, 0x70, 0x92, 0x78, 0x1c, 0x74, 0x9f, 0x75, 0x60, 0x56, 0xf4, 0x39, 0xa8, 0xa8, 0x62}} ,
+ {{0x3b, 0xbf, 0x55, 0x35, 0x61, 0x8b, 0x44, 0x97, 0xe8, 0x3a, 0x55, 0xc1, 0xc8, 0x3b, 0xfd, 0x95, 0x29, 0x11, 0x60, 0x96, 0x1e, 0xcb, 0x11, 0x9d, 0xc2, 0x03, 0x8a, 0x1b, 0xc6, 0xd6, 0x45, 0x3d}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x7e, 0x0e, 0x50, 0xb2, 0xcc, 0x0d, 0x6b, 0xa6, 0x71, 0x5b, 0x42, 0xed, 0xbd, 0xaf, 0xac, 0xf0, 0xfc, 0x12, 0xa2, 0x3f, 0x4e, 0xda, 0xe8, 0x11, 0xf3, 0x23, 0xe1, 0x04, 0x62, 0x03, 0x1c, 0x4e}} ,
+ {{0xc8, 0xb1, 0x1b, 0x6f, 0x73, 0x61, 0x3d, 0x27, 0x0d, 0x7d, 0x7a, 0x25, 0x5f, 0x73, 0x0e, 0x2f, 0x93, 0xf6, 0x24, 0xd8, 0x4f, 0x90, 0xac, 0xa2, 0x62, 0x0a, 0xf0, 0x61, 0xd9, 0x08, 0x59, 0x6a}}},
+{{{0x6f, 0x2d, 0x55, 0xf8, 0x2f, 0x8e, 0xf0, 0x18, 0x3b, 0xea, 0xdd, 0x26, 0x72, 0xd1, 0xf5, 0xfe, 0xe5, 0xb8, 0xe6, 0xd3, 0x10, 0x48, 0x46, 0x49, 0x3a, 0x9f, 0x5e, 0x45, 0x6b, 0x90, 0xe8, 0x7f}} ,
+ {{0xd3, 0x76, 0x69, 0x33, 0x7b, 0xb9, 0x40, 0x70, 0xee, 0xa6, 0x29, 0x6b, 0xdd, 0xd0, 0x5d, 0x8d, 0xc1, 0x3e, 0x4a, 0xea, 0x37, 0xb1, 0x03, 0x02, 0x03, 0x35, 0xf1, 0x28, 0x9d, 0xff, 0x00, 0x13}}},
+{{{0x7a, 0xdb, 0x12, 0xd2, 0x8a, 0x82, 0x03, 0x1b, 0x1e, 0xaf, 0xf9, 0x4b, 0x9c, 0xbe, 0xae, 0x7c, 0xe4, 0x94, 0x2a, 0x23, 0xb3, 0x62, 0x86, 0xe7, 0xfd, 0x23, 0xaa, 0x99, 0xbd, 0x2b, 0x11, 0x6c}} ,
+ {{0x8d, 0xa6, 0xd5, 0xac, 0x9d, 0xcc, 0x68, 0x75, 0x7f, 0xc3, 0x4d, 0x4b, 0xdd, 0x6c, 0xbb, 0x11, 0x5a, 0x60, 0xe5, 0xbd, 0x7d, 0x27, 0x8b, 0xda, 0xb4, 0x95, 0xf6, 0x03, 0x27, 0xa4, 0x92, 0x3f}}},
+{{{0x22, 0xd6, 0xb5, 0x17, 0x84, 0xbf, 0x12, 0xcc, 0x23, 0x14, 0x4a, 0xdf, 0x14, 0x31, 0xbc, 0xa1, 0xac, 0x6e, 0xab, 0xfa, 0x57, 0x11, 0x53, 0xb3, 0x27, 0xe6, 0xf9, 0x47, 0x33, 0x44, 0x34, 0x1e}} ,
+ {{0x79, 0xfc, 0xa6, 0xb4, 0x0b, 0x35, 0x20, 0xc9, 0x4d, 0x22, 0x84, 0xc4, 0xa9, 0x20, 0xec, 0x89, 0x94, 0xba, 0x66, 0x56, 0x48, 0xb9, 0x87, 0x7f, 0xca, 0x1e, 0x06, 0xed, 0xa5, 0x55, 0x59, 0x29}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x56, 0xe1, 0xf5, 0xf1, 0xd5, 0xab, 0xa8, 0x2b, 0xae, 0x89, 0xf3, 0xcf, 0x56, 0x9f, 0xf2, 0x4b, 0x31, 0xbc, 0x18, 0xa9, 0x06, 0x5b, 0xbe, 0xb4, 0x61, 0xf8, 0xb2, 0x06, 0x9c, 0x81, 0xab, 0x4c}} ,
+ {{0x1f, 0x68, 0x76, 0x01, 0x16, 0x38, 0x2b, 0x0f, 0x77, 0x97, 0x92, 0x67, 0x4e, 0x86, 0x6a, 0x8b, 0xe5, 0xe8, 0x0c, 0xf7, 0x36, 0x39, 0xb5, 0x33, 0xe6, 0xcf, 0x5e, 0xbd, 0x18, 0xfb, 0x10, 0x1f}}},
+{{{0x83, 0xf0, 0x0d, 0x63, 0xef, 0x53, 0x6b, 0xb5, 0x6b, 0xf9, 0x83, 0xcf, 0xde, 0x04, 0x22, 0x9b, 0x2c, 0x0a, 0xe0, 0xa5, 0xd8, 0xc7, 0x9c, 0xa5, 0xa3, 0xf6, 0x6f, 0xcf, 0x90, 0x6b, 0x68, 0x7c}} ,
+ {{0x33, 0x15, 0xd7, 0x7f, 0x1a, 0xd5, 0x21, 0x58, 0xc4, 0x18, 0xa5, 0xf0, 0xcc, 0x73, 0xa8, 0xfd, 0xfa, 0x18, 0xd1, 0x03, 0x91, 0x8d, 0x52, 0xd2, 0xa3, 0xa4, 0xd3, 0xb1, 0xea, 0x1d, 0x0f, 0x00}}},
+{{{0xcc, 0x48, 0x83, 0x90, 0xe5, 0xfd, 0x3f, 0x84, 0xaa, 0xf9, 0x8b, 0x82, 0x59, 0x24, 0x34, 0x68, 0x4f, 0x1c, 0x23, 0xd9, 0xcc, 0x71, 0xe1, 0x7f, 0x8c, 0xaf, 0xf1, 0xee, 0x00, 0xb6, 0xa0, 0x77}} ,
+ {{0xf5, 0x1a, 0x61, 0xf7, 0x37, 0x9d, 0x00, 0xf4, 0xf2, 0x69, 0x6f, 0x4b, 0x01, 0x85, 0x19, 0x45, 0x4d, 0x7f, 0x02, 0x7c, 0x6a, 0x05, 0x47, 0x6c, 0x1f, 0x81, 0x20, 0xd4, 0xe8, 0x50, 0x27, 0x72}}},
+{{{0x2c, 0x3a, 0xe5, 0xad, 0xf4, 0xdd, 0x2d, 0xf7, 0x5c, 0x44, 0xb5, 0x5b, 0x21, 0xa3, 0x89, 0x5f, 0x96, 0x45, 0xca, 0x4d, 0xa4, 0x21, 0x99, 0x70, 0xda, 0xc4, 0xc4, 0xa0, 0xe5, 0xf4, 0xec, 0x0a}} ,
+ {{0x07, 0x68, 0x21, 0x65, 0xe9, 0x08, 0xa0, 0x0b, 0x6a, 0x4a, 0xba, 0xb5, 0x80, 0xaf, 0xd0, 0x1b, 0xc5, 0xf5, 0x4b, 0x73, 0x50, 0x60, 0x2d, 0x71, 0x69, 0x61, 0x0e, 0xc0, 0x20, 0x40, 0x30, 0x19}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0xd0, 0x75, 0x57, 0x3b, 0xeb, 0x5c, 0x14, 0x56, 0x50, 0xc9, 0x4f, 0xb8, 0xb8, 0x1e, 0xa3, 0xf4, 0xab, 0xf5, 0xa9, 0x20, 0x15, 0x94, 0x82, 0xda, 0x96, 0x1c, 0x9b, 0x59, 0x8c, 0xff, 0xf4, 0x51}} ,
+ {{0xc1, 0x3a, 0x86, 0xd7, 0xb0, 0x06, 0x84, 0x7f, 0x1b, 0xbd, 0xd4, 0x07, 0x78, 0x80, 0x2e, 0xb1, 0xb4, 0xee, 0x52, 0x38, 0xee, 0x9a, 0xf9, 0xf6, 0xf3, 0x41, 0x6e, 0xd4, 0x88, 0x95, 0xac, 0x35}}},
+{{{0x41, 0x97, 0xbf, 0x71, 0x6a, 0x9b, 0x72, 0xec, 0xf3, 0xf8, 0x6b, 0xe6, 0x0e, 0x6c, 0x69, 0xa5, 0x2f, 0x68, 0x52, 0xd8, 0x61, 0x81, 0xc0, 0x63, 0x3f, 0xa6, 0x3c, 0x13, 0x90, 0xe6, 0x8d, 0x56}} ,
+ {{0xe8, 0x39, 0x30, 0x77, 0x23, 0xb1, 0xfd, 0x1b, 0x3d, 0x3e, 0x74, 0x4d, 0x7f, 0xae, 0x5b, 0x3a, 0xb4, 0x65, 0x0e, 0x3a, 0x43, 0xdc, 0xdc, 0x41, 0x47, 0xe6, 0xe8, 0x92, 0x09, 0x22, 0x48, 0x4c}}},
+{{{0x85, 0x57, 0x9f, 0xb5, 0xc8, 0x06, 0xb2, 0x9f, 0x47, 0x3f, 0xf0, 0xfa, 0xe6, 0xa9, 0xb1, 0x9b, 0x6f, 0x96, 0x7d, 0xf9, 0xa4, 0x65, 0x09, 0x75, 0x32, 0xa6, 0x6c, 0x7f, 0x47, 0x4b, 0x2f, 0x4f}} ,
+ {{0x34, 0xe9, 0x59, 0x93, 0x9d, 0x26, 0x80, 0x54, 0xf2, 0xcc, 0x3c, 0xc2, 0x25, 0x85, 0xe3, 0x6a, 0xc1, 0x62, 0x04, 0xa7, 0x08, 0x32, 0x6d, 0xa1, 0x39, 0x84, 0x8a, 0x3b, 0x87, 0x5f, 0x11, 0x13}}},
+{{{0xda, 0x03, 0x34, 0x66, 0xc4, 0x0c, 0x73, 0x6e, 0xbc, 0x24, 0xb5, 0xf9, 0x70, 0x81, 0x52, 0xe9, 0xf4, 0x7c, 0x23, 0xdd, 0x9f, 0xb8, 0x46, 0xef, 0x1d, 0x22, 0x55, 0x7d, 0x71, 0xc4, 0x42, 0x33}} ,
+ {{0xc5, 0x37, 0x69, 0x5b, 0xa8, 0xc6, 0x9d, 0xa4, 0xfc, 0x61, 0x6e, 0x68, 0x46, 0xea, 0xd7, 0x1c, 0x67, 0xd2, 0x7d, 0xfa, 0xf1, 0xcc, 0x54, 0x8d, 0x36, 0x35, 0xc9, 0x00, 0xdf, 0x6c, 0x67, 0x50}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x9a, 0x4d, 0x42, 0x29, 0x5d, 0xa4, 0x6b, 0x6f, 0xa8, 0x8a, 0x4d, 0x91, 0x7b, 0xd2, 0xdf, 0x36, 0xef, 0x01, 0x22, 0xc5, 0xcc, 0x8d, 0xeb, 0x58, 0x3d, 0xb3, 0x50, 0xfc, 0x8b, 0x97, 0x96, 0x33}} ,
+ {{0x93, 0x33, 0x07, 0xc8, 0x4a, 0xca, 0xd0, 0xb1, 0xab, 0xbd, 0xdd, 0xa7, 0x7c, 0xac, 0x3e, 0x45, 0xcb, 0xcc, 0x07, 0x91, 0xbf, 0x35, 0x9d, 0xcb, 0x7d, 0x12, 0x3c, 0x11, 0x59, 0x13, 0xcf, 0x5c}}},
+{{{0x45, 0xb8, 0x41, 0xd7, 0xab, 0x07, 0x15, 0x00, 0x8e, 0xce, 0xdf, 0xb2, 0x43, 0x5c, 0x01, 0xdc, 0xf4, 0x01, 0x51, 0x95, 0x10, 0x5a, 0xf6, 0x24, 0x24, 0xa0, 0x19, 0x3a, 0x09, 0x2a, 0xaa, 0x3f}} ,
+ {{0xdc, 0x8e, 0xeb, 0xc6, 0xbf, 0xdd, 0x11, 0x7b, 0xe7, 0x47, 0xe6, 0xce, 0xe7, 0xb6, 0xc5, 0xe8, 0x8a, 0xdc, 0x4b, 0x57, 0x15, 0x3b, 0x66, 0xca, 0x89, 0xa3, 0xfd, 0xac, 0x0d, 0xe1, 0x1d, 0x7a}}},
+{{{0x89, 0xef, 0xbf, 0x03, 0x75, 0xd0, 0x29, 0x50, 0xcb, 0x7d, 0xd6, 0xbe, 0xad, 0x5f, 0x7b, 0x00, 0x32, 0xaa, 0x98, 0xed, 0x3f, 0x8f, 0x92, 0xcb, 0x81, 0x56, 0x01, 0x63, 0x64, 0xa3, 0x38, 0x39}} ,
+ {{0x8b, 0xa4, 0xd6, 0x50, 0xb4, 0xaa, 0x5d, 0x64, 0x64, 0x76, 0x2e, 0xa1, 0xa6, 0xb3, 0xb8, 0x7c, 0x7a, 0x56, 0xf5, 0x5c, 0x4e, 0x84, 0x5c, 0xfb, 0xdd, 0xca, 0x48, 0x8b, 0x48, 0xb9, 0xba, 0x34}}},
+{{{0xc5, 0xe3, 0xe8, 0xae, 0x17, 0x27, 0xe3, 0x64, 0x60, 0x71, 0x47, 0x29, 0x02, 0x0f, 0x92, 0x5d, 0x10, 0x93, 0xc8, 0x0e, 0xa1, 0xed, 0xba, 0xa9, 0x96, 0x1c, 0xc5, 0x76, 0x30, 0xcd, 0xf9, 0x30}} ,
+ {{0x95, 0xb0, 0xbd, 0x8c, 0xbc, 0xa7, 0x4f, 0x7e, 0xfd, 0x4e, 0x3a, 0xbf, 0x5f, 0x04, 0x79, 0x80, 0x2b, 0x5a, 0x9f, 0x4f, 0x68, 0x21, 0x19, 0x71, 0xc6, 0x20, 0x01, 0x42, 0xaa, 0xdf, 0xae, 0x2c}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x90, 0x6e, 0x7e, 0x4b, 0x71, 0x93, 0xc0, 0x72, 0xed, 0xeb, 0x71, 0x24, 0x97, 0x26, 0x9c, 0xfe, 0xcb, 0x3e, 0x59, 0x19, 0xa8, 0x0f, 0x75, 0x7d, 0xbe, 0x18, 0xe6, 0x96, 0x1e, 0x95, 0x70, 0x60}} ,
+ {{0x89, 0x66, 0x3e, 0x1d, 0x4c, 0x5f, 0xfe, 0xc0, 0x04, 0x43, 0xd6, 0x44, 0x19, 0xb5, 0xad, 0xc7, 0x22, 0xdc, 0x71, 0x28, 0x64, 0xde, 0x41, 0x38, 0x27, 0x8f, 0x2c, 0x6b, 0x08, 0xb8, 0xb8, 0x7b}}},
+{{{0x3d, 0x70, 0x27, 0x9d, 0xd9, 0xaf, 0xb1, 0x27, 0xaf, 0xe3, 0x5d, 0x1e, 0x3a, 0x30, 0x54, 0x61, 0x60, 0xe8, 0xc3, 0x26, 0x3a, 0xbc, 0x7e, 0xf5, 0x81, 0xdd, 0x64, 0x01, 0x04, 0xeb, 0xc0, 0x1e}} ,
+ {{0xda, 0x2c, 0xa4, 0xd1, 0xa1, 0xc3, 0x5c, 0x6e, 0x32, 0x07, 0x1f, 0xb8, 0x0e, 0x19, 0x9e, 0x99, 0x29, 0x33, 0x9a, 0xae, 0x7a, 0xed, 0x68, 0x42, 0x69, 0x7c, 0x07, 0xb3, 0x38, 0x2c, 0xf6, 0x3d}}},
+{{{0x64, 0xaa, 0xb5, 0x88, 0x79, 0x65, 0x38, 0x8c, 0x94, 0xd6, 0x62, 0x37, 0x7d, 0x64, 0xcd, 0x3a, 0xeb, 0xff, 0xe8, 0x81, 0x09, 0xc7, 0x6a, 0x50, 0x09, 0x0d, 0x28, 0x03, 0x0d, 0x9a, 0x93, 0x0a}} ,
+ {{0x42, 0xa3, 0xf1, 0xc5, 0xb4, 0x0f, 0xd8, 0xc8, 0x8d, 0x15, 0x31, 0xbd, 0xf8, 0x07, 0x8b, 0xcd, 0x08, 0x8a, 0xfb, 0x18, 0x07, 0xfe, 0x8e, 0x52, 0x86, 0xef, 0xbe, 0xec, 0x49, 0x52, 0x99, 0x08}}},
+{{{0x0f, 0xa9, 0xd5, 0x01, 0xaa, 0x48, 0x4f, 0x28, 0x66, 0x32, 0x1a, 0xba, 0x7c, 0xea, 0x11, 0x80, 0x17, 0x18, 0x9b, 0x56, 0x88, 0x25, 0x06, 0x69, 0x12, 0x2c, 0xea, 0x56, 0x69, 0x41, 0x24, 0x19}} ,
+ {{0xde, 0x21, 0xf0, 0xda, 0x8a, 0xfb, 0xb1, 0xb8, 0xcd, 0xc8, 0x6a, 0x82, 0x19, 0x73, 0xdb, 0xc7, 0xcf, 0x88, 0xeb, 0x96, 0xee, 0x6f, 0xfb, 0x06, 0xd2, 0xcd, 0x7d, 0x7b, 0x12, 0x28, 0x8e, 0x0c}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x93, 0x44, 0x97, 0xce, 0x28, 0xff, 0x3a, 0x40, 0xc4, 0xf5, 0xf6, 0x9b, 0xf4, 0x6b, 0x07, 0x84, 0xfb, 0x98, 0xd8, 0xec, 0x8c, 0x03, 0x57, 0xec, 0x49, 0xed, 0x63, 0xb6, 0xaa, 0xff, 0x98, 0x28}} ,
+ {{0x3d, 0x16, 0x35, 0xf3, 0x46, 0xbc, 0xb3, 0xf4, 0xc6, 0xb6, 0x4f, 0xfa, 0xf4, 0xa0, 0x13, 0xe6, 0x57, 0x45, 0x93, 0xb9, 0xbc, 0xd6, 0x59, 0xe7, 0x77, 0x94, 0x6c, 0xab, 0x96, 0x3b, 0x4f, 0x09}}},
+{{{0x5a, 0xf7, 0x6b, 0x01, 0x12, 0x4f, 0x51, 0xc1, 0x70, 0x84, 0x94, 0x47, 0xb2, 0x01, 0x6c, 0x71, 0xd7, 0xcc, 0x17, 0x66, 0x0f, 0x59, 0x5d, 0x5d, 0x10, 0x01, 0x57, 0x11, 0xf5, 0xdd, 0xe2, 0x34}} ,
+ {{0x26, 0xd9, 0x1f, 0x5c, 0x58, 0xac, 0x8b, 0x03, 0xd2, 0xc3, 0x85, 0x0f, 0x3a, 0xc3, 0x7f, 0x6d, 0x8e, 0x86, 0xcd, 0x52, 0x74, 0x8f, 0x55, 0x77, 0x17, 0xb7, 0x8e, 0xb7, 0x88, 0xea, 0xda, 0x1b}}},
+{{{0xb6, 0xea, 0x0e, 0x40, 0x93, 0x20, 0x79, 0x35, 0x6a, 0x61, 0x84, 0x5a, 0x07, 0x6d, 0xf9, 0x77, 0x6f, 0xed, 0x69, 0x1c, 0x0d, 0x25, 0x76, 0xcc, 0xf0, 0xdb, 0xbb, 0xc5, 0xad, 0xe2, 0x26, 0x57}} ,
+ {{0xcf, 0xe8, 0x0e, 0x6b, 0x96, 0x7d, 0xed, 0x27, 0xd1, 0x3c, 0xa9, 0xd9, 0x50, 0xa9, 0x98, 0x84, 0x5e, 0x86, 0xef, 0xd6, 0xf0, 0xf8, 0x0e, 0x89, 0x05, 0x2f, 0xd9, 0x5f, 0x15, 0x5f, 0x73, 0x79}}},
+{{{0xc8, 0x5c, 0x16, 0xfe, 0xed, 0x9f, 0x26, 0x56, 0xf6, 0x4b, 0x9f, 0xa7, 0x0a, 0x85, 0xfe, 0xa5, 0x8c, 0x87, 0xdd, 0x98, 0xce, 0x4e, 0xc3, 0x58, 0x55, 0xb2, 0x7b, 0x3d, 0xd8, 0x6b, 0xb5, 0x4c}} ,
+ {{0x65, 0x38, 0xa0, 0x15, 0xfa, 0xa7, 0xb4, 0x8f, 0xeb, 0xc4, 0x86, 0x9b, 0x30, 0xa5, 0x5e, 0x4d, 0xea, 0x8a, 0x9a, 0x9f, 0x1a, 0xd8, 0x5b, 0x53, 0x14, 0x19, 0x25, 0x63, 0xb4, 0x6f, 0x1f, 0x5d}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0xac, 0x8f, 0xbc, 0x1e, 0x7d, 0x8b, 0x5a, 0x0b, 0x8d, 0xaf, 0x76, 0x2e, 0x71, 0xe3, 0x3b, 0x6f, 0x53, 0x2f, 0x3e, 0x90, 0x95, 0xd4, 0x35, 0x14, 0x4f, 0x8c, 0x3c, 0xce, 0x57, 0x1c, 0x76, 0x49}} ,
+ {{0xa8, 0x50, 0xe1, 0x61, 0x6b, 0x57, 0x35, 0xeb, 0x44, 0x0b, 0x0c, 0x6e, 0xf9, 0x25, 0x80, 0x74, 0xf2, 0x8f, 0x6f, 0x7a, 0x3e, 0x7f, 0x2d, 0xf3, 0x4e, 0x09, 0x65, 0x10, 0x5e, 0x03, 0x25, 0x32}}},
+{{{0xa9, 0x60, 0xdc, 0x0f, 0x64, 0xe5, 0x1d, 0xe2, 0x8d, 0x4f, 0x79, 0x2f, 0x0e, 0x24, 0x02, 0x00, 0x05, 0x77, 0x43, 0x25, 0x3d, 0x6a, 0xc7, 0xb7, 0xbf, 0x04, 0x08, 0x65, 0xf4, 0x39, 0x4b, 0x65}} ,
+ {{0x96, 0x19, 0x12, 0x6b, 0x6a, 0xb7, 0xe3, 0xdc, 0x45, 0x9b, 0xdb, 0xb4, 0xa8, 0xae, 0xdc, 0xa8, 0x14, 0x44, 0x65, 0x62, 0xce, 0x34, 0x9a, 0x84, 0x18, 0x12, 0x01, 0xf1, 0xe2, 0x7b, 0xce, 0x50}}},
+{{{0x41, 0x21, 0x30, 0x53, 0x1b, 0x47, 0x01, 0xb7, 0x18, 0xd8, 0x82, 0x57, 0xbd, 0xa3, 0x60, 0xf0, 0x32, 0xf6, 0x5b, 0xf0, 0x30, 0x88, 0x91, 0x59, 0xfd, 0x90, 0xa2, 0xb9, 0x55, 0x93, 0x21, 0x34}} ,
+ {{0x97, 0x67, 0x9e, 0xeb, 0x6a, 0xf9, 0x6e, 0xd6, 0x73, 0xe8, 0x6b, 0x29, 0xec, 0x63, 0x82, 0x00, 0xa8, 0x99, 0x1c, 0x1d, 0x30, 0xc8, 0x90, 0x52, 0x90, 0xb6, 0x6a, 0x80, 0x4e, 0xff, 0x4b, 0x51}}},
+{{{0x0f, 0x7d, 0x63, 0x8c, 0x6e, 0x5c, 0xde, 0x30, 0xdf, 0x65, 0xfa, 0x2e, 0xb0, 0xa3, 0x25, 0x05, 0x54, 0xbd, 0x25, 0xba, 0x06, 0xae, 0xdf, 0x8b, 0xd9, 0x1b, 0xea, 0x38, 0xb3, 0x05, 0x16, 0x09}} ,
+ {{0xc7, 0x8c, 0xbf, 0x64, 0x28, 0xad, 0xf8, 0xa5, 0x5a, 0x6f, 0xc9, 0xba, 0xd5, 0x7f, 0xd5, 0xd6, 0xbd, 0x66, 0x2f, 0x3d, 0xaa, 0x54, 0xf6, 0xba, 0x32, 0x22, 0x9a, 0x1e, 0x52, 0x05, 0xf4, 0x1d}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0xaa, 0x1f, 0xbb, 0xeb, 0xfe, 0xe4, 0x87, 0xfc, 0xb1, 0x2c, 0xb7, 0x88, 0xf4, 0xc6, 0xb9, 0xf5, 0x24, 0x46, 0xf2, 0xa5, 0x9f, 0x8f, 0x8a, 0x93, 0x70, 0x69, 0xd4, 0x56, 0xec, 0xfd, 0x06, 0x46}} ,
+ {{0x4e, 0x66, 0xcf, 0x4e, 0x34, 0xce, 0x0c, 0xd9, 0xa6, 0x50, 0xd6, 0x5e, 0x95, 0xaf, 0xe9, 0x58, 0xfa, 0xee, 0x9b, 0xb8, 0xa5, 0x0f, 0x35, 0xe0, 0x43, 0x82, 0x6d, 0x65, 0xe6, 0xd9, 0x00, 0x0f}}},
+{{{0x7b, 0x75, 0x3a, 0xfc, 0x64, 0xd3, 0x29, 0x7e, 0xdd, 0x49, 0x9a, 0x59, 0x53, 0xbf, 0xb4, 0xa7, 0x52, 0xb3, 0x05, 0xab, 0xc3, 0xaf, 0x16, 0x1a, 0x85, 0x42, 0x32, 0xa2, 0x86, 0xfa, 0x39, 0x43}} ,
+ {{0x0e, 0x4b, 0xa3, 0x63, 0x8a, 0xfe, 0xa5, 0x58, 0xf1, 0x13, 0xbd, 0x9d, 0xaa, 0x7f, 0x76, 0x40, 0x70, 0x81, 0x10, 0x75, 0x99, 0xbb, 0xbe, 0x0b, 0x16, 0xe9, 0xba, 0x62, 0x34, 0xcc, 0x07, 0x6d}}},
+{{{0xc3, 0xf1, 0xc6, 0x93, 0x65, 0xee, 0x0b, 0xbc, 0xea, 0x14, 0xf0, 0xc1, 0xf8, 0x84, 0x89, 0xc2, 0xc9, 0xd7, 0xea, 0x34, 0xca, 0xa7, 0xc4, 0x99, 0xd5, 0x50, 0x69, 0xcb, 0xd6, 0x21, 0x63, 0x7c}} ,
+ {{0x99, 0xeb, 0x7c, 0x31, 0x73, 0x64, 0x67, 0x7f, 0x0c, 0x66, 0xaa, 0x8c, 0x69, 0x91, 0xe2, 0x26, 0xd3, 0x23, 0xe2, 0x76, 0x5d, 0x32, 0x52, 0xdf, 0x5d, 0xc5, 0x8f, 0xb7, 0x7c, 0x84, 0xb3, 0x70}}},
+{{{0xeb, 0x01, 0xc7, 0x36, 0x97, 0x4e, 0xb6, 0xab, 0x5f, 0x0d, 0x2c, 0xba, 0x67, 0x64, 0x55, 0xde, 0xbc, 0xff, 0xa6, 0xec, 0x04, 0xd3, 0x8d, 0x39, 0x56, 0x5e, 0xee, 0xf8, 0xe4, 0x2e, 0x33, 0x62}} ,
+ {{0x65, 0xef, 0xb8, 0x9f, 0xc8, 0x4b, 0xa7, 0xfd, 0x21, 0x49, 0x9b, 0x92, 0x35, 0x82, 0xd6, 0x0a, 0x9b, 0xf2, 0x79, 0xf1, 0x47, 0x2f, 0x6a, 0x7e, 0x9f, 0xcf, 0x18, 0x02, 0x3c, 0xfb, 0x1b, 0x3e}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x2f, 0x8b, 0xc8, 0x40, 0x51, 0xd1, 0xac, 0x1a, 0x0b, 0xe4, 0xa9, 0xa2, 0x42, 0x21, 0x19, 0x2f, 0x7b, 0x97, 0xbf, 0xf7, 0x57, 0x6d, 0x3f, 0x3d, 0x4f, 0x0f, 0xe2, 0xb2, 0x81, 0x00, 0x9e, 0x7b}} ,
+ {{0x8c, 0x85, 0x2b, 0xc4, 0xfc, 0xf1, 0xab, 0xe8, 0x79, 0x22, 0xc4, 0x84, 0x17, 0x3a, 0xfa, 0x86, 0xa6, 0x7d, 0xf9, 0xf3, 0x6f, 0x03, 0x57, 0x20, 0x4d, 0x79, 0xf9, 0x6e, 0x71, 0x54, 0x38, 0x09}}},
+{{{0x40, 0x29, 0x74, 0xa8, 0x2f, 0x5e, 0xf9, 0x79, 0xa4, 0xf3, 0x3e, 0xb9, 0xfd, 0x33, 0x31, 0xac, 0x9a, 0x69, 0x88, 0x1e, 0x77, 0x21, 0x2d, 0xf3, 0x91, 0x52, 0x26, 0x15, 0xb2, 0xa6, 0xcf, 0x7e}} ,
+ {{0xc6, 0x20, 0x47, 0x6c, 0xa4, 0x7d, 0xcb, 0x63, 0xea, 0x5b, 0x03, 0xdf, 0x3e, 0x88, 0x81, 0x6d, 0xce, 0x07, 0x42, 0x18, 0x60, 0x7e, 0x7b, 0x55, 0xfe, 0x6a, 0xf3, 0xda, 0x5c, 0x8b, 0x95, 0x10}}},
+{{{0x62, 0xe4, 0x0d, 0x03, 0xb4, 0xd7, 0xcd, 0xfa, 0xbd, 0x46, 0xdf, 0x93, 0x71, 0x10, 0x2c, 0xa8, 0x3b, 0xb6, 0x09, 0x05, 0x70, 0x84, 0x43, 0x29, 0xa8, 0x59, 0xf5, 0x8e, 0x10, 0xe4, 0xd7, 0x20}} ,
+ {{0x57, 0x82, 0x1c, 0xab, 0xbf, 0x62, 0x70, 0xe8, 0xc4, 0xcf, 0xf0, 0x28, 0x6e, 0x16, 0x3c, 0x08, 0x78, 0x89, 0x85, 0x46, 0x0f, 0xf6, 0x7f, 0xcf, 0xcb, 0x7e, 0xb8, 0x25, 0xe9, 0x5a, 0xfa, 0x03}}},
+{{{0xfb, 0x95, 0x92, 0x63, 0x50, 0xfc, 0x62, 0xf0, 0xa4, 0x5e, 0x8c, 0x18, 0xc2, 0x17, 0x24, 0xb7, 0x78, 0xc2, 0xa9, 0xe7, 0x6a, 0x32, 0xd6, 0x29, 0x85, 0xaf, 0xcb, 0x8d, 0x91, 0x13, 0xda, 0x6b}} ,
+ {{0x36, 0x0a, 0xc2, 0xb6, 0x4b, 0xa5, 0x5d, 0x07, 0x17, 0x41, 0x31, 0x5f, 0x62, 0x46, 0xf8, 0x92, 0xf9, 0x66, 0x48, 0x73, 0xa6, 0x97, 0x0d, 0x7d, 0x88, 0xee, 0x62, 0xb1, 0x03, 0xa8, 0x3f, 0x2c}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x4a, 0xb1, 0x70, 0x8a, 0xa9, 0xe8, 0x63, 0x79, 0x00, 0xe2, 0x25, 0x16, 0xca, 0x4b, 0x0f, 0xa4, 0x66, 0xad, 0x19, 0x9f, 0x88, 0x67, 0x0c, 0x8b, 0xc2, 0x4a, 0x5b, 0x2b, 0x6d, 0x95, 0xaf, 0x19}} ,
+ {{0x8b, 0x9d, 0xb6, 0xcc, 0x60, 0xb4, 0x72, 0x4f, 0x17, 0x69, 0x5a, 0x4a, 0x68, 0x34, 0xab, 0xa1, 0x45, 0x32, 0x3c, 0x83, 0x87, 0x72, 0x30, 0x54, 0x77, 0x68, 0xae, 0xfb, 0xb5, 0x8b, 0x22, 0x5e}}},
+{{{0xf1, 0xb9, 0x87, 0x35, 0xc5, 0xbb, 0xb9, 0xcf, 0xf5, 0xd6, 0xcd, 0xd5, 0x0c, 0x7c, 0x0e, 0xe6, 0x90, 0x34, 0xfb, 0x51, 0x42, 0x1e, 0x6d, 0xac, 0x9a, 0x46, 0xc4, 0x97, 0x29, 0x32, 0xbf, 0x45}} ,
+ {{0x66, 0x9e, 0xc6, 0x24, 0xc0, 0xed, 0xa5, 0x5d, 0x88, 0xd4, 0xf0, 0x73, 0x97, 0x7b, 0xea, 0x7f, 0x42, 0xff, 0x21, 0xa0, 0x9b, 0x2f, 0x9a, 0xfd, 0x53, 0x57, 0x07, 0x84, 0x48, 0x88, 0x9d, 0x52}}},
+{{{0xc6, 0x96, 0x48, 0x34, 0x2a, 0x06, 0xaf, 0x94, 0x3d, 0xf4, 0x1a, 0xcf, 0xf2, 0xc0, 0x21, 0xc2, 0x42, 0x5e, 0xc8, 0x2f, 0x35, 0xa2, 0x3e, 0x29, 0xfa, 0x0c, 0x84, 0xe5, 0x89, 0x72, 0x7c, 0x06}} ,
+ {{0x32, 0x65, 0x03, 0xe5, 0x89, 0xa6, 0x6e, 0xb3, 0x5b, 0x8e, 0xca, 0xeb, 0xfe, 0x22, 0x56, 0x8b, 0x5d, 0x14, 0x4b, 0x4d, 0xf9, 0xbe, 0xb5, 0xf5, 0xe6, 0x5c, 0x7b, 0x8b, 0xf4, 0x13, 0x11, 0x34}}},
+{{{0x07, 0xc6, 0x22, 0x15, 0xe2, 0x9c, 0x60, 0xa2, 0x19, 0xd9, 0x27, 0xae, 0x37, 0x4e, 0xa6, 0xc9, 0x80, 0xa6, 0x91, 0x8f, 0x12, 0x49, 0xe5, 0x00, 0x18, 0x47, 0xd1, 0xd7, 0x28, 0x22, 0x63, 0x39}} ,
+ {{0xe8, 0xe2, 0x00, 0x7e, 0xf2, 0x9e, 0x1e, 0x99, 0x39, 0x95, 0x04, 0xbd, 0x1e, 0x67, 0x7b, 0xb2, 0x26, 0xac, 0xe6, 0xaa, 0xe2, 0x46, 0xd5, 0xe4, 0xe8, 0x86, 0xbd, 0xab, 0x7c, 0x55, 0x59, 0x6f}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x24, 0x64, 0x6e, 0x9b, 0x35, 0x71, 0x78, 0xce, 0x33, 0x03, 0x21, 0x33, 0x36, 0xf1, 0x73, 0x9b, 0xb9, 0x15, 0x8b, 0x2c, 0x69, 0xcf, 0x4d, 0xed, 0x4f, 0x4d, 0x57, 0x14, 0x13, 0x82, 0xa4, 0x4d}} ,
+ {{0x65, 0x6e, 0x0a, 0xa4, 0x59, 0x07, 0x17, 0xf2, 0x6b, 0x4a, 0x1f, 0x6e, 0xf6, 0xb5, 0xbc, 0x62, 0xe4, 0xb6, 0xda, 0xa2, 0x93, 0xbc, 0x29, 0x05, 0xd2, 0xd2, 0x73, 0x46, 0x03, 0x16, 0x40, 0x31}}},
+{{{0x4c, 0x73, 0x6d, 0x15, 0xbd, 0xa1, 0x4d, 0x5c, 0x13, 0x0b, 0x24, 0x06, 0x98, 0x78, 0x1c, 0x5b, 0xeb, 0x1f, 0x18, 0x54, 0x43, 0xd9, 0x55, 0x66, 0xda, 0x29, 0x21, 0xe8, 0xb8, 0x3c, 0x42, 0x22}} ,
+ {{0xb4, 0xcd, 0x08, 0x6f, 0x15, 0x23, 0x1a, 0x0b, 0x22, 0xed, 0xd1, 0xf1, 0xa7, 0xc7, 0x73, 0x45, 0xf3, 0x9e, 0xce, 0x76, 0xb7, 0xf6, 0x39, 0xb6, 0x8e, 0x79, 0xbe, 0xe9, 0x9b, 0xcf, 0x7d, 0x62}}},
+{{{0x92, 0x5b, 0xfc, 0x72, 0xfd, 0xba, 0xf1, 0xfd, 0xa6, 0x7c, 0x95, 0xe3, 0x61, 0x3f, 0xe9, 0x03, 0xd4, 0x2b, 0xd4, 0x20, 0xd9, 0xdb, 0x4d, 0x32, 0x3e, 0xf5, 0x11, 0x64, 0xe3, 0xb4, 0xbe, 0x32}} ,
+ {{0x86, 0x17, 0x90, 0xe7, 0xc9, 0x1f, 0x10, 0xa5, 0x6a, 0x2d, 0x39, 0xd0, 0x3b, 0xc4, 0xa6, 0xe9, 0x59, 0x13, 0xda, 0x1a, 0xe6, 0xa0, 0xb9, 0x3c, 0x50, 0xb8, 0x40, 0x7c, 0x15, 0x36, 0x5a, 0x42}}},
+{{{0xb4, 0x0b, 0x32, 0xab, 0xdc, 0x04, 0x51, 0x55, 0x21, 0x1e, 0x0b, 0x75, 0x99, 0x89, 0x73, 0x35, 0x3a, 0x91, 0x2b, 0xfe, 0xe7, 0x49, 0xea, 0x76, 0xc1, 0xf9, 0x46, 0xb9, 0x53, 0x02, 0x23, 0x04}} ,
+ {{0xfc, 0x5a, 0x1e, 0x1d, 0x74, 0x58, 0x95, 0xa6, 0x8f, 0x7b, 0x97, 0x3e, 0x17, 0x3b, 0x79, 0x2d, 0xa6, 0x57, 0xef, 0x45, 0x02, 0x0b, 0x4d, 0x6e, 0x9e, 0x93, 0x8d, 0x2f, 0xd9, 0x9d, 0xdb, 0x04}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0xc0, 0xd7, 0x56, 0x97, 0x58, 0x91, 0xde, 0x09, 0x4f, 0x9f, 0xbe, 0x63, 0xb0, 0x83, 0x86, 0x43, 0x5d, 0xbc, 0xe0, 0xf3, 0xc0, 0x75, 0xbf, 0x8b, 0x8e, 0xaa, 0xf7, 0x8b, 0x64, 0x6e, 0xb0, 0x63}} ,
+ {{0x16, 0xae, 0x8b, 0xe0, 0x9b, 0x24, 0x68, 0x5c, 0x44, 0xc2, 0xd0, 0x08, 0xb7, 0x7b, 0x62, 0xfd, 0x7f, 0xd8, 0xd4, 0xb7, 0x50, 0xfd, 0x2c, 0x1b, 0xbf, 0x41, 0x95, 0xd9, 0x8e, 0xd8, 0x17, 0x1b}}},
+{{{0x86, 0x55, 0x37, 0x8e, 0xc3, 0x38, 0x48, 0x14, 0xb5, 0x97, 0xd2, 0xa7, 0x54, 0x45, 0xf1, 0x35, 0x44, 0x38, 0x9e, 0xf1, 0x1b, 0xb6, 0x34, 0x00, 0x3c, 0x96, 0xee, 0x29, 0x00, 0xea, 0x2c, 0x0b}} ,
+ {{0xea, 0xda, 0x99, 0x9e, 0x19, 0x83, 0x66, 0x6d, 0xe9, 0x76, 0x87, 0x50, 0xd1, 0xfd, 0x3c, 0x60, 0x87, 0xc6, 0x41, 0xd9, 0x8e, 0xdb, 0x5e, 0xde, 0xaa, 0x9a, 0xd3, 0x28, 0xda, 0x95, 0xea, 0x47}}},
+{{{0xd0, 0x80, 0xba, 0x19, 0xae, 0x1d, 0xa9, 0x79, 0xf6, 0x3f, 0xac, 0x5d, 0x6f, 0x96, 0x1f, 0x2a, 0xce, 0x29, 0xb2, 0xff, 0x37, 0xf1, 0x94, 0x8f, 0x0c, 0xb5, 0x28, 0xba, 0x9a, 0x21, 0xf6, 0x66}} ,
+ {{0x02, 0xfb, 0x54, 0xb8, 0x05, 0xf3, 0x81, 0x52, 0x69, 0x34, 0x46, 0x9d, 0x86, 0x76, 0x8f, 0xd7, 0xf8, 0x6a, 0x66, 0xff, 0xe6, 0xa7, 0x90, 0xf7, 0x5e, 0xcd, 0x6a, 0x9b, 0x55, 0xfc, 0x9d, 0x48}}},
+{{{0xbd, 0xaa, 0x13, 0xe6, 0xcd, 0x45, 0x4a, 0xa4, 0x59, 0x0a, 0x64, 0xb1, 0x98, 0xd6, 0x34, 0x13, 0x04, 0xe6, 0x97, 0x94, 0x06, 0xcb, 0xd4, 0x4e, 0xbb, 0x96, 0xcd, 0xd1, 0x57, 0xd1, 0xe3, 0x06}} ,
+ {{0x7a, 0x6c, 0x45, 0x27, 0xc4, 0x93, 0x7f, 0x7d, 0x7c, 0x62, 0x50, 0x38, 0x3a, 0x6b, 0xb5, 0x88, 0xc6, 0xd9, 0xf1, 0x78, 0x19, 0xb9, 0x39, 0x93, 0x3d, 0xc9, 0xe0, 0x9c, 0x3c, 0xce, 0xf5, 0x72}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x24, 0xea, 0x23, 0x7d, 0x56, 0x2c, 0xe2, 0x59, 0x0e, 0x85, 0x60, 0x04, 0x88, 0x5a, 0x74, 0x1e, 0x4b, 0xef, 0x13, 0xda, 0x4c, 0xff, 0x83, 0x45, 0x85, 0x3f, 0x08, 0x95, 0x2c, 0x20, 0x13, 0x1f}} ,
+ {{0x48, 0x5f, 0x27, 0x90, 0x5c, 0x02, 0x42, 0xad, 0x78, 0x47, 0x5c, 0xb5, 0x7e, 0x08, 0x85, 0x00, 0xfa, 0x7f, 0xfd, 0xfd, 0xe7, 0x09, 0x11, 0xf2, 0x7e, 0x1b, 0x38, 0x6c, 0x35, 0x6d, 0x33, 0x66}}},
+{{{0x93, 0x03, 0x36, 0x81, 0xac, 0xe4, 0x20, 0x09, 0x35, 0x4c, 0x45, 0xb2, 0x1e, 0x4c, 0x14, 0x21, 0xe6, 0xe9, 0x8a, 0x7b, 0x8d, 0xfe, 0x1e, 0xc6, 0x3e, 0xc1, 0x35, 0xfa, 0xe7, 0x70, 0x4e, 0x1d}} ,
+ {{0x61, 0x2e, 0xc2, 0xdd, 0x95, 0x57, 0xd1, 0xab, 0x80, 0xe8, 0x63, 0x17, 0xb5, 0x48, 0xe4, 0x8a, 0x11, 0x9e, 0x72, 0xbe, 0x85, 0x8d, 0x51, 0x0a, 0xf2, 0x9f, 0xe0, 0x1c, 0xa9, 0x07, 0x28, 0x7b}}},
+{{{0xbb, 0x71, 0x14, 0x5e, 0x26, 0x8c, 0x3d, 0xc8, 0xe9, 0x7c, 0xd3, 0xd6, 0xd1, 0x2f, 0x07, 0x6d, 0xe6, 0xdf, 0xfb, 0x79, 0xd6, 0x99, 0x59, 0x96, 0x48, 0x40, 0x0f, 0x3a, 0x7b, 0xb2, 0xa0, 0x72}} ,
+ {{0x4e, 0x3b, 0x69, 0xc8, 0x43, 0x75, 0x51, 0x6c, 0x79, 0x56, 0xe4, 0xcb, 0xf7, 0xa6, 0x51, 0xc2, 0x2c, 0x42, 0x0b, 0xd4, 0x82, 0x20, 0x1c, 0x01, 0x08, 0x66, 0xd7, 0xbf, 0x04, 0x56, 0xfc, 0x02}}},
+{{{0x24, 0xe8, 0xb7, 0x60, 0xae, 0x47, 0x80, 0xfc, 0xe5, 0x23, 0xe7, 0xc2, 0xc9, 0x85, 0xe6, 0x98, 0xa0, 0x29, 0x4e, 0xe1, 0x84, 0x39, 0x2d, 0x95, 0x2c, 0xf3, 0x45, 0x3c, 0xff, 0xaf, 0x27, 0x4c}} ,
+ {{0x6b, 0xa6, 0xf5, 0x4b, 0x11, 0xbd, 0xba, 0x5b, 0x9e, 0xc4, 0xa4, 0x51, 0x1e, 0xbe, 0xd0, 0x90, 0x3a, 0x9c, 0xc2, 0x26, 0xb6, 0x1e, 0xf1, 0x95, 0x7d, 0xc8, 0x6d, 0x52, 0xe6, 0x99, 0x2c, 0x5f}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x85, 0xe0, 0x24, 0x32, 0xb4, 0xd1, 0xef, 0xfc, 0x69, 0xa2, 0xbf, 0x8f, 0x72, 0x2c, 0x95, 0xf6, 0xe4, 0x6e, 0x7d, 0x90, 0xf7, 0x57, 0x81, 0xa0, 0xf7, 0xda, 0xef, 0x33, 0x07, 0xe3, 0x6b, 0x78}} ,
+ {{0x36, 0x27, 0x3e, 0xc6, 0x12, 0x07, 0xab, 0x4e, 0xbe, 0x69, 0x9d, 0xb3, 0xbe, 0x08, 0x7c, 0x2a, 0x47, 0x08, 0xfd, 0xd4, 0xcd, 0x0e, 0x27, 0x34, 0x5b, 0x98, 0x34, 0x2f, 0x77, 0x5f, 0x3a, 0x65}}},
+{{{0x13, 0xaa, 0x2e, 0x4c, 0xf0, 0x22, 0xb8, 0x6c, 0xb3, 0x19, 0x4d, 0xeb, 0x6b, 0xd0, 0xa4, 0xc6, 0x9c, 0xdd, 0xc8, 0x5b, 0x81, 0x57, 0x89, 0xdf, 0x33, 0xa9, 0x68, 0x49, 0x80, 0xe4, 0xfe, 0x21}} ,
+ {{0x00, 0x17, 0x90, 0x30, 0xe9, 0xd3, 0x60, 0x30, 0x31, 0xc2, 0x72, 0x89, 0x7a, 0x36, 0xa5, 0xbd, 0x39, 0x83, 0x85, 0x50, 0xa1, 0x5d, 0x6c, 0x41, 0x1d, 0xb5, 0x2c, 0x07, 0x40, 0x77, 0x0b, 0x50}}},
+{{{0x64, 0x34, 0xec, 0xc0, 0x9e, 0x44, 0x41, 0xaf, 0xa0, 0x36, 0x05, 0x6d, 0xea, 0x30, 0x25, 0x46, 0x35, 0x24, 0x9d, 0x86, 0xbd, 0x95, 0xf1, 0x6a, 0x46, 0xd7, 0x94, 0x54, 0xf9, 0x3b, 0xbd, 0x5d}} ,
+ {{0x77, 0x5b, 0xe2, 0x37, 0xc7, 0xe1, 0x7c, 0x13, 0x8c, 0x9f, 0x7b, 0x7b, 0x2a, 0xce, 0x42, 0xa3, 0xb9, 0x2a, 0x99, 0xa8, 0xc0, 0xd8, 0x3c, 0x86, 0xb0, 0xfb, 0xe9, 0x76, 0x77, 0xf7, 0xf5, 0x56}}},
+{{{0xdf, 0xb3, 0x46, 0x11, 0x6e, 0x13, 0xb7, 0x28, 0x4e, 0x56, 0xdd, 0xf1, 0xac, 0xad, 0x58, 0xc3, 0xf8, 0x88, 0x94, 0x5e, 0x06, 0x98, 0xa1, 0xe4, 0x6a, 0xfb, 0x0a, 0x49, 0x5d, 0x8a, 0xfe, 0x77}} ,
+ {{0x46, 0x02, 0xf5, 0xa5, 0xaf, 0xc5, 0x75, 0x6d, 0xba, 0x45, 0x35, 0x0a, 0xfe, 0xc9, 0xac, 0x22, 0x91, 0x8d, 0x21, 0x95, 0x33, 0x03, 0xc0, 0x8a, 0x16, 0xf3, 0x39, 0xe0, 0x01, 0x0f, 0x53, 0x3c}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x34, 0x75, 0x37, 0x1f, 0x34, 0x4e, 0xa9, 0x1d, 0x68, 0x67, 0xf8, 0x49, 0x98, 0x96, 0xfc, 0x4c, 0x65, 0x97, 0xf7, 0x02, 0x4a, 0x52, 0x6c, 0x01, 0xbd, 0x48, 0xbb, 0x1b, 0xed, 0xa4, 0xe2, 0x53}} ,
+ {{0x59, 0xd5, 0x9b, 0x5a, 0xa2, 0x90, 0xd3, 0xb8, 0x37, 0x4c, 0x55, 0x82, 0x28, 0x08, 0x0f, 0x7f, 0xaa, 0x81, 0x65, 0xe0, 0x0c, 0x52, 0xc9, 0xa3, 0x32, 0x27, 0x64, 0xda, 0xfd, 0x34, 0x23, 0x5a}}},
+{{{0xb5, 0xb0, 0x0c, 0x4d, 0xb3, 0x7b, 0x23, 0xc8, 0x1f, 0x8a, 0x39, 0x66, 0xe6, 0xba, 0x4c, 0x10, 0x37, 0xca, 0x9c, 0x7c, 0x05, 0x9e, 0xff, 0xc0, 0xf8, 0x8e, 0xb1, 0x8f, 0x6f, 0x67, 0x18, 0x26}} ,
+ {{0x4b, 0x41, 0x13, 0x54, 0x23, 0x1a, 0xa4, 0x4e, 0xa9, 0x8b, 0x1e, 0x4b, 0xfc, 0x15, 0x24, 0xbb, 0x7e, 0xcb, 0xb6, 0x1e, 0x1b, 0xf5, 0xf2, 0xc8, 0x56, 0xec, 0x32, 0xa2, 0x60, 0x5b, 0xa0, 0x2a}}},
+{{{0xa4, 0x29, 0x47, 0x86, 0x2e, 0x92, 0x4f, 0x11, 0x4f, 0xf3, 0xb2, 0x5c, 0xd5, 0x3e, 0xa6, 0xb9, 0xc8, 0xe2, 0x33, 0x11, 0x1f, 0x01, 0x8f, 0xb0, 0x9b, 0xc7, 0xa5, 0xff, 0x83, 0x0f, 0x1e, 0x28}} ,
+ {{0x1d, 0x29, 0x7a, 0xa1, 0xec, 0x8e, 0xb5, 0xad, 0xea, 0x02, 0x68, 0x60, 0x74, 0x29, 0x1c, 0xa5, 0xcf, 0xc8, 0x3b, 0x7d, 0x8b, 0x2b, 0x7c, 0xad, 0xa4, 0x40, 0x17, 0x51, 0x59, 0x7c, 0x2e, 0x5d}}},
+{{{0x0a, 0x6c, 0x4f, 0xbc, 0x3e, 0x32, 0xe7, 0x4a, 0x1a, 0x13, 0xc1, 0x49, 0x38, 0xbf, 0xf7, 0xc2, 0xd3, 0x8f, 0x6b, 0xad, 0x52, 0xf7, 0xcf, 0xbc, 0x27, 0xcb, 0x40, 0x67, 0x76, 0xcd, 0x6d, 0x56}} ,
+ {{0xe5, 0xb0, 0x27, 0xad, 0xbe, 0x9b, 0xf2, 0xb5, 0x63, 0xde, 0x3a, 0x23, 0x95, 0xb7, 0x0a, 0x7e, 0xf3, 0x9e, 0x45, 0x6f, 0x19, 0x39, 0x75, 0x8f, 0x39, 0x3d, 0x0f, 0xc0, 0x9f, 0xf1, 0xe9, 0x51}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x88, 0xaa, 0x14, 0x24, 0x86, 0x94, 0x11, 0x12, 0x3e, 0x1a, 0xb5, 0xcc, 0xbb, 0xe0, 0x9c, 0xd5, 0x9c, 0x6d, 0xba, 0x58, 0x72, 0x8d, 0xfb, 0x22, 0x7b, 0x9f, 0x7c, 0x94, 0x30, 0xb3, 0x51, 0x21}} ,
+ {{0xf6, 0x74, 0x3d, 0xf2, 0xaf, 0xd0, 0x1e, 0x03, 0x7c, 0x23, 0x6b, 0xc9, 0xfc, 0x25, 0x70, 0x90, 0xdc, 0x9a, 0xa4, 0xfb, 0x49, 0xfc, 0x3d, 0x0a, 0x35, 0x38, 0x6f, 0xe4, 0x7e, 0x50, 0x01, 0x2a}}},
+{{{0xd6, 0xe3, 0x96, 0x61, 0x3a, 0xfd, 0xef, 0x9b, 0x1f, 0x90, 0xa4, 0x24, 0x14, 0x5b, 0xc8, 0xde, 0x50, 0xb1, 0x1d, 0xaf, 0xe8, 0x55, 0x8a, 0x87, 0x0d, 0xfe, 0xaa, 0x3b, 0x82, 0x2c, 0x8d, 0x7b}} ,
+ {{0x85, 0x0c, 0xaf, 0xf8, 0x83, 0x44, 0x49, 0xd9, 0x45, 0xcf, 0xf7, 0x48, 0xd9, 0x53, 0xb4, 0xf1, 0x65, 0xa0, 0xe1, 0xc3, 0xb3, 0x15, 0xed, 0x89, 0x9b, 0x4f, 0x62, 0xb3, 0x57, 0xa5, 0x45, 0x1c}}},
+{{{0x8f, 0x12, 0xea, 0xaf, 0xd1, 0x1f, 0x79, 0x10, 0x0b, 0xf6, 0xa3, 0x7b, 0xea, 0xac, 0x8b, 0x57, 0x32, 0x62, 0xe7, 0x06, 0x12, 0x51, 0xa0, 0x3b, 0x43, 0x5e, 0xa4, 0x20, 0x78, 0x31, 0xce, 0x0d}} ,
+ {{0x84, 0x7c, 0xc2, 0xa6, 0x91, 0x23, 0xce, 0xbd, 0xdc, 0xf9, 0xce, 0xd5, 0x75, 0x30, 0x22, 0xe6, 0xf9, 0x43, 0x62, 0x0d, 0xf7, 0x75, 0x9d, 0x7f, 0x8c, 0xff, 0x7d, 0xe4, 0x72, 0xac, 0x9f, 0x1c}}},
+{{{0x88, 0xc1, 0x99, 0xd0, 0x3c, 0x1c, 0x5d, 0xb4, 0xef, 0x13, 0x0f, 0x90, 0xb9, 0x36, 0x2f, 0x95, 0x95, 0xc6, 0xdc, 0xde, 0x0a, 0x51, 0xe2, 0x8d, 0xf3, 0xbc, 0x51, 0xec, 0xdf, 0xb1, 0xa2, 0x5f}} ,
+ {{0x2e, 0x68, 0xa1, 0x23, 0x7d, 0x9b, 0x40, 0x69, 0x85, 0x7b, 0x42, 0xbf, 0x90, 0x4b, 0xd6, 0x40, 0x2f, 0xd7, 0x52, 0x52, 0xb2, 0x21, 0xde, 0x64, 0xbd, 0x88, 0xc3, 0x6d, 0xa5, 0xfa, 0x81, 0x3f}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0xfb, 0xfd, 0x47, 0x7b, 0x8a, 0x66, 0x9e, 0x79, 0x2e, 0x64, 0x82, 0xef, 0xf7, 0x21, 0xec, 0xf6, 0xd8, 0x86, 0x09, 0x31, 0x7c, 0xdd, 0x03, 0x6a, 0x58, 0xa0, 0x77, 0xb7, 0x9b, 0x8c, 0x87, 0x1f}} ,
+ {{0x55, 0x47, 0xe4, 0xa8, 0x3d, 0x55, 0x21, 0x34, 0xab, 0x1d, 0xae, 0xe0, 0xf4, 0xea, 0xdb, 0xc5, 0xb9, 0x58, 0xbf, 0xc4, 0x2a, 0x89, 0x31, 0x1a, 0xf4, 0x2d, 0xe1, 0xca, 0x37, 0x99, 0x47, 0x59}}},
+{{{0xc7, 0xca, 0x63, 0xc1, 0x49, 0xa9, 0x35, 0x45, 0x55, 0x7e, 0xda, 0x64, 0x32, 0x07, 0x50, 0xf7, 0x32, 0xac, 0xde, 0x75, 0x58, 0x9b, 0x11, 0xb2, 0x3a, 0x1f, 0xf5, 0xf7, 0x79, 0x04, 0xe6, 0x08}} ,
+ {{0x46, 0xfa, 0x22, 0x4b, 0xfa, 0xe1, 0xfe, 0x96, 0xfc, 0x67, 0xba, 0x67, 0x97, 0xc4, 0xe7, 0x1b, 0x86, 0x90, 0x5f, 0xee, 0xf4, 0x5b, 0x11, 0xb2, 0xcd, 0xad, 0xee, 0xc2, 0x48, 0x6c, 0x2b, 0x1b}}},
+{{{0xe3, 0x39, 0x62, 0xb4, 0x4f, 0x31, 0x04, 0xc9, 0xda, 0xd5, 0x73, 0x51, 0x57, 0xc5, 0xb8, 0xf3, 0xa3, 0x43, 0x70, 0xe4, 0x61, 0x81, 0x84, 0xe2, 0xbb, 0xbf, 0x4f, 0x9e, 0xa4, 0x5e, 0x74, 0x06}} ,
+ {{0x29, 0xac, 0xff, 0x27, 0xe0, 0x59, 0xbe, 0x39, 0x9c, 0x0d, 0x83, 0xd7, 0x10, 0x0b, 0x15, 0xb7, 0xe1, 0xc2, 0x2c, 0x30, 0x73, 0x80, 0x3a, 0x7d, 0x5d, 0xab, 0x58, 0x6b, 0xc1, 0xf0, 0xf4, 0x22}}},
+{{{0xfe, 0x7f, 0xfb, 0x35, 0x7d, 0xc6, 0x01, 0x23, 0x28, 0xc4, 0x02, 0xac, 0x1f, 0x42, 0xb4, 0x9d, 0xfc, 0x00, 0x94, 0xa5, 0xee, 0xca, 0xda, 0x97, 0x09, 0x41, 0x77, 0x87, 0x5d, 0x7b, 0x87, 0x78}} ,
+ {{0xf5, 0xfb, 0x90, 0x2d, 0x81, 0x19, 0x9e, 0x2f, 0x6d, 0x85, 0x88, 0x8c, 0x40, 0x5c, 0x77, 0x41, 0x4d, 0x01, 0x19, 0x76, 0x60, 0xe8, 0x4c, 0x48, 0xe4, 0x33, 0x83, 0x32, 0x6c, 0xb4, 0x41, 0x03}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0xff, 0x10, 0xc2, 0x09, 0x4f, 0x6e, 0xf4, 0xd2, 0xdf, 0x7e, 0xca, 0x7b, 0x1c, 0x1d, 0xba, 0xa3, 0xb6, 0xda, 0x67, 0x33, 0xd4, 0x87, 0x36, 0x4b, 0x11, 0x20, 0x05, 0xa6, 0x29, 0xc1, 0x87, 0x17}} ,
+ {{0xf6, 0x96, 0xca, 0x2f, 0xda, 0x38, 0xa7, 0x1b, 0xfc, 0xca, 0x7d, 0xfe, 0x08, 0x89, 0xe2, 0x47, 0x2b, 0x6a, 0x5d, 0x4b, 0xfa, 0xa1, 0xb4, 0xde, 0xb6, 0xc2, 0x31, 0x51, 0xf5, 0xe0, 0xa4, 0x0b}}},
+{{{0x5c, 0xe5, 0xc6, 0x04, 0x8e, 0x2b, 0x57, 0xbe, 0x38, 0x85, 0x23, 0xcb, 0xb7, 0xbe, 0x4f, 0xa9, 0xd3, 0x6e, 0x12, 0xaa, 0xd5, 0xb2, 0x2e, 0x93, 0x29, 0x9a, 0x4a, 0x88, 0x18, 0x43, 0xf5, 0x01}} ,
+ {{0x50, 0xfc, 0xdb, 0xa2, 0x59, 0x21, 0x8d, 0xbd, 0x7e, 0x33, 0xae, 0x2f, 0x87, 0x1a, 0xd0, 0x97, 0xc7, 0x0d, 0x4d, 0x63, 0x01, 0xef, 0x05, 0x84, 0xec, 0x40, 0xdd, 0xa8, 0x0a, 0x4f, 0x70, 0x0b}}},
+{{{0x41, 0x69, 0x01, 0x67, 0x5c, 0xd3, 0x8a, 0xc5, 0xcf, 0x3f, 0xd1, 0x57, 0xd1, 0x67, 0x3e, 0x01, 0x39, 0xb5, 0xcb, 0x81, 0x56, 0x96, 0x26, 0xb6, 0xc2, 0xe7, 0x5c, 0xfb, 0x63, 0x97, 0x58, 0x06}} ,
+ {{0x0c, 0x0e, 0xf3, 0xba, 0xf0, 0xe5, 0xba, 0xb2, 0x57, 0x77, 0xc6, 0x20, 0x9b, 0x89, 0x24, 0xbe, 0xf2, 0x9c, 0x8a, 0xba, 0x69, 0xc1, 0xf1, 0xb0, 0x4f, 0x2a, 0x05, 0x9a, 0xee, 0x10, 0x7e, 0x36}}},
+{{{0x3f, 0x26, 0xe9, 0x40, 0xe9, 0x03, 0xad, 0x06, 0x69, 0x91, 0xe0, 0xd1, 0x89, 0x60, 0x84, 0x79, 0xde, 0x27, 0x6d, 0xe6, 0x76, 0xbd, 0xea, 0xe6, 0xae, 0x48, 0xc3, 0x67, 0xc0, 0x57, 0xcd, 0x2f}} ,
+ {{0x7f, 0xc1, 0xdc, 0xb9, 0xc7, 0xbc, 0x86, 0x3d, 0x55, 0x4b, 0x28, 0x7a, 0xfb, 0x4d, 0xc7, 0xf8, 0xbc, 0x67, 0x2a, 0x60, 0x4d, 0x8f, 0x07, 0x0b, 0x1a, 0x17, 0xbf, 0xfa, 0xac, 0xa7, 0x3d, 0x1a}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x91, 0x3f, 0xed, 0x5e, 0x18, 0x78, 0x3f, 0x23, 0x2c, 0x0d, 0x8c, 0x44, 0x00, 0xe8, 0xfb, 0xe9, 0x8e, 0xd6, 0xd1, 0x36, 0x58, 0x57, 0x9e, 0xae, 0x4b, 0x5c, 0x0b, 0x07, 0xbc, 0x6b, 0x55, 0x2b}} ,
+ {{0x6f, 0x4d, 0x17, 0xd7, 0xe1, 0x84, 0xd9, 0x78, 0xb1, 0x90, 0xfd, 0x2e, 0xb3, 0xb5, 0x19, 0x3f, 0x1b, 0xfa, 0xc0, 0x68, 0xb3, 0xdd, 0x00, 0x2e, 0x89, 0xbd, 0x7e, 0x80, 0x32, 0x13, 0xa0, 0x7b}}},
+{{{0x1a, 0x6f, 0x40, 0xaf, 0x44, 0x44, 0xb0, 0x43, 0x8f, 0x0d, 0xd0, 0x1e, 0xc4, 0x0b, 0x19, 0x5d, 0x8e, 0xfe, 0xc1, 0xf3, 0xc5, 0x5c, 0x91, 0xf8, 0x04, 0x4e, 0xbe, 0x90, 0xb4, 0x47, 0x5c, 0x3f}} ,
+ {{0xb0, 0x3b, 0x2c, 0xf3, 0xfe, 0x32, 0x71, 0x07, 0x3f, 0xaa, 0xba, 0x45, 0x60, 0xa8, 0x8d, 0xea, 0x54, 0xcb, 0x39, 0x10, 0xb4, 0xf2, 0x8b, 0xd2, 0x14, 0x82, 0x42, 0x07, 0x8e, 0xe9, 0x7c, 0x53}}},
+{{{0xb0, 0xae, 0xc1, 0x8d, 0xc9, 0x8f, 0xb9, 0x7a, 0x77, 0xef, 0xba, 0x79, 0xa0, 0x3c, 0xa8, 0xf5, 0x6a, 0xe2, 0x3f, 0x5d, 0x00, 0xe3, 0x4b, 0x45, 0x24, 0x7b, 0x43, 0x78, 0x55, 0x1d, 0x2b, 0x1e}} ,
+ {{0x01, 0xb8, 0xd6, 0x16, 0x67, 0xa0, 0x15, 0xb9, 0xe1, 0x58, 0xa4, 0xa7, 0x31, 0x37, 0x77, 0x2f, 0x8b, 0x12, 0x9f, 0xf4, 0x3f, 0xc7, 0x36, 0x66, 0xd2, 0xa8, 0x56, 0xf7, 0x7f, 0x74, 0xc6, 0x41}}},
+{{{0x5d, 0xf8, 0xb4, 0xa8, 0x30, 0xdd, 0xcc, 0x38, 0xa5, 0xd3, 0xca, 0xd8, 0xd1, 0xf8, 0xb2, 0x31, 0x91, 0xd4, 0x72, 0x05, 0x57, 0x4a, 0x3b, 0x82, 0x4a, 0xc6, 0x68, 0x20, 0xe2, 0x18, 0x41, 0x61}} ,
+ {{0x19, 0xd4, 0x8d, 0x47, 0x29, 0x12, 0x65, 0xb0, 0x11, 0x78, 0x47, 0xb5, 0xcb, 0xa3, 0xa5, 0xfa, 0x05, 0x85, 0x54, 0xa9, 0x33, 0x97, 0x8d, 0x2b, 0xc2, 0xfe, 0x99, 0x35, 0x28, 0xe5, 0xeb, 0x63}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0xb1, 0x3f, 0x3f, 0xef, 0xd8, 0xf4, 0xfc, 0xb3, 0xa0, 0x60, 0x50, 0x06, 0x2b, 0x29, 0x52, 0x70, 0x15, 0x0b, 0x24, 0x24, 0xf8, 0x5f, 0x79, 0x18, 0xcc, 0xff, 0x89, 0x99, 0x84, 0xa1, 0xae, 0x13}} ,
+ {{0x44, 0x1f, 0xb8, 0xc2, 0x01, 0xc1, 0x30, 0x19, 0x55, 0x05, 0x60, 0x10, 0xa4, 0x6c, 0x2d, 0x67, 0x70, 0xe5, 0x25, 0x1b, 0xf2, 0xbf, 0xdd, 0xfb, 0x70, 0x2b, 0xa1, 0x8c, 0x9c, 0x94, 0x84, 0x08}}},
+{{{0xe7, 0xc4, 0x43, 0x4d, 0xc9, 0x2b, 0x69, 0x5d, 0x1d, 0x3c, 0xaf, 0xbb, 0x43, 0x38, 0x4e, 0x98, 0x3d, 0xed, 0x0d, 0x21, 0x03, 0xfd, 0xf0, 0x99, 0x47, 0x04, 0xb0, 0x98, 0x69, 0x55, 0x72, 0x0f}} ,
+ {{0x5e, 0xdf, 0x15, 0x53, 0x3b, 0x86, 0x80, 0xb0, 0xf1, 0x70, 0x68, 0x8f, 0x66, 0x7c, 0x0e, 0x49, 0x1a, 0xd8, 0x6b, 0xfe, 0x4e, 0xef, 0xca, 0x47, 0xd4, 0x03, 0xc1, 0x37, 0x50, 0x9c, 0xc1, 0x16}}},
+{{{0xcd, 0x24, 0xc6, 0x3e, 0x0c, 0x82, 0x9b, 0x91, 0x2b, 0x61, 0x4a, 0xb2, 0x0f, 0x88, 0x55, 0x5f, 0x5a, 0x57, 0xff, 0xe5, 0x74, 0x0b, 0x13, 0x43, 0x00, 0xd8, 0x6b, 0xcf, 0xd2, 0x15, 0x03, 0x2c}} ,
+ {{0xdc, 0xff, 0x15, 0x61, 0x2f, 0x4a, 0x2f, 0x62, 0xf2, 0x04, 0x2f, 0xb5, 0x0c, 0xb7, 0x1e, 0x3f, 0x74, 0x1a, 0x0f, 0xd7, 0xea, 0xcd, 0xd9, 0x7d, 0xf6, 0x12, 0x0e, 0x2f, 0xdb, 0x5a, 0x3b, 0x16}}},
+{{{0x1b, 0x37, 0x47, 0xe3, 0xf5, 0x9e, 0xea, 0x2c, 0x2a, 0xe7, 0x82, 0x36, 0xf4, 0x1f, 0x81, 0x47, 0x92, 0x4b, 0x69, 0x0e, 0x11, 0x8c, 0x5d, 0x53, 0x5b, 0x81, 0x27, 0x08, 0xbc, 0xa0, 0xae, 0x25}} ,
+ {{0x69, 0x32, 0xa1, 0x05, 0x11, 0x42, 0x00, 0xd2, 0x59, 0xac, 0x4d, 0x62, 0x8b, 0x13, 0xe2, 0x50, 0x5d, 0xa0, 0x9d, 0x9b, 0xfd, 0xbb, 0x12, 0x41, 0x75, 0x41, 0x9e, 0xcc, 0xdc, 0xc7, 0xdc, 0x5d}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0xd9, 0xe3, 0x38, 0x06, 0x46, 0x70, 0x82, 0x5e, 0x28, 0x49, 0x79, 0xff, 0x25, 0xd2, 0x4e, 0x29, 0x8d, 0x06, 0xb0, 0x23, 0xae, 0x9b, 0x66, 0xe4, 0x7d, 0xc0, 0x70, 0x91, 0xa3, 0xfc, 0xec, 0x4e}} ,
+ {{0x62, 0x12, 0x37, 0x6a, 0x30, 0xf6, 0x1e, 0xfb, 0x14, 0x5c, 0x0d, 0x0e, 0xb7, 0x81, 0x6a, 0xe7, 0x08, 0x05, 0xac, 0xaa, 0x38, 0x46, 0xe2, 0x73, 0xea, 0x4b, 0x07, 0x81, 0x43, 0x7c, 0x9e, 0x5e}}},
+{{{0xfc, 0xf9, 0x21, 0x4f, 0x2e, 0x76, 0x9b, 0x1f, 0x28, 0x60, 0x77, 0x43, 0x32, 0x9d, 0xbe, 0x17, 0x30, 0x2a, 0xc6, 0x18, 0x92, 0x66, 0x62, 0x30, 0x98, 0x40, 0x11, 0xa6, 0x7f, 0x18, 0x84, 0x28}} ,
+ {{0x3f, 0xab, 0xd3, 0xf4, 0x8a, 0x76, 0xa1, 0x3c, 0xca, 0x2d, 0x49, 0xc3, 0xea, 0x08, 0x0b, 0x85, 0x17, 0x2a, 0xc3, 0x6c, 0x08, 0xfd, 0x57, 0x9f, 0x3d, 0x5f, 0xdf, 0x67, 0x68, 0x42, 0x00, 0x32}}},
+{{{0x51, 0x60, 0x1b, 0x06, 0x4f, 0x8a, 0x21, 0xba, 0x38, 0xa8, 0xba, 0xd6, 0x40, 0xf6, 0xe9, 0x9b, 0x76, 0x4d, 0x56, 0x21, 0x5b, 0x0a, 0x9b, 0x2e, 0x4f, 0x3d, 0x81, 0x32, 0x08, 0x9f, 0x97, 0x5b}} ,
+ {{0xe5, 0x44, 0xec, 0x06, 0x9d, 0x90, 0x79, 0x9f, 0xd3, 0xe0, 0x79, 0xaf, 0x8f, 0x10, 0xfd, 0xdd, 0x04, 0xae, 0x27, 0x97, 0x46, 0x33, 0x79, 0xea, 0xb8, 0x4e, 0xca, 0x5a, 0x59, 0x57, 0xe1, 0x0e}}},
+{{{0x1a, 0xda, 0xf3, 0xa5, 0x41, 0x43, 0x28, 0xfc, 0x7e, 0xe7, 0x71, 0xea, 0xc6, 0x3b, 0x59, 0xcc, 0x2e, 0xd3, 0x40, 0xec, 0xb3, 0x13, 0x6f, 0x44, 0xcd, 0x13, 0xb2, 0x37, 0xf2, 0x6e, 0xd9, 0x1c}} ,
+ {{0xe3, 0xdb, 0x60, 0xcd, 0x5c, 0x4a, 0x18, 0x0f, 0xef, 0x73, 0x36, 0x71, 0x8c, 0xf6, 0x11, 0xb4, 0xd8, 0xce, 0x17, 0x5e, 0x4f, 0x26, 0x77, 0x97, 0x5f, 0xcb, 0xef, 0x91, 0xeb, 0x6a, 0x62, 0x7a}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x18, 0x4a, 0xa2, 0x97, 0x08, 0x81, 0x2d, 0x83, 0xc4, 0xcc, 0xf0, 0x83, 0x7e, 0xec, 0x0d, 0x95, 0x4c, 0x5b, 0xfb, 0xfa, 0x98, 0x80, 0x4a, 0x66, 0x56, 0x0c, 0x51, 0xb3, 0xf2, 0x04, 0x5d, 0x27}} ,
+ {{0x3b, 0xb9, 0xb8, 0x06, 0x5a, 0x2e, 0xfe, 0xc3, 0x82, 0x37, 0x9c, 0xa3, 0x11, 0x1f, 0x9c, 0xa6, 0xda, 0x63, 0x48, 0x9b, 0xad, 0xde, 0x2d, 0xa6, 0xbc, 0x6e, 0x32, 0xda, 0x27, 0x65, 0xdd, 0x57}}},
+{{{0x84, 0x4f, 0x37, 0x31, 0x7d, 0x2e, 0xbc, 0xad, 0x87, 0x07, 0x2a, 0x6b, 0x37, 0xfc, 0x5f, 0xeb, 0x4e, 0x75, 0x35, 0xa6, 0xde, 0xab, 0x0a, 0x19, 0x3a, 0xb7, 0xb1, 0xef, 0x92, 0x6a, 0x3b, 0x3c}} ,
+ {{0x3b, 0xb2, 0x94, 0x6d, 0x39, 0x60, 0xac, 0xee, 0xe7, 0x81, 0x1a, 0x3b, 0x76, 0x87, 0x5c, 0x05, 0x94, 0x2a, 0x45, 0xb9, 0x80, 0xe9, 0x22, 0xb1, 0x07, 0xcb, 0x40, 0x9e, 0x70, 0x49, 0x6d, 0x12}}},
+{{{0xfd, 0x18, 0x78, 0x84, 0xa8, 0x4c, 0x7d, 0x6e, 0x59, 0xa6, 0xe5, 0x74, 0xf1, 0x19, 0xa6, 0x84, 0x2e, 0x51, 0xc1, 0x29, 0x13, 0xf2, 0x14, 0x6b, 0x5d, 0x53, 0x51, 0xf7, 0xef, 0xbf, 0x01, 0x22}} ,
+ {{0xa4, 0x4b, 0x62, 0x4c, 0xe6, 0xfd, 0x72, 0x07, 0xf2, 0x81, 0xfc, 0xf2, 0xbd, 0x12, 0x7c, 0x68, 0x76, 0x2a, 0xba, 0xf5, 0x65, 0xb1, 0x1f, 0x17, 0x0a, 0x38, 0xb0, 0xbf, 0xc0, 0xf8, 0xf4, 0x2a}}},
+{{{0x55, 0x60, 0x55, 0x5b, 0xe4, 0x1d, 0x71, 0x4c, 0x9d, 0x5b, 0x9f, 0x70, 0xa6, 0x85, 0x9a, 0x2c, 0xa0, 0xe2, 0x32, 0x48, 0xce, 0x9e, 0x2a, 0xa5, 0x07, 0x3b, 0xc7, 0x6c, 0x86, 0x77, 0xde, 0x3c}} ,
+ {{0xf7, 0x18, 0x7a, 0x96, 0x7e, 0x43, 0x57, 0xa9, 0x55, 0xfc, 0x4e, 0xb6, 0x72, 0x00, 0xf2, 0xe4, 0xd7, 0x52, 0xd3, 0xd3, 0xb6, 0x85, 0xf6, 0x71, 0xc7, 0x44, 0x3f, 0x7f, 0xd7, 0xb3, 0xf2, 0x79}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x46, 0xca, 0xa7, 0x55, 0x7b, 0x79, 0xf3, 0xca, 0x5a, 0x65, 0xf6, 0xed, 0x50, 0x14, 0x7b, 0xe4, 0xc4, 0x2a, 0x65, 0x9e, 0xe2, 0xf9, 0xca, 0xa7, 0x22, 0x26, 0x53, 0xcb, 0x21, 0x5b, 0xa7, 0x31}} ,
+ {{0x90, 0xd7, 0xc5, 0x26, 0x08, 0xbd, 0xb0, 0x53, 0x63, 0x58, 0xc3, 0x31, 0x5e, 0x75, 0x46, 0x15, 0x91, 0xa6, 0xf8, 0x2f, 0x1a, 0x08, 0x65, 0x88, 0x2f, 0x98, 0x04, 0xf1, 0x7c, 0x6e, 0x00, 0x77}}},
+{{{0x81, 0x21, 0x61, 0x09, 0xf6, 0x4e, 0xf1, 0x92, 0xee, 0x63, 0x61, 0x73, 0x87, 0xc7, 0x54, 0x0e, 0x42, 0x4b, 0xc9, 0x47, 0xd1, 0xb8, 0x7e, 0x91, 0x75, 0x37, 0x99, 0x28, 0xb8, 0xdd, 0x7f, 0x50}} ,
+ {{0x89, 0x8f, 0xc0, 0xbe, 0x5d, 0xd6, 0x9f, 0xa0, 0xf0, 0x9d, 0x81, 0xce, 0x3a, 0x7b, 0x98, 0x58, 0xbb, 0xd7, 0x78, 0xc8, 0x3f, 0x13, 0xf1, 0x74, 0x19, 0xdf, 0xf8, 0x98, 0x89, 0x5d, 0xfa, 0x5f}}},
+{{{0x9e, 0x35, 0x85, 0x94, 0x47, 0x1f, 0x90, 0x15, 0x26, 0xd0, 0x84, 0xed, 0x8a, 0x80, 0xf7, 0x63, 0x42, 0x86, 0x27, 0xd7, 0xf4, 0x75, 0x58, 0xdc, 0x9c, 0xc0, 0x22, 0x7e, 0x20, 0x35, 0xfd, 0x1f}} ,
+ {{0x68, 0x0e, 0x6f, 0x97, 0xba, 0x70, 0xbb, 0xa3, 0x0e, 0xe5, 0x0b, 0x12, 0xf4, 0xa2, 0xdc, 0x47, 0xf8, 0xe6, 0xd0, 0x23, 0x6c, 0x33, 0xa8, 0x99, 0x46, 0x6e, 0x0f, 0x44, 0xba, 0x76, 0x48, 0x0f}}},
+{{{0xa3, 0x2a, 0x61, 0x37, 0xe2, 0x59, 0x12, 0x0e, 0x27, 0xba, 0x64, 0x43, 0xae, 0xc0, 0x42, 0x69, 0x79, 0xa4, 0x1e, 0x29, 0x8b, 0x15, 0xeb, 0xf8, 0xaf, 0xd4, 0xa2, 0x68, 0x33, 0xb5, 0x7a, 0x24}} ,
+ {{0x2c, 0x19, 0x33, 0xdd, 0x1b, 0xab, 0xec, 0x01, 0xb0, 0x23, 0xf8, 0x42, 0x2b, 0x06, 0x88, 0xea, 0x3d, 0x2d, 0x00, 0x2a, 0x78, 0x45, 0x4d, 0x38, 0xed, 0x2e, 0x2e, 0x44, 0x49, 0xed, 0xcb, 0x33}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0xa0, 0x68, 0xe8, 0x41, 0x8f, 0x91, 0xf8, 0x11, 0x13, 0x90, 0x2e, 0xa7, 0xab, 0x30, 0xef, 0xad, 0xa0, 0x61, 0x00, 0x88, 0xef, 0xdb, 0xce, 0x5b, 0x5c, 0xbb, 0x62, 0xc8, 0x56, 0xf9, 0x00, 0x73}} ,
+ {{0x3f, 0x60, 0xc1, 0x82, 0x2d, 0xa3, 0x28, 0x58, 0x24, 0x9e, 0x9f, 0xe3, 0x70, 0xcc, 0x09, 0x4e, 0x1a, 0x3f, 0x11, 0x11, 0x15, 0x07, 0x3c, 0xa4, 0x41, 0xe0, 0x65, 0xa3, 0x0a, 0x41, 0x6d, 0x11}}},
+{{{0x31, 0x40, 0x01, 0x52, 0x56, 0x94, 0x5b, 0x28, 0x8a, 0xaa, 0x52, 0xee, 0xd8, 0x0a, 0x05, 0x8d, 0xcd, 0xb5, 0xaa, 0x2e, 0x38, 0xaa, 0xb7, 0x87, 0xf7, 0x2b, 0xfb, 0x04, 0xcb, 0x84, 0x3d, 0x54}} ,
+ {{0x20, 0xef, 0x59, 0xde, 0xa4, 0x2b, 0x93, 0x6e, 0x2e, 0xec, 0x42, 0x9a, 0xd4, 0x2d, 0xf4, 0x46, 0x58, 0x27, 0x2b, 0x18, 0x8f, 0x83, 0x3d, 0x69, 0x9e, 0xd4, 0x3e, 0xb6, 0xc5, 0xfd, 0x58, 0x03}}},
+{{{0x33, 0x89, 0xc9, 0x63, 0x62, 0x1c, 0x17, 0xb4, 0x60, 0xc4, 0x26, 0x68, 0x09, 0xc3, 0x2e, 0x37, 0x0f, 0x7b, 0xb4, 0x9c, 0xb6, 0xf9, 0xfb, 0xd4, 0x51, 0x78, 0xc8, 0x63, 0xea, 0x77, 0x47, 0x07}} ,
+ {{0x32, 0xb4, 0x18, 0x47, 0x79, 0xcb, 0xd4, 0x5a, 0x07, 0x14, 0x0f, 0xa0, 0xd5, 0xac, 0xd0, 0x41, 0x40, 0xab, 0x61, 0x23, 0xe5, 0x2a, 0x2a, 0x6f, 0xf7, 0xa8, 0xd4, 0x76, 0xef, 0xe7, 0x45, 0x6c}}},
+{{{0xa1, 0x5e, 0x60, 0x4f, 0xfb, 0xe1, 0x70, 0x6a, 0x1f, 0x55, 0x4f, 0x09, 0xb4, 0x95, 0x33, 0x36, 0xc6, 0x81, 0x01, 0x18, 0x06, 0x25, 0x27, 0xa4, 0xb4, 0x24, 0xa4, 0x86, 0x03, 0x4c, 0xac, 0x02}} ,
+ {{0x77, 0x38, 0xde, 0xd7, 0x60, 0x48, 0x07, 0xf0, 0x74, 0xa8, 0xff, 0x54, 0xe5, 0x30, 0x43, 0xff, 0x77, 0xfb, 0x21, 0x07, 0xff, 0xb2, 0x07, 0x6b, 0xe4, 0xe5, 0x30, 0xfc, 0x19, 0x6c, 0xa3, 0x01}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x13, 0xc5, 0x2c, 0xac, 0xd3, 0x83, 0x82, 0x7c, 0x29, 0xf7, 0x05, 0xa5, 0x00, 0xb6, 0x1f, 0x86, 0x55, 0xf4, 0xd6, 0x2f, 0x0c, 0x99, 0xd0, 0x65, 0x9b, 0x6b, 0x46, 0x0d, 0x43, 0xf8, 0x16, 0x28}} ,
+ {{0x1e, 0x7f, 0xb4, 0x74, 0x7e, 0xb1, 0x89, 0x4f, 0x18, 0x5a, 0xab, 0x64, 0x06, 0xdf, 0x45, 0x87, 0xe0, 0x6a, 0xc6, 0xf0, 0x0e, 0xc9, 0x24, 0x35, 0x38, 0xea, 0x30, 0x54, 0xb4, 0xc4, 0x52, 0x54}}},
+{{{0xe9, 0x9f, 0xdc, 0x3f, 0xc1, 0x89, 0x44, 0x74, 0x27, 0xe4, 0xc1, 0x90, 0xff, 0x4a, 0xa7, 0x3c, 0xee, 0xcd, 0xf4, 0x1d, 0x25, 0x94, 0x7f, 0x63, 0x16, 0x48, 0xbc, 0x64, 0xfe, 0x95, 0xc4, 0x0c}} ,
+ {{0x8b, 0x19, 0x75, 0x6e, 0x03, 0x06, 0x5e, 0x6a, 0x6f, 0x1a, 0x8c, 0xe3, 0xd3, 0x28, 0xf2, 0xe0, 0xb9, 0x7a, 0x43, 0x69, 0xe6, 0xd3, 0xc0, 0xfe, 0x7e, 0x97, 0xab, 0x6c, 0x7b, 0x8e, 0x13, 0x42}}},
+{{{0xd4, 0xca, 0x70, 0x3d, 0xab, 0xfb, 0x5f, 0x5e, 0x00, 0x0c, 0xcc, 0x77, 0x22, 0xf8, 0x78, 0x55, 0xae, 0x62, 0x35, 0xfb, 0x9a, 0xc6, 0x03, 0xe4, 0x0c, 0xee, 0xab, 0xc7, 0xc0, 0x89, 0x87, 0x54}} ,
+ {{0x32, 0xad, 0xae, 0x85, 0x58, 0x43, 0xb8, 0xb1, 0xe6, 0x3e, 0x00, 0x9c, 0x78, 0x88, 0x56, 0xdb, 0x9c, 0xfc, 0x79, 0xf6, 0xf9, 0x41, 0x5f, 0xb7, 0xbc, 0x11, 0xf9, 0x20, 0x36, 0x1c, 0x53, 0x2b}}},
+{{{0x5a, 0x20, 0x5b, 0xa1, 0xa5, 0x44, 0x91, 0x24, 0x02, 0x63, 0x12, 0x64, 0xb8, 0x55, 0xf6, 0xde, 0x2c, 0xdb, 0x47, 0xb8, 0xc6, 0x0a, 0xc3, 0x00, 0x78, 0x93, 0xd8, 0xf5, 0xf5, 0x18, 0x28, 0x0a}} ,
+ {{0xd6, 0x1b, 0x9a, 0x6c, 0xe5, 0x46, 0xea, 0x70, 0x96, 0x8d, 0x4e, 0x2a, 0x52, 0x21, 0x26, 0x4b, 0xb1, 0xbb, 0x0f, 0x7c, 0xa9, 0x9b, 0x04, 0xbb, 0x51, 0x08, 0xf1, 0x9a, 0xa4, 0x76, 0x7c, 0x18}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0xfa, 0x94, 0xf7, 0x40, 0xd0, 0xd7, 0xeb, 0xa9, 0x82, 0x36, 0xd5, 0x15, 0xb9, 0x33, 0x7a, 0xbf, 0x8a, 0xf2, 0x63, 0xaa, 0x37, 0xf5, 0x59, 0xac, 0xbd, 0xbb, 0x32, 0x36, 0xbe, 0x73, 0x99, 0x38}} ,
+ {{0x2c, 0xb3, 0xda, 0x7a, 0xd8, 0x3d, 0x99, 0xca, 0xd2, 0xf4, 0xda, 0x99, 0x8e, 0x4f, 0x98, 0xb7, 0xf4, 0xae, 0x3e, 0x9f, 0x8e, 0x35, 0x60, 0xa4, 0x33, 0x75, 0xa4, 0x04, 0x93, 0xb1, 0x6b, 0x4d}}},
+{{{0x97, 0x9d, 0xa8, 0xcd, 0x97, 0x7b, 0x9d, 0xb9, 0xe7, 0xa5, 0xef, 0xfd, 0xa8, 0x42, 0x6b, 0xc3, 0x62, 0x64, 0x7d, 0xa5, 0x1b, 0xc9, 0x9e, 0xd2, 0x45, 0xb9, 0xee, 0x03, 0xb0, 0xbf, 0xc0, 0x68}} ,
+ {{0xed, 0xb7, 0x84, 0x2c, 0xf6, 0xd3, 0xa1, 0x6b, 0x24, 0x6d, 0x87, 0x56, 0x97, 0x59, 0x79, 0x62, 0x9f, 0xac, 0xed, 0xf3, 0xc9, 0x89, 0x21, 0x2e, 0x04, 0xb3, 0xcc, 0x2f, 0xbe, 0xd6, 0x0a, 0x4b}}},
+{{{0x39, 0x61, 0x05, 0xed, 0x25, 0x89, 0x8b, 0x5d, 0x1b, 0xcb, 0x0c, 0x55, 0xf4, 0x6a, 0x00, 0x8a, 0x46, 0xe8, 0x1e, 0xc6, 0x83, 0xc8, 0x5a, 0x76, 0xdb, 0xcc, 0x19, 0x7a, 0xcc, 0x67, 0x46, 0x0b}} ,
+ {{0x53, 0xcf, 0xc2, 0xa1, 0xad, 0x6a, 0xf3, 0xcd, 0x8f, 0xc9, 0xde, 0x1c, 0xf8, 0x6c, 0x8f, 0xf8, 0x76, 0x42, 0xe7, 0xfe, 0xb2, 0x72, 0x21, 0x0a, 0x66, 0x74, 0x8f, 0xb7, 0xeb, 0xe4, 0x6f, 0x01}}},
+{{{0x22, 0x8c, 0x6b, 0xbe, 0xfc, 0x4d, 0x70, 0x62, 0x6e, 0x52, 0x77, 0x99, 0x88, 0x7e, 0x7b, 0x57, 0x7a, 0x0d, 0xfe, 0xdc, 0x72, 0x92, 0xf1, 0x68, 0x1d, 0x97, 0xd7, 0x7c, 0x8d, 0x53, 0x10, 0x37}} ,
+ {{0x53, 0x88, 0x77, 0x02, 0xca, 0x27, 0xa8, 0xe5, 0x45, 0xe2, 0xa8, 0x48, 0x2a, 0xab, 0x18, 0xca, 0xea, 0x2d, 0x2a, 0x54, 0x17, 0x37, 0x32, 0x09, 0xdc, 0xe0, 0x4a, 0xb7, 0x7d, 0x82, 0x10, 0x7d}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x8a, 0x64, 0x1e, 0x14, 0x0a, 0x57, 0xd4, 0xda, 0x5c, 0x96, 0x9b, 0x01, 0x4c, 0x67, 0xbf, 0x8b, 0x30, 0xfe, 0x08, 0xdb, 0x0d, 0xd5, 0xa8, 0xd7, 0x09, 0x11, 0x85, 0xa2, 0xd3, 0x45, 0xfb, 0x7e}} ,
+ {{0xda, 0x8c, 0xc2, 0xd0, 0xac, 0x18, 0xe8, 0x52, 0x36, 0xd4, 0x21, 0xa3, 0xdd, 0x57, 0x22, 0x79, 0xb7, 0xf8, 0x71, 0x9d, 0xc6, 0x91, 0x70, 0x86, 0x56, 0xbf, 0xa1, 0x11, 0x8b, 0x19, 0xe1, 0x0f}}},
+{{{0x18, 0x32, 0x98, 0x2c, 0x8f, 0x91, 0xae, 0x12, 0xf0, 0x8c, 0xea, 0xf3, 0x3c, 0xb9, 0x5d, 0xe4, 0x69, 0xed, 0xb2, 0x47, 0x18, 0xbd, 0xce, 0x16, 0x52, 0x5c, 0x23, 0xe2, 0xa5, 0x25, 0x52, 0x5d}} ,
+ {{0xb9, 0xb1, 0xe7, 0x5d, 0x4e, 0xbc, 0xee, 0xbb, 0x40, 0x81, 0x77, 0x82, 0x19, 0xab, 0xb5, 0xc6, 0xee, 0xab, 0x5b, 0x6b, 0x63, 0x92, 0x8a, 0x34, 0x8d, 0xcd, 0xee, 0x4f, 0x49, 0xe5, 0xc9, 0x7e}}},
+{{{0x21, 0xac, 0x8b, 0x22, 0xcd, 0xc3, 0x9a, 0xe9, 0x5e, 0x78, 0xbd, 0xde, 0xba, 0xad, 0xab, 0xbf, 0x75, 0x41, 0x09, 0xc5, 0x58, 0xa4, 0x7d, 0x92, 0xb0, 0x7f, 0xf2, 0xa1, 0xd1, 0xc0, 0xb3, 0x6d}} ,
+ {{0x62, 0x4f, 0xd0, 0x75, 0x77, 0xba, 0x76, 0x77, 0xd7, 0xb8, 0xd8, 0x92, 0x6f, 0x98, 0x34, 0x3d, 0xd6, 0x4e, 0x1c, 0x0f, 0xf0, 0x8f, 0x2e, 0xf1, 0xb3, 0xbd, 0xb1, 0xb9, 0xec, 0x99, 0xb4, 0x07}}},
+{{{0x60, 0x57, 0x2e, 0x9a, 0x72, 0x1d, 0x6b, 0x6e, 0x58, 0x33, 0x24, 0x8c, 0x48, 0x39, 0x46, 0x8e, 0x89, 0x6a, 0x88, 0x51, 0x23, 0x62, 0xb5, 0x32, 0x09, 0x36, 0xe3, 0x57, 0xf5, 0x98, 0xde, 0x6f}} ,
+ {{0x8b, 0x2c, 0x00, 0x48, 0x4a, 0xf9, 0x5b, 0x87, 0x69, 0x52, 0xe5, 0x5b, 0xd1, 0xb1, 0xe5, 0x25, 0x25, 0xe0, 0x9c, 0xc2, 0x13, 0x44, 0xe8, 0xb9, 0x0a, 0x70, 0xad, 0xbd, 0x0f, 0x51, 0x94, 0x69}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0xa2, 0xdc, 0xab, 0xa9, 0x25, 0x2d, 0xac, 0x5f, 0x03, 0x33, 0x08, 0xe7, 0x7e, 0xfe, 0x95, 0x36, 0x3c, 0x5b, 0x3a, 0xd3, 0x05, 0x82, 0x1c, 0x95, 0x2d, 0xd8, 0x77, 0x7e, 0x02, 0xd9, 0x5b, 0x70}} ,
+ {{0xc2, 0xfe, 0x1b, 0x0c, 0x67, 0xcd, 0xd6, 0xe0, 0x51, 0x8e, 0x2c, 0xe0, 0x79, 0x88, 0xf0, 0xcf, 0x41, 0x4a, 0xad, 0x23, 0xd4, 0x46, 0xca, 0x94, 0xa1, 0xc3, 0xeb, 0x28, 0x06, 0xfa, 0x17, 0x14}}},
+{{{0x7b, 0xaa, 0x70, 0x0a, 0x4b, 0xfb, 0xf5, 0xbf, 0x80, 0xc5, 0xcf, 0x08, 0x7a, 0xdd, 0xa1, 0xf4, 0x9d, 0x54, 0x50, 0x53, 0x23, 0x77, 0x23, 0xf5, 0x34, 0xa5, 0x22, 0xd1, 0x0d, 0x96, 0x2e, 0x47}} ,
+ {{0xcc, 0xb7, 0x32, 0x89, 0x57, 0xd0, 0x98, 0x75, 0xe4, 0x37, 0x99, 0xa9, 0xe8, 0xba, 0xed, 0xba, 0xeb, 0xc7, 0x4f, 0x15, 0x76, 0x07, 0x0c, 0x4c, 0xef, 0x9f, 0x52, 0xfc, 0x04, 0x5d, 0x58, 0x10}}},
+{{{0xce, 0x82, 0xf0, 0x8f, 0x79, 0x02, 0xa8, 0xd1, 0xda, 0x14, 0x09, 0x48, 0xee, 0x8a, 0x40, 0x98, 0x76, 0x60, 0x54, 0x5a, 0xde, 0x03, 0x24, 0xf5, 0xe6, 0x2f, 0xe1, 0x03, 0xbf, 0x68, 0x82, 0x7f}} ,
+ {{0x64, 0xe9, 0x28, 0xc7, 0xa4, 0xcf, 0x2a, 0xf9, 0x90, 0x64, 0x72, 0x2c, 0x8b, 0xeb, 0xec, 0xa0, 0xf2, 0x7d, 0x35, 0xb5, 0x90, 0x4d, 0x7f, 0x5b, 0x4a, 0x49, 0xe4, 0xb8, 0x3b, 0xc8, 0xa1, 0x2f}}},
+{{{0x8b, 0xc5, 0xcc, 0x3d, 0x69, 0xa6, 0xa1, 0x18, 0x44, 0xbc, 0x4d, 0x77, 0x37, 0xc7, 0x86, 0xec, 0x0c, 0xc9, 0xd6, 0x44, 0xa9, 0x23, 0x27, 0xb9, 0x03, 0x34, 0xa7, 0x0a, 0xd5, 0xc7, 0x34, 0x37}} ,
+ {{0xf9, 0x7e, 0x3e, 0x66, 0xee, 0xf9, 0x99, 0x28, 0xff, 0xad, 0x11, 0xd8, 0xe2, 0x66, 0xc5, 0xcd, 0x0f, 0x0d, 0x0b, 0x6a, 0xfc, 0x7c, 0x24, 0xa8, 0x4f, 0xa8, 0x5e, 0x80, 0x45, 0x8b, 0x6c, 0x41}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0xef, 0x1e, 0xec, 0xf7, 0x8d, 0x77, 0xf2, 0xea, 0xdb, 0x60, 0x03, 0x21, 0xc0, 0xff, 0x5e, 0x67, 0xc3, 0x71, 0x0b, 0x21, 0xb4, 0x41, 0xa0, 0x68, 0x38, 0xc6, 0x01, 0xa3, 0xd3, 0x51, 0x3c, 0x3c}} ,
+ {{0x92, 0xf8, 0xd6, 0x4b, 0xef, 0x42, 0x13, 0xb2, 0x4a, 0xc4, 0x2e, 0x72, 0x3f, 0xc9, 0x11, 0xbd, 0x74, 0x02, 0x0e, 0xf5, 0x13, 0x9d, 0x83, 0x1a, 0x1b, 0xd5, 0x54, 0xde, 0xc4, 0x1e, 0x16, 0x6c}}},
+{{{0x27, 0x52, 0xe4, 0x63, 0xaa, 0x94, 0xe6, 0xc3, 0x28, 0x9c, 0xc6, 0x56, 0xac, 0xfa, 0xb6, 0xbd, 0xe2, 0xcc, 0x76, 0xc6, 0x27, 0x27, 0xa2, 0x8e, 0x78, 0x2b, 0x84, 0x72, 0x10, 0xbd, 0x4e, 0x2a}} ,
+ {{0xea, 0xa7, 0x23, 0xef, 0x04, 0x61, 0x80, 0x50, 0xc9, 0x6e, 0xa5, 0x96, 0xd1, 0xd1, 0xc8, 0xc3, 0x18, 0xd7, 0x2d, 0xfd, 0x26, 0xbd, 0xcb, 0x7b, 0x92, 0x51, 0x0e, 0x4a, 0x65, 0x57, 0xb8, 0x49}}},
+{{{0xab, 0x55, 0x36, 0xc3, 0xec, 0x63, 0x55, 0x11, 0x55, 0xf6, 0xa5, 0xc7, 0x01, 0x5f, 0xfe, 0x79, 0xd8, 0x0a, 0xf7, 0x03, 0xd8, 0x98, 0x99, 0xf5, 0xd0, 0x00, 0x54, 0x6b, 0x66, 0x28, 0xf5, 0x25}} ,
+ {{0x7a, 0x8d, 0xa1, 0x5d, 0x70, 0x5d, 0x51, 0x27, 0xee, 0x30, 0x65, 0x56, 0x95, 0x46, 0xde, 0xbd, 0x03, 0x75, 0xb4, 0x57, 0x59, 0x89, 0xeb, 0x02, 0x9e, 0xcc, 0x89, 0x19, 0xa7, 0xcb, 0x17, 0x67}}},
+{{{0x6a, 0xeb, 0xfc, 0x9a, 0x9a, 0x10, 0xce, 0xdb, 0x3a, 0x1c, 0x3c, 0x6a, 0x9d, 0xea, 0x46, 0xbc, 0x45, 0x49, 0xac, 0xe3, 0x41, 0x12, 0x7c, 0xf0, 0xf7, 0x4f, 0xf9, 0xf7, 0xff, 0x2c, 0x89, 0x04}} ,
+ {{0x30, 0x31, 0x54, 0x1a, 0x46, 0xca, 0xe6, 0xc6, 0xcb, 0xe2, 0xc3, 0xc1, 0x8b, 0x75, 0x81, 0xbe, 0xee, 0xf8, 0xa3, 0x11, 0x1c, 0x25, 0xa3, 0xa7, 0x35, 0x51, 0x55, 0xe2, 0x25, 0xaa, 0xe2, 0x3a}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0xb4, 0x48, 0x10, 0x9f, 0x8a, 0x09, 0x76, 0xfa, 0xf0, 0x7a, 0xb0, 0x70, 0xf7, 0x83, 0x80, 0x52, 0x84, 0x2b, 0x26, 0xa2, 0xc4, 0x5d, 0x4f, 0xba, 0xb1, 0xc8, 0x40, 0x0d, 0x78, 0x97, 0xc4, 0x60}} ,
+ {{0xd4, 0xb1, 0x6c, 0x08, 0xc7, 0x40, 0x38, 0x73, 0x5f, 0x0b, 0xf3, 0x76, 0x5d, 0xb2, 0xa5, 0x2f, 0x57, 0x57, 0x07, 0xed, 0x08, 0xa2, 0x6c, 0x4f, 0x08, 0x02, 0xb5, 0x0e, 0xee, 0x44, 0xfa, 0x22}}},
+{{{0x0f, 0x00, 0x3f, 0xa6, 0x04, 0x19, 0x56, 0x65, 0x31, 0x7f, 0x8b, 0xeb, 0x0d, 0xe1, 0x47, 0x89, 0x97, 0x16, 0x53, 0xfa, 0x81, 0xa7, 0xaa, 0xb2, 0xbf, 0x67, 0xeb, 0x72, 0x60, 0x81, 0x0d, 0x48}} ,
+ {{0x7e, 0x13, 0x33, 0xcd, 0xa8, 0x84, 0x56, 0x1e, 0x67, 0xaf, 0x6b, 0x43, 0xac, 0x17, 0xaf, 0x16, 0xc0, 0x52, 0x99, 0x49, 0x5b, 0x87, 0x73, 0x7e, 0xb5, 0x43, 0xda, 0x6b, 0x1d, 0x0f, 0x2d, 0x55}}},
+{{{0xe9, 0x58, 0x1f, 0xff, 0x84, 0x3f, 0x93, 0x1c, 0xcb, 0xe1, 0x30, 0x69, 0xa5, 0x75, 0x19, 0x7e, 0x14, 0x5f, 0xf8, 0xfc, 0x09, 0xdd, 0xa8, 0x78, 0x9d, 0xca, 0x59, 0x8b, 0xd1, 0x30, 0x01, 0x13}} ,
+ {{0xff, 0x76, 0x03, 0xc5, 0x4b, 0x89, 0x99, 0x70, 0x00, 0x59, 0x70, 0x9c, 0xd5, 0xd9, 0x11, 0x89, 0x5a, 0x46, 0xfe, 0xef, 0xdc, 0xd9, 0x55, 0x2b, 0x45, 0xa7, 0xb0, 0x2d, 0xfb, 0x24, 0xc2, 0x29}}},
+{{{0x38, 0x06, 0xf8, 0x0b, 0xac, 0x82, 0xc4, 0x97, 0x2b, 0x90, 0xe0, 0xf7, 0xa8, 0xab, 0x6c, 0x08, 0x80, 0x66, 0x90, 0x46, 0xf7, 0x26, 0x2d, 0xf8, 0xf1, 0xc4, 0x6b, 0x4a, 0x82, 0x98, 0x8e, 0x37}} ,
+ {{0x8e, 0xb4, 0xee, 0xb8, 0xd4, 0x3f, 0xb2, 0x1b, 0xe0, 0x0a, 0x3d, 0x75, 0x34, 0x28, 0xa2, 0x8e, 0xc4, 0x92, 0x7b, 0xfe, 0x60, 0x6e, 0x6d, 0xb8, 0x31, 0x1d, 0x62, 0x0d, 0x78, 0x14, 0x42, 0x11}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x5e, 0xa8, 0xd8, 0x04, 0x9b, 0x73, 0xc9, 0xc9, 0xdc, 0x0d, 0x73, 0xbf, 0x0a, 0x0a, 0x73, 0xff, 0x18, 0x1f, 0x9c, 0x51, 0xaa, 0xc6, 0xf1, 0x83, 0x25, 0xfd, 0xab, 0xa3, 0x11, 0xd3, 0x01, 0x24}} ,
+ {{0x4d, 0xe3, 0x7e, 0x38, 0x62, 0x5e, 0x64, 0xbb, 0x2b, 0x53, 0xb5, 0x03, 0x68, 0xc4, 0xf2, 0x2b, 0x5a, 0x03, 0x32, 0x99, 0x4a, 0x41, 0x9a, 0xe1, 0x1a, 0xae, 0x8c, 0x48, 0xf3, 0x24, 0x32, 0x65}}},
+{{{0xe8, 0xdd, 0xad, 0x3a, 0x8c, 0xea, 0xf4, 0xb3, 0xb2, 0xe5, 0x73, 0xf2, 0xed, 0x8b, 0xbf, 0xed, 0xb1, 0x0c, 0x0c, 0xfb, 0x2b, 0xf1, 0x01, 0x48, 0xe8, 0x26, 0x03, 0x8e, 0x27, 0x4d, 0x96, 0x72}} ,
+ {{0xc8, 0x09, 0x3b, 0x60, 0xc9, 0x26, 0x4d, 0x7c, 0xf2, 0x9c, 0xd4, 0xa1, 0x3b, 0x26, 0xc2, 0x04, 0x33, 0x44, 0x76, 0x3c, 0x02, 0xbb, 0x11, 0x42, 0x0c, 0x22, 0xb7, 0xc6, 0xe1, 0xac, 0xb4, 0x0e}}},
+{{{0x6f, 0x85, 0xe7, 0xef, 0xde, 0x67, 0x30, 0xfc, 0xbf, 0x5a, 0xe0, 0x7b, 0x7a, 0x2a, 0x54, 0x6b, 0x5d, 0x62, 0x85, 0xa1, 0xf8, 0x16, 0x88, 0xec, 0x61, 0xb9, 0x96, 0xb5, 0xef, 0x2d, 0x43, 0x4d}} ,
+ {{0x7c, 0x31, 0x33, 0xcc, 0xe4, 0xcf, 0x6c, 0xff, 0x80, 0x47, 0x77, 0xd1, 0xd8, 0xe9, 0x69, 0x97, 0x98, 0x7f, 0x20, 0x57, 0x1d, 0x1d, 0x4f, 0x08, 0x27, 0xc8, 0x35, 0x57, 0x40, 0xc6, 0x21, 0x0c}}},
+{{{0xd2, 0x8e, 0x9b, 0xfa, 0x42, 0x8e, 0xdf, 0x8f, 0xc7, 0x86, 0xf9, 0xa4, 0xca, 0x70, 0x00, 0x9d, 0x21, 0xbf, 0xec, 0x57, 0x62, 0x30, 0x58, 0x8c, 0x0d, 0x35, 0xdb, 0x5d, 0x8b, 0x6a, 0xa0, 0x5a}} ,
+ {{0xc1, 0x58, 0x7c, 0x0d, 0x20, 0xdd, 0x11, 0x26, 0x5f, 0x89, 0x3b, 0x97, 0x58, 0xf8, 0x8b, 0xe3, 0xdf, 0x32, 0xe2, 0xfc, 0xd8, 0x67, 0xf2, 0xa5, 0x37, 0x1e, 0x6d, 0xec, 0x7c, 0x27, 0x20, 0x79}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0xd0, 0xe9, 0xc0, 0xfa, 0x95, 0x45, 0x23, 0x96, 0xf1, 0x2c, 0x79, 0x25, 0x14, 0xce, 0x40, 0x14, 0x44, 0x2c, 0x36, 0x50, 0xd9, 0x63, 0x56, 0xb7, 0x56, 0x3b, 0x9e, 0xa7, 0xef, 0x89, 0xbb, 0x0e}} ,
+ {{0xce, 0x7f, 0xdc, 0x0a, 0xcc, 0x82, 0x1c, 0x0a, 0x78, 0x71, 0xe8, 0x74, 0x8d, 0x01, 0x30, 0x0f, 0xa7, 0x11, 0x4c, 0xdf, 0x38, 0xd7, 0xa7, 0x0d, 0xf8, 0x48, 0x52, 0x00, 0x80, 0x7b, 0x5f, 0x0e}}},
+{{{0x25, 0x83, 0xe6, 0x94, 0x7b, 0x81, 0xb2, 0x91, 0xae, 0x0e, 0x05, 0xc9, 0xa3, 0x68, 0x2d, 0xd9, 0x88, 0x25, 0x19, 0x2a, 0x61, 0x61, 0x21, 0x97, 0x15, 0xa1, 0x35, 0xa5, 0x46, 0xc8, 0xa2, 0x0e}} ,
+ {{0x1b, 0x03, 0x0d, 0x8b, 0x5a, 0x1b, 0x97, 0x4b, 0xf2, 0x16, 0x31, 0x3d, 0x1f, 0x33, 0xa0, 0x50, 0x3a, 0x18, 0xbe, 0x13, 0xa1, 0x76, 0xc1, 0xba, 0x1b, 0xf1, 0x05, 0x7b, 0x33, 0xa8, 0x82, 0x3b}}},
+{{{0xba, 0x36, 0x7b, 0x6d, 0xa9, 0xea, 0x14, 0x12, 0xc5, 0xfa, 0x91, 0x00, 0xba, 0x9b, 0x99, 0xcc, 0x56, 0x02, 0xe9, 0xa0, 0x26, 0x40, 0x66, 0x8c, 0xc4, 0xf8, 0x85, 0x33, 0x68, 0xe7, 0x03, 0x20}} ,
+ {{0x50, 0x5b, 0xff, 0xa9, 0xb2, 0xf1, 0xf1, 0x78, 0xcf, 0x14, 0xa4, 0xa9, 0xfc, 0x09, 0x46, 0x94, 0x54, 0x65, 0x0d, 0x9c, 0x5f, 0x72, 0x21, 0xe2, 0x97, 0xa5, 0x2d, 0x81, 0xce, 0x4a, 0x5f, 0x79}}},
+{{{0x3d, 0x5f, 0x5c, 0xd2, 0xbc, 0x7d, 0x77, 0x0e, 0x2a, 0x6d, 0x22, 0x45, 0x84, 0x06, 0xc4, 0xdd, 0xc6, 0xa6, 0xc6, 0xd7, 0x49, 0xad, 0x6d, 0x87, 0x91, 0x0e, 0x3a, 0x67, 0x1d, 0x2c, 0x1d, 0x56}} ,
+ {{0xfe, 0x7a, 0x74, 0xcf, 0xd4, 0xd2, 0xe5, 0x19, 0xde, 0xd0, 0xdb, 0x70, 0x23, 0x69, 0xe6, 0x6d, 0xec, 0xec, 0xcc, 0x09, 0x33, 0x6a, 0x77, 0xdc, 0x6b, 0x22, 0x76, 0x5d, 0x92, 0x09, 0xac, 0x2d}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x23, 0x15, 0x17, 0xeb, 0xd3, 0xdb, 0x12, 0x5e, 0x01, 0xf0, 0x91, 0xab, 0x2c, 0x41, 0xce, 0xac, 0xed, 0x1b, 0x4b, 0x2d, 0xbc, 0xdb, 0x17, 0x66, 0x89, 0x46, 0xad, 0x4b, 0x1e, 0x6f, 0x0b, 0x14}} ,
+ {{0x11, 0xce, 0xbf, 0xb6, 0x77, 0x2d, 0x48, 0x22, 0x18, 0x4f, 0xa3, 0x5d, 0x4a, 0xb0, 0x70, 0x12, 0x3e, 0x54, 0xd7, 0xd8, 0x0e, 0x2b, 0x27, 0xdc, 0x53, 0xff, 0xca, 0x8c, 0x59, 0xb3, 0x4e, 0x44}}},
+{{{0x07, 0x76, 0x61, 0x0f, 0x66, 0xb2, 0x21, 0x39, 0x7e, 0xc0, 0xec, 0x45, 0x28, 0x82, 0xa1, 0x29, 0x32, 0x44, 0x35, 0x13, 0x5e, 0x61, 0x5e, 0x54, 0xcb, 0x7c, 0xef, 0xf6, 0x41, 0xcf, 0x9f, 0x0a}} ,
+ {{0xdd, 0xf9, 0xda, 0x84, 0xc3, 0xe6, 0x8a, 0x9f, 0x24, 0xd2, 0x96, 0x5d, 0x39, 0x6f, 0x58, 0x8c, 0xc1, 0x56, 0x93, 0xab, 0xb5, 0x79, 0x3b, 0xd2, 0xa8, 0x73, 0x16, 0xed, 0xfa, 0xb4, 0x2f, 0x73}}},
+{{{0x8b, 0xb1, 0x95, 0xe5, 0x92, 0x50, 0x35, 0x11, 0x76, 0xac, 0xf4, 0x4d, 0x24, 0xc3, 0x32, 0xe6, 0xeb, 0xfe, 0x2c, 0x87, 0xc4, 0xf1, 0x56, 0xc4, 0x75, 0x24, 0x7a, 0x56, 0x85, 0x5a, 0x3a, 0x13}} ,
+ {{0x0d, 0x16, 0xac, 0x3c, 0x4a, 0x58, 0x86, 0x3a, 0x46, 0x7f, 0x6c, 0xa3, 0x52, 0x6e, 0x37, 0xe4, 0x96, 0x9c, 0xe9, 0x5c, 0x66, 0x41, 0x67, 0xe4, 0xfb, 0x79, 0x0c, 0x05, 0xf6, 0x64, 0xd5, 0x7c}}},
+{{{0x28, 0xc1, 0xe1, 0x54, 0x73, 0xf2, 0xbf, 0x76, 0x74, 0x19, 0x19, 0x1b, 0xe4, 0xb9, 0xa8, 0x46, 0x65, 0x73, 0xf3, 0x77, 0x9b, 0x29, 0x74, 0x5b, 0xc6, 0x89, 0x6c, 0x2c, 0x7c, 0xf8, 0xb3, 0x0f}} ,
+ {{0xf7, 0xd5, 0xe9, 0x74, 0x5d, 0xb8, 0x25, 0x16, 0xb5, 0x30, 0xbc, 0x84, 0xc5, 0xf0, 0xad, 0xca, 0x12, 0x28, 0xbc, 0x9d, 0xd4, 0xfa, 0x82, 0xe6, 0xe3, 0xbf, 0xa2, 0x15, 0x2c, 0xd4, 0x34, 0x10}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x61, 0xb1, 0x46, 0xba, 0x0e, 0x31, 0xa5, 0x67, 0x6c, 0x7f, 0xd6, 0xd9, 0x27, 0x85, 0x0f, 0x79, 0x14, 0xc8, 0x6c, 0x2f, 0x5f, 0x5b, 0x9c, 0x35, 0x3d, 0x38, 0x86, 0x77, 0x65, 0x55, 0x6a, 0x7b}} ,
+ {{0xd3, 0xb0, 0x3a, 0x66, 0x60, 0x1b, 0x43, 0xf1, 0x26, 0x58, 0x99, 0x09, 0x8f, 0x2d, 0xa3, 0x14, 0x71, 0x85, 0xdb, 0xed, 0xf6, 0x26, 0xd5, 0x61, 0x9a, 0x73, 0xac, 0x0e, 0xea, 0xac, 0xb7, 0x0c}}},
+{{{0x5e, 0xf4, 0xe5, 0x17, 0x0e, 0x10, 0x9f, 0xe7, 0x43, 0x5f, 0x67, 0x5c, 0xac, 0x4b, 0xe5, 0x14, 0x41, 0xd2, 0xbf, 0x48, 0xf5, 0x14, 0xb0, 0x71, 0xc6, 0x61, 0xc1, 0xb2, 0x70, 0x58, 0xd2, 0x5a}} ,
+ {{0x2d, 0xba, 0x16, 0x07, 0x92, 0x94, 0xdc, 0xbd, 0x50, 0x2b, 0xc9, 0x7f, 0x42, 0x00, 0xba, 0x61, 0xed, 0xf8, 0x43, 0xed, 0xf5, 0xf9, 0x40, 0x60, 0xb2, 0xb0, 0x82, 0xcb, 0xed, 0x75, 0xc7, 0x65}}},
+{{{0x80, 0xba, 0x0d, 0x09, 0x40, 0xa7, 0x39, 0xa6, 0x67, 0x34, 0x7e, 0x66, 0xbe, 0x56, 0xfb, 0x53, 0x78, 0xc4, 0x46, 0xe8, 0xed, 0x68, 0x6c, 0x7f, 0xce, 0xe8, 0x9f, 0xce, 0xa2, 0x64, 0x58, 0x53}} ,
+ {{0xe8, 0xc1, 0xa9, 0xc2, 0x7b, 0x59, 0x21, 0x33, 0xe2, 0x43, 0x73, 0x2b, 0xac, 0x2d, 0xc1, 0x89, 0x3b, 0x15, 0xe2, 0xd5, 0xc0, 0x97, 0x8a, 0xfd, 0x6f, 0x36, 0x33, 0xb7, 0xb9, 0xc3, 0x88, 0x09}}},
+{{{0xd0, 0xb6, 0x56, 0x30, 0x5c, 0xae, 0xb3, 0x75, 0x44, 0xa4, 0x83, 0x51, 0x6e, 0x01, 0x65, 0xef, 0x45, 0x76, 0xe6, 0xf5, 0xa2, 0x0d, 0xd4, 0x16, 0x3b, 0x58, 0x2f, 0xf2, 0x2f, 0x36, 0x18, 0x3f}} ,
+ {{0xfd, 0x2f, 0xe0, 0x9b, 0x1e, 0x8c, 0xc5, 0x18, 0xa9, 0xca, 0xd4, 0x2b, 0x35, 0xb6, 0x95, 0x0a, 0x9f, 0x7e, 0xfb, 0xc4, 0xef, 0x88, 0x7b, 0x23, 0x43, 0xec, 0x2f, 0x0d, 0x0f, 0x7a, 0xfc, 0x5c}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x8d, 0xd2, 0xda, 0xc7, 0x44, 0xd6, 0x7a, 0xdb, 0x26, 0x7d, 0x1d, 0xb8, 0xe1, 0xde, 0x9d, 0x7a, 0x7d, 0x17, 0x7e, 0x1c, 0x37, 0x04, 0x8d, 0x2d, 0x7c, 0x5e, 0x18, 0x38, 0x1e, 0xaf, 0xc7, 0x1b}} ,
+ {{0x33, 0x48, 0x31, 0x00, 0x59, 0xf6, 0xf2, 0xca, 0x0f, 0x27, 0x1b, 0x63, 0x12, 0x7e, 0x02, 0x1d, 0x49, 0xc0, 0x5d, 0x79, 0x87, 0xef, 0x5e, 0x7a, 0x2f, 0x1f, 0x66, 0x55, 0xd8, 0x09, 0xd9, 0x61}}},
+{{{0x54, 0x83, 0x02, 0x18, 0x82, 0x93, 0x99, 0x07, 0xd0, 0xa7, 0xda, 0xd8, 0x75, 0x89, 0xfa, 0xf2, 0xd9, 0xa3, 0xb8, 0x6b, 0x5a, 0x35, 0x28, 0xd2, 0x6b, 0x59, 0xc2, 0xf8, 0x45, 0xe2, 0xbc, 0x06}} ,
+ {{0x65, 0xc0, 0xa3, 0x88, 0x51, 0x95, 0xfc, 0x96, 0x94, 0x78, 0xe8, 0x0d, 0x8b, 0x41, 0xc9, 0xc2, 0x58, 0x48, 0x75, 0x10, 0x2f, 0xcd, 0x2a, 0xc9, 0xa0, 0x6d, 0x0f, 0xdd, 0x9c, 0x98, 0x26, 0x3d}}},
+{{{0x2f, 0x66, 0x29, 0x1b, 0x04, 0x89, 0xbd, 0x7e, 0xee, 0x6e, 0xdd, 0xb7, 0x0e, 0xef, 0xb0, 0x0c, 0xb4, 0xfc, 0x7f, 0xc2, 0xc9, 0x3a, 0x3c, 0x64, 0xef, 0x45, 0x44, 0xaf, 0x8a, 0x90, 0x65, 0x76}} ,
+ {{0xa1, 0x4c, 0x70, 0x4b, 0x0e, 0xa0, 0x83, 0x70, 0x13, 0xa4, 0xaf, 0xb8, 0x38, 0x19, 0x22, 0x65, 0x09, 0xb4, 0x02, 0x4f, 0x06, 0xf8, 0x17, 0xce, 0x46, 0x45, 0xda, 0x50, 0x7c, 0x8a, 0xd1, 0x4e}}},
+{{{0xf7, 0xd4, 0x16, 0x6c, 0x4e, 0x95, 0x9d, 0x5d, 0x0f, 0x91, 0x2b, 0x52, 0xfe, 0x5c, 0x34, 0xe5, 0x30, 0xe6, 0xa4, 0x3b, 0xf3, 0xf3, 0x34, 0x08, 0xa9, 0x4a, 0xa0, 0xb5, 0x6e, 0xb3, 0x09, 0x0a}} ,
+ {{0x26, 0xd9, 0x5e, 0xa3, 0x0f, 0xeb, 0xa2, 0xf3, 0x20, 0x3b, 0x37, 0xd4, 0xe4, 0x9e, 0xce, 0x06, 0x3d, 0x53, 0xed, 0xae, 0x2b, 0xeb, 0xb6, 0x24, 0x0a, 0x11, 0xa3, 0x0f, 0xd6, 0x7f, 0xa4, 0x3a}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0xdb, 0x9f, 0x2c, 0xfc, 0xd6, 0xb2, 0x1e, 0x2e, 0x52, 0x7a, 0x06, 0x87, 0x2d, 0x86, 0x72, 0x2b, 0x6d, 0x90, 0x77, 0x46, 0x43, 0xb5, 0x7a, 0xf8, 0x60, 0x7d, 0x91, 0x60, 0x5b, 0x9d, 0x9e, 0x07}} ,
+ {{0x97, 0x87, 0xc7, 0x04, 0x1c, 0x38, 0x01, 0x39, 0x58, 0xc7, 0x85, 0xa3, 0xfc, 0x64, 0x00, 0x64, 0x25, 0xa2, 0xbf, 0x50, 0x94, 0xca, 0x26, 0x31, 0x45, 0x0a, 0x24, 0xd2, 0x51, 0x29, 0x51, 0x16}}},
+{{{0x4d, 0x4a, 0xd7, 0x98, 0x71, 0x57, 0xac, 0x7d, 0x8b, 0x37, 0xbd, 0x63, 0xff, 0x87, 0xb1, 0x49, 0x95, 0x20, 0x7c, 0xcf, 0x7c, 0x59, 0xc4, 0x91, 0x9c, 0xef, 0xd0, 0xdb, 0x60, 0x09, 0x9d, 0x46}} ,
+ {{0xcb, 0x78, 0x94, 0x90, 0xe4, 0x45, 0xb3, 0xf6, 0xd9, 0xf6, 0x57, 0x74, 0xd5, 0xf8, 0x83, 0x4f, 0x39, 0xc9, 0xbd, 0x88, 0xc2, 0x57, 0x21, 0x1f, 0x24, 0x32, 0x68, 0xf8, 0xc7, 0x21, 0x5f, 0x0b}}},
+{{{0x2a, 0x36, 0x68, 0xfc, 0x5f, 0xb6, 0x4f, 0xa5, 0xe3, 0x9d, 0x24, 0x2f, 0xc0, 0x93, 0x61, 0xcf, 0xf8, 0x0a, 0xed, 0xe1, 0xdb, 0x27, 0xec, 0x0e, 0x14, 0x32, 0x5f, 0x8e, 0xa1, 0x62, 0x41, 0x16}} ,
+ {{0x95, 0x21, 0x01, 0xce, 0x95, 0x5b, 0x0e, 0x57, 0xc7, 0xb9, 0x62, 0xb5, 0x28, 0xca, 0x11, 0xec, 0xb4, 0x46, 0x06, 0x73, 0x26, 0xff, 0xfb, 0x66, 0x7d, 0xee, 0x5f, 0xb2, 0x56, 0xfd, 0x2a, 0x08}}},
+{{{0x92, 0x67, 0x77, 0x56, 0xa1, 0xff, 0xc4, 0xc5, 0x95, 0xf0, 0xe3, 0x3a, 0x0a, 0xca, 0x94, 0x4d, 0x9e, 0x7e, 0x3d, 0xb9, 0x6e, 0xb6, 0xb0, 0xce, 0xa4, 0x30, 0x89, 0x99, 0xe9, 0xad, 0x11, 0x59}} ,
+ {{0xf6, 0x48, 0x95, 0xa1, 0x6f, 0x5f, 0xb7, 0xa5, 0xbb, 0x30, 0x00, 0x1c, 0xd2, 0x8a, 0xd6, 0x25, 0x26, 0x1b, 0xb2, 0x0d, 0x37, 0x6a, 0x05, 0xf4, 0x9d, 0x3e, 0x17, 0x2a, 0x43, 0xd2, 0x3a, 0x06}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x32, 0x99, 0x93, 0xd1, 0x9a, 0x72, 0xf3, 0xa9, 0x16, 0xbd, 0xb4, 0x4c, 0xdd, 0xf9, 0xd4, 0xb2, 0x64, 0x9a, 0xd3, 0x05, 0xe4, 0xa3, 0x73, 0x1c, 0xcb, 0x7e, 0x57, 0x67, 0xff, 0x04, 0xb3, 0x10}} ,
+ {{0xb9, 0x4b, 0xa4, 0xad, 0xd0, 0x6d, 0x61, 0x23, 0xb4, 0xaf, 0x34, 0xa9, 0xaa, 0x65, 0xec, 0xd9, 0x69, 0xe3, 0x85, 0xcd, 0xcc, 0xe7, 0xb0, 0x9b, 0x41, 0xc1, 0x1c, 0xf9, 0xa0, 0xfa, 0xb7, 0x13}}},
+{{{0x04, 0xfd, 0x88, 0x3c, 0x0c, 0xd0, 0x09, 0x52, 0x51, 0x4f, 0x06, 0x19, 0xcc, 0xc3, 0xbb, 0xde, 0x80, 0xc5, 0x33, 0xbc, 0xf9, 0xf3, 0x17, 0x36, 0xdd, 0xc6, 0xde, 0xe8, 0x9b, 0x5d, 0x79, 0x1b}} ,
+ {{0x65, 0x0a, 0xbe, 0x51, 0x57, 0xad, 0x50, 0x79, 0x08, 0x71, 0x9b, 0x07, 0x95, 0x8f, 0xfb, 0xae, 0x4b, 0x38, 0xba, 0xcf, 0x53, 0x2a, 0x86, 0x1e, 0xc0, 0x50, 0x5c, 0x67, 0x1b, 0xf6, 0x87, 0x6c}}},
+{{{0x4f, 0x00, 0xb2, 0x66, 0x55, 0xed, 0x4a, 0xed, 0x8d, 0xe1, 0x66, 0x18, 0xb2, 0x14, 0x74, 0x8d, 0xfd, 0x1a, 0x36, 0x0f, 0x26, 0x5c, 0x8b, 0x89, 0xf3, 0xab, 0xf2, 0xf3, 0x24, 0x67, 0xfd, 0x70}} ,
+ {{0xfd, 0x4e, 0x2a, 0xc1, 0x3a, 0xca, 0x8f, 0x00, 0xd8, 0xec, 0x74, 0x67, 0xef, 0x61, 0xe0, 0x28, 0xd0, 0x96, 0xf4, 0x48, 0xde, 0x81, 0xe3, 0xef, 0xdc, 0xaa, 0x7d, 0xf3, 0xb6, 0x55, 0xa6, 0x65}}},
+{{{0xeb, 0xcb, 0xc5, 0x70, 0x91, 0x31, 0x10, 0x93, 0x0d, 0xc8, 0xd0, 0xef, 0x62, 0xe8, 0x6f, 0x82, 0xe3, 0x69, 0x3d, 0x91, 0x7f, 0x31, 0xe1, 0x26, 0x35, 0x3c, 0x4a, 0x2f, 0xab, 0xc4, 0x9a, 0x5e}} ,
+ {{0xab, 0x1b, 0xb5, 0xe5, 0x2b, 0xc3, 0x0e, 0x29, 0xb0, 0xd0, 0x73, 0xe6, 0x4f, 0x64, 0xf2, 0xbc, 0xe4, 0xe4, 0xe1, 0x9a, 0x52, 0x33, 0x2f, 0xbd, 0xcc, 0x03, 0xee, 0x8a, 0xfa, 0x00, 0x5f, 0x50}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0xf6, 0xdb, 0x0d, 0x22, 0x3d, 0xb5, 0x14, 0x75, 0x31, 0xf0, 0x81, 0xe2, 0xb9, 0x37, 0xa2, 0xa9, 0x84, 0x11, 0x9a, 0x07, 0xb5, 0x53, 0x89, 0x78, 0xa9, 0x30, 0x27, 0xa1, 0xf1, 0x4e, 0x5c, 0x2e}} ,
+ {{0x8b, 0x00, 0x54, 0xfb, 0x4d, 0xdc, 0xcb, 0x17, 0x35, 0x40, 0xff, 0xb7, 0x8c, 0xfe, 0x4a, 0xe4, 0x4e, 0x99, 0x4e, 0xa8, 0x74, 0x54, 0x5d, 0x5c, 0x96, 0xa3, 0x12, 0x55, 0x36, 0x31, 0x17, 0x5c}}},
+{{{0xce, 0x24, 0xef, 0x7b, 0x86, 0xf2, 0x0f, 0x77, 0xe8, 0x5c, 0x7d, 0x87, 0x38, 0x2d, 0xef, 0xaf, 0xf2, 0x8c, 0x72, 0x2e, 0xeb, 0xb6, 0x55, 0x4b, 0x6e, 0xf1, 0x4e, 0x8a, 0x0e, 0x9a, 0x6c, 0x4c}} ,
+ {{0x25, 0xea, 0x86, 0xc2, 0xd1, 0x4f, 0xb7, 0x3e, 0xa8, 0x5c, 0x8d, 0x66, 0x81, 0x25, 0xed, 0xc5, 0x4c, 0x05, 0xb9, 0xd8, 0xd6, 0x70, 0xbe, 0x73, 0x82, 0xe8, 0xa1, 0xe5, 0x1e, 0x71, 0xd5, 0x26}}},
+{{{0x4e, 0x6d, 0xc3, 0xa7, 0x4f, 0x22, 0x45, 0x26, 0xa2, 0x7e, 0x16, 0xf7, 0xf7, 0x63, 0xdc, 0x86, 0x01, 0x2a, 0x71, 0x38, 0x5c, 0x33, 0xc3, 0xce, 0x30, 0xff, 0xf9, 0x2c, 0x91, 0x71, 0x8a, 0x72}} ,
+ {{0x8c, 0x44, 0x09, 0x28, 0xd5, 0x23, 0xc9, 0x8f, 0xf3, 0x84, 0x45, 0xc6, 0x9a, 0x5e, 0xff, 0xd2, 0xc7, 0x57, 0x93, 0xa3, 0xc1, 0x69, 0xdd, 0x62, 0x0f, 0xda, 0x5c, 0x30, 0x59, 0x5d, 0xe9, 0x4c}}},
+{{{0x92, 0x7e, 0x50, 0x27, 0x72, 0xd7, 0x0c, 0xd6, 0x69, 0x96, 0x81, 0x35, 0x84, 0x94, 0x35, 0x8b, 0x6c, 0xaa, 0x62, 0x86, 0x6e, 0x1c, 0x15, 0xf3, 0x6c, 0xb3, 0xff, 0x65, 0x1b, 0xa2, 0x9b, 0x59}} ,
+ {{0xe2, 0xa9, 0x65, 0x88, 0xc4, 0x50, 0xfa, 0xbb, 0x3b, 0x6e, 0x5f, 0x44, 0x01, 0xca, 0x97, 0xd4, 0xdd, 0xf6, 0xcd, 0x3f, 0x3f, 0xe5, 0x97, 0x67, 0x2b, 0x8c, 0x66, 0x0f, 0x35, 0x9b, 0xf5, 0x07}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0xf1, 0x59, 0x27, 0xd8, 0xdb, 0x5a, 0x11, 0x5e, 0x82, 0xf3, 0x38, 0xff, 0x1c, 0xed, 0xfe, 0x3f, 0x64, 0x54, 0x3f, 0x7f, 0xd1, 0x81, 0xed, 0xef, 0x65, 0xc5, 0xcb, 0xfd, 0xe1, 0x80, 0xcd, 0x11}} ,
+ {{0xe0, 0xdb, 0x22, 0x28, 0xe6, 0xff, 0x61, 0x9d, 0x41, 0x14, 0x2d, 0x3b, 0x26, 0x22, 0xdf, 0xf1, 0x34, 0x81, 0xe9, 0x45, 0xee, 0x0f, 0x98, 0x8b, 0xa6, 0x3f, 0xef, 0xf7, 0x43, 0x19, 0xf1, 0x43}}},
+{{{0xee, 0xf3, 0x00, 0xa1, 0x50, 0xde, 0xc0, 0xb6, 0x01, 0xe3, 0x8c, 0x3c, 0x4d, 0x31, 0xd2, 0xb0, 0x58, 0xcd, 0xed, 0x10, 0x4a, 0x7a, 0xef, 0x80, 0xa9, 0x19, 0x32, 0xf3, 0xd8, 0x33, 0x8c, 0x06}} ,
+ {{0xcb, 0x7d, 0x4f, 0xff, 0x30, 0xd8, 0x12, 0x3b, 0x39, 0x1c, 0x06, 0xf9, 0x4c, 0x34, 0x35, 0x71, 0xb5, 0x16, 0x94, 0x67, 0xdf, 0xee, 0x11, 0xde, 0xa4, 0x1d, 0x88, 0x93, 0x35, 0xa9, 0x32, 0x10}}},
+{{{0xe9, 0xc3, 0xbc, 0x7b, 0x5c, 0xfc, 0xb2, 0xf9, 0xc9, 0x2f, 0xe5, 0xba, 0x3a, 0x0b, 0xab, 0x64, 0x38, 0x6f, 0x5b, 0x4b, 0x93, 0xda, 0x64, 0xec, 0x4d, 0x3d, 0xa0, 0xf5, 0xbb, 0xba, 0x47, 0x48}} ,
+ {{0x60, 0xbc, 0x45, 0x1f, 0x23, 0xa2, 0x3b, 0x70, 0x76, 0xe6, 0x97, 0x99, 0x4f, 0x77, 0x54, 0x67, 0x30, 0x9a, 0xe7, 0x66, 0xd6, 0xcd, 0x2e, 0x51, 0x24, 0x2c, 0x42, 0x4a, 0x11, 0xfe, 0x6f, 0x7e}}},
+{{{0x87, 0xc0, 0xb1, 0xf0, 0xa3, 0x6f, 0x0c, 0x93, 0xa9, 0x0a, 0x72, 0xef, 0x5c, 0xbe, 0x65, 0x35, 0xa7, 0x6a, 0x4e, 0x2c, 0xbf, 0x21, 0x23, 0xe8, 0x2f, 0x97, 0xc7, 0x3e, 0xc8, 0x17, 0xac, 0x1e}} ,
+ {{0x7b, 0xef, 0x21, 0xe5, 0x40, 0xcc, 0x1e, 0xdc, 0xd6, 0xbd, 0x97, 0x7a, 0x7c, 0x75, 0x86, 0x7a, 0x25, 0x5a, 0x6e, 0x7c, 0xe5, 0x51, 0x3c, 0x1b, 0x5b, 0x82, 0x9a, 0x07, 0x60, 0xa1, 0x19, 0x04}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x96, 0x88, 0xa6, 0xab, 0x8f, 0xe3, 0x3a, 0x49, 0xf8, 0xfe, 0x34, 0xe7, 0x6a, 0xb2, 0xfe, 0x40, 0x26, 0x74, 0x57, 0x4c, 0xf6, 0xd4, 0x99, 0xce, 0x5d, 0x7b, 0x2f, 0x67, 0xd6, 0x5a, 0xe4, 0x4e}} ,
+ {{0x5c, 0x82, 0xb3, 0xbd, 0x55, 0x25, 0xf6, 0x6a, 0x93, 0xa4, 0x02, 0xc6, 0x7d, 0x5c, 0xb1, 0x2b, 0x5b, 0xff, 0xfb, 0x56, 0xf8, 0x01, 0x41, 0x90, 0xc6, 0xb6, 0xac, 0x4f, 0xfe, 0xa7, 0x41, 0x70}}},
+{{{0xdb, 0xfa, 0x9b, 0x2c, 0xd4, 0x23, 0x67, 0x2c, 0x8a, 0x63, 0x6c, 0x07, 0x26, 0x48, 0x4f, 0xc2, 0x03, 0xd2, 0x53, 0x20, 0x28, 0xed, 0x65, 0x71, 0x47, 0xa9, 0x16, 0x16, 0x12, 0xbc, 0x28, 0x33}} ,
+ {{0x39, 0xc0, 0xfa, 0xfa, 0xcd, 0x33, 0x43, 0xc7, 0x97, 0x76, 0x9b, 0x93, 0x91, 0x72, 0xeb, 0xc5, 0x18, 0x67, 0x4c, 0x11, 0xf0, 0xf4, 0xe5, 0x73, 0xb2, 0x5c, 0x1b, 0xc2, 0x26, 0x3f, 0xbf, 0x2b}}},
+{{{0x86, 0xe6, 0x8c, 0x1d, 0xdf, 0xca, 0xfc, 0xd5, 0xf8, 0x3a, 0xc3, 0x44, 0x72, 0xe6, 0x78, 0x9d, 0x2b, 0x97, 0xf8, 0x28, 0x45, 0xb4, 0x20, 0xc9, 0x2a, 0x8c, 0x67, 0xaa, 0x11, 0xc5, 0x5b, 0x2f}} ,
+ {{0x17, 0x0f, 0x86, 0x52, 0xd7, 0x9d, 0xc3, 0x44, 0x51, 0x76, 0x32, 0x65, 0xb4, 0x37, 0x81, 0x99, 0x46, 0x37, 0x62, 0xed, 0xcf, 0x64, 0x9d, 0x72, 0x40, 0x7a, 0x4c, 0x0b, 0x76, 0x2a, 0xfb, 0x56}}},
+{{{0x33, 0xa7, 0x90, 0x7c, 0xc3, 0x6f, 0x17, 0xa5, 0xa0, 0x67, 0x72, 0x17, 0xea, 0x7e, 0x63, 0x14, 0x83, 0xde, 0xc1, 0x71, 0x2d, 0x41, 0x32, 0x7a, 0xf3, 0xd1, 0x2b, 0xd8, 0x2a, 0xa6, 0x46, 0x36}} ,
+ {{0xac, 0xcc, 0x6b, 0x7c, 0xf9, 0xb8, 0x8b, 0x08, 0x5c, 0xd0, 0x7d, 0x8f, 0x73, 0xea, 0x20, 0xda, 0x86, 0xca, 0x00, 0xc7, 0xad, 0x73, 0x4d, 0xe9, 0xe8, 0xa9, 0xda, 0x1f, 0x03, 0x06, 0xdd, 0x24}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x9c, 0xb2, 0x61, 0x0a, 0x98, 0x2a, 0xa5, 0xd7, 0xee, 0xa9, 0xac, 0x65, 0xcb, 0x0a, 0x1e, 0xe2, 0xbe, 0xdc, 0x85, 0x59, 0x0f, 0x9c, 0xa6, 0x57, 0x34, 0xa5, 0x87, 0xeb, 0x7b, 0x1e, 0x0c, 0x3c}} ,
+ {{0x2f, 0xbd, 0x84, 0x63, 0x0d, 0xb5, 0xa0, 0xf0, 0x4b, 0x9e, 0x93, 0xc6, 0x34, 0x9a, 0x34, 0xff, 0x73, 0x19, 0x2f, 0x6e, 0x54, 0x45, 0x2c, 0x92, 0x31, 0x76, 0x34, 0xf1, 0xb2, 0x26, 0xe8, 0x74}}},
+{{{0x0a, 0x67, 0x90, 0x6d, 0x0c, 0x4c, 0xcc, 0xc0, 0xe6, 0xbd, 0xa7, 0x5e, 0x55, 0x8c, 0xcd, 0x58, 0x9b, 0x11, 0xa2, 0xbb, 0x4b, 0xb1, 0x43, 0x04, 0x3c, 0x55, 0xed, 0x23, 0xfe, 0xcd, 0xb1, 0x53}} ,
+ {{0x05, 0xfb, 0x75, 0xf5, 0x01, 0xaf, 0x38, 0x72, 0x58, 0xfc, 0x04, 0x29, 0x34, 0x7a, 0x67, 0xa2, 0x08, 0x50, 0x6e, 0xd0, 0x2b, 0x73, 0xd5, 0xb8, 0xe4, 0x30, 0x96, 0xad, 0x45, 0xdf, 0xa6, 0x5c}}},
+{{{0x0d, 0x88, 0x1a, 0x90, 0x7e, 0xdc, 0xd8, 0xfe, 0xc1, 0x2f, 0x5d, 0x67, 0xee, 0x67, 0x2f, 0xed, 0x6f, 0x55, 0x43, 0x5f, 0x87, 0x14, 0x35, 0x42, 0xd3, 0x75, 0xae, 0xd5, 0xd3, 0x85, 0x1a, 0x76}} ,
+ {{0x87, 0xc8, 0xa0, 0x6e, 0xe1, 0xb0, 0xad, 0x6a, 0x4a, 0x34, 0x71, 0xed, 0x7c, 0xd6, 0x44, 0x03, 0x65, 0x4a, 0x5c, 0x5c, 0x04, 0xf5, 0x24, 0x3f, 0xb0, 0x16, 0x5e, 0x8c, 0xb2, 0xd2, 0xc5, 0x20}}},
+{{{0x98, 0x83, 0xc2, 0x37, 0xa0, 0x41, 0xa8, 0x48, 0x5c, 0x5f, 0xbf, 0xc8, 0xfa, 0x24, 0xe0, 0x59, 0x2c, 0xbd, 0xf6, 0x81, 0x7e, 0x88, 0xe6, 0xca, 0x04, 0xd8, 0x5d, 0x60, 0xbb, 0x74, 0xa7, 0x0b}} ,
+ {{0x21, 0x13, 0x91, 0xbf, 0x77, 0x7a, 0x33, 0xbc, 0xe9, 0x07, 0x39, 0x0a, 0xdd, 0x7d, 0x06, 0x10, 0x9a, 0xee, 0x47, 0x73, 0x1b, 0x15, 0x5a, 0xfb, 0xcd, 0x4d, 0xd0, 0xd2, 0x3a, 0x01, 0xba, 0x54}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x48, 0xd5, 0x39, 0x4a, 0x0b, 0x20, 0x6a, 0x43, 0xa0, 0x07, 0x82, 0x5e, 0x49, 0x7c, 0xc9, 0x47, 0xf1, 0x7c, 0x37, 0xb9, 0x23, 0xef, 0x6b, 0x46, 0x45, 0x8c, 0x45, 0x76, 0xdf, 0x14, 0x6b, 0x6e}} ,
+ {{0x42, 0xc9, 0xca, 0x29, 0x4c, 0x76, 0x37, 0xda, 0x8a, 0x2d, 0x7c, 0x3a, 0x58, 0xf2, 0x03, 0xb4, 0xb5, 0xb9, 0x1a, 0x13, 0x2d, 0xde, 0x5f, 0x6b, 0x9d, 0xba, 0x52, 0xc9, 0x5d, 0xb3, 0xf3, 0x30}}},
+{{{0x4c, 0x6f, 0xfe, 0x6b, 0x0c, 0x62, 0xd7, 0x48, 0x71, 0xef, 0xb1, 0x85, 0x79, 0xc0, 0xed, 0x24, 0xb1, 0x08, 0x93, 0x76, 0x8e, 0xf7, 0x38, 0x8e, 0xeb, 0xfe, 0x80, 0x40, 0xaf, 0x90, 0x64, 0x49}} ,
+ {{0x4a, 0x88, 0xda, 0xc1, 0x98, 0x44, 0x3c, 0x53, 0x4e, 0xdb, 0x4b, 0xb9, 0x12, 0x5f, 0xcd, 0x08, 0x04, 0xef, 0x75, 0xe7, 0xb1, 0x3a, 0xe5, 0x07, 0xfa, 0xca, 0x65, 0x7b, 0x72, 0x10, 0x64, 0x7f}}},
+{{{0x3d, 0x81, 0xf0, 0xeb, 0x16, 0xfd, 0x58, 0x33, 0x8d, 0x7c, 0x1a, 0xfb, 0x20, 0x2c, 0x8a, 0xee, 0x90, 0xbb, 0x33, 0x6d, 0x45, 0xe9, 0x8e, 0x99, 0x85, 0xe1, 0x08, 0x1f, 0xc5, 0xf1, 0xb5, 0x46}} ,
+ {{0xe4, 0xe7, 0x43, 0x4b, 0xa0, 0x3f, 0x2b, 0x06, 0xba, 0x17, 0xae, 0x3d, 0xe6, 0xce, 0xbd, 0xb8, 0xed, 0x74, 0x11, 0x35, 0xec, 0x96, 0xfe, 0x31, 0xe3, 0x0e, 0x7a, 0x4e, 0xc9, 0x1d, 0xcb, 0x20}}},
+{{{0xe0, 0x67, 0xe9, 0x7b, 0xdb, 0x96, 0x5c, 0xb0, 0x32, 0xd0, 0x59, 0x31, 0x90, 0xdc, 0x92, 0x97, 0xac, 0x09, 0x38, 0x31, 0x0f, 0x7e, 0xd6, 0x5d, 0xd0, 0x06, 0xb6, 0x1f, 0xea, 0xf0, 0x5b, 0x07}} ,
+ {{0x81, 0x9f, 0xc7, 0xde, 0x6b, 0x41, 0x22, 0x35, 0x14, 0x67, 0x77, 0x3e, 0x90, 0x81, 0xb0, 0xd9, 0x85, 0x4c, 0xca, 0x9b, 0x3f, 0x04, 0x59, 0xd6, 0xaa, 0x17, 0xc3, 0x88, 0x34, 0x37, 0xba, 0x43}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x4c, 0xb6, 0x69, 0xc8, 0x81, 0x95, 0x94, 0x33, 0x92, 0x34, 0xe9, 0x3c, 0x84, 0x0d, 0x3d, 0x5a, 0x37, 0x9c, 0x22, 0xa0, 0xaa, 0x65, 0xce, 0xb4, 0xc2, 0x2d, 0x66, 0x67, 0x02, 0xff, 0x74, 0x10}} ,
+ {{0x22, 0xb0, 0xd5, 0xe6, 0xc7, 0xef, 0xb1, 0xa7, 0x13, 0xda, 0x60, 0xb4, 0x80, 0xc1, 0x42, 0x7d, 0x10, 0x70, 0x97, 0x04, 0x4d, 0xda, 0x23, 0x89, 0xc2, 0x0e, 0x68, 0xcb, 0xde, 0xe0, 0x9b, 0x29}}},
+{{{0x33, 0xfe, 0x42, 0x2a, 0x36, 0x2b, 0x2e, 0x36, 0x64, 0x5c, 0x8b, 0xcc, 0x81, 0x6a, 0x15, 0x08, 0xa1, 0x27, 0xe8, 0x57, 0xe5, 0x78, 0x8e, 0xf2, 0x58, 0x19, 0x12, 0x42, 0xae, 0xc4, 0x63, 0x3e}} ,
+ {{0x78, 0x96, 0x9c, 0xa7, 0xca, 0x80, 0xae, 0x02, 0x85, 0xb1, 0x7c, 0x04, 0x5c, 0xc1, 0x5b, 0x26, 0xc1, 0xba, 0xed, 0xa5, 0x59, 0x70, 0x85, 0x8c, 0x8c, 0xe8, 0x87, 0xac, 0x6a, 0x28, 0x99, 0x35}}},
+{{{0x9f, 0x04, 0x08, 0x28, 0xbe, 0x87, 0xda, 0x80, 0x28, 0x38, 0xde, 0x9f, 0xcd, 0xe4, 0xe3, 0x62, 0xfb, 0x2e, 0x46, 0x8d, 0x01, 0xb3, 0x06, 0x51, 0xd4, 0x19, 0x3b, 0x11, 0xfa, 0xe2, 0xad, 0x1e}} ,
+ {{0xa0, 0x20, 0x99, 0x69, 0x0a, 0xae, 0xa3, 0x70, 0x4e, 0x64, 0x80, 0xb7, 0x85, 0x9c, 0x87, 0x54, 0x43, 0x43, 0x55, 0x80, 0x6d, 0x8d, 0x7c, 0xa9, 0x64, 0xca, 0x6c, 0x2e, 0x21, 0xd8, 0xc8, 0x6c}}},
+{{{0x91, 0x4a, 0x07, 0xad, 0x08, 0x75, 0xc1, 0x4f, 0xa4, 0xb2, 0xc3, 0x6f, 0x46, 0x3e, 0xb1, 0xce, 0x52, 0xab, 0x67, 0x09, 0x54, 0x48, 0x6b, 0x6c, 0xd7, 0x1d, 0x71, 0x76, 0xcb, 0xff, 0xdd, 0x31}} ,
+ {{0x36, 0x88, 0xfa, 0xfd, 0xf0, 0x36, 0x6f, 0x07, 0x74, 0x88, 0x50, 0xd0, 0x95, 0x38, 0x4a, 0x48, 0x2e, 0x07, 0x64, 0x97, 0x11, 0x76, 0x01, 0x1a, 0x27, 0x4d, 0x8e, 0x25, 0x9a, 0x9b, 0x1c, 0x22}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0xbe, 0x57, 0xbd, 0x0e, 0x0f, 0xac, 0x5e, 0x76, 0xa3, 0x71, 0xad, 0x2b, 0x10, 0x45, 0x02, 0xec, 0x59, 0xd5, 0x5d, 0xa9, 0x44, 0xcc, 0x25, 0x4c, 0xb3, 0x3c, 0x5b, 0x69, 0x07, 0x55, 0x26, 0x6b}} ,
+ {{0x30, 0x6b, 0xd4, 0xa7, 0x51, 0x29, 0xe3, 0xf9, 0x7a, 0x75, 0x2a, 0x82, 0x2f, 0xd6, 0x1d, 0x99, 0x2b, 0x80, 0xd5, 0x67, 0x1e, 0x15, 0x9d, 0xca, 0xfd, 0xeb, 0xac, 0x97, 0x35, 0x09, 0x7f, 0x3f}}},
+{{{0x35, 0x0d, 0x34, 0x0a, 0xb8, 0x67, 0x56, 0x29, 0x20, 0xf3, 0x19, 0x5f, 0xe2, 0x83, 0x42, 0x73, 0x53, 0xa8, 0xc5, 0x02, 0x19, 0x33, 0xb4, 0x64, 0xbd, 0xc3, 0x87, 0x8c, 0xd7, 0x76, 0xed, 0x25}} ,
+ {{0x47, 0x39, 0x37, 0x76, 0x0d, 0x1d, 0x0c, 0xf5, 0x5a, 0x6d, 0x43, 0x88, 0x99, 0x15, 0xb4, 0x52, 0x0f, 0x2a, 0xb3, 0xb0, 0x3f, 0xa6, 0xb3, 0x26, 0xb3, 0xc7, 0x45, 0xf5, 0x92, 0x5f, 0x9b, 0x17}}},
+{{{0x9d, 0x23, 0xbd, 0x15, 0xfe, 0x52, 0x52, 0x15, 0x26, 0x79, 0x86, 0xba, 0x06, 0x56, 0x66, 0xbb, 0x8c, 0x2e, 0x10, 0x11, 0xd5, 0x4a, 0x18, 0x52, 0xda, 0x84, 0x44, 0xf0, 0x3e, 0xe9, 0x8c, 0x35}} ,
+ {{0xad, 0xa0, 0x41, 0xec, 0xc8, 0x4d, 0xb9, 0xd2, 0x6e, 0x96, 0x4e, 0x5b, 0xc5, 0xc2, 0xa0, 0x1b, 0xcf, 0x0c, 0xbf, 0x17, 0x66, 0x57, 0xc1, 0x17, 0x90, 0x45, 0x71, 0xc2, 0xe1, 0x24, 0xeb, 0x27}}},
+{{{0x2c, 0xb9, 0x42, 0xa4, 0xaf, 0x3b, 0x42, 0x0e, 0xc2, 0x0f, 0xf2, 0xea, 0x83, 0xaf, 0x9a, 0x13, 0x17, 0xb0, 0xbd, 0x89, 0x17, 0xe3, 0x72, 0xcb, 0x0e, 0x76, 0x7e, 0x41, 0x63, 0x04, 0x88, 0x71}} ,
+ {{0x75, 0x78, 0x38, 0x86, 0x57, 0xdd, 0x9f, 0xee, 0x54, 0x70, 0x65, 0xbf, 0xf1, 0x2c, 0xe0, 0x39, 0x0d, 0xe3, 0x89, 0xfd, 0x8e, 0x93, 0x4f, 0x43, 0xdc, 0xd5, 0x5b, 0xde, 0xf9, 0x98, 0xe5, 0x7b}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0xe7, 0x3b, 0x65, 0x11, 0xdf, 0xb2, 0xf2, 0x63, 0x94, 0x12, 0x6f, 0x5c, 0x9e, 0x77, 0xc1, 0xb6, 0xd8, 0xab, 0x58, 0x7a, 0x1d, 0x95, 0x73, 0xdd, 0xe7, 0xe3, 0x6f, 0xf2, 0x03, 0x1d, 0xdb, 0x76}} ,
+ {{0xae, 0x06, 0x4e, 0x2c, 0x52, 0x1b, 0xbc, 0x5a, 0x5a, 0xa5, 0xbe, 0x27, 0xbd, 0xeb, 0xe1, 0x14, 0x17, 0x68, 0x26, 0x07, 0x03, 0xd1, 0x18, 0x0b, 0xdf, 0xf1, 0x06, 0x5c, 0xa6, 0x1b, 0xb9, 0x24}}},
+{{{0xc5, 0x66, 0x80, 0x13, 0x0e, 0x48, 0x8c, 0x87, 0x31, 0x84, 0xb4, 0x60, 0xed, 0xc5, 0xec, 0xb6, 0xc5, 0x05, 0x33, 0x5f, 0x2f, 0x7d, 0x40, 0xb6, 0x32, 0x1d, 0x38, 0x74, 0x1b, 0xf1, 0x09, 0x3d}} ,
+ {{0xd4, 0x69, 0x82, 0xbc, 0x8d, 0xf8, 0x34, 0x36, 0x75, 0x55, 0x18, 0x55, 0x58, 0x3c, 0x79, 0xaf, 0x26, 0x80, 0xab, 0x9b, 0x95, 0x00, 0xf1, 0xcb, 0xda, 0xc1, 0x9f, 0xf6, 0x2f, 0xa2, 0xf4, 0x45}}},
+{{{0x17, 0xbe, 0xeb, 0x85, 0xed, 0x9e, 0xcd, 0x56, 0xf5, 0x17, 0x45, 0x42, 0xb4, 0x1f, 0x44, 0x4c, 0x05, 0x74, 0x15, 0x47, 0x00, 0xc6, 0x6a, 0x3d, 0x24, 0x09, 0x0d, 0x58, 0xb1, 0x42, 0xd7, 0x04}} ,
+ {{0x8d, 0xbd, 0xa3, 0xc4, 0x06, 0x9b, 0x1f, 0x90, 0x58, 0x60, 0x74, 0xb2, 0x00, 0x3b, 0x3c, 0xd2, 0xda, 0x82, 0xbb, 0x10, 0x90, 0x69, 0x92, 0xa9, 0xb4, 0x30, 0x81, 0xe3, 0x7c, 0xa8, 0x89, 0x45}}},
+{{{0x3f, 0xdc, 0x05, 0xcb, 0x41, 0x3c, 0xc8, 0x23, 0x04, 0x2c, 0x38, 0x99, 0xe3, 0x68, 0x55, 0xf9, 0xd3, 0x32, 0xc7, 0xbf, 0xfa, 0xd4, 0x1b, 0x5d, 0xde, 0xdc, 0x10, 0x42, 0xc0, 0x42, 0xd9, 0x75}} ,
+ {{0x2d, 0xab, 0x35, 0x4e, 0x87, 0xc4, 0x65, 0x97, 0x67, 0x24, 0xa4, 0x47, 0xad, 0x3f, 0x8e, 0xf3, 0xcb, 0x31, 0x17, 0x77, 0xc5, 0xe2, 0xd7, 0x8f, 0x3c, 0xc1, 0xcd, 0x56, 0x48, 0xc1, 0x6c, 0x69}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x14, 0xae, 0x5f, 0x88, 0x7b, 0xa5, 0x90, 0xdf, 0x10, 0xb2, 0x8b, 0x5e, 0x24, 0x17, 0xc3, 0xa3, 0xd4, 0x0f, 0x92, 0x61, 0x1a, 0x19, 0x5a, 0xad, 0x76, 0xbd, 0xd8, 0x1c, 0xdd, 0xe0, 0x12, 0x6d}} ,
+ {{0x8e, 0xbd, 0x70, 0x8f, 0x02, 0xa3, 0x24, 0x4d, 0x5a, 0x67, 0xc4, 0xda, 0xf7, 0x20, 0x0f, 0x81, 0x5b, 0x7a, 0x05, 0x24, 0x67, 0x83, 0x0b, 0x2a, 0x80, 0xe7, 0xfd, 0x74, 0x4b, 0x9e, 0x5c, 0x0d}}},
+{{{0x94, 0xd5, 0x5f, 0x1f, 0xa2, 0xfb, 0xeb, 0xe1, 0x07, 0x34, 0xf8, 0x20, 0xad, 0x81, 0x30, 0x06, 0x2d, 0xa1, 0x81, 0x95, 0x36, 0xcf, 0x11, 0x0b, 0xaf, 0xc1, 0x2b, 0x9a, 0x6c, 0x55, 0xc1, 0x16}} ,
+ {{0x36, 0x4f, 0xf1, 0x5e, 0x74, 0x35, 0x13, 0x28, 0xd7, 0x11, 0xcf, 0xb8, 0xde, 0x93, 0xb3, 0x05, 0xb8, 0xb5, 0x73, 0xe9, 0xeb, 0xad, 0x19, 0x1e, 0x89, 0x0f, 0x8b, 0x15, 0xd5, 0x8c, 0xe3, 0x23}}},
+{{{0x33, 0x79, 0xe7, 0x18, 0xe6, 0x0f, 0x57, 0x93, 0x15, 0xa0, 0xa7, 0xaa, 0xc4, 0xbf, 0x4f, 0x30, 0x74, 0x95, 0x5e, 0x69, 0x4a, 0x5b, 0x45, 0xe4, 0x00, 0xeb, 0x23, 0x74, 0x4c, 0xdf, 0x6b, 0x45}} ,
+ {{0x97, 0x29, 0x6c, 0xc4, 0x42, 0x0b, 0xdd, 0xc0, 0x29, 0x5c, 0x9b, 0x34, 0x97, 0xd0, 0xc7, 0x79, 0x80, 0x63, 0x74, 0xe4, 0x8e, 0x37, 0xb0, 0x2b, 0x7c, 0xe8, 0x68, 0x6c, 0xc3, 0x82, 0x97, 0x57}}},
+{{{0x22, 0xbe, 0x83, 0xb6, 0x4b, 0x80, 0x6b, 0x43, 0x24, 0x5e, 0xef, 0x99, 0x9b, 0xa8, 0xfc, 0x25, 0x8d, 0x3b, 0x03, 0x94, 0x2b, 0x3e, 0xe7, 0x95, 0x76, 0x9b, 0xcc, 0x15, 0xdb, 0x32, 0xe6, 0x66}} ,
+ {{0x84, 0xf0, 0x4a, 0x13, 0xa6, 0xd6, 0xfa, 0x93, 0x46, 0x07, 0xf6, 0x7e, 0x5c, 0x6d, 0x5e, 0xf6, 0xa6, 0xe7, 0x48, 0xf0, 0x06, 0xea, 0xff, 0x90, 0xc1, 0xcc, 0x4c, 0x19, 0x9c, 0x3c, 0x4e, 0x53}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x2a, 0x50, 0xe3, 0x07, 0x15, 0x59, 0xf2, 0x8b, 0x81, 0xf2, 0xf3, 0xd3, 0x6c, 0x99, 0x8c, 0x70, 0x67, 0xec, 0xcc, 0xee, 0x9e, 0x59, 0x45, 0x59, 0x7d, 0x47, 0x75, 0x69, 0xf5, 0x24, 0x93, 0x5d}} ,
+ {{0x6a, 0x4f, 0x1b, 0xbe, 0x6b, 0x30, 0xcf, 0x75, 0x46, 0xe3, 0x7b, 0x9d, 0xfc, 0xcd, 0xd8, 0x5c, 0x1f, 0xb4, 0xc8, 0xe2, 0x24, 0xec, 0x1a, 0x28, 0x05, 0x32, 0x57, 0xfd, 0x3c, 0x5a, 0x98, 0x10}}},
+{{{0xa3, 0xdb, 0xf7, 0x30, 0xd8, 0xc2, 0x9a, 0xe1, 0xd3, 0xce, 0x22, 0xe5, 0x80, 0x1e, 0xd9, 0xe4, 0x1f, 0xab, 0xc0, 0x71, 0x1a, 0x86, 0x0e, 0x27, 0x99, 0x5b, 0xfa, 0x76, 0x99, 0xb0, 0x08, 0x3c}} ,
+ {{0x2a, 0x93, 0xd2, 0x85, 0x1b, 0x6a, 0x5d, 0xa6, 0xee, 0xd1, 0xd1, 0x33, 0xbd, 0x6a, 0x36, 0x73, 0x37, 0x3a, 0x44, 0xb4, 0xec, 0xa9, 0x7a, 0xde, 0x83, 0x40, 0xd7, 0xdf, 0x28, 0xba, 0xa2, 0x30}}},
+{{{0xd3, 0xb5, 0x6d, 0x05, 0x3f, 0x9f, 0xf3, 0x15, 0x8d, 0x7c, 0xca, 0xc9, 0xfc, 0x8a, 0x7c, 0x94, 0xb0, 0x63, 0x36, 0x9b, 0x78, 0xd1, 0x91, 0x1f, 0x93, 0xd8, 0x57, 0x43, 0xde, 0x76, 0xa3, 0x43}} ,
+ {{0x9b, 0x35, 0xe2, 0xa9, 0x3d, 0x32, 0x1e, 0xbb, 0x16, 0x28, 0x70, 0xe9, 0x45, 0x2f, 0x8f, 0x70, 0x7f, 0x08, 0x7e, 0x53, 0xc4, 0x7a, 0xbf, 0xf7, 0xe1, 0xa4, 0x6a, 0xd8, 0xac, 0x64, 0x1b, 0x11}}},
+{{{0xb2, 0xeb, 0x47, 0x46, 0x18, 0x3e, 0x1f, 0x99, 0x0c, 0xcc, 0xf1, 0x2c, 0xe0, 0xe7, 0x8f, 0xe0, 0x01, 0x7e, 0x65, 0xb8, 0x0c, 0xd0, 0xfb, 0xc8, 0xb9, 0x90, 0x98, 0x33, 0x61, 0x3b, 0xd8, 0x27}} ,
+ {{0xa0, 0xbe, 0x72, 0x3a, 0x50, 0x4b, 0x74, 0xab, 0x01, 0xc8, 0x93, 0xc5, 0xe4, 0xc7, 0x08, 0x6c, 0xb4, 0xca, 0xee, 0xeb, 0x8e, 0xd7, 0x4e, 0x26, 0xc6, 0x1d, 0xe2, 0x71, 0xaf, 0x89, 0xa0, 0x2a}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x98, 0x0b, 0xe4, 0xde, 0xdb, 0xa8, 0xfa, 0x82, 0x74, 0x06, 0x52, 0x6d, 0x08, 0x52, 0x8a, 0xff, 0x62, 0xc5, 0x6a, 0x44, 0x0f, 0x51, 0x8c, 0x1f, 0x6e, 0xb6, 0xc6, 0x2c, 0x81, 0xd3, 0x76, 0x46}} ,
+ {{0xf4, 0x29, 0x74, 0x2e, 0x80, 0xa7, 0x1a, 0x8f, 0xf6, 0xbd, 0xd6, 0x8e, 0xbf, 0xc1, 0x95, 0x2a, 0xeb, 0xa0, 0x7f, 0x45, 0xa0, 0x50, 0x14, 0x05, 0xb1, 0x57, 0x4c, 0x74, 0xb7, 0xe2, 0x89, 0x7d}}},
+{{{0x07, 0xee, 0xa7, 0xad, 0xb7, 0x09, 0x0b, 0x49, 0x4e, 0xbf, 0xca, 0xe5, 0x21, 0xe6, 0xe6, 0xaf, 0xd5, 0x67, 0xf3, 0xce, 0x7e, 0x7c, 0x93, 0x7b, 0x5a, 0x10, 0x12, 0x0e, 0x6c, 0x06, 0x11, 0x75}} ,
+ {{0xd5, 0xfc, 0x86, 0xa3, 0x3b, 0xa3, 0x3e, 0x0a, 0xfb, 0x0b, 0xf7, 0x36, 0xb1, 0x5b, 0xda, 0x70, 0xb7, 0x00, 0xa7, 0xda, 0x88, 0x8f, 0x84, 0xa8, 0xbc, 0x1c, 0x39, 0xb8, 0x65, 0xf3, 0x4d, 0x60}}},
+{{{0x96, 0x9d, 0x31, 0xf4, 0xa2, 0xbe, 0x81, 0xb9, 0xa5, 0x59, 0x9e, 0xba, 0x07, 0xbe, 0x74, 0x58, 0xd8, 0xeb, 0xc5, 0x9f, 0x3d, 0xd1, 0xf4, 0xae, 0xce, 0x53, 0xdf, 0x4f, 0xc7, 0x2a, 0x89, 0x4d}} ,
+ {{0x29, 0xd8, 0xf2, 0xaa, 0xe9, 0x0e, 0xf7, 0x2e, 0x5f, 0x9d, 0x8a, 0x5b, 0x09, 0xed, 0xc9, 0x24, 0x22, 0xf4, 0x0f, 0x25, 0x8f, 0x1c, 0x84, 0x6e, 0x34, 0x14, 0x6c, 0xea, 0xb3, 0x86, 0x5d, 0x04}}},
+{{{0x07, 0x98, 0x61, 0xe8, 0x6a, 0xd2, 0x81, 0x49, 0x25, 0xd5, 0x5b, 0x18, 0xc7, 0x35, 0x52, 0x51, 0xa4, 0x46, 0xad, 0x18, 0x0d, 0xc9, 0x5f, 0x18, 0x91, 0x3b, 0xb4, 0xc0, 0x60, 0x59, 0x8d, 0x66}} ,
+ {{0x03, 0x1b, 0x79, 0x53, 0x6e, 0x24, 0xae, 0x57, 0xd9, 0x58, 0x09, 0x85, 0x48, 0xa2, 0xd3, 0xb5, 0xe2, 0x4d, 0x11, 0x82, 0xe6, 0x86, 0x3c, 0xe9, 0xb1, 0x00, 0x19, 0xc2, 0x57, 0xf7, 0x66, 0x7a}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x0f, 0xe3, 0x89, 0x03, 0xd7, 0x22, 0x95, 0x9f, 0xca, 0xb4, 0x8d, 0x9e, 0x6d, 0x97, 0xff, 0x8d, 0x21, 0x59, 0x07, 0xef, 0x03, 0x2d, 0x5e, 0xf8, 0x44, 0x46, 0xe7, 0x85, 0x80, 0xc5, 0x89, 0x50}} ,
+ {{0x8b, 0xd8, 0x53, 0x86, 0x24, 0x86, 0x29, 0x52, 0x01, 0xfa, 0x20, 0xc3, 0x4e, 0x95, 0xcb, 0xad, 0x7b, 0x34, 0x94, 0x30, 0xb7, 0x7a, 0xfa, 0x96, 0x41, 0x60, 0x2b, 0xcb, 0x59, 0xb9, 0xca, 0x50}}},
+{{{0xc2, 0x5b, 0x9b, 0x78, 0x23, 0x1b, 0x3a, 0x88, 0x94, 0x5f, 0x0a, 0x9b, 0x98, 0x2b, 0x6e, 0x53, 0x11, 0xf6, 0xff, 0xc6, 0x7d, 0x42, 0xcc, 0x02, 0x80, 0x40, 0x0d, 0x1e, 0xfb, 0xaf, 0x61, 0x07}} ,
+ {{0xb0, 0xe6, 0x2f, 0x81, 0x70, 0xa1, 0x2e, 0x39, 0x04, 0x7c, 0xc4, 0x2c, 0x87, 0x45, 0x4a, 0x5b, 0x69, 0x97, 0xac, 0x6d, 0x2c, 0x10, 0x42, 0x7c, 0x3b, 0x15, 0x70, 0x60, 0x0e, 0x11, 0x6d, 0x3a}}},
+{{{0x9b, 0x18, 0x80, 0x5e, 0xdb, 0x05, 0xbd, 0xc6, 0xb7, 0x3c, 0xc2, 0x40, 0x4d, 0x5d, 0xce, 0x97, 0x8a, 0x34, 0x15, 0xab, 0x28, 0x5d, 0x10, 0xf0, 0x37, 0x0c, 0xcc, 0x16, 0xfa, 0x1f, 0x33, 0x0d}} ,
+ {{0x19, 0xf9, 0x35, 0xaa, 0x59, 0x1a, 0x0c, 0x5c, 0x06, 0xfc, 0x6a, 0x0b, 0x97, 0x53, 0x36, 0xfc, 0x2a, 0xa5, 0x5a, 0x9b, 0x30, 0xef, 0x23, 0xaf, 0x39, 0x5d, 0x9a, 0x6b, 0x75, 0x57, 0x48, 0x0b}}},
+{{{0x26, 0xdc, 0x76, 0x3b, 0xfc, 0xf9, 0x9c, 0x3f, 0x89, 0x0b, 0x62, 0x53, 0xaf, 0x83, 0x01, 0x2e, 0xbc, 0x6a, 0xc6, 0x03, 0x0d, 0x75, 0x2a, 0x0d, 0xe6, 0x94, 0x54, 0xcf, 0xb3, 0xe5, 0x96, 0x25}} ,
+ {{0xfe, 0x82, 0xb1, 0x74, 0x31, 0x8a, 0xa7, 0x6f, 0x56, 0xbd, 0x8d, 0xf4, 0xe0, 0x94, 0x51, 0x59, 0xde, 0x2c, 0x5a, 0xf4, 0x84, 0x6b, 0x4a, 0x88, 0x93, 0xc0, 0x0c, 0x9a, 0xac, 0xa7, 0xa0, 0x68}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x25, 0x0d, 0xd6, 0xc7, 0x23, 0x47, 0x10, 0xad, 0xc7, 0x08, 0x5c, 0x87, 0x87, 0x93, 0x98, 0x18, 0xb8, 0xd3, 0x9c, 0xac, 0x5a, 0x3d, 0xc5, 0x75, 0xf8, 0x49, 0x32, 0x14, 0xcc, 0x51, 0x96, 0x24}} ,
+ {{0x65, 0x9c, 0x5d, 0xf0, 0x37, 0x04, 0xf0, 0x34, 0x69, 0x2a, 0xf0, 0xa5, 0x64, 0xca, 0xde, 0x2b, 0x5b, 0x15, 0x10, 0xd2, 0xab, 0x06, 0xdd, 0xc4, 0xb0, 0xb6, 0x5b, 0xc1, 0x17, 0xdf, 0x8f, 0x02}}},
+{{{0xbd, 0x59, 0x3d, 0xbf, 0x5c, 0x31, 0x44, 0x2c, 0x32, 0x94, 0x04, 0x60, 0x84, 0x0f, 0xad, 0x00, 0xb6, 0x8f, 0xc9, 0x1d, 0xcc, 0x5c, 0xa2, 0x49, 0x0e, 0x50, 0x91, 0x08, 0x9a, 0x43, 0x55, 0x05}} ,
+ {{0x5d, 0x93, 0x55, 0xdf, 0x9b, 0x12, 0x19, 0xec, 0x93, 0x85, 0x42, 0x9e, 0x66, 0x0f, 0x9d, 0xaf, 0x99, 0xaf, 0x26, 0x89, 0xbc, 0x61, 0xfd, 0xff, 0xce, 0x4b, 0xf4, 0x33, 0x95, 0xc9, 0x35, 0x58}}},
+{{{0x12, 0x55, 0xf9, 0xda, 0xcb, 0x44, 0xa7, 0xdc, 0x57, 0xe2, 0xf9, 0x9a, 0xe6, 0x07, 0x23, 0x60, 0x54, 0xa7, 0x39, 0xa5, 0x9b, 0x84, 0x56, 0x6e, 0xaa, 0x8b, 0x8f, 0xb0, 0x2c, 0x87, 0xaf, 0x67}} ,
+ {{0x00, 0xa9, 0x4c, 0xb2, 0x12, 0xf8, 0x32, 0xa8, 0x7a, 0x00, 0x4b, 0x49, 0x32, 0xba, 0x1f, 0x5d, 0x44, 0x8e, 0x44, 0x7a, 0xdc, 0x11, 0xfb, 0x39, 0x08, 0x57, 0x87, 0xa5, 0x12, 0x42, 0x93, 0x0e}}},
+{{{0x17, 0xb4, 0xae, 0x72, 0x59, 0xd0, 0xaa, 0xa8, 0x16, 0x8b, 0x63, 0x11, 0xb3, 0x43, 0x04, 0xda, 0x0c, 0xa8, 0xb7, 0x68, 0xdd, 0x4e, 0x54, 0xe7, 0xaf, 0x5d, 0x5d, 0x05, 0x76, 0x36, 0xec, 0x0d}} ,
+ {{0x6d, 0x7c, 0x82, 0x32, 0x38, 0x55, 0x57, 0x74, 0x5b, 0x7d, 0xc3, 0xc4, 0xfb, 0x06, 0x29, 0xf0, 0x13, 0x55, 0x54, 0xc6, 0xa7, 0xdc, 0x4c, 0x9f, 0x98, 0x49, 0x20, 0xa8, 0xc3, 0x8d, 0xfa, 0x48}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x87, 0x47, 0x9d, 0xe9, 0x25, 0xd5, 0xe3, 0x47, 0x78, 0xdf, 0x85, 0xa7, 0x85, 0x5e, 0x7a, 0x4c, 0x5f, 0x79, 0x1a, 0xf3, 0xa2, 0xb2, 0x28, 0xa0, 0x9c, 0xdd, 0x30, 0x40, 0xd4, 0x38, 0xbd, 0x28}} ,
+ {{0xfc, 0xbb, 0xd5, 0x78, 0x6d, 0x1d, 0xd4, 0x99, 0xb4, 0xaa, 0x44, 0x44, 0x7a, 0x1b, 0xd8, 0xfe, 0xb4, 0x99, 0xb9, 0xcc, 0xe7, 0xc4, 0xd3, 0x3a, 0x73, 0x83, 0x41, 0x5c, 0x40, 0xd7, 0x2d, 0x55}}},
+{{{0x26, 0xe1, 0x7b, 0x5f, 0xe5, 0xdc, 0x3f, 0x7d, 0xa1, 0xa7, 0x26, 0x44, 0x22, 0x23, 0xc0, 0x8f, 0x7d, 0xf1, 0xb5, 0x11, 0x47, 0x7b, 0x19, 0xd4, 0x75, 0x6f, 0x1e, 0xa5, 0x27, 0xfe, 0xc8, 0x0e}} ,
+ {{0xd3, 0x11, 0x3d, 0xab, 0xef, 0x2c, 0xed, 0xb1, 0x3d, 0x7c, 0x32, 0x81, 0x6b, 0xfe, 0xf8, 0x1c, 0x3c, 0x7b, 0xc0, 0x61, 0xdf, 0xb8, 0x75, 0x76, 0x7f, 0xaa, 0xd8, 0x93, 0xaf, 0x3d, 0xe8, 0x3d}}},
+{{{0xfd, 0x5b, 0x4e, 0x8d, 0xb6, 0x7e, 0x82, 0x9b, 0xef, 0xce, 0x04, 0x69, 0x51, 0x52, 0xff, 0xef, 0xa0, 0x52, 0xb5, 0x79, 0x17, 0x5e, 0x2f, 0xde, 0xd6, 0x3c, 0x2d, 0xa0, 0x43, 0xb4, 0x0b, 0x19}} ,
+ {{0xc0, 0x61, 0x48, 0x48, 0x17, 0xf4, 0x9e, 0x18, 0x51, 0x2d, 0xea, 0x2f, 0xf2, 0xf2, 0xe0, 0xa3, 0x14, 0xb7, 0x8b, 0x3a, 0x30, 0xf5, 0x81, 0xc1, 0x5d, 0x71, 0x39, 0x62, 0x55, 0x1f, 0x60, 0x5a}}},
+{{{0xe5, 0x89, 0x8a, 0x76, 0x6c, 0xdb, 0x4d, 0x0a, 0x5b, 0x72, 0x9d, 0x59, 0x6e, 0x63, 0x63, 0x18, 0x7c, 0xe3, 0xfa, 0xe2, 0xdb, 0xa1, 0x8d, 0xf4, 0xa5, 0xd7, 0x16, 0xb2, 0xd0, 0xb3, 0x3f, 0x39}} ,
+ {{0xce, 0x60, 0x09, 0x6c, 0xf5, 0x76, 0x17, 0x24, 0x80, 0x3a, 0x96, 0xc7, 0x94, 0x2e, 0xf7, 0x6b, 0xef, 0xb5, 0x05, 0x96, 0xef, 0xd3, 0x7b, 0x51, 0xda, 0x05, 0x44, 0x67, 0xbc, 0x07, 0x21, 0x4e}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0xe9, 0x73, 0x6f, 0x21, 0xb9, 0xde, 0x22, 0x7d, 0xeb, 0x97, 0x31, 0x10, 0xa3, 0xea, 0xe1, 0xc6, 0x37, 0xeb, 0x8f, 0x43, 0x58, 0xde, 0x41, 0x64, 0x0e, 0x3e, 0x07, 0x99, 0x3d, 0xf1, 0xdf, 0x1e}} ,
+ {{0xf8, 0xad, 0x43, 0xc2, 0x17, 0x06, 0xe2, 0xe4, 0xa9, 0x86, 0xcd, 0x18, 0xd7, 0x78, 0xc8, 0x74, 0x66, 0xd2, 0x09, 0x18, 0xa5, 0xf1, 0xca, 0xa6, 0x62, 0x92, 0xc1, 0xcb, 0x00, 0xeb, 0x42, 0x2e}}},
+{{{0x7b, 0x34, 0x24, 0x4c, 0xcf, 0x38, 0xe5, 0x6c, 0x0a, 0x01, 0x2c, 0x22, 0x0b, 0x24, 0x38, 0xad, 0x24, 0x7e, 0x19, 0xf0, 0x6c, 0xf9, 0x31, 0xf4, 0x35, 0x11, 0xf6, 0x46, 0x33, 0x3a, 0x23, 0x59}} ,
+ {{0x20, 0x0b, 0xa1, 0x08, 0x19, 0xad, 0x39, 0x54, 0xea, 0x3e, 0x23, 0x09, 0xb6, 0xe2, 0xd2, 0xbc, 0x4d, 0xfc, 0x9c, 0xf0, 0x13, 0x16, 0x22, 0x3f, 0xb9, 0xd2, 0x11, 0x86, 0x90, 0x55, 0xce, 0x3c}}},
+{{{0xc4, 0x0b, 0x4b, 0x62, 0x99, 0x37, 0x84, 0x3f, 0x74, 0xa2, 0xf9, 0xce, 0xe2, 0x0b, 0x0f, 0x2a, 0x3d, 0xa3, 0xe3, 0xdb, 0x5a, 0x9d, 0x93, 0xcc, 0xa5, 0xef, 0x82, 0x91, 0x1d, 0xe6, 0x6c, 0x68}} ,
+ {{0xa3, 0x64, 0x17, 0x9b, 0x8b, 0xc8, 0x3a, 0x61, 0xe6, 0x9d, 0xc6, 0xed, 0x7b, 0x03, 0x52, 0x26, 0x9d, 0x3a, 0xb3, 0x13, 0xcc, 0x8a, 0xfd, 0x2c, 0x1a, 0x1d, 0xed, 0x13, 0xd0, 0x55, 0x57, 0x0e}}},
+{{{0x1a, 0xea, 0xbf, 0xfd, 0x4a, 0x3c, 0x8e, 0xec, 0x29, 0x7e, 0x77, 0x77, 0x12, 0x99, 0xd7, 0x84, 0xf9, 0x55, 0x7f, 0xf1, 0x8b, 0xb4, 0xd2, 0x95, 0xa3, 0x8d, 0xf0, 0x8a, 0xa7, 0xeb, 0x82, 0x4b}} ,
+ {{0x2c, 0x28, 0xf4, 0x3a, 0xf6, 0xde, 0x0a, 0xe0, 0x41, 0x44, 0x23, 0xf8, 0x3f, 0x03, 0x64, 0x9f, 0xc3, 0x55, 0x4c, 0xc6, 0xc1, 0x94, 0x1c, 0x24, 0x5d, 0x5f, 0x92, 0x45, 0x96, 0x57, 0x37, 0x14}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0xc1, 0xcd, 0x90, 0x66, 0xb9, 0x76, 0xa0, 0x5b, 0xa5, 0x85, 0x75, 0x23, 0xf9, 0x89, 0xa5, 0x82, 0xb2, 0x6f, 0xb1, 0xeb, 0xc4, 0x69, 0x6f, 0x18, 0x5a, 0xed, 0x94, 0x3d, 0x9d, 0xd9, 0x2c, 0x1a}} ,
+ {{0x35, 0xb0, 0xe6, 0x73, 0x06, 0xb7, 0x37, 0xe0, 0xf8, 0xb0, 0x22, 0xe8, 0xd2, 0xed, 0x0b, 0xef, 0xe6, 0xc6, 0x5a, 0x99, 0x9e, 0x1a, 0x9f, 0x04, 0x97, 0xe4, 0x4d, 0x0b, 0xbe, 0xba, 0x44, 0x40}}},
+{{{0xc1, 0x56, 0x96, 0x91, 0x5f, 0x1f, 0xbb, 0x54, 0x6f, 0x88, 0x89, 0x0a, 0xb2, 0xd6, 0x41, 0x42, 0x6a, 0x82, 0xee, 0x14, 0xaa, 0x76, 0x30, 0x65, 0x0f, 0x67, 0x39, 0xa6, 0x51, 0x7c, 0x49, 0x24}} ,
+ {{0x35, 0xa3, 0x78, 0xd1, 0x11, 0x0f, 0x75, 0xd3, 0x70, 0x46, 0xdb, 0x20, 0x51, 0xcb, 0x92, 0x80, 0x54, 0x10, 0x74, 0x36, 0x86, 0xa9, 0xd7, 0xa3, 0x08, 0x78, 0xf1, 0x01, 0x29, 0xf8, 0x80, 0x3b}}},
+{{{0xdb, 0xa7, 0x9d, 0x9d, 0xbf, 0xa0, 0xcc, 0xed, 0x53, 0xa2, 0xa2, 0x19, 0x39, 0x48, 0x83, 0x19, 0x37, 0x58, 0xd1, 0x04, 0x28, 0x40, 0xf7, 0x8a, 0xc2, 0x08, 0xb7, 0xa5, 0x42, 0xcf, 0x53, 0x4c}} ,
+ {{0xa7, 0xbb, 0xf6, 0x8e, 0xad, 0xdd, 0xf7, 0x90, 0xdd, 0x5f, 0x93, 0x89, 0xae, 0x04, 0x37, 0xe6, 0x9a, 0xb7, 0xe8, 0xc0, 0xdf, 0x16, 0x2a, 0xbf, 0xc4, 0x3a, 0x3c, 0x41, 0xd5, 0x89, 0x72, 0x5a}}},
+{{{0x1f, 0x96, 0xff, 0x34, 0x2c, 0x13, 0x21, 0xcb, 0x0a, 0x89, 0x85, 0xbe, 0xb3, 0x70, 0x9e, 0x1e, 0xde, 0x97, 0xaf, 0x96, 0x30, 0xf7, 0x48, 0x89, 0x40, 0x8d, 0x07, 0xf1, 0x25, 0xf0, 0x30, 0x58}} ,
+ {{0x1e, 0xd4, 0x93, 0x57, 0xe2, 0x17, 0xe7, 0x9d, 0xab, 0x3c, 0x55, 0x03, 0x82, 0x2f, 0x2b, 0xdb, 0x56, 0x1e, 0x30, 0x2e, 0x24, 0x47, 0x6e, 0xe6, 0xff, 0x33, 0x24, 0x2c, 0x75, 0x51, 0xd4, 0x67}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0x2b, 0x06, 0xd9, 0xa1, 0x5d, 0xe1, 0xf4, 0xd1, 0x1e, 0x3c, 0x9a, 0xc6, 0x29, 0x2b, 0x13, 0x13, 0x78, 0xc0, 0xd8, 0x16, 0x17, 0x2d, 0x9e, 0xa9, 0xc9, 0x79, 0x57, 0xab, 0x24, 0x91, 0x92, 0x19}} ,
+ {{0x69, 0xfb, 0xa1, 0x9c, 0xa6, 0x75, 0x49, 0x7d, 0x60, 0x73, 0x40, 0x42, 0xc4, 0x13, 0x0a, 0x95, 0x79, 0x1e, 0x04, 0x83, 0x94, 0x99, 0x9b, 0x1e, 0x0c, 0xe8, 0x1f, 0x54, 0xef, 0xcb, 0xc0, 0x52}}},
+{{{0x14, 0x89, 0x73, 0xa1, 0x37, 0x87, 0x6a, 0x7a, 0xcf, 0x1d, 0xd9, 0x2e, 0x1a, 0x67, 0xed, 0x74, 0xc0, 0xf0, 0x9c, 0x33, 0xdd, 0xdf, 0x08, 0xbf, 0x7b, 0xd1, 0x66, 0xda, 0xe6, 0xc9, 0x49, 0x08}} ,
+ {{0xe9, 0xdd, 0x5e, 0x55, 0xb0, 0x0a, 0xde, 0x21, 0x4c, 0x5a, 0x2e, 0xd4, 0x80, 0x3a, 0x57, 0x92, 0x7a, 0xf1, 0xc4, 0x2c, 0x40, 0xaf, 0x2f, 0xc9, 0x92, 0x03, 0xe5, 0x5a, 0xbc, 0xdc, 0xf4, 0x09}}},
+{{{0xf3, 0xe1, 0x2b, 0x7c, 0x05, 0x86, 0x80, 0x93, 0x4a, 0xad, 0xb4, 0x8f, 0x7e, 0x99, 0x0c, 0xfd, 0xcd, 0xef, 0xd1, 0xff, 0x2c, 0x69, 0x34, 0x13, 0x41, 0x64, 0xcf, 0x3b, 0xd0, 0x90, 0x09, 0x1e}} ,
+ {{0x9d, 0x45, 0xd6, 0x80, 0xe6, 0x45, 0xaa, 0xf4, 0x15, 0xaa, 0x5c, 0x34, 0x87, 0x99, 0xa2, 0x8c, 0x26, 0x84, 0x62, 0x7d, 0xb6, 0x29, 0xc0, 0x52, 0xea, 0xf5, 0x81, 0x18, 0x0f, 0x35, 0xa9, 0x0e}}},
+{{{0xe7, 0x20, 0x72, 0x7c, 0x6d, 0x94, 0x5f, 0x52, 0x44, 0x54, 0xe3, 0xf1, 0xb2, 0xb0, 0x36, 0x46, 0x0f, 0xae, 0x92, 0xe8, 0x70, 0x9d, 0x6e, 0x79, 0xb1, 0xad, 0x37, 0xa9, 0x5f, 0xc0, 0xde, 0x03}} ,
+ {{0x15, 0x55, 0x37, 0xc6, 0x1c, 0x27, 0x1c, 0x6d, 0x14, 0x4f, 0xca, 0xa4, 0xc4, 0x88, 0x25, 0x46, 0x39, 0xfc, 0x5a, 0xe5, 0xfe, 0x29, 0x11, 0x69, 0xf5, 0x72, 0x84, 0x4d, 0x78, 0x9f, 0x94, 0x15}}},
+{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+{{{0xec, 0xd3, 0xff, 0x57, 0x0b, 0xb0, 0xb2, 0xdc, 0xf8, 0x4f, 0xe2, 0x12, 0xd5, 0x36, 0xbe, 0x6b, 0x09, 0x43, 0x6d, 0xa3, 0x4d, 0x90, 0x2d, 0xb8, 0x74, 0xe8, 0x71, 0x45, 0x19, 0x8b, 0x0c, 0x6a}} ,
+ {{0xb8, 0x42, 0x1c, 0x03, 0xad, 0x2c, 0x03, 0x8e, 0xac, 0xd7, 0x98, 0x29, 0x13, 0xc6, 0x02, 0x29, 0xb5, 0xd4, 0xe7, 0xcf, 0xcc, 0x8b, 0x83, 0xec, 0x35, 0xc7, 0x9c, 0x74, 0xb7, 0xad, 0x85, 0x5f}}},
+{{{0x78, 0x84, 0xe1, 0x56, 0x45, 0x69, 0x68, 0x5a, 0x4f, 0xb8, 0xb1, 0x29, 0xff, 0x33, 0x03, 0x31, 0xb7, 0xcb, 0x96, 0x25, 0xe6, 0xe6, 0x41, 0x98, 0x1a, 0xbb, 0x03, 0x56, 0xf2, 0xb2, 0x91, 0x34}} ,
+ {{0x2c, 0x6c, 0xf7, 0x66, 0xa4, 0x62, 0x6b, 0x39, 0xb3, 0xba, 0x65, 0xd3, 0x1c, 0xf8, 0x11, 0xaa, 0xbe, 0xdc, 0x80, 0x59, 0x87, 0xf5, 0x7b, 0xe5, 0xe3, 0xb3, 0x3e, 0x39, 0xda, 0xbe, 0x88, 0x09}}},
+{{{0x8b, 0xf1, 0xa0, 0xf5, 0xdc, 0x29, 0xb4, 0xe2, 0x07, 0xc6, 0x7a, 0x00, 0xd0, 0x89, 0x17, 0x51, 0xd4, 0xbb, 0xd4, 0x22, 0xea, 0x7e, 0x7d, 0x7c, 0x24, 0xea, 0xf2, 0xe8, 0x22, 0x12, 0x95, 0x06}} ,
+ {{0xda, 0x7c, 0xa4, 0x0c, 0xf4, 0xba, 0x6e, 0xe1, 0x89, 0xb5, 0x59, 0xca, 0xf1, 0xc0, 0x29, 0x36, 0x09, 0x44, 0xe2, 0x7f, 0xd1, 0x63, 0x15, 0x99, 0xea, 0x25, 0xcf, 0x0c, 0x9d, 0xc0, 0x44, 0x6f}}},
+{{{0x1d, 0x86, 0x4e, 0xcf, 0xf7, 0x37, 0x10, 0x25, 0x8f, 0x12, 0xfb, 0x19, 0xfb, 0xe0, 0xed, 0x10, 0xc8, 0xe2, 0xf5, 0x75, 0xb1, 0x33, 0xc0, 0x96, 0x0d, 0xfb, 0x15, 0x6c, 0x0d, 0x07, 0x5f, 0x05}} ,
+ {{0x69, 0x3e, 0x47, 0x97, 0x2c, 0xaf, 0x52, 0x7c, 0x78, 0x83, 0xad, 0x1b, 0x39, 0x82, 0x2f, 0x02, 0x6f, 0x47, 0xdb, 0x2a, 0xb0, 0xe1, 0x91, 0x99, 0x55, 0xb8, 0x99, 0x3a, 0xa0, 0x44, 0x11, 0x51}}}
+};
+
+static void p1p1_to_p2(ge25519_p2 *r, const ge25519_p1p1 *p)
+{
+ fe25519_mul(&r->x, &p->x, &p->t);
+ fe25519_mul(&r->y, &p->y, &p->z);
+ fe25519_mul(&r->z, &p->z, &p->t);
+}
+
+static void p1p1_to_p3(ge25519_p3 *r, const ge25519_p1p1 *p)
+{
+ p1p1_to_p2((ge25519_p2 *)r, p);
+ fe25519_mul(&r->t, &p->x, &p->y);
+}
+
+static void ge25519_mixadd2(ge25519_p3 *r, const ge25519_aff *q)
+{
+ fe25519 a,b,t1,t2,c,d,e,f,g,h,qt;
+ fe25519_mul(&qt, &q->x, &q->y);
+ fe25519_sub(&a, &r->y, &r->x); /* A = (Y1-X1)*(Y2-X2) */
+ fe25519_add(&b, &r->y, &r->x); /* B = (Y1+X1)*(Y2+X2) */
+ fe25519_sub(&t1, &q->y, &q->x);
+ fe25519_add(&t2, &q->y, &q->x);
+ fe25519_mul(&a, &a, &t1);
+ fe25519_mul(&b, &b, &t2);
+ fe25519_sub(&e, &b, &a); /* E = B-A */
+ fe25519_add(&h, &b, &a); /* H = B+A */
+ fe25519_mul(&c, &r->t, &qt); /* C = T1*k*T2 */
+ fe25519_mul(&c, &c, &ge25519_ec2d);
+ fe25519_add(&d, &r->z, &r->z); /* D = Z1*2 */
+ fe25519_sub(&f, &d, &c); /* F = D-C */
+ fe25519_add(&g, &d, &c); /* G = D+C */
+ fe25519_mul(&r->x, &e, &f);
+ fe25519_mul(&r->y, &h, &g);
+ fe25519_mul(&r->z, &g, &f);
+ fe25519_mul(&r->t, &e, &h);
+}
+
+static void add_p1p1(ge25519_p1p1 *r, const ge25519_p3 *p, const ge25519_p3 *q)
+{
+ fe25519 a, b, c, d, t;
+
+ fe25519_sub(&a, &p->y, &p->x); /* A = (Y1-X1)*(Y2-X2) */
+ fe25519_sub(&t, &q->y, &q->x);
+ fe25519_mul(&a, &a, &t);
+ fe25519_add(&b, &p->x, &p->y); /* B = (Y1+X1)*(Y2+X2) */
+ fe25519_add(&t, &q->x, &q->y);
+ fe25519_mul(&b, &b, &t);
+ fe25519_mul(&c, &p->t, &q->t); /* C = T1*k*T2 */
+ fe25519_mul(&c, &c, &ge25519_ec2d);
+ fe25519_mul(&d, &p->z, &q->z); /* D = Z1*2*Z2 */
+ fe25519_add(&d, &d, &d);
+ fe25519_sub(&r->x, &b, &a); /* E = B-A */
+ fe25519_sub(&r->t, &d, &c); /* F = D-C */
+ fe25519_add(&r->z, &d, &c); /* G = D+C */
+ fe25519_add(&r->y, &b, &a); /* H = B+A */
+}
+
+/* See http://www.hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html#doubling-dbl-2008-hwcd */
+static void dbl_p1p1(ge25519_p1p1 *r, const ge25519_p2 *p)
+{
+ fe25519 a,b,c,d;
+ fe25519_square(&a, &p->x);
+ fe25519_square(&b, &p->y);
+ fe25519_square(&c, &p->z);
+ fe25519_add(&c, &c, &c);
+ fe25519_neg(&d, &a);
+
+ fe25519_add(&r->x, &p->x, &p->y);
+ fe25519_square(&r->x, &r->x);
+ fe25519_sub(&r->x, &r->x, &a);
+ fe25519_sub(&r->x, &r->x, &b);
+ fe25519_add(&r->z, &d, &b);
+ fe25519_sub(&r->t, &r->z, &c);
+ fe25519_sub(&r->y, &d, &b);
+}
+
+/* Constant-time version of: if(b) r = p */
+static void cmov_aff(ge25519_aff *r, const ge25519_aff *p, unsigned char b)
+{
+ fe25519_cmov(&r->x, &p->x, b);
+ fe25519_cmov(&r->y, &p->y, b);
+}
+
+static unsigned char equal(signed char b,signed char c)
+{
+ unsigned char ub = b;
+ unsigned char uc = c;
+ unsigned char x = ub ^ uc; /* 0: yes; 1..255: no */
+ crypto_uint32 y = x; /* 0: yes; 1..255: no */
+ y -= 1; /* 4294967295: yes; 0..254: no */
+ y >>= 31; /* 1: yes; 0: no */
+ return y;
+}
+
+static unsigned char negative(signed char b)
+{
+ unsigned long long x = b; /* 18446744073709551361..18446744073709551615: yes; 0..255: no */
+ x >>= 63; /* 1: yes; 0: no */
+ return x;
+}
+
+static void choose_t(ge25519_aff *t, unsigned long long pos, signed char b)
+{
+ /* constant time */
+ fe25519 v;
+ *t = ge25519_base_multiples_affine[5*pos+0];
+ cmov_aff(t, &ge25519_base_multiples_affine[5*pos+1],equal(b,1) | equal(b,-1));
+ cmov_aff(t, &ge25519_base_multiples_affine[5*pos+2],equal(b,2) | equal(b,-2));
+ cmov_aff(t, &ge25519_base_multiples_affine[5*pos+3],equal(b,3) | equal(b,-3));
+ cmov_aff(t, &ge25519_base_multiples_affine[5*pos+4],equal(b,-4));
+ fe25519_neg(&v, &t->x);
+ fe25519_cmov(&t->x, &v, negative(b));
+}
+
+static void setneutral(ge25519 *r)
+{
+ fe25519_setzero(&r->x);
+ fe25519_setone(&r->y);
+ fe25519_setone(&r->z);
+ fe25519_setzero(&r->t);
+}
+
+/* ********************************************************************
+ * EXPORTED FUNCTIONS
+ ******************************************************************** */
+
+/* return 0 on success, -1 otherwise */
+int ge25519_unpackneg_vartime(ge25519_p3 *r, const unsigned char p[32])
+{
+ unsigned char par;
+ fe25519 t, chk, num, den, den2, den4, den6;
+ fe25519_setone(&r->z);
+ par = p[31] >> 7;
+ fe25519_unpack(&r->y, p);
+ fe25519_square(&num, &r->y); /* x = y^2 */
+ fe25519_mul(&den, &num, &ge25519_ecd); /* den = dy^2 */
+ fe25519_sub(&num, &num, &r->z); /* x = y^2-1 */
+ fe25519_add(&den, &r->z, &den); /* den = dy^2+1 */
+
+ /* Computation of sqrt(num/den) */
+ /* 1.: computation of num^((p-5)/8)*den^((7p-35)/8) = (num*den^7)^((p-5)/8) */
+ fe25519_square(&den2, &den);
+ fe25519_square(&den4, &den2);
+ fe25519_mul(&den6, &den4, &den2);
+ fe25519_mul(&t, &den6, &num);
+ fe25519_mul(&t, &t, &den);
+
+ fe25519_pow2523(&t, &t);
+ /* 2. computation of r->x = t * num * den^3 */
+ fe25519_mul(&t, &t, &num);
+ fe25519_mul(&t, &t, &den);
+ fe25519_mul(&t, &t, &den);
+ fe25519_mul(&r->x, &t, &den);
+
+ /* 3. Check whether sqrt computation gave correct result, multiply by sqrt(-1) if not: */
+ fe25519_square(&chk, &r->x);
+ fe25519_mul(&chk, &chk, &den);
+ if (!fe25519_iseq_vartime(&chk, &num))
+ fe25519_mul(&r->x, &r->x, &ge25519_sqrtm1);
+
+ /* 4. Now we have one of the two square roots, except if input was not a square */
+ fe25519_square(&chk, &r->x);
+ fe25519_mul(&chk, &chk, &den);
+ if (!fe25519_iseq_vartime(&chk, &num))
+ return -1;
+
+ /* 5. Choose the desired square root according to parity: */
+ if(fe25519_getparity(&r->x) != (1-par))
+ fe25519_neg(&r->x, &r->x);
+
+ fe25519_mul(&r->t, &r->x, &r->y);
+ return 0;
+}
+
+static void ge25519_pack(unsigned char r[32], const ge25519_p3 *p)
+{
+ fe25519 tx, ty, zi;
+ fe25519_invert(&zi, &p->z);
+ fe25519_mul(&tx, &p->x, &zi);
+ fe25519_mul(&ty, &p->y, &zi);
+ fe25519_pack(r, &ty);
+ r[31] ^= fe25519_getparity(&tx) << 7;
+}
+
+int ge25519_isneutral_vartime(const ge25519_p3 *p)
+{
+ int ret = 1;
+ if(!fe25519_iszero(&p->x)) ret = 0;
+ if(!fe25519_iseq_vartime(&p->y, &p->z)) ret = 0;
+ return ret;
+}
+
+/* computes [s1]p1 + [s2]p2 */
+static void ge25519_double_scalarmult_vartime(ge25519_p3 *r, const ge25519_p3 *p1, const sc25519 *s1, const ge25519_p3 *p2, const sc25519 *s2)
+{
+ ge25519_p1p1 tp1p1;
+ ge25519_p3 pre[16];
+ unsigned char b[127];
+ int i;
+
+ /* precomputation s2 s1 */
+ setneutral(pre); /* 00 00 */
+ pre[1] = *p1; /* 00 01 */
+ dbl_p1p1(&tp1p1,(ge25519_p2 *)p1); p1p1_to_p3( &pre[2], &tp1p1); /* 00 10 */
+ add_p1p1(&tp1p1,&pre[1], &pre[2]); p1p1_to_p3( &pre[3], &tp1p1); /* 00 11 */
+ pre[4] = *p2; /* 01 00 */
+ add_p1p1(&tp1p1,&pre[1], &pre[4]); p1p1_to_p3( &pre[5], &tp1p1); /* 01 01 */
+ add_p1p1(&tp1p1,&pre[2], &pre[4]); p1p1_to_p3( &pre[6], &tp1p1); /* 01 10 */
+ add_p1p1(&tp1p1,&pre[3], &pre[4]); p1p1_to_p3( &pre[7], &tp1p1); /* 01 11 */
+ dbl_p1p1(&tp1p1,(ge25519_p2 *)p2); p1p1_to_p3( &pre[8], &tp1p1); /* 10 00 */
+ add_p1p1(&tp1p1,&pre[1], &pre[8]); p1p1_to_p3( &pre[9], &tp1p1); /* 10 01 */
+ dbl_p1p1(&tp1p1,(ge25519_p2 *)&pre[5]); p1p1_to_p3(&pre[10], &tp1p1); /* 10 10 */
+ add_p1p1(&tp1p1,&pre[3], &pre[8]); p1p1_to_p3(&pre[11], &tp1p1); /* 10 11 */
+ add_p1p1(&tp1p1,&pre[4], &pre[8]); p1p1_to_p3(&pre[12], &tp1p1); /* 11 00 */
+ add_p1p1(&tp1p1,&pre[1],&pre[12]); p1p1_to_p3(&pre[13], &tp1p1); /* 11 01 */
+ add_p1p1(&tp1p1,&pre[2],&pre[12]); p1p1_to_p3(&pre[14], &tp1p1); /* 11 10 */
+ add_p1p1(&tp1p1,&pre[3],&pre[12]); p1p1_to_p3(&pre[15], &tp1p1); /* 11 11 */
+
+ sc25519_2interleave2(b,s1,s2);
+
+ /* scalar multiplication */
+ *r = pre[b[126]];
+ for(i=125;i>=0;i--)
+ {
+ dbl_p1p1(&tp1p1, (ge25519_p2 *)r);
+ p1p1_to_p2((ge25519_p2 *) r, &tp1p1);
+ dbl_p1p1(&tp1p1, (ge25519_p2 *)r);
+ if(b[i]!=0)
+ {
+ p1p1_to_p3(r, &tp1p1);
+ add_p1p1(&tp1p1, r, &pre[b[i]]);
+ }
+ if(i != 0) p1p1_to_p2((ge25519_p2 *)r, &tp1p1);
+ else p1p1_to_p3(r, &tp1p1);
+ }
+}
+
+static void ge25519_scalarmult_base(ge25519_p3 *r, const sc25519 *s)
+{
+ signed char b[85];
+ int i;
+ ge25519_aff t;
+ sc25519_window3(b,s);
+
+ choose_t((ge25519_aff *)r, 0, b[0]);
+ fe25519_setone(&r->z);
+ fe25519_mul(&r->t, &r->x, &r->y);
+ for(i=1;i<85;i++)
+ {
+ choose_t(&t, (unsigned long long) i, b[i]);
+ ge25519_mixadd2(r, &t);
+ }
+}
+/* from supercop-20221122/crypto_sign/ed25519/ref/keypair.c */
+
+int crypto_sign_ed25519_keypair(unsigned char *pk,unsigned char *sk)
+{
+ unsigned char az[64];
sc25519 scsk;
ge25519 gepk;
- unsigned char extsk[64];
- int i;
- randombytes(sk, 32);
- crypto_hash_sha512(extsk, sk, 32);
- extsk[0] &= 248;
- extsk[31] &= 127;
- extsk[31] |= 64;
+ randombytes(sk,32);
+ crypto_hash_sha512(az,sk,32);
+ az[0] &= 248;
+ az[31] &= 127;
+ az[31] |= 64;
+
+ sc25519_from32bytes(&scsk,az);
- sc25519_from32bytes(&scsk,extsk);
-
ge25519_scalarmult_base(&gepk, &scsk);
ge25519_pack(pk, &gepk);
- for(i=0;i<32;i++)
- sk[32 + i] = pk[i];
+ memmove(sk + 32,pk,32);
return 0;
}
+/* from supercop-20221122/crypto_sign/ed25519/ref/sign.c */
int crypto_sign_ed25519(
unsigned char *sm,unsigned long long *smlen,
const unsigned char *m,unsigned long long mlen,
const unsigned char *sk
)
{
+ unsigned char pk[32];
+ unsigned char az[64];
+ unsigned char nonce[64];
+ unsigned char hram[64];
sc25519 sck, scs, scsk;
ge25519 ger;
- unsigned char r[32];
- unsigned char s[32];
- unsigned char extsk[64];
- unsigned long long i;
- unsigned char hmg[crypto_hash_sha512_BYTES];
- unsigned char hram[crypto_hash_sha512_BYTES];
-
- crypto_hash_sha512(extsk, sk, 32);
- extsk[0] &= 248;
- extsk[31] &= 127;
- extsk[31] |= 64;
-
- *smlen = mlen+64;
- for(i=0;i<mlen;i++)
- sm[64 + i] = m[i];
- for(i=0;i<32;i++)
- sm[32 + i] = extsk[32+i];
- crypto_hash_sha512(hmg, sm+32, mlen+32); /* Generate k as h(extsk[32],...,extsk[63],m) */
+ memmove(pk,sk + 32,32);
+ /* pk: 32-byte public key A */
+
+ crypto_hash_sha512(az,sk,32);
+ az[0] &= 248;
+ az[31] &= 127;
+ az[31] |= 64;
+ /* az: 32-byte scalar a, 32-byte randomizer z */
+
+ *smlen = mlen + 64;
+ memmove(sm + 64,m,mlen);
+ memmove(sm + 32,az + 32,32);
+ /* sm: 32-byte uninit, 32-byte z, mlen-byte m */
- /* Computation of R */
- sc25519_from64bytes(&sck, hmg);
+ crypto_hash_sha512(nonce, sm+32, mlen+32);
+ /* nonce: 64-byte H(z,m) */
+
+ sc25519_from64bytes(&sck, nonce);
ge25519_scalarmult_base(&ger, &sck);
- ge25519_pack(r, &ger);
-
- /* Computation of s */
- for(i=0;i<32;i++)
- sm[i] = r[i];
+ ge25519_pack(sm, &ger);
+ /* sm: 32-byte R, 32-byte z, mlen-byte m */
+
+ memmove(sm + 32,pk,32);
+ /* sm: 32-byte R, 32-byte A, mlen-byte m */
- get_hram(hram, sm, sk+32, sm, mlen+64);
+ crypto_hash_sha512(hram,sm,mlen + 64);
+ /* hram: 64-byte H(R,A,m) */
sc25519_from64bytes(&scs, hram);
- sc25519_from32bytes(&scsk, extsk);
+ sc25519_from32bytes(&scsk, az);
sc25519_mul(&scs, &scs, &scsk);
-
sc25519_add(&scs, &scs, &sck);
+ /* scs: S = nonce + H(R,A,m)a */
- sc25519_to32bytes(s,&scs); /* cat s */
- for(i=0;i<32;i++)
- sm[32 + i] = s[i];
+ sc25519_to32bytes(sm + 32,&scs);
+ /* sm: 32-byte R, 32-byte S, mlen-byte m */
return 0;
}
+/* from supercop-20221122/crypto_sign/ed25519/ref/open.c */
int crypto_sign_ed25519_open(
unsigned char *m,unsigned long long *mlen,
const unsigned char *sm,unsigned long long smlen,
const unsigned char *pk
)
{
- unsigned int i;
- int ret;
- unsigned char t2[32];
+ unsigned char pkcopy[32];
+ unsigned char rcopy[32];
+ unsigned char hram[64];
+ unsigned char rcheck[32];
ge25519 get1, get2;
sc25519 schram, scs;
- unsigned char hram[crypto_hash_sha512_BYTES];
- *mlen = (unsigned long long) -1;
- if (smlen < 64) return -1;
+ if (smlen < 64) goto badsig;
+ if (sm[63] & 224) goto badsig;
+ if (ge25519_unpackneg_vartime(&get1,pk)) goto badsig;
- if (ge25519_unpackneg_vartime(&get1, pk)) return -1;
+ memmove(pkcopy,pk,32);
+ memmove(rcopy,sm,32);
- get_hram(hram,sm,pk,m,smlen);
+ sc25519_from32bytes(&scs, sm+32);
- sc25519_from64bytes(&schram, hram);
+ memmove(m,sm,smlen);
+ memmove(m + 32,pkcopy,32);
+ crypto_hash_sha512(hram,m,smlen);
- sc25519_from32bytes(&scs, sm+32);
+ sc25519_from64bytes(&schram, hram);
ge25519_double_scalarmult_vartime(&get2, &get1, &schram, &ge25519_base, &scs);
- ge25519_pack(t2, &get2);
-
- ret = crypto_verify_32(sm, t2);
+ ge25519_pack(rcheck, &get2);
- if (!ret)
- {
- for(i=0;i<smlen-64;i++)
- m[i] = sm[i + 64];
- *mlen = smlen-64;
+ if (crypto_verify_32(rcopy,rcheck) == 0) {
+ memmove(m,m + 64,smlen - 64);
+ memset(m + smlen - 64,0,64);
+ *mlen = smlen - 64;
+ return 0;
}
- else
- {
- for(i=0;i<smlen-64;i++)
- m[i] = 0;
- }
- return ret;
+
+badsig:
+ *mlen = (unsigned long long) -1;
+ memset(m,0,smlen);
+ return -1;
}
diff --git a/crypto/openssh/ed25519.sh b/crypto/openssh/ed25519.sh
new file mode 100644
index 000000000000..8722338dba3b
--- /dev/null
+++ b/crypto/openssh/ed25519.sh
@@ -0,0 +1,119 @@
+#!/bin/sh
+# $OpenBSD: ed25519.sh,v 1.1 2023/01/15 23:05:32 djm Exp $
+# Placed in the Public Domain.
+#
+AUTHOR="supercop-20221122/crypto_sign/ed25519/ref/implementors"
+FILES="
+ supercop-20221122/crypto_verify/32/ref/verify.c
+ supercop-20221122/crypto_sign/ed25519/ref/fe25519.h
+ supercop-20221122/crypto_sign/ed25519/ref/fe25519.c
+ supercop-20221122/crypto_sign/ed25519/ref/sc25519.h
+ supercop-20221122/crypto_sign/ed25519/ref/sc25519.c
+ supercop-20221122/crypto_sign/ed25519/ref/ge25519.h
+ supercop-20221122/crypto_sign/ed25519/ref/ge25519.c
+ supercop-20221122/crypto_sign/ed25519/ref/keypair.c
+ supercop-20221122/crypto_sign/ed25519/ref/sign.c
+ supercop-20221122/crypto_sign/ed25519/ref/open.c
+"
+###
+
+DATA="supercop-20221122/crypto_sign/ed25519/ref/ge25519_base.data"
+
+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
+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:
+ # - inline ge25519_base.data where it is included
+ # - expand CRYPTO_NAMESPACE() namespacing define
+ # - remove all includes, we inline everything required.
+ # - make functions not required elsewhere static.
+ # - rename the functions we do use.
+ sed \
+ -e "/#include \"ge25519_base.data\"/r $DATA" \
+ -e "/#include/d" \
+ -e "s/^void /static void /g" \
+ -e 's/CRYPTO_NAMESPACE[(]\([a-zA-Z0-9_]*\)[)]/crypto_sign_ed25519_ref_\1/g' \
+ $i | \
+ case "$i" in
+ */crypto_verify/32/ref/verify.c)
+ # rename crypto_verify() to the name that the ed25519 code expects.
+ sed -e "/^#include.*/d" \
+ -e "s/crypto_verify/crypto_verify_32/g" \
+ -e "s/^int /static int /g"
+ ;;
+ */crypto_sign/ed25519/ref/sign.c)
+ # rename signing function to the name OpenSSH expects
+ sed -e "s/crypto_sign/crypto_sign_ed25519/g"
+ ;;
+ */crypto_sign/ed25519/ref/keypair.c)
+ # rename key generation function to the name OpenSSH expects
+ sed -e "s/crypto_sign_keypair/crypto_sign_ed25519_keypair/g"
+ ;;
+ */crypto_sign/ed25519/ref/open.c)
+ # rename verification function to the name OpenSSH expects
+ sed -e "s/crypto_sign_open/crypto_sign_ed25519_open/g"
+ ;;
+ */crypto_sign/ed25519/ref/fe25519.*)
+ # avoid a couple of name collions with other files
+ sed -e "s/reduce_add_sub/fe25519_reduce_add_sub/g" \
+ -e "s/ equal[(]/ fe25519_equal(/g" \
+ -e "s/^int /static int /g"
+ ;;
+ */crypto_sign/ed25519/ref/sc25519.h)
+ # Lots of unused prototypes to remove
+ sed -e "s/^int /static int /g" \
+ -e '/shortsc25519_from16bytes/d' \
+ -e '/sc25519_iszero_vartime/d' \
+ -e '/sc25519_isshort_vartime/d' \
+ -e '/sc25519_lt_vartime/d' \
+ -e '/sc25519_sub_nored/d' \
+ -e '/sc25519_mul_shortsc/d' \
+ -e '/sc25519_from_shortsc/d' \
+ -e '/sc25519_window5/d'
+ ;;
+ */crypto_sign/ed25519/ref/sc25519.c)
+ # Lots of unused code to remove, some name collisions to avoid
+ sed -e "s/reduce_add_sub/sc25519_reduce_add_sub/g" \
+ -e "s/ equal[(]/ sc25519_equal(/g" \
+ -e "s/^int /static int /g" \
+ -e "s/m[[]/sc25519_m[/g" \
+ -e "s/mu[[]/sc25519_mu[/g" \
+ -e '/shortsc25519_from16bytes/,/^}$/d' \
+ -e '/sc25519_iszero_vartime/,/^}$/d' \
+ -e '/sc25519_isshort_vartime/,/^}$/d' \
+ -e '/sc25519_lt_vartime/,/^}$/d' \
+ -e '/sc25519_sub_nored/,/^}$/d' \
+ -e '/sc25519_mul_shortsc/,/^}$/d' \
+ -e '/sc25519_from_shortsc/,/^}$/d' \
+ -e '/sc25519_window5/,/^}$/d'
+ ;;
+ */crypto_sign/ed25519/ref//ge25519.*)
+ sed -e "s/^int /static int /g"
+ ;;
+ # Default: pass through.
+ *)
+ cat
+ ;;
+ esac | \
+ sed -e 's/[ ]*$//'
+done
diff --git a/crypto/openssh/entropy.c b/crypto/openssh/entropy.c
index a4088e43cdf8..842c66fd6d0f 100644
--- a/crypto/openssh/entropy.c
+++ b/crypto/openssh/entropy.c
@@ -1,143 +1,109 @@
/*
* 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"
#define RANDOM_SEED_SIZE 48
#ifdef WITH_OPENSSL
#include <sys/types.h>
#include <errno.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <openssl/rand.h>
#include <openssl/crypto.h>
#include <openssl/err.h>
#include "openbsd-compat/openssl-compat.h"
#include "ssh.h"
#include "misc.h"
#include "xmalloc.h"
#include "atomicio.h"
#include "pathnames.h"
#include "log.h"
#include "sshbuf.h"
#include "ssherr.h"
/*
* Portable OpenSSH PRNG seeding:
* If OpenSSL has not "internally seeded" itself (e.g. pulled data from
* /dev/random), then collect RANDOM_SEED_SIZE bytes of randomness from
* PRNGd.
*/
-#ifndef OPENSSL_PRNG_ONLY
-
-void
-rexec_send_rng_seed(struct sshbuf *m)
-{
- u_char buf[RANDOM_SEED_SIZE];
- size_t len = sizeof(buf);
- int r;
-
- if (RAND_bytes(buf, sizeof(buf)) <= 0) {
- error("Couldn't obtain random bytes (error %ld)",
- ERR_get_error());
- len = 0;
- }
- if ((r = sshbuf_put_string(m, buf, len)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
- explicit_bzero(buf, sizeof(buf));
-}
-
-void
-rexec_recv_rng_seed(struct sshbuf *m)
-{
- const u_char *buf = NULL;
- size_t len = 0;
- int r;
-
- if ((r = sshbuf_get_string_direct(m, &buf, &len)) != 0)
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
-
- debug3("rexec_recv_rng_seed: seeding rng with %lu bytes",
- (unsigned long)len);
- RAND_add(buf, len, len);
-}
-#endif /* OPENSSL_PRNG_ONLY */
void
seed_rng(void)
{
unsigned char buf[RANDOM_SEED_SIZE];
/* Initialise libcrypto */
ssh_libcrypto_init();
if (!ssh_compatible_openssl(OPENSSL_VERSION_NUMBER,
OpenSSL_version_num()))
fatal("OpenSSL version mismatch. Built against %lx, you "
"have %lx", (u_long)OPENSSL_VERSION_NUMBER,
OpenSSL_version_num());
#ifndef OPENSSL_PRNG_ONLY
if (RAND_status() == 1)
debug3("RNG is ready, skipping seeding");
else {
if (seed_from_prngd(buf, sizeof(buf)) == -1)
fatal("Could not obtain seed from PRNGd");
RAND_add(buf, sizeof(buf), sizeof(buf));
}
#endif /* OPENSSL_PRNG_ONLY */
if (RAND_status() != 1)
fatal("PRNG is not seeded");
/* Ensure arc4random() is primed */
arc4random_buf(buf, sizeof(buf));
explicit_bzero(buf, sizeof(buf));
}
#else /* WITH_OPENSSL */
#include <stdlib.h>
#include <string.h>
/* Actual initialisation is handled in arc4random() */
void
seed_rng(void)
{
unsigned char buf[RANDOM_SEED_SIZE];
/* Ensure arc4random() is primed */
arc4random_buf(buf, sizeof(buf));
explicit_bzero(buf, sizeof(buf));
}
#endif /* WITH_OPENSSL */
diff --git a/crypto/openssh/fe25519.c b/crypto/openssh/fe25519.c
deleted file mode 100644
index e54fd154738b..000000000000
--- a/crypto/openssh/fe25519.c
+++ /dev/null
@@ -1,337 +0,0 @@
-/* $OpenBSD: fe25519.c,v 1.3 2013/12/09 11:03:45 markus Exp $ */
-
-/*
- * Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange,
- * Peter Schwabe, Bo-Yin Yang.
- * Copied from supercop-20130419/crypto_sign/ed25519/ref/fe25519.c
- */
-
-#include "includes.h"
-
-#define WINDOWSIZE 1 /* Should be 1,2, or 4 */
-#define WINDOWMASK ((1<<WINDOWSIZE)-1)
-
-#include "fe25519.h"
-
-static crypto_uint32 equal(crypto_uint32 a,crypto_uint32 b) /* 16-bit inputs */
-{
- crypto_uint32 x = a ^ b; /* 0: yes; 1..65535: no */
- x -= 1; /* 4294967295: yes; 0..65534: no */
- x >>= 31; /* 1: yes; 0: no */
- return x;
-}
-
-static crypto_uint32 ge(crypto_uint32 a,crypto_uint32 b) /* 16-bit inputs */
-{
- unsigned int x = a;
- x -= (unsigned int) b; /* 0..65535: yes; 4294901761..4294967295: no */
- x >>= 31; /* 0: yes; 1: no */
- x ^= 1; /* 1: yes; 0: no */
- return x;
-}
-
-static crypto_uint32 times19(crypto_uint32 a)
-{
- return (a << 4) + (a << 1) + a;
-}
-
-static crypto_uint32 times38(crypto_uint32 a)
-{
- return (a << 5) + (a << 2) + (a << 1);
-}
-
-static void reduce_add_sub(fe25519 *r)
-{
- crypto_uint32 t;
- int i,rep;
-
- for(rep=0;rep<4;rep++)
- {
- t = r->v[31] >> 7;
- r->v[31] &= 127;
- t = times19(t);
- r->v[0] += t;
- for(i=0;i<31;i++)
- {
- t = r->v[i] >> 8;
- r->v[i+1] += t;
- r->v[i] &= 255;
- }
- }
-}
-
-static void reduce_mul(fe25519 *r)
-{
- crypto_uint32 t;
- int i,rep;
-
- for(rep=0;rep<2;rep++)
- {
- t = r->v[31] >> 7;
- r->v[31] &= 127;
- t = times19(t);
- r->v[0] += t;
- for(i=0;i<31;i++)
- {
- t = r->v[i] >> 8;
- r->v[i+1] += t;
- r->v[i] &= 255;
- }
- }
-}
-
-/* reduction modulo 2^255-19 */
-void fe25519_freeze(fe25519 *r)
-{
- int i;
- crypto_uint32 m = equal(r->v[31],127);
- for(i=30;i>0;i--)
- m &= equal(r->v[i],255);
- m &= ge(r->v[0],237);
-
- m = -m;
-
- r->v[31] -= m&127;
- for(i=30;i>0;i--)
- r->v[i] -= m&255;
- r->v[0] -= m&237;
-}
-
-void fe25519_unpack(fe25519 *r, const unsigned char x[32])
-{
- int i;
- for(i=0;i<32;i++) r->v[i] = x[i];
- r->v[31] &= 127;
-}
-
-/* Assumes input x being reduced below 2^255 */
-void fe25519_pack(unsigned char r[32], const fe25519 *x)
-{
- int i;
- fe25519 y = *x;
- fe25519_freeze(&y);
- for(i=0;i<32;i++)
- r[i] = y.v[i];
-}
-
-int fe25519_iszero(const fe25519 *x)
-{
- int i;
- int r;
- fe25519 t = *x;
- fe25519_freeze(&t);
- r = equal(t.v[0],0);
- for(i=1;i<32;i++)
- r &= equal(t.v[i],0);
- return r;
-}
-
-int fe25519_iseq_vartime(const fe25519 *x, const fe25519 *y)
-{
- int i;
- fe25519 t1 = *x;
- fe25519 t2 = *y;
- fe25519_freeze(&t1);
- fe25519_freeze(&t2);
- for(i=0;i<32;i++)
- if(t1.v[i] != t2.v[i]) return 0;
- return 1;
-}
-
-void fe25519_cmov(fe25519 *r, const fe25519 *x, unsigned char b)
-{
- int i;
- crypto_uint32 mask = b;
- mask = -mask;
- for(i=0;i<32;i++) r->v[i] ^= mask & (x->v[i] ^ r->v[i]);
-}
-
-unsigned char fe25519_getparity(const fe25519 *x)
-{
- fe25519 t = *x;
- fe25519_freeze(&t);
- return t.v[0] & 1;
-}
-
-void fe25519_setone(fe25519 *r)
-{
- int i;
- r->v[0] = 1;
- for(i=1;i<32;i++) r->v[i]=0;
-}
-
-void fe25519_setzero(fe25519 *r)
-{
- int i;
- for(i=0;i<32;i++) r->v[i]=0;
-}
-
-void fe25519_neg(fe25519 *r, const fe25519 *x)
-{
- fe25519 t;
- int i;
- for(i=0;i<32;i++) t.v[i]=x->v[i];
- fe25519_setzero(r);
- fe25519_sub(r, r, &t);
-}
-
-void fe25519_add(fe25519 *r, const fe25519 *x, const fe25519 *y)
-{
- int i;
- for(i=0;i<32;i++) r->v[i] = x->v[i] + y->v[i];
- reduce_add_sub(r);
-}
-
-void fe25519_sub(fe25519 *r, const fe25519 *x, const fe25519 *y)
-{
- int i;
- crypto_uint32 t[32];
- t[0] = x->v[0] + 0x1da;
- t[31] = x->v[31] + 0xfe;
- for(i=1;i<31;i++) t[i] = x->v[i] + 0x1fe;
- for(i=0;i<32;i++) r->v[i] = t[i] - y->v[i];
- reduce_add_sub(r);
-}
-
-void fe25519_mul(fe25519 *r, const fe25519 *x, const fe25519 *y)
-{
- int i,j;
- crypto_uint32 t[63];
- for(i=0;i<63;i++)t[i] = 0;
-
- for(i=0;i<32;i++)
- for(j=0;j<32;j++)
- t[i+j] += x->v[i] * y->v[j];
-
- for(i=32;i<63;i++)
- r->v[i-32] = t[i-32] + times38(t[i]);
- r->v[31] = t[31]; /* result now in r[0]...r[31] */
-
- reduce_mul(r);
-}
-
-void fe25519_square(fe25519 *r, const fe25519 *x)
-{
- fe25519_mul(r, x, x);
-}
-
-void fe25519_invert(fe25519 *r, const fe25519 *x)
-{
- fe25519 z2;
- fe25519 z9;
- fe25519 z11;
- fe25519 z2_5_0;
- fe25519 z2_10_0;
- fe25519 z2_20_0;
- fe25519 z2_50_0;
- fe25519 z2_100_0;
- fe25519 t0;
- fe25519 t1;
- int i;
-
- /* 2 */ fe25519_square(&z2,x);
- /* 4 */ fe25519_square(&t1,&z2);
- /* 8 */ fe25519_square(&t0,&t1);
- /* 9 */ fe25519_mul(&z9,&t0,x);
- /* 11 */ fe25519_mul(&z11,&z9,&z2);
- /* 22 */ fe25519_square(&t0,&z11);
- /* 2^5 - 2^0 = 31 */ fe25519_mul(&z2_5_0,&t0,&z9);
-
- /* 2^6 - 2^1 */ fe25519_square(&t0,&z2_5_0);
- /* 2^7 - 2^2 */ fe25519_square(&t1,&t0);
- /* 2^8 - 2^3 */ fe25519_square(&t0,&t1);
- /* 2^9 - 2^4 */ fe25519_square(&t1,&t0);
- /* 2^10 - 2^5 */ fe25519_square(&t0,&t1);
- /* 2^10 - 2^0 */ fe25519_mul(&z2_10_0,&t0,&z2_5_0);
-
- /* 2^11 - 2^1 */ fe25519_square(&t0,&z2_10_0);
- /* 2^12 - 2^2 */ fe25519_square(&t1,&t0);
- /* 2^20 - 2^10 */ for (i = 2;i < 10;i += 2) { fe25519_square(&t0,&t1); fe25519_square(&t1,&t0); }
- /* 2^20 - 2^0 */ fe25519_mul(&z2_20_0,&t1,&z2_10_0);
-
- /* 2^21 - 2^1 */ fe25519_square(&t0,&z2_20_0);
- /* 2^22 - 2^2 */ fe25519_square(&t1,&t0);
- /* 2^40 - 2^20 */ for (i = 2;i < 20;i += 2) { fe25519_square(&t0,&t1); fe25519_square(&t1,&t0); }
- /* 2^40 - 2^0 */ fe25519_mul(&t0,&t1,&z2_20_0);
-
- /* 2^41 - 2^1 */ fe25519_square(&t1,&t0);
- /* 2^42 - 2^2 */ fe25519_square(&t0,&t1);
- /* 2^50 - 2^10 */ for (i = 2;i < 10;i += 2) { fe25519_square(&t1,&t0); fe25519_square(&t0,&t1); }
- /* 2^50 - 2^0 */ fe25519_mul(&z2_50_0,&t0,&z2_10_0);
-
- /* 2^51 - 2^1 */ fe25519_square(&t0,&z2_50_0);
- /* 2^52 - 2^2 */ fe25519_square(&t1,&t0);
- /* 2^100 - 2^50 */ for (i = 2;i < 50;i += 2) { fe25519_square(&t0,&t1); fe25519_square(&t1,&t0); }
- /* 2^100 - 2^0 */ fe25519_mul(&z2_100_0,&t1,&z2_50_0);
-
- /* 2^101 - 2^1 */ fe25519_square(&t1,&z2_100_0);
- /* 2^102 - 2^2 */ fe25519_square(&t0,&t1);
- /* 2^200 - 2^100 */ for (i = 2;i < 100;i += 2) { fe25519_square(&t1,&t0); fe25519_square(&t0,&t1); }
- /* 2^200 - 2^0 */ fe25519_mul(&t1,&t0,&z2_100_0);
-
- /* 2^201 - 2^1 */ fe25519_square(&t0,&t1);
- /* 2^202 - 2^2 */ fe25519_square(&t1,&t0);
- /* 2^250 - 2^50 */ for (i = 2;i < 50;i += 2) { fe25519_square(&t0,&t1); fe25519_square(&t1,&t0); }
- /* 2^250 - 2^0 */ fe25519_mul(&t0,&t1,&z2_50_0);
-
- /* 2^251 - 2^1 */ fe25519_square(&t1,&t0);
- /* 2^252 - 2^2 */ fe25519_square(&t0,&t1);
- /* 2^253 - 2^3 */ fe25519_square(&t1,&t0);
- /* 2^254 - 2^4 */ fe25519_square(&t0,&t1);
- /* 2^255 - 2^5 */ fe25519_square(&t1,&t0);
- /* 2^255 - 21 */ fe25519_mul(r,&t1,&z11);
-}
-
-void fe25519_pow2523(fe25519 *r, const fe25519 *x)
-{
- fe25519 z2;
- fe25519 z9;
- fe25519 z11;
- fe25519 z2_5_0;
- fe25519 z2_10_0;
- fe25519 z2_20_0;
- fe25519 z2_50_0;
- fe25519 z2_100_0;
- fe25519 t;
- int i;
-
- /* 2 */ fe25519_square(&z2,x);
- /* 4 */ fe25519_square(&t,&z2);
- /* 8 */ fe25519_square(&t,&t);
- /* 9 */ fe25519_mul(&z9,&t,x);
- /* 11 */ fe25519_mul(&z11,&z9,&z2);
- /* 22 */ fe25519_square(&t,&z11);
- /* 2^5 - 2^0 = 31 */ fe25519_mul(&z2_5_0,&t,&z9);
-
- /* 2^6 - 2^1 */ fe25519_square(&t,&z2_5_0);
- /* 2^10 - 2^5 */ for (i = 1;i < 5;i++) { fe25519_square(&t,&t); }
- /* 2^10 - 2^0 */ fe25519_mul(&z2_10_0,&t,&z2_5_0);
-
- /* 2^11 - 2^1 */ fe25519_square(&t,&z2_10_0);
- /* 2^20 - 2^10 */ for (i = 1;i < 10;i++) { fe25519_square(&t,&t); }
- /* 2^20 - 2^0 */ fe25519_mul(&z2_20_0,&t,&z2_10_0);
-
- /* 2^21 - 2^1 */ fe25519_square(&t,&z2_20_0);
- /* 2^40 - 2^20 */ for (i = 1;i < 20;i++) { fe25519_square(&t,&t); }
- /* 2^40 - 2^0 */ fe25519_mul(&t,&t,&z2_20_0);
-
- /* 2^41 - 2^1 */ fe25519_square(&t,&t);
- /* 2^50 - 2^10 */ for (i = 1;i < 10;i++) { fe25519_square(&t,&t); }
- /* 2^50 - 2^0 */ fe25519_mul(&z2_50_0,&t,&z2_10_0);
-
- /* 2^51 - 2^1 */ fe25519_square(&t,&z2_50_0);
- /* 2^100 - 2^50 */ for (i = 1;i < 50;i++) { fe25519_square(&t,&t); }
- /* 2^100 - 2^0 */ fe25519_mul(&z2_100_0,&t,&z2_50_0);
-
- /* 2^101 - 2^1 */ fe25519_square(&t,&z2_100_0);
- /* 2^200 - 2^100 */ for (i = 1;i < 100;i++) { fe25519_square(&t,&t); }
- /* 2^200 - 2^0 */ fe25519_mul(&t,&t,&z2_100_0);
-
- /* 2^201 - 2^1 */ fe25519_square(&t,&t);
- /* 2^250 - 2^50 */ for (i = 1;i < 50;i++) { fe25519_square(&t,&t); }
- /* 2^250 - 2^0 */ fe25519_mul(&t,&t,&z2_50_0);
-
- /* 2^251 - 2^1 */ fe25519_square(&t,&t);
- /* 2^252 - 2^2 */ fe25519_square(&t,&t);
- /* 2^252 - 3 */ fe25519_mul(r,&t,x);
-}
diff --git a/crypto/openssh/fe25519.h b/crypto/openssh/fe25519.h
deleted file mode 100644
index 41b3cbb49dc6..000000000000
--- a/crypto/openssh/fe25519.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/* $OpenBSD: fe25519.h,v 1.3 2013/12/09 11:03:45 markus Exp $ */
-
-/*
- * Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange,
- * Peter Schwabe, Bo-Yin Yang.
- * Copied from supercop-20130419/crypto_sign/ed25519/ref/fe25519.h
- */
-
-#ifndef FE25519_H
-#define FE25519_H
-
-#include "crypto_api.h"
-
-#define fe25519 crypto_sign_ed25519_ref_fe25519
-#define fe25519_freeze crypto_sign_ed25519_ref_fe25519_freeze
-#define fe25519_unpack crypto_sign_ed25519_ref_fe25519_unpack
-#define fe25519_pack crypto_sign_ed25519_ref_fe25519_pack
-#define fe25519_iszero crypto_sign_ed25519_ref_fe25519_iszero
-#define fe25519_iseq_vartime crypto_sign_ed25519_ref_fe25519_iseq_vartime
-#define fe25519_cmov crypto_sign_ed25519_ref_fe25519_cmov
-#define fe25519_setone crypto_sign_ed25519_ref_fe25519_setone
-#define fe25519_setzero crypto_sign_ed25519_ref_fe25519_setzero
-#define fe25519_neg crypto_sign_ed25519_ref_fe25519_neg
-#define fe25519_getparity crypto_sign_ed25519_ref_fe25519_getparity
-#define fe25519_add crypto_sign_ed25519_ref_fe25519_add
-#define fe25519_sub crypto_sign_ed25519_ref_fe25519_sub
-#define fe25519_mul crypto_sign_ed25519_ref_fe25519_mul
-#define fe25519_square crypto_sign_ed25519_ref_fe25519_square
-#define fe25519_invert crypto_sign_ed25519_ref_fe25519_invert
-#define fe25519_pow2523 crypto_sign_ed25519_ref_fe25519_pow2523
-
-typedef struct
-{
- crypto_uint32 v[32];
-}
-fe25519;
-
-void fe25519_freeze(fe25519 *r);
-
-void fe25519_unpack(fe25519 *r, const unsigned char x[32]);
-
-void fe25519_pack(unsigned char r[32], const fe25519 *x);
-
-int fe25519_iszero(const fe25519 *x);
-
-int fe25519_iseq_vartime(const fe25519 *x, const fe25519 *y);
-
-void fe25519_cmov(fe25519 *r, const fe25519 *x, unsigned char b);
-
-void fe25519_setone(fe25519 *r);
-
-void fe25519_setzero(fe25519 *r);
-
-void fe25519_neg(fe25519 *r, const fe25519 *x);
-
-unsigned char fe25519_getparity(const fe25519 *x);
-
-void fe25519_add(fe25519 *r, const fe25519 *x, const fe25519 *y);
-
-void fe25519_sub(fe25519 *r, const fe25519 *x, const fe25519 *y);
-
-void fe25519_mul(fe25519 *r, const fe25519 *x, const fe25519 *y);
-
-void fe25519_square(fe25519 *r, const fe25519 *x);
-
-void fe25519_invert(fe25519 *r, const fe25519 *x);
-
-void fe25519_pow2523(fe25519 *r, const fe25519 *x);
-
-#endif
diff --git a/crypto/openssh/ge25519.c b/crypto/openssh/ge25519.c
deleted file mode 100644
index dfe3849b931b..000000000000
--- a/crypto/openssh/ge25519.c
+++ /dev/null
@@ -1,321 +0,0 @@
-/* $OpenBSD: ge25519.c,v 1.3 2013/12/09 11:03:45 markus Exp $ */
-
-/*
- * Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange,
- * Peter Schwabe, Bo-Yin Yang.
- * Copied from supercop-20130419/crypto_sign/ed25519/ref/ge25519.c
- */
-
-#include "includes.h"
-
-#include "fe25519.h"
-#include "sc25519.h"
-#include "ge25519.h"
-
-/*
- * Arithmetic on the twisted Edwards curve -x^2 + y^2 = 1 + dx^2y^2
- * with d = -(121665/121666) = 37095705934669439343138083508754565189542113879843219016388785533085940283555
- * Base point: (15112221349535400772501151409588531511454012693041857206046113283949847762202,46316835694926478169428394003475163141307993866256225615783033603165251855960);
- */
-
-/* d */
-static const fe25519 ge25519_ecd = {{0xA3, 0x78, 0x59, 0x13, 0xCA, 0x4D, 0xEB, 0x75, 0xAB, 0xD8, 0x41, 0x41, 0x4D, 0x0A, 0x70, 0x00,
- 0x98, 0xE8, 0x79, 0x77, 0x79, 0x40, 0xC7, 0x8C, 0x73, 0xFE, 0x6F, 0x2B, 0xEE, 0x6C, 0x03, 0x52}};
-/* 2*d */
-static const fe25519 ge25519_ec2d = {{0x59, 0xF1, 0xB2, 0x26, 0x94, 0x9B, 0xD6, 0xEB, 0x56, 0xB1, 0x83, 0x82, 0x9A, 0x14, 0xE0, 0x00,
- 0x30, 0xD1, 0xF3, 0xEE, 0xF2, 0x80, 0x8E, 0x19, 0xE7, 0xFC, 0xDF, 0x56, 0xDC, 0xD9, 0x06, 0x24}};
-/* sqrt(-1) */
-static const fe25519 ge25519_sqrtm1 = {{0xB0, 0xA0, 0x0E, 0x4A, 0x27, 0x1B, 0xEE, 0xC4, 0x78, 0xE4, 0x2F, 0xAD, 0x06, 0x18, 0x43, 0x2F,
- 0xA7, 0xD7, 0xFB, 0x3D, 0x99, 0x00, 0x4D, 0x2B, 0x0B, 0xDF, 0xC1, 0x4F, 0x80, 0x24, 0x83, 0x2B}};
-
-#define ge25519_p3 ge25519
-
-typedef struct
-{
- fe25519 x;
- fe25519 z;
- fe25519 y;
- fe25519 t;
-} ge25519_p1p1;
-
-typedef struct
-{
- fe25519 x;
- fe25519 y;
- fe25519 z;
-} ge25519_p2;
-
-typedef struct
-{
- fe25519 x;
- fe25519 y;
-} ge25519_aff;
-
-
-/* Packed coordinates of the base point */
-const ge25519 ge25519_base = {{{0x1A, 0xD5, 0x25, 0x8F, 0x60, 0x2D, 0x56, 0xC9, 0xB2, 0xA7, 0x25, 0x95, 0x60, 0xC7, 0x2C, 0x69,
- 0x5C, 0xDC, 0xD6, 0xFD, 0x31, 0xE2, 0xA4, 0xC0, 0xFE, 0x53, 0x6E, 0xCD, 0xD3, 0x36, 0x69, 0x21}},
- {{0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
- 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0xA3, 0xDD, 0xB7, 0xA5, 0xB3, 0x8A, 0xDE, 0x6D, 0xF5, 0x52, 0x51, 0x77, 0x80, 0x9F, 0xF0, 0x20,
- 0x7D, 0xE3, 0xAB, 0x64, 0x8E, 0x4E, 0xEA, 0x66, 0x65, 0x76, 0x8B, 0xD7, 0x0F, 0x5F, 0x87, 0x67}}};
-
-/* Multiples of the base point in affine representation */
-static const ge25519_aff ge25519_base_multiples_affine[425] = {
-#include "ge25519_base.data"
-};
-
-static void p1p1_to_p2(ge25519_p2 *r, const ge25519_p1p1 *p)
-{
- fe25519_mul(&r->x, &p->x, &p->t);
- fe25519_mul(&r->y, &p->y, &p->z);
- fe25519_mul(&r->z, &p->z, &p->t);
-}
-
-static void p1p1_to_p3(ge25519_p3 *r, const ge25519_p1p1 *p)
-{
- p1p1_to_p2((ge25519_p2 *)r, p);
- fe25519_mul(&r->t, &p->x, &p->y);
-}
-
-static void ge25519_mixadd2(ge25519_p3 *r, const ge25519_aff *q)
-{
- fe25519 a,b,t1,t2,c,d,e,f,g,h,qt;
- fe25519_mul(&qt, &q->x, &q->y);
- fe25519_sub(&a, &r->y, &r->x); /* A = (Y1-X1)*(Y2-X2) */
- fe25519_add(&b, &r->y, &r->x); /* B = (Y1+X1)*(Y2+X2) */
- fe25519_sub(&t1, &q->y, &q->x);
- fe25519_add(&t2, &q->y, &q->x);
- fe25519_mul(&a, &a, &t1);
- fe25519_mul(&b, &b, &t2);
- fe25519_sub(&e, &b, &a); /* E = B-A */
- fe25519_add(&h, &b, &a); /* H = B+A */
- fe25519_mul(&c, &r->t, &qt); /* C = T1*k*T2 */
- fe25519_mul(&c, &c, &ge25519_ec2d);
- fe25519_add(&d, &r->z, &r->z); /* D = Z1*2 */
- fe25519_sub(&f, &d, &c); /* F = D-C */
- fe25519_add(&g, &d, &c); /* G = D+C */
- fe25519_mul(&r->x, &e, &f);
- fe25519_mul(&r->y, &h, &g);
- fe25519_mul(&r->z, &g, &f);
- fe25519_mul(&r->t, &e, &h);
-}
-
-static void add_p1p1(ge25519_p1p1 *r, const ge25519_p3 *p, const ge25519_p3 *q)
-{
- fe25519 a, b, c, d, t;
-
- fe25519_sub(&a, &p->y, &p->x); /* A = (Y1-X1)*(Y2-X2) */
- fe25519_sub(&t, &q->y, &q->x);
- fe25519_mul(&a, &a, &t);
- fe25519_add(&b, &p->x, &p->y); /* B = (Y1+X1)*(Y2+X2) */
- fe25519_add(&t, &q->x, &q->y);
- fe25519_mul(&b, &b, &t);
- fe25519_mul(&c, &p->t, &q->t); /* C = T1*k*T2 */
- fe25519_mul(&c, &c, &ge25519_ec2d);
- fe25519_mul(&d, &p->z, &q->z); /* D = Z1*2*Z2 */
- fe25519_add(&d, &d, &d);
- fe25519_sub(&r->x, &b, &a); /* E = B-A */
- fe25519_sub(&r->t, &d, &c); /* F = D-C */
- fe25519_add(&r->z, &d, &c); /* G = D+C */
- fe25519_add(&r->y, &b, &a); /* H = B+A */
-}
-
-/* See http://www.hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html#doubling-dbl-2008-hwcd */
-static void dbl_p1p1(ge25519_p1p1 *r, const ge25519_p2 *p)
-{
- fe25519 a,b,c,d;
- fe25519_square(&a, &p->x);
- fe25519_square(&b, &p->y);
- fe25519_square(&c, &p->z);
- fe25519_add(&c, &c, &c);
- fe25519_neg(&d, &a);
-
- fe25519_add(&r->x, &p->x, &p->y);
- fe25519_square(&r->x, &r->x);
- fe25519_sub(&r->x, &r->x, &a);
- fe25519_sub(&r->x, &r->x, &b);
- fe25519_add(&r->z, &d, &b);
- fe25519_sub(&r->t, &r->z, &c);
- fe25519_sub(&r->y, &d, &b);
-}
-
-/* Constant-time version of: if(b) r = p */
-static void cmov_aff(ge25519_aff *r, const ge25519_aff *p, unsigned char b)
-{
- fe25519_cmov(&r->x, &p->x, b);
- fe25519_cmov(&r->y, &p->y, b);
-}
-
-static unsigned char equal(signed char b,signed char c)
-{
- unsigned char ub = b;
- unsigned char uc = c;
- unsigned char x = ub ^ uc; /* 0: yes; 1..255: no */
- crypto_uint32 y = x; /* 0: yes; 1..255: no */
- y -= 1; /* 4294967295: yes; 0..254: no */
- y >>= 31; /* 1: yes; 0: no */
- return y;
-}
-
-static unsigned char negative(signed char b)
-{
- unsigned long long x = b; /* 18446744073709551361..18446744073709551615: yes; 0..255: no */
- x >>= 63; /* 1: yes; 0: no */
- return x;
-}
-
-static void choose_t(ge25519_aff *t, unsigned long long pos, signed char b)
-{
- /* constant time */
- fe25519 v;
- *t = ge25519_base_multiples_affine[5*pos+0];
- cmov_aff(t, &ge25519_base_multiples_affine[5*pos+1],equal(b,1) | equal(b,-1));
- cmov_aff(t, &ge25519_base_multiples_affine[5*pos+2],equal(b,2) | equal(b,-2));
- cmov_aff(t, &ge25519_base_multiples_affine[5*pos+3],equal(b,3) | equal(b,-3));
- cmov_aff(t, &ge25519_base_multiples_affine[5*pos+4],equal(b,-4));
- fe25519_neg(&v, &t->x);
- fe25519_cmov(&t->x, &v, negative(b));
-}
-
-static void setneutral(ge25519 *r)
-{
- fe25519_setzero(&r->x);
- fe25519_setone(&r->y);
- fe25519_setone(&r->z);
- fe25519_setzero(&r->t);
-}
-
-/* ********************************************************************
- * EXPORTED FUNCTIONS
- ******************************************************************** */
-
-/* return 0 on success, -1 otherwise */
-int ge25519_unpackneg_vartime(ge25519_p3 *r, const unsigned char p[32])
-{
- unsigned char par;
- fe25519 t, chk, num, den, den2, den4, den6;
- fe25519_setone(&r->z);
- par = p[31] >> 7;
- fe25519_unpack(&r->y, p);
- fe25519_square(&num, &r->y); /* x = y^2 */
- fe25519_mul(&den, &num, &ge25519_ecd); /* den = dy^2 */
- fe25519_sub(&num, &num, &r->z); /* x = y^2-1 */
- fe25519_add(&den, &r->z, &den); /* den = dy^2+1 */
-
- /* Computation of sqrt(num/den) */
- /* 1.: computation of num^((p-5)/8)*den^((7p-35)/8) = (num*den^7)^((p-5)/8) */
- fe25519_square(&den2, &den);
- fe25519_square(&den4, &den2);
- fe25519_mul(&den6, &den4, &den2);
- fe25519_mul(&t, &den6, &num);
- fe25519_mul(&t, &t, &den);
-
- fe25519_pow2523(&t, &t);
- /* 2. computation of r->x = t * num * den^3 */
- fe25519_mul(&t, &t, &num);
- fe25519_mul(&t, &t, &den);
- fe25519_mul(&t, &t, &den);
- fe25519_mul(&r->x, &t, &den);
-
- /* 3. Check whether sqrt computation gave correct result, multiply by sqrt(-1) if not: */
- fe25519_square(&chk, &r->x);
- fe25519_mul(&chk, &chk, &den);
- if (!fe25519_iseq_vartime(&chk, &num))
- fe25519_mul(&r->x, &r->x, &ge25519_sqrtm1);
-
- /* 4. Now we have one of the two square roots, except if input was not a square */
- fe25519_square(&chk, &r->x);
- fe25519_mul(&chk, &chk, &den);
- if (!fe25519_iseq_vartime(&chk, &num))
- return -1;
-
- /* 5. Choose the desired square root according to parity: */
- if(fe25519_getparity(&r->x) != (1-par))
- fe25519_neg(&r->x, &r->x);
-
- fe25519_mul(&r->t, &r->x, &r->y);
- return 0;
-}
-
-void ge25519_pack(unsigned char r[32], const ge25519_p3 *p)
-{
- fe25519 tx, ty, zi;
- fe25519_invert(&zi, &p->z);
- fe25519_mul(&tx, &p->x, &zi);
- fe25519_mul(&ty, &p->y, &zi);
- fe25519_pack(r, &ty);
- r[31] ^= fe25519_getparity(&tx) << 7;
-}
-
-int ge25519_isneutral_vartime(const ge25519_p3 *p)
-{
- int ret = 1;
- if(!fe25519_iszero(&p->x)) ret = 0;
- if(!fe25519_iseq_vartime(&p->y, &p->z)) ret = 0;
- return ret;
-}
-
-/* computes [s1]p1 + [s2]p2 */
-void ge25519_double_scalarmult_vartime(ge25519_p3 *r, const ge25519_p3 *p1, const sc25519 *s1, const ge25519_p3 *p2, const sc25519 *s2)
-{
- ge25519_p1p1 tp1p1;
- ge25519_p3 pre[16];
- unsigned char b[127];
- int i;
-
- /* precomputation s2 s1 */
- setneutral(pre); /* 00 00 */
- pre[1] = *p1; /* 00 01 */
- dbl_p1p1(&tp1p1,(ge25519_p2 *)p1); p1p1_to_p3( &pre[2], &tp1p1); /* 00 10 */
- add_p1p1(&tp1p1,&pre[1], &pre[2]); p1p1_to_p3( &pre[3], &tp1p1); /* 00 11 */
- pre[4] = *p2; /* 01 00 */
- add_p1p1(&tp1p1,&pre[1], &pre[4]); p1p1_to_p3( &pre[5], &tp1p1); /* 01 01 */
- add_p1p1(&tp1p1,&pre[2], &pre[4]); p1p1_to_p3( &pre[6], &tp1p1); /* 01 10 */
- add_p1p1(&tp1p1,&pre[3], &pre[4]); p1p1_to_p3( &pre[7], &tp1p1); /* 01 11 */
- dbl_p1p1(&tp1p1,(ge25519_p2 *)p2); p1p1_to_p3( &pre[8], &tp1p1); /* 10 00 */
- add_p1p1(&tp1p1,&pre[1], &pre[8]); p1p1_to_p3( &pre[9], &tp1p1); /* 10 01 */
- dbl_p1p1(&tp1p1,(ge25519_p2 *)&pre[5]); p1p1_to_p3(&pre[10], &tp1p1); /* 10 10 */
- add_p1p1(&tp1p1,&pre[3], &pre[8]); p1p1_to_p3(&pre[11], &tp1p1); /* 10 11 */
- add_p1p1(&tp1p1,&pre[4], &pre[8]); p1p1_to_p3(&pre[12], &tp1p1); /* 11 00 */
- add_p1p1(&tp1p1,&pre[1],&pre[12]); p1p1_to_p3(&pre[13], &tp1p1); /* 11 01 */
- add_p1p1(&tp1p1,&pre[2],&pre[12]); p1p1_to_p3(&pre[14], &tp1p1); /* 11 10 */
- add_p1p1(&tp1p1,&pre[3],&pre[12]); p1p1_to_p3(&pre[15], &tp1p1); /* 11 11 */
-
- sc25519_2interleave2(b,s1,s2);
-
- /* scalar multiplication */
- *r = pre[b[126]];
- for(i=125;i>=0;i--)
- {
- dbl_p1p1(&tp1p1, (ge25519_p2 *)r);
- p1p1_to_p2((ge25519_p2 *) r, &tp1p1);
- dbl_p1p1(&tp1p1, (ge25519_p2 *)r);
- if(b[i]!=0)
- {
- p1p1_to_p3(r, &tp1p1);
- add_p1p1(&tp1p1, r, &pre[b[i]]);
- }
- if(i != 0) p1p1_to_p2((ge25519_p2 *)r, &tp1p1);
- else p1p1_to_p3(r, &tp1p1);
- }
-}
-
-void ge25519_scalarmult_base(ge25519_p3 *r, const sc25519 *s)
-{
- signed char b[85];
- int i;
- ge25519_aff t;
- sc25519_window3(b,s);
-
- choose_t((ge25519_aff *)r, 0, b[0]);
- fe25519_setone(&r->z);
- fe25519_mul(&r->t, &r->x, &r->y);
- for(i=1;i<85;i++)
- {
- choose_t(&t, (unsigned long long) i, b[i]);
- ge25519_mixadd2(r, &t);
- }
-}
diff --git a/crypto/openssh/ge25519.h b/crypto/openssh/ge25519.h
deleted file mode 100644
index a09763760931..000000000000
--- a/crypto/openssh/ge25519.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* $OpenBSD: ge25519.h,v 1.4 2015/02/16 18:26:26 miod Exp $ */
-
-/*
- * Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange,
- * Peter Schwabe, Bo-Yin Yang.
- * Copied from supercop-20130419/crypto_sign/ed25519/ref/ge25519.h
- */
-
-#ifndef GE25519_H
-#define GE25519_H
-
-#include "fe25519.h"
-#include "sc25519.h"
-
-#define ge25519 crypto_sign_ed25519_ref_ge25519
-#define ge25519_base crypto_sign_ed25519_ref_ge25519_base
-#define ge25519_unpackneg_vartime crypto_sign_ed25519_ref_unpackneg_vartime
-#define ge25519_pack crypto_sign_ed25519_ref_pack
-#define ge25519_isneutral_vartime crypto_sign_ed25519_ref_isneutral_vartime
-#define ge25519_double_scalarmult_vartime crypto_sign_ed25519_ref_double_scalarmult_vartime
-#define ge25519_scalarmult_base crypto_sign_ed25519_ref_scalarmult_base
-
-typedef struct
-{
- fe25519 x;
- fe25519 y;
- fe25519 z;
- fe25519 t;
-} ge25519;
-
-extern const ge25519 ge25519_base;
-
-int ge25519_unpackneg_vartime(ge25519 *r, const unsigned char p[32]);
-
-void ge25519_pack(unsigned char r[32], const ge25519 *p);
-
-int ge25519_isneutral_vartime(const ge25519 *p);
-
-void ge25519_double_scalarmult_vartime(ge25519 *r, const ge25519 *p1, const sc25519 *s1, const ge25519 *p2, const sc25519 *s2);
-
-void ge25519_scalarmult_base(ge25519 *r, const sc25519 *s);
-
-#endif
diff --git a/crypto/openssh/ge25519_base.data b/crypto/openssh/ge25519_base.data
deleted file mode 100644
index 66fb1b61c67d..000000000000
--- a/crypto/openssh/ge25519_base.data
+++ /dev/null
@@ -1,858 +0,0 @@
-/* $OpenBSD: ge25519_base.data,v 1.3 2013/12/09 11:03:45 markus Exp $ */
-
-/*
- * Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange,
- * Peter Schwabe, Bo-Yin Yang.
- * Copied from supercop-20130419/crypto_sign/ed25519/ref/ge25519_base.data
- */
-
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0x1a, 0xd5, 0x25, 0x8f, 0x60, 0x2d, 0x56, 0xc9, 0xb2, 0xa7, 0x25, 0x95, 0x60, 0xc7, 0x2c, 0x69, 0x5c, 0xdc, 0xd6, 0xfd, 0x31, 0xe2, 0xa4, 0xc0, 0xfe, 0x53, 0x6e, 0xcd, 0xd3, 0x36, 0x69, 0x21}} ,
- {{0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66}}},
-{{{0x0e, 0xce, 0x43, 0x28, 0x4e, 0xa1, 0xc5, 0x83, 0x5f, 0xa4, 0xd7, 0x15, 0x45, 0x8e, 0x0d, 0x08, 0xac, 0xe7, 0x33, 0x18, 0x7d, 0x3b, 0x04, 0x3d, 0x6c, 0x04, 0x5a, 0x9f, 0x4c, 0x38, 0xab, 0x36}} ,
- {{0xc9, 0xa3, 0xf8, 0x6a, 0xae, 0x46, 0x5f, 0x0e, 0x56, 0x51, 0x38, 0x64, 0x51, 0x0f, 0x39, 0x97, 0x56, 0x1f, 0xa2, 0xc9, 0xe8, 0x5e, 0xa2, 0x1d, 0xc2, 0x29, 0x23, 0x09, 0xf3, 0xcd, 0x60, 0x22}}},
-{{{0x5c, 0xe2, 0xf8, 0xd3, 0x5f, 0x48, 0x62, 0xac, 0x86, 0x48, 0x62, 0x81, 0x19, 0x98, 0x43, 0x63, 0x3a, 0xc8, 0xda, 0x3e, 0x74, 0xae, 0xf4, 0x1f, 0x49, 0x8f, 0x92, 0x22, 0x4a, 0x9c, 0xae, 0x67}} ,
- {{0xd4, 0xb4, 0xf5, 0x78, 0x48, 0x68, 0xc3, 0x02, 0x04, 0x03, 0x24, 0x67, 0x17, 0xec, 0x16, 0x9f, 0xf7, 0x9e, 0x26, 0x60, 0x8e, 0xa1, 0x26, 0xa1, 0xab, 0x69, 0xee, 0x77, 0xd1, 0xb1, 0x67, 0x12}}},
-{{{0x70, 0xf8, 0xc9, 0xc4, 0x57, 0xa6, 0x3a, 0x49, 0x47, 0x15, 0xce, 0x93, 0xc1, 0x9e, 0x73, 0x1a, 0xf9, 0x20, 0x35, 0x7a, 0xb8, 0xd4, 0x25, 0x83, 0x46, 0xf1, 0xcf, 0x56, 0xdb, 0xa8, 0x3d, 0x20}} ,
- {{0x2f, 0x11, 0x32, 0xca, 0x61, 0xab, 0x38, 0xdf, 0xf0, 0x0f, 0x2f, 0xea, 0x32, 0x28, 0xf2, 0x4c, 0x6c, 0x71, 0xd5, 0x80, 0x85, 0xb8, 0x0e, 0x47, 0xe1, 0x95, 0x15, 0xcb, 0x27, 0xe8, 0xd0, 0x47}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0xc8, 0x84, 0xa5, 0x08, 0xbc, 0xfd, 0x87, 0x3b, 0x99, 0x8b, 0x69, 0x80, 0x7b, 0xc6, 0x3a, 0xeb, 0x93, 0xcf, 0x4e, 0xf8, 0x5c, 0x2d, 0x86, 0x42, 0xb6, 0x71, 0xd7, 0x97, 0x5f, 0xe1, 0x42, 0x67}} ,
- {{0xb4, 0xb9, 0x37, 0xfc, 0xa9, 0x5b, 0x2f, 0x1e, 0x93, 0xe4, 0x1e, 0x62, 0xfc, 0x3c, 0x78, 0x81, 0x8f, 0xf3, 0x8a, 0x66, 0x09, 0x6f, 0xad, 0x6e, 0x79, 0x73, 0xe5, 0xc9, 0x00, 0x06, 0xd3, 0x21}}},
-{{{0xf8, 0xf9, 0x28, 0x6c, 0x6d, 0x59, 0xb2, 0x59, 0x74, 0x23, 0xbf, 0xe7, 0x33, 0x8d, 0x57, 0x09, 0x91, 0x9c, 0x24, 0x08, 0x15, 0x2b, 0xe2, 0xb8, 0xee, 0x3a, 0xe5, 0x27, 0x06, 0x86, 0xa4, 0x23}} ,
- {{0xeb, 0x27, 0x67, 0xc1, 0x37, 0xab, 0x7a, 0xd8, 0x27, 0x9c, 0x07, 0x8e, 0xff, 0x11, 0x6a, 0xb0, 0x78, 0x6e, 0xad, 0x3a, 0x2e, 0x0f, 0x98, 0x9f, 0x72, 0xc3, 0x7f, 0x82, 0xf2, 0x96, 0x96, 0x70}}},
-{{{0x81, 0x6b, 0x88, 0xe8, 0x1e, 0xc7, 0x77, 0x96, 0x0e, 0xa1, 0xa9, 0x52, 0xe0, 0xd8, 0x0e, 0x61, 0x9e, 0x79, 0x2d, 0x95, 0x9c, 0x8d, 0x96, 0xe0, 0x06, 0x40, 0x5d, 0x87, 0x28, 0x5f, 0x98, 0x70}} ,
- {{0xf1, 0x79, 0x7b, 0xed, 0x4f, 0x44, 0xb2, 0xe7, 0x08, 0x0d, 0xc2, 0x08, 0x12, 0xd2, 0x9f, 0xdf, 0xcd, 0x93, 0x20, 0x8a, 0xcf, 0x33, 0xca, 0x6d, 0x89, 0xb9, 0x77, 0xc8, 0x93, 0x1b, 0x4e, 0x60}}},
-{{{0x26, 0x4f, 0x7e, 0x97, 0xf6, 0x40, 0xdd, 0x4f, 0xfc, 0x52, 0x78, 0xf9, 0x90, 0x31, 0x03, 0xe6, 0x7d, 0x56, 0x39, 0x0b, 0x1d, 0x56, 0x82, 0x85, 0xf9, 0x1a, 0x42, 0x17, 0x69, 0x6c, 0xcf, 0x39}} ,
- {{0x69, 0xd2, 0x06, 0x3a, 0x4f, 0x39, 0x2d, 0xf9, 0x38, 0x40, 0x8c, 0x4c, 0xe7, 0x05, 0x12, 0xb4, 0x78, 0x8b, 0xf8, 0xc0, 0xec, 0x93, 0xde, 0x7a, 0x6b, 0xce, 0x2c, 0xe1, 0x0e, 0xa9, 0x34, 0x44}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0x0b, 0xa4, 0x3c, 0xb0, 0x0f, 0x7a, 0x51, 0xf1, 0x78, 0xd6, 0xd9, 0x6a, 0xfd, 0x46, 0xe8, 0xb8, 0xa8, 0x79, 0x1d, 0x87, 0xf9, 0x90, 0xf2, 0x9c, 0x13, 0x29, 0xf8, 0x0b, 0x20, 0x64, 0xfa, 0x05}} ,
- {{0x26, 0x09, 0xda, 0x17, 0xaf, 0x95, 0xd6, 0xfb, 0x6a, 0x19, 0x0d, 0x6e, 0x5e, 0x12, 0xf1, 0x99, 0x4c, 0xaa, 0xa8, 0x6f, 0x79, 0x86, 0xf4, 0x72, 0x28, 0x00, 0x26, 0xf9, 0xea, 0x9e, 0x19, 0x3d}}},
-{{{0x87, 0xdd, 0xcf, 0xf0, 0x5b, 0x49, 0xa2, 0x5d, 0x40, 0x7a, 0x23, 0x26, 0xa4, 0x7a, 0x83, 0x8a, 0xb7, 0x8b, 0xd2, 0x1a, 0xbf, 0xea, 0x02, 0x24, 0x08, 0x5f, 0x7b, 0xa9, 0xb1, 0xbe, 0x9d, 0x37}} ,
- {{0xfc, 0x86, 0x4b, 0x08, 0xee, 0xe7, 0xa0, 0xfd, 0x21, 0x45, 0x09, 0x34, 0xc1, 0x61, 0x32, 0x23, 0xfc, 0x9b, 0x55, 0x48, 0x53, 0x99, 0xf7, 0x63, 0xd0, 0x99, 0xce, 0x01, 0xe0, 0x9f, 0xeb, 0x28}}},
-{{{0x47, 0xfc, 0xab, 0x5a, 0x17, 0xf0, 0x85, 0x56, 0x3a, 0x30, 0x86, 0x20, 0x28, 0x4b, 0x8e, 0x44, 0x74, 0x3a, 0x6e, 0x02, 0xf1, 0x32, 0x8f, 0x9f, 0x3f, 0x08, 0x35, 0xe9, 0xca, 0x16, 0x5f, 0x6e}} ,
- {{0x1c, 0x59, 0x1c, 0x65, 0x5d, 0x34, 0xa4, 0x09, 0xcd, 0x13, 0x9c, 0x70, 0x7d, 0xb1, 0x2a, 0xc5, 0x88, 0xaf, 0x0b, 0x60, 0xc7, 0x9f, 0x34, 0x8d, 0xd6, 0xb7, 0x7f, 0xea, 0x78, 0x65, 0x8d, 0x77}}},
-{{{0x56, 0xa5, 0xc2, 0x0c, 0xdd, 0xbc, 0xb8, 0x20, 0x6d, 0x57, 0x61, 0xb5, 0xfb, 0x78, 0xb5, 0xd4, 0x49, 0x54, 0x90, 0x26, 0xc1, 0xcb, 0xe9, 0xe6, 0xbf, 0xec, 0x1d, 0x4e, 0xed, 0x07, 0x7e, 0x5e}} ,
- {{0xc7, 0xf6, 0x6c, 0x56, 0x31, 0x20, 0x14, 0x0e, 0xa8, 0xd9, 0x27, 0xc1, 0x9a, 0x3d, 0x1b, 0x7d, 0x0e, 0x26, 0xd3, 0x81, 0xaa, 0xeb, 0xf5, 0x6b, 0x79, 0x02, 0xf1, 0x51, 0x5c, 0x75, 0x55, 0x0f}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0x0a, 0x34, 0xcd, 0x82, 0x3c, 0x33, 0x09, 0x54, 0xd2, 0x61, 0x39, 0x30, 0x9b, 0xfd, 0xef, 0x21, 0x26, 0xd4, 0x70, 0xfa, 0xee, 0xf9, 0x31, 0x33, 0x73, 0x84, 0xd0, 0xb3, 0x81, 0xbf, 0xec, 0x2e}} ,
- {{0xe8, 0x93, 0x8b, 0x00, 0x64, 0xf7, 0x9c, 0xb8, 0x74, 0xe0, 0xe6, 0x49, 0x48, 0x4d, 0x4d, 0x48, 0xb6, 0x19, 0xa1, 0x40, 0xb7, 0xd9, 0x32, 0x41, 0x7c, 0x82, 0x37, 0xa1, 0x2d, 0xdc, 0xd2, 0x54}}},
-{{{0x68, 0x2b, 0x4a, 0x5b, 0xd5, 0xc7, 0x51, 0x91, 0x1d, 0xe1, 0x2a, 0x4b, 0xc4, 0x47, 0xf1, 0xbc, 0x7a, 0xb3, 0xcb, 0xc8, 0xb6, 0x7c, 0xac, 0x90, 0x05, 0xfd, 0xf3, 0xf9, 0x52, 0x3a, 0x11, 0x6b}} ,
- {{0x3d, 0xc1, 0x27, 0xf3, 0x59, 0x43, 0x95, 0x90, 0xc5, 0x96, 0x79, 0xf5, 0xf4, 0x95, 0x65, 0x29, 0x06, 0x9c, 0x51, 0x05, 0x18, 0xda, 0xb8, 0x2e, 0x79, 0x7e, 0x69, 0x59, 0x71, 0x01, 0xeb, 0x1a}}},
-{{{0x15, 0x06, 0x49, 0xb6, 0x8a, 0x3c, 0xea, 0x2f, 0x34, 0x20, 0x14, 0xc3, 0xaa, 0xd6, 0xaf, 0x2c, 0x3e, 0xbd, 0x65, 0x20, 0xe2, 0x4d, 0x4b, 0x3b, 0xeb, 0x9f, 0x4a, 0xc3, 0xad, 0xa4, 0x3b, 0x60}} ,
- {{0xbc, 0x58, 0xe6, 0xc0, 0x95, 0x2a, 0x2a, 0x81, 0x9a, 0x7a, 0xf3, 0xd2, 0x06, 0xbe, 0x48, 0xbc, 0x0c, 0xc5, 0x46, 0xe0, 0x6a, 0xd4, 0xac, 0x0f, 0xd9, 0xcc, 0x82, 0x34, 0x2c, 0xaf, 0xdb, 0x1f}}},
-{{{0xf7, 0x17, 0x13, 0xbd, 0xfb, 0xbc, 0xd2, 0xec, 0x45, 0xb3, 0x15, 0x31, 0xe9, 0xaf, 0x82, 0x84, 0x3d, 0x28, 0xc6, 0xfc, 0x11, 0xf5, 0x41, 0xb5, 0x8b, 0xd3, 0x12, 0x76, 0x52, 0xe7, 0x1a, 0x3c}} ,
- {{0x4e, 0x36, 0x11, 0x07, 0xa2, 0x15, 0x20, 0x51, 0xc4, 0x2a, 0xc3, 0x62, 0x8b, 0x5e, 0x7f, 0xa6, 0x0f, 0xf9, 0x45, 0x85, 0x6c, 0x11, 0x86, 0xb7, 0x7e, 0xe5, 0xd7, 0xf9, 0xc3, 0x91, 0x1c, 0x05}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0xea, 0xd6, 0xde, 0x29, 0x3a, 0x00, 0xb9, 0x02, 0x59, 0xcb, 0x26, 0xc4, 0xba, 0x99, 0xb1, 0x97, 0x2f, 0x8e, 0x00, 0x92, 0x26, 0x4f, 0x52, 0xeb, 0x47, 0x1b, 0x89, 0x8b, 0x24, 0xc0, 0x13, 0x7d}} ,
- {{0xd5, 0x20, 0x5b, 0x80, 0xa6, 0x80, 0x20, 0x95, 0xc3, 0xe9, 0x9f, 0x8e, 0x87, 0x9e, 0x1e, 0x9e, 0x7a, 0xc7, 0xcc, 0x75, 0x6c, 0xa5, 0xf1, 0x91, 0x1a, 0xa8, 0x01, 0x2c, 0xab, 0x76, 0xa9, 0x59}}},
-{{{0xde, 0xc9, 0xb1, 0x31, 0x10, 0x16, 0xaa, 0x35, 0x14, 0x6a, 0xd4, 0xb5, 0x34, 0x82, 0x71, 0xd2, 0x4a, 0x5d, 0x9a, 0x1f, 0x53, 0x26, 0x3c, 0xe5, 0x8e, 0x8d, 0x33, 0x7f, 0xff, 0xa9, 0xd5, 0x17}} ,
- {{0x89, 0xaf, 0xf6, 0xa4, 0x64, 0xd5, 0x10, 0xe0, 0x1d, 0xad, 0xef, 0x44, 0xbd, 0xda, 0x83, 0xac, 0x7a, 0xa8, 0xf0, 0x1c, 0x07, 0xf9, 0xc3, 0x43, 0x6c, 0x3f, 0xb7, 0xd3, 0x87, 0x22, 0x02, 0x73}}},
-{{{0x64, 0x1d, 0x49, 0x13, 0x2f, 0x71, 0xec, 0x69, 0x87, 0xd0, 0x42, 0xee, 0x13, 0xec, 0xe3, 0xed, 0x56, 0x7b, 0xbf, 0xbd, 0x8c, 0x2f, 0x7d, 0x7b, 0x9d, 0x28, 0xec, 0x8e, 0x76, 0x2f, 0x6f, 0x08}} ,
- {{0x22, 0xf5, 0x5f, 0x4d, 0x15, 0xef, 0xfc, 0x4e, 0x57, 0x03, 0x36, 0x89, 0xf0, 0xeb, 0x5b, 0x91, 0xd6, 0xe2, 0xca, 0x01, 0xa5, 0xee, 0x52, 0xec, 0xa0, 0x3c, 0x8f, 0x33, 0x90, 0x5a, 0x94, 0x72}}},
-{{{0x8a, 0x4b, 0xe7, 0x38, 0xbc, 0xda, 0xc2, 0xb0, 0x85, 0xe1, 0x4a, 0xfe, 0x2d, 0x44, 0x84, 0xcb, 0x20, 0x6b, 0x2d, 0xbf, 0x11, 0x9c, 0xd7, 0xbe, 0xd3, 0x3e, 0x5f, 0xbf, 0x68, 0xbc, 0xa8, 0x07}} ,
- {{0x01, 0x89, 0x28, 0x22, 0x6a, 0x78, 0xaa, 0x29, 0x03, 0xc8, 0x74, 0x95, 0x03, 0x3e, 0xdc, 0xbd, 0x07, 0x13, 0xa8, 0xa2, 0x20, 0x2d, 0xb3, 0x18, 0x70, 0x42, 0xfd, 0x7a, 0xc4, 0xd7, 0x49, 0x72}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0x02, 0xff, 0x32, 0x2b, 0x5c, 0x93, 0x54, 0x32, 0xe8, 0x57, 0x54, 0x1a, 0x8b, 0x33, 0x60, 0x65, 0xd3, 0x67, 0xa4, 0xc1, 0x26, 0xc4, 0xa4, 0x34, 0x1f, 0x9b, 0xa7, 0xa9, 0xf4, 0xd9, 0x4f, 0x5b}} ,
- {{0x46, 0x8d, 0xb0, 0x33, 0x54, 0x26, 0x5b, 0x68, 0xdf, 0xbb, 0xc5, 0xec, 0xc2, 0xf9, 0x3c, 0x5a, 0x37, 0xc1, 0x8e, 0x27, 0x47, 0xaa, 0x49, 0x5a, 0xf8, 0xfb, 0x68, 0x04, 0x23, 0xd1, 0xeb, 0x40}}},
-{{{0x65, 0xa5, 0x11, 0x84, 0x8a, 0x67, 0x9d, 0x9e, 0xd1, 0x44, 0x68, 0x7a, 0x34, 0xe1, 0x9f, 0xa3, 0x54, 0xcd, 0x07, 0xca, 0x79, 0x1f, 0x54, 0x2f, 0x13, 0x70, 0x4e, 0xee, 0xa2, 0xfa, 0xe7, 0x5d}} ,
- {{0x36, 0xec, 0x54, 0xf8, 0xce, 0xe4, 0x85, 0xdf, 0xf6, 0x6f, 0x1d, 0x90, 0x08, 0xbc, 0xe8, 0xc0, 0x92, 0x2d, 0x43, 0x6b, 0x92, 0xa9, 0x8e, 0xab, 0x0a, 0x2e, 0x1c, 0x1e, 0x64, 0x23, 0x9f, 0x2c}}},
-{{{0xa7, 0xd6, 0x2e, 0xd5, 0xcc, 0xd4, 0xcb, 0x5a, 0x3b, 0xa7, 0xf9, 0x46, 0x03, 0x1d, 0xad, 0x2b, 0x34, 0x31, 0x90, 0x00, 0x46, 0x08, 0x82, 0x14, 0xc4, 0xe0, 0x9c, 0xf0, 0xe3, 0x55, 0x43, 0x31}} ,
- {{0x60, 0xd6, 0xdd, 0x78, 0xe6, 0xd4, 0x22, 0x42, 0x1f, 0x00, 0xf9, 0xb1, 0x6a, 0x63, 0xe2, 0x92, 0x59, 0xd1, 0x1a, 0xb7, 0x00, 0x54, 0x29, 0xc9, 0xc1, 0xf6, 0x6f, 0x7a, 0xc5, 0x3c, 0x5f, 0x65}}},
-{{{0x27, 0x4f, 0xd0, 0x72, 0xb1, 0x11, 0x14, 0x27, 0x15, 0x94, 0x48, 0x81, 0x7e, 0x74, 0xd8, 0x32, 0xd5, 0xd1, 0x11, 0x28, 0x60, 0x63, 0x36, 0x32, 0x37, 0xb5, 0x13, 0x1c, 0xa0, 0x37, 0xe3, 0x74}} ,
- {{0xf1, 0x25, 0x4e, 0x11, 0x96, 0x67, 0xe6, 0x1c, 0xc2, 0xb2, 0x53, 0xe2, 0xda, 0x85, 0xee, 0xb2, 0x9f, 0x59, 0xf3, 0xba, 0xbd, 0xfa, 0xcf, 0x6e, 0xf9, 0xda, 0xa4, 0xb3, 0x02, 0x8f, 0x64, 0x08}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0x34, 0x94, 0xf2, 0x64, 0x54, 0x47, 0x37, 0x07, 0x40, 0x8a, 0x20, 0xba, 0x4a, 0x55, 0xd7, 0x3f, 0x47, 0xba, 0x25, 0x23, 0x14, 0xb0, 0x2c, 0xe8, 0x55, 0xa8, 0xa6, 0xef, 0x51, 0xbd, 0x6f, 0x6a}} ,
- {{0x71, 0xd6, 0x16, 0x76, 0xb2, 0x06, 0xea, 0x79, 0xf5, 0xc4, 0xc3, 0x52, 0x7e, 0x61, 0xd1, 0xe1, 0xad, 0x70, 0x78, 0x1d, 0x16, 0x11, 0xf8, 0x7c, 0x2b, 0xfc, 0x55, 0x9f, 0x52, 0xf8, 0xf5, 0x16}}},
-{{{0x34, 0x96, 0x9a, 0xf6, 0xc5, 0xe0, 0x14, 0x03, 0x24, 0x0e, 0x4c, 0xad, 0x9e, 0x9a, 0x70, 0x23, 0x96, 0xb2, 0xf1, 0x2e, 0x9d, 0xc3, 0x32, 0x9b, 0x54, 0xa5, 0x73, 0xde, 0x88, 0xb1, 0x3e, 0x24}} ,
- {{0xf6, 0xe2, 0x4c, 0x1f, 0x5b, 0xb2, 0xaf, 0x82, 0xa5, 0xcf, 0x81, 0x10, 0x04, 0xef, 0xdb, 0xa2, 0xcc, 0x24, 0xb2, 0x7e, 0x0b, 0x7a, 0xeb, 0x01, 0xd8, 0x52, 0xf4, 0x51, 0x89, 0x29, 0x79, 0x37}}},
-{{{0x74, 0xde, 0x12, 0xf3, 0x68, 0xb7, 0x66, 0xc3, 0xee, 0x68, 0xdc, 0x81, 0xb5, 0x55, 0x99, 0xab, 0xd9, 0x28, 0x63, 0x6d, 0x8b, 0x40, 0x69, 0x75, 0x6c, 0xcd, 0x5c, 0x2a, 0x7e, 0x32, 0x7b, 0x29}} ,
- {{0x02, 0xcc, 0x22, 0x74, 0x4d, 0x19, 0x07, 0xc0, 0xda, 0xb5, 0x76, 0x51, 0x2a, 0xaa, 0xa6, 0x0a, 0x5f, 0x26, 0xd4, 0xbc, 0xaf, 0x48, 0x88, 0x7f, 0x02, 0xbc, 0xf2, 0xe1, 0xcf, 0xe9, 0xdd, 0x15}}},
-{{{0xed, 0xb5, 0x9a, 0x8c, 0x9a, 0xdd, 0x27, 0xf4, 0x7f, 0x47, 0xd9, 0x52, 0xa7, 0xcd, 0x65, 0xa5, 0x31, 0x22, 0xed, 0xa6, 0x63, 0x5b, 0x80, 0x4a, 0xad, 0x4d, 0xed, 0xbf, 0xee, 0x49, 0xb3, 0x06}} ,
- {{0xf8, 0x64, 0x8b, 0x60, 0x90, 0xe9, 0xde, 0x44, 0x77, 0xb9, 0x07, 0x36, 0x32, 0xc2, 0x50, 0xf5, 0x65, 0xdf, 0x48, 0x4c, 0x37, 0xaa, 0x68, 0xab, 0x9a, 0x1f, 0x3e, 0xff, 0x89, 0x92, 0xa0, 0x07}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0x7d, 0x4f, 0x9c, 0x19, 0xc0, 0x4a, 0x31, 0xec, 0xf9, 0xaa, 0xeb, 0xb2, 0x16, 0x9c, 0xa3, 0x66, 0x5f, 0xd1, 0xd4, 0xed, 0xb8, 0x92, 0x1c, 0xab, 0xda, 0xea, 0xd9, 0x57, 0xdf, 0x4c, 0x2a, 0x48}} ,
- {{0x4b, 0xb0, 0x4e, 0x6e, 0x11, 0x3b, 0x51, 0xbd, 0x6a, 0xfd, 0xe4, 0x25, 0xa5, 0x5f, 0x11, 0x3f, 0x98, 0x92, 0x51, 0x14, 0xc6, 0x5f, 0x3c, 0x0b, 0xa8, 0xf7, 0xc2, 0x81, 0x43, 0xde, 0x91, 0x73}}},
-{{{0x3c, 0x8f, 0x9f, 0x33, 0x2a, 0x1f, 0x43, 0x33, 0x8f, 0x68, 0xff, 0x1f, 0x3d, 0x73, 0x6b, 0xbf, 0x68, 0xcc, 0x7d, 0x13, 0x6c, 0x24, 0x4b, 0xcc, 0x4d, 0x24, 0x0d, 0xfe, 0xde, 0x86, 0xad, 0x3b}} ,
- {{0x79, 0x51, 0x81, 0x01, 0xdc, 0x73, 0x53, 0xe0, 0x6e, 0x9b, 0xea, 0x68, 0x3f, 0x5c, 0x14, 0x84, 0x53, 0x8d, 0x4b, 0xc0, 0x9f, 0x9f, 0x89, 0x2b, 0x8c, 0xba, 0x86, 0xfa, 0xf2, 0xcd, 0xe3, 0x2d}}},
-{{{0x06, 0xf9, 0x29, 0x5a, 0xdb, 0x3d, 0x84, 0x52, 0xab, 0xcc, 0x6b, 0x60, 0x9d, 0xb7, 0x4a, 0x0e, 0x36, 0x63, 0x91, 0xad, 0xa0, 0x95, 0xb0, 0x97, 0x89, 0x4e, 0xcf, 0x7d, 0x3c, 0xe5, 0x7c, 0x28}} ,
- {{0x2e, 0x69, 0x98, 0xfd, 0xc6, 0xbd, 0xcc, 0xca, 0xdf, 0x9a, 0x44, 0x7e, 0x9d, 0xca, 0x89, 0x6d, 0xbf, 0x27, 0xc2, 0xf8, 0xcd, 0x46, 0x00, 0x2b, 0xb5, 0x58, 0x4e, 0xb7, 0x89, 0x09, 0xe9, 0x2d}}},
-{{{0x54, 0xbe, 0x75, 0xcb, 0x05, 0xb0, 0x54, 0xb7, 0xe7, 0x26, 0x86, 0x4a, 0xfc, 0x19, 0xcf, 0x27, 0x46, 0xd4, 0x22, 0x96, 0x5a, 0x11, 0xe8, 0xd5, 0x1b, 0xed, 0x71, 0xc5, 0x5d, 0xc8, 0xaf, 0x45}} ,
- {{0x40, 0x7b, 0x77, 0x57, 0x49, 0x9e, 0x80, 0x39, 0x23, 0xee, 0x81, 0x0b, 0x22, 0xcf, 0xdb, 0x7a, 0x2f, 0x14, 0xb8, 0x57, 0x8f, 0xa1, 0x39, 0x1e, 0x77, 0xfc, 0x0b, 0xa6, 0xbf, 0x8a, 0x0c, 0x6c}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0x77, 0x3a, 0xd4, 0xd8, 0x27, 0xcf, 0xe8, 0xa1, 0x72, 0x9d, 0xca, 0xdd, 0x0d, 0x96, 0xda, 0x79, 0xed, 0x56, 0x42, 0x15, 0x60, 0xc7, 0x1c, 0x6b, 0x26, 0x30, 0xf6, 0x6a, 0x95, 0x67, 0xf3, 0x0a}} ,
- {{0xc5, 0x08, 0xa4, 0x2b, 0x2f, 0xbd, 0x31, 0x81, 0x2a, 0xa6, 0xb6, 0xe4, 0x00, 0x91, 0xda, 0x3d, 0xb2, 0xb0, 0x96, 0xce, 0x8a, 0xd2, 0x8d, 0x70, 0xb3, 0xd3, 0x34, 0x01, 0x90, 0x8d, 0x10, 0x21}}},
-{{{0x33, 0x0d, 0xe7, 0xba, 0x4f, 0x07, 0xdf, 0x8d, 0xea, 0x7d, 0xa0, 0xc5, 0xd6, 0xb1, 0xb0, 0xe5, 0x57, 0x1b, 0x5b, 0xf5, 0x45, 0x13, 0x14, 0x64, 0x5a, 0xeb, 0x5c, 0xfc, 0x54, 0x01, 0x76, 0x2b}} ,
- {{0x02, 0x0c, 0xc2, 0xaf, 0x96, 0x36, 0xfe, 0x4a, 0xe2, 0x54, 0x20, 0x6a, 0xeb, 0xb2, 0x9f, 0x62, 0xd7, 0xce, 0xa2, 0x3f, 0x20, 0x11, 0x34, 0x37, 0xe0, 0x42, 0xed, 0x6f, 0xf9, 0x1a, 0xc8, 0x7d}}},
-{{{0xd8, 0xb9, 0x11, 0xe8, 0x36, 0x3f, 0x42, 0xc1, 0xca, 0xdc, 0xd3, 0xf1, 0xc8, 0x23, 0x3d, 0x4f, 0x51, 0x7b, 0x9d, 0x8d, 0xd8, 0xe4, 0xa0, 0xaa, 0xf3, 0x04, 0xd6, 0x11, 0x93, 0xc8, 0x35, 0x45}} ,
- {{0x61, 0x36, 0xd6, 0x08, 0x90, 0xbf, 0xa7, 0x7a, 0x97, 0x6c, 0x0f, 0x84, 0xd5, 0x33, 0x2d, 0x37, 0xc9, 0x6a, 0x80, 0x90, 0x3d, 0x0a, 0xa2, 0xaa, 0xe1, 0xb8, 0x84, 0xba, 0x61, 0x36, 0xdd, 0x69}}},
-{{{0x6b, 0xdb, 0x5b, 0x9c, 0xc6, 0x92, 0xbc, 0x23, 0xaf, 0xc5, 0xb8, 0x75, 0xf8, 0x42, 0xfa, 0xd6, 0xb6, 0x84, 0x94, 0x63, 0x98, 0x93, 0x48, 0x78, 0x38, 0xcd, 0xbb, 0x18, 0x34, 0xc3, 0xdb, 0x67}} ,
- {{0x96, 0xf3, 0x3a, 0x09, 0x56, 0xb0, 0x6f, 0x7c, 0x51, 0x1e, 0x1b, 0x39, 0x48, 0xea, 0xc9, 0x0c, 0x25, 0xa2, 0x7a, 0xca, 0xe7, 0x92, 0xfc, 0x59, 0x30, 0xa3, 0x89, 0x85, 0xdf, 0x6f, 0x43, 0x38}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0x79, 0x84, 0x44, 0x19, 0xbd, 0xe9, 0x54, 0xc4, 0xc0, 0x6e, 0x2a, 0xa8, 0xa8, 0x9b, 0x43, 0xd5, 0x71, 0x22, 0x5f, 0xdc, 0x01, 0xfa, 0xdf, 0xb3, 0xb8, 0x47, 0x4b, 0x0a, 0xa5, 0x44, 0xea, 0x29}} ,
- {{0x05, 0x90, 0x50, 0xaf, 0x63, 0x5f, 0x9d, 0x9e, 0xe1, 0x9d, 0x38, 0x97, 0x1f, 0x6c, 0xac, 0x30, 0x46, 0xb2, 0x6a, 0x19, 0xd1, 0x4b, 0xdb, 0xbb, 0x8c, 0xda, 0x2e, 0xab, 0xc8, 0x5a, 0x77, 0x6c}}},
-{{{0x2b, 0xbe, 0xaf, 0xa1, 0x6d, 0x2f, 0x0b, 0xb1, 0x8f, 0xe3, 0xe0, 0x38, 0xcd, 0x0b, 0x41, 0x1b, 0x4a, 0x15, 0x07, 0xf3, 0x6f, 0xdc, 0xb8, 0xe9, 0xde, 0xb2, 0xa3, 0x40, 0x01, 0xa6, 0x45, 0x1e}} ,
- {{0x76, 0x0a, 0xda, 0x8d, 0x2c, 0x07, 0x3f, 0x89, 0x7d, 0x04, 0xad, 0x43, 0x50, 0x6e, 0xd2, 0x47, 0xcb, 0x8a, 0xe6, 0x85, 0x1a, 0x24, 0xf3, 0xd2, 0x60, 0xfd, 0xdf, 0x73, 0xa4, 0x0d, 0x73, 0x0e}}},
-{{{0xfd, 0x67, 0x6b, 0x71, 0x9b, 0x81, 0x53, 0x39, 0x39, 0xf4, 0xb8, 0xd5, 0xc3, 0x30, 0x9b, 0x3b, 0x7c, 0xa3, 0xf0, 0xd0, 0x84, 0x21, 0xd6, 0xbf, 0xb7, 0x4c, 0x87, 0x13, 0x45, 0x2d, 0xa7, 0x55}} ,
- {{0x5d, 0x04, 0xb3, 0x40, 0x28, 0x95, 0x2d, 0x30, 0x83, 0xec, 0x5e, 0xe4, 0xff, 0x75, 0xfe, 0x79, 0x26, 0x9d, 0x1d, 0x36, 0xcd, 0x0a, 0x15, 0xd2, 0x24, 0x14, 0x77, 0x71, 0xd7, 0x8a, 0x1b, 0x04}}},
-{{{0x5d, 0x93, 0xc9, 0xbe, 0xaa, 0x90, 0xcd, 0x9b, 0xfb, 0x73, 0x7e, 0xb0, 0x64, 0x98, 0x57, 0x44, 0x42, 0x41, 0xb1, 0xaf, 0xea, 0xc1, 0xc3, 0x22, 0xff, 0x60, 0x46, 0xcb, 0x61, 0x81, 0x70, 0x61}} ,
- {{0x0d, 0x82, 0xb9, 0xfe, 0x21, 0xcd, 0xc4, 0xf5, 0x98, 0x0c, 0x4e, 0x72, 0xee, 0x87, 0x49, 0xf8, 0xa1, 0x95, 0xdf, 0x8f, 0x2d, 0xbd, 0x21, 0x06, 0x7c, 0x15, 0xe8, 0x12, 0x6d, 0x93, 0xd6, 0x38}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0x91, 0xf7, 0x51, 0xd9, 0xef, 0x7d, 0x42, 0x01, 0x13, 0xe9, 0xb8, 0x7f, 0xa6, 0x49, 0x17, 0x64, 0x21, 0x80, 0x83, 0x2c, 0x63, 0x4c, 0x60, 0x09, 0x59, 0x91, 0x92, 0x77, 0x39, 0x51, 0xf4, 0x48}} ,
- {{0x60, 0xd5, 0x22, 0x83, 0x08, 0x2f, 0xff, 0x99, 0x3e, 0x69, 0x6d, 0x88, 0xda, 0xe7, 0x5b, 0x52, 0x26, 0x31, 0x2a, 0xe5, 0x89, 0xde, 0x68, 0x90, 0xb6, 0x22, 0x5a, 0xbd, 0xd3, 0x85, 0x53, 0x31}}},
-{{{0xd8, 0xce, 0xdc, 0xf9, 0x3c, 0x4b, 0xa2, 0x1d, 0x2c, 0x2f, 0x36, 0xbe, 0x7a, 0xfc, 0xcd, 0xbc, 0xdc, 0xf9, 0x30, 0xbd, 0xff, 0x05, 0xc7, 0xe4, 0x8e, 0x17, 0x62, 0xf8, 0x4d, 0xa0, 0x56, 0x79}} ,
- {{0x82, 0xe7, 0xf6, 0xba, 0x53, 0x84, 0x0a, 0xa3, 0x34, 0xff, 0x3c, 0xa3, 0x6a, 0xa1, 0x37, 0xea, 0xdd, 0xb6, 0x95, 0xb3, 0x78, 0x19, 0x76, 0x1e, 0x55, 0x2f, 0x77, 0x2e, 0x7f, 0xc1, 0xea, 0x5e}}},
-{{{0x83, 0xe1, 0x6e, 0xa9, 0x07, 0x33, 0x3e, 0x83, 0xff, 0xcb, 0x1c, 0x9f, 0xb1, 0xa3, 0xb4, 0xc9, 0xe1, 0x07, 0x97, 0xff, 0xf8, 0x23, 0x8f, 0xce, 0x40, 0xfd, 0x2e, 0x5e, 0xdb, 0x16, 0x43, 0x2d}} ,
- {{0xba, 0x38, 0x02, 0xf7, 0x81, 0x43, 0x83, 0xa3, 0x20, 0x4f, 0x01, 0x3b, 0x8a, 0x04, 0x38, 0x31, 0xc6, 0x0f, 0xc8, 0xdf, 0xd7, 0xfa, 0x2f, 0x88, 0x3f, 0xfc, 0x0c, 0x76, 0xc4, 0xa6, 0x45, 0x72}}},
-{{{0xbb, 0x0c, 0xbc, 0x6a, 0xa4, 0x97, 0x17, 0x93, 0x2d, 0x6f, 0xde, 0x72, 0x10, 0x1c, 0x08, 0x2c, 0x0f, 0x80, 0x32, 0x68, 0x27, 0xd4, 0xab, 0xdd, 0xc5, 0x58, 0x61, 0x13, 0x6d, 0x11, 0x1e, 0x4d}} ,
- {{0x1a, 0xb9, 0xc9, 0x10, 0xfb, 0x1e, 0x4e, 0xf4, 0x84, 0x4b, 0x8a, 0x5e, 0x7b, 0x4b, 0xe8, 0x43, 0x8c, 0x8f, 0x00, 0xb5, 0x54, 0x13, 0xc5, 0x5c, 0xb6, 0x35, 0x4e, 0x9d, 0xe4, 0x5b, 0x41, 0x6d}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0x15, 0x7d, 0x12, 0x48, 0x82, 0x14, 0x42, 0xcd, 0x32, 0xd4, 0x4b, 0xc1, 0x72, 0x61, 0x2a, 0x8c, 0xec, 0xe2, 0xf8, 0x24, 0x45, 0x94, 0xe3, 0xbe, 0xdd, 0x67, 0xa8, 0x77, 0x5a, 0xae, 0x5b, 0x4b}} ,
- {{0xcb, 0x77, 0x9a, 0x20, 0xde, 0xb8, 0x23, 0xd9, 0xa0, 0x0f, 0x8c, 0x7b, 0xa5, 0xcb, 0xae, 0xb6, 0xec, 0x42, 0x67, 0x0e, 0x58, 0xa4, 0x75, 0x98, 0x21, 0x71, 0x84, 0xb3, 0xe0, 0x76, 0x94, 0x73}}},
-{{{0xdf, 0xfc, 0x69, 0x28, 0x23, 0x3f, 0x5b, 0xf8, 0x3b, 0x24, 0x37, 0xf3, 0x1d, 0xd5, 0x22, 0x6b, 0xd0, 0x98, 0xa8, 0x6c, 0xcf, 0xff, 0x06, 0xe1, 0x13, 0xdf, 0xb9, 0xc1, 0x0c, 0xa9, 0xbf, 0x33}} ,
- {{0xd9, 0x81, 0xda, 0xb2, 0x4f, 0x82, 0x9d, 0x43, 0x81, 0x09, 0xf1, 0xd2, 0x01, 0xef, 0xac, 0xf4, 0x2d, 0x7d, 0x01, 0x09, 0xf1, 0xff, 0xa5, 0x9f, 0xe5, 0xca, 0x27, 0x63, 0xdb, 0x20, 0xb1, 0x53}}},
-{{{0x67, 0x02, 0xe8, 0xad, 0xa9, 0x34, 0xd4, 0xf0, 0x15, 0x81, 0xaa, 0xc7, 0x4d, 0x87, 0x94, 0xea, 0x75, 0xe7, 0x4c, 0x94, 0x04, 0x0e, 0x69, 0x87, 0xe7, 0x51, 0x91, 0x10, 0x03, 0xc7, 0xbe, 0x56}} ,
- {{0x32, 0xfb, 0x86, 0xec, 0x33, 0x6b, 0x2e, 0x51, 0x2b, 0xc8, 0xfa, 0x6c, 0x70, 0x47, 0x7e, 0xce, 0x05, 0x0c, 0x71, 0xf3, 0xb4, 0x56, 0xa6, 0xdc, 0xcc, 0x78, 0x07, 0x75, 0xd0, 0xdd, 0xb2, 0x6a}}},
-{{{0xc6, 0xef, 0xb9, 0xc0, 0x2b, 0x22, 0x08, 0x1e, 0x71, 0x70, 0xb3, 0x35, 0x9c, 0x7a, 0x01, 0x92, 0x44, 0x9a, 0xf6, 0xb0, 0x58, 0x95, 0xc1, 0x9b, 0x02, 0xed, 0x2d, 0x7c, 0x34, 0x29, 0x49, 0x44}} ,
- {{0x45, 0x62, 0x1d, 0x2e, 0xff, 0x2a, 0x1c, 0x21, 0xa4, 0x25, 0x7b, 0x0d, 0x8c, 0x15, 0x39, 0xfc, 0x8f, 0x7c, 0xa5, 0x7d, 0x1e, 0x25, 0xa3, 0x45, 0xd6, 0xab, 0xbd, 0xcb, 0xc5, 0x5e, 0x78, 0x77}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0xd0, 0xd3, 0x42, 0xed, 0x1d, 0x00, 0x3c, 0x15, 0x2c, 0x9c, 0x77, 0x81, 0xd2, 0x73, 0xd1, 0x06, 0xd5, 0xc4, 0x7f, 0x94, 0xbb, 0x92, 0x2d, 0x2c, 0x4b, 0x45, 0x4b, 0xe9, 0x2a, 0x89, 0x6b, 0x2b}} ,
- {{0xd2, 0x0c, 0x88, 0xc5, 0x48, 0x4d, 0xea, 0x0d, 0x4a, 0xc9, 0x52, 0x6a, 0x61, 0x79, 0xe9, 0x76, 0xf3, 0x85, 0x52, 0x5c, 0x1b, 0x2c, 0xe1, 0xd6, 0xc4, 0x0f, 0x18, 0x0e, 0x4e, 0xf6, 0x1c, 0x7f}}},
-{{{0xb4, 0x04, 0x2e, 0x42, 0xcb, 0x1f, 0x2b, 0x11, 0x51, 0x7b, 0x08, 0xac, 0xaa, 0x3e, 0x9e, 0x52, 0x60, 0xb7, 0xc2, 0x61, 0x57, 0x8c, 0x84, 0xd5, 0x18, 0xa6, 0x19, 0xfc, 0xb7, 0x75, 0x91, 0x1b}} ,
- {{0xe8, 0x68, 0xca, 0x44, 0xc8, 0x38, 0x38, 0xcc, 0x53, 0x0a, 0x32, 0x35, 0xcc, 0x52, 0xcb, 0x0e, 0xf7, 0xc5, 0xe7, 0xec, 0x3d, 0x85, 0xcc, 0x58, 0xe2, 0x17, 0x47, 0xff, 0x9f, 0xa5, 0x30, 0x17}}},
-{{{0xe3, 0xae, 0xc8, 0xc1, 0x71, 0x75, 0x31, 0x00, 0x37, 0x41, 0x5c, 0x0e, 0x39, 0xda, 0x73, 0xa0, 0xc7, 0x97, 0x36, 0x6c, 0x5b, 0xf2, 0xee, 0x64, 0x0a, 0x3d, 0x89, 0x1e, 0x1d, 0x49, 0x8c, 0x37}} ,
- {{0x4c, 0xe6, 0xb0, 0xc1, 0xa5, 0x2a, 0x82, 0x09, 0x08, 0xad, 0x79, 0x9c, 0x56, 0xf6, 0xf9, 0xc1, 0xd7, 0x7c, 0x39, 0x7f, 0x93, 0xca, 0x11, 0x55, 0xbf, 0x07, 0x1b, 0x82, 0x29, 0x69, 0x95, 0x5c}}},
-{{{0x87, 0xee, 0xa6, 0x56, 0x9e, 0xc2, 0x9a, 0x56, 0x24, 0x42, 0x85, 0x4d, 0x98, 0x31, 0x1e, 0x60, 0x4d, 0x87, 0x85, 0x04, 0xae, 0x46, 0x12, 0xf9, 0x8e, 0x7f, 0xe4, 0x7f, 0xf6, 0x1c, 0x37, 0x01}} ,
- {{0x73, 0x4c, 0xb6, 0xc5, 0xc4, 0xe9, 0x6c, 0x85, 0x48, 0x4a, 0x5a, 0xac, 0xd9, 0x1f, 0x43, 0xf8, 0x62, 0x5b, 0xee, 0x98, 0x2a, 0x33, 0x8e, 0x79, 0xce, 0x61, 0x06, 0x35, 0xd8, 0xd7, 0xca, 0x71}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0x72, 0xd3, 0xae, 0xa6, 0xca, 0x8f, 0xcd, 0xcc, 0x78, 0x8e, 0x19, 0x4d, 0xa7, 0xd2, 0x27, 0xe9, 0xa4, 0x3c, 0x16, 0x5b, 0x84, 0x80, 0xf9, 0xd0, 0xcc, 0x6a, 0x1e, 0xca, 0x1e, 0x67, 0xbd, 0x63}} ,
- {{0x7b, 0x6e, 0x2a, 0xd2, 0x87, 0x48, 0xff, 0xa1, 0xca, 0xe9, 0x15, 0x85, 0xdc, 0xdb, 0x2c, 0x39, 0x12, 0x91, 0xa9, 0x20, 0xaa, 0x4f, 0x29, 0xf4, 0x15, 0x7a, 0xd2, 0xf5, 0x32, 0xcc, 0x60, 0x04}}},
-{{{0xe5, 0x10, 0x47, 0x3b, 0xfa, 0x90, 0xfc, 0x30, 0xb5, 0xea, 0x6f, 0x56, 0x8f, 0xfb, 0x0e, 0xa7, 0x3b, 0xc8, 0xb2, 0xff, 0x02, 0x7a, 0x33, 0x94, 0x93, 0x2a, 0x03, 0xe0, 0x96, 0x3a, 0x6c, 0x0f}} ,
- {{0x5a, 0x63, 0x67, 0xe1, 0x9b, 0x47, 0x78, 0x9f, 0x38, 0x79, 0xac, 0x97, 0x66, 0x1d, 0x5e, 0x51, 0xee, 0x24, 0x42, 0xe8, 0x58, 0x4b, 0x8a, 0x03, 0x75, 0x86, 0x37, 0x86, 0xe2, 0x97, 0x4e, 0x3d}}},
-{{{0x3f, 0x75, 0x8e, 0xb4, 0xff, 0xd8, 0xdd, 0xd6, 0x37, 0x57, 0x9d, 0x6d, 0x3b, 0xbd, 0xd5, 0x60, 0x88, 0x65, 0x9a, 0xb9, 0x4a, 0x68, 0x84, 0xa2, 0x67, 0xdd, 0x17, 0x25, 0x97, 0x04, 0x8b, 0x5e}} ,
- {{0xbb, 0x40, 0x5e, 0xbc, 0x16, 0x92, 0x05, 0xc4, 0xc0, 0x4e, 0x72, 0x90, 0x0e, 0xab, 0xcf, 0x8a, 0xed, 0xef, 0xb9, 0x2d, 0x3b, 0xf8, 0x43, 0x5b, 0xba, 0x2d, 0xeb, 0x2f, 0x52, 0xd2, 0xd1, 0x5a}}},
-{{{0x40, 0xb4, 0xab, 0xe6, 0xad, 0x9f, 0x46, 0x69, 0x4a, 0xb3, 0x8e, 0xaa, 0xea, 0x9c, 0x8a, 0x20, 0x16, 0x5d, 0x8c, 0x13, 0xbd, 0xf6, 0x1d, 0xc5, 0x24, 0xbd, 0x90, 0x2a, 0x1c, 0xc7, 0x13, 0x3b}} ,
- {{0x54, 0xdc, 0x16, 0x0d, 0x18, 0xbe, 0x35, 0x64, 0x61, 0x52, 0x02, 0x80, 0xaf, 0x05, 0xf7, 0xa6, 0x42, 0xd3, 0x8f, 0x2e, 0x79, 0x26, 0xa8, 0xbb, 0xb2, 0x17, 0x48, 0xb2, 0x7a, 0x0a, 0x89, 0x14}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0x20, 0xa8, 0x88, 0xe3, 0x91, 0xc0, 0x6e, 0xbb, 0x8a, 0x27, 0x82, 0x51, 0x83, 0xb2, 0x28, 0xa9, 0x83, 0xeb, 0xa6, 0xa9, 0x4d, 0x17, 0x59, 0x22, 0x54, 0x00, 0x50, 0x45, 0xcb, 0x48, 0x4b, 0x18}} ,
- {{0x33, 0x7c, 0xe7, 0x26, 0xba, 0x4d, 0x32, 0xfe, 0x53, 0xf4, 0xfa, 0x83, 0xe3, 0xa5, 0x79, 0x66, 0x73, 0xef, 0x80, 0x23, 0x68, 0xc2, 0x60, 0xdd, 0xa9, 0x33, 0xdc, 0x03, 0x7a, 0xe0, 0xe0, 0x3e}}},
-{{{0x34, 0x5c, 0x13, 0xfb, 0xc0, 0xe3, 0x78, 0x2b, 0x54, 0x58, 0x22, 0x9b, 0x76, 0x81, 0x7f, 0x93, 0x9c, 0x25, 0x3c, 0xd2, 0xe9, 0x96, 0x21, 0x26, 0x08, 0xf5, 0xed, 0x95, 0x11, 0xae, 0x04, 0x5a}} ,
- {{0xb9, 0xe8, 0xc5, 0x12, 0x97, 0x1f, 0x83, 0xfe, 0x3e, 0x94, 0x99, 0xd4, 0x2d, 0xf9, 0x52, 0x59, 0x5c, 0x82, 0xa6, 0xf0, 0x75, 0x7e, 0xe8, 0xec, 0xcc, 0xac, 0x18, 0x21, 0x09, 0x67, 0x66, 0x67}}},
-{{{0xb3, 0x40, 0x29, 0xd1, 0xcb, 0x1b, 0x08, 0x9e, 0x9c, 0xb7, 0x53, 0xb9, 0x3b, 0x71, 0x08, 0x95, 0x12, 0x1a, 0x58, 0xaf, 0x7e, 0x82, 0x52, 0x43, 0x4f, 0x11, 0x39, 0xf4, 0x93, 0x1a, 0x26, 0x05}} ,
- {{0x6e, 0x44, 0xa3, 0xf9, 0x64, 0xaf, 0xe7, 0x6d, 0x7d, 0xdf, 0x1e, 0xac, 0x04, 0xea, 0x3b, 0x5f, 0x9b, 0xe8, 0x24, 0x9d, 0x0e, 0xe5, 0x2e, 0x3e, 0xdf, 0xa9, 0xf7, 0xd4, 0x50, 0x71, 0xf0, 0x78}}},
-{{{0x3e, 0xa8, 0x38, 0xc2, 0x57, 0x56, 0x42, 0x9a, 0xb1, 0xe2, 0xf8, 0x45, 0xaa, 0x11, 0x48, 0x5f, 0x17, 0xc4, 0x54, 0x27, 0xdc, 0x5d, 0xaa, 0xdd, 0x41, 0xbc, 0xdf, 0x81, 0xb9, 0x53, 0xee, 0x52}} ,
- {{0xc3, 0xf1, 0xa7, 0x6d, 0xb3, 0x5f, 0x92, 0x6f, 0xcc, 0x91, 0xb8, 0x95, 0x05, 0xdf, 0x3c, 0x64, 0x57, 0x39, 0x61, 0x51, 0xad, 0x8c, 0x38, 0x7b, 0xc8, 0xde, 0x00, 0x34, 0xbe, 0xa1, 0xb0, 0x7e}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0x25, 0x24, 0x1d, 0x8a, 0x67, 0x20, 0xee, 0x42, 0xeb, 0x38, 0xed, 0x0b, 0x8b, 0xcd, 0x46, 0x9d, 0x5e, 0x6b, 0x1e, 0x24, 0x9d, 0x12, 0x05, 0x1a, 0xcc, 0x05, 0x4e, 0x92, 0x38, 0xe1, 0x1f, 0x50}} ,
- {{0x4e, 0xee, 0x1c, 0x91, 0xe6, 0x11, 0xbd, 0x8e, 0x55, 0x1a, 0x18, 0x75, 0x66, 0xaf, 0x4d, 0x7b, 0x0f, 0xae, 0x6d, 0x85, 0xca, 0x82, 0x58, 0x21, 0x9c, 0x18, 0xe0, 0xed, 0xec, 0x22, 0x80, 0x2f}}},
-{{{0x68, 0x3b, 0x0a, 0x39, 0x1d, 0x6a, 0x15, 0x57, 0xfc, 0xf0, 0x63, 0x54, 0xdb, 0x39, 0xdb, 0xe8, 0x5c, 0x64, 0xff, 0xa0, 0x09, 0x4f, 0x3b, 0xb7, 0x32, 0x60, 0x99, 0x94, 0xfd, 0x94, 0x82, 0x2d}} ,
- {{0x24, 0xf6, 0x5a, 0x44, 0xf1, 0x55, 0x2c, 0xdb, 0xea, 0x7c, 0x84, 0x7c, 0x01, 0xac, 0xe3, 0xfd, 0xc9, 0x27, 0xc1, 0x5a, 0xb9, 0xde, 0x4f, 0x5a, 0x90, 0xdd, 0xc6, 0x67, 0xaa, 0x6f, 0x8a, 0x3a}}},
-{{{0x78, 0x52, 0x87, 0xc9, 0x97, 0x63, 0xb1, 0xdd, 0x54, 0x5f, 0xc1, 0xf8, 0xf1, 0x06, 0xa6, 0xa8, 0xa3, 0x88, 0x82, 0xd4, 0xcb, 0xa6, 0x19, 0xdd, 0xd1, 0x11, 0x87, 0x08, 0x17, 0x4c, 0x37, 0x2a}} ,
- {{0xa1, 0x0c, 0xf3, 0x08, 0x43, 0xd9, 0x24, 0x1e, 0x83, 0xa7, 0xdf, 0x91, 0xca, 0xbd, 0x69, 0x47, 0x8d, 0x1b, 0xe2, 0xb9, 0x4e, 0xb5, 0xe1, 0x76, 0xb3, 0x1c, 0x93, 0x03, 0xce, 0x5f, 0xb3, 0x5a}}},
-{{{0x1d, 0xda, 0xe4, 0x61, 0x03, 0x50, 0xa9, 0x8b, 0x68, 0x18, 0xef, 0xb2, 0x1c, 0x84, 0x3b, 0xa2, 0x44, 0x95, 0xa3, 0x04, 0x3b, 0xd6, 0x99, 0x00, 0xaf, 0x76, 0x42, 0x67, 0x02, 0x7d, 0x85, 0x56}} ,
- {{0xce, 0x72, 0x0e, 0x29, 0x84, 0xb2, 0x7d, 0xd2, 0x45, 0xbe, 0x57, 0x06, 0xed, 0x7f, 0xcf, 0xed, 0xcd, 0xef, 0x19, 0xd6, 0xbc, 0x15, 0x79, 0x64, 0xd2, 0x18, 0xe3, 0x20, 0x67, 0x3a, 0x54, 0x0b}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0x52, 0xfd, 0x04, 0xc5, 0xfb, 0x99, 0xe7, 0xe8, 0xfb, 0x8c, 0xe1, 0x42, 0x03, 0xef, 0x9d, 0xd9, 0x9e, 0x4d, 0xf7, 0x80, 0xcf, 0x2e, 0xcc, 0x9b, 0x45, 0xc9, 0x7b, 0x7a, 0xbc, 0x37, 0xa8, 0x52}} ,
- {{0x96, 0x11, 0x41, 0x8a, 0x47, 0x91, 0xfe, 0xb6, 0xda, 0x7a, 0x54, 0x63, 0xd1, 0x14, 0x35, 0x05, 0x86, 0x8c, 0xa9, 0x36, 0x3f, 0xf2, 0x85, 0x54, 0x4e, 0x92, 0xd8, 0x85, 0x01, 0x46, 0xd6, 0x50}}},
-{{{0x53, 0xcd, 0xf3, 0x86, 0x40, 0xe6, 0x39, 0x42, 0x95, 0xd6, 0xcb, 0x45, 0x1a, 0x20, 0xc8, 0x45, 0x4b, 0x32, 0x69, 0x04, 0xb1, 0xaf, 0x20, 0x46, 0xc7, 0x6b, 0x23, 0x5b, 0x69, 0xee, 0x30, 0x3f}} ,
- {{0x70, 0x83, 0x47, 0xc0, 0xdb, 0x55, 0x08, 0xa8, 0x7b, 0x18, 0x6d, 0xf5, 0x04, 0x5a, 0x20, 0x0c, 0x4a, 0x8c, 0x60, 0xae, 0xae, 0x0f, 0x64, 0x55, 0x55, 0x2e, 0xd5, 0x1d, 0x53, 0x31, 0x42, 0x41}}},
-{{{0xca, 0xfc, 0x88, 0x6b, 0x96, 0x78, 0x0a, 0x8b, 0x83, 0xdc, 0xbc, 0xaf, 0x40, 0xb6, 0x8d, 0x7f, 0xef, 0xb4, 0xd1, 0x3f, 0xcc, 0xa2, 0x74, 0xc9, 0xc2, 0x92, 0x55, 0x00, 0xab, 0xdb, 0xbf, 0x4f}} ,
- {{0x93, 0x1c, 0x06, 0x2d, 0x66, 0x65, 0x02, 0xa4, 0x97, 0x18, 0xfd, 0x00, 0xe7, 0xab, 0x03, 0xec, 0xce, 0xc1, 0xbf, 0x37, 0xf8, 0x13, 0x53, 0xa5, 0xe5, 0x0c, 0x3a, 0xa8, 0x55, 0xb9, 0xff, 0x68}}},
-{{{0xe4, 0xe6, 0x6d, 0x30, 0x7d, 0x30, 0x35, 0xc2, 0x78, 0x87, 0xf9, 0xfc, 0x6b, 0x5a, 0xc3, 0xb7, 0x65, 0xd8, 0x2e, 0xc7, 0xa5, 0x0c, 0xc6, 0xdc, 0x12, 0xaa, 0xd6, 0x4f, 0xc5, 0x38, 0xbc, 0x0e}} ,
- {{0xe2, 0x3c, 0x76, 0x86, 0x38, 0xf2, 0x7b, 0x2c, 0x16, 0x78, 0x8d, 0xf5, 0xa4, 0x15, 0xda, 0xdb, 0x26, 0x85, 0xa0, 0x56, 0xdd, 0x1d, 0xe3, 0xb3, 0xfd, 0x40, 0xef, 0xf2, 0xd9, 0xa1, 0xb3, 0x04}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0xdb, 0x49, 0x0e, 0xe6, 0x58, 0x10, 0x7a, 0x52, 0xda, 0xb5, 0x7d, 0x37, 0x6a, 0x3e, 0xa1, 0x78, 0xce, 0xc7, 0x1c, 0x24, 0x23, 0xdb, 0x7d, 0xfb, 0x8c, 0x8d, 0xdc, 0x30, 0x67, 0x69, 0x75, 0x3b}} ,
- {{0xa9, 0xea, 0x6d, 0x16, 0x16, 0x60, 0xf4, 0x60, 0x87, 0x19, 0x44, 0x8c, 0x4a, 0x8b, 0x3e, 0xfb, 0x16, 0x00, 0x00, 0x54, 0xa6, 0x9e, 0x9f, 0xef, 0xcf, 0xd9, 0xd2, 0x4c, 0x74, 0x31, 0xd0, 0x34}}},
-{{{0xa4, 0xeb, 0x04, 0xa4, 0x8c, 0x8f, 0x71, 0x27, 0x95, 0x85, 0x5d, 0x55, 0x4b, 0xb1, 0x26, 0x26, 0xc8, 0xae, 0x6a, 0x7d, 0xa2, 0x21, 0xca, 0xce, 0x38, 0xab, 0x0f, 0xd0, 0xd5, 0x2b, 0x6b, 0x00}} ,
- {{0xe5, 0x67, 0x0c, 0xf1, 0x3a, 0x9a, 0xea, 0x09, 0x39, 0xef, 0xd1, 0x30, 0xbc, 0x33, 0xba, 0xb1, 0x6a, 0xc5, 0x27, 0x08, 0x7f, 0x54, 0x80, 0x3d, 0xab, 0xf6, 0x15, 0x7a, 0xc2, 0x40, 0x73, 0x72}}},
-{{{0x84, 0x56, 0x82, 0xb6, 0x12, 0x70, 0x7f, 0xf7, 0xf0, 0xbd, 0x5b, 0xa9, 0xd5, 0xc5, 0x5f, 0x59, 0xbf, 0x7f, 0xb3, 0x55, 0x22, 0x02, 0xc9, 0x44, 0x55, 0x87, 0x8f, 0x96, 0x98, 0x64, 0x6d, 0x15}} ,
- {{0xb0, 0x8b, 0xaa, 0x1e, 0xec, 0xc7, 0xa5, 0x8f, 0x1f, 0x92, 0x04, 0xc6, 0x05, 0xf6, 0xdf, 0xa1, 0xcc, 0x1f, 0x81, 0xf5, 0x0e, 0x9c, 0x57, 0xdc, 0xe3, 0xbb, 0x06, 0x87, 0x1e, 0xfe, 0x23, 0x6c}}},
-{{{0xd8, 0x2b, 0x5b, 0x16, 0xea, 0x20, 0xf1, 0xd3, 0x68, 0x8f, 0xae, 0x5b, 0xd0, 0xa9, 0x1a, 0x19, 0xa8, 0x36, 0xfb, 0x2b, 0x57, 0x88, 0x7d, 0x90, 0xd5, 0xa6, 0xf3, 0xdc, 0x38, 0x89, 0x4e, 0x1f}} ,
- {{0xcc, 0x19, 0xda, 0x9b, 0x3b, 0x43, 0x48, 0x21, 0x2e, 0x23, 0x4d, 0x3d, 0xae, 0xf8, 0x8c, 0xfc, 0xdd, 0xa6, 0x74, 0x37, 0x65, 0xca, 0xee, 0x1a, 0x19, 0x8e, 0x9f, 0x64, 0x6f, 0x0c, 0x8b, 0x5a}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0x25, 0xb9, 0xc2, 0xf0, 0x72, 0xb8, 0x15, 0x16, 0xcc, 0x8d, 0x3c, 0x6f, 0x25, 0xed, 0xf4, 0x46, 0x2e, 0x0c, 0x60, 0x0f, 0xe2, 0x84, 0x34, 0x55, 0x89, 0x59, 0x34, 0x1b, 0xf5, 0x8d, 0xfe, 0x08}} ,
- {{0xf8, 0xab, 0x93, 0xbc, 0x44, 0xba, 0x1b, 0x75, 0x4b, 0x49, 0x6f, 0xd0, 0x54, 0x2e, 0x63, 0xba, 0xb5, 0xea, 0xed, 0x32, 0x14, 0xc9, 0x94, 0xd8, 0xc5, 0xce, 0xf4, 0x10, 0x68, 0xe0, 0x38, 0x27}}},
-{{{0x74, 0x1c, 0x14, 0x9b, 0xd4, 0x64, 0x61, 0x71, 0x5a, 0xb6, 0x21, 0x33, 0x4f, 0xf7, 0x8e, 0xba, 0xa5, 0x48, 0x9a, 0xc7, 0xfa, 0x9a, 0xf0, 0xb4, 0x62, 0xad, 0xf2, 0x5e, 0xcc, 0x03, 0x24, 0x1a}} ,
- {{0xf5, 0x76, 0xfd, 0xe4, 0xaf, 0xb9, 0x03, 0x59, 0xce, 0x63, 0xd2, 0x3b, 0x1f, 0xcd, 0x21, 0x0c, 0xad, 0x44, 0xa5, 0x97, 0xac, 0x80, 0x11, 0x02, 0x9b, 0x0c, 0xe5, 0x8b, 0xcd, 0xfb, 0x79, 0x77}}},
-{{{0x15, 0xbe, 0x9a, 0x0d, 0xba, 0x38, 0x72, 0x20, 0x8a, 0xf5, 0xbe, 0x59, 0x93, 0x79, 0xb7, 0xf6, 0x6a, 0x0c, 0x38, 0x27, 0x1a, 0x60, 0xf4, 0x86, 0x3b, 0xab, 0x5a, 0x00, 0xa0, 0xce, 0x21, 0x7d}} ,
- {{0x6c, 0xba, 0x14, 0xc5, 0xea, 0x12, 0x9e, 0x2e, 0x82, 0x63, 0xce, 0x9b, 0x4a, 0xe7, 0x1d, 0xec, 0xf1, 0x2e, 0x51, 0x1c, 0xf4, 0xd0, 0x69, 0x15, 0x42, 0x9d, 0xa3, 0x3f, 0x0e, 0xbf, 0xe9, 0x5c}}},
-{{{0xe4, 0x0d, 0xf4, 0xbd, 0xee, 0x31, 0x10, 0xed, 0xcb, 0x12, 0x86, 0xad, 0xd4, 0x2f, 0x90, 0x37, 0x32, 0xc3, 0x0b, 0x73, 0xec, 0x97, 0x85, 0xa4, 0x01, 0x1c, 0x76, 0x35, 0xfe, 0x75, 0xdd, 0x71}} ,
- {{0x11, 0xa4, 0x88, 0x9f, 0x3e, 0x53, 0x69, 0x3b, 0x1b, 0xe0, 0xf7, 0xba, 0x9b, 0xad, 0x4e, 0x81, 0x5f, 0xb5, 0x5c, 0xae, 0xbe, 0x67, 0x86, 0x37, 0x34, 0x8e, 0x07, 0x32, 0x45, 0x4a, 0x67, 0x39}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0x90, 0x70, 0x58, 0x20, 0x03, 0x1e, 0x67, 0xb2, 0xc8, 0x9b, 0x58, 0xc5, 0xb1, 0xeb, 0x2d, 0x4a, 0xde, 0x82, 0x8c, 0xf2, 0xd2, 0x14, 0xb8, 0x70, 0x61, 0x4e, 0x73, 0xd6, 0x0b, 0x6b, 0x0d, 0x30}} ,
- {{0x81, 0xfc, 0x55, 0x5c, 0xbf, 0xa7, 0xc4, 0xbd, 0xe2, 0xf0, 0x4b, 0x8f, 0xe9, 0x7d, 0x99, 0xfa, 0xd3, 0xab, 0xbc, 0xc7, 0x83, 0x2b, 0x04, 0x7f, 0x0c, 0x19, 0x43, 0x03, 0x3d, 0x07, 0xca, 0x40}}},
-{{{0xf9, 0xc8, 0xbe, 0x8c, 0x16, 0x81, 0x39, 0x96, 0xf6, 0x17, 0x58, 0xc8, 0x30, 0x58, 0xfb, 0xc2, 0x03, 0x45, 0xd2, 0x52, 0x76, 0xe0, 0x6a, 0x26, 0x28, 0x5c, 0x88, 0x59, 0x6a, 0x5a, 0x54, 0x42}} ,
- {{0x07, 0xb5, 0x2e, 0x2c, 0x67, 0x15, 0x9b, 0xfb, 0x83, 0x69, 0x1e, 0x0f, 0xda, 0xd6, 0x29, 0xb1, 0x60, 0xe0, 0xb2, 0xba, 0x69, 0xa2, 0x9e, 0xbd, 0xbd, 0xe0, 0x1c, 0xbd, 0xcd, 0x06, 0x64, 0x70}}},
-{{{0x41, 0xfa, 0x8c, 0xe1, 0x89, 0x8f, 0x27, 0xc8, 0x25, 0x8f, 0x6f, 0x5f, 0x55, 0xf8, 0xde, 0x95, 0x6d, 0x2f, 0x75, 0x16, 0x2b, 0x4e, 0x44, 0xfd, 0x86, 0x6e, 0xe9, 0x70, 0x39, 0x76, 0x97, 0x7e}} ,
- {{0x17, 0x62, 0x6b, 0x14, 0xa1, 0x7c, 0xd0, 0x79, 0x6e, 0xd8, 0x8a, 0xa5, 0x6d, 0x8c, 0x93, 0xd2, 0x3f, 0xec, 0x44, 0x8d, 0x6e, 0x91, 0x01, 0x8c, 0x8f, 0xee, 0x01, 0x8f, 0xc0, 0xb4, 0x85, 0x0e}}},
-{{{0x02, 0x3a, 0x70, 0x41, 0xe4, 0x11, 0x57, 0x23, 0xac, 0xe6, 0xfc, 0x54, 0x7e, 0xcd, 0xd7, 0x22, 0xcb, 0x76, 0x9f, 0x20, 0xce, 0xa0, 0x73, 0x76, 0x51, 0x3b, 0xa4, 0xf8, 0xe3, 0x62, 0x12, 0x6c}} ,
- {{0x7f, 0x00, 0x9c, 0x26, 0x0d, 0x6f, 0x48, 0x7f, 0x3a, 0x01, 0xed, 0xc5, 0x96, 0xb0, 0x1f, 0x4f, 0xa8, 0x02, 0x62, 0x27, 0x8a, 0x50, 0x8d, 0x9a, 0x8b, 0x52, 0x0f, 0x1e, 0xcf, 0x41, 0x38, 0x19}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0xf5, 0x6c, 0xd4, 0x2f, 0x0f, 0x69, 0x0f, 0x87, 0x3f, 0x61, 0x65, 0x1e, 0x35, 0x34, 0x85, 0xba, 0x02, 0x30, 0xac, 0x25, 0x3d, 0xe2, 0x62, 0xf1, 0xcc, 0xe9, 0x1b, 0xc2, 0xef, 0x6a, 0x42, 0x57}} ,
- {{0x34, 0x1f, 0x2e, 0xac, 0xd1, 0xc7, 0x04, 0x52, 0x32, 0x66, 0xb2, 0x33, 0x73, 0x21, 0x34, 0x54, 0xf7, 0x71, 0xed, 0x06, 0xb0, 0xff, 0xa6, 0x59, 0x6f, 0x8a, 0x4e, 0xfb, 0x02, 0xb0, 0x45, 0x6b}}},
-{{{0xf5, 0x48, 0x0b, 0x03, 0xc5, 0x22, 0x7d, 0x80, 0x08, 0x53, 0xfe, 0x32, 0xb1, 0xa1, 0x8a, 0x74, 0x6f, 0xbd, 0x3f, 0x85, 0xf4, 0xcf, 0xf5, 0x60, 0xaf, 0x41, 0x7e, 0x3e, 0x46, 0xa3, 0x5a, 0x20}} ,
- {{0xaa, 0x35, 0x87, 0x44, 0x63, 0x66, 0x97, 0xf8, 0x6e, 0x55, 0x0c, 0x04, 0x3e, 0x35, 0x50, 0xbf, 0x93, 0x69, 0xd2, 0x8b, 0x05, 0x55, 0x99, 0xbe, 0xe2, 0x53, 0x61, 0xec, 0xe8, 0x08, 0x0b, 0x32}}},
-{{{0xb3, 0x10, 0x45, 0x02, 0x69, 0x59, 0x2e, 0x97, 0xd9, 0x64, 0xf8, 0xdb, 0x25, 0x80, 0xdc, 0xc4, 0xd5, 0x62, 0x3c, 0xed, 0x65, 0x91, 0xad, 0xd1, 0x57, 0x81, 0x94, 0xaa, 0xa1, 0x29, 0xfc, 0x68}} ,
- {{0xdd, 0xb5, 0x7d, 0xab, 0x5a, 0x21, 0x41, 0x53, 0xbb, 0x17, 0x79, 0x0d, 0xd1, 0xa8, 0x0c, 0x0c, 0x20, 0x88, 0x09, 0xe9, 0x84, 0xe8, 0x25, 0x11, 0x67, 0x7a, 0x8b, 0x1a, 0xe4, 0x5d, 0xe1, 0x5d}}},
-{{{0x37, 0xea, 0xfe, 0x65, 0x3b, 0x25, 0xe8, 0xe1, 0xc2, 0xc5, 0x02, 0xa4, 0xbe, 0x98, 0x0a, 0x2b, 0x61, 0xc1, 0x9b, 0xe2, 0xd5, 0x92, 0xe6, 0x9e, 0x7d, 0x1f, 0xca, 0x43, 0x88, 0x8b, 0x2c, 0x59}} ,
- {{0xe0, 0xb5, 0x00, 0x1d, 0x2a, 0x6f, 0xaf, 0x79, 0x86, 0x2f, 0xa6, 0x5a, 0x93, 0xd1, 0xfe, 0xae, 0x3a, 0xee, 0xdb, 0x7c, 0x61, 0xbe, 0x7c, 0x01, 0xf9, 0xfe, 0x52, 0xdc, 0xd8, 0x52, 0xa3, 0x42}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0x22, 0xaf, 0x13, 0x37, 0xbd, 0x37, 0x71, 0xac, 0x04, 0x46, 0x63, 0xac, 0xa4, 0x77, 0xed, 0x25, 0x38, 0xe0, 0x15, 0xa8, 0x64, 0x00, 0x0d, 0xce, 0x51, 0x01, 0xa9, 0xbc, 0x0f, 0x03, 0x1c, 0x04}} ,
- {{0x89, 0xf9, 0x80, 0x07, 0xcf, 0x3f, 0xb3, 0xe9, 0xe7, 0x45, 0x44, 0x3d, 0x2a, 0x7c, 0xe9, 0xe4, 0x16, 0x5c, 0x5e, 0x65, 0x1c, 0xc7, 0x7d, 0xc6, 0x7a, 0xfb, 0x43, 0xee, 0x25, 0x76, 0x46, 0x72}}},
-{{{0x02, 0xa2, 0xed, 0xf4, 0x8f, 0x6b, 0x0b, 0x3e, 0xeb, 0x35, 0x1a, 0xd5, 0x7e, 0xdb, 0x78, 0x00, 0x96, 0x8a, 0xa0, 0xb4, 0xcf, 0x60, 0x4b, 0xd4, 0xd5, 0xf9, 0x2d, 0xbf, 0x88, 0xbd, 0x22, 0x62}} ,
- {{0x13, 0x53, 0xe4, 0x82, 0x57, 0xfa, 0x1e, 0x8f, 0x06, 0x2b, 0x90, 0xba, 0x08, 0xb6, 0x10, 0x54, 0x4f, 0x7c, 0x1b, 0x26, 0xed, 0xda, 0x6b, 0xdd, 0x25, 0xd0, 0x4e, 0xea, 0x42, 0xbb, 0x25, 0x03}}},
-{{{0x51, 0x16, 0x50, 0x7c, 0xd5, 0x5d, 0xf6, 0x99, 0xe8, 0x77, 0x72, 0x4e, 0xfa, 0x62, 0xcb, 0x76, 0x75, 0x0c, 0xe2, 0x71, 0x98, 0x92, 0xd5, 0xfa, 0x45, 0xdf, 0x5c, 0x6f, 0x1e, 0x9e, 0x28, 0x69}} ,
- {{0x0d, 0xac, 0x66, 0x6d, 0xc3, 0x8b, 0xba, 0x16, 0xb5, 0xe2, 0xa0, 0x0d, 0x0c, 0xbd, 0xa4, 0x8e, 0x18, 0x6c, 0xf2, 0xdc, 0xf9, 0xdc, 0x4a, 0x86, 0x25, 0x95, 0x14, 0xcb, 0xd8, 0x1a, 0x04, 0x0f}}},
-{{{0x97, 0xa5, 0xdb, 0x8b, 0x2d, 0xaa, 0x42, 0x11, 0x09, 0xf2, 0x93, 0xbb, 0xd9, 0x06, 0x84, 0x4e, 0x11, 0xa8, 0xa0, 0x25, 0x2b, 0xa6, 0x5f, 0xae, 0xc4, 0xb4, 0x4c, 0xc8, 0xab, 0xc7, 0x3b, 0x02}} ,
- {{0xee, 0xc9, 0x29, 0x0f, 0xdf, 0x11, 0x85, 0xed, 0xce, 0x0d, 0x62, 0x2c, 0x8f, 0x4b, 0xf9, 0x04, 0xe9, 0x06, 0x72, 0x1d, 0x37, 0x20, 0x50, 0xc9, 0x14, 0xeb, 0xec, 0x39, 0xa7, 0x97, 0x2b, 0x4d}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0x69, 0xd1, 0x39, 0xbd, 0xfb, 0x33, 0xbe, 0xc4, 0xf0, 0x5c, 0xef, 0xf0, 0x56, 0x68, 0xfc, 0x97, 0x47, 0xc8, 0x72, 0xb6, 0x53, 0xa4, 0x0a, 0x98, 0xa5, 0xb4, 0x37, 0x71, 0xcf, 0x66, 0x50, 0x6d}} ,
- {{0x17, 0xa4, 0x19, 0x52, 0x11, 0x47, 0xb3, 0x5c, 0x5b, 0xa9, 0x2e, 0x22, 0xb4, 0x00, 0x52, 0xf9, 0x57, 0x18, 0xb8, 0xbe, 0x5a, 0xe3, 0xab, 0x83, 0xc8, 0x87, 0x0a, 0x2a, 0xd8, 0x8c, 0xbb, 0x54}}},
-{{{0xa9, 0x62, 0x93, 0x85, 0xbe, 0xe8, 0x73, 0x4a, 0x0e, 0xb0, 0xb5, 0x2d, 0x94, 0x50, 0xaa, 0xd3, 0xb2, 0xea, 0x9d, 0x62, 0x76, 0x3b, 0x07, 0x34, 0x4e, 0x2d, 0x70, 0xc8, 0x9a, 0x15, 0x66, 0x6b}} ,
- {{0xc5, 0x96, 0xca, 0xc8, 0x22, 0x1a, 0xee, 0x5f, 0xe7, 0x31, 0x60, 0x22, 0x83, 0x08, 0x63, 0xce, 0xb9, 0x32, 0x44, 0x58, 0x5d, 0x3a, 0x9b, 0xe4, 0x04, 0xd5, 0xef, 0x38, 0xef, 0x4b, 0xdd, 0x19}}},
-{{{0x4d, 0xc2, 0x17, 0x75, 0xa1, 0x68, 0xcd, 0xc3, 0xc6, 0x03, 0x44, 0xe3, 0x78, 0x09, 0x91, 0x47, 0x3f, 0x0f, 0xe4, 0x92, 0x58, 0xfa, 0x7d, 0x1f, 0x20, 0x94, 0x58, 0x5e, 0xbc, 0x19, 0x02, 0x6f}} ,
- {{0x20, 0xd6, 0xd8, 0x91, 0x54, 0xa7, 0xf3, 0x20, 0x4b, 0x34, 0x06, 0xfa, 0x30, 0xc8, 0x6f, 0x14, 0x10, 0x65, 0x74, 0x13, 0x4e, 0xf0, 0x69, 0x26, 0xce, 0xcf, 0x90, 0xf4, 0xd0, 0xc5, 0xc8, 0x64}}},
-{{{0x26, 0xa2, 0x50, 0x02, 0x24, 0x72, 0xf1, 0xf0, 0x4e, 0x2d, 0x93, 0xd5, 0x08, 0xe7, 0xae, 0x38, 0xf7, 0x18, 0xa5, 0x32, 0x34, 0xc2, 0xf0, 0xa6, 0xec, 0xb9, 0x61, 0x7b, 0x64, 0x99, 0xac, 0x71}} ,
- {{0x25, 0xcf, 0x74, 0x55, 0x1b, 0xaa, 0xa9, 0x38, 0x41, 0x40, 0xd5, 0x95, 0x95, 0xab, 0x1c, 0x5e, 0xbc, 0x41, 0x7e, 0x14, 0x30, 0xbe, 0x13, 0x89, 0xf4, 0xe5, 0xeb, 0x28, 0xc0, 0xc2, 0x96, 0x3a}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0x2b, 0x77, 0x45, 0xec, 0x67, 0x76, 0x32, 0x4c, 0xb9, 0xdf, 0x25, 0x32, 0x6b, 0xcb, 0xe7, 0x14, 0x61, 0x43, 0xee, 0xba, 0x9b, 0x71, 0xef, 0xd2, 0x48, 0x65, 0xbb, 0x1b, 0x8a, 0x13, 0x1b, 0x22}} ,
- {{0x84, 0xad, 0x0c, 0x18, 0x38, 0x5a, 0xba, 0xd0, 0x98, 0x59, 0xbf, 0x37, 0xb0, 0x4f, 0x97, 0x60, 0x20, 0xb3, 0x9b, 0x97, 0xf6, 0x08, 0x6c, 0xa4, 0xff, 0xfb, 0xb7, 0xfa, 0x95, 0xb2, 0x51, 0x79}}},
-{{{0x28, 0x5c, 0x3f, 0xdb, 0x6b, 0x18, 0x3b, 0x5c, 0xd1, 0x04, 0x28, 0xde, 0x85, 0x52, 0x31, 0xb5, 0xbb, 0xf6, 0xa9, 0xed, 0xbe, 0x28, 0x4f, 0xb3, 0x7e, 0x05, 0x6a, 0xdb, 0x95, 0x0d, 0x1b, 0x1c}} ,
- {{0xd5, 0xc5, 0xc3, 0x9a, 0x0a, 0xd0, 0x31, 0x3e, 0x07, 0x36, 0x8e, 0xc0, 0x8a, 0x62, 0xb1, 0xca, 0xd6, 0x0e, 0x1e, 0x9d, 0xef, 0xab, 0x98, 0x4d, 0xbb, 0x6c, 0x05, 0xe0, 0xe4, 0x5d, 0xbd, 0x57}}},
-{{{0xcc, 0x21, 0x27, 0xce, 0xfd, 0xa9, 0x94, 0x8e, 0xe1, 0xab, 0x49, 0xe0, 0x46, 0x26, 0xa1, 0xa8, 0x8c, 0xa1, 0x99, 0x1d, 0xb4, 0x27, 0x6d, 0x2d, 0xc8, 0x39, 0x30, 0x5e, 0x37, 0x52, 0xc4, 0x6e}} ,
- {{0xa9, 0x85, 0xf4, 0xe7, 0xb0, 0x15, 0x33, 0x84, 0x1b, 0x14, 0x1a, 0x02, 0xd9, 0x3b, 0xad, 0x0f, 0x43, 0x6c, 0xea, 0x3e, 0x0f, 0x7e, 0xda, 0xdd, 0x6b, 0x4c, 0x7f, 0x6e, 0xd4, 0x6b, 0xbf, 0x0f}}},
-{{{0x47, 0x9f, 0x7c, 0x56, 0x7c, 0x43, 0x91, 0x1c, 0xbb, 0x4e, 0x72, 0x3e, 0x64, 0xab, 0xa0, 0xa0, 0xdf, 0xb4, 0xd8, 0x87, 0x3a, 0xbd, 0xa8, 0x48, 0xc9, 0xb8, 0xef, 0x2e, 0xad, 0x6f, 0x84, 0x4f}} ,
- {{0x2d, 0x2d, 0xf0, 0x1b, 0x7e, 0x2a, 0x6c, 0xf8, 0xa9, 0x6a, 0xe1, 0xf0, 0x99, 0xa1, 0x67, 0x9a, 0xd4, 0x13, 0xca, 0xca, 0xba, 0x27, 0x92, 0xaa, 0xa1, 0x5d, 0x50, 0xde, 0xcc, 0x40, 0x26, 0x0a}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0x9f, 0x3e, 0xf2, 0xb2, 0x90, 0xce, 0xdb, 0x64, 0x3e, 0x03, 0xdd, 0x37, 0x36, 0x54, 0x70, 0x76, 0x24, 0xb5, 0x69, 0x03, 0xfc, 0xa0, 0x2b, 0x74, 0xb2, 0x05, 0x0e, 0xcc, 0xd8, 0x1f, 0x6a, 0x1f}} ,
- {{0x19, 0x5e, 0x60, 0x69, 0x58, 0x86, 0xa0, 0x31, 0xbd, 0x32, 0xe9, 0x2c, 0x5c, 0xd2, 0x85, 0xba, 0x40, 0x64, 0xa8, 0x74, 0xf8, 0x0e, 0x1c, 0xb3, 0xa9, 0x69, 0xe8, 0x1e, 0x40, 0x64, 0x99, 0x77}}},
-{{{0x6c, 0x32, 0x4f, 0xfd, 0xbb, 0x5c, 0xbb, 0x8d, 0x64, 0x66, 0x4a, 0x71, 0x1f, 0x79, 0xa3, 0xad, 0x8d, 0xf9, 0xd4, 0xec, 0xcf, 0x67, 0x70, 0xfa, 0x05, 0x4a, 0x0f, 0x6e, 0xaf, 0x87, 0x0a, 0x6f}} ,
- {{0xc6, 0x36, 0x6e, 0x6c, 0x8c, 0x24, 0x09, 0x60, 0xbe, 0x26, 0xd2, 0x4c, 0x5e, 0x17, 0xca, 0x5f, 0x1d, 0xcc, 0x87, 0xe8, 0x42, 0x6a, 0xcb, 0xcb, 0x7d, 0x92, 0x05, 0x35, 0x81, 0x13, 0x60, 0x6b}}},
-{{{0xf4, 0x15, 0xcd, 0x0f, 0x0a, 0xaf, 0x4e, 0x6b, 0x51, 0xfd, 0x14, 0xc4, 0x2e, 0x13, 0x86, 0x74, 0x44, 0xcb, 0x66, 0x6b, 0xb6, 0x9d, 0x74, 0x56, 0x32, 0xac, 0x8d, 0x8e, 0x8c, 0x8c, 0x8c, 0x39}} ,
- {{0xca, 0x59, 0x74, 0x1a, 0x11, 0xef, 0x6d, 0xf7, 0x39, 0x5c, 0x3b, 0x1f, 0xfa, 0xe3, 0x40, 0x41, 0x23, 0x9e, 0xf6, 0xd1, 0x21, 0xa2, 0xbf, 0xad, 0x65, 0x42, 0x6b, 0x59, 0x8a, 0xe8, 0xc5, 0x7f}}},
-{{{0x64, 0x05, 0x7a, 0x84, 0x4a, 0x13, 0xc3, 0xf6, 0xb0, 0x6e, 0x9a, 0x6b, 0x53, 0x6b, 0x32, 0xda, 0xd9, 0x74, 0x75, 0xc4, 0xba, 0x64, 0x3d, 0x3b, 0x08, 0xdd, 0x10, 0x46, 0xef, 0xc7, 0x90, 0x1f}} ,
- {{0x7b, 0x2f, 0x3a, 0xce, 0xc8, 0xa1, 0x79, 0x3c, 0x30, 0x12, 0x44, 0x28, 0xf6, 0xbc, 0xff, 0xfd, 0xf4, 0xc0, 0x97, 0xb0, 0xcc, 0xc3, 0x13, 0x7a, 0xb9, 0x9a, 0x16, 0xe4, 0xcb, 0x4c, 0x34, 0x63}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0x07, 0x4e, 0xd3, 0x2d, 0x09, 0x33, 0x0e, 0xd2, 0x0d, 0xbe, 0x3e, 0xe7, 0xe4, 0xaa, 0xb7, 0x00, 0x8b, 0xe8, 0xad, 0xaa, 0x7a, 0x8d, 0x34, 0x28, 0xa9, 0x81, 0x94, 0xc5, 0xe7, 0x42, 0xac, 0x47}} ,
- {{0x24, 0x89, 0x7a, 0x8f, 0xb5, 0x9b, 0xf0, 0xc2, 0x03, 0x64, 0xd0, 0x1e, 0xf5, 0xa4, 0xb2, 0xf3, 0x74, 0xe9, 0x1a, 0x16, 0xfd, 0xcb, 0x15, 0xea, 0xeb, 0x10, 0x6c, 0x35, 0xd1, 0xc1, 0xa6, 0x28}}},
-{{{0xcc, 0xd5, 0x39, 0xfc, 0xa5, 0xa4, 0xad, 0x32, 0x15, 0xce, 0x19, 0xe8, 0x34, 0x2b, 0x1c, 0x60, 0x91, 0xfc, 0x05, 0xa9, 0xb3, 0xdc, 0x80, 0x29, 0xc4, 0x20, 0x79, 0x06, 0x39, 0xc0, 0xe2, 0x22}} ,
- {{0xbb, 0xa8, 0xe1, 0x89, 0x70, 0x57, 0x18, 0x54, 0x3c, 0xf6, 0x0d, 0x82, 0x12, 0x05, 0x87, 0x96, 0x06, 0x39, 0xe3, 0xf8, 0xb3, 0x95, 0xe5, 0xd7, 0x26, 0xbf, 0x09, 0x5a, 0x94, 0xf9, 0x1c, 0x63}}},
-{{{0x2b, 0x8c, 0x2d, 0x9a, 0x8b, 0x84, 0xf2, 0x56, 0xfb, 0xad, 0x2e, 0x7f, 0xb7, 0xfc, 0x30, 0xe1, 0x35, 0x89, 0xba, 0x4d, 0xa8, 0x6d, 0xce, 0x8c, 0x8b, 0x30, 0xe0, 0xda, 0x29, 0x18, 0x11, 0x17}} ,
- {{0x19, 0xa6, 0x5a, 0x65, 0x93, 0xc3, 0xb5, 0x31, 0x22, 0x4f, 0xf3, 0xf6, 0x0f, 0xeb, 0x28, 0xc3, 0x7c, 0xeb, 0xce, 0x86, 0xec, 0x67, 0x76, 0x6e, 0x35, 0x45, 0x7b, 0xd8, 0x6b, 0x92, 0x01, 0x65}}},
-{{{0x3d, 0xd5, 0x9a, 0x64, 0x73, 0x36, 0xb1, 0xd6, 0x86, 0x98, 0x42, 0x3f, 0x8a, 0xf1, 0xc7, 0xf5, 0x42, 0xa8, 0x9c, 0x52, 0xa8, 0xdc, 0xf9, 0x24, 0x3f, 0x4a, 0xa1, 0xa4, 0x5b, 0xe8, 0x62, 0x1a}} ,
- {{0xc5, 0xbd, 0xc8, 0x14, 0xd5, 0x0d, 0xeb, 0xe1, 0xa5, 0xe6, 0x83, 0x11, 0x09, 0x00, 0x1d, 0x55, 0x83, 0x51, 0x7e, 0x75, 0x00, 0x81, 0xb9, 0xcb, 0xd8, 0xc5, 0xe5, 0xa1, 0xd9, 0x17, 0x6d, 0x1f}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0xea, 0xf9, 0xe4, 0xe9, 0xe1, 0x52, 0x3f, 0x51, 0x19, 0x0d, 0xdd, 0xd9, 0x9d, 0x93, 0x31, 0x87, 0x23, 0x09, 0xd5, 0x83, 0xeb, 0x92, 0x09, 0x76, 0x6e, 0xe3, 0xf8, 0xc0, 0xa2, 0x66, 0xb5, 0x36}} ,
- {{0x3a, 0xbb, 0x39, 0xed, 0x32, 0x02, 0xe7, 0x43, 0x7a, 0x38, 0x14, 0x84, 0xe3, 0x44, 0xd2, 0x5e, 0x94, 0xdd, 0x78, 0x89, 0x55, 0x4c, 0x73, 0x9e, 0xe1, 0xe4, 0x3e, 0x43, 0xd0, 0x4a, 0xde, 0x1b}}},
-{{{0xb2, 0xe7, 0x8f, 0xe3, 0xa3, 0xc5, 0xcb, 0x72, 0xee, 0x79, 0x41, 0xf8, 0xdf, 0xee, 0x65, 0xc5, 0x45, 0x77, 0x27, 0x3c, 0xbd, 0x58, 0xd3, 0x75, 0xe2, 0x04, 0x4b, 0xbb, 0x65, 0xf3, 0xc8, 0x0f}} ,
- {{0x24, 0x7b, 0x93, 0x34, 0xb5, 0xe2, 0x74, 0x48, 0xcd, 0xa0, 0x0b, 0x92, 0x97, 0x66, 0x39, 0xf4, 0xb0, 0xe2, 0x5d, 0x39, 0x6a, 0x5b, 0x45, 0x17, 0x78, 0x1e, 0xdb, 0x91, 0x81, 0x1c, 0xf9, 0x16}}},
-{{{0x16, 0xdf, 0xd1, 0x5a, 0xd5, 0xe9, 0x4e, 0x58, 0x95, 0x93, 0x5f, 0x51, 0x09, 0xc3, 0x2a, 0xc9, 0xd4, 0x55, 0x48, 0x79, 0xa4, 0xa3, 0xb2, 0xc3, 0x62, 0xaa, 0x8c, 0xe8, 0xad, 0x47, 0x39, 0x1b}} ,
- {{0x46, 0xda, 0x9e, 0x51, 0x3a, 0xe6, 0xd1, 0xa6, 0xbb, 0x4d, 0x7b, 0x08, 0xbe, 0x8c, 0xd5, 0xf3, 0x3f, 0xfd, 0xf7, 0x44, 0x80, 0x2d, 0x53, 0x4b, 0xd0, 0x87, 0x68, 0xc1, 0xb5, 0xd8, 0xf7, 0x07}}},
-{{{0xf4, 0x10, 0x46, 0xbe, 0xb7, 0xd2, 0xd1, 0xce, 0x5e, 0x76, 0xa2, 0xd7, 0x03, 0xdc, 0xe4, 0x81, 0x5a, 0xf6, 0x3c, 0xde, 0xae, 0x7a, 0x9d, 0x21, 0x34, 0xa5, 0xf6, 0xa9, 0x73, 0xe2, 0x8d, 0x60}} ,
- {{0xfa, 0x44, 0x71, 0xf6, 0x41, 0xd8, 0xc6, 0x58, 0x13, 0x37, 0xeb, 0x84, 0x0f, 0x96, 0xc7, 0xdc, 0xc8, 0xa9, 0x7a, 0x83, 0xb2, 0x2f, 0x31, 0xb1, 0x1a, 0xd8, 0x98, 0x3f, 0x11, 0xd0, 0x31, 0x3b}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0x81, 0xd5, 0x34, 0x16, 0x01, 0xa3, 0x93, 0xea, 0x52, 0x94, 0xec, 0x93, 0xb7, 0x81, 0x11, 0x2d, 0x58, 0xf9, 0xb5, 0x0a, 0xaa, 0x4f, 0xf6, 0x2e, 0x3f, 0x36, 0xbf, 0x33, 0x5a, 0xe7, 0xd1, 0x08}} ,
- {{0x1a, 0xcf, 0x42, 0xae, 0xcc, 0xb5, 0x77, 0x39, 0xc4, 0x5b, 0x5b, 0xd0, 0x26, 0x59, 0x27, 0xd0, 0x55, 0x71, 0x12, 0x9d, 0x88, 0x3d, 0x9c, 0xea, 0x41, 0x6a, 0xf0, 0x50, 0x93, 0x93, 0xdd, 0x47}}},
-{{{0x6f, 0xc9, 0x51, 0x6d, 0x1c, 0xaa, 0xf5, 0xa5, 0x90, 0x3f, 0x14, 0xe2, 0x6e, 0x8e, 0x64, 0xfd, 0xac, 0xe0, 0x4e, 0x22, 0xe5, 0xc1, 0xbc, 0x29, 0x0a, 0x6a, 0x9e, 0xa1, 0x60, 0xcb, 0x2f, 0x0b}} ,
- {{0xdc, 0x39, 0x32, 0xf3, 0xa1, 0x44, 0xe9, 0xc5, 0xc3, 0x78, 0xfb, 0x95, 0x47, 0x34, 0x35, 0x34, 0xe8, 0x25, 0xde, 0x93, 0xc6, 0xb4, 0x76, 0x6d, 0x86, 0x13, 0xc6, 0xe9, 0x68, 0xb5, 0x01, 0x63}}},
-{{{0x1f, 0x9a, 0x52, 0x64, 0x97, 0xd9, 0x1c, 0x08, 0x51, 0x6f, 0x26, 0x9d, 0xaa, 0x93, 0x33, 0x43, 0xfa, 0x77, 0xe9, 0x62, 0x9b, 0x5d, 0x18, 0x75, 0xeb, 0x78, 0xf7, 0x87, 0x8f, 0x41, 0xb4, 0x4d}} ,
- {{0x13, 0xa8, 0x82, 0x3e, 0xe9, 0x13, 0xad, 0xeb, 0x01, 0xca, 0xcf, 0xda, 0xcd, 0xf7, 0x6c, 0xc7, 0x7a, 0xdc, 0x1e, 0x6e, 0xc8, 0x4e, 0x55, 0x62, 0x80, 0xea, 0x78, 0x0c, 0x86, 0xb9, 0x40, 0x51}}},
-{{{0x27, 0xae, 0xd3, 0x0d, 0x4c, 0x8f, 0x34, 0xea, 0x7d, 0x3c, 0xe5, 0x8a, 0xcf, 0x5b, 0x92, 0xd8, 0x30, 0x16, 0xb4, 0xa3, 0x75, 0xff, 0xeb, 0x27, 0xc8, 0x5c, 0x6c, 0xc2, 0xee, 0x6c, 0x21, 0x0b}} ,
- {{0xc3, 0xba, 0x12, 0x53, 0x2a, 0xaa, 0x77, 0xad, 0x19, 0x78, 0x55, 0x8a, 0x2e, 0x60, 0x87, 0xc2, 0x6e, 0x91, 0x38, 0x91, 0x3f, 0x7a, 0xc5, 0x24, 0x8f, 0x51, 0xc5, 0xde, 0xb0, 0x53, 0x30, 0x56}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0x02, 0xfe, 0x54, 0x12, 0x18, 0xca, 0x7d, 0xa5, 0x68, 0x43, 0xa3, 0x6d, 0x14, 0x2a, 0x6a, 0xa5, 0x8e, 0x32, 0xe7, 0x63, 0x4f, 0xe3, 0xc6, 0x44, 0x3e, 0xab, 0x63, 0xca, 0x17, 0x86, 0x74, 0x3f}} ,
- {{0x1e, 0x64, 0xc1, 0x7d, 0x52, 0xdc, 0x13, 0x5a, 0xa1, 0x9c, 0x4e, 0xee, 0x99, 0x28, 0xbb, 0x4c, 0xee, 0xac, 0xa9, 0x1b, 0x89, 0xa2, 0x38, 0x39, 0x7b, 0xc4, 0x0f, 0x42, 0xe6, 0x89, 0xed, 0x0f}}},
-{{{0xf3, 0x3c, 0x8c, 0x80, 0x83, 0x10, 0x8a, 0x37, 0x50, 0x9c, 0xb4, 0xdf, 0x3f, 0x8c, 0xf7, 0x23, 0x07, 0xd6, 0xff, 0xa0, 0x82, 0x6c, 0x75, 0x3b, 0xe4, 0xb5, 0xbb, 0xe4, 0xe6, 0x50, 0xf0, 0x08}} ,
- {{0x62, 0xee, 0x75, 0x48, 0x92, 0x33, 0xf2, 0xf4, 0xad, 0x15, 0x7a, 0xa1, 0x01, 0x46, 0xa9, 0x32, 0x06, 0x88, 0xb6, 0x36, 0x47, 0x35, 0xb9, 0xb4, 0x42, 0x85, 0x76, 0xf0, 0x48, 0x00, 0x90, 0x38}}},
-{{{0x51, 0x15, 0x9d, 0xc3, 0x95, 0xd1, 0x39, 0xbb, 0x64, 0x9d, 0x15, 0x81, 0xc1, 0x68, 0xd0, 0xb6, 0xa4, 0x2c, 0x7d, 0x5e, 0x02, 0x39, 0x00, 0xe0, 0x3b, 0xa4, 0xcc, 0xca, 0x1d, 0x81, 0x24, 0x10}} ,
- {{0xe7, 0x29, 0xf9, 0x37, 0xd9, 0x46, 0x5a, 0xcd, 0x70, 0xfe, 0x4d, 0x5b, 0xbf, 0xa5, 0xcf, 0x91, 0xf4, 0xef, 0xee, 0x8a, 0x29, 0xd0, 0xe7, 0xc4, 0x25, 0x92, 0x8a, 0xff, 0x36, 0xfc, 0xe4, 0x49}}},
-{{{0xbd, 0x00, 0xb9, 0x04, 0x7d, 0x35, 0xfc, 0xeb, 0xd0, 0x0b, 0x05, 0x32, 0x52, 0x7a, 0x89, 0x24, 0x75, 0x50, 0xe1, 0x63, 0x02, 0x82, 0x8e, 0xe7, 0x85, 0x0c, 0xf2, 0x56, 0x44, 0x37, 0x83, 0x25}} ,
- {{0x8f, 0xa1, 0xce, 0xcb, 0x60, 0xda, 0x12, 0x02, 0x1e, 0x29, 0x39, 0x2a, 0x03, 0xb7, 0xeb, 0x77, 0x40, 0xea, 0xc9, 0x2b, 0x2c, 0xd5, 0x7d, 0x7e, 0x2c, 0xc7, 0x5a, 0xfd, 0xff, 0xc4, 0xd1, 0x62}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0x1d, 0x88, 0x98, 0x5b, 0x4e, 0xfc, 0x41, 0x24, 0x05, 0xe6, 0x50, 0x2b, 0xae, 0x96, 0x51, 0xd9, 0x6b, 0x72, 0xb2, 0x33, 0x42, 0x98, 0x68, 0xbb, 0x10, 0x5a, 0x7a, 0x8c, 0x9d, 0x07, 0xb4, 0x05}} ,
- {{0x2f, 0x61, 0x9f, 0xd7, 0xa8, 0x3f, 0x83, 0x8c, 0x10, 0x69, 0x90, 0xe6, 0xcf, 0xd2, 0x63, 0xa3, 0xe4, 0x54, 0x7e, 0xe5, 0x69, 0x13, 0x1c, 0x90, 0x57, 0xaa, 0xe9, 0x53, 0x22, 0x43, 0x29, 0x23}}},
-{{{0xe5, 0x1c, 0xf8, 0x0a, 0xfd, 0x2d, 0x7e, 0xf5, 0xf5, 0x70, 0x7d, 0x41, 0x6b, 0x11, 0xfe, 0xbe, 0x99, 0xd1, 0x55, 0x29, 0x31, 0xbf, 0xc0, 0x97, 0x6c, 0xd5, 0x35, 0xcc, 0x5e, 0x8b, 0xd9, 0x69}} ,
- {{0x8e, 0x4e, 0x9f, 0x25, 0xf8, 0x81, 0x54, 0x2d, 0x0e, 0xd5, 0x54, 0x81, 0x9b, 0xa6, 0x92, 0xce, 0x4b, 0xe9, 0x8f, 0x24, 0x3b, 0xca, 0xe0, 0x44, 0xab, 0x36, 0xfe, 0xfb, 0x87, 0xd4, 0x26, 0x3e}}},
-{{{0x0f, 0x93, 0x9c, 0x11, 0xe7, 0xdb, 0xf1, 0xf0, 0x85, 0x43, 0x28, 0x15, 0x37, 0xdd, 0xde, 0x27, 0xdf, 0xad, 0x3e, 0x49, 0x4f, 0xe0, 0x5b, 0xf6, 0x80, 0x59, 0x15, 0x3c, 0x85, 0xb7, 0x3e, 0x12}} ,
- {{0xf5, 0xff, 0xcc, 0xf0, 0xb4, 0x12, 0x03, 0x5f, 0xc9, 0x84, 0xcb, 0x1d, 0x17, 0xe0, 0xbc, 0xcc, 0x03, 0x62, 0xa9, 0x8b, 0x94, 0xa6, 0xaa, 0x18, 0xcb, 0x27, 0x8d, 0x49, 0xa6, 0x17, 0x15, 0x07}}},
-{{{0xd9, 0xb6, 0xd4, 0x9d, 0xd4, 0x6a, 0xaf, 0x70, 0x07, 0x2c, 0x10, 0x9e, 0xbd, 0x11, 0xad, 0xe4, 0x26, 0x33, 0x70, 0x92, 0x78, 0x1c, 0x74, 0x9f, 0x75, 0x60, 0x56, 0xf4, 0x39, 0xa8, 0xa8, 0x62}} ,
- {{0x3b, 0xbf, 0x55, 0x35, 0x61, 0x8b, 0x44, 0x97, 0xe8, 0x3a, 0x55, 0xc1, 0xc8, 0x3b, 0xfd, 0x95, 0x29, 0x11, 0x60, 0x96, 0x1e, 0xcb, 0x11, 0x9d, 0xc2, 0x03, 0x8a, 0x1b, 0xc6, 0xd6, 0x45, 0x3d}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0x7e, 0x0e, 0x50, 0xb2, 0xcc, 0x0d, 0x6b, 0xa6, 0x71, 0x5b, 0x42, 0xed, 0xbd, 0xaf, 0xac, 0xf0, 0xfc, 0x12, 0xa2, 0x3f, 0x4e, 0xda, 0xe8, 0x11, 0xf3, 0x23, 0xe1, 0x04, 0x62, 0x03, 0x1c, 0x4e}} ,
- {{0xc8, 0xb1, 0x1b, 0x6f, 0x73, 0x61, 0x3d, 0x27, 0x0d, 0x7d, 0x7a, 0x25, 0x5f, 0x73, 0x0e, 0x2f, 0x93, 0xf6, 0x24, 0xd8, 0x4f, 0x90, 0xac, 0xa2, 0x62, 0x0a, 0xf0, 0x61, 0xd9, 0x08, 0x59, 0x6a}}},
-{{{0x6f, 0x2d, 0x55, 0xf8, 0x2f, 0x8e, 0xf0, 0x18, 0x3b, 0xea, 0xdd, 0x26, 0x72, 0xd1, 0xf5, 0xfe, 0xe5, 0xb8, 0xe6, 0xd3, 0x10, 0x48, 0x46, 0x49, 0x3a, 0x9f, 0x5e, 0x45, 0x6b, 0x90, 0xe8, 0x7f}} ,
- {{0xd3, 0x76, 0x69, 0x33, 0x7b, 0xb9, 0x40, 0x70, 0xee, 0xa6, 0x29, 0x6b, 0xdd, 0xd0, 0x5d, 0x8d, 0xc1, 0x3e, 0x4a, 0xea, 0x37, 0xb1, 0x03, 0x02, 0x03, 0x35, 0xf1, 0x28, 0x9d, 0xff, 0x00, 0x13}}},
-{{{0x7a, 0xdb, 0x12, 0xd2, 0x8a, 0x82, 0x03, 0x1b, 0x1e, 0xaf, 0xf9, 0x4b, 0x9c, 0xbe, 0xae, 0x7c, 0xe4, 0x94, 0x2a, 0x23, 0xb3, 0x62, 0x86, 0xe7, 0xfd, 0x23, 0xaa, 0x99, 0xbd, 0x2b, 0x11, 0x6c}} ,
- {{0x8d, 0xa6, 0xd5, 0xac, 0x9d, 0xcc, 0x68, 0x75, 0x7f, 0xc3, 0x4d, 0x4b, 0xdd, 0x6c, 0xbb, 0x11, 0x5a, 0x60, 0xe5, 0xbd, 0x7d, 0x27, 0x8b, 0xda, 0xb4, 0x95, 0xf6, 0x03, 0x27, 0xa4, 0x92, 0x3f}}},
-{{{0x22, 0xd6, 0xb5, 0x17, 0x84, 0xbf, 0x12, 0xcc, 0x23, 0x14, 0x4a, 0xdf, 0x14, 0x31, 0xbc, 0xa1, 0xac, 0x6e, 0xab, 0xfa, 0x57, 0x11, 0x53, 0xb3, 0x27, 0xe6, 0xf9, 0x47, 0x33, 0x44, 0x34, 0x1e}} ,
- {{0x79, 0xfc, 0xa6, 0xb4, 0x0b, 0x35, 0x20, 0xc9, 0x4d, 0x22, 0x84, 0xc4, 0xa9, 0x20, 0xec, 0x89, 0x94, 0xba, 0x66, 0x56, 0x48, 0xb9, 0x87, 0x7f, 0xca, 0x1e, 0x06, 0xed, 0xa5, 0x55, 0x59, 0x29}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0x56, 0xe1, 0xf5, 0xf1, 0xd5, 0xab, 0xa8, 0x2b, 0xae, 0x89, 0xf3, 0xcf, 0x56, 0x9f, 0xf2, 0x4b, 0x31, 0xbc, 0x18, 0xa9, 0x06, 0x5b, 0xbe, 0xb4, 0x61, 0xf8, 0xb2, 0x06, 0x9c, 0x81, 0xab, 0x4c}} ,
- {{0x1f, 0x68, 0x76, 0x01, 0x16, 0x38, 0x2b, 0x0f, 0x77, 0x97, 0x92, 0x67, 0x4e, 0x86, 0x6a, 0x8b, 0xe5, 0xe8, 0x0c, 0xf7, 0x36, 0x39, 0xb5, 0x33, 0xe6, 0xcf, 0x5e, 0xbd, 0x18, 0xfb, 0x10, 0x1f}}},
-{{{0x83, 0xf0, 0x0d, 0x63, 0xef, 0x53, 0x6b, 0xb5, 0x6b, 0xf9, 0x83, 0xcf, 0xde, 0x04, 0x22, 0x9b, 0x2c, 0x0a, 0xe0, 0xa5, 0xd8, 0xc7, 0x9c, 0xa5, 0xa3, 0xf6, 0x6f, 0xcf, 0x90, 0x6b, 0x68, 0x7c}} ,
- {{0x33, 0x15, 0xd7, 0x7f, 0x1a, 0xd5, 0x21, 0x58, 0xc4, 0x18, 0xa5, 0xf0, 0xcc, 0x73, 0xa8, 0xfd, 0xfa, 0x18, 0xd1, 0x03, 0x91, 0x8d, 0x52, 0xd2, 0xa3, 0xa4, 0xd3, 0xb1, 0xea, 0x1d, 0x0f, 0x00}}},
-{{{0xcc, 0x48, 0x83, 0x90, 0xe5, 0xfd, 0x3f, 0x84, 0xaa, 0xf9, 0x8b, 0x82, 0x59, 0x24, 0x34, 0x68, 0x4f, 0x1c, 0x23, 0xd9, 0xcc, 0x71, 0xe1, 0x7f, 0x8c, 0xaf, 0xf1, 0xee, 0x00, 0xb6, 0xa0, 0x77}} ,
- {{0xf5, 0x1a, 0x61, 0xf7, 0x37, 0x9d, 0x00, 0xf4, 0xf2, 0x69, 0x6f, 0x4b, 0x01, 0x85, 0x19, 0x45, 0x4d, 0x7f, 0x02, 0x7c, 0x6a, 0x05, 0x47, 0x6c, 0x1f, 0x81, 0x20, 0xd4, 0xe8, 0x50, 0x27, 0x72}}},
-{{{0x2c, 0x3a, 0xe5, 0xad, 0xf4, 0xdd, 0x2d, 0xf7, 0x5c, 0x44, 0xb5, 0x5b, 0x21, 0xa3, 0x89, 0x5f, 0x96, 0x45, 0xca, 0x4d, 0xa4, 0x21, 0x99, 0x70, 0xda, 0xc4, 0xc4, 0xa0, 0xe5, 0xf4, 0xec, 0x0a}} ,
- {{0x07, 0x68, 0x21, 0x65, 0xe9, 0x08, 0xa0, 0x0b, 0x6a, 0x4a, 0xba, 0xb5, 0x80, 0xaf, 0xd0, 0x1b, 0xc5, 0xf5, 0x4b, 0x73, 0x50, 0x60, 0x2d, 0x71, 0x69, 0x61, 0x0e, 0xc0, 0x20, 0x40, 0x30, 0x19}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0xd0, 0x75, 0x57, 0x3b, 0xeb, 0x5c, 0x14, 0x56, 0x50, 0xc9, 0x4f, 0xb8, 0xb8, 0x1e, 0xa3, 0xf4, 0xab, 0xf5, 0xa9, 0x20, 0x15, 0x94, 0x82, 0xda, 0x96, 0x1c, 0x9b, 0x59, 0x8c, 0xff, 0xf4, 0x51}} ,
- {{0xc1, 0x3a, 0x86, 0xd7, 0xb0, 0x06, 0x84, 0x7f, 0x1b, 0xbd, 0xd4, 0x07, 0x78, 0x80, 0x2e, 0xb1, 0xb4, 0xee, 0x52, 0x38, 0xee, 0x9a, 0xf9, 0xf6, 0xf3, 0x41, 0x6e, 0xd4, 0x88, 0x95, 0xac, 0x35}}},
-{{{0x41, 0x97, 0xbf, 0x71, 0x6a, 0x9b, 0x72, 0xec, 0xf3, 0xf8, 0x6b, 0xe6, 0x0e, 0x6c, 0x69, 0xa5, 0x2f, 0x68, 0x52, 0xd8, 0x61, 0x81, 0xc0, 0x63, 0x3f, 0xa6, 0x3c, 0x13, 0x90, 0xe6, 0x8d, 0x56}} ,
- {{0xe8, 0x39, 0x30, 0x77, 0x23, 0xb1, 0xfd, 0x1b, 0x3d, 0x3e, 0x74, 0x4d, 0x7f, 0xae, 0x5b, 0x3a, 0xb4, 0x65, 0x0e, 0x3a, 0x43, 0xdc, 0xdc, 0x41, 0x47, 0xe6, 0xe8, 0x92, 0x09, 0x22, 0x48, 0x4c}}},
-{{{0x85, 0x57, 0x9f, 0xb5, 0xc8, 0x06, 0xb2, 0x9f, 0x47, 0x3f, 0xf0, 0xfa, 0xe6, 0xa9, 0xb1, 0x9b, 0x6f, 0x96, 0x7d, 0xf9, 0xa4, 0x65, 0x09, 0x75, 0x32, 0xa6, 0x6c, 0x7f, 0x47, 0x4b, 0x2f, 0x4f}} ,
- {{0x34, 0xe9, 0x59, 0x93, 0x9d, 0x26, 0x80, 0x54, 0xf2, 0xcc, 0x3c, 0xc2, 0x25, 0x85, 0xe3, 0x6a, 0xc1, 0x62, 0x04, 0xa7, 0x08, 0x32, 0x6d, 0xa1, 0x39, 0x84, 0x8a, 0x3b, 0x87, 0x5f, 0x11, 0x13}}},
-{{{0xda, 0x03, 0x34, 0x66, 0xc4, 0x0c, 0x73, 0x6e, 0xbc, 0x24, 0xb5, 0xf9, 0x70, 0x81, 0x52, 0xe9, 0xf4, 0x7c, 0x23, 0xdd, 0x9f, 0xb8, 0x46, 0xef, 0x1d, 0x22, 0x55, 0x7d, 0x71, 0xc4, 0x42, 0x33}} ,
- {{0xc5, 0x37, 0x69, 0x5b, 0xa8, 0xc6, 0x9d, 0xa4, 0xfc, 0x61, 0x6e, 0x68, 0x46, 0xea, 0xd7, 0x1c, 0x67, 0xd2, 0x7d, 0xfa, 0xf1, 0xcc, 0x54, 0x8d, 0x36, 0x35, 0xc9, 0x00, 0xdf, 0x6c, 0x67, 0x50}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0x9a, 0x4d, 0x42, 0x29, 0x5d, 0xa4, 0x6b, 0x6f, 0xa8, 0x8a, 0x4d, 0x91, 0x7b, 0xd2, 0xdf, 0x36, 0xef, 0x01, 0x22, 0xc5, 0xcc, 0x8d, 0xeb, 0x58, 0x3d, 0xb3, 0x50, 0xfc, 0x8b, 0x97, 0x96, 0x33}} ,
- {{0x93, 0x33, 0x07, 0xc8, 0x4a, 0xca, 0xd0, 0xb1, 0xab, 0xbd, 0xdd, 0xa7, 0x7c, 0xac, 0x3e, 0x45, 0xcb, 0xcc, 0x07, 0x91, 0xbf, 0x35, 0x9d, 0xcb, 0x7d, 0x12, 0x3c, 0x11, 0x59, 0x13, 0xcf, 0x5c}}},
-{{{0x45, 0xb8, 0x41, 0xd7, 0xab, 0x07, 0x15, 0x00, 0x8e, 0xce, 0xdf, 0xb2, 0x43, 0x5c, 0x01, 0xdc, 0xf4, 0x01, 0x51, 0x95, 0x10, 0x5a, 0xf6, 0x24, 0x24, 0xa0, 0x19, 0x3a, 0x09, 0x2a, 0xaa, 0x3f}} ,
- {{0xdc, 0x8e, 0xeb, 0xc6, 0xbf, 0xdd, 0x11, 0x7b, 0xe7, 0x47, 0xe6, 0xce, 0xe7, 0xb6, 0xc5, 0xe8, 0x8a, 0xdc, 0x4b, 0x57, 0x15, 0x3b, 0x66, 0xca, 0x89, 0xa3, 0xfd, 0xac, 0x0d, 0xe1, 0x1d, 0x7a}}},
-{{{0x89, 0xef, 0xbf, 0x03, 0x75, 0xd0, 0x29, 0x50, 0xcb, 0x7d, 0xd6, 0xbe, 0xad, 0x5f, 0x7b, 0x00, 0x32, 0xaa, 0x98, 0xed, 0x3f, 0x8f, 0x92, 0xcb, 0x81, 0x56, 0x01, 0x63, 0x64, 0xa3, 0x38, 0x39}} ,
- {{0x8b, 0xa4, 0xd6, 0x50, 0xb4, 0xaa, 0x5d, 0x64, 0x64, 0x76, 0x2e, 0xa1, 0xa6, 0xb3, 0xb8, 0x7c, 0x7a, 0x56, 0xf5, 0x5c, 0x4e, 0x84, 0x5c, 0xfb, 0xdd, 0xca, 0x48, 0x8b, 0x48, 0xb9, 0xba, 0x34}}},
-{{{0xc5, 0xe3, 0xe8, 0xae, 0x17, 0x27, 0xe3, 0x64, 0x60, 0x71, 0x47, 0x29, 0x02, 0x0f, 0x92, 0x5d, 0x10, 0x93, 0xc8, 0x0e, 0xa1, 0xed, 0xba, 0xa9, 0x96, 0x1c, 0xc5, 0x76, 0x30, 0xcd, 0xf9, 0x30}} ,
- {{0x95, 0xb0, 0xbd, 0x8c, 0xbc, 0xa7, 0x4f, 0x7e, 0xfd, 0x4e, 0x3a, 0xbf, 0x5f, 0x04, 0x79, 0x80, 0x2b, 0x5a, 0x9f, 0x4f, 0x68, 0x21, 0x19, 0x71, 0xc6, 0x20, 0x01, 0x42, 0xaa, 0xdf, 0xae, 0x2c}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0x90, 0x6e, 0x7e, 0x4b, 0x71, 0x93, 0xc0, 0x72, 0xed, 0xeb, 0x71, 0x24, 0x97, 0x26, 0x9c, 0xfe, 0xcb, 0x3e, 0x59, 0x19, 0xa8, 0x0f, 0x75, 0x7d, 0xbe, 0x18, 0xe6, 0x96, 0x1e, 0x95, 0x70, 0x60}} ,
- {{0x89, 0x66, 0x3e, 0x1d, 0x4c, 0x5f, 0xfe, 0xc0, 0x04, 0x43, 0xd6, 0x44, 0x19, 0xb5, 0xad, 0xc7, 0x22, 0xdc, 0x71, 0x28, 0x64, 0xde, 0x41, 0x38, 0x27, 0x8f, 0x2c, 0x6b, 0x08, 0xb8, 0xb8, 0x7b}}},
-{{{0x3d, 0x70, 0x27, 0x9d, 0xd9, 0xaf, 0xb1, 0x27, 0xaf, 0xe3, 0x5d, 0x1e, 0x3a, 0x30, 0x54, 0x61, 0x60, 0xe8, 0xc3, 0x26, 0x3a, 0xbc, 0x7e, 0xf5, 0x81, 0xdd, 0x64, 0x01, 0x04, 0xeb, 0xc0, 0x1e}} ,
- {{0xda, 0x2c, 0xa4, 0xd1, 0xa1, 0xc3, 0x5c, 0x6e, 0x32, 0x07, 0x1f, 0xb8, 0x0e, 0x19, 0x9e, 0x99, 0x29, 0x33, 0x9a, 0xae, 0x7a, 0xed, 0x68, 0x42, 0x69, 0x7c, 0x07, 0xb3, 0x38, 0x2c, 0xf6, 0x3d}}},
-{{{0x64, 0xaa, 0xb5, 0x88, 0x79, 0x65, 0x38, 0x8c, 0x94, 0xd6, 0x62, 0x37, 0x7d, 0x64, 0xcd, 0x3a, 0xeb, 0xff, 0xe8, 0x81, 0x09, 0xc7, 0x6a, 0x50, 0x09, 0x0d, 0x28, 0x03, 0x0d, 0x9a, 0x93, 0x0a}} ,
- {{0x42, 0xa3, 0xf1, 0xc5, 0xb4, 0x0f, 0xd8, 0xc8, 0x8d, 0x15, 0x31, 0xbd, 0xf8, 0x07, 0x8b, 0xcd, 0x08, 0x8a, 0xfb, 0x18, 0x07, 0xfe, 0x8e, 0x52, 0x86, 0xef, 0xbe, 0xec, 0x49, 0x52, 0x99, 0x08}}},
-{{{0x0f, 0xa9, 0xd5, 0x01, 0xaa, 0x48, 0x4f, 0x28, 0x66, 0x32, 0x1a, 0xba, 0x7c, 0xea, 0x11, 0x80, 0x17, 0x18, 0x9b, 0x56, 0x88, 0x25, 0x06, 0x69, 0x12, 0x2c, 0xea, 0x56, 0x69, 0x41, 0x24, 0x19}} ,
- {{0xde, 0x21, 0xf0, 0xda, 0x8a, 0xfb, 0xb1, 0xb8, 0xcd, 0xc8, 0x6a, 0x82, 0x19, 0x73, 0xdb, 0xc7, 0xcf, 0x88, 0xeb, 0x96, 0xee, 0x6f, 0xfb, 0x06, 0xd2, 0xcd, 0x7d, 0x7b, 0x12, 0x28, 0x8e, 0x0c}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0x93, 0x44, 0x97, 0xce, 0x28, 0xff, 0x3a, 0x40, 0xc4, 0xf5, 0xf6, 0x9b, 0xf4, 0x6b, 0x07, 0x84, 0xfb, 0x98, 0xd8, 0xec, 0x8c, 0x03, 0x57, 0xec, 0x49, 0xed, 0x63, 0xb6, 0xaa, 0xff, 0x98, 0x28}} ,
- {{0x3d, 0x16, 0x35, 0xf3, 0x46, 0xbc, 0xb3, 0xf4, 0xc6, 0xb6, 0x4f, 0xfa, 0xf4, 0xa0, 0x13, 0xe6, 0x57, 0x45, 0x93, 0xb9, 0xbc, 0xd6, 0x59, 0xe7, 0x77, 0x94, 0x6c, 0xab, 0x96, 0x3b, 0x4f, 0x09}}},
-{{{0x5a, 0xf7, 0x6b, 0x01, 0x12, 0x4f, 0x51, 0xc1, 0x70, 0x84, 0x94, 0x47, 0xb2, 0x01, 0x6c, 0x71, 0xd7, 0xcc, 0x17, 0x66, 0x0f, 0x59, 0x5d, 0x5d, 0x10, 0x01, 0x57, 0x11, 0xf5, 0xdd, 0xe2, 0x34}} ,
- {{0x26, 0xd9, 0x1f, 0x5c, 0x58, 0xac, 0x8b, 0x03, 0xd2, 0xc3, 0x85, 0x0f, 0x3a, 0xc3, 0x7f, 0x6d, 0x8e, 0x86, 0xcd, 0x52, 0x74, 0x8f, 0x55, 0x77, 0x17, 0xb7, 0x8e, 0xb7, 0x88, 0xea, 0xda, 0x1b}}},
-{{{0xb6, 0xea, 0x0e, 0x40, 0x93, 0x20, 0x79, 0x35, 0x6a, 0x61, 0x84, 0x5a, 0x07, 0x6d, 0xf9, 0x77, 0x6f, 0xed, 0x69, 0x1c, 0x0d, 0x25, 0x76, 0xcc, 0xf0, 0xdb, 0xbb, 0xc5, 0xad, 0xe2, 0x26, 0x57}} ,
- {{0xcf, 0xe8, 0x0e, 0x6b, 0x96, 0x7d, 0xed, 0x27, 0xd1, 0x3c, 0xa9, 0xd9, 0x50, 0xa9, 0x98, 0x84, 0x5e, 0x86, 0xef, 0xd6, 0xf0, 0xf8, 0x0e, 0x89, 0x05, 0x2f, 0xd9, 0x5f, 0x15, 0x5f, 0x73, 0x79}}},
-{{{0xc8, 0x5c, 0x16, 0xfe, 0xed, 0x9f, 0x26, 0x56, 0xf6, 0x4b, 0x9f, 0xa7, 0x0a, 0x85, 0xfe, 0xa5, 0x8c, 0x87, 0xdd, 0x98, 0xce, 0x4e, 0xc3, 0x58, 0x55, 0xb2, 0x7b, 0x3d, 0xd8, 0x6b, 0xb5, 0x4c}} ,
- {{0x65, 0x38, 0xa0, 0x15, 0xfa, 0xa7, 0xb4, 0x8f, 0xeb, 0xc4, 0x86, 0x9b, 0x30, 0xa5, 0x5e, 0x4d, 0xea, 0x8a, 0x9a, 0x9f, 0x1a, 0xd8, 0x5b, 0x53, 0x14, 0x19, 0x25, 0x63, 0xb4, 0x6f, 0x1f, 0x5d}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0xac, 0x8f, 0xbc, 0x1e, 0x7d, 0x8b, 0x5a, 0x0b, 0x8d, 0xaf, 0x76, 0x2e, 0x71, 0xe3, 0x3b, 0x6f, 0x53, 0x2f, 0x3e, 0x90, 0x95, 0xd4, 0x35, 0x14, 0x4f, 0x8c, 0x3c, 0xce, 0x57, 0x1c, 0x76, 0x49}} ,
- {{0xa8, 0x50, 0xe1, 0x61, 0x6b, 0x57, 0x35, 0xeb, 0x44, 0x0b, 0x0c, 0x6e, 0xf9, 0x25, 0x80, 0x74, 0xf2, 0x8f, 0x6f, 0x7a, 0x3e, 0x7f, 0x2d, 0xf3, 0x4e, 0x09, 0x65, 0x10, 0x5e, 0x03, 0x25, 0x32}}},
-{{{0xa9, 0x60, 0xdc, 0x0f, 0x64, 0xe5, 0x1d, 0xe2, 0x8d, 0x4f, 0x79, 0x2f, 0x0e, 0x24, 0x02, 0x00, 0x05, 0x77, 0x43, 0x25, 0x3d, 0x6a, 0xc7, 0xb7, 0xbf, 0x04, 0x08, 0x65, 0xf4, 0x39, 0x4b, 0x65}} ,
- {{0x96, 0x19, 0x12, 0x6b, 0x6a, 0xb7, 0xe3, 0xdc, 0x45, 0x9b, 0xdb, 0xb4, 0xa8, 0xae, 0xdc, 0xa8, 0x14, 0x44, 0x65, 0x62, 0xce, 0x34, 0x9a, 0x84, 0x18, 0x12, 0x01, 0xf1, 0xe2, 0x7b, 0xce, 0x50}}},
-{{{0x41, 0x21, 0x30, 0x53, 0x1b, 0x47, 0x01, 0xb7, 0x18, 0xd8, 0x82, 0x57, 0xbd, 0xa3, 0x60, 0xf0, 0x32, 0xf6, 0x5b, 0xf0, 0x30, 0x88, 0x91, 0x59, 0xfd, 0x90, 0xa2, 0xb9, 0x55, 0x93, 0x21, 0x34}} ,
- {{0x97, 0x67, 0x9e, 0xeb, 0x6a, 0xf9, 0x6e, 0xd6, 0x73, 0xe8, 0x6b, 0x29, 0xec, 0x63, 0x82, 0x00, 0xa8, 0x99, 0x1c, 0x1d, 0x30, 0xc8, 0x90, 0x52, 0x90, 0xb6, 0x6a, 0x80, 0x4e, 0xff, 0x4b, 0x51}}},
-{{{0x0f, 0x7d, 0x63, 0x8c, 0x6e, 0x5c, 0xde, 0x30, 0xdf, 0x65, 0xfa, 0x2e, 0xb0, 0xa3, 0x25, 0x05, 0x54, 0xbd, 0x25, 0xba, 0x06, 0xae, 0xdf, 0x8b, 0xd9, 0x1b, 0xea, 0x38, 0xb3, 0x05, 0x16, 0x09}} ,
- {{0xc7, 0x8c, 0xbf, 0x64, 0x28, 0xad, 0xf8, 0xa5, 0x5a, 0x6f, 0xc9, 0xba, 0xd5, 0x7f, 0xd5, 0xd6, 0xbd, 0x66, 0x2f, 0x3d, 0xaa, 0x54, 0xf6, 0xba, 0x32, 0x22, 0x9a, 0x1e, 0x52, 0x05, 0xf4, 0x1d}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0xaa, 0x1f, 0xbb, 0xeb, 0xfe, 0xe4, 0x87, 0xfc, 0xb1, 0x2c, 0xb7, 0x88, 0xf4, 0xc6, 0xb9, 0xf5, 0x24, 0x46, 0xf2, 0xa5, 0x9f, 0x8f, 0x8a, 0x93, 0x70, 0x69, 0xd4, 0x56, 0xec, 0xfd, 0x06, 0x46}} ,
- {{0x4e, 0x66, 0xcf, 0x4e, 0x34, 0xce, 0x0c, 0xd9, 0xa6, 0x50, 0xd6, 0x5e, 0x95, 0xaf, 0xe9, 0x58, 0xfa, 0xee, 0x9b, 0xb8, 0xa5, 0x0f, 0x35, 0xe0, 0x43, 0x82, 0x6d, 0x65, 0xe6, 0xd9, 0x00, 0x0f}}},
-{{{0x7b, 0x75, 0x3a, 0xfc, 0x64, 0xd3, 0x29, 0x7e, 0xdd, 0x49, 0x9a, 0x59, 0x53, 0xbf, 0xb4, 0xa7, 0x52, 0xb3, 0x05, 0xab, 0xc3, 0xaf, 0x16, 0x1a, 0x85, 0x42, 0x32, 0xa2, 0x86, 0xfa, 0x39, 0x43}} ,
- {{0x0e, 0x4b, 0xa3, 0x63, 0x8a, 0xfe, 0xa5, 0x58, 0xf1, 0x13, 0xbd, 0x9d, 0xaa, 0x7f, 0x76, 0x40, 0x70, 0x81, 0x10, 0x75, 0x99, 0xbb, 0xbe, 0x0b, 0x16, 0xe9, 0xba, 0x62, 0x34, 0xcc, 0x07, 0x6d}}},
-{{{0xc3, 0xf1, 0xc6, 0x93, 0x65, 0xee, 0x0b, 0xbc, 0xea, 0x14, 0xf0, 0xc1, 0xf8, 0x84, 0x89, 0xc2, 0xc9, 0xd7, 0xea, 0x34, 0xca, 0xa7, 0xc4, 0x99, 0xd5, 0x50, 0x69, 0xcb, 0xd6, 0x21, 0x63, 0x7c}} ,
- {{0x99, 0xeb, 0x7c, 0x31, 0x73, 0x64, 0x67, 0x7f, 0x0c, 0x66, 0xaa, 0x8c, 0x69, 0x91, 0xe2, 0x26, 0xd3, 0x23, 0xe2, 0x76, 0x5d, 0x32, 0x52, 0xdf, 0x5d, 0xc5, 0x8f, 0xb7, 0x7c, 0x84, 0xb3, 0x70}}},
-{{{0xeb, 0x01, 0xc7, 0x36, 0x97, 0x4e, 0xb6, 0xab, 0x5f, 0x0d, 0x2c, 0xba, 0x67, 0x64, 0x55, 0xde, 0xbc, 0xff, 0xa6, 0xec, 0x04, 0xd3, 0x8d, 0x39, 0x56, 0x5e, 0xee, 0xf8, 0xe4, 0x2e, 0x33, 0x62}} ,
- {{0x65, 0xef, 0xb8, 0x9f, 0xc8, 0x4b, 0xa7, 0xfd, 0x21, 0x49, 0x9b, 0x92, 0x35, 0x82, 0xd6, 0x0a, 0x9b, 0xf2, 0x79, 0xf1, 0x47, 0x2f, 0x6a, 0x7e, 0x9f, 0xcf, 0x18, 0x02, 0x3c, 0xfb, 0x1b, 0x3e}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0x2f, 0x8b, 0xc8, 0x40, 0x51, 0xd1, 0xac, 0x1a, 0x0b, 0xe4, 0xa9, 0xa2, 0x42, 0x21, 0x19, 0x2f, 0x7b, 0x97, 0xbf, 0xf7, 0x57, 0x6d, 0x3f, 0x3d, 0x4f, 0x0f, 0xe2, 0xb2, 0x81, 0x00, 0x9e, 0x7b}} ,
- {{0x8c, 0x85, 0x2b, 0xc4, 0xfc, 0xf1, 0xab, 0xe8, 0x79, 0x22, 0xc4, 0x84, 0x17, 0x3a, 0xfa, 0x86, 0xa6, 0x7d, 0xf9, 0xf3, 0x6f, 0x03, 0x57, 0x20, 0x4d, 0x79, 0xf9, 0x6e, 0x71, 0x54, 0x38, 0x09}}},
-{{{0x40, 0x29, 0x74, 0xa8, 0x2f, 0x5e, 0xf9, 0x79, 0xa4, 0xf3, 0x3e, 0xb9, 0xfd, 0x33, 0x31, 0xac, 0x9a, 0x69, 0x88, 0x1e, 0x77, 0x21, 0x2d, 0xf3, 0x91, 0x52, 0x26, 0x15, 0xb2, 0xa6, 0xcf, 0x7e}} ,
- {{0xc6, 0x20, 0x47, 0x6c, 0xa4, 0x7d, 0xcb, 0x63, 0xea, 0x5b, 0x03, 0xdf, 0x3e, 0x88, 0x81, 0x6d, 0xce, 0x07, 0x42, 0x18, 0x60, 0x7e, 0x7b, 0x55, 0xfe, 0x6a, 0xf3, 0xda, 0x5c, 0x8b, 0x95, 0x10}}},
-{{{0x62, 0xe4, 0x0d, 0x03, 0xb4, 0xd7, 0xcd, 0xfa, 0xbd, 0x46, 0xdf, 0x93, 0x71, 0x10, 0x2c, 0xa8, 0x3b, 0xb6, 0x09, 0x05, 0x70, 0x84, 0x43, 0x29, 0xa8, 0x59, 0xf5, 0x8e, 0x10, 0xe4, 0xd7, 0x20}} ,
- {{0x57, 0x82, 0x1c, 0xab, 0xbf, 0x62, 0x70, 0xe8, 0xc4, 0xcf, 0xf0, 0x28, 0x6e, 0x16, 0x3c, 0x08, 0x78, 0x89, 0x85, 0x46, 0x0f, 0xf6, 0x7f, 0xcf, 0xcb, 0x7e, 0xb8, 0x25, 0xe9, 0x5a, 0xfa, 0x03}}},
-{{{0xfb, 0x95, 0x92, 0x63, 0x50, 0xfc, 0x62, 0xf0, 0xa4, 0x5e, 0x8c, 0x18, 0xc2, 0x17, 0x24, 0xb7, 0x78, 0xc2, 0xa9, 0xe7, 0x6a, 0x32, 0xd6, 0x29, 0x85, 0xaf, 0xcb, 0x8d, 0x91, 0x13, 0xda, 0x6b}} ,
- {{0x36, 0x0a, 0xc2, 0xb6, 0x4b, 0xa5, 0x5d, 0x07, 0x17, 0x41, 0x31, 0x5f, 0x62, 0x46, 0xf8, 0x92, 0xf9, 0x66, 0x48, 0x73, 0xa6, 0x97, 0x0d, 0x7d, 0x88, 0xee, 0x62, 0xb1, 0x03, 0xa8, 0x3f, 0x2c}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0x4a, 0xb1, 0x70, 0x8a, 0xa9, 0xe8, 0x63, 0x79, 0x00, 0xe2, 0x25, 0x16, 0xca, 0x4b, 0x0f, 0xa4, 0x66, 0xad, 0x19, 0x9f, 0x88, 0x67, 0x0c, 0x8b, 0xc2, 0x4a, 0x5b, 0x2b, 0x6d, 0x95, 0xaf, 0x19}} ,
- {{0x8b, 0x9d, 0xb6, 0xcc, 0x60, 0xb4, 0x72, 0x4f, 0x17, 0x69, 0x5a, 0x4a, 0x68, 0x34, 0xab, 0xa1, 0x45, 0x32, 0x3c, 0x83, 0x87, 0x72, 0x30, 0x54, 0x77, 0x68, 0xae, 0xfb, 0xb5, 0x8b, 0x22, 0x5e}}},
-{{{0xf1, 0xb9, 0x87, 0x35, 0xc5, 0xbb, 0xb9, 0xcf, 0xf5, 0xd6, 0xcd, 0xd5, 0x0c, 0x7c, 0x0e, 0xe6, 0x90, 0x34, 0xfb, 0x51, 0x42, 0x1e, 0x6d, 0xac, 0x9a, 0x46, 0xc4, 0x97, 0x29, 0x32, 0xbf, 0x45}} ,
- {{0x66, 0x9e, 0xc6, 0x24, 0xc0, 0xed, 0xa5, 0x5d, 0x88, 0xd4, 0xf0, 0x73, 0x97, 0x7b, 0xea, 0x7f, 0x42, 0xff, 0x21, 0xa0, 0x9b, 0x2f, 0x9a, 0xfd, 0x53, 0x57, 0x07, 0x84, 0x48, 0x88, 0x9d, 0x52}}},
-{{{0xc6, 0x96, 0x48, 0x34, 0x2a, 0x06, 0xaf, 0x94, 0x3d, 0xf4, 0x1a, 0xcf, 0xf2, 0xc0, 0x21, 0xc2, 0x42, 0x5e, 0xc8, 0x2f, 0x35, 0xa2, 0x3e, 0x29, 0xfa, 0x0c, 0x84, 0xe5, 0x89, 0x72, 0x7c, 0x06}} ,
- {{0x32, 0x65, 0x03, 0xe5, 0x89, 0xa6, 0x6e, 0xb3, 0x5b, 0x8e, 0xca, 0xeb, 0xfe, 0x22, 0x56, 0x8b, 0x5d, 0x14, 0x4b, 0x4d, 0xf9, 0xbe, 0xb5, 0xf5, 0xe6, 0x5c, 0x7b, 0x8b, 0xf4, 0x13, 0x11, 0x34}}},
-{{{0x07, 0xc6, 0x22, 0x15, 0xe2, 0x9c, 0x60, 0xa2, 0x19, 0xd9, 0x27, 0xae, 0x37, 0x4e, 0xa6, 0xc9, 0x80, 0xa6, 0x91, 0x8f, 0x12, 0x49, 0xe5, 0x00, 0x18, 0x47, 0xd1, 0xd7, 0x28, 0x22, 0x63, 0x39}} ,
- {{0xe8, 0xe2, 0x00, 0x7e, 0xf2, 0x9e, 0x1e, 0x99, 0x39, 0x95, 0x04, 0xbd, 0x1e, 0x67, 0x7b, 0xb2, 0x26, 0xac, 0xe6, 0xaa, 0xe2, 0x46, 0xd5, 0xe4, 0xe8, 0x86, 0xbd, 0xab, 0x7c, 0x55, 0x59, 0x6f}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0x24, 0x64, 0x6e, 0x9b, 0x35, 0x71, 0x78, 0xce, 0x33, 0x03, 0x21, 0x33, 0x36, 0xf1, 0x73, 0x9b, 0xb9, 0x15, 0x8b, 0x2c, 0x69, 0xcf, 0x4d, 0xed, 0x4f, 0x4d, 0x57, 0x14, 0x13, 0x82, 0xa4, 0x4d}} ,
- {{0x65, 0x6e, 0x0a, 0xa4, 0x59, 0x07, 0x17, 0xf2, 0x6b, 0x4a, 0x1f, 0x6e, 0xf6, 0xb5, 0xbc, 0x62, 0xe4, 0xb6, 0xda, 0xa2, 0x93, 0xbc, 0x29, 0x05, 0xd2, 0xd2, 0x73, 0x46, 0x03, 0x16, 0x40, 0x31}}},
-{{{0x4c, 0x73, 0x6d, 0x15, 0xbd, 0xa1, 0x4d, 0x5c, 0x13, 0x0b, 0x24, 0x06, 0x98, 0x78, 0x1c, 0x5b, 0xeb, 0x1f, 0x18, 0x54, 0x43, 0xd9, 0x55, 0x66, 0xda, 0x29, 0x21, 0xe8, 0xb8, 0x3c, 0x42, 0x22}} ,
- {{0xb4, 0xcd, 0x08, 0x6f, 0x15, 0x23, 0x1a, 0x0b, 0x22, 0xed, 0xd1, 0xf1, 0xa7, 0xc7, 0x73, 0x45, 0xf3, 0x9e, 0xce, 0x76, 0xb7, 0xf6, 0x39, 0xb6, 0x8e, 0x79, 0xbe, 0xe9, 0x9b, 0xcf, 0x7d, 0x62}}},
-{{{0x92, 0x5b, 0xfc, 0x72, 0xfd, 0xba, 0xf1, 0xfd, 0xa6, 0x7c, 0x95, 0xe3, 0x61, 0x3f, 0xe9, 0x03, 0xd4, 0x2b, 0xd4, 0x20, 0xd9, 0xdb, 0x4d, 0x32, 0x3e, 0xf5, 0x11, 0x64, 0xe3, 0xb4, 0xbe, 0x32}} ,
- {{0x86, 0x17, 0x90, 0xe7, 0xc9, 0x1f, 0x10, 0xa5, 0x6a, 0x2d, 0x39, 0xd0, 0x3b, 0xc4, 0xa6, 0xe9, 0x59, 0x13, 0xda, 0x1a, 0xe6, 0xa0, 0xb9, 0x3c, 0x50, 0xb8, 0x40, 0x7c, 0x15, 0x36, 0x5a, 0x42}}},
-{{{0xb4, 0x0b, 0x32, 0xab, 0xdc, 0x04, 0x51, 0x55, 0x21, 0x1e, 0x0b, 0x75, 0x99, 0x89, 0x73, 0x35, 0x3a, 0x91, 0x2b, 0xfe, 0xe7, 0x49, 0xea, 0x76, 0xc1, 0xf9, 0x46, 0xb9, 0x53, 0x02, 0x23, 0x04}} ,
- {{0xfc, 0x5a, 0x1e, 0x1d, 0x74, 0x58, 0x95, 0xa6, 0x8f, 0x7b, 0x97, 0x3e, 0x17, 0x3b, 0x79, 0x2d, 0xa6, 0x57, 0xef, 0x45, 0x02, 0x0b, 0x4d, 0x6e, 0x9e, 0x93, 0x8d, 0x2f, 0xd9, 0x9d, 0xdb, 0x04}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0xc0, 0xd7, 0x56, 0x97, 0x58, 0x91, 0xde, 0x09, 0x4f, 0x9f, 0xbe, 0x63, 0xb0, 0x83, 0x86, 0x43, 0x5d, 0xbc, 0xe0, 0xf3, 0xc0, 0x75, 0xbf, 0x8b, 0x8e, 0xaa, 0xf7, 0x8b, 0x64, 0x6e, 0xb0, 0x63}} ,
- {{0x16, 0xae, 0x8b, 0xe0, 0x9b, 0x24, 0x68, 0x5c, 0x44, 0xc2, 0xd0, 0x08, 0xb7, 0x7b, 0x62, 0xfd, 0x7f, 0xd8, 0xd4, 0xb7, 0x50, 0xfd, 0x2c, 0x1b, 0xbf, 0x41, 0x95, 0xd9, 0x8e, 0xd8, 0x17, 0x1b}}},
-{{{0x86, 0x55, 0x37, 0x8e, 0xc3, 0x38, 0x48, 0x14, 0xb5, 0x97, 0xd2, 0xa7, 0x54, 0x45, 0xf1, 0x35, 0x44, 0x38, 0x9e, 0xf1, 0x1b, 0xb6, 0x34, 0x00, 0x3c, 0x96, 0xee, 0x29, 0x00, 0xea, 0x2c, 0x0b}} ,
- {{0xea, 0xda, 0x99, 0x9e, 0x19, 0x83, 0x66, 0x6d, 0xe9, 0x76, 0x87, 0x50, 0xd1, 0xfd, 0x3c, 0x60, 0x87, 0xc6, 0x41, 0xd9, 0x8e, 0xdb, 0x5e, 0xde, 0xaa, 0x9a, 0xd3, 0x28, 0xda, 0x95, 0xea, 0x47}}},
-{{{0xd0, 0x80, 0xba, 0x19, 0xae, 0x1d, 0xa9, 0x79, 0xf6, 0x3f, 0xac, 0x5d, 0x6f, 0x96, 0x1f, 0x2a, 0xce, 0x29, 0xb2, 0xff, 0x37, 0xf1, 0x94, 0x8f, 0x0c, 0xb5, 0x28, 0xba, 0x9a, 0x21, 0xf6, 0x66}} ,
- {{0x02, 0xfb, 0x54, 0xb8, 0x05, 0xf3, 0x81, 0x52, 0x69, 0x34, 0x46, 0x9d, 0x86, 0x76, 0x8f, 0xd7, 0xf8, 0x6a, 0x66, 0xff, 0xe6, 0xa7, 0x90, 0xf7, 0x5e, 0xcd, 0x6a, 0x9b, 0x55, 0xfc, 0x9d, 0x48}}},
-{{{0xbd, 0xaa, 0x13, 0xe6, 0xcd, 0x45, 0x4a, 0xa4, 0x59, 0x0a, 0x64, 0xb1, 0x98, 0xd6, 0x34, 0x13, 0x04, 0xe6, 0x97, 0x94, 0x06, 0xcb, 0xd4, 0x4e, 0xbb, 0x96, 0xcd, 0xd1, 0x57, 0xd1, 0xe3, 0x06}} ,
- {{0x7a, 0x6c, 0x45, 0x27, 0xc4, 0x93, 0x7f, 0x7d, 0x7c, 0x62, 0x50, 0x38, 0x3a, 0x6b, 0xb5, 0x88, 0xc6, 0xd9, 0xf1, 0x78, 0x19, 0xb9, 0x39, 0x93, 0x3d, 0xc9, 0xe0, 0x9c, 0x3c, 0xce, 0xf5, 0x72}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0x24, 0xea, 0x23, 0x7d, 0x56, 0x2c, 0xe2, 0x59, 0x0e, 0x85, 0x60, 0x04, 0x88, 0x5a, 0x74, 0x1e, 0x4b, 0xef, 0x13, 0xda, 0x4c, 0xff, 0x83, 0x45, 0x85, 0x3f, 0x08, 0x95, 0x2c, 0x20, 0x13, 0x1f}} ,
- {{0x48, 0x5f, 0x27, 0x90, 0x5c, 0x02, 0x42, 0xad, 0x78, 0x47, 0x5c, 0xb5, 0x7e, 0x08, 0x85, 0x00, 0xfa, 0x7f, 0xfd, 0xfd, 0xe7, 0x09, 0x11, 0xf2, 0x7e, 0x1b, 0x38, 0x6c, 0x35, 0x6d, 0x33, 0x66}}},
-{{{0x93, 0x03, 0x36, 0x81, 0xac, 0xe4, 0x20, 0x09, 0x35, 0x4c, 0x45, 0xb2, 0x1e, 0x4c, 0x14, 0x21, 0xe6, 0xe9, 0x8a, 0x7b, 0x8d, 0xfe, 0x1e, 0xc6, 0x3e, 0xc1, 0x35, 0xfa, 0xe7, 0x70, 0x4e, 0x1d}} ,
- {{0x61, 0x2e, 0xc2, 0xdd, 0x95, 0x57, 0xd1, 0xab, 0x80, 0xe8, 0x63, 0x17, 0xb5, 0x48, 0xe4, 0x8a, 0x11, 0x9e, 0x72, 0xbe, 0x85, 0x8d, 0x51, 0x0a, 0xf2, 0x9f, 0xe0, 0x1c, 0xa9, 0x07, 0x28, 0x7b}}},
-{{{0xbb, 0x71, 0x14, 0x5e, 0x26, 0x8c, 0x3d, 0xc8, 0xe9, 0x7c, 0xd3, 0xd6, 0xd1, 0x2f, 0x07, 0x6d, 0xe6, 0xdf, 0xfb, 0x79, 0xd6, 0x99, 0x59, 0x96, 0x48, 0x40, 0x0f, 0x3a, 0x7b, 0xb2, 0xa0, 0x72}} ,
- {{0x4e, 0x3b, 0x69, 0xc8, 0x43, 0x75, 0x51, 0x6c, 0x79, 0x56, 0xe4, 0xcb, 0xf7, 0xa6, 0x51, 0xc2, 0x2c, 0x42, 0x0b, 0xd4, 0x82, 0x20, 0x1c, 0x01, 0x08, 0x66, 0xd7, 0xbf, 0x04, 0x56, 0xfc, 0x02}}},
-{{{0x24, 0xe8, 0xb7, 0x60, 0xae, 0x47, 0x80, 0xfc, 0xe5, 0x23, 0xe7, 0xc2, 0xc9, 0x85, 0xe6, 0x98, 0xa0, 0x29, 0x4e, 0xe1, 0x84, 0x39, 0x2d, 0x95, 0x2c, 0xf3, 0x45, 0x3c, 0xff, 0xaf, 0x27, 0x4c}} ,
- {{0x6b, 0xa6, 0xf5, 0x4b, 0x11, 0xbd, 0xba, 0x5b, 0x9e, 0xc4, 0xa4, 0x51, 0x1e, 0xbe, 0xd0, 0x90, 0x3a, 0x9c, 0xc2, 0x26, 0xb6, 0x1e, 0xf1, 0x95, 0x7d, 0xc8, 0x6d, 0x52, 0xe6, 0x99, 0x2c, 0x5f}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0x85, 0xe0, 0x24, 0x32, 0xb4, 0xd1, 0xef, 0xfc, 0x69, 0xa2, 0xbf, 0x8f, 0x72, 0x2c, 0x95, 0xf6, 0xe4, 0x6e, 0x7d, 0x90, 0xf7, 0x57, 0x81, 0xa0, 0xf7, 0xda, 0xef, 0x33, 0x07, 0xe3, 0x6b, 0x78}} ,
- {{0x36, 0x27, 0x3e, 0xc6, 0x12, 0x07, 0xab, 0x4e, 0xbe, 0x69, 0x9d, 0xb3, 0xbe, 0x08, 0x7c, 0x2a, 0x47, 0x08, 0xfd, 0xd4, 0xcd, 0x0e, 0x27, 0x34, 0x5b, 0x98, 0x34, 0x2f, 0x77, 0x5f, 0x3a, 0x65}}},
-{{{0x13, 0xaa, 0x2e, 0x4c, 0xf0, 0x22, 0xb8, 0x6c, 0xb3, 0x19, 0x4d, 0xeb, 0x6b, 0xd0, 0xa4, 0xc6, 0x9c, 0xdd, 0xc8, 0x5b, 0x81, 0x57, 0x89, 0xdf, 0x33, 0xa9, 0x68, 0x49, 0x80, 0xe4, 0xfe, 0x21}} ,
- {{0x00, 0x17, 0x90, 0x30, 0xe9, 0xd3, 0x60, 0x30, 0x31, 0xc2, 0x72, 0x89, 0x7a, 0x36, 0xa5, 0xbd, 0x39, 0x83, 0x85, 0x50, 0xa1, 0x5d, 0x6c, 0x41, 0x1d, 0xb5, 0x2c, 0x07, 0x40, 0x77, 0x0b, 0x50}}},
-{{{0x64, 0x34, 0xec, 0xc0, 0x9e, 0x44, 0x41, 0xaf, 0xa0, 0x36, 0x05, 0x6d, 0xea, 0x30, 0x25, 0x46, 0x35, 0x24, 0x9d, 0x86, 0xbd, 0x95, 0xf1, 0x6a, 0x46, 0xd7, 0x94, 0x54, 0xf9, 0x3b, 0xbd, 0x5d}} ,
- {{0x77, 0x5b, 0xe2, 0x37, 0xc7, 0xe1, 0x7c, 0x13, 0x8c, 0x9f, 0x7b, 0x7b, 0x2a, 0xce, 0x42, 0xa3, 0xb9, 0x2a, 0x99, 0xa8, 0xc0, 0xd8, 0x3c, 0x86, 0xb0, 0xfb, 0xe9, 0x76, 0x77, 0xf7, 0xf5, 0x56}}},
-{{{0xdf, 0xb3, 0x46, 0x11, 0x6e, 0x13, 0xb7, 0x28, 0x4e, 0x56, 0xdd, 0xf1, 0xac, 0xad, 0x58, 0xc3, 0xf8, 0x88, 0x94, 0x5e, 0x06, 0x98, 0xa1, 0xe4, 0x6a, 0xfb, 0x0a, 0x49, 0x5d, 0x8a, 0xfe, 0x77}} ,
- {{0x46, 0x02, 0xf5, 0xa5, 0xaf, 0xc5, 0x75, 0x6d, 0xba, 0x45, 0x35, 0x0a, 0xfe, 0xc9, 0xac, 0x22, 0x91, 0x8d, 0x21, 0x95, 0x33, 0x03, 0xc0, 0x8a, 0x16, 0xf3, 0x39, 0xe0, 0x01, 0x0f, 0x53, 0x3c}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0x34, 0x75, 0x37, 0x1f, 0x34, 0x4e, 0xa9, 0x1d, 0x68, 0x67, 0xf8, 0x49, 0x98, 0x96, 0xfc, 0x4c, 0x65, 0x97, 0xf7, 0x02, 0x4a, 0x52, 0x6c, 0x01, 0xbd, 0x48, 0xbb, 0x1b, 0xed, 0xa4, 0xe2, 0x53}} ,
- {{0x59, 0xd5, 0x9b, 0x5a, 0xa2, 0x90, 0xd3, 0xb8, 0x37, 0x4c, 0x55, 0x82, 0x28, 0x08, 0x0f, 0x7f, 0xaa, 0x81, 0x65, 0xe0, 0x0c, 0x52, 0xc9, 0xa3, 0x32, 0x27, 0x64, 0xda, 0xfd, 0x34, 0x23, 0x5a}}},
-{{{0xb5, 0xb0, 0x0c, 0x4d, 0xb3, 0x7b, 0x23, 0xc8, 0x1f, 0x8a, 0x39, 0x66, 0xe6, 0xba, 0x4c, 0x10, 0x37, 0xca, 0x9c, 0x7c, 0x05, 0x9e, 0xff, 0xc0, 0xf8, 0x8e, 0xb1, 0x8f, 0x6f, 0x67, 0x18, 0x26}} ,
- {{0x4b, 0x41, 0x13, 0x54, 0x23, 0x1a, 0xa4, 0x4e, 0xa9, 0x8b, 0x1e, 0x4b, 0xfc, 0x15, 0x24, 0xbb, 0x7e, 0xcb, 0xb6, 0x1e, 0x1b, 0xf5, 0xf2, 0xc8, 0x56, 0xec, 0x32, 0xa2, 0x60, 0x5b, 0xa0, 0x2a}}},
-{{{0xa4, 0x29, 0x47, 0x86, 0x2e, 0x92, 0x4f, 0x11, 0x4f, 0xf3, 0xb2, 0x5c, 0xd5, 0x3e, 0xa6, 0xb9, 0xc8, 0xe2, 0x33, 0x11, 0x1f, 0x01, 0x8f, 0xb0, 0x9b, 0xc7, 0xa5, 0xff, 0x83, 0x0f, 0x1e, 0x28}} ,
- {{0x1d, 0x29, 0x7a, 0xa1, 0xec, 0x8e, 0xb5, 0xad, 0xea, 0x02, 0x68, 0x60, 0x74, 0x29, 0x1c, 0xa5, 0xcf, 0xc8, 0x3b, 0x7d, 0x8b, 0x2b, 0x7c, 0xad, 0xa4, 0x40, 0x17, 0x51, 0x59, 0x7c, 0x2e, 0x5d}}},
-{{{0x0a, 0x6c, 0x4f, 0xbc, 0x3e, 0x32, 0xe7, 0x4a, 0x1a, 0x13, 0xc1, 0x49, 0x38, 0xbf, 0xf7, 0xc2, 0xd3, 0x8f, 0x6b, 0xad, 0x52, 0xf7, 0xcf, 0xbc, 0x27, 0xcb, 0x40, 0x67, 0x76, 0xcd, 0x6d, 0x56}} ,
- {{0xe5, 0xb0, 0x27, 0xad, 0xbe, 0x9b, 0xf2, 0xb5, 0x63, 0xde, 0x3a, 0x23, 0x95, 0xb7, 0x0a, 0x7e, 0xf3, 0x9e, 0x45, 0x6f, 0x19, 0x39, 0x75, 0x8f, 0x39, 0x3d, 0x0f, 0xc0, 0x9f, 0xf1, 0xe9, 0x51}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0x88, 0xaa, 0x14, 0x24, 0x86, 0x94, 0x11, 0x12, 0x3e, 0x1a, 0xb5, 0xcc, 0xbb, 0xe0, 0x9c, 0xd5, 0x9c, 0x6d, 0xba, 0x58, 0x72, 0x8d, 0xfb, 0x22, 0x7b, 0x9f, 0x7c, 0x94, 0x30, 0xb3, 0x51, 0x21}} ,
- {{0xf6, 0x74, 0x3d, 0xf2, 0xaf, 0xd0, 0x1e, 0x03, 0x7c, 0x23, 0x6b, 0xc9, 0xfc, 0x25, 0x70, 0x90, 0xdc, 0x9a, 0xa4, 0xfb, 0x49, 0xfc, 0x3d, 0x0a, 0x35, 0x38, 0x6f, 0xe4, 0x7e, 0x50, 0x01, 0x2a}}},
-{{{0xd6, 0xe3, 0x96, 0x61, 0x3a, 0xfd, 0xef, 0x9b, 0x1f, 0x90, 0xa4, 0x24, 0x14, 0x5b, 0xc8, 0xde, 0x50, 0xb1, 0x1d, 0xaf, 0xe8, 0x55, 0x8a, 0x87, 0x0d, 0xfe, 0xaa, 0x3b, 0x82, 0x2c, 0x8d, 0x7b}} ,
- {{0x85, 0x0c, 0xaf, 0xf8, 0x83, 0x44, 0x49, 0xd9, 0x45, 0xcf, 0xf7, 0x48, 0xd9, 0x53, 0xb4, 0xf1, 0x65, 0xa0, 0xe1, 0xc3, 0xb3, 0x15, 0xed, 0x89, 0x9b, 0x4f, 0x62, 0xb3, 0x57, 0xa5, 0x45, 0x1c}}},
-{{{0x8f, 0x12, 0xea, 0xaf, 0xd1, 0x1f, 0x79, 0x10, 0x0b, 0xf6, 0xa3, 0x7b, 0xea, 0xac, 0x8b, 0x57, 0x32, 0x62, 0xe7, 0x06, 0x12, 0x51, 0xa0, 0x3b, 0x43, 0x5e, 0xa4, 0x20, 0x78, 0x31, 0xce, 0x0d}} ,
- {{0x84, 0x7c, 0xc2, 0xa6, 0x91, 0x23, 0xce, 0xbd, 0xdc, 0xf9, 0xce, 0xd5, 0x75, 0x30, 0x22, 0xe6, 0xf9, 0x43, 0x62, 0x0d, 0xf7, 0x75, 0x9d, 0x7f, 0x8c, 0xff, 0x7d, 0xe4, 0x72, 0xac, 0x9f, 0x1c}}},
-{{{0x88, 0xc1, 0x99, 0xd0, 0x3c, 0x1c, 0x5d, 0xb4, 0xef, 0x13, 0x0f, 0x90, 0xb9, 0x36, 0x2f, 0x95, 0x95, 0xc6, 0xdc, 0xde, 0x0a, 0x51, 0xe2, 0x8d, 0xf3, 0xbc, 0x51, 0xec, 0xdf, 0xb1, 0xa2, 0x5f}} ,
- {{0x2e, 0x68, 0xa1, 0x23, 0x7d, 0x9b, 0x40, 0x69, 0x85, 0x7b, 0x42, 0xbf, 0x90, 0x4b, 0xd6, 0x40, 0x2f, 0xd7, 0x52, 0x52, 0xb2, 0x21, 0xde, 0x64, 0xbd, 0x88, 0xc3, 0x6d, 0xa5, 0xfa, 0x81, 0x3f}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0xfb, 0xfd, 0x47, 0x7b, 0x8a, 0x66, 0x9e, 0x79, 0x2e, 0x64, 0x82, 0xef, 0xf7, 0x21, 0xec, 0xf6, 0xd8, 0x86, 0x09, 0x31, 0x7c, 0xdd, 0x03, 0x6a, 0x58, 0xa0, 0x77, 0xb7, 0x9b, 0x8c, 0x87, 0x1f}} ,
- {{0x55, 0x47, 0xe4, 0xa8, 0x3d, 0x55, 0x21, 0x34, 0xab, 0x1d, 0xae, 0xe0, 0xf4, 0xea, 0xdb, 0xc5, 0xb9, 0x58, 0xbf, 0xc4, 0x2a, 0x89, 0x31, 0x1a, 0xf4, 0x2d, 0xe1, 0xca, 0x37, 0x99, 0x47, 0x59}}},
-{{{0xc7, 0xca, 0x63, 0xc1, 0x49, 0xa9, 0x35, 0x45, 0x55, 0x7e, 0xda, 0x64, 0x32, 0x07, 0x50, 0xf7, 0x32, 0xac, 0xde, 0x75, 0x58, 0x9b, 0x11, 0xb2, 0x3a, 0x1f, 0xf5, 0xf7, 0x79, 0x04, 0xe6, 0x08}} ,
- {{0x46, 0xfa, 0x22, 0x4b, 0xfa, 0xe1, 0xfe, 0x96, 0xfc, 0x67, 0xba, 0x67, 0x97, 0xc4, 0xe7, 0x1b, 0x86, 0x90, 0x5f, 0xee, 0xf4, 0x5b, 0x11, 0xb2, 0xcd, 0xad, 0xee, 0xc2, 0x48, 0x6c, 0x2b, 0x1b}}},
-{{{0xe3, 0x39, 0x62, 0xb4, 0x4f, 0x31, 0x04, 0xc9, 0xda, 0xd5, 0x73, 0x51, 0x57, 0xc5, 0xb8, 0xf3, 0xa3, 0x43, 0x70, 0xe4, 0x61, 0x81, 0x84, 0xe2, 0xbb, 0xbf, 0x4f, 0x9e, 0xa4, 0x5e, 0x74, 0x06}} ,
- {{0x29, 0xac, 0xff, 0x27, 0xe0, 0x59, 0xbe, 0x39, 0x9c, 0x0d, 0x83, 0xd7, 0x10, 0x0b, 0x15, 0xb7, 0xe1, 0xc2, 0x2c, 0x30, 0x73, 0x80, 0x3a, 0x7d, 0x5d, 0xab, 0x58, 0x6b, 0xc1, 0xf0, 0xf4, 0x22}}},
-{{{0xfe, 0x7f, 0xfb, 0x35, 0x7d, 0xc6, 0x01, 0x23, 0x28, 0xc4, 0x02, 0xac, 0x1f, 0x42, 0xb4, 0x9d, 0xfc, 0x00, 0x94, 0xa5, 0xee, 0xca, 0xda, 0x97, 0x09, 0x41, 0x77, 0x87, 0x5d, 0x7b, 0x87, 0x78}} ,
- {{0xf5, 0xfb, 0x90, 0x2d, 0x81, 0x19, 0x9e, 0x2f, 0x6d, 0x85, 0x88, 0x8c, 0x40, 0x5c, 0x77, 0x41, 0x4d, 0x01, 0x19, 0x76, 0x60, 0xe8, 0x4c, 0x48, 0xe4, 0x33, 0x83, 0x32, 0x6c, 0xb4, 0x41, 0x03}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0xff, 0x10, 0xc2, 0x09, 0x4f, 0x6e, 0xf4, 0xd2, 0xdf, 0x7e, 0xca, 0x7b, 0x1c, 0x1d, 0xba, 0xa3, 0xb6, 0xda, 0x67, 0x33, 0xd4, 0x87, 0x36, 0x4b, 0x11, 0x20, 0x05, 0xa6, 0x29, 0xc1, 0x87, 0x17}} ,
- {{0xf6, 0x96, 0xca, 0x2f, 0xda, 0x38, 0xa7, 0x1b, 0xfc, 0xca, 0x7d, 0xfe, 0x08, 0x89, 0xe2, 0x47, 0x2b, 0x6a, 0x5d, 0x4b, 0xfa, 0xa1, 0xb4, 0xde, 0xb6, 0xc2, 0x31, 0x51, 0xf5, 0xe0, 0xa4, 0x0b}}},
-{{{0x5c, 0xe5, 0xc6, 0x04, 0x8e, 0x2b, 0x57, 0xbe, 0x38, 0x85, 0x23, 0xcb, 0xb7, 0xbe, 0x4f, 0xa9, 0xd3, 0x6e, 0x12, 0xaa, 0xd5, 0xb2, 0x2e, 0x93, 0x29, 0x9a, 0x4a, 0x88, 0x18, 0x43, 0xf5, 0x01}} ,
- {{0x50, 0xfc, 0xdb, 0xa2, 0x59, 0x21, 0x8d, 0xbd, 0x7e, 0x33, 0xae, 0x2f, 0x87, 0x1a, 0xd0, 0x97, 0xc7, 0x0d, 0x4d, 0x63, 0x01, 0xef, 0x05, 0x84, 0xec, 0x40, 0xdd, 0xa8, 0x0a, 0x4f, 0x70, 0x0b}}},
-{{{0x41, 0x69, 0x01, 0x67, 0x5c, 0xd3, 0x8a, 0xc5, 0xcf, 0x3f, 0xd1, 0x57, 0xd1, 0x67, 0x3e, 0x01, 0x39, 0xb5, 0xcb, 0x81, 0x56, 0x96, 0x26, 0xb6, 0xc2, 0xe7, 0x5c, 0xfb, 0x63, 0x97, 0x58, 0x06}} ,
- {{0x0c, 0x0e, 0xf3, 0xba, 0xf0, 0xe5, 0xba, 0xb2, 0x57, 0x77, 0xc6, 0x20, 0x9b, 0x89, 0x24, 0xbe, 0xf2, 0x9c, 0x8a, 0xba, 0x69, 0xc1, 0xf1, 0xb0, 0x4f, 0x2a, 0x05, 0x9a, 0xee, 0x10, 0x7e, 0x36}}},
-{{{0x3f, 0x26, 0xe9, 0x40, 0xe9, 0x03, 0xad, 0x06, 0x69, 0x91, 0xe0, 0xd1, 0x89, 0x60, 0x84, 0x79, 0xde, 0x27, 0x6d, 0xe6, 0x76, 0xbd, 0xea, 0xe6, 0xae, 0x48, 0xc3, 0x67, 0xc0, 0x57, 0xcd, 0x2f}} ,
- {{0x7f, 0xc1, 0xdc, 0xb9, 0xc7, 0xbc, 0x86, 0x3d, 0x55, 0x4b, 0x28, 0x7a, 0xfb, 0x4d, 0xc7, 0xf8, 0xbc, 0x67, 0x2a, 0x60, 0x4d, 0x8f, 0x07, 0x0b, 0x1a, 0x17, 0xbf, 0xfa, 0xac, 0xa7, 0x3d, 0x1a}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0x91, 0x3f, 0xed, 0x5e, 0x18, 0x78, 0x3f, 0x23, 0x2c, 0x0d, 0x8c, 0x44, 0x00, 0xe8, 0xfb, 0xe9, 0x8e, 0xd6, 0xd1, 0x36, 0x58, 0x57, 0x9e, 0xae, 0x4b, 0x5c, 0x0b, 0x07, 0xbc, 0x6b, 0x55, 0x2b}} ,
- {{0x6f, 0x4d, 0x17, 0xd7, 0xe1, 0x84, 0xd9, 0x78, 0xb1, 0x90, 0xfd, 0x2e, 0xb3, 0xb5, 0x19, 0x3f, 0x1b, 0xfa, 0xc0, 0x68, 0xb3, 0xdd, 0x00, 0x2e, 0x89, 0xbd, 0x7e, 0x80, 0x32, 0x13, 0xa0, 0x7b}}},
-{{{0x1a, 0x6f, 0x40, 0xaf, 0x44, 0x44, 0xb0, 0x43, 0x8f, 0x0d, 0xd0, 0x1e, 0xc4, 0x0b, 0x19, 0x5d, 0x8e, 0xfe, 0xc1, 0xf3, 0xc5, 0x5c, 0x91, 0xf8, 0x04, 0x4e, 0xbe, 0x90, 0xb4, 0x47, 0x5c, 0x3f}} ,
- {{0xb0, 0x3b, 0x2c, 0xf3, 0xfe, 0x32, 0x71, 0x07, 0x3f, 0xaa, 0xba, 0x45, 0x60, 0xa8, 0x8d, 0xea, 0x54, 0xcb, 0x39, 0x10, 0xb4, 0xf2, 0x8b, 0xd2, 0x14, 0x82, 0x42, 0x07, 0x8e, 0xe9, 0x7c, 0x53}}},
-{{{0xb0, 0xae, 0xc1, 0x8d, 0xc9, 0x8f, 0xb9, 0x7a, 0x77, 0xef, 0xba, 0x79, 0xa0, 0x3c, 0xa8, 0xf5, 0x6a, 0xe2, 0x3f, 0x5d, 0x00, 0xe3, 0x4b, 0x45, 0x24, 0x7b, 0x43, 0x78, 0x55, 0x1d, 0x2b, 0x1e}} ,
- {{0x01, 0xb8, 0xd6, 0x16, 0x67, 0xa0, 0x15, 0xb9, 0xe1, 0x58, 0xa4, 0xa7, 0x31, 0x37, 0x77, 0x2f, 0x8b, 0x12, 0x9f, 0xf4, 0x3f, 0xc7, 0x36, 0x66, 0xd2, 0xa8, 0x56, 0xf7, 0x7f, 0x74, 0xc6, 0x41}}},
-{{{0x5d, 0xf8, 0xb4, 0xa8, 0x30, 0xdd, 0xcc, 0x38, 0xa5, 0xd3, 0xca, 0xd8, 0xd1, 0xf8, 0xb2, 0x31, 0x91, 0xd4, 0x72, 0x05, 0x57, 0x4a, 0x3b, 0x82, 0x4a, 0xc6, 0x68, 0x20, 0xe2, 0x18, 0x41, 0x61}} ,
- {{0x19, 0xd4, 0x8d, 0x47, 0x29, 0x12, 0x65, 0xb0, 0x11, 0x78, 0x47, 0xb5, 0xcb, 0xa3, 0xa5, 0xfa, 0x05, 0x85, 0x54, 0xa9, 0x33, 0x97, 0x8d, 0x2b, 0xc2, 0xfe, 0x99, 0x35, 0x28, 0xe5, 0xeb, 0x63}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0xb1, 0x3f, 0x3f, 0xef, 0xd8, 0xf4, 0xfc, 0xb3, 0xa0, 0x60, 0x50, 0x06, 0x2b, 0x29, 0x52, 0x70, 0x15, 0x0b, 0x24, 0x24, 0xf8, 0x5f, 0x79, 0x18, 0xcc, 0xff, 0x89, 0x99, 0x84, 0xa1, 0xae, 0x13}} ,
- {{0x44, 0x1f, 0xb8, 0xc2, 0x01, 0xc1, 0x30, 0x19, 0x55, 0x05, 0x60, 0x10, 0xa4, 0x6c, 0x2d, 0x67, 0x70, 0xe5, 0x25, 0x1b, 0xf2, 0xbf, 0xdd, 0xfb, 0x70, 0x2b, 0xa1, 0x8c, 0x9c, 0x94, 0x84, 0x08}}},
-{{{0xe7, 0xc4, 0x43, 0x4d, 0xc9, 0x2b, 0x69, 0x5d, 0x1d, 0x3c, 0xaf, 0xbb, 0x43, 0x38, 0x4e, 0x98, 0x3d, 0xed, 0x0d, 0x21, 0x03, 0xfd, 0xf0, 0x99, 0x47, 0x04, 0xb0, 0x98, 0x69, 0x55, 0x72, 0x0f}} ,
- {{0x5e, 0xdf, 0x15, 0x53, 0x3b, 0x86, 0x80, 0xb0, 0xf1, 0x70, 0x68, 0x8f, 0x66, 0x7c, 0x0e, 0x49, 0x1a, 0xd8, 0x6b, 0xfe, 0x4e, 0xef, 0xca, 0x47, 0xd4, 0x03, 0xc1, 0x37, 0x50, 0x9c, 0xc1, 0x16}}},
-{{{0xcd, 0x24, 0xc6, 0x3e, 0x0c, 0x82, 0x9b, 0x91, 0x2b, 0x61, 0x4a, 0xb2, 0x0f, 0x88, 0x55, 0x5f, 0x5a, 0x57, 0xff, 0xe5, 0x74, 0x0b, 0x13, 0x43, 0x00, 0xd8, 0x6b, 0xcf, 0xd2, 0x15, 0x03, 0x2c}} ,
- {{0xdc, 0xff, 0x15, 0x61, 0x2f, 0x4a, 0x2f, 0x62, 0xf2, 0x04, 0x2f, 0xb5, 0x0c, 0xb7, 0x1e, 0x3f, 0x74, 0x1a, 0x0f, 0xd7, 0xea, 0xcd, 0xd9, 0x7d, 0xf6, 0x12, 0x0e, 0x2f, 0xdb, 0x5a, 0x3b, 0x16}}},
-{{{0x1b, 0x37, 0x47, 0xe3, 0xf5, 0x9e, 0xea, 0x2c, 0x2a, 0xe7, 0x82, 0x36, 0xf4, 0x1f, 0x81, 0x47, 0x92, 0x4b, 0x69, 0x0e, 0x11, 0x8c, 0x5d, 0x53, 0x5b, 0x81, 0x27, 0x08, 0xbc, 0xa0, 0xae, 0x25}} ,
- {{0x69, 0x32, 0xa1, 0x05, 0x11, 0x42, 0x00, 0xd2, 0x59, 0xac, 0x4d, 0x62, 0x8b, 0x13, 0xe2, 0x50, 0x5d, 0xa0, 0x9d, 0x9b, 0xfd, 0xbb, 0x12, 0x41, 0x75, 0x41, 0x9e, 0xcc, 0xdc, 0xc7, 0xdc, 0x5d}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0xd9, 0xe3, 0x38, 0x06, 0x46, 0x70, 0x82, 0x5e, 0x28, 0x49, 0x79, 0xff, 0x25, 0xd2, 0x4e, 0x29, 0x8d, 0x06, 0xb0, 0x23, 0xae, 0x9b, 0x66, 0xe4, 0x7d, 0xc0, 0x70, 0x91, 0xa3, 0xfc, 0xec, 0x4e}} ,
- {{0x62, 0x12, 0x37, 0x6a, 0x30, 0xf6, 0x1e, 0xfb, 0x14, 0x5c, 0x0d, 0x0e, 0xb7, 0x81, 0x6a, 0xe7, 0x08, 0x05, 0xac, 0xaa, 0x38, 0x46, 0xe2, 0x73, 0xea, 0x4b, 0x07, 0x81, 0x43, 0x7c, 0x9e, 0x5e}}},
-{{{0xfc, 0xf9, 0x21, 0x4f, 0x2e, 0x76, 0x9b, 0x1f, 0x28, 0x60, 0x77, 0x43, 0x32, 0x9d, 0xbe, 0x17, 0x30, 0x2a, 0xc6, 0x18, 0x92, 0x66, 0x62, 0x30, 0x98, 0x40, 0x11, 0xa6, 0x7f, 0x18, 0x84, 0x28}} ,
- {{0x3f, 0xab, 0xd3, 0xf4, 0x8a, 0x76, 0xa1, 0x3c, 0xca, 0x2d, 0x49, 0xc3, 0xea, 0x08, 0x0b, 0x85, 0x17, 0x2a, 0xc3, 0x6c, 0x08, 0xfd, 0x57, 0x9f, 0x3d, 0x5f, 0xdf, 0x67, 0x68, 0x42, 0x00, 0x32}}},
-{{{0x51, 0x60, 0x1b, 0x06, 0x4f, 0x8a, 0x21, 0xba, 0x38, 0xa8, 0xba, 0xd6, 0x40, 0xf6, 0xe9, 0x9b, 0x76, 0x4d, 0x56, 0x21, 0x5b, 0x0a, 0x9b, 0x2e, 0x4f, 0x3d, 0x81, 0x32, 0x08, 0x9f, 0x97, 0x5b}} ,
- {{0xe5, 0x44, 0xec, 0x06, 0x9d, 0x90, 0x79, 0x9f, 0xd3, 0xe0, 0x79, 0xaf, 0x8f, 0x10, 0xfd, 0xdd, 0x04, 0xae, 0x27, 0x97, 0x46, 0x33, 0x79, 0xea, 0xb8, 0x4e, 0xca, 0x5a, 0x59, 0x57, 0xe1, 0x0e}}},
-{{{0x1a, 0xda, 0xf3, 0xa5, 0x41, 0x43, 0x28, 0xfc, 0x7e, 0xe7, 0x71, 0xea, 0xc6, 0x3b, 0x59, 0xcc, 0x2e, 0xd3, 0x40, 0xec, 0xb3, 0x13, 0x6f, 0x44, 0xcd, 0x13, 0xb2, 0x37, 0xf2, 0x6e, 0xd9, 0x1c}} ,
- {{0xe3, 0xdb, 0x60, 0xcd, 0x5c, 0x4a, 0x18, 0x0f, 0xef, 0x73, 0x36, 0x71, 0x8c, 0xf6, 0x11, 0xb4, 0xd8, 0xce, 0x17, 0x5e, 0x4f, 0x26, 0x77, 0x97, 0x5f, 0xcb, 0xef, 0x91, 0xeb, 0x6a, 0x62, 0x7a}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0x18, 0x4a, 0xa2, 0x97, 0x08, 0x81, 0x2d, 0x83, 0xc4, 0xcc, 0xf0, 0x83, 0x7e, 0xec, 0x0d, 0x95, 0x4c, 0x5b, 0xfb, 0xfa, 0x98, 0x80, 0x4a, 0x66, 0x56, 0x0c, 0x51, 0xb3, 0xf2, 0x04, 0x5d, 0x27}} ,
- {{0x3b, 0xb9, 0xb8, 0x06, 0x5a, 0x2e, 0xfe, 0xc3, 0x82, 0x37, 0x9c, 0xa3, 0x11, 0x1f, 0x9c, 0xa6, 0xda, 0x63, 0x48, 0x9b, 0xad, 0xde, 0x2d, 0xa6, 0xbc, 0x6e, 0x32, 0xda, 0x27, 0x65, 0xdd, 0x57}}},
-{{{0x84, 0x4f, 0x37, 0x31, 0x7d, 0x2e, 0xbc, 0xad, 0x87, 0x07, 0x2a, 0x6b, 0x37, 0xfc, 0x5f, 0xeb, 0x4e, 0x75, 0x35, 0xa6, 0xde, 0xab, 0x0a, 0x19, 0x3a, 0xb7, 0xb1, 0xef, 0x92, 0x6a, 0x3b, 0x3c}} ,
- {{0x3b, 0xb2, 0x94, 0x6d, 0x39, 0x60, 0xac, 0xee, 0xe7, 0x81, 0x1a, 0x3b, 0x76, 0x87, 0x5c, 0x05, 0x94, 0x2a, 0x45, 0xb9, 0x80, 0xe9, 0x22, 0xb1, 0x07, 0xcb, 0x40, 0x9e, 0x70, 0x49, 0x6d, 0x12}}},
-{{{0xfd, 0x18, 0x78, 0x84, 0xa8, 0x4c, 0x7d, 0x6e, 0x59, 0xa6, 0xe5, 0x74, 0xf1, 0x19, 0xa6, 0x84, 0x2e, 0x51, 0xc1, 0x29, 0x13, 0xf2, 0x14, 0x6b, 0x5d, 0x53, 0x51, 0xf7, 0xef, 0xbf, 0x01, 0x22}} ,
- {{0xa4, 0x4b, 0x62, 0x4c, 0xe6, 0xfd, 0x72, 0x07, 0xf2, 0x81, 0xfc, 0xf2, 0xbd, 0x12, 0x7c, 0x68, 0x76, 0x2a, 0xba, 0xf5, 0x65, 0xb1, 0x1f, 0x17, 0x0a, 0x38, 0xb0, 0xbf, 0xc0, 0xf8, 0xf4, 0x2a}}},
-{{{0x55, 0x60, 0x55, 0x5b, 0xe4, 0x1d, 0x71, 0x4c, 0x9d, 0x5b, 0x9f, 0x70, 0xa6, 0x85, 0x9a, 0x2c, 0xa0, 0xe2, 0x32, 0x48, 0xce, 0x9e, 0x2a, 0xa5, 0x07, 0x3b, 0xc7, 0x6c, 0x86, 0x77, 0xde, 0x3c}} ,
- {{0xf7, 0x18, 0x7a, 0x96, 0x7e, 0x43, 0x57, 0xa9, 0x55, 0xfc, 0x4e, 0xb6, 0x72, 0x00, 0xf2, 0xe4, 0xd7, 0x52, 0xd3, 0xd3, 0xb6, 0x85, 0xf6, 0x71, 0xc7, 0x44, 0x3f, 0x7f, 0xd7, 0xb3, 0xf2, 0x79}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0x46, 0xca, 0xa7, 0x55, 0x7b, 0x79, 0xf3, 0xca, 0x5a, 0x65, 0xf6, 0xed, 0x50, 0x14, 0x7b, 0xe4, 0xc4, 0x2a, 0x65, 0x9e, 0xe2, 0xf9, 0xca, 0xa7, 0x22, 0x26, 0x53, 0xcb, 0x21, 0x5b, 0xa7, 0x31}} ,
- {{0x90, 0xd7, 0xc5, 0x26, 0x08, 0xbd, 0xb0, 0x53, 0x63, 0x58, 0xc3, 0x31, 0x5e, 0x75, 0x46, 0x15, 0x91, 0xa6, 0xf8, 0x2f, 0x1a, 0x08, 0x65, 0x88, 0x2f, 0x98, 0x04, 0xf1, 0x7c, 0x6e, 0x00, 0x77}}},
-{{{0x81, 0x21, 0x61, 0x09, 0xf6, 0x4e, 0xf1, 0x92, 0xee, 0x63, 0x61, 0x73, 0x87, 0xc7, 0x54, 0x0e, 0x42, 0x4b, 0xc9, 0x47, 0xd1, 0xb8, 0x7e, 0x91, 0x75, 0x37, 0x99, 0x28, 0xb8, 0xdd, 0x7f, 0x50}} ,
- {{0x89, 0x8f, 0xc0, 0xbe, 0x5d, 0xd6, 0x9f, 0xa0, 0xf0, 0x9d, 0x81, 0xce, 0x3a, 0x7b, 0x98, 0x58, 0xbb, 0xd7, 0x78, 0xc8, 0x3f, 0x13, 0xf1, 0x74, 0x19, 0xdf, 0xf8, 0x98, 0x89, 0x5d, 0xfa, 0x5f}}},
-{{{0x9e, 0x35, 0x85, 0x94, 0x47, 0x1f, 0x90, 0x15, 0x26, 0xd0, 0x84, 0xed, 0x8a, 0x80, 0xf7, 0x63, 0x42, 0x86, 0x27, 0xd7, 0xf4, 0x75, 0x58, 0xdc, 0x9c, 0xc0, 0x22, 0x7e, 0x20, 0x35, 0xfd, 0x1f}} ,
- {{0x68, 0x0e, 0x6f, 0x97, 0xba, 0x70, 0xbb, 0xa3, 0x0e, 0xe5, 0x0b, 0x12, 0xf4, 0xa2, 0xdc, 0x47, 0xf8, 0xe6, 0xd0, 0x23, 0x6c, 0x33, 0xa8, 0x99, 0x46, 0x6e, 0x0f, 0x44, 0xba, 0x76, 0x48, 0x0f}}},
-{{{0xa3, 0x2a, 0x61, 0x37, 0xe2, 0x59, 0x12, 0x0e, 0x27, 0xba, 0x64, 0x43, 0xae, 0xc0, 0x42, 0x69, 0x79, 0xa4, 0x1e, 0x29, 0x8b, 0x15, 0xeb, 0xf8, 0xaf, 0xd4, 0xa2, 0x68, 0x33, 0xb5, 0x7a, 0x24}} ,
- {{0x2c, 0x19, 0x33, 0xdd, 0x1b, 0xab, 0xec, 0x01, 0xb0, 0x23, 0xf8, 0x42, 0x2b, 0x06, 0x88, 0xea, 0x3d, 0x2d, 0x00, 0x2a, 0x78, 0x45, 0x4d, 0x38, 0xed, 0x2e, 0x2e, 0x44, 0x49, 0xed, 0xcb, 0x33}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0xa0, 0x68, 0xe8, 0x41, 0x8f, 0x91, 0xf8, 0x11, 0x13, 0x90, 0x2e, 0xa7, 0xab, 0x30, 0xef, 0xad, 0xa0, 0x61, 0x00, 0x88, 0xef, 0xdb, 0xce, 0x5b, 0x5c, 0xbb, 0x62, 0xc8, 0x56, 0xf9, 0x00, 0x73}} ,
- {{0x3f, 0x60, 0xc1, 0x82, 0x2d, 0xa3, 0x28, 0x58, 0x24, 0x9e, 0x9f, 0xe3, 0x70, 0xcc, 0x09, 0x4e, 0x1a, 0x3f, 0x11, 0x11, 0x15, 0x07, 0x3c, 0xa4, 0x41, 0xe0, 0x65, 0xa3, 0x0a, 0x41, 0x6d, 0x11}}},
-{{{0x31, 0x40, 0x01, 0x52, 0x56, 0x94, 0x5b, 0x28, 0x8a, 0xaa, 0x52, 0xee, 0xd8, 0x0a, 0x05, 0x8d, 0xcd, 0xb5, 0xaa, 0x2e, 0x38, 0xaa, 0xb7, 0x87, 0xf7, 0x2b, 0xfb, 0x04, 0xcb, 0x84, 0x3d, 0x54}} ,
- {{0x20, 0xef, 0x59, 0xde, 0xa4, 0x2b, 0x93, 0x6e, 0x2e, 0xec, 0x42, 0x9a, 0xd4, 0x2d, 0xf4, 0x46, 0x58, 0x27, 0x2b, 0x18, 0x8f, 0x83, 0x3d, 0x69, 0x9e, 0xd4, 0x3e, 0xb6, 0xc5, 0xfd, 0x58, 0x03}}},
-{{{0x33, 0x89, 0xc9, 0x63, 0x62, 0x1c, 0x17, 0xb4, 0x60, 0xc4, 0x26, 0x68, 0x09, 0xc3, 0x2e, 0x37, 0x0f, 0x7b, 0xb4, 0x9c, 0xb6, 0xf9, 0xfb, 0xd4, 0x51, 0x78, 0xc8, 0x63, 0xea, 0x77, 0x47, 0x07}} ,
- {{0x32, 0xb4, 0x18, 0x47, 0x79, 0xcb, 0xd4, 0x5a, 0x07, 0x14, 0x0f, 0xa0, 0xd5, 0xac, 0xd0, 0x41, 0x40, 0xab, 0x61, 0x23, 0xe5, 0x2a, 0x2a, 0x6f, 0xf7, 0xa8, 0xd4, 0x76, 0xef, 0xe7, 0x45, 0x6c}}},
-{{{0xa1, 0x5e, 0x60, 0x4f, 0xfb, 0xe1, 0x70, 0x6a, 0x1f, 0x55, 0x4f, 0x09, 0xb4, 0x95, 0x33, 0x36, 0xc6, 0x81, 0x01, 0x18, 0x06, 0x25, 0x27, 0xa4, 0xb4, 0x24, 0xa4, 0x86, 0x03, 0x4c, 0xac, 0x02}} ,
- {{0x77, 0x38, 0xde, 0xd7, 0x60, 0x48, 0x07, 0xf0, 0x74, 0xa8, 0xff, 0x54, 0xe5, 0x30, 0x43, 0xff, 0x77, 0xfb, 0x21, 0x07, 0xff, 0xb2, 0x07, 0x6b, 0xe4, 0xe5, 0x30, 0xfc, 0x19, 0x6c, 0xa3, 0x01}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0x13, 0xc5, 0x2c, 0xac, 0xd3, 0x83, 0x82, 0x7c, 0x29, 0xf7, 0x05, 0xa5, 0x00, 0xb6, 0x1f, 0x86, 0x55, 0xf4, 0xd6, 0x2f, 0x0c, 0x99, 0xd0, 0x65, 0x9b, 0x6b, 0x46, 0x0d, 0x43, 0xf8, 0x16, 0x28}} ,
- {{0x1e, 0x7f, 0xb4, 0x74, 0x7e, 0xb1, 0x89, 0x4f, 0x18, 0x5a, 0xab, 0x64, 0x06, 0xdf, 0x45, 0x87, 0xe0, 0x6a, 0xc6, 0xf0, 0x0e, 0xc9, 0x24, 0x35, 0x38, 0xea, 0x30, 0x54, 0xb4, 0xc4, 0x52, 0x54}}},
-{{{0xe9, 0x9f, 0xdc, 0x3f, 0xc1, 0x89, 0x44, 0x74, 0x27, 0xe4, 0xc1, 0x90, 0xff, 0x4a, 0xa7, 0x3c, 0xee, 0xcd, 0xf4, 0x1d, 0x25, 0x94, 0x7f, 0x63, 0x16, 0x48, 0xbc, 0x64, 0xfe, 0x95, 0xc4, 0x0c}} ,
- {{0x8b, 0x19, 0x75, 0x6e, 0x03, 0x06, 0x5e, 0x6a, 0x6f, 0x1a, 0x8c, 0xe3, 0xd3, 0x28, 0xf2, 0xe0, 0xb9, 0x7a, 0x43, 0x69, 0xe6, 0xd3, 0xc0, 0xfe, 0x7e, 0x97, 0xab, 0x6c, 0x7b, 0x8e, 0x13, 0x42}}},
-{{{0xd4, 0xca, 0x70, 0x3d, 0xab, 0xfb, 0x5f, 0x5e, 0x00, 0x0c, 0xcc, 0x77, 0x22, 0xf8, 0x78, 0x55, 0xae, 0x62, 0x35, 0xfb, 0x9a, 0xc6, 0x03, 0xe4, 0x0c, 0xee, 0xab, 0xc7, 0xc0, 0x89, 0x87, 0x54}} ,
- {{0x32, 0xad, 0xae, 0x85, 0x58, 0x43, 0xb8, 0xb1, 0xe6, 0x3e, 0x00, 0x9c, 0x78, 0x88, 0x56, 0xdb, 0x9c, 0xfc, 0x79, 0xf6, 0xf9, 0x41, 0x5f, 0xb7, 0xbc, 0x11, 0xf9, 0x20, 0x36, 0x1c, 0x53, 0x2b}}},
-{{{0x5a, 0x20, 0x5b, 0xa1, 0xa5, 0x44, 0x91, 0x24, 0x02, 0x63, 0x12, 0x64, 0xb8, 0x55, 0xf6, 0xde, 0x2c, 0xdb, 0x47, 0xb8, 0xc6, 0x0a, 0xc3, 0x00, 0x78, 0x93, 0xd8, 0xf5, 0xf5, 0x18, 0x28, 0x0a}} ,
- {{0xd6, 0x1b, 0x9a, 0x6c, 0xe5, 0x46, 0xea, 0x70, 0x96, 0x8d, 0x4e, 0x2a, 0x52, 0x21, 0x26, 0x4b, 0xb1, 0xbb, 0x0f, 0x7c, 0xa9, 0x9b, 0x04, 0xbb, 0x51, 0x08, 0xf1, 0x9a, 0xa4, 0x76, 0x7c, 0x18}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0xfa, 0x94, 0xf7, 0x40, 0xd0, 0xd7, 0xeb, 0xa9, 0x82, 0x36, 0xd5, 0x15, 0xb9, 0x33, 0x7a, 0xbf, 0x8a, 0xf2, 0x63, 0xaa, 0x37, 0xf5, 0x59, 0xac, 0xbd, 0xbb, 0x32, 0x36, 0xbe, 0x73, 0x99, 0x38}} ,
- {{0x2c, 0xb3, 0xda, 0x7a, 0xd8, 0x3d, 0x99, 0xca, 0xd2, 0xf4, 0xda, 0x99, 0x8e, 0x4f, 0x98, 0xb7, 0xf4, 0xae, 0x3e, 0x9f, 0x8e, 0x35, 0x60, 0xa4, 0x33, 0x75, 0xa4, 0x04, 0x93, 0xb1, 0x6b, 0x4d}}},
-{{{0x97, 0x9d, 0xa8, 0xcd, 0x97, 0x7b, 0x9d, 0xb9, 0xe7, 0xa5, 0xef, 0xfd, 0xa8, 0x42, 0x6b, 0xc3, 0x62, 0x64, 0x7d, 0xa5, 0x1b, 0xc9, 0x9e, 0xd2, 0x45, 0xb9, 0xee, 0x03, 0xb0, 0xbf, 0xc0, 0x68}} ,
- {{0xed, 0xb7, 0x84, 0x2c, 0xf6, 0xd3, 0xa1, 0x6b, 0x24, 0x6d, 0x87, 0x56, 0x97, 0x59, 0x79, 0x62, 0x9f, 0xac, 0xed, 0xf3, 0xc9, 0x89, 0x21, 0x2e, 0x04, 0xb3, 0xcc, 0x2f, 0xbe, 0xd6, 0x0a, 0x4b}}},
-{{{0x39, 0x61, 0x05, 0xed, 0x25, 0x89, 0x8b, 0x5d, 0x1b, 0xcb, 0x0c, 0x55, 0xf4, 0x6a, 0x00, 0x8a, 0x46, 0xe8, 0x1e, 0xc6, 0x83, 0xc8, 0x5a, 0x76, 0xdb, 0xcc, 0x19, 0x7a, 0xcc, 0x67, 0x46, 0x0b}} ,
- {{0x53, 0xcf, 0xc2, 0xa1, 0xad, 0x6a, 0xf3, 0xcd, 0x8f, 0xc9, 0xde, 0x1c, 0xf8, 0x6c, 0x8f, 0xf8, 0x76, 0x42, 0xe7, 0xfe, 0xb2, 0x72, 0x21, 0x0a, 0x66, 0x74, 0x8f, 0xb7, 0xeb, 0xe4, 0x6f, 0x01}}},
-{{{0x22, 0x8c, 0x6b, 0xbe, 0xfc, 0x4d, 0x70, 0x62, 0x6e, 0x52, 0x77, 0x99, 0x88, 0x7e, 0x7b, 0x57, 0x7a, 0x0d, 0xfe, 0xdc, 0x72, 0x92, 0xf1, 0x68, 0x1d, 0x97, 0xd7, 0x7c, 0x8d, 0x53, 0x10, 0x37}} ,
- {{0x53, 0x88, 0x77, 0x02, 0xca, 0x27, 0xa8, 0xe5, 0x45, 0xe2, 0xa8, 0x48, 0x2a, 0xab, 0x18, 0xca, 0xea, 0x2d, 0x2a, 0x54, 0x17, 0x37, 0x32, 0x09, 0xdc, 0xe0, 0x4a, 0xb7, 0x7d, 0x82, 0x10, 0x7d}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0x8a, 0x64, 0x1e, 0x14, 0x0a, 0x57, 0xd4, 0xda, 0x5c, 0x96, 0x9b, 0x01, 0x4c, 0x67, 0xbf, 0x8b, 0x30, 0xfe, 0x08, 0xdb, 0x0d, 0xd5, 0xa8, 0xd7, 0x09, 0x11, 0x85, 0xa2, 0xd3, 0x45, 0xfb, 0x7e}} ,
- {{0xda, 0x8c, 0xc2, 0xd0, 0xac, 0x18, 0xe8, 0x52, 0x36, 0xd4, 0x21, 0xa3, 0xdd, 0x57, 0x22, 0x79, 0xb7, 0xf8, 0x71, 0x9d, 0xc6, 0x91, 0x70, 0x86, 0x56, 0xbf, 0xa1, 0x11, 0x8b, 0x19, 0xe1, 0x0f}}},
-{{{0x18, 0x32, 0x98, 0x2c, 0x8f, 0x91, 0xae, 0x12, 0xf0, 0x8c, 0xea, 0xf3, 0x3c, 0xb9, 0x5d, 0xe4, 0x69, 0xed, 0xb2, 0x47, 0x18, 0xbd, 0xce, 0x16, 0x52, 0x5c, 0x23, 0xe2, 0xa5, 0x25, 0x52, 0x5d}} ,
- {{0xb9, 0xb1, 0xe7, 0x5d, 0x4e, 0xbc, 0xee, 0xbb, 0x40, 0x81, 0x77, 0x82, 0x19, 0xab, 0xb5, 0xc6, 0xee, 0xab, 0x5b, 0x6b, 0x63, 0x92, 0x8a, 0x34, 0x8d, 0xcd, 0xee, 0x4f, 0x49, 0xe5, 0xc9, 0x7e}}},
-{{{0x21, 0xac, 0x8b, 0x22, 0xcd, 0xc3, 0x9a, 0xe9, 0x5e, 0x78, 0xbd, 0xde, 0xba, 0xad, 0xab, 0xbf, 0x75, 0x41, 0x09, 0xc5, 0x58, 0xa4, 0x7d, 0x92, 0xb0, 0x7f, 0xf2, 0xa1, 0xd1, 0xc0, 0xb3, 0x6d}} ,
- {{0x62, 0x4f, 0xd0, 0x75, 0x77, 0xba, 0x76, 0x77, 0xd7, 0xb8, 0xd8, 0x92, 0x6f, 0x98, 0x34, 0x3d, 0xd6, 0x4e, 0x1c, 0x0f, 0xf0, 0x8f, 0x2e, 0xf1, 0xb3, 0xbd, 0xb1, 0xb9, 0xec, 0x99, 0xb4, 0x07}}},
-{{{0x60, 0x57, 0x2e, 0x9a, 0x72, 0x1d, 0x6b, 0x6e, 0x58, 0x33, 0x24, 0x8c, 0x48, 0x39, 0x46, 0x8e, 0x89, 0x6a, 0x88, 0x51, 0x23, 0x62, 0xb5, 0x32, 0x09, 0x36, 0xe3, 0x57, 0xf5, 0x98, 0xde, 0x6f}} ,
- {{0x8b, 0x2c, 0x00, 0x48, 0x4a, 0xf9, 0x5b, 0x87, 0x69, 0x52, 0xe5, 0x5b, 0xd1, 0xb1, 0xe5, 0x25, 0x25, 0xe0, 0x9c, 0xc2, 0x13, 0x44, 0xe8, 0xb9, 0x0a, 0x70, 0xad, 0xbd, 0x0f, 0x51, 0x94, 0x69}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0xa2, 0xdc, 0xab, 0xa9, 0x25, 0x2d, 0xac, 0x5f, 0x03, 0x33, 0x08, 0xe7, 0x7e, 0xfe, 0x95, 0x36, 0x3c, 0x5b, 0x3a, 0xd3, 0x05, 0x82, 0x1c, 0x95, 0x2d, 0xd8, 0x77, 0x7e, 0x02, 0xd9, 0x5b, 0x70}} ,
- {{0xc2, 0xfe, 0x1b, 0x0c, 0x67, 0xcd, 0xd6, 0xe0, 0x51, 0x8e, 0x2c, 0xe0, 0x79, 0x88, 0xf0, 0xcf, 0x41, 0x4a, 0xad, 0x23, 0xd4, 0x46, 0xca, 0x94, 0xa1, 0xc3, 0xeb, 0x28, 0x06, 0xfa, 0x17, 0x14}}},
-{{{0x7b, 0xaa, 0x70, 0x0a, 0x4b, 0xfb, 0xf5, 0xbf, 0x80, 0xc5, 0xcf, 0x08, 0x7a, 0xdd, 0xa1, 0xf4, 0x9d, 0x54, 0x50, 0x53, 0x23, 0x77, 0x23, 0xf5, 0x34, 0xa5, 0x22, 0xd1, 0x0d, 0x96, 0x2e, 0x47}} ,
- {{0xcc, 0xb7, 0x32, 0x89, 0x57, 0xd0, 0x98, 0x75, 0xe4, 0x37, 0x99, 0xa9, 0xe8, 0xba, 0xed, 0xba, 0xeb, 0xc7, 0x4f, 0x15, 0x76, 0x07, 0x0c, 0x4c, 0xef, 0x9f, 0x52, 0xfc, 0x04, 0x5d, 0x58, 0x10}}},
-{{{0xce, 0x82, 0xf0, 0x8f, 0x79, 0x02, 0xa8, 0xd1, 0xda, 0x14, 0x09, 0x48, 0xee, 0x8a, 0x40, 0x98, 0x76, 0x60, 0x54, 0x5a, 0xde, 0x03, 0x24, 0xf5, 0xe6, 0x2f, 0xe1, 0x03, 0xbf, 0x68, 0x82, 0x7f}} ,
- {{0x64, 0xe9, 0x28, 0xc7, 0xa4, 0xcf, 0x2a, 0xf9, 0x90, 0x64, 0x72, 0x2c, 0x8b, 0xeb, 0xec, 0xa0, 0xf2, 0x7d, 0x35, 0xb5, 0x90, 0x4d, 0x7f, 0x5b, 0x4a, 0x49, 0xe4, 0xb8, 0x3b, 0xc8, 0xa1, 0x2f}}},
-{{{0x8b, 0xc5, 0xcc, 0x3d, 0x69, 0xa6, 0xa1, 0x18, 0x44, 0xbc, 0x4d, 0x77, 0x37, 0xc7, 0x86, 0xec, 0x0c, 0xc9, 0xd6, 0x44, 0xa9, 0x23, 0x27, 0xb9, 0x03, 0x34, 0xa7, 0x0a, 0xd5, 0xc7, 0x34, 0x37}} ,
- {{0xf9, 0x7e, 0x3e, 0x66, 0xee, 0xf9, 0x99, 0x28, 0xff, 0xad, 0x11, 0xd8, 0xe2, 0x66, 0xc5, 0xcd, 0x0f, 0x0d, 0x0b, 0x6a, 0xfc, 0x7c, 0x24, 0xa8, 0x4f, 0xa8, 0x5e, 0x80, 0x45, 0x8b, 0x6c, 0x41}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0xef, 0x1e, 0xec, 0xf7, 0x8d, 0x77, 0xf2, 0xea, 0xdb, 0x60, 0x03, 0x21, 0xc0, 0xff, 0x5e, 0x67, 0xc3, 0x71, 0x0b, 0x21, 0xb4, 0x41, 0xa0, 0x68, 0x38, 0xc6, 0x01, 0xa3, 0xd3, 0x51, 0x3c, 0x3c}} ,
- {{0x92, 0xf8, 0xd6, 0x4b, 0xef, 0x42, 0x13, 0xb2, 0x4a, 0xc4, 0x2e, 0x72, 0x3f, 0xc9, 0x11, 0xbd, 0x74, 0x02, 0x0e, 0xf5, 0x13, 0x9d, 0x83, 0x1a, 0x1b, 0xd5, 0x54, 0xde, 0xc4, 0x1e, 0x16, 0x6c}}},
-{{{0x27, 0x52, 0xe4, 0x63, 0xaa, 0x94, 0xe6, 0xc3, 0x28, 0x9c, 0xc6, 0x56, 0xac, 0xfa, 0xb6, 0xbd, 0xe2, 0xcc, 0x76, 0xc6, 0x27, 0x27, 0xa2, 0x8e, 0x78, 0x2b, 0x84, 0x72, 0x10, 0xbd, 0x4e, 0x2a}} ,
- {{0xea, 0xa7, 0x23, 0xef, 0x04, 0x61, 0x80, 0x50, 0xc9, 0x6e, 0xa5, 0x96, 0xd1, 0xd1, 0xc8, 0xc3, 0x18, 0xd7, 0x2d, 0xfd, 0x26, 0xbd, 0xcb, 0x7b, 0x92, 0x51, 0x0e, 0x4a, 0x65, 0x57, 0xb8, 0x49}}},
-{{{0xab, 0x55, 0x36, 0xc3, 0xec, 0x63, 0x55, 0x11, 0x55, 0xf6, 0xa5, 0xc7, 0x01, 0x5f, 0xfe, 0x79, 0xd8, 0x0a, 0xf7, 0x03, 0xd8, 0x98, 0x99, 0xf5, 0xd0, 0x00, 0x54, 0x6b, 0x66, 0x28, 0xf5, 0x25}} ,
- {{0x7a, 0x8d, 0xa1, 0x5d, 0x70, 0x5d, 0x51, 0x27, 0xee, 0x30, 0x65, 0x56, 0x95, 0x46, 0xde, 0xbd, 0x03, 0x75, 0xb4, 0x57, 0x59, 0x89, 0xeb, 0x02, 0x9e, 0xcc, 0x89, 0x19, 0xa7, 0xcb, 0x17, 0x67}}},
-{{{0x6a, 0xeb, 0xfc, 0x9a, 0x9a, 0x10, 0xce, 0xdb, 0x3a, 0x1c, 0x3c, 0x6a, 0x9d, 0xea, 0x46, 0xbc, 0x45, 0x49, 0xac, 0xe3, 0x41, 0x12, 0x7c, 0xf0, 0xf7, 0x4f, 0xf9, 0xf7, 0xff, 0x2c, 0x89, 0x04}} ,
- {{0x30, 0x31, 0x54, 0x1a, 0x46, 0xca, 0xe6, 0xc6, 0xcb, 0xe2, 0xc3, 0xc1, 0x8b, 0x75, 0x81, 0xbe, 0xee, 0xf8, 0xa3, 0x11, 0x1c, 0x25, 0xa3, 0xa7, 0x35, 0x51, 0x55, 0xe2, 0x25, 0xaa, 0xe2, 0x3a}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0xb4, 0x48, 0x10, 0x9f, 0x8a, 0x09, 0x76, 0xfa, 0xf0, 0x7a, 0xb0, 0x70, 0xf7, 0x83, 0x80, 0x52, 0x84, 0x2b, 0x26, 0xa2, 0xc4, 0x5d, 0x4f, 0xba, 0xb1, 0xc8, 0x40, 0x0d, 0x78, 0x97, 0xc4, 0x60}} ,
- {{0xd4, 0xb1, 0x6c, 0x08, 0xc7, 0x40, 0x38, 0x73, 0x5f, 0x0b, 0xf3, 0x76, 0x5d, 0xb2, 0xa5, 0x2f, 0x57, 0x57, 0x07, 0xed, 0x08, 0xa2, 0x6c, 0x4f, 0x08, 0x02, 0xb5, 0x0e, 0xee, 0x44, 0xfa, 0x22}}},
-{{{0x0f, 0x00, 0x3f, 0xa6, 0x04, 0x19, 0x56, 0x65, 0x31, 0x7f, 0x8b, 0xeb, 0x0d, 0xe1, 0x47, 0x89, 0x97, 0x16, 0x53, 0xfa, 0x81, 0xa7, 0xaa, 0xb2, 0xbf, 0x67, 0xeb, 0x72, 0x60, 0x81, 0x0d, 0x48}} ,
- {{0x7e, 0x13, 0x33, 0xcd, 0xa8, 0x84, 0x56, 0x1e, 0x67, 0xaf, 0x6b, 0x43, 0xac, 0x17, 0xaf, 0x16, 0xc0, 0x52, 0x99, 0x49, 0x5b, 0x87, 0x73, 0x7e, 0xb5, 0x43, 0xda, 0x6b, 0x1d, 0x0f, 0x2d, 0x55}}},
-{{{0xe9, 0x58, 0x1f, 0xff, 0x84, 0x3f, 0x93, 0x1c, 0xcb, 0xe1, 0x30, 0x69, 0xa5, 0x75, 0x19, 0x7e, 0x14, 0x5f, 0xf8, 0xfc, 0x09, 0xdd, 0xa8, 0x78, 0x9d, 0xca, 0x59, 0x8b, 0xd1, 0x30, 0x01, 0x13}} ,
- {{0xff, 0x76, 0x03, 0xc5, 0x4b, 0x89, 0x99, 0x70, 0x00, 0x59, 0x70, 0x9c, 0xd5, 0xd9, 0x11, 0x89, 0x5a, 0x46, 0xfe, 0xef, 0xdc, 0xd9, 0x55, 0x2b, 0x45, 0xa7, 0xb0, 0x2d, 0xfb, 0x24, 0xc2, 0x29}}},
-{{{0x38, 0x06, 0xf8, 0x0b, 0xac, 0x82, 0xc4, 0x97, 0x2b, 0x90, 0xe0, 0xf7, 0xa8, 0xab, 0x6c, 0x08, 0x80, 0x66, 0x90, 0x46, 0xf7, 0x26, 0x2d, 0xf8, 0xf1, 0xc4, 0x6b, 0x4a, 0x82, 0x98, 0x8e, 0x37}} ,
- {{0x8e, 0xb4, 0xee, 0xb8, 0xd4, 0x3f, 0xb2, 0x1b, 0xe0, 0x0a, 0x3d, 0x75, 0x34, 0x28, 0xa2, 0x8e, 0xc4, 0x92, 0x7b, 0xfe, 0x60, 0x6e, 0x6d, 0xb8, 0x31, 0x1d, 0x62, 0x0d, 0x78, 0x14, 0x42, 0x11}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0x5e, 0xa8, 0xd8, 0x04, 0x9b, 0x73, 0xc9, 0xc9, 0xdc, 0x0d, 0x73, 0xbf, 0x0a, 0x0a, 0x73, 0xff, 0x18, 0x1f, 0x9c, 0x51, 0xaa, 0xc6, 0xf1, 0x83, 0x25, 0xfd, 0xab, 0xa3, 0x11, 0xd3, 0x01, 0x24}} ,
- {{0x4d, 0xe3, 0x7e, 0x38, 0x62, 0x5e, 0x64, 0xbb, 0x2b, 0x53, 0xb5, 0x03, 0x68, 0xc4, 0xf2, 0x2b, 0x5a, 0x03, 0x32, 0x99, 0x4a, 0x41, 0x9a, 0xe1, 0x1a, 0xae, 0x8c, 0x48, 0xf3, 0x24, 0x32, 0x65}}},
-{{{0xe8, 0xdd, 0xad, 0x3a, 0x8c, 0xea, 0xf4, 0xb3, 0xb2, 0xe5, 0x73, 0xf2, 0xed, 0x8b, 0xbf, 0xed, 0xb1, 0x0c, 0x0c, 0xfb, 0x2b, 0xf1, 0x01, 0x48, 0xe8, 0x26, 0x03, 0x8e, 0x27, 0x4d, 0x96, 0x72}} ,
- {{0xc8, 0x09, 0x3b, 0x60, 0xc9, 0x26, 0x4d, 0x7c, 0xf2, 0x9c, 0xd4, 0xa1, 0x3b, 0x26, 0xc2, 0x04, 0x33, 0x44, 0x76, 0x3c, 0x02, 0xbb, 0x11, 0x42, 0x0c, 0x22, 0xb7, 0xc6, 0xe1, 0xac, 0xb4, 0x0e}}},
-{{{0x6f, 0x85, 0xe7, 0xef, 0xde, 0x67, 0x30, 0xfc, 0xbf, 0x5a, 0xe0, 0x7b, 0x7a, 0x2a, 0x54, 0x6b, 0x5d, 0x62, 0x85, 0xa1, 0xf8, 0x16, 0x88, 0xec, 0x61, 0xb9, 0x96, 0xb5, 0xef, 0x2d, 0x43, 0x4d}} ,
- {{0x7c, 0x31, 0x33, 0xcc, 0xe4, 0xcf, 0x6c, 0xff, 0x80, 0x47, 0x77, 0xd1, 0xd8, 0xe9, 0x69, 0x97, 0x98, 0x7f, 0x20, 0x57, 0x1d, 0x1d, 0x4f, 0x08, 0x27, 0xc8, 0x35, 0x57, 0x40, 0xc6, 0x21, 0x0c}}},
-{{{0xd2, 0x8e, 0x9b, 0xfa, 0x42, 0x8e, 0xdf, 0x8f, 0xc7, 0x86, 0xf9, 0xa4, 0xca, 0x70, 0x00, 0x9d, 0x21, 0xbf, 0xec, 0x57, 0x62, 0x30, 0x58, 0x8c, 0x0d, 0x35, 0xdb, 0x5d, 0x8b, 0x6a, 0xa0, 0x5a}} ,
- {{0xc1, 0x58, 0x7c, 0x0d, 0x20, 0xdd, 0x11, 0x26, 0x5f, 0x89, 0x3b, 0x97, 0x58, 0xf8, 0x8b, 0xe3, 0xdf, 0x32, 0xe2, 0xfc, 0xd8, 0x67, 0xf2, 0xa5, 0x37, 0x1e, 0x6d, 0xec, 0x7c, 0x27, 0x20, 0x79}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0xd0, 0xe9, 0xc0, 0xfa, 0x95, 0x45, 0x23, 0x96, 0xf1, 0x2c, 0x79, 0x25, 0x14, 0xce, 0x40, 0x14, 0x44, 0x2c, 0x36, 0x50, 0xd9, 0x63, 0x56, 0xb7, 0x56, 0x3b, 0x9e, 0xa7, 0xef, 0x89, 0xbb, 0x0e}} ,
- {{0xce, 0x7f, 0xdc, 0x0a, 0xcc, 0x82, 0x1c, 0x0a, 0x78, 0x71, 0xe8, 0x74, 0x8d, 0x01, 0x30, 0x0f, 0xa7, 0x11, 0x4c, 0xdf, 0x38, 0xd7, 0xa7, 0x0d, 0xf8, 0x48, 0x52, 0x00, 0x80, 0x7b, 0x5f, 0x0e}}},
-{{{0x25, 0x83, 0xe6, 0x94, 0x7b, 0x81, 0xb2, 0x91, 0xae, 0x0e, 0x05, 0xc9, 0xa3, 0x68, 0x2d, 0xd9, 0x88, 0x25, 0x19, 0x2a, 0x61, 0x61, 0x21, 0x97, 0x15, 0xa1, 0x35, 0xa5, 0x46, 0xc8, 0xa2, 0x0e}} ,
- {{0x1b, 0x03, 0x0d, 0x8b, 0x5a, 0x1b, 0x97, 0x4b, 0xf2, 0x16, 0x31, 0x3d, 0x1f, 0x33, 0xa0, 0x50, 0x3a, 0x18, 0xbe, 0x13, 0xa1, 0x76, 0xc1, 0xba, 0x1b, 0xf1, 0x05, 0x7b, 0x33, 0xa8, 0x82, 0x3b}}},
-{{{0xba, 0x36, 0x7b, 0x6d, 0xa9, 0xea, 0x14, 0x12, 0xc5, 0xfa, 0x91, 0x00, 0xba, 0x9b, 0x99, 0xcc, 0x56, 0x02, 0xe9, 0xa0, 0x26, 0x40, 0x66, 0x8c, 0xc4, 0xf8, 0x85, 0x33, 0x68, 0xe7, 0x03, 0x20}} ,
- {{0x50, 0x5b, 0xff, 0xa9, 0xb2, 0xf1, 0xf1, 0x78, 0xcf, 0x14, 0xa4, 0xa9, 0xfc, 0x09, 0x46, 0x94, 0x54, 0x65, 0x0d, 0x9c, 0x5f, 0x72, 0x21, 0xe2, 0x97, 0xa5, 0x2d, 0x81, 0xce, 0x4a, 0x5f, 0x79}}},
-{{{0x3d, 0x5f, 0x5c, 0xd2, 0xbc, 0x7d, 0x77, 0x0e, 0x2a, 0x6d, 0x22, 0x45, 0x84, 0x06, 0xc4, 0xdd, 0xc6, 0xa6, 0xc6, 0xd7, 0x49, 0xad, 0x6d, 0x87, 0x91, 0x0e, 0x3a, 0x67, 0x1d, 0x2c, 0x1d, 0x56}} ,
- {{0xfe, 0x7a, 0x74, 0xcf, 0xd4, 0xd2, 0xe5, 0x19, 0xde, 0xd0, 0xdb, 0x70, 0x23, 0x69, 0xe6, 0x6d, 0xec, 0xec, 0xcc, 0x09, 0x33, 0x6a, 0x77, 0xdc, 0x6b, 0x22, 0x76, 0x5d, 0x92, 0x09, 0xac, 0x2d}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0x23, 0x15, 0x17, 0xeb, 0xd3, 0xdb, 0x12, 0x5e, 0x01, 0xf0, 0x91, 0xab, 0x2c, 0x41, 0xce, 0xac, 0xed, 0x1b, 0x4b, 0x2d, 0xbc, 0xdb, 0x17, 0x66, 0x89, 0x46, 0xad, 0x4b, 0x1e, 0x6f, 0x0b, 0x14}} ,
- {{0x11, 0xce, 0xbf, 0xb6, 0x77, 0x2d, 0x48, 0x22, 0x18, 0x4f, 0xa3, 0x5d, 0x4a, 0xb0, 0x70, 0x12, 0x3e, 0x54, 0xd7, 0xd8, 0x0e, 0x2b, 0x27, 0xdc, 0x53, 0xff, 0xca, 0x8c, 0x59, 0xb3, 0x4e, 0x44}}},
-{{{0x07, 0x76, 0x61, 0x0f, 0x66, 0xb2, 0x21, 0x39, 0x7e, 0xc0, 0xec, 0x45, 0x28, 0x82, 0xa1, 0x29, 0x32, 0x44, 0x35, 0x13, 0x5e, 0x61, 0x5e, 0x54, 0xcb, 0x7c, 0xef, 0xf6, 0x41, 0xcf, 0x9f, 0x0a}} ,
- {{0xdd, 0xf9, 0xda, 0x84, 0xc3, 0xe6, 0x8a, 0x9f, 0x24, 0xd2, 0x96, 0x5d, 0x39, 0x6f, 0x58, 0x8c, 0xc1, 0x56, 0x93, 0xab, 0xb5, 0x79, 0x3b, 0xd2, 0xa8, 0x73, 0x16, 0xed, 0xfa, 0xb4, 0x2f, 0x73}}},
-{{{0x8b, 0xb1, 0x95, 0xe5, 0x92, 0x50, 0x35, 0x11, 0x76, 0xac, 0xf4, 0x4d, 0x24, 0xc3, 0x32, 0xe6, 0xeb, 0xfe, 0x2c, 0x87, 0xc4, 0xf1, 0x56, 0xc4, 0x75, 0x24, 0x7a, 0x56, 0x85, 0x5a, 0x3a, 0x13}} ,
- {{0x0d, 0x16, 0xac, 0x3c, 0x4a, 0x58, 0x86, 0x3a, 0x46, 0x7f, 0x6c, 0xa3, 0x52, 0x6e, 0x37, 0xe4, 0x96, 0x9c, 0xe9, 0x5c, 0x66, 0x41, 0x67, 0xe4, 0xfb, 0x79, 0x0c, 0x05, 0xf6, 0x64, 0xd5, 0x7c}}},
-{{{0x28, 0xc1, 0xe1, 0x54, 0x73, 0xf2, 0xbf, 0x76, 0x74, 0x19, 0x19, 0x1b, 0xe4, 0xb9, 0xa8, 0x46, 0x65, 0x73, 0xf3, 0x77, 0x9b, 0x29, 0x74, 0x5b, 0xc6, 0x89, 0x6c, 0x2c, 0x7c, 0xf8, 0xb3, 0x0f}} ,
- {{0xf7, 0xd5, 0xe9, 0x74, 0x5d, 0xb8, 0x25, 0x16, 0xb5, 0x30, 0xbc, 0x84, 0xc5, 0xf0, 0xad, 0xca, 0x12, 0x28, 0xbc, 0x9d, 0xd4, 0xfa, 0x82, 0xe6, 0xe3, 0xbf, 0xa2, 0x15, 0x2c, 0xd4, 0x34, 0x10}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0x61, 0xb1, 0x46, 0xba, 0x0e, 0x31, 0xa5, 0x67, 0x6c, 0x7f, 0xd6, 0xd9, 0x27, 0x85, 0x0f, 0x79, 0x14, 0xc8, 0x6c, 0x2f, 0x5f, 0x5b, 0x9c, 0x35, 0x3d, 0x38, 0x86, 0x77, 0x65, 0x55, 0x6a, 0x7b}} ,
- {{0xd3, 0xb0, 0x3a, 0x66, 0x60, 0x1b, 0x43, 0xf1, 0x26, 0x58, 0x99, 0x09, 0x8f, 0x2d, 0xa3, 0x14, 0x71, 0x85, 0xdb, 0xed, 0xf6, 0x26, 0xd5, 0x61, 0x9a, 0x73, 0xac, 0x0e, 0xea, 0xac, 0xb7, 0x0c}}},
-{{{0x5e, 0xf4, 0xe5, 0x17, 0x0e, 0x10, 0x9f, 0xe7, 0x43, 0x5f, 0x67, 0x5c, 0xac, 0x4b, 0xe5, 0x14, 0x41, 0xd2, 0xbf, 0x48, 0xf5, 0x14, 0xb0, 0x71, 0xc6, 0x61, 0xc1, 0xb2, 0x70, 0x58, 0xd2, 0x5a}} ,
- {{0x2d, 0xba, 0x16, 0x07, 0x92, 0x94, 0xdc, 0xbd, 0x50, 0x2b, 0xc9, 0x7f, 0x42, 0x00, 0xba, 0x61, 0xed, 0xf8, 0x43, 0xed, 0xf5, 0xf9, 0x40, 0x60, 0xb2, 0xb0, 0x82, 0xcb, 0xed, 0x75, 0xc7, 0x65}}},
-{{{0x80, 0xba, 0x0d, 0x09, 0x40, 0xa7, 0x39, 0xa6, 0x67, 0x34, 0x7e, 0x66, 0xbe, 0x56, 0xfb, 0x53, 0x78, 0xc4, 0x46, 0xe8, 0xed, 0x68, 0x6c, 0x7f, 0xce, 0xe8, 0x9f, 0xce, 0xa2, 0x64, 0x58, 0x53}} ,
- {{0xe8, 0xc1, 0xa9, 0xc2, 0x7b, 0x59, 0x21, 0x33, 0xe2, 0x43, 0x73, 0x2b, 0xac, 0x2d, 0xc1, 0x89, 0x3b, 0x15, 0xe2, 0xd5, 0xc0, 0x97, 0x8a, 0xfd, 0x6f, 0x36, 0x33, 0xb7, 0xb9, 0xc3, 0x88, 0x09}}},
-{{{0xd0, 0xb6, 0x56, 0x30, 0x5c, 0xae, 0xb3, 0x75, 0x44, 0xa4, 0x83, 0x51, 0x6e, 0x01, 0x65, 0xef, 0x45, 0x76, 0xe6, 0xf5, 0xa2, 0x0d, 0xd4, 0x16, 0x3b, 0x58, 0x2f, 0xf2, 0x2f, 0x36, 0x18, 0x3f}} ,
- {{0xfd, 0x2f, 0xe0, 0x9b, 0x1e, 0x8c, 0xc5, 0x18, 0xa9, 0xca, 0xd4, 0x2b, 0x35, 0xb6, 0x95, 0x0a, 0x9f, 0x7e, 0xfb, 0xc4, 0xef, 0x88, 0x7b, 0x23, 0x43, 0xec, 0x2f, 0x0d, 0x0f, 0x7a, 0xfc, 0x5c}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0x8d, 0xd2, 0xda, 0xc7, 0x44, 0xd6, 0x7a, 0xdb, 0x26, 0x7d, 0x1d, 0xb8, 0xe1, 0xde, 0x9d, 0x7a, 0x7d, 0x17, 0x7e, 0x1c, 0x37, 0x04, 0x8d, 0x2d, 0x7c, 0x5e, 0x18, 0x38, 0x1e, 0xaf, 0xc7, 0x1b}} ,
- {{0x33, 0x48, 0x31, 0x00, 0x59, 0xf6, 0xf2, 0xca, 0x0f, 0x27, 0x1b, 0x63, 0x12, 0x7e, 0x02, 0x1d, 0x49, 0xc0, 0x5d, 0x79, 0x87, 0xef, 0x5e, 0x7a, 0x2f, 0x1f, 0x66, 0x55, 0xd8, 0x09, 0xd9, 0x61}}},
-{{{0x54, 0x83, 0x02, 0x18, 0x82, 0x93, 0x99, 0x07, 0xd0, 0xa7, 0xda, 0xd8, 0x75, 0x89, 0xfa, 0xf2, 0xd9, 0xa3, 0xb8, 0x6b, 0x5a, 0x35, 0x28, 0xd2, 0x6b, 0x59, 0xc2, 0xf8, 0x45, 0xe2, 0xbc, 0x06}} ,
- {{0x65, 0xc0, 0xa3, 0x88, 0x51, 0x95, 0xfc, 0x96, 0x94, 0x78, 0xe8, 0x0d, 0x8b, 0x41, 0xc9, 0xc2, 0x58, 0x48, 0x75, 0x10, 0x2f, 0xcd, 0x2a, 0xc9, 0xa0, 0x6d, 0x0f, 0xdd, 0x9c, 0x98, 0x26, 0x3d}}},
-{{{0x2f, 0x66, 0x29, 0x1b, 0x04, 0x89, 0xbd, 0x7e, 0xee, 0x6e, 0xdd, 0xb7, 0x0e, 0xef, 0xb0, 0x0c, 0xb4, 0xfc, 0x7f, 0xc2, 0xc9, 0x3a, 0x3c, 0x64, 0xef, 0x45, 0x44, 0xaf, 0x8a, 0x90, 0x65, 0x76}} ,
- {{0xa1, 0x4c, 0x70, 0x4b, 0x0e, 0xa0, 0x83, 0x70, 0x13, 0xa4, 0xaf, 0xb8, 0x38, 0x19, 0x22, 0x65, 0x09, 0xb4, 0x02, 0x4f, 0x06, 0xf8, 0x17, 0xce, 0x46, 0x45, 0xda, 0x50, 0x7c, 0x8a, 0xd1, 0x4e}}},
-{{{0xf7, 0xd4, 0x16, 0x6c, 0x4e, 0x95, 0x9d, 0x5d, 0x0f, 0x91, 0x2b, 0x52, 0xfe, 0x5c, 0x34, 0xe5, 0x30, 0xe6, 0xa4, 0x3b, 0xf3, 0xf3, 0x34, 0x08, 0xa9, 0x4a, 0xa0, 0xb5, 0x6e, 0xb3, 0x09, 0x0a}} ,
- {{0x26, 0xd9, 0x5e, 0xa3, 0x0f, 0xeb, 0xa2, 0xf3, 0x20, 0x3b, 0x37, 0xd4, 0xe4, 0x9e, 0xce, 0x06, 0x3d, 0x53, 0xed, 0xae, 0x2b, 0xeb, 0xb6, 0x24, 0x0a, 0x11, 0xa3, 0x0f, 0xd6, 0x7f, 0xa4, 0x3a}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0xdb, 0x9f, 0x2c, 0xfc, 0xd6, 0xb2, 0x1e, 0x2e, 0x52, 0x7a, 0x06, 0x87, 0x2d, 0x86, 0x72, 0x2b, 0x6d, 0x90, 0x77, 0x46, 0x43, 0xb5, 0x7a, 0xf8, 0x60, 0x7d, 0x91, 0x60, 0x5b, 0x9d, 0x9e, 0x07}} ,
- {{0x97, 0x87, 0xc7, 0x04, 0x1c, 0x38, 0x01, 0x39, 0x58, 0xc7, 0x85, 0xa3, 0xfc, 0x64, 0x00, 0x64, 0x25, 0xa2, 0xbf, 0x50, 0x94, 0xca, 0x26, 0x31, 0x45, 0x0a, 0x24, 0xd2, 0x51, 0x29, 0x51, 0x16}}},
-{{{0x4d, 0x4a, 0xd7, 0x98, 0x71, 0x57, 0xac, 0x7d, 0x8b, 0x37, 0xbd, 0x63, 0xff, 0x87, 0xb1, 0x49, 0x95, 0x20, 0x7c, 0xcf, 0x7c, 0x59, 0xc4, 0x91, 0x9c, 0xef, 0xd0, 0xdb, 0x60, 0x09, 0x9d, 0x46}} ,
- {{0xcb, 0x78, 0x94, 0x90, 0xe4, 0x45, 0xb3, 0xf6, 0xd9, 0xf6, 0x57, 0x74, 0xd5, 0xf8, 0x83, 0x4f, 0x39, 0xc9, 0xbd, 0x88, 0xc2, 0x57, 0x21, 0x1f, 0x24, 0x32, 0x68, 0xf8, 0xc7, 0x21, 0x5f, 0x0b}}},
-{{{0x2a, 0x36, 0x68, 0xfc, 0x5f, 0xb6, 0x4f, 0xa5, 0xe3, 0x9d, 0x24, 0x2f, 0xc0, 0x93, 0x61, 0xcf, 0xf8, 0x0a, 0xed, 0xe1, 0xdb, 0x27, 0xec, 0x0e, 0x14, 0x32, 0x5f, 0x8e, 0xa1, 0x62, 0x41, 0x16}} ,
- {{0x95, 0x21, 0x01, 0xce, 0x95, 0x5b, 0x0e, 0x57, 0xc7, 0xb9, 0x62, 0xb5, 0x28, 0xca, 0x11, 0xec, 0xb4, 0x46, 0x06, 0x73, 0x26, 0xff, 0xfb, 0x66, 0x7d, 0xee, 0x5f, 0xb2, 0x56, 0xfd, 0x2a, 0x08}}},
-{{{0x92, 0x67, 0x77, 0x56, 0xa1, 0xff, 0xc4, 0xc5, 0x95, 0xf0, 0xe3, 0x3a, 0x0a, 0xca, 0x94, 0x4d, 0x9e, 0x7e, 0x3d, 0xb9, 0x6e, 0xb6, 0xb0, 0xce, 0xa4, 0x30, 0x89, 0x99, 0xe9, 0xad, 0x11, 0x59}} ,
- {{0xf6, 0x48, 0x95, 0xa1, 0x6f, 0x5f, 0xb7, 0xa5, 0xbb, 0x30, 0x00, 0x1c, 0xd2, 0x8a, 0xd6, 0x25, 0x26, 0x1b, 0xb2, 0x0d, 0x37, 0x6a, 0x05, 0xf4, 0x9d, 0x3e, 0x17, 0x2a, 0x43, 0xd2, 0x3a, 0x06}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0x32, 0x99, 0x93, 0xd1, 0x9a, 0x72, 0xf3, 0xa9, 0x16, 0xbd, 0xb4, 0x4c, 0xdd, 0xf9, 0xd4, 0xb2, 0x64, 0x9a, 0xd3, 0x05, 0xe4, 0xa3, 0x73, 0x1c, 0xcb, 0x7e, 0x57, 0x67, 0xff, 0x04, 0xb3, 0x10}} ,
- {{0xb9, 0x4b, 0xa4, 0xad, 0xd0, 0x6d, 0x61, 0x23, 0xb4, 0xaf, 0x34, 0xa9, 0xaa, 0x65, 0xec, 0xd9, 0x69, 0xe3, 0x85, 0xcd, 0xcc, 0xe7, 0xb0, 0x9b, 0x41, 0xc1, 0x1c, 0xf9, 0xa0, 0xfa, 0xb7, 0x13}}},
-{{{0x04, 0xfd, 0x88, 0x3c, 0x0c, 0xd0, 0x09, 0x52, 0x51, 0x4f, 0x06, 0x19, 0xcc, 0xc3, 0xbb, 0xde, 0x80, 0xc5, 0x33, 0xbc, 0xf9, 0xf3, 0x17, 0x36, 0xdd, 0xc6, 0xde, 0xe8, 0x9b, 0x5d, 0x79, 0x1b}} ,
- {{0x65, 0x0a, 0xbe, 0x51, 0x57, 0xad, 0x50, 0x79, 0x08, 0x71, 0x9b, 0x07, 0x95, 0x8f, 0xfb, 0xae, 0x4b, 0x38, 0xba, 0xcf, 0x53, 0x2a, 0x86, 0x1e, 0xc0, 0x50, 0x5c, 0x67, 0x1b, 0xf6, 0x87, 0x6c}}},
-{{{0x4f, 0x00, 0xb2, 0x66, 0x55, 0xed, 0x4a, 0xed, 0x8d, 0xe1, 0x66, 0x18, 0xb2, 0x14, 0x74, 0x8d, 0xfd, 0x1a, 0x36, 0x0f, 0x26, 0x5c, 0x8b, 0x89, 0xf3, 0xab, 0xf2, 0xf3, 0x24, 0x67, 0xfd, 0x70}} ,
- {{0xfd, 0x4e, 0x2a, 0xc1, 0x3a, 0xca, 0x8f, 0x00, 0xd8, 0xec, 0x74, 0x67, 0xef, 0x61, 0xe0, 0x28, 0xd0, 0x96, 0xf4, 0x48, 0xde, 0x81, 0xe3, 0xef, 0xdc, 0xaa, 0x7d, 0xf3, 0xb6, 0x55, 0xa6, 0x65}}},
-{{{0xeb, 0xcb, 0xc5, 0x70, 0x91, 0x31, 0x10, 0x93, 0x0d, 0xc8, 0xd0, 0xef, 0x62, 0xe8, 0x6f, 0x82, 0xe3, 0x69, 0x3d, 0x91, 0x7f, 0x31, 0xe1, 0x26, 0x35, 0x3c, 0x4a, 0x2f, 0xab, 0xc4, 0x9a, 0x5e}} ,
- {{0xab, 0x1b, 0xb5, 0xe5, 0x2b, 0xc3, 0x0e, 0x29, 0xb0, 0xd0, 0x73, 0xe6, 0x4f, 0x64, 0xf2, 0xbc, 0xe4, 0xe4, 0xe1, 0x9a, 0x52, 0x33, 0x2f, 0xbd, 0xcc, 0x03, 0xee, 0x8a, 0xfa, 0x00, 0x5f, 0x50}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0xf6, 0xdb, 0x0d, 0x22, 0x3d, 0xb5, 0x14, 0x75, 0x31, 0xf0, 0x81, 0xe2, 0xb9, 0x37, 0xa2, 0xa9, 0x84, 0x11, 0x9a, 0x07, 0xb5, 0x53, 0x89, 0x78, 0xa9, 0x30, 0x27, 0xa1, 0xf1, 0x4e, 0x5c, 0x2e}} ,
- {{0x8b, 0x00, 0x54, 0xfb, 0x4d, 0xdc, 0xcb, 0x17, 0x35, 0x40, 0xff, 0xb7, 0x8c, 0xfe, 0x4a, 0xe4, 0x4e, 0x99, 0x4e, 0xa8, 0x74, 0x54, 0x5d, 0x5c, 0x96, 0xa3, 0x12, 0x55, 0x36, 0x31, 0x17, 0x5c}}},
-{{{0xce, 0x24, 0xef, 0x7b, 0x86, 0xf2, 0x0f, 0x77, 0xe8, 0x5c, 0x7d, 0x87, 0x38, 0x2d, 0xef, 0xaf, 0xf2, 0x8c, 0x72, 0x2e, 0xeb, 0xb6, 0x55, 0x4b, 0x6e, 0xf1, 0x4e, 0x8a, 0x0e, 0x9a, 0x6c, 0x4c}} ,
- {{0x25, 0xea, 0x86, 0xc2, 0xd1, 0x4f, 0xb7, 0x3e, 0xa8, 0x5c, 0x8d, 0x66, 0x81, 0x25, 0xed, 0xc5, 0x4c, 0x05, 0xb9, 0xd8, 0xd6, 0x70, 0xbe, 0x73, 0x82, 0xe8, 0xa1, 0xe5, 0x1e, 0x71, 0xd5, 0x26}}},
-{{{0x4e, 0x6d, 0xc3, 0xa7, 0x4f, 0x22, 0x45, 0x26, 0xa2, 0x7e, 0x16, 0xf7, 0xf7, 0x63, 0xdc, 0x86, 0x01, 0x2a, 0x71, 0x38, 0x5c, 0x33, 0xc3, 0xce, 0x30, 0xff, 0xf9, 0x2c, 0x91, 0x71, 0x8a, 0x72}} ,
- {{0x8c, 0x44, 0x09, 0x28, 0xd5, 0x23, 0xc9, 0x8f, 0xf3, 0x84, 0x45, 0xc6, 0x9a, 0x5e, 0xff, 0xd2, 0xc7, 0x57, 0x93, 0xa3, 0xc1, 0x69, 0xdd, 0x62, 0x0f, 0xda, 0x5c, 0x30, 0x59, 0x5d, 0xe9, 0x4c}}},
-{{{0x92, 0x7e, 0x50, 0x27, 0x72, 0xd7, 0x0c, 0xd6, 0x69, 0x96, 0x81, 0x35, 0x84, 0x94, 0x35, 0x8b, 0x6c, 0xaa, 0x62, 0x86, 0x6e, 0x1c, 0x15, 0xf3, 0x6c, 0xb3, 0xff, 0x65, 0x1b, 0xa2, 0x9b, 0x59}} ,
- {{0xe2, 0xa9, 0x65, 0x88, 0xc4, 0x50, 0xfa, 0xbb, 0x3b, 0x6e, 0x5f, 0x44, 0x01, 0xca, 0x97, 0xd4, 0xdd, 0xf6, 0xcd, 0x3f, 0x3f, 0xe5, 0x97, 0x67, 0x2b, 0x8c, 0x66, 0x0f, 0x35, 0x9b, 0xf5, 0x07}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0xf1, 0x59, 0x27, 0xd8, 0xdb, 0x5a, 0x11, 0x5e, 0x82, 0xf3, 0x38, 0xff, 0x1c, 0xed, 0xfe, 0x3f, 0x64, 0x54, 0x3f, 0x7f, 0xd1, 0x81, 0xed, 0xef, 0x65, 0xc5, 0xcb, 0xfd, 0xe1, 0x80, 0xcd, 0x11}} ,
- {{0xe0, 0xdb, 0x22, 0x28, 0xe6, 0xff, 0x61, 0x9d, 0x41, 0x14, 0x2d, 0x3b, 0x26, 0x22, 0xdf, 0xf1, 0x34, 0x81, 0xe9, 0x45, 0xee, 0x0f, 0x98, 0x8b, 0xa6, 0x3f, 0xef, 0xf7, 0x43, 0x19, 0xf1, 0x43}}},
-{{{0xee, 0xf3, 0x00, 0xa1, 0x50, 0xde, 0xc0, 0xb6, 0x01, 0xe3, 0x8c, 0x3c, 0x4d, 0x31, 0xd2, 0xb0, 0x58, 0xcd, 0xed, 0x10, 0x4a, 0x7a, 0xef, 0x80, 0xa9, 0x19, 0x32, 0xf3, 0xd8, 0x33, 0x8c, 0x06}} ,
- {{0xcb, 0x7d, 0x4f, 0xff, 0x30, 0xd8, 0x12, 0x3b, 0x39, 0x1c, 0x06, 0xf9, 0x4c, 0x34, 0x35, 0x71, 0xb5, 0x16, 0x94, 0x67, 0xdf, 0xee, 0x11, 0xde, 0xa4, 0x1d, 0x88, 0x93, 0x35, 0xa9, 0x32, 0x10}}},
-{{{0xe9, 0xc3, 0xbc, 0x7b, 0x5c, 0xfc, 0xb2, 0xf9, 0xc9, 0x2f, 0xe5, 0xba, 0x3a, 0x0b, 0xab, 0x64, 0x38, 0x6f, 0x5b, 0x4b, 0x93, 0xda, 0x64, 0xec, 0x4d, 0x3d, 0xa0, 0xf5, 0xbb, 0xba, 0x47, 0x48}} ,
- {{0x60, 0xbc, 0x45, 0x1f, 0x23, 0xa2, 0x3b, 0x70, 0x76, 0xe6, 0x97, 0x99, 0x4f, 0x77, 0x54, 0x67, 0x30, 0x9a, 0xe7, 0x66, 0xd6, 0xcd, 0x2e, 0x51, 0x24, 0x2c, 0x42, 0x4a, 0x11, 0xfe, 0x6f, 0x7e}}},
-{{{0x87, 0xc0, 0xb1, 0xf0, 0xa3, 0x6f, 0x0c, 0x93, 0xa9, 0x0a, 0x72, 0xef, 0x5c, 0xbe, 0x65, 0x35, 0xa7, 0x6a, 0x4e, 0x2c, 0xbf, 0x21, 0x23, 0xe8, 0x2f, 0x97, 0xc7, 0x3e, 0xc8, 0x17, 0xac, 0x1e}} ,
- {{0x7b, 0xef, 0x21, 0xe5, 0x40, 0xcc, 0x1e, 0xdc, 0xd6, 0xbd, 0x97, 0x7a, 0x7c, 0x75, 0x86, 0x7a, 0x25, 0x5a, 0x6e, 0x7c, 0xe5, 0x51, 0x3c, 0x1b, 0x5b, 0x82, 0x9a, 0x07, 0x60, 0xa1, 0x19, 0x04}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0x96, 0x88, 0xa6, 0xab, 0x8f, 0xe3, 0x3a, 0x49, 0xf8, 0xfe, 0x34, 0xe7, 0x6a, 0xb2, 0xfe, 0x40, 0x26, 0x74, 0x57, 0x4c, 0xf6, 0xd4, 0x99, 0xce, 0x5d, 0x7b, 0x2f, 0x67, 0xd6, 0x5a, 0xe4, 0x4e}} ,
- {{0x5c, 0x82, 0xb3, 0xbd, 0x55, 0x25, 0xf6, 0x6a, 0x93, 0xa4, 0x02, 0xc6, 0x7d, 0x5c, 0xb1, 0x2b, 0x5b, 0xff, 0xfb, 0x56, 0xf8, 0x01, 0x41, 0x90, 0xc6, 0xb6, 0xac, 0x4f, 0xfe, 0xa7, 0x41, 0x70}}},
-{{{0xdb, 0xfa, 0x9b, 0x2c, 0xd4, 0x23, 0x67, 0x2c, 0x8a, 0x63, 0x6c, 0x07, 0x26, 0x48, 0x4f, 0xc2, 0x03, 0xd2, 0x53, 0x20, 0x28, 0xed, 0x65, 0x71, 0x47, 0xa9, 0x16, 0x16, 0x12, 0xbc, 0x28, 0x33}} ,
- {{0x39, 0xc0, 0xfa, 0xfa, 0xcd, 0x33, 0x43, 0xc7, 0x97, 0x76, 0x9b, 0x93, 0x91, 0x72, 0xeb, 0xc5, 0x18, 0x67, 0x4c, 0x11, 0xf0, 0xf4, 0xe5, 0x73, 0xb2, 0x5c, 0x1b, 0xc2, 0x26, 0x3f, 0xbf, 0x2b}}},
-{{{0x86, 0xe6, 0x8c, 0x1d, 0xdf, 0xca, 0xfc, 0xd5, 0xf8, 0x3a, 0xc3, 0x44, 0x72, 0xe6, 0x78, 0x9d, 0x2b, 0x97, 0xf8, 0x28, 0x45, 0xb4, 0x20, 0xc9, 0x2a, 0x8c, 0x67, 0xaa, 0x11, 0xc5, 0x5b, 0x2f}} ,
- {{0x17, 0x0f, 0x86, 0x52, 0xd7, 0x9d, 0xc3, 0x44, 0x51, 0x76, 0x32, 0x65, 0xb4, 0x37, 0x81, 0x99, 0x46, 0x37, 0x62, 0xed, 0xcf, 0x64, 0x9d, 0x72, 0x40, 0x7a, 0x4c, 0x0b, 0x76, 0x2a, 0xfb, 0x56}}},
-{{{0x33, 0xa7, 0x90, 0x7c, 0xc3, 0x6f, 0x17, 0xa5, 0xa0, 0x67, 0x72, 0x17, 0xea, 0x7e, 0x63, 0x14, 0x83, 0xde, 0xc1, 0x71, 0x2d, 0x41, 0x32, 0x7a, 0xf3, 0xd1, 0x2b, 0xd8, 0x2a, 0xa6, 0x46, 0x36}} ,
- {{0xac, 0xcc, 0x6b, 0x7c, 0xf9, 0xb8, 0x8b, 0x08, 0x5c, 0xd0, 0x7d, 0x8f, 0x73, 0xea, 0x20, 0xda, 0x86, 0xca, 0x00, 0xc7, 0xad, 0x73, 0x4d, 0xe9, 0xe8, 0xa9, 0xda, 0x1f, 0x03, 0x06, 0xdd, 0x24}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0x9c, 0xb2, 0x61, 0x0a, 0x98, 0x2a, 0xa5, 0xd7, 0xee, 0xa9, 0xac, 0x65, 0xcb, 0x0a, 0x1e, 0xe2, 0xbe, 0xdc, 0x85, 0x59, 0x0f, 0x9c, 0xa6, 0x57, 0x34, 0xa5, 0x87, 0xeb, 0x7b, 0x1e, 0x0c, 0x3c}} ,
- {{0x2f, 0xbd, 0x84, 0x63, 0x0d, 0xb5, 0xa0, 0xf0, 0x4b, 0x9e, 0x93, 0xc6, 0x34, 0x9a, 0x34, 0xff, 0x73, 0x19, 0x2f, 0x6e, 0x54, 0x45, 0x2c, 0x92, 0x31, 0x76, 0x34, 0xf1, 0xb2, 0x26, 0xe8, 0x74}}},
-{{{0x0a, 0x67, 0x90, 0x6d, 0x0c, 0x4c, 0xcc, 0xc0, 0xe6, 0xbd, 0xa7, 0x5e, 0x55, 0x8c, 0xcd, 0x58, 0x9b, 0x11, 0xa2, 0xbb, 0x4b, 0xb1, 0x43, 0x04, 0x3c, 0x55, 0xed, 0x23, 0xfe, 0xcd, 0xb1, 0x53}} ,
- {{0x05, 0xfb, 0x75, 0xf5, 0x01, 0xaf, 0x38, 0x72, 0x58, 0xfc, 0x04, 0x29, 0x34, 0x7a, 0x67, 0xa2, 0x08, 0x50, 0x6e, 0xd0, 0x2b, 0x73, 0xd5, 0xb8, 0xe4, 0x30, 0x96, 0xad, 0x45, 0xdf, 0xa6, 0x5c}}},
-{{{0x0d, 0x88, 0x1a, 0x90, 0x7e, 0xdc, 0xd8, 0xfe, 0xc1, 0x2f, 0x5d, 0x67, 0xee, 0x67, 0x2f, 0xed, 0x6f, 0x55, 0x43, 0x5f, 0x87, 0x14, 0x35, 0x42, 0xd3, 0x75, 0xae, 0xd5, 0xd3, 0x85, 0x1a, 0x76}} ,
- {{0x87, 0xc8, 0xa0, 0x6e, 0xe1, 0xb0, 0xad, 0x6a, 0x4a, 0x34, 0x71, 0xed, 0x7c, 0xd6, 0x44, 0x03, 0x65, 0x4a, 0x5c, 0x5c, 0x04, 0xf5, 0x24, 0x3f, 0xb0, 0x16, 0x5e, 0x8c, 0xb2, 0xd2, 0xc5, 0x20}}},
-{{{0x98, 0x83, 0xc2, 0x37, 0xa0, 0x41, 0xa8, 0x48, 0x5c, 0x5f, 0xbf, 0xc8, 0xfa, 0x24, 0xe0, 0x59, 0x2c, 0xbd, 0xf6, 0x81, 0x7e, 0x88, 0xe6, 0xca, 0x04, 0xd8, 0x5d, 0x60, 0xbb, 0x74, 0xa7, 0x0b}} ,
- {{0x21, 0x13, 0x91, 0xbf, 0x77, 0x7a, 0x33, 0xbc, 0xe9, 0x07, 0x39, 0x0a, 0xdd, 0x7d, 0x06, 0x10, 0x9a, 0xee, 0x47, 0x73, 0x1b, 0x15, 0x5a, 0xfb, 0xcd, 0x4d, 0xd0, 0xd2, 0x3a, 0x01, 0xba, 0x54}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0x48, 0xd5, 0x39, 0x4a, 0x0b, 0x20, 0x6a, 0x43, 0xa0, 0x07, 0x82, 0x5e, 0x49, 0x7c, 0xc9, 0x47, 0xf1, 0x7c, 0x37, 0xb9, 0x23, 0xef, 0x6b, 0x46, 0x45, 0x8c, 0x45, 0x76, 0xdf, 0x14, 0x6b, 0x6e}} ,
- {{0x42, 0xc9, 0xca, 0x29, 0x4c, 0x76, 0x37, 0xda, 0x8a, 0x2d, 0x7c, 0x3a, 0x58, 0xf2, 0x03, 0xb4, 0xb5, 0xb9, 0x1a, 0x13, 0x2d, 0xde, 0x5f, 0x6b, 0x9d, 0xba, 0x52, 0xc9, 0x5d, 0xb3, 0xf3, 0x30}}},
-{{{0x4c, 0x6f, 0xfe, 0x6b, 0x0c, 0x62, 0xd7, 0x48, 0x71, 0xef, 0xb1, 0x85, 0x79, 0xc0, 0xed, 0x24, 0xb1, 0x08, 0x93, 0x76, 0x8e, 0xf7, 0x38, 0x8e, 0xeb, 0xfe, 0x80, 0x40, 0xaf, 0x90, 0x64, 0x49}} ,
- {{0x4a, 0x88, 0xda, 0xc1, 0x98, 0x44, 0x3c, 0x53, 0x4e, 0xdb, 0x4b, 0xb9, 0x12, 0x5f, 0xcd, 0x08, 0x04, 0xef, 0x75, 0xe7, 0xb1, 0x3a, 0xe5, 0x07, 0xfa, 0xca, 0x65, 0x7b, 0x72, 0x10, 0x64, 0x7f}}},
-{{{0x3d, 0x81, 0xf0, 0xeb, 0x16, 0xfd, 0x58, 0x33, 0x8d, 0x7c, 0x1a, 0xfb, 0x20, 0x2c, 0x8a, 0xee, 0x90, 0xbb, 0x33, 0x6d, 0x45, 0xe9, 0x8e, 0x99, 0x85, 0xe1, 0x08, 0x1f, 0xc5, 0xf1, 0xb5, 0x46}} ,
- {{0xe4, 0xe7, 0x43, 0x4b, 0xa0, 0x3f, 0x2b, 0x06, 0xba, 0x17, 0xae, 0x3d, 0xe6, 0xce, 0xbd, 0xb8, 0xed, 0x74, 0x11, 0x35, 0xec, 0x96, 0xfe, 0x31, 0xe3, 0x0e, 0x7a, 0x4e, 0xc9, 0x1d, 0xcb, 0x20}}},
-{{{0xe0, 0x67, 0xe9, 0x7b, 0xdb, 0x96, 0x5c, 0xb0, 0x32, 0xd0, 0x59, 0x31, 0x90, 0xdc, 0x92, 0x97, 0xac, 0x09, 0x38, 0x31, 0x0f, 0x7e, 0xd6, 0x5d, 0xd0, 0x06, 0xb6, 0x1f, 0xea, 0xf0, 0x5b, 0x07}} ,
- {{0x81, 0x9f, 0xc7, 0xde, 0x6b, 0x41, 0x22, 0x35, 0x14, 0x67, 0x77, 0x3e, 0x90, 0x81, 0xb0, 0xd9, 0x85, 0x4c, 0xca, 0x9b, 0x3f, 0x04, 0x59, 0xd6, 0xaa, 0x17, 0xc3, 0x88, 0x34, 0x37, 0xba, 0x43}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0x4c, 0xb6, 0x69, 0xc8, 0x81, 0x95, 0x94, 0x33, 0x92, 0x34, 0xe9, 0x3c, 0x84, 0x0d, 0x3d, 0x5a, 0x37, 0x9c, 0x22, 0xa0, 0xaa, 0x65, 0xce, 0xb4, 0xc2, 0x2d, 0x66, 0x67, 0x02, 0xff, 0x74, 0x10}} ,
- {{0x22, 0xb0, 0xd5, 0xe6, 0xc7, 0xef, 0xb1, 0xa7, 0x13, 0xda, 0x60, 0xb4, 0x80, 0xc1, 0x42, 0x7d, 0x10, 0x70, 0x97, 0x04, 0x4d, 0xda, 0x23, 0x89, 0xc2, 0x0e, 0x68, 0xcb, 0xde, 0xe0, 0x9b, 0x29}}},
-{{{0x33, 0xfe, 0x42, 0x2a, 0x36, 0x2b, 0x2e, 0x36, 0x64, 0x5c, 0x8b, 0xcc, 0x81, 0x6a, 0x15, 0x08, 0xa1, 0x27, 0xe8, 0x57, 0xe5, 0x78, 0x8e, 0xf2, 0x58, 0x19, 0x12, 0x42, 0xae, 0xc4, 0x63, 0x3e}} ,
- {{0x78, 0x96, 0x9c, 0xa7, 0xca, 0x80, 0xae, 0x02, 0x85, 0xb1, 0x7c, 0x04, 0x5c, 0xc1, 0x5b, 0x26, 0xc1, 0xba, 0xed, 0xa5, 0x59, 0x70, 0x85, 0x8c, 0x8c, 0xe8, 0x87, 0xac, 0x6a, 0x28, 0x99, 0x35}}},
-{{{0x9f, 0x04, 0x08, 0x28, 0xbe, 0x87, 0xda, 0x80, 0x28, 0x38, 0xde, 0x9f, 0xcd, 0xe4, 0xe3, 0x62, 0xfb, 0x2e, 0x46, 0x8d, 0x01, 0xb3, 0x06, 0x51, 0xd4, 0x19, 0x3b, 0x11, 0xfa, 0xe2, 0xad, 0x1e}} ,
- {{0xa0, 0x20, 0x99, 0x69, 0x0a, 0xae, 0xa3, 0x70, 0x4e, 0x64, 0x80, 0xb7, 0x85, 0x9c, 0x87, 0x54, 0x43, 0x43, 0x55, 0x80, 0x6d, 0x8d, 0x7c, 0xa9, 0x64, 0xca, 0x6c, 0x2e, 0x21, 0xd8, 0xc8, 0x6c}}},
-{{{0x91, 0x4a, 0x07, 0xad, 0x08, 0x75, 0xc1, 0x4f, 0xa4, 0xb2, 0xc3, 0x6f, 0x46, 0x3e, 0xb1, 0xce, 0x52, 0xab, 0x67, 0x09, 0x54, 0x48, 0x6b, 0x6c, 0xd7, 0x1d, 0x71, 0x76, 0xcb, 0xff, 0xdd, 0x31}} ,
- {{0x36, 0x88, 0xfa, 0xfd, 0xf0, 0x36, 0x6f, 0x07, 0x74, 0x88, 0x50, 0xd0, 0x95, 0x38, 0x4a, 0x48, 0x2e, 0x07, 0x64, 0x97, 0x11, 0x76, 0x01, 0x1a, 0x27, 0x4d, 0x8e, 0x25, 0x9a, 0x9b, 0x1c, 0x22}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0xbe, 0x57, 0xbd, 0x0e, 0x0f, 0xac, 0x5e, 0x76, 0xa3, 0x71, 0xad, 0x2b, 0x10, 0x45, 0x02, 0xec, 0x59, 0xd5, 0x5d, 0xa9, 0x44, 0xcc, 0x25, 0x4c, 0xb3, 0x3c, 0x5b, 0x69, 0x07, 0x55, 0x26, 0x6b}} ,
- {{0x30, 0x6b, 0xd4, 0xa7, 0x51, 0x29, 0xe3, 0xf9, 0x7a, 0x75, 0x2a, 0x82, 0x2f, 0xd6, 0x1d, 0x99, 0x2b, 0x80, 0xd5, 0x67, 0x1e, 0x15, 0x9d, 0xca, 0xfd, 0xeb, 0xac, 0x97, 0x35, 0x09, 0x7f, 0x3f}}},
-{{{0x35, 0x0d, 0x34, 0x0a, 0xb8, 0x67, 0x56, 0x29, 0x20, 0xf3, 0x19, 0x5f, 0xe2, 0x83, 0x42, 0x73, 0x53, 0xa8, 0xc5, 0x02, 0x19, 0x33, 0xb4, 0x64, 0xbd, 0xc3, 0x87, 0x8c, 0xd7, 0x76, 0xed, 0x25}} ,
- {{0x47, 0x39, 0x37, 0x76, 0x0d, 0x1d, 0x0c, 0xf5, 0x5a, 0x6d, 0x43, 0x88, 0x99, 0x15, 0xb4, 0x52, 0x0f, 0x2a, 0xb3, 0xb0, 0x3f, 0xa6, 0xb3, 0x26, 0xb3, 0xc7, 0x45, 0xf5, 0x92, 0x5f, 0x9b, 0x17}}},
-{{{0x9d, 0x23, 0xbd, 0x15, 0xfe, 0x52, 0x52, 0x15, 0x26, 0x79, 0x86, 0xba, 0x06, 0x56, 0x66, 0xbb, 0x8c, 0x2e, 0x10, 0x11, 0xd5, 0x4a, 0x18, 0x52, 0xda, 0x84, 0x44, 0xf0, 0x3e, 0xe9, 0x8c, 0x35}} ,
- {{0xad, 0xa0, 0x41, 0xec, 0xc8, 0x4d, 0xb9, 0xd2, 0x6e, 0x96, 0x4e, 0x5b, 0xc5, 0xc2, 0xa0, 0x1b, 0xcf, 0x0c, 0xbf, 0x17, 0x66, 0x57, 0xc1, 0x17, 0x90, 0x45, 0x71, 0xc2, 0xe1, 0x24, 0xeb, 0x27}}},
-{{{0x2c, 0xb9, 0x42, 0xa4, 0xaf, 0x3b, 0x42, 0x0e, 0xc2, 0x0f, 0xf2, 0xea, 0x83, 0xaf, 0x9a, 0x13, 0x17, 0xb0, 0xbd, 0x89, 0x17, 0xe3, 0x72, 0xcb, 0x0e, 0x76, 0x7e, 0x41, 0x63, 0x04, 0x88, 0x71}} ,
- {{0x75, 0x78, 0x38, 0x86, 0x57, 0xdd, 0x9f, 0xee, 0x54, 0x70, 0x65, 0xbf, 0xf1, 0x2c, 0xe0, 0x39, 0x0d, 0xe3, 0x89, 0xfd, 0x8e, 0x93, 0x4f, 0x43, 0xdc, 0xd5, 0x5b, 0xde, 0xf9, 0x98, 0xe5, 0x7b}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0xe7, 0x3b, 0x65, 0x11, 0xdf, 0xb2, 0xf2, 0x63, 0x94, 0x12, 0x6f, 0x5c, 0x9e, 0x77, 0xc1, 0xb6, 0xd8, 0xab, 0x58, 0x7a, 0x1d, 0x95, 0x73, 0xdd, 0xe7, 0xe3, 0x6f, 0xf2, 0x03, 0x1d, 0xdb, 0x76}} ,
- {{0xae, 0x06, 0x4e, 0x2c, 0x52, 0x1b, 0xbc, 0x5a, 0x5a, 0xa5, 0xbe, 0x27, 0xbd, 0xeb, 0xe1, 0x14, 0x17, 0x68, 0x26, 0x07, 0x03, 0xd1, 0x18, 0x0b, 0xdf, 0xf1, 0x06, 0x5c, 0xa6, 0x1b, 0xb9, 0x24}}},
-{{{0xc5, 0x66, 0x80, 0x13, 0x0e, 0x48, 0x8c, 0x87, 0x31, 0x84, 0xb4, 0x60, 0xed, 0xc5, 0xec, 0xb6, 0xc5, 0x05, 0x33, 0x5f, 0x2f, 0x7d, 0x40, 0xb6, 0x32, 0x1d, 0x38, 0x74, 0x1b, 0xf1, 0x09, 0x3d}} ,
- {{0xd4, 0x69, 0x82, 0xbc, 0x8d, 0xf8, 0x34, 0x36, 0x75, 0x55, 0x18, 0x55, 0x58, 0x3c, 0x79, 0xaf, 0x26, 0x80, 0xab, 0x9b, 0x95, 0x00, 0xf1, 0xcb, 0xda, 0xc1, 0x9f, 0xf6, 0x2f, 0xa2, 0xf4, 0x45}}},
-{{{0x17, 0xbe, 0xeb, 0x85, 0xed, 0x9e, 0xcd, 0x56, 0xf5, 0x17, 0x45, 0x42, 0xb4, 0x1f, 0x44, 0x4c, 0x05, 0x74, 0x15, 0x47, 0x00, 0xc6, 0x6a, 0x3d, 0x24, 0x09, 0x0d, 0x58, 0xb1, 0x42, 0xd7, 0x04}} ,
- {{0x8d, 0xbd, 0xa3, 0xc4, 0x06, 0x9b, 0x1f, 0x90, 0x58, 0x60, 0x74, 0xb2, 0x00, 0x3b, 0x3c, 0xd2, 0xda, 0x82, 0xbb, 0x10, 0x90, 0x69, 0x92, 0xa9, 0xb4, 0x30, 0x81, 0xe3, 0x7c, 0xa8, 0x89, 0x45}}},
-{{{0x3f, 0xdc, 0x05, 0xcb, 0x41, 0x3c, 0xc8, 0x23, 0x04, 0x2c, 0x38, 0x99, 0xe3, 0x68, 0x55, 0xf9, 0xd3, 0x32, 0xc7, 0xbf, 0xfa, 0xd4, 0x1b, 0x5d, 0xde, 0xdc, 0x10, 0x42, 0xc0, 0x42, 0xd9, 0x75}} ,
- {{0x2d, 0xab, 0x35, 0x4e, 0x87, 0xc4, 0x65, 0x97, 0x67, 0x24, 0xa4, 0x47, 0xad, 0x3f, 0x8e, 0xf3, 0xcb, 0x31, 0x17, 0x77, 0xc5, 0xe2, 0xd7, 0x8f, 0x3c, 0xc1, 0xcd, 0x56, 0x48, 0xc1, 0x6c, 0x69}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0x14, 0xae, 0x5f, 0x88, 0x7b, 0xa5, 0x90, 0xdf, 0x10, 0xb2, 0x8b, 0x5e, 0x24, 0x17, 0xc3, 0xa3, 0xd4, 0x0f, 0x92, 0x61, 0x1a, 0x19, 0x5a, 0xad, 0x76, 0xbd, 0xd8, 0x1c, 0xdd, 0xe0, 0x12, 0x6d}} ,
- {{0x8e, 0xbd, 0x70, 0x8f, 0x02, 0xa3, 0x24, 0x4d, 0x5a, 0x67, 0xc4, 0xda, 0xf7, 0x20, 0x0f, 0x81, 0x5b, 0x7a, 0x05, 0x24, 0x67, 0x83, 0x0b, 0x2a, 0x80, 0xe7, 0xfd, 0x74, 0x4b, 0x9e, 0x5c, 0x0d}}},
-{{{0x94, 0xd5, 0x5f, 0x1f, 0xa2, 0xfb, 0xeb, 0xe1, 0x07, 0x34, 0xf8, 0x20, 0xad, 0x81, 0x30, 0x06, 0x2d, 0xa1, 0x81, 0x95, 0x36, 0xcf, 0x11, 0x0b, 0xaf, 0xc1, 0x2b, 0x9a, 0x6c, 0x55, 0xc1, 0x16}} ,
- {{0x36, 0x4f, 0xf1, 0x5e, 0x74, 0x35, 0x13, 0x28, 0xd7, 0x11, 0xcf, 0xb8, 0xde, 0x93, 0xb3, 0x05, 0xb8, 0xb5, 0x73, 0xe9, 0xeb, 0xad, 0x19, 0x1e, 0x89, 0x0f, 0x8b, 0x15, 0xd5, 0x8c, 0xe3, 0x23}}},
-{{{0x33, 0x79, 0xe7, 0x18, 0xe6, 0x0f, 0x57, 0x93, 0x15, 0xa0, 0xa7, 0xaa, 0xc4, 0xbf, 0x4f, 0x30, 0x74, 0x95, 0x5e, 0x69, 0x4a, 0x5b, 0x45, 0xe4, 0x00, 0xeb, 0x23, 0x74, 0x4c, 0xdf, 0x6b, 0x45}} ,
- {{0x97, 0x29, 0x6c, 0xc4, 0x42, 0x0b, 0xdd, 0xc0, 0x29, 0x5c, 0x9b, 0x34, 0x97, 0xd0, 0xc7, 0x79, 0x80, 0x63, 0x74, 0xe4, 0x8e, 0x37, 0xb0, 0x2b, 0x7c, 0xe8, 0x68, 0x6c, 0xc3, 0x82, 0x97, 0x57}}},
-{{{0x22, 0xbe, 0x83, 0xb6, 0x4b, 0x80, 0x6b, 0x43, 0x24, 0x5e, 0xef, 0x99, 0x9b, 0xa8, 0xfc, 0x25, 0x8d, 0x3b, 0x03, 0x94, 0x2b, 0x3e, 0xe7, 0x95, 0x76, 0x9b, 0xcc, 0x15, 0xdb, 0x32, 0xe6, 0x66}} ,
- {{0x84, 0xf0, 0x4a, 0x13, 0xa6, 0xd6, 0xfa, 0x93, 0x46, 0x07, 0xf6, 0x7e, 0x5c, 0x6d, 0x5e, 0xf6, 0xa6, 0xe7, 0x48, 0xf0, 0x06, 0xea, 0xff, 0x90, 0xc1, 0xcc, 0x4c, 0x19, 0x9c, 0x3c, 0x4e, 0x53}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0x2a, 0x50, 0xe3, 0x07, 0x15, 0x59, 0xf2, 0x8b, 0x81, 0xf2, 0xf3, 0xd3, 0x6c, 0x99, 0x8c, 0x70, 0x67, 0xec, 0xcc, 0xee, 0x9e, 0x59, 0x45, 0x59, 0x7d, 0x47, 0x75, 0x69, 0xf5, 0x24, 0x93, 0x5d}} ,
- {{0x6a, 0x4f, 0x1b, 0xbe, 0x6b, 0x30, 0xcf, 0x75, 0x46, 0xe3, 0x7b, 0x9d, 0xfc, 0xcd, 0xd8, 0x5c, 0x1f, 0xb4, 0xc8, 0xe2, 0x24, 0xec, 0x1a, 0x28, 0x05, 0x32, 0x57, 0xfd, 0x3c, 0x5a, 0x98, 0x10}}},
-{{{0xa3, 0xdb, 0xf7, 0x30, 0xd8, 0xc2, 0x9a, 0xe1, 0xd3, 0xce, 0x22, 0xe5, 0x80, 0x1e, 0xd9, 0xe4, 0x1f, 0xab, 0xc0, 0x71, 0x1a, 0x86, 0x0e, 0x27, 0x99, 0x5b, 0xfa, 0x76, 0x99, 0xb0, 0x08, 0x3c}} ,
- {{0x2a, 0x93, 0xd2, 0x85, 0x1b, 0x6a, 0x5d, 0xa6, 0xee, 0xd1, 0xd1, 0x33, 0xbd, 0x6a, 0x36, 0x73, 0x37, 0x3a, 0x44, 0xb4, 0xec, 0xa9, 0x7a, 0xde, 0x83, 0x40, 0xd7, 0xdf, 0x28, 0xba, 0xa2, 0x30}}},
-{{{0xd3, 0xb5, 0x6d, 0x05, 0x3f, 0x9f, 0xf3, 0x15, 0x8d, 0x7c, 0xca, 0xc9, 0xfc, 0x8a, 0x7c, 0x94, 0xb0, 0x63, 0x36, 0x9b, 0x78, 0xd1, 0x91, 0x1f, 0x93, 0xd8, 0x57, 0x43, 0xde, 0x76, 0xa3, 0x43}} ,
- {{0x9b, 0x35, 0xe2, 0xa9, 0x3d, 0x32, 0x1e, 0xbb, 0x16, 0x28, 0x70, 0xe9, 0x45, 0x2f, 0x8f, 0x70, 0x7f, 0x08, 0x7e, 0x53, 0xc4, 0x7a, 0xbf, 0xf7, 0xe1, 0xa4, 0x6a, 0xd8, 0xac, 0x64, 0x1b, 0x11}}},
-{{{0xb2, 0xeb, 0x47, 0x46, 0x18, 0x3e, 0x1f, 0x99, 0x0c, 0xcc, 0xf1, 0x2c, 0xe0, 0xe7, 0x8f, 0xe0, 0x01, 0x7e, 0x65, 0xb8, 0x0c, 0xd0, 0xfb, 0xc8, 0xb9, 0x90, 0x98, 0x33, 0x61, 0x3b, 0xd8, 0x27}} ,
- {{0xa0, 0xbe, 0x72, 0x3a, 0x50, 0x4b, 0x74, 0xab, 0x01, 0xc8, 0x93, 0xc5, 0xe4, 0xc7, 0x08, 0x6c, 0xb4, 0xca, 0xee, 0xeb, 0x8e, 0xd7, 0x4e, 0x26, 0xc6, 0x1d, 0xe2, 0x71, 0xaf, 0x89, 0xa0, 0x2a}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0x98, 0x0b, 0xe4, 0xde, 0xdb, 0xa8, 0xfa, 0x82, 0x74, 0x06, 0x52, 0x6d, 0x08, 0x52, 0x8a, 0xff, 0x62, 0xc5, 0x6a, 0x44, 0x0f, 0x51, 0x8c, 0x1f, 0x6e, 0xb6, 0xc6, 0x2c, 0x81, 0xd3, 0x76, 0x46}} ,
- {{0xf4, 0x29, 0x74, 0x2e, 0x80, 0xa7, 0x1a, 0x8f, 0xf6, 0xbd, 0xd6, 0x8e, 0xbf, 0xc1, 0x95, 0x2a, 0xeb, 0xa0, 0x7f, 0x45, 0xa0, 0x50, 0x14, 0x05, 0xb1, 0x57, 0x4c, 0x74, 0xb7, 0xe2, 0x89, 0x7d}}},
-{{{0x07, 0xee, 0xa7, 0xad, 0xb7, 0x09, 0x0b, 0x49, 0x4e, 0xbf, 0xca, 0xe5, 0x21, 0xe6, 0xe6, 0xaf, 0xd5, 0x67, 0xf3, 0xce, 0x7e, 0x7c, 0x93, 0x7b, 0x5a, 0x10, 0x12, 0x0e, 0x6c, 0x06, 0x11, 0x75}} ,
- {{0xd5, 0xfc, 0x86, 0xa3, 0x3b, 0xa3, 0x3e, 0x0a, 0xfb, 0x0b, 0xf7, 0x36, 0xb1, 0x5b, 0xda, 0x70, 0xb7, 0x00, 0xa7, 0xda, 0x88, 0x8f, 0x84, 0xa8, 0xbc, 0x1c, 0x39, 0xb8, 0x65, 0xf3, 0x4d, 0x60}}},
-{{{0x96, 0x9d, 0x31, 0xf4, 0xa2, 0xbe, 0x81, 0xb9, 0xa5, 0x59, 0x9e, 0xba, 0x07, 0xbe, 0x74, 0x58, 0xd8, 0xeb, 0xc5, 0x9f, 0x3d, 0xd1, 0xf4, 0xae, 0xce, 0x53, 0xdf, 0x4f, 0xc7, 0x2a, 0x89, 0x4d}} ,
- {{0x29, 0xd8, 0xf2, 0xaa, 0xe9, 0x0e, 0xf7, 0x2e, 0x5f, 0x9d, 0x8a, 0x5b, 0x09, 0xed, 0xc9, 0x24, 0x22, 0xf4, 0x0f, 0x25, 0x8f, 0x1c, 0x84, 0x6e, 0x34, 0x14, 0x6c, 0xea, 0xb3, 0x86, 0x5d, 0x04}}},
-{{{0x07, 0x98, 0x61, 0xe8, 0x6a, 0xd2, 0x81, 0x49, 0x25, 0xd5, 0x5b, 0x18, 0xc7, 0x35, 0x52, 0x51, 0xa4, 0x46, 0xad, 0x18, 0x0d, 0xc9, 0x5f, 0x18, 0x91, 0x3b, 0xb4, 0xc0, 0x60, 0x59, 0x8d, 0x66}} ,
- {{0x03, 0x1b, 0x79, 0x53, 0x6e, 0x24, 0xae, 0x57, 0xd9, 0x58, 0x09, 0x85, 0x48, 0xa2, 0xd3, 0xb5, 0xe2, 0x4d, 0x11, 0x82, 0xe6, 0x86, 0x3c, 0xe9, 0xb1, 0x00, 0x19, 0xc2, 0x57, 0xf7, 0x66, 0x7a}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0x0f, 0xe3, 0x89, 0x03, 0xd7, 0x22, 0x95, 0x9f, 0xca, 0xb4, 0x8d, 0x9e, 0x6d, 0x97, 0xff, 0x8d, 0x21, 0x59, 0x07, 0xef, 0x03, 0x2d, 0x5e, 0xf8, 0x44, 0x46, 0xe7, 0x85, 0x80, 0xc5, 0x89, 0x50}} ,
- {{0x8b, 0xd8, 0x53, 0x86, 0x24, 0x86, 0x29, 0x52, 0x01, 0xfa, 0x20, 0xc3, 0x4e, 0x95, 0xcb, 0xad, 0x7b, 0x34, 0x94, 0x30, 0xb7, 0x7a, 0xfa, 0x96, 0x41, 0x60, 0x2b, 0xcb, 0x59, 0xb9, 0xca, 0x50}}},
-{{{0xc2, 0x5b, 0x9b, 0x78, 0x23, 0x1b, 0x3a, 0x88, 0x94, 0x5f, 0x0a, 0x9b, 0x98, 0x2b, 0x6e, 0x53, 0x11, 0xf6, 0xff, 0xc6, 0x7d, 0x42, 0xcc, 0x02, 0x80, 0x40, 0x0d, 0x1e, 0xfb, 0xaf, 0x61, 0x07}} ,
- {{0xb0, 0xe6, 0x2f, 0x81, 0x70, 0xa1, 0x2e, 0x39, 0x04, 0x7c, 0xc4, 0x2c, 0x87, 0x45, 0x4a, 0x5b, 0x69, 0x97, 0xac, 0x6d, 0x2c, 0x10, 0x42, 0x7c, 0x3b, 0x15, 0x70, 0x60, 0x0e, 0x11, 0x6d, 0x3a}}},
-{{{0x9b, 0x18, 0x80, 0x5e, 0xdb, 0x05, 0xbd, 0xc6, 0xb7, 0x3c, 0xc2, 0x40, 0x4d, 0x5d, 0xce, 0x97, 0x8a, 0x34, 0x15, 0xab, 0x28, 0x5d, 0x10, 0xf0, 0x37, 0x0c, 0xcc, 0x16, 0xfa, 0x1f, 0x33, 0x0d}} ,
- {{0x19, 0xf9, 0x35, 0xaa, 0x59, 0x1a, 0x0c, 0x5c, 0x06, 0xfc, 0x6a, 0x0b, 0x97, 0x53, 0x36, 0xfc, 0x2a, 0xa5, 0x5a, 0x9b, 0x30, 0xef, 0x23, 0xaf, 0x39, 0x5d, 0x9a, 0x6b, 0x75, 0x57, 0x48, 0x0b}}},
-{{{0x26, 0xdc, 0x76, 0x3b, 0xfc, 0xf9, 0x9c, 0x3f, 0x89, 0x0b, 0x62, 0x53, 0xaf, 0x83, 0x01, 0x2e, 0xbc, 0x6a, 0xc6, 0x03, 0x0d, 0x75, 0x2a, 0x0d, 0xe6, 0x94, 0x54, 0xcf, 0xb3, 0xe5, 0x96, 0x25}} ,
- {{0xfe, 0x82, 0xb1, 0x74, 0x31, 0x8a, 0xa7, 0x6f, 0x56, 0xbd, 0x8d, 0xf4, 0xe0, 0x94, 0x51, 0x59, 0xde, 0x2c, 0x5a, 0xf4, 0x84, 0x6b, 0x4a, 0x88, 0x93, 0xc0, 0x0c, 0x9a, 0xac, 0xa7, 0xa0, 0x68}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0x25, 0x0d, 0xd6, 0xc7, 0x23, 0x47, 0x10, 0xad, 0xc7, 0x08, 0x5c, 0x87, 0x87, 0x93, 0x98, 0x18, 0xb8, 0xd3, 0x9c, 0xac, 0x5a, 0x3d, 0xc5, 0x75, 0xf8, 0x49, 0x32, 0x14, 0xcc, 0x51, 0x96, 0x24}} ,
- {{0x65, 0x9c, 0x5d, 0xf0, 0x37, 0x04, 0xf0, 0x34, 0x69, 0x2a, 0xf0, 0xa5, 0x64, 0xca, 0xde, 0x2b, 0x5b, 0x15, 0x10, 0xd2, 0xab, 0x06, 0xdd, 0xc4, 0xb0, 0xb6, 0x5b, 0xc1, 0x17, 0xdf, 0x8f, 0x02}}},
-{{{0xbd, 0x59, 0x3d, 0xbf, 0x5c, 0x31, 0x44, 0x2c, 0x32, 0x94, 0x04, 0x60, 0x84, 0x0f, 0xad, 0x00, 0xb6, 0x8f, 0xc9, 0x1d, 0xcc, 0x5c, 0xa2, 0x49, 0x0e, 0x50, 0x91, 0x08, 0x9a, 0x43, 0x55, 0x05}} ,
- {{0x5d, 0x93, 0x55, 0xdf, 0x9b, 0x12, 0x19, 0xec, 0x93, 0x85, 0x42, 0x9e, 0x66, 0x0f, 0x9d, 0xaf, 0x99, 0xaf, 0x26, 0x89, 0xbc, 0x61, 0xfd, 0xff, 0xce, 0x4b, 0xf4, 0x33, 0x95, 0xc9, 0x35, 0x58}}},
-{{{0x12, 0x55, 0xf9, 0xda, 0xcb, 0x44, 0xa7, 0xdc, 0x57, 0xe2, 0xf9, 0x9a, 0xe6, 0x07, 0x23, 0x60, 0x54, 0xa7, 0x39, 0xa5, 0x9b, 0x84, 0x56, 0x6e, 0xaa, 0x8b, 0x8f, 0xb0, 0x2c, 0x87, 0xaf, 0x67}} ,
- {{0x00, 0xa9, 0x4c, 0xb2, 0x12, 0xf8, 0x32, 0xa8, 0x7a, 0x00, 0x4b, 0x49, 0x32, 0xba, 0x1f, 0x5d, 0x44, 0x8e, 0x44, 0x7a, 0xdc, 0x11, 0xfb, 0x39, 0x08, 0x57, 0x87, 0xa5, 0x12, 0x42, 0x93, 0x0e}}},
-{{{0x17, 0xb4, 0xae, 0x72, 0x59, 0xd0, 0xaa, 0xa8, 0x16, 0x8b, 0x63, 0x11, 0xb3, 0x43, 0x04, 0xda, 0x0c, 0xa8, 0xb7, 0x68, 0xdd, 0x4e, 0x54, 0xe7, 0xaf, 0x5d, 0x5d, 0x05, 0x76, 0x36, 0xec, 0x0d}} ,
- {{0x6d, 0x7c, 0x82, 0x32, 0x38, 0x55, 0x57, 0x74, 0x5b, 0x7d, 0xc3, 0xc4, 0xfb, 0x06, 0x29, 0xf0, 0x13, 0x55, 0x54, 0xc6, 0xa7, 0xdc, 0x4c, 0x9f, 0x98, 0x49, 0x20, 0xa8, 0xc3, 0x8d, 0xfa, 0x48}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0x87, 0x47, 0x9d, 0xe9, 0x25, 0xd5, 0xe3, 0x47, 0x78, 0xdf, 0x85, 0xa7, 0x85, 0x5e, 0x7a, 0x4c, 0x5f, 0x79, 0x1a, 0xf3, 0xa2, 0xb2, 0x28, 0xa0, 0x9c, 0xdd, 0x30, 0x40, 0xd4, 0x38, 0xbd, 0x28}} ,
- {{0xfc, 0xbb, 0xd5, 0x78, 0x6d, 0x1d, 0xd4, 0x99, 0xb4, 0xaa, 0x44, 0x44, 0x7a, 0x1b, 0xd8, 0xfe, 0xb4, 0x99, 0xb9, 0xcc, 0xe7, 0xc4, 0xd3, 0x3a, 0x73, 0x83, 0x41, 0x5c, 0x40, 0xd7, 0x2d, 0x55}}},
-{{{0x26, 0xe1, 0x7b, 0x5f, 0xe5, 0xdc, 0x3f, 0x7d, 0xa1, 0xa7, 0x26, 0x44, 0x22, 0x23, 0xc0, 0x8f, 0x7d, 0xf1, 0xb5, 0x11, 0x47, 0x7b, 0x19, 0xd4, 0x75, 0x6f, 0x1e, 0xa5, 0x27, 0xfe, 0xc8, 0x0e}} ,
- {{0xd3, 0x11, 0x3d, 0xab, 0xef, 0x2c, 0xed, 0xb1, 0x3d, 0x7c, 0x32, 0x81, 0x6b, 0xfe, 0xf8, 0x1c, 0x3c, 0x7b, 0xc0, 0x61, 0xdf, 0xb8, 0x75, 0x76, 0x7f, 0xaa, 0xd8, 0x93, 0xaf, 0x3d, 0xe8, 0x3d}}},
-{{{0xfd, 0x5b, 0x4e, 0x8d, 0xb6, 0x7e, 0x82, 0x9b, 0xef, 0xce, 0x04, 0x69, 0x51, 0x52, 0xff, 0xef, 0xa0, 0x52, 0xb5, 0x79, 0x17, 0x5e, 0x2f, 0xde, 0xd6, 0x3c, 0x2d, 0xa0, 0x43, 0xb4, 0x0b, 0x19}} ,
- {{0xc0, 0x61, 0x48, 0x48, 0x17, 0xf4, 0x9e, 0x18, 0x51, 0x2d, 0xea, 0x2f, 0xf2, 0xf2, 0xe0, 0xa3, 0x14, 0xb7, 0x8b, 0x3a, 0x30, 0xf5, 0x81, 0xc1, 0x5d, 0x71, 0x39, 0x62, 0x55, 0x1f, 0x60, 0x5a}}},
-{{{0xe5, 0x89, 0x8a, 0x76, 0x6c, 0xdb, 0x4d, 0x0a, 0x5b, 0x72, 0x9d, 0x59, 0x6e, 0x63, 0x63, 0x18, 0x7c, 0xe3, 0xfa, 0xe2, 0xdb, 0xa1, 0x8d, 0xf4, 0xa5, 0xd7, 0x16, 0xb2, 0xd0, 0xb3, 0x3f, 0x39}} ,
- {{0xce, 0x60, 0x09, 0x6c, 0xf5, 0x76, 0x17, 0x24, 0x80, 0x3a, 0x96, 0xc7, 0x94, 0x2e, 0xf7, 0x6b, 0xef, 0xb5, 0x05, 0x96, 0xef, 0xd3, 0x7b, 0x51, 0xda, 0x05, 0x44, 0x67, 0xbc, 0x07, 0x21, 0x4e}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0xe9, 0x73, 0x6f, 0x21, 0xb9, 0xde, 0x22, 0x7d, 0xeb, 0x97, 0x31, 0x10, 0xa3, 0xea, 0xe1, 0xc6, 0x37, 0xeb, 0x8f, 0x43, 0x58, 0xde, 0x41, 0x64, 0x0e, 0x3e, 0x07, 0x99, 0x3d, 0xf1, 0xdf, 0x1e}} ,
- {{0xf8, 0xad, 0x43, 0xc2, 0x17, 0x06, 0xe2, 0xe4, 0xa9, 0x86, 0xcd, 0x18, 0xd7, 0x78, 0xc8, 0x74, 0x66, 0xd2, 0x09, 0x18, 0xa5, 0xf1, 0xca, 0xa6, 0x62, 0x92, 0xc1, 0xcb, 0x00, 0xeb, 0x42, 0x2e}}},
-{{{0x7b, 0x34, 0x24, 0x4c, 0xcf, 0x38, 0xe5, 0x6c, 0x0a, 0x01, 0x2c, 0x22, 0x0b, 0x24, 0x38, 0xad, 0x24, 0x7e, 0x19, 0xf0, 0x6c, 0xf9, 0x31, 0xf4, 0x35, 0x11, 0xf6, 0x46, 0x33, 0x3a, 0x23, 0x59}} ,
- {{0x20, 0x0b, 0xa1, 0x08, 0x19, 0xad, 0x39, 0x54, 0xea, 0x3e, 0x23, 0x09, 0xb6, 0xe2, 0xd2, 0xbc, 0x4d, 0xfc, 0x9c, 0xf0, 0x13, 0x16, 0x22, 0x3f, 0xb9, 0xd2, 0x11, 0x86, 0x90, 0x55, 0xce, 0x3c}}},
-{{{0xc4, 0x0b, 0x4b, 0x62, 0x99, 0x37, 0x84, 0x3f, 0x74, 0xa2, 0xf9, 0xce, 0xe2, 0x0b, 0x0f, 0x2a, 0x3d, 0xa3, 0xe3, 0xdb, 0x5a, 0x9d, 0x93, 0xcc, 0xa5, 0xef, 0x82, 0x91, 0x1d, 0xe6, 0x6c, 0x68}} ,
- {{0xa3, 0x64, 0x17, 0x9b, 0x8b, 0xc8, 0x3a, 0x61, 0xe6, 0x9d, 0xc6, 0xed, 0x7b, 0x03, 0x52, 0x26, 0x9d, 0x3a, 0xb3, 0x13, 0xcc, 0x8a, 0xfd, 0x2c, 0x1a, 0x1d, 0xed, 0x13, 0xd0, 0x55, 0x57, 0x0e}}},
-{{{0x1a, 0xea, 0xbf, 0xfd, 0x4a, 0x3c, 0x8e, 0xec, 0x29, 0x7e, 0x77, 0x77, 0x12, 0x99, 0xd7, 0x84, 0xf9, 0x55, 0x7f, 0xf1, 0x8b, 0xb4, 0xd2, 0x95, 0xa3, 0x8d, 0xf0, 0x8a, 0xa7, 0xeb, 0x82, 0x4b}} ,
- {{0x2c, 0x28, 0xf4, 0x3a, 0xf6, 0xde, 0x0a, 0xe0, 0x41, 0x44, 0x23, 0xf8, 0x3f, 0x03, 0x64, 0x9f, 0xc3, 0x55, 0x4c, 0xc6, 0xc1, 0x94, 0x1c, 0x24, 0x5d, 0x5f, 0x92, 0x45, 0x96, 0x57, 0x37, 0x14}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0xc1, 0xcd, 0x90, 0x66, 0xb9, 0x76, 0xa0, 0x5b, 0xa5, 0x85, 0x75, 0x23, 0xf9, 0x89, 0xa5, 0x82, 0xb2, 0x6f, 0xb1, 0xeb, 0xc4, 0x69, 0x6f, 0x18, 0x5a, 0xed, 0x94, 0x3d, 0x9d, 0xd9, 0x2c, 0x1a}} ,
- {{0x35, 0xb0, 0xe6, 0x73, 0x06, 0xb7, 0x37, 0xe0, 0xf8, 0xb0, 0x22, 0xe8, 0xd2, 0xed, 0x0b, 0xef, 0xe6, 0xc6, 0x5a, 0x99, 0x9e, 0x1a, 0x9f, 0x04, 0x97, 0xe4, 0x4d, 0x0b, 0xbe, 0xba, 0x44, 0x40}}},
-{{{0xc1, 0x56, 0x96, 0x91, 0x5f, 0x1f, 0xbb, 0x54, 0x6f, 0x88, 0x89, 0x0a, 0xb2, 0xd6, 0x41, 0x42, 0x6a, 0x82, 0xee, 0x14, 0xaa, 0x76, 0x30, 0x65, 0x0f, 0x67, 0x39, 0xa6, 0x51, 0x7c, 0x49, 0x24}} ,
- {{0x35, 0xa3, 0x78, 0xd1, 0x11, 0x0f, 0x75, 0xd3, 0x70, 0x46, 0xdb, 0x20, 0x51, 0xcb, 0x92, 0x80, 0x54, 0x10, 0x74, 0x36, 0x86, 0xa9, 0xd7, 0xa3, 0x08, 0x78, 0xf1, 0x01, 0x29, 0xf8, 0x80, 0x3b}}},
-{{{0xdb, 0xa7, 0x9d, 0x9d, 0xbf, 0xa0, 0xcc, 0xed, 0x53, 0xa2, 0xa2, 0x19, 0x39, 0x48, 0x83, 0x19, 0x37, 0x58, 0xd1, 0x04, 0x28, 0x40, 0xf7, 0x8a, 0xc2, 0x08, 0xb7, 0xa5, 0x42, 0xcf, 0x53, 0x4c}} ,
- {{0xa7, 0xbb, 0xf6, 0x8e, 0xad, 0xdd, 0xf7, 0x90, 0xdd, 0x5f, 0x93, 0x89, 0xae, 0x04, 0x37, 0xe6, 0x9a, 0xb7, 0xe8, 0xc0, 0xdf, 0x16, 0x2a, 0xbf, 0xc4, 0x3a, 0x3c, 0x41, 0xd5, 0x89, 0x72, 0x5a}}},
-{{{0x1f, 0x96, 0xff, 0x34, 0x2c, 0x13, 0x21, 0xcb, 0x0a, 0x89, 0x85, 0xbe, 0xb3, 0x70, 0x9e, 0x1e, 0xde, 0x97, 0xaf, 0x96, 0x30, 0xf7, 0x48, 0x89, 0x40, 0x8d, 0x07, 0xf1, 0x25, 0xf0, 0x30, 0x58}} ,
- {{0x1e, 0xd4, 0x93, 0x57, 0xe2, 0x17, 0xe7, 0x9d, 0xab, 0x3c, 0x55, 0x03, 0x82, 0x2f, 0x2b, 0xdb, 0x56, 0x1e, 0x30, 0x2e, 0x24, 0x47, 0x6e, 0xe6, 0xff, 0x33, 0x24, 0x2c, 0x75, 0x51, 0xd4, 0x67}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0x2b, 0x06, 0xd9, 0xa1, 0x5d, 0xe1, 0xf4, 0xd1, 0x1e, 0x3c, 0x9a, 0xc6, 0x29, 0x2b, 0x13, 0x13, 0x78, 0xc0, 0xd8, 0x16, 0x17, 0x2d, 0x9e, 0xa9, 0xc9, 0x79, 0x57, 0xab, 0x24, 0x91, 0x92, 0x19}} ,
- {{0x69, 0xfb, 0xa1, 0x9c, 0xa6, 0x75, 0x49, 0x7d, 0x60, 0x73, 0x40, 0x42, 0xc4, 0x13, 0x0a, 0x95, 0x79, 0x1e, 0x04, 0x83, 0x94, 0x99, 0x9b, 0x1e, 0x0c, 0xe8, 0x1f, 0x54, 0xef, 0xcb, 0xc0, 0x52}}},
-{{{0x14, 0x89, 0x73, 0xa1, 0x37, 0x87, 0x6a, 0x7a, 0xcf, 0x1d, 0xd9, 0x2e, 0x1a, 0x67, 0xed, 0x74, 0xc0, 0xf0, 0x9c, 0x33, 0xdd, 0xdf, 0x08, 0xbf, 0x7b, 0xd1, 0x66, 0xda, 0xe6, 0xc9, 0x49, 0x08}} ,
- {{0xe9, 0xdd, 0x5e, 0x55, 0xb0, 0x0a, 0xde, 0x21, 0x4c, 0x5a, 0x2e, 0xd4, 0x80, 0x3a, 0x57, 0x92, 0x7a, 0xf1, 0xc4, 0x2c, 0x40, 0xaf, 0x2f, 0xc9, 0x92, 0x03, 0xe5, 0x5a, 0xbc, 0xdc, 0xf4, 0x09}}},
-{{{0xf3, 0xe1, 0x2b, 0x7c, 0x05, 0x86, 0x80, 0x93, 0x4a, 0xad, 0xb4, 0x8f, 0x7e, 0x99, 0x0c, 0xfd, 0xcd, 0xef, 0xd1, 0xff, 0x2c, 0x69, 0x34, 0x13, 0x41, 0x64, 0xcf, 0x3b, 0xd0, 0x90, 0x09, 0x1e}} ,
- {{0x9d, 0x45, 0xd6, 0x80, 0xe6, 0x45, 0xaa, 0xf4, 0x15, 0xaa, 0x5c, 0x34, 0x87, 0x99, 0xa2, 0x8c, 0x26, 0x84, 0x62, 0x7d, 0xb6, 0x29, 0xc0, 0x52, 0xea, 0xf5, 0x81, 0x18, 0x0f, 0x35, 0xa9, 0x0e}}},
-{{{0xe7, 0x20, 0x72, 0x7c, 0x6d, 0x94, 0x5f, 0x52, 0x44, 0x54, 0xe3, 0xf1, 0xb2, 0xb0, 0x36, 0x46, 0x0f, 0xae, 0x92, 0xe8, 0x70, 0x9d, 0x6e, 0x79, 0xb1, 0xad, 0x37, 0xa9, 0x5f, 0xc0, 0xde, 0x03}} ,
- {{0x15, 0x55, 0x37, 0xc6, 0x1c, 0x27, 0x1c, 0x6d, 0x14, 0x4f, 0xca, 0xa4, 0xc4, 0x88, 0x25, 0x46, 0x39, 0xfc, 0x5a, 0xe5, 0xfe, 0x29, 0x11, 0x69, 0xf5, 0x72, 0x84, 0x4d, 0x78, 0x9f, 0x94, 0x15}}},
-{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
- {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-{{{0xec, 0xd3, 0xff, 0x57, 0x0b, 0xb0, 0xb2, 0xdc, 0xf8, 0x4f, 0xe2, 0x12, 0xd5, 0x36, 0xbe, 0x6b, 0x09, 0x43, 0x6d, 0xa3, 0x4d, 0x90, 0x2d, 0xb8, 0x74, 0xe8, 0x71, 0x45, 0x19, 0x8b, 0x0c, 0x6a}} ,
- {{0xb8, 0x42, 0x1c, 0x03, 0xad, 0x2c, 0x03, 0x8e, 0xac, 0xd7, 0x98, 0x29, 0x13, 0xc6, 0x02, 0x29, 0xb5, 0xd4, 0xe7, 0xcf, 0xcc, 0x8b, 0x83, 0xec, 0x35, 0xc7, 0x9c, 0x74, 0xb7, 0xad, 0x85, 0x5f}}},
-{{{0x78, 0x84, 0xe1, 0x56, 0x45, 0x69, 0x68, 0x5a, 0x4f, 0xb8, 0xb1, 0x29, 0xff, 0x33, 0x03, 0x31, 0xb7, 0xcb, 0x96, 0x25, 0xe6, 0xe6, 0x41, 0x98, 0x1a, 0xbb, 0x03, 0x56, 0xf2, 0xb2, 0x91, 0x34}} ,
- {{0x2c, 0x6c, 0xf7, 0x66, 0xa4, 0x62, 0x6b, 0x39, 0xb3, 0xba, 0x65, 0xd3, 0x1c, 0xf8, 0x11, 0xaa, 0xbe, 0xdc, 0x80, 0x59, 0x87, 0xf5, 0x7b, 0xe5, 0xe3, 0xb3, 0x3e, 0x39, 0xda, 0xbe, 0x88, 0x09}}},
-{{{0x8b, 0xf1, 0xa0, 0xf5, 0xdc, 0x29, 0xb4, 0xe2, 0x07, 0xc6, 0x7a, 0x00, 0xd0, 0x89, 0x17, 0x51, 0xd4, 0xbb, 0xd4, 0x22, 0xea, 0x7e, 0x7d, 0x7c, 0x24, 0xea, 0xf2, 0xe8, 0x22, 0x12, 0x95, 0x06}} ,
- {{0xda, 0x7c, 0xa4, 0x0c, 0xf4, 0xba, 0x6e, 0xe1, 0x89, 0xb5, 0x59, 0xca, 0xf1, 0xc0, 0x29, 0x36, 0x09, 0x44, 0xe2, 0x7f, 0xd1, 0x63, 0x15, 0x99, 0xea, 0x25, 0xcf, 0x0c, 0x9d, 0xc0, 0x44, 0x6f}}},
-{{{0x1d, 0x86, 0x4e, 0xcf, 0xf7, 0x37, 0x10, 0x25, 0x8f, 0x12, 0xfb, 0x19, 0xfb, 0xe0, 0xed, 0x10, 0xc8, 0xe2, 0xf5, 0x75, 0xb1, 0x33, 0xc0, 0x96, 0x0d, 0xfb, 0x15, 0x6c, 0x0d, 0x07, 0x5f, 0x05}} ,
- {{0x69, 0x3e, 0x47, 0x97, 0x2c, 0xaf, 0x52, 0x7c, 0x78, 0x83, 0xad, 0x1b, 0x39, 0x82, 0x2f, 0x02, 0x6f, 0x47, 0xdb, 0x2a, 0xb0, 0xe1, 0x91, 0x99, 0x55, 0xb8, 0x99, 0x3a, 0xa0, 0x44, 0x11, 0x51}}}
diff --git a/crypto/openssh/install-sh b/crypto/openssh/install-sh
index 377bb8687ffe..ec298b537402 100755
--- a/crypto/openssh/install-sh
+++ b/crypto/openssh/install-sh
@@ -1,527 +1,541 @@
#!/bin/sh
# install - install a program, script, or datafile
-scriptversion=2011-11-20.07; # UTC
+scriptversion=2020-11-14.01; # UTC
# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
# following copyright and license.
#
# Copyright (C) 1994 X Consortium
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name of the X Consortium shall not
# be used in advertising or otherwise to promote the sale, use or other deal-
# ings in this Software without prior written authorization from the X Consor-
# tium.
#
#
# FSF changes to this file are in the public domain.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# 'make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch.
+tab=' '
nl='
'
-IFS=" "" $nl"
+IFS=" $tab$nl"
-# set DOITPROG to echo to test this script
+# Set DOITPROG to "echo" to test this script.
-# Don't use :- since 4.3BSD and earlier shells don't like it.
doit=${DOITPROG-}
-if test -z "$doit"; then
- doit_exec=exec
-else
- doit_exec=$doit
-fi
+doit_exec=${doit:-exec}
# Put in absolute file names if you don't have them in your path;
# or use environment vars.
chgrpprog=${CHGRPPROG-chgrp}
chmodprog=${CHMODPROG-chmod}
chownprog=${CHOWNPROG-chown}
cmpprog=${CMPPROG-cmp}
cpprog=${CPPROG-cp}
mkdirprog=${MKDIRPROG-mkdir}
mvprog=${MVPROG-mv}
rmprog=${RMPROG-rm}
stripprog=${STRIPPROG-strip}
-posix_glob='?'
-initialize_posix_glob='
- test "$posix_glob" != "?" || {
- if (set -f) 2>/dev/null; then
- posix_glob=
- else
- posix_glob=:
- fi
- }
-'
-
posix_mkdir=
# Desired mode of installed file.
mode=0755
+# Create dirs (including intermediate dirs) using mode 755.
+# This is like GNU 'install' as of coreutils 8.32 (2020).
+mkdir_umask=22
+
+backupsuffix=
chgrpcmd=
chmodcmd=$chmodprog
chowncmd=
mvcmd=$mvprog
rmcmd="$rmprog -f"
stripcmd=
src=
dst=
dir_arg=
dst_arg=
copy_on_change=false
-no_target_directory=
+is_target_a_directory=possibly
usage="\
Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
or: $0 [OPTION]... SRCFILES... DIRECTORY
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
or: $0 [OPTION]... -d DIRECTORIES...
In the 1st form, copy SRCFILE to DSTFILE.
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
In the 4th, create DIRECTORIES.
Options:
--help display this help and exit.
--version display version info and exit.
-c (ignored)
- -C install only if different (preserve the last data modification time)
+ -C install only if different (preserve data modification time)
-d create directories instead of installing files.
-g GROUP $chgrpprog installed files to GROUP.
-m MODE $chmodprog installed files to MODE.
-o USER $chownprog installed files to USER.
+ -p pass -p to $cpprog.
-s $stripprog installed files.
+ -S SUFFIX attempt to back up existing files, with suffix SUFFIX.
-t DIRECTORY install into DIRECTORY.
-T report an error if DSTFILE is a directory.
Environment variables override the default commands:
CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
RMPROG STRIPPROG
+
+By default, rm is invoked with -f; when overridden with RMPROG,
+it's up to you to specify -f if you want it.
+
+If -S is not specified, no backups are attempted.
+
+Email bug reports to bug-automake@gnu.org.
+Automake home page: https://www.gnu.org/software/automake/
"
while test $# -ne 0; do
case $1 in
-c) ;;
-C) copy_on_change=true;;
-d) dir_arg=true;;
-g) chgrpcmd="$chgrpprog $2"
- shift;;
+ shift;;
--help) echo "$usage"; exit $?;;
-m) mode=$2
- case $mode in
- *' '* | *' '* | *'
-'* | *'*'* | *'?'* | *'['*)
- echo "$0: invalid mode: $mode" >&2
- exit 1;;
- esac
- shift;;
+ case $mode in
+ *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
+ echo "$0: invalid mode: $mode" >&2
+ exit 1;;
+ esac
+ shift;;
-o) chowncmd="$chownprog $2"
- shift;;
+ shift;;
+
+ -p) cpprog="$cpprog -p";;
-s) stripcmd=$stripprog;;
- -t) dst_arg=$2
- # Protect names problematic for 'test' and other utilities.
- case $dst_arg in
- -* | [=\(\)!]) dst_arg=./$dst_arg;;
- esac
- shift;;
+ -S) backupsuffix="$2"
+ shift;;
- -T) no_target_directory=true;;
+ -t)
+ is_target_a_directory=always
+ dst_arg=$2
+ # Protect names problematic for 'test' and other utilities.
+ case $dst_arg in
+ -* | [=\(\)!]) dst_arg=./$dst_arg;;
+ esac
+ shift;;
+
+ -T) is_target_a_directory=never;;
--version) echo "$0 $scriptversion"; exit $?;;
- --) shift
- break;;
+ --) shift
+ break;;
- -*) echo "$0: invalid option: $1" >&2
- exit 1;;
+ -*) echo "$0: invalid option: $1" >&2
+ exit 1;;
*) break;;
esac
shift
done
+# We allow the use of options -d and -T together, by making -d
+# take the precedence; this is for compatibility with GNU install.
+
+if test -n "$dir_arg"; then
+ if test -n "$dst_arg"; then
+ echo "$0: target directory not allowed when installing a directory." >&2
+ exit 1
+ fi
+fi
+
if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
# When -d is used, all remaining arguments are directories to create.
# When -t is used, the destination is already specified.
# Otherwise, the last argument is the destination. Remove it from $@.
for arg
do
if test -n "$dst_arg"; then
# $@ is not empty: it contains at least $arg.
set fnord "$@" "$dst_arg"
shift # fnord
fi
shift # arg
dst_arg=$arg
# Protect names problematic for 'test' and other utilities.
case $dst_arg in
-* | [=\(\)!]) dst_arg=./$dst_arg;;
esac
done
fi
if test $# -eq 0; then
if test -z "$dir_arg"; then
echo "$0: no input file specified." >&2
exit 1
fi
# It's OK to call 'install-sh -d' without argument.
# This can happen when creating conditional directories.
exit 0
fi
+if test -z "$dir_arg"; then
+ if test $# -gt 1 || test "$is_target_a_directory" = always; then
+ if test ! -d "$dst_arg"; then
+ echo "$0: $dst_arg: Is not a directory." >&2
+ exit 1
+ fi
+ fi
+fi
+
if test -z "$dir_arg"; then
do_exit='(exit $ret); exit $ret'
trap "ret=129; $do_exit" 1
trap "ret=130; $do_exit" 2
trap "ret=141; $do_exit" 13
trap "ret=143; $do_exit" 15
# Set umask so as not to create temps with too-generous modes.
# However, 'strip' requires both read and write access to temps.
case $mode in
# Optimize common cases.
*644) cp_umask=133;;
*755) cp_umask=22;;
*[0-7])
if test -z "$stripcmd"; then
- u_plus_rw=
+ u_plus_rw=
else
- u_plus_rw='% 200'
+ u_plus_rw='% 200'
fi
cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
*)
if test -z "$stripcmd"; then
- u_plus_rw=
+ u_plus_rw=
else
- u_plus_rw=,u+rw
+ u_plus_rw=,u+rw
fi
cp_umask=$mode$u_plus_rw;;
esac
fi
for src
do
# Protect names problematic for 'test' and other utilities.
case $src in
-* | [=\(\)!]) src=./$src;;
esac
if test -n "$dir_arg"; then
dst=$src
dstdir=$dst
test -d "$dstdir"
dstdir_status=$?
+ # Don't chown directories that already exist.
+ if test $dstdir_status = 0; then
+ chowncmd=""
+ fi
else
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if test ! -f "$src" && test ! -d "$src"; then
echo "$0: $src does not exist." >&2
exit 1
fi
if test -z "$dst_arg"; then
echo "$0: no destination specified." >&2
exit 1
fi
dst=$dst_arg
- # If destination is a directory, append the input filename; won't work
- # if double slashes aren't ignored.
+ # If destination is a directory, append the input filename.
if test -d "$dst"; then
- if test -n "$no_target_directory"; then
- echo "$0: $dst_arg: Is a directory" >&2
- exit 1
+ if test "$is_target_a_directory" = never; then
+ echo "$0: $dst_arg: Is a directory" >&2
+ exit 1
fi
dstdir=$dst
- dst=$dstdir/`basename "$src"`
+ dstbase=`basename "$src"`
+ case $dst in
+ */) dst=$dst$dstbase;;
+ *) dst=$dst/$dstbase;;
+ esac
dstdir_status=0
else
- # Prefer dirname, but fall back on a substitute if dirname fails.
- dstdir=`
- (dirname "$dst") 2>/dev/null ||
- expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$dst" : 'X\(//\)[^/]' \| \
- X"$dst" : 'X\(//\)$' \| \
- X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
- echo X"$dst" |
- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
- s//\1/
- q
- }
- /^X\(\/\/\)[^/].*/{
- s//\1/
- q
- }
- /^X\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'
- `
-
+ dstdir=`dirname "$dst"`
test -d "$dstdir"
dstdir_status=$?
fi
fi
+ case $dstdir in
+ */) dstdirslash=$dstdir;;
+ *) dstdirslash=$dstdir/;;
+ esac
+
obsolete_mkdir_used=false
if test $dstdir_status != 0; then
case $posix_mkdir in
'')
- # Create intermediate dirs using mode 755 as modified by the umask.
- # This is like FreeBSD 'install' as of 1997-10-28.
- umask=`umask`
- case $stripcmd.$umask in
- # Optimize common cases.
- *[2367][2367]) mkdir_umask=$umask;;
- .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
-
- *[0-7])
- mkdir_umask=`expr $umask + 22 \
- - $umask % 100 % 40 + $umask % 20 \
- - $umask % 10 % 4 + $umask % 2
- `;;
- *) mkdir_umask=$umask,go-w;;
- esac
-
- # With -d, create the new directory with the user-specified mode.
- # Otherwise, rely on $mkdir_umask.
- if test -n "$dir_arg"; then
- mkdir_mode=-m$mode
+ # With -d, create the new directory with the user-specified mode.
+ # Otherwise, rely on $mkdir_umask.
+ if test -n "$dir_arg"; then
+ mkdir_mode=-m$mode
+ else
+ mkdir_mode=
+ fi
+
+ posix_mkdir=false
+ # The $RANDOM variable is not portable (e.g., dash). Use it
+ # here however when possible just to lower collision chance.
+ tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
+
+ trap '
+ ret=$?
+ rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null
+ exit $ret
+ ' 0
+
+ # Because "mkdir -p" follows existing symlinks and we likely work
+ # directly in world-writeable /tmp, make sure that the '$tmpdir'
+ # directory is successfully created first before we actually test
+ # 'mkdir -p'.
+ if (umask $mkdir_umask &&
+ $mkdirprog $mkdir_mode "$tmpdir" &&
+ exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
+ then
+ if test -z "$dir_arg" || {
+ # Check for POSIX incompatibilities with -m.
+ # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
+ # other-writable bit of parent directory when it shouldn't.
+ # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
+ test_tmpdir="$tmpdir/a"
+ ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
+ case $ls_ld_tmpdir in
+ d????-?r-*) different_mode=700;;
+ d????-?--*) different_mode=755;;
+ *) false;;
+ esac &&
+ $mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
+ ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
+ test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
+ }
+ }
+ then posix_mkdir=:
+ fi
+ rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
else
- mkdir_mode=
+ # Remove any dirs left behind by ancient mkdir implementations.
+ rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
fi
-
- posix_mkdir=false
- case $umask in
- *[123567][0-7][0-7])
- # POSIX mkdir -p sets u+wx bits regardless of umask, which
- # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
- ;;
- *)
- tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
- trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
-
- if (umask $mkdir_umask &&
- exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
- then
- if test -z "$dir_arg" || {
- # Check for POSIX incompatibilities with -m.
- # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
- # other-writable bit of parent directory when it shouldn't.
- # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
- ls_ld_tmpdir=`ls -ld "$tmpdir"`
- case $ls_ld_tmpdir in
- d????-?r-*) different_mode=700;;
- d????-?--*) different_mode=755;;
- *) false;;
- esac &&
- $mkdirprog -m$different_mode -p -- "$tmpdir" && {
- ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
- test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
- }
- }
- then posix_mkdir=:
- fi
- rmdir "$tmpdir/d" "$tmpdir"
- else
- # Remove any dirs left behind by ancient mkdir implementations.
- rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
- fi
- trap '' 0;;
- esac;;
+ trap '' 0;;
esac
if
$posix_mkdir && (
- umask $mkdir_umask &&
- $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
+ umask $mkdir_umask &&
+ $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
)
then :
else
- # The umask is ridiculous, or mkdir does not conform to POSIX,
+ # mkdir does not conform to POSIX,
# or it failed possibly due to a race condition. Create the
# directory the slow way, step by step, checking for races as we go.
case $dstdir in
- /*) prefix='/';;
- [-=\(\)!]*) prefix='./';;
- *) prefix='';;
+ /*) prefix='/';;
+ [-=\(\)!]*) prefix='./';;
+ *) prefix='';;
esac
- eval "$initialize_posix_glob"
-
oIFS=$IFS
IFS=/
- $posix_glob set -f
+ set -f
set fnord $dstdir
shift
- $posix_glob set +f
+ set +f
IFS=$oIFS
prefixes=
for d
do
- test X"$d" = X && continue
-
- prefix=$prefix$d
- if test -d "$prefix"; then
- prefixes=
- else
- if $posix_mkdir; then
- (umask=$mkdir_umask &&
- $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
- # Don't fail if two instances are running concurrently.
- test -d "$prefix" || exit 1
- else
- case $prefix in
- *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
- *) qprefix=$prefix;;
- esac
- prefixes="$prefixes '$qprefix'"
- fi
- fi
- prefix=$prefix/
+ test X"$d" = X && continue
+
+ prefix=$prefix$d
+ if test -d "$prefix"; then
+ prefixes=
+ else
+ if $posix_mkdir; then
+ (umask $mkdir_umask &&
+ $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
+ # Don't fail if two instances are running concurrently.
+ test -d "$prefix" || exit 1
+ else
+ case $prefix in
+ *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
+ *) qprefix=$prefix;;
+ esac
+ prefixes="$prefixes '$qprefix'"
+ fi
+ fi
+ prefix=$prefix/
done
if test -n "$prefixes"; then
- # Don't fail if two instances are running concurrently.
- (umask $mkdir_umask &&
- eval "\$doit_exec \$mkdirprog $prefixes") ||
- test -d "$dstdir" || exit 1
- obsolete_mkdir_used=true
+ # Don't fail if two instances are running concurrently.
+ (umask $mkdir_umask &&
+ eval "\$doit_exec \$mkdirprog $prefixes") ||
+ test -d "$dstdir" || exit 1
+ obsolete_mkdir_used=true
fi
fi
fi
if test -n "$dir_arg"; then
{ test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
{ test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
else
# Make a couple of temp file names in the proper directory.
- dsttmp=$dstdir/_inst.$$_
- rmtmp=$dstdir/_rm.$$_
+ dsttmp=${dstdirslash}_inst.$$_
+ rmtmp=${dstdirslash}_rm.$$_
# Trap to clean up those temp files at exit.
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
# Copy the file name to the temp name.
- (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
+ (umask $cp_umask &&
+ { test -z "$stripcmd" || {
+ # Create $dsttmp read-write so that cp doesn't create it read-only,
+ # which would cause strip to fail.
+ if test -z "$doit"; then
+ : >"$dsttmp" # No need to fork-exec 'touch'.
+ else
+ $doit touch "$dsttmp"
+ fi
+ }
+ } &&
+ $doit_exec $cpprog "$src" "$dsttmp") &&
# and set any options; do chmod last to preserve setuid bits.
#
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $cpprog $src $dsttmp" command.
#
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
{ test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
{ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
# If -C, don't bother to copy if it wouldn't change the file.
if $copy_on_change &&
- old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
- new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
-
- eval "$initialize_posix_glob" &&
- $posix_glob set -f &&
+ old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
+ new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
+ set -f &&
set X $old && old=:$2:$4:$5:$6 &&
set X $new && new=:$2:$4:$5:$6 &&
- $posix_glob set +f &&
-
+ set +f &&
test "$old" = "$new" &&
$cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
then
rm -f "$dsttmp"
else
+ # If $backupsuffix is set, and the file being installed
+ # already exists, attempt a backup. Don't worry if it fails,
+ # e.g., if mv doesn't support -f.
+ if test -n "$backupsuffix" && test -f "$dst"; then
+ $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null
+ fi
+
# Rename the file to the real destination.
$doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
# The rename failed, perhaps because mv can't rename something else
# to itself, or perhaps because mv is so ancient that it does not
# support -f.
{
- # Now remove or move aside any old file at destination location.
- # We try this two ways since rm can't unlink itself on some
- # systems and the destination file might be busy for other
- # reasons. In this case, the final cleanup might fail but the new
- # file should still install successfully.
- {
- test ! -f "$dst" ||
- $doit $rmcmd -f "$dst" 2>/dev/null ||
- { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
- { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
- } ||
- { echo "$0: cannot unlink or rename $dst" >&2
- (exit 1); exit 1
- }
- } &&
-
- # Now rename the file to the real destination.
- $doit $mvcmd "$dsttmp" "$dst"
+ # Now remove or move aside any old file at destination location.
+ # We try this two ways since rm can't unlink itself on some
+ # systems and the destination file might be busy for other
+ # reasons. In this case, the final cleanup might fail but the new
+ # file should still install successfully.
+ {
+ test ! -f "$dst" ||
+ $doit $rmcmd "$dst" 2>/dev/null ||
+ { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
+ { $doit $rmcmd "$rmtmp" 2>/dev/null; :; }
+ } ||
+ { echo "$0: cannot unlink or rename $dst" >&2
+ (exit 1); exit 1
+ }
+ } &&
+
+ # Now rename the file to the real destination.
+ $doit $mvcmd "$dsttmp" "$dst"
}
fi || exit 1
trap '' 0
fi
done
# Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
+# eval: (add-hook 'before-save-hook 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-time-zone: "UTC"
+# time-stamp-time-zone: "UTC0"
# time-stamp-end: "; # UTC"
# End:
diff --git a/crypto/openssh/kex.c b/crypto/openssh/kex.c
index 0bcd27dc5825..8cdefcf7cbb9 100644
--- a/crypto/openssh/kex.c
+++ b/crypto/openssh/kex.c
@@ -1,1421 +1,1421 @@
-/* $OpenBSD: kex.c,v 1.172 2022/02/01 23:32:51 djm Exp $ */
+/* $OpenBSD: kex.c,v 1.173 2022/11/07 10:05:38 dtucker Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "includes.h"
#include <sys/types.h>
#include <errno.h>
#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#ifdef HAVE_POLL_H
#include <poll.h>
#endif
#ifdef WITH_OPENSSL
#include <openssl/crypto.h>
#include <openssl/dh.h>
#endif
#include "ssh.h"
#include "ssh2.h"
#include "atomicio.h"
#include "version.h"
#include "packet.h"
#include "compat.h"
#include "cipher.h"
#include "sshkey.h"
#include "kex.h"
#include "log.h"
#include "mac.h"
#include "match.h"
#include "misc.h"
#include "dispatch.h"
#include "monitor.h"
#include "ssherr.h"
#include "sshbuf.h"
#include "digest.h"
/* prototype */
static int kex_choose_conf(struct ssh *);
static int kex_input_newkeys(int, u_int32_t, struct ssh *);
static const char * const proposal_names[PROPOSAL_MAX] = {
"KEX algorithms",
"host key algorithms",
"ciphers ctos",
"ciphers stoc",
"MACs ctos",
"MACs stoc",
"compression ctos",
"compression stoc",
"languages ctos",
"languages stoc",
};
struct kexalg {
char *name;
u_int type;
int ec_nid;
int hash_alg;
};
static const struct kexalg kexalgs[] = {
#ifdef WITH_OPENSSL
{ KEX_DH1, KEX_DH_GRP1_SHA1, 0, SSH_DIGEST_SHA1 },
{ KEX_DH14_SHA1, KEX_DH_GRP14_SHA1, 0, SSH_DIGEST_SHA1 },
{ KEX_DH14_SHA256, KEX_DH_GRP14_SHA256, 0, SSH_DIGEST_SHA256 },
{ KEX_DH16_SHA512, KEX_DH_GRP16_SHA512, 0, SSH_DIGEST_SHA512 },
{ KEX_DH18_SHA512, KEX_DH_GRP18_SHA512, 0, SSH_DIGEST_SHA512 },
{ KEX_DHGEX_SHA1, KEX_DH_GEX_SHA1, 0, SSH_DIGEST_SHA1 },
#ifdef HAVE_EVP_SHA256
{ KEX_DHGEX_SHA256, KEX_DH_GEX_SHA256, 0, SSH_DIGEST_SHA256 },
#endif /* HAVE_EVP_SHA256 */
#ifdef OPENSSL_HAS_ECC
{ KEX_ECDH_SHA2_NISTP256, KEX_ECDH_SHA2,
NID_X9_62_prime256v1, SSH_DIGEST_SHA256 },
{ KEX_ECDH_SHA2_NISTP384, KEX_ECDH_SHA2, NID_secp384r1,
SSH_DIGEST_SHA384 },
# ifdef OPENSSL_HAS_NISTP521
{ KEX_ECDH_SHA2_NISTP521, KEX_ECDH_SHA2, NID_secp521r1,
SSH_DIGEST_SHA512 },
# endif /* OPENSSL_HAS_NISTP521 */
#endif /* OPENSSL_HAS_ECC */
#endif /* WITH_OPENSSL */
#if defined(HAVE_EVP_SHA256) || !defined(WITH_OPENSSL)
{ KEX_CURVE25519_SHA256, KEX_C25519_SHA256, 0, SSH_DIGEST_SHA256 },
{ KEX_CURVE25519_SHA256_OLD, KEX_C25519_SHA256, 0, SSH_DIGEST_SHA256 },
#ifdef USE_SNTRUP761X25519
{ KEX_SNTRUP761X25519_SHA512, KEX_KEM_SNTRUP761X25519_SHA512, 0,
SSH_DIGEST_SHA512 },
#endif
#endif /* HAVE_EVP_SHA256 || !WITH_OPENSSL */
{ NULL, 0, -1, -1},
};
char *
kex_alg_list(char sep)
{
char *ret = NULL, *tmp;
size_t nlen, rlen = 0;
const struct kexalg *k;
for (k = kexalgs; k->name != NULL; k++) {
if (ret != NULL)
ret[rlen++] = sep;
nlen = strlen(k->name);
if ((tmp = realloc(ret, rlen + nlen + 2)) == NULL) {
free(ret);
return NULL;
}
ret = tmp;
memcpy(ret + rlen, k->name, nlen + 1);
rlen += nlen;
}
return ret;
}
static const struct kexalg *
kex_alg_by_name(const char *name)
{
const struct kexalg *k;
for (k = kexalgs; k->name != NULL; k++) {
if (strcmp(k->name, name) == 0)
return k;
}
return NULL;
}
/* Validate KEX method name list */
int
kex_names_valid(const char *names)
{
char *s, *cp, *p;
if (names == NULL || strcmp(names, "") == 0)
return 0;
if ((s = cp = strdup(names)) == NULL)
return 0;
for ((p = strsep(&cp, ",")); p && *p != '\0';
(p = strsep(&cp, ","))) {
if (kex_alg_by_name(p) == NULL) {
error("Unsupported KEX algorithm \"%.100s\"", p);
free(s);
return 0;
}
}
debug3("kex names ok: [%s]", names);
free(s);
return 1;
}
/*
* Concatenate algorithm names, avoiding duplicates in the process.
* Caller must free returned string.
*/
char *
kex_names_cat(const char *a, const char *b)
{
char *ret = NULL, *tmp = NULL, *cp, *p, *m;
size_t len;
if (a == NULL || *a == '\0')
return strdup(b);
if (b == NULL || *b == '\0')
return strdup(a);
if (strlen(b) > 1024*1024)
return NULL;
len = strlen(a) + strlen(b) + 2;
if ((tmp = cp = strdup(b)) == NULL ||
(ret = calloc(1, len)) == NULL) {
free(tmp);
return NULL;
}
strlcpy(ret, a, len);
for ((p = strsep(&cp, ",")); p && *p != '\0'; (p = strsep(&cp, ","))) {
if ((m = match_list(ret, p, NULL)) != NULL) {
free(m);
continue; /* Algorithm already present */
}
if (strlcat(ret, ",", len) >= len ||
strlcat(ret, p, len) >= len) {
free(tmp);
free(ret);
return NULL; /* Shouldn't happen */
}
}
free(tmp);
return ret;
}
/*
* Assemble a list of algorithms from a default list and a string from a
* configuration file. The user-provided string may begin with '+' to
* indicate that it should be appended to the default, '-' that the
* specified names should be removed, or '^' that they should be placed
* at the head.
*/
int
kex_assemble_names(char **listp, const char *def, const char *all)
{
char *cp, *tmp, *patterns;
char *list = NULL, *ret = NULL, *matching = NULL, *opatterns = NULL;
int r = SSH_ERR_INTERNAL_ERROR;
if (listp == NULL || def == NULL || all == NULL)
return SSH_ERR_INVALID_ARGUMENT;
if (*listp == NULL || **listp == '\0') {
if ((*listp = strdup(def)) == NULL)
return SSH_ERR_ALLOC_FAIL;
return 0;
}
list = *listp;
*listp = NULL;
if (*list == '+') {
/* Append names to default list */
if ((tmp = kex_names_cat(def, list + 1)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto fail;
}
free(list);
list = tmp;
} else if (*list == '-') {
/* Remove names from default list */
if ((*listp = match_filter_denylist(def, list + 1)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto fail;
}
free(list);
/* filtering has already been done */
return 0;
} else if (*list == '^') {
/* Place names at head of default list */
if ((tmp = kex_names_cat(list + 1, def)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto fail;
}
free(list);
list = tmp;
} else {
/* Explicit list, overrides default - just use "list" as is */
}
/*
* The supplied names may be a pattern-list. For the -list case,
* the patterns are applied above. For the +list and explicit list
* cases we need to do it now.
*/
ret = NULL;
if ((patterns = opatterns = strdup(list)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto fail;
}
/* Apply positive (i.e. non-negated) patterns from the list */
while ((cp = strsep(&patterns, ",")) != NULL) {
if (*cp == '!') {
/* negated matches are not supported here */
r = SSH_ERR_INVALID_ARGUMENT;
goto fail;
}
free(matching);
if ((matching = match_filter_allowlist(all, cp)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto fail;
}
if ((tmp = kex_names_cat(ret, matching)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto fail;
}
free(ret);
ret = tmp;
}
if (ret == NULL || *ret == '\0') {
/* An empty name-list is an error */
/* XXX better error code? */
r = SSH_ERR_INVALID_ARGUMENT;
goto fail;
}
/* success */
*listp = ret;
ret = NULL;
r = 0;
fail:
free(matching);
free(opatterns);
free(list);
free(ret);
return r;
}
/* put algorithm proposal into buffer */
int
kex_prop2buf(struct sshbuf *b, char *proposal[PROPOSAL_MAX])
{
u_int i;
int r;
sshbuf_reset(b);
/*
* add a dummy cookie, the cookie will be overwritten by
* kex_send_kexinit(), each time a kexinit is set
*/
for (i = 0; i < KEX_COOKIE_LEN; i++) {
if ((r = sshbuf_put_u8(b, 0)) != 0)
return r;
}
for (i = 0; i < PROPOSAL_MAX; i++) {
if ((r = sshbuf_put_cstring(b, proposal[i])) != 0)
return r;
}
if ((r = sshbuf_put_u8(b, 0)) != 0 || /* first_kex_packet_follows */
(r = sshbuf_put_u32(b, 0)) != 0) /* uint32 reserved */
return r;
return 0;
}
/* parse buffer and return algorithm proposal */
int
kex_buf2prop(struct sshbuf *raw, int *first_kex_follows, char ***propp)
{
struct sshbuf *b = NULL;
u_char v;
u_int i;
char **proposal = NULL;
int r;
*propp = NULL;
if ((proposal = calloc(PROPOSAL_MAX, sizeof(char *))) == NULL)
return SSH_ERR_ALLOC_FAIL;
if ((b = sshbuf_fromb(raw)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
if ((r = sshbuf_consume(b, KEX_COOKIE_LEN)) != 0) { /* skip cookie */
error_fr(r, "consume cookie");
goto out;
}
/* extract kex init proposal strings */
for (i = 0; i < PROPOSAL_MAX; i++) {
if ((r = sshbuf_get_cstring(b, &(proposal[i]), NULL)) != 0) {
error_fr(r, "parse proposal %u", i);
goto out;
}
debug2("%s: %s", proposal_names[i], proposal[i]);
}
/* first kex follows / reserved */
if ((r = sshbuf_get_u8(b, &v)) != 0 || /* first_kex_follows */
(r = sshbuf_get_u32(b, &i)) != 0) { /* reserved */
error_fr(r, "parse");
goto out;
}
if (first_kex_follows != NULL)
*first_kex_follows = v;
debug2("first_kex_follows %d ", v);
debug2("reserved %u ", i);
r = 0;
*propp = proposal;
out:
if (r != 0 && proposal != NULL)
kex_prop_free(proposal);
sshbuf_free(b);
return r;
}
void
kex_prop_free(char **proposal)
{
u_int i;
if (proposal == NULL)
return;
for (i = 0; i < PROPOSAL_MAX; i++)
free(proposal[i]);
free(proposal);
}
/* ARGSUSED */
int
kex_protocol_error(int type, u_int32_t seq, struct ssh *ssh)
{
int r;
error("kex protocol error: type %d seq %u", type, seq);
if ((r = sshpkt_start(ssh, SSH2_MSG_UNIMPLEMENTED)) != 0 ||
(r = sshpkt_put_u32(ssh, seq)) != 0 ||
(r = sshpkt_send(ssh)) != 0)
return r;
return 0;
}
static void
kex_reset_dispatch(struct ssh *ssh)
{
ssh_dispatch_range(ssh, SSH2_MSG_TRANSPORT_MIN,
SSH2_MSG_TRANSPORT_MAX, &kex_protocol_error);
}
static int
kex_send_ext_info(struct ssh *ssh)
{
int r;
char *algs;
debug("Sending SSH2_MSG_EXT_INFO");
if ((algs = sshkey_alg_list(0, 1, 1, ',')) == NULL)
return SSH_ERR_ALLOC_FAIL;
/* XXX filter algs list by allowed pubkey/hostbased types */
if ((r = sshpkt_start(ssh, SSH2_MSG_EXT_INFO)) != 0 ||
(r = sshpkt_put_u32(ssh, 2)) != 0 ||
(r = sshpkt_put_cstring(ssh, "server-sig-algs")) != 0 ||
(r = sshpkt_put_cstring(ssh, algs)) != 0 ||
(r = sshpkt_put_cstring(ssh,
"publickey-hostbound@openssh.com")) != 0 ||
(r = sshpkt_put_cstring(ssh, "0")) != 0 ||
(r = sshpkt_send(ssh)) != 0) {
error_fr(r, "compose");
goto out;
}
/* success */
r = 0;
out:
free(algs);
return r;
}
int
kex_send_newkeys(struct ssh *ssh)
{
int r;
kex_reset_dispatch(ssh);
if ((r = sshpkt_start(ssh, SSH2_MSG_NEWKEYS)) != 0 ||
(r = sshpkt_send(ssh)) != 0)
return r;
debug("SSH2_MSG_NEWKEYS sent");
ssh_dispatch_set(ssh, SSH2_MSG_NEWKEYS, &kex_input_newkeys);
if (ssh->kex->ext_info_c && (ssh->kex->flags & KEX_INITIAL) != 0)
if ((r = kex_send_ext_info(ssh)) != 0)
return r;
debug("expecting SSH2_MSG_NEWKEYS");
return 0;
}
int
kex_input_ext_info(int type, u_int32_t seq, struct ssh *ssh)
{
struct kex *kex = ssh->kex;
u_int32_t i, ninfo;
char *name;
u_char *val;
size_t vlen;
int r;
debug("SSH2_MSG_EXT_INFO received");
ssh_dispatch_set(ssh, SSH2_MSG_EXT_INFO, &kex_protocol_error);
if ((r = sshpkt_get_u32(ssh, &ninfo)) != 0)
return r;
for (i = 0; i < ninfo; i++) {
if ((r = sshpkt_get_cstring(ssh, &name, NULL)) != 0)
return r;
if ((r = sshpkt_get_string(ssh, &val, &vlen)) != 0) {
free(name);
return r;
}
if (strcmp(name, "server-sig-algs") == 0) {
/* Ensure no \0 lurking in value */
if (memchr(val, '\0', vlen) != NULL) {
error_f("nul byte in %s", name);
return SSH_ERR_INVALID_FORMAT;
}
debug_f("%s=<%s>", name, val);
kex->server_sig_algs = val;
val = NULL;
} else if (strcmp(name,
"publickey-hostbound@openssh.com") == 0) {
/* XXX refactor */
/* Ensure no \0 lurking in value */
if (memchr(val, '\0', vlen) != NULL) {
error_f("nul byte in %s", name);
return SSH_ERR_INVALID_FORMAT;
}
debug_f("%s=<%s>", name, val);
if (strcmp(val, "0") == 0)
kex->flags |= KEX_HAS_PUBKEY_HOSTBOUND;
else {
debug_f("unsupported version of %s extension",
name);
}
} else
debug_f("%s (unrecognised)", name);
free(name);
free(val);
}
return sshpkt_get_end(ssh);
}
static int
kex_input_newkeys(int type, u_int32_t seq, struct ssh *ssh)
{
struct kex *kex = ssh->kex;
int r;
debug("SSH2_MSG_NEWKEYS received");
ssh_dispatch_set(ssh, SSH2_MSG_NEWKEYS, &kex_protocol_error);
ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, &kex_input_kexinit);
if ((r = sshpkt_get_end(ssh)) != 0)
return r;
if ((r = ssh_set_newkeys(ssh, MODE_IN)) != 0)
return r;
kex->done = 1;
kex->flags &= ~KEX_INITIAL;
sshbuf_reset(kex->peer);
/* sshbuf_reset(kex->my); */
kex->flags &= ~KEX_INIT_SENT;
free(kex->name);
kex->name = NULL;
return 0;
}
int
kex_send_kexinit(struct ssh *ssh)
{
u_char *cookie;
struct kex *kex = ssh->kex;
int r;
if (kex == NULL) {
error_f("no kex");
return SSH_ERR_INTERNAL_ERROR;
}
if (kex->flags & KEX_INIT_SENT)
return 0;
kex->done = 0;
/* generate a random cookie */
if (sshbuf_len(kex->my) < KEX_COOKIE_LEN) {
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_f("buffer error");
return SSH_ERR_INTERNAL_ERROR;
}
arc4random_buf(cookie, KEX_COOKIE_LEN);
if ((r = sshpkt_start(ssh, SSH2_MSG_KEXINIT)) != 0 ||
(r = sshpkt_putb(ssh, kex->my)) != 0 ||
(r = sshpkt_send(ssh)) != 0) {
error_fr(r, "compose reply");
return r;
}
debug("SSH2_MSG_KEXINIT sent");
kex->flags |= KEX_INIT_SENT;
return 0;
}
/* ARGSUSED */
int
kex_input_kexinit(int type, u_int32_t seq, struct ssh *ssh)
{
struct kex *kex = ssh->kex;
const u_char *ptr;
u_int i;
size_t dlen;
int r;
debug("SSH2_MSG_KEXINIT received");
if (kex == NULL) {
error_f("no kex");
return SSH_ERR_INTERNAL_ERROR;
}
ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, NULL);
ptr = sshpkt_ptr(ssh, &dlen);
if ((r = sshbuf_put(kex->peer, ptr, dlen)) != 0)
return r;
/* discard packet */
for (i = 0; i < KEX_COOKIE_LEN; i++) {
if ((r = sshpkt_get_u8(ssh, NULL)) != 0) {
error_fr(r, "discard cookie");
return r;
}
}
for (i = 0; i < PROPOSAL_MAX; i++) {
if ((r = sshpkt_get_string(ssh, NULL, NULL)) != 0) {
error_fr(r, "discard proposal");
return r;
}
}
/*
* XXX RFC4253 sec 7: "each side MAY guess" - currently no supported
* KEX method has the server move first, but a server might be using
* a custom method or one that we otherwise don't support. We should
* be prepared to remember first_kex_follows here so we can eat a
* packet later.
* XXX2 - RFC4253 is kind of ambiguous on what first_kex_follows means
* for cases where the server *doesn't* go first. I guess we should
* ignore it when it is set for these cases, which is what we do now.
*/
if ((r = sshpkt_get_u8(ssh, NULL)) != 0 || /* first_kex_follows */
(r = sshpkt_get_u32(ssh, NULL)) != 0 || /* reserved */
(r = sshpkt_get_end(ssh)) != 0)
return r;
if (!(kex->flags & KEX_INIT_SENT))
if ((r = kex_send_kexinit(ssh)) != 0)
return r;
if ((r = kex_choose_conf(ssh)) != 0)
return r;
if (kex->kex_type < KEX_MAX && kex->kex[kex->kex_type] != NULL)
return (kex->kex[kex->kex_type])(ssh);
error_f("unknown kex type %u", kex->kex_type);
return SSH_ERR_INTERNAL_ERROR;
}
struct kex *
kex_new(void)
{
struct kex *kex;
if ((kex = calloc(1, sizeof(*kex))) == NULL ||
(kex->peer = sshbuf_new()) == NULL ||
(kex->my = sshbuf_new()) == NULL ||
(kex->client_version = sshbuf_new()) == NULL ||
(kex->server_version = sshbuf_new()) == NULL ||
(kex->session_id = sshbuf_new()) == NULL) {
kex_free(kex);
return NULL;
}
return kex;
}
void
kex_free_newkeys(struct newkeys *newkeys)
{
if (newkeys == NULL)
return;
if (newkeys->enc.key) {
explicit_bzero(newkeys->enc.key, newkeys->enc.key_len);
free(newkeys->enc.key);
newkeys->enc.key = NULL;
}
if (newkeys->enc.iv) {
explicit_bzero(newkeys->enc.iv, newkeys->enc.iv_len);
free(newkeys->enc.iv);
newkeys->enc.iv = NULL;
}
free(newkeys->enc.name);
explicit_bzero(&newkeys->enc, sizeof(newkeys->enc));
free(newkeys->comp.name);
explicit_bzero(&newkeys->comp, sizeof(newkeys->comp));
mac_clear(&newkeys->mac);
if (newkeys->mac.key) {
explicit_bzero(newkeys->mac.key, newkeys->mac.key_len);
free(newkeys->mac.key);
newkeys->mac.key = NULL;
}
free(newkeys->mac.name);
explicit_bzero(&newkeys->mac, sizeof(newkeys->mac));
freezero(newkeys, sizeof(*newkeys));
}
void
kex_free(struct kex *kex)
{
u_int mode;
if (kex == NULL)
return;
#ifdef WITH_OPENSSL
DH_free(kex->dh);
#ifdef OPENSSL_HAS_ECC
EC_KEY_free(kex->ec_client_key);
#endif /* OPENSSL_HAS_ECC */
#endif /* WITH_OPENSSL */
for (mode = 0; mode < MODE_MAX; mode++) {
kex_free_newkeys(kex->newkeys[mode]);
kex->newkeys[mode] = NULL;
}
sshbuf_free(kex->peer);
sshbuf_free(kex->my);
sshbuf_free(kex->client_version);
sshbuf_free(kex->server_version);
sshbuf_free(kex->client_pub);
sshbuf_free(kex->session_id);
sshbuf_free(kex->initial_sig);
sshkey_free(kex->initial_hostkey);
free(kex->failed_choice);
free(kex->hostkey_alg);
free(kex->name);
free(kex);
}
int
kex_ready(struct ssh *ssh, char *proposal[PROPOSAL_MAX])
{
int r;
if ((r = kex_prop2buf(ssh->kex->my, proposal)) != 0)
return r;
ssh->kex->flags = KEX_INITIAL;
kex_reset_dispatch(ssh);
ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, &kex_input_kexinit);
return 0;
}
int
kex_setup(struct ssh *ssh, char *proposal[PROPOSAL_MAX])
{
int r;
if ((r = kex_ready(ssh, proposal)) != 0)
return r;
if ((r = kex_send_kexinit(ssh)) != 0) { /* we start */
kex_free(ssh->kex);
ssh->kex = NULL;
return r;
}
return 0;
}
/*
* Request key re-exchange, returns 0 on success or a ssherr.h error
* code otherwise. Must not be called if KEX is incomplete or in-progress.
*/
int
kex_start_rekex(struct ssh *ssh)
{
if (ssh->kex == NULL) {
error_f("no kex");
return SSH_ERR_INTERNAL_ERROR;
}
if (ssh->kex->done == 0) {
error_f("requested twice");
return SSH_ERR_INTERNAL_ERROR;
}
ssh->kex->done = 0;
return kex_send_kexinit(ssh);
}
static int
choose_enc(struct sshenc *enc, char *client, char *server)
{
char *name = match_list(client, server, NULL);
if (name == NULL)
return SSH_ERR_NO_CIPHER_ALG_MATCH;
if ((enc->cipher = cipher_by_name(name)) == NULL) {
error_f("unsupported cipher %s", name);
free(name);
return SSH_ERR_INTERNAL_ERROR;
}
enc->name = name;
enc->enabled = 0;
enc->iv = NULL;
enc->iv_len = cipher_ivlen(enc->cipher);
enc->key = NULL;
enc->key_len = cipher_keylen(enc->cipher);
enc->block_size = cipher_blocksize(enc->cipher);
return 0;
}
static int
choose_mac(struct ssh *ssh, struct sshmac *mac, char *client, char *server)
{
char *name = match_list(client, server, NULL);
if (name == NULL)
return SSH_ERR_NO_MAC_ALG_MATCH;
if (mac_setup(mac, name) < 0) {
error_f("unsupported MAC %s", name);
free(name);
return SSH_ERR_INTERNAL_ERROR;
}
mac->name = name;
mac->key = NULL;
mac->enabled = 0;
return 0;
}
static int
choose_comp(struct sshcomp *comp, char *client, char *server)
{
char *name = match_list(client, server, NULL);
if (name == NULL)
return SSH_ERR_NO_COMPRESS_ALG_MATCH;
#ifdef WITH_ZLIB
if (strcmp(name, "zlib@openssh.com") == 0) {
comp->type = COMP_DELAYED;
} else if (strcmp(name, "zlib") == 0) {
comp->type = COMP_ZLIB;
} else
#endif /* WITH_ZLIB */
if (strcmp(name, "none") == 0) {
comp->type = COMP_NONE;
} else {
error_f("unsupported compression scheme %s", name);
free(name);
return SSH_ERR_INTERNAL_ERROR;
}
comp->name = name;
return 0;
}
static int
choose_kex(struct kex *k, char *client, char *server)
{
const struct kexalg *kexalg;
k->name = match_list(client, server, NULL);
debug("kex: algorithm: %s", k->name ? k->name : "(no match)");
if (k->name == NULL)
return SSH_ERR_NO_KEX_ALG_MATCH;
if ((kexalg = kex_alg_by_name(k->name)) == NULL) {
error_f("unsupported KEX method %s", k->name);
return SSH_ERR_INTERNAL_ERROR;
}
k->kex_type = kexalg->type;
k->hash_alg = kexalg->hash_alg;
k->ec_nid = kexalg->ec_nid;
return 0;
}
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",
k->hostkey_alg ? k->hostkey_alg : "(no match)");
if (k->hostkey_alg == NULL)
return SSH_ERR_NO_HOSTKEY_ALG_MATCH;
k->hostkey_type = sshkey_type_from_name(k->hostkey_alg);
if (k->hostkey_type == KEY_UNSPEC) {
error_f("unsupported hostkey algorithm %s", k->hostkey_alg);
return SSH_ERR_INTERNAL_ERROR;
}
k->hostkey_nid = sshkey_ecdsa_nid_from_name(k->hostkey_alg);
return 0;
}
static int
proposals_match(char *my[PROPOSAL_MAX], char *peer[PROPOSAL_MAX])
{
static int check[] = {
PROPOSAL_KEX_ALGS, PROPOSAL_SERVER_HOST_KEY_ALGS, -1
};
int *idx;
char *p;
for (idx = &check[0]; *idx != -1; idx++) {
if ((p = strchr(my[*idx], ',')) != NULL)
*p = '\0';
if ((p = strchr(peer[*idx], ',')) != NULL)
*p = '\0';
if (strcmp(my[*idx], peer[*idx]) != 0) {
debug2("proposal mismatch: my %s peer %s",
my[*idx], peer[*idx]);
return (0);
}
}
debug2("proposals match");
return (1);
}
/* returns non-zero if proposal contains any algorithm from algs */
static int
has_any_alg(const char *proposal, const char *algs)
{
char *cp;
if ((cp = match_list(proposal, algs, NULL)) == NULL)
return 0;
free(cp);
return 1;
}
static int
kex_choose_conf(struct ssh *ssh)
{
struct kex *kex = ssh->kex;
struct newkeys *newkeys;
char **my = NULL, **peer = NULL;
char **cprop, **sprop;
int nenc, nmac, ncomp;
u_int mode, ctos, need, dh_need, authlen;
int r, first_kex_follows;
debug2("local %s KEXINIT proposal", kex->server ? "server" : "client");
if ((r = kex_buf2prop(kex->my, NULL, &my)) != 0)
goto out;
debug2("peer %s KEXINIT proposal", kex->server ? "client" : "server");
if ((r = kex_buf2prop(kex->peer, &first_kex_follows, &peer)) != 0)
goto out;
if (kex->server) {
cprop=peer;
sprop=my;
} else {
cprop=my;
sprop=peer;
}
/* Check whether client supports ext_info_c */
if (kex->server && (kex->flags & KEX_INITIAL)) {
char *ext;
ext = match_list("ext-info-c", peer[PROPOSAL_KEX_ALGS], NULL);
kex->ext_info_c = (ext != NULL);
free(ext);
}
/* Check whether client supports rsa-sha2 algorithms */
if (kex->server && (kex->flags & KEX_INITIAL)) {
if (has_any_alg(peer[PROPOSAL_SERVER_HOST_KEY_ALGS],
"rsa-sha2-256,rsa-sha2-256-cert-v01@openssh.com"))
kex->flags |= KEX_RSA_SHA2_256_SUPPORTED;
if (has_any_alg(peer[PROPOSAL_SERVER_HOST_KEY_ALGS],
"rsa-sha2-512,rsa-sha2-512-cert-v01@openssh.com"))
kex->flags |= KEX_RSA_SHA2_512_SUPPORTED;
}
/* Algorithm Negotiation */
if ((r = choose_kex(kex, cprop[PROPOSAL_KEX_ALGS],
sprop[PROPOSAL_KEX_ALGS])) != 0) {
kex->failed_choice = peer[PROPOSAL_KEX_ALGS];
peer[PROPOSAL_KEX_ALGS] = NULL;
goto out;
}
if ((r = choose_hostkeyalg(kex, cprop[PROPOSAL_SERVER_HOST_KEY_ALGS],
sprop[PROPOSAL_SERVER_HOST_KEY_ALGS])) != 0) {
kex->failed_choice = peer[PROPOSAL_SERVER_HOST_KEY_ALGS];
peer[PROPOSAL_SERVER_HOST_KEY_ALGS] = NULL;
goto out;
}
for (mode = 0; mode < MODE_MAX; mode++) {
if ((newkeys = calloc(1, sizeof(*newkeys))) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
kex->newkeys[mode] = newkeys;
ctos = (!kex->server && mode == MODE_OUT) ||
(kex->server && mode == MODE_IN);
nenc = ctos ? PROPOSAL_ENC_ALGS_CTOS : PROPOSAL_ENC_ALGS_STOC;
nmac = ctos ? PROPOSAL_MAC_ALGS_CTOS : PROPOSAL_MAC_ALGS_STOC;
ncomp = ctos ? PROPOSAL_COMP_ALGS_CTOS : PROPOSAL_COMP_ALGS_STOC;
if ((r = choose_enc(&newkeys->enc, cprop[nenc],
sprop[nenc])) != 0) {
kex->failed_choice = peer[nenc];
peer[nenc] = NULL;
goto out;
}
authlen = cipher_authlen(newkeys->enc.cipher);
/* ignore mac for authenticated encryption */
if (authlen == 0 &&
(r = choose_mac(ssh, &newkeys->mac, cprop[nmac],
sprop[nmac])) != 0) {
kex->failed_choice = peer[nmac];
peer[nmac] = NULL;
goto out;
}
if ((r = choose_comp(&newkeys->comp, cprop[ncomp],
sprop[ncomp])) != 0) {
kex->failed_choice = peer[ncomp];
peer[ncomp] = NULL;
goto out;
}
debug("kex: %s cipher: %s MAC: %s compression: %s",
ctos ? "client->server" : "server->client",
newkeys->enc.name,
authlen == 0 ? newkeys->mac.name : "<implicit>",
newkeys->comp.name);
}
need = dh_need = 0;
for (mode = 0; mode < MODE_MAX; mode++) {
newkeys = kex->newkeys[mode];
need = MAXIMUM(need, newkeys->enc.key_len);
need = MAXIMUM(need, newkeys->enc.block_size);
need = MAXIMUM(need, newkeys->enc.iv_len);
need = MAXIMUM(need, newkeys->mac.key_len);
dh_need = MAXIMUM(dh_need, cipher_seclen(newkeys->enc.cipher));
dh_need = MAXIMUM(dh_need, newkeys->enc.block_size);
dh_need = MAXIMUM(dh_need, newkeys->enc.iv_len);
dh_need = MAXIMUM(dh_need, newkeys->mac.key_len);
}
/* XXX need runden? */
kex->we_need = need;
kex->dh_need = dh_need;
/* ignore the next message if the proposals do not match */
if (first_kex_follows && !proposals_match(my, peer))
ssh->dispatch_skip_packets = 1;
r = 0;
out:
kex_prop_free(my);
kex_prop_free(peer);
return r;
}
static int
derive_key(struct ssh *ssh, int id, u_int need, u_char *hash, u_int hashlen,
const struct sshbuf *shared_secret, u_char **keyp)
{
struct kex *kex = ssh->kex;
struct ssh_digest_ctx *hashctx = NULL;
char c = id;
u_int have;
size_t mdsz;
u_char *digest;
int r;
if ((mdsz = ssh_digest_bytes(kex->hash_alg)) == 0)
return SSH_ERR_INVALID_ARGUMENT;
if ((digest = calloc(1, ROUNDUP(need, mdsz))) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
/* K1 = HASH(K || H || "A" || session_id) */
if ((hashctx = ssh_digest_start(kex->hash_alg)) == NULL ||
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_buffer(hashctx, kex->session_id) != 0 ||
ssh_digest_final(hashctx, digest, mdsz) != 0) {
r = SSH_ERR_LIBCRYPTO_ERROR;
error_f("KEX hash failed");
goto out;
}
ssh_digest_free(hashctx);
hashctx = NULL;
/*
* expand key:
* Kn = HASH(K || H || K1 || K2 || ... || Kn-1)
* Key = K1 || K2 || ... || Kn
*/
for (have = mdsz; need > have; have += mdsz) {
if ((hashctx = ssh_digest_start(kex->hash_alg)) == NULL ||
ssh_digest_update_buffer(hashctx, shared_secret) != 0 ||
ssh_digest_update(hashctx, hash, hashlen) != 0 ||
ssh_digest_update(hashctx, digest, have) != 0 ||
ssh_digest_final(hashctx, digest + have, mdsz) != 0) {
error_f("KDF failed");
r = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
ssh_digest_free(hashctx);
hashctx = NULL;
}
#ifdef DEBUG_KEX
fprintf(stderr, "key '%c'== ", c);
dump_digest("key", digest, need);
#endif
*keyp = digest;
digest = NULL;
r = 0;
out:
free(digest);
ssh_digest_free(hashctx);
return r;
}
#define NKEYS 6
int
kex_derive_keys(struct ssh *ssh, u_char *hash, u_int hashlen,
const struct sshbuf *shared_secret)
{
struct kex *kex = ssh->kex;
u_char *keys[NKEYS];
u_int i, j, mode, ctos;
int r;
/* save initial hash as session id */
if ((kex->flags & KEX_INITIAL) != 0) {
if (sshbuf_len(kex->session_id) != 0) {
error_f("already have session ID at kex");
return SSH_ERR_INTERNAL_ERROR;
}
if ((r = sshbuf_put(kex->session_id, hash, hashlen)) != 0)
return r;
} else if (sshbuf_len(kex->session_id) == 0) {
error_f("no session ID in rekex");
return SSH_ERR_INTERNAL_ERROR;
}
for (i = 0; i < NKEYS; i++) {
if ((r = derive_key(ssh, 'A'+i, kex->we_need, hash, hashlen,
shared_secret, &keys[i])) != 0) {
for (j = 0; j < i; j++)
free(keys[j]);
return r;
}
}
for (mode = 0; mode < MODE_MAX; mode++) {
ctos = (!kex->server && mode == MODE_OUT) ||
(kex->server && mode == MODE_IN);
kex->newkeys[mode]->enc.iv = keys[ctos ? 0 : 1];
kex->newkeys[mode]->enc.key = keys[ctos ? 2 : 3];
kex->newkeys[mode]->mac.key = keys[ctos ? 4 : 5];
}
return 0;
}
int
kex_load_hostkey(struct ssh *ssh, struct sshkey **prvp, struct sshkey **pubp)
{
struct kex *kex = ssh->kex;
*pubp = NULL;
*prvp = NULL;
if (kex->load_host_public_key == NULL ||
kex->load_host_private_key == NULL) {
error_f("missing hostkey loader");
return SSH_ERR_INVALID_ARGUMENT;
}
*pubp = kex->load_host_public_key(kex->hostkey_type,
kex->hostkey_nid, ssh);
*prvp = kex->load_host_private_key(kex->hostkey_type,
kex->hostkey_nid, ssh);
if (*pubp == NULL)
return SSH_ERR_NO_HOSTKEY_LOADED;
return 0;
}
int
kex_verify_host_key(struct ssh *ssh, struct sshkey *server_host_key)
{
struct kex *kex = ssh->kex;
if (kex->verify_host_key == NULL) {
error_f("missing hostkey verifier");
return SSH_ERR_INVALID_ARGUMENT;
}
if (server_host_key->type != kex->hostkey_type ||
(kex->hostkey_type == KEY_ECDSA &&
server_host_key->ecdsa_nid != kex->hostkey_nid))
return SSH_ERR_KEY_TYPE_MISMATCH;
if (kex->verify_host_key(server_host_key, ssh) == -1)
return SSH_ERR_SIGNATURE_INVALID;
return 0;
}
#if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) || defined(DEBUG_KEXECDH)
void
dump_digest(const char *msg, const u_char *digest, int len)
{
fprintf(stderr, "%s\n", msg);
sshbuf_dump_data(digest, len, stderr);
}
#endif
/*
* Send a plaintext error message to the peer, suffixed by \r\n.
* Only used during banner exchange, and there only for the server.
*/
static void
send_error(struct ssh *ssh, char *msg)
{
char *crnl = "\r\n";
if (!ssh->kex->server)
return;
if (atomicio(vwrite, ssh_packet_get_connection_out(ssh),
msg, strlen(msg)) != strlen(msg) ||
atomicio(vwrite, ssh_packet_get_connection_out(ssh),
crnl, strlen(crnl)) != strlen(crnl))
error_f("write: %.100s", strerror(errno));
}
/*
* Sends our identification string and waits for the peer's. Will block for
* up to timeout_ms (or indefinitely if timeout_ms <= 0).
* Returns on 0 success or a ssherr.h code on failure.
*/
int
kex_exchange_identification(struct ssh *ssh, int timeout_ms,
const char *version_addendum)
{
int remote_major, remote_minor, mismatch, oerrno = 0;
- size_t len, i, n;
+ size_t len, n;
int r, expect_nl;
u_char c;
struct sshbuf *our_version = ssh->kex->server ?
ssh->kex->server_version : ssh->kex->client_version;
struct sshbuf *peer_version = ssh->kex->server ?
ssh->kex->client_version : ssh->kex->server_version;
char *our_version_string = NULL, *peer_version_string = NULL;
char *cp, *remote_version = NULL;
/* Prepare and send our banner */
sshbuf_reset(our_version);
if (version_addendum != NULL && *version_addendum == '\0')
version_addendum = NULL;
if ((r = sshbuf_putf(our_version, "SSH-%d.%d-%.100s%s%s\r\n",
PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, SSH_VERSION,
version_addendum == NULL ? "" : " ",
version_addendum == NULL ? "" : version_addendum)) != 0) {
oerrno = errno;
error_fr(r, "sshbuf_putf");
goto out;
}
if (atomicio(vwrite, ssh_packet_get_connection_out(ssh),
sshbuf_mutable_ptr(our_version),
sshbuf_len(our_version)) != sshbuf_len(our_version)) {
oerrno = errno;
debug_f("write: %.100s", strerror(errno));
r = SSH_ERR_SYSTEM_ERROR;
goto out;
}
if ((r = sshbuf_consume_end(our_version, 2)) != 0) { /* trim \r\n */
oerrno = errno;
error_fr(r, "sshbuf_consume_end");
goto out;
}
our_version_string = sshbuf_dup_string(our_version);
if (our_version_string == NULL) {
error_f("sshbuf_dup_string failed");
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
debug("Local version string %.100s", our_version_string);
/* Read other side's version identification. */
for (n = 0; ; n++) {
if (n >= SSH_MAX_PRE_BANNER_LINES) {
send_error(ssh, "No SSH identification string "
"received.");
error_f("No SSH version received in first %u lines "
"from server", SSH_MAX_PRE_BANNER_LINES);
r = SSH_ERR_INVALID_FORMAT;
goto out;
}
sshbuf_reset(peer_version);
expect_nl = 0;
- for (i = 0; ; i++) {
+ for (;;) {
if (timeout_ms > 0) {
r = waitrfd(ssh_packet_get_connection_in(ssh),
&timeout_ms);
if (r == -1 && errno == ETIMEDOUT) {
send_error(ssh, "Timed out waiting "
"for SSH identification string.");
error("Connection timed out during "
"banner exchange");
r = SSH_ERR_CONN_TIMEOUT;
goto out;
} else if (r == -1) {
oerrno = errno;
error_f("%s", strerror(errno));
r = SSH_ERR_SYSTEM_ERROR;
goto out;
}
}
len = atomicio(read, ssh_packet_get_connection_in(ssh),
&c, 1);
if (len != 1 && errno == EPIPE) {
error_f("Connection closed by remote host");
r = SSH_ERR_CONN_CLOSED;
goto out;
} else if (len != 1) {
oerrno = errno;
error_f("read: %.100s", strerror(errno));
r = SSH_ERR_SYSTEM_ERROR;
goto out;
}
if (c == '\r') {
expect_nl = 1;
continue;
}
if (c == '\n')
break;
if (c == '\0' || expect_nl) {
error_f("banner line contains invalid "
"characters");
goto invalid;
}
if ((r = sshbuf_put_u8(peer_version, c)) != 0) {
oerrno = errno;
error_fr(r, "sshbuf_put");
goto out;
}
if (sshbuf_len(peer_version) > SSH_MAX_BANNER_LEN) {
error_f("banner line too long");
goto invalid;
}
}
/* Is this an actual protocol banner? */
if (sshbuf_len(peer_version) > 4 &&
memcmp(sshbuf_ptr(peer_version), "SSH-", 4) == 0)
break;
/* If not, then just log the line and continue */
if ((cp = sshbuf_dup_string(peer_version)) == NULL) {
error_f("sshbuf_dup_string failed");
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
/* Do not accept lines before the SSH ident from a client */
if (ssh->kex->server) {
error_f("client sent invalid protocol identifier "
"\"%.256s\"", cp);
free(cp);
goto invalid;
}
debug_f("banner line %zu: %s", n, cp);
free(cp);
}
peer_version_string = sshbuf_dup_string(peer_version);
if (peer_version_string == NULL)
error_f("sshbuf_dup_string failed");
/* XXX must be same size for sscanf */
if ((remote_version = calloc(1, sshbuf_len(peer_version))) == NULL) {
error_f("calloc failed");
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
/*
* Check that the versions match. In future this might accept
* several versions and set appropriate flags to handle them.
*/
if (sscanf(peer_version_string, "SSH-%d.%d-%[^\n]\n",
&remote_major, &remote_minor, remote_version) != 3) {
error("Bad remote protocol version identification: '%.100s'",
peer_version_string);
invalid:
send_error(ssh, "Invalid SSH identification string.");
r = SSH_ERR_INVALID_FORMAT;
goto out;
}
debug("Remote protocol version %d.%d, remote software version %.100s",
remote_major, remote_minor, remote_version);
compat_banner(ssh, remote_version);
mismatch = 0;
switch (remote_major) {
case 2:
break;
case 1:
if (remote_minor != 99)
mismatch = 1;
break;
default:
mismatch = 1;
break;
}
if (mismatch) {
error("Protocol major versions differ: %d vs. %d",
PROTOCOL_MAJOR_2, remote_major);
send_error(ssh, "Protocol major versions differ.");
r = SSH_ERR_NO_PROTOCOL_VERSION;
goto out;
}
if (ssh->kex->server && (ssh->compat & SSH_BUG_PROBE) != 0) {
logit("probed from %s port %d with %s. Don't panic.",
ssh_remote_ipaddr(ssh), ssh_remote_port(ssh),
peer_version_string);
r = SSH_ERR_CONN_CLOSED; /* XXX */
goto out;
}
if (ssh->kex->server && (ssh->compat & SSH_BUG_SCANNER) != 0) {
logit("scanned from %s port %d with %s. Don't panic.",
ssh_remote_ipaddr(ssh), ssh_remote_port(ssh),
peer_version_string);
r = SSH_ERR_CONN_CLOSED; /* XXX */
goto out;
}
if ((ssh->compat & SSH_BUG_RSASIGMD5) != 0) {
logit("Remote version \"%.100s\" uses unsafe RSA signature "
"scheme; disabling use of RSA keys", remote_version);
}
/* success */
r = 0;
out:
free(our_version_string);
free(peer_version_string);
free(remote_version);
if (r == SSH_ERR_SYSTEM_ERROR)
errno = oerrno;
return r;
}
diff --git a/crypto/openssh/misc.c b/crypto/openssh/misc.c
index f2135803737a..c098dc610b7b 100644
--- a/crypto/openssh/misc.c
+++ b/crypto/openssh/misc.c
@@ -1,2828 +1,2917 @@
-/* $OpenBSD: misc.c,v 1.177 2022/08/11 01:56:51 djm Exp $ */
+/* $OpenBSD: misc.c,v 1.180 2023/01/06 02:37:04 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
* Copyright (c) 2005-2020 Damien Miller. All rights reserved.
* Copyright (c) 2004 Henning Brauer <henning@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/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <sys/un.h>
#include <limits.h>
#ifdef HAVE_LIBGEN_H
# include <libgen.h>
#endif
#ifdef HAVE_POLL_H
#include <poll.h>
#endif
#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <netdb.h>
#ifdef HAVE_PATHS_H
# include <paths.h>
#include <pwd.h>
#include <grp.h>
#endif
#ifdef SSH_TUN_OPENBSD
#include <net/if.h>
#endif
#include "xmalloc.h"
#include "misc.h"
#include "log.h"
#include "ssh.h"
#include "sshbuf.h"
#include "ssherr.h"
#include "platform.h"
/* remove newline at end of string */
char *
chop(char *s)
{
char *t = s;
while (*t) {
if (*t == '\n' || *t == '\r') {
*t = '\0';
return s;
}
t++;
}
return 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]))
+ if (isspace((unsigned char)s[i]))
s[i] = '\0';
}
}
/* set/unset filedescriptor to non-blocking */
int
set_nonblock(int fd)
{
int val;
val = fcntl(fd, F_GETFL);
if (val == -1) {
error("fcntl(%d, F_GETFL): %s", fd, strerror(errno));
return (-1);
}
if (val & O_NONBLOCK) {
debug3("fd %d is O_NONBLOCK", fd);
return (0);
}
debug2("fd %d setting O_NONBLOCK", fd);
val |= O_NONBLOCK;
if (fcntl(fd, F_SETFL, val) == -1) {
debug("fcntl(%d, F_SETFL, O_NONBLOCK): %s", fd,
strerror(errno));
return (-1);
}
return (0);
}
int
unset_nonblock(int fd)
{
int val;
val = fcntl(fd, F_GETFL);
if (val == -1) {
error("fcntl(%d, F_GETFL): %s", fd, strerror(errno));
return (-1);
}
if (!(val & O_NONBLOCK)) {
debug3("fd %d is not O_NONBLOCK", fd);
return (0);
}
debug("fd %d clearing O_NONBLOCK", fd);
val &= ~O_NONBLOCK;
if (fcntl(fd, F_SETFL, val) == -1) {
debug("fcntl(%d, F_SETFL, ~O_NONBLOCK): %s",
fd, strerror(errno));
return (-1);
}
return (0);
}
const char *
ssh_gai_strerror(int gaierr)
{
if (gaierr == EAI_SYSTEM && errno != 0)
return strerror(errno);
return gai_strerror(gaierr);
}
/* disable nagle on socket */
void
set_nodelay(int fd)
{
int opt;
socklen_t optlen;
optlen = sizeof opt;
if (getsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &opt, &optlen) == -1) {
debug("getsockopt TCP_NODELAY: %.100s", strerror(errno));
return;
}
if (opt == 1) {
debug2("fd %d is TCP_NODELAY", fd);
return;
}
opt = 1;
debug2("fd %d setting TCP_NODELAY", fd);
if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof opt) == -1)
error("setsockopt TCP_NODELAY: %.100s", strerror(errno));
}
/* Allow local port reuse in TIME_WAIT */
int
set_reuseaddr(int fd)
{
int on = 1;
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) {
error("setsockopt SO_REUSEADDR fd %d: %s", fd, strerror(errno));
return -1;
}
return 0;
}
/* Get/set routing domain */
char *
get_rdomain(int fd)
{
#if defined(HAVE_SYS_GET_RDOMAIN)
return sys_get_rdomain(fd);
#elif defined(__OpenBSD__)
int rtable;
char *ret;
socklen_t len = sizeof(rtable);
if (getsockopt(fd, SOL_SOCKET, SO_RTABLE, &rtable, &len) == -1) {
error("Failed to get routing domain for fd %d: %s",
fd, strerror(errno));
return NULL;
}
xasprintf(&ret, "%d", rtable);
return ret;
#else /* defined(__OpenBSD__) */
return NULL;
#endif
}
int
set_rdomain(int fd, const char *name)
{
#if defined(HAVE_SYS_SET_RDOMAIN)
return sys_set_rdomain(fd, name);
#elif defined(__OpenBSD__)
int rtable;
const char *errstr;
if (name == NULL)
return 0; /* default table */
rtable = (int)strtonum(name, 0, 255, &errstr);
if (errstr != NULL) {
/* Shouldn't happen */
error("Invalid routing domain \"%s\": %s", name, errstr);
return -1;
}
if (setsockopt(fd, SOL_SOCKET, SO_RTABLE,
&rtable, sizeof(rtable)) == -1) {
error("Failed to set routing domain %d on fd %d: %s",
rtable, fd, strerror(errno));
return -1;
}
return 0;
#else /* defined(__OpenBSD__) */
error("Setting routing domain is not supported on this platform");
return -1;
#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:",
+ 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:",
+ error("setsockopt socket %d IPV6_TCLASS %d: %s",
fd, tos, strerror(errno));
}
# endif /* IPV6_TCLASS */
break;
default:
debug2_f("unsupported socket family %d", af);
break;
}
#endif /* IP_TOS_IS_BROKEN */
}
/*
* Wait up to *timeoutp milliseconds for events on fd. Updates
* *timeoutp with time remaining.
* Returns 0 if fd ready or -1 on timeout or error (see errno).
*/
static int
waitfd(int fd, int *timeoutp, short events)
{
struct pollfd pfd;
struct timeval t_start;
int oerrno, r;
pfd.fd = fd;
pfd.events = events;
for (; *timeoutp >= 0;) {
monotime_tv(&t_start);
r = poll(&pfd, 1, *timeoutp);
oerrno = errno;
ms_subtract_diff(&t_start, timeoutp);
errno = oerrno;
if (r > 0)
return 0;
else if (r == -1 && errno != EAGAIN && errno != EINTR)
return -1;
else if (r == 0)
break;
}
/* timeout */
errno = ETIMEDOUT;
return -1;
}
/*
* Wait up to *timeoutp milliseconds for fd to be readable. Updates
* *timeoutp with time remaining.
* Returns 0 if fd ready or -1 on timeout or error (see errno).
*/
int
waitrfd(int fd, int *timeoutp) {
return waitfd(fd, timeoutp, POLLIN);
}
/*
* Attempt a non-blocking connect(2) to the specified address, waiting up to
* *timeoutp milliseconds for the connection to complete. If the timeout is
* <=0, then wait indefinitely.
*
* Returns 0 on success or -1 on failure.
*/
int
timeout_connect(int sockfd, const struct sockaddr *serv_addr,
socklen_t addrlen, int *timeoutp)
{
int optval = 0;
socklen_t optlen = sizeof(optval);
/* No timeout: just do a blocking connect() */
if (timeoutp == NULL || *timeoutp <= 0)
return connect(sockfd, serv_addr, addrlen);
set_nonblock(sockfd);
for (;;) {
if (connect(sockfd, serv_addr, addrlen) == 0) {
/* Succeeded already? */
unset_nonblock(sockfd);
return 0;
} else if (errno == EINTR)
continue;
else if (errno != EINPROGRESS)
return -1;
break;
}
if (waitfd(sockfd, timeoutp, POLLIN | POLLOUT) == -1)
return -1;
/* Completed or failed */
if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &optval, &optlen) == -1) {
debug("getsockopt: %s", strerror(errno));
return -1;
}
if (optval != 0) {
errno = optval;
return -1;
}
unset_nonblock(sockfd);
return 0;
}
/* Characters considered whitespace in strsep calls. */
#define WHITESPACE " \t\r\n"
#define QUOTE "\""
/* return next token in configuration line */
static char *
strdelim_internal(char **s, int split_equals)
{
char *old;
int wspace = 0;
if (*s == NULL)
return NULL;
old = *s;
*s = strpbrk(*s,
split_equals ? WHITESPACE QUOTE "=" : WHITESPACE QUOTE);
if (*s == NULL)
return (old);
if (*s[0] == '\"') {
memmove(*s, *s + 1, strlen(*s)); /* move nul too */
/* Find matching quote */
if ((*s = strpbrk(*s, QUOTE)) == NULL) {
return (NULL); /* no matching quote */
} else {
*s[0] = '\0';
*s += strspn(*s + 1, WHITESPACE) + 1;
return (old);
}
}
/* Allow only one '=' to be skipped */
if (split_equals && *s[0] == '=')
wspace = 1;
*s[0] = '\0';
/* Skip any extra whitespace after first token */
*s += strspn(*s + 1, WHITESPACE) + 1;
if (split_equals && *s[0] == '=' && !wspace)
*s += strspn(*s + 1, WHITESPACE) + 1;
return (old);
}
/*
* Return next token in configuration line; splts on whitespace or a
* single '=' character.
*/
char *
strdelim(char **s)
{
return strdelim_internal(s, 1);
}
/*
* Return next token in configuration line; splts on whitespace only.
*/
char *
strdelimw(char **s)
{
return strdelim_internal(s, 0);
}
struct passwd *
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 == NULL ? "*" : pw->pw_passwd);
#ifdef HAVE_STRUCT_PASSWD_PW_GECOS
copy->pw_gecos = xstrdup(pw->pw_gecos);
#endif
copy->pw_uid = pw->pw_uid;
copy->pw_gid = pw->pw_gid;
#ifdef HAVE_STRUCT_PASSWD_PW_EXPIRE
copy->pw_expire = pw->pw_expire;
#endif
#ifdef HAVE_STRUCT_PASSWD_PW_CHANGE
copy->pw_change = pw->pw_change;
#endif
#ifdef HAVE_STRUCT_PASSWD_PW_CLASS
copy->pw_class = xstrdup(pw->pw_class);
#endif
copy->pw_dir = xstrdup(pw->pw_dir);
copy->pw_shell = xstrdup(pw->pw_shell);
return copy;
}
/*
* Convert ASCII string to TCP/IP port number.
* Port must be >=0 and <=65535.
* Return -1 if invalid.
*/
int
a2port(const char *s)
{
struct servent *se;
long long port;
const char *errstr;
port = strtonum(s, 0, 65535, &errstr);
if (errstr == NULL)
return (int)port;
if ((se = getservbyname(s, "tcp")) != NULL)
return ntohs(se->s_port);
return -1;
}
int
a2tun(const char *s, int *remote)
{
const char *errstr = NULL;
char *sp, *ep;
int tun;
if (remote != NULL) {
*remote = SSH_TUNID_ANY;
sp = xstrdup(s);
if ((ep = strchr(sp, ':')) == NULL) {
free(sp);
return (a2tun(s, NULL));
}
ep[0] = '\0'; ep++;
*remote = a2tun(ep, NULL);
tun = a2tun(sp, NULL);
free(sp);
return (*remote == SSH_TUNID_ERR ? *remote : tun);
}
if (strcasecmp(s, "any") == 0)
return (SSH_TUNID_ANY);
tun = strtonum(s, 0, SSH_TUNID_MAX, &errstr);
if (errstr != NULL)
return (SSH_TUNID_ERR);
return (tun);
}
#define SECONDS 1
#define MINUTES (SECONDS * 60)
#define HOURS (MINUTES * 60)
#define DAYS (HOURS * 24)
#define WEEKS (DAYS * 7)
/*
* Convert a time string into seconds; format is
* a sequence of:
* time[qualifier]
*
* Valid time qualifiers are:
* <none> seconds
* s|S seconds
* m|M minutes
* h|H hours
* d|D days
* w|W weeks
*
* Examples:
* 90m 90 minutes
* 1h30m 90 minutes
* 2d 2 days
* 1w 1 week
*
* Return -1 if time string is invalid.
*/
int
convtime(const char *s)
{
long total, secs, multiplier;
const char *p;
char *endp;
errno = 0;
total = 0;
p = s;
if (p == NULL || *p == '\0')
return -1;
while (*p) {
secs = strtol(p, &endp, 10);
if (p == endp ||
(errno == ERANGE && (secs == INT_MIN || secs == INT_MAX)) ||
secs < 0)
return -1;
multiplier = 1;
switch (*endp++) {
case '\0':
endp--;
break;
case 's':
case 'S':
break;
case 'm':
case 'M':
multiplier = MINUTES;
break;
case 'h':
case 'H':
multiplier = HOURS;
break;
case 'd':
case 'D':
multiplier = DAYS;
break;
case 'w':
case 'W':
multiplier = WEEKS;
break;
default:
return -1;
}
if (secs > INT_MAX / multiplier)
return -1;
secs *= multiplier;
if (total > INT_MAX - secs)
return -1;
total += secs;
if (total < 0)
return -1;
p = endp;
}
return total;
}
#define TF_BUFS 8
#define TF_LEN 9
const char *
fmt_timeframe(time_t t)
{
char *buf;
static char tfbuf[TF_BUFS][TF_LEN]; /* ring buffer */
static int idx = 0;
unsigned int sec, min, hrs, day;
unsigned long long week;
buf = tfbuf[idx++];
if (idx == TF_BUFS)
idx = 0;
week = t;
sec = week % 60;
week /= 60;
min = week % 60;
week /= 60;
hrs = week % 24;
week /= 24;
day = week % 7;
week /= 7;
if (week > 0)
snprintf(buf, TF_LEN, "%02lluw%01ud%02uh", week, day, hrs);
else if (day > 0)
snprintf(buf, TF_LEN, "%01ud%02uh%02um", day, hrs, min);
else
snprintf(buf, TF_LEN, "%02u:%02u:%02u", hrs, min, sec);
return (buf);
}
/*
* Returns a standardized host+port identifier string.
* Caller must free returned string.
*/
char *
put_host_port(const char *host, u_short port)
{
char *hoststr;
if (port == 0 || port == SSH_DEFAULT_PORT)
return(xstrdup(host));
if (asprintf(&hoststr, "[%s]:%d", host, (int)port) == -1)
fatal("put_host_port: asprintf: %s", strerror(errno));
debug3("put_host_port: %s", hoststr);
return hoststr;
}
/*
* Search for next delimiter between hostnames/addresses and ports.
* Argument may be modified (for termination).
* Returns *cp if parsing succeeds.
* *cp is set to the start of the next field, if one was found.
* The delimiter char, if present, is stored in delim.
* If this is the last field, *cp is set to NULL.
*/
char *
hpdelim2(char **cp, char *delim)
{
char *s, *old;
if (cp == NULL || *cp == NULL)
return NULL;
old = s = *cp;
if (*s == '[') {
if ((s = strchr(s, ']')) == NULL)
return NULL;
else
s++;
} else if ((s = strpbrk(s, ":/")) == NULL)
s = *cp + strlen(*cp); /* skip to end (see first case below) */
switch (*s) {
case '\0':
*cp = NULL; /* no more fields*/
break;
case ':':
case '/':
if (delim != NULL)
*delim = *s;
*s = '\0'; /* terminate */
*cp = s + 1;
break;
default:
return NULL;
}
return old;
}
/* The common case: only accept colon as delimiter. */
char *
hpdelim(char **cp)
{
char *r, delim = '\0';
r = hpdelim2(cp, &delim);
if (delim == '/')
return NULL;
return r;
}
char *
cleanhostname(char *host)
{
if (*host == '[' && host[strlen(host) - 1] == ']') {
host[strlen(host) - 1] = '\0';
return (host + 1);
} else
return host;
}
char *
colon(char *cp)
{
int flag = 0;
if (*cp == ':') /* Leading colon is part of file name. */
return NULL;
if (*cp == '[')
flag = 1;
for (; *cp; ++cp) {
if (*cp == '@' && *(cp+1) == '[')
flag = 1;
if (*cp == ']' && *(cp+1) == ':' && flag)
return (cp+1);
if (*cp == ':' && !flag)
return (cp);
if (*cp == '/')
return NULL;
}
return NULL;
}
/*
* Parse a [user@]host:[path] string.
* Caller must free returned user, host and path.
* Any of the pointer return arguments may be NULL (useful for syntax checking).
* If user was not specified then *userp will be set to NULL.
* If host was not specified then *hostp will be set to NULL.
* If path was not specified then *pathp will be set to ".".
* Returns 0 on success, -1 on failure.
*/
int
parse_user_host_path(const char *s, char **userp, char **hostp, char **pathp)
{
char *user = NULL, *host = NULL, *path = NULL;
char *sdup, *tmp;
int ret = -1;
if (userp != NULL)
*userp = NULL;
if (hostp != NULL)
*hostp = NULL;
if (pathp != NULL)
*pathp = NULL;
sdup = xstrdup(s);
/* Check for remote syntax: [user@]host:[path] */
if ((tmp = colon(sdup)) == NULL)
goto out;
/* Extract optional path */
*tmp++ = '\0';
if (*tmp == '\0')
tmp = ".";
path = xstrdup(tmp);
/* Extract optional user and mandatory host */
tmp = strrchr(sdup, '@');
if (tmp != NULL) {
*tmp++ = '\0';
host = xstrdup(cleanhostname(tmp));
if (*sdup != '\0')
user = xstrdup(sdup);
} else {
host = xstrdup(cleanhostname(sdup));
user = NULL;
}
/* Success */
if (userp != NULL) {
*userp = user;
user = NULL;
}
if (hostp != NULL) {
*hostp = host;
host = NULL;
}
if (pathp != NULL) {
*pathp = path;
path = NULL;
}
ret = 0;
out:
free(sdup);
free(user);
free(host);
free(path);
return ret;
}
/*
* Parse a [user@]host[:port] string.
* Caller must free returned user and host.
* Any of the pointer return arguments may be NULL (useful for syntax checking).
* If user was not specified then *userp will be set to NULL.
* If port was not specified then *portp will be -1.
* Returns 0 on success, -1 on failure.
*/
int
parse_user_host_port(const char *s, char **userp, char **hostp, int *portp)
{
char *sdup, *cp, *tmp;
char *user = NULL, *host = NULL;
int port = -1, ret = -1;
if (userp != NULL)
*userp = NULL;
if (hostp != NULL)
*hostp = NULL;
if (portp != NULL)
*portp = -1;
if ((sdup = tmp = strdup(s)) == NULL)
return -1;
/* Extract optional username */
if ((cp = strrchr(tmp, '@')) != NULL) {
*cp = '\0';
if (*tmp == '\0')
goto out;
if ((user = strdup(tmp)) == NULL)
goto out;
tmp = cp + 1;
}
/* Extract mandatory hostname */
if ((cp = hpdelim(&tmp)) == NULL || *cp == '\0')
goto out;
host = xstrdup(cleanhostname(cp));
/* Convert and verify optional port */
if (tmp != NULL && *tmp != '\0') {
if ((port = a2port(tmp)) <= 0)
goto out;
}
/* Success */
if (userp != NULL) {
*userp = user;
user = NULL;
}
if (hostp != NULL) {
*hostp = host;
host = NULL;
}
if (portp != NULL)
*portp = port;
ret = 0;
out:
free(sdup);
free(user);
free(host);
return ret;
}
/*
* Converts a two-byte hex string to decimal.
* Returns the decimal value or -1 for invalid input.
*/
static int
hexchar(const char *s)
{
unsigned char result[2];
int i;
for (i = 0; i < 2; i++) {
if (s[i] >= '0' && s[i] <= '9')
result[i] = (unsigned char)(s[i] - '0');
else if (s[i] >= 'a' && s[i] <= 'f')
result[i] = (unsigned char)(s[i] - 'a') + 10;
else if (s[i] >= 'A' && s[i] <= 'F')
result[i] = (unsigned char)(s[i] - 'A') + 10;
else
return -1;
}
return (result[0] << 4) | result[1];
}
/*
* Decode an url-encoded string.
* Returns a newly allocated string on success or NULL on failure.
*/
static char *
urldecode(const char *src)
{
char *ret, *dst;
int ch;
ret = xmalloc(strlen(src) + 1);
for (dst = ret; *src != '\0'; src++) {
switch (*src) {
case '+':
*dst++ = ' ';
break;
case '%':
if (!isxdigit((unsigned char)src[1]) ||
!isxdigit((unsigned char)src[2]) ||
(ch = hexchar(src + 1)) == -1) {
free(ret);
return NULL;
}
*dst++ = ch;
src += 2;
break;
default:
*dst++ = *src;
break;
}
}
*dst = '\0';
return ret;
}
/*
* Parse an (scp|ssh|sftp)://[user@]host[:port][/path] URI.
* See https://tools.ietf.org/html/draft-ietf-secsh-scp-sftp-ssh-uri-04
* Either user or path may be url-encoded (but not host or port).
* Caller must free returned user, host and path.
* Any of the pointer return arguments may be NULL (useful for syntax checking)
* but the scheme must always be specified.
* If user was not specified then *userp will be set to NULL.
* If port was not specified then *portp will be -1.
* If path was not specified then *pathp will be set to NULL.
* Returns 0 on success, 1 if non-uri/wrong scheme, -1 on error/invalid uri.
*/
int
parse_uri(const char *scheme, const char *uri, char **userp, char **hostp,
int *portp, char **pathp)
{
char *uridup, *cp, *tmp, ch;
char *user = NULL, *host = NULL, *path = NULL;
int port = -1, ret = -1;
size_t len;
len = strlen(scheme);
if (strncmp(uri, scheme, len) != 0 || strncmp(uri + len, "://", 3) != 0)
return 1;
uri += len + 3;
if (userp != NULL)
*userp = NULL;
if (hostp != NULL)
*hostp = NULL;
if (portp != NULL)
*portp = -1;
if (pathp != NULL)
*pathp = NULL;
uridup = tmp = xstrdup(uri);
/* Extract optional ssh-info (username + connection params) */
if ((cp = strchr(tmp, '@')) != NULL) {
char *delim;
*cp = '\0';
/* Extract username and connection params */
if ((delim = strchr(tmp, ';')) != NULL) {
/* Just ignore connection params for now */
*delim = '\0';
}
if (*tmp == '\0') {
/* Empty username */
goto out;
}
if ((user = urldecode(tmp)) == NULL)
goto out;
tmp = cp + 1;
}
/* Extract mandatory hostname */
if ((cp = hpdelim2(&tmp, &ch)) == NULL || *cp == '\0')
goto out;
host = xstrdup(cleanhostname(cp));
if (!valid_domain(host, 0, NULL))
goto out;
if (tmp != NULL && *tmp != '\0') {
if (ch == ':') {
/* Convert and verify port. */
if ((cp = strchr(tmp, '/')) != NULL)
*cp = '\0';
if ((port = a2port(tmp)) <= 0)
goto out;
tmp = cp ? cp + 1 : NULL;
}
if (tmp != NULL && *tmp != '\0') {
/* Extract optional path */
if ((path = urldecode(tmp)) == NULL)
goto out;
}
}
/* Success */
if (userp != NULL) {
*userp = user;
user = NULL;
}
if (hostp != NULL) {
*hostp = host;
host = NULL;
}
if (portp != NULL)
*portp = port;
if (pathp != NULL) {
*pathp = path;
path = NULL;
}
ret = 0;
out:
free(uridup);
free(user);
free(host);
free(path);
return ret;
}
/* function to assist building execv() arguments */
void
addargs(arglist *args, char *fmt, ...)
{
va_list ap;
char *cp;
u_int nalloc;
int r;
va_start(ap, fmt);
r = vasprintf(&cp, fmt, ap);
va_end(ap);
if (r == -1)
fatal_f("argument too long");
nalloc = args->nalloc;
if (args->list == NULL) {
nalloc = 32;
args->num = 0;
} else if (args->num > (256 * 1024))
fatal_f("too many arguments");
else if (args->num >= args->nalloc)
fatal_f("arglist corrupt");
else if (args->num+2 >= nalloc)
nalloc *= 2;
args->list = xrecallocarray(args->list, args->nalloc,
nalloc, sizeof(char *));
args->nalloc = nalloc;
args->list[args->num++] = cp;
args->list[args->num] = NULL;
}
void
replacearg(arglist *args, u_int which, char *fmt, ...)
{
va_list ap;
char *cp;
int r;
va_start(ap, fmt);
r = vasprintf(&cp, fmt, ap);
va_end(ap);
if (r == -1)
fatal_f("argument too long");
if (args->list == NULL || args->num >= args->nalloc)
fatal_f("arglist corrupt");
if (which >= args->num)
fatal_f("tried to replace invalid arg %d >= %d",
which, args->num);
free(args->list[which]);
args->list[which] = cp;
}
void
freeargs(arglist *args)
{
u_int i;
if (args == NULL)
return;
if (args->list != NULL && args->num < args->nalloc) {
for (i = 0; i < args->num; i++)
free(args->list[i]);
free(args->list);
}
args->nalloc = args->num = 0;
args->list = NULL;
}
/*
* Expands tildes in the file name. Returns data allocated by xmalloc.
* Warning: this calls getpw*.
*/
int
tilde_expand(const char *filename, uid_t uid, char **retp)
{
char *ocopy = NULL, *copy, *s = NULL;
const char *path = NULL, *user = NULL;
struct passwd *pw;
size_t len;
int ret = -1, r, slash;
*retp = NULL;
if (*filename != '~') {
*retp = xstrdup(filename);
return 0;
}
ocopy = copy = xstrdup(filename + 1);
if (*copy == '\0') /* ~ */
path = NULL;
else if (*copy == '/') {
copy += strspn(copy, "/");
if (*copy == '\0')
path = NULL; /* ~/ */
else
path = copy; /* ~/path */
} else {
user = copy;
if ((path = strchr(copy, '/')) != NULL) {
copy[path - copy] = '\0';
path++;
path += strspn(path, "/");
if (*path == '\0') /* ~user/ */
path = NULL;
/* else ~user/path */
}
/* else ~user */
}
if (user != NULL) {
if ((pw = getpwnam(user)) == NULL) {
error_f("No such user %s", user);
goto out;
}
} else if ((pw = getpwuid(uid)) == NULL) {
error_f("No such uid %ld", (long)uid);
goto out;
}
/* Make sure directory has a trailing '/' */
slash = (len = strlen(pw->pw_dir)) == 0 || pw->pw_dir[len - 1] != '/';
if ((r = xasprintf(&s, "%s%s%s", pw->pw_dir,
slash ? "/" : "", path != NULL ? path : "")) <= 0) {
error_f("xasprintf failed");
goto out;
}
if (r >= PATH_MAX) {
error_f("Path too long");
goto out;
}
/* success */
ret = 0;
*retp = s;
s = NULL;
out:
free(s);
free(ocopy);
return ret;
}
char *
tilde_expand_filename(const char *filename, uid_t uid)
{
char *ret;
if (tilde_expand(filename, uid, &ret) != 0)
cleanup_exit(255);
return ret;
}
/*
* Expand a string with a set of %[char] escapes and/or ${ENVIRONMENT}
* substitutions. A number of escapes may be specified as
* (char *escape_chars, char *replacement) pairs. The list must be terminated
* by a NULL escape_char. Returns replaced string in memory allocated by
* xmalloc which the caller must free.
*/
static char *
vdollar_percent_expand(int *parseerror, int dollar, int percent,
const char *string, va_list ap)
{
#define EXPAND_MAX_KEYS 16
u_int num_keys = 0, i;
struct {
const char *key;
const char *repl;
} keys[EXPAND_MAX_KEYS];
struct sshbuf *buf;
int r, missingvar = 0;
char *ret = NULL, *var, *varend, *val;
size_t len;
if ((buf = sshbuf_new()) == NULL)
fatal_f("sshbuf_new failed");
if (parseerror == NULL)
fatal_f("null parseerror arg");
*parseerror = 1;
/* Gather keys if we're doing percent expansion. */
if (percent) {
for (num_keys = 0; num_keys < EXPAND_MAX_KEYS; num_keys++) {
keys[num_keys].key = va_arg(ap, char *);
if (keys[num_keys].key == NULL)
break;
keys[num_keys].repl = va_arg(ap, char *);
if (keys[num_keys].repl == NULL) {
fatal_f("NULL replacement for token %s",
keys[num_keys].key);
}
}
if (num_keys == EXPAND_MAX_KEYS && va_arg(ap, char *) != NULL)
fatal_f("too many keys");
if (num_keys == 0)
fatal_f("percent expansion without token list");
}
/* Expand string */
for (i = 0; *string != '\0'; string++) {
/* Optionally process ${ENVIRONMENT} expansions. */
if (dollar && string[0] == '$' && string[1] == '{') {
string += 2; /* skip over '${' */
if ((varend = strchr(string, '}')) == NULL) {
error_f("environment variable '%s' missing "
"closing '}'", string);
goto out;
}
len = varend - string;
if (len == 0) {
error_f("zero-length environment variable");
goto out;
}
var = xmalloc(len + 1);
(void)strlcpy(var, string, len + 1);
if ((val = getenv(var)) == NULL) {
error_f("env var ${%s} has no value", var);
missingvar = 1;
} else {
debug3_f("expand ${%s} -> '%s'", var, val);
if ((r = sshbuf_put(buf, val, strlen(val))) !=0)
fatal_fr(r, "sshbuf_put ${}");
}
free(var);
string += len;
continue;
}
/*
* Process percent expansions if we have a list of TOKENs.
* If we're not doing percent expansion everything just gets
* appended here.
*/
if (*string != '%' || !percent) {
append:
if ((r = sshbuf_put_u8(buf, *string)) != 0)
fatal_fr(r, "sshbuf_put_u8 %%");
continue;
}
string++;
/* %% case */
if (*string == '%')
goto append;
if (*string == '\0') {
error_f("invalid format");
goto out;
}
for (i = 0; i < num_keys; i++) {
if (strchr(keys[i].key, *string) != NULL) {
if ((r = sshbuf_put(buf, keys[i].repl,
strlen(keys[i].repl))) != 0)
fatal_fr(r, "sshbuf_put %%-repl");
break;
}
}
if (i >= num_keys) {
error_f("unknown key %%%c", *string);
goto out;
}
}
if (!missingvar && (ret = sshbuf_dup_string(buf)) == NULL)
fatal_f("sshbuf_dup_string failed");
*parseerror = 0;
out:
sshbuf_free(buf);
return *parseerror ? NULL : ret;
#undef EXPAND_MAX_KEYS
}
/*
* Expand only environment variables.
* Note that although this function is variadic like the other similar
* functions, any such arguments will be unused.
*/
char *
dollar_expand(int *parseerr, const char *string, ...)
{
char *ret;
int err;
va_list ap;
va_start(ap, string);
ret = vdollar_percent_expand(&err, 1, 0, string, ap);
va_end(ap);
if (parseerr != NULL)
*parseerr = err;
return ret;
}
/*
* Returns expanded string or NULL if a specified environment variable is
* not defined, or calls fatal if the string is invalid.
*/
char *
percent_expand(const char *string, ...)
{
char *ret;
int err;
va_list ap;
va_start(ap, string);
ret = vdollar_percent_expand(&err, 0, 1, string, ap);
va_end(ap);
if (err)
fatal_f("failed");
return ret;
}
/*
* Returns expanded string or NULL if a specified environment variable is
* not defined, or calls fatal if the string is invalid.
*/
char *
percent_dollar_expand(const char *string, ...)
{
char *ret;
int err;
va_list ap;
va_start(ap, string);
ret = vdollar_percent_expand(&err, 1, 1, string, ap);
va_end(ap);
if (err)
fatal_f("failed");
return ret;
}
int
tun_open(int tun, int mode, char **ifname)
{
#if defined(CUSTOM_SYS_TUN_OPEN)
return (sys_tun_open(tun, mode, ifname));
#elif defined(SSH_TUN_OPENBSD)
struct ifreq ifr;
char name[100];
int fd = -1, sock;
const char *tunbase = "tun";
if (ifname != NULL)
*ifname = NULL;
if (mode == SSH_TUNMODE_ETHERNET)
tunbase = "tap";
/* Open the tunnel device */
if (tun <= SSH_TUNID_MAX) {
snprintf(name, sizeof(name), "/dev/%s%d", tunbase, tun);
fd = open(name, O_RDWR);
} else if (tun == SSH_TUNID_ANY) {
for (tun = 100; tun >= 0; tun--) {
snprintf(name, sizeof(name), "/dev/%s%d",
tunbase, tun);
if ((fd = open(name, O_RDWR)) >= 0)
break;
}
} else {
debug_f("invalid tunnel %u", tun);
return -1;
}
if (fd == -1) {
debug_f("%s open: %s", name, strerror(errno));
return -1;
}
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);
if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) == -1)
goto failed;
if (ioctl(sock, SIOCGIFFLAGS, &ifr) == -1) {
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_f("activate interface %s: %s", ifr.ifr_name,
strerror(errno));
goto failed;
}
}
if (ifname != NULL)
*ifname = xstrdup(ifr.ifr_name);
close(sock);
return fd;
failed:
if (fd >= 0)
close(fd);
if (sock >= 0)
close(sock);
return -1;
#else
error("Tunnel interfaces are not supported on this platform");
return (-1);
#endif
}
void
sanitise_stdfd(void)
{
int nullfd, dupfd;
if ((nullfd = dupfd = open(_PATH_DEVNULL, O_RDWR)) == -1) {
fprintf(stderr, "Couldn't open /dev/null: %s\n",
strerror(errno));
exit(1);
}
while (++dupfd <= STDERR_FILENO) {
/* Only populate closed fds. */
if (fcntl(dupfd, F_GETFL) == -1 && errno == EBADF) {
if (dup2(nullfd, dupfd) == -1) {
fprintf(stderr, "dup2: %s\n", strerror(errno));
exit(1);
}
}
}
if (nullfd > STDERR_FILENO)
close(nullfd);
}
char *
tohex(const void *vp, size_t l)
{
const u_char *p = (const u_char *)vp;
char b[3], *r;
size_t i, hl;
if (l > 65536)
return xstrdup("tohex: length > 65536");
hl = l * 2 + 1;
r = xcalloc(1, hl);
for (i = 0; i < l; i++) {
snprintf(b, sizeof(b), "%02x", p[i]);
strlcat(r, b, hl);
}
return (r);
}
/*
* Extend string *sp by the specified format. If *sp is not NULL (or empty),
* then the separator 'sep' will be prepended before the formatted arguments.
* Extended strings are heap allocated.
*/
void
xextendf(char **sp, const char *sep, const char *fmt, ...)
{
va_list ap;
char *tmp1, *tmp2;
va_start(ap, fmt);
xvasprintf(&tmp1, fmt, ap);
va_end(ap);
if (*sp == NULL || **sp == '\0') {
free(*sp);
*sp = tmp1;
return;
}
xasprintf(&tmp2, "%s%s%s", *sp, sep == NULL ? "" : sep, tmp1);
free(tmp1);
free(*sp);
*sp = tmp2;
}
u_int64_t
get_u64(const void *vp)
{
const u_char *p = (const u_char *)vp;
u_int64_t v;
v = (u_int64_t)p[0] << 56;
v |= (u_int64_t)p[1] << 48;
v |= (u_int64_t)p[2] << 40;
v |= (u_int64_t)p[3] << 32;
v |= (u_int64_t)p[4] << 24;
v |= (u_int64_t)p[5] << 16;
v |= (u_int64_t)p[6] << 8;
v |= (u_int64_t)p[7];
return (v);
}
u_int32_t
get_u32(const void *vp)
{
const u_char *p = (const u_char *)vp;
u_int32_t v;
v = (u_int32_t)p[0] << 24;
v |= (u_int32_t)p[1] << 16;
v |= (u_int32_t)p[2] << 8;
v |= (u_int32_t)p[3];
return (v);
}
u_int32_t
get_u32_le(const void *vp)
{
const u_char *p = (const u_char *)vp;
u_int32_t v;
v = (u_int32_t)p[0];
v |= (u_int32_t)p[1] << 8;
v |= (u_int32_t)p[2] << 16;
v |= (u_int32_t)p[3] << 24;
return (v);
}
u_int16_t
get_u16(const void *vp)
{
const u_char *p = (const u_char *)vp;
u_int16_t v;
v = (u_int16_t)p[0] << 8;
v |= (u_int16_t)p[1];
return (v);
}
void
put_u64(void *vp, u_int64_t v)
{
u_char *p = (u_char *)vp;
p[0] = (u_char)(v >> 56) & 0xff;
p[1] = (u_char)(v >> 48) & 0xff;
p[2] = (u_char)(v >> 40) & 0xff;
p[3] = (u_char)(v >> 32) & 0xff;
p[4] = (u_char)(v >> 24) & 0xff;
p[5] = (u_char)(v >> 16) & 0xff;
p[6] = (u_char)(v >> 8) & 0xff;
p[7] = (u_char)v & 0xff;
}
void
put_u32(void *vp, u_int32_t v)
{
u_char *p = (u_char *)vp;
p[0] = (u_char)(v >> 24) & 0xff;
p[1] = (u_char)(v >> 16) & 0xff;
p[2] = (u_char)(v >> 8) & 0xff;
p[3] = (u_char)v & 0xff;
}
void
put_u32_le(void *vp, u_int32_t v)
{
u_char *p = (u_char *)vp;
p[0] = (u_char)v & 0xff;
p[1] = (u_char)(v >> 8) & 0xff;
p[2] = (u_char)(v >> 16) & 0xff;
p[3] = (u_char)(v >> 24) & 0xff;
}
void
put_u16(void *vp, u_int16_t v)
{
u_char *p = (u_char *)vp;
p[0] = (u_char)(v >> 8) & 0xff;
p[1] = (u_char)v & 0xff;
}
void
ms_subtract_diff(struct timeval *start, int *ms)
{
struct timeval diff, finish;
monotime_tv(&finish);
timersub(&finish, start, &diff);
*ms -= (diff.tv_sec * 1000) + (diff.tv_usec / 1000);
}
void
ms_to_timespec(struct timespec *ts, int ms)
{
if (ms < 0)
ms = 0;
ts->tv_sec = ms / 1000;
ts->tv_nsec = (ms % 1000) * 1000 * 1000;
}
void
monotime_ts(struct timespec *ts)
{
struct timeval tv;
#if defined(HAVE_CLOCK_GETTIME) && (defined(CLOCK_BOOTTIME) || \
defined(CLOCK_MONOTONIC) || defined(CLOCK_REALTIME))
static int gettime_failed = 0;
if (!gettime_failed) {
# ifdef CLOCK_BOOTTIME
if (clock_gettime(CLOCK_BOOTTIME, ts) == 0)
return;
# endif /* CLOCK_BOOTTIME */
# ifdef CLOCK_MONOTONIC
if (clock_gettime(CLOCK_MONOTONIC, ts) == 0)
return;
# endif /* CLOCK_MONOTONIC */
# ifdef CLOCK_REALTIME
/* Not monotonic, but we're almost out of options here. */
if (clock_gettime(CLOCK_REALTIME, ts) == 0)
return;
# endif /* CLOCK_REALTIME */
debug3("clock_gettime: %s", strerror(errno));
gettime_failed = 1;
}
#endif /* HAVE_CLOCK_GETTIME && (BOOTTIME || MONOTONIC || REALTIME) */
gettimeofday(&tv, NULL);
ts->tv_sec = tv.tv_sec;
ts->tv_nsec = (long)tv.tv_usec * 1000;
}
void
monotime_tv(struct timeval *tv)
{
struct timespec ts;
monotime_ts(&ts);
tv->tv_sec = ts.tv_sec;
tv->tv_usec = ts.tv_nsec / 1000;
}
time_t
monotime(void)
{
struct timespec ts;
monotime_ts(&ts);
return ts.tv_sec;
}
double
monotime_double(void)
{
struct timespec ts;
monotime_ts(&ts);
return ts.tv_sec + ((double)ts.tv_nsec / 1000000000);
}
void
bandwidth_limit_init(struct bwlimit *bw, u_int64_t kbps, size_t buflen)
{
bw->buflen = buflen;
bw->rate = kbps;
bw->thresh = buflen;
bw->lamt = 0;
timerclear(&bw->bwstart);
timerclear(&bw->bwend);
}
/* Callback from read/write loop to insert bandwidth-limiting delays */
void
bandwidth_limit(struct bwlimit *bw, size_t read_len)
{
u_int64_t waitlen;
struct timespec ts, rm;
bw->lamt += read_len;
if (!timerisset(&bw->bwstart)) {
monotime_tv(&bw->bwstart);
return;
}
if (bw->lamt < bw->thresh)
return;
monotime_tv(&bw->bwend);
timersub(&bw->bwend, &bw->bwstart, &bw->bwend);
if (!timerisset(&bw->bwend))
return;
bw->lamt *= 8;
waitlen = (double)1000000L * bw->lamt / bw->rate;
bw->bwstart.tv_sec = waitlen / 1000000L;
bw->bwstart.tv_usec = waitlen % 1000000L;
if (timercmp(&bw->bwstart, &bw->bwend, >)) {
timersub(&bw->bwstart, &bw->bwend, &bw->bwend);
/* Adjust the wait time */
if (bw->bwend.tv_sec) {
bw->thresh /= 2;
if (bw->thresh < bw->buflen / 4)
bw->thresh = bw->buflen / 4;
} else if (bw->bwend.tv_usec < 10000) {
bw->thresh *= 2;
if (bw->thresh > bw->buflen * 8)
bw->thresh = bw->buflen * 8;
}
TIMEVAL_TO_TIMESPEC(&bw->bwend, &ts);
while (nanosleep(&ts, &rm) == -1) {
if (errno != EINTR)
break;
ts = rm;
}
}
bw->lamt = 0;
monotime_tv(&bw->bwstart);
}
/* Make a template filename for mk[sd]temp() */
void
mktemp_proto(char *s, size_t len)
{
const char *tmpdir;
int r;
if ((tmpdir = getenv("TMPDIR")) != NULL) {
r = snprintf(s, len, "%s/ssh-XXXXXXXXXXXX", tmpdir);
if (r > 0 && (size_t)r < len)
return;
}
r = snprintf(s, len, "/tmp/ssh-XXXXXXXXXXXX");
if (r < 0 || (size_t)r >= len)
fatal_f("template string too short");
}
static const struct {
const char *name;
int value;
} ipqos[] = {
{ "none", INT_MAX }, /* can't use 0 here; that's CS0 */
{ "af11", IPTOS_DSCP_AF11 },
{ "af12", IPTOS_DSCP_AF12 },
{ "af13", IPTOS_DSCP_AF13 },
{ "af21", IPTOS_DSCP_AF21 },
{ "af22", IPTOS_DSCP_AF22 },
{ "af23", IPTOS_DSCP_AF23 },
{ "af31", IPTOS_DSCP_AF31 },
{ "af32", IPTOS_DSCP_AF32 },
{ "af33", IPTOS_DSCP_AF33 },
{ "af41", IPTOS_DSCP_AF41 },
{ "af42", IPTOS_DSCP_AF42 },
{ "af43", IPTOS_DSCP_AF43 },
{ "cs0", IPTOS_DSCP_CS0 },
{ "cs1", IPTOS_DSCP_CS1 },
{ "cs2", IPTOS_DSCP_CS2 },
{ "cs3", IPTOS_DSCP_CS3 },
{ "cs4", IPTOS_DSCP_CS4 },
{ "cs5", IPTOS_DSCP_CS5 },
{ "cs6", IPTOS_DSCP_CS6 },
{ "cs7", IPTOS_DSCP_CS7 },
{ "ef", IPTOS_DSCP_EF },
{ "le", IPTOS_DSCP_LE },
{ "lowdelay", IPTOS_LOWDELAY },
{ "throughput", IPTOS_THROUGHPUT },
{ "reliability", IPTOS_RELIABILITY },
{ NULL, -1 }
};
int
parse_ipqos(const char *cp)
{
u_int i;
char *ep;
long val;
if (cp == NULL)
return -1;
for (i = 0; ipqos[i].name != NULL; i++) {
if (strcasecmp(cp, ipqos[i].name) == 0)
return ipqos[i].value;
}
/* Try parsing as an integer */
val = strtol(cp, &ep, 0);
if (*cp == '\0' || *ep != '\0' || val < 0 || val > 255)
return -1;
return val;
}
const char *
iptos2str(int iptos)
{
int i;
static char iptos_str[sizeof "0xff"];
for (i = 0; ipqos[i].name != NULL; i++) {
if (ipqos[i].value == iptos)
return ipqos[i].name;
}
snprintf(iptos_str, sizeof iptos_str, "0x%02x", iptos);
return iptos_str;
}
void
lowercase(char *s)
{
for (; *s; s++)
*s = tolower((u_char)*s);
}
int
unix_listener(const char *path, int backlog, int unlink_first)
{
struct sockaddr_un sunaddr;
int saved_errno, sock;
memset(&sunaddr, 0, sizeof(sunaddr));
sunaddr.sun_family = AF_UNIX;
if (strlcpy(sunaddr.sun_path, path,
sizeof(sunaddr.sun_path)) >= sizeof(sunaddr.sun_path)) {
error_f("path \"%s\" too long for Unix domain socket", path);
errno = ENAMETOOLONG;
return -1;
}
sock = socket(PF_UNIX, SOCK_STREAM, 0);
if (sock == -1) {
saved_errno = errno;
error_f("socket: %.100s", strerror(errno));
errno = saved_errno;
return -1;
}
if (unlink_first == 1) {
if (unlink(path) != 0 && errno != ENOENT)
error("unlink(%s): %.100s", path, strerror(errno));
}
if (bind(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) == -1) {
saved_errno = 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_f("cannot listen on path %s: %s", path, strerror(errno));
close(sock);
unlink(path);
errno = saved_errno;
return -1;
}
return sock;
}
void
sock_set_v6only(int s)
{
#if defined(IPV6_V6ONLY) && !defined(__OpenBSD__)
int on = 1;
debug3("%s: set socket %d IPV6_V6ONLY", __func__, s);
if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) == -1)
error("setsockopt IPV6_V6ONLY: %s", strerror(errno));
#endif
}
/*
* Compares two strings that maybe be NULL. Returns non-zero if strings
* are both NULL or are identical, returns zero otherwise.
*/
static int
strcmp_maybe_null(const char *a, const char *b)
{
if ((a == NULL && b != NULL) || (a != NULL && b == NULL))
return 0;
if (a != NULL && strcmp(a, b) != 0)
return 0;
return 1;
}
/*
* Compare two forwards, returning non-zero if they are identical or
* zero otherwise.
*/
int
forward_equals(const struct Forward *a, const struct Forward *b)
{
if (strcmp_maybe_null(a->listen_host, b->listen_host) == 0)
return 0;
if (a->listen_port != b->listen_port)
return 0;
if (strcmp_maybe_null(a->listen_path, b->listen_path) == 0)
return 0;
if (strcmp_maybe_null(a->connect_host, b->connect_host) == 0)
return 0;
if (a->connect_port != b->connect_port)
return 0;
if (strcmp_maybe_null(a->connect_path, b->connect_path) == 0)
return 0;
/* allocated_port and handle are not checked */
return 1;
}
/* returns 1 if process is already daemonized, 0 otherwise */
int
daemonized(void)
{
int fd;
if ((fd = open(_PATH_TTY, O_RDONLY | O_NOCTTY)) >= 0) {
close(fd);
return 0; /* have controlling terminal */
}
if (getppid() != 1)
return 0; /* parent is not init */
if (getsid(0) != getpid())
return 0; /* not session leader */
debug3("already daemonized");
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, int terminate_on_comment)
{
int r = SSH_ERR_INTERNAL_ERROR;
int argc = 0, quote, i, j;
char *arg, **argv = xcalloc(1, sizeof(*argv));
*argvp = NULL;
*argcp = 0;
for (i = 0; s[i] != '\0'; i++) {
/* Skip leading whitespace */
if (s[i] == ' ' || s[i] == '\t')
continue;
if (terminate_on_comment && s[i] == '#')
break;
/* Start of a token */
quote = 0;
argv = xreallocarray(argv, (argc + 2), sizeof(*argv));
arg = argv[argc++] = xcalloc(1, strlen(s + i) + 1);
argv[argc] = NULL;
/* Copy the token in, removing escapes */
for (j = 0; s[i] != '\0'; i++) {
if (s[i] == '\\') {
if (s[i + 1] == '\'' ||
s[i + 1] == '\"' ||
s[i + 1] == '\\' ||
(quote == 0 && s[i + 1] == ' ')) {
i++; /* Skip '\' */
arg[j++] = s[i];
} else {
/* Unrecognised escape */
arg[j++] = s[i];
}
} 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)
quote = 0; /* quote end */
else
arg[j++] = s[i];
}
if (s[i] == '\0') {
if (quote != 0) {
/* Ran out of string looking for close quote */
r = SSH_ERR_INVALID_FORMAT;
goto out;
}
break;
}
}
/* Success */
*argcp = argc;
*argvp = argv;
argc = 0;
argv = NULL;
r = 0;
out:
if (argc != 0 && argv != NULL) {
for (i = 0; i < argc; i++)
free(argv[i]);
free(argv);
}
return r;
}
/*
* Reassemble an argument vector into a string, quoting and escaping as
* necessary. Caller must free returned string.
*/
char *
argv_assemble(int argc, char **argv)
{
int i, j, ws, r;
char c, *ret;
struct sshbuf *buf, *arg;
if ((buf = sshbuf_new()) == NULL || (arg = sshbuf_new()) == NULL)
fatal_f("sshbuf_new failed");
for (i = 0; i < argc; i++) {
ws = 0;
sshbuf_reset(arg);
for (j = 0; argv[i][j] != '\0'; j++) {
r = 0;
c = argv[i][j];
switch (c) {
case ' ':
case '\t':
ws = 1;
r = sshbuf_put_u8(arg, c);
break;
case '\\':
case '\'':
case '"':
if ((r = sshbuf_put_u8(arg, '\\')) != 0)
break;
/* FALLTHROUGH */
default:
r = sshbuf_put_u8(arg, c);
break;
}
if (r != 0)
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_fr(r, "assemble");
}
if ((ret = malloc(sshbuf_len(buf) + 1)) == NULL)
fatal_f("malloc failed");
memcpy(ret, sshbuf_ptr(buf), sshbuf_len(buf));
ret[sshbuf_len(buf)] = '\0';
sshbuf_free(buf);
sshbuf_free(arg);
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)
{
int status;
while (waitpid(pid, &status, 0) == -1) {
if (errno != EINTR) {
error("%s waitpid: %s", tag, strerror(errno));
return -1;
}
}
if (WIFSIGNALED(status)) {
error("%s %s exited on signal %d", tag, cmd, WTERMSIG(status));
return -1;
} else if (WEXITSTATUS(status) != 0) {
do_log2(quiet ? SYSLOG_LEVEL_DEBUG1 : SYSLOG_LEVEL_INFO,
"%s %s failed, status %d", tag, cmd, WEXITSTATUS(status));
return -1;
}
return 0;
}
/*
* Check a given path for security. This is defined as all components
* of the path to the file must be owned by either the owner of
* of the file or root and no directories must be group or world writable.
*
* XXX Should any specific check be done for sym links ?
*
* Takes a file name, its stat information (preferably from fstat() to
* avoid races), the uid of the expected owner, their home directory and an
* error buffer plus max size as arguments.
*
* Returns 0 on success and -1 on failure
*/
int
safe_path(const char *name, struct stat *stp, const char *pw_dir,
uid_t uid, char *err, size_t errlen)
{
char buf[PATH_MAX], homedir[PATH_MAX];
char *cp;
int comparehome = 0;
struct stat st;
if (realpath(name, buf) == NULL) {
snprintf(err, errlen, "realpath %s failed: %s", name,
strerror(errno));
return -1;
}
if (pw_dir != NULL && realpath(pw_dir, homedir) != NULL)
comparehome = 1;
if (!S_ISREG(stp->st_mode)) {
snprintf(err, errlen, "%s is not a regular file", buf);
return -1;
}
if ((!platform_sys_dir_uid(stp->st_uid) && stp->st_uid != uid) ||
(stp->st_mode & 022) != 0) {
snprintf(err, errlen, "bad ownership or modes for file %s",
buf);
return -1;
}
/* for each component of the canonical path, walking upwards */
for (;;) {
if ((cp = dirname(buf)) == NULL) {
snprintf(err, errlen, "dirname() failed");
return -1;
}
strlcpy(buf, cp, sizeof(buf));
if (stat(buf, &st) == -1 ||
(!platform_sys_dir_uid(st.st_uid) && st.st_uid != uid) ||
(st.st_mode & 022) != 0) {
snprintf(err, errlen,
"bad ownership or modes for directory %s", buf);
return -1;
}
/* If are past the homedir then we can stop */
if (comparehome && strcmp(homedir, buf) == 0)
break;
/*
* dirname should always complete with a "/" path,
* but we can be paranoid and check for "." too
*/
if ((strcmp("/", buf) == 0) || (strcmp(".", buf) == 0))
break;
}
return 0;
}
/*
* Version of safe_path() that accepts an open file descriptor to
* avoid races.
*
* Returns 0 on success and -1 on failure
*/
int
safe_path_fd(int fd, const char *file, struct passwd *pw,
char *err, size_t errlen)
{
struct stat st;
/* check the open file to avoid races */
if (fstat(fd, &st) == -1) {
snprintf(err, errlen, "cannot stat file %s: %s",
file, strerror(errno));
return -1;
}
return safe_path(file, &st, pw->pw_dir, pw->pw_uid, err, errlen);
}
/*
* Sets the value of the given variable in the environment. If the variable
* already exists, its value is overridden.
*/
void
child_set_env(char ***envp, u_int *envsizep, const char *name,
const char *value)
{
char **env;
u_int envsize;
u_int i, namelen;
if (strchr(name, '=') != NULL) {
error("Invalid environment variable \"%.100s\"", name);
return;
}
/*
* If we're passed an uninitialized list, allocate a single null
* entry before continuing.
*/
if (*envp == NULL && *envsizep == 0) {
*envp = xmalloc(sizeof(char *));
*envp[0] = NULL;
*envsizep = 1;
}
/*
* Find the slot where the value should be stored. If the variable
* already exists, we reuse the slot; otherwise we append a new slot
* at the end of the array, expanding if necessary.
*/
env = *envp;
namelen = strlen(name);
for (i = 0; env[i]; i++)
if (strncmp(env[i], name, namelen) == 0 && env[i][namelen] == '=')
break;
if (env[i]) {
/* Reuse the slot. */
free(env[i]);
} else {
/* New variable. Expand if necessary. */
envsize = *envsizep;
if (i >= envsize - 1) {
if (envsize >= 1000)
fatal("child_set_env: too many env vars");
envsize += 50;
env = (*envp) = xreallocarray(env, envsize, sizeof(char *));
*envsizep = envsize;
}
/* Need to set the NULL pointer at end of array beyond the new slot. */
env[i + 1] = NULL;
}
/* Allocate space and format the variable in the appropriate slot. */
/* XXX xasprintf */
env[i] = xmalloc(strlen(name) + 1 + strlen(value) + 1);
snprintf(env[i], strlen(name) + 1 + strlen(value) + 1, "%s=%s", name, value);
}
/*
* Check and optionally lowercase a domain name, also removes trailing '.'
* Returns 1 on success and 0 on failure, storing an error message in errstr.
*/
int
valid_domain(char *name, int makelower, const char **errstr)
{
size_t i, l = strlen(name);
u_char c, last = '\0';
static char errbuf[256];
if (l == 0) {
strlcpy(errbuf, "empty domain name", sizeof(errbuf));
goto bad;
}
if (!isalpha((u_char)name[0]) && !isdigit((u_char)name[0])) {
snprintf(errbuf, sizeof(errbuf), "domain name \"%.100s\" "
"starts with invalid character", name);
goto bad;
}
for (i = 0; i < l; i++) {
c = tolower((u_char)name[i]);
if (makelower)
name[i] = (char)c;
if (last == '.' && c == '.') {
snprintf(errbuf, sizeof(errbuf), "domain name "
"\"%.100s\" contains consecutive separators", name);
goto bad;
}
if (c != '.' && c != '-' && !isalnum(c) &&
c != '_') /* technically invalid, but common */ {
snprintf(errbuf, sizeof(errbuf), "domain name "
"\"%.100s\" contains invalid characters", name);
goto bad;
}
last = c;
}
if (name[l - 1] == '.')
name[l - 1] = '\0';
if (errstr != NULL)
*errstr = NULL;
return 1;
bad:
if (errstr != NULL)
*errstr = errbuf;
return 0;
}
/*
* Verify that a environment variable name (not including initial '$') is
* valid; consisting of one or more alphanumeric or underscore characters only.
* Returns 1 on valid, 0 otherwise.
*/
int
valid_env_name(const char *name)
{
const char *cp;
if (name[0] == '\0')
return 0;
for (cp = name; *cp != '\0'; cp++) {
if (!isalnum((u_char)*cp) && *cp != '_')
return 0;
}
return 1;
}
const char *
atoi_err(const char *nptr, int *val)
{
const char *errstr = NULL;
long long num;
if (nptr == NULL || *nptr == '\0')
return "missing";
num = strtonum(nptr, 0, INT_MAX, &errstr);
if (errstr == NULL)
*val = (int)num;
return errstr;
}
int
parse_absolute_time(const char *s, uint64_t *tp)
{
struct tm tm;
time_t tt;
char buf[32], *fmt;
const char *cp;
size_t l;
int is_utc = 0;
*tp = 0;
l = strlen(s);
if (l > 1 && strcasecmp(s + l - 1, "Z") == 0) {
is_utc = 1;
l--;
} else if (l > 3 && strcasecmp(s + l - 3, "UTC") == 0) {
is_utc = 1;
l -= 3;
}
/*
* POSIX strptime says "The application shall ensure that there
* is white-space or other non-alphanumeric characters between
* any two conversion specifications" so arrange things this way.
*/
switch (l) {
case 8: /* YYYYMMDD */
fmt = "%Y-%m-%d";
snprintf(buf, sizeof(buf), "%.4s-%.2s-%.2s", s, s + 4, s + 6);
break;
case 12: /* YYYYMMDDHHMM */
fmt = "%Y-%m-%dT%H:%M";
snprintf(buf, sizeof(buf), "%.4s-%.2s-%.2sT%.2s:%.2s",
s, s + 4, s + 6, s + 8, s + 10);
break;
case 14: /* YYYYMMDDHHMMSS */
fmt = "%Y-%m-%dT%H:%M:%S";
snprintf(buf, sizeof(buf), "%.4s-%.2s-%.2sT%.2s:%.2s:%.2s",
s, s + 4, s + 6, s + 8, s + 10, s + 12);
break;
default:
return SSH_ERR_INVALID_FORMAT;
}
memset(&tm, 0, sizeof(tm));
if ((cp = strptime(buf, fmt, &tm)) == NULL || *cp != '\0')
return SSH_ERR_INVALID_FORMAT;
if (is_utc) {
if ((tt = timegm(&tm)) < 0)
return SSH_ERR_INVALID_FORMAT;
} else {
if ((tt = mktime(&tm)) < 0)
return SSH_ERR_INVALID_FORMAT;
}
/* success */
*tp = (uint64_t)tt;
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 > SSH_TIME_T_MAX ? SSH_TIME_T_MAX : t;
struct tm tm;
localtime_r(&tt, &tm);
strftime(buf, len, "%Y-%m-%dT%H:%M:%S", &tm);
}
/* check if path is absolute */
int
path_absolute(const char *path)
{
return (*path == '/') ? 1 : 0;
}
void
skip_space(char **cpp)
{
char *cp;
for (cp = *cpp; *cp == ' ' || *cp == '\t'; cp++)
;
*cpp = cp;
}
/* authorized_key-style options parsing helpers */
/*
* Match flag 'opt' in *optsp, and if allow_negate is set then also match
* 'no-opt'. Returns -1 if option not matched, 1 if option matches or 0
* if negated option matches.
* If the option or negated option matches, then *optsp is updated to
* point to the first character after the option.
*/
int
opt_flag(const char *opt, int allow_negate, const char **optsp)
{
size_t opt_len = strlen(opt);
const char *opts = *optsp;
int negate = 0;
if (allow_negate && strncasecmp(opts, "no-", 3) == 0) {
opts += 3;
negate = 1;
}
if (strncasecmp(opts, opt, opt_len) == 0) {
*optsp = opts + opt_len;
return negate ? 0 : 1;
}
return -1;
}
char *
opt_dequote(const char **sp, const char **errstrp)
{
const char *s = *sp;
char *ret;
size_t i;
*errstrp = NULL;
if (*s != '"') {
*errstrp = "missing start quote";
return NULL;
}
s++;
if ((ret = malloc(strlen((s)) + 1)) == NULL) {
*errstrp = "memory allocation failed";
return NULL;
}
for (i = 0; *s != '\0' && *s != '"';) {
if (s[0] == '\\' && s[1] == '"')
s++;
ret[i++] = *s++;
}
if (*s == '\0') {
*errstrp = "missing end quote";
free(ret);
return NULL;
}
ret[i] = '\0';
s++;
*sp = s;
return ret;
}
int
opt_match(const char **opts, const char *term)
{
if (strncasecmp((*opts), term, strlen(term)) == 0 &&
(*opts)[strlen(term)] == '=') {
*opts += strlen(term) + 1;
return 1;
}
return 0;
}
void
opt_array_append2(const char *file, const int line, const char *directive,
char ***array, int **iarray, u_int *lp, const char *s, int i)
{
if (*lp >= INT_MAX)
fatal("%s line %d: Too many %s entries", file, line, directive);
if (iarray != NULL) {
*iarray = xrecallocarray(*iarray, *lp, *lp + 1,
sizeof(**iarray));
(*iarray)[*lp] = i;
}
*array = xrecallocarray(*array, *lp, *lp + 1, sizeof(**array));
(*array)[*lp] = xstrdup(s);
(*lp)++;
}
void
opt_array_append(const char *file, const int line, const char *directive,
char ***array, u_int *lp, const char *s)
{
opt_array_append2(file, line, directive, array, NULL, lp, s, 0);
}
sshsig_t
ssh_signal(int signum, sshsig_t handler)
{
struct sigaction sa, osa;
/* mask all other signals while in handler */
memset(&sa, 0, sizeof(sa));
sa.sa_handler = handler;
sigfillset(&sa.sa_mask);
#if defined(SA_RESTART) && !defined(NO_SA_RESTART)
if (signum != SIGALRM)
sa.sa_flags = SA_RESTART;
#endif
if (sigaction(signum, &sa, &osa) == -1) {
debug3("sigaction(%s): %s", strsignal(signum), strerror(errno));
return SIG_ERR;
}
return osa.sa_handler;
}
int
stdfd_devnull(int do_stdin, int do_stdout, int do_stderr)
{
int devnull, ret = 0;
if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1) {
error_f("open %s: %s", _PATH_DEVNULL,
strerror(errno));
return -1;
}
if ((do_stdin && dup2(devnull, STDIN_FILENO) == -1) ||
(do_stdout && dup2(devnull, STDOUT_FILENO) == -1) ||
(do_stderr && dup2(devnull, STDERR_FILENO) == -1)) {
error_f("dup2: %s", strerror(errno));
ret = -1;
}
if (devnull > STDERR_FILENO)
close(devnull);
return ret;
}
/*
* Runs command in a subprocess with a minimal environment.
* Returns pid on success, 0 on failure.
* The child stdout and stderr maybe captured, left attached or sent to
* /dev/null depending on the contents of flags.
* "tag" is prepended to log messages.
* NB. "command" is only used for logging; the actual command executed is
* av[0].
*/
pid_t
subprocess(const char *tag, const char *command,
int ac, char **av, FILE **child, u_int flags,
struct passwd *pw, privdrop_fn *drop_privs, privrestore_fn *restore_privs)
{
FILE *f = NULL;
struct stat st;
int fd, devnull, p[2], i;
pid_t pid;
char *cp, errmsg[512];
u_int nenv = 0;
char **env = NULL;
/* If dropping privs, then must specify user and restore function */
if (drop_privs != NULL && (pw == NULL || restore_privs == NULL)) {
error("%s: inconsistent arguments", tag); /* XXX fatal? */
return 0;
}
if (pw == NULL && (pw = getpwuid(getuid())) == NULL) {
error("%s: no user for current uid", tag);
return 0;
}
if (child != NULL)
*child = NULL;
debug3_f("%s command \"%s\" running as %s (flags 0x%x)",
tag, command, pw->pw_name, flags);
/* Check consistency */
if ((flags & SSH_SUBPROCESS_STDOUT_DISCARD) != 0 &&
(flags & SSH_SUBPROCESS_STDOUT_CAPTURE) != 0) {
error_f("inconsistent flags");
return 0;
}
if (((flags & SSH_SUBPROCESS_STDOUT_CAPTURE) == 0) != (child == NULL)) {
error_f("inconsistent flags/output");
return 0;
}
/*
* If executing an explicit binary, then verify the it exists
* and appears safe-ish to execute
*/
if (!path_absolute(av[0])) {
error("%s path is not absolute", tag);
return 0;
}
if (drop_privs != NULL)
drop_privs(pw);
if (stat(av[0], &st) == -1) {
error("Could not stat %s \"%s\": %s", tag,
av[0], strerror(errno));
goto restore_return;
}
if ((flags & SSH_SUBPROCESS_UNSAFE_PATH) == 0 &&
safe_path(av[0], &st, NULL, 0, errmsg, sizeof(errmsg)) != 0) {
error("Unsafe %s \"%s\": %s", tag, av[0], errmsg);
goto restore_return;
}
/* Prepare to keep the child's stdout if requested */
if (pipe(p) == -1) {
error("%s: pipe: %s", tag, strerror(errno));
restore_return:
if (restore_privs != NULL)
restore_privs();
return 0;
}
if (restore_privs != NULL)
restore_privs();
switch ((pid = fork())) {
case -1: /* error */
error("%s: fork: %s", tag, strerror(errno));
close(p[0]);
close(p[1]);
return 0;
case 0: /* child */
/* Prepare a minimal environment for the child. */
if ((flags & SSH_SUBPROCESS_PRESERVE_ENV) == 0) {
nenv = 5;
env = xcalloc(sizeof(*env), nenv);
child_set_env(&env, &nenv, "PATH", _PATH_STDPATH);
child_set_env(&env, &nenv, "USER", pw->pw_name);
child_set_env(&env, &nenv, "LOGNAME", pw->pw_name);
child_set_env(&env, &nenv, "HOME", pw->pw_dir);
if ((cp = getenv("LANG")) != NULL)
child_set_env(&env, &nenv, "LANG", cp);
}
for (i = 1; i < NSIG; i++)
ssh_signal(i, SIG_DFL);
if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1) {
error("%s: open %s: %s", tag, _PATH_DEVNULL,
strerror(errno));
_exit(1);
}
if (dup2(devnull, STDIN_FILENO) == -1) {
error("%s: dup2: %s", tag, strerror(errno));
_exit(1);
}
/* Set up stdout as requested; leave stderr in place for now. */
fd = -1;
if ((flags & SSH_SUBPROCESS_STDOUT_CAPTURE) != 0)
fd = p[1];
else if ((flags & SSH_SUBPROCESS_STDOUT_DISCARD) != 0)
fd = devnull;
if (fd != -1 && dup2(fd, STDOUT_FILENO) == -1) {
error("%s: dup2: %s", tag, strerror(errno));
_exit(1);
}
closefrom(STDERR_FILENO + 1);
if (geteuid() == 0 &&
initgroups(pw->pw_name, pw->pw_gid) == -1) {
error("%s: initgroups(%s, %u): %s", tag,
pw->pw_name, (u_int)pw->pw_gid, strerror(errno));
_exit(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;
}
const char *
lookup_setenv_in_list(const char *env, char * const *envs, size_t nenvs)
{
char *name, *cp;
const char *ret;
name = xstrdup(env);
if ((cp = strchr(name, '=')) == NULL) {
free(name);
return NULL; /* not env=val */
}
*cp = '\0';
ret = lookup_env_in_list(name, envs, nenvs);
free(name);
return ret;
}
+
+/*
+ * Helpers for managing poll(2)/ppoll(2) timeouts
+ * Will remember the earliest deadline and return it for use in poll/ppoll.
+ */
+
+/* Initialise a poll/ppoll timeout with an indefinite deadline */
+void
+ptimeout_init(struct timespec *pt)
+{
+ /*
+ * Deliberately invalid for ppoll(2).
+ * Will be converted to NULL in ptimeout_get_tspec() later.
+ */
+ pt->tv_sec = -1;
+ pt->tv_nsec = 0;
+}
+
+/* Specify a poll/ppoll deadline of at most 'sec' seconds */
+void
+ptimeout_deadline_sec(struct timespec *pt, long sec)
+{
+ if (pt->tv_sec == -1 || pt->tv_sec >= sec) {
+ pt->tv_sec = sec;
+ pt->tv_nsec = 0;
+ }
+}
+
+/* Specify a poll/ppoll deadline of at most 'p' (timespec) */
+static void
+ptimeout_deadline_tsp(struct timespec *pt, struct timespec *p)
+{
+ if (pt->tv_sec == -1 || timespeccmp(pt, p, >=))
+ *pt = *p;
+}
+
+/* Specify a poll/ppoll deadline of at most 'ms' milliseconds */
+void
+ptimeout_deadline_ms(struct timespec *pt, long ms)
+{
+ struct timespec p;
+
+ p.tv_sec = ms / 1000;
+ p.tv_nsec = (ms % 1000) * 1000000;
+ ptimeout_deadline_tsp(pt, &p);
+}
+
+/* Specify a poll/ppoll deadline at wall clock monotime 'when' */
+void
+ptimeout_deadline_monotime(struct timespec *pt, time_t when)
+{
+ struct timespec now, t;
+
+ t.tv_sec = when;
+ t.tv_nsec = 0;
+ monotime_ts(&now);
+
+ if (timespeccmp(&now, &t, >=))
+ ptimeout_deadline_sec(pt, 0);
+ else {
+ timespecsub(&t, &now, &t);
+ ptimeout_deadline_tsp(pt, &t);
+ }
+}
+
+/* Get a poll(2) timeout value in milliseconds */
+int
+ptimeout_get_ms(struct timespec *pt)
+{
+ if (pt->tv_sec == -1)
+ return -1;
+ if (pt->tv_sec >= (INT_MAX - (pt->tv_nsec / 1000000)) / 1000)
+ return INT_MAX;
+ return (pt->tv_sec * 1000) + (pt->tv_nsec / 1000000);
+}
+
+/* Get a ppoll(2) timeout value as a timespec pointer */
+struct timespec *
+ptimeout_get_tsp(struct timespec *pt)
+{
+ return pt->tv_sec == -1 ? NULL : pt;
+}
+
+/* Returns non-zero if a timeout has been set (i.e. is not indefinite) */
+int
+ptimeout_isset(struct timespec *pt)
+{
+ return pt->tv_sec != -1;
+}
diff --git a/crypto/openssh/misc.h b/crypto/openssh/misc.h
index 7ef75bd0929c..84d93e059ea9 100644
--- a/crypto/openssh/misc.h
+++ b/crypto/openssh/misc.h
@@ -1,234 +1,243 @@
-/* $OpenBSD: misc.h,v 1.100 2022/06/03 04:30:47 djm Exp $ */
+/* $OpenBSD: misc.h,v 1.101 2023/01/06 02:37:04 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
*
* As far as I am concerned, the code I have written for this software
* can be used freely for any purpose. Any derived versions of this
* software must be clearly marked as such, and if the derived work is
* incompatible with the protocol description in the RFC file, it must be
* called by a name other than "ssh" or "Secure Shell".
*/
#ifndef _MISC_H
#define _MISC_H
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
/* Data structure for representing a forwarding request. */
struct Forward {
char *listen_host; /* Host (address) to listen on. */
int listen_port; /* Port to forward. */
char *listen_path; /* Path to bind domain socket. */
char *connect_host; /* Host to connect. */
int connect_port; /* Port to connect on connect_host. */
char *connect_path; /* Path to connect domain socket. */
int allocated_port; /* Dynamically allocated listen port */
int handle; /* Handle for dynamic listen ports */
};
int forward_equals(const struct Forward *, const struct Forward *);
int daemonized(void);
/* Common server and client forwarding options. */
struct ForwardOptions {
int gateway_ports; /* Allow remote connects to forwarded ports. */
mode_t streamlocal_bind_mask; /* umask for streamlocal binds */
int streamlocal_bind_unlink; /* unlink socket before bind */
};
/* misc.c */
char *chop(char *);
void rtrim(char *);
void skip_space(char **);
char *strdelim(char **);
char *strdelimw(char **);
int set_nonblock(int);
int unset_nonblock(int);
void set_nodelay(int);
int set_reuseaddr(int);
char *get_rdomain(int);
int set_rdomain(int, const char *);
int get_sock_af(int);
void set_sock_tos(int, int);
int waitrfd(int, int *);
int timeout_connect(int, const struct sockaddr *, socklen_t, int *);
int a2port(const char *);
int a2tun(const char *, int *);
char *put_host_port(const char *, u_short);
char *hpdelim2(char **, char *);
char *hpdelim(char **);
char *cleanhostname(char *);
char *colon(char *);
int parse_user_host_path(const char *, char **, char **, char **);
int parse_user_host_port(const char *, char **, char **, int *);
int parse_uri(const char *, const char *, char **, char **, int *, char **);
int convtime(const char *);
const char *fmt_timeframe(time_t t);
int tilde_expand(const char *, uid_t, char **);
char *tilde_expand_filename(const char *, uid_t);
char *dollar_expand(int *, const char *string, ...);
char *percent_expand(const char *, ...) __attribute__((__sentinel__));
char *percent_dollar_expand(const char *, ...) __attribute__((__sentinel__));
char *tohex(const void *, size_t);
void xextendf(char **s, const char *sep, const char *fmt, ...)
__attribute__((__format__ (printf, 3, 4))) __attribute__((__nonnull__ (3)));
void sanitise_stdfd(void);
void ms_subtract_diff(struct timeval *, int *);
void ms_to_timespec(struct timespec *, int);
void monotime_ts(struct timespec *);
void monotime_tv(struct timeval *);
time_t monotime(void);
double monotime_double(void);
void lowercase(char *s);
int unix_listener(const char *, int, int);
int valid_domain(char *, int, const char **);
int valid_env_name(const char *);
const char *atoi_err(const char *, int *);
int parse_absolute_time(const char *, uint64_t *);
void format_absolute_time(uint64_t, char *, size_t);
int path_absolute(const char *);
int stdfd_devnull(int, int, int);
void sock_set_v6only(int);
struct passwd *pwcopy(struct passwd *);
const char *ssh_gai_strerror(int);
typedef void privdrop_fn(struct passwd *);
typedef void privrestore_fn(void);
#define SSH_SUBPROCESS_STDOUT_DISCARD (1) /* Discard stdout */
#define SSH_SUBPROCESS_STDOUT_CAPTURE (1<<1) /* Redirect stdout */
#define SSH_SUBPROCESS_STDERR_DISCARD (1<<2) /* Discard stderr */
#define SSH_SUBPROCESS_UNSAFE_PATH (1<<3) /* Don't check for safe cmd */
#define SSH_SUBPROCESS_PRESERVE_ENV (1<<4) /* Keep parent environment */
pid_t subprocess(const char *, const char *, int, char **, FILE **, u_int,
struct passwd *, privdrop_fn *, privrestore_fn *);
typedef struct arglist arglist;
struct arglist {
char **list;
u_int num;
u_int nalloc;
};
void addargs(arglist *, char *, ...)
__attribute__((format(printf, 2, 3)));
void replacearg(arglist *, u_int, char *, ...)
__attribute__((format(printf, 3, 4)));
void freeargs(arglist *);
int tun_open(int, int, char **);
/* Common definitions for ssh tunnel device forwarding */
#define SSH_TUNMODE_NO 0x00
#define SSH_TUNMODE_POINTOPOINT 0x01
#define SSH_TUNMODE_ETHERNET 0x02
#define SSH_TUNMODE_DEFAULT SSH_TUNMODE_POINTOPOINT
#define SSH_TUNMODE_YES (SSH_TUNMODE_POINTOPOINT|SSH_TUNMODE_ETHERNET)
#define SSH_TUNID_ANY 0x7fffffff
#define SSH_TUNID_ERR (SSH_TUNID_ANY - 1)
#define SSH_TUNID_MAX (SSH_TUNID_ANY - 2)
/* Fake port to indicate that host field is really a path. */
#define PORT_STREAMLOCAL -2
/* Functions to extract or store big-endian words of various sizes */
u_int64_t get_u64(const void *)
__attribute__((__bounded__( __minbytes__, 1, 8)));
u_int32_t get_u32(const void *)
__attribute__((__bounded__( __minbytes__, 1, 4)));
u_int16_t get_u16(const void *)
__attribute__((__bounded__( __minbytes__, 1, 2)));
void put_u64(void *, u_int64_t)
__attribute__((__bounded__( __minbytes__, 1, 8)));
void put_u32(void *, u_int32_t)
__attribute__((__bounded__( __minbytes__, 1, 4)));
void put_u16(void *, u_int16_t)
__attribute__((__bounded__( __minbytes__, 1, 2)));
/* Little-endian store/load, used by umac.c */
u_int32_t get_u32_le(const void *)
__attribute__((__bounded__(__minbytes__, 1, 4)));
void put_u32_le(void *, u_int32_t)
__attribute__((__bounded__(__minbytes__, 1, 4)));
struct bwlimit {
size_t buflen;
u_int64_t rate; /* desired rate in kbit/s */
u_int64_t thresh; /* threshold after which we'll check timers */
u_int64_t lamt; /* amount written in last timer interval */
struct timeval bwstart, bwend;
};
void bandwidth_limit_init(struct bwlimit *, u_int64_t, size_t);
void bandwidth_limit(struct bwlimit *, size_t);
int parse_ipqos(const char *);
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 *lookup_env_in_list(const char *env,
char * const *envs, size_t nenvs);
const char *lookup_setenv_in_list(const char *env,
char * const *envs, size_t nenvs);
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);
int safe_path_fd(int, const char *, struct passwd *,
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);
+struct timespec;
+void ptimeout_init(struct timespec *pt);
+void ptimeout_deadline_sec(struct timespec *pt, long sec);
+void ptimeout_deadline_ms(struct timespec *pt, long ms);
+void ptimeout_deadline_monotime(struct timespec *pt, time_t when);
+int ptimeout_get_ms(struct timespec *pt);
+struct timespec *ptimeout_get_tsp(struct timespec *pt);
+int ptimeout_isset(struct timespec *pt);
+
/* readpass.c */
#define RP_ECHO 0x0001
#define RP_ALLOW_STDIN 0x0002
#define RP_ALLOW_EOF 0x0004
#define RP_USE_ASKPASS 0x0008
struct notifier_ctx;
char *read_passphrase(const char *, int);
int ask_permission(const char *, ...) __attribute__((format(printf, 1, 2)));
struct notifier_ctx *notify_start(int, const char *, ...)
__attribute__((format(printf, 2, 3)));
void notify_complete(struct notifier_ctx *, const char *, ...)
__attribute__((format(printf, 2, 3)));
#define MINIMUM(a, b) (((a) < (b)) ? (a) : (b))
#define MAXIMUM(a, b) (((a) > (b)) ? (a) : (b))
#define ROUNDUP(x, y) ((((x)+((y)-1))/(y))*(y))
typedef void (*sshsig_t)(int);
sshsig_t ssh_signal(int, sshsig_t);
#endif /* _MISC_H */
diff --git a/crypto/openssh/moduli b/crypto/openssh/moduli
index c580e1773469..099fc4263da9 100644
--- a/crypto/openssh/moduli
+++ b/crypto/openssh/moduli
@@ -1,420 +1,425 @@
-# $OpenBSD: moduli,v 1.32 2022/04/20 01:13:47 dtucker Exp $
+# $OpenBSD: moduli,v 1.33 2022/11/07 02:21:21 dtucker Exp $
# Time Type Tests Tries Size Generator Modulus
-20220414072358 2 6 100 2047 5 F19C2D09AD49978F8A0C1B84168A4011A26F9CD516815934764A319FDC5975FA514AAF11B747D8CA6B3919532BEFB68FA118079473895674F3770F71FBB742F176883841EB3DE679BEF53C6AFE437A662F228B03C1E34B5A0D3909F608CEAA16C1F8131DE11E67878EFD918A89205E5E4DE323054010CA4711F25D466BB7727A016DD3F9F53BDBCE093055A4F2497ADEFB5A2500F9C5C3B0BCD88C6489F4C1CBC7CFB67BA6EABA0195794E4188CE9060F431041AD52FB9BAC4DF7FA536F585FBE67746CD57BFAD67567E9706C24D95C49BE95B759657C6BB5151E2AEA32F4CD557C40298A5C402101520EE8AAB8DFEED6FFC11AAF8036D6345923CFB5D1B922F
-20220414072402 2 6 100 2047 2 F19C2D09AD49978F8A0C1B84168A4011A26F9CD516815934764A319FDC5975FA514AAF11B747D8CA6B3919532BEFB68FA118079473895674F3770F71FBB742F176883841EB3DE679BEF53C6AFE437A662F228B03C1E34B5A0D3909F608CEAA16C1F8131DE11E67878EFD918A89205E5E4DE323054010CA4711F25D466BB7727A016DD3F9F53BDBCE093055A4F2497ADEFB5A2500F9C5C3B0BCD88C6489F4C1CBC7CFB67BA6EABA0195794E4188CE9060F431041AD52FB9BAC4DF7FA536F585FBE67746CD57BFAD67567E9706C24D95C49BE95B759657C6BB5151E2AEA32F4CD557C40298A5C402101520EE8AAB8DFEED6FFC11AAF8036D6345923CFB5D3FAAB3
-20220414072411 2 6 100 2047 5 F19C2D09AD49978F8A0C1B84168A4011A26F9CD516815934764A319FDC5975FA514AAF11B747D8CA6B3919532BEFB68FA118079473895674F3770F71FBB742F176883841EB3DE679BEF53C6AFE437A662F228B03C1E34B5A0D3909F608CEAA16C1F8131DE11E67878EFD918A89205E5E4DE323054010CA4711F25D466BB7727A016DD3F9F53BDBCE093055A4F2497ADEFB5A2500F9C5C3B0BCD88C6489F4C1CBC7CFB67BA6EABA0195794E4188CE9060F431041AD52FB9BAC4DF7FA536F585FBE67746CD57BFAD67567E9706C24D95C49BE95B759657C6BB5151E2AEA32F4CD557C40298A5C402101520EE8AAB8DFEED6FFC11AAF8036D6345923CFB5DA6E2EF
-20220414072429 2 6 100 2047 5 F19C2D09AD49978F8A0C1B84168A4011A26F9CD516815934764A319FDC5975FA514AAF11B747D8CA6B3919532BEFB68FA118079473895674F3770F71FBB742F176883841EB3DE679BEF53C6AFE437A662F228B03C1E34B5A0D3909F608CEAA16C1F8131DE11E67878EFD918A89205E5E4DE323054010CA4711F25D466BB7727A016DD3F9F53BDBCE093055A4F2497ADEFB5A2500F9C5C3B0BCD88C6489F4C1CBC7CFB67BA6EABA0195794E4188CE9060F431041AD52FB9BAC4DF7FA536F585FBE67746CD57BFAD67567E9706C24D95C49BE95B759657C6BB5151E2AEA32F4CD557C40298A5C402101520EE8AAB8DFEED6FFC11AAF8036D6345923CFB5E5C2677
-20220414072430 2 6 100 2047 5 F19C2D09AD49978F8A0C1B84168A4011A26F9CD516815934764A319FDC5975FA514AAF11B747D8CA6B3919532BEFB68FA118079473895674F3770F71FBB742F176883841EB3DE679BEF53C6AFE437A662F228B03C1E34B5A0D3909F608CEAA16C1F8131DE11E67878EFD918A89205E5E4DE323054010CA4711F25D466BB7727A016DD3F9F53BDBCE093055A4F2497ADEFB5A2500F9C5C3B0BCD88C6489F4C1CBC7CFB67BA6EABA0195794E4188CE9060F431041AD52FB9BAC4DF7FA536F585FBE67746CD57BFAD67567E9706C24D95C49BE95B759657C6BB5151E2AEA32F4CD557C40298A5C402101520EE8AAB8DFEED6FFC11AAF8036D6345923CFB5E5C4C6F
-20220414072435 2 6 100 2047 2 F19C2D09AD49978F8A0C1B84168A4011A26F9CD516815934764A319FDC5975FA514AAF11B747D8CA6B3919532BEFB68FA118079473895674F3770F71FBB742F176883841EB3DE679BEF53C6AFE437A662F228B03C1E34B5A0D3909F608CEAA16C1F8131DE11E67878EFD918A89205E5E4DE323054010CA4711F25D466BB7727A016DD3F9F53BDBCE093055A4F2497ADEFB5A2500F9C5C3B0BCD88C6489F4C1CBC7CFB67BA6EABA0195794E4188CE9060F431041AD52FB9BAC4DF7FA536F585FBE67746CD57BFAD67567E9706C24D95C49BE95B759657C6BB5151E2AEA32F4CD557C40298A5C402101520EE8AAB8DFEED6FFC11AAF8036D6345923CFB5E8EADAB
-20220414072436 2 6 100 2047 5 F19C2D09AD49978F8A0C1B84168A4011A26F9CD516815934764A319FDC5975FA514AAF11B747D8CA6B3919532BEFB68FA118079473895674F3770F71FBB742F176883841EB3DE679BEF53C6AFE437A662F228B03C1E34B5A0D3909F608CEAA16C1F8131DE11E67878EFD918A89205E5E4DE323054010CA4711F25D466BB7727A016DD3F9F53BDBCE093055A4F2497ADEFB5A2500F9C5C3B0BCD88C6489F4C1CBC7CFB67BA6EABA0195794E4188CE9060F431041AD52FB9BAC4DF7FA536F585FBE67746CD57BFAD67567E9706C24D95C49BE95B759657C6BB5151E2AEA32F4CD557C40298A5C402101520EE8AAB8DFEED6FFC11AAF8036D6345923CFB5E9B7C6F
-20220414072440 2 6 100 2047 2 F19C2D09AD49978F8A0C1B84168A4011A26F9CD516815934764A319FDC5975FA514AAF11B747D8CA6B3919532BEFB68FA118079473895674F3770F71FBB742F176883841EB3DE679BEF53C6AFE437A662F228B03C1E34B5A0D3909F608CEAA16C1F8131DE11E67878EFD918A89205E5E4DE323054010CA4711F25D466BB7727A016DD3F9F53BDBCE093055A4F2497ADEFB5A2500F9C5C3B0BCD88C6489F4C1CBC7CFB67BA6EABA0195794E4188CE9060F431041AD52FB9BAC4DF7FA536F585FBE67746CD57BFAD67567E9706C24D95C49BE95B759657C6BB5151E2AEA32F4CD557C40298A5C402101520EE8AAB8DFEED6FFC11AAF8036D6345923CFB5EBA84AB
-20220414072442 2 6 100 2047 2 F19C2D09AD49978F8A0C1B84168A4011A26F9CD516815934764A319FDC5975FA514AAF11B747D8CA6B3919532BEFB68FA118079473895674F3770F71FBB742F176883841EB3DE679BEF53C6AFE437A662F228B03C1E34B5A0D3909F608CEAA16C1F8131DE11E67878EFD918A89205E5E4DE323054010CA4711F25D466BB7727A016DD3F9F53BDBCE093055A4F2497ADEFB5A2500F9C5C3B0BCD88C6489F4C1CBC7CFB67BA6EABA0195794E4188CE9060F431041AD52FB9BAC4DF7FA536F585FBE67746CD57BFAD67567E9706C24D95C49BE95B759657C6BB5151E2AEA32F4CD557C40298A5C402101520EE8AAB8DFEED6FFC11AAF8036D6345923CFB5ECDB22B
-20220414072457 2 6 100 2047 2 F19C2D09AD49978F8A0C1B84168A4011A26F9CD516815934764A319FDC5975FA514AAF11B747D8CA6B3919532BEFB68FA118079473895674F3770F71FBB742F176883841EB3DE679BEF53C6AFE437A662F228B03C1E34B5A0D3909F608CEAA16C1F8131DE11E67878EFD918A89205E5E4DE323054010CA4711F25D466BB7727A016DD3F9F53BDBCE093055A4F2497ADEFB5A2500F9C5C3B0BCD88C6489F4C1CBC7CFB67BA6EABA0195794E4188CE9060F431041AD52FB9BAC4DF7FA536F585FBE67746CD57BFAD67567E9706C24D95C49BE95B759657C6BB5151E2AEA32F4CD557C40298A5C402101520EE8AAB8DFEED6FFC11AAF8036D6345923CFB5F71BAC3
-20220414072517 2 6 100 2047 5 F19C2D09AD49978F8A0C1B84168A4011A26F9CD516815934764A319FDC5975FA514AAF11B747D8CA6B3919532BEFB68FA118079473895674F3770F71FBB742F176883841EB3DE679BEF53C6AFE437A662F228B03C1E34B5A0D3909F608CEAA16C1F8131DE11E67878EFD918A89205E5E4DE323054010CA4711F25D466BB7727A016DD3F9F53BDBCE093055A4F2497ADEFB5A2500F9C5C3B0BCD88C6489F4C1CBC7CFB67BA6EABA0195794E4188CE9060F431041AD52FB9BAC4DF7FA536F585FBE67746CD57BFAD67567E9706C24D95C49BE95B759657C6BB5151E2AEA32F4CD557C40298A5C402101520EE8AAB8DFEED6FFC11AAF8036D6345923CFB6044356F
-20220414072521 2 6 100 2047 5 F19C2D09AD49978F8A0C1B84168A4011A26F9CD516815934764A319FDC5975FA514AAF11B747D8CA6B3919532BEFB68FA118079473895674F3770F71FBB742F176883841EB3DE679BEF53C6AFE437A662F228B03C1E34B5A0D3909F608CEAA16C1F8131DE11E67878EFD918A89205E5E4DE323054010CA4711F25D466BB7727A016DD3F9F53BDBCE093055A4F2497ADEFB5A2500F9C5C3B0BCD88C6489F4C1CBC7CFB67BA6EABA0195794E4188CE9060F431041AD52FB9BAC4DF7FA536F585FBE67746CD57BFAD67567E9706C24D95C49BE95B759657C6BB5151E2AEA32F4CD557C40298A5C402101520EE8AAB8DFEED6FFC11AAF8036D6345923CFB60678097
-20220414072523 2 6 100 2047 5 F19C2D09AD49978F8A0C1B84168A4011A26F9CD516815934764A319FDC5975FA514AAF11B747D8CA6B3919532BEFB68FA118079473895674F3770F71FBB742F176883841EB3DE679BEF53C6AFE437A662F228B03C1E34B5A0D3909F608CEAA16C1F8131DE11E67878EFD918A89205E5E4DE323054010CA4711F25D466BB7727A016DD3F9F53BDBCE093055A4F2497ADEFB5A2500F9C5C3B0BCD88C6489F4C1CBC7CFB67BA6EABA0195794E4188CE9060F431041AD52FB9BAC4DF7FA536F585FBE67746CD57BFAD67567E9706C24D95C49BE95B759657C6BB5151E2AEA32F4CD557C40298A5C402101520EE8AAB8DFEED6FFC11AAF8036D6345923CFB607297CF
-20220414072528 2 6 100 2047 5 F19C2D09AD49978F8A0C1B84168A4011A26F9CD516815934764A319FDC5975FA514AAF11B747D8CA6B3919532BEFB68FA118079473895674F3770F71FBB742F176883841EB3DE679BEF53C6AFE437A662F228B03C1E34B5A0D3909F608CEAA16C1F8131DE11E67878EFD918A89205E5E4DE323054010CA4711F25D466BB7727A016DD3F9F53BDBCE093055A4F2497ADEFB5A2500F9C5C3B0BCD88C6489F4C1CBC7CFB67BA6EABA0195794E4188CE9060F431041AD52FB9BAC4DF7FA536F585FBE67746CD57BFAD67567E9706C24D95C49BE95B759657C6BB5151E2AEA32F4CD557C40298A5C402101520EE8AAB8DFEED6FFC11AAF8036D6345923CFB60A2A627
-20220414072529 2 6 100 2047 5 F19C2D09AD49978F8A0C1B84168A4011A26F9CD516815934764A319FDC5975FA514AAF11B747D8CA6B3919532BEFB68FA118079473895674F3770F71FBB742F176883841EB3DE679BEF53C6AFE437A662F228B03C1E34B5A0D3909F608CEAA16C1F8131DE11E67878EFD918A89205E5E4DE323054010CA4711F25D466BB7727A016DD3F9F53BDBCE093055A4F2497ADEFB5A2500F9C5C3B0BCD88C6489F4C1CBC7CFB67BA6EABA0195794E4188CE9060F431041AD52FB9BAC4DF7FA536F585FBE67746CD57BFAD67567E9706C24D95C49BE95B759657C6BB5151E2AEA32F4CD557C40298A5C402101520EE8AAB8DFEED6FFC11AAF8036D6345923CFB60AAC38F
-20220414072533 2 6 100 2047 5 F19C2D09AD49978F8A0C1B84168A4011A26F9CD516815934764A319FDC5975FA514AAF11B747D8CA6B3919532BEFB68FA118079473895674F3770F71FBB742F176883841EB3DE679BEF53C6AFE437A662F228B03C1E34B5A0D3909F608CEAA16C1F8131DE11E67878EFD918A89205E5E4DE323054010CA4711F25D466BB7727A016DD3F9F53BDBCE093055A4F2497ADEFB5A2500F9C5C3B0BCD88C6489F4C1CBC7CFB67BA6EABA0195794E4188CE9060F431041AD52FB9BAC4DF7FA536F585FBE67746CD57BFAD67567E9706C24D95C49BE95B759657C6BB5151E2AEA32F4CD557C40298A5C402101520EE8AAB8DFEED6FFC11AAF8036D6345923CFB60CD7B87
-20220414072538 2 6 100 2047 2 F19C2D09AD49978F8A0C1B84168A4011A26F9CD516815934764A319FDC5975FA514AAF11B747D8CA6B3919532BEFB68FA118079473895674F3770F71FBB742F176883841EB3DE679BEF53C6AFE437A662F228B03C1E34B5A0D3909F608CEAA16C1F8131DE11E67878EFD918A89205E5E4DE323054010CA4711F25D466BB7727A016DD3F9F53BDBCE093055A4F2497ADEFB5A2500F9C5C3B0BCD88C6489F4C1CBC7CFB67BA6EABA0195794E4188CE9060F431041AD52FB9BAC4DF7FA536F585FBE67746CD57BFAD67567E9706C24D95C49BE95B759657C6BB5151E2AEA32F4CD557C40298A5C402101520EE8AAB8DFEED6FFC11AAF8036D6345923CFB60F9FD4B
-20220414072540 2 6 100 2047 5 F19C2D09AD49978F8A0C1B84168A4011A26F9CD516815934764A319FDC5975FA514AAF11B747D8CA6B3919532BEFB68FA118079473895674F3770F71FBB742F176883841EB3DE679BEF53C6AFE437A662F228B03C1E34B5A0D3909F608CEAA16C1F8131DE11E67878EFD918A89205E5E4DE323054010CA4711F25D466BB7727A016DD3F9F53BDBCE093055A4F2497ADEFB5A2500F9C5C3B0BCD88C6489F4C1CBC7CFB67BA6EABA0195794E4188CE9060F431041AD52FB9BAC4DF7FA536F585FBE67746CD57BFAD67567E9706C24D95C49BE95B759657C6BB5151E2AEA32F4CD557C40298A5C402101520EE8AAB8DFEED6FFC11AAF8036D6345923CFB6103C8C7
-20220414072545 2 6 100 2047 5 F19C2D09AD49978F8A0C1B84168A4011A26F9CD516815934764A319FDC5975FA514AAF11B747D8CA6B3919532BEFB68FA118079473895674F3770F71FBB742F176883841EB3DE679BEF53C6AFE437A662F228B03C1E34B5A0D3909F608CEAA16C1F8131DE11E67878EFD918A89205E5E4DE323054010CA4711F25D466BB7727A016DD3F9F53BDBCE093055A4F2497ADEFB5A2500F9C5C3B0BCD88C6489F4C1CBC7CFB67BA6EABA0195794E4188CE9060F431041AD52FB9BAC4DF7FA536F585FBE67746CD57BFAD67567E9706C24D95C49BE95B759657C6BB5151E2AEA32F4CD557C40298A5C402101520EE8AAB8DFEED6FFC11AAF8036D6345923CFB612FA3CF
-20220414072547 2 6 100 2047 5 F19C2D09AD49978F8A0C1B84168A4011A26F9CD516815934764A319FDC5975FA514AAF11B747D8CA6B3919532BEFB68FA118079473895674F3770F71FBB742F176883841EB3DE679BEF53C6AFE437A662F228B03C1E34B5A0D3909F608CEAA16C1F8131DE11E67878EFD918A89205E5E4DE323054010CA4711F25D466BB7727A016DD3F9F53BDBCE093055A4F2497ADEFB5A2500F9C5C3B0BCD88C6489F4C1CBC7CFB67BA6EABA0195794E4188CE9060F431041AD52FB9BAC4DF7FA536F585FBE67746CD57BFAD67567E9706C24D95C49BE95B759657C6BB5151E2AEA32F4CD557C40298A5C402101520EE8AAB8DFEED6FFC11AAF8036D6345923CFB6139A9BF
-20220414072548 2 6 100 2047 5 F19C2D09AD49978F8A0C1B84168A4011A26F9CD516815934764A319FDC5975FA514AAF11B747D8CA6B3919532BEFB68FA118079473895674F3770F71FBB742F176883841EB3DE679BEF53C6AFE437A662F228B03C1E34B5A0D3909F608CEAA16C1F8131DE11E67878EFD918A89205E5E4DE323054010CA4711F25D466BB7727A016DD3F9F53BDBCE093055A4F2497ADEFB5A2500F9C5C3B0BCD88C6489F4C1CBC7CFB67BA6EABA0195794E4188CE9060F431041AD52FB9BAC4DF7FA536F585FBE67746CD57BFAD67567E9706C24D95C49BE95B759657C6BB5151E2AEA32F4CD557C40298A5C402101520EE8AAB8DFEED6FFC11AAF8036D6345923CFB613E9CC7
-20220414072553 2 6 100 2047 2 F19C2D09AD49978F8A0C1B84168A4011A26F9CD516815934764A319FDC5975FA514AAF11B747D8CA6B3919532BEFB68FA118079473895674F3770F71FBB742F176883841EB3DE679BEF53C6AFE437A662F228B03C1E34B5A0D3909F608CEAA16C1F8131DE11E67878EFD918A89205E5E4DE323054010CA4711F25D466BB7727A016DD3F9F53BDBCE093055A4F2497ADEFB5A2500F9C5C3B0BCD88C6489F4C1CBC7CFB67BA6EABA0195794E4188CE9060F431041AD52FB9BAC4DF7FA536F585FBE67746CD57BFAD67567E9706C24D95C49BE95B759657C6BB5151E2AEA32F4CD557C40298A5C402101520EE8AAB8DFEED6FFC11AAF8036D6345923CFB6171EBF3
-20220414072601 2 6 100 2047 2 F19C2D09AD49978F8A0C1B84168A4011A26F9CD516815934764A319FDC5975FA514AAF11B747D8CA6B3919532BEFB68FA118079473895674F3770F71FBB742F176883841EB3DE679BEF53C6AFE437A662F228B03C1E34B5A0D3909F608CEAA16C1F8131DE11E67878EFD918A89205E5E4DE323054010CA4711F25D466BB7727A016DD3F9F53BDBCE093055A4F2497ADEFB5A2500F9C5C3B0BCD88C6489F4C1CBC7CFB67BA6EABA0195794E4188CE9060F431041AD52FB9BAC4DF7FA536F585FBE67746CD57BFAD67567E9706C24D95C49BE95B759657C6BB5151E2AEA32F4CD557C40298A5C402101520EE8AAB8DFEED6FFC11AAF8036D6345923CFB61BAEA33
-20220414072603 2 6 100 2047 5 F19C2D09AD49978F8A0C1B84168A4011A26F9CD516815934764A319FDC5975FA514AAF11B747D8CA6B3919532BEFB68FA118079473895674F3770F71FBB742F176883841EB3DE679BEF53C6AFE437A662F228B03C1E34B5A0D3909F608CEAA16C1F8131DE11E67878EFD918A89205E5E4DE323054010CA4711F25D466BB7727A016DD3F9F53BDBCE093055A4F2497ADEFB5A2500F9C5C3B0BCD88C6489F4C1CBC7CFB67BA6EABA0195794E4188CE9060F431041AD52FB9BAC4DF7FA536F585FBE67746CD57BFAD67567E9706C24D95C49BE95B759657C6BB5151E2AEA32F4CD557C40298A5C402101520EE8AAB8DFEED6FFC11AAF8036D6345923CFB61CF5307
-20220414072606 2 6 100 2047 5 F19C2D09AD49978F8A0C1B84168A4011A26F9CD516815934764A319FDC5975FA514AAF11B747D8CA6B3919532BEFB68FA118079473895674F3770F71FBB742F176883841EB3DE679BEF53C6AFE437A662F228B03C1E34B5A0D3909F608CEAA16C1F8131DE11E67878EFD918A89205E5E4DE323054010CA4711F25D466BB7727A016DD3F9F53BDBCE093055A4F2497ADEFB5A2500F9C5C3B0BCD88C6489F4C1CBC7CFB67BA6EABA0195794E4188CE9060F431041AD52FB9BAC4DF7FA536F585FBE67746CD57BFAD67567E9706C24D95C49BE95B759657C6BB5151E2AEA32F4CD557C40298A5C402101520EE8AAB8DFEED6FFC11AAF8036D6345923CFB61E8149F
-20220414072607 2 6 100 2047 5 F19C2D09AD49978F8A0C1B84168A4011A26F9CD516815934764A319FDC5975FA514AAF11B747D8CA6B3919532BEFB68FA118079473895674F3770F71FBB742F176883841EB3DE679BEF53C6AFE437A662F228B03C1E34B5A0D3909F608CEAA16C1F8131DE11E67878EFD918A89205E5E4DE323054010CA4711F25D466BB7727A016DD3F9F53BDBCE093055A4F2497ADEFB5A2500F9C5C3B0BCD88C6489F4C1CBC7CFB67BA6EABA0195794E4188CE9060F431041AD52FB9BAC4DF7FA536F585FBE67746CD57BFAD67567E9706C24D95C49BE95B759657C6BB5151E2AEA32F4CD557C40298A5C402101520EE8AAB8DFEED6FFC11AAF8036D6345923CFB61EB7577
-20220414072607 2 6 100 2047 2 F19C2D09AD49978F8A0C1B84168A4011A26F9CD516815934764A319FDC5975FA514AAF11B747D8CA6B3919532BEFB68FA118079473895674F3770F71FBB742F176883841EB3DE679BEF53C6AFE437A662F228B03C1E34B5A0D3909F608CEAA16C1F8131DE11E67878EFD918A89205E5E4DE323054010CA4711F25D466BB7727A016DD3F9F53BDBCE093055A4F2497ADEFB5A2500F9C5C3B0BCD88C6489F4C1CBC7CFB67BA6EABA0195794E4188CE9060F431041AD52FB9BAC4DF7FA536F585FBE67746CD57BFAD67567E9706C24D95C49BE95B759657C6BB5151E2AEA32F4CD557C40298A5C402101520EE8AAB8DFEED6FFC11AAF8036D6345923CFB61ED0BA3
-20220414072611 2 6 100 2047 2 F19C2D09AD49978F8A0C1B84168A4011A26F9CD516815934764A319FDC5975FA514AAF11B747D8CA6B3919532BEFB68FA118079473895674F3770F71FBB742F176883841EB3DE679BEF53C6AFE437A662F228B03C1E34B5A0D3909F608CEAA16C1F8131DE11E67878EFD918A89205E5E4DE323054010CA4711F25D466BB7727A016DD3F9F53BDBCE093055A4F2497ADEFB5A2500F9C5C3B0BCD88C6489F4C1CBC7CFB67BA6EABA0195794E4188CE9060F431041AD52FB9BAC4DF7FA536F585FBE67746CD57BFAD67567E9706C24D95C49BE95B759657C6BB5151E2AEA32F4CD557C40298A5C402101520EE8AAB8DFEED6FFC11AAF8036D6345923CFB620FE4E3
-20220414072615 2 6 100 2047 2 F19C2D09AD49978F8A0C1B84168A4011A26F9CD516815934764A319FDC5975FA514AAF11B747D8CA6B3919532BEFB68FA118079473895674F3770F71FBB742F176883841EB3DE679BEF53C6AFE437A662F228B03C1E34B5A0D3909F608CEAA16C1F8131DE11E67878EFD918A89205E5E4DE323054010CA4711F25D466BB7727A016DD3F9F53BDBCE093055A4F2497ADEFB5A2500F9C5C3B0BCD88C6489F4C1CBC7CFB67BA6EABA0195794E4188CE9060F431041AD52FB9BAC4DF7FA536F585FBE67746CD57BFAD67567E9706C24D95C49BE95B759657C6BB5151E2AEA32F4CD557C40298A5C402101520EE8AAB8DFEED6FFC11AAF8036D6345923CFB622D2F63
-20220414072616 2 6 100 2047 2 F19C2D09AD49978F8A0C1B84168A4011A26F9CD516815934764A319FDC5975FA514AAF11B747D8CA6B3919532BEFB68FA118079473895674F3770F71FBB742F176883841EB3DE679BEF53C6AFE437A662F228B03C1E34B5A0D3909F608CEAA16C1F8131DE11E67878EFD918A89205E5E4DE323054010CA4711F25D466BB7727A016DD3F9F53BDBCE093055A4F2497ADEFB5A2500F9C5C3B0BCD88C6489F4C1CBC7CFB67BA6EABA0195794E4188CE9060F431041AD52FB9BAC4DF7FA536F585FBE67746CD57BFAD67567E9706C24D95C49BE95B759657C6BB5151E2AEA32F4CD557C40298A5C402101520EE8AAB8DFEED6FFC11AAF8036D6345923CFB623847EB
-20220414072628 2 6 100 2047 2 F19C2D09AD49978F8A0C1B84168A4011A26F9CD516815934764A319FDC5975FA514AAF11B747D8CA6B3919532BEFB68FA118079473895674F3770F71FBB742F176883841EB3DE679BEF53C6AFE437A662F228B03C1E34B5A0D3909F608CEAA16C1F8131DE11E67878EFD918A89205E5E4DE323054010CA4711F25D466BB7727A016DD3F9F53BDBCE093055A4F2497ADEFB5A2500F9C5C3B0BCD88C6489F4C1CBC7CFB67BA6EABA0195794E4188CE9060F431041AD52FB9BAC4DF7FA536F585FBE67746CD57BFAD67567E9706C24D95C49BE95B759657C6BB5151E2AEA32F4CD557C40298A5C402101520EE8AAB8DFEED6FFC11AAF8036D6345923CFB62ABB94B
-20220414072638 2 6 100 2047 5 F19C2D09AD49978F8A0C1B84168A4011A26F9CD516815934764A319FDC5975FA514AAF11B747D8CA6B3919532BEFB68FA118079473895674F3770F71FBB742F176883841EB3DE679BEF53C6AFE437A662F228B03C1E34B5A0D3909F608CEAA16C1F8131DE11E67878EFD918A89205E5E4DE323054010CA4711F25D466BB7727A016DD3F9F53BDBCE093055A4F2497ADEFB5A2500F9C5C3B0BCD88C6489F4C1CBC7CFB67BA6EABA0195794E4188CE9060F431041AD52FB9BAC4DF7FA536F585FBE67746CD57BFAD67567E9706C24D95C49BE95B759657C6BB5151E2AEA32F4CD557C40298A5C402101520EE8AAB8DFEED6FFC11AAF8036D6345923CFB6312214F
-20220414072643 2 6 100 2047 2 F19C2D09AD49978F8A0C1B84168A4011A26F9CD516815934764A319FDC5975FA514AAF11B747D8CA6B3919532BEFB68FA118079473895674F3770F71FBB742F176883841EB3DE679BEF53C6AFE437A662F228B03C1E34B5A0D3909F608CEAA16C1F8131DE11E67878EFD918A89205E5E4DE323054010CA4711F25D466BB7727A016DD3F9F53BDBCE093055A4F2497ADEFB5A2500F9C5C3B0BCD88C6489F4C1CBC7CFB67BA6EABA0195794E4188CE9060F431041AD52FB9BAC4DF7FA536F585FBE67746CD57BFAD67567E9706C24D95C49BE95B759657C6BB5151E2AEA32F4CD557C40298A5C402101520EE8AAB8DFEED6FFC11AAF8036D6345923CFB633E1C73
-20220414072647 2 6 100 2047 2 F19C2D09AD49978F8A0C1B84168A4011A26F9CD516815934764A319FDC5975FA514AAF11B747D8CA6B3919532BEFB68FA118079473895674F3770F71FBB742F176883841EB3DE679BEF53C6AFE437A662F228B03C1E34B5A0D3909F608CEAA16C1F8131DE11E67878EFD918A89205E5E4DE323054010CA4711F25D466BB7727A016DD3F9F53BDBCE093055A4F2497ADEFB5A2500F9C5C3B0BCD88C6489F4C1CBC7CFB67BA6EABA0195794E4188CE9060F431041AD52FB9BAC4DF7FA536F585FBE67746CD57BFAD67567E9706C24D95C49BE95B759657C6BB5151E2AEA32F4CD557C40298A5C402101520EE8AAB8DFEED6FFC11AAF8036D6345923CFB63669B3B
-20220414072650 2 6 100 2047 5 F19C2D09AD49978F8A0C1B84168A4011A26F9CD516815934764A319FDC5975FA514AAF11B747D8CA6B3919532BEFB68FA118079473895674F3770F71FBB742F176883841EB3DE679BEF53C6AFE437A662F228B03C1E34B5A0D3909F608CEAA16C1F8131DE11E67878EFD918A89205E5E4DE323054010CA4711F25D466BB7727A016DD3F9F53BDBCE093055A4F2497ADEFB5A2500F9C5C3B0BCD88C6489F4C1CBC7CFB67BA6EABA0195794E4188CE9060F431041AD52FB9BAC4DF7FA536F585FBE67746CD57BFAD67567E9706C24D95C49BE95B759657C6BB5151E2AEA32F4CD557C40298A5C402101520EE8AAB8DFEED6FFC11AAF8036D6345923CFB638220F7
-20220414072653 2 6 100 2047 2 F19C2D09AD49978F8A0C1B84168A4011A26F9CD516815934764A319FDC5975FA514AAF11B747D8CA6B3919532BEFB68FA118079473895674F3770F71FBB742F176883841EB3DE679BEF53C6AFE437A662F228B03C1E34B5A0D3909F608CEAA16C1F8131DE11E67878EFD918A89205E5E4DE323054010CA4711F25D466BB7727A016DD3F9F53BDBCE093055A4F2497ADEFB5A2500F9C5C3B0BCD88C6489F4C1CBC7CFB67BA6EABA0195794E4188CE9060F431041AD52FB9BAC4DF7FA536F585FBE67746CD57BFAD67567E9706C24D95C49BE95B759657C6BB5151E2AEA32F4CD557C40298A5C402101520EE8AAB8DFEED6FFC11AAF8036D6345923CFB6398ADAB
-20220414072654 2 6 100 2047 2 F19C2D09AD49978F8A0C1B84168A4011A26F9CD516815934764A319FDC5975FA514AAF11B747D8CA6B3919532BEFB68FA118079473895674F3770F71FBB742F176883841EB3DE679BEF53C6AFE437A662F228B03C1E34B5A0D3909F608CEAA16C1F8131DE11E67878EFD918A89205E5E4DE323054010CA4711F25D466BB7727A016DD3F9F53BDBCE093055A4F2497ADEFB5A2500F9C5C3B0BCD88C6489F4C1CBC7CFB67BA6EABA0195794E4188CE9060F431041AD52FB9BAC4DF7FA536F585FBE67746CD57BFAD67567E9706C24D95C49BE95B759657C6BB5151E2AEA32F4CD557C40298A5C402101520EE8AAB8DFEED6FFC11AAF8036D6345923CFB639EBE43
-20220414072707 2 6 100 2047 2 F19C2D09AD49978F8A0C1B84168A4011A26F9CD516815934764A319FDC5975FA514AAF11B747D8CA6B3919532BEFB68FA118079473895674F3770F71FBB742F176883841EB3DE679BEF53C6AFE437A662F228B03C1E34B5A0D3909F608CEAA16C1F8131DE11E67878EFD918A89205E5E4DE323054010CA4711F25D466BB7727A016DD3F9F53BDBCE093055A4F2497ADEFB5A2500F9C5C3B0BCD88C6489F4C1CBC7CFB67BA6EABA0195794E4188CE9060F431041AD52FB9BAC4DF7FA536F585FBE67746CD57BFAD67567E9706C24D95C49BE95B759657C6BB5151E2AEA32F4CD557C40298A5C402101520EE8AAB8DFEED6FFC11AAF8036D6345923CFB641D23FB
-20220414072710 2 6 100 2047 5 F19C2D09AD49978F8A0C1B84168A4011A26F9CD516815934764A319FDC5975FA514AAF11B747D8CA6B3919532BEFB68FA118079473895674F3770F71FBB742F176883841EB3DE679BEF53C6AFE437A662F228B03C1E34B5A0D3909F608CEAA16C1F8131DE11E67878EFD918A89205E5E4DE323054010CA4711F25D466BB7727A016DD3F9F53BDBCE093055A4F2497ADEFB5A2500F9C5C3B0BCD88C6489F4C1CBC7CFB67BA6EABA0195794E4188CE9060F431041AD52FB9BAC4DF7FA536F585FBE67746CD57BFAD67567E9706C24D95C49BE95B759657C6BB5151E2AEA32F4CD557C40298A5C402101520EE8AAB8DFEED6FFC11AAF8036D6345923CFB6434F4DF
-20220414072729 2 6 100 2047 5 E28FC4E08A6D57BC5842065F7028D34B56B517A920144E422159168C0CF6F65E1C9CB385AD0BAFFDA8A78C13A1D32CDC4C0E695426E46F524468E9FF7E423C61B626710F9F3BB9F67F058AC00FFD91AFF9061C88EC8D698F974AA4D7070633D1B7982FA906ED686783E607438859AF0E23BA99392DE67A01D4E2CB47E005EFF3C0DEE0AFFA72D80AD54803FA4C341F6B1B8680C6EB9E3B4A93931485B1F0E92ADA1F3D3F049430454E0C51492C5502BE844CF7AFABC9B6ED351B59098B457C17BBDF6E90B63EBA42E0F03818AB4250668C0F55C0DD8F64D5EE5BFB47713E7935129A97C5B3F917972D7F75263D20B9664DEC37045C7659039593F3AF6436684F
-20220414072730 2 6 100 2047 5 E28FC4E08A6D57BC5842065F7028D34B56B517A920144E422159168C0CF6F65E1C9CB385AD0BAFFDA8A78C13A1D32CDC4C0E695426E46F524468E9FF7E423C61B626710F9F3BB9F67F058AC00FFD91AFF9061C88EC8D698F974AA4D7070633D1B7982FA906ED686783E607438859AF0E23BA99392DE67A01D4E2CB47E005EFF3C0DEE0AFFA72D80AD54803FA4C341F6B1B8680C6EB9E3B4A93931485B1F0E92ADA1F3D3F049430454E0C51492C5502BE844CF7AFABC9B6ED351B59098B457C17BBDF6E90B63EBA42E0F03818AB4250668C0F55C0DD8F64D5EE5BFB47713E7935129A97C5B3F917972D7F75263D20B9664DEC37045C7659039593F3AF643C46A7
-20220414072734 2 6 100 2047 5 E28FC4E08A6D57BC5842065F7028D34B56B517A920144E422159168C0CF6F65E1C9CB385AD0BAFFDA8A78C13A1D32CDC4C0E695426E46F524468E9FF7E423C61B626710F9F3BB9F67F058AC00FFD91AFF9061C88EC8D698F974AA4D7070633D1B7982FA906ED686783E607438859AF0E23BA99392DE67A01D4E2CB47E005EFF3C0DEE0AFFA72D80AD54803FA4C341F6B1B8680C6EB9E3B4A93931485B1F0E92ADA1F3D3F049430454E0C51492C5502BE844CF7AFABC9B6ED351B59098B457C17BBDF6E90B63EBA42E0F03818AB4250668C0F55C0DD8F64D5EE5BFB47713E7935129A97C5B3F917972D7F75263D20B9664DEC37045C7659039593F3AF64668B47
-20220414072739 2 6 100 2047 2 E28FC4E08A6D57BC5842065F7028D34B56B517A920144E422159168C0CF6F65E1C9CB385AD0BAFFDA8A78C13A1D32CDC4C0E695426E46F524468E9FF7E423C61B626710F9F3BB9F67F058AC00FFD91AFF9061C88EC8D698F974AA4D7070633D1B7982FA906ED686783E607438859AF0E23BA99392DE67A01D4E2CB47E005EFF3C0DEE0AFFA72D80AD54803FA4C341F6B1B8680C6EB9E3B4A93931485B1F0E92ADA1F3D3F049430454E0C51492C5502BE844CF7AFABC9B6ED351B59098B457C17BBDF6E90B63EBA42E0F03818AB4250668C0F55C0DD8F64D5EE5BFB47713E7935129A97C5B3F917972D7F75263D20B9664DEC37045C7659039593F3AF648F9F5B
-20220414072741 2 6 100 2047 2 E28FC4E08A6D57BC5842065F7028D34B56B517A920144E422159168C0CF6F65E1C9CB385AD0BAFFDA8A78C13A1D32CDC4C0E695426E46F524468E9FF7E423C61B626710F9F3BB9F67F058AC00FFD91AFF9061C88EC8D698F974AA4D7070633D1B7982FA906ED686783E607438859AF0E23BA99392DE67A01D4E2CB47E005EFF3C0DEE0AFFA72D80AD54803FA4C341F6B1B8680C6EB9E3B4A93931485B1F0E92ADA1F3D3F049430454E0C51492C5502BE844CF7AFABC9B6ED351B59098B457C17BBDF6E90B63EBA42E0F03818AB4250668C0F55C0DD8F64D5EE5BFB47713E7935129A97C5B3F917972D7F75263D20B9664DEC37045C7659039593F3AF64973923
-20220414072744 2 6 100 2047 2 E28FC4E08A6D57BC5842065F7028D34B56B517A920144E422159168C0CF6F65E1C9CB385AD0BAFFDA8A78C13A1D32CDC4C0E695426E46F524468E9FF7E423C61B626710F9F3BB9F67F058AC00FFD91AFF9061C88EC8D698F974AA4D7070633D1B7982FA906ED686783E607438859AF0E23BA99392DE67A01D4E2CB47E005EFF3C0DEE0AFFA72D80AD54803FA4C341F6B1B8680C6EB9E3B4A93931485B1F0E92ADA1F3D3F049430454E0C51492C5502BE844CF7AFABC9B6ED351B59098B457C17BBDF6E90B63EBA42E0F03818AB4250668C0F55C0DD8F64D5EE5BFB47713E7935129A97C5B3F917972D7F75263D20B9664DEC37045C7659039593F3AF64B4BA7B
-20220414072749 2 6 100 2047 2 E28FC4E08A6D57BC5842065F7028D34B56B517A920144E422159168C0CF6F65E1C9CB385AD0BAFFDA8A78C13A1D32CDC4C0E695426E46F524468E9FF7E423C61B626710F9F3BB9F67F058AC00FFD91AFF9061C88EC8D698F974AA4D7070633D1B7982FA906ED686783E607438859AF0E23BA99392DE67A01D4E2CB47E005EFF3C0DEE0AFFA72D80AD54803FA4C341F6B1B8680C6EB9E3B4A93931485B1F0E92ADA1F3D3F049430454E0C51492C5502BE844CF7AFABC9B6ED351B59098B457C17BBDF6E90B63EBA42E0F03818AB4250668C0F55C0DD8F64D5EE5BFB47713E7935129A97C5B3F917972D7F75263D20B9664DEC37045C7659039593F3AF64E993BB
-20220414072753 2 6 100 2047 2 E28FC4E08A6D57BC5842065F7028D34B56B517A920144E422159168C0CF6F65E1C9CB385AD0BAFFDA8A78C13A1D32CDC4C0E695426E46F524468E9FF7E423C61B626710F9F3BB9F67F058AC00FFD91AFF9061C88EC8D698F974AA4D7070633D1B7982FA906ED686783E607438859AF0E23BA99392DE67A01D4E2CB47E005EFF3C0DEE0AFFA72D80AD54803FA4C341F6B1B8680C6EB9E3B4A93931485B1F0E92ADA1F3D3F049430454E0C51492C5502BE844CF7AFABC9B6ED351B59098B457C17BBDF6E90B63EBA42E0F03818AB4250668C0F55C0DD8F64D5EE5BFB47713E7935129A97C5B3F917972D7F75263D20B9664DEC37045C7659039593F3AF6515105B
-20220414072757 2 6 100 2047 2 E28FC4E08A6D57BC5842065F7028D34B56B517A920144E422159168C0CF6F65E1C9CB385AD0BAFFDA8A78C13A1D32CDC4C0E695426E46F524468E9FF7E423C61B626710F9F3BB9F67F058AC00FFD91AFF9061C88EC8D698F974AA4D7070633D1B7982FA906ED686783E607438859AF0E23BA99392DE67A01D4E2CB47E005EFF3C0DEE0AFFA72D80AD54803FA4C341F6B1B8680C6EB9E3B4A93931485B1F0E92ADA1F3D3F049430454E0C51492C5502BE844CF7AFABC9B6ED351B59098B457C17BBDF6E90B63EBA42E0F03818AB4250668C0F55C0DD8F64D5EE5BFB47713E7935129A97C5B3F917972D7F75263D20B9664DEC37045C7659039593F3AF65323FDB
-20220414072809 2 6 100 2047 5 E28FC4E08A6D57BC5842065F7028D34B56B517A920144E422159168C0CF6F65E1C9CB385AD0BAFFDA8A78C13A1D32CDC4C0E695426E46F524468E9FF7E423C61B626710F9F3BB9F67F058AC00FFD91AFF9061C88EC8D698F974AA4D7070633D1B7982FA906ED686783E607438859AF0E23BA99392DE67A01D4E2CB47E005EFF3C0DEE0AFFA72D80AD54803FA4C341F6B1B8680C6EB9E3B4A93931485B1F0E92ADA1F3D3F049430454E0C51492C5502BE844CF7AFABC9B6ED351B59098B457C17BBDF6E90B63EBA42E0F03818AB4250668C0F55C0DD8F64D5EE5BFB47713E7935129A97C5B3F917972D7F75263D20B9664DEC37045C7659039593F3AF65A7F357
-20220414072813 2 6 100 2047 5 E28FC4E08A6D57BC5842065F7028D34B56B517A920144E422159168C0CF6F65E1C9CB385AD0BAFFDA8A78C13A1D32CDC4C0E695426E46F524468E9FF7E423C61B626710F9F3BB9F67F058AC00FFD91AFF9061C88EC8D698F974AA4D7070633D1B7982FA906ED686783E607438859AF0E23BA99392DE67A01D4E2CB47E005EFF3C0DEE0AFFA72D80AD54803FA4C341F6B1B8680C6EB9E3B4A93931485B1F0E92ADA1F3D3F049430454E0C51492C5502BE844CF7AFABC9B6ED351B59098B457C17BBDF6E90B63EBA42E0F03818AB4250668C0F55C0DD8F64D5EE5BFB47713E7935129A97C5B3F917972D7F75263D20B9664DEC37045C7659039593F3AF65CC809F
-20220414072817 2 6 100 2047 2 E28FC4E08A6D57BC5842065F7028D34B56B517A920144E422159168C0CF6F65E1C9CB385AD0BAFFDA8A78C13A1D32CDC4C0E695426E46F524468E9FF7E423C61B626710F9F3BB9F67F058AC00FFD91AFF9061C88EC8D698F974AA4D7070633D1B7982FA906ED686783E607438859AF0E23BA99392DE67A01D4E2CB47E005EFF3C0DEE0AFFA72D80AD54803FA4C341F6B1B8680C6EB9E3B4A93931485B1F0E92ADA1F3D3F049430454E0C51492C5502BE844CF7AFABC9B6ED351B59098B457C17BBDF6E90B63EBA42E0F03818AB4250668C0F55C0DD8F64D5EE5BFB47713E7935129A97C5B3F917972D7F75263D20B9664DEC37045C7659039593F3AF65F46043
-20220414072829 2 6 100 2047 2 E28FC4E08A6D57BC5842065F7028D34B56B517A920144E422159168C0CF6F65E1C9CB385AD0BAFFDA8A78C13A1D32CDC4C0E695426E46F524468E9FF7E423C61B626710F9F3BB9F67F058AC00FFD91AFF9061C88EC8D698F974AA4D7070633D1B7982FA906ED686783E607438859AF0E23BA99392DE67A01D4E2CB47E005EFF3C0DEE0AFFA72D80AD54803FA4C341F6B1B8680C6EB9E3B4A93931485B1F0E92ADA1F3D3F049430454E0C51492C5502BE844CF7AFABC9B6ED351B59098B457C17BBDF6E90B63EBA42E0F03818AB4250668C0F55C0DD8F64D5EE5BFB47713E7935129A97C5B3F917972D7F75263D20B9664DEC37045C7659039593F3AF666C8F9B
-20220414072832 2 6 100 2047 2 E28FC4E08A6D57BC5842065F7028D34B56B517A920144E422159168C0CF6F65E1C9CB385AD0BAFFDA8A78C13A1D32CDC4C0E695426E46F524468E9FF7E423C61B626710F9F3BB9F67F058AC00FFD91AFF9061C88EC8D698F974AA4D7070633D1B7982FA906ED686783E607438859AF0E23BA99392DE67A01D4E2CB47E005EFF3C0DEE0AFFA72D80AD54803FA4C341F6B1B8680C6EB9E3B4A93931485B1F0E92ADA1F3D3F049430454E0C51492C5502BE844CF7AFABC9B6ED351B59098B457C17BBDF6E90B63EBA42E0F03818AB4250668C0F55C0DD8F64D5EE5BFB47713E7935129A97C5B3F917972D7F75263D20B9664DEC37045C7659039593F3AF668915E3
-20220414072835 2 6 100 2047 2 E28FC4E08A6D57BC5842065F7028D34B56B517A920144E422159168C0CF6F65E1C9CB385AD0BAFFDA8A78C13A1D32CDC4C0E695426E46F524468E9FF7E423C61B626710F9F3BB9F67F058AC00FFD91AFF9061C88EC8D698F974AA4D7070633D1B7982FA906ED686783E607438859AF0E23BA99392DE67A01D4E2CB47E005EFF3C0DEE0AFFA72D80AD54803FA4C341F6B1B8680C6EB9E3B4A93931485B1F0E92ADA1F3D3F049430454E0C51492C5502BE844CF7AFABC9B6ED351B59098B457C17BBDF6E90B63EBA42E0F03818AB4250668C0F55C0DD8F64D5EE5BFB47713E7935129A97C5B3F917972D7F75263D20B9664DEC37045C7659039593F3AF66A68853
-20220414072848 2 6 100 2047 5 E28FC4E08A6D57BC5842065F7028D34B56B517A920144E422159168C0CF6F65E1C9CB385AD0BAFFDA8A78C13A1D32CDC4C0E695426E46F524468E9FF7E423C61B626710F9F3BB9F67F058AC00FFD91AFF9061C88EC8D698F974AA4D7070633D1B7982FA906ED686783E607438859AF0E23BA99392DE67A01D4E2CB47E005EFF3C0DEE0AFFA72D80AD54803FA4C341F6B1B8680C6EB9E3B4A93931485B1F0E92ADA1F3D3F049430454E0C51492C5502BE844CF7AFABC9B6ED351B59098B457C17BBDF6E90B63EBA42E0F03818AB4250668C0F55C0DD8F64D5EE5BFB47713E7935129A97C5B3F917972D7F75263D20B9664DEC37045C7659039593F3AF672C226F
-20220414072851 2 6 100 2047 2 E28FC4E08A6D57BC5842065F7028D34B56B517A920144E422159168C0CF6F65E1C9CB385AD0BAFFDA8A78C13A1D32CDC4C0E695426E46F524468E9FF7E423C61B626710F9F3BB9F67F058AC00FFD91AFF9061C88EC8D698F974AA4D7070633D1B7982FA906ED686783E607438859AF0E23BA99392DE67A01D4E2CB47E005EFF3C0DEE0AFFA72D80AD54803FA4C341F6B1B8680C6EB9E3B4A93931485B1F0E92ADA1F3D3F049430454E0C51492C5502BE844CF7AFABC9B6ED351B59098B457C17BBDF6E90B63EBA42E0F03818AB4250668C0F55C0DD8F64D5EE5BFB47713E7935129A97C5B3F917972D7F75263D20B9664DEC37045C7659039593F3AF674E2523
-20220414072854 2 6 100 2047 5 E28FC4E08A6D57BC5842065F7028D34B56B517A920144E422159168C0CF6F65E1C9CB385AD0BAFFDA8A78C13A1D32CDC4C0E695426E46F524468E9FF7E423C61B626710F9F3BB9F67F058AC00FFD91AFF9061C88EC8D698F974AA4D7070633D1B7982FA906ED686783E607438859AF0E23BA99392DE67A01D4E2CB47E005EFF3C0DEE0AFFA72D80AD54803FA4C341F6B1B8680C6EB9E3B4A93931485B1F0E92ADA1F3D3F049430454E0C51492C5502BE844CF7AFABC9B6ED351B59098B457C17BBDF6E90B63EBA42E0F03818AB4250668C0F55C0DD8F64D5EE5BFB47713E7935129A97C5B3F917972D7F75263D20B9664DEC37045C7659039593F3AF67616DDF
-20220414072857 2 6 100 2047 5 E28FC4E08A6D57BC5842065F7028D34B56B517A920144E422159168C0CF6F65E1C9CB385AD0BAFFDA8A78C13A1D32CDC4C0E695426E46F524468E9FF7E423C61B626710F9F3BB9F67F058AC00FFD91AFF9061C88EC8D698F974AA4D7070633D1B7982FA906ED686783E607438859AF0E23BA99392DE67A01D4E2CB47E005EFF3C0DEE0AFFA72D80AD54803FA4C341F6B1B8680C6EB9E3B4A93931485B1F0E92ADA1F3D3F049430454E0C51492C5502BE844CF7AFABC9B6ED351B59098B457C17BBDF6E90B63EBA42E0F03818AB4250668C0F55C0DD8F64D5EE5BFB47713E7935129A97C5B3F917972D7F75263D20B9664DEC37045C7659039593F3AF677613DF
-20220414072900 2 6 100 2047 2 E28FC4E08A6D57BC5842065F7028D34B56B517A920144E422159168C0CF6F65E1C9CB385AD0BAFFDA8A78C13A1D32CDC4C0E695426E46F524468E9FF7E423C61B626710F9F3BB9F67F058AC00FFD91AFF9061C88EC8D698F974AA4D7070633D1B7982FA906ED686783E607438859AF0E23BA99392DE67A01D4E2CB47E005EFF3C0DEE0AFFA72D80AD54803FA4C341F6B1B8680C6EB9E3B4A93931485B1F0E92ADA1F3D3F049430454E0C51492C5502BE844CF7AFABC9B6ED351B59098B457C17BBDF6E90B63EBA42E0F03818AB4250668C0F55C0DD8F64D5EE5BFB47713E7935129A97C5B3F917972D7F75263D20B9664DEC37045C7659039593F3AF6792A07B
-20220414072903 2 6 100 2047 5 E28FC4E08A6D57BC5842065F7028D34B56B517A920144E422159168C0CF6F65E1C9CB385AD0BAFFDA8A78C13A1D32CDC4C0E695426E46F524468E9FF7E423C61B626710F9F3BB9F67F058AC00FFD91AFF9061C88EC8D698F974AA4D7070633D1B7982FA906ED686783E607438859AF0E23BA99392DE67A01D4E2CB47E005EFF3C0DEE0AFFA72D80AD54803FA4C341F6B1B8680C6EB9E3B4A93931485B1F0E92ADA1F3D3F049430454E0C51492C5502BE844CF7AFABC9B6ED351B59098B457C17BBDF6E90B63EBA42E0F03818AB4250668C0F55C0DD8F64D5EE5BFB47713E7935129A97C5B3F917972D7F75263D20B9664DEC37045C7659039593F3AF67AC314F
-20220414072905 2 6 100 2047 2 E28FC4E08A6D57BC5842065F7028D34B56B517A920144E422159168C0CF6F65E1C9CB385AD0BAFFDA8A78C13A1D32CDC4C0E695426E46F524468E9FF7E423C61B626710F9F3BB9F67F058AC00FFD91AFF9061C88EC8D698F974AA4D7070633D1B7982FA906ED686783E607438859AF0E23BA99392DE67A01D4E2CB47E005EFF3C0DEE0AFFA72D80AD54803FA4C341F6B1B8680C6EB9E3B4A93931485B1F0E92ADA1F3D3F049430454E0C51492C5502BE844CF7AFABC9B6ED351B59098B457C17BBDF6E90B63EBA42E0F03818AB4250668C0F55C0DD8F64D5EE5BFB47713E7935129A97C5B3F917972D7F75263D20B9664DEC37045C7659039593F3AF67B61CAB
-20220414072907 2 6 100 2047 2 E28FC4E08A6D57BC5842065F7028D34B56B517A920144E422159168C0CF6F65E1C9CB385AD0BAFFDA8A78C13A1D32CDC4C0E695426E46F524468E9FF7E423C61B626710F9F3BB9F67F058AC00FFD91AFF9061C88EC8D698F974AA4D7070633D1B7982FA906ED686783E607438859AF0E23BA99392DE67A01D4E2CB47E005EFF3C0DEE0AFFA72D80AD54803FA4C341F6B1B8680C6EB9E3B4A93931485B1F0E92ADA1F3D3F049430454E0C51492C5502BE844CF7AFABC9B6ED351B59098B457C17BBDF6E90B63EBA42E0F03818AB4250668C0F55C0DD8F64D5EE5BFB47713E7935129A97C5B3F917972D7F75263D20B9664DEC37045C7659039593F3AF67CB88C3
-20220414072908 2 6 100 2047 2 E28FC4E08A6D57BC5842065F7028D34B56B517A920144E422159168C0CF6F65E1C9CB385AD0BAFFDA8A78C13A1D32CDC4C0E695426E46F524468E9FF7E423C61B626710F9F3BB9F67F058AC00FFD91AFF9061C88EC8D698F974AA4D7070633D1B7982FA906ED686783E607438859AF0E23BA99392DE67A01D4E2CB47E005EFF3C0DEE0AFFA72D80AD54803FA4C341F6B1B8680C6EB9E3B4A93931485B1F0E92ADA1F3D3F049430454E0C51492C5502BE844CF7AFABC9B6ED351B59098B457C17BBDF6E90B63EBA42E0F03818AB4250668C0F55C0DD8F64D5EE5BFB47713E7935129A97C5B3F917972D7F75263D20B9664DEC37045C7659039593F3AF67CBC62B
-20220414072909 2 6 100 2047 2 E28FC4E08A6D57BC5842065F7028D34B56B517A920144E422159168C0CF6F65E1C9CB385AD0BAFFDA8A78C13A1D32CDC4C0E695426E46F524468E9FF7E423C61B626710F9F3BB9F67F058AC00FFD91AFF9061C88EC8D698F974AA4D7070633D1B7982FA906ED686783E607438859AF0E23BA99392DE67A01D4E2CB47E005EFF3C0DEE0AFFA72D80AD54803FA4C341F6B1B8680C6EB9E3B4A93931485B1F0E92ADA1F3D3F049430454E0C51492C5502BE844CF7AFABC9B6ED351B59098B457C17BBDF6E90B63EBA42E0F03818AB4250668C0F55C0DD8F64D5EE5BFB47713E7935129A97C5B3F917972D7F75263D20B9664DEC37045C7659039593F3AF67D5028B
-20220414072925 2 6 100 2047 2 E28FC4E08A6D57BC5842065F7028D34B56B517A920144E422159168C0CF6F65E1C9CB385AD0BAFFDA8A78C13A1D32CDC4C0E695426E46F524468E9FF7E423C61B626710F9F3BB9F67F058AC00FFD91AFF9061C88EC8D698F974AA4D7070633D1B7982FA906ED686783E607438859AF0E23BA99392DE67A01D4E2CB47E005EFF3C0DEE0AFFA72D80AD54803FA4C341F6B1B8680C6EB9E3B4A93931485B1F0E92ADA1F3D3F049430454E0C51492C5502BE844CF7AFABC9B6ED351B59098B457C17BBDF6E90B63EBA42E0F03818AB4250668C0F55C0DD8F64D5EE5BFB47713E7935129A97C5B3F917972D7F75263D20B9664DEC37045C7659039593F3AF6879A003
-20220414072927 2 6 100 2047 5 E28FC4E08A6D57BC5842065F7028D34B56B517A920144E422159168C0CF6F65E1C9CB385AD0BAFFDA8A78C13A1D32CDC4C0E695426E46F524468E9FF7E423C61B626710F9F3BB9F67F058AC00FFD91AFF9061C88EC8D698F974AA4D7070633D1B7982FA906ED686783E607438859AF0E23BA99392DE67A01D4E2CB47E005EFF3C0DEE0AFFA72D80AD54803FA4C341F6B1B8680C6EB9E3B4A93931485B1F0E92ADA1F3D3F049430454E0C51492C5502BE844CF7AFABC9B6ED351B59098B457C17BBDF6E90B63EBA42E0F03818AB4250668C0F55C0DD8F64D5EE5BFB47713E7935129A97C5B3F917972D7F75263D20B9664DEC37045C7659039593F3AF68874667
-20220414072929 2 6 100 2047 2 E28FC4E08A6D57BC5842065F7028D34B56B517A920144E422159168C0CF6F65E1C9CB385AD0BAFFDA8A78C13A1D32CDC4C0E695426E46F524468E9FF7E423C61B626710F9F3BB9F67F058AC00FFD91AFF9061C88EC8D698F974AA4D7070633D1B7982FA906ED686783E607438859AF0E23BA99392DE67A01D4E2CB47E005EFF3C0DEE0AFFA72D80AD54803FA4C341F6B1B8680C6EB9E3B4A93931485B1F0E92ADA1F3D3F049430454E0C51492C5502BE844CF7AFABC9B6ED351B59098B457C17BBDF6E90B63EBA42E0F03818AB4250668C0F55C0DD8F64D5EE5BFB47713E7935129A97C5B3F917972D7F75263D20B9664DEC37045C7659039593F3AF68967B9B
-20220414072935 2 6 100 2047 2 E28FC4E08A6D57BC5842065F7028D34B56B517A920144E422159168C0CF6F65E1C9CB385AD0BAFFDA8A78C13A1D32CDC4C0E695426E46F524468E9FF7E423C61B626710F9F3BB9F67F058AC00FFD91AFF9061C88EC8D698F974AA4D7070633D1B7982FA906ED686783E607438859AF0E23BA99392DE67A01D4E2CB47E005EFF3C0DEE0AFFA72D80AD54803FA4C341F6B1B8680C6EB9E3B4A93931485B1F0E92ADA1F3D3F049430454E0C51492C5502BE844CF7AFABC9B6ED351B59098B457C17BBDF6E90B63EBA42E0F03818AB4250668C0F55C0DD8F64D5EE5BFB47713E7935129A97C5B3F917972D7F75263D20B9664DEC37045C7659039593F3AF68D81493
-20220414072953 2 6 100 2047 2 E28FC4E08A6D57BC5842065F7028D34B56B517A920144E422159168C0CF6F65E1C9CB385AD0BAFFDA8A78C13A1D32CDC4C0E695426E46F524468E9FF7E423C61B626710F9F3BB9F67F058AC00FFD91AFF9061C88EC8D698F974AA4D7070633D1B7982FA906ED686783E607438859AF0E23BA99392DE67A01D4E2CB47E005EFF3C0DEE0AFFA72D80AD54803FA4C341F6B1B8680C6EB9E3B4A93931485B1F0E92ADA1F3D3F049430454E0C51492C5502BE844CF7AFABC9B6ED351B59098B457C17BBDF6E90B63EBA42E0F03818AB4250668C0F55C0DD8F64D5EE5BFB47713E7935129A97C5B3F917972D7F75263D20B9664DEC37045C7659039593F3AF69A1B363
-20220414072957 2 6 100 2047 2 E28FC4E08A6D57BC5842065F7028D34B56B517A920144E422159168C0CF6F65E1C9CB385AD0BAFFDA8A78C13A1D32CDC4C0E695426E46F524468E9FF7E423C61B626710F9F3BB9F67F058AC00FFD91AFF9061C88EC8D698F974AA4D7070633D1B7982FA906ED686783E607438859AF0E23BA99392DE67A01D4E2CB47E005EFF3C0DEE0AFFA72D80AD54803FA4C341F6B1B8680C6EB9E3B4A93931485B1F0E92ADA1F3D3F049430454E0C51492C5502BE844CF7AFABC9B6ED351B59098B457C17BBDF6E90B63EBA42E0F03818AB4250668C0F55C0DD8F64D5EE5BFB47713E7935129A97C5B3F917972D7F75263D20B9664DEC37045C7659039593F3AF69C2BBA3
-20220414072959 2 6 100 2047 5 E28FC4E08A6D57BC5842065F7028D34B56B517A920144E422159168C0CF6F65E1C9CB385AD0BAFFDA8A78C13A1D32CDC4C0E695426E46F524468E9FF7E423C61B626710F9F3BB9F67F058AC00FFD91AFF9061C88EC8D698F974AA4D7070633D1B7982FA906ED686783E607438859AF0E23BA99392DE67A01D4E2CB47E005EFF3C0DEE0AFFA72D80AD54803FA4C341F6B1B8680C6EB9E3B4A93931485B1F0E92ADA1F3D3F049430454E0C51492C5502BE844CF7AFABC9B6ED351B59098B457C17BBDF6E90B63EBA42E0F03818AB4250668C0F55C0DD8F64D5EE5BFB47713E7935129A97C5B3F917972D7F75263D20B9664DEC37045C7659039593F3AF69D13857
-20220414073003 2 6 100 2047 2 E28FC4E08A6D57BC5842065F7028D34B56B517A920144E422159168C0CF6F65E1C9CB385AD0BAFFDA8A78C13A1D32CDC4C0E695426E46F524468E9FF7E423C61B626710F9F3BB9F67F058AC00FFD91AFF9061C88EC8D698F974AA4D7070633D1B7982FA906ED686783E607438859AF0E23BA99392DE67A01D4E2CB47E005EFF3C0DEE0AFFA72D80AD54803FA4C341F6B1B8680C6EB9E3B4A93931485B1F0E92ADA1F3D3F049430454E0C51492C5502BE844CF7AFABC9B6ED351B59098B457C17BBDF6E90B63EBA42E0F03818AB4250668C0F55C0DD8F64D5EE5BFB47713E7935129A97C5B3F917972D7F75263D20B9664DEC37045C7659039593F3AF69EF96CB
-20220414073004 2 6 100 2047 2 E28FC4E08A6D57BC5842065F7028D34B56B517A920144E422159168C0CF6F65E1C9CB385AD0BAFFDA8A78C13A1D32CDC4C0E695426E46F524468E9FF7E423C61B626710F9F3BB9F67F058AC00FFD91AFF9061C88EC8D698F974AA4D7070633D1B7982FA906ED686783E607438859AF0E23BA99392DE67A01D4E2CB47E005EFF3C0DEE0AFFA72D80AD54803FA4C341F6B1B8680C6EB9E3B4A93931485B1F0E92ADA1F3D3F049430454E0C51492C5502BE844CF7AFABC9B6ED351B59098B457C17BBDF6E90B63EBA42E0F03818AB4250668C0F55C0DD8F64D5EE5BFB47713E7935129A97C5B3F917972D7F75263D20B9664DEC37045C7659039593F3AF69F43F4B
-20220414073006 2 6 100 2047 2 E28FC4E08A6D57BC5842065F7028D34B56B517A920144E422159168C0CF6F65E1C9CB385AD0BAFFDA8A78C13A1D32CDC4C0E695426E46F524468E9FF7E423C61B626710F9F3BB9F67F058AC00FFD91AFF9061C88EC8D698F974AA4D7070633D1B7982FA906ED686783E607438859AF0E23BA99392DE67A01D4E2CB47E005EFF3C0DEE0AFFA72D80AD54803FA4C341F6B1B8680C6EB9E3B4A93931485B1F0E92ADA1F3D3F049430454E0C51492C5502BE844CF7AFABC9B6ED351B59098B457C17BBDF6E90B63EBA42E0F03818AB4250668C0F55C0DD8F64D5EE5BFB47713E7935129A97C5B3F917972D7F75263D20B9664DEC37045C7659039593F3AF6A06D42B
-20220414073016 2 6 100 2047 2 E28FC4E08A6D57BC5842065F7028D34B56B517A920144E422159168C0CF6F65E1C9CB385AD0BAFFDA8A78C13A1D32CDC4C0E695426E46F524468E9FF7E423C61B626710F9F3BB9F67F058AC00FFD91AFF9061C88EC8D698F974AA4D7070633D1B7982FA906ED686783E607438859AF0E23BA99392DE67A01D4E2CB47E005EFF3C0DEE0AFFA72D80AD54803FA4C341F6B1B8680C6EB9E3B4A93931485B1F0E92ADA1F3D3F049430454E0C51492C5502BE844CF7AFABC9B6ED351B59098B457C17BBDF6E90B63EBA42E0F03818AB4250668C0F55C0DD8F64D5EE5BFB47713E7935129A97C5B3F917972D7F75263D20B9664DEC37045C7659039593F3AF6A6A7103
-20220414073018 2 6 100 2047 2 E28FC4E08A6D57BC5842065F7028D34B56B517A920144E422159168C0CF6F65E1C9CB385AD0BAFFDA8A78C13A1D32CDC4C0E695426E46F524468E9FF7E423C61B626710F9F3BB9F67F058AC00FFD91AFF9061C88EC8D698F974AA4D7070633D1B7982FA906ED686783E607438859AF0E23BA99392DE67A01D4E2CB47E005EFF3C0DEE0AFFA72D80AD54803FA4C341F6B1B8680C6EB9E3B4A93931485B1F0E92ADA1F3D3F049430454E0C51492C5502BE844CF7AFABC9B6ED351B59098B457C17BBDF6E90B63EBA42E0F03818AB4250668C0F55C0DD8F64D5EE5BFB47713E7935129A97C5B3F917972D7F75263D20B9664DEC37045C7659039593F3AF6A7B9AFB
-20220414073018 2 6 100 2047 5 E28FC4E08A6D57BC5842065F7028D34B56B517A920144E422159168C0CF6F65E1C9CB385AD0BAFFDA8A78C13A1D32CDC4C0E695426E46F524468E9FF7E423C61B626710F9F3BB9F67F058AC00FFD91AFF9061C88EC8D698F974AA4D7070633D1B7982FA906ED686783E607438859AF0E23BA99392DE67A01D4E2CB47E005EFF3C0DEE0AFFA72D80AD54803FA4C341F6B1B8680C6EB9E3B4A93931485B1F0E92ADA1F3D3F049430454E0C51492C5502BE844CF7AFABC9B6ED351B59098B457C17BBDF6E90B63EBA42E0F03818AB4250668C0F55C0DD8F64D5EE5BFB47713E7935129A97C5B3F917972D7F75263D20B9664DEC37045C7659039593F3AF6A7BD38F
-20220414073019 2 6 100 2047 5 E28FC4E08A6D57BC5842065F7028D34B56B517A920144E422159168C0CF6F65E1C9CB385AD0BAFFDA8A78C13A1D32CDC4C0E695426E46F524468E9FF7E423C61B626710F9F3BB9F67F058AC00FFD91AFF9061C88EC8D698F974AA4D7070633D1B7982FA906ED686783E607438859AF0E23BA99392DE67A01D4E2CB47E005EFF3C0DEE0AFFA72D80AD54803FA4C341F6B1B8680C6EB9E3B4A93931485B1F0E92ADA1F3D3F049430454E0C51492C5502BE844CF7AFABC9B6ED351B59098B457C17BBDF6E90B63EBA42E0F03818AB4250668C0F55C0DD8F64D5EE5BFB47713E7935129A97C5B3F917972D7F75263D20B9664DEC37045C7659039593F3AF6A7F4A6F
-20220414073036 2 6 100 2047 5 E28FC4E08A6D57BC5842065F7028D34B56B517A920144E422159168C0CF6F65E1C9CB385AD0BAFFDA8A78C13A1D32CDC4C0E695426E46F524468E9FF7E423C61B626710F9F3BB9F67F058AC00FFD91AFF9061C88EC8D698F974AA4D7070633D1B7982FA906ED686783E607438859AF0E23BA99392DE67A01D4E2CB47E005EFF3C0DEE0AFFA72D80AD54803FA4C341F6B1B8680C6EB9E3B4A93931485B1F0E92ADA1F3D3F049430454E0C51492C5502BE844CF7AFABC9B6ED351B59098B457C17BBDF6E90B63EBA42E0F03818AB4250668C0F55C0DD8F64D5EE5BFB47713E7935129A97C5B3F917972D7F75263D20B9664DEC37045C7659039593F3AF6B2FC84F
-20220414073041 2 6 100 2047 2 E28FC4E08A6D57BC5842065F7028D34B56B517A920144E422159168C0CF6F65E1C9CB385AD0BAFFDA8A78C13A1D32CDC4C0E695426E46F524468E9FF7E423C61B626710F9F3BB9F67F058AC00FFD91AFF9061C88EC8D698F974AA4D7070633D1B7982FA906ED686783E607438859AF0E23BA99392DE67A01D4E2CB47E005EFF3C0DEE0AFFA72D80AD54803FA4C341F6B1B8680C6EB9E3B4A93931485B1F0E92ADA1F3D3F049430454E0C51492C5502BE844CF7AFABC9B6ED351B59098B457C17BBDF6E90B63EBA42E0F03818AB4250668C0F55C0DD8F64D5EE5BFB47713E7935129A97C5B3F917972D7F75263D20B9664DEC37045C7659039593F3AF6B67F26B
-20220414073055 2 6 100 2047 5 E28FC4E08A6D57BC5842065F7028D34B56B517A920144E422159168C0CF6F65E1C9CB385AD0BAFFDA8A78C13A1D32CDC4C0E695426E46F524468E9FF7E423C61B626710F9F3BB9F67F058AC00FFD91AFF9061C88EC8D698F974AA4D7070633D1B7982FA906ED686783E607438859AF0E23BA99392DE67A01D4E2CB47E005EFF3C0DEE0AFFA72D80AD54803FA4C341F6B1B8680C6EB9E3B4A93931485B1F0E92ADA1F3D3F049430454E0C51492C5502BE844CF7AFABC9B6ED351B59098B457C17BBDF6E90B63EBA42E0F03818AB4250668C0F55C0DD8F64D5EE5BFB47713E7935129A97C5B3F917972D7F75263D20B9664DEC37045C7659039593F3AF6C025837
-20220414073058 2 6 100 2047 5 E28FC4E08A6D57BC5842065F7028D34B56B517A920144E422159168C0CF6F65E1C9CB385AD0BAFFDA8A78C13A1D32CDC4C0E695426E46F524468E9FF7E423C61B626710F9F3BB9F67F058AC00FFD91AFF9061C88EC8D698F974AA4D7070633D1B7982FA906ED686783E607438859AF0E23BA99392DE67A01D4E2CB47E005EFF3C0DEE0AFFA72D80AD54803FA4C341F6B1B8680C6EB9E3B4A93931485B1F0E92ADA1F3D3F049430454E0C51492C5502BE844CF7AFABC9B6ED351B59098B457C17BBDF6E90B63EBA42E0F03818AB4250668C0F55C0DD8F64D5EE5BFB47713E7935129A97C5B3F917972D7F75263D20B9664DEC37045C7659039593F3AF6C19C927
-20220414073921 2 6 100 3071 5 C51B2203994018FE66AF950975C59F6B678BD895CBD976250E5513528EF9B03B85B0DD85C17B519B1D41CB11CFCF86F9649C411D746E8ADA9A743D09458BE956D59D6C471945A92E1A6AD2B519D24373242BDD1A13BDE5EAE3518F17F8D2EB158F5340F76212DE07E67816FCC95EABAA1568116D400FC2EE789EB0C097AC9E94DB7B6A861F35B7F57C58934FD6034B4352F83978CB943D63921D8B29BC30A5CB5069A31F550206767EAB17FF80BD34A849F05CEA09CE2B374D70B25DFC31DD546310C948F9DAF4E0C873FA5AC0221EF1D761F581AE4C8C890FCC7D16E5A82B4DB3C9C713A3A13E8039D62AB2DC9B4AD3B1BB721D985C2DD6333E9871F5E4D76AC163D90CC629CC81783087DBC70739200FB5703FF4BEA4202FBEAD26311123672F1E6CBD0DA429CD253E4F579D5FFECEF1DDA78D2AF6B6D8B9818E334D42DFF3F7ACAFD350421BC6C551C004FBE620D397EB602AD2CEDD0D61C9E22D622AF8197393CFEB7250F6D13CBC5CB7625242B0CD23B174F66B00BEDA0E4CB839BF99CF
-20220414074048 2 6 100 3071 2 C51B2203994018FE66AF950975C59F6B678BD895CBD976250E5513528EF9B03B85B0DD85C17B519B1D41CB11CFCF86F9649C411D746E8ADA9A743D09458BE956D59D6C471945A92E1A6AD2B519D24373242BDD1A13BDE5EAE3518F17F8D2EB158F5340F76212DE07E67816FCC95EABAA1568116D400FC2EE789EB0C097AC9E94DB7B6A861F35B7F57C58934FD6034B4352F83978CB943D63921D8B29BC30A5CB5069A31F550206767EAB17FF80BD34A849F05CEA09CE2B374D70B25DFC31DD546310C948F9DAF4E0C873FA5AC0221EF1D761F581AE4C8C890FCC7D16E5A82B4DB3C9C713A3A13E8039D62AB2DC9B4AD3B1BB721D985C2DD6333E9871F5E4D76AC163D90CC629CC81783087DBC70739200FB5703FF4BEA4202FBEAD26311123672F1E6CBD0DA429CD253E4F579D5FFECEF1DDA78D2AF6B6D8B9818E334D42DFF3F7ACAFD350421BC6C551C004FBE620D397EB602AD2CEDD0D61C9E22D622AF8197393CFEB7250F6D13CBC5CB7625242B0CD23B174F66B00BEDA0E4CB83B22A8CB
-20220414074055 2 6 100 3071 2 C51B2203994018FE66AF950975C59F6B678BD895CBD976250E5513528EF9B03B85B0DD85C17B519B1D41CB11CFCF86F9649C411D746E8ADA9A743D09458BE956D59D6C471945A92E1A6AD2B519D24373242BDD1A13BDE5EAE3518F17F8D2EB158F5340F76212DE07E67816FCC95EABAA1568116D400FC2EE789EB0C097AC9E94DB7B6A861F35B7F57C58934FD6034B4352F83978CB943D63921D8B29BC30A5CB5069A31F550206767EAB17FF80BD34A849F05CEA09CE2B374D70B25DFC31DD546310C948F9DAF4E0C873FA5AC0221EF1D761F581AE4C8C890FCC7D16E5A82B4DB3C9C713A3A13E8039D62AB2DC9B4AD3B1BB721D985C2DD6333E9871F5E4D76AC163D90CC629CC81783087DBC70739200FB5703FF4BEA4202FBEAD26311123672F1E6CBD0DA429CD253E4F579D5FFECEF1DDA78D2AF6B6D8B9818E334D42DFF3F7ACAFD350421BC6C551C004FBE620D397EB602AD2CEDD0D61C9E22D622AF8197393CFEB7250F6D13CBC5CB7625242B0CD23B174F66B00BEDA0E4CB83B38DF4B
-20220414074204 2 6 100 3071 2 C51B2203994018FE66AF950975C59F6B678BD895CBD976250E5513528EF9B03B85B0DD85C17B519B1D41CB11CFCF86F9649C411D746E8ADA9A743D09458BE956D59D6C471945A92E1A6AD2B519D24373242BDD1A13BDE5EAE3518F17F8D2EB158F5340F76212DE07E67816FCC95EABAA1568116D400FC2EE789EB0C097AC9E94DB7B6A861F35B7F57C58934FD6034B4352F83978CB943D63921D8B29BC30A5CB5069A31F550206767EAB17FF80BD34A849F05CEA09CE2B374D70B25DFC31DD546310C948F9DAF4E0C873FA5AC0221EF1D761F581AE4C8C890FCC7D16E5A82B4DB3C9C713A3A13E8039D62AB2DC9B4AD3B1BB721D985C2DD6333E9871F5E4D76AC163D90CC629CC81783087DBC70739200FB5703FF4BEA4202FBEAD26311123672F1E6CBD0DA429CD253E4F579D5FFECEF1DDA78D2AF6B6D8B9818E334D42DFF3F7ACAFD350421BC6C551C004FBE620D397EB602AD2CEDD0D61C9E22D622AF8197393CFEB7250F6D13CBC5CB7625242B0CD23B174F66B00BEDA0E4CB83C4E96FB
-20220414074223 2 6 100 3071 5 C51B2203994018FE66AF950975C59F6B678BD895CBD976250E5513528EF9B03B85B0DD85C17B519B1D41CB11CFCF86F9649C411D746E8ADA9A743D09458BE956D59D6C471945A92E1A6AD2B519D24373242BDD1A13BDE5EAE3518F17F8D2EB158F5340F76212DE07E67816FCC95EABAA1568116D400FC2EE789EB0C097AC9E94DB7B6A861F35B7F57C58934FD6034B4352F83978CB943D63921D8B29BC30A5CB5069A31F550206767EAB17FF80BD34A849F05CEA09CE2B374D70B25DFC31DD546310C948F9DAF4E0C873FA5AC0221EF1D761F581AE4C8C890FCC7D16E5A82B4DB3C9C713A3A13E8039D62AB2DC9B4AD3B1BB721D985C2DD6333E9871F5E4D76AC163D90CC629CC81783087DBC70739200FB5703FF4BEA4202FBEAD26311123672F1E6CBD0DA429CD253E4F579D5FFECEF1DDA78D2AF6B6D8B9818E334D42DFF3F7ACAFD350421BC6C551C004FBE620D397EB602AD2CEDD0D61C9E22D622AF8197393CFEB7250F6D13CBC5CB7625242B0CD23B174F66B00BEDA0E4CB83C952457
-20220414074458 2 6 100 3071 2 C51B2203994018FE66AF950975C59F6B678BD895CBD976250E5513528EF9B03B85B0DD85C17B519B1D41CB11CFCF86F9649C411D746E8ADA9A743D09458BE956D59D6C471945A92E1A6AD2B519D24373242BDD1A13BDE5EAE3518F17F8D2EB158F5340F76212DE07E67816FCC95EABAA1568116D400FC2EE789EB0C097AC9E94DB7B6A861F35B7F57C58934FD6034B4352F83978CB943D63921D8B29BC30A5CB5069A31F550206767EAB17FF80BD34A849F05CEA09CE2B374D70B25DFC31DD546310C948F9DAF4E0C873FA5AC0221EF1D761F581AE4C8C890FCC7D16E5A82B4DB3C9C713A3A13E8039D62AB2DC9B4AD3B1BB721D985C2DD6333E9871F5E4D76AC163D90CC629CC81783087DBC70739200FB5703FF4BEA4202FBEAD26311123672F1E6CBD0DA429CD253E4F579D5FFECEF1DDA78D2AF6B6D8B9818E334D42DFF3F7ACAFD350421BC6C551C004FBE620D397EB602AD2CEDD0D61C9E22D622AF8197393CFEB7250F6D13CBC5CB7625242B0CD23B174F66B00BEDA0E4CB83EF76EDB
-20220414074505 2 6 100 3071 2 C51B2203994018FE66AF950975C59F6B678BD895CBD976250E5513528EF9B03B85B0DD85C17B519B1D41CB11CFCF86F9649C411D746E8ADA9A743D09458BE956D59D6C471945A92E1A6AD2B519D24373242BDD1A13BDE5EAE3518F17F8D2EB158F5340F76212DE07E67816FCC95EABAA1568116D400FC2EE789EB0C097AC9E94DB7B6A861F35B7F57C58934FD6034B4352F83978CB943D63921D8B29BC30A5CB5069A31F550206767EAB17FF80BD34A849F05CEA09CE2B374D70B25DFC31DD546310C948F9DAF4E0C873FA5AC0221EF1D761F581AE4C8C890FCC7D16E5A82B4DB3C9C713A3A13E8039D62AB2DC9B4AD3B1BB721D985C2DD6333E9871F5E4D76AC163D90CC629CC81783087DBC70739200FB5703FF4BEA4202FBEAD26311123672F1E6CBD0DA429CD253E4F579D5FFECEF1DDA78D2AF6B6D8B9818E334D42DFF3F7ACAFD350421BC6C551C004FBE620D397EB602AD2CEDD0D61C9E22D622AF8197393CFEB7250F6D13CBC5CB7625242B0CD23B174F66B00BEDA0E4CB83F0B3E5B
-20220414074508 2 6 100 3071 5 C51B2203994018FE66AF950975C59F6B678BD895CBD976250E5513528EF9B03B85B0DD85C17B519B1D41CB11CFCF86F9649C411D746E8ADA9A743D09458BE956D59D6C471945A92E1A6AD2B519D24373242BDD1A13BDE5EAE3518F17F8D2EB158F5340F76212DE07E67816FCC95EABAA1568116D400FC2EE789EB0C097AC9E94DB7B6A861F35B7F57C58934FD6034B4352F83978CB943D63921D8B29BC30A5CB5069A31F550206767EAB17FF80BD34A849F05CEA09CE2B374D70B25DFC31DD546310C948F9DAF4E0C873FA5AC0221EF1D761F581AE4C8C890FCC7D16E5A82B4DB3C9C713A3A13E8039D62AB2DC9B4AD3B1BB721D985C2DD6333E9871F5E4D76AC163D90CC629CC81783087DBC70739200FB5703FF4BEA4202FBEAD26311123672F1E6CBD0DA429CD253E4F579D5FFECEF1DDA78D2AF6B6D8B9818E334D42DFF3F7ACAFD350421BC6C551C004FBE620D397EB602AD2CEDD0D61C9E22D622AF8197393CFEB7250F6D13CBC5CB7625242B0CD23B174F66B00BEDA0E4CB83F1192F7
-20220414074657 2 6 100 3071 2 C51B2203994018FE66AF950975C59F6B678BD895CBD976250E5513528EF9B03B85B0DD85C17B519B1D41CB11CFCF86F9649C411D746E8ADA9A743D09458BE956D59D6C471945A92E1A6AD2B519D24373242BDD1A13BDE5EAE3518F17F8D2EB158F5340F76212DE07E67816FCC95EABAA1568116D400FC2EE789EB0C097AC9E94DB7B6A861F35B7F57C58934FD6034B4352F83978CB943D63921D8B29BC30A5CB5069A31F550206767EAB17FF80BD34A849F05CEA09CE2B374D70B25DFC31DD546310C948F9DAF4E0C873FA5AC0221EF1D761F581AE4C8C890FCC7D16E5A82B4DB3C9C713A3A13E8039D62AB2DC9B4AD3B1BB721D985C2DD6333E9871F5E4D76AC163D90CC629CC81783087DBC70739200FB5703FF4BEA4202FBEAD26311123672F1E6CBD0DA429CD253E4F579D5FFECEF1DDA78D2AF6B6D8B9818E334D42DFF3F7ACAFD350421BC6C551C004FBE620D397EB602AD2CEDD0D61C9E22D622AF8197393CFEB7250F6D13CBC5CB7625242B0CD23B174F66B00BEDA0E4CB840C320E3
-20220414074757 2 6 100 3071 5 C51B2203994018FE66AF950975C59F6B678BD895CBD976250E5513528EF9B03B85B0DD85C17B519B1D41CB11CFCF86F9649C411D746E8ADA9A743D09458BE956D59D6C471945A92E1A6AD2B519D24373242BDD1A13BDE5EAE3518F17F8D2EB158F5340F76212DE07E67816FCC95EABAA1568116D400FC2EE789EB0C097AC9E94DB7B6A861F35B7F57C58934FD6034B4352F83978CB943D63921D8B29BC30A5CB5069A31F550206767EAB17FF80BD34A849F05CEA09CE2B374D70B25DFC31DD546310C948F9DAF4E0C873FA5AC0221EF1D761F581AE4C8C890FCC7D16E5A82B4DB3C9C713A3A13E8039D62AB2DC9B4AD3B1BB721D985C2DD6333E9871F5E4D76AC163D90CC629CC81783087DBC70739200FB5703FF4BEA4202FBEAD26311123672F1E6CBD0DA429CD253E4F579D5FFECEF1DDA78D2AF6B6D8B9818E334D42DFF3F7ACAFD350421BC6C551C004FBE620D397EB602AD2CEDD0D61C9E22D622AF8197393CFEB7250F6D13CBC5CB7625242B0CD23B174F66B00BEDA0E4CB841ACDB2F
-20220414074809 2 6 100 3071 2 C51B2203994018FE66AF950975C59F6B678BD895CBD976250E5513528EF9B03B85B0DD85C17B519B1D41CB11CFCF86F9649C411D746E8ADA9A743D09458BE956D59D6C471945A92E1A6AD2B519D24373242BDD1A13BDE5EAE3518F17F8D2EB158F5340F76212DE07E67816FCC95EABAA1568116D400FC2EE789EB0C097AC9E94DB7B6A861F35B7F57C58934FD6034B4352F83978CB943D63921D8B29BC30A5CB5069A31F550206767EAB17FF80BD34A849F05CEA09CE2B374D70B25DFC31DD546310C948F9DAF4E0C873FA5AC0221EF1D761F581AE4C8C890FCC7D16E5A82B4DB3C9C713A3A13E8039D62AB2DC9B4AD3B1BB721D985C2DD6333E9871F5E4D76AC163D90CC629CC81783087DBC70739200FB5703FF4BEA4202FBEAD26311123672F1E6CBD0DA429CD253E4F579D5FFECEF1DDA78D2AF6B6D8B9818E334D42DFF3F7ACAFD350421BC6C551C004FBE620D397EB602AD2CEDD0D61C9E22D622AF8197393CFEB7250F6D13CBC5CB7625242B0CD23B174F66B00BEDA0E4CB841D33923
-20220414074813 2 6 100 3071 5 C51B2203994018FE66AF950975C59F6B678BD895CBD976250E5513528EF9B03B85B0DD85C17B519B1D41CB11CFCF86F9649C411D746E8ADA9A743D09458BE956D59D6C471945A92E1A6AD2B519D24373242BDD1A13BDE5EAE3518F17F8D2EB158F5340F76212DE07E67816FCC95EABAA1568116D400FC2EE789EB0C097AC9E94DB7B6A861F35B7F57C58934FD6034B4352F83978CB943D63921D8B29BC30A5CB5069A31F550206767EAB17FF80BD34A849F05CEA09CE2B374D70B25DFC31DD546310C948F9DAF4E0C873FA5AC0221EF1D761F581AE4C8C890FCC7D16E5A82B4DB3C9C713A3A13E8039D62AB2DC9B4AD3B1BB721D985C2DD6333E9871F5E4D76AC163D90CC629CC81783087DBC70739200FB5703FF4BEA4202FBEAD26311123672F1E6CBD0DA429CD253E4F579D5FFECEF1DDA78D2AF6B6D8B9818E334D42DFF3F7ACAFD350421BC6C551C004FBE620D397EB602AD2CEDD0D61C9E22D622AF8197393CFEB7250F6D13CBC5CB7625242B0CD23B174F66B00BEDA0E4CB841DCED47
-20220414074823 2 6 100 3071 2 C51B2203994018FE66AF950975C59F6B678BD895CBD976250E5513528EF9B03B85B0DD85C17B519B1D41CB11CFCF86F9649C411D746E8ADA9A743D09458BE956D59D6C471945A92E1A6AD2B519D24373242BDD1A13BDE5EAE3518F17F8D2EB158F5340F76212DE07E67816FCC95EABAA1568116D400FC2EE789EB0C097AC9E94DB7B6A861F35B7F57C58934FD6034B4352F83978CB943D63921D8B29BC30A5CB5069A31F550206767EAB17FF80BD34A849F05CEA09CE2B374D70B25DFC31DD546310C948F9DAF4E0C873FA5AC0221EF1D761F581AE4C8C890FCC7D16E5A82B4DB3C9C713A3A13E8039D62AB2DC9B4AD3B1BB721D985C2DD6333E9871F5E4D76AC163D90CC629CC81783087DBC70739200FB5703FF4BEA4202FBEAD26311123672F1E6CBD0DA429CD253E4F579D5FFECEF1DDA78D2AF6B6D8B9818E334D42DFF3F7ACAFD350421BC6C551C004FBE620D397EB602AD2CEDD0D61C9E22D622AF8197393CFEB7250F6D13CBC5CB7625242B0CD23B174F66B00BEDA0E4CB842009833
-20220414074835 2 6 100 3071 2 C51B2203994018FE66AF950975C59F6B678BD895CBD976250E5513528EF9B03B85B0DD85C17B519B1D41CB11CFCF86F9649C411D746E8ADA9A743D09458BE956D59D6C471945A92E1A6AD2B519D24373242BDD1A13BDE5EAE3518F17F8D2EB158F5340F76212DE07E67816FCC95EABAA1568116D400FC2EE789EB0C097AC9E94DB7B6A861F35B7F57C58934FD6034B4352F83978CB943D63921D8B29BC30A5CB5069A31F550206767EAB17FF80BD34A849F05CEA09CE2B374D70B25DFC31DD546310C948F9DAF4E0C873FA5AC0221EF1D761F581AE4C8C890FCC7D16E5A82B4DB3C9C713A3A13E8039D62AB2DC9B4AD3B1BB721D985C2DD6333E9871F5E4D76AC163D90CC629CC81783087DBC70739200FB5703FF4BEA4202FBEAD26311123672F1E6CBD0DA429CD253E4F579D5FFECEF1DDA78D2AF6B6D8B9818E334D42DFF3F7ACAFD350421BC6C551C004FBE620D397EB602AD2CEDD0D61C9E22D622AF8197393CFEB7250F6D13CBC5CB7625242B0CD23B174F66B00BEDA0E4CB842257813
-20220414074840 2 6 100 3071 2 C51B2203994018FE66AF950975C59F6B678BD895CBD976250E5513528EF9B03B85B0DD85C17B519B1D41CB11CFCF86F9649C411D746E8ADA9A743D09458BE956D59D6C471945A92E1A6AD2B519D24373242BDD1A13BDE5EAE3518F17F8D2EB158F5340F76212DE07E67816FCC95EABAA1568116D400FC2EE789EB0C097AC9E94DB7B6A861F35B7F57C58934FD6034B4352F83978CB943D63921D8B29BC30A5CB5069A31F550206767EAB17FF80BD34A849F05CEA09CE2B374D70B25DFC31DD546310C948F9DAF4E0C873FA5AC0221EF1D761F581AE4C8C890FCC7D16E5A82B4DB3C9C713A3A13E8039D62AB2DC9B4AD3B1BB721D985C2DD6333E9871F5E4D76AC163D90CC629CC81783087DBC70739200FB5703FF4BEA4202FBEAD26311123672F1E6CBD0DA429CD253E4F579D5FFECEF1DDA78D2AF6B6D8B9818E334D42DFF3F7ACAFD350421BC6C551C004FBE620D397EB602AD2CEDD0D61C9E22D622AF8197393CFEB7250F6D13CBC5CB7625242B0CD23B174F66B00BEDA0E4CB8423357CB
-20220414074844 2 6 100 3071 2 C51B2203994018FE66AF950975C59F6B678BD895CBD976250E5513528EF9B03B85B0DD85C17B519B1D41CB11CFCF86F9649C411D746E8ADA9A743D09458BE956D59D6C471945A92E1A6AD2B519D24373242BDD1A13BDE5EAE3518F17F8D2EB158F5340F76212DE07E67816FCC95EABAA1568116D400FC2EE789EB0C097AC9E94DB7B6A861F35B7F57C58934FD6034B4352F83978CB943D63921D8B29BC30A5CB5069A31F550206767EAB17FF80BD34A849F05CEA09CE2B374D70B25DFC31DD546310C948F9DAF4E0C873FA5AC0221EF1D761F581AE4C8C890FCC7D16E5A82B4DB3C9C713A3A13E8039D62AB2DC9B4AD3B1BB721D985C2DD6333E9871F5E4D76AC163D90CC629CC81783087DBC70739200FB5703FF4BEA4202FBEAD26311123672F1E6CBD0DA429CD253E4F579D5FFECEF1DDA78D2AF6B6D8B9818E334D42DFF3F7ACAFD350421BC6C551C004FBE620D397EB602AD2CEDD0D61C9E22D622AF8197393CFEB7250F6D13CBC5CB7625242B0CD23B174F66B00BEDA0E4CB8423B8E6B
-20220414074923 2 6 100 3071 2 C51B2203994018FE66AF950975C59F6B678BD895CBD976250E5513528EF9B03B85B0DD85C17B519B1D41CB11CFCF86F9649C411D746E8ADA9A743D09458BE956D59D6C471945A92E1A6AD2B519D24373242BDD1A13BDE5EAE3518F17F8D2EB158F5340F76212DE07E67816FCC95EABAA1568116D400FC2EE789EB0C097AC9E94DB7B6A861F35B7F57C58934FD6034B4352F83978CB943D63921D8B29BC30A5CB5069A31F550206767EAB17FF80BD34A849F05CEA09CE2B374D70B25DFC31DD546310C948F9DAF4E0C873FA5AC0221EF1D761F581AE4C8C890FCC7D16E5A82B4DB3C9C713A3A13E8039D62AB2DC9B4AD3B1BB721D985C2DD6333E9871F5E4D76AC163D90CC629CC81783087DBC70739200FB5703FF4BEA4202FBEAD26311123672F1E6CBD0DA429CD253E4F579D5FFECEF1DDA78D2AF6B6D8B9818E334D42DFF3F7ACAFD350421BC6C551C004FBE620D397EB602AD2CEDD0D61C9E22D622AF8197393CFEB7250F6D13CBC5CB7625242B0CD23B174F66B00BEDA0E4CB842CB64CB
-20220414075134 2 6 100 3071 2 C51B2203994018FE66AF950975C59F6B678BD895CBD976250E5513528EF9B03B85B0DD85C17B519B1D41CB11CFCF86F9649C411D746E8ADA9A743D09458BE956D59D6C471945A92E1A6AD2B519D24373242BDD1A13BDE5EAE3518F17F8D2EB158F5340F76212DE07E67816FCC95EABAA1568116D400FC2EE789EB0C097AC9E94DB7B6A861F35B7F57C58934FD6034B4352F83978CB943D63921D8B29BC30A5CB5069A31F550206767EAB17FF80BD34A849F05CEA09CE2B374D70B25DFC31DD546310C948F9DAF4E0C873FA5AC0221EF1D761F581AE4C8C890FCC7D16E5A82B4DB3C9C713A3A13E8039D62AB2DC9B4AD3B1BB721D985C2DD6333E9871F5E4D76AC163D90CC629CC81783087DBC70739200FB5703FF4BEA4202FBEAD26311123672F1E6CBD0DA429CD253E4F579D5FFECEF1DDA78D2AF6B6D8B9818E334D42DFF3F7ACAFD350421BC6C551C004FBE620D397EB602AD2CEDD0D61C9E22D622AF8197393CFEB7250F6D13CBC5CB7625242B0CD23B174F66B00BEDA0E4CB844C6295B
-20220414075206 2 6 100 3071 2 C51B2203994018FE66AF950975C59F6B678BD895CBD976250E5513528EF9B03B85B0DD85C17B519B1D41CB11CFCF86F9649C411D746E8ADA9A743D09458BE956D59D6C471945A92E1A6AD2B519D24373242BDD1A13BDE5EAE3518F17F8D2EB158F5340F76212DE07E67816FCC95EABAA1568116D400FC2EE789EB0C097AC9E94DB7B6A861F35B7F57C58934FD6034B4352F83978CB943D63921D8B29BC30A5CB5069A31F550206767EAB17FF80BD34A849F05CEA09CE2B374D70B25DFC31DD546310C948F9DAF4E0C873FA5AC0221EF1D761F581AE4C8C890FCC7D16E5A82B4DB3C9C713A3A13E8039D62AB2DC9B4AD3B1BB721D985C2DD6333E9871F5E4D76AC163D90CC629CC81783087DBC70739200FB5703FF4BEA4202FBEAD26311123672F1E6CBD0DA429CD253E4F579D5FFECEF1DDA78D2AF6B6D8B9818E334D42DFF3F7ACAFD350421BC6C551C004FBE620D397EB602AD2CEDD0D61C9E22D622AF8197393CFEB7250F6D13CBC5CB7625242B0CD23B174F66B00BEDA0E4CB8453EA8F3
-20220414075228 2 6 100 3071 2 C51B2203994018FE66AF950975C59F6B678BD895CBD976250E5513528EF9B03B85B0DD85C17B519B1D41CB11CFCF86F9649C411D746E8ADA9A743D09458BE956D59D6C471945A92E1A6AD2B519D24373242BDD1A13BDE5EAE3518F17F8D2EB158F5340F76212DE07E67816FCC95EABAA1568116D400FC2EE789EB0C097AC9E94DB7B6A861F35B7F57C58934FD6034B4352F83978CB943D63921D8B29BC30A5CB5069A31F550206767EAB17FF80BD34A849F05CEA09CE2B374D70B25DFC31DD546310C948F9DAF4E0C873FA5AC0221EF1D761F581AE4C8C890FCC7D16E5A82B4DB3C9C713A3A13E8039D62AB2DC9B4AD3B1BB721D985C2DD6333E9871F5E4D76AC163D90CC629CC81783087DBC70739200FB5703FF4BEA4202FBEAD26311123672F1E6CBD0DA429CD253E4F579D5FFECEF1DDA78D2AF6B6D8B9818E334D42DFF3F7ACAFD350421BC6C551C004FBE620D397EB602AD2CEDD0D61C9E22D622AF8197393CFEB7250F6D13CBC5CB7625242B0CD23B174F66B00BEDA0E4CB8458F2F8B
-20220414075251 2 6 100 3071 5 C51B2203994018FE66AF950975C59F6B678BD895CBD976250E5513528EF9B03B85B0DD85C17B519B1D41CB11CFCF86F9649C411D746E8ADA9A743D09458BE956D59D6C471945A92E1A6AD2B519D24373242BDD1A13BDE5EAE3518F17F8D2EB158F5340F76212DE07E67816FCC95EABAA1568116D400FC2EE789EB0C097AC9E94DB7B6A861F35B7F57C58934FD6034B4352F83978CB943D63921D8B29BC30A5CB5069A31F550206767EAB17FF80BD34A849F05CEA09CE2B374D70B25DFC31DD546310C948F9DAF4E0C873FA5AC0221EF1D761F581AE4C8C890FCC7D16E5A82B4DB3C9C713A3A13E8039D62AB2DC9B4AD3B1BB721D985C2DD6333E9871F5E4D76AC163D90CC629CC81783087DBC70739200FB5703FF4BEA4202FBEAD26311123672F1E6CBD0DA429CD253E4F579D5FFECEF1DDA78D2AF6B6D8B9818E334D42DFF3F7ACAFD350421BC6C551C004FBE620D397EB602AD2CEDD0D61C9E22D622AF8197393CFEB7250F6D13CBC5CB7625242B0CD23B174F66B00BEDA0E4CB845E71A57
-20220414075317 2 6 100 3071 5 C51B2203994018FE66AF950975C59F6B678BD895CBD976250E5513528EF9B03B85B0DD85C17B519B1D41CB11CFCF86F9649C411D746E8ADA9A743D09458BE956D59D6C471945A92E1A6AD2B519D24373242BDD1A13BDE5EAE3518F17F8D2EB158F5340F76212DE07E67816FCC95EABAA1568116D400FC2EE789EB0C097AC9E94DB7B6A861F35B7F57C58934FD6034B4352F83978CB943D63921D8B29BC30A5CB5069A31F550206767EAB17FF80BD34A849F05CEA09CE2B374D70B25DFC31DD546310C948F9DAF4E0C873FA5AC0221EF1D761F581AE4C8C890FCC7D16E5A82B4DB3C9C713A3A13E8039D62AB2DC9B4AD3B1BB721D985C2DD6333E9871F5E4D76AC163D90CC629CC81783087DBC70739200FB5703FF4BEA4202FBEAD26311123672F1E6CBD0DA429CD253E4F579D5FFECEF1DDA78D2AF6B6D8B9818E334D42DFF3F7ACAFD350421BC6C551C004FBE620D397EB602AD2CEDD0D61C9E22D622AF8197393CFEB7250F6D13CBC5CB7625242B0CD23B174F66B00BEDA0E4CB84648C5EF
-20220414075352 2 6 100 3071 5 C51B2203994018FE66AF950975C59F6B678BD895CBD976250E5513528EF9B03B85B0DD85C17B519B1D41CB11CFCF86F9649C411D746E8ADA9A743D09458BE956D59D6C471945A92E1A6AD2B519D24373242BDD1A13BDE5EAE3518F17F8D2EB158F5340F76212DE07E67816FCC95EABAA1568116D400FC2EE789EB0C097AC9E94DB7B6A861F35B7F57C58934FD6034B4352F83978CB943D63921D8B29BC30A5CB5069A31F550206767EAB17FF80BD34A849F05CEA09CE2B374D70B25DFC31DD546310C948F9DAF4E0C873FA5AC0221EF1D761F581AE4C8C890FCC7D16E5A82B4DB3C9C713A3A13E8039D62AB2DC9B4AD3B1BB721D985C2DD6333E9871F5E4D76AC163D90CC629CC81783087DBC70739200FB5703FF4BEA4202FBEAD26311123672F1E6CBD0DA429CD253E4F579D5FFECEF1DDA78D2AF6B6D8B9818E334D42DFF3F7ACAFD350421BC6C551C004FBE620D397EB602AD2CEDD0D61C9E22D622AF8197393CFEB7250F6D13CBC5CB7625242B0CD23B174F66B00BEDA0E4CB846C72BBF
-20220414075450 2 6 100 3071 5 C51B2203994018FE66AF950975C59F6B678BD895CBD976250E5513528EF9B03B85B0DD85C17B519B1D41CB11CFCF86F9649C411D746E8ADA9A743D09458BE956D59D6C471945A92E1A6AD2B519D24373242BDD1A13BDE5EAE3518F17F8D2EB158F5340F76212DE07E67816FCC95EABAA1568116D400FC2EE789EB0C097AC9E94DB7B6A861F35B7F57C58934FD6034B4352F83978CB943D63921D8B29BC30A5CB5069A31F550206767EAB17FF80BD34A849F05CEA09CE2B374D70B25DFC31DD546310C948F9DAF4E0C873FA5AC0221EF1D761F581AE4C8C890FCC7D16E5A82B4DB3C9C713A3A13E8039D62AB2DC9B4AD3B1BB721D985C2DD6333E9871F5E4D76AC163D90CC629CC81783087DBC70739200FB5703FF4BEA4202FBEAD26311123672F1E6CBD0DA429CD253E4F579D5FFECEF1DDA78D2AF6B6D8B9818E334D42DFF3F7ACAFD350421BC6C551C004FBE620D397EB602AD2CEDD0D61C9E22D622AF8197393CFEB7250F6D13CBC5CB7625242B0CD23B174F66B00BEDA0E4CB847A0F4F7
-20220414075521 2 6 100 3071 2 C51B2203994018FE66AF950975C59F6B678BD895CBD976250E5513528EF9B03B85B0DD85C17B519B1D41CB11CFCF86F9649C411D746E8ADA9A743D09458BE956D59D6C471945A92E1A6AD2B519D24373242BDD1A13BDE5EAE3518F17F8D2EB158F5340F76212DE07E67816FCC95EABAA1568116D400FC2EE789EB0C097AC9E94DB7B6A861F35B7F57C58934FD6034B4352F83978CB943D63921D8B29BC30A5CB5069A31F550206767EAB17FF80BD34A849F05CEA09CE2B374D70B25DFC31DD546310C948F9DAF4E0C873FA5AC0221EF1D761F581AE4C8C890FCC7D16E5A82B4DB3C9C713A3A13E8039D62AB2DC9B4AD3B1BB721D985C2DD6333E9871F5E4D76AC163D90CC629CC81783087DBC70739200FB5703FF4BEA4202FBEAD26311123672F1E6CBD0DA429CD253E4F579D5FFECEF1DDA78D2AF6B6D8B9818E334D42DFF3F7ACAFD350421BC6C551C004FBE620D397EB602AD2CEDD0D61C9E22D622AF8197393CFEB7250F6D13CBC5CB7625242B0CD23B174F66B00BEDA0E4CB84817FBD3
-20220414075541 2 6 100 3071 5 C51B2203994018FE66AF950975C59F6B678BD895CBD976250E5513528EF9B03B85B0DD85C17B519B1D41CB11CFCF86F9649C411D746E8ADA9A743D09458BE956D59D6C471945A92E1A6AD2B519D24373242BDD1A13BDE5EAE3518F17F8D2EB158F5340F76212DE07E67816FCC95EABAA1568116D400FC2EE789EB0C097AC9E94DB7B6A861F35B7F57C58934FD6034B4352F83978CB943D63921D8B29BC30A5CB5069A31F550206767EAB17FF80BD34A849F05CEA09CE2B374D70B25DFC31DD546310C948F9DAF4E0C873FA5AC0221EF1D761F581AE4C8C890FCC7D16E5A82B4DB3C9C713A3A13E8039D62AB2DC9B4AD3B1BB721D985C2DD6333E9871F5E4D76AC163D90CC629CC81783087DBC70739200FB5703FF4BEA4202FBEAD26311123672F1E6CBD0DA429CD253E4F579D5FFECEF1DDA78D2AF6B6D8B9818E334D42DFF3F7ACAFD350421BC6C551C004FBE620D397EB602AD2CEDD0D61C9E22D622AF8197393CFEB7250F6D13CBC5CB7625242B0CD23B174F66B00BEDA0E4CB84866A397
-20220414075556 2 6 100 3071 5 C51B2203994018FE66AF950975C59F6B678BD895CBD976250E5513528EF9B03B85B0DD85C17B519B1D41CB11CFCF86F9649C411D746E8ADA9A743D09458BE956D59D6C471945A92E1A6AD2B519D24373242BDD1A13BDE5EAE3518F17F8D2EB158F5340F76212DE07E67816FCC95EABAA1568116D400FC2EE789EB0C097AC9E94DB7B6A861F35B7F57C58934FD6034B4352F83978CB943D63921D8B29BC30A5CB5069A31F550206767EAB17FF80BD34A849F05CEA09CE2B374D70B25DFC31DD546310C948F9DAF4E0C873FA5AC0221EF1D761F581AE4C8C890FCC7D16E5A82B4DB3C9C713A3A13E8039D62AB2DC9B4AD3B1BB721D985C2DD6333E9871F5E4D76AC163D90CC629CC81783087DBC70739200FB5703FF4BEA4202FBEAD26311123672F1E6CBD0DA429CD253E4F579D5FFECEF1DDA78D2AF6B6D8B9818E334D42DFF3F7ACAFD350421BC6C551C004FBE620D397EB602AD2CEDD0D61C9E22D622AF8197393CFEB7250F6D13CBC5CB7625242B0CD23B174F66B00BEDA0E4CB8489919F7
-20220414075630 2 6 100 3071 2 C51B2203994018FE66AF950975C59F6B678BD895CBD976250E5513528EF9B03B85B0DD85C17B519B1D41CB11CFCF86F9649C411D746E8ADA9A743D09458BE956D59D6C471945A92E1A6AD2B519D24373242BDD1A13BDE5EAE3518F17F8D2EB158F5340F76212DE07E67816FCC95EABAA1568116D400FC2EE789EB0C097AC9E94DB7B6A861F35B7F57C58934FD6034B4352F83978CB943D63921D8B29BC30A5CB5069A31F550206767EAB17FF80BD34A849F05CEA09CE2B374D70B25DFC31DD546310C948F9DAF4E0C873FA5AC0221EF1D761F581AE4C8C890FCC7D16E5A82B4DB3C9C713A3A13E8039D62AB2DC9B4AD3B1BB721D985C2DD6333E9871F5E4D76AC163D90CC629CC81783087DBC70739200FB5703FF4BEA4202FBEAD26311123672F1E6CBD0DA429CD253E4F579D5FFECEF1DDA78D2AF6B6D8B9818E334D42DFF3F7ACAFD350421BC6C551C004FBE620D397EB602AD2CEDD0D61C9E22D622AF8197393CFEB7250F6D13CBC5CB7625242B0CD23B174F66B00BEDA0E4CB84916DB03
-20220414075833 2 6 100 3071 2 C51B2203994018FE66AF950975C59F6B678BD895CBD976250E5513528EF9B03B85B0DD85C17B519B1D41CB11CFCF86F9649C411D746E8ADA9A743D09458BE956D59D6C471945A92E1A6AD2B519D24373242BDD1A13BDE5EAE3518F17F8D2EB158F5340F76212DE07E67816FCC95EABAA1568116D400FC2EE789EB0C097AC9E94DB7B6A861F35B7F57C58934FD6034B4352F83978CB943D63921D8B29BC30A5CB5069A31F550206767EAB17FF80BD34A849F05CEA09CE2B374D70B25DFC31DD546310C948F9DAF4E0C873FA5AC0221EF1D761F581AE4C8C890FCC7D16E5A82B4DB3C9C713A3A13E8039D62AB2DC9B4AD3B1BB721D985C2DD6333E9871F5E4D76AC163D90CC629CC81783087DBC70739200FB5703FF4BEA4202FBEAD26311123672F1E6CBD0DA429CD253E4F579D5FFECEF1DDA78D2AF6B6D8B9818E334D42DFF3F7ACAFD350421BC6C551C004FBE620D397EB602AD2CEDD0D61C9E22D622AF8197393CFEB7250F6D13CBC5CB7625242B0CD23B174F66B00BEDA0E4CB84AFEC0BB
-20220414075927 2 6 100 3071 5 F5A593C9AFA507A500AC0F2C6389F394E8818163FA32B928AC5A46FBC5556CFC88FC789A9EE0E99C002FC4E3DABCAA2BF268FD7FB49A26E986A300CAEEED3C55E43DD1681074B52C4DB264879CE4B96F2CBB172EBBEE34A7E87CC3818AB3E6AAF135C7CDB655F220B93C32B2CB69F538CCE40AF86994CB6D80D0456B3CAA38C46B0D09C0D26C8E67D4EE6E4FE219AC92FF244216E6DCB4267C0DA00E906730792FA9BDA189B9CE5D552B04F1314418936BF02B08FE3AC2033A6B17DF3956D1316FAA6347FD940DDA68FB8AAE1B42E225B2CB8C81BA82DD05A0284F4C08DA48B991DFC1DD08E8ED02AA3FAF82E34CAC009930DDA85040A5D380F8B9B79F69F46D860319636C5931E1C25EF07F5B3D9964ED066E8E0D1C9E73121907C3A27EDCDDBD231B0BAEB124C13F1EBAC60035DE0017D5B0DABA74763096E26F7C9A7394B73BB65A7733F2A69FA6B0D8543CE3D98C083DE93B48BF974556CE3B0230DE2B13D4BA011DB8272BA6DDAF54E0E26E10180C03397156FFCAE19A95ABA416BC45B7
-20220414075956 2 6 100 3071 5 F5A593C9AFA507A500AC0F2C6389F394E8818163FA32B928AC5A46FBC5556CFC88FC789A9EE0E99C002FC4E3DABCAA2BF268FD7FB49A26E986A300CAEEED3C55E43DD1681074B52C4DB264879CE4B96F2CBB172EBBEE34A7E87CC3818AB3E6AAF135C7CDB655F220B93C32B2CB69F538CCE40AF86994CB6D80D0456B3CAA38C46B0D09C0D26C8E67D4EE6E4FE219AC92FF244216E6DCB4267C0DA00E906730792FA9BDA189B9CE5D552B04F1314418936BF02B08FE3AC2033A6B17DF3956D1316FAA6347FD940DDA68FB8AAE1B42E225B2CB8C81BA82DD05A0284F4C08DA48B991DFC1DD08E8ED02AA3FAF82E34CAC009930DDA85040A5D380F8B9B79F69F46D860319636C5931E1C25EF07F5B3D9964ED066E8E0D1C9E73121907C3A27EDCDDBD231B0BAEB124C13F1EBAC60035DE0017D5B0DABA74763096E26F7C9A7394B73BB65A7733F2A69FA6B0D8543CE3D98C083DE93B48BF974556CE3B0230DE2B13D4BA011DB8272BA6DDAF54E0E26E10180C03397156FFCAE19A95ABA4172ADEAF
-20220414080014 2 6 100 3071 2 F5A593C9AFA507A500AC0F2C6389F394E8818163FA32B928AC5A46FBC5556CFC88FC789A9EE0E99C002FC4E3DABCAA2BF268FD7FB49A26E986A300CAEEED3C55E43DD1681074B52C4DB264879CE4B96F2CBB172EBBEE34A7E87CC3818AB3E6AAF135C7CDB655F220B93C32B2CB69F538CCE40AF86994CB6D80D0456B3CAA38C46B0D09C0D26C8E67D4EE6E4FE219AC92FF244216E6DCB4267C0DA00E906730792FA9BDA189B9CE5D552B04F1314418936BF02B08FE3AC2033A6B17DF3956D1316FAA6347FD940DDA68FB8AAE1B42E225B2CB8C81BA82DD05A0284F4C08DA48B991DFC1DD08E8ED02AA3FAF82E34CAC009930DDA85040A5D380F8B9B79F69F46D860319636C5931E1C25EF07F5B3D9964ED066E8E0D1C9E73121907C3A27EDCDDBD231B0BAEB124C13F1EBAC60035DE0017D5B0DABA74763096E26F7C9A7394B73BB65A7733F2A69FA6B0D8543CE3D98C083DE93B48BF974556CE3B0230DE2B13D4BA011DB8272BA6DDAF54E0E26E10180C03397156FFCAE19A95ABA4176C3D1B
-20220414080031 2 6 100 3071 5 F5A593C9AFA507A500AC0F2C6389F394E8818163FA32B928AC5A46FBC5556CFC88FC789A9EE0E99C002FC4E3DABCAA2BF268FD7FB49A26E986A300CAEEED3C55E43DD1681074B52C4DB264879CE4B96F2CBB172EBBEE34A7E87CC3818AB3E6AAF135C7CDB655F220B93C32B2CB69F538CCE40AF86994CB6D80D0456B3CAA38C46B0D09C0D26C8E67D4EE6E4FE219AC92FF244216E6DCB4267C0DA00E906730792FA9BDA189B9CE5D552B04F1314418936BF02B08FE3AC2033A6B17DF3956D1316FAA6347FD940DDA68FB8AAE1B42E225B2CB8C81BA82DD05A0284F4C08DA48B991DFC1DD08E8ED02AA3FAF82E34CAC009930DDA85040A5D380F8B9B79F69F46D860319636C5931E1C25EF07F5B3D9964ED066E8E0D1C9E73121907C3A27EDCDDBD231B0BAEB124C13F1EBAC60035DE0017D5B0DABA74763096E26F7C9A7394B73BB65A7733F2A69FA6B0D8543CE3D98C083DE93B48BF974556CE3B0230DE2B13D4BA011DB8272BA6DDAF54E0E26E10180C03397156FFCAE19A95ABA417A81CB7
-20220414080111 2 6 100 3071 2 F5A593C9AFA507A500AC0F2C6389F394E8818163FA32B928AC5A46FBC5556CFC88FC789A9EE0E99C002FC4E3DABCAA2BF268FD7FB49A26E986A300CAEEED3C55E43DD1681074B52C4DB264879CE4B96F2CBB172EBBEE34A7E87CC3818AB3E6AAF135C7CDB655F220B93C32B2CB69F538CCE40AF86994CB6D80D0456B3CAA38C46B0D09C0D26C8E67D4EE6E4FE219AC92FF244216E6DCB4267C0DA00E906730792FA9BDA189B9CE5D552B04F1314418936BF02B08FE3AC2033A6B17DF3956D1316FAA6347FD940DDA68FB8AAE1B42E225B2CB8C81BA82DD05A0284F4C08DA48B991DFC1DD08E8ED02AA3FAF82E34CAC009930DDA85040A5D380F8B9B79F69F46D860319636C5931E1C25EF07F5B3D9964ED066E8E0D1C9E73121907C3A27EDCDDBD231B0BAEB124C13F1EBAC60035DE0017D5B0DABA74763096E26F7C9A7394B73BB65A7733F2A69FA6B0D8543CE3D98C083DE93B48BF974556CE3B0230DE2B13D4BA011DB8272BA6DDAF54E0E26E10180C03397156FFCAE19A95ABA41846F30B
-20220414080114 2 6 100 3071 2 F5A593C9AFA507A500AC0F2C6389F394E8818163FA32B928AC5A46FBC5556CFC88FC789A9EE0E99C002FC4E3DABCAA2BF268FD7FB49A26E986A300CAEEED3C55E43DD1681074B52C4DB264879CE4B96F2CBB172EBBEE34A7E87CC3818AB3E6AAF135C7CDB655F220B93C32B2CB69F538CCE40AF86994CB6D80D0456B3CAA38C46B0D09C0D26C8E67D4EE6E4FE219AC92FF244216E6DCB4267C0DA00E906730792FA9BDA189B9CE5D552B04F1314418936BF02B08FE3AC2033A6B17DF3956D1316FAA6347FD940DDA68FB8AAE1B42E225B2CB8C81BA82DD05A0284F4C08DA48B991DFC1DD08E8ED02AA3FAF82E34CAC009930DDA85040A5D380F8B9B79F69F46D860319636C5931E1C25EF07F5B3D9964ED066E8E0D1C9E73121907C3A27EDCDDBD231B0BAEB124C13F1EBAC60035DE0017D5B0DABA74763096E26F7C9A7394B73BB65A7733F2A69FA6B0D8543CE3D98C083DE93B48BF974556CE3B0230DE2B13D4BA011DB8272BA6DDAF54E0E26E10180C03397156FFCAE19A95ABA4184B28B3
-20220414080215 2 6 100 3071 5 F5A593C9AFA507A500AC0F2C6389F394E8818163FA32B928AC5A46FBC5556CFC88FC789A9EE0E99C002FC4E3DABCAA2BF268FD7FB49A26E986A300CAEEED3C55E43DD1681074B52C4DB264879CE4B96F2CBB172EBBEE34A7E87CC3818AB3E6AAF135C7CDB655F220B93C32B2CB69F538CCE40AF86994CB6D80D0456B3CAA38C46B0D09C0D26C8E67D4EE6E4FE219AC92FF244216E6DCB4267C0DA00E906730792FA9BDA189B9CE5D552B04F1314418936BF02B08FE3AC2033A6B17DF3956D1316FAA6347FD940DDA68FB8AAE1B42E225B2CB8C81BA82DD05A0284F4C08DA48B991DFC1DD08E8ED02AA3FAF82E34CAC009930DDA85040A5D380F8B9B79F69F46D860319636C5931E1C25EF07F5B3D9964ED066E8E0D1C9E73121907C3A27EDCDDBD231B0BAEB124C13F1EBAC60035DE0017D5B0DABA74763096E26F7C9A7394B73BB65A7733F2A69FA6B0D8543CE3D98C083DE93B48BF974556CE3B0230DE2B13D4BA011DB8272BA6DDAF54E0E26E10180C03397156FFCAE19A95ABA4193CE3E7
-20220414080230 2 6 100 3071 2 F5A593C9AFA507A500AC0F2C6389F394E8818163FA32B928AC5A46FBC5556CFC88FC789A9EE0E99C002FC4E3DABCAA2BF268FD7FB49A26E986A300CAEEED3C55E43DD1681074B52C4DB264879CE4B96F2CBB172EBBEE34A7E87CC3818AB3E6AAF135C7CDB655F220B93C32B2CB69F538CCE40AF86994CB6D80D0456B3CAA38C46B0D09C0D26C8E67D4EE6E4FE219AC92FF244216E6DCB4267C0DA00E906730792FA9BDA189B9CE5D552B04F1314418936BF02B08FE3AC2033A6B17DF3956D1316FAA6347FD940DDA68FB8AAE1B42E225B2CB8C81BA82DD05A0284F4C08DA48B991DFC1DD08E8ED02AA3FAF82E34CAC009930DDA85040A5D380F8B9B79F69F46D860319636C5931E1C25EF07F5B3D9964ED066E8E0D1C9E73121907C3A27EDCDDBD231B0BAEB124C13F1EBAC60035DE0017D5B0DABA74763096E26F7C9A7394B73BB65A7733F2A69FA6B0D8543CE3D98C083DE93B48BF974556CE3B0230DE2B13D4BA011DB8272BA6DDAF54E0E26E10180C03397156FFCAE19A95ABA41972BB5B
-20220414080234 2 6 100 3071 2 F5A593C9AFA507A500AC0F2C6389F394E8818163FA32B928AC5A46FBC5556CFC88FC789A9EE0E99C002FC4E3DABCAA2BF268FD7FB49A26E986A300CAEEED3C55E43DD1681074B52C4DB264879CE4B96F2CBB172EBBEE34A7E87CC3818AB3E6AAF135C7CDB655F220B93C32B2CB69F538CCE40AF86994CB6D80D0456B3CAA38C46B0D09C0D26C8E67D4EE6E4FE219AC92FF244216E6DCB4267C0DA00E906730792FA9BDA189B9CE5D552B04F1314418936BF02B08FE3AC2033A6B17DF3956D1316FAA6347FD940DDA68FB8AAE1B42E225B2CB8C81BA82DD05A0284F4C08DA48B991DFC1DD08E8ED02AA3FAF82E34CAC009930DDA85040A5D380F8B9B79F69F46D860319636C5931E1C25EF07F5B3D9964ED066E8E0D1C9E73121907C3A27EDCDDBD231B0BAEB124C13F1EBAC60035DE0017D5B0DABA74763096E26F7C9A7394B73BB65A7733F2A69FA6B0D8543CE3D98C083DE93B48BF974556CE3B0230DE2B13D4BA011DB8272BA6DDAF54E0E26E10180C03397156FFCAE19A95ABA4197B2B2B
-20220414080256 2 6 100 3071 5 F5A593C9AFA507A500AC0F2C6389F394E8818163FA32B928AC5A46FBC5556CFC88FC789A9EE0E99C002FC4E3DABCAA2BF268FD7FB49A26E986A300CAEEED3C55E43DD1681074B52C4DB264879CE4B96F2CBB172EBBEE34A7E87CC3818AB3E6AAF135C7CDB655F220B93C32B2CB69F538CCE40AF86994CB6D80D0456B3CAA38C46B0D09C0D26C8E67D4EE6E4FE219AC92FF244216E6DCB4267C0DA00E906730792FA9BDA189B9CE5D552B04F1314418936BF02B08FE3AC2033A6B17DF3956D1316FAA6347FD940DDA68FB8AAE1B42E225B2CB8C81BA82DD05A0284F4C08DA48B991DFC1DD08E8ED02AA3FAF82E34CAC009930DDA85040A5D380F8B9B79F69F46D860319636C5931E1C25EF07F5B3D9964ED066E8E0D1C9E73121907C3A27EDCDDBD231B0BAEB124C13F1EBAC60035DE0017D5B0DABA74763096E26F7C9A7394B73BB65A7733F2A69FA6B0D8543CE3D98C083DE93B48BF974556CE3B0230DE2B13D4BA011DB8272BA6DDAF54E0E26E10180C03397156FFCAE19A95ABA419CEB82F
-20220414080413 2 6 100 3071 5 F5A593C9AFA507A500AC0F2C6389F394E8818163FA32B928AC5A46FBC5556CFC88FC789A9EE0E99C002FC4E3DABCAA2BF268FD7FB49A26E986A300CAEEED3C55E43DD1681074B52C4DB264879CE4B96F2CBB172EBBEE34A7E87CC3818AB3E6AAF135C7CDB655F220B93C32B2CB69F538CCE40AF86994CB6D80D0456B3CAA38C46B0D09C0D26C8E67D4EE6E4FE219AC92FF244216E6DCB4267C0DA00E906730792FA9BDA189B9CE5D552B04F1314418936BF02B08FE3AC2033A6B17DF3956D1316FAA6347FD940DDA68FB8AAE1B42E225B2CB8C81BA82DD05A0284F4C08DA48B991DFC1DD08E8ED02AA3FAF82E34CAC009930DDA85040A5D380F8B9B79F69F46D860319636C5931E1C25EF07F5B3D9964ED066E8E0D1C9E73121907C3A27EDCDDBD231B0BAEB124C13F1EBAC60035DE0017D5B0DABA74763096E26F7C9A7394B73BB65A7733F2A69FA6B0D8543CE3D98C083DE93B48BF974556CE3B0230DE2B13D4BA011DB8272BA6DDAF54E0E26E10180C03397156FFCAE19A95ABA41B04B177
-20220414080440 2 6 100 3071 5 F5A593C9AFA507A500AC0F2C6389F394E8818163FA32B928AC5A46FBC5556CFC88FC789A9EE0E99C002FC4E3DABCAA2BF268FD7FB49A26E986A300CAEEED3C55E43DD1681074B52C4DB264879CE4B96F2CBB172EBBEE34A7E87CC3818AB3E6AAF135C7CDB655F220B93C32B2CB69F538CCE40AF86994CB6D80D0456B3CAA38C46B0D09C0D26C8E67D4EE6E4FE219AC92FF244216E6DCB4267C0DA00E906730792FA9BDA189B9CE5D552B04F1314418936BF02B08FE3AC2033A6B17DF3956D1316FAA6347FD940DDA68FB8AAE1B42E225B2CB8C81BA82DD05A0284F4C08DA48B991DFC1DD08E8ED02AA3FAF82E34CAC009930DDA85040A5D380F8B9B79F69F46D860319636C5931E1C25EF07F5B3D9964ED066E8E0D1C9E73121907C3A27EDCDDBD231B0BAEB124C13F1EBAC60035DE0017D5B0DABA74763096E26F7C9A7394B73BB65A7733F2A69FA6B0D8543CE3D98C083DE93B48BF974556CE3B0230DE2B13D4BA011DB8272BA6DDAF54E0E26E10180C03397156FFCAE19A95ABA41B6F0F87
-20220414080455 2 6 100 3071 2 F5A593C9AFA507A500AC0F2C6389F394E8818163FA32B928AC5A46FBC5556CFC88FC789A9EE0E99C002FC4E3DABCAA2BF268FD7FB49A26E986A300CAEEED3C55E43DD1681074B52C4DB264879CE4B96F2CBB172EBBEE34A7E87CC3818AB3E6AAF135C7CDB655F220B93C32B2CB69F538CCE40AF86994CB6D80D0456B3CAA38C46B0D09C0D26C8E67D4EE6E4FE219AC92FF244216E6DCB4267C0DA00E906730792FA9BDA189B9CE5D552B04F1314418936BF02B08FE3AC2033A6B17DF3956D1316FAA6347FD940DDA68FB8AAE1B42E225B2CB8C81BA82DD05A0284F4C08DA48B991DFC1DD08E8ED02AA3FAF82E34CAC009930DDA85040A5D380F8B9B79F69F46D860319636C5931E1C25EF07F5B3D9964ED066E8E0D1C9E73121907C3A27EDCDDBD231B0BAEB124C13F1EBAC60035DE0017D5B0DABA74763096E26F7C9A7394B73BB65A7733F2A69FA6B0D8543CE3D98C083DE93B48BF974556CE3B0230DE2B13D4BA011DB8272BA6DDAF54E0E26E10180C03397156FFCAE19A95ABA41BA8FF03
-20220414080531 2 6 100 3071 5 F5A593C9AFA507A500AC0F2C6389F394E8818163FA32B928AC5A46FBC5556CFC88FC789A9EE0E99C002FC4E3DABCAA2BF268FD7FB49A26E986A300CAEEED3C55E43DD1681074B52C4DB264879CE4B96F2CBB172EBBEE34A7E87CC3818AB3E6AAF135C7CDB655F220B93C32B2CB69F538CCE40AF86994CB6D80D0456B3CAA38C46B0D09C0D26C8E67D4EE6E4FE219AC92FF244216E6DCB4267C0DA00E906730792FA9BDA189B9CE5D552B04F1314418936BF02B08FE3AC2033A6B17DF3956D1316FAA6347FD940DDA68FB8AAE1B42E225B2CB8C81BA82DD05A0284F4C08DA48B991DFC1DD08E8ED02AA3FAF82E34CAC009930DDA85040A5D380F8B9B79F69F46D860319636C5931E1C25EF07F5B3D9964ED066E8E0D1C9E73121907C3A27EDCDDBD231B0BAEB124C13F1EBAC60035DE0017D5B0DABA74763096E26F7C9A7394B73BB65A7733F2A69FA6B0D8543CE3D98C083DE93B48BF974556CE3B0230DE2B13D4BA011DB8272BA6DDAF54E0E26E10180C03397156FFCAE19A95ABA41C38E9AF
-20220414080538 2 6 100 3071 5 F5A593C9AFA507A500AC0F2C6389F394E8818163FA32B928AC5A46FBC5556CFC88FC789A9EE0E99C002FC4E3DABCAA2BF268FD7FB49A26E986A300CAEEED3C55E43DD1681074B52C4DB264879CE4B96F2CBB172EBBEE34A7E87CC3818AB3E6AAF135C7CDB655F220B93C32B2CB69F538CCE40AF86994CB6D80D0456B3CAA38C46B0D09C0D26C8E67D4EE6E4FE219AC92FF244216E6DCB4267C0DA00E906730792FA9BDA189B9CE5D552B04F1314418936BF02B08FE3AC2033A6B17DF3956D1316FAA6347FD940DDA68FB8AAE1B42E225B2CB8C81BA82DD05A0284F4C08DA48B991DFC1DD08E8ED02AA3FAF82E34CAC009930DDA85040A5D380F8B9B79F69F46D860319636C5931E1C25EF07F5B3D9964ED066E8E0D1C9E73121907C3A27EDCDDBD231B0BAEB124C13F1EBAC60035DE0017D5B0DABA74763096E26F7C9A7394B73BB65A7733F2A69FA6B0D8543CE3D98C083DE93B48BF974556CE3B0230DE2B13D4BA011DB8272BA6DDAF54E0E26E10180C03397156FFCAE19A95ABA41C4CE0D7
-20220414080549 2 6 100 3071 5 F5A593C9AFA507A500AC0F2C6389F394E8818163FA32B928AC5A46FBC5556CFC88FC789A9EE0E99C002FC4E3DABCAA2BF268FD7FB49A26E986A300CAEEED3C55E43DD1681074B52C4DB264879CE4B96F2CBB172EBBEE34A7E87CC3818AB3E6AAF135C7CDB655F220B93C32B2CB69F538CCE40AF86994CB6D80D0456B3CAA38C46B0D09C0D26C8E67D4EE6E4FE219AC92FF244216E6DCB4267C0DA00E906730792FA9BDA189B9CE5D552B04F1314418936BF02B08FE3AC2033A6B17DF3956D1316FAA6347FD940DDA68FB8AAE1B42E225B2CB8C81BA82DD05A0284F4C08DA48B991DFC1DD08E8ED02AA3FAF82E34CAC009930DDA85040A5D380F8B9B79F69F46D860319636C5931E1C25EF07F5B3D9964ED066E8E0D1C9E73121907C3A27EDCDDBD231B0BAEB124C13F1EBAC60035DE0017D5B0DABA74763096E26F7C9A7394B73BB65A7733F2A69FA6B0D8543CE3D98C083DE93B48BF974556CE3B0230DE2B13D4BA011DB8272BA6DDAF54E0E26E10180C03397156FFCAE19A95ABA41C714107
-20220414080559 2 6 100 3071 5 F5A593C9AFA507A500AC0F2C6389F394E8818163FA32B928AC5A46FBC5556CFC88FC789A9EE0E99C002FC4E3DABCAA2BF268FD7FB49A26E986A300CAEEED3C55E43DD1681074B52C4DB264879CE4B96F2CBB172EBBEE34A7E87CC3818AB3E6AAF135C7CDB655F220B93C32B2CB69F538CCE40AF86994CB6D80D0456B3CAA38C46B0D09C0D26C8E67D4EE6E4FE219AC92FF244216E6DCB4267C0DA00E906730792FA9BDA189B9CE5D552B04F1314418936BF02B08FE3AC2033A6B17DF3956D1316FAA6347FD940DDA68FB8AAE1B42E225B2CB8C81BA82DD05A0284F4C08DA48B991DFC1DD08E8ED02AA3FAF82E34CAC009930DDA85040A5D380F8B9B79F69F46D860319636C5931E1C25EF07F5B3D9964ED066E8E0D1C9E73121907C3A27EDCDDBD231B0BAEB124C13F1EBAC60035DE0017D5B0DABA74763096E26F7C9A7394B73BB65A7733F2A69FA6B0D8543CE3D98C083DE93B48BF974556CE3B0230DE2B13D4BA011DB8272BA6DDAF54E0E26E10180C03397156FFCAE19A95ABA41C93CC8F
-20220414080612 2 6 100 3071 2 F5A593C9AFA507A500AC0F2C6389F394E8818163FA32B928AC5A46FBC5556CFC88FC789A9EE0E99C002FC4E3DABCAA2BF268FD7FB49A26E986A300CAEEED3C55E43DD1681074B52C4DB264879CE4B96F2CBB172EBBEE34A7E87CC3818AB3E6AAF135C7CDB655F220B93C32B2CB69F538CCE40AF86994CB6D80D0456B3CAA38C46B0D09C0D26C8E67D4EE6E4FE219AC92FF244216E6DCB4267C0DA00E906730792FA9BDA189B9CE5D552B04F1314418936BF02B08FE3AC2033A6B17DF3956D1316FAA6347FD940DDA68FB8AAE1B42E225B2CB8C81BA82DD05A0284F4C08DA48B991DFC1DD08E8ED02AA3FAF82E34CAC009930DDA85040A5D380F8B9B79F69F46D860319636C5931E1C25EF07F5B3D9964ED066E8E0D1C9E73121907C3A27EDCDDBD231B0BAEB124C13F1EBAC60035DE0017D5B0DABA74763096E26F7C9A7394B73BB65A7733F2A69FA6B0D8543CE3D98C083DE93B48BF974556CE3B0230DE2B13D4BA011DB8272BA6DDAF54E0E26E10180C03397156FFCAE19A95ABA41CC0E6F3
-20220414080632 2 6 100 3071 5 F5A593C9AFA507A500AC0F2C6389F394E8818163FA32B928AC5A46FBC5556CFC88FC789A9EE0E99C002FC4E3DABCAA2BF268FD7FB49A26E986A300CAEEED3C55E43DD1681074B52C4DB264879CE4B96F2CBB172EBBEE34A7E87CC3818AB3E6AAF135C7CDB655F220B93C32B2CB69F538CCE40AF86994CB6D80D0456B3CAA38C46B0D09C0D26C8E67D4EE6E4FE219AC92FF244216E6DCB4267C0DA00E906730792FA9BDA189B9CE5D552B04F1314418936BF02B08FE3AC2033A6B17DF3956D1316FAA6347FD940DDA68FB8AAE1B42E225B2CB8C81BA82DD05A0284F4C08DA48B991DFC1DD08E8ED02AA3FAF82E34CAC009930DDA85040A5D380F8B9B79F69F46D860319636C5931E1C25EF07F5B3D9964ED066E8E0D1C9E73121907C3A27EDCDDBD231B0BAEB124C13F1EBAC60035DE0017D5B0DABA74763096E26F7C9A7394B73BB65A7733F2A69FA6B0D8543CE3D98C083DE93B48BF974556CE3B0230DE2B13D4BA011DB8272BA6DDAF54E0E26E10180C03397156FFCAE19A95ABA41D090397
-20220414080739 2 6 100 3071 5 F5A593C9AFA507A500AC0F2C6389F394E8818163FA32B928AC5A46FBC5556CFC88FC789A9EE0E99C002FC4E3DABCAA2BF268FD7FB49A26E986A300CAEEED3C55E43DD1681074B52C4DB264879CE4B96F2CBB172EBBEE34A7E87CC3818AB3E6AAF135C7CDB655F220B93C32B2CB69F538CCE40AF86994CB6D80D0456B3CAA38C46B0D09C0D26C8E67D4EE6E4FE219AC92FF244216E6DCB4267C0DA00E906730792FA9BDA189B9CE5D552B04F1314418936BF02B08FE3AC2033A6B17DF3956D1316FAA6347FD940DDA68FB8AAE1B42E225B2CB8C81BA82DD05A0284F4C08DA48B991DFC1DD08E8ED02AA3FAF82E34CAC009930DDA85040A5D380F8B9B79F69F46D860319636C5931E1C25EF07F5B3D9964ED066E8E0D1C9E73121907C3A27EDCDDBD231B0BAEB124C13F1EBAC60035DE0017D5B0DABA74763096E26F7C9A7394B73BB65A7733F2A69FA6B0D8543CE3D98C083DE93B48BF974556CE3B0230DE2B13D4BA011DB8272BA6DDAF54E0E26E10180C03397156FFCAE19A95ABA41E0CE6AF
-20220414080844 2 6 100 3071 2 F5A593C9AFA507A500AC0F2C6389F394E8818163FA32B928AC5A46FBC5556CFC88FC789A9EE0E99C002FC4E3DABCAA2BF268FD7FB49A26E986A300CAEEED3C55E43DD1681074B52C4DB264879CE4B96F2CBB172EBBEE34A7E87CC3818AB3E6AAF135C7CDB655F220B93C32B2CB69F538CCE40AF86994CB6D80D0456B3CAA38C46B0D09C0D26C8E67D4EE6E4FE219AC92FF244216E6DCB4267C0DA00E906730792FA9BDA189B9CE5D552B04F1314418936BF02B08FE3AC2033A6B17DF3956D1316FAA6347FD940DDA68FB8AAE1B42E225B2CB8C81BA82DD05A0284F4C08DA48B991DFC1DD08E8ED02AA3FAF82E34CAC009930DDA85040A5D380F8B9B79F69F46D860319636C5931E1C25EF07F5B3D9964ED066E8E0D1C9E73121907C3A27EDCDDBD231B0BAEB124C13F1EBAC60035DE0017D5B0DABA74763096E26F7C9A7394B73BB65A7733F2A69FA6B0D8543CE3D98C083DE93B48BF974556CE3B0230DE2B13D4BA011DB8272BA6DDAF54E0E26E10180C03397156FFCAE19A95ABA41F0FD883
-20220414080927 2 6 100 3071 2 F5A593C9AFA507A500AC0F2C6389F394E8818163FA32B928AC5A46FBC5556CFC88FC789A9EE0E99C002FC4E3DABCAA2BF268FD7FB49A26E986A300CAEEED3C55E43DD1681074B52C4DB264879CE4B96F2CBB172EBBEE34A7E87CC3818AB3E6AAF135C7CDB655F220B93C32B2CB69F538CCE40AF86994CB6D80D0456B3CAA38C46B0D09C0D26C8E67D4EE6E4FE219AC92FF244216E6DCB4267C0DA00E906730792FA9BDA189B9CE5D552B04F1314418936BF02B08FE3AC2033A6B17DF3956D1316FAA6347FD940DDA68FB8AAE1B42E225B2CB8C81BA82DD05A0284F4C08DA48B991DFC1DD08E8ED02AA3FAF82E34CAC009930DDA85040A5D380F8B9B79F69F46D860319636C5931E1C25EF07F5B3D9964ED066E8E0D1C9E73121907C3A27EDCDDBD231B0BAEB124C13F1EBAC60035DE0017D5B0DABA74763096E26F7C9A7394B73BB65A7733F2A69FA6B0D8543CE3D98C083DE93B48BF974556CE3B0230DE2B13D4BA011DB8272BA6DDAF54E0E26E10180C03397156FFCAE19A95ABA41FAF88C3
-20220414080944 2 6 100 3071 2 F5A593C9AFA507A500AC0F2C6389F394E8818163FA32B928AC5A46FBC5556CFC88FC789A9EE0E99C002FC4E3DABCAA2BF268FD7FB49A26E986A300CAEEED3C55E43DD1681074B52C4DB264879CE4B96F2CBB172EBBEE34A7E87CC3818AB3E6AAF135C7CDB655F220B93C32B2CB69F538CCE40AF86994CB6D80D0456B3CAA38C46B0D09C0D26C8E67D4EE6E4FE219AC92FF244216E6DCB4267C0DA00E906730792FA9BDA189B9CE5D552B04F1314418936BF02B08FE3AC2033A6B17DF3956D1316FAA6347FD940DDA68FB8AAE1B42E225B2CB8C81BA82DD05A0284F4C08DA48B991DFC1DD08E8ED02AA3FAF82E34CAC009930DDA85040A5D380F8B9B79F69F46D860319636C5931E1C25EF07F5B3D9964ED066E8E0D1C9E73121907C3A27EDCDDBD231B0BAEB124C13F1EBAC60035DE0017D5B0DABA74763096E26F7C9A7394B73BB65A7733F2A69FA6B0D8543CE3D98C083DE93B48BF974556CE3B0230DE2B13D4BA011DB8272BA6DDAF54E0E26E10180C03397156FFCAE19A95ABA41FED798B
-20220414081010 2 6 100 3071 2 F5A593C9AFA507A500AC0F2C6389F394E8818163FA32B928AC5A46FBC5556CFC88FC789A9EE0E99C002FC4E3DABCAA2BF268FD7FB49A26E986A300CAEEED3C55E43DD1681074B52C4DB264879CE4B96F2CBB172EBBEE34A7E87CC3818AB3E6AAF135C7CDB655F220B93C32B2CB69F538CCE40AF86994CB6D80D0456B3CAA38C46B0D09C0D26C8E67D4EE6E4FE219AC92FF244216E6DCB4267C0DA00E906730792FA9BDA189B9CE5D552B04F1314418936BF02B08FE3AC2033A6B17DF3956D1316FAA6347FD940DDA68FB8AAE1B42E225B2CB8C81BA82DD05A0284F4C08DA48B991DFC1DD08E8ED02AA3FAF82E34CAC009930DDA85040A5D380F8B9B79F69F46D860319636C5931E1C25EF07F5B3D9964ED066E8E0D1C9E73121907C3A27EDCDDBD231B0BAEB124C13F1EBAC60035DE0017D5B0DABA74763096E26F7C9A7394B73BB65A7733F2A69FA6B0D8543CE3D98C083DE93B48BF974556CE3B0230DE2B13D4BA011DB8272BA6DDAF54E0E26E10180C03397156FFCAE19A95ABA4204E96A3
-20220414081036 2 6 100 3071 5 F5A593C9AFA507A500AC0F2C6389F394E8818163FA32B928AC5A46FBC5556CFC88FC789A9EE0E99C002FC4E3DABCAA2BF268FD7FB49A26E986A300CAEEED3C55E43DD1681074B52C4DB264879CE4B96F2CBB172EBBEE34A7E87CC3818AB3E6AAF135C7CDB655F220B93C32B2CB69F538CCE40AF86994CB6D80D0456B3CAA38C46B0D09C0D26C8E67D4EE6E4FE219AC92FF244216E6DCB4267C0DA00E906730792FA9BDA189B9CE5D552B04F1314418936BF02B08FE3AC2033A6B17DF3956D1316FAA6347FD940DDA68FB8AAE1B42E225B2CB8C81BA82DD05A0284F4C08DA48B991DFC1DD08E8ED02AA3FAF82E34CAC009930DDA85040A5D380F8B9B79F69F46D860319636C5931E1C25EF07F5B3D9964ED066E8E0D1C9E73121907C3A27EDCDDBD231B0BAEB124C13F1EBAC60035DE0017D5B0DABA74763096E26F7C9A7394B73BB65A7733F2A69FA6B0D8543CE3D98C083DE93B48BF974556CE3B0230DE2B13D4BA011DB8272BA6DDAF54E0E26E10180C03397156FFCAE19A95ABA420AE22CF
-20220414081101 2 6 100 3071 5 F5A593C9AFA507A500AC0F2C6389F394E8818163FA32B928AC5A46FBC5556CFC88FC789A9EE0E99C002FC4E3DABCAA2BF268FD7FB49A26E986A300CAEEED3C55E43DD1681074B52C4DB264879CE4B96F2CBB172EBBEE34A7E87CC3818AB3E6AAF135C7CDB655F220B93C32B2CB69F538CCE40AF86994CB6D80D0456B3CAA38C46B0D09C0D26C8E67D4EE6E4FE219AC92FF244216E6DCB4267C0DA00E906730792FA9BDA189B9CE5D552B04F1314418936BF02B08FE3AC2033A6B17DF3956D1316FAA6347FD940DDA68FB8AAE1B42E225B2CB8C81BA82DD05A0284F4C08DA48B991DFC1DD08E8ED02AA3FAF82E34CAC009930DDA85040A5D380F8B9B79F69F46D860319636C5931E1C25EF07F5B3D9964ED066E8E0D1C9E73121907C3A27EDCDDBD231B0BAEB124C13F1EBAC60035DE0017D5B0DABA74763096E26F7C9A7394B73BB65A7733F2A69FA6B0D8543CE3D98C083DE93B48BF974556CE3B0230DE2B13D4BA011DB8272BA6DDAF54E0E26E10180C03397156FFCAE19A95ABA42108AABF
-20220414081119 2 6 100 3071 5 F5A593C9AFA507A500AC0F2C6389F394E8818163FA32B928AC5A46FBC5556CFC88FC789A9EE0E99C002FC4E3DABCAA2BF268FD7FB49A26E986A300CAEEED3C55E43DD1681074B52C4DB264879CE4B96F2CBB172EBBEE34A7E87CC3818AB3E6AAF135C7CDB655F220B93C32B2CB69F538CCE40AF86994CB6D80D0456B3CAA38C46B0D09C0D26C8E67D4EE6E4FE219AC92FF244216E6DCB4267C0DA00E906730792FA9BDA189B9CE5D552B04F1314418936BF02B08FE3AC2033A6B17DF3956D1316FAA6347FD940DDA68FB8AAE1B42E225B2CB8C81BA82DD05A0284F4C08DA48B991DFC1DD08E8ED02AA3FAF82E34CAC009930DDA85040A5D380F8B9B79F69F46D860319636C5931E1C25EF07F5B3D9964ED066E8E0D1C9E73121907C3A27EDCDDBD231B0BAEB124C13F1EBAC60035DE0017D5B0DABA74763096E26F7C9A7394B73BB65A7733F2A69FA6B0D8543CE3D98C083DE93B48BF974556CE3B0230DE2B13D4BA011DB8272BA6DDAF54E0E26E10180C03397156FFCAE19A95ABA4214499C7
-20220414081154 2 6 100 3071 2 F5A593C9AFA507A500AC0F2C6389F394E8818163FA32B928AC5A46FBC5556CFC88FC789A9EE0E99C002FC4E3DABCAA2BF268FD7FB49A26E986A300CAEEED3C55E43DD1681074B52C4DB264879CE4B96F2CBB172EBBEE34A7E87CC3818AB3E6AAF135C7CDB655F220B93C32B2CB69F538CCE40AF86994CB6D80D0456B3CAA38C46B0D09C0D26C8E67D4EE6E4FE219AC92FF244216E6DCB4267C0DA00E906730792FA9BDA189B9CE5D552B04F1314418936BF02B08FE3AC2033A6B17DF3956D1316FAA6347FD940DDA68FB8AAE1B42E225B2CB8C81BA82DD05A0284F4C08DA48B991DFC1DD08E8ED02AA3FAF82E34CAC009930DDA85040A5D380F8B9B79F69F46D860319636C5931E1C25EF07F5B3D9964ED066E8E0D1C9E73121907C3A27EDCDDBD231B0BAEB124C13F1EBAC60035DE0017D5B0DABA74763096E26F7C9A7394B73BB65A7733F2A69FA6B0D8543CE3D98C083DE93B48BF974556CE3B0230DE2B13D4BA011DB8272BA6DDAF54E0E26E10180C03397156FFCAE19A95ABA421C7C413
-20220414081217 2 6 100 3071 5 F5A593C9AFA507A500AC0F2C6389F394E8818163FA32B928AC5A46FBC5556CFC88FC789A9EE0E99C002FC4E3DABCAA2BF268FD7FB49A26E986A300CAEEED3C55E43DD1681074B52C4DB264879CE4B96F2CBB172EBBEE34A7E87CC3818AB3E6AAF135C7CDB655F220B93C32B2CB69F538CCE40AF86994CB6D80D0456B3CAA38C46B0D09C0D26C8E67D4EE6E4FE219AC92FF244216E6DCB4267C0DA00E906730792FA9BDA189B9CE5D552B04F1314418936BF02B08FE3AC2033A6B17DF3956D1316FAA6347FD940DDA68FB8AAE1B42E225B2CB8C81BA82DD05A0284F4C08DA48B991DFC1DD08E8ED02AA3FAF82E34CAC009930DDA85040A5D380F8B9B79F69F46D860319636C5931E1C25EF07F5B3D9964ED066E8E0D1C9E73121907C3A27EDCDDBD231B0BAEB124C13F1EBAC60035DE0017D5B0DABA74763096E26F7C9A7394B73BB65A7733F2A69FA6B0D8543CE3D98C083DE93B48BF974556CE3B0230DE2B13D4BA011DB8272BA6DDAF54E0E26E10180C03397156FFCAE19A95ABA4221AEE5F
-20220414081236 2 6 100 3071 2 F5A593C9AFA507A500AC0F2C6389F394E8818163FA32B928AC5A46FBC5556CFC88FC789A9EE0E99C002FC4E3DABCAA2BF268FD7FB49A26E986A300CAEEED3C55E43DD1681074B52C4DB264879CE4B96F2CBB172EBBEE34A7E87CC3818AB3E6AAF135C7CDB655F220B93C32B2CB69F538CCE40AF86994CB6D80D0456B3CAA38C46B0D09C0D26C8E67D4EE6E4FE219AC92FF244216E6DCB4267C0DA00E906730792FA9BDA189B9CE5D552B04F1314418936BF02B08FE3AC2033A6B17DF3956D1316FAA6347FD940DDA68FB8AAE1B42E225B2CB8C81BA82DD05A0284F4C08DA48B991DFC1DD08E8ED02AA3FAF82E34CAC009930DDA85040A5D380F8B9B79F69F46D860319636C5931E1C25EF07F5B3D9964ED066E8E0D1C9E73121907C3A27EDCDDBD231B0BAEB124C13F1EBAC60035DE0017D5B0DABA74763096E26F7C9A7394B73BB65A7733F2A69FA6B0D8543CE3D98C083DE93B48BF974556CE3B0230DE2B13D4BA011DB8272BA6DDAF54E0E26E10180C03397156FFCAE19A95ABA42261B5C3
-20220414081253 2 6 100 3071 5 F5A593C9AFA507A500AC0F2C6389F394E8818163FA32B928AC5A46FBC5556CFC88FC789A9EE0E99C002FC4E3DABCAA2BF268FD7FB49A26E986A300CAEEED3C55E43DD1681074B52C4DB264879CE4B96F2CBB172EBBEE34A7E87CC3818AB3E6AAF135C7CDB655F220B93C32B2CB69F538CCE40AF86994CB6D80D0456B3CAA38C46B0D09C0D26C8E67D4EE6E4FE219AC92FF244216E6DCB4267C0DA00E906730792FA9BDA189B9CE5D552B04F1314418936BF02B08FE3AC2033A6B17DF3956D1316FAA6347FD940DDA68FB8AAE1B42E225B2CB8C81BA82DD05A0284F4C08DA48B991DFC1DD08E8ED02AA3FAF82E34CAC009930DDA85040A5D380F8B9B79F69F46D860319636C5931E1C25EF07F5B3D9964ED066E8E0D1C9E73121907C3A27EDCDDBD231B0BAEB124C13F1EBAC60035DE0017D5B0DABA74763096E26F7C9A7394B73BB65A7733F2A69FA6B0D8543CE3D98C083DE93B48BF974556CE3B0230DE2B13D4BA011DB8272BA6DDAF54E0E26E10180C03397156FFCAE19A95ABA4229C2F0F
-20220414081339 2 6 100 3071 2 F5A593C9AFA507A500AC0F2C6389F394E8818163FA32B928AC5A46FBC5556CFC88FC789A9EE0E99C002FC4E3DABCAA2BF268FD7FB49A26E986A300CAEEED3C55E43DD1681074B52C4DB264879CE4B96F2CBB172EBBEE34A7E87CC3818AB3E6AAF135C7CDB655F220B93C32B2CB69F538CCE40AF86994CB6D80D0456B3CAA38C46B0D09C0D26C8E67D4EE6E4FE219AC92FF244216E6DCB4267C0DA00E906730792FA9BDA189B9CE5D552B04F1314418936BF02B08FE3AC2033A6B17DF3956D1316FAA6347FD940DDA68FB8AAE1B42E225B2CB8C81BA82DD05A0284F4C08DA48B991DFC1DD08E8ED02AA3FAF82E34CAC009930DDA85040A5D380F8B9B79F69F46D860319636C5931E1C25EF07F5B3D9964ED066E8E0D1C9E73121907C3A27EDCDDBD231B0BAEB124C13F1EBAC60035DE0017D5B0DABA74763096E26F7C9A7394B73BB65A7733F2A69FA6B0D8543CE3D98C083DE93B48BF974556CE3B0230DE2B13D4BA011DB8272BA6DDAF54E0E26E10180C03397156FFCAE19A95ABA4234DEBD3
-20220414081352 2 6 100 3071 5 F5A593C9AFA507A500AC0F2C6389F394E8818163FA32B928AC5A46FBC5556CFC88FC789A9EE0E99C002FC4E3DABCAA2BF268FD7FB49A26E986A300CAEEED3C55E43DD1681074B52C4DB264879CE4B96F2CBB172EBBEE34A7E87CC3818AB3E6AAF135C7CDB655F220B93C32B2CB69F538CCE40AF86994CB6D80D0456B3CAA38C46B0D09C0D26C8E67D4EE6E4FE219AC92FF244216E6DCB4267C0DA00E906730792FA9BDA189B9CE5D552B04F1314418936BF02B08FE3AC2033A6B17DF3956D1316FAA6347FD940DDA68FB8AAE1B42E225B2CB8C81BA82DD05A0284F4C08DA48B991DFC1DD08E8ED02AA3FAF82E34CAC009930DDA85040A5D380F8B9B79F69F46D860319636C5931E1C25EF07F5B3D9964ED066E8E0D1C9E73121907C3A27EDCDDBD231B0BAEB124C13F1EBAC60035DE0017D5B0DABA74763096E26F7C9A7394B73BB65A7733F2A69FA6B0D8543CE3D98C083DE93B48BF974556CE3B0230DE2B13D4BA011DB8272BA6DDAF54E0E26E10180C03397156FFCAE19A95ABA4237ABDBF
-20220414081357 2 6 100 3071 5 F5A593C9AFA507A500AC0F2C6389F394E8818163FA32B928AC5A46FBC5556CFC88FC789A9EE0E99C002FC4E3DABCAA2BF268FD7FB49A26E986A300CAEEED3C55E43DD1681074B52C4DB264879CE4B96F2CBB172EBBEE34A7E87CC3818AB3E6AAF135C7CDB655F220B93C32B2CB69F538CCE40AF86994CB6D80D0456B3CAA38C46B0D09C0D26C8E67D4EE6E4FE219AC92FF244216E6DCB4267C0DA00E906730792FA9BDA189B9CE5D552B04F1314418936BF02B08FE3AC2033A6B17DF3956D1316FAA6347FD940DDA68FB8AAE1B42E225B2CB8C81BA82DD05A0284F4C08DA48B991DFC1DD08E8ED02AA3FAF82E34CAC009930DDA85040A5D380F8B9B79F69F46D860319636C5931E1C25EF07F5B3D9964ED066E8E0D1C9E73121907C3A27EDCDDBD231B0BAEB124C13F1EBAC60035DE0017D5B0DABA74763096E26F7C9A7394B73BB65A7733F2A69FA6B0D8543CE3D98C083DE93B48BF974556CE3B0230DE2B13D4BA011DB8272BA6DDAF54E0E26E10180C03397156FFCAE19A95ABA42388B4CF
-20220414081406 2 6 100 3071 5 F5A593C9AFA507A500AC0F2C6389F394E8818163FA32B928AC5A46FBC5556CFC88FC789A9EE0E99C002FC4E3DABCAA2BF268FD7FB49A26E986A300CAEEED3C55E43DD1681074B52C4DB264879CE4B96F2CBB172EBBEE34A7E87CC3818AB3E6AAF135C7CDB655F220B93C32B2CB69F538CCE40AF86994CB6D80D0456B3CAA38C46B0D09C0D26C8E67D4EE6E4FE219AC92FF244216E6DCB4267C0DA00E906730792FA9BDA189B9CE5D552B04F1314418936BF02B08FE3AC2033A6B17DF3956D1316FAA6347FD940DDA68FB8AAE1B42E225B2CB8C81BA82DD05A0284F4C08DA48B991DFC1DD08E8ED02AA3FAF82E34CAC009930DDA85040A5D380F8B9B79F69F46D860319636C5931E1C25EF07F5B3D9964ED066E8E0D1C9E73121907C3A27EDCDDBD231B0BAEB124C13F1EBAC60035DE0017D5B0DABA74763096E26F7C9A7394B73BB65A7733F2A69FA6B0D8543CE3D98C083DE93B48BF974556CE3B0230DE2B13D4BA011DB8272BA6DDAF54E0E26E10180C03397156FFCAE19A95ABA423A221F7
-20220414081420 2 6 100 3071 2 F5A593C9AFA507A500AC0F2C6389F394E8818163FA32B928AC5A46FBC5556CFC88FC789A9EE0E99C002FC4E3DABCAA2BF268FD7FB49A26E986A300CAEEED3C55E43DD1681074B52C4DB264879CE4B96F2CBB172EBBEE34A7E87CC3818AB3E6AAF135C7CDB655F220B93C32B2CB69F538CCE40AF86994CB6D80D0456B3CAA38C46B0D09C0D26C8E67D4EE6E4FE219AC92FF244216E6DCB4267C0DA00E906730792FA9BDA189B9CE5D552B04F1314418936BF02B08FE3AC2033A6B17DF3956D1316FAA6347FD940DDA68FB8AAE1B42E225B2CB8C81BA82DD05A0284F4C08DA48B991DFC1DD08E8ED02AA3FAF82E34CAC009930DDA85040A5D380F8B9B79F69F46D860319636C5931E1C25EF07F5B3D9964ED066E8E0D1C9E73121907C3A27EDCDDBD231B0BAEB124C13F1EBAC60035DE0017D5B0DABA74763096E26F7C9A7394B73BB65A7733F2A69FA6B0D8543CE3D98C083DE93B48BF974556CE3B0230DE2B13D4BA011DB8272BA6DDAF54E0E26E10180C03397156FFCAE19A95ABA423D608D3
-20220414081459 2 6 100 3071 2 F5A593C9AFA507A500AC0F2C6389F394E8818163FA32B928AC5A46FBC5556CFC88FC789A9EE0E99C002FC4E3DABCAA2BF268FD7FB49A26E986A300CAEEED3C55E43DD1681074B52C4DB264879CE4B96F2CBB172EBBEE34A7E87CC3818AB3E6AAF135C7CDB655F220B93C32B2CB69F538CCE40AF86994CB6D80D0456B3CAA38C46B0D09C0D26C8E67D4EE6E4FE219AC92FF244216E6DCB4267C0DA00E906730792FA9BDA189B9CE5D552B04F1314418936BF02B08FE3AC2033A6B17DF3956D1316FAA6347FD940DDA68FB8AAE1B42E225B2CB8C81BA82DD05A0284F4C08DA48B991DFC1DD08E8ED02AA3FAF82E34CAC009930DDA85040A5D380F8B9B79F69F46D860319636C5931E1C25EF07F5B3D9964ED066E8E0D1C9E73121907C3A27EDCDDBD231B0BAEB124C13F1EBAC60035DE0017D5B0DABA74763096E26F7C9A7394B73BB65A7733F2A69FA6B0D8543CE3D98C083DE93B48BF974556CE3B0230DE2B13D4BA011DB8272BA6DDAF54E0E26E10180C03397156FFCAE19A95ABA4246BBC83
-20220414081542 2 6 100 3071 2 F5A593C9AFA507A500AC0F2C6389F394E8818163FA32B928AC5A46FBC5556CFC88FC789A9EE0E99C002FC4E3DABCAA2BF268FD7FB49A26E986A300CAEEED3C55E43DD1681074B52C4DB264879CE4B96F2CBB172EBBEE34A7E87CC3818AB3E6AAF135C7CDB655F220B93C32B2CB69F538CCE40AF86994CB6D80D0456B3CAA38C46B0D09C0D26C8E67D4EE6E4FE219AC92FF244216E6DCB4267C0DA00E906730792FA9BDA189B9CE5D552B04F1314418936BF02B08FE3AC2033A6B17DF3956D1316FAA6347FD940DDA68FB8AAE1B42E225B2CB8C81BA82DD05A0284F4C08DA48B991DFC1DD08E8ED02AA3FAF82E34CAC009930DDA85040A5D380F8B9B79F69F46D860319636C5931E1C25EF07F5B3D9964ED066E8E0D1C9E73121907C3A27EDCDDBD231B0BAEB124C13F1EBAC60035DE0017D5B0DABA74763096E26F7C9A7394B73BB65A7733F2A69FA6B0D8543CE3D98C083DE93B48BF974556CE3B0230DE2B13D4BA011DB8272BA6DDAF54E0E26E10180C03397156FFCAE19A95ABA4250E9783
-20220414081700 2 6 100 3071 2 F5A593C9AFA507A500AC0F2C6389F394E8818163FA32B928AC5A46FBC5556CFC88FC789A9EE0E99C002FC4E3DABCAA2BF268FD7FB49A26E986A300CAEEED3C55E43DD1681074B52C4DB264879CE4B96F2CBB172EBBEE34A7E87CC3818AB3E6AAF135C7CDB655F220B93C32B2CB69F538CCE40AF86994CB6D80D0456B3CAA38C46B0D09C0D26C8E67D4EE6E4FE219AC92FF244216E6DCB4267C0DA00E906730792FA9BDA189B9CE5D552B04F1314418936BF02B08FE3AC2033A6B17DF3956D1316FAA6347FD940DDA68FB8AAE1B42E225B2CB8C81BA82DD05A0284F4C08DA48B991DFC1DD08E8ED02AA3FAF82E34CAC009930DDA85040A5D380F8B9B79F69F46D860319636C5931E1C25EF07F5B3D9964ED066E8E0D1C9E73121907C3A27EDCDDBD231B0BAEB124C13F1EBAC60035DE0017D5B0DABA74763096E26F7C9A7394B73BB65A7733F2A69FA6B0D8543CE3D98C083DE93B48BF974556CE3B0230DE2B13D4BA011DB8272BA6DDAF54E0E26E10180C03397156FFCAE19A95ABA42630DCAB
-20220414081734 2 6 100 3071 5 F5A593C9AFA507A500AC0F2C6389F394E8818163FA32B928AC5A46FBC5556CFC88FC789A9EE0E99C002FC4E3DABCAA2BF268FD7FB49A26E986A300CAEEED3C55E43DD1681074B52C4DB264879CE4B96F2CBB172EBBEE34A7E87CC3818AB3E6AAF135C7CDB655F220B93C32B2CB69F538CCE40AF86994CB6D80D0456B3CAA38C46B0D09C0D26C8E67D4EE6E4FE219AC92FF244216E6DCB4267C0DA00E906730792FA9BDA189B9CE5D552B04F1314418936BF02B08FE3AC2033A6B17DF3956D1316FAA6347FD940DDA68FB8AAE1B42E225B2CB8C81BA82DD05A0284F4C08DA48B991DFC1DD08E8ED02AA3FAF82E34CAC009930DDA85040A5D380F8B9B79F69F46D860319636C5931E1C25EF07F5B3D9964ED066E8E0D1C9E73121907C3A27EDCDDBD231B0BAEB124C13F1EBAC60035DE0017D5B0DABA74763096E26F7C9A7394B73BB65A7733F2A69FA6B0D8543CE3D98C083DE93B48BF974556CE3B0230DE2B13D4BA011DB8272BA6DDAF54E0E26E10180C03397156FFCAE19A95ABA426B23DD7
-20220414081825 2 6 100 3071 2 F5A593C9AFA507A500AC0F2C6389F394E8818163FA32B928AC5A46FBC5556CFC88FC789A9EE0E99C002FC4E3DABCAA2BF268FD7FB49A26E986A300CAEEED3C55E43DD1681074B52C4DB264879CE4B96F2CBB172EBBEE34A7E87CC3818AB3E6AAF135C7CDB655F220B93C32B2CB69F538CCE40AF86994CB6D80D0456B3CAA38C46B0D09C0D26C8E67D4EE6E4FE219AC92FF244216E6DCB4267C0DA00E906730792FA9BDA189B9CE5D552B04F1314418936BF02B08FE3AC2033A6B17DF3956D1316FAA6347FD940DDA68FB8AAE1B42E225B2CB8C81BA82DD05A0284F4C08DA48B991DFC1DD08E8ED02AA3FAF82E34CAC009930DDA85040A5D380F8B9B79F69F46D860319636C5931E1C25EF07F5B3D9964ED066E8E0D1C9E73121907C3A27EDCDDBD231B0BAEB124C13F1EBAC60035DE0017D5B0DABA74763096E26F7C9A7394B73BB65A7733F2A69FA6B0D8543CE3D98C083DE93B48BF974556CE3B0230DE2B13D4BA011DB8272BA6DDAF54E0E26E10180C03397156FFCAE19A95ABA42776DBCB
-20220414081912 2 6 100 3071 2 F5A593C9AFA507A500AC0F2C6389F394E8818163FA32B928AC5A46FBC5556CFC88FC789A9EE0E99C002FC4E3DABCAA2BF268FD7FB49A26E986A300CAEEED3C55E43DD1681074B52C4DB264879CE4B96F2CBB172EBBEE34A7E87CC3818AB3E6AAF135C7CDB655F220B93C32B2CB69F538CCE40AF86994CB6D80D0456B3CAA38C46B0D09C0D26C8E67D4EE6E4FE219AC92FF244216E6DCB4267C0DA00E906730792FA9BDA189B9CE5D552B04F1314418936BF02B08FE3AC2033A6B17DF3956D1316FAA6347FD940DDA68FB8AAE1B42E225B2CB8C81BA82DD05A0284F4C08DA48B991DFC1DD08E8ED02AA3FAF82E34CAC009930DDA85040A5D380F8B9B79F69F46D860319636C5931E1C25EF07F5B3D9964ED066E8E0D1C9E73121907C3A27EDCDDBD231B0BAEB124C13F1EBAC60035DE0017D5B0DABA74763096E26F7C9A7394B73BB65A7733F2A69FA6B0D8543CE3D98C083DE93B48BF974556CE3B0230DE2B13D4BA011DB8272BA6DDAF54E0E26E10180C03397156FFCAE19A95ABA4282A042B
-20220414083041 2 6 100 4095 2 F32919EC12E2FE5DCC900B63D26BA6DD1030C9D818431D43D7629C26DF0B797B85C4DE6D39A179EFDBF452D6FAEAFF7D89C80E2BF78133324537D863C67C527C8C8D321CCB69E1B4A97675179F0D581560D1BB4CB5FC0EE1BBE740DC53E81D509A2AB1C502E02196CB7910868E93FE8151C148430654A623949C8C985F169D78CF7143FADEA9363103FABE79F14F966061DAE8202CE667C23877B4375148E3FE6969270D90C0BB11983A725320FE2E110452D56CD29924687638285FF60F528FBCC8F9F21D1AF2C150265F6846BABF083F10B43D92FCC02F5794034DE043ED9EDD2088E590314930FDECCAF3BDE0D07ED9DB167BF2AF1634EF88C77D3016BFC17B0903449E3611BE247665FD4A2A4F1D988C67BA1B81B4C9453ADF5C98EEB584C5FB25F8B0EA3606C80A459DD58B0D10E50FE9A7E062E9E918765B1C5D2BE056F846BC7BBA649F2BCE549B2FA5A55D3F31388C1EFEA4E8F2800A2A050E8468E8DDD4DA986C6496159A26E2CA9CA26415EE53F6403DAB022C1F19EC1B311A39495AF6A82BD1FD9AE47BF5C10B013E7CA7DAB015BDA7B60EFA5FF4916BC6CB81C5B6132AA9EF4E49716D98FB66C349CB956DDE33CAAE1BEA93AC395C84B3F58FCDAEF3F58F9DEF5F7EDB527578D1711A754BFE19718A41CA16FAB7C106194455EEAF4E0D4FA29D2BF224B328F7B546382F2FB4E8EE41C96ECAB23411639DA0F7DB
-20220414083420 2 6 100 4095 2 F32919EC12E2FE5DCC900B63D26BA6DD1030C9D818431D43D7629C26DF0B797B85C4DE6D39A179EFDBF452D6FAEAFF7D89C80E2BF78133324537D863C67C527C8C8D321CCB69E1B4A97675179F0D581560D1BB4CB5FC0EE1BBE740DC53E81D509A2AB1C502E02196CB7910868E93FE8151C148430654A623949C8C985F169D78CF7143FADEA9363103FABE79F14F966061DAE8202CE667C23877B4375148E3FE6969270D90C0BB11983A725320FE2E110452D56CD29924687638285FF60F528FBCC8F9F21D1AF2C150265F6846BABF083F10B43D92FCC02F5794034DE043ED9EDD2088E590314930FDECCAF3BDE0D07ED9DB167BF2AF1634EF88C77D3016BFC17B0903449E3611BE247665FD4A2A4F1D988C67BA1B81B4C9453ADF5C98EEB584C5FB25F8B0EA3606C80A459DD58B0D10E50FE9A7E062E9E918765B1C5D2BE056F846BC7BBA649F2BCE549B2FA5A55D3F31388C1EFEA4E8F2800A2A050E8468E8DDD4DA986C6496159A26E2CA9CA26415EE53F6403DAB022C1F19EC1B311A39495AF6A82BD1FD9AE47BF5C10B013E7CA7DAB015BDA7B60EFA5FF4916BC6CB81C5B6132AA9EF4E49716D98FB66C349CB956DDE33CAAE1BEA93AC395C84B3F58FCDAEF3F58F9DEF5F7EDB527578D1711A754BFE19718A41CA16FAB7C106194455EEAF4E0D4FA29D2BF224B328F7B546382F2FB4E8EE41C96ECAB23411639F33C3DB
-20220414083538 2 6 100 4095 2 F32919EC12E2FE5DCC900B63D26BA6DD1030C9D818431D43D7629C26DF0B797B85C4DE6D39A179EFDBF452D6FAEAFF7D89C80E2BF78133324537D863C67C527C8C8D321CCB69E1B4A97675179F0D581560D1BB4CB5FC0EE1BBE740DC53E81D509A2AB1C502E02196CB7910868E93FE8151C148430654A623949C8C985F169D78CF7143FADEA9363103FABE79F14F966061DAE8202CE667C23877B4375148E3FE6969270D90C0BB11983A725320FE2E110452D56CD29924687638285FF60F528FBCC8F9F21D1AF2C150265F6846BABF083F10B43D92FCC02F5794034DE043ED9EDD2088E590314930FDECCAF3BDE0D07ED9DB167BF2AF1634EF88C77D3016BFC17B0903449E3611BE247665FD4A2A4F1D988C67BA1B81B4C9453ADF5C98EEB584C5FB25F8B0EA3606C80A459DD58B0D10E50FE9A7E062E9E918765B1C5D2BE056F846BC7BBA649F2BCE549B2FA5A55D3F31388C1EFEA4E8F2800A2A050E8468E8DDD4DA986C6496159A26E2CA9CA26415EE53F6403DAB022C1F19EC1B311A39495AF6A82BD1FD9AE47BF5C10B013E7CA7DAB015BDA7B60EFA5FF4916BC6CB81C5B6132AA9EF4E49716D98FB66C349CB956DDE33CAAE1BEA93AC395C84B3F58FCDAEF3F58F9DEF5F7EDB527578D1711A754BFE19718A41CA16FAB7C106194455EEAF4E0D4FA29D2BF224B328F7B546382F2FB4E8EE41C96ECAB23411639FBF5323
-20220414083742 2 6 100 4095 2 F32919EC12E2FE5DCC900B63D26BA6DD1030C9D818431D43D7629C26DF0B797B85C4DE6D39A179EFDBF452D6FAEAFF7D89C80E2BF78133324537D863C67C527C8C8D321CCB69E1B4A97675179F0D581560D1BB4CB5FC0EE1BBE740DC53E81D509A2AB1C502E02196CB7910868E93FE8151C148430654A623949C8C985F169D78CF7143FADEA9363103FABE79F14F966061DAE8202CE667C23877B4375148E3FE6969270D90C0BB11983A725320FE2E110452D56CD29924687638285FF60F528FBCC8F9F21D1AF2C150265F6846BABF083F10B43D92FCC02F5794034DE043ED9EDD2088E590314930FDECCAF3BDE0D07ED9DB167BF2AF1634EF88C77D3016BFC17B0903449E3611BE247665FD4A2A4F1D988C67BA1B81B4C9453ADF5C98EEB584C5FB25F8B0EA3606C80A459DD58B0D10E50FE9A7E062E9E918765B1C5D2BE056F846BC7BBA649F2BCE549B2FA5A55D3F31388C1EFEA4E8F2800A2A050E8468E8DDD4DA986C6496159A26E2CA9CA26415EE53F6403DAB022C1F19EC1B311A39495AF6A82BD1FD9AE47BF5C10B013E7CA7DAB015BDA7B60EFA5FF4916BC6CB81C5B6132AA9EF4E49716D98FB66C349CB956DDE33CAAE1BEA93AC395C84B3F58FCDAEF3F58F9DEF5F7EDB527578D1711A754BFE19718A41CA16FAB7C106194455EEAF4E0D4FA29D2BF224B328F7B546382F2FB4E8EE41C96ECAB2341163A0A39C73
-20220414083748 2 6 100 4095 2 F32919EC12E2FE5DCC900B63D26BA6DD1030C9D818431D43D7629C26DF0B797B85C4DE6D39A179EFDBF452D6FAEAFF7D89C80E2BF78133324537D863C67C527C8C8D321CCB69E1B4A97675179F0D581560D1BB4CB5FC0EE1BBE740DC53E81D509A2AB1C502E02196CB7910868E93FE8151C148430654A623949C8C985F169D78CF7143FADEA9363103FABE79F14F966061DAE8202CE667C23877B4375148E3FE6969270D90C0BB11983A725320FE2E110452D56CD29924687638285FF60F528FBCC8F9F21D1AF2C150265F6846BABF083F10B43D92FCC02F5794034DE043ED9EDD2088E590314930FDECCAF3BDE0D07ED9DB167BF2AF1634EF88C77D3016BFC17B0903449E3611BE247665FD4A2A4F1D988C67BA1B81B4C9453ADF5C98EEB584C5FB25F8B0EA3606C80A459DD58B0D10E50FE9A7E062E9E918765B1C5D2BE056F846BC7BBA649F2BCE549B2FA5A55D3F31388C1EFEA4E8F2800A2A050E8468E8DDD4DA986C6496159A26E2CA9CA26415EE53F6403DAB022C1F19EC1B311A39495AF6A82BD1FD9AE47BF5C10B013E7CA7DAB015BDA7B60EFA5FF4916BC6CB81C5B6132AA9EF4E49716D98FB66C349CB956DDE33CAAE1BEA93AC395C84B3F58FCDAEF3F58F9DEF5F7EDB527578D1711A754BFE19718A41CA16FAB7C106194455EEAF4E0D4FA29D2BF224B328F7B546382F2FB4E8EE41C96ECAB2341163A0A515CB
-20220414083806 2 6 100 4095 2 F32919EC12E2FE5DCC900B63D26BA6DD1030C9D818431D43D7629C26DF0B797B85C4DE6D39A179EFDBF452D6FAEAFF7D89C80E2BF78133324537D863C67C527C8C8D321CCB69E1B4A97675179F0D581560D1BB4CB5FC0EE1BBE740DC53E81D509A2AB1C502E02196CB7910868E93FE8151C148430654A623949C8C985F169D78CF7143FADEA9363103FABE79F14F966061DAE8202CE667C23877B4375148E3FE6969270D90C0BB11983A725320FE2E110452D56CD29924687638285FF60F528FBCC8F9F21D1AF2C150265F6846BABF083F10B43D92FCC02F5794034DE043ED9EDD2088E590314930FDECCAF3BDE0D07ED9DB167BF2AF1634EF88C77D3016BFC17B0903449E3611BE247665FD4A2A4F1D988C67BA1B81B4C9453ADF5C98EEB584C5FB25F8B0EA3606C80A459DD58B0D10E50FE9A7E062E9E918765B1C5D2BE056F846BC7BBA649F2BCE549B2FA5A55D3F31388C1EFEA4E8F2800A2A050E8468E8DDD4DA986C6496159A26E2CA9CA26415EE53F6403DAB022C1F19EC1B311A39495AF6A82BD1FD9AE47BF5C10B013E7CA7DAB015BDA7B60EFA5FF4916BC6CB81C5B6132AA9EF4E49716D98FB66C349CB956DDE33CAAE1BEA93AC395C84B3F58FCDAEF3F58F9DEF5F7EDB527578D1711A754BFE19718A41CA16FAB7C106194455EEAF4E0D4FA29D2BF224B328F7B546382F2FB4E8EE41C96ECAB2341163A0BD1AC3
-20220414083844 2 6 100 4095 5 F32919EC12E2FE5DCC900B63D26BA6DD1030C9D818431D43D7629C26DF0B797B85C4DE6D39A179EFDBF452D6FAEAFF7D89C80E2BF78133324537D863C67C527C8C8D321CCB69E1B4A97675179F0D581560D1BB4CB5FC0EE1BBE740DC53E81D509A2AB1C502E02196CB7910868E93FE8151C148430654A623949C8C985F169D78CF7143FADEA9363103FABE79F14F966061DAE8202CE667C23877B4375148E3FE6969270D90C0BB11983A725320FE2E110452D56CD29924687638285FF60F528FBCC8F9F21D1AF2C150265F6846BABF083F10B43D92FCC02F5794034DE043ED9EDD2088E590314930FDECCAF3BDE0D07ED9DB167BF2AF1634EF88C77D3016BFC17B0903449E3611BE247665FD4A2A4F1D988C67BA1B81B4C9453ADF5C98EEB584C5FB25F8B0EA3606C80A459DD58B0D10E50FE9A7E062E9E918765B1C5D2BE056F846BC7BBA649F2BCE549B2FA5A55D3F31388C1EFEA4E8F2800A2A050E8468E8DDD4DA986C6496159A26E2CA9CA26415EE53F6403DAB022C1F19EC1B311A39495AF6A82BD1FD9AE47BF5C10B013E7CA7DAB015BDA7B60EFA5FF4916BC6CB81C5B6132AA9EF4E49716D98FB66C349CB956DDE33CAAE1BEA93AC395C84B3F58FCDAEF3F58F9DEF5F7EDB527578D1711A754BFE19718A41CA16FAB7C106194455EEAF4E0D4FA29D2BF224B328F7B546382F2FB4E8EE41C96ECAB2341163A0FE2EEF
-20220414083857 2 6 100 4095 2 F32919EC12E2FE5DCC900B63D26BA6DD1030C9D818431D43D7629C26DF0B797B85C4DE6D39A179EFDBF452D6FAEAFF7D89C80E2BF78133324537D863C67C527C8C8D321CCB69E1B4A97675179F0D581560D1BB4CB5FC0EE1BBE740DC53E81D509A2AB1C502E02196CB7910868E93FE8151C148430654A623949C8C985F169D78CF7143FADEA9363103FABE79F14F966061DAE8202CE667C23877B4375148E3FE6969270D90C0BB11983A725320FE2E110452D56CD29924687638285FF60F528FBCC8F9F21D1AF2C150265F6846BABF083F10B43D92FCC02F5794034DE043ED9EDD2088E590314930FDECCAF3BDE0D07ED9DB167BF2AF1634EF88C77D3016BFC17B0903449E3611BE247665FD4A2A4F1D988C67BA1B81B4C9453ADF5C98EEB584C5FB25F8B0EA3606C80A459DD58B0D10E50FE9A7E062E9E918765B1C5D2BE056F846BC7BBA649F2BCE549B2FA5A55D3F31388C1EFEA4E8F2800A2A050E8468E8DDD4DA986C6496159A26E2CA9CA26415EE53F6403DAB022C1F19EC1B311A39495AF6A82BD1FD9AE47BF5C10B013E7CA7DAB015BDA7B60EFA5FF4916BC6CB81C5B6132AA9EF4E49716D98FB66C349CB956DDE33CAAE1BEA93AC395C84B3F58FCDAEF3F58F9DEF5F7EDB527578D1711A754BFE19718A41CA16FAB7C106194455EEAF4E0D4FA29D2BF224B328F7B546382F2FB4E8EE41C96ECAB2341163A10F0FBB
-20220414084033 2 6 100 4095 5 F32919EC12E2FE5DCC900B63D26BA6DD1030C9D818431D43D7629C26DF0B797B85C4DE6D39A179EFDBF452D6FAEAFF7D89C80E2BF78133324537D863C67C527C8C8D321CCB69E1B4A97675179F0D581560D1BB4CB5FC0EE1BBE740DC53E81D509A2AB1C502E02196CB7910868E93FE8151C148430654A623949C8C985F169D78CF7143FADEA9363103FABE79F14F966061DAE8202CE667C23877B4375148E3FE6969270D90C0BB11983A725320FE2E110452D56CD29924687638285FF60F528FBCC8F9F21D1AF2C150265F6846BABF083F10B43D92FCC02F5794034DE043ED9EDD2088E590314930FDECCAF3BDE0D07ED9DB167BF2AF1634EF88C77D3016BFC17B0903449E3611BE247665FD4A2A4F1D988C67BA1B81B4C9453ADF5C98EEB584C5FB25F8B0EA3606C80A459DD58B0D10E50FE9A7E062E9E918765B1C5D2BE056F846BC7BBA649F2BCE549B2FA5A55D3F31388C1EFEA4E8F2800A2A050E8468E8DDD4DA986C6496159A26E2CA9CA26415EE53F6403DAB022C1F19EC1B311A39495AF6A82BD1FD9AE47BF5C10B013E7CA7DAB015BDA7B60EFA5FF4916BC6CB81C5B6132AA9EF4E49716D98FB66C349CB956DDE33CAAE1BEA93AC395C84B3F58FCDAEF3F58F9DEF5F7EDB527578D1711A754BFE19718A41CA16FAB7C106194455EEAF4E0D4FA29D2BF224B328F7B546382F2FB4E8EE41C96ECAB2341163A1B65ABF
-20220414084433 2 6 100 4095 2 F32919EC12E2FE5DCC900B63D26BA6DD1030C9D818431D43D7629C26DF0B797B85C4DE6D39A179EFDBF452D6FAEAFF7D89C80E2BF78133324537D863C67C527C8C8D321CCB69E1B4A97675179F0D581560D1BB4CB5FC0EE1BBE740DC53E81D509A2AB1C502E02196CB7910868E93FE8151C148430654A623949C8C985F169D78CF7143FADEA9363103FABE79F14F966061DAE8202CE667C23877B4375148E3FE6969270D90C0BB11983A725320FE2E110452D56CD29924687638285FF60F528FBCC8F9F21D1AF2C150265F6846BABF083F10B43D92FCC02F5794034DE043ED9EDD2088E590314930FDECCAF3BDE0D07ED9DB167BF2AF1634EF88C77D3016BFC17B0903449E3611BE247665FD4A2A4F1D988C67BA1B81B4C9453ADF5C98EEB584C5FB25F8B0EA3606C80A459DD58B0D10E50FE9A7E062E9E918765B1C5D2BE056F846BC7BBA649F2BCE549B2FA5A55D3F31388C1EFEA4E8F2800A2A050E8468E8DDD4DA986C6496159A26E2CA9CA26415EE53F6403DAB022C1F19EC1B311A39495AF6A82BD1FD9AE47BF5C10B013E7CA7DAB015BDA7B60EFA5FF4916BC6CB81C5B6132AA9EF4E49716D98FB66C349CB956DDE33CAAE1BEA93AC395C84B3F58FCDAEF3F58F9DEF5F7EDB527578D1711A754BFE19718A41CA16FAB7C106194455EEAF4E0D4FA29D2BF224B328F7B546382F2FB4E8EE41C96ECAB2341163A3641CDB
-20220414084513 2 6 100 4095 2 F32919EC12E2FE5DCC900B63D26BA6DD1030C9D818431D43D7629C26DF0B797B85C4DE6D39A179EFDBF452D6FAEAFF7D89C80E2BF78133324537D863C67C527C8C8D321CCB69E1B4A97675179F0D581560D1BB4CB5FC0EE1BBE740DC53E81D509A2AB1C502E02196CB7910868E93FE8151C148430654A623949C8C985F169D78CF7143FADEA9363103FABE79F14F966061DAE8202CE667C23877B4375148E3FE6969270D90C0BB11983A725320FE2E110452D56CD29924687638285FF60F528FBCC8F9F21D1AF2C150265F6846BABF083F10B43D92FCC02F5794034DE043ED9EDD2088E590314930FDECCAF3BDE0D07ED9DB167BF2AF1634EF88C77D3016BFC17B0903449E3611BE247665FD4A2A4F1D988C67BA1B81B4C9453ADF5C98EEB584C5FB25F8B0EA3606C80A459DD58B0D10E50FE9A7E062E9E918765B1C5D2BE056F846BC7BBA649F2BCE549B2FA5A55D3F31388C1EFEA4E8F2800A2A050E8468E8DDD4DA986C6496159A26E2CA9CA26415EE53F6403DAB022C1F19EC1B311A39495AF6A82BD1FD9AE47BF5C10B013E7CA7DAB015BDA7B60EFA5FF4916BC6CB81C5B6132AA9EF4E49716D98FB66C349CB956DDE33CAAE1BEA93AC395C84B3F58FCDAEF3F58F9DEF5F7EDB527578D1711A754BFE19718A41CA16FAB7C106194455EEAF4E0D4FA29D2BF224B328F7B546382F2FB4E8EE41C96ECAB2341163A3A411D3
-20220414084808 2 6 100 4095 2 F32919EC12E2FE5DCC900B63D26BA6DD1030C9D818431D43D7629C26DF0B797B85C4DE6D39A179EFDBF452D6FAEAFF7D89C80E2BF78133324537D863C67C527C8C8D321CCB69E1B4A97675179F0D581560D1BB4CB5FC0EE1BBE740DC53E81D509A2AB1C502E02196CB7910868E93FE8151C148430654A623949C8C985F169D78CF7143FADEA9363103FABE79F14F966061DAE8202CE667C23877B4375148E3FE6969270D90C0BB11983A725320FE2E110452D56CD29924687638285FF60F528FBCC8F9F21D1AF2C150265F6846BABF083F10B43D92FCC02F5794034DE043ED9EDD2088E590314930FDECCAF3BDE0D07ED9DB167BF2AF1634EF88C77D3016BFC17B0903449E3611BE247665FD4A2A4F1D988C67BA1B81B4C9453ADF5C98EEB584C5FB25F8B0EA3606C80A459DD58B0D10E50FE9A7E062E9E918765B1C5D2BE056F846BC7BBA649F2BCE549B2FA5A55D3F31388C1EFEA4E8F2800A2A050E8468E8DDD4DA986C6496159A26E2CA9CA26415EE53F6403DAB022C1F19EC1B311A39495AF6A82BD1FD9AE47BF5C10B013E7CA7DAB015BDA7B60EFA5FF4916BC6CB81C5B6132AA9EF4E49716D98FB66C349CB956DDE33CAAE1BEA93AC395C84B3F58FCDAEF3F58F9DEF5F7EDB527578D1711A754BFE19718A41CA16FAB7C106194455EEAF4E0D4FA29D2BF224B328F7B546382F2FB4E8EE41C96ECAB2341163A4E0E273
-20220414085212 2 6 100 4095 2 F32919EC12E2FE5DCC900B63D26BA6DD1030C9D818431D43D7629C26DF0B797B85C4DE6D39A179EFDBF452D6FAEAFF7D89C80E2BF78133324537D863C67C527C8C8D321CCB69E1B4A97675179F0D581560D1BB4CB5FC0EE1BBE740DC53E81D509A2AB1C502E02196CB7910868E93FE8151C148430654A623949C8C985F169D78CF7143FADEA9363103FABE79F14F966061DAE8202CE667C23877B4375148E3FE6969270D90C0BB11983A725320FE2E110452D56CD29924687638285FF60F528FBCC8F9F21D1AF2C150265F6846BABF083F10B43D92FCC02F5794034DE043ED9EDD2088E590314930FDECCAF3BDE0D07ED9DB167BF2AF1634EF88C77D3016BFC17B0903449E3611BE247665FD4A2A4F1D988C67BA1B81B4C9453ADF5C98EEB584C5FB25F8B0EA3606C80A459DD58B0D10E50FE9A7E062E9E918765B1C5D2BE056F846BC7BBA649F2BCE549B2FA5A55D3F31388C1EFEA4E8F2800A2A050E8468E8DDD4DA986C6496159A26E2CA9CA26415EE53F6403DAB022C1F19EC1B311A39495AF6A82BD1FD9AE47BF5C10B013E7CA7DAB015BDA7B60EFA5FF4916BC6CB81C5B6132AA9EF4E49716D98FB66C349CB956DDE33CAAE1BEA93AC395C84B3F58FCDAEF3F58F9DEF5F7EDB527578D1711A754BFE19718A41CA16FAB7C106194455EEAF4E0D4FA29D2BF224B328F7B546382F2FB4E8EE41C96ECAB2341163A6A1D0B3
-20220414085536 2 6 100 4095 5 F32919EC12E2FE5DCC900B63D26BA6DD1030C9D818431D43D7629C26DF0B797B85C4DE6D39A179EFDBF452D6FAEAFF7D89C80E2BF78133324537D863C67C527C8C8D321CCB69E1B4A97675179F0D581560D1BB4CB5FC0EE1BBE740DC53E81D509A2AB1C502E02196CB7910868E93FE8151C148430654A623949C8C985F169D78CF7143FADEA9363103FABE79F14F966061DAE8202CE667C23877B4375148E3FE6969270D90C0BB11983A725320FE2E110452D56CD29924687638285FF60F528FBCC8F9F21D1AF2C150265F6846BABF083F10B43D92FCC02F5794034DE043ED9EDD2088E590314930FDECCAF3BDE0D07ED9DB167BF2AF1634EF88C77D3016BFC17B0903449E3611BE247665FD4A2A4F1D988C67BA1B81B4C9453ADF5C98EEB584C5FB25F8B0EA3606C80A459DD58B0D10E50FE9A7E062E9E918765B1C5D2BE056F846BC7BBA649F2BCE549B2FA5A55D3F31388C1EFEA4E8F2800A2A050E8468E8DDD4DA986C6496159A26E2CA9CA26415EE53F6403DAB022C1F19EC1B311A39495AF6A82BD1FD9AE47BF5C10B013E7CA7DAB015BDA7B60EFA5FF4916BC6CB81C5B6132AA9EF4E49716D98FB66C349CB956DDE33CAAE1BEA93AC395C84B3F58FCDAEF3F58F9DEF5F7EDB527578D1711A754BFE19718A41CA16FAB7C106194455EEAF4E0D4FA29D2BF224B328F7B546382F2FB4E8EE41C96ECAB2341163A81A77BF
-20220414090236 2 6 100 4095 2 F32919EC12E2FE5DCC900B63D26BA6DD1030C9D818431D43D7629C26DF0B797B85C4DE6D39A179EFDBF452D6FAEAFF7D89C80E2BF78133324537D863C67C527C8C8D321CCB69E1B4A97675179F0D581560D1BB4CB5FC0EE1BBE740DC53E81D509A2AB1C502E02196CB7910868E93FE8151C148430654A623949C8C985F169D78CF7143FADEA9363103FABE79F14F966061DAE8202CE667C23877B4375148E3FE6969270D90C0BB11983A725320FE2E110452D56CD29924687638285FF60F528FBCC8F9F21D1AF2C150265F6846BABF083F10B43D92FCC02F5794034DE043ED9EDD2088E590314930FDECCAF3BDE0D07ED9DB167BF2AF1634EF88C77D3016BFC17B0903449E3611BE247665FD4A2A4F1D988C67BA1B81B4C9453ADF5C98EEB584C5FB25F8B0EA3606C80A459DD58B0D10E50FE9A7E062E9E918765B1C5D2BE056F846BC7BBA649F2BCE549B2FA5A55D3F31388C1EFEA4E8F2800A2A050E8468E8DDD4DA986C6496159A26E2CA9CA26415EE53F6403DAB022C1F19EC1B311A39495AF6A82BD1FD9AE47BF5C10B013E7CA7DAB015BDA7B60EFA5FF4916BC6CB81C5B6132AA9EF4E49716D98FB66C349CB956DDE33CAAE1BEA93AC395C84B3F58FCDAEF3F58F9DEF5F7EDB527578D1711A754BFE19718A41CA16FAB7C106194455EEAF4E0D4FA29D2BF224B328F7B546382F2FB4E8EE41C96ECAB2341163AB233EFB
-20220414090316 2 6 100 4095 2 F32919EC12E2FE5DCC900B63D26BA6DD1030C9D818431D43D7629C26DF0B797B85C4DE6D39A179EFDBF452D6FAEAFF7D89C80E2BF78133324537D863C67C527C8C8D321CCB69E1B4A97675179F0D581560D1BB4CB5FC0EE1BBE740DC53E81D509A2AB1C502E02196CB7910868E93FE8151C148430654A623949C8C985F169D78CF7143FADEA9363103FABE79F14F966061DAE8202CE667C23877B4375148E3FE6969270D90C0BB11983A725320FE2E110452D56CD29924687638285FF60F528FBCC8F9F21D1AF2C150265F6846BABF083F10B43D92FCC02F5794034DE043ED9EDD2088E590314930FDECCAF3BDE0D07ED9DB167BF2AF1634EF88C77D3016BFC17B0903449E3611BE247665FD4A2A4F1D988C67BA1B81B4C9453ADF5C98EEB584C5FB25F8B0EA3606C80A459DD58B0D10E50FE9A7E062E9E918765B1C5D2BE056F846BC7BBA649F2BCE549B2FA5A55D3F31388C1EFEA4E8F2800A2A050E8468E8DDD4DA986C6496159A26E2CA9CA26415EE53F6403DAB022C1F19EC1B311A39495AF6A82BD1FD9AE47BF5C10B013E7CA7DAB015BDA7B60EFA5FF4916BC6CB81C5B6132AA9EF4E49716D98FB66C349CB956DDE33CAAE1BEA93AC395C84B3F58FCDAEF3F58F9DEF5F7EDB527578D1711A754BFE19718A41CA16FAB7C106194455EEAF4E0D4FA29D2BF224B328F7B546382F2FB4E8EE41C96ECAB2341163AB65D58B
-20220414090426 2 6 100 4095 5 F32919EC12E2FE5DCC900B63D26BA6DD1030C9D818431D43D7629C26DF0B797B85C4DE6D39A179EFDBF452D6FAEAFF7D89C80E2BF78133324537D863C67C527C8C8D321CCB69E1B4A97675179F0D581560D1BB4CB5FC0EE1BBE740DC53E81D509A2AB1C502E02196CB7910868E93FE8151C148430654A623949C8C985F169D78CF7143FADEA9363103FABE79F14F966061DAE8202CE667C23877B4375148E3FE6969270D90C0BB11983A725320FE2E110452D56CD29924687638285FF60F528FBCC8F9F21D1AF2C150265F6846BABF083F10B43D92FCC02F5794034DE043ED9EDD2088E590314930FDECCAF3BDE0D07ED9DB167BF2AF1634EF88C77D3016BFC17B0903449E3611BE247665FD4A2A4F1D988C67BA1B81B4C9453ADF5C98EEB584C5FB25F8B0EA3606C80A459DD58B0D10E50FE9A7E062E9E918765B1C5D2BE056F846BC7BBA649F2BCE549B2FA5A55D3F31388C1EFEA4E8F2800A2A050E8468E8DDD4DA986C6496159A26E2CA9CA26415EE53F6403DAB022C1F19EC1B311A39495AF6A82BD1FD9AE47BF5C10B013E7CA7DAB015BDA7B60EFA5FF4916BC6CB81C5B6132AA9EF4E49716D98FB66C349CB956DDE33CAAE1BEA93AC395C84B3F58FCDAEF3F58F9DEF5F7EDB527578D1711A754BFE19718A41CA16FAB7C106194455EEAF4E0D4FA29D2BF224B328F7B546382F2FB4E8EE41C96ECAB2341163ABE1A11F
-20220414090629 2 6 100 4095 2 F32919EC12E2FE5DCC900B63D26BA6DD1030C9D818431D43D7629C26DF0B797B85C4DE6D39A179EFDBF452D6FAEAFF7D89C80E2BF78133324537D863C67C527C8C8D321CCB69E1B4A97675179F0D581560D1BB4CB5FC0EE1BBE740DC53E81D509A2AB1C502E02196CB7910868E93FE8151C148430654A623949C8C985F169D78CF7143FADEA9363103FABE79F14F966061DAE8202CE667C23877B4375148E3FE6969270D90C0BB11983A725320FE2E110452D56CD29924687638285FF60F528FBCC8F9F21D1AF2C150265F6846BABF083F10B43D92FCC02F5794034DE043ED9EDD2088E590314930FDECCAF3BDE0D07ED9DB167BF2AF1634EF88C77D3016BFC17B0903449E3611BE247665FD4A2A4F1D988C67BA1B81B4C9453ADF5C98EEB584C5FB25F8B0EA3606C80A459DD58B0D10E50FE9A7E062E9E918765B1C5D2BE056F846BC7BBA649F2BCE549B2FA5A55D3F31388C1EFEA4E8F2800A2A050E8468E8DDD4DA986C6496159A26E2CA9CA26415EE53F6403DAB022C1F19EC1B311A39495AF6A82BD1FD9AE47BF5C10B013E7CA7DAB015BDA7B60EFA5FF4916BC6CB81C5B6132AA9EF4E49716D98FB66C349CB956DDE33CAAE1BEA93AC395C84B3F58FCDAEF3F58F9DEF5F7EDB527578D1711A754BFE19718A41CA16FAB7C106194455EEAF4E0D4FA29D2BF224B328F7B546382F2FB4E8EE41C96ECAB2341163ACC285FB
-20220414091059 2 6 100 4095 2 F32919EC12E2FE5DCC900B63D26BA6DD1030C9D818431D43D7629C26DF0B797B85C4DE6D39A179EFDBF452D6FAEAFF7D89C80E2BF78133324537D863C67C527C8C8D321CCB69E1B4A97675179F0D581560D1BB4CB5FC0EE1BBE740DC53E81D509A2AB1C502E02196CB7910868E93FE8151C148430654A623949C8C985F169D78CF7143FADEA9363103FABE79F14F966061DAE8202CE667C23877B4375148E3FE6969270D90C0BB11983A725320FE2E110452D56CD29924687638285FF60F528FBCC8F9F21D1AF2C150265F6846BABF083F10B43D92FCC02F5794034DE043ED9EDD2088E590314930FDECCAF3BDE0D07ED9DB167BF2AF1634EF88C77D3016BFC17B0903449E3611BE247665FD4A2A4F1D988C67BA1B81B4C9453ADF5C98EEB584C5FB25F8B0EA3606C80A459DD58B0D10E50FE9A7E062E9E918765B1C5D2BE056F846BC7BBA649F2BCE549B2FA5A55D3F31388C1EFEA4E8F2800A2A050E8468E8DDD4DA986C6496159A26E2CA9CA26415EE53F6403DAB022C1F19EC1B311A39495AF6A82BD1FD9AE47BF5C10B013E7CA7DAB015BDA7B60EFA5FF4916BC6CB81C5B6132AA9EF4E49716D98FB66C349CB956DDE33CAAE1BEA93AC395C84B3F58FCDAEF3F58F9DEF5F7EDB527578D1711A754BFE19718A41CA16FAB7C106194455EEAF4E0D4FA29D2BF224B328F7B546382F2FB4E8EE41C96ECAB2341163AEC45C03
-20220414091158 2 6 100 4095 2 F32919EC12E2FE5DCC900B63D26BA6DD1030C9D818431D43D7629C26DF0B797B85C4DE6D39A179EFDBF452D6FAEAFF7D89C80E2BF78133324537D863C67C527C8C8D321CCB69E1B4A97675179F0D581560D1BB4CB5FC0EE1BBE740DC53E81D509A2AB1C502E02196CB7910868E93FE8151C148430654A623949C8C985F169D78CF7143FADEA9363103FABE79F14F966061DAE8202CE667C23877B4375148E3FE6969270D90C0BB11983A725320FE2E110452D56CD29924687638285FF60F528FBCC8F9F21D1AF2C150265F6846BABF083F10B43D92FCC02F5794034DE043ED9EDD2088E590314930FDECCAF3BDE0D07ED9DB167BF2AF1634EF88C77D3016BFC17B0903449E3611BE247665FD4A2A4F1D988C67BA1B81B4C9453ADF5C98EEB584C5FB25F8B0EA3606C80A459DD58B0D10E50FE9A7E062E9E918765B1C5D2BE056F846BC7BBA649F2BCE549B2FA5A55D3F31388C1EFEA4E8F2800A2A050E8468E8DDD4DA986C6496159A26E2CA9CA26415EE53F6403DAB022C1F19EC1B311A39495AF6A82BD1FD9AE47BF5C10B013E7CA7DAB015BDA7B60EFA5FF4916BC6CB81C5B6132AA9EF4E49716D98FB66C349CB956DDE33CAAE1BEA93AC395C84B3F58FCDAEF3F58F9DEF5F7EDB527578D1711A754BFE19718A41CA16FAB7C106194455EEAF4E0D4FA29D2BF224B328F7B546382F2FB4E8EE41C96ECAB2341163AF2CCFF3
-20220414091314 2 6 100 4095 5 F32919EC12E2FE5DCC900B63D26BA6DD1030C9D818431D43D7629C26DF0B797B85C4DE6D39A179EFDBF452D6FAEAFF7D89C80E2BF78133324537D863C67C527C8C8D321CCB69E1B4A97675179F0D581560D1BB4CB5FC0EE1BBE740DC53E81D509A2AB1C502E02196CB7910868E93FE8151C148430654A623949C8C985F169D78CF7143FADEA9363103FABE79F14F966061DAE8202CE667C23877B4375148E3FE6969270D90C0BB11983A725320FE2E110452D56CD29924687638285FF60F528FBCC8F9F21D1AF2C150265F6846BABF083F10B43D92FCC02F5794034DE043ED9EDD2088E590314930FDECCAF3BDE0D07ED9DB167BF2AF1634EF88C77D3016BFC17B0903449E3611BE247665FD4A2A4F1D988C67BA1B81B4C9453ADF5C98EEB584C5FB25F8B0EA3606C80A459DD58B0D10E50FE9A7E062E9E918765B1C5D2BE056F846BC7BBA649F2BCE549B2FA5A55D3F31388C1EFEA4E8F2800A2A050E8468E8DDD4DA986C6496159A26E2CA9CA26415EE53F6403DAB022C1F19EC1B311A39495AF6A82BD1FD9AE47BF5C10B013E7CA7DAB015BDA7B60EFA5FF4916BC6CB81C5B6132AA9EF4E49716D98FB66C349CB956DDE33CAAE1BEA93AC395C84B3F58FCDAEF3F58F9DEF5F7EDB527578D1711A754BFE19718A41CA16FAB7C106194455EEAF4E0D4FA29D2BF224B328F7B546382F2FB4E8EE41C96ECAB2341163AFB69BF7
-20220414091552 2 6 100 4095 5 F32919EC12E2FE5DCC900B63D26BA6DD1030C9D818431D43D7629C26DF0B797B85C4DE6D39A179EFDBF452D6FAEAFF7D89C80E2BF78133324537D863C67C527C8C8D321CCB69E1B4A97675179F0D581560D1BB4CB5FC0EE1BBE740DC53E81D509A2AB1C502E02196CB7910868E93FE8151C148430654A623949C8C985F169D78CF7143FADEA9363103FABE79F14F966061DAE8202CE667C23877B4375148E3FE6969270D90C0BB11983A725320FE2E110452D56CD29924687638285FF60F528FBCC8F9F21D1AF2C150265F6846BABF083F10B43D92FCC02F5794034DE043ED9EDD2088E590314930FDECCAF3BDE0D07ED9DB167BF2AF1634EF88C77D3016BFC17B0903449E3611BE247665FD4A2A4F1D988C67BA1B81B4C9453ADF5C98EEB584C5FB25F8B0EA3606C80A459DD58B0D10E50FE9A7E062E9E918765B1C5D2BE056F846BC7BBA649F2BCE549B2FA5A55D3F31388C1EFEA4E8F2800A2A050E8468E8DDD4DA986C6496159A26E2CA9CA26415EE53F6403DAB022C1F19EC1B311A39495AF6A82BD1FD9AE47BF5C10B013E7CA7DAB015BDA7B60EFA5FF4916BC6CB81C5B6132AA9EF4E49716D98FB66C349CB956DDE33CAAE1BEA93AC395C84B3F58FCDAEF3F58F9DEF5F7EDB527578D1711A754BFE19718A41CA16FAB7C106194455EEAF4E0D4FA29D2BF224B328F7B546382F2FB4E8EE41C96ECAB2341163B0D7D40F
-20220414091928 2 6 100 4095 2 F32919EC12E2FE5DCC900B63D26BA6DD1030C9D818431D43D7629C26DF0B797B85C4DE6D39A179EFDBF452D6FAEAFF7D89C80E2BF78133324537D863C67C527C8C8D321CCB69E1B4A97675179F0D581560D1BB4CB5FC0EE1BBE740DC53E81D509A2AB1C502E02196CB7910868E93FE8151C148430654A623949C8C985F169D78CF7143FADEA9363103FABE79F14F966061DAE8202CE667C23877B4375148E3FE6969270D90C0BB11983A725320FE2E110452D56CD29924687638285FF60F528FBCC8F9F21D1AF2C150265F6846BABF083F10B43D92FCC02F5794034DE043ED9EDD2088E590314930FDECCAF3BDE0D07ED9DB167BF2AF1634EF88C77D3016BFC17B0903449E3611BE247665FD4A2A4F1D988C67BA1B81B4C9453ADF5C98EEB584C5FB25F8B0EA3606C80A459DD58B0D10E50FE9A7E062E9E918765B1C5D2BE056F846BC7BBA649F2BCE549B2FA5A55D3F31388C1EFEA4E8F2800A2A050E8468E8DDD4DA986C6496159A26E2CA9CA26415EE53F6403DAB022C1F19EC1B311A39495AF6A82BD1FD9AE47BF5C10B013E7CA7DAB015BDA7B60EFA5FF4916BC6CB81C5B6132AA9EF4E49716D98FB66C349CB956DDE33CAAE1BEA93AC395C84B3F58FCDAEF3F58F9DEF5F7EDB527578D1711A754BFE19718A41CA16FAB7C106194455EEAF4E0D4FA29D2BF224B328F7B546382F2FB4E8EE41C96ECAB2341163B26330CB
-20220414092153 2 6 100 4095 2 F32919EC12E2FE5DCC900B63D26BA6DD1030C9D818431D43D7629C26DF0B797B85C4DE6D39A179EFDBF452D6FAEAFF7D89C80E2BF78133324537D863C67C527C8C8D321CCB69E1B4A97675179F0D581560D1BB4CB5FC0EE1BBE740DC53E81D509A2AB1C502E02196CB7910868E93FE8151C148430654A623949C8C985F169D78CF7143FADEA9363103FABE79F14F966061DAE8202CE667C23877B4375148E3FE6969270D90C0BB11983A725320FE2E110452D56CD29924687638285FF60F528FBCC8F9F21D1AF2C150265F6846BABF083F10B43D92FCC02F5794034DE043ED9EDD2088E590314930FDECCAF3BDE0D07ED9DB167BF2AF1634EF88C77D3016BFC17B0903449E3611BE247665FD4A2A4F1D988C67BA1B81B4C9453ADF5C98EEB584C5FB25F8B0EA3606C80A459DD58B0D10E50FE9A7E062E9E918765B1C5D2BE056F846BC7BBA649F2BCE549B2FA5A55D3F31388C1EFEA4E8F2800A2A050E8468E8DDD4DA986C6496159A26E2CA9CA26415EE53F6403DAB022C1F19EC1B311A39495AF6A82BD1FD9AE47BF5C10B013E7CA7DAB015BDA7B60EFA5FF4916BC6CB81C5B6132AA9EF4E49716D98FB66C349CB956DDE33CAAE1BEA93AC395C84B3F58FCDAEF3F58F9DEF5F7EDB527578D1711A754BFE19718A41CA16FAB7C106194455EEAF4E0D4FA29D2BF224B328F7B546382F2FB4E8EE41C96ECAB2341163B3673963
-20220414092830 2 6 100 4095 5 F32919EC12E2FE5DCC900B63D26BA6DD1030C9D818431D43D7629C26DF0B797B85C4DE6D39A179EFDBF452D6FAEAFF7D89C80E2BF78133324537D863C67C527C8C8D321CCB69E1B4A97675179F0D581560D1BB4CB5FC0EE1BBE740DC53E81D509A2AB1C502E02196CB7910868E93FE8151C148430654A623949C8C985F169D78CF7143FADEA9363103FABE79F14F966061DAE8202CE667C23877B4375148E3FE6969270D90C0BB11983A725320FE2E110452D56CD29924687638285FF60F528FBCC8F9F21D1AF2C150265F6846BABF083F10B43D92FCC02F5794034DE043ED9EDD2088E590314930FDECCAF3BDE0D07ED9DB167BF2AF1634EF88C77D3016BFC17B0903449E3611BE247665FD4A2A4F1D988C67BA1B81B4C9453ADF5C98EEB584C5FB25F8B0EA3606C80A459DD58B0D10E50FE9A7E062E9E918765B1C5D2BE056F846BC7BBA649F2BCE549B2FA5A55D3F31388C1EFEA4E8F2800A2A050E8468E8DDD4DA986C6496159A26E2CA9CA26415EE53F6403DAB022C1F19EC1B311A39495AF6A82BD1FD9AE47BF5C10B013E7CA7DAB015BDA7B60EFA5FF4916BC6CB81C5B6132AA9EF4E49716D98FB66C349CB956DDE33CAAE1BEA93AC395C84B3F58FCDAEF3F58F9DEF5F7EDB527578D1711A754BFE19718A41CA16FAB7C106194455EEAF4E0D4FA29D2BF224B328F7B546382F2FB4E8EE41C96ECAB2341163B62CC3A7
-20220414092943 2 6 100 4095 5 F32919EC12E2FE5DCC900B63D26BA6DD1030C9D818431D43D7629C26DF0B797B85C4DE6D39A179EFDBF452D6FAEAFF7D89C80E2BF78133324537D863C67C527C8C8D321CCB69E1B4A97675179F0D581560D1BB4CB5FC0EE1BBE740DC53E81D509A2AB1C502E02196CB7910868E93FE8151C148430654A623949C8C985F169D78CF7143FADEA9363103FABE79F14F966061DAE8202CE667C23877B4375148E3FE6969270D90C0BB11983A725320FE2E110452D56CD29924687638285FF60F528FBCC8F9F21D1AF2C150265F6846BABF083F10B43D92FCC02F5794034DE043ED9EDD2088E590314930FDECCAF3BDE0D07ED9DB167BF2AF1634EF88C77D3016BFC17B0903449E3611BE247665FD4A2A4F1D988C67BA1B81B4C9453ADF5C98EEB584C5FB25F8B0EA3606C80A459DD58B0D10E50FE9A7E062E9E918765B1C5D2BE056F846BC7BBA649F2BCE549B2FA5A55D3F31388C1EFEA4E8F2800A2A050E8468E8DDD4DA986C6496159A26E2CA9CA26415EE53F6403DAB022C1F19EC1B311A39495AF6A82BD1FD9AE47BF5C10B013E7CA7DAB015BDA7B60EFA5FF4916BC6CB81C5B6132AA9EF4E49716D98FB66C349CB956DDE33CAAE1BEA93AC395C84B3F58FCDAEF3F58F9DEF5F7EDB527578D1711A754BFE19718A41CA16FAB7C106194455EEAF4E0D4FA29D2BF224B328F7B546382F2FB4E8EE41C96ECAB2341163B6A8C34F
-20220414093010 2 6 100 4095 5 F32919EC12E2FE5DCC900B63D26BA6DD1030C9D818431D43D7629C26DF0B797B85C4DE6D39A179EFDBF452D6FAEAFF7D89C80E2BF78133324537D863C67C527C8C8D321CCB69E1B4A97675179F0D581560D1BB4CB5FC0EE1BBE740DC53E81D509A2AB1C502E02196CB7910868E93FE8151C148430654A623949C8C985F169D78CF7143FADEA9363103FABE79F14F966061DAE8202CE667C23877B4375148E3FE6969270D90C0BB11983A725320FE2E110452D56CD29924687638285FF60F528FBCC8F9F21D1AF2C150265F6846BABF083F10B43D92FCC02F5794034DE043ED9EDD2088E590314930FDECCAF3BDE0D07ED9DB167BF2AF1634EF88C77D3016BFC17B0903449E3611BE247665FD4A2A4F1D988C67BA1B81B4C9453ADF5C98EEB584C5FB25F8B0EA3606C80A459DD58B0D10E50FE9A7E062E9E918765B1C5D2BE056F846BC7BBA649F2BCE549B2FA5A55D3F31388C1EFEA4E8F2800A2A050E8468E8DDD4DA986C6496159A26E2CA9CA26415EE53F6403DAB022C1F19EC1B311A39495AF6A82BD1FD9AE47BF5C10B013E7CA7DAB015BDA7B60EFA5FF4916BC6CB81C5B6132AA9EF4E49716D98FB66C349CB956DDE33CAAE1BEA93AC395C84B3F58FCDAEF3F58F9DEF5F7EDB527578D1711A754BFE19718A41CA16FAB7C106194455EEAF4E0D4FA29D2BF224B328F7B546382F2FB4E8EE41C96ECAB2341163B6D25E3F
-20220414093441 2 6 100 4095 5 F32919EC12E2FE5DCC900B63D26BA6DD1030C9D818431D43D7629C26DF0B797B85C4DE6D39A179EFDBF452D6FAEAFF7D89C80E2BF78133324537D863C67C527C8C8D321CCB69E1B4A97675179F0D581560D1BB4CB5FC0EE1BBE740DC53E81D509A2AB1C502E02196CB7910868E93FE8151C148430654A623949C8C985F169D78CF7143FADEA9363103FABE79F14F966061DAE8202CE667C23877B4375148E3FE6969270D90C0BB11983A725320FE2E110452D56CD29924687638285FF60F528FBCC8F9F21D1AF2C150265F6846BABF083F10B43D92FCC02F5794034DE043ED9EDD2088E590314930FDECCAF3BDE0D07ED9DB167BF2AF1634EF88C77D3016BFC17B0903449E3611BE247665FD4A2A4F1D988C67BA1B81B4C9453ADF5C98EEB584C5FB25F8B0EA3606C80A459DD58B0D10E50FE9A7E062E9E918765B1C5D2BE056F846BC7BBA649F2BCE549B2FA5A55D3F31388C1EFEA4E8F2800A2A050E8468E8DDD4DA986C6496159A26E2CA9CA26415EE53F6403DAB022C1F19EC1B311A39495AF6A82BD1FD9AE47BF5C10B013E7CA7DAB015BDA7B60EFA5FF4916BC6CB81C5B6132AA9EF4E49716D98FB66C349CB956DDE33CAAE1BEA93AC395C84B3F58FCDAEF3F58F9DEF5F7EDB527578D1711A754BFE19718A41CA16FAB7C106194455EEAF4E0D4FA29D2BF224B328F7B546382F2FB4E8EE41C96ECAB2341163B8C7B5FF
-20220414093544 2 6 100 4095 2 F32919EC12E2FE5DCC900B63D26BA6DD1030C9D818431D43D7629C26DF0B797B85C4DE6D39A179EFDBF452D6FAEAFF7D89C80E2BF78133324537D863C67C527C8C8D321CCB69E1B4A97675179F0D581560D1BB4CB5FC0EE1BBE740DC53E81D509A2AB1C502E02196CB7910868E93FE8151C148430654A623949C8C985F169D78CF7143FADEA9363103FABE79F14F966061DAE8202CE667C23877B4375148E3FE6969270D90C0BB11983A725320FE2E110452D56CD29924687638285FF60F528FBCC8F9F21D1AF2C150265F6846BABF083F10B43D92FCC02F5794034DE043ED9EDD2088E590314930FDECCAF3BDE0D07ED9DB167BF2AF1634EF88C77D3016BFC17B0903449E3611BE247665FD4A2A4F1D988C67BA1B81B4C9453ADF5C98EEB584C5FB25F8B0EA3606C80A459DD58B0D10E50FE9A7E062E9E918765B1C5D2BE056F846BC7BBA649F2BCE549B2FA5A55D3F31388C1EFEA4E8F2800A2A050E8468E8DDD4DA986C6496159A26E2CA9CA26415EE53F6403DAB022C1F19EC1B311A39495AF6A82BD1FD9AE47BF5C10B013E7CA7DAB015BDA7B60EFA5FF4916BC6CB81C5B6132AA9EF4E49716D98FB66C349CB956DDE33CAAE1BEA93AC395C84B3F58FCDAEF3F58F9DEF5F7EDB527578D1711A754BFE19718A41CA16FAB7C106194455EEAF4E0D4FA29D2BF224B328F7B546382F2FB4E8EE41C96ECAB2341163B934C513
-20220414093731 2 6 100 4095 5 F32919EC12E2FE5DCC900B63D26BA6DD1030C9D818431D43D7629C26DF0B797B85C4DE6D39A179EFDBF452D6FAEAFF7D89C80E2BF78133324537D863C67C527C8C8D321CCB69E1B4A97675179F0D581560D1BB4CB5FC0EE1BBE740DC53E81D509A2AB1C502E02196CB7910868E93FE8151C148430654A623949C8C985F169D78CF7143FADEA9363103FABE79F14F966061DAE8202CE667C23877B4375148E3FE6969270D90C0BB11983A725320FE2E110452D56CD29924687638285FF60F528FBCC8F9F21D1AF2C150265F6846BABF083F10B43D92FCC02F5794034DE043ED9EDD2088E590314930FDECCAF3BDE0D07ED9DB167BF2AF1634EF88C77D3016BFC17B0903449E3611BE247665FD4A2A4F1D988C67BA1B81B4C9453ADF5C98EEB584C5FB25F8B0EA3606C80A459DD58B0D10E50FE9A7E062E9E918765B1C5D2BE056F846BC7BBA649F2BCE549B2FA5A55D3F31388C1EFEA4E8F2800A2A050E8468E8DDD4DA986C6496159A26E2CA9CA26415EE53F6403DAB022C1F19EC1B311A39495AF6A82BD1FD9AE47BF5C10B013E7CA7DAB015BDA7B60EFA5FF4916BC6CB81C5B6132AA9EF4E49716D98FB66C349CB956DDE33CAAE1BEA93AC395C84B3F58FCDAEF3F58F9DEF5F7EDB527578D1711A754BFE19718A41CA16FAB7C106194455EEAF4E0D4FA29D2BF224B328F7B546382F2FB4E8EE41C96ECAB2341163B9EC8F87
-20220414093843 2 6 100 4095 2 F32919EC12E2FE5DCC900B63D26BA6DD1030C9D818431D43D7629C26DF0B797B85C4DE6D39A179EFDBF452D6FAEAFF7D89C80E2BF78133324537D863C67C527C8C8D321CCB69E1B4A97675179F0D581560D1BB4CB5FC0EE1BBE740DC53E81D509A2AB1C502E02196CB7910868E93FE8151C148430654A623949C8C985F169D78CF7143FADEA9363103FABE79F14F966061DAE8202CE667C23877B4375148E3FE6969270D90C0BB11983A725320FE2E110452D56CD29924687638285FF60F528FBCC8F9F21D1AF2C150265F6846BABF083F10B43D92FCC02F5794034DE043ED9EDD2088E590314930FDECCAF3BDE0D07ED9DB167BF2AF1634EF88C77D3016BFC17B0903449E3611BE247665FD4A2A4F1D988C67BA1B81B4C9453ADF5C98EEB584C5FB25F8B0EA3606C80A459DD58B0D10E50FE9A7E062E9E918765B1C5D2BE056F846BC7BBA649F2BCE549B2FA5A55D3F31388C1EFEA4E8F2800A2A050E8468E8DDD4DA986C6496159A26E2CA9CA26415EE53F6403DAB022C1F19EC1B311A39495AF6A82BD1FD9AE47BF5C10B013E7CA7DAB015BDA7B60EFA5FF4916BC6CB81C5B6132AA9EF4E49716D98FB66C349CB956DDE33CAAE1BEA93AC395C84B3F58FCDAEF3F58F9DEF5F7EDB527578D1711A754BFE19718A41CA16FAB7C106194455EEAF4E0D4FA29D2BF224B328F7B546382F2FB4E8EE41C96ECAB2341163BA69E11B
-20220414093925 2 6 100 4095 2 F32919EC12E2FE5DCC900B63D26BA6DD1030C9D818431D43D7629C26DF0B797B85C4DE6D39A179EFDBF452D6FAEAFF7D89C80E2BF78133324537D863C67C527C8C8D321CCB69E1B4A97675179F0D581560D1BB4CB5FC0EE1BBE740DC53E81D509A2AB1C502E02196CB7910868E93FE8151C148430654A623949C8C985F169D78CF7143FADEA9363103FABE79F14F966061DAE8202CE667C23877B4375148E3FE6969270D90C0BB11983A725320FE2E110452D56CD29924687638285FF60F528FBCC8F9F21D1AF2C150265F6846BABF083F10B43D92FCC02F5794034DE043ED9EDD2088E590314930FDECCAF3BDE0D07ED9DB167BF2AF1634EF88C77D3016BFC17B0903449E3611BE247665FD4A2A4F1D988C67BA1B81B4C9453ADF5C98EEB584C5FB25F8B0EA3606C80A459DD58B0D10E50FE9A7E062E9E918765B1C5D2BE056F846BC7BBA649F2BCE549B2FA5A55D3F31388C1EFEA4E8F2800A2A050E8468E8DDD4DA986C6496159A26E2CA9CA26415EE53F6403DAB022C1F19EC1B311A39495AF6A82BD1FD9AE47BF5C10B013E7CA7DAB015BDA7B60EFA5FF4916BC6CB81C5B6132AA9EF4E49716D98FB66C349CB956DDE33CAAE1BEA93AC395C84B3F58FCDAEF3F58F9DEF5F7EDB527578D1711A754BFE19718A41CA16FAB7C106194455EEAF4E0D4FA29D2BF224B328F7B546382F2FB4E8EE41C96ECAB2341163BAB069A3
-20220414094303 2 6 100 4095 5 F32919EC12E2FE5DCC900B63D26BA6DD1030C9D818431D43D7629C26DF0B797B85C4DE6D39A179EFDBF452D6FAEAFF7D89C80E2BF78133324537D863C67C527C8C8D321CCB69E1B4A97675179F0D581560D1BB4CB5FC0EE1BBE740DC53E81D509A2AB1C502E02196CB7910868E93FE8151C148430654A623949C8C985F169D78CF7143FADEA9363103FABE79F14F966061DAE8202CE667C23877B4375148E3FE6969270D90C0BB11983A725320FE2E110452D56CD29924687638285FF60F528FBCC8F9F21D1AF2C150265F6846BABF083F10B43D92FCC02F5794034DE043ED9EDD2088E590314930FDECCAF3BDE0D07ED9DB167BF2AF1634EF88C77D3016BFC17B0903449E3611BE247665FD4A2A4F1D988C67BA1B81B4C9453ADF5C98EEB584C5FB25F8B0EA3606C80A459DD58B0D10E50FE9A7E062E9E918765B1C5D2BE056F846BC7BBA649F2BCE549B2FA5A55D3F31388C1EFEA4E8F2800A2A050E8468E8DDD4DA986C6496159A26E2CA9CA26415EE53F6403DAB022C1F19EC1B311A39495AF6A82BD1FD9AE47BF5C10B013E7CA7DAB015BDA7B60EFA5FF4916BC6CB81C5B6132AA9EF4E49716D98FB66C349CB956DDE33CAAE1BEA93AC395C84B3F58FCDAEF3F58F9DEF5F7EDB527578D1711A754BFE19718A41CA16FAB7C106194455EEAF4E0D4FA29D2BF224B328F7B546382F2FB4E8EE41C96ECAB2341163BC328B97
-20220414094931 2 6 100 4095 5 E8B371757422F6F4C734F2E4380126789768169B37154E4E3A4A74A3DF6545653A5970CDE0F0BD17CCFDAABBEE7568E1285D5A704BB9739EAB680D7EF59C134D327B55CF4AD69A4128536E2F055F5FBF0DB661C322A4993E382B997B2A0C5E434678B1910862AE385C415FF811BA11727CFE39C559847E710AC2D4BDA8D658F2259887E78D54179287BFE112E9C532CB1D062419DFF6E031F82EC991523A1144385189A813DFACBC63D8DAD98199696715C6BC5A22A1943B2CFC4BDAD8473FBEB7BCEC204EC12CFDB1A9BB66DCF85B3121C9E1C3587960769115B2F27ACEEC29A1CDC717B7505A561051F0E88A3C51798CD829E234ED14C277E9635B3E05EB13FA36F117B46094CA68F45F3667D6E84E0214F1650BF080CC4CC5510D6569E0226E88CD842B2ACFBD31370B136E5FD22C6697090586F38323AB36FB5569FB0FD53BB4AF10C16F0B809C1FB5B1B1C56027244F5A174A37250721197CE425CB5E5C5A51D4A5EA4A1EBEED71511BBE0BFF03CB1AE76968166167A775AB1AD9C9665C6ACC04203E5B2E80AA9F7CF395C28EC432A36A97CDBB354E20BEA600F383D7729DE8B9DF5B16B721BEE8C6ADF51DA8EF5B7B3367EC8E6788F9772835586D09A9F8423AF1221CA87CBD54EC399E0BE49AEF19C017EEF36B3B18517DB2246EABBB21F6DF5CA2F4E1D178D0F42384CA192AA1461452BBC453FB59C54818DA7CECB7
-20220414095121 2 6 100 4095 5 E8B371757422F6F4C734F2E4380126789768169B37154E4E3A4A74A3DF6545653A5970CDE0F0BD17CCFDAABBEE7568E1285D5A704BB9739EAB680D7EF59C134D327B55CF4AD69A4128536E2F055F5FBF0DB661C322A4993E382B997B2A0C5E434678B1910862AE385C415FF811BA11727CFE39C559847E710AC2D4BDA8D658F2259887E78D54179287BFE112E9C532CB1D062419DFF6E031F82EC991523A1144385189A813DFACBC63D8DAD98199696715C6BC5A22A1943B2CFC4BDAD8473FBEB7BCEC204EC12CFDB1A9BB66DCF85B3121C9E1C3587960769115B2F27ACEEC29A1CDC717B7505A561051F0E88A3C51798CD829E234ED14C277E9635B3E05EB13FA36F117B46094CA68F45F3667D6E84E0214F1650BF080CC4CC5510D6569E0226E88CD842B2ACFBD31370B136E5FD22C6697090586F38323AB36FB5569FB0FD53BB4AF10C16F0B809C1FB5B1B1C56027244F5A174A37250721197CE425CB5E5C5A51D4A5EA4A1EBEED71511BBE0BFF03CB1AE76968166167A775AB1AD9C9665C6ACC04203E5B2E80AA9F7CF395C28EC432A36A97CDBB354E20BEA600F383D7729DE8B9DF5B16B721BEE8C6ADF51DA8EF5B7B3367EC8E6788F9772835586D09A9F8423AF1221CA87CBD54EC399E0BE49AEF19C017EEF36B3B18517DB2246EABBB21F6DF5CA2F4E1D178D0F42384CA192AA1461452BBC453FB59C54818DB3FEE97
-20220414095821 2 6 100 4095 2 E8B371757422F6F4C734F2E4380126789768169B37154E4E3A4A74A3DF6545653A5970CDE0F0BD17CCFDAABBEE7568E1285D5A704BB9739EAB680D7EF59C134D327B55CF4AD69A4128536E2F055F5FBF0DB661C322A4993E382B997B2A0C5E434678B1910862AE385C415FF811BA11727CFE39C559847E710AC2D4BDA8D658F2259887E78D54179287BFE112E9C532CB1D062419DFF6E031F82EC991523A1144385189A813DFACBC63D8DAD98199696715C6BC5A22A1943B2CFC4BDAD8473FBEB7BCEC204EC12CFDB1A9BB66DCF85B3121C9E1C3587960769115B2F27ACEEC29A1CDC717B7505A561051F0E88A3C51798CD829E234ED14C277E9635B3E05EB13FA36F117B46094CA68F45F3667D6E84E0214F1650BF080CC4CC5510D6569E0226E88CD842B2ACFBD31370B136E5FD22C6697090586F38323AB36FB5569FB0FD53BB4AF10C16F0B809C1FB5B1B1C56027244F5A174A37250721197CE425CB5E5C5A51D4A5EA4A1EBEED71511BBE0BFF03CB1AE76968166167A775AB1AD9C9665C6ACC04203E5B2E80AA9F7CF395C28EC432A36A97CDBB354E20BEA600F383D7729DE8B9DF5B16B721BEE8C6ADF51DA8EF5B7B3367EC8E6788F9772835586D09A9F8423AF1221CA87CBD54EC399E0BE49AEF19C017EEF36B3B18517DB2246EABBB21F6DF5CA2F4E1D178D0F42384CA192AA1461452BBC453FB59C54818DE590FC3
-20220414100127 2 6 100 4095 2 E8B371757422F6F4C734F2E4380126789768169B37154E4E3A4A74A3DF6545653A5970CDE0F0BD17CCFDAABBEE7568E1285D5A704BB9739EAB680D7EF59C134D327B55CF4AD69A4128536E2F055F5FBF0DB661C322A4993E382B997B2A0C5E434678B1910862AE385C415FF811BA11727CFE39C559847E710AC2D4BDA8D658F2259887E78D54179287BFE112E9C532CB1D062419DFF6E031F82EC991523A1144385189A813DFACBC63D8DAD98199696715C6BC5A22A1943B2CFC4BDAD8473FBEB7BCEC204EC12CFDB1A9BB66DCF85B3121C9E1C3587960769115B2F27ACEEC29A1CDC717B7505A561051F0E88A3C51798CD829E234ED14C277E9635B3E05EB13FA36F117B46094CA68F45F3667D6E84E0214F1650BF080CC4CC5510D6569E0226E88CD842B2ACFBD31370B136E5FD22C6697090586F38323AB36FB5569FB0FD53BB4AF10C16F0B809C1FB5B1B1C56027244F5A174A37250721197CE425CB5E5C5A51D4A5EA4A1EBEED71511BBE0BFF03CB1AE76968166167A775AB1AD9C9665C6ACC04203E5B2E80AA9F7CF395C28EC432A36A97CDBB354E20BEA600F383D7729DE8B9DF5B16B721BEE8C6ADF51DA8EF5B7B3367EC8E6788F9772835586D09A9F8423AF1221CA87CBD54EC399E0BE49AEF19C017EEF36B3B18517DB2246EABBB21F6DF5CA2F4E1D178D0F42384CA192AA1461452BBC453FB59C54818DFAAB9F3
-20220414100220 2 6 100 4095 2 E8B371757422F6F4C734F2E4380126789768169B37154E4E3A4A74A3DF6545653A5970CDE0F0BD17CCFDAABBEE7568E1285D5A704BB9739EAB680D7EF59C134D327B55CF4AD69A4128536E2F055F5FBF0DB661C322A4993E382B997B2A0C5E434678B1910862AE385C415FF811BA11727CFE39C559847E710AC2D4BDA8D658F2259887E78D54179287BFE112E9C532CB1D062419DFF6E031F82EC991523A1144385189A813DFACBC63D8DAD98199696715C6BC5A22A1943B2CFC4BDAD8473FBEB7BCEC204EC12CFDB1A9BB66DCF85B3121C9E1C3587960769115B2F27ACEEC29A1CDC717B7505A561051F0E88A3C51798CD829E234ED14C277E9635B3E05EB13FA36F117B46094CA68F45F3667D6E84E0214F1650BF080CC4CC5510D6569E0226E88CD842B2ACFBD31370B136E5FD22C6697090586F38323AB36FB5569FB0FD53BB4AF10C16F0B809C1FB5B1B1C56027244F5A174A37250721197CE425CB5E5C5A51D4A5EA4A1EBEED71511BBE0BFF03CB1AE76968166167A775AB1AD9C9665C6ACC04203E5B2E80AA9F7CF395C28EC432A36A97CDBB354E20BEA600F383D7729DE8B9DF5B16B721BEE8C6ADF51DA8EF5B7B3367EC8E6788F9772835586D09A9F8423AF1221CA87CBD54EC399E0BE49AEF19C017EEF36B3B18517DB2246EABBB21F6DF5CA2F4E1D178D0F42384CA192AA1461452BBC453FB59C54818E005F20B
-20220414100244 2 6 100 4095 2 E8B371757422F6F4C734F2E4380126789768169B37154E4E3A4A74A3DF6545653A5970CDE0F0BD17CCFDAABBEE7568E1285D5A704BB9739EAB680D7EF59C134D327B55CF4AD69A4128536E2F055F5FBF0DB661C322A4993E382B997B2A0C5E434678B1910862AE385C415FF811BA11727CFE39C559847E710AC2D4BDA8D658F2259887E78D54179287BFE112E9C532CB1D062419DFF6E031F82EC991523A1144385189A813DFACBC63D8DAD98199696715C6BC5A22A1943B2CFC4BDAD8473FBEB7BCEC204EC12CFDB1A9BB66DCF85B3121C9E1C3587960769115B2F27ACEEC29A1CDC717B7505A561051F0E88A3C51798CD829E234ED14C277E9635B3E05EB13FA36F117B46094CA68F45F3667D6E84E0214F1650BF080CC4CC5510D6569E0226E88CD842B2ACFBD31370B136E5FD22C6697090586F38323AB36FB5569FB0FD53BB4AF10C16F0B809C1FB5B1B1C56027244F5A174A37250721197CE425CB5E5C5A51D4A5EA4A1EBEED71511BBE0BFF03CB1AE76968166167A775AB1AD9C9665C6ACC04203E5B2E80AA9F7CF395C28EC432A36A97CDBB354E20BEA600F383D7729DE8B9DF5B16B721BEE8C6ADF51DA8EF5B7B3367EC8E6788F9772835586D09A9F8423AF1221CA87CBD54EC399E0BE49AEF19C017EEF36B3B18517DB2246EABBB21F6DF5CA2F4E1D178D0F42384CA192AA1461452BBC453FB59C54818E029D1B3
-20220414100254 2 6 100 4095 2 E8B371757422F6F4C734F2E4380126789768169B37154E4E3A4A74A3DF6545653A5970CDE0F0BD17CCFDAABBEE7568E1285D5A704BB9739EAB680D7EF59C134D327B55CF4AD69A4128536E2F055F5FBF0DB661C322A4993E382B997B2A0C5E434678B1910862AE385C415FF811BA11727CFE39C559847E710AC2D4BDA8D658F2259887E78D54179287BFE112E9C532CB1D062419DFF6E031F82EC991523A1144385189A813DFACBC63D8DAD98199696715C6BC5A22A1943B2CFC4BDAD8473FBEB7BCEC204EC12CFDB1A9BB66DCF85B3121C9E1C3587960769115B2F27ACEEC29A1CDC717B7505A561051F0E88A3C51798CD829E234ED14C277E9635B3E05EB13FA36F117B46094CA68F45F3667D6E84E0214F1650BF080CC4CC5510D6569E0226E88CD842B2ACFBD31370B136E5FD22C6697090586F38323AB36FB5569FB0FD53BB4AF10C16F0B809C1FB5B1B1C56027244F5A174A37250721197CE425CB5E5C5A51D4A5EA4A1EBEED71511BBE0BFF03CB1AE76968166167A775AB1AD9C9665C6ACC04203E5B2E80AA9F7CF395C28EC432A36A97CDBB354E20BEA600F383D7729DE8B9DF5B16B721BEE8C6ADF51DA8EF5B7B3367EC8E6788F9772835586D09A9F8423AF1221CA87CBD54EC399E0BE49AEF19C017EEF36B3B18517DB2246EABBB21F6DF5CA2F4E1D178D0F42384CA192AA1461452BBC453FB59C54818E034AA33
-20220414100620 2 6 100 4095 2 E8B371757422F6F4C734F2E4380126789768169B37154E4E3A4A74A3DF6545653A5970CDE0F0BD17CCFDAABBEE7568E1285D5A704BB9739EAB680D7EF59C134D327B55CF4AD69A4128536E2F055F5FBF0DB661C322A4993E382B997B2A0C5E434678B1910862AE385C415FF811BA11727CFE39C559847E710AC2D4BDA8D658F2259887E78D54179287BFE112E9C532CB1D062419DFF6E031F82EC991523A1144385189A813DFACBC63D8DAD98199696715C6BC5A22A1943B2CFC4BDAD8473FBEB7BCEC204EC12CFDB1A9BB66DCF85B3121C9E1C3587960769115B2F27ACEEC29A1CDC717B7505A561051F0E88A3C51798CD829E234ED14C277E9635B3E05EB13FA36F117B46094CA68F45F3667D6E84E0214F1650BF080CC4CC5510D6569E0226E88CD842B2ACFBD31370B136E5FD22C6697090586F38323AB36FB5569FB0FD53BB4AF10C16F0B809C1FB5B1B1C56027244F5A174A37250721197CE425CB5E5C5A51D4A5EA4A1EBEED71511BBE0BFF03CB1AE76968166167A775AB1AD9C9665C6ACC04203E5B2E80AA9F7CF395C28EC432A36A97CDBB354E20BEA600F383D7729DE8B9DF5B16B721BEE8C6ADF51DA8EF5B7B3367EC8E6788F9772835586D09A9F8423AF1221CA87CBD54EC399E0BE49AEF19C017EEF36B3B18517DB2246EABBB21F6DF5CA2F4E1D178D0F42384CA192AA1461452BBC453FB59C54818E1B8C073
-20220414100630 2 6 100 4095 2 E8B371757422F6F4C734F2E4380126789768169B37154E4E3A4A74A3DF6545653A5970CDE0F0BD17CCFDAABBEE7568E1285D5A704BB9739EAB680D7EF59C134D327B55CF4AD69A4128536E2F055F5FBF0DB661C322A4993E382B997B2A0C5E434678B1910862AE385C415FF811BA11727CFE39C559847E710AC2D4BDA8D658F2259887E78D54179287BFE112E9C532CB1D062419DFF6E031F82EC991523A1144385189A813DFACBC63D8DAD98199696715C6BC5A22A1943B2CFC4BDAD8473FBEB7BCEC204EC12CFDB1A9BB66DCF85B3121C9E1C3587960769115B2F27ACEEC29A1CDC717B7505A561051F0E88A3C51798CD829E234ED14C277E9635B3E05EB13FA36F117B46094CA68F45F3667D6E84E0214F1650BF080CC4CC5510D6569E0226E88CD842B2ACFBD31370B136E5FD22C6697090586F38323AB36FB5569FB0FD53BB4AF10C16F0B809C1FB5B1B1C56027244F5A174A37250721197CE425CB5E5C5A51D4A5EA4A1EBEED71511BBE0BFF03CB1AE76968166167A775AB1AD9C9665C6ACC04203E5B2E80AA9F7CF395C28EC432A36A97CDBB354E20BEA600F383D7729DE8B9DF5B16B721BEE8C6ADF51DA8EF5B7B3367EC8E6788F9772835586D09A9F8423AF1221CA87CBD54EC399E0BE49AEF19C017EEF36B3B18517DB2246EABBB21F6DF5CA2F4E1D178D0F42384CA192AA1461452BBC453FB59C54818E1C2553B
-20220414101142 2 6 100 4095 2 E8B371757422F6F4C734F2E4380126789768169B37154E4E3A4A74A3DF6545653A5970CDE0F0BD17CCFDAABBEE7568E1285D5A704BB9739EAB680D7EF59C134D327B55CF4AD69A4128536E2F055F5FBF0DB661C322A4993E382B997B2A0C5E434678B1910862AE385C415FF811BA11727CFE39C559847E710AC2D4BDA8D658F2259887E78D54179287BFE112E9C532CB1D062419DFF6E031F82EC991523A1144385189A813DFACBC63D8DAD98199696715C6BC5A22A1943B2CFC4BDAD8473FBEB7BCEC204EC12CFDB1A9BB66DCF85B3121C9E1C3587960769115B2F27ACEEC29A1CDC717B7505A561051F0E88A3C51798CD829E234ED14C277E9635B3E05EB13FA36F117B46094CA68F45F3667D6E84E0214F1650BF080CC4CC5510D6569E0226E88CD842B2ACFBD31370B136E5FD22C6697090586F38323AB36FB5569FB0FD53BB4AF10C16F0B809C1FB5B1B1C56027244F5A174A37250721197CE425CB5E5C5A51D4A5EA4A1EBEED71511BBE0BFF03CB1AE76968166167A775AB1AD9C9665C6ACC04203E5B2E80AA9F7CF395C28EC432A36A97CDBB354E20BEA600F383D7729DE8B9DF5B16B721BEE8C6ADF51DA8EF5B7B3367EC8E6788F9772835586D09A9F8423AF1221CA87CBD54EC399E0BE49AEF19C017EEF36B3B18517DB2246EABBB21F6DF5CA2F4E1D178D0F42384CA192AA1461452BBC453FB59C54818E40A1E13
-20220414101258 2 6 100 4095 5 E8B371757422F6F4C734F2E4380126789768169B37154E4E3A4A74A3DF6545653A5970CDE0F0BD17CCFDAABBEE7568E1285D5A704BB9739EAB680D7EF59C134D327B55CF4AD69A4128536E2F055F5FBF0DB661C322A4993E382B997B2A0C5E434678B1910862AE385C415FF811BA11727CFE39C559847E710AC2D4BDA8D658F2259887E78D54179287BFE112E9C532CB1D062419DFF6E031F82EC991523A1144385189A813DFACBC63D8DAD98199696715C6BC5A22A1943B2CFC4BDAD8473FBEB7BCEC204EC12CFDB1A9BB66DCF85B3121C9E1C3587960769115B2F27ACEEC29A1CDC717B7505A561051F0E88A3C51798CD829E234ED14C277E9635B3E05EB13FA36F117B46094CA68F45F3667D6E84E0214F1650BF080CC4CC5510D6569E0226E88CD842B2ACFBD31370B136E5FD22C6697090586F38323AB36FB5569FB0FD53BB4AF10C16F0B809C1FB5B1B1C56027244F5A174A37250721197CE425CB5E5C5A51D4A5EA4A1EBEED71511BBE0BFF03CB1AE76968166167A775AB1AD9C9665C6ACC04203E5B2E80AA9F7CF395C28EC432A36A97CDBB354E20BEA600F383D7729DE8B9DF5B16B721BEE8C6ADF51DA8EF5B7B3367EC8E6788F9772835586D09A9F8423AF1221CA87CBD54EC399E0BE49AEF19C017EEF36B3B18517DB2246EABBB21F6DF5CA2F4E1D178D0F42384CA192AA1461452BBC453FB59C54818E48D9E87
-20220414101626 2 6 100 4095 2 E8B371757422F6F4C734F2E4380126789768169B37154E4E3A4A74A3DF6545653A5970CDE0F0BD17CCFDAABBEE7568E1285D5A704BB9739EAB680D7EF59C134D327B55CF4AD69A4128536E2F055F5FBF0DB661C322A4993E382B997B2A0C5E434678B1910862AE385C415FF811BA11727CFE39C559847E710AC2D4BDA8D658F2259887E78D54179287BFE112E9C532CB1D062419DFF6E031F82EC991523A1144385189A813DFACBC63D8DAD98199696715C6BC5A22A1943B2CFC4BDAD8473FBEB7BCEC204EC12CFDB1A9BB66DCF85B3121C9E1C3587960769115B2F27ACEEC29A1CDC717B7505A561051F0E88A3C51798CD829E234ED14C277E9635B3E05EB13FA36F117B46094CA68F45F3667D6E84E0214F1650BF080CC4CC5510D6569E0226E88CD842B2ACFBD31370B136E5FD22C6697090586F38323AB36FB5569FB0FD53BB4AF10C16F0B809C1FB5B1B1C56027244F5A174A37250721197CE425CB5E5C5A51D4A5EA4A1EBEED71511BBE0BFF03CB1AE76968166167A775AB1AD9C9665C6ACC04203E5B2E80AA9F7CF395C28EC432A36A97CDBB354E20BEA600F383D7729DE8B9DF5B16B721BEE8C6ADF51DA8EF5B7B3367EC8E6788F9772835586D09A9F8423AF1221CA87CBD54EC399E0BE49AEF19C017EEF36B3B18517DB2246EABBB21F6DF5CA2F4E1D178D0F42384CA192AA1461452BBC453FB59C54818E60387F3
-20220414101801 2 6 100 4095 2 E8B371757422F6F4C734F2E4380126789768169B37154E4E3A4A74A3DF6545653A5970CDE0F0BD17CCFDAABBEE7568E1285D5A704BB9739EAB680D7EF59C134D327B55CF4AD69A4128536E2F055F5FBF0DB661C322A4993E382B997B2A0C5E434678B1910862AE385C415FF811BA11727CFE39C559847E710AC2D4BDA8D658F2259887E78D54179287BFE112E9C532CB1D062419DFF6E031F82EC991523A1144385189A813DFACBC63D8DAD98199696715C6BC5A22A1943B2CFC4BDAD8473FBEB7BCEC204EC12CFDB1A9BB66DCF85B3121C9E1C3587960769115B2F27ACEEC29A1CDC717B7505A561051F0E88A3C51798CD829E234ED14C277E9635B3E05EB13FA36F117B46094CA68F45F3667D6E84E0214F1650BF080CC4CC5510D6569E0226E88CD842B2ACFBD31370B136E5FD22C6697090586F38323AB36FB5569FB0FD53BB4AF10C16F0B809C1FB5B1B1C56027244F5A174A37250721197CE425CB5E5C5A51D4A5EA4A1EBEED71511BBE0BFF03CB1AE76968166167A775AB1AD9C9665C6ACC04203E5B2E80AA9F7CF395C28EC432A36A97CDBB354E20BEA600F383D7729DE8B9DF5B16B721BEE8C6ADF51DA8EF5B7B3367EC8E6788F9772835586D09A9F8423AF1221CA87CBD54EC399E0BE49AEF19C017EEF36B3B18517DB2246EABBB21F6DF5CA2F4E1D178D0F42384CA192AA1461452BBC453FB59C54818E6A9F503
-20220414102152 2 6 100 4095 5 E8B371757422F6F4C734F2E4380126789768169B37154E4E3A4A74A3DF6545653A5970CDE0F0BD17CCFDAABBEE7568E1285D5A704BB9739EAB680D7EF59C134D327B55CF4AD69A4128536E2F055F5FBF0DB661C322A4993E382B997B2A0C5E434678B1910862AE385C415FF811BA11727CFE39C559847E710AC2D4BDA8D658F2259887E78D54179287BFE112E9C532CB1D062419DFF6E031F82EC991523A1144385189A813DFACBC63D8DAD98199696715C6BC5A22A1943B2CFC4BDAD8473FBEB7BCEC204EC12CFDB1A9BB66DCF85B3121C9E1C3587960769115B2F27ACEEC29A1CDC717B7505A561051F0E88A3C51798CD829E234ED14C277E9635B3E05EB13FA36F117B46094CA68F45F3667D6E84E0214F1650BF080CC4CC5510D6569E0226E88CD842B2ACFBD31370B136E5FD22C6697090586F38323AB36FB5569FB0FD53BB4AF10C16F0B809C1FB5B1B1C56027244F5A174A37250721197CE425CB5E5C5A51D4A5EA4A1EBEED71511BBE0BFF03CB1AE76968166167A775AB1AD9C9665C6ACC04203E5B2E80AA9F7CF395C28EC432A36A97CDBB354E20BEA600F383D7729DE8B9DF5B16B721BEE8C6ADF51DA8EF5B7B3367EC8E6788F9772835586D09A9F8423AF1221CA87CBD54EC399E0BE49AEF19C017EEF36B3B18517DB2246EABBB21F6DF5CA2F4E1D178D0F42384CA192AA1461452BBC453FB59C54818E84F18E7
-20220414102225 2 6 100 4095 5 E8B371757422F6F4C734F2E4380126789768169B37154E4E3A4A74A3DF6545653A5970CDE0F0BD17CCFDAABBEE7568E1285D5A704BB9739EAB680D7EF59C134D327B55CF4AD69A4128536E2F055F5FBF0DB661C322A4993E382B997B2A0C5E434678B1910862AE385C415FF811BA11727CFE39C559847E710AC2D4BDA8D658F2259887E78D54179287BFE112E9C532CB1D062419DFF6E031F82EC991523A1144385189A813DFACBC63D8DAD98199696715C6BC5A22A1943B2CFC4BDAD8473FBEB7BCEC204EC12CFDB1A9BB66DCF85B3121C9E1C3587960769115B2F27ACEEC29A1CDC717B7505A561051F0E88A3C51798CD829E234ED14C277E9635B3E05EB13FA36F117B46094CA68F45F3667D6E84E0214F1650BF080CC4CC5510D6569E0226E88CD842B2ACFBD31370B136E5FD22C6697090586F38323AB36FB5569FB0FD53BB4AF10C16F0B809C1FB5B1B1C56027244F5A174A37250721197CE425CB5E5C5A51D4A5EA4A1EBEED71511BBE0BFF03CB1AE76968166167A775AB1AD9C9665C6ACC04203E5B2E80AA9F7CF395C28EC432A36A97CDBB354E20BEA600F383D7729DE8B9DF5B16B721BEE8C6ADF51DA8EF5B7B3367EC8E6788F9772835586D09A9F8423AF1221CA87CBD54EC399E0BE49AEF19C017EEF36B3B18517DB2246EABBB21F6DF5CA2F4E1D178D0F42384CA192AA1461452BBC453FB59C54818E886BDBF
-20220414102443 2 6 100 4095 2 E8B371757422F6F4C734F2E4380126789768169B37154E4E3A4A74A3DF6545653A5970CDE0F0BD17CCFDAABBEE7568E1285D5A704BB9739EAB680D7EF59C134D327B55CF4AD69A4128536E2F055F5FBF0DB661C322A4993E382B997B2A0C5E434678B1910862AE385C415FF811BA11727CFE39C559847E710AC2D4BDA8D658F2259887E78D54179287BFE112E9C532CB1D062419DFF6E031F82EC991523A1144385189A813DFACBC63D8DAD98199696715C6BC5A22A1943B2CFC4BDAD8473FBEB7BCEC204EC12CFDB1A9BB66DCF85B3121C9E1C3587960769115B2F27ACEEC29A1CDC717B7505A561051F0E88A3C51798CD829E234ED14C277E9635B3E05EB13FA36F117B46094CA68F45F3667D6E84E0214F1650BF080CC4CC5510D6569E0226E88CD842B2ACFBD31370B136E5FD22C6697090586F38323AB36FB5569FB0FD53BB4AF10C16F0B809C1FB5B1B1C56027244F5A174A37250721197CE425CB5E5C5A51D4A5EA4A1EBEED71511BBE0BFF03CB1AE76968166167A775AB1AD9C9665C6ACC04203E5B2E80AA9F7CF395C28EC432A36A97CDBB354E20BEA600F383D7729DE8B9DF5B16B721BEE8C6ADF51DA8EF5B7B3367EC8E6788F9772835586D09A9F8423AF1221CA87CBD54EC399E0BE49AEF19C017EEF36B3B18517DB2246EABBB21F6DF5CA2F4E1D178D0F42384CA192AA1461452BBC453FB59C54818E97C4BFB
-20220414102556 2 6 100 4095 5 E8B371757422F6F4C734F2E4380126789768169B37154E4E3A4A74A3DF6545653A5970CDE0F0BD17CCFDAABBEE7568E1285D5A704BB9739EAB680D7EF59C134D327B55CF4AD69A4128536E2F055F5FBF0DB661C322A4993E382B997B2A0C5E434678B1910862AE385C415FF811BA11727CFE39C559847E710AC2D4BDA8D658F2259887E78D54179287BFE112E9C532CB1D062419DFF6E031F82EC991523A1144385189A813DFACBC63D8DAD98199696715C6BC5A22A1943B2CFC4BDAD8473FBEB7BCEC204EC12CFDB1A9BB66DCF85B3121C9E1C3587960769115B2F27ACEEC29A1CDC717B7505A561051F0E88A3C51798CD829E234ED14C277E9635B3E05EB13FA36F117B46094CA68F45F3667D6E84E0214F1650BF080CC4CC5510D6569E0226E88CD842B2ACFBD31370B136E5FD22C6697090586F38323AB36FB5569FB0FD53BB4AF10C16F0B809C1FB5B1B1C56027244F5A174A37250721197CE425CB5E5C5A51D4A5EA4A1EBEED71511BBE0BFF03CB1AE76968166167A775AB1AD9C9665C6ACC04203E5B2E80AA9F7CF395C28EC432A36A97CDBB354E20BEA600F383D7729DE8B9DF5B16B721BEE8C6ADF51DA8EF5B7B3367EC8E6788F9772835586D09A9F8423AF1221CA87CBD54EC399E0BE49AEF19C017EEF36B3B18517DB2246EABBB21F6DF5CA2F4E1D178D0F42384CA192AA1461452BBC453FB59C54818EA01679F
-20220414102609 2 6 100 4095 5 E8B371757422F6F4C734F2E4380126789768169B37154E4E3A4A74A3DF6545653A5970CDE0F0BD17CCFDAABBEE7568E1285D5A704BB9739EAB680D7EF59C134D327B55CF4AD69A4128536E2F055F5FBF0DB661C322A4993E382B997B2A0C5E434678B1910862AE385C415FF811BA11727CFE39C559847E710AC2D4BDA8D658F2259887E78D54179287BFE112E9C532CB1D062419DFF6E031F82EC991523A1144385189A813DFACBC63D8DAD98199696715C6BC5A22A1943B2CFC4BDAD8473FBEB7BCEC204EC12CFDB1A9BB66DCF85B3121C9E1C3587960769115B2F27ACEEC29A1CDC717B7505A561051F0E88A3C51798CD829E234ED14C277E9635B3E05EB13FA36F117B46094CA68F45F3667D6E84E0214F1650BF080CC4CC5510D6569E0226E88CD842B2ACFBD31370B136E5FD22C6697090586F38323AB36FB5569FB0FD53BB4AF10C16F0B809C1FB5B1B1C56027244F5A174A37250721197CE425CB5E5C5A51D4A5EA4A1EBEED71511BBE0BFF03CB1AE76968166167A775AB1AD9C9665C6ACC04203E5B2E80AA9F7CF395C28EC432A36A97CDBB354E20BEA600F383D7729DE8B9DF5B16B721BEE8C6ADF51DA8EF5B7B3367EC8E6788F9772835586D09A9F8423AF1221CA87CBD54EC399E0BE49AEF19C017EEF36B3B18517DB2246EABBB21F6DF5CA2F4E1D178D0F42384CA192AA1461452BBC453FB59C54818EA10FE8F
-20220414102639 2 6 100 4095 2 E8B371757422F6F4C734F2E4380126789768169B37154E4E3A4A74A3DF6545653A5970CDE0F0BD17CCFDAABBEE7568E1285D5A704BB9739EAB680D7EF59C134D327B55CF4AD69A4128536E2F055F5FBF0DB661C322A4993E382B997B2A0C5E434678B1910862AE385C415FF811BA11727CFE39C559847E710AC2D4BDA8D658F2259887E78D54179287BFE112E9C532CB1D062419DFF6E031F82EC991523A1144385189A813DFACBC63D8DAD98199696715C6BC5A22A1943B2CFC4BDAD8473FBEB7BCEC204EC12CFDB1A9BB66DCF85B3121C9E1C3587960769115B2F27ACEEC29A1CDC717B7505A561051F0E88A3C51798CD829E234ED14C277E9635B3E05EB13FA36F117B46094CA68F45F3667D6E84E0214F1650BF080CC4CC5510D6569E0226E88CD842B2ACFBD31370B136E5FD22C6697090586F38323AB36FB5569FB0FD53BB4AF10C16F0B809C1FB5B1B1C56027244F5A174A37250721197CE425CB5E5C5A51D4A5EA4A1EBEED71511BBE0BFF03CB1AE76968166167A775AB1AD9C9665C6ACC04203E5B2E80AA9F7CF395C28EC432A36A97CDBB354E20BEA600F383D7729DE8B9DF5B16B721BEE8C6ADF51DA8EF5B7B3367EC8E6788F9772835586D09A9F8423AF1221CA87CBD54EC399E0BE49AEF19C017EEF36B3B18517DB2246EABBB21F6DF5CA2F4E1D178D0F42384CA192AA1461452BBC453FB59C54818EA3F86AB
-20220414102917 2 6 100 4095 5 E8B371757422F6F4C734F2E4380126789768169B37154E4E3A4A74A3DF6545653A5970CDE0F0BD17CCFDAABBEE7568E1285D5A704BB9739EAB680D7EF59C134D327B55CF4AD69A4128536E2F055F5FBF0DB661C322A4993E382B997B2A0C5E434678B1910862AE385C415FF811BA11727CFE39C559847E710AC2D4BDA8D658F2259887E78D54179287BFE112E9C532CB1D062419DFF6E031F82EC991523A1144385189A813DFACBC63D8DAD98199696715C6BC5A22A1943B2CFC4BDAD8473FBEB7BCEC204EC12CFDB1A9BB66DCF85B3121C9E1C3587960769115B2F27ACEEC29A1CDC717B7505A561051F0E88A3C51798CD829E234ED14C277E9635B3E05EB13FA36F117B46094CA68F45F3667D6E84E0214F1650BF080CC4CC5510D6569E0226E88CD842B2ACFBD31370B136E5FD22C6697090586F38323AB36FB5569FB0FD53BB4AF10C16F0B809C1FB5B1B1C56027244F5A174A37250721197CE425CB5E5C5A51D4A5EA4A1EBEED71511BBE0BFF03CB1AE76968166167A775AB1AD9C9665C6ACC04203E5B2E80AA9F7CF395C28EC432A36A97CDBB354E20BEA600F383D7729DE8B9DF5B16B721BEE8C6ADF51DA8EF5B7B3367EC8E6788F9772835586D09A9F8423AF1221CA87CBD54EC399E0BE49AEF19C017EEF36B3B18517DB2246EABBB21F6DF5CA2F4E1D178D0F42384CA192AA1461452BBC453FB59C54818EB641A1F
-20220414102948 2 6 100 4095 5 E8B371757422F6F4C734F2E4380126789768169B37154E4E3A4A74A3DF6545653A5970CDE0F0BD17CCFDAABBEE7568E1285D5A704BB9739EAB680D7EF59C134D327B55CF4AD69A4128536E2F055F5FBF0DB661C322A4993E382B997B2A0C5E434678B1910862AE385C415FF811BA11727CFE39C559847E710AC2D4BDA8D658F2259887E78D54179287BFE112E9C532CB1D062419DFF6E031F82EC991523A1144385189A813DFACBC63D8DAD98199696715C6BC5A22A1943B2CFC4BDAD8473FBEB7BCEC204EC12CFDB1A9BB66DCF85B3121C9E1C3587960769115B2F27ACEEC29A1CDC717B7505A561051F0E88A3C51798CD829E234ED14C277E9635B3E05EB13FA36F117B46094CA68F45F3667D6E84E0214F1650BF080CC4CC5510D6569E0226E88CD842B2ACFBD31370B136E5FD22C6697090586F38323AB36FB5569FB0FD53BB4AF10C16F0B809C1FB5B1B1C56027244F5A174A37250721197CE425CB5E5C5A51D4A5EA4A1EBEED71511BBE0BFF03CB1AE76968166167A775AB1AD9C9665C6ACC04203E5B2E80AA9F7CF395C28EC432A36A97CDBB354E20BEA600F383D7729DE8B9DF5B16B721BEE8C6ADF51DA8EF5B7B3367EC8E6788F9772835586D09A9F8423AF1221CA87CBD54EC399E0BE49AEF19C017EEF36B3B18517DB2246EABBB21F6DF5CA2F4E1D178D0F42384CA192AA1461452BBC453FB59C54818EB94F7A7
-20220414103222 2 6 100 4095 2 E8B371757422F6F4C734F2E4380126789768169B37154E4E3A4A74A3DF6545653A5970CDE0F0BD17CCFDAABBEE7568E1285D5A704BB9739EAB680D7EF59C134D327B55CF4AD69A4128536E2F055F5FBF0DB661C322A4993E382B997B2A0C5E434678B1910862AE385C415FF811BA11727CFE39C559847E710AC2D4BDA8D658F2259887E78D54179287BFE112E9C532CB1D062419DFF6E031F82EC991523A1144385189A813DFACBC63D8DAD98199696715C6BC5A22A1943B2CFC4BDAD8473FBEB7BCEC204EC12CFDB1A9BB66DCF85B3121C9E1C3587960769115B2F27ACEEC29A1CDC717B7505A561051F0E88A3C51798CD829E234ED14C277E9635B3E05EB13FA36F117B46094CA68F45F3667D6E84E0214F1650BF080CC4CC5510D6569E0226E88CD842B2ACFBD31370B136E5FD22C6697090586F38323AB36FB5569FB0FD53BB4AF10C16F0B809C1FB5B1B1C56027244F5A174A37250721197CE425CB5E5C5A51D4A5EA4A1EBEED71511BBE0BFF03CB1AE76968166167A775AB1AD9C9665C6ACC04203E5B2E80AA9F7CF395C28EC432A36A97CDBB354E20BEA600F383D7729DE8B9DF5B16B721BEE8C6ADF51DA8EF5B7B3367EC8E6788F9772835586D09A9F8423AF1221CA87CBD54EC399E0BE49AEF19C017EEF36B3B18517DB2246EABBB21F6DF5CA2F4E1D178D0F42384CA192AA1461452BBC453FB59C54818ECA88E23
-20220414103323 2 6 100 4095 5 E8B371757422F6F4C734F2E4380126789768169B37154E4E3A4A74A3DF6545653A5970CDE0F0BD17CCFDAABBEE7568E1285D5A704BB9739EAB680D7EF59C134D327B55CF4AD69A4128536E2F055F5FBF0DB661C322A4993E382B997B2A0C5E434678B1910862AE385C415FF811BA11727CFE39C559847E710AC2D4BDA8D658F2259887E78D54179287BFE112E9C532CB1D062419DFF6E031F82EC991523A1144385189A813DFACBC63D8DAD98199696715C6BC5A22A1943B2CFC4BDAD8473FBEB7BCEC204EC12CFDB1A9BB66DCF85B3121C9E1C3587960769115B2F27ACEEC29A1CDC717B7505A561051F0E88A3C51798CD829E234ED14C277E9635B3E05EB13FA36F117B46094CA68F45F3667D6E84E0214F1650BF080CC4CC5510D6569E0226E88CD842B2ACFBD31370B136E5FD22C6697090586F38323AB36FB5569FB0FD53BB4AF10C16F0B809C1FB5B1B1C56027244F5A174A37250721197CE425CB5E5C5A51D4A5EA4A1EBEED71511BBE0BFF03CB1AE76968166167A775AB1AD9C9665C6ACC04203E5B2E80AA9F7CF395C28EC432A36A97CDBB354E20BEA600F383D7729DE8B9DF5B16B721BEE8C6ADF51DA8EF5B7B3367EC8E6788F9772835586D09A9F8423AF1221CA87CBD54EC399E0BE49AEF19C017EEF36B3B18517DB2246EABBB21F6DF5CA2F4E1D178D0F42384CA192AA1461452BBC453FB59C54818ED15B99F
-20220414103354 2 6 100 4095 2 E8B371757422F6F4C734F2E4380126789768169B37154E4E3A4A74A3DF6545653A5970CDE0F0BD17CCFDAABBEE7568E1285D5A704BB9739EAB680D7EF59C134D327B55CF4AD69A4128536E2F055F5FBF0DB661C322A4993E382B997B2A0C5E434678B1910862AE385C415FF811BA11727CFE39C559847E710AC2D4BDA8D658F2259887E78D54179287BFE112E9C532CB1D062419DFF6E031F82EC991523A1144385189A813DFACBC63D8DAD98199696715C6BC5A22A1943B2CFC4BDAD8473FBEB7BCEC204EC12CFDB1A9BB66DCF85B3121C9E1C3587960769115B2F27ACEEC29A1CDC717B7505A561051F0E88A3C51798CD829E234ED14C277E9635B3E05EB13FA36F117B46094CA68F45F3667D6E84E0214F1650BF080CC4CC5510D6569E0226E88CD842B2ACFBD31370B136E5FD22C6697090586F38323AB36FB5569FB0FD53BB4AF10C16F0B809C1FB5B1B1C56027244F5A174A37250721197CE425CB5E5C5A51D4A5EA4A1EBEED71511BBE0BFF03CB1AE76968166167A775AB1AD9C9665C6ACC04203E5B2E80AA9F7CF395C28EC432A36A97CDBB354E20BEA600F383D7729DE8B9DF5B16B721BEE8C6ADF51DA8EF5B7B3367EC8E6788F9772835586D09A9F8423AF1221CA87CBD54EC399E0BE49AEF19C017EEF36B3B18517DB2246EABBB21F6DF5CA2F4E1D178D0F42384CA192AA1461452BBC453FB59C54818ED44961B
-20220414103407 2 6 100 4095 2 E8B371757422F6F4C734F2E4380126789768169B37154E4E3A4A74A3DF6545653A5970CDE0F0BD17CCFDAABBEE7568E1285D5A704BB9739EAB680D7EF59C134D327B55CF4AD69A4128536E2F055F5FBF0DB661C322A4993E382B997B2A0C5E434678B1910862AE385C415FF811BA11727CFE39C559847E710AC2D4BDA8D658F2259887E78D54179287BFE112E9C532CB1D062419DFF6E031F82EC991523A1144385189A813DFACBC63D8DAD98199696715C6BC5A22A1943B2CFC4BDAD8473FBEB7BCEC204EC12CFDB1A9BB66DCF85B3121C9E1C3587960769115B2F27ACEEC29A1CDC717B7505A561051F0E88A3C51798CD829E234ED14C277E9635B3E05EB13FA36F117B46094CA68F45F3667D6E84E0214F1650BF080CC4CC5510D6569E0226E88CD842B2ACFBD31370B136E5FD22C6697090586F38323AB36FB5569FB0FD53BB4AF10C16F0B809C1FB5B1B1C56027244F5A174A37250721197CE425CB5E5C5A51D4A5EA4A1EBEED71511BBE0BFF03CB1AE76968166167A775AB1AD9C9665C6ACC04203E5B2E80AA9F7CF395C28EC432A36A97CDBB354E20BEA600F383D7729DE8B9DF5B16B721BEE8C6ADF51DA8EF5B7B3367EC8E6788F9772835586D09A9F8423AF1221CA87CBD54EC399E0BE49AEF19C017EEF36B3B18517DB2246EABBB21F6DF5CA2F4E1D178D0F42384CA192AA1461452BBC453FB59C54818ED54ECC3
-20220414103413 2 6 100 4095 2 E8B371757422F6F4C734F2E4380126789768169B37154E4E3A4A74A3DF6545653A5970CDE0F0BD17CCFDAABBEE7568E1285D5A704BB9739EAB680D7EF59C134D327B55CF4AD69A4128536E2F055F5FBF0DB661C322A4993E382B997B2A0C5E434678B1910862AE385C415FF811BA11727CFE39C559847E710AC2D4BDA8D658F2259887E78D54179287BFE112E9C532CB1D062419DFF6E031F82EC991523A1144385189A813DFACBC63D8DAD98199696715C6BC5A22A1943B2CFC4BDAD8473FBEB7BCEC204EC12CFDB1A9BB66DCF85B3121C9E1C3587960769115B2F27ACEEC29A1CDC717B7505A561051F0E88A3C51798CD829E234ED14C277E9635B3E05EB13FA36F117B46094CA68F45F3667D6E84E0214F1650BF080CC4CC5510D6569E0226E88CD842B2ACFBD31370B136E5FD22C6697090586F38323AB36FB5569FB0FD53BB4AF10C16F0B809C1FB5B1B1C56027244F5A174A37250721197CE425CB5E5C5A51D4A5EA4A1EBEED71511BBE0BFF03CB1AE76968166167A775AB1AD9C9665C6ACC04203E5B2E80AA9F7CF395C28EC432A36A97CDBB354E20BEA600F383D7729DE8B9DF5B16B721BEE8C6ADF51DA8EF5B7B3367EC8E6788F9772835586D09A9F8423AF1221CA87CBD54EC399E0BE49AEF19C017EEF36B3B18517DB2246EABBB21F6DF5CA2F4E1D178D0F42384CA192AA1461452BBC453FB59C54818ED5700CB
-20220414103734 2 6 100 4095 2 E8B371757422F6F4C734F2E4380126789768169B37154E4E3A4A74A3DF6545653A5970CDE0F0BD17CCFDAABBEE7568E1285D5A704BB9739EAB680D7EF59C134D327B55CF4AD69A4128536E2F055F5FBF0DB661C322A4993E382B997B2A0C5E434678B1910862AE385C415FF811BA11727CFE39C559847E710AC2D4BDA8D658F2259887E78D54179287BFE112E9C532CB1D062419DFF6E031F82EC991523A1144385189A813DFACBC63D8DAD98199696715C6BC5A22A1943B2CFC4BDAD8473FBEB7BCEC204EC12CFDB1A9BB66DCF85B3121C9E1C3587960769115B2F27ACEEC29A1CDC717B7505A561051F0E88A3C51798CD829E234ED14C277E9635B3E05EB13FA36F117B46094CA68F45F3667D6E84E0214F1650BF080CC4CC5510D6569E0226E88CD842B2ACFBD31370B136E5FD22C6697090586F38323AB36FB5569FB0FD53BB4AF10C16F0B809C1FB5B1B1C56027244F5A174A37250721197CE425CB5E5C5A51D4A5EA4A1EBEED71511BBE0BFF03CB1AE76968166167A775AB1AD9C9665C6ACC04203E5B2E80AA9F7CF395C28EC432A36A97CDBB354E20BEA600F383D7729DE8B9DF5B16B721BEE8C6ADF51DA8EF5B7B3367EC8E6788F9772835586D09A9F8423AF1221CA87CBD54EC399E0BE49AEF19C017EEF36B3B18517DB2246EABBB21F6DF5CA2F4E1D178D0F42384CA192AA1461452BBC453FB59C54818EEB53ED3
-20220414103800 2 6 100 4095 5 E8B371757422F6F4C734F2E4380126789768169B37154E4E3A4A74A3DF6545653A5970CDE0F0BD17CCFDAABBEE7568E1285D5A704BB9739EAB680D7EF59C134D327B55CF4AD69A4128536E2F055F5FBF0DB661C322A4993E382B997B2A0C5E434678B1910862AE385C415FF811BA11727CFE39C559847E710AC2D4BDA8D658F2259887E78D54179287BFE112E9C532CB1D062419DFF6E031F82EC991523A1144385189A813DFACBC63D8DAD98199696715C6BC5A22A1943B2CFC4BDAD8473FBEB7BCEC204EC12CFDB1A9BB66DCF85B3121C9E1C3587960769115B2F27ACEEC29A1CDC717B7505A561051F0E88A3C51798CD829E234ED14C277E9635B3E05EB13FA36F117B46094CA68F45F3667D6E84E0214F1650BF080CC4CC5510D6569E0226E88CD842B2ACFBD31370B136E5FD22C6697090586F38323AB36FB5569FB0FD53BB4AF10C16F0B809C1FB5B1B1C56027244F5A174A37250721197CE425CB5E5C5A51D4A5EA4A1EBEED71511BBE0BFF03CB1AE76968166167A775AB1AD9C9665C6ACC04203E5B2E80AA9F7CF395C28EC432A36A97CDBB354E20BEA600F383D7729DE8B9DF5B16B721BEE8C6ADF51DA8EF5B7B3367EC8E6788F9772835586D09A9F8423AF1221CA87CBD54EC399E0BE49AEF19C017EEF36B3B18517DB2246EABBB21F6DF5CA2F4E1D178D0F42384CA192AA1461452BBC453FB59C54818EEDDB6FF
-20220414104012 2 6 100 4095 2 E8B371757422F6F4C734F2E4380126789768169B37154E4E3A4A74A3DF6545653A5970CDE0F0BD17CCFDAABBEE7568E1285D5A704BB9739EAB680D7EF59C134D327B55CF4AD69A4128536E2F055F5FBF0DB661C322A4993E382B997B2A0C5E434678B1910862AE385C415FF811BA11727CFE39C559847E710AC2D4BDA8D658F2259887E78D54179287BFE112E9C532CB1D062419DFF6E031F82EC991523A1144385189A813DFACBC63D8DAD98199696715C6BC5A22A1943B2CFC4BDAD8473FBEB7BCEC204EC12CFDB1A9BB66DCF85B3121C9E1C3587960769115B2F27ACEEC29A1CDC717B7505A561051F0E88A3C51798CD829E234ED14C277E9635B3E05EB13FA36F117B46094CA68F45F3667D6E84E0214F1650BF080CC4CC5510D6569E0226E88CD842B2ACFBD31370B136E5FD22C6697090586F38323AB36FB5569FB0FD53BB4AF10C16F0B809C1FB5B1B1C56027244F5A174A37250721197CE425CB5E5C5A51D4A5EA4A1EBEED71511BBE0BFF03CB1AE76968166167A775AB1AD9C9665C6ACC04203E5B2E80AA9F7CF395C28EC432A36A97CDBB354E20BEA600F383D7729DE8B9DF5B16B721BEE8C6ADF51DA8EF5B7B3367EC8E6788F9772835586D09A9F8423AF1221CA87CBD54EC399E0BE49AEF19C017EEF36B3B18517DB2246EABBB21F6DF5CA2F4E1D178D0F42384CA192AA1461452BBC453FB59C54818EFC5E0E3
-20220414104150 2 6 100 4095 2 E8B371757422F6F4C734F2E4380126789768169B37154E4E3A4A74A3DF6545653A5970CDE0F0BD17CCFDAABBEE7568E1285D5A704BB9739EAB680D7EF59C134D327B55CF4AD69A4128536E2F055F5FBF0DB661C322A4993E382B997B2A0C5E434678B1910862AE385C415FF811BA11727CFE39C559847E710AC2D4BDA8D658F2259887E78D54179287BFE112E9C532CB1D062419DFF6E031F82EC991523A1144385189A813DFACBC63D8DAD98199696715C6BC5A22A1943B2CFC4BDAD8473FBEB7BCEC204EC12CFDB1A9BB66DCF85B3121C9E1C3587960769115B2F27ACEEC29A1CDC717B7505A561051F0E88A3C51798CD829E234ED14C277E9635B3E05EB13FA36F117B46094CA68F45F3667D6E84E0214F1650BF080CC4CC5510D6569E0226E88CD842B2ACFBD31370B136E5FD22C6697090586F38323AB36FB5569FB0FD53BB4AF10C16F0B809C1FB5B1B1C56027244F5A174A37250721197CE425CB5E5C5A51D4A5EA4A1EBEED71511BBE0BFF03CB1AE76968166167A775AB1AD9C9665C6ACC04203E5B2E80AA9F7CF395C28EC432A36A97CDBB354E20BEA600F383D7729DE8B9DF5B16B721BEE8C6ADF51DA8EF5B7B3367EC8E6788F9772835586D09A9F8423AF1221CA87CBD54EC399E0BE49AEF19C017EEF36B3B18517DB2246EABBB21F6DF5CA2F4E1D178D0F42384CA192AA1461452BBC453FB59C54818F0739283
-20220414104329 2 6 100 4095 5 E8B371757422F6F4C734F2E4380126789768169B37154E4E3A4A74A3DF6545653A5970CDE0F0BD17CCFDAABBEE7568E1285D5A704BB9739EAB680D7EF59C134D327B55CF4AD69A4128536E2F055F5FBF0DB661C322A4993E382B997B2A0C5E434678B1910862AE385C415FF811BA11727CFE39C559847E710AC2D4BDA8D658F2259887E78D54179287BFE112E9C532CB1D062419DFF6E031F82EC991523A1144385189A813DFACBC63D8DAD98199696715C6BC5A22A1943B2CFC4BDAD8473FBEB7BCEC204EC12CFDB1A9BB66DCF85B3121C9E1C3587960769115B2F27ACEEC29A1CDC717B7505A561051F0E88A3C51798CD829E234ED14C277E9635B3E05EB13FA36F117B46094CA68F45F3667D6E84E0214F1650BF080CC4CC5510D6569E0226E88CD842B2ACFBD31370B136E5FD22C6697090586F38323AB36FB5569FB0FD53BB4AF10C16F0B809C1FB5B1B1C56027244F5A174A37250721197CE425CB5E5C5A51D4A5EA4A1EBEED71511BBE0BFF03CB1AE76968166167A775AB1AD9C9665C6ACC04203E5B2E80AA9F7CF395C28EC432A36A97CDBB354E20BEA600F383D7729DE8B9DF5B16B721BEE8C6ADF51DA8EF5B7B3367EC8E6788F9772835586D09A9F8423AF1221CA87CBD54EC399E0BE49AEF19C017EEF36B3B18517DB2246EABBB21F6DF5CA2F4E1D178D0F42384CA192AA1461452BBC453FB59C54818F11E163F
-20220414105100 2 6 100 4095 2 E8B371757422F6F4C734F2E4380126789768169B37154E4E3A4A74A3DF6545653A5970CDE0F0BD17CCFDAABBEE7568E1285D5A704BB9739EAB680D7EF59C134D327B55CF4AD69A4128536E2F055F5FBF0DB661C322A4993E382B997B2A0C5E434678B1910862AE385C415FF811BA11727CFE39C559847E710AC2D4BDA8D658F2259887E78D54179287BFE112E9C532CB1D062419DFF6E031F82EC991523A1144385189A813DFACBC63D8DAD98199696715C6BC5A22A1943B2CFC4BDAD8473FBEB7BCEC204EC12CFDB1A9BB66DCF85B3121C9E1C3587960769115B2F27ACEEC29A1CDC717B7505A561051F0E88A3C51798CD829E234ED14C277E9635B3E05EB13FA36F117B46094CA68F45F3667D6E84E0214F1650BF080CC4CC5510D6569E0226E88CD842B2ACFBD31370B136E5FD22C6697090586F38323AB36FB5569FB0FD53BB4AF10C16F0B809C1FB5B1B1C56027244F5A174A37250721197CE425CB5E5C5A51D4A5EA4A1EBEED71511BBE0BFF03CB1AE76968166167A775AB1AD9C9665C6ACC04203E5B2E80AA9F7CF395C28EC432A36A97CDBB354E20BEA600F383D7729DE8B9DF5B16B721BEE8C6ADF51DA8EF5B7B3367EC8E6788F9772835586D09A9F8423AF1221CA87CBD54EC399E0BE49AEF19C017EEF36B3B18517DB2246EABBB21F6DF5CA2F4E1D178D0F42384CA192AA1461452BBC453FB59C54818F451B803
-20220414110021 2 6 100 4095 2 E8B371757422F6F4C734F2E4380126789768169B37154E4E3A4A74A3DF6545653A5970CDE0F0BD17CCFDAABBEE7568E1285D5A704BB9739EAB680D7EF59C134D327B55CF4AD69A4128536E2F055F5FBF0DB661C322A4993E382B997B2A0C5E434678B1910862AE385C415FF811BA11727CFE39C559847E710AC2D4BDA8D658F2259887E78D54179287BFE112E9C532CB1D062419DFF6E031F82EC991523A1144385189A813DFACBC63D8DAD98199696715C6BC5A22A1943B2CFC4BDAD8473FBEB7BCEC204EC12CFDB1A9BB66DCF85B3121C9E1C3587960769115B2F27ACEEC29A1CDC717B7505A561051F0E88A3C51798CD829E234ED14C277E9635B3E05EB13FA36F117B46094CA68F45F3667D6E84E0214F1650BF080CC4CC5510D6569E0226E88CD842B2ACFBD31370B136E5FD22C6697090586F38323AB36FB5569FB0FD53BB4AF10C16F0B809C1FB5B1B1C56027244F5A174A37250721197CE425CB5E5C5A51D4A5EA4A1EBEED71511BBE0BFF03CB1AE76968166167A775AB1AD9C9665C6ACC04203E5B2E80AA9F7CF395C28EC432A36A97CDBB354E20BEA600F383D7729DE8B9DF5B16B721BEE8C6ADF51DA8EF5B7B3367EC8E6788F9772835586D09A9F8423AF1221CA87CBD54EC399E0BE49AEF19C017EEF36B3B18517DB2246EABBB21F6DF5CA2F4E1D178D0F42384CA192AA1461452BBC453FB59C54818F852CDBB
-20220414112534 2 6 100 6143 2 C008BA5D87ECC10B5E79F4C05438A7EAFA57C290A50C25A0DFD5FF2FF19F5D39568056AF4AA2FB56F1CEFB636A5E30D99379305FE9633EA9CF219FD87C501640F500E2AFAAF304B7EF862B6C4C8339B558E3B8F00AB714AD6460786AAE3B328D41806A94F270B4D1F13B958579F3C1A7ACB166FB2E5566ED4305AB36C357852B2ED67D4C877338D891E0FFBBDE512E976B754CA2BA1770D8CE7117D5CEB99715C99D97285F3744533CD9BE72A4FBE2CACD4796FA3EFCA27CCA1F7F96DC2A521CCD7776125A5DB2EE4A12B1DCFD797C47188CE5CB6859ACBB452F922F4FF7E2098CB090F83812A18D8DD9B7465B2572EED81332A84C1591F1BA1633B571423FE38BAA819B0AF2C30676B00EBD98D386FED880BB6D9FF4A05C206A8394E973350A597FC337260025BE097EB7409A182C500853B9C90A096708BB83A80F2EEF4EA23190B9CE095C92A1B675903B07149C34E9FFAF6908BCC27D495AFED5C652242B939F71690748895E93181C746CB6E94C2E58C97149F5F3FE3CE552F44AA859115AC5459C3CA343EAC5F98D076E661EE24E15F22FA81393F85E7D1B26FD4D6CC1DC7BFAC0E1C97438141A98D65EFD1592D4A1211DC089CEC0903DD7F333F55FFE70609FACDE7B7293036BAAB67E6DEE7FB82E16019AF642814BFF4AF6676446AE656ACD601812A86B8DB9A53A1EBB744ABDC7C88DBABE4AA023FC253B56B3B517DFE66156BE7DB0653B3DA80ACF010125D652C38DC91BBA2C247AD9F769A9C2F8FA16A0B0507CA632612F9AD03C5E281FFB3341A929E1EE9A946889AF525B348DE24362FABAE20E583D67B4624C96053960F4744BA71C1911D5A84B3615CC8F52E23C10C38E542B61969BD82257B2BE5B50EF63B5110D6D23B81D33176473020D363845C45BD03D2AEF81F2A87C1BADD4C1248A3004AE57562E38B0FB10124E23DFC0AB9257F5982748E39610A46A974459A2F30D852D560D45BAABEC8B8BE77F8AC9AC2424F69FBD9E23F226FD7FCBA827ACCC49E9EEDDF659ACA0E931B965401E416FB6969743B8CDEC4DEC49648D7C1B82B7B337AB496F9C5FD31B97D57323
-20220414112820 2 6 100 6143 5 C008BA5D87ECC10B5E79F4C05438A7EAFA57C290A50C25A0DFD5FF2FF19F5D39568056AF4AA2FB56F1CEFB636A5E30D99379305FE9633EA9CF219FD87C501640F500E2AFAAF304B7EF862B6C4C8339B558E3B8F00AB714AD6460786AAE3B328D41806A94F270B4D1F13B958579F3C1A7ACB166FB2E5566ED4305AB36C357852B2ED67D4C877338D891E0FFBBDE512E976B754CA2BA1770D8CE7117D5CEB99715C99D97285F3744533CD9BE72A4FBE2CACD4796FA3EFCA27CCA1F7F96DC2A521CCD7776125A5DB2EE4A12B1DCFD797C47188CE5CB6859ACBB452F922F4FF7E2098CB090F83812A18D8DD9B7465B2572EED81332A84C1591F1BA1633B571423FE38BAA819B0AF2C30676B00EBD98D386FED880BB6D9FF4A05C206A8394E973350A597FC337260025BE097EB7409A182C500853B9C90A096708BB83A80F2EEF4EA23190B9CE095C92A1B675903B07149C34E9FFAF6908BCC27D495AFED5C652242B939F71690748895E93181C746CB6E94C2E58C97149F5F3FE3CE552F44AA859115AC5459C3CA343EAC5F98D076E661EE24E15F22FA81393F85E7D1B26FD4D6CC1DC7BFAC0E1C97438141A98D65EFD1592D4A1211DC089CEC0903DD7F333F55FFE70609FACDE7B7293036BAAB67E6DEE7FB82E16019AF642814BFF4AF6676446AE656ACD601812A86B8DB9A53A1EBB744ABDC7C88DBABE4AA023FC253B56B3B517DFE66156BE7DB0653B3DA80ACF010125D652C38DC91BBA2C247AD9F769A9C2F8FA16A0B0507CA632612F9AD03C5E281FFB3341A929E1EE9A946889AF525B348DE24362FABAE20E583D67B4624C96053960F4744BA71C1911D5A84B3615CC8F52E23C10C38E542B61969BD82257B2BE5B50EF63B5110D6D23B81D33176473020D363845C45BD03D2AEF81F2A87C1BADD4C1248A3004AE57562E38B0FB10124E23DFC0AB9257F5982748E39610A46A974459A2F30D852D560D45BAABEC8B8BE77F8AC9AC2424F69FBD9E23F226FD7FCBA827ACCC49E9EEDDF659ACA0E931B965401E416FB6969743B8CDEC4DEC49648D7C1B82B7B337AB496F9C5FD31B9836476F
-20220414112915 2 6 100 6143 2 C008BA5D87ECC10B5E79F4C05438A7EAFA57C290A50C25A0DFD5FF2FF19F5D39568056AF4AA2FB56F1CEFB636A5E30D99379305FE9633EA9CF219FD87C501640F500E2AFAAF304B7EF862B6C4C8339B558E3B8F00AB714AD6460786AAE3B328D41806A94F270B4D1F13B958579F3C1A7ACB166FB2E5566ED4305AB36C357852B2ED67D4C877338D891E0FFBBDE512E976B754CA2BA1770D8CE7117D5CEB99715C99D97285F3744533CD9BE72A4FBE2CACD4796FA3EFCA27CCA1F7F96DC2A521CCD7776125A5DB2EE4A12B1DCFD797C47188CE5CB6859ACBB452F922F4FF7E2098CB090F83812A18D8DD9B7465B2572EED81332A84C1591F1BA1633B571423FE38BAA819B0AF2C30676B00EBD98D386FED880BB6D9FF4A05C206A8394E973350A597FC337260025BE097EB7409A182C500853B9C90A096708BB83A80F2EEF4EA23190B9CE095C92A1B675903B07149C34E9FFAF6908BCC27D495AFED5C652242B939F71690748895E93181C746CB6E94C2E58C97149F5F3FE3CE552F44AA859115AC5459C3CA343EAC5F98D076E661EE24E15F22FA81393F85E7D1B26FD4D6CC1DC7BFAC0E1C97438141A98D65EFD1592D4A1211DC089CEC0903DD7F333F55FFE70609FACDE7B7293036BAAB67E6DEE7FB82E16019AF642814BFF4AF6676446AE656ACD601812A86B8DB9A53A1EBB744ABDC7C88DBABE4AA023FC253B56B3B517DFE66156BE7DB0653B3DA80ACF010125D652C38DC91BBA2C247AD9F769A9C2F8FA16A0B0507CA632612F9AD03C5E281FFB3341A929E1EE9A946889AF525B348DE24362FABAE20E583D67B4624C96053960F4744BA71C1911D5A84B3615CC8F52E23C10C38E542B61969BD82257B2BE5B50EF63B5110D6D23B81D33176473020D363845C45BD03D2AEF81F2A87C1BADD4C1248A3004AE57562E38B0FB10124E23DFC0AB9257F5982748E39610A46A974459A2F30D852D560D45BAABEC8B8BE77F8AC9AC2424F69FBD9E23F226FD7FCBA827ACCC49E9EEDDF659ACA0E931B965401E416FB6969743B8CDEC4DEC49648D7C1B82B7B337AB496F9C5FD31B98509153
-20220414113222 2 6 100 6143 2 C008BA5D87ECC10B5E79F4C05438A7EAFA57C290A50C25A0DFD5FF2FF19F5D39568056AF4AA2FB56F1CEFB636A5E30D99379305FE9633EA9CF219FD87C501640F500E2AFAAF304B7EF862B6C4C8339B558E3B8F00AB714AD6460786AAE3B328D41806A94F270B4D1F13B958579F3C1A7ACB166FB2E5566ED4305AB36C357852B2ED67D4C877338D891E0FFBBDE512E976B754CA2BA1770D8CE7117D5CEB99715C99D97285F3744533CD9BE72A4FBE2CACD4796FA3EFCA27CCA1F7F96DC2A521CCD7776125A5DB2EE4A12B1DCFD797C47188CE5CB6859ACBB452F922F4FF7E2098CB090F83812A18D8DD9B7465B2572EED81332A84C1591F1BA1633B571423FE38BAA819B0AF2C30676B00EBD98D386FED880BB6D9FF4A05C206A8394E973350A597FC337260025BE097EB7409A182C500853B9C90A096708BB83A80F2EEF4EA23190B9CE095C92A1B675903B07149C34E9FFAF6908BCC27D495AFED5C652242B939F71690748895E93181C746CB6E94C2E58C97149F5F3FE3CE552F44AA859115AC5459C3CA343EAC5F98D076E661EE24E15F22FA81393F85E7D1B26FD4D6CC1DC7BFAC0E1C97438141A98D65EFD1592D4A1211DC089CEC0903DD7F333F55FFE70609FACDE7B7293036BAAB67E6DEE7FB82E16019AF642814BFF4AF6676446AE656ACD601812A86B8DB9A53A1EBB744ABDC7C88DBABE4AA023FC253B56B3B517DFE66156BE7DB0653B3DA80ACF010125D652C38DC91BBA2C247AD9F769A9C2F8FA16A0B0507CA632612F9AD03C5E281FFB3341A929E1EE9A946889AF525B348DE24362FABAE20E583D67B4624C96053960F4744BA71C1911D5A84B3615CC8F52E23C10C38E542B61969BD82257B2BE5B50EF63B5110D6D23B81D33176473020D363845C45BD03D2AEF81F2A87C1BADD4C1248A3004AE57562E38B0FB10124E23DFC0AB9257F5982748E39610A46A974459A2F30D852D560D45BAABEC8B8BE77F8AC9AC2424F69FBD9E23F226FD7FCBA827ACCC49E9EEDDF659ACA0E931B965401E416FB6969743B8CDEC4DEC49648D7C1B82B7B337AB496F9C5FD31B98BB7CAB
-20220414113851 2 6 100 6143 5 C008BA5D87ECC10B5E79F4C05438A7EAFA57C290A50C25A0DFD5FF2FF19F5D39568056AF4AA2FB56F1CEFB636A5E30D99379305FE9633EA9CF219FD87C501640F500E2AFAAF304B7EF862B6C4C8339B558E3B8F00AB714AD6460786AAE3B328D41806A94F270B4D1F13B958579F3C1A7ACB166FB2E5566ED4305AB36C357852B2ED67D4C877338D891E0FFBBDE512E976B754CA2BA1770D8CE7117D5CEB99715C99D97285F3744533CD9BE72A4FBE2CACD4796FA3EFCA27CCA1F7F96DC2A521CCD7776125A5DB2EE4A12B1DCFD797C47188CE5CB6859ACBB452F922F4FF7E2098CB090F83812A18D8DD9B7465B2572EED81332A84C1591F1BA1633B571423FE38BAA819B0AF2C30676B00EBD98D386FED880BB6D9FF4A05C206A8394E973350A597FC337260025BE097EB7409A182C500853B9C90A096708BB83A80F2EEF4EA23190B9CE095C92A1B675903B07149C34E9FFAF6908BCC27D495AFED5C652242B939F71690748895E93181C746CB6E94C2E58C97149F5F3FE3CE552F44AA859115AC5459C3CA343EAC5F98D076E661EE24E15F22FA81393F85E7D1B26FD4D6CC1DC7BFAC0E1C97438141A98D65EFD1592D4A1211DC089CEC0903DD7F333F55FFE70609FACDE7B7293036BAAB67E6DEE7FB82E16019AF642814BFF4AF6676446AE656ACD601812A86B8DB9A53A1EBB744ABDC7C88DBABE4AA023FC253B56B3B517DFE66156BE7DB0653B3DA80ACF010125D652C38DC91BBA2C247AD9F769A9C2F8FA16A0B0507CA632612F9AD03C5E281FFB3341A929E1EE9A946889AF525B348DE24362FABAE20E583D67B4624C96053960F4744BA71C1911D5A84B3615CC8F52E23C10C38E542B61969BD82257B2BE5B50EF63B5110D6D23B81D33176473020D363845C45BD03D2AEF81F2A87C1BADD4C1248A3004AE57562E38B0FB10124E23DFC0AB9257F5982748E39610A46A974459A2F30D852D560D45BAABEC8B8BE77F8AC9AC2424F69FBD9E23F226FD7FCBA827ACCC49E9EEDDF659ACA0E931B965401E416FB6969743B8CDEC4DEC49648D7C1B82B7B337AB496F9C5FD31B99A6C927
-20220414115900 2 6 100 6143 5 C008BA5D87ECC10B5E79F4C05438A7EAFA57C290A50C25A0DFD5FF2FF19F5D39568056AF4AA2FB56F1CEFB636A5E30D99379305FE9633EA9CF219FD87C501640F500E2AFAAF304B7EF862B6C4C8339B558E3B8F00AB714AD6460786AAE3B328D41806A94F270B4D1F13B958579F3C1A7ACB166FB2E5566ED4305AB36C357852B2ED67D4C877338D891E0FFBBDE512E976B754CA2BA1770D8CE7117D5CEB99715C99D97285F3744533CD9BE72A4FBE2CACD4796FA3EFCA27CCA1F7F96DC2A521CCD7776125A5DB2EE4A12B1DCFD797C47188CE5CB6859ACBB452F922F4FF7E2098CB090F83812A18D8DD9B7465B2572EED81332A84C1591F1BA1633B571423FE38BAA819B0AF2C30676B00EBD98D386FED880BB6D9FF4A05C206A8394E973350A597FC337260025BE097EB7409A182C500853B9C90A096708BB83A80F2EEF4EA23190B9CE095C92A1B675903B07149C34E9FFAF6908BCC27D495AFED5C652242B939F71690748895E93181C746CB6E94C2E58C97149F5F3FE3CE552F44AA859115AC5459C3CA343EAC5F98D076E661EE24E15F22FA81393F85E7D1B26FD4D6CC1DC7BFAC0E1C97438141A98D65EFD1592D4A1211DC089CEC0903DD7F333F55FFE70609FACDE7B7293036BAAB67E6DEE7FB82E16019AF642814BFF4AF6676446AE656ACD601812A86B8DB9A53A1EBB744ABDC7C88DBABE4AA023FC253B56B3B517DFE66156BE7DB0653B3DA80ACF010125D652C38DC91BBA2C247AD9F769A9C2F8FA16A0B0507CA632612F9AD03C5E281FFB3341A929E1EE9A946889AF525B348DE24362FABAE20E583D67B4624C96053960F4744BA71C1911D5A84B3615CC8F52E23C10C38E542B61969BD82257B2BE5B50EF63B5110D6D23B81D33176473020D363845C45BD03D2AEF81F2A87C1BADD4C1248A3004AE57562E38B0FB10124E23DFC0AB9257F5982748E39610A46A974459A2F30D852D560D45BAABEC8B8BE77F8AC9AC2424F69FBD9E23F226FD7FCBA827ACCC49E9EEDDF659ACA0E931B965401E416FB6969743B8CDEC4DEC49648D7C1B82B7B337AB496F9C5FD31B9C9A8187
-20220414121305 2 6 100 6143 2 C008BA5D87ECC10B5E79F4C05438A7EAFA57C290A50C25A0DFD5FF2FF19F5D39568056AF4AA2FB56F1CEFB636A5E30D99379305FE9633EA9CF219FD87C501640F500E2AFAAF304B7EF862B6C4C8339B558E3B8F00AB714AD6460786AAE3B328D41806A94F270B4D1F13B958579F3C1A7ACB166FB2E5566ED4305AB36C357852B2ED67D4C877338D891E0FFBBDE512E976B754CA2BA1770D8CE7117D5CEB99715C99D97285F3744533CD9BE72A4FBE2CACD4796FA3EFCA27CCA1F7F96DC2A521CCD7776125A5DB2EE4A12B1DCFD797C47188CE5CB6859ACBB452F922F4FF7E2098CB090F83812A18D8DD9B7465B2572EED81332A84C1591F1BA1633B571423FE38BAA819B0AF2C30676B00EBD98D386FED880BB6D9FF4A05C206A8394E973350A597FC337260025BE097EB7409A182C500853B9C90A096708BB83A80F2EEF4EA23190B9CE095C92A1B675903B07149C34E9FFAF6908BCC27D495AFED5C652242B939F71690748895E93181C746CB6E94C2E58C97149F5F3FE3CE552F44AA859115AC5459C3CA343EAC5F98D076E661EE24E15F22FA81393F85E7D1B26FD4D6CC1DC7BFAC0E1C97438141A98D65EFD1592D4A1211DC089CEC0903DD7F333F55FFE70609FACDE7B7293036BAAB67E6DEE7FB82E16019AF642814BFF4AF6676446AE656ACD601812A86B8DB9A53A1EBB744ABDC7C88DBABE4AA023FC253B56B3B517DFE66156BE7DB0653B3DA80ACF010125D652C38DC91BBA2C247AD9F769A9C2F8FA16A0B0507CA632612F9AD03C5E281FFB3341A929E1EE9A946889AF525B348DE24362FABAE20E583D67B4624C96053960F4744BA71C1911D5A84B3615CC8F52E23C10C38E542B61969BD82257B2BE5B50EF63B5110D6D23B81D33176473020D363845C45BD03D2AEF81F2A87C1BADD4C1248A3004AE57562E38B0FB10124E23DFC0AB9257F5982748E39610A46A974459A2F30D852D560D45BAABEC8B8BE77F8AC9AC2424F69FBD9E23F226FD7FCBA827ACCC49E9EEDDF659ACA0E931B965401E416FB6969743B8CDEC4DEC49648D7C1B82B7B337AB496F9C5FD31B9EAC674B
-20220414124550 2 6 100 6143 5 C008BA5D87ECC10B5E79F4C05438A7EAFA57C290A50C25A0DFD5FF2FF19F5D39568056AF4AA2FB56F1CEFB636A5E30D99379305FE9633EA9CF219FD87C501640F500E2AFAAF304B7EF862B6C4C8339B558E3B8F00AB714AD6460786AAE3B328D41806A94F270B4D1F13B958579F3C1A7ACB166FB2E5566ED4305AB36C357852B2ED67D4C877338D891E0FFBBDE512E976B754CA2BA1770D8CE7117D5CEB99715C99D97285F3744533CD9BE72A4FBE2CACD4796FA3EFCA27CCA1F7F96DC2A521CCD7776125A5DB2EE4A12B1DCFD797C47188CE5CB6859ACBB452F922F4FF7E2098CB090F83812A18D8DD9B7465B2572EED81332A84C1591F1BA1633B571423FE38BAA819B0AF2C30676B00EBD98D386FED880BB6D9FF4A05C206A8394E973350A597FC337260025BE097EB7409A182C500853B9C90A096708BB83A80F2EEF4EA23190B9CE095C92A1B675903B07149C34E9FFAF6908BCC27D495AFED5C652242B939F71690748895E93181C746CB6E94C2E58C97149F5F3FE3CE552F44AA859115AC5459C3CA343EAC5F98D076E661EE24E15F22FA81393F85E7D1B26FD4D6CC1DC7BFAC0E1C97438141A98D65EFD1592D4A1211DC089CEC0903DD7F333F55FFE70609FACDE7B7293036BAAB67E6DEE7FB82E16019AF642814BFF4AF6676446AE656ACD601812A86B8DB9A53A1EBB744ABDC7C88DBABE4AA023FC253B56B3B517DFE66156BE7DB0653B3DA80ACF010125D652C38DC91BBA2C247AD9F769A9C2F8FA16A0B0507CA632612F9AD03C5E281FFB3341A929E1EE9A946889AF525B348DE24362FABAE20E583D67B4624C96053960F4744BA71C1911D5A84B3615CC8F52E23C10C38E542B61969BD82257B2BE5B50EF63B5110D6D23B81D33176473020D363845C45BD03D2AEF81F2A87C1BADD4C1248A3004AE57562E38B0FB10124E23DFC0AB9257F5982748E39610A46A974459A2F30D852D560D45BAABEC8B8BE77F8AC9AC2424F69FBD9E23F226FD7FCBA827ACCC49E9EEDDF659ACA0E931B965401E416FB6969743B8CDEC4DEC49648D7C1B82B7B337AB496F9C5FD31BA38974A7
-20220414124932 2 6 100 6143 2 C008BA5D87ECC10B5E79F4C05438A7EAFA57C290A50C25A0DFD5FF2FF19F5D39568056AF4AA2FB56F1CEFB636A5E30D99379305FE9633EA9CF219FD87C501640F500E2AFAAF304B7EF862B6C4C8339B558E3B8F00AB714AD6460786AAE3B328D41806A94F270B4D1F13B958579F3C1A7ACB166FB2E5566ED4305AB36C357852B2ED67D4C877338D891E0FFBBDE512E976B754CA2BA1770D8CE7117D5CEB99715C99D97285F3744533CD9BE72A4FBE2CACD4796FA3EFCA27CCA1F7F96DC2A521CCD7776125A5DB2EE4A12B1DCFD797C47188CE5CB6859ACBB452F922F4FF7E2098CB090F83812A18D8DD9B7465B2572EED81332A84C1591F1BA1633B571423FE38BAA819B0AF2C30676B00EBD98D386FED880BB6D9FF4A05C206A8394E973350A597FC337260025BE097EB7409A182C500853B9C90A096708BB83A80F2EEF4EA23190B9CE095C92A1B675903B07149C34E9FFAF6908BCC27D495AFED5C652242B939F71690748895E93181C746CB6E94C2E58C97149F5F3FE3CE552F44AA859115AC5459C3CA343EAC5F98D076E661EE24E15F22FA81393F85E7D1B26FD4D6CC1DC7BFAC0E1C97438141A98D65EFD1592D4A1211DC089CEC0903DD7F333F55FFE70609FACDE7B7293036BAAB67E6DEE7FB82E16019AF642814BFF4AF6676446AE656ACD601812A86B8DB9A53A1EBB744ABDC7C88DBABE4AA023FC253B56B3B517DFE66156BE7DB0653B3DA80ACF010125D652C38DC91BBA2C247AD9F769A9C2F8FA16A0B0507CA632612F9AD03C5E281FFB3341A929E1EE9A946889AF525B348DE24362FABAE20E583D67B4624C96053960F4744BA71C1911D5A84B3615CC8F52E23C10C38E542B61969BD82257B2BE5B50EF63B5110D6D23B81D33176473020D363845C45BD03D2AEF81F2A87C1BADD4C1248A3004AE57562E38B0FB10124E23DFC0AB9257F5982748E39610A46A974459A2F30D852D560D45BAABEC8B8BE77F8AC9AC2424F69FBD9E23F226FD7FCBA827ACCC49E9EEDDF659ACA0E931B965401E416FB6969743B8CDEC4DEC49648D7C1B82B7B337AB496F9C5FD31BA40E655B
-20220414131030 2 6 100 6143 5 C008BA5D87ECC10B5E79F4C05438A7EAFA57C290A50C25A0DFD5FF2FF19F5D39568056AF4AA2FB56F1CEFB636A5E30D99379305FE9633EA9CF219FD87C501640F500E2AFAAF304B7EF862B6C4C8339B558E3B8F00AB714AD6460786AAE3B328D41806A94F270B4D1F13B958579F3C1A7ACB166FB2E5566ED4305AB36C357852B2ED67D4C877338D891E0FFBBDE512E976B754CA2BA1770D8CE7117D5CEB99715C99D97285F3744533CD9BE72A4FBE2CACD4796FA3EFCA27CCA1F7F96DC2A521CCD7776125A5DB2EE4A12B1DCFD797C47188CE5CB6859ACBB452F922F4FF7E2098CB090F83812A18D8DD9B7465B2572EED81332A84C1591F1BA1633B571423FE38BAA819B0AF2C30676B00EBD98D386FED880BB6D9FF4A05C206A8394E973350A597FC337260025BE097EB7409A182C500853B9C90A096708BB83A80F2EEF4EA23190B9CE095C92A1B675903B07149C34E9FFAF6908BCC27D495AFED5C652242B939F71690748895E93181C746CB6E94C2E58C97149F5F3FE3CE552F44AA859115AC5459C3CA343EAC5F98D076E661EE24E15F22FA81393F85E7D1B26FD4D6CC1DC7BFAC0E1C97438141A98D65EFD1592D4A1211DC089CEC0903DD7F333F55FFE70609FACDE7B7293036BAAB67E6DEE7FB82E16019AF642814BFF4AF6676446AE656ACD601812A86B8DB9A53A1EBB744ABDC7C88DBABE4AA023FC253B56B3B517DFE66156BE7DB0653B3DA80ACF010125D652C38DC91BBA2C247AD9F769A9C2F8FA16A0B0507CA632612F9AD03C5E281FFB3341A929E1EE9A946889AF525B348DE24362FABAE20E583D67B4624C96053960F4744BA71C1911D5A84B3615CC8F52E23C10C38E542B61969BD82257B2BE5B50EF63B5110D6D23B81D33176473020D363845C45BD03D2AEF81F2A87C1BADD4C1248A3004AE57562E38B0FB10124E23DFC0AB9257F5982748E39610A46A974459A2F30D852D560D45BAABEC8B8BE77F8AC9AC2424F69FBD9E23F226FD7FCBA827ACCC49E9EEDDF659ACA0E931B965401E416FB6969743B8CDEC4DEC49648D7C1B82B7B337AB496F9C5FD31BA71F8DAF
-20220414131803 2 6 100 6143 5 C008BA5D87ECC10B5E79F4C05438A7EAFA57C290A50C25A0DFD5FF2FF19F5D39568056AF4AA2FB56F1CEFB636A5E30D99379305FE9633EA9CF219FD87C501640F500E2AFAAF304B7EF862B6C4C8339B558E3B8F00AB714AD6460786AAE3B328D41806A94F270B4D1F13B958579F3C1A7ACB166FB2E5566ED4305AB36C357852B2ED67D4C877338D891E0FFBBDE512E976B754CA2BA1770D8CE7117D5CEB99715C99D97285F3744533CD9BE72A4FBE2CACD4796FA3EFCA27CCA1F7F96DC2A521CCD7776125A5DB2EE4A12B1DCFD797C47188CE5CB6859ACBB452F922F4FF7E2098CB090F83812A18D8DD9B7465B2572EED81332A84C1591F1BA1633B571423FE38BAA819B0AF2C30676B00EBD98D386FED880BB6D9FF4A05C206A8394E973350A597FC337260025BE097EB7409A182C500853B9C90A096708BB83A80F2EEF4EA23190B9CE095C92A1B675903B07149C34E9FFAF6908BCC27D495AFED5C652242B939F71690748895E93181C746CB6E94C2E58C97149F5F3FE3CE552F44AA859115AC5459C3CA343EAC5F98D076E661EE24E15F22FA81393F85E7D1B26FD4D6CC1DC7BFAC0E1C97438141A98D65EFD1592D4A1211DC089CEC0903DD7F333F55FFE70609FACDE7B7293036BAAB67E6DEE7FB82E16019AF642814BFF4AF6676446AE656ACD601812A86B8DB9A53A1EBB744ABDC7C88DBABE4AA023FC253B56B3B517DFE66156BE7DB0653B3DA80ACF010125D652C38DC91BBA2C247AD9F769A9C2F8FA16A0B0507CA632612F9AD03C5E281FFB3341A929E1EE9A946889AF525B348DE24362FABAE20E583D67B4624C96053960F4744BA71C1911D5A84B3615CC8F52E23C10C38E542B61969BD82257B2BE5B50EF63B5110D6D23B81D33176473020D363845C45BD03D2AEF81F2A87C1BADD4C1248A3004AE57562E38B0FB10124E23DFC0AB9257F5982748E39610A46A974459A2F30D852D560D45BAABEC8B8BE77F8AC9AC2424F69FBD9E23F226FD7FCBA827ACCC49E9EEDDF659ACA0E931B965401E416FB6969743B8CDEC4DEC49648D7C1B82B7B337AB496F9C5FD31BA82FCF2F
-20220414133154 2 6 100 6143 2 C008BA5D87ECC10B5E79F4C05438A7EAFA57C290A50C25A0DFD5FF2FF19F5D39568056AF4AA2FB56F1CEFB636A5E30D99379305FE9633EA9CF219FD87C501640F500E2AFAAF304B7EF862B6C4C8339B558E3B8F00AB714AD6460786AAE3B328D41806A94F270B4D1F13B958579F3C1A7ACB166FB2E5566ED4305AB36C357852B2ED67D4C877338D891E0FFBBDE512E976B754CA2BA1770D8CE7117D5CEB99715C99D97285F3744533CD9BE72A4FBE2CACD4796FA3EFCA27CCA1F7F96DC2A521CCD7776125A5DB2EE4A12B1DCFD797C47188CE5CB6859ACBB452F922F4FF7E2098CB090F83812A18D8DD9B7465B2572EED81332A84C1591F1BA1633B571423FE38BAA819B0AF2C30676B00EBD98D386FED880BB6D9FF4A05C206A8394E973350A597FC337260025BE097EB7409A182C500853B9C90A096708BB83A80F2EEF4EA23190B9CE095C92A1B675903B07149C34E9FFAF6908BCC27D495AFED5C652242B939F71690748895E93181C746CB6E94C2E58C97149F5F3FE3CE552F44AA859115AC5459C3CA343EAC5F98D076E661EE24E15F22FA81393F85E7D1B26FD4D6CC1DC7BFAC0E1C97438141A98D65EFD1592D4A1211DC089CEC0903DD7F333F55FFE70609FACDE7B7293036BAAB67E6DEE7FB82E16019AF642814BFF4AF6676446AE656ACD601812A86B8DB9A53A1EBB744ABDC7C88DBABE4AA023FC253B56B3B517DFE66156BE7DB0653B3DA80ACF010125D652C38DC91BBA2C247AD9F769A9C2F8FA16A0B0507CA632612F9AD03C5E281FFB3341A929E1EE9A946889AF525B348DE24362FABAE20E583D67B4624C96053960F4744BA71C1911D5A84B3615CC8F52E23C10C38E542B61969BD82257B2BE5B50EF63B5110D6D23B81D33176473020D363845C45BD03D2AEF81F2A87C1BADD4C1248A3004AE57562E38B0FB10124E23DFC0AB9257F5982748E39610A46A974459A2F30D852D560D45BAABEC8B8BE77F8AC9AC2424F69FBD9E23F226FD7FCBA827ACCC49E9EEDDF659ACA0E931B965401E416FB6969743B8CDEC4DEC49648D7C1B82B7B337AB496F9C5FD31BAA30669B
-20220414133700 2 6 100 6143 5 C008BA5D87ECC10B5E79F4C05438A7EAFA57C290A50C25A0DFD5FF2FF19F5D39568056AF4AA2FB56F1CEFB636A5E30D99379305FE9633EA9CF219FD87C501640F500E2AFAAF304B7EF862B6C4C8339B558E3B8F00AB714AD6460786AAE3B328D41806A94F270B4D1F13B958579F3C1A7ACB166FB2E5566ED4305AB36C357852B2ED67D4C877338D891E0FFBBDE512E976B754CA2BA1770D8CE7117D5CEB99715C99D97285F3744533CD9BE72A4FBE2CACD4796FA3EFCA27CCA1F7F96DC2A521CCD7776125A5DB2EE4A12B1DCFD797C47188CE5CB6859ACBB452F922F4FF7E2098CB090F83812A18D8DD9B7465B2572EED81332A84C1591F1BA1633B571423FE38BAA819B0AF2C30676B00EBD98D386FED880BB6D9FF4A05C206A8394E973350A597FC337260025BE097EB7409A182C500853B9C90A096708BB83A80F2EEF4EA23190B9CE095C92A1B675903B07149C34E9FFAF6908BCC27D495AFED5C652242B939F71690748895E93181C746CB6E94C2E58C97149F5F3FE3CE552F44AA859115AC5459C3CA343EAC5F98D076E661EE24E15F22FA81393F85E7D1B26FD4D6CC1DC7BFAC0E1C97438141A98D65EFD1592D4A1211DC089CEC0903DD7F333F55FFE70609FACDE7B7293036BAAB67E6DEE7FB82E16019AF642814BFF4AF6676446AE656ACD601812A86B8DB9A53A1EBB744ABDC7C88DBABE4AA023FC253B56B3B517DFE66156BE7DB0653B3DA80ACF010125D652C38DC91BBA2C247AD9F769A9C2F8FA16A0B0507CA632612F9AD03C5E281FFB3341A929E1EE9A946889AF525B348DE24362FABAE20E583D67B4624C96053960F4744BA71C1911D5A84B3615CC8F52E23C10C38E542B61969BD82257B2BE5B50EF63B5110D6D23B81D33176473020D363845C45BD03D2AEF81F2A87C1BADD4C1248A3004AE57562E38B0FB10124E23DFC0AB9257F5982748E39610A46A974459A2F30D852D560D45BAABEC8B8BE77F8AC9AC2424F69FBD9E23F226FD7FCBA827ACCC49E9EEDDF659ACA0E931B965401E416FB6969743B8CDEC4DEC49648D7C1B82B7B337AB496F9C5FD31BAAE42927
-20220414133729 2 6 100 6143 2 C008BA5D87ECC10B5E79F4C05438A7EAFA57C290A50C25A0DFD5FF2FF19F5D39568056AF4AA2FB56F1CEFB636A5E30D99379305FE9633EA9CF219FD87C501640F500E2AFAAF304B7EF862B6C4C8339B558E3B8F00AB714AD6460786AAE3B328D41806A94F270B4D1F13B958579F3C1A7ACB166FB2E5566ED4305AB36C357852B2ED67D4C877338D891E0FFBBDE512E976B754CA2BA1770D8CE7117D5CEB99715C99D97285F3744533CD9BE72A4FBE2CACD4796FA3EFCA27CCA1F7F96DC2A521CCD7776125A5DB2EE4A12B1DCFD797C47188CE5CB6859ACBB452F922F4FF7E2098CB090F83812A18D8DD9B7465B2572EED81332A84C1591F1BA1633B571423FE38BAA819B0AF2C30676B00EBD98D386FED880BB6D9FF4A05C206A8394E973350A597FC337260025BE097EB7409A182C500853B9C90A096708BB83A80F2EEF4EA23190B9CE095C92A1B675903B07149C34E9FFAF6908BCC27D495AFED5C652242B939F71690748895E93181C746CB6E94C2E58C97149F5F3FE3CE552F44AA859115AC5459C3CA343EAC5F98D076E661EE24E15F22FA81393F85E7D1B26FD4D6CC1DC7BFAC0E1C97438141A98D65EFD1592D4A1211DC089CEC0903DD7F333F55FFE70609FACDE7B7293036BAAB67E6DEE7FB82E16019AF642814BFF4AF6676446AE656ACD601812A86B8DB9A53A1EBB744ABDC7C88DBABE4AA023FC253B56B3B517DFE66156BE7DB0653B3DA80ACF010125D652C38DC91BBA2C247AD9F769A9C2F8FA16A0B0507CA632612F9AD03C5E281FFB3341A929E1EE9A946889AF525B348DE24362FABAE20E583D67B4624C96053960F4744BA71C1911D5A84B3615CC8F52E23C10C38E542B61969BD82257B2BE5B50EF63B5110D6D23B81D33176473020D363845C45BD03D2AEF81F2A87C1BADD4C1248A3004AE57562E38B0FB10124E23DFC0AB9257F5982748E39610A46A974459A2F30D852D560D45BAABEC8B8BE77F8AC9AC2424F69FBD9E23F226FD7FCBA827ACCC49E9EEDDF659ACA0E931B965401E416FB6969743B8CDEC4DEC49648D7C1B82B7B337AB496F9C5FD31BAAECA503
-20220414135933 2 6 100 6143 5 C008BA5D87ECC10B5E79F4C05438A7EAFA57C290A50C25A0DFD5FF2FF19F5D39568056AF4AA2FB56F1CEFB636A5E30D99379305FE9633EA9CF219FD87C501640F500E2AFAAF304B7EF862B6C4C8339B558E3B8F00AB714AD6460786AAE3B328D41806A94F270B4D1F13B958579F3C1A7ACB166FB2E5566ED4305AB36C357852B2ED67D4C877338D891E0FFBBDE512E976B754CA2BA1770D8CE7117D5CEB99715C99D97285F3744533CD9BE72A4FBE2CACD4796FA3EFCA27CCA1F7F96DC2A521CCD7776125A5DB2EE4A12B1DCFD797C47188CE5CB6859ACBB452F922F4FF7E2098CB090F83812A18D8DD9B7465B2572EED81332A84C1591F1BA1633B571423FE38BAA819B0AF2C30676B00EBD98D386FED880BB6D9FF4A05C206A8394E973350A597FC337260025BE097EB7409A182C500853B9C90A096708BB83A80F2EEF4EA23190B9CE095C92A1B675903B07149C34E9FFAF6908BCC27D495AFED5C652242B939F71690748895E93181C746CB6E94C2E58C97149F5F3FE3CE552F44AA859115AC5459C3CA343EAC5F98D076E661EE24E15F22FA81393F85E7D1B26FD4D6CC1DC7BFAC0E1C97438141A98D65EFD1592D4A1211DC089CEC0903DD7F333F55FFE70609FACDE7B7293036BAAB67E6DEE7FB82E16019AF642814BFF4AF6676446AE656ACD601812A86B8DB9A53A1EBB744ABDC7C88DBABE4AA023FC253B56B3B517DFE66156BE7DB0653B3DA80ACF010125D652C38DC91BBA2C247AD9F769A9C2F8FA16A0B0507CA632612F9AD03C5E281FFB3341A929E1EE9A946889AF525B348DE24362FABAE20E583D67B4624C96053960F4744BA71C1911D5A84B3615CC8F52E23C10C38E542B61969BD82257B2BE5B50EF63B5110D6D23B81D33176473020D363845C45BD03D2AEF81F2A87C1BADD4C1248A3004AE57562E38B0FB10124E23DFC0AB9257F5982748E39610A46A974459A2F30D852D560D45BAABEC8B8BE77F8AC9AC2424F69FBD9E23F226FD7FCBA827ACCC49E9EEDDF659ACA0E931B965401E416FB6969743B8CDEC4DEC49648D7C1B82B7B337AB496F9C5FD31BAE1D12A7
-20220414140132 2 6 100 6143 5 C008BA5D87ECC10B5E79F4C05438A7EAFA57C290A50C25A0DFD5FF2FF19F5D39568056AF4AA2FB56F1CEFB636A5E30D99379305FE9633EA9CF219FD87C501640F500E2AFAAF304B7EF862B6C4C8339B558E3B8F00AB714AD6460786AAE3B328D41806A94F270B4D1F13B958579F3C1A7ACB166FB2E5566ED4305AB36C357852B2ED67D4C877338D891E0FFBBDE512E976B754CA2BA1770D8CE7117D5CEB99715C99D97285F3744533CD9BE72A4FBE2CACD4796FA3EFCA27CCA1F7F96DC2A521CCD7776125A5DB2EE4A12B1DCFD797C47188CE5CB6859ACBB452F922F4FF7E2098CB090F83812A18D8DD9B7465B2572EED81332A84C1591F1BA1633B571423FE38BAA819B0AF2C30676B00EBD98D386FED880BB6D9FF4A05C206A8394E973350A597FC337260025BE097EB7409A182C500853B9C90A096708BB83A80F2EEF4EA23190B9CE095C92A1B675903B07149C34E9FFAF6908BCC27D495AFED5C652242B939F71690748895E93181C746CB6E94C2E58C97149F5F3FE3CE552F44AA859115AC5459C3CA343EAC5F98D076E661EE24E15F22FA81393F85E7D1B26FD4D6CC1DC7BFAC0E1C97438141A98D65EFD1592D4A1211DC089CEC0903DD7F333F55FFE70609FACDE7B7293036BAAB67E6DEE7FB82E16019AF642814BFF4AF6676446AE656ACD601812A86B8DB9A53A1EBB744ABDC7C88DBABE4AA023FC253B56B3B517DFE66156BE7DB0653B3DA80ACF010125D652C38DC91BBA2C247AD9F769A9C2F8FA16A0B0507CA632612F9AD03C5E281FFB3341A929E1EE9A946889AF525B348DE24362FABAE20E583D67B4624C96053960F4744BA71C1911D5A84B3615CC8F52E23C10C38E542B61969BD82257B2BE5B50EF63B5110D6D23B81D33176473020D363845C45BD03D2AEF81F2A87C1BADD4C1248A3004AE57562E38B0FB10124E23DFC0AB9257F5982748E39610A46A974459A2F30D852D560D45BAABEC8B8BE77F8AC9AC2424F69FBD9E23F226FD7FCBA827ACCC49E9EEDDF659ACA0E931B965401E416FB6969743B8CDEC4DEC49648D7C1B82B7B337AB496F9C5FD31BAE5AE7DF
-20220414141651 2 6 100 6143 5 C008BA5D87ECC10B5E79F4C05438A7EAFA57C290A50C25A0DFD5FF2FF19F5D39568056AF4AA2FB56F1CEFB636A5E30D99379305FE9633EA9CF219FD87C501640F500E2AFAAF304B7EF862B6C4C8339B558E3B8F00AB714AD6460786AAE3B328D41806A94F270B4D1F13B958579F3C1A7ACB166FB2E5566ED4305AB36C357852B2ED67D4C877338D891E0FFBBDE512E976B754CA2BA1770D8CE7117D5CEB99715C99D97285F3744533CD9BE72A4FBE2CACD4796FA3EFCA27CCA1F7F96DC2A521CCD7776125A5DB2EE4A12B1DCFD797C47188CE5CB6859ACBB452F922F4FF7E2098CB090F83812A18D8DD9B7465B2572EED81332A84C1591F1BA1633B571423FE38BAA819B0AF2C30676B00EBD98D386FED880BB6D9FF4A05C206A8394E973350A597FC337260025BE097EB7409A182C500853B9C90A096708BB83A80F2EEF4EA23190B9CE095C92A1B675903B07149C34E9FFAF6908BCC27D495AFED5C652242B939F71690748895E93181C746CB6E94C2E58C97149F5F3FE3CE552F44AA859115AC5459C3CA343EAC5F98D076E661EE24E15F22FA81393F85E7D1B26FD4D6CC1DC7BFAC0E1C97438141A98D65EFD1592D4A1211DC089CEC0903DD7F333F55FFE70609FACDE7B7293036BAAB67E6DEE7FB82E16019AF642814BFF4AF6676446AE656ACD601812A86B8DB9A53A1EBB744ABDC7C88DBABE4AA023FC253B56B3B517DFE66156BE7DB0653B3DA80ACF010125D652C38DC91BBA2C247AD9F769A9C2F8FA16A0B0507CA632612F9AD03C5E281FFB3341A929E1EE9A946889AF525B348DE24362FABAE20E583D67B4624C96053960F4744BA71C1911D5A84B3615CC8F52E23C10C38E542B61969BD82257B2BE5B50EF63B5110D6D23B81D33176473020D363845C45BD03D2AEF81F2A87C1BADD4C1248A3004AE57562E38B0FB10124E23DFC0AB9257F5982748E39610A46A974459A2F30D852D560D45BAABEC8B8BE77F8AC9AC2424F69FBD9E23F226FD7FCBA827ACCC49E9EEDDF659ACA0E931B965401E416FB6969743B8CDEC4DEC49648D7C1B82B7B337AB496F9C5FD31BB08CFCFF
-20220414141714 2 6 100 6143 2 C008BA5D87ECC10B5E79F4C05438A7EAFA57C290A50C25A0DFD5FF2FF19F5D39568056AF4AA2FB56F1CEFB636A5E30D99379305FE9633EA9CF219FD87C501640F500E2AFAAF304B7EF862B6C4C8339B558E3B8F00AB714AD6460786AAE3B328D41806A94F270B4D1F13B958579F3C1A7ACB166FB2E5566ED4305AB36C357852B2ED67D4C877338D891E0FFBBDE512E976B754CA2BA1770D8CE7117D5CEB99715C99D97285F3744533CD9BE72A4FBE2CACD4796FA3EFCA27CCA1F7F96DC2A521CCD7776125A5DB2EE4A12B1DCFD797C47188CE5CB6859ACBB452F922F4FF7E2098CB090F83812A18D8DD9B7465B2572EED81332A84C1591F1BA1633B571423FE38BAA819B0AF2C30676B00EBD98D386FED880BB6D9FF4A05C206A8394E973350A597FC337260025BE097EB7409A182C500853B9C90A096708BB83A80F2EEF4EA23190B9CE095C92A1B675903B07149C34E9FFAF6908BCC27D495AFED5C652242B939F71690748895E93181C746CB6E94C2E58C97149F5F3FE3CE552F44AA859115AC5459C3CA343EAC5F98D076E661EE24E15F22FA81393F85E7D1B26FD4D6CC1DC7BFAC0E1C97438141A98D65EFD1592D4A1211DC089CEC0903DD7F333F55FFE70609FACDE7B7293036BAAB67E6DEE7FB82E16019AF642814BFF4AF6676446AE656ACD601812A86B8DB9A53A1EBB744ABDC7C88DBABE4AA023FC253B56B3B517DFE66156BE7DB0653B3DA80ACF010125D652C38DC91BBA2C247AD9F769A9C2F8FA16A0B0507CA632612F9AD03C5E281FFB3341A929E1EE9A946889AF525B348DE24362FABAE20E583D67B4624C96053960F4744BA71C1911D5A84B3615CC8F52E23C10C38E542B61969BD82257B2BE5B50EF63B5110D6D23B81D33176473020D363845C45BD03D2AEF81F2A87C1BADD4C1248A3004AE57562E38B0FB10124E23DFC0AB9257F5982748E39610A46A974459A2F30D852D560D45BAABEC8B8BE77F8AC9AC2424F69FBD9E23F226FD7FCBA827ACCC49E9EEDDF659ACA0E931B965401E416FB6969743B8CDEC4DEC49648D7C1B82B7B337AB496F9C5FD31BB091AD83
-20220414142320 2 6 100 6143 2 C008BA5D87ECC10B5E79F4C05438A7EAFA57C290A50C25A0DFD5FF2FF19F5D39568056AF4AA2FB56F1CEFB636A5E30D99379305FE9633EA9CF219FD87C501640F500E2AFAAF304B7EF862B6C4C8339B558E3B8F00AB714AD6460786AAE3B328D41806A94F270B4D1F13B958579F3C1A7ACB166FB2E5566ED4305AB36C357852B2ED67D4C877338D891E0FFBBDE512E976B754CA2BA1770D8CE7117D5CEB99715C99D97285F3744533CD9BE72A4FBE2CACD4796FA3EFCA27CCA1F7F96DC2A521CCD7776125A5DB2EE4A12B1DCFD797C47188CE5CB6859ACBB452F922F4FF7E2098CB090F83812A18D8DD9B7465B2572EED81332A84C1591F1BA1633B571423FE38BAA819B0AF2C30676B00EBD98D386FED880BB6D9FF4A05C206A8394E973350A597FC337260025BE097EB7409A182C500853B9C90A096708BB83A80F2EEF4EA23190B9CE095C92A1B675903B07149C34E9FFAF6908BCC27D495AFED5C652242B939F71690748895E93181C746CB6E94C2E58C97149F5F3FE3CE552F44AA859115AC5459C3CA343EAC5F98D076E661EE24E15F22FA81393F85E7D1B26FD4D6CC1DC7BFAC0E1C97438141A98D65EFD1592D4A1211DC089CEC0903DD7F333F55FFE70609FACDE7B7293036BAAB67E6DEE7FB82E16019AF642814BFF4AF6676446AE656ACD601812A86B8DB9A53A1EBB744ABDC7C88DBABE4AA023FC253B56B3B517DFE66156BE7DB0653B3DA80ACF010125D652C38DC91BBA2C247AD9F769A9C2F8FA16A0B0507CA632612F9AD03C5E281FFB3341A929E1EE9A946889AF525B348DE24362FABAE20E583D67B4624C96053960F4744BA71C1911D5A84B3615CC8F52E23C10C38E542B61969BD82257B2BE5B50EF63B5110D6D23B81D33176473020D363845C45BD03D2AEF81F2A87C1BADD4C1248A3004AE57562E38B0FB10124E23DFC0AB9257F5982748E39610A46A974459A2F30D852D560D45BAABEC8B8BE77F8AC9AC2424F69FBD9E23F226FD7FCBA827ACCC49E9EEDDF659ACA0E931B965401E416FB6969743B8CDEC4DEC49648D7C1B82B7B337AB496F9C5FD31BB168D7F3
-20220414143527 2 6 100 6143 2 C008BA5D87ECC10B5E79F4C05438A7EAFA57C290A50C25A0DFD5FF2FF19F5D39568056AF4AA2FB56F1CEFB636A5E30D99379305FE9633EA9CF219FD87C501640F500E2AFAAF304B7EF862B6C4C8339B558E3B8F00AB714AD6460786AAE3B328D41806A94F270B4D1F13B958579F3C1A7ACB166FB2E5566ED4305AB36C357852B2ED67D4C877338D891E0FFBBDE512E976B754CA2BA1770D8CE7117D5CEB99715C99D97285F3744533CD9BE72A4FBE2CACD4796FA3EFCA27CCA1F7F96DC2A521CCD7776125A5DB2EE4A12B1DCFD797C47188CE5CB6859ACBB452F922F4FF7E2098CB090F83812A18D8DD9B7465B2572EED81332A84C1591F1BA1633B571423FE38BAA819B0AF2C30676B00EBD98D386FED880BB6D9FF4A05C206A8394E973350A597FC337260025BE097EB7409A182C500853B9C90A096708BB83A80F2EEF4EA23190B9CE095C92A1B675903B07149C34E9FFAF6908BCC27D495AFED5C652242B939F71690748895E93181C746CB6E94C2E58C97149F5F3FE3CE552F44AA859115AC5459C3CA343EAC5F98D076E661EE24E15F22FA81393F85E7D1B26FD4D6CC1DC7BFAC0E1C97438141A98D65EFD1592D4A1211DC089CEC0903DD7F333F55FFE70609FACDE7B7293036BAAB67E6DEE7FB82E16019AF642814BFF4AF6676446AE656ACD601812A86B8DB9A53A1EBB744ABDC7C88DBABE4AA023FC253B56B3B517DFE66156BE7DB0653B3DA80ACF010125D652C38DC91BBA2C247AD9F769A9C2F8FA16A0B0507CA632612F9AD03C5E281FFB3341A929E1EE9A946889AF525B348DE24362FABAE20E583D67B4624C96053960F4744BA71C1911D5A84B3615CC8F52E23C10C38E542B61969BD82257B2BE5B50EF63B5110D6D23B81D33176473020D363845C45BD03D2AEF81F2A87C1BADD4C1248A3004AE57562E38B0FB10124E23DFC0AB9257F5982748E39610A46A974459A2F30D852D560D45BAABEC8B8BE77F8AC9AC2424F69FBD9E23F226FD7FCBA827ACCC49E9EEDDF659ACA0E931B965401E416FB6969743B8CDEC4DEC49648D7C1B82B7B337AB496F9C5FD31BB322E33B
-20220414144127 2 6 100 6143 2 C008BA5D87ECC10B5E79F4C05438A7EAFA57C290A50C25A0DFD5FF2FF19F5D39568056AF4AA2FB56F1CEFB636A5E30D99379305FE9633EA9CF219FD87C501640F500E2AFAAF304B7EF862B6C4C8339B558E3B8F00AB714AD6460786AAE3B328D41806A94F270B4D1F13B958579F3C1A7ACB166FB2E5566ED4305AB36C357852B2ED67D4C877338D891E0FFBBDE512E976B754CA2BA1770D8CE7117D5CEB99715C99D97285F3744533CD9BE72A4FBE2CACD4796FA3EFCA27CCA1F7F96DC2A521CCD7776125A5DB2EE4A12B1DCFD797C47188CE5CB6859ACBB452F922F4FF7E2098CB090F83812A18D8DD9B7465B2572EED81332A84C1591F1BA1633B571423FE38BAA819B0AF2C30676B00EBD98D386FED880BB6D9FF4A05C206A8394E973350A597FC337260025BE097EB7409A182C500853B9C90A096708BB83A80F2EEF4EA23190B9CE095C92A1B675903B07149C34E9FFAF6908BCC27D495AFED5C652242B939F71690748895E93181C746CB6E94C2E58C97149F5F3FE3CE552F44AA859115AC5459C3CA343EAC5F98D076E661EE24E15F22FA81393F85E7D1B26FD4D6CC1DC7BFAC0E1C97438141A98D65EFD1592D4A1211DC089CEC0903DD7F333F55FFE70609FACDE7B7293036BAAB67E6DEE7FB82E16019AF642814BFF4AF6676446AE656ACD601812A86B8DB9A53A1EBB744ABDC7C88DBABE4AA023FC253B56B3B517DFE66156BE7DB0653B3DA80ACF010125D652C38DC91BBA2C247AD9F769A9C2F8FA16A0B0507CA632612F9AD03C5E281FFB3341A929E1EE9A946889AF525B348DE24362FABAE20E583D67B4624C96053960F4744BA71C1911D5A84B3615CC8F52E23C10C38E542B61969BD82257B2BE5B50EF63B5110D6D23B81D33176473020D363845C45BD03D2AEF81F2A87C1BADD4C1248A3004AE57562E38B0FB10124E23DFC0AB9257F5982748E39610A46A974459A2F30D852D560D45BAABEC8B8BE77F8AC9AC2424F69FBD9E23F226FD7FCBA827ACCC49E9EEDDF659ACA0E931B965401E416FB6969743B8CDEC4DEC49648D7C1B82B7B337AB496F9C5FD31BB3F516CB
-20220414145100 2 6 100 6143 5 C008BA5D87ECC10B5E79F4C05438A7EAFA57C290A50C25A0DFD5FF2FF19F5D39568056AF4AA2FB56F1CEFB636A5E30D99379305FE9633EA9CF219FD87C501640F500E2AFAAF304B7EF862B6C4C8339B558E3B8F00AB714AD6460786AAE3B328D41806A94F270B4D1F13B958579F3C1A7ACB166FB2E5566ED4305AB36C357852B2ED67D4C877338D891E0FFBBDE512E976B754CA2BA1770D8CE7117D5CEB99715C99D97285F3744533CD9BE72A4FBE2CACD4796FA3EFCA27CCA1F7F96DC2A521CCD7776125A5DB2EE4A12B1DCFD797C47188CE5CB6859ACBB452F922F4FF7E2098CB090F83812A18D8DD9B7465B2572EED81332A84C1591F1BA1633B571423FE38BAA819B0AF2C30676B00EBD98D386FED880BB6D9FF4A05C206A8394E973350A597FC337260025BE097EB7409A182C500853B9C90A096708BB83A80F2EEF4EA23190B9CE095C92A1B675903B07149C34E9FFAF6908BCC27D495AFED5C652242B939F71690748895E93181C746CB6E94C2E58C97149F5F3FE3CE552F44AA859115AC5459C3CA343EAC5F98D076E661EE24E15F22FA81393F85E7D1B26FD4D6CC1DC7BFAC0E1C97438141A98D65EFD1592D4A1211DC089CEC0903DD7F333F55FFE70609FACDE7B7293036BAAB67E6DEE7FB82E16019AF642814BFF4AF6676446AE656ACD601812A86B8DB9A53A1EBB744ABDC7C88DBABE4AA023FC253B56B3B517DFE66156BE7DB0653B3DA80ACF010125D652C38DC91BBA2C247AD9F769A9C2F8FA16A0B0507CA632612F9AD03C5E281FFB3341A929E1EE9A946889AF525B348DE24362FABAE20E583D67B4624C96053960F4744BA71C1911D5A84B3615CC8F52E23C10C38E542B61969BD82257B2BE5B50EF63B5110D6D23B81D33176473020D363845C45BD03D2AEF81F2A87C1BADD4C1248A3004AE57562E38B0FB10124E23DFC0AB9257F5982748E39610A46A974459A2F30D852D560D45BAABEC8B8BE77F8AC9AC2424F69FBD9E23F226FD7FCBA827ACCC49E9EEDDF659ACA0E931B965401E416FB6969743B8CDEC4DEC49648D7C1B82B7B337AB496F9C5FD31BB545E7CF
-20220414145934 2 6 100 6143 5 C008BA5D87ECC10B5E79F4C05438A7EAFA57C290A50C25A0DFD5FF2FF19F5D39568056AF4AA2FB56F1CEFB636A5E30D99379305FE9633EA9CF219FD87C501640F500E2AFAAF304B7EF862B6C4C8339B558E3B8F00AB714AD6460786AAE3B328D41806A94F270B4D1F13B958579F3C1A7ACB166FB2E5566ED4305AB36C357852B2ED67D4C877338D891E0FFBBDE512E976B754CA2BA1770D8CE7117D5CEB99715C99D97285F3744533CD9BE72A4FBE2CACD4796FA3EFCA27CCA1F7F96DC2A521CCD7776125A5DB2EE4A12B1DCFD797C47188CE5CB6859ACBB452F922F4FF7E2098CB090F83812A18D8DD9B7465B2572EED81332A84C1591F1BA1633B571423FE38BAA819B0AF2C30676B00EBD98D386FED880BB6D9FF4A05C206A8394E973350A597FC337260025BE097EB7409A182C500853B9C90A096708BB83A80F2EEF4EA23190B9CE095C92A1B675903B07149C34E9FFAF6908BCC27D495AFED5C652242B939F71690748895E93181C746CB6E94C2E58C97149F5F3FE3CE552F44AA859115AC5459C3CA343EAC5F98D076E661EE24E15F22FA81393F85E7D1B26FD4D6CC1DC7BFAC0E1C97438141A98D65EFD1592D4A1211DC089CEC0903DD7F333F55FFE70609FACDE7B7293036BAAB67E6DEE7FB82E16019AF642814BFF4AF6676446AE656ACD601812A86B8DB9A53A1EBB744ABDC7C88DBABE4AA023FC253B56B3B517DFE66156BE7DB0653B3DA80ACF010125D652C38DC91BBA2C247AD9F769A9C2F8FA16A0B0507CA632612F9AD03C5E281FFB3341A929E1EE9A946889AF525B348DE24362FABAE20E583D67B4624C96053960F4744BA71C1911D5A84B3615CC8F52E23C10C38E542B61969BD82257B2BE5B50EF63B5110D6D23B81D33176473020D363845C45BD03D2AEF81F2A87C1BADD4C1248A3004AE57562E38B0FB10124E23DFC0AB9257F5982748E39610A46A974459A2F30D852D560D45BAABEC8B8BE77F8AC9AC2424F69FBD9E23F226FD7FCBA827ACCC49E9EEDDF659ACA0E931B965401E416FB6969743B8CDEC4DEC49648D7C1B82B7B337AB496F9C5FD31BB676BF17
-20220414150941 2 6 100 6143 5 C008BA5D87ECC10B5E79F4C05438A7EAFA57C290A50C25A0DFD5FF2FF19F5D39568056AF4AA2FB56F1CEFB636A5E30D99379305FE9633EA9CF219FD87C501640F500E2AFAAF304B7EF862B6C4C8339B558E3B8F00AB714AD6460786AAE3B328D41806A94F270B4D1F13B958579F3C1A7ACB166FB2E5566ED4305AB36C357852B2ED67D4C877338D891E0FFBBDE512E976B754CA2BA1770D8CE7117D5CEB99715C99D97285F3744533CD9BE72A4FBE2CACD4796FA3EFCA27CCA1F7F96DC2A521CCD7776125A5DB2EE4A12B1DCFD797C47188CE5CB6859ACBB452F922F4FF7E2098CB090F83812A18D8DD9B7465B2572EED81332A84C1591F1BA1633B571423FE38BAA819B0AF2C30676B00EBD98D386FED880BB6D9FF4A05C206A8394E973350A597FC337260025BE097EB7409A182C500853B9C90A096708BB83A80F2EEF4EA23190B9CE095C92A1B675903B07149C34E9FFAF6908BCC27D495AFED5C652242B939F71690748895E93181C746CB6E94C2E58C97149F5F3FE3CE552F44AA859115AC5459C3CA343EAC5F98D076E661EE24E15F22FA81393F85E7D1B26FD4D6CC1DC7BFAC0E1C97438141A98D65EFD1592D4A1211DC089CEC0903DD7F333F55FFE70609FACDE7B7293036BAAB67E6DEE7FB82E16019AF642814BFF4AF6676446AE656ACD601812A86B8DB9A53A1EBB744ABDC7C88DBABE4AA023FC253B56B3B517DFE66156BE7DB0653B3DA80ACF010125D652C38DC91BBA2C247AD9F769A9C2F8FA16A0B0507CA632612F9AD03C5E281FFB3341A929E1EE9A946889AF525B348DE24362FABAE20E583D67B4624C96053960F4744BA71C1911D5A84B3615CC8F52E23C10C38E542B61969BD82257B2BE5B50EF63B5110D6D23B81D33176473020D363845C45BD03D2AEF81F2A87C1BADD4C1248A3004AE57562E38B0FB10124E23DFC0AB9257F5982748E39610A46A974459A2F30D852D560D45BAABEC8B8BE77F8AC9AC2424F69FBD9E23F226FD7FCBA827ACCC49E9EEDDF659ACA0E931B965401E416FB6969743B8CDEC4DEC49648D7C1B82B7B337AB496F9C5FD31BB7E51E57
-20220414151158 2 6 100 6143 2 C008BA5D87ECC10B5E79F4C05438A7EAFA57C290A50C25A0DFD5FF2FF19F5D39568056AF4AA2FB56F1CEFB636A5E30D99379305FE9633EA9CF219FD87C501640F500E2AFAAF304B7EF862B6C4C8339B558E3B8F00AB714AD6460786AAE3B328D41806A94F270B4D1F13B958579F3C1A7ACB166FB2E5566ED4305AB36C357852B2ED67D4C877338D891E0FFBBDE512E976B754CA2BA1770D8CE7117D5CEB99715C99D97285F3744533CD9BE72A4FBE2CACD4796FA3EFCA27CCA1F7F96DC2A521CCD7776125A5DB2EE4A12B1DCFD797C47188CE5CB6859ACBB452F922F4FF7E2098CB090F83812A18D8DD9B7465B2572EED81332A84C1591F1BA1633B571423FE38BAA819B0AF2C30676B00EBD98D386FED880BB6D9FF4A05C206A8394E973350A597FC337260025BE097EB7409A182C500853B9C90A096708BB83A80F2EEF4EA23190B9CE095C92A1B675903B07149C34E9FFAF6908BCC27D495AFED5C652242B939F71690748895E93181C746CB6E94C2E58C97149F5F3FE3CE552F44AA859115AC5459C3CA343EAC5F98D076E661EE24E15F22FA81393F85E7D1B26FD4D6CC1DC7BFAC0E1C97438141A98D65EFD1592D4A1211DC089CEC0903DD7F333F55FFE70609FACDE7B7293036BAAB67E6DEE7FB82E16019AF642814BFF4AF6676446AE656ACD601812A86B8DB9A53A1EBB744ABDC7C88DBABE4AA023FC253B56B3B517DFE66156BE7DB0653B3DA80ACF010125D652C38DC91BBA2C247AD9F769A9C2F8FA16A0B0507CA632612F9AD03C5E281FFB3341A929E1EE9A946889AF525B348DE24362FABAE20E583D67B4624C96053960F4744BA71C1911D5A84B3615CC8F52E23C10C38E542B61969BD82257B2BE5B50EF63B5110D6D23B81D33176473020D363845C45BD03D2AEF81F2A87C1BADD4C1248A3004AE57562E38B0FB10124E23DFC0AB9257F5982748E39610A46A974459A2F30D852D560D45BAABEC8B8BE77F8AC9AC2424F69FBD9E23F226FD7FCBA827ACCC49E9EEDDF659ACA0E931B965401E416FB6969743B8CDEC4DEC49648D7C1B82B7B337AB496F9C5FD31BB831F3E3
-20220414151904 2 6 100 6143 5 C008BA5D87ECC10B5E79F4C05438A7EAFA57C290A50C25A0DFD5FF2FF19F5D39568056AF4AA2FB56F1CEFB636A5E30D99379305FE9633EA9CF219FD87C501640F500E2AFAAF304B7EF862B6C4C8339B558E3B8F00AB714AD6460786AAE3B328D41806A94F270B4D1F13B958579F3C1A7ACB166FB2E5566ED4305AB36C357852B2ED67D4C877338D891E0FFBBDE512E976B754CA2BA1770D8CE7117D5CEB99715C99D97285F3744533CD9BE72A4FBE2CACD4796FA3EFCA27CCA1F7F96DC2A521CCD7776125A5DB2EE4A12B1DCFD797C47188CE5CB6859ACBB452F922F4FF7E2098CB090F83812A18D8DD9B7465B2572EED81332A84C1591F1BA1633B571423FE38BAA819B0AF2C30676B00EBD98D386FED880BB6D9FF4A05C206A8394E973350A597FC337260025BE097EB7409A182C500853B9C90A096708BB83A80F2EEF4EA23190B9CE095C92A1B675903B07149C34E9FFAF6908BCC27D495AFED5C652242B939F71690748895E93181C746CB6E94C2E58C97149F5F3FE3CE552F44AA859115AC5459C3CA343EAC5F98D076E661EE24E15F22FA81393F85E7D1B26FD4D6CC1DC7BFAC0E1C97438141A98D65EFD1592D4A1211DC089CEC0903DD7F333F55FFE70609FACDE7B7293036BAAB67E6DEE7FB82E16019AF642814BFF4AF6676446AE656ACD601812A86B8DB9A53A1EBB744ABDC7C88DBABE4AA023FC253B56B3B517DFE66156BE7DB0653B3DA80ACF010125D652C38DC91BBA2C247AD9F769A9C2F8FA16A0B0507CA632612F9AD03C5E281FFB3341A929E1EE9A946889AF525B348DE24362FABAE20E583D67B4624C96053960F4744BA71C1911D5A84B3615CC8F52E23C10C38E542B61969BD82257B2BE5B50EF63B5110D6D23B81D33176473020D363845C45BD03D2AEF81F2A87C1BADD4C1248A3004AE57562E38B0FB10124E23DFC0AB9257F5982748E39610A46A974459A2F30D852D560D45BAABEC8B8BE77F8AC9AC2424F69FBD9E23F226FD7FCBA827ACCC49E9EEDDF659ACA0E931B965401E416FB6969743B8CDEC4DEC49648D7C1B82B7B337AB496F9C5FD31BB92D7ACF
-20220414154448 2 6 100 6143 5 C008BA5D87ECC10B5E79F4C05438A7EAFA57C290A50C25A0DFD5FF2FF19F5D39568056AF4AA2FB56F1CEFB636A5E30D99379305FE9633EA9CF219FD87C501640F500E2AFAAF304B7EF862B6C4C8339B558E3B8F00AB714AD6460786AAE3B328D41806A94F270B4D1F13B958579F3C1A7ACB166FB2E5566ED4305AB36C357852B2ED67D4C877338D891E0FFBBDE512E976B754CA2BA1770D8CE7117D5CEB99715C99D97285F3744533CD9BE72A4FBE2CACD4796FA3EFCA27CCA1F7F96DC2A521CCD7776125A5DB2EE4A12B1DCFD797C47188CE5CB6859ACBB452F922F4FF7E2098CB090F83812A18D8DD9B7465B2572EED81332A84C1591F1BA1633B571423FE38BAA819B0AF2C30676B00EBD98D386FED880BB6D9FF4A05C206A8394E973350A597FC337260025BE097EB7409A182C500853B9C90A096708BB83A80F2EEF4EA23190B9CE095C92A1B675903B07149C34E9FFAF6908BCC27D495AFED5C652242B939F71690748895E93181C746CB6E94C2E58C97149F5F3FE3CE552F44AA859115AC5459C3CA343EAC5F98D076E661EE24E15F22FA81393F85E7D1B26FD4D6CC1DC7BFAC0E1C97438141A98D65EFD1592D4A1211DC089CEC0903DD7F333F55FFE70609FACDE7B7293036BAAB67E6DEE7FB82E16019AF642814BFF4AF6676446AE656ACD601812A86B8DB9A53A1EBB744ABDC7C88DBABE4AA023FC253B56B3B517DFE66156BE7DB0653B3DA80ACF010125D652C38DC91BBA2C247AD9F769A9C2F8FA16A0B0507CA632612F9AD03C5E281FFB3341A929E1EE9A946889AF525B348DE24362FABAE20E583D67B4624C96053960F4744BA71C1911D5A84B3615CC8F52E23C10C38E542B61969BD82257B2BE5B50EF63B5110D6D23B81D33176473020D363845C45BD03D2AEF81F2A87C1BADD4C1248A3004AE57562E38B0FB10124E23DFC0AB9257F5982748E39610A46A974459A2F30D852D560D45BAABEC8B8BE77F8AC9AC2424F69FBD9E23F226FD7FCBA827ACCC49E9EEDDF659ACA0E931B965401E416FB6969743B8CDEC4DEC49648D7C1B82B7B337AB496F9C5FD31BBCD2236F
-20220414154556 2 6 100 6143 5 C008BA5D87ECC10B5E79F4C05438A7EAFA57C290A50C25A0DFD5FF2FF19F5D39568056AF4AA2FB56F1CEFB636A5E30D99379305FE9633EA9CF219FD87C501640F500E2AFAAF304B7EF862B6C4C8339B558E3B8F00AB714AD6460786AAE3B328D41806A94F270B4D1F13B958579F3C1A7ACB166FB2E5566ED4305AB36C357852B2ED67D4C877338D891E0FFBBDE512E976B754CA2BA1770D8CE7117D5CEB99715C99D97285F3744533CD9BE72A4FBE2CACD4796FA3EFCA27CCA1F7F96DC2A521CCD7776125A5DB2EE4A12B1DCFD797C47188CE5CB6859ACBB452F922F4FF7E2098CB090F83812A18D8DD9B7465B2572EED81332A84C1591F1BA1633B571423FE38BAA819B0AF2C30676B00EBD98D386FED880BB6D9FF4A05C206A8394E973350A597FC337260025BE097EB7409A182C500853B9C90A096708BB83A80F2EEF4EA23190B9CE095C92A1B675903B07149C34E9FFAF6908BCC27D495AFED5C652242B939F71690748895E93181C746CB6E94C2E58C97149F5F3FE3CE552F44AA859115AC5459C3CA343EAC5F98D076E661EE24E15F22FA81393F85E7D1B26FD4D6CC1DC7BFAC0E1C97438141A98D65EFD1592D4A1211DC089CEC0903DD7F333F55FFE70609FACDE7B7293036BAAB67E6DEE7FB82E16019AF642814BFF4AF6676446AE656ACD601812A86B8DB9A53A1EBB744ABDC7C88DBABE4AA023FC253B56B3B517DFE66156BE7DB0653B3DA80ACF010125D652C38DC91BBA2C247AD9F769A9C2F8FA16A0B0507CA632612F9AD03C5E281FFB3341A929E1EE9A946889AF525B348DE24362FABAE20E583D67B4624C96053960F4744BA71C1911D5A84B3615CC8F52E23C10C38E542B61969BD82257B2BE5B50EF63B5110D6D23B81D33176473020D363845C45BD03D2AEF81F2A87C1BADD4C1248A3004AE57562E38B0FB10124E23DFC0AB9257F5982748E39610A46A974459A2F30D852D560D45BAABEC8B8BE77F8AC9AC2424F69FBD9E23F226FD7FCBA827ACCC49E9EEDDF659ACA0E931B965401E416FB6969743B8CDEC4DEC49648D7C1B82B7B337AB496F9C5FD31BBCF2D2B7
-20220414162116 2 6 100 6143 2 C008BA5D87ECC10B5E79F4C05438A7EAFA57C290A50C25A0DFD5FF2FF19F5D39568056AF4AA2FB56F1CEFB636A5E30D99379305FE9633EA9CF219FD87C501640F500E2AFAAF304B7EF862B6C4C8339B558E3B8F00AB714AD6460786AAE3B328D41806A94F270B4D1F13B958579F3C1A7ACB166FB2E5566ED4305AB36C357852B2ED67D4C877338D891E0FFBBDE512E976B754CA2BA1770D8CE7117D5CEB99715C99D97285F3744533CD9BE72A4FBE2CACD4796FA3EFCA27CCA1F7F96DC2A521CCD7776125A5DB2EE4A12B1DCFD797C47188CE5CB6859ACBB452F922F4FF7E2098CB090F83812A18D8DD9B7465B2572EED81332A84C1591F1BA1633B571423FE38BAA819B0AF2C30676B00EBD98D386FED880BB6D9FF4A05C206A8394E973350A597FC337260025BE097EB7409A182C500853B9C90A096708BB83A80F2EEF4EA23190B9CE095C92A1B675903B07149C34E9FFAF6908BCC27D495AFED5C652242B939F71690748895E93181C746CB6E94C2E58C97149F5F3FE3CE552F44AA859115AC5459C3CA343EAC5F98D076E661EE24E15F22FA81393F85E7D1B26FD4D6CC1DC7BFAC0E1C97438141A98D65EFD1592D4A1211DC089CEC0903DD7F333F55FFE70609FACDE7B7293036BAAB67E6DEE7FB82E16019AF642814BFF4AF6676446AE656ACD601812A86B8DB9A53A1EBB744ABDC7C88DBABE4AA023FC253B56B3B517DFE66156BE7DB0653B3DA80ACF010125D652C38DC91BBA2C247AD9F769A9C2F8FA16A0B0507CA632612F9AD03C5E281FFB3341A929E1EE9A946889AF525B348DE24362FABAE20E583D67B4624C96053960F4744BA71C1911D5A84B3615CC8F52E23C10C38E542B61969BD82257B2BE5B50EF63B5110D6D23B81D33176473020D363845C45BD03D2AEF81F2A87C1BADD4C1248A3004AE57562E38B0FB10124E23DFC0AB9257F5982748E39610A46A974459A2F30D852D560D45BAABEC8B8BE77F8AC9AC2424F69FBD9E23F226FD7FCBA827ACCC49E9EEDDF659ACA0E931B965401E416FB6969743B8CDEC4DEC49648D7C1B82B7B337AB496F9C5FD31BC1F88833
-20220414165146 2 6 100 6143 2 C008BA5D87ECC10B5E79F4C05438A7EAFA57C290A50C25A0DFD5FF2FF19F5D39568056AF4AA2FB56F1CEFB636A5E30D99379305FE9633EA9CF219FD87C501640F500E2AFAAF304B7EF862B6C4C8339B558E3B8F00AB714AD6460786AAE3B328D41806A94F270B4D1F13B958579F3C1A7ACB166FB2E5566ED4305AB36C357852B2ED67D4C877338D891E0FFBBDE512E976B754CA2BA1770D8CE7117D5CEB99715C99D97285F3744533CD9BE72A4FBE2CACD4796FA3EFCA27CCA1F7F96DC2A521CCD7776125A5DB2EE4A12B1DCFD797C47188CE5CB6859ACBB452F922F4FF7E2098CB090F83812A18D8DD9B7465B2572EED81332A84C1591F1BA1633B571423FE38BAA819B0AF2C30676B00EBD98D386FED880BB6D9FF4A05C206A8394E973350A597FC337260025BE097EB7409A182C500853B9C90A096708BB83A80F2EEF4EA23190B9CE095C92A1B675903B07149C34E9FFAF6908BCC27D495AFED5C652242B939F71690748895E93181C746CB6E94C2E58C97149F5F3FE3CE552F44AA859115AC5459C3CA343EAC5F98D076E661EE24E15F22FA81393F85E7D1B26FD4D6CC1DC7BFAC0E1C97438141A98D65EFD1592D4A1211DC089CEC0903DD7F333F55FFE70609FACDE7B7293036BAAB67E6DEE7FB82E16019AF642814BFF4AF6676446AE656ACD601812A86B8DB9A53A1EBB744ABDC7C88DBABE4AA023FC253B56B3B517DFE66156BE7DB0653B3DA80ACF010125D652C38DC91BBA2C247AD9F769A9C2F8FA16A0B0507CA632612F9AD03C5E281FFB3341A929E1EE9A946889AF525B348DE24362FABAE20E583D67B4624C96053960F4744BA71C1911D5A84B3615CC8F52E23C10C38E542B61969BD82257B2BE5B50EF63B5110D6D23B81D33176473020D363845C45BD03D2AEF81F2A87C1BADD4C1248A3004AE57562E38B0FB10124E23DFC0AB9257F5982748E39610A46A974459A2F30D852D560D45BAABEC8B8BE77F8AC9AC2424F69FBD9E23F226FD7FCBA827ACCC49E9EEDDF659ACA0E931B965401E416FB6969743B8CDEC4DEC49648D7C1B82B7B337AB496F9C5FD31BC6458233
-20220414165524 2 6 100 6143 2 C008BA5D87ECC10B5E79F4C05438A7EAFA57C290A50C25A0DFD5FF2FF19F5D39568056AF4AA2FB56F1CEFB636A5E30D99379305FE9633EA9CF219FD87C501640F500E2AFAAF304B7EF862B6C4C8339B558E3B8F00AB714AD6460786AAE3B328D41806A94F270B4D1F13B958579F3C1A7ACB166FB2E5566ED4305AB36C357852B2ED67D4C877338D891E0FFBBDE512E976B754CA2BA1770D8CE7117D5CEB99715C99D97285F3744533CD9BE72A4FBE2CACD4796FA3EFCA27CCA1F7F96DC2A521CCD7776125A5DB2EE4A12B1DCFD797C47188CE5CB6859ACBB452F922F4FF7E2098CB090F83812A18D8DD9B7465B2572EED81332A84C1591F1BA1633B571423FE38BAA819B0AF2C30676B00EBD98D386FED880BB6D9FF4A05C206A8394E973350A597FC337260025BE097EB7409A182C500853B9C90A096708BB83A80F2EEF4EA23190B9CE095C92A1B675903B07149C34E9FFAF6908BCC27D495AFED5C652242B939F71690748895E93181C746CB6E94C2E58C97149F5F3FE3CE552F44AA859115AC5459C3CA343EAC5F98D076E661EE24E15F22FA81393F85E7D1B26FD4D6CC1DC7BFAC0E1C97438141A98D65EFD1592D4A1211DC089CEC0903DD7F333F55FFE70609FACDE7B7293036BAAB67E6DEE7FB82E16019AF642814BFF4AF6676446AE656ACD601812A86B8DB9A53A1EBB744ABDC7C88DBABE4AA023FC253B56B3B517DFE66156BE7DB0653B3DA80ACF010125D652C38DC91BBA2C247AD9F769A9C2F8FA16A0B0507CA632612F9AD03C5E281FFB3341A929E1EE9A946889AF525B348DE24362FABAE20E583D67B4624C96053960F4744BA71C1911D5A84B3615CC8F52E23C10C38E542B61969BD82257B2BE5B50EF63B5110D6D23B81D33176473020D363845C45BD03D2AEF81F2A87C1BADD4C1248A3004AE57562E38B0FB10124E23DFC0AB9257F5982748E39610A46A974459A2F30D852D560D45BAABEC8B8BE77F8AC9AC2424F69FBD9E23F226FD7FCBA827ACCC49E9EEDDF659ACA0E931B965401E416FB6969743B8CDEC4DEC49648D7C1B82B7B337AB496F9C5FD31BC6C0DCC3
-20220414170020 2 6 100 6143 2 C008BA5D87ECC10B5E79F4C05438A7EAFA57C290A50C25A0DFD5FF2FF19F5D39568056AF4AA2FB56F1CEFB636A5E30D99379305FE9633EA9CF219FD87C501640F500E2AFAAF304B7EF862B6C4C8339B558E3B8F00AB714AD6460786AAE3B328D41806A94F270B4D1F13B958579F3C1A7ACB166FB2E5566ED4305AB36C357852B2ED67D4C877338D891E0FFBBDE512E976B754CA2BA1770D8CE7117D5CEB99715C99D97285F3744533CD9BE72A4FBE2CACD4796FA3EFCA27CCA1F7F96DC2A521CCD7776125A5DB2EE4A12B1DCFD797C47188CE5CB6859ACBB452F922F4FF7E2098CB090F83812A18D8DD9B7465B2572EED81332A84C1591F1BA1633B571423FE38BAA819B0AF2C30676B00EBD98D386FED880BB6D9FF4A05C206A8394E973350A597FC337260025BE097EB7409A182C500853B9C90A096708BB83A80F2EEF4EA23190B9CE095C92A1B675903B07149C34E9FFAF6908BCC27D495AFED5C652242B939F71690748895E93181C746CB6E94C2E58C97149F5F3FE3CE552F44AA859115AC5459C3CA343EAC5F98D076E661EE24E15F22FA81393F85E7D1B26FD4D6CC1DC7BFAC0E1C97438141A98D65EFD1592D4A1211DC089CEC0903DD7F333F55FFE70609FACDE7B7293036BAAB67E6DEE7FB82E16019AF642814BFF4AF6676446AE656ACD601812A86B8DB9A53A1EBB744ABDC7C88DBABE4AA023FC253B56B3B517DFE66156BE7DB0653B3DA80ACF010125D652C38DC91BBA2C247AD9F769A9C2F8FA16A0B0507CA632612F9AD03C5E281FFB3341A929E1EE9A946889AF525B348DE24362FABAE20E583D67B4624C96053960F4744BA71C1911D5A84B3615CC8F52E23C10C38E542B61969BD82257B2BE5B50EF63B5110D6D23B81D33176473020D363845C45BD03D2AEF81F2A87C1BADD4C1248A3004AE57562E38B0FB10124E23DFC0AB9257F5982748E39610A46A974459A2F30D852D560D45BAABEC8B8BE77F8AC9AC2424F69FBD9E23F226FD7FCBA827ACCC49E9EEDDF659ACA0E931B965401E416FB6969743B8CDEC4DEC49648D7C1B82B7B337AB496F9C5FD31BC7669C1B
-20220414170406 2 6 100 6143 5 C008BA5D87ECC10B5E79F4C05438A7EAFA57C290A50C25A0DFD5FF2FF19F5D39568056AF4AA2FB56F1CEFB636A5E30D99379305FE9633EA9CF219FD87C501640F500E2AFAAF304B7EF862B6C4C8339B558E3B8F00AB714AD6460786AAE3B328D41806A94F270B4D1F13B958579F3C1A7ACB166FB2E5566ED4305AB36C357852B2ED67D4C877338D891E0FFBBDE512E976B754CA2BA1770D8CE7117D5CEB99715C99D97285F3744533CD9BE72A4FBE2CACD4796FA3EFCA27CCA1F7F96DC2A521CCD7776125A5DB2EE4A12B1DCFD797C47188CE5CB6859ACBB452F922F4FF7E2098CB090F83812A18D8DD9B7465B2572EED81332A84C1591F1BA1633B571423FE38BAA819B0AF2C30676B00EBD98D386FED880BB6D9FF4A05C206A8394E973350A597FC337260025BE097EB7409A182C500853B9C90A096708BB83A80F2EEF4EA23190B9CE095C92A1B675903B07149C34E9FFAF6908BCC27D495AFED5C652242B939F71690748895E93181C746CB6E94C2E58C97149F5F3FE3CE552F44AA859115AC5459C3CA343EAC5F98D076E661EE24E15F22FA81393F85E7D1B26FD4D6CC1DC7BFAC0E1C97438141A98D65EFD1592D4A1211DC089CEC0903DD7F333F55FFE70609FACDE7B7293036BAAB67E6DEE7FB82E16019AF642814BFF4AF6676446AE656ACD601812A86B8DB9A53A1EBB744ABDC7C88DBABE4AA023FC253B56B3B517DFE66156BE7DB0653B3DA80ACF010125D652C38DC91BBA2C247AD9F769A9C2F8FA16A0B0507CA632612F9AD03C5E281FFB3341A929E1EE9A946889AF525B348DE24362FABAE20E583D67B4624C96053960F4744BA71C1911D5A84B3615CC8F52E23C10C38E542B61969BD82257B2BE5B50EF63B5110D6D23B81D33176473020D363845C45BD03D2AEF81F2A87C1BADD4C1248A3004AE57562E38B0FB10124E23DFC0AB9257F5982748E39610A46A974459A2F30D852D560D45BAABEC8B8BE77F8AC9AC2424F69FBD9E23F226FD7FCBA827ACCC49E9EEDDF659ACA0E931B965401E416FB6969743B8CDEC4DEC49648D7C1B82B7B337AB496F9C5FD31BC7E116A7
-20220414170516 2 6 100 6143 5 C008BA5D87ECC10B5E79F4C05438A7EAFA57C290A50C25A0DFD5FF2FF19F5D39568056AF4AA2FB56F1CEFB636A5E30D99379305FE9633EA9CF219FD87C501640F500E2AFAAF304B7EF862B6C4C8339B558E3B8F00AB714AD6460786AAE3B328D41806A94F270B4D1F13B958579F3C1A7ACB166FB2E5566ED4305AB36C357852B2ED67D4C877338D891E0FFBBDE512E976B754CA2BA1770D8CE7117D5CEB99715C99D97285F3744533CD9BE72A4FBE2CACD4796FA3EFCA27CCA1F7F96DC2A521CCD7776125A5DB2EE4A12B1DCFD797C47188CE5CB6859ACBB452F922F4FF7E2098CB090F83812A18D8DD9B7465B2572EED81332A84C1591F1BA1633B571423FE38BAA819B0AF2C30676B00EBD98D386FED880BB6D9FF4A05C206A8394E973350A597FC337260025BE097EB7409A182C500853B9C90A096708BB83A80F2EEF4EA23190B9CE095C92A1B675903B07149C34E9FFAF6908BCC27D495AFED5C652242B939F71690748895E93181C746CB6E94C2E58C97149F5F3FE3CE552F44AA859115AC5459C3CA343EAC5F98D076E661EE24E15F22FA81393F85E7D1B26FD4D6CC1DC7BFAC0E1C97438141A98D65EFD1592D4A1211DC089CEC0903DD7F333F55FFE70609FACDE7B7293036BAAB67E6DEE7FB82E16019AF642814BFF4AF6676446AE656ACD601812A86B8DB9A53A1EBB744ABDC7C88DBABE4AA023FC253B56B3B517DFE66156BE7DB0653B3DA80ACF010125D652C38DC91BBA2C247AD9F769A9C2F8FA16A0B0507CA632612F9AD03C5E281FFB3341A929E1EE9A946889AF525B348DE24362FABAE20E583D67B4624C96053960F4744BA71C1911D5A84B3615CC8F52E23C10C38E542B61969BD82257B2BE5B50EF63B5110D6D23B81D33176473020D363845C45BD03D2AEF81F2A87C1BADD4C1248A3004AE57562E38B0FB10124E23DFC0AB9257F5982748E39610A46A974459A2F30D852D560D45BAABEC8B8BE77F8AC9AC2424F69FBD9E23F226FD7FCBA827ACCC49E9EEDDF659ACA0E931B965401E416FB6969743B8CDEC4DEC49648D7C1B82B7B337AB496F9C5FD31BC802E3C7
-20220414171447 2 6 100 6143 5 C008BA5D87ECC10B5E79F4C05438A7EAFA57C290A50C25A0DFD5FF2FF19F5D39568056AF4AA2FB56F1CEFB636A5E30D99379305FE9633EA9CF219FD87C501640F500E2AFAAF304B7EF862B6C4C8339B558E3B8F00AB714AD6460786AAE3B328D41806A94F270B4D1F13B958579F3C1A7ACB166FB2E5566ED4305AB36C357852B2ED67D4C877338D891E0FFBBDE512E976B754CA2BA1770D8CE7117D5CEB99715C99D97285F3744533CD9BE72A4FBE2CACD4796FA3EFCA27CCA1F7F96DC2A521CCD7776125A5DB2EE4A12B1DCFD797C47188CE5CB6859ACBB452F922F4FF7E2098CB090F83812A18D8DD9B7465B2572EED81332A84C1591F1BA1633B571423FE38BAA819B0AF2C30676B00EBD98D386FED880BB6D9FF4A05C206A8394E973350A597FC337260025BE097EB7409A182C500853B9C90A096708BB83A80F2EEF4EA23190B9CE095C92A1B675903B07149C34E9FFAF6908BCC27D495AFED5C652242B939F71690748895E93181C746CB6E94C2E58C97149F5F3FE3CE552F44AA859115AC5459C3CA343EAC5F98D076E661EE24E15F22FA81393F85E7D1B26FD4D6CC1DC7BFAC0E1C97438141A98D65EFD1592D4A1211DC089CEC0903DD7F333F55FFE70609FACDE7B7293036BAAB67E6DEE7FB82E16019AF642814BFF4AF6676446AE656ACD601812A86B8DB9A53A1EBB744ABDC7C88DBABE4AA023FC253B56B3B517DFE66156BE7DB0653B3DA80ACF010125D652C38DC91BBA2C247AD9F769A9C2F8FA16A0B0507CA632612F9AD03C5E281FFB3341A929E1EE9A946889AF525B348DE24362FABAE20E583D67B4624C96053960F4744BA71C1911D5A84B3615CC8F52E23C10C38E542B61969BD82257B2BE5B50EF63B5110D6D23B81D33176473020D363845C45BD03D2AEF81F2A87C1BADD4C1248A3004AE57562E38B0FB10124E23DFC0AB9257F5982748E39610A46A974459A2F30D852D560D45BAABEC8B8BE77F8AC9AC2424F69FBD9E23F226FD7FCBA827ACCC49E9EEDDF659ACA0E931B965401E416FB6969743B8CDEC4DEC49648D7C1B82B7B337AB496F9C5FD31BC946FB1F
-20220414171849 2 6 100 6143 2 C008BA5D87ECC10B5E79F4C05438A7EAFA57C290A50C25A0DFD5FF2FF19F5D39568056AF4AA2FB56F1CEFB636A5E30D99379305FE9633EA9CF219FD87C501640F500E2AFAAF304B7EF862B6C4C8339B558E3B8F00AB714AD6460786AAE3B328D41806A94F270B4D1F13B958579F3C1A7ACB166FB2E5566ED4305AB36C357852B2ED67D4C877338D891E0FFBBDE512E976B754CA2BA1770D8CE7117D5CEB99715C99D97285F3744533CD9BE72A4FBE2CACD4796FA3EFCA27CCA1F7F96DC2A521CCD7776125A5DB2EE4A12B1DCFD797C47188CE5CB6859ACBB452F922F4FF7E2098CB090F83812A18D8DD9B7465B2572EED81332A84C1591F1BA1633B571423FE38BAA819B0AF2C30676B00EBD98D386FED880BB6D9FF4A05C206A8394E973350A597FC337260025BE097EB7409A182C500853B9C90A096708BB83A80F2EEF4EA23190B9CE095C92A1B675903B07149C34E9FFAF6908BCC27D495AFED5C652242B939F71690748895E93181C746CB6E94C2E58C97149F5F3FE3CE552F44AA859115AC5459C3CA343EAC5F98D076E661EE24E15F22FA81393F85E7D1B26FD4D6CC1DC7BFAC0E1C97438141A98D65EFD1592D4A1211DC089CEC0903DD7F333F55FFE70609FACDE7B7293036BAAB67E6DEE7FB82E16019AF642814BFF4AF6676446AE656ACD601812A86B8DB9A53A1EBB744ABDC7C88DBABE4AA023FC253B56B3B517DFE66156BE7DB0653B3DA80ACF010125D652C38DC91BBA2C247AD9F769A9C2F8FA16A0B0507CA632612F9AD03C5E281FFB3341A929E1EE9A946889AF525B348DE24362FABAE20E583D67B4624C96053960F4744BA71C1911D5A84B3615CC8F52E23C10C38E542B61969BD82257B2BE5B50EF63B5110D6D23B81D33176473020D363845C45BD03D2AEF81F2A87C1BADD4C1248A3004AE57562E38B0FB10124E23DFC0AB9257F5982748E39610A46A974459A2F30D852D560D45BAABEC8B8BE77F8AC9AC2424F69FBD9E23F226FD7FCBA827ACCC49E9EEDDF659ACA0E931B965401E416FB6969743B8CDEC4DEC49648D7C1B82B7B337AB496F9C5FD31BC9D13AEB
-20220414173651 2 6 100 6143 5 C008BA5D87ECC10B5E79F4C05438A7EAFA57C290A50C25A0DFD5FF2FF19F5D39568056AF4AA2FB56F1CEFB636A5E30D99379305FE9633EA9CF219FD87C501640F500E2AFAAF304B7EF862B6C4C8339B558E3B8F00AB714AD6460786AAE3B328D41806A94F270B4D1F13B958579F3C1A7ACB166FB2E5566ED4305AB36C357852B2ED67D4C877338D891E0FFBBDE512E976B754CA2BA1770D8CE7117D5CEB99715C99D97285F3744533CD9BE72A4FBE2CACD4796FA3EFCA27CCA1F7F96DC2A521CCD7776125A5DB2EE4A12B1DCFD797C47188CE5CB6859ACBB452F922F4FF7E2098CB090F83812A18D8DD9B7465B2572EED81332A84C1591F1BA1633B571423FE38BAA819B0AF2C30676B00EBD98D386FED880BB6D9FF4A05C206A8394E973350A597FC337260025BE097EB7409A182C500853B9C90A096708BB83A80F2EEF4EA23190B9CE095C92A1B675903B07149C34E9FFAF6908BCC27D495AFED5C652242B939F71690748895E93181C746CB6E94C2E58C97149F5F3FE3CE552F44AA859115AC5459C3CA343EAC5F98D076E661EE24E15F22FA81393F85E7D1B26FD4D6CC1DC7BFAC0E1C97438141A98D65EFD1592D4A1211DC089CEC0903DD7F333F55FFE70609FACDE7B7293036BAAB67E6DEE7FB82E16019AF642814BFF4AF6676446AE656ACD601812A86B8DB9A53A1EBB744ABDC7C88DBABE4AA023FC253B56B3B517DFE66156BE7DB0653B3DA80ACF010125D652C38DC91BBA2C247AD9F769A9C2F8FA16A0B0507CA632612F9AD03C5E281FFB3341A929E1EE9A946889AF525B348DE24362FABAE20E583D67B4624C96053960F4744BA71C1911D5A84B3615CC8F52E23C10C38E542B61969BD82257B2BE5B50EF63B5110D6D23B81D33176473020D363845C45BD03D2AEF81F2A87C1BADD4C1248A3004AE57562E38B0FB10124E23DFC0AB9257F5982748E39610A46A974459A2F30D852D560D45BAABEC8B8BE77F8AC9AC2424F69FBD9E23F226FD7FCBA827ACCC49E9EEDDF659ACA0E931B965401E416FB6969743B8CDEC4DEC49648D7C1B82B7B337AB496F9C5FD31BCC51B887
-20220414174909 2 6 100 6143 5 C008BA5D87ECC10B5E79F4C05438A7EAFA57C290A50C25A0DFD5FF2FF19F5D39568056AF4AA2FB56F1CEFB636A5E30D99379305FE9633EA9CF219FD87C501640F500E2AFAAF304B7EF862B6C4C8339B558E3B8F00AB714AD6460786AAE3B328D41806A94F270B4D1F13B958579F3C1A7ACB166FB2E5566ED4305AB36C357852B2ED67D4C877338D891E0FFBBDE512E976B754CA2BA1770D8CE7117D5CEB99715C99D97285F3744533CD9BE72A4FBE2CACD4796FA3EFCA27CCA1F7F96DC2A521CCD7776125A5DB2EE4A12B1DCFD797C47188CE5CB6859ACBB452F922F4FF7E2098CB090F83812A18D8DD9B7465B2572EED81332A84C1591F1BA1633B571423FE38BAA819B0AF2C30676B00EBD98D386FED880BB6D9FF4A05C206A8394E973350A597FC337260025BE097EB7409A182C500853B9C90A096708BB83A80F2EEF4EA23190B9CE095C92A1B675903B07149C34E9FFAF6908BCC27D495AFED5C652242B939F71690748895E93181C746CB6E94C2E58C97149F5F3FE3CE552F44AA859115AC5459C3CA343EAC5F98D076E661EE24E15F22FA81393F85E7D1B26FD4D6CC1DC7BFAC0E1C97438141A98D65EFD1592D4A1211DC089CEC0903DD7F333F55FFE70609FACDE7B7293036BAAB67E6DEE7FB82E16019AF642814BFF4AF6676446AE656ACD601812A86B8DB9A53A1EBB744ABDC7C88DBABE4AA023FC253B56B3B517DFE66156BE7DB0653B3DA80ACF010125D652C38DC91BBA2C247AD9F769A9C2F8FA16A0B0507CA632612F9AD03C5E281FFB3341A929E1EE9A946889AF525B348DE24362FABAE20E583D67B4624C96053960F4744BA71C1911D5A84B3615CC8F52E23C10C38E542B61969BD82257B2BE5B50EF63B5110D6D23B81D33176473020D363845C45BD03D2AEF81F2A87C1BADD4C1248A3004AE57562E38B0FB10124E23DFC0AB9257F5982748E39610A46A974459A2F30D852D560D45BAABEC8B8BE77F8AC9AC2424F69FBD9E23F226FD7FCBA827ACCC49E9EEDDF659ACA0E931B965401E416FB6969743B8CDEC4DEC49648D7C1B82B7B337AB496F9C5FD31BCDFE595F
-20220414175707 2 6 100 6143 2 C008BA5D87ECC10B5E79F4C05438A7EAFA57C290A50C25A0DFD5FF2FF19F5D39568056AF4AA2FB56F1CEFB636A5E30D99379305FE9633EA9CF219FD87C501640F500E2AFAAF304B7EF862B6C4C8339B558E3B8F00AB714AD6460786AAE3B328D41806A94F270B4D1F13B958579F3C1A7ACB166FB2E5566ED4305AB36C357852B2ED67D4C877338D891E0FFBBDE512E976B754CA2BA1770D8CE7117D5CEB99715C99D97285F3744533CD9BE72A4FBE2CACD4796FA3EFCA27CCA1F7F96DC2A521CCD7776125A5DB2EE4A12B1DCFD797C47188CE5CB6859ACBB452F922F4FF7E2098CB090F83812A18D8DD9B7465B2572EED81332A84C1591F1BA1633B571423FE38BAA819B0AF2C30676B00EBD98D386FED880BB6D9FF4A05C206A8394E973350A597FC337260025BE097EB7409A182C500853B9C90A096708BB83A80F2EEF4EA23190B9CE095C92A1B675903B07149C34E9FFAF6908BCC27D495AFED5C652242B939F71690748895E93181C746CB6E94C2E58C97149F5F3FE3CE552F44AA859115AC5459C3CA343EAC5F98D076E661EE24E15F22FA81393F85E7D1B26FD4D6CC1DC7BFAC0E1C97438141A98D65EFD1592D4A1211DC089CEC0903DD7F333F55FFE70609FACDE7B7293036BAAB67E6DEE7FB82E16019AF642814BFF4AF6676446AE656ACD601812A86B8DB9A53A1EBB744ABDC7C88DBABE4AA023FC253B56B3B517DFE66156BE7DB0653B3DA80ACF010125D652C38DC91BBA2C247AD9F769A9C2F8FA16A0B0507CA632612F9AD03C5E281FFB3341A929E1EE9A946889AF525B348DE24362FABAE20E583D67B4624C96053960F4744BA71C1911D5A84B3615CC8F52E23C10C38E542B61969BD82257B2BE5B50EF63B5110D6D23B81D33176473020D363845C45BD03D2AEF81F2A87C1BADD4C1248A3004AE57562E38B0FB10124E23DFC0AB9257F5982748E39610A46A974459A2F30D852D560D45BAABEC8B8BE77F8AC9AC2424F69FBD9E23F226FD7FCBA827ACCC49E9EEDDF659ACA0E931B965401E416FB6969743B8CDEC4DEC49648D7C1B82B7B337AB496F9C5FD31BCF0D967B
-20220414180209 2 6 100 6143 2 C008BA5D87ECC10B5E79F4C05438A7EAFA57C290A50C25A0DFD5FF2FF19F5D39568056AF4AA2FB56F1CEFB636A5E30D99379305FE9633EA9CF219FD87C501640F500E2AFAAF304B7EF862B6C4C8339B558E3B8F00AB714AD6460786AAE3B328D41806A94F270B4D1F13B958579F3C1A7ACB166FB2E5566ED4305AB36C357852B2ED67D4C877338D891E0FFBBDE512E976B754CA2BA1770D8CE7117D5CEB99715C99D97285F3744533CD9BE72A4FBE2CACD4796FA3EFCA27CCA1F7F96DC2A521CCD7776125A5DB2EE4A12B1DCFD797C47188CE5CB6859ACBB452F922F4FF7E2098CB090F83812A18D8DD9B7465B2572EED81332A84C1591F1BA1633B571423FE38BAA819B0AF2C30676B00EBD98D386FED880BB6D9FF4A05C206A8394E973350A597FC337260025BE097EB7409A182C500853B9C90A096708BB83A80F2EEF4EA23190B9CE095C92A1B675903B07149C34E9FFAF6908BCC27D495AFED5C652242B939F71690748895E93181C746CB6E94C2E58C97149F5F3FE3CE552F44AA859115AC5459C3CA343EAC5F98D076E661EE24E15F22FA81393F85E7D1B26FD4D6CC1DC7BFAC0E1C97438141A98D65EFD1592D4A1211DC089CEC0903DD7F333F55FFE70609FACDE7B7293036BAAB67E6DEE7FB82E16019AF642814BFF4AF6676446AE656ACD601812A86B8DB9A53A1EBB744ABDC7C88DBABE4AA023FC253B56B3B517DFE66156BE7DB0653B3DA80ACF010125D652C38DC91BBA2C247AD9F769A9C2F8FA16A0B0507CA632612F9AD03C5E281FFB3341A929E1EE9A946889AF525B348DE24362FABAE20E583D67B4624C96053960F4744BA71C1911D5A84B3615CC8F52E23C10C38E542B61969BD82257B2BE5B50EF63B5110D6D23B81D33176473020D363845C45BD03D2AEF81F2A87C1BADD4C1248A3004AE57562E38B0FB10124E23DFC0AB9257F5982748E39610A46A974459A2F30D852D560D45BAABEC8B8BE77F8AC9AC2424F69FBD9E23F226FD7FCBA827ACCC49E9EEDDF659ACA0E931B965401E416FB6969743B8CDEC4DEC49648D7C1B82B7B337AB496F9C5FD31BCFB6BC33
-20220414180857 2 6 100 6143 2 C008BA5D87ECC10B5E79F4C05438A7EAFA57C290A50C25A0DFD5FF2FF19F5D39568056AF4AA2FB56F1CEFB636A5E30D99379305FE9633EA9CF219FD87C501640F500E2AFAAF304B7EF862B6C4C8339B558E3B8F00AB714AD6460786AAE3B328D41806A94F270B4D1F13B958579F3C1A7ACB166FB2E5566ED4305AB36C357852B2ED67D4C877338D891E0FFBBDE512E976B754CA2BA1770D8CE7117D5CEB99715C99D97285F3744533CD9BE72A4FBE2CACD4796FA3EFCA27CCA1F7F96DC2A521CCD7776125A5DB2EE4A12B1DCFD797C47188CE5CB6859ACBB452F922F4FF7E2098CB090F83812A18D8DD9B7465B2572EED81332A84C1591F1BA1633B571423FE38BAA819B0AF2C30676B00EBD98D386FED880BB6D9FF4A05C206A8394E973350A597FC337260025BE097EB7409A182C500853B9C90A096708BB83A80F2EEF4EA23190B9CE095C92A1B675903B07149C34E9FFAF6908BCC27D495AFED5C652242B939F71690748895E93181C746CB6E94C2E58C97149F5F3FE3CE552F44AA859115AC5459C3CA343EAC5F98D076E661EE24E15F22FA81393F85E7D1B26FD4D6CC1DC7BFAC0E1C97438141A98D65EFD1592D4A1211DC089CEC0903DD7F333F55FFE70609FACDE7B7293036BAAB67E6DEE7FB82E16019AF642814BFF4AF6676446AE656ACD601812A86B8DB9A53A1EBB744ABDC7C88DBABE4AA023FC253B56B3B517DFE66156BE7DB0653B3DA80ACF010125D652C38DC91BBA2C247AD9F769A9C2F8FA16A0B0507CA632612F9AD03C5E281FFB3341A929E1EE9A946889AF525B348DE24362FABAE20E583D67B4624C96053960F4744BA71C1911D5A84B3615CC8F52E23C10C38E542B61969BD82257B2BE5B50EF63B5110D6D23B81D33176473020D363845C45BD03D2AEF81F2A87C1BADD4C1248A3004AE57562E38B0FB10124E23DFC0AB9257F5982748E39610A46A974459A2F30D852D560D45BAABEC8B8BE77F8AC9AC2424F69FBD9E23F226FD7FCBA827ACCC49E9EEDDF659ACA0E931B965401E416FB6969743B8CDEC4DEC49648D7C1B82B7B337AB496F9C5FD31BD09DEC93
-20220414183147 2 6 100 6143 2 C008BA5D87ECC10B5E79F4C05438A7EAFA57C290A50C25A0DFD5FF2FF19F5D39568056AF4AA2FB56F1CEFB636A5E30D99379305FE9633EA9CF219FD87C501640F500E2AFAAF304B7EF862B6C4C8339B558E3B8F00AB714AD6460786AAE3B328D41806A94F270B4D1F13B958579F3C1A7ACB166FB2E5566ED4305AB36C357852B2ED67D4C877338D891E0FFBBDE512E976B754CA2BA1770D8CE7117D5CEB99715C99D97285F3744533CD9BE72A4FBE2CACD4796FA3EFCA27CCA1F7F96DC2A521CCD7776125A5DB2EE4A12B1DCFD797C47188CE5CB6859ACBB452F922F4FF7E2098CB090F83812A18D8DD9B7465B2572EED81332A84C1591F1BA1633B571423FE38BAA819B0AF2C30676B00EBD98D386FED880BB6D9FF4A05C206A8394E973350A597FC337260025BE097EB7409A182C500853B9C90A096708BB83A80F2EEF4EA23190B9CE095C92A1B675903B07149C34E9FFAF6908BCC27D495AFED5C652242B939F71690748895E93181C746CB6E94C2E58C97149F5F3FE3CE552F44AA859115AC5459C3CA343EAC5F98D076E661EE24E15F22FA81393F85E7D1B26FD4D6CC1DC7BFAC0E1C97438141A98D65EFD1592D4A1211DC089CEC0903DD7F333F55FFE70609FACDE7B7293036BAAB67E6DEE7FB82E16019AF642814BFF4AF6676446AE656ACD601812A86B8DB9A53A1EBB744ABDC7C88DBABE4AA023FC253B56B3B517DFE66156BE7DB0653B3DA80ACF010125D652C38DC91BBA2C247AD9F769A9C2F8FA16A0B0507CA632612F9AD03C5E281FFB3341A929E1EE9A946889AF525B348DE24362FABAE20E583D67B4624C96053960F4744BA71C1911D5A84B3615CC8F52E23C10C38E542B61969BD82257B2BE5B50EF63B5110D6D23B81D33176473020D363845C45BD03D2AEF81F2A87C1BADD4C1248A3004AE57562E38B0FB10124E23DFC0AB9257F5982748E39610A46A974459A2F30D852D560D45BAABEC8B8BE77F8AC9AC2424F69FBD9E23F226FD7FCBA827ACCC49E9EEDDF659ACA0E931B965401E416FB6969743B8CDEC4DEC49648D7C1B82B7B337AB496F9C5FD31BD3C3862B
-20220414183832 2 6 100 6143 5 C008BA5D87ECC10B5E79F4C05438A7EAFA57C290A50C25A0DFD5FF2FF19F5D39568056AF4AA2FB56F1CEFB636A5E30D99379305FE9633EA9CF219FD87C501640F500E2AFAAF304B7EF862B6C4C8339B558E3B8F00AB714AD6460786AAE3B328D41806A94F270B4D1F13B958579F3C1A7ACB166FB2E5566ED4305AB36C357852B2ED67D4C877338D891E0FFBBDE512E976B754CA2BA1770D8CE7117D5CEB99715C99D97285F3744533CD9BE72A4FBE2CACD4796FA3EFCA27CCA1F7F96DC2A521CCD7776125A5DB2EE4A12B1DCFD797C47188CE5CB6859ACBB452F922F4FF7E2098CB090F83812A18D8DD9B7465B2572EED81332A84C1591F1BA1633B571423FE38BAA819B0AF2C30676B00EBD98D386FED880BB6D9FF4A05C206A8394E973350A597FC337260025BE097EB7409A182C500853B9C90A096708BB83A80F2EEF4EA23190B9CE095C92A1B675903B07149C34E9FFAF6908BCC27D495AFED5C652242B939F71690748895E93181C746CB6E94C2E58C97149F5F3FE3CE552F44AA859115AC5459C3CA343EAC5F98D076E661EE24E15F22FA81393F85E7D1B26FD4D6CC1DC7BFAC0E1C97438141A98D65EFD1592D4A1211DC089CEC0903DD7F333F55FFE70609FACDE7B7293036BAAB67E6DEE7FB82E16019AF642814BFF4AF6676446AE656ACD601812A86B8DB9A53A1EBB744ABDC7C88DBABE4AA023FC253B56B3B517DFE66156BE7DB0653B3DA80ACF010125D652C38DC91BBA2C247AD9F769A9C2F8FA16A0B0507CA632612F9AD03C5E281FFB3341A929E1EE9A946889AF525B348DE24362FABAE20E583D67B4624C96053960F4744BA71C1911D5A84B3615CC8F52E23C10C38E542B61969BD82257B2BE5B50EF63B5110D6D23B81D33176473020D363845C45BD03D2AEF81F2A87C1BADD4C1248A3004AE57562E38B0FB10124E23DFC0AB9257F5982748E39610A46A974459A2F30D852D560D45BAABEC8B8BE77F8AC9AC2424F69FBD9E23F226FD7FCBA827ACCC49E9EEDDF659ACA0E931B965401E416FB6969743B8CDEC4DEC49648D7C1B82B7B337AB496F9C5FD31BD4AAE607
-20220414184336 2 6 100 6143 5 C008BA5D87ECC10B5E79F4C05438A7EAFA57C290A50C25A0DFD5FF2FF19F5D39568056AF4AA2FB56F1CEFB636A5E30D99379305FE9633EA9CF219FD87C501640F500E2AFAAF304B7EF862B6C4C8339B558E3B8F00AB714AD6460786AAE3B328D41806A94F270B4D1F13B958579F3C1A7ACB166FB2E5566ED4305AB36C357852B2ED67D4C877338D891E0FFBBDE512E976B754CA2BA1770D8CE7117D5CEB99715C99D97285F3744533CD9BE72A4FBE2CACD4796FA3EFCA27CCA1F7F96DC2A521CCD7776125A5DB2EE4A12B1DCFD797C47188CE5CB6859ACBB452F922F4FF7E2098CB090F83812A18D8DD9B7465B2572EED81332A84C1591F1BA1633B571423FE38BAA819B0AF2C30676B00EBD98D386FED880BB6D9FF4A05C206A8394E973350A597FC337260025BE097EB7409A182C500853B9C90A096708BB83A80F2EEF4EA23190B9CE095C92A1B675903B07149C34E9FFAF6908BCC27D495AFED5C652242B939F71690748895E93181C746CB6E94C2E58C97149F5F3FE3CE552F44AA859115AC5459C3CA343EAC5F98D076E661EE24E15F22FA81393F85E7D1B26FD4D6CC1DC7BFAC0E1C97438141A98D65EFD1592D4A1211DC089CEC0903DD7F333F55FFE70609FACDE7B7293036BAAB67E6DEE7FB82E16019AF642814BFF4AF6676446AE656ACD601812A86B8DB9A53A1EBB744ABDC7C88DBABE4AA023FC253B56B3B517DFE66156BE7DB0653B3DA80ACF010125D652C38DC91BBA2C247AD9F769A9C2F8FA16A0B0507CA632612F9AD03C5E281FFB3341A929E1EE9A946889AF525B348DE24362FABAE20E583D67B4624C96053960F4744BA71C1911D5A84B3615CC8F52E23C10C38E542B61969BD82257B2BE5B50EF63B5110D6D23B81D33176473020D363845C45BD03D2AEF81F2A87C1BADD4C1248A3004AE57562E38B0FB10124E23DFC0AB9257F5982748E39610A46A974459A2F30D852D560D45BAABEC8B8BE77F8AC9AC2424F69FBD9E23F226FD7FCBA827ACCC49E9EEDDF659ACA0E931B965401E416FB6969743B8CDEC4DEC49648D7C1B82B7B337AB496F9C5FD31BD559A367
-20220414184426 2 6 100 6143 2 C008BA5D87ECC10B5E79F4C05438A7EAFA57C290A50C25A0DFD5FF2FF19F5D39568056AF4AA2FB56F1CEFB636A5E30D99379305FE9633EA9CF219FD87C501640F500E2AFAAF304B7EF862B6C4C8339B558E3B8F00AB714AD6460786AAE3B328D41806A94F270B4D1F13B958579F3C1A7ACB166FB2E5566ED4305AB36C357852B2ED67D4C877338D891E0FFBBDE512E976B754CA2BA1770D8CE7117D5CEB99715C99D97285F3744533CD9BE72A4FBE2CACD4796FA3EFCA27CCA1F7F96DC2A521CCD7776125A5DB2EE4A12B1DCFD797C47188CE5CB6859ACBB452F922F4FF7E2098CB090F83812A18D8DD9B7465B2572EED81332A84C1591F1BA1633B571423FE38BAA819B0AF2C30676B00EBD98D386FED880BB6D9FF4A05C206A8394E973350A597FC337260025BE097EB7409A182C500853B9C90A096708BB83A80F2EEF4EA23190B9CE095C92A1B675903B07149C34E9FFAF6908BCC27D495AFED5C652242B939F71690748895E93181C746CB6E94C2E58C97149F5F3FE3CE552F44AA859115AC5459C3CA343EAC5F98D076E661EE24E15F22FA81393F85E7D1B26FD4D6CC1DC7BFAC0E1C97438141A98D65EFD1592D4A1211DC089CEC0903DD7F333F55FFE70609FACDE7B7293036BAAB67E6DEE7FB82E16019AF642814BFF4AF6676446AE656ACD601812A86B8DB9A53A1EBB744ABDC7C88DBABE4AA023FC253B56B3B517DFE66156BE7DB0653B3DA80ACF010125D652C38DC91BBA2C247AD9F769A9C2F8FA16A0B0507CA632612F9AD03C5E281FFB3341A929E1EE9A946889AF525B348DE24362FABAE20E583D67B4624C96053960F4744BA71C1911D5A84B3615CC8F52E23C10C38E542B61969BD82257B2BE5B50EF63B5110D6D23B81D33176473020D363845C45BD03D2AEF81F2A87C1BADD4C1248A3004AE57562E38B0FB10124E23DFC0AB9257F5982748E39610A46A974459A2F30D852D560D45BAABEC8B8BE77F8AC9AC2424F69FBD9E23F226FD7FCBA827ACCC49E9EEDDF659ACA0E931B965401E416FB6969743B8CDEC4DEC49648D7C1B82B7B337AB496F9C5FD31BD56C4CAB
-20220414185501 2 6 100 6143 5 C008BA5D87ECC10B5E79F4C05438A7EAFA57C290A50C25A0DFD5FF2FF19F5D39568056AF4AA2FB56F1CEFB636A5E30D99379305FE9633EA9CF219FD87C501640F500E2AFAAF304B7EF862B6C4C8339B558E3B8F00AB714AD6460786AAE3B328D41806A94F270B4D1F13B958579F3C1A7ACB166FB2E5566ED4305AB36C357852B2ED67D4C877338D891E0FFBBDE512E976B754CA2BA1770D8CE7117D5CEB99715C99D97285F3744533CD9BE72A4FBE2CACD4796FA3EFCA27CCA1F7F96DC2A521CCD7776125A5DB2EE4A12B1DCFD797C47188CE5CB6859ACBB452F922F4FF7E2098CB090F83812A18D8DD9B7465B2572EED81332A84C1591F1BA1633B571423FE38BAA819B0AF2C30676B00EBD98D386FED880BB6D9FF4A05C206A8394E973350A597FC337260025BE097EB7409A182C500853B9C90A096708BB83A80F2EEF4EA23190B9CE095C92A1B675903B07149C34E9FFAF6908BCC27D495AFED5C652242B939F71690748895E93181C746CB6E94C2E58C97149F5F3FE3CE552F44AA859115AC5459C3CA343EAC5F98D076E661EE24E15F22FA81393F85E7D1B26FD4D6CC1DC7BFAC0E1C97438141A98D65EFD1592D4A1211DC089CEC0903DD7F333F55FFE70609FACDE7B7293036BAAB67E6DEE7FB82E16019AF642814BFF4AF6676446AE656ACD601812A86B8DB9A53A1EBB744ABDC7C88DBABE4AA023FC253B56B3B517DFE66156BE7DB0653B3DA80ACF010125D652C38DC91BBA2C247AD9F769A9C2F8FA16A0B0507CA632612F9AD03C5E281FFB3341A929E1EE9A946889AF525B348DE24362FABAE20E583D67B4624C96053960F4744BA71C1911D5A84B3615CC8F52E23C10C38E542B61969BD82257B2BE5B50EF63B5110D6D23B81D33176473020D363845C45BD03D2AEF81F2A87C1BADD4C1248A3004AE57562E38B0FB10124E23DFC0AB9257F5982748E39610A46A974459A2F30D852D560D45BAABEC8B8BE77F8AC9AC2424F69FBD9E23F226FD7FCBA827ACCC49E9EEDDF659ACA0E931B965401E416FB6969743B8CDEC4DEC49648D7C1B82B7B337AB496F9C5FD31BD6D7EA1F
-20220414185956 2 6 100 6143 2 C008BA5D87ECC10B5E79F4C05438A7EAFA57C290A50C25A0DFD5FF2FF19F5D39568056AF4AA2FB56F1CEFB636A5E30D99379305FE9633EA9CF219FD87C501640F500E2AFAAF304B7EF862B6C4C8339B558E3B8F00AB714AD6460786AAE3B328D41806A94F270B4D1F13B958579F3C1A7ACB166FB2E5566ED4305AB36C357852B2ED67D4C877338D891E0FFBBDE512E976B754CA2BA1770D8CE7117D5CEB99715C99D97285F3744533CD9BE72A4FBE2CACD4796FA3EFCA27CCA1F7F96DC2A521CCD7776125A5DB2EE4A12B1DCFD797C47188CE5CB6859ACBB452F922F4FF7E2098CB090F83812A18D8DD9B7465B2572EED81332A84C1591F1BA1633B571423FE38BAA819B0AF2C30676B00EBD98D386FED880BB6D9FF4A05C206A8394E973350A597FC337260025BE097EB7409A182C500853B9C90A096708BB83A80F2EEF4EA23190B9CE095C92A1B675903B07149C34E9FFAF6908BCC27D495AFED5C652242B939F71690748895E93181C746CB6E94C2E58C97149F5F3FE3CE552F44AA859115AC5459C3CA343EAC5F98D076E661EE24E15F22FA81393F85E7D1B26FD4D6CC1DC7BFAC0E1C97438141A98D65EFD1592D4A1211DC089CEC0903DD7F333F55FFE70609FACDE7B7293036BAAB67E6DEE7FB82E16019AF642814BFF4AF6676446AE656ACD601812A86B8DB9A53A1EBB744ABDC7C88DBABE4AA023FC253B56B3B517DFE66156BE7DB0653B3DA80ACF010125D652C38DC91BBA2C247AD9F769A9C2F8FA16A0B0507CA632612F9AD03C5E281FFB3341A929E1EE9A946889AF525B348DE24362FABAE20E583D67B4624C96053960F4744BA71C1911D5A84B3615CC8F52E23C10C38E542B61969BD82257B2BE5B50EF63B5110D6D23B81D33176473020D363845C45BD03D2AEF81F2A87C1BADD4C1248A3004AE57562E38B0FB10124E23DFC0AB9257F5982748E39610A46A974459A2F30D852D560D45BAABEC8B8BE77F8AC9AC2424F69FBD9E23F226FD7FCBA827ACCC49E9EEDDF659ACA0E931B965401E416FB6969743B8CDEC4DEC49648D7C1B82B7B337AB496F9C5FD31BD77C34DB
-20220414192107 2 6 100 6143 2 C008BA5D87ECC10B5E79F4C05438A7EAFA57C290A50C25A0DFD5FF2FF19F5D39568056AF4AA2FB56F1CEFB636A5E30D99379305FE9633EA9CF219FD87C501640F500E2AFAAF304B7EF862B6C4C8339B558E3B8F00AB714AD6460786AAE3B328D41806A94F270B4D1F13B958579F3C1A7ACB166FB2E5566ED4305AB36C357852B2ED67D4C877338D891E0FFBBDE512E976B754CA2BA1770D8CE7117D5CEB99715C99D97285F3744533CD9BE72A4FBE2CACD4796FA3EFCA27CCA1F7F96DC2A521CCD7776125A5DB2EE4A12B1DCFD797C47188CE5CB6859ACBB452F922F4FF7E2098CB090F83812A18D8DD9B7465B2572EED81332A84C1591F1BA1633B571423FE38BAA819B0AF2C30676B00EBD98D386FED880BB6D9FF4A05C206A8394E973350A597FC337260025BE097EB7409A182C500853B9C90A096708BB83A80F2EEF4EA23190B9CE095C92A1B675903B07149C34E9FFAF6908BCC27D495AFED5C652242B939F71690748895E93181C746CB6E94C2E58C97149F5F3FE3CE552F44AA859115AC5459C3CA343EAC5F98D076E661EE24E15F22FA81393F85E7D1B26FD4D6CC1DC7BFAC0E1C97438141A98D65EFD1592D4A1211DC089CEC0903DD7F333F55FFE70609FACDE7B7293036BAAB67E6DEE7FB82E16019AF642814BFF4AF6676446AE656ACD601812A86B8DB9A53A1EBB744ABDC7C88DBABE4AA023FC253B56B3B517DFE66156BE7DB0653B3DA80ACF010125D652C38DC91BBA2C247AD9F769A9C2F8FA16A0B0507CA632612F9AD03C5E281FFB3341A929E1EE9A946889AF525B348DE24362FABAE20E583D67B4624C96053960F4744BA71C1911D5A84B3615CC8F52E23C10C38E542B61969BD82257B2BE5B50EF63B5110D6D23B81D33176473020D363845C45BD03D2AEF81F2A87C1BADD4C1248A3004AE57562E38B0FB10124E23DFC0AB9257F5982748E39610A46A974459A2F30D852D560D45BAABEC8B8BE77F8AC9AC2424F69FBD9E23F226FD7FCBA827ACCC49E9EEDDF659ACA0E931B965401E416FB6969743B8CDEC4DEC49648D7C1B82B7B337AB496F9C5FD31BDA56DD2B
-20220414194147 2 6 100 6143 5 C008BA5D87ECC10B5E79F4C05438A7EAFA57C290A50C25A0DFD5FF2FF19F5D39568056AF4AA2FB56F1CEFB636A5E30D99379305FE9633EA9CF219FD87C501640F500E2AFAAF304B7EF862B6C4C8339B558E3B8F00AB714AD6460786AAE3B328D41806A94F270B4D1F13B958579F3C1A7ACB166FB2E5566ED4305AB36C357852B2ED67D4C877338D891E0FFBBDE512E976B754CA2BA1770D8CE7117D5CEB99715C99D97285F3744533CD9BE72A4FBE2CACD4796FA3EFCA27CCA1F7F96DC2A521CCD7776125A5DB2EE4A12B1DCFD797C47188CE5CB6859ACBB452F922F4FF7E2098CB090F83812A18D8DD9B7465B2572EED81332A84C1591F1BA1633B571423FE38BAA819B0AF2C30676B00EBD98D386FED880BB6D9FF4A05C206A8394E973350A597FC337260025BE097EB7409A182C500853B9C90A096708BB83A80F2EEF4EA23190B9CE095C92A1B675903B07149C34E9FFAF6908BCC27D495AFED5C652242B939F71690748895E93181C746CB6E94C2E58C97149F5F3FE3CE552F44AA859115AC5459C3CA343EAC5F98D076E661EE24E15F22FA81393F85E7D1B26FD4D6CC1DC7BFAC0E1C97438141A98D65EFD1592D4A1211DC089CEC0903DD7F333F55FFE70609FACDE7B7293036BAAB67E6DEE7FB82E16019AF642814BFF4AF6676446AE656ACD601812A86B8DB9A53A1EBB744ABDC7C88DBABE4AA023FC253B56B3B517DFE66156BE7DB0653B3DA80ACF010125D652C38DC91BBA2C247AD9F769A9C2F8FA16A0B0507CA632612F9AD03C5E281FFB3341A929E1EE9A946889AF525B348DE24362FABAE20E583D67B4624C96053960F4744BA71C1911D5A84B3615CC8F52E23C10C38E542B61969BD82257B2BE5B50EF63B5110D6D23B81D33176473020D363845C45BD03D2AEF81F2A87C1BADD4C1248A3004AE57562E38B0FB10124E23DFC0AB9257F5982748E39610A46A974459A2F30D852D560D45BAABEC8B8BE77F8AC9AC2424F69FBD9E23F226FD7FCBA827ACCC49E9EEDDF659ACA0E931B965401E416FB6969743B8CDEC4DEC49648D7C1B82B7B337AB496F9C5FD31BDD2AA5D7
-20220414200557 2 6 100 6143 5 ECFEBE907ED5229E0F2A017AAC2F662065526E4CD6767D11B9BC47C5C4D0E39E232885C9039387645B0C61FC91A5B5F97A3A3264DC42DD48A30C3E923D467D8CDDD98F0DE77067BFB45F466CA03EC5B86BF836D9C6298948D315FF4627FE23F62CE3E722A3B60F7D9D6F97D4B10E30924ABF0E094D5155F57DFBD93B17A3E958816225D458E063A4785F4D04A131D6C3AEFF9B405648DC2E0A64F061AB428E6C3B69C65266514A729829756E016CF55D1A917D9CE64ECEA6EB081A85F177BDEED9062CA130A23BB3D90817644F84890C55BB158DA2C0F590826B7073E933EC081268331D56BFB282D4DA250EC39EF3E477BAC8E5B64B712F4457C5B116D0D491AC7AF0E68F3337A51AADA71152604FF386C9CCB4F67204F6A2FBDBE18E5AF591DDA0B5A93382BC210A549262C0A250EF2CB3D3009C4EA412324E359DBEFF97ADA37287D08C11ED12B170B06B8055BC5B17B3F464BFDE141A145A6393750FE9D5EF33C33A43B575091076A24A9E67C56C7B41F023C42166C89E57D001E9161E924A693FD3712355AD60EAC3BD8AC16BA15F5BEABEE3D014B7F5361D7EB36B3F594E1BB98F6813A2D88FD6FC9F008713334AE962B0CB4C07FDB32D549C0F24D127486707C29A7F5EC7F8601961D2E4C189BA3129E48D0D2215E70D9115AAD993E78565715E50EA0E336EA456D469A23368CFB3F0ED6B8AC77738B2A2AC0A7F155CF6D402687212585A2DD9EEAAF614387C7C8D3089D3F42DBD1A594233ABB618AAD84D52F8A234281F2B0F62E3FE23B1E7F28DD89F6F79572506F9B02021CE44914237C190C82F1E5CB395844550EF279E9B50FA1D5B7AE84FE9F31538546244BD4C86FDADB5974396692A7BBE7AD493834DD13418929F8EA0F44BBF8E3D9DFCEF170DF138351932FA05468DE9A922953DF5AB791406E89F752A378A0D98A957773EC3B952DAE04200C1944F30B43D80450F8F83AC4F688D806DE9C9C406D30FC0D9098BE612EF0C4AD2E80B2C746944C727A1015538A53C69280EE0F00D6601CAA6CB0EAF4D3DADBF849D4C1F8F1FD7D438619C70364DACE440858687646A1E9F
-20220414201020 2 6 100 6143 5 ECFEBE907ED5229E0F2A017AAC2F662065526E4CD6767D11B9BC47C5C4D0E39E232885C9039387645B0C61FC91A5B5F97A3A3264DC42DD48A30C3E923D467D8CDDD98F0DE77067BFB45F466CA03EC5B86BF836D9C6298948D315FF4627FE23F62CE3E722A3B60F7D9D6F97D4B10E30924ABF0E094D5155F57DFBD93B17A3E958816225D458E063A4785F4D04A131D6C3AEFF9B405648DC2E0A64F061AB428E6C3B69C65266514A729829756E016CF55D1A917D9CE64ECEA6EB081A85F177BDEED9062CA130A23BB3D90817644F84890C55BB158DA2C0F590826B7073E933EC081268331D56BFB282D4DA250EC39EF3E477BAC8E5B64B712F4457C5B116D0D491AC7AF0E68F3337A51AADA71152604FF386C9CCB4F67204F6A2FBDBE18E5AF591DDA0B5A93382BC210A549262C0A250EF2CB3D3009C4EA412324E359DBEFF97ADA37287D08C11ED12B170B06B8055BC5B17B3F464BFDE141A145A6393750FE9D5EF33C33A43B575091076A24A9E67C56C7B41F023C42166C89E57D001E9161E924A693FD3712355AD60EAC3BD8AC16BA15F5BEABEE3D014B7F5361D7EB36B3F594E1BB98F6813A2D88FD6FC9F008713334AE962B0CB4C07FDB32D549C0F24D127486707C29A7F5EC7F8601961D2E4C189BA3129E48D0D2215E70D9115AAD993E78565715E50EA0E336EA456D469A23368CFB3F0ED6B8AC77738B2A2AC0A7F155CF6D402687212585A2DD9EEAAF614387C7C8D3089D3F42DBD1A594233ABB618AAD84D52F8A234281F2B0F62E3FE23B1E7F28DD89F6F79572506F9B02021CE44914237C190C82F1E5CB395844550EF279E9B50FA1D5B7AE84FE9F31538546244BD4C86FDADB5974396692A7BBE7AD493834DD13418929F8EA0F44BBF8E3D9DFCEF170DF138351932FA05468DE9A922953DF5AB791406E89F752A378A0D98A957773EC3B952DAE04200C1944F30B43D80450F8F83AC4F688D806DE9C9C406D30FC0D9098BE612EF0C4AD2E80B2C746944C727A1015538A53C69280EE0F00D6601CAA6CB0EAF4D3DADBF849D4C1F8F1FD7D438619C70364DACE44085868765073AC7
-20220414201829 2 6 100 6143 2 ECFEBE907ED5229E0F2A017AAC2F662065526E4CD6767D11B9BC47C5C4D0E39E232885C9039387645B0C61FC91A5B5F97A3A3264DC42DD48A30C3E923D467D8CDDD98F0DE77067BFB45F466CA03EC5B86BF836D9C6298948D315FF4627FE23F62CE3E722A3B60F7D9D6F97D4B10E30924ABF0E094D5155F57DFBD93B17A3E958816225D458E063A4785F4D04A131D6C3AEFF9B405648DC2E0A64F061AB428E6C3B69C65266514A729829756E016CF55D1A917D9CE64ECEA6EB081A85F177BDEED9062CA130A23BB3D90817644F84890C55BB158DA2C0F590826B7073E933EC081268331D56BFB282D4DA250EC39EF3E477BAC8E5B64B712F4457C5B116D0D491AC7AF0E68F3337A51AADA71152604FF386C9CCB4F67204F6A2FBDBE18E5AF591DDA0B5A93382BC210A549262C0A250EF2CB3D3009C4EA412324E359DBEFF97ADA37287D08C11ED12B170B06B8055BC5B17B3F464BFDE141A145A6393750FE9D5EF33C33A43B575091076A24A9E67C56C7B41F023C42166C89E57D001E9161E924A693FD3712355AD60EAC3BD8AC16BA15F5BEABEE3D014B7F5361D7EB36B3F594E1BB98F6813A2D88FD6FC9F008713334AE962B0CB4C07FDB32D549C0F24D127486707C29A7F5EC7F8601961D2E4C189BA3129E48D0D2215E70D9115AAD993E78565715E50EA0E336EA456D469A23368CFB3F0ED6B8AC77738B2A2AC0A7F155CF6D402687212585A2DD9EEAAF614387C7C8D3089D3F42DBD1A594233ABB618AAD84D52F8A234281F2B0F62E3FE23B1E7F28DD89F6F79572506F9B02021CE44914237C190C82F1E5CB395844550EF279E9B50FA1D5B7AE84FE9F31538546244BD4C86FDADB5974396692A7BBE7AD493834DD13418929F8EA0F44BBF8E3D9DFCEF170DF138351932FA05468DE9A922953DF5AB791406E89F752A378A0D98A957773EC3B952DAE04200C1944F30B43D80450F8F83AC4F688D806DE9C9C406D30FC0D9098BE612EF0C4AD2E80B2C746944C727A1015538A53C69280EE0F00D6601CAA6CB0EAF4D3DADBF849D4C1F8F1FD7D438619C70364DACE440858687663CEA53
-20220414203003 2 6 100 6143 5 ECFEBE907ED5229E0F2A017AAC2F662065526E4CD6767D11B9BC47C5C4D0E39E232885C9039387645B0C61FC91A5B5F97A3A3264DC42DD48A30C3E923D467D8CDDD98F0DE77067BFB45F466CA03EC5B86BF836D9C6298948D315FF4627FE23F62CE3E722A3B60F7D9D6F97D4B10E30924ABF0E094D5155F57DFBD93B17A3E958816225D458E063A4785F4D04A131D6C3AEFF9B405648DC2E0A64F061AB428E6C3B69C65266514A729829756E016CF55D1A917D9CE64ECEA6EB081A85F177BDEED9062CA130A23BB3D90817644F84890C55BB158DA2C0F590826B7073E933EC081268331D56BFB282D4DA250EC39EF3E477BAC8E5B64B712F4457C5B116D0D491AC7AF0E68F3337A51AADA71152604FF386C9CCB4F67204F6A2FBDBE18E5AF591DDA0B5A93382BC210A549262C0A250EF2CB3D3009C4EA412324E359DBEFF97ADA37287D08C11ED12B170B06B8055BC5B17B3F464BFDE141A145A6393750FE9D5EF33C33A43B575091076A24A9E67C56C7B41F023C42166C89E57D001E9161E924A693FD3712355AD60EAC3BD8AC16BA15F5BEABEE3D014B7F5361D7EB36B3F594E1BB98F6813A2D88FD6FC9F008713334AE962B0CB4C07FDB32D549C0F24D127486707C29A7F5EC7F8601961D2E4C189BA3129E48D0D2215E70D9115AAD993E78565715E50EA0E336EA456D469A23368CFB3F0ED6B8AC77738B2A2AC0A7F155CF6D402687212585A2DD9EEAAF614387C7C8D3089D3F42DBD1A594233ABB618AAD84D52F8A234281F2B0F62E3FE23B1E7F28DD89F6F79572506F9B02021CE44914237C190C82F1E5CB395844550EF279E9B50FA1D5B7AE84FE9F31538546244BD4C86FDADB5974396692A7BBE7AD493834DD13418929F8EA0F44BBF8E3D9DFCEF170DF138351932FA05468DE9A922953DF5AB791406E89F752A378A0D98A957773EC3B952DAE04200C1944F30B43D80450F8F83AC4F688D806DE9C9C406D30FC0D9098BE612EF0C4AD2E80B2C746944C727A1015538A53C69280EE0F00D6601CAA6CB0EAF4D3DADBF849D4C1F8F1FD7D438619C70364DACE44085868767F30C97
-20220414203735 2 6 100 6143 2 ECFEBE907ED5229E0F2A017AAC2F662065526E4CD6767D11B9BC47C5C4D0E39E232885C9039387645B0C61FC91A5B5F97A3A3264DC42DD48A30C3E923D467D8CDDD98F0DE77067BFB45F466CA03EC5B86BF836D9C6298948D315FF4627FE23F62CE3E722A3B60F7D9D6F97D4B10E30924ABF0E094D5155F57DFBD93B17A3E958816225D458E063A4785F4D04A131D6C3AEFF9B405648DC2E0A64F061AB428E6C3B69C65266514A729829756E016CF55D1A917D9CE64ECEA6EB081A85F177BDEED9062CA130A23BB3D90817644F84890C55BB158DA2C0F590826B7073E933EC081268331D56BFB282D4DA250EC39EF3E477BAC8E5B64B712F4457C5B116D0D491AC7AF0E68F3337A51AADA71152604FF386C9CCB4F67204F6A2FBDBE18E5AF591DDA0B5A93382BC210A549262C0A250EF2CB3D3009C4EA412324E359DBEFF97ADA37287D08C11ED12B170B06B8055BC5B17B3F464BFDE141A145A6393750FE9D5EF33C33A43B575091076A24A9E67C56C7B41F023C42166C89E57D001E9161E924A693FD3712355AD60EAC3BD8AC16BA15F5BEABEE3D014B7F5361D7EB36B3F594E1BB98F6813A2D88FD6FC9F008713334AE962B0CB4C07FDB32D549C0F24D127486707C29A7F5EC7F8601961D2E4C189BA3129E48D0D2215E70D9115AAD993E78565715E50EA0E336EA456D469A23368CFB3F0ED6B8AC77738B2A2AC0A7F155CF6D402687212585A2DD9EEAAF614387C7C8D3089D3F42DBD1A594233ABB618AAD84D52F8A234281F2B0F62E3FE23B1E7F28DD89F6F79572506F9B02021CE44914237C190C82F1E5CB395844550EF279E9B50FA1D5B7AE84FE9F31538546244BD4C86FDADB5974396692A7BBE7AD493834DD13418929F8EA0F44BBF8E3D9DFCEF170DF138351932FA05468DE9A922953DF5AB791406E89F752A378A0D98A957773EC3B952DAE04200C1944F30B43D80450F8F83AC4F688D806DE9C9C406D30FC0D9098BE612EF0C4AD2E80B2C746944C727A1015538A53C69280EE0F00D6601CAA6CB0EAF4D3DADBF849D4C1F8F1FD7D438619C70364DACE44085868769010163
-20220414204108 2 6 100 6143 2 ECFEBE907ED5229E0F2A017AAC2F662065526E4CD6767D11B9BC47C5C4D0E39E232885C9039387645B0C61FC91A5B5F97A3A3264DC42DD48A30C3E923D467D8CDDD98F0DE77067BFB45F466CA03EC5B86BF836D9C6298948D315FF4627FE23F62CE3E722A3B60F7D9D6F97D4B10E30924ABF0E094D5155F57DFBD93B17A3E958816225D458E063A4785F4D04A131D6C3AEFF9B405648DC2E0A64F061AB428E6C3B69C65266514A729829756E016CF55D1A917D9CE64ECEA6EB081A85F177BDEED9062CA130A23BB3D90817644F84890C55BB158DA2C0F590826B7073E933EC081268331D56BFB282D4DA250EC39EF3E477BAC8E5B64B712F4457C5B116D0D491AC7AF0E68F3337A51AADA71152604FF386C9CCB4F67204F6A2FBDBE18E5AF591DDA0B5A93382BC210A549262C0A250EF2CB3D3009C4EA412324E359DBEFF97ADA37287D08C11ED12B170B06B8055BC5B17B3F464BFDE141A145A6393750FE9D5EF33C33A43B575091076A24A9E67C56C7B41F023C42166C89E57D001E9161E924A693FD3712355AD60EAC3BD8AC16BA15F5BEABEE3D014B7F5361D7EB36B3F594E1BB98F6813A2D88FD6FC9F008713334AE962B0CB4C07FDB32D549C0F24D127486707C29A7F5EC7F8601961D2E4C189BA3129E48D0D2215E70D9115AAD993E78565715E50EA0E336EA456D469A23368CFB3F0ED6B8AC77738B2A2AC0A7F155CF6D402687212585A2DD9EEAAF614387C7C8D3089D3F42DBD1A594233ABB618AAD84D52F8A234281F2B0F62E3FE23B1E7F28DD89F6F79572506F9B02021CE44914237C190C82F1E5CB395844550EF279E9B50FA1D5B7AE84FE9F31538546244BD4C86FDADB5974396692A7BBE7AD493834DD13418929F8EA0F44BBF8E3D9DFCEF170DF138351932FA05468DE9A922953DF5AB791406E89F752A378A0D98A957773EC3B952DAE04200C1944F30B43D80450F8F83AC4F688D806DE9C9C406D30FC0D9098BE612EF0C4AD2E80B2C746944C727A1015538A53C69280EE0F00D6601CAA6CB0EAF4D3DADBF849D4C1F8F1FD7D438619C70364DACE440858687697DB9D3
-20220414204650 2 6 100 6143 2 ECFEBE907ED5229E0F2A017AAC2F662065526E4CD6767D11B9BC47C5C4D0E39E232885C9039387645B0C61FC91A5B5F97A3A3264DC42DD48A30C3E923D467D8CDDD98F0DE77067BFB45F466CA03EC5B86BF836D9C6298948D315FF4627FE23F62CE3E722A3B60F7D9D6F97D4B10E30924ABF0E094D5155F57DFBD93B17A3E958816225D458E063A4785F4D04A131D6C3AEFF9B405648DC2E0A64F061AB428E6C3B69C65266514A729829756E016CF55D1A917D9CE64ECEA6EB081A85F177BDEED9062CA130A23BB3D90817644F84890C55BB158DA2C0F590826B7073E933EC081268331D56BFB282D4DA250EC39EF3E477BAC8E5B64B712F4457C5B116D0D491AC7AF0E68F3337A51AADA71152604FF386C9CCB4F67204F6A2FBDBE18E5AF591DDA0B5A93382BC210A549262C0A250EF2CB3D3009C4EA412324E359DBEFF97ADA37287D08C11ED12B170B06B8055BC5B17B3F464BFDE141A145A6393750FE9D5EF33C33A43B575091076A24A9E67C56C7B41F023C42166C89E57D001E9161E924A693FD3712355AD60EAC3BD8AC16BA15F5BEABEE3D014B7F5361D7EB36B3F594E1BB98F6813A2D88FD6FC9F008713334AE962B0CB4C07FDB32D549C0F24D127486707C29A7F5EC7F8601961D2E4C189BA3129E48D0D2215E70D9115AAD993E78565715E50EA0E336EA456D469A23368CFB3F0ED6B8AC77738B2A2AC0A7F155CF6D402687212585A2DD9EEAAF614387C7C8D3089D3F42DBD1A594233ABB618AAD84D52F8A234281F2B0F62E3FE23B1E7F28DD89F6F79572506F9B02021CE44914237C190C82F1E5CB395844550EF279E9B50FA1D5B7AE84FE9F31538546244BD4C86FDADB5974396692A7BBE7AD493834DD13418929F8EA0F44BBF8E3D9DFCEF170DF138351932FA05468DE9A922953DF5AB791406E89F752A378A0D98A957773EC3B952DAE04200C1944F30B43D80450F8F83AC4F688D806DE9C9C406D30FC0D9098BE612EF0C4AD2E80B2C746944C727A1015538A53C69280EE0F00D6601CAA6CB0EAF4D3DADBF849D4C1F8F1FD7D438619C70364DACE4408586876A4AA523
-20220414210821 2 6 100 6143 2 ECFEBE907ED5229E0F2A017AAC2F662065526E4CD6767D11B9BC47C5C4D0E39E232885C9039387645B0C61FC91A5B5F97A3A3264DC42DD48A30C3E923D467D8CDDD98F0DE77067BFB45F466CA03EC5B86BF836D9C6298948D315FF4627FE23F62CE3E722A3B60F7D9D6F97D4B10E30924ABF0E094D5155F57DFBD93B17A3E958816225D458E063A4785F4D04A131D6C3AEFF9B405648DC2E0A64F061AB428E6C3B69C65266514A729829756E016CF55D1A917D9CE64ECEA6EB081A85F177BDEED9062CA130A23BB3D90817644F84890C55BB158DA2C0F590826B7073E933EC081268331D56BFB282D4DA250EC39EF3E477BAC8E5B64B712F4457C5B116D0D491AC7AF0E68F3337A51AADA71152604FF386C9CCB4F67204F6A2FBDBE18E5AF591DDA0B5A93382BC210A549262C0A250EF2CB3D3009C4EA412324E359DBEFF97ADA37287D08C11ED12B170B06B8055BC5B17B3F464BFDE141A145A6393750FE9D5EF33C33A43B575091076A24A9E67C56C7B41F023C42166C89E57D001E9161E924A693FD3712355AD60EAC3BD8AC16BA15F5BEABEE3D014B7F5361D7EB36B3F594E1BB98F6813A2D88FD6FC9F008713334AE962B0CB4C07FDB32D549C0F24D127486707C29A7F5EC7F8601961D2E4C189BA3129E48D0D2215E70D9115AAD993E78565715E50EA0E336EA456D469A23368CFB3F0ED6B8AC77738B2A2AC0A7F155CF6D402687212585A2DD9EEAAF614387C7C8D3089D3F42DBD1A594233ABB618AAD84D52F8A234281F2B0F62E3FE23B1E7F28DD89F6F79572506F9B02021CE44914237C190C82F1E5CB395844550EF279E9B50FA1D5B7AE84FE9F31538546244BD4C86FDADB5974396692A7BBE7AD493834DD13418929F8EA0F44BBF8E3D9DFCEF170DF138351932FA05468DE9A922953DF5AB791406E89F752A378A0D98A957773EC3B952DAE04200C1944F30B43D80450F8F83AC4F688D806DE9C9C406D30FC0D9098BE612EF0C4AD2E80B2C746944C727A1015538A53C69280EE0F00D6601CAA6CB0EAF4D3DADBF849D4C1F8F1FD7D438619C70364DACE4408586876D725353
-20220414211625 2 6 100 6143 2 ECFEBE907ED5229E0F2A017AAC2F662065526E4CD6767D11B9BC47C5C4D0E39E232885C9039387645B0C61FC91A5B5F97A3A3264DC42DD48A30C3E923D467D8CDDD98F0DE77067BFB45F466CA03EC5B86BF836D9C6298948D315FF4627FE23F62CE3E722A3B60F7D9D6F97D4B10E30924ABF0E094D5155F57DFBD93B17A3E958816225D458E063A4785F4D04A131D6C3AEFF9B405648DC2E0A64F061AB428E6C3B69C65266514A729829756E016CF55D1A917D9CE64ECEA6EB081A85F177BDEED9062CA130A23BB3D90817644F84890C55BB158DA2C0F590826B7073E933EC081268331D56BFB282D4DA250EC39EF3E477BAC8E5B64B712F4457C5B116D0D491AC7AF0E68F3337A51AADA71152604FF386C9CCB4F67204F6A2FBDBE18E5AF591DDA0B5A93382BC210A549262C0A250EF2CB3D3009C4EA412324E359DBEFF97ADA37287D08C11ED12B170B06B8055BC5B17B3F464BFDE141A145A6393750FE9D5EF33C33A43B575091076A24A9E67C56C7B41F023C42166C89E57D001E9161E924A693FD3712355AD60EAC3BD8AC16BA15F5BEABEE3D014B7F5361D7EB36B3F594E1BB98F6813A2D88FD6FC9F008713334AE962B0CB4C07FDB32D549C0F24D127486707C29A7F5EC7F8601961D2E4C189BA3129E48D0D2215E70D9115AAD993E78565715E50EA0E336EA456D469A23368CFB3F0ED6B8AC77738B2A2AC0A7F155CF6D402687212585A2DD9EEAAF614387C7C8D3089D3F42DBD1A594233ABB618AAD84D52F8A234281F2B0F62E3FE23B1E7F28DD89F6F79572506F9B02021CE44914237C190C82F1E5CB395844550EF279E9B50FA1D5B7AE84FE9F31538546244BD4C86FDADB5974396692A7BBE7AD493834DD13418929F8EA0F44BBF8E3D9DFCEF170DF138351932FA05468DE9A922953DF5AB791406E89F752A378A0D98A957773EC3B952DAE04200C1944F30B43D80450F8F83AC4F688D806DE9C9C406D30FC0D9098BE612EF0C4AD2E80B2C746944C727A1015538A53C69280EE0F00D6601CAA6CB0EAF4D3DADBF849D4C1F8F1FD7D438619C70364DACE4408586876E9775FB
-20220414212842 2 6 100 6143 2 ECFEBE907ED5229E0F2A017AAC2F662065526E4CD6767D11B9BC47C5C4D0E39E232885C9039387645B0C61FC91A5B5F97A3A3264DC42DD48A30C3E923D467D8CDDD98F0DE77067BFB45F466CA03EC5B86BF836D9C6298948D315FF4627FE23F62CE3E722A3B60F7D9D6F97D4B10E30924ABF0E094D5155F57DFBD93B17A3E958816225D458E063A4785F4D04A131D6C3AEFF9B405648DC2E0A64F061AB428E6C3B69C65266514A729829756E016CF55D1A917D9CE64ECEA6EB081A85F177BDEED9062CA130A23BB3D90817644F84890C55BB158DA2C0F590826B7073E933EC081268331D56BFB282D4DA250EC39EF3E477BAC8E5B64B712F4457C5B116D0D491AC7AF0E68F3337A51AADA71152604FF386C9CCB4F67204F6A2FBDBE18E5AF591DDA0B5A93382BC210A549262C0A250EF2CB3D3009C4EA412324E359DBEFF97ADA37287D08C11ED12B170B06B8055BC5B17B3F464BFDE141A145A6393750FE9D5EF33C33A43B575091076A24A9E67C56C7B41F023C42166C89E57D001E9161E924A693FD3712355AD60EAC3BD8AC16BA15F5BEABEE3D014B7F5361D7EB36B3F594E1BB98F6813A2D88FD6FC9F008713334AE962B0CB4C07FDB32D549C0F24D127486707C29A7F5EC7F8601961D2E4C189BA3129E48D0D2215E70D9115AAD993E78565715E50EA0E336EA456D469A23368CFB3F0ED6B8AC77738B2A2AC0A7F155CF6D402687212585A2DD9EEAAF614387C7C8D3089D3F42DBD1A594233ABB618AAD84D52F8A234281F2B0F62E3FE23B1E7F28DD89F6F79572506F9B02021CE44914237C190C82F1E5CB395844550EF279E9B50FA1D5B7AE84FE9F31538546244BD4C86FDADB5974396692A7BBE7AD493834DD13418929F8EA0F44BBF8E3D9DFCEF170DF138351932FA05468DE9A922953DF5AB791406E89F752A378A0D98A957773EC3B952DAE04200C1944F30B43D80450F8F83AC4F688D806DE9C9C406D30FC0D9098BE612EF0C4AD2E80B2C746944C727A1015538A53C69280EE0F00D6601CAA6CB0EAF4D3DADBF849D4C1F8F1FD7D438619C70364DACE4408586877066A0AB
-20220414220717 2 6 100 6143 2 ECFEBE907ED5229E0F2A017AAC2F662065526E4CD6767D11B9BC47C5C4D0E39E232885C9039387645B0C61FC91A5B5F97A3A3264DC42DD48A30C3E923D467D8CDDD98F0DE77067BFB45F466CA03EC5B86BF836D9C6298948D315FF4627FE23F62CE3E722A3B60F7D9D6F97D4B10E30924ABF0E094D5155F57DFBD93B17A3E958816225D458E063A4785F4D04A131D6C3AEFF9B405648DC2E0A64F061AB428E6C3B69C65266514A729829756E016CF55D1A917D9CE64ECEA6EB081A85F177BDEED9062CA130A23BB3D90817644F84890C55BB158DA2C0F590826B7073E933EC081268331D56BFB282D4DA250EC39EF3E477BAC8E5B64B712F4457C5B116D0D491AC7AF0E68F3337A51AADA71152604FF386C9CCB4F67204F6A2FBDBE18E5AF591DDA0B5A93382BC210A549262C0A250EF2CB3D3009C4EA412324E359DBEFF97ADA37287D08C11ED12B170B06B8055BC5B17B3F464BFDE141A145A6393750FE9D5EF33C33A43B575091076A24A9E67C56C7B41F023C42166C89E57D001E9161E924A693FD3712355AD60EAC3BD8AC16BA15F5BEABEE3D014B7F5361D7EB36B3F594E1BB98F6813A2D88FD6FC9F008713334AE962B0CB4C07FDB32D549C0F24D127486707C29A7F5EC7F8601961D2E4C189BA3129E48D0D2215E70D9115AAD993E78565715E50EA0E336EA456D469A23368CFB3F0ED6B8AC77738B2A2AC0A7F155CF6D402687212585A2DD9EEAAF614387C7C8D3089D3F42DBD1A594233ABB618AAD84D52F8A234281F2B0F62E3FE23B1E7F28DD89F6F79572506F9B02021CE44914237C190C82F1E5CB395844550EF279E9B50FA1D5B7AE84FE9F31538546244BD4C86FDADB5974396692A7BBE7AD493834DD13418929F8EA0F44BBF8E3D9DFCEF170DF138351932FA05468DE9A922953DF5AB791406E89F752A378A0D98A957773EC3B952DAE04200C1944F30B43D80450F8F83AC4F688D806DE9C9C406D30FC0D9098BE612EF0C4AD2E80B2C746944C727A1015538A53C69280EE0F00D6601CAA6CB0EAF4D3DADBF849D4C1F8F1FD7D438619C70364DACE44085868776159A7B
-20220414232618 2 6 100 6143 5 ECFEBE907ED5229E0F2A017AAC2F662065526E4CD6767D11B9BC47C5C4D0E39E232885C9039387645B0C61FC91A5B5F97A3A3264DC42DD48A30C3E923D467D8CDDD98F0DE77067BFB45F466CA03EC5B86BF836D9C6298948D315FF4627FE23F62CE3E722A3B60F7D9D6F97D4B10E30924ABF0E094D5155F57DFBD93B17A3E958816225D458E063A4785F4D04A131D6C3AEFF9B405648DC2E0A64F061AB428E6C3B69C65266514A729829756E016CF55D1A917D9CE64ECEA6EB081A85F177BDEED9062CA130A23BB3D90817644F84890C55BB158DA2C0F590826B7073E933EC081268331D56BFB282D4DA250EC39EF3E477BAC8E5B64B712F4457C5B116D0D491AC7AF0E68F3337A51AADA71152604FF386C9CCB4F67204F6A2FBDBE18E5AF591DDA0B5A93382BC210A549262C0A250EF2CB3D3009C4EA412324E359DBEFF97ADA37287D08C11ED12B170B06B8055BC5B17B3F464BFDE141A145A6393750FE9D5EF33C33A43B575091076A24A9E67C56C7B41F023C42166C89E57D001E9161E924A693FD3712355AD60EAC3BD8AC16BA15F5BEABEE3D014B7F5361D7EB36B3F594E1BB98F6813A2D88FD6FC9F008713334AE962B0CB4C07FDB32D549C0F24D127486707C29A7F5EC7F8601961D2E4C189BA3129E48D0D2215E70D9115AAD993E78565715E50EA0E336EA456D469A23368CFB3F0ED6B8AC77738B2A2AC0A7F155CF6D402687212585A2DD9EEAAF614387C7C8D3089D3F42DBD1A594233ABB618AAD84D52F8A234281F2B0F62E3FE23B1E7F28DD89F6F79572506F9B02021CE44914237C190C82F1E5CB395844550EF279E9B50FA1D5B7AE84FE9F31538546244BD4C86FDADB5974396692A7BBE7AD493834DD13418929F8EA0F44BBF8E3D9DFCEF170DF138351932FA05468DE9A922953DF5AB791406E89F752A378A0D98A957773EC3B952DAE04200C1944F30B43D80450F8F83AC4F688D806DE9C9C406D30FC0D9098BE612EF0C4AD2E80B2C746944C727A1015538A53C69280EE0F00D6601CAA6CB0EAF4D3DADBF849D4C1F8F1FD7D438619C70364DACE4408586878185133F
-20220414233421 2 6 100 6143 5 ECFEBE907ED5229E0F2A017AAC2F662065526E4CD6767D11B9BC47C5C4D0E39E232885C9039387645B0C61FC91A5B5F97A3A3264DC42DD48A30C3E923D467D8CDDD98F0DE77067BFB45F466CA03EC5B86BF836D9C6298948D315FF4627FE23F62CE3E722A3B60F7D9D6F97D4B10E30924ABF0E094D5155F57DFBD93B17A3E958816225D458E063A4785F4D04A131D6C3AEFF9B405648DC2E0A64F061AB428E6C3B69C65266514A729829756E016CF55D1A917D9CE64ECEA6EB081A85F177BDEED9062CA130A23BB3D90817644F84890C55BB158DA2C0F590826B7073E933EC081268331D56BFB282D4DA250EC39EF3E477BAC8E5B64B712F4457C5B116D0D491AC7AF0E68F3337A51AADA71152604FF386C9CCB4F67204F6A2FBDBE18E5AF591DDA0B5A93382BC210A549262C0A250EF2CB3D3009C4EA412324E359DBEFF97ADA37287D08C11ED12B170B06B8055BC5B17B3F464BFDE141A145A6393750FE9D5EF33C33A43B575091076A24A9E67C56C7B41F023C42166C89E57D001E9161E924A693FD3712355AD60EAC3BD8AC16BA15F5BEABEE3D014B7F5361D7EB36B3F594E1BB98F6813A2D88FD6FC9F008713334AE962B0CB4C07FDB32D549C0F24D127486707C29A7F5EC7F8601961D2E4C189BA3129E48D0D2215E70D9115AAD993E78565715E50EA0E336EA456D469A23368CFB3F0ED6B8AC77738B2A2AC0A7F155CF6D402687212585A2DD9EEAAF614387C7C8D3089D3F42DBD1A594233ABB618AAD84D52F8A234281F2B0F62E3FE23B1E7F28DD89F6F79572506F9B02021CE44914237C190C82F1E5CB395844550EF279E9B50FA1D5B7AE84FE9F31538546244BD4C86FDADB5974396692A7BBE7AD493834DD13418929F8EA0F44BBF8E3D9DFCEF170DF138351932FA05468DE9A922953DF5AB791406E89F752A378A0D98A957773EC3B952DAE04200C1944F30B43D80450F8F83AC4F688D806DE9C9C406D30FC0D9098BE612EF0C4AD2E80B2C746944C727A1015538A53C69280EE0F00D6601CAA6CB0EAF4D3DADBF849D4C1F8F1FD7D438619C70364DACE44085868782A4E2C7
-20220414234330 2 6 100 6143 2 ECFEBE907ED5229E0F2A017AAC2F662065526E4CD6767D11B9BC47C5C4D0E39E232885C9039387645B0C61FC91A5B5F97A3A3264DC42DD48A30C3E923D467D8CDDD98F0DE77067BFB45F466CA03EC5B86BF836D9C6298948D315FF4627FE23F62CE3E722A3B60F7D9D6F97D4B10E30924ABF0E094D5155F57DFBD93B17A3E958816225D458E063A4785F4D04A131D6C3AEFF9B405648DC2E0A64F061AB428E6C3B69C65266514A729829756E016CF55D1A917D9CE64ECEA6EB081A85F177BDEED9062CA130A23BB3D90817644F84890C55BB158DA2C0F590826B7073E933EC081268331D56BFB282D4DA250EC39EF3E477BAC8E5B64B712F4457C5B116D0D491AC7AF0E68F3337A51AADA71152604FF386C9CCB4F67204F6A2FBDBE18E5AF591DDA0B5A93382BC210A549262C0A250EF2CB3D3009C4EA412324E359DBEFF97ADA37287D08C11ED12B170B06B8055BC5B17B3F464BFDE141A145A6393750FE9D5EF33C33A43B575091076A24A9E67C56C7B41F023C42166C89E57D001E9161E924A693FD3712355AD60EAC3BD8AC16BA15F5BEABEE3D014B7F5361D7EB36B3F594E1BB98F6813A2D88FD6FC9F008713334AE962B0CB4C07FDB32D549C0F24D127486707C29A7F5EC7F8601961D2E4C189BA3129E48D0D2215E70D9115AAD993E78565715E50EA0E336EA456D469A23368CFB3F0ED6B8AC77738B2A2AC0A7F155CF6D402687212585A2DD9EEAAF614387C7C8D3089D3F42DBD1A594233ABB618AAD84D52F8A234281F2B0F62E3FE23B1E7F28DD89F6F79572506F9B02021CE44914237C190C82F1E5CB395844550EF279E9B50FA1D5B7AE84FE9F31538546244BD4C86FDADB5974396692A7BBE7AD493834DD13418929F8EA0F44BBF8E3D9DFCEF170DF138351932FA05468DE9A922953DF5AB791406E89F752A378A0D98A957773EC3B952DAE04200C1944F30B43D80450F8F83AC4F688D806DE9C9C406D30FC0D9098BE612EF0C4AD2E80B2C746944C727A1015538A53C69280EE0F00D6601CAA6CB0EAF4D3DADBF849D4C1F8F1FD7D438619C70364DACE44085868783E43363
-20220415002146 2 6 100 6143 2 ECFEBE907ED5229E0F2A017AAC2F662065526E4CD6767D11B9BC47C5C4D0E39E232885C9039387645B0C61FC91A5B5F97A3A3264DC42DD48A30C3E923D467D8CDDD98F0DE77067BFB45F466CA03EC5B86BF836D9C6298948D315FF4627FE23F62CE3E722A3B60F7D9D6F97D4B10E30924ABF0E094D5155F57DFBD93B17A3E958816225D458E063A4785F4D04A131D6C3AEFF9B405648DC2E0A64F061AB428E6C3B69C65266514A729829756E016CF55D1A917D9CE64ECEA6EB081A85F177BDEED9062CA130A23BB3D90817644F84890C55BB158DA2C0F590826B7073E933EC081268331D56BFB282D4DA250EC39EF3E477BAC8E5B64B712F4457C5B116D0D491AC7AF0E68F3337A51AADA71152604FF386C9CCB4F67204F6A2FBDBE18E5AF591DDA0B5A93382BC210A549262C0A250EF2CB3D3009C4EA412324E359DBEFF97ADA37287D08C11ED12B170B06B8055BC5B17B3F464BFDE141A145A6393750FE9D5EF33C33A43B575091076A24A9E67C56C7B41F023C42166C89E57D001E9161E924A693FD3712355AD60EAC3BD8AC16BA15F5BEABEE3D014B7F5361D7EB36B3F594E1BB98F6813A2D88FD6FC9F008713334AE962B0CB4C07FDB32D549C0F24D127486707C29A7F5EC7F8601961D2E4C189BA3129E48D0D2215E70D9115AAD993E78565715E50EA0E336EA456D469A23368CFB3F0ED6B8AC77738B2A2AC0A7F155CF6D402687212585A2DD9EEAAF614387C7C8D3089D3F42DBD1A594233ABB618AAD84D52F8A234281F2B0F62E3FE23B1E7F28DD89F6F79572506F9B02021CE44914237C190C82F1E5CB395844550EF279E9B50FA1D5B7AE84FE9F31538546244BD4C86FDADB5974396692A7BBE7AD493834DD13418929F8EA0F44BBF8E3D9DFCEF170DF138351932FA05468DE9A922953DF5AB791406E89F752A378A0D98A957773EC3B952DAE04200C1944F30B43D80450F8F83AC4F688D806DE9C9C406D30FC0D9098BE612EF0C4AD2E80B2C746944C727A1015538A53C69280EE0F00D6601CAA6CB0EAF4D3DADBF849D4C1F8F1FD7D438619C70364DACE44085868789570393
-20220415004554 2 6 100 6143 2 ECFEBE907ED5229E0F2A017AAC2F662065526E4CD6767D11B9BC47C5C4D0E39E232885C9039387645B0C61FC91A5B5F97A3A3264DC42DD48A30C3E923D467D8CDDD98F0DE77067BFB45F466CA03EC5B86BF836D9C6298948D315FF4627FE23F62CE3E722A3B60F7D9D6F97D4B10E30924ABF0E094D5155F57DFBD93B17A3E958816225D458E063A4785F4D04A131D6C3AEFF9B405648DC2E0A64F061AB428E6C3B69C65266514A729829756E016CF55D1A917D9CE64ECEA6EB081A85F177BDEED9062CA130A23BB3D90817644F84890C55BB158DA2C0F590826B7073E933EC081268331D56BFB282D4DA250EC39EF3E477BAC8E5B64B712F4457C5B116D0D491AC7AF0E68F3337A51AADA71152604FF386C9CCB4F67204F6A2FBDBE18E5AF591DDA0B5A93382BC210A549262C0A250EF2CB3D3009C4EA412324E359DBEFF97ADA37287D08C11ED12B170B06B8055BC5B17B3F464BFDE141A145A6393750FE9D5EF33C33A43B575091076A24A9E67C56C7B41F023C42166C89E57D001E9161E924A693FD3712355AD60EAC3BD8AC16BA15F5BEABEE3D014B7F5361D7EB36B3F594E1BB98F6813A2D88FD6FC9F008713334AE962B0CB4C07FDB32D549C0F24D127486707C29A7F5EC7F8601961D2E4C189BA3129E48D0D2215E70D9115AAD993E78565715E50EA0E336EA456D469A23368CFB3F0ED6B8AC77738B2A2AC0A7F155CF6D402687212585A2DD9EEAAF614387C7C8D3089D3F42DBD1A594233ABB618AAD84D52F8A234281F2B0F62E3FE23B1E7F28DD89F6F79572506F9B02021CE44914237C190C82F1E5CB395844550EF279E9B50FA1D5B7AE84FE9F31538546244BD4C86FDADB5974396692A7BBE7AD493834DD13418929F8EA0F44BBF8E3D9DFCEF170DF138351932FA05468DE9A922953DF5AB791406E89F752A378A0D98A957773EC3B952DAE04200C1944F30B43D80450F8F83AC4F688D806DE9C9C406D30FC0D9098BE612EF0C4AD2E80B2C746944C727A1015538A53C69280EE0F00D6601CAA6CB0EAF4D3DADBF849D4C1F8F1FD7D438619C70364DACE4408586878CBF2353
-20220415005307 2 6 100 6143 2 ECFEBE907ED5229E0F2A017AAC2F662065526E4CD6767D11B9BC47C5C4D0E39E232885C9039387645B0C61FC91A5B5F97A3A3264DC42DD48A30C3E923D467D8CDDD98F0DE77067BFB45F466CA03EC5B86BF836D9C6298948D315FF4627FE23F62CE3E722A3B60F7D9D6F97D4B10E30924ABF0E094D5155F57DFBD93B17A3E958816225D458E063A4785F4D04A131D6C3AEFF9B405648DC2E0A64F061AB428E6C3B69C65266514A729829756E016CF55D1A917D9CE64ECEA6EB081A85F177BDEED9062CA130A23BB3D90817644F84890C55BB158DA2C0F590826B7073E933EC081268331D56BFB282D4DA250EC39EF3E477BAC8E5B64B712F4457C5B116D0D491AC7AF0E68F3337A51AADA71152604FF386C9CCB4F67204F6A2FBDBE18E5AF591DDA0B5A93382BC210A549262C0A250EF2CB3D3009C4EA412324E359DBEFF97ADA37287D08C11ED12B170B06B8055BC5B17B3F464BFDE141A145A6393750FE9D5EF33C33A43B575091076A24A9E67C56C7B41F023C42166C89E57D001E9161E924A693FD3712355AD60EAC3BD8AC16BA15F5BEABEE3D014B7F5361D7EB36B3F594E1BB98F6813A2D88FD6FC9F008713334AE962B0CB4C07FDB32D549C0F24D127486707C29A7F5EC7F8601961D2E4C189BA3129E48D0D2215E70D9115AAD993E78565715E50EA0E336EA456D469A23368CFB3F0ED6B8AC77738B2A2AC0A7F155CF6D402687212585A2DD9EEAAF614387C7C8D3089D3F42DBD1A594233ABB618AAD84D52F8A234281F2B0F62E3FE23B1E7F28DD89F6F79572506F9B02021CE44914237C190C82F1E5CB395844550EF279E9B50FA1D5B7AE84FE9F31538546244BD4C86FDADB5974396692A7BBE7AD493834DD13418929F8EA0F44BBF8E3D9DFCEF170DF138351932FA05468DE9A922953DF5AB791406E89F752A378A0D98A957773EC3B952DAE04200C1944F30B43D80450F8F83AC4F688D806DE9C9C406D30FC0D9098BE612EF0C4AD2E80B2C746944C727A1015538A53C69280EE0F00D6601CAA6CB0EAF4D3DADBF849D4C1F8F1FD7D438619C70364DACE4408586878DBC5B9B
-20220415011041 2 6 100 6143 2 ECFEBE907ED5229E0F2A017AAC2F662065526E4CD6767D11B9BC47C5C4D0E39E232885C9039387645B0C61FC91A5B5F97A3A3264DC42DD48A30C3E923D467D8CDDD98F0DE77067BFB45F466CA03EC5B86BF836D9C6298948D315FF4627FE23F62CE3E722A3B60F7D9D6F97D4B10E30924ABF0E094D5155F57DFBD93B17A3E958816225D458E063A4785F4D04A131D6C3AEFF9B405648DC2E0A64F061AB428E6C3B69C65266514A729829756E016CF55D1A917D9CE64ECEA6EB081A85F177BDEED9062CA130A23BB3D90817644F84890C55BB158DA2C0F590826B7073E933EC081268331D56BFB282D4DA250EC39EF3E477BAC8E5B64B712F4457C5B116D0D491AC7AF0E68F3337A51AADA71152604FF386C9CCB4F67204F6A2FBDBE18E5AF591DDA0B5A93382BC210A549262C0A250EF2CB3D3009C4EA412324E359DBEFF97ADA37287D08C11ED12B170B06B8055BC5B17B3F464BFDE141A145A6393750FE9D5EF33C33A43B575091076A24A9E67C56C7B41F023C42166C89E57D001E9161E924A693FD3712355AD60EAC3BD8AC16BA15F5BEABEE3D014B7F5361D7EB36B3F594E1BB98F6813A2D88FD6FC9F008713334AE962B0CB4C07FDB32D549C0F24D127486707C29A7F5EC7F8601961D2E4C189BA3129E48D0D2215E70D9115AAD993E78565715E50EA0E336EA456D469A23368CFB3F0ED6B8AC77738B2A2AC0A7F155CF6D402687212585A2DD9EEAAF614387C7C8D3089D3F42DBD1A594233ABB618AAD84D52F8A234281F2B0F62E3FE23B1E7F28DD89F6F79572506F9B02021CE44914237C190C82F1E5CB395844550EF279E9B50FA1D5B7AE84FE9F31538546244BD4C86FDADB5974396692A7BBE7AD493834DD13418929F8EA0F44BBF8E3D9DFCEF170DF138351932FA05468DE9A922953DF5AB791406E89F752A378A0D98A957773EC3B952DAE04200C1944F30B43D80450F8F83AC4F688D806DE9C9C406D30FC0D9098BE612EF0C4AD2E80B2C746944C727A1015538A53C69280EE0F00D6601CAA6CB0EAF4D3DADBF849D4C1F8F1FD7D438619C70364DACE44085868790357083
-20220415011858 2 6 100 6143 2 ECFEBE907ED5229E0F2A017AAC2F662065526E4CD6767D11B9BC47C5C4D0E39E232885C9039387645B0C61FC91A5B5F97A3A3264DC42DD48A30C3E923D467D8CDDD98F0DE77067BFB45F466CA03EC5B86BF836D9C6298948D315FF4627FE23F62CE3E722A3B60F7D9D6F97D4B10E30924ABF0E094D5155F57DFBD93B17A3E958816225D458E063A4785F4D04A131D6C3AEFF9B405648DC2E0A64F061AB428E6C3B69C65266514A729829756E016CF55D1A917D9CE64ECEA6EB081A85F177BDEED9062CA130A23BB3D90817644F84890C55BB158DA2C0F590826B7073E933EC081268331D56BFB282D4DA250EC39EF3E477BAC8E5B64B712F4457C5B116D0D491AC7AF0E68F3337A51AADA71152604FF386C9CCB4F67204F6A2FBDBE18E5AF591DDA0B5A93382BC210A549262C0A250EF2CB3D3009C4EA412324E359DBEFF97ADA37287D08C11ED12B170B06B8055BC5B17B3F464BFDE141A145A6393750FE9D5EF33C33A43B575091076A24A9E67C56C7B41F023C42166C89E57D001E9161E924A693FD3712355AD60EAC3BD8AC16BA15F5BEABEE3D014B7F5361D7EB36B3F594E1BB98F6813A2D88FD6FC9F008713334AE962B0CB4C07FDB32D549C0F24D127486707C29A7F5EC7F8601961D2E4C189BA3129E48D0D2215E70D9115AAD993E78565715E50EA0E336EA456D469A23368CFB3F0ED6B8AC77738B2A2AC0A7F155CF6D402687212585A2DD9EEAAF614387C7C8D3089D3F42DBD1A594233ABB618AAD84D52F8A234281F2B0F62E3FE23B1E7F28DD89F6F79572506F9B02021CE44914237C190C82F1E5CB395844550EF279E9B50FA1D5B7AE84FE9F31538546244BD4C86FDADB5974396692A7BBE7AD493834DD13418929F8EA0F44BBF8E3D9DFCEF170DF138351932FA05468DE9A922953DF5AB791406E89F752A378A0D98A957773EC3B952DAE04200C1944F30B43D80450F8F83AC4F688D806DE9C9C406D30FC0D9098BE612EF0C4AD2E80B2C746944C727A1015538A53C69280EE0F00D6601CAA6CB0EAF4D3DADBF849D4C1F8F1FD7D438619C70364DACE440858687915FF2DB
-20220415011944 2 6 100 6143 2 ECFEBE907ED5229E0F2A017AAC2F662065526E4CD6767D11B9BC47C5C4D0E39E232885C9039387645B0C61FC91A5B5F97A3A3264DC42DD48A30C3E923D467D8CDDD98F0DE77067BFB45F466CA03EC5B86BF836D9C6298948D315FF4627FE23F62CE3E722A3B60F7D9D6F97D4B10E30924ABF0E094D5155F57DFBD93B17A3E958816225D458E063A4785F4D04A131D6C3AEFF9B405648DC2E0A64F061AB428E6C3B69C65266514A729829756E016CF55D1A917D9CE64ECEA6EB081A85F177BDEED9062CA130A23BB3D90817644F84890C55BB158DA2C0F590826B7073E933EC081268331D56BFB282D4DA250EC39EF3E477BAC8E5B64B712F4457C5B116D0D491AC7AF0E68F3337A51AADA71152604FF386C9CCB4F67204F6A2FBDBE18E5AF591DDA0B5A93382BC210A549262C0A250EF2CB3D3009C4EA412324E359DBEFF97ADA37287D08C11ED12B170B06B8055BC5B17B3F464BFDE141A145A6393750FE9D5EF33C33A43B575091076A24A9E67C56C7B41F023C42166C89E57D001E9161E924A693FD3712355AD60EAC3BD8AC16BA15F5BEABEE3D014B7F5361D7EB36B3F594E1BB98F6813A2D88FD6FC9F008713334AE962B0CB4C07FDB32D549C0F24D127486707C29A7F5EC7F8601961D2E4C189BA3129E48D0D2215E70D9115AAD993E78565715E50EA0E336EA456D469A23368CFB3F0ED6B8AC77738B2A2AC0A7F155CF6D402687212585A2DD9EEAAF614387C7C8D3089D3F42DBD1A594233ABB618AAD84D52F8A234281F2B0F62E3FE23B1E7F28DD89F6F79572506F9B02021CE44914237C190C82F1E5CB395844550EF279E9B50FA1D5B7AE84FE9F31538546244BD4C86FDADB5974396692A7BBE7AD493834DD13418929F8EA0F44BBF8E3D9DFCEF170DF138351932FA05468DE9A922953DF5AB791406E89F752A378A0D98A957773EC3B952DAE04200C1944F30B43D80450F8F83AC4F688D806DE9C9C406D30FC0D9098BE612EF0C4AD2E80B2C746944C727A1015538A53C69280EE0F00D6601CAA6CB0EAF4D3DADBF849D4C1F8F1FD7D438619C70364DACE4408586879171F173
-20220415015846 2 6 100 6143 5 ECFEBE907ED5229E0F2A017AAC2F662065526E4CD6767D11B9BC47C5C4D0E39E232885C9039387645B0C61FC91A5B5F97A3A3264DC42DD48A30C3E923D467D8CDDD98F0DE77067BFB45F466CA03EC5B86BF836D9C6298948D315FF4627FE23F62CE3E722A3B60F7D9D6F97D4B10E30924ABF0E094D5155F57DFBD93B17A3E958816225D458E063A4785F4D04A131D6C3AEFF9B405648DC2E0A64F061AB428E6C3B69C65266514A729829756E016CF55D1A917D9CE64ECEA6EB081A85F177BDEED9062CA130A23BB3D90817644F84890C55BB158DA2C0F590826B7073E933EC081268331D56BFB282D4DA250EC39EF3E477BAC8E5B64B712F4457C5B116D0D491AC7AF0E68F3337A51AADA71152604FF386C9CCB4F67204F6A2FBDBE18E5AF591DDA0B5A93382BC210A549262C0A250EF2CB3D3009C4EA412324E359DBEFF97ADA37287D08C11ED12B170B06B8055BC5B17B3F464BFDE141A145A6393750FE9D5EF33C33A43B575091076A24A9E67C56C7B41F023C42166C89E57D001E9161E924A693FD3712355AD60EAC3BD8AC16BA15F5BEABEE3D014B7F5361D7EB36B3F594E1BB98F6813A2D88FD6FC9F008713334AE962B0CB4C07FDB32D549C0F24D127486707C29A7F5EC7F8601961D2E4C189BA3129E48D0D2215E70D9115AAD993E78565715E50EA0E336EA456D469A23368CFB3F0ED6B8AC77738B2A2AC0A7F155CF6D402687212585A2DD9EEAAF614387C7C8D3089D3F42DBD1A594233ABB618AAD84D52F8A234281F2B0F62E3FE23B1E7F28DD89F6F79572506F9B02021CE44914237C190C82F1E5CB395844550EF279E9B50FA1D5B7AE84FE9F31538546244BD4C86FDADB5974396692A7BBE7AD493834DD13418929F8EA0F44BBF8E3D9DFCEF170DF138351932FA05468DE9A922953DF5AB791406E89F752A378A0D98A957773EC3B952DAE04200C1944F30B43D80450F8F83AC4F688D806DE9C9C406D30FC0D9098BE612EF0C4AD2E80B2C746944C727A1015538A53C69280EE0F00D6601CAA6CB0EAF4D3DADBF849D4C1F8F1FD7D438619C70364DACE44085868796EBC7E7
-20220415020913 2 6 100 6143 2 ECFEBE907ED5229E0F2A017AAC2F662065526E4CD6767D11B9BC47C5C4D0E39E232885C9039387645B0C61FC91A5B5F97A3A3264DC42DD48A30C3E923D467D8CDDD98F0DE77067BFB45F466CA03EC5B86BF836D9C6298948D315FF4627FE23F62CE3E722A3B60F7D9D6F97D4B10E30924ABF0E094D5155F57DFBD93B17A3E958816225D458E063A4785F4D04A131D6C3AEFF9B405648DC2E0A64F061AB428E6C3B69C65266514A729829756E016CF55D1A917D9CE64ECEA6EB081A85F177BDEED9062CA130A23BB3D90817644F84890C55BB158DA2C0F590826B7073E933EC081268331D56BFB282D4DA250EC39EF3E477BAC8E5B64B712F4457C5B116D0D491AC7AF0E68F3337A51AADA71152604FF386C9CCB4F67204F6A2FBDBE18E5AF591DDA0B5A93382BC210A549262C0A250EF2CB3D3009C4EA412324E359DBEFF97ADA37287D08C11ED12B170B06B8055BC5B17B3F464BFDE141A145A6393750FE9D5EF33C33A43B575091076A24A9E67C56C7B41F023C42166C89E57D001E9161E924A693FD3712355AD60EAC3BD8AC16BA15F5BEABEE3D014B7F5361D7EB36B3F594E1BB98F6813A2D88FD6FC9F008713334AE962B0CB4C07FDB32D549C0F24D127486707C29A7F5EC7F8601961D2E4C189BA3129E48D0D2215E70D9115AAD993E78565715E50EA0E336EA456D469A23368CFB3F0ED6B8AC77738B2A2AC0A7F155CF6D402687212585A2DD9EEAAF614387C7C8D3089D3F42DBD1A594233ABB618AAD84D52F8A234281F2B0F62E3FE23B1E7F28DD89F6F79572506F9B02021CE44914237C190C82F1E5CB395844550EF279E9B50FA1D5B7AE84FE9F31538546244BD4C86FDADB5974396692A7BBE7AD493834DD13418929F8EA0F44BBF8E3D9DFCEF170DF138351932FA05468DE9A922953DF5AB791406E89F752A378A0D98A957773EC3B952DAE04200C1944F30B43D80450F8F83AC4F688D806DE9C9C406D30FC0D9098BE612EF0C4AD2E80B2C746944C727A1015538A53C69280EE0F00D6601CAA6CB0EAF4D3DADBF849D4C1F8F1FD7D438619C70364DACE4408586879851976B
-20220415021312 2 6 100 6143 2 ECFEBE907ED5229E0F2A017AAC2F662065526E4CD6767D11B9BC47C5C4D0E39E232885C9039387645B0C61FC91A5B5F97A3A3264DC42DD48A30C3E923D467D8CDDD98F0DE77067BFB45F466CA03EC5B86BF836D9C6298948D315FF4627FE23F62CE3E722A3B60F7D9D6F97D4B10E30924ABF0E094D5155F57DFBD93B17A3E958816225D458E063A4785F4D04A131D6C3AEFF9B405648DC2E0A64F061AB428E6C3B69C65266514A729829756E016CF55D1A917D9CE64ECEA6EB081A85F177BDEED9062CA130A23BB3D90817644F84890C55BB158DA2C0F590826B7073E933EC081268331D56BFB282D4DA250EC39EF3E477BAC8E5B64B712F4457C5B116D0D491AC7AF0E68F3337A51AADA71152604FF386C9CCB4F67204F6A2FBDBE18E5AF591DDA0B5A93382BC210A549262C0A250EF2CB3D3009C4EA412324E359DBEFF97ADA37287D08C11ED12B170B06B8055BC5B17B3F464BFDE141A145A6393750FE9D5EF33C33A43B575091076A24A9E67C56C7B41F023C42166C89E57D001E9161E924A693FD3712355AD60EAC3BD8AC16BA15F5BEABEE3D014B7F5361D7EB36B3F594E1BB98F6813A2D88FD6FC9F008713334AE962B0CB4C07FDB32D549C0F24D127486707C29A7F5EC7F8601961D2E4C189BA3129E48D0D2215E70D9115AAD993E78565715E50EA0E336EA456D469A23368CFB3F0ED6B8AC77738B2A2AC0A7F155CF6D402687212585A2DD9EEAAF614387C7C8D3089D3F42DBD1A594233ABB618AAD84D52F8A234281F2B0F62E3FE23B1E7F28DD89F6F79572506F9B02021CE44914237C190C82F1E5CB395844550EF279E9B50FA1D5B7AE84FE9F31538546244BD4C86FDADB5974396692A7BBE7AD493834DD13418929F8EA0F44BBF8E3D9DFCEF170DF138351932FA05468DE9A922953DF5AB791406E89F752A378A0D98A957773EC3B952DAE04200C1944F30B43D80450F8F83AC4F688D806DE9C9C406D30FC0D9098BE612EF0C4AD2E80B2C746944C727A1015538A53C69280EE0F00D6601CAA6CB0EAF4D3DADBF849D4C1F8F1FD7D438619C70364DACE44085868798D86EA3
-20220415023006 2 6 100 6143 5 ECFEBE907ED5229E0F2A017AAC2F662065526E4CD6767D11B9BC47C5C4D0E39E232885C9039387645B0C61FC91A5B5F97A3A3264DC42DD48A30C3E923D467D8CDDD98F0DE77067BFB45F466CA03EC5B86BF836D9C6298948D315FF4627FE23F62CE3E722A3B60F7D9D6F97D4B10E30924ABF0E094D5155F57DFBD93B17A3E958816225D458E063A4785F4D04A131D6C3AEFF9B405648DC2E0A64F061AB428E6C3B69C65266514A729829756E016CF55D1A917D9CE64ECEA6EB081A85F177BDEED9062CA130A23BB3D90817644F84890C55BB158DA2C0F590826B7073E933EC081268331D56BFB282D4DA250EC39EF3E477BAC8E5B64B712F4457C5B116D0D491AC7AF0E68F3337A51AADA71152604FF386C9CCB4F67204F6A2FBDBE18E5AF591DDA0B5A93382BC210A549262C0A250EF2CB3D3009C4EA412324E359DBEFF97ADA37287D08C11ED12B170B06B8055BC5B17B3F464BFDE141A145A6393750FE9D5EF33C33A43B575091076A24A9E67C56C7B41F023C42166C89E57D001E9161E924A693FD3712355AD60EAC3BD8AC16BA15F5BEABEE3D014B7F5361D7EB36B3F594E1BB98F6813A2D88FD6FC9F008713334AE962B0CB4C07FDB32D549C0F24D127486707C29A7F5EC7F8601961D2E4C189BA3129E48D0D2215E70D9115AAD993E78565715E50EA0E336EA456D469A23368CFB3F0ED6B8AC77738B2A2AC0A7F155CF6D402687212585A2DD9EEAAF614387C7C8D3089D3F42DBD1A594233ABB618AAD84D52F8A234281F2B0F62E3FE23B1E7F28DD89F6F79572506F9B02021CE44914237C190C82F1E5CB395844550EF279E9B50FA1D5B7AE84FE9F31538546244BD4C86FDADB5974396692A7BBE7AD493834DD13418929F8EA0F44BBF8E3D9DFCEF170DF138351932FA05468DE9A922953DF5AB791406E89F752A378A0D98A957773EC3B952DAE04200C1944F30B43D80450F8F83AC4F688D806DE9C9C406D30FC0D9098BE612EF0C4AD2E80B2C746944C727A1015538A53C69280EE0F00D6601CAA6CB0EAF4D3DADBF849D4C1F8F1FD7D438619C70364DACE4408586879B22E39F
-20220415030146 2 6 100 6143 5 ECFEBE907ED5229E0F2A017AAC2F662065526E4CD6767D11B9BC47C5C4D0E39E232885C9039387645B0C61FC91A5B5F97A3A3264DC42DD48A30C3E923D467D8CDDD98F0DE77067BFB45F466CA03EC5B86BF836D9C6298948D315FF4627FE23F62CE3E722A3B60F7D9D6F97D4B10E30924ABF0E094D5155F57DFBD93B17A3E958816225D458E063A4785F4D04A131D6C3AEFF9B405648DC2E0A64F061AB428E6C3B69C65266514A729829756E016CF55D1A917D9CE64ECEA6EB081A85F177BDEED9062CA130A23BB3D90817644F84890C55BB158DA2C0F590826B7073E933EC081268331D56BFB282D4DA250EC39EF3E477BAC8E5B64B712F4457C5B116D0D491AC7AF0E68F3337A51AADA71152604FF386C9CCB4F67204F6A2FBDBE18E5AF591DDA0B5A93382BC210A549262C0A250EF2CB3D3009C4EA412324E359DBEFF97ADA37287D08C11ED12B170B06B8055BC5B17B3F464BFDE141A145A6393750FE9D5EF33C33A43B575091076A24A9E67C56C7B41F023C42166C89E57D001E9161E924A693FD3712355AD60EAC3BD8AC16BA15F5BEABEE3D014B7F5361D7EB36B3F594E1BB98F6813A2D88FD6FC9F008713334AE962B0CB4C07FDB32D549C0F24D127486707C29A7F5EC7F8601961D2E4C189BA3129E48D0D2215E70D9115AAD993E78565715E50EA0E336EA456D469A23368CFB3F0ED6B8AC77738B2A2AC0A7F155CF6D402687212585A2DD9EEAAF614387C7C8D3089D3F42DBD1A594233ABB618AAD84D52F8A234281F2B0F62E3FE23B1E7F28DD89F6F79572506F9B02021CE44914237C190C82F1E5CB395844550EF279E9B50FA1D5B7AE84FE9F31538546244BD4C86FDADB5974396692A7BBE7AD493834DD13418929F8EA0F44BBF8E3D9DFCEF170DF138351932FA05468DE9A922953DF5AB791406E89F752A378A0D98A957773EC3B952DAE04200C1944F30B43D80450F8F83AC4F688D806DE9C9C406D30FC0D9098BE612EF0C4AD2E80B2C746944C727A1015538A53C69280EE0F00D6601CAA6CB0EAF4D3DADBF849D4C1F8F1FD7D438619C70364DACE4408586879F87F92F
-20220415031549 2 6 100 6143 2 ECFEBE907ED5229E0F2A017AAC2F662065526E4CD6767D11B9BC47C5C4D0E39E232885C9039387645B0C61FC91A5B5F97A3A3264DC42DD48A30C3E923D467D8CDDD98F0DE77067BFB45F466CA03EC5B86BF836D9C6298948D315FF4627FE23F62CE3E722A3B60F7D9D6F97D4B10E30924ABF0E094D5155F57DFBD93B17A3E958816225D458E063A4785F4D04A131D6C3AEFF9B405648DC2E0A64F061AB428E6C3B69C65266514A729829756E016CF55D1A917D9CE64ECEA6EB081A85F177BDEED9062CA130A23BB3D90817644F84890C55BB158DA2C0F590826B7073E933EC081268331D56BFB282D4DA250EC39EF3E477BAC8E5B64B712F4457C5B116D0D491AC7AF0E68F3337A51AADA71152604FF386C9CCB4F67204F6A2FBDBE18E5AF591DDA0B5A93382BC210A549262C0A250EF2CB3D3009C4EA412324E359DBEFF97ADA37287D08C11ED12B170B06B8055BC5B17B3F464BFDE141A145A6393750FE9D5EF33C33A43B575091076A24A9E67C56C7B41F023C42166C89E57D001E9161E924A693FD3712355AD60EAC3BD8AC16BA15F5BEABEE3D014B7F5361D7EB36B3F594E1BB98F6813A2D88FD6FC9F008713334AE962B0CB4C07FDB32D549C0F24D127486707C29A7F5EC7F8601961D2E4C189BA3129E48D0D2215E70D9115AAD993E78565715E50EA0E336EA456D469A23368CFB3F0ED6B8AC77738B2A2AC0A7F155CF6D402687212585A2DD9EEAAF614387C7C8D3089D3F42DBD1A594233ABB618AAD84D52F8A234281F2B0F62E3FE23B1E7F28DD89F6F79572506F9B02021CE44914237C190C82F1E5CB395844550EF279E9B50FA1D5B7AE84FE9F31538546244BD4C86FDADB5974396692A7BBE7AD493834DD13418929F8EA0F44BBF8E3D9DFCEF170DF138351932FA05468DE9A922953DF5AB791406E89F752A378A0D98A957773EC3B952DAE04200C1944F30B43D80450F8F83AC4F688D806DE9C9C406D30FC0D9098BE612EF0C4AD2E80B2C746944C727A1015538A53C69280EE0F00D6601CAA6CB0EAF4D3DADBF849D4C1F8F1FD7D438619C70364DACE440858687A169CCAB
-20220415040641 2 6 100 6143 5 ECFEBE907ED5229E0F2A017AAC2F662065526E4CD6767D11B9BC47C5C4D0E39E232885C9039387645B0C61FC91A5B5F97A3A3264DC42DD48A30C3E923D467D8CDDD98F0DE77067BFB45F466CA03EC5B86BF836D9C6298948D315FF4627FE23F62CE3E722A3B60F7D9D6F97D4B10E30924ABF0E094D5155F57DFBD93B17A3E958816225D458E063A4785F4D04A131D6C3AEFF9B405648DC2E0A64F061AB428E6C3B69C65266514A729829756E016CF55D1A917D9CE64ECEA6EB081A85F177BDEED9062CA130A23BB3D90817644F84890C55BB158DA2C0F590826B7073E933EC081268331D56BFB282D4DA250EC39EF3E477BAC8E5B64B712F4457C5B116D0D491AC7AF0E68F3337A51AADA71152604FF386C9CCB4F67204F6A2FBDBE18E5AF591DDA0B5A93382BC210A549262C0A250EF2CB3D3009C4EA412324E359DBEFF97ADA37287D08C11ED12B170B06B8055BC5B17B3F464BFDE141A145A6393750FE9D5EF33C33A43B575091076A24A9E67C56C7B41F023C42166C89E57D001E9161E924A693FD3712355AD60EAC3BD8AC16BA15F5BEABEE3D014B7F5361D7EB36B3F594E1BB98F6813A2D88FD6FC9F008713334AE962B0CB4C07FDB32D549C0F24D127486707C29A7F5EC7F8601961D2E4C189BA3129E48D0D2215E70D9115AAD993E78565715E50EA0E336EA456D469A23368CFB3F0ED6B8AC77738B2A2AC0A7F155CF6D402687212585A2DD9EEAAF614387C7C8D3089D3F42DBD1A594233ABB618AAD84D52F8A234281F2B0F62E3FE23B1E7F28DD89F6F79572506F9B02021CE44914237C190C82F1E5CB395844550EF279E9B50FA1D5B7AE84FE9F31538546244BD4C86FDADB5974396692A7BBE7AD493834DD13418929F8EA0F44BBF8E3D9DFCEF170DF138351932FA05468DE9A922953DF5AB791406E89F752A378A0D98A957773EC3B952DAE04200C1944F30B43D80450F8F83AC4F688D806DE9C9C406D30FC0D9098BE612EF0C4AD2E80B2C746944C727A1015538A53C69280EE0F00D6601CAA6CB0EAF4D3DADBF849D4C1F8F1FD7D438619C70364DACE440858687A85F5E8F
-20220415055156 2 6 100 7679 2 D73E4A149D00067AF38F615C7920E3E58F83FDF73F493F4712369137702E94062D5E0857DA1D94CE7C7660F89D285B5DF0F8FC8A8CD2FF69819BED74B0F05EAA467BA2CB1337A7F6E9EE06670C393AD6C845C1743F511BEE7ED9D65AA1BF3FD41BD6F0EF131358CCEE448D0EFEE47EF75D3F4AA2FE7A70210CE62E2C6F791BCBB4852CDF41C5EF6B481ABB954A6AB79AB82ABC543C6CF66F971F590ECA63988A886308218202016278C80C8F7142E1CC482FCFC313123AAD101AF837EB8A210CE3522F0554FE4A00C29E51510678F9DAB40C21A644BC9237D982C24AD1788C3D20F6520144B491C77DB1C53CE98726DCF09DBD1978573CF32848096B44A72CEF3221D98C44BB32A524549A20D822F5531D7E7875B1B564ABDE9EE100A90A8E51B37EAEAE3E89E3E8348F3BC9D8FD284E0FA829406C5D8CE0826CB3EAD353B6052B9C7FC1CD4967090AFE5F2BC11B3280C93278A1396AFC640AD8AFE9101965306601723E689714C3190C41C4D4635F1541241F452C981A5F574DCE109014A274CDBA4CE6AD7C693AA7D3F18418AA4F1487E657858DF460D53BD835685581BB461310DAF203B67C23E0C17ADCD024033C40EEF27957151D01971F43254C6C4E3D86F6ACADB8BCDDCB300A21FEAA54E59A547C9C06ABA312A5B4736356230580FBCACD3FB08626BD622934B81B8697291C6DCB1124F7A6762DB30B9CFA22A92FEC007E7EDBB188F34755C350A884DE8890D0E5D6F491D9C23D951DEBADCB26E1D25D971F5FD23FFA0BCAA84646352DCA69C7A3BB991961E762E96C48E58A2F8FA52DE7CD9FE7C529289A73E13032154349ECA5CCCB3D5B89980B29872AC5B03EBAA726CFD9790AF85E371F0A5B0588E4874EA300C5A370ED42A97C6E372D1DB9825EA995C0B5FABFEC09A632010EE138E8E35794640D65CA647ECDDC20A4D453CA4C35EE78350A8045B3CAD6CF41D3DF5260E355EB03E819C0068C91C2F530F7C74F680386947FE3FD00C91C5CEB7D0AF97DDC251DE856355D16F7CE88E69B20BB20BDB3204C63EC00277B7D5DC9A77682DE0750EBFF7313289998DE1C6E940F0B172A173531140FDA7A3422FB739F8F1647907355B26C37A47EC420791F68C61CC7A55CA855DE158B43D0DB363153AB9F0DEEC632AE784F62775862C4319971738352448A4D653C1CD7380247C05D56198D19720CB284E6CBF137616D8DB5510FBE81A7F646E5356C998B56125895D10ECAE67FD4CCD73FA78ACAA774DB11BBD5314ABDA3DA139107FCD342BA6CBB9BDCBED536411BD50B38F7234511CE74B1362D07BF71DBD033E6F637C45FB0B25871B173BCE2337D963AD41693E02A82E93B
-20220415055855 2 6 100 7679 2 D73E4A149D00067AF38F615C7920E3E58F83FDF73F493F4712369137702E94062D5E0857DA1D94CE7C7660F89D285B5DF0F8FC8A8CD2FF69819BED74B0F05EAA467BA2CB1337A7F6E9EE06670C393AD6C845C1743F511BEE7ED9D65AA1BF3FD41BD6F0EF131358CCEE448D0EFEE47EF75D3F4AA2FE7A70210CE62E2C6F791BCBB4852CDF41C5EF6B481ABB954A6AB79AB82ABC543C6CF66F971F590ECA63988A886308218202016278C80C8F7142E1CC482FCFC313123AAD101AF837EB8A210CE3522F0554FE4A00C29E51510678F9DAB40C21A644BC9237D982C24AD1788C3D20F6520144B491C77DB1C53CE98726DCF09DBD1978573CF32848096B44A72CEF3221D98C44BB32A524549A20D822F5531D7E7875B1B564ABDE9EE100A90A8E51B37EAEAE3E89E3E8348F3BC9D8FD284E0FA829406C5D8CE0826CB3EAD353B6052B9C7FC1CD4967090AFE5F2BC11B3280C93278A1396AFC640AD8AFE9101965306601723E689714C3190C41C4D4635F1541241F452C981A5F574DCE109014A274CDBA4CE6AD7C693AA7D3F18418AA4F1487E657858DF460D53BD835685581BB461310DAF203B67C23E0C17ADCD024033C40EEF27957151D01971F43254C6C4E3D86F6ACADB8BCDDCB300A21FEAA54E59A547C9C06ABA312A5B4736356230580FBCACD3FB08626BD622934B81B8697291C6DCB1124F7A6762DB30B9CFA22A92FEC007E7EDBB188F34755C350A884DE8890D0E5D6F491D9C23D951DEBADCB26E1D25D971F5FD23FFA0BCAA84646352DCA69C7A3BB991961E762E96C48E58A2F8FA52DE7CD9FE7C529289A73E13032154349ECA5CCCB3D5B89980B29872AC5B03EBAA726CFD9790AF85E371F0A5B0588E4874EA300C5A370ED42A97C6E372D1DB9825EA995C0B5FABFEC09A632010EE138E8E35794640D65CA647ECDDC20A4D453CA4C35EE78350A8045B3CAD6CF41D3DF5260E355EB03E819C0068C91C2F530F7C74F680386947FE3FD00C91C5CEB7D0AF97DDC251DE856355D16F7CE88E69B20BB20BDB3204C63EC00277B7D5DC9A77682DE0750EBFF7313289998DE1C6E940F0B172A173531140FDA7A3422FB739F8F1647907355B26C37A47EC420791F68C61CC7A55CA855DE158B43D0DB363153AB9F0DEEC632AE784F62775862C4319971738352448A4D653C1CD7380247C05D56198D19720CB284E6CBF137616D8DB5510FBE81A7F646E5356C998B56125895D10ECAE67FD4CCD73FA78ACAA774DB11BBD5314ABDA3DA139107FCD342BA6CBB9BDCBED536411BD50B38F7234511CE74B1362D07BF71DBD033E6F637C45FB0B25871B173BCE2337D963AD41693E02B0AF64B
-20220415080431 2 6 100 7679 2 D73E4A149D00067AF38F615C7920E3E58F83FDF73F493F4712369137702E94062D5E0857DA1D94CE7C7660F89D285B5DF0F8FC8A8CD2FF69819BED74B0F05EAA467BA2CB1337A7F6E9EE06670C393AD6C845C1743F511BEE7ED9D65AA1BF3FD41BD6F0EF131358CCEE448D0EFEE47EF75D3F4AA2FE7A70210CE62E2C6F791BCBB4852CDF41C5EF6B481ABB954A6AB79AB82ABC543C6CF66F971F590ECA63988A886308218202016278C80C8F7142E1CC482FCFC313123AAD101AF837EB8A210CE3522F0554FE4A00C29E51510678F9DAB40C21A644BC9237D982C24AD1788C3D20F6520144B491C77DB1C53CE98726DCF09DBD1978573CF32848096B44A72CEF3221D98C44BB32A524549A20D822F5531D7E7875B1B564ABDE9EE100A90A8E51B37EAEAE3E89E3E8348F3BC9D8FD284E0FA829406C5D8CE0826CB3EAD353B6052B9C7FC1CD4967090AFE5F2BC11B3280C93278A1396AFC640AD8AFE9101965306601723E689714C3190C41C4D4635F1541241F452C981A5F574DCE109014A274CDBA4CE6AD7C693AA7D3F18418AA4F1487E657858DF460D53BD835685581BB461310DAF203B67C23E0C17ADCD024033C40EEF27957151D01971F43254C6C4E3D86F6ACADB8BCDDCB300A21FEAA54E59A547C9C06ABA312A5B4736356230580FBCACD3FB08626BD622934B81B8697291C6DCB1124F7A6762DB30B9CFA22A92FEC007E7EDBB188F34755C350A884DE8890D0E5D6F491D9C23D951DEBADCB26E1D25D971F5FD23FFA0BCAA84646352DCA69C7A3BB991961E762E96C48E58A2F8FA52DE7CD9FE7C529289A73E13032154349ECA5CCCB3D5B89980B29872AC5B03EBAA726CFD9790AF85E371F0A5B0588E4874EA300C5A370ED42A97C6E372D1DB9825EA995C0B5FABFEC09A632010EE138E8E35794640D65CA647ECDDC20A4D453CA4C35EE78350A8045B3CAD6CF41D3DF5260E355EB03E819C0068C91C2F530F7C74F680386947FE3FD00C91C5CEB7D0AF97DDC251DE856355D16F7CE88E69B20BB20BDB3204C63EC00277B7D5DC9A77682DE0750EBFF7313289998DE1C6E940F0B172A173531140FDA7A3422FB739F8F1647907355B26C37A47EC420791F68C61CC7A55CA855DE158B43D0DB363153AB9F0DEEC632AE784F62775862C4319971738352448A4D653C1CD7380247C05D56198D19720CB284E6CBF137616D8DB5510FBE81A7F646E5356C998B56125895D10ECAE67FD4CCD73FA78ACAA774DB11BBD5314ABDA3DA139107FCD342BA6CBB9BDCBED536411BD50B38F7234511CE74B1362D07BF71DBD033E6F637C45FB0B25871B173BCE2337D963AD41693E0357CD26B
-20220415104028 2 6 100 7679 2 D73E4A149D00067AF38F615C7920E3E58F83FDF73F493F4712369137702E94062D5E0857DA1D94CE7C7660F89D285B5DF0F8FC8A8CD2FF69819BED74B0F05EAA467BA2CB1337A7F6E9EE06670C393AD6C845C1743F511BEE7ED9D65AA1BF3FD41BD6F0EF131358CCEE448D0EFEE47EF75D3F4AA2FE7A70210CE62E2C6F791BCBB4852CDF41C5EF6B481ABB954A6AB79AB82ABC543C6CF66F971F590ECA63988A886308218202016278C80C8F7142E1CC482FCFC313123AAD101AF837EB8A210CE3522F0554FE4A00C29E51510678F9DAB40C21A644BC9237D982C24AD1788C3D20F6520144B491C77DB1C53CE98726DCF09DBD1978573CF32848096B44A72CEF3221D98C44BB32A524549A20D822F5531D7E7875B1B564ABDE9EE100A90A8E51B37EAEAE3E89E3E8348F3BC9D8FD284E0FA829406C5D8CE0826CB3EAD353B6052B9C7FC1CD4967090AFE5F2BC11B3280C93278A1396AFC640AD8AFE9101965306601723E689714C3190C41C4D4635F1541241F452C981A5F574DCE109014A274CDBA4CE6AD7C693AA7D3F18418AA4F1487E657858DF460D53BD835685581BB461310DAF203B67C23E0C17ADCD024033C40EEF27957151D01971F43254C6C4E3D86F6ACADB8BCDDCB300A21FEAA54E59A547C9C06ABA312A5B4736356230580FBCACD3FB08626BD622934B81B8697291C6DCB1124F7A6762DB30B9CFA22A92FEC007E7EDBB188F34755C350A884DE8890D0E5D6F491D9C23D951DEBADCB26E1D25D971F5FD23FFA0BCAA84646352DCA69C7A3BB991961E762E96C48E58A2F8FA52DE7CD9FE7C529289A73E13032154349ECA5CCCB3D5B89980B29872AC5B03EBAA726CFD9790AF85E371F0A5B0588E4874EA300C5A370ED42A97C6E372D1DB9825EA995C0B5FABFEC09A632010EE138E8E35794640D65CA647ECDDC20A4D453CA4C35EE78350A8045B3CAD6CF41D3DF5260E355EB03E819C0068C91C2F530F7C74F680386947FE3FD00C91C5CEB7D0AF97DDC251DE856355D16F7CE88E69B20BB20BDB3204C63EC00277B7D5DC9A77682DE0750EBFF7313289998DE1C6E940F0B172A173531140FDA7A3422FB739F8F1647907355B26C37A47EC420791F68C61CC7A55CA855DE158B43D0DB363153AB9F0DEEC632AE784F62775862C4319971738352448A4D653C1CD7380247C05D56198D19720CB284E6CBF137616D8DB5510FBE81A7F646E5356C998B56125895D10ECAE67FD4CCD73FA78ACAA774DB11BBD5314ABDA3DA139107FCD342BA6CBB9BDCBED536411BD50B38F7234511CE74B1362D07BF71DBD033E6F637C45FB0B25871B173BCE2337D963AD41693E0420DED43
-20220415110553 2 6 100 7679 2 D73E4A149D00067AF38F615C7920E3E58F83FDF73F493F4712369137702E94062D5E0857DA1D94CE7C7660F89D285B5DF0F8FC8A8CD2FF69819BED74B0F05EAA467BA2CB1337A7F6E9EE06670C393AD6C845C1743F511BEE7ED9D65AA1BF3FD41BD6F0EF131358CCEE448D0EFEE47EF75D3F4AA2FE7A70210CE62E2C6F791BCBB4852CDF41C5EF6B481ABB954A6AB79AB82ABC543C6CF66F971F590ECA63988A886308218202016278C80C8F7142E1CC482FCFC313123AAD101AF837EB8A210CE3522F0554FE4A00C29E51510678F9DAB40C21A644BC9237D982C24AD1788C3D20F6520144B491C77DB1C53CE98726DCF09DBD1978573CF32848096B44A72CEF3221D98C44BB32A524549A20D822F5531D7E7875B1B564ABDE9EE100A90A8E51B37EAEAE3E89E3E8348F3BC9D8FD284E0FA829406C5D8CE0826CB3EAD353B6052B9C7FC1CD4967090AFE5F2BC11B3280C93278A1396AFC640AD8AFE9101965306601723E689714C3190C41C4D4635F1541241F452C981A5F574DCE109014A274CDBA4CE6AD7C693AA7D3F18418AA4F1487E657858DF460D53BD835685581BB461310DAF203B67C23E0C17ADCD024033C40EEF27957151D01971F43254C6C4E3D86F6ACADB8BCDDCB300A21FEAA54E59A547C9C06ABA312A5B4736356230580FBCACD3FB08626BD622934B81B8697291C6DCB1124F7A6762DB30B9CFA22A92FEC007E7EDBB188F34755C350A884DE8890D0E5D6F491D9C23D951DEBADCB26E1D25D971F5FD23FFA0BCAA84646352DCA69C7A3BB991961E762E96C48E58A2F8FA52DE7CD9FE7C529289A73E13032154349ECA5CCCB3D5B89980B29872AC5B03EBAA726CFD9790AF85E371F0A5B0588E4874EA300C5A370ED42A97C6E372D1DB9825EA995C0B5FABFEC09A632010EE138E8E35794640D65CA647ECDDC20A4D453CA4C35EE78350A8045B3CAD6CF41D3DF5260E355EB03E819C0068C91C2F530F7C74F680386947FE3FD00C91C5CEB7D0AF97DDC251DE856355D16F7CE88E69B20BB20BDB3204C63EC00277B7D5DC9A77682DE0750EBFF7313289998DE1C6E940F0B172A173531140FDA7A3422FB739F8F1647907355B26C37A47EC420791F68C61CC7A55CA855DE158B43D0DB363153AB9F0DEEC632AE784F62775862C4319971738352448A4D653C1CD7380247C05D56198D19720CB284E6CBF137616D8DB5510FBE81A7F646E5356C998B56125895D10ECAE67FD4CCD73FA78ACAA774DB11BBD5314ABDA3DA139107FCD342BA6CBB9BDCBED536411BD50B38F7234511CE74B1362D07BF71DBD033E6F637C45FB0B25871B173BCE2337D963AD41693E0440C48AB
-20220415113849 2 6 100 7679 2 D73E4A149D00067AF38F615C7920E3E58F83FDF73F493F4712369137702E94062D5E0857DA1D94CE7C7660F89D285B5DF0F8FC8A8CD2FF69819BED74B0F05EAA467BA2CB1337A7F6E9EE06670C393AD6C845C1743F511BEE7ED9D65AA1BF3FD41BD6F0EF131358CCEE448D0EFEE47EF75D3F4AA2FE7A70210CE62E2C6F791BCBB4852CDF41C5EF6B481ABB954A6AB79AB82ABC543C6CF66F971F590ECA63988A886308218202016278C80C8F7142E1CC482FCFC313123AAD101AF837EB8A210CE3522F0554FE4A00C29E51510678F9DAB40C21A644BC9237D982C24AD1788C3D20F6520144B491C77DB1C53CE98726DCF09DBD1978573CF32848096B44A72CEF3221D98C44BB32A524549A20D822F5531D7E7875B1B564ABDE9EE100A90A8E51B37EAEAE3E89E3E8348F3BC9D8FD284E0FA829406C5D8CE0826CB3EAD353B6052B9C7FC1CD4967090AFE5F2BC11B3280C93278A1396AFC640AD8AFE9101965306601723E689714C3190C41C4D4635F1541241F452C981A5F574DCE109014A274CDBA4CE6AD7C693AA7D3F18418AA4F1487E657858DF460D53BD835685581BB461310DAF203B67C23E0C17ADCD024033C40EEF27957151D01971F43254C6C4E3D86F6ACADB8BCDDCB300A21FEAA54E59A547C9C06ABA312A5B4736356230580FBCACD3FB08626BD622934B81B8697291C6DCB1124F7A6762DB30B9CFA22A92FEC007E7EDBB188F34755C350A884DE8890D0E5D6F491D9C23D951DEBADCB26E1D25D971F5FD23FFA0BCAA84646352DCA69C7A3BB991961E762E96C48E58A2F8FA52DE7CD9FE7C529289A73E13032154349ECA5CCCB3D5B89980B29872AC5B03EBAA726CFD9790AF85E371F0A5B0588E4874EA300C5A370ED42A97C6E372D1DB9825EA995C0B5FABFEC09A632010EE138E8E35794640D65CA647ECDDC20A4D453CA4C35EE78350A8045B3CAD6CF41D3DF5260E355EB03E819C0068C91C2F530F7C74F680386947FE3FD00C91C5CEB7D0AF97DDC251DE856355D16F7CE88E69B20BB20BDB3204C63EC00277B7D5DC9A77682DE0750EBFF7313289998DE1C6E940F0B172A173531140FDA7A3422FB739F8F1647907355B26C37A47EC420791F68C61CC7A55CA855DE158B43D0DB363153AB9F0DEEC632AE784F62775862C4319971738352448A4D653C1CD7380247C05D56198D19720CB284E6CBF137616D8DB5510FBE81A7F646E5356C998B56125895D10ECAE67FD4CCD73FA78ACAA774DB11BBD5314ABDA3DA139107FCD342BA6CBB9BDCBED536411BD50B38F7234511CE74B1362D07BF71DBD033E6F637C45FB0B25871B173BCE2337D963AD41693E0469931F3
-20220415122158 2 6 100 7679 2 D73E4A149D00067AF38F615C7920E3E58F83FDF73F493F4712369137702E94062D5E0857DA1D94CE7C7660F89D285B5DF0F8FC8A8CD2FF69819BED74B0F05EAA467BA2CB1337A7F6E9EE06670C393AD6C845C1743F511BEE7ED9D65AA1BF3FD41BD6F0EF131358CCEE448D0EFEE47EF75D3F4AA2FE7A70210CE62E2C6F791BCBB4852CDF41C5EF6B481ABB954A6AB79AB82ABC543C6CF66F971F590ECA63988A886308218202016278C80C8F7142E1CC482FCFC313123AAD101AF837EB8A210CE3522F0554FE4A00C29E51510678F9DAB40C21A644BC9237D982C24AD1788C3D20F6520144B491C77DB1C53CE98726DCF09DBD1978573CF32848096B44A72CEF3221D98C44BB32A524549A20D822F5531D7E7875B1B564ABDE9EE100A90A8E51B37EAEAE3E89E3E8348F3BC9D8FD284E0FA829406C5D8CE0826CB3EAD353B6052B9C7FC1CD4967090AFE5F2BC11B3280C93278A1396AFC640AD8AFE9101965306601723E689714C3190C41C4D4635F1541241F452C981A5F574DCE109014A274CDBA4CE6AD7C693AA7D3F18418AA4F1487E657858DF460D53BD835685581BB461310DAF203B67C23E0C17ADCD024033C40EEF27957151D01971F43254C6C4E3D86F6ACADB8BCDDCB300A21FEAA54E59A547C9C06ABA312A5B4736356230580FBCACD3FB08626BD622934B81B8697291C6DCB1124F7A6762DB30B9CFA22A92FEC007E7EDBB188F34755C350A884DE8890D0E5D6F491D9C23D951DEBADCB26E1D25D971F5FD23FFA0BCAA84646352DCA69C7A3BB991961E762E96C48E58A2F8FA52DE7CD9FE7C529289A73E13032154349ECA5CCCB3D5B89980B29872AC5B03EBAA726CFD9790AF85E371F0A5B0588E4874EA300C5A370ED42A97C6E372D1DB9825EA995C0B5FABFEC09A632010EE138E8E35794640D65CA647ECDDC20A4D453CA4C35EE78350A8045B3CAD6CF41D3DF5260E355EB03E819C0068C91C2F530F7C74F680386947FE3FD00C91C5CEB7D0AF97DDC251DE856355D16F7CE88E69B20BB20BDB3204C63EC00277B7D5DC9A77682DE0750EBFF7313289998DE1C6E940F0B172A173531140FDA7A3422FB739F8F1647907355B26C37A47EC420791F68C61CC7A55CA855DE158B43D0DB363153AB9F0DEEC632AE784F62775862C4319971738352448A4D653C1CD7380247C05D56198D19720CB284E6CBF137616D8DB5510FBE81A7F646E5356C998B56125895D10ECAE67FD4CCD73FA78ACAA774DB11BBD5314ABDA3DA139107FCD342BA6CBB9BDCBED536411BD50B38F7234511CE74B1362D07BF71DBD033E6F637C45FB0B25871B173BCE2337D963AD41693E04A10FEC3
-20220415125947 2 6 100 7679 2 D73E4A149D00067AF38F615C7920E3E58F83FDF73F493F4712369137702E94062D5E0857DA1D94CE7C7660F89D285B5DF0F8FC8A8CD2FF69819BED74B0F05EAA467BA2CB1337A7F6E9EE06670C393AD6C845C1743F511BEE7ED9D65AA1BF3FD41BD6F0EF131358CCEE448D0EFEE47EF75D3F4AA2FE7A70210CE62E2C6F791BCBB4852CDF41C5EF6B481ABB954A6AB79AB82ABC543C6CF66F971F590ECA63988A886308218202016278C80C8F7142E1CC482FCFC313123AAD101AF837EB8A210CE3522F0554FE4A00C29E51510678F9DAB40C21A644BC9237D982C24AD1788C3D20F6520144B491C77DB1C53CE98726DCF09DBD1978573CF32848096B44A72CEF3221D98C44BB32A524549A20D822F5531D7E7875B1B564ABDE9EE100A90A8E51B37EAEAE3E89E3E8348F3BC9D8FD284E0FA829406C5D8CE0826CB3EAD353B6052B9C7FC1CD4967090AFE5F2BC11B3280C93278A1396AFC640AD8AFE9101965306601723E689714C3190C41C4D4635F1541241F452C981A5F574DCE109014A274CDBA4CE6AD7C693AA7D3F18418AA4F1487E657858DF460D53BD835685581BB461310DAF203B67C23E0C17ADCD024033C40EEF27957151D01971F43254C6C4E3D86F6ACADB8BCDDCB300A21FEAA54E59A547C9C06ABA312A5B4736356230580FBCACD3FB08626BD622934B81B8697291C6DCB1124F7A6762DB30B9CFA22A92FEC007E7EDBB188F34755C350A884DE8890D0E5D6F491D9C23D951DEBADCB26E1D25D971F5FD23FFA0BCAA84646352DCA69C7A3BB991961E762E96C48E58A2F8FA52DE7CD9FE7C529289A73E13032154349ECA5CCCB3D5B89980B29872AC5B03EBAA726CFD9790AF85E371F0A5B0588E4874EA300C5A370ED42A97C6E372D1DB9825EA995C0B5FABFEC09A632010EE138E8E35794640D65CA647ECDDC20A4D453CA4C35EE78350A8045B3CAD6CF41D3DF5260E355EB03E819C0068C91C2F530F7C74F680386947FE3FD00C91C5CEB7D0AF97DDC251DE856355D16F7CE88E69B20BB20BDB3204C63EC00277B7D5DC9A77682DE0750EBFF7313289998DE1C6E940F0B172A173531140FDA7A3422FB739F8F1647907355B26C37A47EC420791F68C61CC7A55CA855DE158B43D0DB363153AB9F0DEEC632AE784F62775862C4319971738352448A4D653C1CD7380247C05D56198D19720CB284E6CBF137616D8DB5510FBE81A7F646E5356C998B56125895D10ECAE67FD4CCD73FA78ACAA774DB11BBD5314ABDA3DA139107FCD342BA6CBB9BDCBED536411BD50B38F7234511CE74B1362D07BF71DBD033E6F637C45FB0B25871B173BCE2337D963AD41693E04CFE8C63
-20220415130450 2 6 100 7679 5 D73E4A149D00067AF38F615C7920E3E58F83FDF73F493F4712369137702E94062D5E0857DA1D94CE7C7660F89D285B5DF0F8FC8A8CD2FF69819BED74B0F05EAA467BA2CB1337A7F6E9EE06670C393AD6C845C1743F511BEE7ED9D65AA1BF3FD41BD6F0EF131358CCEE448D0EFEE47EF75D3F4AA2FE7A70210CE62E2C6F791BCBB4852CDF41C5EF6B481ABB954A6AB79AB82ABC543C6CF66F971F590ECA63988A886308218202016278C80C8F7142E1CC482FCFC313123AAD101AF837EB8A210CE3522F0554FE4A00C29E51510678F9DAB40C21A644BC9237D982C24AD1788C3D20F6520144B491C77DB1C53CE98726DCF09DBD1978573CF32848096B44A72CEF3221D98C44BB32A524549A20D822F5531D7E7875B1B564ABDE9EE100A90A8E51B37EAEAE3E89E3E8348F3BC9D8FD284E0FA829406C5D8CE0826CB3EAD353B6052B9C7FC1CD4967090AFE5F2BC11B3280C93278A1396AFC640AD8AFE9101965306601723E689714C3190C41C4D4635F1541241F452C981A5F574DCE109014A274CDBA4CE6AD7C693AA7D3F18418AA4F1487E657858DF460D53BD835685581BB461310DAF203B67C23E0C17ADCD024033C40EEF27957151D01971F43254C6C4E3D86F6ACADB8BCDDCB300A21FEAA54E59A547C9C06ABA312A5B4736356230580FBCACD3FB08626BD622934B81B8697291C6DCB1124F7A6762DB30B9CFA22A92FEC007E7EDBB188F34755C350A884DE8890D0E5D6F491D9C23D951DEBADCB26E1D25D971F5FD23FFA0BCAA84646352DCA69C7A3BB991961E762E96C48E58A2F8FA52DE7CD9FE7C529289A73E13032154349ECA5CCCB3D5B89980B29872AC5B03EBAA726CFD9790AF85E371F0A5B0588E4874EA300C5A370ED42A97C6E372D1DB9825EA995C0B5FABFEC09A632010EE138E8E35794640D65CA647ECDDC20A4D453CA4C35EE78350A8045B3CAD6CF41D3DF5260E355EB03E819C0068C91C2F530F7C74F680386947FE3FD00C91C5CEB7D0AF97DDC251DE856355D16F7CE88E69B20BB20BDB3204C63EC00277B7D5DC9A77682DE0750EBFF7313289998DE1C6E940F0B172A173531140FDA7A3422FB739F8F1647907355B26C37A47EC420791F68C61CC7A55CA855DE158B43D0DB363153AB9F0DEEC632AE784F62775862C4319971738352448A4D653C1CD7380247C05D56198D19720CB284E6CBF137616D8DB5510FBE81A7F646E5356C998B56125895D10ECAE67FD4CCD73FA78ACAA774DB11BBD5314ABDA3DA139107FCD342BA6CBB9BDCBED536411BD50B38F7234511CE74B1362D07BF71DBD033E6F637C45FB0B25871B173BCE2337D963AD41693E04D5A7257
-20220415133311 2 6 100 7679 2 D73E4A149D00067AF38F615C7920E3E58F83FDF73F493F4712369137702E94062D5E0857DA1D94CE7C7660F89D285B5DF0F8FC8A8CD2FF69819BED74B0F05EAA467BA2CB1337A7F6E9EE06670C393AD6C845C1743F511BEE7ED9D65AA1BF3FD41BD6F0EF131358CCEE448D0EFEE47EF75D3F4AA2FE7A70210CE62E2C6F791BCBB4852CDF41C5EF6B481ABB954A6AB79AB82ABC543C6CF66F971F590ECA63988A886308218202016278C80C8F7142E1CC482FCFC313123AAD101AF837EB8A210CE3522F0554FE4A00C29E51510678F9DAB40C21A644BC9237D982C24AD1788C3D20F6520144B491C77DB1C53CE98726DCF09DBD1978573CF32848096B44A72CEF3221D98C44BB32A524549A20D822F5531D7E7875B1B564ABDE9EE100A90A8E51B37EAEAE3E89E3E8348F3BC9D8FD284E0FA829406C5D8CE0826CB3EAD353B6052B9C7FC1CD4967090AFE5F2BC11B3280C93278A1396AFC640AD8AFE9101965306601723E689714C3190C41C4D4635F1541241F452C981A5F574DCE109014A274CDBA4CE6AD7C693AA7D3F18418AA4F1487E657858DF460D53BD835685581BB461310DAF203B67C23E0C17ADCD024033C40EEF27957151D01971F43254C6C4E3D86F6ACADB8BCDDCB300A21FEAA54E59A547C9C06ABA312A5B4736356230580FBCACD3FB08626BD622934B81B8697291C6DCB1124F7A6762DB30B9CFA22A92FEC007E7EDBB188F34755C350A884DE8890D0E5D6F491D9C23D951DEBADCB26E1D25D971F5FD23FFA0BCAA84646352DCA69C7A3BB991961E762E96C48E58A2F8FA52DE7CD9FE7C529289A73E13032154349ECA5CCCB3D5B89980B29872AC5B03EBAA726CFD9790AF85E371F0A5B0588E4874EA300C5A370ED42A97C6E372D1DB9825EA995C0B5FABFEC09A632010EE138E8E35794640D65CA647ECDDC20A4D453CA4C35EE78350A8045B3CAD6CF41D3DF5260E355EB03E819C0068C91C2F530F7C74F680386947FE3FD00C91C5CEB7D0AF97DDC251DE856355D16F7CE88E69B20BB20BDB3204C63EC00277B7D5DC9A77682DE0750EBFF7313289998DE1C6E940F0B172A173531140FDA7A3422FB739F8F1647907355B26C37A47EC420791F68C61CC7A55CA855DE158B43D0DB363153AB9F0DEEC632AE784F62775862C4319971738352448A4D653C1CD7380247C05D56198D19720CB284E6CBF137616D8DB5510FBE81A7F646E5356C998B56125895D10ECAE67FD4CCD73FA78ACAA774DB11BBD5314ABDA3DA139107FCD342BA6CBB9BDCBED536411BD50B38F7234511CE74B1362D07BF71DBD033E6F637C45FB0B25871B173BCE2337D963AD41693E04F929113
-20220415135605 2 6 100 7679 5 D73E4A149D00067AF38F615C7920E3E58F83FDF73F493F4712369137702E94062D5E0857DA1D94CE7C7660F89D285B5DF0F8FC8A8CD2FF69819BED74B0F05EAA467BA2CB1337A7F6E9EE06670C393AD6C845C1743F511BEE7ED9D65AA1BF3FD41BD6F0EF131358CCEE448D0EFEE47EF75D3F4AA2FE7A70210CE62E2C6F791BCBB4852CDF41C5EF6B481ABB954A6AB79AB82ABC543C6CF66F971F590ECA63988A886308218202016278C80C8F7142E1CC482FCFC313123AAD101AF837EB8A210CE3522F0554FE4A00C29E51510678F9DAB40C21A644BC9237D982C24AD1788C3D20F6520144B491C77DB1C53CE98726DCF09DBD1978573CF32848096B44A72CEF3221D98C44BB32A524549A20D822F5531D7E7875B1B564ABDE9EE100A90A8E51B37EAEAE3E89E3E8348F3BC9D8FD284E0FA829406C5D8CE0826CB3EAD353B6052B9C7FC1CD4967090AFE5F2BC11B3280C93278A1396AFC640AD8AFE9101965306601723E689714C3190C41C4D4635F1541241F452C981A5F574DCE109014A274CDBA4CE6AD7C693AA7D3F18418AA4F1487E657858DF460D53BD835685581BB461310DAF203B67C23E0C17ADCD024033C40EEF27957151D01971F43254C6C4E3D86F6ACADB8BCDDCB300A21FEAA54E59A547C9C06ABA312A5B4736356230580FBCACD3FB08626BD622934B81B8697291C6DCB1124F7A6762DB30B9CFA22A92FEC007E7EDBB188F34755C350A884DE8890D0E5D6F491D9C23D951DEBADCB26E1D25D971F5FD23FFA0BCAA84646352DCA69C7A3BB991961E762E96C48E58A2F8FA52DE7CD9FE7C529289A73E13032154349ECA5CCCB3D5B89980B29872AC5B03EBAA726CFD9790AF85E371F0A5B0588E4874EA300C5A370ED42A97C6E372D1DB9825EA995C0B5FABFEC09A632010EE138E8E35794640D65CA647ECDDC20A4D453CA4C35EE78350A8045B3CAD6CF41D3DF5260E355EB03E819C0068C91C2F530F7C74F680386947FE3FD00C91C5CEB7D0AF97DDC251DE856355D16F7CE88E69B20BB20BDB3204C63EC00277B7D5DC9A77682DE0750EBFF7313289998DE1C6E940F0B172A173531140FDA7A3422FB739F8F1647907355B26C37A47EC420791F68C61CC7A55CA855DE158B43D0DB363153AB9F0DEEC632AE784F62775862C4319971738352448A4D653C1CD7380247C05D56198D19720CB284E6CBF137616D8DB5510FBE81A7F646E5356C998B56125895D10ECAE67FD4CCD73FA78ACAA774DB11BBD5314ABDA3DA139107FCD342BA6CBB9BDCBED536411BD50B38F7234511CE74B1362D07BF71DBD033E6F637C45FB0B25871B173BCE2337D963AD41693E05156D2E7
-20220415142115 2 6 100 7679 2 D73E4A149D00067AF38F615C7920E3E58F83FDF73F493F4712369137702E94062D5E0857DA1D94CE7C7660F89D285B5DF0F8FC8A8CD2FF69819BED74B0F05EAA467BA2CB1337A7F6E9EE06670C393AD6C845C1743F511BEE7ED9D65AA1BF3FD41BD6F0EF131358CCEE448D0EFEE47EF75D3F4AA2FE7A70210CE62E2C6F791BCBB4852CDF41C5EF6B481ABB954A6AB79AB82ABC543C6CF66F971F590ECA63988A886308218202016278C80C8F7142E1CC482FCFC313123AAD101AF837EB8A210CE3522F0554FE4A00C29E51510678F9DAB40C21A644BC9237D982C24AD1788C3D20F6520144B491C77DB1C53CE98726DCF09DBD1978573CF32848096B44A72CEF3221D98C44BB32A524549A20D822F5531D7E7875B1B564ABDE9EE100A90A8E51B37EAEAE3E89E3E8348F3BC9D8FD284E0FA829406C5D8CE0826CB3EAD353B6052B9C7FC1CD4967090AFE5F2BC11B3280C93278A1396AFC640AD8AFE9101965306601723E689714C3190C41C4D4635F1541241F452C981A5F574DCE109014A274CDBA4CE6AD7C693AA7D3F18418AA4F1487E657858DF460D53BD835685581BB461310DAF203B67C23E0C17ADCD024033C40EEF27957151D01971F43254C6C4E3D86F6ACADB8BCDDCB300A21FEAA54E59A547C9C06ABA312A5B4736356230580FBCACD3FB08626BD622934B81B8697291C6DCB1124F7A6762DB30B9CFA22A92FEC007E7EDBB188F34755C350A884DE8890D0E5D6F491D9C23D951DEBADCB26E1D25D971F5FD23FFA0BCAA84646352DCA69C7A3BB991961E762E96C48E58A2F8FA52DE7CD9FE7C529289A73E13032154349ECA5CCCB3D5B89980B29872AC5B03EBAA726CFD9790AF85E371F0A5B0588E4874EA300C5A370ED42A97C6E372D1DB9825EA995C0B5FABFEC09A632010EE138E8E35794640D65CA647ECDDC20A4D453CA4C35EE78350A8045B3CAD6CF41D3DF5260E355EB03E819C0068C91C2F530F7C74F680386947FE3FD00C91C5CEB7D0AF97DDC251DE856355D16F7CE88E69B20BB20BDB3204C63EC00277B7D5DC9A77682DE0750EBFF7313289998DE1C6E940F0B172A173531140FDA7A3422FB739F8F1647907355B26C37A47EC420791F68C61CC7A55CA855DE158B43D0DB363153AB9F0DEEC632AE784F62775862C4319971738352448A4D653C1CD7380247C05D56198D19720CB284E6CBF137616D8DB5510FBE81A7F646E5356C998B56125895D10ECAE67FD4CCD73FA78ACAA774DB11BBD5314ABDA3DA139107FCD342BA6CBB9BDCBED536411BD50B38F7234511CE74B1362D07BF71DBD033E6F637C45FB0B25871B173BCE2337D963AD41693E0534A50FB
-20220415151250 2 6 100 7679 2 D73E4A149D00067AF38F615C7920E3E58F83FDF73F493F4712369137702E94062D5E0857DA1D94CE7C7660F89D285B5DF0F8FC8A8CD2FF69819BED74B0F05EAA467BA2CB1337A7F6E9EE06670C393AD6C845C1743F511BEE7ED9D65AA1BF3FD41BD6F0EF131358CCEE448D0EFEE47EF75D3F4AA2FE7A70210CE62E2C6F791BCBB4852CDF41C5EF6B481ABB954A6AB79AB82ABC543C6CF66F971F590ECA63988A886308218202016278C80C8F7142E1CC482FCFC313123AAD101AF837EB8A210CE3522F0554FE4A00C29E51510678F9DAB40C21A644BC9237D982C24AD1788C3D20F6520144B491C77DB1C53CE98726DCF09DBD1978573CF32848096B44A72CEF3221D98C44BB32A524549A20D822F5531D7E7875B1B564ABDE9EE100A90A8E51B37EAEAE3E89E3E8348F3BC9D8FD284E0FA829406C5D8CE0826CB3EAD353B6052B9C7FC1CD4967090AFE5F2BC11B3280C93278A1396AFC640AD8AFE9101965306601723E689714C3190C41C4D4635F1541241F452C981A5F574DCE109014A274CDBA4CE6AD7C693AA7D3F18418AA4F1487E657858DF460D53BD835685581BB461310DAF203B67C23E0C17ADCD024033C40EEF27957151D01971F43254C6C4E3D86F6ACADB8BCDDCB300A21FEAA54E59A547C9C06ABA312A5B4736356230580FBCACD3FB08626BD622934B81B8697291C6DCB1124F7A6762DB30B9CFA22A92FEC007E7EDBB188F34755C350A884DE8890D0E5D6F491D9C23D951DEBADCB26E1D25D971F5FD23FFA0BCAA84646352DCA69C7A3BB991961E762E96C48E58A2F8FA52DE7CD9FE7C529289A73E13032154349ECA5CCCB3D5B89980B29872AC5B03EBAA726CFD9790AF85E371F0A5B0588E4874EA300C5A370ED42A97C6E372D1DB9825EA995C0B5FABFEC09A632010EE138E8E35794640D65CA647ECDDC20A4D453CA4C35EE78350A8045B3CAD6CF41D3DF5260E355EB03E819C0068C91C2F530F7C74F680386947FE3FD00C91C5CEB7D0AF97DDC251DE856355D16F7CE88E69B20BB20BDB3204C63EC00277B7D5DC9A77682DE0750EBFF7313289998DE1C6E940F0B172A173531140FDA7A3422FB739F8F1647907355B26C37A47EC420791F68C61CC7A55CA855DE158B43D0DB363153AB9F0DEEC632AE784F62775862C4319971738352448A4D653C1CD7380247C05D56198D19720CB284E6CBF137616D8DB5510FBE81A7F646E5356C998B56125895D10ECAE67FD4CCD73FA78ACAA774DB11BBD5314ABDA3DA139107FCD342BA6CBB9BDCBED536411BD50B38F7234511CE74B1362D07BF71DBD033E6F637C45FB0B25871B173BCE2337D963AD41693E057418E9B
-20220415162045 2 6 100 7679 5 D73E4A149D00067AF38F615C7920E3E58F83FDF73F493F4712369137702E94062D5E0857DA1D94CE7C7660F89D285B5DF0F8FC8A8CD2FF69819BED74B0F05EAA467BA2CB1337A7F6E9EE06670C393AD6C845C1743F511BEE7ED9D65AA1BF3FD41BD6F0EF131358CCEE448D0EFEE47EF75D3F4AA2FE7A70210CE62E2C6F791BCBB4852CDF41C5EF6B481ABB954A6AB79AB82ABC543C6CF66F971F590ECA63988A886308218202016278C80C8F7142E1CC482FCFC313123AAD101AF837EB8A210CE3522F0554FE4A00C29E51510678F9DAB40C21A644BC9237D982C24AD1788C3D20F6520144B491C77DB1C53CE98726DCF09DBD1978573CF32848096B44A72CEF3221D98C44BB32A524549A20D822F5531D7E7875B1B564ABDE9EE100A90A8E51B37EAEAE3E89E3E8348F3BC9D8FD284E0FA829406C5D8CE0826CB3EAD353B6052B9C7FC1CD4967090AFE5F2BC11B3280C93278A1396AFC640AD8AFE9101965306601723E689714C3190C41C4D4635F1541241F452C981A5F574DCE109014A274CDBA4CE6AD7C693AA7D3F18418AA4F1487E657858DF460D53BD835685581BB461310DAF203B67C23E0C17ADCD024033C40EEF27957151D01971F43254C6C4E3D86F6ACADB8BCDDCB300A21FEAA54E59A547C9C06ABA312A5B4736356230580FBCACD3FB08626BD622934B81B8697291C6DCB1124F7A6762DB30B9CFA22A92FEC007E7EDBB188F34755C350A884DE8890D0E5D6F491D9C23D951DEBADCB26E1D25D971F5FD23FFA0BCAA84646352DCA69C7A3BB991961E762E96C48E58A2F8FA52DE7CD9FE7C529289A73E13032154349ECA5CCCB3D5B89980B29872AC5B03EBAA726CFD9790AF85E371F0A5B0588E4874EA300C5A370ED42A97C6E372D1DB9825EA995C0B5FABFEC09A632010EE138E8E35794640D65CA647ECDDC20A4D453CA4C35EE78350A8045B3CAD6CF41D3DF5260E355EB03E819C0068C91C2F530F7C74F680386947FE3FD00C91C5CEB7D0AF97DDC251DE856355D16F7CE88E69B20BB20BDB3204C63EC00277B7D5DC9A77682DE0750EBFF7313289998DE1C6E940F0B172A173531140FDA7A3422FB739F8F1647907355B26C37A47EC420791F68C61CC7A55CA855DE158B43D0DB363153AB9F0DEEC632AE784F62775862C4319971738352448A4D653C1CD7380247C05D56198D19720CB284E6CBF137616D8DB5510FBE81A7F646E5356C998B56125895D10ECAE67FD4CCD73FA78ACAA774DB11BBD5314ABDA3DA139107FCD342BA6CBB9BDCBED536411BD50B38F7234511CE74B1362D07BF71DBD033E6F637C45FB0B25871B173BCE2337D963AD41693E05C89A9FF
-20220415171606 2 6 100 7679 2 D73E4A149D00067AF38F615C7920E3E58F83FDF73F493F4712369137702E94062D5E0857DA1D94CE7C7660F89D285B5DF0F8FC8A8CD2FF69819BED74B0F05EAA467BA2CB1337A7F6E9EE06670C393AD6C845C1743F511BEE7ED9D65AA1BF3FD41BD6F0EF131358CCEE448D0EFEE47EF75D3F4AA2FE7A70210CE62E2C6F791BCBB4852CDF41C5EF6B481ABB954A6AB79AB82ABC543C6CF66F971F590ECA63988A886308218202016278C80C8F7142E1CC482FCFC313123AAD101AF837EB8A210CE3522F0554FE4A00C29E51510678F9DAB40C21A644BC9237D982C24AD1788C3D20F6520144B491C77DB1C53CE98726DCF09DBD1978573CF32848096B44A72CEF3221D98C44BB32A524549A20D822F5531D7E7875B1B564ABDE9EE100A90A8E51B37EAEAE3E89E3E8348F3BC9D8FD284E0FA829406C5D8CE0826CB3EAD353B6052B9C7FC1CD4967090AFE5F2BC11B3280C93278A1396AFC640AD8AFE9101965306601723E689714C3190C41C4D4635F1541241F452C981A5F574DCE109014A274CDBA4CE6AD7C693AA7D3F18418AA4F1487E657858DF460D53BD835685581BB461310DAF203B67C23E0C17ADCD024033C40EEF27957151D01971F43254C6C4E3D86F6ACADB8BCDDCB300A21FEAA54E59A547C9C06ABA312A5B4736356230580FBCACD3FB08626BD622934B81B8697291C6DCB1124F7A6762DB30B9CFA22A92FEC007E7EDBB188F34755C350A884DE8890D0E5D6F491D9C23D951DEBADCB26E1D25D971F5FD23FFA0BCAA84646352DCA69C7A3BB991961E762E96C48E58A2F8FA52DE7CD9FE7C529289A73E13032154349ECA5CCCB3D5B89980B29872AC5B03EBAA726CFD9790AF85E371F0A5B0588E4874EA300C5A370ED42A97C6E372D1DB9825EA995C0B5FABFEC09A632010EE138E8E35794640D65CA647ECDDC20A4D453CA4C35EE78350A8045B3CAD6CF41D3DF5260E355EB03E819C0068C91C2F530F7C74F680386947FE3FD00C91C5CEB7D0AF97DDC251DE856355D16F7CE88E69B20BB20BDB3204C63EC00277B7D5DC9A77682DE0750EBFF7313289998DE1C6E940F0B172A173531140FDA7A3422FB739F8F1647907355B26C37A47EC420791F68C61CC7A55CA855DE158B43D0DB363153AB9F0DEEC632AE784F62775862C4319971738352448A4D653C1CD7380247C05D56198D19720CB284E6CBF137616D8DB5510FBE81A7F646E5356C998B56125895D10ECAE67FD4CCD73FA78ACAA774DB11BBD5314ABDA3DA139107FCD342BA6CBB9BDCBED536411BD50B38F7234511CE74B1362D07BF71DBD033E6F637C45FB0B25871B173BCE2337D963AD41693E060CD4F4B
-20220415180941 2 6 100 7679 2 D73E4A149D00067AF38F615C7920E3E58F83FDF73F493F4712369137702E94062D5E0857DA1D94CE7C7660F89D285B5DF0F8FC8A8CD2FF69819BED74B0F05EAA467BA2CB1337A7F6E9EE06670C393AD6C845C1743F511BEE7ED9D65AA1BF3FD41BD6F0EF131358CCEE448D0EFEE47EF75D3F4AA2FE7A70210CE62E2C6F791BCBB4852CDF41C5EF6B481ABB954A6AB79AB82ABC543C6CF66F971F590ECA63988A886308218202016278C80C8F7142E1CC482FCFC313123AAD101AF837EB8A210CE3522F0554FE4A00C29E51510678F9DAB40C21A644BC9237D982C24AD1788C3D20F6520144B491C77DB1C53CE98726DCF09DBD1978573CF32848096B44A72CEF3221D98C44BB32A524549A20D822F5531D7E7875B1B564ABDE9EE100A90A8E51B37EAEAE3E89E3E8348F3BC9D8FD284E0FA829406C5D8CE0826CB3EAD353B6052B9C7FC1CD4967090AFE5F2BC11B3280C93278A1396AFC640AD8AFE9101965306601723E689714C3190C41C4D4635F1541241F452C981A5F574DCE109014A274CDBA4CE6AD7C693AA7D3F18418AA4F1487E657858DF460D53BD835685581BB461310DAF203B67C23E0C17ADCD024033C40EEF27957151D01971F43254C6C4E3D86F6ACADB8BCDDCB300A21FEAA54E59A547C9C06ABA312A5B4736356230580FBCACD3FB08626BD622934B81B8697291C6DCB1124F7A6762DB30B9CFA22A92FEC007E7EDBB188F34755C350A884DE8890D0E5D6F491D9C23D951DEBADCB26E1D25D971F5FD23FFA0BCAA84646352DCA69C7A3BB991961E762E96C48E58A2F8FA52DE7CD9FE7C529289A73E13032154349ECA5CCCB3D5B89980B29872AC5B03EBAA726CFD9790AF85E371F0A5B0588E4874EA300C5A370ED42A97C6E372D1DB9825EA995C0B5FABFEC09A632010EE138E8E35794640D65CA647ECDDC20A4D453CA4C35EE78350A8045B3CAD6CF41D3DF5260E355EB03E819C0068C91C2F530F7C74F680386947FE3FD00C91C5CEB7D0AF97DDC251DE856355D16F7CE88E69B20BB20BDB3204C63EC00277B7D5DC9A77682DE0750EBFF7313289998DE1C6E940F0B172A173531140FDA7A3422FB739F8F1647907355B26C37A47EC420791F68C61CC7A55CA855DE158B43D0DB363153AB9F0DEEC632AE784F62775862C4319971738352448A4D653C1CD7380247C05D56198D19720CB284E6CBF137616D8DB5510FBE81A7F646E5356C998B56125895D10ECAE67FD4CCD73FA78ACAA774DB11BBD5314ABDA3DA139107FCD342BA6CBB9BDCBED536411BD50B38F7234511CE74B1362D07BF71DBD033E6F637C45FB0B25871B173BCE2337D963AD41693E064E85D4B
-20220415194613 2 6 100 7679 2 D73E4A149D00067AF38F615C7920E3E58F83FDF73F493F4712369137702E94062D5E0857DA1D94CE7C7660F89D285B5DF0F8FC8A8CD2FF69819BED74B0F05EAA467BA2CB1337A7F6E9EE06670C393AD6C845C1743F511BEE7ED9D65AA1BF3FD41BD6F0EF131358CCEE448D0EFEE47EF75D3F4AA2FE7A70210CE62E2C6F791BCBB4852CDF41C5EF6B481ABB954A6AB79AB82ABC543C6CF66F971F590ECA63988A886308218202016278C80C8F7142E1CC482FCFC313123AAD101AF837EB8A210CE3522F0554FE4A00C29E51510678F9DAB40C21A644BC9237D982C24AD1788C3D20F6520144B491C77DB1C53CE98726DCF09DBD1978573CF32848096B44A72CEF3221D98C44BB32A524549A20D822F5531D7E7875B1B564ABDE9EE100A90A8E51B37EAEAE3E89E3E8348F3BC9D8FD284E0FA829406C5D8CE0826CB3EAD353B6052B9C7FC1CD4967090AFE5F2BC11B3280C93278A1396AFC640AD8AFE9101965306601723E689714C3190C41C4D4635F1541241F452C981A5F574DCE109014A274CDBA4CE6AD7C693AA7D3F18418AA4F1487E657858DF460D53BD835685581BB461310DAF203B67C23E0C17ADCD024033C40EEF27957151D01971F43254C6C4E3D86F6ACADB8BCDDCB300A21FEAA54E59A547C9C06ABA312A5B4736356230580FBCACD3FB08626BD622934B81B8697291C6DCB1124F7A6762DB30B9CFA22A92FEC007E7EDBB188F34755C350A884DE8890D0E5D6F491D9C23D951DEBADCB26E1D25D971F5FD23FFA0BCAA84646352DCA69C7A3BB991961E762E96C48E58A2F8FA52DE7CD9FE7C529289A73E13032154349ECA5CCCB3D5B89980B29872AC5B03EBAA726CFD9790AF85E371F0A5B0588E4874EA300C5A370ED42A97C6E372D1DB9825EA995C0B5FABFEC09A632010EE138E8E35794640D65CA647ECDDC20A4D453CA4C35EE78350A8045B3CAD6CF41D3DF5260E355EB03E819C0068C91C2F530F7C74F680386947FE3FD00C91C5CEB7D0AF97DDC251DE856355D16F7CE88E69B20BB20BDB3204C63EC00277B7D5DC9A77682DE0750EBFF7313289998DE1C6E940F0B172A173531140FDA7A3422FB739F8F1647907355B26C37A47EC420791F68C61CC7A55CA855DE158B43D0DB363153AB9F0DEEC632AE784F62775862C4319971738352448A4D653C1CD7380247C05D56198D19720CB284E6CBF137616D8DB5510FBE81A7F646E5356C998B56125895D10ECAE67FD4CCD73FA78ACAA774DB11BBD5314ABDA3DA139107FCD342BA6CBB9BDCBED536411BD50B38F7234511CE74B1362D07BF71DBD033E6F637C45FB0B25871B173BCE2337D963AD41693E06C3089C3
-20220415202412 2 6 100 7679 2 D73E4A149D00067AF38F615C7920E3E58F83FDF73F493F4712369137702E94062D5E0857DA1D94CE7C7660F89D285B5DF0F8FC8A8CD2FF69819BED74B0F05EAA467BA2CB1337A7F6E9EE06670C393AD6C845C1743F511BEE7ED9D65AA1BF3FD41BD6F0EF131358CCEE448D0EFEE47EF75D3F4AA2FE7A70210CE62E2C6F791BCBB4852CDF41C5EF6B481ABB954A6AB79AB82ABC543C6CF66F971F590ECA63988A886308218202016278C80C8F7142E1CC482FCFC313123AAD101AF837EB8A210CE3522F0554FE4A00C29E51510678F9DAB40C21A644BC9237D982C24AD1788C3D20F6520144B491C77DB1C53CE98726DCF09DBD1978573CF32848096B44A72CEF3221D98C44BB32A524549A20D822F5531D7E7875B1B564ABDE9EE100A90A8E51B37EAEAE3E89E3E8348F3BC9D8FD284E0FA829406C5D8CE0826CB3EAD353B6052B9C7FC1CD4967090AFE5F2BC11B3280C93278A1396AFC640AD8AFE9101965306601723E689714C3190C41C4D4635F1541241F452C981A5F574DCE109014A274CDBA4CE6AD7C693AA7D3F18418AA4F1487E657858DF460D53BD835685581BB461310DAF203B67C23E0C17ADCD024033C40EEF27957151D01971F43254C6C4E3D86F6ACADB8BCDDCB300A21FEAA54E59A547C9C06ABA312A5B4736356230580FBCACD3FB08626BD622934B81B8697291C6DCB1124F7A6762DB30B9CFA22A92FEC007E7EDBB188F34755C350A884DE8890D0E5D6F491D9C23D951DEBADCB26E1D25D971F5FD23FFA0BCAA84646352DCA69C7A3BB991961E762E96C48E58A2F8FA52DE7CD9FE7C529289A73E13032154349ECA5CCCB3D5B89980B29872AC5B03EBAA726CFD9790AF85E371F0A5B0588E4874EA300C5A370ED42A97C6E372D1DB9825EA995C0B5FABFEC09A632010EE138E8E35794640D65CA647ECDDC20A4D453CA4C35EE78350A8045B3CAD6CF41D3DF5260E355EB03E819C0068C91C2F530F7C74F680386947FE3FD00C91C5CEB7D0AF97DDC251DE856355D16F7CE88E69B20BB20BDB3204C63EC00277B7D5DC9A77682DE0750EBFF7313289998DE1C6E940F0B172A173531140FDA7A3422FB739F8F1647907355B26C37A47EC420791F68C61CC7A55CA855DE158B43D0DB363153AB9F0DEEC632AE784F62775862C4319971738352448A4D653C1CD7380247C05D56198D19720CB284E6CBF137616D8DB5510FBE81A7F646E5356C998B56125895D10ECAE67FD4CCD73FA78ACAA774DB11BBD5314ABDA3DA139107FCD342BA6CBB9BDCBED536411BD50B38F7234511CE74B1362D07BF71DBD033E6F637C45FB0B25871B173BCE2337D963AD41693E06F041BA3
-20220415204136 2 6 100 7679 2 D73E4A149D00067AF38F615C7920E3E58F83FDF73F493F4712369137702E94062D5E0857DA1D94CE7C7660F89D285B5DF0F8FC8A8CD2FF69819BED74B0F05EAA467BA2CB1337A7F6E9EE06670C393AD6C845C1743F511BEE7ED9D65AA1BF3FD41BD6F0EF131358CCEE448D0EFEE47EF75D3F4AA2FE7A70210CE62E2C6F791BCBB4852CDF41C5EF6B481ABB954A6AB79AB82ABC543C6CF66F971F590ECA63988A886308218202016278C80C8F7142E1CC482FCFC313123AAD101AF837EB8A210CE3522F0554FE4A00C29E51510678F9DAB40C21A644BC9237D982C24AD1788C3D20F6520144B491C77DB1C53CE98726DCF09DBD1978573CF32848096B44A72CEF3221D98C44BB32A524549A20D822F5531D7E7875B1B564ABDE9EE100A90A8E51B37EAEAE3E89E3E8348F3BC9D8FD284E0FA829406C5D8CE0826CB3EAD353B6052B9C7FC1CD4967090AFE5F2BC11B3280C93278A1396AFC640AD8AFE9101965306601723E689714C3190C41C4D4635F1541241F452C981A5F574DCE109014A274CDBA4CE6AD7C693AA7D3F18418AA4F1487E657858DF460D53BD835685581BB461310DAF203B67C23E0C17ADCD024033C40EEF27957151D01971F43254C6C4E3D86F6ACADB8BCDDCB300A21FEAA54E59A547C9C06ABA312A5B4736356230580FBCACD3FB08626BD622934B81B8697291C6DCB1124F7A6762DB30B9CFA22A92FEC007E7EDBB188F34755C350A884DE8890D0E5D6F491D9C23D951DEBADCB26E1D25D971F5FD23FFA0BCAA84646352DCA69C7A3BB991961E762E96C48E58A2F8FA52DE7CD9FE7C529289A73E13032154349ECA5CCCB3D5B89980B29872AC5B03EBAA726CFD9790AF85E371F0A5B0588E4874EA300C5A370ED42A97C6E372D1DB9825EA995C0B5FABFEC09A632010EE138E8E35794640D65CA647ECDDC20A4D453CA4C35EE78350A8045B3CAD6CF41D3DF5260E355EB03E819C0068C91C2F530F7C74F680386947FE3FD00C91C5CEB7D0AF97DDC251DE856355D16F7CE88E69B20BB20BDB3204C63EC00277B7D5DC9A77682DE0750EBFF7313289998DE1C6E940F0B172A173531140FDA7A3422FB739F8F1647907355B26C37A47EC420791F68C61CC7A55CA855DE158B43D0DB363153AB9F0DEEC632AE784F62775862C4319971738352448A4D653C1CD7380247C05D56198D19720CB284E6CBF137616D8DB5510FBE81A7F646E5356C998B56125895D10ECAE67FD4CCD73FA78ACAA774DB11BBD5314ABDA3DA139107FCD342BA6CBB9BDCBED536411BD50B38F7234511CE74B1362D07BF71DBD033E6F637C45FB0B25871B173BCE2337D963AD41693E0704DA05B
-20220415205914 2 6 100 7679 5 D73E4A149D00067AF38F615C7920E3E58F83FDF73F493F4712369137702E94062D5E0857DA1D94CE7C7660F89D285B5DF0F8FC8A8CD2FF69819BED74B0F05EAA467BA2CB1337A7F6E9EE06670C393AD6C845C1743F511BEE7ED9D65AA1BF3FD41BD6F0EF131358CCEE448D0EFEE47EF75D3F4AA2FE7A70210CE62E2C6F791BCBB4852CDF41C5EF6B481ABB954A6AB79AB82ABC543C6CF66F971F590ECA63988A886308218202016278C80C8F7142E1CC482FCFC313123AAD101AF837EB8A210CE3522F0554FE4A00C29E51510678F9DAB40C21A644BC9237D982C24AD1788C3D20F6520144B491C77DB1C53CE98726DCF09DBD1978573CF32848096B44A72CEF3221D98C44BB32A524549A20D822F5531D7E7875B1B564ABDE9EE100A90A8E51B37EAEAE3E89E3E8348F3BC9D8FD284E0FA829406C5D8CE0826CB3EAD353B6052B9C7FC1CD4967090AFE5F2BC11B3280C93278A1396AFC640AD8AFE9101965306601723E689714C3190C41C4D4635F1541241F452C981A5F574DCE109014A274CDBA4CE6AD7C693AA7D3F18418AA4F1487E657858DF460D53BD835685581BB461310DAF203B67C23E0C17ADCD024033C40EEF27957151D01971F43254C6C4E3D86F6ACADB8BCDDCB300A21FEAA54E59A547C9C06ABA312A5B4736356230580FBCACD3FB08626BD622934B81B8697291C6DCB1124F7A6762DB30B9CFA22A92FEC007E7EDBB188F34755C350A884DE8890D0E5D6F491D9C23D951DEBADCB26E1D25D971F5FD23FFA0BCAA84646352DCA69C7A3BB991961E762E96C48E58A2F8FA52DE7CD9FE7C529289A73E13032154349ECA5CCCB3D5B89980B29872AC5B03EBAA726CFD9790AF85E371F0A5B0588E4874EA300C5A370ED42A97C6E372D1DB9825EA995C0B5FABFEC09A632010EE138E8E35794640D65CA647ECDDC20A4D453CA4C35EE78350A8045B3CAD6CF41D3DF5260E355EB03E819C0068C91C2F530F7C74F680386947FE3FD00C91C5CEB7D0AF97DDC251DE856355D16F7CE88E69B20BB20BDB3204C63EC00277B7D5DC9A77682DE0750EBFF7313289998DE1C6E940F0B172A173531140FDA7A3422FB739F8F1647907355B26C37A47EC420791F68C61CC7A55CA855DE158B43D0DB363153AB9F0DEEC632AE784F62775862C4319971738352448A4D653C1CD7380247C05D56198D19720CB284E6CBF137616D8DB5510FBE81A7F646E5356C998B56125895D10ECAE67FD4CCD73FA78ACAA774DB11BBD5314ABDA3DA139107FCD342BA6CBB9BDCBED536411BD50B38F7234511CE74B1362D07BF71DBD033E6F637C45FB0B25871B173BCE2337D963AD41693E07193837F
-20220415225928 2 6 100 7679 2 D73E4A149D00067AF38F615C7920E3E58F83FDF73F493F4712369137702E94062D5E0857DA1D94CE7C7660F89D285B5DF0F8FC8A8CD2FF69819BED74B0F05EAA467BA2CB1337A7F6E9EE06670C393AD6C845C1743F511BEE7ED9D65AA1BF3FD41BD6F0EF131358CCEE448D0EFEE47EF75D3F4AA2FE7A70210CE62E2C6F791BCBB4852CDF41C5EF6B481ABB954A6AB79AB82ABC543C6CF66F971F590ECA63988A886308218202016278C80C8F7142E1CC482FCFC313123AAD101AF837EB8A210CE3522F0554FE4A00C29E51510678F9DAB40C21A644BC9237D982C24AD1788C3D20F6520144B491C77DB1C53CE98726DCF09DBD1978573CF32848096B44A72CEF3221D98C44BB32A524549A20D822F5531D7E7875B1B564ABDE9EE100A90A8E51B37EAEAE3E89E3E8348F3BC9D8FD284E0FA829406C5D8CE0826CB3EAD353B6052B9C7FC1CD4967090AFE5F2BC11B3280C93278A1396AFC640AD8AFE9101965306601723E689714C3190C41C4D4635F1541241F452C981A5F574DCE109014A274CDBA4CE6AD7C693AA7D3F18418AA4F1487E657858DF460D53BD835685581BB461310DAF203B67C23E0C17ADCD024033C40EEF27957151D01971F43254C6C4E3D86F6ACADB8BCDDCB300A21FEAA54E59A547C9C06ABA312A5B4736356230580FBCACD3FB08626BD622934B81B8697291C6DCB1124F7A6762DB30B9CFA22A92FEC007E7EDBB188F34755C350A884DE8890D0E5D6F491D9C23D951DEBADCB26E1D25D971F5FD23FFA0BCAA84646352DCA69C7A3BB991961E762E96C48E58A2F8FA52DE7CD9FE7C529289A73E13032154349ECA5CCCB3D5B89980B29872AC5B03EBAA726CFD9790AF85E371F0A5B0588E4874EA300C5A370ED42A97C6E372D1DB9825EA995C0B5FABFEC09A632010EE138E8E35794640D65CA647ECDDC20A4D453CA4C35EE78350A8045B3CAD6CF41D3DF5260E355EB03E819C0068C91C2F530F7C74F680386947FE3FD00C91C5CEB7D0AF97DDC251DE856355D16F7CE88E69B20BB20BDB3204C63EC00277B7D5DC9A77682DE0750EBFF7313289998DE1C6E940F0B172A173531140FDA7A3422FB739F8F1647907355B26C37A47EC420791F68C61CC7A55CA855DE158B43D0DB363153AB9F0DEEC632AE784F62775862C4319971738352448A4D653C1CD7380247C05D56198D19720CB284E6CBF137616D8DB5510FBE81A7F646E5356C998B56125895D10ECAE67FD4CCD73FA78ACAA774DB11BBD5314ABDA3DA139107FCD342BA6CBB9BDCBED536411BD50B38F7234511CE74B1362D07BF71DBD033E6F637C45FB0B25871B173BCE2337D963AD41693E07A9B3103
-20220416005936 2 6 100 7679 2 D73E4A149D00067AF38F615C7920E3E58F83FDF73F493F4712369137702E94062D5E0857DA1D94CE7C7660F89D285B5DF0F8FC8A8CD2FF69819BED74B0F05EAA467BA2CB1337A7F6E9EE06670C393AD6C845C1743F511BEE7ED9D65AA1BF3FD41BD6F0EF131358CCEE448D0EFEE47EF75D3F4AA2FE7A70210CE62E2C6F791BCBB4852CDF41C5EF6B481ABB954A6AB79AB82ABC543C6CF66F971F590ECA63988A886308218202016278C80C8F7142E1CC482FCFC313123AAD101AF837EB8A210CE3522F0554FE4A00C29E51510678F9DAB40C21A644BC9237D982C24AD1788C3D20F6520144B491C77DB1C53CE98726DCF09DBD1978573CF32848096B44A72CEF3221D98C44BB32A524549A20D822F5531D7E7875B1B564ABDE9EE100A90A8E51B37EAEAE3E89E3E8348F3BC9D8FD284E0FA829406C5D8CE0826CB3EAD353B6052B9C7FC1CD4967090AFE5F2BC11B3280C93278A1396AFC640AD8AFE9101965306601723E689714C3190C41C4D4635F1541241F452C981A5F574DCE109014A274CDBA4CE6AD7C693AA7D3F18418AA4F1487E657858DF460D53BD835685581BB461310DAF203B67C23E0C17ADCD024033C40EEF27957151D01971F43254C6C4E3D86F6ACADB8BCDDCB300A21FEAA54E59A547C9C06ABA312A5B4736356230580FBCACD3FB08626BD622934B81B8697291C6DCB1124F7A6762DB30B9CFA22A92FEC007E7EDBB188F34755C350A884DE8890D0E5D6F491D9C23D951DEBADCB26E1D25D971F5FD23FFA0BCAA84646352DCA69C7A3BB991961E762E96C48E58A2F8FA52DE7CD9FE7C529289A73E13032154349ECA5CCCB3D5B89980B29872AC5B03EBAA726CFD9790AF85E371F0A5B0588E4874EA300C5A370ED42A97C6E372D1DB9825EA995C0B5FABFEC09A632010EE138E8E35794640D65CA647ECDDC20A4D453CA4C35EE78350A8045B3CAD6CF41D3DF5260E355EB03E819C0068C91C2F530F7C74F680386947FE3FD00C91C5CEB7D0AF97DDC251DE856355D16F7CE88E69B20BB20BDB3204C63EC00277B7D5DC9A77682DE0750EBFF7313289998DE1C6E940F0B172A173531140FDA7A3422FB739F8F1647907355B26C37A47EC420791F68C61CC7A55CA855DE158B43D0DB363153AB9F0DEEC632AE784F62775862C4319971738352448A4D653C1CD7380247C05D56198D19720CB284E6CBF137616D8DB5510FBE81A7F646E5356C998B56125895D10ECAE67FD4CCD73FA78ACAA774DB11BBD5314ABDA3DA139107FCD342BA6CBB9BDCBED536411BD50B38F7234511CE74B1362D07BF71DBD033E6F637C45FB0B25871B173BCE2337D963AD41693E083760473
-20220416011857 2 6 100 7679 5 D73E4A149D00067AF38F615C7920E3E58F83FDF73F493F4712369137702E94062D5E0857DA1D94CE7C7660F89D285B5DF0F8FC8A8CD2FF69819BED74B0F05EAA467BA2CB1337A7F6E9EE06670C393AD6C845C1743F511BEE7ED9D65AA1BF3FD41BD6F0EF131358CCEE448D0EFEE47EF75D3F4AA2FE7A70210CE62E2C6F791BCBB4852CDF41C5EF6B481ABB954A6AB79AB82ABC543C6CF66F971F590ECA63988A886308218202016278C80C8F7142E1CC482FCFC313123AAD101AF837EB8A210CE3522F0554FE4A00C29E51510678F9DAB40C21A644BC9237D982C24AD1788C3D20F6520144B491C77DB1C53CE98726DCF09DBD1978573CF32848096B44A72CEF3221D98C44BB32A524549A20D822F5531D7E7875B1B564ABDE9EE100A90A8E51B37EAEAE3E89E3E8348F3BC9D8FD284E0FA829406C5D8CE0826CB3EAD353B6052B9C7FC1CD4967090AFE5F2BC11B3280C93278A1396AFC640AD8AFE9101965306601723E689714C3190C41C4D4635F1541241F452C981A5F574DCE109014A274CDBA4CE6AD7C693AA7D3F18418AA4F1487E657858DF460D53BD835685581BB461310DAF203B67C23E0C17ADCD024033C40EEF27957151D01971F43254C6C4E3D86F6ACADB8BCDDCB300A21FEAA54E59A547C9C06ABA312A5B4736356230580FBCACD3FB08626BD622934B81B8697291C6DCB1124F7A6762DB30B9CFA22A92FEC007E7EDBB188F34755C350A884DE8890D0E5D6F491D9C23D951DEBADCB26E1D25D971F5FD23FFA0BCAA84646352DCA69C7A3BB991961E762E96C48E58A2F8FA52DE7CD9FE7C529289A73E13032154349ECA5CCCB3D5B89980B29872AC5B03EBAA726CFD9790AF85E371F0A5B0588E4874EA300C5A370ED42A97C6E372D1DB9825EA995C0B5FABFEC09A632010EE138E8E35794640D65CA647ECDDC20A4D453CA4C35EE78350A8045B3CAD6CF41D3DF5260E355EB03E819C0068C91C2F530F7C74F680386947FE3FD00C91C5CEB7D0AF97DDC251DE856355D16F7CE88E69B20BB20BDB3204C63EC00277B7D5DC9A77682DE0750EBFF7313289998DE1C6E940F0B172A173531140FDA7A3422FB739F8F1647907355B26C37A47EC420791F68C61CC7A55CA855DE158B43D0DB363153AB9F0DEEC632AE784F62775862C4319971738352448A4D653C1CD7380247C05D56198D19720CB284E6CBF137616D8DB5510FBE81A7F646E5356C998B56125895D10ECAE67FD4CCD73FA78ACAA774DB11BBD5314ABDA3DA139107FCD342BA6CBB9BDCBED536411BD50B38F7234511CE74B1362D07BF71DBD033E6F637C45FB0B25871B173BCE2337D963AD41693E084DB18EF
-20220416014012 2 6 100 7679 5 D73E4A149D00067AF38F615C7920E3E58F83FDF73F493F4712369137702E94062D5E0857DA1D94CE7C7660F89D285B5DF0F8FC8A8CD2FF69819BED74B0F05EAA467BA2CB1337A7F6E9EE06670C393AD6C845C1743F511BEE7ED9D65AA1BF3FD41BD6F0EF131358CCEE448D0EFEE47EF75D3F4AA2FE7A70210CE62E2C6F791BCBB4852CDF41C5EF6B481ABB954A6AB79AB82ABC543C6CF66F971F590ECA63988A886308218202016278C80C8F7142E1CC482FCFC313123AAD101AF837EB8A210CE3522F0554FE4A00C29E51510678F9DAB40C21A644BC9237D982C24AD1788C3D20F6520144B491C77DB1C53CE98726DCF09DBD1978573CF32848096B44A72CEF3221D98C44BB32A524549A20D822F5531D7E7875B1B564ABDE9EE100A90A8E51B37EAEAE3E89E3E8348F3BC9D8FD284E0FA829406C5D8CE0826CB3EAD353B6052B9C7FC1CD4967090AFE5F2BC11B3280C93278A1396AFC640AD8AFE9101965306601723E689714C3190C41C4D4635F1541241F452C981A5F574DCE109014A274CDBA4CE6AD7C693AA7D3F18418AA4F1487E657858DF460D53BD835685581BB461310DAF203B67C23E0C17ADCD024033C40EEF27957151D01971F43254C6C4E3D86F6ACADB8BCDDCB300A21FEAA54E59A547C9C06ABA312A5B4736356230580FBCACD3FB08626BD622934B81B8697291C6DCB1124F7A6762DB30B9CFA22A92FEC007E7EDBB188F34755C350A884DE8890D0E5D6F491D9C23D951DEBADCB26E1D25D971F5FD23FFA0BCAA84646352DCA69C7A3BB991961E762E96C48E58A2F8FA52DE7CD9FE7C529289A73E13032154349ECA5CCCB3D5B89980B29872AC5B03EBAA726CFD9790AF85E371F0A5B0588E4874EA300C5A370ED42A97C6E372D1DB9825EA995C0B5FABFEC09A632010EE138E8E35794640D65CA647ECDDC20A4D453CA4C35EE78350A8045B3CAD6CF41D3DF5260E355EB03E819C0068C91C2F530F7C74F680386947FE3FD00C91C5CEB7D0AF97DDC251DE856355D16F7CE88E69B20BB20BDB3204C63EC00277B7D5DC9A77682DE0750EBFF7313289998DE1C6E940F0B172A173531140FDA7A3422FB739F8F1647907355B26C37A47EC420791F68C61CC7A55CA855DE158B43D0DB363153AB9F0DEEC632AE784F62775862C4319971738352448A4D653C1CD7380247C05D56198D19720CB284E6CBF137616D8DB5510FBE81A7F646E5356C998B56125895D10ECAE67FD4CCD73FA78ACAA774DB11BBD5314ABDA3DA139107FCD342BA6CBB9BDCBED536411BD50B38F7234511CE74B1362D07BF71DBD033E6F637C45FB0B25871B173BCE2337D963AD41693E0865D0237
-20220416040204 2 6 100 7679 2 D73E4A149D00067AF38F615C7920E3E58F83FDF73F493F4712369137702E94062D5E0857DA1D94CE7C7660F89D285B5DF0F8FC8A8CD2FF69819BED74B0F05EAA467BA2CB1337A7F6E9EE06670C393AD6C845C1743F511BEE7ED9D65AA1BF3FD41BD6F0EF131358CCEE448D0EFEE47EF75D3F4AA2FE7A70210CE62E2C6F791BCBB4852CDF41C5EF6B481ABB954A6AB79AB82ABC543C6CF66F971F590ECA63988A886308218202016278C80C8F7142E1CC482FCFC313123AAD101AF837EB8A210CE3522F0554FE4A00C29E51510678F9DAB40C21A644BC9237D982C24AD1788C3D20F6520144B491C77DB1C53CE98726DCF09DBD1978573CF32848096B44A72CEF3221D98C44BB32A524549A20D822F5531D7E7875B1B564ABDE9EE100A90A8E51B37EAEAE3E89E3E8348F3BC9D8FD284E0FA829406C5D8CE0826CB3EAD353B6052B9C7FC1CD4967090AFE5F2BC11B3280C93278A1396AFC640AD8AFE9101965306601723E689714C3190C41C4D4635F1541241F452C981A5F574DCE109014A274CDBA4CE6AD7C693AA7D3F18418AA4F1487E657858DF460D53BD835685581BB461310DAF203B67C23E0C17ADCD024033C40EEF27957151D01971F43254C6C4E3D86F6ACADB8BCDDCB300A21FEAA54E59A547C9C06ABA312A5B4736356230580FBCACD3FB08626BD622934B81B8697291C6DCB1124F7A6762DB30B9CFA22A92FEC007E7EDBB188F34755C350A884DE8890D0E5D6F491D9C23D951DEBADCB26E1D25D971F5FD23FFA0BCAA84646352DCA69C7A3BB991961E762E96C48E58A2F8FA52DE7CD9FE7C529289A73E13032154349ECA5CCCB3D5B89980B29872AC5B03EBAA726CFD9790AF85E371F0A5B0588E4874EA300C5A370ED42A97C6E372D1DB9825EA995C0B5FABFEC09A632010EE138E8E35794640D65CA647ECDDC20A4D453CA4C35EE78350A8045B3CAD6CF41D3DF5260E355EB03E819C0068C91C2F530F7C74F680386947FE3FD00C91C5CEB7D0AF97DDC251DE856355D16F7CE88E69B20BB20BDB3204C63EC00277B7D5DC9A77682DE0750EBFF7313289998DE1C6E940F0B172A173531140FDA7A3422FB739F8F1647907355B26C37A47EC420791F68C61CC7A55CA855DE158B43D0DB363153AB9F0DEEC632AE784F62775862C4319971738352448A4D653C1CD7380247C05D56198D19720CB284E6CBF137616D8DB5510FBE81A7F646E5356C998B56125895D10ECAE67FD4CCD73FA78ACAA774DB11BBD5314ABDA3DA139107FCD342BA6CBB9BDCBED536411BD50B38F7234511CE74B1362D07BF71DBD033E6F637C45FB0B25871B173BCE2337D963AD41693E090AFB413
-20220416043614 2 6 100 7679 2 D73E4A149D00067AF38F615C7920E3E58F83FDF73F493F4712369137702E94062D5E0857DA1D94CE7C7660F89D285B5DF0F8FC8A8CD2FF69819BED74B0F05EAA467BA2CB1337A7F6E9EE06670C393AD6C845C1743F511BEE7ED9D65AA1BF3FD41BD6F0EF131358CCEE448D0EFEE47EF75D3F4AA2FE7A70210CE62E2C6F791BCBB4852CDF41C5EF6B481ABB954A6AB79AB82ABC543C6CF66F971F590ECA63988A886308218202016278C80C8F7142E1CC482FCFC313123AAD101AF837EB8A210CE3522F0554FE4A00C29E51510678F9DAB40C21A644BC9237D982C24AD1788C3D20F6520144B491C77DB1C53CE98726DCF09DBD1978573CF32848096B44A72CEF3221D98C44BB32A524549A20D822F5531D7E7875B1B564ABDE9EE100A90A8E51B37EAEAE3E89E3E8348F3BC9D8FD284E0FA829406C5D8CE0826CB3EAD353B6052B9C7FC1CD4967090AFE5F2BC11B3280C93278A1396AFC640AD8AFE9101965306601723E689714C3190C41C4D4635F1541241F452C981A5F574DCE109014A274CDBA4CE6AD7C693AA7D3F18418AA4F1487E657858DF460D53BD835685581BB461310DAF203B67C23E0C17ADCD024033C40EEF27957151D01971F43254C6C4E3D86F6ACADB8BCDDCB300A21FEAA54E59A547C9C06ABA312A5B4736356230580FBCACD3FB08626BD622934B81B8697291C6DCB1124F7A6762DB30B9CFA22A92FEC007E7EDBB188F34755C350A884DE8890D0E5D6F491D9C23D951DEBADCB26E1D25D971F5FD23FFA0BCAA84646352DCA69C7A3BB991961E762E96C48E58A2F8FA52DE7CD9FE7C529289A73E13032154349ECA5CCCB3D5B89980B29872AC5B03EBAA726CFD9790AF85E371F0A5B0588E4874EA300C5A370ED42A97C6E372D1DB9825EA995C0B5FABFEC09A632010EE138E8E35794640D65CA647ECDDC20A4D453CA4C35EE78350A8045B3CAD6CF41D3DF5260E355EB03E819C0068C91C2F530F7C74F680386947FE3FD00C91C5CEB7D0AF97DDC251DE856355D16F7CE88E69B20BB20BDB3204C63EC00277B7D5DC9A77682DE0750EBFF7313289998DE1C6E940F0B172A173531140FDA7A3422FB739F8F1647907355B26C37A47EC420791F68C61CC7A55CA855DE158B43D0DB363153AB9F0DEEC632AE784F62775862C4319971738352448A4D653C1CD7380247C05D56198D19720CB284E6CBF137616D8DB5510FBE81A7F646E5356C998B56125895D10ECAE67FD4CCD73FA78ACAA774DB11BBD5314ABDA3DA139107FCD342BA6CBB9BDCBED536411BD50B38F7234511CE74B1362D07BF71DBD033E6F637C45FB0B25871B173BCE2337D963AD41693E0932065A3
-20220416062823 2 6 100 7679 2 CBC85C4D4EBCF255C5C59577D8AA5AD90A69B25B5296F0E56375785F984F7C899F7F9AF6B2C9194B15A6986941981AC7F389B6B4929F2E376CBF404FC982D91B1D5D8742069C5FF04CB06F655261C68FB38232C141DF7E03297340FA6687EF802A2A9B616B998F04BA24B6657E65250B52DF17531834455D250CB3A0E8CDD070B4F89C82F996416365AB47F1028D66207A6BAD8BA74D0E27BB3CE3F234C59C9CD050ED201ED5C816CAA3DF52A43C612C1079BF51304ED475DDDC73A289AFFA650FC7C4C568ACA26474BD48122BC45354B3AB4F070F6B91F64DACB2FB6F3A6B9FC1182A6818184DDBDF76226DEACA74B78CBAAB347134ED242212BE83D5D1BCD7CD70040518875F00402BBD118E941AF4F038674617A6BCA30F22F40CCFBF6138C854020BDFA5D1336B55081EB46965F647EB1EBD9D290056180489B1E7104FBD061B751D0472124624607D2E6867F7079C0531FECF05A79ADEF6F22DD6FFF9431C6A077BAE0384D447F4085CC805165DD8EB9C8C309B2EDD032DF0D4568FC21E428D6049D809567C707829579A066AA7F62C70EC559586A0749109764F5AE32CAC0C2127BB3654141BA6F87F1911671906B60D77BEE322D71515086B4E9BDA8E853DCF1906CFAEB099B0A1BB5EF0A06752A9C89EB506C773DC12FA8DE2DD8FE789624D80406619AE1BB342C7F01F424E4D5908A02731F051996721E2C0CB6703E131F4B5D1768E386783ED41C1C1318F9E19D995CFEEF998D5659D4A9FBEEDE6313B9E4C1665F1E44BF213E66EAE4435DFC2533EB131F235E0075F406028B650E758F38A582705423BB661A095D24E79B6A1D5C6A36989B28FD2ADA228961C1574187F18D419B46545D7FB147358A8409F5CA3ABBFD14EDDE9C0768E84E77F6E61307908F0DD8CD49B9C413EDE4FD13E4D1FB5CFB0075297258D828C20FD01A261F8D5672BFD190FAE191250F533B548B5469879E8B6BDA77D650ADB83AE9FAEC37FBE8A9F5F85CF47159EBC54A9129692A2B253C735E2F629D183A2ED4F2747BCF143D6D673F0F3703D0122BEDC5255F003311A81FA236D0E93D6CCC3375C4C35474427756E58A245A8F0AD68F1226BDA8ABB969A68B0758F1229038CB16711996B27923A0AE7D81384C24763C72B72B6A23A6EED923D0C70A3E47E47BD572A3398F3D651614A47C942A26F785F75A2DE7EE6FC927BE209729BF52943889E8C14708F592036BD3E3E4990659A13D64A755C39BC588B7D03BBE6129A39746304FEF371C760B1986A6FBF4DD588873571984B10FA6624239082E2273F772BC4FB28BC1E57DCCD35511FB1303BA03BE961D3788131E7A106A63BEB80218A9572A3
-20220416092832 2 6 100 7679 5 CBC85C4D4EBCF255C5C59577D8AA5AD90A69B25B5296F0E56375785F984F7C899F7F9AF6B2C9194B15A6986941981AC7F389B6B4929F2E376CBF404FC982D91B1D5D8742069C5FF04CB06F655261C68FB38232C141DF7E03297340FA6687EF802A2A9B616B998F04BA24B6657E65250B52DF17531834455D250CB3A0E8CDD070B4F89C82F996416365AB47F1028D66207A6BAD8BA74D0E27BB3CE3F234C59C9CD050ED201ED5C816CAA3DF52A43C612C1079BF51304ED475DDDC73A289AFFA650FC7C4C568ACA26474BD48122BC45354B3AB4F070F6B91F64DACB2FB6F3A6B9FC1182A6818184DDBDF76226DEACA74B78CBAAB347134ED242212BE83D5D1BCD7CD70040518875F00402BBD118E941AF4F038674617A6BCA30F22F40CCFBF6138C854020BDFA5D1336B55081EB46965F647EB1EBD9D290056180489B1E7104FBD061B751D0472124624607D2E6867F7079C0531FECF05A79ADEF6F22DD6FFF9431C6A077BAE0384D447F4085CC805165DD8EB9C8C309B2EDD032DF0D4568FC21E428D6049D809567C707829579A066AA7F62C70EC559586A0749109764F5AE32CAC0C2127BB3654141BA6F87F1911671906B60D77BEE322D71515086B4E9BDA8E853DCF1906CFAEB099B0A1BB5EF0A06752A9C89EB506C773DC12FA8DE2DD8FE789624D80406619AE1BB342C7F01F424E4D5908A02731F051996721E2C0CB6703E131F4B5D1768E386783ED41C1C1318F9E19D995CFEEF998D5659D4A9FBEEDE6313B9E4C1665F1E44BF213E66EAE4435DFC2533EB131F235E0075F406028B650E758F38A582705423BB661A095D24E79B6A1D5C6A36989B28FD2ADA228961C1574187F18D419B46545D7FB147358A8409F5CA3ABBFD14EDDE9C0768E84E77F6E61307908F0DD8CD49B9C413EDE4FD13E4D1FB5CFB0075297258D828C20FD01A261F8D5672BFD190FAE191250F533B548B5469879E8B6BDA77D650ADB83AE9FAEC37FBE8A9F5F85CF47159EBC54A9129692A2B253C735E2F629D183A2ED4F2747BCF143D6D673F0F3703D0122BEDC5255F003311A81FA236D0E93D6CCC3375C4C35474427756E58A245A8F0AD68F1226BDA8ABB969A68B0758F1229038CB16711996B27923A0AE7D81384C24763C72B72B6A23A6EED923D0C70A3E47E47BD572A3398F3D651614A47C942A26F785F75A2DE7EE6FC927BE209729BF52943889E8C14708F592036BD3E3E4990659A13D64A755C39BC588B7D03BBE6129A39746304FEF371C760B1986A6FBF4DD588873571984B10FA6624239082E2273F772BC4FB28BC1E57DCCD35511FB1303BA03BE961D3788131E7A106A63BEB8021995B7A27
-20220416094426 2 6 100 7679 2 CBC85C4D4EBCF255C5C59577D8AA5AD90A69B25B5296F0E56375785F984F7C899F7F9AF6B2C9194B15A6986941981AC7F389B6B4929F2E376CBF404FC982D91B1D5D8742069C5FF04CB06F655261C68FB38232C141DF7E03297340FA6687EF802A2A9B616B998F04BA24B6657E65250B52DF17531834455D250CB3A0E8CDD070B4F89C82F996416365AB47F1028D66207A6BAD8BA74D0E27BB3CE3F234C59C9CD050ED201ED5C816CAA3DF52A43C612C1079BF51304ED475DDDC73A289AFFA650FC7C4C568ACA26474BD48122BC45354B3AB4F070F6B91F64DACB2FB6F3A6B9FC1182A6818184DDBDF76226DEACA74B78CBAAB347134ED242212BE83D5D1BCD7CD70040518875F00402BBD118E941AF4F038674617A6BCA30F22F40CCFBF6138C854020BDFA5D1336B55081EB46965F647EB1EBD9D290056180489B1E7104FBD061B751D0472124624607D2E6867F7079C0531FECF05A79ADEF6F22DD6FFF9431C6A077BAE0384D447F4085CC805165DD8EB9C8C309B2EDD032DF0D4568FC21E428D6049D809567C707829579A066AA7F62C70EC559586A0749109764F5AE32CAC0C2127BB3654141BA6F87F1911671906B60D77BEE322D71515086B4E9BDA8E853DCF1906CFAEB099B0A1BB5EF0A06752A9C89EB506C773DC12FA8DE2DD8FE789624D80406619AE1BB342C7F01F424E4D5908A02731F051996721E2C0CB6703E131F4B5D1768E386783ED41C1C1318F9E19D995CFEEF998D5659D4A9FBEEDE6313B9E4C1665F1E44BF213E66EAE4435DFC2533EB131F235E0075F406028B650E758F38A582705423BB661A095D24E79B6A1D5C6A36989B28FD2ADA228961C1574187F18D419B46545D7FB147358A8409F5CA3ABBFD14EDDE9C0768E84E77F6E61307908F0DD8CD49B9C413EDE4FD13E4D1FB5CFB0075297258D828C20FD01A261F8D5672BFD190FAE191250F533B548B5469879E8B6BDA77D650ADB83AE9FAEC37FBE8A9F5F85CF47159EBC54A9129692A2B253C735E2F629D183A2ED4F2747BCF143D6D673F0F3703D0122BEDC5255F003311A81FA236D0E93D6CCC3375C4C35474427756E58A245A8F0AD68F1226BDA8ABB969A68B0758F1229038CB16711996B27923A0AE7D81384C24763C72B72B6A23A6EED923D0C70A3E47E47BD572A3398F3D651614A47C942A26F785F75A2DE7EE6FC927BE209729BF52943889E8C14708F592036BD3E3E4990659A13D64A755C39BC588B7D03BBE6129A39746304FEF371C760B1986A6FBF4DD588873571984B10FA6624239082E2273F772BC4FB28BC1E57DCCD35511FB1303BA03BE961D3788131E7A106A63BEB80219A994F8B
-20220416095028 2 6 100 7679 2 CBC85C4D4EBCF255C5C59577D8AA5AD90A69B25B5296F0E56375785F984F7C899F7F9AF6B2C9194B15A6986941981AC7F389B6B4929F2E376CBF404FC982D91B1D5D8742069C5FF04CB06F655261C68FB38232C141DF7E03297340FA6687EF802A2A9B616B998F04BA24B6657E65250B52DF17531834455D250CB3A0E8CDD070B4F89C82F996416365AB47F1028D66207A6BAD8BA74D0E27BB3CE3F234C59C9CD050ED201ED5C816CAA3DF52A43C612C1079BF51304ED475DDDC73A289AFFA650FC7C4C568ACA26474BD48122BC45354B3AB4F070F6B91F64DACB2FB6F3A6B9FC1182A6818184DDBDF76226DEACA74B78CBAAB347134ED242212BE83D5D1BCD7CD70040518875F00402BBD118E941AF4F038674617A6BCA30F22F40CCFBF6138C854020BDFA5D1336B55081EB46965F647EB1EBD9D290056180489B1E7104FBD061B751D0472124624607D2E6867F7079C0531FECF05A79ADEF6F22DD6FFF9431C6A077BAE0384D447F4085CC805165DD8EB9C8C309B2EDD032DF0D4568FC21E428D6049D809567C707829579A066AA7F62C70EC559586A0749109764F5AE32CAC0C2127BB3654141BA6F87F1911671906B60D77BEE322D71515086B4E9BDA8E853DCF1906CFAEB099B0A1BB5EF0A06752A9C89EB506C773DC12FA8DE2DD8FE789624D80406619AE1BB342C7F01F424E4D5908A02731F051996721E2C0CB6703E131F4B5D1768E386783ED41C1C1318F9E19D995CFEEF998D5659D4A9FBEEDE6313B9E4C1665F1E44BF213E66EAE4435DFC2533EB131F235E0075F406028B650E758F38A582705423BB661A095D24E79B6A1D5C6A36989B28FD2ADA228961C1574187F18D419B46545D7FB147358A8409F5CA3ABBFD14EDDE9C0768E84E77F6E61307908F0DD8CD49B9C413EDE4FD13E4D1FB5CFB0075297258D828C20FD01A261F8D5672BFD190FAE191250F533B548B5469879E8B6BDA77D650ADB83AE9FAEC37FBE8A9F5F85CF47159EBC54A9129692A2B253C735E2F629D183A2ED4F2747BCF143D6D673F0F3703D0122BEDC5255F003311A81FA236D0E93D6CCC3375C4C35474427756E58A245A8F0AD68F1226BDA8ABB969A68B0758F1229038CB16711996B27923A0AE7D81384C24763C72B72B6A23A6EED923D0C70A3E47E47BD572A3398F3D651614A47C942A26F785F75A2DE7EE6FC927BE209729BF52943889E8C14708F592036BD3E3E4990659A13D64A755C39BC588B7D03BBE6129A39746304FEF371C760B1986A6FBF4DD588873571984B10FA6624239082E2273F772BC4FB28BC1E57DCCD35511FB1303BA03BE961D3788131E7A106A63BEB80219B0F266B
-20220416102802 2 6 100 7679 5 CBC85C4D4EBCF255C5C59577D8AA5AD90A69B25B5296F0E56375785F984F7C899F7F9AF6B2C9194B15A6986941981AC7F389B6B4929F2E376CBF404FC982D91B1D5D8742069C5FF04CB06F655261C68FB38232C141DF7E03297340FA6687EF802A2A9B616B998F04BA24B6657E65250B52DF17531834455D250CB3A0E8CDD070B4F89C82F996416365AB47F1028D66207A6BAD8BA74D0E27BB3CE3F234C59C9CD050ED201ED5C816CAA3DF52A43C612C1079BF51304ED475DDDC73A289AFFA650FC7C4C568ACA26474BD48122BC45354B3AB4F070F6B91F64DACB2FB6F3A6B9FC1182A6818184DDBDF76226DEACA74B78CBAAB347134ED242212BE83D5D1BCD7CD70040518875F00402BBD118E941AF4F038674617A6BCA30F22F40CCFBF6138C854020BDFA5D1336B55081EB46965F647EB1EBD9D290056180489B1E7104FBD061B751D0472124624607D2E6867F7079C0531FECF05A79ADEF6F22DD6FFF9431C6A077BAE0384D447F4085CC805165DD8EB9C8C309B2EDD032DF0D4568FC21E428D6049D809567C707829579A066AA7F62C70EC559586A0749109764F5AE32CAC0C2127BB3654141BA6F87F1911671906B60D77BEE322D71515086B4E9BDA8E853DCF1906CFAEB099B0A1BB5EF0A06752A9C89EB506C773DC12FA8DE2DD8FE789624D80406619AE1BB342C7F01F424E4D5908A02731F051996721E2C0CB6703E131F4B5D1768E386783ED41C1C1318F9E19D995CFEEF998D5659D4A9FBEEDE6313B9E4C1665F1E44BF213E66EAE4435DFC2533EB131F235E0075F406028B650E758F38A582705423BB661A095D24E79B6A1D5C6A36989B28FD2ADA228961C1574187F18D419B46545D7FB147358A8409F5CA3ABBFD14EDDE9C0768E84E77F6E61307908F0DD8CD49B9C413EDE4FD13E4D1FB5CFB0075297258D828C20FD01A261F8D5672BFD190FAE191250F533B548B5469879E8B6BDA77D650ADB83AE9FAEC37FBE8A9F5F85CF47159EBC54A9129692A2B253C735E2F629D183A2ED4F2747BCF143D6D673F0F3703D0122BEDC5255F003311A81FA236D0E93D6CCC3375C4C35474427756E58A245A8F0AD68F1226BDA8ABB969A68B0758F1229038CB16711996B27923A0AE7D81384C24763C72B72B6A23A6EED923D0C70A3E47E47BD572A3398F3D651614A47C942A26F785F75A2DE7EE6FC927BE209729BF52943889E8C14708F592036BD3E3E4990659A13D64A755C39BC588B7D03BBE6129A39746304FEF371C760B1986A6FBF4DD588873571984B10FA6624239082E2273F772BC4FB28BC1E57DCCD35511FB1303BA03BE961D3788131E7A106A63BEB80219E13BF97
-20220416120843 2 6 100 7679 5 CBC85C4D4EBCF255C5C59577D8AA5AD90A69B25B5296F0E56375785F984F7C899F7F9AF6B2C9194B15A6986941981AC7F389B6B4929F2E376CBF404FC982D91B1D5D8742069C5FF04CB06F655261C68FB38232C141DF7E03297340FA6687EF802A2A9B616B998F04BA24B6657E65250B52DF17531834455D250CB3A0E8CDD070B4F89C82F996416365AB47F1028D66207A6BAD8BA74D0E27BB3CE3F234C59C9CD050ED201ED5C816CAA3DF52A43C612C1079BF51304ED475DDDC73A289AFFA650FC7C4C568ACA26474BD48122BC45354B3AB4F070F6B91F64DACB2FB6F3A6B9FC1182A6818184DDBDF76226DEACA74B78CBAAB347134ED242212BE83D5D1BCD7CD70040518875F00402BBD118E941AF4F038674617A6BCA30F22F40CCFBF6138C854020BDFA5D1336B55081EB46965F647EB1EBD9D290056180489B1E7104FBD061B751D0472124624607D2E6867F7079C0531FECF05A79ADEF6F22DD6FFF9431C6A077BAE0384D447F4085CC805165DD8EB9C8C309B2EDD032DF0D4568FC21E428D6049D809567C707829579A066AA7F62C70EC559586A0749109764F5AE32CAC0C2127BB3654141BA6F87F1911671906B60D77BEE322D71515086B4E9BDA8E853DCF1906CFAEB099B0A1BB5EF0A06752A9C89EB506C773DC12FA8DE2DD8FE789624D80406619AE1BB342C7F01F424E4D5908A02731F051996721E2C0CB6703E131F4B5D1768E386783ED41C1C1318F9E19D995CFEEF998D5659D4A9FBEEDE6313B9E4C1665F1E44BF213E66EAE4435DFC2533EB131F235E0075F406028B650E758F38A582705423BB661A095D24E79B6A1D5C6A36989B28FD2ADA228961C1574187F18D419B46545D7FB147358A8409F5CA3ABBFD14EDDE9C0768E84E77F6E61307908F0DD8CD49B9C413EDE4FD13E4D1FB5CFB0075297258D828C20FD01A261F8D5672BFD190FAE191250F533B548B5469879E8B6BDA77D650ADB83AE9FAEC37FBE8A9F5F85CF47159EBC54A9129692A2B253C735E2F629D183A2ED4F2747BCF143D6D673F0F3703D0122BEDC5255F003311A81FA236D0E93D6CCC3375C4C35474427756E58A245A8F0AD68F1226BDA8ABB969A68B0758F1229038CB16711996B27923A0AE7D81384C24763C72B72B6A23A6EED923D0C70A3E47E47BD572A3398F3D651614A47C942A26F785F75A2DE7EE6FC927BE209729BF52943889E8C14708F592036BD3E3E4990659A13D64A755C39BC588B7D03BBE6129A39746304FEF371C760B1986A6FBF4DD588873571984B10FA6624239082E2273F772BC4FB28BC1E57DCCD35511FB1303BA03BE961D3788131E7A106A63BEB8021A609A13F
-20220416133156 2 6 100 7679 2 CBC85C4D4EBCF255C5C59577D8AA5AD90A69B25B5296F0E56375785F984F7C899F7F9AF6B2C9194B15A6986941981AC7F389B6B4929F2E376CBF404FC982D91B1D5D8742069C5FF04CB06F655261C68FB38232C141DF7E03297340FA6687EF802A2A9B616B998F04BA24B6657E65250B52DF17531834455D250CB3A0E8CDD070B4F89C82F996416365AB47F1028D66207A6BAD8BA74D0E27BB3CE3F234C59C9CD050ED201ED5C816CAA3DF52A43C612C1079BF51304ED475DDDC73A289AFFA650FC7C4C568ACA26474BD48122BC45354B3AB4F070F6B91F64DACB2FB6F3A6B9FC1182A6818184DDBDF76226DEACA74B78CBAAB347134ED242212BE83D5D1BCD7CD70040518875F00402BBD118E941AF4F038674617A6BCA30F22F40CCFBF6138C854020BDFA5D1336B55081EB46965F647EB1EBD9D290056180489B1E7104FBD061B751D0472124624607D2E6867F7079C0531FECF05A79ADEF6F22DD6FFF9431C6A077BAE0384D447F4085CC805165DD8EB9C8C309B2EDD032DF0D4568FC21E428D6049D809567C707829579A066AA7F62C70EC559586A0749109764F5AE32CAC0C2127BB3654141BA6F87F1911671906B60D77BEE322D71515086B4E9BDA8E853DCF1906CFAEB099B0A1BB5EF0A06752A9C89EB506C773DC12FA8DE2DD8FE789624D80406619AE1BB342C7F01F424E4D5908A02731F051996721E2C0CB6703E131F4B5D1768E386783ED41C1C1318F9E19D995CFEEF998D5659D4A9FBEEDE6313B9E4C1665F1E44BF213E66EAE4435DFC2533EB131F235E0075F406028B650E758F38A582705423BB661A095D24E79B6A1D5C6A36989B28FD2ADA228961C1574187F18D419B46545D7FB147358A8409F5CA3ABBFD14EDDE9C0768E84E77F6E61307908F0DD8CD49B9C413EDE4FD13E4D1FB5CFB0075297258D828C20FD01A261F8D5672BFD190FAE191250F533B548B5469879E8B6BDA77D650ADB83AE9FAEC37FBE8A9F5F85CF47159EBC54A9129692A2B253C735E2F629D183A2ED4F2747BCF143D6D673F0F3703D0122BEDC5255F003311A81FA236D0E93D6CCC3375C4C35474427756E58A245A8F0AD68F1226BDA8ABB969A68B0758F1229038CB16711996B27923A0AE7D81384C24763C72B72B6A23A6EED923D0C70A3E47E47BD572A3398F3D651614A47C942A26F785F75A2DE7EE6FC927BE209729BF52943889E8C14708F592036BD3E3E4990659A13D64A755C39BC588B7D03BBE6129A39746304FEF371C760B1986A6FBF4DD588873571984B10FA6624239082E2273F772BC4FB28BC1E57DCCD35511FB1303BA03BE961D3788131E7A106A63BEB8021ACA2E43B
-20220416135357 2 6 100 7679 5 CBC85C4D4EBCF255C5C59577D8AA5AD90A69B25B5296F0E56375785F984F7C899F7F9AF6B2C9194B15A6986941981AC7F389B6B4929F2E376CBF404FC982D91B1D5D8742069C5FF04CB06F655261C68FB38232C141DF7E03297340FA6687EF802A2A9B616B998F04BA24B6657E65250B52DF17531834455D250CB3A0E8CDD070B4F89C82F996416365AB47F1028D66207A6BAD8BA74D0E27BB3CE3F234C59C9CD050ED201ED5C816CAA3DF52A43C612C1079BF51304ED475DDDC73A289AFFA650FC7C4C568ACA26474BD48122BC45354B3AB4F070F6B91F64DACB2FB6F3A6B9FC1182A6818184DDBDF76226DEACA74B78CBAAB347134ED242212BE83D5D1BCD7CD70040518875F00402BBD118E941AF4F038674617A6BCA30F22F40CCFBF6138C854020BDFA5D1336B55081EB46965F647EB1EBD9D290056180489B1E7104FBD061B751D0472124624607D2E6867F7079C0531FECF05A79ADEF6F22DD6FFF9431C6A077BAE0384D447F4085CC805165DD8EB9C8C309B2EDD032DF0D4568FC21E428D6049D809567C707829579A066AA7F62C70EC559586A0749109764F5AE32CAC0C2127BB3654141BA6F87F1911671906B60D77BEE322D71515086B4E9BDA8E853DCF1906CFAEB099B0A1BB5EF0A06752A9C89EB506C773DC12FA8DE2DD8FE789624D80406619AE1BB342C7F01F424E4D5908A02731F051996721E2C0CB6703E131F4B5D1768E386783ED41C1C1318F9E19D995CFEEF998D5659D4A9FBEEDE6313B9E4C1665F1E44BF213E66EAE4435DFC2533EB131F235E0075F406028B650E758F38A582705423BB661A095D24E79B6A1D5C6A36989B28FD2ADA228961C1574187F18D419B46545D7FB147358A8409F5CA3ABBFD14EDDE9C0768E84E77F6E61307908F0DD8CD49B9C413EDE4FD13E4D1FB5CFB0075297258D828C20FD01A261F8D5672BFD190FAE191250F533B548B5469879E8B6BDA77D650ADB83AE9FAEC37FBE8A9F5F85CF47159EBC54A9129692A2B253C735E2F629D183A2ED4F2747BCF143D6D673F0F3703D0122BEDC5255F003311A81FA236D0E93D6CCC3375C4C35474427756E58A245A8F0AD68F1226BDA8ABB969A68B0758F1229038CB16711996B27923A0AE7D81384C24763C72B72B6A23A6EED923D0C70A3E47E47BD572A3398F3D651614A47C942A26F785F75A2DE7EE6FC927BE209729BF52943889E8C14708F592036BD3E3E4990659A13D64A755C39BC588B7D03BBE6129A39746304FEF371C760B1986A6FBF4DD588873571984B10FA6624239082E2273F772BC4FB28BC1E57DCCD35511FB1303BA03BE961D3788131E7A106A63BEB8021AE55C347
-20220416150622 2 6 100 7679 2 CBC85C4D4EBCF255C5C59577D8AA5AD90A69B25B5296F0E56375785F984F7C899F7F9AF6B2C9194B15A6986941981AC7F389B6B4929F2E376CBF404FC982D91B1D5D8742069C5FF04CB06F655261C68FB38232C141DF7E03297340FA6687EF802A2A9B616B998F04BA24B6657E65250B52DF17531834455D250CB3A0E8CDD070B4F89C82F996416365AB47F1028D66207A6BAD8BA74D0E27BB3CE3F234C59C9CD050ED201ED5C816CAA3DF52A43C612C1079BF51304ED475DDDC73A289AFFA650FC7C4C568ACA26474BD48122BC45354B3AB4F070F6B91F64DACB2FB6F3A6B9FC1182A6818184DDBDF76226DEACA74B78CBAAB347134ED242212BE83D5D1BCD7CD70040518875F00402BBD118E941AF4F038674617A6BCA30F22F40CCFBF6138C854020BDFA5D1336B55081EB46965F647EB1EBD9D290056180489B1E7104FBD061B751D0472124624607D2E6867F7079C0531FECF05A79ADEF6F22DD6FFF9431C6A077BAE0384D447F4085CC805165DD8EB9C8C309B2EDD032DF0D4568FC21E428D6049D809567C707829579A066AA7F62C70EC559586A0749109764F5AE32CAC0C2127BB3654141BA6F87F1911671906B60D77BEE322D71515086B4E9BDA8E853DCF1906CFAEB099B0A1BB5EF0A06752A9C89EB506C773DC12FA8DE2DD8FE789624D80406619AE1BB342C7F01F424E4D5908A02731F051996721E2C0CB6703E131F4B5D1768E386783ED41C1C1318F9E19D995CFEEF998D5659D4A9FBEEDE6313B9E4C1665F1E44BF213E66EAE4435DFC2533EB131F235E0075F406028B650E758F38A582705423BB661A095D24E79B6A1D5C6A36989B28FD2ADA228961C1574187F18D419B46545D7FB147358A8409F5CA3ABBFD14EDDE9C0768E84E77F6E61307908F0DD8CD49B9C413EDE4FD13E4D1FB5CFB0075297258D828C20FD01A261F8D5672BFD190FAE191250F533B548B5469879E8B6BDA77D650ADB83AE9FAEC37FBE8A9F5F85CF47159EBC54A9129692A2B253C735E2F629D183A2ED4F2747BCF143D6D673F0F3703D0122BEDC5255F003311A81FA236D0E93D6CCC3375C4C35474427756E58A245A8F0AD68F1226BDA8ABB969A68B0758F1229038CB16711996B27923A0AE7D81384C24763C72B72B6A23A6EED923D0C70A3E47E47BD572A3398F3D651614A47C942A26F785F75A2DE7EE6FC927BE209729BF52943889E8C14708F592036BD3E3E4990659A13D64A755C39BC588B7D03BBE6129A39746304FEF371C760B1986A6FBF4DD588873571984B10FA6624239082E2273F772BC4FB28BC1E57DCCD35511FB1303BA03BE961D3788131E7A106A63BEB8021B404E4E3
-20220416151128 2 6 100 7679 5 CBC85C4D4EBCF255C5C59577D8AA5AD90A69B25B5296F0E56375785F984F7C899F7F9AF6B2C9194B15A6986941981AC7F389B6B4929F2E376CBF404FC982D91B1D5D8742069C5FF04CB06F655261C68FB38232C141DF7E03297340FA6687EF802A2A9B616B998F04BA24B6657E65250B52DF17531834455D250CB3A0E8CDD070B4F89C82F996416365AB47F1028D66207A6BAD8BA74D0E27BB3CE3F234C59C9CD050ED201ED5C816CAA3DF52A43C612C1079BF51304ED475DDDC73A289AFFA650FC7C4C568ACA26474BD48122BC45354B3AB4F070F6B91F64DACB2FB6F3A6B9FC1182A6818184DDBDF76226DEACA74B78CBAAB347134ED242212BE83D5D1BCD7CD70040518875F00402BBD118E941AF4F038674617A6BCA30F22F40CCFBF6138C854020BDFA5D1336B55081EB46965F647EB1EBD9D290056180489B1E7104FBD061B751D0472124624607D2E6867F7079C0531FECF05A79ADEF6F22DD6FFF9431C6A077BAE0384D447F4085CC805165DD8EB9C8C309B2EDD032DF0D4568FC21E428D6049D809567C707829579A066AA7F62C70EC559586A0749109764F5AE32CAC0C2127BB3654141BA6F87F1911671906B60D77BEE322D71515086B4E9BDA8E853DCF1906CFAEB099B0A1BB5EF0A06752A9C89EB506C773DC12FA8DE2DD8FE789624D80406619AE1BB342C7F01F424E4D5908A02731F051996721E2C0CB6703E131F4B5D1768E386783ED41C1C1318F9E19D995CFEEF998D5659D4A9FBEEDE6313B9E4C1665F1E44BF213E66EAE4435DFC2533EB131F235E0075F406028B650E758F38A582705423BB661A095D24E79B6A1D5C6A36989B28FD2ADA228961C1574187F18D419B46545D7FB147358A8409F5CA3ABBFD14EDDE9C0768E84E77F6E61307908F0DD8CD49B9C413EDE4FD13E4D1FB5CFB0075297258D828C20FD01A261F8D5672BFD190FAE191250F533B548B5469879E8B6BDA77D650ADB83AE9FAEC37FBE8A9F5F85CF47159EBC54A9129692A2B253C735E2F629D183A2ED4F2747BCF143D6D673F0F3703D0122BEDC5255F003311A81FA236D0E93D6CCC3375C4C35474427756E58A245A8F0AD68F1226BDA8ABB969A68B0758F1229038CB16711996B27923A0AE7D81384C24763C72B72B6A23A6EED923D0C70A3E47E47BD572A3398F3D651614A47C942A26F785F75A2DE7EE6FC927BE209729BF52943889E8C14708F592036BD3E3E4990659A13D64A755C39BC588B7D03BBE6129A39746304FEF371C760B1986A6FBF4DD588873571984B10FA6624239082E2273F772BC4FB28BC1E57DCCD35511FB1303BA03BE961D3788131E7A106A63BEB8021B462EA07
-20220416155217 2 6 100 7679 2 CBC85C4D4EBCF255C5C59577D8AA5AD90A69B25B5296F0E56375785F984F7C899F7F9AF6B2C9194B15A6986941981AC7F389B6B4929F2E376CBF404FC982D91B1D5D8742069C5FF04CB06F655261C68FB38232C141DF7E03297340FA6687EF802A2A9B616B998F04BA24B6657E65250B52DF17531834455D250CB3A0E8CDD070B4F89C82F996416365AB47F1028D66207A6BAD8BA74D0E27BB3CE3F234C59C9CD050ED201ED5C816CAA3DF52A43C612C1079BF51304ED475DDDC73A289AFFA650FC7C4C568ACA26474BD48122BC45354B3AB4F070F6B91F64DACB2FB6F3A6B9FC1182A6818184DDBDF76226DEACA74B78CBAAB347134ED242212BE83D5D1BCD7CD70040518875F00402BBD118E941AF4F038674617A6BCA30F22F40CCFBF6138C854020BDFA5D1336B55081EB46965F647EB1EBD9D290056180489B1E7104FBD061B751D0472124624607D2E6867F7079C0531FECF05A79ADEF6F22DD6FFF9431C6A077BAE0384D447F4085CC805165DD8EB9C8C309B2EDD032DF0D4568FC21E428D6049D809567C707829579A066AA7F62C70EC559586A0749109764F5AE32CAC0C2127BB3654141BA6F87F1911671906B60D77BEE322D71515086B4E9BDA8E853DCF1906CFAEB099B0A1BB5EF0A06752A9C89EB506C773DC12FA8DE2DD8FE789624D80406619AE1BB342C7F01F424E4D5908A02731F051996721E2C0CB6703E131F4B5D1768E386783ED41C1C1318F9E19D995CFEEF998D5659D4A9FBEEDE6313B9E4C1665F1E44BF213E66EAE4435DFC2533EB131F235E0075F406028B650E758F38A582705423BB661A095D24E79B6A1D5C6A36989B28FD2ADA228961C1574187F18D419B46545D7FB147358A8409F5CA3ABBFD14EDDE9C0768E84E77F6E61307908F0DD8CD49B9C413EDE4FD13E4D1FB5CFB0075297258D828C20FD01A261F8D5672BFD190FAE191250F533B548B5469879E8B6BDA77D650ADB83AE9FAEC37FBE8A9F5F85CF47159EBC54A9129692A2B253C735E2F629D183A2ED4F2747BCF143D6D673F0F3703D0122BEDC5255F003311A81FA236D0E93D6CCC3375C4C35474427756E58A245A8F0AD68F1226BDA8ABB969A68B0758F1229038CB16711996B27923A0AE7D81384C24763C72B72B6A23A6EED923D0C70A3E47E47BD572A3398F3D651614A47C942A26F785F75A2DE7EE6FC927BE209729BF52943889E8C14708F592036BD3E3E4990659A13D64A755C39BC588B7D03BBE6129A39746304FEF371C760B1986A6FBF4DD588873571984B10FA6624239082E2273F772BC4FB28BC1E57DCCD35511FB1303BA03BE961D3788131E7A106A63BEB8021B782687B
-20220416155712 2 6 100 7679 2 CBC85C4D4EBCF255C5C59577D8AA5AD90A69B25B5296F0E56375785F984F7C899F7F9AF6B2C9194B15A6986941981AC7F389B6B4929F2E376CBF404FC982D91B1D5D8742069C5FF04CB06F655261C68FB38232C141DF7E03297340FA6687EF802A2A9B616B998F04BA24B6657E65250B52DF17531834455D250CB3A0E8CDD070B4F89C82F996416365AB47F1028D66207A6BAD8BA74D0E27BB3CE3F234C59C9CD050ED201ED5C816CAA3DF52A43C612C1079BF51304ED475DDDC73A289AFFA650FC7C4C568ACA26474BD48122BC45354B3AB4F070F6B91F64DACB2FB6F3A6B9FC1182A6818184DDBDF76226DEACA74B78CBAAB347134ED242212BE83D5D1BCD7CD70040518875F00402BBD118E941AF4F038674617A6BCA30F22F40CCFBF6138C854020BDFA5D1336B55081EB46965F647EB1EBD9D290056180489B1E7104FBD061B751D0472124624607D2E6867F7079C0531FECF05A79ADEF6F22DD6FFF9431C6A077BAE0384D447F4085CC805165DD8EB9C8C309B2EDD032DF0D4568FC21E428D6049D809567C707829579A066AA7F62C70EC559586A0749109764F5AE32CAC0C2127BB3654141BA6F87F1911671906B60D77BEE322D71515086B4E9BDA8E853DCF1906CFAEB099B0A1BB5EF0A06752A9C89EB506C773DC12FA8DE2DD8FE789624D80406619AE1BB342C7F01F424E4D5908A02731F051996721E2C0CB6703E131F4B5D1768E386783ED41C1C1318F9E19D995CFEEF998D5659D4A9FBEEDE6313B9E4C1665F1E44BF213E66EAE4435DFC2533EB131F235E0075F406028B650E758F38A582705423BB661A095D24E79B6A1D5C6A36989B28FD2ADA228961C1574187F18D419B46545D7FB147358A8409F5CA3ABBFD14EDDE9C0768E84E77F6E61307908F0DD8CD49B9C413EDE4FD13E4D1FB5CFB0075297258D828C20FD01A261F8D5672BFD190FAE191250F533B548B5469879E8B6BDA77D650ADB83AE9FAEC37FBE8A9F5F85CF47159EBC54A9129692A2B253C735E2F629D183A2ED4F2747BCF143D6D673F0F3703D0122BEDC5255F003311A81FA236D0E93D6CCC3375C4C35474427756E58A245A8F0AD68F1226BDA8ABB969A68B0758F1229038CB16711996B27923A0AE7D81384C24763C72B72B6A23A6EED923D0C70A3E47E47BD572A3398F3D651614A47C942A26F785F75A2DE7EE6FC927BE209729BF52943889E8C14708F592036BD3E3E4990659A13D64A755C39BC588B7D03BBE6129A39746304FEF371C760B1986A6FBF4DD588873571984B10FA6624239082E2273F772BC4FB28BC1E57DCCD35511FB1303BA03BE961D3788131E7A106A63BEB8021B7D8961B
-20220416165422 2 6 100 7679 2 CBC85C4D4EBCF255C5C59577D8AA5AD90A69B25B5296F0E56375785F984F7C899F7F9AF6B2C9194B15A6986941981AC7F389B6B4929F2E376CBF404FC982D91B1D5D8742069C5FF04CB06F655261C68FB38232C141DF7E03297340FA6687EF802A2A9B616B998F04BA24B6657E65250B52DF17531834455D250CB3A0E8CDD070B4F89C82F996416365AB47F1028D66207A6BAD8BA74D0E27BB3CE3F234C59C9CD050ED201ED5C816CAA3DF52A43C612C1079BF51304ED475DDDC73A289AFFA650FC7C4C568ACA26474BD48122BC45354B3AB4F070F6B91F64DACB2FB6F3A6B9FC1182A6818184DDBDF76226DEACA74B78CBAAB347134ED242212BE83D5D1BCD7CD70040518875F00402BBD118E941AF4F038674617A6BCA30F22F40CCFBF6138C854020BDFA5D1336B55081EB46965F647EB1EBD9D290056180489B1E7104FBD061B751D0472124624607D2E6867F7079C0531FECF05A79ADEF6F22DD6FFF9431C6A077BAE0384D447F4085CC805165DD8EB9C8C309B2EDD032DF0D4568FC21E428D6049D809567C707829579A066AA7F62C70EC559586A0749109764F5AE32CAC0C2127BB3654141BA6F87F1911671906B60D77BEE322D71515086B4E9BDA8E853DCF1906CFAEB099B0A1BB5EF0A06752A9C89EB506C773DC12FA8DE2DD8FE789624D80406619AE1BB342C7F01F424E4D5908A02731F051996721E2C0CB6703E131F4B5D1768E386783ED41C1C1318F9E19D995CFEEF998D5659D4A9FBEEDE6313B9E4C1665F1E44BF213E66EAE4435DFC2533EB131F235E0075F406028B650E758F38A582705423BB661A095D24E79B6A1D5C6A36989B28FD2ADA228961C1574187F18D419B46545D7FB147358A8409F5CA3ABBFD14EDDE9C0768E84E77F6E61307908F0DD8CD49B9C413EDE4FD13E4D1FB5CFB0075297258D828C20FD01A261F8D5672BFD190FAE191250F533B548B5469879E8B6BDA77D650ADB83AE9FAEC37FBE8A9F5F85CF47159EBC54A9129692A2B253C735E2F629D183A2ED4F2747BCF143D6D673F0F3703D0122BEDC5255F003311A81FA236D0E93D6CCC3375C4C35474427756E58A245A8F0AD68F1226BDA8ABB969A68B0758F1229038CB16711996B27923A0AE7D81384C24763C72B72B6A23A6EED923D0C70A3E47E47BD572A3398F3D651614A47C942A26F785F75A2DE7EE6FC927BE209729BF52943889E8C14708F592036BD3E3E4990659A13D64A755C39BC588B7D03BBE6129A39746304FEF371C760B1986A6FBF4DD588873571984B10FA6624239082E2273F772BC4FB28BC1E57DCCD35511FB1303BA03BE961D3788131E7A106A63BEB8021BC44747B
-20220416170631 2 6 100 7679 5 CBC85C4D4EBCF255C5C59577D8AA5AD90A69B25B5296F0E56375785F984F7C899F7F9AF6B2C9194B15A6986941981AC7F389B6B4929F2E376CBF404FC982D91B1D5D8742069C5FF04CB06F655261C68FB38232C141DF7E03297340FA6687EF802A2A9B616B998F04BA24B6657E65250B52DF17531834455D250CB3A0E8CDD070B4F89C82F996416365AB47F1028D66207A6BAD8BA74D0E27BB3CE3F234C59C9CD050ED201ED5C816CAA3DF52A43C612C1079BF51304ED475DDDC73A289AFFA650FC7C4C568ACA26474BD48122BC45354B3AB4F070F6B91F64DACB2FB6F3A6B9FC1182A6818184DDBDF76226DEACA74B78CBAAB347134ED242212BE83D5D1BCD7CD70040518875F00402BBD118E941AF4F038674617A6BCA30F22F40CCFBF6138C854020BDFA5D1336B55081EB46965F647EB1EBD9D290056180489B1E7104FBD061B751D0472124624607D2E6867F7079C0531FECF05A79ADEF6F22DD6FFF9431C6A077BAE0384D447F4085CC805165DD8EB9C8C309B2EDD032DF0D4568FC21E428D6049D809567C707829579A066AA7F62C70EC559586A0749109764F5AE32CAC0C2127BB3654141BA6F87F1911671906B60D77BEE322D71515086B4E9BDA8E853DCF1906CFAEB099B0A1BB5EF0A06752A9C89EB506C773DC12FA8DE2DD8FE789624D80406619AE1BB342C7F01F424E4D5908A02731F051996721E2C0CB6703E131F4B5D1768E386783ED41C1C1318F9E19D995CFEEF998D5659D4A9FBEEDE6313B9E4C1665F1E44BF213E66EAE4435DFC2533EB131F235E0075F406028B650E758F38A582705423BB661A095D24E79B6A1D5C6A36989B28FD2ADA228961C1574187F18D419B46545D7FB147358A8409F5CA3ABBFD14EDDE9C0768E84E77F6E61307908F0DD8CD49B9C413EDE4FD13E4D1FB5CFB0075297258D828C20FD01A261F8D5672BFD190FAE191250F533B548B5469879E8B6BDA77D650ADB83AE9FAEC37FBE8A9F5F85CF47159EBC54A9129692A2B253C735E2F629D183A2ED4F2747BCF143D6D673F0F3703D0122BEDC5255F003311A81FA236D0E93D6CCC3375C4C35474427756E58A245A8F0AD68F1226BDA8ABB969A68B0758F1229038CB16711996B27923A0AE7D81384C24763C72B72B6A23A6EED923D0C70A3E47E47BD572A3398F3D651614A47C942A26F785F75A2DE7EE6FC927BE209729BF52943889E8C14708F592036BD3E3E4990659A13D64A755C39BC588B7D03BBE6129A39746304FEF371C760B1986A6FBF4DD588873571984B10FA6624239082E2273F772BC4FB28BC1E57DCCD35511FB1303BA03BE961D3788131E7A106A63BEB8021BD2BC4F7
-20220416185708 2 6 100 7679 5 CBC85C4D4EBCF255C5C59577D8AA5AD90A69B25B5296F0E56375785F984F7C899F7F9AF6B2C9194B15A6986941981AC7F389B6B4929F2E376CBF404FC982D91B1D5D8742069C5FF04CB06F655261C68FB38232C141DF7E03297340FA6687EF802A2A9B616B998F04BA24B6657E65250B52DF17531834455D250CB3A0E8CDD070B4F89C82F996416365AB47F1028D66207A6BAD8BA74D0E27BB3CE3F234C59C9CD050ED201ED5C816CAA3DF52A43C612C1079BF51304ED475DDDC73A289AFFA650FC7C4C568ACA26474BD48122BC45354B3AB4F070F6B91F64DACB2FB6F3A6B9FC1182A6818184DDBDF76226DEACA74B78CBAAB347134ED242212BE83D5D1BCD7CD70040518875F00402BBD118E941AF4F038674617A6BCA30F22F40CCFBF6138C854020BDFA5D1336B55081EB46965F647EB1EBD9D290056180489B1E7104FBD061B751D0472124624607D2E6867F7079C0531FECF05A79ADEF6F22DD6FFF9431C6A077BAE0384D447F4085CC805165DD8EB9C8C309B2EDD032DF0D4568FC21E428D6049D809567C707829579A066AA7F62C70EC559586A0749109764F5AE32CAC0C2127BB3654141BA6F87F1911671906B60D77BEE322D71515086B4E9BDA8E853DCF1906CFAEB099B0A1BB5EF0A06752A9C89EB506C773DC12FA8DE2DD8FE789624D80406619AE1BB342C7F01F424E4D5908A02731F051996721E2C0CB6703E131F4B5D1768E386783ED41C1C1318F9E19D995CFEEF998D5659D4A9FBEEDE6313B9E4C1665F1E44BF213E66EAE4435DFC2533EB131F235E0075F406028B650E758F38A582705423BB661A095D24E79B6A1D5C6A36989B28FD2ADA228961C1574187F18D419B46545D7FB147358A8409F5CA3ABBFD14EDDE9C0768E84E77F6E61307908F0DD8CD49B9C413EDE4FD13E4D1FB5CFB0075297258D828C20FD01A261F8D5672BFD190FAE191250F533B548B5469879E8B6BDA77D650ADB83AE9FAEC37FBE8A9F5F85CF47159EBC54A9129692A2B253C735E2F629D183A2ED4F2747BCF143D6D673F0F3703D0122BEDC5255F003311A81FA236D0E93D6CCC3375C4C35474427756E58A245A8F0AD68F1226BDA8ABB969A68B0758F1229038CB16711996B27923A0AE7D81384C24763C72B72B6A23A6EED923D0C70A3E47E47BD572A3398F3D651614A47C942A26F785F75A2DE7EE6FC927BE209729BF52943889E8C14708F592036BD3E3E4990659A13D64A755C39BC588B7D03BBE6129A39746304FEF371C760B1986A6FBF4DD588873571984B10FA6624239082E2273F772BC4FB28BC1E57DCCD35511FB1303BA03BE961D3788131E7A106A63BEB8021C588EACF
-20220416193124 2 6 100 7679 2 CBC85C4D4EBCF255C5C59577D8AA5AD90A69B25B5296F0E56375785F984F7C899F7F9AF6B2C9194B15A6986941981AC7F389B6B4929F2E376CBF404FC982D91B1D5D8742069C5FF04CB06F655261C68FB38232C141DF7E03297340FA6687EF802A2A9B616B998F04BA24B6657E65250B52DF17531834455D250CB3A0E8CDD070B4F89C82F996416365AB47F1028D66207A6BAD8BA74D0E27BB3CE3F234C59C9CD050ED201ED5C816CAA3DF52A43C612C1079BF51304ED475DDDC73A289AFFA650FC7C4C568ACA26474BD48122BC45354B3AB4F070F6B91F64DACB2FB6F3A6B9FC1182A6818184DDBDF76226DEACA74B78CBAAB347134ED242212BE83D5D1BCD7CD70040518875F00402BBD118E941AF4F038674617A6BCA30F22F40CCFBF6138C854020BDFA5D1336B55081EB46965F647EB1EBD9D290056180489B1E7104FBD061B751D0472124624607D2E6867F7079C0531FECF05A79ADEF6F22DD6FFF9431C6A077BAE0384D447F4085CC805165DD8EB9C8C309B2EDD032DF0D4568FC21E428D6049D809567C707829579A066AA7F62C70EC559586A0749109764F5AE32CAC0C2127BB3654141BA6F87F1911671906B60D77BEE322D71515086B4E9BDA8E853DCF1906CFAEB099B0A1BB5EF0A06752A9C89EB506C773DC12FA8DE2DD8FE789624D80406619AE1BB342C7F01F424E4D5908A02731F051996721E2C0CB6703E131F4B5D1768E386783ED41C1C1318F9E19D995CFEEF998D5659D4A9FBEEDE6313B9E4C1665F1E44BF213E66EAE4435DFC2533EB131F235E0075F406028B650E758F38A582705423BB661A095D24E79B6A1D5C6A36989B28FD2ADA228961C1574187F18D419B46545D7FB147358A8409F5CA3ABBFD14EDDE9C0768E84E77F6E61307908F0DD8CD49B9C413EDE4FD13E4D1FB5CFB0075297258D828C20FD01A261F8D5672BFD190FAE191250F533B548B5469879E8B6BDA77D650ADB83AE9FAEC37FBE8A9F5F85CF47159EBC54A9129692A2B253C735E2F629D183A2ED4F2747BCF143D6D673F0F3703D0122BEDC5255F003311A81FA236D0E93D6CCC3375C4C35474427756E58A245A8F0AD68F1226BDA8ABB969A68B0758F1229038CB16711996B27923A0AE7D81384C24763C72B72B6A23A6EED923D0C70A3E47E47BD572A3398F3D651614A47C942A26F785F75A2DE7EE6FC927BE209729BF52943889E8C14708F592036BD3E3E4990659A13D64A755C39BC588B7D03BBE6129A39746304FEF371C760B1986A6FBF4DD588873571984B10FA6624239082E2273F772BC4FB28BC1E57DCCD35511FB1303BA03BE961D3788131E7A106A63BEB8021C8261C8B
-20220416194631 2 6 100 7679 2 CBC85C4D4EBCF255C5C59577D8AA5AD90A69B25B5296F0E56375785F984F7C899F7F9AF6B2C9194B15A6986941981AC7F389B6B4929F2E376CBF404FC982D91B1D5D8742069C5FF04CB06F655261C68FB38232C141DF7E03297340FA6687EF802A2A9B616B998F04BA24B6657E65250B52DF17531834455D250CB3A0E8CDD070B4F89C82F996416365AB47F1028D66207A6BAD8BA74D0E27BB3CE3F234C59C9CD050ED201ED5C816CAA3DF52A43C612C1079BF51304ED475DDDC73A289AFFA650FC7C4C568ACA26474BD48122BC45354B3AB4F070F6B91F64DACB2FB6F3A6B9FC1182A6818184DDBDF76226DEACA74B78CBAAB347134ED242212BE83D5D1BCD7CD70040518875F00402BBD118E941AF4F038674617A6BCA30F22F40CCFBF6138C854020BDFA5D1336B55081EB46965F647EB1EBD9D290056180489B1E7104FBD061B751D0472124624607D2E6867F7079C0531FECF05A79ADEF6F22DD6FFF9431C6A077BAE0384D447F4085CC805165DD8EB9C8C309B2EDD032DF0D4568FC21E428D6049D809567C707829579A066AA7F62C70EC559586A0749109764F5AE32CAC0C2127BB3654141BA6F87F1911671906B60D77BEE322D71515086B4E9BDA8E853DCF1906CFAEB099B0A1BB5EF0A06752A9C89EB506C773DC12FA8DE2DD8FE789624D80406619AE1BB342C7F01F424E4D5908A02731F051996721E2C0CB6703E131F4B5D1768E386783ED41C1C1318F9E19D995CFEEF998D5659D4A9FBEEDE6313B9E4C1665F1E44BF213E66EAE4435DFC2533EB131F235E0075F406028B650E758F38A582705423BB661A095D24E79B6A1D5C6A36989B28FD2ADA228961C1574187F18D419B46545D7FB147358A8409F5CA3ABBFD14EDDE9C0768E84E77F6E61307908F0DD8CD49B9C413EDE4FD13E4D1FB5CFB0075297258D828C20FD01A261F8D5672BFD190FAE191250F533B548B5469879E8B6BDA77D650ADB83AE9FAEC37FBE8A9F5F85CF47159EBC54A9129692A2B253C735E2F629D183A2ED4F2747BCF143D6D673F0F3703D0122BEDC5255F003311A81FA236D0E93D6CCC3375C4C35474427756E58A245A8F0AD68F1226BDA8ABB969A68B0758F1229038CB16711996B27923A0AE7D81384C24763C72B72B6A23A6EED923D0C70A3E47E47BD572A3398F3D651614A47C942A26F785F75A2DE7EE6FC927BE209729BF52943889E8C14708F592036BD3E3E4990659A13D64A755C39BC588B7D03BBE6129A39746304FEF371C760B1986A6FBF4DD588873571984B10FA6624239082E2273F772BC4FB28BC1E57DCCD35511FB1303BA03BE961D3788131E7A106A63BEB8021C941917B
-20220416200225 2 6 100 7679 5 CBC85C4D4EBCF255C5C59577D8AA5AD90A69B25B5296F0E56375785F984F7C899F7F9AF6B2C9194B15A6986941981AC7F389B6B4929F2E376CBF404FC982D91B1D5D8742069C5FF04CB06F655261C68FB38232C141DF7E03297340FA6687EF802A2A9B616B998F04BA24B6657E65250B52DF17531834455D250CB3A0E8CDD070B4F89C82F996416365AB47F1028D66207A6BAD8BA74D0E27BB3CE3F234C59C9CD050ED201ED5C816CAA3DF52A43C612C1079BF51304ED475DDDC73A289AFFA650FC7C4C568ACA26474BD48122BC45354B3AB4F070F6B91F64DACB2FB6F3A6B9FC1182A6818184DDBDF76226DEACA74B78CBAAB347134ED242212BE83D5D1BCD7CD70040518875F00402BBD118E941AF4F038674617A6BCA30F22F40CCFBF6138C854020BDFA5D1336B55081EB46965F647EB1EBD9D290056180489B1E7104FBD061B751D0472124624607D2E6867F7079C0531FECF05A79ADEF6F22DD6FFF9431C6A077BAE0384D447F4085CC805165DD8EB9C8C309B2EDD032DF0D4568FC21E428D6049D809567C707829579A066AA7F62C70EC559586A0749109764F5AE32CAC0C2127BB3654141BA6F87F1911671906B60D77BEE322D71515086B4E9BDA8E853DCF1906CFAEB099B0A1BB5EF0A06752A9C89EB506C773DC12FA8DE2DD8FE789624D80406619AE1BB342C7F01F424E4D5908A02731F051996721E2C0CB6703E131F4B5D1768E386783ED41C1C1318F9E19D995CFEEF998D5659D4A9FBEEDE6313B9E4C1665F1E44BF213E66EAE4435DFC2533EB131F235E0075F406028B650E758F38A582705423BB661A095D24E79B6A1D5C6A36989B28FD2ADA228961C1574187F18D419B46545D7FB147358A8409F5CA3ABBFD14EDDE9C0768E84E77F6E61307908F0DD8CD49B9C413EDE4FD13E4D1FB5CFB0075297258D828C20FD01A261F8D5672BFD190FAE191250F533B548B5469879E8B6BDA77D650ADB83AE9FAEC37FBE8A9F5F85CF47159EBC54A9129692A2B253C735E2F629D183A2ED4F2747BCF143D6D673F0F3703D0122BEDC5255F003311A81FA236D0E93D6CCC3375C4C35474427756E58A245A8F0AD68F1226BDA8ABB969A68B0758F1229038CB16711996B27923A0AE7D81384C24763C72B72B6A23A6EED923D0C70A3E47E47BD572A3398F3D651614A47C942A26F785F75A2DE7EE6FC927BE209729BF52943889E8C14708F592036BD3E3E4990659A13D64A755C39BC588B7D03BBE6129A39746304FEF371C760B1986A6FBF4DD588873571984B10FA6624239082E2273F772BC4FB28BC1E57DCCD35511FB1303BA03BE961D3788131E7A106A63BEB8021CA6E54B7
-20220416201249 2 6 100 7679 2 CBC85C4D4EBCF255C5C59577D8AA5AD90A69B25B5296F0E56375785F984F7C899F7F9AF6B2C9194B15A6986941981AC7F389B6B4929F2E376CBF404FC982D91B1D5D8742069C5FF04CB06F655261C68FB38232C141DF7E03297340FA6687EF802A2A9B616B998F04BA24B6657E65250B52DF17531834455D250CB3A0E8CDD070B4F89C82F996416365AB47F1028D66207A6BAD8BA74D0E27BB3CE3F234C59C9CD050ED201ED5C816CAA3DF52A43C612C1079BF51304ED475DDDC73A289AFFA650FC7C4C568ACA26474BD48122BC45354B3AB4F070F6B91F64DACB2FB6F3A6B9FC1182A6818184DDBDF76226DEACA74B78CBAAB347134ED242212BE83D5D1BCD7CD70040518875F00402BBD118E941AF4F038674617A6BCA30F22F40CCFBF6138C854020BDFA5D1336B55081EB46965F647EB1EBD9D290056180489B1E7104FBD061B751D0472124624607D2E6867F7079C0531FECF05A79ADEF6F22DD6FFF9431C6A077BAE0384D447F4085CC805165DD8EB9C8C309B2EDD032DF0D4568FC21E428D6049D809567C707829579A066AA7F62C70EC559586A0749109764F5AE32CAC0C2127BB3654141BA6F87F1911671906B60D77BEE322D71515086B4E9BDA8E853DCF1906CFAEB099B0A1BB5EF0A06752A9C89EB506C773DC12FA8DE2DD8FE789624D80406619AE1BB342C7F01F424E4D5908A02731F051996721E2C0CB6703E131F4B5D1768E386783ED41C1C1318F9E19D995CFEEF998D5659D4A9FBEEDE6313B9E4C1665F1E44BF213E66EAE4435DFC2533EB131F235E0075F406028B650E758F38A582705423BB661A095D24E79B6A1D5C6A36989B28FD2ADA228961C1574187F18D419B46545D7FB147358A8409F5CA3ABBFD14EDDE9C0768E84E77F6E61307908F0DD8CD49B9C413EDE4FD13E4D1FB5CFB0075297258D828C20FD01A261F8D5672BFD190FAE191250F533B548B5469879E8B6BDA77D650ADB83AE9FAEC37FBE8A9F5F85CF47159EBC54A9129692A2B253C735E2F629D183A2ED4F2747BCF143D6D673F0F3703D0122BEDC5255F003311A81FA236D0E93D6CCC3375C4C35474427756E58A245A8F0AD68F1226BDA8ABB969A68B0758F1229038CB16711996B27923A0AE7D81384C24763C72B72B6A23A6EED923D0C70A3E47E47BD572A3398F3D651614A47C942A26F785F75A2DE7EE6FC927BE209729BF52943889E8C14708F592036BD3E3E4990659A13D64A755C39BC588B7D03BBE6129A39746304FEF371C760B1986A6FBF4DD588873571984B10FA6624239082E2273F772BC4FB28BC1E57DCCD35511FB1303BA03BE961D3788131E7A106A63BEB8021CB31B7C3
-20220416204005 2 6 100 7679 2 CBC85C4D4EBCF255C5C59577D8AA5AD90A69B25B5296F0E56375785F984F7C899F7F9AF6B2C9194B15A6986941981AC7F389B6B4929F2E376CBF404FC982D91B1D5D8742069C5FF04CB06F655261C68FB38232C141DF7E03297340FA6687EF802A2A9B616B998F04BA24B6657E65250B52DF17531834455D250CB3A0E8CDD070B4F89C82F996416365AB47F1028D66207A6BAD8BA74D0E27BB3CE3F234C59C9CD050ED201ED5C816CAA3DF52A43C612C1079BF51304ED475DDDC73A289AFFA650FC7C4C568ACA26474BD48122BC45354B3AB4F070F6B91F64DACB2FB6F3A6B9FC1182A6818184DDBDF76226DEACA74B78CBAAB347134ED242212BE83D5D1BCD7CD70040518875F00402BBD118E941AF4F038674617A6BCA30F22F40CCFBF6138C854020BDFA5D1336B55081EB46965F647EB1EBD9D290056180489B1E7104FBD061B751D0472124624607D2E6867F7079C0531FECF05A79ADEF6F22DD6FFF9431C6A077BAE0384D447F4085CC805165DD8EB9C8C309B2EDD032DF0D4568FC21E428D6049D809567C707829579A066AA7F62C70EC559586A0749109764F5AE32CAC0C2127BB3654141BA6F87F1911671906B60D77BEE322D71515086B4E9BDA8E853DCF1906CFAEB099B0A1BB5EF0A06752A9C89EB506C773DC12FA8DE2DD8FE789624D80406619AE1BB342C7F01F424E4D5908A02731F051996721E2C0CB6703E131F4B5D1768E386783ED41C1C1318F9E19D995CFEEF998D5659D4A9FBEEDE6313B9E4C1665F1E44BF213E66EAE4435DFC2533EB131F235E0075F406028B650E758F38A582705423BB661A095D24E79B6A1D5C6A36989B28FD2ADA228961C1574187F18D419B46545D7FB147358A8409F5CA3ABBFD14EDDE9C0768E84E77F6E61307908F0DD8CD49B9C413EDE4FD13E4D1FB5CFB0075297258D828C20FD01A261F8D5672BFD190FAE191250F533B548B5469879E8B6BDA77D650ADB83AE9FAEC37FBE8A9F5F85CF47159EBC54A9129692A2B253C735E2F629D183A2ED4F2747BCF143D6D673F0F3703D0122BEDC5255F003311A81FA236D0E93D6CCC3375C4C35474427756E58A245A8F0AD68F1226BDA8ABB969A68B0758F1229038CB16711996B27923A0AE7D81384C24763C72B72B6A23A6EED923D0C70A3E47E47BD572A3398F3D651614A47C942A26F785F75A2DE7EE6FC927BE209729BF52943889E8C14708F592036BD3E3E4990659A13D64A755C39BC588B7D03BBE6129A39746304FEF371C760B1986A6FBF4DD588873571984B10FA6624239082E2273F772BC4FB28BC1E57DCCD35511FB1303BA03BE961D3788131E7A106A63BEB8021CD39B303
-20220416214143 2 6 100 7679 2 CBC85C4D4EBCF255C5C59577D8AA5AD90A69B25B5296F0E56375785F984F7C899F7F9AF6B2C9194B15A6986941981AC7F389B6B4929F2E376CBF404FC982D91B1D5D8742069C5FF04CB06F655261C68FB38232C141DF7E03297340FA6687EF802A2A9B616B998F04BA24B6657E65250B52DF17531834455D250CB3A0E8CDD070B4F89C82F996416365AB47F1028D66207A6BAD8BA74D0E27BB3CE3F234C59C9CD050ED201ED5C816CAA3DF52A43C612C1079BF51304ED475DDDC73A289AFFA650FC7C4C568ACA26474BD48122BC45354B3AB4F070F6B91F64DACB2FB6F3A6B9FC1182A6818184DDBDF76226DEACA74B78CBAAB347134ED242212BE83D5D1BCD7CD70040518875F00402BBD118E941AF4F038674617A6BCA30F22F40CCFBF6138C854020BDFA5D1336B55081EB46965F647EB1EBD9D290056180489B1E7104FBD061B751D0472124624607D2E6867F7079C0531FECF05A79ADEF6F22DD6FFF9431C6A077BAE0384D447F4085CC805165DD8EB9C8C309B2EDD032DF0D4568FC21E428D6049D809567C707829579A066AA7F62C70EC559586A0749109764F5AE32CAC0C2127BB3654141BA6F87F1911671906B60D77BEE322D71515086B4E9BDA8E853DCF1906CFAEB099B0A1BB5EF0A06752A9C89EB506C773DC12FA8DE2DD8FE789624D80406619AE1BB342C7F01F424E4D5908A02731F051996721E2C0CB6703E131F4B5D1768E386783ED41C1C1318F9E19D995CFEEF998D5659D4A9FBEEDE6313B9E4C1665F1E44BF213E66EAE4435DFC2533EB131F235E0075F406028B650E758F38A582705423BB661A095D24E79B6A1D5C6A36989B28FD2ADA228961C1574187F18D419B46545D7FB147358A8409F5CA3ABBFD14EDDE9C0768E84E77F6E61307908F0DD8CD49B9C413EDE4FD13E4D1FB5CFB0075297258D828C20FD01A261F8D5672BFD190FAE191250F533B548B5469879E8B6BDA77D650ADB83AE9FAEC37FBE8A9F5F85CF47159EBC54A9129692A2B253C735E2F629D183A2ED4F2747BCF143D6D673F0F3703D0122BEDC5255F003311A81FA236D0E93D6CCC3375C4C35474427756E58A245A8F0AD68F1226BDA8ABB969A68B0758F1229038CB16711996B27923A0AE7D81384C24763C72B72B6A23A6EED923D0C70A3E47E47BD572A3398F3D651614A47C942A26F785F75A2DE7EE6FC927BE209729BF52943889E8C14708F592036BD3E3E4990659A13D64A755C39BC588B7D03BBE6129A39746304FEF371C760B1986A6FBF4DD588873571984B10FA6624239082E2273F772BC4FB28BC1E57DCCD35511FB1303BA03BE961D3788131E7A106A63BEB8021D1CB213B
-20220416222645 2 6 100 7679 2 CBC85C4D4EBCF255C5C59577D8AA5AD90A69B25B5296F0E56375785F984F7C899F7F9AF6B2C9194B15A6986941981AC7F389B6B4929F2E376CBF404FC982D91B1D5D8742069C5FF04CB06F655261C68FB38232C141DF7E03297340FA6687EF802A2A9B616B998F04BA24B6657E65250B52DF17531834455D250CB3A0E8CDD070B4F89C82F996416365AB47F1028D66207A6BAD8BA74D0E27BB3CE3F234C59C9CD050ED201ED5C816CAA3DF52A43C612C1079BF51304ED475DDDC73A289AFFA650FC7C4C568ACA26474BD48122BC45354B3AB4F070F6B91F64DACB2FB6F3A6B9FC1182A6818184DDBDF76226DEACA74B78CBAAB347134ED242212BE83D5D1BCD7CD70040518875F00402BBD118E941AF4F038674617A6BCA30F22F40CCFBF6138C854020BDFA5D1336B55081EB46965F647EB1EBD9D290056180489B1E7104FBD061B751D0472124624607D2E6867F7079C0531FECF05A79ADEF6F22DD6FFF9431C6A077BAE0384D447F4085CC805165DD8EB9C8C309B2EDD032DF0D4568FC21E428D6049D809567C707829579A066AA7F62C70EC559586A0749109764F5AE32CAC0C2127BB3654141BA6F87F1911671906B60D77BEE322D71515086B4E9BDA8E853DCF1906CFAEB099B0A1BB5EF0A06752A9C89EB506C773DC12FA8DE2DD8FE789624D80406619AE1BB342C7F01F424E4D5908A02731F051996721E2C0CB6703E131F4B5D1768E386783ED41C1C1318F9E19D995CFEEF998D5659D4A9FBEEDE6313B9E4C1665F1E44BF213E66EAE4435DFC2533EB131F235E0075F406028B650E758F38A582705423BB661A095D24E79B6A1D5C6A36989B28FD2ADA228961C1574187F18D419B46545D7FB147358A8409F5CA3ABBFD14EDDE9C0768E84E77F6E61307908F0DD8CD49B9C413EDE4FD13E4D1FB5CFB0075297258D828C20FD01A261F8D5672BFD190FAE191250F533B548B5469879E8B6BDA77D650ADB83AE9FAEC37FBE8A9F5F85CF47159EBC54A9129692A2B253C735E2F629D183A2ED4F2747BCF143D6D673F0F3703D0122BEDC5255F003311A81FA236D0E93D6CCC3375C4C35474427756E58A245A8F0AD68F1226BDA8ABB969A68B0758F1229038CB16711996B27923A0AE7D81384C24763C72B72B6A23A6EED923D0C70A3E47E47BD572A3398F3D651614A47C942A26F785F75A2DE7EE6FC927BE209729BF52943889E8C14708F592036BD3E3E4990659A13D64A755C39BC588B7D03BBE6129A39746304FEF371C760B1986A6FBF4DD588873571984B10FA6624239082E2273F772BC4FB28BC1E57DCCD35511FB1303BA03BE961D3788131E7A106A63BEB8021D51E3AB3
-20220416230352 2 6 100 7679 5 CBC85C4D4EBCF255C5C59577D8AA5AD90A69B25B5296F0E56375785F984F7C899F7F9AF6B2C9194B15A6986941981AC7F389B6B4929F2E376CBF404FC982D91B1D5D8742069C5FF04CB06F655261C68FB38232C141DF7E03297340FA6687EF802A2A9B616B998F04BA24B6657E65250B52DF17531834455D250CB3A0E8CDD070B4F89C82F996416365AB47F1028D66207A6BAD8BA74D0E27BB3CE3F234C59C9CD050ED201ED5C816CAA3DF52A43C612C1079BF51304ED475DDDC73A289AFFA650FC7C4C568ACA26474BD48122BC45354B3AB4F070F6B91F64DACB2FB6F3A6B9FC1182A6818184DDBDF76226DEACA74B78CBAAB347134ED242212BE83D5D1BCD7CD70040518875F00402BBD118E941AF4F038674617A6BCA30F22F40CCFBF6138C854020BDFA5D1336B55081EB46965F647EB1EBD9D290056180489B1E7104FBD061B751D0472124624607D2E6867F7079C0531FECF05A79ADEF6F22DD6FFF9431C6A077BAE0384D447F4085CC805165DD8EB9C8C309B2EDD032DF0D4568FC21E428D6049D809567C707829579A066AA7F62C70EC559586A0749109764F5AE32CAC0C2127BB3654141BA6F87F1911671906B60D77BEE322D71515086B4E9BDA8E853DCF1906CFAEB099B0A1BB5EF0A06752A9C89EB506C773DC12FA8DE2DD8FE789624D80406619AE1BB342C7F01F424E4D5908A02731F051996721E2C0CB6703E131F4B5D1768E386783ED41C1C1318F9E19D995CFEEF998D5659D4A9FBEEDE6313B9E4C1665F1E44BF213E66EAE4435DFC2533EB131F235E0075F406028B650E758F38A582705423BB661A095D24E79B6A1D5C6A36989B28FD2ADA228961C1574187F18D419B46545D7FB147358A8409F5CA3ABBFD14EDDE9C0768E84E77F6E61307908F0DD8CD49B9C413EDE4FD13E4D1FB5CFB0075297258D828C20FD01A261F8D5672BFD190FAE191250F533B548B5469879E8B6BDA77D650ADB83AE9FAEC37FBE8A9F5F85CF47159EBC54A9129692A2B253C735E2F629D183A2ED4F2747BCF143D6D673F0F3703D0122BEDC5255F003311A81FA236D0E93D6CCC3375C4C35474427756E58A245A8F0AD68F1226BDA8ABB969A68B0758F1229038CB16711996B27923A0AE7D81384C24763C72B72B6A23A6EED923D0C70A3E47E47BD572A3398F3D651614A47C942A26F785F75A2DE7EE6FC927BE209729BF52943889E8C14708F592036BD3E3E4990659A13D64A755C39BC588B7D03BBE6129A39746304FEF371C760B1986A6FBF4DD588873571984B10FA6624239082E2273F772BC4FB28BC1E57DCCD35511FB1303BA03BE961D3788131E7A106A63BEB8021D7D44ED7
-20220416234159 2 6 100 7679 2 CBC85C4D4EBCF255C5C59577D8AA5AD90A69B25B5296F0E56375785F984F7C899F7F9AF6B2C9194B15A6986941981AC7F389B6B4929F2E376CBF404FC982D91B1D5D8742069C5FF04CB06F655261C68FB38232C141DF7E03297340FA6687EF802A2A9B616B998F04BA24B6657E65250B52DF17531834455D250CB3A0E8CDD070B4F89C82F996416365AB47F1028D66207A6BAD8BA74D0E27BB3CE3F234C59C9CD050ED201ED5C816CAA3DF52A43C612C1079BF51304ED475DDDC73A289AFFA650FC7C4C568ACA26474BD48122BC45354B3AB4F070F6B91F64DACB2FB6F3A6B9FC1182A6818184DDBDF76226DEACA74B78CBAAB347134ED242212BE83D5D1BCD7CD70040518875F00402BBD118E941AF4F038674617A6BCA30F22F40CCFBF6138C854020BDFA5D1336B55081EB46965F647EB1EBD9D290056180489B1E7104FBD061B751D0472124624607D2E6867F7079C0531FECF05A79ADEF6F22DD6FFF9431C6A077BAE0384D447F4085CC805165DD8EB9C8C309B2EDD032DF0D4568FC21E428D6049D809567C707829579A066AA7F62C70EC559586A0749109764F5AE32CAC0C2127BB3654141BA6F87F1911671906B60D77BEE322D71515086B4E9BDA8E853DCF1906CFAEB099B0A1BB5EF0A06752A9C89EB506C773DC12FA8DE2DD8FE789624D80406619AE1BB342C7F01F424E4D5908A02731F051996721E2C0CB6703E131F4B5D1768E386783ED41C1C1318F9E19D995CFEEF998D5659D4A9FBEEDE6313B9E4C1665F1E44BF213E66EAE4435DFC2533EB131F235E0075F406028B650E758F38A582705423BB661A095D24E79B6A1D5C6A36989B28FD2ADA228961C1574187F18D419B46545D7FB147358A8409F5CA3ABBFD14EDDE9C0768E84E77F6E61307908F0DD8CD49B9C413EDE4FD13E4D1FB5CFB0075297258D828C20FD01A261F8D5672BFD190FAE191250F533B548B5469879E8B6BDA77D650ADB83AE9FAEC37FBE8A9F5F85CF47159EBC54A9129692A2B253C735E2F629D183A2ED4F2747BCF143D6D673F0F3703D0122BEDC5255F003311A81FA236D0E93D6CCC3375C4C35474427756E58A245A8F0AD68F1226BDA8ABB969A68B0758F1229038CB16711996B27923A0AE7D81384C24763C72B72B6A23A6EED923D0C70A3E47E47BD572A3398F3D651614A47C942A26F785F75A2DE7EE6FC927BE209729BF52943889E8C14708F592036BD3E3E4990659A13D64A755C39BC588B7D03BBE6129A39746304FEF371C760B1986A6FBF4DD588873571984B10FA6624239082E2273F772BC4FB28BC1E57DCCD35511FB1303BA03BE961D3788131E7A106A63BEB8021DAA0700B
-20220417010500 2 6 100 7679 2 CBC85C4D4EBCF255C5C59577D8AA5AD90A69B25B5296F0E56375785F984F7C899F7F9AF6B2C9194B15A6986941981AC7F389B6B4929F2E376CBF404FC982D91B1D5D8742069C5FF04CB06F655261C68FB38232C141DF7E03297340FA6687EF802A2A9B616B998F04BA24B6657E65250B52DF17531834455D250CB3A0E8CDD070B4F89C82F996416365AB47F1028D66207A6BAD8BA74D0E27BB3CE3F234C59C9CD050ED201ED5C816CAA3DF52A43C612C1079BF51304ED475DDDC73A289AFFA650FC7C4C568ACA26474BD48122BC45354B3AB4F070F6B91F64DACB2FB6F3A6B9FC1182A6818184DDBDF76226DEACA74B78CBAAB347134ED242212BE83D5D1BCD7CD70040518875F00402BBD118E941AF4F038674617A6BCA30F22F40CCFBF6138C854020BDFA5D1336B55081EB46965F647EB1EBD9D290056180489B1E7104FBD061B751D0472124624607D2E6867F7079C0531FECF05A79ADEF6F22DD6FFF9431C6A077BAE0384D447F4085CC805165DD8EB9C8C309B2EDD032DF0D4568FC21E428D6049D809567C707829579A066AA7F62C70EC559586A0749109764F5AE32CAC0C2127BB3654141BA6F87F1911671906B60D77BEE322D71515086B4E9BDA8E853DCF1906CFAEB099B0A1BB5EF0A06752A9C89EB506C773DC12FA8DE2DD8FE789624D80406619AE1BB342C7F01F424E4D5908A02731F051996721E2C0CB6703E131F4B5D1768E386783ED41C1C1318F9E19D995CFEEF998D5659D4A9FBEEDE6313B9E4C1665F1E44BF213E66EAE4435DFC2533EB131F235E0075F406028B650E758F38A582705423BB661A095D24E79B6A1D5C6A36989B28FD2ADA228961C1574187F18D419B46545D7FB147358A8409F5CA3ABBFD14EDDE9C0768E84E77F6E61307908F0DD8CD49B9C413EDE4FD13E4D1FB5CFB0075297258D828C20FD01A261F8D5672BFD190FAE191250F533B548B5469879E8B6BDA77D650ADB83AE9FAEC37FBE8A9F5F85CF47159EBC54A9129692A2B253C735E2F629D183A2ED4F2747BCF143D6D673F0F3703D0122BEDC5255F003311A81FA236D0E93D6CCC3375C4C35474427756E58A245A8F0AD68F1226BDA8ABB969A68B0758F1229038CB16711996B27923A0AE7D81384C24763C72B72B6A23A6EED923D0C70A3E47E47BD572A3398F3D651614A47C942A26F785F75A2DE7EE6FC927BE209729BF52943889E8C14708F592036BD3E3E4990659A13D64A755C39BC588B7D03BBE6129A39746304FEF371C760B1986A6FBF4DD588873571984B10FA6624239082E2273F772BC4FB28BC1E57DCCD35511FB1303BA03BE961D3788131E7A106A63BEB8021E0C9B503
-20220417020435 2 6 100 7679 2 CBC85C4D4EBCF255C5C59577D8AA5AD90A69B25B5296F0E56375785F984F7C899F7F9AF6B2C9194B15A6986941981AC7F389B6B4929F2E376CBF404FC982D91B1D5D8742069C5FF04CB06F655261C68FB38232C141DF7E03297340FA6687EF802A2A9B616B998F04BA24B6657E65250B52DF17531834455D250CB3A0E8CDD070B4F89C82F996416365AB47F1028D66207A6BAD8BA74D0E27BB3CE3F234C59C9CD050ED201ED5C816CAA3DF52A43C612C1079BF51304ED475DDDC73A289AFFA650FC7C4C568ACA26474BD48122BC45354B3AB4F070F6B91F64DACB2FB6F3A6B9FC1182A6818184DDBDF76226DEACA74B78CBAAB347134ED242212BE83D5D1BCD7CD70040518875F00402BBD118E941AF4F038674617A6BCA30F22F40CCFBF6138C854020BDFA5D1336B55081EB46965F647EB1EBD9D290056180489B1E7104FBD061B751D0472124624607D2E6867F7079C0531FECF05A79ADEF6F22DD6FFF9431C6A077BAE0384D447F4085CC805165DD8EB9C8C309B2EDD032DF0D4568FC21E428D6049D809567C707829579A066AA7F62C70EC559586A0749109764F5AE32CAC0C2127BB3654141BA6F87F1911671906B60D77BEE322D71515086B4E9BDA8E853DCF1906CFAEB099B0A1BB5EF0A06752A9C89EB506C773DC12FA8DE2DD8FE789624D80406619AE1BB342C7F01F424E4D5908A02731F051996721E2C0CB6703E131F4B5D1768E386783ED41C1C1318F9E19D995CFEEF998D5659D4A9FBEEDE6313B9E4C1665F1E44BF213E66EAE4435DFC2533EB131F235E0075F406028B650E758F38A582705423BB661A095D24E79B6A1D5C6A36989B28FD2ADA228961C1574187F18D419B46545D7FB147358A8409F5CA3ABBFD14EDDE9C0768E84E77F6E61307908F0DD8CD49B9C413EDE4FD13E4D1FB5CFB0075297258D828C20FD01A261F8D5672BFD190FAE191250F533B548B5469879E8B6BDA77D650ADB83AE9FAEC37FBE8A9F5F85CF47159EBC54A9129692A2B253C735E2F629D183A2ED4F2747BCF143D6D673F0F3703D0122BEDC5255F003311A81FA236D0E93D6CCC3375C4C35474427756E58A245A8F0AD68F1226BDA8ABB969A68B0758F1229038CB16711996B27923A0AE7D81384C24763C72B72B6A23A6EED923D0C70A3E47E47BD572A3398F3D651614A47C942A26F785F75A2DE7EE6FC927BE209729BF52943889E8C14708F592036BD3E3E4990659A13D64A755C39BC588B7D03BBE6129A39746304FEF371C760B1986A6FBF4DD588873571984B10FA6624239082E2273F772BC4FB28BC1E57DCCD35511FB1303BA03BE961D3788131E7A106A63BEB8021E5207D2B
-20220417025157 2 6 100 7679 5 CBC85C4D4EBCF255C5C59577D8AA5AD90A69B25B5296F0E56375785F984F7C899F7F9AF6B2C9194B15A6986941981AC7F389B6B4929F2E376CBF404FC982D91B1D5D8742069C5FF04CB06F655261C68FB38232C141DF7E03297340FA6687EF802A2A9B616B998F04BA24B6657E65250B52DF17531834455D250CB3A0E8CDD070B4F89C82F996416365AB47F1028D66207A6BAD8BA74D0E27BB3CE3F234C59C9CD050ED201ED5C816CAA3DF52A43C612C1079BF51304ED475DDDC73A289AFFA650FC7C4C568ACA26474BD48122BC45354B3AB4F070F6B91F64DACB2FB6F3A6B9FC1182A6818184DDBDF76226DEACA74B78CBAAB347134ED242212BE83D5D1BCD7CD70040518875F00402BBD118E941AF4F038674617A6BCA30F22F40CCFBF6138C854020BDFA5D1336B55081EB46965F647EB1EBD9D290056180489B1E7104FBD061B751D0472124624607D2E6867F7079C0531FECF05A79ADEF6F22DD6FFF9431C6A077BAE0384D447F4085CC805165DD8EB9C8C309B2EDD032DF0D4568FC21E428D6049D809567C707829579A066AA7F62C70EC559586A0749109764F5AE32CAC0C2127BB3654141BA6F87F1911671906B60D77BEE322D71515086B4E9BDA8E853DCF1906CFAEB099B0A1BB5EF0A06752A9C89EB506C773DC12FA8DE2DD8FE789624D80406619AE1BB342C7F01F424E4D5908A02731F051996721E2C0CB6703E131F4B5D1768E386783ED41C1C1318F9E19D995CFEEF998D5659D4A9FBEEDE6313B9E4C1665F1E44BF213E66EAE4435DFC2533EB131F235E0075F406028B650E758F38A582705423BB661A095D24E79B6A1D5C6A36989B28FD2ADA228961C1574187F18D419B46545D7FB147358A8409F5CA3ABBFD14EDDE9C0768E84E77F6E61307908F0DD8CD49B9C413EDE4FD13E4D1FB5CFB0075297258D828C20FD01A261F8D5672BFD190FAE191250F533B548B5469879E8B6BDA77D650ADB83AE9FAEC37FBE8A9F5F85CF47159EBC54A9129692A2B253C735E2F629D183A2ED4F2747BCF143D6D673F0F3703D0122BEDC5255F003311A81FA236D0E93D6CCC3375C4C35474427756E58A245A8F0AD68F1226BDA8ABB969A68B0758F1229038CB16711996B27923A0AE7D81384C24763C72B72B6A23A6EED923D0C70A3E47E47BD572A3398F3D651614A47C942A26F785F75A2DE7EE6FC927BE209729BF52943889E8C14708F592036BD3E3E4990659A13D64A755C39BC588B7D03BBE6129A39746304FEF371C760B1986A6FBF4DD588873571984B10FA6624239082E2273F772BC4FB28BC1E57DCCD35511FB1303BA03BE961D3788131E7A106A63BEB8021E88D137F
-20220417032310 2 6 100 7679 2 CBC85C4D4EBCF255C5C59577D8AA5AD90A69B25B5296F0E56375785F984F7C899F7F9AF6B2C9194B15A6986941981AC7F389B6B4929F2E376CBF404FC982D91B1D5D8742069C5FF04CB06F655261C68FB38232C141DF7E03297340FA6687EF802A2A9B616B998F04BA24B6657E65250B52DF17531834455D250CB3A0E8CDD070B4F89C82F996416365AB47F1028D66207A6BAD8BA74D0E27BB3CE3F234C59C9CD050ED201ED5C816CAA3DF52A43C612C1079BF51304ED475DDDC73A289AFFA650FC7C4C568ACA26474BD48122BC45354B3AB4F070F6B91F64DACB2FB6F3A6B9FC1182A6818184DDBDF76226DEACA74B78CBAAB347134ED242212BE83D5D1BCD7CD70040518875F00402BBD118E941AF4F038674617A6BCA30F22F40CCFBF6138C854020BDFA5D1336B55081EB46965F647EB1EBD9D290056180489B1E7104FBD061B751D0472124624607D2E6867F7079C0531FECF05A79ADEF6F22DD6FFF9431C6A077BAE0384D447F4085CC805165DD8EB9C8C309B2EDD032DF0D4568FC21E428D6049D809567C707829579A066AA7F62C70EC559586A0749109764F5AE32CAC0C2127BB3654141BA6F87F1911671906B60D77BEE322D71515086B4E9BDA8E853DCF1906CFAEB099B0A1BB5EF0A06752A9C89EB506C773DC12FA8DE2DD8FE789624D80406619AE1BB342C7F01F424E4D5908A02731F051996721E2C0CB6703E131F4B5D1768E386783ED41C1C1318F9E19D995CFEEF998D5659D4A9FBEEDE6313B9E4C1665F1E44BF213E66EAE4435DFC2533EB131F235E0075F406028B650E758F38A582705423BB661A095D24E79B6A1D5C6A36989B28FD2ADA228961C1574187F18D419B46545D7FB147358A8409F5CA3ABBFD14EDDE9C0768E84E77F6E61307908F0DD8CD49B9C413EDE4FD13E4D1FB5CFB0075297258D828C20FD01A261F8D5672BFD190FAE191250F533B548B5469879E8B6BDA77D650ADB83AE9FAEC37FBE8A9F5F85CF47159EBC54A9129692A2B253C735E2F629D183A2ED4F2747BCF143D6D673F0F3703D0122BEDC5255F003311A81FA236D0E93D6CCC3375C4C35474427756E58A245A8F0AD68F1226BDA8ABB969A68B0758F1229038CB16711996B27923A0AE7D81384C24763C72B72B6A23A6EED923D0C70A3E47E47BD572A3398F3D651614A47C942A26F785F75A2DE7EE6FC927BE209729BF52943889E8C14708F592036BD3E3E4990659A13D64A755C39BC588B7D03BBE6129A39746304FEF371C760B1986A6FBF4DD588873571984B10FA6624239082E2273F772BC4FB28BC1E57DCCD35511FB1303BA03BE961D3788131E7A106A63BEB8021EACBFA03
-20220417035624 2 6 100 7679 2 CBC85C4D4EBCF255C5C59577D8AA5AD90A69B25B5296F0E56375785F984F7C899F7F9AF6B2C9194B15A6986941981AC7F389B6B4929F2E376CBF404FC982D91B1D5D8742069C5FF04CB06F655261C68FB38232C141DF7E03297340FA6687EF802A2A9B616B998F04BA24B6657E65250B52DF17531834455D250CB3A0E8CDD070B4F89C82F996416365AB47F1028D66207A6BAD8BA74D0E27BB3CE3F234C59C9CD050ED201ED5C816CAA3DF52A43C612C1079BF51304ED475DDDC73A289AFFA650FC7C4C568ACA26474BD48122BC45354B3AB4F070F6B91F64DACB2FB6F3A6B9FC1182A6818184DDBDF76226DEACA74B78CBAAB347134ED242212BE83D5D1BCD7CD70040518875F00402BBD118E941AF4F038674617A6BCA30F22F40CCFBF6138C854020BDFA5D1336B55081EB46965F647EB1EBD9D290056180489B1E7104FBD061B751D0472124624607D2E6867F7079C0531FECF05A79ADEF6F22DD6FFF9431C6A077BAE0384D447F4085CC805165DD8EB9C8C309B2EDD032DF0D4568FC21E428D6049D809567C707829579A066AA7F62C70EC559586A0749109764F5AE32CAC0C2127BB3654141BA6F87F1911671906B60D77BEE322D71515086B4E9BDA8E853DCF1906CFAEB099B0A1BB5EF0A06752A9C89EB506C773DC12FA8DE2DD8FE789624D80406619AE1BB342C7F01F424E4D5908A02731F051996721E2C0CB6703E131F4B5D1768E386783ED41C1C1318F9E19D995CFEEF998D5659D4A9FBEEDE6313B9E4C1665F1E44BF213E66EAE4435DFC2533EB131F235E0075F406028B650E758F38A582705423BB661A095D24E79B6A1D5C6A36989B28FD2ADA228961C1574187F18D419B46545D7FB147358A8409F5CA3ABBFD14EDDE9C0768E84E77F6E61307908F0DD8CD49B9C413EDE4FD13E4D1FB5CFB0075297258D828C20FD01A261F8D5672BFD190FAE191250F533B548B5469879E8B6BDA77D650ADB83AE9FAEC37FBE8A9F5F85CF47159EBC54A9129692A2B253C735E2F629D183A2ED4F2747BCF143D6D673F0F3703D0122BEDC5255F003311A81FA236D0E93D6CCC3375C4C35474427756E58A245A8F0AD68F1226BDA8ABB969A68B0758F1229038CB16711996B27923A0AE7D81384C24763C72B72B6A23A6EED923D0C70A3E47E47BD572A3398F3D651614A47C942A26F785F75A2DE7EE6FC927BE209729BF52943889E8C14708F592036BD3E3E4990659A13D64A755C39BC588B7D03BBE6129A39746304FEF371C760B1986A6FBF4DD588873571984B10FA6624239082E2273F772BC4FB28BC1E57DCCD35511FB1303BA03BE961D3788131E7A106A63BEB8021ED21FED3
-20220417051440 2 6 100 7679 2 CBC85C4D4EBCF255C5C59577D8AA5AD90A69B25B5296F0E56375785F984F7C899F7F9AF6B2C9194B15A6986941981AC7F389B6B4929F2E376CBF404FC982D91B1D5D8742069C5FF04CB06F655261C68FB38232C141DF7E03297340FA6687EF802A2A9B616B998F04BA24B6657E65250B52DF17531834455D250CB3A0E8CDD070B4F89C82F996416365AB47F1028D66207A6BAD8BA74D0E27BB3CE3F234C59C9CD050ED201ED5C816CAA3DF52A43C612C1079BF51304ED475DDDC73A289AFFA650FC7C4C568ACA26474BD48122BC45354B3AB4F070F6B91F64DACB2FB6F3A6B9FC1182A6818184DDBDF76226DEACA74B78CBAAB347134ED242212BE83D5D1BCD7CD70040518875F00402BBD118E941AF4F038674617A6BCA30F22F40CCFBF6138C854020BDFA5D1336B55081EB46965F647EB1EBD9D290056180489B1E7104FBD061B751D0472124624607D2E6867F7079C0531FECF05A79ADEF6F22DD6FFF9431C6A077BAE0384D447F4085CC805165DD8EB9C8C309B2EDD032DF0D4568FC21E428D6049D809567C707829579A066AA7F62C70EC559586A0749109764F5AE32CAC0C2127BB3654141BA6F87F1911671906B60D77BEE322D71515086B4E9BDA8E853DCF1906CFAEB099B0A1BB5EF0A06752A9C89EB506C773DC12FA8DE2DD8FE789624D80406619AE1BB342C7F01F424E4D5908A02731F051996721E2C0CB6703E131F4B5D1768E386783ED41C1C1318F9E19D995CFEEF998D5659D4A9FBEEDE6313B9E4C1665F1E44BF213E66EAE4435DFC2533EB131F235E0075F406028B650E758F38A582705423BB661A095D24E79B6A1D5C6A36989B28FD2ADA228961C1574187F18D419B46545D7FB147358A8409F5CA3ABBFD14EDDE9C0768E84E77F6E61307908F0DD8CD49B9C413EDE4FD13E4D1FB5CFB0075297258D828C20FD01A261F8D5672BFD190FAE191250F533B548B5469879E8B6BDA77D650ADB83AE9FAEC37FBE8A9F5F85CF47159EBC54A9129692A2B253C735E2F629D183A2ED4F2747BCF143D6D673F0F3703D0122BEDC5255F003311A81FA236D0E93D6CCC3375C4C35474427756E58A245A8F0AD68F1226BDA8ABB969A68B0758F1229038CB16711996B27923A0AE7D81384C24763C72B72B6A23A6EED923D0C70A3E47E47BD572A3398F3D651614A47C942A26F785F75A2DE7EE6FC927BE209729BF52943889E8C14708F592036BD3E3E4990659A13D64A755C39BC588B7D03BBE6129A39746304FEF371C760B1986A6FBF4DD588873571984B10FA6624239082E2273F772BC4FB28BC1E57DCCD35511FB1303BA03BE961D3788131E7A106A63BEB8021F2C36493
-20220417052159 2 6 100 7679 2 CBC85C4D4EBCF255C5C59577D8AA5AD90A69B25B5296F0E56375785F984F7C899F7F9AF6B2C9194B15A6986941981AC7F389B6B4929F2E376CBF404FC982D91B1D5D8742069C5FF04CB06F655261C68FB38232C141DF7E03297340FA6687EF802A2A9B616B998F04BA24B6657E65250B52DF17531834455D250CB3A0E8CDD070B4F89C82F996416365AB47F1028D66207A6BAD8BA74D0E27BB3CE3F234C59C9CD050ED201ED5C816CAA3DF52A43C612C1079BF51304ED475DDDC73A289AFFA650FC7C4C568ACA26474BD48122BC45354B3AB4F070F6B91F64DACB2FB6F3A6B9FC1182A6818184DDBDF76226DEACA74B78CBAAB347134ED242212BE83D5D1BCD7CD70040518875F00402BBD118E941AF4F038674617A6BCA30F22F40CCFBF6138C854020BDFA5D1336B55081EB46965F647EB1EBD9D290056180489B1E7104FBD061B751D0472124624607D2E6867F7079C0531FECF05A79ADEF6F22DD6FFF9431C6A077BAE0384D447F4085CC805165DD8EB9C8C309B2EDD032DF0D4568FC21E428D6049D809567C707829579A066AA7F62C70EC559586A0749109764F5AE32CAC0C2127BB3654141BA6F87F1911671906B60D77BEE322D71515086B4E9BDA8E853DCF1906CFAEB099B0A1BB5EF0A06752A9C89EB506C773DC12FA8DE2DD8FE789624D80406619AE1BB342C7F01F424E4D5908A02731F051996721E2C0CB6703E131F4B5D1768E386783ED41C1C1318F9E19D995CFEEF998D5659D4A9FBEEDE6313B9E4C1665F1E44BF213E66EAE4435DFC2533EB131F235E0075F406028B650E758F38A582705423BB661A095D24E79B6A1D5C6A36989B28FD2ADA228961C1574187F18D419B46545D7FB147358A8409F5CA3ABBFD14EDDE9C0768E84E77F6E61307908F0DD8CD49B9C413EDE4FD13E4D1FB5CFB0075297258D828C20FD01A261F8D5672BFD190FAE191250F533B548B5469879E8B6BDA77D650ADB83AE9FAEC37FBE8A9F5F85CF47159EBC54A9129692A2B253C735E2F629D183A2ED4F2747BCF143D6D673F0F3703D0122BEDC5255F003311A81FA236D0E93D6CCC3375C4C35474427756E58A245A8F0AD68F1226BDA8ABB969A68B0758F1229038CB16711996B27923A0AE7D81384C24763C72B72B6A23A6EED923D0C70A3E47E47BD572A3398F3D651614A47C942A26F785F75A2DE7EE6FC927BE209729BF52943889E8C14708F592036BD3E3E4990659A13D64A755C39BC588B7D03BBE6129A39746304FEF371C760B1986A6FBF4DD588873571984B10FA6624239082E2273F772BC4FB28BC1E57DCCD35511FB1303BA03BE961D3788131E7A106A63BEB8021F342D84B
-20220417052424 2 6 100 7679 2 CBC85C4D4EBCF255C5C59577D8AA5AD90A69B25B5296F0E56375785F984F7C899F7F9AF6B2C9194B15A6986941981AC7F389B6B4929F2E376CBF404FC982D91B1D5D8742069C5FF04CB06F655261C68FB38232C141DF7E03297340FA6687EF802A2A9B616B998F04BA24B6657E65250B52DF17531834455D250CB3A0E8CDD070B4F89C82F996416365AB47F1028D66207A6BAD8BA74D0E27BB3CE3F234C59C9CD050ED201ED5C816CAA3DF52A43C612C1079BF51304ED475DDDC73A289AFFA650FC7C4C568ACA26474BD48122BC45354B3AB4F070F6B91F64DACB2FB6F3A6B9FC1182A6818184DDBDF76226DEACA74B78CBAAB347134ED242212BE83D5D1BCD7CD70040518875F00402BBD118E941AF4F038674617A6BCA30F22F40CCFBF6138C854020BDFA5D1336B55081EB46965F647EB1EBD9D290056180489B1E7104FBD061B751D0472124624607D2E6867F7079C0531FECF05A79ADEF6F22DD6FFF9431C6A077BAE0384D447F4085CC805165DD8EB9C8C309B2EDD032DF0D4568FC21E428D6049D809567C707829579A066AA7F62C70EC559586A0749109764F5AE32CAC0C2127BB3654141BA6F87F1911671906B60D77BEE322D71515086B4E9BDA8E853DCF1906CFAEB099B0A1BB5EF0A06752A9C89EB506C773DC12FA8DE2DD8FE789624D80406619AE1BB342C7F01F424E4D5908A02731F051996721E2C0CB6703E131F4B5D1768E386783ED41C1C1318F9E19D995CFEEF998D5659D4A9FBEEDE6313B9E4C1665F1E44BF213E66EAE4435DFC2533EB131F235E0075F406028B650E758F38A582705423BB661A095D24E79B6A1D5C6A36989B28FD2ADA228961C1574187F18D419B46545D7FB147358A8409F5CA3ABBFD14EDDE9C0768E84E77F6E61307908F0DD8CD49B9C413EDE4FD13E4D1FB5CFB0075297258D828C20FD01A261F8D5672BFD190FAE191250F533B548B5469879E8B6BDA77D650ADB83AE9FAEC37FBE8A9F5F85CF47159EBC54A9129692A2B253C735E2F629D183A2ED4F2747BCF143D6D673F0F3703D0122BEDC5255F003311A81FA236D0E93D6CCC3375C4C35474427756E58A245A8F0AD68F1226BDA8ABB969A68B0758F1229038CB16711996B27923A0AE7D81384C24763C72B72B6A23A6EED923D0C70A3E47E47BD572A3398F3D651614A47C942A26F785F75A2DE7EE6FC927BE209729BF52943889E8C14708F592036BD3E3E4990659A13D64A755C39BC588B7D03BBE6129A39746304FEF371C760B1986A6FBF4DD588873571984B10FA6624239082E2273F772BC4FB28BC1E57DCCD35511FB1303BA03BE961D3788131E7A106A63BEB8021F366931B
-20220417063546 2 6 100 8191 5 C52C5842553651D384813D75CCBD7B83BD255568A4C68FF4D52E1E7FF21591F027FCB743BE99262A53363C83B0A9C2D2E1C1DAEDCCF76A89344F891B001F588691CBC39D7582E69AB96E1E7A2AD2710D4870E1270A36FB44D7D358B0E7EB06AED2AE31FF68CE0198CF3A59EBAEAD81B1C823C4D88F490C2923C993D1B9E267E50DD8FAD09B83CA87A831B31B96DBF72089B9576FC5AFCA41AED93BBE1D5C627255CD02D6F98D097F8FE1F17B1B743B6E66DF5AC512AA430F04436E06793E7E73A914750833BC69830DEEE6FB57C32C3D7941529B915B1C4B6F37FCEC221A9DA83F050D47EA10DD4546309BB15CDC2A25C287B9A16CB0B2BB663A3D64BB7C26107034804C2C7569ECACBD609EF8A68E19768F86476DAEC2F12E14C325C5498DAD1BBFA5AB8F139E588C3B6BAE947D14283E944443B1DC19896D61730F5EA8A43D5AB9E48EC3861DC3D740FAFC39C408DB1E86F96681D630158C66FE42E187ABFB18304CDCF2718CE7B04F7FC55B78A19A0A43FDDB6CB9077FD680D50989DB1EB674BC03F20A1AEB6F9C546515F6C32C4276E5297A4A3AFBE8E6026C10FEA7F791F9049D0768668AFCCAA2D18878190353C870C6E9D4AC0DABF50BDA3B25EB99528566B9E0FAA44711FA57D1D15B75E00CCA8C1C0E76CDE80607556AAEBC173E0025FF7B05858610B85D868C92789BF1A9736B93E6B4AD7EB23A99F83E69B82BB1BFA26696C68D1066566AD45AA1BFF3C88ADDDF4181E9B9733B2D310B360D7865E4853C72AD5CA7614988B631926C237CBCEF8BFC9F861F9BD8FD92CACF2ABA9A72521CD7AF9465E00CA0F3CCECDBFAF75C148DEC07886536E1CCE9A68620F750657DD7EE912A1B9C7D35ED9AD81984544F7221DB21F2B47FA71BC1B76CFD51D3796F04323FEF98802EE57DE86BF7BC3C27CDAF15F00824CA24C928E0A2E9DE4E66097E382DE41B32769CFE9853EC1EB4B788364E9DE1CEAE0DF13545C9FF6DA8C0DC9289B4BE38A3600912AE233859D59BD1CE3A44C4EAFF6B1548C5D8CF7A63E449702ADBEE391C3BB1FB8A7217D74AFCEED66EC0E7C448B4B0D3FB011D666598F238968B66A3BE5D0D2F7E3D1D8D93736AE5FF605D8E17696F4FD6386FE2DB6BAEE6D142D184F5C088F9FC4DC05C1E7005092A6E7214BA7E5E85A7D9666A10B9AB7C14425FA7A1D82910E4B17E9B7DB09DA89CAE91D89277814A46A6F20E70AB75C45B0BD32227E0F7085C84B8A3864C25FB684DCF5B4512C46E04C7CFE7911C5E256CA017186A33447619E65C1839988874FCF00FCD2BB7FC4960B1107045898573AC4C7A7F0E3C17AE2DD5FBB92479B55517D435B4F582EEBE2CB6B926C424C3F1243F6FDDD33184E4132C08AE4DA1ABF5C5036FC8D3883855251B8589F7147889A37A300E7EAEDEDAD9262B626074F039DAE19BEEFB84320EDAA824C207
-20220417073924 2 6 100 8191 2 C52C5842553651D384813D75CCBD7B83BD255568A4C68FF4D52E1E7FF21591F027FCB743BE99262A53363C83B0A9C2D2E1C1DAEDCCF76A89344F891B001F588691CBC39D7582E69AB96E1E7A2AD2710D4870E1270A36FB44D7D358B0E7EB06AED2AE31FF68CE0198CF3A59EBAEAD81B1C823C4D88F490C2923C993D1B9E267E50DD8FAD09B83CA87A831B31B96DBF72089B9576FC5AFCA41AED93BBE1D5C627255CD02D6F98D097F8FE1F17B1B743B6E66DF5AC512AA430F04436E06793E7E73A914750833BC69830DEEE6FB57C32C3D7941529B915B1C4B6F37FCEC221A9DA83F050D47EA10DD4546309BB15CDC2A25C287B9A16CB0B2BB663A3D64BB7C26107034804C2C7569ECACBD609EF8A68E19768F86476DAEC2F12E14C325C5498DAD1BBFA5AB8F139E588C3B6BAE947D14283E944443B1DC19896D61730F5EA8A43D5AB9E48EC3861DC3D740FAFC39C408DB1E86F96681D630158C66FE42E187ABFB18304CDCF2718CE7B04F7FC55B78A19A0A43FDDB6CB9077FD680D50989DB1EB674BC03F20A1AEB6F9C546515F6C32C4276E5297A4A3AFBE8E6026C10FEA7F791F9049D0768668AFCCAA2D18878190353C870C6E9D4AC0DABF50BDA3B25EB99528566B9E0FAA44711FA57D1D15B75E00CCA8C1C0E76CDE80607556AAEBC173E0025FF7B05858610B85D868C92789BF1A9736B93E6B4AD7EB23A99F83E69B82BB1BFA26696C68D1066566AD45AA1BFF3C88ADDDF4181E9B9733B2D310B360D7865E4853C72AD5CA7614988B631926C237CBCEF8BFC9F861F9BD8FD92CACF2ABA9A72521CD7AF9465E00CA0F3CCECDBFAF75C148DEC07886536E1CCE9A68620F750657DD7EE912A1B9C7D35ED9AD81984544F7221DB21F2B47FA71BC1B76CFD51D3796F04323FEF98802EE57DE86BF7BC3C27CDAF15F00824CA24C928E0A2E9DE4E66097E382DE41B32769CFE9853EC1EB4B788364E9DE1CEAE0DF13545C9FF6DA8C0DC9289B4BE38A3600912AE233859D59BD1CE3A44C4EAFF6B1548C5D8CF7A63E449702ADBEE391C3BB1FB8A7217D74AFCEED66EC0E7C448B4B0D3FB011D666598F238968B66A3BE5D0D2F7E3D1D8D93736AE5FF605D8E17696F4FD6386FE2DB6BAEE6D142D184F5C088F9FC4DC05C1E7005092A6E7214BA7E5E85A7D9666A10B9AB7C14425FA7A1D82910E4B17E9B7DB09DA89CAE91D89277814A46A6F20E70AB75C45B0BD32227E0F7085C84B8A3864C25FB684DCF5B4512C46E04C7CFE7911C5E256CA017186A33447619E65C1839988874FCF00FCD2BB7FC4960B1107045898573AC4C7A7F0E3C17AE2DD5FBB92479B55517D435B4F582EEBE2CB6B926C424C3F1243F6FDDD33184E4132C08AE4DA1ABF5C5036FC8D3883855251B8589F7147889A37A300E7EAEDEDAD9262B626074F039DAE19BEEFB84320EDAAC98E38B
-20220417084530 2 6 100 8191 5 C52C5842553651D384813D75CCBD7B83BD255568A4C68FF4D52E1E7FF21591F027FCB743BE99262A53363C83B0A9C2D2E1C1DAEDCCF76A89344F891B001F588691CBC39D7582E69AB96E1E7A2AD2710D4870E1270A36FB44D7D358B0E7EB06AED2AE31FF68CE0198CF3A59EBAEAD81B1C823C4D88F490C2923C993D1B9E267E50DD8FAD09B83CA87A831B31B96DBF72089B9576FC5AFCA41AED93BBE1D5C627255CD02D6F98D097F8FE1F17B1B743B6E66DF5AC512AA430F04436E06793E7E73A914750833BC69830DEEE6FB57C32C3D7941529B915B1C4B6F37FCEC221A9DA83F050D47EA10DD4546309BB15CDC2A25C287B9A16CB0B2BB663A3D64BB7C26107034804C2C7569ECACBD609EF8A68E19768F86476DAEC2F12E14C325C5498DAD1BBFA5AB8F139E588C3B6BAE947D14283E944443B1DC19896D61730F5EA8A43D5AB9E48EC3861DC3D740FAFC39C408DB1E86F96681D630158C66FE42E187ABFB18304CDCF2718CE7B04F7FC55B78A19A0A43FDDB6CB9077FD680D50989DB1EB674BC03F20A1AEB6F9C546515F6C32C4276E5297A4A3AFBE8E6026C10FEA7F791F9049D0768668AFCCAA2D18878190353C870C6E9D4AC0DABF50BDA3B25EB99528566B9E0FAA44711FA57D1D15B75E00CCA8C1C0E76CDE80607556AAEBC173E0025FF7B05858610B85D868C92789BF1A9736B93E6B4AD7EB23A99F83E69B82BB1BFA26696C68D1066566AD45AA1BFF3C88ADDDF4181E9B9733B2D310B360D7865E4853C72AD5CA7614988B631926C237CBCEF8BFC9F861F9BD8FD92CACF2ABA9A72521CD7AF9465E00CA0F3CCECDBFAF75C148DEC07886536E1CCE9A68620F750657DD7EE912A1B9C7D35ED9AD81984544F7221DB21F2B47FA71BC1B76CFD51D3796F04323FEF98802EE57DE86BF7BC3C27CDAF15F00824CA24C928E0A2E9DE4E66097E382DE41B32769CFE9853EC1EB4B788364E9DE1CEAE0DF13545C9FF6DA8C0DC9289B4BE38A3600912AE233859D59BD1CE3A44C4EAFF6B1548C5D8CF7A63E449702ADBEE391C3BB1FB8A7217D74AFCEED66EC0E7C448B4B0D3FB011D666598F238968B66A3BE5D0D2F7E3D1D8D93736AE5FF605D8E17696F4FD6386FE2DB6BAEE6D142D184F5C088F9FC4DC05C1E7005092A6E7214BA7E5E85A7D9666A10B9AB7C14425FA7A1D82910E4B17E9B7DB09DA89CAE91D89277814A46A6F20E70AB75C45B0BD32227E0F7085C84B8A3864C25FB684DCF5B4512C46E04C7CFE7911C5E256CA017186A33447619E65C1839988874FCF00FCD2BB7FC4960B1107045898573AC4C7A7F0E3C17AE2DD5FBB92479B55517D435B4F582EEBE2CB6B926C424C3F1243F6FDDD33184E4132C08AE4DA1ABF5C5036FC8D3883855251B8589F7147889A37A300E7EAEDEDAD9262B626074F039DAE19BEEFB84320EDAB1415F77
-20220417090433 2 6 100 8191 2 C52C5842553651D384813D75CCBD7B83BD255568A4C68FF4D52E1E7FF21591F027FCB743BE99262A53363C83B0A9C2D2E1C1DAEDCCF76A89344F891B001F588691CBC39D7582E69AB96E1E7A2AD2710D4870E1270A36FB44D7D358B0E7EB06AED2AE31FF68CE0198CF3A59EBAEAD81B1C823C4D88F490C2923C993D1B9E267E50DD8FAD09B83CA87A831B31B96DBF72089B9576FC5AFCA41AED93BBE1D5C627255CD02D6F98D097F8FE1F17B1B743B6E66DF5AC512AA430F04436E06793E7E73A914750833BC69830DEEE6FB57C32C3D7941529B915B1C4B6F37FCEC221A9DA83F050D47EA10DD4546309BB15CDC2A25C287B9A16CB0B2BB663A3D64BB7C26107034804C2C7569ECACBD609EF8A68E19768F86476DAEC2F12E14C325C5498DAD1BBFA5AB8F139E588C3B6BAE947D14283E944443B1DC19896D61730F5EA8A43D5AB9E48EC3861DC3D740FAFC39C408DB1E86F96681D630158C66FE42E187ABFB18304CDCF2718CE7B04F7FC55B78A19A0A43FDDB6CB9077FD680D50989DB1EB674BC03F20A1AEB6F9C546515F6C32C4276E5297A4A3AFBE8E6026C10FEA7F791F9049D0768668AFCCAA2D18878190353C870C6E9D4AC0DABF50BDA3B25EB99528566B9E0FAA44711FA57D1D15B75E00CCA8C1C0E76CDE80607556AAEBC173E0025FF7B05858610B85D868C92789BF1A9736B93E6B4AD7EB23A99F83E69B82BB1BFA26696C68D1066566AD45AA1BFF3C88ADDDF4181E9B9733B2D310B360D7865E4853C72AD5CA7614988B631926C237CBCEF8BFC9F861F9BD8FD92CACF2ABA9A72521CD7AF9465E00CA0F3CCECDBFAF75C148DEC07886536E1CCE9A68620F750657DD7EE912A1B9C7D35ED9AD81984544F7221DB21F2B47FA71BC1B76CFD51D3796F04323FEF98802EE57DE86BF7BC3C27CDAF15F00824CA24C928E0A2E9DE4E66097E382DE41B32769CFE9853EC1EB4B788364E9DE1CEAE0DF13545C9FF6DA8C0DC9289B4BE38A3600912AE233859D59BD1CE3A44C4EAFF6B1548C5D8CF7A63E449702ADBEE391C3BB1FB8A7217D74AFCEED66EC0E7C448B4B0D3FB011D666598F238968B66A3BE5D0D2F7E3D1D8D93736AE5FF605D8E17696F4FD6386FE2DB6BAEE6D142D184F5C088F9FC4DC05C1E7005092A6E7214BA7E5E85A7D9666A10B9AB7C14425FA7A1D82910E4B17E9B7DB09DA89CAE91D89277814A46A6F20E70AB75C45B0BD32227E0F7085C84B8A3864C25FB684DCF5B4512C46E04C7CFE7911C5E256CA017186A33447619E65C1839988874FCF00FCD2BB7FC4960B1107045898573AC4C7A7F0E3C17AE2DD5FBB92479B55517D435B4F582EEBE2CB6B926C424C3F1243F6FDDD33184E4132C08AE4DA1ABF5C5036FC8D3883855251B8589F7147889A37A300E7EAEDEDAD9262B626074F039DAE19BEEFB84320EDAB29029DB
-20220417091538 2 6 100 8191 5 C52C5842553651D384813D75CCBD7B83BD255568A4C68FF4D52E1E7FF21591F027FCB743BE99262A53363C83B0A9C2D2E1C1DAEDCCF76A89344F891B001F588691CBC39D7582E69AB96E1E7A2AD2710D4870E1270A36FB44D7D358B0E7EB06AED2AE31FF68CE0198CF3A59EBAEAD81B1C823C4D88F490C2923C993D1B9E267E50DD8FAD09B83CA87A831B31B96DBF72089B9576FC5AFCA41AED93BBE1D5C627255CD02D6F98D097F8FE1F17B1B743B6E66DF5AC512AA430F04436E06793E7E73A914750833BC69830DEEE6FB57C32C3D7941529B915B1C4B6F37FCEC221A9DA83F050D47EA10DD4546309BB15CDC2A25C287B9A16CB0B2BB663A3D64BB7C26107034804C2C7569ECACBD609EF8A68E19768F86476DAEC2F12E14C325C5498DAD1BBFA5AB8F139E588C3B6BAE947D14283E944443B1DC19896D61730F5EA8A43D5AB9E48EC3861DC3D740FAFC39C408DB1E86F96681D630158C66FE42E187ABFB18304CDCF2718CE7B04F7FC55B78A19A0A43FDDB6CB9077FD680D50989DB1EB674BC03F20A1AEB6F9C546515F6C32C4276E5297A4A3AFBE8E6026C10FEA7F791F9049D0768668AFCCAA2D18878190353C870C6E9D4AC0DABF50BDA3B25EB99528566B9E0FAA44711FA57D1D15B75E00CCA8C1C0E76CDE80607556AAEBC173E0025FF7B05858610B85D868C92789BF1A9736B93E6B4AD7EB23A99F83E69B82BB1BFA26696C68D1066566AD45AA1BFF3C88ADDDF4181E9B9733B2D310B360D7865E4853C72AD5CA7614988B631926C237CBCEF8BFC9F861F9BD8FD92CACF2ABA9A72521CD7AF9465E00CA0F3CCECDBFAF75C148DEC07886536E1CCE9A68620F750657DD7EE912A1B9C7D35ED9AD81984544F7221DB21F2B47FA71BC1B76CFD51D3796F04323FEF98802EE57DE86BF7BC3C27CDAF15F00824CA24C928E0A2E9DE4E66097E382DE41B32769CFE9853EC1EB4B788364E9DE1CEAE0DF13545C9FF6DA8C0DC9289B4BE38A3600912AE233859D59BD1CE3A44C4EAFF6B1548C5D8CF7A63E449702ADBEE391C3BB1FB8A7217D74AFCEED66EC0E7C448B4B0D3FB011D666598F238968B66A3BE5D0D2F7E3D1D8D93736AE5FF605D8E17696F4FD6386FE2DB6BAEE6D142D184F5C088F9FC4DC05C1E7005092A6E7214BA7E5E85A7D9666A10B9AB7C14425FA7A1D82910E4B17E9B7DB09DA89CAE91D89277814A46A6F20E70AB75C45B0BD32227E0F7085C84B8A3864C25FB684DCF5B4512C46E04C7CFE7911C5E256CA017186A33447619E65C1839988874FCF00FCD2BB7FC4960B1107045898573AC4C7A7F0E3C17AE2DD5FBB92479B55517D435B4F582EEBE2CB6B926C424C3F1243F6FDDD33184E4132C08AE4DA1ABF5C5036FC8D3883855251B8589F7147889A37A300E7EAEDEDAD9262B626074F039DAE19BEEFB84320EDAB351952F
-20220417105457 2 6 100 8191 5 C52C5842553651D384813D75CCBD7B83BD255568A4C68FF4D52E1E7FF21591F027FCB743BE99262A53363C83B0A9C2D2E1C1DAEDCCF76A89344F891B001F588691CBC39D7582E69AB96E1E7A2AD2710D4870E1270A36FB44D7D358B0E7EB06AED2AE31FF68CE0198CF3A59EBAEAD81B1C823C4D88F490C2923C993D1B9E267E50DD8FAD09B83CA87A831B31B96DBF72089B9576FC5AFCA41AED93BBE1D5C627255CD02D6F98D097F8FE1F17B1B743B6E66DF5AC512AA430F04436E06793E7E73A914750833BC69830DEEE6FB57C32C3D7941529B915B1C4B6F37FCEC221A9DA83F050D47EA10DD4546309BB15CDC2A25C287B9A16CB0B2BB663A3D64BB7C26107034804C2C7569ECACBD609EF8A68E19768F86476DAEC2F12E14C325C5498DAD1BBFA5AB8F139E588C3B6BAE947D14283E944443B1DC19896D61730F5EA8A43D5AB9E48EC3861DC3D740FAFC39C408DB1E86F96681D630158C66FE42E187ABFB18304CDCF2718CE7B04F7FC55B78A19A0A43FDDB6CB9077FD680D50989DB1EB674BC03F20A1AEB6F9C546515F6C32C4276E5297A4A3AFBE8E6026C10FEA7F791F9049D0768668AFCCAA2D18878190353C870C6E9D4AC0DABF50BDA3B25EB99528566B9E0FAA44711FA57D1D15B75E00CCA8C1C0E76CDE80607556AAEBC173E0025FF7B05858610B85D868C92789BF1A9736B93E6B4AD7EB23A99F83E69B82BB1BFA26696C68D1066566AD45AA1BFF3C88ADDDF4181E9B9733B2D310B360D7865E4853C72AD5CA7614988B631926C237CBCEF8BFC9F861F9BD8FD92CACF2ABA9A72521CD7AF9465E00CA0F3CCECDBFAF75C148DEC07886536E1CCE9A68620F750657DD7EE912A1B9C7D35ED9AD81984544F7221DB21F2B47FA71BC1B76CFD51D3796F04323FEF98802EE57DE86BF7BC3C27CDAF15F00824CA24C928E0A2E9DE4E66097E382DE41B32769CFE9853EC1EB4B788364E9DE1CEAE0DF13545C9FF6DA8C0DC9289B4BE38A3600912AE233859D59BD1CE3A44C4EAFF6B1548C5D8CF7A63E449702ADBEE391C3BB1FB8A7217D74AFCEED66EC0E7C448B4B0D3FB011D666598F238968B66A3BE5D0D2F7E3D1D8D93736AE5FF605D8E17696F4FD6386FE2DB6BAEE6D142D184F5C088F9FC4DC05C1E7005092A6E7214BA7E5E85A7D9666A10B9AB7C14425FA7A1D82910E4B17E9B7DB09DA89CAE91D89277814A46A6F20E70AB75C45B0BD32227E0F7085C84B8A3864C25FB684DCF5B4512C46E04C7CFE7911C5E256CA017186A33447619E65C1839988874FCF00FCD2BB7FC4960B1107045898573AC4C7A7F0E3C17AE2DD5FBB92479B55517D435B4F582EEBE2CB6B926C424C3F1243F6FDDD33184E4132C08AE4DA1ABF5C5036FC8D3883855251B8589F7147889A37A300E7EAEDEDAD9262B626074F039DAE19BEEFB84320EDABA287EEF
-20220417121015 2 6 100 8191 2 C52C5842553651D384813D75CCBD7B83BD255568A4C68FF4D52E1E7FF21591F027FCB743BE99262A53363C83B0A9C2D2E1C1DAEDCCF76A89344F891B001F588691CBC39D7582E69AB96E1E7A2AD2710D4870E1270A36FB44D7D358B0E7EB06AED2AE31FF68CE0198CF3A59EBAEAD81B1C823C4D88F490C2923C993D1B9E267E50DD8FAD09B83CA87A831B31B96DBF72089B9576FC5AFCA41AED93BBE1D5C627255CD02D6F98D097F8FE1F17B1B743B6E66DF5AC512AA430F04436E06793E7E73A914750833BC69830DEEE6FB57C32C3D7941529B915B1C4B6F37FCEC221A9DA83F050D47EA10DD4546309BB15CDC2A25C287B9A16CB0B2BB663A3D64BB7C26107034804C2C7569ECACBD609EF8A68E19768F86476DAEC2F12E14C325C5498DAD1BBFA5AB8F139E588C3B6BAE947D14283E944443B1DC19896D61730F5EA8A43D5AB9E48EC3861DC3D740FAFC39C408DB1E86F96681D630158C66FE42E187ABFB18304CDCF2718CE7B04F7FC55B78A19A0A43FDDB6CB9077FD680D50989DB1EB674BC03F20A1AEB6F9C546515F6C32C4276E5297A4A3AFBE8E6026C10FEA7F791F9049D0768668AFCCAA2D18878190353C870C6E9D4AC0DABF50BDA3B25EB99528566B9E0FAA44711FA57D1D15B75E00CCA8C1C0E76CDE80607556AAEBC173E0025FF7B05858610B85D868C92789BF1A9736B93E6B4AD7EB23A99F83E69B82BB1BFA26696C68D1066566AD45AA1BFF3C88ADDDF4181E9B9733B2D310B360D7865E4853C72AD5CA7614988B631926C237CBCEF8BFC9F861F9BD8FD92CACF2ABA9A72521CD7AF9465E00CA0F3CCECDBFAF75C148DEC07886536E1CCE9A68620F750657DD7EE912A1B9C7D35ED9AD81984544F7221DB21F2B47FA71BC1B76CFD51D3796F04323FEF98802EE57DE86BF7BC3C27CDAF15F00824CA24C928E0A2E9DE4E66097E382DE41B32769CFE9853EC1EB4B788364E9DE1CEAE0DF13545C9FF6DA8C0DC9289B4BE38A3600912AE233859D59BD1CE3A44C4EAFF6B1548C5D8CF7A63E449702ADBEE391C3BB1FB8A7217D74AFCEED66EC0E7C448B4B0D3FB011D666598F238968B66A3BE5D0D2F7E3D1D8D93736AE5FF605D8E17696F4FD6386FE2DB6BAEE6D142D184F5C088F9FC4DC05C1E7005092A6E7214BA7E5E85A7D9666A10B9AB7C14425FA7A1D82910E4B17E9B7DB09DA89CAE91D89277814A46A6F20E70AB75C45B0BD32227E0F7085C84B8A3864C25FB684DCF5B4512C46E04C7CFE7911C5E256CA017186A33447619E65C1839988874FCF00FCD2BB7FC4960B1107045898573AC4C7A7F0E3C17AE2DD5FBB92479B55517D435B4F582EEBE2CB6B926C424C3F1243F6FDDD33184E4132C08AE4DA1ABF5C5036FC8D3883855251B8589F7147889A37A300E7EAEDEDAD9262B626074F039DAE19BEEFB84320EDABF594DF3
-20220417131800 2 6 100 8191 2 C52C5842553651D384813D75CCBD7B83BD255568A4C68FF4D52E1E7FF21591F027FCB743BE99262A53363C83B0A9C2D2E1C1DAEDCCF76A89344F891B001F588691CBC39D7582E69AB96E1E7A2AD2710D4870E1270A36FB44D7D358B0E7EB06AED2AE31FF68CE0198CF3A59EBAEAD81B1C823C4D88F490C2923C993D1B9E267E50DD8FAD09B83CA87A831B31B96DBF72089B9576FC5AFCA41AED93BBE1D5C627255CD02D6F98D097F8FE1F17B1B743B6E66DF5AC512AA430F04436E06793E7E73A914750833BC69830DEEE6FB57C32C3D7941529B915B1C4B6F37FCEC221A9DA83F050D47EA10DD4546309BB15CDC2A25C287B9A16CB0B2BB663A3D64BB7C26107034804C2C7569ECACBD609EF8A68E19768F86476DAEC2F12E14C325C5498DAD1BBFA5AB8F139E588C3B6BAE947D14283E944443B1DC19896D61730F5EA8A43D5AB9E48EC3861DC3D740FAFC39C408DB1E86F96681D630158C66FE42E187ABFB18304CDCF2718CE7B04F7FC55B78A19A0A43FDDB6CB9077FD680D50989DB1EB674BC03F20A1AEB6F9C546515F6C32C4276E5297A4A3AFBE8E6026C10FEA7F791F9049D0768668AFCCAA2D18878190353C870C6E9D4AC0DABF50BDA3B25EB99528566B9E0FAA44711FA57D1D15B75E00CCA8C1C0E76CDE80607556AAEBC173E0025FF7B05858610B85D868C92789BF1A9736B93E6B4AD7EB23A99F83E69B82BB1BFA26696C68D1066566AD45AA1BFF3C88ADDDF4181E9B9733B2D310B360D7865E4853C72AD5CA7614988B631926C237CBCEF8BFC9F861F9BD8FD92CACF2ABA9A72521CD7AF9465E00CA0F3CCECDBFAF75C148DEC07886536E1CCE9A68620F750657DD7EE912A1B9C7D35ED9AD81984544F7221DB21F2B47FA71BC1B76CFD51D3796F04323FEF98802EE57DE86BF7BC3C27CDAF15F00824CA24C928E0A2E9DE4E66097E382DE41B32769CFE9853EC1EB4B788364E9DE1CEAE0DF13545C9FF6DA8C0DC9289B4BE38A3600912AE233859D59BD1CE3A44C4EAFF6B1548C5D8CF7A63E449702ADBEE391C3BB1FB8A7217D74AFCEED66EC0E7C448B4B0D3FB011D666598F238968B66A3BE5D0D2F7E3D1D8D93736AE5FF605D8E17696F4FD6386FE2DB6BAEE6D142D184F5C088F9FC4DC05C1E7005092A6E7214BA7E5E85A7D9666A10B9AB7C14425FA7A1D82910E4B17E9B7DB09DA89CAE91D89277814A46A6F20E70AB75C45B0BD32227E0F7085C84B8A3864C25FB684DCF5B4512C46E04C7CFE7911C5E256CA017186A33447619E65C1839988874FCF00FCD2BB7FC4960B1107045898573AC4C7A7F0E3C17AE2DD5FBB92479B55517D435B4F582EEBE2CB6B926C424C3F1243F6FDDD33184E4132C08AE4DA1ABF5C5036FC8D3883855251B8589F7147889A37A300E7EAEDEDAD9262B626074F039DAE19BEEFB84320EDAC3FF4F83
-20220417160405 2 6 100 8191 2 C52C5842553651D384813D75CCBD7B83BD255568A4C68FF4D52E1E7FF21591F027FCB743BE99262A53363C83B0A9C2D2E1C1DAEDCCF76A89344F891B001F588691CBC39D7582E69AB96E1E7A2AD2710D4870E1270A36FB44D7D358B0E7EB06AED2AE31FF68CE0198CF3A59EBAEAD81B1C823C4D88F490C2923C993D1B9E267E50DD8FAD09B83CA87A831B31B96DBF72089B9576FC5AFCA41AED93BBE1D5C627255CD02D6F98D097F8FE1F17B1B743B6E66DF5AC512AA430F04436E06793E7E73A914750833BC69830DEEE6FB57C32C3D7941529B915B1C4B6F37FCEC221A9DA83F050D47EA10DD4546309BB15CDC2A25C287B9A16CB0B2BB663A3D64BB7C26107034804C2C7569ECACBD609EF8A68E19768F86476DAEC2F12E14C325C5498DAD1BBFA5AB8F139E588C3B6BAE947D14283E944443B1DC19896D61730F5EA8A43D5AB9E48EC3861DC3D740FAFC39C408DB1E86F96681D630158C66FE42E187ABFB18304CDCF2718CE7B04F7FC55B78A19A0A43FDDB6CB9077FD680D50989DB1EB674BC03F20A1AEB6F9C546515F6C32C4276E5297A4A3AFBE8E6026C10FEA7F791F9049D0768668AFCCAA2D18878190353C870C6E9D4AC0DABF50BDA3B25EB99528566B9E0FAA44711FA57D1D15B75E00CCA8C1C0E76CDE80607556AAEBC173E0025FF7B05858610B85D868C92789BF1A9736B93E6B4AD7EB23A99F83E69B82BB1BFA26696C68D1066566AD45AA1BFF3C88ADDDF4181E9B9733B2D310B360D7865E4853C72AD5CA7614988B631926C237CBCEF8BFC9F861F9BD8FD92CACF2ABA9A72521CD7AF9465E00CA0F3CCECDBFAF75C148DEC07886536E1CCE9A68620F750657DD7EE912A1B9C7D35ED9AD81984544F7221DB21F2B47FA71BC1B76CFD51D3796F04323FEF98802EE57DE86BF7BC3C27CDAF15F00824CA24C928E0A2E9DE4E66097E382DE41B32769CFE9853EC1EB4B788364E9DE1CEAE0DF13545C9FF6DA8C0DC9289B4BE38A3600912AE233859D59BD1CE3A44C4EAFF6B1548C5D8CF7A63E449702ADBEE391C3BB1FB8A7217D74AFCEED66EC0E7C448B4B0D3FB011D666598F238968B66A3BE5D0D2F7E3D1D8D93736AE5FF605D8E17696F4FD6386FE2DB6BAEE6D142D184F5C088F9FC4DC05C1E7005092A6E7214BA7E5E85A7D9666A10B9AB7C14425FA7A1D82910E4B17E9B7DB09DA89CAE91D89277814A46A6F20E70AB75C45B0BD32227E0F7085C84B8A3864C25FB684DCF5B4512C46E04C7CFE7911C5E256CA017186A33447619E65C1839988874FCF00FCD2BB7FC4960B1107045898573AC4C7A7F0E3C17AE2DD5FBB92479B55517D435B4F582EEBE2CB6B926C424C3F1243F6FDDD33184E4132C08AE4DA1ABF5C5036FC8D3883855251B8589F7147889A37A300E7EAEDEDAD9262B626074F039DAE19BEEFB84320EDACF38B053
-20220417171411 2 6 100 8191 5 C52C5842553651D384813D75CCBD7B83BD255568A4C68FF4D52E1E7FF21591F027FCB743BE99262A53363C83B0A9C2D2E1C1DAEDCCF76A89344F891B001F588691CBC39D7582E69AB96E1E7A2AD2710D4870E1270A36FB44D7D358B0E7EB06AED2AE31FF68CE0198CF3A59EBAEAD81B1C823C4D88F490C2923C993D1B9E267E50DD8FAD09B83CA87A831B31B96DBF72089B9576FC5AFCA41AED93BBE1D5C627255CD02D6F98D097F8FE1F17B1B743B6E66DF5AC512AA430F04436E06793E7E73A914750833BC69830DEEE6FB57C32C3D7941529B915B1C4B6F37FCEC221A9DA83F050D47EA10DD4546309BB15CDC2A25C287B9A16CB0B2BB663A3D64BB7C26107034804C2C7569ECACBD609EF8A68E19768F86476DAEC2F12E14C325C5498DAD1BBFA5AB8F139E588C3B6BAE947D14283E944443B1DC19896D61730F5EA8A43D5AB9E48EC3861DC3D740FAFC39C408DB1E86F96681D630158C66FE42E187ABFB18304CDCF2718CE7B04F7FC55B78A19A0A43FDDB6CB9077FD680D50989DB1EB674BC03F20A1AEB6F9C546515F6C32C4276E5297A4A3AFBE8E6026C10FEA7F791F9049D0768668AFCCAA2D18878190353C870C6E9D4AC0DABF50BDA3B25EB99528566B9E0FAA44711FA57D1D15B75E00CCA8C1C0E76CDE80607556AAEBC173E0025FF7B05858610B85D868C92789BF1A9736B93E6B4AD7EB23A99F83E69B82BB1BFA26696C68D1066566AD45AA1BFF3C88ADDDF4181E9B9733B2D310B360D7865E4853C72AD5CA7614988B631926C237CBCEF8BFC9F861F9BD8FD92CACF2ABA9A72521CD7AF9465E00CA0F3CCECDBFAF75C148DEC07886536E1CCE9A68620F750657DD7EE912A1B9C7D35ED9AD81984544F7221DB21F2B47FA71BC1B76CFD51D3796F04323FEF98802EE57DE86BF7BC3C27CDAF15F00824CA24C928E0A2E9DE4E66097E382DE41B32769CFE9853EC1EB4B788364E9DE1CEAE0DF13545C9FF6DA8C0DC9289B4BE38A3600912AE233859D59BD1CE3A44C4EAFF6B1548C5D8CF7A63E449702ADBEE391C3BB1FB8A7217D74AFCEED66EC0E7C448B4B0D3FB011D666598F238968B66A3BE5D0D2F7E3D1D8D93736AE5FF605D8E17696F4FD6386FE2DB6BAEE6D142D184F5C088F9FC4DC05C1E7005092A6E7214BA7E5E85A7D9666A10B9AB7C14425FA7A1D82910E4B17E9B7DB09DA89CAE91D89277814A46A6F20E70AB75C45B0BD32227E0F7085C84B8A3864C25FB684DCF5B4512C46E04C7CFE7911C5E256CA017186A33447619E65C1839988874FCF00FCD2BB7FC4960B1107045898573AC4C7A7F0E3C17AE2DD5FBB92479B55517D435B4F582EEBE2CB6B926C424C3F1243F6FDDD33184E4132C08AE4DA1ABF5C5036FC8D3883855251B8589F7147889A37A300E7EAEDEDAD9262B626074F039DAE19BEEFB84320EDAD3CDA357
-20220417172520 2 6 100 8191 2 C52C5842553651D384813D75CCBD7B83BD255568A4C68FF4D52E1E7FF21591F027FCB743BE99262A53363C83B0A9C2D2E1C1DAEDCCF76A89344F891B001F588691CBC39D7582E69AB96E1E7A2AD2710D4870E1270A36FB44D7D358B0E7EB06AED2AE31FF68CE0198CF3A59EBAEAD81B1C823C4D88F490C2923C993D1B9E267E50DD8FAD09B83CA87A831B31B96DBF72089B9576FC5AFCA41AED93BBE1D5C627255CD02D6F98D097F8FE1F17B1B743B6E66DF5AC512AA430F04436E06793E7E73A914750833BC69830DEEE6FB57C32C3D7941529B915B1C4B6F37FCEC221A9DA83F050D47EA10DD4546309BB15CDC2A25C287B9A16CB0B2BB663A3D64BB7C26107034804C2C7569ECACBD609EF8A68E19768F86476DAEC2F12E14C325C5498DAD1BBFA5AB8F139E588C3B6BAE947D14283E944443B1DC19896D61730F5EA8A43D5AB9E48EC3861DC3D740FAFC39C408DB1E86F96681D630158C66FE42E187ABFB18304CDCF2718CE7B04F7FC55B78A19A0A43FDDB6CB9077FD680D50989DB1EB674BC03F20A1AEB6F9C546515F6C32C4276E5297A4A3AFBE8E6026C10FEA7F791F9049D0768668AFCCAA2D18878190353C870C6E9D4AC0DABF50BDA3B25EB99528566B9E0FAA44711FA57D1D15B75E00CCA8C1C0E76CDE80607556AAEBC173E0025FF7B05858610B85D868C92789BF1A9736B93E6B4AD7EB23A99F83E69B82BB1BFA26696C68D1066566AD45AA1BFF3C88ADDDF4181E9B9733B2D310B360D7865E4853C72AD5CA7614988B631926C237CBCEF8BFC9F861F9BD8FD92CACF2ABA9A72521CD7AF9465E00CA0F3CCECDBFAF75C148DEC07886536E1CCE9A68620F750657DD7EE912A1B9C7D35ED9AD81984544F7221DB21F2B47FA71BC1B76CFD51D3796F04323FEF98802EE57DE86BF7BC3C27CDAF15F00824CA24C928E0A2E9DE4E66097E382DE41B32769CFE9853EC1EB4B788364E9DE1CEAE0DF13545C9FF6DA8C0DC9289B4BE38A3600912AE233859D59BD1CE3A44C4EAFF6B1548C5D8CF7A63E449702ADBEE391C3BB1FB8A7217D74AFCEED66EC0E7C448B4B0D3FB011D666598F238968B66A3BE5D0D2F7E3D1D8D93736AE5FF605D8E17696F4FD6386FE2DB6BAEE6D142D184F5C088F9FC4DC05C1E7005092A6E7214BA7E5E85A7D9666A10B9AB7C14425FA7A1D82910E4B17E9B7DB09DA89CAE91D89277814A46A6F20E70AB75C45B0BD32227E0F7085C84B8A3864C25FB684DCF5B4512C46E04C7CFE7911C5E256CA017186A33447619E65C1839988874FCF00FCD2BB7FC4960B1107045898573AC4C7A7F0E3C17AE2DD5FBB92479B55517D435B4F582EEBE2CB6B926C424C3F1243F6FDDD33184E4132C08AE4DA1ABF5C5036FC8D3883855251B8589F7147889A37A300E7EAEDEDAD9262B626074F039DAE19BEEFB84320EDAD4899F6B
-20220417200514 2 6 100 8191 5 C52C5842553651D384813D75CCBD7B83BD255568A4C68FF4D52E1E7FF21591F027FCB743BE99262A53363C83B0A9C2D2E1C1DAEDCCF76A89344F891B001F588691CBC39D7582E69AB96E1E7A2AD2710D4870E1270A36FB44D7D358B0E7EB06AED2AE31FF68CE0198CF3A59EBAEAD81B1C823C4D88F490C2923C993D1B9E267E50DD8FAD09B83CA87A831B31B96DBF72089B9576FC5AFCA41AED93BBE1D5C627255CD02D6F98D097F8FE1F17B1B743B6E66DF5AC512AA430F04436E06793E7E73A914750833BC69830DEEE6FB57C32C3D7941529B915B1C4B6F37FCEC221A9DA83F050D47EA10DD4546309BB15CDC2A25C287B9A16CB0B2BB663A3D64BB7C26107034804C2C7569ECACBD609EF8A68E19768F86476DAEC2F12E14C325C5498DAD1BBFA5AB8F139E588C3B6BAE947D14283E944443B1DC19896D61730F5EA8A43D5AB9E48EC3861DC3D740FAFC39C408DB1E86F96681D630158C66FE42E187ABFB18304CDCF2718CE7B04F7FC55B78A19A0A43FDDB6CB9077FD680D50989DB1EB674BC03F20A1AEB6F9C546515F6C32C4276E5297A4A3AFBE8E6026C10FEA7F791F9049D0768668AFCCAA2D18878190353C870C6E9D4AC0DABF50BDA3B25EB99528566B9E0FAA44711FA57D1D15B75E00CCA8C1C0E76CDE80607556AAEBC173E0025FF7B05858610B85D868C92789BF1A9736B93E6B4AD7EB23A99F83E69B82BB1BFA26696C68D1066566AD45AA1BFF3C88ADDDF4181E9B9733B2D310B360D7865E4853C72AD5CA7614988B631926C237CBCEF8BFC9F861F9BD8FD92CACF2ABA9A72521CD7AF9465E00CA0F3CCECDBFAF75C148DEC07886536E1CCE9A68620F750657DD7EE912A1B9C7D35ED9AD81984544F7221DB21F2B47FA71BC1B76CFD51D3796F04323FEF98802EE57DE86BF7BC3C27CDAF15F00824CA24C928E0A2E9DE4E66097E382DE41B32769CFE9853EC1EB4B788364E9DE1CEAE0DF13545C9FF6DA8C0DC9289B4BE38A3600912AE233859D59BD1CE3A44C4EAFF6B1548C5D8CF7A63E449702ADBEE391C3BB1FB8A7217D74AFCEED66EC0E7C448B4B0D3FB011D666598F238968B66A3BE5D0D2F7E3D1D8D93736AE5FF605D8E17696F4FD6386FE2DB6BAEE6D142D184F5C088F9FC4DC05C1E7005092A6E7214BA7E5E85A7D9666A10B9AB7C14425FA7A1D82910E4B17E9B7DB09DA89CAE91D89277814A46A6F20E70AB75C45B0BD32227E0F7085C84B8A3864C25FB684DCF5B4512C46E04C7CFE7911C5E256CA017186A33447619E65C1839988874FCF00FCD2BB7FC4960B1107045898573AC4C7A7F0E3C17AE2DD5FBB92479B55517D435B4F582EEBE2CB6B926C424C3F1243F6FDDD33184E4132C08AE4DA1ABF5C5036FC8D3883855251B8589F7147889A37A300E7EAEDEDAD9262B626074F039DAE19BEEFB84320EDADF12383F
-20220417203736 2 6 100 8191 2 C52C5842553651D384813D75CCBD7B83BD255568A4C68FF4D52E1E7FF21591F027FCB743BE99262A53363C83B0A9C2D2E1C1DAEDCCF76A89344F891B001F588691CBC39D7582E69AB96E1E7A2AD2710D4870E1270A36FB44D7D358B0E7EB06AED2AE31FF68CE0198CF3A59EBAEAD81B1C823C4D88F490C2923C993D1B9E267E50DD8FAD09B83CA87A831B31B96DBF72089B9576FC5AFCA41AED93BBE1D5C627255CD02D6F98D097F8FE1F17B1B743B6E66DF5AC512AA430F04436E06793E7E73A914750833BC69830DEEE6FB57C32C3D7941529B915B1C4B6F37FCEC221A9DA83F050D47EA10DD4546309BB15CDC2A25C287B9A16CB0B2BB663A3D64BB7C26107034804C2C7569ECACBD609EF8A68E19768F86476DAEC2F12E14C325C5498DAD1BBFA5AB8F139E588C3B6BAE947D14283E944443B1DC19896D61730F5EA8A43D5AB9E48EC3861DC3D740FAFC39C408DB1E86F96681D630158C66FE42E187ABFB18304CDCF2718CE7B04F7FC55B78A19A0A43FDDB6CB9077FD680D50989DB1EB674BC03F20A1AEB6F9C546515F6C32C4276E5297A4A3AFBE8E6026C10FEA7F791F9049D0768668AFCCAA2D18878190353C870C6E9D4AC0DABF50BDA3B25EB99528566B9E0FAA44711FA57D1D15B75E00CCA8C1C0E76CDE80607556AAEBC173E0025FF7B05858610B85D868C92789BF1A9736B93E6B4AD7EB23A99F83E69B82BB1BFA26696C68D1066566AD45AA1BFF3C88ADDDF4181E9B9733B2D310B360D7865E4853C72AD5CA7614988B631926C237CBCEF8BFC9F861F9BD8FD92CACF2ABA9A72521CD7AF9465E00CA0F3CCECDBFAF75C148DEC07886536E1CCE9A68620F750657DD7EE912A1B9C7D35ED9AD81984544F7221DB21F2B47FA71BC1B76CFD51D3796F04323FEF98802EE57DE86BF7BC3C27CDAF15F00824CA24C928E0A2E9DE4E66097E382DE41B32769CFE9853EC1EB4B788364E9DE1CEAE0DF13545C9FF6DA8C0DC9289B4BE38A3600912AE233859D59BD1CE3A44C4EAFF6B1548C5D8CF7A63E449702ADBEE391C3BB1FB8A7217D74AFCEED66EC0E7C448B4B0D3FB011D666598F238968B66A3BE5D0D2F7E3D1D8D93736AE5FF605D8E17696F4FD6386FE2DB6BAEE6D142D184F5C088F9FC4DC05C1E7005092A6E7214BA7E5E85A7D9666A10B9AB7C14425FA7A1D82910E4B17E9B7DB09DA89CAE91D89277814A46A6F20E70AB75C45B0BD32227E0F7085C84B8A3864C25FB684DCF5B4512C46E04C7CFE7911C5E256CA017186A33447619E65C1839988874FCF00FCD2BB7FC4960B1107045898573AC4C7A7F0E3C17AE2DD5FBB92479B55517D435B4F582EEBE2CB6B926C424C3F1243F6FDDD33184E4132C08AE4DA1ABF5C5036FC8D3883855251B8589F7147889A37A300E7EAEDEDAD9262B626074F039DAE19BEEFB84320EDAE12A45AB
-20220417215125 2 6 100 8191 2 C52C5842553651D384813D75CCBD7B83BD255568A4C68FF4D52E1E7FF21591F027FCB743BE99262A53363C83B0A9C2D2E1C1DAEDCCF76A89344F891B001F588691CBC39D7582E69AB96E1E7A2AD2710D4870E1270A36FB44D7D358B0E7EB06AED2AE31FF68CE0198CF3A59EBAEAD81B1C823C4D88F490C2923C993D1B9E267E50DD8FAD09B83CA87A831B31B96DBF72089B9576FC5AFCA41AED93BBE1D5C627255CD02D6F98D097F8FE1F17B1B743B6E66DF5AC512AA430F04436E06793E7E73A914750833BC69830DEEE6FB57C32C3D7941529B915B1C4B6F37FCEC221A9DA83F050D47EA10DD4546309BB15CDC2A25C287B9A16CB0B2BB663A3D64BB7C26107034804C2C7569ECACBD609EF8A68E19768F86476DAEC2F12E14C325C5498DAD1BBFA5AB8F139E588C3B6BAE947D14283E944443B1DC19896D61730F5EA8A43D5AB9E48EC3861DC3D740FAFC39C408DB1E86F96681D630158C66FE42E187ABFB18304CDCF2718CE7B04F7FC55B78A19A0A43FDDB6CB9077FD680D50989DB1EB674BC03F20A1AEB6F9C546515F6C32C4276E5297A4A3AFBE8E6026C10FEA7F791F9049D0768668AFCCAA2D18878190353C870C6E9D4AC0DABF50BDA3B25EB99528566B9E0FAA44711FA57D1D15B75E00CCA8C1C0E76CDE80607556AAEBC173E0025FF7B05858610B85D868C92789BF1A9736B93E6B4AD7EB23A99F83E69B82BB1BFA26696C68D1066566AD45AA1BFF3C88ADDDF4181E9B9733B2D310B360D7865E4853C72AD5CA7614988B631926C237CBCEF8BFC9F861F9BD8FD92CACF2ABA9A72521CD7AF9465E00CA0F3CCECDBFAF75C148DEC07886536E1CCE9A68620F750657DD7EE912A1B9C7D35ED9AD81984544F7221DB21F2B47FA71BC1B76CFD51D3796F04323FEF98802EE57DE86BF7BC3C27CDAF15F00824CA24C928E0A2E9DE4E66097E382DE41B32769CFE9853EC1EB4B788364E9DE1CEAE0DF13545C9FF6DA8C0DC9289B4BE38A3600912AE233859D59BD1CE3A44C4EAFF6B1548C5D8CF7A63E449702ADBEE391C3BB1FB8A7217D74AFCEED66EC0E7C448B4B0D3FB011D666598F238968B66A3BE5D0D2F7E3D1D8D93736AE5FF605D8E17696F4FD6386FE2DB6BAEE6D142D184F5C088F9FC4DC05C1E7005092A6E7214BA7E5E85A7D9666A10B9AB7C14425FA7A1D82910E4B17E9B7DB09DA89CAE91D89277814A46A6F20E70AB75C45B0BD32227E0F7085C84B8A3864C25FB684DCF5B4512C46E04C7CFE7911C5E256CA017186A33447619E65C1839988874FCF00FCD2BB7FC4960B1107045898573AC4C7A7F0E3C17AE2DD5FBB92479B55517D435B4F582EEBE2CB6B926C424C3F1243F6FDDD33184E4132C08AE4DA1ABF5C5036FC8D3883855251B8589F7147889A37A300E7EAEDEDAD9262B626074F039DAE19BEEFB84320EDAE5E926EB
-20220417224905 2 6 100 8191 5 C52C5842553651D384813D75CCBD7B83BD255568A4C68FF4D52E1E7FF21591F027FCB743BE99262A53363C83B0A9C2D2E1C1DAEDCCF76A89344F891B001F588691CBC39D7582E69AB96E1E7A2AD2710D4870E1270A36FB44D7D358B0E7EB06AED2AE31FF68CE0198CF3A59EBAEAD81B1C823C4D88F490C2923C993D1B9E267E50DD8FAD09B83CA87A831B31B96DBF72089B9576FC5AFCA41AED93BBE1D5C627255CD02D6F98D097F8FE1F17B1B743B6E66DF5AC512AA430F04436E06793E7E73A914750833BC69830DEEE6FB57C32C3D7941529B915B1C4B6F37FCEC221A9DA83F050D47EA10DD4546309BB15CDC2A25C287B9A16CB0B2BB663A3D64BB7C26107034804C2C7569ECACBD609EF8A68E19768F86476DAEC2F12E14C325C5498DAD1BBFA5AB8F139E588C3B6BAE947D14283E944443B1DC19896D61730F5EA8A43D5AB9E48EC3861DC3D740FAFC39C408DB1E86F96681D630158C66FE42E187ABFB18304CDCF2718CE7B04F7FC55B78A19A0A43FDDB6CB9077FD680D50989DB1EB674BC03F20A1AEB6F9C546515F6C32C4276E5297A4A3AFBE8E6026C10FEA7F791F9049D0768668AFCCAA2D18878190353C870C6E9D4AC0DABF50BDA3B25EB99528566B9E0FAA44711FA57D1D15B75E00CCA8C1C0E76CDE80607556AAEBC173E0025FF7B05858610B85D868C92789BF1A9736B93E6B4AD7EB23A99F83E69B82BB1BFA26696C68D1066566AD45AA1BFF3C88ADDDF4181E9B9733B2D310B360D7865E4853C72AD5CA7614988B631926C237CBCEF8BFC9F861F9BD8FD92CACF2ABA9A72521CD7AF9465E00CA0F3CCECDBFAF75C148DEC07886536E1CCE9A68620F750657DD7EE912A1B9C7D35ED9AD81984544F7221DB21F2B47FA71BC1B76CFD51D3796F04323FEF98802EE57DE86BF7BC3C27CDAF15F00824CA24C928E0A2E9DE4E66097E382DE41B32769CFE9853EC1EB4B788364E9DE1CEAE0DF13545C9FF6DA8C0DC9289B4BE38A3600912AE233859D59BD1CE3A44C4EAFF6B1548C5D8CF7A63E449702ADBEE391C3BB1FB8A7217D74AFCEED66EC0E7C448B4B0D3FB011D666598F238968B66A3BE5D0D2F7E3D1D8D93736AE5FF605D8E17696F4FD6386FE2DB6BAEE6D142D184F5C088F9FC4DC05C1E7005092A6E7214BA7E5E85A7D9666A10B9AB7C14425FA7A1D82910E4B17E9B7DB09DA89CAE91D89277814A46A6F20E70AB75C45B0BD32227E0F7085C84B8A3864C25FB684DCF5B4512C46E04C7CFE7911C5E256CA017186A33447619E65C1839988874FCF00FCD2BB7FC4960B1107045898573AC4C7A7F0E3C17AE2DD5FBB92479B55517D435B4F582EEBE2CB6B926C424C3F1243F6FDDD33184E4132C08AE4DA1ABF5C5036FC8D3883855251B8589F7147889A37A300E7EAEDEDAD9262B626074F039DAE19BEEFB84320EDAE9A3B337
-20220417233642 2 6 100 8191 2 C52C5842553651D384813D75CCBD7B83BD255568A4C68FF4D52E1E7FF21591F027FCB743BE99262A53363C83B0A9C2D2E1C1DAEDCCF76A89344F891B001F588691CBC39D7582E69AB96E1E7A2AD2710D4870E1270A36FB44D7D358B0E7EB06AED2AE31FF68CE0198CF3A59EBAEAD81B1C823C4D88F490C2923C993D1B9E267E50DD8FAD09B83CA87A831B31B96DBF72089B9576FC5AFCA41AED93BBE1D5C627255CD02D6F98D097F8FE1F17B1B743B6E66DF5AC512AA430F04436E06793E7E73A914750833BC69830DEEE6FB57C32C3D7941529B915B1C4B6F37FCEC221A9DA83F050D47EA10DD4546309BB15CDC2A25C287B9A16CB0B2BB663A3D64BB7C26107034804C2C7569ECACBD609EF8A68E19768F86476DAEC2F12E14C325C5498DAD1BBFA5AB8F139E588C3B6BAE947D14283E944443B1DC19896D61730F5EA8A43D5AB9E48EC3861DC3D740FAFC39C408DB1E86F96681D630158C66FE42E187ABFB18304CDCF2718CE7B04F7FC55B78A19A0A43FDDB6CB9077FD680D50989DB1EB674BC03F20A1AEB6F9C546515F6C32C4276E5297A4A3AFBE8E6026C10FEA7F791F9049D0768668AFCCAA2D18878190353C870C6E9D4AC0DABF50BDA3B25EB99528566B9E0FAA44711FA57D1D15B75E00CCA8C1C0E76CDE80607556AAEBC173E0025FF7B05858610B85D868C92789BF1A9736B93E6B4AD7EB23A99F83E69B82BB1BFA26696C68D1066566AD45AA1BFF3C88ADDDF4181E9B9733B2D310B360D7865E4853C72AD5CA7614988B631926C237CBCEF8BFC9F861F9BD8FD92CACF2ABA9A72521CD7AF9465E00CA0F3CCECDBFAF75C148DEC07886536E1CCE9A68620F750657DD7EE912A1B9C7D35ED9AD81984544F7221DB21F2B47FA71BC1B76CFD51D3796F04323FEF98802EE57DE86BF7BC3C27CDAF15F00824CA24C928E0A2E9DE4E66097E382DE41B32769CFE9853EC1EB4B788364E9DE1CEAE0DF13545C9FF6DA8C0DC9289B4BE38A3600912AE233859D59BD1CE3A44C4EAFF6B1548C5D8CF7A63E449702ADBEE391C3BB1FB8A7217D74AFCEED66EC0E7C448B4B0D3FB011D666598F238968B66A3BE5D0D2F7E3D1D8D93736AE5FF605D8E17696F4FD6386FE2DB6BAEE6D142D184F5C088F9FC4DC05C1E7005092A6E7214BA7E5E85A7D9666A10B9AB7C14425FA7A1D82910E4B17E9B7DB09DA89CAE91D89277814A46A6F20E70AB75C45B0BD32227E0F7085C84B8A3864C25FB684DCF5B4512C46E04C7CFE7911C5E256CA017186A33447619E65C1839988874FCF00FCD2BB7FC4960B1107045898573AC4C7A7F0E3C17AE2DD5FBB92479B55517D435B4F582EEBE2CB6B926C424C3F1243F6FDDD33184E4132C08AE4DA1ABF5C5036FC8D3883855251B8589F7147889A37A300E7EAEDEDAD9262B626074F039DAE19BEEFB84320EDAECA4D2E3
-20220418001736 2 6 100 8191 2 C52C5842553651D384813D75CCBD7B83BD255568A4C68FF4D52E1E7FF21591F027FCB743BE99262A53363C83B0A9C2D2E1C1DAEDCCF76A89344F891B001F588691CBC39D7582E69AB96E1E7A2AD2710D4870E1270A36FB44D7D358B0E7EB06AED2AE31FF68CE0198CF3A59EBAEAD81B1C823C4D88F490C2923C993D1B9E267E50DD8FAD09B83CA87A831B31B96DBF72089B9576FC5AFCA41AED93BBE1D5C627255CD02D6F98D097F8FE1F17B1B743B6E66DF5AC512AA430F04436E06793E7E73A914750833BC69830DEEE6FB57C32C3D7941529B915B1C4B6F37FCEC221A9DA83F050D47EA10DD4546309BB15CDC2A25C287B9A16CB0B2BB663A3D64BB7C26107034804C2C7569ECACBD609EF8A68E19768F86476DAEC2F12E14C325C5498DAD1BBFA5AB8F139E588C3B6BAE947D14283E944443B1DC19896D61730F5EA8A43D5AB9E48EC3861DC3D740FAFC39C408DB1E86F96681D630158C66FE42E187ABFB18304CDCF2718CE7B04F7FC55B78A19A0A43FDDB6CB9077FD680D50989DB1EB674BC03F20A1AEB6F9C546515F6C32C4276E5297A4A3AFBE8E6026C10FEA7F791F9049D0768668AFCCAA2D18878190353C870C6E9D4AC0DABF50BDA3B25EB99528566B9E0FAA44711FA57D1D15B75E00CCA8C1C0E76CDE80607556AAEBC173E0025FF7B05858610B85D868C92789BF1A9736B93E6B4AD7EB23A99F83E69B82BB1BFA26696C68D1066566AD45AA1BFF3C88ADDDF4181E9B9733B2D310B360D7865E4853C72AD5CA7614988B631926C237CBCEF8BFC9F861F9BD8FD92CACF2ABA9A72521CD7AF9465E00CA0F3CCECDBFAF75C148DEC07886536E1CCE9A68620F750657DD7EE912A1B9C7D35ED9AD81984544F7221DB21F2B47FA71BC1B76CFD51D3796F04323FEF98802EE57DE86BF7BC3C27CDAF15F00824CA24C928E0A2E9DE4E66097E382DE41B32769CFE9853EC1EB4B788364E9DE1CEAE0DF13545C9FF6DA8C0DC9289B4BE38A3600912AE233859D59BD1CE3A44C4EAFF6B1548C5D8CF7A63E449702ADBEE391C3BB1FB8A7217D74AFCEED66EC0E7C448B4B0D3FB011D666598F238968B66A3BE5D0D2F7E3D1D8D93736AE5FF605D8E17696F4FD6386FE2DB6BAEE6D142D184F5C088F9FC4DC05C1E7005092A6E7214BA7E5E85A7D9666A10B9AB7C14425FA7A1D82910E4B17E9B7DB09DA89CAE91D89277814A46A6F20E70AB75C45B0BD32227E0F7085C84B8A3864C25FB684DCF5B4512C46E04C7CFE7911C5E256CA017186A33447619E65C1839988874FCF00FCD2BB7FC4960B1107045898573AC4C7A7F0E3C17AE2DD5FBB92479B55517D435B4F582EEBE2CB6B926C424C3F1243F6FDDD33184E4132C08AE4DA1ABF5C5036FC8D3883855251B8589F7147889A37A300E7EAEDEDAD9262B626074F039DAE19BEEFB84320EDAEF4202CB
-20220418013943 2 6 100 8191 2 C52C5842553651D384813D75CCBD7B83BD255568A4C68FF4D52E1E7FF21591F027FCB743BE99262A53363C83B0A9C2D2E1C1DAEDCCF76A89344F891B001F588691CBC39D7582E69AB96E1E7A2AD2710D4870E1270A36FB44D7D358B0E7EB06AED2AE31FF68CE0198CF3A59EBAEAD81B1C823C4D88F490C2923C993D1B9E267E50DD8FAD09B83CA87A831B31B96DBF72089B9576FC5AFCA41AED93BBE1D5C627255CD02D6F98D097F8FE1F17B1B743B6E66DF5AC512AA430F04436E06793E7E73A914750833BC69830DEEE6FB57C32C3D7941529B915B1C4B6F37FCEC221A9DA83F050D47EA10DD4546309BB15CDC2A25C287B9A16CB0B2BB663A3D64BB7C26107034804C2C7569ECACBD609EF8A68E19768F86476DAEC2F12E14C325C5498DAD1BBFA5AB8F139E588C3B6BAE947D14283E944443B1DC19896D61730F5EA8A43D5AB9E48EC3861DC3D740FAFC39C408DB1E86F96681D630158C66FE42E187ABFB18304CDCF2718CE7B04F7FC55B78A19A0A43FDDB6CB9077FD680D50989DB1EB674BC03F20A1AEB6F9C546515F6C32C4276E5297A4A3AFBE8E6026C10FEA7F791F9049D0768668AFCCAA2D18878190353C870C6E9D4AC0DABF50BDA3B25EB99528566B9E0FAA44711FA57D1D15B75E00CCA8C1C0E76CDE80607556AAEBC173E0025FF7B05858610B85D868C92789BF1A9736B93E6B4AD7EB23A99F83E69B82BB1BFA26696C68D1066566AD45AA1BFF3C88ADDDF4181E9B9733B2D310B360D7865E4853C72AD5CA7614988B631926C237CBCEF8BFC9F861F9BD8FD92CACF2ABA9A72521CD7AF9465E00CA0F3CCECDBFAF75C148DEC07886536E1CCE9A68620F750657DD7EE912A1B9C7D35ED9AD81984544F7221DB21F2B47FA71BC1B76CFD51D3796F04323FEF98802EE57DE86BF7BC3C27CDAF15F00824CA24C928E0A2E9DE4E66097E382DE41B32769CFE9853EC1EB4B788364E9DE1CEAE0DF13545C9FF6DA8C0DC9289B4BE38A3600912AE233859D59BD1CE3A44C4EAFF6B1548C5D8CF7A63E449702ADBEE391C3BB1FB8A7217D74AFCEED66EC0E7C448B4B0D3FB011D666598F238968B66A3BE5D0D2F7E3D1D8D93736AE5FF605D8E17696F4FD6386FE2DB6BAEE6D142D184F5C088F9FC4DC05C1E7005092A6E7214BA7E5E85A7D9666A10B9AB7C14425FA7A1D82910E4B17E9B7DB09DA89CAE91D89277814A46A6F20E70AB75C45B0BD32227E0F7085C84B8A3864C25FB684DCF5B4512C46E04C7CFE7911C5E256CA017186A33447619E65C1839988874FCF00FCD2BB7FC4960B1107045898573AC4C7A7F0E3C17AE2DD5FBB92479B55517D435B4F582EEBE2CB6B926C424C3F1243F6FDDD33184E4132C08AE4DA1ABF5C5036FC8D3883855251B8589F7147889A37A300E7EAEDEDAD9262B626074F039DAE19BEEFB84320EDAF48042DB
-20220418030345 2 6 100 8191 2 C52C5842553651D384813D75CCBD7B83BD255568A4C68FF4D52E1E7FF21591F027FCB743BE99262A53363C83B0A9C2D2E1C1DAEDCCF76A89344F891B001F588691CBC39D7582E69AB96E1E7A2AD2710D4870E1270A36FB44D7D358B0E7EB06AED2AE31FF68CE0198CF3A59EBAEAD81B1C823C4D88F490C2923C993D1B9E267E50DD8FAD09B83CA87A831B31B96DBF72089B9576FC5AFCA41AED93BBE1D5C627255CD02D6F98D097F8FE1F17B1B743B6E66DF5AC512AA430F04436E06793E7E73A914750833BC69830DEEE6FB57C32C3D7941529B915B1C4B6F37FCEC221A9DA83F050D47EA10DD4546309BB15CDC2A25C287B9A16CB0B2BB663A3D64BB7C26107034804C2C7569ECACBD609EF8A68E19768F86476DAEC2F12E14C325C5498DAD1BBFA5AB8F139E588C3B6BAE947D14283E944443B1DC19896D61730F5EA8A43D5AB9E48EC3861DC3D740FAFC39C408DB1E86F96681D630158C66FE42E187ABFB18304CDCF2718CE7B04F7FC55B78A19A0A43FDDB6CB9077FD680D50989DB1EB674BC03F20A1AEB6F9C546515F6C32C4276E5297A4A3AFBE8E6026C10FEA7F791F9049D0768668AFCCAA2D18878190353C870C6E9D4AC0DABF50BDA3B25EB99528566B9E0FAA44711FA57D1D15B75E00CCA8C1C0E76CDE80607556AAEBC173E0025FF7B05858610B85D868C92789BF1A9736B93E6B4AD7EB23A99F83E69B82BB1BFA26696C68D1066566AD45AA1BFF3C88ADDDF4181E9B9733B2D310B360D7865E4853C72AD5CA7614988B631926C237CBCEF8BFC9F861F9BD8FD92CACF2ABA9A72521CD7AF9465E00CA0F3CCECDBFAF75C148DEC07886536E1CCE9A68620F750657DD7EE912A1B9C7D35ED9AD81984544F7221DB21F2B47FA71BC1B76CFD51D3796F04323FEF98802EE57DE86BF7BC3C27CDAF15F00824CA24C928E0A2E9DE4E66097E382DE41B32769CFE9853EC1EB4B788364E9DE1CEAE0DF13545C9FF6DA8C0DC9289B4BE38A3600912AE233859D59BD1CE3A44C4EAFF6B1548C5D8CF7A63E449702ADBEE391C3BB1FB8A7217D74AFCEED66EC0E7C448B4B0D3FB011D666598F238968B66A3BE5D0D2F7E3D1D8D93736AE5FF605D8E17696F4FD6386FE2DB6BAEE6D142D184F5C088F9FC4DC05C1E7005092A6E7214BA7E5E85A7D9666A10B9AB7C14425FA7A1D82910E4B17E9B7DB09DA89CAE91D89277814A46A6F20E70AB75C45B0BD32227E0F7085C84B8A3864C25FB684DCF5B4512C46E04C7CFE7911C5E256CA017186A33447619E65C1839988874FCF00FCD2BB7FC4960B1107045898573AC4C7A7F0E3C17AE2DD5FBB92479B55517D435B4F582EEBE2CB6B926C424C3F1243F6FDDD33184E4132C08AE4DA1ABF5C5036FC8D3883855251B8589F7147889A37A300E7EAEDEDAD9262B626074F039DAE19BEEFB84320EDAF9C843DB
-20220418035729 2 6 100 8191 2 C52C5842553651D384813D75CCBD7B83BD255568A4C68FF4D52E1E7FF21591F027FCB743BE99262A53363C83B0A9C2D2E1C1DAEDCCF76A89344F891B001F588691CBC39D7582E69AB96E1E7A2AD2710D4870E1270A36FB44D7D358B0E7EB06AED2AE31FF68CE0198CF3A59EBAEAD81B1C823C4D88F490C2923C993D1B9E267E50DD8FAD09B83CA87A831B31B96DBF72089B9576FC5AFCA41AED93BBE1D5C627255CD02D6F98D097F8FE1F17B1B743B6E66DF5AC512AA430F04436E06793E7E73A914750833BC69830DEEE6FB57C32C3D7941529B915B1C4B6F37FCEC221A9DA83F050D47EA10DD4546309BB15CDC2A25C287B9A16CB0B2BB663A3D64BB7C26107034804C2C7569ECACBD609EF8A68E19768F86476DAEC2F12E14C325C5498DAD1BBFA5AB8F139E588C3B6BAE947D14283E944443B1DC19896D61730F5EA8A43D5AB9E48EC3861DC3D740FAFC39C408DB1E86F96681D630158C66FE42E187ABFB18304CDCF2718CE7B04F7FC55B78A19A0A43FDDB6CB9077FD680D50989DB1EB674BC03F20A1AEB6F9C546515F6C32C4276E5297A4A3AFBE8E6026C10FEA7F791F9049D0768668AFCCAA2D18878190353C870C6E9D4AC0DABF50BDA3B25EB99528566B9E0FAA44711FA57D1D15B75E00CCA8C1C0E76CDE80607556AAEBC173E0025FF7B05858610B85D868C92789BF1A9736B93E6B4AD7EB23A99F83E69B82BB1BFA26696C68D1066566AD45AA1BFF3C88ADDDF4181E9B9733B2D310B360D7865E4853C72AD5CA7614988B631926C237CBCEF8BFC9F861F9BD8FD92CACF2ABA9A72521CD7AF9465E00CA0F3CCECDBFAF75C148DEC07886536E1CCE9A68620F750657DD7EE912A1B9C7D35ED9AD81984544F7221DB21F2B47FA71BC1B76CFD51D3796F04323FEF98802EE57DE86BF7BC3C27CDAF15F00824CA24C928E0A2E9DE4E66097E382DE41B32769CFE9853EC1EB4B788364E9DE1CEAE0DF13545C9FF6DA8C0DC9289B4BE38A3600912AE233859D59BD1CE3A44C4EAFF6B1548C5D8CF7A63E449702ADBEE391C3BB1FB8A7217D74AFCEED66EC0E7C448B4B0D3FB011D666598F238968B66A3BE5D0D2F7E3D1D8D93736AE5FF605D8E17696F4FD6386FE2DB6BAEE6D142D184F5C088F9FC4DC05C1E7005092A6E7214BA7E5E85A7D9666A10B9AB7C14425FA7A1D82910E4B17E9B7DB09DA89CAE91D89277814A46A6F20E70AB75C45B0BD32227E0F7085C84B8A3864C25FB684DCF5B4512C46E04C7CFE7911C5E256CA017186A33447619E65C1839988874FCF00FCD2BB7FC4960B1107045898573AC4C7A7F0E3C17AE2DD5FBB92479B55517D435B4F582EEBE2CB6B926C424C3F1243F6FDDD33184E4132C08AE4DA1ABF5C5036FC8D3883855251B8589F7147889A37A300E7EAEDEDAD9262B626074F039DAE19BEEFB84320EDAFD2E683B
-20220418071750 2 6 100 8191 2 C52C5842553651D384813D75CCBD7B83BD255568A4C68FF4D52E1E7FF21591F027FCB743BE99262A53363C83B0A9C2D2E1C1DAEDCCF76A89344F891B001F588691CBC39D7582E69AB96E1E7A2AD2710D4870E1270A36FB44D7D358B0E7EB06AED2AE31FF68CE0198CF3A59EBAEAD81B1C823C4D88F490C2923C993D1B9E267E50DD8FAD09B83CA87A831B31B96DBF72089B9576FC5AFCA41AED93BBE1D5C627255CD02D6F98D097F8FE1F17B1B743B6E66DF5AC512AA430F04436E06793E7E73A914750833BC69830DEEE6FB57C32C3D7941529B915B1C4B6F37FCEC221A9DA83F050D47EA10DD4546309BB15CDC2A25C287B9A16CB0B2BB663A3D64BB7C26107034804C2C7569ECACBD609EF8A68E19768F86476DAEC2F12E14C325C5498DAD1BBFA5AB8F139E588C3B6BAE947D14283E944443B1DC19896D61730F5EA8A43D5AB9E48EC3861DC3D740FAFC39C408DB1E86F96681D630158C66FE42E187ABFB18304CDCF2718CE7B04F7FC55B78A19A0A43FDDB6CB9077FD680D50989DB1EB674BC03F20A1AEB6F9C546515F6C32C4276E5297A4A3AFBE8E6026C10FEA7F791F9049D0768668AFCCAA2D18878190353C870C6E9D4AC0DABF50BDA3B25EB99528566B9E0FAA44711FA57D1D15B75E00CCA8C1C0E76CDE80607556AAEBC173E0025FF7B05858610B85D868C92789BF1A9736B93E6B4AD7EB23A99F83E69B82BB1BFA26696C68D1066566AD45AA1BFF3C88ADDDF4181E9B9733B2D310B360D7865E4853C72AD5CA7614988B631926C237CBCEF8BFC9F861F9BD8FD92CACF2ABA9A72521CD7AF9465E00CA0F3CCECDBFAF75C148DEC07886536E1CCE9A68620F750657DD7EE912A1B9C7D35ED9AD81984544F7221DB21F2B47FA71BC1B76CFD51D3796F04323FEF98802EE57DE86BF7BC3C27CDAF15F00824CA24C928E0A2E9DE4E66097E382DE41B32769CFE9853EC1EB4B788364E9DE1CEAE0DF13545C9FF6DA8C0DC9289B4BE38A3600912AE233859D59BD1CE3A44C4EAFF6B1548C5D8CF7A63E449702ADBEE391C3BB1FB8A7217D74AFCEED66EC0E7C448B4B0D3FB011D666598F238968B66A3BE5D0D2F7E3D1D8D93736AE5FF605D8E17696F4FD6386FE2DB6BAEE6D142D184F5C088F9FC4DC05C1E7005092A6E7214BA7E5E85A7D9666A10B9AB7C14425FA7A1D82910E4B17E9B7DB09DA89CAE91D89277814A46A6F20E70AB75C45B0BD32227E0F7085C84B8A3864C25FB684DCF5B4512C46E04C7CFE7911C5E256CA017186A33447619E65C1839988874FCF00FCD2BB7FC4960B1107045898573AC4C7A7F0E3C17AE2DD5FBB92479B55517D435B4F582EEBE2CB6B926C424C3F1243F6FDDD33184E4132C08AE4DA1ABF5C5036FC8D3883855251B8589F7147889A37A300E7EAEDEDAD9262B626074F039DAE19BEEFB84320EDB09CEE313
-20220418075023 2 6 100 8191 5 C52C5842553651D384813D75CCBD7B83BD255568A4C68FF4D52E1E7FF21591F027FCB743BE99262A53363C83B0A9C2D2E1C1DAEDCCF76A89344F891B001F588691CBC39D7582E69AB96E1E7A2AD2710D4870E1270A36FB44D7D358B0E7EB06AED2AE31FF68CE0198CF3A59EBAEAD81B1C823C4D88F490C2923C993D1B9E267E50DD8FAD09B83CA87A831B31B96DBF72089B9576FC5AFCA41AED93BBE1D5C627255CD02D6F98D097F8FE1F17B1B743B6E66DF5AC512AA430F04436E06793E7E73A914750833BC69830DEEE6FB57C32C3D7941529B915B1C4B6F37FCEC221A9DA83F050D47EA10DD4546309BB15CDC2A25C287B9A16CB0B2BB663A3D64BB7C26107034804C2C7569ECACBD609EF8A68E19768F86476DAEC2F12E14C325C5498DAD1BBFA5AB8F139E588C3B6BAE947D14283E944443B1DC19896D61730F5EA8A43D5AB9E48EC3861DC3D740FAFC39C408DB1E86F96681D630158C66FE42E187ABFB18304CDCF2718CE7B04F7FC55B78A19A0A43FDDB6CB9077FD680D50989DB1EB674BC03F20A1AEB6F9C546515F6C32C4276E5297A4A3AFBE8E6026C10FEA7F791F9049D0768668AFCCAA2D18878190353C870C6E9D4AC0DABF50BDA3B25EB99528566B9E0FAA44711FA57D1D15B75E00CCA8C1C0E76CDE80607556AAEBC173E0025FF7B05858610B85D868C92789BF1A9736B93E6B4AD7EB23A99F83E69B82BB1BFA26696C68D1066566AD45AA1BFF3C88ADDDF4181E9B9733B2D310B360D7865E4853C72AD5CA7614988B631926C237CBCEF8BFC9F861F9BD8FD92CACF2ABA9A72521CD7AF9465E00CA0F3CCECDBFAF75C148DEC07886536E1CCE9A68620F750657DD7EE912A1B9C7D35ED9AD81984544F7221DB21F2B47FA71BC1B76CFD51D3796F04323FEF98802EE57DE86BF7BC3C27CDAF15F00824CA24C928E0A2E9DE4E66097E382DE41B32769CFE9853EC1EB4B788364E9DE1CEAE0DF13545C9FF6DA8C0DC9289B4BE38A3600912AE233859D59BD1CE3A44C4EAFF6B1548C5D8CF7A63E449702ADBEE391C3BB1FB8A7217D74AFCEED66EC0E7C448B4B0D3FB011D666598F238968B66A3BE5D0D2F7E3D1D8D93736AE5FF605D8E17696F4FD6386FE2DB6BAEE6D142D184F5C088F9FC4DC05C1E7005092A6E7214BA7E5E85A7D9666A10B9AB7C14425FA7A1D82910E4B17E9B7DB09DA89CAE91D89277814A46A6F20E70AB75C45B0BD32227E0F7085C84B8A3864C25FB684DCF5B4512C46E04C7CFE7911C5E256CA017186A33447619E65C1839988874FCF00FCD2BB7FC4960B1107045898573AC4C7A7F0E3C17AE2DD5FBB92479B55517D435B4F582EEBE2CB6B926C424C3F1243F6FDDD33184E4132C08AE4DA1ABF5C5036FC8D3883855251B8589F7147889A37A300E7EAEDEDAD9262B626074F039DAE19BEEFB84320EDB0BCCA41F
-20220418080602 2 6 100 8191 2 C52C5842553651D384813D75CCBD7B83BD255568A4C68FF4D52E1E7FF21591F027FCB743BE99262A53363C83B0A9C2D2E1C1DAEDCCF76A89344F891B001F588691CBC39D7582E69AB96E1E7A2AD2710D4870E1270A36FB44D7D358B0E7EB06AED2AE31FF68CE0198CF3A59EBAEAD81B1C823C4D88F490C2923C993D1B9E267E50DD8FAD09B83CA87A831B31B96DBF72089B9576FC5AFCA41AED93BBE1D5C627255CD02D6F98D097F8FE1F17B1B743B6E66DF5AC512AA430F04436E06793E7E73A914750833BC69830DEEE6FB57C32C3D7941529B915B1C4B6F37FCEC221A9DA83F050D47EA10DD4546309BB15CDC2A25C287B9A16CB0B2BB663A3D64BB7C26107034804C2C7569ECACBD609EF8A68E19768F86476DAEC2F12E14C325C5498DAD1BBFA5AB8F139E588C3B6BAE947D14283E944443B1DC19896D61730F5EA8A43D5AB9E48EC3861DC3D740FAFC39C408DB1E86F96681D630158C66FE42E187ABFB18304CDCF2718CE7B04F7FC55B78A19A0A43FDDB6CB9077FD680D50989DB1EB674BC03F20A1AEB6F9C546515F6C32C4276E5297A4A3AFBE8E6026C10FEA7F791F9049D0768668AFCCAA2D18878190353C870C6E9D4AC0DABF50BDA3B25EB99528566B9E0FAA44711FA57D1D15B75E00CCA8C1C0E76CDE80607556AAEBC173E0025FF7B05858610B85D868C92789BF1A9736B93E6B4AD7EB23A99F83E69B82BB1BFA26696C68D1066566AD45AA1BFF3C88ADDDF4181E9B9733B2D310B360D7865E4853C72AD5CA7614988B631926C237CBCEF8BFC9F861F9BD8FD92CACF2ABA9A72521CD7AF9465E00CA0F3CCECDBFAF75C148DEC07886536E1CCE9A68620F750657DD7EE912A1B9C7D35ED9AD81984544F7221DB21F2B47FA71BC1B76CFD51D3796F04323FEF98802EE57DE86BF7BC3C27CDAF15F00824CA24C928E0A2E9DE4E66097E382DE41B32769CFE9853EC1EB4B788364E9DE1CEAE0DF13545C9FF6DA8C0DC9289B4BE38A3600912AE233859D59BD1CE3A44C4EAFF6B1548C5D8CF7A63E449702ADBEE391C3BB1FB8A7217D74AFCEED66EC0E7C448B4B0D3FB011D666598F238968B66A3BE5D0D2F7E3D1D8D93736AE5FF605D8E17696F4FD6386FE2DB6BAEE6D142D184F5C088F9FC4DC05C1E7005092A6E7214BA7E5E85A7D9666A10B9AB7C14425FA7A1D82910E4B17E9B7DB09DA89CAE91D89277814A46A6F20E70AB75C45B0BD32227E0F7085C84B8A3864C25FB684DCF5B4512C46E04C7CFE7911C5E256CA017186A33447619E65C1839988874FCF00FCD2BB7FC4960B1107045898573AC4C7A7F0E3C17AE2DD5FBB92479B55517D435B4F582EEBE2CB6B926C424C3F1243F6FDDD33184E4132C08AE4DA1ABF5C5036FC8D3883855251B8589F7147889A37A300E7EAEDEDAD9262B626074F039DAE19BEEFB84320EDB0CC11E8B
-20220418082746 2 6 100 8191 2 C52C5842553651D384813D75CCBD7B83BD255568A4C68FF4D52E1E7FF21591F027FCB743BE99262A53363C83B0A9C2D2E1C1DAEDCCF76A89344F891B001F588691CBC39D7582E69AB96E1E7A2AD2710D4870E1270A36FB44D7D358B0E7EB06AED2AE31FF68CE0198CF3A59EBAEAD81B1C823C4D88F490C2923C993D1B9E267E50DD8FAD09B83CA87A831B31B96DBF72089B9576FC5AFCA41AED93BBE1D5C627255CD02D6F98D097F8FE1F17B1B743B6E66DF5AC512AA430F04436E06793E7E73A914750833BC69830DEEE6FB57C32C3D7941529B915B1C4B6F37FCEC221A9DA83F050D47EA10DD4546309BB15CDC2A25C287B9A16CB0B2BB663A3D64BB7C26107034804C2C7569ECACBD609EF8A68E19768F86476DAEC2F12E14C325C5498DAD1BBFA5AB8F139E588C3B6BAE947D14283E944443B1DC19896D61730F5EA8A43D5AB9E48EC3861DC3D740FAFC39C408DB1E86F96681D630158C66FE42E187ABFB18304CDCF2718CE7B04F7FC55B78A19A0A43FDDB6CB9077FD680D50989DB1EB674BC03F20A1AEB6F9C546515F6C32C4276E5297A4A3AFBE8E6026C10FEA7F791F9049D0768668AFCCAA2D18878190353C870C6E9D4AC0DABF50BDA3B25EB99528566B9E0FAA44711FA57D1D15B75E00CCA8C1C0E76CDE80607556AAEBC173E0025FF7B05858610B85D868C92789BF1A9736B93E6B4AD7EB23A99F83E69B82BB1BFA26696C68D1066566AD45AA1BFF3C88ADDDF4181E9B9733B2D310B360D7865E4853C72AD5CA7614988B631926C237CBCEF8BFC9F861F9BD8FD92CACF2ABA9A72521CD7AF9465E00CA0F3CCECDBFAF75C148DEC07886536E1CCE9A68620F750657DD7EE912A1B9C7D35ED9AD81984544F7221DB21F2B47FA71BC1B76CFD51D3796F04323FEF98802EE57DE86BF7BC3C27CDAF15F00824CA24C928E0A2E9DE4E66097E382DE41B32769CFE9853EC1EB4B788364E9DE1CEAE0DF13545C9FF6DA8C0DC9289B4BE38A3600912AE233859D59BD1CE3A44C4EAFF6B1548C5D8CF7A63E449702ADBEE391C3BB1FB8A7217D74AFCEED66EC0E7C448B4B0D3FB011D666598F238968B66A3BE5D0D2F7E3D1D8D93736AE5FF605D8E17696F4FD6386FE2DB6BAEE6D142D184F5C088F9FC4DC05C1E7005092A6E7214BA7E5E85A7D9666A10B9AB7C14425FA7A1D82910E4B17E9B7DB09DA89CAE91D89277814A46A6F20E70AB75C45B0BD32227E0F7085C84B8A3864C25FB684DCF5B4512C46E04C7CFE7911C5E256CA017186A33447619E65C1839988874FCF00FCD2BB7FC4960B1107045898573AC4C7A7F0E3C17AE2DD5FBB92479B55517D435B4F582EEBE2CB6B926C424C3F1243F6FDDD33184E4132C08AE4DA1ABF5C5036FC8D3883855251B8589F7147889A37A300E7EAEDEDAD9262B626074F039DAE19BEEFB84320EDB0E073263
-20220418083338 2 6 100 8191 2 C52C5842553651D384813D75CCBD7B83BD255568A4C68FF4D52E1E7FF21591F027FCB743BE99262A53363C83B0A9C2D2E1C1DAEDCCF76A89344F891B001F588691CBC39D7582E69AB96E1E7A2AD2710D4870E1270A36FB44D7D358B0E7EB06AED2AE31FF68CE0198CF3A59EBAEAD81B1C823C4D88F490C2923C993D1B9E267E50DD8FAD09B83CA87A831B31B96DBF72089B9576FC5AFCA41AED93BBE1D5C627255CD02D6F98D097F8FE1F17B1B743B6E66DF5AC512AA430F04436E06793E7E73A914750833BC69830DEEE6FB57C32C3D7941529B915B1C4B6F37FCEC221A9DA83F050D47EA10DD4546309BB15CDC2A25C287B9A16CB0B2BB663A3D64BB7C26107034804C2C7569ECACBD609EF8A68E19768F86476DAEC2F12E14C325C5498DAD1BBFA5AB8F139E588C3B6BAE947D14283E944443B1DC19896D61730F5EA8A43D5AB9E48EC3861DC3D740FAFC39C408DB1E86F96681D630158C66FE42E187ABFB18304CDCF2718CE7B04F7FC55B78A19A0A43FDDB6CB9077FD680D50989DB1EB674BC03F20A1AEB6F9C546515F6C32C4276E5297A4A3AFBE8E6026C10FEA7F791F9049D0768668AFCCAA2D18878190353C870C6E9D4AC0DABF50BDA3B25EB99528566B9E0FAA44711FA57D1D15B75E00CCA8C1C0E76CDE80607556AAEBC173E0025FF7B05858610B85D868C92789BF1A9736B93E6B4AD7EB23A99F83E69B82BB1BFA26696C68D1066566AD45AA1BFF3C88ADDDF4181E9B9733B2D310B360D7865E4853C72AD5CA7614988B631926C237CBCEF8BFC9F861F9BD8FD92CACF2ABA9A72521CD7AF9465E00CA0F3CCECDBFAF75C148DEC07886536E1CCE9A68620F750657DD7EE912A1B9C7D35ED9AD81984544F7221DB21F2B47FA71BC1B76CFD51D3796F04323FEF98802EE57DE86BF7BC3C27CDAF15F00824CA24C928E0A2E9DE4E66097E382DE41B32769CFE9853EC1EB4B788364E9DE1CEAE0DF13545C9FF6DA8C0DC9289B4BE38A3600912AE233859D59BD1CE3A44C4EAFF6B1548C5D8CF7A63E449702ADBEE391C3BB1FB8A7217D74AFCEED66EC0E7C448B4B0D3FB011D666598F238968B66A3BE5D0D2F7E3D1D8D93736AE5FF605D8E17696F4FD6386FE2DB6BAEE6D142D184F5C088F9FC4DC05C1E7005092A6E7214BA7E5E85A7D9666A10B9AB7C14425FA7A1D82910E4B17E9B7DB09DA89CAE91D89277814A46A6F20E70AB75C45B0BD32227E0F7085C84B8A3864C25FB684DCF5B4512C46E04C7CFE7911C5E256CA017186A33447619E65C1839988874FCF00FCD2BB7FC4960B1107045898573AC4C7A7F0E3C17AE2DD5FBB92479B55517D435B4F582EEBE2CB6B926C424C3F1243F6FDDD33184E4132C08AE4DA1ABF5C5036FC8D3883855251B8589F7147889A37A300E7EAEDEDAD9262B626074F039DAE19BEEFB84320EDB0E5A8D33
-20220418100322 2 6 100 8191 5 C52C5842553651D384813D75CCBD7B83BD255568A4C68FF4D52E1E7FF21591F027FCB743BE99262A53363C83B0A9C2D2E1C1DAEDCCF76A89344F891B001F588691CBC39D7582E69AB96E1E7A2AD2710D4870E1270A36FB44D7D358B0E7EB06AED2AE31FF68CE0198CF3A59EBAEAD81B1C823C4D88F490C2923C993D1B9E267E50DD8FAD09B83CA87A831B31B96DBF72089B9576FC5AFCA41AED93BBE1D5C627255CD02D6F98D097F8FE1F17B1B743B6E66DF5AC512AA430F04436E06793E7E73A914750833BC69830DEEE6FB57C32C3D7941529B915B1C4B6F37FCEC221A9DA83F050D47EA10DD4546309BB15CDC2A25C287B9A16CB0B2BB663A3D64BB7C26107034804C2C7569ECACBD609EF8A68E19768F86476DAEC2F12E14C325C5498DAD1BBFA5AB8F139E588C3B6BAE947D14283E944443B1DC19896D61730F5EA8A43D5AB9E48EC3861DC3D740FAFC39C408DB1E86F96681D630158C66FE42E187ABFB18304CDCF2718CE7B04F7FC55B78A19A0A43FDDB6CB9077FD680D50989DB1EB674BC03F20A1AEB6F9C546515F6C32C4276E5297A4A3AFBE8E6026C10FEA7F791F9049D0768668AFCCAA2D18878190353C870C6E9D4AC0DABF50BDA3B25EB99528566B9E0FAA44711FA57D1D15B75E00CCA8C1C0E76CDE80607556AAEBC173E0025FF7B05858610B85D868C92789BF1A9736B93E6B4AD7EB23A99F83E69B82BB1BFA26696C68D1066566AD45AA1BFF3C88ADDDF4181E9B9733B2D310B360D7865E4853C72AD5CA7614988B631926C237CBCEF8BFC9F861F9BD8FD92CACF2ABA9A72521CD7AF9465E00CA0F3CCECDBFAF75C148DEC07886536E1CCE9A68620F750657DD7EE912A1B9C7D35ED9AD81984544F7221DB21F2B47FA71BC1B76CFD51D3796F04323FEF98802EE57DE86BF7BC3C27CDAF15F00824CA24C928E0A2E9DE4E66097E382DE41B32769CFE9853EC1EB4B788364E9DE1CEAE0DF13545C9FF6DA8C0DC9289B4BE38A3600912AE233859D59BD1CE3A44C4EAFF6B1548C5D8CF7A63E449702ADBEE391C3BB1FB8A7217D74AFCEED66EC0E7C448B4B0D3FB011D666598F238968B66A3BE5D0D2F7E3D1D8D93736AE5FF605D8E17696F4FD6386FE2DB6BAEE6D142D184F5C088F9FC4DC05C1E7005092A6E7214BA7E5E85A7D9666A10B9AB7C14425FA7A1D82910E4B17E9B7DB09DA89CAE91D89277814A46A6F20E70AB75C45B0BD32227E0F7085C84B8A3864C25FB684DCF5B4512C46E04C7CFE7911C5E256CA017186A33447619E65C1839988874FCF00FCD2BB7FC4960B1107045898573AC4C7A7F0E3C17AE2DD5FBB92479B55517D435B4F582EEBE2CB6B926C424C3F1243F6FDDD33184E4132C08AE4DA1ABF5C5036FC8D3883855251B8589F7147889A37A300E7EAEDEDAD9262B626074F039DAE19BEEFB84320EDB13D22C2F
-20220418122110 2 6 100 8191 2 C52C5842553651D384813D75CCBD7B83BD255568A4C68FF4D52E1E7FF21591F027FCB743BE99262A53363C83B0A9C2D2E1C1DAEDCCF76A89344F891B001F588691CBC39D7582E69AB96E1E7A2AD2710D4870E1270A36FB44D7D358B0E7EB06AED2AE31FF68CE0198CF3A59EBAEAD81B1C823C4D88F490C2923C993D1B9E267E50DD8FAD09B83CA87A831B31B96DBF72089B9576FC5AFCA41AED93BBE1D5C627255CD02D6F98D097F8FE1F17B1B743B6E66DF5AC512AA430F04436E06793E7E73A914750833BC69830DEEE6FB57C32C3D7941529B915B1C4B6F37FCEC221A9DA83F050D47EA10DD4546309BB15CDC2A25C287B9A16CB0B2BB663A3D64BB7C26107034804C2C7569ECACBD609EF8A68E19768F86476DAEC2F12E14C325C5498DAD1BBFA5AB8F139E588C3B6BAE947D14283E944443B1DC19896D61730F5EA8A43D5AB9E48EC3861DC3D740FAFC39C408DB1E86F96681D630158C66FE42E187ABFB18304CDCF2718CE7B04F7FC55B78A19A0A43FDDB6CB9077FD680D50989DB1EB674BC03F20A1AEB6F9C546515F6C32C4276E5297A4A3AFBE8E6026C10FEA7F791F9049D0768668AFCCAA2D18878190353C870C6E9D4AC0DABF50BDA3B25EB99528566B9E0FAA44711FA57D1D15B75E00CCA8C1C0E76CDE80607556AAEBC173E0025FF7B05858610B85D868C92789BF1A9736B93E6B4AD7EB23A99F83E69B82BB1BFA26696C68D1066566AD45AA1BFF3C88ADDDF4181E9B9733B2D310B360D7865E4853C72AD5CA7614988B631926C237CBCEF8BFC9F861F9BD8FD92CACF2ABA9A72521CD7AF9465E00CA0F3CCECDBFAF75C148DEC07886536E1CCE9A68620F750657DD7EE912A1B9C7D35ED9AD81984544F7221DB21F2B47FA71BC1B76CFD51D3796F04323FEF98802EE57DE86BF7BC3C27CDAF15F00824CA24C928E0A2E9DE4E66097E382DE41B32769CFE9853EC1EB4B788364E9DE1CEAE0DF13545C9FF6DA8C0DC9289B4BE38A3600912AE233859D59BD1CE3A44C4EAFF6B1548C5D8CF7A63E449702ADBEE391C3BB1FB8A7217D74AFCEED66EC0E7C448B4B0D3FB011D666598F238968B66A3BE5D0D2F7E3D1D8D93736AE5FF605D8E17696F4FD6386FE2DB6BAEE6D142D184F5C088F9FC4DC05C1E7005092A6E7214BA7E5E85A7D9666A10B9AB7C14425FA7A1D82910E4B17E9B7DB09DA89CAE91D89277814A46A6F20E70AB75C45B0BD32227E0F7085C84B8A3864C25FB684DCF5B4512C46E04C7CFE7911C5E256CA017186A33447619E65C1839988874FCF00FCD2BB7FC4960B1107045898573AC4C7A7F0E3C17AE2DD5FBB92479B55517D435B4F582EEBE2CB6B926C424C3F1243F6FDDD33184E4132C08AE4DA1ABF5C5036FC8D3883855251B8589F7147889A37A300E7EAEDEDAD9262B626074F039DAE19BEEFB84320EDB1C284B33
-20220418125647 2 6 100 8191 2 C52C5842553651D384813D75CCBD7B83BD255568A4C68FF4D52E1E7FF21591F027FCB743BE99262A53363C83B0A9C2D2E1C1DAEDCCF76A89344F891B001F588691CBC39D7582E69AB96E1E7A2AD2710D4870E1270A36FB44D7D358B0E7EB06AED2AE31FF68CE0198CF3A59EBAEAD81B1C823C4D88F490C2923C993D1B9E267E50DD8FAD09B83CA87A831B31B96DBF72089B9576FC5AFCA41AED93BBE1D5C627255CD02D6F98D097F8FE1F17B1B743B6E66DF5AC512AA430F04436E06793E7E73A914750833BC69830DEEE6FB57C32C3D7941529B915B1C4B6F37FCEC221A9DA83F050D47EA10DD4546309BB15CDC2A25C287B9A16CB0B2BB663A3D64BB7C26107034804C2C7569ECACBD609EF8A68E19768F86476DAEC2F12E14C325C5498DAD1BBFA5AB8F139E588C3B6BAE947D14283E944443B1DC19896D61730F5EA8A43D5AB9E48EC3861DC3D740FAFC39C408DB1E86F96681D630158C66FE42E187ABFB18304CDCF2718CE7B04F7FC55B78A19A0A43FDDB6CB9077FD680D50989DB1EB674BC03F20A1AEB6F9C546515F6C32C4276E5297A4A3AFBE8E6026C10FEA7F791F9049D0768668AFCCAA2D18878190353C870C6E9D4AC0DABF50BDA3B25EB99528566B9E0FAA44711FA57D1D15B75E00CCA8C1C0E76CDE80607556AAEBC173E0025FF7B05858610B85D868C92789BF1A9736B93E6B4AD7EB23A99F83E69B82BB1BFA26696C68D1066566AD45AA1BFF3C88ADDDF4181E9B9733B2D310B360D7865E4853C72AD5CA7614988B631926C237CBCEF8BFC9F861F9BD8FD92CACF2ABA9A72521CD7AF9465E00CA0F3CCECDBFAF75C148DEC07886536E1CCE9A68620F750657DD7EE912A1B9C7D35ED9AD81984544F7221DB21F2B47FA71BC1B76CFD51D3796F04323FEF98802EE57DE86BF7BC3C27CDAF15F00824CA24C928E0A2E9DE4E66097E382DE41B32769CFE9853EC1EB4B788364E9DE1CEAE0DF13545C9FF6DA8C0DC9289B4BE38A3600912AE233859D59BD1CE3A44C4EAFF6B1548C5D8CF7A63E449702ADBEE391C3BB1FB8A7217D74AFCEED66EC0E7C448B4B0D3FB011D666598F238968B66A3BE5D0D2F7E3D1D8D93736AE5FF605D8E17696F4FD6386FE2DB6BAEE6D142D184F5C088F9FC4DC05C1E7005092A6E7214BA7E5E85A7D9666A10B9AB7C14425FA7A1D82910E4B17E9B7DB09DA89CAE91D89277814A46A6F20E70AB75C45B0BD32227E0F7085C84B8A3864C25FB684DCF5B4512C46E04C7CFE7911C5E256CA017186A33447619E65C1839988874FCF00FCD2BB7FC4960B1107045898573AC4C7A7F0E3C17AE2DD5FBB92479B55517D435B4F582EEBE2CB6B926C424C3F1243F6FDDD33184E4132C08AE4DA1ABF5C5036FC8D3883855251B8589F7147889A37A300E7EAEDEDAD9262B626074F039DAE19BEEFB84320EDB1E510FB3
-20220418130116 2 6 100 8191 5 C52C5842553651D384813D75CCBD7B83BD255568A4C68FF4D52E1E7FF21591F027FCB743BE99262A53363C83B0A9C2D2E1C1DAEDCCF76A89344F891B001F588691CBC39D7582E69AB96E1E7A2AD2710D4870E1270A36FB44D7D358B0E7EB06AED2AE31FF68CE0198CF3A59EBAEAD81B1C823C4D88F490C2923C993D1B9E267E50DD8FAD09B83CA87A831B31B96DBF72089B9576FC5AFCA41AED93BBE1D5C627255CD02D6F98D097F8FE1F17B1B743B6E66DF5AC512AA430F04436E06793E7E73A914750833BC69830DEEE6FB57C32C3D7941529B915B1C4B6F37FCEC221A9DA83F050D47EA10DD4546309BB15CDC2A25C287B9A16CB0B2BB663A3D64BB7C26107034804C2C7569ECACBD609EF8A68E19768F86476DAEC2F12E14C325C5498DAD1BBFA5AB8F139E588C3B6BAE947D14283E944443B1DC19896D61730F5EA8A43D5AB9E48EC3861DC3D740FAFC39C408DB1E86F96681D630158C66FE42E187ABFB18304CDCF2718CE7B04F7FC55B78A19A0A43FDDB6CB9077FD680D50989DB1EB674BC03F20A1AEB6F9C546515F6C32C4276E5297A4A3AFBE8E6026C10FEA7F791F9049D0768668AFCCAA2D18878190353C870C6E9D4AC0DABF50BDA3B25EB99528566B9E0FAA44711FA57D1D15B75E00CCA8C1C0E76CDE80607556AAEBC173E0025FF7B05858610B85D868C92789BF1A9736B93E6B4AD7EB23A99F83E69B82BB1BFA26696C68D1066566AD45AA1BFF3C88ADDDF4181E9B9733B2D310B360D7865E4853C72AD5CA7614988B631926C237CBCEF8BFC9F861F9BD8FD92CACF2ABA9A72521CD7AF9465E00CA0F3CCECDBFAF75C148DEC07886536E1CCE9A68620F750657DD7EE912A1B9C7D35ED9AD81984544F7221DB21F2B47FA71BC1B76CFD51D3796F04323FEF98802EE57DE86BF7BC3C27CDAF15F00824CA24C928E0A2E9DE4E66097E382DE41B32769CFE9853EC1EB4B788364E9DE1CEAE0DF13545C9FF6DA8C0DC9289B4BE38A3600912AE233859D59BD1CE3A44C4EAFF6B1548C5D8CF7A63E449702ADBEE391C3BB1FB8A7217D74AFCEED66EC0E7C448B4B0D3FB011D666598F238968B66A3BE5D0D2F7E3D1D8D93736AE5FF605D8E17696F4FD6386FE2DB6BAEE6D142D184F5C088F9FC4DC05C1E7005092A6E7214BA7E5E85A7D9666A10B9AB7C14425FA7A1D82910E4B17E9B7DB09DA89CAE91D89277814A46A6F20E70AB75C45B0BD32227E0F7085C84B8A3864C25FB684DCF5B4512C46E04C7CFE7911C5E256CA017186A33447619E65C1839988874FCF00FCD2BB7FC4960B1107045898573AC4C7A7F0E3C17AE2DD5FBB92479B55517D435B4F582EEBE2CB6B926C424C3F1243F6FDDD33184E4132C08AE4DA1ABF5C5036FC8D3883855251B8589F7147889A37A300E7EAEDEDAD9262B626074F039DAE19BEEFB84320EDB1E90B78F
-20220418132740 2 6 100 8191 2 C52C5842553651D384813D75CCBD7B83BD255568A4C68FF4D52E1E7FF21591F027FCB743BE99262A53363C83B0A9C2D2E1C1DAEDCCF76A89344F891B001F588691CBC39D7582E69AB96E1E7A2AD2710D4870E1270A36FB44D7D358B0E7EB06AED2AE31FF68CE0198CF3A59EBAEAD81B1C823C4D88F490C2923C993D1B9E267E50DD8FAD09B83CA87A831B31B96DBF72089B9576FC5AFCA41AED93BBE1D5C627255CD02D6F98D097F8FE1F17B1B743B6E66DF5AC512AA430F04436E06793E7E73A914750833BC69830DEEE6FB57C32C3D7941529B915B1C4B6F37FCEC221A9DA83F050D47EA10DD4546309BB15CDC2A25C287B9A16CB0B2BB663A3D64BB7C26107034804C2C7569ECACBD609EF8A68E19768F86476DAEC2F12E14C325C5498DAD1BBFA5AB8F139E588C3B6BAE947D14283E944443B1DC19896D61730F5EA8A43D5AB9E48EC3861DC3D740FAFC39C408DB1E86F96681D630158C66FE42E187ABFB18304CDCF2718CE7B04F7FC55B78A19A0A43FDDB6CB9077FD680D50989DB1EB674BC03F20A1AEB6F9C546515F6C32C4276E5297A4A3AFBE8E6026C10FEA7F791F9049D0768668AFCCAA2D18878190353C870C6E9D4AC0DABF50BDA3B25EB99528566B9E0FAA44711FA57D1D15B75E00CCA8C1C0E76CDE80607556AAEBC173E0025FF7B05858610B85D868C92789BF1A9736B93E6B4AD7EB23A99F83E69B82BB1BFA26696C68D1066566AD45AA1BFF3C88ADDDF4181E9B9733B2D310B360D7865E4853C72AD5CA7614988B631926C237CBCEF8BFC9F861F9BD8FD92CACF2ABA9A72521CD7AF9465E00CA0F3CCECDBFAF75C148DEC07886536E1CCE9A68620F750657DD7EE912A1B9C7D35ED9AD81984544F7221DB21F2B47FA71BC1B76CFD51D3796F04323FEF98802EE57DE86BF7BC3C27CDAF15F00824CA24C928E0A2E9DE4E66097E382DE41B32769CFE9853EC1EB4B788364E9DE1CEAE0DF13545C9FF6DA8C0DC9289B4BE38A3600912AE233859D59BD1CE3A44C4EAFF6B1548C5D8CF7A63E449702ADBEE391C3BB1FB8A7217D74AFCEED66EC0E7C448B4B0D3FB011D666598F238968B66A3BE5D0D2F7E3D1D8D93736AE5FF605D8E17696F4FD6386FE2DB6BAEE6D142D184F5C088F9FC4DC05C1E7005092A6E7214BA7E5E85A7D9666A10B9AB7C14425FA7A1D82910E4B17E9B7DB09DA89CAE91D89277814A46A6F20E70AB75C45B0BD32227E0F7085C84B8A3864C25FB684DCF5B4512C46E04C7CFE7911C5E256CA017186A33447619E65C1839988874FCF00FCD2BB7FC4960B1107045898573AC4C7A7F0E3C17AE2DD5FBB92479B55517D435B4F582EEBE2CB6B926C424C3F1243F6FDDD33184E4132C08AE4DA1ABF5C5036FC8D3883855251B8589F7147889A37A300E7EAEDEDAD9262B626074F039DAE19BEEFB84320EDB201DF103
-20220418144902 2 6 100 8191 2 CF0A168167DAB1FDFD5C0376DC6E2C93907F486EF5576F14B83FAD667FCC774D179D9A0CB69771C381E7A3AC0F7561E06C8BFD155A9B527EE6F015BDFF6DAE1556CEB985BAAA83E40720B4D91830DDA2BC4BE8C137AB7EB0107D3E04DB39A092C84AEF71E223A40F18B586FA813ED2EC4453A8C15B3531DC651AAFA6136D5BA894B22FA94E96D6034E9A569F4D3366B323D656B5C480D0FC443BA5597B42071CB28466F084FA31856AEAB54268E7DF559C47D0F53F7584273FD41C9C59C130E9E43B0E5664B1FFAE5D3608EBFCDCA6E257B0AED1E270938A03C7494B16E725389F8106CFA4746BD350EFD6688AF36BA679CF2437E25C0335A4C7E51AD3043938D7D49EAD349D50B153346687EC29B70982760D6280C1B92F58AEFC66BAB600A905A40B720A8E75CC1C1D96557F1988FF927ED6C2C614357242CB03E314B19766B1C7D70575A1607B25C6E90F2412DE7D3F140B3B6CD743FEE66DD2F32B35F34C1C4F1523B03F9E68E873FB7697D0D09D387B8E4BA6FF9EE302A8B6D4BEBA2659E8933B8A411BEE451870CA8F388C96C0D1A59F2BCB29CBD5FFDCA855A7A9720E7BCA71037B417D9D54EFED70FB695EB8E3461262884DADE4C7E2F9ED544D650CB9853F1AEE8C48FD285F8C806823065A238AD70A99C832C815970C33E8326ECC759378A603C77D20248DFAAD6AC718D5F04AF2635061C904159E1EB37873B383C7A244C81F58A22553B1DC1A74AFB44B44A5AEA3B096DEB8B6FEFA7778ACBE1B1EF0331B2667611340085C51D092DD6AC47814A4D68384007F87EA2EF20E005ED221855CCF2B67FF58CAA28E40CD9C44586CB054670C2B0EF0E6B73852B5B475409BDD6A6042345630EB1A675F51A13F7453936B72FDACC671D863DEFE781698B6AE6CE15FB6936A27A9D5EE7442380812B8EB4FB525A518239E138112E6BCA6FEA3FB27B30E28F6D3084D8B5E01F20C7D3FD7EEF3E3EB55F392717BCA9CA76900EBADB7AEA8A26F704C8417708D51374E98D61E0D649BFCC0957FB0636762453C8D1CE08B95FB90BB5EFF6A50210679E167C1E0B67AEDC6E7000C1C4AA5509F8F81D679855BD6CF8FE556FADACE0E45F1C1387DD1A14BBC8A3097DC11C7E40E5A31BCE2188D99008BC3163D04D03ABFB8AA3F17DCFADF8A26F4F275886B1C3DE598068054BB5D8D1B4CB5BCA9E6E822377AA7625490BD4735DDB2B4558D677C1DC2AF39CD9C67242D1C41FF3109FBA72C9C22E362310A905738BF8CEB12697EA0A0885BE11AE0A44DD1FE5F6F863AA8740BAD7300FE1FE72062D3C1669CA796B541637141925DE49515D497F669A695C2735489B58A6E48FF5D6E884D262E5EE95F1EDF49DF55485891DE9B7F5B1E73AD0953C021E4E58D3B7001B702EB6A030E81DC6DB9265290FC224695CAB521CCA0449069CBF358949B03FD67858150C3
-20220418152824 2 6 100 8191 2 CF0A168167DAB1FDFD5C0376DC6E2C93907F486EF5576F14B83FAD667FCC774D179D9A0CB69771C381E7A3AC0F7561E06C8BFD155A9B527EE6F015BDFF6DAE1556CEB985BAAA83E40720B4D91830DDA2BC4BE8C137AB7EB0107D3E04DB39A092C84AEF71E223A40F18B586FA813ED2EC4453A8C15B3531DC651AAFA6136D5BA894B22FA94E96D6034E9A569F4D3366B323D656B5C480D0FC443BA5597B42071CB28466F084FA31856AEAB54268E7DF559C47D0F53F7584273FD41C9C59C130E9E43B0E5664B1FFAE5D3608EBFCDCA6E257B0AED1E270938A03C7494B16E725389F8106CFA4746BD350EFD6688AF36BA679CF2437E25C0335A4C7E51AD3043938D7D49EAD349D50B153346687EC29B70982760D6280C1B92F58AEFC66BAB600A905A40B720A8E75CC1C1D96557F1988FF927ED6C2C614357242CB03E314B19766B1C7D70575A1607B25C6E90F2412DE7D3F140B3B6CD743FEE66DD2F32B35F34C1C4F1523B03F9E68E873FB7697D0D09D387B8E4BA6FF9EE302A8B6D4BEBA2659E8933B8A411BEE451870CA8F388C96C0D1A59F2BCB29CBD5FFDCA855A7A9720E7BCA71037B417D9D54EFED70FB695EB8E3461262884DADE4C7E2F9ED544D650CB9853F1AEE8C48FD285F8C806823065A238AD70A99C832C815970C33E8326ECC759378A603C77D20248DFAAD6AC718D5F04AF2635061C904159E1EB37873B383C7A244C81F58A22553B1DC1A74AFB44B44A5AEA3B096DEB8B6FEFA7778ACBE1B1EF0331B2667611340085C51D092DD6AC47814A4D68384007F87EA2EF20E005ED221855CCF2B67FF58CAA28E40CD9C44586CB054670C2B0EF0E6B73852B5B475409BDD6A6042345630EB1A675F51A13F7453936B72FDACC671D863DEFE781698B6AE6CE15FB6936A27A9D5EE7442380812B8EB4FB525A518239E138112E6BCA6FEA3FB27B30E28F6D3084D8B5E01F20C7D3FD7EEF3E3EB55F392717BCA9CA76900EBADB7AEA8A26F704C8417708D51374E98D61E0D649BFCC0957FB0636762453C8D1CE08B95FB90BB5EFF6A50210679E167C1E0B67AEDC6E7000C1C4AA5509F8F81D679855BD6CF8FE556FADACE0E45F1C1387DD1A14BBC8A3097DC11C7E40E5A31BCE2188D99008BC3163D04D03ABFB8AA3F17DCFADF8A26F4F275886B1C3DE598068054BB5D8D1B4CB5BCA9E6E822377AA7625490BD4735DDB2B4558D677C1DC2AF39CD9C67242D1C41FF3109FBA72C9C22E362310A905738BF8CEB12697EA0A0885BE11AE0A44DD1FE5F6F863AA8740BAD7300FE1FE72062D3C1669CA796B541637141925DE49515D497F669A695C2735489B58A6E48FF5D6E884D262E5EE95F1EDF49DF55485891DE9B7F5B1E73AD0953C021E4E58D3B7001B702EB6A030E81DC6DB9265290FC224695CAB521CCA0449069CBF358949B03FD67884BD073
-20220418171630 2 6 100 8191 2 CF0A168167DAB1FDFD5C0376DC6E2C93907F486EF5576F14B83FAD667FCC774D179D9A0CB69771C381E7A3AC0F7561E06C8BFD155A9B527EE6F015BDFF6DAE1556CEB985BAAA83E40720B4D91830DDA2BC4BE8C137AB7EB0107D3E04DB39A092C84AEF71E223A40F18B586FA813ED2EC4453A8C15B3531DC651AAFA6136D5BA894B22FA94E96D6034E9A569F4D3366B323D656B5C480D0FC443BA5597B42071CB28466F084FA31856AEAB54268E7DF559C47D0F53F7584273FD41C9C59C130E9E43B0E5664B1FFAE5D3608EBFCDCA6E257B0AED1E270938A03C7494B16E725389F8106CFA4746BD350EFD6688AF36BA679CF2437E25C0335A4C7E51AD3043938D7D49EAD349D50B153346687EC29B70982760D6280C1B92F58AEFC66BAB600A905A40B720A8E75CC1C1D96557F1988FF927ED6C2C614357242CB03E314B19766B1C7D70575A1607B25C6E90F2412DE7D3F140B3B6CD743FEE66DD2F32B35F34C1C4F1523B03F9E68E873FB7697D0D09D387B8E4BA6FF9EE302A8B6D4BEBA2659E8933B8A411BEE451870CA8F388C96C0D1A59F2BCB29CBD5FFDCA855A7A9720E7BCA71037B417D9D54EFED70FB695EB8E3461262884DADE4C7E2F9ED544D650CB9853F1AEE8C48FD285F8C806823065A238AD70A99C832C815970C33E8326ECC759378A603C77D20248DFAAD6AC718D5F04AF2635061C904159E1EB37873B383C7A244C81F58A22553B1DC1A74AFB44B44A5AEA3B096DEB8B6FEFA7778ACBE1B1EF0331B2667611340085C51D092DD6AC47814A4D68384007F87EA2EF20E005ED221855CCF2B67FF58CAA28E40CD9C44586CB054670C2B0EF0E6B73852B5B475409BDD6A6042345630EB1A675F51A13F7453936B72FDACC671D863DEFE781698B6AE6CE15FB6936A27A9D5EE7442380812B8EB4FB525A518239E138112E6BCA6FEA3FB27B30E28F6D3084D8B5E01F20C7D3FD7EEF3E3EB55F392717BCA9CA76900EBADB7AEA8A26F704C8417708D51374E98D61E0D649BFCC0957FB0636762453C8D1CE08B95FB90BB5EFF6A50210679E167C1E0B67AEDC6E7000C1C4AA5509F8F81D679855BD6CF8FE556FADACE0E45F1C1387DD1A14BBC8A3097DC11C7E40E5A31BCE2188D99008BC3163D04D03ABFB8AA3F17DCFADF8A26F4F275886B1C3DE598068054BB5D8D1B4CB5BCA9E6E822377AA7625490BD4735DDB2B4558D677C1DC2AF39CD9C67242D1C41FF3109FBA72C9C22E362310A905738BF8CEB12697EA0A0885BE11AE0A44DD1FE5F6F863AA8740BAD7300FE1FE72062D3C1669CA796B541637141925DE49515D497F669A695C2735489B58A6E48FF5D6E884D262E5EE95F1EDF49DF55485891DE9B7F5B1E73AD0953C021E4E58D3B7001B702EB6A030E81DC6DB9265290FC224695CAB521CCA0449069CBF358949B03FD678FEE66DB
-20220418182724 2 6 100 8191 2 CF0A168167DAB1FDFD5C0376DC6E2C93907F486EF5576F14B83FAD667FCC774D179D9A0CB69771C381E7A3AC0F7561E06C8BFD155A9B527EE6F015BDFF6DAE1556CEB985BAAA83E40720B4D91830DDA2BC4BE8C137AB7EB0107D3E04DB39A092C84AEF71E223A40F18B586FA813ED2EC4453A8C15B3531DC651AAFA6136D5BA894B22FA94E96D6034E9A569F4D3366B323D656B5C480D0FC443BA5597B42071CB28466F084FA31856AEAB54268E7DF559C47D0F53F7584273FD41C9C59C130E9E43B0E5664B1FFAE5D3608EBFCDCA6E257B0AED1E270938A03C7494B16E725389F8106CFA4746BD350EFD6688AF36BA679CF2437E25C0335A4C7E51AD3043938D7D49EAD349D50B153346687EC29B70982760D6280C1B92F58AEFC66BAB600A905A40B720A8E75CC1C1D96557F1988FF927ED6C2C614357242CB03E314B19766B1C7D70575A1607B25C6E90F2412DE7D3F140B3B6CD743FEE66DD2F32B35F34C1C4F1523B03F9E68E873FB7697D0D09D387B8E4BA6FF9EE302A8B6D4BEBA2659E8933B8A411BEE451870CA8F388C96C0D1A59F2BCB29CBD5FFDCA855A7A9720E7BCA71037B417D9D54EFED70FB695EB8E3461262884DADE4C7E2F9ED544D650CB9853F1AEE8C48FD285F8C806823065A238AD70A99C832C815970C33E8326ECC759378A603C77D20248DFAAD6AC718D5F04AF2635061C904159E1EB37873B383C7A244C81F58A22553B1DC1A74AFB44B44A5AEA3B096DEB8B6FEFA7778ACBE1B1EF0331B2667611340085C51D092DD6AC47814A4D68384007F87EA2EF20E005ED221855CCF2B67FF58CAA28E40CD9C44586CB054670C2B0EF0E6B73852B5B475409BDD6A6042345630EB1A675F51A13F7453936B72FDACC671D863DEFE781698B6AE6CE15FB6936A27A9D5EE7442380812B8EB4FB525A518239E138112E6BCA6FEA3FB27B30E28F6D3084D8B5E01F20C7D3FD7EEF3E3EB55F392717BCA9CA76900EBADB7AEA8A26F704C8417708D51374E98D61E0D649BFCC0957FB0636762453C8D1CE08B95FB90BB5EFF6A50210679E167C1E0B67AEDC6E7000C1C4AA5509F8F81D679855BD6CF8FE556FADACE0E45F1C1387DD1A14BBC8A3097DC11C7E40E5A31BCE2188D99008BC3163D04D03ABFB8AA3F17DCFADF8A26F4F275886B1C3DE598068054BB5D8D1B4CB5BCA9E6E822377AA7625490BD4735DDB2B4558D677C1DC2AF39CD9C67242D1C41FF3109FBA72C9C22E362310A905738BF8CEB12697EA0A0885BE11AE0A44DD1FE5F6F863AA8740BAD7300FE1FE72062D3C1669CA796B541637141925DE49515D497F669A695C2735489B58A6E48FF5D6E884D262E5EE95F1EDF49DF55485891DE9B7F5B1E73AD0953C021E4E58D3B7001B702EB6A030E81DC6DB9265290FC224695CAB521CCA0449069CBF358949B03FD6794E3AFCB
-20220418183435 2 6 100 8191 5 CF0A168167DAB1FDFD5C0376DC6E2C93907F486EF5576F14B83FAD667FCC774D179D9A0CB69771C381E7A3AC0F7561E06C8BFD155A9B527EE6F015BDFF6DAE1556CEB985BAAA83E40720B4D91830DDA2BC4BE8C137AB7EB0107D3E04DB39A092C84AEF71E223A40F18B586FA813ED2EC4453A8C15B3531DC651AAFA6136D5BA894B22FA94E96D6034E9A569F4D3366B323D656B5C480D0FC443BA5597B42071CB28466F084FA31856AEAB54268E7DF559C47D0F53F7584273FD41C9C59C130E9E43B0E5664B1FFAE5D3608EBFCDCA6E257B0AED1E270938A03C7494B16E725389F8106CFA4746BD350EFD6688AF36BA679CF2437E25C0335A4C7E51AD3043938D7D49EAD349D50B153346687EC29B70982760D6280C1B92F58AEFC66BAB600A905A40B720A8E75CC1C1D96557F1988FF927ED6C2C614357242CB03E314B19766B1C7D70575A1607B25C6E90F2412DE7D3F140B3B6CD743FEE66DD2F32B35F34C1C4F1523B03F9E68E873FB7697D0D09D387B8E4BA6FF9EE302A8B6D4BEBA2659E8933B8A411BEE451870CA8F388C96C0D1A59F2BCB29CBD5FFDCA855A7A9720E7BCA71037B417D9D54EFED70FB695EB8E3461262884DADE4C7E2F9ED544D650CB9853F1AEE8C48FD285F8C806823065A238AD70A99C832C815970C33E8326ECC759378A603C77D20248DFAAD6AC718D5F04AF2635061C904159E1EB37873B383C7A244C81F58A22553B1DC1A74AFB44B44A5AEA3B096DEB8B6FEFA7778ACBE1B1EF0331B2667611340085C51D092DD6AC47814A4D68384007F87EA2EF20E005ED221855CCF2B67FF58CAA28E40CD9C44586CB054670C2B0EF0E6B73852B5B475409BDD6A6042345630EB1A675F51A13F7453936B72FDACC671D863DEFE781698B6AE6CE15FB6936A27A9D5EE7442380812B8EB4FB525A518239E138112E6BCA6FEA3FB27B30E28F6D3084D8B5E01F20C7D3FD7EEF3E3EB55F392717BCA9CA76900EBADB7AEA8A26F704C8417708D51374E98D61E0D649BFCC0957FB0636762453C8D1CE08B95FB90BB5EFF6A50210679E167C1E0B67AEDC6E7000C1C4AA5509F8F81D679855BD6CF8FE556FADACE0E45F1C1387DD1A14BBC8A3097DC11C7E40E5A31BCE2188D99008BC3163D04D03ABFB8AA3F17DCFADF8A26F4F275886B1C3DE598068054BB5D8D1B4CB5BCA9E6E822377AA7625490BD4735DDB2B4558D677C1DC2AF39CD9C67242D1C41FF3109FBA72C9C22E362310A905738BF8CEB12697EA0A0885BE11AE0A44DD1FE5F6F863AA8740BAD7300FE1FE72062D3C1669CA796B541637141925DE49515D497F669A695C2735489B58A6E48FF5D6E884D262E5EE95F1EDF49DF55485891DE9B7F5B1E73AD0953C021E4E58D3B7001B702EB6A030E81DC6DB9265290FC224695CAB521CCA0449069CBF358949B03FD67955AEE87
-20220418185712 2 6 100 8191 5 CF0A168167DAB1FDFD5C0376DC6E2C93907F486EF5576F14B83FAD667FCC774D179D9A0CB69771C381E7A3AC0F7561E06C8BFD155A9B527EE6F015BDFF6DAE1556CEB985BAAA83E40720B4D91830DDA2BC4BE8C137AB7EB0107D3E04DB39A092C84AEF71E223A40F18B586FA813ED2EC4453A8C15B3531DC651AAFA6136D5BA894B22FA94E96D6034E9A569F4D3366B323D656B5C480D0FC443BA5597B42071CB28466F084FA31856AEAB54268E7DF559C47D0F53F7584273FD41C9C59C130E9E43B0E5664B1FFAE5D3608EBFCDCA6E257B0AED1E270938A03C7494B16E725389F8106CFA4746BD350EFD6688AF36BA679CF2437E25C0335A4C7E51AD3043938D7D49EAD349D50B153346687EC29B70982760D6280C1B92F58AEFC66BAB600A905A40B720A8E75CC1C1D96557F1988FF927ED6C2C614357242CB03E314B19766B1C7D70575A1607B25C6E90F2412DE7D3F140B3B6CD743FEE66DD2F32B35F34C1C4F1523B03F9E68E873FB7697D0D09D387B8E4BA6FF9EE302A8B6D4BEBA2659E8933B8A411BEE451870CA8F388C96C0D1A59F2BCB29CBD5FFDCA855A7A9720E7BCA71037B417D9D54EFED70FB695EB8E3461262884DADE4C7E2F9ED544D650CB9853F1AEE8C48FD285F8C806823065A238AD70A99C832C815970C33E8326ECC759378A603C77D20248DFAAD6AC718D5F04AF2635061C904159E1EB37873B383C7A244C81F58A22553B1DC1A74AFB44B44A5AEA3B096DEB8B6FEFA7778ACBE1B1EF0331B2667611340085C51D092DD6AC47814A4D68384007F87EA2EF20E005ED221855CCF2B67FF58CAA28E40CD9C44586CB054670C2B0EF0E6B73852B5B475409BDD6A6042345630EB1A675F51A13F7453936B72FDACC671D863DEFE781698B6AE6CE15FB6936A27A9D5EE7442380812B8EB4FB525A518239E138112E6BCA6FEA3FB27B30E28F6D3084D8B5E01F20C7D3FD7EEF3E3EB55F392717BCA9CA76900EBADB7AEA8A26F704C8417708D51374E98D61E0D649BFCC0957FB0636762453C8D1CE08B95FB90BB5EFF6A50210679E167C1E0B67AEDC6E7000C1C4AA5509F8F81D679855BD6CF8FE556FADACE0E45F1C1387DD1A14BBC8A3097DC11C7E40E5A31BCE2188D99008BC3163D04D03ABFB8AA3F17DCFADF8A26F4F275886B1C3DE598068054BB5D8D1B4CB5BCA9E6E822377AA7625490BD4735DDB2B4558D677C1DC2AF39CD9C67242D1C41FF3109FBA72C9C22E362310A905738BF8CEB12697EA0A0885BE11AE0A44DD1FE5F6F863AA8740BAD7300FE1FE72062D3C1669CA796B541637141925DE49515D497F669A695C2735489B58A6E48FF5D6E884D262E5EE95F1EDF49DF55485891DE9B7F5B1E73AD0953C021E4E58D3B7001B702EB6A030E81DC6DB9265290FC224695CAB521CCA0449069CBF358949B03FD6796E81A27
-20220418201627 2 6 100 8191 5 CF0A168167DAB1FDFD5C0376DC6E2C93907F486EF5576F14B83FAD667FCC774D179D9A0CB69771C381E7A3AC0F7561E06C8BFD155A9B527EE6F015BDFF6DAE1556CEB985BAAA83E40720B4D91830DDA2BC4BE8C137AB7EB0107D3E04DB39A092C84AEF71E223A40F18B586FA813ED2EC4453A8C15B3531DC651AAFA6136D5BA894B22FA94E96D6034E9A569F4D3366B323D656B5C480D0FC443BA5597B42071CB28466F084FA31856AEAB54268E7DF559C47D0F53F7584273FD41C9C59C130E9E43B0E5664B1FFAE5D3608EBFCDCA6E257B0AED1E270938A03C7494B16E725389F8106CFA4746BD350EFD6688AF36BA679CF2437E25C0335A4C7E51AD3043938D7D49EAD349D50B153346687EC29B70982760D6280C1B92F58AEFC66BAB600A905A40B720A8E75CC1C1D96557F1988FF927ED6C2C614357242CB03E314B19766B1C7D70575A1607B25C6E90F2412DE7D3F140B3B6CD743FEE66DD2F32B35F34C1C4F1523B03F9E68E873FB7697D0D09D387B8E4BA6FF9EE302A8B6D4BEBA2659E8933B8A411BEE451870CA8F388C96C0D1A59F2BCB29CBD5FFDCA855A7A9720E7BCA71037B417D9D54EFED70FB695EB8E3461262884DADE4C7E2F9ED544D650CB9853F1AEE8C48FD285F8C806823065A238AD70A99C832C815970C33E8326ECC759378A603C77D20248DFAAD6AC718D5F04AF2635061C904159E1EB37873B383C7A244C81F58A22553B1DC1A74AFB44B44A5AEA3B096DEB8B6FEFA7778ACBE1B1EF0331B2667611340085C51D092DD6AC47814A4D68384007F87EA2EF20E005ED221855CCF2B67FF58CAA28E40CD9C44586CB054670C2B0EF0E6B73852B5B475409BDD6A6042345630EB1A675F51A13F7453936B72FDACC671D863DEFE781698B6AE6CE15FB6936A27A9D5EE7442380812B8EB4FB525A518239E138112E6BCA6FEA3FB27B30E28F6D3084D8B5E01F20C7D3FD7EEF3E3EB55F392717BCA9CA76900EBADB7AEA8A26F704C8417708D51374E98D61E0D649BFCC0957FB0636762453C8D1CE08B95FB90BB5EFF6A50210679E167C1E0B67AEDC6E7000C1C4AA5509F8F81D679855BD6CF8FE556FADACE0E45F1C1387DD1A14BBC8A3097DC11C7E40E5A31BCE2188D99008BC3163D04D03ABFB8AA3F17DCFADF8A26F4F275886B1C3DE598068054BB5D8D1B4CB5BCA9E6E822377AA7625490BD4735DDB2B4558D677C1DC2AF39CD9C67242D1C41FF3109FBA72C9C22E362310A905738BF8CEB12697EA0A0885BE11AE0A44DD1FE5F6F863AA8740BAD7300FE1FE72062D3C1669CA796B541637141925DE49515D497F669A695C2735489B58A6E48FF5D6E884D262E5EE95F1EDF49DF55485891DE9B7F5B1E73AD0953C021E4E58D3B7001B702EB6A030E81DC6DB9265290FC224695CAB521CCA0449069CBF358949B03FD679C621EC7
-20220418211708 2 6 100 8191 2 CF0A168167DAB1FDFD5C0376DC6E2C93907F486EF5576F14B83FAD667FCC774D179D9A0CB69771C381E7A3AC0F7561E06C8BFD155A9B527EE6F015BDFF6DAE1556CEB985BAAA83E40720B4D91830DDA2BC4BE8C137AB7EB0107D3E04DB39A092C84AEF71E223A40F18B586FA813ED2EC4453A8C15B3531DC651AAFA6136D5BA894B22FA94E96D6034E9A569F4D3366B323D656B5C480D0FC443BA5597B42071CB28466F084FA31856AEAB54268E7DF559C47D0F53F7584273FD41C9C59C130E9E43B0E5664B1FFAE5D3608EBFCDCA6E257B0AED1E270938A03C7494B16E725389F8106CFA4746BD350EFD6688AF36BA679CF2437E25C0335A4C7E51AD3043938D7D49EAD349D50B153346687EC29B70982760D6280C1B92F58AEFC66BAB600A905A40B720A8E75CC1C1D96557F1988FF927ED6C2C614357242CB03E314B19766B1C7D70575A1607B25C6E90F2412DE7D3F140B3B6CD743FEE66DD2F32B35F34C1C4F1523B03F9E68E873FB7697D0D09D387B8E4BA6FF9EE302A8B6D4BEBA2659E8933B8A411BEE451870CA8F388C96C0D1A59F2BCB29CBD5FFDCA855A7A9720E7BCA71037B417D9D54EFED70FB695EB8E3461262884DADE4C7E2F9ED544D650CB9853F1AEE8C48FD285F8C806823065A238AD70A99C832C815970C33E8326ECC759378A603C77D20248DFAAD6AC718D5F04AF2635061C904159E1EB37873B383C7A244C81F58A22553B1DC1A74AFB44B44A5AEA3B096DEB8B6FEFA7778ACBE1B1EF0331B2667611340085C51D092DD6AC47814A4D68384007F87EA2EF20E005ED221855CCF2B67FF58CAA28E40CD9C44586CB054670C2B0EF0E6B73852B5B475409BDD6A6042345630EB1A675F51A13F7453936B72FDACC671D863DEFE781698B6AE6CE15FB6936A27A9D5EE7442380812B8EB4FB525A518239E138112E6BCA6FEA3FB27B30E28F6D3084D8B5E01F20C7D3FD7EEF3E3EB55F392717BCA9CA76900EBADB7AEA8A26F704C8417708D51374E98D61E0D649BFCC0957FB0636762453C8D1CE08B95FB90BB5EFF6A50210679E167C1E0B67AEDC6E7000C1C4AA5509F8F81D679855BD6CF8FE556FADACE0E45F1C1387DD1A14BBC8A3097DC11C7E40E5A31BCE2188D99008BC3163D04D03ABFB8AA3F17DCFADF8A26F4F275886B1C3DE598068054BB5D8D1B4CB5BCA9E6E822377AA7625490BD4735DDB2B4558D677C1DC2AF39CD9C67242D1C41FF3109FBA72C9C22E362310A905738BF8CEB12697EA0A0885BE11AE0A44DD1FE5F6F863AA8740BAD7300FE1FE72062D3C1669CA796B541637141925DE49515D497F669A695C2735489B58A6E48FF5D6E884D262E5EE95F1EDF49DF55485891DE9B7F5B1E73AD0953C021E4E58D3B7001B702EB6A030E81DC6DB9265290FC224695CAB521CCA0449069CBF358949B03FD67A079830B
-20220418213706 2 6 100 8191 2 CF0A168167DAB1FDFD5C0376DC6E2C93907F486EF5576F14B83FAD667FCC774D179D9A0CB69771C381E7A3AC0F7561E06C8BFD155A9B527EE6F015BDFF6DAE1556CEB985BAAA83E40720B4D91830DDA2BC4BE8C137AB7EB0107D3E04DB39A092C84AEF71E223A40F18B586FA813ED2EC4453A8C15B3531DC651AAFA6136D5BA894B22FA94E96D6034E9A569F4D3366B323D656B5C480D0FC443BA5597B42071CB28466F084FA31856AEAB54268E7DF559C47D0F53F7584273FD41C9C59C130E9E43B0E5664B1FFAE5D3608EBFCDCA6E257B0AED1E270938A03C7494B16E725389F8106CFA4746BD350EFD6688AF36BA679CF2437E25C0335A4C7E51AD3043938D7D49EAD349D50B153346687EC29B70982760D6280C1B92F58AEFC66BAB600A905A40B720A8E75CC1C1D96557F1988FF927ED6C2C614357242CB03E314B19766B1C7D70575A1607B25C6E90F2412DE7D3F140B3B6CD743FEE66DD2F32B35F34C1C4F1523B03F9E68E873FB7697D0D09D387B8E4BA6FF9EE302A8B6D4BEBA2659E8933B8A411BEE451870CA8F388C96C0D1A59F2BCB29CBD5FFDCA855A7A9720E7BCA71037B417D9D54EFED70FB695EB8E3461262884DADE4C7E2F9ED544D650CB9853F1AEE8C48FD285F8C806823065A238AD70A99C832C815970C33E8326ECC759378A603C77D20248DFAAD6AC718D5F04AF2635061C904159E1EB37873B383C7A244C81F58A22553B1DC1A74AFB44B44A5AEA3B096DEB8B6FEFA7778ACBE1B1EF0331B2667611340085C51D092DD6AC47814A4D68384007F87EA2EF20E005ED221855CCF2B67FF58CAA28E40CD9C44586CB054670C2B0EF0E6B73852B5B475409BDD6A6042345630EB1A675F51A13F7453936B72FDACC671D863DEFE781698B6AE6CE15FB6936A27A9D5EE7442380812B8EB4FB525A518239E138112E6BCA6FEA3FB27B30E28F6D3084D8B5E01F20C7D3FD7EEF3E3EB55F392717BCA9CA76900EBADB7AEA8A26F704C8417708D51374E98D61E0D649BFCC0957FB0636762453C8D1CE08B95FB90BB5EFF6A50210679E167C1E0B67AEDC6E7000C1C4AA5509F8F81D679855BD6CF8FE556FADACE0E45F1C1387DD1A14BBC8A3097DC11C7E40E5A31BCE2188D99008BC3163D04D03ABFB8AA3F17DCFADF8A26F4F275886B1C3DE598068054BB5D8D1B4CB5BCA9E6E822377AA7625490BD4735DDB2B4558D677C1DC2AF39CD9C67242D1C41FF3109FBA72C9C22E362310A905738BF8CEB12697EA0A0885BE11AE0A44DD1FE5F6F863AA8740BAD7300FE1FE72062D3C1669CA796B541637141925DE49515D497F669A695C2735489B58A6E48FF5D6E884D262E5EE95F1EDF49DF55485891DE9B7F5B1E73AD0953C021E4E58D3B7001B702EB6A030E81DC6DB9265290FC224695CAB521CCA0449069CBF358949B03FD67A1C79F63
-20220418222050 2 6 100 8191 5 CF0A168167DAB1FDFD5C0376DC6E2C93907F486EF5576F14B83FAD667FCC774D179D9A0CB69771C381E7A3AC0F7561E06C8BFD155A9B527EE6F015BDFF6DAE1556CEB985BAAA83E40720B4D91830DDA2BC4BE8C137AB7EB0107D3E04DB39A092C84AEF71E223A40F18B586FA813ED2EC4453A8C15B3531DC651AAFA6136D5BA894B22FA94E96D6034E9A569F4D3366B323D656B5C480D0FC443BA5597B42071CB28466F084FA31856AEAB54268E7DF559C47D0F53F7584273FD41C9C59C130E9E43B0E5664B1FFAE5D3608EBFCDCA6E257B0AED1E270938A03C7494B16E725389F8106CFA4746BD350EFD6688AF36BA679CF2437E25C0335A4C7E51AD3043938D7D49EAD349D50B153346687EC29B70982760D6280C1B92F58AEFC66BAB600A905A40B720A8E75CC1C1D96557F1988FF927ED6C2C614357242CB03E314B19766B1C7D70575A1607B25C6E90F2412DE7D3F140B3B6CD743FEE66DD2F32B35F34C1C4F1523B03F9E68E873FB7697D0D09D387B8E4BA6FF9EE302A8B6D4BEBA2659E8933B8A411BEE451870CA8F388C96C0D1A59F2BCB29CBD5FFDCA855A7A9720E7BCA71037B417D9D54EFED70FB695EB8E3461262884DADE4C7E2F9ED544D650CB9853F1AEE8C48FD285F8C806823065A238AD70A99C832C815970C33E8326ECC759378A603C77D20248DFAAD6AC718D5F04AF2635061C904159E1EB37873B383C7A244C81F58A22553B1DC1A74AFB44B44A5AEA3B096DEB8B6FEFA7778ACBE1B1EF0331B2667611340085C51D092DD6AC47814A4D68384007F87EA2EF20E005ED221855CCF2B67FF58CAA28E40CD9C44586CB054670C2B0EF0E6B73852B5B475409BDD6A6042345630EB1A675F51A13F7453936B72FDACC671D863DEFE781698B6AE6CE15FB6936A27A9D5EE7442380812B8EB4FB525A518239E138112E6BCA6FEA3FB27B30E28F6D3084D8B5E01F20C7D3FD7EEF3E3EB55F392717BCA9CA76900EBADB7AEA8A26F704C8417708D51374E98D61E0D649BFCC0957FB0636762453C8D1CE08B95FB90BB5EFF6A50210679E167C1E0B67AEDC6E7000C1C4AA5509F8F81D679855BD6CF8FE556FADACE0E45F1C1387DD1A14BBC8A3097DC11C7E40E5A31BCE2188D99008BC3163D04D03ABFB8AA3F17DCFADF8A26F4F275886B1C3DE598068054BB5D8D1B4CB5BCA9E6E822377AA7625490BD4735DDB2B4558D677C1DC2AF39CD9C67242D1C41FF3109FBA72C9C22E362310A905738BF8CEB12697EA0A0885BE11AE0A44DD1FE5F6F863AA8740BAD7300FE1FE72062D3C1669CA796B541637141925DE49515D497F669A695C2735489B58A6E48FF5D6E884D262E5EE95F1EDF49DF55485891DE9B7F5B1E73AD0953C021E4E58D3B7001B702EB6A030E81DC6DB9265290FC224695CAB521CCA0449069CBF358949B03FD67A4C4F48F
-20220418224223 2 6 100 8191 5 CF0A168167DAB1FDFD5C0376DC6E2C93907F486EF5576F14B83FAD667FCC774D179D9A0CB69771C381E7A3AC0F7561E06C8BFD155A9B527EE6F015BDFF6DAE1556CEB985BAAA83E40720B4D91830DDA2BC4BE8C137AB7EB0107D3E04DB39A092C84AEF71E223A40F18B586FA813ED2EC4453A8C15B3531DC651AAFA6136D5BA894B22FA94E96D6034E9A569F4D3366B323D656B5C480D0FC443BA5597B42071CB28466F084FA31856AEAB54268E7DF559C47D0F53F7584273FD41C9C59C130E9E43B0E5664B1FFAE5D3608EBFCDCA6E257B0AED1E270938A03C7494B16E725389F8106CFA4746BD350EFD6688AF36BA679CF2437E25C0335A4C7E51AD3043938D7D49EAD349D50B153346687EC29B70982760D6280C1B92F58AEFC66BAB600A905A40B720A8E75CC1C1D96557F1988FF927ED6C2C614357242CB03E314B19766B1C7D70575A1607B25C6E90F2412DE7D3F140B3B6CD743FEE66DD2F32B35F34C1C4F1523B03F9E68E873FB7697D0D09D387B8E4BA6FF9EE302A8B6D4BEBA2659E8933B8A411BEE451870CA8F388C96C0D1A59F2BCB29CBD5FFDCA855A7A9720E7BCA71037B417D9D54EFED70FB695EB8E3461262884DADE4C7E2F9ED544D650CB9853F1AEE8C48FD285F8C806823065A238AD70A99C832C815970C33E8326ECC759378A603C77D20248DFAAD6AC718D5F04AF2635061C904159E1EB37873B383C7A244C81F58A22553B1DC1A74AFB44B44A5AEA3B096DEB8B6FEFA7778ACBE1B1EF0331B2667611340085C51D092DD6AC47814A4D68384007F87EA2EF20E005ED221855CCF2B67FF58CAA28E40CD9C44586CB054670C2B0EF0E6B73852B5B475409BDD6A6042345630EB1A675F51A13F7453936B72FDACC671D863DEFE781698B6AE6CE15FB6936A27A9D5EE7442380812B8EB4FB525A518239E138112E6BCA6FEA3FB27B30E28F6D3084D8B5E01F20C7D3FD7EEF3E3EB55F392717BCA9CA76900EBADB7AEA8A26F704C8417708D51374E98D61E0D649BFCC0957FB0636762453C8D1CE08B95FB90BB5EFF6A50210679E167C1E0B67AEDC6E7000C1C4AA5509F8F81D679855BD6CF8FE556FADACE0E45F1C1387DD1A14BBC8A3097DC11C7E40E5A31BCE2188D99008BC3163D04D03ABFB8AA3F17DCFADF8A26F4F275886B1C3DE598068054BB5D8D1B4CB5BCA9E6E822377AA7625490BD4735DDB2B4558D677C1DC2AF39CD9C67242D1C41FF3109FBA72C9C22E362310A905738BF8CEB12697EA0A0885BE11AE0A44DD1FE5F6F863AA8740BAD7300FE1FE72062D3C1669CA796B541637141925DE49515D497F669A695C2735489B58A6E48FF5D6E884D262E5EE95F1EDF49DF55485891DE9B7F5B1E73AD0953C021E4E58D3B7001B702EB6A030E81DC6DB9265290FC224695CAB521CCA0449069CBF358949B03FD67A634298F
-20220419011431 2 6 100 8191 2 CF0A168167DAB1FDFD5C0376DC6E2C93907F486EF5576F14B83FAD667FCC774D179D9A0CB69771C381E7A3AC0F7561E06C8BFD155A9B527EE6F015BDFF6DAE1556CEB985BAAA83E40720B4D91830DDA2BC4BE8C137AB7EB0107D3E04DB39A092C84AEF71E223A40F18B586FA813ED2EC4453A8C15B3531DC651AAFA6136D5BA894B22FA94E96D6034E9A569F4D3366B323D656B5C480D0FC443BA5597B42071CB28466F084FA31856AEAB54268E7DF559C47D0F53F7584273FD41C9C59C130E9E43B0E5664B1FFAE5D3608EBFCDCA6E257B0AED1E270938A03C7494B16E725389F8106CFA4746BD350EFD6688AF36BA679CF2437E25C0335A4C7E51AD3043938D7D49EAD349D50B153346687EC29B70982760D6280C1B92F58AEFC66BAB600A905A40B720A8E75CC1C1D96557F1988FF927ED6C2C614357242CB03E314B19766B1C7D70575A1607B25C6E90F2412DE7D3F140B3B6CD743FEE66DD2F32B35F34C1C4F1523B03F9E68E873FB7697D0D09D387B8E4BA6FF9EE302A8B6D4BEBA2659E8933B8A411BEE451870CA8F388C96C0D1A59F2BCB29CBD5FFDCA855A7A9720E7BCA71037B417D9D54EFED70FB695EB8E3461262884DADE4C7E2F9ED544D650CB9853F1AEE8C48FD285F8C806823065A238AD70A99C832C815970C33E8326ECC759378A603C77D20248DFAAD6AC718D5F04AF2635061C904159E1EB37873B383C7A244C81F58A22553B1DC1A74AFB44B44A5AEA3B096DEB8B6FEFA7778ACBE1B1EF0331B2667611340085C51D092DD6AC47814A4D68384007F87EA2EF20E005ED221855CCF2B67FF58CAA28E40CD9C44586CB054670C2B0EF0E6B73852B5B475409BDD6A6042345630EB1A675F51A13F7453936B72FDACC671D863DEFE781698B6AE6CE15FB6936A27A9D5EE7442380812B8EB4FB525A518239E138112E6BCA6FEA3FB27B30E28F6D3084D8B5E01F20C7D3FD7EEF3E3EB55F392717BCA9CA76900EBADB7AEA8A26F704C8417708D51374E98D61E0D649BFCC0957FB0636762453C8D1CE08B95FB90BB5EFF6A50210679E167C1E0B67AEDC6E7000C1C4AA5509F8F81D679855BD6CF8FE556FADACE0E45F1C1387DD1A14BBC8A3097DC11C7E40E5A31BCE2188D99008BC3163D04D03ABFB8AA3F17DCFADF8A26F4F275886B1C3DE598068054BB5D8D1B4CB5BCA9E6E822377AA7625490BD4735DDB2B4558D677C1DC2AF39CD9C67242D1C41FF3109FBA72C9C22E362310A905738BF8CEB12697EA0A0885BE11AE0A44DD1FE5F6F863AA8740BAD7300FE1FE72062D3C1669CA796B541637141925DE49515D497F669A695C2735489B58A6E48FF5D6E884D262E5EE95F1EDF49DF55485891DE9B7F5B1E73AD0953C021E4E58D3B7001B702EB6A030E81DC6DB9265290FC224695CAB521CCA0449069CBF358949B03FD67B069D573
-20220419021153 2 6 100 8191 2 CF0A168167DAB1FDFD5C0376DC6E2C93907F486EF5576F14B83FAD667FCC774D179D9A0CB69771C381E7A3AC0F7561E06C8BFD155A9B527EE6F015BDFF6DAE1556CEB985BAAA83E40720B4D91830DDA2BC4BE8C137AB7EB0107D3E04DB39A092C84AEF71E223A40F18B586FA813ED2EC4453A8C15B3531DC651AAFA6136D5BA894B22FA94E96D6034E9A569F4D3366B323D656B5C480D0FC443BA5597B42071CB28466F084FA31856AEAB54268E7DF559C47D0F53F7584273FD41C9C59C130E9E43B0E5664B1FFAE5D3608EBFCDCA6E257B0AED1E270938A03C7494B16E725389F8106CFA4746BD350EFD6688AF36BA679CF2437E25C0335A4C7E51AD3043938D7D49EAD349D50B153346687EC29B70982760D6280C1B92F58AEFC66BAB600A905A40B720A8E75CC1C1D96557F1988FF927ED6C2C614357242CB03E314B19766B1C7D70575A1607B25C6E90F2412DE7D3F140B3B6CD743FEE66DD2F32B35F34C1C4F1523B03F9E68E873FB7697D0D09D387B8E4BA6FF9EE302A8B6D4BEBA2659E8933B8A411BEE451870CA8F388C96C0D1A59F2BCB29CBD5FFDCA855A7A9720E7BCA71037B417D9D54EFED70FB695EB8E3461262884DADE4C7E2F9ED544D650CB9853F1AEE8C48FD285F8C806823065A238AD70A99C832C815970C33E8326ECC759378A603C77D20248DFAAD6AC718D5F04AF2635061C904159E1EB37873B383C7A244C81F58A22553B1DC1A74AFB44B44A5AEA3B096DEB8B6FEFA7778ACBE1B1EF0331B2667611340085C51D092DD6AC47814A4D68384007F87EA2EF20E005ED221855CCF2B67FF58CAA28E40CD9C44586CB054670C2B0EF0E6B73852B5B475409BDD6A6042345630EB1A675F51A13F7453936B72FDACC671D863DEFE781698B6AE6CE15FB6936A27A9D5EE7442380812B8EB4FB525A518239E138112E6BCA6FEA3FB27B30E28F6D3084D8B5E01F20C7D3FD7EEF3E3EB55F392717BCA9CA76900EBADB7AEA8A26F704C8417708D51374E98D61E0D649BFCC0957FB0636762453C8D1CE08B95FB90BB5EFF6A50210679E167C1E0B67AEDC6E7000C1C4AA5509F8F81D679855BD6CF8FE556FADACE0E45F1C1387DD1A14BBC8A3097DC11C7E40E5A31BCE2188D99008BC3163D04D03ABFB8AA3F17DCFADF8A26F4F275886B1C3DE598068054BB5D8D1B4CB5BCA9E6E822377AA7625490BD4735DDB2B4558D677C1DC2AF39CD9C67242D1C41FF3109FBA72C9C22E362310A905738BF8CEB12697EA0A0885BE11AE0A44DD1FE5F6F863AA8740BAD7300FE1FE72062D3C1669CA796B541637141925DE49515D497F669A695C2735489B58A6E48FF5D6E884D262E5EE95F1EDF49DF55485891DE9B7F5B1E73AD0953C021E4E58D3B7001B702EB6A030E81DC6DB9265290FC224695CAB521CCA0449069CBF358949B03FD67B43DEC33
-20220419031338 2 6 100 8191 2 CF0A168167DAB1FDFD5C0376DC6E2C93907F486EF5576F14B83FAD667FCC774D179D9A0CB69771C381E7A3AC0F7561E06C8BFD155A9B527EE6F015BDFF6DAE1556CEB985BAAA83E40720B4D91830DDA2BC4BE8C137AB7EB0107D3E04DB39A092C84AEF71E223A40F18B586FA813ED2EC4453A8C15B3531DC651AAFA6136D5BA894B22FA94E96D6034E9A569F4D3366B323D656B5C480D0FC443BA5597B42071CB28466F084FA31856AEAB54268E7DF559C47D0F53F7584273FD41C9C59C130E9E43B0E5664B1FFAE5D3608EBFCDCA6E257B0AED1E270938A03C7494B16E725389F8106CFA4746BD350EFD6688AF36BA679CF2437E25C0335A4C7E51AD3043938D7D49EAD349D50B153346687EC29B70982760D6280C1B92F58AEFC66BAB600A905A40B720A8E75CC1C1D96557F1988FF927ED6C2C614357242CB03E314B19766B1C7D70575A1607B25C6E90F2412DE7D3F140B3B6CD743FEE66DD2F32B35F34C1C4F1523B03F9E68E873FB7697D0D09D387B8E4BA6FF9EE302A8B6D4BEBA2659E8933B8A411BEE451870CA8F388C96C0D1A59F2BCB29CBD5FFDCA855A7A9720E7BCA71037B417D9D54EFED70FB695EB8E3461262884DADE4C7E2F9ED544D650CB9853F1AEE8C48FD285F8C806823065A238AD70A99C832C815970C33E8326ECC759378A603C77D20248DFAAD6AC718D5F04AF2635061C904159E1EB37873B383C7A244C81F58A22553B1DC1A74AFB44B44A5AEA3B096DEB8B6FEFA7778ACBE1B1EF0331B2667611340085C51D092DD6AC47814A4D68384007F87EA2EF20E005ED221855CCF2B67FF58CAA28E40CD9C44586CB054670C2B0EF0E6B73852B5B475409BDD6A6042345630EB1A675F51A13F7453936B72FDACC671D863DEFE781698B6AE6CE15FB6936A27A9D5EE7442380812B8EB4FB525A518239E138112E6BCA6FEA3FB27B30E28F6D3084D8B5E01F20C7D3FD7EEF3E3EB55F392717BCA9CA76900EBADB7AEA8A26F704C8417708D51374E98D61E0D649BFCC0957FB0636762453C8D1CE08B95FB90BB5EFF6A50210679E167C1E0B67AEDC6E7000C1C4AA5509F8F81D679855BD6CF8FE556FADACE0E45F1C1387DD1A14BBC8A3097DC11C7E40E5A31BCE2188D99008BC3163D04D03ABFB8AA3F17DCFADF8A26F4F275886B1C3DE598068054BB5D8D1B4CB5BCA9E6E822377AA7625490BD4735DDB2B4558D677C1DC2AF39CD9C67242D1C41FF3109FBA72C9C22E362310A905738BF8CEB12697EA0A0885BE11AE0A44DD1FE5F6F863AA8740BAD7300FE1FE72062D3C1669CA796B541637141925DE49515D497F669A695C2735489B58A6E48FF5D6E884D262E5EE95F1EDF49DF55485891DE9B7F5B1E73AD0953C021E4E58D3B7001B702EB6A030E81DC6DB9265290FC224695CAB521CCA0449069CBF358949B03FD67B845003B
-20220419040146 2 6 100 8191 2 CF0A168167DAB1FDFD5C0376DC6E2C93907F486EF5576F14B83FAD667FCC774D179D9A0CB69771C381E7A3AC0F7561E06C8BFD155A9B527EE6F015BDFF6DAE1556CEB985BAAA83E40720B4D91830DDA2BC4BE8C137AB7EB0107D3E04DB39A092C84AEF71E223A40F18B586FA813ED2EC4453A8C15B3531DC651AAFA6136D5BA894B22FA94E96D6034E9A569F4D3366B323D656B5C480D0FC443BA5597B42071CB28466F084FA31856AEAB54268E7DF559C47D0F53F7584273FD41C9C59C130E9E43B0E5664B1FFAE5D3608EBFCDCA6E257B0AED1E270938A03C7494B16E725389F8106CFA4746BD350EFD6688AF36BA679CF2437E25C0335A4C7E51AD3043938D7D49EAD349D50B153346687EC29B70982760D6280C1B92F58AEFC66BAB600A905A40B720A8E75CC1C1D96557F1988FF927ED6C2C614357242CB03E314B19766B1C7D70575A1607B25C6E90F2412DE7D3F140B3B6CD743FEE66DD2F32B35F34C1C4F1523B03F9E68E873FB7697D0D09D387B8E4BA6FF9EE302A8B6D4BEBA2659E8933B8A411BEE451870CA8F388C96C0D1A59F2BCB29CBD5FFDCA855A7A9720E7BCA71037B417D9D54EFED70FB695EB8E3461262884DADE4C7E2F9ED544D650CB9853F1AEE8C48FD285F8C806823065A238AD70A99C832C815970C33E8326ECC759378A603C77D20248DFAAD6AC718D5F04AF2635061C904159E1EB37873B383C7A244C81F58A22553B1DC1A74AFB44B44A5AEA3B096DEB8B6FEFA7778ACBE1B1EF0331B2667611340085C51D092DD6AC47814A4D68384007F87EA2EF20E005ED221855CCF2B67FF58CAA28E40CD9C44586CB054670C2B0EF0E6B73852B5B475409BDD6A6042345630EB1A675F51A13F7453936B72FDACC671D863DEFE781698B6AE6CE15FB6936A27A9D5EE7442380812B8EB4FB525A518239E138112E6BCA6FEA3FB27B30E28F6D3084D8B5E01F20C7D3FD7EEF3E3EB55F392717BCA9CA76900EBADB7AEA8A26F704C8417708D51374E98D61E0D649BFCC0957FB0636762453C8D1CE08B95FB90BB5EFF6A50210679E167C1E0B67AEDC6E7000C1C4AA5509F8F81D679855BD6CF8FE556FADACE0E45F1C1387DD1A14BBC8A3097DC11C7E40E5A31BCE2188D99008BC3163D04D03ABFB8AA3F17DCFADF8A26F4F275886B1C3DE598068054BB5D8D1B4CB5BCA9E6E822377AA7625490BD4735DDB2B4558D677C1DC2AF39CD9C67242D1C41FF3109FBA72C9C22E362310A905738BF8CEB12697EA0A0885BE11AE0A44DD1FE5F6F863AA8740BAD7300FE1FE72062D3C1669CA796B541637141925DE49515D497F669A695C2735489B58A6E48FF5D6E884D262E5EE95F1EDF49DF55485891DE9B7F5B1E73AD0953C021E4E58D3B7001B702EB6A030E81DC6DB9265290FC224695CAB521CCA0449069CBF358949B03FD67BB6317DB
-20220419060359 2 6 100 8191 5 CF0A168167DAB1FDFD5C0376DC6E2C93907F486EF5576F14B83FAD667FCC774D179D9A0CB69771C381E7A3AC0F7561E06C8BFD155A9B527EE6F015BDFF6DAE1556CEB985BAAA83E40720B4D91830DDA2BC4BE8C137AB7EB0107D3E04DB39A092C84AEF71E223A40F18B586FA813ED2EC4453A8C15B3531DC651AAFA6136D5BA894B22FA94E96D6034E9A569F4D3366B323D656B5C480D0FC443BA5597B42071CB28466F084FA31856AEAB54268E7DF559C47D0F53F7584273FD41C9C59C130E9E43B0E5664B1FFAE5D3608EBFCDCA6E257B0AED1E270938A03C7494B16E725389F8106CFA4746BD350EFD6688AF36BA679CF2437E25C0335A4C7E51AD3043938D7D49EAD349D50B153346687EC29B70982760D6280C1B92F58AEFC66BAB600A905A40B720A8E75CC1C1D96557F1988FF927ED6C2C614357242CB03E314B19766B1C7D70575A1607B25C6E90F2412DE7D3F140B3B6CD743FEE66DD2F32B35F34C1C4F1523B03F9E68E873FB7697D0D09D387B8E4BA6FF9EE302A8B6D4BEBA2659E8933B8A411BEE451870CA8F388C96C0D1A59F2BCB29CBD5FFDCA855A7A9720E7BCA71037B417D9D54EFED70FB695EB8E3461262884DADE4C7E2F9ED544D650CB9853F1AEE8C48FD285F8C806823065A238AD70A99C832C815970C33E8326ECC759378A603C77D20248DFAAD6AC718D5F04AF2635061C904159E1EB37873B383C7A244C81F58A22553B1DC1A74AFB44B44A5AEA3B096DEB8B6FEFA7778ACBE1B1EF0331B2667611340085C51D092DD6AC47814A4D68384007F87EA2EF20E005ED221855CCF2B67FF58CAA28E40CD9C44586CB054670C2B0EF0E6B73852B5B475409BDD6A6042345630EB1A675F51A13F7453936B72FDACC671D863DEFE781698B6AE6CE15FB6936A27A9D5EE7442380812B8EB4FB525A518239E138112E6BCA6FEA3FB27B30E28F6D3084D8B5E01F20C7D3FD7EEF3E3EB55F392717BCA9CA76900EBADB7AEA8A26F704C8417708D51374E98D61E0D649BFCC0957FB0636762453C8D1CE08B95FB90BB5EFF6A50210679E167C1E0B67AEDC6E7000C1C4AA5509F8F81D679855BD6CF8FE556FADACE0E45F1C1387DD1A14BBC8A3097DC11C7E40E5A31BCE2188D99008BC3163D04D03ABFB8AA3F17DCFADF8A26F4F275886B1C3DE598068054BB5D8D1B4CB5BCA9E6E822377AA7625490BD4735DDB2B4558D677C1DC2AF39CD9C67242D1C41FF3109FBA72C9C22E362310A905738BF8CEB12697EA0A0885BE11AE0A44DD1FE5F6F863AA8740BAD7300FE1FE72062D3C1669CA796B541637141925DE49515D497F669A695C2735489B58A6E48FF5D6E884D262E5EE95F1EDF49DF55485891DE9B7F5B1E73AD0953C021E4E58D3B7001B702EB6A030E81DC6DB9265290FC224695CAB521CCA0449069CBF358949B03FD67C35DBBA7
-20220419082948 2 6 100 8191 2 CF0A168167DAB1FDFD5C0376DC6E2C93907F486EF5576F14B83FAD667FCC774D179D9A0CB69771C381E7A3AC0F7561E06C8BFD155A9B527EE6F015BDFF6DAE1556CEB985BAAA83E40720B4D91830DDA2BC4BE8C137AB7EB0107D3E04DB39A092C84AEF71E223A40F18B586FA813ED2EC4453A8C15B3531DC651AAFA6136D5BA894B22FA94E96D6034E9A569F4D3366B323D656B5C480D0FC443BA5597B42071CB28466F084FA31856AEAB54268E7DF559C47D0F53F7584273FD41C9C59C130E9E43B0E5664B1FFAE5D3608EBFCDCA6E257B0AED1E270938A03C7494B16E725389F8106CFA4746BD350EFD6688AF36BA679CF2437E25C0335A4C7E51AD3043938D7D49EAD349D50B153346687EC29B70982760D6280C1B92F58AEFC66BAB600A905A40B720A8E75CC1C1D96557F1988FF927ED6C2C614357242CB03E314B19766B1C7D70575A1607B25C6E90F2412DE7D3F140B3B6CD743FEE66DD2F32B35F34C1C4F1523B03F9E68E873FB7697D0D09D387B8E4BA6FF9EE302A8B6D4BEBA2659E8933B8A411BEE451870CA8F388C96C0D1A59F2BCB29CBD5FFDCA855A7A9720E7BCA71037B417D9D54EFED70FB695EB8E3461262884DADE4C7E2F9ED544D650CB9853F1AEE8C48FD285F8C806823065A238AD70A99C832C815970C33E8326ECC759378A603C77D20248DFAAD6AC718D5F04AF2635061C904159E1EB37873B383C7A244C81F58A22553B1DC1A74AFB44B44A5AEA3B096DEB8B6FEFA7778ACBE1B1EF0331B2667611340085C51D092DD6AC47814A4D68384007F87EA2EF20E005ED221855CCF2B67FF58CAA28E40CD9C44586CB054670C2B0EF0E6B73852B5B475409BDD6A6042345630EB1A675F51A13F7453936B72FDACC671D863DEFE781698B6AE6CE15FB6936A27A9D5EE7442380812B8EB4FB525A518239E138112E6BCA6FEA3FB27B30E28F6D3084D8B5E01F20C7D3FD7EEF3E3EB55F392717BCA9CA76900EBADB7AEA8A26F704C8417708D51374E98D61E0D649BFCC0957FB0636762453C8D1CE08B95FB90BB5EFF6A50210679E167C1E0B67AEDC6E7000C1C4AA5509F8F81D679855BD6CF8FE556FADACE0E45F1C1387DD1A14BBC8A3097DC11C7E40E5A31BCE2188D99008BC3163D04D03ABFB8AA3F17DCFADF8A26F4F275886B1C3DE598068054BB5D8D1B4CB5BCA9E6E822377AA7625490BD4735DDB2B4558D677C1DC2AF39CD9C67242D1C41FF3109FBA72C9C22E362310A905738BF8CEB12697EA0A0885BE11AE0A44DD1FE5F6F863AA8740BAD7300FE1FE72062D3C1669CA796B541637141925DE49515D497F669A695C2735489B58A6E48FF5D6E884D262E5EE95F1EDF49DF55485891DE9B7F5B1E73AD0953C021E4E58D3B7001B702EB6A030E81DC6DB9265290FC224695CAB521CCA0449069CBF358949B03FD67CCD1BF53
-20220419084823 2 6 100 8191 2 CF0A168167DAB1FDFD5C0376DC6E2C93907F486EF5576F14B83FAD667FCC774D179D9A0CB69771C381E7A3AC0F7561E06C8BFD155A9B527EE6F015BDFF6DAE1556CEB985BAAA83E40720B4D91830DDA2BC4BE8C137AB7EB0107D3E04DB39A092C84AEF71E223A40F18B586FA813ED2EC4453A8C15B3531DC651AAFA6136D5BA894B22FA94E96D6034E9A569F4D3366B323D656B5C480D0FC443BA5597B42071CB28466F084FA31856AEAB54268E7DF559C47D0F53F7584273FD41C9C59C130E9E43B0E5664B1FFAE5D3608EBFCDCA6E257B0AED1E270938A03C7494B16E725389F8106CFA4746BD350EFD6688AF36BA679CF2437E25C0335A4C7E51AD3043938D7D49EAD349D50B153346687EC29B70982760D6280C1B92F58AEFC66BAB600A905A40B720A8E75CC1C1D96557F1988FF927ED6C2C614357242CB03E314B19766B1C7D70575A1607B25C6E90F2412DE7D3F140B3B6CD743FEE66DD2F32B35F34C1C4F1523B03F9E68E873FB7697D0D09D387B8E4BA6FF9EE302A8B6D4BEBA2659E8933B8A411BEE451870CA8F388C96C0D1A59F2BCB29CBD5FFDCA855A7A9720E7BCA71037B417D9D54EFED70FB695EB8E3461262884DADE4C7E2F9ED544D650CB9853F1AEE8C48FD285F8C806823065A238AD70A99C832C815970C33E8326ECC759378A603C77D20248DFAAD6AC718D5F04AF2635061C904159E1EB37873B383C7A244C81F58A22553B1DC1A74AFB44B44A5AEA3B096DEB8B6FEFA7778ACBE1B1EF0331B2667611340085C51D092DD6AC47814A4D68384007F87EA2EF20E005ED221855CCF2B67FF58CAA28E40CD9C44586CB054670C2B0EF0E6B73852B5B475409BDD6A6042345630EB1A675F51A13F7453936B72FDACC671D863DEFE781698B6AE6CE15FB6936A27A9D5EE7442380812B8EB4FB525A518239E138112E6BCA6FEA3FB27B30E28F6D3084D8B5E01F20C7D3FD7EEF3E3EB55F392717BCA9CA76900EBADB7AEA8A26F704C8417708D51374E98D61E0D649BFCC0957FB0636762453C8D1CE08B95FB90BB5EFF6A50210679E167C1E0B67AEDC6E7000C1C4AA5509F8F81D679855BD6CF8FE556FADACE0E45F1C1387DD1A14BBC8A3097DC11C7E40E5A31BCE2188D99008BC3163D04D03ABFB8AA3F17DCFADF8A26F4F275886B1C3DE598068054BB5D8D1B4CB5BCA9E6E822377AA7625490BD4735DDB2B4558D677C1DC2AF39CD9C67242D1C41FF3109FBA72C9C22E362310A905738BF8CEB12697EA0A0885BE11AE0A44DD1FE5F6F863AA8740BAD7300FE1FE72062D3C1669CA796B541637141925DE49515D497F669A695C2735489B58A6E48FF5D6E884D262E5EE95F1EDF49DF55485891DE9B7F5B1E73AD0953C021E4E58D3B7001B702EB6A030E81DC6DB9265290FC224695CAB521CCA0449069CBF358949B03FD67CDFBAF53
-20220419091604 2 6 100 8191 2 CF0A168167DAB1FDFD5C0376DC6E2C93907F486EF5576F14B83FAD667FCC774D179D9A0CB69771C381E7A3AC0F7561E06C8BFD155A9B527EE6F015BDFF6DAE1556CEB985BAAA83E40720B4D91830DDA2BC4BE8C137AB7EB0107D3E04DB39A092C84AEF71E223A40F18B586FA813ED2EC4453A8C15B3531DC651AAFA6136D5BA894B22FA94E96D6034E9A569F4D3366B323D656B5C480D0FC443BA5597B42071CB28466F084FA31856AEAB54268E7DF559C47D0F53F7584273FD41C9C59C130E9E43B0E5664B1FFAE5D3608EBFCDCA6E257B0AED1E270938A03C7494B16E725389F8106CFA4746BD350EFD6688AF36BA679CF2437E25C0335A4C7E51AD3043938D7D49EAD349D50B153346687EC29B70982760D6280C1B92F58AEFC66BAB600A905A40B720A8E75CC1C1D96557F1988FF927ED6C2C614357242CB03E314B19766B1C7D70575A1607B25C6E90F2412DE7D3F140B3B6CD743FEE66DD2F32B35F34C1C4F1523B03F9E68E873FB7697D0D09D387B8E4BA6FF9EE302A8B6D4BEBA2659E8933B8A411BEE451870CA8F388C96C0D1A59F2BCB29CBD5FFDCA855A7A9720E7BCA71037B417D9D54EFED70FB695EB8E3461262884DADE4C7E2F9ED544D650CB9853F1AEE8C48FD285F8C806823065A238AD70A99C832C815970C33E8326ECC759378A603C77D20248DFAAD6AC718D5F04AF2635061C904159E1EB37873B383C7A244C81F58A22553B1DC1A74AFB44B44A5AEA3B096DEB8B6FEFA7778ACBE1B1EF0331B2667611340085C51D092DD6AC47814A4D68384007F87EA2EF20E005ED221855CCF2B67FF58CAA28E40CD9C44586CB054670C2B0EF0E6B73852B5B475409BDD6A6042345630EB1A675F51A13F7453936B72FDACC671D863DEFE781698B6AE6CE15FB6936A27A9D5EE7442380812B8EB4FB525A518239E138112E6BCA6FEA3FB27B30E28F6D3084D8B5E01F20C7D3FD7EEF3E3EB55F392717BCA9CA76900EBADB7AEA8A26F704C8417708D51374E98D61E0D649BFCC0957FB0636762453C8D1CE08B95FB90BB5EFF6A50210679E167C1E0B67AEDC6E7000C1C4AA5509F8F81D679855BD6CF8FE556FADACE0E45F1C1387DD1A14BBC8A3097DC11C7E40E5A31BCE2188D99008BC3163D04D03ABFB8AA3F17DCFADF8A26F4F275886B1C3DE598068054BB5D8D1B4CB5BCA9E6E822377AA7625490BD4735DDB2B4558D677C1DC2AF39CD9C67242D1C41FF3109FBA72C9C22E362310A905738BF8CEB12697EA0A0885BE11AE0A44DD1FE5F6F863AA8740BAD7300FE1FE72062D3C1669CA796B541637141925DE49515D497F669A695C2735489B58A6E48FF5D6E884D262E5EE95F1EDF49DF55485891DE9B7F5B1E73AD0953C021E4E58D3B7001B702EB6A030E81DC6DB9265290FC224695CAB521CCA0449069CBF358949B03FD67CFB4406B
-20220419103659 2 6 100 8191 2 CF0A168167DAB1FDFD5C0376DC6E2C93907F486EF5576F14B83FAD667FCC774D179D9A0CB69771C381E7A3AC0F7561E06C8BFD155A9B527EE6F015BDFF6DAE1556CEB985BAAA83E40720B4D91830DDA2BC4BE8C137AB7EB0107D3E04DB39A092C84AEF71E223A40F18B586FA813ED2EC4453A8C15B3531DC651AAFA6136D5BA894B22FA94E96D6034E9A569F4D3366B323D656B5C480D0FC443BA5597B42071CB28466F084FA31856AEAB54268E7DF559C47D0F53F7584273FD41C9C59C130E9E43B0E5664B1FFAE5D3608EBFCDCA6E257B0AED1E270938A03C7494B16E725389F8106CFA4746BD350EFD6688AF36BA679CF2437E25C0335A4C7E51AD3043938D7D49EAD349D50B153346687EC29B70982760D6280C1B92F58AEFC66BAB600A905A40B720A8E75CC1C1D96557F1988FF927ED6C2C614357242CB03E314B19766B1C7D70575A1607B25C6E90F2412DE7D3F140B3B6CD743FEE66DD2F32B35F34C1C4F1523B03F9E68E873FB7697D0D09D387B8E4BA6FF9EE302A8B6D4BEBA2659E8933B8A411BEE451870CA8F388C96C0D1A59F2BCB29CBD5FFDCA855A7A9720E7BCA71037B417D9D54EFED70FB695EB8E3461262884DADE4C7E2F9ED544D650CB9853F1AEE8C48FD285F8C806823065A238AD70A99C832C815970C33E8326ECC759378A603C77D20248DFAAD6AC718D5F04AF2635061C904159E1EB37873B383C7A244C81F58A22553B1DC1A74AFB44B44A5AEA3B096DEB8B6FEFA7778ACBE1B1EF0331B2667611340085C51D092DD6AC47814A4D68384007F87EA2EF20E005ED221855CCF2B67FF58CAA28E40CD9C44586CB054670C2B0EF0E6B73852B5B475409BDD6A6042345630EB1A675F51A13F7453936B72FDACC671D863DEFE781698B6AE6CE15FB6936A27A9D5EE7442380812B8EB4FB525A518239E138112E6BCA6FEA3FB27B30E28F6D3084D8B5E01F20C7D3FD7EEF3E3EB55F392717BCA9CA76900EBADB7AEA8A26F704C8417708D51374E98D61E0D649BFCC0957FB0636762453C8D1CE08B95FB90BB5EFF6A50210679E167C1E0B67AEDC6E7000C1C4AA5509F8F81D679855BD6CF8FE556FADACE0E45F1C1387DD1A14BBC8A3097DC11C7E40E5A31BCE2188D99008BC3163D04D03ABFB8AA3F17DCFADF8A26F4F275886B1C3DE598068054BB5D8D1B4CB5BCA9E6E822377AA7625490BD4735DDB2B4558D677C1DC2AF39CD9C67242D1C41FF3109FBA72C9C22E362310A905738BF8CEB12697EA0A0885BE11AE0A44DD1FE5F6F863AA8740BAD7300FE1FE72062D3C1669CA796B541637141925DE49515D497F669A695C2735489B58A6E48FF5D6E884D262E5EE95F1EDF49DF55485891DE9B7F5B1E73AD0953C021E4E58D3B7001B702EB6A030E81DC6DB9265290FC224695CAB521CCA0449069CBF358949B03FD67D4D81393
-20220419110019 2 6 100 8191 2 CF0A168167DAB1FDFD5C0376DC6E2C93907F486EF5576F14B83FAD667FCC774D179D9A0CB69771C381E7A3AC0F7561E06C8BFD155A9B527EE6F015BDFF6DAE1556CEB985BAAA83E40720B4D91830DDA2BC4BE8C137AB7EB0107D3E04DB39A092C84AEF71E223A40F18B586FA813ED2EC4453A8C15B3531DC651AAFA6136D5BA894B22FA94E96D6034E9A569F4D3366B323D656B5C480D0FC443BA5597B42071CB28466F084FA31856AEAB54268E7DF559C47D0F53F7584273FD41C9C59C130E9E43B0E5664B1FFAE5D3608EBFCDCA6E257B0AED1E270938A03C7494B16E725389F8106CFA4746BD350EFD6688AF36BA679CF2437E25C0335A4C7E51AD3043938D7D49EAD349D50B153346687EC29B70982760D6280C1B92F58AEFC66BAB600A905A40B720A8E75CC1C1D96557F1988FF927ED6C2C614357242CB03E314B19766B1C7D70575A1607B25C6E90F2412DE7D3F140B3B6CD743FEE66DD2F32B35F34C1C4F1523B03F9E68E873FB7697D0D09D387B8E4BA6FF9EE302A8B6D4BEBA2659E8933B8A411BEE451870CA8F388C96C0D1A59F2BCB29CBD5FFDCA855A7A9720E7BCA71037B417D9D54EFED70FB695EB8E3461262884DADE4C7E2F9ED544D650CB9853F1AEE8C48FD285F8C806823065A238AD70A99C832C815970C33E8326ECC759378A603C77D20248DFAAD6AC718D5F04AF2635061C904159E1EB37873B383C7A244C81F58A22553B1DC1A74AFB44B44A5AEA3B096DEB8B6FEFA7778ACBE1B1EF0331B2667611340085C51D092DD6AC47814A4D68384007F87EA2EF20E005ED221855CCF2B67FF58CAA28E40CD9C44586CB054670C2B0EF0E6B73852B5B475409BDD6A6042345630EB1A675F51A13F7453936B72FDACC671D863DEFE781698B6AE6CE15FB6936A27A9D5EE7442380812B8EB4FB525A518239E138112E6BCA6FEA3FB27B30E28F6D3084D8B5E01F20C7D3FD7EEF3E3EB55F392717BCA9CA76900EBADB7AEA8A26F704C8417708D51374E98D61E0D649BFCC0957FB0636762453C8D1CE08B95FB90BB5EFF6A50210679E167C1E0B67AEDC6E7000C1C4AA5509F8F81D679855BD6CF8FE556FADACE0E45F1C1387DD1A14BBC8A3097DC11C7E40E5A31BCE2188D99008BC3163D04D03ABFB8AA3F17DCFADF8A26F4F275886B1C3DE598068054BB5D8D1B4CB5BCA9E6E822377AA7625490BD4735DDB2B4558D677C1DC2AF39CD9C67242D1C41FF3109FBA72C9C22E362310A905738BF8CEB12697EA0A0885BE11AE0A44DD1FE5F6F863AA8740BAD7300FE1FE72062D3C1669CA796B541637141925DE49515D497F669A695C2735489B58A6E48FF5D6E884D262E5EE95F1EDF49DF55485891DE9B7F5B1E73AD0953C021E4E58D3B7001B702EB6A030E81DC6DB9265290FC224695CAB521CCA0449069CBF358949B03FD67D653D053
-20220419124806 2 6 100 8191 2 CF0A168167DAB1FDFD5C0376DC6E2C93907F486EF5576F14B83FAD667FCC774D179D9A0CB69771C381E7A3AC0F7561E06C8BFD155A9B527EE6F015BDFF6DAE1556CEB985BAAA83E40720B4D91830DDA2BC4BE8C137AB7EB0107D3E04DB39A092C84AEF71E223A40F18B586FA813ED2EC4453A8C15B3531DC651AAFA6136D5BA894B22FA94E96D6034E9A569F4D3366B323D656B5C480D0FC443BA5597B42071CB28466F084FA31856AEAB54268E7DF559C47D0F53F7584273FD41C9C59C130E9E43B0E5664B1FFAE5D3608EBFCDCA6E257B0AED1E270938A03C7494B16E725389F8106CFA4746BD350EFD6688AF36BA679CF2437E25C0335A4C7E51AD3043938D7D49EAD349D50B153346687EC29B70982760D6280C1B92F58AEFC66BAB600A905A40B720A8E75CC1C1D96557F1988FF927ED6C2C614357242CB03E314B19766B1C7D70575A1607B25C6E90F2412DE7D3F140B3B6CD743FEE66DD2F32B35F34C1C4F1523B03F9E68E873FB7697D0D09D387B8E4BA6FF9EE302A8B6D4BEBA2659E8933B8A411BEE451870CA8F388C96C0D1A59F2BCB29CBD5FFDCA855A7A9720E7BCA71037B417D9D54EFED70FB695EB8E3461262884DADE4C7E2F9ED544D650CB9853F1AEE8C48FD285F8C806823065A238AD70A99C832C815970C33E8326ECC759378A603C77D20248DFAAD6AC718D5F04AF2635061C904159E1EB37873B383C7A244C81F58A22553B1DC1A74AFB44B44A5AEA3B096DEB8B6FEFA7778ACBE1B1EF0331B2667611340085C51D092DD6AC47814A4D68384007F87EA2EF20E005ED221855CCF2B67FF58CAA28E40CD9C44586CB054670C2B0EF0E6B73852B5B475409BDD6A6042345630EB1A675F51A13F7453936B72FDACC671D863DEFE781698B6AE6CE15FB6936A27A9D5EE7442380812B8EB4FB525A518239E138112E6BCA6FEA3FB27B30E28F6D3084D8B5E01F20C7D3FD7EEF3E3EB55F392717BCA9CA76900EBADB7AEA8A26F704C8417708D51374E98D61E0D649BFCC0957FB0636762453C8D1CE08B95FB90BB5EFF6A50210679E167C1E0B67AEDC6E7000C1C4AA5509F8F81D679855BD6CF8FE556FADACE0E45F1C1387DD1A14BBC8A3097DC11C7E40E5A31BCE2188D99008BC3163D04D03ABFB8AA3F17DCFADF8A26F4F275886B1C3DE598068054BB5D8D1B4CB5BCA9E6E822377AA7625490BD4735DDB2B4558D677C1DC2AF39CD9C67242D1C41FF3109FBA72C9C22E362310A905738BF8CEB12697EA0A0885BE11AE0A44DD1FE5F6F863AA8740BAD7300FE1FE72062D3C1669CA796B541637141925DE49515D497F669A695C2735489B58A6E48FF5D6E884D262E5EE95F1EDF49DF55485891DE9B7F5B1E73AD0953C021E4E58D3B7001B702EB6A030E81DC6DB9265290FC224695CAB521CCA0449069CBF358949B03FD67DD1EC41B
-20220419133200 2 6 100 8191 2 CF0A168167DAB1FDFD5C0376DC6E2C93907F486EF5576F14B83FAD667FCC774D179D9A0CB69771C381E7A3AC0F7561E06C8BFD155A9B527EE6F015BDFF6DAE1556CEB985BAAA83E40720B4D91830DDA2BC4BE8C137AB7EB0107D3E04DB39A092C84AEF71E223A40F18B586FA813ED2EC4453A8C15B3531DC651AAFA6136D5BA894B22FA94E96D6034E9A569F4D3366B323D656B5C480D0FC443BA5597B42071CB28466F084FA31856AEAB54268E7DF559C47D0F53F7584273FD41C9C59C130E9E43B0E5664B1FFAE5D3608EBFCDCA6E257B0AED1E270938A03C7494B16E725389F8106CFA4746BD350EFD6688AF36BA679CF2437E25C0335A4C7E51AD3043938D7D49EAD349D50B153346687EC29B70982760D6280C1B92F58AEFC66BAB600A905A40B720A8E75CC1C1D96557F1988FF927ED6C2C614357242CB03E314B19766B1C7D70575A1607B25C6E90F2412DE7D3F140B3B6CD743FEE66DD2F32B35F34C1C4F1523B03F9E68E873FB7697D0D09D387B8E4BA6FF9EE302A8B6D4BEBA2659E8933B8A411BEE451870CA8F388C96C0D1A59F2BCB29CBD5FFDCA855A7A9720E7BCA71037B417D9D54EFED70FB695EB8E3461262884DADE4C7E2F9ED544D650CB9853F1AEE8C48FD285F8C806823065A238AD70A99C832C815970C33E8326ECC759378A603C77D20248DFAAD6AC718D5F04AF2635061C904159E1EB37873B383C7A244C81F58A22553B1DC1A74AFB44B44A5AEA3B096DEB8B6FEFA7778ACBE1B1EF0331B2667611340085C51D092DD6AC47814A4D68384007F87EA2EF20E005ED221855CCF2B67FF58CAA28E40CD9C44586CB054670C2B0EF0E6B73852B5B475409BDD6A6042345630EB1A675F51A13F7453936B72FDACC671D863DEFE781698B6AE6CE15FB6936A27A9D5EE7442380812B8EB4FB525A518239E138112E6BCA6FEA3FB27B30E28F6D3084D8B5E01F20C7D3FD7EEF3E3EB55F392717BCA9CA76900EBADB7AEA8A26F704C8417708D51374E98D61E0D649BFCC0957FB0636762453C8D1CE08B95FB90BB5EFF6A50210679E167C1E0B67AEDC6E7000C1C4AA5509F8F81D679855BD6CF8FE556FADACE0E45F1C1387DD1A14BBC8A3097DC11C7E40E5A31BCE2188D99008BC3163D04D03ABFB8AA3F17DCFADF8A26F4F275886B1C3DE598068054BB5D8D1B4CB5BCA9E6E822377AA7625490BD4735DDB2B4558D677C1DC2AF39CD9C67242D1C41FF3109FBA72C9C22E362310A905738BF8CEB12697EA0A0885BE11AE0A44DD1FE5F6F863AA8740BAD7300FE1FE72062D3C1669CA796B541637141925DE49515D497F669A695C2735489B58A6E48FF5D6E884D262E5EE95F1EDF49DF55485891DE9B7F5B1E73AD0953C021E4E58D3B7001B702EB6A030E81DC6DB9265290FC224695CAB521CCA0449069CBF358949B03FD67DFE53A7B
-20220419144722 2 6 100 8191 5 CF0A168167DAB1FDFD5C0376DC6E2C93907F486EF5576F14B83FAD667FCC774D179D9A0CB69771C381E7A3AC0F7561E06C8BFD155A9B527EE6F015BDFF6DAE1556CEB985BAAA83E40720B4D91830DDA2BC4BE8C137AB7EB0107D3E04DB39A092C84AEF71E223A40F18B586FA813ED2EC4453A8C15B3531DC651AAFA6136D5BA894B22FA94E96D6034E9A569F4D3366B323D656B5C480D0FC443BA5597B42071CB28466F084FA31856AEAB54268E7DF559C47D0F53F7584273FD41C9C59C130E9E43B0E5664B1FFAE5D3608EBFCDCA6E257B0AED1E270938A03C7494B16E725389F8106CFA4746BD350EFD6688AF36BA679CF2437E25C0335A4C7E51AD3043938D7D49EAD349D50B153346687EC29B70982760D6280C1B92F58AEFC66BAB600A905A40B720A8E75CC1C1D96557F1988FF927ED6C2C614357242CB03E314B19766B1C7D70575A1607B25C6E90F2412DE7D3F140B3B6CD743FEE66DD2F32B35F34C1C4F1523B03F9E68E873FB7697D0D09D387B8E4BA6FF9EE302A8B6D4BEBA2659E8933B8A411BEE451870CA8F388C96C0D1A59F2BCB29CBD5FFDCA855A7A9720E7BCA71037B417D9D54EFED70FB695EB8E3461262884DADE4C7E2F9ED544D650CB9853F1AEE8C48FD285F8C806823065A238AD70A99C832C815970C33E8326ECC759378A603C77D20248DFAAD6AC718D5F04AF2635061C904159E1EB37873B383C7A244C81F58A22553B1DC1A74AFB44B44A5AEA3B096DEB8B6FEFA7778ACBE1B1EF0331B2667611340085C51D092DD6AC47814A4D68384007F87EA2EF20E005ED221855CCF2B67FF58CAA28E40CD9C44586CB054670C2B0EF0E6B73852B5B475409BDD6A6042345630EB1A675F51A13F7453936B72FDACC671D863DEFE781698B6AE6CE15FB6936A27A9D5EE7442380812B8EB4FB525A518239E138112E6BCA6FEA3FB27B30E28F6D3084D8B5E01F20C7D3FD7EEF3E3EB55F392717BCA9CA76900EBADB7AEA8A26F704C8417708D51374E98D61E0D649BFCC0957FB0636762453C8D1CE08B95FB90BB5EFF6A50210679E167C1E0B67AEDC6E7000C1C4AA5509F8F81D679855BD6CF8FE556FADACE0E45F1C1387DD1A14BBC8A3097DC11C7E40E5A31BCE2188D99008BC3163D04D03ABFB8AA3F17DCFADF8A26F4F275886B1C3DE598068054BB5D8D1B4CB5BCA9E6E822377AA7625490BD4735DDB2B4558D677C1DC2AF39CD9C67242D1C41FF3109FBA72C9C22E362310A905738BF8CEB12697EA0A0885BE11AE0A44DD1FE5F6F863AA8740BAD7300FE1FE72062D3C1669CA796B541637141925DE49515D497F669A695C2735489B58A6E48FF5D6E884D262E5EE95F1EDF49DF55485891DE9B7F5B1E73AD0953C021E4E58D3B7001B702EB6A030E81DC6DB9265290FC224695CAB521CCA0449069CBF358949B03FD67E49063CF
-20220419152308 2 6 100 8191 5 CF0A168167DAB1FDFD5C0376DC6E2C93907F486EF5576F14B83FAD667FCC774D179D9A0CB69771C381E7A3AC0F7561E06C8BFD155A9B527EE6F015BDFF6DAE1556CEB985BAAA83E40720B4D91830DDA2BC4BE8C137AB7EB0107D3E04DB39A092C84AEF71E223A40F18B586FA813ED2EC4453A8C15B3531DC651AAFA6136D5BA894B22FA94E96D6034E9A569F4D3366B323D656B5C480D0FC443BA5597B42071CB28466F084FA31856AEAB54268E7DF559C47D0F53F7584273FD41C9C59C130E9E43B0E5664B1FFAE5D3608EBFCDCA6E257B0AED1E270938A03C7494B16E725389F8106CFA4746BD350EFD6688AF36BA679CF2437E25C0335A4C7E51AD3043938D7D49EAD349D50B153346687EC29B70982760D6280C1B92F58AEFC66BAB600A905A40B720A8E75CC1C1D96557F1988FF927ED6C2C614357242CB03E314B19766B1C7D70575A1607B25C6E90F2412DE7D3F140B3B6CD743FEE66DD2F32B35F34C1C4F1523B03F9E68E873FB7697D0D09D387B8E4BA6FF9EE302A8B6D4BEBA2659E8933B8A411BEE451870CA8F388C96C0D1A59F2BCB29CBD5FFDCA855A7A9720E7BCA71037B417D9D54EFED70FB695EB8E3461262884DADE4C7E2F9ED544D650CB9853F1AEE8C48FD285F8C806823065A238AD70A99C832C815970C33E8326ECC759378A603C77D20248DFAAD6AC718D5F04AF2635061C904159E1EB37873B383C7A244C81F58A22553B1DC1A74AFB44B44A5AEA3B096DEB8B6FEFA7778ACBE1B1EF0331B2667611340085C51D092DD6AC47814A4D68384007F87EA2EF20E005ED221855CCF2B67FF58CAA28E40CD9C44586CB054670C2B0EF0E6B73852B5B475409BDD6A6042345630EB1A675F51A13F7453936B72FDACC671D863DEFE781698B6AE6CE15FB6936A27A9D5EE7442380812B8EB4FB525A518239E138112E6BCA6FEA3FB27B30E28F6D3084D8B5E01F20C7D3FD7EEF3E3EB55F392717BCA9CA76900EBADB7AEA8A26F704C8417708D51374E98D61E0D649BFCC0957FB0636762453C8D1CE08B95FB90BB5EFF6A50210679E167C1E0B67AEDC6E7000C1C4AA5509F8F81D679855BD6CF8FE556FADACE0E45F1C1387DD1A14BBC8A3097DC11C7E40E5A31BCE2188D99008BC3163D04D03ABFB8AA3F17DCFADF8A26F4F275886B1C3DE598068054BB5D8D1B4CB5BCA9E6E822377AA7625490BD4735DDB2B4558D677C1DC2AF39CD9C67242D1C41FF3109FBA72C9C22E362310A905738BF8CEB12697EA0A0885BE11AE0A44DD1FE5F6F863AA8740BAD7300FE1FE72062D3C1669CA796B541637141925DE49515D497F669A695C2735489B58A6E48FF5D6E884D262E5EE95F1EDF49DF55485891DE9B7F5B1E73AD0953C021E4E58D3B7001B702EB6A030E81DC6DB9265290FC224695CAB521CCA0449069CBF358949B03FD67E6C7E127
-20220419161040 2 6 100 8191 2 CF0A168167DAB1FDFD5C0376DC6E2C93907F486EF5576F14B83FAD667FCC774D179D9A0CB69771C381E7A3AC0F7561E06C8BFD155A9B527EE6F015BDFF6DAE1556CEB985BAAA83E40720B4D91830DDA2BC4BE8C137AB7EB0107D3E04DB39A092C84AEF71E223A40F18B586FA813ED2EC4453A8C15B3531DC651AAFA6136D5BA894B22FA94E96D6034E9A569F4D3366B323D656B5C480D0FC443BA5597B42071CB28466F084FA31856AEAB54268E7DF559C47D0F53F7584273FD41C9C59C130E9E43B0E5664B1FFAE5D3608EBFCDCA6E257B0AED1E270938A03C7494B16E725389F8106CFA4746BD350EFD6688AF36BA679CF2437E25C0335A4C7E51AD3043938D7D49EAD349D50B153346687EC29B70982760D6280C1B92F58AEFC66BAB600A905A40B720A8E75CC1C1D96557F1988FF927ED6C2C614357242CB03E314B19766B1C7D70575A1607B25C6E90F2412DE7D3F140B3B6CD743FEE66DD2F32B35F34C1C4F1523B03F9E68E873FB7697D0D09D387B8E4BA6FF9EE302A8B6D4BEBA2659E8933B8A411BEE451870CA8F388C96C0D1A59F2BCB29CBD5FFDCA855A7A9720E7BCA71037B417D9D54EFED70FB695EB8E3461262884DADE4C7E2F9ED544D650CB9853F1AEE8C48FD285F8C806823065A238AD70A99C832C815970C33E8326ECC759378A603C77D20248DFAAD6AC718D5F04AF2635061C904159E1EB37873B383C7A244C81F58A22553B1DC1A74AFB44B44A5AEA3B096DEB8B6FEFA7778ACBE1B1EF0331B2667611340085C51D092DD6AC47814A4D68384007F87EA2EF20E005ED221855CCF2B67FF58CAA28E40CD9C44586CB054670C2B0EF0E6B73852B5B475409BDD6A6042345630EB1A675F51A13F7453936B72FDACC671D863DEFE781698B6AE6CE15FB6936A27A9D5EE7442380812B8EB4FB525A518239E138112E6BCA6FEA3FB27B30E28F6D3084D8B5E01F20C7D3FD7EEF3E3EB55F392717BCA9CA76900EBADB7AEA8A26F704C8417708D51374E98D61E0D649BFCC0957FB0636762453C8D1CE08B95FB90BB5EFF6A50210679E167C1E0B67AEDC6E7000C1C4AA5509F8F81D679855BD6CF8FE556FADACE0E45F1C1387DD1A14BBC8A3097DC11C7E40E5A31BCE2188D99008BC3163D04D03ABFB8AA3F17DCFADF8A26F4F275886B1C3DE598068054BB5D8D1B4CB5BCA9E6E822377AA7625490BD4735DDB2B4558D677C1DC2AF39CD9C67242D1C41FF3109FBA72C9C22E362310A905738BF8CEB12697EA0A0885BE11AE0A44DD1FE5F6F863AA8740BAD7300FE1FE72062D3C1669CA796B541637141925DE49515D497F669A695C2735489B58A6E48FF5D6E884D262E5EE95F1EDF49DF55485891DE9B7F5B1E73AD0953C021E4E58D3B7001B702EB6A030E81DC6DB9265290FC224695CAB521CCA0449069CBF358949B03FD67E9B7FA1B
-20220419172345 2 6 100 8191 5 CF0A168167DAB1FDFD5C0376DC6E2C93907F486EF5576F14B83FAD667FCC774D179D9A0CB69771C381E7A3AC0F7561E06C8BFD155A9B527EE6F015BDFF6DAE1556CEB985BAAA83E40720B4D91830DDA2BC4BE8C137AB7EB0107D3E04DB39A092C84AEF71E223A40F18B586FA813ED2EC4453A8C15B3531DC651AAFA6136D5BA894B22FA94E96D6034E9A569F4D3366B323D656B5C480D0FC443BA5597B42071CB28466F084FA31856AEAB54268E7DF559C47D0F53F7584273FD41C9C59C130E9E43B0E5664B1FFAE5D3608EBFCDCA6E257B0AED1E270938A03C7494B16E725389F8106CFA4746BD350EFD6688AF36BA679CF2437E25C0335A4C7E51AD3043938D7D49EAD349D50B153346687EC29B70982760D6280C1B92F58AEFC66BAB600A905A40B720A8E75CC1C1D96557F1988FF927ED6C2C614357242CB03E314B19766B1C7D70575A1607B25C6E90F2412DE7D3F140B3B6CD743FEE66DD2F32B35F34C1C4F1523B03F9E68E873FB7697D0D09D387B8E4BA6FF9EE302A8B6D4BEBA2659E8933B8A411BEE451870CA8F388C96C0D1A59F2BCB29CBD5FFDCA855A7A9720E7BCA71037B417D9D54EFED70FB695EB8E3461262884DADE4C7E2F9ED544D650CB9853F1AEE8C48FD285F8C806823065A238AD70A99C832C815970C33E8326ECC759378A603C77D20248DFAAD6AC718D5F04AF2635061C904159E1EB37873B383C7A244C81F58A22553B1DC1A74AFB44B44A5AEA3B096DEB8B6FEFA7778ACBE1B1EF0331B2667611340085C51D092DD6AC47814A4D68384007F87EA2EF20E005ED221855CCF2B67FF58CAA28E40CD9C44586CB054670C2B0EF0E6B73852B5B475409BDD6A6042345630EB1A675F51A13F7453936B72FDACC671D863DEFE781698B6AE6CE15FB6936A27A9D5EE7442380812B8EB4FB525A518239E138112E6BCA6FEA3FB27B30E28F6D3084D8B5E01F20C7D3FD7EEF3E3EB55F392717BCA9CA76900EBADB7AEA8A26F704C8417708D51374E98D61E0D649BFCC0957FB0636762453C8D1CE08B95FB90BB5EFF6A50210679E167C1E0B67AEDC6E7000C1C4AA5509F8F81D679855BD6CF8FE556FADACE0E45F1C1387DD1A14BBC8A3097DC11C7E40E5A31BCE2188D99008BC3163D04D03ABFB8AA3F17DCFADF8A26F4F275886B1C3DE598068054BB5D8D1B4CB5BCA9E6E822377AA7625490BD4735DDB2B4558D677C1DC2AF39CD9C67242D1C41FF3109FBA72C9C22E362310A905738BF8CEB12697EA0A0885BE11AE0A44DD1FE5F6F863AA8740BAD7300FE1FE72062D3C1669CA796B541637141925DE49515D497F669A695C2735489B58A6E48FF5D6E884D262E5EE95F1EDF49DF55485891DE9B7F5B1E73AD0953C021E4E58D3B7001B702EB6A030E81DC6DB9265290FC224695CAB521CCA0449069CBF358949B03FD67EE2EB17F
-20220419184212 2 6 100 8191 2 CF0A168167DAB1FDFD5C0376DC6E2C93907F486EF5576F14B83FAD667FCC774D179D9A0CB69771C381E7A3AC0F7561E06C8BFD155A9B527EE6F015BDFF6DAE1556CEB985BAAA83E40720B4D91830DDA2BC4BE8C137AB7EB0107D3E04DB39A092C84AEF71E223A40F18B586FA813ED2EC4453A8C15B3531DC651AAFA6136D5BA894B22FA94E96D6034E9A569F4D3366B323D656B5C480D0FC443BA5597B42071CB28466F084FA31856AEAB54268E7DF559C47D0F53F7584273FD41C9C59C130E9E43B0E5664B1FFAE5D3608EBFCDCA6E257B0AED1E270938A03C7494B16E725389F8106CFA4746BD350EFD6688AF36BA679CF2437E25C0335A4C7E51AD3043938D7D49EAD349D50B153346687EC29B70982760D6280C1B92F58AEFC66BAB600A905A40B720A8E75CC1C1D96557F1988FF927ED6C2C614357242CB03E314B19766B1C7D70575A1607B25C6E90F2412DE7D3F140B3B6CD743FEE66DD2F32B35F34C1C4F1523B03F9E68E873FB7697D0D09D387B8E4BA6FF9EE302A8B6D4BEBA2659E8933B8A411BEE451870CA8F388C96C0D1A59F2BCB29CBD5FFDCA855A7A9720E7BCA71037B417D9D54EFED70FB695EB8E3461262884DADE4C7E2F9ED544D650CB9853F1AEE8C48FD285F8C806823065A238AD70A99C832C815970C33E8326ECC759378A603C77D20248DFAAD6AC718D5F04AF2635061C904159E1EB37873B383C7A244C81F58A22553B1DC1A74AFB44B44A5AEA3B096DEB8B6FEFA7778ACBE1B1EF0331B2667611340085C51D092DD6AC47814A4D68384007F87EA2EF20E005ED221855CCF2B67FF58CAA28E40CD9C44586CB054670C2B0EF0E6B73852B5B475409BDD6A6042345630EB1A675F51A13F7453936B72FDACC671D863DEFE781698B6AE6CE15FB6936A27A9D5EE7442380812B8EB4FB525A518239E138112E6BCA6FEA3FB27B30E28F6D3084D8B5E01F20C7D3FD7EEF3E3EB55F392717BCA9CA76900EBADB7AEA8A26F704C8417708D51374E98D61E0D649BFCC0957FB0636762453C8D1CE08B95FB90BB5EFF6A50210679E167C1E0B67AEDC6E7000C1C4AA5509F8F81D679855BD6CF8FE556FADACE0E45F1C1387DD1A14BBC8A3097DC11C7E40E5A31BCE2188D99008BC3163D04D03ABFB8AA3F17DCFADF8A26F4F275886B1C3DE598068054BB5D8D1B4CB5BCA9E6E822377AA7625490BD4735DDB2B4558D677C1DC2AF39CD9C67242D1C41FF3109FBA72C9C22E362310A905738BF8CEB12697EA0A0885BE11AE0A44DD1FE5F6F863AA8740BAD7300FE1FE72062D3C1669CA796B541637141925DE49515D497F669A695C2735489B58A6E48FF5D6E884D262E5EE95F1EDF49DF55485891DE9B7F5B1E73AD0953C021E4E58D3B7001B702EB6A030E81DC6DB9265290FC224695CAB521CCA0449069CBF358949B03FD67F2FFC2FB
-20220419184630 2 6 100 8191 5 CF0A168167DAB1FDFD5C0376DC6E2C93907F486EF5576F14B83FAD667FCC774D179D9A0CB69771C381E7A3AC0F7561E06C8BFD155A9B527EE6F015BDFF6DAE1556CEB985BAAA83E40720B4D91830DDA2BC4BE8C137AB7EB0107D3E04DB39A092C84AEF71E223A40F18B586FA813ED2EC4453A8C15B3531DC651AAFA6136D5BA894B22FA94E96D6034E9A569F4D3366B323D656B5C480D0FC443BA5597B42071CB28466F084FA31856AEAB54268E7DF559C47D0F53F7584273FD41C9C59C130E9E43B0E5664B1FFAE5D3608EBFCDCA6E257B0AED1E270938A03C7494B16E725389F8106CFA4746BD350EFD6688AF36BA679CF2437E25C0335A4C7E51AD3043938D7D49EAD349D50B153346687EC29B70982760D6280C1B92F58AEFC66BAB600A905A40B720A8E75CC1C1D96557F1988FF927ED6C2C614357242CB03E314B19766B1C7D70575A1607B25C6E90F2412DE7D3F140B3B6CD743FEE66DD2F32B35F34C1C4F1523B03F9E68E873FB7697D0D09D387B8E4BA6FF9EE302A8B6D4BEBA2659E8933B8A411BEE451870CA8F388C96C0D1A59F2BCB29CBD5FFDCA855A7A9720E7BCA71037B417D9D54EFED70FB695EB8E3461262884DADE4C7E2F9ED544D650CB9853F1AEE8C48FD285F8C806823065A238AD70A99C832C815970C33E8326ECC759378A603C77D20248DFAAD6AC718D5F04AF2635061C904159E1EB37873B383C7A244C81F58A22553B1DC1A74AFB44B44A5AEA3B096DEB8B6FEFA7778ACBE1B1EF0331B2667611340085C51D092DD6AC47814A4D68384007F87EA2EF20E005ED221855CCF2B67FF58CAA28E40CD9C44586CB054670C2B0EF0E6B73852B5B475409BDD6A6042345630EB1A675F51A13F7453936B72FDACC671D863DEFE781698B6AE6CE15FB6936A27A9D5EE7442380812B8EB4FB525A518239E138112E6BCA6FEA3FB27B30E28F6D3084D8B5E01F20C7D3FD7EEF3E3EB55F392717BCA9CA76900EBADB7AEA8A26F704C8417708D51374E98D61E0D649BFCC0957FB0636762453C8D1CE08B95FB90BB5EFF6A50210679E167C1E0B67AEDC6E7000C1C4AA5509F8F81D679855BD6CF8FE556FADACE0E45F1C1387DD1A14BBC8A3097DC11C7E40E5A31BCE2188D99008BC3163D04D03ABFB8AA3F17DCFADF8A26F4F275886B1C3DE598068054BB5D8D1B4CB5BCA9E6E822377AA7625490BD4735DDB2B4558D677C1DC2AF39CD9C67242D1C41FF3109FBA72C9C22E362310A905738BF8CEB12697EA0A0885BE11AE0A44DD1FE5F6F863AA8740BAD7300FE1FE72062D3C1669CA796B541637141925DE49515D497F669A695C2735489B58A6E48FF5D6E884D262E5EE95F1EDF49DF55485891DE9B7F5B1E73AD0953C021E4E58D3B7001B702EB6A030E81DC6DB9265290FC224695CAB521CCA0449069CBF358949B03FD67F3381C0F
-20220419193320 2 6 100 8191 5 CF0A168167DAB1FDFD5C0376DC6E2C93907F486EF5576F14B83FAD667FCC774D179D9A0CB69771C381E7A3AC0F7561E06C8BFD155A9B527EE6F015BDFF6DAE1556CEB985BAAA83E40720B4D91830DDA2BC4BE8C137AB7EB0107D3E04DB39A092C84AEF71E223A40F18B586FA813ED2EC4453A8C15B3531DC651AAFA6136D5BA894B22FA94E96D6034E9A569F4D3366B323D656B5C480D0FC443BA5597B42071CB28466F084FA31856AEAB54268E7DF559C47D0F53F7584273FD41C9C59C130E9E43B0E5664B1FFAE5D3608EBFCDCA6E257B0AED1E270938A03C7494B16E725389F8106CFA4746BD350EFD6688AF36BA679CF2437E25C0335A4C7E51AD3043938D7D49EAD349D50B153346687EC29B70982760D6280C1B92F58AEFC66BAB600A905A40B720A8E75CC1C1D96557F1988FF927ED6C2C614357242CB03E314B19766B1C7D70575A1607B25C6E90F2412DE7D3F140B3B6CD743FEE66DD2F32B35F34C1C4F1523B03F9E68E873FB7697D0D09D387B8E4BA6FF9EE302A8B6D4BEBA2659E8933B8A411BEE451870CA8F388C96C0D1A59F2BCB29CBD5FFDCA855A7A9720E7BCA71037B417D9D54EFED70FB695EB8E3461262884DADE4C7E2F9ED544D650CB9853F1AEE8C48FD285F8C806823065A238AD70A99C832C815970C33E8326ECC759378A603C77D20248DFAAD6AC718D5F04AF2635061C904159E1EB37873B383C7A244C81F58A22553B1DC1A74AFB44B44A5AEA3B096DEB8B6FEFA7778ACBE1B1EF0331B2667611340085C51D092DD6AC47814A4D68384007F87EA2EF20E005ED221855CCF2B67FF58CAA28E40CD9C44586CB054670C2B0EF0E6B73852B5B475409BDD6A6042345630EB1A675F51A13F7453936B72FDACC671D863DEFE781698B6AE6CE15FB6936A27A9D5EE7442380812B8EB4FB525A518239E138112E6BCA6FEA3FB27B30E28F6D3084D8B5E01F20C7D3FD7EEF3E3EB55F392717BCA9CA76900EBADB7AEA8A26F704C8417708D51374E98D61E0D649BFCC0957FB0636762453C8D1CE08B95FB90BB5EFF6A50210679E167C1E0B67AEDC6E7000C1C4AA5509F8F81D679855BD6CF8FE556FADACE0E45F1C1387DD1A14BBC8A3097DC11C7E40E5A31BCE2188D99008BC3163D04D03ABFB8AA3F17DCFADF8A26F4F275886B1C3DE598068054BB5D8D1B4CB5BCA9E6E822377AA7625490BD4735DDB2B4558D677C1DC2AF39CD9C67242D1C41FF3109FBA72C9C22E362310A905738BF8CEB12697EA0A0885BE11AE0A44DD1FE5F6F863AA8740BAD7300FE1FE72062D3C1669CA796B541637141925DE49515D497F669A695C2735489B58A6E48FF5D6E884D262E5EE95F1EDF49DF55485891DE9B7F5B1E73AD0953C021E4E58D3B7001B702EB6A030E81DC6DB9265290FC224695CAB521CCA0449069CBF358949B03FD67F608FFDF
-20220419193640 2 6 100 8191 2 CF0A168167DAB1FDFD5C0376DC6E2C93907F486EF5576F14B83FAD667FCC774D179D9A0CB69771C381E7A3AC0F7561E06C8BFD155A9B527EE6F015BDFF6DAE1556CEB985BAAA83E40720B4D91830DDA2BC4BE8C137AB7EB0107D3E04DB39A092C84AEF71E223A40F18B586FA813ED2EC4453A8C15B3531DC651AAFA6136D5BA894B22FA94E96D6034E9A569F4D3366B323D656B5C480D0FC443BA5597B42071CB28466F084FA31856AEAB54268E7DF559C47D0F53F7584273FD41C9C59C130E9E43B0E5664B1FFAE5D3608EBFCDCA6E257B0AED1E270938A03C7494B16E725389F8106CFA4746BD350EFD6688AF36BA679CF2437E25C0335A4C7E51AD3043938D7D49EAD349D50B153346687EC29B70982760D6280C1B92F58AEFC66BAB600A905A40B720A8E75CC1C1D96557F1988FF927ED6C2C614357242CB03E314B19766B1C7D70575A1607B25C6E90F2412DE7D3F140B3B6CD743FEE66DD2F32B35F34C1C4F1523B03F9E68E873FB7697D0D09D387B8E4BA6FF9EE302A8B6D4BEBA2659E8933B8A411BEE451870CA8F388C96C0D1A59F2BCB29CBD5FFDCA855A7A9720E7BCA71037B417D9D54EFED70FB695EB8E3461262884DADE4C7E2F9ED544D650CB9853F1AEE8C48FD285F8C806823065A238AD70A99C832C815970C33E8326ECC759378A603C77D20248DFAAD6AC718D5F04AF2635061C904159E1EB37873B383C7A244C81F58A22553B1DC1A74AFB44B44A5AEA3B096DEB8B6FEFA7778ACBE1B1EF0331B2667611340085C51D092DD6AC47814A4D68384007F87EA2EF20E005ED221855CCF2B67FF58CAA28E40CD9C44586CB054670C2B0EF0E6B73852B5B475409BDD6A6042345630EB1A675F51A13F7453936B72FDACC671D863DEFE781698B6AE6CE15FB6936A27A9D5EE7442380812B8EB4FB525A518239E138112E6BCA6FEA3FB27B30E28F6D3084D8B5E01F20C7D3FD7EEF3E3EB55F392717BCA9CA76900EBADB7AEA8A26F704C8417708D51374E98D61E0D649BFCC0957FB0636762453C8D1CE08B95FB90BB5EFF6A50210679E167C1E0B67AEDC6E7000C1C4AA5509F8F81D679855BD6CF8FE556FADACE0E45F1C1387DD1A14BBC8A3097DC11C7E40E5A31BCE2188D99008BC3163D04D03ABFB8AA3F17DCFADF8A26F4F275886B1C3DE598068054BB5D8D1B4CB5BCA9E6E822377AA7625490BD4735DDB2B4558D677C1DC2AF39CD9C67242D1C41FF3109FBA72C9C22E362310A905738BF8CEB12697EA0A0885BE11AE0A44DD1FE5F6F863AA8740BAD7300FE1FE72062D3C1669CA796B541637141925DE49515D497F669A695C2735489B58A6E48FF5D6E884D262E5EE95F1EDF49DF55485891DE9B7F5B1E73AD0953C021E4E58D3B7001B702EB6A030E81DC6DB9265290FC224695CAB521CCA0449069CBF358949B03FD67F634CE4B
-20220419204750 2 6 100 8191 2 CF0A168167DAB1FDFD5C0376DC6E2C93907F486EF5576F14B83FAD667FCC774D179D9A0CB69771C381E7A3AC0F7561E06C8BFD155A9B527EE6F015BDFF6DAE1556CEB985BAAA83E40720B4D91830DDA2BC4BE8C137AB7EB0107D3E04DB39A092C84AEF71E223A40F18B586FA813ED2EC4453A8C15B3531DC651AAFA6136D5BA894B22FA94E96D6034E9A569F4D3366B323D656B5C480D0FC443BA5597B42071CB28466F084FA31856AEAB54268E7DF559C47D0F53F7584273FD41C9C59C130E9E43B0E5664B1FFAE5D3608EBFCDCA6E257B0AED1E270938A03C7494B16E725389F8106CFA4746BD350EFD6688AF36BA679CF2437E25C0335A4C7E51AD3043938D7D49EAD349D50B153346687EC29B70982760D6280C1B92F58AEFC66BAB600A905A40B720A8E75CC1C1D96557F1988FF927ED6C2C614357242CB03E314B19766B1C7D70575A1607B25C6E90F2412DE7D3F140B3B6CD743FEE66DD2F32B35F34C1C4F1523B03F9E68E873FB7697D0D09D387B8E4BA6FF9EE302A8B6D4BEBA2659E8933B8A411BEE451870CA8F388C96C0D1A59F2BCB29CBD5FFDCA855A7A9720E7BCA71037B417D9D54EFED70FB695EB8E3461262884DADE4C7E2F9ED544D650CB9853F1AEE8C48FD285F8C806823065A238AD70A99C832C815970C33E8326ECC759378A603C77D20248DFAAD6AC718D5F04AF2635061C904159E1EB37873B383C7A244C81F58A22553B1DC1A74AFB44B44A5AEA3B096DEB8B6FEFA7778ACBE1B1EF0331B2667611340085C51D092DD6AC47814A4D68384007F87EA2EF20E005ED221855CCF2B67FF58CAA28E40CD9C44586CB054670C2B0EF0E6B73852B5B475409BDD6A6042345630EB1A675F51A13F7453936B72FDACC671D863DEFE781698B6AE6CE15FB6936A27A9D5EE7442380812B8EB4FB525A518239E138112E6BCA6FEA3FB27B30E28F6D3084D8B5E01F20C7D3FD7EEF3E3EB55F392717BCA9CA76900EBADB7AEA8A26F704C8417708D51374E98D61E0D649BFCC0957FB0636762453C8D1CE08B95FB90BB5EFF6A50210679E167C1E0B67AEDC6E7000C1C4AA5509F8F81D679855BD6CF8FE556FADACE0E45F1C1387DD1A14BBC8A3097DC11C7E40E5A31BCE2188D99008BC3163D04D03ABFB8AA3F17DCFADF8A26F4F275886B1C3DE598068054BB5D8D1B4CB5BCA9E6E822377AA7625490BD4735DDB2B4558D677C1DC2AF39CD9C67242D1C41FF3109FBA72C9C22E362310A905738BF8CEB12697EA0A0885BE11AE0A44DD1FE5F6F863AA8740BAD7300FE1FE72062D3C1669CA796B541637141925DE49515D497F669A695C2735489B58A6E48FF5D6E884D262E5EE95F1EDF49DF55485891DE9B7F5B1E73AD0953C021E4E58D3B7001B702EB6A030E81DC6DB9265290FC224695CAB521CCA0449069CBF358949B03FD67FA7B8963
-20220419205514 2 6 100 8191 2 CF0A168167DAB1FDFD5C0376DC6E2C93907F486EF5576F14B83FAD667FCC774D179D9A0CB69771C381E7A3AC0F7561E06C8BFD155A9B527EE6F015BDFF6DAE1556CEB985BAAA83E40720B4D91830DDA2BC4BE8C137AB7EB0107D3E04DB39A092C84AEF71E223A40F18B586FA813ED2EC4453A8C15B3531DC651AAFA6136D5BA894B22FA94E96D6034E9A569F4D3366B323D656B5C480D0FC443BA5597B42071CB28466F084FA31856AEAB54268E7DF559C47D0F53F7584273FD41C9C59C130E9E43B0E5664B1FFAE5D3608EBFCDCA6E257B0AED1E270938A03C7494B16E725389F8106CFA4746BD350EFD6688AF36BA679CF2437E25C0335A4C7E51AD3043938D7D49EAD349D50B153346687EC29B70982760D6280C1B92F58AEFC66BAB600A905A40B720A8E75CC1C1D96557F1988FF927ED6C2C614357242CB03E314B19766B1C7D70575A1607B25C6E90F2412DE7D3F140B3B6CD743FEE66DD2F32B35F34C1C4F1523B03F9E68E873FB7697D0D09D387B8E4BA6FF9EE302A8B6D4BEBA2659E8933B8A411BEE451870CA8F388C96C0D1A59F2BCB29CBD5FFDCA855A7A9720E7BCA71037B417D9D54EFED70FB695EB8E3461262884DADE4C7E2F9ED544D650CB9853F1AEE8C48FD285F8C806823065A238AD70A99C832C815970C33E8326ECC759378A603C77D20248DFAAD6AC718D5F04AF2635061C904159E1EB37873B383C7A244C81F58A22553B1DC1A74AFB44B44A5AEA3B096DEB8B6FEFA7778ACBE1B1EF0331B2667611340085C51D092DD6AC47814A4D68384007F87EA2EF20E005ED221855CCF2B67FF58CAA28E40CD9C44586CB054670C2B0EF0E6B73852B5B475409BDD6A6042345630EB1A675F51A13F7453936B72FDACC671D863DEFE781698B6AE6CE15FB6936A27A9D5EE7442380812B8EB4FB525A518239E138112E6BCA6FEA3FB27B30E28F6D3084D8B5E01F20C7D3FD7EEF3E3EB55F392717BCA9CA76900EBADB7AEA8A26F704C8417708D51374E98D61E0D649BFCC0957FB0636762453C8D1CE08B95FB90BB5EFF6A50210679E167C1E0B67AEDC6E7000C1C4AA5509F8F81D679855BD6CF8FE556FADACE0E45F1C1387DD1A14BBC8A3097DC11C7E40E5A31BCE2188D99008BC3163D04D03ABFB8AA3F17DCFADF8A26F4F275886B1C3DE598068054BB5D8D1B4CB5BCA9E6E822377AA7625490BD4735DDB2B4558D677C1DC2AF39CD9C67242D1C41FF3109FBA72C9C22E362310A905738BF8CEB12697EA0A0885BE11AE0A44DD1FE5F6F863AA8740BAD7300FE1FE72062D3C1669CA796B541637141925DE49515D497F669A695C2735489B58A6E48FF5D6E884D262E5EE95F1EDF49DF55485891DE9B7F5B1E73AD0953C021E4E58D3B7001B702EB6A030E81DC6DB9265290FC224695CAB521CCA0449069CBF358949B03FD67FAE5B15B
-20220419225936 2 6 100 8191 5 CF0A168167DAB1FDFD5C0376DC6E2C93907F486EF5576F14B83FAD667FCC774D179D9A0CB69771C381E7A3AC0F7561E06C8BFD155A9B527EE6F015BDFF6DAE1556CEB985BAAA83E40720B4D91830DDA2BC4BE8C137AB7EB0107D3E04DB39A092C84AEF71E223A40F18B586FA813ED2EC4453A8C15B3531DC651AAFA6136D5BA894B22FA94E96D6034E9A569F4D3366B323D656B5C480D0FC443BA5597B42071CB28466F084FA31856AEAB54268E7DF559C47D0F53F7584273FD41C9C59C130E9E43B0E5664B1FFAE5D3608EBFCDCA6E257B0AED1E270938A03C7494B16E725389F8106CFA4746BD350EFD6688AF36BA679CF2437E25C0335A4C7E51AD3043938D7D49EAD349D50B153346687EC29B70982760D6280C1B92F58AEFC66BAB600A905A40B720A8E75CC1C1D96557F1988FF927ED6C2C614357242CB03E314B19766B1C7D70575A1607B25C6E90F2412DE7D3F140B3B6CD743FEE66DD2F32B35F34C1C4F1523B03F9E68E873FB7697D0D09D387B8E4BA6FF9EE302A8B6D4BEBA2659E8933B8A411BEE451870CA8F388C96C0D1A59F2BCB29CBD5FFDCA855A7A9720E7BCA71037B417D9D54EFED70FB695EB8E3461262884DADE4C7E2F9ED544D650CB9853F1AEE8C48FD285F8C806823065A238AD70A99C832C815970C33E8326ECC759378A603C77D20248DFAAD6AC718D5F04AF2635061C904159E1EB37873B383C7A244C81F58A22553B1DC1A74AFB44B44A5AEA3B096DEB8B6FEFA7778ACBE1B1EF0331B2667611340085C51D092DD6AC47814A4D68384007F87EA2EF20E005ED221855CCF2B67FF58CAA28E40CD9C44586CB054670C2B0EF0E6B73852B5B475409BDD6A6042345630EB1A675F51A13F7453936B72FDACC671D863DEFE781698B6AE6CE15FB6936A27A9D5EE7442380812B8EB4FB525A518239E138112E6BCA6FEA3FB27B30E28F6D3084D8B5E01F20C7D3FD7EEF3E3EB55F392717BCA9CA76900EBADB7AEA8A26F704C8417708D51374E98D61E0D649BFCC0957FB0636762453C8D1CE08B95FB90BB5EFF6A50210679E167C1E0B67AEDC6E7000C1C4AA5509F8F81D679855BD6CF8FE556FADACE0E45F1C1387DD1A14BBC8A3097DC11C7E40E5A31BCE2188D99008BC3163D04D03ABFB8AA3F17DCFADF8A26F4F275886B1C3DE598068054BB5D8D1B4CB5BCA9E6E822377AA7625490BD4735DDB2B4558D677C1DC2AF39CD9C67242D1C41FF3109FBA72C9C22E362310A905738BF8CEB12697EA0A0885BE11AE0A44DD1FE5F6F863AA8740BAD7300FE1FE72062D3C1669CA796B541637141925DE49515D497F669A695C2735489B58A6E48FF5D6E884D262E5EE95F1EDF49DF55485891DE9B7F5B1E73AD0953C021E4E58D3B7001B702EB6A030E81DC6DB9265290FC224695CAB521CCA0449069CBF358949B03FD6802713B8F
-20220419233957 2 6 100 8191 5 CF0A168167DAB1FDFD5C0376DC6E2C93907F486EF5576F14B83FAD667FCC774D179D9A0CB69771C381E7A3AC0F7561E06C8BFD155A9B527EE6F015BDFF6DAE1556CEB985BAAA83E40720B4D91830DDA2BC4BE8C137AB7EB0107D3E04DB39A092C84AEF71E223A40F18B586FA813ED2EC4453A8C15B3531DC651AAFA6136D5BA894B22FA94E96D6034E9A569F4D3366B323D656B5C480D0FC443BA5597B42071CB28466F084FA31856AEAB54268E7DF559C47D0F53F7584273FD41C9C59C130E9E43B0E5664B1FFAE5D3608EBFCDCA6E257B0AED1E270938A03C7494B16E725389F8106CFA4746BD350EFD6688AF36BA679CF2437E25C0335A4C7E51AD3043938D7D49EAD349D50B153346687EC29B70982760D6280C1B92F58AEFC66BAB600A905A40B720A8E75CC1C1D96557F1988FF927ED6C2C614357242CB03E314B19766B1C7D70575A1607B25C6E90F2412DE7D3F140B3B6CD743FEE66DD2F32B35F34C1C4F1523B03F9E68E873FB7697D0D09D387B8E4BA6FF9EE302A8B6D4BEBA2659E8933B8A411BEE451870CA8F388C96C0D1A59F2BCB29CBD5FFDCA855A7A9720E7BCA71037B417D9D54EFED70FB695EB8E3461262884DADE4C7E2F9ED544D650CB9853F1AEE8C48FD285F8C806823065A238AD70A99C832C815970C33E8326ECC759378A603C77D20248DFAAD6AC718D5F04AF2635061C904159E1EB37873B383C7A244C81F58A22553B1DC1A74AFB44B44A5AEA3B096DEB8B6FEFA7778ACBE1B1EF0331B2667611340085C51D092DD6AC47814A4D68384007F87EA2EF20E005ED221855CCF2B67FF58CAA28E40CD9C44586CB054670C2B0EF0E6B73852B5B475409BDD6A6042345630EB1A675F51A13F7453936B72FDACC671D863DEFE781698B6AE6CE15FB6936A27A9D5EE7442380812B8EB4FB525A518239E138112E6BCA6FEA3FB27B30E28F6D3084D8B5E01F20C7D3FD7EEF3E3EB55F392717BCA9CA76900EBADB7AEA8A26F704C8417708D51374E98D61E0D649BFCC0957FB0636762453C8D1CE08B95FB90BB5EFF6A50210679E167C1E0B67AEDC6E7000C1C4AA5509F8F81D679855BD6CF8FE556FADACE0E45F1C1387DD1A14BBC8A3097DC11C7E40E5A31BCE2188D99008BC3163D04D03ABFB8AA3F17DCFADF8A26F4F275886B1C3DE598068054BB5D8D1B4CB5BCA9E6E822377AA7625490BD4735DDB2B4558D677C1DC2AF39CD9C67242D1C41FF3109FBA72C9C22E362310A905738BF8CEB12697EA0A0885BE11AE0A44DD1FE5F6F863AA8740BAD7300FE1FE72062D3C1669CA796B541637141925DE49515D497F669A695C2735489B58A6E48FF5D6E884D262E5EE95F1EDF49DF55485891DE9B7F5B1E73AD0953C021E4E58D3B7001B702EB6A030E81DC6DB9265290FC224695CAB521CCA0449069CBF358949B03FD6804DDE8AF
+20220714110357 2 6 100 2047 2 E98F2A209BA9F4C8C1FFB02490E599A99FBE28F6A053E240A4BD5FEDE80B23FEA8A1476E9EF6605A4B4B41CC74CB945C7E168A91DB112424480A85CBF5853234B9B1F60F030D38F678BA80AE1461F716C463D7396151EB5F037CC88690FEEF8D16A1B67F56C11874DB5AA3D541BEFF390077C79C86434EDBC2B46821D2AE5D2FA4FFF1B086B07669B09498EA11B0FE26C773F79ACA044E085E0BA43BBE1EBE954AA1EC7A465A3232699E54958B1760AB7A04D9627EC1810970706C96B58BF84999EBED8846D8B384CB945BF782141B1BE2B7C0E04D531A2334DB41BBFD1BEA428C5FD22F50BABDBDFCC5B848F64CBA8D039636311F8D844DFFFBD77A429A9923
+20220714110358 2 6 100 2047 5 E98F2A209BA9F4C8C1FFB02490E599A99FBE28F6A053E240A4BD5FEDE80B23FEA8A1476E9EF6605A4B4B41CC74CB945C7E168A91DB112424480A85CBF5853234B9B1F60F030D38F678BA80AE1461F716C463D7396151EB5F037CC88690FEEF8D16A1B67F56C11874DB5AA3D541BEFF390077C79C86434EDBC2B46821D2AE5D2FA4FFF1B086B07669B09498EA11B0FE26C773F79ACA044E085E0BA43BBE1EBE954AA1EC7A465A3232699E54958B1760AB7A04D9627EC1810970706C96B58BF84999EBED8846D8B384CB945BF782141B1BE2B7C0E04D531A2334DB41BBFD1BEA428C5FD22F50BABDBDFCC5B848F64CBA8D039636311F8D844DFFFBD77A42A9BFB7
+20220714110417 2 6 100 2047 2 E98F2A209BA9F4C8C1FFB02490E599A99FBE28F6A053E240A4BD5FEDE80B23FEA8A1476E9EF6605A4B4B41CC74CB945C7E168A91DB112424480A85CBF5853234B9B1F60F030D38F678BA80AE1461F716C463D7396151EB5F037CC88690FEEF8D16A1B67F56C11874DB5AA3D541BEFF390077C79C86434EDBC2B46821D2AE5D2FA4FFF1B086B07669B09498EA11B0FE26C773F79ACA044E085E0BA43BBE1EBE954AA1EC7A465A3232699E54958B1760AB7A04D9627EC1810970706C96B58BF84999EBED8846D8B384CB945BF782141B1BE2B7C0E04D531A2334DB41BBFD1BEA428C5FD22F50BABDBDFCC5B848F64CBA8D039636311F8D844DFFFBD77A4349E923
+20220714110421 2 6 100 2047 5 E98F2A209BA9F4C8C1FFB02490E599A99FBE28F6A053E240A4BD5FEDE80B23FEA8A1476E9EF6605A4B4B41CC74CB945C7E168A91DB112424480A85CBF5853234B9B1F60F030D38F678BA80AE1461F716C463D7396151EB5F037CC88690FEEF8D16A1B67F56C11874DB5AA3D541BEFF390077C79C86434EDBC2B46821D2AE5D2FA4FFF1B086B07669B09498EA11B0FE26C773F79ACA044E085E0BA43BBE1EBE954AA1EC7A465A3232699E54958B1760AB7A04D9627EC1810970706C96B58BF84999EBED8846D8B384CB945BF782141B1BE2B7C0E04D531A2334DB41BBFD1BEA428C5FD22F50BABDBDFCC5B848F64CBA8D039636311F8D844DFFFBD77A436AA537
+20220714110429 2 6 100 2047 2 E98F2A209BA9F4C8C1FFB02490E599A99FBE28F6A053E240A4BD5FEDE80B23FEA8A1476E9EF6605A4B4B41CC74CB945C7E168A91DB112424480A85CBF5853234B9B1F60F030D38F678BA80AE1461F716C463D7396151EB5F037CC88690FEEF8D16A1B67F56C11874DB5AA3D541BEFF390077C79C86434EDBC2B46821D2AE5D2FA4FFF1B086B07669B09498EA11B0FE26C773F79ACA044E085E0BA43BBE1EBE954AA1EC7A465A3232699E54958B1760AB7A04D9627EC1810970706C96B58BF84999EBED8846D8B384CB945BF782141B1BE2B7C0E04D531A2334DB41BBFD1BEA428C5FD22F50BABDBDFCC5B848F64CBA8D039636311F8D844DFFFBD77A43ADB17B
+20220714110437 2 6 100 2047 2 E98F2A209BA9F4C8C1FFB02490E599A99FBE28F6A053E240A4BD5FEDE80B23FEA8A1476E9EF6605A4B4B41CC74CB945C7E168A91DB112424480A85CBF5853234B9B1F60F030D38F678BA80AE1461F716C463D7396151EB5F037CC88690FEEF8D16A1B67F56C11874DB5AA3D541BEFF390077C79C86434EDBC2B46821D2AE5D2FA4FFF1B086B07669B09498EA11B0FE26C773F79ACA044E085E0BA43BBE1EBE954AA1EC7A465A3232699E54958B1760AB7A04D9627EC1810970706C96B58BF84999EBED8846D8B384CB945BF782141B1BE2B7C0E04D531A2334DB41BBFD1BEA428C5FD22F50BABDBDFCC5B848F64CBA8D039636311F8D844DFFFBD77A43F26D23
+20220714110452 2 6 100 2047 2 E98F2A209BA9F4C8C1FFB02490E599A99FBE28F6A053E240A4BD5FEDE80B23FEA8A1476E9EF6605A4B4B41CC74CB945C7E168A91DB112424480A85CBF5853234B9B1F60F030D38F678BA80AE1461F716C463D7396151EB5F037CC88690FEEF8D16A1B67F56C11874DB5AA3D541BEFF390077C79C86434EDBC2B46821D2AE5D2FA4FFF1B086B07669B09498EA11B0FE26C773F79ACA044E085E0BA43BBE1EBE954AA1EC7A465A3232699E54958B1760AB7A04D9627EC1810970706C96B58BF84999EBED8846D8B384CB945BF782141B1BE2B7C0E04D531A2334DB41BBFD1BEA428C5FD22F50BABDBDFCC5B848F64CBA8D039636311F8D844DFFFBD77A4478434B
+20220714110507 2 6 100 2047 5 E98F2A209BA9F4C8C1FFB02490E599A99FBE28F6A053E240A4BD5FEDE80B23FEA8A1476E9EF6605A4B4B41CC74CB945C7E168A91DB112424480A85CBF5853234B9B1F60F030D38F678BA80AE1461F716C463D7396151EB5F037CC88690FEEF8D16A1B67F56C11874DB5AA3D541BEFF390077C79C86434EDBC2B46821D2AE5D2FA4FFF1B086B07669B09498EA11B0FE26C773F79ACA044E085E0BA43BBE1EBE954AA1EC7A465A3232699E54958B1760AB7A04D9627EC1810970706C96B58BF84999EBED8846D8B384CB945BF782141B1BE2B7C0E04D531A2334DB41BBFD1BEA428C5FD22F50BABDBDFCC5B848F64CBA8D039636311F8D844DFFFBD77A44FF2077
+20220714110531 2 6 100 2047 2 E98F2A209BA9F4C8C1FFB02490E599A99FBE28F6A053E240A4BD5FEDE80B23FEA8A1476E9EF6605A4B4B41CC74CB945C7E168A91DB112424480A85CBF5853234B9B1F60F030D38F678BA80AE1461F716C463D7396151EB5F037CC88690FEEF8D16A1B67F56C11874DB5AA3D541BEFF390077C79C86434EDBC2B46821D2AE5D2FA4FFF1B086B07669B09498EA11B0FE26C773F79ACA044E085E0BA43BBE1EBE954AA1EC7A465A3232699E54958B1760AB7A04D9627EC1810970706C96B58BF84999EBED8846D8B384CB945BF782141B1BE2B7C0E04D531A2334DB41BBFD1BEA428C5FD22F50BABDBDFCC5B848F64CBA8D039636311F8D844DFFFBD77A45D0597B
+20220714110534 2 6 100 2047 2 E98F2A209BA9F4C8C1FFB02490E599A99FBE28F6A053E240A4BD5FEDE80B23FEA8A1476E9EF6605A4B4B41CC74CB945C7E168A91DB112424480A85CBF5853234B9B1F60F030D38F678BA80AE1461F716C463D7396151EB5F037CC88690FEEF8D16A1B67F56C11874DB5AA3D541BEFF390077C79C86434EDBC2B46821D2AE5D2FA4FFF1B086B07669B09498EA11B0FE26C773F79ACA044E085E0BA43BBE1EBE954AA1EC7A465A3232699E54958B1760AB7A04D9627EC1810970706C96B58BF84999EBED8846D8B384CB945BF782141B1BE2B7C0E04D531A2334DB41BBFD1BEA428C5FD22F50BABDBDFCC5B848F64CBA8D039636311F8D844DFFFBD77A45E81313
+20220714110541 2 6 100 2047 5 E98F2A209BA9F4C8C1FFB02490E599A99FBE28F6A053E240A4BD5FEDE80B23FEA8A1476E9EF6605A4B4B41CC74CB945C7E168A91DB112424480A85CBF5853234B9B1F60F030D38F678BA80AE1461F716C463D7396151EB5F037CC88690FEEF8D16A1B67F56C11874DB5AA3D541BEFF390077C79C86434EDBC2B46821D2AE5D2FA4FFF1B086B07669B09498EA11B0FE26C773F79ACA044E085E0BA43BBE1EBE954AA1EC7A465A3232699E54958B1760AB7A04D9627EC1810970706C96B58BF84999EBED8846D8B384CB945BF782141B1BE2B7C0E04D531A2334DB41BBFD1BEA428C5FD22F50BABDBDFCC5B848F64CBA8D039636311F8D844DFFFBD77A462B1987
+20220714110550 2 6 100 2047 5 E98F2A209BA9F4C8C1FFB02490E599A99FBE28F6A053E240A4BD5FEDE80B23FEA8A1476E9EF6605A4B4B41CC74CB945C7E168A91DB112424480A85CBF5853234B9B1F60F030D38F678BA80AE1461F716C463D7396151EB5F037CC88690FEEF8D16A1B67F56C11874DB5AA3D541BEFF390077C79C86434EDBC2B46821D2AE5D2FA4FFF1B086B07669B09498EA11B0FE26C773F79ACA044E085E0BA43BBE1EBE954AA1EC7A465A3232699E54958B1760AB7A04D9627EC1810970706C96B58BF84999EBED8846D8B384CB945BF782141B1BE2B7C0E04D531A2334DB41BBFD1BEA428C5FD22F50BABDBDFCC5B848F64CBA8D039636311F8D844DFFFBD77A467A15E7
+20220714110557 2 6 100 2047 5 E98F2A209BA9F4C8C1FFB02490E599A99FBE28F6A053E240A4BD5FEDE80B23FEA8A1476E9EF6605A4B4B41CC74CB945C7E168A91DB112424480A85CBF5853234B9B1F60F030D38F678BA80AE1461F716C463D7396151EB5F037CC88690FEEF8D16A1B67F56C11874DB5AA3D541BEFF390077C79C86434EDBC2B46821D2AE5D2FA4FFF1B086B07669B09498EA11B0FE26C773F79ACA044E085E0BA43BBE1EBE954AA1EC7A465A3232699E54958B1760AB7A04D9627EC1810970706C96B58BF84999EBED8846D8B384CB945BF782141B1BE2B7C0E04D531A2334DB41BBFD1BEA428C5FD22F50BABDBDFCC5B848F64CBA8D039636311F8D844DFFFBD77A46BD40AF
+20220714110605 2 6 100 2047 2 E98F2A209BA9F4C8C1FFB02490E599A99FBE28F6A053E240A4BD5FEDE80B23FEA8A1476E9EF6605A4B4B41CC74CB945C7E168A91DB112424480A85CBF5853234B9B1F60F030D38F678BA80AE1461F716C463D7396151EB5F037CC88690FEEF8D16A1B67F56C11874DB5AA3D541BEFF390077C79C86434EDBC2B46821D2AE5D2FA4FFF1B086B07669B09498EA11B0FE26C773F79ACA044E085E0BA43BBE1EBE954AA1EC7A465A3232699E54958B1760AB7A04D9627EC1810970706C96B58BF84999EBED8846D8B384CB945BF782141B1BE2B7C0E04D531A2334DB41BBFD1BEA428C5FD22F50BABDBDFCC5B848F64CBA8D039636311F8D844DFFFBD77A470351EB
+20220714110630 2 6 100 2047 2 E98F2A209BA9F4C8C1FFB02490E599A99FBE28F6A053E240A4BD5FEDE80B23FEA8A1476E9EF6605A4B4B41CC74CB945C7E168A91DB112424480A85CBF5853234B9B1F60F030D38F678BA80AE1461F716C463D7396151EB5F037CC88690FEEF8D16A1B67F56C11874DB5AA3D541BEFF390077C79C86434EDBC2B46821D2AE5D2FA4FFF1B086B07669B09498EA11B0FE26C773F79ACA044E085E0BA43BBE1EBE954AA1EC7A465A3232699E54958B1760AB7A04D9627EC1810970706C96B58BF84999EBED8846D8B384CB945BF782141B1BE2B7C0E04D531A2334DB41BBFD1BEA428C5FD22F50BABDBDFCC5B848F64CBA8D039636311F8D844DFFFBD77A47EA97DB
+20220714110630 2 6 100 2047 2 E98F2A209BA9F4C8C1FFB02490E599A99FBE28F6A053E240A4BD5FEDE80B23FEA8A1476E9EF6605A4B4B41CC74CB945C7E168A91DB112424480A85CBF5853234B9B1F60F030D38F678BA80AE1461F716C463D7396151EB5F037CC88690FEEF8D16A1B67F56C11874DB5AA3D541BEFF390077C79C86434EDBC2B46821D2AE5D2FA4FFF1B086B07669B09498EA11B0FE26C773F79ACA044E085E0BA43BBE1EBE954AA1EC7A465A3232699E54958B1760AB7A04D9627EC1810970706C96B58BF84999EBED8846D8B384CB945BF782141B1BE2B7C0E04D531A2334DB41BBFD1BEA428C5FD22F50BABDBDFCC5B848F64CBA8D039636311F8D844DFFFBD77A47EAA76B
+20220714110648 2 6 100 2047 2 E98F2A209BA9F4C8C1FFB02490E599A99FBE28F6A053E240A4BD5FEDE80B23FEA8A1476E9EF6605A4B4B41CC74CB945C7E168A91DB112424480A85CBF5853234B9B1F60F030D38F678BA80AE1461F716C463D7396151EB5F037CC88690FEEF8D16A1B67F56C11874DB5AA3D541BEFF390077C79C86434EDBC2B46821D2AE5D2FA4FFF1B086B07669B09498EA11B0FE26C773F79ACA044E085E0BA43BBE1EBE954AA1EC7A465A3232699E54958B1760AB7A04D9627EC1810970706C96B58BF84999EBED8846D8B384CB945BF782141B1BE2B7C0E04D531A2334DB41BBFD1BEA428C5FD22F50BABDBDFCC5B848F64CBA8D039636311F8D844DFFFBD77A4891615B
+20220714110652 2 6 100 2047 5 E98F2A209BA9F4C8C1FFB02490E599A99FBE28F6A053E240A4BD5FEDE80B23FEA8A1476E9EF6605A4B4B41CC74CB945C7E168A91DB112424480A85CBF5853234B9B1F60F030D38F678BA80AE1461F716C463D7396151EB5F037CC88690FEEF8D16A1B67F56C11874DB5AA3D541BEFF390077C79C86434EDBC2B46821D2AE5D2FA4FFF1B086B07669B09498EA11B0FE26C773F79ACA044E085E0BA43BBE1EBE954AA1EC7A465A3232699E54958B1760AB7A04D9627EC1810970706C96B58BF84999EBED8846D8B384CB945BF782141B1BE2B7C0E04D531A2334DB41BBFD1BEA428C5FD22F50BABDBDFCC5B848F64CBA8D039636311F8D844DFFFBD77A48B5137F
+20220714110654 2 6 100 2047 2 E98F2A209BA9F4C8C1FFB02490E599A99FBE28F6A053E240A4BD5FEDE80B23FEA8A1476E9EF6605A4B4B41CC74CB945C7E168A91DB112424480A85CBF5853234B9B1F60F030D38F678BA80AE1461F716C463D7396151EB5F037CC88690FEEF8D16A1B67F56C11874DB5AA3D541BEFF390077C79C86434EDBC2B46821D2AE5D2FA4FFF1B086B07669B09498EA11B0FE26C773F79ACA044E085E0BA43BBE1EBE954AA1EC7A465A3232699E54958B1760AB7A04D9627EC1810970706C96B58BF84999EBED8846D8B384CB945BF782141B1BE2B7C0E04D531A2334DB41BBFD1BEA428C5FD22F50BABDBDFCC5B848F64CBA8D039636311F8D844DFFFBD77A48C1EC7B
+20220714110707 2 6 100 2047 2 E98F2A209BA9F4C8C1FFB02490E599A99FBE28F6A053E240A4BD5FEDE80B23FEA8A1476E9EF6605A4B4B41CC74CB945C7E168A91DB112424480A85CBF5853234B9B1F60F030D38F678BA80AE1461F716C463D7396151EB5F037CC88690FEEF8D16A1B67F56C11874DB5AA3D541BEFF390077C79C86434EDBC2B46821D2AE5D2FA4FFF1B086B07669B09498EA11B0FE26C773F79ACA044E085E0BA43BBE1EBE954AA1EC7A465A3232699E54958B1760AB7A04D9627EC1810970706C96B58BF84999EBED8846D8B384CB945BF782141B1BE2B7C0E04D531A2334DB41BBFD1BEA428C5FD22F50BABDBDFCC5B848F64CBA8D039636311F8D844DFFFBD77A4935FBBB
+20220714110707 2 6 100 2047 2 E98F2A209BA9F4C8C1FFB02490E599A99FBE28F6A053E240A4BD5FEDE80B23FEA8A1476E9EF6605A4B4B41CC74CB945C7E168A91DB112424480A85CBF5853234B9B1F60F030D38F678BA80AE1461F716C463D7396151EB5F037CC88690FEEF8D16A1B67F56C11874DB5AA3D541BEFF390077C79C86434EDBC2B46821D2AE5D2FA4FFF1B086B07669B09498EA11B0FE26C773F79ACA044E085E0BA43BBE1EBE954AA1EC7A465A3232699E54958B1760AB7A04D9627EC1810970706C96B58BF84999EBED8846D8B384CB945BF782141B1BE2B7C0E04D531A2334DB41BBFD1BEA428C5FD22F50BABDBDFCC5B848F64CBA8D039636311F8D844DFFFBD77A4938A2F3
+20220714110715 2 6 100 2047 2 E98F2A209BA9F4C8C1FFB02490E599A99FBE28F6A053E240A4BD5FEDE80B23FEA8A1476E9EF6605A4B4B41CC74CB945C7E168A91DB112424480A85CBF5853234B9B1F60F030D38F678BA80AE1461F716C463D7396151EB5F037CC88690FEEF8D16A1B67F56C11874DB5AA3D541BEFF390077C79C86434EDBC2B46821D2AE5D2FA4FFF1B086B07669B09498EA11B0FE26C773F79ACA044E085E0BA43BBE1EBE954AA1EC7A465A3232699E54958B1760AB7A04D9627EC1810970706C96B58BF84999EBED8846D8B384CB945BF782141B1BE2B7C0E04D531A2334DB41BBFD1BEA428C5FD22F50BABDBDFCC5B848F64CBA8D039636311F8D844DFFFBD77A49847CD3
+20220714110722 2 6 100 2047 5 E98F2A209BA9F4C8C1FFB02490E599A99FBE28F6A053E240A4BD5FEDE80B23FEA8A1476E9EF6605A4B4B41CC74CB945C7E168A91DB112424480A85CBF5853234B9B1F60F030D38F678BA80AE1461F716C463D7396151EB5F037CC88690FEEF8D16A1B67F56C11874DB5AA3D541BEFF390077C79C86434EDBC2B46821D2AE5D2FA4FFF1B086B07669B09498EA11B0FE26C773F79ACA044E085E0BA43BBE1EBE954AA1EC7A465A3232699E54958B1760AB7A04D9627EC1810970706C96B58BF84999EBED8846D8B384CB945BF782141B1BE2B7C0E04D531A2334DB41BBFD1BEA428C5FD22F50BABDBDFCC5B848F64CBA8D039636311F8D844DFFFBD77A49C04CDF
+20220714110726 2 6 100 2047 2 E98F2A209BA9F4C8C1FFB02490E599A99FBE28F6A053E240A4BD5FEDE80B23FEA8A1476E9EF6605A4B4B41CC74CB945C7E168A91DB112424480A85CBF5853234B9B1F60F030D38F678BA80AE1461F716C463D7396151EB5F037CC88690FEEF8D16A1B67F56C11874DB5AA3D541BEFF390077C79C86434EDBC2B46821D2AE5D2FA4FFF1B086B07669B09498EA11B0FE26C773F79ACA044E085E0BA43BBE1EBE954AA1EC7A465A3232699E54958B1760AB7A04D9627EC1810970706C96B58BF84999EBED8846D8B384CB945BF782141B1BE2B7C0E04D531A2334DB41BBFD1BEA428C5FD22F50BABDBDFCC5B848F64CBA8D039636311F8D844DFFFBD77A49E68FA3
+20220714110728 2 6 100 2047 2 E98F2A209BA9F4C8C1FFB02490E599A99FBE28F6A053E240A4BD5FEDE80B23FEA8A1476E9EF6605A4B4B41CC74CB945C7E168A91DB112424480A85CBF5853234B9B1F60F030D38F678BA80AE1461F716C463D7396151EB5F037CC88690FEEF8D16A1B67F56C11874DB5AA3D541BEFF390077C79C86434EDBC2B46821D2AE5D2FA4FFF1B086B07669B09498EA11B0FE26C773F79ACA044E085E0BA43BBE1EBE954AA1EC7A465A3232699E54958B1760AB7A04D9627EC1810970706C96B58BF84999EBED8846D8B384CB945BF782141B1BE2B7C0E04D531A2334DB41BBFD1BEA428C5FD22F50BABDBDFCC5B848F64CBA8D039636311F8D844DFFFBD77A49FF3563
+20220714110733 2 6 100 2047 2 E98F2A209BA9F4C8C1FFB02490E599A99FBE28F6A053E240A4BD5FEDE80B23FEA8A1476E9EF6605A4B4B41CC74CB945C7E168A91DB112424480A85CBF5853234B9B1F60F030D38F678BA80AE1461F716C463D7396151EB5F037CC88690FEEF8D16A1B67F56C11874DB5AA3D541BEFF390077C79C86434EDBC2B46821D2AE5D2FA4FFF1B086B07669B09498EA11B0FE26C773F79ACA044E085E0BA43BBE1EBE954AA1EC7A465A3232699E54958B1760AB7A04D9627EC1810970706C96B58BF84999EBED8846D8B384CB945BF782141B1BE2B7C0E04D531A2334DB41BBFD1BEA428C5FD22F50BABDBDFCC5B848F64CBA8D039636311F8D844DFFFBD77A4A266083
+20220714110736 2 6 100 2047 5 E98F2A209BA9F4C8C1FFB02490E599A99FBE28F6A053E240A4BD5FEDE80B23FEA8A1476E9EF6605A4B4B41CC74CB945C7E168A91DB112424480A85CBF5853234B9B1F60F030D38F678BA80AE1461F716C463D7396151EB5F037CC88690FEEF8D16A1B67F56C11874DB5AA3D541BEFF390077C79C86434EDBC2B46821D2AE5D2FA4FFF1B086B07669B09498EA11B0FE26C773F79ACA044E085E0BA43BBE1EBE954AA1EC7A465A3232699E54958B1760AB7A04D9627EC1810970706C96B58BF84999EBED8846D8B384CB945BF782141B1BE2B7C0E04D531A2334DB41BBFD1BEA428C5FD22F50BABDBDFCC5B848F64CBA8D039636311F8D844DFFFBD77A4A4718EF
+20220714110741 2 6 100 2047 5 E459BD05870898B0392DDF50E0E0FBCA35E6D6FC6CC9174AE997BE7CBB6902931A8686BEF0D0BC2C82308F0DBF995B77A5952BE4EB437C277A3CBD94356E4AEF676686E76B33FC5586BC6C68859F45F9E71B87AF29583F0808D2F73FD54B15E5D10DDDDB3CF0680C42F17EAD0BD5CAC0B94ED891D1A4775AD74F3E7D7E36B12EF546F6EB27610D5EFBE3F89EC644901CD8D8293CDF9B99731D8FBD2FE920674E74117FCB9CD20B3FD23D2ADD966F5090265131571699A84F3894B14730E0F99E1A49067CB3BE74A34C0E94A6992E02BE30940BDAB6C6E992AF81F6615674B232F4B152F97D9523B1C2ED6EA6DF7C4C69EB66FF9976325AB0A7D50DE63A97ACE7
+20220714110743 2 6 100 2047 2 E459BD05870898B0392DDF50E0E0FBCA35E6D6FC6CC9174AE997BE7CBB6902931A8686BEF0D0BC2C82308F0DBF995B77A5952BE4EB437C277A3CBD94356E4AEF676686E76B33FC5586BC6C68859F45F9E71B87AF29583F0808D2F73FD54B15E5D10DDDDB3CF0680C42F17EAD0BD5CAC0B94ED891D1A4775AD74F3E7D7E36B12EF546F6EB27610D5EFBE3F89EC644901CD8D8293CDF9B99731D8FBD2FE920674E74117FCB9CD20B3FD23D2ADD966F5090265131571699A84F3894B14730E0F99E1A49067CB3BE74A34C0E94A6992E02BE30940BDAB6C6E992AF81F6615674B232F4B152F97D9523B1C2ED6EA6DF7C4C69EB66FF9976325AB0A7D50DE63AA92DEB
+20220714110749 2 6 100 2047 5 E459BD05870898B0392DDF50E0E0FBCA35E6D6FC6CC9174AE997BE7CBB6902931A8686BEF0D0BC2C82308F0DBF995B77A5952BE4EB437C277A3CBD94356E4AEF676686E76B33FC5586BC6C68859F45F9E71B87AF29583F0808D2F73FD54B15E5D10DDDDB3CF0680C42F17EAD0BD5CAC0B94ED891D1A4775AD74F3E7D7E36B12EF546F6EB27610D5EFBE3F89EC644901CD8D8293CDF9B99731D8FBD2FE920674E74117FCB9CD20B3FD23D2ADD966F5090265131571699A84F3894B14730E0F99E1A49067CB3BE74A34C0E94A6992E02BE30940BDAB6C6E992AF81F6615674B232F4B152F97D9523B1C2ED6EA6DF7C4C69EB66FF9976325AB0A7D50DE63ADC6787
+20220714110814 2 6 100 2047 2 E459BD05870898B0392DDF50E0E0FBCA35E6D6FC6CC9174AE997BE7CBB6902931A8686BEF0D0BC2C82308F0DBF995B77A5952BE4EB437C277A3CBD94356E4AEF676686E76B33FC5586BC6C68859F45F9E71B87AF29583F0808D2F73FD54B15E5D10DDDDB3CF0680C42F17EAD0BD5CAC0B94ED891D1A4775AD74F3E7D7E36B12EF546F6EB27610D5EFBE3F89EC644901CD8D8293CDF9B99731D8FBD2FE920674E74117FCB9CD20B3FD23D2ADD966F5090265131571699A84F3894B14730E0F99E1A49067CB3BE74A34C0E94A6992E02BE30940BDAB6C6E992AF81F6615674B232F4B152F97D9523B1C2ED6EA6DF7C4C69EB66FF9976325AB0A7D50DE63BC349AB
+20220714110816 2 6 100 2047 2 E459BD05870898B0392DDF50E0E0FBCA35E6D6FC6CC9174AE997BE7CBB6902931A8686BEF0D0BC2C82308F0DBF995B77A5952BE4EB437C277A3CBD94356E4AEF676686E76B33FC5586BC6C68859F45F9E71B87AF29583F0808D2F73FD54B15E5D10DDDDB3CF0680C42F17EAD0BD5CAC0B94ED891D1A4775AD74F3E7D7E36B12EF546F6EB27610D5EFBE3F89EC644901CD8D8293CDF9B99731D8FBD2FE920674E74117FCB9CD20B3FD23D2ADD966F5090265131571699A84F3894B14730E0F99E1A49067CB3BE74A34C0E94A6992E02BE30940BDAB6C6E992AF81F6615674B232F4B152F97D9523B1C2ED6EA6DF7C4C69EB66FF9976325AB0A7D50DE63BD5A5D3
+20220714110819 2 6 100 2047 2 E459BD05870898B0392DDF50E0E0FBCA35E6D6FC6CC9174AE997BE7CBB6902931A8686BEF0D0BC2C82308F0DBF995B77A5952BE4EB437C277A3CBD94356E4AEF676686E76B33FC5586BC6C68859F45F9E71B87AF29583F0808D2F73FD54B15E5D10DDDDB3CF0680C42F17EAD0BD5CAC0B94ED891D1A4775AD74F3E7D7E36B12EF546F6EB27610D5EFBE3F89EC644901CD8D8293CDF9B99731D8FBD2FE920674E74117FCB9CD20B3FD23D2ADD966F5090265131571699A84F3894B14730E0F99E1A49067CB3BE74A34C0E94A6992E02BE30940BDAB6C6E992AF81F6615674B232F4B152F97D9523B1C2ED6EA6DF7C4C69EB66FF9976325AB0A7D50DE63BF25123
+20220714110823 2 6 100 2047 5 E459BD05870898B0392DDF50E0E0FBCA35E6D6FC6CC9174AE997BE7CBB6902931A8686BEF0D0BC2C82308F0DBF995B77A5952BE4EB437C277A3CBD94356E4AEF676686E76B33FC5586BC6C68859F45F9E71B87AF29583F0808D2F73FD54B15E5D10DDDDB3CF0680C42F17EAD0BD5CAC0B94ED891D1A4775AD74F3E7D7E36B12EF546F6EB27610D5EFBE3F89EC644901CD8D8293CDF9B99731D8FBD2FE920674E74117FCB9CD20B3FD23D2ADD966F5090265131571699A84F3894B14730E0F99E1A49067CB3BE74A34C0E94A6992E02BE30940BDAB6C6E992AF81F6615674B232F4B152F97D9523B1C2ED6EA6DF7C4C69EB66FF9976325AB0A7D50DE63C158EEF
+20220714110828 2 6 100 2047 2 E459BD05870898B0392DDF50E0E0FBCA35E6D6FC6CC9174AE997BE7CBB6902931A8686BEF0D0BC2C82308F0DBF995B77A5952BE4EB437C277A3CBD94356E4AEF676686E76B33FC5586BC6C68859F45F9E71B87AF29583F0808D2F73FD54B15E5D10DDDDB3CF0680C42F17EAD0BD5CAC0B94ED891D1A4775AD74F3E7D7E36B12EF546F6EB27610D5EFBE3F89EC644901CD8D8293CDF9B99731D8FBD2FE920674E74117FCB9CD20B3FD23D2ADD966F5090265131571699A84F3894B14730E0F99E1A49067CB3BE74A34C0E94A6992E02BE30940BDAB6C6E992AF81F6615674B232F4B152F97D9523B1C2ED6EA6DF7C4C69EB66FF9976325AB0A7D50DE63C438BD3
+20220714110845 2 6 100 2047 5 E459BD05870898B0392DDF50E0E0FBCA35E6D6FC6CC9174AE997BE7CBB6902931A8686BEF0D0BC2C82308F0DBF995B77A5952BE4EB437C277A3CBD94356E4AEF676686E76B33FC5586BC6C68859F45F9E71B87AF29583F0808D2F73FD54B15E5D10DDDDB3CF0680C42F17EAD0BD5CAC0B94ED891D1A4775AD74F3E7D7E36B12EF546F6EB27610D5EFBE3F89EC644901CD8D8293CDF9B99731D8FBD2FE920674E74117FCB9CD20B3FD23D2ADD966F5090265131571699A84F3894B14730E0F99E1A49067CB3BE74A34C0E94A6992E02BE30940BDAB6C6E992AF81F6615674B232F4B152F97D9523B1C2ED6EA6DF7C4C69EB66FF9976325AB0A7D50DE63CD80AD7
+20220714110857 2 6 100 2047 2 E459BD05870898B0392DDF50E0E0FBCA35E6D6FC6CC9174AE997BE7CBB6902931A8686BEF0D0BC2C82308F0DBF995B77A5952BE4EB437C277A3CBD94356E4AEF676686E76B33FC5586BC6C68859F45F9E71B87AF29583F0808D2F73FD54B15E5D10DDDDB3CF0680C42F17EAD0BD5CAC0B94ED891D1A4775AD74F3E7D7E36B12EF546F6EB27610D5EFBE3F89EC644901CD8D8293CDF9B99731D8FBD2FE920674E74117FCB9CD20B3FD23D2ADD966F5090265131571699A84F3894B14730E0F99E1A49067CB3BE74A34C0E94A6992E02BE30940BDAB6C6E992AF81F6615674B232F4B152F97D9523B1C2ED6EA6DF7C4C69EB66FF9976325AB0A7D50DE63D3CF5C3
+20220714110900 2 6 100 2047 2 E459BD05870898B0392DDF50E0E0FBCA35E6D6FC6CC9174AE997BE7CBB6902931A8686BEF0D0BC2C82308F0DBF995B77A5952BE4EB437C277A3CBD94356E4AEF676686E76B33FC5586BC6C68859F45F9E71B87AF29583F0808D2F73FD54B15E5D10DDDDB3CF0680C42F17EAD0BD5CAC0B94ED891D1A4775AD74F3E7D7E36B12EF546F6EB27610D5EFBE3F89EC644901CD8D8293CDF9B99731D8FBD2FE920674E74117FCB9CD20B3FD23D2ADD966F5090265131571699A84F3894B14730E0F99E1A49067CB3BE74A34C0E94A6992E02BE30940BDAB6C6E992AF81F6615674B232F4B152F97D9523B1C2ED6EA6DF7C4C69EB66FF9976325AB0A7D50DE63D598D1B
+20220714110905 2 6 100 2047 2 E459BD05870898B0392DDF50E0E0FBCA35E6D6FC6CC9174AE997BE7CBB6902931A8686BEF0D0BC2C82308F0DBF995B77A5952BE4EB437C277A3CBD94356E4AEF676686E76B33FC5586BC6C68859F45F9E71B87AF29583F0808D2F73FD54B15E5D10DDDDB3CF0680C42F17EAD0BD5CAC0B94ED891D1A4775AD74F3E7D7E36B12EF546F6EB27610D5EFBE3F89EC644901CD8D8293CDF9B99731D8FBD2FE920674E74117FCB9CD20B3FD23D2ADD966F5090265131571699A84F3894B14730E0F99E1A49067CB3BE74A34C0E94A6992E02BE30940BDAB6C6E992AF81F6615674B232F4B152F97D9523B1C2ED6EA6DF7C4C69EB66FF9976325AB0A7D50DE63D85CF73
+20220714110905 2 6 100 2047 2 E459BD05870898B0392DDF50E0E0FBCA35E6D6FC6CC9174AE997BE7CBB6902931A8686BEF0D0BC2C82308F0DBF995B77A5952BE4EB437C277A3CBD94356E4AEF676686E76B33FC5586BC6C68859F45F9E71B87AF29583F0808D2F73FD54B15E5D10DDDDB3CF0680C42F17EAD0BD5CAC0B94ED891D1A4775AD74F3E7D7E36B12EF546F6EB27610D5EFBE3F89EC644901CD8D8293CDF9B99731D8FBD2FE920674E74117FCB9CD20B3FD23D2ADD966F5090265131571699A84F3894B14730E0F99E1A49067CB3BE74A34C0E94A6992E02BE30940BDAB6C6E992AF81F6615674B232F4B152F97D9523B1C2ED6EA6DF7C4C69EB66FF9976325AB0A7D50DE63D88E27B
+20220714110906 2 6 100 2047 5 E459BD05870898B0392DDF50E0E0FBCA35E6D6FC6CC9174AE997BE7CBB6902931A8686BEF0D0BC2C82308F0DBF995B77A5952BE4EB437C277A3CBD94356E4AEF676686E76B33FC5586BC6C68859F45F9E71B87AF29583F0808D2F73FD54B15E5D10DDDDB3CF0680C42F17EAD0BD5CAC0B94ED891D1A4775AD74F3E7D7E36B12EF546F6EB27610D5EFBE3F89EC644901CD8D8293CDF9B99731D8FBD2FE920674E74117FCB9CD20B3FD23D2ADD966F5090265131571699A84F3894B14730E0F99E1A49067CB3BE74A34C0E94A6992E02BE30940BDAB6C6E992AF81F6615674B232F4B152F97D9523B1C2ED6EA6DF7C4C69EB66FF9976325AB0A7D50DE63D93B057
+20220714110907 2 6 100 2047 5 E459BD05870898B0392DDF50E0E0FBCA35E6D6FC6CC9174AE997BE7CBB6902931A8686BEF0D0BC2C82308F0DBF995B77A5952BE4EB437C277A3CBD94356E4AEF676686E76B33FC5586BC6C68859F45F9E71B87AF29583F0808D2F73FD54B15E5D10DDDDB3CF0680C42F17EAD0BD5CAC0B94ED891D1A4775AD74F3E7D7E36B12EF546F6EB27610D5EFBE3F89EC644901CD8D8293CDF9B99731D8FBD2FE920674E74117FCB9CD20B3FD23D2ADD966F5090265131571699A84F3894B14730E0F99E1A49067CB3BE74A34C0E94A6992E02BE30940BDAB6C6E992AF81F6615674B232F4B152F97D9523B1C2ED6EA6DF7C4C69EB66FF9976325AB0A7D50DE63D997D57
+20220714110947 2 6 100 2047 2 E459BD05870898B0392DDF50E0E0FBCA35E6D6FC6CC9174AE997BE7CBB6902931A8686BEF0D0BC2C82308F0DBF995B77A5952BE4EB437C277A3CBD94356E4AEF676686E76B33FC5586BC6C68859F45F9E71B87AF29583F0808D2F73FD54B15E5D10DDDDB3CF0680C42F17EAD0BD5CAC0B94ED891D1A4775AD74F3E7D7E36B12EF546F6EB27610D5EFBE3F89EC644901CD8D8293CDF9B99731D8FBD2FE920674E74117FCB9CD20B3FD23D2ADD966F5090265131571699A84F3894B14730E0F99E1A49067CB3BE74A34C0E94A6992E02BE30940BDAB6C6E992AF81F6615674B232F4B152F97D9523B1C2ED6EA6DF7C4C69EB66FF9976325AB0A7D50DE63F07D89B
+20220714110948 2 6 100 2047 5 E459BD05870898B0392DDF50E0E0FBCA35E6D6FC6CC9174AE997BE7CBB6902931A8686BEF0D0BC2C82308F0DBF995B77A5952BE4EB437C277A3CBD94356E4AEF676686E76B33FC5586BC6C68859F45F9E71B87AF29583F0808D2F73FD54B15E5D10DDDDB3CF0680C42F17EAD0BD5CAC0B94ED891D1A4775AD74F3E7D7E36B12EF546F6EB27610D5EFBE3F89EC644901CD8D8293CDF9B99731D8FBD2FE920674E74117FCB9CD20B3FD23D2ADD966F5090265131571699A84F3894B14730E0F99E1A49067CB3BE74A34C0E94A6992E02BE30940BDAB6C6E992AF81F6615674B232F4B152F97D9523B1C2ED6EA6DF7C4C69EB66FF9976325AB0A7D50DE63F12EC37
+20220714110950 2 6 100 2047 2 E459BD05870898B0392DDF50E0E0FBCA35E6D6FC6CC9174AE997BE7CBB6902931A8686BEF0D0BC2C82308F0DBF995B77A5952BE4EB437C277A3CBD94356E4AEF676686E76B33FC5586BC6C68859F45F9E71B87AF29583F0808D2F73FD54B15E5D10DDDDB3CF0680C42F17EAD0BD5CAC0B94ED891D1A4775AD74F3E7D7E36B12EF546F6EB27610D5EFBE3F89EC644901CD8D8293CDF9B99731D8FBD2FE920674E74117FCB9CD20B3FD23D2ADD966F5090265131571699A84F3894B14730E0F99E1A49067CB3BE74A34C0E94A6992E02BE30940BDAB6C6E992AF81F6615674B232F4B152F97D9523B1C2ED6EA6DF7C4C69EB66FF9976325AB0A7D50DE63F1E46CB
+20220714110952 2 6 100 2047 5 E459BD05870898B0392DDF50E0E0FBCA35E6D6FC6CC9174AE997BE7CBB6902931A8686BEF0D0BC2C82308F0DBF995B77A5952BE4EB437C277A3CBD94356E4AEF676686E76B33FC5586BC6C68859F45F9E71B87AF29583F0808D2F73FD54B15E5D10DDDDB3CF0680C42F17EAD0BD5CAC0B94ED891D1A4775AD74F3E7D7E36B12EF546F6EB27610D5EFBE3F89EC644901CD8D8293CDF9B99731D8FBD2FE920674E74117FCB9CD20B3FD23D2ADD966F5090265131571699A84F3894B14730E0F99E1A49067CB3BE74A34C0E94A6992E02BE30940BDAB6C6E992AF81F6615674B232F4B152F97D9523B1C2ED6EA6DF7C4C69EB66FF9976325AB0A7D50DE63F36E2EF
+20220714110953 2 6 100 2047 2 E459BD05870898B0392DDF50E0E0FBCA35E6D6FC6CC9174AE997BE7CBB6902931A8686BEF0D0BC2C82308F0DBF995B77A5952BE4EB437C277A3CBD94356E4AEF676686E76B33FC5586BC6C68859F45F9E71B87AF29583F0808D2F73FD54B15E5D10DDDDB3CF0680C42F17EAD0BD5CAC0B94ED891D1A4775AD74F3E7D7E36B12EF546F6EB27610D5EFBE3F89EC644901CD8D8293CDF9B99731D8FBD2FE920674E74117FCB9CD20B3FD23D2ADD966F5090265131571699A84F3894B14730E0F99E1A49067CB3BE74A34C0E94A6992E02BE30940BDAB6C6E992AF81F6615674B232F4B152F97D9523B1C2ED6EA6DF7C4C69EB66FF9976325AB0A7D50DE63F3EFE3B
+20220714110954 2 6 100 2047 2 E459BD05870898B0392DDF50E0E0FBCA35E6D6FC6CC9174AE997BE7CBB6902931A8686BEF0D0BC2C82308F0DBF995B77A5952BE4EB437C277A3CBD94356E4AEF676686E76B33FC5586BC6C68859F45F9E71B87AF29583F0808D2F73FD54B15E5D10DDDDB3CF0680C42F17EAD0BD5CAC0B94ED891D1A4775AD74F3E7D7E36B12EF546F6EB27610D5EFBE3F89EC644901CD8D8293CDF9B99731D8FBD2FE920674E74117FCB9CD20B3FD23D2ADD966F5090265131571699A84F3894B14730E0F99E1A49067CB3BE74A34C0E94A6992E02BE30940BDAB6C6E992AF81F6615674B232F4B152F97D9523B1C2ED6EA6DF7C4C69EB66FF9976325AB0A7D50DE63F45AF83
+20220714110957 2 6 100 2047 2 E459BD05870898B0392DDF50E0E0FBCA35E6D6FC6CC9174AE997BE7CBB6902931A8686BEF0D0BC2C82308F0DBF995B77A5952BE4EB437C277A3CBD94356E4AEF676686E76B33FC5586BC6C68859F45F9E71B87AF29583F0808D2F73FD54B15E5D10DDDDB3CF0680C42F17EAD0BD5CAC0B94ED891D1A4775AD74F3E7D7E36B12EF546F6EB27610D5EFBE3F89EC644901CD8D8293CDF9B99731D8FBD2FE920674E74117FCB9CD20B3FD23D2ADD966F5090265131571699A84F3894B14730E0F99E1A49067CB3BE74A34C0E94A6992E02BE30940BDAB6C6E992AF81F6615674B232F4B152F97D9523B1C2ED6EA6DF7C4C69EB66FF9976325AB0A7D50DE63F6684DB
+20220714110957 2 6 100 2047 5 E459BD05870898B0392DDF50E0E0FBCA35E6D6FC6CC9174AE997BE7CBB6902931A8686BEF0D0BC2C82308F0DBF995B77A5952BE4EB437C277A3CBD94356E4AEF676686E76B33FC5586BC6C68859F45F9E71B87AF29583F0808D2F73FD54B15E5D10DDDDB3CF0680C42F17EAD0BD5CAC0B94ED891D1A4775AD74F3E7D7E36B12EF546F6EB27610D5EFBE3F89EC644901CD8D8293CDF9B99731D8FBD2FE920674E74117FCB9CD20B3FD23D2ADD966F5090265131571699A84F3894B14730E0F99E1A49067CB3BE74A34C0E94A6992E02BE30940BDAB6C6E992AF81F6615674B232F4B152F97D9523B1C2ED6EA6DF7C4C69EB66FF9976325AB0A7D50DE63F674AE7
+20220714111000 2 6 100 2047 2 E459BD05870898B0392DDF50E0E0FBCA35E6D6FC6CC9174AE997BE7CBB6902931A8686BEF0D0BC2C82308F0DBF995B77A5952BE4EB437C277A3CBD94356E4AEF676686E76B33FC5586BC6C68859F45F9E71B87AF29583F0808D2F73FD54B15E5D10DDDDB3CF0680C42F17EAD0BD5CAC0B94ED891D1A4775AD74F3E7D7E36B12EF546F6EB27610D5EFBE3F89EC644901CD8D8293CDF9B99731D8FBD2FE920674E74117FCB9CD20B3FD23D2ADD966F5090265131571699A84F3894B14730E0F99E1A49067CB3BE74A34C0E94A6992E02BE30940BDAB6C6E992AF81F6615674B232F4B152F97D9523B1C2ED6EA6DF7C4C69EB66FF9976325AB0A7D50DE63F798EBB
+20220714111037 2 6 100 2047 5 E459BD05870898B0392DDF50E0E0FBCA35E6D6FC6CC9174AE997BE7CBB6902931A8686BEF0D0BC2C82308F0DBF995B77A5952BE4EB437C277A3CBD94356E4AEF676686E76B33FC5586BC6C68859F45F9E71B87AF29583F0808D2F73FD54B15E5D10DDDDB3CF0680C42F17EAD0BD5CAC0B94ED891D1A4775AD74F3E7D7E36B12EF546F6EB27610D5EFBE3F89EC644901CD8D8293CDF9B99731D8FBD2FE920674E74117FCB9CD20B3FD23D2ADD966F5090265131571699A84F3894B14730E0F99E1A49067CB3BE74A34C0E94A6992E02BE30940BDAB6C6E992AF81F6615674B232F4B152F97D9523B1C2ED6EA6DF7C4C69EB66FF9976325AB0A7D50DE640C91997
+20220714111042 2 6 100 2047 5 E459BD05870898B0392DDF50E0E0FBCA35E6D6FC6CC9174AE997BE7CBB6902931A8686BEF0D0BC2C82308F0DBF995B77A5952BE4EB437C277A3CBD94356E4AEF676686E76B33FC5586BC6C68859F45F9E71B87AF29583F0808D2F73FD54B15E5D10DDDDB3CF0680C42F17EAD0BD5CAC0B94ED891D1A4775AD74F3E7D7E36B12EF546F6EB27610D5EFBE3F89EC644901CD8D8293CDF9B99731D8FBD2FE920674E74117FCB9CD20B3FD23D2ADD966F5090265131571699A84F3894B14730E0F99E1A49067CB3BE74A34C0E94A6992E02BE30940BDAB6C6E992AF81F6615674B232F4B152F97D9523B1C2ED6EA6DF7C4C69EB66FF9976325AB0A7D50DE640F6CD07
+20220714111048 2 6 100 2047 2 E459BD05870898B0392DDF50E0E0FBCA35E6D6FC6CC9174AE997BE7CBB6902931A8686BEF0D0BC2C82308F0DBF995B77A5952BE4EB437C277A3CBD94356E4AEF676686E76B33FC5586BC6C68859F45F9E71B87AF29583F0808D2F73FD54B15E5D10DDDDB3CF0680C42F17EAD0BD5CAC0B94ED891D1A4775AD74F3E7D7E36B12EF546F6EB27610D5EFBE3F89EC644901CD8D8293CDF9B99731D8FBD2FE920674E74117FCB9CD20B3FD23D2ADD966F5090265131571699A84F3894B14730E0F99E1A49067CB3BE74A34C0E94A6992E02BE30940BDAB6C6E992AF81F6615674B232F4B152F97D9523B1C2ED6EA6DF7C4C69EB66FF9976325AB0A7D50DE641309F8B
+20220714111052 2 6 100 2047 5 E459BD05870898B0392DDF50E0E0FBCA35E6D6FC6CC9174AE997BE7CBB6902931A8686BEF0D0BC2C82308F0DBF995B77A5952BE4EB437C277A3CBD94356E4AEF676686E76B33FC5586BC6C68859F45F9E71B87AF29583F0808D2F73FD54B15E5D10DDDDB3CF0680C42F17EAD0BD5CAC0B94ED891D1A4775AD74F3E7D7E36B12EF546F6EB27610D5EFBE3F89EC644901CD8D8293CDF9B99731D8FBD2FE920674E74117FCB9CD20B3FD23D2ADD966F5090265131571699A84F3894B14730E0F99E1A49067CB3BE74A34C0E94A6992E02BE30940BDAB6C6E992AF81F6615674B232F4B152F97D9523B1C2ED6EA6DF7C4C69EB66FF9976325AB0A7D50DE64153581F
+20220714111054 2 6 100 2047 5 E459BD05870898B0392DDF50E0E0FBCA35E6D6FC6CC9174AE997BE7CBB6902931A8686BEF0D0BC2C82308F0DBF995B77A5952BE4EB437C277A3CBD94356E4AEF676686E76B33FC5586BC6C68859F45F9E71B87AF29583F0808D2F73FD54B15E5D10DDDDB3CF0680C42F17EAD0BD5CAC0B94ED891D1A4775AD74F3E7D7E36B12EF546F6EB27610D5EFBE3F89EC644901CD8D8293CDF9B99731D8FBD2FE920674E74117FCB9CD20B3FD23D2ADD966F5090265131571699A84F3894B14730E0F99E1A49067CB3BE74A34C0E94A6992E02BE30940BDAB6C6E992AF81F6615674B232F4B152F97D9523B1C2ED6EA6DF7C4C69EB66FF9976325AB0A7D50DE6415DF757
+20220714111055 2 6 100 2047 5 E459BD05870898B0392DDF50E0E0FBCA35E6D6FC6CC9174AE997BE7CBB6902931A8686BEF0D0BC2C82308F0DBF995B77A5952BE4EB437C277A3CBD94356E4AEF676686E76B33FC5586BC6C68859F45F9E71B87AF29583F0808D2F73FD54B15E5D10DDDDB3CF0680C42F17EAD0BD5CAC0B94ED891D1A4775AD74F3E7D7E36B12EF546F6EB27610D5EFBE3F89EC644901CD8D8293CDF9B99731D8FBD2FE920674E74117FCB9CD20B3FD23D2ADD966F5090265131571699A84F3894B14730E0F99E1A49067CB3BE74A34C0E94A6992E02BE30940BDAB6C6E992AF81F6615674B232F4B152F97D9523B1C2ED6EA6DF7C4C69EB66FF9976325AB0A7D50DE6416B572F
+20220714111059 2 6 100 2047 2 E459BD05870898B0392DDF50E0E0FBCA35E6D6FC6CC9174AE997BE7CBB6902931A8686BEF0D0BC2C82308F0DBF995B77A5952BE4EB437C277A3CBD94356E4AEF676686E76B33FC5586BC6C68859F45F9E71B87AF29583F0808D2F73FD54B15E5D10DDDDB3CF0680C42F17EAD0BD5CAC0B94ED891D1A4775AD74F3E7D7E36B12EF546F6EB27610D5EFBE3F89EC644901CD8D8293CDF9B99731D8FBD2FE920674E74117FCB9CD20B3FD23D2ADD966F5090265131571699A84F3894B14730E0F99E1A49067CB3BE74A34C0E94A6992E02BE30940BDAB6C6E992AF81F6615674B232F4B152F97D9523B1C2ED6EA6DF7C4C69EB66FF9976325AB0A7D50DE6418D88DB
+20220714111109 2 6 100 2047 2 E459BD05870898B0392DDF50E0E0FBCA35E6D6FC6CC9174AE997BE7CBB6902931A8686BEF0D0BC2C82308F0DBF995B77A5952BE4EB437C277A3CBD94356E4AEF676686E76B33FC5586BC6C68859F45F9E71B87AF29583F0808D2F73FD54B15E5D10DDDDB3CF0680C42F17EAD0BD5CAC0B94ED891D1A4775AD74F3E7D7E36B12EF546F6EB27610D5EFBE3F89EC644901CD8D8293CDF9B99731D8FBD2FE920674E74117FCB9CD20B3FD23D2ADD966F5090265131571699A84F3894B14730E0F99E1A49067CB3BE74A34C0E94A6992E02BE30940BDAB6C6E992AF81F6615674B232F4B152F97D9523B1C2ED6EA6DF7C4C69EB66FF9976325AB0A7D50DE641E2FC7B
+20220714111127 2 6 100 2047 2 E459BD05870898B0392DDF50E0E0FBCA35E6D6FC6CC9174AE997BE7CBB6902931A8686BEF0D0BC2C82308F0DBF995B77A5952BE4EB437C277A3CBD94356E4AEF676686E76B33FC5586BC6C68859F45F9E71B87AF29583F0808D2F73FD54B15E5D10DDDDB3CF0680C42F17EAD0BD5CAC0B94ED891D1A4775AD74F3E7D7E36B12EF546F6EB27610D5EFBE3F89EC644901CD8D8293CDF9B99731D8FBD2FE920674E74117FCB9CD20B3FD23D2ADD966F5090265131571699A84F3894B14730E0F99E1A49067CB3BE74A34C0E94A6992E02BE30940BDAB6C6E992AF81F6615674B232F4B152F97D9523B1C2ED6EA6DF7C4C69EB66FF9976325AB0A7D50DE6428AF363
+20220714111939 2 6 100 3071 2 C60003BD3BEA8A30306CD503D00EFB4ED2BF6A45DEA568495ABAF8D2D53A1E0BA1D2C2D3648219C03F47CD52B677D72316114A3882A8A3EB62C4F002DB326C27811A36E332D121EE420DDDF830741F14AA96AC0D2AEB5A80BF31CD18D4E3C02A22BD1986A906EEC3D635669FF26DD25A73FD7650666B101D6C42B0A58D96331E0666C990B56E4F0A5649C76FC7BA599A6DBE245F3A2F16AA4A9216B3AFAA93FE40BBB1149A657C934EC408C063B7130027EF7624C721931FECB563EF32C68E9C275A6A9F8BBF5428CBAED0987CD0EB4BF1BF7AC6F33C37FD88C7A026ABD735F0CD7395A4A22DB22B26C78823FB3BDC98150A82573259E64F407A2B3C017D2E9933E64EF5DDABDD3E748D507D21FF4F7B3450F2640E51DF3993B067DB952F8CD179BE389000934363E209ACF6235D1E9D07D3B0E865C4F9EA6EEB91D2B46B8032B2A3890E4DCA5905E269BD5BF2810548243F13FB13691E5346533538503C9CAA0E56DBE759C182BD04663461B435B8D7A20D69DE33D98AFAA302B86A40451D63
+20220714111946 2 6 100 3071 2 C60003BD3BEA8A30306CD503D00EFB4ED2BF6A45DEA568495ABAF8D2D53A1E0BA1D2C2D3648219C03F47CD52B677D72316114A3882A8A3EB62C4F002DB326C27811A36E332D121EE420DDDF830741F14AA96AC0D2AEB5A80BF31CD18D4E3C02A22BD1986A906EEC3D635669FF26DD25A73FD7650666B101D6C42B0A58D96331E0666C990B56E4F0A5649C76FC7BA599A6DBE245F3A2F16AA4A9216B3AFAA93FE40BBB1149A657C934EC408C063B7130027EF7624C721931FECB563EF32C68E9C275A6A9F8BBF5428CBAED0987CD0EB4BF1BF7AC6F33C37FD88C7A026ABD735F0CD7395A4A22DB22B26C78823FB3BDC98150A82573259E64F407A2B3C017D2E9933E64EF5DDABDD3E748D507D21FF4F7B3450F2640E51DF3993B067DB952F8CD179BE389000934363E209ACF6235D1E9D07D3B0E865C4F9EA6EEB91D2B46B8032B2A3890E4DCA5905E269BD5BF2810548243F13FB13691E5346533538503C9CAA0E56DBE759C182BD04663461B435B8D7A20D69DE33D98AFAA302B86A405CC61B
+20220714111948 2 6 100 3071 2 C60003BD3BEA8A30306CD503D00EFB4ED2BF6A45DEA568495ABAF8D2D53A1E0BA1D2C2D3648219C03F47CD52B677D72316114A3882A8A3EB62C4F002DB326C27811A36E332D121EE420DDDF830741F14AA96AC0D2AEB5A80BF31CD18D4E3C02A22BD1986A906EEC3D635669FF26DD25A73FD7650666B101D6C42B0A58D96331E0666C990B56E4F0A5649C76FC7BA599A6DBE245F3A2F16AA4A9216B3AFAA93FE40BBB1149A657C934EC408C063B7130027EF7624C721931FECB563EF32C68E9C275A6A9F8BBF5428CBAED0987CD0EB4BF1BF7AC6F33C37FD88C7A026ABD735F0CD7395A4A22DB22B26C78823FB3BDC98150A82573259E64F407A2B3C017D2E9933E64EF5DDABDD3E748D507D21FF4F7B3450F2640E51DF3993B067DB952F8CD179BE389000934363E209ACF6235D1E9D07D3B0E865C4F9EA6EEB91D2B46B8032B2A3890E4DCA5905E269BD5BF2810548243F13FB13691E5346533538503C9CAA0E56DBE759C182BD04663461B435B8D7A20D69DE33D98AFAA302B86A4064ADCB
+20220714111958 2 6 100 3071 2 C60003BD3BEA8A30306CD503D00EFB4ED2BF6A45DEA568495ABAF8D2D53A1E0BA1D2C2D3648219C03F47CD52B677D72316114A3882A8A3EB62C4F002DB326C27811A36E332D121EE420DDDF830741F14AA96AC0D2AEB5A80BF31CD18D4E3C02A22BD1986A906EEC3D635669FF26DD25A73FD7650666B101D6C42B0A58D96331E0666C990B56E4F0A5649C76FC7BA599A6DBE245F3A2F16AA4A9216B3AFAA93FE40BBB1149A657C934EC408C063B7130027EF7624C721931FECB563EF32C68E9C275A6A9F8BBF5428CBAED0987CD0EB4BF1BF7AC6F33C37FD88C7A026ABD735F0CD7395A4A22DB22B26C78823FB3BDC98150A82573259E64F407A2B3C017D2E9933E64EF5DDABDD3E748D507D21FF4F7B3450F2640E51DF3993B067DB952F8CD179BE389000934363E209ACF6235D1E9D07D3B0E865C4F9EA6EEB91D2B46B8032B2A3890E4DCA5905E269BD5BF2810548243F13FB13691E5346533538503C9CAA0E56DBE759C182BD04663461B435B8D7A20D69DE33D98AFAA302B86A4087EDCB
+20220714112015 2 6 100 3071 5 C60003BD3BEA8A30306CD503D00EFB4ED2BF6A45DEA568495ABAF8D2D53A1E0BA1D2C2D3648219C03F47CD52B677D72316114A3882A8A3EB62C4F002DB326C27811A36E332D121EE420DDDF830741F14AA96AC0D2AEB5A80BF31CD18D4E3C02A22BD1986A906EEC3D635669FF26DD25A73FD7650666B101D6C42B0A58D96331E0666C990B56E4F0A5649C76FC7BA599A6DBE245F3A2F16AA4A9216B3AFAA93FE40BBB1149A657C934EC408C063B7130027EF7624C721931FECB563EF32C68E9C275A6A9F8BBF5428CBAED0987CD0EB4BF1BF7AC6F33C37FD88C7A026ABD735F0CD7395A4A22DB22B26C78823FB3BDC98150A82573259E64F407A2B3C017D2E9933E64EF5DDABDD3E748D507D21FF4F7B3450F2640E51DF3993B067DB952F8CD179BE389000934363E209ACF6235D1E9D07D3B0E865C4F9EA6EEB91D2B46B8032B2A3890E4DCA5905E269BD5BF2810548243F13FB13691E5346533538503C9CAA0E56DBE759C182BD04663461B435B8D7A20D69DE33D98AFAA302B86A40C3D9C7
+20220714112026 2 6 100 3071 5 C60003BD3BEA8A30306CD503D00EFB4ED2BF6A45DEA568495ABAF8D2D53A1E0BA1D2C2D3648219C03F47CD52B677D72316114A3882A8A3EB62C4F002DB326C27811A36E332D121EE420DDDF830741F14AA96AC0D2AEB5A80BF31CD18D4E3C02A22BD1986A906EEC3D635669FF26DD25A73FD7650666B101D6C42B0A58D96331E0666C990B56E4F0A5649C76FC7BA599A6DBE245F3A2F16AA4A9216B3AFAA93FE40BBB1149A657C934EC408C063B7130027EF7624C721931FECB563EF32C68E9C275A6A9F8BBF5428CBAED0987CD0EB4BF1BF7AC6F33C37FD88C7A026ABD735F0CD7395A4A22DB22B26C78823FB3BDC98150A82573259E64F407A2B3C017D2E9933E64EF5DDABDD3E748D507D21FF4F7B3450F2640E51DF3993B067DB952F8CD179BE389000934363E209ACF6235D1E9D07D3B0E865C4F9EA6EEB91D2B46B8032B2A3890E4DCA5905E269BD5BF2810548243F13FB13691E5346533538503C9CAA0E56DBE759C182BD04663461B435B8D7A20D69DE33D98AFAA302B86A40EBD6CF
+20220714112102 2 6 100 3071 2 C60003BD3BEA8A30306CD503D00EFB4ED2BF6A45DEA568495ABAF8D2D53A1E0BA1D2C2D3648219C03F47CD52B677D72316114A3882A8A3EB62C4F002DB326C27811A36E332D121EE420DDDF830741F14AA96AC0D2AEB5A80BF31CD18D4E3C02A22BD1986A906EEC3D635669FF26DD25A73FD7650666B101D6C42B0A58D96331E0666C990B56E4F0A5649C76FC7BA599A6DBE245F3A2F16AA4A9216B3AFAA93FE40BBB1149A657C934EC408C063B7130027EF7624C721931FECB563EF32C68E9C275A6A9F8BBF5428CBAED0987CD0EB4BF1BF7AC6F33C37FD88C7A026ABD735F0CD7395A4A22DB22B26C78823FB3BDC98150A82573259E64F407A2B3C017D2E9933E64EF5DDABDD3E748D507D21FF4F7B3450F2640E51DF3993B067DB952F8CD179BE389000934363E209ACF6235D1E9D07D3B0E865C4F9EA6EEB91D2B46B8032B2A3890E4DCA5905E269BD5BF2810548243F13FB13691E5346533538503C9CAA0E56DBE759C182BD04663461B435B8D7A20D69DE33D98AFAA302B86A416BB97B
+20220714112247 2 6 100 3071 2 C60003BD3BEA8A30306CD503D00EFB4ED2BF6A45DEA568495ABAF8D2D53A1E0BA1D2C2D3648219C03F47CD52B677D72316114A3882A8A3EB62C4F002DB326C27811A36E332D121EE420DDDF830741F14AA96AC0D2AEB5A80BF31CD18D4E3C02A22BD1986A906EEC3D635669FF26DD25A73FD7650666B101D6C42B0A58D96331E0666C990B56E4F0A5649C76FC7BA599A6DBE245F3A2F16AA4A9216B3AFAA93FE40BBB1149A657C934EC408C063B7130027EF7624C721931FECB563EF32C68E9C275A6A9F8BBF5428CBAED0987CD0EB4BF1BF7AC6F33C37FD88C7A026ABD735F0CD7395A4A22DB22B26C78823FB3BDC98150A82573259E64F407A2B3C017D2E9933E64EF5DDABDD3E748D507D21FF4F7B3450F2640E51DF3993B067DB952F8CD179BE389000934363E209ACF6235D1E9D07D3B0E865C4F9EA6EEB91D2B46B8032B2A3890E4DCA5905E269BD5BF2810548243F13FB13691E5346533538503C9CAA0E56DBE759C182BD04663461B435B8D7A20D69DE33D98AFAA302B86A42DDD67B
+20220714112248 2 6 100 3071 5 C60003BD3BEA8A30306CD503D00EFB4ED2BF6A45DEA568495ABAF8D2D53A1E0BA1D2C2D3648219C03F47CD52B677D72316114A3882A8A3EB62C4F002DB326C27811A36E332D121EE420DDDF830741F14AA96AC0D2AEB5A80BF31CD18D4E3C02A22BD1986A906EEC3D635669FF26DD25A73FD7650666B101D6C42B0A58D96331E0666C990B56E4F0A5649C76FC7BA599A6DBE245F3A2F16AA4A9216B3AFAA93FE40BBB1149A657C934EC408C063B7130027EF7624C721931FECB563EF32C68E9C275A6A9F8BBF5428CBAED0987CD0EB4BF1BF7AC6F33C37FD88C7A026ABD735F0CD7395A4A22DB22B26C78823FB3BDC98150A82573259E64F407A2B3C017D2E9933E64EF5DDABDD3E748D507D21FF4F7B3450F2640E51DF3993B067DB952F8CD179BE389000934363E209ACF6235D1E9D07D3B0E865C4F9EA6EEB91D2B46B8032B2A3890E4DCA5905E269BD5BF2810548243F13FB13691E5346533538503C9CAA0E56DBE759C182BD04663461B435B8D7A20D69DE33D98AFAA302B86A42DFEABF
+20220714112340 2 6 100 3071 2 C60003BD3BEA8A30306CD503D00EFB4ED2BF6A45DEA568495ABAF8D2D53A1E0BA1D2C2D3648219C03F47CD52B677D72316114A3882A8A3EB62C4F002DB326C27811A36E332D121EE420DDDF830741F14AA96AC0D2AEB5A80BF31CD18D4E3C02A22BD1986A906EEC3D635669FF26DD25A73FD7650666B101D6C42B0A58D96331E0666C990B56E4F0A5649C76FC7BA599A6DBE245F3A2F16AA4A9216B3AFAA93FE40BBB1149A657C934EC408C063B7130027EF7624C721931FECB563EF32C68E9C275A6A9F8BBF5428CBAED0987CD0EB4BF1BF7AC6F33C37FD88C7A026ABD735F0CD7395A4A22DB22B26C78823FB3BDC98150A82573259E64F407A2B3C017D2E9933E64EF5DDABDD3E748D507D21FF4F7B3450F2640E51DF3993B067DB952F8CD179BE389000934363E209ACF6235D1E9D07D3B0E865C4F9EA6EEB91D2B46B8032B2A3890E4DCA5905E269BD5BF2810548243F13FB13691E5346533538503C9CAA0E56DBE759C182BD04663461B435B8D7A20D69DE33D98AFAA302B86A439694EB
+20220714112353 2 6 100 3071 2 C60003BD3BEA8A30306CD503D00EFB4ED2BF6A45DEA568495ABAF8D2D53A1E0BA1D2C2D3648219C03F47CD52B677D72316114A3882A8A3EB62C4F002DB326C27811A36E332D121EE420DDDF830741F14AA96AC0D2AEB5A80BF31CD18D4E3C02A22BD1986A906EEC3D635669FF26DD25A73FD7650666B101D6C42B0A58D96331E0666C990B56E4F0A5649C76FC7BA599A6DBE245F3A2F16AA4A9216B3AFAA93FE40BBB1149A657C934EC408C063B7130027EF7624C721931FECB563EF32C68E9C275A6A9F8BBF5428CBAED0987CD0EB4BF1BF7AC6F33C37FD88C7A026ABD735F0CD7395A4A22DB22B26C78823FB3BDC98150A82573259E64F407A2B3C017D2E9933E64EF5DDABDD3E748D507D21FF4F7B3450F2640E51DF3993B067DB952F8CD179BE389000934363E209ACF6235D1E9D07D3B0E865C4F9EA6EEB91D2B46B8032B2A3890E4DCA5905E269BD5BF2810548243F13FB13691E5346533538503C9CAA0E56DBE759C182BD04663461B435B8D7A20D69DE33D98AFAA302B86A43C65423
+20220714112428 2 6 100 3071 2 C60003BD3BEA8A30306CD503D00EFB4ED2BF6A45DEA568495ABAF8D2D53A1E0BA1D2C2D3648219C03F47CD52B677D72316114A3882A8A3EB62C4F002DB326C27811A36E332D121EE420DDDF830741F14AA96AC0D2AEB5A80BF31CD18D4E3C02A22BD1986A906EEC3D635669FF26DD25A73FD7650666B101D6C42B0A58D96331E0666C990B56E4F0A5649C76FC7BA599A6DBE245F3A2F16AA4A9216B3AFAA93FE40BBB1149A657C934EC408C063B7130027EF7624C721931FECB563EF32C68E9C275A6A9F8BBF5428CBAED0987CD0EB4BF1BF7AC6F33C37FD88C7A026ABD735F0CD7395A4A22DB22B26C78823FB3BDC98150A82573259E64F407A2B3C017D2E9933E64EF5DDABDD3E748D507D21FF4F7B3450F2640E51DF3993B067DB952F8CD179BE389000934363E209ACF6235D1E9D07D3B0E865C4F9EA6EEB91D2B46B8032B2A3890E4DCA5905E269BD5BF2810548243F13FB13691E5346533538503C9CAA0E56DBE759C182BD04663461B435B8D7A20D69DE33D98AFAA302B86A4444AE0B
+20220714112507 2 6 100 3071 5 C60003BD3BEA8A30306CD503D00EFB4ED2BF6A45DEA568495ABAF8D2D53A1E0BA1D2C2D3648219C03F47CD52B677D72316114A3882A8A3EB62C4F002DB326C27811A36E332D121EE420DDDF830741F14AA96AC0D2AEB5A80BF31CD18D4E3C02A22BD1986A906EEC3D635669FF26DD25A73FD7650666B101D6C42B0A58D96331E0666C990B56E4F0A5649C76FC7BA599A6DBE245F3A2F16AA4A9216B3AFAA93FE40BBB1149A657C934EC408C063B7130027EF7624C721931FECB563EF32C68E9C275A6A9F8BBF5428CBAED0987CD0EB4BF1BF7AC6F33C37FD88C7A026ABD735F0CD7395A4A22DB22B26C78823FB3BDC98150A82573259E64F407A2B3C017D2E9933E64EF5DDABDD3E748D507D21FF4F7B3450F2640E51DF3993B067DB952F8CD179BE389000934363E209ACF6235D1E9D07D3B0E865C4F9EA6EEB91D2B46B8032B2A3890E4DCA5905E269BD5BF2810548243F13FB13691E5346533538503C9CAA0E56DBE759C182BD04663461B435B8D7A20D69DE33D98AFAA302B86A44D48CFF
+20220714112511 2 6 100 3071 2 C60003BD3BEA8A30306CD503D00EFB4ED2BF6A45DEA568495ABAF8D2D53A1E0BA1D2C2D3648219C03F47CD52B677D72316114A3882A8A3EB62C4F002DB326C27811A36E332D121EE420DDDF830741F14AA96AC0D2AEB5A80BF31CD18D4E3C02A22BD1986A906EEC3D635669FF26DD25A73FD7650666B101D6C42B0A58D96331E0666C990B56E4F0A5649C76FC7BA599A6DBE245F3A2F16AA4A9216B3AFAA93FE40BBB1149A657C934EC408C063B7130027EF7624C721931FECB563EF32C68E9C275A6A9F8BBF5428CBAED0987CD0EB4BF1BF7AC6F33C37FD88C7A026ABD735F0CD7395A4A22DB22B26C78823FB3BDC98150A82573259E64F407A2B3C017D2E9933E64EF5DDABDD3E748D507D21FF4F7B3450F2640E51DF3993B067DB952F8CD179BE389000934363E209ACF6235D1E9D07D3B0E865C4F9EA6EEB91D2B46B8032B2A3890E4DCA5905E269BD5BF2810548243F13FB13691E5346533538503C9CAA0E56DBE759C182BD04663461B435B8D7A20D69DE33D98AFAA302B86A44DEBF3B
+20220714112549 2 6 100 3071 5 C60003BD3BEA8A30306CD503D00EFB4ED2BF6A45DEA568495ABAF8D2D53A1E0BA1D2C2D3648219C03F47CD52B677D72316114A3882A8A3EB62C4F002DB326C27811A36E332D121EE420DDDF830741F14AA96AC0D2AEB5A80BF31CD18D4E3C02A22BD1986A906EEC3D635669FF26DD25A73FD7650666B101D6C42B0A58D96331E0666C990B56E4F0A5649C76FC7BA599A6DBE245F3A2F16AA4A9216B3AFAA93FE40BBB1149A657C934EC408C063B7130027EF7624C721931FECB563EF32C68E9C275A6A9F8BBF5428CBAED0987CD0EB4BF1BF7AC6F33C37FD88C7A026ABD735F0CD7395A4A22DB22B26C78823FB3BDC98150A82573259E64F407A2B3C017D2E9933E64EF5DDABDD3E748D507D21FF4F7B3450F2640E51DF3993B067DB952F8CD179BE389000934363E209ACF6235D1E9D07D3B0E865C4F9EA6EEB91D2B46B8032B2A3890E4DCA5905E269BD5BF2810548243F13FB13691E5346533538503C9CAA0E56DBE759C182BD04663461B435B8D7A20D69DE33D98AFAA302B86A456724A7
+20220714112651 2 6 100 3071 5 C60003BD3BEA8A30306CD503D00EFB4ED2BF6A45DEA568495ABAF8D2D53A1E0BA1D2C2D3648219C03F47CD52B677D72316114A3882A8A3EB62C4F002DB326C27811A36E332D121EE420DDDF830741F14AA96AC0D2AEB5A80BF31CD18D4E3C02A22BD1986A906EEC3D635669FF26DD25A73FD7650666B101D6C42B0A58D96331E0666C990B56E4F0A5649C76FC7BA599A6DBE245F3A2F16AA4A9216B3AFAA93FE40BBB1149A657C934EC408C063B7130027EF7624C721931FECB563EF32C68E9C275A6A9F8BBF5428CBAED0987CD0EB4BF1BF7AC6F33C37FD88C7A026ABD735F0CD7395A4A22DB22B26C78823FB3BDC98150A82573259E64F407A2B3C017D2E9933E64EF5DDABDD3E748D507D21FF4F7B3450F2640E51DF3993B067DB952F8CD179BE389000934363E209ACF6235D1E9D07D3B0E865C4F9EA6EEB91D2B46B8032B2A3890E4DCA5905E269BD5BF2810548243F13FB13691E5346533538503C9CAA0E56DBE759C182BD04663461B435B8D7A20D69DE33D98AFAA302B86A464873DF
+20220714112736 2 6 100 3071 2 C60003BD3BEA8A30306CD503D00EFB4ED2BF6A45DEA568495ABAF8D2D53A1E0BA1D2C2D3648219C03F47CD52B677D72316114A3882A8A3EB62C4F002DB326C27811A36E332D121EE420DDDF830741F14AA96AC0D2AEB5A80BF31CD18D4E3C02A22BD1986A906EEC3D635669FF26DD25A73FD7650666B101D6C42B0A58D96331E0666C990B56E4F0A5649C76FC7BA599A6DBE245F3A2F16AA4A9216B3AFAA93FE40BBB1149A657C934EC408C063B7130027EF7624C721931FECB563EF32C68E9C275A6A9F8BBF5428CBAED0987CD0EB4BF1BF7AC6F33C37FD88C7A026ABD735F0CD7395A4A22DB22B26C78823FB3BDC98150A82573259E64F407A2B3C017D2E9933E64EF5DDABDD3E748D507D21FF4F7B3450F2640E51DF3993B067DB952F8CD179BE389000934363E209ACF6235D1E9D07D3B0E865C4F9EA6EEB91D2B46B8032B2A3890E4DCA5905E269BD5BF2810548243F13FB13691E5346533538503C9CAA0E56DBE759C182BD04663461B435B8D7A20D69DE33D98AFAA302B86A46EA45CB
+20220714112754 2 6 100 3071 2 C60003BD3BEA8A30306CD503D00EFB4ED2BF6A45DEA568495ABAF8D2D53A1E0BA1D2C2D3648219C03F47CD52B677D72316114A3882A8A3EB62C4F002DB326C27811A36E332D121EE420DDDF830741F14AA96AC0D2AEB5A80BF31CD18D4E3C02A22BD1986A906EEC3D635669FF26DD25A73FD7650666B101D6C42B0A58D96331E0666C990B56E4F0A5649C76FC7BA599A6DBE245F3A2F16AA4A9216B3AFAA93FE40BBB1149A657C934EC408C063B7130027EF7624C721931FECB563EF32C68E9C275A6A9F8BBF5428CBAED0987CD0EB4BF1BF7AC6F33C37FD88C7A026ABD735F0CD7395A4A22DB22B26C78823FB3BDC98150A82573259E64F407A2B3C017D2E9933E64EF5DDABDD3E748D507D21FF4F7B3450F2640E51DF3993B067DB952F8CD179BE389000934363E209ACF6235D1E9D07D3B0E865C4F9EA6EEB91D2B46B8032B2A3890E4DCA5905E269BD5BF2810548243F13FB13691E5346533538503C9CAA0E56DBE759C182BD04663461B435B8D7A20D69DE33D98AFAA302B86A47292543
+20220714112800 2 6 100 3071 2 C60003BD3BEA8A30306CD503D00EFB4ED2BF6A45DEA568495ABAF8D2D53A1E0BA1D2C2D3648219C03F47CD52B677D72316114A3882A8A3EB62C4F002DB326C27811A36E332D121EE420DDDF830741F14AA96AC0D2AEB5A80BF31CD18D4E3C02A22BD1986A906EEC3D635669FF26DD25A73FD7650666B101D6C42B0A58D96331E0666C990B56E4F0A5649C76FC7BA599A6DBE245F3A2F16AA4A9216B3AFAA93FE40BBB1149A657C934EC408C063B7130027EF7624C721931FECB563EF32C68E9C275A6A9F8BBF5428CBAED0987CD0EB4BF1BF7AC6F33C37FD88C7A026ABD735F0CD7395A4A22DB22B26C78823FB3BDC98150A82573259E64F407A2B3C017D2E9933E64EF5DDABDD3E748D507D21FF4F7B3450F2640E51DF3993B067DB952F8CD179BE389000934363E209ACF6235D1E9D07D3B0E865C4F9EA6EEB91D2B46B8032B2A3890E4DCA5905E269BD5BF2810548243F13FB13691E5346533538503C9CAA0E56DBE759C182BD04663461B435B8D7A20D69DE33D98AFAA302B86A4741F39B
+20220714112844 2 6 100 3071 5 C60003BD3BEA8A30306CD503D00EFB4ED2BF6A45DEA568495ABAF8D2D53A1E0BA1D2C2D3648219C03F47CD52B677D72316114A3882A8A3EB62C4F002DB326C27811A36E332D121EE420DDDF830741F14AA96AC0D2AEB5A80BF31CD18D4E3C02A22BD1986A906EEC3D635669FF26DD25A73FD7650666B101D6C42B0A58D96331E0666C990B56E4F0A5649C76FC7BA599A6DBE245F3A2F16AA4A9216B3AFAA93FE40BBB1149A657C934EC408C063B7130027EF7624C721931FECB563EF32C68E9C275A6A9F8BBF5428CBAED0987CD0EB4BF1BF7AC6F33C37FD88C7A026ABD735F0CD7395A4A22DB22B26C78823FB3BDC98150A82573259E64F407A2B3C017D2E9933E64EF5DDABDD3E748D507D21FF4F7B3450F2640E51DF3993B067DB952F8CD179BE389000934363E209ACF6235D1E9D07D3B0E865C4F9EA6EEB91D2B46B8032B2A3890E4DCA5905E269BD5BF2810548243F13FB13691E5346533538503C9CAA0E56DBE759C182BD04663461B435B8D7A20D69DE33D98AFAA302B86A47E12BFF
+20220714112924 2 6 100 3071 5 C60003BD3BEA8A30306CD503D00EFB4ED2BF6A45DEA568495ABAF8D2D53A1E0BA1D2C2D3648219C03F47CD52B677D72316114A3882A8A3EB62C4F002DB326C27811A36E332D121EE420DDDF830741F14AA96AC0D2AEB5A80BF31CD18D4E3C02A22BD1986A906EEC3D635669FF26DD25A73FD7650666B101D6C42B0A58D96331E0666C990B56E4F0A5649C76FC7BA599A6DBE245F3A2F16AA4A9216B3AFAA93FE40BBB1149A657C934EC408C063B7130027EF7624C721931FECB563EF32C68E9C275A6A9F8BBF5428CBAED0987CD0EB4BF1BF7AC6F33C37FD88C7A026ABD735F0CD7395A4A22DB22B26C78823FB3BDC98150A82573259E64F407A2B3C017D2E9933E64EF5DDABDD3E748D507D21FF4F7B3450F2640E51DF3993B067DB952F8CD179BE389000934363E209ACF6235D1E9D07D3B0E865C4F9EA6EEB91D2B46B8032B2A3890E4DCA5905E269BD5BF2810548243F13FB13691E5346533538503C9CAA0E56DBE759C182BD04663461B435B8D7A20D69DE33D98AFAA302B86A486E93AF
+20220714112931 2 6 100 3071 2 C60003BD3BEA8A30306CD503D00EFB4ED2BF6A45DEA568495ABAF8D2D53A1E0BA1D2C2D3648219C03F47CD52B677D72316114A3882A8A3EB62C4F002DB326C27811A36E332D121EE420DDDF830741F14AA96AC0D2AEB5A80BF31CD18D4E3C02A22BD1986A906EEC3D635669FF26DD25A73FD7650666B101D6C42B0A58D96331E0666C990B56E4F0A5649C76FC7BA599A6DBE245F3A2F16AA4A9216B3AFAA93FE40BBB1149A657C934EC408C063B7130027EF7624C721931FECB563EF32C68E9C275A6A9F8BBF5428CBAED0987CD0EB4BF1BF7AC6F33C37FD88C7A026ABD735F0CD7395A4A22DB22B26C78823FB3BDC98150A82573259E64F407A2B3C017D2E9933E64EF5DDABDD3E748D507D21FF4F7B3450F2640E51DF3993B067DB952F8CD179BE389000934363E209ACF6235D1E9D07D3B0E865C4F9EA6EEB91D2B46B8032B2A3890E4DCA5905E269BD5BF2810548243F13FB13691E5346533538503C9CAA0E56DBE759C182BD04663461B435B8D7A20D69DE33D98AFAA302B86A4887FCAB
+20220714112951 2 6 100 3071 5 C60003BD3BEA8A30306CD503D00EFB4ED2BF6A45DEA568495ABAF8D2D53A1E0BA1D2C2D3648219C03F47CD52B677D72316114A3882A8A3EB62C4F002DB326C27811A36E332D121EE420DDDF830741F14AA96AC0D2AEB5A80BF31CD18D4E3C02A22BD1986A906EEC3D635669FF26DD25A73FD7650666B101D6C42B0A58D96331E0666C990B56E4F0A5649C76FC7BA599A6DBE245F3A2F16AA4A9216B3AFAA93FE40BBB1149A657C934EC408C063B7130027EF7624C721931FECB563EF32C68E9C275A6A9F8BBF5428CBAED0987CD0EB4BF1BF7AC6F33C37FD88C7A026ABD735F0CD7395A4A22DB22B26C78823FB3BDC98150A82573259E64F407A2B3C017D2E9933E64EF5DDABDD3E748D507D21FF4F7B3450F2640E51DF3993B067DB952F8CD179BE389000934363E209ACF6235D1E9D07D3B0E865C4F9EA6EEB91D2B46B8032B2A3890E4DCA5905E269BD5BF2810548243F13FB13691E5346533538503C9CAA0E56DBE759C182BD04663461B435B8D7A20D69DE33D98AFAA302B86A48CAB4D7
+20220714113009 2 6 100 3071 5 C60003BD3BEA8A30306CD503D00EFB4ED2BF6A45DEA568495ABAF8D2D53A1E0BA1D2C2D3648219C03F47CD52B677D72316114A3882A8A3EB62C4F002DB326C27811A36E332D121EE420DDDF830741F14AA96AC0D2AEB5A80BF31CD18D4E3C02A22BD1986A906EEC3D635669FF26DD25A73FD7650666B101D6C42B0A58D96331E0666C990B56E4F0A5649C76FC7BA599A6DBE245F3A2F16AA4A9216B3AFAA93FE40BBB1149A657C934EC408C063B7130027EF7624C721931FECB563EF32C68E9C275A6A9F8BBF5428CBAED0987CD0EB4BF1BF7AC6F33C37FD88C7A026ABD735F0CD7395A4A22DB22B26C78823FB3BDC98150A82573259E64F407A2B3C017D2E9933E64EF5DDABDD3E748D507D21FF4F7B3450F2640E51DF3993B067DB952F8CD179BE389000934363E209ACF6235D1E9D07D3B0E865C4F9EA6EEB91D2B46B8032B2A3890E4DCA5905E269BD5BF2810548243F13FB13691E5346533538503C9CAA0E56DBE759C182BD04663461B435B8D7A20D69DE33D98AFAA302B86A4908F30F
+20220714113024 2 6 100 3071 5 C60003BD3BEA8A30306CD503D00EFB4ED2BF6A45DEA568495ABAF8D2D53A1E0BA1D2C2D3648219C03F47CD52B677D72316114A3882A8A3EB62C4F002DB326C27811A36E332D121EE420DDDF830741F14AA96AC0D2AEB5A80BF31CD18D4E3C02A22BD1986A906EEC3D635669FF26DD25A73FD7650666B101D6C42B0A58D96331E0666C990B56E4F0A5649C76FC7BA599A6DBE245F3A2F16AA4A9216B3AFAA93FE40BBB1149A657C934EC408C063B7130027EF7624C721931FECB563EF32C68E9C275A6A9F8BBF5428CBAED0987CD0EB4BF1BF7AC6F33C37FD88C7A026ABD735F0CD7395A4A22DB22B26C78823FB3BDC98150A82573259E64F407A2B3C017D2E9933E64EF5DDABDD3E748D507D21FF4F7B3450F2640E51DF3993B067DB952F8CD179BE389000934363E209ACF6235D1E9D07D3B0E865C4F9EA6EEB91D2B46B8032B2A3890E4DCA5905E269BD5BF2810548243F13FB13691E5346533538503C9CAA0E56DBE759C182BD04663461B435B8D7A20D69DE33D98AFAA302B86A4942A64F
+20220714113032 2 6 100 3071 2 C60003BD3BEA8A30306CD503D00EFB4ED2BF6A45DEA568495ABAF8D2D53A1E0BA1D2C2D3648219C03F47CD52B677D72316114A3882A8A3EB62C4F002DB326C27811A36E332D121EE420DDDF830741F14AA96AC0D2AEB5A80BF31CD18D4E3C02A22BD1986A906EEC3D635669FF26DD25A73FD7650666B101D6C42B0A58D96331E0666C990B56E4F0A5649C76FC7BA599A6DBE245F3A2F16AA4A9216B3AFAA93FE40BBB1149A657C934EC408C063B7130027EF7624C721931FECB563EF32C68E9C275A6A9F8BBF5428CBAED0987CD0EB4BF1BF7AC6F33C37FD88C7A026ABD735F0CD7395A4A22DB22B26C78823FB3BDC98150A82573259E64F407A2B3C017D2E9933E64EF5DDABDD3E748D507D21FF4F7B3450F2640E51DF3993B067DB952F8CD179BE389000934363E209ACF6235D1E9D07D3B0E865C4F9EA6EEB91D2B46B8032B2A3890E4DCA5905E269BD5BF2810548243F13FB13691E5346533538503C9CAA0E56DBE759C182BD04663461B435B8D7A20D69DE33D98AFAA302B86A495DA0A3
+20220714113137 2 6 100 3071 2 C60003BD3BEA8A30306CD503D00EFB4ED2BF6A45DEA568495ABAF8D2D53A1E0BA1D2C2D3648219C03F47CD52B677D72316114A3882A8A3EB62C4F002DB326C27811A36E332D121EE420DDDF830741F14AA96AC0D2AEB5A80BF31CD18D4E3C02A22BD1986A906EEC3D635669FF26DD25A73FD7650666B101D6C42B0A58D96331E0666C990B56E4F0A5649C76FC7BA599A6DBE245F3A2F16AA4A9216B3AFAA93FE40BBB1149A657C934EC408C063B7130027EF7624C721931FECB563EF32C68E9C275A6A9F8BBF5428CBAED0987CD0EB4BF1BF7AC6F33C37FD88C7A026ABD735F0CD7395A4A22DB22B26C78823FB3BDC98150A82573259E64F407A2B3C017D2E9933E64EF5DDABDD3E748D507D21FF4F7B3450F2640E51DF3993B067DB952F8CD179BE389000934363E209ACF6235D1E9D07D3B0E865C4F9EA6EEB91D2B46B8032B2A3890E4DCA5905E269BD5BF2810548243F13FB13691E5346533538503C9CAA0E56DBE759C182BD04663461B435B8D7A20D69DE33D98AFAA302B86A4A48C463
+20220714113138 2 6 100 3071 2 C60003BD3BEA8A30306CD503D00EFB4ED2BF6A45DEA568495ABAF8D2D53A1E0BA1D2C2D3648219C03F47CD52B677D72316114A3882A8A3EB62C4F002DB326C27811A36E332D121EE420DDDF830741F14AA96AC0D2AEB5A80BF31CD18D4E3C02A22BD1986A906EEC3D635669FF26DD25A73FD7650666B101D6C42B0A58D96331E0666C990B56E4F0A5649C76FC7BA599A6DBE245F3A2F16AA4A9216B3AFAA93FE40BBB1149A657C934EC408C063B7130027EF7624C721931FECB563EF32C68E9C275A6A9F8BBF5428CBAED0987CD0EB4BF1BF7AC6F33C37FD88C7A026ABD735F0CD7395A4A22DB22B26C78823FB3BDC98150A82573259E64F407A2B3C017D2E9933E64EF5DDABDD3E748D507D21FF4F7B3450F2640E51DF3993B067DB952F8CD179BE389000934363E209ACF6235D1E9D07D3B0E865C4F9EA6EEB91D2B46B8032B2A3890E4DCA5905E269BD5BF2810548243F13FB13691E5346533538503C9CAA0E56DBE759C182BD04663461B435B8D7A20D69DE33D98AFAA302B86A4A4AD4C3
+20220714113152 2 6 100 3071 2 C60003BD3BEA8A30306CD503D00EFB4ED2BF6A45DEA568495ABAF8D2D53A1E0BA1D2C2D3648219C03F47CD52B677D72316114A3882A8A3EB62C4F002DB326C27811A36E332D121EE420DDDF830741F14AA96AC0D2AEB5A80BF31CD18D4E3C02A22BD1986A906EEC3D635669FF26DD25A73FD7650666B101D6C42B0A58D96331E0666C990B56E4F0A5649C76FC7BA599A6DBE245F3A2F16AA4A9216B3AFAA93FE40BBB1149A657C934EC408C063B7130027EF7624C721931FECB563EF32C68E9C275A6A9F8BBF5428CBAED0987CD0EB4BF1BF7AC6F33C37FD88C7A026ABD735F0CD7395A4A22DB22B26C78823FB3BDC98150A82573259E64F407A2B3C017D2E9933E64EF5DDABDD3E748D507D21FF4F7B3450F2640E51DF3993B067DB952F8CD179BE389000934363E209ACF6235D1E9D07D3B0E865C4F9EA6EEB91D2B46B8032B2A3890E4DCA5905E269BD5BF2810548243F13FB13691E5346533538503C9CAA0E56DBE759C182BD04663461B435B8D7A20D69DE33D98AFAA302B86A4A7E9E6B
+20220714113302 2 6 100 3071 5 C60003BD3BEA8A30306CD503D00EFB4ED2BF6A45DEA568495ABAF8D2D53A1E0BA1D2C2D3648219C03F47CD52B677D72316114A3882A8A3EB62C4F002DB326C27811A36E332D121EE420DDDF830741F14AA96AC0D2AEB5A80BF31CD18D4E3C02A22BD1986A906EEC3D635669FF26DD25A73FD7650666B101D6C42B0A58D96331E0666C990B56E4F0A5649C76FC7BA599A6DBE245F3A2F16AA4A9216B3AFAA93FE40BBB1149A657C934EC408C063B7130027EF7624C721931FECB563EF32C68E9C275A6A9F8BBF5428CBAED0987CD0EB4BF1BF7AC6F33C37FD88C7A026ABD735F0CD7395A4A22DB22B26C78823FB3BDC98150A82573259E64F407A2B3C017D2E9933E64EF5DDABDD3E748D507D21FF4F7B3450F2640E51DF3993B067DB952F8CD179BE389000934363E209ACF6235D1E9D07D3B0E865C4F9EA6EEB91D2B46B8032B2A3890E4DCA5905E269BD5BF2810548243F13FB13691E5346533538503C9CAA0E56DBE759C182BD04663461B435B8D7A20D69DE33D98AFAA302B86A4B7771A7
+20220714113325 2 6 100 3071 5 C60003BD3BEA8A30306CD503D00EFB4ED2BF6A45DEA568495ABAF8D2D53A1E0BA1D2C2D3648219C03F47CD52B677D72316114A3882A8A3EB62C4F002DB326C27811A36E332D121EE420DDDF830741F14AA96AC0D2AEB5A80BF31CD18D4E3C02A22BD1986A906EEC3D635669FF26DD25A73FD7650666B101D6C42B0A58D96331E0666C990B56E4F0A5649C76FC7BA599A6DBE245F3A2F16AA4A9216B3AFAA93FE40BBB1149A657C934EC408C063B7130027EF7624C721931FECB563EF32C68E9C275A6A9F8BBF5428CBAED0987CD0EB4BF1BF7AC6F33C37FD88C7A026ABD735F0CD7395A4A22DB22B26C78823FB3BDC98150A82573259E64F407A2B3C017D2E9933E64EF5DDABDD3E748D507D21FF4F7B3450F2640E51DF3993B067DB952F8CD179BE389000934363E209ACF6235D1E9D07D3B0E865C4F9EA6EEB91D2B46B8032B2A3890E4DCA5905E269BD5BF2810548243F13FB13691E5346533538503C9CAA0E56DBE759C182BD04663461B435B8D7A20D69DE33D98AFAA302B86A4BCC7A67
+20220714113406 2 6 100 3071 2 C60003BD3BEA8A30306CD503D00EFB4ED2BF6A45DEA568495ABAF8D2D53A1E0BA1D2C2D3648219C03F47CD52B677D72316114A3882A8A3EB62C4F002DB326C27811A36E332D121EE420DDDF830741F14AA96AC0D2AEB5A80BF31CD18D4E3C02A22BD1986A906EEC3D635669FF26DD25A73FD7650666B101D6C42B0A58D96331E0666C990B56E4F0A5649C76FC7BA599A6DBE245F3A2F16AA4A9216B3AFAA93FE40BBB1149A657C934EC408C063B7130027EF7624C721931FECB563EF32C68E9C275A6A9F8BBF5428CBAED0987CD0EB4BF1BF7AC6F33C37FD88C7A026ABD735F0CD7395A4A22DB22B26C78823FB3BDC98150A82573259E64F407A2B3C017D2E9933E64EF5DDABDD3E748D507D21FF4F7B3450F2640E51DF3993B067DB952F8CD179BE389000934363E209ACF6235D1E9D07D3B0E865C4F9EA6EEB91D2B46B8032B2A3890E4DCA5905E269BD5BF2810548243F13FB13691E5346533538503C9CAA0E56DBE759C182BD04663461B435B8D7A20D69DE33D98AFAA302B86A4C5B14CB
+20220714113419 2 6 100 3071 2 C60003BD3BEA8A30306CD503D00EFB4ED2BF6A45DEA568495ABAF8D2D53A1E0BA1D2C2D3648219C03F47CD52B677D72316114A3882A8A3EB62C4F002DB326C27811A36E332D121EE420DDDF830741F14AA96AC0D2AEB5A80BF31CD18D4E3C02A22BD1986A906EEC3D635669FF26DD25A73FD7650666B101D6C42B0A58D96331E0666C990B56E4F0A5649C76FC7BA599A6DBE245F3A2F16AA4A9216B3AFAA93FE40BBB1149A657C934EC408C063B7130027EF7624C721931FECB563EF32C68E9C275A6A9F8BBF5428CBAED0987CD0EB4BF1BF7AC6F33C37FD88C7A026ABD735F0CD7395A4A22DB22B26C78823FB3BDC98150A82573259E64F407A2B3C017D2E9933E64EF5DDABDD3E748D507D21FF4F7B3450F2640E51DF3993B067DB952F8CD179BE389000934363E209ACF6235D1E9D07D3B0E865C4F9EA6EEB91D2B46B8032B2A3890E4DCA5905E269BD5BF2810548243F13FB13691E5346533538503C9CAA0E56DBE759C182BD04663461B435B8D7A20D69DE33D98AFAA302B86A4C8D693B
+20220714113438 2 6 100 3071 5 C60003BD3BEA8A30306CD503D00EFB4ED2BF6A45DEA568495ABAF8D2D53A1E0BA1D2C2D3648219C03F47CD52B677D72316114A3882A8A3EB62C4F002DB326C27811A36E332D121EE420DDDF830741F14AA96AC0D2AEB5A80BF31CD18D4E3C02A22BD1986A906EEC3D635669FF26DD25A73FD7650666B101D6C42B0A58D96331E0666C990B56E4F0A5649C76FC7BA599A6DBE245F3A2F16AA4A9216B3AFAA93FE40BBB1149A657C934EC408C063B7130027EF7624C721931FECB563EF32C68E9C275A6A9F8BBF5428CBAED0987CD0EB4BF1BF7AC6F33C37FD88C7A026ABD735F0CD7395A4A22DB22B26C78823FB3BDC98150A82573259E64F407A2B3C017D2E9933E64EF5DDABDD3E748D507D21FF4F7B3450F2640E51DF3993B067DB952F8CD179BE389000934363E209ACF6235D1E9D07D3B0E865C4F9EA6EEB91D2B46B8032B2A3890E4DCA5905E269BD5BF2810548243F13FB13691E5346533538503C9CAA0E56DBE759C182BD04663461B435B8D7A20D69DE33D98AFAA302B86A4CD38C17
+20220714113459 2 6 100 3071 2 C60003BD3BEA8A30306CD503D00EFB4ED2BF6A45DEA568495ABAF8D2D53A1E0BA1D2C2D3648219C03F47CD52B677D72316114A3882A8A3EB62C4F002DB326C27811A36E332D121EE420DDDF830741F14AA96AC0D2AEB5A80BF31CD18D4E3C02A22BD1986A906EEC3D635669FF26DD25A73FD7650666B101D6C42B0A58D96331E0666C990B56E4F0A5649C76FC7BA599A6DBE245F3A2F16AA4A9216B3AFAA93FE40BBB1149A657C934EC408C063B7130027EF7624C721931FECB563EF32C68E9C275A6A9F8BBF5428CBAED0987CD0EB4BF1BF7AC6F33C37FD88C7A026ABD735F0CD7395A4A22DB22B26C78823FB3BDC98150A82573259E64F407A2B3C017D2E9933E64EF5DDABDD3E748D507D21FF4F7B3450F2640E51DF3993B067DB952F8CD179BE389000934363E209ACF6235D1E9D07D3B0E865C4F9EA6EEB91D2B46B8032B2A3890E4DCA5905E269BD5BF2810548243F13FB13691E5346533538503C9CAA0E56DBE759C182BD04663461B435B8D7A20D69DE33D98AFAA302B86A4D1FD413
+20220714113606 2 6 100 3071 2 C60003BD3BEA8A30306CD503D00EFB4ED2BF6A45DEA568495ABAF8D2D53A1E0BA1D2C2D3648219C03F47CD52B677D72316114A3882A8A3EB62C4F002DB326C27811A36E332D121EE420DDDF830741F14AA96AC0D2AEB5A80BF31CD18D4E3C02A22BD1986A906EEC3D635669FF26DD25A73FD7650666B101D6C42B0A58D96331E0666C990B56E4F0A5649C76FC7BA599A6DBE245F3A2F16AA4A9216B3AFAA93FE40BBB1149A657C934EC408C063B7130027EF7624C721931FECB563EF32C68E9C275A6A9F8BBF5428CBAED0987CD0EB4BF1BF7AC6F33C37FD88C7A026ABD735F0CD7395A4A22DB22B26C78823FB3BDC98150A82573259E64F407A2B3C017D2E9933E64EF5DDABDD3E748D507D21FF4F7B3450F2640E51DF3993B067DB952F8CD179BE389000934363E209ACF6235D1E9D07D3B0E865C4F9EA6EEB91D2B46B8032B2A3890E4DCA5905E269BD5BF2810548243F13FB13691E5346533538503C9CAA0E56DBE759C182BD04663461B435B8D7A20D69DE33D98AFAA302B86A4E11131B
+20220714113620 2 6 100 3071 2 C60003BD3BEA8A30306CD503D00EFB4ED2BF6A45DEA568495ABAF8D2D53A1E0BA1D2C2D3648219C03F47CD52B677D72316114A3882A8A3EB62C4F002DB326C27811A36E332D121EE420DDDF830741F14AA96AC0D2AEB5A80BF31CD18D4E3C02A22BD1986A906EEC3D635669FF26DD25A73FD7650666B101D6C42B0A58D96331E0666C990B56E4F0A5649C76FC7BA599A6DBE245F3A2F16AA4A9216B3AFAA93FE40BBB1149A657C934EC408C063B7130027EF7624C721931FECB563EF32C68E9C275A6A9F8BBF5428CBAED0987CD0EB4BF1BF7AC6F33C37FD88C7A026ABD735F0CD7395A4A22DB22B26C78823FB3BDC98150A82573259E64F407A2B3C017D2E9933E64EF5DDABDD3E748D507D21FF4F7B3450F2640E51DF3993B067DB952F8CD179BE389000934363E209ACF6235D1E9D07D3B0E865C4F9EA6EEB91D2B46B8032B2A3890E4DCA5905E269BD5BF2810548243F13FB13691E5346533538503C9CAA0E56DBE759C182BD04663461B435B8D7A20D69DE33D98AFAA302B86A4E407DDB
+20220714113639 2 6 100 3071 5 C60003BD3BEA8A30306CD503D00EFB4ED2BF6A45DEA568495ABAF8D2D53A1E0BA1D2C2D3648219C03F47CD52B677D72316114A3882A8A3EB62C4F002DB326C27811A36E332D121EE420DDDF830741F14AA96AC0D2AEB5A80BF31CD18D4E3C02A22BD1986A906EEC3D635669FF26DD25A73FD7650666B101D6C42B0A58D96331E0666C990B56E4F0A5649C76FC7BA599A6DBE245F3A2F16AA4A9216B3AFAA93FE40BBB1149A657C934EC408C063B7130027EF7624C721931FECB563EF32C68E9C275A6A9F8BBF5428CBAED0987CD0EB4BF1BF7AC6F33C37FD88C7A026ABD735F0CD7395A4A22DB22B26C78823FB3BDC98150A82573259E64F407A2B3C017D2E9933E64EF5DDABDD3E748D507D21FF4F7B3450F2640E51DF3993B067DB952F8CD179BE389000934363E209ACF6235D1E9D07D3B0E865C4F9EA6EEB91D2B46B8032B2A3890E4DCA5905E269BD5BF2810548243F13FB13691E5346533538503C9CAA0E56DBE759C182BD04663461B435B8D7A20D69DE33D98AFAA302B86A4E816DEF
+20220714113802 2 6 100 3071 2 C60003BD3BEA8A30306CD503D00EFB4ED2BF6A45DEA568495ABAF8D2D53A1E0BA1D2C2D3648219C03F47CD52B677D72316114A3882A8A3EB62C4F002DB326C27811A36E332D121EE420DDDF830741F14AA96AC0D2AEB5A80BF31CD18D4E3C02A22BD1986A906EEC3D635669FF26DD25A73FD7650666B101D6C42B0A58D96331E0666C990B56E4F0A5649C76FC7BA599A6DBE245F3A2F16AA4A9216B3AFAA93FE40BBB1149A657C934EC408C063B7130027EF7624C721931FECB563EF32C68E9C275A6A9F8BBF5428CBAED0987CD0EB4BF1BF7AC6F33C37FD88C7A026ABD735F0CD7395A4A22DB22B26C78823FB3BDC98150A82573259E64F407A2B3C017D2E9933E64EF5DDABDD3E748D507D21FF4F7B3450F2640E51DF3993B067DB952F8CD179BE389000934363E209ACF6235D1E9D07D3B0E865C4F9EA6EEB91D2B46B8032B2A3890E4DCA5905E269BD5BF2810548243F13FB13691E5346533538503C9CAA0E56DBE759C182BD04663461B435B8D7A20D69DE33D98AFAA302B86A4FA7B0BB
+20220714113835 2 6 100 3071 5 C60003BD3BEA8A30306CD503D00EFB4ED2BF6A45DEA568495ABAF8D2D53A1E0BA1D2C2D3648219C03F47CD52B677D72316114A3882A8A3EB62C4F002DB326C27811A36E332D121EE420DDDF830741F14AA96AC0D2AEB5A80BF31CD18D4E3C02A22BD1986A906EEC3D635669FF26DD25A73FD7650666B101D6C42B0A58D96331E0666C990B56E4F0A5649C76FC7BA599A6DBE245F3A2F16AA4A9216B3AFAA93FE40BBB1149A657C934EC408C063B7130027EF7624C721931FECB563EF32C68E9C275A6A9F8BBF5428CBAED0987CD0EB4BF1BF7AC6F33C37FD88C7A026ABD735F0CD7395A4A22DB22B26C78823FB3BDC98150A82573259E64F407A2B3C017D2E9933E64EF5DDABDD3E748D507D21FF4F7B3450F2640E51DF3993B067DB952F8CD179BE389000934363E209ACF6235D1E9D07D3B0E865C4F9EA6EEB91D2B46B8032B2A3890E4DCA5905E269BD5BF2810548243F13FB13691E5346533538503C9CAA0E56DBE759C182BD04663461B435B8D7A20D69DE33D98AFAA302B86A501BFD27
+20220714113901 2 6 100 3071 5 C60003BD3BEA8A30306CD503D00EFB4ED2BF6A45DEA568495ABAF8D2D53A1E0BA1D2C2D3648219C03F47CD52B677D72316114A3882A8A3EB62C4F002DB326C27811A36E332D121EE420DDDF830741F14AA96AC0D2AEB5A80BF31CD18D4E3C02A22BD1986A906EEC3D635669FF26DD25A73FD7650666B101D6C42B0A58D96331E0666C990B56E4F0A5649C76FC7BA599A6DBE245F3A2F16AA4A9216B3AFAA93FE40BBB1149A657C934EC408C063B7130027EF7624C721931FECB563EF32C68E9C275A6A9F8BBF5428CBAED0987CD0EB4BF1BF7AC6F33C37FD88C7A026ABD735F0CD7395A4A22DB22B26C78823FB3BDC98150A82573259E64F407A2B3C017D2E9933E64EF5DDABDD3E748D507D21FF4F7B3450F2640E51DF3993B067DB952F8CD179BE389000934363E209ACF6235D1E9D07D3B0E865C4F9EA6EEB91D2B46B8032B2A3890E4DCA5905E269BD5BF2810548243F13FB13691E5346533538503C9CAA0E56DBE759C182BD04663461B435B8D7A20D69DE33D98AFAA302B86A5077B90F
+20220714113910 2 6 100 3071 2 C60003BD3BEA8A30306CD503D00EFB4ED2BF6A45DEA568495ABAF8D2D53A1E0BA1D2C2D3648219C03F47CD52B677D72316114A3882A8A3EB62C4F002DB326C27811A36E332D121EE420DDDF830741F14AA96AC0D2AEB5A80BF31CD18D4E3C02A22BD1986A906EEC3D635669FF26DD25A73FD7650666B101D6C42B0A58D96331E0666C990B56E4F0A5649C76FC7BA599A6DBE245F3A2F16AA4A9216B3AFAA93FE40BBB1149A657C934EC408C063B7130027EF7624C721931FECB563EF32C68E9C275A6A9F8BBF5428CBAED0987CD0EB4BF1BF7AC6F33C37FD88C7A026ABD735F0CD7395A4A22DB22B26C78823FB3BDC98150A82573259E64F407A2B3C017D2E9933E64EF5DDABDD3E748D507D21FF4F7B3450F2640E51DF3993B067DB952F8CD179BE389000934363E209ACF6235D1E9D07D3B0E865C4F9EA6EEB91D2B46B8032B2A3890E4DCA5905E269BD5BF2810548243F13FB13691E5346533538503C9CAA0E56DBE759C182BD04663461B435B8D7A20D69DE33D98AFAA302B86A5096B1BB
+20220714113911 2 6 100 3071 5 C60003BD3BEA8A30306CD503D00EFB4ED2BF6A45DEA568495ABAF8D2D53A1E0BA1D2C2D3648219C03F47CD52B677D72316114A3882A8A3EB62C4F002DB326C27811A36E332D121EE420DDDF830741F14AA96AC0D2AEB5A80BF31CD18D4E3C02A22BD1986A906EEC3D635669FF26DD25A73FD7650666B101D6C42B0A58D96331E0666C990B56E4F0A5649C76FC7BA599A6DBE245F3A2F16AA4A9216B3AFAA93FE40BBB1149A657C934EC408C063B7130027EF7624C721931FECB563EF32C68E9C275A6A9F8BBF5428CBAED0987CD0EB4BF1BF7AC6F33C37FD88C7A026ABD735F0CD7395A4A22DB22B26C78823FB3BDC98150A82573259E64F407A2B3C017D2E9933E64EF5DDABDD3E748D507D21FF4F7B3450F2640E51DF3993B067DB952F8CD179BE389000934363E209ACF6235D1E9D07D3B0E865C4F9EA6EEB91D2B46B8032B2A3890E4DCA5905E269BD5BF2810548243F13FB13691E5346533538503C9CAA0E56DBE759C182BD04663461B435B8D7A20D69DE33D98AFAA302B86A509ABFAF
+20220714114137 2 6 100 3071 2 DA55F6EE023BA05F89B992D6CCEAAD8F6F787812100336939D4C7BD3E08406588C1D2D9C8F4F13A4CEE2F74AAD1ED582272D56866BCBA0449DD6E701CC63FF2DD3B90551DAFE6F228ACF5E3F2B5FE0630B2E5C66D16AE17321A30A0701E511036AAB085C8D3672721EB89A6A6C5CD1406742343617A0B2B09DAD465A2798DEF580B49E25073F0CA98217F242BDB49FD43FB32D31B1983B271A92C13B2A5BD1F39FAF6EC9DE65B5181AB4F6AE3D7D052046ABED2928B5C0B98148EFFB3C2EFD06A61144DDBABE0C4B0E9EDAF0037652A9C5C658F0DAF177DDDFC589A906F46E4F1EBC4A915AE00BB9ACB01B1B62F605209929A8A4274AA498A884DC2E26A1BE9A4FBAD44CF68AA5F92ED35EC66455A01F2273DE2369AB2F07702171AE4D4A551AABAC9C53063C9F1697653877CDE27893DEDF391154D6E5866C919E0C154E5B2B6E00CBA6216FF5FE7EEBE52690BBE6A4CD0693BEDFCB6B217BBA802C6926CEA2021005568848D957894473D76D41254E97267C25836CC2DA3D515243E7AF7A33
+20220714114223 2 6 100 3071 5 DA55F6EE023BA05F89B992D6CCEAAD8F6F787812100336939D4C7BD3E08406588C1D2D9C8F4F13A4CEE2F74AAD1ED582272D56866BCBA0449DD6E701CC63FF2DD3B90551DAFE6F228ACF5E3F2B5FE0630B2E5C66D16AE17321A30A0701E511036AAB085C8D3672721EB89A6A6C5CD1406742343617A0B2B09DAD465A2798DEF580B49E25073F0CA98217F242BDB49FD43FB32D31B1983B271A92C13B2A5BD1F39FAF6EC9DE65B5181AB4F6AE3D7D052046ABED2928B5C0B98148EFFB3C2EFD06A61144DDBABE0C4B0E9EDAF0037652A9C5C658F0DAF177DDDFC589A906F46E4F1EBC4A915AE00BB9ACB01B1B62F605209929A8A4274AA498A884DC2E26A1BE9A4FBAD44CF68AA5F92ED35EC66455A01F2273DE2369AB2F07702171AE4D4A551AABAC9C53063C9F1697653877CDE27893DEDF391154D6E5866C919E0C154E5B2B6E00CBA6216FF5FE7EEBE52690BBE6A4CD0693BEDFCB6B217BBA802C6926CEA2021005568848D957894473D76D41254E97267C25836CC2DA3D515243E853FBF7
+20220714114400 2 6 100 3071 2 DA55F6EE023BA05F89B992D6CCEAAD8F6F787812100336939D4C7BD3E08406588C1D2D9C8F4F13A4CEE2F74AAD1ED582272D56866BCBA0449DD6E701CC63FF2DD3B90551DAFE6F228ACF5E3F2B5FE0630B2E5C66D16AE17321A30A0701E511036AAB085C8D3672721EB89A6A6C5CD1406742343617A0B2B09DAD465A2798DEF580B49E25073F0CA98217F242BDB49FD43FB32D31B1983B271A92C13B2A5BD1F39FAF6EC9DE65B5181AB4F6AE3D7D052046ABED2928B5C0B98148EFFB3C2EFD06A61144DDBABE0C4B0E9EDAF0037652A9C5C658F0DAF177DDDFC589A906F46E4F1EBC4A915AE00BB9ACB01B1B62F605209929A8A4274AA498A884DC2E26A1BE9A4FBAD44CF68AA5F92ED35EC66455A01F2273DE2369AB2F07702171AE4D4A551AABAC9C53063C9F1697653877CDE27893DEDF391154D6E5866C919E0C154E5B2B6E00CBA6216FF5FE7EEBE52690BBE6A4CD0693BEDFCB6B217BBA802C6926CEA2021005568848D957894473D76D41254E97267C25836CC2DA3D515243E99CF2CB
+20220714114432 2 6 100 3071 2 DA55F6EE023BA05F89B992D6CCEAAD8F6F787812100336939D4C7BD3E08406588C1D2D9C8F4F13A4CEE2F74AAD1ED582272D56866BCBA0449DD6E701CC63FF2DD3B90551DAFE6F228ACF5E3F2B5FE0630B2E5C66D16AE17321A30A0701E511036AAB085C8D3672721EB89A6A6C5CD1406742343617A0B2B09DAD465A2798DEF580B49E25073F0CA98217F242BDB49FD43FB32D31B1983B271A92C13B2A5BD1F39FAF6EC9DE65B5181AB4F6AE3D7D052046ABED2928B5C0B98148EFFB3C2EFD06A61144DDBABE0C4B0E9EDAF0037652A9C5C658F0DAF177DDDFC589A906F46E4F1EBC4A915AE00BB9ACB01B1B62F605209929A8A4274AA498A884DC2E26A1BE9A4FBAD44CF68AA5F92ED35EC66455A01F2273DE2369AB2F07702171AE4D4A551AABAC9C53063C9F1697653877CDE27893DEDF391154D6E5866C919E0C154E5B2B6E00CBA6216FF5FE7EEBE52690BBE6A4CD0693BEDFCB6B217BBA802C6926CEA2021005568848D957894473D76D41254E97267C25836CC2DA3D515243EA1047DB
+20220714114439 2 6 100 3071 2 DA55F6EE023BA05F89B992D6CCEAAD8F6F787812100336939D4C7BD3E08406588C1D2D9C8F4F13A4CEE2F74AAD1ED582272D56866BCBA0449DD6E701CC63FF2DD3B90551DAFE6F228ACF5E3F2B5FE0630B2E5C66D16AE17321A30A0701E511036AAB085C8D3672721EB89A6A6C5CD1406742343617A0B2B09DAD465A2798DEF580B49E25073F0CA98217F242BDB49FD43FB32D31B1983B271A92C13B2A5BD1F39FAF6EC9DE65B5181AB4F6AE3D7D052046ABED2928B5C0B98148EFFB3C2EFD06A61144DDBABE0C4B0E9EDAF0037652A9C5C658F0DAF177DDDFC589A906F46E4F1EBC4A915AE00BB9ACB01B1B62F605209929A8A4274AA498A884DC2E26A1BE9A4FBAD44CF68AA5F92ED35EC66455A01F2273DE2369AB2F07702171AE4D4A551AABAC9C53063C9F1697653877CDE27893DEDF391154D6E5866C919E0C154E5B2B6E00CBA6216FF5FE7EEBE52690BBE6A4CD0693BEDFCB6B217BBA802C6926CEA2021005568848D957894473D76D41254E97267C25836CC2DA3D515243EA262BF3
+20220714114453 2 6 100 3071 5 DA55F6EE023BA05F89B992D6CCEAAD8F6F787812100336939D4C7BD3E08406588C1D2D9C8F4F13A4CEE2F74AAD1ED582272D56866BCBA0449DD6E701CC63FF2DD3B90551DAFE6F228ACF5E3F2B5FE0630B2E5C66D16AE17321A30A0701E511036AAB085C8D3672721EB89A6A6C5CD1406742343617A0B2B09DAD465A2798DEF580B49E25073F0CA98217F242BDB49FD43FB32D31B1983B271A92C13B2A5BD1F39FAF6EC9DE65B5181AB4F6AE3D7D052046ABED2928B5C0B98148EFFB3C2EFD06A61144DDBABE0C4B0E9EDAF0037652A9C5C658F0DAF177DDDFC589A906F46E4F1EBC4A915AE00BB9ACB01B1B62F605209929A8A4274AA498A884DC2E26A1BE9A4FBAD44CF68AA5F92ED35EC66455A01F2273DE2369AB2F07702171AE4D4A551AABAC9C53063C9F1697653877CDE27893DEDF391154D6E5866C919E0C154E5B2B6E00CBA6216FF5FE7EEBE52690BBE6A4CD0693BEDFCB6B217BBA802C6926CEA2021005568848D957894473D76D41254E97267C25836CC2DA3D515243EA58ABD7
+20220714114510 2 6 100 3071 5 DA55F6EE023BA05F89B992D6CCEAAD8F6F787812100336939D4C7BD3E08406588C1D2D9C8F4F13A4CEE2F74AAD1ED582272D56866BCBA0449DD6E701CC63FF2DD3B90551DAFE6F228ACF5E3F2B5FE0630B2E5C66D16AE17321A30A0701E511036AAB085C8D3672721EB89A6A6C5CD1406742343617A0B2B09DAD465A2798DEF580B49E25073F0CA98217F242BDB49FD43FB32D31B1983B271A92C13B2A5BD1F39FAF6EC9DE65B5181AB4F6AE3D7D052046ABED2928B5C0B98148EFFB3C2EFD06A61144DDBABE0C4B0E9EDAF0037652A9C5C658F0DAF177DDDFC589A906F46E4F1EBC4A915AE00BB9ACB01B1B62F605209929A8A4274AA498A884DC2E26A1BE9A4FBAD44CF68AA5F92ED35EC66455A01F2273DE2369AB2F07702171AE4D4A551AABAC9C53063C9F1697653877CDE27893DEDF391154D6E5866C919E0C154E5B2B6E00CBA6216FF5FE7EEBE52690BBE6A4CD0693BEDFCB6B217BBA802C6926CEA2021005568848D957894473D76D41254E97267C25836CC2DA3D515243EA98697F
+20220714114514 2 6 100 3071 2 DA55F6EE023BA05F89B992D6CCEAAD8F6F787812100336939D4C7BD3E08406588C1D2D9C8F4F13A4CEE2F74AAD1ED582272D56866BCBA0449DD6E701CC63FF2DD3B90551DAFE6F228ACF5E3F2B5FE0630B2E5C66D16AE17321A30A0701E511036AAB085C8D3672721EB89A6A6C5CD1406742343617A0B2B09DAD465A2798DEF580B49E25073F0CA98217F242BDB49FD43FB32D31B1983B271A92C13B2A5BD1F39FAF6EC9DE65B5181AB4F6AE3D7D052046ABED2928B5C0B98148EFFB3C2EFD06A61144DDBABE0C4B0E9EDAF0037652A9C5C658F0DAF177DDDFC589A906F46E4F1EBC4A915AE00BB9ACB01B1B62F605209929A8A4274AA498A884DC2E26A1BE9A4FBAD44CF68AA5F92ED35EC66455A01F2273DE2369AB2F07702171AE4D4A551AABAC9C53063C9F1697653877CDE27893DEDF391154D6E5866C919E0C154E5B2B6E00CBA6216FF5FE7EEBE52690BBE6A4CD0693BEDFCB6B217BBA802C6926CEA2021005568848D957894473D76D41254E97267C25836CC2DA3D515243EAA6423B
+20220714114554 2 6 100 3071 5 DA55F6EE023BA05F89B992D6CCEAAD8F6F787812100336939D4C7BD3E08406588C1D2D9C8F4F13A4CEE2F74AAD1ED582272D56866BCBA0449DD6E701CC63FF2DD3B90551DAFE6F228ACF5E3F2B5FE0630B2E5C66D16AE17321A30A0701E511036AAB085C8D3672721EB89A6A6C5CD1406742343617A0B2B09DAD465A2798DEF580B49E25073F0CA98217F242BDB49FD43FB32D31B1983B271A92C13B2A5BD1F39FAF6EC9DE65B5181AB4F6AE3D7D052046ABED2928B5C0B98148EFFB3C2EFD06A61144DDBABE0C4B0E9EDAF0037652A9C5C658F0DAF177DDDFC589A906F46E4F1EBC4A915AE00BB9ACB01B1B62F605209929A8A4274AA498A884DC2E26A1BE9A4FBAD44CF68AA5F92ED35EC66455A01F2273DE2369AB2F07702171AE4D4A551AABAC9C53063C9F1697653877CDE27893DEDF391154D6E5866C919E0C154E5B2B6E00CBA6216FF5FE7EEBE52690BBE6A4CD0693BEDFCB6B217BBA802C6926CEA2021005568848D957894473D76D41254E97267C25836CC2DA3D515243EB37D447
+20220714114630 2 6 100 3071 5 DA55F6EE023BA05F89B992D6CCEAAD8F6F787812100336939D4C7BD3E08406588C1D2D9C8F4F13A4CEE2F74AAD1ED582272D56866BCBA0449DD6E701CC63FF2DD3B90551DAFE6F228ACF5E3F2B5FE0630B2E5C66D16AE17321A30A0701E511036AAB085C8D3672721EB89A6A6C5CD1406742343617A0B2B09DAD465A2798DEF580B49E25073F0CA98217F242BDB49FD43FB32D31B1983B271A92C13B2A5BD1F39FAF6EC9DE65B5181AB4F6AE3D7D052046ABED2928B5C0B98148EFFB3C2EFD06A61144DDBABE0C4B0E9EDAF0037652A9C5C658F0DAF177DDDFC589A906F46E4F1EBC4A915AE00BB9ACB01B1B62F605209929A8A4274AA498A884DC2E26A1BE9A4FBAD44CF68AA5F92ED35EC66455A01F2273DE2369AB2F07702171AE4D4A551AABAC9C53063C9F1697653877CDE27893DEDF391154D6E5866C919E0C154E5B2B6E00CBA6216FF5FE7EEBE52690BBE6A4CD0693BEDFCB6B217BBA802C6926CEA2021005568848D957894473D76D41254E97267C25836CC2DA3D515243EBBBB32F
+20220714114922 2 6 100 3071 2 DA55F6EE023BA05F89B992D6CCEAAD8F6F787812100336939D4C7BD3E08406588C1D2D9C8F4F13A4CEE2F74AAD1ED582272D56866BCBA0449DD6E701CC63FF2DD3B90551DAFE6F228ACF5E3F2B5FE0630B2E5C66D16AE17321A30A0701E511036AAB085C8D3672721EB89A6A6C5CD1406742343617A0B2B09DAD465A2798DEF580B49E25073F0CA98217F242BDB49FD43FB32D31B1983B271A92C13B2A5BD1F39FAF6EC9DE65B5181AB4F6AE3D7D052046ABED2928B5C0B98148EFFB3C2EFD06A61144DDBABE0C4B0E9EDAF0037652A9C5C658F0DAF177DDDFC589A906F46E4F1EBC4A915AE00BB9ACB01B1B62F605209929A8A4274AA498A884DC2E26A1BE9A4FBAD44CF68AA5F92ED35EC66455A01F2273DE2369AB2F07702171AE4D4A551AABAC9C53063C9F1697653877CDE27893DEDF391154D6E5866C919E0C154E5B2B6E00CBA6216FF5FE7EEBE52690BBE6A4CD0693BEDFCB6B217BBA802C6926CEA2021005568848D957894473D76D41254E97267C25836CC2DA3D515243EE2FD6FB
+20220714114946 2 6 100 3071 2 DA55F6EE023BA05F89B992D6CCEAAD8F6F787812100336939D4C7BD3E08406588C1D2D9C8F4F13A4CEE2F74AAD1ED582272D56866BCBA0449DD6E701CC63FF2DD3B90551DAFE6F228ACF5E3F2B5FE0630B2E5C66D16AE17321A30A0701E511036AAB085C8D3672721EB89A6A6C5CD1406742343617A0B2B09DAD465A2798DEF580B49E25073F0CA98217F242BDB49FD43FB32D31B1983B271A92C13B2A5BD1F39FAF6EC9DE65B5181AB4F6AE3D7D052046ABED2928B5C0B98148EFFB3C2EFD06A61144DDBABE0C4B0E9EDAF0037652A9C5C658F0DAF177DDDFC589A906F46E4F1EBC4A915AE00BB9ACB01B1B62F605209929A8A4274AA498A884DC2E26A1BE9A4FBAD44CF68AA5F92ED35EC66455A01F2273DE2369AB2F07702171AE4D4A551AABAC9C53063C9F1697653877CDE27893DEDF391154D6E5866C919E0C154E5B2B6E00CBA6216FF5FE7EEBE52690BBE6A4CD0693BEDFCB6B217BBA802C6926CEA2021005568848D957894473D76D41254E97267C25836CC2DA3D515243EE87B393
+20220714114947 2 6 100 3071 2 DA55F6EE023BA05F89B992D6CCEAAD8F6F787812100336939D4C7BD3E08406588C1D2D9C8F4F13A4CEE2F74AAD1ED582272D56866BCBA0449DD6E701CC63FF2DD3B90551DAFE6F228ACF5E3F2B5FE0630B2E5C66D16AE17321A30A0701E511036AAB085C8D3672721EB89A6A6C5CD1406742343617A0B2B09DAD465A2798DEF580B49E25073F0CA98217F242BDB49FD43FB32D31B1983B271A92C13B2A5BD1F39FAF6EC9DE65B5181AB4F6AE3D7D052046ABED2928B5C0B98148EFFB3C2EFD06A61144DDBABE0C4B0E9EDAF0037652A9C5C658F0DAF177DDDFC589A906F46E4F1EBC4A915AE00BB9ACB01B1B62F605209929A8A4274AA498A884DC2E26A1BE9A4FBAD44CF68AA5F92ED35EC66455A01F2273DE2369AB2F07702171AE4D4A551AABAC9C53063C9F1697653877CDE27893DEDF391154D6E5866C919E0C154E5B2B6E00CBA6216FF5FE7EEBE52690BBE6A4CD0693BEDFCB6B217BBA802C6926CEA2021005568848D957894473D76D41254E97267C25836CC2DA3D515243EE89E703
+20220714115027 2 6 100 3071 5 DA55F6EE023BA05F89B992D6CCEAAD8F6F787812100336939D4C7BD3E08406588C1D2D9C8F4F13A4CEE2F74AAD1ED582272D56866BCBA0449DD6E701CC63FF2DD3B90551DAFE6F228ACF5E3F2B5FE0630B2E5C66D16AE17321A30A0701E511036AAB085C8D3672721EB89A6A6C5CD1406742343617A0B2B09DAD465A2798DEF580B49E25073F0CA98217F242BDB49FD43FB32D31B1983B271A92C13B2A5BD1F39FAF6EC9DE65B5181AB4F6AE3D7D052046ABED2928B5C0B98148EFFB3C2EFD06A61144DDBABE0C4B0E9EDAF0037652A9C5C658F0DAF177DDDFC589A906F46E4F1EBC4A915AE00BB9ACB01B1B62F605209929A8A4274AA498A884DC2E26A1BE9A4FBAD44CF68AA5F92ED35EC66455A01F2273DE2369AB2F07702171AE4D4A551AABAC9C53063C9F1697653877CDE27893DEDF391154D6E5866C919E0C154E5B2B6E00CBA6216FF5FE7EEBE52690BBE6A4CD0693BEDFCB6B217BBA802C6926CEA2021005568848D957894473D76D41254E97267C25836CC2DA3D515243EF1D4457
+20220714115124 2 6 100 3071 5 DA55F6EE023BA05F89B992D6CCEAAD8F6F787812100336939D4C7BD3E08406588C1D2D9C8F4F13A4CEE2F74AAD1ED582272D56866BCBA0449DD6E701CC63FF2DD3B90551DAFE6F228ACF5E3F2B5FE0630B2E5C66D16AE17321A30A0701E511036AAB085C8D3672721EB89A6A6C5CD1406742343617A0B2B09DAD465A2798DEF580B49E25073F0CA98217F242BDB49FD43FB32D31B1983B271A92C13B2A5BD1F39FAF6EC9DE65B5181AB4F6AE3D7D052046ABED2928B5C0B98148EFFB3C2EFD06A61144DDBABE0C4B0E9EDAF0037652A9C5C658F0DAF177DDDFC589A906F46E4F1EBC4A915AE00BB9ACB01B1B62F605209929A8A4274AA498A884DC2E26A1BE9A4FBAD44CF68AA5F92ED35EC66455A01F2273DE2369AB2F07702171AE4D4A551AABAC9C53063C9F1697653877CDE27893DEDF391154D6E5866C919E0C154E5B2B6E00CBA6216FF5FE7EEBE52690BBE6A4CD0693BEDFCB6B217BBA802C6926CEA2021005568848D957894473D76D41254E97267C25836CC2DA3D515243EFF0E74F
+20220714115140 2 6 100 3071 2 DA55F6EE023BA05F89B992D6CCEAAD8F6F787812100336939D4C7BD3E08406588C1D2D9C8F4F13A4CEE2F74AAD1ED582272D56866BCBA0449DD6E701CC63FF2DD3B90551DAFE6F228ACF5E3F2B5FE0630B2E5C66D16AE17321A30A0701E511036AAB085C8D3672721EB89A6A6C5CD1406742343617A0B2B09DAD465A2798DEF580B49E25073F0CA98217F242BDB49FD43FB32D31B1983B271A92C13B2A5BD1F39FAF6EC9DE65B5181AB4F6AE3D7D052046ABED2928B5C0B98148EFFB3C2EFD06A61144DDBABE0C4B0E9EDAF0037652A9C5C658F0DAF177DDDFC589A906F46E4F1EBC4A915AE00BB9ACB01B1B62F605209929A8A4274AA498A884DC2E26A1BE9A4FBAD44CF68AA5F92ED35EC66455A01F2273DE2369AB2F07702171AE4D4A551AABAC9C53063C9F1697653877CDE27893DEDF391154D6E5866C919E0C154E5B2B6E00CBA6216FF5FE7EEBE52690BBE6A4CD0693BEDFCB6B217BBA802C6926CEA2021005568848D957894473D76D41254E97267C25836CC2DA3D515243F02F1483
+20220714115239 2 6 100 3071 2 DA55F6EE023BA05F89B992D6CCEAAD8F6F787812100336939D4C7BD3E08406588C1D2D9C8F4F13A4CEE2F74AAD1ED582272D56866BCBA0449DD6E701CC63FF2DD3B90551DAFE6F228ACF5E3F2B5FE0630B2E5C66D16AE17321A30A0701E511036AAB085C8D3672721EB89A6A6C5CD1406742343617A0B2B09DAD465A2798DEF580B49E25073F0CA98217F242BDB49FD43FB32D31B1983B271A92C13B2A5BD1F39FAF6EC9DE65B5181AB4F6AE3D7D052046ABED2928B5C0B98148EFFB3C2EFD06A61144DDBABE0C4B0E9EDAF0037652A9C5C658F0DAF177DDDFC589A906F46E4F1EBC4A915AE00BB9ACB01B1B62F605209929A8A4274AA498A884DC2E26A1BE9A4FBAD44CF68AA5F92ED35EC66455A01F2273DE2369AB2F07702171AE4D4A551AABAC9C53063C9F1697653877CDE27893DEDF391154D6E5866C919E0C154E5B2B6E00CBA6216FF5FE7EEBE52690BBE6A4CD0693BEDFCB6B217BBA802C6926CEA2021005568848D957894473D76D41254E97267C25836CC2DA3D515243F1048C9B
+20220714115329 2 6 100 3071 5 DA55F6EE023BA05F89B992D6CCEAAD8F6F787812100336939D4C7BD3E08406588C1D2D9C8F4F13A4CEE2F74AAD1ED582272D56866BCBA0449DD6E701CC63FF2DD3B90551DAFE6F228ACF5E3F2B5FE0630B2E5C66D16AE17321A30A0701E511036AAB085C8D3672721EB89A6A6C5CD1406742343617A0B2B09DAD465A2798DEF580B49E25073F0CA98217F242BDB49FD43FB32D31B1983B271A92C13B2A5BD1F39FAF6EC9DE65B5181AB4F6AE3D7D052046ABED2928B5C0B98148EFFB3C2EFD06A61144DDBABE0C4B0E9EDAF0037652A9C5C658F0DAF177DDDFC589A906F46E4F1EBC4A915AE00BB9ACB01B1B62F605209929A8A4274AA498A884DC2E26A1BE9A4FBAD44CF68AA5F92ED35EC66455A01F2273DE2369AB2F07702171AE4D4A551AABAC9C53063C9F1697653877CDE27893DEDF391154D6E5866C919E0C154E5B2B6E00CBA6216FF5FE7EEBE52690BBE6A4CD0693BEDFCB6B217BBA802C6926CEA2021005568848D957894473D76D41254E97267C25836CC2DA3D515243F1B76437
+20220714115359 2 6 100 3071 5 DA55F6EE023BA05F89B992D6CCEAAD8F6F787812100336939D4C7BD3E08406588C1D2D9C8F4F13A4CEE2F74AAD1ED582272D56866BCBA0449DD6E701CC63FF2DD3B90551DAFE6F228ACF5E3F2B5FE0630B2E5C66D16AE17321A30A0701E511036AAB085C8D3672721EB89A6A6C5CD1406742343617A0B2B09DAD465A2798DEF580B49E25073F0CA98217F242BDB49FD43FB32D31B1983B271A92C13B2A5BD1F39FAF6EC9DE65B5181AB4F6AE3D7D052046ABED2928B5C0B98148EFFB3C2EFD06A61144DDBABE0C4B0E9EDAF0037652A9C5C658F0DAF177DDDFC589A906F46E4F1EBC4A915AE00BB9ACB01B1B62F605209929A8A4274AA498A884DC2E26A1BE9A4FBAD44CF68AA5F92ED35EC66455A01F2273DE2369AB2F07702171AE4D4A551AABAC9C53063C9F1697653877CDE27893DEDF391154D6E5866C919E0C154E5B2B6E00CBA6216FF5FE7EEBE52690BBE6A4CD0693BEDFCB6B217BBA802C6926CEA2021005568848D957894473D76D41254E97267C25836CC2DA3D515243F2205357
+20220714115442 2 6 100 3071 5 DA55F6EE023BA05F89B992D6CCEAAD8F6F787812100336939D4C7BD3E08406588C1D2D9C8F4F13A4CEE2F74AAD1ED582272D56866BCBA0449DD6E701CC63FF2DD3B90551DAFE6F228ACF5E3F2B5FE0630B2E5C66D16AE17321A30A0701E511036AAB085C8D3672721EB89A6A6C5CD1406742343617A0B2B09DAD465A2798DEF580B49E25073F0CA98217F242BDB49FD43FB32D31B1983B271A92C13B2A5BD1F39FAF6EC9DE65B5181AB4F6AE3D7D052046ABED2928B5C0B98148EFFB3C2EFD06A61144DDBABE0C4B0E9EDAF0037652A9C5C658F0DAF177DDDFC589A906F46E4F1EBC4A915AE00BB9ACB01B1B62F605209929A8A4274AA498A884DC2E26A1BE9A4FBAD44CF68AA5F92ED35EC66455A01F2273DE2369AB2F07702171AE4D4A551AABAC9C53063C9F1697653877CDE27893DEDF391154D6E5866C919E0C154E5B2B6E00CBA6216FF5FE7EEBE52690BBE6A4CD0693BEDFCB6B217BBA802C6926CEA2021005568848D957894473D76D41254E97267C25836CC2DA3D515243F2BCF797
+20220714115448 2 6 100 3071 2 DA55F6EE023BA05F89B992D6CCEAAD8F6F787812100336939D4C7BD3E08406588C1D2D9C8F4F13A4CEE2F74AAD1ED582272D56866BCBA0449DD6E701CC63FF2DD3B90551DAFE6F228ACF5E3F2B5FE0630B2E5C66D16AE17321A30A0701E511036AAB085C8D3672721EB89A6A6C5CD1406742343617A0B2B09DAD465A2798DEF580B49E25073F0CA98217F242BDB49FD43FB32D31B1983B271A92C13B2A5BD1F39FAF6EC9DE65B5181AB4F6AE3D7D052046ABED2928B5C0B98148EFFB3C2EFD06A61144DDBABE0C4B0E9EDAF0037652A9C5C658F0DAF177DDDFC589A906F46E4F1EBC4A915AE00BB9ACB01B1B62F605209929A8A4274AA498A884DC2E26A1BE9A4FBAD44CF68AA5F92ED35EC66455A01F2273DE2369AB2F07702171AE4D4A551AABAC9C53063C9F1697653877CDE27893DEDF391154D6E5866C919E0C154E5B2B6E00CBA6216FF5FE7EEBE52690BBE6A4CD0693BEDFCB6B217BBA802C6926CEA2021005568848D957894473D76D41254E97267C25836CC2DA3D515243F2D1B3DB
+20220714115516 2 6 100 3071 2 DA55F6EE023BA05F89B992D6CCEAAD8F6F787812100336939D4C7BD3E08406588C1D2D9C8F4F13A4CEE2F74AAD1ED582272D56866BCBA0449DD6E701CC63FF2DD3B90551DAFE6F228ACF5E3F2B5FE0630B2E5C66D16AE17321A30A0701E511036AAB085C8D3672721EB89A6A6C5CD1406742343617A0B2B09DAD465A2798DEF580B49E25073F0CA98217F242BDB49FD43FB32D31B1983B271A92C13B2A5BD1F39FAF6EC9DE65B5181AB4F6AE3D7D052046ABED2928B5C0B98148EFFB3C2EFD06A61144DDBABE0C4B0E9EDAF0037652A9C5C658F0DAF177DDDFC589A906F46E4F1EBC4A915AE00BB9ACB01B1B62F605209929A8A4274AA498A884DC2E26A1BE9A4FBAD44CF68AA5F92ED35EC66455A01F2273DE2369AB2F07702171AE4D4A551AABAC9C53063C9F1697653877CDE27893DEDF391154D6E5866C919E0C154E5B2B6E00CBA6216FF5FE7EEBE52690BBE6A4CD0693BEDFCB6B217BBA802C6926CEA2021005568848D957894473D76D41254E97267C25836CC2DA3D515243F33828DB
+20220714115531 2 6 100 3071 5 DA55F6EE023BA05F89B992D6CCEAAD8F6F787812100336939D4C7BD3E08406588C1D2D9C8F4F13A4CEE2F74AAD1ED582272D56866BCBA0449DD6E701CC63FF2DD3B90551DAFE6F228ACF5E3F2B5FE0630B2E5C66D16AE17321A30A0701E511036AAB085C8D3672721EB89A6A6C5CD1406742343617A0B2B09DAD465A2798DEF580B49E25073F0CA98217F242BDB49FD43FB32D31B1983B271A92C13B2A5BD1F39FAF6EC9DE65B5181AB4F6AE3D7D052046ABED2928B5C0B98148EFFB3C2EFD06A61144DDBABE0C4B0E9EDAF0037652A9C5C658F0DAF177DDDFC589A906F46E4F1EBC4A915AE00BB9ACB01B1B62F605209929A8A4274AA498A884DC2E26A1BE9A4FBAD44CF68AA5F92ED35EC66455A01F2273DE2369AB2F07702171AE4D4A551AABAC9C53063C9F1697653877CDE27893DEDF391154D6E5866C919E0C154E5B2B6E00CBA6216FF5FE7EEBE52690BBE6A4CD0693BEDFCB6B217BBA802C6926CEA2021005568848D957894473D76D41254E97267C25836CC2DA3D515243F36A7D87
+20220714115553 2 6 100 3071 5 DA55F6EE023BA05F89B992D6CCEAAD8F6F787812100336939D4C7BD3E08406588C1D2D9C8F4F13A4CEE2F74AAD1ED582272D56866BCBA0449DD6E701CC63FF2DD3B90551DAFE6F228ACF5E3F2B5FE0630B2E5C66D16AE17321A30A0701E511036AAB085C8D3672721EB89A6A6C5CD1406742343617A0B2B09DAD465A2798DEF580B49E25073F0CA98217F242BDB49FD43FB32D31B1983B271A92C13B2A5BD1F39FAF6EC9DE65B5181AB4F6AE3D7D052046ABED2928B5C0B98148EFFB3C2EFD06A61144DDBABE0C4B0E9EDAF0037652A9C5C658F0DAF177DDDFC589A906F46E4F1EBC4A915AE00BB9ACB01B1B62F605209929A8A4274AA498A884DC2E26A1BE9A4FBAD44CF68AA5F92ED35EC66455A01F2273DE2369AB2F07702171AE4D4A551AABAC9C53063C9F1697653877CDE27893DEDF391154D6E5866C919E0C154E5B2B6E00CBA6216FF5FE7EEBE52690BBE6A4CD0693BEDFCB6B217BBA802C6926CEA2021005568848D957894473D76D41254E97267C25836CC2DA3D515243F3B6A657
+20220714115559 2 6 100 3071 5 DA55F6EE023BA05F89B992D6CCEAAD8F6F787812100336939D4C7BD3E08406588C1D2D9C8F4F13A4CEE2F74AAD1ED582272D56866BCBA0449DD6E701CC63FF2DD3B90551DAFE6F228ACF5E3F2B5FE0630B2E5C66D16AE17321A30A0701E511036AAB085C8D3672721EB89A6A6C5CD1406742343617A0B2B09DAD465A2798DEF580B49E25073F0CA98217F242BDB49FD43FB32D31B1983B271A92C13B2A5BD1F39FAF6EC9DE65B5181AB4F6AE3D7D052046ABED2928B5C0B98148EFFB3C2EFD06A61144DDBABE0C4B0E9EDAF0037652A9C5C658F0DAF177DDDFC589A906F46E4F1EBC4A915AE00BB9ACB01B1B62F605209929A8A4274AA498A884DC2E26A1BE9A4FBAD44CF68AA5F92ED35EC66455A01F2273DE2369AB2F07702171AE4D4A551AABAC9C53063C9F1697653877CDE27893DEDF391154D6E5866C919E0C154E5B2B6E00CBA6216FF5FE7EEBE52690BBE6A4CD0693BEDFCB6B217BBA802C6926CEA2021005568848D957894473D76D41254E97267C25836CC2DA3D515243F3CB724F
+20220714115604 2 6 100 3071 5 DA55F6EE023BA05F89B992D6CCEAAD8F6F787812100336939D4C7BD3E08406588C1D2D9C8F4F13A4CEE2F74AAD1ED582272D56866BCBA0449DD6E701CC63FF2DD3B90551DAFE6F228ACF5E3F2B5FE0630B2E5C66D16AE17321A30A0701E511036AAB085C8D3672721EB89A6A6C5CD1406742343617A0B2B09DAD465A2798DEF580B49E25073F0CA98217F242BDB49FD43FB32D31B1983B271A92C13B2A5BD1F39FAF6EC9DE65B5181AB4F6AE3D7D052046ABED2928B5C0B98148EFFB3C2EFD06A61144DDBABE0C4B0E9EDAF0037652A9C5C658F0DAF177DDDFC589A906F46E4F1EBC4A915AE00BB9ACB01B1B62F605209929A8A4274AA498A884DC2E26A1BE9A4FBAD44CF68AA5F92ED35EC66455A01F2273DE2369AB2F07702171AE4D4A551AABAC9C53063C9F1697653877CDE27893DEDF391154D6E5866C919E0C154E5B2B6E00CBA6216FF5FE7EEBE52690BBE6A4CD0693BEDFCB6B217BBA802C6926CEA2021005568848D957894473D76D41254E97267C25836CC2DA3D515243F3DB43EF
+20220714115627 2 6 100 3071 2 DA55F6EE023BA05F89B992D6CCEAAD8F6F787812100336939D4C7BD3E08406588C1D2D9C8F4F13A4CEE2F74AAD1ED582272D56866BCBA0449DD6E701CC63FF2DD3B90551DAFE6F228ACF5E3F2B5FE0630B2E5C66D16AE17321A30A0701E511036AAB085C8D3672721EB89A6A6C5CD1406742343617A0B2B09DAD465A2798DEF580B49E25073F0CA98217F242BDB49FD43FB32D31B1983B271A92C13B2A5BD1F39FAF6EC9DE65B5181AB4F6AE3D7D052046ABED2928B5C0B98148EFFB3C2EFD06A61144DDBABE0C4B0E9EDAF0037652A9C5C658F0DAF177DDDFC589A906F46E4F1EBC4A915AE00BB9ACB01B1B62F605209929A8A4274AA498A884DC2E26A1BE9A4FBAD44CF68AA5F92ED35EC66455A01F2273DE2369AB2F07702171AE4D4A551AABAC9C53063C9F1697653877CDE27893DEDF391154D6E5866C919E0C154E5B2B6E00CBA6216FF5FE7EEBE52690BBE6A4CD0693BEDFCB6B217BBA802C6926CEA2021005568848D957894473D76D41254E97267C25836CC2DA3D515243F42F1353
+20220714115641 2 6 100 3071 2 DA55F6EE023BA05F89B992D6CCEAAD8F6F787812100336939D4C7BD3E08406588C1D2D9C8F4F13A4CEE2F74AAD1ED582272D56866BCBA0449DD6E701CC63FF2DD3B90551DAFE6F228ACF5E3F2B5FE0630B2E5C66D16AE17321A30A0701E511036AAB085C8D3672721EB89A6A6C5CD1406742343617A0B2B09DAD465A2798DEF580B49E25073F0CA98217F242BDB49FD43FB32D31B1983B271A92C13B2A5BD1F39FAF6EC9DE65B5181AB4F6AE3D7D052046ABED2928B5C0B98148EFFB3C2EFD06A61144DDBABE0C4B0E9EDAF0037652A9C5C658F0DAF177DDDFC589A906F46E4F1EBC4A915AE00BB9ACB01B1B62F605209929A8A4274AA498A884DC2E26A1BE9A4FBAD44CF68AA5F92ED35EC66455A01F2273DE2369AB2F07702171AE4D4A551AABAC9C53063C9F1697653877CDE27893DEDF391154D6E5866C919E0C154E5B2B6E00CBA6216FF5FE7EEBE52690BBE6A4CD0693BEDFCB6B217BBA802C6926CEA2021005568848D957894473D76D41254E97267C25836CC2DA3D515243F45D4ADB
+20220714115649 2 6 100 3071 5 DA55F6EE023BA05F89B992D6CCEAAD8F6F787812100336939D4C7BD3E08406588C1D2D9C8F4F13A4CEE2F74AAD1ED582272D56866BCBA0449DD6E701CC63FF2DD3B90551DAFE6F228ACF5E3F2B5FE0630B2E5C66D16AE17321A30A0701E511036AAB085C8D3672721EB89A6A6C5CD1406742343617A0B2B09DAD465A2798DEF580B49E25073F0CA98217F242BDB49FD43FB32D31B1983B271A92C13B2A5BD1F39FAF6EC9DE65B5181AB4F6AE3D7D052046ABED2928B5C0B98148EFFB3C2EFD06A61144DDBABE0C4B0E9EDAF0037652A9C5C658F0DAF177DDDFC589A906F46E4F1EBC4A915AE00BB9ACB01B1B62F605209929A8A4274AA498A884DC2E26A1BE9A4FBAD44CF68AA5F92ED35EC66455A01F2273DE2369AB2F07702171AE4D4A551AABAC9C53063C9F1697653877CDE27893DEDF391154D6E5866C919E0C154E5B2B6E00CBA6216FF5FE7EEBE52690BBE6A4CD0693BEDFCB6B217BBA802C6926CEA2021005568848D957894473D76D41254E97267C25836CC2DA3D515243F478CA07
+20220714115654 2 6 100 3071 2 DA55F6EE023BA05F89B992D6CCEAAD8F6F787812100336939D4C7BD3E08406588C1D2D9C8F4F13A4CEE2F74AAD1ED582272D56866BCBA0449DD6E701CC63FF2DD3B90551DAFE6F228ACF5E3F2B5FE0630B2E5C66D16AE17321A30A0701E511036AAB085C8D3672721EB89A6A6C5CD1406742343617A0B2B09DAD465A2798DEF580B49E25073F0CA98217F242BDB49FD43FB32D31B1983B271A92C13B2A5BD1F39FAF6EC9DE65B5181AB4F6AE3D7D052046ABED2928B5C0B98148EFFB3C2EFD06A61144DDBABE0C4B0E9EDAF0037652A9C5C658F0DAF177DDDFC589A906F46E4F1EBC4A915AE00BB9ACB01B1B62F605209929A8A4274AA498A884DC2E26A1BE9A4FBAD44CF68AA5F92ED35EC66455A01F2273DE2369AB2F07702171AE4D4A551AABAC9C53063C9F1697653877CDE27893DEDF391154D6E5866C919E0C154E5B2B6E00CBA6216FF5FE7EEBE52690BBE6A4CD0693BEDFCB6B217BBA802C6926CEA2021005568848D957894473D76D41254E97267C25836CC2DA3D515243F48960F3
+20220714115824 2 6 100 3071 2 DA55F6EE023BA05F89B992D6CCEAAD8F6F787812100336939D4C7BD3E08406588C1D2D9C8F4F13A4CEE2F74AAD1ED582272D56866BCBA0449DD6E701CC63FF2DD3B90551DAFE6F228ACF5E3F2B5FE0630B2E5C66D16AE17321A30A0701E511036AAB085C8D3672721EB89A6A6C5CD1406742343617A0B2B09DAD465A2798DEF580B49E25073F0CA98217F242BDB49FD43FB32D31B1983B271A92C13B2A5BD1F39FAF6EC9DE65B5181AB4F6AE3D7D052046ABED2928B5C0B98148EFFB3C2EFD06A61144DDBABE0C4B0E9EDAF0037652A9C5C658F0DAF177DDDFC589A906F46E4F1EBC4A915AE00BB9ACB01B1B62F605209929A8A4274AA498A884DC2E26A1BE9A4FBAD44CF68AA5F92ED35EC66455A01F2273DE2369AB2F07702171AE4D4A551AABAC9C53063C9F1697653877CDE27893DEDF391154D6E5866C919E0C154E5B2B6E00CBA6216FF5FE7EEBE52690BBE6A4CD0693BEDFCB6B217BBA802C6926CEA2021005568848D957894473D76D41254E97267C25836CC2DA3D515243F5C8FB7B
+20220714115834 2 6 100 3071 2 DA55F6EE023BA05F89B992D6CCEAAD8F6F787812100336939D4C7BD3E08406588C1D2D9C8F4F13A4CEE2F74AAD1ED582272D56866BCBA0449DD6E701CC63FF2DD3B90551DAFE6F228ACF5E3F2B5FE0630B2E5C66D16AE17321A30A0701E511036AAB085C8D3672721EB89A6A6C5CD1406742343617A0B2B09DAD465A2798DEF580B49E25073F0CA98217F242BDB49FD43FB32D31B1983B271A92C13B2A5BD1F39FAF6EC9DE65B5181AB4F6AE3D7D052046ABED2928B5C0B98148EFFB3C2EFD06A61144DDBABE0C4B0E9EDAF0037652A9C5C658F0DAF177DDDFC589A906F46E4F1EBC4A915AE00BB9ACB01B1B62F605209929A8A4274AA498A884DC2E26A1BE9A4FBAD44CF68AA5F92ED35EC66455A01F2273DE2369AB2F07702171AE4D4A551AABAC9C53063C9F1697653877CDE27893DEDF391154D6E5866C919E0C154E5B2B6E00CBA6216FF5FE7EEBE52690BBE6A4CD0693BEDFCB6B217BBA802C6926CEA2021005568848D957894473D76D41254E97267C25836CC2DA3D515243F5EAA1CB
+20220714120147 2 6 100 3071 2 DA55F6EE023BA05F89B992D6CCEAAD8F6F787812100336939D4C7BD3E08406588C1D2D9C8F4F13A4CEE2F74AAD1ED582272D56866BCBA0449DD6E701CC63FF2DD3B90551DAFE6F228ACF5E3F2B5FE0630B2E5C66D16AE17321A30A0701E511036AAB085C8D3672721EB89A6A6C5CD1406742343617A0B2B09DAD465A2798DEF580B49E25073F0CA98217F242BDB49FD43FB32D31B1983B271A92C13B2A5BD1F39FAF6EC9DE65B5181AB4F6AE3D7D052046ABED2928B5C0B98148EFFB3C2EFD06A61144DDBABE0C4B0E9EDAF0037652A9C5C658F0DAF177DDDFC589A906F46E4F1EBC4A915AE00BB9ACB01B1B62F605209929A8A4274AA498A884DC2E26A1BE9A4FBAD44CF68AA5F92ED35EC66455A01F2273DE2369AB2F07702171AE4D4A551AABAC9C53063C9F1697653877CDE27893DEDF391154D6E5866C919E0C154E5B2B6E00CBA6216FF5FE7EEBE52690BBE6A4CD0693BEDFCB6B217BBA802C6926CEA2021005568848D957894473D76D41254E97267C25836CC2DA3D515243F890B7EB
+20220714121337 2 6 100 4095 2 ED38FC9DDCD01CDF39C887875AA0A7EFF8682144089FC338C06E2C138653B5E7A082B537BA5C80A93B7192D153313DE56606C8E2A0CAE8370284BE3ADD97F04BD4EBDFD21A999E13461B544C49742DE120C46D046F6E9C55922E68FF3C8A115E51E70071377B60F8127EB9228A332BD38AF8EF1DA8EFA7012496070426203F3BEECBB286E33C053DC070CD919074DBA97E19C081C6CD8B74DBDF6674F64CD7A7B5F0B7E40B0FD607AF531D55FACAB38C9F550C1D60D89601E6BA1D6BA66F5E18D4C8D4D634C464EC748A260C285D84158CC3DFA9BC03973F32077F7D92C104314173584B96C43F22AFEFA135F3A4C5A0D959B963C8227A337DAC30D8B96F7580D67763621C9F51FAA9E2641D81565810770727EF4C25F8210CCF60B2480070556E874E59D910B9B1822B13420C2843BED4FA4F5CBD7822D651C07CB8657AD1B3629EB337CBA9F1FA50E819E9DEC1DB564FFBC1DEF0561079F96D8ABD0740BE2C997F4EEEF7E8244ECAA6E2BA85E832329220C26A7F088165F583343C190B245CEE6AE40E01D2AFAAFDD509302EBD989AE641131152538C749718FD8D1642B9802DACF3945C0A445D2ECDCF921F8E360495A564C0EE64D74224CF93119AFF5BEA0B61ABBF1DB67A6820A4BF9AD622207ECE7DB9ECE03B4FB6D69D06BBCBEACFCF62D85763DAA5B8C22385D5F4E22352C6EF6495485D00FD019FDF6D629C7D4793
+20220714121340 2 6 100 4095 5 ED38FC9DDCD01CDF39C887875AA0A7EFF8682144089FC338C06E2C138653B5E7A082B537BA5C80A93B7192D153313DE56606C8E2A0CAE8370284BE3ADD97F04BD4EBDFD21A999E13461B544C49742DE120C46D046F6E9C55922E68FF3C8A115E51E70071377B60F8127EB9228A332BD38AF8EF1DA8EFA7012496070426203F3BEECBB286E33C053DC070CD919074DBA97E19C081C6CD8B74DBDF6674F64CD7A7B5F0B7E40B0FD607AF531D55FACAB38C9F550C1D60D89601E6BA1D6BA66F5E18D4C8D4D634C464EC748A260C285D84158CC3DFA9BC03973F32077F7D92C104314173584B96C43F22AFEFA135F3A4C5A0D959B963C8227A337DAC30D8B96F7580D67763621C9F51FAA9E2641D81565810770727EF4C25F8210CCF60B2480070556E874E59D910B9B1822B13420C2843BED4FA4F5CBD7822D651C07CB8657AD1B3629EB337CBA9F1FA50E819E9DEC1DB564FFBC1DEF0561079F96D8ABD0740BE2C997F4EEEF7E8244ECAA6E2BA85E832329220C26A7F088165F583343C190B245CEE6AE40E01D2AFAAFDD509302EBD989AE641131152538C749718FD8D1642B9802DACF3945C0A445D2ECDCF921F8E360495A564C0EE64D74224CF93119AFF5BEA0B61ABBF1DB67A6820A4BF9AD622207ECE7DB9ECE03B4FB6D69D06BBCBEACFCF62D85763DAA5B8C22385D5F4E22352C6EF6495485D00FD019FDF6D629C8256DF
+20220714121625 2 6 100 4095 5 ED38FC9DDCD01CDF39C887875AA0A7EFF8682144089FC338C06E2C138653B5E7A082B537BA5C80A93B7192D153313DE56606C8E2A0CAE8370284BE3ADD97F04BD4EBDFD21A999E13461B544C49742DE120C46D046F6E9C55922E68FF3C8A115E51E70071377B60F8127EB9228A332BD38AF8EF1DA8EFA7012496070426203F3BEECBB286E33C053DC070CD919074DBA97E19C081C6CD8B74DBDF6674F64CD7A7B5F0B7E40B0FD607AF531D55FACAB38C9F550C1D60D89601E6BA1D6BA66F5E18D4C8D4D634C464EC748A260C285D84158CC3DFA9BC03973F32077F7D92C104314173584B96C43F22AFEFA135F3A4C5A0D959B963C8227A337DAC30D8B96F7580D67763621C9F51FAA9E2641D81565810770727EF4C25F8210CCF60B2480070556E874E59D910B9B1822B13420C2843BED4FA4F5CBD7822D651C07CB8657AD1B3629EB337CBA9F1FA50E819E9DEC1DB564FFBC1DEF0561079F96D8ABD0740BE2C997F4EEEF7E8244ECAA6E2BA85E832329220C26A7F088165F583343C190B245CEE6AE40E01D2AFAAFDD509302EBD989AE641131152538C749718FD8D1642B9802DACF3945C0A445D2ECDCF921F8E360495A564C0EE64D74224CF93119AFF5BEA0B61ABBF1DB67A6820A4BF9AD622207ECE7DB9ECE03B4FB6D69D06BBCBEACFCF62D85763DAA5B8C22385D5F4E22352C6EF6495485D00FD019FDF6D629DA597BF
+20220714122153 2 6 100 4095 2 ED38FC9DDCD01CDF39C887875AA0A7EFF8682144089FC338C06E2C138653B5E7A082B537BA5C80A93B7192D153313DE56606C8E2A0CAE8370284BE3ADD97F04BD4EBDFD21A999E13461B544C49742DE120C46D046F6E9C55922E68FF3C8A115E51E70071377B60F8127EB9228A332BD38AF8EF1DA8EFA7012496070426203F3BEECBB286E33C053DC070CD919074DBA97E19C081C6CD8B74DBDF6674F64CD7A7B5F0B7E40B0FD607AF531D55FACAB38C9F550C1D60D89601E6BA1D6BA66F5E18D4C8D4D634C464EC748A260C285D84158CC3DFA9BC03973F32077F7D92C104314173584B96C43F22AFEFA135F3A4C5A0D959B963C8227A337DAC30D8B96F7580D67763621C9F51FAA9E2641D81565810770727EF4C25F8210CCF60B2480070556E874E59D910B9B1822B13420C2843BED4FA4F5CBD7822D651C07CB8657AD1B3629EB337CBA9F1FA50E819E9DEC1DB564FFBC1DEF0561079F96D8ABD0740BE2C997F4EEEF7E8244ECAA6E2BA85E832329220C26A7F088165F583343C190B245CEE6AE40E01D2AFAAFDD509302EBD989AE641131152538C749718FD8D1642B9802DACF3945C0A445D2ECDCF921F8E360495A564C0EE64D74224CF93119AFF5BEA0B61ABBF1DB67A6820A4BF9AD622207ECE7DB9ECE03B4FB6D69D06BBCBEACFCF62D85763DAA5B8C22385D5F4E22352C6EF6495485D00FD019FDF6D629FE36413
+20220714122227 2 6 100 4095 2 ED38FC9DDCD01CDF39C887875AA0A7EFF8682144089FC338C06E2C138653B5E7A082B537BA5C80A93B7192D153313DE56606C8E2A0CAE8370284BE3ADD97F04BD4EBDFD21A999E13461B544C49742DE120C46D046F6E9C55922E68FF3C8A115E51E70071377B60F8127EB9228A332BD38AF8EF1DA8EFA7012496070426203F3BEECBB286E33C053DC070CD919074DBA97E19C081C6CD8B74DBDF6674F64CD7A7B5F0B7E40B0FD607AF531D55FACAB38C9F550C1D60D89601E6BA1D6BA66F5E18D4C8D4D634C464EC748A260C285D84158CC3DFA9BC03973F32077F7D92C104314173584B96C43F22AFEFA135F3A4C5A0D959B963C8227A337DAC30D8B96F7580D67763621C9F51FAA9E2641D81565810770727EF4C25F8210CCF60B2480070556E874E59D910B9B1822B13420C2843BED4FA4F5CBD7822D651C07CB8657AD1B3629EB337CBA9F1FA50E819E9DEC1DB564FFBC1DEF0561079F96D8ABD0740BE2C997F4EEEF7E8244ECAA6E2BA85E832329220C26A7F088165F583343C190B245CEE6AE40E01D2AFAAFDD509302EBD989AE641131152538C749718FD8D1642B9802DACF3945C0A445D2ECDCF921F8E360495A564C0EE64D74224CF93119AFF5BEA0B61ABBF1DB67A6820A4BF9AD622207ECE7DB9ECE03B4FB6D69D06BBCBEACFCF62D85763DAA5B8C22385D5F4E22352C6EF6495485D00FD019FDF6D62A01CEFF3
+20220714122714 2 6 100 4095 2 ED38FC9DDCD01CDF39C887875AA0A7EFF8682144089FC338C06E2C138653B5E7A082B537BA5C80A93B7192D153313DE56606C8E2A0CAE8370284BE3ADD97F04BD4EBDFD21A999E13461B544C49742DE120C46D046F6E9C55922E68FF3C8A115E51E70071377B60F8127EB9228A332BD38AF8EF1DA8EFA7012496070426203F3BEECBB286E33C053DC070CD919074DBA97E19C081C6CD8B74DBDF6674F64CD7A7B5F0B7E40B0FD607AF531D55FACAB38C9F550C1D60D89601E6BA1D6BA66F5E18D4C8D4D634C464EC748A260C285D84158CC3DFA9BC03973F32077F7D92C104314173584B96C43F22AFEFA135F3A4C5A0D959B963C8227A337DAC30D8B96F7580D67763621C9F51FAA9E2641D81565810770727EF4C25F8210CCF60B2480070556E874E59D910B9B1822B13420C2843BED4FA4F5CBD7822D651C07CB8657AD1B3629EB337CBA9F1FA50E819E9DEC1DB564FFBC1DEF0561079F96D8ABD0740BE2C997F4EEEF7E8244ECAA6E2BA85E832329220C26A7F088165F583343C190B245CEE6AE40E01D2AFAAFDD509302EBD989AE641131152538C749718FD8D1642B9802DACF3945C0A445D2ECDCF921F8E360495A564C0EE64D74224CF93119AFF5BEA0B61ABBF1DB67A6820A4BF9AD622207ECE7DB9ECE03B4FB6D69D06BBCBEACFCF62D85763DAA5B8C22385D5F4E22352C6EF6495485D00FD019FDF6D62A20F9823
+20220714122853 2 6 100 4095 2 ED38FC9DDCD01CDF39C887875AA0A7EFF8682144089FC338C06E2C138653B5E7A082B537BA5C80A93B7192D153313DE56606C8E2A0CAE8370284BE3ADD97F04BD4EBDFD21A999E13461B544C49742DE120C46D046F6E9C55922E68FF3C8A115E51E70071377B60F8127EB9228A332BD38AF8EF1DA8EFA7012496070426203F3BEECBB286E33C053DC070CD919074DBA97E19C081C6CD8B74DBDF6674F64CD7A7B5F0B7E40B0FD607AF531D55FACAB38C9F550C1D60D89601E6BA1D6BA66F5E18D4C8D4D634C464EC748A260C285D84158CC3DFA9BC03973F32077F7D92C104314173584B96C43F22AFEFA135F3A4C5A0D959B963C8227A337DAC30D8B96F7580D67763621C9F51FAA9E2641D81565810770727EF4C25F8210CCF60B2480070556E874E59D910B9B1822B13420C2843BED4FA4F5CBD7822D651C07CB8657AD1B3629EB337CBA9F1FA50E819E9DEC1DB564FFBC1DEF0561079F96D8ABD0740BE2C997F4EEEF7E8244ECAA6E2BA85E832329220C26A7F088165F583343C190B245CEE6AE40E01D2AFAAFDD509302EBD989AE641131152538C749718FD8D1642B9802DACF3945C0A445D2ECDCF921F8E360495A564C0EE64D74224CF93119AFF5BEA0B61ABBF1DB67A6820A4BF9AD622207ECE7DB9ECE03B4FB6D69D06BBCBEACFCF62D85763DAA5B8C22385D5F4E22352C6EF6495485D00FD019FDF6D62A2BD77FB
+20220714123034 2 6 100 4095 5 ED38FC9DDCD01CDF39C887875AA0A7EFF8682144089FC338C06E2C138653B5E7A082B537BA5C80A93B7192D153313DE56606C8E2A0CAE8370284BE3ADD97F04BD4EBDFD21A999E13461B544C49742DE120C46D046F6E9C55922E68FF3C8A115E51E70071377B60F8127EB9228A332BD38AF8EF1DA8EFA7012496070426203F3BEECBB286E33C053DC070CD919074DBA97E19C081C6CD8B74DBDF6674F64CD7A7B5F0B7E40B0FD607AF531D55FACAB38C9F550C1D60D89601E6BA1D6BA66F5E18D4C8D4D634C464EC748A260C285D84158CC3DFA9BC03973F32077F7D92C104314173584B96C43F22AFEFA135F3A4C5A0D959B963C8227A337DAC30D8B96F7580D67763621C9F51FAA9E2641D81565810770727EF4C25F8210CCF60B2480070556E874E59D910B9B1822B13420C2843BED4FA4F5CBD7822D651C07CB8657AD1B3629EB337CBA9F1FA50E819E9DEC1DB564FFBC1DEF0561079F96D8ABD0740BE2C997F4EEEF7E8244ECAA6E2BA85E832329220C26A7F088165F583343C190B245CEE6AE40E01D2AFAAFDD509302EBD989AE641131152538C749718FD8D1642B9802DACF3945C0A445D2ECDCF921F8E360495A564C0EE64D74224CF93119AFF5BEA0B61ABBF1DB67A6820A4BF9AD622207ECE7DB9ECE03B4FB6D69D06BBCBEACFCF62D85763DAA5B8C22385D5F4E22352C6EF6495485D00FD019FDF6D62A36B3637
+20220714123040 2 6 100 4095 2 ED38FC9DDCD01CDF39C887875AA0A7EFF8682144089FC338C06E2C138653B5E7A082B537BA5C80A93B7192D153313DE56606C8E2A0CAE8370284BE3ADD97F04BD4EBDFD21A999E13461B544C49742DE120C46D046F6E9C55922E68FF3C8A115E51E70071377B60F8127EB9228A332BD38AF8EF1DA8EFA7012496070426203F3BEECBB286E33C053DC070CD919074DBA97E19C081C6CD8B74DBDF6674F64CD7A7B5F0B7E40B0FD607AF531D55FACAB38C9F550C1D60D89601E6BA1D6BA66F5E18D4C8D4D634C464EC748A260C285D84158CC3DFA9BC03973F32077F7D92C104314173584B96C43F22AFEFA135F3A4C5A0D959B963C8227A337DAC30D8B96F7580D67763621C9F51FAA9E2641D81565810770727EF4C25F8210CCF60B2480070556E874E59D910B9B1822B13420C2843BED4FA4F5CBD7822D651C07CB8657AD1B3629EB337CBA9F1FA50E819E9DEC1DB564FFBC1DEF0561079F96D8ABD0740BE2C997F4EEEF7E8244ECAA6E2BA85E832329220C26A7F088165F583343C190B245CEE6AE40E01D2AFAAFDD509302EBD989AE641131152538C749718FD8D1642B9802DACF3945C0A445D2ECDCF921F8E360495A564C0EE64D74224CF93119AFF5BEA0B61ABBF1DB67A6820A4BF9AD622207ECE7DB9ECE03B4FB6D69D06BBCBEACFCF62D85763DAA5B8C22385D5F4E22352C6EF6495485D00FD019FDF6D62A3746D03
+20220714123232 2 6 100 4095 5 ED38FC9DDCD01CDF39C887875AA0A7EFF8682144089FC338C06E2C138653B5E7A082B537BA5C80A93B7192D153313DE56606C8E2A0CAE8370284BE3ADD97F04BD4EBDFD21A999E13461B544C49742DE120C46D046F6E9C55922E68FF3C8A115E51E70071377B60F8127EB9228A332BD38AF8EF1DA8EFA7012496070426203F3BEECBB286E33C053DC070CD919074DBA97E19C081C6CD8B74DBDF6674F64CD7A7B5F0B7E40B0FD607AF531D55FACAB38C9F550C1D60D89601E6BA1D6BA66F5E18D4C8D4D634C464EC748A260C285D84158CC3DFA9BC03973F32077F7D92C104314173584B96C43F22AFEFA135F3A4C5A0D959B963C8227A337DAC30D8B96F7580D67763621C9F51FAA9E2641D81565810770727EF4C25F8210CCF60B2480070556E874E59D910B9B1822B13420C2843BED4FA4F5CBD7822D651C07CB8657AD1B3629EB337CBA9F1FA50E819E9DEC1DB564FFBC1DEF0561079F96D8ABD0740BE2C997F4EEEF7E8244ECAA6E2BA85E832329220C26A7F088165F583343C190B245CEE6AE40E01D2AFAAFDD509302EBD989AE641131152538C749718FD8D1642B9802DACF3945C0A445D2ECDCF921F8E360495A564C0EE64D74224CF93119AFF5BEA0B61ABBF1DB67A6820A4BF9AD622207ECE7DB9ECE03B4FB6D69D06BBCBEACFCF62D85763DAA5B8C22385D5F4E22352C6EF6495485D00FD019FDF6D62A437C667
+20220714123319 2 6 100 4095 2 ED38FC9DDCD01CDF39C887875AA0A7EFF8682144089FC338C06E2C138653B5E7A082B537BA5C80A93B7192D153313DE56606C8E2A0CAE8370284BE3ADD97F04BD4EBDFD21A999E13461B544C49742DE120C46D046F6E9C55922E68FF3C8A115E51E70071377B60F8127EB9228A332BD38AF8EF1DA8EFA7012496070426203F3BEECBB286E33C053DC070CD919074DBA97E19C081C6CD8B74DBDF6674F64CD7A7B5F0B7E40B0FD607AF531D55FACAB38C9F550C1D60D89601E6BA1D6BA66F5E18D4C8D4D634C464EC748A260C285D84158CC3DFA9BC03973F32077F7D92C104314173584B96C43F22AFEFA135F3A4C5A0D959B963C8227A337DAC30D8B96F7580D67763621C9F51FAA9E2641D81565810770727EF4C25F8210CCF60B2480070556E874E59D910B9B1822B13420C2843BED4FA4F5CBD7822D651C07CB8657AD1B3629EB337CBA9F1FA50E819E9DEC1DB564FFBC1DEF0561079F96D8ABD0740BE2C997F4EEEF7E8244ECAA6E2BA85E832329220C26A7F088165F583343C190B245CEE6AE40E01D2AFAAFDD509302EBD989AE641131152538C749718FD8D1642B9802DACF3945C0A445D2ECDCF921F8E360495A564C0EE64D74224CF93119AFF5BEA0B61ABBF1DB67A6820A4BF9AD622207ECE7DB9ECE03B4FB6D69D06BBCBEACFCF62D85763DAA5B8C22385D5F4E22352C6EF6495485D00FD019FDF6D62A487CC0B
+20220714123750 2 6 100 4095 5 ED38FC9DDCD01CDF39C887875AA0A7EFF8682144089FC338C06E2C138653B5E7A082B537BA5C80A93B7192D153313DE56606C8E2A0CAE8370284BE3ADD97F04BD4EBDFD21A999E13461B544C49742DE120C46D046F6E9C55922E68FF3C8A115E51E70071377B60F8127EB9228A332BD38AF8EF1DA8EFA7012496070426203F3BEECBB286E33C053DC070CD919074DBA97E19C081C6CD8B74DBDF6674F64CD7A7B5F0B7E40B0FD607AF531D55FACAB38C9F550C1D60D89601E6BA1D6BA66F5E18D4C8D4D634C464EC748A260C285D84158CC3DFA9BC03973F32077F7D92C104314173584B96C43F22AFEFA135F3A4C5A0D959B963C8227A337DAC30D8B96F7580D67763621C9F51FAA9E2641D81565810770727EF4C25F8210CCF60B2480070556E874E59D910B9B1822B13420C2843BED4FA4F5CBD7822D651C07CB8657AD1B3629EB337CBA9F1FA50E819E9DEC1DB564FFBC1DEF0561079F96D8ABD0740BE2C997F4EEEF7E8244ECAA6E2BA85E832329220C26A7F088165F583343C190B245CEE6AE40E01D2AFAAFDD509302EBD989AE641131152538C749718FD8D1642B9802DACF3945C0A445D2ECDCF921F8E360495A564C0EE64D74224CF93119AFF5BEA0B61ABBF1DB67A6820A4BF9AD622207ECE7DB9ECE03B4FB6D69D06BBCBEACFCF62D85763DAA5B8C22385D5F4E22352C6EF6495485D00FD019FDF6D62A65E695F
+20220714123800 2 6 100 4095 2 ED38FC9DDCD01CDF39C887875AA0A7EFF8682144089FC338C06E2C138653B5E7A082B537BA5C80A93B7192D153313DE56606C8E2A0CAE8370284BE3ADD97F04BD4EBDFD21A999E13461B544C49742DE120C46D046F6E9C55922E68FF3C8A115E51E70071377B60F8127EB9228A332BD38AF8EF1DA8EFA7012496070426203F3BEECBB286E33C053DC070CD919074DBA97E19C081C6CD8B74DBDF6674F64CD7A7B5F0B7E40B0FD607AF531D55FACAB38C9F550C1D60D89601E6BA1D6BA66F5E18D4C8D4D634C464EC748A260C285D84158CC3DFA9BC03973F32077F7D92C104314173584B96C43F22AFEFA135F3A4C5A0D959B963C8227A337DAC30D8B96F7580D67763621C9F51FAA9E2641D81565810770727EF4C25F8210CCF60B2480070556E874E59D910B9B1822B13420C2843BED4FA4F5CBD7822D651C07CB8657AD1B3629EB337CBA9F1FA50E819E9DEC1DB564FFBC1DEF0561079F96D8ABD0740BE2C997F4EEEF7E8244ECAA6E2BA85E832329220C26A7F088165F583343C190B245CEE6AE40E01D2AFAAFDD509302EBD989AE641131152538C749718FD8D1642B9802DACF3945C0A445D2ECDCF921F8E360495A564C0EE64D74224CF93119AFF5BEA0B61ABBF1DB67A6820A4BF9AD622207ECE7DB9ECE03B4FB6D69D06BBCBEACFCF62D85763DAA5B8C22385D5F4E22352C6EF6495485D00FD019FDF6D62A66E6103
+20220714124312 2 6 100 4095 5 ED38FC9DDCD01CDF39C887875AA0A7EFF8682144089FC338C06E2C138653B5E7A082B537BA5C80A93B7192D153313DE56606C8E2A0CAE8370284BE3ADD97F04BD4EBDFD21A999E13461B544C49742DE120C46D046F6E9C55922E68FF3C8A115E51E70071377B60F8127EB9228A332BD38AF8EF1DA8EFA7012496070426203F3BEECBB286E33C053DC070CD919074DBA97E19C081C6CD8B74DBDF6674F64CD7A7B5F0B7E40B0FD607AF531D55FACAB38C9F550C1D60D89601E6BA1D6BA66F5E18D4C8D4D634C464EC748A260C285D84158CC3DFA9BC03973F32077F7D92C104314173584B96C43F22AFEFA135F3A4C5A0D959B963C8227A337DAC30D8B96F7580D67763621C9F51FAA9E2641D81565810770727EF4C25F8210CCF60B2480070556E874E59D910B9B1822B13420C2843BED4FA4F5CBD7822D651C07CB8657AD1B3629EB337CBA9F1FA50E819E9DEC1DB564FFBC1DEF0561079F96D8ABD0740BE2C997F4EEEF7E8244ECAA6E2BA85E832329220C26A7F088165F583343C190B245CEE6AE40E01D2AFAAFDD509302EBD989AE641131152538C749718FD8D1642B9802DACF3945C0A445D2ECDCF921F8E360495A564C0EE64D74224CF93119AFF5BEA0B61ABBF1DB67A6820A4BF9AD622207ECE7DB9ECE03B4FB6D69D06BBCBEACFCF62D85763DAA5B8C22385D5F4E22352C6EF6495485D00FD019FDF6D62A8859627
+20220714124408 2 6 100 4095 2 ED38FC9DDCD01CDF39C887875AA0A7EFF8682144089FC338C06E2C138653B5E7A082B537BA5C80A93B7192D153313DE56606C8E2A0CAE8370284BE3ADD97F04BD4EBDFD21A999E13461B544C49742DE120C46D046F6E9C55922E68FF3C8A115E51E70071377B60F8127EB9228A332BD38AF8EF1DA8EFA7012496070426203F3BEECBB286E33C053DC070CD919074DBA97E19C081C6CD8B74DBDF6674F64CD7A7B5F0B7E40B0FD607AF531D55FACAB38C9F550C1D60D89601E6BA1D6BA66F5E18D4C8D4D634C464EC748A260C285D84158CC3DFA9BC03973F32077F7D92C104314173584B96C43F22AFEFA135F3A4C5A0D959B963C8227A337DAC30D8B96F7580D67763621C9F51FAA9E2641D81565810770727EF4C25F8210CCF60B2480070556E874E59D910B9B1822B13420C2843BED4FA4F5CBD7822D651C07CB8657AD1B3629EB337CBA9F1FA50E819E9DEC1DB564FFBC1DEF0561079F96D8ABD0740BE2C997F4EEEF7E8244ECAA6E2BA85E832329220C26A7F088165F583343C190B245CEE6AE40E01D2AFAAFDD509302EBD989AE641131152538C749718FD8D1642B9802DACF3945C0A445D2ECDCF921F8E360495A564C0EE64D74224CF93119AFF5BEA0B61ABBF1DB67A6820A4BF9AD622207ECE7DB9ECE03B4FB6D69D06BBCBEACFCF62D85763DAA5B8C22385D5F4E22352C6EF6495485D00FD019FDF6D62A8E56B5B
+20220714124440 2 6 100 4095 5 ED38FC9DDCD01CDF39C887875AA0A7EFF8682144089FC338C06E2C138653B5E7A082B537BA5C80A93B7192D153313DE56606C8E2A0CAE8370284BE3ADD97F04BD4EBDFD21A999E13461B544C49742DE120C46D046F6E9C55922E68FF3C8A115E51E70071377B60F8127EB9228A332BD38AF8EF1DA8EFA7012496070426203F3BEECBB286E33C053DC070CD919074DBA97E19C081C6CD8B74DBDF6674F64CD7A7B5F0B7E40B0FD607AF531D55FACAB38C9F550C1D60D89601E6BA1D6BA66F5E18D4C8D4D634C464EC748A260C285D84158CC3DFA9BC03973F32077F7D92C104314173584B96C43F22AFEFA135F3A4C5A0D959B963C8227A337DAC30D8B96F7580D67763621C9F51FAA9E2641D81565810770727EF4C25F8210CCF60B2480070556E874E59D910B9B1822B13420C2843BED4FA4F5CBD7822D651C07CB8657AD1B3629EB337CBA9F1FA50E819E9DEC1DB564FFBC1DEF0561079F96D8ABD0740BE2C997F4EEEF7E8244ECAA6E2BA85E832329220C26A7F088165F583343C190B245CEE6AE40E01D2AFAAFDD509302EBD989AE641131152538C749718FD8D1642B9802DACF3945C0A445D2ECDCF921F8E360495A564C0EE64D74224CF93119AFF5BEA0B61ABBF1DB67A6820A4BF9AD622207ECE7DB9ECE03B4FB6D69D06BBCBEACFCF62D85763DAA5B8C22385D5F4E22352C6EF6495485D00FD019FDF6D62A91A43B7
+20220714124606 2 6 100 4095 5 ED38FC9DDCD01CDF39C887875AA0A7EFF8682144089FC338C06E2C138653B5E7A082B537BA5C80A93B7192D153313DE56606C8E2A0CAE8370284BE3ADD97F04BD4EBDFD21A999E13461B544C49742DE120C46D046F6E9C55922E68FF3C8A115E51E70071377B60F8127EB9228A332BD38AF8EF1DA8EFA7012496070426203F3BEECBB286E33C053DC070CD919074DBA97E19C081C6CD8B74DBDF6674F64CD7A7B5F0B7E40B0FD607AF531D55FACAB38C9F550C1D60D89601E6BA1D6BA66F5E18D4C8D4D634C464EC748A260C285D84158CC3DFA9BC03973F32077F7D92C104314173584B96C43F22AFEFA135F3A4C5A0D959B963C8227A337DAC30D8B96F7580D67763621C9F51FAA9E2641D81565810770727EF4C25F8210CCF60B2480070556E874E59D910B9B1822B13420C2843BED4FA4F5CBD7822D651C07CB8657AD1B3629EB337CBA9F1FA50E819E9DEC1DB564FFBC1DEF0561079F96D8ABD0740BE2C997F4EEEF7E8244ECAA6E2BA85E832329220C26A7F088165F583343C190B245CEE6AE40E01D2AFAAFDD509302EBD989AE641131152538C749718FD8D1642B9802DACF3945C0A445D2ECDCF921F8E360495A564C0EE64D74224CF93119AFF5BEA0B61ABBF1DB67A6820A4BF9AD622207ECE7DB9ECE03B4FB6D69D06BBCBEACFCF62D85763DAA5B8C22385D5F4E22352C6EF6495485D00FD019FDF6D62A9B26B87
+20220714124627 2 6 100 4095 5 ED38FC9DDCD01CDF39C887875AA0A7EFF8682144089FC338C06E2C138653B5E7A082B537BA5C80A93B7192D153313DE56606C8E2A0CAE8370284BE3ADD97F04BD4EBDFD21A999E13461B544C49742DE120C46D046F6E9C55922E68FF3C8A115E51E70071377B60F8127EB9228A332BD38AF8EF1DA8EFA7012496070426203F3BEECBB286E33C053DC070CD919074DBA97E19C081C6CD8B74DBDF6674F64CD7A7B5F0B7E40B0FD607AF531D55FACAB38C9F550C1D60D89601E6BA1D6BA66F5E18D4C8D4D634C464EC748A260C285D84158CC3DFA9BC03973F32077F7D92C104314173584B96C43F22AFEFA135F3A4C5A0D959B963C8227A337DAC30D8B96F7580D67763621C9F51FAA9E2641D81565810770727EF4C25F8210CCF60B2480070556E874E59D910B9B1822B13420C2843BED4FA4F5CBD7822D651C07CB8657AD1B3629EB337CBA9F1FA50E819E9DEC1DB564FFBC1DEF0561079F96D8ABD0740BE2C997F4EEEF7E8244ECAA6E2BA85E832329220C26A7F088165F583343C190B245CEE6AE40E01D2AFAAFDD509302EBD989AE641131152538C749718FD8D1642B9802DACF3945C0A445D2ECDCF921F8E360495A564C0EE64D74224CF93119AFF5BEA0B61ABBF1DB67A6820A4BF9AD622207ECE7DB9ECE03B4FB6D69D06BBCBEACFCF62D85763DAA5B8C22385D5F4E22352C6EF6495485D00FD019FDF6D62A9D62D47
+20220714124631 2 6 100 4095 5 ED38FC9DDCD01CDF39C887875AA0A7EFF8682144089FC338C06E2C138653B5E7A082B537BA5C80A93B7192D153313DE56606C8E2A0CAE8370284BE3ADD97F04BD4EBDFD21A999E13461B544C49742DE120C46D046F6E9C55922E68FF3C8A115E51E70071377B60F8127EB9228A332BD38AF8EF1DA8EFA7012496070426203F3BEECBB286E33C053DC070CD919074DBA97E19C081C6CD8B74DBDF6674F64CD7A7B5F0B7E40B0FD607AF531D55FACAB38C9F550C1D60D89601E6BA1D6BA66F5E18D4C8D4D634C464EC748A260C285D84158CC3DFA9BC03973F32077F7D92C104314173584B96C43F22AFEFA135F3A4C5A0D959B963C8227A337DAC30D8B96F7580D67763621C9F51FAA9E2641D81565810770727EF4C25F8210CCF60B2480070556E874E59D910B9B1822B13420C2843BED4FA4F5CBD7822D651C07CB8657AD1B3629EB337CBA9F1FA50E819E9DEC1DB564FFBC1DEF0561079F96D8ABD0740BE2C997F4EEEF7E8244ECAA6E2BA85E832329220C26A7F088165F583343C190B245CEE6AE40E01D2AFAAFDD509302EBD989AE641131152538C749718FD8D1642B9802DACF3945C0A445D2ECDCF921F8E360495A564C0EE64D74224CF93119AFF5BEA0B61ABBF1DB67A6820A4BF9AD622207ECE7DB9ECE03B4FB6D69D06BBCBEACFCF62D85763DAA5B8C22385D5F4E22352C6EF6495485D00FD019FDF6D62A9DC09BF
+20220714125015 2 6 100 4095 2 ED38FC9DDCD01CDF39C887875AA0A7EFF8682144089FC338C06E2C138653B5E7A082B537BA5C80A93B7192D153313DE56606C8E2A0CAE8370284BE3ADD97F04BD4EBDFD21A999E13461B544C49742DE120C46D046F6E9C55922E68FF3C8A115E51E70071377B60F8127EB9228A332BD38AF8EF1DA8EFA7012496070426203F3BEECBB286E33C053DC070CD919074DBA97E19C081C6CD8B74DBDF6674F64CD7A7B5F0B7E40B0FD607AF531D55FACAB38C9F550C1D60D89601E6BA1D6BA66F5E18D4C8D4D634C464EC748A260C285D84158CC3DFA9BC03973F32077F7D92C104314173584B96C43F22AFEFA135F3A4C5A0D959B963C8227A337DAC30D8B96F7580D67763621C9F51FAA9E2641D81565810770727EF4C25F8210CCF60B2480070556E874E59D910B9B1822B13420C2843BED4FA4F5CBD7822D651C07CB8657AD1B3629EB337CBA9F1FA50E819E9DEC1DB564FFBC1DEF0561079F96D8ABD0740BE2C997F4EEEF7E8244ECAA6E2BA85E832329220C26A7F088165F583343C190B245CEE6AE40E01D2AFAAFDD509302EBD989AE641131152538C749718FD8D1642B9802DACF3945C0A445D2ECDCF921F8E360495A564C0EE64D74224CF93119AFF5BEA0B61ABBF1DB67A6820A4BF9AD622207ECE7DB9ECE03B4FB6D69D06BBCBEACFCF62D85763DAA5B8C22385D5F4E22352C6EF6495485D00FD019FDF6D62AB5FE7E3
+20220714125134 2 6 100 4095 5 ED38FC9DDCD01CDF39C887875AA0A7EFF8682144089FC338C06E2C138653B5E7A082B537BA5C80A93B7192D153313DE56606C8E2A0CAE8370284BE3ADD97F04BD4EBDFD21A999E13461B544C49742DE120C46D046F6E9C55922E68FF3C8A115E51E70071377B60F8127EB9228A332BD38AF8EF1DA8EFA7012496070426203F3BEECBB286E33C053DC070CD919074DBA97E19C081C6CD8B74DBDF6674F64CD7A7B5F0B7E40B0FD607AF531D55FACAB38C9F550C1D60D89601E6BA1D6BA66F5E18D4C8D4D634C464EC748A260C285D84158CC3DFA9BC03973F32077F7D92C104314173584B96C43F22AFEFA135F3A4C5A0D959B963C8227A337DAC30D8B96F7580D67763621C9F51FAA9E2641D81565810770727EF4C25F8210CCF60B2480070556E874E59D910B9B1822B13420C2843BED4FA4F5CBD7822D651C07CB8657AD1B3629EB337CBA9F1FA50E819E9DEC1DB564FFBC1DEF0561079F96D8ABD0740BE2C997F4EEEF7E8244ECAA6E2BA85E832329220C26A7F088165F583343C190B245CEE6AE40E01D2AFAAFDD509302EBD989AE641131152538C749718FD8D1642B9802DACF3945C0A445D2ECDCF921F8E360495A564C0EE64D74224CF93119AFF5BEA0B61ABBF1DB67A6820A4BF9AD622207ECE7DB9ECE03B4FB6D69D06BBCBEACFCF62D85763DAA5B8C22385D5F4E22352C6EF6495485D00FD019FDF6D62ABE6A13F
+20220714125205 2 6 100 4095 5 ED38FC9DDCD01CDF39C887875AA0A7EFF8682144089FC338C06E2C138653B5E7A082B537BA5C80A93B7192D153313DE56606C8E2A0CAE8370284BE3ADD97F04BD4EBDFD21A999E13461B544C49742DE120C46D046F6E9C55922E68FF3C8A115E51E70071377B60F8127EB9228A332BD38AF8EF1DA8EFA7012496070426203F3BEECBB286E33C053DC070CD919074DBA97E19C081C6CD8B74DBDF6674F64CD7A7B5F0B7E40B0FD607AF531D55FACAB38C9F550C1D60D89601E6BA1D6BA66F5E18D4C8D4D634C464EC748A260C285D84158CC3DFA9BC03973F32077F7D92C104314173584B96C43F22AFEFA135F3A4C5A0D959B963C8227A337DAC30D8B96F7580D67763621C9F51FAA9E2641D81565810770727EF4C25F8210CCF60B2480070556E874E59D910B9B1822B13420C2843BED4FA4F5CBD7822D651C07CB8657AD1B3629EB337CBA9F1FA50E819E9DEC1DB564FFBC1DEF0561079F96D8ABD0740BE2C997F4EEEF7E8244ECAA6E2BA85E832329220C26A7F088165F583343C190B245CEE6AE40E01D2AFAAFDD509302EBD989AE641131152538C749718FD8D1642B9802DACF3945C0A445D2ECDCF921F8E360495A564C0EE64D74224CF93119AFF5BEA0B61ABBF1DB67A6820A4BF9AD622207ECE7DB9ECE03B4FB6D69D06BBCBEACFCF62D85763DAA5B8C22385D5F4E22352C6EF6495485D00FD019FDF6D62AC1B5F1F
+20220714125308 2 6 100 4095 5 ED38FC9DDCD01CDF39C887875AA0A7EFF8682144089FC338C06E2C138653B5E7A082B537BA5C80A93B7192D153313DE56606C8E2A0CAE8370284BE3ADD97F04BD4EBDFD21A999E13461B544C49742DE120C46D046F6E9C55922E68FF3C8A115E51E70071377B60F8127EB9228A332BD38AF8EF1DA8EFA7012496070426203F3BEECBB286E33C053DC070CD919074DBA97E19C081C6CD8B74DBDF6674F64CD7A7B5F0B7E40B0FD607AF531D55FACAB38C9F550C1D60D89601E6BA1D6BA66F5E18D4C8D4D634C464EC748A260C285D84158CC3DFA9BC03973F32077F7D92C104314173584B96C43F22AFEFA135F3A4C5A0D959B963C8227A337DAC30D8B96F7580D67763621C9F51FAA9E2641D81565810770727EF4C25F8210CCF60B2480070556E874E59D910B9B1822B13420C2843BED4FA4F5CBD7822D651C07CB8657AD1B3629EB337CBA9F1FA50E819E9DEC1DB564FFBC1DEF0561079F96D8ABD0740BE2C997F4EEEF7E8244ECAA6E2BA85E832329220C26A7F088165F583343C190B245CEE6AE40E01D2AFAAFDD509302EBD989AE641131152538C749718FD8D1642B9802DACF3945C0A445D2ECDCF921F8E360495A564C0EE64D74224CF93119AFF5BEA0B61ABBF1DB67A6820A4BF9AD622207ECE7DB9ECE03B4FB6D69D06BBCBEACFCF62D85763DAA5B8C22385D5F4E22352C6EF6495485D00FD019FDF6D62AC85569F
+20220714125411 2 6 100 4095 5 ED38FC9DDCD01CDF39C887875AA0A7EFF8682144089FC338C06E2C138653B5E7A082B537BA5C80A93B7192D153313DE56606C8E2A0CAE8370284BE3ADD97F04BD4EBDFD21A999E13461B544C49742DE120C46D046F6E9C55922E68FF3C8A115E51E70071377B60F8127EB9228A332BD38AF8EF1DA8EFA7012496070426203F3BEECBB286E33C053DC070CD919074DBA97E19C081C6CD8B74DBDF6674F64CD7A7B5F0B7E40B0FD607AF531D55FACAB38C9F550C1D60D89601E6BA1D6BA66F5E18D4C8D4D634C464EC748A260C285D84158CC3DFA9BC03973F32077F7D92C104314173584B96C43F22AFEFA135F3A4C5A0D959B963C8227A337DAC30D8B96F7580D67763621C9F51FAA9E2641D81565810770727EF4C25F8210CCF60B2480070556E874E59D910B9B1822B13420C2843BED4FA4F5CBD7822D651C07CB8657AD1B3629EB337CBA9F1FA50E819E9DEC1DB564FFBC1DEF0561079F96D8ABD0740BE2C997F4EEEF7E8244ECAA6E2BA85E832329220C26A7F088165F583343C190B245CEE6AE40E01D2AFAAFDD509302EBD989AE641131152538C749718FD8D1642B9802DACF3945C0A445D2ECDCF921F8E360495A564C0EE64D74224CF93119AFF5BEA0B61ABBF1DB67A6820A4BF9AD622207ECE7DB9ECE03B4FB6D69D06BBCBEACFCF62D85763DAA5B8C22385D5F4E22352C6EF6495485D00FD019FDF6D62ACF096CF
+20220714130454 2 6 100 4095 2 ED38FC9DDCD01CDF39C887875AA0A7EFF8682144089FC338C06E2C138653B5E7A082B537BA5C80A93B7192D153313DE56606C8E2A0CAE8370284BE3ADD97F04BD4EBDFD21A999E13461B544C49742DE120C46D046F6E9C55922E68FF3C8A115E51E70071377B60F8127EB9228A332BD38AF8EF1DA8EFA7012496070426203F3BEECBB286E33C053DC070CD919074DBA97E19C081C6CD8B74DBDF6674F64CD7A7B5F0B7E40B0FD607AF531D55FACAB38C9F550C1D60D89601E6BA1D6BA66F5E18D4C8D4D634C464EC748A260C285D84158CC3DFA9BC03973F32077F7D92C104314173584B96C43F22AFEFA135F3A4C5A0D959B963C8227A337DAC30D8B96F7580D67763621C9F51FAA9E2641D81565810770727EF4C25F8210CCF60B2480070556E874E59D910B9B1822B13420C2843BED4FA4F5CBD7822D651C07CB8657AD1B3629EB337CBA9F1FA50E819E9DEC1DB564FFBC1DEF0561079F96D8ABD0740BE2C997F4EEEF7E8244ECAA6E2BA85E832329220C26A7F088165F583343C190B245CEE6AE40E01D2AFAAFDD509302EBD989AE641131152538C749718FD8D1642B9802DACF3945C0A445D2ECDCF921F8E360495A564C0EE64D74224CF93119AFF5BEA0B61ABBF1DB67A6820A4BF9AD622207ECE7DB9ECE03B4FB6D69D06BBCBEACFCF62D85763DAA5B8C22385D5F4E22352C6EF6495485D00FD019FDF6D62B1384403
+20220714130821 2 6 100 4095 2 ED38FC9DDCD01CDF39C887875AA0A7EFF8682144089FC338C06E2C138653B5E7A082B537BA5C80A93B7192D153313DE56606C8E2A0CAE8370284BE3ADD97F04BD4EBDFD21A999E13461B544C49742DE120C46D046F6E9C55922E68FF3C8A115E51E70071377B60F8127EB9228A332BD38AF8EF1DA8EFA7012496070426203F3BEECBB286E33C053DC070CD919074DBA97E19C081C6CD8B74DBDF6674F64CD7A7B5F0B7E40B0FD607AF531D55FACAB38C9F550C1D60D89601E6BA1D6BA66F5E18D4C8D4D634C464EC748A260C285D84158CC3DFA9BC03973F32077F7D92C104314173584B96C43F22AFEFA135F3A4C5A0D959B963C8227A337DAC30D8B96F7580D67763621C9F51FAA9E2641D81565810770727EF4C25F8210CCF60B2480070556E874E59D910B9B1822B13420C2843BED4FA4F5CBD7822D651C07CB8657AD1B3629EB337CBA9F1FA50E819E9DEC1DB564FFBC1DEF0561079F96D8ABD0740BE2C997F4EEEF7E8244ECAA6E2BA85E832329220C26A7F088165F583343C190B245CEE6AE40E01D2AFAAFDD509302EBD989AE641131152538C749718FD8D1642B9802DACF3945C0A445D2ECDCF921F8E360495A564C0EE64D74224CF93119AFF5BEA0B61ABBF1DB67A6820A4BF9AD622207ECE7DB9ECE03B4FB6D69D06BBCBEACFCF62D85763DAA5B8C22385D5F4E22352C6EF6495485D00FD019FDF6D62B295BE03
+20220714131228 2 6 100 4095 5 ED38FC9DDCD01CDF39C887875AA0A7EFF8682144089FC338C06E2C138653B5E7A082B537BA5C80A93B7192D153313DE56606C8E2A0CAE8370284BE3ADD97F04BD4EBDFD21A999E13461B544C49742DE120C46D046F6E9C55922E68FF3C8A115E51E70071377B60F8127EB9228A332BD38AF8EF1DA8EFA7012496070426203F3BEECBB286E33C053DC070CD919074DBA97E19C081C6CD8B74DBDF6674F64CD7A7B5F0B7E40B0FD607AF531D55FACAB38C9F550C1D60D89601E6BA1D6BA66F5E18D4C8D4D634C464EC748A260C285D84158CC3DFA9BC03973F32077F7D92C104314173584B96C43F22AFEFA135F3A4C5A0D959B963C8227A337DAC30D8B96F7580D67763621C9F51FAA9E2641D81565810770727EF4C25F8210CCF60B2480070556E874E59D910B9B1822B13420C2843BED4FA4F5CBD7822D651C07CB8657AD1B3629EB337CBA9F1FA50E819E9DEC1DB564FFBC1DEF0561079F96D8ABD0740BE2C997F4EEEF7E8244ECAA6E2BA85E832329220C26A7F088165F583343C190B245CEE6AE40E01D2AFAAFDD509302EBD989AE641131152538C749718FD8D1642B9802DACF3945C0A445D2ECDCF921F8E360495A564C0EE64D74224CF93119AFF5BEA0B61ABBF1DB67A6820A4BF9AD622207ECE7DB9ECE03B4FB6D69D06BBCBEACFCF62D85763DAA5B8C22385D5F4E22352C6EF6495485D00FD019FDF6D62B434EA3F
+20220714131424 2 6 100 4095 2 ED38FC9DDCD01CDF39C887875AA0A7EFF8682144089FC338C06E2C138653B5E7A082B537BA5C80A93B7192D153313DE56606C8E2A0CAE8370284BE3ADD97F04BD4EBDFD21A999E13461B544C49742DE120C46D046F6E9C55922E68FF3C8A115E51E70071377B60F8127EB9228A332BD38AF8EF1DA8EFA7012496070426203F3BEECBB286E33C053DC070CD919074DBA97E19C081C6CD8B74DBDF6674F64CD7A7B5F0B7E40B0FD607AF531D55FACAB38C9F550C1D60D89601E6BA1D6BA66F5E18D4C8D4D634C464EC748A260C285D84158CC3DFA9BC03973F32077F7D92C104314173584B96C43F22AFEFA135F3A4C5A0D959B963C8227A337DAC30D8B96F7580D67763621C9F51FAA9E2641D81565810770727EF4C25F8210CCF60B2480070556E874E59D910B9B1822B13420C2843BED4FA4F5CBD7822D651C07CB8657AD1B3629EB337CBA9F1FA50E819E9DEC1DB564FFBC1DEF0561079F96D8ABD0740BE2C997F4EEEF7E8244ECAA6E2BA85E832329220C26A7F088165F583343C190B245CEE6AE40E01D2AFAAFDD509302EBD989AE641131152538C749718FD8D1642B9802DACF3945C0A445D2ECDCF921F8E360495A564C0EE64D74224CF93119AFF5BEA0B61ABBF1DB67A6820A4BF9AD622207ECE7DB9ECE03B4FB6D69D06BBCBEACFCF62D85763DAA5B8C22385D5F4E22352C6EF6495485D00FD019FDF6D62B4F3596B
+20220714131529 2 6 100 4095 5 ED38FC9DDCD01CDF39C887875AA0A7EFF8682144089FC338C06E2C138653B5E7A082B537BA5C80A93B7192D153313DE56606C8E2A0CAE8370284BE3ADD97F04BD4EBDFD21A999E13461B544C49742DE120C46D046F6E9C55922E68FF3C8A115E51E70071377B60F8127EB9228A332BD38AF8EF1DA8EFA7012496070426203F3BEECBB286E33C053DC070CD919074DBA97E19C081C6CD8B74DBDF6674F64CD7A7B5F0B7E40B0FD607AF531D55FACAB38C9F550C1D60D89601E6BA1D6BA66F5E18D4C8D4D634C464EC748A260C285D84158CC3DFA9BC03973F32077F7D92C104314173584B96C43F22AFEFA135F3A4C5A0D959B963C8227A337DAC30D8B96F7580D67763621C9F51FAA9E2641D81565810770727EF4C25F8210CCF60B2480070556E874E59D910B9B1822B13420C2843BED4FA4F5CBD7822D651C07CB8657AD1B3629EB337CBA9F1FA50E819E9DEC1DB564FFBC1DEF0561079F96D8ABD0740BE2C997F4EEEF7E8244ECAA6E2BA85E832329220C26A7F088165F583343C190B245CEE6AE40E01D2AFAAFDD509302EBD989AE641131152538C749718FD8D1642B9802DACF3945C0A445D2ECDCF921F8E360495A564C0EE64D74224CF93119AFF5BEA0B61ABBF1DB67A6820A4BF9AD622207ECE7DB9ECE03B4FB6D69D06BBCBEACFCF62D85763DAA5B8C22385D5F4E22352C6EF6495485D00FD019FDF6D62B560201F
+20220714131556 2 6 100 4095 2 ED38FC9DDCD01CDF39C887875AA0A7EFF8682144089FC338C06E2C138653B5E7A082B537BA5C80A93B7192D153313DE56606C8E2A0CAE8370284BE3ADD97F04BD4EBDFD21A999E13461B544C49742DE120C46D046F6E9C55922E68FF3C8A115E51E70071377B60F8127EB9228A332BD38AF8EF1DA8EFA7012496070426203F3BEECBB286E33C053DC070CD919074DBA97E19C081C6CD8B74DBDF6674F64CD7A7B5F0B7E40B0FD607AF531D55FACAB38C9F550C1D60D89601E6BA1D6BA66F5E18D4C8D4D634C464EC748A260C285D84158CC3DFA9BC03973F32077F7D92C104314173584B96C43F22AFEFA135F3A4C5A0D959B963C8227A337DAC30D8B96F7580D67763621C9F51FAA9E2641D81565810770727EF4C25F8210CCF60B2480070556E874E59D910B9B1822B13420C2843BED4FA4F5CBD7822D651C07CB8657AD1B3629EB337CBA9F1FA50E819E9DEC1DB564FFBC1DEF0561079F96D8ABD0740BE2C997F4EEEF7E8244ECAA6E2BA85E832329220C26A7F088165F583343C190B245CEE6AE40E01D2AFAAFDD509302EBD989AE641131152538C749718FD8D1642B9802DACF3945C0A445D2ECDCF921F8E360495A564C0EE64D74224CF93119AFF5BEA0B61ABBF1DB67A6820A4BF9AD622207ECE7DB9ECE03B4FB6D69D06BBCBEACFCF62D85763DAA5B8C22385D5F4E22352C6EF6495485D00FD019FDF6D62B58D1C3B
+20220714131810 2 6 100 4095 5 ED38FC9DDCD01CDF39C887875AA0A7EFF8682144089FC338C06E2C138653B5E7A082B537BA5C80A93B7192D153313DE56606C8E2A0CAE8370284BE3ADD97F04BD4EBDFD21A999E13461B544C49742DE120C46D046F6E9C55922E68FF3C8A115E51E70071377B60F8127EB9228A332BD38AF8EF1DA8EFA7012496070426203F3BEECBB286E33C053DC070CD919074DBA97E19C081C6CD8B74DBDF6674F64CD7A7B5F0B7E40B0FD607AF531D55FACAB38C9F550C1D60D89601E6BA1D6BA66F5E18D4C8D4D634C464EC748A260C285D84158CC3DFA9BC03973F32077F7D92C104314173584B96C43F22AFEFA135F3A4C5A0D959B963C8227A337DAC30D8B96F7580D67763621C9F51FAA9E2641D81565810770727EF4C25F8210CCF60B2480070556E874E59D910B9B1822B13420C2843BED4FA4F5CBD7822D651C07CB8657AD1B3629EB337CBA9F1FA50E819E9DEC1DB564FFBC1DEF0561079F96D8ABD0740BE2C997F4EEEF7E8244ECAA6E2BA85E832329220C26A7F088165F583343C190B245CEE6AE40E01D2AFAAFDD509302EBD989AE641131152538C749718FD8D1642B9802DACF3945C0A445D2ECDCF921F8E360495A564C0EE64D74224CF93119AFF5BEA0B61ABBF1DB67A6820A4BF9AD622207ECE7DB9ECE03B4FB6D69D06BBCBEACFCF62D85763DAA5B8C22385D5F4E22352C6EF6495485D00FD019FDF6D62B673859F
+20220714131928 2 6 100 4095 2 ED38FC9DDCD01CDF39C887875AA0A7EFF8682144089FC338C06E2C138653B5E7A082B537BA5C80A93B7192D153313DE56606C8E2A0CAE8370284BE3ADD97F04BD4EBDFD21A999E13461B544C49742DE120C46D046F6E9C55922E68FF3C8A115E51E70071377B60F8127EB9228A332BD38AF8EF1DA8EFA7012496070426203F3BEECBB286E33C053DC070CD919074DBA97E19C081C6CD8B74DBDF6674F64CD7A7B5F0B7E40B0FD607AF531D55FACAB38C9F550C1D60D89601E6BA1D6BA66F5E18D4C8D4D634C464EC748A260C285D84158CC3DFA9BC03973F32077F7D92C104314173584B96C43F22AFEFA135F3A4C5A0D959B963C8227A337DAC30D8B96F7580D67763621C9F51FAA9E2641D81565810770727EF4C25F8210CCF60B2480070556E874E59D910B9B1822B13420C2843BED4FA4F5CBD7822D651C07CB8657AD1B3629EB337CBA9F1FA50E819E9DEC1DB564FFBC1DEF0561079F96D8ABD0740BE2C997F4EEEF7E8244ECAA6E2BA85E832329220C26A7F088165F583343C190B245CEE6AE40E01D2AFAAFDD509302EBD989AE641131152538C749718FD8D1642B9802DACF3945C0A445D2ECDCF921F8E360495A564C0EE64D74224CF93119AFF5BEA0B61ABBF1DB67A6820A4BF9AD622207ECE7DB9ECE03B4FB6D69D06BBCBEACFCF62D85763DAA5B8C22385D5F4E22352C6EF6495485D00FD019FDF6D62B6F7B87B
+20220714132227 2 6 100 4095 5 ED38FC9DDCD01CDF39C887875AA0A7EFF8682144089FC338C06E2C138653B5E7A082B537BA5C80A93B7192D153313DE56606C8E2A0CAE8370284BE3ADD97F04BD4EBDFD21A999E13461B544C49742DE120C46D046F6E9C55922E68FF3C8A115E51E70071377B60F8127EB9228A332BD38AF8EF1DA8EFA7012496070426203F3BEECBB286E33C053DC070CD919074DBA97E19C081C6CD8B74DBDF6674F64CD7A7B5F0B7E40B0FD607AF531D55FACAB38C9F550C1D60D89601E6BA1D6BA66F5E18D4C8D4D634C464EC748A260C285D84158CC3DFA9BC03973F32077F7D92C104314173584B96C43F22AFEFA135F3A4C5A0D959B963C8227A337DAC30D8B96F7580D67763621C9F51FAA9E2641D81565810770727EF4C25F8210CCF60B2480070556E874E59D910B9B1822B13420C2843BED4FA4F5CBD7822D651C07CB8657AD1B3629EB337CBA9F1FA50E819E9DEC1DB564FFBC1DEF0561079F96D8ABD0740BE2C997F4EEEF7E8244ECAA6E2BA85E832329220C26A7F088165F583343C190B245CEE6AE40E01D2AFAAFDD509302EBD989AE641131152538C749718FD8D1642B9802DACF3945C0A445D2ECDCF921F8E360495A564C0EE64D74224CF93119AFF5BEA0B61ABBF1DB67A6820A4BF9AD622207ECE7DB9ECE03B4FB6D69D06BBCBEACFCF62D85763DAA5B8C22385D5F4E22352C6EF6495485D00FD019FDF6D62B83525E7
+20220714132255 2 6 100 4095 2 ED38FC9DDCD01CDF39C887875AA0A7EFF8682144089FC338C06E2C138653B5E7A082B537BA5C80A93B7192D153313DE56606C8E2A0CAE8370284BE3ADD97F04BD4EBDFD21A999E13461B544C49742DE120C46D046F6E9C55922E68FF3C8A115E51E70071377B60F8127EB9228A332BD38AF8EF1DA8EFA7012496070426203F3BEECBB286E33C053DC070CD919074DBA97E19C081C6CD8B74DBDF6674F64CD7A7B5F0B7E40B0FD607AF531D55FACAB38C9F550C1D60D89601E6BA1D6BA66F5E18D4C8D4D634C464EC748A260C285D84158CC3DFA9BC03973F32077F7D92C104314173584B96C43F22AFEFA135F3A4C5A0D959B963C8227A337DAC30D8B96F7580D67763621C9F51FAA9E2641D81565810770727EF4C25F8210CCF60B2480070556E874E59D910B9B1822B13420C2843BED4FA4F5CBD7822D651C07CB8657AD1B3629EB337CBA9F1FA50E819E9DEC1DB564FFBC1DEF0561079F96D8ABD0740BE2C997F4EEEF7E8244ECAA6E2BA85E832329220C26A7F088165F583343C190B245CEE6AE40E01D2AFAAFDD509302EBD989AE641131152538C749718FD8D1642B9802DACF3945C0A445D2ECDCF921F8E360495A564C0EE64D74224CF93119AFF5BEA0B61ABBF1DB67A6820A4BF9AD622207ECE7DB9ECE03B4FB6D69D06BBCBEACFCF62D85763DAA5B8C22385D5F4E22352C6EF6495485D00FD019FDF6D62B863A7EB
+20220714132258 2 6 100 4095 2 ED38FC9DDCD01CDF39C887875AA0A7EFF8682144089FC338C06E2C138653B5E7A082B537BA5C80A93B7192D153313DE56606C8E2A0CAE8370284BE3ADD97F04BD4EBDFD21A999E13461B544C49742DE120C46D046F6E9C55922E68FF3C8A115E51E70071377B60F8127EB9228A332BD38AF8EF1DA8EFA7012496070426203F3BEECBB286E33C053DC070CD919074DBA97E19C081C6CD8B74DBDF6674F64CD7A7B5F0B7E40B0FD607AF531D55FACAB38C9F550C1D60D89601E6BA1D6BA66F5E18D4C8D4D634C464EC748A260C285D84158CC3DFA9BC03973F32077F7D92C104314173584B96C43F22AFEFA135F3A4C5A0D959B963C8227A337DAC30D8B96F7580D67763621C9F51FAA9E2641D81565810770727EF4C25F8210CCF60B2480070556E874E59D910B9B1822B13420C2843BED4FA4F5CBD7822D651C07CB8657AD1B3629EB337CBA9F1FA50E819E9DEC1DB564FFBC1DEF0561079F96D8ABD0740BE2C997F4EEEF7E8244ECAA6E2BA85E832329220C26A7F088165F583343C190B245CEE6AE40E01D2AFAAFDD509302EBD989AE641131152538C749718FD8D1642B9802DACF3945C0A445D2ECDCF921F8E360495A564C0EE64D74224CF93119AFF5BEA0B61ABBF1DB67A6820A4BF9AD622207ECE7DB9ECE03B4FB6D69D06BBCBEACFCF62D85763DAA5B8C22385D5F4E22352C6EF6495485D00FD019FDF6D62B869E2B3
+20220714132926 2 6 100 4095 2 ED38FC9DDCD01CDF39C887875AA0A7EFF8682144089FC338C06E2C138653B5E7A082B537BA5C80A93B7192D153313DE56606C8E2A0CAE8370284BE3ADD97F04BD4EBDFD21A999E13461B544C49742DE120C46D046F6E9C55922E68FF3C8A115E51E70071377B60F8127EB9228A332BD38AF8EF1DA8EFA7012496070426203F3BEECBB286E33C053DC070CD919074DBA97E19C081C6CD8B74DBDF6674F64CD7A7B5F0B7E40B0FD607AF531D55FACAB38C9F550C1D60D89601E6BA1D6BA66F5E18D4C8D4D634C464EC748A260C285D84158CC3DFA9BC03973F32077F7D92C104314173584B96C43F22AFEFA135F3A4C5A0D959B963C8227A337DAC30D8B96F7580D67763621C9F51FAA9E2641D81565810770727EF4C25F8210CCF60B2480070556E874E59D910B9B1822B13420C2843BED4FA4F5CBD7822D651C07CB8657AD1B3629EB337CBA9F1FA50E819E9DEC1DB564FFBC1DEF0561079F96D8ABD0740BE2C997F4EEEF7E8244ECAA6E2BA85E832329220C26A7F088165F583343C190B245CEE6AE40E01D2AFAAFDD509302EBD989AE641131152538C749718FD8D1642B9802DACF3945C0A445D2ECDCF921F8E360495A564C0EE64D74224CF93119AFF5BEA0B61ABBF1DB67A6820A4BF9AD622207ECE7DB9ECE03B4FB6D69D06BBCBEACFCF62D85763DAA5B8C22385D5F4E22352C6EF6495485D00FD019FDF6D62BB0FCCF3
+20220714133046 2 6 100 4095 2 ED38FC9DDCD01CDF39C887875AA0A7EFF8682144089FC338C06E2C138653B5E7A082B537BA5C80A93B7192D153313DE56606C8E2A0CAE8370284BE3ADD97F04BD4EBDFD21A999E13461B544C49742DE120C46D046F6E9C55922E68FF3C8A115E51E70071377B60F8127EB9228A332BD38AF8EF1DA8EFA7012496070426203F3BEECBB286E33C053DC070CD919074DBA97E19C081C6CD8B74DBDF6674F64CD7A7B5F0B7E40B0FD607AF531D55FACAB38C9F550C1D60D89601E6BA1D6BA66F5E18D4C8D4D634C464EC748A260C285D84158CC3DFA9BC03973F32077F7D92C104314173584B96C43F22AFEFA135F3A4C5A0D959B963C8227A337DAC30D8B96F7580D67763621C9F51FAA9E2641D81565810770727EF4C25F8210CCF60B2480070556E874E59D910B9B1822B13420C2843BED4FA4F5CBD7822D651C07CB8657AD1B3629EB337CBA9F1FA50E819E9DEC1DB564FFBC1DEF0561079F96D8ABD0740BE2C997F4EEEF7E8244ECAA6E2BA85E832329220C26A7F088165F583343C190B245CEE6AE40E01D2AFAAFDD509302EBD989AE641131152538C749718FD8D1642B9802DACF3945C0A445D2ECDCF921F8E360495A564C0EE64D74224CF93119AFF5BEA0B61ABBF1DB67A6820A4BF9AD622207ECE7DB9ECE03B4FB6D69D06BBCBEACFCF62D85763DAA5B8C22385D5F4E22352C6EF6495485D00FD019FDF6D62BB96BAAB
+20220714133233 2 6 100 4095 5 C26EA920269D893CF64405388D11C71D52FBD982A1A9308A076F5B755328380B3D920C48C770CFBD278FCEAC8F9425A0A90DF855870D484BAD937C546B0A77676A0C55A150CE32CD4F6EB2F42A1A176199B683E383035F00F93D13B136E94EF38000FA07B393E7FCF3D3780FE4D8B222C94C389ACBBCFDDA3B5EBA8ABA2E8864E9A5A82097DACE58E7B051CAFFE23DB7F1B5A1AC27E5245A40CCE4F85C9F5FF162A994F68E4D6287CA45160ED1FD545ACC957893BC1D39C6FFD755CD8995EEA46A70E462391D5C23D346074415499E835F3F4EFF95A76CB60F1A7B447799105A542C0870A74BEF1C575A112A1CBE2383C32D44CE8D813EE45511ECF7FE252E0882C81300BA1055E44EE6E0EF5A8FBAFF5DB2A3E62EC9BCA93DAB6134D2F3B2EE20C979D17D5272E6BD1F47B4997C02B2A0766B79B1710DE7F5933C4DCBE6C35A376D914B04E07809B94ECD8CE029A54F1AFCBA92EBF0C19AB692F5CD0DE32F78EAB4AD53DBA881F7D737A6899345A8CE7C20E697B6D8E1E3A9886A9EFBCD95FE408E340D298EDD0276AF776FBB4EBD9FDA18322E09BF101506AA8C471EE71CBCF1DCD969524C052B6066D7AE54614DD4AFFAC6EAB393D0CA1CB22FE487DAB99BBA1835490AC275AD9C2C7A7138AC9DF236AD48951C13C0DE1EC58A2120DD24144DCA31564C74A5CEEF143D9BA7F2F6D01670FC6F6DBC07A08D25EE7C71821637
+20220714133651 2 6 100 4095 2 C26EA920269D893CF64405388D11C71D52FBD982A1A9308A076F5B755328380B3D920C48C770CFBD278FCEAC8F9425A0A90DF855870D484BAD937C546B0A77676A0C55A150CE32CD4F6EB2F42A1A176199B683E383035F00F93D13B136E94EF38000FA07B393E7FCF3D3780FE4D8B222C94C389ACBBCFDDA3B5EBA8ABA2E8864E9A5A82097DACE58E7B051CAFFE23DB7F1B5A1AC27E5245A40CCE4F85C9F5FF162A994F68E4D6287CA45160ED1FD545ACC957893BC1D39C6FFD755CD8995EEA46A70E462391D5C23D346074415499E835F3F4EFF95A76CB60F1A7B447799105A542C0870A74BEF1C575A112A1CBE2383C32D44CE8D813EE45511ECF7FE252E0882C81300BA1055E44EE6E0EF5A8FBAFF5DB2A3E62EC9BCA93DAB6134D2F3B2EE20C979D17D5272E6BD1F47B4997C02B2A0766B79B1710DE7F5933C4DCBE6C35A376D914B04E07809B94ECD8CE029A54F1AFCBA92EBF0C19AB692F5CD0DE32F78EAB4AD53DBA881F7D737A6899345A8CE7C20E697B6D8E1E3A9886A9EFBCD95FE408E340D298EDD0276AF776FBB4EBD9FDA18322E09BF101506AA8C471EE71CBCF1DCD969524C052B6066D7AE54614DD4AFFAC6EAB393D0CA1CB22FE487DAB99BBA1835490AC275AD9C2C7A7138AC9DF236AD48951C13C0DE1EC58A2120DD24144DCA31564C74A5CEEF143D9BA7F2F6D01670FC6F6DBC07A08D25EE7C733193F3
+20220714133712 2 6 100 4095 2 C26EA920269D893CF64405388D11C71D52FBD982A1A9308A076F5B755328380B3D920C48C770CFBD278FCEAC8F9425A0A90DF855870D484BAD937C546B0A77676A0C55A150CE32CD4F6EB2F42A1A176199B683E383035F00F93D13B136E94EF38000FA07B393E7FCF3D3780FE4D8B222C94C389ACBBCFDDA3B5EBA8ABA2E8864E9A5A82097DACE58E7B051CAFFE23DB7F1B5A1AC27E5245A40CCE4F85C9F5FF162A994F68E4D6287CA45160ED1FD545ACC957893BC1D39C6FFD755CD8995EEA46A70E462391D5C23D346074415499E835F3F4EFF95A76CB60F1A7B447799105A542C0870A74BEF1C575A112A1CBE2383C32D44CE8D813EE45511ECF7FE252E0882C81300BA1055E44EE6E0EF5A8FBAFF5DB2A3E62EC9BCA93DAB6134D2F3B2EE20C979D17D5272E6BD1F47B4997C02B2A0766B79B1710DE7F5933C4DCBE6C35A376D914B04E07809B94ECD8CE029A54F1AFCBA92EBF0C19AB692F5CD0DE32F78EAB4AD53DBA881F7D737A6899345A8CE7C20E697B6D8E1E3A9886A9EFBCD95FE408E340D298EDD0276AF776FBB4EBD9FDA18322E09BF101506AA8C471EE71CBCF1DCD969524C052B6066D7AE54614DD4AFFAC6EAB393D0CA1CB22FE487DAB99BBA1835490AC275AD9C2C7A7138AC9DF236AD48951C13C0DE1EC58A2120DD24144DCA31564C74A5CEEF143D9BA7F2F6D01670FC6F6DBC07A08D25EE7C73526D3B
+20220714134252 2 6 100 4095 2 C26EA920269D893CF64405388D11C71D52FBD982A1A9308A076F5B755328380B3D920C48C770CFBD278FCEAC8F9425A0A90DF855870D484BAD937C546B0A77676A0C55A150CE32CD4F6EB2F42A1A176199B683E383035F00F93D13B136E94EF38000FA07B393E7FCF3D3780FE4D8B222C94C389ACBBCFDDA3B5EBA8ABA2E8864E9A5A82097DACE58E7B051CAFFE23DB7F1B5A1AC27E5245A40CCE4F85C9F5FF162A994F68E4D6287CA45160ED1FD545ACC957893BC1D39C6FFD755CD8995EEA46A70E462391D5C23D346074415499E835F3F4EFF95A76CB60F1A7B447799105A542C0870A74BEF1C575A112A1CBE2383C32D44CE8D813EE45511ECF7FE252E0882C81300BA1055E44EE6E0EF5A8FBAFF5DB2A3E62EC9BCA93DAB6134D2F3B2EE20C979D17D5272E6BD1F47B4997C02B2A0766B79B1710DE7F5933C4DCBE6C35A376D914B04E07809B94ECD8CE029A54F1AFCBA92EBF0C19AB692F5CD0DE32F78EAB4AD53DBA881F7D737A6899345A8CE7C20E697B6D8E1E3A9886A9EFBCD95FE408E340D298EDD0276AF776FBB4EBD9FDA18322E09BF101506AA8C471EE71CBCF1DCD969524C052B6066D7AE54614DD4AFFAC6EAB393D0CA1CB22FE487DAB99BBA1835490AC275AD9C2C7A7138AC9DF236AD48951C13C0DE1EC58A2120DD24144DCA31564C74A5CEEF143D9BA7F2F6D01670FC6F6DBC07A08D25EE7C75A257CB
+20220714134434 2 6 100 4095 5 C26EA920269D893CF64405388D11C71D52FBD982A1A9308A076F5B755328380B3D920C48C770CFBD278FCEAC8F9425A0A90DF855870D484BAD937C546B0A77676A0C55A150CE32CD4F6EB2F42A1A176199B683E383035F00F93D13B136E94EF38000FA07B393E7FCF3D3780FE4D8B222C94C389ACBBCFDDA3B5EBA8ABA2E8864E9A5A82097DACE58E7B051CAFFE23DB7F1B5A1AC27E5245A40CCE4F85C9F5FF162A994F68E4D6287CA45160ED1FD545ACC957893BC1D39C6FFD755CD8995EEA46A70E462391D5C23D346074415499E835F3F4EFF95A76CB60F1A7B447799105A542C0870A74BEF1C575A112A1CBE2383C32D44CE8D813EE45511ECF7FE252E0882C81300BA1055E44EE6E0EF5A8FBAFF5DB2A3E62EC9BCA93DAB6134D2F3B2EE20C979D17D5272E6BD1F47B4997C02B2A0766B79B1710DE7F5933C4DCBE6C35A376D914B04E07809B94ECD8CE029A54F1AFCBA92EBF0C19AB692F5CD0DE32F78EAB4AD53DBA881F7D737A6899345A8CE7C20E697B6D8E1E3A9886A9EFBCD95FE408E340D298EDD0276AF776FBB4EBD9FDA18322E09BF101506AA8C471EE71CBCF1DCD969524C052B6066D7AE54614DD4AFFAC6EAB393D0CA1CB22FE487DAB99BBA1835490AC275AD9C2C7A7138AC9DF236AD48951C13C0DE1EC58A2120DD24144DCA31564C74A5CEEF143D9BA7F2F6D01670FC6F6DBC07A08D25EE7C764BC487
+20220714134946 2 6 100 4095 2 C26EA920269D893CF64405388D11C71D52FBD982A1A9308A076F5B755328380B3D920C48C770CFBD278FCEAC8F9425A0A90DF855870D484BAD937C546B0A77676A0C55A150CE32CD4F6EB2F42A1A176199B683E383035F00F93D13B136E94EF38000FA07B393E7FCF3D3780FE4D8B222C94C389ACBBCFDDA3B5EBA8ABA2E8864E9A5A82097DACE58E7B051CAFFE23DB7F1B5A1AC27E5245A40CCE4F85C9F5FF162A994F68E4D6287CA45160ED1FD545ACC957893BC1D39C6FFD755CD8995EEA46A70E462391D5C23D346074415499E835F3F4EFF95A76CB60F1A7B447799105A542C0870A74BEF1C575A112A1CBE2383C32D44CE8D813EE45511ECF7FE252E0882C81300BA1055E44EE6E0EF5A8FBAFF5DB2A3E62EC9BCA93DAB6134D2F3B2EE20C979D17D5272E6BD1F47B4997C02B2A0766B79B1710DE7F5933C4DCBE6C35A376D914B04E07809B94ECD8CE029A54F1AFCBA92EBF0C19AB692F5CD0DE32F78EAB4AD53DBA881F7D737A6899345A8CE7C20E697B6D8E1E3A9886A9EFBCD95FE408E340D298EDD0276AF776FBB4EBD9FDA18322E09BF101506AA8C471EE71CBCF1DCD969524C052B6066D7AE54614DD4AFFAC6EAB393D0CA1CB22FE487DAB99BBA1835490AC275AD9C2C7A7138AC9DF236AD48951C13C0DE1EC58A2120DD24144DCA31564C74A5CEEF143D9BA7F2F6D01670FC6F6DBC07A08D25EE7C785EAE2B
+20220714135018 2 6 100 4095 5 C26EA920269D893CF64405388D11C71D52FBD982A1A9308A076F5B755328380B3D920C48C770CFBD278FCEAC8F9425A0A90DF855870D484BAD937C546B0A77676A0C55A150CE32CD4F6EB2F42A1A176199B683E383035F00F93D13B136E94EF38000FA07B393E7FCF3D3780FE4D8B222C94C389ACBBCFDDA3B5EBA8ABA2E8864E9A5A82097DACE58E7B051CAFFE23DB7F1B5A1AC27E5245A40CCE4F85C9F5FF162A994F68E4D6287CA45160ED1FD545ACC957893BC1D39C6FFD755CD8995EEA46A70E462391D5C23D346074415499E835F3F4EFF95A76CB60F1A7B447799105A542C0870A74BEF1C575A112A1CBE2383C32D44CE8D813EE45511ECF7FE252E0882C81300BA1055E44EE6E0EF5A8FBAFF5DB2A3E62EC9BCA93DAB6134D2F3B2EE20C979D17D5272E6BD1F47B4997C02B2A0766B79B1710DE7F5933C4DCBE6C35A376D914B04E07809B94ECD8CE029A54F1AFCBA92EBF0C19AB692F5CD0DE32F78EAB4AD53DBA881F7D737A6899345A8CE7C20E697B6D8E1E3A9886A9EFBCD95FE408E340D298EDD0276AF776FBB4EBD9FDA18322E09BF101506AA8C471EE71CBCF1DCD969524C052B6066D7AE54614DD4AFFAC6EAB393D0CA1CB22FE487DAB99BBA1835490AC275AD9C2C7A7138AC9DF236AD48951C13C0DE1EC58A2120DD24144DCA31564C74A5CEEF143D9BA7F2F6D01670FC6F6DBC07A08D25EE7C78963137
+20220714135147 2 6 100 4095 5 C26EA920269D893CF64405388D11C71D52FBD982A1A9308A076F5B755328380B3D920C48C770CFBD278FCEAC8F9425A0A90DF855870D484BAD937C546B0A77676A0C55A150CE32CD4F6EB2F42A1A176199B683E383035F00F93D13B136E94EF38000FA07B393E7FCF3D3780FE4D8B222C94C389ACBBCFDDA3B5EBA8ABA2E8864E9A5A82097DACE58E7B051CAFFE23DB7F1B5A1AC27E5245A40CCE4F85C9F5FF162A994F68E4D6287CA45160ED1FD545ACC957893BC1D39C6FFD755CD8995EEA46A70E462391D5C23D346074415499E835F3F4EFF95A76CB60F1A7B447799105A542C0870A74BEF1C575A112A1CBE2383C32D44CE8D813EE45511ECF7FE252E0882C81300BA1055E44EE6E0EF5A8FBAFF5DB2A3E62EC9BCA93DAB6134D2F3B2EE20C979D17D5272E6BD1F47B4997C02B2A0766B79B1710DE7F5933C4DCBE6C35A376D914B04E07809B94ECD8CE029A54F1AFCBA92EBF0C19AB692F5CD0DE32F78EAB4AD53DBA881F7D737A6899345A8CE7C20E697B6D8E1E3A9886A9EFBCD95FE408E340D298EDD0276AF776FBB4EBD9FDA18322E09BF101506AA8C471EE71CBCF1DCD969524C052B6066D7AE54614DD4AFFAC6EAB393D0CA1CB22FE487DAB99BBA1835490AC275AD9C2C7A7138AC9DF236AD48951C13C0DE1EC58A2120DD24144DCA31564C74A5CEEF143D9BA7F2F6D01670FC6F6DBC07A08D25EE7C792D0D87
+20220714135358 2 6 100 4095 2 C26EA920269D893CF64405388D11C71D52FBD982A1A9308A076F5B755328380B3D920C48C770CFBD278FCEAC8F9425A0A90DF855870D484BAD937C546B0A77676A0C55A150CE32CD4F6EB2F42A1A176199B683E383035F00F93D13B136E94EF38000FA07B393E7FCF3D3780FE4D8B222C94C389ACBBCFDDA3B5EBA8ABA2E8864E9A5A82097DACE58E7B051CAFFE23DB7F1B5A1AC27E5245A40CCE4F85C9F5FF162A994F68E4D6287CA45160ED1FD545ACC957893BC1D39C6FFD755CD8995EEA46A70E462391D5C23D346074415499E835F3F4EFF95A76CB60F1A7B447799105A542C0870A74BEF1C575A112A1CBE2383C32D44CE8D813EE45511ECF7FE252E0882C81300BA1055E44EE6E0EF5A8FBAFF5DB2A3E62EC9BCA93DAB6134D2F3B2EE20C979D17D5272E6BD1F47B4997C02B2A0766B79B1710DE7F5933C4DCBE6C35A376D914B04E07809B94ECD8CE029A54F1AFCBA92EBF0C19AB692F5CD0DE32F78EAB4AD53DBA881F7D737A6899345A8CE7C20E697B6D8E1E3A9886A9EFBCD95FE408E340D298EDD0276AF776FBB4EBD9FDA18322E09BF101506AA8C471EE71CBCF1DCD969524C052B6066D7AE54614DD4AFFAC6EAB393D0CA1CB22FE487DAB99BBA1835490AC275AD9C2C7A7138AC9DF236AD48951C13C0DE1EC58A2120DD24144DCA31564C74A5CEEF143D9BA7F2F6D01670FC6F6DBC07A08D25EE7C7A0DE73B
+20220714135921 2 6 100 4095 2 C26EA920269D893CF64405388D11C71D52FBD982A1A9308A076F5B755328380B3D920C48C770CFBD278FCEAC8F9425A0A90DF855870D484BAD937C546B0A77676A0C55A150CE32CD4F6EB2F42A1A176199B683E383035F00F93D13B136E94EF38000FA07B393E7FCF3D3780FE4D8B222C94C389ACBBCFDDA3B5EBA8ABA2E8864E9A5A82097DACE58E7B051CAFFE23DB7F1B5A1AC27E5245A40CCE4F85C9F5FF162A994F68E4D6287CA45160ED1FD545ACC957893BC1D39C6FFD755CD8995EEA46A70E462391D5C23D346074415499E835F3F4EFF95A76CB60F1A7B447799105A542C0870A74BEF1C575A112A1CBE2383C32D44CE8D813EE45511ECF7FE252E0882C81300BA1055E44EE6E0EF5A8FBAFF5DB2A3E62EC9BCA93DAB6134D2F3B2EE20C979D17D5272E6BD1F47B4997C02B2A0766B79B1710DE7F5933C4DCBE6C35A376D914B04E07809B94ECD8CE029A54F1AFCBA92EBF0C19AB692F5CD0DE32F78EAB4AD53DBA881F7D737A6899345A8CE7C20E697B6D8E1E3A9886A9EFBCD95FE408E340D298EDD0276AF776FBB4EBD9FDA18322E09BF101506AA8C471EE71CBCF1DCD969524C052B6066D7AE54614DD4AFFAC6EAB393D0CA1CB22FE487DAB99BBA1835490AC275AD9C2C7A7138AC9DF236AD48951C13C0DE1EC58A2120DD24144DCA31564C74A5CEEF143D9BA7F2F6D01670FC6F6DBC07A08D25EE7C7C4451E3
+20220714140317 2 6 100 4095 2 C26EA920269D893CF64405388D11C71D52FBD982A1A9308A076F5B755328380B3D920C48C770CFBD278FCEAC8F9425A0A90DF855870D484BAD937C546B0A77676A0C55A150CE32CD4F6EB2F42A1A176199B683E383035F00F93D13B136E94EF38000FA07B393E7FCF3D3780FE4D8B222C94C389ACBBCFDDA3B5EBA8ABA2E8864E9A5A82097DACE58E7B051CAFFE23DB7F1B5A1AC27E5245A40CCE4F85C9F5FF162A994F68E4D6287CA45160ED1FD545ACC957893BC1D39C6FFD755CD8995EEA46A70E462391D5C23D346074415499E835F3F4EFF95A76CB60F1A7B447799105A542C0870A74BEF1C575A112A1CBE2383C32D44CE8D813EE45511ECF7FE252E0882C81300BA1055E44EE6E0EF5A8FBAFF5DB2A3E62EC9BCA93DAB6134D2F3B2EE20C979D17D5272E6BD1F47B4997C02B2A0766B79B1710DE7F5933C4DCBE6C35A376D914B04E07809B94ECD8CE029A54F1AFCBA92EBF0C19AB692F5CD0DE32F78EAB4AD53DBA881F7D737A6899345A8CE7C20E697B6D8E1E3A9886A9EFBCD95FE408E340D298EDD0276AF776FBB4EBD9FDA18322E09BF101506AA8C471EE71CBCF1DCD969524C052B6066D7AE54614DD4AFFAC6EAB393D0CA1CB22FE487DAB99BBA1835490AC275AD9C2C7A7138AC9DF236AD48951C13C0DE1EC58A2120DD24144DCA31564C74A5CEEF143D9BA7F2F6D01670FC6F6DBC07A08D25EE7C7DE6BDEB
+20220714140350 2 6 100 4095 2 C26EA920269D893CF64405388D11C71D52FBD982A1A9308A076F5B755328380B3D920C48C770CFBD278FCEAC8F9425A0A90DF855870D484BAD937C546B0A77676A0C55A150CE32CD4F6EB2F42A1A176199B683E383035F00F93D13B136E94EF38000FA07B393E7FCF3D3780FE4D8B222C94C389ACBBCFDDA3B5EBA8ABA2E8864E9A5A82097DACE58E7B051CAFFE23DB7F1B5A1AC27E5245A40CCE4F85C9F5FF162A994F68E4D6287CA45160ED1FD545ACC957893BC1D39C6FFD755CD8995EEA46A70E462391D5C23D346074415499E835F3F4EFF95A76CB60F1A7B447799105A542C0870A74BEF1C575A112A1CBE2383C32D44CE8D813EE45511ECF7FE252E0882C81300BA1055E44EE6E0EF5A8FBAFF5DB2A3E62EC9BCA93DAB6134D2F3B2EE20C979D17D5272E6BD1F47B4997C02B2A0766B79B1710DE7F5933C4DCBE6C35A376D914B04E07809B94ECD8CE029A54F1AFCBA92EBF0C19AB692F5CD0DE32F78EAB4AD53DBA881F7D737A6899345A8CE7C20E697B6D8E1E3A9886A9EFBCD95FE408E340D298EDD0276AF776FBB4EBD9FDA18322E09BF101506AA8C471EE71CBCF1DCD969524C052B6066D7AE54614DD4AFFAC6EAB393D0CA1CB22FE487DAB99BBA1835490AC275AD9C2C7A7138AC9DF236AD48951C13C0DE1EC58A2120DD24144DCA31564C74A5CEEF143D9BA7F2F6D01670FC6F6DBC07A08D25EE7C7E21885B
+20220714140711 2 6 100 4095 5 C26EA920269D893CF64405388D11C71D52FBD982A1A9308A076F5B755328380B3D920C48C770CFBD278FCEAC8F9425A0A90DF855870D484BAD937C546B0A77676A0C55A150CE32CD4F6EB2F42A1A176199B683E383035F00F93D13B136E94EF38000FA07B393E7FCF3D3780FE4D8B222C94C389ACBBCFDDA3B5EBA8ABA2E8864E9A5A82097DACE58E7B051CAFFE23DB7F1B5A1AC27E5245A40CCE4F85C9F5FF162A994F68E4D6287CA45160ED1FD545ACC957893BC1D39C6FFD755CD8995EEA46A70E462391D5C23D346074415499E835F3F4EFF95A76CB60F1A7B447799105A542C0870A74BEF1C575A112A1CBE2383C32D44CE8D813EE45511ECF7FE252E0882C81300BA1055E44EE6E0EF5A8FBAFF5DB2A3E62EC9BCA93DAB6134D2F3B2EE20C979D17D5272E6BD1F47B4997C02B2A0766B79B1710DE7F5933C4DCBE6C35A376D914B04E07809B94ECD8CE029A54F1AFCBA92EBF0C19AB692F5CD0DE32F78EAB4AD53DBA881F7D737A6899345A8CE7C20E697B6D8E1E3A9886A9EFBCD95FE408E340D298EDD0276AF776FBB4EBD9FDA18322E09BF101506AA8C471EE71CBCF1DCD969524C052B6066D7AE54614DD4AFFAC6EAB393D0CA1CB22FE487DAB99BBA1835490AC275AD9C2C7A7138AC9DF236AD48951C13C0DE1EC58A2120DD24144DCA31564C74A5CEEF143D9BA7F2F6D01670FC6F6DBC07A08D25EE7C7F85C48F
+20220714140736 2 6 100 4095 2 C26EA920269D893CF64405388D11C71D52FBD982A1A9308A076F5B755328380B3D920C48C770CFBD278FCEAC8F9425A0A90DF855870D484BAD937C546B0A77676A0C55A150CE32CD4F6EB2F42A1A176199B683E383035F00F93D13B136E94EF38000FA07B393E7FCF3D3780FE4D8B222C94C389ACBBCFDDA3B5EBA8ABA2E8864E9A5A82097DACE58E7B051CAFFE23DB7F1B5A1AC27E5245A40CCE4F85C9F5FF162A994F68E4D6287CA45160ED1FD545ACC957893BC1D39C6FFD755CD8995EEA46A70E462391D5C23D346074415499E835F3F4EFF95A76CB60F1A7B447799105A542C0870A74BEF1C575A112A1CBE2383C32D44CE8D813EE45511ECF7FE252E0882C81300BA1055E44EE6E0EF5A8FBAFF5DB2A3E62EC9BCA93DAB6134D2F3B2EE20C979D17D5272E6BD1F47B4997C02B2A0766B79B1710DE7F5933C4DCBE6C35A376D914B04E07809B94ECD8CE029A54F1AFCBA92EBF0C19AB692F5CD0DE32F78EAB4AD53DBA881F7D737A6899345A8CE7C20E697B6D8E1E3A9886A9EFBCD95FE408E340D298EDD0276AF776FBB4EBD9FDA18322E09BF101506AA8C471EE71CBCF1DCD969524C052B6066D7AE54614DD4AFFAC6EAB393D0CA1CB22FE487DAB99BBA1835490AC275AD9C2C7A7138AC9DF236AD48951C13C0DE1EC58A2120DD24144DCA31564C74A5CEEF143D9BA7F2F6D01670FC6F6DBC07A08D25EE7C7FAFD0B3
+20220714140813 2 6 100 4095 5 C26EA920269D893CF64405388D11C71D52FBD982A1A9308A076F5B755328380B3D920C48C770CFBD278FCEAC8F9425A0A90DF855870D484BAD937C546B0A77676A0C55A150CE32CD4F6EB2F42A1A176199B683E383035F00F93D13B136E94EF38000FA07B393E7FCF3D3780FE4D8B222C94C389ACBBCFDDA3B5EBA8ABA2E8864E9A5A82097DACE58E7B051CAFFE23DB7F1B5A1AC27E5245A40CCE4F85C9F5FF162A994F68E4D6287CA45160ED1FD545ACC957893BC1D39C6FFD755CD8995EEA46A70E462391D5C23D346074415499E835F3F4EFF95A76CB60F1A7B447799105A542C0870A74BEF1C575A112A1CBE2383C32D44CE8D813EE45511ECF7FE252E0882C81300BA1055E44EE6E0EF5A8FBAFF5DB2A3E62EC9BCA93DAB6134D2F3B2EE20C979D17D5272E6BD1F47B4997C02B2A0766B79B1710DE7F5933C4DCBE6C35A376D914B04E07809B94ECD8CE029A54F1AFCBA92EBF0C19AB692F5CD0DE32F78EAB4AD53DBA881F7D737A6899345A8CE7C20E697B6D8E1E3A9886A9EFBCD95FE408E340D298EDD0276AF776FBB4EBD9FDA18322E09BF101506AA8C471EE71CBCF1DCD969524C052B6066D7AE54614DD4AFFAC6EAB393D0CA1CB22FE487DAB99BBA1835490AC275AD9C2C7A7138AC9DF236AD48951C13C0DE1EC58A2120DD24144DCA31564C74A5CEEF143D9BA7F2F6D01670FC6F6DBC07A08D25EE7C7FEDFEA7
+20220714141031 2 6 100 4095 5 C26EA920269D893CF64405388D11C71D52FBD982A1A9308A076F5B755328380B3D920C48C770CFBD278FCEAC8F9425A0A90DF855870D484BAD937C546B0A77676A0C55A150CE32CD4F6EB2F42A1A176199B683E383035F00F93D13B136E94EF38000FA07B393E7FCF3D3780FE4D8B222C94C389ACBBCFDDA3B5EBA8ABA2E8864E9A5A82097DACE58E7B051CAFFE23DB7F1B5A1AC27E5245A40CCE4F85C9F5FF162A994F68E4D6287CA45160ED1FD545ACC957893BC1D39C6FFD755CD8995EEA46A70E462391D5C23D346074415499E835F3F4EFF95A76CB60F1A7B447799105A542C0870A74BEF1C575A112A1CBE2383C32D44CE8D813EE45511ECF7FE252E0882C81300BA1055E44EE6E0EF5A8FBAFF5DB2A3E62EC9BCA93DAB6134D2F3B2EE20C979D17D5272E6BD1F47B4997C02B2A0766B79B1710DE7F5933C4DCBE6C35A376D914B04E07809B94ECD8CE029A54F1AFCBA92EBF0C19AB692F5CD0DE32F78EAB4AD53DBA881F7D737A6899345A8CE7C20E697B6D8E1E3A9886A9EFBCD95FE408E340D298EDD0276AF776FBB4EBD9FDA18322E09BF101506AA8C471EE71CBCF1DCD969524C052B6066D7AE54614DD4AFFAC6EAB393D0CA1CB22FE487DAB99BBA1835490AC275AD9C2C7A7138AC9DF236AD48951C13C0DE1EC58A2120DD24144DCA31564C74A5CEEF143D9BA7F2F6D01670FC6F6DBC07A08D25EE7C80E164A7
+20220714141111 2 6 100 4095 5 C26EA920269D893CF64405388D11C71D52FBD982A1A9308A076F5B755328380B3D920C48C770CFBD278FCEAC8F9425A0A90DF855870D484BAD937C546B0A77676A0C55A150CE32CD4F6EB2F42A1A176199B683E383035F00F93D13B136E94EF38000FA07B393E7FCF3D3780FE4D8B222C94C389ACBBCFDDA3B5EBA8ABA2E8864E9A5A82097DACE58E7B051CAFFE23DB7F1B5A1AC27E5245A40CCE4F85C9F5FF162A994F68E4D6287CA45160ED1FD545ACC957893BC1D39C6FFD755CD8995EEA46A70E462391D5C23D346074415499E835F3F4EFF95A76CB60F1A7B447799105A542C0870A74BEF1C575A112A1CBE2383C32D44CE8D813EE45511ECF7FE252E0882C81300BA1055E44EE6E0EF5A8FBAFF5DB2A3E62EC9BCA93DAB6134D2F3B2EE20C979D17D5272E6BD1F47B4997C02B2A0766B79B1710DE7F5933C4DCBE6C35A376D914B04E07809B94ECD8CE029A54F1AFCBA92EBF0C19AB692F5CD0DE32F78EAB4AD53DBA881F7D737A6899345A8CE7C20E697B6D8E1E3A9886A9EFBCD95FE408E340D298EDD0276AF776FBB4EBD9FDA18322E09BF101506AA8C471EE71CBCF1DCD969524C052B6066D7AE54614DD4AFFAC6EAB393D0CA1CB22FE487DAB99BBA1835490AC275AD9C2C7A7138AC9DF236AD48951C13C0DE1EC58A2120DD24144DCA31564C74A5CEEF143D9BA7F2F6D01670FC6F6DBC07A08D25EE7C812A1B2F
+20220714141544 2 6 100 4095 2 C26EA920269D893CF64405388D11C71D52FBD982A1A9308A076F5B755328380B3D920C48C770CFBD278FCEAC8F9425A0A90DF855870D484BAD937C546B0A77676A0C55A150CE32CD4F6EB2F42A1A176199B683E383035F00F93D13B136E94EF38000FA07B393E7FCF3D3780FE4D8B222C94C389ACBBCFDDA3B5EBA8ABA2E8864E9A5A82097DACE58E7B051CAFFE23DB7F1B5A1AC27E5245A40CCE4F85C9F5FF162A994F68E4D6287CA45160ED1FD545ACC957893BC1D39C6FFD755CD8995EEA46A70E462391D5C23D346074415499E835F3F4EFF95A76CB60F1A7B447799105A542C0870A74BEF1C575A112A1CBE2383C32D44CE8D813EE45511ECF7FE252E0882C81300BA1055E44EE6E0EF5A8FBAFF5DB2A3E62EC9BCA93DAB6134D2F3B2EE20C979D17D5272E6BD1F47B4997C02B2A0766B79B1710DE7F5933C4DCBE6C35A376D914B04E07809B94ECD8CE029A54F1AFCBA92EBF0C19AB692F5CD0DE32F78EAB4AD53DBA881F7D737A6899345A8CE7C20E697B6D8E1E3A9886A9EFBCD95FE408E340D298EDD0276AF776FBB4EBD9FDA18322E09BF101506AA8C471EE71CBCF1DCD969524C052B6066D7AE54614DD4AFFAC6EAB393D0CA1CB22FE487DAB99BBA1835490AC275AD9C2C7A7138AC9DF236AD48951C13C0DE1EC58A2120DD24144DCA31564C74A5CEEF143D9BA7F2F6D01670FC6F6DBC07A08D25EE7C8303F01B
+20220714141716 2 6 100 4095 2 C26EA920269D893CF64405388D11C71D52FBD982A1A9308A076F5B755328380B3D920C48C770CFBD278FCEAC8F9425A0A90DF855870D484BAD937C546B0A77676A0C55A150CE32CD4F6EB2F42A1A176199B683E383035F00F93D13B136E94EF38000FA07B393E7FCF3D3780FE4D8B222C94C389ACBBCFDDA3B5EBA8ABA2E8864E9A5A82097DACE58E7B051CAFFE23DB7F1B5A1AC27E5245A40CCE4F85C9F5FF162A994F68E4D6287CA45160ED1FD545ACC957893BC1D39C6FFD755CD8995EEA46A70E462391D5C23D346074415499E835F3F4EFF95A76CB60F1A7B447799105A542C0870A74BEF1C575A112A1CBE2383C32D44CE8D813EE45511ECF7FE252E0882C81300BA1055E44EE6E0EF5A8FBAFF5DB2A3E62EC9BCA93DAB6134D2F3B2EE20C979D17D5272E6BD1F47B4997C02B2A0766B79B1710DE7F5933C4DCBE6C35A376D914B04E07809B94ECD8CE029A54F1AFCBA92EBF0C19AB692F5CD0DE32F78EAB4AD53DBA881F7D737A6899345A8CE7C20E697B6D8E1E3A9886A9EFBCD95FE408E340D298EDD0276AF776FBB4EBD9FDA18322E09BF101506AA8C471EE71CBCF1DCD969524C052B6066D7AE54614DD4AFFAC6EAB393D0CA1CB22FE487DAB99BBA1835490AC275AD9C2C7A7138AC9DF236AD48951C13C0DE1EC58A2120DD24144DCA31564C74A5CEEF143D9BA7F2F6D01670FC6F6DBC07A08D25EE7C839F487B
+20220714141912 2 6 100 4095 5 C26EA920269D893CF64405388D11C71D52FBD982A1A9308A076F5B755328380B3D920C48C770CFBD278FCEAC8F9425A0A90DF855870D484BAD937C546B0A77676A0C55A150CE32CD4F6EB2F42A1A176199B683E383035F00F93D13B136E94EF38000FA07B393E7FCF3D3780FE4D8B222C94C389ACBBCFDDA3B5EBA8ABA2E8864E9A5A82097DACE58E7B051CAFFE23DB7F1B5A1AC27E5245A40CCE4F85C9F5FF162A994F68E4D6287CA45160ED1FD545ACC957893BC1D39C6FFD755CD8995EEA46A70E462391D5C23D346074415499E835F3F4EFF95A76CB60F1A7B447799105A542C0870A74BEF1C575A112A1CBE2383C32D44CE8D813EE45511ECF7FE252E0882C81300BA1055E44EE6E0EF5A8FBAFF5DB2A3E62EC9BCA93DAB6134D2F3B2EE20C979D17D5272E6BD1F47B4997C02B2A0766B79B1710DE7F5933C4DCBE6C35A376D914B04E07809B94ECD8CE029A54F1AFCBA92EBF0C19AB692F5CD0DE32F78EAB4AD53DBA881F7D737A6899345A8CE7C20E697B6D8E1E3A9886A9EFBCD95FE408E340D298EDD0276AF776FBB4EBD9FDA18322E09BF101506AA8C471EE71CBCF1DCD969524C052B6066D7AE54614DD4AFFAC6EAB393D0CA1CB22FE487DAB99BBA1835490AC275AD9C2C7A7138AC9DF236AD48951C13C0DE1EC58A2120DD24144DCA31564C74A5CEEF143D9BA7F2F6D01670FC6F6DBC07A08D25EE7C846C71CF
+20220714142105 2 6 100 4095 5 C26EA920269D893CF64405388D11C71D52FBD982A1A9308A076F5B755328380B3D920C48C770CFBD278FCEAC8F9425A0A90DF855870D484BAD937C546B0A77676A0C55A150CE32CD4F6EB2F42A1A176199B683E383035F00F93D13B136E94EF38000FA07B393E7FCF3D3780FE4D8B222C94C389ACBBCFDDA3B5EBA8ABA2E8864E9A5A82097DACE58E7B051CAFFE23DB7F1B5A1AC27E5245A40CCE4F85C9F5FF162A994F68E4D6287CA45160ED1FD545ACC957893BC1D39C6FFD755CD8995EEA46A70E462391D5C23D346074415499E835F3F4EFF95A76CB60F1A7B447799105A542C0870A74BEF1C575A112A1CBE2383C32D44CE8D813EE45511ECF7FE252E0882C81300BA1055E44EE6E0EF5A8FBAFF5DB2A3E62EC9BCA93DAB6134D2F3B2EE20C979D17D5272E6BD1F47B4997C02B2A0766B79B1710DE7F5933C4DCBE6C35A376D914B04E07809B94ECD8CE029A54F1AFCBA92EBF0C19AB692F5CD0DE32F78EAB4AD53DBA881F7D737A6899345A8CE7C20E697B6D8E1E3A9886A9EFBCD95FE408E340D298EDD0276AF776FBB4EBD9FDA18322E09BF101506AA8C471EE71CBCF1DCD969524C052B6066D7AE54614DD4AFFAC6EAB393D0CA1CB22FE487DAB99BBA1835490AC275AD9C2C7A7138AC9DF236AD48951C13C0DE1EC58A2120DD24144DCA31564C74A5CEEF143D9BA7F2F6D01670FC6F6DBC07A08D25EE7C853302EF
+20220714142236 2 6 100 4095 2 C26EA920269D893CF64405388D11C71D52FBD982A1A9308A076F5B755328380B3D920C48C770CFBD278FCEAC8F9425A0A90DF855870D484BAD937C546B0A77676A0C55A150CE32CD4F6EB2F42A1A176199B683E383035F00F93D13B136E94EF38000FA07B393E7FCF3D3780FE4D8B222C94C389ACBBCFDDA3B5EBA8ABA2E8864E9A5A82097DACE58E7B051CAFFE23DB7F1B5A1AC27E5245A40CCE4F85C9F5FF162A994F68E4D6287CA45160ED1FD545ACC957893BC1D39C6FFD755CD8995EEA46A70E462391D5C23D346074415499E835F3F4EFF95A76CB60F1A7B447799105A542C0870A74BEF1C575A112A1CBE2383C32D44CE8D813EE45511ECF7FE252E0882C81300BA1055E44EE6E0EF5A8FBAFF5DB2A3E62EC9BCA93DAB6134D2F3B2EE20C979D17D5272E6BD1F47B4997C02B2A0766B79B1710DE7F5933C4DCBE6C35A376D914B04E07809B94ECD8CE029A54F1AFCBA92EBF0C19AB692F5CD0DE32F78EAB4AD53DBA881F7D737A6899345A8CE7C20E697B6D8E1E3A9886A9EFBCD95FE408E340D298EDD0276AF776FBB4EBD9FDA18322E09BF101506AA8C471EE71CBCF1DCD969524C052B6066D7AE54614DD4AFFAC6EAB393D0CA1CB22FE487DAB99BBA1835490AC275AD9C2C7A7138AC9DF236AD48951C13C0DE1EC58A2120DD24144DCA31564C74A5CEEF143D9BA7F2F6D01670FC6F6DBC07A08D25EE7C85CD2F13
+20220714142326 2 6 100 4095 2 C26EA920269D893CF64405388D11C71D52FBD982A1A9308A076F5B755328380B3D920C48C770CFBD278FCEAC8F9425A0A90DF855870D484BAD937C546B0A77676A0C55A150CE32CD4F6EB2F42A1A176199B683E383035F00F93D13B136E94EF38000FA07B393E7FCF3D3780FE4D8B222C94C389ACBBCFDDA3B5EBA8ABA2E8864E9A5A82097DACE58E7B051CAFFE23DB7F1B5A1AC27E5245A40CCE4F85C9F5FF162A994F68E4D6287CA45160ED1FD545ACC957893BC1D39C6FFD755CD8995EEA46A70E462391D5C23D346074415499E835F3F4EFF95A76CB60F1A7B447799105A542C0870A74BEF1C575A112A1CBE2383C32D44CE8D813EE45511ECF7FE252E0882C81300BA1055E44EE6E0EF5A8FBAFF5DB2A3E62EC9BCA93DAB6134D2F3B2EE20C979D17D5272E6BD1F47B4997C02B2A0766B79B1710DE7F5933C4DCBE6C35A376D914B04E07809B94ECD8CE029A54F1AFCBA92EBF0C19AB692F5CD0DE32F78EAB4AD53DBA881F7D737A6899345A8CE7C20E697B6D8E1E3A9886A9EFBCD95FE408E340D298EDD0276AF776FBB4EBD9FDA18322E09BF101506AA8C471EE71CBCF1DCD969524C052B6066D7AE54614DD4AFFAC6EAB393D0CA1CB22FE487DAB99BBA1835490AC275AD9C2C7A7138AC9DF236AD48951C13C0DE1EC58A2120DD24144DCA31564C74A5CEEF143D9BA7F2F6D01670FC6F6DBC07A08D25EE7C8625DC73
+20220714142751 2 6 100 4095 2 C26EA920269D893CF64405388D11C71D52FBD982A1A9308A076F5B755328380B3D920C48C770CFBD278FCEAC8F9425A0A90DF855870D484BAD937C546B0A77676A0C55A150CE32CD4F6EB2F42A1A176199B683E383035F00F93D13B136E94EF38000FA07B393E7FCF3D3780FE4D8B222C94C389ACBBCFDDA3B5EBA8ABA2E8864E9A5A82097DACE58E7B051CAFFE23DB7F1B5A1AC27E5245A40CCE4F85C9F5FF162A994F68E4D6287CA45160ED1FD545ACC957893BC1D39C6FFD755CD8995EEA46A70E462391D5C23D346074415499E835F3F4EFF95A76CB60F1A7B447799105A542C0870A74BEF1C575A112A1CBE2383C32D44CE8D813EE45511ECF7FE252E0882C81300BA1055E44EE6E0EF5A8FBAFF5DB2A3E62EC9BCA93DAB6134D2F3B2EE20C979D17D5272E6BD1F47B4997C02B2A0766B79B1710DE7F5933C4DCBE6C35A376D914B04E07809B94ECD8CE029A54F1AFCBA92EBF0C19AB692F5CD0DE32F78EAB4AD53DBA881F7D737A6899345A8CE7C20E697B6D8E1E3A9886A9EFBCD95FE408E340D298EDD0276AF776FBB4EBD9FDA18322E09BF101506AA8C471EE71CBCF1DCD969524C052B6066D7AE54614DD4AFFAC6EAB393D0CA1CB22FE487DAB99BBA1835490AC275AD9C2C7A7138AC9DF236AD48951C13C0DE1EC58A2120DD24144DCA31564C74A5CEEF143D9BA7F2F6D01670FC6F6DBC07A08D25EE7C87E4924B
+20220714142911 2 6 100 4095 2 C26EA920269D893CF64405388D11C71D52FBD982A1A9308A076F5B755328380B3D920C48C770CFBD278FCEAC8F9425A0A90DF855870D484BAD937C546B0A77676A0C55A150CE32CD4F6EB2F42A1A176199B683E383035F00F93D13B136E94EF38000FA07B393E7FCF3D3780FE4D8B222C94C389ACBBCFDDA3B5EBA8ABA2E8864E9A5A82097DACE58E7B051CAFFE23DB7F1B5A1AC27E5245A40CCE4F85C9F5FF162A994F68E4D6287CA45160ED1FD545ACC957893BC1D39C6FFD755CD8995EEA46A70E462391D5C23D346074415499E835F3F4EFF95A76CB60F1A7B447799105A542C0870A74BEF1C575A112A1CBE2383C32D44CE8D813EE45511ECF7FE252E0882C81300BA1055E44EE6E0EF5A8FBAFF5DB2A3E62EC9BCA93DAB6134D2F3B2EE20C979D17D5272E6BD1F47B4997C02B2A0766B79B1710DE7F5933C4DCBE6C35A376D914B04E07809B94ECD8CE029A54F1AFCBA92EBF0C19AB692F5CD0DE32F78EAB4AD53DBA881F7D737A6899345A8CE7C20E697B6D8E1E3A9886A9EFBCD95FE408E340D298EDD0276AF776FBB4EBD9FDA18322E09BF101506AA8C471EE71CBCF1DCD969524C052B6066D7AE54614DD4AFFAC6EAB393D0CA1CB22FE487DAB99BBA1835490AC275AD9C2C7A7138AC9DF236AD48951C13C0DE1EC58A2120DD24144DCA31564C74A5CEEF143D9BA7F2F6D01670FC6F6DBC07A08D25EE7C88684F73
+20220714143324 2 6 100 4095 2 C26EA920269D893CF64405388D11C71D52FBD982A1A9308A076F5B755328380B3D920C48C770CFBD278FCEAC8F9425A0A90DF855870D484BAD937C546B0A77676A0C55A150CE32CD4F6EB2F42A1A176199B683E383035F00F93D13B136E94EF38000FA07B393E7FCF3D3780FE4D8B222C94C389ACBBCFDDA3B5EBA8ABA2E8864E9A5A82097DACE58E7B051CAFFE23DB7F1B5A1AC27E5245A40CCE4F85C9F5FF162A994F68E4D6287CA45160ED1FD545ACC957893BC1D39C6FFD755CD8995EEA46A70E462391D5C23D346074415499E835F3F4EFF95A76CB60F1A7B447799105A542C0870A74BEF1C575A112A1CBE2383C32D44CE8D813EE45511ECF7FE252E0882C81300BA1055E44EE6E0EF5A8FBAFF5DB2A3E62EC9BCA93DAB6134D2F3B2EE20C979D17D5272E6BD1F47B4997C02B2A0766B79B1710DE7F5933C4DCBE6C35A376D914B04E07809B94ECD8CE029A54F1AFCBA92EBF0C19AB692F5CD0DE32F78EAB4AD53DBA881F7D737A6899345A8CE7C20E697B6D8E1E3A9886A9EFBCD95FE408E340D298EDD0276AF776FBB4EBD9FDA18322E09BF101506AA8C471EE71CBCF1DCD969524C052B6066D7AE54614DD4AFFAC6EAB393D0CA1CB22FE487DAB99BBA1835490AC275AD9C2C7A7138AC9DF236AD48951C13C0DE1EC58A2120DD24144DCA31564C74A5CEEF143D9BA7F2F6D01670FC6F6DBC07A08D25EE7C8A2318DB
+20220714143325 2 6 100 4095 5 C26EA920269D893CF64405388D11C71D52FBD982A1A9308A076F5B755328380B3D920C48C770CFBD278FCEAC8F9425A0A90DF855870D484BAD937C546B0A77676A0C55A150CE32CD4F6EB2F42A1A176199B683E383035F00F93D13B136E94EF38000FA07B393E7FCF3D3780FE4D8B222C94C389ACBBCFDDA3B5EBA8ABA2E8864E9A5A82097DACE58E7B051CAFFE23DB7F1B5A1AC27E5245A40CCE4F85C9F5FF162A994F68E4D6287CA45160ED1FD545ACC957893BC1D39C6FFD755CD8995EEA46A70E462391D5C23D346074415499E835F3F4EFF95A76CB60F1A7B447799105A542C0870A74BEF1C575A112A1CBE2383C32D44CE8D813EE45511ECF7FE252E0882C81300BA1055E44EE6E0EF5A8FBAFF5DB2A3E62EC9BCA93DAB6134D2F3B2EE20C979D17D5272E6BD1F47B4997C02B2A0766B79B1710DE7F5933C4DCBE6C35A376D914B04E07809B94ECD8CE029A54F1AFCBA92EBF0C19AB692F5CD0DE32F78EAB4AD53DBA881F7D737A6899345A8CE7C20E697B6D8E1E3A9886A9EFBCD95FE408E340D298EDD0276AF776FBB4EBD9FDA18322E09BF101506AA8C471EE71CBCF1DCD969524C052B6066D7AE54614DD4AFFAC6EAB393D0CA1CB22FE487DAB99BBA1835490AC275AD9C2C7A7138AC9DF236AD48951C13C0DE1EC58A2120DD24144DCA31564C74A5CEEF143D9BA7F2F6D01670FC6F6DBC07A08D25EE7C8A23F507
+20220714143405 2 6 100 4095 2 C26EA920269D893CF64405388D11C71D52FBD982A1A9308A076F5B755328380B3D920C48C770CFBD278FCEAC8F9425A0A90DF855870D484BAD937C546B0A77676A0C55A150CE32CD4F6EB2F42A1A176199B683E383035F00F93D13B136E94EF38000FA07B393E7FCF3D3780FE4D8B222C94C389ACBBCFDDA3B5EBA8ABA2E8864E9A5A82097DACE58E7B051CAFFE23DB7F1B5A1AC27E5245A40CCE4F85C9F5FF162A994F68E4D6287CA45160ED1FD545ACC957893BC1D39C6FFD755CD8995EEA46A70E462391D5C23D346074415499E835F3F4EFF95A76CB60F1A7B447799105A542C0870A74BEF1C575A112A1CBE2383C32D44CE8D813EE45511ECF7FE252E0882C81300BA1055E44EE6E0EF5A8FBAFF5DB2A3E62EC9BCA93DAB6134D2F3B2EE20C979D17D5272E6BD1F47B4997C02B2A0766B79B1710DE7F5933C4DCBE6C35A376D914B04E07809B94ECD8CE029A54F1AFCBA92EBF0C19AB692F5CD0DE32F78EAB4AD53DBA881F7D737A6899345A8CE7C20E697B6D8E1E3A9886A9EFBCD95FE408E340D298EDD0276AF776FBB4EBD9FDA18322E09BF101506AA8C471EE71CBCF1DCD969524C052B6066D7AE54614DD4AFFAC6EAB393D0CA1CB22FE487DAB99BBA1835490AC275AD9C2C7A7138AC9DF236AD48951C13C0DE1EC58A2120DD24144DCA31564C74A5CEEF143D9BA7F2F6D01670FC6F6DBC07A08D25EE7C8A690A43
+20220714144651 2 6 100 4095 2 C26EA920269D893CF64405388D11C71D52FBD982A1A9308A076F5B755328380B3D920C48C770CFBD278FCEAC8F9425A0A90DF855870D484BAD937C546B0A77676A0C55A150CE32CD4F6EB2F42A1A176199B683E383035F00F93D13B136E94EF38000FA07B393E7FCF3D3780FE4D8B222C94C389ACBBCFDDA3B5EBA8ABA2E8864E9A5A82097DACE58E7B051CAFFE23DB7F1B5A1AC27E5245A40CCE4F85C9F5FF162A994F68E4D6287CA45160ED1FD545ACC957893BC1D39C6FFD755CD8995EEA46A70E462391D5C23D346074415499E835F3F4EFF95A76CB60F1A7B447799105A542C0870A74BEF1C575A112A1CBE2383C32D44CE8D813EE45511ECF7FE252E0882C81300BA1055E44EE6E0EF5A8FBAFF5DB2A3E62EC9BCA93DAB6134D2F3B2EE20C979D17D5272E6BD1F47B4997C02B2A0766B79B1710DE7F5933C4DCBE6C35A376D914B04E07809B94ECD8CE029A54F1AFCBA92EBF0C19AB692F5CD0DE32F78EAB4AD53DBA881F7D737A6899345A8CE7C20E697B6D8E1E3A9886A9EFBCD95FE408E340D298EDD0276AF776FBB4EBD9FDA18322E09BF101506AA8C471EE71CBCF1DCD969524C052B6066D7AE54614DD4AFFAC6EAB393D0CA1CB22FE487DAB99BBA1835490AC275AD9C2C7A7138AC9DF236AD48951C13C0DE1EC58A2120DD24144DCA31564C74A5CEEF143D9BA7F2F6D01670FC6F6DBC07A08D25EE7C8F8FC3A3
+20220714144923 2 6 100 4095 2 C26EA920269D893CF64405388D11C71D52FBD982A1A9308A076F5B755328380B3D920C48C770CFBD278FCEAC8F9425A0A90DF855870D484BAD937C546B0A77676A0C55A150CE32CD4F6EB2F42A1A176199B683E383035F00F93D13B136E94EF38000FA07B393E7FCF3D3780FE4D8B222C94C389ACBBCFDDA3B5EBA8ABA2E8864E9A5A82097DACE58E7B051CAFFE23DB7F1B5A1AC27E5245A40CCE4F85C9F5FF162A994F68E4D6287CA45160ED1FD545ACC957893BC1D39C6FFD755CD8995EEA46A70E462391D5C23D346074415499E835F3F4EFF95A76CB60F1A7B447799105A542C0870A74BEF1C575A112A1CBE2383C32D44CE8D813EE45511ECF7FE252E0882C81300BA1055E44EE6E0EF5A8FBAFF5DB2A3E62EC9BCA93DAB6134D2F3B2EE20C979D17D5272E6BD1F47B4997C02B2A0766B79B1710DE7F5933C4DCBE6C35A376D914B04E07809B94ECD8CE029A54F1AFCBA92EBF0C19AB692F5CD0DE32F78EAB4AD53DBA881F7D737A6899345A8CE7C20E697B6D8E1E3A9886A9EFBCD95FE408E340D298EDD0276AF776FBB4EBD9FDA18322E09BF101506AA8C471EE71CBCF1DCD969524C052B6066D7AE54614DD4AFFAC6EAB393D0CA1CB22FE487DAB99BBA1835490AC275AD9C2C7A7138AC9DF236AD48951C13C0DE1EC58A2120DD24144DCA31564C74A5CEEF143D9BA7F2F6D01670FC6F6DBC07A08D25EE7C90A21B53
+20220714144936 2 6 100 4095 2 C26EA920269D893CF64405388D11C71D52FBD982A1A9308A076F5B755328380B3D920C48C770CFBD278FCEAC8F9425A0A90DF855870D484BAD937C546B0A77676A0C55A150CE32CD4F6EB2F42A1A176199B683E383035F00F93D13B136E94EF38000FA07B393E7FCF3D3780FE4D8B222C94C389ACBBCFDDA3B5EBA8ABA2E8864E9A5A82097DACE58E7B051CAFFE23DB7F1B5A1AC27E5245A40CCE4F85C9F5FF162A994F68E4D6287CA45160ED1FD545ACC957893BC1D39C6FFD755CD8995EEA46A70E462391D5C23D346074415499E835F3F4EFF95A76CB60F1A7B447799105A542C0870A74BEF1C575A112A1CBE2383C32D44CE8D813EE45511ECF7FE252E0882C81300BA1055E44EE6E0EF5A8FBAFF5DB2A3E62EC9BCA93DAB6134D2F3B2EE20C979D17D5272E6BD1F47B4997C02B2A0766B79B1710DE7F5933C4DCBE6C35A376D914B04E07809B94ECD8CE029A54F1AFCBA92EBF0C19AB692F5CD0DE32F78EAB4AD53DBA881F7D737A6899345A8CE7C20E697B6D8E1E3A9886A9EFBCD95FE408E340D298EDD0276AF776FBB4EBD9FDA18322E09BF101506AA8C471EE71CBCF1DCD969524C052B6066D7AE54614DD4AFFAC6EAB393D0CA1CB22FE487DAB99BBA1835490AC275AD9C2C7A7138AC9DF236AD48951C13C0DE1EC58A2120DD24144DCA31564C74A5CEEF143D9BA7F2F6D01670FC6F6DBC07A08D25EE7C90B7330B
+20220714150424 2 6 100 6143 2 FFB27E2CC8B774D736BFE9ECC0EB33B1BC6D4DEA1E8B360AD96E83A7213A91CCC112624B99480D8B7E7C3B6A70A96B7F267C4FE080158429ECB77525C930D5C61BFC7858FF4D571FE7C533CC24A8B1188EF52DD31B0910207C6B5166A9A097F1D12932EBE47B9B876F2FE0F9344AD4B4BA45B0BBB58908E9D6F8DA689D318AA7C1E198CA2AD22722C00C03A393C8BFC2C037C33429CEDF0660F5716CBC1A15530ED5A3C368B96973A43F1AB70E8BA75ABBB35C85B15E58B56E5C8196B6E9D3C65A236786B55733B64FD6D4F46672EFB796962A3E07AB74C597961E99B573BD8F6046F89C317CA6D9F4922A222CC0EA11E9823F742937FB0EC1A8B7FC8A588193B2AF4C2DECA3EE9724FD8818A0792445FF5E0B7ADDD3EF2282BF471F5322FE0950D91B9B7688B7D134741B60BA427DAF6F09A57C027BE9D5FF6AF15A6DBB183E86E4C682FCD711472039537425BBC2C07D91503187E5F7B9CE7C576AC0CC799791971C23F82C2519635F9B4E1BEE7941DD602EE778E5A99EF77FF9FCFEDC0CC6F90E1F8E2C09D596237C37EC368A78BE8CA54A7406A5BF0708885967909CE810651BC792BD84B1805E3964F31002B647A88FAFF57E94F56E75E5C866E43E7360928B8E7D8E89CE43F5D84E21A3075E9974ED065C825268994DA5E0ABBAFDC1A6636AEB8856C6703CA917C7DF7B607F7DEECD894E6DC133E1904C73499706EC71D2780726A3019F3975835EB22CD82451522CD11A38B28BD742B2A278B886BFFBAF1354D248DE81CE41E8DC7CDD31264D5374CD6D1E53FB07798A5122E18710B2648ABF174A3C8F31222BEFCA76C3F6D7240483119BE84BDB5B72D6CC812A21E2C3A3AF1C263DD5794A716028943E3491EDD9976C4AD900BA4E5BBE2A531BA3B8AF6BF5B952876DB85A70B5C6EBBDDF82E4FD4E518277CDAA86824F82DADE5F73FC60E81C3035A92CC374274DDD8400C144AD28B2B410E186D2A799A1BBAD5B88B1117BE0721D8FD55BF0235620209AACE1B8B2992DBE94F8238AC7E31C758202C548152AF1E4FF39B070B650A52E25793E6E344E027A94CC0CB98269CB3AC32B
+20220714150807 2 6 100 6143 2 FFB27E2CC8B774D736BFE9ECC0EB33B1BC6D4DEA1E8B360AD96E83A7213A91CCC112624B99480D8B7E7C3B6A70A96B7F267C4FE080158429ECB77525C930D5C61BFC7858FF4D571FE7C533CC24A8B1188EF52DD31B0910207C6B5166A9A097F1D12932EBE47B9B876F2FE0F9344AD4B4BA45B0BBB58908E9D6F8DA689D318AA7C1E198CA2AD22722C00C03A393C8BFC2C037C33429CEDF0660F5716CBC1A15530ED5A3C368B96973A43F1AB70E8BA75ABBB35C85B15E58B56E5C8196B6E9D3C65A236786B55733B64FD6D4F46672EFB796962A3E07AB74C597961E99B573BD8F6046F89C317CA6D9F4922A222CC0EA11E9823F742937FB0EC1A8B7FC8A588193B2AF4C2DECA3EE9724FD8818A0792445FF5E0B7ADDD3EF2282BF471F5322FE0950D91B9B7688B7D134741B60BA427DAF6F09A57C027BE9D5FF6AF15A6DBB183E86E4C682FCD711472039537425BBC2C07D91503187E5F7B9CE7C576AC0CC799791971C23F82C2519635F9B4E1BEE7941DD602EE778E5A99EF77FF9FCFEDC0CC6F90E1F8E2C09D596237C37EC368A78BE8CA54A7406A5BF0708885967909CE810651BC792BD84B1805E3964F31002B647A88FAFF57E94F56E75E5C866E43E7360928B8E7D8E89CE43F5D84E21A3075E9974ED065C825268994DA5E0ABBAFDC1A6636AEB8856C6703CA917C7DF7B607F7DEECD894E6DC133E1904C73499706EC71D2780726A3019F3975835EB22CD82451522CD11A38B28BD742B2A278B886BFFBAF1354D248DE81CE41E8DC7CDD31264D5374CD6D1E53FB07798A5122E18710B2648ABF174A3C8F31222BEFCA76C3F6D7240483119BE84BDB5B72D6CC812A21E2C3A3AF1C263DD5794A716028943E3491EDD9976C4AD900BA4E5BBE2A531BA3B8AF6BF5B952876DB85A70B5C6EBBDDF82E4FD4E518277CDAA86824F82DADE5F73FC60E81C3035A92CC374274DDD8400C144AD28B2B410E186D2A799A1BBAD5B88B1117BE0721D8FD55BF0235620209AACE1B8B2992DBE94F8238AC7E31C758202C548152AF1E4FF39B070B650A52E25793E6E344E027A94CC0CB98269CBBB9D93
+20220714153843 2 6 100 6143 5 FFB27E2CC8B774D736BFE9ECC0EB33B1BC6D4DEA1E8B360AD96E83A7213A91CCC112624B99480D8B7E7C3B6A70A96B7F267C4FE080158429ECB77525C930D5C61BFC7858FF4D571FE7C533CC24A8B1188EF52DD31B0910207C6B5166A9A097F1D12932EBE47B9B876F2FE0F9344AD4B4BA45B0BBB58908E9D6F8DA689D318AA7C1E198CA2AD22722C00C03A393C8BFC2C037C33429CEDF0660F5716CBC1A15530ED5A3C368B96973A43F1AB70E8BA75ABBB35C85B15E58B56E5C8196B6E9D3C65A236786B55733B64FD6D4F46672EFB796962A3E07AB74C597961E99B573BD8F6046F89C317CA6D9F4922A222CC0EA11E9823F742937FB0EC1A8B7FC8A588193B2AF4C2DECA3EE9724FD8818A0792445FF5E0B7ADDD3EF2282BF471F5322FE0950D91B9B7688B7D134741B60BA427DAF6F09A57C027BE9D5FF6AF15A6DBB183E86E4C682FCD711472039537425BBC2C07D91503187E5F7B9CE7C576AC0CC799791971C23F82C2519635F9B4E1BEE7941DD602EE778E5A99EF77FF9FCFEDC0CC6F90E1F8E2C09D596237C37EC368A78BE8CA54A7406A5BF0708885967909CE810651BC792BD84B1805E3964F31002B647A88FAFF57E94F56E75E5C866E43E7360928B8E7D8E89CE43F5D84E21A3075E9974ED065C825268994DA5E0ABBAFDC1A6636AEB8856C6703CA917C7DF7B607F7DEECD894E6DC133E1904C73499706EC71D2780726A3019F3975835EB22CD82451522CD11A38B28BD742B2A278B886BFFBAF1354D248DE81CE41E8DC7CDD31264D5374CD6D1E53FB07798A5122E18710B2648ABF174A3C8F31222BEFCA76C3F6D7240483119BE84BDB5B72D6CC812A21E2C3A3AF1C263DD5794A716028943E3491EDD9976C4AD900BA4E5BBE2A531BA3B8AF6BF5B952876DB85A70B5C6EBBDDF82E4FD4E518277CDAA86824F82DADE5F73FC60E81C3035A92CC374274DDD8400C144AD28B2B410E186D2A799A1BBAD5B88B1117BE0721D8FD55BF0235620209AACE1B8B2992DBE94F8238AC7E31C758202C548152AF1E4FF39B070B650A52E25793E6E344E027A94CC0CB98269CFDFF54F
+20220714155314 2 6 100 6143 2 FFB27E2CC8B774D736BFE9ECC0EB33B1BC6D4DEA1E8B360AD96E83A7213A91CCC112624B99480D8B7E7C3B6A70A96B7F267C4FE080158429ECB77525C930D5C61BFC7858FF4D571FE7C533CC24A8B1188EF52DD31B0910207C6B5166A9A097F1D12932EBE47B9B876F2FE0F9344AD4B4BA45B0BBB58908E9D6F8DA689D318AA7C1E198CA2AD22722C00C03A393C8BFC2C037C33429CEDF0660F5716CBC1A15530ED5A3C368B96973A43F1AB70E8BA75ABBB35C85B15E58B56E5C8196B6E9D3C65A236786B55733B64FD6D4F46672EFB796962A3E07AB74C597961E99B573BD8F6046F89C317CA6D9F4922A222CC0EA11E9823F742937FB0EC1A8B7FC8A588193B2AF4C2DECA3EE9724FD8818A0792445FF5E0B7ADDD3EF2282BF471F5322FE0950D91B9B7688B7D134741B60BA427DAF6F09A57C027BE9D5FF6AF15A6DBB183E86E4C682FCD711472039537425BBC2C07D91503187E5F7B9CE7C576AC0CC799791971C23F82C2519635F9B4E1BEE7941DD602EE778E5A99EF77FF9FCFEDC0CC6F90E1F8E2C09D596237C37EC368A78BE8CA54A7406A5BF0708885967909CE810651BC792BD84B1805E3964F31002B647A88FAFF57E94F56E75E5C866E43E7360928B8E7D8E89CE43F5D84E21A3075E9974ED065C825268994DA5E0ABBAFDC1A6636AEB8856C6703CA917C7DF7B607F7DEECD894E6DC133E1904C73499706EC71D2780726A3019F3975835EB22CD82451522CD11A38B28BD742B2A278B886BFFBAF1354D248DE81CE41E8DC7CDD31264D5374CD6D1E53FB07798A5122E18710B2648ABF174A3C8F31222BEFCA76C3F6D7240483119BE84BDB5B72D6CC812A21E2C3A3AF1C263DD5794A716028943E3491EDD9976C4AD900BA4E5BBE2A531BA3B8AF6BF5B952876DB85A70B5C6EBBDDF82E4FD4E518277CDAA86824F82DADE5F73FC60E81C3035A92CC374274DDD8400C144AD28B2B410E186D2A799A1BBAD5B88B1117BE0721D8FD55BF0235620209AACE1B8B2992DBE94F8238AC7E31C758202C548152AF1E4FF39B070B650A52E25793E6E344E027A94CC0CB98269D1D2942B
+20220714160052 2 6 100 6143 2 FFB27E2CC8B774D736BFE9ECC0EB33B1BC6D4DEA1E8B360AD96E83A7213A91CCC112624B99480D8B7E7C3B6A70A96B7F267C4FE080158429ECB77525C930D5C61BFC7858FF4D571FE7C533CC24A8B1188EF52DD31B0910207C6B5166A9A097F1D12932EBE47B9B876F2FE0F9344AD4B4BA45B0BBB58908E9D6F8DA689D318AA7C1E198CA2AD22722C00C03A393C8BFC2C037C33429CEDF0660F5716CBC1A15530ED5A3C368B96973A43F1AB70E8BA75ABBB35C85B15E58B56E5C8196B6E9D3C65A236786B55733B64FD6D4F46672EFB796962A3E07AB74C597961E99B573BD8F6046F89C317CA6D9F4922A222CC0EA11E9823F742937FB0EC1A8B7FC8A588193B2AF4C2DECA3EE9724FD8818A0792445FF5E0B7ADDD3EF2282BF471F5322FE0950D91B9B7688B7D134741B60BA427DAF6F09A57C027BE9D5FF6AF15A6DBB183E86E4C682FCD711472039537425BBC2C07D91503187E5F7B9CE7C576AC0CC799791971C23F82C2519635F9B4E1BEE7941DD602EE778E5A99EF77FF9FCFEDC0CC6F90E1F8E2C09D596237C37EC368A78BE8CA54A7406A5BF0708885967909CE810651BC792BD84B1805E3964F31002B647A88FAFF57E94F56E75E5C866E43E7360928B8E7D8E89CE43F5D84E21A3075E9974ED065C825268994DA5E0ABBAFDC1A6636AEB8856C6703CA917C7DF7B607F7DEECD894E6DC133E1904C73499706EC71D2780726A3019F3975835EB22CD82451522CD11A38B28BD742B2A278B886BFFBAF1354D248DE81CE41E8DC7CDD31264D5374CD6D1E53FB07798A5122E18710B2648ABF174A3C8F31222BEFCA76C3F6D7240483119BE84BDB5B72D6CC812A21E2C3A3AF1C263DD5794A716028943E3491EDD9976C4AD900BA4E5BBE2A531BA3B8AF6BF5B952876DB85A70B5C6EBBDDF82E4FD4E518277CDAA86824F82DADE5F73FC60E81C3035A92CC374274DDD8400C144AD28B2B410E186D2A799A1BBAD5B88B1117BE0721D8FD55BF0235620209AACE1B8B2992DBE94F8238AC7E31C758202C548152AF1E4FF39B070B650A52E25793E6E344E027A94CC0CB98269D2DACC3B
+20220714163103 2 6 100 6143 2 FFB27E2CC8B774D736BFE9ECC0EB33B1BC6D4DEA1E8B360AD96E83A7213A91CCC112624B99480D8B7E7C3B6A70A96B7F267C4FE080158429ECB77525C930D5C61BFC7858FF4D571FE7C533CC24A8B1188EF52DD31B0910207C6B5166A9A097F1D12932EBE47B9B876F2FE0F9344AD4B4BA45B0BBB58908E9D6F8DA689D318AA7C1E198CA2AD22722C00C03A393C8BFC2C037C33429CEDF0660F5716CBC1A15530ED5A3C368B96973A43F1AB70E8BA75ABBB35C85B15E58B56E5C8196B6E9D3C65A236786B55733B64FD6D4F46672EFB796962A3E07AB74C597961E99B573BD8F6046F89C317CA6D9F4922A222CC0EA11E9823F742937FB0EC1A8B7FC8A588193B2AF4C2DECA3EE9724FD8818A0792445FF5E0B7ADDD3EF2282BF471F5322FE0950D91B9B7688B7D134741B60BA427DAF6F09A57C027BE9D5FF6AF15A6DBB183E86E4C682FCD711472039537425BBC2C07D91503187E5F7B9CE7C576AC0CC799791971C23F82C2519635F9B4E1BEE7941DD602EE778E5A99EF77FF9FCFEDC0CC6F90E1F8E2C09D596237C37EC368A78BE8CA54A7406A5BF0708885967909CE810651BC792BD84B1805E3964F31002B647A88FAFF57E94F56E75E5C866E43E7360928B8E7D8E89CE43F5D84E21A3075E9974ED065C825268994DA5E0ABBAFDC1A6636AEB8856C6703CA917C7DF7B607F7DEECD894E6DC133E1904C73499706EC71D2780726A3019F3975835EB22CD82451522CD11A38B28BD742B2A278B886BFFBAF1354D248DE81CE41E8DC7CDD31264D5374CD6D1E53FB07798A5122E18710B2648ABF174A3C8F31222BEFCA76C3F6D7240483119BE84BDB5B72D6CC812A21E2C3A3AF1C263DD5794A716028943E3491EDD9976C4AD900BA4E5BBE2A531BA3B8AF6BF5B952876DB85A70B5C6EBBDDF82E4FD4E518277CDAA86824F82DADE5F73FC60E81C3035A92CC374274DDD8400C144AD28B2B410E186D2A799A1BBAD5B88B1117BE0721D8FD55BF0235620209AACE1B8B2992DBE94F8238AC7E31C758202C548152AF1E4FF39B070B650A52E25793E6E344E027A94CC0CB98269D6EA99C3
+20220714171421 2 6 100 6143 5 FFB27E2CC8B774D736BFE9ECC0EB33B1BC6D4DEA1E8B360AD96E83A7213A91CCC112624B99480D8B7E7C3B6A70A96B7F267C4FE080158429ECB77525C930D5C61BFC7858FF4D571FE7C533CC24A8B1188EF52DD31B0910207C6B5166A9A097F1D12932EBE47B9B876F2FE0F9344AD4B4BA45B0BBB58908E9D6F8DA689D318AA7C1E198CA2AD22722C00C03A393C8BFC2C037C33429CEDF0660F5716CBC1A15530ED5A3C368B96973A43F1AB70E8BA75ABBB35C85B15E58B56E5C8196B6E9D3C65A236786B55733B64FD6D4F46672EFB796962A3E07AB74C597961E99B573BD8F6046F89C317CA6D9F4922A222CC0EA11E9823F742937FB0EC1A8B7FC8A588193B2AF4C2DECA3EE9724FD8818A0792445FF5E0B7ADDD3EF2282BF471F5322FE0950D91B9B7688B7D134741B60BA427DAF6F09A57C027BE9D5FF6AF15A6DBB183E86E4C682FCD711472039537425BBC2C07D91503187E5F7B9CE7C576AC0CC799791971C23F82C2519635F9B4E1BEE7941DD602EE778E5A99EF77FF9FCFEDC0CC6F90E1F8E2C09D596237C37EC368A78BE8CA54A7406A5BF0708885967909CE810651BC792BD84B1805E3964F31002B647A88FAFF57E94F56E75E5C866E43E7360928B8E7D8E89CE43F5D84E21A3075E9974ED065C825268994DA5E0ABBAFDC1A6636AEB8856C6703CA917C7DF7B607F7DEECD894E6DC133E1904C73499706EC71D2780726A3019F3975835EB22CD82451522CD11A38B28BD742B2A278B886BFFBAF1354D248DE81CE41E8DC7CDD31264D5374CD6D1E53FB07798A5122E18710B2648ABF174A3C8F31222BEFCA76C3F6D7240483119BE84BDB5B72D6CC812A21E2C3A3AF1C263DD5794A716028943E3491EDD9976C4AD900BA4E5BBE2A531BA3B8AF6BF5B952876DB85A70B5C6EBBDDF82E4FD4E518277CDAA86824F82DADE5F73FC60E81C3035A92CC374274DDD8400C144AD28B2B410E186D2A799A1BBAD5B88B1117BE0721D8FD55BF0235620209AACE1B8B2992DBE94F8238AC7E31C758202C548152AF1E4FF39B070B650A52E25793E6E344E027A94CC0CB98269DCBECCBF
+20220714171847 2 6 100 6143 2 FFB27E2CC8B774D736BFE9ECC0EB33B1BC6D4DEA1E8B360AD96E83A7213A91CCC112624B99480D8B7E7C3B6A70A96B7F267C4FE080158429ECB77525C930D5C61BFC7858FF4D571FE7C533CC24A8B1188EF52DD31B0910207C6B5166A9A097F1D12932EBE47B9B876F2FE0F9344AD4B4BA45B0BBB58908E9D6F8DA689D318AA7C1E198CA2AD22722C00C03A393C8BFC2C037C33429CEDF0660F5716CBC1A15530ED5A3C368B96973A43F1AB70E8BA75ABBB35C85B15E58B56E5C8196B6E9D3C65A236786B55733B64FD6D4F46672EFB796962A3E07AB74C597961E99B573BD8F6046F89C317CA6D9F4922A222CC0EA11E9823F742937FB0EC1A8B7FC8A588193B2AF4C2DECA3EE9724FD8818A0792445FF5E0B7ADDD3EF2282BF471F5322FE0950D91B9B7688B7D134741B60BA427DAF6F09A57C027BE9D5FF6AF15A6DBB183E86E4C682FCD711472039537425BBC2C07D91503187E5F7B9CE7C576AC0CC799791971C23F82C2519635F9B4E1BEE7941DD602EE778E5A99EF77FF9FCFEDC0CC6F90E1F8E2C09D596237C37EC368A78BE8CA54A7406A5BF0708885967909CE810651BC792BD84B1805E3964F31002B647A88FAFF57E94F56E75E5C866E43E7360928B8E7D8E89CE43F5D84E21A3075E9974ED065C825268994DA5E0ABBAFDC1A6636AEB8856C6703CA917C7DF7B607F7DEECD894E6DC133E1904C73499706EC71D2780726A3019F3975835EB22CD82451522CD11A38B28BD742B2A278B886BFFBAF1354D248DE81CE41E8DC7CDD31264D5374CD6D1E53FB07798A5122E18710B2648ABF174A3C8F31222BEFCA76C3F6D7240483119BE84BDB5B72D6CC812A21E2C3A3AF1C263DD5794A716028943E3491EDD9976C4AD900BA4E5BBE2A531BA3B8AF6BF5B952876DB85A70B5C6EBBDDF82E4FD4E518277CDAA86824F82DADE5F73FC60E81C3035A92CC374274DDD8400C144AD28B2B410E186D2A799A1BBAD5B88B1117BE0721D8FD55BF0235620209AACE1B8B2992DBE94F8238AC7E31C758202C548152AF1E4FF39B070B650A52E25793E6E344E027A94CC0CB98269DD5B7993
+20220714173040 2 6 100 6143 5 FFB27E2CC8B774D736BFE9ECC0EB33B1BC6D4DEA1E8B360AD96E83A7213A91CCC112624B99480D8B7E7C3B6A70A96B7F267C4FE080158429ECB77525C930D5C61BFC7858FF4D571FE7C533CC24A8B1188EF52DD31B0910207C6B5166A9A097F1D12932EBE47B9B876F2FE0F9344AD4B4BA45B0BBB58908E9D6F8DA689D318AA7C1E198CA2AD22722C00C03A393C8BFC2C037C33429CEDF0660F5716CBC1A15530ED5A3C368B96973A43F1AB70E8BA75ABBB35C85B15E58B56E5C8196B6E9D3C65A236786B55733B64FD6D4F46672EFB796962A3E07AB74C597961E99B573BD8F6046F89C317CA6D9F4922A222CC0EA11E9823F742937FB0EC1A8B7FC8A588193B2AF4C2DECA3EE9724FD8818A0792445FF5E0B7ADDD3EF2282BF471F5322FE0950D91B9B7688B7D134741B60BA427DAF6F09A57C027BE9D5FF6AF15A6DBB183E86E4C682FCD711472039537425BBC2C07D91503187E5F7B9CE7C576AC0CC799791971C23F82C2519635F9B4E1BEE7941DD602EE778E5A99EF77FF9FCFEDC0CC6F90E1F8E2C09D596237C37EC368A78BE8CA54A7406A5BF0708885967909CE810651BC792BD84B1805E3964F31002B647A88FAFF57E94F56E75E5C866E43E7360928B8E7D8E89CE43F5D84E21A3075E9974ED065C825268994DA5E0ABBAFDC1A6636AEB8856C6703CA917C7DF7B607F7DEECD894E6DC133E1904C73499706EC71D2780726A3019F3975835EB22CD82451522CD11A38B28BD742B2A278B886BFFBAF1354D248DE81CE41E8DC7CDD31264D5374CD6D1E53FB07798A5122E18710B2648ABF174A3C8F31222BEFCA76C3F6D7240483119BE84BDB5B72D6CC812A21E2C3A3AF1C263DD5794A716028943E3491EDD9976C4AD900BA4E5BBE2A531BA3B8AF6BF5B952876DB85A70B5C6EBBDDF82E4FD4E518277CDAA86824F82DADE5F73FC60E81C3035A92CC374274DDD8400C144AD28B2B410E186D2A799A1BBAD5B88B1117BE0721D8FD55BF0235620209AACE1B8B2992DBE94F8238AC7E31C758202C548152AF1E4FF39B070B650A52E25793E6E344E027A94CC0CB98269DEFCEA7F
+20220714174048 2 6 100 6143 5 FFB27E2CC8B774D736BFE9ECC0EB33B1BC6D4DEA1E8B360AD96E83A7213A91CCC112624B99480D8B7E7C3B6A70A96B7F267C4FE080158429ECB77525C930D5C61BFC7858FF4D571FE7C533CC24A8B1188EF52DD31B0910207C6B5166A9A097F1D12932EBE47B9B876F2FE0F9344AD4B4BA45B0BBB58908E9D6F8DA689D318AA7C1E198CA2AD22722C00C03A393C8BFC2C037C33429CEDF0660F5716CBC1A15530ED5A3C368B96973A43F1AB70E8BA75ABBB35C85B15E58B56E5C8196B6E9D3C65A236786B55733B64FD6D4F46672EFB796962A3E07AB74C597961E99B573BD8F6046F89C317CA6D9F4922A222CC0EA11E9823F742937FB0EC1A8B7FC8A588193B2AF4C2DECA3EE9724FD8818A0792445FF5E0B7ADDD3EF2282BF471F5322FE0950D91B9B7688B7D134741B60BA427DAF6F09A57C027BE9D5FF6AF15A6DBB183E86E4C682FCD711472039537425BBC2C07D91503187E5F7B9CE7C576AC0CC799791971C23F82C2519635F9B4E1BEE7941DD602EE778E5A99EF77FF9FCFEDC0CC6F90E1F8E2C09D596237C37EC368A78BE8CA54A7406A5BF0708885967909CE810651BC792BD84B1805E3964F31002B647A88FAFF57E94F56E75E5C866E43E7360928B8E7D8E89CE43F5D84E21A3075E9974ED065C825268994DA5E0ABBAFDC1A6636AEB8856C6703CA917C7DF7B607F7DEECD894E6DC133E1904C73499706EC71D2780726A3019F3975835EB22CD82451522CD11A38B28BD742B2A278B886BFFBAF1354D248DE81CE41E8DC7CDD31264D5374CD6D1E53FB07798A5122E18710B2648ABF174A3C8F31222BEFCA76C3F6D7240483119BE84BDB5B72D6CC812A21E2C3A3AF1C263DD5794A716028943E3491EDD9976C4AD900BA4E5BBE2A531BA3B8AF6BF5B952876DB85A70B5C6EBBDDF82E4FD4E518277CDAA86824F82DADE5F73FC60E81C3035A92CC374274DDD8400C144AD28B2B410E186D2A799A1BBAD5B88B1117BE0721D8FD55BF0235620209AACE1B8B2992DBE94F8238AC7E31C758202C548152AF1E4FF39B070B650A52E25793E6E344E027A94CC0CB98269E060A22F
+20220714175752 2 6 100 6143 5 FFB27E2CC8B774D736BFE9ECC0EB33B1BC6D4DEA1E8B360AD96E83A7213A91CCC112624B99480D8B7E7C3B6A70A96B7F267C4FE080158429ECB77525C930D5C61BFC7858FF4D571FE7C533CC24A8B1188EF52DD31B0910207C6B5166A9A097F1D12932EBE47B9B876F2FE0F9344AD4B4BA45B0BBB58908E9D6F8DA689D318AA7C1E198CA2AD22722C00C03A393C8BFC2C037C33429CEDF0660F5716CBC1A15530ED5A3C368B96973A43F1AB70E8BA75ABBB35C85B15E58B56E5C8196B6E9D3C65A236786B55733B64FD6D4F46672EFB796962A3E07AB74C597961E99B573BD8F6046F89C317CA6D9F4922A222CC0EA11E9823F742937FB0EC1A8B7FC8A588193B2AF4C2DECA3EE9724FD8818A0792445FF5E0B7ADDD3EF2282BF471F5322FE0950D91B9B7688B7D134741B60BA427DAF6F09A57C027BE9D5FF6AF15A6DBB183E86E4C682FCD711472039537425BBC2C07D91503187E5F7B9CE7C576AC0CC799791971C23F82C2519635F9B4E1BEE7941DD602EE778E5A99EF77FF9FCFEDC0CC6F90E1F8E2C09D596237C37EC368A78BE8CA54A7406A5BF0708885967909CE810651BC792BD84B1805E3964F31002B647A88FAFF57E94F56E75E5C866E43E7360928B8E7D8E89CE43F5D84E21A3075E9974ED065C825268994DA5E0ABBAFDC1A6636AEB8856C6703CA917C7DF7B607F7DEECD894E6DC133E1904C73499706EC71D2780726A3019F3975835EB22CD82451522CD11A38B28BD742B2A278B886BFFBAF1354D248DE81CE41E8DC7CDD31264D5374CD6D1E53FB07798A5122E18710B2648ABF174A3C8F31222BEFCA76C3F6D7240483119BE84BDB5B72D6CC812A21E2C3A3AF1C263DD5794A716028943E3491EDD9976C4AD900BA4E5BBE2A531BA3B8AF6BF5B952876DB85A70B5C6EBBDDF82E4FD4E518277CDAA86824F82DADE5F73FC60E81C3035A92CC374274DDD8400C144AD28B2B410E186D2A799A1BBAD5B88B1117BE0721D8FD55BF0235620209AACE1B8B2992DBE94F8238AC7E31C758202C548152AF1E4FF39B070B650A52E25793E6E344E027A94CC0CB98269E2B3A90F
+20220714180116 2 6 100 6143 2 FFB27E2CC8B774D736BFE9ECC0EB33B1BC6D4DEA1E8B360AD96E83A7213A91CCC112624B99480D8B7E7C3B6A70A96B7F267C4FE080158429ECB77525C930D5C61BFC7858FF4D571FE7C533CC24A8B1188EF52DD31B0910207C6B5166A9A097F1D12932EBE47B9B876F2FE0F9344AD4B4BA45B0BBB58908E9D6F8DA689D318AA7C1E198CA2AD22722C00C03A393C8BFC2C037C33429CEDF0660F5716CBC1A15530ED5A3C368B96973A43F1AB70E8BA75ABBB35C85B15E58B56E5C8196B6E9D3C65A236786B55733B64FD6D4F46672EFB796962A3E07AB74C597961E99B573BD8F6046F89C317CA6D9F4922A222CC0EA11E9823F742937FB0EC1A8B7FC8A588193B2AF4C2DECA3EE9724FD8818A0792445FF5E0B7ADDD3EF2282BF471F5322FE0950D91B9B7688B7D134741B60BA427DAF6F09A57C027BE9D5FF6AF15A6DBB183E86E4C682FCD711472039537425BBC2C07D91503187E5F7B9CE7C576AC0CC799791971C23F82C2519635F9B4E1BEE7941DD602EE778E5A99EF77FF9FCFEDC0CC6F90E1F8E2C09D596237C37EC368A78BE8CA54A7406A5BF0708885967909CE810651BC792BD84B1805E3964F31002B647A88FAFF57E94F56E75E5C866E43E7360928B8E7D8E89CE43F5D84E21A3075E9974ED065C825268994DA5E0ABBAFDC1A6636AEB8856C6703CA917C7DF7B607F7DEECD894E6DC133E1904C73499706EC71D2780726A3019F3975835EB22CD82451522CD11A38B28BD742B2A278B886BFFBAF1354D248DE81CE41E8DC7CDD31264D5374CD6D1E53FB07798A5122E18710B2648ABF174A3C8F31222BEFCA76C3F6D7240483119BE84BDB5B72D6CC812A21E2C3A3AF1C263DD5794A716028943E3491EDD9976C4AD900BA4E5BBE2A531BA3B8AF6BF5B952876DB85A70B5C6EBBDDF82E4FD4E518277CDAA86824F82DADE5F73FC60E81C3035A92CC374274DDD8400C144AD28B2B410E186D2A799A1BBAD5B88B1117BE0721D8FD55BF0235620209AACE1B8B2992DBE94F8238AC7E31C758202C548152AF1E4FF39B070B650A52E25793E6E344E027A94CC0CB98269E328818B
+20220714181520 2 6 100 6143 2 FFB27E2CC8B774D736BFE9ECC0EB33B1BC6D4DEA1E8B360AD96E83A7213A91CCC112624B99480D8B7E7C3B6A70A96B7F267C4FE080158429ECB77525C930D5C61BFC7858FF4D571FE7C533CC24A8B1188EF52DD31B0910207C6B5166A9A097F1D12932EBE47B9B876F2FE0F9344AD4B4BA45B0BBB58908E9D6F8DA689D318AA7C1E198CA2AD22722C00C03A393C8BFC2C037C33429CEDF0660F5716CBC1A15530ED5A3C368B96973A43F1AB70E8BA75ABBB35C85B15E58B56E5C8196B6E9D3C65A236786B55733B64FD6D4F46672EFB796962A3E07AB74C597961E99B573BD8F6046F89C317CA6D9F4922A222CC0EA11E9823F742937FB0EC1A8B7FC8A588193B2AF4C2DECA3EE9724FD8818A0792445FF5E0B7ADDD3EF2282BF471F5322FE0950D91B9B7688B7D134741B60BA427DAF6F09A57C027BE9D5FF6AF15A6DBB183E86E4C682FCD711472039537425BBC2C07D91503187E5F7B9CE7C576AC0CC799791971C23F82C2519635F9B4E1BEE7941DD602EE778E5A99EF77FF9FCFEDC0CC6F90E1F8E2C09D596237C37EC368A78BE8CA54A7406A5BF0708885967909CE810651BC792BD84B1805E3964F31002B647A88FAFF57E94F56E75E5C866E43E7360928B8E7D8E89CE43F5D84E21A3075E9974ED065C825268994DA5E0ABBAFDC1A6636AEB8856C6703CA917C7DF7B607F7DEECD894E6DC133E1904C73499706EC71D2780726A3019F3975835EB22CD82451522CD11A38B28BD742B2A278B886BFFBAF1354D248DE81CE41E8DC7CDD31264D5374CD6D1E53FB07798A5122E18710B2648ABF174A3C8F31222BEFCA76C3F6D7240483119BE84BDB5B72D6CC812A21E2C3A3AF1C263DD5794A716028943E3491EDD9976C4AD900BA4E5BBE2A531BA3B8AF6BF5B952876DB85A70B5C6EBBDDF82E4FD4E518277CDAA86824F82DADE5F73FC60E81C3035A92CC374274DDD8400C144AD28B2B410E186D2A799A1BBAD5B88B1117BE0721D8FD55BF0235620209AACE1B8B2992DBE94F8238AC7E31C758202C548152AF1E4FF39B070B650A52E25793E6E344E027A94CC0CB98269E513DE83
+20220714182218 2 6 100 6143 5 FFB27E2CC8B774D736BFE9ECC0EB33B1BC6D4DEA1E8B360AD96E83A7213A91CCC112624B99480D8B7E7C3B6A70A96B7F267C4FE080158429ECB77525C930D5C61BFC7858FF4D571FE7C533CC24A8B1188EF52DD31B0910207C6B5166A9A097F1D12932EBE47B9B876F2FE0F9344AD4B4BA45B0BBB58908E9D6F8DA689D318AA7C1E198CA2AD22722C00C03A393C8BFC2C037C33429CEDF0660F5716CBC1A15530ED5A3C368B96973A43F1AB70E8BA75ABBB35C85B15E58B56E5C8196B6E9D3C65A236786B55733B64FD6D4F46672EFB796962A3E07AB74C597961E99B573BD8F6046F89C317CA6D9F4922A222CC0EA11E9823F742937FB0EC1A8B7FC8A588193B2AF4C2DECA3EE9724FD8818A0792445FF5E0B7ADDD3EF2282BF471F5322FE0950D91B9B7688B7D134741B60BA427DAF6F09A57C027BE9D5FF6AF15A6DBB183E86E4C682FCD711472039537425BBC2C07D91503187E5F7B9CE7C576AC0CC799791971C23F82C2519635F9B4E1BEE7941DD602EE778E5A99EF77FF9FCFEDC0CC6F90E1F8E2C09D596237C37EC368A78BE8CA54A7406A5BF0708885967909CE810651BC792BD84B1805E3964F31002B647A88FAFF57E94F56E75E5C866E43E7360928B8E7D8E89CE43F5D84E21A3075E9974ED065C825268994DA5E0ABBAFDC1A6636AEB8856C6703CA917C7DF7B607F7DEECD894E6DC133E1904C73499706EC71D2780726A3019F3975835EB22CD82451522CD11A38B28BD742B2A278B886BFFBAF1354D248DE81CE41E8DC7CDD31264D5374CD6D1E53FB07798A5122E18710B2648ABF174A3C8F31222BEFCA76C3F6D7240483119BE84BDB5B72D6CC812A21E2C3A3AF1C263DD5794A716028943E3491EDD9976C4AD900BA4E5BBE2A531BA3B8AF6BF5B952876DB85A70B5C6EBBDDF82E4FD4E518277CDAA86824F82DADE5F73FC60E81C3035A92CC374274DDD8400C144AD28B2B410E186D2A799A1BBAD5B88B1117BE0721D8FD55BF0235620209AACE1B8B2992DBE94F8238AC7E31C758202C548152AF1E4FF39B070B650A52E25793E6E344E027A94CC0CB98269E604A3CF
+20220714182735 2 6 100 6143 2 FFB27E2CC8B774D736BFE9ECC0EB33B1BC6D4DEA1E8B360AD96E83A7213A91CCC112624B99480D8B7E7C3B6A70A96B7F267C4FE080158429ECB77525C930D5C61BFC7858FF4D571FE7C533CC24A8B1188EF52DD31B0910207C6B5166A9A097F1D12932EBE47B9B876F2FE0F9344AD4B4BA45B0BBB58908E9D6F8DA689D318AA7C1E198CA2AD22722C00C03A393C8BFC2C037C33429CEDF0660F5716CBC1A15530ED5A3C368B96973A43F1AB70E8BA75ABBB35C85B15E58B56E5C8196B6E9D3C65A236786B55733B64FD6D4F46672EFB796962A3E07AB74C597961E99B573BD8F6046F89C317CA6D9F4922A222CC0EA11E9823F742937FB0EC1A8B7FC8A588193B2AF4C2DECA3EE9724FD8818A0792445FF5E0B7ADDD3EF2282BF471F5322FE0950D91B9B7688B7D134741B60BA427DAF6F09A57C027BE9D5FF6AF15A6DBB183E86E4C682FCD711472039537425BBC2C07D91503187E5F7B9CE7C576AC0CC799791971C23F82C2519635F9B4E1BEE7941DD602EE778E5A99EF77FF9FCFEDC0CC6F90E1F8E2C09D596237C37EC368A78BE8CA54A7406A5BF0708885967909CE810651BC792BD84B1805E3964F31002B647A88FAFF57E94F56E75E5C866E43E7360928B8E7D8E89CE43F5D84E21A3075E9974ED065C825268994DA5E0ABBAFDC1A6636AEB8856C6703CA917C7DF7B607F7DEECD894E6DC133E1904C73499706EC71D2780726A3019F3975835EB22CD82451522CD11A38B28BD742B2A278B886BFFBAF1354D248DE81CE41E8DC7CDD31264D5374CD6D1E53FB07798A5122E18710B2648ABF174A3C8F31222BEFCA76C3F6D7240483119BE84BDB5B72D6CC812A21E2C3A3AF1C263DD5794A716028943E3491EDD9976C4AD900BA4E5BBE2A531BA3B8AF6BF5B952876DB85A70B5C6EBBDDF82E4FD4E518277CDAA86824F82DADE5F73FC60E81C3035A92CC374274DDD8400C144AD28B2B410E186D2A799A1BBAD5B88B1117BE0721D8FD55BF0235620209AACE1B8B2992DBE94F8238AC7E31C758202C548152AF1E4FF39B070B650A52E25793E6E344E027A94CC0CB98269E6BBA01B
+20220714191804 2 6 100 6143 5 FFB27E2CC8B774D736BFE9ECC0EB33B1BC6D4DEA1E8B360AD96E83A7213A91CCC112624B99480D8B7E7C3B6A70A96B7F267C4FE080158429ECB77525C930D5C61BFC7858FF4D571FE7C533CC24A8B1188EF52DD31B0910207C6B5166A9A097F1D12932EBE47B9B876F2FE0F9344AD4B4BA45B0BBB58908E9D6F8DA689D318AA7C1E198CA2AD22722C00C03A393C8BFC2C037C33429CEDF0660F5716CBC1A15530ED5A3C368B96973A43F1AB70E8BA75ABBB35C85B15E58B56E5C8196B6E9D3C65A236786B55733B64FD6D4F46672EFB796962A3E07AB74C597961E99B573BD8F6046F89C317CA6D9F4922A222CC0EA11E9823F742937FB0EC1A8B7FC8A588193B2AF4C2DECA3EE9724FD8818A0792445FF5E0B7ADDD3EF2282BF471F5322FE0950D91B9B7688B7D134741B60BA427DAF6F09A57C027BE9D5FF6AF15A6DBB183E86E4C682FCD711472039537425BBC2C07D91503187E5F7B9CE7C576AC0CC799791971C23F82C2519635F9B4E1BEE7941DD602EE778E5A99EF77FF9FCFEDC0CC6F90E1F8E2C09D596237C37EC368A78BE8CA54A7406A5BF0708885967909CE810651BC792BD84B1805E3964F31002B647A88FAFF57E94F56E75E5C866E43E7360928B8E7D8E89CE43F5D84E21A3075E9974ED065C825268994DA5E0ABBAFDC1A6636AEB8856C6703CA917C7DF7B607F7DEECD894E6DC133E1904C73499706EC71D2780726A3019F3975835EB22CD82451522CD11A38B28BD742B2A278B886BFFBAF1354D248DE81CE41E8DC7CDD31264D5374CD6D1E53FB07798A5122E18710B2648ABF174A3C8F31222BEFCA76C3F6D7240483119BE84BDB5B72D6CC812A21E2C3A3AF1C263DD5794A716028943E3491EDD9976C4AD900BA4E5BBE2A531BA3B8AF6BF5B952876DB85A70B5C6EBBDDF82E4FD4E518277CDAA86824F82DADE5F73FC60E81C3035A92CC374274DDD8400C144AD28B2B410E186D2A799A1BBAD5B88B1117BE0721D8FD55BF0235620209AACE1B8B2992DBE94F8238AC7E31C758202C548152AF1E4FF39B070B650A52E25793E6E344E027A94CC0CB98269ED919FB7
+20220714191958 2 6 100 6143 2 FFB27E2CC8B774D736BFE9ECC0EB33B1BC6D4DEA1E8B360AD96E83A7213A91CCC112624B99480D8B7E7C3B6A70A96B7F267C4FE080158429ECB77525C930D5C61BFC7858FF4D571FE7C533CC24A8B1188EF52DD31B0910207C6B5166A9A097F1D12932EBE47B9B876F2FE0F9344AD4B4BA45B0BBB58908E9D6F8DA689D318AA7C1E198CA2AD22722C00C03A393C8BFC2C037C33429CEDF0660F5716CBC1A15530ED5A3C368B96973A43F1AB70E8BA75ABBB35C85B15E58B56E5C8196B6E9D3C65A236786B55733B64FD6D4F46672EFB796962A3E07AB74C597961E99B573BD8F6046F89C317CA6D9F4922A222CC0EA11E9823F742937FB0EC1A8B7FC8A588193B2AF4C2DECA3EE9724FD8818A0792445FF5E0B7ADDD3EF2282BF471F5322FE0950D91B9B7688B7D134741B60BA427DAF6F09A57C027BE9D5FF6AF15A6DBB183E86E4C682FCD711472039537425BBC2C07D91503187E5F7B9CE7C576AC0CC799791971C23F82C2519635F9B4E1BEE7941DD602EE778E5A99EF77FF9FCFEDC0CC6F90E1F8E2C09D596237C37EC368A78BE8CA54A7406A5BF0708885967909CE810651BC792BD84B1805E3964F31002B647A88FAFF57E94F56E75E5C866E43E7360928B8E7D8E89CE43F5D84E21A3075E9974ED065C825268994DA5E0ABBAFDC1A6636AEB8856C6703CA917C7DF7B607F7DEECD894E6DC133E1904C73499706EC71D2780726A3019F3975835EB22CD82451522CD11A38B28BD742B2A278B886BFFBAF1354D248DE81CE41E8DC7CDD31264D5374CD6D1E53FB07798A5122E18710B2648ABF174A3C8F31222BEFCA76C3F6D7240483119BE84BDB5B72D6CC812A21E2C3A3AF1C263DD5794A716028943E3491EDD9976C4AD900BA4E5BBE2A531BA3B8AF6BF5B952876DB85A70B5C6EBBDDF82E4FD4E518277CDAA86824F82DADE5F73FC60E81C3035A92CC374274DDD8400C144AD28B2B410E186D2A799A1BBAD5B88B1117BE0721D8FD55BF0235620209AACE1B8B2992DBE94F8238AC7E31C758202C548152AF1E4FF39B070B650A52E25793E6E344E027A94CC0CB98269EDD630C3
+20220714193455 2 6 100 6143 2 FFB27E2CC8B774D736BFE9ECC0EB33B1BC6D4DEA1E8B360AD96E83A7213A91CCC112624B99480D8B7E7C3B6A70A96B7F267C4FE080158429ECB77525C930D5C61BFC7858FF4D571FE7C533CC24A8B1188EF52DD31B0910207C6B5166A9A097F1D12932EBE47B9B876F2FE0F9344AD4B4BA45B0BBB58908E9D6F8DA689D318AA7C1E198CA2AD22722C00C03A393C8BFC2C037C33429CEDF0660F5716CBC1A15530ED5A3C368B96973A43F1AB70E8BA75ABBB35C85B15E58B56E5C8196B6E9D3C65A236786B55733B64FD6D4F46672EFB796962A3E07AB74C597961E99B573BD8F6046F89C317CA6D9F4922A222CC0EA11E9823F742937FB0EC1A8B7FC8A588193B2AF4C2DECA3EE9724FD8818A0792445FF5E0B7ADDD3EF2282BF471F5322FE0950D91B9B7688B7D134741B60BA427DAF6F09A57C027BE9D5FF6AF15A6DBB183E86E4C682FCD711472039537425BBC2C07D91503187E5F7B9CE7C576AC0CC799791971C23F82C2519635F9B4E1BEE7941DD602EE778E5A99EF77FF9FCFEDC0CC6F90E1F8E2C09D596237C37EC368A78BE8CA54A7406A5BF0708885967909CE810651BC792BD84B1805E3964F31002B647A88FAFF57E94F56E75E5C866E43E7360928B8E7D8E89CE43F5D84E21A3075E9974ED065C825268994DA5E0ABBAFDC1A6636AEB8856C6703CA917C7DF7B607F7DEECD894E6DC133E1904C73499706EC71D2780726A3019F3975835EB22CD82451522CD11A38B28BD742B2A278B886BFFBAF1354D248DE81CE41E8DC7CDD31264D5374CD6D1E53FB07798A5122E18710B2648ABF174A3C8F31222BEFCA76C3F6D7240483119BE84BDB5B72D6CC812A21E2C3A3AF1C263DD5794A716028943E3491EDD9976C4AD900BA4E5BBE2A531BA3B8AF6BF5B952876DB85A70B5C6EBBDDF82E4FD4E518277CDAA86824F82DADE5F73FC60E81C3035A92CC374274DDD8400C144AD28B2B410E186D2A799A1BBAD5B88B1117BE0721D8FD55BF0235620209AACE1B8B2992DBE94F8238AC7E31C758202C548152AF1E4FF39B070B650A52E25793E6E344E027A94CC0CB98269EFDB6C53
+20220714193500 2 6 100 6143 2 FFB27E2CC8B774D736BFE9ECC0EB33B1BC6D4DEA1E8B360AD96E83A7213A91CCC112624B99480D8B7E7C3B6A70A96B7F267C4FE080158429ECB77525C930D5C61BFC7858FF4D571FE7C533CC24A8B1188EF52DD31B0910207C6B5166A9A097F1D12932EBE47B9B876F2FE0F9344AD4B4BA45B0BBB58908E9D6F8DA689D318AA7C1E198CA2AD22722C00C03A393C8BFC2C037C33429CEDF0660F5716CBC1A15530ED5A3C368B96973A43F1AB70E8BA75ABBB35C85B15E58B56E5C8196B6E9D3C65A236786B55733B64FD6D4F46672EFB796962A3E07AB74C597961E99B573BD8F6046F89C317CA6D9F4922A222CC0EA11E9823F742937FB0EC1A8B7FC8A588193B2AF4C2DECA3EE9724FD8818A0792445FF5E0B7ADDD3EF2282BF471F5322FE0950D91B9B7688B7D134741B60BA427DAF6F09A57C027BE9D5FF6AF15A6DBB183E86E4C682FCD711472039537425BBC2C07D91503187E5F7B9CE7C576AC0CC799791971C23F82C2519635F9B4E1BEE7941DD602EE778E5A99EF77FF9FCFEDC0CC6F90E1F8E2C09D596237C37EC368A78BE8CA54A7406A5BF0708885967909CE810651BC792BD84B1805E3964F31002B647A88FAFF57E94F56E75E5C866E43E7360928B8E7D8E89CE43F5D84E21A3075E9974ED065C825268994DA5E0ABBAFDC1A6636AEB8856C6703CA917C7DF7B607F7DEECD894E6DC133E1904C73499706EC71D2780726A3019F3975835EB22CD82451522CD11A38B28BD742B2A278B886BFFBAF1354D248DE81CE41E8DC7CDD31264D5374CD6D1E53FB07798A5122E18710B2648ABF174A3C8F31222BEFCA76C3F6D7240483119BE84BDB5B72D6CC812A21E2C3A3AF1C263DD5794A716028943E3491EDD9976C4AD900BA4E5BBE2A531BA3B8AF6BF5B952876DB85A70B5C6EBBDDF82E4FD4E518277CDAA86824F82DADE5F73FC60E81C3035A92CC374274DDD8400C144AD28B2B410E186D2A799A1BBAD5B88B1117BE0721D8FD55BF0235620209AACE1B8B2992DBE94F8238AC7E31C758202C548152AF1E4FF39B070B650A52E25793E6E344E027A94CC0CB98269EFDE36FB
+20220714194107 2 6 100 6143 2 FFB27E2CC8B774D736BFE9ECC0EB33B1BC6D4DEA1E8B360AD96E83A7213A91CCC112624B99480D8B7E7C3B6A70A96B7F267C4FE080158429ECB77525C930D5C61BFC7858FF4D571FE7C533CC24A8B1188EF52DD31B0910207C6B5166A9A097F1D12932EBE47B9B876F2FE0F9344AD4B4BA45B0BBB58908E9D6F8DA689D318AA7C1E198CA2AD22722C00C03A393C8BFC2C037C33429CEDF0660F5716CBC1A15530ED5A3C368B96973A43F1AB70E8BA75ABBB35C85B15E58B56E5C8196B6E9D3C65A236786B55733B64FD6D4F46672EFB796962A3E07AB74C597961E99B573BD8F6046F89C317CA6D9F4922A222CC0EA11E9823F742937FB0EC1A8B7FC8A588193B2AF4C2DECA3EE9724FD8818A0792445FF5E0B7ADDD3EF2282BF471F5322FE0950D91B9B7688B7D134741B60BA427DAF6F09A57C027BE9D5FF6AF15A6DBB183E86E4C682FCD711472039537425BBC2C07D91503187E5F7B9CE7C576AC0CC799791971C23F82C2519635F9B4E1BEE7941DD602EE778E5A99EF77FF9FCFEDC0CC6F90E1F8E2C09D596237C37EC368A78BE8CA54A7406A5BF0708885967909CE810651BC792BD84B1805E3964F31002B647A88FAFF57E94F56E75E5C866E43E7360928B8E7D8E89CE43F5D84E21A3075E9974ED065C825268994DA5E0ABBAFDC1A6636AEB8856C6703CA917C7DF7B607F7DEECD894E6DC133E1904C73499706EC71D2780726A3019F3975835EB22CD82451522CD11A38B28BD742B2A278B886BFFBAF1354D248DE81CE41E8DC7CDD31264D5374CD6D1E53FB07798A5122E18710B2648ABF174A3C8F31222BEFCA76C3F6D7240483119BE84BDB5B72D6CC812A21E2C3A3AF1C263DD5794A716028943E3491EDD9976C4AD900BA4E5BBE2A531BA3B8AF6BF5B952876DB85A70B5C6EBBDDF82E4FD4E518277CDAA86824F82DADE5F73FC60E81C3035A92CC374274DDD8400C144AD28B2B410E186D2A799A1BBAD5B88B1117BE0721D8FD55BF0235620209AACE1B8B2992DBE94F8238AC7E31C758202C548152AF1E4FF39B070B650A52E25793E6E344E027A94CC0CB98269F0AC9F63
+20220714195248 2 6 100 6143 2 FFB27E2CC8B774D736BFE9ECC0EB33B1BC6D4DEA1E8B360AD96E83A7213A91CCC112624B99480D8B7E7C3B6A70A96B7F267C4FE080158429ECB77525C930D5C61BFC7858FF4D571FE7C533CC24A8B1188EF52DD31B0910207C6B5166A9A097F1D12932EBE47B9B876F2FE0F9344AD4B4BA45B0BBB58908E9D6F8DA689D318AA7C1E198CA2AD22722C00C03A393C8BFC2C037C33429CEDF0660F5716CBC1A15530ED5A3C368B96973A43F1AB70E8BA75ABBB35C85B15E58B56E5C8196B6E9D3C65A236786B55733B64FD6D4F46672EFB796962A3E07AB74C597961E99B573BD8F6046F89C317CA6D9F4922A222CC0EA11E9823F742937FB0EC1A8B7FC8A588193B2AF4C2DECA3EE9724FD8818A0792445FF5E0B7ADDD3EF2282BF471F5322FE0950D91B9B7688B7D134741B60BA427DAF6F09A57C027BE9D5FF6AF15A6DBB183E86E4C682FCD711472039537425BBC2C07D91503187E5F7B9CE7C576AC0CC799791971C23F82C2519635F9B4E1BEE7941DD602EE778E5A99EF77FF9FCFEDC0CC6F90E1F8E2C09D596237C37EC368A78BE8CA54A7406A5BF0708885967909CE810651BC792BD84B1805E3964F31002B647A88FAFF57E94F56E75E5C866E43E7360928B8E7D8E89CE43F5D84E21A3075E9974ED065C825268994DA5E0ABBAFDC1A6636AEB8856C6703CA917C7DF7B607F7DEECD894E6DC133E1904C73499706EC71D2780726A3019F3975835EB22CD82451522CD11A38B28BD742B2A278B886BFFBAF1354D248DE81CE41E8DC7CDD31264D5374CD6D1E53FB07798A5122E18710B2648ABF174A3C8F31222BEFCA76C3F6D7240483119BE84BDB5B72D6CC812A21E2C3A3AF1C263DD5794A716028943E3491EDD9976C4AD900BA4E5BBE2A531BA3B8AF6BF5B952876DB85A70B5C6EBBDDF82E4FD4E518277CDAA86824F82DADE5F73FC60E81C3035A92CC374274DDD8400C144AD28B2B410E186D2A799A1BBAD5B88B1117BE0721D8FD55BF0235620209AACE1B8B2992DBE94F8238AC7E31C758202C548152AF1E4FF39B070B650A52E25793E6E344E027A94CC0CB98269F23F6BF3
+20220714195808 2 6 100 6143 5 FFB27E2CC8B774D736BFE9ECC0EB33B1BC6D4DEA1E8B360AD96E83A7213A91CCC112624B99480D8B7E7C3B6A70A96B7F267C4FE080158429ECB77525C930D5C61BFC7858FF4D571FE7C533CC24A8B1188EF52DD31B0910207C6B5166A9A097F1D12932EBE47B9B876F2FE0F9344AD4B4BA45B0BBB58908E9D6F8DA689D318AA7C1E198CA2AD22722C00C03A393C8BFC2C037C33429CEDF0660F5716CBC1A15530ED5A3C368B96973A43F1AB70E8BA75ABBB35C85B15E58B56E5C8196B6E9D3C65A236786B55733B64FD6D4F46672EFB796962A3E07AB74C597961E99B573BD8F6046F89C317CA6D9F4922A222CC0EA11E9823F742937FB0EC1A8B7FC8A588193B2AF4C2DECA3EE9724FD8818A0792445FF5E0B7ADDD3EF2282BF471F5322FE0950D91B9B7688B7D134741B60BA427DAF6F09A57C027BE9D5FF6AF15A6DBB183E86E4C682FCD711472039537425BBC2C07D91503187E5F7B9CE7C576AC0CC799791971C23F82C2519635F9B4E1BEE7941DD602EE778E5A99EF77FF9FCFEDC0CC6F90E1F8E2C09D596237C37EC368A78BE8CA54A7406A5BF0708885967909CE810651BC792BD84B1805E3964F31002B647A88FAFF57E94F56E75E5C866E43E7360928B8E7D8E89CE43F5D84E21A3075E9974ED065C825268994DA5E0ABBAFDC1A6636AEB8856C6703CA917C7DF7B607F7DEECD894E6DC133E1904C73499706EC71D2780726A3019F3975835EB22CD82451522CD11A38B28BD742B2A278B886BFFBAF1354D248DE81CE41E8DC7CDD31264D5374CD6D1E53FB07798A5122E18710B2648ABF174A3C8F31222BEFCA76C3F6D7240483119BE84BDB5B72D6CC812A21E2C3A3AF1C263DD5794A716028943E3491EDD9976C4AD900BA4E5BBE2A531BA3B8AF6BF5B952876DB85A70B5C6EBBDDF82E4FD4E518277CDAA86824F82DADE5F73FC60E81C3035A92CC374274DDD8400C144AD28B2B410E186D2A799A1BBAD5B88B1117BE0721D8FD55BF0235620209AACE1B8B2992DBE94F8238AC7E31C758202C548152AF1E4FF39B070B650A52E25793E6E344E027A94CC0CB98269F300673F
+20220714200658 2 6 100 6143 5 FFB27E2CC8B774D736BFE9ECC0EB33B1BC6D4DEA1E8B360AD96E83A7213A91CCC112624B99480D8B7E7C3B6A70A96B7F267C4FE080158429ECB77525C930D5C61BFC7858FF4D571FE7C533CC24A8B1188EF52DD31B0910207C6B5166A9A097F1D12932EBE47B9B876F2FE0F9344AD4B4BA45B0BBB58908E9D6F8DA689D318AA7C1E198CA2AD22722C00C03A393C8BFC2C037C33429CEDF0660F5716CBC1A15530ED5A3C368B96973A43F1AB70E8BA75ABBB35C85B15E58B56E5C8196B6E9D3C65A236786B55733B64FD6D4F46672EFB796962A3E07AB74C597961E99B573BD8F6046F89C317CA6D9F4922A222CC0EA11E9823F742937FB0EC1A8B7FC8A588193B2AF4C2DECA3EE9724FD8818A0792445FF5E0B7ADDD3EF2282BF471F5322FE0950D91B9B7688B7D134741B60BA427DAF6F09A57C027BE9D5FF6AF15A6DBB183E86E4C682FCD711472039537425BBC2C07D91503187E5F7B9CE7C576AC0CC799791971C23F82C2519635F9B4E1BEE7941DD602EE778E5A99EF77FF9FCFEDC0CC6F90E1F8E2C09D596237C37EC368A78BE8CA54A7406A5BF0708885967909CE810651BC792BD84B1805E3964F31002B647A88FAFF57E94F56E75E5C866E43E7360928B8E7D8E89CE43F5D84E21A3075E9974ED065C825268994DA5E0ABBAFDC1A6636AEB8856C6703CA917C7DF7B607F7DEECD894E6DC133E1904C73499706EC71D2780726A3019F3975835EB22CD82451522CD11A38B28BD742B2A278B886BFFBAF1354D248DE81CE41E8DC7CDD31264D5374CD6D1E53FB07798A5122E18710B2648ABF174A3C8F31222BEFCA76C3F6D7240483119BE84BDB5B72D6CC812A21E2C3A3AF1C263DD5794A716028943E3491EDD9976C4AD900BA4E5BBE2A531BA3B8AF6BF5B952876DB85A70B5C6EBBDDF82E4FD4E518277CDAA86824F82DADE5F73FC60E81C3035A92CC374274DDD8400C144AD28B2B410E186D2A799A1BBAD5B88B1117BE0721D8FD55BF0235620209AACE1B8B2992DBE94F8238AC7E31C758202C548152AF1E4FF39B070B650A52E25793E6E344E027A94CC0CB98269F4322A4F
+20220714201511 2 6 100 6143 5 FFB27E2CC8B774D736BFE9ECC0EB33B1BC6D4DEA1E8B360AD96E83A7213A91CCC112624B99480D8B7E7C3B6A70A96B7F267C4FE080158429ECB77525C930D5C61BFC7858FF4D571FE7C533CC24A8B1188EF52DD31B0910207C6B5166A9A097F1D12932EBE47B9B876F2FE0F9344AD4B4BA45B0BBB58908E9D6F8DA689D318AA7C1E198CA2AD22722C00C03A393C8BFC2C037C33429CEDF0660F5716CBC1A15530ED5A3C368B96973A43F1AB70E8BA75ABBB35C85B15E58B56E5C8196B6E9D3C65A236786B55733B64FD6D4F46672EFB796962A3E07AB74C597961E99B573BD8F6046F89C317CA6D9F4922A222CC0EA11E9823F742937FB0EC1A8B7FC8A588193B2AF4C2DECA3EE9724FD8818A0792445FF5E0B7ADDD3EF2282BF471F5322FE0950D91B9B7688B7D134741B60BA427DAF6F09A57C027BE9D5FF6AF15A6DBB183E86E4C682FCD711472039537425BBC2C07D91503187E5F7B9CE7C576AC0CC799791971C23F82C2519635F9B4E1BEE7941DD602EE778E5A99EF77FF9FCFEDC0CC6F90E1F8E2C09D596237C37EC368A78BE8CA54A7406A5BF0708885967909CE810651BC792BD84B1805E3964F31002B647A88FAFF57E94F56E75E5C866E43E7360928B8E7D8E89CE43F5D84E21A3075E9974ED065C825268994DA5E0ABBAFDC1A6636AEB8856C6703CA917C7DF7B607F7DEECD894E6DC133E1904C73499706EC71D2780726A3019F3975835EB22CD82451522CD11A38B28BD742B2A278B886BFFBAF1354D248DE81CE41E8DC7CDD31264D5374CD6D1E53FB07798A5122E18710B2648ABF174A3C8F31222BEFCA76C3F6D7240483119BE84BDB5B72D6CC812A21E2C3A3AF1C263DD5794A716028943E3491EDD9976C4AD900BA4E5BBE2A531BA3B8AF6BF5B952876DB85A70B5C6EBBDDF82E4FD4E518277CDAA86824F82DADE5F73FC60E81C3035A92CC374274DDD8400C144AD28B2B410E186D2A799A1BBAD5B88B1117BE0721D8FD55BF0235620209AACE1B8B2992DBE94F8238AC7E31C758202C548152AF1E4FF39B070B650A52E25793E6E344E027A94CC0CB98269F553D0EF
+20220714204211 2 6 100 6143 2 FFB27E2CC8B774D736BFE9ECC0EB33B1BC6D4DEA1E8B360AD96E83A7213A91CCC112624B99480D8B7E7C3B6A70A96B7F267C4FE080158429ECB77525C930D5C61BFC7858FF4D571FE7C533CC24A8B1188EF52DD31B0910207C6B5166A9A097F1D12932EBE47B9B876F2FE0F9344AD4B4BA45B0BBB58908E9D6F8DA689D318AA7C1E198CA2AD22722C00C03A393C8BFC2C037C33429CEDF0660F5716CBC1A15530ED5A3C368B96973A43F1AB70E8BA75ABBB35C85B15E58B56E5C8196B6E9D3C65A236786B55733B64FD6D4F46672EFB796962A3E07AB74C597961E99B573BD8F6046F89C317CA6D9F4922A222CC0EA11E9823F742937FB0EC1A8B7FC8A588193B2AF4C2DECA3EE9724FD8818A0792445FF5E0B7ADDD3EF2282BF471F5322FE0950D91B9B7688B7D134741B60BA427DAF6F09A57C027BE9D5FF6AF15A6DBB183E86E4C682FCD711472039537425BBC2C07D91503187E5F7B9CE7C576AC0CC799791971C23F82C2519635F9B4E1BEE7941DD602EE778E5A99EF77FF9FCFEDC0CC6F90E1F8E2C09D596237C37EC368A78BE8CA54A7406A5BF0708885967909CE810651BC792BD84B1805E3964F31002B647A88FAFF57E94F56E75E5C866E43E7360928B8E7D8E89CE43F5D84E21A3075E9974ED065C825268994DA5E0ABBAFDC1A6636AEB8856C6703CA917C7DF7B607F7DEECD894E6DC133E1904C73499706EC71D2780726A3019F3975835EB22CD82451522CD11A38B28BD742B2A278B886BFFBAF1354D248DE81CE41E8DC7CDD31264D5374CD6D1E53FB07798A5122E18710B2648ABF174A3C8F31222BEFCA76C3F6D7240483119BE84BDB5B72D6CC812A21E2C3A3AF1C263DD5794A716028943E3491EDD9976C4AD900BA4E5BBE2A531BA3B8AF6BF5B952876DB85A70B5C6EBBDDF82E4FD4E518277CDAA86824F82DADE5F73FC60E81C3035A92CC374274DDD8400C144AD28B2B410E186D2A799A1BBAD5B88B1117BE0721D8FD55BF0235620209AACE1B8B2992DBE94F8238AC7E31C758202C548152AF1E4FF39B070B650A52E25793E6E344E027A94CC0CB98269F8F97DF3
+20220714210501 2 6 100 6143 2 FFB27E2CC8B774D736BFE9ECC0EB33B1BC6D4DEA1E8B360AD96E83A7213A91CCC112624B99480D8B7E7C3B6A70A96B7F267C4FE080158429ECB77525C930D5C61BFC7858FF4D571FE7C533CC24A8B1188EF52DD31B0910207C6B5166A9A097F1D12932EBE47B9B876F2FE0F9344AD4B4BA45B0BBB58908E9D6F8DA689D318AA7C1E198CA2AD22722C00C03A393C8BFC2C037C33429CEDF0660F5716CBC1A15530ED5A3C368B96973A43F1AB70E8BA75ABBB35C85B15E58B56E5C8196B6E9D3C65A236786B55733B64FD6D4F46672EFB796962A3E07AB74C597961E99B573BD8F6046F89C317CA6D9F4922A222CC0EA11E9823F742937FB0EC1A8B7FC8A588193B2AF4C2DECA3EE9724FD8818A0792445FF5E0B7ADDD3EF2282BF471F5322FE0950D91B9B7688B7D134741B60BA427DAF6F09A57C027BE9D5FF6AF15A6DBB183E86E4C682FCD711472039537425BBC2C07D91503187E5F7B9CE7C576AC0CC799791971C23F82C2519635F9B4E1BEE7941DD602EE778E5A99EF77FF9FCFEDC0CC6F90E1F8E2C09D596237C37EC368A78BE8CA54A7406A5BF0708885967909CE810651BC792BD84B1805E3964F31002B647A88FAFF57E94F56E75E5C866E43E7360928B8E7D8E89CE43F5D84E21A3075E9974ED065C825268994DA5E0ABBAFDC1A6636AEB8856C6703CA917C7DF7B607F7DEECD894E6DC133E1904C73499706EC71D2780726A3019F3975835EB22CD82451522CD11A38B28BD742B2A278B886BFFBAF1354D248DE81CE41E8DC7CDD31264D5374CD6D1E53FB07798A5122E18710B2648ABF174A3C8F31222BEFCA76C3F6D7240483119BE84BDB5B72D6CC812A21E2C3A3AF1C263DD5794A716028943E3491EDD9976C4AD900BA4E5BBE2A531BA3B8AF6BF5B952876DB85A70B5C6EBBDDF82E4FD4E518277CDAA86824F82DADE5F73FC60E81C3035A92CC374274DDD8400C144AD28B2B410E186D2A799A1BBAD5B88B1117BE0721D8FD55BF0235620209AACE1B8B2992DBE94F8238AC7E31C758202C548152AF1E4FF39B070B650A52E25793E6E344E027A94CC0CB98269FC032A43
+20220714210527 2 6 100 6143 5 FFB27E2CC8B774D736BFE9ECC0EB33B1BC6D4DEA1E8B360AD96E83A7213A91CCC112624B99480D8B7E7C3B6A70A96B7F267C4FE080158429ECB77525C930D5C61BFC7858FF4D571FE7C533CC24A8B1188EF52DD31B0910207C6B5166A9A097F1D12932EBE47B9B876F2FE0F9344AD4B4BA45B0BBB58908E9D6F8DA689D318AA7C1E198CA2AD22722C00C03A393C8BFC2C037C33429CEDF0660F5716CBC1A15530ED5A3C368B96973A43F1AB70E8BA75ABBB35C85B15E58B56E5C8196B6E9D3C65A236786B55733B64FD6D4F46672EFB796962A3E07AB74C597961E99B573BD8F6046F89C317CA6D9F4922A222CC0EA11E9823F742937FB0EC1A8B7FC8A588193B2AF4C2DECA3EE9724FD8818A0792445FF5E0B7ADDD3EF2282BF471F5322FE0950D91B9B7688B7D134741B60BA427DAF6F09A57C027BE9D5FF6AF15A6DBB183E86E4C682FCD711472039537425BBC2C07D91503187E5F7B9CE7C576AC0CC799791971C23F82C2519635F9B4E1BEE7941DD602EE778E5A99EF77FF9FCFEDC0CC6F90E1F8E2C09D596237C37EC368A78BE8CA54A7406A5BF0708885967909CE810651BC792BD84B1805E3964F31002B647A88FAFF57E94F56E75E5C866E43E7360928B8E7D8E89CE43F5D84E21A3075E9974ED065C825268994DA5E0ABBAFDC1A6636AEB8856C6703CA917C7DF7B607F7DEECD894E6DC133E1904C73499706EC71D2780726A3019F3975835EB22CD82451522CD11A38B28BD742B2A278B886BFFBAF1354D248DE81CE41E8DC7CDD31264D5374CD6D1E53FB07798A5122E18710B2648ABF174A3C8F31222BEFCA76C3F6D7240483119BE84BDB5B72D6CC812A21E2C3A3AF1C263DD5794A716028943E3491EDD9976C4AD900BA4E5BBE2A531BA3B8AF6BF5B952876DB85A70B5C6EBBDDF82E4FD4E518277CDAA86824F82DADE5F73FC60E81C3035A92CC374274DDD8400C144AD28B2B410E186D2A799A1BBAD5B88B1117BE0721D8FD55BF0235620209AACE1B8B2992DBE94F8238AC7E31C758202C548152AF1E4FF39B070B650A52E25793E6E344E027A94CC0CB98269FC1045CF
+20220714214423 2 6 100 6143 2 FFB27E2CC8B774D736BFE9ECC0EB33B1BC6D4DEA1E8B360AD96E83A7213A91CCC112624B99480D8B7E7C3B6A70A96B7F267C4FE080158429ECB77525C930D5C61BFC7858FF4D571FE7C533CC24A8B1188EF52DD31B0910207C6B5166A9A097F1D12932EBE47B9B876F2FE0F9344AD4B4BA45B0BBB58908E9D6F8DA689D318AA7C1E198CA2AD22722C00C03A393C8BFC2C037C33429CEDF0660F5716CBC1A15530ED5A3C368B96973A43F1AB70E8BA75ABBB35C85B15E58B56E5C8196B6E9D3C65A236786B55733B64FD6D4F46672EFB796962A3E07AB74C597961E99B573BD8F6046F89C317CA6D9F4922A222CC0EA11E9823F742937FB0EC1A8B7FC8A588193B2AF4C2DECA3EE9724FD8818A0792445FF5E0B7ADDD3EF2282BF471F5322FE0950D91B9B7688B7D134741B60BA427DAF6F09A57C027BE9D5FF6AF15A6DBB183E86E4C682FCD711472039537425BBC2C07D91503187E5F7B9CE7C576AC0CC799791971C23F82C2519635F9B4E1BEE7941DD602EE778E5A99EF77FF9FCFEDC0CC6F90E1F8E2C09D596237C37EC368A78BE8CA54A7406A5BF0708885967909CE810651BC792BD84B1805E3964F31002B647A88FAFF57E94F56E75E5C866E43E7360928B8E7D8E89CE43F5D84E21A3075E9974ED065C825268994DA5E0ABBAFDC1A6636AEB8856C6703CA917C7DF7B607F7DEECD894E6DC133E1904C73499706EC71D2780726A3019F3975835EB22CD82451522CD11A38B28BD742B2A278B886BFFBAF1354D248DE81CE41E8DC7CDD31264D5374CD6D1E53FB07798A5122E18710B2648ABF174A3C8F31222BEFCA76C3F6D7240483119BE84BDB5B72D6CC812A21E2C3A3AF1C263DD5794A716028943E3491EDD9976C4AD900BA4E5BBE2A531BA3B8AF6BF5B952876DB85A70B5C6EBBDDF82E4FD4E518277CDAA86824F82DADE5F73FC60E81C3035A92CC374274DDD8400C144AD28B2B410E186D2A799A1BBAD5B88B1117BE0721D8FD55BF0235620209AACE1B8B2992DBE94F8238AC7E31C758202C548152AF1E4FF39B070B650A52E25793E6E344E027A94CC0CB9826A014F6733
+20220714214717 2 6 100 6143 2 FFB27E2CC8B774D736BFE9ECC0EB33B1BC6D4DEA1E8B360AD96E83A7213A91CCC112624B99480D8B7E7C3B6A70A96B7F267C4FE080158429ECB77525C930D5C61BFC7858FF4D571FE7C533CC24A8B1188EF52DD31B0910207C6B5166A9A097F1D12932EBE47B9B876F2FE0F9344AD4B4BA45B0BBB58908E9D6F8DA689D318AA7C1E198CA2AD22722C00C03A393C8BFC2C037C33429CEDF0660F5716CBC1A15530ED5A3C368B96973A43F1AB70E8BA75ABBB35C85B15E58B56E5C8196B6E9D3C65A236786B55733B64FD6D4F46672EFB796962A3E07AB74C597961E99B573BD8F6046F89C317CA6D9F4922A222CC0EA11E9823F742937FB0EC1A8B7FC8A588193B2AF4C2DECA3EE9724FD8818A0792445FF5E0B7ADDD3EF2282BF471F5322FE0950D91B9B7688B7D134741B60BA427DAF6F09A57C027BE9D5FF6AF15A6DBB183E86E4C682FCD711472039537425BBC2C07D91503187E5F7B9CE7C576AC0CC799791971C23F82C2519635F9B4E1BEE7941DD602EE778E5A99EF77FF9FCFEDC0CC6F90E1F8E2C09D596237C37EC368A78BE8CA54A7406A5BF0708885967909CE810651BC792BD84B1805E3964F31002B647A88FAFF57E94F56E75E5C866E43E7360928B8E7D8E89CE43F5D84E21A3075E9974ED065C825268994DA5E0ABBAFDC1A6636AEB8856C6703CA917C7DF7B607F7DEECD894E6DC133E1904C73499706EC71D2780726A3019F3975835EB22CD82451522CD11A38B28BD742B2A278B886BFFBAF1354D248DE81CE41E8DC7CDD31264D5374CD6D1E53FB07798A5122E18710B2648ABF174A3C8F31222BEFCA76C3F6D7240483119BE84BDB5B72D6CC812A21E2C3A3AF1C263DD5794A716028943E3491EDD9976C4AD900BA4E5BBE2A531BA3B8AF6BF5B952876DB85A70B5C6EBBDDF82E4FD4E518277CDAA86824F82DADE5F73FC60E81C3035A92CC374274DDD8400C144AD28B2B410E186D2A799A1BBAD5B88B1117BE0721D8FD55BF0235620209AACE1B8B2992DBE94F8238AC7E31C758202C548152AF1E4FF39B070B650A52E25793E6E344E027A94CC0CB9826A01B72D0B
+20220714215814 2 6 100 6143 5 FFB27E2CC8B774D736BFE9ECC0EB33B1BC6D4DEA1E8B360AD96E83A7213A91CCC112624B99480D8B7E7C3B6A70A96B7F267C4FE080158429ECB77525C930D5C61BFC7858FF4D571FE7C533CC24A8B1188EF52DD31B0910207C6B5166A9A097F1D12932EBE47B9B876F2FE0F9344AD4B4BA45B0BBB58908E9D6F8DA689D318AA7C1E198CA2AD22722C00C03A393C8BFC2C037C33429CEDF0660F5716CBC1A15530ED5A3C368B96973A43F1AB70E8BA75ABBB35C85B15E58B56E5C8196B6E9D3C65A236786B55733B64FD6D4F46672EFB796962A3E07AB74C597961E99B573BD8F6046F89C317CA6D9F4922A222CC0EA11E9823F742937FB0EC1A8B7FC8A588193B2AF4C2DECA3EE9724FD8818A0792445FF5E0B7ADDD3EF2282BF471F5322FE0950D91B9B7688B7D134741B60BA427DAF6F09A57C027BE9D5FF6AF15A6DBB183E86E4C682FCD711472039537425BBC2C07D91503187E5F7B9CE7C576AC0CC799791971C23F82C2519635F9B4E1BEE7941DD602EE778E5A99EF77FF9FCFEDC0CC6F90E1F8E2C09D596237C37EC368A78BE8CA54A7406A5BF0708885967909CE810651BC792BD84B1805E3964F31002B647A88FAFF57E94F56E75E5C866E43E7360928B8E7D8E89CE43F5D84E21A3075E9974ED065C825268994DA5E0ABBAFDC1A6636AEB8856C6703CA917C7DF7B607F7DEECD894E6DC133E1904C73499706EC71D2780726A3019F3975835EB22CD82451522CD11A38B28BD742B2A278B886BFFBAF1354D248DE81CE41E8DC7CDD31264D5374CD6D1E53FB07798A5122E18710B2648ABF174A3C8F31222BEFCA76C3F6D7240483119BE84BDB5B72D6CC812A21E2C3A3AF1C263DD5794A716028943E3491EDD9976C4AD900BA4E5BBE2A531BA3B8AF6BF5B952876DB85A70B5C6EBBDDF82E4FD4E518277CDAA86824F82DADE5F73FC60E81C3035A92CC374274DDD8400C144AD28B2B410E186D2A799A1BBAD5B88B1117BE0721D8FD55BF0235620209AACE1B8B2992DBE94F8238AC7E31C758202C548152AF1E4FF39B070B650A52E25793E6E344E027A94CC0CB9826A0332253F
+20220714222646 2 6 100 6143 5 FFB27E2CC8B774D736BFE9ECC0EB33B1BC6D4DEA1E8B360AD96E83A7213A91CCC112624B99480D8B7E7C3B6A70A96B7F267C4FE080158429ECB77525C930D5C61BFC7858FF4D571FE7C533CC24A8B1188EF52DD31B0910207C6B5166A9A097F1D12932EBE47B9B876F2FE0F9344AD4B4BA45B0BBB58908E9D6F8DA689D318AA7C1E198CA2AD22722C00C03A393C8BFC2C037C33429CEDF0660F5716CBC1A15530ED5A3C368B96973A43F1AB70E8BA75ABBB35C85B15E58B56E5C8196B6E9D3C65A236786B55733B64FD6D4F46672EFB796962A3E07AB74C597961E99B573BD8F6046F89C317CA6D9F4922A222CC0EA11E9823F742937FB0EC1A8B7FC8A588193B2AF4C2DECA3EE9724FD8818A0792445FF5E0B7ADDD3EF2282BF471F5322FE0950D91B9B7688B7D134741B60BA427DAF6F09A57C027BE9D5FF6AF15A6DBB183E86E4C682FCD711472039537425BBC2C07D91503187E5F7B9CE7C576AC0CC799791971C23F82C2519635F9B4E1BEE7941DD602EE778E5A99EF77FF9FCFEDC0CC6F90E1F8E2C09D596237C37EC368A78BE8CA54A7406A5BF0708885967909CE810651BC792BD84B1805E3964F31002B647A88FAFF57E94F56E75E5C866E43E7360928B8E7D8E89CE43F5D84E21A3075E9974ED065C825268994DA5E0ABBAFDC1A6636AEB8856C6703CA917C7DF7B607F7DEECD894E6DC133E1904C73499706EC71D2780726A3019F3975835EB22CD82451522CD11A38B28BD742B2A278B886BFFBAF1354D248DE81CE41E8DC7CDD31264D5374CD6D1E53FB07798A5122E18710B2648ABF174A3C8F31222BEFCA76C3F6D7240483119BE84BDB5B72D6CC812A21E2C3A3AF1C263DD5794A716028943E3491EDD9976C4AD900BA4E5BBE2A531BA3B8AF6BF5B952876DB85A70B5C6EBBDDF82E4FD4E518277CDAA86824F82DADE5F73FC60E81C3035A92CC374274DDD8400C144AD28B2B410E186D2A799A1BBAD5B88B1117BE0721D8FD55BF0235620209AACE1B8B2992DBE94F8238AC7E31C758202C548152AF1E4FF39B070B650A52E25793E6E344E027A94CC0CB9826A07072DC7
+20220714222943 2 6 100 6143 2 FFB27E2CC8B774D736BFE9ECC0EB33B1BC6D4DEA1E8B360AD96E83A7213A91CCC112624B99480D8B7E7C3B6A70A96B7F267C4FE080158429ECB77525C930D5C61BFC7858FF4D571FE7C533CC24A8B1188EF52DD31B0910207C6B5166A9A097F1D12932EBE47B9B876F2FE0F9344AD4B4BA45B0BBB58908E9D6F8DA689D318AA7C1E198CA2AD22722C00C03A393C8BFC2C037C33429CEDF0660F5716CBC1A15530ED5A3C368B96973A43F1AB70E8BA75ABBB35C85B15E58B56E5C8196B6E9D3C65A236786B55733B64FD6D4F46672EFB796962A3E07AB74C597961E99B573BD8F6046F89C317CA6D9F4922A222CC0EA11E9823F742937FB0EC1A8B7FC8A588193B2AF4C2DECA3EE9724FD8818A0792445FF5E0B7ADDD3EF2282BF471F5322FE0950D91B9B7688B7D134741B60BA427DAF6F09A57C027BE9D5FF6AF15A6DBB183E86E4C682FCD711472039537425BBC2C07D91503187E5F7B9CE7C576AC0CC799791971C23F82C2519635F9B4E1BEE7941DD602EE778E5A99EF77FF9FCFEDC0CC6F90E1F8E2C09D596237C37EC368A78BE8CA54A7406A5BF0708885967909CE810651BC792BD84B1805E3964F31002B647A88FAFF57E94F56E75E5C866E43E7360928B8E7D8E89CE43F5D84E21A3075E9974ED065C825268994DA5E0ABBAFDC1A6636AEB8856C6703CA917C7DF7B607F7DEECD894E6DC133E1904C73499706EC71D2780726A3019F3975835EB22CD82451522CD11A38B28BD742B2A278B886BFFBAF1354D248DE81CE41E8DC7CDD31264D5374CD6D1E53FB07798A5122E18710B2648ABF174A3C8F31222BEFCA76C3F6D7240483119BE84BDB5B72D6CC812A21E2C3A3AF1C263DD5794A716028943E3491EDD9976C4AD900BA4E5BBE2A531BA3B8AF6BF5B952876DB85A70B5C6EBBDDF82E4FD4E518277CDAA86824F82DADE5F73FC60E81C3035A92CC374274DDD8400C144AD28B2B410E186D2A799A1BBAD5B88B1117BE0721D8FD55BF0235620209AACE1B8B2992DBE94F8238AC7E31C758202C548152AF1E4FF39B070B650A52E25793E6E344E027A94CC0CB9826A076F0173
+20220714222954 2 6 100 6143 2 FFB27E2CC8B774D736BFE9ECC0EB33B1BC6D4DEA1E8B360AD96E83A7213A91CCC112624B99480D8B7E7C3B6A70A96B7F267C4FE080158429ECB77525C930D5C61BFC7858FF4D571FE7C533CC24A8B1188EF52DD31B0910207C6B5166A9A097F1D12932EBE47B9B876F2FE0F9344AD4B4BA45B0BBB58908E9D6F8DA689D318AA7C1E198CA2AD22722C00C03A393C8BFC2C037C33429CEDF0660F5716CBC1A15530ED5A3C368B96973A43F1AB70E8BA75ABBB35C85B15E58B56E5C8196B6E9D3C65A236786B55733B64FD6D4F46672EFB796962A3E07AB74C597961E99B573BD8F6046F89C317CA6D9F4922A222CC0EA11E9823F742937FB0EC1A8B7FC8A588193B2AF4C2DECA3EE9724FD8818A0792445FF5E0B7ADDD3EF2282BF471F5322FE0950D91B9B7688B7D134741B60BA427DAF6F09A57C027BE9D5FF6AF15A6DBB183E86E4C682FCD711472039537425BBC2C07D91503187E5F7B9CE7C576AC0CC799791971C23F82C2519635F9B4E1BEE7941DD602EE778E5A99EF77FF9FCFEDC0CC6F90E1F8E2C09D596237C37EC368A78BE8CA54A7406A5BF0708885967909CE810651BC792BD84B1805E3964F31002B647A88FAFF57E94F56E75E5C866E43E7360928B8E7D8E89CE43F5D84E21A3075E9974ED065C825268994DA5E0ABBAFDC1A6636AEB8856C6703CA917C7DF7B607F7DEECD894E6DC133E1904C73499706EC71D2780726A3019F3975835EB22CD82451522CD11A38B28BD742B2A278B886BFFBAF1354D248DE81CE41E8DC7CDD31264D5374CD6D1E53FB07798A5122E18710B2648ABF174A3C8F31222BEFCA76C3F6D7240483119BE84BDB5B72D6CC812A21E2C3A3AF1C263DD5794A716028943E3491EDD9976C4AD900BA4E5BBE2A531BA3B8AF6BF5B952876DB85A70B5C6EBBDDF82E4FD4E518277CDAA86824F82DADE5F73FC60E81C3035A92CC374274DDD8400C144AD28B2B410E186D2A799A1BBAD5B88B1117BE0721D8FD55BF0235620209AACE1B8B2992DBE94F8238AC7E31C758202C548152AF1E4FF39B070B650A52E25793E6E344E027A94CC0CB9826A07745AAB
+20220714223227 2 6 100 6143 2 FFB27E2CC8B774D736BFE9ECC0EB33B1BC6D4DEA1E8B360AD96E83A7213A91CCC112624B99480D8B7E7C3B6A70A96B7F267C4FE080158429ECB77525C930D5C61BFC7858FF4D571FE7C533CC24A8B1188EF52DD31B0910207C6B5166A9A097F1D12932EBE47B9B876F2FE0F9344AD4B4BA45B0BBB58908E9D6F8DA689D318AA7C1E198CA2AD22722C00C03A393C8BFC2C037C33429CEDF0660F5716CBC1A15530ED5A3C368B96973A43F1AB70E8BA75ABBB35C85B15E58B56E5C8196B6E9D3C65A236786B55733B64FD6D4F46672EFB796962A3E07AB74C597961E99B573BD8F6046F89C317CA6D9F4922A222CC0EA11E9823F742937FB0EC1A8B7FC8A588193B2AF4C2DECA3EE9724FD8818A0792445FF5E0B7ADDD3EF2282BF471F5322FE0950D91B9B7688B7D134741B60BA427DAF6F09A57C027BE9D5FF6AF15A6DBB183E86E4C682FCD711472039537425BBC2C07D91503187E5F7B9CE7C576AC0CC799791971C23F82C2519635F9B4E1BEE7941DD602EE778E5A99EF77FF9FCFEDC0CC6F90E1F8E2C09D596237C37EC368A78BE8CA54A7406A5BF0708885967909CE810651BC792BD84B1805E3964F31002B647A88FAFF57E94F56E75E5C866E43E7360928B8E7D8E89CE43F5D84E21A3075E9974ED065C825268994DA5E0ABBAFDC1A6636AEB8856C6703CA917C7DF7B607F7DEECD894E6DC133E1904C73499706EC71D2780726A3019F3975835EB22CD82451522CD11A38B28BD742B2A278B886BFFBAF1354D248DE81CE41E8DC7CDD31264D5374CD6D1E53FB07798A5122E18710B2648ABF174A3C8F31222BEFCA76C3F6D7240483119BE84BDB5B72D6CC812A21E2C3A3AF1C263DD5794A716028943E3491EDD9976C4AD900BA4E5BBE2A531BA3B8AF6BF5B952876DB85A70B5C6EBBDDF82E4FD4E518277CDAA86824F82DADE5F73FC60E81C3035A92CC374274DDD8400C144AD28B2B410E186D2A799A1BBAD5B88B1117BE0721D8FD55BF0235620209AACE1B8B2992DBE94F8238AC7E31C758202C548152AF1E4FF39B070B650A52E25793E6E344E027A94CC0CB9826A07CC7BB3
+20220714224745 2 6 100 6143 2 FFB27E2CC8B774D736BFE9ECC0EB33B1BC6D4DEA1E8B360AD96E83A7213A91CCC112624B99480D8B7E7C3B6A70A96B7F267C4FE080158429ECB77525C930D5C61BFC7858FF4D571FE7C533CC24A8B1188EF52DD31B0910207C6B5166A9A097F1D12932EBE47B9B876F2FE0F9344AD4B4BA45B0BBB58908E9D6F8DA689D318AA7C1E198CA2AD22722C00C03A393C8BFC2C037C33429CEDF0660F5716CBC1A15530ED5A3C368B96973A43F1AB70E8BA75ABBB35C85B15E58B56E5C8196B6E9D3C65A236786B55733B64FD6D4F46672EFB796962A3E07AB74C597961E99B573BD8F6046F89C317CA6D9F4922A222CC0EA11E9823F742937FB0EC1A8B7FC8A588193B2AF4C2DECA3EE9724FD8818A0792445FF5E0B7ADDD3EF2282BF471F5322FE0950D91B9B7688B7D134741B60BA427DAF6F09A57C027BE9D5FF6AF15A6DBB183E86E4C682FCD711472039537425BBC2C07D91503187E5F7B9CE7C576AC0CC799791971C23F82C2519635F9B4E1BEE7941DD602EE778E5A99EF77FF9FCFEDC0CC6F90E1F8E2C09D596237C37EC368A78BE8CA54A7406A5BF0708885967909CE810651BC792BD84B1805E3964F31002B647A88FAFF57E94F56E75E5C866E43E7360928B8E7D8E89CE43F5D84E21A3075E9974ED065C825268994DA5E0ABBAFDC1A6636AEB8856C6703CA917C7DF7B607F7DEECD894E6DC133E1904C73499706EC71D2780726A3019F3975835EB22CD82451522CD11A38B28BD742B2A278B886BFFBAF1354D248DE81CE41E8DC7CDD31264D5374CD6D1E53FB07798A5122E18710B2648ABF174A3C8F31222BEFCA76C3F6D7240483119BE84BDB5B72D6CC812A21E2C3A3AF1C263DD5794A716028943E3491EDD9976C4AD900BA4E5BBE2A531BA3B8AF6BF5B952876DB85A70B5C6EBBDDF82E4FD4E518277CDAA86824F82DADE5F73FC60E81C3035A92CC374274DDD8400C144AD28B2B410E186D2A799A1BBAD5B88B1117BE0721D8FD55BF0235620209AACE1B8B2992DBE94F8238AC7E31C758202C548152AF1E4FF39B070B650A52E25793E6E344E027A94CC0CB9826A09DF82A3
+20220715000506 2 6 100 6143 2 E258E7BF12F3DDA792F3E7480A3563579067E7CB60FB18E010DAC18E1AD5671C1E0B1CED8BCF199C52405B70A169CCDAE2B112117B67D54C6F892B1822DC08FACB88D9C1E424709E41932AB799392DA34E0D560B03C459B2208DDB99ECA51883F8BADB33EF313D908ADB72802512653760C2AE00320555606FC09B797CFF13219A102668C5DCF4248DEEB9B7C779A2AE009842942DAE4032491A233698B8BEC159904F8AC25D1E90454A45F786C433C843224D755DE28AC1CAD4E9736C6D4180BA705B607842915F257BBC730C733882911A8A51738DF20BA48EF64240646041BA8C6F3FDEDE140EC3AA3EBD710F5E12A3F5C50C2784FA32CB6E24CDFC621602E67C80DEB8347146AF1983C201E2B4A868B2DD61D079D41AD874F63E22B42101130C646F0217A74192C47B8A732F69DDE9C05ED4E2B7E3CCA501D687F1FAED478D3910BF3689DB3865574926D16FD3DED6561FDD8BA46FDE6121312E798A0CA83993CEEFECC033CB73442A2C954E8BD1C752BAAD8D074F6F6829E515446A8BA834CF7D08B3170721C1388BD55BC802011B9863B91C9B4DB305D881A503B918428569418BC0B2ECC7FC3F9F34B8F66C5EA842B4AB441AFD29FFE658AFE94BE0E9FD2E9743778DC58CBD1DD8DC7220A9D04944B032C6FC0DFA46BEE2D47AA5DC569F0945F72E7751EC0DD7F218CED8AEF74AA9A8864147C3A89B5C6217888C86C51C83FB77FB91B2F7C6BC0D2624192F33FA8891D897593FD164F4822077B028627CB568412A4A2E9931C24BAF6F01A5A7A85EC446A0E67002F55367249F74087A7015D2580009DA08CA0789265B4EE073185A0892AEB1BEEDD00265AD397F87AB4ED831E3702A562627584AA7A195CF453F70D56CF201F73D6AC01E934A32432464337A6599C97F7B61F04E198AC75AA77BD9FAD027B1C82FBB1E78DC641859D3CA7C7EF28F1A612AE1F41B9B360C3A96367D0F3B4BBB9E0F5EDFDFDCD2731510DFB728BD4688B62988D79CE39513524935E2A43E68EB7210093111D92C3683A7FAD835D2B2C86A8C173AA67CCFD59934234D5EB190F8AB93E9C1E0DB9F7FAC33
+20220715000641 2 6 100 6143 5 E258E7BF12F3DDA792F3E7480A3563579067E7CB60FB18E010DAC18E1AD5671C1E0B1CED8BCF199C52405B70A169CCDAE2B112117B67D54C6F892B1822DC08FACB88D9C1E424709E41932AB799392DA34E0D560B03C459B2208DDB99ECA51883F8BADB33EF313D908ADB72802512653760C2AE00320555606FC09B797CFF13219A102668C5DCF4248DEEB9B7C779A2AE009842942DAE4032491A233698B8BEC159904F8AC25D1E90454A45F786C433C843224D755DE28AC1CAD4E9736C6D4180BA705B607842915F257BBC730C733882911A8A51738DF20BA48EF64240646041BA8C6F3FDEDE140EC3AA3EBD710F5E12A3F5C50C2784FA32CB6E24CDFC621602E67C80DEB8347146AF1983C201E2B4A868B2DD61D079D41AD874F63E22B42101130C646F0217A74192C47B8A732F69DDE9C05ED4E2B7E3CCA501D687F1FAED478D3910BF3689DB3865574926D16FD3DED6561FDD8BA46FDE6121312E798A0CA83993CEEFECC033CB73442A2C954E8BD1C752BAAD8D074F6F6829E515446A8BA834CF7D08B3170721C1388BD55BC802011B9863B91C9B4DB305D881A503B918428569418BC0B2ECC7FC3F9F34B8F66C5EA842B4AB441AFD29FFE658AFE94BE0E9FD2E9743778DC58CBD1DD8DC7220A9D04944B032C6FC0DFA46BEE2D47AA5DC569F0945F72E7751EC0DD7F218CED8AEF74AA9A8864147C3A89B5C6217888C86C51C83FB77FB91B2F7C6BC0D2624192F33FA8891D897593FD164F4822077B028627CB568412A4A2E9931C24BAF6F01A5A7A85EC446A0E67002F55367249F74087A7015D2580009DA08CA0789265B4EE073185A0892AEB1BEEDD00265AD397F87AB4ED831E3702A562627584AA7A195CF453F70D56CF201F73D6AC01E934A32432464337A6599C97F7B61F04E198AC75AA77BD9FAD027B1C82FBB1E78DC641859D3CA7C7EF28F1A612AE1F41B9B360C3A96367D0F3B4BBB9E0F5EDFDFDCD2731510DFB728BD4688B62988D79CE39513524935E2A43E68EB7210093111D92C3683A7FAD835D2B2C86A8C173AA67CCFD59934234D5EB190F8AB93E9C1E0DB9FB84627
+20220715001211 2 6 100 6143 2 E258E7BF12F3DDA792F3E7480A3563579067E7CB60FB18E010DAC18E1AD5671C1E0B1CED8BCF199C52405B70A169CCDAE2B112117B67D54C6F892B1822DC08FACB88D9C1E424709E41932AB799392DA34E0D560B03C459B2208DDB99ECA51883F8BADB33EF313D908ADB72802512653760C2AE00320555606FC09B797CFF13219A102668C5DCF4248DEEB9B7C779A2AE009842942DAE4032491A233698B8BEC159904F8AC25D1E90454A45F786C433C843224D755DE28AC1CAD4E9736C6D4180BA705B607842915F257BBC730C733882911A8A51738DF20BA48EF64240646041BA8C6F3FDEDE140EC3AA3EBD710F5E12A3F5C50C2784FA32CB6E24CDFC621602E67C80DEB8347146AF1983C201E2B4A868B2DD61D079D41AD874F63E22B42101130C646F0217A74192C47B8A732F69DDE9C05ED4E2B7E3CCA501D687F1FAED478D3910BF3689DB3865574926D16FD3DED6561FDD8BA46FDE6121312E798A0CA83993CEEFECC033CB73442A2C954E8BD1C752BAAD8D074F6F6829E515446A8BA834CF7D08B3170721C1388BD55BC802011B9863B91C9B4DB305D881A503B918428569418BC0B2ECC7FC3F9F34B8F66C5EA842B4AB441AFD29FFE658AFE94BE0E9FD2E9743778DC58CBD1DD8DC7220A9D04944B032C6FC0DFA46BEE2D47AA5DC569F0945F72E7751EC0DD7F218CED8AEF74AA9A8864147C3A89B5C6217888C86C51C83FB77FB91B2F7C6BC0D2624192F33FA8891D897593FD164F4822077B028627CB568412A4A2E9931C24BAF6F01A5A7A85EC446A0E67002F55367249F74087A7015D2580009DA08CA0789265B4EE073185A0892AEB1BEEDD00265AD397F87AB4ED831E3702A562627584AA7A195CF453F70D56CF201F73D6AC01E934A32432464337A6599C97F7B61F04E198AC75AA77BD9FAD027B1C82FBB1E78DC641859D3CA7C7EF28F1A612AE1F41B9B360C3A96367D0F3B4BBB9E0F5EDFDFDCD2731510DFB728BD4688B62988D79CE39513524935E2A43E68EB7210093111D92C3683A7FAD835D2B2C86A8C173AA67CCFD59934234D5EB190F8AB93E9C1E0DBA0756D33
+20220715005345 2 6 100 6143 2 E258E7BF12F3DDA792F3E7480A3563579067E7CB60FB18E010DAC18E1AD5671C1E0B1CED8BCF199C52405B70A169CCDAE2B112117B67D54C6F892B1822DC08FACB88D9C1E424709E41932AB799392DA34E0D560B03C459B2208DDB99ECA51883F8BADB33EF313D908ADB72802512653760C2AE00320555606FC09B797CFF13219A102668C5DCF4248DEEB9B7C779A2AE009842942DAE4032491A233698B8BEC159904F8AC25D1E90454A45F786C433C843224D755DE28AC1CAD4E9736C6D4180BA705B607842915F257BBC730C733882911A8A51738DF20BA48EF64240646041BA8C6F3FDEDE140EC3AA3EBD710F5E12A3F5C50C2784FA32CB6E24CDFC621602E67C80DEB8347146AF1983C201E2B4A868B2DD61D079D41AD874F63E22B42101130C646F0217A74192C47B8A732F69DDE9C05ED4E2B7E3CCA501D687F1FAED478D3910BF3689DB3865574926D16FD3DED6561FDD8BA46FDE6121312E798A0CA83993CEEFECC033CB73442A2C954E8BD1C752BAAD8D074F6F6829E515446A8BA834CF7D08B3170721C1388BD55BC802011B9863B91C9B4DB305D881A503B918428569418BC0B2ECC7FC3F9F34B8F66C5EA842B4AB441AFD29FFE658AFE94BE0E9FD2E9743778DC58CBD1DD8DC7220A9D04944B032C6FC0DFA46BEE2D47AA5DC569F0945F72E7751EC0DD7F218CED8AEF74AA9A8864147C3A89B5C6217888C86C51C83FB77FB91B2F7C6BC0D2624192F33FA8891D897593FD164F4822077B028627CB568412A4A2E9931C24BAF6F01A5A7A85EC446A0E67002F55367249F74087A7015D2580009DA08CA0789265B4EE073185A0892AEB1BEEDD00265AD397F87AB4ED831E3702A562627584AA7A195CF453F70D56CF201F73D6AC01E934A32432464337A6599C97F7B61F04E198AC75AA77BD9FAD027B1C82FBB1E78DC641859D3CA7C7EF28F1A612AE1F41B9B360C3A96367D0F3B4BBB9E0F5EDFDFDCD2731510DFB728BD4688B62988D79CE39513524935E2A43E68EB7210093111D92C3683A7FAD835D2B2C86A8C173AA67CCFD59934234D5EB190F8AB93E9C1E0DBA6234223
+20220715011011 2 6 100 6143 5 E258E7BF12F3DDA792F3E7480A3563579067E7CB60FB18E010DAC18E1AD5671C1E0B1CED8BCF199C52405B70A169CCDAE2B112117B67D54C6F892B1822DC08FACB88D9C1E424709E41932AB799392DA34E0D560B03C459B2208DDB99ECA51883F8BADB33EF313D908ADB72802512653760C2AE00320555606FC09B797CFF13219A102668C5DCF4248DEEB9B7C779A2AE009842942DAE4032491A233698B8BEC159904F8AC25D1E90454A45F786C433C843224D755DE28AC1CAD4E9736C6D4180BA705B607842915F257BBC730C733882911A8A51738DF20BA48EF64240646041BA8C6F3FDEDE140EC3AA3EBD710F5E12A3F5C50C2784FA32CB6E24CDFC621602E67C80DEB8347146AF1983C201E2B4A868B2DD61D079D41AD874F63E22B42101130C646F0217A74192C47B8A732F69DDE9C05ED4E2B7E3CCA501D687F1FAED478D3910BF3689DB3865574926D16FD3DED6561FDD8BA46FDE6121312E798A0CA83993CEEFECC033CB73442A2C954E8BD1C752BAAD8D074F6F6829E515446A8BA834CF7D08B3170721C1388BD55BC802011B9863B91C9B4DB305D881A503B918428569418BC0B2ECC7FC3F9F34B8F66C5EA842B4AB441AFD29FFE658AFE94BE0E9FD2E9743778DC58CBD1DD8DC7220A9D04944B032C6FC0DFA46BEE2D47AA5DC569F0945F72E7751EC0DD7F218CED8AEF74AA9A8864147C3A89B5C6217888C86C51C83FB77FB91B2F7C6BC0D2624192F33FA8891D897593FD164F4822077B028627CB568412A4A2E9931C24BAF6F01A5A7A85EC446A0E67002F55367249F74087A7015D2580009DA08CA0789265B4EE073185A0892AEB1BEEDD00265AD397F87AB4ED831E3702A562627584AA7A195CF453F70D56CF201F73D6AC01E934A32432464337A6599C97F7B61F04E198AC75AA77BD9FAD027B1C82FBB1E78DC641859D3CA7C7EF28F1A612AE1F41B9B360C3A96367D0F3B4BBB9E0F5EDFDFDCD2731510DFB728BD4688B62988D79CE39513524935E2A43E68EB7210093111D92C3683A7FAD835D2B2C86A8C173AA67CCFD59934234D5EB190F8AB93E9C1E0DBA85B2A97
+20220715011444 2 6 100 6143 2 E258E7BF12F3DDA792F3E7480A3563579067E7CB60FB18E010DAC18E1AD5671C1E0B1CED8BCF199C52405B70A169CCDAE2B112117B67D54C6F892B1822DC08FACB88D9C1E424709E41932AB799392DA34E0D560B03C459B2208DDB99ECA51883F8BADB33EF313D908ADB72802512653760C2AE00320555606FC09B797CFF13219A102668C5DCF4248DEEB9B7C779A2AE009842942DAE4032491A233698B8BEC159904F8AC25D1E90454A45F786C433C843224D755DE28AC1CAD4E9736C6D4180BA705B607842915F257BBC730C733882911A8A51738DF20BA48EF64240646041BA8C6F3FDEDE140EC3AA3EBD710F5E12A3F5C50C2784FA32CB6E24CDFC621602E67C80DEB8347146AF1983C201E2B4A868B2DD61D079D41AD874F63E22B42101130C646F0217A74192C47B8A732F69DDE9C05ED4E2B7E3CCA501D687F1FAED478D3910BF3689DB3865574926D16FD3DED6561FDD8BA46FDE6121312E798A0CA83993CEEFECC033CB73442A2C954E8BD1C752BAAD8D074F6F6829E515446A8BA834CF7D08B3170721C1388BD55BC802011B9863B91C9B4DB305D881A503B918428569418BC0B2ECC7FC3F9F34B8F66C5EA842B4AB441AFD29FFE658AFE94BE0E9FD2E9743778DC58CBD1DD8DC7220A9D04944B032C6FC0DFA46BEE2D47AA5DC569F0945F72E7751EC0DD7F218CED8AEF74AA9A8864147C3A89B5C6217888C86C51C83FB77FB91B2F7C6BC0D2624192F33FA8891D897593FD164F4822077B028627CB568412A4A2E9931C24BAF6F01A5A7A85EC446A0E67002F55367249F74087A7015D2580009DA08CA0789265B4EE073185A0892AEB1BEEDD00265AD397F87AB4ED831E3702A562627584AA7A195CF453F70D56CF201F73D6AC01E934A32432464337A6599C97F7B61F04E198AC75AA77BD9FAD027B1C82FBB1E78DC641859D3CA7C7EF28F1A612AE1F41B9B360C3A96367D0F3B4BBB9E0F5EDFDFDCD2731510DFB728BD4688B62988D79CE39513524935E2A43E68EB7210093111D92C3683A7FAD835D2B2C86A8C173AA67CCFD59934234D5EB190F8AB93E9C1E0DBA8F9C90B
+20220715011554 2 6 100 6143 2 E258E7BF12F3DDA792F3E7480A3563579067E7CB60FB18E010DAC18E1AD5671C1E0B1CED8BCF199C52405B70A169CCDAE2B112117B67D54C6F892B1822DC08FACB88D9C1E424709E41932AB799392DA34E0D560B03C459B2208DDB99ECA51883F8BADB33EF313D908ADB72802512653760C2AE00320555606FC09B797CFF13219A102668C5DCF4248DEEB9B7C779A2AE009842942DAE4032491A233698B8BEC159904F8AC25D1E90454A45F786C433C843224D755DE28AC1CAD4E9736C6D4180BA705B607842915F257BBC730C733882911A8A51738DF20BA48EF64240646041BA8C6F3FDEDE140EC3AA3EBD710F5E12A3F5C50C2784FA32CB6E24CDFC621602E67C80DEB8347146AF1983C201E2B4A868B2DD61D079D41AD874F63E22B42101130C646F0217A74192C47B8A732F69DDE9C05ED4E2B7E3CCA501D687F1FAED478D3910BF3689DB3865574926D16FD3DED6561FDD8BA46FDE6121312E798A0CA83993CEEFECC033CB73442A2C954E8BD1C752BAAD8D074F6F6829E515446A8BA834CF7D08B3170721C1388BD55BC802011B9863B91C9B4DB305D881A503B918428569418BC0B2ECC7FC3F9F34B8F66C5EA842B4AB441AFD29FFE658AFE94BE0E9FD2E9743778DC58CBD1DD8DC7220A9D04944B032C6FC0DFA46BEE2D47AA5DC569F0945F72E7751EC0DD7F218CED8AEF74AA9A8864147C3A89B5C6217888C86C51C83FB77FB91B2F7C6BC0D2624192F33FA8891D897593FD164F4822077B028627CB568412A4A2E9931C24BAF6F01A5A7A85EC446A0E67002F55367249F74087A7015D2580009DA08CA0789265B4EE073185A0892AEB1BEEDD00265AD397F87AB4ED831E3702A562627584AA7A195CF453F70D56CF201F73D6AC01E934A32432464337A6599C97F7B61F04E198AC75AA77BD9FAD027B1C82FBB1E78DC641859D3CA7C7EF28F1A612AE1F41B9B360C3A96367D0F3B4BBB9E0F5EDFDFDCD2731510DFB728BD4688B62988D79CE39513524935E2A43E68EB7210093111D92C3683A7FAD835D2B2C86A8C173AA67CCFD59934234D5EB190F8AB93E9C1E0DBA9233533
+20220715013220 2 6 100 6143 2 E258E7BF12F3DDA792F3E7480A3563579067E7CB60FB18E010DAC18E1AD5671C1E0B1CED8BCF199C52405B70A169CCDAE2B112117B67D54C6F892B1822DC08FACB88D9C1E424709E41932AB799392DA34E0D560B03C459B2208DDB99ECA51883F8BADB33EF313D908ADB72802512653760C2AE00320555606FC09B797CFF13219A102668C5DCF4248DEEB9B7C779A2AE009842942DAE4032491A233698B8BEC159904F8AC25D1E90454A45F786C433C843224D755DE28AC1CAD4E9736C6D4180BA705B607842915F257BBC730C733882911A8A51738DF20BA48EF64240646041BA8C6F3FDEDE140EC3AA3EBD710F5E12A3F5C50C2784FA32CB6E24CDFC621602E67C80DEB8347146AF1983C201E2B4A868B2DD61D079D41AD874F63E22B42101130C646F0217A74192C47B8A732F69DDE9C05ED4E2B7E3CCA501D687F1FAED478D3910BF3689DB3865574926D16FD3DED6561FDD8BA46FDE6121312E798A0CA83993CEEFECC033CB73442A2C954E8BD1C752BAAD8D074F6F6829E515446A8BA834CF7D08B3170721C1388BD55BC802011B9863B91C9B4DB305D881A503B918428569418BC0B2ECC7FC3F9F34B8F66C5EA842B4AB441AFD29FFE658AFE94BE0E9FD2E9743778DC58CBD1DD8DC7220A9D04944B032C6FC0DFA46BEE2D47AA5DC569F0945F72E7751EC0DD7F218CED8AEF74AA9A8864147C3A89B5C6217888C86C51C83FB77FB91B2F7C6BC0D2624192F33FA8891D897593FD164F4822077B028627CB568412A4A2E9931C24BAF6F01A5A7A85EC446A0E67002F55367249F74087A7015D2580009DA08CA0789265B4EE073185A0892AEB1BEEDD00265AD397F87AB4ED831E3702A562627584AA7A195CF453F70D56CF201F73D6AC01E934A32432464337A6599C97F7B61F04E198AC75AA77BD9FAD027B1C82FBB1E78DC641859D3CA7C7EF28F1A612AE1F41B9B360C3A96367D0F3B4BBB9E0F5EDFDFDCD2731510DFB728BD4688B62988D79CE39513524935E2A43E68EB7210093111D92C3683A7FAD835D2B2C86A8C173AA67CCFD59934234D5EB190F8AB93E9C1E0DBAB54738B
+20220715015353 2 6 100 6143 2 E258E7BF12F3DDA792F3E7480A3563579067E7CB60FB18E010DAC18E1AD5671C1E0B1CED8BCF199C52405B70A169CCDAE2B112117B67D54C6F892B1822DC08FACB88D9C1E424709E41932AB799392DA34E0D560B03C459B2208DDB99ECA51883F8BADB33EF313D908ADB72802512653760C2AE00320555606FC09B797CFF13219A102668C5DCF4248DEEB9B7C779A2AE009842942DAE4032491A233698B8BEC159904F8AC25D1E90454A45F786C433C843224D755DE28AC1CAD4E9736C6D4180BA705B607842915F257BBC730C733882911A8A51738DF20BA48EF64240646041BA8C6F3FDEDE140EC3AA3EBD710F5E12A3F5C50C2784FA32CB6E24CDFC621602E67C80DEB8347146AF1983C201E2B4A868B2DD61D079D41AD874F63E22B42101130C646F0217A74192C47B8A732F69DDE9C05ED4E2B7E3CCA501D687F1FAED478D3910BF3689DB3865574926D16FD3DED6561FDD8BA46FDE6121312E798A0CA83993CEEFECC033CB73442A2C954E8BD1C752BAAD8D074F6F6829E515446A8BA834CF7D08B3170721C1388BD55BC802011B9863B91C9B4DB305D881A503B918428569418BC0B2ECC7FC3F9F34B8F66C5EA842B4AB441AFD29FFE658AFE94BE0E9FD2E9743778DC58CBD1DD8DC7220A9D04944B032C6FC0DFA46BEE2D47AA5DC569F0945F72E7751EC0DD7F218CED8AEF74AA9A8864147C3A89B5C6217888C86C51C83FB77FB91B2F7C6BC0D2624192F33FA8891D897593FD164F4822077B028627CB568412A4A2E9931C24BAF6F01A5A7A85EC446A0E67002F55367249F74087A7015D2580009DA08CA0789265B4EE073185A0892AEB1BEEDD00265AD397F87AB4ED831E3702A562627584AA7A195CF453F70D56CF201F73D6AC01E934A32432464337A6599C97F7B61F04E198AC75AA77BD9FAD027B1C82FBB1E78DC641859D3CA7C7EF28F1A612AE1F41B9B360C3A96367D0F3B4BBB9E0F5EDFDFDCD2731510DFB728BD4688B62988D79CE39513524935E2A43E68EB7210093111D92C3683A7FAD835D2B2C86A8C173AA67CCFD59934234D5EB190F8AB93E9C1E0DBAE41CA83
+20220715023846 2 6 100 6143 5 E258E7BF12F3DDA792F3E7480A3563579067E7CB60FB18E010DAC18E1AD5671C1E0B1CED8BCF199C52405B70A169CCDAE2B112117B67D54C6F892B1822DC08FACB88D9C1E424709E41932AB799392DA34E0D560B03C459B2208DDB99ECA51883F8BADB33EF313D908ADB72802512653760C2AE00320555606FC09B797CFF13219A102668C5DCF4248DEEB9B7C779A2AE009842942DAE4032491A233698B8BEC159904F8AC25D1E90454A45F786C433C843224D755DE28AC1CAD4E9736C6D4180BA705B607842915F257BBC730C733882911A8A51738DF20BA48EF64240646041BA8C6F3FDEDE140EC3AA3EBD710F5E12A3F5C50C2784FA32CB6E24CDFC621602E67C80DEB8347146AF1983C201E2B4A868B2DD61D079D41AD874F63E22B42101130C646F0217A74192C47B8A732F69DDE9C05ED4E2B7E3CCA501D687F1FAED478D3910BF3689DB3865574926D16FD3DED6561FDD8BA46FDE6121312E798A0CA83993CEEFECC033CB73442A2C954E8BD1C752BAAD8D074F6F6829E515446A8BA834CF7D08B3170721C1388BD55BC802011B9863B91C9B4DB305D881A503B918428569418BC0B2ECC7FC3F9F34B8F66C5EA842B4AB441AFD29FFE658AFE94BE0E9FD2E9743778DC58CBD1DD8DC7220A9D04944B032C6FC0DFA46BEE2D47AA5DC569F0945F72E7751EC0DD7F218CED8AEF74AA9A8864147C3A89B5C6217888C86C51C83FB77FB91B2F7C6BC0D2624192F33FA8891D897593FD164F4822077B028627CB568412A4A2E9931C24BAF6F01A5A7A85EC446A0E67002F55367249F74087A7015D2580009DA08CA0789265B4EE073185A0892AEB1BEEDD00265AD397F87AB4ED831E3702A562627584AA7A195CF453F70D56CF201F73D6AC01E934A32432464337A6599C97F7B61F04E198AC75AA77BD9FAD027B1C82FBB1E78DC641859D3CA7C7EF28F1A612AE1F41B9B360C3A96367D0F3B4BBB9E0F5EDFDFDCD2731510DFB728BD4688B62988D79CE39513524935E2A43E68EB7210093111D92C3683A7FAD835D2B2C86A8C173AA67CCFD59934234D5EB190F8AB93E9C1E0DBB4450E27
+20220715024203 2 6 100 6143 2 E258E7BF12F3DDA792F3E7480A3563579067E7CB60FB18E010DAC18E1AD5671C1E0B1CED8BCF199C52405B70A169CCDAE2B112117B67D54C6F892B1822DC08FACB88D9C1E424709E41932AB799392DA34E0D560B03C459B2208DDB99ECA51883F8BADB33EF313D908ADB72802512653760C2AE00320555606FC09B797CFF13219A102668C5DCF4248DEEB9B7C779A2AE009842942DAE4032491A233698B8BEC159904F8AC25D1E90454A45F786C433C843224D755DE28AC1CAD4E9736C6D4180BA705B607842915F257BBC730C733882911A8A51738DF20BA48EF64240646041BA8C6F3FDEDE140EC3AA3EBD710F5E12A3F5C50C2784FA32CB6E24CDFC621602E67C80DEB8347146AF1983C201E2B4A868B2DD61D079D41AD874F63E22B42101130C646F0217A74192C47B8A732F69DDE9C05ED4E2B7E3CCA501D687F1FAED478D3910BF3689DB3865574926D16FD3DED6561FDD8BA46FDE6121312E798A0CA83993CEEFECC033CB73442A2C954E8BD1C752BAAD8D074F6F6829E515446A8BA834CF7D08B3170721C1388BD55BC802011B9863B91C9B4DB305D881A503B918428569418BC0B2ECC7FC3F9F34B8F66C5EA842B4AB441AFD29FFE658AFE94BE0E9FD2E9743778DC58CBD1DD8DC7220A9D04944B032C6FC0DFA46BEE2D47AA5DC569F0945F72E7751EC0DD7F218CED8AEF74AA9A8864147C3A89B5C6217888C86C51C83FB77FB91B2F7C6BC0D2624192F33FA8891D897593FD164F4822077B028627CB568412A4A2E9931C24BAF6F01A5A7A85EC446A0E67002F55367249F74087A7015D2580009DA08CA0789265B4EE073185A0892AEB1BEEDD00265AD397F87AB4ED831E3702A562627584AA7A195CF453F70D56CF201F73D6AC01E934A32432464337A6599C97F7B61F04E198AC75AA77BD9FAD027B1C82FBB1E78DC641859D3CA7C7EF28F1A612AE1F41B9B360C3A96367D0F3B4BBB9E0F5EDFDFDCD2731510DFB728BD4688B62988D79CE39513524935E2A43E68EB7210093111D92C3683A7FAD835D2B2C86A8C173AA67CCFD59934234D5EB190F8AB93E9C1E0DBB4B76CCB
+20220715024757 2 6 100 6143 5 E258E7BF12F3DDA792F3E7480A3563579067E7CB60FB18E010DAC18E1AD5671C1E0B1CED8BCF199C52405B70A169CCDAE2B112117B67D54C6F892B1822DC08FACB88D9C1E424709E41932AB799392DA34E0D560B03C459B2208DDB99ECA51883F8BADB33EF313D908ADB72802512653760C2AE00320555606FC09B797CFF13219A102668C5DCF4248DEEB9B7C779A2AE009842942DAE4032491A233698B8BEC159904F8AC25D1E90454A45F786C433C843224D755DE28AC1CAD4E9736C6D4180BA705B607842915F257BBC730C733882911A8A51738DF20BA48EF64240646041BA8C6F3FDEDE140EC3AA3EBD710F5E12A3F5C50C2784FA32CB6E24CDFC621602E67C80DEB8347146AF1983C201E2B4A868B2DD61D079D41AD874F63E22B42101130C646F0217A74192C47B8A732F69DDE9C05ED4E2B7E3CCA501D687F1FAED478D3910BF3689DB3865574926D16FD3DED6561FDD8BA46FDE6121312E798A0CA83993CEEFECC033CB73442A2C954E8BD1C752BAAD8D074F6F6829E515446A8BA834CF7D08B3170721C1388BD55BC802011B9863B91C9B4DB305D881A503B918428569418BC0B2ECC7FC3F9F34B8F66C5EA842B4AB441AFD29FFE658AFE94BE0E9FD2E9743778DC58CBD1DD8DC7220A9D04944B032C6FC0DFA46BEE2D47AA5DC569F0945F72E7751EC0DD7F218CED8AEF74AA9A8864147C3A89B5C6217888C86C51C83FB77FB91B2F7C6BC0D2624192F33FA8891D897593FD164F4822077B028627CB568412A4A2E9931C24BAF6F01A5A7A85EC446A0E67002F55367249F74087A7015D2580009DA08CA0789265B4EE073185A0892AEB1BEEDD00265AD397F87AB4ED831E3702A562627584AA7A195CF453F70D56CF201F73D6AC01E934A32432464337A6599C97F7B61F04E198AC75AA77BD9FAD027B1C82FBB1E78DC641859D3CA7C7EF28F1A612AE1F41B9B360C3A96367D0F3B4BBB9E0F5EDFDFDCD2731510DFB728BD4688B62988D79CE39513524935E2A43E68EB7210093111D92C3683A7FAD835D2B2C86A8C173AA67CCFD59934234D5EB190F8AB93E9C1E0DBB58180EF
+20220715024833 2 6 100 6143 2 E258E7BF12F3DDA792F3E7480A3563579067E7CB60FB18E010DAC18E1AD5671C1E0B1CED8BCF199C52405B70A169CCDAE2B112117B67D54C6F892B1822DC08FACB88D9C1E424709E41932AB799392DA34E0D560B03C459B2208DDB99ECA51883F8BADB33EF313D908ADB72802512653760C2AE00320555606FC09B797CFF13219A102668C5DCF4248DEEB9B7C779A2AE009842942DAE4032491A233698B8BEC159904F8AC25D1E90454A45F786C433C843224D755DE28AC1CAD4E9736C6D4180BA705B607842915F257BBC730C733882911A8A51738DF20BA48EF64240646041BA8C6F3FDEDE140EC3AA3EBD710F5E12A3F5C50C2784FA32CB6E24CDFC621602E67C80DEB8347146AF1983C201E2B4A868B2DD61D079D41AD874F63E22B42101130C646F0217A74192C47B8A732F69DDE9C05ED4E2B7E3CCA501D687F1FAED478D3910BF3689DB3865574926D16FD3DED6561FDD8BA46FDE6121312E798A0CA83993CEEFECC033CB73442A2C954E8BD1C752BAAD8D074F6F6829E515446A8BA834CF7D08B3170721C1388BD55BC802011B9863B91C9B4DB305D881A503B918428569418BC0B2ECC7FC3F9F34B8F66C5EA842B4AB441AFD29FFE658AFE94BE0E9FD2E9743778DC58CBD1DD8DC7220A9D04944B032C6FC0DFA46BEE2D47AA5DC569F0945F72E7751EC0DD7F218CED8AEF74AA9A8864147C3A89B5C6217888C86C51C83FB77FB91B2F7C6BC0D2624192F33FA8891D897593FD164F4822077B028627CB568412A4A2E9931C24BAF6F01A5A7A85EC446A0E67002F55367249F74087A7015D2580009DA08CA0789265B4EE073185A0892AEB1BEEDD00265AD397F87AB4ED831E3702A562627584AA7A195CF453F70D56CF201F73D6AC01E934A32432464337A6599C97F7B61F04E198AC75AA77BD9FAD027B1C82FBB1E78DC641859D3CA7C7EF28F1A612AE1F41B9B360C3A96367D0F3B4BBB9E0F5EDFDFDCD2731510DFB728BD4688B62988D79CE39513524935E2A43E68EB7210093111D92C3683A7FAD835D2B2C86A8C173AA67CCFD59934234D5EB190F8AB93E9C1E0DBB5965263
+20220715025025 2 6 100 6143 5 E258E7BF12F3DDA792F3E7480A3563579067E7CB60FB18E010DAC18E1AD5671C1E0B1CED8BCF199C52405B70A169CCDAE2B112117B67D54C6F892B1822DC08FACB88D9C1E424709E41932AB799392DA34E0D560B03C459B2208DDB99ECA51883F8BADB33EF313D908ADB72802512653760C2AE00320555606FC09B797CFF13219A102668C5DCF4248DEEB9B7C779A2AE009842942DAE4032491A233698B8BEC159904F8AC25D1E90454A45F786C433C843224D755DE28AC1CAD4E9736C6D4180BA705B607842915F257BBC730C733882911A8A51738DF20BA48EF64240646041BA8C6F3FDEDE140EC3AA3EBD710F5E12A3F5C50C2784FA32CB6E24CDFC621602E67C80DEB8347146AF1983C201E2B4A868B2DD61D079D41AD874F63E22B42101130C646F0217A74192C47B8A732F69DDE9C05ED4E2B7E3CCA501D687F1FAED478D3910BF3689DB3865574926D16FD3DED6561FDD8BA46FDE6121312E798A0CA83993CEEFECC033CB73442A2C954E8BD1C752BAAD8D074F6F6829E515446A8BA834CF7D08B3170721C1388BD55BC802011B9863B91C9B4DB305D881A503B918428569418BC0B2ECC7FC3F9F34B8F66C5EA842B4AB441AFD29FFE658AFE94BE0E9FD2E9743778DC58CBD1DD8DC7220A9D04944B032C6FC0DFA46BEE2D47AA5DC569F0945F72E7751EC0DD7F218CED8AEF74AA9A8864147C3A89B5C6217888C86C51C83FB77FB91B2F7C6BC0D2624192F33FA8891D897593FD164F4822077B028627CB568412A4A2E9931C24BAF6F01A5A7A85EC446A0E67002F55367249F74087A7015D2580009DA08CA0789265B4EE073185A0892AEB1BEEDD00265AD397F87AB4ED831E3702A562627584AA7A195CF453F70D56CF201F73D6AC01E934A32432464337A6599C97F7B61F04E198AC75AA77BD9FAD027B1C82FBB1E78DC641859D3CA7C7EF28F1A612AE1F41B9B360C3A96367D0F3B4BBB9E0F5EDFDFDCD2731510DFB728BD4688B62988D79CE39513524935E2A43E68EB7210093111D92C3683A7FAD835D2B2C86A8C173AA67CCFD59934234D5EB190F8AB93E9C1E0DBB5D2C667
+20220715025333 2 6 100 6143 5 E258E7BF12F3DDA792F3E7480A3563579067E7CB60FB18E010DAC18E1AD5671C1E0B1CED8BCF199C52405B70A169CCDAE2B112117B67D54C6F892B1822DC08FACB88D9C1E424709E41932AB799392DA34E0D560B03C459B2208DDB99ECA51883F8BADB33EF313D908ADB72802512653760C2AE00320555606FC09B797CFF13219A102668C5DCF4248DEEB9B7C779A2AE009842942DAE4032491A233698B8BEC159904F8AC25D1E90454A45F786C433C843224D755DE28AC1CAD4E9736C6D4180BA705B607842915F257BBC730C733882911A8A51738DF20BA48EF64240646041BA8C6F3FDEDE140EC3AA3EBD710F5E12A3F5C50C2784FA32CB6E24CDFC621602E67C80DEB8347146AF1983C201E2B4A868B2DD61D079D41AD874F63E22B42101130C646F0217A74192C47B8A732F69DDE9C05ED4E2B7E3CCA501D687F1FAED478D3910BF3689DB3865574926D16FD3DED6561FDD8BA46FDE6121312E798A0CA83993CEEFECC033CB73442A2C954E8BD1C752BAAD8D074F6F6829E515446A8BA834CF7D08B3170721C1388BD55BC802011B9863B91C9B4DB305D881A503B918428569418BC0B2ECC7FC3F9F34B8F66C5EA842B4AB441AFD29FFE658AFE94BE0E9FD2E9743778DC58CBD1DD8DC7220A9D04944B032C6FC0DFA46BEE2D47AA5DC569F0945F72E7751EC0DD7F218CED8AEF74AA9A8864147C3A89B5C6217888C86C51C83FB77FB91B2F7C6BC0D2624192F33FA8891D897593FD164F4822077B028627CB568412A4A2E9931C24BAF6F01A5A7A85EC446A0E67002F55367249F74087A7015D2580009DA08CA0789265B4EE073185A0892AEB1BEEDD00265AD397F87AB4ED831E3702A562627584AA7A195CF453F70D56CF201F73D6AC01E934A32432464337A6599C97F7B61F04E198AC75AA77BD9FAD027B1C82FBB1E78DC641859D3CA7C7EF28F1A612AE1F41B9B360C3A96367D0F3B4BBB9E0F5EDFDFDCD2731510DFB728BD4688B62988D79CE39513524935E2A43E68EB7210093111D92C3683A7FAD835D2B2C86A8C173AA67CCFD59934234D5EB190F8AB93E9C1E0DBB63FE40F
+20220715025633 2 6 100 6143 2 E258E7BF12F3DDA792F3E7480A3563579067E7CB60FB18E010DAC18E1AD5671C1E0B1CED8BCF199C52405B70A169CCDAE2B112117B67D54C6F892B1822DC08FACB88D9C1E424709E41932AB799392DA34E0D560B03C459B2208DDB99ECA51883F8BADB33EF313D908ADB72802512653760C2AE00320555606FC09B797CFF13219A102668C5DCF4248DEEB9B7C779A2AE009842942DAE4032491A233698B8BEC159904F8AC25D1E90454A45F786C433C843224D755DE28AC1CAD4E9736C6D4180BA705B607842915F257BBC730C733882911A8A51738DF20BA48EF64240646041BA8C6F3FDEDE140EC3AA3EBD710F5E12A3F5C50C2784FA32CB6E24CDFC621602E67C80DEB8347146AF1983C201E2B4A868B2DD61D079D41AD874F63E22B42101130C646F0217A74192C47B8A732F69DDE9C05ED4E2B7E3CCA501D687F1FAED478D3910BF3689DB3865574926D16FD3DED6561FDD8BA46FDE6121312E798A0CA83993CEEFECC033CB73442A2C954E8BD1C752BAAD8D074F6F6829E515446A8BA834CF7D08B3170721C1388BD55BC802011B9863B91C9B4DB305D881A503B918428569418BC0B2ECC7FC3F9F34B8F66C5EA842B4AB441AFD29FFE658AFE94BE0E9FD2E9743778DC58CBD1DD8DC7220A9D04944B032C6FC0DFA46BEE2D47AA5DC569F0945F72E7751EC0DD7F218CED8AEF74AA9A8864147C3A89B5C6217888C86C51C83FB77FB91B2F7C6BC0D2624192F33FA8891D897593FD164F4822077B028627CB568412A4A2E9931C24BAF6F01A5A7A85EC446A0E67002F55367249F74087A7015D2580009DA08CA0789265B4EE073185A0892AEB1BEEDD00265AD397F87AB4ED831E3702A562627584AA7A195CF453F70D56CF201F73D6AC01E934A32432464337A6599C97F7B61F04E198AC75AA77BD9FAD027B1C82FBB1E78DC641859D3CA7C7EF28F1A612AE1F41B9B360C3A96367D0F3B4BBB9E0F5EDFDFDCD2731510DFB728BD4688B62988D79CE39513524935E2A43E68EB7210093111D92C3683A7FAD835D2B2C86A8C173AA67CCFD59934234D5EB190F8AB93E9C1E0DBB6A8BD4B
+20220715030337 2 6 100 6143 5 E258E7BF12F3DDA792F3E7480A3563579067E7CB60FB18E010DAC18E1AD5671C1E0B1CED8BCF199C52405B70A169CCDAE2B112117B67D54C6F892B1822DC08FACB88D9C1E424709E41932AB799392DA34E0D560B03C459B2208DDB99ECA51883F8BADB33EF313D908ADB72802512653760C2AE00320555606FC09B797CFF13219A102668C5DCF4248DEEB9B7C779A2AE009842942DAE4032491A233698B8BEC159904F8AC25D1E90454A45F786C433C843224D755DE28AC1CAD4E9736C6D4180BA705B607842915F257BBC730C733882911A8A51738DF20BA48EF64240646041BA8C6F3FDEDE140EC3AA3EBD710F5E12A3F5C50C2784FA32CB6E24CDFC621602E67C80DEB8347146AF1983C201E2B4A868B2DD61D079D41AD874F63E22B42101130C646F0217A74192C47B8A732F69DDE9C05ED4E2B7E3CCA501D687F1FAED478D3910BF3689DB3865574926D16FD3DED6561FDD8BA46FDE6121312E798A0CA83993CEEFECC033CB73442A2C954E8BD1C752BAAD8D074F6F6829E515446A8BA834CF7D08B3170721C1388BD55BC802011B9863B91C9B4DB305D881A503B918428569418BC0B2ECC7FC3F9F34B8F66C5EA842B4AB441AFD29FFE658AFE94BE0E9FD2E9743778DC58CBD1DD8DC7220A9D04944B032C6FC0DFA46BEE2D47AA5DC569F0945F72E7751EC0DD7F218CED8AEF74AA9A8864147C3A89B5C6217888C86C51C83FB77FB91B2F7C6BC0D2624192F33FA8891D897593FD164F4822077B028627CB568412A4A2E9931C24BAF6F01A5A7A85EC446A0E67002F55367249F74087A7015D2580009DA08CA0789265B4EE073185A0892AEB1BEEDD00265AD397F87AB4ED831E3702A562627584AA7A195CF453F70D56CF201F73D6AC01E934A32432464337A6599C97F7B61F04E198AC75AA77BD9FAD027B1C82FBB1E78DC641859D3CA7C7EF28F1A612AE1F41B9B360C3A96367D0F3B4BBB9E0F5EDFDFDCD2731510DFB728BD4688B62988D79CE39513524935E2A43E68EB7210093111D92C3683A7FAD835D2B2C86A8C173AA67CCFD59934234D5EB190F8AB93E9C1E0DBB79F8147
+20220715031630 2 6 100 6143 2 E258E7BF12F3DDA792F3E7480A3563579067E7CB60FB18E010DAC18E1AD5671C1E0B1CED8BCF199C52405B70A169CCDAE2B112117B67D54C6F892B1822DC08FACB88D9C1E424709E41932AB799392DA34E0D560B03C459B2208DDB99ECA51883F8BADB33EF313D908ADB72802512653760C2AE00320555606FC09B797CFF13219A102668C5DCF4248DEEB9B7C779A2AE009842942DAE4032491A233698B8BEC159904F8AC25D1E90454A45F786C433C843224D755DE28AC1CAD4E9736C6D4180BA705B607842915F257BBC730C733882911A8A51738DF20BA48EF64240646041BA8C6F3FDEDE140EC3AA3EBD710F5E12A3F5C50C2784FA32CB6E24CDFC621602E67C80DEB8347146AF1983C201E2B4A868B2DD61D079D41AD874F63E22B42101130C646F0217A74192C47B8A732F69DDE9C05ED4E2B7E3CCA501D687F1FAED478D3910BF3689DB3865574926D16FD3DED6561FDD8BA46FDE6121312E798A0CA83993CEEFECC033CB73442A2C954E8BD1C752BAAD8D074F6F6829E515446A8BA834CF7D08B3170721C1388BD55BC802011B9863B91C9B4DB305D881A503B918428569418BC0B2ECC7FC3F9F34B8F66C5EA842B4AB441AFD29FFE658AFE94BE0E9FD2E9743778DC58CBD1DD8DC7220A9D04944B032C6FC0DFA46BEE2D47AA5DC569F0945F72E7751EC0DD7F218CED8AEF74AA9A8864147C3A89B5C6217888C86C51C83FB77FB91B2F7C6BC0D2624192F33FA8891D897593FD164F4822077B028627CB568412A4A2E9931C24BAF6F01A5A7A85EC446A0E67002F55367249F74087A7015D2580009DA08CA0789265B4EE073185A0892AEB1BEEDD00265AD397F87AB4ED831E3702A562627584AA7A195CF453F70D56CF201F73D6AC01E934A32432464337A6599C97F7B61F04E198AC75AA77BD9FAD027B1C82FBB1E78DC641859D3CA7C7EF28F1A612AE1F41B9B360C3A96367D0F3B4BBB9E0F5EDFDFDCD2731510DFB728BD4688B62988D79CE39513524935E2A43E68EB7210093111D92C3683A7FAD835D2B2C86A8C173AA67CCFD59934234D5EB190F8AB93E9C1E0DBB9537AB3
+20220715034438 2 6 100 6143 5 E258E7BF12F3DDA792F3E7480A3563579067E7CB60FB18E010DAC18E1AD5671C1E0B1CED8BCF199C52405B70A169CCDAE2B112117B67D54C6F892B1822DC08FACB88D9C1E424709E41932AB799392DA34E0D560B03C459B2208DDB99ECA51883F8BADB33EF313D908ADB72802512653760C2AE00320555606FC09B797CFF13219A102668C5DCF4248DEEB9B7C779A2AE009842942DAE4032491A233698B8BEC159904F8AC25D1E90454A45F786C433C843224D755DE28AC1CAD4E9736C6D4180BA705B607842915F257BBC730C733882911A8A51738DF20BA48EF64240646041BA8C6F3FDEDE140EC3AA3EBD710F5E12A3F5C50C2784FA32CB6E24CDFC621602E67C80DEB8347146AF1983C201E2B4A868B2DD61D079D41AD874F63E22B42101130C646F0217A74192C47B8A732F69DDE9C05ED4E2B7E3CCA501D687F1FAED478D3910BF3689DB3865574926D16FD3DED6561FDD8BA46FDE6121312E798A0CA83993CEEFECC033CB73442A2C954E8BD1C752BAAD8D074F6F6829E515446A8BA834CF7D08B3170721C1388BD55BC802011B9863B91C9B4DB305D881A503B918428569418BC0B2ECC7FC3F9F34B8F66C5EA842B4AB441AFD29FFE658AFE94BE0E9FD2E9743778DC58CBD1DD8DC7220A9D04944B032C6FC0DFA46BEE2D47AA5DC569F0945F72E7751EC0DD7F218CED8AEF74AA9A8864147C3A89B5C6217888C86C51C83FB77FB91B2F7C6BC0D2624192F33FA8891D897593FD164F4822077B028627CB568412A4A2E9931C24BAF6F01A5A7A85EC446A0E67002F55367249F74087A7015D2580009DA08CA0789265B4EE073185A0892AEB1BEEDD00265AD397F87AB4ED831E3702A562627584AA7A195CF453F70D56CF201F73D6AC01E934A32432464337A6599C97F7B61F04E198AC75AA77BD9FAD027B1C82FBB1E78DC641859D3CA7C7EF28F1A612AE1F41B9B360C3A96367D0F3B4BBB9E0F5EDFDFDCD2731510DFB728BD4688B62988D79CE39513524935E2A43E68EB7210093111D92C3683A7FAD835D2B2C86A8C173AA67CCFD59934234D5EB190F8AB93E9C1E0DBBD1C7CE7
+20220715035610 2 6 100 6143 5 E258E7BF12F3DDA792F3E7480A3563579067E7CB60FB18E010DAC18E1AD5671C1E0B1CED8BCF199C52405B70A169CCDAE2B112117B67D54C6F892B1822DC08FACB88D9C1E424709E41932AB799392DA34E0D560B03C459B2208DDB99ECA51883F8BADB33EF313D908ADB72802512653760C2AE00320555606FC09B797CFF13219A102668C5DCF4248DEEB9B7C779A2AE009842942DAE4032491A233698B8BEC159904F8AC25D1E90454A45F786C433C843224D755DE28AC1CAD4E9736C6D4180BA705B607842915F257BBC730C733882911A8A51738DF20BA48EF64240646041BA8C6F3FDEDE140EC3AA3EBD710F5E12A3F5C50C2784FA32CB6E24CDFC621602E67C80DEB8347146AF1983C201E2B4A868B2DD61D079D41AD874F63E22B42101130C646F0217A74192C47B8A732F69DDE9C05ED4E2B7E3CCA501D687F1FAED478D3910BF3689DB3865574926D16FD3DED6561FDD8BA46FDE6121312E798A0CA83993CEEFECC033CB73442A2C954E8BD1C752BAAD8D074F6F6829E515446A8BA834CF7D08B3170721C1388BD55BC802011B9863B91C9B4DB305D881A503B918428569418BC0B2ECC7FC3F9F34B8F66C5EA842B4AB441AFD29FFE658AFE94BE0E9FD2E9743778DC58CBD1DD8DC7220A9D04944B032C6FC0DFA46BEE2D47AA5DC569F0945F72E7751EC0DD7F218CED8AEF74AA9A8864147C3A89B5C6217888C86C51C83FB77FB91B2F7C6BC0D2624192F33FA8891D897593FD164F4822077B028627CB568412A4A2E9931C24BAF6F01A5A7A85EC446A0E67002F55367249F74087A7015D2580009DA08CA0789265B4EE073185A0892AEB1BEEDD00265AD397F87AB4ED831E3702A562627584AA7A195CF453F70D56CF201F73D6AC01E934A32432464337A6599C97F7B61F04E198AC75AA77BD9FAD027B1C82FBB1E78DC641859D3CA7C7EF28F1A612AE1F41B9B360C3A96367D0F3B4BBB9E0F5EDFDFDCD2731510DFB728BD4688B62988D79CE39513524935E2A43E68EB7210093111D92C3683A7FAD835D2B2C86A8C173AA67CCFD59934234D5EB190F8AB93E9C1E0DBBEAD09D7
+20220715040817 2 6 100 6143 5 E258E7BF12F3DDA792F3E7480A3563579067E7CB60FB18E010DAC18E1AD5671C1E0B1CED8BCF199C52405B70A169CCDAE2B112117B67D54C6F892B1822DC08FACB88D9C1E424709E41932AB799392DA34E0D560B03C459B2208DDB99ECA51883F8BADB33EF313D908ADB72802512653760C2AE00320555606FC09B797CFF13219A102668C5DCF4248DEEB9B7C779A2AE009842942DAE4032491A233698B8BEC159904F8AC25D1E90454A45F786C433C843224D755DE28AC1CAD4E9736C6D4180BA705B607842915F257BBC730C733882911A8A51738DF20BA48EF64240646041BA8C6F3FDEDE140EC3AA3EBD710F5E12A3F5C50C2784FA32CB6E24CDFC621602E67C80DEB8347146AF1983C201E2B4A868B2DD61D079D41AD874F63E22B42101130C646F0217A74192C47B8A732F69DDE9C05ED4E2B7E3CCA501D687F1FAED478D3910BF3689DB3865574926D16FD3DED6561FDD8BA46FDE6121312E798A0CA83993CEEFECC033CB73442A2C954E8BD1C752BAAD8D074F6F6829E515446A8BA834CF7D08B3170721C1388BD55BC802011B9863B91C9B4DB305D881A503B918428569418BC0B2ECC7FC3F9F34B8F66C5EA842B4AB441AFD29FFE658AFE94BE0E9FD2E9743778DC58CBD1DD8DC7220A9D04944B032C6FC0DFA46BEE2D47AA5DC569F0945F72E7751EC0DD7F218CED8AEF74AA9A8864147C3A89B5C6217888C86C51C83FB77FB91B2F7C6BC0D2624192F33FA8891D897593FD164F4822077B028627CB568412A4A2E9931C24BAF6F01A5A7A85EC446A0E67002F55367249F74087A7015D2580009DA08CA0789265B4EE073185A0892AEB1BEEDD00265AD397F87AB4ED831E3702A562627584AA7A195CF453F70D56CF201F73D6AC01E934A32432464337A6599C97F7B61F04E198AC75AA77BD9FAD027B1C82FBB1E78DC641859D3CA7C7EF28F1A612AE1F41B9B360C3A96367D0F3B4BBB9E0F5EDFDFDCD2731510DFB728BD4688B62988D79CE39513524935E2A43E68EB7210093111D92C3683A7FAD835D2B2C86A8C173AA67CCFD59934234D5EB190F8AB93E9C1E0DBC04657DF
+20220715041331 2 6 100 6143 2 E258E7BF12F3DDA792F3E7480A3563579067E7CB60FB18E010DAC18E1AD5671C1E0B1CED8BCF199C52405B70A169CCDAE2B112117B67D54C6F892B1822DC08FACB88D9C1E424709E41932AB799392DA34E0D560B03C459B2208DDB99ECA51883F8BADB33EF313D908ADB72802512653760C2AE00320555606FC09B797CFF13219A102668C5DCF4248DEEB9B7C779A2AE009842942DAE4032491A233698B8BEC159904F8AC25D1E90454A45F786C433C843224D755DE28AC1CAD4E9736C6D4180BA705B607842915F257BBC730C733882911A8A51738DF20BA48EF64240646041BA8C6F3FDEDE140EC3AA3EBD710F5E12A3F5C50C2784FA32CB6E24CDFC621602E67C80DEB8347146AF1983C201E2B4A868B2DD61D079D41AD874F63E22B42101130C646F0217A74192C47B8A732F69DDE9C05ED4E2B7E3CCA501D687F1FAED478D3910BF3689DB3865574926D16FD3DED6561FDD8BA46FDE6121312E798A0CA83993CEEFECC033CB73442A2C954E8BD1C752BAAD8D074F6F6829E515446A8BA834CF7D08B3170721C1388BD55BC802011B9863B91C9B4DB305D881A503B918428569418BC0B2ECC7FC3F9F34B8F66C5EA842B4AB441AFD29FFE658AFE94BE0E9FD2E9743778DC58CBD1DD8DC7220A9D04944B032C6FC0DFA46BEE2D47AA5DC569F0945F72E7751EC0DD7F218CED8AEF74AA9A8864147C3A89B5C6217888C86C51C83FB77FB91B2F7C6BC0D2624192F33FA8891D897593FD164F4822077B028627CB568412A4A2E9931C24BAF6F01A5A7A85EC446A0E67002F55367249F74087A7015D2580009DA08CA0789265B4EE073185A0892AEB1BEEDD00265AD397F87AB4ED831E3702A562627584AA7A195CF453F70D56CF201F73D6AC01E934A32432464337A6599C97F7B61F04E198AC75AA77BD9FAD027B1C82FBB1E78DC641859D3CA7C7EF28F1A612AE1F41B9B360C3A96367D0F3B4BBB9E0F5EDFDFDCD2731510DFB728BD4688B62988D79CE39513524935E2A43E68EB7210093111D92C3683A7FAD835D2B2C86A8C173AA67CCFD59934234D5EB190F8AB93E9C1E0DBC0FC243B
+20220715041430 2 6 100 6143 5 E258E7BF12F3DDA792F3E7480A3563579067E7CB60FB18E010DAC18E1AD5671C1E0B1CED8BCF199C52405B70A169CCDAE2B112117B67D54C6F892B1822DC08FACB88D9C1E424709E41932AB799392DA34E0D560B03C459B2208DDB99ECA51883F8BADB33EF313D908ADB72802512653760C2AE00320555606FC09B797CFF13219A102668C5DCF4248DEEB9B7C779A2AE009842942DAE4032491A233698B8BEC159904F8AC25D1E90454A45F786C433C843224D755DE28AC1CAD4E9736C6D4180BA705B607842915F257BBC730C733882911A8A51738DF20BA48EF64240646041BA8C6F3FDEDE140EC3AA3EBD710F5E12A3F5C50C2784FA32CB6E24CDFC621602E67C80DEB8347146AF1983C201E2B4A868B2DD61D079D41AD874F63E22B42101130C646F0217A74192C47B8A732F69DDE9C05ED4E2B7E3CCA501D687F1FAED478D3910BF3689DB3865574926D16FD3DED6561FDD8BA46FDE6121312E798A0CA83993CEEFECC033CB73442A2C954E8BD1C752BAAD8D074F6F6829E515446A8BA834CF7D08B3170721C1388BD55BC802011B9863B91C9B4DB305D881A503B918428569418BC0B2ECC7FC3F9F34B8F66C5EA842B4AB441AFD29FFE658AFE94BE0E9FD2E9743778DC58CBD1DD8DC7220A9D04944B032C6FC0DFA46BEE2D47AA5DC569F0945F72E7751EC0DD7F218CED8AEF74AA9A8864147C3A89B5C6217888C86C51C83FB77FB91B2F7C6BC0D2624192F33FA8891D897593FD164F4822077B028627CB568412A4A2E9931C24BAF6F01A5A7A85EC446A0E67002F55367249F74087A7015D2580009DA08CA0789265B4EE073185A0892AEB1BEEDD00265AD397F87AB4ED831E3702A562627584AA7A195CF453F70D56CF201F73D6AC01E934A32432464337A6599C97F7B61F04E198AC75AA77BD9FAD027B1C82FBB1E78DC641859D3CA7C7EF28F1A612AE1F41B9B360C3A96367D0F3B4BBB9E0F5EDFDFDCD2731510DFB728BD4688B62988D79CE39513524935E2A43E68EB7210093111D92C3683A7FAD835D2B2C86A8C173AA67CCFD59934234D5EB190F8AB93E9C1E0DBC11DB2DF
+20220715042040 2 6 100 6143 2 E258E7BF12F3DDA792F3E7480A3563579067E7CB60FB18E010DAC18E1AD5671C1E0B1CED8BCF199C52405B70A169CCDAE2B112117B67D54C6F892B1822DC08FACB88D9C1E424709E41932AB799392DA34E0D560B03C459B2208DDB99ECA51883F8BADB33EF313D908ADB72802512653760C2AE00320555606FC09B797CFF13219A102668C5DCF4248DEEB9B7C779A2AE009842942DAE4032491A233698B8BEC159904F8AC25D1E90454A45F786C433C843224D755DE28AC1CAD4E9736C6D4180BA705B607842915F257BBC730C733882911A8A51738DF20BA48EF64240646041BA8C6F3FDEDE140EC3AA3EBD710F5E12A3F5C50C2784FA32CB6E24CDFC621602E67C80DEB8347146AF1983C201E2B4A868B2DD61D079D41AD874F63E22B42101130C646F0217A74192C47B8A732F69DDE9C05ED4E2B7E3CCA501D687F1FAED478D3910BF3689DB3865574926D16FD3DED6561FDD8BA46FDE6121312E798A0CA83993CEEFECC033CB73442A2C954E8BD1C752BAAD8D074F6F6829E515446A8BA834CF7D08B3170721C1388BD55BC802011B9863B91C9B4DB305D881A503B918428569418BC0B2ECC7FC3F9F34B8F66C5EA842B4AB441AFD29FFE658AFE94BE0E9FD2E9743778DC58CBD1DD8DC7220A9D04944B032C6FC0DFA46BEE2D47AA5DC569F0945F72E7751EC0DD7F218CED8AEF74AA9A8864147C3A89B5C6217888C86C51C83FB77FB91B2F7C6BC0D2624192F33FA8891D897593FD164F4822077B028627CB568412A4A2E9931C24BAF6F01A5A7A85EC446A0E67002F55367249F74087A7015D2580009DA08CA0789265B4EE073185A0892AEB1BEEDD00265AD397F87AB4ED831E3702A562627584AA7A195CF453F70D56CF201F73D6AC01E934A32432464337A6599C97F7B61F04E198AC75AA77BD9FAD027B1C82FBB1E78DC641859D3CA7C7EF28F1A612AE1F41B9B360C3A96367D0F3B4BBB9E0F5EDFDFDCD2731510DFB728BD4688B62988D79CE39513524935E2A43E68EB7210093111D92C3683A7FAD835D2B2C86A8C173AA67CCFD59934234D5EB190F8AB93E9C1E0DBC1ED4A53
+20220715042920 2 6 100 6143 5 E258E7BF12F3DDA792F3E7480A3563579067E7CB60FB18E010DAC18E1AD5671C1E0B1CED8BCF199C52405B70A169CCDAE2B112117B67D54C6F892B1822DC08FACB88D9C1E424709E41932AB799392DA34E0D560B03C459B2208DDB99ECA51883F8BADB33EF313D908ADB72802512653760C2AE00320555606FC09B797CFF13219A102668C5DCF4248DEEB9B7C779A2AE009842942DAE4032491A233698B8BEC159904F8AC25D1E90454A45F786C433C843224D755DE28AC1CAD4E9736C6D4180BA705B607842915F257BBC730C733882911A8A51738DF20BA48EF64240646041BA8C6F3FDEDE140EC3AA3EBD710F5E12A3F5C50C2784FA32CB6E24CDFC621602E67C80DEB8347146AF1983C201E2B4A868B2DD61D079D41AD874F63E22B42101130C646F0217A74192C47B8A732F69DDE9C05ED4E2B7E3CCA501D687F1FAED478D3910BF3689DB3865574926D16FD3DED6561FDD8BA46FDE6121312E798A0CA83993CEEFECC033CB73442A2C954E8BD1C752BAAD8D074F6F6829E515446A8BA834CF7D08B3170721C1388BD55BC802011B9863B91C9B4DB305D881A503B918428569418BC0B2ECC7FC3F9F34B8F66C5EA842B4AB441AFD29FFE658AFE94BE0E9FD2E9743778DC58CBD1DD8DC7220A9D04944B032C6FC0DFA46BEE2D47AA5DC569F0945F72E7751EC0DD7F218CED8AEF74AA9A8864147C3A89B5C6217888C86C51C83FB77FB91B2F7C6BC0D2624192F33FA8891D897593FD164F4822077B028627CB568412A4A2E9931C24BAF6F01A5A7A85EC446A0E67002F55367249F74087A7015D2580009DA08CA0789265B4EE073185A0892AEB1BEEDD00265AD397F87AB4ED831E3702A562627584AA7A195CF453F70D56CF201F73D6AC01E934A32432464337A6599C97F7B61F04E198AC75AA77BD9FAD027B1C82FBB1E78DC641859D3CA7C7EF28F1A612AE1F41B9B360C3A96367D0F3B4BBB9E0F5EDFDFDCD2731510DFB728BD4688B62988D79CE39513524935E2A43E68EB7210093111D92C3683A7FAD835D2B2C86A8C173AA67CCFD59934234D5EB190F8AB93E9C1E0DBC31D6CE7
+20220715043335 2 6 100 6143 2 E258E7BF12F3DDA792F3E7480A3563579067E7CB60FB18E010DAC18E1AD5671C1E0B1CED8BCF199C52405B70A169CCDAE2B112117B67D54C6F892B1822DC08FACB88D9C1E424709E41932AB799392DA34E0D560B03C459B2208DDB99ECA51883F8BADB33EF313D908ADB72802512653760C2AE00320555606FC09B797CFF13219A102668C5DCF4248DEEB9B7C779A2AE009842942DAE4032491A233698B8BEC159904F8AC25D1E90454A45F786C433C843224D755DE28AC1CAD4E9736C6D4180BA705B607842915F257BBC730C733882911A8A51738DF20BA48EF64240646041BA8C6F3FDEDE140EC3AA3EBD710F5E12A3F5C50C2784FA32CB6E24CDFC621602E67C80DEB8347146AF1983C201E2B4A868B2DD61D079D41AD874F63E22B42101130C646F0217A74192C47B8A732F69DDE9C05ED4E2B7E3CCA501D687F1FAED478D3910BF3689DB3865574926D16FD3DED6561FDD8BA46FDE6121312E798A0CA83993CEEFECC033CB73442A2C954E8BD1C752BAAD8D074F6F6829E515446A8BA834CF7D08B3170721C1388BD55BC802011B9863B91C9B4DB305D881A503B918428569418BC0B2ECC7FC3F9F34B8F66C5EA842B4AB441AFD29FFE658AFE94BE0E9FD2E9743778DC58CBD1DD8DC7220A9D04944B032C6FC0DFA46BEE2D47AA5DC569F0945F72E7751EC0DD7F218CED8AEF74AA9A8864147C3A89B5C6217888C86C51C83FB77FB91B2F7C6BC0D2624192F33FA8891D897593FD164F4822077B028627CB568412A4A2E9931C24BAF6F01A5A7A85EC446A0E67002F55367249F74087A7015D2580009DA08CA0789265B4EE073185A0892AEB1BEEDD00265AD397F87AB4ED831E3702A562627584AA7A195CF453F70D56CF201F73D6AC01E934A32432464337A6599C97F7B61F04E198AC75AA77BD9FAD027B1C82FBB1E78DC641859D3CA7C7EF28F1A612AE1F41B9B360C3A96367D0F3B4BBB9E0F5EDFDFDCD2731510DFB728BD4688B62988D79CE39513524935E2A43E68EB7210093111D92C3683A7FAD835D2B2C86A8C173AA67CCFD59934234D5EB190F8AB93E9C1E0DBC3B0A75B
+20220715051034 2 6 100 6143 5 E258E7BF12F3DDA792F3E7480A3563579067E7CB60FB18E010DAC18E1AD5671C1E0B1CED8BCF199C52405B70A169CCDAE2B112117B67D54C6F892B1822DC08FACB88D9C1E424709E41932AB799392DA34E0D560B03C459B2208DDB99ECA51883F8BADB33EF313D908ADB72802512653760C2AE00320555606FC09B797CFF13219A102668C5DCF4248DEEB9B7C779A2AE009842942DAE4032491A233698B8BEC159904F8AC25D1E90454A45F786C433C843224D755DE28AC1CAD4E9736C6D4180BA705B607842915F257BBC730C733882911A8A51738DF20BA48EF64240646041BA8C6F3FDEDE140EC3AA3EBD710F5E12A3F5C50C2784FA32CB6E24CDFC621602E67C80DEB8347146AF1983C201E2B4A868B2DD61D079D41AD874F63E22B42101130C646F0217A74192C47B8A732F69DDE9C05ED4E2B7E3CCA501D687F1FAED478D3910BF3689DB3865574926D16FD3DED6561FDD8BA46FDE6121312E798A0CA83993CEEFECC033CB73442A2C954E8BD1C752BAAD8D074F6F6829E515446A8BA834CF7D08B3170721C1388BD55BC802011B9863B91C9B4DB305D881A503B918428569418BC0B2ECC7FC3F9F34B8F66C5EA842B4AB441AFD29FFE658AFE94BE0E9FD2E9743778DC58CBD1DD8DC7220A9D04944B032C6FC0DFA46BEE2D47AA5DC569F0945F72E7751EC0DD7F218CED8AEF74AA9A8864147C3A89B5C6217888C86C51C83FB77FB91B2F7C6BC0D2624192F33FA8891D897593FD164F4822077B028627CB568412A4A2E9931C24BAF6F01A5A7A85EC446A0E67002F55367249F74087A7015D2580009DA08CA0789265B4EE073185A0892AEB1BEEDD00265AD397F87AB4ED831E3702A562627584AA7A195CF453F70D56CF201F73D6AC01E934A32432464337A6599C97F7B61F04E198AC75AA77BD9FAD027B1C82FBB1E78DC641859D3CA7C7EF28F1A612AE1F41B9B360C3A96367D0F3B4BBB9E0F5EDFDFDCD2731510DFB728BD4688B62988D79CE39513524935E2A43E68EB7210093111D92C3683A7FAD835D2B2C86A8C173AA67CCFD59934234D5EB190F8AB93E9C1E0DBC8A470E7
+20220715051434 2 6 100 6143 5 E258E7BF12F3DDA792F3E7480A3563579067E7CB60FB18E010DAC18E1AD5671C1E0B1CED8BCF199C52405B70A169CCDAE2B112117B67D54C6F892B1822DC08FACB88D9C1E424709E41932AB799392DA34E0D560B03C459B2208DDB99ECA51883F8BADB33EF313D908ADB72802512653760C2AE00320555606FC09B797CFF13219A102668C5DCF4248DEEB9B7C779A2AE009842942DAE4032491A233698B8BEC159904F8AC25D1E90454A45F786C433C843224D755DE28AC1CAD4E9736C6D4180BA705B607842915F257BBC730C733882911A8A51738DF20BA48EF64240646041BA8C6F3FDEDE140EC3AA3EBD710F5E12A3F5C50C2784FA32CB6E24CDFC621602E67C80DEB8347146AF1983C201E2B4A868B2DD61D079D41AD874F63E22B42101130C646F0217A74192C47B8A732F69DDE9C05ED4E2B7E3CCA501D687F1FAED478D3910BF3689DB3865574926D16FD3DED6561FDD8BA46FDE6121312E798A0CA83993CEEFECC033CB73442A2C954E8BD1C752BAAD8D074F6F6829E515446A8BA834CF7D08B3170721C1388BD55BC802011B9863B91C9B4DB305D881A503B918428569418BC0B2ECC7FC3F9F34B8F66C5EA842B4AB441AFD29FFE658AFE94BE0E9FD2E9743778DC58CBD1DD8DC7220A9D04944B032C6FC0DFA46BEE2D47AA5DC569F0945F72E7751EC0DD7F218CED8AEF74AA9A8864147C3A89B5C6217888C86C51C83FB77FB91B2F7C6BC0D2624192F33FA8891D897593FD164F4822077B028627CB568412A4A2E9931C24BAF6F01A5A7A85EC446A0E67002F55367249F74087A7015D2580009DA08CA0789265B4EE073185A0892AEB1BEEDD00265AD397F87AB4ED831E3702A562627584AA7A195CF453F70D56CF201F73D6AC01E934A32432464337A6599C97F7B61F04E198AC75AA77BD9FAD027B1C82FBB1E78DC641859D3CA7C7EF28F1A612AE1F41B9B360C3A96367D0F3B4BBB9E0F5EDFDFDCD2731510DFB728BD4688B62988D79CE39513524935E2A43E68EB7210093111D92C3683A7FAD835D2B2C86A8C173AA67CCFD59934234D5EB190F8AB93E9C1E0DBC92E3067
+20220715052452 2 6 100 6143 2 E258E7BF12F3DDA792F3E7480A3563579067E7CB60FB18E010DAC18E1AD5671C1E0B1CED8BCF199C52405B70A169CCDAE2B112117B67D54C6F892B1822DC08FACB88D9C1E424709E41932AB799392DA34E0D560B03C459B2208DDB99ECA51883F8BADB33EF313D908ADB72802512653760C2AE00320555606FC09B797CFF13219A102668C5DCF4248DEEB9B7C779A2AE009842942DAE4032491A233698B8BEC159904F8AC25D1E90454A45F786C433C843224D755DE28AC1CAD4E9736C6D4180BA705B607842915F257BBC730C733882911A8A51738DF20BA48EF64240646041BA8C6F3FDEDE140EC3AA3EBD710F5E12A3F5C50C2784FA32CB6E24CDFC621602E67C80DEB8347146AF1983C201E2B4A868B2DD61D079D41AD874F63E22B42101130C646F0217A74192C47B8A732F69DDE9C05ED4E2B7E3CCA501D687F1FAED478D3910BF3689DB3865574926D16FD3DED6561FDD8BA46FDE6121312E798A0CA83993CEEFECC033CB73442A2C954E8BD1C752BAAD8D074F6F6829E515446A8BA834CF7D08B3170721C1388BD55BC802011B9863B91C9B4DB305D881A503B918428569418BC0B2ECC7FC3F9F34B8F66C5EA842B4AB441AFD29FFE658AFE94BE0E9FD2E9743778DC58CBD1DD8DC7220A9D04944B032C6FC0DFA46BEE2D47AA5DC569F0945F72E7751EC0DD7F218CED8AEF74AA9A8864147C3A89B5C6217888C86C51C83FB77FB91B2F7C6BC0D2624192F33FA8891D897593FD164F4822077B028627CB568412A4A2E9931C24BAF6F01A5A7A85EC446A0E67002F55367249F74087A7015D2580009DA08CA0789265B4EE073185A0892AEB1BEEDD00265AD397F87AB4ED831E3702A562627584AA7A195CF453F70D56CF201F73D6AC01E934A32432464337A6599C97F7B61F04E198AC75AA77BD9FAD027B1C82FBB1E78DC641859D3CA7C7EF28F1A612AE1F41B9B360C3A96367D0F3B4BBB9E0F5EDFDFDCD2731510DFB728BD4688B62988D79CE39513524935E2A43E68EB7210093111D92C3683A7FAD835D2B2C86A8C173AA67CCFD59934234D5EB190F8AB93E9C1E0DBCA8D11CB
+20220715052700 2 6 100 6143 2 E258E7BF12F3DDA792F3E7480A3563579067E7CB60FB18E010DAC18E1AD5671C1E0B1CED8BCF199C52405B70A169CCDAE2B112117B67D54C6F892B1822DC08FACB88D9C1E424709E41932AB799392DA34E0D560B03C459B2208DDB99ECA51883F8BADB33EF313D908ADB72802512653760C2AE00320555606FC09B797CFF13219A102668C5DCF4248DEEB9B7C779A2AE009842942DAE4032491A233698B8BEC159904F8AC25D1E90454A45F786C433C843224D755DE28AC1CAD4E9736C6D4180BA705B607842915F257BBC730C733882911A8A51738DF20BA48EF64240646041BA8C6F3FDEDE140EC3AA3EBD710F5E12A3F5C50C2784FA32CB6E24CDFC621602E67C80DEB8347146AF1983C201E2B4A868B2DD61D079D41AD874F63E22B42101130C646F0217A74192C47B8A732F69DDE9C05ED4E2B7E3CCA501D687F1FAED478D3910BF3689DB3865574926D16FD3DED6561FDD8BA46FDE6121312E798A0CA83993CEEFECC033CB73442A2C954E8BD1C752BAAD8D074F6F6829E515446A8BA834CF7D08B3170721C1388BD55BC802011B9863B91C9B4DB305D881A503B918428569418BC0B2ECC7FC3F9F34B8F66C5EA842B4AB441AFD29FFE658AFE94BE0E9FD2E9743778DC58CBD1DD8DC7220A9D04944B032C6FC0DFA46BEE2D47AA5DC569F0945F72E7751EC0DD7F218CED8AEF74AA9A8864147C3A89B5C6217888C86C51C83FB77FB91B2F7C6BC0D2624192F33FA8891D897593FD164F4822077B028627CB568412A4A2E9931C24BAF6F01A5A7A85EC446A0E67002F55367249F74087A7015D2580009DA08CA0789265B4EE073185A0892AEB1BEEDD00265AD397F87AB4ED831E3702A562627584AA7A195CF453F70D56CF201F73D6AC01E934A32432464337A6599C97F7B61F04E198AC75AA77BD9FAD027B1C82FBB1E78DC641859D3CA7C7EF28F1A612AE1F41B9B360C3A96367D0F3B4BBB9E0F5EDFDFDCD2731510DFB728BD4688B62988D79CE39513524935E2A43E68EB7210093111D92C3683A7FAD835D2B2C86A8C173AA67CCFD59934234D5EB190F8AB93E9C1E0DBCAD7588B
+20220715053146 2 6 100 6143 5 E258E7BF12F3DDA792F3E7480A3563579067E7CB60FB18E010DAC18E1AD5671C1E0B1CED8BCF199C52405B70A169CCDAE2B112117B67D54C6F892B1822DC08FACB88D9C1E424709E41932AB799392DA34E0D560B03C459B2208DDB99ECA51883F8BADB33EF313D908ADB72802512653760C2AE00320555606FC09B797CFF13219A102668C5DCF4248DEEB9B7C779A2AE009842942DAE4032491A233698B8BEC159904F8AC25D1E90454A45F786C433C843224D755DE28AC1CAD4E9736C6D4180BA705B607842915F257BBC730C733882911A8A51738DF20BA48EF64240646041BA8C6F3FDEDE140EC3AA3EBD710F5E12A3F5C50C2784FA32CB6E24CDFC621602E67C80DEB8347146AF1983C201E2B4A868B2DD61D079D41AD874F63E22B42101130C646F0217A74192C47B8A732F69DDE9C05ED4E2B7E3CCA501D687F1FAED478D3910BF3689DB3865574926D16FD3DED6561FDD8BA46FDE6121312E798A0CA83993CEEFECC033CB73442A2C954E8BD1C752BAAD8D074F6F6829E515446A8BA834CF7D08B3170721C1388BD55BC802011B9863B91C9B4DB305D881A503B918428569418BC0B2ECC7FC3F9F34B8F66C5EA842B4AB441AFD29FFE658AFE94BE0E9FD2E9743778DC58CBD1DD8DC7220A9D04944B032C6FC0DFA46BEE2D47AA5DC569F0945F72E7751EC0DD7F218CED8AEF74AA9A8864147C3A89B5C6217888C86C51C83FB77FB91B2F7C6BC0D2624192F33FA8891D897593FD164F4822077B028627CB568412A4A2E9931C24BAF6F01A5A7A85EC446A0E67002F55367249F74087A7015D2580009DA08CA0789265B4EE073185A0892AEB1BEEDD00265AD397F87AB4ED831E3702A562627584AA7A195CF453F70D56CF201F73D6AC01E934A32432464337A6599C97F7B61F04E198AC75AA77BD9FAD027B1C82FBB1E78DC641859D3CA7C7EF28F1A612AE1F41B9B360C3A96367D0F3B4BBB9E0F5EDFDFDCD2731510DFB728BD4688B62988D79CE39513524935E2A43E68EB7210093111D92C3683A7FAD835D2B2C86A8C173AA67CCFD59934234D5EB190F8AB93E9C1E0DBCB7CEC27
+20220715061333 2 6 100 6143 2 E258E7BF12F3DDA792F3E7480A3563579067E7CB60FB18E010DAC18E1AD5671C1E0B1CED8BCF199C52405B70A169CCDAE2B112117B67D54C6F892B1822DC08FACB88D9C1E424709E41932AB799392DA34E0D560B03C459B2208DDB99ECA51883F8BADB33EF313D908ADB72802512653760C2AE00320555606FC09B797CFF13219A102668C5DCF4248DEEB9B7C779A2AE009842942DAE4032491A233698B8BEC159904F8AC25D1E90454A45F786C433C843224D755DE28AC1CAD4E9736C6D4180BA705B607842915F257BBC730C733882911A8A51738DF20BA48EF64240646041BA8C6F3FDEDE140EC3AA3EBD710F5E12A3F5C50C2784FA32CB6E24CDFC621602E67C80DEB8347146AF1983C201E2B4A868B2DD61D079D41AD874F63E22B42101130C646F0217A74192C47B8A732F69DDE9C05ED4E2B7E3CCA501D687F1FAED478D3910BF3689DB3865574926D16FD3DED6561FDD8BA46FDE6121312E798A0CA83993CEEFECC033CB73442A2C954E8BD1C752BAAD8D074F6F6829E515446A8BA834CF7D08B3170721C1388BD55BC802011B9863B91C9B4DB305D881A503B918428569418BC0B2ECC7FC3F9F34B8F66C5EA842B4AB441AFD29FFE658AFE94BE0E9FD2E9743778DC58CBD1DD8DC7220A9D04944B032C6FC0DFA46BEE2D47AA5DC569F0945F72E7751EC0DD7F218CED8AEF74AA9A8864147C3A89B5C6217888C86C51C83FB77FB91B2F7C6BC0D2624192F33FA8891D897593FD164F4822077B028627CB568412A4A2E9931C24BAF6F01A5A7A85EC446A0E67002F55367249F74087A7015D2580009DA08CA0789265B4EE073185A0892AEB1BEEDD00265AD397F87AB4ED831E3702A562627584AA7A195CF453F70D56CF201F73D6AC01E934A32432464337A6599C97F7B61F04E198AC75AA77BD9FAD027B1C82FBB1E78DC641859D3CA7C7EF28F1A612AE1F41B9B360C3A96367D0F3B4BBB9E0F5EDFDFDCD2731510DFB728BD4688B62988D79CE39513524935E2A43E68EB7210093111D92C3683A7FAD835D2B2C86A8C173AA67CCFD59934234D5EB190F8AB93E9C1E0DBD12F317B
+20220715063310 2 6 100 6143 5 E258E7BF12F3DDA792F3E7480A3563579067E7CB60FB18E010DAC18E1AD5671C1E0B1CED8BCF199C52405B70A169CCDAE2B112117B67D54C6F892B1822DC08FACB88D9C1E424709E41932AB799392DA34E0D560B03C459B2208DDB99ECA51883F8BADB33EF313D908ADB72802512653760C2AE00320555606FC09B797CFF13219A102668C5DCF4248DEEB9B7C779A2AE009842942DAE4032491A233698B8BEC159904F8AC25D1E90454A45F786C433C843224D755DE28AC1CAD4E9736C6D4180BA705B607842915F257BBC730C733882911A8A51738DF20BA48EF64240646041BA8C6F3FDEDE140EC3AA3EBD710F5E12A3F5C50C2784FA32CB6E24CDFC621602E67C80DEB8347146AF1983C201E2B4A868B2DD61D079D41AD874F63E22B42101130C646F0217A74192C47B8A732F69DDE9C05ED4E2B7E3CCA501D687F1FAED478D3910BF3689DB3865574926D16FD3DED6561FDD8BA46FDE6121312E798A0CA83993CEEFECC033CB73442A2C954E8BD1C752BAAD8D074F6F6829E515446A8BA834CF7D08B3170721C1388BD55BC802011B9863B91C9B4DB305D881A503B918428569418BC0B2ECC7FC3F9F34B8F66C5EA842B4AB441AFD29FFE658AFE94BE0E9FD2E9743778DC58CBD1DD8DC7220A9D04944B032C6FC0DFA46BEE2D47AA5DC569F0945F72E7751EC0DD7F218CED8AEF74AA9A8864147C3A89B5C6217888C86C51C83FB77FB91B2F7C6BC0D2624192F33FA8891D897593FD164F4822077B028627CB568412A4A2E9931C24BAF6F01A5A7A85EC446A0E67002F55367249F74087A7015D2580009DA08CA0789265B4EE073185A0892AEB1BEEDD00265AD397F87AB4ED831E3702A562627584AA7A195CF453F70D56CF201F73D6AC01E934A32432464337A6599C97F7B61F04E198AC75AA77BD9FAD027B1C82FBB1E78DC641859D3CA7C7EF28F1A612AE1F41B9B360C3A96367D0F3B4BBB9E0F5EDFDFDCD2731510DFB728BD4688B62988D79CE39513524935E2A43E68EB7210093111D92C3683A7FAD835D2B2C86A8C173AA67CCFD59934234D5EB190F8AB93E9C1E0DBD3D846E7
+20220715071637 2 6 100 6143 5 E258E7BF12F3DDA792F3E7480A3563579067E7CB60FB18E010DAC18E1AD5671C1E0B1CED8BCF199C52405B70A169CCDAE2B112117B67D54C6F892B1822DC08FACB88D9C1E424709E41932AB799392DA34E0D560B03C459B2208DDB99ECA51883F8BADB33EF313D908ADB72802512653760C2AE00320555606FC09B797CFF13219A102668C5DCF4248DEEB9B7C779A2AE009842942DAE4032491A233698B8BEC159904F8AC25D1E90454A45F786C433C843224D755DE28AC1CAD4E9736C6D4180BA705B607842915F257BBC730C733882911A8A51738DF20BA48EF64240646041BA8C6F3FDEDE140EC3AA3EBD710F5E12A3F5C50C2784FA32CB6E24CDFC621602E67C80DEB8347146AF1983C201E2B4A868B2DD61D079D41AD874F63E22B42101130C646F0217A74192C47B8A732F69DDE9C05ED4E2B7E3CCA501D687F1FAED478D3910BF3689DB3865574926D16FD3DED6561FDD8BA46FDE6121312E798A0CA83993CEEFECC033CB73442A2C954E8BD1C752BAAD8D074F6F6829E515446A8BA834CF7D08B3170721C1388BD55BC802011B9863B91C9B4DB305D881A503B918428569418BC0B2ECC7FC3F9F34B8F66C5EA842B4AB441AFD29FFE658AFE94BE0E9FD2E9743778DC58CBD1DD8DC7220A9D04944B032C6FC0DFA46BEE2D47AA5DC569F0945F72E7751EC0DD7F218CED8AEF74AA9A8864147C3A89B5C6217888C86C51C83FB77FB91B2F7C6BC0D2624192F33FA8891D897593FD164F4822077B028627CB568412A4A2E9931C24BAF6F01A5A7A85EC446A0E67002F55367249F74087A7015D2580009DA08CA0789265B4EE073185A0892AEB1BEEDD00265AD397F87AB4ED831E3702A562627584AA7A195CF453F70D56CF201F73D6AC01E934A32432464337A6599C97F7B61F04E198AC75AA77BD9FAD027B1C82FBB1E78DC641859D3CA7C7EF28F1A612AE1F41B9B360C3A96367D0F3B4BBB9E0F5EDFDFDCD2731510DFB728BD4688B62988D79CE39513524935E2A43E68EB7210093111D92C3683A7FAD835D2B2C86A8C173AA67CCFD59934234D5EB190F8AB93E9C1E0DBD9B91D57
+20220715074108 2 6 100 6143 2 E258E7BF12F3DDA792F3E7480A3563579067E7CB60FB18E010DAC18E1AD5671C1E0B1CED8BCF199C52405B70A169CCDAE2B112117B67D54C6F892B1822DC08FACB88D9C1E424709E41932AB799392DA34E0D560B03C459B2208DDB99ECA51883F8BADB33EF313D908ADB72802512653760C2AE00320555606FC09B797CFF13219A102668C5DCF4248DEEB9B7C779A2AE009842942DAE4032491A233698B8BEC159904F8AC25D1E90454A45F786C433C843224D755DE28AC1CAD4E9736C6D4180BA705B607842915F257BBC730C733882911A8A51738DF20BA48EF64240646041BA8C6F3FDEDE140EC3AA3EBD710F5E12A3F5C50C2784FA32CB6E24CDFC621602E67C80DEB8347146AF1983C201E2B4A868B2DD61D079D41AD874F63E22B42101130C646F0217A74192C47B8A732F69DDE9C05ED4E2B7E3CCA501D687F1FAED478D3910BF3689DB3865574926D16FD3DED6561FDD8BA46FDE6121312E798A0CA83993CEEFECC033CB73442A2C954E8BD1C752BAAD8D074F6F6829E515446A8BA834CF7D08B3170721C1388BD55BC802011B9863B91C9B4DB305D881A503B918428569418BC0B2ECC7FC3F9F34B8F66C5EA842B4AB441AFD29FFE658AFE94BE0E9FD2E9743778DC58CBD1DD8DC7220A9D04944B032C6FC0DFA46BEE2D47AA5DC569F0945F72E7751EC0DD7F218CED8AEF74AA9A8864147C3A89B5C6217888C86C51C83FB77FB91B2F7C6BC0D2624192F33FA8891D897593FD164F4822077B028627CB568412A4A2E9931C24BAF6F01A5A7A85EC446A0E67002F55367249F74087A7015D2580009DA08CA0789265B4EE073185A0892AEB1BEEDD00265AD397F87AB4ED831E3702A562627584AA7A195CF453F70D56CF201F73D6AC01E934A32432464337A6599C97F7B61F04E198AC75AA77BD9FAD027B1C82FBB1E78DC641859D3CA7C7EF28F1A612AE1F41B9B360C3A96367D0F3B4BBB9E0F5EDFDFDCD2731510DFB728BD4688B62988D79CE39513524935E2A43E68EB7210093111D92C3683A7FAD835D2B2C86A8C173AA67CCFD59934234D5EB190F8AB93E9C1E0DBDCFB3DEB
+20220715074918 2 6 100 6143 5 E258E7BF12F3DDA792F3E7480A3563579067E7CB60FB18E010DAC18E1AD5671C1E0B1CED8BCF199C52405B70A169CCDAE2B112117B67D54C6F892B1822DC08FACB88D9C1E424709E41932AB799392DA34E0D560B03C459B2208DDB99ECA51883F8BADB33EF313D908ADB72802512653760C2AE00320555606FC09B797CFF13219A102668C5DCF4248DEEB9B7C779A2AE009842942DAE4032491A233698B8BEC159904F8AC25D1E90454A45F786C433C843224D755DE28AC1CAD4E9736C6D4180BA705B607842915F257BBC730C733882911A8A51738DF20BA48EF64240646041BA8C6F3FDEDE140EC3AA3EBD710F5E12A3F5C50C2784FA32CB6E24CDFC621602E67C80DEB8347146AF1983C201E2B4A868B2DD61D079D41AD874F63E22B42101130C646F0217A74192C47B8A732F69DDE9C05ED4E2B7E3CCA501D687F1FAED478D3910BF3689DB3865574926D16FD3DED6561FDD8BA46FDE6121312E798A0CA83993CEEFECC033CB73442A2C954E8BD1C752BAAD8D074F6F6829E515446A8BA834CF7D08B3170721C1388BD55BC802011B9863B91C9B4DB305D881A503B918428569418BC0B2ECC7FC3F9F34B8F66C5EA842B4AB441AFD29FFE658AFE94BE0E9FD2E9743778DC58CBD1DD8DC7220A9D04944B032C6FC0DFA46BEE2D47AA5DC569F0945F72E7751EC0DD7F218CED8AEF74AA9A8864147C3A89B5C6217888C86C51C83FB77FB91B2F7C6BC0D2624192F33FA8891D897593FD164F4822077B028627CB568412A4A2E9931C24BAF6F01A5A7A85EC446A0E67002F55367249F74087A7015D2580009DA08CA0789265B4EE073185A0892AEB1BEEDD00265AD397F87AB4ED831E3702A562627584AA7A195CF453F70D56CF201F73D6AC01E934A32432464337A6599C97F7B61F04E198AC75AA77BD9FAD027B1C82FBB1E78DC641859D3CA7C7EF28F1A612AE1F41B9B360C3A96367D0F3B4BBB9E0F5EDFDFDCD2731510DFB728BD4688B62988D79CE39513524935E2A43E68EB7210093111D92C3683A7FAD835D2B2C86A8C173AA67CCFD59934234D5EB190F8AB93E9C1E0DBDE19622F
+20220715080656 2 6 100 6143 5 E258E7BF12F3DDA792F3E7480A3563579067E7CB60FB18E010DAC18E1AD5671C1E0B1CED8BCF199C52405B70A169CCDAE2B112117B67D54C6F892B1822DC08FACB88D9C1E424709E41932AB799392DA34E0D560B03C459B2208DDB99ECA51883F8BADB33EF313D908ADB72802512653760C2AE00320555606FC09B797CFF13219A102668C5DCF4248DEEB9B7C779A2AE009842942DAE4032491A233698B8BEC159904F8AC25D1E90454A45F786C433C843224D755DE28AC1CAD4E9736C6D4180BA705B607842915F257BBC730C733882911A8A51738DF20BA48EF64240646041BA8C6F3FDEDE140EC3AA3EBD710F5E12A3F5C50C2784FA32CB6E24CDFC621602E67C80DEB8347146AF1983C201E2B4A868B2DD61D079D41AD874F63E22B42101130C646F0217A74192C47B8A732F69DDE9C05ED4E2B7E3CCA501D687F1FAED478D3910BF3689DB3865574926D16FD3DED6561FDD8BA46FDE6121312E798A0CA83993CEEFECC033CB73442A2C954E8BD1C752BAAD8D074F6F6829E515446A8BA834CF7D08B3170721C1388BD55BC802011B9863B91C9B4DB305D881A503B918428569418BC0B2ECC7FC3F9F34B8F66C5EA842B4AB441AFD29FFE658AFE94BE0E9FD2E9743778DC58CBD1DD8DC7220A9D04944B032C6FC0DFA46BEE2D47AA5DC569F0945F72E7751EC0DD7F218CED8AEF74AA9A8864147C3A89B5C6217888C86C51C83FB77FB91B2F7C6BC0D2624192F33FA8891D897593FD164F4822077B028627CB568412A4A2E9931C24BAF6F01A5A7A85EC446A0E67002F55367249F74087A7015D2580009DA08CA0789265B4EE073185A0892AEB1BEEDD00265AD397F87AB4ED831E3702A562627584AA7A195CF453F70D56CF201F73D6AC01E934A32432464337A6599C97F7B61F04E198AC75AA77BD9FAD027B1C82FBB1E78DC641859D3CA7C7EF28F1A612AE1F41B9B360C3A96367D0F3B4BBB9E0F5EDFDFDCD2731510DFB728BD4688B62988D79CE39513524935E2A43E68EB7210093111D92C3683A7FAD835D2B2C86A8C173AA67CCFD59934234D5EB190F8AB93E9C1E0DBE07CF9D7
+20220715083930 2 6 100 6143 2 E258E7BF12F3DDA792F3E7480A3563579067E7CB60FB18E010DAC18E1AD5671C1E0B1CED8BCF199C52405B70A169CCDAE2B112117B67D54C6F892B1822DC08FACB88D9C1E424709E41932AB799392DA34E0D560B03C459B2208DDB99ECA51883F8BADB33EF313D908ADB72802512653760C2AE00320555606FC09B797CFF13219A102668C5DCF4248DEEB9B7C779A2AE009842942DAE4032491A233698B8BEC159904F8AC25D1E90454A45F786C433C843224D755DE28AC1CAD4E9736C6D4180BA705B607842915F257BBC730C733882911A8A51738DF20BA48EF64240646041BA8C6F3FDEDE140EC3AA3EBD710F5E12A3F5C50C2784FA32CB6E24CDFC621602E67C80DEB8347146AF1983C201E2B4A868B2DD61D079D41AD874F63E22B42101130C646F0217A74192C47B8A732F69DDE9C05ED4E2B7E3CCA501D687F1FAED478D3910BF3689DB3865574926D16FD3DED6561FDD8BA46FDE6121312E798A0CA83993CEEFECC033CB73442A2C954E8BD1C752BAAD8D074F6F6829E515446A8BA834CF7D08B3170721C1388BD55BC802011B9863B91C9B4DB305D881A503B918428569418BC0B2ECC7FC3F9F34B8F66C5EA842B4AB441AFD29FFE658AFE94BE0E9FD2E9743778DC58CBD1DD8DC7220A9D04944B032C6FC0DFA46BEE2D47AA5DC569F0945F72E7751EC0DD7F218CED8AEF74AA9A8864147C3A89B5C6217888C86C51C83FB77FB91B2F7C6BC0D2624192F33FA8891D897593FD164F4822077B028627CB568412A4A2E9931C24BAF6F01A5A7A85EC446A0E67002F55367249F74087A7015D2580009DA08CA0789265B4EE073185A0892AEB1BEEDD00265AD397F87AB4ED831E3702A562627584AA7A195CF453F70D56CF201F73D6AC01E934A32432464337A6599C97F7B61F04E198AC75AA77BD9FAD027B1C82FBB1E78DC641859D3CA7C7EF28F1A612AE1F41B9B360C3A96367D0F3B4BBB9E0F5EDFDFDCD2731510DFB728BD4688B62988D79CE39513524935E2A43E68EB7210093111D92C3683A7FAD835D2B2C86A8C173AA67CCFD59934234D5EB190F8AB93E9C1E0DBE4E93003
+20220715092424 2 6 100 7679 5 D29885507D691EF92591A09643ED996F7CBCB7BC2C100AB3FEF5257A5931CC62D6E976C8702F99622C00702F7A97A8DF2C58E6CE1B087955544A6F08E64CC55AE62AB2F2ACA5CCAAC3FB093CC1D0CD964316B4E10C149B72EF468C7D57DC47980B0B4682B79EA3DB224C5E13BA7B8B0CD8C26BD8E884F0A96B77ED42A749A4556C14B417241BFD807B6B985F8474D53AB3002E46E860DA6AF2FC4387C33540FE64DBA835028710E1A8EB05307283DFA15CB67282334BFFF511D4B6284C18620B0F64A87E026EE576D0C201314CB24FE513DDA9AC0747065B315BAEB2D7AC801CE819708A224840C3C2C23F34DAEF1BED28091CB489EBC99E7B89A285ADC47D3DE4DDB71A5EE4184A642FF8E3E1E67536F7534C67D2A196319B597D7A7A4B2B7D852613818A51FF6CE7D1DF0161AD5F06FFD764F0026354A1CB946F03E37C14F7DD98A9F59A7493F2869AAE39AF064F81DEBF3C94A082CCDA26F5C03367BDA1D1975B5E08CD7E91F02D3537EABB4D98B36D7DAD24C7CB36C850148CD911BA89585653F5B582A23C459A78515E3FC5851B08F8EC2E68736BD7488DC5C73FE40A61DC7F4581C95E20E70E7ECB010365B89CD233A8175A4CE862770D5126AB0E606CD8030490E3B1B05EB3F094B8246259D9A9A84434D02A173F37A9FB883844BFBEE307790649463C4EDE0F1F68D9B61C50004E5F38913D160D5AD214A2C1D85E985A288316951FE89FB77890C1BC16B2DE9920803C9BD746373B0D1F42F829083BC4725EA573509AB8F9DAF3BC3309B4B4A29A8A37023A53B7B73B5DD172809329DC7A966953C30A6A0824EEE510657CEC1F93A9C3CD21D58E8B04B4C877AB6D13D575D206D90ED601E9BB8244944A941CFD382806CF5774E6A61502A63AEB74769B80D65D155FC1F5AD9177C81326DC157750D3B8BB75CF52CD21382BE99983F5AD520351166A4B83A7F2BD8D2EFB143492246F2BAF9247839FDCB947E1EB162E2FB8CD4248DEFCD728929684C6F0DF72F25837EC2A7E23064B9FC38590988B79A5FC925B6E7564167CEE374D24FEB1CF59AD5FF37A65BCBAAE9961DFC805E49EDB3DF6001C2EBBC868E9B4A46AB2BF6D9F060D85E965DB7C5D9E5F4DE5677C1A127A26FFE12C57FCA2ED7A950C89B1CAD3C4E5E279C6D197DAC5300051BDF4A05C2FC76E57F3A7362F145C651AFC9AEBB962A3D7D1FAD0DBFAC833B968DE988A4FC799CE55479D89E5F64A2DBE6102926E49661A000A0B0BD49DE7826EEFC0638DE10DB3E68591FFEDA521BE4A6C5447406B293866292CFAB1CE3E68AED693F1D3EB9EE521962ECA88D7D2629FD9DA3E324C131AFB78B5C41831FF5F92A52BAF
+20220715100057 2 6 100 7679 5 D29885507D691EF92591A09643ED996F7CBCB7BC2C100AB3FEF5257A5931CC62D6E976C8702F99622C00702F7A97A8DF2C58E6CE1B087955544A6F08E64CC55AE62AB2F2ACA5CCAAC3FB093CC1D0CD964316B4E10C149B72EF468C7D57DC47980B0B4682B79EA3DB224C5E13BA7B8B0CD8C26BD8E884F0A96B77ED42A749A4556C14B417241BFD807B6B985F8474D53AB3002E46E860DA6AF2FC4387C33540FE64DBA835028710E1A8EB05307283DFA15CB67282334BFFF511D4B6284C18620B0F64A87E026EE576D0C201314CB24FE513DDA9AC0747065B315BAEB2D7AC801CE819708A224840C3C2C23F34DAEF1BED28091CB489EBC99E7B89A285ADC47D3DE4DDB71A5EE4184A642FF8E3E1E67536F7534C67D2A196319B597D7A7A4B2B7D852613818A51FF6CE7D1DF0161AD5F06FFD764F0026354A1CB946F03E37C14F7DD98A9F59A7493F2869AAE39AF064F81DEBF3C94A082CCDA26F5C03367BDA1D1975B5E08CD7E91F02D3537EABB4D98B36D7DAD24C7CB36C850148CD911BA89585653F5B582A23C459A78515E3FC5851B08F8EC2E68736BD7488DC5C73FE40A61DC7F4581C95E20E70E7ECB010365B89CD233A8175A4CE862770D5126AB0E606CD8030490E3B1B05EB3F094B8246259D9A9A84434D02A173F37A9FB883844BFBEE307790649463C4EDE0F1F68D9B61C50004E5F38913D160D5AD214A2C1D85E985A288316951FE89FB77890C1BC16B2DE9920803C9BD746373B0D1F42F829083BC4725EA573509AB8F9DAF3BC3309B4B4A29A8A37023A53B7B73B5DD172809329DC7A966953C30A6A0824EEE510657CEC1F93A9C3CD21D58E8B04B4C877AB6D13D575D206D90ED601E9BB8244944A941CFD382806CF5774E6A61502A63AEB74769B80D65D155FC1F5AD9177C81326DC157750D3B8BB75CF52CD21382BE99983F5AD520351166A4B83A7F2BD8D2EFB143492246F2BAF9247839FDCB947E1EB162E2FB8CD4248DEFCD728929684C6F0DF72F25837EC2A7E23064B9FC38590988B79A5FC925B6E7564167CEE374D24FEB1CF59AD5FF37A65BCBAAE9961DFC805E49EDB3DF6001C2EBBC868E9B4A46AB2BF6D9F060D85E965DB7C5D9E5F4DE5677C1A127A26FFE12C57FCA2ED7A950C89B1CAD3C4E5E279C6D197DAC5300051BDF4A05C2FC76E57F3A7362F145C651AFC9AEBB962A3D7D1FAD0DBFAC833B968DE988A4FC799CE55479D89E5F64A2DBE6102926E49661A000A0B0BD49DE7826EEFC0638DE10DB3E68591FFEDA521BE4A6C5447406B293866292CFAB1CE3E68AED693F1D3EB9EE521962ECA88D7D2629FD9DA3E324C131AFB78B5C41831FF5F9547AC47
+20220715100859 2 6 100 7679 2 D29885507D691EF92591A09643ED996F7CBCB7BC2C100AB3FEF5257A5931CC62D6E976C8702F99622C00702F7A97A8DF2C58E6CE1B087955544A6F08E64CC55AE62AB2F2ACA5CCAAC3FB093CC1D0CD964316B4E10C149B72EF468C7D57DC47980B0B4682B79EA3DB224C5E13BA7B8B0CD8C26BD8E884F0A96B77ED42A749A4556C14B417241BFD807B6B985F8474D53AB3002E46E860DA6AF2FC4387C33540FE64DBA835028710E1A8EB05307283DFA15CB67282334BFFF511D4B6284C18620B0F64A87E026EE576D0C201314CB24FE513DDA9AC0747065B315BAEB2D7AC801CE819708A224840C3C2C23F34DAEF1BED28091CB489EBC99E7B89A285ADC47D3DE4DDB71A5EE4184A642FF8E3E1E67536F7534C67D2A196319B597D7A7A4B2B7D852613818A51FF6CE7D1DF0161AD5F06FFD764F0026354A1CB946F03E37C14F7DD98A9F59A7493F2869AAE39AF064F81DEBF3C94A082CCDA26F5C03367BDA1D1975B5E08CD7E91F02D3537EABB4D98B36D7DAD24C7CB36C850148CD911BA89585653F5B582A23C459A78515E3FC5851B08F8EC2E68736BD7488DC5C73FE40A61DC7F4581C95E20E70E7ECB010365B89CD233A8175A4CE862770D5126AB0E606CD8030490E3B1B05EB3F094B8246259D9A9A84434D02A173F37A9FB883844BFBEE307790649463C4EDE0F1F68D9B61C50004E5F38913D160D5AD214A2C1D85E985A288316951FE89FB77890C1BC16B2DE9920803C9BD746373B0D1F42F829083BC4725EA573509AB8F9DAF3BC3309B4B4A29A8A37023A53B7B73B5DD172809329DC7A966953C30A6A0824EEE510657CEC1F93A9C3CD21D58E8B04B4C877AB6D13D575D206D90ED601E9BB8244944A941CFD382806CF5774E6A61502A63AEB74769B80D65D155FC1F5AD9177C81326DC157750D3B8BB75CF52CD21382BE99983F5AD520351166A4B83A7F2BD8D2EFB143492246F2BAF9247839FDCB947E1EB162E2FB8CD4248DEFCD728929684C6F0DF72F25837EC2A7E23064B9FC38590988B79A5FC925B6E7564167CEE374D24FEB1CF59AD5FF37A65BCBAAE9961DFC805E49EDB3DF6001C2EBBC868E9B4A46AB2BF6D9F060D85E965DB7C5D9E5F4DE5677C1A127A26FFE12C57FCA2ED7A950C89B1CAD3C4E5E279C6D197DAC5300051BDF4A05C2FC76E57F3A7362F145C651AFC9AEBB962A3D7D1FAD0DBFAC833B968DE988A4FC799CE55479D89E5F64A2DBE6102926E49661A000A0B0BD49DE7826EEFC0638DE10DB3E68591FFEDA521BE4A6C5447406B293866292CFAB1CE3E68AED693F1D3EB9EE521962ECA88D7D2629FD9DA3E324C131AFB78B5C41831FF5F95DC0013
+20220715102100 2 6 100 7679 2 D29885507D691EF92591A09643ED996F7CBCB7BC2C100AB3FEF5257A5931CC62D6E976C8702F99622C00702F7A97A8DF2C58E6CE1B087955544A6F08E64CC55AE62AB2F2ACA5CCAAC3FB093CC1D0CD964316B4E10C149B72EF468C7D57DC47980B0B4682B79EA3DB224C5E13BA7B8B0CD8C26BD8E884F0A96B77ED42A749A4556C14B417241BFD807B6B985F8474D53AB3002E46E860DA6AF2FC4387C33540FE64DBA835028710E1A8EB05307283DFA15CB67282334BFFF511D4B6284C18620B0F64A87E026EE576D0C201314CB24FE513DDA9AC0747065B315BAEB2D7AC801CE819708A224840C3C2C23F34DAEF1BED28091CB489EBC99E7B89A285ADC47D3DE4DDB71A5EE4184A642FF8E3E1E67536F7534C67D2A196319B597D7A7A4B2B7D852613818A51FF6CE7D1DF0161AD5F06FFD764F0026354A1CB946F03E37C14F7DD98A9F59A7493F2869AAE39AF064F81DEBF3C94A082CCDA26F5C03367BDA1D1975B5E08CD7E91F02D3537EABB4D98B36D7DAD24C7CB36C850148CD911BA89585653F5B582A23C459A78515E3FC5851B08F8EC2E68736BD7488DC5C73FE40A61DC7F4581C95E20E70E7ECB010365B89CD233A8175A4CE862770D5126AB0E606CD8030490E3B1B05EB3F094B8246259D9A9A84434D02A173F37A9FB883844BFBEE307790649463C4EDE0F1F68D9B61C50004E5F38913D160D5AD214A2C1D85E985A288316951FE89FB77890C1BC16B2DE9920803C9BD746373B0D1F42F829083BC4725EA573509AB8F9DAF3BC3309B4B4A29A8A37023A53B7B73B5DD172809329DC7A966953C30A6A0824EEE510657CEC1F93A9C3CD21D58E8B04B4C877AB6D13D575D206D90ED601E9BB8244944A941CFD382806CF5774E6A61502A63AEB74769B80D65D155FC1F5AD9177C81326DC157750D3B8BB75CF52CD21382BE99983F5AD520351166A4B83A7F2BD8D2EFB143492246F2BAF9247839FDCB947E1EB162E2FB8CD4248DEFCD728929684C6F0DF72F25837EC2A7E23064B9FC38590988B79A5FC925B6E7564167CEE374D24FEB1CF59AD5FF37A65BCBAAE9961DFC805E49EDB3DF6001C2EBBC868E9B4A46AB2BF6D9F060D85E965DB7C5D9E5F4DE5677C1A127A26FFE12C57FCA2ED7A950C89B1CAD3C4E5E279C6D197DAC5300051BDF4A05C2FC76E57F3A7362F145C651AFC9AEBB962A3D7D1FAD0DBFAC833B968DE988A4FC799CE55479D89E5F64A2DBE6102926E49661A000A0B0BD49DE7826EEFC0638DE10DB3E68591FFEDA521BE4A6C5447406B293866292CFAB1CE3E68AED693F1D3EB9EE521962ECA88D7D2629FD9DA3E324C131AFB78B5C41831FF5F96B85E23
+20220715132304 2 6 100 7679 2 D29885507D691EF92591A09643ED996F7CBCB7BC2C100AB3FEF5257A5931CC62D6E976C8702F99622C00702F7A97A8DF2C58E6CE1B087955544A6F08E64CC55AE62AB2F2ACA5CCAAC3FB093CC1D0CD964316B4E10C149B72EF468C7D57DC47980B0B4682B79EA3DB224C5E13BA7B8B0CD8C26BD8E884F0A96B77ED42A749A4556C14B417241BFD807B6B985F8474D53AB3002E46E860DA6AF2FC4387C33540FE64DBA835028710E1A8EB05307283DFA15CB67282334BFFF511D4B6284C18620B0F64A87E026EE576D0C201314CB24FE513DDA9AC0747065B315BAEB2D7AC801CE819708A224840C3C2C23F34DAEF1BED28091CB489EBC99E7B89A285ADC47D3DE4DDB71A5EE4184A642FF8E3E1E67536F7534C67D2A196319B597D7A7A4B2B7D852613818A51FF6CE7D1DF0161AD5F06FFD764F0026354A1CB946F03E37C14F7DD98A9F59A7493F2869AAE39AF064F81DEBF3C94A082CCDA26F5C03367BDA1D1975B5E08CD7E91F02D3537EABB4D98B36D7DAD24C7CB36C850148CD911BA89585653F5B582A23C459A78515E3FC5851B08F8EC2E68736BD7488DC5C73FE40A61DC7F4581C95E20E70E7ECB010365B89CD233A8175A4CE862770D5126AB0E606CD8030490E3B1B05EB3F094B8246259D9A9A84434D02A173F37A9FB883844BFBEE307790649463C4EDE0F1F68D9B61C50004E5F38913D160D5AD214A2C1D85E985A288316951FE89FB77890C1BC16B2DE9920803C9BD746373B0D1F42F829083BC4725EA573509AB8F9DAF3BC3309B4B4A29A8A37023A53B7B73B5DD172809329DC7A966953C30A6A0824EEE510657CEC1F93A9C3CD21D58E8B04B4C877AB6D13D575D206D90ED601E9BB8244944A941CFD382806CF5774E6A61502A63AEB74769B80D65D155FC1F5AD9177C81326DC157750D3B8BB75CF52CD21382BE99983F5AD520351166A4B83A7F2BD8D2EFB143492246F2BAF9247839FDCB947E1EB162E2FB8CD4248DEFCD728929684C6F0DF72F25837EC2A7E23064B9FC38590988B79A5FC925B6E7564167CEE374D24FEB1CF59AD5FF37A65BCBAAE9961DFC805E49EDB3DF6001C2EBBC868E9B4A46AB2BF6D9F060D85E965DB7C5D9E5F4DE5677C1A127A26FFE12C57FCA2ED7A950C89B1CAD3C4E5E279C6D197DAC5300051BDF4A05C2FC76E57F3A7362F145C651AFC9AEBB962A3D7D1FAD0DBFAC833B968DE988A4FC799CE55479D89E5F64A2DBE6102926E49661A000A0B0BD49DE7826EEFC0638DE10DB3E68591FFEDA521BE4A6C5447406B293866292CFAB1CE3E68AED693F1D3EB9EE521962ECA88D7D2629FD9DA3E324C131AFB78B5C41831FF5FA3BD9C93
+20220715133936 2 6 100 7679 5 D29885507D691EF92591A09643ED996F7CBCB7BC2C100AB3FEF5257A5931CC62D6E976C8702F99622C00702F7A97A8DF2C58E6CE1B087955544A6F08E64CC55AE62AB2F2ACA5CCAAC3FB093CC1D0CD964316B4E10C149B72EF468C7D57DC47980B0B4682B79EA3DB224C5E13BA7B8B0CD8C26BD8E884F0A96B77ED42A749A4556C14B417241BFD807B6B985F8474D53AB3002E46E860DA6AF2FC4387C33540FE64DBA835028710E1A8EB05307283DFA15CB67282334BFFF511D4B6284C18620B0F64A87E026EE576D0C201314CB24FE513DDA9AC0747065B315BAEB2D7AC801CE819708A224840C3C2C23F34DAEF1BED28091CB489EBC99E7B89A285ADC47D3DE4DDB71A5EE4184A642FF8E3E1E67536F7534C67D2A196319B597D7A7A4B2B7D852613818A51FF6CE7D1DF0161AD5F06FFD764F0026354A1CB946F03E37C14F7DD98A9F59A7493F2869AAE39AF064F81DEBF3C94A082CCDA26F5C03367BDA1D1975B5E08CD7E91F02D3537EABB4D98B36D7DAD24C7CB36C850148CD911BA89585653F5B582A23C459A78515E3FC5851B08F8EC2E68736BD7488DC5C73FE40A61DC7F4581C95E20E70E7ECB010365B89CD233A8175A4CE862770D5126AB0E606CD8030490E3B1B05EB3F094B8246259D9A9A84434D02A173F37A9FB883844BFBEE307790649463C4EDE0F1F68D9B61C50004E5F38913D160D5AD214A2C1D85E985A288316951FE89FB77890C1BC16B2DE9920803C9BD746373B0D1F42F829083BC4725EA573509AB8F9DAF3BC3309B4B4A29A8A37023A53B7B73B5DD172809329DC7A966953C30A6A0824EEE510657CEC1F93A9C3CD21D58E8B04B4C877AB6D13D575D206D90ED601E9BB8244944A941CFD382806CF5774E6A61502A63AEB74769B80D65D155FC1F5AD9177C81326DC157750D3B8BB75CF52CD21382BE99983F5AD520351166A4B83A7F2BD8D2EFB143492246F2BAF9247839FDCB947E1EB162E2FB8CD4248DEFCD728929684C6F0DF72F25837EC2A7E23064B9FC38590988B79A5FC925B6E7564167CEE374D24FEB1CF59AD5FF37A65BCBAAE9961DFC805E49EDB3DF6001C2EBBC868E9B4A46AB2BF6D9F060D85E965DB7C5D9E5F4DE5677C1A127A26FFE12C57FCA2ED7A950C89B1CAD3C4E5E279C6D197DAC5300051BDF4A05C2FC76E57F3A7362F145C651AFC9AEBB962A3D7D1FAD0DBFAC833B968DE988A4FC799CE55479D89E5F64A2DBE6102926E49661A000A0B0BD49DE7826EEFC0638DE10DB3E68591FFEDA521BE4A6C5447406B293866292CFAB1CE3E68AED693F1D3EB9EE521962ECA88D7D2629FD9DA3E324C131AFB78B5C41831FF5FA4ECF027
+20220715140222 2 6 100 7679 2 D29885507D691EF92591A09643ED996F7CBCB7BC2C100AB3FEF5257A5931CC62D6E976C8702F99622C00702F7A97A8DF2C58E6CE1B087955544A6F08E64CC55AE62AB2F2ACA5CCAAC3FB093CC1D0CD964316B4E10C149B72EF468C7D57DC47980B0B4682B79EA3DB224C5E13BA7B8B0CD8C26BD8E884F0A96B77ED42A749A4556C14B417241BFD807B6B985F8474D53AB3002E46E860DA6AF2FC4387C33540FE64DBA835028710E1A8EB05307283DFA15CB67282334BFFF511D4B6284C18620B0F64A87E026EE576D0C201314CB24FE513DDA9AC0747065B315BAEB2D7AC801CE819708A224840C3C2C23F34DAEF1BED28091CB489EBC99E7B89A285ADC47D3DE4DDB71A5EE4184A642FF8E3E1E67536F7534C67D2A196319B597D7A7A4B2B7D852613818A51FF6CE7D1DF0161AD5F06FFD764F0026354A1CB946F03E37C14F7DD98A9F59A7493F2869AAE39AF064F81DEBF3C94A082CCDA26F5C03367BDA1D1975B5E08CD7E91F02D3537EABB4D98B36D7DAD24C7CB36C850148CD911BA89585653F5B582A23C459A78515E3FC5851B08F8EC2E68736BD7488DC5C73FE40A61DC7F4581C95E20E70E7ECB010365B89CD233A8175A4CE862770D5126AB0E606CD8030490E3B1B05EB3F094B8246259D9A9A84434D02A173F37A9FB883844BFBEE307790649463C4EDE0F1F68D9B61C50004E5F38913D160D5AD214A2C1D85E985A288316951FE89FB77890C1BC16B2DE9920803C9BD746373B0D1F42F829083BC4725EA573509AB8F9DAF3BC3309B4B4A29A8A37023A53B7B73B5DD172809329DC7A966953C30A6A0824EEE510657CEC1F93A9C3CD21D58E8B04B4C877AB6D13D575D206D90ED601E9BB8244944A941CFD382806CF5774E6A61502A63AEB74769B80D65D155FC1F5AD9177C81326DC157750D3B8BB75CF52CD21382BE99983F5AD520351166A4B83A7F2BD8D2EFB143492246F2BAF9247839FDCB947E1EB162E2FB8CD4248DEFCD728929684C6F0DF72F25837EC2A7E23064B9FC38590988B79A5FC925B6E7564167CEE374D24FEB1CF59AD5FF37A65BCBAAE9961DFC805E49EDB3DF6001C2EBBC868E9B4A46AB2BF6D9F060D85E965DB7C5D9E5F4DE5677C1A127A26FFE12C57FCA2ED7A950C89B1CAD3C4E5E279C6D197DAC5300051BDF4A05C2FC76E57F3A7362F145C651AFC9AEBB962A3D7D1FAD0DBFAC833B968DE988A4FC799CE55479D89E5F64A2DBE6102926E49661A000A0B0BD49DE7826EEFC0638DE10DB3E68591FFEDA521BE4A6C5447406B293866292CFAB1CE3E68AED693F1D3EB9EE521962ECA88D7D2629FD9DA3E324C131AFB78B5C41831FF5FA68BEE73
+20220715161822 2 6 100 7679 2 D29885507D691EF92591A09643ED996F7CBCB7BC2C100AB3FEF5257A5931CC62D6E976C8702F99622C00702F7A97A8DF2C58E6CE1B087955544A6F08E64CC55AE62AB2F2ACA5CCAAC3FB093CC1D0CD964316B4E10C149B72EF468C7D57DC47980B0B4682B79EA3DB224C5E13BA7B8B0CD8C26BD8E884F0A96B77ED42A749A4556C14B417241BFD807B6B985F8474D53AB3002E46E860DA6AF2FC4387C33540FE64DBA835028710E1A8EB05307283DFA15CB67282334BFFF511D4B6284C18620B0F64A87E026EE576D0C201314CB24FE513DDA9AC0747065B315BAEB2D7AC801CE819708A224840C3C2C23F34DAEF1BED28091CB489EBC99E7B89A285ADC47D3DE4DDB71A5EE4184A642FF8E3E1E67536F7534C67D2A196319B597D7A7A4B2B7D852613818A51FF6CE7D1DF0161AD5F06FFD764F0026354A1CB946F03E37C14F7DD98A9F59A7493F2869AAE39AF064F81DEBF3C94A082CCDA26F5C03367BDA1D1975B5E08CD7E91F02D3537EABB4D98B36D7DAD24C7CB36C850148CD911BA89585653F5B582A23C459A78515E3FC5851B08F8EC2E68736BD7488DC5C73FE40A61DC7F4581C95E20E70E7ECB010365B89CD233A8175A4CE862770D5126AB0E606CD8030490E3B1B05EB3F094B8246259D9A9A84434D02A173F37A9FB883844BFBEE307790649463C4EDE0F1F68D9B61C50004E5F38913D160D5AD214A2C1D85E985A288316951FE89FB77890C1BC16B2DE9920803C9BD746373B0D1F42F829083BC4725EA573509AB8F9DAF3BC3309B4B4A29A8A37023A53B7B73B5DD172809329DC7A966953C30A6A0824EEE510657CEC1F93A9C3CD21D58E8B04B4C877AB6D13D575D206D90ED601E9BB8244944A941CFD382806CF5774E6A61502A63AEB74769B80D65D155FC1F5AD9177C81326DC157750D3B8BB75CF52CD21382BE99983F5AD520351166A4B83A7F2BD8D2EFB143492246F2BAF9247839FDCB947E1EB162E2FB8CD4248DEFCD728929684C6F0DF72F25837EC2A7E23064B9FC38590988B79A5FC925B6E7564167CEE374D24FEB1CF59AD5FF37A65BCBAAE9961DFC805E49EDB3DF6001C2EBBC868E9B4A46AB2BF6D9F060D85E965DB7C5D9E5F4DE5677C1A127A26FFE12C57FCA2ED7A950C89B1CAD3C4E5E279C6D197DAC5300051BDF4A05C2FC76E57F3A7362F145C651AFC9AEBB962A3D7D1FAD0DBFAC833B968DE988A4FC799CE55479D89E5F64A2DBE6102926E49661A000A0B0BD49DE7826EEFC0638DE10DB3E68591FFEDA521BE4A6C5447406B293866292CFAB1CE3E68AED693F1D3EB9EE521962ECA88D7D2629FD9DA3E324C131AFB78B5C41831FF5FB045A9D3
+20220715162253 2 6 100 7679 2 D29885507D691EF92591A09643ED996F7CBCB7BC2C100AB3FEF5257A5931CC62D6E976C8702F99622C00702F7A97A8DF2C58E6CE1B087955544A6F08E64CC55AE62AB2F2ACA5CCAAC3FB093CC1D0CD964316B4E10C149B72EF468C7D57DC47980B0B4682B79EA3DB224C5E13BA7B8B0CD8C26BD8E884F0A96B77ED42A749A4556C14B417241BFD807B6B985F8474D53AB3002E46E860DA6AF2FC4387C33540FE64DBA835028710E1A8EB05307283DFA15CB67282334BFFF511D4B6284C18620B0F64A87E026EE576D0C201314CB24FE513DDA9AC0747065B315BAEB2D7AC801CE819708A224840C3C2C23F34DAEF1BED28091CB489EBC99E7B89A285ADC47D3DE4DDB71A5EE4184A642FF8E3E1E67536F7534C67D2A196319B597D7A7A4B2B7D852613818A51FF6CE7D1DF0161AD5F06FFD764F0026354A1CB946F03E37C14F7DD98A9F59A7493F2869AAE39AF064F81DEBF3C94A082CCDA26F5C03367BDA1D1975B5E08CD7E91F02D3537EABB4D98B36D7DAD24C7CB36C850148CD911BA89585653F5B582A23C459A78515E3FC5851B08F8EC2E68736BD7488DC5C73FE40A61DC7F4581C95E20E70E7ECB010365B89CD233A8175A4CE862770D5126AB0E606CD8030490E3B1B05EB3F094B8246259D9A9A84434D02A173F37A9FB883844BFBEE307790649463C4EDE0F1F68D9B61C50004E5F38913D160D5AD214A2C1D85E985A288316951FE89FB77890C1BC16B2DE9920803C9BD746373B0D1F42F829083BC4725EA573509AB8F9DAF3BC3309B4B4A29A8A37023A53B7B73B5DD172809329DC7A966953C30A6A0824EEE510657CEC1F93A9C3CD21D58E8B04B4C877AB6D13D575D206D90ED601E9BB8244944A941CFD382806CF5774E6A61502A63AEB74769B80D65D155FC1F5AD9177C81326DC157750D3B8BB75CF52CD21382BE99983F5AD520351166A4B83A7F2BD8D2EFB143492246F2BAF9247839FDCB947E1EB162E2FB8CD4248DEFCD728929684C6F0DF72F25837EC2A7E23064B9FC38590988B79A5FC925B6E7564167CEE374D24FEB1CF59AD5FF37A65BCBAAE9961DFC805E49EDB3DF6001C2EBBC868E9B4A46AB2BF6D9F060D85E965DB7C5D9E5F4DE5677C1A127A26FFE12C57FCA2ED7A950C89B1CAD3C4E5E279C6D197DAC5300051BDF4A05C2FC76E57F3A7362F145C651AFC9AEBB962A3D7D1FAD0DBFAC833B968DE988A4FC799CE55479D89E5F64A2DBE6102926E49661A000A0B0BD49DE7826EEFC0638DE10DB3E68591FFEDA521BE4A6C5447406B293866292CFAB1CE3E68AED693F1D3EB9EE521962ECA88D7D2629FD9DA3E324C131AFB78B5C41831FF5FB09339CB
+20220715175344 2 6 100 7679 2 D29885507D691EF92591A09643ED996F7CBCB7BC2C100AB3FEF5257A5931CC62D6E976C8702F99622C00702F7A97A8DF2C58E6CE1B087955544A6F08E64CC55AE62AB2F2ACA5CCAAC3FB093CC1D0CD964316B4E10C149B72EF468C7D57DC47980B0B4682B79EA3DB224C5E13BA7B8B0CD8C26BD8E884F0A96B77ED42A749A4556C14B417241BFD807B6B985F8474D53AB3002E46E860DA6AF2FC4387C33540FE64DBA835028710E1A8EB05307283DFA15CB67282334BFFF511D4B6284C18620B0F64A87E026EE576D0C201314CB24FE513DDA9AC0747065B315BAEB2D7AC801CE819708A224840C3C2C23F34DAEF1BED28091CB489EBC99E7B89A285ADC47D3DE4DDB71A5EE4184A642FF8E3E1E67536F7534C67D2A196319B597D7A7A4B2B7D852613818A51FF6CE7D1DF0161AD5F06FFD764F0026354A1CB946F03E37C14F7DD98A9F59A7493F2869AAE39AF064F81DEBF3C94A082CCDA26F5C03367BDA1D1975B5E08CD7E91F02D3537EABB4D98B36D7DAD24C7CB36C850148CD911BA89585653F5B582A23C459A78515E3FC5851B08F8EC2E68736BD7488DC5C73FE40A61DC7F4581C95E20E70E7ECB010365B89CD233A8175A4CE862770D5126AB0E606CD8030490E3B1B05EB3F094B8246259D9A9A84434D02A173F37A9FB883844BFBEE307790649463C4EDE0F1F68D9B61C50004E5F38913D160D5AD214A2C1D85E985A288316951FE89FB77890C1BC16B2DE9920803C9BD746373B0D1F42F829083BC4725EA573509AB8F9DAF3BC3309B4B4A29A8A37023A53B7B73B5DD172809329DC7A966953C30A6A0824EEE510657CEC1F93A9C3CD21D58E8B04B4C877AB6D13D575D206D90ED601E9BB8244944A941CFD382806CF5774E6A61502A63AEB74769B80D65D155FC1F5AD9177C81326DC157750D3B8BB75CF52CD21382BE99983F5AD520351166A4B83A7F2BD8D2EFB143492246F2BAF9247839FDCB947E1EB162E2FB8CD4248DEFCD728929684C6F0DF72F25837EC2A7E23064B9FC38590988B79A5FC925B6E7564167CEE374D24FEB1CF59AD5FF37A65BCBAAE9961DFC805E49EDB3DF6001C2EBBC868E9B4A46AB2BF6D9F060D85E965DB7C5D9E5F4DE5677C1A127A26FFE12C57FCA2ED7A950C89B1CAD3C4E5E279C6D197DAC5300051BDF4A05C2FC76E57F3A7362F145C651AFC9AEBB962A3D7D1FAD0DBFAC833B968DE988A4FC799CE55479D89E5F64A2DBE6102926E49661A000A0B0BD49DE7826EEFC0638DE10DB3E68591FFEDA521BE4A6C5447406B293866292CFAB1CE3E68AED693F1D3EB9EE521962ECA88D7D2629FD9DA3E324C131AFB78B5C41831FF5FB7156F2B
+20220715182025 2 6 100 7679 5 D29885507D691EF92591A09643ED996F7CBCB7BC2C100AB3FEF5257A5931CC62D6E976C8702F99622C00702F7A97A8DF2C58E6CE1B087955544A6F08E64CC55AE62AB2F2ACA5CCAAC3FB093CC1D0CD964316B4E10C149B72EF468C7D57DC47980B0B4682B79EA3DB224C5E13BA7B8B0CD8C26BD8E884F0A96B77ED42A749A4556C14B417241BFD807B6B985F8474D53AB3002E46E860DA6AF2FC4387C33540FE64DBA835028710E1A8EB05307283DFA15CB67282334BFFF511D4B6284C18620B0F64A87E026EE576D0C201314CB24FE513DDA9AC0747065B315BAEB2D7AC801CE819708A224840C3C2C23F34DAEF1BED28091CB489EBC99E7B89A285ADC47D3DE4DDB71A5EE4184A642FF8E3E1E67536F7534C67D2A196319B597D7A7A4B2B7D852613818A51FF6CE7D1DF0161AD5F06FFD764F0026354A1CB946F03E37C14F7DD98A9F59A7493F2869AAE39AF064F81DEBF3C94A082CCDA26F5C03367BDA1D1975B5E08CD7E91F02D3537EABB4D98B36D7DAD24C7CB36C850148CD911BA89585653F5B582A23C459A78515E3FC5851B08F8EC2E68736BD7488DC5C73FE40A61DC7F4581C95E20E70E7ECB010365B89CD233A8175A4CE862770D5126AB0E606CD8030490E3B1B05EB3F094B8246259D9A9A84434D02A173F37A9FB883844BFBEE307790649463C4EDE0F1F68D9B61C50004E5F38913D160D5AD214A2C1D85E985A288316951FE89FB77890C1BC16B2DE9920803C9BD746373B0D1F42F829083BC4725EA573509AB8F9DAF3BC3309B4B4A29A8A37023A53B7B73B5DD172809329DC7A966953C30A6A0824EEE510657CEC1F93A9C3CD21D58E8B04B4C877AB6D13D575D206D90ED601E9BB8244944A941CFD382806CF5774E6A61502A63AEB74769B80D65D155FC1F5AD9177C81326DC157750D3B8BB75CF52CD21382BE99983F5AD520351166A4B83A7F2BD8D2EFB143492246F2BAF9247839FDCB947E1EB162E2FB8CD4248DEFCD728929684C6F0DF72F25837EC2A7E23064B9FC38590988B79A5FC925B6E7564167CEE374D24FEB1CF59AD5FF37A65BCBAAE9961DFC805E49EDB3DF6001C2EBBC868E9B4A46AB2BF6D9F060D85E965DB7C5D9E5F4DE5677C1A127A26FFE12C57FCA2ED7A950C89B1CAD3C4E5E279C6D197DAC5300051BDF4A05C2FC76E57F3A7362F145C651AFC9AEBB962A3D7D1FAD0DBFAC833B968DE988A4FC799CE55479D89E5F64A2DBE6102926E49661A000A0B0BD49DE7826EEFC0638DE10DB3E68591FFEDA521BE4A6C5447406B293866292CFAB1CE3E68AED693F1D3EB9EE521962ECA88D7D2629FD9DA3E324C131AFB78B5C41831FF5FB90A53D7
+20220715190627 2 6 100 7679 5 D29885507D691EF92591A09643ED996F7CBCB7BC2C100AB3FEF5257A5931CC62D6E976C8702F99622C00702F7A97A8DF2C58E6CE1B087955544A6F08E64CC55AE62AB2F2ACA5CCAAC3FB093CC1D0CD964316B4E10C149B72EF468C7D57DC47980B0B4682B79EA3DB224C5E13BA7B8B0CD8C26BD8E884F0A96B77ED42A749A4556C14B417241BFD807B6B985F8474D53AB3002E46E860DA6AF2FC4387C33540FE64DBA835028710E1A8EB05307283DFA15CB67282334BFFF511D4B6284C18620B0F64A87E026EE576D0C201314CB24FE513DDA9AC0747065B315BAEB2D7AC801CE819708A224840C3C2C23F34DAEF1BED28091CB489EBC99E7B89A285ADC47D3DE4DDB71A5EE4184A642FF8E3E1E67536F7534C67D2A196319B597D7A7A4B2B7D852613818A51FF6CE7D1DF0161AD5F06FFD764F0026354A1CB946F03E37C14F7DD98A9F59A7493F2869AAE39AF064F81DEBF3C94A082CCDA26F5C03367BDA1D1975B5E08CD7E91F02D3537EABB4D98B36D7DAD24C7CB36C850148CD911BA89585653F5B582A23C459A78515E3FC5851B08F8EC2E68736BD7488DC5C73FE40A61DC7F4581C95E20E70E7ECB010365B89CD233A8175A4CE862770D5126AB0E606CD8030490E3B1B05EB3F094B8246259D9A9A84434D02A173F37A9FB883844BFBEE307790649463C4EDE0F1F68D9B61C50004E5F38913D160D5AD214A2C1D85E985A288316951FE89FB77890C1BC16B2DE9920803C9BD746373B0D1F42F829083BC4725EA573509AB8F9DAF3BC3309B4B4A29A8A37023A53B7B73B5DD172809329DC7A966953C30A6A0824EEE510657CEC1F93A9C3CD21D58E8B04B4C877AB6D13D575D206D90ED601E9BB8244944A941CFD382806CF5774E6A61502A63AEB74769B80D65D155FC1F5AD9177C81326DC157750D3B8BB75CF52CD21382BE99983F5AD520351166A4B83A7F2BD8D2EFB143492246F2BAF9247839FDCB947E1EB162E2FB8CD4248DEFCD728929684C6F0DF72F25837EC2A7E23064B9FC38590988B79A5FC925B6E7564167CEE374D24FEB1CF59AD5FF37A65BCBAAE9961DFC805E49EDB3DF6001C2EBBC868E9B4A46AB2BF6D9F060D85E965DB7C5D9E5F4DE5677C1A127A26FFE12C57FCA2ED7A950C89B1CAD3C4E5E279C6D197DAC5300051BDF4A05C2FC76E57F3A7362F145C651AFC9AEBB962A3D7D1FAD0DBFAC833B968DE988A4FC799CE55479D89E5F64A2DBE6102926E49661A000A0B0BD49DE7826EEFC0638DE10DB3E68591FFEDA521BE4A6C5447406B293866292CFAB1CE3E68AED693F1D3EB9EE521962ECA88D7D2629FD9DA3E324C131AFB78B5C41831FF5FBC5E2767
+20220715191213 2 6 100 7679 5 D29885507D691EF92591A09643ED996F7CBCB7BC2C100AB3FEF5257A5931CC62D6E976C8702F99622C00702F7A97A8DF2C58E6CE1B087955544A6F08E64CC55AE62AB2F2ACA5CCAAC3FB093CC1D0CD964316B4E10C149B72EF468C7D57DC47980B0B4682B79EA3DB224C5E13BA7B8B0CD8C26BD8E884F0A96B77ED42A749A4556C14B417241BFD807B6B985F8474D53AB3002E46E860DA6AF2FC4387C33540FE64DBA835028710E1A8EB05307283DFA15CB67282334BFFF511D4B6284C18620B0F64A87E026EE576D0C201314CB24FE513DDA9AC0747065B315BAEB2D7AC801CE819708A224840C3C2C23F34DAEF1BED28091CB489EBC99E7B89A285ADC47D3DE4DDB71A5EE4184A642FF8E3E1E67536F7534C67D2A196319B597D7A7A4B2B7D852613818A51FF6CE7D1DF0161AD5F06FFD764F0026354A1CB946F03E37C14F7DD98A9F59A7493F2869AAE39AF064F81DEBF3C94A082CCDA26F5C03367BDA1D1975B5E08CD7E91F02D3537EABB4D98B36D7DAD24C7CB36C850148CD911BA89585653F5B582A23C459A78515E3FC5851B08F8EC2E68736BD7488DC5C73FE40A61DC7F4581C95E20E70E7ECB010365B89CD233A8175A4CE862770D5126AB0E606CD8030490E3B1B05EB3F094B8246259D9A9A84434D02A173F37A9FB883844BFBEE307790649463C4EDE0F1F68D9B61C50004E5F38913D160D5AD214A2C1D85E985A288316951FE89FB77890C1BC16B2DE9920803C9BD746373B0D1F42F829083BC4725EA573509AB8F9DAF3BC3309B4B4A29A8A37023A53B7B73B5DD172809329DC7A966953C30A6A0824EEE510657CEC1F93A9C3CD21D58E8B04B4C877AB6D13D575D206D90ED601E9BB8244944A941CFD382806CF5774E6A61502A63AEB74769B80D65D155FC1F5AD9177C81326DC157750D3B8BB75CF52CD21382BE99983F5AD520351166A4B83A7F2BD8D2EFB143492246F2BAF9247839FDCB947E1EB162E2FB8CD4248DEFCD728929684C6F0DF72F25837EC2A7E23064B9FC38590988B79A5FC925B6E7564167CEE374D24FEB1CF59AD5FF37A65BCBAAE9961DFC805E49EDB3DF6001C2EBBC868E9B4A46AB2BF6D9F060D85E965DB7C5D9E5F4DE5677C1A127A26FFE12C57FCA2ED7A950C89B1CAD3C4E5E279C6D197DAC5300051BDF4A05C2FC76E57F3A7362F145C651AFC9AEBB962A3D7D1FAD0DBFAC833B968DE988A4FC799CE55479D89E5F64A2DBE6102926E49661A000A0B0BD49DE7826EEFC0638DE10DB3E68591FFEDA521BE4A6C5447406B293866292CFAB1CE3E68AED693F1D3EB9EE521962ECA88D7D2629FD9DA3E324C131AFB78B5C41831FF5FBCCA724F
+20220715193806 2 6 100 7679 2 D29885507D691EF92591A09643ED996F7CBCB7BC2C100AB3FEF5257A5931CC62D6E976C8702F99622C00702F7A97A8DF2C58E6CE1B087955544A6F08E64CC55AE62AB2F2ACA5CCAAC3FB093CC1D0CD964316B4E10C149B72EF468C7D57DC47980B0B4682B79EA3DB224C5E13BA7B8B0CD8C26BD8E884F0A96B77ED42A749A4556C14B417241BFD807B6B985F8474D53AB3002E46E860DA6AF2FC4387C33540FE64DBA835028710E1A8EB05307283DFA15CB67282334BFFF511D4B6284C18620B0F64A87E026EE576D0C201314CB24FE513DDA9AC0747065B315BAEB2D7AC801CE819708A224840C3C2C23F34DAEF1BED28091CB489EBC99E7B89A285ADC47D3DE4DDB71A5EE4184A642FF8E3E1E67536F7534C67D2A196319B597D7A7A4B2B7D852613818A51FF6CE7D1DF0161AD5F06FFD764F0026354A1CB946F03E37C14F7DD98A9F59A7493F2869AAE39AF064F81DEBF3C94A082CCDA26F5C03367BDA1D1975B5E08CD7E91F02D3537EABB4D98B36D7DAD24C7CB36C850148CD911BA89585653F5B582A23C459A78515E3FC5851B08F8EC2E68736BD7488DC5C73FE40A61DC7F4581C95E20E70E7ECB010365B89CD233A8175A4CE862770D5126AB0E606CD8030490E3B1B05EB3F094B8246259D9A9A84434D02A173F37A9FB883844BFBEE307790649463C4EDE0F1F68D9B61C50004E5F38913D160D5AD214A2C1D85E985A288316951FE89FB77890C1BC16B2DE9920803C9BD746373B0D1F42F829083BC4725EA573509AB8F9DAF3BC3309B4B4A29A8A37023A53B7B73B5DD172809329DC7A966953C30A6A0824EEE510657CEC1F93A9C3CD21D58E8B04B4C877AB6D13D575D206D90ED601E9BB8244944A941CFD382806CF5774E6A61502A63AEB74769B80D65D155FC1F5AD9177C81326DC157750D3B8BB75CF52CD21382BE99983F5AD520351166A4B83A7F2BD8D2EFB143492246F2BAF9247839FDCB947E1EB162E2FB8CD4248DEFCD728929684C6F0DF72F25837EC2A7E23064B9FC38590988B79A5FC925B6E7564167CEE374D24FEB1CF59AD5FF37A65BCBAAE9961DFC805E49EDB3DF6001C2EBBC868E9B4A46AB2BF6D9F060D85E965DB7C5D9E5F4DE5677C1A127A26FFE12C57FCA2ED7A950C89B1CAD3C4E5E279C6D197DAC5300051BDF4A05C2FC76E57F3A7362F145C651AFC9AEBB962A3D7D1FAD0DBFAC833B968DE988A4FC799CE55479D89E5F64A2DBE6102926E49661A000A0B0BD49DE7826EEFC0638DE10DB3E68591FFEDA521BE4A6C5447406B293866292CFAB1CE3E68AED693F1D3EB9EE521962ECA88D7D2629FD9DA3E324C131AFB78B5C41831FF5FBEA4C29B
+20220715204457 2 6 100 7679 5 D29885507D691EF92591A09643ED996F7CBCB7BC2C100AB3FEF5257A5931CC62D6E976C8702F99622C00702F7A97A8DF2C58E6CE1B087955544A6F08E64CC55AE62AB2F2ACA5CCAAC3FB093CC1D0CD964316B4E10C149B72EF468C7D57DC47980B0B4682B79EA3DB224C5E13BA7B8B0CD8C26BD8E884F0A96B77ED42A749A4556C14B417241BFD807B6B985F8474D53AB3002E46E860DA6AF2FC4387C33540FE64DBA835028710E1A8EB05307283DFA15CB67282334BFFF511D4B6284C18620B0F64A87E026EE576D0C201314CB24FE513DDA9AC0747065B315BAEB2D7AC801CE819708A224840C3C2C23F34DAEF1BED28091CB489EBC99E7B89A285ADC47D3DE4DDB71A5EE4184A642FF8E3E1E67536F7534C67D2A196319B597D7A7A4B2B7D852613818A51FF6CE7D1DF0161AD5F06FFD764F0026354A1CB946F03E37C14F7DD98A9F59A7493F2869AAE39AF064F81DEBF3C94A082CCDA26F5C03367BDA1D1975B5E08CD7E91F02D3537EABB4D98B36D7DAD24C7CB36C850148CD911BA89585653F5B582A23C459A78515E3FC5851B08F8EC2E68736BD7488DC5C73FE40A61DC7F4581C95E20E70E7ECB010365B89CD233A8175A4CE862770D5126AB0E606CD8030490E3B1B05EB3F094B8246259D9A9A84434D02A173F37A9FB883844BFBEE307790649463C4EDE0F1F68D9B61C50004E5F38913D160D5AD214A2C1D85E985A288316951FE89FB77890C1BC16B2DE9920803C9BD746373B0D1F42F829083BC4725EA573509AB8F9DAF3BC3309B4B4A29A8A37023A53B7B73B5DD172809329DC7A966953C30A6A0824EEE510657CEC1F93A9C3CD21D58E8B04B4C877AB6D13D575D206D90ED601E9BB8244944A941CFD382806CF5774E6A61502A63AEB74769B80D65D155FC1F5AD9177C81326DC157750D3B8BB75CF52CD21382BE99983F5AD520351166A4B83A7F2BD8D2EFB143492246F2BAF9247839FDCB947E1EB162E2FB8CD4248DEFCD728929684C6F0DF72F25837EC2A7E23064B9FC38590988B79A5FC925B6E7564167CEE374D24FEB1CF59AD5FF37A65BCBAAE9961DFC805E49EDB3DF6001C2EBBC868E9B4A46AB2BF6D9F060D85E965DB7C5D9E5F4DE5677C1A127A26FFE12C57FCA2ED7A950C89B1CAD3C4E5E279C6D197DAC5300051BDF4A05C2FC76E57F3A7362F145C651AFC9AEBB962A3D7D1FAD0DBFAC833B968DE988A4FC799CE55479D89E5F64A2DBE6102926E49661A000A0B0BD49DE7826EEFC0638DE10DB3E68591FFEDA521BE4A6C5447406B293866292CFAB1CE3E68AED693F1D3EB9EE521962ECA88D7D2629FD9DA3E324C131AFB78B5C41831FF5FC370204F
+20220715212313 2 6 100 7679 5 D29885507D691EF92591A09643ED996F7CBCB7BC2C100AB3FEF5257A5931CC62D6E976C8702F99622C00702F7A97A8DF2C58E6CE1B087955544A6F08E64CC55AE62AB2F2ACA5CCAAC3FB093CC1D0CD964316B4E10C149B72EF468C7D57DC47980B0B4682B79EA3DB224C5E13BA7B8B0CD8C26BD8E884F0A96B77ED42A749A4556C14B417241BFD807B6B985F8474D53AB3002E46E860DA6AF2FC4387C33540FE64DBA835028710E1A8EB05307283DFA15CB67282334BFFF511D4B6284C18620B0F64A87E026EE576D0C201314CB24FE513DDA9AC0747065B315BAEB2D7AC801CE819708A224840C3C2C23F34DAEF1BED28091CB489EBC99E7B89A285ADC47D3DE4DDB71A5EE4184A642FF8E3E1E67536F7534C67D2A196319B597D7A7A4B2B7D852613818A51FF6CE7D1DF0161AD5F06FFD764F0026354A1CB946F03E37C14F7DD98A9F59A7493F2869AAE39AF064F81DEBF3C94A082CCDA26F5C03367BDA1D1975B5E08CD7E91F02D3537EABB4D98B36D7DAD24C7CB36C850148CD911BA89585653F5B582A23C459A78515E3FC5851B08F8EC2E68736BD7488DC5C73FE40A61DC7F4581C95E20E70E7ECB010365B89CD233A8175A4CE862770D5126AB0E606CD8030490E3B1B05EB3F094B8246259D9A9A84434D02A173F37A9FB883844BFBEE307790649463C4EDE0F1F68D9B61C50004E5F38913D160D5AD214A2C1D85E985A288316951FE89FB77890C1BC16B2DE9920803C9BD746373B0D1F42F829083BC4725EA573509AB8F9DAF3BC3309B4B4A29A8A37023A53B7B73B5DD172809329DC7A966953C30A6A0824EEE510657CEC1F93A9C3CD21D58E8B04B4C877AB6D13D575D206D90ED601E9BB8244944A941CFD382806CF5774E6A61502A63AEB74769B80D65D155FC1F5AD9177C81326DC157750D3B8BB75CF52CD21382BE99983F5AD520351166A4B83A7F2BD8D2EFB143492246F2BAF9247839FDCB947E1EB162E2FB8CD4248DEFCD728929684C6F0DF72F25837EC2A7E23064B9FC38590988B79A5FC925B6E7564167CEE374D24FEB1CF59AD5FF37A65BCBAAE9961DFC805E49EDB3DF6001C2EBBC868E9B4A46AB2BF6D9F060D85E965DB7C5D9E5F4DE5677C1A127A26FFE12C57FCA2ED7A950C89B1CAD3C4E5E279C6D197DAC5300051BDF4A05C2FC76E57F3A7362F145C651AFC9AEBB962A3D7D1FAD0DBFAC833B968DE988A4FC799CE55479D89E5F64A2DBE6102926E49661A000A0B0BD49DE7826EEFC0638DE10DB3E68591FFEDA521BE4A6C5447406B293866292CFAB1CE3E68AED693F1D3EB9EE521962ECA88D7D2629FD9DA3E324C131AFB78B5C41831FF5FC63E9CA7
+20220715225401 2 6 100 7679 5 D29885507D691EF92591A09643ED996F7CBCB7BC2C100AB3FEF5257A5931CC62D6E976C8702F99622C00702F7A97A8DF2C58E6CE1B087955544A6F08E64CC55AE62AB2F2ACA5CCAAC3FB093CC1D0CD964316B4E10C149B72EF468C7D57DC47980B0B4682B79EA3DB224C5E13BA7B8B0CD8C26BD8E884F0A96B77ED42A749A4556C14B417241BFD807B6B985F8474D53AB3002E46E860DA6AF2FC4387C33540FE64DBA835028710E1A8EB05307283DFA15CB67282334BFFF511D4B6284C18620B0F64A87E026EE576D0C201314CB24FE513DDA9AC0747065B315BAEB2D7AC801CE819708A224840C3C2C23F34DAEF1BED28091CB489EBC99E7B89A285ADC47D3DE4DDB71A5EE4184A642FF8E3E1E67536F7534C67D2A196319B597D7A7A4B2B7D852613818A51FF6CE7D1DF0161AD5F06FFD764F0026354A1CB946F03E37C14F7DD98A9F59A7493F2869AAE39AF064F81DEBF3C94A082CCDA26F5C03367BDA1D1975B5E08CD7E91F02D3537EABB4D98B36D7DAD24C7CB36C850148CD911BA89585653F5B582A23C459A78515E3FC5851B08F8EC2E68736BD7488DC5C73FE40A61DC7F4581C95E20E70E7ECB010365B89CD233A8175A4CE862770D5126AB0E606CD8030490E3B1B05EB3F094B8246259D9A9A84434D02A173F37A9FB883844BFBEE307790649463C4EDE0F1F68D9B61C50004E5F38913D160D5AD214A2C1D85E985A288316951FE89FB77890C1BC16B2DE9920803C9BD746373B0D1F42F829083BC4725EA573509AB8F9DAF3BC3309B4B4A29A8A37023A53B7B73B5DD172809329DC7A966953C30A6A0824EEE510657CEC1F93A9C3CD21D58E8B04B4C877AB6D13D575D206D90ED601E9BB8244944A941CFD382806CF5774E6A61502A63AEB74769B80D65D155FC1F5AD9177C81326DC157750D3B8BB75CF52CD21382BE99983F5AD520351166A4B83A7F2BD8D2EFB143492246F2BAF9247839FDCB947E1EB162E2FB8CD4248DEFCD728929684C6F0DF72F25837EC2A7E23064B9FC38590988B79A5FC925B6E7564167CEE374D24FEB1CF59AD5FF37A65BCBAAE9961DFC805E49EDB3DF6001C2EBBC868E9B4A46AB2BF6D9F060D85E965DB7C5D9E5F4DE5677C1A127A26FFE12C57FCA2ED7A950C89B1CAD3C4E5E279C6D197DAC5300051BDF4A05C2FC76E57F3A7362F145C651AFC9AEBB962A3D7D1FAD0DBFAC833B968DE988A4FC799CE55479D89E5F64A2DBE6102926E49661A000A0B0BD49DE7826EEFC0638DE10DB3E68591FFEDA521BE4A6C5447406B293866292CFAB1CE3E68AED693F1D3EB9EE521962ECA88D7D2629FD9DA3E324C131AFB78B5C41831FF5FCCC8EC9F
+20220715230508 2 6 100 7679 2 D29885507D691EF92591A09643ED996F7CBCB7BC2C100AB3FEF5257A5931CC62D6E976C8702F99622C00702F7A97A8DF2C58E6CE1B087955544A6F08E64CC55AE62AB2F2ACA5CCAAC3FB093CC1D0CD964316B4E10C149B72EF468C7D57DC47980B0B4682B79EA3DB224C5E13BA7B8B0CD8C26BD8E884F0A96B77ED42A749A4556C14B417241BFD807B6B985F8474D53AB3002E46E860DA6AF2FC4387C33540FE64DBA835028710E1A8EB05307283DFA15CB67282334BFFF511D4B6284C18620B0F64A87E026EE576D0C201314CB24FE513DDA9AC0747065B315BAEB2D7AC801CE819708A224840C3C2C23F34DAEF1BED28091CB489EBC99E7B89A285ADC47D3DE4DDB71A5EE4184A642FF8E3E1E67536F7534C67D2A196319B597D7A7A4B2B7D852613818A51FF6CE7D1DF0161AD5F06FFD764F0026354A1CB946F03E37C14F7DD98A9F59A7493F2869AAE39AF064F81DEBF3C94A082CCDA26F5C03367BDA1D1975B5E08CD7E91F02D3537EABB4D98B36D7DAD24C7CB36C850148CD911BA89585653F5B582A23C459A78515E3FC5851B08F8EC2E68736BD7488DC5C73FE40A61DC7F4581C95E20E70E7ECB010365B89CD233A8175A4CE862770D5126AB0E606CD8030490E3B1B05EB3F094B8246259D9A9A84434D02A173F37A9FB883844BFBEE307790649463C4EDE0F1F68D9B61C50004E5F38913D160D5AD214A2C1D85E985A288316951FE89FB77890C1BC16B2DE9920803C9BD746373B0D1F42F829083BC4725EA573509AB8F9DAF3BC3309B4B4A29A8A37023A53B7B73B5DD172809329DC7A966953C30A6A0824EEE510657CEC1F93A9C3CD21D58E8B04B4C877AB6D13D575D206D90ED601E9BB8244944A941CFD382806CF5774E6A61502A63AEB74769B80D65D155FC1F5AD9177C81326DC157750D3B8BB75CF52CD21382BE99983F5AD520351166A4B83A7F2BD8D2EFB143492246F2BAF9247839FDCB947E1EB162E2FB8CD4248DEFCD728929684C6F0DF72F25837EC2A7E23064B9FC38590988B79A5FC925B6E7564167CEE374D24FEB1CF59AD5FF37A65BCBAAE9961DFC805E49EDB3DF6001C2EBBC868E9B4A46AB2BF6D9F060D85E965DB7C5D9E5F4DE5677C1A127A26FFE12C57FCA2ED7A950C89B1CAD3C4E5E279C6D197DAC5300051BDF4A05C2FC76E57F3A7362F145C651AFC9AEBB962A3D7D1FAD0DBFAC833B968DE988A4FC799CE55479D89E5F64A2DBE6102926E49661A000A0B0BD49DE7826EEFC0638DE10DB3E68591FFEDA521BE4A6C5447406B293866292CFAB1CE3E68AED693F1D3EB9EE521962ECA88D7D2629FD9DA3E324C131AFB78B5C41831FF5FCD93025B
+20220716003950 2 6 100 7679 2 D29885507D691EF92591A09643ED996F7CBCB7BC2C100AB3FEF5257A5931CC62D6E976C8702F99622C00702F7A97A8DF2C58E6CE1B087955544A6F08E64CC55AE62AB2F2ACA5CCAAC3FB093CC1D0CD964316B4E10C149B72EF468C7D57DC47980B0B4682B79EA3DB224C5E13BA7B8B0CD8C26BD8E884F0A96B77ED42A749A4556C14B417241BFD807B6B985F8474D53AB3002E46E860DA6AF2FC4387C33540FE64DBA835028710E1A8EB05307283DFA15CB67282334BFFF511D4B6284C18620B0F64A87E026EE576D0C201314CB24FE513DDA9AC0747065B315BAEB2D7AC801CE819708A224840C3C2C23F34DAEF1BED28091CB489EBC99E7B89A285ADC47D3DE4DDB71A5EE4184A642FF8E3E1E67536F7534C67D2A196319B597D7A7A4B2B7D852613818A51FF6CE7D1DF0161AD5F06FFD764F0026354A1CB946F03E37C14F7DD98A9F59A7493F2869AAE39AF064F81DEBF3C94A082CCDA26F5C03367BDA1D1975B5E08CD7E91F02D3537EABB4D98B36D7DAD24C7CB36C850148CD911BA89585653F5B582A23C459A78515E3FC5851B08F8EC2E68736BD7488DC5C73FE40A61DC7F4581C95E20E70E7ECB010365B89CD233A8175A4CE862770D5126AB0E606CD8030490E3B1B05EB3F094B8246259D9A9A84434D02A173F37A9FB883844BFBEE307790649463C4EDE0F1F68D9B61C50004E5F38913D160D5AD214A2C1D85E985A288316951FE89FB77890C1BC16B2DE9920803C9BD746373B0D1F42F829083BC4725EA573509AB8F9DAF3BC3309B4B4A29A8A37023A53B7B73B5DD172809329DC7A966953C30A6A0824EEE510657CEC1F93A9C3CD21D58E8B04B4C877AB6D13D575D206D90ED601E9BB8244944A941CFD382806CF5774E6A61502A63AEB74769B80D65D155FC1F5AD9177C81326DC157750D3B8BB75CF52CD21382BE99983F5AD520351166A4B83A7F2BD8D2EFB143492246F2BAF9247839FDCB947E1EB162E2FB8CD4248DEFCD728929684C6F0DF72F25837EC2A7E23064B9FC38590988B79A5FC925B6E7564167CEE374D24FEB1CF59AD5FF37A65BCBAAE9961DFC805E49EDB3DF6001C2EBBC868E9B4A46AB2BF6D9F060D85E965DB7C5D9E5F4DE5677C1A127A26FFE12C57FCA2ED7A950C89B1CAD3C4E5E279C6D197DAC5300051BDF4A05C2FC76E57F3A7362F145C651AFC9AEBB962A3D7D1FAD0DBFAC833B968DE988A4FC799CE55479D89E5F64A2DBE6102926E49661A000A0B0BD49DE7826EEFC0638DE10DB3E68591FFEDA521BE4A6C5447406B293866292CFAB1CE3E68AED693F1D3EB9EE521962ECA88D7D2629FD9DA3E324C131AFB78B5C41831FF5FD4674843
+20220716005647 2 6 100 7679 2 D29885507D691EF92591A09643ED996F7CBCB7BC2C100AB3FEF5257A5931CC62D6E976C8702F99622C00702F7A97A8DF2C58E6CE1B087955544A6F08E64CC55AE62AB2F2ACA5CCAAC3FB093CC1D0CD964316B4E10C149B72EF468C7D57DC47980B0B4682B79EA3DB224C5E13BA7B8B0CD8C26BD8E884F0A96B77ED42A749A4556C14B417241BFD807B6B985F8474D53AB3002E46E860DA6AF2FC4387C33540FE64DBA835028710E1A8EB05307283DFA15CB67282334BFFF511D4B6284C18620B0F64A87E026EE576D0C201314CB24FE513DDA9AC0747065B315BAEB2D7AC801CE819708A224840C3C2C23F34DAEF1BED28091CB489EBC99E7B89A285ADC47D3DE4DDB71A5EE4184A642FF8E3E1E67536F7534C67D2A196319B597D7A7A4B2B7D852613818A51FF6CE7D1DF0161AD5F06FFD764F0026354A1CB946F03E37C14F7DD98A9F59A7493F2869AAE39AF064F81DEBF3C94A082CCDA26F5C03367BDA1D1975B5E08CD7E91F02D3537EABB4D98B36D7DAD24C7CB36C850148CD911BA89585653F5B582A23C459A78515E3FC5851B08F8EC2E68736BD7488DC5C73FE40A61DC7F4581C95E20E70E7ECB010365B89CD233A8175A4CE862770D5126AB0E606CD8030490E3B1B05EB3F094B8246259D9A9A84434D02A173F37A9FB883844BFBEE307790649463C4EDE0F1F68D9B61C50004E5F38913D160D5AD214A2C1D85E985A288316951FE89FB77890C1BC16B2DE9920803C9BD746373B0D1F42F829083BC4725EA573509AB8F9DAF3BC3309B4B4A29A8A37023A53B7B73B5DD172809329DC7A966953C30A6A0824EEE510657CEC1F93A9C3CD21D58E8B04B4C877AB6D13D575D206D90ED601E9BB8244944A941CFD382806CF5774E6A61502A63AEB74769B80D65D155FC1F5AD9177C81326DC157750D3B8BB75CF52CD21382BE99983F5AD520351166A4B83A7F2BD8D2EFB143492246F2BAF9247839FDCB947E1EB162E2FB8CD4248DEFCD728929684C6F0DF72F25837EC2A7E23064B9FC38590988B79A5FC925B6E7564167CEE374D24FEB1CF59AD5FF37A65BCBAAE9961DFC805E49EDB3DF6001C2EBBC868E9B4A46AB2BF6D9F060D85E965DB7C5D9E5F4DE5677C1A127A26FFE12C57FCA2ED7A950C89B1CAD3C4E5E279C6D197DAC5300051BDF4A05C2FC76E57F3A7362F145C651AFC9AEBB962A3D7D1FAD0DBFAC833B968DE988A4FC799CE55479D89E5F64A2DBE6102926E49661A000A0B0BD49DE7826EEFC0638DE10DB3E68591FFEDA521BE4A6C5447406B293866292CFAB1CE3E68AED693F1D3EB9EE521962ECA88D7D2629FD9DA3E324C131AFB78B5C41831FF5FD59BD53B
+20220716005928 2 6 100 7679 2 D29885507D691EF92591A09643ED996F7CBCB7BC2C100AB3FEF5257A5931CC62D6E976C8702F99622C00702F7A97A8DF2C58E6CE1B087955544A6F08E64CC55AE62AB2F2ACA5CCAAC3FB093CC1D0CD964316B4E10C149B72EF468C7D57DC47980B0B4682B79EA3DB224C5E13BA7B8B0CD8C26BD8E884F0A96B77ED42A749A4556C14B417241BFD807B6B985F8474D53AB3002E46E860DA6AF2FC4387C33540FE64DBA835028710E1A8EB05307283DFA15CB67282334BFFF511D4B6284C18620B0F64A87E026EE576D0C201314CB24FE513DDA9AC0747065B315BAEB2D7AC801CE819708A224840C3C2C23F34DAEF1BED28091CB489EBC99E7B89A285ADC47D3DE4DDB71A5EE4184A642FF8E3E1E67536F7534C67D2A196319B597D7A7A4B2B7D852613818A51FF6CE7D1DF0161AD5F06FFD764F0026354A1CB946F03E37C14F7DD98A9F59A7493F2869AAE39AF064F81DEBF3C94A082CCDA26F5C03367BDA1D1975B5E08CD7E91F02D3537EABB4D98B36D7DAD24C7CB36C850148CD911BA89585653F5B582A23C459A78515E3FC5851B08F8EC2E68736BD7488DC5C73FE40A61DC7F4581C95E20E70E7ECB010365B89CD233A8175A4CE862770D5126AB0E606CD8030490E3B1B05EB3F094B8246259D9A9A84434D02A173F37A9FB883844BFBEE307790649463C4EDE0F1F68D9B61C50004E5F38913D160D5AD214A2C1D85E985A288316951FE89FB77890C1BC16B2DE9920803C9BD746373B0D1F42F829083BC4725EA573509AB8F9DAF3BC3309B4B4A29A8A37023A53B7B73B5DD172809329DC7A966953C30A6A0824EEE510657CEC1F93A9C3CD21D58E8B04B4C877AB6D13D575D206D90ED601E9BB8244944A941CFD382806CF5774E6A61502A63AEB74769B80D65D155FC1F5AD9177C81326DC157750D3B8BB75CF52CD21382BE99983F5AD520351166A4B83A7F2BD8D2EFB143492246F2BAF9247839FDCB947E1EB162E2FB8CD4248DEFCD728929684C6F0DF72F25837EC2A7E23064B9FC38590988B79A5FC925B6E7564167CEE374D24FEB1CF59AD5FF37A65BCBAAE9961DFC805E49EDB3DF6001C2EBBC868E9B4A46AB2BF6D9F060D85E965DB7C5D9E5F4DE5677C1A127A26FFE12C57FCA2ED7A950C89B1CAD3C4E5E279C6D197DAC5300051BDF4A05C2FC76E57F3A7362F145C651AFC9AEBB962A3D7D1FAD0DBFAC833B968DE988A4FC799CE55479D89E5F64A2DBE6102926E49661A000A0B0BD49DE7826EEFC0638DE10DB3E68591FFEDA521BE4A6C5447406B293866292CFAB1CE3E68AED693F1D3EB9EE521962ECA88D7D2629FD9DA3E324C131AFB78B5C41831FF5FD5CCEB93
+20220716010051 2 6 100 7679 2 D29885507D691EF92591A09643ED996F7CBCB7BC2C100AB3FEF5257A5931CC62D6E976C8702F99622C00702F7A97A8DF2C58E6CE1B087955544A6F08E64CC55AE62AB2F2ACA5CCAAC3FB093CC1D0CD964316B4E10C149B72EF468C7D57DC47980B0B4682B79EA3DB224C5E13BA7B8B0CD8C26BD8E884F0A96B77ED42A749A4556C14B417241BFD807B6B985F8474D53AB3002E46E860DA6AF2FC4387C33540FE64DBA835028710E1A8EB05307283DFA15CB67282334BFFF511D4B6284C18620B0F64A87E026EE576D0C201314CB24FE513DDA9AC0747065B315BAEB2D7AC801CE819708A224840C3C2C23F34DAEF1BED28091CB489EBC99E7B89A285ADC47D3DE4DDB71A5EE4184A642FF8E3E1E67536F7534C67D2A196319B597D7A7A4B2B7D852613818A51FF6CE7D1DF0161AD5F06FFD764F0026354A1CB946F03E37C14F7DD98A9F59A7493F2869AAE39AF064F81DEBF3C94A082CCDA26F5C03367BDA1D1975B5E08CD7E91F02D3537EABB4D98B36D7DAD24C7CB36C850148CD911BA89585653F5B582A23C459A78515E3FC5851B08F8EC2E68736BD7488DC5C73FE40A61DC7F4581C95E20E70E7ECB010365B89CD233A8175A4CE862770D5126AB0E606CD8030490E3B1B05EB3F094B8246259D9A9A84434D02A173F37A9FB883844BFBEE307790649463C4EDE0F1F68D9B61C50004E5F38913D160D5AD214A2C1D85E985A288316951FE89FB77890C1BC16B2DE9920803C9BD746373B0D1F42F829083BC4725EA573509AB8F9DAF3BC3309B4B4A29A8A37023A53B7B73B5DD172809329DC7A966953C30A6A0824EEE510657CEC1F93A9C3CD21D58E8B04B4C877AB6D13D575D206D90ED601E9BB8244944A941CFD382806CF5774E6A61502A63AEB74769B80D65D155FC1F5AD9177C81326DC157750D3B8BB75CF52CD21382BE99983F5AD520351166A4B83A7F2BD8D2EFB143492246F2BAF9247839FDCB947E1EB162E2FB8CD4248DEFCD728929684C6F0DF72F25837EC2A7E23064B9FC38590988B79A5FC925B6E7564167CEE374D24FEB1CF59AD5FF37A65BCBAAE9961DFC805E49EDB3DF6001C2EBBC868E9B4A46AB2BF6D9F060D85E965DB7C5D9E5F4DE5677C1A127A26FFE12C57FCA2ED7A950C89B1CAD3C4E5E279C6D197DAC5300051BDF4A05C2FC76E57F3A7362F145C651AFC9AEBB962A3D7D1FAD0DBFAC833B968DE988A4FC799CE55479D89E5F64A2DBE6102926E49661A000A0B0BD49DE7826EEFC0638DE10DB3E68591FFEDA521BE4A6C5447406B293866292CFAB1CE3E68AED693F1D3EB9EE521962ECA88D7D2629FD9DA3E324C131AFB78B5C41831FF5FD5E69E93
+20220716020432 2 6 100 7679 2 D29885507D691EF92591A09643ED996F7CBCB7BC2C100AB3FEF5257A5931CC62D6E976C8702F99622C00702F7A97A8DF2C58E6CE1B087955544A6F08E64CC55AE62AB2F2ACA5CCAAC3FB093CC1D0CD964316B4E10C149B72EF468C7D57DC47980B0B4682B79EA3DB224C5E13BA7B8B0CD8C26BD8E884F0A96B77ED42A749A4556C14B417241BFD807B6B985F8474D53AB3002E46E860DA6AF2FC4387C33540FE64DBA835028710E1A8EB05307283DFA15CB67282334BFFF511D4B6284C18620B0F64A87E026EE576D0C201314CB24FE513DDA9AC0747065B315BAEB2D7AC801CE819708A224840C3C2C23F34DAEF1BED28091CB489EBC99E7B89A285ADC47D3DE4DDB71A5EE4184A642FF8E3E1E67536F7534C67D2A196319B597D7A7A4B2B7D852613818A51FF6CE7D1DF0161AD5F06FFD764F0026354A1CB946F03E37C14F7DD98A9F59A7493F2869AAE39AF064F81DEBF3C94A082CCDA26F5C03367BDA1D1975B5E08CD7E91F02D3537EABB4D98B36D7DAD24C7CB36C850148CD911BA89585653F5B582A23C459A78515E3FC5851B08F8EC2E68736BD7488DC5C73FE40A61DC7F4581C95E20E70E7ECB010365B89CD233A8175A4CE862770D5126AB0E606CD8030490E3B1B05EB3F094B8246259D9A9A84434D02A173F37A9FB883844BFBEE307790649463C4EDE0F1F68D9B61C50004E5F38913D160D5AD214A2C1D85E985A288316951FE89FB77890C1BC16B2DE9920803C9BD746373B0D1F42F829083BC4725EA573509AB8F9DAF3BC3309B4B4A29A8A37023A53B7B73B5DD172809329DC7A966953C30A6A0824EEE510657CEC1F93A9C3CD21D58E8B04B4C877AB6D13D575D206D90ED601E9BB8244944A941CFD382806CF5774E6A61502A63AEB74769B80D65D155FC1F5AD9177C81326DC157750D3B8BB75CF52CD21382BE99983F5AD520351166A4B83A7F2BD8D2EFB143492246F2BAF9247839FDCB947E1EB162E2FB8CD4248DEFCD728929684C6F0DF72F25837EC2A7E23064B9FC38590988B79A5FC925B6E7564167CEE374D24FEB1CF59AD5FF37A65BCBAAE9961DFC805E49EDB3DF6001C2EBBC868E9B4A46AB2BF6D9F060D85E965DB7C5D9E5F4DE5677C1A127A26FFE12C57FCA2ED7A950C89B1CAD3C4E5E279C6D197DAC5300051BDF4A05C2FC76E57F3A7362F145C651AFC9AEBB962A3D7D1FAD0DBFAC833B968DE988A4FC799CE55479D89E5F64A2DBE6102926E49661A000A0B0BD49DE7826EEFC0638DE10DB3E68591FFEDA521BE4A6C5447406B293866292CFAB1CE3E68AED693F1D3EB9EE521962ECA88D7D2629FD9DA3E324C131AFB78B5C41831FF5FDA8D1BCB
+20220716023453 2 6 100 7679 2 D29885507D691EF92591A09643ED996F7CBCB7BC2C100AB3FEF5257A5931CC62D6E976C8702F99622C00702F7A97A8DF2C58E6CE1B087955544A6F08E64CC55AE62AB2F2ACA5CCAAC3FB093CC1D0CD964316B4E10C149B72EF468C7D57DC47980B0B4682B79EA3DB224C5E13BA7B8B0CD8C26BD8E884F0A96B77ED42A749A4556C14B417241BFD807B6B985F8474D53AB3002E46E860DA6AF2FC4387C33540FE64DBA835028710E1A8EB05307283DFA15CB67282334BFFF511D4B6284C18620B0F64A87E026EE576D0C201314CB24FE513DDA9AC0747065B315BAEB2D7AC801CE819708A224840C3C2C23F34DAEF1BED28091CB489EBC99E7B89A285ADC47D3DE4DDB71A5EE4184A642FF8E3E1E67536F7534C67D2A196319B597D7A7A4B2B7D852613818A51FF6CE7D1DF0161AD5F06FFD764F0026354A1CB946F03E37C14F7DD98A9F59A7493F2869AAE39AF064F81DEBF3C94A082CCDA26F5C03367BDA1D1975B5E08CD7E91F02D3537EABB4D98B36D7DAD24C7CB36C850148CD911BA89585653F5B582A23C459A78515E3FC5851B08F8EC2E68736BD7488DC5C73FE40A61DC7F4581C95E20E70E7ECB010365B89CD233A8175A4CE862770D5126AB0E606CD8030490E3B1B05EB3F094B8246259D9A9A84434D02A173F37A9FB883844BFBEE307790649463C4EDE0F1F68D9B61C50004E5F38913D160D5AD214A2C1D85E985A288316951FE89FB77890C1BC16B2DE9920803C9BD746373B0D1F42F829083BC4725EA573509AB8F9DAF3BC3309B4B4A29A8A37023A53B7B73B5DD172809329DC7A966953C30A6A0824EEE510657CEC1F93A9C3CD21D58E8B04B4C877AB6D13D575D206D90ED601E9BB8244944A941CFD382806CF5774E6A61502A63AEB74769B80D65D155FC1F5AD9177C81326DC157750D3B8BB75CF52CD21382BE99983F5AD520351166A4B83A7F2BD8D2EFB143492246F2BAF9247839FDCB947E1EB162E2FB8CD4248DEFCD728929684C6F0DF72F25837EC2A7E23064B9FC38590988B79A5FC925B6E7564167CEE374D24FEB1CF59AD5FF37A65BCBAAE9961DFC805E49EDB3DF6001C2EBBC868E9B4A46AB2BF6D9F060D85E965DB7C5D9E5F4DE5677C1A127A26FFE12C57FCA2ED7A950C89B1CAD3C4E5E279C6D197DAC5300051BDF4A05C2FC76E57F3A7362F145C651AFC9AEBB962A3D7D1FAD0DBFAC833B968DE988A4FC799CE55479D89E5F64A2DBE6102926E49661A000A0B0BD49DE7826EEFC0638DE10DB3E68591FFEDA521BE4A6C5447406B293866292CFAB1CE3E68AED693F1D3EB9EE521962ECA88D7D2629FD9DA3E324C131AFB78B5C41831FF5FDCC2AC1B
+20220716034034 2 6 100 7679 5 D29885507D691EF92591A09643ED996F7CBCB7BC2C100AB3FEF5257A5931CC62D6E976C8702F99622C00702F7A97A8DF2C58E6CE1B087955544A6F08E64CC55AE62AB2F2ACA5CCAAC3FB093CC1D0CD964316B4E10C149B72EF468C7D57DC47980B0B4682B79EA3DB224C5E13BA7B8B0CD8C26BD8E884F0A96B77ED42A749A4556C14B417241BFD807B6B985F8474D53AB3002E46E860DA6AF2FC4387C33540FE64DBA835028710E1A8EB05307283DFA15CB67282334BFFF511D4B6284C18620B0F64A87E026EE576D0C201314CB24FE513DDA9AC0747065B315BAEB2D7AC801CE819708A224840C3C2C23F34DAEF1BED28091CB489EBC99E7B89A285ADC47D3DE4DDB71A5EE4184A642FF8E3E1E67536F7534C67D2A196319B597D7A7A4B2B7D852613818A51FF6CE7D1DF0161AD5F06FFD764F0026354A1CB946F03E37C14F7DD98A9F59A7493F2869AAE39AF064F81DEBF3C94A082CCDA26F5C03367BDA1D1975B5E08CD7E91F02D3537EABB4D98B36D7DAD24C7CB36C850148CD911BA89585653F5B582A23C459A78515E3FC5851B08F8EC2E68736BD7488DC5C73FE40A61DC7F4581C95E20E70E7ECB010365B89CD233A8175A4CE862770D5126AB0E606CD8030490E3B1B05EB3F094B8246259D9A9A84434D02A173F37A9FB883844BFBEE307790649463C4EDE0F1F68D9B61C50004E5F38913D160D5AD214A2C1D85E985A288316951FE89FB77890C1BC16B2DE9920803C9BD746373B0D1F42F829083BC4725EA573509AB8F9DAF3BC3309B4B4A29A8A37023A53B7B73B5DD172809329DC7A966953C30A6A0824EEE510657CEC1F93A9C3CD21D58E8B04B4C877AB6D13D575D206D90ED601E9BB8244944A941CFD382806CF5774E6A61502A63AEB74769B80D65D155FC1F5AD9177C81326DC157750D3B8BB75CF52CD21382BE99983F5AD520351166A4B83A7F2BD8D2EFB143492246F2BAF9247839FDCB947E1EB162E2FB8CD4248DEFCD728929684C6F0DF72F25837EC2A7E23064B9FC38590988B79A5FC925B6E7564167CEE374D24FEB1CF59AD5FF37A65BCBAAE9961DFC805E49EDB3DF6001C2EBBC868E9B4A46AB2BF6D9F060D85E965DB7C5D9E5F4DE5677C1A127A26FFE12C57FCA2ED7A950C89B1CAD3C4E5E279C6D197DAC5300051BDF4A05C2FC76E57F3A7362F145C651AFC9AEBB962A3D7D1FAD0DBFAC833B968DE988A4FC799CE55479D89E5F64A2DBE6102926E49661A000A0B0BD49DE7826EEFC0638DE10DB3E68591FFEDA521BE4A6C5447406B293866292CFAB1CE3E68AED693F1D3EB9EE521962ECA88D7D2629FD9DA3E324C131AFB78B5C41831FF5FE18492D7
+20220716040249 2 6 100 7679 5 D29885507D691EF92591A09643ED996F7CBCB7BC2C100AB3FEF5257A5931CC62D6E976C8702F99622C00702F7A97A8DF2C58E6CE1B087955544A6F08E64CC55AE62AB2F2ACA5CCAAC3FB093CC1D0CD964316B4E10C149B72EF468C7D57DC47980B0B4682B79EA3DB224C5E13BA7B8B0CD8C26BD8E884F0A96B77ED42A749A4556C14B417241BFD807B6B985F8474D53AB3002E46E860DA6AF2FC4387C33540FE64DBA835028710E1A8EB05307283DFA15CB67282334BFFF511D4B6284C18620B0F64A87E026EE576D0C201314CB24FE513DDA9AC0747065B315BAEB2D7AC801CE819708A224840C3C2C23F34DAEF1BED28091CB489EBC99E7B89A285ADC47D3DE4DDB71A5EE4184A642FF8E3E1E67536F7534C67D2A196319B597D7A7A4B2B7D852613818A51FF6CE7D1DF0161AD5F06FFD764F0026354A1CB946F03E37C14F7DD98A9F59A7493F2869AAE39AF064F81DEBF3C94A082CCDA26F5C03367BDA1D1975B5E08CD7E91F02D3537EABB4D98B36D7DAD24C7CB36C850148CD911BA89585653F5B582A23C459A78515E3FC5851B08F8EC2E68736BD7488DC5C73FE40A61DC7F4581C95E20E70E7ECB010365B89CD233A8175A4CE862770D5126AB0E606CD8030490E3B1B05EB3F094B8246259D9A9A84434D02A173F37A9FB883844BFBEE307790649463C4EDE0F1F68D9B61C50004E5F38913D160D5AD214A2C1D85E985A288316951FE89FB77890C1BC16B2DE9920803C9BD746373B0D1F42F829083BC4725EA573509AB8F9DAF3BC3309B4B4A29A8A37023A53B7B73B5DD172809329DC7A966953C30A6A0824EEE510657CEC1F93A9C3CD21D58E8B04B4C877AB6D13D575D206D90ED601E9BB8244944A941CFD382806CF5774E6A61502A63AEB74769B80D65D155FC1F5AD9177C81326DC157750D3B8BB75CF52CD21382BE99983F5AD520351166A4B83A7F2BD8D2EFB143492246F2BAF9247839FDCB947E1EB162E2FB8CD4248DEFCD728929684C6F0DF72F25837EC2A7E23064B9FC38590988B79A5FC925B6E7564167CEE374D24FEB1CF59AD5FF37A65BCBAAE9961DFC805E49EDB3DF6001C2EBBC868E9B4A46AB2BF6D9F060D85E965DB7C5D9E5F4DE5677C1A127A26FFE12C57FCA2ED7A950C89B1CAD3C4E5E279C6D197DAC5300051BDF4A05C2FC76E57F3A7362F145C651AFC9AEBB962A3D7D1FAD0DBFAC833B968DE988A4FC799CE55479D89E5F64A2DBE6102926E49661A000A0B0BD49DE7826EEFC0638DE10DB3E68591FFEDA521BE4A6C5447406B293866292CFAB1CE3E68AED693F1D3EB9EE521962ECA88D7D2629FD9DA3E324C131AFB78B5C41831FF5FE31D1047
+20220716044634 2 6 100 7679 2 D29885507D691EF92591A09643ED996F7CBCB7BC2C100AB3FEF5257A5931CC62D6E976C8702F99622C00702F7A97A8DF2C58E6CE1B087955544A6F08E64CC55AE62AB2F2ACA5CCAAC3FB093CC1D0CD964316B4E10C149B72EF468C7D57DC47980B0B4682B79EA3DB224C5E13BA7B8B0CD8C26BD8E884F0A96B77ED42A749A4556C14B417241BFD807B6B985F8474D53AB3002E46E860DA6AF2FC4387C33540FE64DBA835028710E1A8EB05307283DFA15CB67282334BFFF511D4B6284C18620B0F64A87E026EE576D0C201314CB24FE513DDA9AC0747065B315BAEB2D7AC801CE819708A224840C3C2C23F34DAEF1BED28091CB489EBC99E7B89A285ADC47D3DE4DDB71A5EE4184A642FF8E3E1E67536F7534C67D2A196319B597D7A7A4B2B7D852613818A51FF6CE7D1DF0161AD5F06FFD764F0026354A1CB946F03E37C14F7DD98A9F59A7493F2869AAE39AF064F81DEBF3C94A082CCDA26F5C03367BDA1D1975B5E08CD7E91F02D3537EABB4D98B36D7DAD24C7CB36C850148CD911BA89585653F5B582A23C459A78515E3FC5851B08F8EC2E68736BD7488DC5C73FE40A61DC7F4581C95E20E70E7ECB010365B89CD233A8175A4CE862770D5126AB0E606CD8030490E3B1B05EB3F094B8246259D9A9A84434D02A173F37A9FB883844BFBEE307790649463C4EDE0F1F68D9B61C50004E5F38913D160D5AD214A2C1D85E985A288316951FE89FB77890C1BC16B2DE9920803C9BD746373B0D1F42F829083BC4725EA573509AB8F9DAF3BC3309B4B4A29A8A37023A53B7B73B5DD172809329DC7A966953C30A6A0824EEE510657CEC1F93A9C3CD21D58E8B04B4C877AB6D13D575D206D90ED601E9BB8244944A941CFD382806CF5774E6A61502A63AEB74769B80D65D155FC1F5AD9177C81326DC157750D3B8BB75CF52CD21382BE99983F5AD520351166A4B83A7F2BD8D2EFB143492246F2BAF9247839FDCB947E1EB162E2FB8CD4248DEFCD728929684C6F0DF72F25837EC2A7E23064B9FC38590988B79A5FC925B6E7564167CEE374D24FEB1CF59AD5FF37A65BCBAAE9961DFC805E49EDB3DF6001C2EBBC868E9B4A46AB2BF6D9F060D85E965DB7C5D9E5F4DE5677C1A127A26FFE12C57FCA2ED7A950C89B1CAD3C4E5E279C6D197DAC5300051BDF4A05C2FC76E57F3A7362F145C651AFC9AEBB962A3D7D1FAD0DBFAC833B968DE988A4FC799CE55479D89E5F64A2DBE6102926E49661A000A0B0BD49DE7826EEFC0638DE10DB3E68591FFEDA521BE4A6C5447406B293866292CFAB1CE3E68AED693F1D3EB9EE521962ECA88D7D2629FD9DA3E324C131AFB78B5C41831FF5FE64EDBE3
+20220716051650 2 6 100 7679 2 D29885507D691EF92591A09643ED996F7CBCB7BC2C100AB3FEF5257A5931CC62D6E976C8702F99622C00702F7A97A8DF2C58E6CE1B087955544A6F08E64CC55AE62AB2F2ACA5CCAAC3FB093CC1D0CD964316B4E10C149B72EF468C7D57DC47980B0B4682B79EA3DB224C5E13BA7B8B0CD8C26BD8E884F0A96B77ED42A749A4556C14B417241BFD807B6B985F8474D53AB3002E46E860DA6AF2FC4387C33540FE64DBA835028710E1A8EB05307283DFA15CB67282334BFFF511D4B6284C18620B0F64A87E026EE576D0C201314CB24FE513DDA9AC0747065B315BAEB2D7AC801CE819708A224840C3C2C23F34DAEF1BED28091CB489EBC99E7B89A285ADC47D3DE4DDB71A5EE4184A642FF8E3E1E67536F7534C67D2A196319B597D7A7A4B2B7D852613818A51FF6CE7D1DF0161AD5F06FFD764F0026354A1CB946F03E37C14F7DD98A9F59A7493F2869AAE39AF064F81DEBF3C94A082CCDA26F5C03367BDA1D1975B5E08CD7E91F02D3537EABB4D98B36D7DAD24C7CB36C850148CD911BA89585653F5B582A23C459A78515E3FC5851B08F8EC2E68736BD7488DC5C73FE40A61DC7F4581C95E20E70E7ECB010365B89CD233A8175A4CE862770D5126AB0E606CD8030490E3B1B05EB3F094B8246259D9A9A84434D02A173F37A9FB883844BFBEE307790649463C4EDE0F1F68D9B61C50004E5F38913D160D5AD214A2C1D85E985A288316951FE89FB77890C1BC16B2DE9920803C9BD746373B0D1F42F829083BC4725EA573509AB8F9DAF3BC3309B4B4A29A8A37023A53B7B73B5DD172809329DC7A966953C30A6A0824EEE510657CEC1F93A9C3CD21D58E8B04B4C877AB6D13D575D206D90ED601E9BB8244944A941CFD382806CF5774E6A61502A63AEB74769B80D65D155FC1F5AD9177C81326DC157750D3B8BB75CF52CD21382BE99983F5AD520351166A4B83A7F2BD8D2EFB143492246F2BAF9247839FDCB947E1EB162E2FB8CD4248DEFCD728929684C6F0DF72F25837EC2A7E23064B9FC38590988B79A5FC925B6E7564167CEE374D24FEB1CF59AD5FF37A65BCBAAE9961DFC805E49EDB3DF6001C2EBBC868E9B4A46AB2BF6D9F060D85E965DB7C5D9E5F4DE5677C1A127A26FFE12C57FCA2ED7A950C89B1CAD3C4E5E279C6D197DAC5300051BDF4A05C2FC76E57F3A7362F145C651AFC9AEBB962A3D7D1FAD0DBFAC833B968DE988A4FC799CE55479D89E5F64A2DBE6102926E49661A000A0B0BD49DE7826EEFC0638DE10DB3E68591FFEDA521BE4A6C5447406B293866292CFAB1CE3E68AED693F1D3EB9EE521962ECA88D7D2629FD9DA3E324C131AFB78B5C41831FF5FE87F8BEB
+20220716052859 2 6 100 7679 2 D29885507D691EF92591A09643ED996F7CBCB7BC2C100AB3FEF5257A5931CC62D6E976C8702F99622C00702F7A97A8DF2C58E6CE1B087955544A6F08E64CC55AE62AB2F2ACA5CCAAC3FB093CC1D0CD964316B4E10C149B72EF468C7D57DC47980B0B4682B79EA3DB224C5E13BA7B8B0CD8C26BD8E884F0A96B77ED42A749A4556C14B417241BFD807B6B985F8474D53AB3002E46E860DA6AF2FC4387C33540FE64DBA835028710E1A8EB05307283DFA15CB67282334BFFF511D4B6284C18620B0F64A87E026EE576D0C201314CB24FE513DDA9AC0747065B315BAEB2D7AC801CE819708A224840C3C2C23F34DAEF1BED28091CB489EBC99E7B89A285ADC47D3DE4DDB71A5EE4184A642FF8E3E1E67536F7534C67D2A196319B597D7A7A4B2B7D852613818A51FF6CE7D1DF0161AD5F06FFD764F0026354A1CB946F03E37C14F7DD98A9F59A7493F2869AAE39AF064F81DEBF3C94A082CCDA26F5C03367BDA1D1975B5E08CD7E91F02D3537EABB4D98B36D7DAD24C7CB36C850148CD911BA89585653F5B582A23C459A78515E3FC5851B08F8EC2E68736BD7488DC5C73FE40A61DC7F4581C95E20E70E7ECB010365B89CD233A8175A4CE862770D5126AB0E606CD8030490E3B1B05EB3F094B8246259D9A9A84434D02A173F37A9FB883844BFBEE307790649463C4EDE0F1F68D9B61C50004E5F38913D160D5AD214A2C1D85E985A288316951FE89FB77890C1BC16B2DE9920803C9BD746373B0D1F42F829083BC4725EA573509AB8F9DAF3BC3309B4B4A29A8A37023A53B7B73B5DD172809329DC7A966953C30A6A0824EEE510657CEC1F93A9C3CD21D58E8B04B4C877AB6D13D575D206D90ED601E9BB8244944A941CFD382806CF5774E6A61502A63AEB74769B80D65D155FC1F5AD9177C81326DC157750D3B8BB75CF52CD21382BE99983F5AD520351166A4B83A7F2BD8D2EFB143492246F2BAF9247839FDCB947E1EB162E2FB8CD4248DEFCD728929684C6F0DF72F25837EC2A7E23064B9FC38590988B79A5FC925B6E7564167CEE374D24FEB1CF59AD5FF37A65BCBAAE9961DFC805E49EDB3DF6001C2EBBC868E9B4A46AB2BF6D9F060D85E965DB7C5D9E5F4DE5677C1A127A26FFE12C57FCA2ED7A950C89B1CAD3C4E5E279C6D197DAC5300051BDF4A05C2FC76E57F3A7362F145C651AFC9AEBB962A3D7D1FAD0DBFAC833B968DE988A4FC799CE55479D89E5F64A2DBE6102926E49661A000A0B0BD49DE7826EEFC0638DE10DB3E68591FFEDA521BE4A6C5447406B293866292CFAB1CE3E68AED693F1D3EB9EE521962ECA88D7D2629FD9DA3E324C131AFB78B5C41831FF5FE963564B
+20220716055849 2 6 100 7679 2 D29885507D691EF92591A09643ED996F7CBCB7BC2C100AB3FEF5257A5931CC62D6E976C8702F99622C00702F7A97A8DF2C58E6CE1B087955544A6F08E64CC55AE62AB2F2ACA5CCAAC3FB093CC1D0CD964316B4E10C149B72EF468C7D57DC47980B0B4682B79EA3DB224C5E13BA7B8B0CD8C26BD8E884F0A96B77ED42A749A4556C14B417241BFD807B6B985F8474D53AB3002E46E860DA6AF2FC4387C33540FE64DBA835028710E1A8EB05307283DFA15CB67282334BFFF511D4B6284C18620B0F64A87E026EE576D0C201314CB24FE513DDA9AC0747065B315BAEB2D7AC801CE819708A224840C3C2C23F34DAEF1BED28091CB489EBC99E7B89A285ADC47D3DE4DDB71A5EE4184A642FF8E3E1E67536F7534C67D2A196319B597D7A7A4B2B7D852613818A51FF6CE7D1DF0161AD5F06FFD764F0026354A1CB946F03E37C14F7DD98A9F59A7493F2869AAE39AF064F81DEBF3C94A082CCDA26F5C03367BDA1D1975B5E08CD7E91F02D3537EABB4D98B36D7DAD24C7CB36C850148CD911BA89585653F5B582A23C459A78515E3FC5851B08F8EC2E68736BD7488DC5C73FE40A61DC7F4581C95E20E70E7ECB010365B89CD233A8175A4CE862770D5126AB0E606CD8030490E3B1B05EB3F094B8246259D9A9A84434D02A173F37A9FB883844BFBEE307790649463C4EDE0F1F68D9B61C50004E5F38913D160D5AD214A2C1D85E985A288316951FE89FB77890C1BC16B2DE9920803C9BD746373B0D1F42F829083BC4725EA573509AB8F9DAF3BC3309B4B4A29A8A37023A53B7B73B5DD172809329DC7A966953C30A6A0824EEE510657CEC1F93A9C3CD21D58E8B04B4C877AB6D13D575D206D90ED601E9BB8244944A941CFD382806CF5774E6A61502A63AEB74769B80D65D155FC1F5AD9177C81326DC157750D3B8BB75CF52CD21382BE99983F5AD520351166A4B83A7F2BD8D2EFB143492246F2BAF9247839FDCB947E1EB162E2FB8CD4248DEFCD728929684C6F0DF72F25837EC2A7E23064B9FC38590988B79A5FC925B6E7564167CEE374D24FEB1CF59AD5FF37A65BCBAAE9961DFC805E49EDB3DF6001C2EBBC868E9B4A46AB2BF6D9F060D85E965DB7C5D9E5F4DE5677C1A127A26FFE12C57FCA2ED7A950C89B1CAD3C4E5E279C6D197DAC5300051BDF4A05C2FC76E57F3A7362F145C651AFC9AEBB962A3D7D1FAD0DBFAC833B968DE988A4FC799CE55479D89E5F64A2DBE6102926E49661A000A0B0BD49DE7826EEFC0638DE10DB3E68591FFEDA521BE4A6C5447406B293866292CFAB1CE3E68AED693F1D3EB9EE521962ECA88D7D2629FD9DA3E324C131AFB78B5C41831FF5FEB816243
+20220716063757 2 6 100 7679 5 D29885507D691EF92591A09643ED996F7CBCB7BC2C100AB3FEF5257A5931CC62D6E976C8702F99622C00702F7A97A8DF2C58E6CE1B087955544A6F08E64CC55AE62AB2F2ACA5CCAAC3FB093CC1D0CD964316B4E10C149B72EF468C7D57DC47980B0B4682B79EA3DB224C5E13BA7B8B0CD8C26BD8E884F0A96B77ED42A749A4556C14B417241BFD807B6B985F8474D53AB3002E46E860DA6AF2FC4387C33540FE64DBA835028710E1A8EB05307283DFA15CB67282334BFFF511D4B6284C18620B0F64A87E026EE576D0C201314CB24FE513DDA9AC0747065B315BAEB2D7AC801CE819708A224840C3C2C23F34DAEF1BED28091CB489EBC99E7B89A285ADC47D3DE4DDB71A5EE4184A642FF8E3E1E67536F7534C67D2A196319B597D7A7A4B2B7D852613818A51FF6CE7D1DF0161AD5F06FFD764F0026354A1CB946F03E37C14F7DD98A9F59A7493F2869AAE39AF064F81DEBF3C94A082CCDA26F5C03367BDA1D1975B5E08CD7E91F02D3537EABB4D98B36D7DAD24C7CB36C850148CD911BA89585653F5B582A23C459A78515E3FC5851B08F8EC2E68736BD7488DC5C73FE40A61DC7F4581C95E20E70E7ECB010365B89CD233A8175A4CE862770D5126AB0E606CD8030490E3B1B05EB3F094B8246259D9A9A84434D02A173F37A9FB883844BFBEE307790649463C4EDE0F1F68D9B61C50004E5F38913D160D5AD214A2C1D85E985A288316951FE89FB77890C1BC16B2DE9920803C9BD746373B0D1F42F829083BC4725EA573509AB8F9DAF3BC3309B4B4A29A8A37023A53B7B73B5DD172809329DC7A966953C30A6A0824EEE510657CEC1F93A9C3CD21D58E8B04B4C877AB6D13D575D206D90ED601E9BB8244944A941CFD382806CF5774E6A61502A63AEB74769B80D65D155FC1F5AD9177C81326DC157750D3B8BB75CF52CD21382BE99983F5AD520351166A4B83A7F2BD8D2EFB143492246F2BAF9247839FDCB947E1EB162E2FB8CD4248DEFCD728929684C6F0DF72F25837EC2A7E23064B9FC38590988B79A5FC925B6E7564167CEE374D24FEB1CF59AD5FF37A65BCBAAE9961DFC805E49EDB3DF6001C2EBBC868E9B4A46AB2BF6D9F060D85E965DB7C5D9E5F4DE5677C1A127A26FFE12C57FCA2ED7A950C89B1CAD3C4E5E279C6D197DAC5300051BDF4A05C2FC76E57F3A7362F145C651AFC9AEBB962A3D7D1FAD0DBFAC833B968DE988A4FC799CE55479D89E5F64A2DBE6102926E49661A000A0B0BD49DE7826EEFC0638DE10DB3E68591FFEDA521BE4A6C5447406B293866292CFAB1CE3E68AED693F1D3EB9EE521962ECA88D7D2629FD9DA3E324C131AFB78B5C41831FF5FEE5510C7
+20220716071444 2 6 100 7679 2 D29885507D691EF92591A09643ED996F7CBCB7BC2C100AB3FEF5257A5931CC62D6E976C8702F99622C00702F7A97A8DF2C58E6CE1B087955544A6F08E64CC55AE62AB2F2ACA5CCAAC3FB093CC1D0CD964316B4E10C149B72EF468C7D57DC47980B0B4682B79EA3DB224C5E13BA7B8B0CD8C26BD8E884F0A96B77ED42A749A4556C14B417241BFD807B6B985F8474D53AB3002E46E860DA6AF2FC4387C33540FE64DBA835028710E1A8EB05307283DFA15CB67282334BFFF511D4B6284C18620B0F64A87E026EE576D0C201314CB24FE513DDA9AC0747065B315BAEB2D7AC801CE819708A224840C3C2C23F34DAEF1BED28091CB489EBC99E7B89A285ADC47D3DE4DDB71A5EE4184A642FF8E3E1E67536F7534C67D2A196319B597D7A7A4B2B7D852613818A51FF6CE7D1DF0161AD5F06FFD764F0026354A1CB946F03E37C14F7DD98A9F59A7493F2869AAE39AF064F81DEBF3C94A082CCDA26F5C03367BDA1D1975B5E08CD7E91F02D3537EABB4D98B36D7DAD24C7CB36C850148CD911BA89585653F5B582A23C459A78515E3FC5851B08F8EC2E68736BD7488DC5C73FE40A61DC7F4581C95E20E70E7ECB010365B89CD233A8175A4CE862770D5126AB0E606CD8030490E3B1B05EB3F094B8246259D9A9A84434D02A173F37A9FB883844BFBEE307790649463C4EDE0F1F68D9B61C50004E5F38913D160D5AD214A2C1D85E985A288316951FE89FB77890C1BC16B2DE9920803C9BD746373B0D1F42F829083BC4725EA573509AB8F9DAF3BC3309B4B4A29A8A37023A53B7B73B5DD172809329DC7A966953C30A6A0824EEE510657CEC1F93A9C3CD21D58E8B04B4C877AB6D13D575D206D90ED601E9BB8244944A941CFD382806CF5774E6A61502A63AEB74769B80D65D155FC1F5AD9177C81326DC157750D3B8BB75CF52CD21382BE99983F5AD520351166A4B83A7F2BD8D2EFB143492246F2BAF9247839FDCB947E1EB162E2FB8CD4248DEFCD728929684C6F0DF72F25837EC2A7E23064B9FC38590988B79A5FC925B6E7564167CEE374D24FEB1CF59AD5FF37A65BCBAAE9961DFC805E49EDB3DF6001C2EBBC868E9B4A46AB2BF6D9F060D85E965DB7C5D9E5F4DE5677C1A127A26FFE12C57FCA2ED7A950C89B1CAD3C4E5E279C6D197DAC5300051BDF4A05C2FC76E57F3A7362F145C651AFC9AEBB962A3D7D1FAD0DBFAC833B968DE988A4FC799CE55479D89E5F64A2DBE6102926E49661A000A0B0BD49DE7826EEFC0638DE10DB3E68591FFEDA521BE4A6C5447406B293866292CFAB1CE3E68AED693F1D3EB9EE521962ECA88D7D2629FD9DA3E324C131AFB78B5C41831FF5FF0F7F9DB
+20220716071604 2 6 100 7679 2 D29885507D691EF92591A09643ED996F7CBCB7BC2C100AB3FEF5257A5931CC62D6E976C8702F99622C00702F7A97A8DF2C58E6CE1B087955544A6F08E64CC55AE62AB2F2ACA5CCAAC3FB093CC1D0CD964316B4E10C149B72EF468C7D57DC47980B0B4682B79EA3DB224C5E13BA7B8B0CD8C26BD8E884F0A96B77ED42A749A4556C14B417241BFD807B6B985F8474D53AB3002E46E860DA6AF2FC4387C33540FE64DBA835028710E1A8EB05307283DFA15CB67282334BFFF511D4B6284C18620B0F64A87E026EE576D0C201314CB24FE513DDA9AC0747065B315BAEB2D7AC801CE819708A224840C3C2C23F34DAEF1BED28091CB489EBC99E7B89A285ADC47D3DE4DDB71A5EE4184A642FF8E3E1E67536F7534C67D2A196319B597D7A7A4B2B7D852613818A51FF6CE7D1DF0161AD5F06FFD764F0026354A1CB946F03E37C14F7DD98A9F59A7493F2869AAE39AF064F81DEBF3C94A082CCDA26F5C03367BDA1D1975B5E08CD7E91F02D3537EABB4D98B36D7DAD24C7CB36C850148CD911BA89585653F5B582A23C459A78515E3FC5851B08F8EC2E68736BD7488DC5C73FE40A61DC7F4581C95E20E70E7ECB010365B89CD233A8175A4CE862770D5126AB0E606CD8030490E3B1B05EB3F094B8246259D9A9A84434D02A173F37A9FB883844BFBEE307790649463C4EDE0F1F68D9B61C50004E5F38913D160D5AD214A2C1D85E985A288316951FE89FB77890C1BC16B2DE9920803C9BD746373B0D1F42F829083BC4725EA573509AB8F9DAF3BC3309B4B4A29A8A37023A53B7B73B5DD172809329DC7A966953C30A6A0824EEE510657CEC1F93A9C3CD21D58E8B04B4C877AB6D13D575D206D90ED601E9BB8244944A941CFD382806CF5774E6A61502A63AEB74769B80D65D155FC1F5AD9177C81326DC157750D3B8BB75CF52CD21382BE99983F5AD520351166A4B83A7F2BD8D2EFB143492246F2BAF9247839FDCB947E1EB162E2FB8CD4248DEFCD728929684C6F0DF72F25837EC2A7E23064B9FC38590988B79A5FC925B6E7564167CEE374D24FEB1CF59AD5FF37A65BCBAAE9961DFC805E49EDB3DF6001C2EBBC868E9B4A46AB2BF6D9F060D85E965DB7C5D9E5F4DE5677C1A127A26FFE12C57FCA2ED7A950C89B1CAD3C4E5E279C6D197DAC5300051BDF4A05C2FC76E57F3A7362F145C651AFC9AEBB962A3D7D1FAD0DBFAC833B968DE988A4FC799CE55479D89E5F64A2DBE6102926E49661A000A0B0BD49DE7826EEFC0638DE10DB3E68591FFEDA521BE4A6C5447406B293866292CFAB1CE3E68AED693F1D3EB9EE521962ECA88D7D2629FD9DA3E324C131AFB78B5C41831FF5FF10F3AFB
+20220716073329 2 6 100 7679 5 D29885507D691EF92591A09643ED996F7CBCB7BC2C100AB3FEF5257A5931CC62D6E976C8702F99622C00702F7A97A8DF2C58E6CE1B087955544A6F08E64CC55AE62AB2F2ACA5CCAAC3FB093CC1D0CD964316B4E10C149B72EF468C7D57DC47980B0B4682B79EA3DB224C5E13BA7B8B0CD8C26BD8E884F0A96B77ED42A749A4556C14B417241BFD807B6B985F8474D53AB3002E46E860DA6AF2FC4387C33540FE64DBA835028710E1A8EB05307283DFA15CB67282334BFFF511D4B6284C18620B0F64A87E026EE576D0C201314CB24FE513DDA9AC0747065B315BAEB2D7AC801CE819708A224840C3C2C23F34DAEF1BED28091CB489EBC99E7B89A285ADC47D3DE4DDB71A5EE4184A642FF8E3E1E67536F7534C67D2A196319B597D7A7A4B2B7D852613818A51FF6CE7D1DF0161AD5F06FFD764F0026354A1CB946F03E37C14F7DD98A9F59A7493F2869AAE39AF064F81DEBF3C94A082CCDA26F5C03367BDA1D1975B5E08CD7E91F02D3537EABB4D98B36D7DAD24C7CB36C850148CD911BA89585653F5B582A23C459A78515E3FC5851B08F8EC2E68736BD7488DC5C73FE40A61DC7F4581C95E20E70E7ECB010365B89CD233A8175A4CE862770D5126AB0E606CD8030490E3B1B05EB3F094B8246259D9A9A84434D02A173F37A9FB883844BFBEE307790649463C4EDE0F1F68D9B61C50004E5F38913D160D5AD214A2C1D85E985A288316951FE89FB77890C1BC16B2DE9920803C9BD746373B0D1F42F829083BC4725EA573509AB8F9DAF3BC3309B4B4A29A8A37023A53B7B73B5DD172809329DC7A966953C30A6A0824EEE510657CEC1F93A9C3CD21D58E8B04B4C877AB6D13D575D206D90ED601E9BB8244944A941CFD382806CF5774E6A61502A63AEB74769B80D65D155FC1F5AD9177C81326DC157750D3B8BB75CF52CD21382BE99983F5AD520351166A4B83A7F2BD8D2EFB143492246F2BAF9247839FDCB947E1EB162E2FB8CD4248DEFCD728929684C6F0DF72F25837EC2A7E23064B9FC38590988B79A5FC925B6E7564167CEE374D24FEB1CF59AD5FF37A65BCBAAE9961DFC805E49EDB3DF6001C2EBBC868E9B4A46AB2BF6D9F060D85E965DB7C5D9E5F4DE5677C1A127A26FFE12C57FCA2ED7A950C89B1CAD3C4E5E279C6D197DAC5300051BDF4A05C2FC76E57F3A7362F145C651AFC9AEBB962A3D7D1FAD0DBFAC833B968DE988A4FC799CE55479D89E5F64A2DBE6102926E49661A000A0B0BD49DE7826EEFC0638DE10DB3E68591FFEDA521BE4A6C5447406B293866292CFAB1CE3E68AED693F1D3EB9EE521962ECA88D7D2629FD9DA3E324C131AFB78B5C41831FF5FF251281F
+20220716074224 2 6 100 7679 2 D29885507D691EF92591A09643ED996F7CBCB7BC2C100AB3FEF5257A5931CC62D6E976C8702F99622C00702F7A97A8DF2C58E6CE1B087955544A6F08E64CC55AE62AB2F2ACA5CCAAC3FB093CC1D0CD964316B4E10C149B72EF468C7D57DC47980B0B4682B79EA3DB224C5E13BA7B8B0CD8C26BD8E884F0A96B77ED42A749A4556C14B417241BFD807B6B985F8474D53AB3002E46E860DA6AF2FC4387C33540FE64DBA835028710E1A8EB05307283DFA15CB67282334BFFF511D4B6284C18620B0F64A87E026EE576D0C201314CB24FE513DDA9AC0747065B315BAEB2D7AC801CE819708A224840C3C2C23F34DAEF1BED28091CB489EBC99E7B89A285ADC47D3DE4DDB71A5EE4184A642FF8E3E1E67536F7534C67D2A196319B597D7A7A4B2B7D852613818A51FF6CE7D1DF0161AD5F06FFD764F0026354A1CB946F03E37C14F7DD98A9F59A7493F2869AAE39AF064F81DEBF3C94A082CCDA26F5C03367BDA1D1975B5E08CD7E91F02D3537EABB4D98B36D7DAD24C7CB36C850148CD911BA89585653F5B582A23C459A78515E3FC5851B08F8EC2E68736BD7488DC5C73FE40A61DC7F4581C95E20E70E7ECB010365B89CD233A8175A4CE862770D5126AB0E606CD8030490E3B1B05EB3F094B8246259D9A9A84434D02A173F37A9FB883844BFBEE307790649463C4EDE0F1F68D9B61C50004E5F38913D160D5AD214A2C1D85E985A288316951FE89FB77890C1BC16B2DE9920803C9BD746373B0D1F42F829083BC4725EA573509AB8F9DAF3BC3309B4B4A29A8A37023A53B7B73B5DD172809329DC7A966953C30A6A0824EEE510657CEC1F93A9C3CD21D58E8B04B4C877AB6D13D575D206D90ED601E9BB8244944A941CFD382806CF5774E6A61502A63AEB74769B80D65D155FC1F5AD9177C81326DC157750D3B8BB75CF52CD21382BE99983F5AD520351166A4B83A7F2BD8D2EFB143492246F2BAF9247839FDCB947E1EB162E2FB8CD4248DEFCD728929684C6F0DF72F25837EC2A7E23064B9FC38590988B79A5FC925B6E7564167CEE374D24FEB1CF59AD5FF37A65BCBAAE9961DFC805E49EDB3DF6001C2EBBC868E9B4A46AB2BF6D9F060D85E965DB7C5D9E5F4DE5677C1A127A26FFE12C57FCA2ED7A950C89B1CAD3C4E5E279C6D197DAC5300051BDF4A05C2FC76E57F3A7362F145C651AFC9AEBB962A3D7D1FAD0DBFAC833B968DE988A4FC799CE55479D89E5F64A2DBE6102926E49661A000A0B0BD49DE7826EEFC0638DE10DB3E68591FFEDA521BE4A6C5447406B293866292CFAB1CE3E68AED693F1D3EB9EE521962ECA88D7D2629FD9DA3E324C131AFB78B5C41831FF5FF2F3BB2B
+20220716074605 2 6 100 7679 2 D29885507D691EF92591A09643ED996F7CBCB7BC2C100AB3FEF5257A5931CC62D6E976C8702F99622C00702F7A97A8DF2C58E6CE1B087955544A6F08E64CC55AE62AB2F2ACA5CCAAC3FB093CC1D0CD964316B4E10C149B72EF468C7D57DC47980B0B4682B79EA3DB224C5E13BA7B8B0CD8C26BD8E884F0A96B77ED42A749A4556C14B417241BFD807B6B985F8474D53AB3002E46E860DA6AF2FC4387C33540FE64DBA835028710E1A8EB05307283DFA15CB67282334BFFF511D4B6284C18620B0F64A87E026EE576D0C201314CB24FE513DDA9AC0747065B315BAEB2D7AC801CE819708A224840C3C2C23F34DAEF1BED28091CB489EBC99E7B89A285ADC47D3DE4DDB71A5EE4184A642FF8E3E1E67536F7534C67D2A196319B597D7A7A4B2B7D852613818A51FF6CE7D1DF0161AD5F06FFD764F0026354A1CB946F03E37C14F7DD98A9F59A7493F2869AAE39AF064F81DEBF3C94A082CCDA26F5C03367BDA1D1975B5E08CD7E91F02D3537EABB4D98B36D7DAD24C7CB36C850148CD911BA89585653F5B582A23C459A78515E3FC5851B08F8EC2E68736BD7488DC5C73FE40A61DC7F4581C95E20E70E7ECB010365B89CD233A8175A4CE862770D5126AB0E606CD8030490E3B1B05EB3F094B8246259D9A9A84434D02A173F37A9FB883844BFBEE307790649463C4EDE0F1F68D9B61C50004E5F38913D160D5AD214A2C1D85E985A288316951FE89FB77890C1BC16B2DE9920803C9BD746373B0D1F42F829083BC4725EA573509AB8F9DAF3BC3309B4B4A29A8A37023A53B7B73B5DD172809329DC7A966953C30A6A0824EEE510657CEC1F93A9C3CD21D58E8B04B4C877AB6D13D575D206D90ED601E9BB8244944A941CFD382806CF5774E6A61502A63AEB74769B80D65D155FC1F5AD9177C81326DC157750D3B8BB75CF52CD21382BE99983F5AD520351166A4B83A7F2BD8D2EFB143492246F2BAF9247839FDCB947E1EB162E2FB8CD4248DEFCD728929684C6F0DF72F25837EC2A7E23064B9FC38590988B79A5FC925B6E7564167CEE374D24FEB1CF59AD5FF37A65BCBAAE9961DFC805E49EDB3DF6001C2EBBC868E9B4A46AB2BF6D9F060D85E965DB7C5D9E5F4DE5677C1A127A26FFE12C57FCA2ED7A950C89B1CAD3C4E5E279C6D197DAC5300051BDF4A05C2FC76E57F3A7362F145C651AFC9AEBB962A3D7D1FAD0DBFAC833B968DE988A4FC799CE55479D89E5F64A2DBE6102926E49661A000A0B0BD49DE7826EEFC0638DE10DB3E68591FFEDA521BE4A6C5447406B293866292CFAB1CE3E68AED693F1D3EB9EE521962ECA88D7D2629FD9DA3E324C131AFB78B5C41831FF5FF338BF7B
+20220716075807 2 6 100 7679 5 D29885507D691EF92591A09643ED996F7CBCB7BC2C100AB3FEF5257A5931CC62D6E976C8702F99622C00702F7A97A8DF2C58E6CE1B087955544A6F08E64CC55AE62AB2F2ACA5CCAAC3FB093CC1D0CD964316B4E10C149B72EF468C7D57DC47980B0B4682B79EA3DB224C5E13BA7B8B0CD8C26BD8E884F0A96B77ED42A749A4556C14B417241BFD807B6B985F8474D53AB3002E46E860DA6AF2FC4387C33540FE64DBA835028710E1A8EB05307283DFA15CB67282334BFFF511D4B6284C18620B0F64A87E026EE576D0C201314CB24FE513DDA9AC0747065B315BAEB2D7AC801CE819708A224840C3C2C23F34DAEF1BED28091CB489EBC99E7B89A285ADC47D3DE4DDB71A5EE4184A642FF8E3E1E67536F7534C67D2A196319B597D7A7A4B2B7D852613818A51FF6CE7D1DF0161AD5F06FFD764F0026354A1CB946F03E37C14F7DD98A9F59A7493F2869AAE39AF064F81DEBF3C94A082CCDA26F5C03367BDA1D1975B5E08CD7E91F02D3537EABB4D98B36D7DAD24C7CB36C850148CD911BA89585653F5B582A23C459A78515E3FC5851B08F8EC2E68736BD7488DC5C73FE40A61DC7F4581C95E20E70E7ECB010365B89CD233A8175A4CE862770D5126AB0E606CD8030490E3B1B05EB3F094B8246259D9A9A84434D02A173F37A9FB883844BFBEE307790649463C4EDE0F1F68D9B61C50004E5F38913D160D5AD214A2C1D85E985A288316951FE89FB77890C1BC16B2DE9920803C9BD746373B0D1F42F829083BC4725EA573509AB8F9DAF3BC3309B4B4A29A8A37023A53B7B73B5DD172809329DC7A966953C30A6A0824EEE510657CEC1F93A9C3CD21D58E8B04B4C877AB6D13D575D206D90ED601E9BB8244944A941CFD382806CF5774E6A61502A63AEB74769B80D65D155FC1F5AD9177C81326DC157750D3B8BB75CF52CD21382BE99983F5AD520351166A4B83A7F2BD8D2EFB143492246F2BAF9247839FDCB947E1EB162E2FB8CD4248DEFCD728929684C6F0DF72F25837EC2A7E23064B9FC38590988B79A5FC925B6E7564167CEE374D24FEB1CF59AD5FF37A65BCBAAE9961DFC805E49EDB3DF6001C2EBBC868E9B4A46AB2BF6D9F060D85E965DB7C5D9E5F4DE5677C1A127A26FFE12C57FCA2ED7A950C89B1CAD3C4E5E279C6D197DAC5300051BDF4A05C2FC76E57F3A7362F145C651AFC9AEBB962A3D7D1FAD0DBFAC833B968DE988A4FC799CE55479D89E5F64A2DBE6102926E49661A000A0B0BD49DE7826EEFC0638DE10DB3E68591FFEDA521BE4A6C5447406B293866292CFAB1CE3E68AED693F1D3EB9EE521962ECA88D7D2629FD9DA3E324C131AFB78B5C41831FF5FF4157C77
+20220716082904 2 6 100 7679 2 D29885507D691EF92591A09643ED996F7CBCB7BC2C100AB3FEF5257A5931CC62D6E976C8702F99622C00702F7A97A8DF2C58E6CE1B087955544A6F08E64CC55AE62AB2F2ACA5CCAAC3FB093CC1D0CD964316B4E10C149B72EF468C7D57DC47980B0B4682B79EA3DB224C5E13BA7B8B0CD8C26BD8E884F0A96B77ED42A749A4556C14B417241BFD807B6B985F8474D53AB3002E46E860DA6AF2FC4387C33540FE64DBA835028710E1A8EB05307283DFA15CB67282334BFFF511D4B6284C18620B0F64A87E026EE576D0C201314CB24FE513DDA9AC0747065B315BAEB2D7AC801CE819708A224840C3C2C23F34DAEF1BED28091CB489EBC99E7B89A285ADC47D3DE4DDB71A5EE4184A642FF8E3E1E67536F7534C67D2A196319B597D7A7A4B2B7D852613818A51FF6CE7D1DF0161AD5F06FFD764F0026354A1CB946F03E37C14F7DD98A9F59A7493F2869AAE39AF064F81DEBF3C94A082CCDA26F5C03367BDA1D1975B5E08CD7E91F02D3537EABB4D98B36D7DAD24C7CB36C850148CD911BA89585653F5B582A23C459A78515E3FC5851B08F8EC2E68736BD7488DC5C73FE40A61DC7F4581C95E20E70E7ECB010365B89CD233A8175A4CE862770D5126AB0E606CD8030490E3B1B05EB3F094B8246259D9A9A84434D02A173F37A9FB883844BFBEE307790649463C4EDE0F1F68D9B61C50004E5F38913D160D5AD214A2C1D85E985A288316951FE89FB77890C1BC16B2DE9920803C9BD746373B0D1F42F829083BC4725EA573509AB8F9DAF3BC3309B4B4A29A8A37023A53B7B73B5DD172809329DC7A966953C30A6A0824EEE510657CEC1F93A9C3CD21D58E8B04B4C877AB6D13D575D206D90ED601E9BB8244944A941CFD382806CF5774E6A61502A63AEB74769B80D65D155FC1F5AD9177C81326DC157750D3B8BB75CF52CD21382BE99983F5AD520351166A4B83A7F2BD8D2EFB143492246F2BAF9247839FDCB947E1EB162E2FB8CD4248DEFCD728929684C6F0DF72F25837EC2A7E23064B9FC38590988B79A5FC925B6E7564167CEE374D24FEB1CF59AD5FF37A65BCBAAE9961DFC805E49EDB3DF6001C2EBBC868E9B4A46AB2BF6D9F060D85E965DB7C5D9E5F4DE5677C1A127A26FFE12C57FCA2ED7A950C89B1CAD3C4E5E279C6D197DAC5300051BDF4A05C2FC76E57F3A7362F145C651AFC9AEBB962A3D7D1FAD0DBFAC833B968DE988A4FC799CE55479D89E5F64A2DBE6102926E49661A000A0B0BD49DE7826EEFC0638DE10DB3E68591FFEDA521BE4A6C5447406B293866292CFAB1CE3E68AED693F1D3EB9EE521962ECA88D7D2629FD9DA3E324C131AFB78B5C41831FF5FF657E773
+20220716083710 2 6 100 7679 2 D29885507D691EF92591A09643ED996F7CBCB7BC2C100AB3FEF5257A5931CC62D6E976C8702F99622C00702F7A97A8DF2C58E6CE1B087955544A6F08E64CC55AE62AB2F2ACA5CCAAC3FB093CC1D0CD964316B4E10C149B72EF468C7D57DC47980B0B4682B79EA3DB224C5E13BA7B8B0CD8C26BD8E884F0A96B77ED42A749A4556C14B417241BFD807B6B985F8474D53AB3002E46E860DA6AF2FC4387C33540FE64DBA835028710E1A8EB05307283DFA15CB67282334BFFF511D4B6284C18620B0F64A87E026EE576D0C201314CB24FE513DDA9AC0747065B315BAEB2D7AC801CE819708A224840C3C2C23F34DAEF1BED28091CB489EBC99E7B89A285ADC47D3DE4DDB71A5EE4184A642FF8E3E1E67536F7534C67D2A196319B597D7A7A4B2B7D852613818A51FF6CE7D1DF0161AD5F06FFD764F0026354A1CB946F03E37C14F7DD98A9F59A7493F2869AAE39AF064F81DEBF3C94A082CCDA26F5C03367BDA1D1975B5E08CD7E91F02D3537EABB4D98B36D7DAD24C7CB36C850148CD911BA89585653F5B582A23C459A78515E3FC5851B08F8EC2E68736BD7488DC5C73FE40A61DC7F4581C95E20E70E7ECB010365B89CD233A8175A4CE862770D5126AB0E606CD8030490E3B1B05EB3F094B8246259D9A9A84434D02A173F37A9FB883844BFBEE307790649463C4EDE0F1F68D9B61C50004E5F38913D160D5AD214A2C1D85E985A288316951FE89FB77890C1BC16B2DE9920803C9BD746373B0D1F42F829083BC4725EA573509AB8F9DAF3BC3309B4B4A29A8A37023A53B7B73B5DD172809329DC7A966953C30A6A0824EEE510657CEC1F93A9C3CD21D58E8B04B4C877AB6D13D575D206D90ED601E9BB8244944A941CFD382806CF5774E6A61502A63AEB74769B80D65D155FC1F5AD9177C81326DC157750D3B8BB75CF52CD21382BE99983F5AD520351166A4B83A7F2BD8D2EFB143492246F2BAF9247839FDCB947E1EB162E2FB8CD4248DEFCD728929684C6F0DF72F25837EC2A7E23064B9FC38590988B79A5FC925B6E7564167CEE374D24FEB1CF59AD5FF37A65BCBAAE9961DFC805E49EDB3DF6001C2EBBC868E9B4A46AB2BF6D9F060D85E965DB7C5D9E5F4DE5677C1A127A26FFE12C57FCA2ED7A950C89B1CAD3C4E5E279C6D197DAC5300051BDF4A05C2FC76E57F3A7362F145C651AFC9AEBB962A3D7D1FAD0DBFAC833B968DE988A4FC799CE55479D89E5F64A2DBE6102926E49661A000A0B0BD49DE7826EEFC0638DE10DB3E68591FFEDA521BE4A6C5447406B293866292CFAB1CE3E68AED693F1D3EB9EE521962ECA88D7D2629FD9DA3E324C131AFB78B5C41831FF5FF6EF1FA3
+20220716120340 2 6 100 7679 5 EA4C603AE36BD71059D57FCCBE1B8044C230D76993BB57E1277B27A6C4A4B08347D6279C073FCF3AAD938D631C2E6E154467895D8B122C872ED09D0C78541A55F8830207EFC2CA1556E6D9E0E78B0312C663061F6B0692FBB22CA020B4CC24E01DA76F8DC12D2BB87459FC747E3ECE875C8AD2879CD41BD91192BDEB4F30701EB53DD437163646BB8CEDCF66068617495CA9D1611A5C9E4D531A3B575745036E3A3D933984464EB3D86C30ABB3219805BA78FDA311A8F734BCCC83463CDC569AFFB0ECED647616BB7BC3C9865E79E2C4E711F2EB4A2DA078AFF66C15BEAEE0B581037715C505BFB0FE9A9FA47121981F8528DFD137FA66D33083E6F4B74BF2C4AAF0754D0E704803F0F16DF0A9FE41E0C237FFB72BCF0E458F009A77A3E096FD6BDB4799B70C9CE864A108B66D34B56DC9F390CAEBFFC15DAD572F8E57D7CAC68ECE12652303221AF1CC9AD239473CA7E14A1B7B9A6EBF827813340F6D1C97032A7A1FEF147A202A274B0C17F9DCA25214180FA619E3201C174D4B0DDA30D4A1F3EF179126EF859526C539E075EB6E91E2E30AC104FBC69D940D5A70225BBDE026CBBF357DC7543BF3F83A7525AB8F96FDEC0464CD4EB3B106984BD1C4F27BF166079C66790F1CA1AFB56A3B780F6927143E9F85687A2A99F77C46806D8E1C190147CF42E2D1D9A70F964A5CC63D813511685F6BEE77E20CD38D58334EFE7EC2F068A26426001A83758DC82E9B0300CC2FAA0999616147B6B2BF93CBE227D8586CF54FCED628C1AD540844FB6E57CC378881FC90FC3989536CA13F097EAD6F0B45356C6A9DA87873793E68AA272D5253CA239515318649B54DEB926AF82E3D9DE7DBBA0962ED73A8233577E7073A303EDFFFA7E94D596CCECA2BC8BA08A5DBE249F45232C3675FBD21A32E9B489C7804E2C406C7B4B071976E8064A91C5E53A5316CBA74A5398A625B8BAAAFA34A225E54AC174ACEEA6135EFDB59FF42774E3E30B1C8D4CDC20F8803AF0743A8CD0343C8A6065D94C0EB262BD8CB2556D1C9639E52087DDF83698A6040619246D3DAD1CCC8F5373E06FA90AFAC990E64E91EF4C0315AF1F1114B61FC7E8198BA27E7519D81842534D19E4EDF1F356D150F389F1F3D4942A68F08A404E551A4387D1D81ACFC1BD8721B228371DF7FFD9153C3E3EE705E950C2BE384CEB19E47F04C7631F67D7AFF302BD1901648855D8E585605823A95AE079C3C278DF3C5FBB5F40D35473544A37DFA2F3A1EA09908340706E655AAB5DC8C54637738A77DAF6777221463D125A2D9DDE153A0BC99A92A4FFEECCB766F012AC74909A66DD6828F23C6B3C45A2AEEE593DECA2A6FA5F9C6CA376F
+20220716142712 2 6 100 7679 5 EA4C603AE36BD71059D57FCCBE1B8044C230D76993BB57E1277B27A6C4A4B08347D6279C073FCF3AAD938D631C2E6E154467895D8B122C872ED09D0C78541A55F8830207EFC2CA1556E6D9E0E78B0312C663061F6B0692FBB22CA020B4CC24E01DA76F8DC12D2BB87459FC747E3ECE875C8AD2879CD41BD91192BDEB4F30701EB53DD437163646BB8CEDCF66068617495CA9D1611A5C9E4D531A3B575745036E3A3D933984464EB3D86C30ABB3219805BA78FDA311A8F734BCCC83463CDC569AFFB0ECED647616BB7BC3C9865E79E2C4E711F2EB4A2DA078AFF66C15BEAEE0B581037715C505BFB0FE9A9FA47121981F8528DFD137FA66D33083E6F4B74BF2C4AAF0754D0E704803F0F16DF0A9FE41E0C237FFB72BCF0E458F009A77A3E096FD6BDB4799B70C9CE864A108B66D34B56DC9F390CAEBFFC15DAD572F8E57D7CAC68ECE12652303221AF1CC9AD239473CA7E14A1B7B9A6EBF827813340F6D1C97032A7A1FEF147A202A274B0C17F9DCA25214180FA619E3201C174D4B0DDA30D4A1F3EF179126EF859526C539E075EB6E91E2E30AC104FBC69D940D5A70225BBDE026CBBF357DC7543BF3F83A7525AB8F96FDEC0464CD4EB3B106984BD1C4F27BF166079C66790F1CA1AFB56A3B780F6927143E9F85687A2A99F77C46806D8E1C190147CF42E2D1D9A70F964A5CC63D813511685F6BEE77E20CD38D58334EFE7EC2F068A26426001A83758DC82E9B0300CC2FAA0999616147B6B2BF93CBE227D8586CF54FCED628C1AD540844FB6E57CC378881FC90FC3989536CA13F097EAD6F0B45356C6A9DA87873793E68AA272D5253CA239515318649B54DEB926AF82E3D9DE7DBBA0962ED73A8233577E7073A303EDFFFA7E94D596CCECA2BC8BA08A5DBE249F45232C3675FBD21A32E9B489C7804E2C406C7B4B071976E8064A91C5E53A5316CBA74A5398A625B8BAAAFA34A225E54AC174ACEEA6135EFDB59FF42774E3E30B1C8D4CDC20F8803AF0743A8CD0343C8A6065D94C0EB262BD8CB2556D1C9639E52087DDF83698A6040619246D3DAD1CCC8F5373E06FA90AFAC990E64E91EF4C0315AF1F1114B61FC7E8198BA27E7519D81842534D19E4EDF1F356D150F389F1F3D4942A68F08A404E551A4387D1D81ACFC1BD8721B228371DF7FFD9153C3E3EE705E950C2BE384CEB19E47F04C7631F67D7AFF302BD1901648855D8E585605823A95AE079C3C278DF3C5FBB5F40D35473544A37DFA2F3A1EA09908340706E655AAB5DC8C54637738A77DAF6777221463D125A2D9DDE153A0BC99A92A4FFEECCB766F012AC74909A66DD6828F23C6B3C45A2AEEE593DECA2A6FA5F9D11411D7
+20220716145403 2 6 100 7679 5 EA4C603AE36BD71059D57FCCBE1B8044C230D76993BB57E1277B27A6C4A4B08347D6279C073FCF3AAD938D631C2E6E154467895D8B122C872ED09D0C78541A55F8830207EFC2CA1556E6D9E0E78B0312C663061F6B0692FBB22CA020B4CC24E01DA76F8DC12D2BB87459FC747E3ECE875C8AD2879CD41BD91192BDEB4F30701EB53DD437163646BB8CEDCF66068617495CA9D1611A5C9E4D531A3B575745036E3A3D933984464EB3D86C30ABB3219805BA78FDA311A8F734BCCC83463CDC569AFFB0ECED647616BB7BC3C9865E79E2C4E711F2EB4A2DA078AFF66C15BEAEE0B581037715C505BFB0FE9A9FA47121981F8528DFD137FA66D33083E6F4B74BF2C4AAF0754D0E704803F0F16DF0A9FE41E0C237FFB72BCF0E458F009A77A3E096FD6BDB4799B70C9CE864A108B66D34B56DC9F390CAEBFFC15DAD572F8E57D7CAC68ECE12652303221AF1CC9AD239473CA7E14A1B7B9A6EBF827813340F6D1C97032A7A1FEF147A202A274B0C17F9DCA25214180FA619E3201C174D4B0DDA30D4A1F3EF179126EF859526C539E075EB6E91E2E30AC104FBC69D940D5A70225BBDE026CBBF357DC7543BF3F83A7525AB8F96FDEC0464CD4EB3B106984BD1C4F27BF166079C66790F1CA1AFB56A3B780F6927143E9F85687A2A99F77C46806D8E1C190147CF42E2D1D9A70F964A5CC63D813511685F6BEE77E20CD38D58334EFE7EC2F068A26426001A83758DC82E9B0300CC2FAA0999616147B6B2BF93CBE227D8586CF54FCED628C1AD540844FB6E57CC378881FC90FC3989536CA13F097EAD6F0B45356C6A9DA87873793E68AA272D5253CA239515318649B54DEB926AF82E3D9DE7DBBA0962ED73A8233577E7073A303EDFFFA7E94D596CCECA2BC8BA08A5DBE249F45232C3675FBD21A32E9B489C7804E2C406C7B4B071976E8064A91C5E53A5316CBA74A5398A625B8BAAAFA34A225E54AC174ACEEA6135EFDB59FF42774E3E30B1C8D4CDC20F8803AF0743A8CD0343C8A6065D94C0EB262BD8CB2556D1C9639E52087DDF83698A6040619246D3DAD1CCC8F5373E06FA90AFAC990E64E91EF4C0315AF1F1114B61FC7E8198BA27E7519D81842534D19E4EDF1F356D150F389F1F3D4942A68F08A404E551A4387D1D81ACFC1BD8721B228371DF7FFD9153C3E3EE705E950C2BE384CEB19E47F04C7631F67D7AFF302BD1901648855D8E585605823A95AE079C3C278DF3C5FBB5F40D35473544A37DFA2F3A1EA09908340706E655AAB5DC8C54637738A77DAF6777221463D125A2D9DDE153A0BC99A92A4FFEECCB766F012AC74909A66DD6828F23C6B3C45A2AEEE593DECA2A6FA5F9D307585F
+20220716150439 2 6 100 7679 5 EA4C603AE36BD71059D57FCCBE1B8044C230D76993BB57E1277B27A6C4A4B08347D6279C073FCF3AAD938D631C2E6E154467895D8B122C872ED09D0C78541A55F8830207EFC2CA1556E6D9E0E78B0312C663061F6B0692FBB22CA020B4CC24E01DA76F8DC12D2BB87459FC747E3ECE875C8AD2879CD41BD91192BDEB4F30701EB53DD437163646BB8CEDCF66068617495CA9D1611A5C9E4D531A3B575745036E3A3D933984464EB3D86C30ABB3219805BA78FDA311A8F734BCCC83463CDC569AFFB0ECED647616BB7BC3C9865E79E2C4E711F2EB4A2DA078AFF66C15BEAEE0B581037715C505BFB0FE9A9FA47121981F8528DFD137FA66D33083E6F4B74BF2C4AAF0754D0E704803F0F16DF0A9FE41E0C237FFB72BCF0E458F009A77A3E096FD6BDB4799B70C9CE864A108B66D34B56DC9F390CAEBFFC15DAD572F8E57D7CAC68ECE12652303221AF1CC9AD239473CA7E14A1B7B9A6EBF827813340F6D1C97032A7A1FEF147A202A274B0C17F9DCA25214180FA619E3201C174D4B0DDA30D4A1F3EF179126EF859526C539E075EB6E91E2E30AC104FBC69D940D5A70225BBDE026CBBF357DC7543BF3F83A7525AB8F96FDEC0464CD4EB3B106984BD1C4F27BF166079C66790F1CA1AFB56A3B780F6927143E9F85687A2A99F77C46806D8E1C190147CF42E2D1D9A70F964A5CC63D813511685F6BEE77E20CD38D58334EFE7EC2F068A26426001A83758DC82E9B0300CC2FAA0999616147B6B2BF93CBE227D8586CF54FCED628C1AD540844FB6E57CC378881FC90FC3989536CA13F097EAD6F0B45356C6A9DA87873793E68AA272D5253CA239515318649B54DEB926AF82E3D9DE7DBBA0962ED73A8233577E7073A303EDFFFA7E94D596CCECA2BC8BA08A5DBE249F45232C3675FBD21A32E9B489C7804E2C406C7B4B071976E8064A91C5E53A5316CBA74A5398A625B8BAAAFA34A225E54AC174ACEEA6135EFDB59FF42774E3E30B1C8D4CDC20F8803AF0743A8CD0343C8A6065D94C0EB262BD8CB2556D1C9639E52087DDF83698A6040619246D3DAD1CCC8F5373E06FA90AFAC990E64E91EF4C0315AF1F1114B61FC7E8198BA27E7519D81842534D19E4EDF1F356D150F389F1F3D4942A68F08A404E551A4387D1D81ACFC1BD8721B228371DF7FFD9153C3E3EE705E950C2BE384CEB19E47F04C7631F67D7AFF302BD1901648855D8E585605823A95AE079C3C278DF3C5FBB5F40D35473544A37DFA2F3A1EA09908340706E655AAB5DC8C54637738A77DAF6777221463D125A2D9DDE153A0BC99A92A4FFEECCB766F012AC74909A66DD6828F23C6B3C45A2AEEE593DECA2A6FA5F9D3C1E427
+20220716152458 2 6 100 7679 5 EA4C603AE36BD71059D57FCCBE1B8044C230D76993BB57E1277B27A6C4A4B08347D6279C073FCF3AAD938D631C2E6E154467895D8B122C872ED09D0C78541A55F8830207EFC2CA1556E6D9E0E78B0312C663061F6B0692FBB22CA020B4CC24E01DA76F8DC12D2BB87459FC747E3ECE875C8AD2879CD41BD91192BDEB4F30701EB53DD437163646BB8CEDCF66068617495CA9D1611A5C9E4D531A3B575745036E3A3D933984464EB3D86C30ABB3219805BA78FDA311A8F734BCCC83463CDC569AFFB0ECED647616BB7BC3C9865E79E2C4E711F2EB4A2DA078AFF66C15BEAEE0B581037715C505BFB0FE9A9FA47121981F8528DFD137FA66D33083E6F4B74BF2C4AAF0754D0E704803F0F16DF0A9FE41E0C237FFB72BCF0E458F009A77A3E096FD6BDB4799B70C9CE864A108B66D34B56DC9F390CAEBFFC15DAD572F8E57D7CAC68ECE12652303221AF1CC9AD239473CA7E14A1B7B9A6EBF827813340F6D1C97032A7A1FEF147A202A274B0C17F9DCA25214180FA619E3201C174D4B0DDA30D4A1F3EF179126EF859526C539E075EB6E91E2E30AC104FBC69D940D5A70225BBDE026CBBF357DC7543BF3F83A7525AB8F96FDEC0464CD4EB3B106984BD1C4F27BF166079C66790F1CA1AFB56A3B780F6927143E9F85687A2A99F77C46806D8E1C190147CF42E2D1D9A70F964A5CC63D813511685F6BEE77E20CD38D58334EFE7EC2F068A26426001A83758DC82E9B0300CC2FAA0999616147B6B2BF93CBE227D8586CF54FCED628C1AD540844FB6E57CC378881FC90FC3989536CA13F097EAD6F0B45356C6A9DA87873793E68AA272D5253CA239515318649B54DEB926AF82E3D9DE7DBBA0962ED73A8233577E7073A303EDFFFA7E94D596CCECA2BC8BA08A5DBE249F45232C3675FBD21A32E9B489C7804E2C406C7B4B071976E8064A91C5E53A5316CBA74A5398A625B8BAAAFA34A225E54AC174ACEEA6135EFDB59FF42774E3E30B1C8D4CDC20F8803AF0743A8CD0343C8A6065D94C0EB262BD8CB2556D1C9639E52087DDF83698A6040619246D3DAD1CCC8F5373E06FA90AFAC990E64E91EF4C0315AF1F1114B61FC7E8198BA27E7519D81842534D19E4EDF1F356D150F389F1F3D4942A68F08A404E551A4387D1D81ACFC1BD8721B228371DF7FFD9153C3E3EE705E950C2BE384CEB19E47F04C7631F67D7AFF302BD1901648855D8E585605823A95AE079C3C278DF3C5FBB5F40D35473544A37DFA2F3A1EA09908340706E655AAB5DC8C54637738A77DAF6777221463D125A2D9DDE153A0BC99A92A4FFEECCB766F012AC74909A66DD6828F23C6B3C45A2AEEE593DECA2A6FA5F9D530FD67
+20220716154334 2 6 100 7679 2 EA4C603AE36BD71059D57FCCBE1B8044C230D76993BB57E1277B27A6C4A4B08347D6279C073FCF3AAD938D631C2E6E154467895D8B122C872ED09D0C78541A55F8830207EFC2CA1556E6D9E0E78B0312C663061F6B0692FBB22CA020B4CC24E01DA76F8DC12D2BB87459FC747E3ECE875C8AD2879CD41BD91192BDEB4F30701EB53DD437163646BB8CEDCF66068617495CA9D1611A5C9E4D531A3B575745036E3A3D933984464EB3D86C30ABB3219805BA78FDA311A8F734BCCC83463CDC569AFFB0ECED647616BB7BC3C9865E79E2C4E711F2EB4A2DA078AFF66C15BEAEE0B581037715C505BFB0FE9A9FA47121981F8528DFD137FA66D33083E6F4B74BF2C4AAF0754D0E704803F0F16DF0A9FE41E0C237FFB72BCF0E458F009A77A3E096FD6BDB4799B70C9CE864A108B66D34B56DC9F390CAEBFFC15DAD572F8E57D7CAC68ECE12652303221AF1CC9AD239473CA7E14A1B7B9A6EBF827813340F6D1C97032A7A1FEF147A202A274B0C17F9DCA25214180FA619E3201C174D4B0DDA30D4A1F3EF179126EF859526C539E075EB6E91E2E30AC104FBC69D940D5A70225BBDE026CBBF357DC7543BF3F83A7525AB8F96FDEC0464CD4EB3B106984BD1C4F27BF166079C66790F1CA1AFB56A3B780F6927143E9F85687A2A99F77C46806D8E1C190147CF42E2D1D9A70F964A5CC63D813511685F6BEE77E20CD38D58334EFE7EC2F068A26426001A83758DC82E9B0300CC2FAA0999616147B6B2BF93CBE227D8586CF54FCED628C1AD540844FB6E57CC378881FC90FC3989536CA13F097EAD6F0B45356C6A9DA87873793E68AA272D5253CA239515318649B54DEB926AF82E3D9DE7DBBA0962ED73A8233577E7073A303EDFFFA7E94D596CCECA2BC8BA08A5DBE249F45232C3675FBD21A32E9B489C7804E2C406C7B4B071976E8064A91C5E53A5316CBA74A5398A625B8BAAAFA34A225E54AC174ACEEA6135EFDB59FF42774E3E30B1C8D4CDC20F8803AF0743A8CD0343C8A6065D94C0EB262BD8CB2556D1C9639E52087DDF83698A6040619246D3DAD1CCC8F5373E06FA90AFAC990E64E91EF4C0315AF1F1114B61FC7E8198BA27E7519D81842534D19E4EDF1F356D150F389F1F3D4942A68F08A404E551A4387D1D81ACFC1BD8721B228371DF7FFD9153C3E3EE705E950C2BE384CEB19E47F04C7631F67D7AFF302BD1901648855D8E585605823A95AE079C3C278DF3C5FBB5F40D35473544A37DFA2F3A1EA09908340706E655AAB5DC8C54637738A77DAF6777221463D125A2D9DDE153A0BC99A92A4FFEECCB766F012AC74909A66DD6828F23C6B3C45A2AEEE593DECA2A6FA5F9D680C84B
+20220716161140 2 6 100 7679 2 EA4C603AE36BD71059D57FCCBE1B8044C230D76993BB57E1277B27A6C4A4B08347D6279C073FCF3AAD938D631C2E6E154467895D8B122C872ED09D0C78541A55F8830207EFC2CA1556E6D9E0E78B0312C663061F6B0692FBB22CA020B4CC24E01DA76F8DC12D2BB87459FC747E3ECE875C8AD2879CD41BD91192BDEB4F30701EB53DD437163646BB8CEDCF66068617495CA9D1611A5C9E4D531A3B575745036E3A3D933984464EB3D86C30ABB3219805BA78FDA311A8F734BCCC83463CDC569AFFB0ECED647616BB7BC3C9865E79E2C4E711F2EB4A2DA078AFF66C15BEAEE0B581037715C505BFB0FE9A9FA47121981F8528DFD137FA66D33083E6F4B74BF2C4AAF0754D0E704803F0F16DF0A9FE41E0C237FFB72BCF0E458F009A77A3E096FD6BDB4799B70C9CE864A108B66D34B56DC9F390CAEBFFC15DAD572F8E57D7CAC68ECE12652303221AF1CC9AD239473CA7E14A1B7B9A6EBF827813340F6D1C97032A7A1FEF147A202A274B0C17F9DCA25214180FA619E3201C174D4B0DDA30D4A1F3EF179126EF859526C539E075EB6E91E2E30AC104FBC69D940D5A70225BBDE026CBBF357DC7543BF3F83A7525AB8F96FDEC0464CD4EB3B106984BD1C4F27BF166079C66790F1CA1AFB56A3B780F6927143E9F85687A2A99F77C46806D8E1C190147CF42E2D1D9A70F964A5CC63D813511685F6BEE77E20CD38D58334EFE7EC2F068A26426001A83758DC82E9B0300CC2FAA0999616147B6B2BF93CBE227D8586CF54FCED628C1AD540844FB6E57CC378881FC90FC3989536CA13F097EAD6F0B45356C6A9DA87873793E68AA272D5253CA239515318649B54DEB926AF82E3D9DE7DBBA0962ED73A8233577E7073A303EDFFFA7E94D596CCECA2BC8BA08A5DBE249F45232C3675FBD21A32E9B489C7804E2C406C7B4B071976E8064A91C5E53A5316CBA74A5398A625B8BAAAFA34A225E54AC174ACEEA6135EFDB59FF42774E3E30B1C8D4CDC20F8803AF0743A8CD0343C8A6065D94C0EB262BD8CB2556D1C9639E52087DDF83698A6040619246D3DAD1CCC8F5373E06FA90AFAC990E64E91EF4C0315AF1F1114B61FC7E8198BA27E7519D81842534D19E4EDF1F356D150F389F1F3D4942A68F08A404E551A4387D1D81ACFC1BD8721B228371DF7FFD9153C3E3EE705E950C2BE384CEB19E47F04C7631F67D7AFF302BD1901648855D8E585605823A95AE079C3C278DF3C5FBB5F40D35473544A37DFA2F3A1EA09908340706E655AAB5DC8C54637738A77DAF6777221463D125A2D9DDE153A0BC99A92A4FFEECCB766F012AC74909A66DD6828F23C6B3C45A2AEEE593DECA2A6FA5F9D885D85B
+20220716162236 2 6 100 7679 5 EA4C603AE36BD71059D57FCCBE1B8044C230D76993BB57E1277B27A6C4A4B08347D6279C073FCF3AAD938D631C2E6E154467895D8B122C872ED09D0C78541A55F8830207EFC2CA1556E6D9E0E78B0312C663061F6B0692FBB22CA020B4CC24E01DA76F8DC12D2BB87459FC747E3ECE875C8AD2879CD41BD91192BDEB4F30701EB53DD437163646BB8CEDCF66068617495CA9D1611A5C9E4D531A3B575745036E3A3D933984464EB3D86C30ABB3219805BA78FDA311A8F734BCCC83463CDC569AFFB0ECED647616BB7BC3C9865E79E2C4E711F2EB4A2DA078AFF66C15BEAEE0B581037715C505BFB0FE9A9FA47121981F8528DFD137FA66D33083E6F4B74BF2C4AAF0754D0E704803F0F16DF0A9FE41E0C237FFB72BCF0E458F009A77A3E096FD6BDB4799B70C9CE864A108B66D34B56DC9F390CAEBFFC15DAD572F8E57D7CAC68ECE12652303221AF1CC9AD239473CA7E14A1B7B9A6EBF827813340F6D1C97032A7A1FEF147A202A274B0C17F9DCA25214180FA619E3201C174D4B0DDA30D4A1F3EF179126EF859526C539E075EB6E91E2E30AC104FBC69D940D5A70225BBDE026CBBF357DC7543BF3F83A7525AB8F96FDEC0464CD4EB3B106984BD1C4F27BF166079C66790F1CA1AFB56A3B780F6927143E9F85687A2A99F77C46806D8E1C190147CF42E2D1D9A70F964A5CC63D813511685F6BEE77E20CD38D58334EFE7EC2F068A26426001A83758DC82E9B0300CC2FAA0999616147B6B2BF93CBE227D8586CF54FCED628C1AD540844FB6E57CC378881FC90FC3989536CA13F097EAD6F0B45356C6A9DA87873793E68AA272D5253CA239515318649B54DEB926AF82E3D9DE7DBBA0962ED73A8233577E7073A303EDFFFA7E94D596CCECA2BC8BA08A5DBE249F45232C3675FBD21A32E9B489C7804E2C406C7B4B071976E8064A91C5E53A5316CBA74A5398A625B8BAAAFA34A225E54AC174ACEEA6135EFDB59FF42774E3E30B1C8D4CDC20F8803AF0743A8CD0343C8A6065D94C0EB262BD8CB2556D1C9639E52087DDF83698A6040619246D3DAD1CCC8F5373E06FA90AFAC990E64E91EF4C0315AF1F1114B61FC7E8198BA27E7519D81842534D19E4EDF1F356D150F389F1F3D4942A68F08A404E551A4387D1D81ACFC1BD8721B228371DF7FFD9153C3E3EE705E950C2BE384CEB19E47F04C7631F67D7AFF302BD1901648855D8E585605823A95AE079C3C278DF3C5FBB5F40D35473544A37DFA2F3A1EA09908340706E655AAB5DC8C54637738A77DAF6777221463D125A2D9DDE153A0BC99A92A4FFEECCB766F012AC74909A66DD6828F23C6B3C45A2AEEE593DECA2A6FA5F9D954CF4F
+20220716171055 2 6 100 7679 5 EA4C603AE36BD71059D57FCCBE1B8044C230D76993BB57E1277B27A6C4A4B08347D6279C073FCF3AAD938D631C2E6E154467895D8B122C872ED09D0C78541A55F8830207EFC2CA1556E6D9E0E78B0312C663061F6B0692FBB22CA020B4CC24E01DA76F8DC12D2BB87459FC747E3ECE875C8AD2879CD41BD91192BDEB4F30701EB53DD437163646BB8CEDCF66068617495CA9D1611A5C9E4D531A3B575745036E3A3D933984464EB3D86C30ABB3219805BA78FDA311A8F734BCCC83463CDC569AFFB0ECED647616BB7BC3C9865E79E2C4E711F2EB4A2DA078AFF66C15BEAEE0B581037715C505BFB0FE9A9FA47121981F8528DFD137FA66D33083E6F4B74BF2C4AAF0754D0E704803F0F16DF0A9FE41E0C237FFB72BCF0E458F009A77A3E096FD6BDB4799B70C9CE864A108B66D34B56DC9F390CAEBFFC15DAD572F8E57D7CAC68ECE12652303221AF1CC9AD239473CA7E14A1B7B9A6EBF827813340F6D1C97032A7A1FEF147A202A274B0C17F9DCA25214180FA619E3201C174D4B0DDA30D4A1F3EF179126EF859526C539E075EB6E91E2E30AC104FBC69D940D5A70225BBDE026CBBF357DC7543BF3F83A7525AB8F96FDEC0464CD4EB3B106984BD1C4F27BF166079C66790F1CA1AFB56A3B780F6927143E9F85687A2A99F77C46806D8E1C190147CF42E2D1D9A70F964A5CC63D813511685F6BEE77E20CD38D58334EFE7EC2F068A26426001A83758DC82E9B0300CC2FAA0999616147B6B2BF93CBE227D8586CF54FCED628C1AD540844FB6E57CC378881FC90FC3989536CA13F097EAD6F0B45356C6A9DA87873793E68AA272D5253CA239515318649B54DEB926AF82E3D9DE7DBBA0962ED73A8233577E7073A303EDFFFA7E94D596CCECA2BC8BA08A5DBE249F45232C3675FBD21A32E9B489C7804E2C406C7B4B071976E8064A91C5E53A5316CBA74A5398A625B8BAAAFA34A225E54AC174ACEEA6135EFDB59FF42774E3E30B1C8D4CDC20F8803AF0743A8CD0343C8A6065D94C0EB262BD8CB2556D1C9639E52087DDF83698A6040619246D3DAD1CCC8F5373E06FA90AFAC990E64E91EF4C0315AF1F1114B61FC7E8198BA27E7519D81842534D19E4EDF1F356D150F389F1F3D4942A68F08A404E551A4387D1D81ACFC1BD8721B228371DF7FFD9153C3E3EE705E950C2BE384CEB19E47F04C7631F67D7AFF302BD1901648855D8E585605823A95AE079C3C278DF3C5FBB5F40D35473544A37DFA2F3A1EA09908340706E655AAB5DC8C54637738A77DAF6777221463D125A2D9DDE153A0BC99A92A4FFEECCB766F012AC74909A66DD6828F23C6B3C45A2AEEE593DECA2A6FA5F9DCC6C8EF
+20220716174339 2 6 100 7679 2 EA4C603AE36BD71059D57FCCBE1B8044C230D76993BB57E1277B27A6C4A4B08347D6279C073FCF3AAD938D631C2E6E154467895D8B122C872ED09D0C78541A55F8830207EFC2CA1556E6D9E0E78B0312C663061F6B0692FBB22CA020B4CC24E01DA76F8DC12D2BB87459FC747E3ECE875C8AD2879CD41BD91192BDEB4F30701EB53DD437163646BB8CEDCF66068617495CA9D1611A5C9E4D531A3B575745036E3A3D933984464EB3D86C30ABB3219805BA78FDA311A8F734BCCC83463CDC569AFFB0ECED647616BB7BC3C9865E79E2C4E711F2EB4A2DA078AFF66C15BEAEE0B581037715C505BFB0FE9A9FA47121981F8528DFD137FA66D33083E6F4B74BF2C4AAF0754D0E704803F0F16DF0A9FE41E0C237FFB72BCF0E458F009A77A3E096FD6BDB4799B70C9CE864A108B66D34B56DC9F390CAEBFFC15DAD572F8E57D7CAC68ECE12652303221AF1CC9AD239473CA7E14A1B7B9A6EBF827813340F6D1C97032A7A1FEF147A202A274B0C17F9DCA25214180FA619E3201C174D4B0DDA30D4A1F3EF179126EF859526C539E075EB6E91E2E30AC104FBC69D940D5A70225BBDE026CBBF357DC7543BF3F83A7525AB8F96FDEC0464CD4EB3B106984BD1C4F27BF166079C66790F1CA1AFB56A3B780F6927143E9F85687A2A99F77C46806D8E1C190147CF42E2D1D9A70F964A5CC63D813511685F6BEE77E20CD38D58334EFE7EC2F068A26426001A83758DC82E9B0300CC2FAA0999616147B6B2BF93CBE227D8586CF54FCED628C1AD540844FB6E57CC378881FC90FC3989536CA13F097EAD6F0B45356C6A9DA87873793E68AA272D5253CA239515318649B54DEB926AF82E3D9DE7DBBA0962ED73A8233577E7073A303EDFFFA7E94D596CCECA2BC8BA08A5DBE249F45232C3675FBD21A32E9B489C7804E2C406C7B4B071976E8064A91C5E53A5316CBA74A5398A625B8BAAAFA34A225E54AC174ACEEA6135EFDB59FF42774E3E30B1C8D4CDC20F8803AF0743A8CD0343C8A6065D94C0EB262BD8CB2556D1C9639E52087DDF83698A6040619246D3DAD1CCC8F5373E06FA90AFAC990E64E91EF4C0315AF1F1114B61FC7E8198BA27E7519D81842534D19E4EDF1F356D150F389F1F3D4942A68F08A404E551A4387D1D81ACFC1BD8721B228371DF7FFD9153C3E3EE705E950C2BE384CEB19E47F04C7631F67D7AFF302BD1901648855D8E585605823A95AE079C3C278DF3C5FBB5F40D35473544A37DFA2F3A1EA09908340706E655AAB5DC8C54637738A77DAF6777221463D125A2D9DDE153A0BC99A92A4FFEECCB766F012AC74909A66DD6828F23C6B3C45A2AEEE593DECA2A6FA5F9DF237BE3
+20220716174802 2 6 100 7679 2 EA4C603AE36BD71059D57FCCBE1B8044C230D76993BB57E1277B27A6C4A4B08347D6279C073FCF3AAD938D631C2E6E154467895D8B122C872ED09D0C78541A55F8830207EFC2CA1556E6D9E0E78B0312C663061F6B0692FBB22CA020B4CC24E01DA76F8DC12D2BB87459FC747E3ECE875C8AD2879CD41BD91192BDEB4F30701EB53DD437163646BB8CEDCF66068617495CA9D1611A5C9E4D531A3B575745036E3A3D933984464EB3D86C30ABB3219805BA78FDA311A8F734BCCC83463CDC569AFFB0ECED647616BB7BC3C9865E79E2C4E711F2EB4A2DA078AFF66C15BEAEE0B581037715C505BFB0FE9A9FA47121981F8528DFD137FA66D33083E6F4B74BF2C4AAF0754D0E704803F0F16DF0A9FE41E0C237FFB72BCF0E458F009A77A3E096FD6BDB4799B70C9CE864A108B66D34B56DC9F390CAEBFFC15DAD572F8E57D7CAC68ECE12652303221AF1CC9AD239473CA7E14A1B7B9A6EBF827813340F6D1C97032A7A1FEF147A202A274B0C17F9DCA25214180FA619E3201C174D4B0DDA30D4A1F3EF179126EF859526C539E075EB6E91E2E30AC104FBC69D940D5A70225BBDE026CBBF357DC7543BF3F83A7525AB8F96FDEC0464CD4EB3B106984BD1C4F27BF166079C66790F1CA1AFB56A3B780F6927143E9F85687A2A99F77C46806D8E1C190147CF42E2D1D9A70F964A5CC63D813511685F6BEE77E20CD38D58334EFE7EC2F068A26426001A83758DC82E9B0300CC2FAA0999616147B6B2BF93CBE227D8586CF54FCED628C1AD540844FB6E57CC378881FC90FC3989536CA13F097EAD6F0B45356C6A9DA87873793E68AA272D5253CA239515318649B54DEB926AF82E3D9DE7DBBA0962ED73A8233577E7073A303EDFFFA7E94D596CCECA2BC8BA08A5DBE249F45232C3675FBD21A32E9B489C7804E2C406C7B4B071976E8064A91C5E53A5316CBA74A5398A625B8BAAAFA34A225E54AC174ACEEA6135EFDB59FF42774E3E30B1C8D4CDC20F8803AF0743A8CD0343C8A6065D94C0EB262BD8CB2556D1C9639E52087DDF83698A6040619246D3DAD1CCC8F5373E06FA90AFAC990E64E91EF4C0315AF1F1114B61FC7E8198BA27E7519D81842534D19E4EDF1F356D150F389F1F3D4942A68F08A404E551A4387D1D81ACFC1BD8721B228371DF7FFD9153C3E3EE705E950C2BE384CEB19E47F04C7631F67D7AFF302BD1901648855D8E585605823A95AE079C3C278DF3C5FBB5F40D35473544A37DFA2F3A1EA09908340706E655AAB5DC8C54637738A77DAF6777221463D125A2D9DDE153A0BC99A92A4FFEECCB766F012AC74909A66DD6828F23C6B3C45A2AEEE593DECA2A6FA5F9DF73C52B
+20220716175227 2 6 100 7679 2 EA4C603AE36BD71059D57FCCBE1B8044C230D76993BB57E1277B27A6C4A4B08347D6279C073FCF3AAD938D631C2E6E154467895D8B122C872ED09D0C78541A55F8830207EFC2CA1556E6D9E0E78B0312C663061F6B0692FBB22CA020B4CC24E01DA76F8DC12D2BB87459FC747E3ECE875C8AD2879CD41BD91192BDEB4F30701EB53DD437163646BB8CEDCF66068617495CA9D1611A5C9E4D531A3B575745036E3A3D933984464EB3D86C30ABB3219805BA78FDA311A8F734BCCC83463CDC569AFFB0ECED647616BB7BC3C9865E79E2C4E711F2EB4A2DA078AFF66C15BEAEE0B581037715C505BFB0FE9A9FA47121981F8528DFD137FA66D33083E6F4B74BF2C4AAF0754D0E704803F0F16DF0A9FE41E0C237FFB72BCF0E458F009A77A3E096FD6BDB4799B70C9CE864A108B66D34B56DC9F390CAEBFFC15DAD572F8E57D7CAC68ECE12652303221AF1CC9AD239473CA7E14A1B7B9A6EBF827813340F6D1C97032A7A1FEF147A202A274B0C17F9DCA25214180FA619E3201C174D4B0DDA30D4A1F3EF179126EF859526C539E075EB6E91E2E30AC104FBC69D940D5A70225BBDE026CBBF357DC7543BF3F83A7525AB8F96FDEC0464CD4EB3B106984BD1C4F27BF166079C66790F1CA1AFB56A3B780F6927143E9F85687A2A99F77C46806D8E1C190147CF42E2D1D9A70F964A5CC63D813511685F6BEE77E20CD38D58334EFE7EC2F068A26426001A83758DC82E9B0300CC2FAA0999616147B6B2BF93CBE227D8586CF54FCED628C1AD540844FB6E57CC378881FC90FC3989536CA13F097EAD6F0B45356C6A9DA87873793E68AA272D5253CA239515318649B54DEB926AF82E3D9DE7DBBA0962ED73A8233577E7073A303EDFFFA7E94D596CCECA2BC8BA08A5DBE249F45232C3675FBD21A32E9B489C7804E2C406C7B4B071976E8064A91C5E53A5316CBA74A5398A625B8BAAAFA34A225E54AC174ACEEA6135EFDB59FF42774E3E30B1C8D4CDC20F8803AF0743A8CD0343C8A6065D94C0EB262BD8CB2556D1C9639E52087DDF83698A6040619246D3DAD1CCC8F5373E06FA90AFAC990E64E91EF4C0315AF1F1114B61FC7E8198BA27E7519D81842534D19E4EDF1F356D150F389F1F3D4942A68F08A404E551A4387D1D81ACFC1BD8721B228371DF7FFD9153C3E3EE705E950C2BE384CEB19E47F04C7631F67D7AFF302BD1901648855D8E585605823A95AE079C3C278DF3C5FBB5F40D35473544A37DFA2F3A1EA09908340706E655AAB5DC8C54637738A77DAF6777221463D125A2D9DDE153A0BC99A92A4FFEECCB766F012AC74909A66DD6828F23C6B3C45A2AEEE593DECA2A6FA5F9DFC26653
+20220716181229 2 6 100 7679 5 EA4C603AE36BD71059D57FCCBE1B8044C230D76993BB57E1277B27A6C4A4B08347D6279C073FCF3AAD938D631C2E6E154467895D8B122C872ED09D0C78541A55F8830207EFC2CA1556E6D9E0E78B0312C663061F6B0692FBB22CA020B4CC24E01DA76F8DC12D2BB87459FC747E3ECE875C8AD2879CD41BD91192BDEB4F30701EB53DD437163646BB8CEDCF66068617495CA9D1611A5C9E4D531A3B575745036E3A3D933984464EB3D86C30ABB3219805BA78FDA311A8F734BCCC83463CDC569AFFB0ECED647616BB7BC3C9865E79E2C4E711F2EB4A2DA078AFF66C15BEAEE0B581037715C505BFB0FE9A9FA47121981F8528DFD137FA66D33083E6F4B74BF2C4AAF0754D0E704803F0F16DF0A9FE41E0C237FFB72BCF0E458F009A77A3E096FD6BDB4799B70C9CE864A108B66D34B56DC9F390CAEBFFC15DAD572F8E57D7CAC68ECE12652303221AF1CC9AD239473CA7E14A1B7B9A6EBF827813340F6D1C97032A7A1FEF147A202A274B0C17F9DCA25214180FA619E3201C174D4B0DDA30D4A1F3EF179126EF859526C539E075EB6E91E2E30AC104FBC69D940D5A70225BBDE026CBBF357DC7543BF3F83A7525AB8F96FDEC0464CD4EB3B106984BD1C4F27BF166079C66790F1CA1AFB56A3B780F6927143E9F85687A2A99F77C46806D8E1C190147CF42E2D1D9A70F964A5CC63D813511685F6BEE77E20CD38D58334EFE7EC2F068A26426001A83758DC82E9B0300CC2FAA0999616147B6B2BF93CBE227D8586CF54FCED628C1AD540844FB6E57CC378881FC90FC3989536CA13F097EAD6F0B45356C6A9DA87873793E68AA272D5253CA239515318649B54DEB926AF82E3D9DE7DBBA0962ED73A8233577E7073A303EDFFFA7E94D596CCECA2BC8BA08A5DBE249F45232C3675FBD21A32E9B489C7804E2C406C7B4B071976E8064A91C5E53A5316CBA74A5398A625B8BAAAFA34A225E54AC174ACEEA6135EFDB59FF42774E3E30B1C8D4CDC20F8803AF0743A8CD0343C8A6065D94C0EB262BD8CB2556D1C9639E52087DDF83698A6040619246D3DAD1CCC8F5373E06FA90AFAC990E64E91EF4C0315AF1F1114B61FC7E8198BA27E7519D81842534D19E4EDF1F356D150F389F1F3D4942A68F08A404E551A4387D1D81ACFC1BD8721B228371DF7FFD9153C3E3EE705E950C2BE384CEB19E47F04C7631F67D7AFF302BD1901648855D8E585605823A95AE079C3C278DF3C5FBB5F40D35473544A37DFA2F3A1EA09908340706E655AAB5DC8C54637738A77DAF6777221463D125A2D9DDE153A0BC99A92A4FFEECCB766F012AC74909A66DD6828F23C6B3C45A2AEEE593DECA2A6FA5F9E131151F
+20220716182155 2 6 100 7679 2 EA4C603AE36BD71059D57FCCBE1B8044C230D76993BB57E1277B27A6C4A4B08347D6279C073FCF3AAD938D631C2E6E154467895D8B122C872ED09D0C78541A55F8830207EFC2CA1556E6D9E0E78B0312C663061F6B0692FBB22CA020B4CC24E01DA76F8DC12D2BB87459FC747E3ECE875C8AD2879CD41BD91192BDEB4F30701EB53DD437163646BB8CEDCF66068617495CA9D1611A5C9E4D531A3B575745036E3A3D933984464EB3D86C30ABB3219805BA78FDA311A8F734BCCC83463CDC569AFFB0ECED647616BB7BC3C9865E79E2C4E711F2EB4A2DA078AFF66C15BEAEE0B581037715C505BFB0FE9A9FA47121981F8528DFD137FA66D33083E6F4B74BF2C4AAF0754D0E704803F0F16DF0A9FE41E0C237FFB72BCF0E458F009A77A3E096FD6BDB4799B70C9CE864A108B66D34B56DC9F390CAEBFFC15DAD572F8E57D7CAC68ECE12652303221AF1CC9AD239473CA7E14A1B7B9A6EBF827813340F6D1C97032A7A1FEF147A202A274B0C17F9DCA25214180FA619E3201C174D4B0DDA30D4A1F3EF179126EF859526C539E075EB6E91E2E30AC104FBC69D940D5A70225BBDE026CBBF357DC7543BF3F83A7525AB8F96FDEC0464CD4EB3B106984BD1C4F27BF166079C66790F1CA1AFB56A3B780F6927143E9F85687A2A99F77C46806D8E1C190147CF42E2D1D9A70F964A5CC63D813511685F6BEE77E20CD38D58334EFE7EC2F068A26426001A83758DC82E9B0300CC2FAA0999616147B6B2BF93CBE227D8586CF54FCED628C1AD540844FB6E57CC378881FC90FC3989536CA13F097EAD6F0B45356C6A9DA87873793E68AA272D5253CA239515318649B54DEB926AF82E3D9DE7DBBA0962ED73A8233577E7073A303EDFFFA7E94D596CCECA2BC8BA08A5DBE249F45232C3675FBD21A32E9B489C7804E2C406C7B4B071976E8064A91C5E53A5316CBA74A5398A625B8BAAAFA34A225E54AC174ACEEA6135EFDB59FF42774E3E30B1C8D4CDC20F8803AF0743A8CD0343C8A6065D94C0EB262BD8CB2556D1C9639E52087DDF83698A6040619246D3DAD1CCC8F5373E06FA90AFAC990E64E91EF4C0315AF1F1114B61FC7E8198BA27E7519D81842534D19E4EDF1F356D150F389F1F3D4942A68F08A404E551A4387D1D81ACFC1BD8721B228371DF7FFD9153C3E3EE705E950C2BE384CEB19E47F04C7631F67D7AFF302BD1901648855D8E585605823A95AE079C3C278DF3C5FBB5F40D35473544A37DFA2F3A1EA09908340706E655AAB5DC8C54637738A77DAF6777221463D125A2D9DDE153A0BC99A92A4FFEECCB766F012AC74909A66DD6828F23C6B3C45A2AEEE593DECA2A6FA5F9E1D9F2CB
+20220716194638 2 6 100 7679 5 EA4C603AE36BD71059D57FCCBE1B8044C230D76993BB57E1277B27A6C4A4B08347D6279C073FCF3AAD938D631C2E6E154467895D8B122C872ED09D0C78541A55F8830207EFC2CA1556E6D9E0E78B0312C663061F6B0692FBB22CA020B4CC24E01DA76F8DC12D2BB87459FC747E3ECE875C8AD2879CD41BD91192BDEB4F30701EB53DD437163646BB8CEDCF66068617495CA9D1611A5C9E4D531A3B575745036E3A3D933984464EB3D86C30ABB3219805BA78FDA311A8F734BCCC83463CDC569AFFB0ECED647616BB7BC3C9865E79E2C4E711F2EB4A2DA078AFF66C15BEAEE0B581037715C505BFB0FE9A9FA47121981F8528DFD137FA66D33083E6F4B74BF2C4AAF0754D0E704803F0F16DF0A9FE41E0C237FFB72BCF0E458F009A77A3E096FD6BDB4799B70C9CE864A108B66D34B56DC9F390CAEBFFC15DAD572F8E57D7CAC68ECE12652303221AF1CC9AD239473CA7E14A1B7B9A6EBF827813340F6D1C97032A7A1FEF147A202A274B0C17F9DCA25214180FA619E3201C174D4B0DDA30D4A1F3EF179126EF859526C539E075EB6E91E2E30AC104FBC69D940D5A70225BBDE026CBBF357DC7543BF3F83A7525AB8F96FDEC0464CD4EB3B106984BD1C4F27BF166079C66790F1CA1AFB56A3B780F6927143E9F85687A2A99F77C46806D8E1C190147CF42E2D1D9A70F964A5CC63D813511685F6BEE77E20CD38D58334EFE7EC2F068A26426001A83758DC82E9B0300CC2FAA0999616147B6B2BF93CBE227D8586CF54FCED628C1AD540844FB6E57CC378881FC90FC3989536CA13F097EAD6F0B45356C6A9DA87873793E68AA272D5253CA239515318649B54DEB926AF82E3D9DE7DBBA0962ED73A8233577E7073A303EDFFFA7E94D596CCECA2BC8BA08A5DBE249F45232C3675FBD21A32E9B489C7804E2C406C7B4B071976E8064A91C5E53A5316CBA74A5398A625B8BAAAFA34A225E54AC174ACEEA6135EFDB59FF42774E3E30B1C8D4CDC20F8803AF0743A8CD0343C8A6065D94C0EB262BD8CB2556D1C9639E52087DDF83698A6040619246D3DAD1CCC8F5373E06FA90AFAC990E64E91EF4C0315AF1F1114B61FC7E8198BA27E7519D81842534D19E4EDF1F356D150F389F1F3D4942A68F08A404E551A4387D1D81ACFC1BD8721B228371DF7FFD9153C3E3EE705E950C2BE384CEB19E47F04C7631F67D7AFF302BD1901648855D8E585605823A95AE079C3C278DF3C5FBB5F40D35473544A37DFA2F3A1EA09908340706E655AAB5DC8C54637738A77DAF6777221463D125A2D9DDE153A0BC99A92A4FFEECCB766F012AC74909A66DD6828F23C6B3C45A2AEEE593DECA2A6FA5F9E7EE6D9F
+20220716195641 2 6 100 7679 5 EA4C603AE36BD71059D57FCCBE1B8044C230D76993BB57E1277B27A6C4A4B08347D6279C073FCF3AAD938D631C2E6E154467895D8B122C872ED09D0C78541A55F8830207EFC2CA1556E6D9E0E78B0312C663061F6B0692FBB22CA020B4CC24E01DA76F8DC12D2BB87459FC747E3ECE875C8AD2879CD41BD91192BDEB4F30701EB53DD437163646BB8CEDCF66068617495CA9D1611A5C9E4D531A3B575745036E3A3D933984464EB3D86C30ABB3219805BA78FDA311A8F734BCCC83463CDC569AFFB0ECED647616BB7BC3C9865E79E2C4E711F2EB4A2DA078AFF66C15BEAEE0B581037715C505BFB0FE9A9FA47121981F8528DFD137FA66D33083E6F4B74BF2C4AAF0754D0E704803F0F16DF0A9FE41E0C237FFB72BCF0E458F009A77A3E096FD6BDB4799B70C9CE864A108B66D34B56DC9F390CAEBFFC15DAD572F8E57D7CAC68ECE12652303221AF1CC9AD239473CA7E14A1B7B9A6EBF827813340F6D1C97032A7A1FEF147A202A274B0C17F9DCA25214180FA619E3201C174D4B0DDA30D4A1F3EF179126EF859526C539E075EB6E91E2E30AC104FBC69D940D5A70225BBDE026CBBF357DC7543BF3F83A7525AB8F96FDEC0464CD4EB3B106984BD1C4F27BF166079C66790F1CA1AFB56A3B780F6927143E9F85687A2A99F77C46806D8E1C190147CF42E2D1D9A70F964A5CC63D813511685F6BEE77E20CD38D58334EFE7EC2F068A26426001A83758DC82E9B0300CC2FAA0999616147B6B2BF93CBE227D8586CF54FCED628C1AD540844FB6E57CC378881FC90FC3989536CA13F097EAD6F0B45356C6A9DA87873793E68AA272D5253CA239515318649B54DEB926AF82E3D9DE7DBBA0962ED73A8233577E7073A303EDFFFA7E94D596CCECA2BC8BA08A5DBE249F45232C3675FBD21A32E9B489C7804E2C406C7B4B071976E8064A91C5E53A5316CBA74A5398A625B8BAAAFA34A225E54AC174ACEEA6135EFDB59FF42774E3E30B1C8D4CDC20F8803AF0743A8CD0343C8A6065D94C0EB262BD8CB2556D1C9639E52087DDF83698A6040619246D3DAD1CCC8F5373E06FA90AFAC990E64E91EF4C0315AF1F1114B61FC7E8198BA27E7519D81842534D19E4EDF1F356D150F389F1F3D4942A68F08A404E551A4387D1D81ACFC1BD8721B228371DF7FFD9153C3E3EE705E950C2BE384CEB19E47F04C7631F67D7AFF302BD1901648855D8E585605823A95AE079C3C278DF3C5FBB5F40D35473544A37DFA2F3A1EA09908340706E655AAB5DC8C54637738A77DAF6777221463D125A2D9DDE153A0BC99A92A4FFEECCB766F012AC74909A66DD6828F23C6B3C45A2AEEE593DECA2A6FA5F9E8A6F4EF
+20220716204017 2 6 100 7679 5 EA4C603AE36BD71059D57FCCBE1B8044C230D76993BB57E1277B27A6C4A4B08347D6279C073FCF3AAD938D631C2E6E154467895D8B122C872ED09D0C78541A55F8830207EFC2CA1556E6D9E0E78B0312C663061F6B0692FBB22CA020B4CC24E01DA76F8DC12D2BB87459FC747E3ECE875C8AD2879CD41BD91192BDEB4F30701EB53DD437163646BB8CEDCF66068617495CA9D1611A5C9E4D531A3B575745036E3A3D933984464EB3D86C30ABB3219805BA78FDA311A8F734BCCC83463CDC569AFFB0ECED647616BB7BC3C9865E79E2C4E711F2EB4A2DA078AFF66C15BEAEE0B581037715C505BFB0FE9A9FA47121981F8528DFD137FA66D33083E6F4B74BF2C4AAF0754D0E704803F0F16DF0A9FE41E0C237FFB72BCF0E458F009A77A3E096FD6BDB4799B70C9CE864A108B66D34B56DC9F390CAEBFFC15DAD572F8E57D7CAC68ECE12652303221AF1CC9AD239473CA7E14A1B7B9A6EBF827813340F6D1C97032A7A1FEF147A202A274B0C17F9DCA25214180FA619E3201C174D4B0DDA30D4A1F3EF179126EF859526C539E075EB6E91E2E30AC104FBC69D940D5A70225BBDE026CBBF357DC7543BF3F83A7525AB8F96FDEC0464CD4EB3B106984BD1C4F27BF166079C66790F1CA1AFB56A3B780F6927143E9F85687A2A99F77C46806D8E1C190147CF42E2D1D9A70F964A5CC63D813511685F6BEE77E20CD38D58334EFE7EC2F068A26426001A83758DC82E9B0300CC2FAA0999616147B6B2BF93CBE227D8586CF54FCED628C1AD540844FB6E57CC378881FC90FC3989536CA13F097EAD6F0B45356C6A9DA87873793E68AA272D5253CA239515318649B54DEB926AF82E3D9DE7DBBA0962ED73A8233577E7073A303EDFFFA7E94D596CCECA2BC8BA08A5DBE249F45232C3675FBD21A32E9B489C7804E2C406C7B4B071976E8064A91C5E53A5316CBA74A5398A625B8BAAAFA34A225E54AC174ACEEA6135EFDB59FF42774E3E30B1C8D4CDC20F8803AF0743A8CD0343C8A6065D94C0EB262BD8CB2556D1C9639E52087DDF83698A6040619246D3DAD1CCC8F5373E06FA90AFAC990E64E91EF4C0315AF1F1114B61FC7E8198BA27E7519D81842534D19E4EDF1F356D150F389F1F3D4942A68F08A404E551A4387D1D81ACFC1BD8721B228371DF7FFD9153C3E3EE705E950C2BE384CEB19E47F04C7631F67D7AFF302BD1901648855D8E585605823A95AE079C3C278DF3C5FBB5F40D35473544A37DFA2F3A1EA09908340706E655AAB5DC8C54637738A77DAF6777221463D125A2D9DDE153A0BC99A92A4FFEECCB766F012AC74909A66DD6828F23C6B3C45A2AEEE593DECA2A6FA5F9EBD085BF
+20220716212803 2 6 100 7679 2 EA4C603AE36BD71059D57FCCBE1B8044C230D76993BB57E1277B27A6C4A4B08347D6279C073FCF3AAD938D631C2E6E154467895D8B122C872ED09D0C78541A55F8830207EFC2CA1556E6D9E0E78B0312C663061F6B0692FBB22CA020B4CC24E01DA76F8DC12D2BB87459FC747E3ECE875C8AD2879CD41BD91192BDEB4F30701EB53DD437163646BB8CEDCF66068617495CA9D1611A5C9E4D531A3B575745036E3A3D933984464EB3D86C30ABB3219805BA78FDA311A8F734BCCC83463CDC569AFFB0ECED647616BB7BC3C9865E79E2C4E711F2EB4A2DA078AFF66C15BEAEE0B581037715C505BFB0FE9A9FA47121981F8528DFD137FA66D33083E6F4B74BF2C4AAF0754D0E704803F0F16DF0A9FE41E0C237FFB72BCF0E458F009A77A3E096FD6BDB4799B70C9CE864A108B66D34B56DC9F390CAEBFFC15DAD572F8E57D7CAC68ECE12652303221AF1CC9AD239473CA7E14A1B7B9A6EBF827813340F6D1C97032A7A1FEF147A202A274B0C17F9DCA25214180FA619E3201C174D4B0DDA30D4A1F3EF179126EF859526C539E075EB6E91E2E30AC104FBC69D940D5A70225BBDE026CBBF357DC7543BF3F83A7525AB8F96FDEC0464CD4EB3B106984BD1C4F27BF166079C66790F1CA1AFB56A3B780F6927143E9F85687A2A99F77C46806D8E1C190147CF42E2D1D9A70F964A5CC63D813511685F6BEE77E20CD38D58334EFE7EC2F068A26426001A83758DC82E9B0300CC2FAA0999616147B6B2BF93CBE227D8586CF54FCED628C1AD540844FB6E57CC378881FC90FC3989536CA13F097EAD6F0B45356C6A9DA87873793E68AA272D5253CA239515318649B54DEB926AF82E3D9DE7DBBA0962ED73A8233577E7073A303EDFFFA7E94D596CCECA2BC8BA08A5DBE249F45232C3675FBD21A32E9B489C7804E2C406C7B4B071976E8064A91C5E53A5316CBA74A5398A625B8BAAAFA34A225E54AC174ACEEA6135EFDB59FF42774E3E30B1C8D4CDC20F8803AF0743A8CD0343C8A6065D94C0EB262BD8CB2556D1C9639E52087DDF83698A6040619246D3DAD1CCC8F5373E06FA90AFAC990E64E91EF4C0315AF1F1114B61FC7E8198BA27E7519D81842534D19E4EDF1F356D150F389F1F3D4942A68F08A404E551A4387D1D81ACFC1BD8721B228371DF7FFD9153C3E3EE705E950C2BE384CEB19E47F04C7631F67D7AFF302BD1901648855D8E585605823A95AE079C3C278DF3C5FBB5F40D35473544A37DFA2F3A1EA09908340706E655AAB5DC8C54637738A77DAF6777221463D125A2D9DDE153A0BC99A92A4FFEECCB766F012AC74909A66DD6828F23C6B3C45A2AEEE593DECA2A6FA5F9EF3B06BB
+20220716213736 2 6 100 7679 2 EA4C603AE36BD71059D57FCCBE1B8044C230D76993BB57E1277B27A6C4A4B08347D6279C073FCF3AAD938D631C2E6E154467895D8B122C872ED09D0C78541A55F8830207EFC2CA1556E6D9E0E78B0312C663061F6B0692FBB22CA020B4CC24E01DA76F8DC12D2BB87459FC747E3ECE875C8AD2879CD41BD91192BDEB4F30701EB53DD437163646BB8CEDCF66068617495CA9D1611A5C9E4D531A3B575745036E3A3D933984464EB3D86C30ABB3219805BA78FDA311A8F734BCCC83463CDC569AFFB0ECED647616BB7BC3C9865E79E2C4E711F2EB4A2DA078AFF66C15BEAEE0B581037715C505BFB0FE9A9FA47121981F8528DFD137FA66D33083E6F4B74BF2C4AAF0754D0E704803F0F16DF0A9FE41E0C237FFB72BCF0E458F009A77A3E096FD6BDB4799B70C9CE864A108B66D34B56DC9F390CAEBFFC15DAD572F8E57D7CAC68ECE12652303221AF1CC9AD239473CA7E14A1B7B9A6EBF827813340F6D1C97032A7A1FEF147A202A274B0C17F9DCA25214180FA619E3201C174D4B0DDA30D4A1F3EF179126EF859526C539E075EB6E91E2E30AC104FBC69D940D5A70225BBDE026CBBF357DC7543BF3F83A7525AB8F96FDEC0464CD4EB3B106984BD1C4F27BF166079C66790F1CA1AFB56A3B780F6927143E9F85687A2A99F77C46806D8E1C190147CF42E2D1D9A70F964A5CC63D813511685F6BEE77E20CD38D58334EFE7EC2F068A26426001A83758DC82E9B0300CC2FAA0999616147B6B2BF93CBE227D8586CF54FCED628C1AD540844FB6E57CC378881FC90FC3989536CA13F097EAD6F0B45356C6A9DA87873793E68AA272D5253CA239515318649B54DEB926AF82E3D9DE7DBBA0962ED73A8233577E7073A303EDFFFA7E94D596CCECA2BC8BA08A5DBE249F45232C3675FBD21A32E9B489C7804E2C406C7B4B071976E8064A91C5E53A5316CBA74A5398A625B8BAAAFA34A225E54AC174ACEEA6135EFDB59FF42774E3E30B1C8D4CDC20F8803AF0743A8CD0343C8A6065D94C0EB262BD8CB2556D1C9639E52087DDF83698A6040619246D3DAD1CCC8F5373E06FA90AFAC990E64E91EF4C0315AF1F1114B61FC7E8198BA27E7519D81842534D19E4EDF1F356D150F389F1F3D4942A68F08A404E551A4387D1D81ACFC1BD8721B228371DF7FFD9153C3E3EE705E950C2BE384CEB19E47F04C7631F67D7AFF302BD1901648855D8E585605823A95AE079C3C278DF3C5FBB5F40D35473544A37DFA2F3A1EA09908340706E655AAB5DC8C54637738A77DAF6777221463D125A2D9DDE153A0BC99A92A4FFEECCB766F012AC74909A66DD6828F23C6B3C45A2AEEE593DECA2A6FA5F9EFE990EB
+20220716213807 2 6 100 7679 2 EA4C603AE36BD71059D57FCCBE1B8044C230D76993BB57E1277B27A6C4A4B08347D6279C073FCF3AAD938D631C2E6E154467895D8B122C872ED09D0C78541A55F8830207EFC2CA1556E6D9E0E78B0312C663061F6B0692FBB22CA020B4CC24E01DA76F8DC12D2BB87459FC747E3ECE875C8AD2879CD41BD91192BDEB4F30701EB53DD437163646BB8CEDCF66068617495CA9D1611A5C9E4D531A3B575745036E3A3D933984464EB3D86C30ABB3219805BA78FDA311A8F734BCCC83463CDC569AFFB0ECED647616BB7BC3C9865E79E2C4E711F2EB4A2DA078AFF66C15BEAEE0B581037715C505BFB0FE9A9FA47121981F8528DFD137FA66D33083E6F4B74BF2C4AAF0754D0E704803F0F16DF0A9FE41E0C237FFB72BCF0E458F009A77A3E096FD6BDB4799B70C9CE864A108B66D34B56DC9F390CAEBFFC15DAD572F8E57D7CAC68ECE12652303221AF1CC9AD239473CA7E14A1B7B9A6EBF827813340F6D1C97032A7A1FEF147A202A274B0C17F9DCA25214180FA619E3201C174D4B0DDA30D4A1F3EF179126EF859526C539E075EB6E91E2E30AC104FBC69D940D5A70225BBDE026CBBF357DC7543BF3F83A7525AB8F96FDEC0464CD4EB3B106984BD1C4F27BF166079C66790F1CA1AFB56A3B780F6927143E9F85687A2A99F77C46806D8E1C190147CF42E2D1D9A70F964A5CC63D813511685F6BEE77E20CD38D58334EFE7EC2F068A26426001A83758DC82E9B0300CC2FAA0999616147B6B2BF93CBE227D8586CF54FCED628C1AD540844FB6E57CC378881FC90FC3989536CA13F097EAD6F0B45356C6A9DA87873793E68AA272D5253CA239515318649B54DEB926AF82E3D9DE7DBBA0962ED73A8233577E7073A303EDFFFA7E94D596CCECA2BC8BA08A5DBE249F45232C3675FBD21A32E9B489C7804E2C406C7B4B071976E8064A91C5E53A5316CBA74A5398A625B8BAAAFA34A225E54AC174ACEEA6135EFDB59FF42774E3E30B1C8D4CDC20F8803AF0743A8CD0343C8A6065D94C0EB262BD8CB2556D1C9639E52087DDF83698A6040619246D3DAD1CCC8F5373E06FA90AFAC990E64E91EF4C0315AF1F1114B61FC7E8198BA27E7519D81842534D19E4EDF1F356D150F389F1F3D4942A68F08A404E551A4387D1D81ACFC1BD8721B228371DF7FFD9153C3E3EE705E950C2BE384CEB19E47F04C7631F67D7AFF302BD1901648855D8E585605823A95AE079C3C278DF3C5FBB5F40D35473544A37DFA2F3A1EA09908340706E655AAB5DC8C54637738A77DAF6777221463D125A2D9DDE153A0BC99A92A4FFEECCB766F012AC74909A66DD6828F23C6B3C45A2AEEE593DECA2A6FA5F9EFF487B3
+20220716213938 2 6 100 7679 2 EA4C603AE36BD71059D57FCCBE1B8044C230D76993BB57E1277B27A6C4A4B08347D6279C073FCF3AAD938D631C2E6E154467895D8B122C872ED09D0C78541A55F8830207EFC2CA1556E6D9E0E78B0312C663061F6B0692FBB22CA020B4CC24E01DA76F8DC12D2BB87459FC747E3ECE875C8AD2879CD41BD91192BDEB4F30701EB53DD437163646BB8CEDCF66068617495CA9D1611A5C9E4D531A3B575745036E3A3D933984464EB3D86C30ABB3219805BA78FDA311A8F734BCCC83463CDC569AFFB0ECED647616BB7BC3C9865E79E2C4E711F2EB4A2DA078AFF66C15BEAEE0B581037715C505BFB0FE9A9FA47121981F8528DFD137FA66D33083E6F4B74BF2C4AAF0754D0E704803F0F16DF0A9FE41E0C237FFB72BCF0E458F009A77A3E096FD6BDB4799B70C9CE864A108B66D34B56DC9F390CAEBFFC15DAD572F8E57D7CAC68ECE12652303221AF1CC9AD239473CA7E14A1B7B9A6EBF827813340F6D1C97032A7A1FEF147A202A274B0C17F9DCA25214180FA619E3201C174D4B0DDA30D4A1F3EF179126EF859526C539E075EB6E91E2E30AC104FBC69D940D5A70225BBDE026CBBF357DC7543BF3F83A7525AB8F96FDEC0464CD4EB3B106984BD1C4F27BF166079C66790F1CA1AFB56A3B780F6927143E9F85687A2A99F77C46806D8E1C190147CF42E2D1D9A70F964A5CC63D813511685F6BEE77E20CD38D58334EFE7EC2F068A26426001A83758DC82E9B0300CC2FAA0999616147B6B2BF93CBE227D8586CF54FCED628C1AD540844FB6E57CC378881FC90FC3989536CA13F097EAD6F0B45356C6A9DA87873793E68AA272D5253CA239515318649B54DEB926AF82E3D9DE7DBBA0962ED73A8233577E7073A303EDFFFA7E94D596CCECA2BC8BA08A5DBE249F45232C3675FBD21A32E9B489C7804E2C406C7B4B071976E8064A91C5E53A5316CBA74A5398A625B8BAAAFA34A225E54AC174ACEEA6135EFDB59FF42774E3E30B1C8D4CDC20F8803AF0743A8CD0343C8A6065D94C0EB262BD8CB2556D1C9639E52087DDF83698A6040619246D3DAD1CCC8F5373E06FA90AFAC990E64E91EF4C0315AF1F1114B61FC7E8198BA27E7519D81842534D19E4EDF1F356D150F389F1F3D4942A68F08A404E551A4387D1D81ACFC1BD8721B228371DF7FFD9153C3E3EE705E950C2BE384CEB19E47F04C7631F67D7AFF302BD1901648855D8E585605823A95AE079C3C278DF3C5FBB5F40D35473544A37DFA2F3A1EA09908340706E655AAB5DC8C54637738A77DAF6777221463D125A2D9DDE153A0BC99A92A4FFEECCB766F012AC74909A66DD6828F23C6B3C45A2AEEE593DECA2A6FA5F9F0105893
+20220716221754 2 6 100 7679 2 EA4C603AE36BD71059D57FCCBE1B8044C230D76993BB57E1277B27A6C4A4B08347D6279C073FCF3AAD938D631C2E6E154467895D8B122C872ED09D0C78541A55F8830207EFC2CA1556E6D9E0E78B0312C663061F6B0692FBB22CA020B4CC24E01DA76F8DC12D2BB87459FC747E3ECE875C8AD2879CD41BD91192BDEB4F30701EB53DD437163646BB8CEDCF66068617495CA9D1611A5C9E4D531A3B575745036E3A3D933984464EB3D86C30ABB3219805BA78FDA311A8F734BCCC83463CDC569AFFB0ECED647616BB7BC3C9865E79E2C4E711F2EB4A2DA078AFF66C15BEAEE0B581037715C505BFB0FE9A9FA47121981F8528DFD137FA66D33083E6F4B74BF2C4AAF0754D0E704803F0F16DF0A9FE41E0C237FFB72BCF0E458F009A77A3E096FD6BDB4799B70C9CE864A108B66D34B56DC9F390CAEBFFC15DAD572F8E57D7CAC68ECE12652303221AF1CC9AD239473CA7E14A1B7B9A6EBF827813340F6D1C97032A7A1FEF147A202A274B0C17F9DCA25214180FA619E3201C174D4B0DDA30D4A1F3EF179126EF859526C539E075EB6E91E2E30AC104FBC69D940D5A70225BBDE026CBBF357DC7543BF3F83A7525AB8F96FDEC0464CD4EB3B106984BD1C4F27BF166079C66790F1CA1AFB56A3B780F6927143E9F85687A2A99F77C46806D8E1C190147CF42E2D1D9A70F964A5CC63D813511685F6BEE77E20CD38D58334EFE7EC2F068A26426001A83758DC82E9B0300CC2FAA0999616147B6B2BF93CBE227D8586CF54FCED628C1AD540844FB6E57CC378881FC90FC3989536CA13F097EAD6F0B45356C6A9DA87873793E68AA272D5253CA239515318649B54DEB926AF82E3D9DE7DBBA0962ED73A8233577E7073A303EDFFFA7E94D596CCECA2BC8BA08A5DBE249F45232C3675FBD21A32E9B489C7804E2C406C7B4B071976E8064A91C5E53A5316CBA74A5398A625B8BAAAFA34A225E54AC174ACEEA6135EFDB59FF42774E3E30B1C8D4CDC20F8803AF0743A8CD0343C8A6065D94C0EB262BD8CB2556D1C9639E52087DDF83698A6040619246D3DAD1CCC8F5373E06FA90AFAC990E64E91EF4C0315AF1F1114B61FC7E8198BA27E7519D81842534D19E4EDF1F356D150F389F1F3D4942A68F08A404E551A4387D1D81ACFC1BD8721B228371DF7FFD9153C3E3EE705E950C2BE384CEB19E47F04C7631F67D7AFF302BD1901648855D8E585605823A95AE079C3C278DF3C5FBB5F40D35473544A37DFA2F3A1EA09908340706E655AAB5DC8C54637738A77DAF6777221463D125A2D9DDE153A0BC99A92A4FFEECCB766F012AC74909A66DD6828F23C6B3C45A2AEEE593DECA2A6FA5F9F2D67283
+20220716223623 2 6 100 7679 5 EA4C603AE36BD71059D57FCCBE1B8044C230D76993BB57E1277B27A6C4A4B08347D6279C073FCF3AAD938D631C2E6E154467895D8B122C872ED09D0C78541A55F8830207EFC2CA1556E6D9E0E78B0312C663061F6B0692FBB22CA020B4CC24E01DA76F8DC12D2BB87459FC747E3ECE875C8AD2879CD41BD91192BDEB4F30701EB53DD437163646BB8CEDCF66068617495CA9D1611A5C9E4D531A3B575745036E3A3D933984464EB3D86C30ABB3219805BA78FDA311A8F734BCCC83463CDC569AFFB0ECED647616BB7BC3C9865E79E2C4E711F2EB4A2DA078AFF66C15BEAEE0B581037715C505BFB0FE9A9FA47121981F8528DFD137FA66D33083E6F4B74BF2C4AAF0754D0E704803F0F16DF0A9FE41E0C237FFB72BCF0E458F009A77A3E096FD6BDB4799B70C9CE864A108B66D34B56DC9F390CAEBFFC15DAD572F8E57D7CAC68ECE12652303221AF1CC9AD239473CA7E14A1B7B9A6EBF827813340F6D1C97032A7A1FEF147A202A274B0C17F9DCA25214180FA619E3201C174D4B0DDA30D4A1F3EF179126EF859526C539E075EB6E91E2E30AC104FBC69D940D5A70225BBDE026CBBF357DC7543BF3F83A7525AB8F96FDEC0464CD4EB3B106984BD1C4F27BF166079C66790F1CA1AFB56A3B780F6927143E9F85687A2A99F77C46806D8E1C190147CF42E2D1D9A70F964A5CC63D813511685F6BEE77E20CD38D58334EFE7EC2F068A26426001A83758DC82E9B0300CC2FAA0999616147B6B2BF93CBE227D8586CF54FCED628C1AD540844FB6E57CC378881FC90FC3989536CA13F097EAD6F0B45356C6A9DA87873793E68AA272D5253CA239515318649B54DEB926AF82E3D9DE7DBBA0962ED73A8233577E7073A303EDFFFA7E94D596CCECA2BC8BA08A5DBE249F45232C3675FBD21A32E9B489C7804E2C406C7B4B071976E8064A91C5E53A5316CBA74A5398A625B8BAAAFA34A225E54AC174ACEEA6135EFDB59FF42774E3E30B1C8D4CDC20F8803AF0743A8CD0343C8A6065D94C0EB262BD8CB2556D1C9639E52087DDF83698A6040619246D3DAD1CCC8F5373E06FA90AFAC990E64E91EF4C0315AF1F1114B61FC7E8198BA27E7519D81842534D19E4EDF1F356D150F389F1F3D4942A68F08A404E551A4387D1D81ACFC1BD8721B228371DF7FFD9153C3E3EE705E950C2BE384CEB19E47F04C7631F67D7AFF302BD1901648855D8E585605823A95AE079C3C278DF3C5FBB5F40D35473544A37DFA2F3A1EA09908340706E655AAB5DC8C54637738A77DAF6777221463D125A2D9DDE153A0BC99A92A4FFEECCB766F012AC74909A66DD6828F23C6B3C45A2AEEE593DECA2A6FA5F9F4287F5F
+20220716225952 2 6 100 7679 2 EA4C603AE36BD71059D57FCCBE1B8044C230D76993BB57E1277B27A6C4A4B08347D6279C073FCF3AAD938D631C2E6E154467895D8B122C872ED09D0C78541A55F8830207EFC2CA1556E6D9E0E78B0312C663061F6B0692FBB22CA020B4CC24E01DA76F8DC12D2BB87459FC747E3ECE875C8AD2879CD41BD91192BDEB4F30701EB53DD437163646BB8CEDCF66068617495CA9D1611A5C9E4D531A3B575745036E3A3D933984464EB3D86C30ABB3219805BA78FDA311A8F734BCCC83463CDC569AFFB0ECED647616BB7BC3C9865E79E2C4E711F2EB4A2DA078AFF66C15BEAEE0B581037715C505BFB0FE9A9FA47121981F8528DFD137FA66D33083E6F4B74BF2C4AAF0754D0E704803F0F16DF0A9FE41E0C237FFB72BCF0E458F009A77A3E096FD6BDB4799B70C9CE864A108B66D34B56DC9F390CAEBFFC15DAD572F8E57D7CAC68ECE12652303221AF1CC9AD239473CA7E14A1B7B9A6EBF827813340F6D1C97032A7A1FEF147A202A274B0C17F9DCA25214180FA619E3201C174D4B0DDA30D4A1F3EF179126EF859526C539E075EB6E91E2E30AC104FBC69D940D5A70225BBDE026CBBF357DC7543BF3F83A7525AB8F96FDEC0464CD4EB3B106984BD1C4F27BF166079C66790F1CA1AFB56A3B780F6927143E9F85687A2A99F77C46806D8E1C190147CF42E2D1D9A70F964A5CC63D813511685F6BEE77E20CD38D58334EFE7EC2F068A26426001A83758DC82E9B0300CC2FAA0999616147B6B2BF93CBE227D8586CF54FCED628C1AD540844FB6E57CC378881FC90FC3989536CA13F097EAD6F0B45356C6A9DA87873793E68AA272D5253CA239515318649B54DEB926AF82E3D9DE7DBBA0962ED73A8233577E7073A303EDFFFA7E94D596CCECA2BC8BA08A5DBE249F45232C3675FBD21A32E9B489C7804E2C406C7B4B071976E8064A91C5E53A5316CBA74A5398A625B8BAAAFA34A225E54AC174ACEEA6135EFDB59FF42774E3E30B1C8D4CDC20F8803AF0743A8CD0343C8A6065D94C0EB262BD8CB2556D1C9639E52087DDF83698A6040619246D3DAD1CCC8F5373E06FA90AFAC990E64E91EF4C0315AF1F1114B61FC7E8198BA27E7519D81842534D19E4EDF1F356D150F389F1F3D4942A68F08A404E551A4387D1D81ACFC1BD8721B228371DF7FFD9153C3E3EE705E950C2BE384CEB19E47F04C7631F67D7AFF302BD1901648855D8E585605823A95AE079C3C278DF3C5FBB5F40D35473544A37DFA2F3A1EA09908340706E655AAB5DC8C54637738A77DAF6777221463D125A2D9DDE153A0BC99A92A4FFEECCB766F012AC74909A66DD6828F23C6B3C45A2AEEE593DECA2A6FA5F9F5D27563
+20220716233959 2 6 100 7679 5 EA4C603AE36BD71059D57FCCBE1B8044C230D76993BB57E1277B27A6C4A4B08347D6279C073FCF3AAD938D631C2E6E154467895D8B122C872ED09D0C78541A55F8830207EFC2CA1556E6D9E0E78B0312C663061F6B0692FBB22CA020B4CC24E01DA76F8DC12D2BB87459FC747E3ECE875C8AD2879CD41BD91192BDEB4F30701EB53DD437163646BB8CEDCF66068617495CA9D1611A5C9E4D531A3B575745036E3A3D933984464EB3D86C30ABB3219805BA78FDA311A8F734BCCC83463CDC569AFFB0ECED647616BB7BC3C9865E79E2C4E711F2EB4A2DA078AFF66C15BEAEE0B581037715C505BFB0FE9A9FA47121981F8528DFD137FA66D33083E6F4B74BF2C4AAF0754D0E704803F0F16DF0A9FE41E0C237FFB72BCF0E458F009A77A3E096FD6BDB4799B70C9CE864A108B66D34B56DC9F390CAEBFFC15DAD572F8E57D7CAC68ECE12652303221AF1CC9AD239473CA7E14A1B7B9A6EBF827813340F6D1C97032A7A1FEF147A202A274B0C17F9DCA25214180FA619E3201C174D4B0DDA30D4A1F3EF179126EF859526C539E075EB6E91E2E30AC104FBC69D940D5A70225BBDE026CBBF357DC7543BF3F83A7525AB8F96FDEC0464CD4EB3B106984BD1C4F27BF166079C66790F1CA1AFB56A3B780F6927143E9F85687A2A99F77C46806D8E1C190147CF42E2D1D9A70F964A5CC63D813511685F6BEE77E20CD38D58334EFE7EC2F068A26426001A83758DC82E9B0300CC2FAA0999616147B6B2BF93CBE227D8586CF54FCED628C1AD540844FB6E57CC378881FC90FC3989536CA13F097EAD6F0B45356C6A9DA87873793E68AA272D5253CA239515318649B54DEB926AF82E3D9DE7DBBA0962ED73A8233577E7073A303EDFFFA7E94D596CCECA2BC8BA08A5DBE249F45232C3675FBD21A32E9B489C7804E2C406C7B4B071976E8064A91C5E53A5316CBA74A5398A625B8BAAAFA34A225E54AC174ACEEA6135EFDB59FF42774E3E30B1C8D4CDC20F8803AF0743A8CD0343C8A6065D94C0EB262BD8CB2556D1C9639E52087DDF83698A6040619246D3DAD1CCC8F5373E06FA90AFAC990E64E91EF4C0315AF1F1114B61FC7E8198BA27E7519D81842534D19E4EDF1F356D150F389F1F3D4942A68F08A404E551A4387D1D81ACFC1BD8721B228371DF7FFD9153C3E3EE705E950C2BE384CEB19E47F04C7631F67D7AFF302BD1901648855D8E585605823A95AE079C3C278DF3C5FBB5F40D35473544A37DFA2F3A1EA09908340706E655AAB5DC8C54637738A77DAF6777221463D125A2D9DDE153A0BC99A92A4FFEECCB766F012AC74909A66DD6828F23C6B3C45A2AEEE593DECA2A6FA5F9F8B474DF
+20220717013433 2 6 100 7679 2 EA4C603AE36BD71059D57FCCBE1B8044C230D76993BB57E1277B27A6C4A4B08347D6279C073FCF3AAD938D631C2E6E154467895D8B122C872ED09D0C78541A55F8830207EFC2CA1556E6D9E0E78B0312C663061F6B0692FBB22CA020B4CC24E01DA76F8DC12D2BB87459FC747E3ECE875C8AD2879CD41BD91192BDEB4F30701EB53DD437163646BB8CEDCF66068617495CA9D1611A5C9E4D531A3B575745036E3A3D933984464EB3D86C30ABB3219805BA78FDA311A8F734BCCC83463CDC569AFFB0ECED647616BB7BC3C9865E79E2C4E711F2EB4A2DA078AFF66C15BEAEE0B581037715C505BFB0FE9A9FA47121981F8528DFD137FA66D33083E6F4B74BF2C4AAF0754D0E704803F0F16DF0A9FE41E0C237FFB72BCF0E458F009A77A3E096FD6BDB4799B70C9CE864A108B66D34B56DC9F390CAEBFFC15DAD572F8E57D7CAC68ECE12652303221AF1CC9AD239473CA7E14A1B7B9A6EBF827813340F6D1C97032A7A1FEF147A202A274B0C17F9DCA25214180FA619E3201C174D4B0DDA30D4A1F3EF179126EF859526C539E075EB6E91E2E30AC104FBC69D940D5A70225BBDE026CBBF357DC7543BF3F83A7525AB8F96FDEC0464CD4EB3B106984BD1C4F27BF166079C66790F1CA1AFB56A3B780F6927143E9F85687A2A99F77C46806D8E1C190147CF42E2D1D9A70F964A5CC63D813511685F6BEE77E20CD38D58334EFE7EC2F068A26426001A83758DC82E9B0300CC2FAA0999616147B6B2BF93CBE227D8586CF54FCED628C1AD540844FB6E57CC378881FC90FC3989536CA13F097EAD6F0B45356C6A9DA87873793E68AA272D5253CA239515318649B54DEB926AF82E3D9DE7DBBA0962ED73A8233577E7073A303EDFFFA7E94D596CCECA2BC8BA08A5DBE249F45232C3675FBD21A32E9B489C7804E2C406C7B4B071976E8064A91C5E53A5316CBA74A5398A625B8BAAAFA34A225E54AC174ACEEA6135EFDB59FF42774E3E30B1C8D4CDC20F8803AF0743A8CD0343C8A6065D94C0EB262BD8CB2556D1C9639E52087DDF83698A6040619246D3DAD1CCC8F5373E06FA90AFAC990E64E91EF4C0315AF1F1114B61FC7E8198BA27E7519D81842534D19E4EDF1F356D150F389F1F3D4942A68F08A404E551A4387D1D81ACFC1BD8721B228371DF7FFD9153C3E3EE705E950C2BE384CEB19E47F04C7631F67D7AFF302BD1901648855D8E585605823A95AE079C3C278DF3C5FBB5F40D35473544A37DFA2F3A1EA09908340706E655AAB5DC8C54637738A77DAF6777221463D125A2D9DDE153A0BC99A92A4FFEECCB766F012AC74909A66DD6828F23C6B3C45A2AEEE593DECA2A6FA5FA00EBDEF3
+20220717053018 2 6 100 7679 5 EA4C603AE36BD71059D57FCCBE1B8044C230D76993BB57E1277B27A6C4A4B08347D6279C073FCF3AAD938D631C2E6E154467895D8B122C872ED09D0C78541A55F8830207EFC2CA1556E6D9E0E78B0312C663061F6B0692FBB22CA020B4CC24E01DA76F8DC12D2BB87459FC747E3ECE875C8AD2879CD41BD91192BDEB4F30701EB53DD437163646BB8CEDCF66068617495CA9D1611A5C9E4D531A3B575745036E3A3D933984464EB3D86C30ABB3219805BA78FDA311A8F734BCCC83463CDC569AFFB0ECED647616BB7BC3C9865E79E2C4E711F2EB4A2DA078AFF66C15BEAEE0B581037715C505BFB0FE9A9FA47121981F8528DFD137FA66D33083E6F4B74BF2C4AAF0754D0E704803F0F16DF0A9FE41E0C237FFB72BCF0E458F009A77A3E096FD6BDB4799B70C9CE864A108B66D34B56DC9F390CAEBFFC15DAD572F8E57D7CAC68ECE12652303221AF1CC9AD239473CA7E14A1B7B9A6EBF827813340F6D1C97032A7A1FEF147A202A274B0C17F9DCA25214180FA619E3201C174D4B0DDA30D4A1F3EF179126EF859526C539E075EB6E91E2E30AC104FBC69D940D5A70225BBDE026CBBF357DC7543BF3F83A7525AB8F96FDEC0464CD4EB3B106984BD1C4F27BF166079C66790F1CA1AFB56A3B780F6927143E9F85687A2A99F77C46806D8E1C190147CF42E2D1D9A70F964A5CC63D813511685F6BEE77E20CD38D58334EFE7EC2F068A26426001A83758DC82E9B0300CC2FAA0999616147B6B2BF93CBE227D8586CF54FCED628C1AD540844FB6E57CC378881FC90FC3989536CA13F097EAD6F0B45356C6A9DA87873793E68AA272D5253CA239515318649B54DEB926AF82E3D9DE7DBBA0962ED73A8233577E7073A303EDFFFA7E94D596CCECA2BC8BA08A5DBE249F45232C3675FBD21A32E9B489C7804E2C406C7B4B071976E8064A91C5E53A5316CBA74A5398A625B8BAAAFA34A225E54AC174ACEEA6135EFDB59FF42774E3E30B1C8D4CDC20F8803AF0743A8CD0343C8A6065D94C0EB262BD8CB2556D1C9639E52087DDF83698A6040619246D3DAD1CCC8F5373E06FA90AFAC990E64E91EF4C0315AF1F1114B61FC7E8198BA27E7519D81842534D19E4EDF1F356D150F389F1F3D4942A68F08A404E551A4387D1D81ACFC1BD8721B228371DF7FFD9153C3E3EE705E950C2BE384CEB19E47F04C7631F67D7AFF302BD1901648855D8E585605823A95AE079C3C278DF3C5FBB5F40D35473544A37DFA2F3A1EA09908340706E655AAB5DC8C54637738A77DAF6777221463D125A2D9DDE153A0BC99A92A4FFEECCB766F012AC74909A66DD6828F23C6B3C45A2AEEE593DECA2A6FA5FA11D62647
+20220717084749 2 6 100 7679 5 EA4C603AE36BD71059D57FCCBE1B8044C230D76993BB57E1277B27A6C4A4B08347D6279C073FCF3AAD938D631C2E6E154467895D8B122C872ED09D0C78541A55F8830207EFC2CA1556E6D9E0E78B0312C663061F6B0692FBB22CA020B4CC24E01DA76F8DC12D2BB87459FC747E3ECE875C8AD2879CD41BD91192BDEB4F30701EB53DD437163646BB8CEDCF66068617495CA9D1611A5C9E4D531A3B575745036E3A3D933984464EB3D86C30ABB3219805BA78FDA311A8F734BCCC83463CDC569AFFB0ECED647616BB7BC3C9865E79E2C4E711F2EB4A2DA078AFF66C15BEAEE0B581037715C505BFB0FE9A9FA47121981F8528DFD137FA66D33083E6F4B74BF2C4AAF0754D0E704803F0F16DF0A9FE41E0C237FFB72BCF0E458F009A77A3E096FD6BDB4799B70C9CE864A108B66D34B56DC9F390CAEBFFC15DAD572F8E57D7CAC68ECE12652303221AF1CC9AD239473CA7E14A1B7B9A6EBF827813340F6D1C97032A7A1FEF147A202A274B0C17F9DCA25214180FA619E3201C174D4B0DDA30D4A1F3EF179126EF859526C539E075EB6E91E2E30AC104FBC69D940D5A70225BBDE026CBBF357DC7543BF3F83A7525AB8F96FDEC0464CD4EB3B106984BD1C4F27BF166079C66790F1CA1AFB56A3B780F6927143E9F85687A2A99F77C46806D8E1C190147CF42E2D1D9A70F964A5CC63D813511685F6BEE77E20CD38D58334EFE7EC2F068A26426001A83758DC82E9B0300CC2FAA0999616147B6B2BF93CBE227D8586CF54FCED628C1AD540844FB6E57CC378881FC90FC3989536CA13F097EAD6F0B45356C6A9DA87873793E68AA272D5253CA239515318649B54DEB926AF82E3D9DE7DBBA0962ED73A8233577E7073A303EDFFFA7E94D596CCECA2BC8BA08A5DBE249F45232C3675FBD21A32E9B489C7804E2C406C7B4B071976E8064A91C5E53A5316CBA74A5398A625B8BAAAFA34A225E54AC174ACEEA6135EFDB59FF42774E3E30B1C8D4CDC20F8803AF0743A8CD0343C8A6065D94C0EB262BD8CB2556D1C9639E52087DDF83698A6040619246D3DAD1CCC8F5373E06FA90AFAC990E64E91EF4C0315AF1F1114B61FC7E8198BA27E7519D81842534D19E4EDF1F356D150F389F1F3D4942A68F08A404E551A4387D1D81ACFC1BD8721B228371DF7FFD9153C3E3EE705E950C2BE384CEB19E47F04C7631F67D7AFF302BD1901648855D8E585605823A95AE079C3C278DF3C5FBB5F40D35473544A37DFA2F3A1EA09908340706E655AAB5DC8C54637738A77DAF6777221463D125A2D9DDE153A0BC99A92A4FFEECCB766F012AC74909A66DD6828F23C6B3C45A2AEEE593DECA2A6FA5FA200FD4E7
+20220717092719 2 6 100 7679 5 EA4C603AE36BD71059D57FCCBE1B8044C230D76993BB57E1277B27A6C4A4B08347D6279C073FCF3AAD938D631C2E6E154467895D8B122C872ED09D0C78541A55F8830207EFC2CA1556E6D9E0E78B0312C663061F6B0692FBB22CA020B4CC24E01DA76F8DC12D2BB87459FC747E3ECE875C8AD2879CD41BD91192BDEB4F30701EB53DD437163646BB8CEDCF66068617495CA9D1611A5C9E4D531A3B575745036E3A3D933984464EB3D86C30ABB3219805BA78FDA311A8F734BCCC83463CDC569AFFB0ECED647616BB7BC3C9865E79E2C4E711F2EB4A2DA078AFF66C15BEAEE0B581037715C505BFB0FE9A9FA47121981F8528DFD137FA66D33083E6F4B74BF2C4AAF0754D0E704803F0F16DF0A9FE41E0C237FFB72BCF0E458F009A77A3E096FD6BDB4799B70C9CE864A108B66D34B56DC9F390CAEBFFC15DAD572F8E57D7CAC68ECE12652303221AF1CC9AD239473CA7E14A1B7B9A6EBF827813340F6D1C97032A7A1FEF147A202A274B0C17F9DCA25214180FA619E3201C174D4B0DDA30D4A1F3EF179126EF859526C539E075EB6E91E2E30AC104FBC69D940D5A70225BBDE026CBBF357DC7543BF3F83A7525AB8F96FDEC0464CD4EB3B106984BD1C4F27BF166079C66790F1CA1AFB56A3B780F6927143E9F85687A2A99F77C46806D8E1C190147CF42E2D1D9A70F964A5CC63D813511685F6BEE77E20CD38D58334EFE7EC2F068A26426001A83758DC82E9B0300CC2FAA0999616147B6B2BF93CBE227D8586CF54FCED628C1AD540844FB6E57CC378881FC90FC3989536CA13F097EAD6F0B45356C6A9DA87873793E68AA272D5253CA239515318649B54DEB926AF82E3D9DE7DBBA0962ED73A8233577E7073A303EDFFFA7E94D596CCECA2BC8BA08A5DBE249F45232C3675FBD21A32E9B489C7804E2C406C7B4B071976E8064A91C5E53A5316CBA74A5398A625B8BAAAFA34A225E54AC174ACEEA6135EFDB59FF42774E3E30B1C8D4CDC20F8803AF0743A8CD0343C8A6065D94C0EB262BD8CB2556D1C9639E52087DDF83698A6040619246D3DAD1CCC8F5373E06FA90AFAC990E64E91EF4C0315AF1F1114B61FC7E8198BA27E7519D81842534D19E4EDF1F356D150F389F1F3D4942A68F08A404E551A4387D1D81ACFC1BD8721B228371DF7FFD9153C3E3EE705E950C2BE384CEB19E47F04C7631F67D7AFF302BD1901648855D8E585605823A95AE079C3C278DF3C5FBB5F40D35473544A37DFA2F3A1EA09908340706E655AAB5DC8C54637738A77DAF6777221463D125A2D9DDE153A0BC99A92A4FFEECCB766F012AC74909A66DD6828F23C6B3C45A2AEEE593DECA2A6FA5FA22EFF85F
+20220717101211 2 6 100 7679 5 EA4C603AE36BD71059D57FCCBE1B8044C230D76993BB57E1277B27A6C4A4B08347D6279C073FCF3AAD938D631C2E6E154467895D8B122C872ED09D0C78541A55F8830207EFC2CA1556E6D9E0E78B0312C663061F6B0692FBB22CA020B4CC24E01DA76F8DC12D2BB87459FC747E3ECE875C8AD2879CD41BD91192BDEB4F30701EB53DD437163646BB8CEDCF66068617495CA9D1611A5C9E4D531A3B575745036E3A3D933984464EB3D86C30ABB3219805BA78FDA311A8F734BCCC83463CDC569AFFB0ECED647616BB7BC3C9865E79E2C4E711F2EB4A2DA078AFF66C15BEAEE0B581037715C505BFB0FE9A9FA47121981F8528DFD137FA66D33083E6F4B74BF2C4AAF0754D0E704803F0F16DF0A9FE41E0C237FFB72BCF0E458F009A77A3E096FD6BDB4799B70C9CE864A108B66D34B56DC9F390CAEBFFC15DAD572F8E57D7CAC68ECE12652303221AF1CC9AD239473CA7E14A1B7B9A6EBF827813340F6D1C97032A7A1FEF147A202A274B0C17F9DCA25214180FA619E3201C174D4B0DDA30D4A1F3EF179126EF859526C539E075EB6E91E2E30AC104FBC69D940D5A70225BBDE026CBBF357DC7543BF3F83A7525AB8F96FDEC0464CD4EB3B106984BD1C4F27BF166079C66790F1CA1AFB56A3B780F6927143E9F85687A2A99F77C46806D8E1C190147CF42E2D1D9A70F964A5CC63D813511685F6BEE77E20CD38D58334EFE7EC2F068A26426001A83758DC82E9B0300CC2FAA0999616147B6B2BF93CBE227D8586CF54FCED628C1AD540844FB6E57CC378881FC90FC3989536CA13F097EAD6F0B45356C6A9DA87873793E68AA272D5253CA239515318649B54DEB926AF82E3D9DE7DBBA0962ED73A8233577E7073A303EDFFFA7E94D596CCECA2BC8BA08A5DBE249F45232C3675FBD21A32E9B489C7804E2C406C7B4B071976E8064A91C5E53A5316CBA74A5398A625B8BAAAFA34A225E54AC174ACEEA6135EFDB59FF42774E3E30B1C8D4CDC20F8803AF0743A8CD0343C8A6065D94C0EB262BD8CB2556D1C9639E52087DDF83698A6040619246D3DAD1CCC8F5373E06FA90AFAC990E64E91EF4C0315AF1F1114B61FC7E8198BA27E7519D81842534D19E4EDF1F356D150F389F1F3D4942A68F08A404E551A4387D1D81ACFC1BD8721B228371DF7FFD9153C3E3EE705E950C2BE384CEB19E47F04C7631F67D7AFF302BD1901648855D8E585605823A95AE079C3C278DF3C5FBB5F40D35473544A37DFA2F3A1EA09908340706E655AAB5DC8C54637738A77DAF6777221463D125A2D9DDE153A0BC99A92A4FFEECCB766F012AC74909A66DD6828F23C6B3C45A2AEEE593DECA2A6FA5FA26140AA7
+20220717123906 2 6 100 7679 2 EA4C603AE36BD71059D57FCCBE1B8044C230D76993BB57E1277B27A6C4A4B08347D6279C073FCF3AAD938D631C2E6E154467895D8B122C872ED09D0C78541A55F8830207EFC2CA1556E6D9E0E78B0312C663061F6B0692FBB22CA020B4CC24E01DA76F8DC12D2BB87459FC747E3ECE875C8AD2879CD41BD91192BDEB4F30701EB53DD437163646BB8CEDCF66068617495CA9D1611A5C9E4D531A3B575745036E3A3D933984464EB3D86C30ABB3219805BA78FDA311A8F734BCCC83463CDC569AFFB0ECED647616BB7BC3C9865E79E2C4E711F2EB4A2DA078AFF66C15BEAEE0B581037715C505BFB0FE9A9FA47121981F8528DFD137FA66D33083E6F4B74BF2C4AAF0754D0E704803F0F16DF0A9FE41E0C237FFB72BCF0E458F009A77A3E096FD6BDB4799B70C9CE864A108B66D34B56DC9F390CAEBFFC15DAD572F8E57D7CAC68ECE12652303221AF1CC9AD239473CA7E14A1B7B9A6EBF827813340F6D1C97032A7A1FEF147A202A274B0C17F9DCA25214180FA619E3201C174D4B0DDA30D4A1F3EF179126EF859526C539E075EB6E91E2E30AC104FBC69D940D5A70225BBDE026CBBF357DC7543BF3F83A7525AB8F96FDEC0464CD4EB3B106984BD1C4F27BF166079C66790F1CA1AFB56A3B780F6927143E9F85687A2A99F77C46806D8E1C190147CF42E2D1D9A70F964A5CC63D813511685F6BEE77E20CD38D58334EFE7EC2F068A26426001A83758DC82E9B0300CC2FAA0999616147B6B2BF93CBE227D8586CF54FCED628C1AD540844FB6E57CC378881FC90FC3989536CA13F097EAD6F0B45356C6A9DA87873793E68AA272D5253CA239515318649B54DEB926AF82E3D9DE7DBBA0962ED73A8233577E7073A303EDFFFA7E94D596CCECA2BC8BA08A5DBE249F45232C3675FBD21A32E9B489C7804E2C406C7B4B071976E8064A91C5E53A5316CBA74A5398A625B8BAAAFA34A225E54AC174ACEEA6135EFDB59FF42774E3E30B1C8D4CDC20F8803AF0743A8CD0343C8A6065D94C0EB262BD8CB2556D1C9639E52087DDF83698A6040619246D3DAD1CCC8F5373E06FA90AFAC990E64E91EF4C0315AF1F1114B61FC7E8198BA27E7519D81842534D19E4EDF1F356D150F389F1F3D4942A68F08A404E551A4387D1D81ACFC1BD8721B228371DF7FFD9153C3E3EE705E950C2BE384CEB19E47F04C7631F67D7AFF302BD1901648855D8E585605823A95AE079C3C278DF3C5FBB5F40D35473544A37DFA2F3A1EA09908340706E655AAB5DC8C54637738A77DAF6777221463D125A2D9DDE153A0BC99A92A4FFEECCB766F012AC74909A66DD6828F23C6B3C45A2AEEE593DECA2A6FA5FA3081C463
+20220717124254 2 6 100 7679 2 EA4C603AE36BD71059D57FCCBE1B8044C230D76993BB57E1277B27A6C4A4B08347D6279C073FCF3AAD938D631C2E6E154467895D8B122C872ED09D0C78541A55F8830207EFC2CA1556E6D9E0E78B0312C663061F6B0692FBB22CA020B4CC24E01DA76F8DC12D2BB87459FC747E3ECE875C8AD2879CD41BD91192BDEB4F30701EB53DD437163646BB8CEDCF66068617495CA9D1611A5C9E4D531A3B575745036E3A3D933984464EB3D86C30ABB3219805BA78FDA311A8F734BCCC83463CDC569AFFB0ECED647616BB7BC3C9865E79E2C4E711F2EB4A2DA078AFF66C15BEAEE0B581037715C505BFB0FE9A9FA47121981F8528DFD137FA66D33083E6F4B74BF2C4AAF0754D0E704803F0F16DF0A9FE41E0C237FFB72BCF0E458F009A77A3E096FD6BDB4799B70C9CE864A108B66D34B56DC9F390CAEBFFC15DAD572F8E57D7CAC68ECE12652303221AF1CC9AD239473CA7E14A1B7B9A6EBF827813340F6D1C97032A7A1FEF147A202A274B0C17F9DCA25214180FA619E3201C174D4B0DDA30D4A1F3EF179126EF859526C539E075EB6E91E2E30AC104FBC69D940D5A70225BBDE026CBBF357DC7543BF3F83A7525AB8F96FDEC0464CD4EB3B106984BD1C4F27BF166079C66790F1CA1AFB56A3B780F6927143E9F85687A2A99F77C46806D8E1C190147CF42E2D1D9A70F964A5CC63D813511685F6BEE77E20CD38D58334EFE7EC2F068A26426001A83758DC82E9B0300CC2FAA0999616147B6B2BF93CBE227D8586CF54FCED628C1AD540844FB6E57CC378881FC90FC3989536CA13F097EAD6F0B45356C6A9DA87873793E68AA272D5253CA239515318649B54DEB926AF82E3D9DE7DBBA0962ED73A8233577E7073A303EDFFFA7E94D596CCECA2BC8BA08A5DBE249F45232C3675FBD21A32E9B489C7804E2C406C7B4B071976E8064A91C5E53A5316CBA74A5398A625B8BAAAFA34A225E54AC174ACEEA6135EFDB59FF42774E3E30B1C8D4CDC20F8803AF0743A8CD0343C8A6065D94C0EB262BD8CB2556D1C9639E52087DDF83698A6040619246D3DAD1CCC8F5373E06FA90AFAC990E64E91EF4C0315AF1F1114B61FC7E8198BA27E7519D81842534D19E4EDF1F356D150F389F1F3D4942A68F08A404E551A4387D1D81ACFC1BD8721B228371DF7FFD9153C3E3EE705E950C2BE384CEB19E47F04C7631F67D7AFF302BD1901648855D8E585605823A95AE079C3C278DF3C5FBB5F40D35473544A37DFA2F3A1EA09908340706E655AAB5DC8C54637738A77DAF6777221463D125A2D9DDE153A0BC99A92A4FFEECCB766F012AC74909A66DD6828F23C6B3C45A2AEEE593DECA2A6FA5FA30C8F0E3
+20220717143701 2 6 100 8191 2 F2F7A2BAF50A41FBCCDE554E561409993B1C6E4133229CAC67C79DE5FEC1F9FBEBECCCE838368FBFA93F774AD02E99F65F8B3F56B3047638FE35167D048A951E3A317CED92846B94A639A0B3D5F098B35BDA8C139A8EB185EC3F843A6778FAB4EEC4DD1B20F071BC9E5075F7AEF1531CC8FB12E64D48A478BBC398D69E12066975EC2A96BCC6D155FB0BDA03C4D4E817DCCF320E8F34447A94C64E28B8F84D07C08BDDA1215CC370EF5EB970A75ED4F8ADB47F36B134A3430DAA59FEF55CD4B9786F693B09BC9C3E6F1F745BABBC6F5892BC4E416BDA02BD59DD7C763179B2897CBCAF284E0A2DE08E4E32BB1F66169D83FA0206C7962184A15527C7CA8EF04AF87921933A2B9C614145AFEC715C833924B8C863E7E20A07AA21A72C450BBC446B9B51407D90261CDE342C5D585A0482DB8FFC95B72992ED5D8085B8A3A8335A1423F7715AB83DB4D88BB599B272B8F80BE3C03B0A3C4F7C2F2486984FE13CA8E4510EA33B45BD782D415AEE1C22885D10BB5D16521E8907054ADE2FA85D8284B89849B05696AC17AD99279CB7675E8261EDFD7CF38B0E714E4C126D13363422B9D1097C590DD4DE80A1CF7872B2D8F6951877EEB91DC4C24F47C9949676565244DB3B923EE368EE43720DC186E96B0B6E0908D967CC5D5C055659978668FCCE03F8D1F087A9EF12446BA87FF4345D757F477C1A838B5EF0A9F45C712A8147A71EA88FBDA3B9A7D1BB5A477A4C224F5F067271E13CBCA9AFBC444FA340B55987BA1D2263107F495BAD2001B296C5E9F700A7C9C3C966E507428A8F9D0A55E240F4E30F3E4E6159E464311FFA3DFC418DD8B5F28640E6CA09D8A76207F978038A3E8A14C66A3237F0E099E16965B72573CE9B895622FF7606EE54E51D0D0F470280EDC42C6F6E0E298ACC1F7DCDFE3B1299BE5774C8584C11EDB9A89A7FF3E899CD4A74816EFB2223D520CEEBD82D09F4CE741BBC0E0B0C597C14AE6C29255C8C8A5E89353FC1A7BDBD5E329D4D850DAF65851D23931426FEBBE80217562727A9088697C7EED3153BD9475FB85A4A443A71680C7032ADDD3A03F4B6CEB8FDD75DA0CA9332C6E5CE2AFAE921F98B37FE8A64EBB1AF3F29D1D1DE8F2328F3C8B2D6BB8ABF00DE82CCDAA0156061616163E1AF9B65AB54D07A0D927DA73C9304C214AE7AF00BC57B759DFDD12CC6947423BBFCF51949E19F6C1CD6FB208FF43C8CCC89D132B0EB4A6C66C1F3EBDDAAA553BB328AB0F89C9D0B28A1DBE5D8302A1333120D3BEEF97F0AD01439C4491EE560D05EB79E62D14328BE63C3D8D3B97973FEF44A23F1DCC674A32EC85E2A6837F2782623D09ED658324912498A4AB925BA55CE6AC89FA1C73ADAFC12AB808A25A49F1301EE991316CEE05D92290908DC9C5709CF9912570EB56DE350DB4604C401380B2F1FFC2869409B2C5A912221EF5FC3
+20220717153012 2 6 100 8191 2 F2F7A2BAF50A41FBCCDE554E561409993B1C6E4133229CAC67C79DE5FEC1F9FBEBECCCE838368FBFA93F774AD02E99F65F8B3F56B3047638FE35167D048A951E3A317CED92846B94A639A0B3D5F098B35BDA8C139A8EB185EC3F843A6778FAB4EEC4DD1B20F071BC9E5075F7AEF1531CC8FB12E64D48A478BBC398D69E12066975EC2A96BCC6D155FB0BDA03C4D4E817DCCF320E8F34447A94C64E28B8F84D07C08BDDA1215CC370EF5EB970A75ED4F8ADB47F36B134A3430DAA59FEF55CD4B9786F693B09BC9C3E6F1F745BABBC6F5892BC4E416BDA02BD59DD7C763179B2897CBCAF284E0A2DE08E4E32BB1F66169D83FA0206C7962184A15527C7CA8EF04AF87921933A2B9C614145AFEC715C833924B8C863E7E20A07AA21A72C450BBC446B9B51407D90261CDE342C5D585A0482DB8FFC95B72992ED5D8085B8A3A8335A1423F7715AB83DB4D88BB599B272B8F80BE3C03B0A3C4F7C2F2486984FE13CA8E4510EA33B45BD782D415AEE1C22885D10BB5D16521E8907054ADE2FA85D8284B89849B05696AC17AD99279CB7675E8261EDFD7CF38B0E714E4C126D13363422B9D1097C590DD4DE80A1CF7872B2D8F6951877EEB91DC4C24F47C9949676565244DB3B923EE368EE43720DC186E96B0B6E0908D967CC5D5C055659978668FCCE03F8D1F087A9EF12446BA87FF4345D757F477C1A838B5EF0A9F45C712A8147A71EA88FBDA3B9A7D1BB5A477A4C224F5F067271E13CBCA9AFBC444FA340B55987BA1D2263107F495BAD2001B296C5E9F700A7C9C3C966E507428A8F9D0A55E240F4E30F3E4E6159E464311FFA3DFC418DD8B5F28640E6CA09D8A76207F978038A3E8A14C66A3237F0E099E16965B72573CE9B895622FF7606EE54E51D0D0F470280EDC42C6F6E0E298ACC1F7DCDFE3B1299BE5774C8584C11EDB9A89A7FF3E899CD4A74816EFB2223D520CEEBD82D09F4CE741BBC0E0B0C597C14AE6C29255C8C8A5E89353FC1A7BDBD5E329D4D850DAF65851D23931426FEBBE80217562727A9088697C7EED3153BD9475FB85A4A443A71680C7032ADDD3A03F4B6CEB8FDD75DA0CA9332C6E5CE2AFAE921F98B37FE8A64EBB1AF3F29D1D1DE8F2328F3C8B2D6BB8ABF00DE82CCDAA0156061616163E1AF9B65AB54D07A0D927DA73C9304C214AE7AF00BC57B759DFDD12CC6947423BBFCF51949E19F6C1CD6FB208FF43C8CCC89D132B0EB4A6C66C1F3EBDDAAA553BB328AB0F89C9D0B28A1DBE5D8302A1333120D3BEEF97F0AD01439C4491EE560D05EB79E62D14328BE63C3D8D3B97973FEF44A23F1DCC674A32EC85E2A6837F2782623D09ED658324912498A4AB925BA55CE6AC89FA1C73ADAFC12AB808A25A49F1301EE991316CEE05D92290908DC9C5709CF9912570EB56DE350DB4604C401380B2F1FFC2869409B2C5A9122251C88EB
+20220717154944 2 6 100 8191 2 F2F7A2BAF50A41FBCCDE554E561409993B1C6E4133229CAC67C79DE5FEC1F9FBEBECCCE838368FBFA93F774AD02E99F65F8B3F56B3047638FE35167D048A951E3A317CED92846B94A639A0B3D5F098B35BDA8C139A8EB185EC3F843A6778FAB4EEC4DD1B20F071BC9E5075F7AEF1531CC8FB12E64D48A478BBC398D69E12066975EC2A96BCC6D155FB0BDA03C4D4E817DCCF320E8F34447A94C64E28B8F84D07C08BDDA1215CC370EF5EB970A75ED4F8ADB47F36B134A3430DAA59FEF55CD4B9786F693B09BC9C3E6F1F745BABBC6F5892BC4E416BDA02BD59DD7C763179B2897CBCAF284E0A2DE08E4E32BB1F66169D83FA0206C7962184A15527C7CA8EF04AF87921933A2B9C614145AFEC715C833924B8C863E7E20A07AA21A72C450BBC446B9B51407D90261CDE342C5D585A0482DB8FFC95B72992ED5D8085B8A3A8335A1423F7715AB83DB4D88BB599B272B8F80BE3C03B0A3C4F7C2F2486984FE13CA8E4510EA33B45BD782D415AEE1C22885D10BB5D16521E8907054ADE2FA85D8284B89849B05696AC17AD99279CB7675E8261EDFD7CF38B0E714E4C126D13363422B9D1097C590DD4DE80A1CF7872B2D8F6951877EEB91DC4C24F47C9949676565244DB3B923EE368EE43720DC186E96B0B6E0908D967CC5D5C055659978668FCCE03F8D1F087A9EF12446BA87FF4345D757F477C1A838B5EF0A9F45C712A8147A71EA88FBDA3B9A7D1BB5A477A4C224F5F067271E13CBCA9AFBC444FA340B55987BA1D2263107F495BAD2001B296C5E9F700A7C9C3C966E507428A8F9D0A55E240F4E30F3E4E6159E464311FFA3DFC418DD8B5F28640E6CA09D8A76207F978038A3E8A14C66A3237F0E099E16965B72573CE9B895622FF7606EE54E51D0D0F470280EDC42C6F6E0E298ACC1F7DCDFE3B1299BE5774C8584C11EDB9A89A7FF3E899CD4A74816EFB2223D520CEEBD82D09F4CE741BBC0E0B0C597C14AE6C29255C8C8A5E89353FC1A7BDBD5E329D4D850DAF65851D23931426FEBBE80217562727A9088697C7EED3153BD9475FB85A4A443A71680C7032ADDD3A03F4B6CEB8FDD75DA0CA9332C6E5CE2AFAE921F98B37FE8A64EBB1AF3F29D1D1DE8F2328F3C8B2D6BB8ABF00DE82CCDAA0156061616163E1AF9B65AB54D07A0D927DA73C9304C214AE7AF00BC57B759DFDD12CC6947423BBFCF51949E19F6C1CD6FB208FF43C8CCC89D132B0EB4A6C66C1F3EBDDAAA553BB328AB0F89C9D0B28A1DBE5D8302A1333120D3BEEF97F0AD01439C4491EE560D05EB79E62D14328BE63C3D8D3B97973FEF44A23F1DCC674A32EC85E2A6837F2782623D09ED658324912498A4AB925BA55CE6AC89FA1C73ADAFC12AB808A25A49F1301EE991316CEE05D92290908DC9C5709CF9912570EB56DE350DB4604C401380B2F1FFC2869409B2C5A91222646A2EB
+20220717155622 2 6 100 8191 2 F2F7A2BAF50A41FBCCDE554E561409993B1C6E4133229CAC67C79DE5FEC1F9FBEBECCCE838368FBFA93F774AD02E99F65F8B3F56B3047638FE35167D048A951E3A317CED92846B94A639A0B3D5F098B35BDA8C139A8EB185EC3F843A6778FAB4EEC4DD1B20F071BC9E5075F7AEF1531CC8FB12E64D48A478BBC398D69E12066975EC2A96BCC6D155FB0BDA03C4D4E817DCCF320E8F34447A94C64E28B8F84D07C08BDDA1215CC370EF5EB970A75ED4F8ADB47F36B134A3430DAA59FEF55CD4B9786F693B09BC9C3E6F1F745BABBC6F5892BC4E416BDA02BD59DD7C763179B2897CBCAF284E0A2DE08E4E32BB1F66169D83FA0206C7962184A15527C7CA8EF04AF87921933A2B9C614145AFEC715C833924B8C863E7E20A07AA21A72C450BBC446B9B51407D90261CDE342C5D585A0482DB8FFC95B72992ED5D8085B8A3A8335A1423F7715AB83DB4D88BB599B272B8F80BE3C03B0A3C4F7C2F2486984FE13CA8E4510EA33B45BD782D415AEE1C22885D10BB5D16521E8907054ADE2FA85D8284B89849B05696AC17AD99279CB7675E8261EDFD7CF38B0E714E4C126D13363422B9D1097C590DD4DE80A1CF7872B2D8F6951877EEB91DC4C24F47C9949676565244DB3B923EE368EE43720DC186E96B0B6E0908D967CC5D5C055659978668FCCE03F8D1F087A9EF12446BA87FF4345D757F477C1A838B5EF0A9F45C712A8147A71EA88FBDA3B9A7D1BB5A477A4C224F5F067271E13CBCA9AFBC444FA340B55987BA1D2263107F495BAD2001B296C5E9F700A7C9C3C966E507428A8F9D0A55E240F4E30F3E4E6159E464311FFA3DFC418DD8B5F28640E6CA09D8A76207F978038A3E8A14C66A3237F0E099E16965B72573CE9B895622FF7606EE54E51D0D0F470280EDC42C6F6E0E298ACC1F7DCDFE3B1299BE5774C8584C11EDB9A89A7FF3E899CD4A74816EFB2223D520CEEBD82D09F4CE741BBC0E0B0C597C14AE6C29255C8C8A5E89353FC1A7BDBD5E329D4D850DAF65851D23931426FEBBE80217562727A9088697C7EED3153BD9475FB85A4A443A71680C7032ADDD3A03F4B6CEB8FDD75DA0CA9332C6E5CE2AFAE921F98B37FE8A64EBB1AF3F29D1D1DE8F2328F3C8B2D6BB8ABF00DE82CCDAA0156061616163E1AF9B65AB54D07A0D927DA73C9304C214AE7AF00BC57B759DFDD12CC6947423BBFCF51949E19F6C1CD6FB208FF43C8CCC89D132B0EB4A6C66C1F3EBDDAAA553BB328AB0F89C9D0B28A1DBE5D8302A1333120D3BEEF97F0AD01439C4491EE560D05EB79E62D14328BE63C3D8D3B97973FEF44A23F1DCC674A32EC85E2A6837F2782623D09ED658324912498A4AB925BA55CE6AC89FA1C73ADAFC12AB808A25A49F1301EE991316CEE05D92290908DC9C5709CF9912570EB56DE350DB4604C401380B2F1FFC2869409B2C5A912226A76CDB
+20220717183729 2 6 100 8191 2 F2F7A2BAF50A41FBCCDE554E561409993B1C6E4133229CAC67C79DE5FEC1F9FBEBECCCE838368FBFA93F774AD02E99F65F8B3F56B3047638FE35167D048A951E3A317CED92846B94A639A0B3D5F098B35BDA8C139A8EB185EC3F843A6778FAB4EEC4DD1B20F071BC9E5075F7AEF1531CC8FB12E64D48A478BBC398D69E12066975EC2A96BCC6D155FB0BDA03C4D4E817DCCF320E8F34447A94C64E28B8F84D07C08BDDA1215CC370EF5EB970A75ED4F8ADB47F36B134A3430DAA59FEF55CD4B9786F693B09BC9C3E6F1F745BABBC6F5892BC4E416BDA02BD59DD7C763179B2897CBCAF284E0A2DE08E4E32BB1F66169D83FA0206C7962184A15527C7CA8EF04AF87921933A2B9C614145AFEC715C833924B8C863E7E20A07AA21A72C450BBC446B9B51407D90261CDE342C5D585A0482DB8FFC95B72992ED5D8085B8A3A8335A1423F7715AB83DB4D88BB599B272B8F80BE3C03B0A3C4F7C2F2486984FE13CA8E4510EA33B45BD782D415AEE1C22885D10BB5D16521E8907054ADE2FA85D8284B89849B05696AC17AD99279CB7675E8261EDFD7CF38B0E714E4C126D13363422B9D1097C590DD4DE80A1CF7872B2D8F6951877EEB91DC4C24F47C9949676565244DB3B923EE368EE43720DC186E96B0B6E0908D967CC5D5C055659978668FCCE03F8D1F087A9EF12446BA87FF4345D757F477C1A838B5EF0A9F45C712A8147A71EA88FBDA3B9A7D1BB5A477A4C224F5F067271E13CBCA9AFBC444FA340B55987BA1D2263107F495BAD2001B296C5E9F700A7C9C3C966E507428A8F9D0A55E240F4E30F3E4E6159E464311FFA3DFC418DD8B5F28640E6CA09D8A76207F978038A3E8A14C66A3237F0E099E16965B72573CE9B895622FF7606EE54E51D0D0F470280EDC42C6F6E0E298ACC1F7DCDFE3B1299BE5774C8584C11EDB9A89A7FF3E899CD4A74816EFB2223D520CEEBD82D09F4CE741BBC0E0B0C597C14AE6C29255C8C8A5E89353FC1A7BDBD5E329D4D850DAF65851D23931426FEBBE80217562727A9088697C7EED3153BD9475FB85A4A443A71680C7032ADDD3A03F4B6CEB8FDD75DA0CA9332C6E5CE2AFAE921F98B37FE8A64EBB1AF3F29D1D1DE8F2328F3C8B2D6BB8ABF00DE82CCDAA0156061616163E1AF9B65AB54D07A0D927DA73C9304C214AE7AF00BC57B759DFDD12CC6947423BBFCF51949E19F6C1CD6FB208FF43C8CCC89D132B0EB4A6C66C1F3EBDDAAA553BB328AB0F89C9D0B28A1DBE5D8302A1333120D3BEEF97F0AD01439C4491EE560D05EB79E62D14328BE63C3D8D3B97973FEF44A23F1DCC674A32EC85E2A6837F2782623D09ED658324912498A4AB925BA55CE6AC89FA1C73ADAFC12AB808A25A49F1301EE991316CEE05D92290908DC9C5709CF9912570EB56DE350DB4604C401380B2F1FFC2869409B2C5A9122303F69EB
+20220717205515 2 6 100 8191 2 F2F7A2BAF50A41FBCCDE554E561409993B1C6E4133229CAC67C79DE5FEC1F9FBEBECCCE838368FBFA93F774AD02E99F65F8B3F56B3047638FE35167D048A951E3A317CED92846B94A639A0B3D5F098B35BDA8C139A8EB185EC3F843A6778FAB4EEC4DD1B20F071BC9E5075F7AEF1531CC8FB12E64D48A478BBC398D69E12066975EC2A96BCC6D155FB0BDA03C4D4E817DCCF320E8F34447A94C64E28B8F84D07C08BDDA1215CC370EF5EB970A75ED4F8ADB47F36B134A3430DAA59FEF55CD4B9786F693B09BC9C3E6F1F745BABBC6F5892BC4E416BDA02BD59DD7C763179B2897CBCAF284E0A2DE08E4E32BB1F66169D83FA0206C7962184A15527C7CA8EF04AF87921933A2B9C614145AFEC715C833924B8C863E7E20A07AA21A72C450BBC446B9B51407D90261CDE342C5D585A0482DB8FFC95B72992ED5D8085B8A3A8335A1423F7715AB83DB4D88BB599B272B8F80BE3C03B0A3C4F7C2F2486984FE13CA8E4510EA33B45BD782D415AEE1C22885D10BB5D16521E8907054ADE2FA85D8284B89849B05696AC17AD99279CB7675E8261EDFD7CF38B0E714E4C126D13363422B9D1097C590DD4DE80A1CF7872B2D8F6951877EEB91DC4C24F47C9949676565244DB3B923EE368EE43720DC186E96B0B6E0908D967CC5D5C055659978668FCCE03F8D1F087A9EF12446BA87FF4345D757F477C1A838B5EF0A9F45C712A8147A71EA88FBDA3B9A7D1BB5A477A4C224F5F067271E13CBCA9AFBC444FA340B55987BA1D2263107F495BAD2001B296C5E9F700A7C9C3C966E507428A8F9D0A55E240F4E30F3E4E6159E464311FFA3DFC418DD8B5F28640E6CA09D8A76207F978038A3E8A14C66A3237F0E099E16965B72573CE9B895622FF7606EE54E51D0D0F470280EDC42C6F6E0E298ACC1F7DCDFE3B1299BE5774C8584C11EDB9A89A7FF3E899CD4A74816EFB2223D520CEEBD82D09F4CE741BBC0E0B0C597C14AE6C29255C8C8A5E89353FC1A7BDBD5E329D4D850DAF65851D23931426FEBBE80217562727A9088697C7EED3153BD9475FB85A4A443A71680C7032ADDD3A03F4B6CEB8FDD75DA0CA9332C6E5CE2AFAE921F98B37FE8A64EBB1AF3F29D1D1DE8F2328F3C8B2D6BB8ABF00DE82CCDAA0156061616163E1AF9B65AB54D07A0D927DA73C9304C214AE7AF00BC57B759DFDD12CC6947423BBFCF51949E19F6C1CD6FB208FF43C8CCC89D132B0EB4A6C66C1F3EBDDAAA553BB328AB0F89C9D0B28A1DBE5D8302A1333120D3BEEF97F0AD01439C4491EE560D05EB79E62D14328BE63C3D8D3B97973FEF44A23F1DCC674A32EC85E2A6837F2782623D09ED658324912498A4AB925BA55CE6AC89FA1C73ADAFC12AB808A25A49F1301EE991316CEE05D92290908DC9C5709CF9912570EB56DE350DB4604C401380B2F1FFC2869409B2C5A9122387E1CD3
+20220717211522 2 6 100 8191 2 F2F7A2BAF50A41FBCCDE554E561409993B1C6E4133229CAC67C79DE5FEC1F9FBEBECCCE838368FBFA93F774AD02E99F65F8B3F56B3047638FE35167D048A951E3A317CED92846B94A639A0B3D5F098B35BDA8C139A8EB185EC3F843A6778FAB4EEC4DD1B20F071BC9E5075F7AEF1531CC8FB12E64D48A478BBC398D69E12066975EC2A96BCC6D155FB0BDA03C4D4E817DCCF320E8F34447A94C64E28B8F84D07C08BDDA1215CC370EF5EB970A75ED4F8ADB47F36B134A3430DAA59FEF55CD4B9786F693B09BC9C3E6F1F745BABBC6F5892BC4E416BDA02BD59DD7C763179B2897CBCAF284E0A2DE08E4E32BB1F66169D83FA0206C7962184A15527C7CA8EF04AF87921933A2B9C614145AFEC715C833924B8C863E7E20A07AA21A72C450BBC446B9B51407D90261CDE342C5D585A0482DB8FFC95B72992ED5D8085B8A3A8335A1423F7715AB83DB4D88BB599B272B8F80BE3C03B0A3C4F7C2F2486984FE13CA8E4510EA33B45BD782D415AEE1C22885D10BB5D16521E8907054ADE2FA85D8284B89849B05696AC17AD99279CB7675E8261EDFD7CF38B0E714E4C126D13363422B9D1097C590DD4DE80A1CF7872B2D8F6951877EEB91DC4C24F47C9949676565244DB3B923EE368EE43720DC186E96B0B6E0908D967CC5D5C055659978668FCCE03F8D1F087A9EF12446BA87FF4345D757F477C1A838B5EF0A9F45C712A8147A71EA88FBDA3B9A7D1BB5A477A4C224F5F067271E13CBCA9AFBC444FA340B55987BA1D2263107F495BAD2001B296C5E9F700A7C9C3C966E507428A8F9D0A55E240F4E30F3E4E6159E464311FFA3DFC418DD8B5F28640E6CA09D8A76207F978038A3E8A14C66A3237F0E099E16965B72573CE9B895622FF7606EE54E51D0D0F470280EDC42C6F6E0E298ACC1F7DCDFE3B1299BE5774C8584C11EDB9A89A7FF3E899CD4A74816EFB2223D520CEEBD82D09F4CE741BBC0E0B0C597C14AE6C29255C8C8A5E89353FC1A7BDBD5E329D4D850DAF65851D23931426FEBBE80217562727A9088697C7EED3153BD9475FB85A4A443A71680C7032ADDD3A03F4B6CEB8FDD75DA0CA9332C6E5CE2AFAE921F98B37FE8A64EBB1AF3F29D1D1DE8F2328F3C8B2D6BB8ABF00DE82CCDAA0156061616163E1AF9B65AB54D07A0D927DA73C9304C214AE7AF00BC57B759DFDD12CC6947423BBFCF51949E19F6C1CD6FB208FF43C8CCC89D132B0EB4A6C66C1F3EBDDAAA553BB328AB0F89C9D0B28A1DBE5D8302A1333120D3BEEF97F0AD01439C4491EE560D05EB79E62D14328BE63C3D8D3B97973FEF44A23F1DCC674A32EC85E2A6837F2782623D09ED658324912498A4AB925BA55CE6AC89FA1C73ADAFC12AB808A25A49F1301EE991316CEE05D92290908DC9C5709CF9912570EB56DE350DB4604C401380B2F1FFC2869409B2C5A912239B0E0C3
+20220717215431 2 6 100 8191 2 F2F7A2BAF50A41FBCCDE554E561409993B1C6E4133229CAC67C79DE5FEC1F9FBEBECCCE838368FBFA93F774AD02E99F65F8B3F56B3047638FE35167D048A951E3A317CED92846B94A639A0B3D5F098B35BDA8C139A8EB185EC3F843A6778FAB4EEC4DD1B20F071BC9E5075F7AEF1531CC8FB12E64D48A478BBC398D69E12066975EC2A96BCC6D155FB0BDA03C4D4E817DCCF320E8F34447A94C64E28B8F84D07C08BDDA1215CC370EF5EB970A75ED4F8ADB47F36B134A3430DAA59FEF55CD4B9786F693B09BC9C3E6F1F745BABBC6F5892BC4E416BDA02BD59DD7C763179B2897CBCAF284E0A2DE08E4E32BB1F66169D83FA0206C7962184A15527C7CA8EF04AF87921933A2B9C614145AFEC715C833924B8C863E7E20A07AA21A72C450BBC446B9B51407D90261CDE342C5D585A0482DB8FFC95B72992ED5D8085B8A3A8335A1423F7715AB83DB4D88BB599B272B8F80BE3C03B0A3C4F7C2F2486984FE13CA8E4510EA33B45BD782D415AEE1C22885D10BB5D16521E8907054ADE2FA85D8284B89849B05696AC17AD99279CB7675E8261EDFD7CF38B0E714E4C126D13363422B9D1097C590DD4DE80A1CF7872B2D8F6951877EEB91DC4C24F47C9949676565244DB3B923EE368EE43720DC186E96B0B6E0908D967CC5D5C055659978668FCCE03F8D1F087A9EF12446BA87FF4345D757F477C1A838B5EF0A9F45C712A8147A71EA88FBDA3B9A7D1BB5A477A4C224F5F067271E13CBCA9AFBC444FA340B55987BA1D2263107F495BAD2001B296C5E9F700A7C9C3C966E507428A8F9D0A55E240F4E30F3E4E6159E464311FFA3DFC418DD8B5F28640E6CA09D8A76207F978038A3E8A14C66A3237F0E099E16965B72573CE9B895622FF7606EE54E51D0D0F470280EDC42C6F6E0E298ACC1F7DCDFE3B1299BE5774C8584C11EDB9A89A7FF3E899CD4A74816EFB2223D520CEEBD82D09F4CE741BBC0E0B0C597C14AE6C29255C8C8A5E89353FC1A7BDBD5E329D4D850DAF65851D23931426FEBBE80217562727A9088697C7EED3153BD9475FB85A4A443A71680C7032ADDD3A03F4B6CEB8FDD75DA0CA9332C6E5CE2AFAE921F98B37FE8A64EBB1AF3F29D1D1DE8F2328F3C8B2D6BB8ABF00DE82CCDAA0156061616163E1AF9B65AB54D07A0D927DA73C9304C214AE7AF00BC57B759DFDD12CC6947423BBFCF51949E19F6C1CD6FB208FF43C8CCC89D132B0EB4A6C66C1F3EBDDAAA553BB328AB0F89C9D0B28A1DBE5D8302A1333120D3BEEF97F0AD01439C4491EE560D05EB79E62D14328BE63C3D8D3B97973FEF44A23F1DCC674A32EC85E2A6837F2782623D09ED658324912498A4AB925BA55CE6AC89FA1C73ADAFC12AB808A25A49F1301EE991316CEE05D92290908DC9C5709CF9912570EB56DE350DB4604C401380B2F1FFC2869409B2C5A91223C0BF2F3
+20220717230904 2 6 100 8191 2 F2F7A2BAF50A41FBCCDE554E561409993B1C6E4133229CAC67C79DE5FEC1F9FBEBECCCE838368FBFA93F774AD02E99F65F8B3F56B3047638FE35167D048A951E3A317CED92846B94A639A0B3D5F098B35BDA8C139A8EB185EC3F843A6778FAB4EEC4DD1B20F071BC9E5075F7AEF1531CC8FB12E64D48A478BBC398D69E12066975EC2A96BCC6D155FB0BDA03C4D4E817DCCF320E8F34447A94C64E28B8F84D07C08BDDA1215CC370EF5EB970A75ED4F8ADB47F36B134A3430DAA59FEF55CD4B9786F693B09BC9C3E6F1F745BABBC6F5892BC4E416BDA02BD59DD7C763179B2897CBCAF284E0A2DE08E4E32BB1F66169D83FA0206C7962184A15527C7CA8EF04AF87921933A2B9C614145AFEC715C833924B8C863E7E20A07AA21A72C450BBC446B9B51407D90261CDE342C5D585A0482DB8FFC95B72992ED5D8085B8A3A8335A1423F7715AB83DB4D88BB599B272B8F80BE3C03B0A3C4F7C2F2486984FE13CA8E4510EA33B45BD782D415AEE1C22885D10BB5D16521E8907054ADE2FA85D8284B89849B05696AC17AD99279CB7675E8261EDFD7CF38B0E714E4C126D13363422B9D1097C590DD4DE80A1CF7872B2D8F6951877EEB91DC4C24F47C9949676565244DB3B923EE368EE43720DC186E96B0B6E0908D967CC5D5C055659978668FCCE03F8D1F087A9EF12446BA87FF4345D757F477C1A838B5EF0A9F45C712A8147A71EA88FBDA3B9A7D1BB5A477A4C224F5F067271E13CBCA9AFBC444FA340B55987BA1D2263107F495BAD2001B296C5E9F700A7C9C3C966E507428A8F9D0A55E240F4E30F3E4E6159E464311FFA3DFC418DD8B5F28640E6CA09D8A76207F978038A3E8A14C66A3237F0E099E16965B72573CE9B895622FF7606EE54E51D0D0F470280EDC42C6F6E0E298ACC1F7DCDFE3B1299BE5774C8584C11EDB9A89A7FF3E899CD4A74816EFB2223D520CEEBD82D09F4CE741BBC0E0B0C597C14AE6C29255C8C8A5E89353FC1A7BDBD5E329D4D850DAF65851D23931426FEBBE80217562727A9088697C7EED3153BD9475FB85A4A443A71680C7032ADDD3A03F4B6CEB8FDD75DA0CA9332C6E5CE2AFAE921F98B37FE8A64EBB1AF3F29D1D1DE8F2328F3C8B2D6BB8ABF00DE82CCDAA0156061616163E1AF9B65AB54D07A0D927DA73C9304C214AE7AF00BC57B759DFDD12CC6947423BBFCF51949E19F6C1CD6FB208FF43C8CCC89D132B0EB4A6C66C1F3EBDDAAA553BB328AB0F89C9D0B28A1DBE5D8302A1333120D3BEEF97F0AD01439C4491EE560D05EB79E62D14328BE63C3D8D3B97973FEF44A23F1DCC674A32EC85E2A6837F2782623D09ED658324912498A4AB925BA55CE6AC89FA1C73ADAFC12AB808A25A49F1301EE991316CEE05D92290908DC9C5709CF9912570EB56DE350DB4604C401380B2F1FFC2869409B2C5A9122407F3053
+20220718023518 2 6 100 8191 2 F2F7A2BAF50A41FBCCDE554E561409993B1C6E4133229CAC67C79DE5FEC1F9FBEBECCCE838368FBFA93F774AD02E99F65F8B3F56B3047638FE35167D048A951E3A317CED92846B94A639A0B3D5F098B35BDA8C139A8EB185EC3F843A6778FAB4EEC4DD1B20F071BC9E5075F7AEF1531CC8FB12E64D48A478BBC398D69E12066975EC2A96BCC6D155FB0BDA03C4D4E817DCCF320E8F34447A94C64E28B8F84D07C08BDDA1215CC370EF5EB970A75ED4F8ADB47F36B134A3430DAA59FEF55CD4B9786F693B09BC9C3E6F1F745BABBC6F5892BC4E416BDA02BD59DD7C763179B2897CBCAF284E0A2DE08E4E32BB1F66169D83FA0206C7962184A15527C7CA8EF04AF87921933A2B9C614145AFEC715C833924B8C863E7E20A07AA21A72C450BBC446B9B51407D90261CDE342C5D585A0482DB8FFC95B72992ED5D8085B8A3A8335A1423F7715AB83DB4D88BB599B272B8F80BE3C03B0A3C4F7C2F2486984FE13CA8E4510EA33B45BD782D415AEE1C22885D10BB5D16521E8907054ADE2FA85D8284B89849B05696AC17AD99279CB7675E8261EDFD7CF38B0E714E4C126D13363422B9D1097C590DD4DE80A1CF7872B2D8F6951877EEB91DC4C24F47C9949676565244DB3B923EE368EE43720DC186E96B0B6E0908D967CC5D5C055659978668FCCE03F8D1F087A9EF12446BA87FF4345D757F477C1A838B5EF0A9F45C712A8147A71EA88FBDA3B9A7D1BB5A477A4C224F5F067271E13CBCA9AFBC444FA340B55987BA1D2263107F495BAD2001B296C5E9F700A7C9C3C966E507428A8F9D0A55E240F4E30F3E4E6159E464311FFA3DFC418DD8B5F28640E6CA09D8A76207F978038A3E8A14C66A3237F0E099E16965B72573CE9B895622FF7606EE54E51D0D0F470280EDC42C6F6E0E298ACC1F7DCDFE3B1299BE5774C8584C11EDB9A89A7FF3E899CD4A74816EFB2223D520CEEBD82D09F4CE741BBC0E0B0C597C14AE6C29255C8C8A5E89353FC1A7BDBD5E329D4D850DAF65851D23931426FEBBE80217562727A9088697C7EED3153BD9475FB85A4A443A71680C7032ADDD3A03F4B6CEB8FDD75DA0CA9332C6E5CE2AFAE921F98B37FE8A64EBB1AF3F29D1D1DE8F2328F3C8B2D6BB8ABF00DE82CCDAA0156061616163E1AF9B65AB54D07A0D927DA73C9304C214AE7AF00BC57B759DFDD12CC6947423BBFCF51949E19F6C1CD6FB208FF43C8CCC89D132B0EB4A6C66C1F3EBDDAAA553BB328AB0F89C9D0B28A1DBE5D8302A1333120D3BEEF97F0AD01439C4491EE560D05EB79E62D14328BE63C3D8D3B97973FEF44A23F1DCC674A32EC85E2A6837F2782623D09ED658324912498A4AB925BA55CE6AC89FA1C73ADAFC12AB808A25A49F1301EE991316CEE05D92290908DC9C5709CF9912570EB56DE350DB4604C401380B2F1FFC2869409B2C5A91224CC83943
+20220718024030 2 6 100 8191 5 F2F7A2BAF50A41FBCCDE554E561409993B1C6E4133229CAC67C79DE5FEC1F9FBEBECCCE838368FBFA93F774AD02E99F65F8B3F56B3047638FE35167D048A951E3A317CED92846B94A639A0B3D5F098B35BDA8C139A8EB185EC3F843A6778FAB4EEC4DD1B20F071BC9E5075F7AEF1531CC8FB12E64D48A478BBC398D69E12066975EC2A96BCC6D155FB0BDA03C4D4E817DCCF320E8F34447A94C64E28B8F84D07C08BDDA1215CC370EF5EB970A75ED4F8ADB47F36B134A3430DAA59FEF55CD4B9786F693B09BC9C3E6F1F745BABBC6F5892BC4E416BDA02BD59DD7C763179B2897CBCAF284E0A2DE08E4E32BB1F66169D83FA0206C7962184A15527C7CA8EF04AF87921933A2B9C614145AFEC715C833924B8C863E7E20A07AA21A72C450BBC446B9B51407D90261CDE342C5D585A0482DB8FFC95B72992ED5D8085B8A3A8335A1423F7715AB83DB4D88BB599B272B8F80BE3C03B0A3C4F7C2F2486984FE13CA8E4510EA33B45BD782D415AEE1C22885D10BB5D16521E8907054ADE2FA85D8284B89849B05696AC17AD99279CB7675E8261EDFD7CF38B0E714E4C126D13363422B9D1097C590DD4DE80A1CF7872B2D8F6951877EEB91DC4C24F47C9949676565244DB3B923EE368EE43720DC186E96B0B6E0908D967CC5D5C055659978668FCCE03F8D1F087A9EF12446BA87FF4345D757F477C1A838B5EF0A9F45C712A8147A71EA88FBDA3B9A7D1BB5A477A4C224F5F067271E13CBCA9AFBC444FA340B55987BA1D2263107F495BAD2001B296C5E9F700A7C9C3C966E507428A8F9D0A55E240F4E30F3E4E6159E464311FFA3DFC418DD8B5F28640E6CA09D8A76207F978038A3E8A14C66A3237F0E099E16965B72573CE9B895622FF7606EE54E51D0D0F470280EDC42C6F6E0E298ACC1F7DCDFE3B1299BE5774C8584C11EDB9A89A7FF3E899CD4A74816EFB2223D520CEEBD82D09F4CE741BBC0E0B0C597C14AE6C29255C8C8A5E89353FC1A7BDBD5E329D4D850DAF65851D23931426FEBBE80217562727A9088697C7EED3153BD9475FB85A4A443A71680C7032ADDD3A03F4B6CEB8FDD75DA0CA9332C6E5CE2AFAE921F98B37FE8A64EBB1AF3F29D1D1DE8F2328F3C8B2D6BB8ABF00DE82CCDAA0156061616163E1AF9B65AB54D07A0D927DA73C9304C214AE7AF00BC57B759DFDD12CC6947423BBFCF51949E19F6C1CD6FB208FF43C8CCC89D132B0EB4A6C66C1F3EBDDAAA553BB328AB0F89C9D0B28A1DBE5D8302A1333120D3BEEF97F0AD01439C4491EE560D05EB79E62D14328BE63C3D8D3B97973FEF44A23F1DCC674A32EC85E2A6837F2782623D09ED658324912498A4AB925BA55CE6AC89FA1C73ADAFC12AB808A25A49F1301EE991316CEE05D92290908DC9C5709CF9912570EB56DE350DB4604C401380B2F1FFC2869409B2C5A91224D17A47F
+20220718025313 2 6 100 8191 2 F2F7A2BAF50A41FBCCDE554E561409993B1C6E4133229CAC67C79DE5FEC1F9FBEBECCCE838368FBFA93F774AD02E99F65F8B3F56B3047638FE35167D048A951E3A317CED92846B94A639A0B3D5F098B35BDA8C139A8EB185EC3F843A6778FAB4EEC4DD1B20F071BC9E5075F7AEF1531CC8FB12E64D48A478BBC398D69E12066975EC2A96BCC6D155FB0BDA03C4D4E817DCCF320E8F34447A94C64E28B8F84D07C08BDDA1215CC370EF5EB970A75ED4F8ADB47F36B134A3430DAA59FEF55CD4B9786F693B09BC9C3E6F1F745BABBC6F5892BC4E416BDA02BD59DD7C763179B2897CBCAF284E0A2DE08E4E32BB1F66169D83FA0206C7962184A15527C7CA8EF04AF87921933A2B9C614145AFEC715C833924B8C863E7E20A07AA21A72C450BBC446B9B51407D90261CDE342C5D585A0482DB8FFC95B72992ED5D8085B8A3A8335A1423F7715AB83DB4D88BB599B272B8F80BE3C03B0A3C4F7C2F2486984FE13CA8E4510EA33B45BD782D415AEE1C22885D10BB5D16521E8907054ADE2FA85D8284B89849B05696AC17AD99279CB7675E8261EDFD7CF38B0E714E4C126D13363422B9D1097C590DD4DE80A1CF7872B2D8F6951877EEB91DC4C24F47C9949676565244DB3B923EE368EE43720DC186E96B0B6E0908D967CC5D5C055659978668FCCE03F8D1F087A9EF12446BA87FF4345D757F477C1A838B5EF0A9F45C712A8147A71EA88FBDA3B9A7D1BB5A477A4C224F5F067271E13CBCA9AFBC444FA340B55987BA1D2263107F495BAD2001B296C5E9F700A7C9C3C966E507428A8F9D0A55E240F4E30F3E4E6159E464311FFA3DFC418DD8B5F28640E6CA09D8A76207F978038A3E8A14C66A3237F0E099E16965B72573CE9B895622FF7606EE54E51D0D0F470280EDC42C6F6E0E298ACC1F7DCDFE3B1299BE5774C8584C11EDB9A89A7FF3E899CD4A74816EFB2223D520CEEBD82D09F4CE741BBC0E0B0C597C14AE6C29255C8C8A5E89353FC1A7BDBD5E329D4D850DAF65851D23931426FEBBE80217562727A9088697C7EED3153BD9475FB85A4A443A71680C7032ADDD3A03F4B6CEB8FDD75DA0CA9332C6E5CE2AFAE921F98B37FE8A64EBB1AF3F29D1D1DE8F2328F3C8B2D6BB8ABF00DE82CCDAA0156061616163E1AF9B65AB54D07A0D927DA73C9304C214AE7AF00BC57B759DFDD12CC6947423BBFCF51949E19F6C1CD6FB208FF43C8CCC89D132B0EB4A6C66C1F3EBDDAAA553BB328AB0F89C9D0B28A1DBE5D8302A1333120D3BEEF97F0AD01439C4491EE560D05EB79E62D14328BE63C3D8D3B97973FEF44A23F1DCC674A32EC85E2A6837F2782623D09ED658324912498A4AB925BA55CE6AC89FA1C73ADAFC12AB808A25A49F1301EE991316CEE05D92290908DC9C5709CF9912570EB56DE350DB4604C401380B2F1FFC2869409B2C5A91224DDA8E53
+20220718030104 2 6 100 8191 2 F2F7A2BAF50A41FBCCDE554E561409993B1C6E4133229CAC67C79DE5FEC1F9FBEBECCCE838368FBFA93F774AD02E99F65F8B3F56B3047638FE35167D048A951E3A317CED92846B94A639A0B3D5F098B35BDA8C139A8EB185EC3F843A6778FAB4EEC4DD1B20F071BC9E5075F7AEF1531CC8FB12E64D48A478BBC398D69E12066975EC2A96BCC6D155FB0BDA03C4D4E817DCCF320E8F34447A94C64E28B8F84D07C08BDDA1215CC370EF5EB970A75ED4F8ADB47F36B134A3430DAA59FEF55CD4B9786F693B09BC9C3E6F1F745BABBC6F5892BC4E416BDA02BD59DD7C763179B2897CBCAF284E0A2DE08E4E32BB1F66169D83FA0206C7962184A15527C7CA8EF04AF87921933A2B9C614145AFEC715C833924B8C863E7E20A07AA21A72C450BBC446B9B51407D90261CDE342C5D585A0482DB8FFC95B72992ED5D8085B8A3A8335A1423F7715AB83DB4D88BB599B272B8F80BE3C03B0A3C4F7C2F2486984FE13CA8E4510EA33B45BD782D415AEE1C22885D10BB5D16521E8907054ADE2FA85D8284B89849B05696AC17AD99279CB7675E8261EDFD7CF38B0E714E4C126D13363422B9D1097C590DD4DE80A1CF7872B2D8F6951877EEB91DC4C24F47C9949676565244DB3B923EE368EE43720DC186E96B0B6E0908D967CC5D5C055659978668FCCE03F8D1F087A9EF12446BA87FF4345D757F477C1A838B5EF0A9F45C712A8147A71EA88FBDA3B9A7D1BB5A477A4C224F5F067271E13CBCA9AFBC444FA340B55987BA1D2263107F495BAD2001B296C5E9F700A7C9C3C966E507428A8F9D0A55E240F4E30F3E4E6159E464311FFA3DFC418DD8B5F28640E6CA09D8A76207F978038A3E8A14C66A3237F0E099E16965B72573CE9B895622FF7606EE54E51D0D0F470280EDC42C6F6E0E298ACC1F7DCDFE3B1299BE5774C8584C11EDB9A89A7FF3E899CD4A74816EFB2223D520CEEBD82D09F4CE741BBC0E0B0C597C14AE6C29255C8C8A5E89353FC1A7BDBD5E329D4D850DAF65851D23931426FEBBE80217562727A9088697C7EED3153BD9475FB85A4A443A71680C7032ADDD3A03F4B6CEB8FDD75DA0CA9332C6E5CE2AFAE921F98B37FE8A64EBB1AF3F29D1D1DE8F2328F3C8B2D6BB8ABF00DE82CCDAA0156061616163E1AF9B65AB54D07A0D927DA73C9304C214AE7AF00BC57B759DFDD12CC6947423BBFCF51949E19F6C1CD6FB208FF43C8CCC89D132B0EB4A6C66C1F3EBDDAAA553BB328AB0F89C9D0B28A1DBE5D8302A1333120D3BEEF97F0AD01439C4491EE560D05EB79E62D14328BE63C3D8D3B97973FEF44A23F1DCC674A32EC85E2A6837F2782623D09ED658324912498A4AB925BA55CE6AC89FA1C73ADAFC12AB808A25A49F1301EE991316CEE05D92290908DC9C5709CF9912570EB56DE350DB4604C401380B2F1FFC2869409B2C5A91224E4FCCC3
+20220718035055 2 6 100 8191 2 F2F7A2BAF50A41FBCCDE554E561409993B1C6E4133229CAC67C79DE5FEC1F9FBEBECCCE838368FBFA93F774AD02E99F65F8B3F56B3047638FE35167D048A951E3A317CED92846B94A639A0B3D5F098B35BDA8C139A8EB185EC3F843A6778FAB4EEC4DD1B20F071BC9E5075F7AEF1531CC8FB12E64D48A478BBC398D69E12066975EC2A96BCC6D155FB0BDA03C4D4E817DCCF320E8F34447A94C64E28B8F84D07C08BDDA1215CC370EF5EB970A75ED4F8ADB47F36B134A3430DAA59FEF55CD4B9786F693B09BC9C3E6F1F745BABBC6F5892BC4E416BDA02BD59DD7C763179B2897CBCAF284E0A2DE08E4E32BB1F66169D83FA0206C7962184A15527C7CA8EF04AF87921933A2B9C614145AFEC715C833924B8C863E7E20A07AA21A72C450BBC446B9B51407D90261CDE342C5D585A0482DB8FFC95B72992ED5D8085B8A3A8335A1423F7715AB83DB4D88BB599B272B8F80BE3C03B0A3C4F7C2F2486984FE13CA8E4510EA33B45BD782D415AEE1C22885D10BB5D16521E8907054ADE2FA85D8284B89849B05696AC17AD99279CB7675E8261EDFD7CF38B0E714E4C126D13363422B9D1097C590DD4DE80A1CF7872B2D8F6951877EEB91DC4C24F47C9949676565244DB3B923EE368EE43720DC186E96B0B6E0908D967CC5D5C055659978668FCCE03F8D1F087A9EF12446BA87FF4345D757F477C1A838B5EF0A9F45C712A8147A71EA88FBDA3B9A7D1BB5A477A4C224F5F067271E13CBCA9AFBC444FA340B55987BA1D2263107F495BAD2001B296C5E9F700A7C9C3C966E507428A8F9D0A55E240F4E30F3E4E6159E464311FFA3DFC418DD8B5F28640E6CA09D8A76207F978038A3E8A14C66A3237F0E099E16965B72573CE9B895622FF7606EE54E51D0D0F470280EDC42C6F6E0E298ACC1F7DCDFE3B1299BE5774C8584C11EDB9A89A7FF3E899CD4A74816EFB2223D520CEEBD82D09F4CE741BBC0E0B0C597C14AE6C29255C8C8A5E89353FC1A7BDBD5E329D4D850DAF65851D23931426FEBBE80217562727A9088697C7EED3153BD9475FB85A4A443A71680C7032ADDD3A03F4B6CEB8FDD75DA0CA9332C6E5CE2AFAE921F98B37FE8A64EBB1AF3F29D1D1DE8F2328F3C8B2D6BB8ABF00DE82CCDAA0156061616163E1AF9B65AB54D07A0D927DA73C9304C214AE7AF00BC57B759DFDD12CC6947423BBFCF51949E19F6C1CD6FB208FF43C8CCC89D132B0EB4A6C66C1F3EBDDAAA553BB328AB0F89C9D0B28A1DBE5D8302A1333120D3BEEF97F0AD01439C4491EE560D05EB79E62D14328BE63C3D8D3B97973FEF44A23F1DCC674A32EC85E2A6837F2782623D09ED658324912498A4AB925BA55CE6AC89FA1C73ADAFC12AB808A25A49F1301EE991316CEE05D92290908DC9C5709CF9912570EB56DE350DB4604C401380B2F1FFC2869409B2C5A9122514E0C5B
+20220718042416 2 6 100 8191 2 F2F7A2BAF50A41FBCCDE554E561409993B1C6E4133229CAC67C79DE5FEC1F9FBEBECCCE838368FBFA93F774AD02E99F65F8B3F56B3047638FE35167D048A951E3A317CED92846B94A639A0B3D5F098B35BDA8C139A8EB185EC3F843A6778FAB4EEC4DD1B20F071BC9E5075F7AEF1531CC8FB12E64D48A478BBC398D69E12066975EC2A96BCC6D155FB0BDA03C4D4E817DCCF320E8F34447A94C64E28B8F84D07C08BDDA1215CC370EF5EB970A75ED4F8ADB47F36B134A3430DAA59FEF55CD4B9786F693B09BC9C3E6F1F745BABBC6F5892BC4E416BDA02BD59DD7C763179B2897CBCAF284E0A2DE08E4E32BB1F66169D83FA0206C7962184A15527C7CA8EF04AF87921933A2B9C614145AFEC715C833924B8C863E7E20A07AA21A72C450BBC446B9B51407D90261CDE342C5D585A0482DB8FFC95B72992ED5D8085B8A3A8335A1423F7715AB83DB4D88BB599B272B8F80BE3C03B0A3C4F7C2F2486984FE13CA8E4510EA33B45BD782D415AEE1C22885D10BB5D16521E8907054ADE2FA85D8284B89849B05696AC17AD99279CB7675E8261EDFD7CF38B0E714E4C126D13363422B9D1097C590DD4DE80A1CF7872B2D8F6951877EEB91DC4C24F47C9949676565244DB3B923EE368EE43720DC186E96B0B6E0908D967CC5D5C055659978668FCCE03F8D1F087A9EF12446BA87FF4345D757F477C1A838B5EF0A9F45C712A8147A71EA88FBDA3B9A7D1BB5A477A4C224F5F067271E13CBCA9AFBC444FA340B55987BA1D2263107F495BAD2001B296C5E9F700A7C9C3C966E507428A8F9D0A55E240F4E30F3E4E6159E464311FFA3DFC418DD8B5F28640E6CA09D8A76207F978038A3E8A14C66A3237F0E099E16965B72573CE9B895622FF7606EE54E51D0D0F470280EDC42C6F6E0E298ACC1F7DCDFE3B1299BE5774C8584C11EDB9A89A7FF3E899CD4A74816EFB2223D520CEEBD82D09F4CE741BBC0E0B0C597C14AE6C29255C8C8A5E89353FC1A7BDBD5E329D4D850DAF65851D23931426FEBBE80217562727A9088697C7EED3153BD9475FB85A4A443A71680C7032ADDD3A03F4B6CEB8FDD75DA0CA9332C6E5CE2AFAE921F98B37FE8A64EBB1AF3F29D1D1DE8F2328F3C8B2D6BB8ABF00DE82CCDAA0156061616163E1AF9B65AB54D07A0D927DA73C9304C214AE7AF00BC57B759DFDD12CC6947423BBFCF51949E19F6C1CD6FB208FF43C8CCC89D132B0EB4A6C66C1F3EBDDAAA553BB328AB0F89C9D0B28A1DBE5D8302A1333120D3BEEF97F0AD01439C4491EE560D05EB79E62D14328BE63C3D8D3B97973FEF44A23F1DCC674A32EC85E2A6837F2782623D09ED658324912498A4AB925BA55CE6AC89FA1C73ADAFC12AB808A25A49F1301EE991316CEE05D92290908DC9C5709CF9912570EB56DE350DB4604C401380B2F1FFC2869409B2C5A91225341AD73
+20220718044525 2 6 100 8191 2 F2F7A2BAF50A41FBCCDE554E561409993B1C6E4133229CAC67C79DE5FEC1F9FBEBECCCE838368FBFA93F774AD02E99F65F8B3F56B3047638FE35167D048A951E3A317CED92846B94A639A0B3D5F098B35BDA8C139A8EB185EC3F843A6778FAB4EEC4DD1B20F071BC9E5075F7AEF1531CC8FB12E64D48A478BBC398D69E12066975EC2A96BCC6D155FB0BDA03C4D4E817DCCF320E8F34447A94C64E28B8F84D07C08BDDA1215CC370EF5EB970A75ED4F8ADB47F36B134A3430DAA59FEF55CD4B9786F693B09BC9C3E6F1F745BABBC6F5892BC4E416BDA02BD59DD7C763179B2897CBCAF284E0A2DE08E4E32BB1F66169D83FA0206C7962184A15527C7CA8EF04AF87921933A2B9C614145AFEC715C833924B8C863E7E20A07AA21A72C450BBC446B9B51407D90261CDE342C5D585A0482DB8FFC95B72992ED5D8085B8A3A8335A1423F7715AB83DB4D88BB599B272B8F80BE3C03B0A3C4F7C2F2486984FE13CA8E4510EA33B45BD782D415AEE1C22885D10BB5D16521E8907054ADE2FA85D8284B89849B05696AC17AD99279CB7675E8261EDFD7CF38B0E714E4C126D13363422B9D1097C590DD4DE80A1CF7872B2D8F6951877EEB91DC4C24F47C9949676565244DB3B923EE368EE43720DC186E96B0B6E0908D967CC5D5C055659978668FCCE03F8D1F087A9EF12446BA87FF4345D757F477C1A838B5EF0A9F45C712A8147A71EA88FBDA3B9A7D1BB5A477A4C224F5F067271E13CBCA9AFBC444FA340B55987BA1D2263107F495BAD2001B296C5E9F700A7C9C3C966E507428A8F9D0A55E240F4E30F3E4E6159E464311FFA3DFC418DD8B5F28640E6CA09D8A76207F978038A3E8A14C66A3237F0E099E16965B72573CE9B895622FF7606EE54E51D0D0F470280EDC42C6F6E0E298ACC1F7DCDFE3B1299BE5774C8584C11EDB9A89A7FF3E899CD4A74816EFB2223D520CEEBD82D09F4CE741BBC0E0B0C597C14AE6C29255C8C8A5E89353FC1A7BDBD5E329D4D850DAF65851D23931426FEBBE80217562727A9088697C7EED3153BD9475FB85A4A443A71680C7032ADDD3A03F4B6CEB8FDD75DA0CA9332C6E5CE2AFAE921F98B37FE8A64EBB1AF3F29D1D1DE8F2328F3C8B2D6BB8ABF00DE82CCDAA0156061616163E1AF9B65AB54D07A0D927DA73C9304C214AE7AF00BC57B759DFDD12CC6947423BBFCF51949E19F6C1CD6FB208FF43C8CCC89D132B0EB4A6C66C1F3EBDDAAA553BB328AB0F89C9D0B28A1DBE5D8302A1333120D3BEEF97F0AD01439C4491EE560D05EB79E62D14328BE63C3D8D3B97973FEF44A23F1DCC674A32EC85E2A6837F2782623D09ED658324912498A4AB925BA55CE6AC89FA1C73ADAFC12AB808A25A49F1301EE991316CEE05D92290908DC9C5709CF9912570EB56DE350DB4604C401380B2F1FFC2869409B2C5A91225482241B
+20220718061152 2 6 100 8191 5 F2F7A2BAF50A41FBCCDE554E561409993B1C6E4133229CAC67C79DE5FEC1F9FBEBECCCE838368FBFA93F774AD02E99F65F8B3F56B3047638FE35167D048A951E3A317CED92846B94A639A0B3D5F098B35BDA8C139A8EB185EC3F843A6778FAB4EEC4DD1B20F071BC9E5075F7AEF1531CC8FB12E64D48A478BBC398D69E12066975EC2A96BCC6D155FB0BDA03C4D4E817DCCF320E8F34447A94C64E28B8F84D07C08BDDA1215CC370EF5EB970A75ED4F8ADB47F36B134A3430DAA59FEF55CD4B9786F693B09BC9C3E6F1F745BABBC6F5892BC4E416BDA02BD59DD7C763179B2897CBCAF284E0A2DE08E4E32BB1F66169D83FA0206C7962184A15527C7CA8EF04AF87921933A2B9C614145AFEC715C833924B8C863E7E20A07AA21A72C450BBC446B9B51407D90261CDE342C5D585A0482DB8FFC95B72992ED5D8085B8A3A8335A1423F7715AB83DB4D88BB599B272B8F80BE3C03B0A3C4F7C2F2486984FE13CA8E4510EA33B45BD782D415AEE1C22885D10BB5D16521E8907054ADE2FA85D8284B89849B05696AC17AD99279CB7675E8261EDFD7CF38B0E714E4C126D13363422B9D1097C590DD4DE80A1CF7872B2D8F6951877EEB91DC4C24F47C9949676565244DB3B923EE368EE43720DC186E96B0B6E0908D967CC5D5C055659978668FCCE03F8D1F087A9EF12446BA87FF4345D757F477C1A838B5EF0A9F45C712A8147A71EA88FBDA3B9A7D1BB5A477A4C224F5F067271E13CBCA9AFBC444FA340B55987BA1D2263107F495BAD2001B296C5E9F700A7C9C3C966E507428A8F9D0A55E240F4E30F3E4E6159E464311FFA3DFC418DD8B5F28640E6CA09D8A76207F978038A3E8A14C66A3237F0E099E16965B72573CE9B895622FF7606EE54E51D0D0F470280EDC42C6F6E0E298ACC1F7DCDFE3B1299BE5774C8584C11EDB9A89A7FF3E899CD4A74816EFB2223D520CEEBD82D09F4CE741BBC0E0B0C597C14AE6C29255C8C8A5E89353FC1A7BDBD5E329D4D850DAF65851D23931426FEBBE80217562727A9088697C7EED3153BD9475FB85A4A443A71680C7032ADDD3A03F4B6CEB8FDD75DA0CA9332C6E5CE2AFAE921F98B37FE8A64EBB1AF3F29D1D1DE8F2328F3C8B2D6BB8ABF00DE82CCDAA0156061616163E1AF9B65AB54D07A0D927DA73C9304C214AE7AF00BC57B759DFDD12CC6947423BBFCF51949E19F6C1CD6FB208FF43C8CCC89D132B0EB4A6C66C1F3EBDDAAA553BB328AB0F89C9D0B28A1DBE5D8302A1333120D3BEEF97F0AD01439C4491EE560D05EB79E62D14328BE63C3D8D3B97973FEF44A23F1DCC674A32EC85E2A6837F2782623D09ED658324912498A4AB925BA55CE6AC89FA1C73ADAFC12AB808A25A49F1301EE991316CEE05D92290908DC9C5709CF9912570EB56DE350DB4604C401380B2F1FFC2869409B2C5A91225999F347
+20220718061417 2 6 100 8191 2 F2F7A2BAF50A41FBCCDE554E561409993B1C6E4133229CAC67C79DE5FEC1F9FBEBECCCE838368FBFA93F774AD02E99F65F8B3F56B3047638FE35167D048A951E3A317CED92846B94A639A0B3D5F098B35BDA8C139A8EB185EC3F843A6778FAB4EEC4DD1B20F071BC9E5075F7AEF1531CC8FB12E64D48A478BBC398D69E12066975EC2A96BCC6D155FB0BDA03C4D4E817DCCF320E8F34447A94C64E28B8F84D07C08BDDA1215CC370EF5EB970A75ED4F8ADB47F36B134A3430DAA59FEF55CD4B9786F693B09BC9C3E6F1F745BABBC6F5892BC4E416BDA02BD59DD7C763179B2897CBCAF284E0A2DE08E4E32BB1F66169D83FA0206C7962184A15527C7CA8EF04AF87921933A2B9C614145AFEC715C833924B8C863E7E20A07AA21A72C450BBC446B9B51407D90261CDE342C5D585A0482DB8FFC95B72992ED5D8085B8A3A8335A1423F7715AB83DB4D88BB599B272B8F80BE3C03B0A3C4F7C2F2486984FE13CA8E4510EA33B45BD782D415AEE1C22885D10BB5D16521E8907054ADE2FA85D8284B89849B05696AC17AD99279CB7675E8261EDFD7CF38B0E714E4C126D13363422B9D1097C590DD4DE80A1CF7872B2D8F6951877EEB91DC4C24F47C9949676565244DB3B923EE368EE43720DC186E96B0B6E0908D967CC5D5C055659978668FCCE03F8D1F087A9EF12446BA87FF4345D757F477C1A838B5EF0A9F45C712A8147A71EA88FBDA3B9A7D1BB5A477A4C224F5F067271E13CBCA9AFBC444FA340B55987BA1D2263107F495BAD2001B296C5E9F700A7C9C3C966E507428A8F9D0A55E240F4E30F3E4E6159E464311FFA3DFC418DD8B5F28640E6CA09D8A76207F978038A3E8A14C66A3237F0E099E16965B72573CE9B895622FF7606EE54E51D0D0F470280EDC42C6F6E0E298ACC1F7DCDFE3B1299BE5774C8584C11EDB9A89A7FF3E899CD4A74816EFB2223D520CEEBD82D09F4CE741BBC0E0B0C597C14AE6C29255C8C8A5E89353FC1A7BDBD5E329D4D850DAF65851D23931426FEBBE80217562727A9088697C7EED3153BD9475FB85A4A443A71680C7032ADDD3A03F4B6CEB8FDD75DA0CA9332C6E5CE2AFAE921F98B37FE8A64EBB1AF3F29D1D1DE8F2328F3C8B2D6BB8ABF00DE82CCDAA0156061616163E1AF9B65AB54D07A0D927DA73C9304C214AE7AF00BC57B759DFDD12CC6947423BBFCF51949E19F6C1CD6FB208FF43C8CCC89D132B0EB4A6C66C1F3EBDDAAA553BB328AB0F89C9D0B28A1DBE5D8302A1333120D3BEEF97F0AD01439C4491EE560D05EB79E62D14328BE63C3D8D3B97973FEF44A23F1DCC674A32EC85E2A6837F2782623D09ED658324912498A4AB925BA55CE6AC89FA1C73ADAFC12AB808A25A49F1301EE991316CEE05D92290908DC9C5709CF9912570EB56DE350DB4604C401380B2F1FFC2869409B2C5A912259BDFF6B
+20220718064948 2 6 100 8191 2 F2F7A2BAF50A41FBCCDE554E561409993B1C6E4133229CAC67C79DE5FEC1F9FBEBECCCE838368FBFA93F774AD02E99F65F8B3F56B3047638FE35167D048A951E3A317CED92846B94A639A0B3D5F098B35BDA8C139A8EB185EC3F843A6778FAB4EEC4DD1B20F071BC9E5075F7AEF1531CC8FB12E64D48A478BBC398D69E12066975EC2A96BCC6D155FB0BDA03C4D4E817DCCF320E8F34447A94C64E28B8F84D07C08BDDA1215CC370EF5EB970A75ED4F8ADB47F36B134A3430DAA59FEF55CD4B9786F693B09BC9C3E6F1F745BABBC6F5892BC4E416BDA02BD59DD7C763179B2897CBCAF284E0A2DE08E4E32BB1F66169D83FA0206C7962184A15527C7CA8EF04AF87921933A2B9C614145AFEC715C833924B8C863E7E20A07AA21A72C450BBC446B9B51407D90261CDE342C5D585A0482DB8FFC95B72992ED5D8085B8A3A8335A1423F7715AB83DB4D88BB599B272B8F80BE3C03B0A3C4F7C2F2486984FE13CA8E4510EA33B45BD782D415AEE1C22885D10BB5D16521E8907054ADE2FA85D8284B89849B05696AC17AD99279CB7675E8261EDFD7CF38B0E714E4C126D13363422B9D1097C590DD4DE80A1CF7872B2D8F6951877EEB91DC4C24F47C9949676565244DB3B923EE368EE43720DC186E96B0B6E0908D967CC5D5C055659978668FCCE03F8D1F087A9EF12446BA87FF4345D757F477C1A838B5EF0A9F45C712A8147A71EA88FBDA3B9A7D1BB5A477A4C224F5F067271E13CBCA9AFBC444FA340B55987BA1D2263107F495BAD2001B296C5E9F700A7C9C3C966E507428A8F9D0A55E240F4E30F3E4E6159E464311FFA3DFC418DD8B5F28640E6CA09D8A76207F978038A3E8A14C66A3237F0E099E16965B72573CE9B895622FF7606EE54E51D0D0F470280EDC42C6F6E0E298ACC1F7DCDFE3B1299BE5774C8584C11EDB9A89A7FF3E899CD4A74816EFB2223D520CEEBD82D09F4CE741BBC0E0B0C597C14AE6C29255C8C8A5E89353FC1A7BDBD5E329D4D850DAF65851D23931426FEBBE80217562727A9088697C7EED3153BD9475FB85A4A443A71680C7032ADDD3A03F4B6CEB8FDD75DA0CA9332C6E5CE2AFAE921F98B37FE8A64EBB1AF3F29D1D1DE8F2328F3C8B2D6BB8ABF00DE82CCDAA0156061616163E1AF9B65AB54D07A0D927DA73C9304C214AE7AF00BC57B759DFDD12CC6947423BBFCF51949E19F6C1CD6FB208FF43C8CCC89D132B0EB4A6C66C1F3EBDDAAA553BB328AB0F89C9D0B28A1DBE5D8302A1333120D3BEEF97F0AD01439C4491EE560D05EB79E62D14328BE63C3D8D3B97973FEF44A23F1DCC674A32EC85E2A6837F2782623D09ED658324912498A4AB925BA55CE6AC89FA1C73ADAFC12AB808A25A49F1301EE991316CEE05D92290908DC9C5709CF9912570EB56DE350DB4604C401380B2F1FFC2869409B2C5A91225BD2B193
+20220718080208 2 6 100 8191 2 F2F7A2BAF50A41FBCCDE554E561409993B1C6E4133229CAC67C79DE5FEC1F9FBEBECCCE838368FBFA93F774AD02E99F65F8B3F56B3047638FE35167D048A951E3A317CED92846B94A639A0B3D5F098B35BDA8C139A8EB185EC3F843A6778FAB4EEC4DD1B20F071BC9E5075F7AEF1531CC8FB12E64D48A478BBC398D69E12066975EC2A96BCC6D155FB0BDA03C4D4E817DCCF320E8F34447A94C64E28B8F84D07C08BDDA1215CC370EF5EB970A75ED4F8ADB47F36B134A3430DAA59FEF55CD4B9786F693B09BC9C3E6F1F745BABBC6F5892BC4E416BDA02BD59DD7C763179B2897CBCAF284E0A2DE08E4E32BB1F66169D83FA0206C7962184A15527C7CA8EF04AF87921933A2B9C614145AFEC715C833924B8C863E7E20A07AA21A72C450BBC446B9B51407D90261CDE342C5D585A0482DB8FFC95B72992ED5D8085B8A3A8335A1423F7715AB83DB4D88BB599B272B8F80BE3C03B0A3C4F7C2F2486984FE13CA8E4510EA33B45BD782D415AEE1C22885D10BB5D16521E8907054ADE2FA85D8284B89849B05696AC17AD99279CB7675E8261EDFD7CF38B0E714E4C126D13363422B9D1097C590DD4DE80A1CF7872B2D8F6951877EEB91DC4C24F47C9949676565244DB3B923EE368EE43720DC186E96B0B6E0908D967CC5D5C055659978668FCCE03F8D1F087A9EF12446BA87FF4345D757F477C1A838B5EF0A9F45C712A8147A71EA88FBDA3B9A7D1BB5A477A4C224F5F067271E13CBCA9AFBC444FA340B55987BA1D2263107F495BAD2001B296C5E9F700A7C9C3C966E507428A8F9D0A55E240F4E30F3E4E6159E464311FFA3DFC418DD8B5F28640E6CA09D8A76207F978038A3E8A14C66A3237F0E099E16965B72573CE9B895622FF7606EE54E51D0D0F470280EDC42C6F6E0E298ACC1F7DCDFE3B1299BE5774C8584C11EDB9A89A7FF3E899CD4A74816EFB2223D520CEEBD82D09F4CE741BBC0E0B0C597C14AE6C29255C8C8A5E89353FC1A7BDBD5E329D4D850DAF65851D23931426FEBBE80217562727A9088697C7EED3153BD9475FB85A4A443A71680C7032ADDD3A03F4B6CEB8FDD75DA0CA9332C6E5CE2AFAE921F98B37FE8A64EBB1AF3F29D1D1DE8F2328F3C8B2D6BB8ABF00DE82CCDAA0156061616163E1AF9B65AB54D07A0D927DA73C9304C214AE7AF00BC57B759DFDD12CC6947423BBFCF51949E19F6C1CD6FB208FF43C8CCC89D132B0EB4A6C66C1F3EBDDAAA553BB328AB0F89C9D0B28A1DBE5D8302A1333120D3BEEF97F0AD01439C4491EE560D05EB79E62D14328BE63C3D8D3B97973FEF44A23F1DCC674A32EC85E2A6837F2782623D09ED658324912498A4AB925BA55CE6AC89FA1C73ADAFC12AB808A25A49F1301EE991316CEE05D92290908DC9C5709CF9912570EB56DE350DB4604C401380B2F1FFC2869409B2C5A9122602EE1DB
+20220718090911 2 6 100 8191 5 F2F7A2BAF50A41FBCCDE554E561409993B1C6E4133229CAC67C79DE5FEC1F9FBEBECCCE838368FBFA93F774AD02E99F65F8B3F56B3047638FE35167D048A951E3A317CED92846B94A639A0B3D5F098B35BDA8C139A8EB185EC3F843A6778FAB4EEC4DD1B20F071BC9E5075F7AEF1531CC8FB12E64D48A478BBC398D69E12066975EC2A96BCC6D155FB0BDA03C4D4E817DCCF320E8F34447A94C64E28B8F84D07C08BDDA1215CC370EF5EB970A75ED4F8ADB47F36B134A3430DAA59FEF55CD4B9786F693B09BC9C3E6F1F745BABBC6F5892BC4E416BDA02BD59DD7C763179B2897CBCAF284E0A2DE08E4E32BB1F66169D83FA0206C7962184A15527C7CA8EF04AF87921933A2B9C614145AFEC715C833924B8C863E7E20A07AA21A72C450BBC446B9B51407D90261CDE342C5D585A0482DB8FFC95B72992ED5D8085B8A3A8335A1423F7715AB83DB4D88BB599B272B8F80BE3C03B0A3C4F7C2F2486984FE13CA8E4510EA33B45BD782D415AEE1C22885D10BB5D16521E8907054ADE2FA85D8284B89849B05696AC17AD99279CB7675E8261EDFD7CF38B0E714E4C126D13363422B9D1097C590DD4DE80A1CF7872B2D8F6951877EEB91DC4C24F47C9949676565244DB3B923EE368EE43720DC186E96B0B6E0908D967CC5D5C055659978668FCCE03F8D1F087A9EF12446BA87FF4345D757F477C1A838B5EF0A9F45C712A8147A71EA88FBDA3B9A7D1BB5A477A4C224F5F067271E13CBCA9AFBC444FA340B55987BA1D2263107F495BAD2001B296C5E9F700A7C9C3C966E507428A8F9D0A55E240F4E30F3E4E6159E464311FFA3DFC418DD8B5F28640E6CA09D8A76207F978038A3E8A14C66A3237F0E099E16965B72573CE9B895622FF7606EE54E51D0D0F470280EDC42C6F6E0E298ACC1F7DCDFE3B1299BE5774C8584C11EDB9A89A7FF3E899CD4A74816EFB2223D520CEEBD82D09F4CE741BBC0E0B0C597C14AE6C29255C8C8A5E89353FC1A7BDBD5E329D4D850DAF65851D23931426FEBBE80217562727A9088697C7EED3153BD9475FB85A4A443A71680C7032ADDD3A03F4B6CEB8FDD75DA0CA9332C6E5CE2AFAE921F98B37FE8A64EBB1AF3F29D1D1DE8F2328F3C8B2D6BB8ABF00DE82CCDAA0156061616163E1AF9B65AB54D07A0D927DA73C9304C214AE7AF00BC57B759DFDD12CC6947423BBFCF51949E19F6C1CD6FB208FF43C8CCC89D132B0EB4A6C66C1F3EBDDAAA553BB328AB0F89C9D0B28A1DBE5D8302A1333120D3BEEF97F0AD01439C4491EE560D05EB79E62D14328BE63C3D8D3B97973FEF44A23F1DCC674A32EC85E2A6837F2782623D09ED658324912498A4AB925BA55CE6AC89FA1C73ADAFC12AB808A25A49F1301EE991316CEE05D92290908DC9C5709CF9912570EB56DE350DB4604C401380B2F1FFC2869409B2C5A912264269067
+20220718102418 2 6 100 8191 5 F2F7A2BAF50A41FBCCDE554E561409993B1C6E4133229CAC67C79DE5FEC1F9FBEBECCCE838368FBFA93F774AD02E99F65F8B3F56B3047638FE35167D048A951E3A317CED92846B94A639A0B3D5F098B35BDA8C139A8EB185EC3F843A6778FAB4EEC4DD1B20F071BC9E5075F7AEF1531CC8FB12E64D48A478BBC398D69E12066975EC2A96BCC6D155FB0BDA03C4D4E817DCCF320E8F34447A94C64E28B8F84D07C08BDDA1215CC370EF5EB970A75ED4F8ADB47F36B134A3430DAA59FEF55CD4B9786F693B09BC9C3E6F1F745BABBC6F5892BC4E416BDA02BD59DD7C763179B2897CBCAF284E0A2DE08E4E32BB1F66169D83FA0206C7962184A15527C7CA8EF04AF87921933A2B9C614145AFEC715C833924B8C863E7E20A07AA21A72C450BBC446B9B51407D90261CDE342C5D585A0482DB8FFC95B72992ED5D8085B8A3A8335A1423F7715AB83DB4D88BB599B272B8F80BE3C03B0A3C4F7C2F2486984FE13CA8E4510EA33B45BD782D415AEE1C22885D10BB5D16521E8907054ADE2FA85D8284B89849B05696AC17AD99279CB7675E8261EDFD7CF38B0E714E4C126D13363422B9D1097C590DD4DE80A1CF7872B2D8F6951877EEB91DC4C24F47C9949676565244DB3B923EE368EE43720DC186E96B0B6E0908D967CC5D5C055659978668FCCE03F8D1F087A9EF12446BA87FF4345D757F477C1A838B5EF0A9F45C712A8147A71EA88FBDA3B9A7D1BB5A477A4C224F5F067271E13CBCA9AFBC444FA340B55987BA1D2263107F495BAD2001B296C5E9F700A7C9C3C966E507428A8F9D0A55E240F4E30F3E4E6159E464311FFA3DFC418DD8B5F28640E6CA09D8A76207F978038A3E8A14C66A3237F0E099E16965B72573CE9B895622FF7606EE54E51D0D0F470280EDC42C6F6E0E298ACC1F7DCDFE3B1299BE5774C8584C11EDB9A89A7FF3E899CD4A74816EFB2223D520CEEBD82D09F4CE741BBC0E0B0C597C14AE6C29255C8C8A5E89353FC1A7BDBD5E329D4D850DAF65851D23931426FEBBE80217562727A9088697C7EED3153BD9475FB85A4A443A71680C7032ADDD3A03F4B6CEB8FDD75DA0CA9332C6E5CE2AFAE921F98B37FE8A64EBB1AF3F29D1D1DE8F2328F3C8B2D6BB8ABF00DE82CCDAA0156061616163E1AF9B65AB54D07A0D927DA73C9304C214AE7AF00BC57B759DFDD12CC6947423BBFCF51949E19F6C1CD6FB208FF43C8CCC89D132B0EB4A6C66C1F3EBDDAAA553BB328AB0F89C9D0B28A1DBE5D8302A1333120D3BEEF97F0AD01439C4491EE560D05EB79E62D14328BE63C3D8D3B97973FEF44A23F1DCC674A32EC85E2A6837F2782623D09ED658324912498A4AB925BA55CE6AC89FA1C73ADAFC12AB808A25A49F1301EE991316CEE05D92290908DC9C5709CF9912570EB56DE350DB4604C401380B2F1FFC2869409B2C5A912268ABA127
+20220718112555 2 6 100 8191 5 F2F7A2BAF50A41FBCCDE554E561409993B1C6E4133229CAC67C79DE5FEC1F9FBEBECCCE838368FBFA93F774AD02E99F65F8B3F56B3047638FE35167D048A951E3A317CED92846B94A639A0B3D5F098B35BDA8C139A8EB185EC3F843A6778FAB4EEC4DD1B20F071BC9E5075F7AEF1531CC8FB12E64D48A478BBC398D69E12066975EC2A96BCC6D155FB0BDA03C4D4E817DCCF320E8F34447A94C64E28B8F84D07C08BDDA1215CC370EF5EB970A75ED4F8ADB47F36B134A3430DAA59FEF55CD4B9786F693B09BC9C3E6F1F745BABBC6F5892BC4E416BDA02BD59DD7C763179B2897CBCAF284E0A2DE08E4E32BB1F66169D83FA0206C7962184A15527C7CA8EF04AF87921933A2B9C614145AFEC715C833924B8C863E7E20A07AA21A72C450BBC446B9B51407D90261CDE342C5D585A0482DB8FFC95B72992ED5D8085B8A3A8335A1423F7715AB83DB4D88BB599B272B8F80BE3C03B0A3C4F7C2F2486984FE13CA8E4510EA33B45BD782D415AEE1C22885D10BB5D16521E8907054ADE2FA85D8284B89849B05696AC17AD99279CB7675E8261EDFD7CF38B0E714E4C126D13363422B9D1097C590DD4DE80A1CF7872B2D8F6951877EEB91DC4C24F47C9949676565244DB3B923EE368EE43720DC186E96B0B6E0908D967CC5D5C055659978668FCCE03F8D1F087A9EF12446BA87FF4345D757F477C1A838B5EF0A9F45C712A8147A71EA88FBDA3B9A7D1BB5A477A4C224F5F067271E13CBCA9AFBC444FA340B55987BA1D2263107F495BAD2001B296C5E9F700A7C9C3C966E507428A8F9D0A55E240F4E30F3E4E6159E464311FFA3DFC418DD8B5F28640E6CA09D8A76207F978038A3E8A14C66A3237F0E099E16965B72573CE9B895622FF7606EE54E51D0D0F470280EDC42C6F6E0E298ACC1F7DCDFE3B1299BE5774C8584C11EDB9A89A7FF3E899CD4A74816EFB2223D520CEEBD82D09F4CE741BBC0E0B0C597C14AE6C29255C8C8A5E89353FC1A7BDBD5E329D4D850DAF65851D23931426FEBBE80217562727A9088697C7EED3153BD9475FB85A4A443A71680C7032ADDD3A03F4B6CEB8FDD75DA0CA9332C6E5CE2AFAE921F98B37FE8A64EBB1AF3F29D1D1DE8F2328F3C8B2D6BB8ABF00DE82CCDAA0156061616163E1AF9B65AB54D07A0D927DA73C9304C214AE7AF00BC57B759DFDD12CC6947423BBFCF51949E19F6C1CD6FB208FF43C8CCC89D132B0EB4A6C66C1F3EBDDAAA553BB328AB0F89C9D0B28A1DBE5D8302A1333120D3BEEF97F0AD01439C4491EE560D05EB79E62D14328BE63C3D8D3B97973FEF44A23F1DCC674A32EC85E2A6837F2782623D09ED658324912498A4AB925BA55CE6AC89FA1C73ADAFC12AB808A25A49F1301EE991316CEE05D92290908DC9C5709CF9912570EB56DE350DB4604C401380B2F1FFC2869409B2C5A91226C611AC7
+20220718120905 2 6 100 8191 2 F2F7A2BAF50A41FBCCDE554E561409993B1C6E4133229CAC67C79DE5FEC1F9FBEBECCCE838368FBFA93F774AD02E99F65F8B3F56B3047638FE35167D048A951E3A317CED92846B94A639A0B3D5F098B35BDA8C139A8EB185EC3F843A6778FAB4EEC4DD1B20F071BC9E5075F7AEF1531CC8FB12E64D48A478BBC398D69E12066975EC2A96BCC6D155FB0BDA03C4D4E817DCCF320E8F34447A94C64E28B8F84D07C08BDDA1215CC370EF5EB970A75ED4F8ADB47F36B134A3430DAA59FEF55CD4B9786F693B09BC9C3E6F1F745BABBC6F5892BC4E416BDA02BD59DD7C763179B2897CBCAF284E0A2DE08E4E32BB1F66169D83FA0206C7962184A15527C7CA8EF04AF87921933A2B9C614145AFEC715C833924B8C863E7E20A07AA21A72C450BBC446B9B51407D90261CDE342C5D585A0482DB8FFC95B72992ED5D8085B8A3A8335A1423F7715AB83DB4D88BB599B272B8F80BE3C03B0A3C4F7C2F2486984FE13CA8E4510EA33B45BD782D415AEE1C22885D10BB5D16521E8907054ADE2FA85D8284B89849B05696AC17AD99279CB7675E8261EDFD7CF38B0E714E4C126D13363422B9D1097C590DD4DE80A1CF7872B2D8F6951877EEB91DC4C24F47C9949676565244DB3B923EE368EE43720DC186E96B0B6E0908D967CC5D5C055659978668FCCE03F8D1F087A9EF12446BA87FF4345D757F477C1A838B5EF0A9F45C712A8147A71EA88FBDA3B9A7D1BB5A477A4C224F5F067271E13CBCA9AFBC444FA340B55987BA1D2263107F495BAD2001B296C5E9F700A7C9C3C966E507428A8F9D0A55E240F4E30F3E4E6159E464311FFA3DFC418DD8B5F28640E6CA09D8A76207F978038A3E8A14C66A3237F0E099E16965B72573CE9B895622FF7606EE54E51D0D0F470280EDC42C6F6E0E298ACC1F7DCDFE3B1299BE5774C8584C11EDB9A89A7FF3E899CD4A74816EFB2223D520CEEBD82D09F4CE741BBC0E0B0C597C14AE6C29255C8C8A5E89353FC1A7BDBD5E329D4D850DAF65851D23931426FEBBE80217562727A9088697C7EED3153BD9475FB85A4A443A71680C7032ADDD3A03F4B6CEB8FDD75DA0CA9332C6E5CE2AFAE921F98B37FE8A64EBB1AF3F29D1D1DE8F2328F3C8B2D6BB8ABF00DE82CCDAA0156061616163E1AF9B65AB54D07A0D927DA73C9304C214AE7AF00BC57B759DFDD12CC6947423BBFCF51949E19F6C1CD6FB208FF43C8CCC89D132B0EB4A6C66C1F3EBDDAAA553BB328AB0F89C9D0B28A1DBE5D8302A1333120D3BEEF97F0AD01439C4491EE560D05EB79E62D14328BE63C3D8D3B97973FEF44A23F1DCC674A32EC85E2A6837F2782623D09ED658324912498A4AB925BA55CE6AC89FA1C73ADAFC12AB808A25A49F1301EE991316CEE05D92290908DC9C5709CF9912570EB56DE350DB4604C401380B2F1FFC2869409B2C5A91226EEF51AB
+20220718123459 2 6 100 8191 2 F2F7A2BAF50A41FBCCDE554E561409993B1C6E4133229CAC67C79DE5FEC1F9FBEBECCCE838368FBFA93F774AD02E99F65F8B3F56B3047638FE35167D048A951E3A317CED92846B94A639A0B3D5F098B35BDA8C139A8EB185EC3F843A6778FAB4EEC4DD1B20F071BC9E5075F7AEF1531CC8FB12E64D48A478BBC398D69E12066975EC2A96BCC6D155FB0BDA03C4D4E817DCCF320E8F34447A94C64E28B8F84D07C08BDDA1215CC370EF5EB970A75ED4F8ADB47F36B134A3430DAA59FEF55CD4B9786F693B09BC9C3E6F1F745BABBC6F5892BC4E416BDA02BD59DD7C763179B2897CBCAF284E0A2DE08E4E32BB1F66169D83FA0206C7962184A15527C7CA8EF04AF87921933A2B9C614145AFEC715C833924B8C863E7E20A07AA21A72C450BBC446B9B51407D90261CDE342C5D585A0482DB8FFC95B72992ED5D8085B8A3A8335A1423F7715AB83DB4D88BB599B272B8F80BE3C03B0A3C4F7C2F2486984FE13CA8E4510EA33B45BD782D415AEE1C22885D10BB5D16521E8907054ADE2FA85D8284B89849B05696AC17AD99279CB7675E8261EDFD7CF38B0E714E4C126D13363422B9D1097C590DD4DE80A1CF7872B2D8F6951877EEB91DC4C24F47C9949676565244DB3B923EE368EE43720DC186E96B0B6E0908D967CC5D5C055659978668FCCE03F8D1F087A9EF12446BA87FF4345D757F477C1A838B5EF0A9F45C712A8147A71EA88FBDA3B9A7D1BB5A477A4C224F5F067271E13CBCA9AFBC444FA340B55987BA1D2263107F495BAD2001B296C5E9F700A7C9C3C966E507428A8F9D0A55E240F4E30F3E4E6159E464311FFA3DFC418DD8B5F28640E6CA09D8A76207F978038A3E8A14C66A3237F0E099E16965B72573CE9B895622FF7606EE54E51D0D0F470280EDC42C6F6E0E298ACC1F7DCDFE3B1299BE5774C8584C11EDB9A89A7FF3E899CD4A74816EFB2223D520CEEBD82D09F4CE741BBC0E0B0C597C14AE6C29255C8C8A5E89353FC1A7BDBD5E329D4D850DAF65851D23931426FEBBE80217562727A9088697C7EED3153BD9475FB85A4A443A71680C7032ADDD3A03F4B6CEB8FDD75DA0CA9332C6E5CE2AFAE921F98B37FE8A64EBB1AF3F29D1D1DE8F2328F3C8B2D6BB8ABF00DE82CCDAA0156061616163E1AF9B65AB54D07A0D927DA73C9304C214AE7AF00BC57B759DFDD12CC6947423BBFCF51949E19F6C1CD6FB208FF43C8CCC89D132B0EB4A6C66C1F3EBDDAAA553BB328AB0F89C9D0B28A1DBE5D8302A1333120D3BEEF97F0AD01439C4491EE560D05EB79E62D14328BE63C3D8D3B97973FEF44A23F1DCC674A32EC85E2A6837F2782623D09ED658324912498A4AB925BA55CE6AC89FA1C73ADAFC12AB808A25A49F1301EE991316CEE05D92290908DC9C5709CF9912570EB56DE350DB4604C401380B2F1FFC2869409B2C5A91227079AAF3
+20220718132216 2 6 100 8191 5 F2F7A2BAF50A41FBCCDE554E561409993B1C6E4133229CAC67C79DE5FEC1F9FBEBECCCE838368FBFA93F774AD02E99F65F8B3F56B3047638FE35167D048A951E3A317CED92846B94A639A0B3D5F098B35BDA8C139A8EB185EC3F843A6778FAB4EEC4DD1B20F071BC9E5075F7AEF1531CC8FB12E64D48A478BBC398D69E12066975EC2A96BCC6D155FB0BDA03C4D4E817DCCF320E8F34447A94C64E28B8F84D07C08BDDA1215CC370EF5EB970A75ED4F8ADB47F36B134A3430DAA59FEF55CD4B9786F693B09BC9C3E6F1F745BABBC6F5892BC4E416BDA02BD59DD7C763179B2897CBCAF284E0A2DE08E4E32BB1F66169D83FA0206C7962184A15527C7CA8EF04AF87921933A2B9C614145AFEC715C833924B8C863E7E20A07AA21A72C450BBC446B9B51407D90261CDE342C5D585A0482DB8FFC95B72992ED5D8085B8A3A8335A1423F7715AB83DB4D88BB599B272B8F80BE3C03B0A3C4F7C2F2486984FE13CA8E4510EA33B45BD782D415AEE1C22885D10BB5D16521E8907054ADE2FA85D8284B89849B05696AC17AD99279CB7675E8261EDFD7CF38B0E714E4C126D13363422B9D1097C590DD4DE80A1CF7872B2D8F6951877EEB91DC4C24F47C9949676565244DB3B923EE368EE43720DC186E96B0B6E0908D967CC5D5C055659978668FCCE03F8D1F087A9EF12446BA87FF4345D757F477C1A838B5EF0A9F45C712A8147A71EA88FBDA3B9A7D1BB5A477A4C224F5F067271E13CBCA9AFBC444FA340B55987BA1D2263107F495BAD2001B296C5E9F700A7C9C3C966E507428A8F9D0A55E240F4E30F3E4E6159E464311FFA3DFC418DD8B5F28640E6CA09D8A76207F978038A3E8A14C66A3237F0E099E16965B72573CE9B895622FF7606EE54E51D0D0F470280EDC42C6F6E0E298ACC1F7DCDFE3B1299BE5774C8584C11EDB9A89A7FF3E899CD4A74816EFB2223D520CEEBD82D09F4CE741BBC0E0B0C597C14AE6C29255C8C8A5E89353FC1A7BDBD5E329D4D850DAF65851D23931426FEBBE80217562727A9088697C7EED3153BD9475FB85A4A443A71680C7032ADDD3A03F4B6CEB8FDD75DA0CA9332C6E5CE2AFAE921F98B37FE8A64EBB1AF3F29D1D1DE8F2328F3C8B2D6BB8ABF00DE82CCDAA0156061616163E1AF9B65AB54D07A0D927DA73C9304C214AE7AF00BC57B759DFDD12CC6947423BBFCF51949E19F6C1CD6FB208FF43C8CCC89D132B0EB4A6C66C1F3EBDDAAA553BB328AB0F89C9D0B28A1DBE5D8302A1333120D3BEEF97F0AD01439C4491EE560D05EB79E62D14328BE63C3D8D3B97973FEF44A23F1DCC674A32EC85E2A6837F2782623D09ED658324912498A4AB925BA55CE6AC89FA1C73ADAFC12AB808A25A49F1301EE991316CEE05D92290908DC9C5709CF9912570EB56DE350DB4604C401380B2F1FFC2869409B2C5A9122734DC097
+20220718151026 2 6 100 8191 5 F2F7A2BAF50A41FBCCDE554E561409993B1C6E4133229CAC67C79DE5FEC1F9FBEBECCCE838368FBFA93F774AD02E99F65F8B3F56B3047638FE35167D048A951E3A317CED92846B94A639A0B3D5F098B35BDA8C139A8EB185EC3F843A6778FAB4EEC4DD1B20F071BC9E5075F7AEF1531CC8FB12E64D48A478BBC398D69E12066975EC2A96BCC6D155FB0BDA03C4D4E817DCCF320E8F34447A94C64E28B8F84D07C08BDDA1215CC370EF5EB970A75ED4F8ADB47F36B134A3430DAA59FEF55CD4B9786F693B09BC9C3E6F1F745BABBC6F5892BC4E416BDA02BD59DD7C763179B2897CBCAF284E0A2DE08E4E32BB1F66169D83FA0206C7962184A15527C7CA8EF04AF87921933A2B9C614145AFEC715C833924B8C863E7E20A07AA21A72C450BBC446B9B51407D90261CDE342C5D585A0482DB8FFC95B72992ED5D8085B8A3A8335A1423F7715AB83DB4D88BB599B272B8F80BE3C03B0A3C4F7C2F2486984FE13CA8E4510EA33B45BD782D415AEE1C22885D10BB5D16521E8907054ADE2FA85D8284B89849B05696AC17AD99279CB7675E8261EDFD7CF38B0E714E4C126D13363422B9D1097C590DD4DE80A1CF7872B2D8F6951877EEB91DC4C24F47C9949676565244DB3B923EE368EE43720DC186E96B0B6E0908D967CC5D5C055659978668FCCE03F8D1F087A9EF12446BA87FF4345D757F477C1A838B5EF0A9F45C712A8147A71EA88FBDA3B9A7D1BB5A477A4C224F5F067271E13CBCA9AFBC444FA340B55987BA1D2263107F495BAD2001B296C5E9F700A7C9C3C966E507428A8F9D0A55E240F4E30F3E4E6159E464311FFA3DFC418DD8B5F28640E6CA09D8A76207F978038A3E8A14C66A3237F0E099E16965B72573CE9B895622FF7606EE54E51D0D0F470280EDC42C6F6E0E298ACC1F7DCDFE3B1299BE5774C8584C11EDB9A89A7FF3E899CD4A74816EFB2223D520CEEBD82D09F4CE741BBC0E0B0C597C14AE6C29255C8C8A5E89353FC1A7BDBD5E329D4D850DAF65851D23931426FEBBE80217562727A9088697C7EED3153BD9475FB85A4A443A71680C7032ADDD3A03F4B6CEB8FDD75DA0CA9332C6E5CE2AFAE921F98B37FE8A64EBB1AF3F29D1D1DE8F2328F3C8B2D6BB8ABF00DE82CCDAA0156061616163E1AF9B65AB54D07A0D927DA73C9304C214AE7AF00BC57B759DFDD12CC6947423BBFCF51949E19F6C1CD6FB208FF43C8CCC89D132B0EB4A6C66C1F3EBDDAAA553BB328AB0F89C9D0B28A1DBE5D8302A1333120D3BEEF97F0AD01439C4491EE560D05EB79E62D14328BE63C3D8D3B97973FEF44A23F1DCC674A32EC85E2A6837F2782623D09ED658324912498A4AB925BA55CE6AC89FA1C73ADAFC12AB808A25A49F1301EE991316CEE05D92290908DC9C5709CF9912570EB56DE350DB4604C401380B2F1FFC2869409B2C5A912279BA57CF
+20220718151038 2 6 100 8191 2 F2F7A2BAF50A41FBCCDE554E561409993B1C6E4133229CAC67C79DE5FEC1F9FBEBECCCE838368FBFA93F774AD02E99F65F8B3F56B3047638FE35167D048A951E3A317CED92846B94A639A0B3D5F098B35BDA8C139A8EB185EC3F843A6778FAB4EEC4DD1B20F071BC9E5075F7AEF1531CC8FB12E64D48A478BBC398D69E12066975EC2A96BCC6D155FB0BDA03C4D4E817DCCF320E8F34447A94C64E28B8F84D07C08BDDA1215CC370EF5EB970A75ED4F8ADB47F36B134A3430DAA59FEF55CD4B9786F693B09BC9C3E6F1F745BABBC6F5892BC4E416BDA02BD59DD7C763179B2897CBCAF284E0A2DE08E4E32BB1F66169D83FA0206C7962184A15527C7CA8EF04AF87921933A2B9C614145AFEC715C833924B8C863E7E20A07AA21A72C450BBC446B9B51407D90261CDE342C5D585A0482DB8FFC95B72992ED5D8085B8A3A8335A1423F7715AB83DB4D88BB599B272B8F80BE3C03B0A3C4F7C2F2486984FE13CA8E4510EA33B45BD782D415AEE1C22885D10BB5D16521E8907054ADE2FA85D8284B89849B05696AC17AD99279CB7675E8261EDFD7CF38B0E714E4C126D13363422B9D1097C590DD4DE80A1CF7872B2D8F6951877EEB91DC4C24F47C9949676565244DB3B923EE368EE43720DC186E96B0B6E0908D967CC5D5C055659978668FCCE03F8D1F087A9EF12446BA87FF4345D757F477C1A838B5EF0A9F45C712A8147A71EA88FBDA3B9A7D1BB5A477A4C224F5F067271E13CBCA9AFBC444FA340B55987BA1D2263107F495BAD2001B296C5E9F700A7C9C3C966E507428A8F9D0A55E240F4E30F3E4E6159E464311FFA3DFC418DD8B5F28640E6CA09D8A76207F978038A3E8A14C66A3237F0E099E16965B72573CE9B895622FF7606EE54E51D0D0F470280EDC42C6F6E0E298ACC1F7DCDFE3B1299BE5774C8584C11EDB9A89A7FF3E899CD4A74816EFB2223D520CEEBD82D09F4CE741BBC0E0B0C597C14AE6C29255C8C8A5E89353FC1A7BDBD5E329D4D850DAF65851D23931426FEBBE80217562727A9088697C7EED3153BD9475FB85A4A443A71680C7032ADDD3A03F4B6CEB8FDD75DA0CA9332C6E5CE2AFAE921F98B37FE8A64EBB1AF3F29D1D1DE8F2328F3C8B2D6BB8ABF00DE82CCDAA0156061616163E1AF9B65AB54D07A0D927DA73C9304C214AE7AF00BC57B759DFDD12CC6947423BBFCF51949E19F6C1CD6FB208FF43C8CCC89D132B0EB4A6C66C1F3EBDDAAA553BB328AB0F89C9D0B28A1DBE5D8302A1333120D3BEEF97F0AD01439C4491EE560D05EB79E62D14328BE63C3D8D3B97973FEF44A23F1DCC674A32EC85E2A6837F2782623D09ED658324912498A4AB925BA55CE6AC89FA1C73ADAFC12AB808A25A49F1301EE991316CEE05D92290908DC9C5709CF9912570EB56DE350DB4604C401380B2F1FFC2869409B2C5A912279BC79AB
+20220718153329 2 6 100 8191 2 F2F7A2BAF50A41FBCCDE554E561409993B1C6E4133229CAC67C79DE5FEC1F9FBEBECCCE838368FBFA93F774AD02E99F65F8B3F56B3047638FE35167D048A951E3A317CED92846B94A639A0B3D5F098B35BDA8C139A8EB185EC3F843A6778FAB4EEC4DD1B20F071BC9E5075F7AEF1531CC8FB12E64D48A478BBC398D69E12066975EC2A96BCC6D155FB0BDA03C4D4E817DCCF320E8F34447A94C64E28B8F84D07C08BDDA1215CC370EF5EB970A75ED4F8ADB47F36B134A3430DAA59FEF55CD4B9786F693B09BC9C3E6F1F745BABBC6F5892BC4E416BDA02BD59DD7C763179B2897CBCAF284E0A2DE08E4E32BB1F66169D83FA0206C7962184A15527C7CA8EF04AF87921933A2B9C614145AFEC715C833924B8C863E7E20A07AA21A72C450BBC446B9B51407D90261CDE342C5D585A0482DB8FFC95B72992ED5D8085B8A3A8335A1423F7715AB83DB4D88BB599B272B8F80BE3C03B0A3C4F7C2F2486984FE13CA8E4510EA33B45BD782D415AEE1C22885D10BB5D16521E8907054ADE2FA85D8284B89849B05696AC17AD99279CB7675E8261EDFD7CF38B0E714E4C126D13363422B9D1097C590DD4DE80A1CF7872B2D8F6951877EEB91DC4C24F47C9949676565244DB3B923EE368EE43720DC186E96B0B6E0908D967CC5D5C055659978668FCCE03F8D1F087A9EF12446BA87FF4345D757F477C1A838B5EF0A9F45C712A8147A71EA88FBDA3B9A7D1BB5A477A4C224F5F067271E13CBCA9AFBC444FA340B55987BA1D2263107F495BAD2001B296C5E9F700A7C9C3C966E507428A8F9D0A55E240F4E30F3E4E6159E464311FFA3DFC418DD8B5F28640E6CA09D8A76207F978038A3E8A14C66A3237F0E099E16965B72573CE9B895622FF7606EE54E51D0D0F470280EDC42C6F6E0E298ACC1F7DCDFE3B1299BE5774C8584C11EDB9A89A7FF3E899CD4A74816EFB2223D520CEEBD82D09F4CE741BBC0E0B0C597C14AE6C29255C8C8A5E89353FC1A7BDBD5E329D4D850DAF65851D23931426FEBBE80217562727A9088697C7EED3153BD9475FB85A4A443A71680C7032ADDD3A03F4B6CEB8FDD75DA0CA9332C6E5CE2AFAE921F98B37FE8A64EBB1AF3F29D1D1DE8F2328F3C8B2D6BB8ABF00DE82CCDAA0156061616163E1AF9B65AB54D07A0D927DA73C9304C214AE7AF00BC57B759DFDD12CC6947423BBFCF51949E19F6C1CD6FB208FF43C8CCC89D132B0EB4A6C66C1F3EBDDAAA553BB328AB0F89C9D0B28A1DBE5D8302A1333120D3BEEF97F0AD01439C4491EE560D05EB79E62D14328BE63C3D8D3B97973FEF44A23F1DCC674A32EC85E2A6837F2782623D09ED658324912498A4AB925BA55CE6AC89FA1C73ADAFC12AB808A25A49F1301EE991316CEE05D92290908DC9C5709CF9912570EB56DE350DB4604C401380B2F1FFC2869409B2C5A91227B1AC9E3
+20220718153657 2 6 100 8191 2 F2F7A2BAF50A41FBCCDE554E561409993B1C6E4133229CAC67C79DE5FEC1F9FBEBECCCE838368FBFA93F774AD02E99F65F8B3F56B3047638FE35167D048A951E3A317CED92846B94A639A0B3D5F098B35BDA8C139A8EB185EC3F843A6778FAB4EEC4DD1B20F071BC9E5075F7AEF1531CC8FB12E64D48A478BBC398D69E12066975EC2A96BCC6D155FB0BDA03C4D4E817DCCF320E8F34447A94C64E28B8F84D07C08BDDA1215CC370EF5EB970A75ED4F8ADB47F36B134A3430DAA59FEF55CD4B9786F693B09BC9C3E6F1F745BABBC6F5892BC4E416BDA02BD59DD7C763179B2897CBCAF284E0A2DE08E4E32BB1F66169D83FA0206C7962184A15527C7CA8EF04AF87921933A2B9C614145AFEC715C833924B8C863E7E20A07AA21A72C450BBC446B9B51407D90261CDE342C5D585A0482DB8FFC95B72992ED5D8085B8A3A8335A1423F7715AB83DB4D88BB599B272B8F80BE3C03B0A3C4F7C2F2486984FE13CA8E4510EA33B45BD782D415AEE1C22885D10BB5D16521E8907054ADE2FA85D8284B89849B05696AC17AD99279CB7675E8261EDFD7CF38B0E714E4C126D13363422B9D1097C590DD4DE80A1CF7872B2D8F6951877EEB91DC4C24F47C9949676565244DB3B923EE368EE43720DC186E96B0B6E0908D967CC5D5C055659978668FCCE03F8D1F087A9EF12446BA87FF4345D757F477C1A838B5EF0A9F45C712A8147A71EA88FBDA3B9A7D1BB5A477A4C224F5F067271E13CBCA9AFBC444FA340B55987BA1D2263107F495BAD2001B296C5E9F700A7C9C3C966E507428A8F9D0A55E240F4E30F3E4E6159E464311FFA3DFC418DD8B5F28640E6CA09D8A76207F978038A3E8A14C66A3237F0E099E16965B72573CE9B895622FF7606EE54E51D0D0F470280EDC42C6F6E0E298ACC1F7DCDFE3B1299BE5774C8584C11EDB9A89A7FF3E899CD4A74816EFB2223D520CEEBD82D09F4CE741BBC0E0B0C597C14AE6C29255C8C8A5E89353FC1A7BDBD5E329D4D850DAF65851D23931426FEBBE80217562727A9088697C7EED3153BD9475FB85A4A443A71680C7032ADDD3A03F4B6CEB8FDD75DA0CA9332C6E5CE2AFAE921F98B37FE8A64EBB1AF3F29D1D1DE8F2328F3C8B2D6BB8ABF00DE82CCDAA0156061616163E1AF9B65AB54D07A0D927DA73C9304C214AE7AF00BC57B759DFDD12CC6947423BBFCF51949E19F6C1CD6FB208FF43C8CCC89D132B0EB4A6C66C1F3EBDDAAA553BB328AB0F89C9D0B28A1DBE5D8302A1333120D3BEEF97F0AD01439C4491EE560D05EB79E62D14328BE63C3D8D3B97973FEF44A23F1DCC674A32EC85E2A6837F2782623D09ED658324912498A4AB925BA55CE6AC89FA1C73ADAFC12AB808A25A49F1301EE991316CEE05D92290908DC9C5709CF9912570EB56DE350DB4604C401380B2F1FFC2869409B2C5A91227B5347F3
+20220718164629 2 6 100 8191 5 F2F7A2BAF50A41FBCCDE554E561409993B1C6E4133229CAC67C79DE5FEC1F9FBEBECCCE838368FBFA93F774AD02E99F65F8B3F56B3047638FE35167D048A951E3A317CED92846B94A639A0B3D5F098B35BDA8C139A8EB185EC3F843A6778FAB4EEC4DD1B20F071BC9E5075F7AEF1531CC8FB12E64D48A478BBC398D69E12066975EC2A96BCC6D155FB0BDA03C4D4E817DCCF320E8F34447A94C64E28B8F84D07C08BDDA1215CC370EF5EB970A75ED4F8ADB47F36B134A3430DAA59FEF55CD4B9786F693B09BC9C3E6F1F745BABBC6F5892BC4E416BDA02BD59DD7C763179B2897CBCAF284E0A2DE08E4E32BB1F66169D83FA0206C7962184A15527C7CA8EF04AF87921933A2B9C614145AFEC715C833924B8C863E7E20A07AA21A72C450BBC446B9B51407D90261CDE342C5D585A0482DB8FFC95B72992ED5D8085B8A3A8335A1423F7715AB83DB4D88BB599B272B8F80BE3C03B0A3C4F7C2F2486984FE13CA8E4510EA33B45BD782D415AEE1C22885D10BB5D16521E8907054ADE2FA85D8284B89849B05696AC17AD99279CB7675E8261EDFD7CF38B0E714E4C126D13363422B9D1097C590DD4DE80A1CF7872B2D8F6951877EEB91DC4C24F47C9949676565244DB3B923EE368EE43720DC186E96B0B6E0908D967CC5D5C055659978668FCCE03F8D1F087A9EF12446BA87FF4345D757F477C1A838B5EF0A9F45C712A8147A71EA88FBDA3B9A7D1BB5A477A4C224F5F067271E13CBCA9AFBC444FA340B55987BA1D2263107F495BAD2001B296C5E9F700A7C9C3C966E507428A8F9D0A55E240F4E30F3E4E6159E464311FFA3DFC418DD8B5F28640E6CA09D8A76207F978038A3E8A14C66A3237F0E099E16965B72573CE9B895622FF7606EE54E51D0D0F470280EDC42C6F6E0E298ACC1F7DCDFE3B1299BE5774C8584C11EDB9A89A7FF3E899CD4A74816EFB2223D520CEEBD82D09F4CE741BBC0E0B0C597C14AE6C29255C8C8A5E89353FC1A7BDBD5E329D4D850DAF65851D23931426FEBBE80217562727A9088697C7EED3153BD9475FB85A4A443A71680C7032ADDD3A03F4B6CEB8FDD75DA0CA9332C6E5CE2AFAE921F98B37FE8A64EBB1AF3F29D1D1DE8F2328F3C8B2D6BB8ABF00DE82CCDAA0156061616163E1AF9B65AB54D07A0D927DA73C9304C214AE7AF00BC57B759DFDD12CC6947423BBFCF51949E19F6C1CD6FB208FF43C8CCC89D132B0EB4A6C66C1F3EBDDAAA553BB328AB0F89C9D0B28A1DBE5D8302A1333120D3BEEF97F0AD01439C4491EE560D05EB79E62D14328BE63C3D8D3B97973FEF44A23F1DCC674A32EC85E2A6837F2782623D09ED658324912498A4AB925BA55CE6AC89FA1C73ADAFC12AB808A25A49F1301EE991316CEE05D92290908DC9C5709CF9912570EB56DE350DB4604C401380B2F1FFC2869409B2C5A91227F6F51E7
+20220718183946 2 6 100 8191 2 F2F7A2BAF50A41FBCCDE554E561409993B1C6E4133229CAC67C79DE5FEC1F9FBEBECCCE838368FBFA93F774AD02E99F65F8B3F56B3047638FE35167D048A951E3A317CED92846B94A639A0B3D5F098B35BDA8C139A8EB185EC3F843A6778FAB4EEC4DD1B20F071BC9E5075F7AEF1531CC8FB12E64D48A478BBC398D69E12066975EC2A96BCC6D155FB0BDA03C4D4E817DCCF320E8F34447A94C64E28B8F84D07C08BDDA1215CC370EF5EB970A75ED4F8ADB47F36B134A3430DAA59FEF55CD4B9786F693B09BC9C3E6F1F745BABBC6F5892BC4E416BDA02BD59DD7C763179B2897CBCAF284E0A2DE08E4E32BB1F66169D83FA0206C7962184A15527C7CA8EF04AF87921933A2B9C614145AFEC715C833924B8C863E7E20A07AA21A72C450BBC446B9B51407D90261CDE342C5D585A0482DB8FFC95B72992ED5D8085B8A3A8335A1423F7715AB83DB4D88BB599B272B8F80BE3C03B0A3C4F7C2F2486984FE13CA8E4510EA33B45BD782D415AEE1C22885D10BB5D16521E8907054ADE2FA85D8284B89849B05696AC17AD99279CB7675E8261EDFD7CF38B0E714E4C126D13363422B9D1097C590DD4DE80A1CF7872B2D8F6951877EEB91DC4C24F47C9949676565244DB3B923EE368EE43720DC186E96B0B6E0908D967CC5D5C055659978668FCCE03F8D1F087A9EF12446BA87FF4345D757F477C1A838B5EF0A9F45C712A8147A71EA88FBDA3B9A7D1BB5A477A4C224F5F067271E13CBCA9AFBC444FA340B55987BA1D2263107F495BAD2001B296C5E9F700A7C9C3C966E507428A8F9D0A55E240F4E30F3E4E6159E464311FFA3DFC418DD8B5F28640E6CA09D8A76207F978038A3E8A14C66A3237F0E099E16965B72573CE9B895622FF7606EE54E51D0D0F470280EDC42C6F6E0E298ACC1F7DCDFE3B1299BE5774C8584C11EDB9A89A7FF3E899CD4A74816EFB2223D520CEEBD82D09F4CE741BBC0E0B0C597C14AE6C29255C8C8A5E89353FC1A7BDBD5E329D4D850DAF65851D23931426FEBBE80217562727A9088697C7EED3153BD9475FB85A4A443A71680C7032ADDD3A03F4B6CEB8FDD75DA0CA9332C6E5CE2AFAE921F98B37FE8A64EBB1AF3F29D1D1DE8F2328F3C8B2D6BB8ABF00DE82CCDAA0156061616163E1AF9B65AB54D07A0D927DA73C9304C214AE7AF00BC57B759DFDD12CC6947423BBFCF51949E19F6C1CD6FB208FF43C8CCC89D132B0EB4A6C66C1F3EBDDAAA553BB328AB0F89C9D0B28A1DBE5D8302A1333120D3BEEF97F0AD01439C4491EE560D05EB79E62D14328BE63C3D8D3B97973FEF44A23F1DCC674A32EC85E2A6837F2782623D09ED658324912498A4AB925BA55CE6AC89FA1C73ADAFC12AB808A25A49F1301EE991316CEE05D92290908DC9C5709CF9912570EB56DE350DB4604C401380B2F1FFC2869409B2C5A9122863E85E3
+20220718195516 2 6 100 8191 2 F2F7A2BAF50A41FBCCDE554E561409993B1C6E4133229CAC67C79DE5FEC1F9FBEBECCCE838368FBFA93F774AD02E99F65F8B3F56B3047638FE35167D048A951E3A317CED92846B94A639A0B3D5F098B35BDA8C139A8EB185EC3F843A6778FAB4EEC4DD1B20F071BC9E5075F7AEF1531CC8FB12E64D48A478BBC398D69E12066975EC2A96BCC6D155FB0BDA03C4D4E817DCCF320E8F34447A94C64E28B8F84D07C08BDDA1215CC370EF5EB970A75ED4F8ADB47F36B134A3430DAA59FEF55CD4B9786F693B09BC9C3E6F1F745BABBC6F5892BC4E416BDA02BD59DD7C763179B2897CBCAF284E0A2DE08E4E32BB1F66169D83FA0206C7962184A15527C7CA8EF04AF87921933A2B9C614145AFEC715C833924B8C863E7E20A07AA21A72C450BBC446B9B51407D90261CDE342C5D585A0482DB8FFC95B72992ED5D8085B8A3A8335A1423F7715AB83DB4D88BB599B272B8F80BE3C03B0A3C4F7C2F2486984FE13CA8E4510EA33B45BD782D415AEE1C22885D10BB5D16521E8907054ADE2FA85D8284B89849B05696AC17AD99279CB7675E8261EDFD7CF38B0E714E4C126D13363422B9D1097C590DD4DE80A1CF7872B2D8F6951877EEB91DC4C24F47C9949676565244DB3B923EE368EE43720DC186E96B0B6E0908D967CC5D5C055659978668FCCE03F8D1F087A9EF12446BA87FF4345D757F477C1A838B5EF0A9F45C712A8147A71EA88FBDA3B9A7D1BB5A477A4C224F5F067271E13CBCA9AFBC444FA340B55987BA1D2263107F495BAD2001B296C5E9F700A7C9C3C966E507428A8F9D0A55E240F4E30F3E4E6159E464311FFA3DFC418DD8B5F28640E6CA09D8A76207F978038A3E8A14C66A3237F0E099E16965B72573CE9B895622FF7606EE54E51D0D0F470280EDC42C6F6E0E298ACC1F7DCDFE3B1299BE5774C8584C11EDB9A89A7FF3E899CD4A74816EFB2223D520CEEBD82D09F4CE741BBC0E0B0C597C14AE6C29255C8C8A5E89353FC1A7BDBD5E329D4D850DAF65851D23931426FEBBE80217562727A9088697C7EED3153BD9475FB85A4A443A71680C7032ADDD3A03F4B6CEB8FDD75DA0CA9332C6E5CE2AFAE921F98B37FE8A64EBB1AF3F29D1D1DE8F2328F3C8B2D6BB8ABF00DE82CCDAA0156061616163E1AF9B65AB54D07A0D927DA73C9304C214AE7AF00BC57B759DFDD12CC6947423BBFCF51949E19F6C1CD6FB208FF43C8CCC89D132B0EB4A6C66C1F3EBDDAAA553BB328AB0F89C9D0B28A1DBE5D8302A1333120D3BEEF97F0AD01439C4491EE560D05EB79E62D14328BE63C3D8D3B97973FEF44A23F1DCC674A32EC85E2A6837F2782623D09ED658324912498A4AB925BA55CE6AC89FA1C73ADAFC12AB808A25A49F1301EE991316CEE05D92290908DC9C5709CF9912570EB56DE350DB4604C401380B2F1FFC2869409B2C5A91228ACE2663
+20220718212930 2 6 100 8191 2 F2F7A2BAF50A41FBCCDE554E561409993B1C6E4133229CAC67C79DE5FEC1F9FBEBECCCE838368FBFA93F774AD02E99F65F8B3F56B3047638FE35167D048A951E3A317CED92846B94A639A0B3D5F098B35BDA8C139A8EB185EC3F843A6778FAB4EEC4DD1B20F071BC9E5075F7AEF1531CC8FB12E64D48A478BBC398D69E12066975EC2A96BCC6D155FB0BDA03C4D4E817DCCF320E8F34447A94C64E28B8F84D07C08BDDA1215CC370EF5EB970A75ED4F8ADB47F36B134A3430DAA59FEF55CD4B9786F693B09BC9C3E6F1F745BABBC6F5892BC4E416BDA02BD59DD7C763179B2897CBCAF284E0A2DE08E4E32BB1F66169D83FA0206C7962184A15527C7CA8EF04AF87921933A2B9C614145AFEC715C833924B8C863E7E20A07AA21A72C450BBC446B9B51407D90261CDE342C5D585A0482DB8FFC95B72992ED5D8085B8A3A8335A1423F7715AB83DB4D88BB599B272B8F80BE3C03B0A3C4F7C2F2486984FE13CA8E4510EA33B45BD782D415AEE1C22885D10BB5D16521E8907054ADE2FA85D8284B89849B05696AC17AD99279CB7675E8261EDFD7CF38B0E714E4C126D13363422B9D1097C590DD4DE80A1CF7872B2D8F6951877EEB91DC4C24F47C9949676565244DB3B923EE368EE43720DC186E96B0B6E0908D967CC5D5C055659978668FCCE03F8D1F087A9EF12446BA87FF4345D757F477C1A838B5EF0A9F45C712A8147A71EA88FBDA3B9A7D1BB5A477A4C224F5F067271E13CBCA9AFBC444FA340B55987BA1D2263107F495BAD2001B296C5E9F700A7C9C3C966E507428A8F9D0A55E240F4E30F3E4E6159E464311FFA3DFC418DD8B5F28640E6CA09D8A76207F978038A3E8A14C66A3237F0E099E16965B72573CE9B895622FF7606EE54E51D0D0F470280EDC42C6F6E0E298ACC1F7DCDFE3B1299BE5774C8584C11EDB9A89A7FF3E899CD4A74816EFB2223D520CEEBD82D09F4CE741BBC0E0B0C597C14AE6C29255C8C8A5E89353FC1A7BDBD5E329D4D850DAF65851D23931426FEBBE80217562727A9088697C7EED3153BD9475FB85A4A443A71680C7032ADDD3A03F4B6CEB8FDD75DA0CA9332C6E5CE2AFAE921F98B37FE8A64EBB1AF3F29D1D1DE8F2328F3C8B2D6BB8ABF00DE82CCDAA0156061616163E1AF9B65AB54D07A0D927DA73C9304C214AE7AF00BC57B759DFDD12CC6947423BBFCF51949E19F6C1CD6FB208FF43C8CCC89D132B0EB4A6C66C1F3EBDDAAA553BB328AB0F89C9D0B28A1DBE5D8302A1333120D3BEEF97F0AD01439C4491EE560D05EB79E62D14328BE63C3D8D3B97973FEF44A23F1DCC674A32EC85E2A6837F2782623D09ED658324912498A4AB925BA55CE6AC89FA1C73ADAFC12AB808A25A49F1301EE991316CEE05D92290908DC9C5709CF9912570EB56DE350DB4604C401380B2F1FFC2869409B2C5A9122906E4B83
+20220719004619 2 6 100 8191 2 F2F7A2BAF50A41FBCCDE554E561409993B1C6E4133229CAC67C79DE5FEC1F9FBEBECCCE838368FBFA93F774AD02E99F65F8B3F56B3047638FE35167D048A951E3A317CED92846B94A639A0B3D5F098B35BDA8C139A8EB185EC3F843A6778FAB4EEC4DD1B20F071BC9E5075F7AEF1531CC8FB12E64D48A478BBC398D69E12066975EC2A96BCC6D155FB0BDA03C4D4E817DCCF320E8F34447A94C64E28B8F84D07C08BDDA1215CC370EF5EB970A75ED4F8ADB47F36B134A3430DAA59FEF55CD4B9786F693B09BC9C3E6F1F745BABBC6F5892BC4E416BDA02BD59DD7C763179B2897CBCAF284E0A2DE08E4E32BB1F66169D83FA0206C7962184A15527C7CA8EF04AF87921933A2B9C614145AFEC715C833924B8C863E7E20A07AA21A72C450BBC446B9B51407D90261CDE342C5D585A0482DB8FFC95B72992ED5D8085B8A3A8335A1423F7715AB83DB4D88BB599B272B8F80BE3C03B0A3C4F7C2F2486984FE13CA8E4510EA33B45BD782D415AEE1C22885D10BB5D16521E8907054ADE2FA85D8284B89849B05696AC17AD99279CB7675E8261EDFD7CF38B0E714E4C126D13363422B9D1097C590DD4DE80A1CF7872B2D8F6951877EEB91DC4C24F47C9949676565244DB3B923EE368EE43720DC186E96B0B6E0908D967CC5D5C055659978668FCCE03F8D1F087A9EF12446BA87FF4345D757F477C1A838B5EF0A9F45C712A8147A71EA88FBDA3B9A7D1BB5A477A4C224F5F067271E13CBCA9AFBC444FA340B55987BA1D2263107F495BAD2001B296C5E9F700A7C9C3C966E507428A8F9D0A55E240F4E30F3E4E6159E464311FFA3DFC418DD8B5F28640E6CA09D8A76207F978038A3E8A14C66A3237F0E099E16965B72573CE9B895622FF7606EE54E51D0D0F470280EDC42C6F6E0E298ACC1F7DCDFE3B1299BE5774C8584C11EDB9A89A7FF3E899CD4A74816EFB2223D520CEEBD82D09F4CE741BBC0E0B0C597C14AE6C29255C8C8A5E89353FC1A7BDBD5E329D4D850DAF65851D23931426FEBBE80217562727A9088697C7EED3153BD9475FB85A4A443A71680C7032ADDD3A03F4B6CEB8FDD75DA0CA9332C6E5CE2AFAE921F98B37FE8A64EBB1AF3F29D1D1DE8F2328F3C8B2D6BB8ABF00DE82CCDAA0156061616163E1AF9B65AB54D07A0D927DA73C9304C214AE7AF00BC57B759DFDD12CC6947423BBFCF51949E19F6C1CD6FB208FF43C8CCC89D132B0EB4A6C66C1F3EBDDAAA553BB328AB0F89C9D0B28A1DBE5D8302A1333120D3BEEF97F0AD01439C4491EE560D05EB79E62D14328BE63C3D8D3B97973FEF44A23F1DCC674A32EC85E2A6837F2782623D09ED658324912498A4AB925BA55CE6AC89FA1C73ADAFC12AB808A25A49F1301EE991316CEE05D92290908DC9C5709CF9912570EB56DE350DB4604C401380B2F1FFC2869409B2C5A91229C28A03B
+20220719005356 2 6 100 8191 5 F2F7A2BAF50A41FBCCDE554E561409993B1C6E4133229CAC67C79DE5FEC1F9FBEBECCCE838368FBFA93F774AD02E99F65F8B3F56B3047638FE35167D048A951E3A317CED92846B94A639A0B3D5F098B35BDA8C139A8EB185EC3F843A6778FAB4EEC4DD1B20F071BC9E5075F7AEF1531CC8FB12E64D48A478BBC398D69E12066975EC2A96BCC6D155FB0BDA03C4D4E817DCCF320E8F34447A94C64E28B8F84D07C08BDDA1215CC370EF5EB970A75ED4F8ADB47F36B134A3430DAA59FEF55CD4B9786F693B09BC9C3E6F1F745BABBC6F5892BC4E416BDA02BD59DD7C763179B2897CBCAF284E0A2DE08E4E32BB1F66169D83FA0206C7962184A15527C7CA8EF04AF87921933A2B9C614145AFEC715C833924B8C863E7E20A07AA21A72C450BBC446B9B51407D90261CDE342C5D585A0482DB8FFC95B72992ED5D8085B8A3A8335A1423F7715AB83DB4D88BB599B272B8F80BE3C03B0A3C4F7C2F2486984FE13CA8E4510EA33B45BD782D415AEE1C22885D10BB5D16521E8907054ADE2FA85D8284B89849B05696AC17AD99279CB7675E8261EDFD7CF38B0E714E4C126D13363422B9D1097C590DD4DE80A1CF7872B2D8F6951877EEB91DC4C24F47C9949676565244DB3B923EE368EE43720DC186E96B0B6E0908D967CC5D5C055659978668FCCE03F8D1F087A9EF12446BA87FF4345D757F477C1A838B5EF0A9F45C712A8147A71EA88FBDA3B9A7D1BB5A477A4C224F5F067271E13CBCA9AFBC444FA340B55987BA1D2263107F495BAD2001B296C5E9F700A7C9C3C966E507428A8F9D0A55E240F4E30F3E4E6159E464311FFA3DFC418DD8B5F28640E6CA09D8A76207F978038A3E8A14C66A3237F0E099E16965B72573CE9B895622FF7606EE54E51D0D0F470280EDC42C6F6E0E298ACC1F7DCDFE3B1299BE5774C8584C11EDB9A89A7FF3E899CD4A74816EFB2223D520CEEBD82D09F4CE741BBC0E0B0C597C14AE6C29255C8C8A5E89353FC1A7BDBD5E329D4D850DAF65851D23931426FEBBE80217562727A9088697C7EED3153BD9475FB85A4A443A71680C7032ADDD3A03F4B6CEB8FDD75DA0CA9332C6E5CE2AFAE921F98B37FE8A64EBB1AF3F29D1D1DE8F2328F3C8B2D6BB8ABF00DE82CCDAA0156061616163E1AF9B65AB54D07A0D927DA73C9304C214AE7AF00BC57B759DFDD12CC6947423BBFCF51949E19F6C1CD6FB208FF43C8CCC89D132B0EB4A6C66C1F3EBDDAAA553BB328AB0F89C9D0B28A1DBE5D8302A1333120D3BEEF97F0AD01439C4491EE560D05EB79E62D14328BE63C3D8D3B97973FEF44A23F1DCC674A32EC85E2A6837F2782623D09ED658324912498A4AB925BA55CE6AC89FA1C73ADAFC12AB808A25A49F1301EE991316CEE05D92290908DC9C5709CF9912570EB56DE350DB4604C401380B2F1FFC2869409B2C5A91229C9C1FCF
+20220719014859 2 6 100 8191 5 C5A088686E2057FDD426A4329908C72093AFD4A412B73B7C03574CCFAA7EBA44BF6CF5AD03B49A0AEF8A18CCAF15B0D7B12DEE66078C6A3CCE94DCA05193912A668B6E247962F8CC51046DC6DAF5AE92C169A8F00D116524762DAA1E9FF3F3270F2831FA8C94010DAD76A0032523EB9A610EBBA3BF3EFE82471449768C5B844277FC90486CBC00B6C0EA93DE6067DF863B5F1E5D5BD9781DEB1C5A111AEF62BD8016C4210CB6CA14C45559266711960B7F7FEF20E96391F59D019973FB9EFEE8C198D70EC2080C69EBCCEFA9CE2D93081A47E916F667AFFE28642A8E36133D03A3058D9E65DC0C13959DDC40CFF31B53768D41369CF05EDA59CAA0643949A1ED78B8D2F748A93F3DCE01A22AB1F23EC4E63F7A97D7863907A401633B92A073F62B56FD341B9E2B1497FB139FC2FEBD1F5EEE3A001D9DE86C6F8EBA8DDC0C0504A7A46409D036BB9534BC293BB4D9E77A9A2D0296528266EB6BD8071695F854C4E35912B78E10B2D9574D9F238E7649F998CCA0F2639068B0895E71F79E84BF631367A9221DA5F0C12191EA1CC93CA0D863269E7D25F65D29BC9D70F30B287849533A99D5DA2B8D1337DFA905E46A8673F45028192B297D52CF62C5137E4F7D824EB166CB37FBC393EF1FCC235DCC5D7A224B3A2CF975ADAEA330413E7B6DE83EF6181CBA7AF33575369AD7FBFAD0A6B7211BC3BD8EC3648AB6421D2A9142E95AA6827ACA734A605B88585BF5B30EEC75823DCA57EF524421EFC354CA2EE5D9123B1883FBDC41A0DB3558536B410089013F051EE93C3ADD61500F1A3A37CB403F5378AC3AC40D0022617442EDDCA56B012C17A0A50F33B3C6A2F8BE955F22800C4DA6D65ADB413E87ADE5351FD20BE2BF281ABF8CC8BB78A6723D2B9CDE699BCCD47FB7EBEC2F2EA46B6060EAC9101A4448D2CC4D0C6EA9A1A78CE6528C39CF879B75EDB0F0F84602A1EC66250F1BEA8BB250BE675BF6EFDBEDEB1B97699A8F248B68506BBD4F968CAB83FC8C3AEED661AD3682A6B38ADCF7FE0C7A257C4BD376A56207EA4E0F89DA41460BAA707C74A6670C5953ECCAF324A79DA05116A0493B16BDE9D12DE376ED0DA9A7B9780BD3096633EF40D52D03C5ECCB24630046AF5270657416BD7B2F45EEA86C3019E91A946132621E6E96BCA9C42609390EEBA2D1CD06C47DB2A2FDEFF2788505AD177A07AE04A6549909FBA711F714B1F76054668E119FA19B4830819C5108EB186F95AD1ECA0D91AA79337EBABA0AA0F84487227E6951F537BA293556D43E16DD77DE63FD9702EA9E6FDAA775B4C96A16D8DD35852A9079ACB398792F6E89D56595B3E9340BA56525F270E2E976FB376E77F02CD8231988125030610AE2FCFA69A8FAD3D98122D0E8CEF28E5AA696EE497C0B8C8299B77480095577B78251DB69997A17F148EEC4E89A323BF747EF869C312A97
+20220719020529 2 6 100 8191 5 C5A088686E2057FDD426A4329908C72093AFD4A412B73B7C03574CCFAA7EBA44BF6CF5AD03B49A0AEF8A18CCAF15B0D7B12DEE66078C6A3CCE94DCA05193912A668B6E247962F8CC51046DC6DAF5AE92C169A8F00D116524762DAA1E9FF3F3270F2831FA8C94010DAD76A0032523EB9A610EBBA3BF3EFE82471449768C5B844277FC90486CBC00B6C0EA93DE6067DF863B5F1E5D5BD9781DEB1C5A111AEF62BD8016C4210CB6CA14C45559266711960B7F7FEF20E96391F59D019973FB9EFEE8C198D70EC2080C69EBCCEFA9CE2D93081A47E916F667AFFE28642A8E36133D03A3058D9E65DC0C13959DDC40CFF31B53768D41369CF05EDA59CAA0643949A1ED78B8D2F748A93F3DCE01A22AB1F23EC4E63F7A97D7863907A401633B92A073F62B56FD341B9E2B1497FB139FC2FEBD1F5EEE3A001D9DE86C6F8EBA8DDC0C0504A7A46409D036BB9534BC293BB4D9E77A9A2D0296528266EB6BD8071695F854C4E35912B78E10B2D9574D9F238E7649F998CCA0F2639068B0895E71F79E84BF631367A9221DA5F0C12191EA1CC93CA0D863269E7D25F65D29BC9D70F30B287849533A99D5DA2B8D1337DFA905E46A8673F45028192B297D52CF62C5137E4F7D824EB166CB37FBC393EF1FCC235DCC5D7A224B3A2CF975ADAEA330413E7B6DE83EF6181CBA7AF33575369AD7FBFAD0A6B7211BC3BD8EC3648AB6421D2A9142E95AA6827ACA734A605B88585BF5B30EEC75823DCA57EF524421EFC354CA2EE5D9123B1883FBDC41A0DB3558536B410089013F051EE93C3ADD61500F1A3A37CB403F5378AC3AC40D0022617442EDDCA56B012C17A0A50F33B3C6A2F8BE955F22800C4DA6D65ADB413E87ADE5351FD20BE2BF281ABF8CC8BB78A6723D2B9CDE699BCCD47FB7EBEC2F2EA46B6060EAC9101A4448D2CC4D0C6EA9A1A78CE6528C39CF879B75EDB0F0F84602A1EC66250F1BEA8BB250BE675BF6EFDBEDEB1B97699A8F248B68506BBD4F968CAB83FC8C3AEED661AD3682A6B38ADCF7FE0C7A257C4BD376A56207EA4E0F89DA41460BAA707C74A6670C5953ECCAF324A79DA05116A0493B16BDE9D12DE376ED0DA9A7B9780BD3096633EF40D52D03C5ECCB24630046AF5270657416BD7B2F45EEA86C3019E91A946132621E6E96BCA9C42609390EEBA2D1CD06C47DB2A2FDEFF2788505AD177A07AE04A6549909FBA711F714B1F76054668E119FA19B4830819C5108EB186F95AD1ECA0D91AA79337EBABA0AA0F84487227E6951F537BA293556D43E16DD77DE63FD9702EA9E6FDAA775B4C96A16D8DD35852A9079ACB398792F6E89D56595B3E9340BA56525F270E2E976FB376E77F02CD8231988125030610AE2FCFA69A8FAD3D98122D0E8CEF28E5AA696EE497C0B8C8299B77480095577B78251DB69997A17F148EEC4E89A323BF747EF869D2642A7
+20220719034913 2 6 100 8191 2 C5A088686E2057FDD426A4329908C72093AFD4A412B73B7C03574CCFAA7EBA44BF6CF5AD03B49A0AEF8A18CCAF15B0D7B12DEE66078C6A3CCE94DCA05193912A668B6E247962F8CC51046DC6DAF5AE92C169A8F00D116524762DAA1E9FF3F3270F2831FA8C94010DAD76A0032523EB9A610EBBA3BF3EFE82471449768C5B844277FC90486CBC00B6C0EA93DE6067DF863B5F1E5D5BD9781DEB1C5A111AEF62BD8016C4210CB6CA14C45559266711960B7F7FEF20E96391F59D019973FB9EFEE8C198D70EC2080C69EBCCEFA9CE2D93081A47E916F667AFFE28642A8E36133D03A3058D9E65DC0C13959DDC40CFF31B53768D41369CF05EDA59CAA0643949A1ED78B8D2F748A93F3DCE01A22AB1F23EC4E63F7A97D7863907A401633B92A073F62B56FD341B9E2B1497FB139FC2FEBD1F5EEE3A001D9DE86C6F8EBA8DDC0C0504A7A46409D036BB9534BC293BB4D9E77A9A2D0296528266EB6BD8071695F854C4E35912B78E10B2D9574D9F238E7649F998CCA0F2639068B0895E71F79E84BF631367A9221DA5F0C12191EA1CC93CA0D863269E7D25F65D29BC9D70F30B287849533A99D5DA2B8D1337DFA905E46A8673F45028192B297D52CF62C5137E4F7D824EB166CB37FBC393EF1FCC235DCC5D7A224B3A2CF975ADAEA330413E7B6DE83EF6181CBA7AF33575369AD7FBFAD0A6B7211BC3BD8EC3648AB6421D2A9142E95AA6827ACA734A605B88585BF5B30EEC75823DCA57EF524421EFC354CA2EE5D9123B1883FBDC41A0DB3558536B410089013F051EE93C3ADD61500F1A3A37CB403F5378AC3AC40D0022617442EDDCA56B012C17A0A50F33B3C6A2F8BE955F22800C4DA6D65ADB413E87ADE5351FD20BE2BF281ABF8CC8BB78A6723D2B9CDE699BCCD47FB7EBEC2F2EA46B6060EAC9101A4448D2CC4D0C6EA9A1A78CE6528C39CF879B75EDB0F0F84602A1EC66250F1BEA8BB250BE675BF6EFDBEDEB1B97699A8F248B68506BBD4F968CAB83FC8C3AEED661AD3682A6B38ADCF7FE0C7A257C4BD376A56207EA4E0F89DA41460BAA707C74A6670C5953ECCAF324A79DA05116A0493B16BDE9D12DE376ED0DA9A7B9780BD3096633EF40D52D03C5ECCB24630046AF5270657416BD7B2F45EEA86C3019E91A946132621E6E96BCA9C42609390EEBA2D1CD06C47DB2A2FDEFF2788505AD177A07AE04A6549909FBA711F714B1F76054668E119FA19B4830819C5108EB186F95AD1ECA0D91AA79337EBABA0AA0F84487227E6951F537BA293556D43E16DD77DE63FD9702EA9E6FDAA775B4C96A16D8DD35852A9079ACB398792F6E89D56595B3E9340BA56525F270E2E976FB376E77F02CD8231988125030610AE2FCFA69A8FAD3D98122D0E8CEF28E5AA696EE497C0B8C8299B77480095577B78251DB69997A17F148EEC4E89A323BF747EF86A3588B53
+20220719044402 2 6 100 8191 2 C5A088686E2057FDD426A4329908C72093AFD4A412B73B7C03574CCFAA7EBA44BF6CF5AD03B49A0AEF8A18CCAF15B0D7B12DEE66078C6A3CCE94DCA05193912A668B6E247962F8CC51046DC6DAF5AE92C169A8F00D116524762DAA1E9FF3F3270F2831FA8C94010DAD76A0032523EB9A610EBBA3BF3EFE82471449768C5B844277FC90486CBC00B6C0EA93DE6067DF863B5F1E5D5BD9781DEB1C5A111AEF62BD8016C4210CB6CA14C45559266711960B7F7FEF20E96391F59D019973FB9EFEE8C198D70EC2080C69EBCCEFA9CE2D93081A47E916F667AFFE28642A8E36133D03A3058D9E65DC0C13959DDC40CFF31B53768D41369CF05EDA59CAA0643949A1ED78B8D2F748A93F3DCE01A22AB1F23EC4E63F7A97D7863907A401633B92A073F62B56FD341B9E2B1497FB139FC2FEBD1F5EEE3A001D9DE86C6F8EBA8DDC0C0504A7A46409D036BB9534BC293BB4D9E77A9A2D0296528266EB6BD8071695F854C4E35912B78E10B2D9574D9F238E7649F998CCA0F2639068B0895E71F79E84BF631367A9221DA5F0C12191EA1CC93CA0D863269E7D25F65D29BC9D70F30B287849533A99D5DA2B8D1337DFA905E46A8673F45028192B297D52CF62C5137E4F7D824EB166CB37FBC393EF1FCC235DCC5D7A224B3A2CF975ADAEA330413E7B6DE83EF6181CBA7AF33575369AD7FBFAD0A6B7211BC3BD8EC3648AB6421D2A9142E95AA6827ACA734A605B88585BF5B30EEC75823DCA57EF524421EFC354CA2EE5D9123B1883FBDC41A0DB3558536B410089013F051EE93C3ADD61500F1A3A37CB403F5378AC3AC40D0022617442EDDCA56B012C17A0A50F33B3C6A2F8BE955F22800C4DA6D65ADB413E87ADE5351FD20BE2BF281ABF8CC8BB78A6723D2B9CDE699BCCD47FB7EBEC2F2EA46B6060EAC9101A4448D2CC4D0C6EA9A1A78CE6528C39CF879B75EDB0F0F84602A1EC66250F1BEA8BB250BE675BF6EFDBEDEB1B97699A8F248B68506BBD4F968CAB83FC8C3AEED661AD3682A6B38ADCF7FE0C7A257C4BD376A56207EA4E0F89DA41460BAA707C74A6670C5953ECCAF324A79DA05116A0493B16BDE9D12DE376ED0DA9A7B9780BD3096633EF40D52D03C5ECCB24630046AF5270657416BD7B2F45EEA86C3019E91A946132621E6E96BCA9C42609390EEBA2D1CD06C47DB2A2FDEFF2788505AD177A07AE04A6549909FBA711F714B1F76054668E119FA19B4830819C5108EB186F95AD1ECA0D91AA79337EBABA0AA0F84487227E6951F537BA293556D43E16DD77DE63FD9702EA9E6FDAA775B4C96A16D8DD35852A9079ACB398792F6E89D56595B3E9340BA56525F270E2E976FB376E77F02CD8231988125030610AE2FCFA69A8FAD3D98122D0E8CEF28E5AA696EE497C0B8C8299B77480095577B78251DB69997A17F148EEC4E89A323BF747EF86A69DB913
+20220719045215 2 6 100 8191 2 C5A088686E2057FDD426A4329908C72093AFD4A412B73B7C03574CCFAA7EBA44BF6CF5AD03B49A0AEF8A18CCAF15B0D7B12DEE66078C6A3CCE94DCA05193912A668B6E247962F8CC51046DC6DAF5AE92C169A8F00D116524762DAA1E9FF3F3270F2831FA8C94010DAD76A0032523EB9A610EBBA3BF3EFE82471449768C5B844277FC90486CBC00B6C0EA93DE6067DF863B5F1E5D5BD9781DEB1C5A111AEF62BD8016C4210CB6CA14C45559266711960B7F7FEF20E96391F59D019973FB9EFEE8C198D70EC2080C69EBCCEFA9CE2D93081A47E916F667AFFE28642A8E36133D03A3058D9E65DC0C13959DDC40CFF31B53768D41369CF05EDA59CAA0643949A1ED78B8D2F748A93F3DCE01A22AB1F23EC4E63F7A97D7863907A401633B92A073F62B56FD341B9E2B1497FB139FC2FEBD1F5EEE3A001D9DE86C6F8EBA8DDC0C0504A7A46409D036BB9534BC293BB4D9E77A9A2D0296528266EB6BD8071695F854C4E35912B78E10B2D9574D9F238E7649F998CCA0F2639068B0895E71F79E84BF631367A9221DA5F0C12191EA1CC93CA0D863269E7D25F65D29BC9D70F30B287849533A99D5DA2B8D1337DFA905E46A8673F45028192B297D52CF62C5137E4F7D824EB166CB37FBC393EF1FCC235DCC5D7A224B3A2CF975ADAEA330413E7B6DE83EF6181CBA7AF33575369AD7FBFAD0A6B7211BC3BD8EC3648AB6421D2A9142E95AA6827ACA734A605B88585BF5B30EEC75823DCA57EF524421EFC354CA2EE5D9123B1883FBDC41A0DB3558536B410089013F051EE93C3ADD61500F1A3A37CB403F5378AC3AC40D0022617442EDDCA56B012C17A0A50F33B3C6A2F8BE955F22800C4DA6D65ADB413E87ADE5351FD20BE2BF281ABF8CC8BB78A6723D2B9CDE699BCCD47FB7EBEC2F2EA46B6060EAC9101A4448D2CC4D0C6EA9A1A78CE6528C39CF879B75EDB0F0F84602A1EC66250F1BEA8BB250BE675BF6EFDBEDEB1B97699A8F248B68506BBD4F968CAB83FC8C3AEED661AD3682A6B38ADCF7FE0C7A257C4BD376A56207EA4E0F89DA41460BAA707C74A6670C5953ECCAF324A79DA05116A0493B16BDE9D12DE376ED0DA9A7B9780BD3096633EF40D52D03C5ECCB24630046AF5270657416BD7B2F45EEA86C3019E91A946132621E6E96BCA9C42609390EEBA2D1CD06C47DB2A2FDEFF2788505AD177A07AE04A6549909FBA711F714B1F76054668E119FA19B4830819C5108EB186F95AD1ECA0D91AA79337EBABA0AA0F84487227E6951F537BA293556D43E16DD77DE63FD9702EA9E6FDAA775B4C96A16D8DD35852A9079ACB398792F6E89D56595B3E9340BA56525F270E2E976FB376E77F02CD8231988125030610AE2FCFA69A8FAD3D98122D0E8CEF28E5AA696EE497C0B8C8299B77480095577B78251DB69997A17F148EEC4E89A323BF747EF86A717D82B
+20220719064925 2 6 100 8191 2 C5A088686E2057FDD426A4329908C72093AFD4A412B73B7C03574CCFAA7EBA44BF6CF5AD03B49A0AEF8A18CCAF15B0D7B12DEE66078C6A3CCE94DCA05193912A668B6E247962F8CC51046DC6DAF5AE92C169A8F00D116524762DAA1E9FF3F3270F2831FA8C94010DAD76A0032523EB9A610EBBA3BF3EFE82471449768C5B844277FC90486CBC00B6C0EA93DE6067DF863B5F1E5D5BD9781DEB1C5A111AEF62BD8016C4210CB6CA14C45559266711960B7F7FEF20E96391F59D019973FB9EFEE8C198D70EC2080C69EBCCEFA9CE2D93081A47E916F667AFFE28642A8E36133D03A3058D9E65DC0C13959DDC40CFF31B53768D41369CF05EDA59CAA0643949A1ED78B8D2F748A93F3DCE01A22AB1F23EC4E63F7A97D7863907A401633B92A073F62B56FD341B9E2B1497FB139FC2FEBD1F5EEE3A001D9DE86C6F8EBA8DDC0C0504A7A46409D036BB9534BC293BB4D9E77A9A2D0296528266EB6BD8071695F854C4E35912B78E10B2D9574D9F238E7649F998CCA0F2639068B0895E71F79E84BF631367A9221DA5F0C12191EA1CC93CA0D863269E7D25F65D29BC9D70F30B287849533A99D5DA2B8D1337DFA905E46A8673F45028192B297D52CF62C5137E4F7D824EB166CB37FBC393EF1FCC235DCC5D7A224B3A2CF975ADAEA330413E7B6DE83EF6181CBA7AF33575369AD7FBFAD0A6B7211BC3BD8EC3648AB6421D2A9142E95AA6827ACA734A605B88585BF5B30EEC75823DCA57EF524421EFC354CA2EE5D9123B1883FBDC41A0DB3558536B410089013F051EE93C3ADD61500F1A3A37CB403F5378AC3AC40D0022617442EDDCA56B012C17A0A50F33B3C6A2F8BE955F22800C4DA6D65ADB413E87ADE5351FD20BE2BF281ABF8CC8BB78A6723D2B9CDE699BCCD47FB7EBEC2F2EA46B6060EAC9101A4448D2CC4D0C6EA9A1A78CE6528C39CF879B75EDB0F0F84602A1EC66250F1BEA8BB250BE675BF6EFDBEDEB1B97699A8F248B68506BBD4F968CAB83FC8C3AEED661AD3682A6B38ADCF7FE0C7A257C4BD376A56207EA4E0F89DA41460BAA707C74A6670C5953ECCAF324A79DA05116A0493B16BDE9D12DE376ED0DA9A7B9780BD3096633EF40D52D03C5ECCB24630046AF5270657416BD7B2F45EEA86C3019E91A946132621E6E96BCA9C42609390EEBA2D1CD06C47DB2A2FDEFF2788505AD177A07AE04A6549909FBA711F714B1F76054668E119FA19B4830819C5108EB186F95AD1ECA0D91AA79337EBABA0AA0F84487227E6951F537BA293556D43E16DD77DE63FD9702EA9E6FDAA775B4C96A16D8DD35852A9079ACB398792F6E89D56595B3E9340BA56525F270E2E976FB376E77F02CD8231988125030610AE2FCFA69A8FAD3D98122D0E8CEF28E5AA696EE497C0B8C8299B77480095577B78251DB69997A17F148EEC4E89A323BF747EF86AE08C58B
+20220719074822 2 6 100 8191 2 C5A088686E2057FDD426A4329908C72093AFD4A412B73B7C03574CCFAA7EBA44BF6CF5AD03B49A0AEF8A18CCAF15B0D7B12DEE66078C6A3CCE94DCA05193912A668B6E247962F8CC51046DC6DAF5AE92C169A8F00D116524762DAA1E9FF3F3270F2831FA8C94010DAD76A0032523EB9A610EBBA3BF3EFE82471449768C5B844277FC90486CBC00B6C0EA93DE6067DF863B5F1E5D5BD9781DEB1C5A111AEF62BD8016C4210CB6CA14C45559266711960B7F7FEF20E96391F59D019973FB9EFEE8C198D70EC2080C69EBCCEFA9CE2D93081A47E916F667AFFE28642A8E36133D03A3058D9E65DC0C13959DDC40CFF31B53768D41369CF05EDA59CAA0643949A1ED78B8D2F748A93F3DCE01A22AB1F23EC4E63F7A97D7863907A401633B92A073F62B56FD341B9E2B1497FB139FC2FEBD1F5EEE3A001D9DE86C6F8EBA8DDC0C0504A7A46409D036BB9534BC293BB4D9E77A9A2D0296528266EB6BD8071695F854C4E35912B78E10B2D9574D9F238E7649F998CCA0F2639068B0895E71F79E84BF631367A9221DA5F0C12191EA1CC93CA0D863269E7D25F65D29BC9D70F30B287849533A99D5DA2B8D1337DFA905E46A8673F45028192B297D52CF62C5137E4F7D824EB166CB37FBC393EF1FCC235DCC5D7A224B3A2CF975ADAEA330413E7B6DE83EF6181CBA7AF33575369AD7FBFAD0A6B7211BC3BD8EC3648AB6421D2A9142E95AA6827ACA734A605B88585BF5B30EEC75823DCA57EF524421EFC354CA2EE5D9123B1883FBDC41A0DB3558536B410089013F051EE93C3ADD61500F1A3A37CB403F5378AC3AC40D0022617442EDDCA56B012C17A0A50F33B3C6A2F8BE955F22800C4DA6D65ADB413E87ADE5351FD20BE2BF281ABF8CC8BB78A6723D2B9CDE699BCCD47FB7EBEC2F2EA46B6060EAC9101A4448D2CC4D0C6EA9A1A78CE6528C39CF879B75EDB0F0F84602A1EC66250F1BEA8BB250BE675BF6EFDBEDEB1B97699A8F248B68506BBD4F968CAB83FC8C3AEED661AD3682A6B38ADCF7FE0C7A257C4BD376A56207EA4E0F89DA41460BAA707C74A6670C5953ECCAF324A79DA05116A0493B16BDE9D12DE376ED0DA9A7B9780BD3096633EF40D52D03C5ECCB24630046AF5270657416BD7B2F45EEA86C3019E91A946132621E6E96BCA9C42609390EEBA2D1CD06C47DB2A2FDEFF2788505AD177A07AE04A6549909FBA711F714B1F76054668E119FA19B4830819C5108EB186F95AD1ECA0D91AA79337EBABA0AA0F84487227E6951F537BA293556D43E16DD77DE63FD9702EA9E6FDAA775B4C96A16D8DD35852A9079ACB398792F6E89D56595B3E9340BA56525F270E2E976FB376E77F02CD8231988125030610AE2FCFA69A8FAD3D98122D0E8CEF28E5AA696EE497C0B8C8299B77480095577B78251DB69997A17F148EEC4E89A323BF747EF86B18928B3
+20220719094802 2 6 100 8191 2 C5A088686E2057FDD426A4329908C72093AFD4A412B73B7C03574CCFAA7EBA44BF6CF5AD03B49A0AEF8A18CCAF15B0D7B12DEE66078C6A3CCE94DCA05193912A668B6E247962F8CC51046DC6DAF5AE92C169A8F00D116524762DAA1E9FF3F3270F2831FA8C94010DAD76A0032523EB9A610EBBA3BF3EFE82471449768C5B844277FC90486CBC00B6C0EA93DE6067DF863B5F1E5D5BD9781DEB1C5A111AEF62BD8016C4210CB6CA14C45559266711960B7F7FEF20E96391F59D019973FB9EFEE8C198D70EC2080C69EBCCEFA9CE2D93081A47E916F667AFFE28642A8E36133D03A3058D9E65DC0C13959DDC40CFF31B53768D41369CF05EDA59CAA0643949A1ED78B8D2F748A93F3DCE01A22AB1F23EC4E63F7A97D7863907A401633B92A073F62B56FD341B9E2B1497FB139FC2FEBD1F5EEE3A001D9DE86C6F8EBA8DDC0C0504A7A46409D036BB9534BC293BB4D9E77A9A2D0296528266EB6BD8071695F854C4E35912B78E10B2D9574D9F238E7649F998CCA0F2639068B0895E71F79E84BF631367A9221DA5F0C12191EA1CC93CA0D863269E7D25F65D29BC9D70F30B287849533A99D5DA2B8D1337DFA905E46A8673F45028192B297D52CF62C5137E4F7D824EB166CB37FBC393EF1FCC235DCC5D7A224B3A2CF975ADAEA330413E7B6DE83EF6181CBA7AF33575369AD7FBFAD0A6B7211BC3BD8EC3648AB6421D2A9142E95AA6827ACA734A605B88585BF5B30EEC75823DCA57EF524421EFC354CA2EE5D9123B1883FBDC41A0DB3558536B410089013F051EE93C3ADD61500F1A3A37CB403F5378AC3AC40D0022617442EDDCA56B012C17A0A50F33B3C6A2F8BE955F22800C4DA6D65ADB413E87ADE5351FD20BE2BF281ABF8CC8BB78A6723D2B9CDE699BCCD47FB7EBEC2F2EA46B6060EAC9101A4448D2CC4D0C6EA9A1A78CE6528C39CF879B75EDB0F0F84602A1EC66250F1BEA8BB250BE675BF6EFDBEDEB1B97699A8F248B68506BBD4F968CAB83FC8C3AEED661AD3682A6B38ADCF7FE0C7A257C4BD376A56207EA4E0F89DA41460BAA707C74A6670C5953ECCAF324A79DA05116A0493B16BDE9D12DE376ED0DA9A7B9780BD3096633EF40D52D03C5ECCB24630046AF5270657416BD7B2F45EEA86C3019E91A946132621E6E96BCA9C42609390EEBA2D1CD06C47DB2A2FDEFF2788505AD177A07AE04A6549909FBA711F714B1F76054668E119FA19B4830819C5108EB186F95AD1ECA0D91AA79337EBABA0AA0F84487227E6951F537BA293556D43E16DD77DE63FD9702EA9E6FDAA775B4C96A16D8DD35852A9079ACB398792F6E89D56595B3E9340BA56525F270E2E976FB376E77F02CD8231988125030610AE2FCFA69A8FAD3D98122D0E8CEF28E5AA696EE497C0B8C8299B77480095577B78251DB69997A17F148EEC4E89A323BF747EF86B8C09B6B
+20220719101343 2 6 100 8191 2 C5A088686E2057FDD426A4329908C72093AFD4A412B73B7C03574CCFAA7EBA44BF6CF5AD03B49A0AEF8A18CCAF15B0D7B12DEE66078C6A3CCE94DCA05193912A668B6E247962F8CC51046DC6DAF5AE92C169A8F00D116524762DAA1E9FF3F3270F2831FA8C94010DAD76A0032523EB9A610EBBA3BF3EFE82471449768C5B844277FC90486CBC00B6C0EA93DE6067DF863B5F1E5D5BD9781DEB1C5A111AEF62BD8016C4210CB6CA14C45559266711960B7F7FEF20E96391F59D019973FB9EFEE8C198D70EC2080C69EBCCEFA9CE2D93081A47E916F667AFFE28642A8E36133D03A3058D9E65DC0C13959DDC40CFF31B53768D41369CF05EDA59CAA0643949A1ED78B8D2F748A93F3DCE01A22AB1F23EC4E63F7A97D7863907A401633B92A073F62B56FD341B9E2B1497FB139FC2FEBD1F5EEE3A001D9DE86C6F8EBA8DDC0C0504A7A46409D036BB9534BC293BB4D9E77A9A2D0296528266EB6BD8071695F854C4E35912B78E10B2D9574D9F238E7649F998CCA0F2639068B0895E71F79E84BF631367A9221DA5F0C12191EA1CC93CA0D863269E7D25F65D29BC9D70F30B287849533A99D5DA2B8D1337DFA905E46A8673F45028192B297D52CF62C5137E4F7D824EB166CB37FBC393EF1FCC235DCC5D7A224B3A2CF975ADAEA330413E7B6DE83EF6181CBA7AF33575369AD7FBFAD0A6B7211BC3BD8EC3648AB6421D2A9142E95AA6827ACA734A605B88585BF5B30EEC75823DCA57EF524421EFC354CA2EE5D9123B1883FBDC41A0DB3558536B410089013F051EE93C3ADD61500F1A3A37CB403F5378AC3AC40D0022617442EDDCA56B012C17A0A50F33B3C6A2F8BE955F22800C4DA6D65ADB413E87ADE5351FD20BE2BF281ABF8CC8BB78A6723D2B9CDE699BCCD47FB7EBEC2F2EA46B6060EAC9101A4448D2CC4D0C6EA9A1A78CE6528C39CF879B75EDB0F0F84602A1EC66250F1BEA8BB250BE675BF6EFDBEDEB1B97699A8F248B68506BBD4F968CAB83FC8C3AEED661AD3682A6B38ADCF7FE0C7A257C4BD376A56207EA4E0F89DA41460BAA707C74A6670C5953ECCAF324A79DA05116A0493B16BDE9D12DE376ED0DA9A7B9780BD3096633EF40D52D03C5ECCB24630046AF5270657416BD7B2F45EEA86C3019E91A946132621E6E96BCA9C42609390EEBA2D1CD06C47DB2A2FDEFF2788505AD177A07AE04A6549909FBA711F714B1F76054668E119FA19B4830819C5108EB186F95AD1ECA0D91AA79337EBABA0AA0F84487227E6951F537BA293556D43E16DD77DE63FD9702EA9E6FDAA775B4C96A16D8DD35852A9079ACB398792F6E89D56595B3E9340BA56525F270E2E976FB376E77F02CD8231988125030610AE2FCFA69A8FAD3D98122D0E8CEF28E5AA696EE497C0B8C8299B77480095577B78251DB69997A17F148EEC4E89A323BF747EF86BA4587CB
+20220719105007 2 6 100 8191 5 C5A088686E2057FDD426A4329908C72093AFD4A412B73B7C03574CCFAA7EBA44BF6CF5AD03B49A0AEF8A18CCAF15B0D7B12DEE66078C6A3CCE94DCA05193912A668B6E247962F8CC51046DC6DAF5AE92C169A8F00D116524762DAA1E9FF3F3270F2831FA8C94010DAD76A0032523EB9A610EBBA3BF3EFE82471449768C5B844277FC90486CBC00B6C0EA93DE6067DF863B5F1E5D5BD9781DEB1C5A111AEF62BD8016C4210CB6CA14C45559266711960B7F7FEF20E96391F59D019973FB9EFEE8C198D70EC2080C69EBCCEFA9CE2D93081A47E916F667AFFE28642A8E36133D03A3058D9E65DC0C13959DDC40CFF31B53768D41369CF05EDA59CAA0643949A1ED78B8D2F748A93F3DCE01A22AB1F23EC4E63F7A97D7863907A401633B92A073F62B56FD341B9E2B1497FB139FC2FEBD1F5EEE3A001D9DE86C6F8EBA8DDC0C0504A7A46409D036BB9534BC293BB4D9E77A9A2D0296528266EB6BD8071695F854C4E35912B78E10B2D9574D9F238E7649F998CCA0F2639068B0895E71F79E84BF631367A9221DA5F0C12191EA1CC93CA0D863269E7D25F65D29BC9D70F30B287849533A99D5DA2B8D1337DFA905E46A8673F45028192B297D52CF62C5137E4F7D824EB166CB37FBC393EF1FCC235DCC5D7A224B3A2CF975ADAEA330413E7B6DE83EF6181CBA7AF33575369AD7FBFAD0A6B7211BC3BD8EC3648AB6421D2A9142E95AA6827ACA734A605B88585BF5B30EEC75823DCA57EF524421EFC354CA2EE5D9123B1883FBDC41A0DB3558536B410089013F051EE93C3ADD61500F1A3A37CB403F5378AC3AC40D0022617442EDDCA56B012C17A0A50F33B3C6A2F8BE955F22800C4DA6D65ADB413E87ADE5351FD20BE2BF281ABF8CC8BB78A6723D2B9CDE699BCCD47FB7EBEC2F2EA46B6060EAC9101A4448D2CC4D0C6EA9A1A78CE6528C39CF879B75EDB0F0F84602A1EC66250F1BEA8BB250BE675BF6EFDBEDEB1B97699A8F248B68506BBD4F968CAB83FC8C3AEED661AD3682A6B38ADCF7FE0C7A257C4BD376A56207EA4E0F89DA41460BAA707C74A6670C5953ECCAF324A79DA05116A0493B16BDE9D12DE376ED0DA9A7B9780BD3096633EF40D52D03C5ECCB24630046AF5270657416BD7B2F45EEA86C3019E91A946132621E6E96BCA9C42609390EEBA2D1CD06C47DB2A2FDEFF2788505AD177A07AE04A6549909FBA711F714B1F76054668E119FA19B4830819C5108EB186F95AD1ECA0D91AA79337EBABA0AA0F84487227E6951F537BA293556D43E16DD77DE63FD9702EA9E6FDAA775B4C96A16D8DD35852A9079ACB398792F6E89D56595B3E9340BA56525F270E2E976FB376E77F02CD8231988125030610AE2FCFA69A8FAD3D98122D0E8CEF28E5AA696EE497C0B8C8299B77480095577B78251DB69997A17F148EEC4E89A323BF747EF86BC6960B7
+20220719115822 2 6 100 8191 2 C5A088686E2057FDD426A4329908C72093AFD4A412B73B7C03574CCFAA7EBA44BF6CF5AD03B49A0AEF8A18CCAF15B0D7B12DEE66078C6A3CCE94DCA05193912A668B6E247962F8CC51046DC6DAF5AE92C169A8F00D116524762DAA1E9FF3F3270F2831FA8C94010DAD76A0032523EB9A610EBBA3BF3EFE82471449768C5B844277FC90486CBC00B6C0EA93DE6067DF863B5F1E5D5BD9781DEB1C5A111AEF62BD8016C4210CB6CA14C45559266711960B7F7FEF20E96391F59D019973FB9EFEE8C198D70EC2080C69EBCCEFA9CE2D93081A47E916F667AFFE28642A8E36133D03A3058D9E65DC0C13959DDC40CFF31B53768D41369CF05EDA59CAA0643949A1ED78B8D2F748A93F3DCE01A22AB1F23EC4E63F7A97D7863907A401633B92A073F62B56FD341B9E2B1497FB139FC2FEBD1F5EEE3A001D9DE86C6F8EBA8DDC0C0504A7A46409D036BB9534BC293BB4D9E77A9A2D0296528266EB6BD8071695F854C4E35912B78E10B2D9574D9F238E7649F998CCA0F2639068B0895E71F79E84BF631367A9221DA5F0C12191EA1CC93CA0D863269E7D25F65D29BC9D70F30B287849533A99D5DA2B8D1337DFA905E46A8673F45028192B297D52CF62C5137E4F7D824EB166CB37FBC393EF1FCC235DCC5D7A224B3A2CF975ADAEA330413E7B6DE83EF6181CBA7AF33575369AD7FBFAD0A6B7211BC3BD8EC3648AB6421D2A9142E95AA6827ACA734A605B88585BF5B30EEC75823DCA57EF524421EFC354CA2EE5D9123B1883FBDC41A0DB3558536B410089013F051EE93C3ADD61500F1A3A37CB403F5378AC3AC40D0022617442EDDCA56B012C17A0A50F33B3C6A2F8BE955F22800C4DA6D65ADB413E87ADE5351FD20BE2BF281ABF8CC8BB78A6723D2B9CDE699BCCD47FB7EBEC2F2EA46B6060EAC9101A4448D2CC4D0C6EA9A1A78CE6528C39CF879B75EDB0F0F84602A1EC66250F1BEA8BB250BE675BF6EFDBEDEB1B97699A8F248B68506BBD4F968CAB83FC8C3AEED661AD3682A6B38ADCF7FE0C7A257C4BD376A56207EA4E0F89DA41460BAA707C74A6670C5953ECCAF324A79DA05116A0493B16BDE9D12DE376ED0DA9A7B9780BD3096633EF40D52D03C5ECCB24630046AF5270657416BD7B2F45EEA86C3019E91A946132621E6E96BCA9C42609390EEBA2D1CD06C47DB2A2FDEFF2788505AD177A07AE04A6549909FBA711F714B1F76054668E119FA19B4830819C5108EB186F95AD1ECA0D91AA79337EBABA0AA0F84487227E6951F537BA293556D43E16DD77DE63FD9702EA9E6FDAA775B4C96A16D8DD35852A9079ACB398792F6E89D56595B3E9340BA56525F270E2E976FB376E77F02CD8231988125030610AE2FCFA69A8FAD3D98122D0E8CEF28E5AA696EE497C0B8C8299B77480095577B78251DB69997A17F148EEC4E89A323BF747EF86C07CBCB3
+20220719124950 2 6 100 8191 2 C5A088686E2057FDD426A4329908C72093AFD4A412B73B7C03574CCFAA7EBA44BF6CF5AD03B49A0AEF8A18CCAF15B0D7B12DEE66078C6A3CCE94DCA05193912A668B6E247962F8CC51046DC6DAF5AE92C169A8F00D116524762DAA1E9FF3F3270F2831FA8C94010DAD76A0032523EB9A610EBBA3BF3EFE82471449768C5B844277FC90486CBC00B6C0EA93DE6067DF863B5F1E5D5BD9781DEB1C5A111AEF62BD8016C4210CB6CA14C45559266711960B7F7FEF20E96391F59D019973FB9EFEE8C198D70EC2080C69EBCCEFA9CE2D93081A47E916F667AFFE28642A8E36133D03A3058D9E65DC0C13959DDC40CFF31B53768D41369CF05EDA59CAA0643949A1ED78B8D2F748A93F3DCE01A22AB1F23EC4E63F7A97D7863907A401633B92A073F62B56FD341B9E2B1497FB139FC2FEBD1F5EEE3A001D9DE86C6F8EBA8DDC0C0504A7A46409D036BB9534BC293BB4D9E77A9A2D0296528266EB6BD8071695F854C4E35912B78E10B2D9574D9F238E7649F998CCA0F2639068B0895E71F79E84BF631367A9221DA5F0C12191EA1CC93CA0D863269E7D25F65D29BC9D70F30B287849533A99D5DA2B8D1337DFA905E46A8673F45028192B297D52CF62C5137E4F7D824EB166CB37FBC393EF1FCC235DCC5D7A224B3A2CF975ADAEA330413E7B6DE83EF6181CBA7AF33575369AD7FBFAD0A6B7211BC3BD8EC3648AB6421D2A9142E95AA6827ACA734A605B88585BF5B30EEC75823DCA57EF524421EFC354CA2EE5D9123B1883FBDC41A0DB3558536B410089013F051EE93C3ADD61500F1A3A37CB403F5378AC3AC40D0022617442EDDCA56B012C17A0A50F33B3C6A2F8BE955F22800C4DA6D65ADB413E87ADE5351FD20BE2BF281ABF8CC8BB78A6723D2B9CDE699BCCD47FB7EBEC2F2EA46B6060EAC9101A4448D2CC4D0C6EA9A1A78CE6528C39CF879B75EDB0F0F84602A1EC66250F1BEA8BB250BE675BF6EFDBEDEB1B97699A8F248B68506BBD4F968CAB83FC8C3AEED661AD3682A6B38ADCF7FE0C7A257C4BD376A56207EA4E0F89DA41460BAA707C74A6670C5953ECCAF324A79DA05116A0493B16BDE9D12DE376ED0DA9A7B9780BD3096633EF40D52D03C5ECCB24630046AF5270657416BD7B2F45EEA86C3019E91A946132621E6E96BCA9C42609390EEBA2D1CD06C47DB2A2FDEFF2788505AD177A07AE04A6549909FBA711F714B1F76054668E119FA19B4830819C5108EB186F95AD1ECA0D91AA79337EBABA0AA0F84487227E6951F537BA293556D43E16DD77DE63FD9702EA9E6FDAA775B4C96A16D8DD35852A9079ACB398792F6E89D56595B3E9340BA56525F270E2E976FB376E77F02CD8231988125030610AE2FCFA69A8FAD3D98122D0E8CEF28E5AA696EE497C0B8C8299B77480095577B78251DB69997A17F148EEC4E89A323BF747EF86C387963B
+20220719151704 2 6 100 8191 5 C5A088686E2057FDD426A4329908C72093AFD4A412B73B7C03574CCFAA7EBA44BF6CF5AD03B49A0AEF8A18CCAF15B0D7B12DEE66078C6A3CCE94DCA05193912A668B6E247962F8CC51046DC6DAF5AE92C169A8F00D116524762DAA1E9FF3F3270F2831FA8C94010DAD76A0032523EB9A610EBBA3BF3EFE82471449768C5B844277FC90486CBC00B6C0EA93DE6067DF863B5F1E5D5BD9781DEB1C5A111AEF62BD8016C4210CB6CA14C45559266711960B7F7FEF20E96391F59D019973FB9EFEE8C198D70EC2080C69EBCCEFA9CE2D93081A47E916F667AFFE28642A8E36133D03A3058D9E65DC0C13959DDC40CFF31B53768D41369CF05EDA59CAA0643949A1ED78B8D2F748A93F3DCE01A22AB1F23EC4E63F7A97D7863907A401633B92A073F62B56FD341B9E2B1497FB139FC2FEBD1F5EEE3A001D9DE86C6F8EBA8DDC0C0504A7A46409D036BB9534BC293BB4D9E77A9A2D0296528266EB6BD8071695F854C4E35912B78E10B2D9574D9F238E7649F998CCA0F2639068B0895E71F79E84BF631367A9221DA5F0C12191EA1CC93CA0D863269E7D25F65D29BC9D70F30B287849533A99D5DA2B8D1337DFA905E46A8673F45028192B297D52CF62C5137E4F7D824EB166CB37FBC393EF1FCC235DCC5D7A224B3A2CF975ADAEA330413E7B6DE83EF6181CBA7AF33575369AD7FBFAD0A6B7211BC3BD8EC3648AB6421D2A9142E95AA6827ACA734A605B88585BF5B30EEC75823DCA57EF524421EFC354CA2EE5D9123B1883FBDC41A0DB3558536B410089013F051EE93C3ADD61500F1A3A37CB403F5378AC3AC40D0022617442EDDCA56B012C17A0A50F33B3C6A2F8BE955F22800C4DA6D65ADB413E87ADE5351FD20BE2BF281ABF8CC8BB78A6723D2B9CDE699BCCD47FB7EBEC2F2EA46B6060EAC9101A4448D2CC4D0C6EA9A1A78CE6528C39CF879B75EDB0F0F84602A1EC66250F1BEA8BB250BE675BF6EFDBEDEB1B97699A8F248B68506BBD4F968CAB83FC8C3AEED661AD3682A6B38ADCF7FE0C7A257C4BD376A56207EA4E0F89DA41460BAA707C74A6670C5953ECCAF324A79DA05116A0493B16BDE9D12DE376ED0DA9A7B9780BD3096633EF40D52D03C5ECCB24630046AF5270657416BD7B2F45EEA86C3019E91A946132621E6E96BCA9C42609390EEBA2D1CD06C47DB2A2FDEFF2788505AD177A07AE04A6549909FBA711F714B1F76054668E119FA19B4830819C5108EB186F95AD1ECA0D91AA79337EBABA0AA0F84487227E6951F537BA293556D43E16DD77DE63FD9702EA9E6FDAA775B4C96A16D8DD35852A9079ACB398792F6E89D56595B3E9340BA56525F270E2E976FB376E77F02CD8231988125030610AE2FCFA69A8FAD3D98122D0E8CEF28E5AA696EE497C0B8C8299B77480095577B78251DB69997A17F148EEC4E89A323BF747EF86CC63DE8F
+20220719153327 2 6 100 8191 5 C5A088686E2057FDD426A4329908C72093AFD4A412B73B7C03574CCFAA7EBA44BF6CF5AD03B49A0AEF8A18CCAF15B0D7B12DEE66078C6A3CCE94DCA05193912A668B6E247962F8CC51046DC6DAF5AE92C169A8F00D116524762DAA1E9FF3F3270F2831FA8C94010DAD76A0032523EB9A610EBBA3BF3EFE82471449768C5B844277FC90486CBC00B6C0EA93DE6067DF863B5F1E5D5BD9781DEB1C5A111AEF62BD8016C4210CB6CA14C45559266711960B7F7FEF20E96391F59D019973FB9EFEE8C198D70EC2080C69EBCCEFA9CE2D93081A47E916F667AFFE28642A8E36133D03A3058D9E65DC0C13959DDC40CFF31B53768D41369CF05EDA59CAA0643949A1ED78B8D2F748A93F3DCE01A22AB1F23EC4E63F7A97D7863907A401633B92A073F62B56FD341B9E2B1497FB139FC2FEBD1F5EEE3A001D9DE86C6F8EBA8DDC0C0504A7A46409D036BB9534BC293BB4D9E77A9A2D0296528266EB6BD8071695F854C4E35912B78E10B2D9574D9F238E7649F998CCA0F2639068B0895E71F79E84BF631367A9221DA5F0C12191EA1CC93CA0D863269E7D25F65D29BC9D70F30B287849533A99D5DA2B8D1337DFA905E46A8673F45028192B297D52CF62C5137E4F7D824EB166CB37FBC393EF1FCC235DCC5D7A224B3A2CF975ADAEA330413E7B6DE83EF6181CBA7AF33575369AD7FBFAD0A6B7211BC3BD8EC3648AB6421D2A9142E95AA6827ACA734A605B88585BF5B30EEC75823DCA57EF524421EFC354CA2EE5D9123B1883FBDC41A0DB3558536B410089013F051EE93C3ADD61500F1A3A37CB403F5378AC3AC40D0022617442EDDCA56B012C17A0A50F33B3C6A2F8BE955F22800C4DA6D65ADB413E87ADE5351FD20BE2BF281ABF8CC8BB78A6723D2B9CDE699BCCD47FB7EBEC2F2EA46B6060EAC9101A4448D2CC4D0C6EA9A1A78CE6528C39CF879B75EDB0F0F84602A1EC66250F1BEA8BB250BE675BF6EFDBEDEB1B97699A8F248B68506BBD4F968CAB83FC8C3AEED661AD3682A6B38ADCF7FE0C7A257C4BD376A56207EA4E0F89DA41460BAA707C74A6670C5953ECCAF324A79DA05116A0493B16BDE9D12DE376ED0DA9A7B9780BD3096633EF40D52D03C5ECCB24630046AF5270657416BD7B2F45EEA86C3019E91A946132621E6E96BCA9C42609390EEBA2D1CD06C47DB2A2FDEFF2788505AD177A07AE04A6549909FBA711F714B1F76054668E119FA19B4830819C5108EB186F95AD1ECA0D91AA79337EBABA0AA0F84487227E6951F537BA293556D43E16DD77DE63FD9702EA9E6FDAA775B4C96A16D8DD35852A9079ACB398792F6E89D56595B3E9340BA56525F270E2E976FB376E77F02CD8231988125030610AE2FCFA69A8FAD3D98122D0E8CEF28E5AA696EE497C0B8C8299B77480095577B78251DB69997A17F148EEC4E89A323BF747EF86CD62A8BF
+20220719161053 2 6 100 8191 5 C5A088686E2057FDD426A4329908C72093AFD4A412B73B7C03574CCFAA7EBA44BF6CF5AD03B49A0AEF8A18CCAF15B0D7B12DEE66078C6A3CCE94DCA05193912A668B6E247962F8CC51046DC6DAF5AE92C169A8F00D116524762DAA1E9FF3F3270F2831FA8C94010DAD76A0032523EB9A610EBBA3BF3EFE82471449768C5B844277FC90486CBC00B6C0EA93DE6067DF863B5F1E5D5BD9781DEB1C5A111AEF62BD8016C4210CB6CA14C45559266711960B7F7FEF20E96391F59D019973FB9EFEE8C198D70EC2080C69EBCCEFA9CE2D93081A47E916F667AFFE28642A8E36133D03A3058D9E65DC0C13959DDC40CFF31B53768D41369CF05EDA59CAA0643949A1ED78B8D2F748A93F3DCE01A22AB1F23EC4E63F7A97D7863907A401633B92A073F62B56FD341B9E2B1497FB139FC2FEBD1F5EEE3A001D9DE86C6F8EBA8DDC0C0504A7A46409D036BB9534BC293BB4D9E77A9A2D0296528266EB6BD8071695F854C4E35912B78E10B2D9574D9F238E7649F998CCA0F2639068B0895E71F79E84BF631367A9221DA5F0C12191EA1CC93CA0D863269E7D25F65D29BC9D70F30B287849533A99D5DA2B8D1337DFA905E46A8673F45028192B297D52CF62C5137E4F7D824EB166CB37FBC393EF1FCC235DCC5D7A224B3A2CF975ADAEA330413E7B6DE83EF6181CBA7AF33575369AD7FBFAD0A6B7211BC3BD8EC3648AB6421D2A9142E95AA6827ACA734A605B88585BF5B30EEC75823DCA57EF524421EFC354CA2EE5D9123B1883FBDC41A0DB3558536B410089013F051EE93C3ADD61500F1A3A37CB403F5378AC3AC40D0022617442EDDCA56B012C17A0A50F33B3C6A2F8BE955F22800C4DA6D65ADB413E87ADE5351FD20BE2BF281ABF8CC8BB78A6723D2B9CDE699BCCD47FB7EBEC2F2EA46B6060EAC9101A4448D2CC4D0C6EA9A1A78CE6528C39CF879B75EDB0F0F84602A1EC66250F1BEA8BB250BE675BF6EFDBEDEB1B97699A8F248B68506BBD4F968CAB83FC8C3AEED661AD3682A6B38ADCF7FE0C7A257C4BD376A56207EA4E0F89DA41460BAA707C74A6670C5953ECCAF324A79DA05116A0493B16BDE9D12DE376ED0DA9A7B9780BD3096633EF40D52D03C5ECCB24630046AF5270657416BD7B2F45EEA86C3019E91A946132621E6E96BCA9C42609390EEBA2D1CD06C47DB2A2FDEFF2788505AD177A07AE04A6549909FBA711F714B1F76054668E119FA19B4830819C5108EB186F95AD1ECA0D91AA79337EBABA0AA0F84487227E6951F537BA293556D43E16DD77DE63FD9702EA9E6FDAA775B4C96A16D8DD35852A9079ACB398792F6E89D56595B3E9340BA56525F270E2E976FB376E77F02CD8231988125030610AE2FCFA69A8FAD3D98122D0E8CEF28E5AA696EE497C0B8C8299B77480095577B78251DB69997A17F148EEC4E89A323BF747EF86CF9B2757
+20220719173122 2 6 100 8191 2 C5A088686E2057FDD426A4329908C72093AFD4A412B73B7C03574CCFAA7EBA44BF6CF5AD03B49A0AEF8A18CCAF15B0D7B12DEE66078C6A3CCE94DCA05193912A668B6E247962F8CC51046DC6DAF5AE92C169A8F00D116524762DAA1E9FF3F3270F2831FA8C94010DAD76A0032523EB9A610EBBA3BF3EFE82471449768C5B844277FC90486CBC00B6C0EA93DE6067DF863B5F1E5D5BD9781DEB1C5A111AEF62BD8016C4210CB6CA14C45559266711960B7F7FEF20E96391F59D019973FB9EFEE8C198D70EC2080C69EBCCEFA9CE2D93081A47E916F667AFFE28642A8E36133D03A3058D9E65DC0C13959DDC40CFF31B53768D41369CF05EDA59CAA0643949A1ED78B8D2F748A93F3DCE01A22AB1F23EC4E63F7A97D7863907A401633B92A073F62B56FD341B9E2B1497FB139FC2FEBD1F5EEE3A001D9DE86C6F8EBA8DDC0C0504A7A46409D036BB9534BC293BB4D9E77A9A2D0296528266EB6BD8071695F854C4E35912B78E10B2D9574D9F238E7649F998CCA0F2639068B0895E71F79E84BF631367A9221DA5F0C12191EA1CC93CA0D863269E7D25F65D29BC9D70F30B287849533A99D5DA2B8D1337DFA905E46A8673F45028192B297D52CF62C5137E4F7D824EB166CB37FBC393EF1FCC235DCC5D7A224B3A2CF975ADAEA330413E7B6DE83EF6181CBA7AF33575369AD7FBFAD0A6B7211BC3BD8EC3648AB6421D2A9142E95AA6827ACA734A605B88585BF5B30EEC75823DCA57EF524421EFC354CA2EE5D9123B1883FBDC41A0DB3558536B410089013F051EE93C3ADD61500F1A3A37CB403F5378AC3AC40D0022617442EDDCA56B012C17A0A50F33B3C6A2F8BE955F22800C4DA6D65ADB413E87ADE5351FD20BE2BF281ABF8CC8BB78A6723D2B9CDE699BCCD47FB7EBEC2F2EA46B6060EAC9101A4448D2CC4D0C6EA9A1A78CE6528C39CF879B75EDB0F0F84602A1EC66250F1BEA8BB250BE675BF6EFDBEDEB1B97699A8F248B68506BBD4F968CAB83FC8C3AEED661AD3682A6B38ADCF7FE0C7A257C4BD376A56207EA4E0F89DA41460BAA707C74A6670C5953ECCAF324A79DA05116A0493B16BDE9D12DE376ED0DA9A7B9780BD3096633EF40D52D03C5ECCB24630046AF5270657416BD7B2F45EEA86C3019E91A946132621E6E96BCA9C42609390EEBA2D1CD06C47DB2A2FDEFF2788505AD177A07AE04A6549909FBA711F714B1F76054668E119FA19B4830819C5108EB186F95AD1ECA0D91AA79337EBABA0AA0F84487227E6951F537BA293556D43E16DD77DE63FD9702EA9E6FDAA775B4C96A16D8DD35852A9079ACB398792F6E89D56595B3E9340BA56525F270E2E976FB376E77F02CD8231988125030610AE2FCFA69A8FAD3D98122D0E8CEF28E5AA696EE497C0B8C8299B77480095577B78251DB69997A17F148EEC4E89A323BF747EF86D470273B
+20220719182307 2 6 100 8191 2 C5A088686E2057FDD426A4329908C72093AFD4A412B73B7C03574CCFAA7EBA44BF6CF5AD03B49A0AEF8A18CCAF15B0D7B12DEE66078C6A3CCE94DCA05193912A668B6E247962F8CC51046DC6DAF5AE92C169A8F00D116524762DAA1E9FF3F3270F2831FA8C94010DAD76A0032523EB9A610EBBA3BF3EFE82471449768C5B844277FC90486CBC00B6C0EA93DE6067DF863B5F1E5D5BD9781DEB1C5A111AEF62BD8016C4210CB6CA14C45559266711960B7F7FEF20E96391F59D019973FB9EFEE8C198D70EC2080C69EBCCEFA9CE2D93081A47E916F667AFFE28642A8E36133D03A3058D9E65DC0C13959DDC40CFF31B53768D41369CF05EDA59CAA0643949A1ED78B8D2F748A93F3DCE01A22AB1F23EC4E63F7A97D7863907A401633B92A073F62B56FD341B9E2B1497FB139FC2FEBD1F5EEE3A001D9DE86C6F8EBA8DDC0C0504A7A46409D036BB9534BC293BB4D9E77A9A2D0296528266EB6BD8071695F854C4E35912B78E10B2D9574D9F238E7649F998CCA0F2639068B0895E71F79E84BF631367A9221DA5F0C12191EA1CC93CA0D863269E7D25F65D29BC9D70F30B287849533A99D5DA2B8D1337DFA905E46A8673F45028192B297D52CF62C5137E4F7D824EB166CB37FBC393EF1FCC235DCC5D7A224B3A2CF975ADAEA330413E7B6DE83EF6181CBA7AF33575369AD7FBFAD0A6B7211BC3BD8EC3648AB6421D2A9142E95AA6827ACA734A605B88585BF5B30EEC75823DCA57EF524421EFC354CA2EE5D9123B1883FBDC41A0DB3558536B410089013F051EE93C3ADD61500F1A3A37CB403F5378AC3AC40D0022617442EDDCA56B012C17A0A50F33B3C6A2F8BE955F22800C4DA6D65ADB413E87ADE5351FD20BE2BF281ABF8CC8BB78A6723D2B9CDE699BCCD47FB7EBEC2F2EA46B6060EAC9101A4448D2CC4D0C6EA9A1A78CE6528C39CF879B75EDB0F0F84602A1EC66250F1BEA8BB250BE675BF6EFDBEDEB1B97699A8F248B68506BBD4F968CAB83FC8C3AEED661AD3682A6B38ADCF7FE0C7A257C4BD376A56207EA4E0F89DA41460BAA707C74A6670C5953ECCAF324A79DA05116A0493B16BDE9D12DE376ED0DA9A7B9780BD3096633EF40D52D03C5ECCB24630046AF5270657416BD7B2F45EEA86C3019E91A946132621E6E96BCA9C42609390EEBA2D1CD06C47DB2A2FDEFF2788505AD177A07AE04A6549909FBA711F714B1F76054668E119FA19B4830819C5108EB186F95AD1ECA0D91AA79337EBABA0AA0F84487227E6951F537BA293556D43E16DD77DE63FD9702EA9E6FDAA775B4C96A16D8DD35852A9079ACB398792F6E89D56595B3E9340BA56525F270E2E976FB376E77F02CD8231988125030610AE2FCFA69A8FAD3D98122D0E8CEF28E5AA696EE497C0B8C8299B77480095577B78251DB69997A17F148EEC4E89A323BF747EF86D77C4343
+20220719193427 2 6 100 8191 5 C5A088686E2057FDD426A4329908C72093AFD4A412B73B7C03574CCFAA7EBA44BF6CF5AD03B49A0AEF8A18CCAF15B0D7B12DEE66078C6A3CCE94DCA05193912A668B6E247962F8CC51046DC6DAF5AE92C169A8F00D116524762DAA1E9FF3F3270F2831FA8C94010DAD76A0032523EB9A610EBBA3BF3EFE82471449768C5B844277FC90486CBC00B6C0EA93DE6067DF863B5F1E5D5BD9781DEB1C5A111AEF62BD8016C4210CB6CA14C45559266711960B7F7FEF20E96391F59D019973FB9EFEE8C198D70EC2080C69EBCCEFA9CE2D93081A47E916F667AFFE28642A8E36133D03A3058D9E65DC0C13959DDC40CFF31B53768D41369CF05EDA59CAA0643949A1ED78B8D2F748A93F3DCE01A22AB1F23EC4E63F7A97D7863907A401633B92A073F62B56FD341B9E2B1497FB139FC2FEBD1F5EEE3A001D9DE86C6F8EBA8DDC0C0504A7A46409D036BB9534BC293BB4D9E77A9A2D0296528266EB6BD8071695F854C4E35912B78E10B2D9574D9F238E7649F998CCA0F2639068B0895E71F79E84BF631367A9221DA5F0C12191EA1CC93CA0D863269E7D25F65D29BC9D70F30B287849533A99D5DA2B8D1337DFA905E46A8673F45028192B297D52CF62C5137E4F7D824EB166CB37FBC393EF1FCC235DCC5D7A224B3A2CF975ADAEA330413E7B6DE83EF6181CBA7AF33575369AD7FBFAD0A6B7211BC3BD8EC3648AB6421D2A9142E95AA6827ACA734A605B88585BF5B30EEC75823DCA57EF524421EFC354CA2EE5D9123B1883FBDC41A0DB3558536B410089013F051EE93C3ADD61500F1A3A37CB403F5378AC3AC40D0022617442EDDCA56B012C17A0A50F33B3C6A2F8BE955F22800C4DA6D65ADB413E87ADE5351FD20BE2BF281ABF8CC8BB78A6723D2B9CDE699BCCD47FB7EBEC2F2EA46B6060EAC9101A4448D2CC4D0C6EA9A1A78CE6528C39CF879B75EDB0F0F84602A1EC66250F1BEA8BB250BE675BF6EFDBEDEB1B97699A8F248B68506BBD4F968CAB83FC8C3AEED661AD3682A6B38ADCF7FE0C7A257C4BD376A56207EA4E0F89DA41460BAA707C74A6670C5953ECCAF324A79DA05116A0493B16BDE9D12DE376ED0DA9A7B9780BD3096633EF40D52D03C5ECCB24630046AF5270657416BD7B2F45EEA86C3019E91A946132621E6E96BCA9C42609390EEBA2D1CD06C47DB2A2FDEFF2788505AD177A07AE04A6549909FBA711F714B1F76054668E119FA19B4830819C5108EB186F95AD1ECA0D91AA79337EBABA0AA0F84487227E6951F537BA293556D43E16DD77DE63FD9702EA9E6FDAA775B4C96A16D8DD35852A9079ACB398792F6E89D56595B3E9340BA56525F270E2E976FB376E77F02CD8231988125030610AE2FCFA69A8FAD3D98122D0E8CEF28E5AA696EE497C0B8C8299B77480095577B78251DB69997A17F148EEC4E89A323BF747EF86DBAD7B57
+20220719202131 2 6 100 8191 5 C5A088686E2057FDD426A4329908C72093AFD4A412B73B7C03574CCFAA7EBA44BF6CF5AD03B49A0AEF8A18CCAF15B0D7B12DEE66078C6A3CCE94DCA05193912A668B6E247962F8CC51046DC6DAF5AE92C169A8F00D116524762DAA1E9FF3F3270F2831FA8C94010DAD76A0032523EB9A610EBBA3BF3EFE82471449768C5B844277FC90486CBC00B6C0EA93DE6067DF863B5F1E5D5BD9781DEB1C5A111AEF62BD8016C4210CB6CA14C45559266711960B7F7FEF20E96391F59D019973FB9EFEE8C198D70EC2080C69EBCCEFA9CE2D93081A47E916F667AFFE28642A8E36133D03A3058D9E65DC0C13959DDC40CFF31B53768D41369CF05EDA59CAA0643949A1ED78B8D2F748A93F3DCE01A22AB1F23EC4E63F7A97D7863907A401633B92A073F62B56FD341B9E2B1497FB139FC2FEBD1F5EEE3A001D9DE86C6F8EBA8DDC0C0504A7A46409D036BB9534BC293BB4D9E77A9A2D0296528266EB6BD8071695F854C4E35912B78E10B2D9574D9F238E7649F998CCA0F2639068B0895E71F79E84BF631367A9221DA5F0C12191EA1CC93CA0D863269E7D25F65D29BC9D70F30B287849533A99D5DA2B8D1337DFA905E46A8673F45028192B297D52CF62C5137E4F7D824EB166CB37FBC393EF1FCC235DCC5D7A224B3A2CF975ADAEA330413E7B6DE83EF6181CBA7AF33575369AD7FBFAD0A6B7211BC3BD8EC3648AB6421D2A9142E95AA6827ACA734A605B88585BF5B30EEC75823DCA57EF524421EFC354CA2EE5D9123B1883FBDC41A0DB3558536B410089013F051EE93C3ADD61500F1A3A37CB403F5378AC3AC40D0022617442EDDCA56B012C17A0A50F33B3C6A2F8BE955F22800C4DA6D65ADB413E87ADE5351FD20BE2BF281ABF8CC8BB78A6723D2B9CDE699BCCD47FB7EBEC2F2EA46B6060EAC9101A4448D2CC4D0C6EA9A1A78CE6528C39CF879B75EDB0F0F84602A1EC66250F1BEA8BB250BE675BF6EFDBEDEB1B97699A8F248B68506BBD4F968CAB83FC8C3AEED661AD3682A6B38ADCF7FE0C7A257C4BD376A56207EA4E0F89DA41460BAA707C74A6670C5953ECCAF324A79DA05116A0493B16BDE9D12DE376ED0DA9A7B9780BD3096633EF40D52D03C5ECCB24630046AF5270657416BD7B2F45EEA86C3019E91A946132621E6E96BCA9C42609390EEBA2D1CD06C47DB2A2FDEFF2788505AD177A07AE04A6549909FBA711F714B1F76054668E119FA19B4830819C5108EB186F95AD1ECA0D91AA79337EBABA0AA0F84487227E6951F537BA293556D43E16DD77DE63FD9702EA9E6FDAA775B4C96A16D8DD35852A9079ACB398792F6E89D56595B3E9340BA56525F270E2E976FB376E77F02CD8231988125030610AE2FCFA69A8FAD3D98122D0E8CEF28E5AA696EE497C0B8C8299B77480095577B78251DB69997A17F148EEC4E89A323BF747EF86DE7D76A7
+20220719211624 2 6 100 8191 5 C5A088686E2057FDD426A4329908C72093AFD4A412B73B7C03574CCFAA7EBA44BF6CF5AD03B49A0AEF8A18CCAF15B0D7B12DEE66078C6A3CCE94DCA05193912A668B6E247962F8CC51046DC6DAF5AE92C169A8F00D116524762DAA1E9FF3F3270F2831FA8C94010DAD76A0032523EB9A610EBBA3BF3EFE82471449768C5B844277FC90486CBC00B6C0EA93DE6067DF863B5F1E5D5BD9781DEB1C5A111AEF62BD8016C4210CB6CA14C45559266711960B7F7FEF20E96391F59D019973FB9EFEE8C198D70EC2080C69EBCCEFA9CE2D93081A47E916F667AFFE28642A8E36133D03A3058D9E65DC0C13959DDC40CFF31B53768D41369CF05EDA59CAA0643949A1ED78B8D2F748A93F3DCE01A22AB1F23EC4E63F7A97D7863907A401633B92A073F62B56FD341B9E2B1497FB139FC2FEBD1F5EEE3A001D9DE86C6F8EBA8DDC0C0504A7A46409D036BB9534BC293BB4D9E77A9A2D0296528266EB6BD8071695F854C4E35912B78E10B2D9574D9F238E7649F998CCA0F2639068B0895E71F79E84BF631367A9221DA5F0C12191EA1CC93CA0D863269E7D25F65D29BC9D70F30B287849533A99D5DA2B8D1337DFA905E46A8673F45028192B297D52CF62C5137E4F7D824EB166CB37FBC393EF1FCC235DCC5D7A224B3A2CF975ADAEA330413E7B6DE83EF6181CBA7AF33575369AD7FBFAD0A6B7211BC3BD8EC3648AB6421D2A9142E95AA6827ACA734A605B88585BF5B30EEC75823DCA57EF524421EFC354CA2EE5D9123B1883FBDC41A0DB3558536B410089013F051EE93C3ADD61500F1A3A37CB403F5378AC3AC40D0022617442EDDCA56B012C17A0A50F33B3C6A2F8BE955F22800C4DA6D65ADB413E87ADE5351FD20BE2BF281ABF8CC8BB78A6723D2B9CDE699BCCD47FB7EBEC2F2EA46B6060EAC9101A4448D2CC4D0C6EA9A1A78CE6528C39CF879B75EDB0F0F84602A1EC66250F1BEA8BB250BE675BF6EFDBEDEB1B97699A8F248B68506BBD4F968CAB83FC8C3AEED661AD3682A6B38ADCF7FE0C7A257C4BD376A56207EA4E0F89DA41460BAA707C74A6670C5953ECCAF324A79DA05116A0493B16BDE9D12DE376ED0DA9A7B9780BD3096633EF40D52D03C5ECCB24630046AF5270657416BD7B2F45EEA86C3019E91A946132621E6E96BCA9C42609390EEBA2D1CD06C47DB2A2FDEFF2788505AD177A07AE04A6549909FBA711F714B1F76054668E119FA19B4830819C5108EB186F95AD1ECA0D91AA79337EBABA0AA0F84487227E6951F537BA293556D43E16DD77DE63FD9702EA9E6FDAA775B4C96A16D8DD35852A9079ACB398792F6E89D56595B3E9340BA56525F270E2E976FB376E77F02CD8231988125030610AE2FCFA69A8FAD3D98122D0E8CEF28E5AA696EE497C0B8C8299B77480095577B78251DB69997A17F148EEC4E89A323BF747EF86E1C9623F
+20220719211743 2 6 100 8191 5 C5A088686E2057FDD426A4329908C72093AFD4A412B73B7C03574CCFAA7EBA44BF6CF5AD03B49A0AEF8A18CCAF15B0D7B12DEE66078C6A3CCE94DCA05193912A668B6E247962F8CC51046DC6DAF5AE92C169A8F00D116524762DAA1E9FF3F3270F2831FA8C94010DAD76A0032523EB9A610EBBA3BF3EFE82471449768C5B844277FC90486CBC00B6C0EA93DE6067DF863B5F1E5D5BD9781DEB1C5A111AEF62BD8016C4210CB6CA14C45559266711960B7F7FEF20E96391F59D019973FB9EFEE8C198D70EC2080C69EBCCEFA9CE2D93081A47E916F667AFFE28642A8E36133D03A3058D9E65DC0C13959DDC40CFF31B53768D41369CF05EDA59CAA0643949A1ED78B8D2F748A93F3DCE01A22AB1F23EC4E63F7A97D7863907A401633B92A073F62B56FD341B9E2B1497FB139FC2FEBD1F5EEE3A001D9DE86C6F8EBA8DDC0C0504A7A46409D036BB9534BC293BB4D9E77A9A2D0296528266EB6BD8071695F854C4E35912B78E10B2D9574D9F238E7649F998CCA0F2639068B0895E71F79E84BF631367A9221DA5F0C12191EA1CC93CA0D863269E7D25F65D29BC9D70F30B287849533A99D5DA2B8D1337DFA905E46A8673F45028192B297D52CF62C5137E4F7D824EB166CB37FBC393EF1FCC235DCC5D7A224B3A2CF975ADAEA330413E7B6DE83EF6181CBA7AF33575369AD7FBFAD0A6B7211BC3BD8EC3648AB6421D2A9142E95AA6827ACA734A605B88585BF5B30EEC75823DCA57EF524421EFC354CA2EE5D9123B1883FBDC41A0DB3558536B410089013F051EE93C3ADD61500F1A3A37CB403F5378AC3AC40D0022617442EDDCA56B012C17A0A50F33B3C6A2F8BE955F22800C4DA6D65ADB413E87ADE5351FD20BE2BF281ABF8CC8BB78A6723D2B9CDE699BCCD47FB7EBEC2F2EA46B6060EAC9101A4448D2CC4D0C6EA9A1A78CE6528C39CF879B75EDB0F0F84602A1EC66250F1BEA8BB250BE675BF6EFDBEDEB1B97699A8F248B68506BBD4F968CAB83FC8C3AEED661AD3682A6B38ADCF7FE0C7A257C4BD376A56207EA4E0F89DA41460BAA707C74A6670C5953ECCAF324A79DA05116A0493B16BDE9D12DE376ED0DA9A7B9780BD3096633EF40D52D03C5ECCB24630046AF5270657416BD7B2F45EEA86C3019E91A946132621E6E96BCA9C42609390EEBA2D1CD06C47DB2A2FDEFF2788505AD177A07AE04A6549909FBA711F714B1F76054668E119FA19B4830819C5108EB186F95AD1ECA0D91AA79337EBABA0AA0F84487227E6951F537BA293556D43E16DD77DE63FD9702EA9E6FDAA775B4C96A16D8DD35852A9079ACB398792F6E89D56595B3E9340BA56525F270E2E976FB376E77F02CD8231988125030610AE2FCFA69A8FAD3D98122D0E8CEF28E5AA696EE497C0B8C8299B77480095577B78251DB69997A17F148EEC4E89A323BF747EF86E1DE6F77
+20220719222342 2 6 100 8191 5 C5A088686E2057FDD426A4329908C72093AFD4A412B73B7C03574CCFAA7EBA44BF6CF5AD03B49A0AEF8A18CCAF15B0D7B12DEE66078C6A3CCE94DCA05193912A668B6E247962F8CC51046DC6DAF5AE92C169A8F00D116524762DAA1E9FF3F3270F2831FA8C94010DAD76A0032523EB9A610EBBA3BF3EFE82471449768C5B844277FC90486CBC00B6C0EA93DE6067DF863B5F1E5D5BD9781DEB1C5A111AEF62BD8016C4210CB6CA14C45559266711960B7F7FEF20E96391F59D019973FB9EFEE8C198D70EC2080C69EBCCEFA9CE2D93081A47E916F667AFFE28642A8E36133D03A3058D9E65DC0C13959DDC40CFF31B53768D41369CF05EDA59CAA0643949A1ED78B8D2F748A93F3DCE01A22AB1F23EC4E63F7A97D7863907A401633B92A073F62B56FD341B9E2B1497FB139FC2FEBD1F5EEE3A001D9DE86C6F8EBA8DDC0C0504A7A46409D036BB9534BC293BB4D9E77A9A2D0296528266EB6BD8071695F854C4E35912B78E10B2D9574D9F238E7649F998CCA0F2639068B0895E71F79E84BF631367A9221DA5F0C12191EA1CC93CA0D863269E7D25F65D29BC9D70F30B287849533A99D5DA2B8D1337DFA905E46A8673F45028192B297D52CF62C5137E4F7D824EB166CB37FBC393EF1FCC235DCC5D7A224B3A2CF975ADAEA330413E7B6DE83EF6181CBA7AF33575369AD7FBFAD0A6B7211BC3BD8EC3648AB6421D2A9142E95AA6827ACA734A605B88585BF5B30EEC75823DCA57EF524421EFC354CA2EE5D9123B1883FBDC41A0DB3558536B410089013F051EE93C3ADD61500F1A3A37CB403F5378AC3AC40D0022617442EDDCA56B012C17A0A50F33B3C6A2F8BE955F22800C4DA6D65ADB413E87ADE5351FD20BE2BF281ABF8CC8BB78A6723D2B9CDE699BCCD47FB7EBEC2F2EA46B6060EAC9101A4448D2CC4D0C6EA9A1A78CE6528C39CF879B75EDB0F0F84602A1EC66250F1BEA8BB250BE675BF6EFDBEDEB1B97699A8F248B68506BBD4F968CAB83FC8C3AEED661AD3682A6B38ADCF7FE0C7A257C4BD376A56207EA4E0F89DA41460BAA707C74A6670C5953ECCAF324A79DA05116A0493B16BDE9D12DE376ED0DA9A7B9780BD3096633EF40D52D03C5ECCB24630046AF5270657416BD7B2F45EEA86C3019E91A946132621E6E96BCA9C42609390EEBA2D1CD06C47DB2A2FDEFF2788505AD177A07AE04A6549909FBA711F714B1F76054668E119FA19B4830819C5108EB186F95AD1ECA0D91AA79337EBABA0AA0F84487227E6951F537BA293556D43E16DD77DE63FD9702EA9E6FDAA775B4C96A16D8DD35852A9079ACB398792F6E89D56595B3E9340BA56525F270E2E976FB376E77F02CD8231988125030610AE2FCFA69A8FAD3D98122D0E8CEF28E5AA696EE497C0B8C8299B77480095577B78251DB69997A17F148EEC4E89A323BF747EF86E5D38CDF
+20220720003008 2 6 100 8191 5 C5A088686E2057FDD426A4329908C72093AFD4A412B73B7C03574CCFAA7EBA44BF6CF5AD03B49A0AEF8A18CCAF15B0D7B12DEE66078C6A3CCE94DCA05193912A668B6E247962F8CC51046DC6DAF5AE92C169A8F00D116524762DAA1E9FF3F3270F2831FA8C94010DAD76A0032523EB9A610EBBA3BF3EFE82471449768C5B844277FC90486CBC00B6C0EA93DE6067DF863B5F1E5D5BD9781DEB1C5A111AEF62BD8016C4210CB6CA14C45559266711960B7F7FEF20E96391F59D019973FB9EFEE8C198D70EC2080C69EBCCEFA9CE2D93081A47E916F667AFFE28642A8E36133D03A3058D9E65DC0C13959DDC40CFF31B53768D41369CF05EDA59CAA0643949A1ED78B8D2F748A93F3DCE01A22AB1F23EC4E63F7A97D7863907A401633B92A073F62B56FD341B9E2B1497FB139FC2FEBD1F5EEE3A001D9DE86C6F8EBA8DDC0C0504A7A46409D036BB9534BC293BB4D9E77A9A2D0296528266EB6BD8071695F854C4E35912B78E10B2D9574D9F238E7649F998CCA0F2639068B0895E71F79E84BF631367A9221DA5F0C12191EA1CC93CA0D863269E7D25F65D29BC9D70F30B287849533A99D5DA2B8D1337DFA905E46A8673F45028192B297D52CF62C5137E4F7D824EB166CB37FBC393EF1FCC235DCC5D7A224B3A2CF975ADAEA330413E7B6DE83EF6181CBA7AF33575369AD7FBFAD0A6B7211BC3BD8EC3648AB6421D2A9142E95AA6827ACA734A605B88585BF5B30EEC75823DCA57EF524421EFC354CA2EE5D9123B1883FBDC41A0DB3558536B410089013F051EE93C3ADD61500F1A3A37CB403F5378AC3AC40D0022617442EDDCA56B012C17A0A50F33B3C6A2F8BE955F22800C4DA6D65ADB413E87ADE5351FD20BE2BF281ABF8CC8BB78A6723D2B9CDE699BCCD47FB7EBEC2F2EA46B6060EAC9101A4448D2CC4D0C6EA9A1A78CE6528C39CF879B75EDB0F0F84602A1EC66250F1BEA8BB250BE675BF6EFDBEDEB1B97699A8F248B68506BBD4F968CAB83FC8C3AEED661AD3682A6B38ADCF7FE0C7A257C4BD376A56207EA4E0F89DA41460BAA707C74A6670C5953ECCAF324A79DA05116A0493B16BDE9D12DE376ED0DA9A7B9780BD3096633EF40D52D03C5ECCB24630046AF5270657416BD7B2F45EEA86C3019E91A946132621E6E96BCA9C42609390EEBA2D1CD06C47DB2A2FDEFF2788505AD177A07AE04A6549909FBA711F714B1F76054668E119FA19B4830819C5108EB186F95AD1ECA0D91AA79337EBABA0AA0F84487227E6951F537BA293556D43E16DD77DE63FD9702EA9E6FDAA775B4C96A16D8DD35852A9079ACB398792F6E89D56595B3E9340BA56525F270E2E976FB376E77F02CD8231988125030610AE2FCFA69A8FAD3D98122D0E8CEF28E5AA696EE497C0B8C8299B77480095577B78251DB69997A17F148EEC4E89A323BF747EF86ED5B9A6F
+20220720003329 2 6 100 8191 5 C5A088686E2057FDD426A4329908C72093AFD4A412B73B7C03574CCFAA7EBA44BF6CF5AD03B49A0AEF8A18CCAF15B0D7B12DEE66078C6A3CCE94DCA05193912A668B6E247962F8CC51046DC6DAF5AE92C169A8F00D116524762DAA1E9FF3F3270F2831FA8C94010DAD76A0032523EB9A610EBBA3BF3EFE82471449768C5B844277FC90486CBC00B6C0EA93DE6067DF863B5F1E5D5BD9781DEB1C5A111AEF62BD8016C4210CB6CA14C45559266711960B7F7FEF20E96391F59D019973FB9EFEE8C198D70EC2080C69EBCCEFA9CE2D93081A47E916F667AFFE28642A8E36133D03A3058D9E65DC0C13959DDC40CFF31B53768D41369CF05EDA59CAA0643949A1ED78B8D2F748A93F3DCE01A22AB1F23EC4E63F7A97D7863907A401633B92A073F62B56FD341B9E2B1497FB139FC2FEBD1F5EEE3A001D9DE86C6F8EBA8DDC0C0504A7A46409D036BB9534BC293BB4D9E77A9A2D0296528266EB6BD8071695F854C4E35912B78E10B2D9574D9F238E7649F998CCA0F2639068B0895E71F79E84BF631367A9221DA5F0C12191EA1CC93CA0D863269E7D25F65D29BC9D70F30B287849533A99D5DA2B8D1337DFA905E46A8673F45028192B297D52CF62C5137E4F7D824EB166CB37FBC393EF1FCC235DCC5D7A224B3A2CF975ADAEA330413E7B6DE83EF6181CBA7AF33575369AD7FBFAD0A6B7211BC3BD8EC3648AB6421D2A9142E95AA6827ACA734A605B88585BF5B30EEC75823DCA57EF524421EFC354CA2EE5D9123B1883FBDC41A0DB3558536B410089013F051EE93C3ADD61500F1A3A37CB403F5378AC3AC40D0022617442EDDCA56B012C17A0A50F33B3C6A2F8BE955F22800C4DA6D65ADB413E87ADE5351FD20BE2BF281ABF8CC8BB78A6723D2B9CDE699BCCD47FB7EBEC2F2EA46B6060EAC9101A4448D2CC4D0C6EA9A1A78CE6528C39CF879B75EDB0F0F84602A1EC66250F1BEA8BB250BE675BF6EFDBEDEB1B97699A8F248B68506BBD4F968CAB83FC8C3AEED661AD3682A6B38ADCF7FE0C7A257C4BD376A56207EA4E0F89DA41460BAA707C74A6670C5953ECCAF324A79DA05116A0493B16BDE9D12DE376ED0DA9A7B9780BD3096633EF40D52D03C5ECCB24630046AF5270657416BD7B2F45EEA86C3019E91A946132621E6E96BCA9C42609390EEBA2D1CD06C47DB2A2FDEFF2788505AD177A07AE04A6549909FBA711F714B1F76054668E119FA19B4830819C5108EB186F95AD1ECA0D91AA79337EBABA0AA0F84487227E6951F537BA293556D43E16DD77DE63FD9702EA9E6FDAA775B4C96A16D8DD35852A9079ACB398792F6E89D56595B3E9340BA56525F270E2E976FB376E77F02CD8231988125030610AE2FCFA69A8FAD3D98122D0E8CEF28E5AA696EE497C0B8C8299B77480095577B78251DB69997A17F148EEC4E89A323BF747EF86ED8EE32F
+20220720034214 2 6 100 8191 2 C5A088686E2057FDD426A4329908C72093AFD4A412B73B7C03574CCFAA7EBA44BF6CF5AD03B49A0AEF8A18CCAF15B0D7B12DEE66078C6A3CCE94DCA05193912A668B6E247962F8CC51046DC6DAF5AE92C169A8F00D116524762DAA1E9FF3F3270F2831FA8C94010DAD76A0032523EB9A610EBBA3BF3EFE82471449768C5B844277FC90486CBC00B6C0EA93DE6067DF863B5F1E5D5BD9781DEB1C5A111AEF62BD8016C4210CB6CA14C45559266711960B7F7FEF20E96391F59D019973FB9EFEE8C198D70EC2080C69EBCCEFA9CE2D93081A47E916F667AFFE28642A8E36133D03A3058D9E65DC0C13959DDC40CFF31B53768D41369CF05EDA59CAA0643949A1ED78B8D2F748A93F3DCE01A22AB1F23EC4E63F7A97D7863907A401633B92A073F62B56FD341B9E2B1497FB139FC2FEBD1F5EEE3A001D9DE86C6F8EBA8DDC0C0504A7A46409D036BB9534BC293BB4D9E77A9A2D0296528266EB6BD8071695F854C4E35912B78E10B2D9574D9F238E7649F998CCA0F2639068B0895E71F79E84BF631367A9221DA5F0C12191EA1CC93CA0D863269E7D25F65D29BC9D70F30B287849533A99D5DA2B8D1337DFA905E46A8673F45028192B297D52CF62C5137E4F7D824EB166CB37FBC393EF1FCC235DCC5D7A224B3A2CF975ADAEA330413E7B6DE83EF6181CBA7AF33575369AD7FBFAD0A6B7211BC3BD8EC3648AB6421D2A9142E95AA6827ACA734A605B88585BF5B30EEC75823DCA57EF524421EFC354CA2EE5D9123B1883FBDC41A0DB3558536B410089013F051EE93C3ADD61500F1A3A37CB403F5378AC3AC40D0022617442EDDCA56B012C17A0A50F33B3C6A2F8BE955F22800C4DA6D65ADB413E87ADE5351FD20BE2BF281ABF8CC8BB78A6723D2B9CDE699BCCD47FB7EBEC2F2EA46B6060EAC9101A4448D2CC4D0C6EA9A1A78CE6528C39CF879B75EDB0F0F84602A1EC66250F1BEA8BB250BE675BF6EFDBEDEB1B97699A8F248B68506BBD4F968CAB83FC8C3AEED661AD3682A6B38ADCF7FE0C7A257C4BD376A56207EA4E0F89DA41460BAA707C74A6670C5953ECCAF324A79DA05116A0493B16BDE9D12DE376ED0DA9A7B9780BD3096633EF40D52D03C5ECCB24630046AF5270657416BD7B2F45EEA86C3019E91A946132621E6E96BCA9C42609390EEBA2D1CD06C47DB2A2FDEFF2788505AD177A07AE04A6549909FBA711F714B1F76054668E119FA19B4830819C5108EB186F95AD1ECA0D91AA79337EBABA0AA0F84487227E6951F537BA293556D43E16DD77DE63FD9702EA9E6FDAA775B4C96A16D8DD35852A9079ACB398792F6E89D56595B3E9340BA56525F270E2E976FB376E77F02CD8231988125030610AE2FCFA69A8FAD3D98122D0E8CEF28E5AA696EE497C0B8C8299B77480095577B78251DB69997A17F148EEC4E89A323BF747EF86F8B88CAB
+20220720041812 2 6 100 8191 2 C5A088686E2057FDD426A4329908C72093AFD4A412B73B7C03574CCFAA7EBA44BF6CF5AD03B49A0AEF8A18CCAF15B0D7B12DEE66078C6A3CCE94DCA05193912A668B6E247962F8CC51046DC6DAF5AE92C169A8F00D116524762DAA1E9FF3F3270F2831FA8C94010DAD76A0032523EB9A610EBBA3BF3EFE82471449768C5B844277FC90486CBC00B6C0EA93DE6067DF863B5F1E5D5BD9781DEB1C5A111AEF62BD8016C4210CB6CA14C45559266711960B7F7FEF20E96391F59D019973FB9EFEE8C198D70EC2080C69EBCCEFA9CE2D93081A47E916F667AFFE28642A8E36133D03A3058D9E65DC0C13959DDC40CFF31B53768D41369CF05EDA59CAA0643949A1ED78B8D2F748A93F3DCE01A22AB1F23EC4E63F7A97D7863907A401633B92A073F62B56FD341B9E2B1497FB139FC2FEBD1F5EEE3A001D9DE86C6F8EBA8DDC0C0504A7A46409D036BB9534BC293BB4D9E77A9A2D0296528266EB6BD8071695F854C4E35912B78E10B2D9574D9F238E7649F998CCA0F2639068B0895E71F79E84BF631367A9221DA5F0C12191EA1CC93CA0D863269E7D25F65D29BC9D70F30B287849533A99D5DA2B8D1337DFA905E46A8673F45028192B297D52CF62C5137E4F7D824EB166CB37FBC393EF1FCC235DCC5D7A224B3A2CF975ADAEA330413E7B6DE83EF6181CBA7AF33575369AD7FBFAD0A6B7211BC3BD8EC3648AB6421D2A9142E95AA6827ACA734A605B88585BF5B30EEC75823DCA57EF524421EFC354CA2EE5D9123B1883FBDC41A0DB3558536B410089013F051EE93C3ADD61500F1A3A37CB403F5378AC3AC40D0022617442EDDCA56B012C17A0A50F33B3C6A2F8BE955F22800C4DA6D65ADB413E87ADE5351FD20BE2BF281ABF8CC8BB78A6723D2B9CDE699BCCD47FB7EBEC2F2EA46B6060EAC9101A4448D2CC4D0C6EA9A1A78CE6528C39CF879B75EDB0F0F84602A1EC66250F1BEA8BB250BE675BF6EFDBEDEB1B97699A8F248B68506BBD4F968CAB83FC8C3AEED661AD3682A6B38ADCF7FE0C7A257C4BD376A56207EA4E0F89DA41460BAA707C74A6670C5953ECCAF324A79DA05116A0493B16BDE9D12DE376ED0DA9A7B9780BD3096633EF40D52D03C5ECCB24630046AF5270657416BD7B2F45EEA86C3019E91A946132621E6E96BCA9C42609390EEBA2D1CD06C47DB2A2FDEFF2788505AD177A07AE04A6549909FBA711F714B1F76054668E119FA19B4830819C5108EB186F95AD1ECA0D91AA79337EBABA0AA0F84487227E6951F537BA293556D43E16DD77DE63FD9702EA9E6FDAA775B4C96A16D8DD35852A9079ACB398792F6E89D56595B3E9340BA56525F270E2E976FB376E77F02CD8231988125030610AE2FCFA69A8FAD3D98122D0E8CEF28E5AA696EE497C0B8C8299B77480095577B78251DB69997A17F148EEC4E89A323BF747EF86FADD0EF3
+20220720042023 2 6 100 8191 2 C5A088686E2057FDD426A4329908C72093AFD4A412B73B7C03574CCFAA7EBA44BF6CF5AD03B49A0AEF8A18CCAF15B0D7B12DEE66078C6A3CCE94DCA05193912A668B6E247962F8CC51046DC6DAF5AE92C169A8F00D116524762DAA1E9FF3F3270F2831FA8C94010DAD76A0032523EB9A610EBBA3BF3EFE82471449768C5B844277FC90486CBC00B6C0EA93DE6067DF863B5F1E5D5BD9781DEB1C5A111AEF62BD8016C4210CB6CA14C45559266711960B7F7FEF20E96391F59D019973FB9EFEE8C198D70EC2080C69EBCCEFA9CE2D93081A47E916F667AFFE28642A8E36133D03A3058D9E65DC0C13959DDC40CFF31B53768D41369CF05EDA59CAA0643949A1ED78B8D2F748A93F3DCE01A22AB1F23EC4E63F7A97D7863907A401633B92A073F62B56FD341B9E2B1497FB139FC2FEBD1F5EEE3A001D9DE86C6F8EBA8DDC0C0504A7A46409D036BB9534BC293BB4D9E77A9A2D0296528266EB6BD8071695F854C4E35912B78E10B2D9574D9F238E7649F998CCA0F2639068B0895E71F79E84BF631367A9221DA5F0C12191EA1CC93CA0D863269E7D25F65D29BC9D70F30B287849533A99D5DA2B8D1337DFA905E46A8673F45028192B297D52CF62C5137E4F7D824EB166CB37FBC393EF1FCC235DCC5D7A224B3A2CF975ADAEA330413E7B6DE83EF6181CBA7AF33575369AD7FBFAD0A6B7211BC3BD8EC3648AB6421D2A9142E95AA6827ACA734A605B88585BF5B30EEC75823DCA57EF524421EFC354CA2EE5D9123B1883FBDC41A0DB3558536B410089013F051EE93C3ADD61500F1A3A37CB403F5378AC3AC40D0022617442EDDCA56B012C17A0A50F33B3C6A2F8BE955F22800C4DA6D65ADB413E87ADE5351FD20BE2BF281ABF8CC8BB78A6723D2B9CDE699BCCD47FB7EBEC2F2EA46B6060EAC9101A4448D2CC4D0C6EA9A1A78CE6528C39CF879B75EDB0F0F84602A1EC66250F1BEA8BB250BE675BF6EFDBEDEB1B97699A8F248B68506BBD4F968CAB83FC8C3AEED661AD3682A6B38ADCF7FE0C7A257C4BD376A56207EA4E0F89DA41460BAA707C74A6670C5953ECCAF324A79DA05116A0493B16BDE9D12DE376ED0DA9A7B9780BD3096633EF40D52D03C5ECCB24630046AF5270657416BD7B2F45EEA86C3019E91A946132621E6E96BCA9C42609390EEBA2D1CD06C47DB2A2FDEFF2788505AD177A07AE04A6549909FBA711F714B1F76054668E119FA19B4830819C5108EB186F95AD1ECA0D91AA79337EBABA0AA0F84487227E6951F537BA293556D43E16DD77DE63FD9702EA9E6FDAA775B4C96A16D8DD35852A9079ACB398792F6E89D56595B3E9340BA56525F270E2E976FB376E77F02CD8231988125030610AE2FCFA69A8FAD3D98122D0E8CEF28E5AA696EE497C0B8C8299B77480095577B78251DB69997A17F148EEC4E89A323BF747EF86FAFF7543
+20220720044537 2 6 100 8191 5 C5A088686E2057FDD426A4329908C72093AFD4A412B73B7C03574CCFAA7EBA44BF6CF5AD03B49A0AEF8A18CCAF15B0D7B12DEE66078C6A3CCE94DCA05193912A668B6E247962F8CC51046DC6DAF5AE92C169A8F00D116524762DAA1E9FF3F3270F2831FA8C94010DAD76A0032523EB9A610EBBA3BF3EFE82471449768C5B844277FC90486CBC00B6C0EA93DE6067DF863B5F1E5D5BD9781DEB1C5A111AEF62BD8016C4210CB6CA14C45559266711960B7F7FEF20E96391F59D019973FB9EFEE8C198D70EC2080C69EBCCEFA9CE2D93081A47E916F667AFFE28642A8E36133D03A3058D9E65DC0C13959DDC40CFF31B53768D41369CF05EDA59CAA0643949A1ED78B8D2F748A93F3DCE01A22AB1F23EC4E63F7A97D7863907A401633B92A073F62B56FD341B9E2B1497FB139FC2FEBD1F5EEE3A001D9DE86C6F8EBA8DDC0C0504A7A46409D036BB9534BC293BB4D9E77A9A2D0296528266EB6BD8071695F854C4E35912B78E10B2D9574D9F238E7649F998CCA0F2639068B0895E71F79E84BF631367A9221DA5F0C12191EA1CC93CA0D863269E7D25F65D29BC9D70F30B287849533A99D5DA2B8D1337DFA905E46A8673F45028192B297D52CF62C5137E4F7D824EB166CB37FBC393EF1FCC235DCC5D7A224B3A2CF975ADAEA330413E7B6DE83EF6181CBA7AF33575369AD7FBFAD0A6B7211BC3BD8EC3648AB6421D2A9142E95AA6827ACA734A605B88585BF5B30EEC75823DCA57EF524421EFC354CA2EE5D9123B1883FBDC41A0DB3558536B410089013F051EE93C3ADD61500F1A3A37CB403F5378AC3AC40D0022617442EDDCA56B012C17A0A50F33B3C6A2F8BE955F22800C4DA6D65ADB413E87ADE5351FD20BE2BF281ABF8CC8BB78A6723D2B9CDE699BCCD47FB7EBEC2F2EA46B6060EAC9101A4448D2CC4D0C6EA9A1A78CE6528C39CF879B75EDB0F0F84602A1EC66250F1BEA8BB250BE675BF6EFDBEDEB1B97699A8F248B68506BBD4F968CAB83FC8C3AEED661AD3682A6B38ADCF7FE0C7A257C4BD376A56207EA4E0F89DA41460BAA707C74A6670C5953ECCAF324A79DA05116A0493B16BDE9D12DE376ED0DA9A7B9780BD3096633EF40D52D03C5ECCB24630046AF5270657416BD7B2F45EEA86C3019E91A946132621E6E96BCA9C42609390EEBA2D1CD06C47DB2A2FDEFF2788505AD177A07AE04A6549909FBA711F714B1F76054668E119FA19B4830819C5108EB186F95AD1ECA0D91AA79337EBABA0AA0F84487227E6951F537BA293556D43E16DD77DE63FD9702EA9E6FDAA775B4C96A16D8DD35852A9079ACB398792F6E89D56595B3E9340BA56525F270E2E976FB376E77F02CD8231988125030610AE2FCFA69A8FAD3D98122D0E8CEF28E5AA696EE497C0B8C8299B77480095577B78251DB69997A17F148EEC4E89A323BF747EF86FC7D0CB7
+20220720045239 2 6 100 8191 2 C5A088686E2057FDD426A4329908C72093AFD4A412B73B7C03574CCFAA7EBA44BF6CF5AD03B49A0AEF8A18CCAF15B0D7B12DEE66078C6A3CCE94DCA05193912A668B6E247962F8CC51046DC6DAF5AE92C169A8F00D116524762DAA1E9FF3F3270F2831FA8C94010DAD76A0032523EB9A610EBBA3BF3EFE82471449768C5B844277FC90486CBC00B6C0EA93DE6067DF863B5F1E5D5BD9781DEB1C5A111AEF62BD8016C4210CB6CA14C45559266711960B7F7FEF20E96391F59D019973FB9EFEE8C198D70EC2080C69EBCCEFA9CE2D93081A47E916F667AFFE28642A8E36133D03A3058D9E65DC0C13959DDC40CFF31B53768D41369CF05EDA59CAA0643949A1ED78B8D2F748A93F3DCE01A22AB1F23EC4E63F7A97D7863907A401633B92A073F62B56FD341B9E2B1497FB139FC2FEBD1F5EEE3A001D9DE86C6F8EBA8DDC0C0504A7A46409D036BB9534BC293BB4D9E77A9A2D0296528266EB6BD8071695F854C4E35912B78E10B2D9574D9F238E7649F998CCA0F2639068B0895E71F79E84BF631367A9221DA5F0C12191EA1CC93CA0D863269E7D25F65D29BC9D70F30B287849533A99D5DA2B8D1337DFA905E46A8673F45028192B297D52CF62C5137E4F7D824EB166CB37FBC393EF1FCC235DCC5D7A224B3A2CF975ADAEA330413E7B6DE83EF6181CBA7AF33575369AD7FBFAD0A6B7211BC3BD8EC3648AB6421D2A9142E95AA6827ACA734A605B88585BF5B30EEC75823DCA57EF524421EFC354CA2EE5D9123B1883FBDC41A0DB3558536B410089013F051EE93C3ADD61500F1A3A37CB403F5378AC3AC40D0022617442EDDCA56B012C17A0A50F33B3C6A2F8BE955F22800C4DA6D65ADB413E87ADE5351FD20BE2BF281ABF8CC8BB78A6723D2B9CDE699BCCD47FB7EBEC2F2EA46B6060EAC9101A4448D2CC4D0C6EA9A1A78CE6528C39CF879B75EDB0F0F84602A1EC66250F1BEA8BB250BE675BF6EFDBEDEB1B97699A8F248B68506BBD4F968CAB83FC8C3AEED661AD3682A6B38ADCF7FE0C7A257C4BD376A56207EA4E0F89DA41460BAA707C74A6670C5953ECCAF324A79DA05116A0493B16BDE9D12DE376ED0DA9A7B9780BD3096633EF40D52D03C5ECCB24630046AF5270657416BD7B2F45EEA86C3019E91A946132621E6E96BCA9C42609390EEBA2D1CD06C47DB2A2FDEFF2788505AD177A07AE04A6549909FBA711F714B1F76054668E119FA19B4830819C5108EB186F95AD1ECA0D91AA79337EBABA0AA0F84487227E6951F537BA293556D43E16DD77DE63FD9702EA9E6FDAA775B4C96A16D8DD35852A9079ACB398792F6E89D56595B3E9340BA56525F270E2E976FB376E77F02CD8231988125030610AE2FCFA69A8FAD3D98122D0E8CEF28E5AA696EE497C0B8C8299B77480095577B78251DB69997A17F148EEC4E89A323BF747EF86FCE7D05B
+20220720055829 2 6 100 8191 2 C5A088686E2057FDD426A4329908C72093AFD4A412B73B7C03574CCFAA7EBA44BF6CF5AD03B49A0AEF8A18CCAF15B0D7B12DEE66078C6A3CCE94DCA05193912A668B6E247962F8CC51046DC6DAF5AE92C169A8F00D116524762DAA1E9FF3F3270F2831FA8C94010DAD76A0032523EB9A610EBBA3BF3EFE82471449768C5B844277FC90486CBC00B6C0EA93DE6067DF863B5F1E5D5BD9781DEB1C5A111AEF62BD8016C4210CB6CA14C45559266711960B7F7FEF20E96391F59D019973FB9EFEE8C198D70EC2080C69EBCCEFA9CE2D93081A47E916F667AFFE28642A8E36133D03A3058D9E65DC0C13959DDC40CFF31B53768D41369CF05EDA59CAA0643949A1ED78B8D2F748A93F3DCE01A22AB1F23EC4E63F7A97D7863907A401633B92A073F62B56FD341B9E2B1497FB139FC2FEBD1F5EEE3A001D9DE86C6F8EBA8DDC0C0504A7A46409D036BB9534BC293BB4D9E77A9A2D0296528266EB6BD8071695F854C4E35912B78E10B2D9574D9F238E7649F998CCA0F2639068B0895E71F79E84BF631367A9221DA5F0C12191EA1CC93CA0D863269E7D25F65D29BC9D70F30B287849533A99D5DA2B8D1337DFA905E46A8673F45028192B297D52CF62C5137E4F7D824EB166CB37FBC393EF1FCC235DCC5D7A224B3A2CF975ADAEA330413E7B6DE83EF6181CBA7AF33575369AD7FBFAD0A6B7211BC3BD8EC3648AB6421D2A9142E95AA6827ACA734A605B88585BF5B30EEC75823DCA57EF524421EFC354CA2EE5D9123B1883FBDC41A0DB3558536B410089013F051EE93C3ADD61500F1A3A37CB403F5378AC3AC40D0022617442EDDCA56B012C17A0A50F33B3C6A2F8BE955F22800C4DA6D65ADB413E87ADE5351FD20BE2BF281ABF8CC8BB78A6723D2B9CDE699BCCD47FB7EBEC2F2EA46B6060EAC9101A4448D2CC4D0C6EA9A1A78CE6528C39CF879B75EDB0F0F84602A1EC66250F1BEA8BB250BE675BF6EFDBEDEB1B97699A8F248B68506BBD4F968CAB83FC8C3AEED661AD3682A6B38ADCF7FE0C7A257C4BD376A56207EA4E0F89DA41460BAA707C74A6670C5953ECCAF324A79DA05116A0493B16BDE9D12DE376ED0DA9A7B9780BD3096633EF40D52D03C5ECCB24630046AF5270657416BD7B2F45EEA86C3019E91A946132621E6E96BCA9C42609390EEBA2D1CD06C47DB2A2FDEFF2788505AD177A07AE04A6549909FBA711F714B1F76054668E119FA19B4830819C5108EB186F95AD1ECA0D91AA79337EBABA0AA0F84487227E6951F537BA293556D43E16DD77DE63FD9702EA9E6FDAA775B4C96A16D8DD35852A9079ACB398792F6E89D56595B3E9340BA56525F270E2E976FB376E77F02CD8231988125030610AE2FCFA69A8FAD3D98122D0E8CEF28E5AA696EE497C0B8C8299B77480095577B78251DB69997A17F148EEC4E89A323BF747EF8700DC7CB3
+20220720061526 2 6 100 8191 5 C5A088686E2057FDD426A4329908C72093AFD4A412B73B7C03574CCFAA7EBA44BF6CF5AD03B49A0AEF8A18CCAF15B0D7B12DEE66078C6A3CCE94DCA05193912A668B6E247962F8CC51046DC6DAF5AE92C169A8F00D116524762DAA1E9FF3F3270F2831FA8C94010DAD76A0032523EB9A610EBBA3BF3EFE82471449768C5B844277FC90486CBC00B6C0EA93DE6067DF863B5F1E5D5BD9781DEB1C5A111AEF62BD8016C4210CB6CA14C45559266711960B7F7FEF20E96391F59D019973FB9EFEE8C198D70EC2080C69EBCCEFA9CE2D93081A47E916F667AFFE28642A8E36133D03A3058D9E65DC0C13959DDC40CFF31B53768D41369CF05EDA59CAA0643949A1ED78B8D2F748A93F3DCE01A22AB1F23EC4E63F7A97D7863907A401633B92A073F62B56FD341B9E2B1497FB139FC2FEBD1F5EEE3A001D9DE86C6F8EBA8DDC0C0504A7A46409D036BB9534BC293BB4D9E77A9A2D0296528266EB6BD8071695F854C4E35912B78E10B2D9574D9F238E7649F998CCA0F2639068B0895E71F79E84BF631367A9221DA5F0C12191EA1CC93CA0D863269E7D25F65D29BC9D70F30B287849533A99D5DA2B8D1337DFA905E46A8673F45028192B297D52CF62C5137E4F7D824EB166CB37FBC393EF1FCC235DCC5D7A224B3A2CF975ADAEA330413E7B6DE83EF6181CBA7AF33575369AD7FBFAD0A6B7211BC3BD8EC3648AB6421D2A9142E95AA6827ACA734A605B88585BF5B30EEC75823DCA57EF524421EFC354CA2EE5D9123B1883FBDC41A0DB3558536B410089013F051EE93C3ADD61500F1A3A37CB403F5378AC3AC40D0022617442EDDCA56B012C17A0A50F33B3C6A2F8BE955F22800C4DA6D65ADB413E87ADE5351FD20BE2BF281ABF8CC8BB78A6723D2B9CDE699BCCD47FB7EBEC2F2EA46B6060EAC9101A4448D2CC4D0C6EA9A1A78CE6528C39CF879B75EDB0F0F84602A1EC66250F1BEA8BB250BE675BF6EFDBEDEB1B97699A8F248B68506BBD4F968CAB83FC8C3AEED661AD3682A6B38ADCF7FE0C7A257C4BD376A56207EA4E0F89DA41460BAA707C74A6670C5953ECCAF324A79DA05116A0493B16BDE9D12DE376ED0DA9A7B9780BD3096633EF40D52D03C5ECCB24630046AF5270657416BD7B2F45EEA86C3019E91A946132621E6E96BCA9C42609390EEBA2D1CD06C47DB2A2FDEFF2788505AD177A07AE04A6549909FBA711F714B1F76054668E119FA19B4830819C5108EB186F95AD1ECA0D91AA79337EBABA0AA0F84487227E6951F537BA293556D43E16DD77DE63FD9702EA9E6FDAA775B4C96A16D8DD35852A9079ACB398792F6E89D56595B3E9340BA56525F270E2E976FB376E77F02CD8231988125030610AE2FCFA69A8FAD3D98122D0E8CEF28E5AA696EE497C0B8C8299B77480095577B78251DB69997A17F148EEC4E89A323BF747EF8701E01D2F
+20220720071915 2 6 100 8191 2 C5A088686E2057FDD426A4329908C72093AFD4A412B73B7C03574CCFAA7EBA44BF6CF5AD03B49A0AEF8A18CCAF15B0D7B12DEE66078C6A3CCE94DCA05193912A668B6E247962F8CC51046DC6DAF5AE92C169A8F00D116524762DAA1E9FF3F3270F2831FA8C94010DAD76A0032523EB9A610EBBA3BF3EFE82471449768C5B844277FC90486CBC00B6C0EA93DE6067DF863B5F1E5D5BD9781DEB1C5A111AEF62BD8016C4210CB6CA14C45559266711960B7F7FEF20E96391F59D019973FB9EFEE8C198D70EC2080C69EBCCEFA9CE2D93081A47E916F667AFFE28642A8E36133D03A3058D9E65DC0C13959DDC40CFF31B53768D41369CF05EDA59CAA0643949A1ED78B8D2F748A93F3DCE01A22AB1F23EC4E63F7A97D7863907A401633B92A073F62B56FD341B9E2B1497FB139FC2FEBD1F5EEE3A001D9DE86C6F8EBA8DDC0C0504A7A46409D036BB9534BC293BB4D9E77A9A2D0296528266EB6BD8071695F854C4E35912B78E10B2D9574D9F238E7649F998CCA0F2639068B0895E71F79E84BF631367A9221DA5F0C12191EA1CC93CA0D863269E7D25F65D29BC9D70F30B287849533A99D5DA2B8D1337DFA905E46A8673F45028192B297D52CF62C5137E4F7D824EB166CB37FBC393EF1FCC235DCC5D7A224B3A2CF975ADAEA330413E7B6DE83EF6181CBA7AF33575369AD7FBFAD0A6B7211BC3BD8EC3648AB6421D2A9142E95AA6827ACA734A605B88585BF5B30EEC75823DCA57EF524421EFC354CA2EE5D9123B1883FBDC41A0DB3558536B410089013F051EE93C3ADD61500F1A3A37CB403F5378AC3AC40D0022617442EDDCA56B012C17A0A50F33B3C6A2F8BE955F22800C4DA6D65ADB413E87ADE5351FD20BE2BF281ABF8CC8BB78A6723D2B9CDE699BCCD47FB7EBEC2F2EA46B6060EAC9101A4448D2CC4D0C6EA9A1A78CE6528C39CF879B75EDB0F0F84602A1EC66250F1BEA8BB250BE675BF6EFDBEDEB1B97699A8F248B68506BBD4F968CAB83FC8C3AEED661AD3682A6B38ADCF7FE0C7A257C4BD376A56207EA4E0F89DA41460BAA707C74A6670C5953ECCAF324A79DA05116A0493B16BDE9D12DE376ED0DA9A7B9780BD3096633EF40D52D03C5ECCB24630046AF5270657416BD7B2F45EEA86C3019E91A946132621E6E96BCA9C42609390EEBA2D1CD06C47DB2A2FDEFF2788505AD177A07AE04A6549909FBA711F714B1F76054668E119FA19B4830819C5108EB186F95AD1ECA0D91AA79337EBABA0AA0F84487227E6951F537BA293556D43E16DD77DE63FD9702EA9E6FDAA775B4C96A16D8DD35852A9079ACB398792F6E89D56595B3E9340BA56525F270E2E976FB376E77F02CD8231988125030610AE2FCFA69A8FAD3D98122D0E8CEF28E5AA696EE497C0B8C8299B77480095577B78251DB69997A17F148EEC4E89A323BF747EF8705ABB603
+20220720080553 2 6 100 8191 5 C5A088686E2057FDD426A4329908C72093AFD4A412B73B7C03574CCFAA7EBA44BF6CF5AD03B49A0AEF8A18CCAF15B0D7B12DEE66078C6A3CCE94DCA05193912A668B6E247962F8CC51046DC6DAF5AE92C169A8F00D116524762DAA1E9FF3F3270F2831FA8C94010DAD76A0032523EB9A610EBBA3BF3EFE82471449768C5B844277FC90486CBC00B6C0EA93DE6067DF863B5F1E5D5BD9781DEB1C5A111AEF62BD8016C4210CB6CA14C45559266711960B7F7FEF20E96391F59D019973FB9EFEE8C198D70EC2080C69EBCCEFA9CE2D93081A47E916F667AFFE28642A8E36133D03A3058D9E65DC0C13959DDC40CFF31B53768D41369CF05EDA59CAA0643949A1ED78B8D2F748A93F3DCE01A22AB1F23EC4E63F7A97D7863907A401633B92A073F62B56FD341B9E2B1497FB139FC2FEBD1F5EEE3A001D9DE86C6F8EBA8DDC0C0504A7A46409D036BB9534BC293BB4D9E77A9A2D0296528266EB6BD8071695F854C4E35912B78E10B2D9574D9F238E7649F998CCA0F2639068B0895E71F79E84BF631367A9221DA5F0C12191EA1CC93CA0D863269E7D25F65D29BC9D70F30B287849533A99D5DA2B8D1337DFA905E46A8673F45028192B297D52CF62C5137E4F7D824EB166CB37FBC393EF1FCC235DCC5D7A224B3A2CF975ADAEA330413E7B6DE83EF6181CBA7AF33575369AD7FBFAD0A6B7211BC3BD8EC3648AB6421D2A9142E95AA6827ACA734A605B88585BF5B30EEC75823DCA57EF524421EFC354CA2EE5D9123B1883FBDC41A0DB3558536B410089013F051EE93C3ADD61500F1A3A37CB403F5378AC3AC40D0022617442EDDCA56B012C17A0A50F33B3C6A2F8BE955F22800C4DA6D65ADB413E87ADE5351FD20BE2BF281ABF8CC8BB78A6723D2B9CDE699BCCD47FB7EBEC2F2EA46B6060EAC9101A4448D2CC4D0C6EA9A1A78CE6528C39CF879B75EDB0F0F84602A1EC66250F1BEA8BB250BE675BF6EFDBEDEB1B97699A8F248B68506BBD4F968CAB83FC8C3AEED661AD3682A6B38ADCF7FE0C7A257C4BD376A56207EA4E0F89DA41460BAA707C74A6670C5953ECCAF324A79DA05116A0493B16BDE9D12DE376ED0DA9A7B9780BD3096633EF40D52D03C5ECCB24630046AF5270657416BD7B2F45EEA86C3019E91A946132621E6E96BCA9C42609390EEBA2D1CD06C47DB2A2FDEFF2788505AD177A07AE04A6549909FBA711F714B1F76054668E119FA19B4830819C5108EB186F95AD1ECA0D91AA79337EBABA0AA0F84487227E6951F537BA293556D43E16DD77DE63FD9702EA9E6FDAA775B4C96A16D8DD35852A9079ACB398792F6E89D56595B3E9340BA56525F270E2E976FB376E77F02CD8231988125030610AE2FCFA69A8FAD3D98122D0E8CEF28E5AA696EE497C0B8C8299B77480095577B78251DB69997A17F148EEC4E89A323BF747EF870876A9CF
+20220720093358 2 6 100 8191 5 C5A088686E2057FDD426A4329908C72093AFD4A412B73B7C03574CCFAA7EBA44BF6CF5AD03B49A0AEF8A18CCAF15B0D7B12DEE66078C6A3CCE94DCA05193912A668B6E247962F8CC51046DC6DAF5AE92C169A8F00D116524762DAA1E9FF3F3270F2831FA8C94010DAD76A0032523EB9A610EBBA3BF3EFE82471449768C5B844277FC90486CBC00B6C0EA93DE6067DF863B5F1E5D5BD9781DEB1C5A111AEF62BD8016C4210CB6CA14C45559266711960B7F7FEF20E96391F59D019973FB9EFEE8C198D70EC2080C69EBCCEFA9CE2D93081A47E916F667AFFE28642A8E36133D03A3058D9E65DC0C13959DDC40CFF31B53768D41369CF05EDA59CAA0643949A1ED78B8D2F748A93F3DCE01A22AB1F23EC4E63F7A97D7863907A401633B92A073F62B56FD341B9E2B1497FB139FC2FEBD1F5EEE3A001D9DE86C6F8EBA8DDC0C0504A7A46409D036BB9534BC293BB4D9E77A9A2D0296528266EB6BD8071695F854C4E35912B78E10B2D9574D9F238E7649F998CCA0F2639068B0895E71F79E84BF631367A9221DA5F0C12191EA1CC93CA0D863269E7D25F65D29BC9D70F30B287849533A99D5DA2B8D1337DFA905E46A8673F45028192B297D52CF62C5137E4F7D824EB166CB37FBC393EF1FCC235DCC5D7A224B3A2CF975ADAEA330413E7B6DE83EF6181CBA7AF33575369AD7FBFAD0A6B7211BC3BD8EC3648AB6421D2A9142E95AA6827ACA734A605B88585BF5B30EEC75823DCA57EF524421EFC354CA2EE5D9123B1883FBDC41A0DB3558536B410089013F051EE93C3ADD61500F1A3A37CB403F5378AC3AC40D0022617442EDDCA56B012C17A0A50F33B3C6A2F8BE955F22800C4DA6D65ADB413E87ADE5351FD20BE2BF281ABF8CC8BB78A6723D2B9CDE699BCCD47FB7EBEC2F2EA46B6060EAC9101A4448D2CC4D0C6EA9A1A78CE6528C39CF879B75EDB0F0F84602A1EC66250F1BEA8BB250BE675BF6EFDBEDEB1B97699A8F248B68506BBD4F968CAB83FC8C3AEED661AD3682A6B38ADCF7FE0C7A257C4BD376A56207EA4E0F89DA41460BAA707C74A6670C5953ECCAF324A79DA05116A0493B16BDE9D12DE376ED0DA9A7B9780BD3096633EF40D52D03C5ECCB24630046AF5270657416BD7B2F45EEA86C3019E91A946132621E6E96BCA9C42609390EEBA2D1CD06C47DB2A2FDEFF2788505AD177A07AE04A6549909FBA711F714B1F76054668E119FA19B4830819C5108EB186F95AD1ECA0D91AA79337EBABA0AA0F84487227E6951F537BA293556D43E16DD77DE63FD9702EA9E6FDAA775B4C96A16D8DD35852A9079ACB398792F6E89D56595B3E9340BA56525F270E2E976FB376E77F02CD8231988125030610AE2FCFA69A8FAD3D98122D0E8CEF28E5AA696EE497C0B8C8299B77480095577B78251DB69997A17F148EEC4E89A323BF747EF870DC82DC7
+20220720094947 2 6 100 8191 5 C5A088686E2057FDD426A4329908C72093AFD4A412B73B7C03574CCFAA7EBA44BF6CF5AD03B49A0AEF8A18CCAF15B0D7B12DEE66078C6A3CCE94DCA05193912A668B6E247962F8CC51046DC6DAF5AE92C169A8F00D116524762DAA1E9FF3F3270F2831FA8C94010DAD76A0032523EB9A610EBBA3BF3EFE82471449768C5B844277FC90486CBC00B6C0EA93DE6067DF863B5F1E5D5BD9781DEB1C5A111AEF62BD8016C4210CB6CA14C45559266711960B7F7FEF20E96391F59D019973FB9EFEE8C198D70EC2080C69EBCCEFA9CE2D93081A47E916F667AFFE28642A8E36133D03A3058D9E65DC0C13959DDC40CFF31B53768D41369CF05EDA59CAA0643949A1ED78B8D2F748A93F3DCE01A22AB1F23EC4E63F7A97D7863907A401633B92A073F62B56FD341B9E2B1497FB139FC2FEBD1F5EEE3A001D9DE86C6F8EBA8DDC0C0504A7A46409D036BB9534BC293BB4D9E77A9A2D0296528266EB6BD8071695F854C4E35912B78E10B2D9574D9F238E7649F998CCA0F2639068B0895E71F79E84BF631367A9221DA5F0C12191EA1CC93CA0D863269E7D25F65D29BC9D70F30B287849533A99D5DA2B8D1337DFA905E46A8673F45028192B297D52CF62C5137E4F7D824EB166CB37FBC393EF1FCC235DCC5D7A224B3A2CF975ADAEA330413E7B6DE83EF6181CBA7AF33575369AD7FBFAD0A6B7211BC3BD8EC3648AB6421D2A9142E95AA6827ACA734A605B88585BF5B30EEC75823DCA57EF524421EFC354CA2EE5D9123B1883FBDC41A0DB3558536B410089013F051EE93C3ADD61500F1A3A37CB403F5378AC3AC40D0022617442EDDCA56B012C17A0A50F33B3C6A2F8BE955F22800C4DA6D65ADB413E87ADE5351FD20BE2BF281ABF8CC8BB78A6723D2B9CDE699BCCD47FB7EBEC2F2EA46B6060EAC9101A4448D2CC4D0C6EA9A1A78CE6528C39CF879B75EDB0F0F84602A1EC66250F1BEA8BB250BE675BF6EFDBEDEB1B97699A8F248B68506BBD4F968CAB83FC8C3AEED661AD3682A6B38ADCF7FE0C7A257C4BD376A56207EA4E0F89DA41460BAA707C74A6670C5953ECCAF324A79DA05116A0493B16BDE9D12DE376ED0DA9A7B9780BD3096633EF40D52D03C5ECCB24630046AF5270657416BD7B2F45EEA86C3019E91A946132621E6E96BCA9C42609390EEBA2D1CD06C47DB2A2FDEFF2788505AD177A07AE04A6549909FBA711F714B1F76054668E119FA19B4830819C5108EB186F95AD1ECA0D91AA79337EBABA0AA0F84487227E6951F537BA293556D43E16DD77DE63FD9702EA9E6FDAA775B4C96A16D8DD35852A9079ACB398792F6E89D56595B3E9340BA56525F270E2E976FB376E77F02CD8231988125030610AE2FCFA69A8FAD3D98122D0E8CEF28E5AA696EE497C0B8C8299B77480095577B78251DB69997A17F148EEC4E89A323BF747EF870EBB9097
+20220720110223 2 6 100 8191 5 C5A088686E2057FDD426A4329908C72093AFD4A412B73B7C03574CCFAA7EBA44BF6CF5AD03B49A0AEF8A18CCAF15B0D7B12DEE66078C6A3CCE94DCA05193912A668B6E247962F8CC51046DC6DAF5AE92C169A8F00D116524762DAA1E9FF3F3270F2831FA8C94010DAD76A0032523EB9A610EBBA3BF3EFE82471449768C5B844277FC90486CBC00B6C0EA93DE6067DF863B5F1E5D5BD9781DEB1C5A111AEF62BD8016C4210CB6CA14C45559266711960B7F7FEF20E96391F59D019973FB9EFEE8C198D70EC2080C69EBCCEFA9CE2D93081A47E916F667AFFE28642A8E36133D03A3058D9E65DC0C13959DDC40CFF31B53768D41369CF05EDA59CAA0643949A1ED78B8D2F748A93F3DCE01A22AB1F23EC4E63F7A97D7863907A401633B92A073F62B56FD341B9E2B1497FB139FC2FEBD1F5EEE3A001D9DE86C6F8EBA8DDC0C0504A7A46409D036BB9534BC293BB4D9E77A9A2D0296528266EB6BD8071695F854C4E35912B78E10B2D9574D9F238E7649F998CCA0F2639068B0895E71F79E84BF631367A9221DA5F0C12191EA1CC93CA0D863269E7D25F65D29BC9D70F30B287849533A99D5DA2B8D1337DFA905E46A8673F45028192B297D52CF62C5137E4F7D824EB166CB37FBC393EF1FCC235DCC5D7A224B3A2CF975ADAEA330413E7B6DE83EF6181CBA7AF33575369AD7FBFAD0A6B7211BC3BD8EC3648AB6421D2A9142E95AA6827ACA734A605B88585BF5B30EEC75823DCA57EF524421EFC354CA2EE5D9123B1883FBDC41A0DB3558536B410089013F051EE93C3ADD61500F1A3A37CB403F5378AC3AC40D0022617442EDDCA56B012C17A0A50F33B3C6A2F8BE955F22800C4DA6D65ADB413E87ADE5351FD20BE2BF281ABF8CC8BB78A6723D2B9CDE699BCCD47FB7EBEC2F2EA46B6060EAC9101A4448D2CC4D0C6EA9A1A78CE6528C39CF879B75EDB0F0F84602A1EC66250F1BEA8BB250BE675BF6EFDBEDEB1B97699A8F248B68506BBD4F968CAB83FC8C3AEED661AD3682A6B38ADCF7FE0C7A257C4BD376A56207EA4E0F89DA41460BAA707C74A6670C5953ECCAF324A79DA05116A0493B16BDE9D12DE376ED0DA9A7B9780BD3096633EF40D52D03C5ECCB24630046AF5270657416BD7B2F45EEA86C3019E91A946132621E6E96BCA9C42609390EEBA2D1CD06C47DB2A2FDEFF2788505AD177A07AE04A6549909FBA711F714B1F76054668E119FA19B4830819C5108EB186F95AD1ECA0D91AA79337EBABA0AA0F84487227E6951F537BA293556D43E16DD77DE63FD9702EA9E6FDAA775B4C96A16D8DD35852A9079ACB398792F6E89D56595B3E9340BA56525F270E2E976FB376E77F02CD8231988125030610AE2FCFA69A8FAD3D98122D0E8CEF28E5AA696EE497C0B8C8299B77480095577B78251DB69997A17F148EEC4E89A323BF747EF871329D297
+20220720112240 2 6 100 8191 2 C5A088686E2057FDD426A4329908C72093AFD4A412B73B7C03574CCFAA7EBA44BF6CF5AD03B49A0AEF8A18CCAF15B0D7B12DEE66078C6A3CCE94DCA05193912A668B6E247962F8CC51046DC6DAF5AE92C169A8F00D116524762DAA1E9FF3F3270F2831FA8C94010DAD76A0032523EB9A610EBBA3BF3EFE82471449768C5B844277FC90486CBC00B6C0EA93DE6067DF863B5F1E5D5BD9781DEB1C5A111AEF62BD8016C4210CB6CA14C45559266711960B7F7FEF20E96391F59D019973FB9EFEE8C198D70EC2080C69EBCCEFA9CE2D93081A47E916F667AFFE28642A8E36133D03A3058D9E65DC0C13959DDC40CFF31B53768D41369CF05EDA59CAA0643949A1ED78B8D2F748A93F3DCE01A22AB1F23EC4E63F7A97D7863907A401633B92A073F62B56FD341B9E2B1497FB139FC2FEBD1F5EEE3A001D9DE86C6F8EBA8DDC0C0504A7A46409D036BB9534BC293BB4D9E77A9A2D0296528266EB6BD8071695F854C4E35912B78E10B2D9574D9F238E7649F998CCA0F2639068B0895E71F79E84BF631367A9221DA5F0C12191EA1CC93CA0D863269E7D25F65D29BC9D70F30B287849533A99D5DA2B8D1337DFA905E46A8673F45028192B297D52CF62C5137E4F7D824EB166CB37FBC393EF1FCC235DCC5D7A224B3A2CF975ADAEA330413E7B6DE83EF6181CBA7AF33575369AD7FBFAD0A6B7211BC3BD8EC3648AB6421D2A9142E95AA6827ACA734A605B88585BF5B30EEC75823DCA57EF524421EFC354CA2EE5D9123B1883FBDC41A0DB3558536B410089013F051EE93C3ADD61500F1A3A37CB403F5378AC3AC40D0022617442EDDCA56B012C17A0A50F33B3C6A2F8BE955F22800C4DA6D65ADB413E87ADE5351FD20BE2BF281ABF8CC8BB78A6723D2B9CDE699BCCD47FB7EBEC2F2EA46B6060EAC9101A4448D2CC4D0C6EA9A1A78CE6528C39CF879B75EDB0F0F84602A1EC66250F1BEA8BB250BE675BF6EFDBEDEB1B97699A8F248B68506BBD4F968CAB83FC8C3AEED661AD3682A6B38ADCF7FE0C7A257C4BD376A56207EA4E0F89DA41460BAA707C74A6670C5953ECCAF324A79DA05116A0493B16BDE9D12DE376ED0DA9A7B9780BD3096633EF40D52D03C5ECCB24630046AF5270657416BD7B2F45EEA86C3019E91A946132621E6E96BCA9C42609390EEBA2D1CD06C47DB2A2FDEFF2788505AD177A07AE04A6549909FBA711F714B1F76054668E119FA19B4830819C5108EB186F95AD1ECA0D91AA79337EBABA0AA0F84487227E6951F537BA293556D43E16DD77DE63FD9702EA9E6FDAA775B4C96A16D8DD35852A9079ACB398792F6E89D56595B3E9340BA56525F270E2E976FB376E77F02CD8231988125030610AE2FCFA69A8FAD3D98122D0E8CEF28E5AA696EE497C0B8C8299B77480095577B78251DB69997A17F148EEC4E89A323BF747EF871467194B
+20220720121337 2 6 100 8191 5 C5A088686E2057FDD426A4329908C72093AFD4A412B73B7C03574CCFAA7EBA44BF6CF5AD03B49A0AEF8A18CCAF15B0D7B12DEE66078C6A3CCE94DCA05193912A668B6E247962F8CC51046DC6DAF5AE92C169A8F00D116524762DAA1E9FF3F3270F2831FA8C94010DAD76A0032523EB9A610EBBA3BF3EFE82471449768C5B844277FC90486CBC00B6C0EA93DE6067DF863B5F1E5D5BD9781DEB1C5A111AEF62BD8016C4210CB6CA14C45559266711960B7F7FEF20E96391F59D019973FB9EFEE8C198D70EC2080C69EBCCEFA9CE2D93081A47E916F667AFFE28642A8E36133D03A3058D9E65DC0C13959DDC40CFF31B53768D41369CF05EDA59CAA0643949A1ED78B8D2F748A93F3DCE01A22AB1F23EC4E63F7A97D7863907A401633B92A073F62B56FD341B9E2B1497FB139FC2FEBD1F5EEE3A001D9DE86C6F8EBA8DDC0C0504A7A46409D036BB9534BC293BB4D9E77A9A2D0296528266EB6BD8071695F854C4E35912B78E10B2D9574D9F238E7649F998CCA0F2639068B0895E71F79E84BF631367A9221DA5F0C12191EA1CC93CA0D863269E7D25F65D29BC9D70F30B287849533A99D5DA2B8D1337DFA905E46A8673F45028192B297D52CF62C5137E4F7D824EB166CB37FBC393EF1FCC235DCC5D7A224B3A2CF975ADAEA330413E7B6DE83EF6181CBA7AF33575369AD7FBFAD0A6B7211BC3BD8EC3648AB6421D2A9142E95AA6827ACA734A605B88585BF5B30EEC75823DCA57EF524421EFC354CA2EE5D9123B1883FBDC41A0DB3558536B410089013F051EE93C3ADD61500F1A3A37CB403F5378AC3AC40D0022617442EDDCA56B012C17A0A50F33B3C6A2F8BE955F22800C4DA6D65ADB413E87ADE5351FD20BE2BF281ABF8CC8BB78A6723D2B9CDE699BCCD47FB7EBEC2F2EA46B6060EAC9101A4448D2CC4D0C6EA9A1A78CE6528C39CF879B75EDB0F0F84602A1EC66250F1BEA8BB250BE675BF6EFDBEDEB1B97699A8F248B68506BBD4F968CAB83FC8C3AEED661AD3682A6B38ADCF7FE0C7A257C4BD376A56207EA4E0F89DA41460BAA707C74A6670C5953ECCAF324A79DA05116A0493B16BDE9D12DE376ED0DA9A7B9780BD3096633EF40D52D03C5ECCB24630046AF5270657416BD7B2F45EEA86C3019E91A946132621E6E96BCA9C42609390EEBA2D1CD06C47DB2A2FDEFF2788505AD177A07AE04A6549909FBA711F714B1F76054668E119FA19B4830819C5108EB186F95AD1ECA0D91AA79337EBABA0AA0F84487227E6951F537BA293556D43E16DD77DE63FD9702EA9E6FDAA775B4C96A16D8DD35852A9079ACB398792F6E89D56595B3E9340BA56525F270E2E976FB376E77F02CD8231988125030610AE2FCFA69A8FAD3D98122D0E8CEF28E5AA696EE497C0B8C8299B77480095577B78251DB69997A17F148EEC4E89A323BF747EF87176DFD6F
+20220720124230 2 6 100 8191 2 C5A088686E2057FDD426A4329908C72093AFD4A412B73B7C03574CCFAA7EBA44BF6CF5AD03B49A0AEF8A18CCAF15B0D7B12DEE66078C6A3CCE94DCA05193912A668B6E247962F8CC51046DC6DAF5AE92C169A8F00D116524762DAA1E9FF3F3270F2831FA8C94010DAD76A0032523EB9A610EBBA3BF3EFE82471449768C5B844277FC90486CBC00B6C0EA93DE6067DF863B5F1E5D5BD9781DEB1C5A111AEF62BD8016C4210CB6CA14C45559266711960B7F7FEF20E96391F59D019973FB9EFEE8C198D70EC2080C69EBCCEFA9CE2D93081A47E916F667AFFE28642A8E36133D03A3058D9E65DC0C13959DDC40CFF31B53768D41369CF05EDA59CAA0643949A1ED78B8D2F748A93F3DCE01A22AB1F23EC4E63F7A97D7863907A401633B92A073F62B56FD341B9E2B1497FB139FC2FEBD1F5EEE3A001D9DE86C6F8EBA8DDC0C0504A7A46409D036BB9534BC293BB4D9E77A9A2D0296528266EB6BD8071695F854C4E35912B78E10B2D9574D9F238E7649F998CCA0F2639068B0895E71F79E84BF631367A9221DA5F0C12191EA1CC93CA0D863269E7D25F65D29BC9D70F30B287849533A99D5DA2B8D1337DFA905E46A8673F45028192B297D52CF62C5137E4F7D824EB166CB37FBC393EF1FCC235DCC5D7A224B3A2CF975ADAEA330413E7B6DE83EF6181CBA7AF33575369AD7FBFAD0A6B7211BC3BD8EC3648AB6421D2A9142E95AA6827ACA734A605B88585BF5B30EEC75823DCA57EF524421EFC354CA2EE5D9123B1883FBDC41A0DB3558536B410089013F051EE93C3ADD61500F1A3A37CB403F5378AC3AC40D0022617442EDDCA56B012C17A0A50F33B3C6A2F8BE955F22800C4DA6D65ADB413E87ADE5351FD20BE2BF281ABF8CC8BB78A6723D2B9CDE699BCCD47FB7EBEC2F2EA46B6060EAC9101A4448D2CC4D0C6EA9A1A78CE6528C39CF879B75EDB0F0F84602A1EC66250F1BEA8BB250BE675BF6EFDBEDEB1B97699A8F248B68506BBD4F968CAB83FC8C3AEED661AD3682A6B38ADCF7FE0C7A257C4BD376A56207EA4E0F89DA41460BAA707C74A6670C5953ECCAF324A79DA05116A0493B16BDE9D12DE376ED0DA9A7B9780BD3096633EF40D52D03C5ECCB24630046AF5270657416BD7B2F45EEA86C3019E91A946132621E6E96BCA9C42609390EEBA2D1CD06C47DB2A2FDEFF2788505AD177A07AE04A6549909FBA711F714B1F76054668E119FA19B4830819C5108EB186F95AD1ECA0D91AA79337EBABA0AA0F84487227E6951F537BA293556D43E16DD77DE63FD9702EA9E6FDAA775B4C96A16D8DD35852A9079ACB398792F6E89D56595B3E9340BA56525F270E2E976FB376E77F02CD8231988125030610AE2FCFA69A8FAD3D98122D0E8CEF28E5AA696EE497C0B8C8299B77480095577B78251DB69997A17F148EEC4E89A323BF747EF871929A88B
diff --git a/crypto/openssh/monitor_wrap.c b/crypto/openssh/monitor_wrap.c
index b2c85205eb96..8e379a15c6b8 100644
--- a/crypto/openssh/monitor_wrap.c
+++ b/crypto/openssh/monitor_wrap.c
@@ -1,1021 +1,1022 @@
-/* $OpenBSD: monitor_wrap.c,v 1.125 2022/06/15 16:08:25 djm Exp $ */
+/* $OpenBSD: monitor_wrap.c,v 1.126 2023/01/06 02:47:18 djm Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
* Copyright 2002 Markus Friedl <markus@openbsd.org>
* 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/uio.h>
#include <errno.h>
#include <pwd.h>
#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#ifdef WITH_OPENSSL
#include <openssl/bn.h>
#include <openssl/dh.h>
#include <openssl/evp.h>
#endif
#include "openbsd-compat/sys-queue.h"
#include "xmalloc.h"
#include "ssh.h"
#ifdef WITH_OPENSSL
#include "dh.h"
#endif
#include "sshbuf.h"
#include "sshkey.h"
#include "cipher.h"
#include "kex.h"
#include "hostfile.h"
#include "auth.h"
#include "auth-options.h"
#include "packet.h"
#include "mac.h"
#include "log.h"
#include "auth-pam.h"
#include "monitor.h"
#ifdef GSSAPI
#include "ssh-gss.h"
#endif
#include "monitor_wrap.h"
#include "atomicio.h"
#include "monitor_fdpass.h"
#include "misc.h"
#include "channels.h"
#include "session.h"
#include "servconf.h"
#include "ssherr.h"
/* Imports */
extern struct monitor *pmonitor;
extern struct sshbuf *loginmsg;
extern ServerOptions options;
void
mm_log_handler(LogLevel level, int forced, const char *msg, void *ctx)
{
struct sshbuf *log_msg;
struct monitor *mon = (struct monitor *)ctx;
int r;
size_t len;
if (mon->m_log_sendfd == -1)
fatal_f("no log channel");
if ((log_msg = sshbuf_new()) == NULL)
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_fr(r, "assemble");
if ((len = sshbuf_len(log_msg)) < 4 || len > 0xffffffff)
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_f("write: %s", strerror(errno));
sshbuf_free(log_msg);
}
int
mm_is_monitor(void)
{
/*
* m_pid is only set in the privileged part, and
* points to the unprivileged child.
*/
return (pmonitor && pmonitor->m_pid > 0);
}
void
mm_request_send(int sock, enum monitor_reqtype type, struct sshbuf *m)
{
size_t mlen = sshbuf_len(m);
u_char buf[5];
debug3_f("entering, type %d", type);
if (mlen >= 0xffffffff)
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_f("write: %s", strerror(errno));
if (atomicio(vwrite, sock, sshbuf_mutable_ptr(m), mlen) != mlen)
fatal_f("write: %s", strerror(errno));
}
void
mm_request_receive(int sock, struct sshbuf *m)
{
u_char buf[4], *p = NULL;
u_int msg_len;
int r;
debug3_f("entering");
if (atomicio(read, sock, buf, sizeof(buf)) != sizeof(buf)) {
if (errno == EPIPE)
cleanup_exit(255);
fatal_f("read: %s", strerror(errno));
}
msg_len = PEEK_U32(buf);
if (msg_len > 256 * 1024)
fatal_f("read: bad msg_len %d", msg_len);
sshbuf_reset(m);
if ((r = sshbuf_reserve(m, msg_len, &p)) != 0)
fatal_fr(r, "reserve");
if (atomicio(read, sock, p, msg_len) != msg_len)
fatal_f("read: %s", strerror(errno));
}
void
mm_request_receive_expect(int sock, enum monitor_reqtype type, struct sshbuf *m)
{
u_char rtype;
int r;
debug3_f("entering, type %d", type);
mm_request_receive(sock, m);
if ((r = sshbuf_get_u8(m, &rtype)) != 0)
fatal_fr(r, "parse");
if (rtype != type)
fatal_f("read: rtype %d != type %d", rtype, type);
}
#ifdef WITH_OPENSSL
DH *
mm_choose_dh(int min, int nbits, int max)
{
BIGNUM *p, *g;
int r;
u_char success = 0;
struct sshbuf *m;
if ((m = sshbuf_new()) == NULL)
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_fr(r, "assemble");
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_MODULI, m);
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_fr(r, "parse success");
if (success == 0)
fatal_f("MONITOR_ANS_MODULI failed");
if ((r = sshbuf_get_bignum2(m, &p)) != 0 ||
(r = sshbuf_get_bignum2(m, &g)) != 0)
fatal_fr(r, "parse group");
debug3_f("remaining %zu", sshbuf_len(m));
sshbuf_free(m);
return (dh_new_group(g, p));
}
#endif
int
mm_sshkey_sign(struct ssh *ssh, struct sshkey *key, u_char **sigp, size_t *lenp,
const u_char *data, size_t datalen, const char *hostkey_alg,
const char *sk_provider, const char *sk_pin, u_int compat)
{
struct kex *kex = *pmonitor->m_pkex;
struct sshbuf *m;
u_int ndx = kex->host_key_index(key, 0, ssh);
int r;
debug3_f("entering");
if ((m = sshbuf_new()) == NULL)
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_fr(r, "assemble");
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SIGN, m);
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_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)
{
struct sshbuf *m;
struct passwd *pw;
size_t len;
u_int i;
ServerOptions *newopts;
int r;
u_char ok;
const u_char *p;
debug3_f("entering");
if ((m = sshbuf_new()) == NULL)
fatal_f("sshbuf_new failed");
if ((r = sshbuf_put_cstring(m, username)) != 0)
fatal_fr(r, "assemble");
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PWNAM, m);
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_fr(r, "parse success");
if (ok == 0) {
pw = NULL;
goto out;
}
/* XXX don't like passing struct passwd like this */
pw = xcalloc(sizeof(*pw), 1);
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
(r = sshbuf_get_cstring(m, &pw->pw_gecos, NULL)) != 0 ||
#endif
#ifdef HAVE_STRUCT_PASSWD_PW_CLASS
(r = sshbuf_get_cstring(m, &pw->pw_class, NULL)) != 0 ||
#endif
(r = sshbuf_get_cstring(m, &pw->pw_dir, NULL)) != 0 ||
(r = sshbuf_get_cstring(m, &pw->pw_shell, NULL)) != 0)
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_fr(r, "parse opts");
if (len != sizeof(*newopts))
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 && \
(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 ? \
NULL : xcalloc(newopts->nx, sizeof(*newopts->x)); \
for (i = 0; i < newopts->nx; i++) { \
if ((r = sshbuf_get_cstring(m, \
&newopts->x[i], NULL)) != 0) \
fatal_fr(r, "parse %s", #x); \
} \
} while (0)
/* See comment in servconf.h */
COPY_MATCH_STRING_OPTS();
#undef M_CP_STROPT
#undef M_CP_STRARRAYOPT
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);
+ process_channel_timeouts(ssh, &options);
free(newopts);
sshbuf_free(m);
return (pw);
}
char *
mm_auth2_read_banner(void)
{
struct sshbuf *m;
char *banner;
int r;
debug3_f("entering");
if ((m = sshbuf_new()) == NULL)
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_fr(r, "parse");
sshbuf_free(m);
/* treat empty banner as missing banner */
if (strlen(banner) == 0) {
free(banner);
banner = NULL;
}
return (banner);
}
/* Inform the privileged process about service and style */
void
mm_inform_authserv(char *service, char *style)
{
struct sshbuf *m;
int r;
debug3_f("entering");
if ((m = sshbuf_new()) == NULL)
fatal_f("sshbuf_new failed");
if ((r = sshbuf_put_cstring(m, service)) != 0 ||
(r = sshbuf_put_cstring(m, style ? style : "")) != 0)
fatal_fr(r, "assemble");
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHSERV, m);
sshbuf_free(m);
}
/* Do the password authentication */
int
mm_auth_password(struct ssh *ssh, char *password)
{
struct sshbuf *m;
int r, authenticated = 0;
#ifdef USE_PAM
u_int maxtries = 0;
#endif
debug3_f("entering");
if ((m = sshbuf_new()) == NULL)
fatal_f("sshbuf_new failed");
if ((r = sshbuf_put_cstring(m, password)) != 0)
fatal_fr(r, "assemble");
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHPASSWORD, m);
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_fr(r, "parse");
#ifdef USE_PAM
if ((r = sshbuf_get_u32(m, &maxtries)) != 0)
fatal_fr(r, "parse PAM");
if (maxtries > INT_MAX)
fatal_fr(r, "bad maxtries");
sshpam_set_maxtries_reached(maxtries);
#endif
sshbuf_free(m);
debug3_f("user %sauthenticated", authenticated ? "" : "not ");
return (authenticated);
}
int
mm_user_key_allowed(struct ssh *ssh, struct passwd *pw, struct sshkey *key,
int pubkey_auth_attempt, struct sshauthopt **authoptp)
{
return (mm_key_allowed(MM_USERKEY, NULL, NULL, key,
pubkey_auth_attempt, authoptp));
}
int
mm_hostbased_key_allowed(struct ssh *ssh, struct passwd *pw,
const char *user, const char *host, struct sshkey *key)
{
return (mm_key_allowed(MM_HOSTKEY, user, host, key, 0, NULL));
}
int
mm_key_allowed(enum mm_keytype type, const char *user, const char *host,
struct sshkey *key, int pubkey_auth_attempt, struct sshauthopt **authoptp)
{
struct sshbuf *m;
int r, allowed = 0;
struct sshauthopt *opts = NULL;
debug3_f("entering");
if (authoptp != NULL)
*authoptp = NULL;
if ((m = sshbuf_new()) == NULL)
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_fr(r, "assemble");
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYALLOWED, m);
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_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) {
*authoptp = opts;
opts = NULL;
}
sshauthopt_free(opts);
return allowed;
}
/*
* This key verify needs to send the key type along, because the
* privileged parent makes the decision if the key is allowed
* for authentication.
*/
int
mm_sshkey_verify(const struct sshkey *key, const u_char *sig, size_t siglen,
const u_char *data, size_t datalen, const char *sigalg, u_int compat,
struct sshkey_sig_details **sig_detailsp)
{
struct sshbuf *m;
u_int encoded_ret = 0;
int r;
u_char sig_details_present, flags;
u_int counter;
debug3_f("entering");
if (sig_detailsp != NULL)
*sig_detailsp = NULL;
if ((m = sshbuf_new()) == NULL)
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_fr(r, "assemble");
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYVERIFY, m);
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_fr(r, "parse");
if (sig_details_present && encoded_ret == 0) {
if ((r = sshbuf_get_u32(m, &counter)) != 0 ||
(r = sshbuf_get_u8(m, &flags)) != 0)
fatal_fr(r, "parse sig_details");
if (sig_detailsp != NULL) {
*sig_detailsp = xcalloc(1, sizeof(**sig_detailsp));
(*sig_detailsp)->sk_counter = counter;
(*sig_detailsp)->sk_flags = flags;
}
}
sshbuf_free(m);
if (encoded_ret != 0)
return SSH_ERR_SIGNATURE_INVALID;
return 0;
}
void
mm_send_keystate(struct ssh *ssh, struct monitor *monitor)
{
struct sshbuf *m;
int r;
if ((m = sshbuf_new()) == NULL)
fatal_f("sshbuf_new failed");
if ((r = ssh_packet_get_state(ssh, m)) != 0)
fatal_fr(r, "ssh_packet_get_state");
mm_request_send(monitor->m_recvfd, MONITOR_REQ_KEYEXPORT, m);
debug3_f("Finished sending state");
sshbuf_free(m);
}
int
mm_pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, size_t namebuflen)
{
struct sshbuf *m;
char *p, *msg;
int success = 0, tmp1 = -1, tmp2 = -1, r;
/* 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_f("cannot allocate fds for pty");
if (tmp1 > 0)
close(tmp1);
if (tmp2 > 0)
close(tmp2);
return 0;
}
close(tmp1);
close(tmp2);
if ((m = sshbuf_new()) == NULL)
fatal_f("sshbuf_new failed");
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PTY, m);
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_fr(r, "parse success");
if (success == 0) {
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_fr(r, "parse");
sshbuf_free(m);
strlcpy(namebuf, p, namebuflen); /* Possible truncation */
free(p);
if ((r = sshbuf_put(loginmsg, msg, strlen(msg))) != 0)
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_f("receive fds failed");
/* Success */
return (1);
}
void
mm_session_pty_cleanup2(Session *s)
{
struct sshbuf *m;
int r;
if (s->ttyfd == -1)
return;
if ((m = sshbuf_new()) == NULL)
fatal_f("sshbuf_new failed");
if ((r = sshbuf_put_cstring(m, s->tty)) != 0)
fatal_fr(r, "assmble");
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PTYCLEANUP, m);
sshbuf_free(m);
/* closed dup'ed master */
if (s->ptymaster != -1 && close(s->ptymaster) == -1)
error("close(s->ptymaster/%d): %s",
s->ptymaster, strerror(errno));
/* unlink pty from session */
s->ttyfd = -1;
}
#ifdef USE_PAM
void
mm_start_pam(struct ssh *ssh)
{
struct sshbuf *m;
debug3("%s entering", __func__);
if (!options.use_pam)
fatal("UsePAM=no, but ended up in %s anyway", __func__);
if ((m = sshbuf_new()) == NULL)
fatal("%s: sshbuf_new failed", __func__);
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_START, m);
sshbuf_free(m);
}
u_int
mm_do_pam_account(void)
{
struct sshbuf *m;
u_int ret;
char *msg;
size_t msglen;
int r;
debug3("%s entering", __func__);
if (!options.use_pam)
fatal("UsePAM=no, but ended up in %s anyway", __func__);
if ((m = sshbuf_new()) == NULL)
fatal("%s: sshbuf_new failed", __func__);
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_ACCOUNT, m);
mm_request_receive_expect(pmonitor->m_recvfd,
MONITOR_ANS_PAM_ACCOUNT, m);
if ((r = sshbuf_get_u32(m, &ret)) != 0 ||
(r = sshbuf_get_cstring(m, &msg, &msglen)) != 0 ||
(r = sshbuf_put(loginmsg, msg, msglen)) != 0)
fatal("%s: buffer error: %s", __func__, ssh_err(r));
free(msg);
sshbuf_free(m);
debug3("%s returning %d", __func__, ret);
return (ret);
}
void *
mm_sshpam_init_ctx(Authctxt *authctxt)
{
struct sshbuf *m;
int r, success;
debug3("%s", __func__);
if ((m = sshbuf_new()) == NULL)
fatal("%s: sshbuf_new failed", __func__);
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_INIT_CTX, m);
debug3("%s: waiting for MONITOR_ANS_PAM_INIT_CTX", __func__);
mm_request_receive_expect(pmonitor->m_recvfd,
MONITOR_ANS_PAM_INIT_CTX, m);
if ((r = sshbuf_get_u32(m, &success)) != 0)
fatal("%s: buffer error: %s", __func__, ssh_err(r));
if (success == 0) {
debug3("%s: pam_init_ctx failed", __func__);
sshbuf_free(m);
return (NULL);
}
sshbuf_free(m);
return (authctxt);
}
int
mm_sshpam_query(void *ctx, char **name, char **info,
u_int *num, char ***prompts, u_int **echo_on)
{
struct sshbuf *m;
u_int i, n;
int r, ret;
debug3("%s", __func__);
if ((m = sshbuf_new()) == NULL)
fatal("%s: sshbuf_new failed", __func__);
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_QUERY, m);
debug3("%s: waiting for MONITOR_ANS_PAM_QUERY", __func__);
mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_QUERY, m);
if ((r = sshbuf_get_u32(m, &ret)) != 0 ||
(r = sshbuf_get_cstring(m, name, NULL)) != 0 ||
(r = sshbuf_get_cstring(m, info, NULL)) != 0 ||
(r = sshbuf_get_u32(m, &n)) != 0 ||
(r = sshbuf_get_u32(m, num)) != 0)
fatal("%s: buffer error: %s", __func__, ssh_err(r));
debug3("%s: pam_query returned %d", __func__, ret);
sshpam_set_maxtries_reached(n);
if (*num > PAM_MAX_NUM_MSG)
fatal("%s: received %u PAM messages, expected <= %u",
__func__, *num, PAM_MAX_NUM_MSG);
*prompts = xcalloc((*num + 1), sizeof(char *));
*echo_on = xcalloc((*num + 1), sizeof(u_int));
for (i = 0; i < *num; ++i) {
if ((r = sshbuf_get_cstring(m, &((*prompts)[i]), NULL)) != 0 ||
(r = sshbuf_get_u32(m, &((*echo_on)[i]))) != 0)
fatal("%s: buffer error: %s", __func__, ssh_err(r));
}
sshbuf_free(m);
return (ret);
}
int
mm_sshpam_respond(void *ctx, u_int num, char **resp)
{
struct sshbuf *m;
u_int n, i;
int r, ret;
debug3("%s", __func__);
if ((m = sshbuf_new()) == NULL)
fatal("%s: sshbuf_new failed", __func__);
if ((r = sshbuf_put_u32(m, num)) != 0)
fatal("%s: buffer error: %s", __func__, ssh_err(r));
for (i = 0; i < num; ++i) {
if ((r = sshbuf_put_cstring(m, resp[i])) != 0)
fatal("%s: buffer error: %s", __func__, ssh_err(r));
}
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_RESPOND, m);
debug3("%s: waiting for MONITOR_ANS_PAM_RESPOND", __func__);
mm_request_receive_expect(pmonitor->m_recvfd,
MONITOR_ANS_PAM_RESPOND, m);
if ((r = sshbuf_get_u32(m, &n)) != 0)
fatal("%s: buffer error: %s", __func__, ssh_err(r));
ret = (int)n; /* XXX */
debug3("%s: pam_respond returned %d", __func__, ret);
sshbuf_free(m);
return (ret);
}
void
mm_sshpam_free_ctx(void *ctxtp)
{
struct sshbuf *m;
debug3("%s", __func__);
if ((m = sshbuf_new()) == NULL)
fatal("%s: sshbuf_new failed", __func__);
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_FREE_CTX, m);
debug3("%s: waiting for MONITOR_ANS_PAM_FREE_CTX", __func__);
mm_request_receive_expect(pmonitor->m_recvfd,
MONITOR_ANS_PAM_FREE_CTX, m);
sshbuf_free(m);
}
#endif /* USE_PAM */
/* Request process termination */
void
mm_terminate(void)
{
struct sshbuf *m;
if ((m = sshbuf_new()) == NULL)
fatal_f("sshbuf_new failed");
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_TERM, m);
sshbuf_free(m);
}
static void
mm_chall_setup(char **name, char **infotxt, u_int *numprompts,
char ***prompts, u_int **echo_on)
{
*name = xstrdup("");
*infotxt = xstrdup("");
*numprompts = 1;
*prompts = xcalloc(*numprompts, sizeof(char *));
*echo_on = xcalloc(*numprompts, sizeof(u_int));
(*echo_on)[0] = 0;
}
int
mm_bsdauth_query(void *ctx, char **name, char **infotxt,
u_int *numprompts, char ***prompts, u_int **echo_on)
{
struct sshbuf *m;
u_int success;
char *challenge;
int r;
debug3_f("entering");
if ((m = sshbuf_new()) == NULL)
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_fr(r, "parse success");
if (success == 0) {
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_fr(r, "parse challenge");
sshbuf_free(m);
mm_chall_setup(name, infotxt, numprompts, prompts, echo_on);
(*prompts)[0] = challenge;
debug3_f("received challenge: %s", challenge);
return (0);
}
int
mm_bsdauth_respond(void *ctx, u_int numresponses, char **responses)
{
struct sshbuf *m;
int r, authok;
debug3_f("entering");
if (numresponses != 1)
return (-1);
if ((m = sshbuf_new()) == NULL)
fatal_f("sshbuf_new failed");
if ((r = sshbuf_put_cstring(m, responses[0])) != 0)
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_fr(r, "parse");
sshbuf_free(m);
return ((authok == 0) ? -1 : 0);
}
#ifdef SSH_AUDIT_EVENTS
void
mm_audit_event(struct ssh *ssh, ssh_audit_event_t event)
{
struct sshbuf *m;
int r;
debug3("%s entering", __func__);
if ((m = sshbuf_new()) == NULL)
fatal("%s: sshbuf_new failed", __func__);
if ((r = sshbuf_put_u32(m, event)) != 0)
fatal("%s: buffer error: %s", __func__, ssh_err(r));
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_EVENT, m);
sshbuf_free(m);
}
void
mm_audit_run_command(const char *command)
{
struct sshbuf *m;
int r;
debug3("%s entering command %s", __func__, command);
if ((m = sshbuf_new()) == NULL)
fatal("%s: sshbuf_new failed", __func__);
if ((r = sshbuf_put_cstring(m, command)) != 0)
fatal("%s: buffer error: %s", __func__, ssh_err(r));
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_COMMAND, m);
sshbuf_free(m);
}
#endif /* SSH_AUDIT_EVENTS */
#ifdef GSSAPI
OM_uint32
mm_ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID goid)
{
struct sshbuf *m;
OM_uint32 major;
int r;
/* Client doesn't get to see the context */
*ctx = NULL;
if ((m = sshbuf_new()) == NULL)
fatal_f("sshbuf_new failed");
if ((r = sshbuf_put_string(m, goid->elements, goid->length)) != 0)
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_fr(r, "parse");
sshbuf_free(m);
return (major);
}
OM_uint32
mm_ssh_gssapi_accept_ctx(Gssctxt *ctx, gss_buffer_desc *in,
gss_buffer_desc *out, OM_uint32 *flagsp)
{
struct sshbuf *m;
OM_uint32 major;
u_int flags;
int r;
if ((m = sshbuf_new()) == NULL)
fatal_f("sshbuf_new failed");
if ((r = sshbuf_put_string(m, in->value, in->length)) != 0)
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_fr(r, "parse");
if (flagsp != NULL) {
if ((r = sshbuf_get_u32(m, &flags)) != 0)
fatal_fr(r, "parse flags");
*flagsp = flags;
}
sshbuf_free(m);
return (major);
}
OM_uint32
mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic)
{
struct sshbuf *m;
OM_uint32 major;
int r;
if ((m = sshbuf_new()) == NULL)
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_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_fr(r, "parse");
sshbuf_free(m);
return(major);
}
int
mm_ssh_gssapi_userok(char *user)
{
struct sshbuf *m;
int r, authenticated = 0;
if ((m = sshbuf_new()) == NULL)
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_fr(r, "parse");
sshbuf_free(m);
debug3_f("user %sauthenticated", authenticated ? "" : "not ");
return (authenticated);
}
#endif /* GSSAPI */
diff --git a/crypto/openssh/mux.c b/crypto/openssh/mux.c
index 3cb3876148aa..e7580ac742ab 100644
--- a/crypto/openssh/mux.c
+++ b/crypto/openssh/mux.c
@@ -1,2344 +1,2344 @@
-/* $OpenBSD: mux.c,v 1.94 2022/06/03 04:30:47 djm Exp $ */
+/* $OpenBSD: mux.c,v 1.95 2023/01/06 02:39:59 djm Exp $ */
/*
* Copyright (c) 2002-2008 Damien Miller <djm@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.
*/
/* ssh session multiplexing support */
#include "includes.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#ifdef HAVE_PATHS_H
#include <paths.h>
#endif
#ifdef HAVE_POLL_H
#include <poll.h>
#else
# ifdef HAVE_SYS_POLL_H
# include <sys/poll.h>
# endif
#endif
#ifdef HAVE_UTIL_H
# include <util.h>
#endif
#include "openbsd-compat/sys-queue.h"
#include "xmalloc.h"
#include "log.h"
#include "ssh.h"
#include "ssh2.h"
#include "pathnames.h"
#include "misc.h"
#include "match.h"
#include "sshbuf.h"
#include "channels.h"
#include "msg.h"
#include "packet.h"
#include "monitor_fdpass.h"
#include "sshpty.h"
#include "sshkey.h"
#include "readconf.h"
#include "clientloop.h"
#include "ssherr.h"
/* from ssh.c */
extern int tty_flag;
extern Options options;
extern char *host;
extern struct sshbuf *command;
extern volatile sig_atomic_t quit_pending;
/* Context for session open confirmation callback */
struct mux_session_confirm_ctx {
u_int want_tty;
u_int want_subsys;
u_int want_x_fwd;
u_int want_agent_fwd;
struct sshbuf *cmd;
char *term;
struct termios tio;
char **env;
u_int rid;
};
/* Context for stdio fwd open confirmation callback */
struct mux_stdio_confirm_ctx {
u_int rid;
};
/* Context for global channel callback */
struct mux_channel_confirm_ctx {
u_int cid; /* channel id */
u_int rid; /* request id */
int fid; /* forward id */
};
/* fd to control socket */
int muxserver_sock = -1;
/* client request id */
u_int muxclient_request_id = 0;
/* Multiplexing control command */
u_int muxclient_command = 0;
/* Set when signalled. */
static volatile sig_atomic_t muxclient_terminate = 0;
/* PID of multiplex server */
static u_int muxserver_pid = 0;
static Channel *mux_listener_channel = NULL;
struct mux_master_state {
int hello_rcvd;
};
/* mux protocol messages */
#define MUX_MSG_HELLO 0x00000001
#define MUX_C_NEW_SESSION 0x10000002
#define MUX_C_ALIVE_CHECK 0x10000004
#define MUX_C_TERMINATE 0x10000005
#define MUX_C_OPEN_FWD 0x10000006
#define MUX_C_CLOSE_FWD 0x10000007
#define MUX_C_NEW_STDIO_FWD 0x10000008
#define MUX_C_STOP_LISTENING 0x10000009
#define MUX_C_PROXY 0x1000000f
#define MUX_S_OK 0x80000001
#define MUX_S_PERMISSION_DENIED 0x80000002
#define MUX_S_FAILURE 0x80000003
#define MUX_S_EXIT_MESSAGE 0x80000004
#define MUX_S_ALIVE 0x80000005
#define MUX_S_SESSION_OPENED 0x80000006
#define MUX_S_REMOTE_PORT 0x80000007
#define MUX_S_TTY_ALLOC_FAIL 0x80000008
#define MUX_S_PROXY 0x8000000f
/* type codes for MUX_C_OPEN_FWD and MUX_C_CLOSE_FWD */
#define MUX_FWD_LOCAL 1
#define MUX_FWD_REMOTE 2
#define MUX_FWD_DYNAMIC 3
static void mux_session_confirm(struct ssh *, int, int, void *);
static void mux_stdio_confirm(struct ssh *, int, int, void *);
static int mux_master_process_hello(struct ssh *, u_int,
Channel *, struct sshbuf *, struct sshbuf *);
static int mux_master_process_new_session(struct ssh *, u_int,
Channel *, struct sshbuf *, struct sshbuf *);
static int mux_master_process_alive_check(struct ssh *, u_int,
Channel *, struct sshbuf *, struct sshbuf *);
static int mux_master_process_terminate(struct ssh *, u_int,
Channel *, struct sshbuf *, struct sshbuf *);
static int mux_master_process_open_fwd(struct ssh *, u_int,
Channel *, struct sshbuf *, struct sshbuf *);
static int mux_master_process_close_fwd(struct ssh *, u_int,
Channel *, struct sshbuf *, struct sshbuf *);
static int mux_master_process_stdio_fwd(struct ssh *, u_int,
Channel *, struct sshbuf *, struct sshbuf *);
static int mux_master_process_stop_listening(struct ssh *, u_int,
Channel *, struct sshbuf *, struct sshbuf *);
static int mux_master_process_proxy(struct ssh *, u_int,
Channel *, struct sshbuf *, struct sshbuf *);
static const struct {
u_int type;
int (*handler)(struct ssh *, u_int, Channel *,
struct sshbuf *, struct sshbuf *);
} mux_master_handlers[] = {
{ MUX_MSG_HELLO, mux_master_process_hello },
{ MUX_C_NEW_SESSION, mux_master_process_new_session },
{ MUX_C_ALIVE_CHECK, mux_master_process_alive_check },
{ MUX_C_TERMINATE, mux_master_process_terminate },
{ MUX_C_OPEN_FWD, mux_master_process_open_fwd },
{ MUX_C_CLOSE_FWD, mux_master_process_close_fwd },
{ MUX_C_NEW_STDIO_FWD, mux_master_process_stdio_fwd },
{ MUX_C_STOP_LISTENING, mux_master_process_stop_listening },
{ MUX_C_PROXY, mux_master_process_proxy },
{ 0, NULL }
};
/* Cleanup callback fired on closure of mux client _session_ channel */
/* ARGSUSED */
static void
-mux_master_session_cleanup_cb(struct ssh *ssh, int cid, void *unused)
+mux_master_session_cleanup_cb(struct ssh *ssh, int cid, int force, void *unused)
{
Channel *cc, *c = channel_by_id(ssh, cid);
debug3_f("entering for channel %d", cid);
if (c == NULL)
fatal_f("channel_by_id(%i) == NULL", cid);
if (c->ctl_chan != -1) {
if ((cc = channel_by_id(ssh, c->ctl_chan)) == NULL)
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;
chan_rcvd_oclose(ssh, cc);
}
channel_cancel_cleanup(ssh, c->self);
}
/* Cleanup callback fired on closure of mux client _control_ channel */
/* ARGSUSED */
static void
-mux_master_control_cleanup_cb(struct ssh *ssh, int cid, void *unused)
+mux_master_control_cleanup_cb(struct ssh *ssh, int cid, int force, void *unused)
{
Channel *sc, *c = channel_by_id(ssh, cid);
debug3_f("entering for channel %d", cid);
if (c == NULL)
fatal_f("channel_by_id(%i) == NULL", cid);
if (c->have_remote_id) {
if ((sc = channel_by_id(ssh, c->remote_id)) == NULL)
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_f("channel %d: not open", sc->self);
chan_mark_dead(ssh, sc);
} else {
if (sc->istate == CHAN_INPUT_OPEN)
chan_read_failed(ssh, sc);
if (sc->ostate == CHAN_OUTPUT_OPEN)
chan_write_failed(ssh, sc);
}
}
channel_cancel_cleanup(ssh, c->self);
}
/* Check mux client environment variables before passing them to mux master. */
static int
env_permitted(const char *env)
{
u_int i;
int ret;
char name[1024], *cp;
if ((cp = strchr(env, '=')) == NULL || cp == env)
return 0;
ret = snprintf(name, sizeof(name), "%.*s", (int)(cp - env), env);
if (ret <= 0 || (size_t)ret >= sizeof(name)) {
error_f("name '%.100s...' too long", env);
return 0;
}
for (i = 0; i < options.num_send_env; i++)
if (match_pattern(name, options.send_env[i]))
return 1;
return 0;
}
/* Mux master protocol message handlers */
static int
mux_master_process_hello(struct ssh *ssh, u_int rid,
Channel *c, struct sshbuf *m, struct sshbuf *reply)
{
u_int ver;
struct mux_master_state *state = (struct mux_master_state *)c->mux_ctx;
int r;
if (state == NULL)
fatal_f("channel %d: c->mux_ctx == NULL", c->self);
if (state->hello_rcvd) {
error_f("HELLO received twice");
return -1;
}
if ((r = sshbuf_get_u32(m, &ver)) != 0) {
error_fr(r, "parse");
return -1;
}
if (ver != SSHMUX_VER) {
error_f("unsupported multiplexing protocol version %u "
"(expected %u)", ver, SSHMUX_VER);
return -1;
}
debug2_f("channel %d client version %u", c->self, ver);
/* No extensions are presently defined */
while (sshbuf_len(m) > 0) {
char *name = NULL;
size_t value_len = 0;
if ((r = sshbuf_get_cstring(m, &name, NULL)) != 0 ||
(r = sshbuf_get_string_direct(m, NULL, &value_len)) != 0) {
error_fr(r, "parse extension");
return -1;
}
debug2_f("Unrecognised extension \"%s\" length %zu",
name, value_len);
free(name);
}
state->hello_rcvd = 1;
return 0;
}
/* Enqueue a "ok" response to the reply buffer */
static void
reply_ok(struct sshbuf *reply, u_int rid)
{
int r;
if ((r = sshbuf_put_u32(reply, MUX_S_OK)) != 0 ||
(r = sshbuf_put_u32(reply, rid)) != 0)
fatal_fr(r, "reply");
}
/* Enqueue an error response to the reply buffer */
static void
reply_error(struct sshbuf *reply, u_int type, u_int rid, const char *msg)
{
int r;
if ((r = sshbuf_put_u32(reply, type)) != 0 ||
(r = sshbuf_put_u32(reply, rid)) != 0 ||
(r = sshbuf_put_cstring(reply, msg)) != 0)
fatal_fr(r, "reply");
}
static int
mux_master_process_new_session(struct ssh *ssh, u_int rid,
Channel *c, struct sshbuf *m, struct sshbuf *reply)
{
Channel *nc;
struct mux_session_confirm_ctx *cctx;
char *cmd, *cp;
u_int i, j, env_len, escape_char, window, packetmax;
int r, new_fd[3];
/* Reply for SSHMUX_COMMAND_OPEN */
cctx = xcalloc(1, sizeof(*cctx));
cctx->term = NULL;
cctx->rid = rid;
cmd = NULL;
cctx->env = NULL;
env_len = 0;
if ((r = sshbuf_skip_string(m)) != 0 || /* reserved */
(r = sshbuf_get_u32(m, &cctx->want_tty)) != 0 ||
(r = sshbuf_get_u32(m, &cctx->want_x_fwd)) != 0 ||
(r = sshbuf_get_u32(m, &cctx->want_agent_fwd)) != 0 ||
(r = sshbuf_get_u32(m, &cctx->want_subsys)) != 0 ||
(r = sshbuf_get_u32(m, &escape_char)) != 0 ||
(r = sshbuf_get_cstring(m, &cctx->term, NULL)) != 0 ||
(r = sshbuf_get_cstring(m, &cmd, NULL)) != 0) {
malf:
free(cmd);
for (j = 0; j < env_len; j++)
free(cctx->env[j]);
free(cctx->env);
free(cctx->term);
free(cctx);
error_f("malformed message");
return -1;
}
#define MUX_MAX_ENV_VARS 4096
while (sshbuf_len(m) > 0) {
if ((r = sshbuf_get_cstring(m, &cp, NULL)) != 0)
goto malf;
if (!env_permitted(cp)) {
free(cp);
continue;
}
cctx->env = xreallocarray(cctx->env, env_len + 2,
sizeof(*cctx->env));
cctx->env[env_len++] = cp;
cctx->env[env_len] = NULL;
if (env_len > MUX_MAX_ENV_VARS) {
error_f(">%d environment variables received, "
"ignoring additional", MUX_MAX_ENV_VARS);
break;
}
}
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_f("sshbuf_new");
if ((r = sshbuf_put(cctx->cmd, cmd, strlen(cmd))) != 0)
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_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++)
free(cctx->env[j]);
free(cctx->env);
free(cctx->term);
sshbuf_free(cctx->cmd);
free(cctx);
reply_error(reply, MUX_S_FAILURE, rid,
"did not receive file descriptors");
return -1;
}
}
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_f("session already open");
reply_error(reply, MUX_S_FAILURE, rid,
"Multiple sessions not supported");
cleanup:
close(new_fd[0]);
close(new_fd[1]);
close(new_fd[2]);
free(cctx->term);
if (env_len != 0) {
for (i = 0; i < env_len; i++)
free(cctx->env[i]);
free(cctx->env);
}
sshbuf_free(cctx->cmd);
free(cctx);
return 0;
}
if (options.control_master == SSHCTL_MASTER_ASK ||
options.control_master == SSHCTL_MASTER_AUTO_ASK) {
if (!ask_permission("Allow shared connection to %s? ", host)) {
debug2_f("session refused by user");
reply_error(reply, MUX_S_PERMISSION_DENIED, rid,
"Permission denied");
goto cleanup;
}
}
/* Try to pick up ttymodes from client before it goes raw */
if (cctx->want_tty && tcgetattr(new_fd[0], &cctx->tio) == -1)
error_f("tcgetattr: %s", strerror(errno));
window = CHAN_SES_WINDOW_DEFAULT;
packetmax = CHAN_SES_PACKET_DEFAULT;
if (cctx->want_tty) {
window >>= 1;
packetmax >>= 1;
}
nc = channel_new(ssh, "session", SSH_CHANNEL_OPENING,
new_fd[0], new_fd[1], new_fd[2], window, packetmax,
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->have_remote_id = 1;
if (cctx->want_tty && escape_char != 0xffffffff) {
channel_register_filter(ssh, nc->self,
client_simple_escape_filter, NULL,
client_filter_cleanup,
client_new_escape_filter_ctx((int)escape_char));
}
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);
c->mux_pause = 1; /* stop handling messages until open_confirm done */
channel_register_cleanup(ssh, nc->self,
mux_master_session_cleanup_cb, 1);
/* reply is deferred, sent by mux_session_confirm */
return 0;
}
static int
mux_master_process_alive_check(struct ssh *ssh, u_int rid,
Channel *c, struct sshbuf *m, struct sshbuf *reply)
{
int r;
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_fr(r, "reply");
return 0;
}
static int
mux_master_process_terminate(struct ssh *ssh, u_int rid,
Channel *c, struct sshbuf *m, struct sshbuf *reply)
{
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_f("termination refused by user");
reply_error(reply, MUX_S_PERMISSION_DENIED, rid,
"Permission denied");
return 0;
}
}
quit_pending = 1;
reply_ok(reply, rid);
/* XXX exit happens too soon - message never makes it to client */
return 0;
}
static char *
format_forward(u_int ftype, struct Forward *fwd)
{
char *ret;
switch (ftype) {
case MUX_FWD_LOCAL:
xasprintf(&ret, "local forward %.200s:%d -> %.200s:%d",
(fwd->listen_path != NULL) ? fwd->listen_path :
(fwd->listen_host == NULL) ?
(options.fwd_opts.gateway_ports ? "*" : "LOCALHOST") :
fwd->listen_host, fwd->listen_port,
(fwd->connect_path != NULL) ? fwd->connect_path :
fwd->connect_host, fwd->connect_port);
break;
case MUX_FWD_DYNAMIC:
xasprintf(&ret, "dynamic forward %.200s:%d -> *",
(fwd->listen_host == NULL) ?
(options.fwd_opts.gateway_ports ? "*" : "LOCALHOST") :
fwd->listen_host, fwd->listen_port);
break;
case MUX_FWD_REMOTE:
xasprintf(&ret, "remote forward %.200s:%d -> %.200s:%d",
(fwd->listen_path != NULL) ? fwd->listen_path :
(fwd->listen_host == NULL) ?
"LOCALHOST" : fwd->listen_host,
fwd->listen_port,
(fwd->connect_path != NULL) ? fwd->connect_path :
fwd->connect_host, fwd->connect_port);
break;
default:
fatal_f("unknown forward type %u", ftype);
}
return ret;
}
static int
compare_host(const char *a, const char *b)
{
if (a == NULL && b == NULL)
return 1;
if (a == NULL || b == NULL)
return 0;
return strcmp(a, b) == 0;
}
static int
compare_forward(struct Forward *a, struct Forward *b)
{
if (!compare_host(a->listen_host, b->listen_host))
return 0;
if (!compare_host(a->listen_path, b->listen_path))
return 0;
if (a->listen_port != b->listen_port)
return 0;
if (!compare_host(a->connect_host, b->connect_host))
return 0;
if (!compare_host(a->connect_path, b->connect_path))
return 0;
if (a->connect_port != b->connect_port)
return 0;
return 1;
}
static void
mux_confirm_remote_forward(struct ssh *ssh, int type, u_int32_t seq, void *ctxt)
{
struct mux_channel_confirm_ctx *fctx = ctxt;
char *failmsg = NULL;
struct Forward *rfwd;
Channel *c;
struct sshbuf *out;
u_int port;
int r;
if ((c = channel_by_id(ssh, fctx->cid)) == NULL) {
/* no channel for reply */
error_f("unknown channel");
return;
}
if ((out = sshbuf_new()) == NULL)
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)) {
xasprintf(&failmsg, "unknown forwarding id %d", fctx->fid);
goto fail;
}
rfwd = &options.remote_forwards[fctx->fid];
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_fr(r, "parse port");
if (port > 65535) {
fatal("Invalid allocated port %u for "
"mux remote forward to %s:%d", port,
rfwd->connect_host, rfwd->connect_port);
}
rfwd->allocated_port = (int)port;
debug("Allocated port %u for mux remote forward"
" to %s:%d", rfwd->allocated_port,
rfwd->connect_host, rfwd->connect_port);
if ((r = sshbuf_put_u32(out,
MUX_S_REMOTE_PORT)) != 0 ||
(r = sshbuf_put_u32(out, fctx->rid)) != 0 ||
(r = sshbuf_put_u32(out,
rfwd->allocated_port)) != 0)
fatal_fr(r, "reply");
channel_update_permission(ssh, rfwd->handle,
rfwd->allocated_port);
} else {
reply_ok(out, fctx->rid);
}
goto out;
} else {
if (rfwd->listen_port == 0)
channel_update_permission(ssh, rfwd->handle, -1);
if (rfwd->listen_path != NULL)
xasprintf(&failmsg, "remote port forwarding failed for "
"listen path %s", rfwd->listen_path);
else
xasprintf(&failmsg, "remote port forwarding failed for "
"listen port %d", 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);
free(rfwd->listen_host);
free(rfwd->listen_path);
free(rfwd->connect_host);
free(rfwd->connect_path);
memset(rfwd, 0, sizeof(*rfwd));
}
fail:
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_fr(r, "enqueue");
sshbuf_free(out);
if (c->mux_pause <= 0)
fatal_f("mux_pause %d", c->mux_pause);
c->mux_pause = 0; /* start processing messages again */
}
static int
mux_master_process_open_fwd(struct ssh *ssh, u_int rid,
Channel *c, struct sshbuf *m, struct sshbuf *reply)
{
struct Forward fwd;
char *fwd_desc = NULL;
char *listen_addr, *connect_addr;
u_int ftype;
u_int lport, cport;
int r, i, ret = 0, freefwd = 1;
memset(&fwd, 0, sizeof(fwd));
/* XXX - lport/cport check redundant */
if ((r = sshbuf_get_u32(m, &ftype)) != 0 ||
(r = sshbuf_get_cstring(m, &listen_addr, NULL)) != 0 ||
(r = sshbuf_get_u32(m, &lport)) != 0 ||
(r = sshbuf_get_cstring(m, &connect_addr, NULL)) != 0 ||
(r = sshbuf_get_u32(m, &cport)) != 0 ||
(lport != (u_int)PORT_STREAMLOCAL && lport > 65535) ||
(cport != (u_int)PORT_STREAMLOCAL && cport > 65535)) {
error_f("malformed message");
ret = -1;
goto out;
}
if (*listen_addr == '\0') {
free(listen_addr);
listen_addr = NULL;
}
if (*connect_addr == '\0') {
free(connect_addr);
connect_addr = NULL;
}
memset(&fwd, 0, sizeof(fwd));
fwd.listen_port = lport;
if (fwd.listen_port == PORT_STREAMLOCAL)
fwd.listen_path = listen_addr;
else
fwd.listen_host = listen_addr;
fwd.connect_port = cport;
if (fwd.connect_port == PORT_STREAMLOCAL)
fwd.connect_path = connect_addr;
else
fwd.connect_host = connect_addr;
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_f("invalid forwarding type %u", ftype);
invalid:
free(listen_addr);
free(connect_addr);
reply_error(reply, MUX_S_FAILURE, rid,
"Invalid forwarding request");
return 0;
}
if (ftype == MUX_FWD_DYNAMIC && fwd.listen_path) {
logit_f("streamlocal and dynamic forwards "
"are mutually exclusive");
goto invalid;
}
if (fwd.listen_port != PORT_STREAMLOCAL && fwd.listen_port >= 65536) {
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_f("invalid connect port %u",
fwd.connect_port);
goto invalid;
}
if (ftype != MUX_FWD_DYNAMIC && fwd.connect_host == NULL &&
fwd.connect_path == NULL) {
logit_f("missing connect host");
goto invalid;
}
/* Skip forwards that have already been requested */
switch (ftype) {
case MUX_FWD_LOCAL:
case MUX_FWD_DYNAMIC:
for (i = 0; i < options.num_local_forwards; i++) {
if (compare_forward(&fwd,
options.local_forwards + i)) {
exists:
debug2_f("found existing forwarding");
reply_ok(reply, rid);
goto out;
}
}
break;
case MUX_FWD_REMOTE:
for (i = 0; i < options.num_remote_forwards; i++) {
if (!compare_forward(&fwd, options.remote_forwards + i))
continue;
if (fwd.listen_port != 0)
goto exists;
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_fr(r, "reply FWD_REMOTE");
goto out;
}
break;
}
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_f("forwarding refused by user");
reply_error(reply, MUX_S_PERMISSION_DENIED, rid,
"Permission denied");
goto out;
}
}
if (ftype == MUX_FWD_LOCAL || ftype == MUX_FWD_DYNAMIC) {
if (!channel_setup_local_fwd_listener(ssh, &fwd,
&options.fwd_opts)) {
fail:
logit_f("requested %s failed", fwd_desc);
reply_error(reply, MUX_S_FAILURE, rid,
"Port forwarding failed");
goto out;
}
add_local_forward(&options, &fwd);
freefwd = 0;
} else {
struct mux_channel_confirm_ctx *fctx;
fwd.handle = channel_request_remote_forwarding(ssh, &fwd);
if (fwd.handle < 0)
goto fail;
add_remote_forward(&options, &fwd);
fctx = xcalloc(1, sizeof(*fctx));
fctx->cid = c->self;
fctx->rid = rid;
fctx->fid = options.num_remote_forwards - 1;
client_register_global_confirm(mux_confirm_remote_forward,
fctx);
freefwd = 0;
c->mux_pause = 1; /* wait for mux_confirm_remote_forward */
/* delayed reply in mux_confirm_remote_forward */
goto out;
}
reply_ok(reply, rid);
out:
free(fwd_desc);
if (freefwd) {
free(fwd.listen_host);
free(fwd.listen_path);
free(fwd.connect_host);
free(fwd.connect_path);
}
return ret;
}
static int
mux_master_process_close_fwd(struct ssh *ssh, u_int rid,
Channel *c, struct sshbuf *m, struct sshbuf *reply)
{
struct Forward fwd, *found_fwd;
char *fwd_desc = NULL;
const char *error_reason = NULL;
char *listen_addr = NULL, *connect_addr = NULL;
u_int ftype;
int r, i, ret = 0;
u_int lport, cport;
memset(&fwd, 0, sizeof(fwd));
if ((r = sshbuf_get_u32(m, &ftype)) != 0 ||
(r = sshbuf_get_cstring(m, &listen_addr, NULL)) != 0 ||
(r = sshbuf_get_u32(m, &lport)) != 0 ||
(r = sshbuf_get_cstring(m, &connect_addr, NULL)) != 0 ||
(r = sshbuf_get_u32(m, &cport)) != 0 ||
(lport != (u_int)PORT_STREAMLOCAL && lport > 65535) ||
(cport != (u_int)PORT_STREAMLOCAL && cport > 65535)) {
error_f("malformed message");
ret = -1;
goto out;
}
if (*listen_addr == '\0') {
free(listen_addr);
listen_addr = NULL;
}
if (*connect_addr == '\0') {
free(connect_addr);
connect_addr = NULL;
}
memset(&fwd, 0, sizeof(fwd));
fwd.listen_port = lport;
if (fwd.listen_port == PORT_STREAMLOCAL)
fwd.listen_path = listen_addr;
else
fwd.listen_host = listen_addr;
fwd.connect_port = cport;
if (fwd.connect_port == PORT_STREAMLOCAL)
fwd.connect_path = connect_addr;
else
fwd.connect_host = connect_addr;
debug2_f("channel %d: request cancel %s", c->self,
(fwd_desc = format_forward(ftype, &fwd)));
/* make sure this has been requested */
found_fwd = NULL;
switch (ftype) {
case MUX_FWD_LOCAL:
case MUX_FWD_DYNAMIC:
for (i = 0; i < options.num_local_forwards; i++) {
if (compare_forward(&fwd,
options.local_forwards + i)) {
found_fwd = options.local_forwards + i;
break;
}
}
break;
case MUX_FWD_REMOTE:
for (i = 0; i < options.num_remote_forwards; i++) {
if (compare_forward(&fwd,
options.remote_forwards + i)) {
found_fwd = options.remote_forwards + i;
break;
}
}
break;
}
if (found_fwd == NULL)
error_reason = "port not forwarded";
else if (ftype == MUX_FWD_REMOTE) {
/*
* This shouldn't fail unless we confused the host/port
* between options.remote_forwards and permitted_opens.
* However, for dynamic allocated listen ports we need
* to use the actual listen port.
*/
if (channel_request_rforward_cancel(ssh, found_fwd) == -1)
error_reason = "port not in permitted opens";
} else { /* local and dynamic forwards */
/* Ditto */
if (channel_cancel_lport_listener(ssh, &fwd, fwd.connect_port,
&options.fwd_opts) == -1)
error_reason = "port not found";
}
if (error_reason != NULL)
reply_error(reply, MUX_S_FAILURE, rid, error_reason);
else {
reply_ok(reply, rid);
free(found_fwd->listen_host);
free(found_fwd->listen_path);
free(found_fwd->connect_host);
free(found_fwd->connect_path);
found_fwd->listen_host = found_fwd->connect_host = NULL;
found_fwd->listen_path = found_fwd->connect_path = NULL;
found_fwd->listen_port = found_fwd->connect_port = 0;
}
out:
free(fwd_desc);
free(listen_addr);
free(connect_addr);
return ret;
}
static int
mux_master_process_stdio_fwd(struct ssh *ssh, u_int rid,
Channel *c, struct sshbuf *m, struct sshbuf *reply)
{
Channel *nc;
char *chost = NULL;
u_int cport, i, j;
int r, new_fd[2];
struct mux_stdio_confirm_ctx *cctx;
if ((r = sshbuf_skip_string(m)) != 0 || /* reserved */
(r = sshbuf_get_cstring(m, &chost, NULL)) != 0 ||
(r = sshbuf_get_u32(m, &cport)) != 0) {
free(chost);
error_f("malformed message");
return -1;
}
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_f("failed to receive fd %d from client", i);
for (j = 0; j < i; j++)
close(new_fd[j]);
free(chost);
/* prepare reply */
reply_error(reply, MUX_S_FAILURE, rid,
"did not receive file descriptors");
return -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_f("session already open");
reply_error(reply, MUX_S_FAILURE, rid,
"Multiple sessions not supported");
cleanup:
close(new_fd[0]);
close(new_fd[1]);
free(chost);
return 0;
}
if (options.control_master == SSHCTL_MASTER_ASK ||
options.control_master == SSHCTL_MASTER_AUTO_ASK) {
if (!ask_permission("Allow forward to %s:%u? ",
chost, cport)) {
debug2_f("stdio fwd refused by user");
reply_error(reply, MUX_S_PERMISSION_DENIED, rid,
"Permission denied");
goto cleanup;
}
}
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->have_remote_id = 1;
debug2_f("channel_new: %d control %d", nc->self, nc->ctl_chan);
channel_register_cleanup(ssh, nc->self,
mux_master_session_cleanup_cb, 1);
cctx = xcalloc(1, sizeof(*cctx));
cctx->rid = rid;
channel_register_open_confirm(ssh, nc->self, mux_stdio_confirm, cctx);
c->mux_pause = 1; /* stop handling messages until open_confirm done */
/* reply is deferred, sent by mux_session_confirm */
return 0;
}
/* Callback on open confirmation in mux master for a mux stdio fwd session. */
static void
mux_stdio_confirm(struct ssh *ssh, int id, int success, void *arg)
{
struct mux_stdio_confirm_ctx *cctx = arg;
Channel *c, *cc;
struct sshbuf *reply;
int r;
if (cctx == NULL)
fatal_f("cctx == NULL");
if ((c = channel_by_id(ssh, id)) == NULL)
fatal_f("no channel for id %d", id);
if ((cc = channel_by_id(ssh, c->ctl_chan)) == NULL)
fatal_f("channel %d lacks control channel %d",
id, c->ctl_chan);
if ((reply = sshbuf_new()) == NULL)
fatal_f("sshbuf_new");
if (!success) {
debug3_f("sending failure reply");
reply_error(reply, MUX_S_FAILURE, cctx->rid,
"Session open refused by peer");
/* prepare reply */
goto done;
}
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_fr(r, "reply");
done:
/* Send reply */
if ((r = sshbuf_put_stringb(cc->output, reply)) != 0)
fatal_fr(r, "enqueue");
sshbuf_free(reply);
if (cc->mux_pause <= 0)
fatal_f("mux_pause %d", cc->mux_pause);
cc->mux_pause = 0; /* start processing messages again */
c->open_confirm_ctx = NULL;
free(cctx);
}
static int
mux_master_process_stop_listening(struct ssh *ssh, u_int rid,
Channel *c, struct sshbuf *m, struct sshbuf *reply)
{
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_f("stop listen refused by user");
reply_error(reply, MUX_S_PERMISSION_DENIED, rid,
"Permission denied");
return 0;
}
}
if (mux_listener_channel != NULL) {
channel_free(ssh, mux_listener_channel);
client_stop_mux();
free(options.control_path);
options.control_path = NULL;
mux_listener_channel = NULL;
muxserver_sock = -1;
}
reply_ok(reply, rid);
return 0;
}
static int
mux_master_process_proxy(struct ssh *ssh, u_int rid,
Channel *c, struct sshbuf *m, struct sshbuf *reply)
{
int r;
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_fr(r, "reply");
return 0;
}
/* Channel callbacks fired on read/write from mux client fd */
static int
mux_master_read_cb(struct ssh *ssh, Channel *c)
{
struct mux_master_state *state = (struct mux_master_state *)c->mux_ctx;
struct sshbuf *in = NULL, *out = NULL;
u_int type, rid, i;
int r, ret = -1;
if ((out = sshbuf_new()) == NULL)
fatal_f("sshbuf_new");
/* Setup ctx and */
if (c->mux_ctx == NULL) {
state = xcalloc(1, sizeof(*state));
c->mux_ctx = state;
channel_register_cleanup(ssh, c->self,
mux_master_control_cleanup_cb, 0);
/* Send hello */
if ((r = sshbuf_put_u32(out, MUX_MSG_HELLO)) != 0 ||
(r = sshbuf_put_u32(out, SSHMUX_VER)) != 0)
fatal_fr(r, "reply");
/* no extensions */
if ((r = sshbuf_put_stringb(c->output, out)) != 0)
fatal_fr(r, "enqueue");
debug3_f("channel %d: hello sent", c->self);
ret = 0;
goto out;
}
/* Channel code ensures that we receive whole packets */
if ((r = sshbuf_froms(c->input, &in)) != 0) {
malf:
error_f("malformed message");
goto out;
}
if ((r = sshbuf_get_u32(in, &type)) != 0)
goto malf;
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_f("expected MUX_MSG_HELLO(0x%08x), "
"received 0x%08x", MUX_MSG_HELLO, type);
goto out;
}
if ((r = sshbuf_get_u32(in, &rid)) != 0)
goto malf;
}
for (i = 0; mux_master_handlers[i].handler != NULL; i++) {
if (type == mux_master_handlers[i].type) {
ret = mux_master_handlers[i].handler(ssh, rid,
c, in, out);
break;
}
}
if (mux_master_handlers[i].handler == NULL) {
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 &&
(r = sshbuf_put_stringb(c->output, out)) != 0)
fatal_fr(r, "enqueue");
out:
sshbuf_free(in);
sshbuf_free(out);
return ret;
}
void
mux_exit_message(struct ssh *ssh, Channel *c, int exitval)
{
struct sshbuf *m;
Channel *mux_chan;
int r;
debug3_f("channel %d: exit message, exitval %d", c->self, exitval);
if ((mux_chan = channel_by_id(ssh, c->ctl_chan)) == NULL)
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_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_fr(r, "reply");
sshbuf_free(m);
}
void
mux_tty_alloc_failed(struct ssh *ssh, Channel *c)
{
struct sshbuf *m;
Channel *mux_chan;
int r;
debug3_f("channel %d: TTY alloc failed", c->self);
if ((mux_chan = channel_by_id(ssh, c->ctl_chan)) == NULL)
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_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_fr(r, "reply");
sshbuf_free(m);
}
/* Prepare a mux master to listen on a Unix domain socket. */
void
muxserver_listen(struct ssh *ssh)
{
mode_t old_umask;
char *orig_control_path = options.control_path;
char rbuf[16+1];
u_int i, r;
int oerrno;
if (options.control_path == NULL ||
options.control_master == SSHCTL_MASTER_NO)
return;
debug("setting up multiplex master socket");
/*
* Use a temporary path before listen so we can pseudo-atomically
* establish the listening socket in its final location to avoid
* other processes racing in between bind() and listen() and hitting
* an unready socket.
*/
for (i = 0; i < sizeof(rbuf) - 1; i++) {
r = arc4random_uniform(26+26+10);
rbuf[i] = (r < 26) ? 'a' + r :
(r < 26*2) ? 'A' + r - 26 :
'0' + r - 26 - 26;
}
rbuf[sizeof(rbuf) - 1] = '\0';
options.control_path = NULL;
xasprintf(&options.control_path, "%s.%s", orig_control_path, rbuf);
debug3_f("temporary control path %s", options.control_path);
old_umask = umask(0177);
muxserver_sock = unix_listener(options.control_path, 64, 0);
oerrno = errno;
umask(old_umask);
if (muxserver_sock < 0) {
if (oerrno == EINVAL || oerrno == EADDRINUSE) {
error("ControlSocket %s already exists, "
"disabling multiplexing", options.control_path);
disable_mux_master:
if (muxserver_sock != -1) {
close(muxserver_sock);
muxserver_sock = -1;
}
free(orig_control_path);
free(options.control_path);
options.control_path = NULL;
options.control_master = SSHCTL_MASTER_NO;
return;
} else {
/* unix_listener() logs the error */
cleanup_exit(255);
}
}
/* Now atomically "move" the mux socket into position */
if (link(options.control_path, orig_control_path) != 0) {
if (errno != EEXIST) {
fatal_f("link mux listener %s => %s: %s",
options.control_path, orig_control_path,
strerror(errno));
}
error("ControlSocket %s already exists, disabling multiplexing",
orig_control_path);
unlink(options.control_path);
goto disable_mux_master;
}
unlink(options.control_path);
free(options.control_path);
options.control_path = orig_control_path;
set_nonblock(muxserver_sock);
mux_listener_channel = channel_new(ssh, "mux listener",
SSH_CHANNEL_MUX_LISTENER, muxserver_sock, muxserver_sock, -1,
CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,
0, options.control_path, 1);
mux_listener_channel->mux_rcb = mux_master_read_cb;
debug3_f("mux listener channel %d fd %d",
mux_listener_channel->self, mux_listener_channel->sock);
}
/* Callback on open confirmation in mux master for a mux client session. */
static void
mux_session_confirm(struct ssh *ssh, int id, int success, void *arg)
{
struct mux_session_confirm_ctx *cctx = arg;
const char *display;
Channel *c, *cc;
int i, r;
struct sshbuf *reply;
if (cctx == NULL)
fatal_f("cctx == NULL");
if ((c = channel_by_id(ssh, id)) == NULL)
fatal_f("no channel for id %d", id);
if ((cc = channel_by_id(ssh, c->ctl_chan)) == NULL)
fatal_f("channel %d lacks control channel %d",
id, c->ctl_chan);
if ((reply = sshbuf_new()) == NULL)
fatal_f("sshbuf_new");
if (!success) {
debug3_f("sending failure reply");
reply_error(reply, MUX_S_FAILURE, cctx->rid,
"Session open refused by peer");
goto done;
}
display = getenv("DISPLAY");
if (cctx->want_x_fwd && options.forward_x11 && display != NULL) {
char *proto, *data;
/* Get reasonable local authentication information. */
if (client_x11_get_proto(ssh, display, options.xauth_location,
options.forward_x11_trusted, options.forward_x11_timeout,
&proto, &data) == 0) {
/* Request forwarding with authentication spoofing. */
debug("Requesting X11 forwarding with authentication "
"spoofing.");
x11_request_forwarding_with_spoofing(ssh, id,
display, proto, data, 1);
/* XXX exit_on_forward_failure */
client_expect_confirm(ssh, id, "X11 forwarding",
CONFIRM_WARN);
}
}
if (cctx->want_agent_fwd && options.forward_agent) {
debug("Requesting authentication agent forwarding.");
channel_request_start(ssh, id, "auth-agent-req@openssh.com", 0);
if ((r = sshpkt_send(ssh)) != 0)
fatal_fr(r, "send");
}
client_session2_setup(ssh, id, cctx->want_tty, cctx->want_subsys,
cctx->term, &cctx->tio, c->rfd, cctx->cmd, cctx->env);
debug3_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_fr(r, "reply");
done:
/* Send reply */
if ((r = sshbuf_put_stringb(cc->output, reply)) != 0)
fatal_fr(r, "enqueue");
sshbuf_free(reply);
if (cc->mux_pause <= 0)
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);
free(cctx->term);
if (cctx->env != NULL) {
for (i = 0; cctx->env[i] != NULL; i++)
free(cctx->env[i]);
free(cctx->env);
}
free(cctx);
}
/* ** Multiplexing client support */
/* Exit signal handler */
static void
control_client_sighandler(int signo)
{
muxclient_terminate = signo;
}
/*
* Relay signal handler - used to pass some signals from mux client to
* mux master.
*/
static void
control_client_sigrelay(int signo)
{
int save_errno = errno;
if (muxserver_pid > 1)
kill(muxserver_pid, signo);
errno = save_errno;
}
static int
mux_client_read(int fd, struct sshbuf *b, size_t need)
{
size_t have;
ssize_t len;
u_char *p;
struct pollfd pfd;
int r;
pfd.fd = fd;
pfd.events = POLLIN;
if ((r = sshbuf_reserve(b, need, &p)) != 0)
fatal_fr(r, "reserve");
for (have = 0; have < need; ) {
if (muxclient_terminate) {
errno = EINTR;
return -1;
}
len = read(fd, p + have, need - have);
if (len == -1) {
switch (errno) {
#if defined(EWOULDBLOCK) && (EWOULDBLOCK != EAGAIN)
case EWOULDBLOCK:
#endif
case EAGAIN:
(void)poll(&pfd, 1, -1);
/* FALLTHROUGH */
case EINTR:
continue;
default:
return -1;
}
}
if (len == 0) {
errno = EPIPE;
return -1;
}
have += (size_t)len;
}
return 0;
}
static int
mux_client_write_packet(int fd, struct sshbuf *m)
{
struct sshbuf *queue;
u_int have, need;
int r, oerrno, len;
const u_char *ptr;
struct pollfd pfd;
pfd.fd = fd;
pfd.events = POLLOUT;
if ((queue = sshbuf_new()) == NULL)
fatal_f("sshbuf_new");
if ((r = sshbuf_put_stringb(queue, m)) != 0)
fatal_fr(r, "enqueue");
need = sshbuf_len(queue);
ptr = sshbuf_ptr(queue);
for (have = 0; have < need; ) {
if (muxclient_terminate) {
sshbuf_free(queue);
errno = EINTR;
return -1;
}
len = write(fd, ptr + have, need - have);
if (len == -1) {
switch (errno) {
#if defined(EWOULDBLOCK) && (EWOULDBLOCK != EAGAIN)
case EWOULDBLOCK:
#endif
case EAGAIN:
(void)poll(&pfd, 1, -1);
/* FALLTHROUGH */
case EINTR:
continue;
default:
oerrno = errno;
sshbuf_free(queue);
errno = oerrno;
return -1;
}
}
if (len == 0) {
sshbuf_free(queue);
errno = EPIPE;
return -1;
}
have += (u_int)len;
}
sshbuf_free(queue);
return 0;
}
static int
mux_client_read_packet(int fd, struct sshbuf *m)
{
struct sshbuf *queue;
size_t need, have;
const u_char *ptr;
int r, oerrno;
if ((queue = sshbuf_new()) == NULL)
fatal_f("sshbuf_new");
if (mux_client_read(fd, queue, 4) != 0) {
if ((oerrno = errno) == EPIPE)
debug3_f("read header failed: %s",
strerror(errno));
sshbuf_free(queue);
errno = oerrno;
return -1;
}
need = PEEK_U32(sshbuf_ptr(queue));
if (mux_client_read(fd, queue, need) != 0) {
oerrno = 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_fr(r, "dequeue");
sshbuf_free(queue);
return 0;
}
static int
mux_client_hello_exchange(int fd)
{
struct sshbuf *m;
u_int type, ver;
int r, ret = -1;
if ((m = sshbuf_new()) == NULL)
fatal_f("sshbuf_new");
if ((r = sshbuf_put_u32(m, MUX_MSG_HELLO)) != 0 ||
(r = sshbuf_put_u32(m, SSHMUX_VER)) != 0)
fatal_fr(r, "assemble hello");
/* no extensions */
if (mux_client_write_packet(fd, m) != 0) {
debug_f("write packet: %s", strerror(errno));
goto out;
}
sshbuf_reset(m);
/* Read their HELLO */
if (mux_client_read_packet(fd, m) != 0) {
debug_f("read packet failed");
goto out;
}
if ((r = sshbuf_get_u32(m, &type)) != 0)
fatal_fr(r, "parse type");
if (type != MUX_MSG_HELLO) {
error_f("expected HELLO (%u) got %u", MUX_MSG_HELLO, type);
goto out;
}
if ((r = sshbuf_get_u32(m, &ver)) != 0)
fatal_fr(r, "parse version");
if (ver != SSHMUX_VER) {
error("Unsupported multiplexing protocol version %d "
"(expected %d)", ver, SSHMUX_VER);
goto out;
}
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_fr(r, "parse extension");
goto out;
}
debug2("Unrecognised master extension \"%s\"", name);
free(name);
}
/* success */
ret = 0;
out:
sshbuf_free(m);
return ret;
}
static u_int
mux_client_request_alive(int fd)
{
struct sshbuf *m;
char *e;
u_int pid, type, rid;
int r;
debug3_f("entering");
if ((m = sshbuf_new()) == NULL)
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_fr(r, "assemble");
if (mux_client_write_packet(fd, m) != 0)
fatal_f("write packet: %s", strerror(errno));
sshbuf_reset(m);
/* Read their reply */
if (mux_client_read_packet(fd, m) != 0) {
sshbuf_free(m);
return 0;
}
if ((r = sshbuf_get_u32(m, &type)) != 0)
fatal_fr(r, "parse type");
if (type != MUX_S_ALIVE) {
if ((r = sshbuf_get_cstring(m, &e, NULL)) != 0)
fatal_fr(r, "parse error message");
fatal_f("master returned error: %s", e);
}
if ((r = sshbuf_get_u32(m, &rid)) != 0)
fatal_fr(r, "parse remote ID");
if (rid != muxclient_request_id)
fatal_f("out of sequence reply: my id %u theirs %u",
muxclient_request_id, rid);
if ((r = sshbuf_get_u32(m, &pid)) != 0)
fatal_fr(r, "parse PID");
sshbuf_free(m);
debug3_f("done pid = %u", pid);
muxclient_request_id++;
return pid;
}
static void
mux_client_request_terminate(int fd)
{
struct sshbuf *m;
char *e;
u_int type, rid;
int r;
debug3_f("entering");
if ((m = sshbuf_new()) == NULL)
fatal_f("sshbuf_new");
if ((r = sshbuf_put_u32(m, MUX_C_TERMINATE)) != 0 ||
(r = sshbuf_put_u32(m, muxclient_request_id)) != 0)
fatal_fr(r, "request");
if (mux_client_write_packet(fd, m) != 0)
fatal_f("write packet: %s", strerror(errno));
sshbuf_reset(m);
/* Read their reply */
if (mux_client_read_packet(fd, m) != 0) {
/* Remote end exited already */
if (errno == EPIPE) {
sshbuf_free(m);
return;
}
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_fr(r, "parse");
if (rid != muxclient_request_id)
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_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_fr(r, "parse error message");
fatal_f("termination request failed: %s", e);
default:
fatal_f("unexpected response from master 0x%08x", type);
}
sshbuf_free(m);
muxclient_request_id++;
}
static int
mux_client_forward(int fd, int cancel_flag, u_int ftype, struct Forward *fwd)
{
struct sshbuf *m;
char *e, *fwd_desc;
const char *lhost, *chost;
u_int type, rid;
int r;
fwd_desc = format_forward(ftype, fwd);
debug("Requesting %s %s",
cancel_flag ? "cancellation of" : "forwarding of", fwd_desc);
free(fwd_desc);
type = cancel_flag ? MUX_C_CLOSE_FWD : MUX_C_OPEN_FWD;
if (fwd->listen_path != NULL)
lhost = fwd->listen_path;
else if (fwd->listen_host == NULL)
lhost = "";
else if (*fwd->listen_host == '\0')
lhost = "*";
else
lhost = fwd->listen_host;
if (fwd->connect_path != NULL)
chost = fwd->connect_path;
else if (fwd->connect_host == NULL)
chost = "";
else
chost = fwd->connect_host;
if ((m = sshbuf_new()) == NULL)
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 ||
(r = sshbuf_put_cstring(m, lhost)) != 0 ||
(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_fr(r, "request");
if (mux_client_write_packet(fd, m) != 0)
fatal_f("write packet: %s", strerror(errno));
sshbuf_reset(m);
/* Read their reply */
if (mux_client_read_packet(fd, m) != 0) {
sshbuf_free(m);
return -1;
}
if ((r = sshbuf_get_u32(m, &type)) != 0 ||
(r = sshbuf_get_u32(m, &rid)) != 0)
fatal_fr(r, "parse");
if (rid != muxclient_request_id)
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_f("got MUX_S_REMOTE_PORT for cancel");
if ((r = sshbuf_get_u32(m, &fwd->allocated_port)) != 0)
fatal_fr(r, "parse port");
verbose("Allocated port %u for remote forward to %s:%d",
fwd->allocated_port,
fwd->connect_host ? fwd->connect_host : "",
fwd->connect_port);
if (muxclient_command == SSHMUX_COMMAND_FORWARD)
fprintf(stdout, "%i\n", fwd->allocated_port);
break;
case MUX_S_PERMISSION_DENIED:
if ((r = sshbuf_get_cstring(m, &e, NULL)) != 0)
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_fr(r, "parse error message");
sshbuf_free(m);
error_f("forwarding request failed: %s", e);
return -1;
default:
fatal_f("unexpected response from master 0x%08x", type);
}
sshbuf_free(m);
muxclient_request_id++;
return 0;
}
static int
mux_client_forwards(int fd, int cancel_flag)
{
int i, ret = 0;
debug3_f("%s forwardings: %d local, %d remote",
cancel_flag ? "cancel" : "request",
options.num_local_forwards, options.num_remote_forwards);
/* XXX ExitOnForwardingFailure */
for (i = 0; i < options.num_local_forwards; i++) {
if (mux_client_forward(fd, cancel_flag,
options.local_forwards[i].connect_port == 0 ?
MUX_FWD_DYNAMIC : MUX_FWD_LOCAL,
options.local_forwards + i) != 0)
ret = -1;
}
for (i = 0; i < options.num_remote_forwards; i++) {
if (mux_client_forward(fd, cancel_flag, MUX_FWD_REMOTE,
options.remote_forwards + i) != 0)
ret = -1;
}
return ret;
}
static int
mux_client_request_session(int fd)
{
struct sshbuf *m;
char *e;
const char *term = NULL;
u_int i, echar, rid, sid, esid, exitval, type, exitval_seen;
extern char **environ;
int r, rawmode;
debug3_f("entering");
if ((muxserver_pid = mux_client_request_alive(fd)) == 0) {
error_f("master alive request failed");
return -1;
}
ssh_signal(SIGPIPE, SIG_IGN);
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");
echar = 0xffffffff;
if (options.escape_char != SSH_ESCAPECHAR_NONE)
echar = (u_int)options.escape_char;
if ((m = sshbuf_new()) == NULL)
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, options.session_type == SESSION_TYPE_SUBSYSTEM)) != 0 ||
(r = sshbuf_put_u32(m, echar)) != 0 ||
(r = sshbuf_put_cstring(m, term == NULL ? "" : term)) != 0 ||
(r = sshbuf_put_stringb(m, command)) != 0)
fatal_fr(r, "request");
/* Pass environment */
if (options.num_send_env > 0 && environ != NULL) {
for (i = 0; environ[i] != NULL; i++) {
if (!env_permitted(environ[i]))
continue;
if ((r = sshbuf_put_cstring(m, environ[i])) != 0)
fatal_fr(r, "request sendenv");
}
}
for (i = 0; i < options.num_setenv; i++) {
if ((r = sshbuf_put_cstring(m, options.setenv[i])) != 0)
fatal_fr(r, "request setenv");
}
if (mux_client_write_packet(fd, m) != 0)
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_f("send fds failed");
debug3_f("session request sent");
/* Read their reply */
sshbuf_reset(m);
if (mux_client_read_packet(fd, m) != 0) {
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_fr(r, "parse");
if (rid != muxclient_request_id)
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_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_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_fr(r, "parse error message");
error_f("session request failed: %s", e);
sshbuf_free(m);
return -1;
default:
sshbuf_free(m);
error_f("unexpected response from master 0x%08x", type);
return -1;
}
muxclient_request_id++;
if (pledge("stdio proc tty", NULL) == -1)
fatal_f("pledge(): %s", strerror(errno));
platform_pledge_mux();
ssh_signal(SIGHUP, control_client_sighandler);
ssh_signal(SIGINT, control_client_sighandler);
ssh_signal(SIGTERM, control_client_sighandler);
ssh_signal(SIGWINCH, control_client_sigrelay);
rawmode = tty_flag;
if (tty_flag)
enter_raw_mode(options.request_tty == REQUEST_TTY_FORCE);
/*
* Stick around until the controlee closes the client_fd.
* Before it does, it is expected to write an exit message.
* This process must read the value and wait for the closure of
* the client_fd; if this one closes early, the multiplex master will
* terminate early too (possibly losing data).
*/
for (exitval = 255, exitval_seen = 0;;) {
sshbuf_reset(m);
if (mux_client_read_packet(fd, m) != 0)
break;
if ((r = sshbuf_get_u32(m, &type)) != 0)
fatal_fr(r, "parse type");
switch (type) {
case MUX_S_TTY_ALLOC_FAIL:
if ((r = sshbuf_get_u32(m, &esid)) != 0)
fatal_fr(r, "parse session ID");
if (esid != sid)
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_fr(r, "parse session ID");
if (esid != sid)
fatal_f("exit on unknown session: "
"my id %u theirs %u", sid, esid);
if (exitval_seen)
fatal_f("exitval sent twice");
if ((r = sshbuf_get_u32(m, &exitval)) != 0)
fatal_fr(r, "parse exitval");
exitval_seen = 1;
continue;
default:
if ((r = sshbuf_get_cstring(m, &e, NULL)) != 0)
fatal_fr(r, "parse error message");
fatal_f("master returned error: %s", e);
}
}
close(fd);
if (rawmode)
leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE);
if (muxclient_terminate) {
debug2("Exiting on signal: %s", strsignal(muxclient_terminate));
exitval = 255;
} else if (!exitval_seen) {
debug2("Control master terminated unexpectedly");
exitval = 255;
} else
debug2("Received exit status from master %d", exitval);
if (tty_flag && options.log_level >= SYSLOG_LEVEL_INFO)
fprintf(stderr, "Shared connection to %s closed.\r\n", host);
exit(exitval);
}
static int
mux_client_proxy(int fd)
{
struct sshbuf *m;
char *e;
u_int type, rid;
int r;
if ((m = sshbuf_new()) == NULL)
fatal_f("sshbuf_new");
if ((r = sshbuf_put_u32(m, MUX_C_PROXY)) != 0 ||
(r = sshbuf_put_u32(m, muxclient_request_id)) != 0)
fatal_fr(r, "request");
if (mux_client_write_packet(fd, m) != 0)
fatal_f("write packet: %s", strerror(errno));
sshbuf_reset(m);
/* Read their reply */
if (mux_client_read_packet(fd, m) != 0) {
sshbuf_free(m);
return 0;
}
if ((r = sshbuf_get_u32(m, &type)) != 0 ||
(r = sshbuf_get_u32(m, &rid)) != 0)
fatal_fr(r, "parse");
if (rid != muxclient_request_id)
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_fr(r, "parse error message");
fatal_f("master returned error: %s", e);
}
sshbuf_free(m);
debug3_f("done");
muxclient_request_id++;
return 0;
}
static int
mux_client_request_stdio_fwd(int fd)
{
struct sshbuf *m;
char *e;
u_int type, rid, sid;
int r;
debug3_f("entering");
if ((muxserver_pid = mux_client_request_alive(fd)) == 0) {
error_f("master alive request failed");
return -1;
}
ssh_signal(SIGPIPE, SIG_IGN);
if (options.stdin_null && stdfd_devnull(1, 0, 0) == -1)
fatal_f("stdfd_devnull failed");
if ((m = sshbuf_new()) == NULL)
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_fr(r, "request");
if (mux_client_write_packet(fd, m) != 0)
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_f("send fds failed");
if (pledge("stdio proc tty", NULL) == -1)
fatal_f("pledge(): %s", strerror(errno));
platform_pledge_mux();
debug3_f("stdio forward request sent");
/* Read their reply */
sshbuf_reset(m);
if (mux_client_read_packet(fd, m) != 0) {
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_fr(r, "parse");
if (rid != muxclient_request_id)
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_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_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_fr(r, "parse error message");
sshbuf_free(m);
fatal("Stdio forwarding request failed: %s", e);
default:
sshbuf_free(m);
error_f("unexpected response from master 0x%08x", type);
return -1;
}
muxclient_request_id++;
ssh_signal(SIGHUP, control_client_sighandler);
ssh_signal(SIGINT, control_client_sighandler);
ssh_signal(SIGTERM, control_client_sighandler);
ssh_signal(SIGWINCH, control_client_sigrelay);
/*
* Stick around until the controlee closes the client_fd.
*/
sshbuf_reset(m);
if (mux_client_read_packet(fd, m) != 0) {
if (errno == EPIPE ||
(errno == EINTR && muxclient_terminate != 0))
return 0;
fatal_f("mux_client_read_packet: %s", strerror(errno));
}
fatal_f("master returned unexpected message %u", type);
}
static void
mux_client_request_stop_listening(int fd)
{
struct sshbuf *m;
char *e;
u_int type, rid;
int r;
debug3_f("entering");
if ((m = sshbuf_new()) == NULL)
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_fr(r, "request");
if (mux_client_write_packet(fd, m) != 0)
fatal_f("write packet: %s", strerror(errno));
sshbuf_reset(m);
/* Read their reply */
if (mux_client_read_packet(fd, m) != 0)
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_fr(r, "parse");
if (rid != muxclient_request_id)
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_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_fr(r, "parse error message");
fatal_f("stop listening request failed: %s", e);
default:
fatal_f("unexpected response from master 0x%08x", type);
}
sshbuf_free(m);
muxclient_request_id++;
}
/* Multiplex client main loop. */
int
muxclient(const char *path)
{
struct sockaddr_un addr;
int sock;
u_int pid;
if (muxclient_command == 0) {
if (options.stdio_forward_host != NULL)
muxclient_command = SSHMUX_COMMAND_STDIO_FWD;
else
muxclient_command = SSHMUX_COMMAND_OPEN;
}
switch (options.control_master) {
case SSHCTL_MASTER_AUTO:
case SSHCTL_MASTER_AUTO_ASK:
debug("auto-mux: Trying existing master");
/* FALLTHROUGH */
case SSHCTL_MASTER_NO:
break;
default:
return -1;
}
memset(&addr, '\0', sizeof(addr));
addr.sun_family = AF_UNIX;
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));
if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) == -1)
fatal_f("socket(): %s", strerror(errno));
if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
switch (muxclient_command) {
case SSHMUX_COMMAND_OPEN:
case SSHMUX_COMMAND_STDIO_FWD:
break;
default:
fatal("Control socket connect(%.100s): %s", path,
strerror(errno));
}
if (errno == ECONNREFUSED &&
options.control_master != SSHCTL_MASTER_NO) {
debug("Stale control socket %.100s, unlinking", path);
unlink(path);
} else if (errno == ENOENT) {
debug("Control socket \"%.100s\" does not exist", path);
} else {
error("Control socket connect(%.100s): %s", path,
strerror(errno));
}
close(sock);
return -1;
}
set_nonblock(sock);
if (mux_client_hello_exchange(sock) != 0) {
error_f("master hello exchange failed");
close(sock);
return -1;
}
switch (muxclient_command) {
case SSHMUX_COMMAND_ALIVE_CHECK:
if ((pid = mux_client_request_alive(sock)) == 0)
fatal_f("master alive check failed");
fprintf(stderr, "Master running (pid=%u)\r\n", pid);
exit(0);
case SSHMUX_COMMAND_TERMINATE:
mux_client_request_terminate(sock);
if (options.log_level != SYSLOG_LEVEL_QUIET)
fprintf(stderr, "Exit request sent.\r\n");
exit(0);
case SSHMUX_COMMAND_FORWARD:
if (mux_client_forwards(sock, 0) != 0)
fatal_f("master forward request failed");
exit(0);
case SSHMUX_COMMAND_OPEN:
if (mux_client_forwards(sock, 0) != 0) {
error_f("master forward request failed");
return -1;
}
mux_client_request_session(sock);
return -1;
case SSHMUX_COMMAND_STDIO_FWD:
mux_client_request_stdio_fwd(sock);
exit(0);
case SSHMUX_COMMAND_STOP:
mux_client_request_stop_listening(sock);
if (options.log_level != SYSLOG_LEVEL_QUIET)
fprintf(stderr, "Stop listening request sent.\r\n");
exit(0);
case SSHMUX_COMMAND_CANCEL_FWD:
if (mux_client_forwards(sock, 1) != 0)
error_f("master cancel forward request failed");
exit(0);
case SSHMUX_COMMAND_PROXY:
mux_client_proxy(sock);
return (sock);
default:
fatal("unrecognised muxclient_command %d", muxclient_command);
}
}
diff --git a/crypto/openssh/openbsd-compat/arc4random.c b/crypto/openssh/openbsd-compat/arc4random.c
index 02f15f9c3bfa..ffd33734db56 100644
--- a/crypto/openssh/openbsd-compat/arc4random.c
+++ b/crypto/openssh/openbsd-compat/arc4random.c
@@ -1,252 +1,254 @@
/* $OpenBSD: arc4random.c,v 1.58 2022/07/31 13:41:45 tb Exp $ */
/*
* Copyright (c) 1996, David Mazieres <dm@uun.org>
* Copyright (c) 2008, Damien Miller <djm@openbsd.org>
* Copyright (c) 2013, Markus Friedl <markus@openbsd.org>
* Copyright (c) 2014, Theo de Raadt <deraadt@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.
*/
/*
* ChaCha based random number generator for OpenBSD.
*/
/* OPENBSD ORIGINAL: lib/libc/crypt/arc4random.c */
#include "includes.h"
#include <sys/types.h>
#include <fcntl.h>
#include <limits.h>
#include <signal.h>
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/time.h>
#ifndef HAVE_ARC4RANDOM
/*
- * If we're not using a native getentropy, use the one from bsd-getentropy.c
- * under a different name, so that if in future these binaries are run on
- * a system that has a native getentropy OpenSSL cannot call the wrong one.
+ * Always use the getentropy implementation from bsd-getentropy.c, which
+ * will call a native getentropy if available then fall back as required.
+ * We use a different name so that OpenSSL cannot call the wrong getentropy.
*/
-#ifndef HAVE_GETENTROPY
-# define getentropy(x, y) (_ssh_compat_getentropy((x), (y)))
+int _ssh_compat_getentropy(void *, size_t);
+#ifdef getentropy
+# undef getentropy
#endif
+#define getentropy(x, y) (_ssh_compat_getentropy((x), (y)))
#include "log.h"
#define KEYSTREAM_ONLY
#include "chacha_private.h"
#define minimum(a, b) ((a) < (b) ? (a) : (b))
#if defined(__GNUC__) || defined(_MSC_VER)
#define inline __inline
#else /* __GNUC__ || _MSC_VER */
#define inline
#endif /* !__GNUC__ && !_MSC_VER */
#define KEYSZ 32
#define IVSZ 8
#define BLOCKSZ 64
#define RSBUFSZ (16*BLOCKSZ)
#define REKEY_BASE (1024*1024) /* NB. should be a power of 2 */
/* Marked MAP_INHERIT_ZERO, so zero'd out in fork children. */
static struct _rs {
size_t rs_have; /* valid bytes at end of rs_buf */
size_t rs_count; /* bytes till reseed */
} *rs;
/* Maybe be preserved in fork children, if _rs_allocate() decides. */
static struct _rsx {
chacha_ctx rs_chacha; /* chacha context for random keystream */
u_char rs_buf[RSBUFSZ]; /* keystream blocks */
} *rsx;
static inline int _rs_allocate(struct _rs **, struct _rsx **);
static inline void _rs_forkdetect(void);
#include "arc4random.h"
static inline void _rs_rekey(u_char *dat, size_t datlen);
static inline void
_rs_init(u_char *buf, size_t n)
{
if (n < KEYSZ + IVSZ)
return;
if (rs == NULL) {
if (_rs_allocate(&rs, &rsx) == -1)
_exit(1);
}
chacha_keysetup(&rsx->rs_chacha, buf, KEYSZ * 8);
chacha_ivsetup(&rsx->rs_chacha, buf + KEYSZ);
}
static void
_rs_stir(void)
{
u_char rnd[KEYSZ + IVSZ];
uint32_t rekey_fuzz = 0;
if (getentropy(rnd, sizeof rnd) == -1)
_getentropy_fail();
if (!rs)
_rs_init(rnd, sizeof(rnd));
else
_rs_rekey(rnd, sizeof(rnd));
explicit_bzero(rnd, sizeof(rnd)); /* discard source seed */
/* invalidate rs_buf */
rs->rs_have = 0;
memset(rsx->rs_buf, 0, sizeof(rsx->rs_buf));
/* rekey interval should not be predictable */
chacha_encrypt_bytes(&rsx->rs_chacha, (uint8_t *)&rekey_fuzz,
(uint8_t *)&rekey_fuzz, sizeof(rekey_fuzz));
rs->rs_count = REKEY_BASE + (rekey_fuzz % REKEY_BASE);
}
static inline void
_rs_stir_if_needed(size_t len)
{
_rs_forkdetect();
if (!rs || rs->rs_count <= len)
_rs_stir();
if (rs->rs_count <= len)
rs->rs_count = 0;
else
rs->rs_count -= len;
}
static inline void
_rs_rekey(u_char *dat, size_t datlen)
{
#ifndef KEYSTREAM_ONLY
memset(rsx->rs_buf, 0, sizeof(rsx->rs_buf));
#endif
/* fill rs_buf with the keystream */
chacha_encrypt_bytes(&rsx->rs_chacha, rsx->rs_buf,
rsx->rs_buf, sizeof(rsx->rs_buf));
/* mix in optional user provided data */
if (dat) {
size_t i, m;
m = minimum(datlen, KEYSZ + IVSZ);
for (i = 0; i < m; i++)
rsx->rs_buf[i] ^= dat[i];
}
/* immediately reinit for backtracking resistance */
_rs_init(rsx->rs_buf, KEYSZ + IVSZ);
memset(rsx->rs_buf, 0, KEYSZ + IVSZ);
rs->rs_have = sizeof(rsx->rs_buf) - KEYSZ - IVSZ;
}
static inline void
_rs_random_buf(void *_buf, size_t n)
{
u_char *buf = (u_char *)_buf;
u_char *keystream;
size_t m;
_rs_stir_if_needed(n);
while (n > 0) {
if (rs->rs_have > 0) {
m = minimum(n, rs->rs_have);
keystream = rsx->rs_buf + sizeof(rsx->rs_buf)
- rs->rs_have;
memcpy(buf, keystream, m);
memset(keystream, 0, m);
buf += m;
n -= m;
rs->rs_have -= m;
}
if (rs->rs_have == 0)
_rs_rekey(NULL, 0);
}
}
static inline void
_rs_random_u32(uint32_t *val)
{
u_char *keystream;
_rs_stir_if_needed(sizeof(*val));
if (rs->rs_have < sizeof(*val))
_rs_rekey(NULL, 0);
keystream = rsx->rs_buf + sizeof(rsx->rs_buf) - rs->rs_have;
memcpy(val, keystream, sizeof(*val));
memset(keystream, 0, sizeof(*val));
rs->rs_have -= sizeof(*val);
}
uint32_t
arc4random(void)
{
uint32_t val;
_ARC4_LOCK();
_rs_random_u32(&val);
_ARC4_UNLOCK();
return val;
}
DEF_WEAK(arc4random);
/*
* If we are providing arc4random, then we can provide a more efficient
* arc4random_buf().
*/
# ifndef HAVE_ARC4RANDOM_BUF
void
arc4random_buf(void *buf, size_t n)
{
_ARC4_LOCK();
_rs_random_buf(buf, n);
_ARC4_UNLOCK();
}
DEF_WEAK(arc4random_buf);
# endif /* !HAVE_ARC4RANDOM_BUF */
#endif /* !HAVE_ARC4RANDOM */
/* arc4random_buf() that uses platform arc4random() */
#if !defined(HAVE_ARC4RANDOM_BUF) && defined(HAVE_ARC4RANDOM)
void
arc4random_buf(void *_buf, size_t n)
{
size_t i;
u_int32_t r = 0;
char *buf = (char *)_buf;
for (i = 0; i < n; i++) {
if (i % 4 == 0)
r = arc4random();
buf[i] = r & 0xff;
r >>= 8;
}
explicit_bzero(&r, sizeof(r));
}
#endif /* !defined(HAVE_ARC4RANDOM_BUF) && defined(HAVE_ARC4RANDOM) */
diff --git a/crypto/openssh/openbsd-compat/arc4random.h b/crypto/openssh/openbsd-compat/arc4random.h
index 2b57611f060c..5af3a4492a82 100644
--- a/crypto/openssh/openbsd-compat/arc4random.h
+++ b/crypto/openssh/openbsd-compat/arc4random.h
@@ -1,79 +1,89 @@
/* $OpenBSD: arc4random_linux.h,v 1.12 2019/07/11 10:37:28 inoguchi Exp $ */
/*
* Copyright (c) 1996, David Mazieres <dm@uun.org>
* Copyright (c) 2008, Damien Miller <djm@openbsd.org>
* Copyright (c) 2013, Markus Friedl <markus@openbsd.org>
* Copyright (c) 2014, Theo de Raadt <deraadt@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.
*/
/*
* Stub functions for portability. From LibreSSL with some adaptations.
*/
#include <sys/mman.h>
#include <signal.h>
/* OpenSSH isn't multithreaded */
#define _ARC4_LOCK()
#define _ARC4_UNLOCK()
#define _ARC4_ATFORK(f)
static inline void
_getentropy_fail(void)
{
fatal("getentropy failed");
}
static volatile sig_atomic_t _rs_forked;
static inline void
_rs_forkhandler(void)
{
_rs_forked = 1;
}
static inline void
_rs_forkdetect(void)
{
static pid_t _rs_pid = 0;
pid_t pid = getpid();
if (_rs_pid == 0 || _rs_pid == 1 || _rs_pid != pid || _rs_forked) {
_rs_pid = pid;
_rs_forked = 0;
if (rs)
memset(rs, 0, sizeof(*rs));
}
}
static inline int
_rs_allocate(struct _rs **rsp, struct _rsx **rsxp)
{
+#if defined(MAP_ANON) && defined(MAP_PRIVATE)
if ((*rsp = mmap(NULL, sizeof(**rsp), PROT_READ|PROT_WRITE,
MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED)
return (-1);
if ((*rsxp = mmap(NULL, sizeof(**rsxp), PROT_READ|PROT_WRITE,
MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED) {
munmap(*rsp, sizeof(**rsp));
*rsp = NULL;
return (-1);
}
+#else
+ if ((*rsp = calloc(1, sizeof(**rsp))) == NULL)
+ return (-1);
+ if ((*rsxp = calloc(1, sizeof(**rsxp))) == NULL) {
+ free(*rsp);
+ *rsp = NULL;
+ return (-1);
+ }
+#endif
_ARC4_ATFORK(_rs_forkhandler);
return (0);
}
diff --git a/crypto/openssh/openbsd-compat/bsd-getentropy.c b/crypto/openssh/openbsd-compat/bsd-getentropy.c
index bd4b6695acc6..554dfad70524 100644
--- a/crypto/openssh/openbsd-compat/bsd-getentropy.c
+++ b/crypto/openssh/openbsd-compat/bsd-getentropy.c
@@ -1,82 +1,83 @@
/*
* Copyright (c) 1996, David Mazieres <dm@uun.org>
* Copyright (c) 2008, Damien Miller <djm@openbsd.org>
* Copyright (c) 2013, Markus Friedl <markus@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"
-#ifndef HAVE_GETENTROPY
-
#ifndef SSH_RANDOM_DEV
# define SSH_RANDOM_DEV "/dev/urandom"
#endif /* SSH_RANDOM_DEV */
#include <sys/types.h>
#ifdef HAVE_SYS_RANDOM_H
# include <sys/random.h>
#endif
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#ifdef WITH_OPENSSL
#include <openssl/rand.h>
#include <openssl/err.h>
#endif
#include "log.h"
int
_ssh_compat_getentropy(void *s, size_t len)
{
#ifdef WITH_OPENSSL
if (RAND_bytes(s, len) <= 0)
fatal("Couldn't obtain random bytes (error 0x%lx)",
(unsigned long)ERR_get_error());
#else
int fd, save_errno;
ssize_t r;
size_t o = 0;
+#ifdef HAVE_GETENTROPY
+ if (r = getentropy(s, len) == 0)
+ return 0;
+#endif /* HAVE_GETENTROPY */
#ifdef HAVE_GETRANDOM
if ((r = getrandom(s, len, 0)) > 0 && (size_t)r == len)
return 0;
#endif /* HAVE_GETRANDOM */
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 0;
fatal("Couldn't open %s: %s", SSH_RANDOM_DEV,
strerror(save_errno));
}
while (o < len) {
r = read(fd, (u_char *)s + o, len - o);
if (r < 0) {
if (errno == EAGAIN || errno == EINTR ||
errno == EWOULDBLOCK)
continue;
fatal("read %s: %s", SSH_RANDOM_DEV, strerror(errno));
}
o += r;
}
close(fd);
#endif /* WITH_OPENSSL */
return 0;
}
-#endif /* WITH_GETENTROPY */
diff --git a/crypto/openssh/openbsd-compat/bsd-poll.c b/crypto/openssh/openbsd-compat/bsd-poll.c
index 9a9794f5863b..967f947b21fd 100644
--- a/crypto/openssh/openbsd-compat/bsd-poll.c
+++ b/crypto/openssh/openbsd-compat/bsd-poll.c
@@ -1,129 +1,115 @@
/*
* Copyright (c) 2004, 2005, 2007 Darren Tucker (dtucker at zip com au).
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "includes.h"
#if !defined(HAVE_PPOLL) || !defined(HAVE_POLL) || defined(BROKEN_POLL)
#include <sys/types.h>
#include <sys/time.h>
#ifdef HAVE_SYS_PARAM_H
# include <sys/param.h>
#endif
#ifdef HAVE_SYS_SELECT_H
# include <sys/select.h>
#endif
#include <errno.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include "bsd-poll.h"
#if !defined(HAVE_PPOLL) || defined(BROKEN_POLL)
/*
* A minimal implementation of ppoll(2), built on top of pselect(2).
*
* Only supports POLLIN, POLLOUT and POLLPRI flags in pfd.events and
* revents. Notably POLLERR, POLLHUP and POLLNVAL are not supported.
*
* Supports pfd.fd = -1 meaning "unused" although it's not standard.
*/
int
ppoll(struct pollfd *fds, nfds_t nfds, const struct timespec *tmoutp,
const sigset_t *sigmask)
{
nfds_t i;
- int saved_errno, ret, fd, maxfd = 0;
- fd_set *readfds = NULL, *writefds = NULL, *exceptfds = NULL;
- size_t nmemb;
+ int ret, fd, maxfd = 0;
+ fd_set readfds, writefds, exceptfds;
for (i = 0; i < nfds; i++) {
fd = fds[i].fd;
if (fd != -1 && fd >= FD_SETSIZE) {
errno = EINVAL;
return -1;
}
maxfd = MAX(maxfd, fd);
}
- nmemb = howmany(maxfd + 1 , NFDBITS);
- if ((readfds = calloc(nmemb, sizeof(fd_mask))) == NULL ||
- (writefds = calloc(nmemb, sizeof(fd_mask))) == NULL ||
- (exceptfds = calloc(nmemb, sizeof(fd_mask))) == NULL) {
- saved_errno = ENOMEM;
- ret = -1;
- goto out;
- }
-
/* populate event bit vectors for the events we're interested in */
+ FD_ZERO(&readfds);
+ FD_ZERO(&writefds);
+ FD_ZERO(&exceptfds);
for (i = 0; i < nfds; i++) {
fd = fds[i].fd;
if (fd == -1)
continue;
if (fds[i].events & POLLIN)
- FD_SET(fd, readfds);
+ FD_SET(fd, &readfds);
if (fds[i].events & POLLOUT)
- FD_SET(fd, writefds);
+ FD_SET(fd, &writefds);
if (fds[i].events & POLLPRI)
- FD_SET(fd, exceptfds);
+ FD_SET(fd, &exceptfds);
}
- ret = pselect(maxfd + 1, readfds, writefds, exceptfds, tmoutp, sigmask);
- saved_errno = errno;
+ ret = pselect(maxfd + 1, &readfds, &writefds, &exceptfds, tmoutp, sigmask);
/* scan through select results and set poll() flags */
for (i = 0; i < nfds; i++) {
fd = fds[i].fd;
fds[i].revents = 0;
if (fd == -1)
continue;
- if ((fds[i].events & POLLIN) && FD_ISSET(fd, readfds))
+ if ((fds[i].events & POLLIN) && FD_ISSET(fd, &readfds))
fds[i].revents |= POLLIN;
- if ((fds[i].events & POLLOUT) && FD_ISSET(fd, writefds))
+ if ((fds[i].events & POLLOUT) && FD_ISSET(fd, &writefds))
fds[i].revents |= POLLOUT;
- if ((fds[i].events & POLLPRI) && FD_ISSET(fd, exceptfds))
+ if ((fds[i].events & POLLPRI) && FD_ISSET(fd, &exceptfds))
fds[i].revents |= POLLPRI;
}
-out:
- free(readfds);
- free(writefds);
- free(exceptfds);
- if (ret == -1)
- errno = saved_errno;
return ret;
}
#endif /* !HAVE_PPOLL || BROKEN_POLL */
#if !defined(HAVE_POLL) || defined(BROKEN_POLL)
int
poll(struct pollfd *fds, nfds_t nfds, int timeout)
{
struct timespec ts, *tsp = NULL;
/* poll timeout is msec, ppoll is timespec (sec + nsec) */
if (timeout >= 0) {
ts.tv_sec = timeout / 1000;
ts.tv_nsec = (timeout % 1000) * 1000000;
tsp = &ts;
}
return ppoll(fds, nfds, tsp, NULL);
}
#endif /* !HAVE_POLL || BROKEN_POLL */
#endif /* !HAVE_PPOLL || !HAVE_POLL || BROKEN_POLL */
diff --git a/crypto/openssh/openbsd-compat/bsd-poll.h b/crypto/openssh/openbsd-compat/bsd-poll.h
index 586647ee1aff..ae865a6e2622 100644
--- a/crypto/openssh/openbsd-compat/bsd-poll.h
+++ b/crypto/openssh/openbsd-compat/bsd-poll.h
@@ -1,77 +1,90 @@
/* $OpenBSD: poll.h,v 1.11 2003/12/10 23:10:08 millert Exp $ */
/*
* Copyright (c) 1996 Theo de Raadt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* OPENBSD ORIGINAL: sys/sys/poll.h */
#ifndef _COMPAT_POLL_H_
#define _COMPAT_POLL_H_
#include <sys/types.h>
#ifdef HAVE_POLL_H
# include <poll.h>
#elif HAVE_SYS_POLL_H
# include <sys/poll.h>
#endif
#ifndef HAVE_STRUCT_POLLFD_FD
typedef struct pollfd {
int fd;
short events;
short revents;
} pollfd_t;
-#define POLLIN 0x0001
-#define POLLPRI 0x0002
-#define POLLOUT 0x0004
-#define POLLERR 0x0008
-#define POLLHUP 0x0010
-#define POLLNVAL 0x0020
+#ifndef POLLIN
+# define POLLIN 0x0001
+#endif
+#ifndef POLLPRI
+# define POLLPRI 0x0002
+#endif
+#ifndef POLLOUT
+# define POLLOUT 0x0004
+#endif
+#ifndef POLLERR
+# define POLLERR 0x0008
+#endif
+#ifndef POLLHUP
+# define POLLHUP 0x0010
+#endif
+#ifndef POLLNVAL
+# define POLLNVAL 0x0020
+#endif
+
#if 0
/* the following are currently not implemented */
#define POLLRDNORM 0x0040
#define POLLNORM POLLRDNORM
#define POLLWRNORM POLLOUT
#define POLLRDBAND 0x0080
#define POLLWRBAND 0x0100
#endif
#define INFTIM (-1) /* not standard */
#endif /* !HAVE_STRUCT_POLLFD_FD */
#ifndef HAVE_NFDS_T
typedef unsigned int nfds_t;
#endif
#ifndef HAVE_POLL
int poll(struct pollfd *, nfds_t, int);
#endif
#ifndef HAVE_PPOLL
int ppoll(struct pollfd *, nfds_t, const struct timespec *, const sigset_t *);
#endif
#endif /* !_COMPAT_POLL_H_ */
diff --git a/crypto/openssh/openbsd-compat/bsd-timegm.c b/crypto/openssh/openbsd-compat/bsd-timegm.c
index 14f6bbf14dad..246724bd6236 100644
--- a/crypto/openssh/openbsd-compat/bsd-timegm.c
+++ b/crypto/openssh/openbsd-compat/bsd-timegm.c
@@ -1,82 +1,82 @@
/*
* Copyright (c) 1997 Kungliga Tekniska Högskolan
- * (Royal Institute of Technology, Stockholm, Sweden).
- * All rights reserved.
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
+ * 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.
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
*
- * 3. Neither the name of the Institute nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
*
- * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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.
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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.
*/
/*
adapted for Samba4 by Andrew Tridgell
*/
#include "includes.h"
#include <time.h>
#ifndef HAVE_TIMEGM
static int is_leap(unsigned y)
{
y += 1900;
return (y % 4) == 0 && ((y % 100) != 0 || (y % 400) == 0);
}
time_t timegm(struct tm *tm)
{
static const unsigned ndays[2][12] ={
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};
time_t res = 0;
unsigned i;
if (tm->tm_mon > 12 ||
tm->tm_mon < 0 ||
tm->tm_mday > 31 ||
tm->tm_min > 60 ||
tm->tm_sec > 60 ||
tm->tm_hour > 24) {
/* invalid tm structure */
return 0;
}
-
+
for (i = 70; i < tm->tm_year; ++i)
res += is_leap(i) ? 366 : 365;
-
+
for (i = 0; i < tm->tm_mon; ++i)
res += ndays[is_leap(tm->tm_year)][i];
res += tm->tm_mday - 1;
res *= 24;
res += tm->tm_hour;
res *= 60;
res += tm->tm_min;
res *= 60;
res += tm->tm_sec;
return res;
}
#endif /* HAVE_TIMEGM */
diff --git a/crypto/openssh/openbsd-compat/getrrsetbyname.c b/crypto/openssh/openbsd-compat/getrrsetbyname.c
index cc1f8ae519eb..73de5e9482b8 100644
--- a/crypto/openssh/openbsd-compat/getrrsetbyname.c
+++ b/crypto/openssh/openbsd-compat/getrrsetbyname.c
@@ -1,609 +1,615 @@
/* $OpenBSD: getrrsetbyname.c,v 1.11 2007/10/11 18:36:41 jakob Exp $ */
/*
* Copyright (c) 2001 Jakob Schlyter. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Portions Copyright (c) 1999-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
* DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
* INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
* FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* OPENBSD ORIGINAL: lib/libc/net/getrrsetbyname.c */
#include "includes.h"
#if !defined (HAVE_GETRRSETBYNAME) && !defined (HAVE_LDNS)
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "getrrsetbyname.h"
#if defined(HAVE_DECL_H_ERRNO) && !HAVE_DECL_H_ERRNO
extern int h_errno;
#endif
/* We don't need multithread support here */
#ifdef _THREAD_PRIVATE
# undef _THREAD_PRIVATE
#endif
#define _THREAD_PRIVATE(a,b,c) (c)
#ifndef HAVE__RES_EXTERN
struct __res_state _res;
#endif
/* Necessary functions and macros */
/*
* Inline versions of get/put short/long. Pointer is advanced.
*
* These macros demonstrate the property of C whereby it can be
* portable or it can be elegant but rarely both.
*/
#ifndef INT32SZ
# define INT32SZ 4
#endif
#ifndef INT16SZ
# define INT16SZ 2
#endif
#ifndef GETSHORT
#define GETSHORT(s, cp) { \
u_char *t_cp = (u_char *)(cp); \
(s) = ((u_int16_t)t_cp[0] << 8) \
| ((u_int16_t)t_cp[1]) \
; \
(cp) += INT16SZ; \
}
#endif
#ifndef GETLONG
#define GETLONG(l, cp) { \
u_char *t_cp = (u_char *)(cp); \
(l) = ((u_int32_t)t_cp[0] << 24) \
| ((u_int32_t)t_cp[1] << 16) \
| ((u_int32_t)t_cp[2] << 8) \
| ((u_int32_t)t_cp[3]) \
; \
(cp) += INT32SZ; \
}
#endif
/*
* If the system doesn't have _getshort/_getlong or that are not exactly what
* we need then use local replacements, avoiding name collisions.
*/
#if !defined(HAVE__GETSHORT) || !defined(HAVE__GETLONG) || \
!defined(HAVE_DECL__GETSHORT) || HAVE_DECL__GETSHORT == 0 || \
!defined(HAVE_DECL__GETLONG) || HAVE_DECL__GETLONG == 0
-#define _getshort(x) (_ssh_compat_getshort(x))
-#define _getlong(x) (_ssh_compat_getlong(x))
+# ifdef _getshort
+# undef _getshort
+# endif
+# ifdef _getlong
+# undef _getlong
+# endif
+# define _getshort(x) (_ssh_compat_getshort(x))
+# define _getlong(x) (_ssh_compat_getlong(x))
/*
* Routines to insert/extract short/long's.
*/
static u_int16_t
_getshort(const u_char *msgp)
{
u_int16_t u;
GETSHORT(u, msgp);
return (u);
}
static u_int32_t
_getlong(const u_char *msgp)
{
u_int32_t u;
GETLONG(u, msgp);
return (u);
}
-#endif
+#endif /* missing _getshort/_getlong */
/* ************** */
#define ANSWER_BUFFER_SIZE 0xffff
struct dns_query {
char *name;
u_int16_t type;
u_int16_t class;
struct dns_query *next;
};
struct dns_rr {
char *name;
u_int16_t type;
u_int16_t class;
u_int16_t ttl;
u_int16_t size;
void *rdata;
struct dns_rr *next;
};
struct dns_response {
HEADER header;
struct dns_query *query;
struct dns_rr *answer;
struct dns_rr *authority;
struct dns_rr *additional;
};
static struct dns_response *parse_dns_response(const u_char *, int);
static struct dns_query *parse_dns_qsection(const u_char *, int,
const u_char **, int);
static struct dns_rr *parse_dns_rrsection(const u_char *, int, const u_char **,
int);
static void free_dns_query(struct dns_query *);
static void free_dns_rr(struct dns_rr *);
static void free_dns_response(struct dns_response *);
static int count_dns_rr(struct dns_rr *, u_int16_t, u_int16_t);
int
getrrsetbyname(const char *hostname, unsigned int rdclass,
unsigned int rdtype, unsigned int flags,
struct rrsetinfo **res)
{
struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
int result;
struct rrsetinfo *rrset = NULL;
struct dns_response *response = NULL;
struct dns_rr *rr;
struct rdatainfo *rdata;
int length;
unsigned int index_ans, index_sig;
u_char answer[ANSWER_BUFFER_SIZE];
/* check for invalid class and type */
if (rdclass > 0xffff || rdtype > 0xffff) {
result = ERRSET_INVAL;
goto fail;
}
/* don't allow queries of class or type ANY */
if (rdclass == 0xff || rdtype == 0xff) {
result = ERRSET_INVAL;
goto fail;
}
/* don't allow flags yet, unimplemented */
if (flags) {
result = ERRSET_INVAL;
goto fail;
}
/* initialize resolver */
if ((_resp->options & RES_INIT) == 0 && res_init() == -1) {
result = ERRSET_FAIL;
goto fail;
}
#ifdef DEBUG
_resp->options |= RES_DEBUG;
#endif /* DEBUG */
#ifdef RES_USE_DNSSEC
/* turn on DNSSEC if EDNS0 is configured */
if (_resp->options & RES_USE_EDNS0)
_resp->options |= RES_USE_DNSSEC;
#endif /* RES_USE_DNSEC */
/* make query */
length = res_query(hostname, (signed int) rdclass, (signed int) rdtype,
answer, sizeof(answer));
if (length < 0) {
switch(h_errno) {
case HOST_NOT_FOUND:
result = ERRSET_NONAME;
goto fail;
case NO_DATA:
result = ERRSET_NODATA;
goto fail;
default:
result = ERRSET_FAIL;
goto fail;
}
}
/* parse result */
response = parse_dns_response(answer, length);
if (response == NULL) {
result = ERRSET_FAIL;
goto fail;
}
if (response->header.qdcount != 1) {
result = ERRSET_FAIL;
goto fail;
}
/* initialize rrset */
rrset = calloc(1, sizeof(struct rrsetinfo));
if (rrset == NULL) {
result = ERRSET_NOMEMORY;
goto fail;
}
rrset->rri_rdclass = response->query->class;
rrset->rri_rdtype = response->query->type;
rrset->rri_ttl = response->answer->ttl;
rrset->rri_nrdatas = response->header.ancount;
#ifdef HAVE_HEADER_AD
/* check for authenticated data */
if (response->header.ad == 1)
rrset->rri_flags |= RRSET_VALIDATED;
#endif
/* copy name from answer section */
rrset->rri_name = strdup(response->answer->name);
if (rrset->rri_name == NULL) {
result = ERRSET_NOMEMORY;
goto fail;
}
/* count answers */
rrset->rri_nrdatas = count_dns_rr(response->answer, rrset->rri_rdclass,
rrset->rri_rdtype);
rrset->rri_nsigs = count_dns_rr(response->answer, rrset->rri_rdclass,
T_RRSIG);
/* allocate memory for answers */
rrset->rri_rdatas = calloc(rrset->rri_nrdatas,
sizeof(struct rdatainfo));
if (rrset->rri_rdatas == NULL) {
result = ERRSET_NOMEMORY;
goto fail;
}
/* allocate memory for signatures */
if (rrset->rri_nsigs > 0) {
rrset->rri_sigs = calloc(rrset->rri_nsigs, sizeof(struct rdatainfo));
if (rrset->rri_sigs == NULL) {
result = ERRSET_NOMEMORY;
goto fail;
}
}
/* copy answers & signatures */
for (rr = response->answer, index_ans = 0, index_sig = 0;
rr; rr = rr->next) {
rdata = NULL;
if (rr->class == rrset->rri_rdclass &&
rr->type == rrset->rri_rdtype)
rdata = &rrset->rri_rdatas[index_ans++];
if (rr->class == rrset->rri_rdclass &&
rr->type == T_RRSIG)
rdata = &rrset->rri_sigs[index_sig++];
if (rdata) {
rdata->rdi_length = rr->size;
rdata->rdi_data = malloc(rr->size);
if (rdata->rdi_data == NULL) {
result = ERRSET_NOMEMORY;
goto fail;
}
memcpy(rdata->rdi_data, rr->rdata, rr->size);
}
}
free_dns_response(response);
*res = rrset;
return (ERRSET_SUCCESS);
fail:
if (rrset != NULL)
freerrset(rrset);
if (response != NULL)
free_dns_response(response);
return (result);
}
void
freerrset(struct rrsetinfo *rrset)
{
u_int16_t i;
if (rrset == NULL)
return;
if (rrset->rri_rdatas) {
for (i = 0; i < rrset->rri_nrdatas; i++) {
if (rrset->rri_rdatas[i].rdi_data == NULL)
break;
free(rrset->rri_rdatas[i].rdi_data);
}
free(rrset->rri_rdatas);
}
if (rrset->rri_sigs) {
for (i = 0; i < rrset->rri_nsigs; i++) {
if (rrset->rri_sigs[i].rdi_data == NULL)
break;
free(rrset->rri_sigs[i].rdi_data);
}
free(rrset->rri_sigs);
}
if (rrset->rri_name)
free(rrset->rri_name);
free(rrset);
}
/*
* DNS response parsing routines
*/
static struct dns_response *
parse_dns_response(const u_char *answer, int size)
{
struct dns_response *resp;
const u_char *cp;
/* allocate memory for the response */
resp = calloc(1, sizeof(*resp));
if (resp == NULL)
return (NULL);
/* initialize current pointer */
cp = answer;
/* copy header */
memcpy(&resp->header, cp, HFIXEDSZ);
cp += HFIXEDSZ;
/* fix header byte order */
resp->header.qdcount = ntohs(resp->header.qdcount);
resp->header.ancount = ntohs(resp->header.ancount);
resp->header.nscount = ntohs(resp->header.nscount);
resp->header.arcount = ntohs(resp->header.arcount);
/* there must be at least one query */
if (resp->header.qdcount < 1) {
free_dns_response(resp);
return (NULL);
}
/* parse query section */
resp->query = parse_dns_qsection(answer, size, &cp,
resp->header.qdcount);
if (resp->header.qdcount && resp->query == NULL) {
free_dns_response(resp);
return (NULL);
}
/* parse answer section */
resp->answer = parse_dns_rrsection(answer, size, &cp,
resp->header.ancount);
if (resp->header.ancount && resp->answer == NULL) {
free_dns_response(resp);
return (NULL);
}
/* parse authority section */
resp->authority = parse_dns_rrsection(answer, size, &cp,
resp->header.nscount);
if (resp->header.nscount && resp->authority == NULL) {
free_dns_response(resp);
return (NULL);
}
/* parse additional section */
resp->additional = parse_dns_rrsection(answer, size, &cp,
resp->header.arcount);
if (resp->header.arcount && resp->additional == NULL) {
free_dns_response(resp);
return (NULL);
}
return (resp);
}
static struct dns_query *
parse_dns_qsection(const u_char *answer, int size, const u_char **cp, int count)
{
struct dns_query *head, *curr, *prev;
int i, length;
char name[MAXDNAME];
for (i = 1, head = NULL, prev = NULL; i <= count; i++, prev = curr) {
/* allocate and initialize struct */
curr = calloc(1, sizeof(struct dns_query));
if (curr == NULL) {
free_dns_query(head);
return (NULL);
}
if (head == NULL)
head = curr;
if (prev != NULL)
prev->next = curr;
/* name */
length = dn_expand(answer, answer + size, *cp, name,
sizeof(name));
if (length < 0) {
free_dns_query(head);
return (NULL);
}
curr->name = strdup(name);
if (curr->name == NULL) {
free_dns_query(head);
return (NULL);
}
*cp += length;
/* type */
curr->type = _getshort(*cp);
*cp += INT16SZ;
/* class */
curr->class = _getshort(*cp);
*cp += INT16SZ;
}
return (head);
}
static struct dns_rr *
parse_dns_rrsection(const u_char *answer, int size, const u_char **cp,
int count)
{
struct dns_rr *head, *curr, *prev;
int i, length;
char name[MAXDNAME];
for (i = 1, head = NULL, prev = NULL; i <= count; i++, prev = curr) {
/* allocate and initialize struct */
curr = calloc(1, sizeof(struct dns_rr));
if (curr == NULL) {
free_dns_rr(head);
return (NULL);
}
if (head == NULL)
head = curr;
if (prev != NULL)
prev->next = curr;
/* name */
length = dn_expand(answer, answer + size, *cp, name,
sizeof(name));
if (length < 0) {
free_dns_rr(head);
return (NULL);
}
curr->name = strdup(name);
if (curr->name == NULL) {
free_dns_rr(head);
return (NULL);
}
*cp += length;
/* type */
curr->type = _getshort(*cp);
*cp += INT16SZ;
/* class */
curr->class = _getshort(*cp);
*cp += INT16SZ;
/* ttl */
curr->ttl = _getlong(*cp);
*cp += INT32SZ;
/* rdata size */
curr->size = _getshort(*cp);
*cp += INT16SZ;
/* rdata itself */
curr->rdata = malloc(curr->size);
if (curr->rdata == NULL) {
free_dns_rr(head);
return (NULL);
}
memcpy(curr->rdata, *cp, curr->size);
*cp += curr->size;
}
return (head);
}
static void
free_dns_query(struct dns_query *p)
{
if (p == NULL)
return;
if (p->name)
free(p->name);
free_dns_query(p->next);
free(p);
}
static void
free_dns_rr(struct dns_rr *p)
{
if (p == NULL)
return;
if (p->name)
free(p->name);
if (p->rdata)
free(p->rdata);
free_dns_rr(p->next);
free(p);
}
static void
free_dns_response(struct dns_response *p)
{
if (p == NULL)
return;
free_dns_query(p->query);
free_dns_rr(p->answer);
free_dns_rr(p->authority);
free_dns_rr(p->additional);
free(p);
}
static int
count_dns_rr(struct dns_rr *p, u_int16_t class, u_int16_t type)
{
int n = 0;
while(p) {
if (p->class == class && p->type == type)
n++;
p = p->next;
}
return (n);
}
#endif /* !defined (HAVE_GETRRSETBYNAME) && !defined (HAVE_LDNS) */
diff --git a/crypto/openssh/openbsd-compat/openbsd-compat.h b/crypto/openssh/openbsd-compat/openbsd-compat.h
index 4af207cdd40f..895ecf9ea111 100644
--- a/crypto/openssh/openbsd-compat/openbsd-compat.h
+++ b/crypto/openssh/openbsd-compat/openbsd-compat.h
@@ -1,381 +1,378 @@
/*
* Copyright (c) 1999-2003 Damien Miller. All rights reserved.
* Copyright (c) 2003 Ben Lindstrom. All rights reserved.
* Copyright (c) 2002 Tim Rice. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _OPENBSD_COMPAT_H
#define _OPENBSD_COMPAT_H
#include "includes.h"
#include <sys/types.h>
#include <pwd.h>
#include <sys/socket.h>
#include <stddef.h> /* for wchar_t */
/* OpenBSD function replacements */
#include "base64.h"
#include "sigact.h"
#include "readpassphrase.h"
#include "vis.h"
#include "getrrsetbyname.h"
#include "sha1.h"
#include "sha2.h"
#include "md5.h"
#include "blf.h"
#include "fnmatch.h"
#if defined(HAVE_LOGIN_CAP) && !defined(HAVE_LOGIN_GETPWCLASS)
# include <login_cap.h>
# define login_getpwclass(pw) login_getclass(pw->pw_class)
#endif
#ifndef HAVE_BASENAME
char *basename(const char *path);
#endif
#ifndef HAVE_BINDRESVPORT_SA
int bindresvport_sa(int sd, struct sockaddr *sa);
#endif
#ifndef HAVE_CLOSEFROM
void closefrom(int);
#endif
#if defined(HAVE_DECL_FTRUNCATE) && HAVE_DECL_FTRUNCATE == 0
int ftruncate(int filedes, off_t length);
#endif
-#if defined(HAVE_DECL_GETENTROPY) && HAVE_DECL_GETENTROPY == 0
-int _ssh_compat_getentropy(void *, size_t);
-#endif
-
#ifndef HAVE_GETLINE
#include <stdio.h>
ssize_t getline(char **, size_t *, FILE *);
#endif
#ifndef HAVE_GETPAGESIZE
int getpagesize(void);
#endif
#ifndef HAVE_GETCWD
char *getcwd(char *pt, size_t size);
#endif
#ifndef HAVE_KILLPG
int killpg(pid_t, int);
#endif
#if defined(HAVE_DECL_MEMMEM) && HAVE_DECL_MEMMEM == 0
void *memmem(const void *, size_t, const void *, size_t);
#endif
#ifndef HAVE_REALLOCARRAY
void *reallocarray(void *, size_t, size_t);
#endif
#ifndef HAVE_RECALLOCARRAY
void *recallocarray(void *, size_t, size_t, size_t);
#endif
#ifndef HAVE_RRESVPORT_AF
int rresvport_af(int *alport, sa_family_t af);
#endif
#ifndef HAVE_STRLCPY
size_t strlcpy(char *dst, const char *src, size_t siz);
#endif
#ifndef HAVE_STRLCAT
size_t strlcat(char *dst, const char *src, size_t siz);
#endif
#ifndef HAVE_STRCASESTR
char *strcasestr(const char *, const char *);
#endif
#ifndef HAVE_STRNLEN
size_t strnlen(const char *, size_t);
#endif
#ifndef HAVE_STRNDUP
char *strndup(const char *s, size_t n);
#endif
#ifndef HAVE_SETENV
int setenv(register const char *name, register const char *value, int rewrite);
#endif
#ifndef HAVE_STRMODE
void strmode(int mode, char *p);
#endif
#ifndef HAVE_STRPTIME
#include <time.h>
char *strptime(const char *buf, const char *fmt, struct tm *tm);
#endif
#if !defined(HAVE_MKDTEMP)
int mkstemps(char *path, int slen);
int mkstemp(char *path);
char *mkdtemp(char *path);
#endif
#ifndef HAVE_DAEMON
int daemon(int nochdir, int noclose);
#endif
#ifndef HAVE_DIRNAME
char *dirname(const char *path);
#endif
#ifndef HAVE_FMT_SCALED
#define FMT_SCALED_STRSIZE 7
int fmt_scaled(long long number, char *result);
#endif
#ifndef HAVE_SCAN_SCALED
int scan_scaled(char *, long long *);
#endif
#if defined(BROKEN_INET_NTOA) || !defined(HAVE_INET_NTOA)
char *inet_ntoa(struct in_addr in);
#endif
#ifndef HAVE_INET_NTOP
const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
#endif
#ifndef HAVE_INET_ATON
int inet_aton(const char *cp, struct in_addr *addr);
#endif
#ifndef HAVE_STRSEP
char *strsep(char **stringp, const char *delim);
#endif
#ifndef HAVE_SETPROCTITLE
void setproctitle(const char *fmt, ...);
void compat_init_setproctitle(int argc, char *argv[]);
#endif
#ifndef HAVE_GETGROUPLIST
int getgrouplist(const char *, gid_t, gid_t *, int *);
#endif
#if !defined(HAVE_GETOPT) || !defined(HAVE_GETOPT_OPTRESET)
int BSDgetopt(int argc, char * const *argv, const char *opts);
#include "openbsd-compat/getopt.h"
#endif
#if ((defined(HAVE_DECL_READV) && HAVE_DECL_READV == 0) || \
(defined(HAVE_DECL_WRITEV) && HAVE_DECL_WRITEV == 0))
# include <sys/types.h>
# include <sys/uio.h>
# if defined(HAVE_DECL_READV) && HAVE_DECL_READV == 0
int readv(int, struct iovec *, int);
# endif
# if defined(HAVE_DECL_WRITEV) && HAVE_DECL_WRITEV == 0
int writev(int, struct iovec *, int);
# endif
#endif
/* Home grown routines */
#include "bsd-signal.h"
#include "bsd-misc.h"
#include "bsd-setres_id.h"
#include "bsd-statvfs.h"
#include "bsd-waitpid.h"
#include "bsd-poll.h"
#if defined(HAVE_DECL_GETPEEREID) && HAVE_DECL_GETPEEREID == 0
int getpeereid(int , uid_t *, gid_t *);
#endif
#ifndef HAVE_ARC4RANDOM
uint32_t arc4random(void);
#endif /* !HAVE_ARC4RANDOM */
#ifndef HAVE_ARC4RANDOM_BUF
void arc4random_buf(void *, size_t);
#endif
#ifndef HAVE_ARC4RANDOM_STIR
# define arc4random_stir()
#endif
#ifndef HAVE_ARC4RANDOM_UNIFORM
uint32_t arc4random_uniform(uint32_t);
#endif
#ifndef HAVE_ASPRINTF
int asprintf(char **, const char *, ...);
#endif
#ifndef HAVE_OPENPTY
# include <sys/ioctl.h> /* for struct winsize */
int openpty(int *, int *, char *, struct termios *, struct winsize *);
#endif /* HAVE_OPENPTY */
#ifndef HAVE_SNPRINTF
int snprintf(char *, size_t, SNPRINTF_CONST char *, ...);
#endif
#ifndef HAVE_STRTOLL
long long strtoll(const char *, char **, int);
#endif
#ifndef HAVE_STRTOUL
unsigned long strtoul(const char *, char **, int);
#endif
#ifndef HAVE_STRTOULL
unsigned long long strtoull(const char *, char **, int);
#endif
#ifndef HAVE_STRTONUM
long long strtonum(const char *, long long, long long, const char **);
#endif
/* multibyte character support */
#ifndef HAVE_MBLEN
# define mblen(x, y) (1)
#endif
#ifndef HAVE_WCWIDTH
# define wcwidth(x) (((x) >= 0x20 && (x) <= 0x7e) ? 1 : -1)
/* force our no-op nl_langinfo and mbtowc */
# undef HAVE_NL_LANGINFO
# undef HAVE_MBTOWC
# undef HAVE_LANGINFO_H
#endif
#ifndef HAVE_NL_LANGINFO
# define nl_langinfo(x) ""
#endif
#ifndef HAVE_MBTOWC
int mbtowc(wchar_t *, const char*, size_t);
#endif
#if !defined(HAVE_VASPRINTF) || !defined(HAVE_VSNPRINTF)
# include <stdarg.h>
#endif
/*
* Some platforms unconditionally undefine va_copy() so we define VA_COPY()
* instead. This is known to be the case on at least some configurations of
* AIX with the xlc compiler.
*/
#ifndef VA_COPY
# ifdef HAVE_VA_COPY
# define VA_COPY(dest, src) va_copy(dest, src)
# else
# ifdef HAVE___VA_COPY
# define VA_COPY(dest, src) __va_copy(dest, src)
# else
# define VA_COPY(dest, src) (dest) = (src)
# endif
# endif
#endif
#ifndef HAVE_VASPRINTF
int vasprintf(char **, const char *, va_list);
#endif
#ifndef HAVE_VSNPRINTF
int vsnprintf(char *, size_t, const char *, va_list);
#endif
#ifndef HAVE_USER_FROM_UID
char *user_from_uid(uid_t, int);
#endif
#ifndef HAVE_GROUP_FROM_GID
char *group_from_gid(gid_t, int);
#endif
#ifndef HAVE_TIMINGSAFE_BCMP
int timingsafe_bcmp(const void *, const void *, size_t);
#endif
#ifndef HAVE_BCRYPT_PBKDF
int bcrypt_pbkdf(const char *, size_t, const uint8_t *, size_t,
uint8_t *, size_t, unsigned int);
#endif
#ifndef HAVE_EXPLICIT_BZERO
void explicit_bzero(void *p, size_t n);
#endif
#ifndef HAVE_FREEZERO
void freezero(void *, size_t);
#endif
#ifndef HAVE_LOCALTIME_R
struct tm *localtime_r(const time_t *, struct tm *);
#endif
#ifndef HAVE_TIMEGM
+#include <time.h>
time_t timegm(struct tm *);
#endif
char *xcrypt(const char *password, const char *salt);
char *shadow_pw(struct passwd *pw);
/* rfc2553 socket API replacements */
#include "fake-rfc2553.h"
/* Routines for a single OS platform */
#include "bsd-cygwin_util.h"
#include "port-aix.h"
#include "port-irix.h"
#include "port-linux.h"
#include "port-solaris.h"
#include "port-net.h"
#include "port-uw.h"
/* _FORTIFY_SOURCE breaks FD_ISSET(n)/FD_SET(n) for n > FD_SETSIZE. Avoid. */
#if defined(HAVE_FEATURES_H) && defined(_FORTIFY_SOURCE)
# include <features.h>
# if defined(__GNU_LIBRARY__) && defined(__GLIBC_PREREQ)
# if __GLIBC_PREREQ(2, 15) && (_FORTIFY_SOURCE > 0)
# include <sys/socket.h> /* Ensure include guard is defined */
# undef FD_SET
# undef FD_ISSET
# define FD_SET(n, set) kludge_FD_SET(n, set)
# define FD_ISSET(n, set) kludge_FD_ISSET(n, set)
void kludge_FD_SET(int, fd_set *);
int kludge_FD_ISSET(int, fd_set *);
# endif /* __GLIBC_PREREQ(2, 15) && (_FORTIFY_SOURCE > 0) */
# endif /* __GNU_LIBRARY__ && __GLIBC_PREREQ */
#endif /* HAVE_FEATURES_H && _FORTIFY_SOURCE */
#endif /* _OPENBSD_COMPAT_H */
diff --git a/crypto/openssh/openbsd-compat/regress/Makefile.in b/crypto/openssh/openbsd-compat/regress/Makefile.in
index dd8cdc4b7e7a..6fabca849e66 100644
--- a/crypto/openssh/openbsd-compat/regress/Makefile.in
+++ b/crypto/openssh/openbsd-compat/regress/Makefile.in
@@ -1,36 +1,37 @@
sysconfdir=@sysconfdir@
piddir=@piddir@
srcdir=@srcdir@
top_srcdir=@top_srcdir@
VPATH=@srcdir@
CC=@CC@
LD=@LD@
CFLAGS=@CFLAGS@
CPPFLAGS=-I. -I.. -I../.. -I$(srcdir) -I$(srcdir)/.. -I$(srcdir)/../.. @CPPFLAGS@ @DEFS@
EXEEXT=@EXEEXT@
LIBCOMPAT=../libopenbsd-compat.a
-LIBS=@LIBS@
+LIBSSH=../../libssh.a
+LIBS=@LIBS@ @CHANNELLIBS@
LDFLAGS=@LDFLAGS@ $(LIBCOMPAT)
TESTPROGS=closefromtest$(EXEEXT) snprintftest$(EXEEXT) strduptest$(EXEEXT) \
strtonumtest$(EXEEXT) opensslvertest$(EXEEXT) utimensattest$(EXEEXT)
all: t-exec ${OTHERTESTS}
-%$(EXEEXT): %.c $(LIBCOMPAT)
- $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -o $@ $< $(LIBCOMPAT) $(LIBS)
+.c: $(LIBCOMPAT) $(LIBSSH)
+ $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -o $@ $< $(LIBCOMPAT) $(LIBSSH) $(LIBS)
t-exec: $(TESTPROGS)
@echo running compat regress tests
@for TEST in ""$?; do \
echo "run test $${TEST}" ... 1>&2; \
./$${TEST}$(EXEEXT) || exit $$? ; \
done
@echo finished compat regress tests
clean:
rm -f *.o *.a core $(TESTPROGS) valid.out
distclean: clean
rm -f Makefile *~
diff --git a/crypto/openssh/openbsd-compat/regress/opensslvertest.c b/crypto/openssh/openbsd-compat/regress/opensslvertest.c
index 43825b24c3eb..d50066609612 100644
--- a/crypto/openssh/openbsd-compat/regress/opensslvertest.c
+++ b/crypto/openssh/openbsd-compat/regress/opensslvertest.c
@@ -1,71 +1,73 @@
/*
* Copyright (c) 2014 Darren Tucker
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "includes.h"
#include <stdio.h>
#include <stdlib.h>
int ssh_compatible_openssl(long, long);
struct version_test {
long headerver;
long libver;
int result;
} version_tests[] = {
/* built with 0.9.8b release headers */
{ 0x0090802fL, 0x0090802fL, 1}, /* exact match */
{ 0x0090802fL, 0x0090804fL, 1}, /* newer library fix version: ok */
{ 0x0090802fL, 0x0090801fL, 1}, /* older library fix version: ok */
{ 0x0090802fL, 0x0090702fL, 0}, /* older library minor version: NO */
{ 0x0090802fL, 0x0090902fL, 0}, /* newer library minor version: NO */
{ 0x0090802fL, 0x0080802fL, 0}, /* older library major version: NO */
{ 0x0090802fL, 0x1000100fL, 0}, /* newer library major version: NO */
/* built with 1.0.1b release headers */
{ 0x1000101fL, 0x1000101fL, 1},/* exact match */
{ 0x1000101fL, 0x1000102fL, 1}, /* newer library patch version: ok */
{ 0x1000101fL, 0x1000100fL, 1}, /* older library patch version: ok */
{ 0x1000101fL, 0x1000201fL, 1}, /* newer library fix version: ok */
{ 0x1000101fL, 0x1000001fL, 0}, /* older library fix version: NO */
{ 0x1000101fL, 0x1010101fL, 0}, /* newer library minor version: NO */
{ 0x1000101fL, 0x0000101fL, 0}, /* older library major version: NO */
{ 0x1000101fL, 0x2000101fL, 0}, /* newer library major version: NO */
};
void
fail(long hver, long lver, int result)
{
fprintf(stderr, "opensslver: header %lx library %lx != %d \n", hver, lver, result);
exit(1);
}
int
main(void)
{
+#ifdef WITH_OPENSSL
unsigned int i;
int res;
long hver, lver;
for (i = 0; i < sizeof(version_tests) / sizeof(version_tests[0]); i++) {
hver = version_tests[i].headerver;
lver = version_tests[i].libver;
res = version_tests[i].result;
if (ssh_compatible_openssl(hver, lver) != res)
fail(hver, lver, res);
}
+#endif
exit(0);
}
diff --git a/crypto/openssh/readconf.c b/crypto/openssh/readconf.c
index fda7937582f4..3440d05e4e3b 100644
--- a/crypto/openssh/readconf.c
+++ b/crypto/openssh/readconf.c
@@ -1,3509 +1,3521 @@
-/* $OpenBSD: readconf.c,v 1.371 2023/01/02 07:03:30 djm Exp $ */
+/* $OpenBSD: readconf.c,v 1.372 2023/01/13 02:58:20 dtucker Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
* Functions for reading the configuration files.
*
* As far as I am concerned, the code I have written for this software
* can be used freely for any purpose. Any derived versions of this
* software must be clearly marked as such, and if the derived work is
* incompatible with the protocol description in the RFC file, it must be
* called by a name other than "ssh" or "Secure Shell".
*/
#include "includes.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <netdb.h>
#ifdef HAVE_PATHS_H
# include <paths.h>
#endif
#include <pwd.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <unistd.h>
#ifdef USE_SYSTEM_GLOB
# include <glob.h>
#else
# include "openbsd-compat/glob.h"
#endif
#ifdef HAVE_UTIL_H
#include <util.h>
#endif
#if defined(HAVE_STRNVIS) && defined(HAVE_VIS_H) && !defined(BROKEN_STRNVIS)
# include <vis.h>
#endif
#include "xmalloc.h"
#include "ssh.h"
#include "ssherr.h"
#include "compat.h"
#include "cipher.h"
#include "pathnames.h"
#include "log.h"
#include "sshkey.h"
#include "misc.h"
#include "readconf.h"
#include "match.h"
#include "kex.h"
#include "mac.h"
#include "uidswap.h"
#include "myproposal.h"
#include "digest.h"
#include "version.h"
/* Format of the configuration file:
# Configuration data is parsed as follows:
# 1. command line options
# 2. user-specific file
# 3. system-wide file
# Any configuration value is only changed the first time it is set.
# Thus, host-specific definitions should be at the beginning of the
# configuration file, and defaults at the end.
# Host-specific declarations. These may override anything above. A single
# host may match multiple declarations; these are processed in the order
# that they are given in.
Host *.ngs.fi ngs.fi
User foo
Host fake.com
Hostname another.host.name.real.org
User blaah
Port 34289
ForwardX11 no
ForwardAgent no
Host books.com
RemoteForward 9999 shadows.cs.hut.fi:9999
Ciphers 3des-cbc
Host fascist.blob.com
Port 23123
User tylonen
PasswordAuthentication no
Host puukko.hut.fi
User t35124p
ProxyCommand ssh-proxy %h %p
Host *.fr
PublicKeyAuthentication no
Host *.su
Ciphers aes128-ctr
PasswordAuthentication no
Host vpn.fake.com
Tunnel yes
TunnelDevice 3
# Defaults for various options
Host *
ForwardAgent no
ForwardX11 no
PasswordAuthentication yes
StrictHostKeyChecking yes
TcpKeepAlive no
IdentityFile ~/.ssh/identity
Port 22
EscapeChar ~
*/
static int read_config_file_depth(const char *filename, struct passwd *pw,
const char *host, const char *original_host, Options *options,
int flags, int *activep, int *want_final_pass, int depth);
static int process_config_line_depth(Options *options, struct passwd *pw,
const char *host, const char *original_host, char *line,
const char *filename, int linenum, int *activep, int flags,
int *want_final_pass, int depth);
/* Keyword tokens. */
typedef enum {
oBadOption,
oVersionAddendum,
oHost, oMatch, oInclude,
oForwardAgent, oForwardX11, oForwardX11Trusted, oForwardX11Timeout,
oGatewayPorts, oExitOnForwardFailure,
oPasswordAuthentication,
oXAuthLocation,
oIdentityFile, oHostname, oPort, oRemoteForward, oLocalForward,
oPermitRemoteOpen,
oCertificateFile, oAddKeysToAgent, oIdentityAgent,
oUser, oEscapeChar, oProxyCommand,
oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
oTCPKeepAlive, oNumberOfPasswordPrompts,
oLogFacility, oLogLevel, oLogVerbose, oCiphers, oMacs,
oPubkeyAuthentication,
oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
oHostKeyAlgorithms, oBindAddress, oBindInterface, oPKCS11Provider,
oClearAllForwardings, oNoHostAuthenticationForLocalhost,
oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
oAddressFamily, oGssAuthentication, oGssDelegateCreds,
oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
oSendEnv, oSetEnv, oControlPath, oControlMaster, oControlPersist,
oHashKnownHosts,
oTunnel, oTunnelDevice,
oLocalCommand, oPermitLocalCommand, oRemoteCommand,
oVisualHostKey,
oKexAlgorithms, oIPQoS, oRequestTTY, oSessionType, oStdinNull,
oForkAfterAuthentication, oIgnoreUnknown, oProxyUseFdpass,
oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots,
oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs,
oStreamLocalBindMask, oStreamLocalBindUnlink, oRevokedHostKeys,
oFingerprintHash, oUpdateHostkeys, oHostbasedAcceptedAlgorithms,
oPubkeyAcceptedAlgorithms, oCASignatureAlgorithms, oProxyJump,
oSecurityKeyProvider, oKnownHostsCommand, oRequiredRSASize,
+ oEnableEscapeCommandline,
oIgnore, oIgnoredUnknownOption, oDeprecated, oUnsupported
} OpCodes;
/* Textual representations of the tokens. */
static struct {
const char *name;
OpCodes opcode;
} keywords[] = {
/* Deprecated options */
{ "protocol", oIgnore }, /* NB. silently ignored */
{ "cipher", oDeprecated },
{ "fallbacktorsh", oDeprecated },
{ "globalknownhostsfile2", oDeprecated },
{ "rhostsauthentication", oDeprecated },
{ "userknownhostsfile2", oDeprecated },
{ "useroaming", oDeprecated },
{ "usersh", oDeprecated },
{ "useprivilegedport", oDeprecated },
/* Unsupported options */
{ "afstokenpassing", oUnsupported },
{ "kerberosauthentication", oUnsupported },
{ "kerberostgtpassing", oUnsupported },
{ "rsaauthentication", oUnsupported },
{ "rhostsrsaauthentication", oUnsupported },
{ "compressionlevel", oUnsupported },
/* Sometimes-unsupported options */
#if defined(GSSAPI)
{ "gssapiauthentication", oGssAuthentication },
{ "gssapidelegatecredentials", oGssDelegateCreds },
# else
{ "gssapiauthentication", oUnsupported },
{ "gssapidelegatecredentials", oUnsupported },
#endif
#ifdef ENABLE_PKCS11
{ "pkcs11provider", oPKCS11Provider },
{ "smartcarddevice", oPKCS11Provider },
# else
{ "smartcarddevice", oUnsupported },
{ "pkcs11provider", oUnsupported },
#endif
{ "forwardagent", oForwardAgent },
{ "forwardx11", oForwardX11 },
{ "forwardx11trusted", oForwardX11Trusted },
{ "forwardx11timeout", oForwardX11Timeout },
{ "exitonforwardfailure", oExitOnForwardFailure },
{ "xauthlocation", oXAuthLocation },
{ "gatewayports", oGatewayPorts },
{ "passwordauthentication", oPasswordAuthentication },
{ "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
{ "kbdinteractivedevices", oKbdInteractiveDevices },
{ "challengeresponseauthentication", oKbdInteractiveAuthentication }, /* alias */
{ "skeyauthentication", oKbdInteractiveAuthentication }, /* alias */
{ "tisauthentication", oKbdInteractiveAuthentication }, /* alias */
{ "pubkeyauthentication", oPubkeyAuthentication },
{ "dsaauthentication", oPubkeyAuthentication }, /* alias */
{ "hostbasedauthentication", oHostbasedAuthentication },
{ "identityfile", oIdentityFile },
{ "identityfile2", oIdentityFile }, /* obsolete */
{ "identitiesonly", oIdentitiesOnly },
{ "certificatefile", oCertificateFile },
{ "addkeystoagent", oAddKeysToAgent },
{ "identityagent", oIdentityAgent },
{ "hostname", oHostname },
{ "hostkeyalias", oHostKeyAlias },
{ "proxycommand", oProxyCommand },
{ "port", oPort },
{ "ciphers", oCiphers },
{ "macs", oMacs },
{ "remoteforward", oRemoteForward },
{ "localforward", oLocalForward },
{ "permitremoteopen", oPermitRemoteOpen },
{ "user", oUser },
{ "host", oHost },
{ "match", oMatch },
{ "escapechar", oEscapeChar },
{ "globalknownhostsfile", oGlobalKnownHostsFile },
{ "userknownhostsfile", oUserKnownHostsFile },
{ "connectionattempts", oConnectionAttempts },
{ "batchmode", oBatchMode },
{ "checkhostip", oCheckHostIP },
{ "stricthostkeychecking", oStrictHostKeyChecking },
{ "compression", oCompression },
{ "tcpkeepalive", oTCPKeepAlive },
{ "keepalive", oTCPKeepAlive }, /* obsolete */
{ "numberofpasswordprompts", oNumberOfPasswordPrompts },
{ "syslogfacility", oLogFacility },
{ "loglevel", oLogLevel },
{ "logverbose", oLogVerbose },
{ "dynamicforward", oDynamicForward },
{ "preferredauthentications", oPreferredAuthentications },
{ "hostkeyalgorithms", oHostKeyAlgorithms },
{ "casignaturealgorithms", oCASignatureAlgorithms },
{ "bindaddress", oBindAddress },
{ "bindinterface", oBindInterface },
{ "clearallforwardings", oClearAllForwardings },
{ "enablesshkeysign", oEnableSSHKeysign },
{ "verifyhostkeydns", oVerifyHostKeyDNS },
{ "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
{ "rekeylimit", oRekeyLimit },
{ "connecttimeout", oConnectTimeout },
{ "addressfamily", oAddressFamily },
{ "serveraliveinterval", oServerAliveInterval },
{ "serveralivecountmax", oServerAliveCountMax },
{ "sendenv", oSendEnv },
{ "setenv", oSetEnv },
{ "controlpath", oControlPath },
{ "controlmaster", oControlMaster },
{ "controlpersist", oControlPersist },
{ "hashknownhosts", oHashKnownHosts },
{ "include", oInclude },
{ "tunnel", oTunnel },
{ "tunneldevice", oTunnelDevice },
{ "localcommand", oLocalCommand },
{ "permitlocalcommand", oPermitLocalCommand },
{ "remotecommand", oRemoteCommand },
{ "visualhostkey", oVisualHostKey },
{ "kexalgorithms", oKexAlgorithms },
{ "ipqos", oIPQoS },
{ "requesttty", oRequestTTY },
{ "sessiontype", oSessionType },
{ "stdinnull", oStdinNull },
{ "forkafterauthentication", oForkAfterAuthentication },
{ "proxyusefdpass", oProxyUseFdpass },
{ "canonicaldomains", oCanonicalDomains },
{ "canonicalizefallbacklocal", oCanonicalizeFallbackLocal },
{ "canonicalizehostname", oCanonicalizeHostname },
{ "canonicalizemaxdots", oCanonicalizeMaxDots },
{ "canonicalizepermittedcnames", oCanonicalizePermittedCNAMEs },
{ "streamlocalbindmask", oStreamLocalBindMask },
{ "streamlocalbindunlink", oStreamLocalBindUnlink },
{ "revokedhostkeys", oRevokedHostKeys },
{ "fingerprinthash", oFingerprintHash },
{ "updatehostkeys", oUpdateHostkeys },
{ "hostbasedacceptedalgorithms", oHostbasedAcceptedAlgorithms },
{ "hostbasedkeytypes", oHostbasedAcceptedAlgorithms }, /* obsolete */
{ "pubkeyacceptedalgorithms", oPubkeyAcceptedAlgorithms },
{ "pubkeyacceptedkeytypes", oPubkeyAcceptedAlgorithms }, /* obsolete */
{ "ignoreunknown", oIgnoreUnknown },
{ "proxyjump", oProxyJump },
{ "securitykeyprovider", oSecurityKeyProvider },
{ "knownhostscommand", oKnownHostsCommand },
{ "requiredrsasize", oRequiredRSASize },
+ { "enableescapecommandline", oEnableEscapeCommandline },
{ "hpndisabled", oDeprecated },
{ "hpnbuffersize", oDeprecated },
{ "tcprcvbufpoll", oDeprecated },
{ "tcprcvbuf", oDeprecated },
{ "noneenabled", oUnsupported },
{ "noneswitch", oUnsupported },
{ "versionaddendum", oVersionAddendum },
{ NULL, oBadOption }
};
static const char *lookup_opcode_name(OpCodes code);
const char *
kex_default_pk_alg(void)
{
static char *pkalgs;
if (pkalgs == NULL) {
char *all_key;
all_key = sshkey_alg_list(0, 0, 1, ',');
pkalgs = match_filter_allowlist(KEX_DEFAULT_PK_ALG, all_key);
free(all_key);
}
return pkalgs;
}
char *
ssh_connection_hash(const char *thishost, const char *host, const char *portstr,
const char *user)
{
struct ssh_digest_ctx *md;
u_char conn_hash[SSH_DIGEST_MAX_LENGTH];
if ((md = ssh_digest_start(SSH_DIGEST_SHA1)) == NULL ||
ssh_digest_update(md, thishost, strlen(thishost)) < 0 ||
ssh_digest_update(md, host, strlen(host)) < 0 ||
ssh_digest_update(md, portstr, strlen(portstr)) < 0 ||
ssh_digest_update(md, user, strlen(user)) < 0 ||
ssh_digest_final(md, conn_hash, sizeof(conn_hash)) < 0)
fatal_f("mux digest failed");
ssh_digest_free(md);
return tohex(conn_hash, ssh_digest_bytes(SSH_DIGEST_SHA1));
}
/*
* Adds a local TCP/IP port forward to options. Never returns if there is an
* error.
*/
void
add_local_forward(Options *options, const struct Forward *newfwd)
{
struct Forward *fwd;
int i;
/* Don't add duplicates */
for (i = 0; i < options->num_local_forwards; i++) {
if (forward_equals(newfwd, options->local_forwards + i))
return;
}
options->local_forwards = xreallocarray(options->local_forwards,
options->num_local_forwards + 1,
sizeof(*options->local_forwards));
fwd = &options->local_forwards[options->num_local_forwards++];
fwd->listen_host = newfwd->listen_host;
fwd->listen_port = newfwd->listen_port;
fwd->listen_path = newfwd->listen_path;
fwd->connect_host = newfwd->connect_host;
fwd->connect_port = newfwd->connect_port;
fwd->connect_path = newfwd->connect_path;
}
/*
* Adds a remote TCP/IP port forward to options. Never returns if there is
* an error.
*/
void
add_remote_forward(Options *options, const struct Forward *newfwd)
{
struct Forward *fwd;
int i;
/* Don't add duplicates */
for (i = 0; i < options->num_remote_forwards; i++) {
if (forward_equals(newfwd, options->remote_forwards + i))
return;
}
options->remote_forwards = xreallocarray(options->remote_forwards,
options->num_remote_forwards + 1,
sizeof(*options->remote_forwards));
fwd = &options->remote_forwards[options->num_remote_forwards++];
fwd->listen_host = newfwd->listen_host;
fwd->listen_port = newfwd->listen_port;
fwd->listen_path = newfwd->listen_path;
fwd->connect_host = newfwd->connect_host;
fwd->connect_port = newfwd->connect_port;
fwd->connect_path = newfwd->connect_path;
fwd->handle = newfwd->handle;
fwd->allocated_port = 0;
}
static void
clear_forwardings(Options *options)
{
int i;
for (i = 0; i < options->num_local_forwards; i++) {
free(options->local_forwards[i].listen_host);
free(options->local_forwards[i].listen_path);
free(options->local_forwards[i].connect_host);
free(options->local_forwards[i].connect_path);
}
if (options->num_local_forwards > 0) {
free(options->local_forwards);
options->local_forwards = NULL;
}
options->num_local_forwards = 0;
for (i = 0; i < options->num_remote_forwards; i++) {
free(options->remote_forwards[i].listen_host);
free(options->remote_forwards[i].listen_path);
free(options->remote_forwards[i].connect_host);
free(options->remote_forwards[i].connect_path);
}
if (options->num_remote_forwards > 0) {
free(options->remote_forwards);
options->remote_forwards = NULL;
}
options->num_remote_forwards = 0;
options->tun_open = SSH_TUNMODE_NO;
}
void
add_certificate_file(Options *options, const char *path, int userprovided)
{
int i;
if (options->num_certificate_files >= SSH_MAX_CERTIFICATE_FILES)
fatal("Too many certificate files specified (max %d)",
SSH_MAX_CERTIFICATE_FILES);
/* Avoid registering duplicates */
for (i = 0; i < options->num_certificate_files; i++) {
if (options->certificate_file_userprovided[i] == userprovided &&
strcmp(options->certificate_files[i], path) == 0) {
debug2_f("ignoring duplicate key %s", path);
return;
}
}
options->certificate_file_userprovided[options->num_certificate_files] =
userprovided;
options->certificate_files[options->num_certificate_files++] =
xstrdup(path);
}
void
add_identity_file(Options *options, const char *dir, const char *filename,
int userprovided)
{
char *path;
int i;
if (options->num_identity_files >= SSH_MAX_IDENTITY_FILES)
fatal("Too many identity files specified (max %d)",
SSH_MAX_IDENTITY_FILES);
if (dir == NULL) /* no dir, filename is absolute */
path = xstrdup(filename);
else if (xasprintf(&path, "%s%s", dir, filename) >= PATH_MAX)
fatal("Identity file path %s too long", path);
/* Avoid registering duplicates */
for (i = 0; i < options->num_identity_files; i++) {
if (options->identity_file_userprovided[i] == userprovided &&
strcmp(options->identity_files[i], path) == 0) {
debug2_f("ignoring duplicate key %s", path);
free(path);
return;
}
}
options->identity_file_userprovided[options->num_identity_files] =
userprovided;
options->identity_files[options->num_identity_files++] = path;
}
int
default_ssh_port(void)
{
static int port;
struct servent *sp;
if (port == 0) {
sp = getservbyname(SSH_SERVICE_NAME, "tcp");
port = sp ? ntohs(sp->s_port) : SSH_DEFAULT_PORT;
}
return port;
}
/*
* Execute a command in a shell.
* Return its exit status or -1 on abnormal exit.
*/
static int
execute_in_shell(const char *cmd)
{
char *shell;
pid_t pid;
int status;
if ((shell = getenv("SHELL")) == NULL)
shell = _PATH_BSHELL;
if (access(shell, X_OK) == -1) {
fatal("Shell \"%s\" is not executable: %s",
shell, strerror(errno));
}
debug("Executing command: '%.500s'", cmd);
/* Fork and execute the command. */
if ((pid = fork()) == 0) {
char *argv[4];
if (stdfd_devnull(1, 1, 0) == -1)
fatal_f("stdfd_devnull failed");
closefrom(STDERR_FILENO + 1);
argv[0] = shell;
argv[1] = "-c";
argv[2] = xstrdup(cmd);
argv[3] = NULL;
execv(argv[0], argv);
error("Unable to execute '%.100s': %s", cmd, strerror(errno));
/* Die with signal to make this error apparent to parent. */
ssh_signal(SIGTERM, SIG_DFL);
kill(getpid(), SIGTERM);
_exit(1);
}
/* Parent. */
if (pid == -1)
fatal_f("fork: %.100s", strerror(errno));
while (waitpid(pid, &status, 0) == -1) {
if (errno != EINTR && errno != EAGAIN)
fatal_f("waitpid: %s", strerror(errno));
}
if (!WIFEXITED(status)) {
error("command '%.100s' exited abnormally", cmd);
return -1;
}
debug3("command returned status %d", WEXITSTATUS(status));
return WEXITSTATUS(status);
}
/*
* Parse and execute a Match directive.
*/
static int
match_cfg_line(Options *options, char **condition, struct passwd *pw,
const char *host_arg, const char *original_host, int final_pass,
int *want_final_pass, const char *filename, int linenum)
{
char *arg, *oattrib, *attrib, *cmd, *cp = *condition, *host, *criteria;
const char *ruser;
int r, port, this_result, result = 1, attributes = 0, negate;
char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV];
char uidstr[32];
/*
* Configuration is likely to be incomplete at this point so we
* must be prepared to use default values.
*/
port = options->port <= 0 ? default_ssh_port() : options->port;
ruser = options->user == NULL ? pw->pw_name : options->user;
if (final_pass) {
host = xstrdup(options->hostname);
} else if (options->hostname != NULL) {
/* NB. Please keep in sync with ssh.c:main() */
host = percent_expand(options->hostname,
"h", host_arg, (char *)NULL);
} else {
host = xstrdup(host_arg);
}
debug2("checking match for '%s' host %s originally %s",
cp, host, original_host);
while ((oattrib = attrib = strdelim(&cp)) && *attrib != '\0') {
/* Terminate on comment */
if (*attrib == '#') {
cp = NULL; /* mark all arguments consumed */
break;
}
arg = criteria = NULL;
this_result = 1;
if ((negate = attrib[0] == '!'))
attrib++;
/* Criterion "all" has no argument and must appear alone */
if (strcasecmp(attrib, "all") == 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) {
/*
* If the config requests "Match final" then remember
* this so we can perform a second pass later.
*/
if (strcasecmp(attrib, "final") == 0 &&
want_final_pass != NULL)
*want_final_pass = 1;
r = !!final_pass; /* force bitmask member to boolean */
if (r == (negate ? 1 : 0))
this_result = result = 0;
debug3("%.200s line %d: %smatched '%s'",
filename, linenum,
this_result ? "" : "not ", oattrib);
continue;
}
/* All other criteria require an argument */
if ((arg = strdelim(&cp)) == NULL ||
*arg == '\0' || *arg == '#') {
error("Missing Match criteria for %s", attrib);
result = -1;
goto out;
}
if (strcasecmp(attrib, "host") == 0) {
criteria = xstrdup(host);
r = match_hostname(host, arg) == 1;
if (r == (negate ? 1 : 0))
this_result = result = 0;
} else if (strcasecmp(attrib, "originalhost") == 0) {
criteria = xstrdup(original_host);
r = match_hostname(original_host, arg) == 1;
if (r == (negate ? 1 : 0))
this_result = result = 0;
} else if (strcasecmp(attrib, "user") == 0) {
criteria = xstrdup(ruser);
r = match_pattern_list(ruser, arg, 0) == 1;
if (r == (negate ? 1 : 0))
this_result = result = 0;
} else if (strcasecmp(attrib, "localuser") == 0) {
criteria = xstrdup(pw->pw_name);
r = match_pattern_list(pw->pw_name, arg, 0) == 1;
if (r == (negate ? 1 : 0))
this_result = result = 0;
} else if (strcasecmp(attrib, "exec") == 0) {
char *conn_hash_hex, *keyalias;
if (gethostname(thishost, sizeof(thishost)) == -1)
fatal("gethostname: %s", strerror(errno));
strlcpy(shorthost, thishost, sizeof(shorthost));
shorthost[strcspn(thishost, ".")] = '\0';
snprintf(portstr, sizeof(portstr), "%d", port);
snprintf(uidstr, sizeof(uidstr), "%llu",
(unsigned long long)pw->pw_uid);
conn_hash_hex = ssh_connection_hash(thishost, host,
portstr, ruser);
keyalias = options->host_key_alias ?
options->host_key_alias : host;
cmd = percent_expand(arg,
"C", conn_hash_hex,
"L", shorthost,
"d", pw->pw_dir,
"h", host,
"k", keyalias,
"l", thishost,
"n", original_host,
"p", portstr,
"r", ruser,
"u", pw->pw_name,
"i", uidstr,
(char *)NULL);
free(conn_hash_hex);
if (result != 1) {
/* skip execution if prior predicate failed */
debug3("%.200s line %d: skipped exec "
"\"%.100s\"", filename, linenum, cmd);
free(cmd);
continue;
}
r = execute_in_shell(cmd);
if (r == -1) {
fatal("%.200s line %d: match exec "
"'%.100s' error", filename,
linenum, cmd);
}
criteria = xstrdup(cmd);
free(cmd);
/* Force exit status to boolean */
r = r == 0;
if (r == (negate ? 1 : 0))
this_result = result = 0;
} else {
error("Unsupported Match attribute %s", attrib);
result = -1;
goto out;
}
debug3("%.200s line %d: %smatched '%s \"%.100s\"' ",
filename, linenum, this_result ? "": "not ",
oattrib, criteria);
free(criteria);
}
if (attributes == 0) {
error("One or more attributes required for Match");
result = -1;
goto out;
}
out:
if (result != -1)
debug2("match %sfound", result ? "" : "not ");
*condition = cp;
free(host);
return result;
}
/* Remove environment variable by pattern */
static void
rm_env(Options *options, const char *arg, const char *filename, int linenum)
{
u_int i, j, onum_send_env = options->num_send_env;
/* Remove an environment variable */
for (i = 0; i < options->num_send_env; ) {
if (!match_pattern(options->send_env[i], arg + 1)) {
i++;
continue;
}
debug3("%s line %d: removing environment %s",
filename, linenum, options->send_env[i]);
free(options->send_env[i]);
options->send_env[i] = NULL;
for (j = i; j < options->num_send_env - 1; j++) {
options->send_env[j] = options->send_env[j + 1];
options->send_env[j + 1] = NULL;
}
options->num_send_env--;
/* NB. don't increment i */
}
if (onum_send_env != options->num_send_env) {
options->send_env = xrecallocarray(options->send_env,
onum_send_env, options->num_send_env,
sizeof(*options->send_env));
}
}
/*
* Returns the number of the token pointed to by cp or oBadOption.
*/
static OpCodes
parse_token(const char *cp, const char *filename, int linenum,
const char *ignored_unknown)
{
int i;
for (i = 0; keywords[i].name; i++)
if (strcmp(cp, keywords[i].name) == 0)
return keywords[i].opcode;
if (ignored_unknown != NULL &&
match_pattern_list(cp, ignored_unknown, 1) == 1)
return oIgnoredUnknownOption;
error("%s: line %d: Bad configuration option: %s",
filename, linenum, cp);
return oBadOption;
}
/* Multistate option parsing */
struct multistate {
char *key;
int value;
};
static const struct multistate multistate_flag[] = {
{ "true", 1 },
{ "false", 0 },
{ "yes", 1 },
{ "no", 0 },
{ NULL, -1 }
};
static const struct multistate multistate_yesnoask[] = {
{ "true", 1 },
{ "false", 0 },
{ "yes", 1 },
{ "no", 0 },
{ "ask", 2 },
{ NULL, -1 }
};
static const struct multistate multistate_strict_hostkey[] = {
{ "true", SSH_STRICT_HOSTKEY_YES },
{ "false", SSH_STRICT_HOSTKEY_OFF },
{ "yes", SSH_STRICT_HOSTKEY_YES },
{ "no", SSH_STRICT_HOSTKEY_OFF },
{ "ask", SSH_STRICT_HOSTKEY_ASK },
{ "off", SSH_STRICT_HOSTKEY_OFF },
{ "accept-new", SSH_STRICT_HOSTKEY_NEW },
{ NULL, -1 }
};
static const struct multistate multistate_yesnoaskconfirm[] = {
{ "true", 1 },
{ "false", 0 },
{ "yes", 1 },
{ "no", 0 },
{ "ask", 2 },
{ "confirm", 3 },
{ NULL, -1 }
};
static const struct multistate multistate_addressfamily[] = {
{ "inet", AF_INET },
{ "inet6", AF_INET6 },
{ "any", AF_UNSPEC },
{ NULL, -1 }
};
static const struct multistate multistate_controlmaster[] = {
{ "true", SSHCTL_MASTER_YES },
{ "yes", SSHCTL_MASTER_YES },
{ "false", SSHCTL_MASTER_NO },
{ "no", SSHCTL_MASTER_NO },
{ "auto", SSHCTL_MASTER_AUTO },
{ "ask", SSHCTL_MASTER_ASK },
{ "autoask", SSHCTL_MASTER_AUTO_ASK },
{ NULL, -1 }
};
static const struct multistate multistate_tunnel[] = {
{ "ethernet", SSH_TUNMODE_ETHERNET },
{ "point-to-point", SSH_TUNMODE_POINTOPOINT },
{ "true", SSH_TUNMODE_DEFAULT },
{ "yes", SSH_TUNMODE_DEFAULT },
{ "false", SSH_TUNMODE_NO },
{ "no", SSH_TUNMODE_NO },
{ NULL, -1 }
};
static const struct multistate multistate_requesttty[] = {
{ "true", REQUEST_TTY_YES },
{ "yes", REQUEST_TTY_YES },
{ "false", REQUEST_TTY_NO },
{ "no", REQUEST_TTY_NO },
{ "force", REQUEST_TTY_FORCE },
{ "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 },
{ "yes", SSH_CANONICALISE_YES },
{ "no", SSH_CANONICALISE_NO },
{ "always", SSH_CANONICALISE_ALWAYS },
{ NULL, -1 }
};
static const struct multistate multistate_pubkey_auth[] = {
{ "true", SSH_PUBKEY_AUTH_ALL },
{ "false", SSH_PUBKEY_AUTH_NO },
{ "yes", SSH_PUBKEY_AUTH_ALL },
{ "no", SSH_PUBKEY_AUTH_NO },
{ "unbound", SSH_PUBKEY_AUTH_UNBOUND },
{ "host-bound", SSH_PUBKEY_AUTH_HBOUND },
{ NULL, -1 }
};
static const struct multistate multistate_compression[] = {
#ifdef WITH_ZLIB
{ "yes", COMP_ZLIB },
#endif
{ "no", COMP_NONE },
{ NULL, -1 }
};
static int
parse_multistate_value(const char *arg, const char *filename, int linenum,
const struct multistate *multistate_ptr)
{
int i;
if (!arg || *arg == '\0') {
error("%s line %d: missing argument.", filename, linenum);
return -1;
}
for (i = 0; multistate_ptr[i].key != NULL; i++) {
if (strcasecmp(arg, multistate_ptr[i].key) == 0)
return multistate_ptr[i].value;
}
return -1;
}
/*
* Processes a single option line as used in the configuration files. This
* only sets those values that have not already been set.
*/
int
process_config_line(Options *options, struct passwd *pw, const char *host,
const char *original_host, char *line, const char *filename,
int linenum, int *activep, int flags)
{
return process_config_line_depth(options, pw, host, original_host,
line, filename, linenum, activep, flags, NULL, 0);
}
#define WHITESPACE " \t\r\n"
static int
process_config_line_depth(Options *options, struct passwd *pw, const char *host,
const char *original_host, char *line, const char *filename,
int linenum, int *activep, int flags, int *want_final_pass, int depth)
{
char *str, **charptr, *endofnumber, *keyword, *arg, *arg2, *p;
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;
SyslogFacility *log_facility_ptr;
long long val64;
size_t len;
struct Forward fwd;
const struct multistate *multistate_ptr;
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;
activep = &cmdline;
}
/* Strip trailing whitespace. Allow \f (form feed) at EOL only */
if ((len = strlen(line)) == 0)
return 0;
for (len--; len > 0; len--) {
if (strchr(WHITESPACE "\f", line[len]) == NULL)
break;
line[len] = '\0';
}
str = line;
/* Get the keyword. (Each line is supposed to begin with a keyword). */
if ((keyword = strdelim(&str)) == NULL)
return 0;
/* Ignore leading whitespace. */
if (*keyword == '\0')
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 */
goto out;
case oIgnore:
argv_consume(&ac);
break;
case oIgnoredUnknownOption:
debug("%s line %d: Ignored unknown option \"%s\"",
filename, linenum, keyword);
argv_consume(&ac);
break;
case oConnectTimeout:
intptr = &options->connection_timeout;
parse_time:
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) {
error("%s line %d: invalid time value.",
filename, linenum);
goto out;
}
if (*activep && *intptr == -1)
*intptr = value;
break;
case oForwardAgent:
intptr = &options->forward_agent;
arg = argv_next(&ac, &av);
if (!arg || *arg == '\0') {
error("%s line %d: missing argument.",
filename, linenum);
goto out;
}
value = -1;
multistate_ptr = multistate_flag;
for (i = 0; multistate_ptr[i].key != NULL; i++) {
if (strcasecmp(arg, multistate_ptr[i].key) == 0) {
value = multistate_ptr[i].value;
break;
}
}
if (value != -1) {
if (*activep && *intptr == -1)
*intptr = value;
break;
}
/* ForwardAgent wasn't 'yes' or 'no', assume a path */
if (*activep && *intptr == -1)
*intptr = 1;
charptr = &options->forward_agent_sock_path;
goto parse_agent_path;
case oForwardX11:
intptr = &options->forward_x11;
parse_flag:
multistate_ptr = multistate_flag;
parse_multistate:
arg = argv_next(&ac, &av);
if ((value = parse_multistate_value(arg, filename, linenum,
multistate_ptr)) == -1) {
error("%s line %d: unsupported option \"%s\".",
filename, linenum, arg);
goto out;
}
if (*activep && *intptr == -1)
*intptr = value;
break;
case oForwardX11Trusted:
intptr = &options->forward_x11_trusted;
goto parse_flag;
case oForwardX11Timeout:
intptr = &options->forward_x11_timeout;
goto parse_time;
case oGatewayPorts:
intptr = &options->fwd_opts.gateway_ports;
goto parse_flag;
case oExitOnForwardFailure:
intptr = &options->exit_on_forward_failure;
goto parse_flag;
case oPasswordAuthentication:
intptr = &options->password_authentication;
goto parse_flag;
case oKbdInteractiveAuthentication:
intptr = &options->kbd_interactive_authentication;
goto parse_flag;
case oKbdInteractiveDevices:
charptr = &options->kbd_interactive_devices;
goto parse_string;
case oPubkeyAuthentication:
multistate_ptr = multistate_pubkey_auth;
intptr = &options->pubkey_authentication;
goto parse_multistate;
case oHostbasedAuthentication:
intptr = &options->hostbased_authentication;
goto parse_flag;
case oGssAuthentication:
intptr = &options->gss_authentication;
goto parse_flag;
case oGssDelegateCreds:
intptr = &options->gss_deleg_creds;
goto parse_flag;
case oBatchMode:
intptr = &options->batch_mode;
goto parse_flag;
case oCheckHostIP:
intptr = &options->check_host_ip;
goto parse_flag;
case oVerifyHostKeyDNS:
intptr = &options->verify_host_key_dns;
multistate_ptr = multistate_yesnoask;
goto parse_multistate;
case oStrictHostKeyChecking:
intptr = &options->strict_host_key_checking;
multistate_ptr = multistate_strict_hostkey;
goto parse_multistate;
case oCompression:
intptr = &options->compression;
multistate_ptr = multistate_compression;
goto parse_multistate;
case oTCPKeepAlive:
intptr = &options->tcp_keep_alive;
goto parse_flag;
case oNoHostAuthenticationForLocalhost:
intptr = &options->no_host_authentication_for_localhost;
goto parse_flag;
case oNumberOfPasswordPrompts:
intptr = &options->number_of_password_prompts;
goto parse_int;
case oRekeyLimit:
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) {
error("%.200s line %d: Bad number '%s': %s",
filename, linenum, arg, strerror(errno));
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 (ac != 0) { /* optional rekey interval present */
if (strcmp(av[0], "none") == 0) {
(void)argv_next(&ac, &av); /* discard */
break;
}
intptr = &options->rekey_interval;
goto parse_time;
}
break;
case oIdentityFile:
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) {
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 = 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) {
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);
}
break;
case oXAuthLocation:
charptr=&options->xauth_location;
goto parse_string;
case oUser:
charptr = &options->user;
parse_string:
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;
case oGlobalKnownHostsFile:
cpptr = (char **)&options->system_hostfiles;
uintptr = &options->num_system_hostfiles;
max_entries = SSH_MAX_HOSTS_FILES;
parse_char_array:
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);
}
}
break;
case oUserKnownHostsFile:
cpptr = (char **)&options->user_hostfiles;
uintptr = &options->num_user_hostfiles;
max_entries = SSH_MAX_HOSTS_FILES;
goto parse_char_array;
case oHostname:
charptr = &options->hostname;
goto parse_string;
case oHostKeyAlias:
charptr = &options->host_key_alias;
goto parse_string;
case oPreferredAuthentications:
charptr = &options->preferred_authentications;
goto parse_string;
case oBindAddress:
charptr = &options->bind_address;
goto parse_string;
case oBindInterface:
charptr = &options->bind_interface;
goto parse_string;
case oPKCS11Provider:
charptr = &options->pkcs11_provider;
goto parse_string;
case oSecurityKeyProvider:
charptr = &options->sk_provider;
goto parse_string;
case oKnownHostsCommand:
charptr = &options->known_hosts_command;
goto parse_command;
case oProxyCommand:
charptr = &options->proxy_command;
/* Ignore ProxyCommand if ProxyJump already specified */
if (options->jump_host != NULL)
charptr = &options->jump_host; /* Skip below */
parse_command:
if (str == NULL) {
error("%.200s line %d: Missing argument.",
filename, linenum);
goto out;
}
len = strspn(str, WHITESPACE "=");
if (*activep && *charptr == NULL)
*charptr = xstrdup(str + len);
argv_consume(&ac);
break;
case oProxyJump:
if (str == NULL) {
error("%.200s line %d: Missing argument.",
filename, linenum);
goto out;
}
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;
}
argv_consume(&ac);
break;
case oPort:
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) {
error("%.200s line %d: Bad port '%s'.",
filename, linenum, arg);
goto out;
}
if (*activep && options->port == -1)
options->port = value;
break;
case oConnectionAttempts:
intptr = &options->connection_attempts;
parse_int:
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 = argv_next(&ac, &av);
if (!arg || *arg == '\0') {
error("%.200s line %d: Missing argument.",
filename, linenum);
goto out;
}
if (*arg != '-' &&
!ciphers_valid(*arg == '+' || *arg == '^' ? arg + 1 : arg)){
error("%.200s line %d: Bad SSH2 cipher spec '%s'.",
filename, linenum, arg ? arg : "<NONE>");
goto out;
}
if (*activep && options->ciphers == NULL)
options->ciphers = xstrdup(arg);
break;
case oMacs:
arg = argv_next(&ac, &av);
if (!arg || *arg == '\0') {
error("%.200s line %d: Missing argument.",
filename, linenum);
goto out;
}
if (*arg != '-' &&
!mac_valid(*arg == '+' || *arg == '^' ? arg + 1 : arg)) {
error("%.200s line %d: Bad SSH2 MAC spec '%s'.",
filename, linenum, arg ? arg : "<NONE>");
goto out;
}
if (*activep && options->macs == NULL)
options->macs = xstrdup(arg);
break;
case oKexAlgorithms:
arg = 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)) {
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_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)) {
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_pubkey_algos;
case oLogLevel:
log_level_ptr = &options->log_level;
arg = argv_next(&ac, &av);
value = log_level_number(arg);
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 = argv_next(&ac, &av);
value = log_facility_number(arg);
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 = 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 = argv_next(&ac, &av);
if (arg2 == NULL || *arg2 == '\0') {
if (remotefwd)
dynamicfwd = 1;
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,
arg2);
}
}
if (dynamicfwd)
strlcpy(fwdarg, arg, sizeof(fwdarg));
if (parse_forward(&fwd, fwdarg, dynamicfwd, remotefwd) == 0) {
error("%.200s line %d: Bad forwarding specification.",
filename, linenum);
goto out;
}
if (*activep) {
if (remotefwd) {
add_remote_forward(options, &fwd);
} else {
add_local_forward(options, &fwd);
}
}
break;
case oPermitRemoteOpen:
uintptr = &options->num_permitted_remote_opens;
cppptr = &options->permitted_remote_opens;
uvalue = *uintptr; /* modified later */
i = 0;
while ((arg = argv_next(&ac, &av)) != NULL) {
arg2 = xstrdup(arg);
/* Allow any/none only in first position */
if (strcasecmp(arg, "none") == 0 ||
strcasecmp(arg, "any") == 0) {
if (i > 0 || ac > 0) {
error("%s line %d: keyword %s \"%s\" "
"argument must appear alone.",
filename, linenum, keyword, arg);
goto out;
}
} else {
p = hpdelim(&arg);
if (p == NULL) {
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);
i++;
}
if (i == 0)
fatal("%s line %d: missing %s specification",
filename, linenum, lookup_opcode_name(opcode));
break;
case oClearAllForwardings:
intptr = &options->clear_forwardings;
goto parse_flag;
case oHost:
if (cmdline) {
error("Host directive not supported as a command-line "
"option");
goto out;
}
*activep = 0;
arg2 = NULL;
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++;
if (match_pattern(host, arg)) {
if (negated) {
debug("%.200s line %d: Skipping Host "
"block because of negated match "
"for %.100s", filename, linenum,
arg);
*activep = 0;
argv_consume(&ac);
break;
}
if (!*activep)
arg2 = arg; /* logged below */
*activep = 1;
}
}
if (*activep)
debug("%.200s line %d: Applying options for %.100s",
filename, linenum, arg2);
break;
case oMatch:
if (cmdline) {
error("Host directive not supported as a command-line "
"option");
goto out;
}
value = match_cfg_line(options, &str, pw, host, original_host,
flags & SSHCONF_FINAL, want_final_pass,
filename, linenum);
if (value < 0) {
error("%.200s line %d: Bad Match condition", filename,
linenum);
goto out;
}
*activep = (flags & SSHCONF_NEVERMATCH) ? 0 : value;
/*
* If match_cfg_line() didn't consume all its arguments then
* arrange for the extra arguments check below to fail.
*/
if (str == NULL || *str == '\0')
argv_consume(&ac);
break;
case oEscapeChar:
intptr = &options->escape_char;
arg = 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')
value = (u_char) arg[0];
else if (arg[0] == '^' && arg[2] == 0 &&
(u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
value = (u_char) arg[1] & 31;
else {
error("%.200s line %d: Bad escape character.",
filename, linenum);
goto out;
}
if (*activep && *intptr == -1)
*intptr = value;
break;
case oAddressFamily:
intptr = &options->address_family;
multistate_ptr = multistate_addressfamily;
goto parse_multistate;
case oEnableSSHKeysign:
intptr = &options->enable_ssh_keysign;
goto parse_flag;
case oIdentitiesOnly:
intptr = &options->identities_only;
goto parse_flag;
case oServerAliveInterval:
intptr = &options->server_alive_interval;
goto parse_time;
case oServerAliveCountMax:
intptr = &options->server_alive_count_max;
goto parse_int;
case oSendEnv:
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 == '-') {
/* Removing an env var */
rm_env(options, arg, filename, linenum);
continue;
}
opt_array_append(filename, linenum,
lookup_opcode_name(opcode),
&options->send_env, &options->num_send_env, arg);
}
break;
case oSetEnv:
value = options->num_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;
if (lookup_setenv_in_list(arg, options->setenv,
options->num_setenv) != NULL) {
debug2("%s line %d: ignoring duplicate env "
"name \"%.64s\"", filename, linenum, arg);
continue;
}
opt_array_append(filename, linenum,
lookup_opcode_name(opcode),
&options->setenv, &options->num_setenv, arg);
}
break;
case oControlPath:
charptr = &options->control_path;
goto parse_string;
case oControlMaster:
intptr = &options->control_master;
multistate_ptr = multistate_controlmaster;
goto parse_multistate;
case oControlPersist:
/* no/false/yes/true, or a time spec */
intptr = &options->control_persist;
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)
value = 0;
else if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
value = 1;
else if ((value2 = convtime(arg)) >= 0)
value = 1;
else {
error("%.200s line %d: Bad ControlPersist argument.",
filename, linenum);
goto out;
}
if (*activep && *intptr == -1) {
*intptr = value;
options->control_persist_timeout = value2;
}
break;
case oHashKnownHosts:
intptr = &options->hash_known_hosts;
goto parse_flag;
case oTunnel:
intptr = &options->tun_open;
multistate_ptr = multistate_tunnel;
goto parse_multistate;
case oTunnelDevice:
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) {
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;
}
break;
case oLocalCommand:
charptr = &options->local_command;
goto parse_command;
case oPermitLocalCommand:
intptr = &options->permit_local_command;
goto parse_flag;
case oRemoteCommand:
charptr = &options->remote_command;
goto parse_command;
case oVisualHostKey:
intptr = &options->visual_host_key;
goto parse_flag;
case oInclude:
if (cmdline) {
error("Include directive not supported as a "
"command-line option");
goto out;
}
value = 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
* must not. If the path is relative, then treat it
* as living in ~/.ssh for user configurations or
* /etc/ssh for system ones.
*/
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) ?
"~/" _PATH_SSH_USER_DIR : SSHDIR, arg);
} else
arg2 = xstrdup(arg);
memset(&gl, 0, sizeof(gl));
r = glob(arg2, GLOB_TILDE, NULL, &gl);
if (r == GLOB_NOMATCH) {
debug("%.200s line %d: include %s matched no "
"files",filename, linenum, arg2);
free(arg2);
continue;
} 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++) {
debug3("%.200s line %d: Including file %s "
"depth %d%s", filename, linenum,
gl.gl_pathv[i], depth,
oactive ? "" : " (parse only)");
r = read_config_file_depth(gl.gl_pathv[i],
pw, host, original_host, options,
flags | SSHCONF_CHECKPERM |
(oactive ? 0 : SSHCONF_NEVERMATCH),
activep, want_final_pass, depth + 1);
if (r != 1 && errno != ENOENT) {
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
* containing file's Match state.
*/
*activep = oactive;
if (r != 1)
value = -1;
}
globfree(&gl);
}
if (value != 0)
ret = value;
break;
case oIPQoS:
arg = argv_next(&ac, &av);
if ((value = parse_ipqos(arg)) == -1) {
error("%s line %d: Bad IPQoS value: %s",
filename, linenum, arg);
goto out;
}
arg = argv_next(&ac, &av);
if (arg == NULL)
value2 = value;
else if ((value2 = parse_ipqos(arg)) == -1) {
error("%s line %d: Bad IPQoS value: %s",
filename, linenum, arg);
goto out;
}
if (*activep && options->ip_qos_interactive == -1) {
options->ip_qos_interactive = value;
options->ip_qos_bulk = value2;
}
break;
case oRequestTTY:
intptr = &options->request_tty;
multistate_ptr = multistate_requesttty;
goto parse_multistate;
case oSessionType:
intptr = &options->session_type;
multistate_ptr = multistate_sessiontype;
goto parse_multistate;
case oStdinNull:
intptr = &options->stdin_null;
goto parse_flag;
case oForkAfterAuthentication:
intptr = &options->fork_after_authentication;
goto parse_flag;
case oVersionAddendum:
if (str == NULL)
fatal("%.200s line %d: Missing argument.", filename,
linenum);
len = strspn(str, WHITESPACE);
if (*activep && options->version_addendum == NULL) {
if (strcasecmp(str + len, "none") == 0)
options->version_addendum = xstrdup("");
else if (strchr(str + len, '\r') != NULL)
fatal("%.200s line %d: Invalid argument",
filename, linenum);
else
options->version_addendum = xstrdup(str + len);
}
return 0;
case oIgnoreUnknown:
charptr = &options->ignored_unknown;
goto parse_string;
case oProxyUseFdpass:
intptr = &options->proxy_use_fdpass;
goto parse_flag;
case oCanonicalDomains:
value = options->num_canonical_domains != 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)) {
error("%s line %d: %s", filename, linenum,
errstr);
goto out;
}
if (!*activep || value)
continue;
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);
}
break;
case oCanonicalizePermittedCNAMEs:
value = options->num_permitted_cnames != 0;
i = 0;
while ((arg = argv_next(&ac, &av)) != NULL) {
/*
* Either 'none' (only in first position), '*' for
* everything or 'list:list'
*/
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;
}
arg2 = "";
} else if (strcmp(arg, "*") == 0) {
arg2 = arg;
} else {
lowercase(arg);
if ((arg2 = strchr(arg, ':')) == NULL ||
arg2[1] == '\0') {
error("%s line %d: "
"Invalid permitted CNAME \"%s\"",
filename, linenum, arg);
goto out;
}
*arg2 = '\0';
arg2++;
}
i++;
if (!*activep || value)
continue;
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);
cname->target_list = xstrdup(arg2);
}
break;
case oCanonicalizeHostname:
intptr = &options->canonicalize_hostname;
multistate_ptr = multistate_canonicalizehostname;
goto parse_multistate;
case oCanonicalizeMaxDots:
intptr = &options->canonicalize_max_dots;
goto parse_int;
case oCanonicalizeFallbackLocal:
intptr = &options->canonicalize_fallback_local;
goto parse_flag;
case oStreamLocalBindMask:
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) {
error("%.200s line %d: Bad mask.", filename, linenum);
goto out;
}
options->fwd_opts.streamlocal_bind_mask = (mode_t)value;
break;
case oStreamLocalBindUnlink:
intptr = &options->fwd_opts.streamlocal_bind_unlink;
goto parse_flag;
case oRevokedHostKeys:
charptr = &options->revoked_host_keys;
goto parse_string;
case oFingerprintHash:
intptr = &options->fingerprint_hash;
arg = argv_next(&ac, &av);
if (!arg || *arg == '\0') {
error("%.200s line %d: Missing argument.",
filename, linenum);
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;
case oUpdateHostkeys:
intptr = &options->update_hostkeys;
multistate_ptr = multistate_yesnoask;
goto parse_multistate;
case oHostbasedAcceptedAlgorithms:
charptr = &options->hostbased_accepted_algos;
goto parse_pubkey_algos;
case oPubkeyAcceptedAlgorithms:
charptr = &options->pubkey_accepted_algos;
goto parse_pubkey_algos;
case oAddKeysToAgent:
arg = argv_next(&ac, &av);
arg2 = argv_next(&ac, &av);
value = parse_multistate_value(arg, filename, linenum,
multistate_yesnoaskconfirm);
value2 = 0; /* unlimited lifespan by default */
if (value == 3 && arg2 != NULL) {
/* allow "AddKeysToAgent confirm 5m" */
if ((value2 = convtime(arg2)) == -1 ||
value2 > INT_MAX) {
error("%s line %d: invalid time value.",
filename, linenum);
goto out;
}
} else if (value == -1 && arg2 == NULL) {
if ((value2 = convtime(arg)) == -1 ||
value2 > INT_MAX) {
error("%s line %d: unsupported option",
filename, linenum);
goto out;
}
value = 1; /* yes */
} else if (value == -1 || arg2 != NULL) {
error("%s line %d: unsupported option",
filename, linenum);
goto out;
}
if (*activep && options->add_keys_to_agent == -1) {
options->add_keys_to_agent = value;
options->add_keys_to_agent_lifespan = value2;
}
break;
case oIdentityAgent:
charptr = &options->identity_agent;
arg = 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) {
error("%.200s line %d: Invalid environment expansion "
"%s.", filename, linenum, arg);
goto out;
}
free(arg2);
/* check for legacy environment format */
if (arg[0] == '$' && arg[1] != '{' &&
!valid_env_name(arg + 1)) {
error("%.200s line %d: Invalid environment name %s.",
filename, linenum, arg);
goto out;
}
if (*activep && *charptr == NULL)
*charptr = xstrdup(arg);
break;
+ case oEnableEscapeCommandline:
+ intptr = &options->enable_escape_commandline;
+ goto parse_flag;
+
case oRequiredRSASize:
intptr = &options->required_rsa_size;
goto parse_int;
case oDeprecated:
debug("%s line %d: Deprecated option \"%s\"",
filename, linenum, keyword);
argv_consume(&ac);
break;
case oUnsupported:
error("%s line %d: Unsupported option \"%s\"",
filename, linenum, keyword);
argv_consume(&ac);
break;
default:
error("%s line %d: Unimplemented opcode %d",
filename, linenum, opcode);
goto out;
}
/* 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;
}
/*
* Reads the config file and modifies the options accordingly. Options
* should already be initialized before this call. This never returns if
* there is an error. If the file does not exist, this returns 0.
*/
int
read_config_file(const char *filename, struct passwd *pw, const char *host,
const char *original_host, Options *options, int flags,
int *want_final_pass)
{
int active = 1;
return read_config_file_depth(filename, pw, host, original_host,
options, flags, &active, want_final_pass, 0);
}
#define READCONF_MAX_DEPTH 16
static int
read_config_file_depth(const char *filename, struct passwd *pw,
const char *host, const char *original_host, Options *options,
int flags, int *activep, int *want_final_pass, int depth)
{
FILE *f;
char *line = NULL;
size_t linesize = 0;
int linenum;
int bad_options = 0;
if (depth < 0 || depth > READCONF_MAX_DEPTH)
fatal("Too many recursive configuration includes");
if ((f = fopen(filename, "r")) == NULL)
return 0;
if (flags & SSHCONF_CHECKPERM) {
struct stat sb;
if (fstat(fileno(f), &sb) == -1)
fatal("fstat %s: %s", filename, strerror(errno));
if (((sb.st_uid != 0 && sb.st_uid != getuid()) ||
(sb.st_mode & 022) != 0))
fatal("Bad owner or permissions on %s", filename);
}
debug("Reading configuration data %.200s", filename);
/*
* Mark that we are now processing the options. This flag is turned
* on/off by Host specifications.
*/
linenum = 0;
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)
bad_options++;
}
free(line);
fclose(f);
if (bad_options > 0)
fatal("%s: terminating, %d bad configuration options",
filename, bad_options);
return 1;
}
/* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */
int
option_clear_or_none(const char *o)
{
return o == NULL || strcasecmp(o, "none") == 0;
}
/*
* Returns 1 if CanonicalizePermittedCNAMEs have been specified, 0 otherwise.
* Allowed to be called on non-final configuration.
*/
int
config_has_permitted_cnames(Options *options)
{
if (options->num_permitted_cnames == 1 &&
strcasecmp(options->permitted_cnames[0].source_list, "none") == 0 &&
strcmp(options->permitted_cnames[0].target_list, "") == 0)
return 0;
return options->num_permitted_cnames > 0;
}
/*
* Initializes options to special values that indicate that they have not yet
* been set. Read_config_file will only set options with this value. Options
* are processed in the following order: command line, user config file,
* system config file. Last, fill_default_options is called.
*/
void
initialize_options(Options * options)
{
memset(options, 'X', sizeof(*options));
options->version_addendum = NULL;
+ options->host_arg = NULL;
options->forward_agent = -1;
options->forward_agent_sock_path = NULL;
options->forward_x11 = -1;
options->forward_x11_trusted = -1;
options->forward_x11_timeout = -1;
options->stdio_forward_host = NULL;
options->stdio_forward_port = 0;
options->clear_forwardings = -1;
options->exit_on_forward_failure = -1;
options->xauth_location = NULL;
options->fwd_opts.gateway_ports = -1;
options->fwd_opts.streamlocal_bind_mask = (mode_t)-1;
options->fwd_opts.streamlocal_bind_unlink = -1;
options->pubkey_authentication = -1;
options->gss_authentication = -1;
options->gss_deleg_creds = -1;
options->password_authentication = -1;
options->kbd_interactive_authentication = -1;
options->kbd_interactive_devices = NULL;
options->hostbased_authentication = -1;
options->batch_mode = -1;
options->check_host_ip = -1;
options->strict_host_key_checking = -1;
options->compression = -1;
options->tcp_keep_alive = -1;
options->port = -1;
options->address_family = -1;
options->connection_attempts = -1;
options->connection_timeout = -1;
options->number_of_password_prompts = -1;
options->ciphers = NULL;
options->macs = NULL;
options->kex_algorithms = NULL;
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;
options->jump_user = NULL;
options->jump_host = NULL;
options->jump_port = -1;
options->jump_extra = NULL;
options->user = NULL;
options->escape_char = -1;
options->num_system_hostfiles = 0;
options->num_user_hostfiles = 0;
options->local_forwards = NULL;
options->num_local_forwards = 0;
options->remote_forwards = NULL;
options->num_remote_forwards = 0;
options->permitted_remote_opens = NULL;
options->num_permitted_remote_opens = 0;
options->log_facility = SYSLOG_FACILITY_NOT_SET;
options->log_level = SYSLOG_LEVEL_NOT_SET;
options->num_log_verbose = 0;
options->log_verbose = NULL;
options->preferred_authentications = NULL;
options->bind_address = NULL;
options->bind_interface = NULL;
options->pkcs11_provider = NULL;
options->sk_provider = NULL;
options->enable_ssh_keysign = - 1;
options->no_host_authentication_for_localhost = - 1;
options->identities_only = - 1;
options->rekey_limit = - 1;
options->rekey_interval = -1;
options->verify_host_key_dns = -1;
options->server_alive_interval = -1;
options->server_alive_count_max = -1;
options->send_env = NULL;
options->num_send_env = 0;
options->setenv = NULL;
options->num_setenv = 0;
options->control_path = NULL;
options->control_master = -1;
options->control_persist = -1;
options->control_persist_timeout = 0;
options->hash_known_hosts = -1;
options->tun_open = -1;
options->tun_local = -1;
options->tun_remote = -1;
options->local_command = NULL;
options->permit_local_command = -1;
options->remote_command = NULL;
options->add_keys_to_agent = -1;
options->add_keys_to_agent_lifespan = -1;
options->identity_agent = NULL;
options->visual_host_key = -1;
options->ip_qos_interactive = -1;
options->ip_qos_bulk = -1;
options->request_tty = -1;
options->session_type = -1;
options->stdin_null = -1;
options->fork_after_authentication = -1;
options->proxy_use_fdpass = -1;
options->ignored_unknown = NULL;
options->num_canonical_domains = 0;
options->num_permitted_cnames = 0;
options->canonicalize_max_dots = -1;
options->canonicalize_fallback_local = -1;
options->canonicalize_hostname = -1;
options->revoked_host_keys = NULL;
options->fingerprint_hash = -1;
options->update_hostkeys = -1;
options->hostbased_accepted_algos = NULL;
options->pubkey_accepted_algos = NULL;
options->known_hosts_command = NULL;
options->required_rsa_size = -1;
+ options->enable_escape_commandline = -1;
}
/*
* A petite version of fill_default_options() that just fills the options
* needed for hostname canonicalization to proceed.
*/
void
fill_default_options_for_canonicalization(Options *options)
{
if (options->canonicalize_max_dots == -1)
options->canonicalize_max_dots = 1;
if (options->canonicalize_fallback_local == -1)
options->canonicalize_fallback_local = 1;
if (options->canonicalize_hostname == -1)
options->canonicalize_hostname = SSH_CANONICALISE_NO;
}
/*
* Called after processing other sources of option data, this fills those
* options for which no value has been specified with their default values.
*/
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 ret = 0, r;
if (options->forward_agent == -1)
options->forward_agent = 0;
if (options->forward_x11 == -1)
options->forward_x11 = 0;
if (options->forward_x11_trusted == -1)
options->forward_x11_trusted = 0;
if (options->forward_x11_timeout == -1)
options->forward_x11_timeout = 1200;
/*
* stdio forwarding (-W) changes the default for these but we defer
* setting the values so they can be overridden.
*/
if (options->exit_on_forward_failure == -1)
options->exit_on_forward_failure =
options->stdio_forward_host != NULL ? 1 : 0;
if (options->clear_forwardings == -1)
options->clear_forwardings =
options->stdio_forward_host != NULL ? 1 : 0;
if (options->clear_forwardings == 1)
clear_forwardings(options);
if (options->xauth_location == NULL)
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)
options->fwd_opts.streamlocal_bind_mask = 0177;
if (options->fwd_opts.streamlocal_bind_unlink == -1)
options->fwd_opts.streamlocal_bind_unlink = 0;
if (options->pubkey_authentication == -1)
options->pubkey_authentication = SSH_PUBKEY_AUTH_ALL;
if (options->gss_authentication == -1)
options->gss_authentication = 0;
if (options->gss_deleg_creds == -1)
options->gss_deleg_creds = 0;
if (options->password_authentication == -1)
options->password_authentication = 1;
if (options->kbd_interactive_authentication == -1)
options->kbd_interactive_authentication = 1;
if (options->hostbased_authentication == -1)
options->hostbased_authentication = 0;
if (options->batch_mode == -1)
options->batch_mode = 0;
if (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)
options->compression = 0;
if (options->tcp_keep_alive == -1)
options->tcp_keep_alive = 1;
if (options->port == -1)
options->port = 0; /* Filled in ssh_connect. */
if (options->address_family == -1)
options->address_family = AF_UNSPEC;
if (options->connection_attempts == -1)
options->connection_attempts = 1;
if (options->number_of_password_prompts == -1)
options->number_of_password_prompts = 3;
/* options->hostkeyalgorithms, default set in myproposals.h */
if (options->add_keys_to_agent == -1) {
options->add_keys_to_agent = 0;
options->add_keys_to_agent_lifespan = 0;
}
if (options->num_identity_files == 0) {
add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_RSA, 0);
#ifdef OPENSSL_HAS_ECC
add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_ECDSA, 0);
add_identity_file(options, "~/",
_PATH_SSH_CLIENT_ID_ECDSA_SK, 0);
#endif
add_identity_file(options, "~/",
_PATH_SSH_CLIENT_ID_ED25519, 0);
add_identity_file(options, "~/",
_PATH_SSH_CLIENT_ID_ED25519_SK, 0);
add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_XMSS, 0);
add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_DSA, 0);
}
if (options->escape_char == -1)
options->escape_char = '~';
if (options->num_system_hostfiles == 0) {
options->system_hostfiles[options->num_system_hostfiles++] =
xstrdup(_PATH_SSH_SYSTEM_HOSTFILE);
options->system_hostfiles[options->num_system_hostfiles++] =
xstrdup(_PATH_SSH_SYSTEM_HOSTFILE2);
}
if (options->update_hostkeys == -1) {
if (options->verify_host_key_dns <= 0 &&
(options->num_user_hostfiles == 0 ||
(options->num_user_hostfiles == 1 && strcmp(options->
user_hostfiles[0], _PATH_SSH_USER_HOSTFILE) == 0)))
options->update_hostkeys = SSH_UPDATE_HOSTKEYS_YES;
else
options->update_hostkeys = SSH_UPDATE_HOSTKEYS_NO;
}
if (options->num_user_hostfiles == 0) {
options->user_hostfiles[options->num_user_hostfiles++] =
xstrdup(_PATH_SSH_USER_HOSTFILE);
options->user_hostfiles[options->num_user_hostfiles++] =
xstrdup(_PATH_SSH_USER_HOSTFILE2);
}
if (options->log_level == SYSLOG_LEVEL_NOT_SET)
options->log_level = SYSLOG_LEVEL_INFO;
if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
options->log_facility = SYSLOG_FACILITY_USER;
if (options->no_host_authentication_for_localhost == - 1)
options->no_host_authentication_for_localhost = 0;
if (options->identities_only == -1)
options->identities_only = 0;
if (options->enable_ssh_keysign == -1)
options->enable_ssh_keysign = 0;
if (options->rekey_limit == -1)
options->rekey_limit = 0;
if (options->rekey_interval == -1)
options->rekey_interval = 0;
#if HAVE_LDNS
if (options->verify_host_key_dns == -1)
/* automatically trust a verified SSHFP record */
options->verify_host_key_dns = 1;
#else
if (options->verify_host_key_dns == -1)
options->verify_host_key_dns = 0;
#endif
if (options->server_alive_interval == -1)
options->server_alive_interval = 0;
if (options->server_alive_count_max == -1)
options->server_alive_count_max = 3;
if (options->control_master == -1)
options->control_master = 0;
if (options->control_persist == -1) {
options->control_persist = 0;
options->control_persist_timeout = 0;
}
if (options->hash_known_hosts == -1)
options->hash_known_hosts = 0;
if (options->tun_open == -1)
options->tun_open = SSH_TUNMODE_NO;
if (options->tun_local == -1)
options->tun_local = SSH_TUNID_ANY;
if (options->tun_remote == -1)
options->tun_remote = SSH_TUNID_ANY;
if (options->permit_local_command == -1)
options->permit_local_command = 0;
if (options->visual_host_key == -1)
options->visual_host_key = 0;
if (options->ip_qos_interactive == -1)
options->ip_qos_interactive = IPTOS_DSCP_AF21;
if (options->ip_qos_bulk == -1)
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)
options->canonicalize_max_dots = 1;
if (options->canonicalize_fallback_local == -1)
options->canonicalize_fallback_local = 1;
if (options->canonicalize_hostname == -1)
options->canonicalize_hostname = SSH_CANONICALISE_NO;
if (options->fingerprint_hash == -1)
options->fingerprint_hash = SSH_FP_HASH_DEFAULT;
#ifdef ENABLE_SK_INTERNAL
if (options->sk_provider == NULL)
options->sk_provider = xstrdup("internal");
#else
if (options->sk_provider == NULL)
options->sk_provider = xstrdup("$SSH_SK_PROVIDER");
#endif
if (options->required_rsa_size == -1)
options->required_rsa_size = SSH_RSA_MINIMUM_MODULUS_SIZE;
+ if (options->enable_escape_commandline == -1)
+ options->enable_escape_commandline = 0;
/* Expand KEX name lists */
all_cipher = cipher_alg_list(',', 0);
all_mac = mac_alg_list(',');
all_kex = kex_alg_list(',');
all_key = sshkey_alg_list(0, 0, 1, ',');
all_sig = sshkey_alg_list(0, 1, 1, ',');
/* remove unsupported algos from default lists */
def_cipher = match_filter_allowlist(KEX_CLIENT_ENCRYPT, all_cipher);
def_mac = match_filter_allowlist(KEX_CLIENT_MAC, all_mac);
def_kex = match_filter_allowlist(KEX_CLIENT_KEX, all_kex);
def_key = match_filter_allowlist(KEX_DEFAULT_PK_ALG, all_key);
def_sig = match_filter_allowlist(SSH_ALLOWED_CA_SIGALGS, all_sig);
#define ASSEMBLE(what, defaults, all) \
do { \
if ((r = kex_assemble_names(&options->what, \
defaults, all)) != 0) { \
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_accepted_algos, def_key, all_key);
ASSEMBLE(pubkey_accepted_algos, def_key, all_key);
ASSEMBLE(ca_sign_algorithms, def_sig, all_sig);
#undef ASSEMBLE
#define CLEAR_ON_NONE(v) \
do { \
if (option_clear_or_none(v)) { \
free(v); \
v = NULL; \
} \
} while(0)
CLEAR_ON_NONE(options->local_command);
CLEAR_ON_NONE(options->remote_command);
CLEAR_ON_NONE(options->proxy_command);
CLEAR_ON_NONE(options->control_path);
CLEAR_ON_NONE(options->revoked_host_keys);
CLEAR_ON_NONE(options->pkcs11_provider);
CLEAR_ON_NONE(options->sk_provider);
CLEAR_ON_NONE(options->known_hosts_command);
if (options->jump_host != NULL &&
strcmp(options->jump_host, "none") == 0 &&
options->jump_port == 0 && options->jump_user == NULL) {
free(options->jump_host);
options->jump_host = NULL;
}
if (options->num_permitted_cnames == 1 &&
!config_has_permitted_cnames(options)) {
/* clean up CanonicalizePermittedCNAMEs=none */
free(options->permitted_cnames[0].source_list);
free(options->permitted_cnames[0].target_list);
memset(options->permitted_cnames, '\0',
sizeof(*options->permitted_cnames));
options->num_permitted_cnames = 0;
}
/* options->identity_agent distinguishes NULL from 'none' */
/* options->user will be set in the main program if appropriate */
/* 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 */
if (options->version_addendum == NULL)
options->version_addendum = xstrdup(SSH_VERSION_FREEBSD);
/* success */
ret = 0;
fail:
free(all_cipher);
free(all_mac);
free(all_kex);
free(all_key);
free(all_sig);
free(def_cipher);
free(def_mac);
free(def_kex);
free(def_key);
free(def_sig);
return ret;
}
void
free_options(Options *o)
{
int i;
if (o == NULL)
return;
#define FREE_ARRAY(type, n, a) \
do { \
type _i; \
for (_i = 0; _i < (n); _i++) \
free((a)[_i]); \
} while (0)
free(o->forward_agent_sock_path);
free(o->xauth_location);
FREE_ARRAY(u_int, o->num_log_verbose, o->log_verbose);
free(o->log_verbose);
free(o->ciphers);
free(o->macs);
free(o->hostkeyalgorithms);
free(o->kex_algorithms);
free(o->ca_sign_algorithms);
free(o->hostname);
free(o->host_key_alias);
free(o->proxy_command);
free(o->user);
FREE_ARRAY(u_int, o->num_system_hostfiles, o->system_hostfiles);
FREE_ARRAY(u_int, o->num_user_hostfiles, o->user_hostfiles);
free(o->preferred_authentications);
free(o->bind_address);
free(o->bind_interface);
free(o->pkcs11_provider);
free(o->sk_provider);
for (i = 0; i < o->num_identity_files; i++) {
free(o->identity_files[i]);
sshkey_free(o->identity_keys[i]);
}
for (i = 0; i < o->num_certificate_files; i++) {
free(o->certificate_files[i]);
sshkey_free(o->certificates[i]);
}
free(o->identity_agent);
for (i = 0; i < o->num_local_forwards; i++) {
free(o->local_forwards[i].listen_host);
free(o->local_forwards[i].listen_path);
free(o->local_forwards[i].connect_host);
free(o->local_forwards[i].connect_path);
}
free(o->local_forwards);
for (i = 0; i < o->num_remote_forwards; i++) {
free(o->remote_forwards[i].listen_host);
free(o->remote_forwards[i].listen_path);
free(o->remote_forwards[i].connect_host);
free(o->remote_forwards[i].connect_path);
}
free(o->remote_forwards);
free(o->stdio_forward_host);
FREE_ARRAY(u_int, o->num_send_env, o->send_env);
free(o->send_env);
FREE_ARRAY(u_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 {
char *arg;
int ispath;
};
/*
* parse_fwd_field
* parses the next field in a port forwarding specification.
* sets fwd to the parsed field and advances p past the colon
* or sets it to NULL at end of string.
* returns 0 on success, else non-zero.
*/
static int
parse_fwd_field(char **p, struct fwdarg *fwd)
{
char *ep, *cp = *p;
int ispath = 0;
if (*cp == '\0') {
*p = NULL;
return -1; /* end of string */
}
/*
* A field escaped with square brackets is used literally.
* XXX - allow ']' to be escaped via backslash?
*/
if (*cp == '[') {
/* find matching ']' */
for (ep = cp + 1; *ep != ']' && *ep != '\0'; ep++) {
if (*ep == '/')
ispath = 1;
}
/* no matching ']' or not at end of field. */
if (ep[0] != ']' || (ep[1] != ':' && ep[1] != '\0'))
return -1;
/* NUL terminate the field and advance p past the colon */
*ep++ = '\0';
if (*ep != '\0')
*ep++ = '\0';
fwd->arg = cp + 1;
fwd->ispath = ispath;
*p = ep;
return 0;
}
for (cp = *p; *cp != '\0'; cp++) {
switch (*cp) {
case '\\':
memmove(cp, cp + 1, strlen(cp + 1) + 1);
if (*cp == '\0')
return -1;
break;
case '/':
ispath = 1;
break;
case ':':
*cp++ = '\0';
goto done;
}
}
done:
fwd->arg = *p;
fwd->ispath = ispath;
*p = cp;
return 0;
}
/*
* parse_forward
* parses a string containing a port forwarding specification of the form:
* dynamicfwd == 0
* [listenhost:]listenport|listenpath:connecthost:connectport|connectpath
* listenpath:connectpath
* dynamicfwd == 1
* [listenhost:]listenport
* returns number of arguments parsed or zero on error
*/
int
parse_forward(struct Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd)
{
struct fwdarg fwdargs[4];
char *p, *cp;
int i, err;
memset(fwd, 0, sizeof(*fwd));
memset(fwdargs, 0, sizeof(fwdargs));
/*
* We expand environment variables before checking if we think they're
* paths so that if ${VAR} expands to a fully qualified path it is
* treated as a path.
*/
cp = p = dollar_expand(&err, fwdspec);
if (p == NULL || err)
return 0;
/* skip leading spaces */
while (isspace((u_char)*cp))
cp++;
for (i = 0; i < 4; ++i) {
if (parse_fwd_field(&cp, &fwdargs[i]) != 0)
break;
}
/* Check for trailing garbage */
if (cp != NULL && *cp != '\0') {
i = 0; /* failure */
}
switch (i) {
case 1:
if (fwdargs[0].ispath) {
fwd->listen_path = xstrdup(fwdargs[0].arg);
fwd->listen_port = PORT_STREAMLOCAL;
} else {
fwd->listen_host = NULL;
fwd->listen_port = a2port(fwdargs[0].arg);
}
fwd->connect_host = xstrdup("socks");
break;
case 2:
if (fwdargs[0].ispath && fwdargs[1].ispath) {
fwd->listen_path = xstrdup(fwdargs[0].arg);
fwd->listen_port = PORT_STREAMLOCAL;
fwd->connect_path = xstrdup(fwdargs[1].arg);
fwd->connect_port = PORT_STREAMLOCAL;
} else if (fwdargs[1].ispath) {
fwd->listen_host = NULL;
fwd->listen_port = a2port(fwdargs[0].arg);
fwd->connect_path = xstrdup(fwdargs[1].arg);
fwd->connect_port = PORT_STREAMLOCAL;
} else {
fwd->listen_host = xstrdup(fwdargs[0].arg);
fwd->listen_port = a2port(fwdargs[1].arg);
fwd->connect_host = xstrdup("socks");
}
break;
case 3:
if (fwdargs[0].ispath) {
fwd->listen_path = xstrdup(fwdargs[0].arg);
fwd->listen_port = PORT_STREAMLOCAL;
fwd->connect_host = xstrdup(fwdargs[1].arg);
fwd->connect_port = a2port(fwdargs[2].arg);
} else if (fwdargs[2].ispath) {
fwd->listen_host = xstrdup(fwdargs[0].arg);
fwd->listen_port = a2port(fwdargs[1].arg);
fwd->connect_path = xstrdup(fwdargs[2].arg);
fwd->connect_port = PORT_STREAMLOCAL;
} else {
fwd->listen_host = NULL;
fwd->listen_port = a2port(fwdargs[0].arg);
fwd->connect_host = xstrdup(fwdargs[1].arg);
fwd->connect_port = a2port(fwdargs[2].arg);
}
break;
case 4:
fwd->listen_host = xstrdup(fwdargs[0].arg);
fwd->listen_port = a2port(fwdargs[1].arg);
fwd->connect_host = xstrdup(fwdargs[2].arg);
fwd->connect_port = a2port(fwdargs[3].arg);
break;
default:
i = 0; /* failure */
}
free(p);
if (dynamicfwd) {
if (!(i == 1 || i == 2))
goto fail_free;
} else {
if (!(i == 3 || i == 4)) {
if (fwd->connect_path == NULL &&
fwd->listen_path == NULL)
goto fail_free;
}
if (fwd->connect_port <= 0 && fwd->connect_path == NULL)
goto fail_free;
}
if ((fwd->listen_port < 0 && fwd->listen_path == NULL) ||
(!remotefwd && fwd->listen_port == 0))
goto fail_free;
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
*/
if (fwd->connect_path != NULL &&
strlen(fwd->connect_path) >= PATH_MAX_SUN)
goto fail_free;
if (fwd->listen_host != NULL &&
strlen(fwd->listen_host) >= NI_MAXHOST)
goto fail_free;
if (fwd->listen_path != NULL &&
strlen(fwd->listen_path) >= PATH_MAX_SUN)
goto fail_free;
return (i);
fail_free:
free(fwd->connect_host);
fwd->connect_host = NULL;
free(fwd->connect_path);
fwd->connect_path = NULL;
free(fwd->listen_host);
fwd->listen_host = NULL;
free(fwd->listen_path);
fwd->listen_path = NULL;
return (0);
}
int
parse_jump(const char *s, Options *o, int active)
{
char *orig, *sdup, *cp;
char *host = NULL, *user = NULL;
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)
break;
if ((cp = strrchr(sdup, ',')) == NULL)
cp = sdup; /* last */
else
*cp++ = '\0';
if (first) {
/* First argument and configuration is active */
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 */
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 */
} while (cp != sdup);
/* success */
if (active) {
if (strcasecmp(s, "none") == 0) {
o->jump_host = xstrdup("none");
o->jump_port = 0;
} else {
o->jump_user = user;
o->jump_host = host;
o->jump_port = port;
o->proxy_command = xstrdup("none");
user = host = NULL;
if ((cp = strrchr(s, ',')) != NULL && cp != s) {
o->jump_extra = xstrdup(s);
o->jump_extra[cp - s] = '\0';
}
}
}
ret = 0;
out:
free(orig);
free(user);
free(host);
return ret;
}
int
parse_ssh_uri(const char *uri, char **userp, char **hostp, int *portp)
{
char *user = NULL, *host = NULL, *path = NULL;
int r, port;
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;
}
/* XXX the following is a near-vebatim copy from servconf.c; refactor */
static const char *
fmt_multistate_int(int val, const struct multistate *m)
{
u_int i;
for (i = 0; m[i].key != NULL; i++) {
if (m[i].value == val)
return m[i].key;
}
return "UNKNOWN";
}
static const char *
fmt_intarg(OpCodes code, int val)
{
if (val == -1)
return "unset";
switch (code) {
case oAddressFamily:
return fmt_multistate_int(val, multistate_addressfamily);
case oVerifyHostKeyDNS:
case oUpdateHostkeys:
return fmt_multistate_int(val, multistate_yesnoask);
case oStrictHostKeyChecking:
return fmt_multistate_int(val, multistate_strict_hostkey);
case oControlMaster:
return fmt_multistate_int(val, multistate_controlmaster);
case oTunnel:
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:
return fmt_multistate_int(val, multistate_yesnoaskconfirm);
case oPubkeyAuthentication:
return fmt_multistate_int(val, multistate_pubkey_auth);
case oFingerprintHash:
return ssh_digest_alg_name(val);
default:
switch (val) {
case 0:
return "no";
case 1:
return "yes";
default:
return "UNKNOWN";
}
}
}
static const char *
lookup_opcode_name(OpCodes code)
{
u_int i;
for (i = 0; keywords[i].name != NULL; i++)
if (keywords[i].opcode == code)
return(keywords[i].name);
return "UNKNOWN";
}
static void
dump_cfg_int(OpCodes code, int val)
{
printf("%s %d\n", lookup_opcode_name(code), val);
}
static void
dump_cfg_fmtint(OpCodes code, int val)
{
printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val));
}
static void
dump_cfg_string(OpCodes code, const char *val)
{
if (val == NULL)
return;
printf("%s %s\n", lookup_opcode_name(code), val);
}
static void
dump_cfg_strarray(OpCodes code, u_int count, char **vals)
{
u_int i;
for (i = 0; i < count; i++)
printf("%s %s\n", lookup_opcode_name(code), vals[i]);
}
static void
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");
}
static void
dump_cfg_forwards(OpCodes code, u_int count, const struct Forward *fwds)
{
const struct Forward *fwd;
u_int i;
/* oDynamicForward */
for (i = 0; i < count; i++) {
fwd = &fwds[i];
if (code == oDynamicForward && fwd->connect_host != NULL &&
strcmp(fwd->connect_host, "socks") != 0)
continue;
if (code == oLocalForward && fwd->connect_host != NULL &&
strcmp(fwd->connect_host, "socks") == 0)
continue;
printf("%s", lookup_opcode_name(code));
if (fwd->listen_port == PORT_STREAMLOCAL)
printf(" %s", fwd->listen_path);
else if (fwd->listen_host == NULL)
printf(" %d", fwd->listen_port);
else {
printf(" [%s]:%d",
fwd->listen_host, fwd->listen_port);
}
if (code != oDynamicForward) {
if (fwd->connect_port == PORT_STREAMLOCAL)
printf(" %s", fwd->connect_path);
else if (fwd->connect_host == NULL)
printf(" %d", fwd->connect_port);
else {
printf(" [%s]:%d",
fwd->connect_host, fwd->connect_port);
}
}
printf("\n");
}
}
void
dump_client_config(Options *o, const char *host)
{
int i, r;
char buf[8], *all_key;
/*
* Expand HostKeyAlgorithms name lists. This isn't handled in
* fill_default_options() like the other algorithm lists because
* the host key algorithms are by default dynamically chosen based
* on the host's keys found in known_hosts.
*/
all_key = sshkey_alg_list(0, 0, 1, ',');
if ((r = kex_assemble_names(&o->hostkeyalgorithms, kex_default_pk_alg(),
all_key)) != 0)
fatal_fr(r, "expand HostKeyAlgorithms");
free(all_key);
/* Most interesting options first: user, host, port */
+ dump_cfg_string(oHost, o->host_arg);
dump_cfg_string(oUser, o->user);
dump_cfg_string(oHostname, host);
dump_cfg_int(oPort, o->port);
/* Flag options */
dump_cfg_fmtint(oAddressFamily, o->address_family);
dump_cfg_fmtint(oBatchMode, o->batch_mode);
dump_cfg_fmtint(oCanonicalizeFallbackLocal, o->canonicalize_fallback_local);
dump_cfg_fmtint(oCanonicalizeHostname, o->canonicalize_hostname);
dump_cfg_fmtint(oCheckHostIP, o->check_host_ip);
dump_cfg_fmtint(oCompression, o->compression);
dump_cfg_fmtint(oControlMaster, o->control_master);
dump_cfg_fmtint(oEnableSSHKeysign, o->enable_ssh_keysign);
dump_cfg_fmtint(oClearAllForwardings, o->clear_forwardings);
dump_cfg_fmtint(oExitOnForwardFailure, o->exit_on_forward_failure);
dump_cfg_fmtint(oFingerprintHash, o->fingerprint_hash);
dump_cfg_fmtint(oForwardX11, o->forward_x11);
dump_cfg_fmtint(oForwardX11Trusted, o->forward_x11_trusted);
dump_cfg_fmtint(oGatewayPorts, o->fwd_opts.gateway_ports);
#ifdef GSSAPI
dump_cfg_fmtint(oGssAuthentication, o->gss_authentication);
dump_cfg_fmtint(oGssDelegateCreds, o->gss_deleg_creds);
#endif /* GSSAPI */
dump_cfg_fmtint(oHashKnownHosts, o->hash_known_hosts);
dump_cfg_fmtint(oHostbasedAuthentication, o->hostbased_authentication);
dump_cfg_fmtint(oIdentitiesOnly, o->identities_only);
dump_cfg_fmtint(oKbdInteractiveAuthentication, o->kbd_interactive_authentication);
dump_cfg_fmtint(oNoHostAuthenticationForLocalhost, o->no_host_authentication_for_localhost);
dump_cfg_fmtint(oPasswordAuthentication, o->password_authentication);
dump_cfg_fmtint(oPermitLocalCommand, o->permit_local_command);
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);
dump_cfg_fmtint(oTunnel, o->tun_open);
dump_cfg_fmtint(oVerifyHostKeyDNS, o->verify_host_key_dns);
dump_cfg_fmtint(oVisualHostKey, o->visual_host_key);
dump_cfg_fmtint(oUpdateHostkeys, o->update_hostkeys);
+ dump_cfg_fmtint(oEnableEscapeCommandline, o->enable_escape_commandline);
/* Integer options */
dump_cfg_int(oCanonicalizeMaxDots, o->canonicalize_max_dots);
dump_cfg_int(oConnectionAttempts, o->connection_attempts);
dump_cfg_int(oForwardX11Timeout, o->forward_x11_timeout);
dump_cfg_int(oNumberOfPasswordPrompts, o->number_of_password_prompts);
dump_cfg_int(oServerAliveCountMax, o->server_alive_count_max);
dump_cfg_int(oServerAliveInterval, o->server_alive_interval);
dump_cfg_int(oRequiredRSASize, o->required_rsa_size);
/* String options */
dump_cfg_string(oBindAddress, o->bind_address);
dump_cfg_string(oBindInterface, o->bind_interface);
dump_cfg_string(oCiphers, o->ciphers);
dump_cfg_string(oControlPath, o->control_path);
dump_cfg_string(oHostKeyAlgorithms, o->hostkeyalgorithms);
dump_cfg_string(oHostKeyAlias, o->host_key_alias);
dump_cfg_string(oHostbasedAcceptedAlgorithms, o->hostbased_accepted_algos);
dump_cfg_string(oIdentityAgent, o->identity_agent);
dump_cfg_string(oIgnoreUnknown, o->ignored_unknown);
dump_cfg_string(oKbdInteractiveDevices, o->kbd_interactive_devices);
dump_cfg_string(oKexAlgorithms, o->kex_algorithms);
dump_cfg_string(oCASignatureAlgorithms, o->ca_sign_algorithms);
dump_cfg_string(oLocalCommand, o->local_command);
dump_cfg_string(oRemoteCommand, o->remote_command);
dump_cfg_string(oLogLevel, log_level_name(o->log_level));
dump_cfg_string(oMacs, o->macs);
#ifdef ENABLE_PKCS11
dump_cfg_string(oPKCS11Provider, o->pkcs11_provider);
#endif
dump_cfg_string(oSecurityKeyProvider, o->sk_provider);
dump_cfg_string(oPreferredAuthentications, o->preferred_authentications);
dump_cfg_string(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);
dump_cfg_forwards(oLocalForward, o->num_local_forwards, o->local_forwards);
dump_cfg_forwards(oRemoteForward, o->num_remote_forwards, o->remote_forwards);
/* String array options */
dump_cfg_strarray(oIdentityFile, o->num_identity_files, o->identity_files);
dump_cfg_strarray_oneline(oCanonicalDomains, o->num_canonical_domains, o->canonical_domains);
dump_cfg_strarray(oCertificateFile, o->num_certificate_files, o->certificate_files);
dump_cfg_strarray_oneline(oGlobalKnownHostsFile, o->num_system_hostfiles, o->system_hostfiles);
dump_cfg_strarray_oneline(oUserKnownHostsFile, o->num_user_hostfiles, o->user_hostfiles);
dump_cfg_strarray(oSendEnv, o->num_send_env, o->send_env);
dump_cfg_strarray(oSetEnv, o->num_setenv, o->setenv);
dump_cfg_strarray_oneline(oLogVerbose,
o->num_log_verbose, o->log_verbose);
/* Special cases */
/* PermitRemoteOpen */
if (o->num_permitted_remote_opens == 0)
printf("%s any\n", lookup_opcode_name(oPermitRemoteOpen));
else
dump_cfg_strarray_oneline(oPermitRemoteOpen,
o->num_permitted_remote_opens, o->permitted_remote_opens);
/* AddKeysToAgent */
if (o->add_keys_to_agent_lifespan <= 0)
dump_cfg_fmtint(oAddKeysToAgent, o->add_keys_to_agent);
else {
printf("addkeystoagent%s %d\n",
o->add_keys_to_agent == 3 ? " confirm" : "",
o->add_keys_to_agent_lifespan);
}
/* oForwardAgent */
if (o->forward_agent_sock_path == NULL)
dump_cfg_fmtint(oForwardAgent, o->forward_agent);
else
dump_cfg_string(oForwardAgent, o->forward_agent_sock_path);
/* oConnectTimeout */
if (o->connection_timeout == -1)
printf("connecttimeout none\n");
else
dump_cfg_int(oConnectTimeout, o->connection_timeout);
/* oTunnelDevice */
printf("tunneldevice");
if (o->tun_local == SSH_TUNID_ANY)
printf(" any");
else
printf(" %d", o->tun_local);
if (o->tun_remote == SSH_TUNID_ANY)
printf(":any");
else
printf(":%d", o->tun_remote);
printf("\n");
/* oCanonicalizePermittedCNAMEs */
printf("canonicalizePermittedcnames");
if (o->num_permitted_cnames == 0)
printf(" none");
for (i = 0; i < o->num_permitted_cnames; i++) {
printf(" %s:%s", o->permitted_cnames[i].source_list,
o->permitted_cnames[i].target_list);
}
printf("\n");
/* oControlPersist */
if (o->control_persist == 0 || o->control_persist_timeout == 0)
dump_cfg_fmtint(oControlPersist, o->control_persist);
else
dump_cfg_int(oControlPersist, o->control_persist_timeout);
/* oEscapeChar */
if (o->escape_char == SSH_ESCAPECHAR_NONE)
printf("escapechar none\n");
else {
vis(buf, o->escape_char, VIS_WHITE, 0);
printf("escapechar %s\n", buf);
}
/* oIPQoS */
printf("ipqos %s ", iptos2str(o->ip_qos_interactive));
printf("%s\n", iptos2str(o->ip_qos_bulk));
/* oRekeyLimit */
printf("rekeylimit %llu %d\n",
(unsigned long long)o->rekey_limit, o->rekey_interval);
/* oStreamLocalBindMask */
printf("streamlocalbindmask 0%o\n",
o->fwd_opts.streamlocal_bind_mask);
/* oLogFacility */
printf("syslogfacility %s\n", log_facility_name(o->log_facility));
/* oProxyCommand / oProxyJump */
if (o->jump_host == NULL)
dump_cfg_string(oProxyCommand, o->proxy_command);
else {
/* Check for numeric addresses */
i = strchr(o->jump_host, ':') != NULL ||
strspn(o->jump_host, "1234567890.") == strlen(o->jump_host);
snprintf(buf, sizeof(buf), "%d", o->jump_port);
printf("proxyjump %s%s%s%s%s%s%s%s%s\n",
/* optional additional jump spec */
o->jump_extra == NULL ? "" : o->jump_extra,
o->jump_extra == NULL ? "" : ",",
/* optional user */
o->jump_user == NULL ? "" : o->jump_user,
o->jump_user == NULL ? "" : "@",
/* opening [ if hostname is numeric */
i ? "[" : "",
/* mandatory hostname */
o->jump_host,
/* closing ] if hostname is numeric */
i ? "]" : "",
/* optional port number */
o->jump_port <= 0 ? "" : ":",
o->jump_port <= 0 ? "" : buf);
}
}
diff --git a/crypto/openssh/readconf.h b/crypto/openssh/readconf.h
index 43b8c635c72b..5dc9205bc5b0 100644
--- a/crypto/openssh/readconf.h
+++ b/crypto/openssh/readconf.h
@@ -1,248 +1,250 @@
-/* $OpenBSD: readconf.h,v 1.148 2022/09/17 10:33:18 djm Exp $ */
+/* $OpenBSD: readconf.h,v 1.150 2023/01/13 02:58:20 dtucker Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
* Functions for reading the configuration file.
*
* As far as I am concerned, the code I have written for this software
* can be used freely for any purpose. Any derived versions of this
* software must be clearly marked as such, and if the derived work is
* incompatible with the protocol description in the RFC file, it must be
* called by a name other than "ssh" or "Secure Shell".
*/
#ifndef READCONF_H
#define READCONF_H
/* Data structure for representing option data. */
#define SSH_MAX_HOSTS_FILES 32
#define MAX_CANON_DOMAINS 32
#define PATH_MAX_SUN (sizeof((struct sockaddr_un *)0)->sun_path)
struct allowed_cname {
char *source_list;
char *target_list;
};
typedef struct {
+ char *host_arg; /* Host arg as specified on command line. */
int forward_agent; /* Forward authentication agent. */
char *forward_agent_sock_path; /* Optional path of the agent. */
int forward_x11; /* Forward X11 display. */
int forward_x11_timeout; /* Expiration for Cookies */
int forward_x11_trusted; /* Trust Forward X11 display. */
int exit_on_forward_failure; /* Exit if bind(2) fails for -L/-R */
char *xauth_location; /* Location for xauth program */
struct ForwardOptions fwd_opts; /* forwarding options */
int pubkey_authentication; /* Try ssh2 pubkey authentication. */
int hostbased_authentication; /* ssh2's rhosts_rsa */
int gss_authentication; /* Try GSS authentication */
int gss_deleg_creds; /* Delegate GSS credentials */
int password_authentication; /* Try password
* authentication. */
int kbd_interactive_authentication; /* Try keyboard-interactive auth. */
char *kbd_interactive_devices; /* Keyboard-interactive auth devices. */
int batch_mode; /* Batch mode: do not ask for passwords. */
int check_host_ip; /* Also keep track of keys for IP address */
int strict_host_key_checking; /* Strict host key checking. */
int compression; /* Compress packets in both directions. */
int tcp_keep_alive; /* Set SO_KEEPALIVE. */
int ip_qos_interactive; /* IP ToS/DSCP/class for interactive */
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
* giving up */
int connection_timeout; /* Max time (seconds) before
* aborting connection attempt */
int number_of_password_prompts; /* Max number of password
* prompts. */
char *ciphers; /* SSH2 ciphers in order of preference. */
char *macs; /* SSH2 macs in order of preference. */
char *hostkeyalgorithms; /* SSH2 server key types in order of preference. */
char *kex_algorithms; /* SSH2 kex methods in order of preference. */
char *ca_sign_algorithms; /* Allowed CA signature algorithms */
char *hostname; /* Real host to connect. */
char *host_key_alias; /* hostname alias for .ssh/known_hosts */
char *proxy_command; /* Proxy command for connecting the host. */
char *user; /* User to log in as. */
int escape_char; /* Escape character; -2 = none */
u_int num_system_hostfiles; /* Paths for /etc/ssh/ssh_known_hosts */
char *system_hostfiles[SSH_MAX_HOSTS_FILES];
u_int num_user_hostfiles; /* Path for $HOME/.ssh/known_hosts */
char *user_hostfiles[SSH_MAX_HOSTS_FILES];
char *preferred_authentications;
char *bind_address; /* local socket address for connection to sshd */
char *bind_interface; /* local interface for bind address */
char *pkcs11_provider; /* PKCS#11 provider */
char *sk_provider; /* Security key provider */
int verify_host_key_dns; /* Verify host key using DNS */
int num_identity_files; /* Number of files for RSA/DSA identities. */
char *identity_files[SSH_MAX_IDENTITY_FILES];
int identity_file_userprovided[SSH_MAX_IDENTITY_FILES];
struct sshkey *identity_keys[SSH_MAX_IDENTITY_FILES];
int num_certificate_files; /* Number of extra certificates for ssh. */
char *certificate_files[SSH_MAX_CERTIFICATE_FILES];
int certificate_file_userprovided[SSH_MAX_CERTIFICATE_FILES];
struct sshkey *certificates[SSH_MAX_CERTIFICATE_FILES];
int add_keys_to_agent;
int add_keys_to_agent_lifespan;
char *identity_agent; /* Optional path to ssh-agent socket */
/* Local TCP/IP forward requests. */
int num_local_forwards;
struct Forward *local_forwards;
/* Remote TCP/IP forward requests. */
int num_remote_forwards;
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;
int enable_ssh_keysign;
int64_t rekey_limit;
int rekey_interval;
int no_host_authentication_for_localhost;
int identities_only;
int server_alive_interval;
int server_alive_count_max;
u_int num_send_env;
char **send_env;
u_int num_setenv;
char **setenv;
char *control_path;
int control_master;
int control_persist; /* ControlPersist flag */
int control_persist_timeout; /* ControlPersist timeout (seconds) */
int hash_known_hosts;
int tun_open; /* tun(4) */
int tun_local; /* force tun device (optional) */
int tun_remote; /* force tun device (optional) */
char *local_command;
int permit_local_command;
char *remote_command;
int visual_host_key;
int request_tty;
int session_type;
int stdin_null;
int fork_after_authentication;
int proxy_use_fdpass;
int num_canonical_domains;
char *canonical_domains[MAX_CANON_DOMAINS];
int canonicalize_hostname;
int canonicalize_max_dots;
int canonicalize_fallback_local;
int num_permitted_cnames;
struct allowed_cname permitted_cnames[MAX_CANON_DOMAINS];
char *revoked_host_keys;
int fingerprint_hash;
int update_hostkeys; /* one of SSH_UPDATE_HOSTKEYS_* */
char *hostbased_accepted_algos;
char *pubkey_accepted_algos;
char *version_addendum; /* Appended to SSH banner */
char *jump_user;
char *jump_host;
int jump_port;
char *jump_extra;
char *known_hosts_command;
int required_rsa_size; /* minimum size of RSA keys */
+ int enable_escape_commandline; /* ~C commandline */
char *ignored_unknown; /* Pattern list of unknown tokens to ignore */
} Options;
#define SSH_PUBKEY_AUTH_NO 0x00
#define SSH_PUBKEY_AUTH_UNBOUND 0x01
#define SSH_PUBKEY_AUTH_HBOUND 0x02
#define SSH_PUBKEY_AUTH_ALL 0x03
#define SSH_CANONICALISE_NO 0
#define SSH_CANONICALISE_YES 1
#define SSH_CANONICALISE_ALWAYS 2
#define SSHCTL_MASTER_NO 0
#define SSHCTL_MASTER_YES 1
#define SSHCTL_MASTER_AUTO 2
#define SSHCTL_MASTER_ASK 3
#define SSHCTL_MASTER_AUTO_ASK 4
#define REQUEST_TTY_AUTO 0
#define REQUEST_TTY_NO 1
#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. */
#define SSHCONF_NEVERMATCH 8 /* Match/Host never matches; internal only */
#define SSH_UPDATE_HOSTKEYS_NO 0
#define SSH_UPDATE_HOSTKEYS_YES 1
#define SSH_UPDATE_HOSTKEYS_ASK 2
#define SSH_STRICT_HOSTKEY_OFF 0
#define SSH_STRICT_HOSTKEY_NEW 1
#define SSH_STRICT_HOSTKEY_YES 2
#define SSH_STRICT_HOSTKEY_ASK 3
const char *kex_default_pk_alg(void);
char *ssh_connection_hash(const char *thishost, const char *host,
const char *portstr, const char *user);
void initialize_options(Options *);
int fill_default_options(Options *);
void fill_default_options_for_canonicalization(Options *);
void free_options(Options *o);
int process_config_line(Options *, struct passwd *, const char *,
const char *, char *, const char *, int, int *, int);
int read_config_file(const char *, struct passwd *, const char *,
const char *, Options *, int, int *);
int parse_forward(struct Forward *, const char *, int, int);
int parse_jump(const char *, Options *, int);
int parse_ssh_uri(const char *, char **, char **, int *);
int default_ssh_port(void);
int option_clear_or_none(const char *);
int config_has_permitted_cnames(Options *);
void dump_client_config(Options *o, const char *host);
void add_local_forward(Options *, const struct Forward *);
void add_remote_forward(Options *, const struct Forward *);
void add_identity_file(Options *, const char *, const char *, int);
void add_certificate_file(Options *, const char *, int);
#endif /* READCONF_H */
diff --git a/crypto/openssh/regress/Makefile b/crypto/openssh/regress/Makefile
index 0554c1ac9bc7..bf1d057aad33 100644
--- a/crypto/openssh/regress/Makefile
+++ b/crypto/openssh/regress/Makefile
@@ -1,275 +1,278 @@
-# $OpenBSD: Makefile,v 1.120 2022/01/06 21:46:56 dtucker Exp $
+# $OpenBSD: Makefile,v 1.122 2023/01/06 08:07:39 djm Exp $
tests: prep file-tests t-exec unit
REGRESS_TARGETS= t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t11 t12
# File based tests
file-tests: $(REGRESS_TARGETS)
# Interop tests are not run by default
interop interop-tests: t-exec-interop
prep:
test "x${USE_VALGRIND}" = "x" || mkdir -p $(OBJ)/valgrind-out
clean:
for F in $(CLEANFILES); do rm -f $(OBJ)$$F; done
rm -rf $(OBJ).putty
distclean: clean
LTESTS= connect \
proxy-connect \
sshfp-connect \
connect-privsep \
connect-uri \
proto-version \
proto-mismatch \
exit-status \
exit-status-signal \
envpass \
transfer \
banner \
rekey \
dhgex \
stderr-data \
stderr-after-eof \
broken-pipe \
try-ciphers \
yes-head \
login-timeout \
agent \
agent-getpeereid \
agent-timeout \
agent-ptrace \
agent-subprocess \
keyscan \
keygen-change \
keygen-comment \
keygen-convert \
keygen-knownhosts \
keygen-moduli \
keygen-sshfp \
key-options \
scp \
scp3 \
scp-uri \
sftp \
sftp-chroot \
sftp-cmds \
sftp-badcmds \
sftp-batch \
sftp-glob \
sftp-perm \
sftp-uri \
reconfigure \
dynamic-forward \
forwarding \
multiplex \
reexec \
brokenkeys \
sshcfgparse \
cfgparse \
cfgmatch \
cfgmatchlisten \
percent \
addrmatch \
localcommand \
forcecommand \
portnum \
keytype \
kextype \
cert-hostkey \
cert-userkey \
host-expand \
keys-command \
forward-control \
integrity \
krl \
multipubkey \
limit-keytype \
hostkey-agent \
hostkey-rotate \
principals-command \
cert-file \
cfginclude \
servcfginclude \
allow-deny-users \
authinfo \
sshsig \
knownhosts \
knownhosts-command \
agent-restrict \
- hostbased
+ hostbased \
+ channel-timeout \
+ connection-timeout
INTEROP_TESTS= putty-transfer putty-ciphers putty-kex conch-ciphers
#INTEROP_TESTS+=ssh-com ssh-com-client ssh-com-keygen ssh-com-sftp
EXTRA_TESTS= agent-pkcs11
#EXTRA_TESTS+= cipher-speed
USERNAME= ${LOGNAME}
CLEANFILES= *.core actual agent-key.* authorized_keys_${USERNAME} \
authorized_keys_${USERNAME}.* \
authorized_principals_${USERNAME} \
banner.in banner.out cert_host_key* cert_user_key* \
copy.1 copy.2 data ed25519-agent ed25519-agent* \
ed25519-agent.pub ed25519 ed25519.pub empty.in \
expect failed-regress.log failed-ssh.log failed-sshd.log \
hkr.* host.ecdsa-sha2-nistp256 host.ecdsa-sha2-nistp384 \
host.ecdsa-sha2-nistp521 host.ssh-dss host.ssh-ed25519 \
host.ssh-rsa host_ca_key* host_krl_* host_revoked_* key.* \
key.dsa-* key.ecdsa-* key.ed25519-512 \
key.ed25519-512.pub key.rsa-* keys-command-args kh.* askpass \
known_hosts known_hosts-cert known_hosts.* krl-* ls.copy \
modpipe netcat no_identity_config \
pidfile putty.rsa2 ready regress.log remote_pid \
revoked-* rsa rsa-agent rsa-agent.pub rsa.pub rsa_ssh2_cr.prv \
rsa_ssh2_crnl.prv scp-ssh-wrapper.exe \
scp-ssh-wrapper.scp setuid-allowed sftp-server.log \
sftp-server.sh sftp.log ssh-log-wrapper.sh ssh.log \
+ ssh-agent.log ssh-add.log slow-sftp-server.sh \
ssh-rsa_oldfmt knownhosts_command \
ssh_config ssh_config.* ssh_proxy ssh_proxy_bak \
ssh_proxy_* sshd.log sshd_config sshd_config.* \
sshd_config.* sshd_proxy sshd_proxy.* sshd_proxy_bak \
sshd_proxy_orig t10.out t10.out.pub t12.out t12.out.pub \
t2.out t3.out t6.out1 t6.out2 t7.out t7.out.pub \
t8.out t8.out.pub t9.out t9.out.pub testdata \
user_*key* user_ca* user_key*
# Enable all malloc(3) randomisations and checks
TEST_ENV= "MALLOC_OPTIONS=CFGJRSUX"
TEST_SSH_SSHKEYGEN?=ssh-keygen
CPPFLAGS=-I..
t1:
${TEST_SSH_SSHKEYGEN} -if ${.CURDIR}/rsa_ssh2.prv | diff - ${.CURDIR}/rsa_openssh.prv
tr '\n' '\r' <${.CURDIR}/rsa_ssh2.prv > ${.OBJDIR}/rsa_ssh2_cr.prv
${TEST_SSH_SSHKEYGEN} -if ${.OBJDIR}/rsa_ssh2_cr.prv | diff - ${.CURDIR}/rsa_openssh.prv
awk '{print $$0 "\r"}' ${.CURDIR}/rsa_ssh2.prv > ${.OBJDIR}/rsa_ssh2_crnl.prv
${TEST_SSH_SSHKEYGEN} -if ${.OBJDIR}/rsa_ssh2_crnl.prv | diff - ${.CURDIR}/rsa_openssh.prv
t2:
cat ${.CURDIR}/rsa_openssh.prv > $(OBJ)/t2.out
chmod 600 $(OBJ)/t2.out
${TEST_SSH_SSHKEYGEN} -yf $(OBJ)/t2.out | diff - ${.CURDIR}/rsa_openssh.pub
t3:
${TEST_SSH_SSHKEYGEN} -ef ${.CURDIR}/rsa_openssh.pub >$(OBJ)/t3.out
${TEST_SSH_SSHKEYGEN} -if $(OBJ)/t3.out | diff - ${.CURDIR}/rsa_openssh.pub
t4:
${TEST_SSH_SSHKEYGEN} -E md5 -lf ${.CURDIR}/rsa_openssh.pub |\
awk '{print $$2}' | diff - ${.CURDIR}/t4.ok
t5:
${TEST_SSH_SSHKEYGEN} -Bf ${.CURDIR}/rsa_openssh.pub |\
awk '{print $$2}' | diff - ${.CURDIR}/t5.ok
t6:
${TEST_SSH_SSHKEYGEN} -if ${.CURDIR}/dsa_ssh2.prv > $(OBJ)/t6.out1
${TEST_SSH_SSHKEYGEN} -if ${.CURDIR}/dsa_ssh2.pub > $(OBJ)/t6.out2
chmod 600 $(OBJ)/t6.out1
${TEST_SSH_SSHKEYGEN} -yf $(OBJ)/t6.out1 | diff - $(OBJ)/t6.out2
$(OBJ)/t7.out:
${TEST_SSH_SSHKEYGEN} -q -t rsa -N '' -f $@
t7: $(OBJ)/t7.out
${TEST_SSH_SSHKEYGEN} -lf $(OBJ)/t7.out > /dev/null
${TEST_SSH_SSHKEYGEN} -Bf $(OBJ)/t7.out > /dev/null
$(OBJ)/t8.out:
${TEST_SSH_SSHKEYGEN} -q -t dsa -N '' -f $@
t8: $(OBJ)/t8.out
${TEST_SSH_SSHKEYGEN} -lf $(OBJ)/t8.out > /dev/null
${TEST_SSH_SSHKEYGEN} -Bf $(OBJ)/t8.out > /dev/null
$(OBJ)/t9.out:
! ${TEST_SSH_SSH} -Q key-plain | grep ecdsa >/dev/null || \
${TEST_SSH_SSHKEYGEN} -q -t ecdsa -N '' -f $@
t9: $(OBJ)/t9.out
! ${TEST_SSH_SSH} -Q key-plain | grep ecdsa >/dev/null || \
${TEST_SSH_SSHKEYGEN} -lf $(OBJ)/t9.out > /dev/null
! ${TEST_SSH_SSH} -Q key-plain | grep ecdsa >/dev/null || \
${TEST_SSH_SSHKEYGEN} -Bf $(OBJ)/t9.out > /dev/null
$(OBJ)/t10.out:
${TEST_SSH_SSHKEYGEN} -q -t ed25519 -N '' -f $@
t10: $(OBJ)/t10.out
${TEST_SSH_SSHKEYGEN} -lf $(OBJ)/t10.out > /dev/null
${TEST_SSH_SSHKEYGEN} -Bf $(OBJ)/t10.out > /dev/null
t11:
${TEST_SSH_SSHKEYGEN} -E sha256 -lf ${.CURDIR}/rsa_openssh.pub |\
awk '{print $$2}' | diff - ${.CURDIR}/t11.ok
$(OBJ)/t12.out:
${TEST_SSH_SSHKEYGEN} -q -t ed25519 -N '' -C 'test-comment-1234' -f $@
t12: $(OBJ)/t12.out
${TEST_SSH_SSHKEYGEN} -lf $(OBJ)/t12.out.pub | grep test-comment-1234 >/dev/null
t-exec: ${LTESTS:=.sh}
@if [ "x$?" = "x" ]; then exit 0; fi; \
for TEST in ""$?; do \
skip=no; \
for t in ""$${SKIP_LTESTS}; do \
if [ "x$${t}.sh" = "x$${TEST}" ]; then skip=yes; fi; \
done; \
if [ "x$${skip}" = "xno" ]; then \
echo "run test $${TEST}" ... 1>&2; \
(env SUDO="${SUDO}" TEST_ENV=${TEST_ENV} ${TEST_SHELL} ${.CURDIR}/test-exec.sh ${.OBJDIR} ${.CURDIR}/$${TEST}) || exit $$?; \
else \
echo skip test $${TEST} 1>&2; \
fi; \
done
t-exec-interop: ${INTEROP_TESTS:=.sh}
@if [ "x$?" = "x" ]; then exit 0; fi; \
for TEST in ""$?; do \
echo "run test $${TEST}" ... 1>&2; \
(env SUDO="${SUDO}" TEST_ENV=${TEST_ENV} ${TEST_SHELL} ${.CURDIR}/test-exec.sh ${.OBJDIR} ${.CURDIR}/$${TEST}) || exit $$?; \
done
t-extra: ${EXTRA_TESTS:=.sh}
@if [ "x$?" = "x" ]; then exit 0; fi; \
for TEST in ""$?; do \
echo "run test $${TEST}" ... 1>&2; \
(env SUDO="${SUDO}" TEST_ENV=${TEST_ENV} ${TEST_SHELL} ${.CURDIR}/test-exec.sh ${.OBJDIR} ${.CURDIR}/$${TEST}) || exit $$?; \
done
# Not run by default
interop: ${INTEROP_TARGETS}
# Unit tests, built by top-level Makefile
unit:
set -e ; if test -z "${SKIP_UNIT}" ; then \
V="" ; \
test "x${USE_VALGRIND}" = "x" || \
V=${.CURDIR}/valgrind-unit.sh ; \
$$V ${.OBJDIR}/unittests/sshbuf/test_sshbuf ; \
$$V ${.OBJDIR}/unittests/sshkey/test_sshkey \
-d ${.CURDIR}/unittests/sshkey/testdata ; \
$$V ${.OBJDIR}/unittests/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 \
fi
diff --git a/crypto/openssh/regress/agent-getpeereid.sh b/crypto/openssh/regress/agent-getpeereid.sh
index b84471a78558..79e9c7d9e1c0 100644
--- a/crypto/openssh/regress/agent-getpeereid.sh
+++ b/crypto/openssh/regress/agent-getpeereid.sh
@@ -1,56 +1,59 @@
# $OpenBSD: agent-getpeereid.sh,v 1.13 2021/09/01 00:50:27 dtucker Exp $
# Placed in the Public Domain.
tid="disallow agent attach from other uid"
UNPRIV=nobody
ASOCK=${OBJ}/agent
SSH_AUTH_SOCK=/nonexistent
+>$OBJ/ssh-agent.log
+>$OBJ/ssh-add.log
if config_defined HAVE_GETPEEREID HAVE_GETPEERUCRED HAVE_SO_PEERCRED ; then
:
else
skip "skipped (not supported on this platform)"
fi
if test "x$USER" = "xroot"; then
skip "skipped (running as root)"
fi
case "x$SUDO" in
xsudo) sudo=1;;
xdoas|xdoas\ *) ;;
x)
skip "need SUDO to switch to uid $UNPRIV" ;;
*)
skip "unsupported $SUDO - "doas" and "sudo" are allowed" ;;
esac
trace "start agent"
-eval `${SSHAGENT} ${EXTRA_AGENT_ARGS} -s -a ${ASOCK}` > /dev/null
+eval `${SSHAGENT} ${EXTRA_AGENT_ARGS} -s -a ${ASOCK}` >$OBJ/ssh-agent.log 2>&1
r=$?
if [ $r -ne 0 ]; then
fail "could not start ssh-agent: exit code $r"
else
chmod 644 ${SSH_AUTH_SOCK}
- ${SSHADD} -l > /dev/null 2>&1
+ ${SSHADD} -vvv -l >>$OBJ/ssh-add.log 2>&1
r=$?
if [ $r -ne 1 ]; then
fail "ssh-add failed with $r != 1"
fi
if test -z "$sudo" ; then
# doas
${SUDO} -n -u ${UNPRIV} ${SSHADD} -l 2>/dev/null
else
# sudo
- < /dev/null ${SUDO} -S -u ${UNPRIV} ${SSHADD} -l 2>/dev/null
+ < /dev/null ${SUDO} -S -u ${UNPRIV} ${SSHADD} -vvv -l >>$OBJ/ssh-add.log 2>&1
fi
r=$?
if [ $r -lt 2 ]; then
fail "ssh-add did not fail for ${UNPRIV}: $r < 2"
+ cat $OBJ/ssh-add.log
fi
trace "kill agent"
- ${SSHAGENT} -k > /dev/null
+ ${SSHAGENT} -vvv -k >>$OBJ/ssh-agent.log 2>&1
fi
rm -f ${OBJ}/agent
diff --git a/crypto/openssh/regress/agent-ptrace.sh b/crypto/openssh/regress/agent-ptrace.sh
index feef52416f7c..df55b34a5b88 100644
--- a/crypto/openssh/regress/agent-ptrace.sh
+++ b/crypto/openssh/regress/agent-ptrace.sh
@@ -1,66 +1,67 @@
# $OpenBSD: agent-ptrace.sh,v 1.5 2022/04/22 05:08:43 anton Exp $
# Placed in the Public Domain.
tid="disallow agent ptrace attach"
if have_prog uname ; then
case `uname` in
AIX|CYGWIN*|OSF1)
echo "skipped (not supported on this platform)"
exit 0
;;
esac
fi
if [ "x$USER" = "xroot" ]; then
echo "Skipped: running as root"
exit 0
fi
if have_prog gdb ; then
: ok
else
echo "skipped (gdb not found)"
exit 0
fi
if $OBJ/setuid-allowed ${SSHAGENT} ; then
: ok
else
echo "skipped (${SSHAGENT} is mounted on a no-setuid filesystem)"
exit 0
fi
if test -z "$SUDO" ; then
echo "skipped (SUDO not set)"
exit 0
else
$SUDO chown 0 ${SSHAGENT}
$SUDO chgrp 0 ${SSHAGENT}
$SUDO chmod 2755 ${SSHAGENT}
+ trap "$SUDO chown ${USER} ${SSHAGENT}; $SUDO chmod 755 ${SSHAGENT}" 0
fi
trace "start agent"
eval `${SSHAGENT} ${EXTRA_AGENT_ARGS} -s` > /dev/null
r=$?
if [ $r -ne 0 ]; then
fail "could not start ssh-agent: exit code $r"
else
# ls -l ${SSH_AUTH_SOCK}
gdb ${SSHAGENT} ${SSH_AGENT_PID} > ${OBJ}/gdb.out 2>&1 << EOF
quit
EOF
r=$?
if [ $r -ne 0 ]; then
fail "gdb failed: exit code $r"
fi
egrep 'ptrace: Operation not permitted.|procfs:.*Permission denied.|ttrace.*Permission denied.|procfs:.*: Invalid argument.|Unable to access task ' >/dev/null ${OBJ}/gdb.out
r=$?
rm -f ${OBJ}/gdb.out
if [ $r -ne 0 ]; then
fail "ptrace succeeded?: exit code $r"
fi
trace "kill agent"
${SSHAGENT} -k > /dev/null
fi
diff --git a/crypto/openssh/regress/channel-timeout.sh b/crypto/openssh/regress/channel-timeout.sh
new file mode 100644
index 000000000000..1c42e832ae2c
--- /dev/null
+++ b/crypto/openssh/regress/channel-timeout.sh
@@ -0,0 +1,91 @@
+# $OpenBSD: channel-timeout.sh,v 1.1 2023/01/06 08:07:39 djm Exp $
+# Placed in the Public Domain.
+
+tid="channel timeout"
+
+# XXX not comprehensive. Still need -R -L agent X11 forwarding + interactive
+
+rm -f $OBJ/sshd_proxy.orig
+cp $OBJ/sshd_proxy $OBJ/sshd_proxy.orig
+
+verbose "no timeout"
+${SSH} -F $OBJ/ssh_proxy somehost "sleep 5 ; exit 23"
+r=$?
+if [ $r -ne 23 ]; then
+ fail "ssh failed"
+fi
+
+verbose "command timeout"
+(cat $OBJ/sshd_proxy.orig ; echo "ChannelTimeout session:command=1") \
+ > $OBJ/sshd_proxy
+${SSH} -F $OBJ/ssh_proxy somehost "sleep 5 ; exit 23"
+r=$?
+if [ $r -ne 255 ]; then
+ fail "ssh returned unexpected error code $r"
+fi
+
+verbose "command wildcard timeout"
+(cat $OBJ/sshd_proxy.orig ; echo "ChannelTimeout session:*=1") \
+ > $OBJ/sshd_proxy
+${SSH} -F $OBJ/ssh_proxy somehost "sleep 5 ; exit 23"
+r=$?
+if [ $r -ne 255 ]; then
+ fail "ssh returned unexpected error code $r"
+fi
+
+verbose "command irrelevant timeout"
+(cat $OBJ/sshd_proxy.orig ; echo "ChannelTimeout session:shell=1") \
+ > $OBJ/sshd_proxy
+${SSH} -F $OBJ/ssh_proxy somehost "sleep 5 ; exit 23"
+r=$?
+if [ $r -ne 23 ]; then
+ fail "ssh failed"
+fi
+
+# Set up a "slow sftp server" that sleeps before executing the real one.
+cat > $OBJ/slow-sftp-server.sh << _EOF
+#!/bin/sh
+
+sleep 5
+$SFTPSERVER
+_EOF
+chmod a+x $OBJ/slow-sftp-server.sh
+
+verbose "sftp no timeout"
+(grep -vi subsystem.*sftp $OBJ/sshd_proxy.orig;
+ echo "Subsystem sftp $OBJ/slow-sftp-server.sh" ) > $OBJ/sshd_proxy
+
+rm -f ${COPY}
+$SFTP -qS $SSH -F $OBJ/ssh_proxy somehost:$DATA $COPY
+r=$?
+if [ $r -ne 0 ]; then
+ fail "sftp failed"
+fi
+cmp $DATA $COPY || fail "corrupted copy"
+
+verbose "sftp timeout"
+(grep -vi subsystem.*sftp $OBJ/sshd_proxy.orig;
+ echo "ChannelTimeout session:subsystem:sftp=1" ;
+ echo "Subsystem sftp $OBJ/slow-sftp-server.sh" ) > $OBJ/sshd_proxy
+
+rm -f ${COPY}
+$SFTP -qS $SSH -F $OBJ/ssh_proxy somehost:$DATA $COPY
+r=$?
+if [ $r -eq 0 ]; then
+ fail "sftp succeeded unexpectedly"
+fi
+test -f $COPY && cmp $DATA $COPY && fail "intact copy"
+
+verbose "sftp irrelevant timeout"
+(grep -vi subsystem.*sftp $OBJ/sshd_proxy.orig;
+ echo "ChannelTimeout session:subsystem:command=1" ;
+ echo "Subsystem sftp $OBJ/slow-sftp-server.sh" ) > $OBJ/sshd_proxy
+
+rm -f ${COPY}
+$SFTP -qS $SSH -F $OBJ/ssh_proxy somehost:$DATA $COPY
+r=$?
+if [ $r -ne 0 ]; then
+ fail "sftp failed"
+fi
+cmp $DATA $COPY || fail "corrupted copy"
+
diff --git a/crypto/openssh/regress/connection-timeout.sh b/crypto/openssh/regress/connection-timeout.sh
new file mode 100644
index 000000000000..c77abb38d8d3
--- /dev/null
+++ b/crypto/openssh/regress/connection-timeout.sh
@@ -0,0 +1,87 @@
+# $OpenBSD: connection-timeout.sh,v 1.2 2023/01/17 10:15:10 djm Exp $
+# Placed in the Public Domain.
+
+tid="unused connection timeout"
+if config_defined DISABLE_FD_PASSING ; then
+ skip "not supported on this platform"
+fi
+
+CTL=$OBJ/ctl-sock
+cp $OBJ/sshd_proxy $OBJ/sshd_proxy.orig
+
+check_ssh() {
+ test -S $CTL || return 1
+ if ! ${REAL_SSH} -qF$OBJ/ssh_proxy -O check \
+ -oControlPath=$CTL somehost >/dev/null 2>&1 ; then
+ return 1
+ fi
+ return 0
+}
+
+start_ssh() {
+ trace "start ssh"
+ ${SSH} -nNfF $OBJ/ssh_proxy "$@" -oExitOnForwardFailure=yes \
+ -oControlMaster=yes -oControlPath=$CTL somehost
+ r=$?
+ test $r -eq 0 || fatal "failed to start ssh $r"
+ check_ssh || fatal "ssh process unresponsive"
+}
+
+stop_ssh() {
+ test -S $CTL || return
+ check_ssh || fatal "ssh process is unresponsive: cannot close"
+ if ! ${REAL_SSH} -qF$OBJ/ssh_proxy -O exit \
+ -oControlPath=$CTL >/dev/null somehost >/dev/null ; then
+ fatal "ssh process did not respond to close"
+ fi
+ n=0
+ while [ "$n" -lt 20 ] ; do
+ test -S $CTL || break
+ sleep 1
+ n=`expr $n + 1`
+ done
+ if test -S $CTL ; then
+ fatal "ssh process did not exit"
+ fi
+}
+
+trap "stop_ssh" EXIT
+
+verbose "no timeout"
+start_ssh
+sleep 5
+check_ssh || fatal "ssh unexpectedly missing"
+stop_ssh
+
+(cat $OBJ/sshd_proxy.orig ; echo "UnusedConnectionTimeout 2") > $OBJ/sshd_proxy
+
+verbose "timeout"
+start_ssh
+sleep 8
+check_ssh && fail "ssh unexpectedly present"
+stop_ssh
+
+verbose "session inhibits timeout"
+rm -f $OBJ/copy.1
+start_ssh
+${REAL_SSH} -qoControlPath=$CTL -oControlMaster=no -Fnone somehost \
+ "sleep 8; touch $OBJ/copy.1" &
+check_ssh || fail "ssh unexpectedly missing"
+wait
+test -f $OBJ/copy.1 || fail "missing result file"
+
+verbose "timeout after session"
+# Session should still be running from previous
+sleep 8
+check_ssh && fail "ssh unexpectedly present"
+stop_ssh
+
+LPORT=`expr $PORT + 1`
+RPORT=`expr $LPORT + 1`
+DPORT=`expr $RPORT + 1`
+RDPORT=`expr $DPORT + 1`
+verbose "timeout with listeners"
+start_ssh -L$LPORT:127.0.0.1:$PORT -R$RPORT:127.0.0.1:$PORT -D$DPORT -R$RDPORT
+sleep 8
+check_ssh && fail "ssh unexpectedly present"
+stop_ssh
diff --git a/crypto/openssh/regress/dynamic-forward.sh b/crypto/openssh/regress/dynamic-forward.sh
index 84f8ee19280a..5a4aa6d8e9f7 100644
--- a/crypto/openssh/regress/dynamic-forward.sh
+++ b/crypto/openssh/regress/dynamic-forward.sh
@@ -1,61 +1,110 @@
-# $OpenBSD: dynamic-forward.sh,v 1.13 2017/09/21 19:18:12 markus Exp $
+# $OpenBSD: dynamic-forward.sh,v 1.15 2023/01/06 08:50:33 dtucker Exp $
# Placed in the Public Domain.
tid="dynamic forwarding"
-FWDPORT=`expr $PORT + 1`
-
-if have_prog nc && nc -h 2>&1 | grep "proxy address" >/dev/null; then
- proxycmd="nc -x 127.0.0.1:$FWDPORT -X"
-elif have_prog connect; then
- proxycmd="connect -S 127.0.0.1:$FWDPORT -"
-else
- echo "skipped (no suitable ProxyCommand found)"
- exit 0
+# This is a reasonable proxy for IPv6 support.
+if ! config_defined HAVE_STRUCT_IN6_ADDR ; then
+ SKIP_IPV6=yes
fi
-trace "will use ProxyCommand $proxycmd"
-start_sshd
+FWDPORT=`expr $PORT + 1`
+make_tmpdir
+CTL=${SSH_REGRESS_TMP}/ctl-sock
+cp $OBJ/ssh_config $OBJ/ssh_config.orig
+proxycmd="$OBJ/netcat -x 127.0.0.1:$FWDPORT -X"
+trace "will use ProxyCommand $proxycmd"
-for d in D R; do
+start_ssh() {
+ direction="$1"
+ arg="$2"
n=0
error="1"
- trace "start dynamic forwarding, fork to background"
+ trace "start dynamic -$direction forwarding, fork to background"
+ (cat $OBJ/ssh_config.orig ; echo "$arg") > $OBJ/ssh_config
+ ${REAL_SSH} -vvvnNfF $OBJ/ssh_config -E$TEST_SSH_LOGFILE \
+ -$direction $FWDPORT -oExitOnForwardFailure=yes \
+ -oControlMaster=yes -oControlPath=$CTL somehost
+ r=$?
+ test $r -eq 0 || fatal "failed to start dynamic forwarding $r"
+ if ! ${REAL_SSH} -qF$OBJ/ssh_config -O check \
+ -oControlPath=$CTL somehost >/dev/null 2>&1 ; then
+ fatal "forwarding ssh process unresponsive"
+ fi
+}
- while [ "$error" -ne 0 -a "$n" -lt 3 ]; do
+stop_ssh() {
+ test -S $CTL || return
+ if ! ${REAL_SSH} -qF$OBJ/ssh_config -O exit \
+ -oControlPath=$CTL >/dev/null somehost >/dev/null ; then
+ fatal "forwarding ssh process did not respond to close"
+ fi
+ n=0
+ while [ "$n" -lt 20 ] ; do
+ test -S $CTL || break
+ sleep 1
n=`expr $n + 1`
- ${SSH} -F $OBJ/ssh_config -f -$d $FWDPORT -q \
- -oExitOnForwardFailure=yes somehost exec sh -c \
- \'"echo \$\$ > $OBJ/remote_pid; exec sleep 444"\'
- error=$?
- if [ "$error" -ne 0 ]; then
- trace "forward failed attempt $n err $error"
- sleep $n
- fi
done
- if [ "$error" -ne 0 ]; then
- fatal "failed to start dynamic forwarding"
+ if test -S $CTL ; then
+ fatal "forwarding ssh process did not exit"
fi
+}
+check_socks() {
+ direction=$1
+ expect_success=$2
for s in 4 5; do
for h in 127.0.0.1 localhost; do
- trace "testing ssh socks version $s host $h (-$d)"
- ${SSH} -F $OBJ/ssh_config \
- -o "ProxyCommand ${proxycmd}${s} $h $PORT" \
+ trace "testing ssh socks version $s host $h (-$direction)"
+ ${REAL_SSH} -q -F $OBJ/ssh_config \
+ -o "ProxyCommand ${proxycmd}${s} $h $PORT 2>/dev/null" \
somehost cat ${DATA} > ${COPY}
- test -f ${COPY} || fail "failed copy ${DATA}"
- cmp ${DATA} ${COPY} || fail "corrupted copy of ${DATA}"
+ r=$?
+ if [ "x$expect_success" = "xY" ] ; then
+ if [ $r -ne 0 ] ; then
+ fail "ssh failed with exit status $r"
+ fi
+ test -f ${COPY} || fail "failed copy ${DATA}"
+ cmp ${DATA} ${COPY} || fail "corrupted copy of ${DATA}"
+ elif [ $r -eq 0 ] ; then
+ fail "ssh unexpectedly succeeded"
+ fi
done
done
+}
- if [ -f $OBJ/remote_pid ]; then
- remote=`cat $OBJ/remote_pid`
- trace "terminate remote shell, pid $remote"
- if [ $remote -gt 1 ]; then
- kill -HUP $remote
- fi
- else
- fail "no pid file: $OBJ/remote_pid"
- fi
+start_sshd
+trap "stop_ssh" EXIT
+
+for d in D R; do
+ verbose "test -$d forwarding"
+ start_ssh $d
+ check_socks $d Y
+ stop_ssh
+ test "x$d" = "xR" || continue
+
+ # Test PermitRemoteOpen
+ verbose "PermitRemoteOpen=any"
+ start_ssh $d PermitRemoteOpen=any
+ check_socks $d Y
+ stop_ssh
+
+ verbose "PermitRemoteOpen=none"
+ start_ssh $d PermitRemoteOpen=none
+ check_socks $d N
+ stop_ssh
+
+ verbose "PermitRemoteOpen=explicit"
+ permit="127.0.0.1:$PORT [::1]:$PORT localhost:$PORT"
+ test -z "$SKIP_IPV6" || permit="127.0.0.1:$PORT localhost:$PORT"
+ start_ssh $d PermitRemoteOpen="$permit"
+ check_socks $d Y
+ stop_ssh
+ verbose "PermitRemoteOpen=disallowed"
+ permit="127.0.0.1:1 [::1]:1 localhost:1"
+ test -z "$SKIP_IPV6" || permit="127.0.0.1:1 localhost:1"
+ start_ssh $d PermitRemoteOpen="$permit"
+ check_socks $d N
+ stop_ssh
done
diff --git a/crypto/openssh/regress/hostbased.sh b/crypto/openssh/regress/hostbased.sh
index 04a1c1a2da45..eb9cf2727d33 100644
--- a/crypto/openssh/regress/hostbased.sh
+++ b/crypto/openssh/regress/hostbased.sh
@@ -1,66 +1,66 @@
-# $OpenBSD: hostbased.sh,v 1.3 2022/01/08 07:55:26 dtucker Exp $
+# $OpenBSD: hostbased.sh,v 1.4 2022/12/07 11:45:43 dtucker Exp $
# Placed in the Public Domain.
# This test requires external setup and thus is skipped unless
# TEST_SSH_HOSTBASED_AUTH and SUDO are set to "yes".
# Since ssh-keysign has key paths hard coded, unlike the other tests it
# needs to use the real host keys. It requires:
# - ssh-keysign must be installed and setuid.
# - "EnableSSHKeysign yes" must be in the system ssh_config.
# - the system's own real FQDN the system-wide shosts.equiv.
-# - the system's real public key fingerprints must me in global ssh_known_hosts.
+# - the system's real public key fingerprints must be in global ssh_known_hosts.
#
tid="hostbased"
if [ -z "${TEST_SSH_HOSTBASED_AUTH}" ]; then
skip "TEST_SSH_HOSTBASED_AUTH not set."
elif [ -z "${SUDO}" ]; then
skip "SUDO not set"
fi
# Enable all supported hostkey algos (but no others)
hostkeyalgos=`${SSH} -Q HostKeyAlgorithms | tr '\n' , | sed 's/,$//'`
cat >>$OBJ/sshd_proxy <<EOD
HostbasedAuthentication yes
HostbasedAcceptedAlgorithms $hostkeyalgos
HostbasedUsesNameFromPacketOnly yes
HostKeyAlgorithms $hostkeyalgos
EOD
cat >>$OBJ/ssh_proxy <<EOD
HostbasedAuthentication yes
HostKeyAlgorithms $hostkeyalgos
HostbasedAcceptedAlgorithms $hostkeyalgos
PreferredAuthentications hostbased
EOD
algos=""
for key in `${SUDO} ${SSHD} -T | awk '$1=="hostkey"{print $2}'`; do
case "`$SSHKEYGEN -l -f ${key}.pub`" in
256*ECDSA*) algos="$algos ecdsa-sha2-nistp256" ;;
384*ECDSA*) algos="$algos ecdsa-sha2-nistp384" ;;
521*ECDSA*) algos="$algos ecdsa-sha2-nistp521" ;;
*RSA*) algos="$algos ssh-rsa rsa-sha2-256 rsa-sha2-512" ;;
*ED25519*) algos="$algos ssh-ed25519" ;;
*DSA*) algos="$algos ssh-dss" ;;
*) verbose "unknown host key type $key" ;;
esac
done
for algo in $algos; do
trace "hostbased algo $algo"
opts="-F $OBJ/ssh_proxy"
if [ "x$algo" != "xdefault" ]; then
opts="$opts -oHostbasedAcceptedAlgorithms=$algo"
fi
SSH_CONNECTION=`${SSH} $opts localhost 'echo $SSH_CONNECTION'`
if [ $? -ne 0 ]; then
fail "connect failed, hostbased algo $algo"
elif [ "$SSH_CONNECTION" != "UNKNOWN 65535 UNKNOWN 65535" ]; then
fail "hostbased algo $algo bad SSH_CONNECTION" \
"$SSH_CONNECTION"
else
verbose "ok hostbased algo $algo"
fi
done
diff --git a/crypto/openssh/regress/krl.sh b/crypto/openssh/regress/krl.sh
index c381225ed7cd..d560d61e8ce1 100644
--- a/crypto/openssh/regress/krl.sh
+++ b/crypto/openssh/regress/krl.sh
@@ -1,217 +1,217 @@
-# $OpenBSD: krl.sh,v 1.11 2019/12/16 02:39:05 djm Exp $
+# $OpenBSD: krl.sh,v 1.12 2023/01/16 04:11:29 djm Exp $
# Placed in the Public Domain.
tid="key revocation lists"
# Use ed25519 by default since it's fast and it's supported when building
# w/out OpenSSL. Populate ktype[2-4] with the other types if supported.
ktype1=ed25519; ktype2=ed25519; ktype3=ed25519;
ktype4=ed25519; ktype5=ed25519; ktype6=ed25519;
for t in $SSH_KEYTYPES; do
case "$t" in
ecdsa*) ktype2=ecdsa ;;
ssh-rsa) ktype3=rsa ;;
ssh-dss) ktype4=dsa ;;
sk-ssh-ed25519@openssh.com) ktype5=ed25519-sk ;;
sk-ecdsa-sha2-nistp256@openssh.com) ktype6=ecdsa-sk ;;
esac
done
# Do most testing with ssh-keygen; it uses the same verification code as sshd.
# Old keys will interfere with ssh-keygen.
rm -f $OBJ/revoked-* $OBJ/krl-*
# Generate a CA key
$SSHKEYGEN -t $ktype1 -f $OBJ/revoked-ca -C "" -N "" > /dev/null ||
fatal "$SSHKEYGEN CA failed"
$SSHKEYGEN -t $ktype2 -f $OBJ/revoked-ca2 -C "" -N "" > /dev/null ||
fatal "$SSHKEYGEN CA2 failed"
# A specification that revokes some certificates by serial numbers
# The serial pattern is chosen to ensure the KRL includes list, range and
# bitmap sections.
cat << EOF >> $OBJ/revoked-serials
serial: 1-4
serial: 10
serial: 15
serial: 30
serial: 50
serial: 90
serial: 999
# The following sum to 500-799
serial: 500
serial: 501
serial: 502
serial: 503-600
serial: 700-797
serial: 798
serial: 799
serial: 599-701
# Some multiple consecutive serial number ranges
serial: 10000-20000
serial: 30000-40000
EOF
# A specification that revokes some certificated by key ID.
touch $OBJ/revoked-keyid
for n in 1 2 3 4 10 15 30 50 90 `jot 500 300` 999 1000 1001 1002; do
test "x$n" = "x499" && continue
# Fill in by-ID revocation spec.
echo "id: revoked $n" >> $OBJ/revoked-keyid
done
keygen() {
N=$1
f=$OBJ/revoked-`printf "%04d" $N`
# Vary the keytype. We use mostly ed25519 since this is fast and well
# supported.
keytype=$ktype1
case $N in
2 | 10 | 510 | 1001) keytype=$ktype2 ;;
4 | 30 | 520 | 1002) keytype=$ktype3 ;;
8 | 50 | 530 | 1003) keytype=$ktype4 ;;
16 | 70 | 540 | 1004) keytype=$ktype5 ;;
32 | 90 | 550 | 1005) keytype=$ktype6 ;;
esac
$SSHKEYGEN -t $keytype -f $f -C "" -N "" > /dev/null \
|| fatal "$SSHKEYGEN failed"
# Sign cert
$SSHKEYGEN -s $OBJ/revoked-ca -z $n -I "revoked $N" $f >/dev/null 2>&1 \
|| fatal "$SSHKEYGEN sign failed"
echo $f
}
# Generate some keys.
verbose "$tid: generating test keys"
REVOKED_SERIALS="1 4 10 50 90 500 510 520 550 799 999"
for n in $REVOKED_SERIALS ; do
f=`keygen $n`
RKEYS="$RKEYS ${f}.pub"
RCERTS="$RCERTS ${f}-cert.pub"
done
UNREVOKED_SERIALS="5 9 14 16 29 49 51 499 800 1010 1011"
UNREVOKED=""
for n in $UNREVOKED_SERIALS ; do
f=`keygen $n`
UKEYS="$UKEYS ${f}.pub"
UCERTS="$UCERTS ${f}-cert.pub"
done
# Specifications that revoke keys by hash.
touch $OBJ/revoked-sha1 $OBJ/revoked-sha256 $OBJ/revoked-hash
for rkey in $RKEYS; do
(printf "sha1: "; cat $rkey) >> $OBJ/revoked-sha1
(printf "sha256: "; cat $rkey) >> $OBJ/revoked-sha256
(printf "hash: "; $SSHKEYGEN -lf $rkey | \
awk '{ print $2 }') >> $OBJ/revoked-hash
done
genkrls() {
OPTS=$1
$SSHKEYGEN $OPTS -kf $OBJ/krl-empty - </dev/null \
>/dev/null || fatal "$SSHKEYGEN KRL failed"
$SSHKEYGEN $OPTS -kf $OBJ/krl-keys $RKEYS \
>/dev/null || fatal "$SSHKEYGEN KRL failed"
$SSHKEYGEN $OPTS -kf $OBJ/krl-cert $RCERTS \
>/dev/null || fatal "$SSHKEYGEN KRL failed"
$SSHKEYGEN $OPTS -kf $OBJ/krl-all $RKEYS $RCERTS \
>/dev/null || fatal "$SSHKEYGEN KRL failed"
$SSHKEYGEN $OPTS -kf $OBJ/krl-ca $OBJ/revoked-ca.pub \
>/dev/null || fatal "$SSHKEYGEN KRL failed"
$SSHKEYGEN $OPTS -kf $OBJ/krl-sha1 $OBJ/revoked-sha1 \
>/dev/null 2>&1 || fatal "$SSHKEYGEN KRL failed"
$SSHKEYGEN $OPTS -kf $OBJ/krl-sha256 $OBJ/revoked-sha256 \
>/dev/null 2>&1 || fatal "$SSHKEYGEN KRL failed"
$SSHKEYGEN $OPTS -kf $OBJ/krl-hash $OBJ/revoked-hash \
>/dev/null 2>&1 || fatal "$SSHKEYGEN KRL failed"
# This should fail as KRLs from serial/key-id spec need the CA specified.
$SSHKEYGEN $OPTS -kf $OBJ/krl-serial $OBJ/revoked-serials \
>/dev/null 2>&1 && fatal "$SSHKEYGEN KRL succeeded unexpectedly"
$SSHKEYGEN $OPTS -kf $OBJ/krl-keyid $OBJ/revoked-keyid \
>/dev/null 2>&1 && fatal "$SSHKEYGEN KRL succeeded unexpectedly"
# These should succeed; they specify an explicit CA key.
$SSHKEYGEN $OPTS -kf $OBJ/krl-serial -s $OBJ/revoked-ca \
$OBJ/revoked-serials >/dev/null || fatal "$SSHKEYGEN KRL failed"
$SSHKEYGEN $OPTS -kf $OBJ/krl-keyid -s $OBJ/revoked-ca.pub \
$OBJ/revoked-keyid >/dev/null || fatal "$SSHKEYGEN KRL failed"
# These should succeed; they specify an wildcard CA key.
$SSHKEYGEN $OPTS -kf $OBJ/krl-serial-wild -s NONE $OBJ/revoked-serials \
>/dev/null || fatal "$SSHKEYGEN KRL failed"
$SSHKEYGEN $OPTS -kf $OBJ/krl-keyid-wild -s NONE $OBJ/revoked-keyid \
>/dev/null || fatal "$SSHKEYGEN KRL failed"
# Revoke the same serials with the second CA key to ensure a multi-CA
# KRL is generated.
$SSHKEYGEN $OPTS -kf $OBJ/krl-serial -u -s $OBJ/revoked-ca2 \
$OBJ/revoked-serials >/dev/null || fatal "$SSHKEYGEN KRL failed"
}
## XXX dump with trace and grep for set cert serials
## XXX test ranges near (u64)-1, etc.
verbose "$tid: generating KRLs"
genkrls
check_krl() {
KEY=$1
KRL=$2
EXPECT_REVOKED=$3
TAG=$4
$SSHKEYGEN -Qf $KRL $KEY >/dev/null
result=$?
if test "x$EXPECT_REVOKED" = "xy" -a $result -eq 0 ; then
fatal "key $KEY not revoked by KRL $KRL: $TAG"
elif test "x$EXPECT_REVOKED" = "xn" -a $result -ne 0 ; then
fatal "key $KEY unexpectedly revoked by KRL $KRL: $TAG"
fi
}
test_rev() {
FILES=$1
TAG=$2
KEYS_RESULT=$3
ALL_RESULT=$4
HASH_RESULT=$5
SERIAL_RESULT=$6
KEYID_RESULT=$7
CERTS_RESULT=$8
CA_RESULT=$9
- SERIAL_WRESULT=$10
- KEYID_WRESULT=$11
+ SERIAL_WRESULT=${10}
+ KEYID_WRESULT=${11}
verbose "$tid: checking revocations for $TAG"
for f in $FILES ; do
check_krl $f $OBJ/krl-empty no "$TAG"
check_krl $f $OBJ/krl-keys $KEYS_RESULT "$TAG"
check_krl $f $OBJ/krl-all $ALL_RESULT "$TAG"
check_krl $f $OBJ/krl-sha1 $HASH_RESULT "$TAG"
check_krl $f $OBJ/krl-sha256 $HASH_RESULT "$TAG"
check_krl $f $OBJ/krl-hash $HASH_RESULT "$TAG"
check_krl $f $OBJ/krl-serial $SERIAL_RESULT "$TAG"
check_krl $f $OBJ/krl-keyid $KEYID_RESULT "$TAG"
check_krl $f $OBJ/krl-cert $CERTS_RESULT "$TAG"
check_krl $f $OBJ/krl-ca $CA_RESULT "$TAG"
check_krl $f $OBJ/krl-serial-wild $SERIAL_WRESULT "$TAG"
check_krl $f $OBJ/krl-keyid-wild $KEYID_WRESULT "$TAG"
done
}
test_all() {
# wildcard
# keys all hash sr# ID cert CA srl ID
test_rev "$RKEYS" "revoked keys" y y y n n n n n n
test_rev "$UKEYS" "unrevoked keys" n n n n n n n n n
test_rev "$RCERTS" "revoked certs" y y y y y y y y y
test_rev "$UCERTS" "unrevoked certs" n n n n n n y n n
}
test_all
# Check update. Results should be identical.
verbose "$tid: testing KRL update"
for f in $OBJ/krl-keys $OBJ/krl-cert $OBJ/krl-all \
$OBJ/krl-ca $OBJ/krl-serial $OBJ/krl-keyid \
$OBJ/krl-serial-wild $OBJ/krl-keyid-wild; do
cp -f $OBJ/krl-empty $f
genkrls -u
done
test_all
diff --git a/crypto/openssh/regress/multiplex.sh b/crypto/openssh/regress/multiplex.sh
index 2950d955aa3f..f9c8fc10bd14 100644
--- a/crypto/openssh/regress/multiplex.sh
+++ b/crypto/openssh/regress/multiplex.sh
@@ -1,209 +1,210 @@
-# $OpenBSD: multiplex.sh,v 1.34 2022/06/03 04:31:54 djm Exp $
+# $OpenBSD: multiplex.sh,v 1.35 2023/01/13 04:47:34 dtucker Exp $
# Placed in the Public Domain.
make_tmpdir
CTL=${SSH_REGRESS_TMP}/ctl-sock
tid="connection multiplexing"
trace "will use ProxyCommand $proxycmd"
if config_defined DISABLE_FD_PASSING ; then
echo "skipped (not supported on this platform)"
exit 0
fi
P=3301 # test port
wait_for_mux_master_ready()
{
for i in 1 2 3 4 5 6 7 8 9; do
${SSH} -F $OBJ/ssh_config -S $CTL -Ocheck otherhost \
>/dev/null 2>&1 && return 0
sleep $i
done
fatal "mux master never becomes ready"
}
+maybe_add_scp_path_to_sshd
start_sshd
start_mux_master()
{
trace "start master, fork to background"
${SSH} -Nn2 -MS$CTL -F $OBJ/ssh_config -oSendEnv="_XXX_TEST" somehost \
-E $TEST_REGRESS_LOGFILE 2>&1 &
# NB. $SSH_PID will be killed by test-exec.sh:cleanup on fatal errors.
SSH_PID=$!
wait_for_mux_master_ready
}
start_mux_master
verbose "test $tid: setenv"
trace "setenv over multiplexed connection"
_XXX_TEST=blah ${SSH} -F $OBJ/ssh_config -oSendEnv="_XXX_TEST" -S$CTL otherhost sh << 'EOF'
test X"$_XXX_TEST" = X"blah"
EOF
if [ $? -ne 0 ]; then
fail "environment not found"
fi
verbose "test $tid: envpass"
trace "env passing over multiplexed connection"
${SSH} -F $OBJ/ssh_config -oSetEnv="_XXX_TEST=foo" -S$CTL otherhost sh << 'EOF'
test X"$_XXX_TEST" = X"foo"
EOF
if [ $? -ne 0 ]; then
fail "environment not found"
fi
verbose "test $tid: transfer"
rm -f ${COPY}
trace "ssh transfer over multiplexed connection and check result"
${SSH} -F $OBJ/ssh_config -S$CTL otherhost cat ${DATA} > ${COPY}
test -f ${COPY} || fail "ssh -Sctl: failed copy ${DATA}"
cmp ${DATA} ${COPY} || fail "ssh -Sctl: corrupted copy of ${DATA}"
rm -f ${COPY}
trace "ssh transfer over multiplexed connection and check result"
${SSH} -F $OBJ/ssh_config -S $CTL otherhost cat ${DATA} > ${COPY}
test -f ${COPY} || fail "ssh -S ctl: failed copy ${DATA}"
cmp ${DATA} ${COPY} || fail "ssh -S ctl: corrupted copy of ${DATA}"
rm -f ${COPY}
trace "sftp transfer over multiplexed connection and check result"
echo "get ${DATA} ${COPY}" | \
${SFTP} -S ${SSH} -F $OBJ/ssh_config -oControlPath=$CTL otherhost >>$TEST_REGRESS_LOGFILE 2>&1
test -f ${COPY} || fail "sftp: failed copy ${DATA}"
cmp ${DATA} ${COPY} || fail "sftp: corrupted copy of ${DATA}"
rm -f ${COPY}
trace "scp transfer over multiplexed connection and check result"
${SCP} -S ${SSH} -F $OBJ/ssh_config -oControlPath=$CTL otherhost:${DATA} ${COPY} >>$TEST_REGRESS_LOGFILE 2>&1
test -f ${COPY} || fail "scp: failed copy ${DATA}"
cmp ${DATA} ${COPY} || fail "scp: corrupted copy of ${DATA}"
rm -f ${COPY}
verbose "test $tid: forward"
trace "forward over TCP/IP and check result"
$NC -N -l 127.0.0.1 $((${PORT} + 1)) < ${DATA} > /dev/null &
netcat_pid=$!
${SSH} -F $OBJ/ssh_config -S $CTL -Oforward -L127.0.0.1:$((${PORT} + 2)):127.0.0.1:$((${PORT} + 1)) otherhost >>$TEST_SSH_LOGFILE 2>&1
sleep 1 # XXX remove once race fixed
$NC 127.0.0.1 $((${PORT} + 2)) < /dev/null > ${COPY}
cmp ${DATA} ${COPY} || fail "ssh: corrupted copy of ${DATA}"
kill $netcat_pid 2>/dev/null
rm -f ${COPY} $OBJ/unix-[123].fwd
trace "forward over UNIX and check result"
$NC -N -Ul $OBJ/unix-1.fwd < ${DATA} > /dev/null &
netcat_pid=$!
${SSH} -F $OBJ/ssh_config -S $CTL -Oforward -L$OBJ/unix-2.fwd:$OBJ/unix-1.fwd otherhost >>$TEST_SSH_LOGFILE 2>&1
${SSH} -F $OBJ/ssh_config -S $CTL -Oforward -R$OBJ/unix-3.fwd:$OBJ/unix-2.fwd otherhost >>$TEST_SSH_LOGFILE 2>&1
sleep 1 # XXX remove once race fixed
$NC -U $OBJ/unix-3.fwd < /dev/null > ${COPY}
cmp ${DATA} ${COPY} || fail "ssh: corrupted copy of ${DATA}"
kill $netcat_pid 2>/dev/null
rm -f ${COPY} $OBJ/unix-[123].fwd
for s in 0 1 4 5 44; do
for mode in "" "-Oproxy"; do
trace "exit status $s over multiplexed connection ($mode)"
verbose "test $tid: status $s ($mode)"
${SSH} -F $OBJ/ssh_config -S $CTL $mode otherhost exit $s
r=$?
if [ $r -ne $s ]; then
fail "exit code mismatch: $r != $s"
fi
# same with early close of stdout/err
trace "exit status $s with early close over multiplexed connection ($mode)"
${SSH} -F $OBJ/ssh_config -S $CTL -n $mode otherhost \
exec sh -c \'"sleep 2; exec > /dev/null 2>&1; sleep 3; exit $s"\'
r=$?
if [ $r -ne $s ]; then
fail "exit code (with sleep) mismatch: $r != $s"
fi
done
done
verbose "test $tid: cmd check"
${SSH} -F $OBJ/ssh_config -S $CTL -Ocheck otherhost >>$TEST_REGRESS_LOGFILE 2>&1 \
|| fail "check command failed"
verbose "test $tid: cmd forward local (TCP)"
${SSH} -F $OBJ/ssh_config -S $CTL -Oforward -L $P:localhost:$PORT otherhost \
|| fail "request local forward failed"
sleep 1 # XXX remove once race fixed
${SSH} -F $OBJ/ssh_config -p$P otherhost true \
|| fail "connect to local forward port failed"
${SSH} -F $OBJ/ssh_config -S $CTL -Ocancel -L $P:localhost:$PORT otherhost \
|| fail "cancel local forward failed"
${SSH} -F $OBJ/ssh_config -p$P otherhost true \
&& fail "local forward port still listening"
verbose "test $tid: cmd forward remote (TCP)"
${SSH} -F $OBJ/ssh_config -S $CTL -Oforward -R $P:localhost:$PORT otherhost \
|| fail "request remote forward failed"
sleep 1 # XXX remove once race fixed
${SSH} -F $OBJ/ssh_config -p$P otherhost true \
|| fail "connect to remote forwarded port failed"
${SSH} -F $OBJ/ssh_config -S $CTL -Ocancel -R $P:localhost:$PORT otherhost \
|| fail "cancel remote forward failed"
${SSH} -F $OBJ/ssh_config -p$P otherhost true \
&& fail "remote forward port still listening"
verbose "test $tid: cmd forward local (UNIX)"
${SSH} -F $OBJ/ssh_config -S $CTL -Oforward -L $OBJ/unix-1.fwd:localhost:$PORT otherhost \
|| fail "request local forward failed"
sleep 1 # XXX remove once race fixed
echo "" | $NC -U $OBJ/unix-1.fwd | \
grep "Invalid SSH identification string" >/dev/null 2>&1 \
|| fail "connect to local forward path failed"
${SSH} -F $OBJ/ssh_config -S $CTL -Ocancel -L $OBJ/unix-1.fwd:localhost:$PORT otherhost \
|| fail "cancel local forward failed"
N=$(echo "xyzzy" | $NC -U $OBJ/unix-1.fwd 2>&1 | grep "xyzzy" | wc -l)
test ${N} -eq 0 || fail "local forward path still listening"
rm -f $OBJ/unix-1.fwd
verbose "test $tid: cmd forward remote (UNIX)"
${SSH} -F $OBJ/ssh_config -S $CTL -Oforward -R $OBJ/unix-1.fwd:localhost:$PORT otherhost \
|| fail "request remote forward failed"
sleep 1 # XXX remove once race fixed
echo "" | $NC -U $OBJ/unix-1.fwd | \
grep "Invalid SSH identification string" >/dev/null 2>&1 \
|| fail "connect to remote forwarded path failed"
${SSH} -F $OBJ/ssh_config -S $CTL -Ocancel -R $OBJ/unix-1.fwd:localhost:$PORT otherhost \
|| fail "cancel remote forward failed"
N=$(echo "xyzzy" | $NC -U $OBJ/unix-1.fwd 2>&1 | grep "xyzzy" | wc -l)
test ${N} -eq 0 || fail "remote forward path still listening"
rm -f $OBJ/unix-1.fwd
verbose "test $tid: cmd exit"
${SSH} -F $OBJ/ssh_config -S $CTL -Oexit otherhost >>$TEST_REGRESS_LOGFILE 2>&1 \
|| fail "send exit command failed"
# Wait for master to exit
wait $SSH_PID
kill -0 $SSH_PID >/dev/null 2>&1 && fail "exit command failed"
# Restart master and test -O stop command with master using -N
verbose "test $tid: cmd stop"
trace "restart master, fork to background"
start_mux_master
# start a long-running command then immediately request a stop
${SSH} -F $OBJ/ssh_config -S $CTL otherhost "sleep 10; exit 0" \
>>$TEST_REGRESS_LOGFILE 2>&1 &
SLEEP_PID=$!
${SSH} -F $OBJ/ssh_config -S $CTL -Ostop otherhost >>$TEST_REGRESS_LOGFILE 2>&1 \
|| fail "send stop command failed"
# wait until both long-running command and master have exited.
wait $SLEEP_PID
[ $! != 0 ] || fail "waiting for concurrent command"
wait $SSH_PID
[ $! != 0 ] || fail "waiting for master stop"
kill -0 $SSH_PID >/dev/null 2>&1 && fatal "stop command failed"
SSH_PID="" # Already gone, so don't kill in cleanup
diff --git a/crypto/openssh/regress/percent.sh b/crypto/openssh/regress/percent.sh
index bb81779a013d..3dfa8d2dfe08 100644
--- a/crypto/openssh/regress/percent.sh
+++ b/crypto/openssh/regress/percent.sh
@@ -1,120 +1,128 @@
-# $OpenBSD: percent.sh,v 1.14 2022/02/20 03:47:26 dtucker Exp $
+# $OpenBSD: percent.sh,v 1.16 2023/01/14 09:57:08 dtucker Exp $
# Placed in the Public Domain.
tid="percent expansions"
if [ -x "/usr/xpg4/bin/id" ]; then
PATH=/usr/xpg4/bin:$PATH
export PATH
fi
USER=`id -u -n`
USERID=`id -u`
HOST=`hostname | cut -f1 -d.`
HOSTNAME=`hostname`
+HASH=""
# Localcommand is evaluated after connection because %T is not available
# until then. Because of this we use a different method of exercising it,
# and we can't override the remote user otherwise authentication will fail.
# We also have to explicitly enable it.
echo "permitlocalcommand yes" >> $OBJ/ssh_proxy
trial()
{
opt="$1"; arg="$2"
expect=`echo "$3" | sed 's|^//|/|'` # approximate realpath
trace "test $opt=$arg $expect"
rm -f $OBJ/actual
got=""
case "$opt" in
localcommand)
${SSH} -F $OBJ/ssh_proxy -o $opt="echo '$arg' >$OBJ/actual" \
somehost true
got=`cat $OBJ/actual`
;;
userknownhostsfile)
# Move the userknownhosts file to what the expansion says,
# make sure ssh works then put it back.
mv "$OBJ/known_hosts" "$OBJ/$expect"
${SSH} -F $OBJ/ssh_proxy -o $opt="$OBJ/$arg" somehost true && \
got="$expect"
mv "$OBJ/$expect" "$OBJ/known_hosts"
;;
matchexec)
(cat $OBJ/ssh_proxy && \
echo "Match Exec \"echo '$arg' >$OBJ/actual\"") \
>$OBJ/ssh_proxy_match
${SSH} -F $OBJ/ssh_proxy_match remuser@somehost true || true
got=`cat $OBJ/actual`
;;
*forward)
# LocalForward and RemoteForward take two args and only
# operate on Unix domain socket paths
got=`${SSH} -F $OBJ/ssh_proxy -o $opt="/$arg /$arg" -G \
remuser@somehost | awk '$1=="'$opt'"{print $2" "$3}'`
expect="/$expect /$expect"
;;
*)
got=`${SSH} -F $OBJ/ssh_proxy -o $opt="$arg" -G \
remuser@somehost | awk '$1=="'$opt'"{print $2}'`
esac
if [ "$got" != "$expect" ]; then
fail "$opt=$arg expect $expect got $got"
fi
}
for i in matchexec localcommand remotecommand controlpath identityagent \
forwardagent localforward remoteforward userknownhostsfile; do
verbose $tid $i percent
case "$i" in
localcommand|userknownhostsfile)
# Any test that's going to actually make a connection needs
# to use the real username.
REMUSER=$USER ;;
*)
REMUSER=remuser ;;
esac
if [ "$i" = "$localcommand" ]; then
trial $i '%T' NONE
fi
# Matches implementation in readconf.c:ssh_connection_hash()
- HASH=`printf "${HOSTNAME}127.0.0.1${PORT}$REMUSER" |
- $OPENSSL_BIN sha1 | cut -f2 -d' '`
+ if [ ! -z "${OPENSSL_BIN}" ]; then
+ HASH=`printf "${HOSTNAME}127.0.0.1${PORT}$REMUSER" |
+ $OPENSSL_BIN sha1 | cut -f2 -d' '`
+ trial $i '%C' $HASH
+ fi
trial $i '%%' '%'
- trial $i '%C' $HASH
trial $i '%i' $USERID
trial $i '%h' 127.0.0.1
trial $i '%L' $HOST
trial $i '%l' $HOSTNAME
trial $i '%n' somehost
trial $i '%k' localhost-with-alias
trial $i '%p' $PORT
trial $i '%r' $REMUSER
trial $i '%u' $USER
# We can't specify a full path outside the regress dir, so skip tests
# containing %d for UserKnownHostsFile
if [ "$i" != "userknownhostsfile" ]; then
trial $i '%d' $HOME
- trial $i '%%/%C/%i/%h/%d/%L/%l/%n/%p/%r/%u' \
- "%/$HASH/$USERID/127.0.0.1/$HOME/$HOST/$HOSTNAME/somehost/$PORT/$REMUSER/$USER"
+ in='%%/%i/%h/%d/%L/%l/%n/%p/%r/%u'
+ out="%/$USERID/127.0.0.1/$HOME/$HOST/$HOSTNAME/somehost/$PORT/$REMUSER/$USER"
+ if [ ! -z "${HASH}" ]; then
+ in="$in/%C"
+ out="$out/$HASH"
+ fi
+ trial $i "$in" "$out"
fi
done
# Subset of above since we don't expand shell-style variables on anything that
# runs a command because the shell will expand those.
for i in controlpath identityagent forwardagent localforward remoteforward \
userknownhostsfile; do
verbose $tid $i dollar
FOO=bar
export FOO
trial $i '${FOO}' $FOO
done
# A subset of options support tilde expansion
for i in controlpath identityagent forwardagent; do
verbose $tid $i tilde
trial $i '~' $HOME/
trial $i '~/.ssh' $HOME/.ssh
done
diff --git a/crypto/openssh/regress/reexec.sh b/crypto/openssh/regress/reexec.sh
index 8966ba524e60..3f88d41f534c 100644
--- a/crypto/openssh/regress/reexec.sh
+++ b/crypto/openssh/regress/reexec.sh
@@ -1,57 +1,57 @@
-# $OpenBSD: reexec.sh,v 1.12 2017/08/07 03:52:55 dtucker Exp $
+# $OpenBSD: reexec.sh,v 1.13 2023/01/19 07:53:45 dtucker Exp $
# Placed in the Public Domain.
tid="reexec tests"
SSHD_ORIG=$SSHD
SSHD_COPY=$OBJ/sshd
# Start a sshd and then delete it
start_sshd_copy ()
{
# NB. prefer ln to cp here. On some OSX 19.4 configurations,
# djm has seen failure after fork() when the executable image
# has been removed from the filesystem.
ln $SSHD_ORIG $SSHD_COPY || cp $SSHD_ORIG $SSHD_COPY
SSHD=$SSHD_COPY
start_sshd
SSHD=$SSHD_ORIG
}
# Do basic copy tests
copy_tests ()
{
rm -f ${COPY}
${SSH} -nq -F $OBJ/ssh_config somehost \
cat ${DATA} > ${COPY}
if [ $? -ne 0 ]; then
fail "ssh cat $DATA failed"
fi
cmp ${DATA} ${COPY} || fail "corrupted copy"
rm -f ${COPY}
}
verbose "test config passing"
cp $OBJ/sshd_config $OBJ/sshd_config.orig
start_sshd
echo "InvalidXXX=no" >> $OBJ/sshd_config
copy_tests
stop_sshd
cp $OBJ/sshd_config.orig $OBJ/sshd_config
# cygwin can't fork a deleted binary
if [ "$os" != "cygwin" ]; then
verbose "test reexec fallback"
start_sshd_copy
-rm -f $SSHD_COPY
+$SUDO rm -f $SSHD_COPY
copy_tests
stop_sshd
fi
diff --git a/crypto/openssh/regress/scp-uri.sh b/crypto/openssh/regress/scp-uri.sh
index 20ac3c89ec26..eacbd453afdd 100644
--- a/crypto/openssh/regress/scp-uri.sh
+++ b/crypto/openssh/regress/scp-uri.sh
@@ -1,77 +1,79 @@
-# $OpenBSD: scp-uri.sh,v 1.4 2021/08/10 03:35:45 djm Exp $
+# $OpenBSD: scp-uri.sh,v 1.5 2023/01/13 04:47:34 dtucker Exp $
# Placed in the Public Domain.
tid="scp-uri"
#set -x
COPY2=${OBJ}/copy2
DIR=${COPY}.dd
DIR2=${COPY}.dd2
+maybe_add_scp_path_to_sshd
+
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}
}
# Remove Port and User from ssh_config, we want to rely on the URI
cp $OBJ/ssh_config $OBJ/ssh_config.orig
egrep -v '^ +(Port|User) +.*$' $OBJ/ssh_config.orig > $OBJ/ssh_config
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 "$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 "$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 "$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 "$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 "$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
done
scpclean
rm -f ${OBJ}/scp-ssh-wrapper.exe
diff --git a/crypto/openssh/regress/scp.sh b/crypto/openssh/regress/scp.sh
index f47c594572fd..76c2b2a6bb56 100644
--- a/crypto/openssh/regress/scp.sh
+++ b/crypto/openssh/regress/scp.sh
@@ -1,168 +1,195 @@
-# $OpenBSD: scp.sh,v 1.14 2022/05/15 23:48:07 djm Exp $
+# $OpenBSD: scp.sh,v 1.18 2023/01/13 04:47:34 dtucker Exp $
# Placed in the Public Domain.
tid="scp"
#set -x
-# Figure out if diff understands "-N"
-if diff -N ${SRC}/scp.sh ${SRC}/scp.sh 2>/dev/null; then
- DIFFOPT="-rN"
-else
- DIFFOPT="-r"
-fi
-
COPY2=${OBJ}/copy2
DIR=${COPY}.dd
DIR2=${COPY}.dd2
+COPY3=${OBJ}/copy.glob[123]
+DIR3=${COPY}.dd.glob[456]
+DIFFOPT="-rN"
+
+# Figure out if diff does not understand "-N"
+if ! diff -N ${SRC}/scp.sh ${SRC}/scp.sh 2>/dev/null; then
+ DIFFOPT="-r"
+fi
+
+maybe_add_scp_path_to_sshd
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}
+ rm -rf ${COPY} ${COPY2} ${DIR} ${DIR2} ${COPY3} ${DIR3}
+ mkdir ${DIR} ${DIR2} ${DIR3}
+ chmod 755 ${DIR} ${DIR2} ${DIR3}
}
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"
+ verbose "$tag: simple copy local file to local file"
scpclean
$SCP $scpopts ${DATA} ${COPY} || fail "copy failed"
cmp ${DATA} ${COPY} || fail "corrupted copy"
verbose "$tag: simple copy local file to remote file"
scpclean
$SCP $scpopts ${DATA} somehost:${COPY} || fail "copy failed"
cmp ${DATA} ${COPY} || fail "corrupted copy"
verbose "$tag: simple copy remote file to local file"
scpclean
$SCP $scpopts somehost:${DATA} ${COPY} || fail "copy failed"
cmp ${DATA} ${COPY} || fail "corrupted copy"
verbose "$tag: copy local file to remote file in place"
scpclean
cp ${DATA} ${COPY}
$SCP $scpopts ${COPY} somehost:${COPY} || fail "copy failed"
cmp ${DATA} ${COPY} || fail "corrupted copy"
verbose "$tag: copy remote file to local file in place"
scpclean
cp ${DATA} ${COPY}
$SCP $scpopts somehost:${COPY} ${COPY} || fail "copy failed"
cmp ${DATA} ${COPY} || fail "corrupted copy"
verbose "$tag: copy local file to remote file clobber"
scpclean
cat ${DATA} ${DATA} > ${COPY}
$SCP $scpopts ${DATA} somehost:${COPY} || fail "copy failed"
ls -l $DATA $COPY
cmp ${DATA} ${COPY} || fail "corrupted copy"
verbose "$tag: copy remote file to local file clobber"
scpclean
cat ${DATA} ${DATA} > ${COPY}
$SCP $scpopts somehost:${DATA} ${COPY} || fail "copy failed"
cmp ${DATA} ${COPY} || 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 "$tag: simple copy local file to local dir"
scpclean
cp ${DATA} ${COPY}
$SCP $scpopts ${COPY} ${DIR} || fail "copy failed"
cmp ${COPY} ${DIR}/copy || fail "corrupted copy"
verbose "$tag: simple copy remote file to local dir"
scpclean
cp ${DATA} ${COPY}
$SCP $scpopts somehost:${COPY} ${DIR} || fail "copy failed"
cmp ${COPY} ${DIR}/copy || fail "corrupted copy"
verbose "$tag: recursive local dir to remote dir"
scpclean
rm -rf ${DIR2}
cp ${DATA} ${DIR}/copy
$SCP $scpopts -r ${DIR} somehost:${DIR2} || fail "copy failed"
diff ${DIFFOPT} ${DIR} ${DIR2} || fail "corrupted copy"
verbose "$tag: 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: 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: unmatched glob file local->remote"
+ scpclean
+ $SCP $scpopts ${DATA} somehost:${COPY3} || fail "copy failed"
+ cmp ${DATA} ${COPY3} || fail "corrupted copy"
+
+ verbose "$tag: unmatched glob file remote->local"
+ # NB. no clean
+ $SCP $scpopts somehost:${COPY3} ${COPY2} || fail "copy failed"
+ cmp ${DATA} ${COPY2} || fail "corrupted copy"
+
+ verbose "$tag: unmatched glob dir recursive local->remote"
+ scpclean
+ rm -rf ${DIR3}
+ cp ${DATA} ${DIR}/copy
+ cp ${DATA} ${DIR}/copy.glob[1234]
+ $SCP $scpopts -r ${DIR} somehost:${DIR3} || fail "copy failed"
+ diff ${DIFFOPT} ${DIR} ${DIR3} || fail "corrupted copy"
+
+ verbose "$tag: unmatched glob dir recursive remote->local"
+ # NB. no clean
+ rm -rf ${DIR2}
+ $SCP $scpopts -r somehost:${DIR3} ${DIR2} || fail "copy failed"
+ diff ${DIFFOPT} ${DIR} ${DIR2} || fail "corrupted copy"
+
verbose "$tag: shell metacharacters"
scpclean
(cd ${DIR} && \
touch '`touch metachartest`' && \
$SCP $scpopts *metachar* ${DIR2} 2>/dev/null; \
[ ! -f metachartest ] ) || fail "shell metacharacters"
if [ ! -z "$SUDO" ]; then
verbose "$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
scpclean
rm -f ${OBJ}/scp-ssh-wrapper.scp
diff --git a/crypto/openssh/regress/scp3.sh b/crypto/openssh/regress/scp3.sh
index 47db47cd6a7d..383121f4519e 100644
--- a/crypto/openssh/regress/scp3.sh
+++ b/crypto/openssh/regress/scp3.sh
@@ -1,66 +1,62 @@
-# $OpenBSD: scp3.sh,v 1.3 2021/08/10 03:35:45 djm Exp $
+# $OpenBSD: scp3.sh,v 1.4 2023/01/13 04:47:34 dtucker Exp $
# Placed in the Public Domain.
tid="scp3"
-#set -x
+set -x
COPY2=${OBJ}/copy2
DIR=${COPY}.dd
DIR2=${COPY}.dd2
-$SSH -F $OBJ/ssh_proxy somehost \
- 'IFS=":"; for i in $PATH;do [ -x "$i/scp" ] && exit 0; done; exit 1'
-if [ $? -eq 1 ]; then
- skip "No scp on remote path."
-fi
+maybe_add_scp_path_to_sshd
SRC=`dirname ${SCRIPT}`
cp ${SRC}/scp-ssh-wrapper.sh ${OBJ}/scp-ssh-wrapper.scp
chmod 755 ${OBJ}/scp-ssh-wrapper.scp
export SCP # used in scp-ssh-wrapper.scp
scpclean() {
rm -rf ${COPY} ${COPY2} ${DIR} ${DIR2}
mkdir ${DIR} ${DIR2}
chmod 755 ${DIR} ${DIR2}
}
for mode in scp sftp ; do
scpopts="-F${OBJ}/ssh_proxy -S ${SSH} -q"
tag="$tid: $mode mode"
if test $mode = scp ; then
scpopts="$scpopts -O"
else
scpopts="-s -D ${SFTPSERVER}"
fi
verbose "$tag: simple copy remote file to remote file"
scpclean
$SCP $scpopts -3 hostA:${DATA} hostB:${COPY} || fail "copy failed"
cmp ${DATA} ${COPY} || fail "corrupted copy"
verbose "$tag: simple copy remote file to remote dir"
scpclean
cp ${DATA} ${COPY}
$SCP $scpopts -3 hostA:${COPY} hostB:${DIR} || fail "copy failed"
cmp ${COPY} ${DIR}/copy || fail "corrupted copy"
verbose "$tag: recursive remote dir to remote dir"
scpclean
rm -rf ${DIR2}
cp ${DATA} ${DIR}/copy
$SCP $scpopts -3r hostA:${DIR} hostB:${DIR2} || fail "copy failed"
diff -r ${DIR} ${DIR2} || fail "corrupted copy"
diff -r ${DIR2} ${DIR} || fail "corrupted copy"
verbose "$tag: detect non-directory target"
scpclean
echo a > ${COPY}
echo b > ${COPY2}
$SCP $scpopts -3 hostA:${DATA} hostA:${COPY} hostB:${COPY2}
cmp ${COPY} ${COPY2} >/dev/null && fail "corrupt target"
done
scpclean
rm -f ${OBJ}/scp-ssh-wrapper.exe
diff --git a/crypto/openssh/regress/test-exec.sh b/crypto/openssh/regress/test-exec.sh
index c51f8eac162f..df43f021404f 100644
--- a/crypto/openssh/regress/test-exec.sh
+++ b/crypto/openssh/regress/test-exec.sh
@@ -1,804 +1,816 @@
-# $OpenBSD: test-exec.sh,v 1.92 2022/07/25 07:12:45 dtucker Exp $
+# $OpenBSD: test-exec.sh,v 1.94 2023/01/13 04:47:34 dtucker Exp $
# Placed in the Public Domain.
#SUDO=sudo
if [ ! -z "$TEST_SSH_ELAPSED_TIMES" ]; then
STARTTIME=`date '+%s'`
fi
if [ ! -z "$TEST_SSH_PORT" ]; then
PORT="$TEST_SSH_PORT"
else
PORT=4242
fi
OBJ=$1
if [ "x$OBJ" = "x" ]; then
echo '$OBJ not defined'
exit 2
fi
if [ ! -d $OBJ ]; then
echo "not a directory: $OBJ"
exit 2
fi
SCRIPT=$2
if [ "x$SCRIPT" = "x" ]; then
echo '$SCRIPT not defined'
exit 2
fi
if [ ! -f $SCRIPT ]; then
echo "not a file: $SCRIPT"
exit 2
fi
if $TEST_SHELL -n $SCRIPT; then
true
else
echo "syntax error in $SCRIPT"
exit 2
fi
unset SSH_AUTH_SOCK
# 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
SSH=ssh
SSHD=sshd
SSHAGENT=ssh-agent
SSHADD=ssh-add
SSHKEYGEN=ssh-keygen
SSHKEYSCAN=ssh-keyscan
SFTP=sftp
SFTPSERVER=/usr/libexec/openssh/sftp-server
SCP=scp
# Set by make_tmpdir() on demand (below).
SSH_REGRESS_TMP=
# Interop testing
PLINK=plink
PUTTYGEN=puttygen
CONCH=conch
# Tools used by multiple tests
NC=$OBJ/netcat
OPENSSL_BIN="${OPENSSL_BIN:-openssl}"
if [ "x$TEST_SSH_SSH" != "x" ]; then
SSH="${TEST_SSH_SSH}"
fi
if [ "x$TEST_SSH_SSHD" != "x" ]; then
SSHD="${TEST_SSH_SSHD}"
fi
if [ "x$TEST_SSH_SSHAGENT" != "x" ]; then
SSHAGENT="${TEST_SSH_SSHAGENT}"
fi
if [ "x$TEST_SSH_SSHADD" != "x" ]; then
SSHADD="${TEST_SSH_SSHADD}"
fi
if [ "x$TEST_SSH_SSHKEYGEN" != "x" ]; then
SSHKEYGEN="${TEST_SSH_SSHKEYGEN}"
fi
if [ "x$TEST_SSH_SSHKEYSCAN" != "x" ]; then
SSHKEYSCAN="${TEST_SSH_SSHKEYSCAN}"
fi
if [ "x$TEST_SSH_SFTP" != "x" ]; then
SFTP="${TEST_SSH_SFTP}"
fi
if [ "x$TEST_SSH_SFTPSERVER" != "x" ]; then
SFTPSERVER="${TEST_SSH_SFTPSERVER}"
fi
if [ "x$TEST_SSH_SCP" != "x" ]; then
SCP="${TEST_SSH_SCP}"
fi
if [ "x$TEST_SSH_PLINK" != "x" ]; then
# Find real binary, if it exists
case "${TEST_SSH_PLINK}" in
/*) PLINK="${TEST_SSH_PLINK}" ;;
*) PLINK=`which ${TEST_SSH_PLINK} 2>/dev/null` ;;
esac
fi
if [ "x$TEST_SSH_PUTTYGEN" != "x" ]; then
# Find real binary, if it exists
case "${TEST_SSH_PUTTYGEN}" in
/*) PUTTYGEN="${TEST_SSH_PUTTYGEN}" ;;
*) PUTTYGEN=`which ${TEST_SSH_PUTTYGEN} 2>/dev/null` ;;
esac
fi
if [ "x$TEST_SSH_CONCH" != "x" ]; then
# Find real binary, if it exists
case "${TEST_SSH_CONCH}" in
/*) CONCH="${TEST_SSH_CONCH}" ;;
*) CONCH=`which ${TEST_SSH_CONCH} 2>/dev/null` ;;
esac
fi
if [ "x$TEST_SSH_PKCS11_HELPER" != "x" ]; then
SSH_PKCS11_HELPER="${TEST_SSH_PKCS11_HELPER}"
fi
if [ "x$TEST_SSH_SK_HELPER" != "x" ]; then
SSH_SK_HELPER="${TEST_SSH_SK_HELPER}"
fi
if [ "x$TEST_SSH_OPENSSL" != "x" ]; then
OPENSSL_BIN="${TEST_SSH_OPENSSL}"
fi
# Path to sshd must be absolute for rexec
case "$SSHD" in
/*) ;;
*) SSHD=`which $SSHD` ;;
esac
case "$SSHAGENT" in
/*) ;;
*) SSHAGENT=`which $SSHAGENT` ;;
esac
# Record the actual binaries used.
SSH_BIN=${SSH}
SSHD_BIN=${SSHD}
SSHAGENT_BIN=${SSHAGENT}
SSHADD_BIN=${SSHADD}
SSHKEYGEN_BIN=${SSHKEYGEN}
SSHKEYSCAN_BIN=${SSHKEYSCAN}
SFTP_BIN=${SFTP}
SFTPSERVER_BIN=${SFTPSERVER}
SCP_BIN=${SCP}
if [ "x$USE_VALGRIND" != "x" ]; then
rm -rf $OBJ/valgrind-out $OBJ/valgrind-vgdb
mkdir -p $OBJ/valgrind-out $OBJ/valgrind-vgdb
# When using sudo ensure low-priv tests can write pipes and logs.
if [ "x$SUDO" != "x" ]; then
chmod 777 $OBJ/valgrind-out $OBJ/valgrind-vgdb
fi
VG_TEST=`basename $SCRIPT .sh`
# Some tests are difficult to fix.
case "$VG_TEST" in
reexec)
VG_SKIP=1 ;;
sftp-chroot)
if [ "x${SUDO}" != "x" ]; then
VG_SKIP=1
fi ;;
esac
if [ x"$VG_SKIP" = "x" ]; then
VG_LEAK="--leak-check=no"
if [ x"$VALGRIND_CHECK_LEAKS" != "x" ]; then
VG_LEAK="--leak-check=full"
fi
VG_IGNORE="/bin/*,/sbin/*,/usr/*,/var/*"
VG_LOG="$OBJ/valgrind-out/${VG_TEST}."
VG_OPTS="--track-origins=yes $VG_LEAK"
VG_OPTS="$VG_OPTS --trace-children=yes"
VG_OPTS="$VG_OPTS --trace-children-skip=${VG_IGNORE}"
VG_OPTS="$VG_OPTS --vgdb-prefix=$OBJ/valgrind-vgdb/"
VG_PATH="valgrind"
if [ "x$VALGRIND_PATH" != "x" ]; then
VG_PATH="$VALGRIND_PATH"
fi
VG="$VG_PATH $VG_OPTS"
SSH="$VG --log-file=${VG_LOG}ssh.%p $SSH"
SSHD="$VG --log-file=${VG_LOG}sshd.%p $SSHD"
SSHAGENT="$VG --log-file=${VG_LOG}ssh-agent.%p $SSHAGENT"
SSHADD="$VG --log-file=${VG_LOG}ssh-add.%p $SSHADD"
SSHKEYGEN="$VG --log-file=${VG_LOG}ssh-keygen.%p $SSHKEYGEN"
SSHKEYSCAN="$VG --log-file=${VG_LOG}ssh-keyscan.%p $SSHKEYSCAN"
SFTP="$VG --log-file=${VG_LOG}sftp.%p ${SFTP}"
SCP="$VG --log-file=${VG_LOG}scp.%p $SCP"
cat > $OBJ/valgrind-sftp-server.sh << EOF
#!/bin/sh
exec $VG --log-file=${VG_LOG}sftp-server.%p $SFTPSERVER "\$@"
EOF
chmod a+rx $OBJ/valgrind-sftp-server.sh
SFTPSERVER="$OBJ/valgrind-sftp-server.sh"
fi
fi
# Logfiles.
# SSH_LOGFILE should be the debug output of ssh(1) only
# SSHD_LOGFILE should be the debug output of sshd(8) only
# REGRESS_LOGFILE is the output of the test itself stdout and stderr
if [ "x$TEST_SSH_LOGFILE" = "x" ]; then
TEST_SSH_LOGFILE=$OBJ/ssh.log
fi
if [ "x$TEST_SSHD_LOGFILE" = "x" ]; then
TEST_SSHD_LOGFILE=$OBJ/sshd.log
fi
if [ "x$TEST_REGRESS_LOGFILE" = "x" ]; then
TEST_REGRESS_LOGFILE=$OBJ/regress.log
fi
# If set, keep track of successful tests and skip them them if we've
# previously completed that test.
if [ "x$TEST_REGRESS_CACHE_DIR" != "x" ]; then
if [ ! -d "$TEST_REGRESS_CACHE_DIR" ]; then
mkdir -p "$TEST_REGRESS_CACHE_DIR"
fi
TEST="`basename $SCRIPT .sh`"
CACHE="${TEST_REGRESS_CACHE_DIR}/${TEST}.cache"
for i in ${SSH} ${SSHD} ${SSHAGENT} ${SSHADD} ${SSHKEYGEN} ${SCP} \
${SFTP} ${SFTPSERVER} ${SSHKEYSCAN}; do
case $i in
/*) bin="$i" ;;
*) bin="`which $i`" ;;
esac
if [ "$bin" -nt "$CACHE" ]; then
rm -f "$CACHE"
fi
done
if [ -f "$CACHE" ]; then
echo ok cached $CACHE
exit 0
fi
fi
# truncate logfiles
>$TEST_SSH_LOGFILE
>$TEST_SSHD_LOGFILE
>$TEST_REGRESS_LOGFILE
# Create wrapper ssh with logging. We can't just specify "SSH=ssh -E..."
# because sftp and scp don't handle spaces in arguments. 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
cat >$SSHLOGWRAP <<EOD
#!/bin/sh
echo "Executing: ${SSH} \$@" >>${TEST_SSH_LOGFILE}
for i in "\$@";do shift;case "\$i" in -q):;; *) set -- "\$@" "\$i";;esac;done
exec ${SSH} -E${TEST_SSH_LOGFILE} "\$@"
EOD
chmod a+rx $OBJ/ssh-log-wrapper.sh
REAL_SSH="$SSH"
REAL_SSHD="$SSHD"
SSH="$SSHLOGWRAP"
# Some test data. We make a copy because some tests will overwrite it.
# The tests may assume that $DATA exists and is writable and $COPY does
# not exist. Tests requiring larger data files can call increase_datafile_size
# [kbytes] to ensure the file is at least that large.
DATANAME=data
DATA=$OBJ/${DATANAME}
cat ${SSHAGENT_BIN} >${DATA}
chmod u+w ${DATA}
COPY=$OBJ/copy
rm -f ${COPY}
increase_datafile_size()
{
while [ `du -k ${DATA} | cut -f1` -lt $1 ]; do
cat ${SSHAGENT_BIN} >>${DATA}
done
}
# these should be used in tests
export SSH SSHD SSHAGENT SSHADD SSHKEYGEN SSHKEYSCAN SFTP SFTPSERVER SCP
export SSH_PKCS11_HELPER SSH_SK_HELPER
#echo $SSH $SSHD $SSHAGENT $SSHADD $SSHKEYGEN $SSHKEYSCAN $SFTP $SFTPSERVER $SCP
# Portable specific functions
which()
{
saved_IFS="$IFS"
IFS=":"
for i in $PATH
do
if [ -x $i/$1 ]; then
IFS="$saved_IFS"
echo "$i/$1"
return 0
fi
done
IFS="$saved_IFS"
echo "$i/$1"
return 1
}
have_prog()
{
which "$1" >/dev/null 2>&1
return $?
}
jot() {
awk "BEGIN { for (i = $2; i < $2 + $1; i++) { printf \"%d\n\", i } exit }"
}
if [ ! -x "`which rev`" ]; then
rev()
{
awk '{for (i=length; i>0; i--) printf "%s", substr($0, i, 1); print ""}'
}
fi
# Check whether preprocessor symbols are defined in config.h.
config_defined ()
{
str=$1
while test "x$2" != "x" ; do
str="$str|$2"
shift
done
egrep "^#define.*($str)" ${BUILDDIR}/config.h >/dev/null 2>&1
}
md5 () {
if have_prog md5sum; then
md5sum
elif have_prog openssl; then
openssl md5
elif have_prog cksum; then
cksum
elif have_prog sum; then
sum
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 ()
{
if [ -f $PIDFILE ]; then
pid=`$SUDO cat $PIDFILE`
if [ "X$pid" = "X" ]; then
echo no sshd running
else
if [ $pid -lt 2 ]; then
echo bad pid for sshd: $pid
else
$SUDO kill $pid
trace "wait for sshd to exit"
i=0;
while [ -f $PIDFILE -a $i -lt 5 ]; do
i=`expr $i + 1`
sleep $i
done
if test -f $PIDFILE; then
if $SUDO kill -0 $pid; then
echo "sshd didn't exit " \
"port $PORT pid $pid"
else
echo "sshd died without cleanup"
fi
exit 1
fi
fi
fi
fi
}
# helper
cleanup ()
{
if [ "x$SSH_PID" != "x" ]; then
if [ $SSH_PID -lt 2 ]; then
echo bad pid for ssh: $SSH_PID
else
kill $SSH_PID
fi
fi
if [ "x$SSH_REGRESS_TMP" != "x" ]; then
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 ()
{
echo "trace: $@" >$TEST_REGRESS_LOGFILE
echo "trace: $@" >$TEST_SSH_LOGFILE
echo "trace: $@" >$TEST_SSHD_LOGFILE
}
save_debug_log ()
{
echo $@ >>$TEST_REGRESS_LOGFILE
echo $@ >>$TEST_SSH_LOGFILE
echo $@ >>$TEST_SSHD_LOGFILE
(cat $TEST_REGRESS_LOGFILE; echo) >>$OBJ/failed-regress.log
(cat $TEST_SSH_LOGFILE; echo) >>$OBJ/failed-ssh.log
(cat $TEST_SSHD_LOGFILE; echo) >>$OBJ/failed-sshd.log
}
trace ()
{
start_debug_log $@
if [ "X$TEST_SSH_TRACE" = "Xyes" ]; then
echo "$@"
fi
}
verbose ()
{
start_debug_log $@
if [ "X$TEST_SSH_QUIET" != "Xyes" ]; then
echo "$@"
fi
}
fail ()
{
save_debug_log "FAIL: $@"
RESULT=1
echo "$@"
if test "x$TEST_SSH_FAIL_FATAL" != "x" ; then
cleanup
exit $RESULT
fi
}
fatal ()
{
save_debug_log "FATAL: $@"
printf "FATAL: "
fail "$@"
cleanup
exit $RESULT
}
# Skip remaining tests in script.
skip ()
{
echo "SKIPPED: $@"
cleanup
exit $RESULT
}
+maybe_add_scp_path_to_sshd ()
+{
+ # If we're testing a non-installed scp, add its directory to sshd's
+ # PATH so we can test it. We don't do this for all tests as it
+ # breaks the SetEnv tests.
+ case "$SCP" in
+ /*) PATH_WITH_SCP="`dirname $SCP`:$PATH"
+ echo " SetEnv PATH='$PATH_WITH_SCP'" >>$OBJ/sshd_config
+ echo " SetEnv PATH='$PATH_WITH_SCP'" >>$OBJ/sshd_proxy ;;
+ esac
+}
+
RESULT=0
PIDFILE=$OBJ/pidfile
trap fatal 3 2
# create server config
cat << EOF > $OBJ/sshd_config
StrictModes no
Port $PORT
AddressFamily inet
ListenAddress 127.0.0.1
#ListenAddress ::1
PidFile $PIDFILE
AuthorizedKeysFile $OBJ/authorized_keys_%u
LogLevel DEBUG3
AcceptEnv _XXX_TEST_*
AcceptEnv _XXX_TEST
Subsystem sftp $SFTPSERVER
EOF
# This may be necessary if /usr/src and/or /usr/obj are group-writable,
# 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
else
# check and warn if excessive permissions are likely to cause failures.
unsafe=""
dir="${OBJ}"
while test ${dir} != "/"; do
if test -d "${dir}" && ! test -h "${dir}"; then
perms=`ls -ld ${dir}`
case "${perms}" in
?????w????*|????????w?*) unsafe="${unsafe} ${dir}" ;;
esac
fi
dir=`dirname ${dir}`
done
if ! test -z "${unsafe}"; then
cat <<EOD
WARNING: Unsafe (group or world writable) directory permissions found:
${unsafe}
These could be abused to locally escalate privileges. If you are
sure that this is not a risk (eg there are no other users), you can
bypass this check by setting TEST_SSH_UNSAFE_PERMISSIONS=1
EOD
fi
fi
if [ ! -z "$TEST_SSH_MODULI_FILE" ]; then
trace "adding modulifile='$TEST_SSH_MODULI_FILE' to sshd_config"
echo " ModuliFile '$TEST_SSH_MODULI_FILE'" >> $OBJ/sshd_config
fi
if [ ! -z "$TEST_SSH_SSHD_CONFOPTS" ]; then
trace "adding sshd_config option $TEST_SSH_SSHD_CONFOPTS"
echo "$TEST_SSH_SSHD_CONFOPTS" >> $OBJ/sshd_config
fi
# server config for proxy connects
cp $OBJ/sshd_config $OBJ/sshd_proxy
# allow group-writable directories in proxy-mode
echo 'StrictModes no' >> $OBJ/sshd_proxy
# create client config
cat << EOF > $OBJ/ssh_config
Host *
Hostname 127.0.0.1
HostKeyAlias localhost-with-alias
Port $PORT
User $USER
GlobalKnownHostsFile $OBJ/known_hosts
UserKnownHostsFile $OBJ/known_hosts
PubkeyAuthentication yes
ChallengeResponseAuthentication no
PasswordAuthentication no
BatchMode yes
StrictHostKeyChecking yes
LogLevel DEBUG3
EOF
if [ ! -z "$TEST_SSH_SSH_CONFOPTS" ]; then
trace "adding ssh_config option $TEST_SSH_SSH_CONFOPTS"
echo "$TEST_SSH_SSH_CONFOPTS" >> $OBJ/ssh_config
fi
rm -f $OBJ/known_hosts $OBJ/authorized_keys_$USER
SSH_SK_PROVIDER=
if ! config_defined ENABLE_SK; then
trace skipping sk-dummy
elif [ -f "${SRC}/misc/sk-dummy/obj/sk-dummy.so" ] ; then
SSH_SK_PROVIDER="${SRC}/misc/sk-dummy/obj/sk-dummy.so"
elif [ -f "${OBJ}/misc/sk-dummy/sk-dummy.so" ] ; then
SSH_SK_PROVIDER="${OBJ}/misc/sk-dummy/sk-dummy.so"
elif [ -f "${SRC}/misc/sk-dummy/sk-dummy.so" ] ; then
SSH_SK_PROVIDER="${SRC}/misc/sk-dummy/sk-dummy.so"
fi
export SSH_SK_PROVIDER
if ! test -z "$SSH_SK_PROVIDER"; then
EXTRA_AGENT_ARGS='-P/*' # XXX want realpath(1)...
echo "SecurityKeyProvider $SSH_SK_PROVIDER" >> $OBJ/ssh_config
echo "SecurityKeyProvider $SSH_SK_PROVIDER" >> $OBJ/sshd_config
echo "SecurityKeyProvider $SSH_SK_PROVIDER" >> $OBJ/sshd_proxy
fi
export EXTRA_AGENT_ARGS
maybe_filter_sk() {
if test -z "$SSH_SK_PROVIDER" ; then
grep -v ^sk
else
cat
fi
}
SSH_KEYTYPES=`$SSH -Q key-plain | maybe_filter_sk`
SSH_HOSTKEY_TYPES=`$SSH -Q key-plain | maybe_filter_sk`
for t in ${SSH_KEYTYPES}; do
# generate user key
if [ ! -f $OBJ/$t ] || [ ${SSHKEYGEN_BIN} -nt $OBJ/$t ]; then
trace "generating key type $t"
rm -f $OBJ/$t
${SSHKEYGEN} -q -N '' -t $t -f $OBJ/$t ||\
fail "ssh-keygen for $t failed"
else
trace "using cached key type $t"
fi
# setup authorized keys
cat $OBJ/$t.pub >> $OBJ/authorized_keys_$USER
echo IdentityFile $OBJ/$t >> $OBJ/ssh_config
done
for t in ${SSH_HOSTKEY_TYPES}; do
# known hosts file for client
(
printf 'localhost-with-alias,127.0.0.1,::1 '
cat $OBJ/$t.pub
) >> $OBJ/known_hosts
# use key as host key, too
(umask 077; $SUDO cp $OBJ/$t $OBJ/host.$t)
echo HostKey $OBJ/host.$t >> $OBJ/sshd_config
# don't use SUDO for proxy connect
echo HostKey $OBJ/$t >> $OBJ/sshd_proxy
done
chmod 644 $OBJ/authorized_keys_$USER
# Activate Twisted Conch tests if the binary is present
REGRESS_INTEROP_CONCH=no
if test -x "$CONCH" ; then
REGRESS_INTEROP_CONCH=yes
fi
# If PuTTY is present, new enough and we are running a PuTTY test, prepare
# keys and configuration.
REGRESS_INTEROP_PUTTY=no
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
*putty*) ;;
*) REGRESS_INTEROP_PUTTY=no ;;
esac
if test "$REGRESS_INTEROP_PUTTY" = "yes" ; then
mkdir -p ${OBJ}/.putty
# Add a PuTTY key to authorized_keys
rm -f ${OBJ}/putty.rsa2
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, skipping test" >&2
exit 1
fi
"$PUTTYGEN" -O public-openssh ${OBJ}/putty.rsa2 \
>> $OBJ/authorized_keys_$USER
# Convert rsa2 host key to PuTTY format
cp $OBJ/ssh-rsa $OBJ/ssh-rsa_oldfmt
${SSHKEYGEN} -p -N '' -m PEM -f $OBJ/ssh-rsa_oldfmt >/dev/null
${SRC}/ssh2putty.sh 127.0.0.1 $PORT $OBJ/ssh-rsa_oldfmt > \
${OBJ}/.putty/sshhostkeys
${SRC}/ssh2putty.sh 127.0.0.1 22 $OBJ/ssh-rsa_oldfmt >> \
${OBJ}/.putty/sshhostkeys
rm -f $OBJ/ssh-rsa_oldfmt
# Setup proxied session
mkdir -p ${OBJ}/.putty/sessions
rm -f ${OBJ}/.putty/sessions/localhost_proxy
echo "Protocol=ssh" >> ${OBJ}/.putty/sessions/localhost_proxy
echo "HostName=127.0.0.1" >> ${OBJ}/.putty/sessions/localhost_proxy
echo "PortNumber=$PORT" >> ${OBJ}/.putty/sessions/localhost_proxy
echo "ProxyMethod=5" >> ${OBJ}/.putty/sessions/localhost_proxy
echo "ProxyTelnetCommand=sh ${SRC}/sshd-log-wrapper.sh ${TEST_SSHD_LOGFILE} ${SSHD} -i -f $OBJ/sshd_proxy" >> ${OBJ}/.putty/sessions/localhost_proxy
echo "ProxyLocalhost=1" >> ${OBJ}/.putty/sessions/localhost_proxy
PUTTYDIR=${OBJ}/.putty
export PUTTYDIR
fi
# create a proxy version of the client config
(
cat $OBJ/ssh_config
echo proxycommand ${SUDO} env SSH_SK_HELPER=\"$SSH_SK_HELPER\" sh ${SRC}/sshd-log-wrapper.sh ${TEST_SSHD_LOGFILE} ${SSHD} -i -f $OBJ/sshd_proxy
) > $OBJ/ssh_proxy
# check proxy config
${SSHD} -t -f $OBJ/sshd_proxy || fatal "sshd_proxy broken"
start_sshd ()
{
# start sshd
$SUDO ${SSHD} -f $OBJ/sshd_config "$@" -t || fatal "sshd_config broken"
$SUDO env SSH_SK_HELPER="$SSH_SK_HELPER" \
${SSHD} -f $OBJ/sshd_config "$@" -E$TEST_SSHD_LOGFILE
trace "wait for sshd"
i=0;
while [ ! -f $PIDFILE -a $i -lt 10 ]; do
i=`expr $i + 1`
sleep $i
done
test -f $PIDFILE || fatal "no sshd running on port $PORT"
}
# source test body
. $SCRIPT
# kill sshd
cleanup
if [ "x$USE_VALGRIND" != "x" ]; then
# If there is an EXIT trap handler, invoke it now.
# Some tests set these to clean up processes such as ssh-agent. We
# need to wait for all valgrind processes to complete so we can check
# their logs, but since the EXIT traps are not invoked until
# test-exec.sh exits, waiting here will deadlock.
# This is not very portable but then neither is valgrind itself.
# As a bonus, dash (as used on the runners) has a "trap" that doesn't
# work in a pipeline (hence the temp file) or a subshell.
exithandler=""
trap >/tmp/trap.$$ && exithandler=$(cat /tmp/trap.$$ | \
awk -F "'" '/EXIT$/{print $2}')
rm -f /tmp/trap.$$
if [ "x${exithandler}" != "x" ]; then
verbose invoking EXIT trap handler early: ${exithandler}
eval "${exithandler}"
trap '' EXIT
fi
# wait for any running process to complete
wait; sleep 1
VG_RESULTS=$(find $OBJ/valgrind-out -type f -print)
VG_RESULT_COUNT=0
VG_FAIL_COUNT=0
for i in $VG_RESULTS; do
if grep "ERROR SUMMARY" $i >/dev/null; then
VG_RESULT_COUNT=$(($VG_RESULT_COUNT + 1))
if ! grep "ERROR SUMMARY: 0 errors" $i >/dev/null; then
VG_FAIL_COUNT=$(($VG_FAIL_COUNT + 1))
RESULT=1
verbose valgrind failure $i
cat $i
fi
fi
done
if [ x"$VG_SKIP" != "x" ]; then
verbose valgrind skipped
else
verbose valgrind results $VG_RESULT_COUNT failures $VG_FAIL_COUNT
fi
fi
if [ $RESULT -eq 0 ]; then
verbose ok $tid
if [ "x$CACHE" != "x" ]; then
touch "$CACHE"
fi
else
echo failed $tid
fi
exit $RESULT
diff --git a/crypto/openssh/regress/unittests/hostkeys/Makefile b/crypto/openssh/regress/unittests/hostkeys/Makefile
index 9a53423eeac0..04d93359acaa 100644
--- a/crypto/openssh/regress/unittests/hostkeys/Makefile
+++ b/crypto/openssh/regress/unittests/hostkeys/Makefile
@@ -1,25 +1,25 @@
-# $OpenBSD: Makefile,v 1.9 2021/01/09 12:24:30 dtucker Exp $
+# $OpenBSD: Makefile,v 1.10 2023/01/15 23:35:10 djm Exp $
PROG=test_hostkeys
SRCS=tests.c test_iterate.c
# From usr.bin/ssh
SRCS+=sshbuf-getput-basic.c sshbuf-getput-crypto.c sshbuf-misc.c sshbuf.c
SRCS+=sshbuf-io.c atomicio.c sshkey.c authfile.c cipher.c log.c ssh-rsa.c
SRCS+=ssh-dss.c ssh-ecdsa.c ssh-ed25519.c mac.c umac.c umac128.c hmac.c misc.c
SRCS+=ssherr.c uidswap.c cleanup.c xmalloc.c match.c krl.c fatal.c
SRCS+=addr.c addrmatch.c bitmap.c hostfile.c
-SRCS+=ed25519.c hash.c ge25519.c fe25519.c sc25519.c verify.c
+SRCS+=ed25519.c hash.c
SRCS+=cipher-chachapoly.c chacha.c poly1305.c ssh-ecdsa-sk.c ssh-sk.c
SRCS+=ssh-ed25519-sk.c sk-usbhid.c
SRCS+=digest-openssl.c
#SRCS+=digest-libc.c
SRCS+=utf8.c
REGRESS_TARGETS=run-regress-${PROG}
run-regress-${PROG}: ${PROG}
env ${TEST_ENV} ./${PROG} -d ${.CURDIR}/testdata
.include <bsd.regress.mk>
diff --git a/crypto/openssh/regress/unittests/kex/Makefile b/crypto/openssh/regress/unittests/kex/Makefile
index 50b117c07851..981affe3cbee 100644
--- a/crypto/openssh/regress/unittests/kex/Makefile
+++ b/crypto/openssh/regress/unittests/kex/Makefile
@@ -1,40 +1,40 @@
-# $OpenBSD: Makefile,v 1.12 2021/01/09 12:24:30 dtucker Exp $
+# $OpenBSD: Makefile,v 1.14 2023/02/02 12:12:52 djm Exp $
PROG=test_kex
-SRCS=tests.c test_kex.c
+SRCS=tests.c test_kex.c test_proposal.c
# From usr.bin/ssh
SRCS+=sshbuf-getput-basic.c sshbuf-getput-crypto.c sshbuf-misc.c sshbuf.c
SRCS+=sshbuf-io.c atomicio.c sshkey.c authfile.c cipher.c log.c ssh-rsa.c
SRCS+=ssh-dss.c ssh-ecdsa.c ssh-ed25519.c mac.c umac.c umac128.c hmac.c misc.c
SRCS+=ssherr.c uidswap.c cleanup.c xmalloc.c match.c krl.c fatal.c
SRCS+=addr.c addrmatch.c bitmap.c 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+=compat.c ed25519.c hash.c
SRCS+=cipher-chachapoly.c chacha.c poly1305.c ssh-ecdsa-sk.c ssh-sk.c
SRCS+=ssh-ed25519-sk.c sk-usbhid.c
SRCS+= kex.c
SRCS+= dh.c
SRCS+= kexdh.c
SRCS+= kexecdh.c
SRCS+= kexgex.c
SRCS+= kexgexc.c
SRCS+= kexgexs.c
SRCS+= kexc25519.c
SRCS+= smult_curve25519_ref.c
SRCS+= kexgen.c
SRCS+= kexsntrup761x25519.c
SRCS+= sntrup761.c
SRCS+= utf8.c
SRCS+=digest-openssl.c
#SRCS+=digest-libc.c
REGRESS_TARGETS=run-regress-${PROG}
run-regress-${PROG}: ${PROG}
env ${TEST_ENV} ./${PROG}
.include <bsd.regress.mk>
LDADD+=-lz
diff --git a/crypto/openssh/regress/unittests/kex/test_proposal.c b/crypto/openssh/regress/unittests/kex/test_proposal.c
new file mode 100644
index 000000000000..d6cf0f5da7d7
--- /dev/null
+++ b/crypto/openssh/regress/unittests/kex/test_proposal.c
@@ -0,0 +1,83 @@
+/* $OpenBSD: test_proposal.c,v 1.1 2023/02/02 12:12:52 djm Exp $ */
+/*
+ * Regress test KEX
+ *
+ * Placed in the public domain
+ */
+
+#include "includes.h"
+
+#include <sys/types.h>
+#include <signal.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 "compat.h"
+#include "ssherr.h"
+#include "sshbuf.h"
+#include "kex.h"
+#include "packet.h"
+#include "xmalloc.h"
+
+void kex_proposal(void);
+
+#define CURVE25519 "curve25519-sha256@libssh.org"
+#define DHGEX1 "diffie-hellman-group-exchange-sha1"
+#define DHGEX256 "diffie-hellman-group-exchange-sha256"
+#define KEXALGOS CURVE25519","DHGEX256","DHGEX1
+void
+kex_proposal(void)
+{
+ size_t i;
+ struct ssh ssh;
+ char *result, *out, *in;
+ struct {
+ char *in; /* TODO: make this const */
+ char *out;
+ int compat;
+ } tests[] = {
+ { KEXALGOS, KEXALGOS, 0},
+ { KEXALGOS, DHGEX256","DHGEX1, SSH_BUG_CURVE25519PAD },
+ { KEXALGOS, CURVE25519, SSH_OLD_DHGEX },
+ { "a,"KEXALGOS, "a", SSH_BUG_CURVE25519PAD|SSH_OLD_DHGEX },
+ /* TODO: enable once compat_kex_proposal doesn't fatal() */
+ /* { KEXALGOS, "", SSH_BUG_CURVE25519PAD|SSH_OLD_DHGEX }, */
+ };
+
+ TEST_START("compat_kex_proposal");
+ for (i = 0; i < sizeof(tests) / sizeof(*tests); i++) {
+ ssh.compat = tests[i].compat;
+ /* match entire string */
+ result = compat_kex_proposal(&ssh, tests[i].in);
+ ASSERT_STRING_EQ(result, tests[i].out);
+ free(result);
+ /* match at end */
+ in = kex_names_cat("a", tests[i].in);
+ out = kex_names_cat("a", tests[i].out);
+ result = compat_kex_proposal(&ssh, in);
+ ASSERT_STRING_EQ(result, out);
+ free(result); free(in); free(out);
+ /* match at start */
+ in = kex_names_cat(tests[i].in, "a");
+ out = kex_names_cat(tests[i].out, "a");
+ result = compat_kex_proposal(&ssh, in);
+ ASSERT_STRING_EQ(result, out);
+ free(result); free(in); free(out);
+ /* match in middle */
+ xasprintf(&in, "a,%s,b", tests[i].in);
+ if (*(tests[i].out) == '\0')
+ out = xstrdup("a,b");
+ else
+ xasprintf(&out, "a,%s,b", tests[i].out);
+ result = compat_kex_proposal(&ssh, in);
+ ASSERT_STRING_EQ(result, out);
+ free(result); free(in); free(out);
+ }
+ TEST_DONE();
+}
diff --git a/crypto/openssh/regress/unittests/kex/tests.c b/crypto/openssh/regress/unittests/kex/tests.c
index e7036ec17f7b..2a83dafbc3ae 100644
--- a/crypto/openssh/regress/unittests/kex/tests.c
+++ b/crypto/openssh/regress/unittests/kex/tests.c
@@ -1,14 +1,16 @@
-/* $OpenBSD: tests.c,v 1.1 2015/01/15 23:41:29 markus Exp $ */
+/* $OpenBSD: tests.c,v 1.2 2023/02/02 12:12:52 djm Exp $ */
/*
* Placed in the public domain
*/
#include "../test_helper/test_helper.h"
void kex_tests(void);
+void kex_proposal(void);
void
tests(void)
{
kex_tests();
+ kex_proposal();
}
diff --git a/crypto/openssh/regress/unittests/misc/test_ptimeout.c b/crypto/openssh/regress/unittests/misc/test_ptimeout.c
new file mode 100644
index 000000000000..7adc590e98d6
--- /dev/null
+++ b/crypto/openssh/regress/unittests/misc/test_ptimeout.c
@@ -0,0 +1,85 @@
+/* $OpenBSD: test_ptimeout.c,v 1.1 2023/01/06 02:59:50 djm Exp $ */
+/*
+ * Regress test for misc poll/ppoll timeout helpers.
+ *
+ * Placed in the public domain.
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <poll.h>
+#include <time.h>
+
+#include "../test_helper/test_helper.h"
+
+#include "log.h"
+#include "misc.h"
+
+void test_ptimeout(void);
+
+void
+test_ptimeout(void)
+{
+ struct timespec pt, *ts;
+
+ TEST_START("ptimeout_init");
+ ptimeout_init(&pt);
+ ASSERT_PTR_EQ(ptimeout_get_tsp(&pt), NULL);
+ ASSERT_INT_EQ(ptimeout_get_ms(&pt), -1);
+ TEST_DONE();
+
+ TEST_START("ptimeout_deadline_sec");
+ ptimeout_deadline_sec(&pt, 100);
+ ptimeout_deadline_sec(&pt, 200);
+ ASSERT_INT_EQ(ptimeout_get_ms(&pt), 100 * 1000);
+ ts = ptimeout_get_tsp(&pt);
+ ASSERT_PTR_NE(ts, NULL);
+ ASSERT_LONG_EQ(ts->tv_nsec, 0);
+ ASSERT_LONG_EQ(ts->tv_sec, 100);
+ TEST_DONE();
+
+ TEST_START("ptimeout_deadline_ms");
+ ptimeout_deadline_ms(&pt, 50123);
+ ptimeout_deadline_ms(&pt, 50500);
+ ASSERT_INT_EQ(ptimeout_get_ms(&pt), 50123);
+ ts = ptimeout_get_tsp(&pt);
+ ASSERT_PTR_NE(ts, NULL);
+ ASSERT_LONG_EQ(ts->tv_nsec, 123 * 1000000);
+ ASSERT_LONG_EQ(ts->tv_sec, 50);
+ TEST_DONE();
+
+ TEST_START("ptimeout zero");
+ ptimeout_init(&pt);
+ ptimeout_deadline_ms(&pt, 0);
+ ASSERT_INT_EQ(ptimeout_get_ms(&pt), 0);
+ ts = ptimeout_get_tsp(&pt);
+ ASSERT_PTR_NE(ts, NULL);
+ ASSERT_LONG_EQ(ts->tv_nsec, 0);
+ ASSERT_LONG_EQ(ts->tv_sec, 0);
+ TEST_DONE();
+
+ TEST_START("ptimeout_deadline_monotime");
+ ptimeout_init(&pt);
+ ptimeout_deadline_monotime(&pt, monotime() + 100);
+ ASSERT_INT_GT(ptimeout_get_ms(&pt), 50000);
+ ASSERT_INT_LT(ptimeout_get_ms(&pt), 200000);
+ ts = ptimeout_get_tsp(&pt);
+ ASSERT_PTR_NE(ts, NULL);
+ ASSERT_LONG_GT(ts->tv_sec, 50);
+ ASSERT_LONG_LT(ts->tv_sec, 200);
+ TEST_DONE();
+
+ TEST_START("ptimeout_deadline_monotime past");
+ ptimeout_init(&pt);
+ ptimeout_deadline_monotime(&pt, monotime() + 100);
+ ptimeout_deadline_monotime(&pt, monotime() - 100);
+ ASSERT_INT_EQ(ptimeout_get_ms(&pt), 0);
+ ts = ptimeout_get_tsp(&pt);
+ ASSERT_PTR_NE(ts, NULL);
+ ASSERT_LONG_EQ(ts->tv_nsec, 0);
+ ASSERT_LONG_EQ(ts->tv_sec, 0);
+ TEST_DONE();
+}
diff --git a/crypto/openssh/regress/unittests/misc/tests.c b/crypto/openssh/regress/unittests/misc/tests.c
index d52490e3b3ce..32699541413e 100644
--- a/crypto/openssh/regress/unittests/misc/tests.c
+++ b/crypto/openssh/regress/unittests/misc/tests.c
@@ -1,39 +1,41 @@
-/* $OpenBSD: tests.c,v 1.9 2022/02/04 07:53:44 dtucker Exp $ */
+/* $OpenBSD: tests.c,v 1.10 2023/01/06 02:59:50 djm Exp $ */
/*
* Regress test for misc helper functions.
*
* Placed in the public domain.
*/
#include "includes.h"
#include <sys/types.h>
#include <stdio.h>
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
#include <stdlib.h>
#include <string.h>
#include "../test_helper/test_helper.h"
#include "log.h"
#include "misc.h"
void test_parse(void);
void test_convtime(void);
void test_expand(void);
void test_argv(void);
void test_strdelim(void);
void test_hpdelim(void);
+void test_ptimeout(void);
void
tests(void)
{
test_parse();
test_convtime();
test_expand();
test_argv();
test_strdelim();
test_hpdelim();
+ test_ptimeout();
}
diff --git a/crypto/openssh/regress/unittests/sshkey/Makefile b/crypto/openssh/regress/unittests/sshkey/Makefile
index d4a892375bd7..cd0f44d13d24 100644
--- a/crypto/openssh/regress/unittests/sshkey/Makefile
+++ b/crypto/openssh/regress/unittests/sshkey/Makefile
@@ -1,26 +1,26 @@
-# $OpenBSD: Makefile,v 1.11 2021/01/09 12:24:31 dtucker Exp $
+# $OpenBSD: Makefile,v 1.12 2023/01/15 23:35:10 djm Exp $
PROG=test_sshkey
SRCS=tests.c test_sshkey.c test_file.c test_fuzz.c common.c
# From usr.bin/ssh
SRCS+=sshbuf-getput-basic.c sshbuf-getput-crypto.c sshbuf-misc.c sshbuf.c
SRCS+=sshbuf-io.c atomicio.c sshkey.c authfile.c cipher.c log.c ssh-rsa.c
SRCS+=ssh-dss.c ssh-ecdsa.c ssh-ed25519.c mac.c umac.c umac128.c hmac.c misc.c
SRCS+=ssherr.c uidswap.c cleanup.c xmalloc.c match.c krl.c fatal.c
SRCS+=addr.c addrmatch.c bitmap.c
-SRCS+=ed25519.c hash.c ge25519.c fe25519.c sc25519.c verify.c
+SRCS+=ed25519.c hash.c
SRCS+=cipher-chachapoly.c chacha.c poly1305.c ssh-ecdsa-sk.c ssh-sk.c
SRCS+=ssh-ed25519-sk.c sk-usbhid.c
SRCS+=digest-openssl.c
#SRCS+=digest-libc.c
SRCS+=utf8.c
REGRESS_TARGETS=run-regress-${PROG}
run-regress-${PROG}: ${PROG}
env ${TEST_ENV} ./${PROG} ${UNITTEST_ARGS} -d ${.CURDIR}/testdata
.include <bsd.regress.mk>
diff --git a/crypto/openssh/regress/unittests/sshkey/test_sshkey.c b/crypto/openssh/regress/unittests/sshkey/test_sshkey.c
index a9afa003c60a..266a0bf8c752 100644
--- a/crypto/openssh/regress/unittests/sshkey/test_sshkey.c
+++ b/crypto/openssh/regress/unittests/sshkey/test_sshkey.c
@@ -1,529 +1,529 @@
-/* $OpenBSD: test_sshkey.c,v 1.22 2021/12/14 21:25:27 deraadt Exp $ */
+/* $OpenBSD: test_sshkey.c,v 1.23 2023/01/04 22:48:57 tb Exp $ */
/*
* Regress test for sshkey.h key management API
*
* Placed in the public domain
*/
#include "includes.h"
#include <sys/types.h>
#include <paths.h>
#include <stdio.h>
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
#include <stdlib.h>
#include <string.h>
#ifdef WITH_OPENSSL
#include <openssl/bn.h>
#include <openssl/rsa.h>
#include <openssl/dsa.h>
#if defined(OPENSSL_HAS_ECC) && defined(OPENSSL_HAS_NISTP256)
# include <openssl/ec.h>
#endif
#endif
#include "../test_helper/test_helper.h"
#include "ssherr.h"
#include "sshbuf.h"
#define SSHBUF_INTERNAL 1 /* access internals for testing */
#include "sshkey.h"
#include "authfile.h"
#include "common.h"
#include "ssh2.h"
void sshkey_tests(void);
static void
put_opt(struct sshbuf *b, const char *name, const char *value)
{
struct sshbuf *sect;
sect = sshbuf_new();
ASSERT_PTR_NE(sect, NULL);
ASSERT_INT_EQ(sshbuf_put_cstring(b, name), 0);
if (value != NULL)
ASSERT_INT_EQ(sshbuf_put_cstring(sect, value), 0);
ASSERT_INT_EQ(sshbuf_put_stringb(b, sect), 0);
sshbuf_free(sect);
}
#ifdef WITH_OPENSSL
static void
build_cert(struct sshbuf *b, struct sshkey *k, const char *type,
struct sshkey *sign_key, struct sshkey *ca_key,
const char *sig_alg)
{
struct sshbuf *ca_buf, *pk, *principals, *critopts, *exts;
u_char *sigblob;
size_t siglen;
ca_buf = sshbuf_new();
ASSERT_PTR_NE(ca_buf, NULL);
ASSERT_INT_EQ(sshkey_putb(ca_key, ca_buf), 0);
/*
* Get the public key serialisation by rendering the key and skipping
* the type string. This is a bit of a hack :/
*/
pk = sshbuf_new();
ASSERT_PTR_NE(pk, NULL);
ASSERT_INT_EQ(sshkey_putb_plain(k, pk), 0);
ASSERT_INT_EQ(sshbuf_skip_string(pk), 0);
principals = sshbuf_new();
ASSERT_PTR_NE(principals, NULL);
ASSERT_INT_EQ(sshbuf_put_cstring(principals, "gsamsa"), 0);
ASSERT_INT_EQ(sshbuf_put_cstring(principals, "gregor"), 0);
critopts = sshbuf_new();
ASSERT_PTR_NE(critopts, NULL);
put_opt(critopts, "force-command", _PATH_LOCALBASE "/bin/nethack");
put_opt(critopts, "source-address", "192.168.0.0/24,127.0.0.1,::1");
exts = sshbuf_new();
ASSERT_PTR_NE(exts, NULL);
put_opt(critopts, "permit-X11-forwarding", NULL);
ASSERT_INT_EQ(sshbuf_put_cstring(b, type), 0);
ASSERT_INT_EQ(sshbuf_put_cstring(b, "noncenoncenonce!"), 0); /* nonce */
ASSERT_INT_EQ(sshbuf_putb(b, pk), 0); /* public key serialisation */
ASSERT_INT_EQ(sshbuf_put_u64(b, 1234), 0); /* serial */
ASSERT_INT_EQ(sshbuf_put_u32(b, SSH2_CERT_TYPE_USER), 0); /* type */
ASSERT_INT_EQ(sshbuf_put_cstring(b, "gregor"), 0); /* key ID */
ASSERT_INT_EQ(sshbuf_put_stringb(b, principals), 0); /* principals */
ASSERT_INT_EQ(sshbuf_put_u64(b, 0), 0); /* start */
ASSERT_INT_EQ(sshbuf_put_u64(b, 0xffffffffffffffffULL), 0); /* end */
ASSERT_INT_EQ(sshbuf_put_stringb(b, critopts), 0); /* options */
ASSERT_INT_EQ(sshbuf_put_stringb(b, exts), 0); /* extensions */
ASSERT_INT_EQ(sshbuf_put_string(b, NULL, 0), 0); /* reserved */
ASSERT_INT_EQ(sshbuf_put_stringb(b, ca_buf), 0); /* signature key */
ASSERT_INT_EQ(sshkey_sign(sign_key, &sigblob, &siglen,
sshbuf_ptr(b), sshbuf_len(b), sig_alg, NULL, NULL, 0), 0);
ASSERT_INT_EQ(sshbuf_put_string(b, sigblob, siglen), 0); /* signature */
free(sigblob);
sshbuf_free(ca_buf);
sshbuf_free(exts);
sshbuf_free(critopts);
sshbuf_free(principals);
sshbuf_free(pk);
}
#endif /* WITH_OPENSSL */
static void
signature_test(struct sshkey *k, struct sshkey *bad, const char *sig_alg,
const u_char *d, size_t l)
{
size_t len;
u_char *sig;
ASSERT_INT_EQ(sshkey_sign(k, &sig, &len, d, l, sig_alg,
NULL, NULL, 0), 0);
ASSERT_SIZE_T_GT(len, 8);
ASSERT_PTR_NE(sig, NULL);
ASSERT_INT_EQ(sshkey_verify(k, sig, len, d, l, NULL, 0, NULL), 0);
ASSERT_INT_NE(sshkey_verify(bad, sig, len, d, l, NULL, 0, NULL), 0);
/* Fuzz test is more comprehensive, this is just a smoke test */
sig[len - 5] ^= 0x10;
ASSERT_INT_NE(sshkey_verify(k, sig, len, d, l, NULL, 0, NULL), 0);
free(sig);
}
static void
banana(u_char *s, size_t l)
{
size_t o;
const u_char the_banana[] = { 'b', 'a', 'n', 'a', 'n', 'a' };
for (o = 0; o < l; o += sizeof(the_banana)) {
if (l - o < sizeof(the_banana)) {
memcpy(s + o, "nanananana", l - o);
break;
}
- memcpy(s + o, banana, sizeof(the_banana));
+ memcpy(s + o, the_banana, sizeof(the_banana));
}
}
static void
signature_tests(struct sshkey *k, struct sshkey *bad, const char *sig_alg)
{
u_char i, buf[2049];
size_t lens[] = {
1, 2, 7, 8, 9, 15, 16, 17, 31, 32, 33, 127, 128, 129,
255, 256, 257, 1023, 1024, 1025, 2047, 2048, 2049
};
for (i = 0; i < (sizeof(lens)/sizeof(lens[0])); i++) {
test_subtest_info("%s key, banana length %zu",
sshkey_type(k), lens[i]);
banana(buf, lens[i]);
signature_test(k, bad, sig_alg, buf, lens[i]);
}
}
static struct sshkey *
get_private(const char *n)
{
struct sshbuf *b;
struct sshkey *ret;
b = load_file(n);
ASSERT_INT_EQ(sshkey_parse_private_fileblob(b, "", &ret, NULL), 0);
sshbuf_free(b);
return ret;
}
void
sshkey_tests(void)
{
struct sshkey *k1, *k2, *k3, *kf;
#ifdef WITH_OPENSSL
struct sshkey *k4, *kr, *kd;
#ifdef OPENSSL_HAS_ECC
struct sshkey *ke;
#endif /* OPENSSL_HAS_ECC */
#endif /* WITH_OPENSSL */
struct sshbuf *b;
TEST_START("new invalid");
k1 = sshkey_new(-42);
ASSERT_PTR_EQ(k1, NULL);
TEST_DONE();
TEST_START("new/free KEY_UNSPEC");
k1 = sshkey_new(KEY_UNSPEC);
ASSERT_PTR_NE(k1, NULL);
sshkey_free(k1);
TEST_DONE();
#ifdef WITH_OPENSSL
TEST_START("new/free KEY_RSA");
k1 = sshkey_new(KEY_RSA);
ASSERT_PTR_NE(k1, NULL);
ASSERT_PTR_NE(k1->rsa, NULL);
sshkey_free(k1);
TEST_DONE();
TEST_START("new/free KEY_DSA");
k1 = sshkey_new(KEY_DSA);
ASSERT_PTR_NE(k1, NULL);
ASSERT_PTR_NE(k1->dsa, NULL);
sshkey_free(k1);
TEST_DONE();
#ifdef OPENSSL_HAS_ECC
TEST_START("new/free KEY_ECDSA");
k1 = sshkey_new(KEY_ECDSA);
ASSERT_PTR_NE(k1, NULL);
ASSERT_PTR_EQ(k1->ecdsa, NULL); /* Can't allocate without NID */
sshkey_free(k1);
TEST_DONE();
#endif
TEST_START("new/free KEY_ED25519");
k1 = sshkey_new(KEY_ED25519);
ASSERT_PTR_NE(k1, NULL);
/* These should be blank until key loaded or generated */
ASSERT_PTR_EQ(k1->ed25519_sk, NULL);
ASSERT_PTR_EQ(k1->ed25519_pk, NULL);
sshkey_free(k1);
TEST_DONE();
TEST_START("generate KEY_RSA too small modulus");
ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 128, &k1),
SSH_ERR_KEY_LENGTH);
ASSERT_PTR_EQ(k1, NULL);
TEST_DONE();
TEST_START("generate KEY_RSA too large modulus");
ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 1 << 20, &k1),
SSH_ERR_KEY_LENGTH);
ASSERT_PTR_EQ(k1, NULL);
TEST_DONE();
TEST_START("generate KEY_DSA wrong bits");
ASSERT_INT_EQ(sshkey_generate(KEY_DSA, 2048, &k1),
SSH_ERR_KEY_LENGTH);
ASSERT_PTR_EQ(k1, NULL);
sshkey_free(k1);
TEST_DONE();
#ifdef OPENSSL_HAS_ECC
TEST_START("generate KEY_ECDSA wrong bits");
ASSERT_INT_EQ(sshkey_generate(KEY_ECDSA, 42, &k1),
SSH_ERR_KEY_LENGTH);
ASSERT_PTR_EQ(k1, NULL);
sshkey_free(k1);
TEST_DONE();
#endif
TEST_START("generate KEY_RSA");
ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 767, &kr),
SSH_ERR_KEY_LENGTH);
ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 1024, &kr), 0);
ASSERT_PTR_NE(kr, NULL);
ASSERT_PTR_NE(kr->rsa, NULL);
ASSERT_PTR_NE(rsa_n(kr), NULL);
ASSERT_PTR_NE(rsa_e(kr), NULL);
ASSERT_PTR_NE(rsa_p(kr), NULL);
ASSERT_INT_EQ(BN_num_bits(rsa_n(kr)), 1024);
TEST_DONE();
TEST_START("generate KEY_DSA");
ASSERT_INT_EQ(sshkey_generate(KEY_DSA, 1024, &kd), 0);
ASSERT_PTR_NE(kd, NULL);
ASSERT_PTR_NE(kd->dsa, NULL);
ASSERT_PTR_NE(dsa_g(kd), NULL);
ASSERT_PTR_NE(dsa_priv_key(kd), NULL);
TEST_DONE();
#ifdef OPENSSL_HAS_ECC
TEST_START("generate KEY_ECDSA");
ASSERT_INT_EQ(sshkey_generate(KEY_ECDSA, 256, &ke), 0);
ASSERT_PTR_NE(ke, NULL);
ASSERT_PTR_NE(ke->ecdsa, NULL);
ASSERT_PTR_NE(EC_KEY_get0_public_key(ke->ecdsa), NULL);
ASSERT_PTR_NE(EC_KEY_get0_private_key(ke->ecdsa), NULL);
TEST_DONE();
#endif /* OPENSSL_HAS_ECC */
#endif /* WITH_OPENSSL */
TEST_START("generate KEY_ED25519");
ASSERT_INT_EQ(sshkey_generate(KEY_ED25519, 256, &kf), 0);
ASSERT_PTR_NE(kf, NULL);
ASSERT_INT_EQ(kf->type, KEY_ED25519);
ASSERT_PTR_NE(kf->ed25519_pk, NULL);
ASSERT_PTR_NE(kf->ed25519_sk, NULL);
TEST_DONE();
#ifdef WITH_OPENSSL
TEST_START("demote KEY_RSA");
ASSERT_INT_EQ(sshkey_from_private(kr, &k1), 0);
ASSERT_PTR_NE(k1, NULL);
ASSERT_PTR_NE(kr, k1);
ASSERT_INT_EQ(k1->type, KEY_RSA);
ASSERT_PTR_NE(k1->rsa, NULL);
ASSERT_PTR_NE(rsa_n(k1), NULL);
ASSERT_PTR_NE(rsa_e(k1), NULL);
ASSERT_PTR_EQ(rsa_p(k1), NULL);
TEST_DONE();
TEST_START("equal KEY_RSA/demoted KEY_RSA");
ASSERT_INT_EQ(sshkey_equal(kr, k1), 1);
sshkey_free(k1);
TEST_DONE();
TEST_START("demote KEY_DSA");
ASSERT_INT_EQ(sshkey_from_private(kd, &k1), 0);
ASSERT_PTR_NE(k1, NULL);
ASSERT_PTR_NE(kd, k1);
ASSERT_INT_EQ(k1->type, KEY_DSA);
ASSERT_PTR_NE(k1->dsa, NULL);
ASSERT_PTR_NE(dsa_g(k1), NULL);
ASSERT_PTR_EQ(dsa_priv_key(k1), NULL);
TEST_DONE();
TEST_START("equal KEY_DSA/demoted KEY_DSA");
ASSERT_INT_EQ(sshkey_equal(kd, k1), 1);
sshkey_free(k1);
TEST_DONE();
#ifdef OPENSSL_HAS_ECC
TEST_START("demote KEY_ECDSA");
ASSERT_INT_EQ(sshkey_from_private(ke, &k1), 0);
ASSERT_PTR_NE(k1, NULL);
ASSERT_PTR_NE(ke, k1);
ASSERT_INT_EQ(k1->type, KEY_ECDSA);
ASSERT_PTR_NE(k1->ecdsa, NULL);
ASSERT_INT_EQ(k1->ecdsa_nid, ke->ecdsa_nid);
ASSERT_PTR_NE(EC_KEY_get0_public_key(ke->ecdsa), NULL);
ASSERT_PTR_EQ(EC_KEY_get0_private_key(k1->ecdsa), NULL);
TEST_DONE();
TEST_START("equal KEY_ECDSA/demoted KEY_ECDSA");
ASSERT_INT_EQ(sshkey_equal(ke, k1), 1);
sshkey_free(k1);
TEST_DONE();
#endif /* OPENSSL_HAS_ECC */
#endif /* WITH_OPENSSL */
TEST_START("demote KEY_ED25519");
ASSERT_INT_EQ(sshkey_from_private(kf, &k1), 0);
ASSERT_PTR_NE(k1, NULL);
ASSERT_PTR_NE(kf, k1);
ASSERT_INT_EQ(k1->type, KEY_ED25519);
ASSERT_PTR_NE(k1->ed25519_pk, NULL);
ASSERT_PTR_EQ(k1->ed25519_sk, NULL);
TEST_DONE();
TEST_START("equal KEY_ED25519/demoted KEY_ED25519");
ASSERT_INT_EQ(sshkey_equal(kf, k1), 1);
sshkey_free(k1);
TEST_DONE();
#ifdef WITH_OPENSSL
TEST_START("equal mismatched key types");
ASSERT_INT_EQ(sshkey_equal(kd, kr), 0);
#ifdef OPENSSL_HAS_ECC
ASSERT_INT_EQ(sshkey_equal(kd, ke), 0);
ASSERT_INT_EQ(sshkey_equal(kr, ke), 0);
ASSERT_INT_EQ(sshkey_equal(ke, kf), 0);
#endif /* OPENSSL_HAS_ECC */
ASSERT_INT_EQ(sshkey_equal(kd, kf), 0);
TEST_DONE();
#endif /* WITH_OPENSSL */
TEST_START("equal different keys");
#ifdef WITH_OPENSSL
ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 1024, &k1), 0);
ASSERT_INT_EQ(sshkey_equal(kr, k1), 0);
sshkey_free(k1);
ASSERT_INT_EQ(sshkey_generate(KEY_DSA, 1024, &k1), 0);
ASSERT_INT_EQ(sshkey_equal(kd, k1), 0);
sshkey_free(k1);
#ifdef OPENSSL_HAS_ECC
ASSERT_INT_EQ(sshkey_generate(KEY_ECDSA, 256, &k1), 0);
ASSERT_INT_EQ(sshkey_equal(ke, k1), 0);
sshkey_free(k1);
#endif /* OPENSSL_HAS_ECC */
#endif /* WITH_OPENSSL */
ASSERT_INT_EQ(sshkey_generate(KEY_ED25519, 256, &k1), 0);
ASSERT_INT_EQ(sshkey_equal(kf, k1), 0);
sshkey_free(k1);
TEST_DONE();
#ifdef WITH_OPENSSL
sshkey_free(kr);
sshkey_free(kd);
#ifdef OPENSSL_HAS_ECC
sshkey_free(ke);
#endif /* OPENSSL_HAS_ECC */
#endif /* WITH_OPENSSL */
sshkey_free(kf);
TEST_START("certify key");
ASSERT_INT_EQ(sshkey_load_public(test_data_file("ed25519_1.pub"),
&k1, NULL), 0);
k2 = get_private("ed25519_2");
ASSERT_INT_EQ(sshkey_to_certified(k1), 0);
ASSERT_PTR_NE(k1->cert, NULL);
k1->cert->type = SSH2_CERT_TYPE_USER;
k1->cert->serial = 1234;
k1->cert->key_id = strdup("estragon");
ASSERT_PTR_NE(k1->cert->key_id, NULL);
k1->cert->principals = calloc(4, sizeof(*k1->cert->principals));
ASSERT_PTR_NE(k1->cert->principals, NULL);
k1->cert->principals[0] = strdup("estragon");
k1->cert->principals[1] = strdup("vladimir");
k1->cert->principals[2] = strdup("pozzo");
k1->cert->principals[3] = strdup("lucky");
ASSERT_PTR_NE(k1->cert->principals[0], NULL);
ASSERT_PTR_NE(k1->cert->principals[1], NULL);
ASSERT_PTR_NE(k1->cert->principals[2], NULL);
ASSERT_PTR_NE(k1->cert->principals[3], NULL);
k1->cert->nprincipals = 4;
k1->cert->valid_after = 0;
k1->cert->valid_before = (u_int64_t)-1;
sshbuf_free(k1->cert->critical);
k1->cert->critical = sshbuf_new();
ASSERT_PTR_NE(k1->cert->critical, NULL);
sshbuf_free(k1->cert->extensions);
k1->cert->extensions = sshbuf_new();
ASSERT_PTR_NE(k1->cert->extensions, NULL);
put_opt(k1->cert->critical, "force-command", "/usr/bin/true");
put_opt(k1->cert->critical, "source-address", "127.0.0.1");
put_opt(k1->cert->extensions, "permit-X11-forwarding", NULL);
put_opt(k1->cert->extensions, "permit-agent-forwarding", NULL);
ASSERT_INT_EQ(sshkey_from_private(k2, &k1->cert->signature_key), 0);
ASSERT_INT_EQ(sshkey_certify(k1, k2, NULL, NULL, NULL), 0);
b = sshbuf_new();
ASSERT_PTR_NE(b, NULL);
ASSERT_INT_EQ(sshkey_putb(k1, b), 0);
ASSERT_INT_EQ(sshkey_from_blob(sshbuf_ptr(b), sshbuf_len(b), &k3), 0);
sshkey_free(k1);
sshkey_free(k2);
sshkey_free(k3);
sshbuf_reset(b);
TEST_DONE();
#ifdef WITH_OPENSSL
TEST_START("sign and verify RSA");
k1 = get_private("rsa_1");
ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_2.pub"), &k2,
NULL), 0);
signature_tests(k1, k2, "ssh-rsa");
sshkey_free(k1);
sshkey_free(k2);
TEST_DONE();
TEST_START("sign and verify RSA-SHA256");
k1 = get_private("rsa_1");
ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_2.pub"), &k2,
NULL), 0);
signature_tests(k1, k2, "rsa-sha2-256");
sshkey_free(k1);
sshkey_free(k2);
TEST_DONE();
TEST_START("sign and verify RSA-SHA512");
k1 = get_private("rsa_1");
ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_2.pub"), &k2,
NULL), 0);
signature_tests(k1, k2, "rsa-sha2-512");
sshkey_free(k1);
sshkey_free(k2);
TEST_DONE();
TEST_START("sign and verify DSA");
k1 = get_private("dsa_1");
ASSERT_INT_EQ(sshkey_load_public(test_data_file("dsa_2.pub"), &k2,
NULL), 0);
signature_tests(k1, k2, NULL);
sshkey_free(k1);
sshkey_free(k2);
TEST_DONE();
#ifdef OPENSSL_HAS_ECC
TEST_START("sign and verify ECDSA");
k1 = get_private("ecdsa_1");
ASSERT_INT_EQ(sshkey_load_public(test_data_file("ecdsa_2.pub"), &k2,
NULL), 0);
signature_tests(k1, k2, NULL);
sshkey_free(k1);
sshkey_free(k2);
TEST_DONE();
#endif /* OPENSSL_HAS_ECC */
#endif /* WITH_OPENSSL */
TEST_START("sign and verify ED25519");
k1 = get_private("ed25519_1");
ASSERT_INT_EQ(sshkey_load_public(test_data_file("ed25519_2.pub"), &k2,
NULL), 0);
signature_tests(k1, k2, NULL);
sshkey_free(k1);
sshkey_free(k2);
TEST_DONE();
#ifdef WITH_OPENSSL
TEST_START("nested certificate");
ASSERT_INT_EQ(sshkey_load_cert(test_data_file("rsa_1"), &k1), 0);
ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_1.pub"), &k2,
NULL), 0);
k3 = get_private("rsa_1");
build_cert(b, k2, "ssh-rsa-cert-v01@openssh.com", k3, k1, NULL);
ASSERT_INT_EQ(sshkey_from_blob(sshbuf_ptr(b), sshbuf_len(b), &k4),
SSH_ERR_KEY_CERT_INVALID_SIGN_KEY);
ASSERT_PTR_EQ(k4, NULL);
sshkey_free(k1);
sshkey_free(k2);
sshkey_free(k3);
sshbuf_free(b);
TEST_DONE();
#endif /* WITH_OPENSSL */
}
diff --git a/crypto/openssh/regress/unittests/sshsig/Makefile b/crypto/openssh/regress/unittests/sshsig/Makefile
index 65564d1b278b..bc3c6c739d48 100644
--- a/crypto/openssh/regress/unittests/sshsig/Makefile
+++ b/crypto/openssh/regress/unittests/sshsig/Makefile
@@ -1,25 +1,25 @@
-# $OpenBSD: Makefile,v 1.2 2021/01/09 12:24:31 dtucker Exp $
+# $OpenBSD: Makefile,v 1.3 2023/01/15 23:35:10 djm Exp $
PROG=test_sshsig
SRCS=tests.c
# From usr.bin/ssh
SRCS+=sshbuf-getput-basic.c sshbuf-getput-crypto.c sshbuf-misc.c sshbuf.c
SRCS+=sshbuf-io.c atomicio.c sshkey.c authfile.c cipher.c log.c ssh-rsa.c
SRCS+=ssh-dss.c ssh-ecdsa.c ssh-ed25519.c mac.c umac.c umac128.c hmac.c misc.c
SRCS+=ssherr.c uidswap.c cleanup.c xmalloc.c match.c krl.c fatal.c
SRCS+=addr.c addrmatch.c bitmap.c sshsig.c
-SRCS+=ed25519.c hash.c ge25519.c fe25519.c sc25519.c verify.c
+SRCS+=ed25519.c hash.c
SRCS+=cipher-chachapoly.c chacha.c poly1305.c ssh-ecdsa-sk.c ssh-sk.c
SRCS+=ssh-ed25519-sk.c sk-usbhid.c
SRCS+=digest-openssl.c
#SRCS+=digest-libc.c
SRCS+=utf8.c
REGRESS_TARGETS=run-regress-${PROG}
run-regress-${PROG}: ${PROG}
env ${TEST_ENV} ./${PROG} ${UNITTEST_ARGS} -d ${.CURDIR}/testdata
.include <bsd.regress.mk>
diff --git a/crypto/openssh/regress/yes-head.sh b/crypto/openssh/regress/yes-head.sh
index 2759eb8ce59d..1bde504f0c71 100644
--- a/crypto/openssh/regress/yes-head.sh
+++ b/crypto/openssh/regress/yes-head.sh
@@ -1,13 +1,13 @@
-# $OpenBSD: yes-head.sh,v 1.6 2017/04/30 23:34:55 djm Exp $
+# $OpenBSD: yes-head.sh,v 1.7 2023/01/14 10:05:54 dtucker Exp $
# Placed in the Public Domain.
tid="yes pipe head"
lines=`${SSH} -F $OBJ/ssh_proxy thishost 'sh -c "while true;do echo yes;done | _POSIX2_VERSION=199209 head -2000"' | (sleep 3 ; wc -l)`
if [ $? -ne 0 ]; then
fail "yes|head test failed"
- lines = 0;
++ lines=0
fi
if [ $lines -ne 2000 ]; then
fail "yes|head returns $lines lines instead of 2000"
fi
diff --git a/crypto/openssh/sandbox-seccomp-filter.c b/crypto/openssh/sandbox-seccomp-filter.c
index 9929bdb68513..4ab49eb6e4c3 100644
--- a/crypto/openssh/sandbox-seccomp-filter.c
+++ b/crypto/openssh/sandbox-seccomp-filter.c
@@ -1,457 +1,460 @@
/*
* Copyright (c) 2012 Will Drewry <wad@dataspill.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.
*/
/*
* Uncomment the SANDBOX_SECCOMP_FILTER_DEBUG macro below to help diagnose
* filter breakage during development. *Do not* use this in production,
* as it relies on making library calls that are unsafe in signal context.
*
* Instead, live systems the auditctl(8) may be used to monitor failures.
* E.g.
* auditctl -a task,always -F uid=<privsep uid>
*/
-#define SANDBOX_SECCOMP_FILTER_DEBUG 1
+/* #define SANDBOX_SECCOMP_FILTER_DEBUG 1 */
#if 0
/*
* For older toolchains, it may be necessary to use the kernel
* headers directly.
*/
#ifdef SANDBOX_SECCOMP_FILTER_DEBUG
# include <asm/siginfo.h>
# define __have_siginfo_t 1
# define __have_sigval_t 1
# define __have_sigevent_t 1
#endif /* SANDBOX_SECCOMP_FILTER_DEBUG */
#endif
#include "includes.h"
#ifdef SANDBOX_SECCOMP_FILTER
#include <sys/types.h>
#include <sys/resource.h>
#include <sys/prctl.h>
#include <sys/mman.h>
#include <sys/syscall.h>
#include <linux/net.h>
#include <linux/audit.h>
#include <linux/filter.h>
#include <linux/seccomp.h>
#include <elf.h>
#include <asm/unistd.h>
#ifdef __s390__
#include <asm/zcrypt.h>
#endif
#include <errno.h>
#include <signal.h>
#include <stdarg.h>
#include <stddef.h> /* for offsetof */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "log.h"
#include "ssh-sandbox.h"
#include "xmalloc.h"
/* Linux seccomp_filter sandbox */
#define SECCOMP_FILTER_FAIL SECCOMP_RET_KILL
/* Use a signal handler to emit violations when debugging */
#ifdef SANDBOX_SECCOMP_FILTER_DEBUG
# undef SECCOMP_FILTER_FAIL
# define SECCOMP_FILTER_FAIL SECCOMP_RET_TRAP
#endif /* SANDBOX_SECCOMP_FILTER_DEBUG */
#if __BYTE_ORDER == __LITTLE_ENDIAN
# define ARG_LO_OFFSET 0
# define ARG_HI_OFFSET sizeof(uint32_t)
#elif __BYTE_ORDER == __BIG_ENDIAN
# define ARG_LO_OFFSET sizeof(uint32_t)
# define ARG_HI_OFFSET 0
#else
#error "Unknown endianness"
#endif
/* Simple helpers to avoid manual errors (but larger BPF programs). */
#define SC_DENY(_nr, _errno) \
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (_nr), 0, 1), \
BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ERRNO|(_errno))
#define SC_ALLOW(_nr) \
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (_nr), 0, 1), \
BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW)
#define SC_ALLOW_ARG(_nr, _arg_nr, _arg_val) \
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (_nr), 0, 6), \
/* load and test syscall argument, low word */ \
BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \
offsetof(struct seccomp_data, args[(_arg_nr)]) + ARG_LO_OFFSET), \
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, \
((_arg_val) & 0xFFFFFFFF), 0, 3), \
/* load and test syscall argument, high word */ \
BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \
offsetof(struct seccomp_data, args[(_arg_nr)]) + ARG_HI_OFFSET), \
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, \
(((uint32_t)((uint64_t)(_arg_val) >> 32)) & 0xFFFFFFFF), 0, 1), \
BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW), \
/* reload syscall number; all rules expect it in accumulator */ \
BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \
offsetof(struct seccomp_data, nr))
/* Allow if syscall argument contains only values in mask */
#define SC_ALLOW_ARG_MASK(_nr, _arg_nr, _arg_mask) \
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (_nr), 0, 8), \
/* load, mask and test syscall argument, low word */ \
BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \
offsetof(struct seccomp_data, args[(_arg_nr)]) + ARG_LO_OFFSET), \
BPF_STMT(BPF_ALU+BPF_AND+BPF_K, ~((_arg_mask) & 0xFFFFFFFF)), \
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0, 0, 4), \
/* load, mask and test syscall argument, high word */ \
BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \
offsetof(struct seccomp_data, args[(_arg_nr)]) + ARG_HI_OFFSET), \
BPF_STMT(BPF_ALU+BPF_AND+BPF_K, \
~(((uint32_t)((uint64_t)(_arg_mask) >> 32)) & 0xFFFFFFFF)), \
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0, 0, 1), \
BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW), \
/* reload syscall number; all rules expect it in accumulator */ \
BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \
offsetof(struct seccomp_data, nr))
/* Syscall filtering set for preauth. */
static const struct sock_filter preauth_insns[] = {
/* Ensure the syscall arch convention is as expected. */
BPF_STMT(BPF_LD+BPF_W+BPF_ABS,
offsetof(struct seccomp_data, arch)),
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, SECCOMP_AUDIT_ARCH, 1, 0),
BPF_STMT(BPF_RET+BPF_K, SECCOMP_FILTER_FAIL),
/* Load the syscall number for checking. */
BPF_STMT(BPF_LD+BPF_W+BPF_ABS,
offsetof(struct seccomp_data, nr)),
/* Syscalls to non-fatally deny */
#ifdef __NR_lstat
SC_DENY(__NR_lstat, EACCES),
#endif
#ifdef __NR_lstat64
SC_DENY(__NR_lstat64, EACCES),
#endif
#ifdef __NR_fstat
SC_DENY(__NR_fstat, EACCES),
#endif
#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
#ifdef __NR_openat
SC_DENY(__NR_openat, EACCES),
#endif
#ifdef __NR_newfstatat
SC_DENY(__NR_newfstatat, EACCES),
#endif
#ifdef __NR_stat
SC_DENY(__NR_stat, EACCES),
#endif
#ifdef __NR_stat64
SC_DENY(__NR_stat64, EACCES),
#endif
#ifdef __NR_shmget
SC_DENY(__NR_shmget, EACCES),
#endif
#ifdef __NR_shmat
SC_DENY(__NR_shmat, EACCES),
#endif
#ifdef __NR_shmdt
SC_DENY(__NR_shmdt, EACCES),
#endif
#ifdef __NR_ipc
SC_DENY(__NR_ipc, EACCES),
#endif
#ifdef __NR_statx
SC_DENY(__NR_statx, EACCES),
#endif
/* Syscalls to permit */
#ifdef __NR_brk
SC_ALLOW(__NR_brk),
#endif
#ifdef __NR_clock_gettime
SC_ALLOW(__NR_clock_gettime),
#endif
#ifdef __NR_clock_gettime64
SC_ALLOW(__NR_clock_gettime64),
#endif
#ifdef __NR_close
SC_ALLOW(__NR_close),
#endif
#ifdef __NR_exit
SC_ALLOW(__NR_exit),
#endif
#ifdef __NR_exit_group
SC_ALLOW(__NR_exit_group),
#endif
#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
#ifdef __NR_geteuid32
SC_ALLOW(__NR_geteuid32),
#endif
#ifdef __NR_getpgid
SC_ALLOW(__NR_getpgid),
#endif
#ifdef __NR_getpid
SC_ALLOW(__NR_getpid),
#endif
#ifdef __NR_getrandom
SC_ALLOW(__NR_getrandom),
#endif
#ifdef __NR_gettid
SC_ALLOW(__NR_gettid),
#endif
#ifdef __NR_gettimeofday
SC_ALLOW(__NR_gettimeofday),
#endif
#ifdef __NR_getuid
SC_ALLOW(__NR_getuid),
#endif
#ifdef __NR_getuid32
SC_ALLOW(__NR_getuid32),
#endif
#ifdef __NR_madvise
SC_ALLOW(__NR_madvise),
#endif
#ifdef __NR_mmap
SC_ALLOW_ARG_MASK(__NR_mmap, 2, PROT_READ|PROT_WRITE|PROT_NONE),
#endif
#ifdef __NR_mmap2
SC_ALLOW_ARG_MASK(__NR_mmap2, 2, PROT_READ|PROT_WRITE|PROT_NONE),
#endif
#ifdef __NR_mprotect
SC_ALLOW_ARG_MASK(__NR_mprotect, 2, PROT_READ|PROT_WRITE|PROT_NONE),
#endif
#ifdef __NR_mremap
SC_ALLOW(__NR_mremap),
#endif
#ifdef __NR_munmap
SC_ALLOW(__NR_munmap),
#endif
#ifdef __NR_nanosleep
SC_ALLOW(__NR_nanosleep),
#endif
#ifdef __NR_clock_nanosleep
SC_ALLOW(__NR_clock_nanosleep),
#endif
#ifdef __NR_clock_nanosleep_time64
SC_ALLOW(__NR_clock_nanosleep_time64),
#endif
#ifdef __NR_clock_gettime64
SC_ALLOW(__NR_clock_gettime64),
#endif
#ifdef __NR__newselect
SC_ALLOW(__NR__newselect),
#endif
#ifdef __NR_ppoll
SC_ALLOW(__NR_ppoll),
#endif
#ifdef __NR_ppoll_time64
SC_ALLOW(__NR_ppoll_time64),
#endif
#ifdef __NR_poll
SC_ALLOW(__NR_poll),
#endif
#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
#ifdef __NR_rt_sigprocmask
SC_ALLOW(__NR_rt_sigprocmask),
#endif
#ifdef __NR_select
SC_ALLOW(__NR_select),
#endif
#ifdef __NR_shutdown
SC_ALLOW(__NR_shutdown),
#endif
#ifdef __NR_sigprocmask
SC_ALLOW(__NR_sigprocmask),
#endif
#ifdef __NR_time
SC_ALLOW(__NR_time),
#endif
#ifdef __NR_write
SC_ALLOW(__NR_write),
#endif
+#ifdef __NR_writev
+ SC_ALLOW(__NR_writev),
+#endif
#ifdef __NR_socketcall
SC_ALLOW_ARG(__NR_socketcall, 0, SYS_SHUTDOWN),
SC_DENY(__NR_socketcall, EACCES),
#endif
#if defined(__NR_ioctl) && defined(__s390__)
/* Allow ioctls for ICA crypto card on s390 */
SC_ALLOW_ARG(__NR_ioctl, 1, Z90STAT_STATUS_MASK),
SC_ALLOW_ARG(__NR_ioctl, 1, ICARSAMODEXPO),
SC_ALLOW_ARG(__NR_ioctl, 1, ICARSACRT),
SC_ALLOW_ARG(__NR_ioctl, 1, ZSECSENDCPRB),
/* Allow ioctls for EP11 crypto card on s390 */
SC_ALLOW_ARG(__NR_ioctl, 1, ZSENDEP11CPRB),
#endif
#if defined(__x86_64__) && defined(__ILP32__) && defined(__X32_SYSCALL_BIT)
/*
* On Linux x32, the clock_gettime VDSO falls back to the
* x86-64 syscall under some circumstances, e.g.
* https://bugs.debian.org/849923
*/
SC_ALLOW(__NR_clock_gettime & ~__X32_SYSCALL_BIT),
#endif
/* Default deny */
BPF_STMT(BPF_RET+BPF_K, SECCOMP_FILTER_FAIL),
};
static const struct sock_fprog preauth_program = {
.len = (unsigned short)(sizeof(preauth_insns)/sizeof(preauth_insns[0])),
.filter = (struct sock_filter *)preauth_insns,
};
struct ssh_sandbox {
pid_t child_pid;
};
struct ssh_sandbox *
ssh_sandbox_init(struct monitor *monitor)
{
struct ssh_sandbox *box;
/*
* Strictly, we don't need to maintain any state here but we need
* to return non-NULL to satisfy the API.
*/
debug3("%s: preparing seccomp filter sandbox", __func__);
box = xcalloc(1, sizeof(*box));
box->child_pid = 0;
return box;
}
#ifdef SANDBOX_SECCOMP_FILTER_DEBUG
extern struct monitor *pmonitor;
void mm_log_handler(LogLevel level, int forced, const char *msg, void *ctx);
static void
ssh_sandbox_violation(int signum, siginfo_t *info, void *void_context)
{
char msg[256];
snprintf(msg, sizeof(msg),
"%s: unexpected system call (arch:0x%x,syscall:%d @ %p)",
__func__, info->si_arch, info->si_syscall, info->si_call_addr);
mm_log_handler(SYSLOG_LEVEL_FATAL, 0, msg, pmonitor);
_exit(1);
}
static void
ssh_sandbox_child_debugging(void)
{
struct sigaction act;
sigset_t mask;
debug3("%s: installing SIGSYS handler", __func__);
memset(&act, 0, sizeof(act));
sigemptyset(&mask);
sigaddset(&mask, SIGSYS);
act.sa_sigaction = &ssh_sandbox_violation;
act.sa_flags = SA_SIGINFO;
if (sigaction(SIGSYS, &act, NULL) == -1)
fatal("%s: sigaction(SIGSYS): %s", __func__, strerror(errno));
if (sigprocmask(SIG_UNBLOCK, &mask, NULL) == -1)
fatal("%s: sigprocmask(SIGSYS): %s",
__func__, strerror(errno));
}
#endif /* SANDBOX_SECCOMP_FILTER_DEBUG */
void
ssh_sandbox_child(struct ssh_sandbox *box)
{
struct rlimit rl_zero, rl_one = {.rlim_cur = 1, .rlim_max = 1};
int nnp_failed = 0;
/* Set rlimits for completeness if possible. */
rl_zero.rlim_cur = rl_zero.rlim_max = 0;
if (setrlimit(RLIMIT_FSIZE, &rl_zero) == -1)
fatal("%s: setrlimit(RLIMIT_FSIZE, { 0, 0 }): %s",
__func__, strerror(errno));
/*
* Cannot use zero for nfds, because poll(2) will fail with
* errno=EINVAL if npfds>RLIMIT_NOFILE.
*/
if (setrlimit(RLIMIT_NOFILE, &rl_one) == -1)
fatal("%s: setrlimit(RLIMIT_NOFILE, { 0, 0 }): %s",
__func__, strerror(errno));
if (setrlimit(RLIMIT_NPROC, &rl_zero) == -1)
fatal("%s: setrlimit(RLIMIT_NPROC, { 0, 0 }): %s",
__func__, strerror(errno));
#ifdef SANDBOX_SECCOMP_FILTER_DEBUG
ssh_sandbox_child_debugging();
#endif /* SANDBOX_SECCOMP_FILTER_DEBUG */
debug3("%s: setting PR_SET_NO_NEW_PRIVS", __func__);
if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) == -1) {
debug("%s: prctl(PR_SET_NO_NEW_PRIVS): %s",
__func__, strerror(errno));
nnp_failed = 1;
}
debug3("%s: attaching seccomp filter program", __func__);
if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &preauth_program) == -1)
debug("%s: prctl(PR_SET_SECCOMP): %s",
__func__, strerror(errno));
else if (nnp_failed)
fatal("%s: SECCOMP_MODE_FILTER activated but "
"PR_SET_NO_NEW_PRIVS failed", __func__);
}
void
ssh_sandbox_parent_finish(struct ssh_sandbox *box)
{
free(box);
debug3("%s: finished", __func__);
}
void
ssh_sandbox_parent_preauth(struct ssh_sandbox *box, pid_t child_pid)
{
box->child_pid = child_pid;
}
#endif /* SANDBOX_SECCOMP_FILTER */
diff --git a/crypto/openssh/sc25519.c b/crypto/openssh/sc25519.c
deleted file mode 100644
index 1568d9a58c98..000000000000
--- a/crypto/openssh/sc25519.c
+++ /dev/null
@@ -1,308 +0,0 @@
-/* $OpenBSD: sc25519.c,v 1.3 2013/12/09 11:03:45 markus Exp $ */
-
-/*
- * Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange,
- * Peter Schwabe, Bo-Yin Yang.
- * Copied from supercop-20130419/crypto_sign/ed25519/ref/sc25519.c
- */
-
-#include "includes.h"
-
-#include "sc25519.h"
-
-/*Arithmetic modulo the group order m = 2^252 + 27742317777372353535851937790883648493 = 7237005577332262213973186563042994240857116359379907606001950938285454250989 */
-
-static const crypto_uint32 m[32] = {0xED, 0xD3, 0xF5, 0x5C, 0x1A, 0x63, 0x12, 0x58, 0xD6, 0x9C, 0xF7, 0xA2, 0xDE, 0xF9, 0xDE, 0x14,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
-
-static const crypto_uint32 mu[33] = {0x1B, 0x13, 0x2C, 0x0A, 0xA3, 0xE5, 0x9C, 0xED, 0xA7, 0x29, 0x63, 0x08, 0x5D, 0x21, 0x06, 0x21,
- 0xEB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F};
-
-static crypto_uint32 lt(crypto_uint32 a,crypto_uint32 b) /* 16-bit inputs */
-{
- unsigned int x = a;
- x -= (unsigned int) b; /* 0..65535: no; 4294901761..4294967295: yes */
- x >>= 31; /* 0: no; 1: yes */
- return x;
-}
-
-/* Reduce coefficients of r before calling reduce_add_sub */
-static void reduce_add_sub(sc25519 *r)
-{
- crypto_uint32 pb = 0;
- crypto_uint32 b;
- crypto_uint32 mask;
- int i;
- unsigned char t[32];
-
- for(i=0;i<32;i++)
- {
- pb += m[i];
- b = lt(r->v[i],pb);
- t[i] = r->v[i]-pb+(b<<8);
- pb = b;
- }
- mask = b - 1;
- for(i=0;i<32;i++)
- r->v[i] ^= mask & (r->v[i] ^ t[i]);
-}
-
-/* Reduce coefficients of x before calling barrett_reduce */
-static void barrett_reduce(sc25519 *r, const crypto_uint32 x[64])
-{
- /* See HAC, Alg. 14.42 */
- int i,j;
- crypto_uint32 q2[66];
- crypto_uint32 *q3 = q2 + 33;
- crypto_uint32 r1[33];
- crypto_uint32 r2[33];
- crypto_uint32 carry;
- crypto_uint32 pb = 0;
- crypto_uint32 b;
-
- for (i = 0;i < 66;++i) q2[i] = 0;
- for (i = 0;i < 33;++i) r2[i] = 0;
-
- for(i=0;i<33;i++)
- for(j=0;j<33;j++)
- if(i+j >= 31) q2[i+j] += mu[i]*x[j+31];
- carry = q2[31] >> 8;
- q2[32] += carry;
- carry = q2[32] >> 8;
- q2[33] += carry;
-
- for(i=0;i<33;i++)r1[i] = x[i];
- for(i=0;i<32;i++)
- for(j=0;j<33;j++)
- if(i+j < 33) r2[i+j] += m[i]*q3[j];
-
- for(i=0;i<32;i++)
- {
- carry = r2[i] >> 8;
- r2[i+1] += carry;
- r2[i] &= 0xff;
- }
-
- for(i=0;i<32;i++)
- {
- pb += r2[i];
- b = lt(r1[i],pb);
- r->v[i] = r1[i]-pb+(b<<8);
- pb = b;
- }
-
- /* XXX: Can it really happen that r<0?, See HAC, Alg 14.42, Step 3
- * If so: Handle it here!
- */
-
- reduce_add_sub(r);
- reduce_add_sub(r);
-}
-
-void sc25519_from32bytes(sc25519 *r, const unsigned char x[32])
-{
- int i;
- crypto_uint32 t[64];
- for(i=0;i<32;i++) t[i] = x[i];
- for(i=32;i<64;++i) t[i] = 0;
- barrett_reduce(r, t);
-}
-
-void shortsc25519_from16bytes(shortsc25519 *r, const unsigned char x[16])
-{
- int i;
- for(i=0;i<16;i++) r->v[i] = x[i];
-}
-
-void sc25519_from64bytes(sc25519 *r, const unsigned char x[64])
-{
- int i;
- crypto_uint32 t[64];
- for(i=0;i<64;i++) t[i] = x[i];
- barrett_reduce(r, t);
-}
-
-void sc25519_from_shortsc(sc25519 *r, const shortsc25519 *x)
-{
- int i;
- for(i=0;i<16;i++)
- r->v[i] = x->v[i];
- for(i=0;i<16;i++)
- r->v[16+i] = 0;
-}
-
-void sc25519_to32bytes(unsigned char r[32], const sc25519 *x)
-{
- int i;
- for(i=0;i<32;i++) r[i] = x->v[i];
-}
-
-int sc25519_iszero_vartime(const sc25519 *x)
-{
- int i;
- for(i=0;i<32;i++)
- if(x->v[i] != 0) return 0;
- return 1;
-}
-
-int sc25519_isshort_vartime(const sc25519 *x)
-{
- int i;
- for(i=31;i>15;i--)
- if(x->v[i] != 0) return 0;
- return 1;
-}
-
-int sc25519_lt_vartime(const sc25519 *x, const sc25519 *y)
-{
- int i;
- for(i=31;i>=0;i--)
- {
- if(x->v[i] < y->v[i]) return 1;
- if(x->v[i] > y->v[i]) return 0;
- }
- return 0;
-}
-
-void sc25519_add(sc25519 *r, const sc25519 *x, const sc25519 *y)
-{
- int i, carry;
- for(i=0;i<32;i++) r->v[i] = x->v[i] + y->v[i];
- for(i=0;i<31;i++)
- {
- carry = r->v[i] >> 8;
- r->v[i+1] += carry;
- r->v[i] &= 0xff;
- }
- reduce_add_sub(r);
-}
-
-void sc25519_sub_nored(sc25519 *r, const sc25519 *x, const sc25519 *y)
-{
- crypto_uint32 b = 0;
- crypto_uint32 t;
- int i;
- for(i=0;i<32;i++)
- {
- t = x->v[i] - y->v[i] - b;
- r->v[i] = t & 255;
- b = (t >> 8) & 1;
- }
-}
-
-void sc25519_mul(sc25519 *r, const sc25519 *x, const sc25519 *y)
-{
- int i,j,carry;
- crypto_uint32 t[64];
- for(i=0;i<64;i++)t[i] = 0;
-
- for(i=0;i<32;i++)
- for(j=0;j<32;j++)
- t[i+j] += x->v[i] * y->v[j];
-
- /* Reduce coefficients */
- for(i=0;i<63;i++)
- {
- carry = t[i] >> 8;
- t[i+1] += carry;
- t[i] &= 0xff;
- }
-
- barrett_reduce(r, t);
-}
-
-void sc25519_mul_shortsc(sc25519 *r, const sc25519 *x, const shortsc25519 *y)
-{
- sc25519 t;
- sc25519_from_shortsc(&t, y);
- sc25519_mul(r, x, &t);
-}
-
-void sc25519_window3(signed char r[85], const sc25519 *s)
-{
- char carry;
- int i;
- for(i=0;i<10;i++)
- {
- r[8*i+0] = s->v[3*i+0] & 7;
- r[8*i+1] = (s->v[3*i+0] >> 3) & 7;
- r[8*i+2] = (s->v[3*i+0] >> 6) & 7;
- r[8*i+2] ^= (s->v[3*i+1] << 2) & 7;
- r[8*i+3] = (s->v[3*i+1] >> 1) & 7;
- r[8*i+4] = (s->v[3*i+1] >> 4) & 7;
- r[8*i+5] = (s->v[3*i+1] >> 7) & 7;
- r[8*i+5] ^= (s->v[3*i+2] << 1) & 7;
- r[8*i+6] = (s->v[3*i+2] >> 2) & 7;
- r[8*i+7] = (s->v[3*i+2] >> 5) & 7;
- }
- r[8*i+0] = s->v[3*i+0] & 7;
- r[8*i+1] = (s->v[3*i+0] >> 3) & 7;
- r[8*i+2] = (s->v[3*i+0] >> 6) & 7;
- r[8*i+2] ^= (s->v[3*i+1] << 2) & 7;
- r[8*i+3] = (s->v[3*i+1] >> 1) & 7;
- r[8*i+4] = (s->v[3*i+1] >> 4) & 7;
-
- /* Making it signed */
- carry = 0;
- for(i=0;i<84;i++)
- {
- r[i] += carry;
- r[i+1] += r[i] >> 3;
- r[i] &= 7;
- carry = r[i] >> 2;
- r[i] -= carry<<3;
- }
- r[84] += carry;
-}
-
-void sc25519_window5(signed char r[51], const sc25519 *s)
-{
- char carry;
- int i;
- for(i=0;i<6;i++)
- {
- r[8*i+0] = s->v[5*i+0] & 31;
- r[8*i+1] = (s->v[5*i+0] >> 5) & 31;
- r[8*i+1] ^= (s->v[5*i+1] << 3) & 31;
- r[8*i+2] = (s->v[5*i+1] >> 2) & 31;
- r[8*i+3] = (s->v[5*i+1] >> 7) & 31;
- r[8*i+3] ^= (s->v[5*i+2] << 1) & 31;
- r[8*i+4] = (s->v[5*i+2] >> 4) & 31;
- r[8*i+4] ^= (s->v[5*i+3] << 4) & 31;
- r[8*i+5] = (s->v[5*i+3] >> 1) & 31;
- r[8*i+6] = (s->v[5*i+3] >> 6) & 31;
- r[8*i+6] ^= (s->v[5*i+4] << 2) & 31;
- r[8*i+7] = (s->v[5*i+4] >> 3) & 31;
- }
- r[8*i+0] = s->v[5*i+0] & 31;
- r[8*i+1] = (s->v[5*i+0] >> 5) & 31;
- r[8*i+1] ^= (s->v[5*i+1] << 3) & 31;
- r[8*i+2] = (s->v[5*i+1] >> 2) & 31;
-
- /* Making it signed */
- carry = 0;
- for(i=0;i<50;i++)
- {
- r[i] += carry;
- r[i+1] += r[i] >> 5;
- r[i] &= 31;
- carry = r[i] >> 4;
- r[i] -= carry<<5;
- }
- r[50] += carry;
-}
-
-void sc25519_2interleave2(unsigned char r[127], const sc25519 *s1, const sc25519 *s2)
-{
- int i;
- for(i=0;i<31;i++)
- {
- r[4*i] = ( s1->v[i] & 3) ^ (( s2->v[i] & 3) << 2);
- r[4*i+1] = ((s1->v[i] >> 2) & 3) ^ (((s2->v[i] >> 2) & 3) << 2);
- r[4*i+2] = ((s1->v[i] >> 4) & 3) ^ (((s2->v[i] >> 4) & 3) << 2);
- r[4*i+3] = ((s1->v[i] >> 6) & 3) ^ (((s2->v[i] >> 6) & 3) << 2);
- }
- r[124] = ( s1->v[31] & 3) ^ (( s2->v[31] & 3) << 2);
- r[125] = ((s1->v[31] >> 2) & 3) ^ (((s2->v[31] >> 2) & 3) << 2);
- r[126] = ((s1->v[31] >> 4) & 3) ^ (((s2->v[31] >> 4) & 3) << 2);
-}
diff --git a/crypto/openssh/sc25519.h b/crypto/openssh/sc25519.h
deleted file mode 100644
index a2c15d5ff996..000000000000
--- a/crypto/openssh/sc25519.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/* $OpenBSD: sc25519.h,v 1.3 2013/12/09 11:03:45 markus Exp $ */
-
-/*
- * Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange,
- * Peter Schwabe, Bo-Yin Yang.
- * Copied from supercop-20130419/crypto_sign/ed25519/ref/sc25519.h
- */
-
-#ifndef SC25519_H
-#define SC25519_H
-
-#include "crypto_api.h"
-
-#define sc25519 crypto_sign_ed25519_ref_sc25519
-#define shortsc25519 crypto_sign_ed25519_ref_shortsc25519
-#define sc25519_from32bytes crypto_sign_ed25519_ref_sc25519_from32bytes
-#define shortsc25519_from16bytes crypto_sign_ed25519_ref_shortsc25519_from16bytes
-#define sc25519_from64bytes crypto_sign_ed25519_ref_sc25519_from64bytes
-#define sc25519_from_shortsc crypto_sign_ed25519_ref_sc25519_from_shortsc
-#define sc25519_to32bytes crypto_sign_ed25519_ref_sc25519_to32bytes
-#define sc25519_iszero_vartime crypto_sign_ed25519_ref_sc25519_iszero_vartime
-#define sc25519_isshort_vartime crypto_sign_ed25519_ref_sc25519_isshort_vartime
-#define sc25519_lt_vartime crypto_sign_ed25519_ref_sc25519_lt_vartime
-#define sc25519_add crypto_sign_ed25519_ref_sc25519_add
-#define sc25519_sub_nored crypto_sign_ed25519_ref_sc25519_sub_nored
-#define sc25519_mul crypto_sign_ed25519_ref_sc25519_mul
-#define sc25519_mul_shortsc crypto_sign_ed25519_ref_sc25519_mul_shortsc
-#define sc25519_window3 crypto_sign_ed25519_ref_sc25519_window3
-#define sc25519_window5 crypto_sign_ed25519_ref_sc25519_window5
-#define sc25519_2interleave2 crypto_sign_ed25519_ref_sc25519_2interleave2
-
-typedef struct
-{
- crypto_uint32 v[32];
-}
-sc25519;
-
-typedef struct
-{
- crypto_uint32 v[16];
-}
-shortsc25519;
-
-void sc25519_from32bytes(sc25519 *r, const unsigned char x[32]);
-
-void shortsc25519_from16bytes(shortsc25519 *r, const unsigned char x[16]);
-
-void sc25519_from64bytes(sc25519 *r, const unsigned char x[64]);
-
-void sc25519_from_shortsc(sc25519 *r, const shortsc25519 *x);
-
-void sc25519_to32bytes(unsigned char r[32], const sc25519 *x);
-
-int sc25519_iszero_vartime(const sc25519 *x);
-
-int sc25519_isshort_vartime(const sc25519 *x);
-
-int sc25519_lt_vartime(const sc25519 *x, const sc25519 *y);
-
-void sc25519_add(sc25519 *r, const sc25519 *x, const sc25519 *y);
-
-void sc25519_sub_nored(sc25519 *r, const sc25519 *x, const sc25519 *y);
-
-void sc25519_mul(sc25519 *r, const sc25519 *x, const sc25519 *y);
-
-void sc25519_mul_shortsc(sc25519 *r, const sc25519 *x, const shortsc25519 *y);
-
-/* Convert s into a representation of the form \sum_{i=0}^{84}r[i]2^3
- * with r[i] in {-4,...,3}
- */
-void sc25519_window3(signed char r[85], const sc25519 *s);
-
-/* Convert s into a representation of the form \sum_{i=0}^{50}r[i]2^5
- * with r[i] in {-16,...,15}
- */
-void sc25519_window5(signed char r[51], const sc25519 *s);
-
-void sc25519_2interleave2(unsigned char r[127], const sc25519 *s1, const sc25519 *s2);
-
-#endif
diff --git a/crypto/openssh/scp.1 b/crypto/openssh/scp.1
index 7b8c527d4afb..a89c65660a72 100644
--- a/crypto/openssh/scp.1
+++ b/crypto/openssh/scp.1
@@ -1,308 +1,321 @@
.\"
.\" scp.1
.\"
.\" Author: Tatu Ylonen <ylo@cs.hut.fi>
.\"
.\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
.\" All rights reserved
.\"
.\" Created: Sun May 7 00:14:37 1995 ylo
.\"
-.\" $OpenBSD: scp.1,v 1.110 2022/09/19 21:39:16 djm Exp $
+.\" $OpenBSD: scp.1,v 1.112 2022/12/16 07:13:22 djm Exp $
.\"
-.Dd $Mdocdate: September 19 2022 $
+.Dd $Mdocdate: December 16 2022 $
.Dt SCP 1
.Os
.Sh NAME
.Nm scp
.Nd OpenSSH secure file copy
.Sh SYNOPSIS
.Nm scp
.Op Fl 346ABCOpqRrsTv
.Op Fl c Ar cipher
.Op Fl D Ar sftp_server_path
.Op Fl F Ar ssh_config
.Op Fl i Ar identity_file
.Op Fl J Ar destination
.Op Fl l Ar limit
.Op Fl o Ar ssh_option
.Op Fl P Ar port
.Op Fl S Ar program
+.Op Fl X Ar sftp_option
.Ar source ... target
.Sh DESCRIPTION
.Nm
copies files between hosts on a network.
.Pp
-It uses
+.Nm
+uses the SFTP protocol over a
.Xr ssh 1
-for data transfer, and uses the same authentication and provides the
-same security as a login session.
+connection for data transfer, and uses the same authentication and provides
+the same security as a login session.
.Pp
.Nm
will ask for passwords or passphrases if they are needed for
authentication.
.Pp
The
.Ar source
and
.Ar target
may be specified as a local pathname, a remote host with optional path
in the form
.Sm off
.Oo user @ Oc host : Op path ,
.Sm on
or a URI in the form
.Sm off
.No scp:// Oo user @ Oc host Oo : port Oc Op / path .
.Sm on
Local file names can be made explicit using absolute or relative pathnames
to avoid
.Nm
treating file names containing
.Sq :\&
as host specifiers.
.Pp
When copying between two remote hosts, if the URI format is used, a
.Ar port
cannot be specified on the
.Ar target
if the
.Fl R
option is used.
.Pp
The options are as follows:
.Bl -tag -width Ds
.It Fl 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, when using the original 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
to use IPv4 addresses only.
.It Fl 6
Forces
.Nm
to use IPv6 addresses only.
.It Fl A
Allows forwarding of
.Xr ssh-agent 1
to the remote system.
The default is not to forward an authentication agent.
.It Fl B
Selects batch mode (prevents asking for passwords or passphrases).
.It Fl C
Compression enable.
Passes the
.Fl C
flag to
.Xr ssh 1
to enable compression.
.It Fl c Ar cipher
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 s ,
-connect directly to a local SFTP server program rather than a
+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
.Nm ssh .
This option is directly passed to
.Xr ssh 1 .
.It Fl i Ar identity_file
Selects the file from which the identity (private key) for public key
authentication is read.
This option is directly passed to
.Xr ssh 1 .
.It Fl J Ar destination
Connect to the target host by first making an
.Nm
connection to the jump host described by
.Ar destination
and then establishing a TCP forwarding to the ultimate destination from
there.
Multiple jump hops may be specified separated by comma characters.
This is a shortcut to specify a
.Cm ProxyJump
configuration directive.
This option is directly passed to
.Xr ssh 1 .
.It Fl l Ar limit
Limits the used bandwidth, specified in Kbit/s.
.It Fl O
Use the original 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, for backwards-compatibility for particular filename
wildcard patterns and for expanding paths with a
.Sq ~
prefix for older SFTP servers.
This mode is the default.
.It Fl o Ar ssh_option
Can be used to pass options to
.Nm ssh
in the format used in
.Xr ssh_config 5 .
This is useful for specifying options
for which there is no separate
.Nm scp
command-line flag.
For full details of the options listed below, and their possible values, see
.Xr ssh_config 5 .
.Pp
.Bl -tag -width Ds -offset indent -compact
.It AddressFamily
.It BatchMode
.It BindAddress
.It BindInterface
.It CanonicalDomains
.It CanonicalizeFallbackLocal
.It CanonicalizeHostname
.It CanonicalizeMaxDots
.It CanonicalizePermittedCNAMEs
.It CASignatureAlgorithms
.It CertificateFile
.It CheckHostIP
.It Ciphers
.It Compression
.It ConnectionAttempts
.It ConnectTimeout
.It ControlMaster
.It ControlPath
.It ControlPersist
.It GlobalKnownHostsFile
.It GSSAPIAuthentication
.It GSSAPIDelegateCredentials
.It HashKnownHosts
.It Host
.It HostbasedAcceptedAlgorithms
.It HostbasedAuthentication
.It HostKeyAlgorithms
.It HostKeyAlias
.It Hostname
.It IdentitiesOnly
.It IdentityAgent
.It IdentityFile
.It IPQoS
.It KbdInteractiveAuthentication
.It KbdInteractiveDevices
.It KexAlgorithms
.It KnownHostsCommand
.It LogLevel
.It MACs
.It NoHostAuthenticationForLocalhost
.It NumberOfPasswordPrompts
.It PasswordAuthentication
.It PKCS11Provider
.It Port
.It PreferredAuthentications
.It ProxyCommand
.It ProxyJump
.It PubkeyAcceptedAlgorithms
.It PubkeyAuthentication
.It RekeyLimit
.It RequiredRSASize
.It SendEnv
.It ServerAliveInterval
.It ServerAliveCountMax
.It SetEnv
.It StrictHostKeyChecking
.It TCPKeepAlive
.It UpdateHostKeys
.It User
.It UserKnownHostsFile
.It VerifyHostKeyDNS
.El
.It Fl P Ar port
Specifies the port to connect to on the remote host.
Note that this option is written with a capital
.Sq P ,
because
.Fl p
is already reserved for preserving the times and mode bits of the file.
.It Fl p
Preserves modification times, access times, and file mode bits from the
source file.
.It Fl q
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
.Nm
follows symbolic links encountered in the tree traversal.
.It Fl S Ar program
Name of
.Ar program
to use for the encrypted connection.
The program must understand
.Xr ssh 1
options.
.It Fl s
Use the SFTP protocol for transfers rather than the original scp protocol.
.It Fl T
Disable strict filename checking.
By default when copying files from a remote host to a local directory
.Nm
checks that the received filenames match those requested on the command-line
to prevent the remote end from sending unexpected or unwanted files.
Because of differences in how various operating systems and shells interpret
filename wildcards, these checks may cause wanted files to be rejected.
This option disables these checks at the expense of fully trusting that
the server will not send unexpected filenames.
.It Fl v
Verbose mode.
Causes
.Nm
and
.Xr ssh 1
to print debugging messages about their progress.
This is helpful in
debugging connection, authentication, and configuration problems.
+.It Fl X Ar sftp_option
+Specify an option that controls aspects of SFTP protocol behaviour.
+The valid options are:
+.Bl -tag -width Ds
+.It Cm nrequests Ns = Ns Ar value
+Controls how many concurrent SFTP read or write requests may be in progress
+at any point in time during a download or upload.
+By default 64 requests may be active concurrently.
+.It Cm buffer Ns = Ns Ar value
+Controls the maximum buffer size for a single SFTP read/write operation used
+during download or upload.
+By default a 32KB buffer is used.
+.El
.El
.Sh EXIT STATUS
.Ex -std scp
.Sh SEE ALSO
.Xr sftp 1 ,
.Xr ssh 1 ,
.Xr ssh-add 1 ,
.Xr ssh-agent 1 ,
.Xr ssh-keygen 1 ,
.Xr ssh_config 5 ,
.Xr sftp-server 8 ,
.Xr sshd 8
.Sh HISTORY
.Nm
is based on the rcp program in
.Bx
source code from the Regents of the University of California.
.Sh AUTHORS
.An Timo Rinne Aq Mt tri@iki.fi
.An Tatu Ylonen Aq Mt ylo@cs.hut.fi
.Sh CAVEATS
The original SCP protocol (used by default) requires execution of the
remote user's shell to perform
.Xr glob 3
pattern matching.
This requires careful quoting of any characters that have special meaning to
the remote shell, such as quote characters.
diff --git a/crypto/openssh/scp.c b/crypto/openssh/scp.c
index 8087d715f9e6..59bea5f4c89b 100644
--- a/crypto/openssh/scp.c
+++ b/crypto/openssh/scp.c
@@ -1,2173 +1,2254 @@
-/* $OpenBSD: scp.c,v 1.248 2022/05/13 06:31:50 djm Exp $ */
+/* $OpenBSD: scp.c,v 1.252 2023/01/10 23:22:15 millert Exp $ */
/*
* scp - secure remote copy. This is basically patched BSD rcp which
* uses ssh to do the data transfer (instead of using rcmd).
*
* NOTE: This version should NOT be suid root. (This uses ssh to
* do the transfer and ssh has the necessary privileges.)
*
* 1995 Timo Rinne <tri@iki.fi>, Tatu Ylonen <ylo@cs.hut.fi>
*
* As far as I am concerned, the code I have written for this software
* can be used freely for any purpose. Any derived versions of this
* software must be clearly marked as such, and if the derived work is
* incompatible with the protocol description in the RFC file, it must be
* called by a name other than "ssh" or "Secure Shell".
*/
/*
* Copyright (c) 1999 Theo de Raadt. All rights reserved.
* Copyright (c) 1999 Aaron Campbell. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Parts from:
*
* Copyright (c) 1983, 1990, 1992, 1993, 1995
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
#include "includes.h"
#include <sys/types.h>
#ifdef HAVE_SYS_STAT_H
# include <sys/stat.h>
#endif
#ifdef HAVE_POLL_H
#include <poll.h>
#else
# ifdef HAVE_SYS_POLL_H
# include <sys/poll.h>
# endif
#endif
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
#endif
#include <sys/wait.h>
#include <sys/uio.h>
#include <ctype.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#ifdef HAVE_FNMATCH_H
#include <fnmatch.h>
#endif
#ifdef USE_SYSTEM_GLOB
# include <glob.h>
#else
# include "openbsd-compat/glob.h"
#endif
#ifdef HAVE_LIBGEN_H
#include <libgen.h>
#endif
#include <limits.h>
+#ifdef HAVE_UTIL_H
+# include <util.h>
+#endif
#include <locale.h>
#include <pwd.h>
#include <signal.h>
#include <stdarg.h>
#ifdef HAVE_STDINT_H
# include <stdint.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#if defined(HAVE_STRNVIS) && defined(HAVE_VIS_H) && !defined(BROKEN_STRNVIS)
#include <vis.h>
#endif
#include "xmalloc.h"
#include "ssh.h"
#include "atomicio.h"
#include "pathnames.h"
#include "log.h"
#include "misc.h"
#include "progressmeter.h"
#include "utf8.h"
#include "sftp.h"
#include "sftp-common.h"
#include "sftp-client.h"
extern char *__progname;
#define COPY_BUFLEN 16384
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;
arglist remote_remote_args;
/* Bandwidth limit */
long long limit_kbps = 0;
struct bwlimit bwlimit;
/* Name of current file being transferred. */
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;
/*
* This is set to non-zero if remote-remote copy should be piped
* through this process.
*/
int throughlocal = 1;
/* Non-standard port to use for the ssh connection or -1. */
int sshport = -1;
/* This is the program to execute for the secured connection. ("ssh" or -S) */
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;
+/* SFTP copy parameters */
+size_t sftp_copy_buflen;
+size_t sftp_nrequests;
+
/* 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)
{
if (do_cmd_pid > 1) {
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);
exit(1);
}
static void
suspone(int pid, int signo)
{
int status;
if (pid > 1) {
kill(pid, signo);
while (waitpid(pid, &status, WUNTRACED) == -1 &&
errno == EINTR)
;
}
}
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)
{
u_int i;
int status;
pid_t pid;
if (a->num == 0)
fatal("do_local_cmd: no arguments");
if (verbose_mode) {
fprintf(stderr, "Executing:");
for (i = 0; i < a->num; i++)
fmprintf(stderr, " %s", a->list[i]);
fprintf(stderr, "\n");
}
if ((pid = fork()) == -1)
fatal("do_local_cmd: fork: %s", strerror(errno));
if (pid == 0) {
execvp(a->list[0], a->list);
perror(a->list[0]);
exit(1);
}
do_cmd_pid = pid;
ssh_signal(SIGTERM, killchild);
ssh_signal(SIGINT, killchild);
ssh_signal(SIGHUP, killchild);
while (waitpid(pid, &status, 0) == -1)
if (errno != EINTR)
fatal("do_local_cmd: waitpid: %s", strerror(errno));
do_cmd_pid = -1;
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
return (-1);
return (0);
}
/*
* This function executes the given command as the specified user on the
* given host. This returns < 0 if execution fails, and >= 0 otherwise. This
* assigns the input and output file descriptors on success.
*/
int
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];
+#ifdef USE_PIPES
+ int pin[2], pout[2];
+#else
+ int sv[2];
+#endif
if (verbose_mode)
fmprintf(stderr,
"Executing: program %s host %s, user %s, command %s\n",
program, host,
remuser ? remuser : "(unspecified)", cmd);
if (port == -1)
port = sshport;
- /*
- * Reserve two descriptors so that the real pipes won't get
- * descriptors 0 and 1 because that will screw up dup2 below.
- */
- if (pipe(reserved) == -1)
+#ifdef USE_PIPES
+ if (pipe(pin) == -1 || pipe(pout) == -1)
fatal("pipe: %s", strerror(errno));
-
+#else
/* Create a socket pair for communicating with ssh. */
- if (pipe(pin) == -1)
- fatal("pipe: %s", strerror(errno));
- if (pipe(pout) == -1)
- fatal("pipe: %s", strerror(errno));
-
- /* Free the reserved descriptors. */
- close(reserved[0]);
- close(reserved[1]);
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == -1)
+ fatal("socketpair: %s", strerror(errno));
+#endif
ssh_signal(SIGTSTP, suspchild);
ssh_signal(SIGTTIN, suspchild);
ssh_signal(SIGTTOU, suspchild);
/* Fork a child to execute the command on the remote host using ssh. */
*pid = fork();
- if (*pid == 0) {
+ switch (*pid) {
+ case -1:
+ fatal("fork: %s", strerror(errno));
+ case 0:
/* Child. */
+#ifdef USE_PIPES
+ if (dup2(pin[0], STDIN_FILENO) == -1 ||
+ dup2(pout[1], STDOUT_FILENO) == -1) {
+ error("dup2: %s", strerror(errno));
+ _exit(1);
+ }
+ close(pin[0]);
close(pin[1]);
close(pout[0]);
- dup2(pin[0], 0);
- dup2(pout[1], 1);
- close(pin[0]);
close(pout[1]);
-
+#else
+ if (dup2(sv[0], STDIN_FILENO) == -1 ||
+ dup2(sv[0], STDOUT_FILENO) == -1) {
+ error("dup2: %s", strerror(errno));
+ _exit(1);
+ }
+ close(sv[0]);
+ close(sv[1]);
+#endif
replacearg(&args, 0, "%s", program);
if (port != -1) {
addargs(&args, "-p");
addargs(&args, "%d", port);
}
if (remuser != NULL) {
addargs(&args, "-l");
addargs(&args, "%s", remuser);
}
if (subsystem)
addargs(&args, "-s");
addargs(&args, "--");
addargs(&args, "%s", host);
addargs(&args, "%s", cmd);
execvp(program, args.list);
perror(program);
- exit(1);
- } else if (*pid == -1) {
- fatal("fork: %s", strerror(errno));
+ _exit(1);
+ default:
+ /* Parent. Close the other side, and return the local side. */
+#ifdef USE_PIPES
+ close(pin[0]);
+ close(pout[1]);
+ *fdout = pin[1];
+ *fdin = pout[0];
+#else
+ close(sv[0]);
+ *fdin = sv[1];
+ *fdout = sv[1];
+#endif
+ ssh_signal(SIGTERM, killchild);
+ ssh_signal(SIGINT, killchild);
+ ssh_signal(SIGHUP, killchild);
+ return 0;
}
- /* Parent. Close the other side, and return the local side. */
- close(pin[0]);
- *fdout = pin[1];
- close(pout[1]);
- *fdin = pout[0];
- ssh_signal(SIGTERM, killchild);
- ssh_signal(SIGINT, killchild);
- ssh_signal(SIGHUP, killchild);
- return 0;
}
/*
* This function executes a command similar to do_cmd(), but expects the
* input and output descriptors to be setup by a previous call to do_cmd().
* 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)
{
int status;
pid_t pid;
if (verbose_mode)
fmprintf(stderr,
"Executing: 2nd program %s host %s, user %s, command %s\n",
ssh_program, host,
remuser ? remuser : "(unspecified)", cmd);
if (port == -1)
port = sshport;
/* Fork a child to execute the command on the remote host using ssh. */
pid = fork();
if (pid == 0) {
dup2(fdin, 0);
dup2(fdout, 1);
replacearg(&args, 0, "%s", ssh_program);
if (port != -1) {
addargs(&args, "-p");
addargs(&args, "%d", port);
}
if (remuser != NULL) {
addargs(&args, "-l");
addargs(&args, "%s", remuser);
}
addargs(&args, "-oBatchMode=yes");
addargs(&args, "--");
addargs(&args, "%s", host);
addargs(&args, "%s", cmd);
execvp(ssh_program, args.list);
perror(ssh_program);
exit(1);
} else if (pid == -1) {
fatal("fork: %s", strerror(errno));
}
while (waitpid(pid, &status, 0) == -1)
if (errno != EINTR)
fatal("do_cmd2: waitpid: %s", strerror(errno));
return 0;
}
typedef struct {
size_t cnt;
char *buf;
} BUF;
BUF *allocbuf(BUF *, int, int);
void lostconn(int);
int okname(char *);
void run_err(const char *,...)
__attribute__((__format__ (printf, 1, 2)))
__attribute__((__nonnull__ (1)));
int note_err(const char *,...)
__attribute__((__format__ (printf, 1, 2)));
void verifydir(char *);
struct passwd *pwd;
uid_t userid;
int errs, remin, remout, 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 *[], 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;
+ int ch, fflag, tflag, status, r, n;
char **newargv, *argv0;
const char *errstr;
extern char *optarg;
extern int optind;
enum scp_mode_e mode = MODE_SCP;
char *sftp_direct = NULL;
+ long long llv;
/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
sanitise_stdfd();
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]);
argv = newargv;
__progname = ssh_get_progname(argv[0]);
log_init(argv0, log_level, SYSLOG_FACILITY_USER, 2);
memset(&args, '\0', sizeof(args));
memset(&remote_remote_args, '\0', sizeof(remote_remote_args));
args.list = remote_remote_args.list = NULL;
addargs(&args, "%s", ssh_program);
addargs(&args, "-x");
addargs(&args, "-oPermitLocalCommand=no");
addargs(&args, "-oClearAllForwardings=yes");
addargs(&args, "-oRemoteCommand=none");
addargs(&args, "-oRequestTTY=no");
fflag = Tflag = tflag = 0;
while ((ch = getopt(argc, argv,
- "12346ABCTdfOpqRrstvD:F:J:M:P:S:c:i:l:o:")) != -1) {
+ "12346ABCTdfOpqRrstvD:F:J:M:P:S:c:i:l:o:X:")) != -1) {
switch (ch) {
/* User-visible flags. */
case '1':
fatal("SSH protocol v.1 is no longer supported");
break;
case '2':
/* Ignored */
break;
case 'A':
case '4':
case '6':
case 'C':
addargs(&args, "-%c", ch);
addargs(&remote_remote_args, "-%c", ch);
break;
case 'D':
sftp_direct = optarg;
break;
case '3':
throughlocal = 1;
break;
case 'R':
throughlocal = 0;
break;
case 'o':
case 'c':
case 'i':
case 'F':
case 'J':
addargs(&remote_remote_args, "-%c", ch);
addargs(&remote_remote_args, "%s", optarg);
addargs(&args, "-%c", ch);
addargs(&args, "%s", optarg);
break;
case 'O':
mode = MODE_SCP;
break;
case 's':
mode = MODE_SFTP;
break;
case 'P':
sshport = a2port(optarg);
if (sshport <= 0)
fatal("bad port \"%s\"\n", optarg);
break;
case 'B':
addargs(&remote_remote_args, "-oBatchmode=yes");
addargs(&args, "-oBatchmode=yes");
break;
case 'l':
limit_kbps = strtonum(optarg, 1, 100 * 1024 * 1024,
&errstr);
if (errstr != NULL)
usage();
limit_kbps *= 1024; /* kbps */
bandwidth_limit_init(&bwlimit, limit_kbps, COPY_BUFLEN);
break;
case 'p':
pflag = 1;
break;
case 'r':
iamrecursive = 1;
break;
case 'S':
ssh_program = xstrdup(optarg);
break;
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':
addargs(&args, "-q");
addargs(&remote_remote_args, "-q");
showprogress = 0;
break;
+ case 'X':
+ /* Please keep in sync with sftp.c -X */
+ if (strncmp(optarg, "buffer=", 7) == 0) {
+ r = scan_scaled(optarg + 7, &llv);
+ if (r == 0 && (llv <= 0 || llv > 256 * 1024)) {
+ r = -1;
+ errno = EINVAL;
+ }
+ if (r == -1) {
+ fatal("Invalid buffer size \"%s\": %s",
+ optarg + 7, strerror(errno));
+ }
+ sftp_copy_buflen = (size_t)llv;
+ } else if (strncmp(optarg, "nrequests=", 10) == 0) {
+ llv = strtonum(optarg + 10, 1, 256 * 1024,
+ &errstr);
+ if (errstr != NULL) {
+ fatal("Invalid number of requests "
+ "\"%s\": %s", optarg + 10, errstr);
+ }
+ sftp_nrequests = (size_t)llv;
+ } else {
+ fatal("Invalid -X option");
+ }
+ break;
/* Server options. */
case 'd':
targetshouldbedirectory = 1;
break;
case 'f': /* "from" */
iamremote = 1;
fflag = 1;
break;
case 't': /* "to" */
iamremote = 1;
tflag = 1;
#ifdef HAVE_CYGWIN
setmode(0, O_BINARY);
#endif
break;
case 'T':
Tflag = 1;
break;
default:
usage();
}
}
argc -= optind;
argv += optind;
log_init(argv0, log_level, SYSLOG_FACILITY_USER, 2);
/* 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);
if (!isatty(STDOUT_FILENO))
showprogress = 0;
if (pflag) {
/* Cannot pledge: -p allows setuid/setgid files... */
} else {
if (pledge("stdio rpath wpath cpath fattr tty proc exec",
NULL) == -1) {
perror("pledge");
exit(1);
}
}
remin = STDIN_FILENO;
remout = STDOUT_FILENO;
if (fflag) {
/* Follow "protocol", send data. */
(void) response();
source(argc, argv);
exit(errs != 0);
}
if (tflag) {
/* Receive data. */
sink(argc, argv, NULL);
exit(errs != 0);
}
if (argc < 2)
usage();
if (argc > 2)
targetshouldbedirectory = 1;
remin = remout = -1;
do_cmd_pid = -1;
/* Command to be executed on remote system using "ssh". */
(void) snprintf(cmd, sizeof cmd, "scp%s%s%s%s",
verbose_mode ? " -v" : "",
iamrecursive ? " -r" : "", pflag ? " -p" : "",
targetshouldbedirectory ? " -d" : "");
(void) ssh_signal(SIGPIPE, lostconn);
if (colon(argv[argc - 1])) /* Dest is remote host. */
toremote(argc, argv, mode, sftp_direct);
else {
if (targetshouldbedirectory)
verifydir(argv[argc - 1]);
tolocal(argc, argv, mode, sftp_direct); /* Dest is local host. */
}
/*
* Finally check the exit status of the ssh process, if one was forked
* and no error has occurred yet
*/
if (do_cmd_pid != -1 && (mode == MODE_SFTP || errs == 0)) {
if (remin != -1)
(void) close(remin);
if (remout != -1)
(void) close(remout);
if (waitpid(do_cmd_pid, &status, 0) == -1)
errs = 1;
else {
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
errs = 1;
}
}
exit(errs != 0);
}
/* Callback from atomicio6 to update progress meter and limit bandwidth */
static int
scpio(void *_cnt, size_t s)
{
off_t *cnt = (off_t *)_cnt;
*cnt += s;
refresh_progress_meter(0);
if (limit_kbps > 0)
bandwidth_limit(&bwlimit, s);
return 0;
}
static int
do_times(int fd, int verb, const struct stat *sb)
{
/* strlen(2^64) == 20; strlen(10^6) == 7 */
char buf[(20 + 7 + 2) * 2 + 2];
(void)snprintf(buf, sizeof(buf), "T%llu 0 %llu 0\n",
(unsigned long long) (sb->st_mtime < 0 ? 0 : sb->st_mtime),
(unsigned long long) (sb->st_atime < 0 ? 0 : sb->st_atime));
if (verb) {
fprintf(stderr, "File mtime %lld atime %lld\n",
(long long)sb->st_mtime, (long long)sb->st_atime);
fprintf(stderr, "Sending file timestamps: %s", buf);
}
(void) atomicio(vwrite, fd, buf, strlen(buf));
return (response());
}
static int
parse_scp_uri(const char *uri, char **userp, char **hostp, int *portp,
char **pathp)
{
int r;
r = parse_uri("scp", uri, userp, hostp, portp, pathp);
if (r == 0 && *pathp == NULL)
*pathp = xstrdup(".");
return r;
}
/* Appends a string to an array; returns 0 on success, -1 on alloc failure */
static int
append(char *cp, char ***ap, size_t *np)
{
char **tmp;
if ((tmp = reallocarray(*ap, *np + 1, sizeof(*tmp))) == NULL)
return -1;
tmp[(*np)] = cp;
(*np)++;
*ap = tmp;
return 0;
}
/*
* Finds the start and end of the first brace pair in the pattern.
* returns 0 on success or -1 for invalid patterns.
*/
static int
find_brace(const char *pattern, int *startp, int *endp)
{
int i;
int in_bracket, brace_level;
*startp = *endp = -1;
in_bracket = brace_level = 0;
for (i = 0; i < INT_MAX && *endp < 0 && pattern[i] != '\0'; i++) {
switch (pattern[i]) {
case '\\':
/* skip next character */
if (pattern[i + 1] != '\0')
i++;
break;
case '[':
in_bracket = 1;
break;
case ']':
in_bracket = 0;
break;
case '{':
if (in_bracket)
break;
if (pattern[i + 1] == '}') {
/* Protect a single {}, for find(1), like csh */
i++; /* skip */
break;
}
if (*startp == -1)
*startp = i;
brace_level++;
break;
case '}':
if (in_bracket)
break;
if (*startp < 0) {
/* Unbalanced brace */
return -1;
}
if (--brace_level <= 0)
*endp = i;
break;
}
}
/* unbalanced brackets/braces */
if (*endp < 0 && (*startp >= 0 || in_bracket))
return -1;
return 0;
}
/*
* Assembles and records a successfully-expanded pattern, returns -1 on
* alloc failure.
*/
static int
emit_expansion(const char *pattern, int brace_start, int brace_end,
int sel_start, int sel_end, char ***patternsp, size_t *npatternsp)
{
char *cp;
int o = 0, tail_len = strlen(pattern + brace_end + 1);
if ((cp = malloc(brace_start + (sel_end - sel_start) +
tail_len + 1)) == NULL)
return -1;
/* Pattern before initial brace */
if (brace_start > 0) {
memcpy(cp, pattern, brace_start);
o = brace_start;
}
/* Current braced selection */
if (sel_end - sel_start > 0) {
memcpy(cp + o, pattern + sel_start,
sel_end - sel_start);
o += sel_end - sel_start;
}
/* Remainder of pattern after closing brace */
if (tail_len > 0) {
memcpy(cp + o, pattern + brace_end + 1, tail_len);
o += tail_len;
}
cp[o] = '\0';
if (append(cp, patternsp, npatternsp) != 0) {
free(cp);
return -1;
}
return 0;
}
/*
* Expand the first encountered brace in pattern, appending the expanded
* patterns it yielded to the *patternsp array.
*
* Returns 0 on success or -1 on allocation failure.
*
* Signals whether expansion was performed via *expanded and whether
* pattern was invalid via *invalid.
*/
static int
brace_expand_one(const char *pattern, char ***patternsp, size_t *npatternsp,
int *expanded, int *invalid)
{
int i;
int in_bracket, brace_start, brace_end, brace_level;
int sel_start, sel_end;
*invalid = *expanded = 0;
if (find_brace(pattern, &brace_start, &brace_end) != 0) {
*invalid = 1;
return 0;
} else if (brace_start == -1)
return 0;
in_bracket = brace_level = 0;
for (i = sel_start = brace_start + 1; i < brace_end; i++) {
switch (pattern[i]) {
case '{':
if (in_bracket)
break;
brace_level++;
break;
case '}':
if (in_bracket)
break;
brace_level--;
break;
case '[':
in_bracket = 1;
break;
case ']':
in_bracket = 0;
break;
case '\\':
if (i < brace_end - 1)
i++; /* skip */
break;
}
if (pattern[i] == ',' || i == brace_end - 1) {
if (in_bracket || brace_level > 0)
continue;
/* End of a selection, emit an expanded pattern */
/* Adjust end index for last selection */
sel_end = (i == brace_end - 1) ? brace_end : i;
if (emit_expansion(pattern, brace_start, brace_end,
sel_start, sel_end, patternsp, npatternsp) != 0)
return -1;
/* move on to the next selection */
sel_start = i + 1;
continue;
}
}
if (in_bracket || brace_level > 0) {
*invalid = 1;
return 0;
}
/* success */
*expanded = 1;
return 0;
}
/* Expand braces from pattern. Returns 0 on success, -1 on failure */
static int
brace_expand(const char *pattern, char ***patternsp, size_t *npatternsp)
{
char *cp, *cp2, **active = NULL, **done = NULL;
size_t i, nactive = 0, ndone = 0;
int ret = -1, invalid = 0, expanded = 0;
*patternsp = NULL;
*npatternsp = 0;
/* Start the worklist with the original pattern */
if ((cp = strdup(pattern)) == NULL)
return -1;
if (append(cp, &active, &nactive) != 0) {
free(cp);
return -1;
}
while (nactive > 0) {
cp = active[nactive - 1];
nactive--;
if (brace_expand_one(cp, &active, &nactive,
&expanded, &invalid) == -1) {
free(cp);
goto fail;
}
if (invalid)
fatal_f("invalid brace pattern \"%s\"", cp);
if (expanded) {
/*
* Current entry expanded to new entries on the
* active list; discard the progenitor pattern.
*/
free(cp);
continue;
}
/*
* Pattern did not expand; append the finename component to
* the completed list
*/
if ((cp2 = strrchr(cp, '/')) != NULL)
*cp2++ = '\0';
else
cp2 = cp;
if (append(xstrdup(cp2), &done, &ndone) != 0) {
free(cp);
goto fail;
}
free(cp);
}
/* success */
*patternsp = done;
*npatternsp = ndone;
done = NULL;
ndone = 0;
ret = 0;
fail:
for (i = 0; i < nactive; i++)
free(active[i]);
free(active);
for (i = 0; i < ndone; i++)
free(done[i]);
free(done);
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 {
freeargs(&args);
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);
+ return do_init(*reminp, *remoutp,
+ sftp_copy_buflen, sftp_nrequests, limit_kbps);
}
void
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, status;
u_int j;
memset(&alist, '\0', sizeof(alist));
alist.list = NULL;
/* Parse target */
r = parse_scp_uri(argv[argc - 1], &tuser, &thost, &tport, &targ);
if (r == -1) {
fmprintf(stderr, "%s: invalid uri\n", argv[argc - 1]);
++errs;
goto out;
}
if (r != 0) {
if (parse_user_host_path(argv[argc - 1], &tuser, &thost,
&targ) == -1) {
fmprintf(stderr, "%s: invalid target\n", argv[argc - 1]);
++errs;
goto out;
}
}
/* Parse source files */
for (i = 0; i < argc - 1; i++) {
free(suser);
free(host);
free(src);
r = parse_scp_uri(argv[i], &suser, &host, &sport, &src);
if (r == -1) {
fmprintf(stderr, "%s: invalid uri\n", argv[i]);
++errs;
continue;
}
if (r != 0) {
parse_user_host_path(argv[i], &suser, &host, &src);
}
if (suser != NULL && !okname(suser)) {
++errs;
continue;
}
if (host && throughlocal) { /* extended remote to remote */
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 and the -R option");
}
freeargs(&alist);
addargs(&alist, "%s", ssh_program);
addargs(&alist, "-x");
addargs(&alist, "-oClearAllForwardings=yes");
addargs(&alist, "-n");
for (j = 0; j < remote_remote_args.num; j++) {
addargs(&alist, "%s",
remote_remote_args.list[j]);
}
if (sport != -1) {
addargs(&alist, "-p");
addargs(&alist, "%d", sport);
}
if (suser) {
addargs(&alist, "-l");
addargs(&alist, "%s", suser);
}
addargs(&alist, "--");
addargs(&alist, "%s", host);
addargs(&alist, "%s", cmd);
addargs(&alist, "%s", src);
addargs(&alist, "%s%s%s:%s",
tuser ? tuser : "", tuser ? "@" : "",
thost, targ);
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(ssh_program, thost, tuser, tport, 0,
bp, &remin, &remout, &do_cmd_pid) < 0)
exit(1);
if (response() < 0)
exit(1);
free(bp);
}
source(1, argv + i);
}
}
out:
if (mode == MODE_SFTP)
free(conn);
free(tuser);
free(thost);
free(targ);
free(suser);
free(host);
free(src);
}
void
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));
alist.list = NULL;
for (i = 0; i < argc - 1; i++) {
free(suser);
free(host);
free(src);
r = parse_scp_uri(argv[i], &suser, &host, &sport, &src);
if (r == -1) {
fmprintf(stderr, "%s: invalid uri\n", argv[i]);
++errs;
continue;
}
if (r != 0)
parse_user_host_path(argv[i], &suser, &host, &src);
if (suser != NULL && !okname(suser)) {
++errs;
continue;
}
if (!host) { /* Local to local. */
freeargs(&alist);
addargs(&alist, "%s", _PATH_CP);
if (iamrecursive)
addargs(&alist, "-r");
if (pflag)
addargs(&alist, "-p");
addargs(&alist, "--");
addargs(&alist, "%s", argv[i]);
addargs(&alist, "%s", argv[argc-1]);
if (do_local_cmd(&alist))
++errs;
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("sftp connection failed");
++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(ssh_program, host, suser, sport, 0, bp,
&remin, &remout, &do_cmd_pid) < 0) {
free(bp);
++errs;
continue;
}
free(bp);
sink(1, argv + argc - 1, src);
(void) close(remin);
remin = remout = -1;
}
free(suser);
free(host);
free(src);
}
/* Prepare remote path, handling ~ by assuming cwd is the homedir */
static char *
prepare_remote_path(struct sftp_conn *conn, const char *path)
{
size_t nslash;
/* Handle ~ prefixed paths */
if (*path == '\0' || strcmp(path, "~") == 0)
return xstrdup(".");
if (*path != '~')
return xstrdup(path);
if (strncmp(path, "~/", 2) == 0) {
if ((nslash = strspn(path + 2, "/")) == strlen(path + 2))
return xstrdup(".");
return xstrdup(path + 2 + nslash);
}
if (can_expand_path(conn))
return do_expand_path(conn, path);
/* No protocol extension */
error("server expand-path extension is required "
"for ~user paths in SFTP mode");
return NULL;
}
void
source_sftp(int argc, char *src, char *targ, struct sftp_conn *conn)
{
char *target = NULL, *filename = NULL, *abs_dst = NULL;
int src_is_dir, target_is_dir;
Attrib a;
struct stat st;
memset(&a, '\0', sizeof(a));
if (stat(src, &st) != 0)
fatal("stat local \"%s\": %s", src, strerror(errno));
src_is_dir = S_ISDIR(st.st_mode);
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) {
debug("target directory \"%s\" does not exist", target);
a.flags = SSH2_FILEXFER_ATTR_PERMISSIONS;
a.perm = st.st_mode | 0700; /* ensure writable */
if (do_mkdir(conn, target, &a, 1) != 0)
cleanup_exit(255); /* error already logged */
target_is_dir = 1;
}
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 (src_is_dir && iamrecursive) {
if (upload_dir(conn, src, abs_dst, pflag,
SFTP_PROGRESS_ONLY, 0, 0, 1, 1) != 0) {
error("failed to upload directory %s to %s", src, targ);
errs = 1;
}
} else if (do_upload(conn, src, abs_dst, pflag, 0, 0, 1) != 0) {
error("failed to upload file %s to %s", src, targ);
errs = 1;
}
free(abs_dst);
free(target);
}
void
source(int argc, char **argv)
{
struct stat stb;
static BUF buffer;
BUF *bp;
off_t i, statbytes;
size_t amt, nr;
int fd = -1, haderr, indx;
char *last, *name, buf[PATH_MAX + 128], encname[PATH_MAX];
int len;
for (indx = 0; indx < argc; ++indx) {
name = argv[indx];
statbytes = 0;
len = strlen(name);
while (len > 1 && name[len-1] == '/')
name[--len] = '\0';
if ((fd = open(name, O_RDONLY|O_NONBLOCK)) == -1)
goto syserr;
if (strchr(name, '\n') != NULL) {
strnvis(encname, name, sizeof(encname), VIS_NL);
name = encname;
}
if (fstat(fd, &stb) == -1) {
syserr: run_err("%s: %s", name, strerror(errno));
goto next;
}
if (stb.st_size < 0) {
run_err("%s: %s", name, "Negative file size");
goto next;
}
unset_nonblock(fd);
switch (stb.st_mode & S_IFMT) {
case S_IFREG:
break;
case S_IFDIR:
if (iamrecursive) {
rsource(name, &stb);
goto next;
}
/* FALLTHROUGH */
default:
run_err("%s: not a regular file", name);
goto next;
}
if ((last = strrchr(name, '/')) == NULL)
last = name;
else
++last;
curfile = last;
if (pflag) {
if (do_times(remout, verbose_mode, &stb) < 0)
goto next;
}
#define FILEMODEMASK (S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO)
snprintf(buf, sizeof buf, "C%04o %lld %s\n",
(u_int) (stb.st_mode & FILEMODEMASK),
(long long)stb.st_size, last);
if (verbose_mode)
fmprintf(stderr, "Sending file modes: %s", buf);
(void) atomicio(vwrite, remout, buf, strlen(buf));
if (response() < 0)
goto next;
if ((bp = allocbuf(&buffer, fd, COPY_BUFLEN)) == NULL) {
next: if (fd != -1) {
(void) close(fd);
fd = -1;
}
continue;
}
if (showprogress)
start_progress_meter(curfile, stb.st_size, &statbytes);
set_nonblock(remout);
for (haderr = i = 0; i < stb.st_size; i += bp->cnt) {
amt = bp->cnt;
if (i + (off_t)amt > stb.st_size)
amt = stb.st_size - i;
if (!haderr) {
if ((nr = atomicio(read, fd,
bp->buf, amt)) != amt) {
haderr = errno;
memset(bp->buf + nr, 0, amt - nr);
}
}
/* Keep writing after error to retain sync */
if (haderr) {
(void)atomicio(vwrite, remout, bp->buf, amt);
memset(bp->buf, 0, amt);
continue;
}
if (atomicio6(vwrite, remout, bp->buf, amt, scpio,
&statbytes) != amt)
haderr = errno;
}
unset_nonblock(remout);
if (fd != -1) {
if (close(fd) == -1 && !haderr)
haderr = errno;
fd = -1;
}
if (!haderr)
(void) atomicio(vwrite, remout, "", 1);
else
run_err("%s: %s", name, strerror(haderr));
(void) response();
if (showprogress)
stop_progress_meter();
}
}
void
rsource(char *name, struct stat *statp)
{
DIR *dirp;
struct dirent *dp;
char *last, *vect[1], path[PATH_MAX];
if (!(dirp = opendir(name))) {
run_err("%s: %s", name, strerror(errno));
return;
}
last = strrchr(name, '/');
if (last == NULL)
last = name;
else
last++;
if (pflag) {
if (do_times(remout, verbose_mode, statp) < 0) {
closedir(dirp);
return;
}
}
(void) snprintf(path, sizeof path, "D%04o %d %.1024s\n",
(u_int) (statp->st_mode & FILEMODEMASK), 0, last);
if (verbose_mode)
fmprintf(stderr, "Entering directory: %s", path);
(void) atomicio(vwrite, remout, path, strlen(path));
if (response() < 0) {
closedir(dirp);
return;
}
while ((dp = readdir(dirp)) != NULL) {
if (dp->d_ino == 0)
continue;
if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, ".."))
continue;
if (strlen(name) + 1 + strlen(dp->d_name) >= sizeof(path) - 1) {
run_err("%s/%s: name too long", name, dp->d_name);
continue;
}
(void) snprintf(path, sizeof path, "%s/%s", name, dp->d_name);
vect[0] = path;
source(1, vect);
}
(void) closedir(dirp);
(void) atomicio(vwrite, remout, "E\n", 2);
(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, dst_is_dir;
struct stat st;
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 = remote_glob(conn, abs_src, GLOB_NOCHECK|GLOB_MARK,
+ NULL, &g)) != 0) {
if (r == GLOB_NOSPACE)
error("%s: too many glob matches", src);
else
error("%s: %s", src, strerror(ENOENT));
err = -1;
goto out;
}
+ /* Did we actually get any matches back from the glob? */
+ if (g.gl_matchc == 0 && g.gl_pathc == 1 && g.gl_pathv[0] != 0) {
+ /*
+ * If nothing matched but a path returned, then it's probably
+ * a GLOB_NOCHECK result. Check whether the unglobbed path
+ * exists so we can give a nice error message early.
+ */
+ if (do_stat(conn, g.gl_pathv[0], 1) == NULL) {
+ error("%s: %s", src, strerror(ENOENT));
+ err = -1;
+ goto out;
+ }
+ }
+
if ((r = stat(dst, &st)) != 0)
debug2_f("stat local \"%s\": %s", dst, strerror(errno));
dst_is_dir = r == 0 && S_ISDIR(st.st_mode);
if (g.gl_matchc > 1 && !dst_is_dir) {
if (r == 0) {
error("Multiple files match pattern, but destination "
"\"%s\" is not a directory", dst);
err = -1;
goto out;
}
debug2_f("creating destination \"%s\"", dst);
if (mkdir(dst, 0777) != 0) {
error("local mkdir \"%s\": %s", dst, strerror(errno));
err = -1;
goto out;
}
dst_is_dir = 1;
}
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 (dst_is_dir)
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) == -1)
err = -1;
} else {
if (do_download(conn, g.gl_pathv[i], abs_dst, NULL,
pflag, 0, 0, 1) == -1)
err = -1;
}
free(abs_dst);
abs_dst = NULL;
free(tmp);
tmp = NULL;
}
out:
free(abs_src);
free(tmp);
globfree(&g);
if (err == -1)
errs = 1;
}
#define TYPE_OVERFLOW(type, val) \
((sizeof(type) == 4 && (val) > INT32_MAX) || \
(sizeof(type) == 8 && (val) > INT64_MAX) || \
(sizeof(type) != 4 && sizeof(type) != 8))
void
sink(int argc, char **argv, const char *src)
{
static BUF buffer;
struct stat stb;
BUF *bp;
off_t i;
size_t j, count;
int amt, exists, first, ofd;
mode_t mode, omode, mask;
off_t size, statbytes;
unsigned long long ull;
int setimes, targisdir, wrerr;
char ch, *cp, *np, *targ, *why, *vect[1], buf[2048], visbuf[2048];
char **patterns = NULL;
size_t n, npatterns = 0;
struct timeval tv[2];
#define atime tv[0]
#define mtime tv[1]
#define SCREWUP(str) { why = str; goto screwup; }
if (TYPE_OVERFLOW(time_t, 0) || TYPE_OVERFLOW(off_t, 0))
SCREWUP("Unexpected off_t/time_t size");
setimes = targisdir = 0;
mask = umask(0);
if (!pflag)
(void) umask(mask);
if (argc != 1) {
run_err("ambiguous target");
exit(1);
}
targ = *argv;
if (targetshouldbedirectory)
verifydir(targ);
(void) atomicio(vwrite, remout, "", 1);
if (stat(targ, &stb) == 0 && S_ISDIR(stb.st_mode))
targisdir = 1;
if (src != NULL && !iamrecursive && !Tflag) {
/*
* Prepare to try to restrict incoming filenames to match
* the requested destination file glob.
*/
if (brace_expand(src, &patterns, &npatterns) != 0)
fatal_f("could not expand pattern");
}
for (first = 1;; first = 0) {
cp = buf;
if (atomicio(read, remin, cp, 1) != 1)
goto done;
if (*cp++ == '\n')
SCREWUP("unexpected <newline>");
do {
if (atomicio(read, remin, &ch, sizeof(ch)) != sizeof(ch))
SCREWUP("lost connection");
*cp++ = ch;
} while (cp < &buf[sizeof(buf) - 1] && ch != '\n');
*cp = 0;
if (verbose_mode)
fmprintf(stderr, "Sink: %s", buf);
if (buf[0] == '\01' || buf[0] == '\02') {
if (iamremote == 0) {
(void) snmprintf(visbuf, sizeof(visbuf),
NULL, "%s", buf + 1);
(void) atomicio(vwrite, STDERR_FILENO,
visbuf, strlen(visbuf));
}
if (buf[0] == '\02')
exit(1);
++errs;
continue;
}
if (buf[0] == 'E') {
(void) atomicio(vwrite, remout, "", 1);
goto done;
}
if (ch == '\n')
*--cp = 0;
cp = buf;
if (*cp == 'T') {
setimes++;
cp++;
if (!isdigit((unsigned char)*cp))
SCREWUP("mtime.sec not present");
ull = strtoull(cp, &cp, 10);
if (!cp || *cp++ != ' ')
SCREWUP("mtime.sec not delimited");
if (TYPE_OVERFLOW(time_t, ull))
setimes = 0; /* out of range */
mtime.tv_sec = ull;
mtime.tv_usec = strtol(cp, &cp, 10);
if (!cp || *cp++ != ' ' || mtime.tv_usec < 0 ||
mtime.tv_usec > 999999)
SCREWUP("mtime.usec not delimited");
if (!isdigit((unsigned char)*cp))
SCREWUP("atime.sec not present");
ull = strtoull(cp, &cp, 10);
if (!cp || *cp++ != ' ')
SCREWUP("atime.sec not delimited");
if (TYPE_OVERFLOW(time_t, ull))
setimes = 0; /* out of range */
atime.tv_sec = ull;
atime.tv_usec = strtol(cp, &cp, 10);
if (!cp || *cp++ != '\0' || atime.tv_usec < 0 ||
atime.tv_usec > 999999)
SCREWUP("atime.usec not delimited");
(void) atomicio(vwrite, remout, "", 1);
continue;
}
if (*cp != 'C' && *cp != 'D') {
/*
* Check for the case "rcp remote:foo\* local:bar".
* In this case, the line "No match." can be returned
* by the shell before the rcp command on the remote is
* executed so the ^Aerror_message convention isn't
* followed.
*/
if (first) {
run_err("%s", cp);
exit(1);
}
SCREWUP("expected control record");
}
mode = 0;
for (++cp; cp < buf + 5; cp++) {
if (*cp < '0' || *cp > '7')
SCREWUP("bad mode");
mode = (mode << 3) | (*cp - '0');
}
if (!pflag)
mode &= ~mask;
if (*cp++ != ' ')
SCREWUP("mode not delimited");
if (!isdigit((unsigned char)*cp))
SCREWUP("size not present");
ull = strtoull(cp, &cp, 10);
if (!cp || *cp++ != ' ')
SCREWUP("size not delimited");
if (TYPE_OVERFLOW(off_t, ull))
SCREWUP("size out of range");
size = (off_t)ull;
if (*cp == '\0' || strchr(cp, '/') != NULL ||
strcmp(cp, ".") == 0 || strcmp(cp, "..") == 0) {
run_err("error: unexpected filename: %s", cp);
exit(1);
}
if (npatterns > 0) {
for (n = 0; n < npatterns; n++) {
- if (fnmatch(patterns[n], cp, 0) == 0)
+ if (strcmp(patterns[n], cp) == 0 ||
+ fnmatch(patterns[n], cp, 0) == 0)
break;
}
if (n >= npatterns)
SCREWUP("filename does not match request");
}
if (targisdir) {
static char *namebuf;
static size_t cursize;
size_t need;
need = strlen(targ) + strlen(cp) + 250;
if (need > cursize) {
free(namebuf);
namebuf = xmalloc(need);
cursize = need;
}
(void) snprintf(namebuf, need, "%s%s%s", targ,
strcmp(targ, "/") ? "/" : "", cp);
np = namebuf;
} else
np = targ;
curfile = cp;
exists = stat(np, &stb) == 0;
if (buf[0] == 'D') {
int mod_flag = pflag;
if (!iamrecursive)
SCREWUP("received directory without -r");
if (exists) {
if (!S_ISDIR(stb.st_mode)) {
errno = ENOTDIR;
goto bad;
}
if (pflag)
(void) chmod(np, mode);
} else {
/* Handle copying from a read-only directory */
mod_flag = 1;
if (mkdir(np, mode | S_IRWXU) == -1)
goto bad;
}
vect[0] = xstrdup(np);
sink(1, vect, src);
if (setimes) {
setimes = 0;
(void) utimes(vect[0], tv);
}
if (mod_flag)
(void) chmod(vect[0], mode);
free(vect[0]);
continue;
}
omode = mode;
mode |= S_IWUSR;
if ((ofd = open(np, O_WRONLY|O_CREAT, mode)) == -1) {
bad: run_err("%s: %s", np, strerror(errno));
continue;
}
(void) atomicio(vwrite, remout, "", 1);
if ((bp = allocbuf(&buffer, ofd, COPY_BUFLEN)) == NULL) {
(void) close(ofd);
continue;
}
cp = bp->buf;
wrerr = 0;
/*
* NB. do not use run_err() unless immediately followed by
* exit() below as it may send a spurious reply that might
* desyncronise us from the peer. Use note_err() instead.
*/
statbytes = 0;
if (showprogress)
start_progress_meter(curfile, size, &statbytes);
set_nonblock(remin);
for (count = i = 0; i < size; i += bp->cnt) {
amt = bp->cnt;
if (i + amt > size)
amt = size - i;
count += amt;
do {
j = atomicio6(read, remin, cp, amt,
scpio, &statbytes);
if (j == 0) {
run_err("%s", j != EPIPE ?
strerror(errno) :
"dropped connection");
exit(1);
}
amt -= j;
cp += j;
} while (amt > 0);
if (count == bp->cnt) {
/* Keep reading so we stay sync'd up. */
if (!wrerr) {
if (atomicio(vwrite, ofd, bp->buf,
count) != count) {
note_err("%s: %s", np,
strerror(errno));
wrerr = 1;
}
}
count = 0;
cp = bp->buf;
}
}
unset_nonblock(remin);
if (count != 0 && !wrerr &&
atomicio(vwrite, ofd, bp->buf, count) != count) {
note_err("%s: %s", np, strerror(errno));
wrerr = 1;
}
if (!wrerr && (!exists || S_ISREG(stb.st_mode)) &&
ftruncate(ofd, size) != 0)
note_err("%s: truncate: %s", np, strerror(errno));
if (pflag) {
if (exists || omode != mode)
#ifdef HAVE_FCHMOD
if (fchmod(ofd, omode)) {
#else /* HAVE_FCHMOD */
if (chmod(np, omode)) {
#endif /* HAVE_FCHMOD */
note_err("%s: set mode: %s",
np, strerror(errno));
}
} else {
if (!exists && omode != mode)
#ifdef HAVE_FCHMOD
if (fchmod(ofd, omode & ~mask)) {
#else /* HAVE_FCHMOD */
if (chmod(np, omode & ~mask)) {
#endif /* HAVE_FCHMOD */
note_err("%s: set mode: %s",
np, strerror(errno));
}
}
if (close(ofd) == -1)
note_err("%s: close: %s", np, strerror(errno));
(void) response();
if (showprogress)
stop_progress_meter();
if (setimes && !wrerr) {
setimes = 0;
if (utimes(np, tv) == -1) {
note_err("%s: set times: %s",
np, strerror(errno));
}
}
/* If no error was noted then signal success for this file */
if (note_err(NULL) == 0)
(void) atomicio(vwrite, remout, "", 1);
}
done:
for (n = 0; n < npatterns; n++)
free(patterns[n]);
free(patterns);
return;
screwup:
for (n = 0; n < npatterns; n++)
free(patterns[n]);
free(patterns);
run_err("protocol error: %s", why);
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("%s: destination is not a directory", targ);
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 = remote_glob(from, abs_src, GLOB_NOCHECK|GLOB_MARK,
+ NULL, &g)) != 0) {
if (r == GLOB_NOSPACE)
error("%s: too many glob matches", src);
else
error("%s: %s", src, strerror(ENOENT));
err = -1;
goto out;
}
+ /* Did we actually get any matches back from the glob? */
+ if (g.gl_matchc == 0 && g.gl_pathc == 1 && g.gl_pathv[0] != 0) {
+ /*
+ * If nothing matched but a path returned, then it's probably
+ * a GLOB_NOCHECK result. Check whether the unglobbed path
+ * exists so we can give a nice error message early.
+ */
+ if (do_stat(from, g.gl_pathv[0], 1) == NULL) {
+ error("%s: %s", src, strerror(ENOENT));
+ 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)
errs = 1;
}
int
response(void)
{
char ch, *cp, resp, rbuf[2048], visbuf[2048];
if (atomicio(read, remin, &resp, sizeof(resp)) != sizeof(resp))
lostconn(0);
cp = rbuf;
switch (resp) {
case 0: /* ok */
return (0);
default:
*cp++ = resp;
/* FALLTHROUGH */
case 1: /* error, followed by error msg */
case 2: /* fatal error, "" */
do {
if (atomicio(read, remin, &ch, sizeof(ch)) != sizeof(ch))
lostconn(0);
*cp++ = ch;
} while (cp < &rbuf[sizeof(rbuf) - 1] && ch != '\n');
if (!iamremote) {
cp[-1] = '\0';
(void) snmprintf(visbuf, sizeof(visbuf),
NULL, "%s\n", rbuf);
(void) atomicio(vwrite, STDERR_FILENO,
visbuf, strlen(visbuf));
}
++errs;
if (resp == 1)
return (-1);
exit(1);
}
/* NOTREACHED */
}
void
usage(void)
{
(void) fprintf(stderr,
"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");
+ " [-i identity_file] [-J destination] [-l limit] [-o ssh_option]\n"
+ " [-P port] [-S program] [-X sftp_option] source ... target\n");
exit(1);
}
void
run_err(const char *fmt,...)
{
static FILE *fp;
va_list ap;
++errs;
if (fp != NULL || (remout != -1 && (fp = fdopen(remout, "w")))) {
(void) fprintf(fp, "%c", 0x01);
(void) fprintf(fp, "scp: ");
va_start(ap, fmt);
(void) vfprintf(fp, fmt, ap);
va_end(ap);
(void) fprintf(fp, "\n");
(void) fflush(fp);
}
if (!iamremote) {
va_start(ap, fmt);
vfmprintf(stderr, fmt, ap);
va_end(ap);
fprintf(stderr, "\n");
}
}
/*
* Notes a sink error for sending at the end of a file transfer. Returns 0 if
* no error has been noted or -1 otherwise. Use note_err(NULL) to flush
* any active error at the end of the transfer.
*/
int
note_err(const char *fmt, ...)
{
static char *emsg;
va_list ap;
/* Replay any previously-noted error */
if (fmt == NULL) {
if (emsg == NULL)
return 0;
run_err("%s", emsg);
free(emsg);
emsg = NULL;
return -1;
}
errs++;
/* Prefer first-noted error */
if (emsg != NULL)
return -1;
va_start(ap, fmt);
vasnmprintf(&emsg, INT_MAX, NULL, fmt, ap);
va_end(ap);
return -1;
}
void
verifydir(char *cp)
{
struct stat stb;
if (!stat(cp, &stb)) {
if (S_ISDIR(stb.st_mode))
return;
errno = ENOTDIR;
}
run_err("%s: %s", cp, strerror(errno));
killchild(0);
}
int
okname(char *cp0)
{
int c;
char *cp;
cp = cp0;
do {
c = (int)*cp;
if (c & 0200)
goto bad;
if (!isalpha(c) && !isdigit((unsigned char)c)) {
switch (c) {
case '\'':
case '"':
case '`':
case ' ':
case '#':
goto bad;
default:
break;
}
}
} while (*++cp);
return (1);
bad: fmprintf(stderr, "%s: invalid user name\n", cp0);
return (0);
}
BUF *
allocbuf(BUF *bp, int fd, int blksize)
{
size_t size;
#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
struct stat stb;
if (fstat(fd, &stb) == -1) {
run_err("fstat: %s", strerror(errno));
return (0);
}
size = ROUNDUP(stb.st_blksize, blksize);
if (size == 0)
size = blksize;
#else /* HAVE_STRUCT_STAT_ST_BLKSIZE */
size = blksize;
#endif /* HAVE_STRUCT_STAT_ST_BLKSIZE */
if (bp->cnt >= size)
return (bp);
bp->buf = xrecallocarray(bp->buf, bp->cnt, size, 1);
bp->cnt = size;
return (bp);
}
void
lostconn(int signo)
{
if (!iamremote)
(void)write(STDERR_FILENO, "lost connection\n", 16);
if (signo)
_exit(1);
else
exit(1);
}
void
cleanup_exit(int i)
{
if (remin > 0)
close(remin);
if (remout > 0)
close(remout);
if (remin2 > 0)
close(remin2);
if (remout2 > 0)
close(remout2);
if (do_cmd_pid > 0)
waitpid(do_cmd_pid, NULL, 0);
if (do_cmd_pid2 > 0)
waitpid(do_cmd_pid2, NULL, 0);
exit(i);
}
diff --git a/crypto/openssh/servconf.c b/crypto/openssh/servconf.c
index 210d6330545d..0bffed7b582e 100644
--- a/crypto/openssh/servconf.c
+++ b/crypto/openssh/servconf.c
@@ -1,3071 +1,3185 @@
-/* $OpenBSD: servconf.c,v 1.386 2022/09/17 10:34:29 djm Exp $ */
+/* $OpenBSD: servconf.c,v 1.390 2023/01/17 09:44:48 djm Exp $ */
/*
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
*
* As far as I am concerned, the code I have written for this software
* can be used freely for any purpose. Any derived versions of this
* software must be clearly marked as such, and if the derived work is
* incompatible with the protocol description in the RFC file, it must be
* called by a name other than "ssh" or "Secure Shell".
*/
#include "includes.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#ifdef __OpenBSD__
#include <sys/sysctl.h>
#endif
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#ifdef HAVE_NET_ROUTE_H
#include <net/route.h>
#endif
#include <ctype.h>
#include <netdb.h>
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <limits.h>
#include <stdarg.h>
#include <errno.h>
#ifdef HAVE_UTIL_H
#include <util.h>
#endif
#ifdef USE_SYSTEM_GLOB
# include <glob.h>
#else
# include "openbsd-compat/glob.h"
#endif
#include "openbsd-compat/sys-queue.h"
#include "xmalloc.h"
#include "ssh.h"
#include "log.h"
#include "sshbuf.h"
#include "misc.h"
#include "servconf.h"
#include "compat.h"
#include "pathnames.h"
#include "cipher.h"
#include "sshkey.h"
#include "kex.h"
#include "mac.h"
#include "match.h"
#include "channels.h"
#include "groupaccess.h"
#include "canohost.h"
#include "packet.h"
#include "ssherr.h"
#include "hostfile.h"
#include "auth.h"
#include "myproposal.h"
#include "digest.h"
#include "version.h"
static void add_listen_addr(ServerOptions *, const char *,
const char *, int);
static void add_one_listen_addr(ServerOptions *, const char *,
const char *, int);
static void parse_server_config_depth(ServerOptions *options,
const char *filename, struct sshbuf *conf, struct include_list *includes,
struct connection_info *connectinfo, int flags, int *activep, int depth);
/* Use of privilege separation or not */
extern int use_privsep;
extern struct sshbuf *cfg;
/* Initializes the server options to their default values. */
void
initialize_server_options(ServerOptions *options)
{
memset(options, 0, sizeof(*options));
/* Portable-specific options */
options->use_pam = -1;
/* Standard Options */
options->num_ports = 0;
options->ports_from_cmdline = 0;
options->queued_listen_addrs = NULL;
options->num_queued_listens = 0;
options->listen_addrs = NULL;
options->num_listen_addrs = 0;
options->address_family = -1;
options->routing_domain = NULL;
options->num_host_key_files = 0;
options->num_host_cert_files = 0;
options->host_key_agent = NULL;
options->pid_file = NULL;
options->login_grace_time = -1;
options->permit_root_login = PERMIT_NOT_SET;
options->ignore_rhosts = -1;
options->ignore_user_known_hosts = -1;
options->print_motd = -1;
options->print_lastlog = -1;
options->x11_forwarding = -1;
options->x11_display_offset = -1;
options->x11_use_localhost = -1;
options->permit_tty = -1;
options->permit_user_rc = -1;
options->xauth_location = NULL;
options->strict_modes = -1;
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_accepted_algos = NULL;
options->hostkeyalgorithms = NULL;
options->pubkey_authentication = -1;
options->pubkey_auth_options = -1;
options->pubkey_accepted_algos = NULL;
options->kerberos_authentication = -1;
options->kerberos_or_local_passwd = -1;
options->kerberos_ticket_cleanup = -1;
options->kerberos_get_afs_token = -1;
options->gss_authentication=-1;
options->gss_cleanup_creds = -1;
options->gss_strict_acceptor = -1;
options->password_authentication = -1;
options->kbd_interactive_authentication = -1;
options->permit_empty_passwd = -1;
options->permit_user_env = -1;
options->permit_user_env_allowlist = NULL;
options->compression = -1;
options->rekey_limit = -1;
options->rekey_interval = -1;
options->allow_tcp_forwarding = -1;
options->allow_streamlocal_forwarding = -1;
options->allow_agent_forwarding = -1;
options->num_allow_users = 0;
options->num_deny_users = 0;
options->num_allow_groups = 0;
options->num_deny_groups = 0;
options->ciphers = NULL;
options->macs = NULL;
options->kex_algorithms = NULL;
options->ca_sign_algorithms = NULL;
options->fwd_opts.gateway_ports = -1;
options->fwd_opts.streamlocal_bind_mask = (mode_t)-1;
options->fwd_opts.streamlocal_bind_unlink = -1;
options->num_subsystems = 0;
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;
options->use_dns = -1;
options->client_alive_interval = -1;
options->client_alive_count_max = -1;
options->num_authkeys_files = 0;
options->num_accept_env = 0;
options->num_setenv = 0;
options->permit_tun = -1;
options->permitted_opens = NULL;
options->permitted_listens = NULL;
options->adm_forced_command = NULL;
options->chroot_directory = NULL;
options->authorized_keys_command = NULL;
options->authorized_keys_command_user = NULL;
options->revoked_keys_file = NULL;
options->sk_provider = NULL;
options->trusted_user_ca_keys = NULL;
options->authorized_principals_file = NULL;
options->authorized_principals_command = NULL;
options->authorized_principals_command_user = NULL;
options->ip_qos_interactive = -1;
options->ip_qos_bulk = -1;
options->version_addendum = NULL;
options->fingerprint_hash = -1;
options->disable_forwarding = -1;
options->expose_userauth_info = -1;
options->required_rsa_size = -1;
+ options->channel_timeouts = NULL;
+ options->num_channel_timeouts = 0;
+ options->unused_connection_timeout = -1;
options->use_blacklist = -1;
}
/* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */
static int
option_clear_or_none(const char *o)
{
return o == NULL || strcasecmp(o, "none") == 0;
}
static void
assemble_algorithms(ServerOptions *o)
{
char *all_cipher, *all_mac, *all_kex, *all_key, *all_sig;
char *def_cipher, *def_mac, *def_kex, *def_key, *def_sig;
int r;
all_cipher = cipher_alg_list(',', 0);
all_mac = mac_alg_list(',');
all_kex = kex_alg_list(',');
all_key = sshkey_alg_list(0, 0, 1, ',');
all_sig = sshkey_alg_list(0, 1, 1, ',');
/* remove unsupported algos from default lists */
def_cipher = match_filter_allowlist(KEX_SERVER_ENCRYPT, all_cipher);
def_mac = match_filter_allowlist(KEX_SERVER_MAC, all_mac);
def_kex = match_filter_allowlist(KEX_SERVER_KEX, all_kex);
def_key = match_filter_allowlist(KEX_DEFAULT_PK_ALG, all_key);
def_sig = match_filter_allowlist(SSH_ALLOWED_CA_SIGALGS, all_sig);
#define ASSEMBLE(what, defaults, all) \
do { \
if ((r = kex_assemble_names(&o->what, defaults, all)) != 0) \
fatal_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_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);
free(def_key);
free(def_sig);
}
static const char *defaultkey = "[default]";
void
servconf_add_hostkey(const char *file, const int line,
ServerOptions *options, const char *path, int userprovided)
{
char *apath = derelativise_path(path);
if (file == defaultkey && access(path, R_OK) != 0)
return;
opt_array_append2(file, line, "HostKey",
&options->host_key_files, &options->host_key_file_userprovided,
&options->num_host_key_files, apath, userprovided);
free(apath);
}
void
servconf_add_hostcert(const char *file, const int line,
ServerOptions *options, const char *path)
{
char *apath = derelativise_path(path);
opt_array_append(file, line, "HostCertificate",
&options->host_cert_files, &options->num_host_cert_files, apath);
free(apath);
}
void
fill_default_server_options(ServerOptions *options)
{
u_int i;
/* Portable-specific options */
if (options->use_pam == -1)
options->use_pam = 1;
/* Standard Options */
if (options->num_host_key_files == 0) {
/* fill default hostkeys for protocols */
servconf_add_hostkey(defaultkey, 0, options,
_PATH_HOST_RSA_KEY_FILE, 0);
#ifdef OPENSSL_HAS_ECC
servconf_add_hostkey(defaultkey, 0, options,
_PATH_HOST_ECDSA_KEY_FILE, 0);
#endif
servconf_add_hostkey(defaultkey, 0, options,
_PATH_HOST_ED25519_KEY_FILE, 0);
#ifdef WITH_XMSS
servconf_add_hostkey(defaultkey, 0, options,
_PATH_HOST_XMSS_KEY_FILE, 0);
#endif /* WITH_XMSS */
}
if (options->num_host_key_files == 0)
fatal("No host key files found");
/* No certificates by default */
if (options->num_ports == 0)
options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
if (options->address_family == -1)
options->address_family = AF_UNSPEC;
if (options->listen_addrs == NULL)
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)
options->permit_root_login = PERMIT_NO;
if (options->ignore_rhosts == -1)
options->ignore_rhosts = 1;
if (options->ignore_user_known_hosts == -1)
options->ignore_user_known_hosts = 0;
if (options->print_motd == -1)
options->print_motd = 1;
if (options->print_lastlog == -1)
options->print_lastlog = 1;
if (options->x11_forwarding == -1)
options->x11_forwarding = 1;
if (options->x11_display_offset == -1)
options->x11_display_offset = 10;
if (options->x11_use_localhost == -1)
options->x11_use_localhost = 1;
if (options->xauth_location == NULL)
options->xauth_location = xstrdup(_PATH_XAUTH);
if (options->permit_tty == -1)
options->permit_tty = 1;
if (options->permit_user_rc == -1)
options->permit_user_rc = 1;
if (options->strict_modes == -1)
options->strict_modes = 1;
if (options->tcp_keep_alive == -1)
options->tcp_keep_alive = 1;
if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
options->log_facility = SYSLOG_FACILITY_AUTH;
if (options->log_level == SYSLOG_LEVEL_NOT_SET)
options->log_level = SYSLOG_LEVEL_INFO;
if (options->hostbased_authentication == -1)
options->hostbased_authentication = 0;
if (options->hostbased_uses_name_from_packet_only == -1)
options->hostbased_uses_name_from_packet_only = 0;
if (options->pubkey_authentication == -1)
options->pubkey_authentication = 1;
if (options->pubkey_auth_options == -1)
options->pubkey_auth_options = 0;
if (options->kerberos_authentication == -1)
options->kerberos_authentication = 0;
if (options->kerberos_or_local_passwd == -1)
options->kerberos_or_local_passwd = 1;
if (options->kerberos_ticket_cleanup == -1)
options->kerberos_ticket_cleanup = 1;
if (options->kerberos_get_afs_token == -1)
options->kerberos_get_afs_token = 0;
if (options->gss_authentication == -1)
options->gss_authentication = 0;
if (options->gss_cleanup_creds == -1)
options->gss_cleanup_creds = 1;
if (options->gss_strict_acceptor == -1)
options->gss_strict_acceptor = 1;
if (options->password_authentication == -1)
options->password_authentication = 0;
if (options->kbd_interactive_authentication == -1)
options->kbd_interactive_authentication = 1;
if (options->permit_empty_passwd == -1)
options->permit_empty_passwd = 0;
if (options->permit_user_env == -1) {
options->permit_user_env = 0;
options->permit_user_env_allowlist = NULL;
}
if (options->compression == -1)
#ifdef WITH_ZLIB
options->compression = COMP_DELAYED;
#else
options->compression = COMP_NONE;
#endif
if (options->rekey_limit == -1)
options->rekey_limit = 0;
if (options->rekey_interval == -1)
options->rekey_interval = 0;
if (options->allow_tcp_forwarding == -1)
options->allow_tcp_forwarding = FORWARD_ALLOW;
if (options->allow_streamlocal_forwarding == -1)
options->allow_streamlocal_forwarding = FORWARD_ALLOW;
if (options->allow_agent_forwarding == -1)
options->allow_agent_forwarding = 1;
if (options->fwd_opts.gateway_ports == -1)
options->fwd_opts.gateway_ports = 0;
if (options->max_startups == -1)
options->max_startups = 100;
if (options->max_startups_rate == -1)
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)
options->max_sessions = DEFAULT_SESSIONS_MAX;
if (options->use_dns == -1)
options->use_dns = 1;
if (options->client_alive_interval == -1)
options->client_alive_interval = 0;
if (options->client_alive_count_max == -1)
options->client_alive_count_max = 3;
if (options->num_authkeys_files == 0) {
opt_array_append(defaultkey, 0, "AuthorizedKeysFiles",
&options->authorized_keys_files,
&options->num_authkeys_files,
_PATH_SSH_USER_PERMITTED_KEYS);
opt_array_append(defaultkey, 0, "AuthorizedKeysFiles",
&options->authorized_keys_files,
&options->num_authkeys_files,
_PATH_SSH_USER_PERMITTED_KEYS2);
}
if (options->permit_tun == -1)
options->permit_tun = SSH_TUNMODE_NO;
if (options->ip_qos_interactive == -1)
options->ip_qos_interactive = IPTOS_DSCP_AF21;
if (options->ip_qos_bulk == -1)
options->ip_qos_bulk = IPTOS_DSCP_CS1;
if (options->version_addendum == NULL)
options->version_addendum = xstrdup(SSH_VERSION_FREEBSD);
if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1)
options->fwd_opts.streamlocal_bind_mask = 0177;
if (options->fwd_opts.streamlocal_bind_unlink == -1)
options->fwd_opts.streamlocal_bind_unlink = 0;
if (options->fingerprint_hash == -1)
options->fingerprint_hash = SSH_FP_HASH_DEFAULT;
if (options->disable_forwarding == -1)
options->disable_forwarding = 0;
if (options->expose_userauth_info == -1)
options->expose_userauth_info = 0;
if (options->sk_provider == NULL)
options->sk_provider = xstrdup("internal");
if (options->required_rsa_size == -1)
options->required_rsa_size = SSH_RSA_MINIMUM_MODULUS_SIZE;
+ if (options->unused_connection_timeout == -1)
+ options->unused_connection_timeout = 0;
if (options->use_blacklist == -1)
options->use_blacklist = 0;
assemble_algorithms(options);
/* Turn privilege separation and sandboxing on by default */
if (use_privsep == -1)
use_privsep = PRIVSEP_ON;
#define CLEAR_ON_NONE(v) \
do { \
if (option_clear_or_none(v)) { \
free(v); \
v = NULL; \
} \
} while(0)
+#define CLEAR_ON_NONE_ARRAY(v, nv, none) \
+ do { \
+ if (options->nv == 1 && \
+ strcasecmp(options->v[0], none) == 0) { \
+ free(options->v[0]); \
+ free(options->v); \
+ options->v = NULL; \
+ options->nv = 0; \
+ } \
+ } while (0)
CLEAR_ON_NONE(options->pid_file);
CLEAR_ON_NONE(options->xauth_location);
CLEAR_ON_NONE(options->banner);
CLEAR_ON_NONE(options->trusted_user_ca_keys);
CLEAR_ON_NONE(options->revoked_keys_file);
CLEAR_ON_NONE(options->sk_provider);
CLEAR_ON_NONE(options->authorized_principals_file);
CLEAR_ON_NONE(options->adm_forced_command);
CLEAR_ON_NONE(options->chroot_directory);
CLEAR_ON_NONE(options->routing_domain);
CLEAR_ON_NONE(options->host_key_agent);
+
for (i = 0; i < options->num_host_key_files; i++)
CLEAR_ON_NONE(options->host_key_files[i]);
for (i = 0; i < options->num_host_cert_files; i++)
CLEAR_ON_NONE(options->host_cert_files[i]);
-#undef CLEAR_ON_NONE
- /* Similar handling for AuthenticationMethods=any */
- if (options->num_auth_methods == 1 &&
- strcmp(options->auth_methods[0], "any") == 0) {
- free(options->auth_methods[0]);
- options->auth_methods[0] = NULL;
- options->num_auth_methods = 0;
- }
+ CLEAR_ON_NONE_ARRAY(channel_timeouts, num_channel_timeouts, "none");
+ CLEAR_ON_NONE_ARRAY(auth_methods, num_auth_methods, "any");
+#undef CLEAR_ON_NONE
+#undef CLEAR_ON_NONE_ARRAY
}
/* Keyword tokens. */
typedef enum {
sBadOption, /* == unknown option */
/* Portable-specific options */
sUsePAM,
/* Standard Options */
sPort, sHostKeyFile, sLoginGraceTime,
sPermitRootLogin, sLogFacility, sLogLevel, sLogVerbose,
sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
sKerberosGetAFSToken, sPasswordAuthentication,
sKbdInteractiveAuthentication, sListenAddress, sAddressFamily,
sPrintMotd, sPrintLastLog, sIgnoreRhosts,
sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
sPermitTTY, sStrictModes, sEmptyPasswd, sTCPKeepAlive,
sPermitUserEnvironment, sAllowTcpForwarding, sCompression,
sRekeyLimit, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
sIgnoreUserKnownHosts, sCiphers, sMacs, sPidFile, sModuliFile,
sGatewayPorts, sPubkeyAuthentication, sPubkeyAcceptedAlgorithms,
sXAuthLocation, sSubsystem, sMaxStartups, sMaxAuthTries, sMaxSessions,
sBanner, sUseDNS, sHostbasedAuthentication,
sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedAlgorithms,
sHostKeyAlgorithms, sPerSourceMaxStartups, sPerSourceNetBlockSize,
sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile,
sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor,
sAcceptEnv, sSetEnv, sPermitTunnel,
sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory,
sUsePrivilegeSeparation, sAllowAgentForwarding,
sHostCertificate, sInclude,
sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile,
sAuthorizedPrincipalsCommand, sAuthorizedPrincipalsCommandUser,
sKexAlgorithms, sCASignatureAlgorithms, sIPQoS, sVersionAddendum,
sAuthorizedKeysCommand, sAuthorizedKeysCommandUser,
sAuthenticationMethods, sHostKeyAgent, sPermitUserRC,
sStreamLocalBindMask, sStreamLocalBindUnlink,
sAllowStreamLocalForwarding, sFingerprintHash, sDisableForwarding,
sExposeAuthInfo, sRDomain, sPubkeyAuthOptions, sSecurityKeyProvider,
- sRequiredRSASize,
+ sRequiredRSASize, sChannelTimeout, sUnusedConnectionTimeout,
sUseBlacklist,
sDeprecated, sIgnore, sUnsupported
} ServerOpCodes;
#define SSHCFG_GLOBAL 0x01 /* allowed in main section of config */
#define SSHCFG_MATCH 0x02 /* allowed inside a Match section */
#define SSHCFG_ALL (SSHCFG_GLOBAL|SSHCFG_MATCH)
#define SSHCFG_NEVERMATCH 0x04 /* Match never matches; internal only */
#define SSHCFG_MATCH_ONLY 0x08 /* Match only in conditional blocks; internal only */
/* Textual representation of the tokens. */
static struct {
const char *name;
ServerOpCodes opcode;
u_int flags;
} keywords[] = {
/* Portable-specific options */
#ifdef USE_PAM
{ "usepam", sUsePAM, SSHCFG_GLOBAL },
#else
{ "usepam", sUnsupported, SSHCFG_GLOBAL },
#endif
{ "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL },
/* Standard Options */
{ "port", sPort, SSHCFG_GLOBAL },
{ "hostkey", sHostKeyFile, SSHCFG_GLOBAL },
{ "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 },
{ "hostbasedacceptedalgorithms", sHostbasedAcceptedAlgorithms, SSHCFG_ALL },
{ "hostbasedacceptedkeytypes", sHostbasedAcceptedAlgorithms, SSHCFG_ALL }, /* obsolete */
{ "hostkeyalgorithms", sHostKeyAlgorithms, SSHCFG_GLOBAL },
{ "rsaauthentication", sDeprecated, SSHCFG_ALL },
{ "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_ALL },
{ "pubkeyacceptedalgorithms", sPubkeyAcceptedAlgorithms, SSHCFG_ALL },
{ "pubkeyacceptedkeytypes", sPubkeyAcceptedAlgorithms, SSHCFG_ALL }, /* obsolete */
{ "pubkeyauthoptions", sPubkeyAuthOptions, SSHCFG_ALL },
{ "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, /* alias */
#ifdef KRB5
{ "kerberosauthentication", sKerberosAuthentication, SSHCFG_ALL },
{ "kerberosorlocalpasswd", sKerberosOrLocalPasswd, SSHCFG_GLOBAL },
{ "kerberosticketcleanup", sKerberosTicketCleanup, SSHCFG_GLOBAL },
#ifdef USE_AFS
{ "kerberosgetafstoken", sKerberosGetAFSToken, SSHCFG_GLOBAL },
#else
{ "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
#endif
#else
{ "kerberosauthentication", sUnsupported, SSHCFG_ALL },
{ "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL },
{ "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL },
{ "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
#endif
{ "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL },
{ "afstokenpassing", sUnsupported, SSHCFG_GLOBAL },
#ifdef GSSAPI
{ "gssapiauthentication", sGssAuthentication, SSHCFG_ALL },
{ "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL },
{ "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL },
#else
{ "gssapiauthentication", sUnsupported, SSHCFG_ALL },
{ "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
{ "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL },
#endif
{ "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL },
{ "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL },
{ "challengeresponseauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, /* alias */
{ "skeyauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, /* alias */
{ "checkmail", sDeprecated, SSHCFG_GLOBAL },
{ "listenaddress", sListenAddress, SSHCFG_GLOBAL },
{ "addressfamily", sAddressFamily, SSHCFG_GLOBAL },
{ "printmotd", sPrintMotd, SSHCFG_GLOBAL },
#ifdef DISABLE_LASTLOG
{ "printlastlog", sUnsupported, SSHCFG_GLOBAL },
#else
{ "printlastlog", sPrintLastLog, SSHCFG_GLOBAL },
#endif
{ "ignorerhosts", sIgnoreRhosts, SSHCFG_ALL },
{ "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL },
{ "x11forwarding", sX11Forwarding, SSHCFG_ALL },
{ "x11displayoffset", sX11DisplayOffset, SSHCFG_ALL },
{ "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL },
{ "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL },
{ "strictmodes", sStrictModes, SSHCFG_GLOBAL },
{ "permitemptypasswords", sEmptyPasswd, SSHCFG_ALL },
{ "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL },
{ "uselogin", sDeprecated, SSHCFG_GLOBAL },
{ "compression", sCompression, SSHCFG_GLOBAL },
{ "rekeylimit", sRekeyLimit, SSHCFG_ALL },
{ "tcpkeepalive", sTCPKeepAlive, SSHCFG_GLOBAL },
{ "keepalive", sTCPKeepAlive, SSHCFG_GLOBAL }, /* obsolete alias */
{ "allowtcpforwarding", sAllowTcpForwarding, SSHCFG_ALL },
{ "allowagentforwarding", sAllowAgentForwarding, SSHCFG_ALL },
{ "allowusers", sAllowUsers, SSHCFG_ALL },
{ "denyusers", sDenyUsers, SSHCFG_ALL },
{ "allowgroups", sAllowGroups, SSHCFG_ALL },
{ "denygroups", sDenyGroups, SSHCFG_ALL },
{ "ciphers", sCiphers, SSHCFG_GLOBAL },
{ "macs", sMacs, SSHCFG_GLOBAL },
{ "protocol", sIgnore, SSHCFG_GLOBAL },
{ "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 },
{ "usedns", sUseDNS, SSHCFG_GLOBAL },
{ "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL },
{ "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL },
{ "clientaliveinterval", sClientAliveInterval, SSHCFG_ALL },
{ "clientalivecountmax", sClientAliveCountMax, SSHCFG_ALL },
{ "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_ALL },
{ "authorizedkeysfile2", sDeprecated, SSHCFG_ALL },
{ "useprivilegeseparation", sDeprecated, SSHCFG_GLOBAL},
{ "acceptenv", sAcceptEnv, SSHCFG_ALL },
{ "setenv", sSetEnv, SSHCFG_ALL },
{ "permittunnel", sPermitTunnel, SSHCFG_ALL },
{ "permittty", sPermitTTY, SSHCFG_ALL },
{ "permituserrc", sPermitUserRC, SSHCFG_ALL },
{ "match", sMatch, SSHCFG_ALL },
{ "permitopen", sPermitOpen, SSHCFG_ALL },
{ "permitlisten", sPermitListen, SSHCFG_ALL },
{ "forcecommand", sForceCommand, SSHCFG_ALL },
{ "chrootdirectory", sChrootDirectory, SSHCFG_ALL },
{ "hostcertificate", sHostCertificate, SSHCFG_GLOBAL },
{ "revokedkeys", sRevokedKeys, SSHCFG_ALL },
{ "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL },
{ "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL },
{ "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL },
{ "include", sInclude, SSHCFG_ALL },
{ "ipqos", sIPQoS, SSHCFG_ALL },
{ "authorizedkeyscommand", sAuthorizedKeysCommand, SSHCFG_ALL },
{ "authorizedkeyscommanduser", sAuthorizedKeysCommandUser, SSHCFG_ALL },
{ "authorizedprincipalscommand", sAuthorizedPrincipalsCommand, SSHCFG_ALL },
{ "authorizedprincipalscommanduser", sAuthorizedPrincipalsCommandUser, SSHCFG_ALL },
{ "versionaddendum", sVersionAddendum, SSHCFG_GLOBAL },
{ "authenticationmethods", sAuthenticationMethods, SSHCFG_ALL },
{ "streamlocalbindmask", sStreamLocalBindMask, SSHCFG_ALL },
{ "streamlocalbindunlink", sStreamLocalBindUnlink, SSHCFG_ALL },
{ "allowstreamlocalforwarding", sAllowStreamLocalForwarding, SSHCFG_ALL },
{ "fingerprinthash", sFingerprintHash, SSHCFG_GLOBAL },
{ "disableforwarding", sDisableForwarding, SSHCFG_ALL },
{ "exposeauthinfo", sExposeAuthInfo, SSHCFG_ALL },
{ "rdomain", sRDomain, SSHCFG_ALL },
{ "casignaturealgorithms", sCASignatureAlgorithms, SSHCFG_ALL },
{ "securitykeyprovider", sSecurityKeyProvider, SSHCFG_GLOBAL },
{ "requiredrsasize", sRequiredRSASize, SSHCFG_ALL },
+ { "channeltimeout", sChannelTimeout, SSHCFG_ALL },
+ { "unusedconnectiontimeout", sUnusedConnectionTimeout, SSHCFG_ALL },
{ "useblacklist", sUseBlacklist, SSHCFG_GLOBAL },
{ "useblocklist", sUseBlacklist, SSHCFG_GLOBAL }, /* alias */
{ "noneenabled", sUnsupported, SSHCFG_ALL },
{ "hpndisabled", sDeprecated, SSHCFG_ALL },
{ "hpnbuffersize", sDeprecated, SSHCFG_ALL },
{ "tcprcvbufpoll", sDeprecated, SSHCFG_ALL },
{ NULL, sBadOption, 0 }
};
static struct {
int val;
char *text;
} tunmode_desc[] = {
{ SSH_TUNMODE_NO, "no" },
{ SSH_TUNMODE_POINTOPOINT, "point-to-point" },
{ SSH_TUNMODE_ETHERNET, "ethernet" },
{ SSH_TUNMODE_YES, "yes" },
{ -1, NULL }
};
/* Returns an opcode name from its number */
static const char *
lookup_opcode_name(ServerOpCodes code)
{
u_int i;
for (i = 0; keywords[i].name != NULL; i++)
if (keywords[i].opcode == code)
return(keywords[i].name);
return "UNKNOWN";
}
/*
* Returns the number of the token pointed to by cp or sBadOption.
*/
static ServerOpCodes
parse_token(const char *cp, const char *filename,
int linenum, u_int *flags)
{
u_int i;
for (i = 0; keywords[i].name; i++)
if (strcasecmp(cp, keywords[i].name) == 0) {
*flags = keywords[i].flags;
return keywords[i].opcode;
}
error("%s: line %d: Bad configuration option: %s",
filename, linenum, cp);
return sBadOption;
}
char *
derelativise_path(const char *path)
{
char *expanded, *ret, cwd[PATH_MAX];
if (strcasecmp(path, "none") == 0)
return xstrdup("none");
expanded = tilde_expand_filename(path, getuid());
if (path_absolute(expanded))
return expanded;
if (getcwd(cwd, sizeof(cwd)) == NULL)
fatal_f("getcwd: %s", strerror(errno));
xasprintf(&ret, "%s/%s", cwd, expanded);
free(expanded);
return ret;
}
static void
add_listen_addr(ServerOptions *options, const char *addr,
const char *rdomain, int port)
{
u_int i;
if (port > 0)
add_one_listen_addr(options, addr, rdomain, port);
else {
for (i = 0; i < options->num_ports; i++) {
add_one_listen_addr(options, addr, rdomain,
options->ports[i]);
}
}
}
static void
add_one_listen_addr(ServerOptions *options, const char *addr,
const char *rdomain, int port)
{
struct addrinfo hints, *ai, *aitop;
char strport[NI_MAXSERV];
int gaierr;
u_int i;
/* Find listen_addrs entry for this rdomain */
for (i = 0; i < options->num_listen_addrs; i++) {
if (rdomain == NULL && options->listen_addrs[i].rdomain == NULL)
break;
if (rdomain == NULL || options->listen_addrs[i].rdomain == NULL)
continue;
if (strcmp(rdomain, options->listen_addrs[i].rdomain) == 0)
break;
}
if (i >= options->num_listen_addrs) {
/* No entry for this rdomain; allocate one */
if (i >= INT_MAX)
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));
i = options->num_listen_addrs++;
if (rdomain != NULL)
options->listen_addrs[i].rdomain = xstrdup(rdomain);
}
/* options->listen_addrs[i] points to the addresses for this rdomain */
memset(&hints, 0, sizeof(hints));
hints.ai_family = options->address_family;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
snprintf(strport, sizeof strport, "%d", port);
if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
fatal("bad addr or host: %s (%s)",
addr ? addr : "<NULL>",
ssh_gai_strerror(gaierr));
for (ai = aitop; ai->ai_next; ai = ai->ai_next)
;
ai->ai_next = options->listen_addrs[i].addrs;
options->listen_addrs[i].addrs = aitop;
}
/* Returns nonzero if the routing domain name is valid */
static int
valid_rdomain(const char *name)
{
#if defined(HAVE_SYS_VALID_RDOMAIN)
return sys_valid_rdomain(name);
#elif defined(__OpenBSD__)
const char *errstr;
long long num;
struct rt_tableinfo info;
int mib[6];
size_t miblen = sizeof(mib);
if (name == NULL)
return 1;
num = strtonum(name, 0, 255, &errstr);
if (errstr != NULL)
return 0;
/* Check whether the table actually exists */
memset(mib, 0, sizeof(mib));
mib[0] = CTL_NET;
mib[1] = PF_ROUTE;
mib[4] = NET_RT_TABLE;
mib[5] = (int)num;
if (sysctl(mib, 6, &info, &miblen, NULL, 0) == -1)
return 0;
return 1;
#else /* defined(__OpenBSD__) */
error("Routing domains are not supported on this platform");
return 0;
#endif
}
/*
* Queue a ListenAddress to be processed once we have all of the Ports
* and AddressFamily options.
*/
static void
queue_listen_addr(ServerOptions *options, const char *addr,
const char *rdomain, int port)
{
struct queued_listenaddr *qla;
options->queued_listen_addrs = xrecallocarray(
options->queued_listen_addrs,
options->num_queued_listens, options->num_queued_listens + 1,
sizeof(*options->queued_listen_addrs));
qla = &options->queued_listen_addrs[options->num_queued_listens++];
qla->addr = xstrdup(addr);
qla->port = port;
qla->rdomain = rdomain == NULL ? NULL : xstrdup(rdomain);
}
/*
* Process queued (text) ListenAddress entries.
*/
static void
process_queued_listen_addrs(ServerOptions *options)
{
u_int i;
struct queued_listenaddr *qla;
if (options->num_ports == 0)
options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
if (options->address_family == -1)
options->address_family = AF_UNSPEC;
for (i = 0; i < options->num_queued_listens; i++) {
qla = &options->queued_listen_addrs[i];
add_listen_addr(options, qla->addr, qla->rdomain, qla->port);
free(qla->addr);
free(qla->rdomain);
}
free(options->queued_listen_addrs);
options->queued_listen_addrs = NULL;
options->num_queued_listens = 0;
}
/*
* Inform channels layer of permitopen options for a single forwarding
* direction (local/remote).
*/
static void
process_permitopen_list(struct ssh *ssh, ServerOpCodes opcode,
char **opens, u_int num_opens)
{
u_int i;
int port;
char *host, *arg, *oarg;
int where = opcode == sPermitOpen ? FORWARD_LOCAL : FORWARD_REMOTE;
const char *what = lookup_opcode_name(opcode);
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]);
host = hpdelim(&arg);
if (host == NULL)
fatal_f("missing host in %s", what);
host = cleanhostname(host);
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, host, port);
free(oarg);
}
}
/*
* Inform channels layer of permitopen options from configuration.
*/
void
process_permitopen(struct ssh *ssh, ServerOptions *options)
{
process_permitopen_list(ssh, sPermitOpen,
options->permitted_opens, options->num_permitted_opens);
process_permitopen_list(ssh, sPermitListen,
options->permitted_listens,
options->num_permitted_listens);
}
+/* Parse a ChannelTimeout clause "pattern=interval" */
+static int
+parse_timeout(const char *s, char **typep, u_int *secsp)
+{
+ char *cp, *sdup;
+ int secs;
+
+ if (typep != NULL)
+ *typep = NULL;
+ if (secsp != NULL)
+ *secsp = 0;
+ if (s == NULL)
+ return -1;
+ sdup = xstrdup(s);
+
+ if ((cp = strchr(sdup, '=')) == NULL || cp == sdup) {
+ free(sdup);
+ return -1;
+ }
+ *cp++ = '\0';
+ if ((secs = convtime(cp)) < 0) {
+ free(sdup);
+ return -1;
+ }
+ /* success */
+ if (typep != NULL)
+ *typep = xstrdup(sdup);
+ if (secsp != NULL)
+ *secsp = (u_int)secs;
+ free(sdup);
+ return 0;
+}
+
+void
+process_channel_timeouts(struct ssh *ssh, ServerOptions *options)
+{
+ u_int i, secs;
+ char *type;
+
+ debug3_f("setting %u timeouts", options->num_channel_timeouts);
+ channel_clear_timeouts(ssh);
+ for (i = 0; i < options->num_channel_timeouts; i++) {
+ if (parse_timeout(options->channel_timeouts[i],
+ &type, &secs) != 0) {
+ fatal_f("internal error: bad timeout %s",
+ options->channel_timeouts[i]);
+ }
+ channel_add_timeout(ssh, type, secs);
+ free(type);
+ }
+}
+
struct connection_info *
get_connection_info(struct ssh *ssh, int populate, int use_dns)
{
static struct connection_info ci;
if (ssh == NULL || !populate)
return &ci;
ci.host = auth_get_canonical_hostname(ssh, use_dns);
ci.address = ssh_remote_ipaddr(ssh);
ci.laddress = ssh_local_ipaddr(ssh);
ci.lport = ssh_local_port(ssh);
ci.rdomain = ssh_packet_rdomain_in(ssh);
return &ci;
}
/*
* The strategy for the Match blocks is that the config file is parsed twice.
*
* The first time is at startup. activep is initialized to 1 and the
* directives in the global context are processed and acted on. Hitting a
* Match directive unsets activep and the directives inside the block are
* checked for syntax only.
*
* The second time is after a connection has been established but before
* authentication. activep is initialized to 2 and global config directives
* are ignored since they have already been processed. If the criteria in a
* Match block is met, activep is set and the subsequent directives
* processed and actioned until EOF or another Match block unsets it. Any
* options set are copied into the main server config.
*
* Potential additions/improvements:
* - Add Match support for pre-kex directives, eg. Ciphers.
*
* - Add a Tag directive (idea from David Leonard) ala pf, eg:
* Match Address 192.168.0.*
* Tag trusted
* Match Group wheel
* Tag trusted
* Match Tag trusted
* AllowTcpForwarding yes
* GatewayPorts clientspecified
* [...]
*
* - Add a PermittedChannelRequests directive
* Match Group shell
* PermittedChannelRequests session,forwarded-tcpip
*/
static int
match_cfg_line_group(const char *grps, int line, const char *user)
{
int result = 0;
struct passwd *pw;
if (user == NULL)
goto out;
if ((pw = getpwnam(user)) == NULL) {
debug("Can't match group at line %d because user %.100s does "
"not exist", line, user);
} else if (ga_init(pw->pw_name, pw->pw_gid) == 0) {
debug("Can't Match group because user %.100s not in any group "
"at line %d", user, line);
} else if (ga_match_pattern_list(grps) != 1) {
debug("user %.100s does not match group list %.100s at line %d",
user, grps, line);
} else {
debug("user %.100s matched group list %.100s at line %d", user,
grps, line);
result = 1;
}
out:
ga_free();
return result;
}
static void
match_test_missing_fatal(const char *criteria, const char *attrib)
{
fatal("'Match %s' in configuration but '%s' not in connection "
"test specification.", criteria, attrib);
}
/*
* All of the attributes on a single Match line are ANDed together, so we need
* to check every attribute and set the result to zero if any attribute does
* not match.
*/
static int
match_cfg_line(char **condition, int line, struct connection_info *ci)
{
int result = 1, attributes = 0, port;
char *arg, *attrib, *cp = *condition;
if (ci == NULL)
debug3("checking syntax for 'Match %s'", cp);
else
debug3("checking match for '%s' user %s host %s addr %s "
"laddr %s lport %d", cp, ci->user ? ci->user : "(null)",
ci->host ? ci->host : "(null)",
ci->address ? ci->address : "(null)",
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' && *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;
}
/* All other criteria require an argument */
if ((arg = strdelim(&cp)) == NULL ||
*arg == '\0' || *arg == '#') {
error("Missing Match criteria for %s", attrib);
return -1;
}
if (strcasecmp(attrib, "user") == 0) {
if (ci == NULL || (ci->test && ci->user == NULL)) {
result = 0;
continue;
}
if (ci->user == NULL)
match_test_missing_fatal("User", "user");
if (match_usergroup_pattern_list(ci->user, arg) != 1)
result = 0;
else
debug("user %.100s matched 'User %.100s' at "
"line %d", ci->user, arg, line);
} else if (strcasecmp(attrib, "group") == 0) {
if (ci == NULL || (ci->test && ci->user == NULL)) {
result = 0;
continue;
}
if (ci->user == NULL)
match_test_missing_fatal("Group", "user");
switch (match_cfg_line_group(arg, line, ci->user)) {
case -1:
return -1;
case 0:
result = 0;
}
} else if (strcasecmp(attrib, "host") == 0) {
if (ci == NULL || (ci->test && ci->host == NULL)) {
result = 0;
continue;
}
if (ci->host == NULL)
match_test_missing_fatal("Host", "host");
if (match_hostname(ci->host, arg) != 1)
result = 0;
else
debug("connection from %.100s matched 'Host "
"%.100s' at line %d", ci->host, arg, line);
} else if (strcasecmp(attrib, "address") == 0) {
if (ci == NULL || (ci->test && ci->address == NULL)) {
if (addr_match_list(NULL, arg) != 0)
fatal("Invalid Match address argument "
"'%s' at line %d", arg, line);
result = 0;
continue;
}
if (ci->address == NULL)
match_test_missing_fatal("Address", "addr");
switch (addr_match_list(ci->address, arg)) {
case 1:
debug("connection from %.100s matched 'Address "
"%.100s' at line %d", ci->address, arg, line);
break;
case 0:
case -1:
result = 0;
break;
case -2:
return -1;
}
} else if (strcasecmp(attrib, "localaddress") == 0){
if (ci == NULL || (ci->test && ci->laddress == NULL)) {
if (addr_match_list(NULL, arg) != 0)
fatal("Invalid Match localaddress "
"argument '%s' at line %d", arg,
line);
result = 0;
continue;
}
if (ci->laddress == NULL)
match_test_missing_fatal("LocalAddress",
"laddr");
switch (addr_match_list(ci->laddress, arg)) {
case 1:
debug("connection from %.100s matched "
"'LocalAddress %.100s' at line %d",
ci->laddress, arg, line);
break;
case 0:
case -1:
result = 0;
break;
case -2:
return -1;
}
} else if (strcasecmp(attrib, "localport") == 0) {
if ((port = a2port(arg)) == -1) {
error("Invalid LocalPort '%s' on Match line",
arg);
return -1;
}
if (ci == NULL || (ci->test && ci->lport == -1)) {
result = 0;
continue;
}
if (ci->lport == 0)
match_test_missing_fatal("LocalPort", "lport");
/* TODO support port lists */
if (port == ci->lport)
debug("connection from %.100s matched "
"'LocalPort %d' at line %d",
ci->laddress, port, line);
else
result = 0;
} else if (strcasecmp(attrib, "rdomain") == 0) {
if (ci == NULL || (ci->test && ci->rdomain == NULL)) {
result = 0;
continue;
}
if (ci->rdomain == NULL)
match_test_missing_fatal("RDomain", "rdomain");
if (match_pattern_list(ci->rdomain, arg, 0) != 1)
result = 0;
else
debug("user %.100s matched 'RDomain %.100s' at "
"line %d", ci->rdomain, arg, line);
} else {
error("Unsupported Match attribute %s", attrib);
return -1;
}
}
if (attributes == 0) {
error("One or more attributes required for Match");
return -1;
}
if (ci != NULL)
debug3("match %sfound", result ? "" : "not ");
*condition = cp;
return result;
}
#define WHITESPACE " \t\r\n"
/* Multistate option parsing */
struct multistate {
char *key;
int value;
};
static const struct multistate multistate_flag[] = {
{ "yes", 1 },
{ "no", 0 },
{ NULL, -1 }
};
static const struct multistate multistate_ignore_rhosts[] = {
{ "yes", IGNORE_RHOSTS_YES },
{ "no", IGNORE_RHOSTS_NO },
{ "shosts-only", IGNORE_RHOSTS_SHOSTS },
{ NULL, -1 }
};
static const struct multistate multistate_addressfamily[] = {
{ "inet", AF_INET },
{ "inet6", AF_INET6 },
{ "any", AF_UNSPEC },
{ NULL, -1 }
};
static const struct multistate multistate_permitrootlogin[] = {
{ "without-password", PERMIT_NO_PASSWD },
{ "prohibit-password", PERMIT_NO_PASSWD },
{ "forced-commands-only", PERMIT_FORCED_ONLY },
{ "yes", PERMIT_YES },
{ "no", PERMIT_NO },
{ NULL, -1 }
};
static const struct multistate multistate_compression[] = {
#ifdef WITH_ZLIB
{ "yes", COMP_DELAYED },
{ "delayed", COMP_DELAYED },
#endif
{ "no", COMP_NONE },
{ NULL, -1 }
};
static const struct multistate multistate_gatewayports[] = {
{ "clientspecified", 2 },
{ "yes", 1 },
{ "no", 0 },
{ NULL, -1 }
};
static const struct multistate multistate_tcpfwd[] = {
{ "yes", FORWARD_ALLOW },
{ "all", FORWARD_ALLOW },
{ "no", FORWARD_DENY },
{ "remote", FORWARD_REMOTE },
{ "local", FORWARD_LOCAL },
{ NULL, -1 }
};
static int
process_server_config_line_depth(ServerOptions *options, char *line,
const char *filename, int linenum, int *activep,
struct connection_info *connectinfo, int *inc_flags, int depth,
struct include_list *includes)
{
char *str, ***chararrayptr, **charptr, *arg, *arg2, *p, *keyword;
int cmdline = 0, *intptr, value, value2, n, port, oactive, r, found;
SyslogFacility *log_facility_ptr;
LogLevel *log_level_ptr;
ServerOpCodes opcode;
u_int i, *uintptr, uvalue, flags = 0;
size_t len;
long long val64;
const struct multistate *multistate_ptr;
const char *errstr;
struct include_item *item;
glob_t gbuf;
char **oav = NULL, **av;
int oac = 0, ac;
int ret = -1;
/* Strip trailing whitespace. Allow \f (form feed) at EOL only */
if ((len = strlen(line)) == 0)
return 0;
for (len--; len > 0; len--) {
if (strchr(WHITESPACE "\f", line[len]) == NULL)
break;
line[len] = '\0';
}
str = line;
if ((keyword = strdelim(&str)) == NULL)
return 0;
/* Ignore leading whitespace */
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(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, 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, keyword);
} else { /* this is a directive we have already processed */
ret = 0;
goto out;
}
}
switch (opcode) {
/* Portable-specific options */
case sUsePAM:
intptr = &options->use_pam;
goto parse_flag;
/* Standard Options */
case sBadOption:
goto out;
case sPort:
/* ignore ports from configfile if cmdline specifies ports */
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 = argv_next(&ac, &av);
if (!arg || *arg == '\0')
fatal("%s line %d: missing port number.",
filename, linenum);
options->ports[options->num_ports++] = a2port(arg);
if (options->ports[options->num_ports-1] <= 0)
fatal("%s line %d: Badly formatted port number.",
filename, linenum);
break;
case sLoginGraceTime:
intptr = &options->login_grace_time;
parse_time:
arg = argv_next(&ac, &av);
if (!arg || *arg == '\0')
fatal("%s line %d: missing time value.",
filename, linenum);
if ((value = convtime(arg)) == -1)
fatal("%s line %d: invalid time value.",
filename, linenum);
if (*activep && *intptr == -1)
*intptr = value;
break;
case sListenAddress:
arg = argv_next(&ac, &av);
if (arg == NULL || *arg == '\0')
fatal("%s line %d: missing address",
filename, linenum);
/* check for bare IPv6 address: no "[]" and 2 or more ":" */
if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL
&& strchr(p+1, ':') != NULL) {
port = 0;
p = arg;
} else {
arg2 = NULL;
p = hpdelim(&arg);
if (p == NULL)
fatal("%s line %d: bad address:port usage",
filename, linenum);
p = cleanhostname(p);
if (arg == NULL)
port = 0;
else if ((port = a2port(arg)) <= 0)
fatal("%s line %d: bad port number",
filename, linenum);
}
/* Optional routing table */
arg2 = NULL;
if ((arg = argv_next(&ac, &av)) != NULL) {
if (strcmp(arg, "rdomain") != 0 ||
(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;
case sAddressFamily:
intptr = &options->address_family;
multistate_ptr = multistate_addressfamily;
parse_multistate:
arg = argv_next(&ac, &av);
if (!arg || *arg == '\0')
fatal("%s line %d: missing argument.",
filename, linenum);
value = -1;
for (i = 0; multistate_ptr[i].key != NULL; i++) {
if (strcasecmp(arg, multistate_ptr[i].key) == 0) {
value = multistate_ptr[i].value;
break;
}
}
if (value == -1)
fatal("%s line %d: unsupported option \"%s\".",
filename, linenum, arg);
if (*activep && *intptr == -1)
*intptr = value;
break;
case sHostKeyFile:
arg = argv_next(&ac, &av);
if (!arg || *arg == '\0')
fatal("%s line %d: missing file name.",
filename, linenum);
if (*activep) {
servconf_add_hostkey(filename, linenum,
options, arg, 1);
}
break;
case sHostKeyAgent:
charptr = &options->host_key_agent;
arg = argv_next(&ac, &av);
if (!arg || *arg == '\0')
fatal("%s line %d: missing socket name.",
filename, linenum);
if (*activep && *charptr == NULL)
*charptr = !strcmp(arg, SSH_AUTHSOCKET_ENV_NAME) ?
xstrdup(arg) : derelativise_path(arg);
break;
case sHostCertificate:
arg = argv_next(&ac, &av);
if (!arg || *arg == '\0')
fatal("%s line %d: missing file name.",
filename, linenum);
if (*activep)
servconf_add_hostcert(filename, linenum, options, arg);
break;
case sPidFile:
charptr = &options->pid_file;
parse_filename:
arg = argv_next(&ac, &av);
if (!arg || *arg == '\0')
fatal("%s line %d: missing file name.",
filename, linenum);
if (*activep && *charptr == NULL) {
*charptr = derelativise_path(arg);
/* increase optional counter */
if (intptr != NULL)
*intptr = *intptr + 1;
}
break;
case sModuliFile:
charptr = &options->moduli_file;
goto parse_filename;
case sPermitRootLogin:
intptr = &options->permit_root_login;
multistate_ptr = multistate_permitrootlogin;
goto parse_multistate;
case sIgnoreRhosts:
intptr = &options->ignore_rhosts;
multistate_ptr = multistate_ignore_rhosts;
goto parse_multistate;
case sIgnoreUserKnownHosts:
intptr = &options->ignore_user_known_hosts;
parse_flag:
multistate_ptr = multistate_flag;
goto parse_multistate;
case sHostbasedAuthentication:
intptr = &options->hostbased_authentication;
goto parse_flag;
case sHostbasedUsesNameFromPacketOnly:
intptr = &options->hostbased_uses_name_from_packet_only;
goto parse_flag;
case sHostbasedAcceptedAlgorithms:
charptr = &options->hostbased_accepted_algos;
parse_pubkey_algos:
arg = argv_next(&ac, &av);
if (!arg || *arg == '\0')
fatal("%s line %d: Missing argument.",
filename, linenum);
if (*arg != '-' &&
!sshkey_names_valid2(*arg == '+' || *arg == '^' ?
arg + 1 : arg, 1))
fatal("%s line %d: Bad key types '%s'.",
filename, linenum, arg ? arg : "<NONE>");
if (*activep && *charptr == NULL)
*charptr = xstrdup(arg);
break;
case sHostKeyAlgorithms:
charptr = &options->hostkeyalgorithms;
goto parse_pubkey_algos;
case sCASignatureAlgorithms:
charptr = &options->ca_sign_algorithms;
goto parse_pubkey_algos;
case sPubkeyAuthentication:
intptr = &options->pubkey_authentication;
goto parse_flag;
case sPubkeyAcceptedAlgorithms:
charptr = &options->pubkey_accepted_algos;
goto parse_pubkey_algos;
case sPubkeyAuthOptions:
intptr = &options->pubkey_auth_options;
value = 0;
while ((arg = argv_next(&ac, &av)) != NULL) {
if (strcasecmp(arg, "none") == 0)
continue;
if (strcasecmp(arg, "touch-required") == 0)
value |= PUBKEYAUTH_TOUCH_REQUIRED;
else if (strcasecmp(arg, "verify-required") == 0)
value |= PUBKEYAUTH_VERIFY_REQUIRED;
else {
error("%s line %d: unsupported %s option %s",
filename, linenum, keyword, arg);
goto out;
}
}
if (*activep && *intptr == -1)
*intptr = value;
break;
case sKerberosAuthentication:
intptr = &options->kerberos_authentication;
goto parse_flag;
case sKerberosOrLocalPasswd:
intptr = &options->kerberos_or_local_passwd;
goto parse_flag;
case sKerberosTicketCleanup:
intptr = &options->kerberos_ticket_cleanup;
goto parse_flag;
case sKerberosGetAFSToken:
intptr = &options->kerberos_get_afs_token;
goto parse_flag;
case sGssAuthentication:
intptr = &options->gss_authentication;
goto parse_flag;
case sGssCleanupCreds:
intptr = &options->gss_cleanup_creds;
goto parse_flag;
case sGssStrictAcceptor:
intptr = &options->gss_strict_acceptor;
goto parse_flag;
case sPasswordAuthentication:
intptr = &options->password_authentication;
goto parse_flag;
case sKbdInteractiveAuthentication:
intptr = &options->kbd_interactive_authentication;
goto parse_flag;
case sPrintMotd:
intptr = &options->print_motd;
goto parse_flag;
case sPrintLastLog:
intptr = &options->print_lastlog;
goto parse_flag;
case sX11Forwarding:
intptr = &options->x11_forwarding;
goto parse_flag;
case sX11DisplayOffset:
intptr = &options->x11_display_offset;
parse_int:
arg = argv_next(&ac, &av);
if ((errstr = atoi_err(arg, &value)) != NULL)
fatal("%s line %d: %s integer value %s.",
filename, linenum, keyword, errstr);
if (*activep && *intptr == -1)
*intptr = value;
break;
case sX11UseLocalhost:
intptr = &options->x11_use_localhost;
goto parse_flag;
case sXAuthLocation:
charptr = &options->xauth_location;
goto parse_filename;
case sPermitTTY:
intptr = &options->permit_tty;
goto parse_flag;
case sPermitUserRC:
intptr = &options->permit_user_rc;
goto parse_flag;
case sStrictModes:
intptr = &options->strict_modes;
goto parse_flag;
case sTCPKeepAlive:
intptr = &options->tcp_keep_alive;
goto parse_flag;
case sEmptyPasswd:
intptr = &options->permit_empty_passwd;
goto parse_flag;
case sPermitUserEnvironment:
intptr = &options->permit_user_env;
charptr = &options->permit_user_env_allowlist;
arg = argv_next(&ac, &av);
if (!arg || *arg == '\0')
fatal("%s line %d: %s missing argument.",
filename, linenum, keyword);
value = 0;
p = NULL;
if (strcmp(arg, "yes") == 0)
value = 1;
else if (strcmp(arg, "no") == 0)
value = 0;
else {
/* Pattern-list specified */
value = 1;
p = xstrdup(arg);
}
if (*activep && *intptr == -1) {
*intptr = value;
*charptr = p;
p = NULL;
}
free(p);
break;
case sCompression:
intptr = &options->compression;
multistate_ptr = multistate_compression;
goto parse_multistate;
case sRekeyLimit:
arg = argv_next(&ac, &av);
if (!arg || *arg == '\0')
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 %s number '%s': %s",
filename, linenum, keyword,
arg, strerror(errno));
if (val64 != 0 && val64 < 16)
fatal("%.200s line %d: %s too small",
filename, linenum, keyword);
}
if (*activep && options->rekey_limit == -1)
options->rekey_limit = val64;
if (ac != 0) { /* optional rekey interval present */
if (strcmp(av[0], "none") == 0) {
(void)argv_next(&ac, &av); /* discard */
break;
}
intptr = &options->rekey_interval;
goto parse_time;
}
break;
case sGatewayPorts:
intptr = &options->fwd_opts.gateway_ports;
multistate_ptr = multistate_gatewayports;
goto parse_multistate;
case sUseDNS:
intptr = &options->use_dns;
goto parse_flag;
case sLogFacility:
log_facility_ptr = &options->log_facility;
arg = argv_next(&ac, &av);
value = log_facility_number(arg);
if (value == SYSLOG_FACILITY_NOT_SET)
fatal("%.200s line %d: unsupported log facility '%s'",
filename, linenum, arg ? arg : "<NONE>");
if (*log_facility_ptr == -1)
*log_facility_ptr = (SyslogFacility) value;
break;
case sLogLevel:
log_level_ptr = &options->log_level;
arg = argv_next(&ac, &av);
value = log_level_number(arg);
if (value == SYSLOG_LEVEL_NOT_SET)
fatal("%.200s line %d: unsupported log level '%s'",
filename, linenum, arg ? arg : "<NONE>");
if (*activep && *log_level_ptr == -1)
*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;
goto parse_multistate;
case sAllowStreamLocalForwarding:
intptr = &options->allow_streamlocal_forwarding;
multistate_ptr = multistate_tcpfwd;
goto parse_multistate;
case sAllowAgentForwarding:
intptr = &options->allow_agent_forwarding;
goto parse_flag;
case sDisableForwarding:
intptr = &options->disable_forwarding;
goto parse_flag;
case sAllowUsers:
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;
opt_array_append(filename, linenum, keyword,
chararrayptr, uintptr, arg);
}
break;
case sDenyUsers:
chararrayptr = &options->deny_users;
uintptr = &options->num_deny_users;
goto parse_allowdenyusers;
case sAllowGroups:
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;
opt_array_append(filename, linenum, keyword,
chararrayptr, uintptr, arg);
}
break;
case sDenyGroups:
chararrayptr = &options->deny_groups;
uintptr = &options->num_deny_groups;
goto parse_allowdenygroups;
case sCiphers:
arg = argv_next(&ac, &av);
if (!arg || *arg == '\0')
fatal("%s line %d: %s missing argument.",
filename, linenum, keyword);
if (*arg != '-' &&
!ciphers_valid(*arg == '+' || *arg == '^' ? arg + 1 : arg))
fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
filename, linenum, arg ? arg : "<NONE>");
if (options->ciphers == NULL)
options->ciphers = xstrdup(arg);
break;
case sMacs:
arg = argv_next(&ac, &av);
if (!arg || *arg == '\0')
fatal("%s line %d: %s missing argument.",
filename, linenum, keyword);
if (*arg != '-' &&
!mac_valid(*arg == '+' || *arg == '^' ? arg + 1 : arg))
fatal("%s line %d: Bad SSH2 mac spec '%s'.",
filename, linenum, arg ? arg : "<NONE>");
if (options->macs == NULL)
options->macs = xstrdup(arg);
break;
case sKexAlgorithms:
arg = argv_next(&ac, &av);
if (!arg || *arg == '\0')
fatal("%s line %d: %s missing argument.",
filename, linenum, keyword);
if (*arg != '-' &&
!kex_names_valid(*arg == '+' || *arg == '^' ?
arg + 1 : arg))
fatal("%s line %d: Bad SSH2 KexAlgorithms '%s'.",
filename, linenum, arg ? arg : "<NONE>");
if (options->kex_algorithms == NULL)
options->kex_algorithms = xstrdup(arg);
break;
case sSubsystem:
if (options->num_subsystems >= MAX_SUBSYSTEMS) {
fatal("%s line %d: too many subsystems defined.",
filename, linenum);
}
arg = argv_next(&ac, &av);
if (!arg || *arg == '\0')
fatal("%s line %d: %s missing argument.",
filename, linenum, keyword);
if (!*activep) {
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);
options->subsystem_name[options->num_subsystems] = xstrdup(arg);
arg = argv_next(&ac, &av);
if (!arg || *arg == '\0')
fatal("%s line %d: Missing subsystem command.",
filename, linenum);
options->subsystem_command[options->num_subsystems] = xstrdup(arg);
/* Collect arguments (separate to executable) */
p = xstrdup(arg);
len = strlen(p) + 1;
while ((arg = argv_next(&ac, &av)) != NULL) {
len += 1 + strlen(arg);
p = xreallocarray(p, 1, len);
strlcat(p, " ", len);
strlcat(p, arg, len);
}
options->subsystem_args[options->num_subsystems] = p;
options->num_subsystems++;
break;
case sMaxStartups:
arg = argv_next(&ac, &av);
if (!arg || *arg == '\0')
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,
&options->max_startups)) == 3) {
if (options->max_startups_begin >
options->max_startups ||
options->max_startups_rate > 100 ||
options->max_startups_rate < 1)
fatal("%s line %d: Invalid %s spec.",
filename, linenum, keyword);
} else if (n != 1)
fatal("%s line %d: Invalid %s spec.",
filename, linenum, keyword);
else
options->max_startups = options->max_startups_begin;
+ if (options->max_startups <= 0 ||
+ options->max_startups_begin <= 0)
+ fatal("%s line %d: Invalid %s spec.",
+ filename, linenum, keyword);
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;
case sMaxSessions:
intptr = &options->max_sessions;
goto parse_int;
case sBanner:
charptr = &options->banner;
goto parse_filename;
/*
* These options can contain %X options expanded at
* connect time, so that you can specify paths like:
*
* AuthorizedKeysFile /etc/ssh_keys/%u
*/
case sAuthorizedKeysFile:
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, arg2);
}
free(arg2);
}
break;
case sAuthorizedPrincipalsFile:
charptr = &options->authorized_principals_file;
arg = argv_next(&ac, &av);
if (!arg || *arg == '\0')
fatal("%s line %d: %s missing argument.",
filename, linenum, keyword);
if (*activep && *charptr == NULL) {
*charptr = tilde_expand_filename(arg, getuid());
/* increase optional counter */
if (intptr != NULL)
*intptr = *intptr + 1;
}
break;
case sClientAliveInterval:
intptr = &options->client_alive_interval;
goto parse_time;
case sClientAliveCountMax:
intptr = &options->client_alive_count_max;
goto parse_int;
case sAcceptEnv:
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;
opt_array_append(filename, linenum, keyword,
&options->accept_env, &options->num_accept_env,
arg);
}
break;
case sSetEnv:
uvalue = options->num_setenv;
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;
if (lookup_setenv_in_list(arg, options->setenv,
options->num_setenv) != NULL) {
debug2("%s line %d: ignoring duplicate env "
"name \"%.64s\"", filename, linenum, arg);
continue;
}
opt_array_append(filename, linenum, keyword,
&options->setenv, &options->num_setenv, arg);
}
break;
case sPermitTunnel:
intptr = &options->permit_tun;
arg = argv_next(&ac, &av);
if (!arg || *arg == '\0')
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) {
value = tunmode_desc[i].val;
break;
}
if (value == -1)
fatal("%s line %d: bad %s argument %s",
filename, linenum, keyword, arg);
if (*activep && *intptr == -1)
*intptr = value;
break;
case sInclude:
if (cmdline) {
fatal("Include directive not supported as a "
"command-line option");
}
value = 0;
while ((arg2 = argv_next(&ac, &av)) != NULL) {
if (*arg2 == '\0') {
error("%s line %d: keyword %s empty argument",
filename, linenum, keyword);
goto out;
}
value++;
found = 0;
if (*arg2 != '/' && *arg2 != '~') {
xasprintf(&arg, "%s/%s", SSHDIR, arg2);
} else
arg = xstrdup(arg2);
/*
* Don't let included files clobber the containing
* file's Match state.
*/
oactive = *activep;
/* consult cache of include files */
TAILQ_FOREACH(item, includes, entry) {
if (strcmp(item->selector, arg) != 0)
continue;
if (item->filename != NULL) {
parse_server_config_depth(options,
item->filename, item->contents,
includes, connectinfo,
(*inc_flags & SSHCFG_MATCH_ONLY
? SSHCFG_MATCH_ONLY : (oactive
? 0 : SSHCFG_NEVERMATCH)),
activep, depth + 1);
}
found = 1;
*activep = oactive;
}
if (found != 0) {
free(arg);
continue;
}
/* requested glob was not in cache */
debug2("%s line %d: new include %s",
filename, linenum, arg);
if ((r = glob(arg, 0, NULL, &gbuf)) != 0) {
if (r != GLOB_NOMATCH) {
fatal("%s line %d: include \"%s\" glob "
"failed", filename, linenum, arg);
}
/*
* If no entry matched then record a
* placeholder to skip later glob calls.
*/
debug2("%s line %d: no match for %s",
filename, linenum, arg);
item = xcalloc(1, sizeof(*item));
item->selector = strdup(arg);
TAILQ_INSERT_TAIL(includes,
item, entry);
}
if (gbuf.gl_pathc > INT_MAX)
fatal_f("too many glob results");
for (n = 0; n < (int)gbuf.gl_pathc; n++) {
debug2("%s line %d: including %s",
filename, linenum, gbuf.gl_pathv[n]);
item = xcalloc(1, sizeof(*item));
item->selector = strdup(arg);
item->filename = strdup(gbuf.gl_pathv[n]);
if ((item->contents = sshbuf_new()) == NULL)
fatal_f("sshbuf_new failed");
load_server_config(item->filename,
item->contents);
parse_server_config_depth(options,
item->filename, item->contents,
includes, connectinfo,
(*inc_flags & SSHCFG_MATCH_ONLY
? SSHCFG_MATCH_ONLY : (oactive
? 0 : SSHCFG_NEVERMATCH)),
activep, depth + 1);
*activep = oactive;
TAILQ_INSERT_TAIL(includes, item, entry);
}
globfree(&gbuf);
free(arg);
}
if (value == 0) {
fatal("%s line %d: %s missing filename argument",
filename, linenum, keyword);
}
break;
case sMatch:
if (cmdline)
fatal("Match directive not supported as a command-line "
"option");
value = match_cfg_line(&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 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:
case sPermitOpen:
if (opcode == sPermitListen) {
uintptr = &options->num_permitted_listens;
chararrayptr = &options->permitted_listens;
} else {
uintptr = &options->num_permitted_opens;
chararrayptr = &options->permitted_opens;
}
arg = argv_next(&ac, &av);
if (!arg || *arg == '\0')
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) {
*uintptr = 1;
*chararrayptr = xcalloc(1,
sizeof(**chararrayptr));
(*chararrayptr)[0] = xstrdup(arg);
}
break;
}
for (; arg != NULL && *arg != '\0'; arg = argv_next(&ac, &av)) {
if (opcode == sPermitListen &&
strchr(arg, ':') == NULL) {
/*
* Allow bare port number for PermitListen
* to indicate a wildcard listen host.
*/
xasprintf(&arg2, "*:%s", arg);
} else {
arg2 = xstrdup(arg);
p = hpdelim(&arg);
if (p == NULL) {
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: %s bad port number",
filename, linenum, keyword);
}
if (*activep && uvalue == 0) {
opt_array_append(filename, linenum, keyword,
chararrayptr, uintptr, arg2);
}
free(arg2);
}
break;
case sForceCommand:
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(str + len);
argv_consume(&ac);
break;
case sChrootDirectory:
charptr = &options->chroot_directory;
arg = argv_next(&ac, &av);
if (!arg || *arg == '\0')
fatal("%s line %d: %s missing argument.",
filename, linenum, keyword);
if (*activep && *charptr == NULL)
*charptr = xstrdup(arg);
break;
case sTrustedUserCAKeys:
charptr = &options->trusted_user_ca_keys;
goto parse_filename;
case sRevokedKeys:
charptr = &options->revoked_keys_file;
goto parse_filename;
case sSecurityKeyProvider:
charptr = &options->sk_provider;
arg = argv_next(&ac, &av);
if (!arg || *arg == '\0')
fatal("%s line %d: %s missing argument.",
filename, linenum, keyword);
if (*activep && *charptr == NULL) {
*charptr = strcasecmp(arg, "internal") == 0 ?
xstrdup(arg) : derelativise_path(arg);
/* increase optional counter */
if (intptr != NULL)
*intptr = *intptr + 1;
}
break;
case sIPQoS:
arg = 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 %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 %s value: %s",
filename, linenum, keyword, arg);
if (*activep) {
options->ip_qos_interactive = value;
options->ip_qos_bulk = value2;
}
break;
case sVersionAddendum:
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(str + len, "none") == 0)
options->version_addendum = xstrdup("");
else
options->version_addendum = xstrdup(str + len);
}
argv_consume(&ac);
break;
case sAuthorizedKeysCommand:
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);
}
if (*activep && options->authorized_keys_command == NULL)
*charptr = xstrdup(str + len);
argv_consume(&ac);
break;
case sAuthorizedKeysCommandUser:
charptr = &options->authorized_keys_command_user;
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:
charptr = &options->authorized_principals_command;
goto parse_command;
case sAuthorizedPrincipalsCommandUser:
charptr = &options->authorized_principals_command_user;
goto parse_localuser;
case sAuthenticationMethods:
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);
}
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);
}
if (value2 == 0) {
fatal("%s line %d: no %s specified",
filename, linenum, keyword);
}
break;
case sStreamLocalBindMask:
arg = argv_next(&ac, &av);
if (!arg || *arg == '\0')
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: Invalid %s.",
filename, linenum, keyword);
if (*activep)
options->fwd_opts.streamlocal_bind_mask = (mode_t)value;
break;
case sStreamLocalBindUnlink:
intptr = &options->fwd_opts.streamlocal_bind_unlink;
goto parse_flag;
case sFingerprintHash:
arg = argv_next(&ac, &av);
if (!arg || *arg == '\0')
fatal("%s line %d: %s missing argument.",
filename, linenum, keyword);
if ((value = ssh_digest_alg_by_name(arg)) == -1)
fatal("%.200s line %d: Invalid %s algorithm \"%s\".",
filename, linenum, keyword, arg);
if (*activep)
options->fingerprint_hash = value;
break;
case sExposeAuthInfo:
intptr = &options->expose_userauth_info;
goto parse_flag;
case sRDomain:
#if !defined(__OpenBSD__) && !defined(HAVE_SYS_SET_PROCESS_RDOMAIN)
fatal("%s line %d: setting RDomain not supported on this "
"platform.", filename, linenum);
#endif
charptr = &options->routing_domain;
arg = argv_next(&ac, &av);
if (!arg || *arg == '\0')
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: invalid routing domain",
filename, linenum);
if (*activep && *charptr == NULL)
*charptr = xstrdup(arg);
break;
case sRequiredRSASize:
intptr = &options->required_rsa_size;
goto parse_int;
+ case sChannelTimeout:
+ uvalue = options->num_channel_timeouts;
+ i = 0;
+ while ((arg = argv_next(&ac, &av)) != NULL) {
+ /* 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;
+ }
+ } else if (parse_timeout(arg, NULL, NULL) != 0) {
+ fatal("%s line %d: invalid channel timeout %s",
+ filename, linenum, arg);
+ }
+ if (!*activep || uvalue != 0)
+ continue;
+ opt_array_append(filename, linenum, keyword,
+ &options->channel_timeouts,
+ &options->num_channel_timeouts, arg);
+ }
+ break;
+
+ case sUnusedConnectionTimeout:
+ intptr = &options->unused_connection_timeout;
+ /* peek at first arg for "none" so we can reuse parse_time */
+ if (av[0] != NULL && strcasecmp(av[0], "none") == 0) {
+ (void)argv_next(&ac, &av); /* consume arg */
+ if (*activep)
+ *intptr = 0;
+ break;
+ }
+ goto parse_time;
+
case sUseBlacklist:
intptr = &options->use_blacklist;
goto parse_flag;
case sDeprecated:
case sIgnore:
case sUnsupported:
do_log2(opcode == sIgnore ?
SYSLOG_LEVEL_DEBUG2 : SYSLOG_LEVEL_INFO,
"%s line %d: %s option %s", filename, linenum,
opcode == sUnsupported ? "Unsupported" : "Deprecated",
keyword);
argv_consume(&ac);
break;
default:
fatal("%s line %d: Missing handler for opcode %s (%d)",
filename, linenum, keyword, opcode);
}
/* Check that there is no garbage at end of line. */
if (ac > 0) {
error("%.200s line %d: keyword %s extra arguments "
"at end of line", filename, linenum, keyword);
goto out;
}
/* success */
ret = 0;
out:
argv_free(oav, oac);
return ret;
}
int
process_server_config_line(ServerOptions *options, char *line,
const char *filename, int linenum, int *activep,
struct connection_info *connectinfo, struct include_list *includes)
{
int inc_flags = 0;
return process_server_config_line_depth(options, line, filename,
linenum, activep, connectinfo, &inc_flags, 0, includes);
}
/* Reads the server configuration file. */
void
load_server_config(const char *filename, struct sshbuf *conf)
{
struct stat st;
char *line = NULL, *cp;
size_t linesize = 0;
FILE *f;
- int r, lineno = 0;
+ int r;
debug2_f("filename %s", filename);
if ((f = fopen(filename, "r")) == NULL) {
perror(filename);
exit(1);
}
sshbuf_reset(conf);
/* grow buffer, so realloc is avoided for large config files */
if (fstat(fileno(f), &st) == 0 && st.st_size > 0 &&
(r = sshbuf_allocate(conf, st.st_size)) != 0)
fatal_fr(r, "allocate");
while (getline(&line, &linesize, f) != -1) {
- lineno++;
/*
* Strip whitespace
* NB - preserve newlines, they are needed to reproduce
* line numbers later for error messages
*/
cp = line + strspn(line, " \t\r");
if ((r = sshbuf_put(conf, cp, strlen(cp))) != 0)
fatal_fr(r, "sshbuf_put");
}
free(line);
if ((r = sshbuf_put_u8(conf, 0)) != 0)
fatal_fr(r, "sshbuf_put_u8");
fclose(f);
debug2_f("done config len = %zu", sshbuf_len(conf));
}
void
parse_server_match_config(ServerOptions *options,
struct include_list *includes, struct connection_info *connectinfo)
{
ServerOptions mo;
initialize_server_options(&mo);
parse_server_config(&mo, "reprocess config", cfg, includes,
connectinfo, 0);
copy_set_server_options(options, &mo, 0);
}
int parse_server_match_testspec(struct connection_info *ci, char *spec)
{
char *p;
while ((p = strsep(&spec, ",")) && *p != '\0') {
if (strncmp(p, "addr=", 5) == 0) {
ci->address = xstrdup(p + 5);
} else if (strncmp(p, "host=", 5) == 0) {
ci->host = xstrdup(p + 5);
} else if (strncmp(p, "user=", 5) == 0) {
ci->user = xstrdup(p + 5);
} else if (strncmp(p, "laddr=", 6) == 0) {
ci->laddress = xstrdup(p + 6);
} else if (strncmp(p, "rdomain=", 8) == 0) {
ci->rdomain = xstrdup(p + 8);
} else if (strncmp(p, "lport=", 6) == 0) {
ci->lport = a2port(p + 6);
if (ci->lport == -1) {
fprintf(stderr, "Invalid port '%s' in test mode"
" specification %s\n", p+6, p);
return -1;
}
} else {
fprintf(stderr, "Invalid test mode specification %s\n",
p);
return -1;
}
}
return 0;
}
/*
* Copy any supported values that are set.
*
* If the preauth flag is set, we do not bother copying the string or
* array values that are not used pre-authentication, because any that we
* do use must be explicitly sent in mm_getpwnamallow().
*/
void
copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
{
#define M_CP_INTOPT(n) do {\
if (src->n != -1) \
dst->n = src->n; \
} while (0)
M_CP_INTOPT(password_authentication);
M_CP_INTOPT(gss_authentication);
M_CP_INTOPT(pubkey_authentication);
M_CP_INTOPT(pubkey_auth_options);
M_CP_INTOPT(kerberos_authentication);
M_CP_INTOPT(hostbased_authentication);
M_CP_INTOPT(hostbased_uses_name_from_packet_only);
M_CP_INTOPT(kbd_interactive_authentication);
M_CP_INTOPT(permit_root_login);
M_CP_INTOPT(permit_empty_passwd);
M_CP_INTOPT(ignore_rhosts);
M_CP_INTOPT(allow_tcp_forwarding);
M_CP_INTOPT(allow_streamlocal_forwarding);
M_CP_INTOPT(allow_agent_forwarding);
M_CP_INTOPT(disable_forwarding);
M_CP_INTOPT(expose_userauth_info);
M_CP_INTOPT(permit_tun);
M_CP_INTOPT(fwd_opts.gateway_ports);
M_CP_INTOPT(fwd_opts.streamlocal_bind_unlink);
M_CP_INTOPT(x11_display_offset);
M_CP_INTOPT(x11_forwarding);
M_CP_INTOPT(x11_use_localhost);
M_CP_INTOPT(permit_tty);
M_CP_INTOPT(permit_user_rc);
M_CP_INTOPT(max_sessions);
M_CP_INTOPT(max_authtries);
M_CP_INTOPT(client_alive_count_max);
M_CP_INTOPT(client_alive_interval);
M_CP_INTOPT(ip_qos_interactive);
M_CP_INTOPT(ip_qos_bulk);
M_CP_INTOPT(rekey_limit);
M_CP_INTOPT(rekey_interval);
M_CP_INTOPT(log_level);
M_CP_INTOPT(required_rsa_size);
+ M_CP_INTOPT(unused_connection_timeout);
/*
* The bind_mask is a mode_t that may be unsigned, so we can't use
* M_CP_INTOPT - it does a signed comparison that causes compiler
* warnings.
*/
if (src->fwd_opts.streamlocal_bind_mask != (mode_t)-1) {
dst->fwd_opts.streamlocal_bind_mask =
src->fwd_opts.streamlocal_bind_mask;
}
/* M_CP_STROPT and M_CP_STRARRAYOPT should not appear before here */
#define M_CP_STROPT(n) do {\
if (src->n != NULL && dst->n != src->n) { \
free(dst->n); \
dst->n = src->n; \
} \
} while(0)
#define M_CP_STRARRAYOPT(s, num_s) do {\
u_int i; \
if (src->num_s != 0) { \
for (i = 0; i < dst->num_s; i++) \
free(dst->s[i]); \
free(dst->s); \
dst->s = xcalloc(src->num_s, sizeof(*dst->s)); \
for (i = 0; i < src->num_s; i++) \
dst->s[i] = xstrdup(src->s[i]); \
dst->num_s = src->num_s; \
} \
} while(0)
/* See comment in servconf.h */
COPY_MATCH_STRING_OPTS();
/* Arguments that accept '+...' need to be expanded */
assemble_algorithms(dst);
/*
* The only things that should be below this point are string options
* which are only used after authentication.
*/
if (preauth)
return;
/* These options may be "none" to clear a global setting */
M_CP_STROPT(adm_forced_command);
if (option_clear_or_none(dst->adm_forced_command)) {
free(dst->adm_forced_command);
dst->adm_forced_command = NULL;
}
M_CP_STROPT(chroot_directory);
if (option_clear_or_none(dst->chroot_directory)) {
free(dst->chroot_directory);
dst->chroot_directory = NULL;
}
}
#undef M_CP_INTOPT
#undef M_CP_STROPT
#undef M_CP_STRARRAYOPT
#define SERVCONF_MAX_DEPTH 16
static void
parse_server_config_depth(ServerOptions *options, const char *filename,
struct sshbuf *conf, struct include_list *includes,
struct connection_info *connectinfo, int flags, int *activep, int depth)
{
int linenum, bad_options = 0;
char *cp, *obuf, *cbuf;
if (depth < 0 || depth > SERVCONF_MAX_DEPTH)
fatal("Too many recursive configuration includes");
debug2_f("config %s len %zu%s", filename, sshbuf_len(conf),
(flags & SSHCFG_NEVERMATCH ? " [checking syntax only]" : ""));
if ((obuf = cbuf = sshbuf_dup_string(conf)) == NULL)
fatal_f("sshbuf_dup_string failed");
linenum = 1;
while ((cp = strsep(&cbuf, "\n")) != NULL) {
if (process_server_config_line_depth(options, cp,
filename, linenum++, activep, connectinfo, &flags,
depth, includes) != 0)
bad_options++;
}
free(obuf);
if (bad_options > 0)
fatal("%s: terminating, %d bad configuration options",
filename, bad_options);
}
void
parse_server_config(ServerOptions *options, const char *filename,
struct sshbuf *conf, struct include_list *includes,
struct connection_info *connectinfo, int reexec)
{
int active = connectinfo ? 0 : 1;
parse_server_config_depth(options, filename, conf, includes,
connectinfo, (connectinfo ? SSHCFG_MATCH_ONLY : 0), &active, 0);
if (!reexec)
process_queued_listen_addrs(options);
}
static const char *
fmt_multistate_int(int val, const struct multistate *m)
{
u_int i;
for (i = 0; m[i].key != NULL; i++) {
if (m[i].value == val)
return m[i].key;
}
return "UNKNOWN";
}
static const char *
fmt_intarg(ServerOpCodes code, int val)
{
if (val == -1)
return "unset";
switch (code) {
case sAddressFamily:
return fmt_multistate_int(val, multistate_addressfamily);
case sPermitRootLogin:
return fmt_multistate_int(val, multistate_permitrootlogin);
case sGatewayPorts:
return fmt_multistate_int(val, multistate_gatewayports);
case sCompression:
return fmt_multistate_int(val, multistate_compression);
case sAllowTcpForwarding:
return fmt_multistate_int(val, multistate_tcpfwd);
case sAllowStreamLocalForwarding:
return fmt_multistate_int(val, multistate_tcpfwd);
case sIgnoreRhosts:
return fmt_multistate_int(val, multistate_ignore_rhosts);
case sFingerprintHash:
return ssh_digest_alg_name(val);
default:
switch (val) {
case 0:
return "no";
case 1:
return "yes";
default:
return "UNKNOWN";
}
}
}
static void
dump_cfg_int(ServerOpCodes code, int val)
{
+ if (code == sUnusedConnectionTimeout && val == 0) {
+ printf("%s none\n", lookup_opcode_name(code));
+ return;
+ }
printf("%s %d\n", lookup_opcode_name(code), val);
}
static void
dump_cfg_oct(ServerOpCodes code, int val)
{
printf("%s 0%o\n", lookup_opcode_name(code), val);
}
static void
dump_cfg_fmtint(ServerOpCodes code, int val)
{
printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val));
}
static void
dump_cfg_string(ServerOpCodes code, const char *val)
{
printf("%s %s\n", lookup_opcode_name(code),
val == NULL ? "none" : val);
}
static void
dump_cfg_strarray(ServerOpCodes code, u_int count, char **vals)
{
u_int i;
for (i = 0; i < count; i++)
printf("%s %s\n", lookup_opcode_name(code), vals[i]);
}
static void
dump_cfg_strarray_oneline(ServerOpCodes code, u_int count, char **vals)
{
u_int i;
if (count <= 0 && code != sAuthenticationMethods)
return;
printf("%s", lookup_opcode_name(code));
for (i = 0; i < count; i++)
printf(" %s", vals[i]);
if (code == sAuthenticationMethods && count == 0)
printf(" any");
+ else if (code == sChannelTimeout && count == 0)
+ printf(" none");
printf("\n");
}
static char *
format_listen_addrs(struct listenaddr *la)
{
int r;
struct addrinfo *ai;
char addr[NI_MAXHOST], port[NI_MAXSERV];
char *laddr1 = xstrdup(""), *laddr2 = NULL;
/*
* ListenAddress must be after Port. add_one_listen_addr pushes
* addresses onto a stack, so to maintain ordering we need to
* print these in reverse order.
*/
for (ai = la->addrs; ai; ai = ai->ai_next) {
if ((r = getnameinfo(ai->ai_addr, ai->ai_addrlen, addr,
sizeof(addr), port, sizeof(port),
NI_NUMERICHOST|NI_NUMERICSERV)) != 0) {
error("getnameinfo: %.100s", ssh_gai_strerror(r));
continue;
}
laddr2 = laddr1;
if (ai->ai_family == AF_INET6) {
xasprintf(&laddr1, "listenaddress [%s]:%s%s%s\n%s",
addr, port,
la->rdomain == NULL ? "" : " rdomain ",
la->rdomain == NULL ? "" : la->rdomain,
laddr2);
} else {
xasprintf(&laddr1, "listenaddress %s:%s%s%s\n%s",
addr, port,
la->rdomain == NULL ? "" : " rdomain ",
la->rdomain == NULL ? "" : la->rdomain,
laddr2);
}
free(laddr2);
}
return laddr1;
}
void
dump_config(ServerOptions *o)
{
char *s;
u_int i;
/* these are usually at the top of the config */
for (i = 0; i < o->num_ports; i++)
printf("port %d\n", o->ports[i]);
dump_cfg_fmtint(sAddressFamily, o->address_family);
for (i = 0; i < o->num_listen_addrs; i++) {
s = format_listen_addrs(&o->listen_addrs[i]);
printf("%s", s);
free(s);
}
/* integer arguments */
#ifdef USE_PAM
dump_cfg_fmtint(sUsePAM, o->use_pam);
#endif
dump_cfg_int(sLoginGraceTime, o->login_grace_time);
dump_cfg_int(sX11DisplayOffset, o->x11_display_offset);
dump_cfg_int(sMaxAuthTries, o->max_authtries);
dump_cfg_int(sMaxSessions, o->max_sessions);
dump_cfg_int(sClientAliveInterval, o->client_alive_interval);
dump_cfg_int(sClientAliveCountMax, o->client_alive_count_max);
dump_cfg_int(sRequiredRSASize, o->required_rsa_size);
dump_cfg_oct(sStreamLocalBindMask, o->fwd_opts.streamlocal_bind_mask);
+ dump_cfg_int(sUnusedConnectionTimeout, o->unused_connection_timeout);
/* formatted integer arguments */
dump_cfg_fmtint(sPermitRootLogin, o->permit_root_login);
dump_cfg_fmtint(sIgnoreRhosts, o->ignore_rhosts);
dump_cfg_fmtint(sIgnoreUserKnownHosts, o->ignore_user_known_hosts);
dump_cfg_fmtint(sHostbasedAuthentication, o->hostbased_authentication);
dump_cfg_fmtint(sHostbasedUsesNameFromPacketOnly,
o->hostbased_uses_name_from_packet_only);
dump_cfg_fmtint(sPubkeyAuthentication, o->pubkey_authentication);
#ifdef KRB5
dump_cfg_fmtint(sKerberosAuthentication, o->kerberos_authentication);
dump_cfg_fmtint(sKerberosOrLocalPasswd, o->kerberos_or_local_passwd);
dump_cfg_fmtint(sKerberosTicketCleanup, o->kerberos_ticket_cleanup);
# ifdef USE_AFS
dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token);
# endif
#endif
#ifdef GSSAPI
dump_cfg_fmtint(sGssAuthentication, o->gss_authentication);
dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds);
#endif
dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication);
dump_cfg_fmtint(sKbdInteractiveAuthentication,
o->kbd_interactive_authentication);
dump_cfg_fmtint(sPrintMotd, o->print_motd);
#ifndef DISABLE_LASTLOG
dump_cfg_fmtint(sPrintLastLog, o->print_lastlog);
#endif
dump_cfg_fmtint(sX11Forwarding, o->x11_forwarding);
dump_cfg_fmtint(sX11UseLocalhost, o->x11_use_localhost);
dump_cfg_fmtint(sPermitTTY, o->permit_tty);
dump_cfg_fmtint(sPermitUserRC, o->permit_user_rc);
dump_cfg_fmtint(sStrictModes, o->strict_modes);
dump_cfg_fmtint(sTCPKeepAlive, o->tcp_keep_alive);
dump_cfg_fmtint(sEmptyPasswd, o->permit_empty_passwd);
dump_cfg_fmtint(sCompression, o->compression);
dump_cfg_fmtint(sGatewayPorts, o->fwd_opts.gateway_ports);
dump_cfg_fmtint(sUseDNS, o->use_dns);
dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding);
dump_cfg_fmtint(sAllowAgentForwarding, o->allow_agent_forwarding);
dump_cfg_fmtint(sDisableForwarding, o->disable_forwarding);
dump_cfg_fmtint(sAllowStreamLocalForwarding, o->allow_streamlocal_forwarding);
dump_cfg_fmtint(sStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink);
dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash);
dump_cfg_fmtint(sExposeAuthInfo, o->expose_userauth_info);
dump_cfg_fmtint(sUseBlacklist, o->use_blacklist);
/* 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);
dump_cfg_string(sBanner, o->banner);
dump_cfg_string(sForceCommand, o->adm_forced_command);
dump_cfg_string(sChrootDirectory, o->chroot_directory);
dump_cfg_string(sTrustedUserCAKeys, o->trusted_user_ca_keys);
dump_cfg_string(sRevokedKeys, o->revoked_keys_file);
dump_cfg_string(sSecurityKeyProvider, o->sk_provider);
dump_cfg_string(sAuthorizedPrincipalsFile,
o->authorized_principals_file);
dump_cfg_string(sVersionAddendum, *o->version_addendum == '\0'
? "none" : o->version_addendum);
dump_cfg_string(sAuthorizedKeysCommand, o->authorized_keys_command);
dump_cfg_string(sAuthorizedKeysCommandUser, o->authorized_keys_command_user);
dump_cfg_string(sAuthorizedPrincipalsCommand, o->authorized_principals_command);
dump_cfg_string(sAuthorizedPrincipalsCommandUser, o->authorized_principals_command_user);
dump_cfg_string(sHostKeyAgent, o->host_key_agent);
dump_cfg_string(sKexAlgorithms, o->kex_algorithms);
dump_cfg_string(sCASignatureAlgorithms, o->ca_sign_algorithms);
dump_cfg_string(sHostbasedAcceptedAlgorithms, o->hostbased_accepted_algos);
dump_cfg_string(sHostKeyAlgorithms, o->hostkeyalgorithms);
dump_cfg_string(sPubkeyAcceptedAlgorithms, o->pubkey_accepted_algos);
#if defined(__OpenBSD__) || defined(HAVE_SYS_SET_PROCESS_RDOMAIN)
dump_cfg_string(sRDomain, o->routing_domain);
#endif
/* string arguments requiring a lookup */
dump_cfg_string(sLogLevel, log_level_name(o->log_level));
dump_cfg_string(sLogFacility, log_facility_name(o->log_facility));
/* string array arguments */
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);
dump_cfg_strarray(sHostCertificate, o->num_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);
dump_cfg_strarray(sDenyGroups, o->num_deny_groups, o->deny_groups);
dump_cfg_strarray(sAcceptEnv, o->num_accept_env, o->accept_env);
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);
+ dump_cfg_strarray_oneline(sChannelTimeout,
+ o->num_channel_timeouts, o->channel_timeouts);
/* other arguments */
for (i = 0; i < o->num_subsystems; i++)
printf("subsystem %s %s\n", o->subsystem_name[i],
o->subsystem_args[i]);
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++) {
if (tunmode_desc[i].val == o->permit_tun) {
s = tunmode_desc[i].text;
break;
}
}
dump_cfg_string(sPermitTunnel, s);
printf("ipqos %s ", iptos2str(o->ip_qos_interactive));
printf("%s\n", iptos2str(o->ip_qos_bulk));
printf("rekeylimit %llu %d\n", (unsigned long long)o->rekey_limit,
o->rekey_interval);
printf("permitopen");
if (o->num_permitted_opens == 0)
printf(" any");
else {
for (i = 0; i < o->num_permitted_opens; i++)
printf(" %s", o->permitted_opens[i]);
}
printf("\n");
printf("permitlisten");
if (o->num_permitted_listens == 0)
printf(" any");
else {
for (i = 0; i < o->num_permitted_listens; i++)
printf(" %s", o->permitted_listens[i]);
}
printf("\n");
if (o->permit_user_env_allowlist == NULL) {
dump_cfg_fmtint(sPermitUserEnvironment, o->permit_user_env);
} else {
printf("permituserenvironment %s\n",
o->permit_user_env_allowlist);
}
printf("pubkeyauthoptions");
if (o->pubkey_auth_options == 0)
printf(" none");
if (o->pubkey_auth_options & PUBKEYAUTH_TOUCH_REQUIRED)
printf(" touch-required");
if (o->pubkey_auth_options & PUBKEYAUTH_VERIFY_REQUIRED)
printf(" verify-required");
printf("\n");
}
diff --git a/crypto/openssh/servconf.h b/crypto/openssh/servconf.h
index 83d13fd82e55..de103f623f50 100644
--- a/crypto/openssh/servconf.h
+++ b/crypto/openssh/servconf.h
@@ -1,315 +1,323 @@
-/* $OpenBSD: servconf.h,v 1.157 2022/09/17 10:34:29 djm Exp $ */
+/* $OpenBSD: servconf.h,v 1.159 2023/01/17 09:44:48 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
* Definitions for server configuration data and for the functions reading it.
*
* As far as I am concerned, the code I have written for this software
* can be used freely for any purpose. Any derived versions of this
* software must be clearly marked as such, and if the derived work is
* incompatible with the protocol description in the RFC file, it must be
* called by a name other than "ssh" or "Secure Shell".
*/
#ifndef SERVCONF_H
#define SERVCONF_H
#include <openbsd-compat/sys-queue.h>
#define MAX_PORTS 256 /* Max # ports. */
#define MAX_SUBSYSTEMS 256 /* Max # subsystems. */
/* permit_root_login */
#define PERMIT_NOT_SET -1
#define PERMIT_NO 0
#define PERMIT_FORCED_ONLY 1
#define PERMIT_NO_PASSWD 2
#define PERMIT_YES 3
/* use_privsep */
#define PRIVSEP_OFF 0
#define PRIVSEP_ON 1
#define PRIVSEP_NOSANDBOX 2
/* PermitOpen */
#define PERMITOPEN_ANY 0
#define PERMITOPEN_NONE -2
/* IgnoreRhosts */
#define IGNORE_RHOSTS_NO 0
#define IGNORE_RHOSTS_YES 1
#define IGNORE_RHOSTS_SHOSTS 2
#define DEFAULT_AUTH_FAIL_MAX 6 /* Default for MaxAuthTries */
#define DEFAULT_SESSIONS_MAX 10 /* Default for MaxSessions */
/* Magic name for internal sftp-server */
#define INTERNAL_SFTP_NAME "internal-sftp"
/* PubkeyAuthOptions flags */
#define PUBKEYAUTH_TOUCH_REQUIRED (1)
#define PUBKEYAUTH_VERIFY_REQUIRED (1<<1)
struct ssh;
struct fwd_perm_list;
/*
* Used to store addresses from ListenAddr directives. These may be
* incomplete, as they may specify addresses that need to be merged
* with any ports requested by ListenPort.
*/
struct queued_listenaddr {
char *addr;
int port; /* <=0 if unspecified */
char *rdomain;
};
/* Resolved listen addresses, grouped by optional routing domain */
struct listenaddr {
char *rdomain;
struct addrinfo *addrs;
};
typedef struct {
u_int num_ports;
u_int ports_from_cmdline;
int ports[MAX_PORTS]; /* Port number to listen on. */
struct queued_listenaddr *queued_listen_addrs;
u_int num_queued_listens;
struct listenaddr *listen_addrs;
u_int num_listen_addrs;
int address_family; /* Address family used by the server. */
char *routing_domain; /* Bind session to routing domain */
char **host_key_files; /* Files containing host keys. */
int *host_key_file_userprovided; /* Key was specified by user. */
u_int num_host_key_files; /* Number of files for host keys. */
char **host_cert_files; /* Files containing host certs. */
u_int num_host_cert_files; /* Number of files for host certs. */
char *host_key_agent; /* ssh-agent socket for host keys. */
char *pid_file; /* Where to put our pid */
char *moduli_file; /* moduli file for DH-GEX */
int login_grace_time; /* Disconnect if no auth in this time
* (sec). */
int permit_root_login; /* PERMIT_*, see above */
int ignore_rhosts; /* Ignore .rhosts and .shosts. */
int ignore_user_known_hosts; /* Ignore ~/.ssh/known_hosts
* for RhostsRsaAuth */
int print_motd; /* If true, print /etc/motd. */
int print_lastlog; /* If true, print lastlog */
int x11_forwarding; /* If true, permit inet (spoofing) X11 fwd. */
int x11_display_offset; /* What DISPLAY number to start
* searching at */
int x11_use_localhost; /* If true, use localhost for fake X11 server. */
char *xauth_location; /* Location of xauth program */
int permit_tty; /* If false, deny pty allocation */
int permit_user_rc; /* If false, deny ~/.ssh/rc execution */
int strict_modes; /* If true, require string home dir modes. */
int tcp_keep_alive; /* If true, set SO_KEEPALIVE. */
int ip_qos_interactive; /* IP ToS/DSCP/class for interactive */
int ip_qos_bulk; /* IP ToS/DSCP/class for bulk traffic */
char *ciphers; /* Supported SSH2 ciphers. */
char *macs; /* Supported SSH2 macs. */
char *kex_algorithms; /* SSH2 kex methods in order of preference. */
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_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_accepted_algos; /* Signature algos allowed for pubkey */
int pubkey_auth_options; /* -1 or mask of PUBKEYAUTH_* flags */
int kerberos_authentication; /* If true, permit Kerberos
* authentication. */
int kerberos_or_local_passwd; /* If true, permit kerberos
* and any other password
* authentication mechanism,
* such as SecurID or
* /etc/passwd */
int kerberos_ticket_cleanup; /* If true, destroy ticket
* file on logout. */
int kerberos_get_afs_token; /* If true, try to get AFS token if
* authenticated with Kerberos. */
int gss_authentication; /* If true, permit GSSAPI authentication */
int gss_cleanup_creds; /* If true, destroy cred cache on logout */
int gss_strict_acceptor; /* If true, restrict the GSSAPI acceptor name */
int password_authentication; /* If true, permit password
* authentication. */
int kbd_interactive_authentication; /* If true, permit */
int permit_empty_passwd; /* If false, do not permit empty
* passwords. */
int permit_user_env; /* If true, read ~/.ssh/environment */
char *permit_user_env_allowlist; /* pattern-list of allowed env names */
int compression; /* If true, compression is allowed */
int allow_tcp_forwarding; /* One of FORWARD_* */
int allow_streamlocal_forwarding; /* One of FORWARD_* */
int allow_agent_forwarding;
int disable_forwarding;
u_int num_allow_users;
char **allow_users;
u_int num_deny_users;
char **deny_users;
u_int num_allow_groups;
char **allow_groups;
u_int num_deny_groups;
char **deny_groups;
u_int num_subsystems;
char *subsystem_name[MAX_SUBSYSTEMS];
char *subsystem_command[MAX_SUBSYSTEMS];
char *subsystem_args[MAX_SUBSYSTEMS];
u_int num_accept_env;
char **accept_env;
u_int num_setenv;
char **setenv;
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 */
int use_dns;
int client_alive_interval; /*
* poke the client this often to
* see if it's still there
*/
int client_alive_count_max; /*
* If the client is unresponsive
* for this many intervals above,
* disconnect the session
*/
u_int num_authkeys_files; /* Files containing public keys */
char **authorized_keys_files;
char *adm_forced_command;
int use_pam; /* Enable auth via PAM */
int permit_tun;
char **permitted_opens; /* May also be one of PERMITOPEN_* */
u_int num_permitted_opens;
char **permitted_listens; /* May also be one of PERMITOPEN_* */
u_int num_permitted_listens;
char *chroot_directory;
char *revoked_keys_file;
char *trusted_user_ca_keys;
char *authorized_keys_command;
char *authorized_keys_command_user;
char *authorized_principals_file;
char *authorized_principals_command;
char *authorized_principals_command_user;
int64_t rekey_limit;
int rekey_interval;
char *version_addendum; /* Appended to SSH banner */
u_int num_auth_methods;
char **auth_methods;
int fingerprint_hash;
int expose_userauth_info;
u_int64_t timing_secret;
char *sk_provider;
int required_rsa_size; /* minimum size of RSA keys */
+
+ char **channel_timeouts; /* inactivity timeout by channel type */
+ u_int num_channel_timeouts;
+
+ int unused_connection_timeout;
+
int use_blacklist;
} ServerOptions;
/* Information about the incoming connection as used by Match */
struct connection_info {
const char *user;
const char *host; /* possibly resolved hostname */
const char *address; /* remote address */
const char *laddress; /* local address */
int lport; /* local port */
const char *rdomain; /* routing domain if available */
int test; /* test mode, allow some attributes to be
* unspecified */
};
/* List of included files for re-exec from the parsed configuration */
struct include_item {
char *selector;
char *filename;
struct sshbuf *contents;
TAILQ_ENTRY(include_item) entry;
};
TAILQ_HEAD(include_list, include_item);
/*
* These are string config options that must be copied between the
* Match sub-config and the main config, and must be sent from the
* privsep child to the privsep master. We use a macro to ensure all
* the options are copied and the copies are done in the correct order.
*
* NB. an option must appear in servconf.c:copy_set_server_options() or
* COPY_MATCH_STRING_OPTS here but never both.
*/
#define COPY_MATCH_STRING_OPTS() do { \
M_CP_STROPT(banner); \
M_CP_STROPT(trusted_user_ca_keys); \
M_CP_STROPT(revoked_keys_file); \
M_CP_STROPT(authorized_keys_command); \
M_CP_STROPT(authorized_keys_command_user); \
M_CP_STROPT(authorized_principals_file); \
M_CP_STROPT(authorized_principals_command); \
M_CP_STROPT(authorized_principals_command_user); \
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); \
M_CP_STRARRAYOPT(authorized_keys_files, num_authkeys_files); \
M_CP_STRARRAYOPT(allow_users, num_allow_users); \
M_CP_STRARRAYOPT(deny_users, num_deny_users); \
M_CP_STRARRAYOPT(allow_groups, num_allow_groups); \
M_CP_STRARRAYOPT(deny_groups, num_deny_groups); \
M_CP_STRARRAYOPT(accept_env, num_accept_env); \
M_CP_STRARRAYOPT(setenv, num_setenv); \
M_CP_STRARRAYOPT(auth_methods, num_auth_methods); \
M_CP_STRARRAYOPT(permitted_opens, num_permitted_opens); \
M_CP_STRARRAYOPT(permitted_listens, num_permitted_listens); \
+ M_CP_STRARRAYOPT(channel_timeouts, num_channel_timeouts); \
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);
void process_permitopen(struct ssh *ssh, ServerOptions *options);
+void process_channel_timeouts(struct ssh *ssh, ServerOptions *);
void load_server_config(const char *, struct sshbuf *);
void parse_server_config(ServerOptions *, const char *, struct sshbuf *,
struct include_list *includes, struct connection_info *, int);
void parse_server_match_config(ServerOptions *,
struct include_list *includes, struct connection_info *);
int parse_server_match_testspec(struct connection_info *, char *);
int server_match_spec_complete(struct connection_info *);
void copy_set_server_options(ServerOptions *, ServerOptions *, int);
void dump_config(ServerOptions *);
char *derelativise_path(const char *);
void servconf_add_hostkey(const char *, const int,
ServerOptions *, const char *path, int);
void servconf_add_hostcert(const char *, const int,
ServerOptions *, const char *path);
#endif /* SERVCONF_H */
diff --git a/crypto/openssh/serverloop.c b/crypto/openssh/serverloop.c
index b4c0d82b242d..6db0916d8220 100644
--- a/crypto/openssh/serverloop.c
+++ b/crypto/openssh/serverloop.c
@@ -1,935 +1,935 @@
-/* $OpenBSD: serverloop.c,v 1.232 2022/04/20 04:19:11 djm Exp $ */
+/* $OpenBSD: serverloop.c,v 1.234 2023/01/17 09:44:48 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
* Server main loop for handling the interactive session.
*
* As far as I am concerned, the code I have written for this software
* can be used freely for any purpose. Any derived versions of this
* software must be clearly marked as such, and if the derived work is
* incompatible with the protocol description in the RFC file, it must be
* called by a name other than "ssh" or "Secure Shell".
*
* SSH2 support by Markus Friedl.
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "includes.h"
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/socket.h>
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
#endif
#include <netinet/in.h>
#include <errno.h>
#include <fcntl.h>
#include <pwd.h>
#include <limits.h>
#ifdef HAVE_POLL_H
#include <poll.h>
#endif
#include <signal.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include <stdarg.h>
#include "openbsd-compat/sys-queue.h"
#include "xmalloc.h"
#include "packet.h"
#include "sshbuf.h"
#include "log.h"
#include "misc.h"
#include "servconf.h"
#include "canohost.h"
#include "sshpty.h"
#include "channels.h"
#include "compat.h"
#include "ssh2.h"
#include "sshkey.h"
#include "cipher.h"
#include "kex.h"
#include "hostfile.h"
#include "auth.h"
#include "session.h"
#include "dispatch.h"
#include "auth-options.h"
#include "serverloop.h"
#include "ssherr.h"
extern ServerOptions options;
/* XXX */
extern Authctxt *the_authctxt;
extern struct sshauthopt *auth_opts;
extern int use_privsep;
static int no_more_sessions = 0; /* Disallow further sessions. */
static volatile sig_atomic_t child_terminated = 0; /* The child has terminated. */
/* Cleanup on signals (!use_privsep case only) */
static volatile sig_atomic_t received_sigterm = 0;
/* prototypes */
static void server_init_dispatch(struct ssh *);
/* requested tunnel forwarding interface(s), shared with session.c */
char *tun_fwd_ifnames = NULL;
/* returns 1 if bind to specified port by specified user is permitted */
static int
bind_permitted(int port, uid_t uid)
{
if (use_privsep)
return 1; /* allow system to decide */
if (port < IPPORT_RESERVED && uid != 0)
return 0;
return 1;
}
/*ARGSUSED*/
static void
sigchld_handler(int sig)
{
child_terminated = 1;
}
/*ARGSUSED*/
static void
sigterm_handler(int sig)
{
received_sigterm = sig;
}
static void
client_alive_check(struct ssh *ssh)
{
char remote_id[512];
int r, channel_id;
/* timeout, check to see how many we have had */
if (options.client_alive_count_max > 0 &&
ssh_packet_inc_alive_timeouts(ssh) >
options.client_alive_count_max) {
sshpkt_fmt_connection_id(ssh, remote_id, sizeof(remote_id));
logit("Timeout, client not responding from %s", remote_id);
cleanup_exit(255);
}
/*
* send a bogus global/channel request with "wantreply",
* we should get back a failure
*/
if ((channel_id = channel_find_open(ssh)) == -1) {
if ((r = sshpkt_start(ssh, SSH2_MSG_GLOBAL_REQUEST)) != 0 ||
(r = sshpkt_put_cstring(ssh, "keepalive@openssh.com"))
!= 0 ||
(r = sshpkt_put_u8(ssh, 1)) != 0) /* boolean: want reply */
fatal_fr(r, "compose");
} else {
channel_request_start(ssh, channel_id,
"keepalive@openssh.com", 1);
}
if ((r = sshpkt_send(ssh)) != 0)
fatal_fr(r, "send");
}
/*
* Sleep in ppoll() until we can do something.
* Optionally, a maximum time can be specified for the duration of
* the wait (0 = infinite).
*/
static void
wait_until_can_do_something(struct ssh *ssh,
int connection_in, int connection_out, struct pollfd **pfdp,
- u_int *npfd_allocp, u_int *npfd_activep, u_int64_t max_time_ms,
- sigset_t *sigsetp, int *conn_in_readyp, int *conn_out_readyp)
+ u_int *npfd_allocp, u_int *npfd_activep, sigset_t *sigsetp,
+ int *conn_in_readyp, int *conn_out_readyp)
{
- struct timespec ts, *tsp;
+ struct timespec timeout;
+ char remote_id[512];
int ret;
- time_t minwait_secs = 0;
int client_alive_scheduled = 0;
u_int p;
- /* time we last heard from the client OR sent a keepalive */
- static time_t last_client_time;
+ time_t now;
+ static time_t last_client_time, unused_connection_expiry;
*conn_in_readyp = *conn_out_readyp = 0;
/* Prepare channel poll. First two pollfd entries are reserved */
- channel_prepare_poll(ssh, pfdp, npfd_allocp, npfd_activep,
- 2, &minwait_secs);
+ ptimeout_init(&timeout);
+ channel_prepare_poll(ssh, pfdp, npfd_allocp, npfd_activep, 2, &timeout);
+ now = monotime();
if (*npfd_activep < 2)
fatal_f("bad npfd %u", *npfd_activep); /* shouldn't happen */
+ if (options.rekey_interval > 0 && !ssh_packet_is_rekeying(ssh)) {
+ ptimeout_deadline_sec(&timeout,
+ ssh_packet_get_rekey_timeout(ssh));
+ }
- /* XXX need proper deadline system for rekey/client alive */
- if (minwait_secs != 0)
- max_time_ms = MINIMUM(max_time_ms, (u_int)minwait_secs * 1000);
+ /*
+ * If no channels are open and UnusedConnectionTimeout is set, then
+ * start the clock to terminate the connection.
+ */
+ if (options.unused_connection_timeout != 0) {
+ if (channel_still_open(ssh) || unused_connection_expiry == 0) {
+ unused_connection_expiry = now +
+ options.unused_connection_timeout;
+ }
+ ptimeout_deadline_monotime(&timeout, unused_connection_expiry);
+ }
/*
* if using client_alive, set the max timeout accordingly,
* and indicate that this particular timeout was for client
* alive by setting the client_alive_scheduled flag.
*
* this could be randomized somewhat to make traffic
* analysis more difficult, but we're not doing it yet.
*/
if (options.client_alive_interval) {
- uint64_t keepalive_ms =
- (uint64_t)options.client_alive_interval * 1000;
-
- if (max_time_ms == 0 || max_time_ms > keepalive_ms) {
- max_time_ms = keepalive_ms;
- client_alive_scheduled = 1;
- }
+ /* Time we last heard from the client OR sent a keepalive */
if (last_client_time == 0)
- last_client_time = monotime();
+ last_client_time = now;
+ ptimeout_deadline_sec(&timeout, options.client_alive_interval);
+ /* XXX ? deadline_monotime(last_client_time + alive_interval) */
+ client_alive_scheduled = 1;
}
#if 0
/* wrong: bad condition XXX */
if (channel_not_very_much_buffered_data())
#endif
/* Monitor client connection on reserved pollfd entries */
(*pfdp)[0].fd = connection_in;
(*pfdp)[0].events = POLLIN;
(*pfdp)[1].fd = connection_out;
(*pfdp)[1].events = ssh_packet_have_data_to_write(ssh) ? POLLOUT : 0;
/*
* If child has terminated and there is enough buffer space to read
* from it, then read as much as is available and exit.
*/
if (child_terminated && ssh_packet_not_very_much_data_to_write(ssh))
- if (max_time_ms == 0 || client_alive_scheduled)
- max_time_ms = 100;
-
- if (max_time_ms == 0)
- tsp = NULL;
- else {
- ts.tv_sec = max_time_ms / 1000;
- ts.tv_nsec = 1000000 * (max_time_ms % 1000);
- tsp = &ts;
- }
+ ptimeout_deadline_ms(&timeout, 100);
/* Wait for something to happen, or the timeout to expire. */
- ret = ppoll(*pfdp, *npfd_activep, tsp, sigsetp);
+ ret = ppoll(*pfdp, *npfd_activep, ptimeout_get_tsp(&timeout), sigsetp);
if (ret == -1) {
for (p = 0; p < *npfd_activep; p++)
(*pfdp)[p].revents = 0;
if (errno != EINTR)
fatal_f("ppoll: %.100s", strerror(errno));
return;
}
*conn_in_readyp = (*pfdp)[0].revents != 0;
*conn_out_readyp = (*pfdp)[1].revents != 0;
+ now = monotime(); /* need to reset after ppoll() */
+ /* ClientAliveInterval probing */
if (client_alive_scheduled) {
- time_t now = monotime();
-
- /*
- * If the ppoll timed out, or returned for some other reason
- * but we haven't heard from the client in time, send keepalive.
- */
- if (ret == 0 || (last_client_time != 0 && last_client_time +
- options.client_alive_interval <= now)) {
+ if (ret == 0 &&
+ now > last_client_time + options.client_alive_interval) {
+ /* ppoll timed out and we're due to probe */
client_alive_check(ssh);
last_client_time = now;
- } else if (*conn_in_readyp)
+ } else if (ret != 0 && *conn_in_readyp) {
+ /* Data from peer; reset probe timer. */
last_client_time = now;
+ }
+ }
+
+ /* UnusedConnectionTimeout handling */
+ if (unused_connection_expiry != 0 &&
+ now > unused_connection_expiry && !channel_still_open(ssh)) {
+ sshpkt_fmt_connection_id(ssh, remote_id, sizeof(remote_id));
+ logit("terminating inactive connection from %s", remote_id);
+ cleanup_exit(255);
}
}
/*
* Processes input from the client and the program. Input data is stored
* in buffers and processed later.
*/
static int
process_input(struct ssh *ssh, int connection_in)
{
int r;
if ((r = ssh_packet_process_read(ssh, connection_in)) == 0)
return 0; /* success */
if (r == SSH_ERR_SYSTEM_ERROR) {
if (errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK)
return 0;
if (errno == EPIPE) {
verbose("Connection closed by %.100s port %d",
ssh_remote_ipaddr(ssh), ssh_remote_port(ssh));
return -1;
}
verbose("Read error from remote host %s port %d: %s",
ssh_remote_ipaddr(ssh), ssh_remote_port(ssh),
strerror(errno));
cleanup_exit(255);
}
return -1;
}
/*
* Sends data from internal buffers to client program stdin.
*/
static void
process_output(struct ssh *ssh, int connection_out)
{
int r;
/* Send any buffered packet data to the client. */
if ((r = ssh_packet_write_poll(ssh)) != 0) {
sshpkt_fatal(ssh, r, "%s: ssh_packet_write_poll",
__func__);
}
}
static void
process_buffered_input_packets(struct ssh *ssh)
{
ssh_dispatch_run_fatal(ssh, DISPATCH_NONBLOCK, NULL);
}
static void
collect_children(struct ssh *ssh)
{
pid_t pid;
int status;
if (child_terminated) {
debug("Received SIGCHLD.");
while ((pid = waitpid(-1, &status, WNOHANG)) > 0 ||
(pid == -1 && errno == EINTR))
if (pid > 0)
session_close_by_pid(ssh, pid, status);
child_terminated = 0;
}
}
void
server_loop2(struct ssh *ssh, Authctxt *authctxt)
{
struct pollfd *pfd = NULL;
u_int npfd_alloc = 0, npfd_active = 0;
int r, conn_in_ready, conn_out_ready;
u_int 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);
connection_out = ssh_packet_get_connection_out(ssh);
if (!use_privsep) {
ssh_signal(SIGTERM, sigterm_handler);
ssh_signal(SIGINT, sigterm_handler);
ssh_signal(SIGQUIT, sigterm_handler);
}
server_init_dispatch(ssh);
for (;;) {
process_buffered_input_packets(ssh);
if (!ssh_packet_is_rekeying(ssh) &&
ssh_packet_not_very_much_data_to_write(ssh))
channel_output_poll(ssh);
- if (options.rekey_interval > 0 &&
- !ssh_packet_is_rekeying(ssh)) {
- rekey_timeout_ms = ssh_packet_get_rekey_timeout(ssh) *
- 1000;
- } else {
- rekey_timeout_ms = 0;
- }
/*
* Block SIGCHLD while we check for dead children, then pass
* the old signal mask through to ppoll() 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,
- &pfd, &npfd_alloc, &npfd_active, rekey_timeout_ms, &osigset,
+ &pfd, &npfd_alloc, &npfd_active, &osigset,
&conn_in_ready, &conn_out_ready);
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);
/* Clean up sessions, utmp, etc. */
cleanup_exit(255);
}
channel_after_poll(ssh, pfd, npfd_active);
if (conn_in_ready &&
process_input(ssh, connection_in) < 0)
break;
/* A timeout may have triggered rekeying */
if ((r = ssh_packet_check_rekey(ssh)) != 0)
fatal_fr(r, "cannot start rekeying");
if (conn_out_ready)
process_output(ssh, connection_out);
}
collect_children(ssh);
free(pfd);
/* free all channels, no more reads and writes */
channel_free_all(ssh);
/* free remaining sessions, e.g. remove wtmp entries */
session_destroy_all(ssh, NULL);
}
static int
server_input_keep_alive(int type, u_int32_t seq, struct ssh *ssh)
{
debug("Got %d/%u for keepalive", type, seq);
/*
* reset timeout, since we got a sane answer from the client.
* even if this was generated by something other than
* the bogus CHANNEL_REQUEST we send for keepalives.
*/
ssh_packet_set_alive_timeouts(ssh, 0);
return 0;
}
static Channel *
server_request_direct_tcpip(struct ssh *ssh, int *reason, const char **errmsg)
{
Channel *c = NULL;
char *target = NULL, *originator = NULL;
u_int target_port = 0, originator_port = 0;
int r;
if ((r = sshpkt_get_cstring(ssh, &target, NULL)) != 0 ||
(r = sshpkt_get_u32(ssh, &target_port)) != 0 ||
(r = sshpkt_get_cstring(ssh, &originator, NULL)) != 0 ||
(r = sshpkt_get_u32(ssh, &originator_port)) != 0 ||
(r = sshpkt_get_end(ssh)) != 0)
sshpkt_fatal(ssh, r, "%s: parse packet", __func__);
if (target_port > 0xFFFF) {
error_f("invalid target port");
*reason = SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED;
goto out;
}
if (originator_port > 0xFFFF) {
error_f("invalid originator port");
*reason = SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED;
goto out;
}
debug_f("originator %s port %u, target %s port %u",
originator, originator_port, target, target_port);
/* XXX fine grained permissions */
if ((options.allow_tcp_forwarding & FORWARD_LOCAL) != 0 &&
auth_opts->permit_port_forwarding_flag &&
!options.disable_forwarding) {
c = channel_connect_to_port(ssh, target, target_port,
"direct-tcpip", "direct-tcpip", reason, errmsg);
} else {
logit("refused local port forward: "
"originator %s port %d, target %s port %d",
originator, originator_port, target, target_port);
if (reason != NULL)
*reason = SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED;
}
out:
free(originator);
free(target);
return c;
}
static Channel *
server_request_direct_streamlocal(struct ssh *ssh)
{
Channel *c = NULL;
char *target = NULL, *originator = NULL;
u_int originator_port = 0;
struct passwd *pw = the_authctxt->pw;
int r;
if (pw == NULL || !the_authctxt->valid)
fatal_f("no/invalid user");
if ((r = sshpkt_get_cstring(ssh, &target, NULL)) != 0 ||
(r = sshpkt_get_cstring(ssh, &originator, NULL)) != 0 ||
(r = sshpkt_get_u32(ssh, &originator_port)) != 0 ||
(r = sshpkt_get_end(ssh)) != 0)
sshpkt_fatal(ssh, r, "%s: parse packet", __func__);
if (originator_port > 0xFFFF) {
error_f("invalid originator port");
goto out;
}
debug_f("originator %s port %d, target %s",
originator, originator_port, target);
/* XXX fine grained permissions */
if ((options.allow_streamlocal_forwarding & FORWARD_LOCAL) != 0 &&
auth_opts->permit_port_forwarding_flag &&
!options.disable_forwarding && (pw->pw_uid == 0 || use_privsep)) {
c = channel_connect_to_path(ssh, target,
"direct-streamlocal@openssh.com", "direct-streamlocal");
} else {
logit("refused streamlocal port forward: "
"originator %s port %d, target %s",
originator, originator_port, target);
}
out:
free(originator);
free(target);
return c;
}
static Channel *
server_request_tun(struct ssh *ssh)
{
Channel *c = NULL;
u_int mode, tun;
int r, sock;
char *tmp, *ifname = NULL;
if ((r = sshpkt_get_u32(ssh, &mode)) != 0)
sshpkt_fatal(ssh, r, "%s: parse mode", __func__);
switch (mode) {
case SSH_TUNMODE_POINTOPOINT:
case SSH_TUNMODE_ETHERNET:
break;
default:
ssh_packet_send_debug(ssh, "Unsupported tunnel device mode.");
return NULL;
}
if ((options.permit_tun & mode) == 0) {
ssh_packet_send_debug(ssh, "Server has rejected tunnel device "
"forwarding");
return NULL;
}
if ((r = sshpkt_get_u32(ssh, &tun)) != 0)
sshpkt_fatal(ssh, r, "%s: parse device", __func__);
if (tun > INT_MAX) {
debug_f("invalid tun");
goto done;
}
if (auth_opts->force_tun_device != -1) {
if (tun != SSH_TUNID_ANY &&
auth_opts->force_tun_device != (int)tun)
goto done;
tun = auth_opts->force_tun_device;
}
sock = tun_open(tun, mode, &ifname);
if (sock < 0)
goto done;
debug("Tunnel forwarding using interface %s", ifname);
c = channel_new(ssh, "tun", SSH_CHANNEL_OPEN, sock, sock, -1,
CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1);
c->datagram = 1;
#if defined(SSH_TUN_FILTER)
if (mode == SSH_TUNMODE_POINTOPOINT)
channel_register_filter(ssh, c->self, sys_tun_infilter,
sys_tun_outfilter, NULL, NULL);
#endif
/*
* Update the list of names exposed to the session
* XXX remove these if the tunnels are closed (won't matter
* much if they are already in the environment though)
*/
tmp = tun_fwd_ifnames;
xasprintf(&tun_fwd_ifnames, "%s%s%s",
tun_fwd_ifnames == NULL ? "" : tun_fwd_ifnames,
tun_fwd_ifnames == NULL ? "" : ",",
ifname);
free(tmp);
free(ifname);
done:
if (c == NULL)
ssh_packet_send_debug(ssh, "Failed to open the tunnel device.");
return c;
}
static Channel *
server_request_session(struct ssh *ssh)
{
Channel *c;
int r;
debug("input_session_request");
if ((r = sshpkt_get_end(ssh)) != 0)
sshpkt_fatal(ssh, r, "%s: parse packet", __func__);
if (no_more_sessions) {
ssh_packet_disconnect(ssh, "Possible attack: attempt to open a "
"session after additional sessions disabled");
}
/*
* A server session has no fd to read or write until a
* CHANNEL_REQUEST for a shell is made, so we set the type to
* SSH_CHANNEL_LARVAL. Additionally, a callback for handling all
* CHANNEL_REQUEST messages is registered.
*/
c = channel_new(ssh, "session", SSH_CHANNEL_LARVAL,
-1, -1, -1, /*window size*/0, CHAN_SES_PACKET_DEFAULT,
0, "server-session", 1);
if (session_open(the_authctxt, c->self) != 1) {
debug("session open failed, free channel %d", c->self);
channel_free(ssh, c);
return NULL;
}
channel_register_cleanup(ssh, c->self, session_close_by_channel, 0);
return c;
}
static int
server_input_channel_open(int type, u_int32_t seq, struct ssh *ssh)
{
Channel *c = NULL;
char *ctype = NULL;
const char *errmsg = NULL;
int r, reason = SSH2_OPEN_CONNECT_FAILED;
u_int rchan = 0, rmaxpack = 0, rwindow = 0;
if ((r = sshpkt_get_cstring(ssh, &ctype, NULL)) != 0 ||
(r = sshpkt_get_u32(ssh, &rchan)) != 0 ||
(r = sshpkt_get_u32(ssh, &rwindow)) != 0 ||
(r = sshpkt_get_u32(ssh, &rmaxpack)) != 0)
sshpkt_fatal(ssh, r, "%s: parse packet", __func__);
debug_f("ctype %s rchan %u win %u max %u",
ctype, rchan, rwindow, rmaxpack);
if (strcmp(ctype, "session") == 0) {
c = server_request_session(ssh);
} else if (strcmp(ctype, "direct-tcpip") == 0) {
c = server_request_direct_tcpip(ssh, &reason, &errmsg);
} else if (strcmp(ctype, "direct-streamlocal@openssh.com") == 0) {
c = server_request_direct_streamlocal(ssh);
} else if (strcmp(ctype, "tun@openssh.com") == 0) {
c = server_request_tun(ssh);
}
if (c != NULL) {
debug_f("confirm %s", ctype);
c->remote_id = rchan;
c->have_remote_id = 1;
c->remote_window = rwindow;
c->remote_maxpacket = rmaxpack;
if (c->type != SSH_CHANNEL_CONNECTING) {
if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION)) != 0 ||
(r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
(r = sshpkt_put_u32(ssh, c->self)) != 0 ||
(r = sshpkt_put_u32(ssh, c->local_window)) != 0 ||
(r = sshpkt_put_u32(ssh, c->local_maxpacket)) != 0 ||
(r = sshpkt_send(ssh)) != 0) {
sshpkt_fatal(ssh, r,
"%s: send open confirm", __func__);
}
}
} else {
debug_f("failure %s", ctype);
if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_OPEN_FAILURE)) != 0 ||
(r = sshpkt_put_u32(ssh, rchan)) != 0 ||
(r = sshpkt_put_u32(ssh, reason)) != 0 ||
(r = sshpkt_put_cstring(ssh, errmsg ? errmsg : "open failed")) != 0 ||
(r = sshpkt_put_cstring(ssh, "")) != 0 ||
(r = sshpkt_send(ssh)) != 0) {
sshpkt_fatal(ssh, r,
"%s: send open failure", __func__);
}
}
free(ctype);
return 0;
}
static int
server_input_hostkeys_prove(struct ssh *ssh, struct sshbuf **respp)
{
struct sshbuf *resp = NULL;
struct sshbuf *sigbuf = NULL;
struct sshkey *key = NULL, *key_pub = NULL, *key_prv = NULL;
int r, ndx, success = 0;
const u_char *blob;
const char *sigalg, *kex_rsa_sigalg = NULL;
u_char *sig = 0;
size_t blen, slen;
if ((resp = sshbuf_new()) == NULL || (sigbuf = sshbuf_new()) == NULL)
fatal_f("sshbuf_new");
if (sshkey_type_plain(sshkey_type_from_name(
ssh->kex->hostkey_alg)) == KEY_RSA)
kex_rsa_sigalg = ssh->kex->hostkey_alg;
while (ssh_packet_remaining(ssh) > 0) {
sshkey_free(key);
key = NULL;
if ((r = sshpkt_get_string_direct(ssh, &blob, &blen)) != 0 ||
(r = sshkey_from_blob(blob, blen, &key)) != 0) {
error_fr(r, "parse key");
goto out;
}
/*
* Better check that this is actually one of our hostkeys
* before attempting to sign anything with it.
*/
if ((ndx = ssh->kex->host_key_index(key, 1, ssh)) == -1) {
error_f("unknown host %s key", sshkey_type(key));
goto out;
}
/*
* XXX refactor: make kex->sign just use an index rather
* than passing in public and private keys
*/
if ((key_prv = get_hostkey_by_index(ndx)) == NULL &&
(key_pub = get_hostkey_public_by_index(ndx, ssh)) == NULL) {
error_f("can't retrieve hostkey %d", ndx);
goto out;
}
sshbuf_reset(sigbuf);
free(sig);
sig = NULL;
/*
* For RSA keys, prefer to use the signature type negotiated
* during KEX to the default (SHA1).
*/
sigalg = NULL;
if (sshkey_type_plain(key->type) == KEY_RSA) {
if (kex_rsa_sigalg != NULL)
sigalg = kex_rsa_sigalg;
else if (ssh->kex->flags & KEX_RSA_SHA2_512_SUPPORTED)
sigalg = "rsa-sha2-512";
else if (ssh->kex->flags & KEX_RSA_SHA2_256_SUPPORTED)
sigalg = "rsa-sha2-256";
}
debug3_f("sign %s key (index %d) using sigalg %s",
sshkey_type(key), ndx, sigalg == NULL ? "default" : sigalg);
if ((r = sshbuf_put_cstring(sigbuf,
"hostkeys-prove-00@openssh.com")) != 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), sigalg)) != 0 ||
(r = sshbuf_put_string(resp, sig, slen)) != 0) {
error_fr(r, "assemble signature");
goto out;
}
}
/* Success */
*respp = resp;
resp = NULL; /* don't free it */
success = 1;
out:
free(sig);
sshbuf_free(resp);
sshbuf_free(sigbuf);
sshkey_free(key);
return success;
}
static int
server_input_global_request(int type, u_int32_t seq, struct ssh *ssh)
{
char *rtype = NULL;
u_char want_reply = 0;
int r, success = 0, allocated_listen_port = 0;
u_int port = 0;
struct sshbuf *resp = NULL;
struct passwd *pw = the_authctxt->pw;
struct Forward fwd;
memset(&fwd, 0, sizeof(fwd));
if (pw == NULL || !the_authctxt->valid)
fatal_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_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_f("tcpip-forward listen %s port %u",
fwd.listen_host, port);
if (port <= INT_MAX)
fwd.listen_port = (int)port;
/* check permissions */
if (port > INT_MAX ||
(options.allow_tcp_forwarding & FORWARD_REMOTE) == 0 ||
!auth_opts->permit_port_forwarding_flag ||
options.disable_forwarding ||
(!want_reply && fwd.listen_port == 0) ||
(fwd.listen_port != 0 &&
!bind_permitted(fwd.listen_port, pw->pw_uid))) {
success = 0;
ssh_packet_send_debug(ssh, "Server has disabled port forwarding.");
} else {
/* Start listening on the port */
success = channel_setup_remote_fwd_listener(ssh, &fwd,
&allocated_listen_port, &options.fwd_opts);
}
if ((resp = sshbuf_new()) == NULL)
fatal_f("sshbuf_new");
if (allocated_listen_port != 0 &&
(r = sshbuf_put_u32(resp, allocated_listen_port)) != 0)
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_f("cancel-tcpip-forward addr %s port %d",
fwd.listen_host, port);
if (port <= INT_MAX) {
fwd.listen_port = (int)port;
success = channel_cancel_rport_listener(ssh, &fwd);
}
} else if (strcmp(rtype, "streamlocal-forward@openssh.com") == 0) {
if ((r = sshpkt_get_cstring(ssh, &fwd.listen_path, NULL)) != 0)
sshpkt_fatal(ssh, r, "%s: parse streamlocal-forward@openssh.com", __func__);
debug_f("streamlocal-forward listen path %s",
fwd.listen_path);
/* check permissions */
if ((options.allow_streamlocal_forwarding & FORWARD_REMOTE) == 0
|| !auth_opts->permit_port_forwarding_flag ||
options.disable_forwarding ||
(pw->pw_uid != 0 && !use_privsep)) {
success = 0;
ssh_packet_send_debug(ssh, "Server has disabled "
"streamlocal forwarding.");
} else {
/* Start listening on the socket */
success = channel_setup_remote_fwd_listener(ssh,
&fwd, NULL, &options.fwd_opts);
}
} 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_f("cancel-streamlocal-forward path %s",
fwd.listen_path);
success = channel_cancel_rport_listener(ssh, &fwd);
} else if (strcmp(rtype, "no-more-sessions@openssh.com") == 0) {
no_more_sessions = 1;
success = 1;
} else if (strcmp(rtype, "hostkeys-prove-00@openssh.com") == 0) {
success = server_input_hostkeys_prove(ssh, &resp);
}
/* XXX sshpkt_get_end() */
if (want_reply) {
if ((r = sshpkt_start(ssh, success ?
SSH2_MSG_REQUEST_SUCCESS : SSH2_MSG_REQUEST_FAILURE)) != 0 ||
(success && resp != NULL && (r = sshpkt_putb(ssh, resp)) != 0) ||
(r = sshpkt_send(ssh)) != 0 ||
(r = ssh_packet_write_wait(ssh)) != 0)
sshpkt_fatal(ssh, r, "%s: send reply", __func__);
}
free(fwd.listen_host);
free(fwd.listen_path);
free(rtype);
sshbuf_free(resp);
return 0;
}
static int
server_input_channel_req(int type, u_int32_t seq, struct ssh *ssh)
{
Channel *c;
int r, success = 0;
char *rtype = NULL;
u_char want_reply = 0;
u_int id = 0;
if ((r = sshpkt_get_u32(ssh, &id)) != 0 ||
(r = sshpkt_get_cstring(ssh, &rtype, NULL)) != 0 ||
(r = sshpkt_get_u8(ssh, &want_reply)) != 0)
sshpkt_fatal(ssh, r, "%s: parse packet", __func__);
debug("server_input_channel_req: channel %u request %s reply %d",
id, rtype, want_reply);
if (id >= INT_MAX || (c = channel_lookup(ssh, (int)id)) == NULL) {
ssh_packet_disconnect(ssh, "%s: unknown channel %d",
__func__, id);
}
if (!strcmp(rtype, "eow@openssh.com")) {
if ((r = sshpkt_get_end(ssh)) != 0)
sshpkt_fatal(ssh, r, "%s: parse packet", __func__);
chan_rcvd_eow(ssh, c);
} else if ((c->type == SSH_CHANNEL_LARVAL ||
c->type == SSH_CHANNEL_OPEN) && strcmp(c->ctype, "session") == 0)
success = session_input_channel_req(ssh, c, rtype);
if (want_reply && !(c->flags & CHAN_CLOSE_SENT)) {
if (!c->have_remote_id)
fatal_f("channel %d: no remote_id", c->self);
if ((r = sshpkt_start(ssh, success ?
SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE)) != 0 ||
(r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
(r = sshpkt_send(ssh)) != 0)
sshpkt_fatal(ssh, r, "%s: send reply", __func__);
}
free(rtype);
return 0;
}
static void
server_init_dispatch(struct ssh *ssh)
{
debug("server_init_dispatch");
ssh_dispatch_init(ssh, &dispatch_protocol_error);
ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_CLOSE, &channel_input_oclose);
ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_DATA, &channel_input_data);
ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_EOF, &channel_input_ieof);
ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_EXTENDED_DATA, &channel_input_extended_data);
ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_OPEN, &server_input_channel_open);
ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation);
ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure);
ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_REQUEST, &server_input_channel_req);
ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_WINDOW_ADJUST, &channel_input_window_adjust);
ssh_dispatch_set(ssh, SSH2_MSG_GLOBAL_REQUEST, &server_input_global_request);
/* client_alive */
ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_SUCCESS, &server_input_keep_alive);
ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_FAILURE, &server_input_keep_alive);
ssh_dispatch_set(ssh, SSH2_MSG_REQUEST_SUCCESS, &server_input_keep_alive);
ssh_dispatch_set(ssh, SSH2_MSG_REQUEST_FAILURE, &server_input_keep_alive);
/* rekeying */
ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, &kex_input_kexinit);
}
diff --git a/crypto/openssh/session.c b/crypto/openssh/session.c
index ba0bbffdb440..e45f891d4f97 100644
--- a/crypto/openssh/session.c
+++ b/crypto/openssh/session.c
@@ -1,2732 +1,2743 @@
-/* $OpenBSD: session.c,v 1.330 2022/02/08 08:59:12 dtucker Exp $ */
+/* $OpenBSD: session.c,v 1.333 2023/01/06 02:42:34 djm Exp $ */
/*
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
*
* As far as I am concerned, the code I have written for this software
* can be used freely for any purpose. Any derived versions of this
* software must be clearly marked as such, and if the derived work is
* incompatible with the protocol description in the RFC file, it must be
* called by a name other than "ssh" or "Secure Shell".
*
* SSH2 support by Markus Friedl.
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "includes.h"
#include <sys/types.h>
#ifdef HAVE_SYS_STAT_H
# include <sys/stat.h>
#endif
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/wait.h>
#include <arpa/inet.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <grp.h>
#include <netdb.h>
#ifdef HAVE_PATHS_H
#include <paths.h>
#endif
#include <pwd.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <unistd.h>
#include <limits.h>
#include "openbsd-compat/sys-queue.h"
#include "xmalloc.h"
#include "ssh.h"
#include "ssh2.h"
#include "sshpty.h"
#include "packet.h"
#include "sshbuf.h"
#include "ssherr.h"
#include "match.h"
#include "uidswap.h"
#include "compat.h"
#include "channels.h"
#include "sshkey.h"
#include "cipher.h"
#ifdef GSSAPI
#include "ssh-gss.h"
#endif
#include "hostfile.h"
#include "auth.h"
#include "auth-options.h"
#include "authfd.h"
#include "pathnames.h"
#include "log.h"
#include "misc.h"
#include "servconf.h"
#include "sshlogin.h"
#include "serverloop.h"
#include "canohost.h"
#include "session.h"
#include "kex.h"
#include "monitor_wrap.h"
#include "sftp.h"
#include "atomicio.h"
#if defined(KRB5) && defined(USE_AFS)
#include <kafs.h>
#endif
#ifdef WITH_SELINUX
#include <selinux/selinux.h>
#endif
#define IS_INTERNAL_SFTP(c) \
(!strncmp(c, INTERNAL_SFTP_NAME, sizeof(INTERNAL_SFTP_NAME) - 1) && \
(c[sizeof(INTERNAL_SFTP_NAME) - 1] == '\0' || \
c[sizeof(INTERNAL_SFTP_NAME) - 1] == ' ' || \
c[sizeof(INTERNAL_SFTP_NAME) - 1] == '\t'))
/* func */
Session *session_new(void);
void session_set_fds(struct ssh *, Session *, int, int, int, int, int);
void session_pty_cleanup(Session *);
void session_proctitle(Session *);
int session_setup_x11fwd(struct ssh *, Session *);
int do_exec_pty(struct ssh *, Session *, const char *);
int do_exec_no_pty(struct ssh *, Session *, const char *);
int do_exec(struct ssh *, Session *, const char *);
void do_login(struct ssh *, Session *, const char *);
void do_child(struct ssh *, Session *, const char *);
void do_motd(void);
int check_quietlogin(Session *, const char *);
static void do_authenticated2(struct ssh *, Authctxt *);
static int session_pty_req(struct ssh *, Session *);
/* import */
extern ServerOptions options;
extern char *__progname;
extern int debug_flag;
extern u_int utmp_len;
extern int startup_pipe;
extern void destroy_sensitive_data(void);
extern struct sshbuf *loginmsg;
extern struct sshauthopt *auth_opts;
extern char *tun_fwd_ifnames; /* serverloop.c */
/* original command from peer. */
const char *original_command = NULL;
/* data */
static int sessions_first_unused = -1;
static int sessions_nalloc = 0;
static Session *sessions = NULL;
#define SUBSYSTEM_NONE 0
#define SUBSYSTEM_EXT 1
#define SUBSYSTEM_INT_SFTP 2
#define SUBSYSTEM_INT_SFTP_ERROR 3
#ifdef HAVE_LOGIN_CAP
login_cap_t *lc;
#endif
static int is_child = 0;
static int in_chroot = 0;
/* File containing userauth info, if ExposeAuthInfo set */
static char *auth_info_file = NULL;
/* Name and directory of socket for authentication agent forwarding. */
static char *auth_sock_name = NULL;
static char *auth_sock_dir = NULL;
/* removes the agent forwarding socket */
static void
auth_sock_cleanup_proc(struct passwd *pw)
{
if (auth_sock_name != NULL) {
temporarily_use_uid(pw);
unlink(auth_sock_name);
rmdir(auth_sock_dir);
auth_sock_name = NULL;
restore_uid();
}
}
static int
auth_input_request_forwarding(struct ssh *ssh, struct passwd * pw)
{
Channel *nc;
int sock = -1;
if (auth_sock_name != NULL) {
error("authentication forwarding requested twice.");
return 0;
}
/* Temporarily drop privileged uid for mkdir/bind. */
temporarily_use_uid(pw);
/* Allocate a buffer for the socket name, and format the name. */
auth_sock_dir = xstrdup("/tmp/ssh-XXXXXXXXXX");
/* Create private directory for socket */
if (mkdtemp(auth_sock_dir) == NULL) {
ssh_packet_send_debug(ssh, "Agent forwarding disabled: "
"mkdtemp() failed: %.100s", strerror(errno));
restore_uid();
free(auth_sock_dir);
auth_sock_dir = NULL;
goto authsock_err;
}
xasprintf(&auth_sock_name, "%s/agent.%ld",
auth_sock_dir, (long) getpid());
/* Start a Unix listener on auth_sock_name. */
sock = unix_listener(auth_sock_name, SSH_LISTEN_BACKLOG, 0);
/* Restore the privileged uid. */
restore_uid();
/* Check for socket/bind/listen failure. */
if (sock < 0)
goto authsock_err;
/* Allocate a channel for the authentication agent socket. */
- nc = channel_new(ssh, "auth socket",
+ nc = channel_new(ssh, "auth-listener",
SSH_CHANNEL_AUTH_SOCKET, sock, sock, -1,
CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT,
0, "auth socket", 1);
nc->path = xstrdup(auth_sock_name);
return 1;
authsock_err:
free(auth_sock_name);
if (auth_sock_dir != NULL) {
temporarily_use_uid(pw);
rmdir(auth_sock_dir);
restore_uid();
free(auth_sock_dir);
}
if (sock != -1)
close(sock);
auth_sock_name = NULL;
auth_sock_dir = NULL;
return 0;
}
static void
display_loginmsg(void)
{
int r;
if (sshbuf_len(loginmsg) == 0)
return;
if ((r = sshbuf_put_u8(loginmsg, 0)) != 0)
fatal_fr(r, "sshbuf_put_u8");
printf("%s", (char *)sshbuf_ptr(loginmsg));
sshbuf_reset(loginmsg);
}
static void
prepare_auth_info_file(struct passwd *pw, struct sshbuf *info)
{
int fd = -1, success = 0;
if (!options.expose_userauth_info || info == NULL)
return;
temporarily_use_uid(pw);
auth_info_file = xstrdup("/tmp/sshauth.XXXXXXXXXXXXXXX");
if ((fd = mkstemp(auth_info_file)) == -1) {
error_f("mkstemp: %s", strerror(errno));
goto out;
}
if (atomicio(vwrite, fd, sshbuf_mutable_ptr(info),
sshbuf_len(info)) != sshbuf_len(info)) {
error_f("write: %s", strerror(errno));
goto out;
}
if (close(fd) != 0) {
error_f("close: %s", strerror(errno));
goto out;
}
success = 1;
out:
if (!success) {
if (fd != -1)
close(fd);
free(auth_info_file);
auth_info_file = NULL;
}
restore_uid();
}
static void
set_fwdpermit_from_authopts(struct ssh *ssh, const struct sshauthopt *opts)
{
char *tmp, *cp, *host;
int port;
size_t i;
if ((options.allow_tcp_forwarding & FORWARD_LOCAL) != 0) {
channel_clear_permission(ssh, FORWARD_USER, FORWARD_LOCAL);
for (i = 0; i < auth_opts->npermitopen; i++) {
tmp = cp = xstrdup(auth_opts->permitopen[i]);
/* This shouldn't fail as it has already been checked */
if ((host = hpdelim2(&cp, NULL)) == NULL)
fatal_f("internal error: hpdelim");
host = cleanhostname(host);
if (cp == NULL || (port = permitopen_port(cp)) < 0)
fatal_f("internal error: permitopen port");
channel_add_permission(ssh,
FORWARD_USER, FORWARD_LOCAL, host, port);
free(tmp);
}
}
if ((options.allow_tcp_forwarding & FORWARD_REMOTE) != 0) {
channel_clear_permission(ssh, FORWARD_USER, FORWARD_REMOTE);
for (i = 0; i < auth_opts->npermitlisten; i++) {
tmp = cp = xstrdup(auth_opts->permitlisten[i]);
/* This shouldn't fail as it has already been checked */
if ((host = hpdelim(&cp)) == NULL)
fatal_f("internal error: hpdelim");
host = cleanhostname(host);
if (cp == NULL || (port = permitopen_port(cp)) < 0)
fatal_f("internal error: permitlisten port");
channel_add_permission(ssh,
FORWARD_USER, FORWARD_REMOTE, host, port);
free(tmp);
}
}
}
void
do_authenticated(struct ssh *ssh, Authctxt *authctxt)
{
setproctitle("%s", authctxt->pw->pw_name);
auth_log_authopts("active", auth_opts, 0);
/* setup the channel layer */
/* XXX - streamlocal? */
set_fwdpermit_from_authopts(ssh, auth_opts);
if (!auth_opts->permit_port_forwarding_flag ||
options.disable_forwarding) {
channel_disable_admin(ssh, FORWARD_LOCAL);
channel_disable_admin(ssh, FORWARD_REMOTE);
} else {
if ((options.allow_tcp_forwarding & FORWARD_LOCAL) == 0)
channel_disable_admin(ssh, FORWARD_LOCAL);
else
channel_permit_all(ssh, FORWARD_LOCAL);
if ((options.allow_tcp_forwarding & FORWARD_REMOTE) == 0)
channel_disable_admin(ssh, FORWARD_REMOTE);
else
channel_permit_all(ssh, FORWARD_REMOTE);
}
auth_debug_send(ssh);
prepare_auth_info_file(authctxt->pw, authctxt->session_info);
do_authenticated2(ssh, authctxt);
do_cleanup(ssh, authctxt);
}
/* Check untrusted xauth strings for metacharacters */
static int
xauth_valid_string(const char *s)
{
size_t i;
for (i = 0; s[i] != '\0'; i++) {
if (!isalnum((u_char)s[i]) &&
s[i] != '.' && s[i] != ':' && s[i] != '/' &&
s[i] != '-' && s[i] != '_')
return 0;
}
return 1;
}
#define USE_PIPES 1
/*
* This is called to fork and execute a command when we have no tty. This
* will call do_child from the child, and server_loop from the parent after
* setting up file descriptors and such.
*/
int
do_exec_no_pty(struct ssh *ssh, Session *s, const char *command)
{
pid_t pid;
#ifdef USE_PIPES
int pin[2], pout[2], perr[2];
if (s == NULL)
fatal("do_exec_no_pty: no session");
/* Allocate pipes for communicating with the program. */
if (pipe(pin) == -1) {
error_f("pipe in: %.100s", strerror(errno));
return -1;
}
if (pipe(pout) == -1) {
error_f("pipe out: %.100s", strerror(errno));
close(pin[0]);
close(pin[1]);
return -1;
}
if (pipe(perr) == -1) {
error_f("pipe err: %.100s", strerror(errno));
close(pin[0]);
close(pin[1]);
close(pout[0]);
close(pout[1]);
return -1;
}
#else
int inout[2], err[2];
if (s == NULL)
fatal("do_exec_no_pty: no session");
/* Uses socket pairs to communicate with the program. */
if (socketpair(AF_UNIX, SOCK_STREAM, 0, inout) == -1) {
error_f("socketpair #1: %.100s", strerror(errno));
return -1;
}
if (socketpair(AF_UNIX, SOCK_STREAM, 0, err) == -1) {
error_f("socketpair #2: %.100s", strerror(errno));
close(inout[0]);
close(inout[1]);
return -1;
}
#endif
session_proctitle(s);
/* Fork the child. */
switch ((pid = fork())) {
case -1:
error_f("fork: %.100s", strerror(errno));
#ifdef USE_PIPES
close(pin[0]);
close(pin[1]);
close(pout[0]);
close(pout[1]);
close(perr[0]);
close(perr[1]);
#else
close(inout[0]);
close(inout[1]);
close(err[0]);
close(err[1]);
#endif
return -1;
case 0:
is_child = 1;
/*
* Create a new session and process group since the 4.4BSD
* setlogin() affects the entire process group.
*/
if (setsid() == -1)
error("setsid failed: %.100s", strerror(errno));
#ifdef USE_PIPES
/*
* Redirect stdin. We close the parent side of the socket
* pair, and make the child side the standard input.
*/
close(pin[1]);
if (dup2(pin[0], 0) == -1)
perror("dup2 stdin");
close(pin[0]);
/* Redirect stdout. */
close(pout[0]);
if (dup2(pout[1], 1) == -1)
perror("dup2 stdout");
close(pout[1]);
/* Redirect stderr. */
close(perr[0]);
if (dup2(perr[1], 2) == -1)
perror("dup2 stderr");
close(perr[1]);
#else
/*
* Redirect stdin, stdout, and stderr. Stdin and stdout will
* use the same socket, as some programs (particularly rdist)
* seem to depend on it.
*/
close(inout[1]);
close(err[1]);
if (dup2(inout[0], 0) == -1) /* stdin */
perror("dup2 stdin");
if (dup2(inout[0], 1) == -1) /* stdout (same as stdin) */
perror("dup2 stdout");
close(inout[0]);
if (dup2(err[0], 2) == -1) /* stderr */
perror("dup2 stderr");
close(err[0]);
#endif
/* Do processing for the child (exec command etc). */
do_child(ssh, s, command);
/* NOTREACHED */
default:
break;
}
#ifdef HAVE_CYGWIN
cygwin_set_impersonation_token(INVALID_HANDLE_VALUE);
#endif
s->pid = pid;
/* Set interactive/non-interactive mode. */
ssh_packet_set_interactive(ssh, s->display != NULL,
options.ip_qos_interactive, options.ip_qos_bulk);
/*
* Clear loginmsg, since it's the child's responsibility to display
* it to the user, otherwise multiple sessions may accumulate
* multiple copies of the login messages.
*/
sshbuf_reset(loginmsg);
#ifdef USE_PIPES
/* We are the parent. Close the child sides of the pipes. */
close(pin[0]);
close(pout[1]);
close(perr[1]);
session_set_fds(ssh, s, pin[1], pout[0], perr[0],
s->is_subsystem, 0);
#else
/* We are the parent. Close the child sides of the socket pairs. */
close(inout[0]);
close(err[0]);
/*
* Enter the interactive session. Note: server_loop must be able to
* handle the case that fdin and fdout are the same.
*/
session_set_fds(ssh, s, inout[1], inout[1], err[1],
s->is_subsystem, 0);
#endif
return 0;
}
/*
* This is called to fork and execute a command when we have a tty. This
* will call do_child from the child, and server_loop from the parent after
* setting up file descriptors, controlling tty, updating wtmp, utmp,
* lastlog, and other such operations.
*/
int
do_exec_pty(struct ssh *ssh, Session *s, const char *command)
{
int fdout, ptyfd, ttyfd, ptymaster;
pid_t pid;
if (s == NULL)
fatal("do_exec_pty: no session");
ptyfd = s->ptyfd;
ttyfd = s->ttyfd;
/*
* Create another descriptor of the pty master side for use as the
* standard input. We could use the original descriptor, but this
* simplifies code in server_loop. The descriptor is bidirectional.
* Do this before forking (and cleanup in the child) so as to
* detect and gracefully fail out-of-fd conditions.
*/
if ((fdout = dup(ptyfd)) == -1) {
error_f("dup #1: %s", strerror(errno));
close(ttyfd);
close(ptyfd);
return -1;
}
/* we keep a reference to the pty master */
if ((ptymaster = dup(ptyfd)) == -1) {
error_f("dup #2: %s", strerror(errno));
close(ttyfd);
close(ptyfd);
close(fdout);
return -1;
}
/* Fork the child. */
switch ((pid = fork())) {
case -1:
error_f("fork: %.100s", strerror(errno));
close(fdout);
close(ptymaster);
close(ttyfd);
close(ptyfd);
return -1;
case 0:
is_child = 1;
close(fdout);
close(ptymaster);
/* Close the master side of the pseudo tty. */
close(ptyfd);
/* Make the pseudo tty our controlling tty. */
pty_make_controlling_tty(&ttyfd, s->tty);
/* Redirect stdin/stdout/stderr from the pseudo tty. */
if (dup2(ttyfd, 0) == -1)
error("dup2 stdin: %s", strerror(errno));
if (dup2(ttyfd, 1) == -1)
error("dup2 stdout: %s", strerror(errno));
if (dup2(ttyfd, 2) == -1)
error("dup2 stderr: %s", strerror(errno));
/* Close the extra descriptor for the pseudo tty. */
close(ttyfd);
/* record login, etc. similar to login(1) */
#ifndef HAVE_OSF_SIA
do_login(ssh, s, command);
#endif
/*
* Do common processing for the child, such as execing
* the command.
*/
do_child(ssh, s, command);
/* NOTREACHED */
default:
break;
}
#ifdef HAVE_CYGWIN
cygwin_set_impersonation_token(INVALID_HANDLE_VALUE);
#endif
s->pid = pid;
/* Parent. Close the slave side of the pseudo tty. */
close(ttyfd);
/* Enter interactive session. */
s->ptymaster = ptymaster;
ssh_packet_set_interactive(ssh, 1,
options.ip_qos_interactive, options.ip_qos_bulk);
session_set_fds(ssh, s, ptyfd, fdout, -1, 1, 1);
return 0;
}
/*
* This is called to fork and execute a command. If another command is
* to be forced, execute that instead.
*/
int
do_exec(struct ssh *ssh, Session *s, const char *command)
{
int ret;
const char *forced = NULL, *tty = NULL;
char session_type[1024];
if (options.adm_forced_command) {
original_command = command;
command = options.adm_forced_command;
forced = "(config)";
} else if (auth_opts->force_command != NULL) {
original_command = command;
command = auth_opts->force_command;
forced = "(key-option)";
}
s->forced = 0;
if (forced != NULL) {
s->forced = 1;
if (IS_INTERNAL_SFTP(command)) {
s->is_subsystem = s->is_subsystem ?
SUBSYSTEM_INT_SFTP : SUBSYSTEM_INT_SFTP_ERROR;
} else if (s->is_subsystem)
s->is_subsystem = SUBSYSTEM_EXT;
snprintf(session_type, sizeof(session_type),
"forced-command %s '%.900s'", forced, command);
} else if (s->is_subsystem) {
snprintf(session_type, sizeof(session_type),
"subsystem '%.900s'", s->subsys);
} else if (command == NULL) {
snprintf(session_type, sizeof(session_type), "shell");
} else {
/* NB. we don't log unforced commands to preserve privacy */
snprintf(session_type, sizeof(session_type), "command");
}
if (s->ttyfd != -1) {
tty = s->tty;
if (strncmp(tty, "/dev/", 5) == 0)
tty += 5;
}
verbose("Starting session: %s%s%s for %s from %.200s port %d id %d",
session_type,
tty == NULL ? "" : " on ",
tty == NULL ? "" : tty,
s->pw->pw_name,
ssh_remote_ipaddr(ssh),
ssh_remote_port(ssh),
s->self);
#ifdef SSH_AUDIT_EVENTS
if (command != NULL)
PRIVSEP(audit_run_command(command));
else if (s->ttyfd == -1) {
char *shell = s->pw->pw_shell;
if (shell[0] == '\0') /* empty shell means /bin/sh */
shell =_PATH_BSHELL;
PRIVSEP(audit_run_command(shell));
}
#endif
if (s->ttyfd != -1)
ret = do_exec_pty(ssh, s, command);
else
ret = do_exec_no_pty(ssh, s, command);
original_command = NULL;
/*
* Clear loginmsg: it's the child's responsibility to display
* it to the user, otherwise multiple sessions may accumulate
* multiple copies of the login messages.
*/
sshbuf_reset(loginmsg);
return ret;
}
/* administrative, login(1)-like work */
void
do_login(struct ssh *ssh, Session *s, const char *command)
{
socklen_t fromlen;
struct sockaddr_storage from;
struct passwd * pw = s->pw;
pid_t pid = getpid();
/*
* Get IP address of client. If the connection is not a socket, let
* the address be 0.0.0.0.
*/
memset(&from, 0, sizeof(from));
fromlen = sizeof(from);
if (ssh_packet_connection_is_on_socket(ssh)) {
if (getpeername(ssh_packet_get_connection_in(ssh),
(struct sockaddr *)&from, &fromlen) == -1) {
debug("getpeername: %.100s", strerror(errno));
cleanup_exit(255);
}
}
/* Record that there was a login on that tty from the remote host. */
if (!use_privsep)
record_login(pid, s->tty, pw->pw_name, pw->pw_uid,
session_get_remote_name_or_ip(ssh, utmp_len,
options.use_dns),
(struct sockaddr *)&from, fromlen);
#ifdef USE_PAM
/*
* If password change is needed, do it now.
* This needs to occur before the ~/.hushlogin check.
*/
if (options.use_pam && !use_privsep && s->authctxt->force_pwchange) {
display_loginmsg();
do_pam_chauthtok();
s->authctxt->force_pwchange = 0;
/* XXX - signal [net] parent to enable forwardings */
}
#endif
if (check_quietlogin(s, command))
return;
display_loginmsg();
do_motd();
}
/*
* Display the message of the day.
*/
void
do_motd(void)
{
FILE *f;
char buf[256];
if (options.print_motd) {
#ifdef HAVE_LOGIN_CAP
f = fopen(login_getcapstr(lc, "welcome", "/etc/motd",
"/etc/motd"), "r");
#else
f = fopen("/etc/motd", "r");
#endif
if (f) {
while (fgets(buf, sizeof(buf), f))
fputs(buf, stdout);
fclose(f);
}
}
}
/*
* Check for quiet login, either .hushlogin or command given.
*/
int
check_quietlogin(Session *s, const char *command)
{
char buf[256];
struct passwd *pw = s->pw;
struct stat st;
/* Return 1 if .hushlogin exists or a command given. */
if (command != NULL)
return 1;
snprintf(buf, sizeof(buf), "%.200s/.hushlogin", pw->pw_dir);
#ifdef HAVE_LOGIN_CAP
if (login_getcapbool(lc, "hushlogin", 0) || stat(buf, &st) >= 0)
return 1;
#else
if (stat(buf, &st) >= 0)
return 1;
#endif
return 0;
}
/*
* Reads environment variables from the given file and adds/overrides them
* into the environment. If the file does not exist, this does nothing.
* Otherwise, it must consist of empty lines, comments (line starts with '#')
* and assignments of the form name=value. No other forms are allowed.
* If allowlist is not NULL, then it is interpreted as a pattern list and
* only variable names that match it will be accepted.
*/
static void
read_environment_file(char ***env, u_int *envsize,
const char *filename, const char *allowlist)
{
FILE *f;
char *line = NULL, *cp, *value;
size_t linesize = 0;
u_int lineno = 0;
f = fopen(filename, "r");
if (!f)
return;
while (getline(&line, &linesize, f) != -1) {
if (++lineno > 1000)
fatal("Too many lines in environment file %s", filename);
for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
;
if (!*cp || *cp == '#' || *cp == '\n')
continue;
cp[strcspn(cp, "\n")] = '\0';
value = strchr(cp, '=');
if (value == NULL) {
fprintf(stderr, "Bad line %u in %.100s\n", lineno,
filename);
continue;
}
/*
* Replace the equals sign by nul, and advance value to
* the value string.
*/
*value = '\0';
value++;
if (allowlist != NULL &&
match_pattern_list(cp, allowlist, 0) != 1)
continue;
child_set_env(env, envsize, cp, value);
}
free(line);
fclose(f);
}
#ifdef HAVE_ETC_DEFAULT_LOGIN
/*
* Return named variable from specified environment, or NULL if not present.
*/
static char *
child_get_env(char **env, const char *name)
{
int i;
size_t len;
len = strlen(name);
for (i=0; env[i] != NULL; i++)
if (strncmp(name, env[i], len) == 0 && env[i][len] == '=')
return(env[i] + len + 1);
return NULL;
}
/*
* Read /etc/default/login.
* We pick up the PATH (or SUPATH for root) and UMASK.
*/
static void
read_etc_default_login(char ***env, u_int *envsize, uid_t uid)
{
char **tmpenv = NULL, *var;
u_int i, tmpenvsize = 0;
u_long mask;
/*
* We don't want to copy the whole file to the child's environment,
* so we use a temporary environment and copy the variables we're
* interested in.
*/
read_environment_file(&tmpenv, &tmpenvsize, "/etc/default/login",
options.permit_user_env_allowlist);
if (tmpenv == NULL)
return;
if (uid == 0)
var = child_get_env(tmpenv, "SUPATH");
else
var = child_get_env(tmpenv, "PATH");
if (var != NULL)
child_set_env(env, envsize, "PATH", var);
if ((var = child_get_env(tmpenv, "UMASK")) != NULL)
if (sscanf(var, "%5lo", &mask) == 1)
umask((mode_t)mask);
for (i = 0; tmpenv[i] != NULL; i++)
free(tmpenv[i]);
free(tmpenv);
}
#endif /* HAVE_ETC_DEFAULT_LOGIN */
#if defined(USE_PAM) || defined(HAVE_CYGWIN)
static void
copy_environment_denylist(char **source, char ***env, u_int *envsize,
const char *denylist)
{
char *var_name, *var_val;
int i;
if (source == NULL)
return;
for(i = 0; source[i] != NULL; i++) {
var_name = xstrdup(source[i]);
if ((var_val = strstr(var_name, "=")) == NULL) {
free(var_name);
continue;
}
*var_val++ = '\0';
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);
}
free(var_name);
}
}
#endif /* defined(USE_PAM) || defined(HAVE_CYGWIN) */
#ifdef HAVE_CYGWIN
static void
copy_environment(char **source, char ***env, u_int *envsize)
{
copy_environment_denylist(source, env, envsize, NULL);
}
#endif
static char **
do_setup_env(struct ssh *ssh, Session *s, const char *shell)
{
char buf[256];
size_t n;
u_int i, envsize;
char *ocp, *cp, *value, **env, *laddr;
struct passwd *pw = s->pw;
#if !defined (HAVE_LOGIN_CAP) && !defined (HAVE_CYGWIN)
char *path = NULL;
#else
extern char **environ;
char **senv, **var, *val;
#endif
/* Initialize the environment. */
envsize = 100;
env = xcalloc(envsize, sizeof(char *));
env[0] = NULL;
#ifdef HAVE_CYGWIN
/*
* The Windows environment contains some setting which are
* important for a running system. They must not be dropped.
*/
{
char **p;
p = fetch_windows_environment();
copy_environment(p, &env, &envsize);
free_windows_environment(p);
}
#endif
if (getenv("TZ"))
child_set_env(&env, &envsize, "TZ", getenv("TZ"));
#ifdef GSSAPI
/* Allow any GSSAPI methods that we've used to alter
* the child's environment as they see fit
*/
ssh_gssapi_do_child(&env, &envsize);
#endif
/* Set basic environment. */
for (i = 0; i < s->num_env; i++)
child_set_env(&env, &envsize, s->env[i].name, s->env[i].val);
child_set_env(&env, &envsize, "USER", pw->pw_name);
child_set_env(&env, &envsize, "LOGNAME", pw->pw_name);
#ifdef _AIX
child_set_env(&env, &envsize, "LOGIN", pw->pw_name);
#endif
child_set_env(&env, &envsize, "HOME", pw->pw_dir);
snprintf(buf, sizeof buf, "%.200s/%.50s", _PATH_MAILDIR, pw->pw_name);
child_set_env(&env, &envsize, "MAIL", buf);
#ifdef HAVE_LOGIN_CAP
child_set_env(&env, &envsize, "PATH", _PATH_STDPATH);
child_set_env(&env, &envsize, "TERM", "su");
/*
* Temporarily swap out our real environment with an empty one,
* let setusercontext() apply any environment variables defined
* for the user's login class, copy those variables to the child,
* free the temporary environment, and restore the original.
*/
senv = environ;
environ = xmalloc(sizeof(*environ));
*environ = NULL;
(void)setusercontext(lc, pw, pw->pw_uid, LOGIN_SETENV|LOGIN_SETPATH);
for (var = environ; *var != NULL; ++var) {
if ((val = strchr(*var, '=')) != NULL) {
*val++ = '\0';
child_set_env(&env, &envsize, *var, val);
}
free(*var);
}
free(environ);
environ = senv;
#else /* HAVE_LOGIN_CAP */
# ifndef HAVE_CYGWIN
/*
* There's no standard path on Windows. The path contains
* important components pointing to the system directories,
* needed for loading shared libraries. So the path better
* remains intact here.
*/
# ifdef HAVE_ETC_DEFAULT_LOGIN
read_etc_default_login(&env, &envsize, pw->pw_uid);
path = child_get_env(env, "PATH");
# endif /* HAVE_ETC_DEFAULT_LOGIN */
if (path == NULL || *path == '\0') {
child_set_env(&env, &envsize, "PATH",
s->pw->pw_uid == 0 ? SUPERUSER_PATH : _PATH_STDPATH);
}
# endif /* HAVE_CYGWIN */
#endif /* HAVE_LOGIN_CAP */
/* Normal systems set SHELL by default. */
child_set_env(&env, &envsize, "SHELL", shell);
if (s->term)
child_set_env(&env, &envsize, "TERM", s->term);
if (s->display)
child_set_env(&env, &envsize, "DISPLAY", s->display);
/*
* Since we clear KRB5CCNAME at startup, if it's set now then it
* must have been set by a native authentication method (eg AIX or
* SIA), so copy it to the child.
*/
{
char *cp;
if ((cp = getenv("KRB5CCNAME")) != NULL)
child_set_env(&env, &envsize, "KRB5CCNAME", cp);
}
#ifdef _AIX
{
char *cp;
if ((cp = getenv("AUTHSTATE")) != NULL)
child_set_env(&env, &envsize, "AUTHSTATE", cp);
read_environment_file(&env, &envsize, "/etc/environment",
options.permit_user_env_allowlist);
}
#endif
#ifdef KRB5
if (s->authctxt->krb5_ccname)
child_set_env(&env, &envsize, "KRB5CCNAME",
s->authctxt->krb5_ccname);
#endif
if (auth_sock_name != NULL)
child_set_env(&env, &envsize, SSH_AUTHSOCKET_ENV_NAME,
auth_sock_name);
/* Set custom environment options from pubkey authentication. */
if (options.permit_user_env) {
for (n = 0 ; n < auth_opts->nenv; n++) {
ocp = xstrdup(auth_opts->env[n]);
cp = strchr(ocp, '=');
if (cp != NULL) {
*cp = '\0';
/* Apply PermitUserEnvironment allowlist */
if (options.permit_user_env_allowlist == NULL ||
match_pattern_list(ocp,
options.permit_user_env_allowlist, 0) == 1)
child_set_env(&env, &envsize,
ocp, cp + 1);
}
free(ocp);
}
}
/* read $HOME/.ssh/environment. */
if (options.permit_user_env) {
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);
}
#ifdef USE_PAM
/*
* Pull in any environment variables that may have
* been set by PAM.
*/
if (options.use_pam) {
char **p;
/*
* Don't allow PAM-internal env vars to leak
* back into the session environment.
*/
#define PAM_ENV_DENYLIST "SSH_AUTH_INFO*,SSH_CONNECTION*"
p = fetch_pam_child_environment();
copy_environment_denylist(p, &env, &envsize,
PAM_ENV_DENYLIST);
free_pam_environment(p);
p = fetch_pam_environment();
copy_environment_denylist(p, &env, &envsize,
PAM_ENV_DENYLIST);
free_pam_environment(p);
}
#endif /* USE_PAM */
/* Environment specified by admin */
for (i = 0; i < options.num_setenv; i++) {
cp = xstrdup(options.setenv[i]);
if ((value = strchr(cp, '=')) == NULL) {
/* shouldn't happen; vars are checked in servconf.c */
fatal("Invalid config SetEnv: %s", options.setenv[i]);
}
*value++ = '\0';
child_set_env(&env, &envsize, cp, value);
}
/* SSH_CLIENT deprecated */
snprintf(buf, sizeof buf, "%.50s %d %d",
ssh_remote_ipaddr(ssh), ssh_remote_port(ssh),
ssh_local_port(ssh));
child_set_env(&env, &envsize, "SSH_CLIENT", buf);
laddr = get_local_ipaddr(ssh_packet_get_connection_in(ssh));
snprintf(buf, sizeof buf, "%.50s %d %.50s %d",
ssh_remote_ipaddr(ssh), ssh_remote_port(ssh),
laddr, ssh_local_port(ssh));
free(laddr);
child_set_env(&env, &envsize, "SSH_CONNECTION", buf);
if (tun_fwd_ifnames != NULL)
child_set_env(&env, &envsize, "SSH_TUNNEL", tun_fwd_ifnames);
if (auth_info_file != NULL)
child_set_env(&env, &envsize, "SSH_USER_AUTH", auth_info_file);
if (s->ttyfd != -1)
child_set_env(&env, &envsize, "SSH_TTY", s->tty);
if (original_command)
child_set_env(&env, &envsize, "SSH_ORIGINAL_COMMAND",
original_command);
if (debug_flag) {
/* dump the environment */
fprintf(stderr, "Environment:\n");
for (i = 0; env[i]; i++)
fprintf(stderr, " %.200s\n", env[i]);
}
return env;
}
/*
* Run $HOME/.ssh/rc, /etc/ssh/sshrc, or xauth (whichever is found
* first in this order).
*/
static void
do_rc_files(struct ssh *ssh, Session *s, const char *shell)
{
FILE *f = NULL;
char *cmd = NULL, *user_rc = NULL;
int do_xauth;
struct stat st;
do_xauth =
s->display != NULL && s->auth_proto != NULL && s->auth_data != NULL;
xasprintf(&user_rc, "%s/%s", s->pw->pw_dir, _PATH_SSH_USER_RC);
/* ignore _PATH_SSH_USER_RC for subsystems and admin forced commands */
if (!s->is_subsystem && options.adm_forced_command == NULL &&
auth_opts->permit_user_rc && options.permit_user_rc &&
stat(user_rc, &st) >= 0) {
if (xasprintf(&cmd, "%s -c '%s %s'", shell, _PATH_BSHELL,
user_rc) == -1)
fatal_f("xasprintf: %s", strerror(errno));
if (debug_flag)
fprintf(stderr, "Running %s\n", cmd);
f = popen(cmd, "w");
if (f) {
if (do_xauth)
fprintf(f, "%s %s\n", s->auth_proto,
s->auth_data);
pclose(f);
} else
fprintf(stderr, "Could not run %s\n",
user_rc);
} else if (stat(_PATH_SSH_SYSTEM_RC, &st) >= 0) {
if (debug_flag)
fprintf(stderr, "Running %s %s\n", _PATH_BSHELL,
_PATH_SSH_SYSTEM_RC);
f = popen(_PATH_BSHELL " " _PATH_SSH_SYSTEM_RC, "w");
if (f) {
if (do_xauth)
fprintf(f, "%s %s\n", s->auth_proto,
s->auth_data);
pclose(f);
} else
fprintf(stderr, "Could not run %s\n",
_PATH_SSH_SYSTEM_RC);
} else if (do_xauth && options.xauth_location != NULL) {
/* Add authority data to .Xauthority if appropriate. */
if (debug_flag) {
fprintf(stderr,
"Running %.500s remove %.100s\n",
options.xauth_location, s->auth_display);
fprintf(stderr,
"%.500s add %.100s %.100s %.100s\n",
options.xauth_location, s->auth_display,
s->auth_proto, s->auth_data);
}
if (xasprintf(&cmd, "%s -q -", options.xauth_location) == -1)
fatal_f("xasprintf: %s", strerror(errno));
f = popen(cmd, "w");
if (f) {
fprintf(f, "remove %s\n",
s->auth_display);
fprintf(f, "add %s %s %s\n",
s->auth_display, s->auth_proto,
s->auth_data);
pclose(f);
} else {
fprintf(stderr, "Could not run %s\n",
cmd);
}
}
free(cmd);
free(user_rc);
}
static void
do_nologin(struct passwd *pw)
{
FILE *f = NULL;
const char *nl;
char buf[1024], *def_nl = _PATH_NOLOGIN;
struct stat sb;
#ifdef HAVE_LOGIN_CAP
if (login_getcapbool(lc, "ignorenologin", 0) || pw->pw_uid == 0)
return;
nl = login_getcapstr(lc, "nologin", def_nl, def_nl);
#else
if (pw->pw_uid == 0)
return;
nl = def_nl;
#endif
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);
if ((f = fopen(nl, "r")) != NULL) {
while (fgets(buf, sizeof(buf), f))
fputs(buf, stderr);
fclose(f);
}
exit(254);
}
/*
* Chroot into a directory after checking it for safety: all path components
* must be root-owned directories with strict permissions.
*/
static void
safely_chroot(const char *path, uid_t uid)
{
const char *cp;
char component[PATH_MAX];
struct stat st;
if (!path_absolute(path))
fatal("chroot path does not begin at root");
if (strlen(path) >= sizeof(component))
fatal("chroot path too long");
/*
* Descend the path, checking that each component is a
* root-owned directory with strict permissions.
*/
for (cp = path; cp != NULL;) {
if ((cp = strchr(cp, '/')) == NULL)
strlcpy(component, path, sizeof(component));
else {
cp++;
memcpy(component, path, cp - path);
component[cp - path] = '\0';
}
debug3_f("checking '%s'", component);
if (stat(component, &st) != 0)
fatal_f("stat(\"%s\"): %s",
component, strerror(errno));
if (st.st_uid != 0 || (st.st_mode & 022) != 0)
fatal("bad ownership or modes for chroot "
"directory %s\"%s\"",
cp == NULL ? "" : "component ", component);
if (!S_ISDIR(st.st_mode))
fatal("chroot path %s\"%s\" is not a directory",
cp == NULL ? "" : "component ", component);
}
if (chdir(path) == -1)
fatal("Unable to chdir to chroot path \"%s\": "
"%s", path, strerror(errno));
if (chroot(path) == -1)
fatal("chroot(\"%s\"): %s", path, strerror(errno));
if (chdir("/") == -1)
fatal_f("chdir(/) after chroot: %s", strerror(errno));
verbose("Changed root directory to \"%s\"", path);
}
/* Set login name, uid, gid, and groups. */
void
do_setusercontext(struct passwd *pw)
{
char uidstr[32], *chroot_path, *tmp;
platform_setusercontext(pw);
if (platform_privileged_uidswap()) {
#ifdef HAVE_LOGIN_CAP
if (setusercontext(lc, pw, pw->pw_uid,
(LOGIN_SETALL & ~(LOGIN_SETENV|LOGIN_SETPATH|LOGIN_SETUSER))) < 0) {
perror("unable to set user context");
exit(1);
}
#else
if (setlogin(pw->pw_name) < 0)
error("setlogin failed: %s", strerror(errno));
if (setgid(pw->pw_gid) < 0) {
perror("setgid");
exit(1);
}
/* Initialize the group list. */
if (initgroups(pw->pw_name, pw->pw_gid) < 0) {
perror("initgroups");
exit(1);
}
endgrent();
#endif
platform_setusercontext_post_groups(pw);
if (!in_chroot && options.chroot_directory != NULL &&
strcasecmp(options.chroot_directory, "none") != 0) {
tmp = tilde_expand_filename(options.chroot_directory,
pw->pw_uid);
snprintf(uidstr, sizeof(uidstr), "%llu",
(unsigned long long)pw->pw_uid);
chroot_path = percent_expand(tmp, "h", pw->pw_dir,
"u", pw->pw_name, "U", uidstr, (char *)NULL);
safely_chroot(chroot_path, pw->pw_uid);
free(tmp);
free(chroot_path);
/* Make sure we don't attempt to chroot again */
free(options.chroot_directory);
options.chroot_directory = NULL;
in_chroot = 1;
}
#ifdef HAVE_LOGIN_CAP
if (setusercontext(lc, pw, pw->pw_uid, LOGIN_SETUSER) < 0) {
perror("unable to set user context (setuser)");
exit(1);
}
/*
* FreeBSD's setusercontext() will not apply the user's
* own umask setting unless running with the user's UID.
*/
(void) setusercontext(lc, pw, pw->pw_uid, LOGIN_SETUMASK);
#else
# ifdef USE_LIBIAF
/*
* In a chroot environment, the set_id() will always fail;
* typically because of the lack of necessary authentication
* services and runtime such as ./usr/lib/libiaf.so,
* ./usr/lib/libpam.so.1, and ./etc/passwd We skip it in the
* internal sftp chroot case. We'll lose auditing and ACLs but
* permanently_set_uid will take care of the rest.
*/
if (!in_chroot && set_id(pw->pw_name) != 0)
fatal("set_id(%s) Failed", pw->pw_name);
# endif /* USE_LIBIAF */
/* Permanently switch to the desired uid. */
permanently_set_uid(pw);
#endif
} else if (options.chroot_directory != NULL &&
strcasecmp(options.chroot_directory, "none") != 0) {
fatal("server lacks privileges to chroot to ChrootDirectory");
}
if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid)
fatal("Failed to set uids to %u.", (u_int) pw->pw_uid);
}
static void
do_pwchange(Session *s)
{
fflush(NULL);
fprintf(stderr, "WARNING: Your password has expired.\n");
if (s->ttyfd != -1) {
fprintf(stderr,
"You must change your password now and login again!\n");
#ifdef WITH_SELINUX
setexeccon(NULL);
#endif
#ifdef PASSWD_NEEDS_USERNAME
execl(_PATH_PASSWD_PROG, "passwd", s->pw->pw_name,
(char *)NULL);
#else
execl(_PATH_PASSWD_PROG, "passwd", (char *)NULL);
#endif
perror("passwd");
} else {
fprintf(stderr,
"Password change required but no TTY available.\n");
}
exit(1);
}
static void
child_close_fds(struct ssh *ssh)
{
extern int auth_sock;
if (auth_sock != -1) {
close(auth_sock);
auth_sock = -1;
}
if (ssh_packet_get_connection_in(ssh) ==
ssh_packet_get_connection_out(ssh))
close(ssh_packet_get_connection_in(ssh));
else {
close(ssh_packet_get_connection_in(ssh));
close(ssh_packet_get_connection_out(ssh));
}
/*
* Close all descriptors related to channels. They will still remain
* open in the parent.
*/
/* XXX better use close-on-exec? -markus */
channel_close_all(ssh);
/*
* Close any extra file descriptors. Note that there may still be
* descriptors left by system functions. They will be closed later.
*/
endpwent();
/* Stop directing logs to a high-numbered fd before we close it */
log_redirect_stderr_to(NULL);
/*
* Close any extra open file descriptors so that we don't have them
* hanging around in clients. Note that we want to do this after
* initgroups, because at least on Solaris 2.3 it leaves file
* descriptors open.
*/
closefrom(STDERR_FILENO + 1);
}
/*
* Performs common processing for the child, such as setting up the
* environment, closing extra file descriptors, setting the user and group
* ids, and executing the command or shell.
*/
#define ARGV_MAX 10
void
do_child(struct ssh *ssh, Session *s, const char *command)
{
extern char **environ;
char **env, *argv[ARGV_MAX], remote_id[512];
const char *shell, *shell0;
struct passwd *pw = s->pw;
int r = 0;
sshpkt_fmt_connection_id(ssh, remote_id, sizeof(remote_id));
/* remove hostkey from the child's memory */
destroy_sensitive_data();
ssh_packet_clear_keys(ssh);
/* Force a password change */
if (s->authctxt->force_pwchange) {
do_setusercontext(pw);
child_close_fds(ssh);
do_pwchange(s);
exit(1);
}
/*
* Login(1) does this as well, and it needs uid 0 for the "-h"
* switch, so we let login(1) to this for us.
*/
#ifdef HAVE_OSF_SIA
session_setup_sia(pw, s->ttyfd == -1 ? NULL : s->tty);
if (!check_quietlogin(s, command))
do_motd();
#else /* HAVE_OSF_SIA */
/* When PAM is enabled we rely on it to do the nologin check */
if (!options.use_pam)
do_nologin(pw);
do_setusercontext(pw);
/*
* PAM session modules in do_setusercontext may have
* generated messages, so if this in an interactive
* login then display them too.
*/
if (!check_quietlogin(s, command))
display_loginmsg();
#endif /* HAVE_OSF_SIA */
#ifdef USE_PAM
if (options.use_pam && !is_pam_session_open()) {
debug3("PAM session not opened, exiting");
display_loginmsg();
exit(254);
}
#endif
/*
* Get the shell from the password data. An empty shell field is
* legal, and means /bin/sh.
*/
shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell;
/*
* Make sure $SHELL points to the shell from the password file,
* even if shell is overridden from login.conf
*/
env = do_setup_env(ssh, s, shell);
#ifdef HAVE_LOGIN_CAP
shell = login_getcapstr(lc, "shell", (char *)shell, (char *)shell);
#endif
/*
* Close the connection descriptors; note that this is the child, and
* the server will still have the socket open, and it is important
* that we do not shutdown it. Note that the descriptors cannot be
* closed before building the environment, as we call
* ssh_remote_ipaddr there.
*/
child_close_fds(ssh);
/*
* Must take new environment into use so that .ssh/rc,
* /etc/ssh/sshrc and xauth are run in the proper environment.
*/
environ = env;
#if defined(KRB5) && defined(USE_AFS)
/*
* At this point, we check to see if AFS is active and if we have
* a valid Kerberos 5 TGT. If so, it seems like a good idea to see
* if we can (and need to) extend the ticket into an AFS token. If
* we don't do this, we run into potential problems if the user's
* home directory is in AFS and it's not world-readable.
*/
if (options.kerberos_get_afs_token && k_hasafs() &&
(s->authctxt->krb5_ctx != NULL)) {
char cell[64];
debug("Getting AFS token");
k_setpag();
if (k_afs_cell_of_file(pw->pw_dir, cell, sizeof(cell)) == 0)
krb5_afslog(s->authctxt->krb5_ctx,
s->authctxt->krb5_fwd_ccache, cell, NULL);
krb5_afslog_home(s->authctxt->krb5_ctx,
s->authctxt->krb5_fwd_ccache, NULL, NULL, pw->pw_dir);
}
#endif
/* Change current directory to the user's home directory. */
if (chdir(pw->pw_dir) == -1) {
/* Suppress missing homedir warning for chroot case */
#ifdef HAVE_LOGIN_CAP
r = login_getcapbool(lc, "requirehome", 0);
#endif
if (r || !in_chroot) {
fprintf(stderr, "Could not chdir to home "
"directory %s: %s\n", pw->pw_dir,
strerror(errno));
}
if (r)
exit(1);
}
closefrom(STDERR_FILENO + 1);
do_rc_files(ssh, s, shell);
/* restore SIGPIPE for child */
ssh_signal(SIGPIPE, SIG_DFL);
if (s->is_subsystem == SUBSYSTEM_INT_SFTP_ERROR) {
error("Connection from %s: refusing non-sftp session",
remote_id);
printf("This service allows sftp connections only.\n");
fflush(NULL);
exit(1);
} else if (s->is_subsystem == SUBSYSTEM_INT_SFTP) {
extern int optind, optreset;
int i;
char *p, *args;
setproctitle("%s@%s", s->pw->pw_name, INTERNAL_SFTP_NAME);
args = xstrdup(command ? command : "sftp-server");
for (i = 0, (p = strtok(args, " ")); p; (p = strtok(NULL, " ")))
if (i < ARGV_MAX - 1)
argv[i++] = p;
argv[i] = NULL;
optind = optreset = 1;
__progname = argv[0];
#ifdef WITH_SELINUX
ssh_selinux_change_context("sftpd_t");
#endif
exit(sftp_server_main(i, argv, s->pw));
}
fflush(NULL);
/* Get the last component of the shell name. */
if ((shell0 = strrchr(shell, '/')) != NULL)
shell0++;
else
shell0 = shell;
/*
* If we have no command, execute the shell. In this case, the shell
* name to be passed in argv[0] is preceded by '-' to indicate that
* this is a login shell.
*/
if (!command) {
char argv0[256];
/* Start the shell. Set initial character to '-'. */
argv0[0] = '-';
if (strlcpy(argv0 + 1, shell0, sizeof(argv0) - 1)
>= sizeof(argv0) - 1) {
errno = EINVAL;
perror(shell);
exit(1);
}
/* Execute the shell. */
argv[0] = argv0;
argv[1] = NULL;
execve(shell, argv, env);
/* Executing the shell failed. */
perror(shell);
exit(1);
}
/*
* Execute the command using the user's shell. This uses the -c
* option to execute the command.
*/
argv[0] = (char *) shell0;
argv[1] = "-c";
argv[2] = (char *) command;
argv[3] = NULL;
execve(shell, argv, env);
perror(shell);
exit(1);
}
void
session_unused(int id)
{
debug3_f("session id %d unused", id);
if (id >= options.max_sessions ||
id >= 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;
sessions[id].used = 0;
sessions[id].chanid = -1;
sessions[id].ptyfd = -1;
sessions[id].ttyfd = -1;
sessions[id].ptymaster = -1;
sessions[id].x11_chanids = NULL;
sessions[id].next_unused = sessions_first_unused;
sessions_first_unused = id;
}
Session *
session_new(void)
{
Session *s, *tmp;
if (sessions_first_unused == -1) {
if (sessions_nalloc >= options.max_sessions)
return NULL;
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_f("cannot allocate %d sessions",
sessions_nalloc + 1);
return NULL;
}
sessions = tmp;
session_unused(sessions_nalloc++);
}
if (sessions_first_unused >= sessions_nalloc ||
sessions_first_unused < 0) {
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_f("session %d already used", sessions_first_unused);
sessions_first_unused = s->next_unused;
s->used = 1;
s->next_unused = -1;
debug("session_new: session %d", s->self);
return s;
}
static void
session_dump(void)
{
int i;
for (i = 0; i < sessions_nalloc; i++) {
Session *s = &sessions[i];
debug("dump: used %d next_unused %d session %d "
"channel %d pid %ld",
s->used,
s->next_unused,
s->self,
s->chanid,
(long)s->pid);
}
}
int
session_open(Authctxt *authctxt, int chanid)
{
Session *s = session_new();
debug("session_open: channel %d", chanid);
if (s == NULL) {
error("no more sessions");
return 0;
}
s->authctxt = authctxt;
s->pw = authctxt->pw;
if (s->pw == NULL || !authctxt->valid)
fatal("no user for session %d", s->self);
debug("session_open: session %d: link with channel %d", s->self, chanid);
s->chanid = chanid;
return 1;
}
Session *
session_by_tty(char *tty)
{
int i;
for (i = 0; i < sessions_nalloc; i++) {
Session *s = &sessions[i];
if (s->used && s->ttyfd != -1 && strcmp(s->tty, tty) == 0) {
debug("session_by_tty: session %d tty %s", i, tty);
return s;
}
}
debug("session_by_tty: unknown tty %.100s", tty);
session_dump();
return NULL;
}
static Session *
session_by_channel(int id)
{
int i;
for (i = 0; i < sessions_nalloc; i++) {
Session *s = &sessions[i];
if (s->used && s->chanid == id) {
debug("session_by_channel: session %d channel %d",
i, id);
return s;
}
}
debug("session_by_channel: unknown channel %d", id);
session_dump();
return NULL;
}
static Session *
session_by_x11_channel(int id)
{
int i, j;
for (i = 0; i < sessions_nalloc; i++) {
Session *s = &sessions[i];
if (s->x11_chanids == NULL || !s->used)
continue;
for (j = 0; s->x11_chanids[j] != -1; j++) {
if (s->x11_chanids[j] == id) {
debug("session_by_x11_channel: session %d "
"channel %d", s->self, id);
return s;
}
}
}
debug("session_by_x11_channel: unknown channel %d", id);
session_dump();
return NULL;
}
static Session *
session_by_pid(pid_t pid)
{
int i;
debug("session_by_pid: pid %ld", (long)pid);
for (i = 0; i < sessions_nalloc; i++) {
Session *s = &sessions[i];
if (s->used && s->pid == pid)
return s;
}
error("session_by_pid: unknown pid %ld", (long)pid);
session_dump();
return NULL;
}
static int
session_window_change_req(struct ssh *ssh, Session *s)
{
int r;
if ((r = sshpkt_get_u32(ssh, &s->col)) != 0 ||
(r = sshpkt_get_u32(ssh, &s->row)) != 0 ||
(r = sshpkt_get_u32(ssh, &s->xpixel)) != 0 ||
(r = sshpkt_get_u32(ssh, &s->ypixel)) != 0 ||
(r = sshpkt_get_end(ssh)) != 0)
sshpkt_fatal(ssh, r, "%s: parse packet", __func__);
pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel);
return 1;
}
static int
session_pty_req(struct ssh *ssh, Session *s)
{
int r;
if (!auth_opts->permit_pty_flag || !options.permit_tty) {
debug("Allocating a pty not permitted for this connection.");
return 0;
}
if (s->ttyfd != -1) {
ssh_packet_disconnect(ssh, "Protocol error: you already have a pty.");
return 0;
}
if ((r = sshpkt_get_cstring(ssh, &s->term, NULL)) != 0 ||
(r = sshpkt_get_u32(ssh, &s->col)) != 0 ||
(r = sshpkt_get_u32(ssh, &s->row)) != 0 ||
(r = sshpkt_get_u32(ssh, &s->xpixel)) != 0 ||
(r = sshpkt_get_u32(ssh, &s->ypixel)) != 0)
sshpkt_fatal(ssh, r, "%s: parse packet", __func__);
if (strcmp(s->term, "") == 0) {
free(s->term);
s->term = NULL;
}
/* Allocate a pty and open it. */
debug("Allocating pty.");
if (!PRIVSEP(pty_allocate(&s->ptyfd, &s->ttyfd, s->tty,
sizeof(s->tty)))) {
free(s->term);
s->term = NULL;
s->ptyfd = -1;
s->ttyfd = -1;
error("session_pty_req: session %d alloc failed", s->self);
return 0;
}
debug("session_pty_req: session %d alloc %s", s->self, s->tty);
ssh_tty_parse_modes(ssh, s->ttyfd);
if ((r = sshpkt_get_end(ssh)) != 0)
sshpkt_fatal(ssh, r, "%s: parse packet", __func__);
if (!use_privsep)
pty_setowner(s->pw, s->tty);
/* Set window size from the packet. */
pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel);
session_proctitle(s);
return 1;
}
static int
session_subsystem_req(struct ssh *ssh, Session *s)
{
struct stat st;
int r, success = 0;
- char *prog, *cmd;
+ char *prog, *cmd, *type;
u_int i;
if ((r = sshpkt_get_cstring(ssh, &s->subsys, NULL)) != 0 ||
(r = sshpkt_get_end(ssh)) != 0)
sshpkt_fatal(ssh, r, "%s: parse packet", __func__);
debug2("subsystem request for %.100s by user %s", s->subsys,
s->pw->pw_name);
for (i = 0; i < options.num_subsystems; i++) {
if (strcmp(s->subsys, options.subsystem_name[i]) == 0) {
prog = options.subsystem_command[i];
cmd = options.subsystem_args[i];
if (strcmp(INTERNAL_SFTP_NAME, prog) == 0) {
s->is_subsystem = SUBSYSTEM_INT_SFTP;
debug("subsystem: %s", prog);
} else {
if (stat(prog, &st) == -1)
debug("subsystem: cannot stat %s: %s",
prog, strerror(errno));
s->is_subsystem = SUBSYSTEM_EXT;
debug("subsystem: exec() %s", cmd);
}
+ xasprintf(&type, "session:subsystem:%s",
+ options.subsystem_name[i]);
+ channel_set_xtype(ssh, s->chanid, type);
+ free(type);
success = do_exec(ssh, s, cmd) == 0;
break;
}
}
if (!success)
logit("subsystem request for %.100s by user %s failed, "
"subsystem not found", s->subsys, s->pw->pw_name);
return success;
}
static int
session_x11_req(struct ssh *ssh, Session *s)
{
int r, success;
u_char single_connection = 0;
if (s->auth_proto != NULL || s->auth_data != NULL) {
error("session_x11_req: session %d: "
"x11 forwarding already active", s->self);
return 0;
}
if ((r = sshpkt_get_u8(ssh, &single_connection)) != 0 ||
(r = sshpkt_get_cstring(ssh, &s->auth_proto, NULL)) != 0 ||
(r = sshpkt_get_cstring(ssh, &s->auth_data, NULL)) != 0 ||
(r = sshpkt_get_u32(ssh, &s->screen)) != 0 ||
(r = sshpkt_get_end(ssh)) != 0)
sshpkt_fatal(ssh, r, "%s: parse packet", __func__);
s->single_connection = single_connection;
if (xauth_valid_string(s->auth_proto) &&
xauth_valid_string(s->auth_data))
success = session_setup_x11fwd(ssh, s);
else {
success = 0;
error("Invalid X11 forwarding data");
}
if (!success) {
free(s->auth_proto);
free(s->auth_data);
s->auth_proto = NULL;
s->auth_data = NULL;
}
return success;
}
static int
session_shell_req(struct ssh *ssh, Session *s)
{
int r;
if ((r = sshpkt_get_end(ssh)) != 0)
sshpkt_fatal(ssh, r, "%s: parse packet", __func__);
+
+ channel_set_xtype(ssh, s->chanid, "session:shell");
+
return do_exec(ssh, s, NULL) == 0;
}
static int
session_exec_req(struct ssh *ssh, Session *s)
{
u_int success;
int r;
char *command = NULL;
if ((r = sshpkt_get_cstring(ssh, &command, NULL)) != 0 ||
(r = sshpkt_get_end(ssh)) != 0)
sshpkt_fatal(ssh, r, "%s: parse packet", __func__);
+ channel_set_xtype(ssh, s->chanid, "session:command");
+
success = do_exec(ssh, s, command) == 0;
free(command);
return success;
}
static int
session_break_req(struct ssh *ssh, Session *s)
{
int r;
if ((r = sshpkt_get_u32(ssh, NULL)) != 0 || /* ignore */
(r = sshpkt_get_end(ssh)) != 0)
sshpkt_fatal(ssh, r, "%s: parse packet", __func__);
if (s->ptymaster == -1 || tcsendbreak(s->ptymaster, 0) == -1)
return 0;
return 1;
}
static int
session_env_req(struct ssh *ssh, Session *s)
{
char *name, *val;
u_int i;
int r;
if ((r = sshpkt_get_cstring(ssh, &name, NULL)) != 0 ||
(r = sshpkt_get_cstring(ssh, &val, NULL)) != 0 ||
(r = sshpkt_get_end(ssh)) != 0)
sshpkt_fatal(ssh, r, "%s: parse packet", __func__);
/* Don't set too many environment variables */
if (s->num_env > 128) {
debug2("Ignoring env request %s: too many env vars", name);
goto fail;
}
for (i = 0; i < options.num_accept_env; i++) {
if (match_pattern(name, options.accept_env[i])) {
debug2("Setting env %d: %s=%s", s->num_env, name, val);
s->env = xrecallocarray(s->env, s->num_env,
s->num_env + 1, sizeof(*s->env));
s->env[s->num_env].name = name;
s->env[s->num_env].val = val;
s->num_env++;
return (1);
}
}
debug2("Ignoring env request %s: disallowed name", name);
fail:
free(name);
free(val);
return (0);
}
/*
* Conversion of signals from ssh channel request names.
* Subset of signals from RFC 4254 section 6.10C, with SIGINFO as
* local extension.
*/
static int
name2sig(char *name)
{
#define SSH_SIG(x) if (strcmp(name, #x) == 0) return SIG ## x
SSH_SIG(HUP);
SSH_SIG(INT);
SSH_SIG(KILL);
SSH_SIG(QUIT);
SSH_SIG(TERM);
SSH_SIG(USR1);
SSH_SIG(USR2);
#undef SSH_SIG
#ifdef SIGINFO
if (strcmp(name, "INFO@openssh.com") == 0)
return SIGINFO;
#endif
return -1;
}
static int
session_signal_req(struct ssh *ssh, Session *s)
{
char *signame = NULL;
int r, sig, success = 0;
if ((r = sshpkt_get_cstring(ssh, &signame, NULL)) != 0 ||
(r = sshpkt_get_end(ssh)) != 0) {
error_fr(r, "parse");
goto out;
}
if ((sig = name2sig(signame)) == -1) {
error_f("unsupported signal \"%s\"", signame);
goto out;
}
if (s->pid <= 0) {
error_f("no pid for session %d", s->self);
goto out;
}
if (s->forced || s->is_subsystem) {
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_f("session signalling requires privilege separation");
goto out;
}
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_f("killpg(%ld, %d): %s", (long)s->pid,
sig, strerror(errno));
goto out;
}
/* success */
success = 1;
out:
free(signame);
return success;
}
static int
session_auth_agent_req(struct ssh *ssh, Session *s)
{
static int called = 0;
int r;
if ((r = sshpkt_get_end(ssh)) != 0)
sshpkt_fatal(ssh, r, "%s: parse packet", __func__);
if (!auth_opts->permit_agent_forwarding_flag ||
!options.allow_agent_forwarding) {
debug_f("agent forwarding disabled");
return 0;
}
if (called) {
return 0;
} else {
called = 1;
return auth_input_request_forwarding(ssh, s->pw);
}
}
int
session_input_channel_req(struct ssh *ssh, Channel *c, const char *rtype)
{
int success = 0;
Session *s;
if ((s = session_by_channel(c->self)) == NULL) {
logit_f("no session %d req %.100s", c->self, rtype);
return 0;
}
debug_f("session %d req %s", s->self, rtype);
/*
* a session is in LARVAL state until a shell, a command
* or a subsystem is executed
*/
if (c->type == SSH_CHANNEL_LARVAL) {
if (strcmp(rtype, "shell") == 0) {
success = session_shell_req(ssh, s);
} else if (strcmp(rtype, "exec") == 0) {
success = session_exec_req(ssh, s);
} else if (strcmp(rtype, "pty-req") == 0) {
success = session_pty_req(ssh, s);
} else if (strcmp(rtype, "x11-req") == 0) {
success = session_x11_req(ssh, s);
} else if (strcmp(rtype, "auth-agent-req@openssh.com") == 0) {
success = session_auth_agent_req(ssh, s);
} else if (strcmp(rtype, "subsystem") == 0) {
success = session_subsystem_req(ssh, s);
} else if (strcmp(rtype, "env") == 0) {
success = session_env_req(ssh, s);
}
}
if (strcmp(rtype, "window-change") == 0) {
success = session_window_change_req(ssh, s);
} else if (strcmp(rtype, "break") == 0) {
success = session_break_req(ssh, s);
} else if (strcmp(rtype, "signal") == 0) {
success = session_signal_req(ssh, s);
}
return success;
}
void
session_set_fds(struct ssh *ssh, Session *s,
int fdin, int fdout, int fderr, int ignore_fderr, int is_tty)
{
/*
* now that have a child and a pipe to the child,
* we can activate our channel and register the fd's
*/
if (s->chanid == -1)
fatal("no channel for session %d", s->self);
channel_set_fds(ssh, s->chanid,
fdout, fdin, fderr,
ignore_fderr ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ,
1, is_tty, CHAN_SES_WINDOW_DEFAULT);
}
/*
* Function to perform pty cleanup. Also called if we get aborted abnormally
* (e.g., due to a dropped connection).
*/
void
session_pty_cleanup2(Session *s)
{
if (s == NULL) {
error_f("no session");
return;
}
if (s->ttyfd == -1)
return;
debug_f("session %d release %s", s->self, s->tty);
/* Record that the user has logged out. */
if (s->pid != 0)
record_logout(s->pid, s->tty, s->pw->pw_name);
/* Release the pseudo-tty. */
if (getuid() == 0)
pty_release(s->tty);
/*
* Close the server side of the socket pairs. We must do this after
* the pty cleanup, so that another process doesn't get this pty
* while we're still cleaning up.
*/
if (s->ptymaster != -1 && close(s->ptymaster) == -1)
error("close(s->ptymaster/%d): %s",
s->ptymaster, strerror(errno));
/* unlink pty from session */
s->ttyfd = -1;
}
void
session_pty_cleanup(Session *s)
{
PRIVSEP(session_pty_cleanup2(s));
}
static char *
sig2name(int sig)
{
#define SSH_SIG(x) if (sig == SIG ## x) return #x
SSH_SIG(ABRT);
SSH_SIG(ALRM);
SSH_SIG(FPE);
SSH_SIG(HUP);
SSH_SIG(ILL);
SSH_SIG(INT);
SSH_SIG(KILL);
SSH_SIG(PIPE);
SSH_SIG(QUIT);
SSH_SIG(SEGV);
SSH_SIG(TERM);
SSH_SIG(USR1);
SSH_SIG(USR2);
#undef SSH_SIG
return "SIG@openssh.com";
}
static void
session_close_x11(struct ssh *ssh, int id)
{
Channel *c;
if ((c = channel_by_id(ssh, id)) == NULL) {
debug_f("x11 channel %d missing", id);
} else {
/* Detach X11 listener */
debug_f("detach x11 channel %d", id);
channel_cancel_cleanup(ssh, id);
if (c->ostate != CHAN_OUTPUT_CLOSED)
chan_mark_dead(ssh, c);
}
}
static void
-session_close_single_x11(struct ssh *ssh, int id, void *arg)
+session_close_single_x11(struct ssh *ssh, int id, int force, void *arg)
{
Session *s;
u_int i;
debug3_f("channel %d", id);
channel_cancel_cleanup(ssh, id);
if ((s = session_by_x11_channel(id)) == NULL)
fatal_f("no x11 channel %d", id);
for (i = 0; s->x11_chanids[i] != -1; 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.
*/
if (s->x11_chanids[i] != id)
session_close_x11(ssh, s->x11_chanids[i]);
}
free(s->x11_chanids);
s->x11_chanids = NULL;
free(s->display);
s->display = NULL;
free(s->auth_proto);
s->auth_proto = NULL;
free(s->auth_data);
s->auth_data = NULL;
free(s->auth_display);
s->auth_display = NULL;
}
static void
session_exit_message(struct ssh *ssh, Session *s, int status)
{
Channel *c;
int r;
if ((c = channel_lookup(ssh, s->chanid)) == NULL)
fatal_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);
if ((r = sshpkt_put_u32(ssh, WEXITSTATUS(status))) != 0 ||
(r = sshpkt_send(ssh)) != 0)
sshpkt_fatal(ssh, r, "%s: exit reply", __func__);
} else if (WIFSIGNALED(status)) {
channel_request_start(ssh, s->chanid, "exit-signal", 0);
#ifndef WCOREDUMP
# define WCOREDUMP(x) (0)
#endif
if ((r = sshpkt_put_cstring(ssh, sig2name(WTERMSIG(status)))) != 0 ||
(r = sshpkt_put_u8(ssh, WCOREDUMP(status)? 1 : 0)) != 0 ||
(r = sshpkt_put_cstring(ssh, "")) != 0 ||
(r = sshpkt_put_cstring(ssh, "")) != 0 ||
(r = sshpkt_send(ssh)) != 0)
sshpkt_fatal(ssh, r, "%s: exit reply", __func__);
} else {
/* Some weird exit cause. Just exit. */
ssh_packet_disconnect(ssh, "wait returned status %04x.", status);
}
/* disconnect channel */
debug_f("release channel %d", s->chanid);
/*
* Adjust cleanup callback attachment to send close messages when
* the channel gets EOF. The session will be then be closed
* by session_close_by_channel when the child sessions close their fds.
*/
channel_register_cleanup(ssh, c->self, session_close_by_channel, 1);
/*
* emulate a write failure with 'chan_write_failed', nobody will be
* interested in data we write.
* Note that we must not call 'chan_read_failed', since there could
* be some more data waiting in the pipe.
*/
if (c->ostate != CHAN_OUTPUT_CLOSED)
chan_write_failed(ssh, c);
}
void
session_close(struct ssh *ssh, Session *s)
{
u_int i;
verbose("Close session: user %s from %.200s port %d id %d",
s->pw->pw_name,
ssh_remote_ipaddr(ssh),
ssh_remote_port(ssh),
s->self);
if (s->ttyfd != -1)
session_pty_cleanup(s);
free(s->term);
free(s->display);
free(s->x11_chanids);
free(s->auth_display);
free(s->auth_data);
free(s->auth_proto);
free(s->subsys);
if (s->env != NULL) {
for (i = 0; i < s->num_env; i++) {
free(s->env[i].name);
free(s->env[i].val);
}
free(s->env);
}
session_proctitle(s);
session_unused(s->self);
}
void
session_close_by_pid(struct ssh *ssh, pid_t pid, int status)
{
Session *s = session_by_pid(pid);
if (s == NULL) {
debug_f("no session for pid %ld", (long)pid);
return;
}
if (s->chanid != -1)
session_exit_message(ssh, s, status);
if (s->ttyfd != -1)
session_pty_cleanup(s);
s->pid = 0;
}
/*
* this is called when a channel dies before
* the session 'child' itself dies
*/
void
-session_close_by_channel(struct ssh *ssh, int id, void *arg)
+session_close_by_channel(struct ssh *ssh, int id, int force, void *arg)
{
Session *s = session_by_channel(id);
u_int i;
if (s == NULL) {
debug_f("no session for id %d", id);
return;
}
debug_f("channel %d child %ld", id, (long)s->pid);
if (s->pid != 0) {
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
+ * delay detach of session (unless this is a forced close),
+ * but release pty, since the fd's to the child are already
+ * closed
*/
if (s->ttyfd != -1)
session_pty_cleanup(s);
- return;
+ if (!force)
+ return;
}
/* detach by removing callback */
channel_cancel_cleanup(ssh, s->chanid);
/* Close any X11 listeners associated with this session */
if (s->x11_chanids != NULL) {
for (i = 0; s->x11_chanids[i] != -1; i++) {
session_close_x11(ssh, s->x11_chanids[i]);
s->x11_chanids[i] = -1;
}
}
s->chanid = -1;
session_close(ssh, s);
}
void
session_destroy_all(struct ssh *ssh, void (*closefunc)(Session *))
{
int i;
for (i = 0; i < sessions_nalloc; i++) {
Session *s = &sessions[i];
if (s->used) {
if (closefunc != NULL)
closefunc(s);
else
session_close(ssh, s);
}
}
}
static char *
session_tty_list(void)
{
static char buf[1024];
int i;
char *cp;
buf[0] = '\0';
for (i = 0; i < sessions_nalloc; i++) {
Session *s = &sessions[i];
if (s->used && s->ttyfd != -1) {
if (strncmp(s->tty, "/dev/", 5) != 0) {
cp = strrchr(s->tty, '/');
cp = (cp == NULL) ? s->tty : cp + 1;
} else
cp = s->tty + 5;
if (buf[0] != '\0')
strlcat(buf, ",", sizeof buf);
strlcat(buf, cp, sizeof buf);
}
}
if (buf[0] == '\0')
strlcpy(buf, "notty", sizeof buf);
return buf;
}
void
session_proctitle(Session *s)
{
if (s->pw == NULL)
error("no user for session %d", s->self);
else
setproctitle("%s@%s", s->pw->pw_name, session_tty_list());
}
int
session_setup_x11fwd(struct ssh *ssh, Session *s)
{
struct stat st;
char display[512], auth_display[512];
char hostname[NI_MAXHOST];
u_int i;
if (!auth_opts->permit_x11_forwarding_flag) {
ssh_packet_send_debug(ssh, "X11 forwarding disabled by key options.");
return 0;
}
if (!options.x11_forwarding) {
debug("X11 forwarding disabled in server configuration file.");
return 0;
}
if (options.xauth_location == NULL ||
(stat(options.xauth_location, &st) == -1)) {
ssh_packet_send_debug(ssh, "No xauth program; cannot forward X11.");
return 0;
}
if (s->display != NULL) {
debug("X11 display already set.");
return 0;
}
if (x11_create_display_inet(ssh, options.x11_display_offset,
options.x11_use_localhost, s->single_connection,
&s->display_number, &s->x11_chanids) == -1) {
debug("x11_create_display_inet failed.");
return 0;
}
for (i = 0; s->x11_chanids[i] != -1; i++) {
channel_register_cleanup(ssh, s->x11_chanids[i],
session_close_single_x11, 0);
}
/* Set up a suitable value for the DISPLAY variable. */
if (gethostname(hostname, sizeof(hostname)) == -1)
fatal("gethostname: %.100s", strerror(errno));
/*
* auth_display must be used as the displayname when the
* authorization entry is added with xauth(1). This will be
* different than the DISPLAY string for localhost displays.
*/
if (options.x11_use_localhost) {
snprintf(display, sizeof display, "localhost:%u.%u",
s->display_number, s->screen);
snprintf(auth_display, sizeof auth_display, "unix:%u.%u",
s->display_number, s->screen);
s->display = xstrdup(display);
s->auth_display = xstrdup(auth_display);
} else {
#ifdef IPADDR_IN_DISPLAY
struct hostent *he;
struct in_addr my_addr;
he = gethostbyname(hostname);
if (he == NULL) {
error("Can't get IP address for X11 DISPLAY.");
ssh_packet_send_debug(ssh, "Can't get IP address for X11 DISPLAY.");
return 0;
}
memcpy(&my_addr, he->h_addr_list[0], sizeof(struct in_addr));
snprintf(display, sizeof display, "%.50s:%u.%u", inet_ntoa(my_addr),
s->display_number, s->screen);
#else
snprintf(display, sizeof display, "%.400s:%u.%u", hostname,
s->display_number, s->screen);
#endif
s->display = xstrdup(display);
s->auth_display = xstrdup(display);
}
return 1;
}
static void
do_authenticated2(struct ssh *ssh, Authctxt *authctxt)
{
server_loop2(ssh, authctxt);
}
void
do_cleanup(struct ssh *ssh, Authctxt *authctxt)
{
static int called = 0;
debug("do_cleanup");
/* no cleanup if we're in the child for login shell */
if (is_child)
return;
/* avoid double cleanup */
if (called)
return;
called = 1;
if (authctxt == NULL)
return;
#ifdef USE_PAM
if (options.use_pam) {
sshpam_cleanup();
sshpam_thread_cleanup();
}
#endif
if (!authctxt->authenticated)
return;
#ifdef KRB5
if (options.kerberos_ticket_cleanup &&
authctxt->krb5_ctx)
krb5_cleanup_proc(authctxt);
#endif
#ifdef GSSAPI
if (options.gss_cleanup_creds)
ssh_gssapi_cleanup_creds();
#endif
/* remove agent socket */
auth_sock_cleanup_proc(authctxt->pw);
/* remove userauth info */
if (auth_info_file != NULL) {
temporarily_use_uid(authctxt->pw);
unlink(auth_info_file);
restore_uid();
free(auth_info_file);
auth_info_file = NULL;
}
/*
* Cleanup ptys/utmp only if privsep is disabled,
* or if running in monitor.
*/
if (!use_privsep || mm_is_monitor())
session_destroy_all(ssh, session_pty_cleanup2);
}
/* Return a name for the remote host that fits inside utmp_size */
const char *
session_get_remote_name_or_ip(struct ssh *ssh, u_int utmp_size, int use_dns)
{
const char *remote = "";
if (utmp_size > 0)
remote = auth_get_canonical_hostname(ssh, use_dns);
if (utmp_size == 0 || strlen(remote) > utmp_size)
remote = ssh_remote_ipaddr(ssh);
return remote;
}
diff --git a/crypto/openssh/session.h b/crypto/openssh/session.h
index ce59dabd906d..344a1ddf9d54 100644
--- a/crypto/openssh/session.h
+++ b/crypto/openssh/session.h
@@ -1,84 +1,84 @@
-/* $OpenBSD: session.h,v 1.36 2018/10/02 12:40:07 djm Exp $ */
+/* $OpenBSD: session.h,v 1.37 2023/01/06 02:39:59 djm Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SESSION_H
#define SESSION_H
#define TTYSZ 64
typedef struct Session Session;
struct Session {
int used;
int self;
int next_unused;
struct passwd *pw;
Authctxt *authctxt;
pid_t pid;
int forced;
/* tty */
char *term;
int ptyfd, ttyfd, ptymaster;
u_int row, col, xpixel, ypixel;
char tty[TTYSZ];
/* X11 */
u_int display_number;
char *display;
u_int screen;
char *auth_display;
char *auth_proto;
char *auth_data;
int single_connection;
int chanid;
int *x11_chanids;
int is_subsystem;
char *subsys;
u_int num_env;
struct {
char *name;
char *val;
} *env;
};
void do_authenticated(struct ssh *, Authctxt *);
void do_cleanup(struct ssh *, Authctxt *);
int session_open(Authctxt *, int);
void session_unused(int);
int session_input_channel_req(struct ssh *, Channel *, const char *);
void session_close_by_pid(struct ssh *ssh, pid_t, int);
-void session_close_by_channel(struct ssh *, int, void *);
+void session_close_by_channel(struct ssh *, int, int, void *);
void session_destroy_all(struct ssh *, void (*)(Session *));
void session_pty_cleanup2(Session *);
Session *session_new(void);
Session *session_by_tty(char *);
void session_close(struct ssh *, Session *);
void do_setusercontext(struct passwd *);
const char *session_get_remote_name_or_ip(struct ssh *, u_int, int);
#endif
diff --git a/crypto/openssh/sftp-client.c b/crypto/openssh/sftp-client.c
index 35be53d697b6..e01464818064 100644
--- a/crypto/openssh/sftp-client.c
+++ b/crypto/openssh/sftp-client.c
@@ -1,2938 +1,2947 @@
-/* $OpenBSD: sftp-client.c,v 1.165 2022/09/19 10:43:12 djm Exp $ */
+/* $OpenBSD: sftp-client.c,v 1.168 2023/01/11 05:39:38 djm Exp $ */
/*
* Copyright (c) 2001-2004 Damien Miller <djm@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.
*/
/* XXX: memleaks */
/* XXX: signed vs unsigned */
/* XXX: remove all logging, only return status codes */
/* XXX: copy between two remote sites */
#include "includes.h"
#include <sys/types.h>
#ifdef HAVE_SYS_STATVFS_H
#include <sys/statvfs.h>
#endif
#include "openbsd-compat/sys-queue.h"
#ifdef HAVE_SYS_STAT_H
# include <sys/stat.h>
#endif
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
#endif
#include <sys/uio.h>
#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>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "xmalloc.h"
#include "ssherr.h"
#include "sshbuf.h"
#include "log.h"
#include "atomicio.h"
#include "progressmeter.h"
#include "misc.h"
#include "utf8.h"
#include "sftp.h"
#include "sftp-common.h"
#include "sftp-client.h"
extern volatile sig_atomic_t interrupted;
extern int showprogress;
-/* Default size of buffer for up/download */
+/* Default size of buffer for up/download (fix sftp.1 scp.1 if changed) */
#define DEFAULT_COPY_BUFLEN 32768
-/* Default number of concurrent outstanding requests */
+/* Default number of concurrent xfer requests (fix sftp.1 scp.1 if changed) */
#define DEFAULT_NUM_REQUESTS 64
/* Minimum amount of data to read at a time */
#define MIN_READ_SIZE 512
/* Maximum depth to descend in directory trees */
#define MAX_DIR_DEPTH 64
/* Directory separator characters */
#ifdef HAVE_CYGWIN
# define SFTP_DIRECTORY_CHARS "/\\"
#else /* HAVE_CYGWIN */
# define SFTP_DIRECTORY_CHARS "/"
#endif /* HAVE_CYGWIN */
struct sftp_conn {
int fd_in;
int fd_out;
u_int download_buflen;
u_int upload_buflen;
u_int num_requests;
u_int version;
u_int msg_id;
#define SFTP_EXT_POSIX_RENAME 0x00000001
#define SFTP_EXT_STATVFS 0x00000002
#define SFTP_EXT_FSTATVFS 0x00000004
#define SFTP_EXT_HARDLINK 0x00000008
#define SFTP_EXT_FSYNC 0x00000010
#define SFTP_EXT_LSETSTAT 0x00000020
#define SFTP_EXT_LIMITS 0x00000040
#define SFTP_EXT_PATH_EXPAND 0x00000080
#define SFTP_EXT_COPY_DATA 0x00000100
#define SFTP_EXT_GETUSERSGROUPS_BY_ID 0x00000200
u_int exts;
u_int64_t limit_kbps;
struct bwlimit bwlimit_in, bwlimit_out;
};
/* Tracks in-progress requests during file transfers */
struct request {
u_int id;
size_t len;
u_int64_t offset;
TAILQ_ENTRY(request) tq;
};
TAILQ_HEAD(requests, request);
static u_char *
get_handle(struct sftp_conn *conn, u_int expected_id, size_t *len,
const char *errfmt, ...) __attribute__((format(printf, 4, 5)));
static struct request *
request_enqueue(struct requests *requests, u_int id, size_t len,
uint64_t offset)
{
struct request *req;
req = xcalloc(1, sizeof(*req));
req->id = id;
req->len = len;
req->offset = offset;
TAILQ_INSERT_TAIL(requests, req, tq);
return req;
}
static struct request *
request_find(struct requests *requests, u_int id)
{
struct request *req;
for (req = TAILQ_FIRST(requests);
req != NULL && req->id != id;
req = TAILQ_NEXT(req, tq))
;
return req;
}
/* ARGSUSED */
static int
sftpio(void *_bwlimit, size_t amount)
{
struct bwlimit *bwlimit = (struct bwlimit *)_bwlimit;
refresh_progress_meter(0);
if (bwlimit != NULL)
bandwidth_limit(bwlimit, amount);
return 0;
}
static void
send_msg(struct sftp_conn *conn, struct sshbuf *m)
{
u_char mlen[4];
struct iovec iov[2];
if (sshbuf_len(m) > SFTP_MAX_MSG_LENGTH)
fatal("Outbound message too long %zu", sshbuf_len(m));
/* Send length first */
put_u32(mlen, sshbuf_len(m));
iov[0].iov_base = mlen;
iov[0].iov_len = sizeof(mlen);
iov[1].iov_base = (u_char *)sshbuf_ptr(m);
iov[1].iov_len = sshbuf_len(m);
if (atomiciov6(writev, conn->fd_out, iov, 2, sftpio,
conn->limit_kbps > 0 ? &conn->bwlimit_out : NULL) !=
sshbuf_len(m) + sizeof(mlen))
fatal("Couldn't send packet: %s", strerror(errno));
sshbuf_reset(m);
}
static void
get_msg_extended(struct sftp_conn *conn, struct sshbuf *m, int initial)
{
u_int msg_len;
u_char *p;
int r;
sshbuf_reset(m);
if ((r = sshbuf_reserve(m, 4, &p)) != 0)
fatal_fr(r, "reserve");
if (atomicio6(read, conn->fd_in, p, 4, sftpio,
conn->limit_kbps > 0 ? &conn->bwlimit_in : NULL) != 4) {
if (errno == EPIPE || errno == ECONNRESET)
fatal("Connection closed");
else
fatal("Couldn't read packet: %s", strerror(errno));
}
if ((r = sshbuf_get_u32(m, &msg_len)) != 0)
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);
fatal("Ensure the remote shell produces no output "
"for non-interactive sessions.");
}
if ((r = sshbuf_reserve(m, msg_len, &p)) != 0)
fatal_fr(r, "reserve");
if (atomicio6(read, conn->fd_in, p, msg_len, sftpio,
conn->limit_kbps > 0 ? &conn->bwlimit_in : NULL)
!= msg_len) {
if (errno == EPIPE)
fatal("Connection closed");
else
fatal("Read packet: %s", strerror(errno));
}
}
static void
get_msg(struct sftp_conn *conn, struct sshbuf *m)
{
get_msg_extended(conn, m, 0);
}
static void
send_string_request(struct sftp_conn *conn, u_int id, u_int code, const char *s,
u_int len)
{
struct sshbuf *msg;
int r;
if ((msg = sshbuf_new()) == NULL)
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_fr(r, "compose");
send_msg(conn, msg);
debug3("Sent message fd %d T:%u I:%u", conn->fd_out, code, id);
sshbuf_free(msg);
}
static void
send_string_attrs_request(struct sftp_conn *conn, u_int id, u_int code,
const void *s, u_int len, Attrib *a)
{
struct sshbuf *msg;
int r;
if ((msg = sshbuf_new()) == NULL)
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_fr(r, "compose");
send_msg(conn, msg);
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);
}
static u_int
get_status(struct sftp_conn *conn, u_int expected_id)
{
struct sshbuf *msg;
u_char type;
u_int id, status;
int r;
if ((msg = sshbuf_new()) == NULL)
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_fr(r, "compose");
if (id != expected_id)
fatal("ID mismatch (%u != %u)", id, expected_id);
if (type != SSH2_FXP_STATUS)
fatal("Expected SSH2_FXP_STATUS(%u) packet, got %u",
SSH2_FXP_STATUS, type);
if ((r = sshbuf_get_u32(msg, &status)) != 0)
fatal_fr(r, "parse");
sshbuf_free(msg);
debug3("SSH2_FXP_STATUS %u", status);
return status;
}
static u_char *
get_handle(struct sftp_conn *conn, u_int expected_id, size_t *len,
const char *errfmt, ...)
{
struct sshbuf *msg;
u_int id, status;
u_char type;
u_char *handle;
char errmsg[256];
va_list args;
int r;
va_start(args, errfmt);
if (errfmt != NULL)
vsnprintf(errmsg, sizeof(errmsg), errfmt, args);
va_end(args);
if ((msg = sshbuf_new()) == NULL)
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_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_fr(r, "parse status");
if (errfmt != NULL)
error("%s: %s", errmsg, fx2txt(status));
sshbuf_free(msg);
return(NULL);
} else if (type != SSH2_FXP_HANDLE)
fatal("%s: Expected SSH2_FXP_HANDLE(%u) packet, got %u",
errfmt == NULL ? __func__ : errmsg, SSH2_FXP_HANDLE, type);
if ((r = sshbuf_get_string(msg, &handle, len)) != 0)
fatal_fr(r, "parse handle");
sshbuf_free(msg);
return handle;
}
/* XXX returning &static is error-prone. Refactor to fill *Attrib argument */
static Attrib *
get_decode_stat(struct sftp_conn *conn, u_int expected_id, int quiet)
{
struct sshbuf *msg;
u_int id;
u_char type;
int r;
static Attrib a;
if ((msg = sshbuf_new()) == NULL)
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_fr(r, "parse");
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_fr(r, "parse status");
if (quiet)
debug("stat remote: %s", fx2txt(status));
else
error("stat remote: %s", fx2txt(status));
sshbuf_free(msg);
return(NULL);
} else if (type != SSH2_FXP_ATTRS) {
fatal("Expected SSH2_FXP_ATTRS(%u) packet, got %u",
SSH2_FXP_ATTRS, type);
}
if ((r = decode_attrib(msg, &a)) != 0) {
error_fr(r, "decode_attrib");
sshbuf_free(msg);
return NULL;
}
debug3("Received stat reply T:%u I:%u F:0x%04x M:%05o",
type, id, a.flags, a.perm);
sshbuf_free(msg);
return &a;
}
static int
get_decode_statvfs(struct sftp_conn *conn, struct sftp_statvfs *st,
u_int expected_id, int quiet)
{
struct sshbuf *msg;
u_char type;
u_int id;
u_int64_t flag;
int r;
if ((msg = sshbuf_new()) == NULL)
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_fr(r, "parse");
debug3("Received statvfs 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_fr(r, "parse status");
if (quiet)
debug("remote statvfs: %s", fx2txt(status));
else
error("remote statvfs: %s", fx2txt(status));
sshbuf_free(msg);
return -1;
} else if (type != SSH2_FXP_EXTENDED_REPLY) {
fatal("Expected SSH2_FXP_EXTENDED_REPLY(%u) packet, got %u",
SSH2_FXP_EXTENDED_REPLY, type);
}
memset(st, 0, sizeof(*st));
if ((r = sshbuf_get_u64(msg, &st->f_bsize)) != 0 ||
(r = sshbuf_get_u64(msg, &st->f_frsize)) != 0 ||
(r = sshbuf_get_u64(msg, &st->f_blocks)) != 0 ||
(r = sshbuf_get_u64(msg, &st->f_bfree)) != 0 ||
(r = sshbuf_get_u64(msg, &st->f_bavail)) != 0 ||
(r = sshbuf_get_u64(msg, &st->f_files)) != 0 ||
(r = sshbuf_get_u64(msg, &st->f_ffree)) != 0 ||
(r = sshbuf_get_u64(msg, &st->f_favail)) != 0 ||
(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_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;
sshbuf_free(msg);
return 0;
}
struct sftp_conn *
do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests,
u_int64_t limit_kbps)
{
u_char type;
struct sshbuf *msg;
struct sftp_conn *ret;
int r;
ret = xcalloc(1, sizeof(*ret));
ret->msg_id = 1;
ret->fd_in = fd_in;
ret->fd_out = fd_out;
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_f("sshbuf_new failed");
if ((r = sshbuf_put_u8(msg, SSH2_FXP_INIT)) != 0 ||
(r = sshbuf_put_u32(msg, SSH2_FILEXFER_VERSION)) != 0)
fatal_fr(r, "parse");
send_msg(ret, msg);
get_msg_extended(ret, msg, 1);
/* Expecting a VERSION reply */
if ((r = sshbuf_get_u8(msg, &type)) != 0)
fatal_fr(r, "parse type");
if (type != SSH2_FXP_VERSION) {
error("Invalid packet back from SSH2_FXP_INIT (type %u)",
type);
sshbuf_free(msg);
free(ret);
return(NULL);
}
if ((r = sshbuf_get_u32(msg, &ret->version)) != 0)
fatal_fr(r, "parse version");
debug2("Remote version: %u", ret->version);
/* Check for extensions */
while (sshbuf_len(msg) > 0) {
char *name;
u_char *value;
size_t vlen;
int known = 0;
if ((r = sshbuf_get_cstring(msg, &name, NULL)) != 0 ||
(r = sshbuf_get_string(msg, &value, &vlen)) != 0)
fatal_fr(r, "parse extension");
if (strcmp(name, "posix-rename@openssh.com") == 0 &&
strcmp((char *)value, "1") == 0) {
ret->exts |= SFTP_EXT_POSIX_RENAME;
known = 1;
} else if (strcmp(name, "statvfs@openssh.com") == 0 &&
strcmp((char *)value, "2") == 0) {
ret->exts |= SFTP_EXT_STATVFS;
known = 1;
} else if (strcmp(name, "fstatvfs@openssh.com") == 0 &&
strcmp((char *)value, "2") == 0) {
ret->exts |= SFTP_EXT_FSTATVFS;
known = 1;
} else if (strcmp(name, "hardlink@openssh.com") == 0 &&
strcmp((char *)value, "1") == 0) {
ret->exts |= SFTP_EXT_HARDLINK;
known = 1;
} else if (strcmp(name, "fsync@openssh.com") == 0 &&
strcmp((char *)value, "1") == 0) {
ret->exts |= SFTP_EXT_FSYNC;
known = 1;
} else if (strcmp(name, "lsetstat@openssh.com") == 0 &&
strcmp((char *)value, "1") == 0) {
ret->exts |= SFTP_EXT_LSETSTAT;
known = 1;
} else if (strcmp(name, "limits@openssh.com") == 0 &&
strcmp((char *)value, "1") == 0) {
ret->exts |= SFTP_EXT_LIMITS;
known = 1;
} else if (strcmp(name, "expand-path@openssh.com") == 0 &&
strcmp((char *)value, "1") == 0) {
ret->exts |= SFTP_EXT_PATH_EXPAND;
known = 1;
} else if (strcmp(name, "copy-data") == 0 &&
strcmp((char *)value, "1") == 0) {
ret->exts |= SFTP_EXT_COPY_DATA;
known = 1;
} else if (strcmp(name,
"users-groups-by-id@openssh.com") == 0 &&
strcmp((char *)value, "1") == 0) {
ret->exts |= SFTP_EXT_GETUSERSGROUPS_BY_ID;
known = 1;
}
if (known) {
debug2("Server supports extension \"%s\" revision %s",
name, value);
} else {
debug2("Unrecognised server extension \"%s\"", name);
}
free(name);
free(value);
}
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);
+ ret->download_buflen = MINIMUM(limits.read_length,
+ SFTP_MAX_MSG_LENGTH - 1024);
+ ret->upload_buflen = MINIMUM(limits.write_length,
+ SFTP_MAX_MSG_LENGTH - 1024);
+ ret->download_buflen = MAXIMUM(ret->download_buflen, 64);
+ ret->upload_buflen = MAXIMUM(ret->upload_buflen, 64);
+ debug3("server upload/download buffer sizes "
+ "%llu / %llu; using %u / %u",
+ (unsigned long long)limits.write_length,
+ (unsigned long long)limits.read_length,
+ ret->upload_buflen, ret->download_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",
+ if (ret->num_requests == 0)
+ ret->num_requests = 1;
+ debug3("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->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->download_buflen);
bandwidth_limit_init(&ret->bwlimit_out, ret->limit_kbps,
ret->upload_buflen);
}
return ret;
}
u_int
sftp_proto_version(struct sftp_conn *conn)
{
return conn->version;
}
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;
struct sshbuf *msg;
int r;
if ((msg = sshbuf_new()) == NULL)
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_fr(r, "parse");
send_msg(conn, msg);
debug3("Sent message SSH2_FXP_CLOSE I:%u", id);
status = get_status(conn, id);
if (status != SSH2_FX_OK)
error("close remote: %s", fx2txt(status));
sshbuf_free(msg);
return status == SSH2_FX_OK ? 0 : -1;
}
static int
do_lsreaddir(struct sftp_conn *conn, const char *path, int print_flag,
SFTP_DIRENT ***dir)
{
struct sshbuf *msg;
u_int count, id, i, expected_id, ents = 0;
size_t handle_len;
u_char type, *handle;
int status = SSH2_FX_FAILURE;
int r;
if (dir)
*dir = NULL;
id = conn->msg_id++;
if ((msg = sshbuf_new()) == NULL)
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_fr(r, "compose OPENDIR");
send_msg(conn, msg);
handle = get_handle(conn, id, &handle_len,
"remote readdir(\"%s\")", path);
if (handle == NULL) {
sshbuf_free(msg);
return -1;
}
if (dir) {
ents = 0;
*dir = xcalloc(1, sizeof(**dir));
(*dir)[0] = NULL;
}
for (; !interrupted;) {
id = expected_id = conn->msg_id++;
debug3("Sending SSH2_FXP_READDIR I:%u", id);
sshbuf_reset(msg);
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_fr(r, "compose READDIR");
send_msg(conn, msg);
sshbuf_reset(msg);
get_msg(conn, msg);
if ((r = sshbuf_get_u8(msg, &type)) != 0 ||
(r = sshbuf_get_u32(msg, &id)) != 0)
fatal_fr(r, "parse");
debug3("Received 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 rstatus;
if ((r = sshbuf_get_u32(msg, &rstatus)) != 0)
fatal_fr(r, "parse status");
debug3("Received SSH2_FXP_STATUS %d", rstatus);
if (rstatus == SSH2_FX_EOF)
break;
error("Couldn't read directory: %s", fx2txt(rstatus));
goto out;
} else if (type != SSH2_FXP_NAME)
fatal("Expected SSH2_FXP_NAME(%u) packet, got %u",
SSH2_FXP_NAME, type);
if ((r = sshbuf_get_u32(msg, &count)) != 0)
fatal_fr(r, "parse count");
if (count > SSHBUF_SIZE_MAX)
fatal_f("nonsensical number of entries");
if (count == 0)
break;
debug3("Received %d SSH2_FXP_NAME responses", count);
for (i = 0; i < count; i++) {
char *filename, *longname;
Attrib a;
if ((r = sshbuf_get_cstring(msg, &filename,
NULL)) != 0 ||
(r = sshbuf_get_cstring(msg, &longname,
NULL)) != 0)
fatal_fr(r, "parse filenames");
if ((r = decode_attrib(msg, &a)) != 0) {
error_fr(r, "couldn't decode attrib");
free(filename);
free(longname);
goto out;
}
if (print_flag)
mprintf("%s\n", longname);
/*
* Directory entries should never contain '/'
* These can be used to attack recursive ops
* (e.g. send '../../../../etc/passwd')
*/
if (strpbrk(filename, SFTP_DIRECTORY_CHARS) != NULL) {
error("Server sent suspect path \"%s\" "
"during readdir of \"%s\"", filename, path);
} else if (dir) {
*dir = xreallocarray(*dir, ents + 2, sizeof(**dir));
(*dir)[ents] = xcalloc(1, sizeof(***dir));
(*dir)[ents]->filename = xstrdup(filename);
(*dir)[ents]->longname = xstrdup(longname);
memcpy(&(*dir)[ents]->a, &a, sizeof(a));
(*dir)[++ents] = NULL;
}
free(filename);
free(longname);
}
}
status = 0;
out:
sshbuf_free(msg);
do_close(conn, handle, handle_len);
free(handle);
if (status != 0 && dir != NULL) {
/* Don't return results on error */
free_sftp_dirents(*dir);
*dir = NULL;
} else if (interrupted && dir != NULL && *dir != NULL) {
/* Don't return partial matches on interrupt */
free_sftp_dirents(*dir);
*dir = xcalloc(1, sizeof(**dir));
**dir = NULL;
}
return status == SSH2_FX_OK ? 0 : -1;
}
int
do_readdir(struct sftp_conn *conn, const char *path, SFTP_DIRENT ***dir)
{
return(do_lsreaddir(conn, path, 0, dir));
}
void free_sftp_dirents(SFTP_DIRENT **s)
{
int i;
if (s == NULL)
return;
for (i = 0; s[i]; i++) {
free(s[i]->filename);
free(s[i]->longname);
free(s[i]);
}
free(s);
}
int
do_rm(struct sftp_conn *conn, const char *path)
{
u_int status, id;
debug2("Sending SSH2_FXP_REMOVE \"%s\"", path);
id = conn->msg_id++;
send_string_request(conn, id, SSH2_FXP_REMOVE, path, strlen(path));
status = get_status(conn, id);
if (status != SSH2_FX_OK)
error("remote delete %s: %s", path, fx2txt(status));
return status == SSH2_FX_OK ? 0 : -1;
}
int
do_mkdir(struct sftp_conn *conn, const char *path, Attrib *a, int print_flag)
{
u_int status, id;
debug2("Sending SSH2_FXP_MKDIR \"%s\"", path);
id = conn->msg_id++;
send_string_attrs_request(conn, id, SSH2_FXP_MKDIR, path,
strlen(path), a);
status = get_status(conn, id);
if (status != SSH2_FX_OK && print_flag)
error("remote mkdir \"%s\": %s", path, fx2txt(status));
return status == SSH2_FX_OK ? 0 : -1;
}
int
do_rmdir(struct sftp_conn *conn, const char *path)
{
u_int status, id;
debug2("Sending SSH2_FXP_RMDIR \"%s\"", path);
id = conn->msg_id++;
send_string_request(conn, id, SSH2_FXP_RMDIR, path,
strlen(path));
status = get_status(conn, id);
if (status != SSH2_FX_OK)
error("remote rmdir \"%s\": %s", path, fx2txt(status));
return status == SSH2_FX_OK ? 0 : -1;
}
Attrib *
do_stat(struct sftp_conn *conn, const char *path, int quiet)
{
u_int id;
debug2("Sending SSH2_FXP_STAT \"%s\"", path);
id = conn->msg_id++;
send_string_request(conn, id,
conn->version == 0 ? SSH2_FXP_STAT_VERSION_0 : SSH2_FXP_STAT,
path, strlen(path));
return(get_decode_stat(conn, id, quiet));
}
Attrib *
do_lstat(struct sftp_conn *conn, const char *path, int quiet)
{
u_int id;
if (conn->version == 0) {
if (quiet)
debug("Server version does not support lstat operation");
else
logit("Server version does not support lstat operation");
return(do_stat(conn, path, quiet));
}
id = conn->msg_id++;
send_string_request(conn, id, SSH2_FXP_LSTAT, path,
strlen(path));
return(get_decode_stat(conn, id, quiet));
}
#ifdef notyet
Attrib *
do_fstat(struct sftp_conn *conn, const u_char *handle, u_int handle_len,
int quiet)
{
u_int id;
debug2("Sending SSH2_FXP_FSTAT \"%s\"");
id = conn->msg_id++;
send_string_request(conn, id, SSH2_FXP_FSTAT, handle,
handle_len);
return(get_decode_stat(conn, id, quiet));
}
#endif
int
do_setstat(struct sftp_conn *conn, const char *path, Attrib *a)
{
u_int status, id;
debug2("Sending SSH2_FXP_SETSTAT \"%s\"", path);
id = conn->msg_id++;
send_string_attrs_request(conn, id, SSH2_FXP_SETSTAT, path,
strlen(path), a);
status = get_status(conn, id);
if (status != SSH2_FX_OK)
error("remote setstat \"%s\": %s", path, fx2txt(status));
return status == SSH2_FX_OK ? 0 : -1;
}
int
do_fsetstat(struct sftp_conn *conn, const u_char *handle, u_int handle_len,
Attrib *a)
{
u_int status, id;
debug2("Sending SSH2_FXP_FSETSTAT");
id = conn->msg_id++;
send_string_attrs_request(conn, id, SSH2_FXP_FSETSTAT, handle,
handle_len, a);
status = get_status(conn, id);
if (status != SSH2_FX_OK)
error("remote fsetstat: %s", fx2txt(status));
return status == SSH2_FX_OK ? 0 : -1;
}
/* 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;
char *filename, *longname;
Attrib a;
u_char type;
int r;
const char *what = "SSH2_FXP_REALPATH";
if (expand)
what = "expand-path@openssh.com";
if ((msg = sshbuf_new()) == NULL)
fatal_f("sshbuf_new failed");
expected_id = id = conn->msg_id++;
if (expand) {
debug2("Sending SSH2_FXP_EXTENDED(expand-path@openssh.com) "
"\"%s\"", path);
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 {
debug2("Sending SSH2_FXP_REALPATH \"%s\"", path);
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_fr(r, "parse");
if (id != expected_id)
fatal("ID mismatch (%u != %u)", id, expected_id);
if (type == SSH2_FXP_STATUS) {
u_int status;
char *errmsg;
if ((r = sshbuf_get_u32(msg, &status)) != 0 ||
(r = sshbuf_get_cstring(msg, &errmsg, NULL)) != 0)
fatal_fr(r, "parse status");
error("%s %s: %s", expand ? "expand" : "realpath",
path, *errmsg == '\0' ? fx2txt(status) : errmsg);
free(errmsg);
sshbuf_free(msg);
return NULL;
} else if (type != SSH2_FXP_NAME)
fatal("Expected SSH2_FXP_NAME(%u) packet, got %u",
SSH2_FXP_NAME, type);
if ((r = sshbuf_get_u32(msg, &count)) != 0)
fatal_fr(r, "parse count");
if (count != 1)
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_fr(r, "parse filename/attrib");
debug3("%s %s -> %s", what, path, filename);
free(longname);
sshbuf_free(msg);
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_copy(struct sftp_conn *conn, const char *oldpath, const char *newpath)
{
Attrib junk, *a;
struct sshbuf *msg;
u_char *old_handle, *new_handle;
u_int mode, status, id;
size_t old_handle_len, new_handle_len;
int r;
/* Return if the extension is not supported */
if ((conn->exts & SFTP_EXT_COPY_DATA) == 0) {
error("Server does not support copy-data extension");
return -1;
}
/* Make sure the file exists, and we can copy its perms */
if ((a = do_stat(conn, oldpath, 0)) == NULL)
return -1;
/* Do not preserve set[ug]id here, as we do not preserve ownership */
if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) {
mode = a->perm & 0777;
if (!S_ISREG(a->perm)) {
error("Cannot copy non-regular file: %s", oldpath);
return -1;
}
} else {
/* NB: The user's umask will apply to this */
mode = 0666;
}
/* Set up the new perms for the new file */
attrib_clear(a);
a->perm = mode;
a->flags |= SSH2_FILEXFER_ATTR_PERMISSIONS;
if ((msg = sshbuf_new()) == NULL)
fatal("%s: sshbuf_new failed", __func__);
attrib_clear(&junk); /* Send empty attributes */
/* Open the old file for reading */
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, oldpath)) != 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, oldpath);
sshbuf_reset(msg);
old_handle = get_handle(conn, id, &old_handle_len,
"remote open(\"%s\")", oldpath);
if (old_handle == NULL) {
sshbuf_free(msg);
return -1;
}
/* Open the new file for writing */
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, newpath)) != 0 ||
(r = sshbuf_put_u32(msg, SSH2_FXF_WRITE|SSH2_FXF_CREAT|
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, newpath);
sshbuf_reset(msg);
new_handle = get_handle(conn, id, &new_handle_len,
"remote open(\"%s\")", newpath);
if (new_handle == NULL) {
sshbuf_free(msg);
free(old_handle);
return -1;
}
/* Copy the file data */
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, "copy-data")) != 0 ||
(r = sshbuf_put_string(msg, old_handle, old_handle_len)) != 0 ||
(r = sshbuf_put_u64(msg, 0)) != 0 ||
(r = sshbuf_put_u64(msg, 0)) != 0 ||
(r = sshbuf_put_string(msg, new_handle, new_handle_len)) != 0 ||
(r = sshbuf_put_u64(msg, 0)) != 0)
fatal("%s: buffer error: %s", __func__, ssh_err(r));
send_msg(conn, msg);
debug3("Sent message copy-data \"%s\" 0 0 -> \"%s\" 0",
oldpath, newpath);
status = get_status(conn, id);
if (status != SSH2_FX_OK)
error("Couldn't copy file \"%s\" to \"%s\": %s", oldpath,
newpath, fx2txt(status));
/* Clean up everything */
sshbuf_free(msg);
do_close(conn, old_handle, old_handle_len);
do_close(conn, new_handle, new_handle_len);
free(old_handle);
free(new_handle);
return status == SSH2_FX_OK ? 0 : -1;
}
int
do_rename(struct sftp_conn *conn, const char *oldpath, const char *newpath,
int force_legacy)
{
struct sshbuf *msg;
u_int status, id;
int r, use_ext = (conn->exts & SFTP_EXT_POSIX_RENAME) && !force_legacy;
if ((msg = sshbuf_new()) == NULL)
fatal_f("sshbuf_new failed");
/* Send rename request */
id = conn->msg_id++;
if (use_ext) {
debug2("Sending SSH2_FXP_EXTENDED(posix-rename@openssh.com) "
"\"%s\" to \"%s\"", oldpath, newpath);
if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED)) != 0 ||
(r = sshbuf_put_u32(msg, id)) != 0 ||
(r = sshbuf_put_cstring(msg,
"posix-rename@openssh.com")) != 0)
fatal_fr(r, "compose posix-rename");
} else {
debug2("Sending SSH2_FXP_RENAME \"%s\" to \"%s\"",
oldpath, newpath);
if ((r = sshbuf_put_u8(msg, SSH2_FXP_RENAME)) != 0 ||
(r = sshbuf_put_u32(msg, id)) != 0)
fatal_fr(r, "compose rename");
}
if ((r = sshbuf_put_cstring(msg, oldpath)) != 0 ||
(r = sshbuf_put_cstring(msg, newpath)) != 0)
fatal_fr(r, "compose paths");
send_msg(conn, msg);
debug3("Sent message %s \"%s\" -> \"%s\"",
use_ext ? "posix-rename@openssh.com" :
"SSH2_FXP_RENAME", oldpath, newpath);
sshbuf_free(msg);
status = get_status(conn, id);
if (status != SSH2_FX_OK)
error("remote rename \"%s\" to \"%s\": %s", oldpath,
newpath, fx2txt(status));
return status == SSH2_FX_OK ? 0 : -1;
}
int
do_hardlink(struct sftp_conn *conn, const char *oldpath, const char *newpath)
{
struct sshbuf *msg;
u_int status, id;
int r;
if ((conn->exts & SFTP_EXT_HARDLINK) == 0) {
error("Server does not support hardlink@openssh.com extension");
return -1;
}
debug2("Sending SSH2_FXP_EXTENDED(hardlink@openssh.com) "
"\"%s\" to \"%s\"", oldpath, newpath);
if ((msg = sshbuf_new()) == NULL)
fatal_f("sshbuf_new failed");
/* Send link request */
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, "hardlink@openssh.com")) != 0 ||
(r = sshbuf_put_cstring(msg, oldpath)) != 0 ||
(r = sshbuf_put_cstring(msg, newpath)) != 0)
fatal_fr(r, "compose");
send_msg(conn, msg);
debug3("Sent message hardlink@openssh.com \"%s\" -> \"%s\"",
oldpath, newpath);
sshbuf_free(msg);
status = get_status(conn, id);
if (status != SSH2_FX_OK)
error("remote link \"%s\" to \"%s\": %s", oldpath,
newpath, fx2txt(status));
return status == SSH2_FX_OK ? 0 : -1;
}
int
do_symlink(struct sftp_conn *conn, const char *oldpath, const char *newpath)
{
struct sshbuf *msg;
u_int status, id;
int r;
if (conn->version < 3) {
error("This server does not support the symlink operation");
return(SSH2_FX_OP_UNSUPPORTED);
}
debug2("Sending SSH2_FXP_SYMLINK \"%s\" to \"%s\"", oldpath, newpath);
if ((msg = sshbuf_new()) == NULL)
fatal_f("sshbuf_new failed");
/* Send symlink request */
id = conn->msg_id++;
if ((r = sshbuf_put_u8(msg, SSH2_FXP_SYMLINK)) != 0 ||
(r = sshbuf_put_u32(msg, id)) != 0 ||
(r = sshbuf_put_cstring(msg, oldpath)) != 0 ||
(r = sshbuf_put_cstring(msg, newpath)) != 0)
fatal_fr(r, "compose");
send_msg(conn, msg);
debug3("Sent message SSH2_FXP_SYMLINK \"%s\" -> \"%s\"", oldpath,
newpath);
sshbuf_free(msg);
status = get_status(conn, id);
if (status != SSH2_FX_OK)
error("remote symlink file \"%s\" to \"%s\": %s", oldpath,
newpath, fx2txt(status));
return status == SSH2_FX_OK ? 0 : -1;
}
int
do_fsync(struct sftp_conn *conn, u_char *handle, u_int handle_len)
{
struct sshbuf *msg;
u_int status, id;
int r;
/* Silently return if the extension is not supported */
if ((conn->exts & SFTP_EXT_FSYNC) == 0)
return -1;
debug2("Sending SSH2_FXP_EXTENDED(fsync@openssh.com)");
/* Send fsync request */
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, "fsync@openssh.com")) != 0 ||
(r = sshbuf_put_string(msg, handle, handle_len)) != 0)
fatal_fr(r, "compose");
send_msg(conn, msg);
debug3("Sent message fsync@openssh.com I:%u", id);
sshbuf_free(msg);
status = get_status(conn, id);
if (status != SSH2_FX_OK)
error("remote fsync: %s", fx2txt(status));
return status == SSH2_FX_OK ? 0 : -1;
}
#ifdef notyet
char *
do_readlink(struct sftp_conn *conn, const char *path)
{
struct sshbuf *msg;
u_int expected_id, count, id;
char *filename, *longname;
Attrib a;
u_char type;
int r;
debug2("Sending SSH2_FXP_READLINK \"%s\"", path);
expected_id = id = conn->msg_id++;
send_string_request(conn, id, SSH2_FXP_READLINK, path, strlen(path));
if ((msg = sshbuf_new()) == NULL)
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_fr(r, "parse");
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_fr(r, "parse status");
error("Couldn't readlink: %s", fx2txt(status));
sshbuf_free(msg);
return(NULL);
} else if (type != SSH2_FXP_NAME)
fatal("Expected SSH2_FXP_NAME(%u) packet, got %u",
SSH2_FXP_NAME, type);
if ((r = sshbuf_get_u32(msg, &count)) != 0)
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_fr(r, "parse filenames/attrib");
debug3("SSH_FXP_READLINK %s -> %s", path, filename);
free(longname);
sshbuf_free(msg);
return filename;
}
#endif
int
do_statvfs(struct sftp_conn *conn, const char *path, struct sftp_statvfs *st,
int quiet)
{
struct sshbuf *msg;
u_int id;
int r;
if ((conn->exts & SFTP_EXT_STATVFS) == 0) {
error("Server does not support statvfs@openssh.com extension");
return -1;
}
debug2("Sending SSH2_FXP_EXTENDED(statvfs@openssh.com) \"%s\"", path);
id = conn->msg_id++;
if ((msg = sshbuf_new()) == NULL)
fatal_f("sshbuf_new failed");
if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED)) != 0 ||
(r = sshbuf_put_u32(msg, id)) != 0 ||
(r = sshbuf_put_cstring(msg, "statvfs@openssh.com")) != 0 ||
(r = sshbuf_put_cstring(msg, path)) != 0)
fatal_fr(r, "compose");
send_msg(conn, msg);
sshbuf_free(msg);
return get_decode_statvfs(conn, st, id, quiet);
}
#ifdef notyet
int
do_fstatvfs(struct sftp_conn *conn, const u_char *handle, u_int handle_len,
struct sftp_statvfs *st, int quiet)
{
struct sshbuf *msg;
u_int id;
if ((conn->exts & SFTP_EXT_FSTATVFS) == 0) {
error("Server does not support fstatvfs@openssh.com extension");
return -1;
}
debug2("Sending SSH2_FXP_EXTENDED(fstatvfs@openssh.com)");
id = conn->msg_id++;
if ((msg = sshbuf_new()) == NULL)
fatal_f("sshbuf_new failed");
if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED)) != 0 ||
(r = sshbuf_put_u32(msg, id)) != 0 ||
(r = sshbuf_put_cstring(msg, "fstatvfs@openssh.com")) != 0 ||
(r = sshbuf_put_string(msg, handle, handle_len)) != 0)
fatal_fr(r, "compose");
send_msg(conn, msg);
sshbuf_free(msg);
return get_decode_statvfs(conn, st, id, quiet);
}
#endif
int
do_lsetstat(struct sftp_conn *conn, const char *path, Attrib *a)
{
struct sshbuf *msg;
u_int status, id;
int r;
if ((conn->exts & SFTP_EXT_LSETSTAT) == 0) {
error("Server does not support lsetstat@openssh.com extension");
return -1;
}
debug2("Sending SSH2_FXP_EXTENDED(lsetstat@openssh.com) \"%s\"", path);
id = conn->msg_id++;
if ((msg = sshbuf_new()) == NULL)
fatal_f("sshbuf_new failed");
if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED)) != 0 ||
(r = sshbuf_put_u32(msg, id)) != 0 ||
(r = sshbuf_put_cstring(msg, "lsetstat@openssh.com")) != 0 ||
(r = sshbuf_put_cstring(msg, path)) != 0 ||
(r = encode_attrib(msg, a)) != 0)
fatal_fr(r, "compose");
send_msg(conn, msg);
sshbuf_free(msg);
status = get_status(conn, id);
if (status != SSH2_FX_OK)
error("remote lsetstat \"%s\": %s", path, fx2txt(status));
return status == SSH2_FX_OK ? 0 : -1;
}
static void
send_read_request(struct sftp_conn *conn, u_int id, u_int64_t offset,
u_int len, const u_char *handle, u_int handle_len)
{
struct sshbuf *msg;
int r;
if ((msg = sshbuf_new()) == NULL)
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_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;
debug2("Sending SSH2_FXP_OPEN \"%s\"", path);
*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, int inplace_flag)
{
struct sshbuf *msg;
u_char *handle;
int local_fd = -1, write_error;
int read_error, write_errno, lmodified = 0, reordered = 0, r;
u_int64_t offset = 0, size, highwater;
u_int mode, id, buflen, num_req, max_req, status = SSH2_FX_OK;
off_t progress_counter;
size_t handle_len;
struct stat st;
struct requests requests;
struct request *req;
u_char type;
debug2_f("download remote \"%s\" to local \"%s\"",
remote_path, local_path);
TAILQ_INIT(&requests);
if (a == NULL && (a = do_stat(conn, remote_path, 0)) == NULL)
return -1;
/* Do not preserve set[ug]id here, as we do not preserve ownership */
if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS)
mode = a->perm & 0777;
else
mode = 0666;
if ((a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) &&
(!S_ISREG(a->perm))) {
error("download %s: not a regular file", remote_path);
return(-1);
}
if (a->flags & SSH2_FILEXFER_ATTR_SIZE)
size = a->size;
else
size = 0;
buflen = conn->download_buflen;
/* Send open request */
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 || inplace_flag) ? 0 : O_TRUNC), mode | S_IWUSR);
if (local_fd == -1) {
error("open local \"%s\": %s", local_path, strerror(errno));
goto fail;
}
offset = highwater = 0;
if (resume_flag) {
if (fstat(local_fd, &st) == -1) {
error("stat local \"%s\": %s",
local_path, strerror(errno));
goto fail;
}
if (st.st_size < 0) {
error("\"%s\" has negative size", local_path);
goto fail;
}
if ((u_int64_t)st.st_size > size) {
error("Unable to resume download of \"%s\": "
"local file is larger than remote", local_path);
fail:
do_close(conn, handle, handle_len);
free(handle);
if (local_fd != -1)
close(local_fd);
return -1;
}
offset = highwater = st.st_size;
}
/* Read from remote and write to local */
write_error = read_error = write_errno = num_req = 0;
max_req = 1;
progress_counter = offset;
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;
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, conn->msg_id++,
buflen, offset);
offset += buflen;
num_req++;
send_read_request(conn, req->id, req->offset,
req->len, handle, handle_len);
}
sshbuf_reset(msg);
get_msg(conn, msg);
if ((r = sshbuf_get_u8(msg, &type)) != 0 ||
(r = sshbuf_get_u32(msg, &id)) != 0)
fatal_fr(r, "parse");
debug3("Received 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);
lmodified = 1;
if ((lseek(local_fd, req->offset, SEEK_SET) == -1 ||
atomicio(vwrite, local_fd, data, len) != len) &&
!write_error) {
write_errno = errno;
write_error = 1;
max_req = 0;
}
else if (!reordered && req->offset <= highwater)
highwater = req->offset + len;
else if (!reordered && req->offset > highwater)
reordered = 1;
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 = conn->msg_id++;
req->len -= len;
req->offset += len;
send_read_request(conn, req->id,
req->offset, req->len, handle, 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 < conn->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();
/* Sanity check */
if (TAILQ_FIRST(&requests) != NULL)
fatal("Transfer complete, but requests still in queue");
/*
* Truncate at highest contiguous point to avoid holes on interrupt,
* or unconditionally if writing in place.
*/
if (inplace_flag || read_error || write_error || interrupted) {
if (reordered && resume_flag) {
error("Unable to resume download of \"%s\": "
"server reordered requests", local_path);
}
debug("truncating at %llu", (unsigned long long)highwater);
if (ftruncate(local_fd, highwater) == -1)
error("local ftruncate \"%s\": %s", local_path,
strerror(errno));
}
if (read_error) {
error("read remote \"%s\" : %s", remote_path, fx2txt(status));
status = -1;
do_close(conn, handle, handle_len);
} else if (write_error) {
error("write local \"%s\": %s", local_path,
strerror(write_errno));
status = SSH2_FX_FAILURE;
do_close(conn, handle, handle_len);
} else {
if (do_close(conn, handle, handle_len) != 0 || interrupted)
status = SSH2_FX_FAILURE;
else
status = SSH2_FX_OK;
/* Override umask and utimes if asked */
#ifdef HAVE_FCHMOD
if (preserve_flag && fchmod(local_fd, mode) == -1)
#else
if (preserve_flag && chmod(local_path, mode) == -1)
#endif /* HAVE_FCHMOD */
error("local chmod \"%s\": %s", local_path,
strerror(errno));
if (preserve_flag &&
(a->flags & SSH2_FILEXFER_ATTR_ACMODTIME)) {
struct timeval tv[2];
tv[0].tv_sec = a->atime;
tv[1].tv_sec = a->mtime;
tv[0].tv_usec = tv[1].tv_usec = 0;
if (utimes(local_path, tv) == -1)
error("local set times \"%s\": %s",
local_path, strerror(errno));
}
if (resume_flag && !lmodified)
logit("File \"%s\" was not modified", local_path);
else if (fsync_flag) {
debug("syncing \"%s\"", local_path);
if (fsync(local_fd) == -1)
error("local sync \"%s\": %s",
local_path, strerror(errno));
}
}
close(local_fd);
sshbuf_free(msg);
free(handle);
return status == SSH2_FX_OK ? 0 : -1;
}
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 follow_link_flag, int inplace_flag)
{
int i, ret = 0;
SFTP_DIRENT **dir_entries;
char *filename, *new_src = NULL, *new_dst = NULL;
mode_t mode = 0777, tmpmode = mode;
if (depth >= MAX_DIR_DEPTH) {
error("Maximum directory depth exceeded: %d levels", depth);
return -1;
}
debug2_f("download dir remote \"%s\" to local \"%s\"", src, dst);
if (dirattrib == NULL &&
(dirattrib = do_stat(conn, src, 1)) == NULL) {
error("stat remote \"%s\" directory failed", src);
return -1;
}
if (!S_ISDIR(dirattrib->perm)) {
error("\"%s\" is not a directory", src);
return -1;
}
if (print_flag && print_flag != SFTP_PROGRESS_ONLY)
mprintf("Retrieving %s\n", src);
if (dirattrib->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) {
mode = dirattrib->perm & 01777;
tmpmode = mode | (S_IWUSR|S_IXUSR);
} else {
debug("download remote \"%s\": server "
"did not send permissions", dst);
}
if (mkdir(dst, tmpmode) == -1 && errno != EEXIST) {
error("mkdir %s: %s", dst, strerror(errno));
return -1;
}
if (do_readdir(conn, src, &dir_entries) == -1) {
error("remote readdir \"%s\" failed", src);
return -1;
}
for (i = 0; dir_entries[i] != NULL && !interrupted; i++) {
free(new_dst);
free(new_src);
filename = dir_entries[i]->filename;
new_dst = path_append(dst, filename);
new_src = path_append(src, filename);
if (S_ISDIR(dir_entries[i]->a.perm)) {
if (strcmp(filename, ".") == 0 ||
strcmp(filename, "..") == 0)
continue;
if (download_dir_internal(conn, new_src, new_dst,
depth + 1, &(dir_entries[i]->a), preserve_flag,
print_flag, resume_flag,
fsync_flag, follow_link_flag, inplace_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_download(conn, new_src, new_dst,
S_ISLNK(dir_entries[i]->a.perm) ? NULL :
&(dir_entries[i]->a),
preserve_flag, resume_flag, fsync_flag,
inplace_flag) == -1) {
error("Download of file %s to %s failed",
new_src, new_dst);
ret = -1;
}
} else
logit("download \"%s\": not a regular file", new_src);
}
free(new_dst);
free(new_src);
if (preserve_flag) {
if (dirattrib->flags & SSH2_FILEXFER_ATTR_ACMODTIME) {
struct timeval tv[2];
tv[0].tv_sec = dirattrib->atime;
tv[1].tv_sec = dirattrib->mtime;
tv[0].tv_usec = tv[1].tv_usec = 0;
if (utimes(dst, tv) == -1)
error("local set times on \"%s\": %s",
dst, strerror(errno));
} else
debug("Server did not send times for directory "
"\"%s\"", dst);
}
if (mode != tmpmode && chmod(dst, mode) == -1)
error("local chmod directory \"%s\": %s", dst,
strerror(errno));
free_sftp_dirents(dir_entries);
return ret;
}
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 follow_link_flag, int inplace_flag)
{
char *src_canon;
int ret;
if ((src_canon = do_realpath(conn, src)) == NULL) {
error("download \"%s\": path canonicalization failed", src);
return -1;
}
ret = download_dir_internal(conn, src_canon, dst, 0,
dirattrib, preserve_flag, print_flag, resume_flag, fsync_flag,
follow_link_flag, inplace_flag);
free(src_canon);
return ret;
}
int
do_upload(struct sftp_conn *conn, const char *local_path,
const char *remote_path, int preserve_flag, int resume,
int fsync_flag, int inplace_flag)
{
int r, local_fd;
u_int openmode, id, status = SSH2_FX_OK, reordered = 0;
off_t offset, progress_counter;
u_char type, *handle, *data;
struct sshbuf *msg;
struct stat sb;
Attrib a, t, *c = NULL;
u_int32_t startid, ackid;
u_int64_t highwater = 0;
struct request *ack = NULL;
struct requests acks;
size_t handle_len;
debug2_f("upload local \"%s\" to remote \"%s\"",
local_path, remote_path);
TAILQ_INIT(&acks);
if ((local_fd = open(local_path, O_RDONLY)) == -1) {
error("open local \"%s\": %s", local_path, strerror(errno));
return(-1);
}
if (fstat(local_fd, &sb) == -1) {
error("fstat local \"%s\": %s", local_path, strerror(errno));
close(local_fd);
return(-1);
}
if (!S_ISREG(sb.st_mode)) {
error("local \"%s\" is not a regular file", local_path);
close(local_fd);
return(-1);
}
stat_to_attrib(&sb, &a);
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 (resume) {
/* Get remote file size if it exists */
if ((c = do_stat(conn, remote_path, 0)) == NULL) {
close(local_fd);
return -1;
}
if ((off_t)c->size >= sb.st_size) {
error("resume \"%s\": destination file "
"same size or larger", local_path);
close(local_fd);
return -1;
}
if (lseek(local_fd, (off_t)c->size, SEEK_SET) == -1) {
close(local_fd);
return -1;
}
}
openmode = SSH2_FXF_WRITE|SSH2_FXF_CREAT;
if (resume)
openmode |= SSH2_FXF_APPEND;
else if (!inplace_flag)
openmode |= SSH2_FXF_TRUNC;
/* Send open request */
if (send_open(conn, remote_path, "dest", openmode, &a,
&handle, &handle_len) != 0) {
close(local_fd);
return -1;
}
id = conn->msg_id;
startid = ackid = id + 1;
data = xmalloc(conn->upload_buflen);
/* Read from local and write to remote */
offset = progress_counter = (resume ? c->size : 0);
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;
/*
* Can't use atomicio here because it returns 0 on EOF,
* thus losing the last block of the file.
* Simulate an EOF on interrupt, allowing ACKs from the
* server to drain.
*/
if (interrupted || status != SSH2_FX_OK)
len = 0;
else do
len = read(local_fd, data, conn->upload_buflen);
while ((len == -1) &&
(errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK));
if (len == -1) {
fatal("read local \"%s\": %s",
local_path, strerror(errno));
} else if (len != 0) {
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 ||
(r = sshbuf_put_string(msg, handle,
handle_len)) != 0 ||
(r = sshbuf_put_u64(msg, offset)) != 0 ||
(r = sshbuf_put_string(msg, data, len)) != 0)
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);
} else if (TAILQ_FIRST(&acks) == NULL)
break;
if (ack == NULL)
fatal("Unexpected ACK %u", id);
if (id == startid || len == 0 ||
id - ackid >= conn->num_requests) {
u_int rid;
sshbuf_reset(msg);
get_msg(conn, msg);
if ((r = sshbuf_get_u8(msg, &type)) != 0 ||
(r = sshbuf_get_u32(msg, &rid)) != 0)
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_fr(r, "parse status");
debug3("SSH2_FXP_STATUS %u", status);
/* Find the request in our queue */
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 %zu bytes at %lld",
ack->id, ack->len, (unsigned long long)ack->offset);
++ackid;
progress_counter += ack->len;
if (!reordered && ack->offset <= highwater)
highwater = ack->offset + ack->len;
else if (!reordered && ack->offset > highwater) {
debug3_f("server reordered ACKs");
reordered = 1;
}
free(ack);
}
offset += len;
if (offset < 0)
fatal_f("offset < 0");
}
sshbuf_free(msg);
if (showprogress)
stop_progress_meter();
free(data);
if (status != SSH2_FX_OK) {
error("write remote \"%s\": %s", remote_path, fx2txt(status));
status = SSH2_FX_FAILURE;
}
if (inplace_flag || (resume && (status != SSH2_FX_OK || interrupted))) {
debug("truncating at %llu", (unsigned long long)highwater);
attrib_clear(&t);
t.flags = SSH2_FILEXFER_ATTR_SIZE;
t.size = highwater;
do_fsetstat(conn, handle, handle_len, &t);
}
if (close(local_fd) == -1) {
error("close local \"%s\": %s", local_path, strerror(errno));
status = SSH2_FX_FAILURE;
}
/* Override umask and utimes if asked */
if (preserve_flag)
do_fsetstat(conn, handle, handle_len, &a);
if (fsync_flag)
(void)do_fsync(conn, handle, handle_len);
if (do_close(conn, handle, handle_len) != 0)
status = SSH2_FX_FAILURE;
free(handle);
return status == SSH2_FX_OK ? 0 : -1;
}
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 follow_link_flag, int inplace_flag)
{
int ret = 0;
DIR *dirp;
struct dirent *dp;
char *filename, *new_src = NULL, *new_dst = NULL;
struct stat sb;
Attrib a, *dirattrib;
u_int32_t saved_perm;
debug2_f("upload local dir \"%s\" to remote \"%s\"", src, dst);
if (depth >= MAX_DIR_DEPTH) {
error("Maximum directory depth exceeded: %d levels", depth);
return -1;
}
if (stat(src, &sb) == -1) {
error("stat local \"%s\": %s", src, strerror(errno));
return -1;
}
if (!S_ISDIR(sb.st_mode)) {
error("\"%s\" is not a directory", src);
return -1;
}
if (print_flag && print_flag != SFTP_PROGRESS_ONLY)
mprintf("Entering %s\n", src);
stat_to_attrib(&sb, &a);
a.flags &= ~SSH2_FILEXFER_ATTR_SIZE;
a.flags &= ~SSH2_FILEXFER_ATTR_UIDGID;
a.perm &= 01777;
if (!preserve_flag)
a.flags &= ~SSH2_FILEXFER_ATTR_ACMODTIME;
/*
* 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.
*/
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;
if (!S_ISDIR(dirattrib->perm)) {
error("\"%s\" exists but is not a directory", dst);
return -1;
}
}
a.perm = saved_perm;
if ((dirp = opendir(src)) == NULL) {
error("local opendir \"%s\": %s", src, strerror(errno));
return -1;
}
while (((dp = readdir(dirp)) != NULL) && !interrupted) {
if (dp->d_ino == 0)
continue;
free(new_dst);
free(new_src);
filename = dp->d_name;
new_dst = path_append(dst, filename);
new_src = path_append(src, filename);
if (lstat(new_src, &sb) == -1) {
logit("local lstat \"%s\": %s", filename,
strerror(errno));
ret = -1;
} else if (S_ISDIR(sb.st_mode)) {
if (strcmp(filename, ".") == 0 ||
strcmp(filename, "..") == 0)
continue;
if (upload_dir_internal(conn, new_src, new_dst,
depth + 1, preserve_flag, print_flag, resume,
fsync_flag, follow_link_flag, inplace_flag) == -1)
ret = -1;
} 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,
inplace_flag) == -1) {
error("upload \"%s\" to \"%s\" failed",
new_src, new_dst);
ret = -1;
}
} else
logit("%s: not a regular file", filename);
}
free(new_dst);
free(new_src);
do_setstat(conn, dst, &a);
(void) closedir(dirp);
return ret;
}
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 follow_link_flag, int inplace_flag)
{
char *dst_canon;
int ret;
if ((dst_canon = do_realpath(conn, dst)) == NULL) {
error("upload \"%s\": path canonicalization failed", dst);
return -1;
}
ret = upload_dir_internal(conn, src, dst_canon, 0, preserve_flag,
print_flag, resume, fsync_flag, follow_link_flag, inplace_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);
sshbuf_free(msg);
}
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;
debug2_f("crossload src \"%s\" to dst \"%s\"", from_path, to_path);
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("download \"%s\": not a regular file", 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("dest truncate \"%s\" failed", to_path);
to_handle = NULL;
}
}
if (read_error) {
error("read origin \"%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("write dest \"%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;
debug2_f("crossload dir src \"%s\" to dst \"%s\"", from_path, to_path);
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("stat remote \"%s\" failed", 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("origin readdir \"%s\" failed", 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("crossload \"%s\" to \"%s\" failed",
new_from_path, new_to_path);
ret = -1;
}
} else {
logit("origin \"%s\": not a regular file",
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("crossload \"%s\": path canonicalization failed",
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;
}
int
can_get_users_groups_by_id(struct sftp_conn *conn)
{
return (conn->exts & SFTP_EXT_GETUSERSGROUPS_BY_ID) != 0;
}
int
do_get_users_groups_by_id(struct sftp_conn *conn,
const u_int *uids, u_int nuids,
const u_int *gids, u_int ngids,
char ***usernamesp, char ***groupnamesp)
{
struct sshbuf *msg, *uidbuf, *gidbuf;
u_int i, expected_id, id;
char *name, **usernames = NULL, **groupnames = NULL;
u_char type;
int r;
*usernamesp = *groupnamesp = NULL;
if (!can_get_users_groups_by_id(conn))
return SSH_ERR_FEATURE_UNSUPPORTED;
if ((msg = sshbuf_new()) == NULL ||
(uidbuf = sshbuf_new()) == NULL ||
(gidbuf = sshbuf_new()) == NULL)
fatal_f("sshbuf_new failed");
expected_id = id = conn->msg_id++;
debug2("Sending SSH2_FXP_EXTENDED(users-groups-by-id@openssh.com)");
for (i = 0; i < nuids; i++) {
if ((r = sshbuf_put_u32(uidbuf, uids[i])) != 0)
fatal_fr(r, "compose uids");
}
for (i = 0; i < ngids; i++) {
if ((r = sshbuf_put_u32(gidbuf, gids[i])) != 0)
fatal_fr(r, "compose gids");
}
if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED)) != 0 ||
(r = sshbuf_put_u32(msg, id)) != 0 ||
(r = sshbuf_put_cstring(msg,
"users-groups-by-id@openssh.com")) != 0 ||
(r = sshbuf_put_stringb(msg, uidbuf)) != 0 ||
(r = sshbuf_put_stringb(msg, gidbuf)) != 0)
fatal_fr(r, "compose");
send_msg(conn, msg);
get_msg(conn, msg);
if ((r = sshbuf_get_u8(msg, &type)) != 0 ||
(r = sshbuf_get_u32(msg, &id)) != 0)
fatal_fr(r, "parse");
if (id != expected_id)
fatal("ID mismatch (%u != %u)", id, expected_id);
if (type == SSH2_FXP_STATUS) {
u_int status;
char *errmsg;
if ((r = sshbuf_get_u32(msg, &status)) != 0 ||
(r = sshbuf_get_cstring(msg, &errmsg, NULL)) != 0)
fatal_fr(r, "parse status");
error("users-groups-by-id %s",
*errmsg == '\0' ? fx2txt(status) : errmsg);
free(errmsg);
sshbuf_free(msg);
sshbuf_free(uidbuf);
sshbuf_free(gidbuf);
return -1;
} else if (type != SSH2_FXP_EXTENDED_REPLY)
fatal("Expected SSH2_FXP_EXTENDED_REPLY(%u) packet, got %u",
SSH2_FXP_EXTENDED_REPLY, type);
/* reuse */
sshbuf_free(uidbuf);
sshbuf_free(gidbuf);
uidbuf = gidbuf = NULL;
if ((r = sshbuf_froms(msg, &uidbuf)) != 0 ||
(r = sshbuf_froms(msg, &gidbuf)) != 0)
fatal_fr(r, "parse response");
if (nuids > 0) {
usernames = xcalloc(nuids, sizeof(*usernames));
for (i = 0; i < nuids; i++) {
if ((r = sshbuf_get_cstring(uidbuf, &name, NULL)) != 0)
fatal_fr(r, "parse user name");
/* Handle unresolved names */
if (*name == '\0') {
free(name);
name = NULL;
}
usernames[i] = name;
}
}
if (ngids > 0) {
groupnames = xcalloc(ngids, sizeof(*groupnames));
for (i = 0; i < ngids; i++) {
if ((r = sshbuf_get_cstring(gidbuf, &name, NULL)) != 0)
fatal_fr(r, "parse user name");
/* Handle unresolved names */
if (*name == '\0') {
free(name);
name = NULL;
}
groupnames[i] = name;
}
}
if (sshbuf_len(uidbuf) != 0)
fatal_f("unexpected extra username data");
if (sshbuf_len(gidbuf) != 0)
fatal_f("unexpected extra groupname data");
sshbuf_free(uidbuf);
sshbuf_free(gidbuf);
sshbuf_free(msg);
/* success */
*usernamesp = usernames;
*groupnamesp = groupnames;
return 0;
}
char *
path_append(const char *p1, const char *p2)
{
char *ret;
size_t len = strlen(p1) + strlen(p2) + 2;
ret = xmalloc(len);
strlcpy(ret, p1, len);
if (p1[0] != '\0' && p1[strlen(p1) - 1] != '/')
strlcat(ret, "/", len);
strlcat(ret, p2, len);
return(ret);
}
char *
make_absolute(char *p, const char *pwd)
{
char *abs_str;
/* Derelativise */
if (p && !path_absolute(p)) {
abs_str = path_append(pwd, p);
free(p);
return(abs_str);
} else
return(p);
}
int
remote_is_dir(struct sftp_conn *conn, const char *path)
{
Attrib *a;
/* XXX: report errors? */
if ((a = do_stat(conn, path, 1)) == NULL)
return(0);
if (!(a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS))
return(0);
return(S_ISDIR(a->perm));
}
int
local_is_dir(const char *path)
{
struct stat sb;
/* XXX: report errors? */
if (stat(path, &sb) == -1)
return(0);
return(S_ISDIR(sb.st_mode));
}
/* Check whether path returned from glob(..., GLOB_MARK, ...) is a directory */
int
globpath_is_dir(const char *pathname)
{
size_t l = strlen(pathname);
return l > 0 && pathname[l - 1] == '/';
}
diff --git a/crypto/openssh/sftp-glob.c b/crypto/openssh/sftp-glob.c
index 764e99552d42..afeb15f9ec11 100644
--- a/crypto/openssh/sftp-glob.c
+++ b/crypto/openssh/sftp-glob.c
@@ -1,150 +1,180 @@
-/* $OpenBSD: sftp-glob.c,v 1.30 2022/02/25 09:46:24 dtucker Exp $ */
+/* $OpenBSD: sftp-glob.c,v 1.31 2022/10/24 21:51:55 djm Exp $ */
/*
* Copyright (c) 2001-2004 Damien Miller <djm@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/types.h>
#ifdef HAVE_SYS_STAT_H
# include <sys/stat.h>
#endif
#include <dirent.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include "xmalloc.h"
#include "sftp.h"
#include "sftp-common.h"
#include "sftp-client.h"
int remote_glob(struct sftp_conn *, const char *, int,
int (*)(const char *, int), glob_t *);
struct SFTP_OPENDIR {
SFTP_DIRENT **dir;
int offset;
};
static struct {
struct sftp_conn *conn;
} cur;
static void *
fudge_opendir(const char *path)
{
struct SFTP_OPENDIR *r;
r = xcalloc(1, sizeof(*r));
if (do_readdir(cur.conn, path, &r->dir)) {
free(r);
return(NULL);
}
r->offset = 0;
return((void *)r);
}
static struct dirent *
fudge_readdir(struct SFTP_OPENDIR *od)
{
/* Solaris needs sizeof(dirent) + path length (see below) */
static char buf[sizeof(struct dirent) + MAXPATHLEN];
struct dirent *ret = (struct dirent *)buf;
#ifdef __GNU_LIBRARY__
static int inum = 1;
#endif /* __GNU_LIBRARY__ */
if (od->dir[od->offset] == NULL)
return(NULL);
memset(buf, 0, sizeof(buf));
/*
* Solaris defines dirent->d_name as a one byte array and expects
* you to hack around it.
*/
#ifdef BROKEN_ONE_BYTE_DIRENT_D_NAME
strlcpy(ret->d_name, od->dir[od->offset++]->filename, MAXPATHLEN);
#else
strlcpy(ret->d_name, od->dir[od->offset++]->filename,
sizeof(ret->d_name));
#endif
#ifdef __GNU_LIBRARY__
/*
* Idiot glibc uses extensions to struct dirent for readdir with
* ALTDIRFUNCs. Not that this is documented anywhere but the
* source... Fake an inode number to appease it.
*/
ret->d_ino = inum++;
if (!inum)
inum = 1;
#endif /* __GNU_LIBRARY__ */
return(ret);
}
static void
fudge_closedir(struct SFTP_OPENDIR *od)
{
free_sftp_dirents(od->dir);
free(od);
}
static int
fudge_lstat(const char *path, struct stat *st)
{
Attrib *a;
if (!(a = do_lstat(cur.conn, path, 1)))
return(-1);
attrib_to_stat(a, st);
return(0);
}
static int
fudge_stat(const char *path, struct stat *st)
{
Attrib *a;
if (!(a = do_stat(cur.conn, path, 1)))
return(-1);
attrib_to_stat(a, st);
return(0);
}
int
remote_glob(struct sftp_conn *conn, const char *pattern, int flags,
int (*errfunc)(const char *, int), glob_t *pglob)
{
+ int r;
+ size_t l;
+ char *s;
+ struct stat sb;
+
pglob->gl_opendir = fudge_opendir;
pglob->gl_readdir = (struct dirent *(*)(void *))fudge_readdir;
pglob->gl_closedir = (void (*)(void *))fudge_closedir;
pglob->gl_lstat = fudge_lstat;
pglob->gl_stat = fudge_stat;
memset(&cur, 0, sizeof(cur));
cur.conn = conn;
- return(glob(pattern, flags | GLOB_ALTDIRFUNC, errfunc, pglob));
+ if ((r = glob(pattern, flags | GLOB_ALTDIRFUNC, errfunc, pglob)) != 0)
+ return r;
+ /*
+ * When both GLOB_NOCHECK and GLOB_MARK are active, a single gl_pathv
+ * entry has been returned and that entry has not already been marked,
+ * then check whether it needs a '/' appended as a directory mark.
+ *
+ * This ensures that a NOCHECK result is annotated as a directory.
+ * The glob(3) spec doesn't promise to mark NOCHECK entries, but doing
+ * it simplifies our callers (sftp/scp) considerably.
+ *
+ * XXX doesn't try to handle gl_offs.
+ */
+ if ((flags & (GLOB_NOCHECK|GLOB_MARK)) == (GLOB_NOCHECK|GLOB_MARK) &&
+ pglob->gl_matchc == 0 && pglob->gl_offs == 0 &&
+ pglob->gl_pathc == 1 && (s = pglob->gl_pathv[0]) != NULL &&
+ (l = strlen(s)) > 0 && s[l-1] != '/') {
+ if (fudge_stat(s, &sb) == 0 && S_ISDIR(sb.st_mode)) {
+ /* NOCHECK on a directory; annotate */
+ if ((s = realloc(s, l + 2)) != NULL) {
+ memcpy(s + l, "/", 2);
+ pglob->gl_pathv[0] = s;
+ }
+ }
+ }
+ return 0;
}
diff --git a/crypto/openssh/sftp-server.c b/crypto/openssh/sftp-server.c
index 25f953489759..fe61a35159b3 100644
--- a/crypto/openssh/sftp-server.c
+++ b/crypto/openssh/sftp-server.c
@@ -1,2108 +1,2108 @@
-/* $OpenBSD: sftp-server.c,v 1.144 2022/09/19 10:41:58 djm Exp $ */
+/* $OpenBSD: sftp-server.c,v 1.145 2022/11/09 09:04:12 dtucker Exp $ */
/*
* Copyright (c) 2000-2004 Markus Friedl. All rights reserved.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "includes.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/resource.h>
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
#endif
#ifdef HAVE_SYS_MOUNT_H
#include <sys/mount.h>
#endif
#ifdef HAVE_SYS_STATVFS_H
#include <sys/statvfs.h>
#endif
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#ifdef HAVE_POLL_H
#include <poll.h>
#endif
#include <pwd.h>
#include <grp.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <stdarg.h>
#include "atomicio.h"
#include "xmalloc.h"
#include "sshbuf.h"
#include "ssherr.h"
#include "log.h"
#include "misc.h"
#include "match.h"
#include "uidswap.h"
#include "sftp.h"
#include "sftp-common.h"
char *sftp_realpath(const char *, char *); /* sftp-realpath.c */
/* Maximum data read that we are willing to accept */
#define SFTP_MAX_READ_LENGTH (SFTP_MAX_MSG_LENGTH - 1024)
/* Our verbosity */
static LogLevel log_level = SYSLOG_LEVEL_ERROR;
/* Our client */
static struct passwd *pw = NULL;
static char *client_addr = NULL;
/* input and output queue */
struct sshbuf *iqueue;
struct sshbuf *oqueue;
/* Version of client */
static u_int version;
/* SSH2_FXP_INIT received */
static int init_done;
/* Disable writes */
static int readonly;
/* Requests that are allowed/denied */
static char *request_allowlist, *request_denylist;
/* portable attributes, etc. */
typedef struct Stat Stat;
struct Stat {
char *name;
char *long_name;
Attrib attrib;
};
/* Packet handlers */
static void process_open(u_int32_t id);
static void process_close(u_int32_t id);
static void process_read(u_int32_t id);
static void process_write(u_int32_t id);
static void process_stat(u_int32_t id);
static void process_lstat(u_int32_t id);
static void process_fstat(u_int32_t id);
static void process_setstat(u_int32_t id);
static void process_fsetstat(u_int32_t id);
static void process_opendir(u_int32_t id);
static void process_readdir(u_int32_t id);
static void process_remove(u_int32_t id);
static void process_mkdir(u_int32_t id);
static void process_rmdir(u_int32_t id);
static void process_realpath(u_int32_t id);
static void process_rename(u_int32_t id);
static void process_readlink(u_int32_t id);
static void process_symlink(u_int32_t id);
static void process_extended_posix_rename(u_int32_t id);
static void process_extended_statvfs(u_int32_t id);
static void process_extended_fstatvfs(u_int32_t id);
static void process_extended_hardlink(u_int32_t id);
static void process_extended_fsync(u_int32_t id);
static void process_extended_lsetstat(u_int32_t id);
static void process_extended_limits(u_int32_t id);
static void process_extended_expand(u_int32_t id);
static void process_extended_copy_data(u_int32_t id);
static void process_extended_home_directory(u_int32_t id);
static void process_extended_get_users_groups_by_id(u_int32_t id);
static void process_extended(u_int32_t id);
struct sftp_handler {
const char *name; /* user-visible name for fine-grained perms */
const char *ext_name; /* extended request name */
u_int type; /* packet type, for non extended packets */
void (*handler)(u_int32_t);
int does_write; /* if nonzero, banned for readonly mode */
};
static const struct sftp_handler handlers[] = {
/* NB. SSH2_FXP_OPEN does the readonly check in the handler itself */
{ "open", NULL, SSH2_FXP_OPEN, process_open, 0 },
{ "close", NULL, SSH2_FXP_CLOSE, process_close, 0 },
{ "read", NULL, SSH2_FXP_READ, process_read, 0 },
{ "write", NULL, SSH2_FXP_WRITE, process_write, 1 },
{ "lstat", NULL, SSH2_FXP_LSTAT, process_lstat, 0 },
{ "fstat", NULL, SSH2_FXP_FSTAT, process_fstat, 0 },
{ "setstat", NULL, SSH2_FXP_SETSTAT, process_setstat, 1 },
{ "fsetstat", NULL, SSH2_FXP_FSETSTAT, process_fsetstat, 1 },
{ "opendir", NULL, SSH2_FXP_OPENDIR, process_opendir, 0 },
{ "readdir", NULL, SSH2_FXP_READDIR, process_readdir, 0 },
{ "remove", NULL, SSH2_FXP_REMOVE, process_remove, 1 },
{ "mkdir", NULL, SSH2_FXP_MKDIR, process_mkdir, 1 },
{ "rmdir", NULL, SSH2_FXP_RMDIR, process_rmdir, 1 },
{ "realpath", NULL, SSH2_FXP_REALPATH, process_realpath, 0 },
{ "stat", NULL, SSH2_FXP_STAT, process_stat, 0 },
{ "rename", NULL, SSH2_FXP_RENAME, process_rename, 1 },
{ "readlink", NULL, SSH2_FXP_READLINK, process_readlink, 0 },
{ "symlink", NULL, SSH2_FXP_SYMLINK, process_symlink, 1 },
{ NULL, NULL, 0, NULL, 0 }
};
/* SSH2_FXP_EXTENDED submessages */
static const struct sftp_handler extended_handlers[] = {
{ "posix-rename", "posix-rename@openssh.com", 0,
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 },
{ "copy-data", "copy-data", 0, process_extended_copy_data, 1 },
{ "home-directory", "home-directory", 0,
process_extended_home_directory, 0 },
{ "users-groups-by-id", "users-groups-by-id@openssh.com", 0,
process_extended_get_users_groups_by_id, 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)
{
char *result;
if (readonly && h->does_write) {
verbose("Refusing %s request in read-only mode", h->name);
return 0;
}
if (request_denylist != NULL &&
((result = match_list(h->name, request_denylist, NULL))) != NULL) {
free(result);
verbose("Refusing denylisted %s request", h->name);
return 0;
}
if (request_allowlist != NULL &&
((result = match_list(h->name, request_allowlist, NULL))) != NULL) {
free(result);
debug2("Permitting allowlisted %s request", h->name);
return 1;
}
if (request_allowlist != NULL) {
verbose("Refusing non-allowlisted %s request", h->name);
return 0;
}
return 1;
}
static int
errno_to_portable(int unixerrno)
{
int ret = 0;
switch (unixerrno) {
case 0:
ret = SSH2_FX_OK;
break;
case ENOENT:
case ENOTDIR:
case EBADF:
case ELOOP:
ret = SSH2_FX_NO_SUCH_FILE;
break;
case EPERM:
case EACCES:
case EFAULT:
ret = SSH2_FX_PERMISSION_DENIED;
break;
case ENAMETOOLONG:
case EINVAL:
ret = SSH2_FX_BAD_MESSAGE;
break;
case ENOSYS:
ret = SSH2_FX_OP_UNSUPPORTED;
break;
default:
ret = SSH2_FX_FAILURE;
break;
}
return ret;
}
static int
flags_from_portable(int pflags)
{
int flags = 0;
if ((pflags & SSH2_FXF_READ) &&
(pflags & SSH2_FXF_WRITE)) {
flags = O_RDWR;
} else if (pflags & SSH2_FXF_READ) {
flags = O_RDONLY;
} else if (pflags & SSH2_FXF_WRITE) {
flags = O_WRONLY;
}
if (pflags & SSH2_FXF_APPEND)
flags |= O_APPEND;
if (pflags & SSH2_FXF_CREAT)
flags |= O_CREAT;
if (pflags & SSH2_FXF_TRUNC)
flags |= O_TRUNC;
if (pflags & SSH2_FXF_EXCL)
flags |= O_EXCL;
return flags;
}
static const char *
string_from_portable(int pflags)
{
static char ret[128];
*ret = '\0';
#define PAPPEND(str) { \
if (*ret != '\0') \
strlcat(ret, ",", sizeof(ret)); \
strlcat(ret, str, sizeof(ret)); \
}
if (pflags & SSH2_FXF_READ)
PAPPEND("READ")
if (pflags & SSH2_FXF_WRITE)
PAPPEND("WRITE")
if (pflags & SSH2_FXF_APPEND)
PAPPEND("APPEND")
if (pflags & SSH2_FXF_CREAT)
PAPPEND("CREATE")
if (pflags & SSH2_FXF_TRUNC)
PAPPEND("TRUNCATE")
if (pflags & SSH2_FXF_EXCL)
PAPPEND("EXCL")
return ret;
}
/* handle handles */
typedef struct Handle Handle;
struct Handle {
int use;
DIR *dirp;
int fd;
int flags;
char *name;
u_int64_t bytes_read, bytes_write;
int next_unused;
};
enum {
HANDLE_UNUSED,
HANDLE_DIR,
HANDLE_FILE
};
static Handle *handles = NULL;
static u_int num_handles = 0;
static int first_unused_handle = -1;
static void handle_unused(int i)
{
handles[i].use = HANDLE_UNUSED;
handles[i].next_unused = first_unused_handle;
first_unused_handle = i;
}
static int
handle_new(int use, const char *name, int fd, int flags, DIR *dirp)
{
int i;
if (first_unused_handle == -1) {
if (num_handles + 1 <= num_handles)
return -1;
num_handles++;
handles = xreallocarray(handles, num_handles, sizeof(Handle));
handle_unused(num_handles - 1);
}
i = first_unused_handle;
first_unused_handle = handles[i].next_unused;
handles[i].use = use;
handles[i].dirp = dirp;
handles[i].fd = fd;
handles[i].flags = flags;
handles[i].name = xstrdup(name);
handles[i].bytes_read = handles[i].bytes_write = 0;
return i;
}
static int
handle_is_ok(int i, int type)
{
return i >= 0 && (u_int)i < num_handles && handles[i].use == type;
}
static int
handle_to_string(int handle, u_char **stringp, int *hlenp)
{
if (stringp == NULL || hlenp == NULL)
return -1;
*stringp = xmalloc(sizeof(int32_t));
put_u32(*stringp, handle);
*hlenp = sizeof(int32_t);
return 0;
}
static int
handle_from_string(const u_char *handle, u_int hlen)
{
int val;
if (hlen != sizeof(int32_t))
return -1;
val = get_u32(handle);
if (handle_is_ok(val, HANDLE_FILE) ||
handle_is_ok(val, HANDLE_DIR))
return val;
return -1;
}
static char *
handle_to_name(int handle)
{
if (handle_is_ok(handle, HANDLE_DIR)||
handle_is_ok(handle, HANDLE_FILE))
return handles[handle].name;
return NULL;
}
static DIR *
handle_to_dir(int handle)
{
if (handle_is_ok(handle, HANDLE_DIR))
return handles[handle].dirp;
return NULL;
}
static int
handle_to_fd(int handle)
{
if (handle_is_ok(handle, HANDLE_FILE))
return handles[handle].fd;
return -1;
}
static int
handle_to_flags(int handle)
{
if (handle_is_ok(handle, HANDLE_FILE))
return handles[handle].flags;
return 0;
}
static void
handle_update_read(int handle, ssize_t bytes)
{
if (handle_is_ok(handle, HANDLE_FILE) && bytes > 0)
handles[handle].bytes_read += bytes;
}
static void
handle_update_write(int handle, ssize_t bytes)
{
if (handle_is_ok(handle, HANDLE_FILE) && bytes > 0)
handles[handle].bytes_write += bytes;
}
static u_int64_t
handle_bytes_read(int handle)
{
if (handle_is_ok(handle, HANDLE_FILE))
return (handles[handle].bytes_read);
return 0;
}
static u_int64_t
handle_bytes_write(int handle)
{
if (handle_is_ok(handle, HANDLE_FILE))
return (handles[handle].bytes_write);
return 0;
}
static int
handle_close(int handle)
{
int ret = -1;
if (handle_is_ok(handle, HANDLE_FILE)) {
ret = close(handles[handle].fd);
free(handles[handle].name);
handle_unused(handle);
} else if (handle_is_ok(handle, HANDLE_DIR)) {
ret = closedir(handles[handle].dirp);
free(handles[handle].name);
handle_unused(handle);
} else {
errno = ENOENT;
}
return ret;
}
static void
handle_log_close(int handle, char *emsg)
{
if (handle_is_ok(handle, HANDLE_FILE)) {
logit("%s%sclose \"%s\" bytes read %llu written %llu",
emsg == NULL ? "" : emsg, emsg == NULL ? "" : " ",
handle_to_name(handle),
(unsigned long long)handle_bytes_read(handle),
(unsigned long long)handle_bytes_write(handle));
} else {
logit("%s%sclosedir \"%s\"",
emsg == NULL ? "" : emsg, emsg == NULL ? "" : " ",
handle_to_name(handle));
}
}
static void
handle_log_exit(void)
{
u_int i;
for (i = 0; i < num_handles; i++)
if (handles[i].use != HANDLE_UNUSED)
handle_log_close(i, "forced");
}
static int
get_handle(struct sshbuf *queue, int *hp)
{
u_char *handle;
int r;
size_t hlen;
*hp = -1;
if ((r = sshbuf_get_string(queue, &handle, &hlen)) != 0)
return r;
if (hlen < 256)
*hp = handle_from_string(handle, hlen);
free(handle);
return 0;
}
/* send replies */
static void
send_msg(struct sshbuf *m)
{
int r;
if ((r = sshbuf_put_stringb(oqueue, m)) != 0)
fatal_fr(r, "enqueue");
sshbuf_reset(m);
}
static const char *
status_to_message(u_int32_t status)
{
static const char * const status_messages[] = {
"Success", /* SSH_FX_OK */
"End of file", /* SSH_FX_EOF */
"No such file", /* SSH_FX_NO_SUCH_FILE */
"Permission denied", /* SSH_FX_PERMISSION_DENIED */
"Failure", /* SSH_FX_FAILURE */
"Bad message", /* SSH_FX_BAD_MESSAGE */
"No connection", /* SSH_FX_NO_CONNECTION */
"Connection lost", /* SSH_FX_CONNECTION_LOST */
"Operation unsupported", /* SSH_FX_OP_UNSUPPORTED */
"Unknown error" /* Others */
};
return (status_messages[MINIMUM(status,SSH2_FX_MAX)]);
}
static void
send_status_errmsg(u_int32_t id, u_int32_t status, const char *errmsg)
{
struct sshbuf *msg;
int r;
debug3("request %u: sent status %u", id, status);
if (log_level > SYSLOG_LEVEL_VERBOSE ||
(status != SSH2_FX_OK && status != SSH2_FX_EOF))
logit("sent status %s", status_to_message(status));
if ((msg = sshbuf_new()) == NULL)
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_fr(r, "compose");
if (version >= 3) {
if ((r = sshbuf_put_cstring(msg, errmsg == NULL ?
status_to_message(status) : errmsg)) != 0 ||
(r = sshbuf_put_cstring(msg, "")) != 0)
fatal_fr(r, "compose message");
}
send_msg(msg);
sshbuf_free(msg);
}
static void
send_status(u_int32_t id, u_int32_t status)
{
send_status_errmsg(id, status, NULL);
}
static void
send_data_or_handle(char type, u_int32_t id, const u_char *data, int dlen)
{
struct sshbuf *msg;
int r;
if ((msg = sshbuf_new()) == NULL)
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_fr(r, "compose");
send_msg(msg);
sshbuf_free(msg);
}
static void
send_data(u_int32_t id, const u_char *data, int dlen)
{
debug("request %u: sent data len %d", id, dlen);
send_data_or_handle(SSH2_FXP_DATA, id, data, dlen);
}
static void
send_handle(u_int32_t id, int handle)
{
u_char *string;
int hlen;
handle_to_string(handle, &string, &hlen);
debug("request %u: sent handle handle %d", id, handle);
send_data_or_handle(SSH2_FXP_HANDLE, id, string, hlen);
free(string);
}
static void
send_names(u_int32_t id, int count, const Stat *stats)
{
struct sshbuf *msg;
int i, r;
if ((msg = sshbuf_new()) == NULL)
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_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_fr(r, "compose filenames/attrib");
}
send_msg(msg);
sshbuf_free(msg);
}
static void
send_attrib(u_int32_t id, const Attrib *a)
{
struct sshbuf *msg;
int r;
debug("request %u: sent attrib have 0x%x", id, a->flags);
if ((msg = sshbuf_new()) == NULL)
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_fr(r, "compose");
send_msg(msg);
sshbuf_free(msg);
}
static void
send_statvfs(u_int32_t id, struct statvfs *st)
{
struct sshbuf *msg;
u_int64_t flag;
int r;
flag = (st->f_flag & ST_RDONLY) ? SSH2_FXE_STATVFS_ST_RDONLY : 0;
flag |= (st->f_flag & ST_NOSUID) ? SSH2_FXE_STATVFS_ST_NOSUID : 0;
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 ||
(r = sshbuf_put_u64(msg, st->f_bsize)) != 0 ||
(r = sshbuf_put_u64(msg, st->f_frsize)) != 0 ||
(r = sshbuf_put_u64(msg, st->f_blocks)) != 0 ||
(r = sshbuf_put_u64(msg, st->f_bfree)) != 0 ||
(r = sshbuf_put_u64(msg, st->f_bavail)) != 0 ||
(r = sshbuf_put_u64(msg, st->f_files)) != 0 ||
(r = sshbuf_put_u64(msg, st->f_ffree)) != 0 ||
(r = sshbuf_put_u64(msg, st->f_favail)) != 0 ||
(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_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 advertisement.
*/
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
process_init(void)
{
struct sshbuf *msg;
int r;
if ((r = sshbuf_get_u32(iqueue, &version)) != 0)
fatal_fr(r, "parse");
verbose("received client version %u", version);
if ((msg = sshbuf_new()) == NULL)
fatal_f("sshbuf_new failed");
if ((r = sshbuf_put_u8(msg, SSH2_FXP_VERSION)) != 0 ||
(r = sshbuf_put_u32(msg, SSH2_FILEXFER_VERSION)) != 0)
fatal_fr(r, "compose");
/* extension advertisements */
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");
compose_extension(msg, "copy-data", "1");
compose_extension(msg, "home-directory", "1");
compose_extension(msg, "users-groups-by-id@openssh.com", "1");
send_msg(msg);
sshbuf_free(msg);
}
static void
process_open(u_int32_t id)
{
u_int32_t pflags;
Attrib a;
char *name;
int r, handle, fd, flags, mode, status = SSH2_FX_FAILURE;
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_fr(r, "parse");
debug3("request %u: open flags %d", id, pflags);
flags = flags_from_portable(pflags);
mode = (a.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? a.perm : 0666;
logit("open \"%s\" flags %s mode 0%o",
name, string_from_portable(pflags), mode);
if (readonly &&
((flags & O_ACCMODE) != O_RDONLY ||
(flags & (O_CREAT|O_TRUNC)) != 0)) {
verbose("Refusing open request in read-only mode");
status = SSH2_FX_PERMISSION_DENIED;
} else {
fd = open(name, flags, mode);
if (fd == -1) {
status = errno_to_portable(errno);
} else {
handle = handle_new(HANDLE_FILE, name, fd, flags, NULL);
if (handle < 0) {
close(fd);
} else {
send_handle(id, handle);
status = SSH2_FX_OK;
}
}
}
if (status != SSH2_FX_OK)
send_status(id, status);
free(name);
}
static void
process_close(u_int32_t id)
{
int r, handle, ret, status = SSH2_FX_FAILURE;
if ((r = get_handle(iqueue, &handle)) != 0)
fatal_fr(r, "parse");
debug3("request %u: close handle %u", id, handle);
handle_log_close(handle, NULL);
ret = handle_close(handle);
status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
send_status(id, status);
}
static void
process_read(u_int32_t id)
{
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;
if ((r = get_handle(iqueue, &handle)) != 0 ||
(r = sshbuf_get_u64(iqueue, &off)) != 0 ||
(r = sshbuf_get_u32(iqueue, &len)) != 0)
fatal_fr(r, "parse");
debug("request %u: read \"%s\" (handle %d) off %llu len %u",
id, handle_to_name(handle), handle, (unsigned long long)off, 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;
}
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);
}
static void
process_write(u_int32_t id)
{
u_int64_t off;
size_t len;
int r, handle, fd, ret, status;
u_char *data;
if ((r = get_handle(iqueue, &handle)) != 0 ||
(r = sshbuf_get_u64(iqueue, &off)) != 0 ||
(r = sshbuf_get_string(iqueue, &data, &len)) != 0)
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);
fd = handle_to_fd(handle);
if (fd < 0)
status = SSH2_FX_FAILURE;
else {
if (!(handle_to_flags(handle) & O_APPEND) &&
lseek(fd, off, SEEK_SET) == -1) {
status = errno_to_portable(errno);
error_f("seek \"%.100s\": %s", handle_to_name(handle),
strerror(errno));
} else {
/* XXX ATOMICIO ? */
ret = write(fd, data, len);
if (ret == -1) {
status = errno_to_portable(errno);
error_f("write \"%.100s\": %s",
handle_to_name(handle), strerror(errno));
} else if ((size_t)ret == len) {
status = SSH2_FX_OK;
handle_update_write(handle, ret);
} else {
debug2_f("nothing at all written");
status = SSH2_FX_FAILURE;
}
}
}
send_status(id, status);
free(data);
}
static void
process_do_stat(u_int32_t id, int do_lstat)
{
Attrib a;
struct stat st;
char *name;
int r, status = SSH2_FX_FAILURE;
if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0)
fatal_fr(r, "parse");
debug3("request %u: %sstat", id, do_lstat ? "l" : "");
verbose("%sstat name \"%s\"", do_lstat ? "l" : "", name);
r = do_lstat ? lstat(name, &st) : stat(name, &st);
if (r == -1) {
status = errno_to_portable(errno);
} else {
stat_to_attrib(&st, &a);
send_attrib(id, &a);
status = SSH2_FX_OK;
}
if (status != SSH2_FX_OK)
send_status(id, status);
free(name);
}
static void
process_stat(u_int32_t id)
{
process_do_stat(id, 0);
}
static void
process_lstat(u_int32_t id)
{
process_do_stat(id, 1);
}
static void
process_fstat(u_int32_t id)
{
Attrib a;
struct stat st;
int fd, r, handle, status = SSH2_FX_FAILURE;
if ((r = get_handle(iqueue, &handle)) != 0)
fatal_fr(r, "parse");
debug("request %u: fstat \"%s\" (handle %u)",
id, handle_to_name(handle), handle);
fd = handle_to_fd(handle);
if (fd >= 0) {
r = fstat(fd, &st);
if (r == -1) {
status = errno_to_portable(errno);
} else {
stat_to_attrib(&st, &a);
send_attrib(id, &a);
status = SSH2_FX_OK;
}
}
if (status != SSH2_FX_OK)
send_status(id, status);
}
static struct timeval *
attrib_to_tv(const Attrib *a)
{
static struct timeval tv[2];
tv[0].tv_sec = a->atime;
tv[0].tv_usec = 0;
tv[1].tv_sec = a->mtime;
tv[1].tv_usec = 0;
return tv;
}
static struct timespec *
attrib_to_ts(const Attrib *a)
{
static struct timespec ts[2];
ts[0].tv_sec = a->atime;
ts[0].tv_nsec = 0;
ts[1].tv_sec = a->mtime;
ts[1].tv_nsec = 0;
return ts;
}
static void
process_setstat(u_int32_t id)
{
Attrib a;
char *name;
int r, status = SSH2_FX_OK;
if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0 ||
(r = decode_attrib(iqueue, &a)) != 0)
fatal_fr(r, "parse");
debug("request %u: setstat name \"%s\"", id, name);
if (a.flags & SSH2_FILEXFER_ATTR_SIZE) {
logit("set \"%s\" size %llu",
name, (unsigned long long)a.size);
r = truncate(name, a.size);
if (r == -1)
status = errno_to_portable(errno);
}
if (a.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) {
logit("set \"%s\" mode %04o", name, a.perm);
r = chmod(name, a.perm & 07777);
if (r == -1)
status = errno_to_portable(errno);
}
if (a.flags & SSH2_FILEXFER_ATTR_ACMODTIME) {
char buf[64];
time_t t = a.mtime;
strftime(buf, sizeof(buf), "%Y%m%d-%H:%M:%S",
localtime(&t));
logit("set \"%s\" modtime %s", name, buf);
r = utimes(name, attrib_to_tv(&a));
if (r == -1)
status = errno_to_portable(errno);
}
if (a.flags & SSH2_FILEXFER_ATTR_UIDGID) {
logit("set \"%s\" owner %lu group %lu", name,
(u_long)a.uid, (u_long)a.gid);
r = chown(name, a.uid, a.gid);
if (r == -1)
status = errno_to_portable(errno);
}
send_status(id, status);
free(name);
}
static void
process_fsetstat(u_int32_t id)
{
Attrib a;
int handle, fd, r;
int status = SSH2_FX_OK;
if ((r = get_handle(iqueue, &handle)) != 0 ||
(r = decode_attrib(iqueue, &a)) != 0)
fatal_fr(r, "parse");
debug("request %u: fsetstat handle %d", id, handle);
fd = handle_to_fd(handle);
if (fd < 0)
status = SSH2_FX_FAILURE;
else {
char *name = handle_to_name(handle);
if (a.flags & SSH2_FILEXFER_ATTR_SIZE) {
logit("set \"%s\" size %llu",
name, (unsigned long long)a.size);
r = ftruncate(fd, a.size);
if (r == -1)
status = errno_to_portable(errno);
}
if (a.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) {
logit("set \"%s\" mode %04o", name, a.perm);
#ifdef HAVE_FCHMOD
r = fchmod(fd, a.perm & 07777);
#else
r = chmod(name, a.perm & 07777);
#endif
if (r == -1)
status = errno_to_portable(errno);
}
if (a.flags & SSH2_FILEXFER_ATTR_ACMODTIME) {
char buf[64];
time_t t = a.mtime;
strftime(buf, sizeof(buf), "%Y%m%d-%H:%M:%S",
localtime(&t));
logit("set \"%s\" modtime %s", name, buf);
#ifdef HAVE_FUTIMES
r = futimes(fd, attrib_to_tv(&a));
#else
r = utimes(name, attrib_to_tv(&a));
#endif
if (r == -1)
status = errno_to_portable(errno);
}
if (a.flags & SSH2_FILEXFER_ATTR_UIDGID) {
logit("set \"%s\" owner %lu group %lu", name,
(u_long)a.uid, (u_long)a.gid);
#ifdef HAVE_FCHOWN
r = fchown(fd, a.uid, a.gid);
#else
r = chown(name, a.uid, a.gid);
#endif
if (r == -1)
status = errno_to_portable(errno);
}
}
send_status(id, status);
}
static void
process_opendir(u_int32_t id)
{
DIR *dirp = NULL;
char *path;
int r, handle, status = SSH2_FX_FAILURE;
if ((r = sshbuf_get_cstring(iqueue, &path, NULL)) != 0)
fatal_fr(r, "parse");
debug3("request %u: opendir", id);
logit("opendir \"%s\"", path);
dirp = opendir(path);
if (dirp == NULL) {
status = errno_to_portable(errno);
} else {
handle = handle_new(HANDLE_DIR, path, 0, 0, dirp);
if (handle < 0) {
closedir(dirp);
} else {
send_handle(id, handle);
status = SSH2_FX_OK;
}
}
if (status != SSH2_FX_OK)
send_status(id, status);
free(path);
}
static void
process_readdir(u_int32_t id)
{
DIR *dirp;
struct dirent *dp;
char *path;
int r, handle;
if ((r = get_handle(iqueue, &handle)) != 0)
fatal_fr(r, "parse");
debug("request %u: readdir \"%s\" (handle %d)", id,
handle_to_name(handle), handle);
dirp = handle_to_dir(handle);
path = handle_to_name(handle);
if (dirp == NULL || path == NULL) {
send_status(id, SSH2_FX_FAILURE);
} else {
struct stat st;
char pathname[PATH_MAX];
Stat *stats;
int nstats = 10, count = 0, i;
stats = xcalloc(nstats, sizeof(Stat));
while ((dp = readdir(dirp)) != NULL) {
if (count >= nstats) {
nstats *= 2;
stats = xreallocarray(stats, nstats, sizeof(Stat));
}
/* XXX OVERFLOW ? */
snprintf(pathname, sizeof pathname, "%s%s%s", path,
strcmp(path, "/") ? "/" : "", dp->d_name);
if (lstat(pathname, &st) == -1)
continue;
stat_to_attrib(&st, &(stats[count].attrib));
stats[count].name = xstrdup(dp->d_name);
stats[count].long_name = ls_file(dp->d_name, &st,
0, 0, NULL, NULL);
count++;
/* send up to 100 entries in one message */
/* XXX check packet size instead */
if (count == 100)
break;
}
if (count > 0) {
send_names(id, count, stats);
for (i = 0; i < count; i++) {
free(stats[i].name);
free(stats[i].long_name);
}
} else {
send_status(id, SSH2_FX_EOF);
}
free(stats);
}
}
static void
process_remove(u_int32_t id)
{
char *name;
int r, status = SSH2_FX_FAILURE;
if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0)
fatal_fr(r, "parse");
debug3("request %u: remove", id);
logit("remove name \"%s\"", name);
r = unlink(name);
status = (r == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
send_status(id, status);
free(name);
}
static void
process_mkdir(u_int32_t id)
{
Attrib a;
char *name;
int r, mode, status = SSH2_FX_FAILURE;
if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0 ||
(r = decode_attrib(iqueue, &a)) != 0)
fatal_fr(r, "parse");
mode = (a.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ?
a.perm & 07777 : 0777;
debug3("request %u: mkdir", id);
logit("mkdir name \"%s\" mode 0%o", name, mode);
r = mkdir(name, mode);
status = (r == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
send_status(id, status);
free(name);
}
static void
process_rmdir(u_int32_t id)
{
char *name;
int r, status;
if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0)
fatal_fr(r, "parse");
debug3("request %u: rmdir", id);
logit("rmdir name \"%s\"", name);
r = rmdir(name);
status = (r == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
send_status(id, status);
free(name);
}
static void
process_realpath(u_int32_t id)
{
char resolvedname[PATH_MAX];
char *path;
int r;
if ((r = sshbuf_get_cstring(iqueue, &path, NULL)) != 0)
fatal_fr(r, "parse");
if (path[0] == '\0') {
free(path);
path = xstrdup(".");
}
debug3("request %u: realpath", id);
verbose("realpath \"%s\"", path);
if (sftp_realpath(path, resolvedname) == NULL) {
send_status(id, errno_to_portable(errno));
} else {
Stat s;
attrib_clear(&s.attrib);
s.name = s.long_name = resolvedname;
send_names(id, 1, &s);
}
free(path);
}
static void
process_rename(u_int32_t id)
{
char *oldpath, *newpath;
int r, status;
struct stat sb;
if ((r = sshbuf_get_cstring(iqueue, &oldpath, NULL)) != 0 ||
(r = sshbuf_get_cstring(iqueue, &newpath, NULL)) != 0)
fatal_fr(r, "parse");
debug3("request %u: rename", id);
logit("rename old \"%s\" new \"%s\"", oldpath, newpath);
status = SSH2_FX_FAILURE;
if (lstat(oldpath, &sb) == -1)
status = errno_to_portable(errno);
else if (S_ISREG(sb.st_mode)) {
/* Race-free rename of regular files */
if (link(oldpath, newpath) == -1) {
if (errno == EOPNOTSUPP || errno == ENOSYS
#ifdef EXDEV
|| errno == EXDEV
#endif
#ifdef LINK_OPNOTSUPP_ERRNO
|| errno == LINK_OPNOTSUPP_ERRNO
#endif
) {
struct stat st;
/*
* fs doesn't support links, so fall back to
* stat+rename. This is racy.
*/
if (stat(newpath, &st) == -1) {
if (rename(oldpath, newpath) == -1)
status =
errno_to_portable(errno);
else
status = SSH2_FX_OK;
}
} else {
status = errno_to_portable(errno);
}
} else if (unlink(oldpath) == -1) {
status = errno_to_portable(errno);
/* clean spare link */
unlink(newpath);
} else
status = SSH2_FX_OK;
} else if (stat(newpath, &sb) == -1) {
if (rename(oldpath, newpath) == -1)
status = errno_to_portable(errno);
else
status = SSH2_FX_OK;
}
send_status(id, status);
free(oldpath);
free(newpath);
}
static void
process_readlink(u_int32_t id)
{
int r, len;
char buf[PATH_MAX];
char *path;
if ((r = sshbuf_get_cstring(iqueue, &path, NULL)) != 0)
fatal_fr(r, "parse");
debug3("request %u: readlink", id);
verbose("readlink \"%s\"", path);
if ((len = readlink(path, buf, sizeof(buf) - 1)) == -1)
send_status(id, errno_to_portable(errno));
else {
Stat s;
buf[len] = '\0';
attrib_clear(&s.attrib);
s.name = s.long_name = buf;
send_names(id, 1, &s);
}
free(path);
}
static void
process_symlink(u_int32_t id)
{
char *oldpath, *newpath;
int r, status;
if ((r = sshbuf_get_cstring(iqueue, &oldpath, NULL)) != 0 ||
(r = sshbuf_get_cstring(iqueue, &newpath, NULL)) != 0)
fatal_fr(r, "parse");
debug3("request %u: symlink", id);
logit("symlink old \"%s\" new \"%s\"", oldpath, newpath);
/* this will fail if 'newpath' exists */
r = symlink(oldpath, newpath);
status = (r == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
send_status(id, status);
free(oldpath);
free(newpath);
}
static void
process_extended_posix_rename(u_int32_t id)
{
char *oldpath, *newpath;
int r, status;
if ((r = sshbuf_get_cstring(iqueue, &oldpath, NULL)) != 0 ||
(r = sshbuf_get_cstring(iqueue, &newpath, NULL)) != 0)
fatal_fr(r, "parse");
debug3("request %u: posix-rename", id);
logit("posix-rename old \"%s\" new \"%s\"", oldpath, newpath);
r = rename(oldpath, newpath);
status = (r == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
send_status(id, status);
free(oldpath);
free(newpath);
}
static void
process_extended_statvfs(u_int32_t id)
{
char *path;
struct statvfs st;
int r;
if ((r = sshbuf_get_cstring(iqueue, &path, NULL)) != 0)
fatal_fr(r, "parse");
debug3("request %u: statvfs", id);
logit("statvfs \"%s\"", path);
if (statvfs(path, &st) != 0)
send_status(id, errno_to_portable(errno));
else
send_statvfs(id, &st);
free(path);
}
static void
process_extended_fstatvfs(u_int32_t id)
{
int r, handle, fd;
struct statvfs st;
if ((r = get_handle(iqueue, &handle)) != 0)
fatal_fr(r, "parse");
debug("request %u: fstatvfs \"%s\" (handle %u)",
id, handle_to_name(handle), handle);
if ((fd = handle_to_fd(handle)) < 0) {
send_status(id, SSH2_FX_FAILURE);
return;
}
if (fstatvfs(fd, &st) != 0)
send_status(id, errno_to_portable(errno));
else
send_statvfs(id, &st);
}
static void
process_extended_hardlink(u_int32_t id)
{
char *oldpath, *newpath;
int r, status;
if ((r = sshbuf_get_cstring(iqueue, &oldpath, NULL)) != 0 ||
(r = sshbuf_get_cstring(iqueue, &newpath, NULL)) != 0)
fatal_fr(r, "parse");
debug3("request %u: hardlink", id);
logit("hardlink old \"%s\" new \"%s\"", oldpath, newpath);
r = link(oldpath, newpath);
status = (r == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
send_status(id, status);
free(oldpath);
free(newpath);
}
static void
process_extended_fsync(u_int32_t id)
{
int handle, fd, r, status = SSH2_FX_OP_UNSUPPORTED;
if ((r = get_handle(iqueue, &handle)) != 0)
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)
status = SSH2_FX_NO_SUCH_FILE;
else if (handle_is_ok(handle, HANDLE_FILE)) {
r = fsync(fd);
status = (r == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
}
send_status(id, status);
}
static void
process_extended_lsetstat(u_int32_t id)
{
Attrib a;
char *name;
int r, status = SSH2_FX_OK;
if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0 ||
(r = decode_attrib(iqueue, &a)) != 0)
fatal_fr(r, "parse");
debug("request %u: lsetstat name \"%s\"", id, name);
if (a.flags & SSH2_FILEXFER_ATTR_SIZE) {
/* nonsensical for links */
status = SSH2_FX_BAD_MESSAGE;
goto out;
}
if (a.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) {
logit("set \"%s\" mode %04o", name, a.perm);
r = fchmodat(AT_FDCWD, name,
a.perm & 07777, AT_SYMLINK_NOFOLLOW);
if (r == -1)
status = errno_to_portable(errno);
}
if (a.flags & SSH2_FILEXFER_ATTR_ACMODTIME) {
char buf[64];
time_t t = a.mtime;
strftime(buf, sizeof(buf), "%Y%m%d-%H:%M:%S",
localtime(&t));
logit("set \"%s\" modtime %s", name, buf);
r = utimensat(AT_FDCWD, name,
attrib_to_ts(&a), AT_SYMLINK_NOFOLLOW);
if (r == -1)
status = errno_to_portable(errno);
}
if (a.flags & SSH2_FILEXFER_ATTR_UIDGID) {
logit("set \"%s\" owner %lu group %lu", name,
(u_long)a.uid, (u_long)a.gid);
r = fchownat(AT_FDCWD, name, a.uid, a.gid,
AT_SYMLINK_NOFOLLOW);
if (r == -1)
status = errno_to_portable(errno);
}
out:
send_status(id, status);
free(name);
}
static void
process_extended_limits(u_int32_t id)
{
struct sshbuf *msg;
int r;
uint64_t nfiles = 0;
#if defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE)
struct rlimit rlim;
#endif
debug("request %u: limits", id);
#if defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE)
if (getrlimit(RLIMIT_NOFILE, &rlim) != -1 && rlim.rlim_cur > 5)
nfiles = rlim.rlim_cur - 5; /* stdio(3) + syslog + spare */
#endif
if ((msg = sshbuf_new()) == NULL)
fatal_f("sshbuf_new failed");
if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED_REPLY)) != 0 ||
(r = sshbuf_put_u32(msg, id)) != 0 ||
/* max-packet-length */
(r = sshbuf_put_u64(msg, SFTP_MAX_MSG_LENGTH)) != 0 ||
/* max-read-length */
(r = sshbuf_put_u64(msg, SFTP_MAX_READ_LENGTH)) != 0 ||
/* max-write-length */
(r = sshbuf_put_u64(msg, SFTP_MAX_MSG_LENGTH - 1024)) != 0 ||
/* max-open-handles */
(r = sshbuf_put_u64(msg, nfiles)) != 0)
fatal_fr(r, "compose");
send_msg(msg);
sshbuf_free(msg);
}
static void
process_extended_expand(u_int32_t id)
{
char cwd[PATH_MAX], resolvedname[PATH_MAX];
char *path, *npath;
int r;
Stat s;
if ((r = sshbuf_get_cstring(iqueue, &path, NULL)) != 0)
fatal_fr(r, "parse");
if (getcwd(cwd, sizeof(cwd)) == NULL) {
send_status(id, errno_to_portable(errno));
goto out;
}
debug3("request %u: expand, original \"%s\"", id, path);
if (path[0] == '\0') {
/* empty path */
free(path);
path = xstrdup(".");
} else if (*path == '~') {
/* ~ expand path */
/* Special-case for "~" and "~/" to respect homedir flag */
if (strcmp(path, "~") == 0) {
free(path);
path = xstrdup(cwd);
} else if (strncmp(path, "~/", 2) == 0) {
npath = xstrdup(path + 2);
free(path);
xasprintf(&path, "%s/%s", cwd, npath);
free(npath);
} else {
/* ~user expansions */
if (tilde_expand(path, pw->pw_uid, &npath) != 0) {
send_status_errmsg(id,
errno_to_portable(ENOENT), "no such user");
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_copy_data(u_int32_t id)
{
u_char buf[64*1024];
int read_handle, read_fd, write_handle, write_fd;
u_int64_t len, read_off, read_len, write_off;
int r, copy_until_eof, status = SSH2_FX_OP_UNSUPPORTED;
size_t ret;
if ((r = get_handle(iqueue, &read_handle)) != 0 ||
(r = sshbuf_get_u64(iqueue, &read_off)) != 0 ||
(r = sshbuf_get_u64(iqueue, &read_len)) != 0 ||
(r = get_handle(iqueue, &write_handle)) != 0 ||
(r = sshbuf_get_u64(iqueue, &write_off)) != 0)
fatal("%s: buffer error: %s", __func__, ssh_err(r));
debug("request %u: copy-data from \"%s\" (handle %d) off %llu len %llu "
"to \"%s\" (handle %d) off %llu",
id, handle_to_name(read_handle), read_handle,
(unsigned long long)read_off, (unsigned long long)read_len,
handle_to_name(write_handle), write_handle,
(unsigned long long)write_off);
/* For read length of 0, we read until EOF. */
if (read_len == 0) {
read_len = (u_int64_t)-1 - read_off;
copy_until_eof = 1;
} else
copy_until_eof = 0;
read_fd = handle_to_fd(read_handle);
write_fd = handle_to_fd(write_handle);
/* Disallow reading & writing to the same handle or same path or dirs */
if (read_handle == write_handle || read_fd < 0 || write_fd < 0 ||
!strcmp(handle_to_name(read_handle), handle_to_name(write_handle))) {
status = SSH2_FX_FAILURE;
goto out;
}
if (lseek(read_fd, read_off, SEEK_SET) < 0) {
status = errno_to_portable(errno);
error("%s: read_seek failed", __func__);
goto out;
}
if ((handle_to_flags(write_handle) & O_APPEND) == 0 &&
lseek(write_fd, write_off, SEEK_SET) < 0) {
status = errno_to_portable(errno);
error("%s: write_seek failed", __func__);
goto out;
}
/* Process the request in chunks. */
while (read_len > 0 || copy_until_eof) {
len = MINIMUM(sizeof(buf), read_len);
read_len -= len;
ret = atomicio(read, read_fd, buf, len);
if (ret == 0 && errno == EPIPE) {
status = copy_until_eof ? SSH2_FX_OK : SSH2_FX_EOF;
break;
} else if (ret == 0) {
status = errno_to_portable(errno);
error("%s: read failed: %s", __func__, strerror(errno));
break;
}
len = ret;
handle_update_read(read_handle, len);
ret = atomicio(vwrite, write_fd, buf, len);
if (ret != len) {
status = errno_to_portable(errno);
error("%s: write failed: %llu != %llu: %s", __func__,
(unsigned long long)ret, (unsigned long long)len,
strerror(errno));
break;
}
handle_update_write(write_handle, len);
}
if (read_len == 0)
status = SSH2_FX_OK;
out:
send_status(id, status);
}
static void
process_extended_home_directory(u_int32_t id)
{
char *username;
struct passwd *user_pw;
int r;
Stat s;
if ((r = sshbuf_get_cstring(iqueue, &username, NULL)) != 0)
fatal_fr(r, "parse");
debug3("request %u: home-directory \"%s\"", id, username);
if ((user_pw = getpwnam(username)) == NULL) {
send_status(id, SSH2_FX_FAILURE);
goto out;
}
verbose("home-directory \"%s\"", pw->pw_dir);
attrib_clear(&s.attrib);
s.name = s.long_name = pw->pw_dir;
send_names(id, 1, &s);
out:
free(username);
}
static void
process_extended_get_users_groups_by_id(u_int32_t id)
{
struct passwd *user_pw;
struct group *gr;
struct sshbuf *uids, *gids, *usernames, *groupnames, *msg;
int r;
u_int n, nusers = 0, ngroups = 0;
const char *name;
if ((usernames = sshbuf_new()) == NULL ||
(groupnames = sshbuf_new()) == NULL ||
(msg = sshbuf_new()) == NULL)
fatal_f("sshbuf_new failed");
if ((r = sshbuf_froms(iqueue, &uids)) != 0 ||
(r = sshbuf_froms(iqueue, &gids)) != 0)
fatal_fr(r, "parse");
debug_f("uids len = %zu, gids len = %zu",
sshbuf_len(uids), sshbuf_len(gids));
while (sshbuf_len(uids) != 0) {
if ((r = sshbuf_get_u32(uids, &n)) != 0)
fatal_fr(r, "parse inner uid");
user_pw = getpwuid((uid_t)n);
name = user_pw == NULL ? "" : user_pw->pw_name;
debug3_f("uid %u => \"%s\"", n, name);
if ((r = sshbuf_put_cstring(usernames, name)) != 0)
- fatal_fr(r, "assemble gid reply");
+ fatal_fr(r, "assemble uid reply");
nusers++;
}
while (sshbuf_len(gids) != 0) {
if ((r = sshbuf_get_u32(gids, &n)) != 0)
fatal_fr(r, "parse inner gid");
gr = getgrgid((gid_t)n);
name = gr == NULL ? "" : gr->gr_name;
debug3_f("gid %u => \"%s\"", n, name);
if ((r = sshbuf_put_cstring(groupnames, name)) != 0)
fatal_fr(r, "assemble gid reply");
nusers++;
}
verbose("users-groups-by-id: %u users, %u groups", nusers, ngroups);
if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED_REPLY)) != 0 ||
(r = sshbuf_put_u32(msg, id)) != 0 ||
(r = sshbuf_put_stringb(msg, usernames)) != 0 ||
(r = sshbuf_put_stringb(msg, groupnames)) != 0)
fatal_fr(r, "compose");
send_msg(msg);
sshbuf_free(uids);
sshbuf_free(gids);
sshbuf_free(usernames);
sshbuf_free(groupnames);
sshbuf_free(msg);
}
static void
process_extended(u_int32_t id)
{
char *request;
int r;
const struct sftp_handler *exthand;
if ((r = sshbuf_get_cstring(iqueue, &request, NULL)) != 0)
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);
}
/* stolen from ssh-agent */
static void
process(void)
{
u_int msg_len;
u_int buf_len;
u_int consumed;
u_char type;
const u_char *cp;
int i, r;
u_int32_t id;
buf_len = sshbuf_len(iqueue);
if (buf_len < 5)
return; /* Incomplete message. */
cp = sshbuf_ptr(iqueue);
msg_len = get_u32(cp);
if (msg_len > SFTP_MAX_MSG_LENGTH) {
error("bad message from %s local user %s",
client_addr, pw->pw_name);
sftp_server_cleanup_exit(11);
}
if (buf_len < msg_len + 4)
return;
if ((r = sshbuf_consume(iqueue, 4)) != 0)
fatal_fr(r, "consume");
buf_len -= 4;
if ((r = sshbuf_get_u8(iqueue, &type)) != 0)
fatal_fr(r, "parse type");
switch (type) {
case SSH2_FXP_INIT:
process_init();
init_done = 1;
break;
case SSH2_FXP_EXTENDED:
if (!init_done)
fatal("Received extended request before init");
if ((r = sshbuf_get_u32(iqueue, &id)) != 0)
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_fr(r, "parse ID");
for (i = 0; handlers[i].handler != NULL; i++) {
if (type == handlers[i].type) {
if (!request_permitted(&handlers[i])) {
send_status(id,
SSH2_FX_PERMISSION_DENIED);
} else {
handlers[i].handler(id);
}
break;
}
}
if (handlers[i].handler == NULL)
error("Unknown message %u", type);
}
/* discard the remaining bytes from the current packet */
if (buf_len < sshbuf_len(iqueue)) {
error("iqueue grew unexpectedly");
sftp_server_cleanup_exit(255);
}
consumed = buf_len - sshbuf_len(iqueue);
if (msg_len < consumed) {
error("msg_len %u < consumed %u", msg_len, consumed);
sftp_server_cleanup_exit(255);
}
if (msg_len > consumed &&
(r = sshbuf_consume(iqueue, msg_len - consumed)) != 0)
fatal_fr(r, "consume");
}
/* Cleanup handler that logs active handles upon normal exit */
void
sftp_server_cleanup_exit(int i)
{
if (pw != NULL && client_addr != NULL) {
handle_log_exit();
logit("session closed for local user %s from [%s]",
pw->pw_name, client_addr);
}
_exit(i);
}
static void
sftp_server_usage(void)
{
extern char *__progname;
fprintf(stderr,
"usage: %s [-ehR] [-d start_directory] [-f log_facility] "
"[-l log_level]\n\t[-P denied_requests] "
"[-p allowed_requests] [-u umask]\n"
" %s -Q protocol_feature\n",
__progname, __progname);
exit(1);
}
int
sftp_server_main(int argc, char **argv, struct passwd *user_pw)
{
int i, r, in, out, ch, skipargs = 0, log_stderr = 0;
ssize_t len, olen;
SyslogFacility log_facility = SYSLOG_FACILITY_AUTH;
char *cp, *homedir = NULL, uidstr[32], buf[4*4096];
long mask;
extern char *optarg;
extern char *__progname;
__progname = ssh_get_progname(argv[0]);
log_init(__progname, log_level, log_facility, log_stderr);
pw = pwcopy(user_pw);
while (!skipargs && (ch = getopt(argc, argv,
"d:f:l:P:p:Q:u:cehR")) != -1) {
switch (ch) {
case 'Q':
if (strcasecmp(optarg, "requests") != 0) {
fprintf(stderr, "Invalid query type\n");
exit(1);
}
for (i = 0; handlers[i].handler != NULL; i++)
printf("%s\n", handlers[i].name);
for (i = 0; extended_handlers[i].handler != NULL; i++)
printf("%s\n", extended_handlers[i].name);
exit(0);
break;
case 'R':
readonly = 1;
break;
case 'c':
/*
* Ignore all arguments if we are invoked as a
* shell using "sftp-server -c command"
*/
skipargs = 1;
break;
case 'e':
log_stderr = 1;
break;
case 'l':
log_level = log_level_number(optarg);
if (log_level == SYSLOG_LEVEL_NOT_SET)
error("Invalid log level \"%s\"", optarg);
break;
case 'f':
log_facility = log_facility_number(optarg);
if (log_facility == SYSLOG_FACILITY_NOT_SET)
error("Invalid log facility \"%s\"", optarg);
break;
case 'd':
cp = tilde_expand_filename(optarg, user_pw->pw_uid);
snprintf(uidstr, sizeof(uidstr), "%llu",
(unsigned long long)pw->pw_uid);
homedir = percent_expand(cp, "d", user_pw->pw_dir,
"u", user_pw->pw_name, "U", uidstr, (char *)NULL);
free(cp);
break;
case 'p':
if (request_allowlist != NULL)
fatal("Permitted requests already set");
request_allowlist = xstrdup(optarg);
break;
case 'P':
if (request_denylist != NULL)
fatal("Refused requests already set");
request_denylist = xstrdup(optarg);
break;
case 'u':
errno = 0;
mask = strtol(optarg, &cp, 8);
if (mask < 0 || mask > 0777 || *cp != '\0' ||
cp == optarg || (mask == 0 && errno != 0))
fatal("Invalid umask \"%s\"", optarg);
(void)umask((mode_t)mask);
break;
case 'h':
default:
sftp_server_usage();
}
}
log_init(__progname, log_level, log_facility, log_stderr);
/*
* On platforms where we can, avoid making /proc/self/{mem,maps}
* available to the user so that sftp access doesn't automatically
* imply arbitrary code execution access that will break
* restricted configurations.
*/
platform_disable_tracing(1); /* strict */
/* Drop any fine-grained privileges we don't need */
platform_pledge_sftp_server();
if ((cp = getenv("SSH_CONNECTION")) != NULL) {
client_addr = xstrdup(cp);
if ((cp = strchr(client_addr, ' ')) == NULL) {
error("Malformed SSH_CONNECTION variable: \"%s\"",
getenv("SSH_CONNECTION"));
sftp_server_cleanup_exit(255);
}
*cp = '\0';
} else
client_addr = xstrdup("UNKNOWN");
logit("session opened for local user %s from [%s]",
pw->pw_name, client_addr);
in = STDIN_FILENO;
out = STDOUT_FILENO;
#ifdef HAVE_CYGWIN
setmode(in, O_BINARY);
setmode(out, O_BINARY);
#endif
if ((iqueue = sshbuf_new()) == NULL)
fatal_f("sshbuf_new failed");
if ((oqueue = sshbuf_new()) == NULL)
fatal_f("sshbuf_new failed");
if (homedir != NULL) {
if (chdir(homedir) != 0) {
error("chdir to \"%s\" failed: %s", homedir,
strerror(errno));
}
}
for (;;) {
struct pollfd pfd[2];
memset(pfd, 0, sizeof pfd);
pfd[0].fd = pfd[1].fd = -1;
/*
* Ensure that we can read a full buffer and handle
* the worst-case length packet it can generate,
* otherwise apply backpressure by stopping reads.
*/
if ((r = sshbuf_check_reserve(iqueue, sizeof(buf))) == 0 &&
(r = sshbuf_check_reserve(oqueue,
SFTP_MAX_MSG_LENGTH)) == 0) {
pfd[0].fd = in;
pfd[0].events = POLLIN;
}
else if (r != SSH_ERR_NO_BUFFER_SPACE)
fatal_fr(r, "reserve");
olen = sshbuf_len(oqueue);
if (olen > 0) {
pfd[1].fd = out;
pfd[1].events = POLLOUT;
}
if (poll(pfd, 2, -1) == -1) {
if (errno == EINTR)
continue;
error("poll: %s", strerror(errno));
sftp_server_cleanup_exit(2);
}
/* copy stdin to iqueue */
if (pfd[0].revents & (POLLIN|POLLHUP)) {
len = read(in, buf, sizeof buf);
if (len == 0) {
debug("read eof");
sftp_server_cleanup_exit(0);
} else if (len == -1) {
if (errno != EAGAIN && errno != EINTR) {
error("read: %s", strerror(errno));
sftp_server_cleanup_exit(1);
}
} else if ((r = sshbuf_put(iqueue, buf, len)) != 0)
fatal_fr(r, "sshbuf_put");
}
/* send oqueue to stdout */
if (pfd[1].revents & (POLLOUT|POLLHUP)) {
len = write(out, sshbuf_ptr(oqueue), olen);
if (len == 0 || (len == -1 && errno == EPIPE)) {
debug("write eof");
sftp_server_cleanup_exit(0);
} else if (len == -1) {
sftp_server_cleanup_exit(1);
if (errno != EAGAIN && errno != EINTR) {
error("write: %s", strerror(errno));
sftp_server_cleanup_exit(1);
}
} else if ((r = sshbuf_consume(oqueue, len)) != 0)
fatal_fr(r, "consume");
}
/*
* Process requests from client if we can fit the results
* into the output buffer, otherwise stop processing input
* and let the output queue drain.
*/
r = sshbuf_check_reserve(oqueue, SFTP_MAX_MSG_LENGTH);
if (r == 0)
process();
else if (r != SSH_ERR_NO_BUFFER_SPACE)
fatal_fr(r, "reserve");
}
}
diff --git a/crypto/openssh/sftp.1 b/crypto/openssh/sftp.1
index 3b3f2c5a7917..68923ae20b19 100644
--- a/crypto/openssh/sftp.1
+++ b/crypto/openssh/sftp.1
@@ -1,714 +1,728 @@
-.\" $OpenBSD: sftp.1,v 1.142 2022/09/19 21:39:16 djm Exp $
+.\" $OpenBSD: sftp.1,v 1.143 2022/12/16 03:40:03 djm Exp $
.\"
.\" 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.
.\"
-.Dd $Mdocdate: September 19 2022 $
+.Dd $Mdocdate: December 16 2022 $
.Dt SFTP 1
.Os
.Sh NAME
.Nm sftp
.Nd OpenSSH secure file transfer
.Sh SYNOPSIS
.Nm sftp
.Op Fl 46AaCfNpqrv
.Op Fl B Ar buffer_size
.Op Fl b Ar batchfile
.Op Fl c Ar cipher
.Op Fl D Ar sftp_server_command
.Op Fl F Ar ssh_config
.Op Fl i Ar identity_file
.Op Fl J Ar destination
.Op Fl l Ar limit
.Op Fl o Ar ssh_option
.Op Fl P Ar port
.Op Fl R Ar num_requests
.Op Fl S Ar program
.Op Fl s Ar subsystem | sftp_server
+.Op Fl X Ar sftp_option
.Ar destination
.Sh DESCRIPTION
.Nm
is a file transfer program, similar to
.Xr ftp 1 ,
which performs all operations over an encrypted
.Xr ssh 1
transport.
It may also use many features of ssh, such as public key authentication and
compression.
.Pp
The
.Ar destination
may be specified either as
.Sm off
.Oo user @ Oc host Op : path
.Sm on
or as a URI in the form
.Sm off
.No sftp:// Oo user @ Oc host Oo : port Oc Op / path .
.Sm on
.Pp
If the
.Ar destination
includes a
.Ar path
and it is not a directory,
.Nm
will retrieve files automatically if a non-interactive
authentication method is used; otherwise it will do so after
successful interactive authentication.
.Pp
If no
.Ar path
is specified, or if the
.Ar path
is a directory,
.Nm
will log in to the specified
.Ar host
and enter interactive command mode, changing to the remote directory
if one was specified.
An optional trailing slash can be used to force the
.Ar path
to be interpreted as a directory.
.Pp
Since the destination formats use colon characters to delimit host
names from path names or port numbers, IPv6 addresses must be
enclosed in square brackets to avoid ambiguity.
.Pp
The options are as follows:
.Bl -tag -width Ds
.It Fl 4
Forces
.Nm
to use IPv4 addresses only.
.It Fl 6
Forces
.Nm
to use IPv6 addresses only.
.It Fl A
Allows forwarding of
.Xr ssh-agent 1
to the remote system.
The default is not to forward an authentication agent.
.It Fl a
Attempt to continue interrupted transfers rather than overwriting
existing partial or complete copies of files.
If the partial contents differ from those being transferred,
then the resultant file is likely to be corrupt.
.It Fl B Ar buffer_size
Specify the size of the buffer that
.Nm
uses when transferring files.
Larger buffers require fewer round trips at the cost of higher
memory consumption.
The default is 32768 bytes.
.It Fl b Ar batchfile
Batch mode reads a series of commands from an input
.Ar batchfile
instead of
.Em stdin .
Since it lacks user interaction, it should be used in conjunction with
non-interactive authentication to obviate the need to enter a password
at connection time (see
.Xr sshd 8
and
.Xr ssh-keygen 1
for details).
.Pp
A
.Ar batchfile
of
.Sq \-
may be used to indicate standard input.
.Nm
will abort if any of the following
commands fail:
.Ic get , put , reget , reput , rename , ln ,
.Ic rm , mkdir , chdir , ls ,
.Ic lchdir , copy , cp , chmod , chown ,
.Ic chgrp , lpwd , df , symlink ,
and
.Ic lmkdir .
.Pp
Termination on error can be suppressed on a command by command basis by
prefixing the command with a
.Sq \-
character (for example,
.Ic -rm /tmp/blah* ) .
Echo of the command may be suppressed by prefixing the command with a
.Sq @
character.
These two prefixes may be combined in any order, for example
.Ic -@ls /bsd .
.It Fl C
Enables compression (via ssh's
.Fl C
flag).
.It Fl c Ar cipher
Selects the cipher to use for encrypting the data transfers.
This option is directly passed to
.Xr ssh 1 .
.It Fl D Ar sftp_server_command
Connect directly to a local sftp server
(rather than via
.Xr ssh 1 ) .
A command and arguments may be specified, for example
.Qq /path/sftp-server -el debug3 .
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
.Xr ssh 1 .
This option is directly passed to
.Xr ssh 1 .
.It Fl f
Requests that files be flushed to disk immediately after transfer.
When uploading files, this feature is only enabled if the server
implements the "fsync@openssh.com" extension.
.It Fl i Ar identity_file
Selects the file from which the identity (private key) for public key
authentication is read.
This option is directly passed to
.Xr ssh 1 .
.It Fl J Ar destination
Connect to the target host by first making an
.Nm
connection to the jump host described by
.Ar destination
and then establishing a TCP forwarding to the ultimate destination from
there.
Multiple jump hops may be specified separated by comma characters.
This is a shortcut to specify a
.Cm ProxyJump
configuration directive.
This option is directly passed to
.Xr ssh 1 .
.It Fl l Ar limit
Limits the used bandwidth, specified in Kbit/s.
.It Fl N
Disables quiet mode, e.g. to override the implicit quiet mode set by the
.Fl b
flag.
.It Fl o Ar ssh_option
Can be used to pass options to
.Nm ssh
in the format used in
.Xr ssh_config 5 .
This is useful for specifying options
for which there is no separate
.Nm sftp
command-line flag.
For example, to specify an alternate port use:
.Ic sftp -oPort=24 .
For full details of the options listed below, and their possible values, see
.Xr ssh_config 5 .
.Pp
.Bl -tag -width Ds -offset indent -compact
.It AddressFamily
.It BatchMode
.It BindAddress
.It BindInterface
.It CanonicalDomains
.It CanonicalizeFallbackLocal
.It CanonicalizeHostname
.It CanonicalizeMaxDots
.It CanonicalizePermittedCNAMEs
.It CASignatureAlgorithms
.It CertificateFile
.It CheckHostIP
.It Ciphers
.It Compression
.It ConnectionAttempts
.It ConnectTimeout
.It ControlMaster
.It ControlPath
.It ControlPersist
.It GlobalKnownHostsFile
.It GSSAPIAuthentication
.It GSSAPIDelegateCredentials
.It HashKnownHosts
.It Host
.It HostbasedAcceptedAlgorithms
.It HostbasedAuthentication
.It HostKeyAlgorithms
.It HostKeyAlias
.It Hostname
.It IdentitiesOnly
.It IdentityAgent
.It IdentityFile
.It IPQoS
.It KbdInteractiveAuthentication
.It KbdInteractiveDevices
.It KexAlgorithms
.It KnownHostsCommand
.It LogLevel
.It MACs
.It NoHostAuthenticationForLocalhost
.It NumberOfPasswordPrompts
.It PasswordAuthentication
.It PKCS11Provider
.It Port
.It PreferredAuthentications
.It ProxyCommand
.It ProxyJump
.It PubkeyAcceptedAlgorithms
.It PubkeyAuthentication
.It RekeyLimit
.It RequiredRSASize
.It SendEnv
.It ServerAliveInterval
.It ServerAliveCountMax
.It SetEnv
.It StrictHostKeyChecking
.It TCPKeepAlive
.It UpdateHostKeys
.It User
.It UserKnownHostsFile
.It VerifyHostKeyDNS
.El
.It Fl P Ar port
Specifies the port to connect to on the remote host.
.It Fl p
Preserves modification times, access times, and modes from the
original files transferred.
.It Fl q
Quiet mode: disables the progress meter as well as warning and
diagnostic messages from
.Xr ssh 1 .
.It Fl R Ar num_requests
Specify how many requests may be outstanding at any one time.
Increasing this may slightly improve file transfer speed
but will increase memory usage.
The default is 64 outstanding requests.
.It Fl r
Recursively copy entire directories when uploading and downloading.
Note that
.Nm
does not follow symbolic links encountered in the tree traversal.
.It Fl S Ar program
Name of the
.Ar program
to use for the encrypted connection.
The program must understand
.Xr ssh 1
options.
.It Fl s Ar subsystem | sftp_server
Specifies the SSH2 subsystem or the path for an sftp server
on the remote host.
A path is useful when the remote
.Xr sshd 8
does not have an sftp subsystem configured.
.It Fl v
Raise logging level.
This option is also passed to ssh.
+.It Fl X Ar sftp_option
+Specify an option that controls aspects of SFTP protocol behaviour.
+The valid options are:
+.Bl -tag -width Ds
+.It Cm nrequests Ns = Ns Ar value
+Controls how many concurrent SFTP read or write requests may be in progress
+at any point in time during a download or upload.
+By default 64 requests may be active concurrently.
+.It Cm buffer Ns = Ns Ar value
+Controls the maximum buffer size for a single SFTP read/write operation used
+during download or upload.
+By default a 32KB buffer is used.
+.El
.El
.Sh INTERACTIVE COMMANDS
Once in interactive mode,
.Nm
understands a set of commands similar to those of
.Xr ftp 1 .
Commands are case insensitive.
Pathnames that contain spaces must be enclosed in quotes.
Any special characters contained within pathnames that are recognized by
.Xr glob 3
must be escaped with backslashes
.Pq Sq \e .
.Bl -tag -width Ds
.It Ic bye
Quit
.Nm sftp .
.It Ic cd Op Ar path
Change remote directory to
.Ar path .
If
.Ar path
is not specified, then change directory to the one the session started in.
.It Xo Ic chgrp
.Op Fl h
.Ar grp
.Ar path
.Xc
Change group of file
.Ar path
to
.Ar grp .
.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
.Ar path
.Xc
Change permissions of file
.Ar path
to
.Ar mode .
.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
.Ar path
.Xc
Change owner of file
.Ar path
to
.Ar own .
.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 Ic copy Ar oldpath Ar newpath
Copy remote file from
.Ar oldpath
to
.Ar newpath .
.Pp
Note that this is only supported by servers that implement the "copy-data"
extension.
.It Ic cp Ar oldpath Ar newpath
Alias to
.Ic copy
command.
.It Xo Ic df
.Op Fl hi
.Op Ar path
.Xc
Display usage information for the filesystem holding the current directory
(or
.Ar path
if specified).
If the
.Fl h
flag is specified, the capacity information will be displayed using
"human-readable" suffixes.
The
.Fl i
flag requests display of inode information in addition to capacity information.
This command is only supported on servers that implement the
.Dq statvfs@openssh.com
extension.
.It Ic exit
Quit
.Nm sftp .
.It Xo Ic get
.Op Fl afpR
.Ar remote-path
.Op Ar local-path
.Xc
Retrieve the
.Ar remote-path
and store it on the local machine.
If the local
path name is not specified, it is given the same name it has on the
remote machine.
.Ar remote-path
may contain
.Xr glob 7
characters and may match multiple files.
If it does and
.Ar local-path
is specified, then
.Ar local-path
must specify a directory.
.Pp
If the
.Fl a
flag is specified, then attempt to resume partial transfers of existing files.
Note that resumption assumes that any partial copy of the local file matches
the remote copy.
If the remote file contents differ from the partial local copy then the
resultant file is likely to be corrupt.
.Pp
If the
.Fl f
flag is specified, then
.Xr fsync 2
will be called after the file transfer has completed to flush the file
to disk.
.Pp
If the
.Fl p
.\" undocumented redundant alias
.\" or
.\" .Fl P
flag is specified, then full file permissions and access times are
copied too.
.Pp
If the
.Fl R
.\" undocumented redundant alias
.\" or
.\" .Fl r
flag is specified then directories will be copied recursively.
Note that
.Nm
does not follow symbolic links when performing recursive transfers.
.It Ic help
Display help text.
.It Ic lcd Op Ar path
Change local directory to
.Ar path .
If
.Ar path
is not specified, then change directory to the local user's home directory.
.It Ic lls Op Ar ls-options Op Ar path
Display local directory listing of either
.Ar path
or current directory if
.Ar path
is not specified.
.Ar ls-options
may contain any flags supported by the local system's
.Xr ls 1
command.
.Ar path
may contain
.Xr glob 7
characters and may match multiple files.
.It Ic lmkdir Ar path
Create local directory specified by
.Ar path .
.It Xo Ic ln
.Op Fl s
.Ar oldpath
.Ar newpath
.Xc
Create a link from
.Ar oldpath
to
.Ar newpath .
If the
.Fl s
flag is specified the created link is a symbolic link, otherwise it is
a hard link.
.It Ic lpwd
Print local working directory.
.It Xo Ic ls
.Op Fl 1afhlnrSt
.Op Ar path
.Xc
Display a remote directory listing of either
.Ar path
or the current directory if
.Ar path
is not specified.
.Ar path
may contain
.Xr glob 7
characters and may match multiple files.
.Pp
The following flags are recognized and alter the behaviour of
.Ic ls
accordingly:
.Bl -tag -width Ds
.It Fl 1
Produce single columnar output.
.It Fl a
List files beginning with a dot
.Pq Sq \&. .
.It Fl f
Do not sort the listing.
The default sort order is lexicographical.
.It Fl h
When used with a long format option, use unit suffixes: Byte, Kilobyte,
Megabyte, Gigabyte, Terabyte, Petabyte, and Exabyte in order to reduce
the number of digits to four or fewer using powers of 2 for sizes (K=1024,
M=1048576, etc.).
.It Fl l
Display additional details including permissions
and ownership information.
.It Fl n
Produce a long listing with user and group information presented
numerically.
.It Fl r
Reverse the sort order of the listing.
.It Fl S
Sort the listing by file size.
.It Fl t
Sort the listing by last modification time.
.El
.It Ic lumask Ar umask
Set local umask to
.Ar umask .
.It Ic mkdir Ar path
Create remote directory specified by
.Ar path .
.It Ic progress
Toggle display of progress meter.
.It Xo Ic put
.Op Fl afpR
.Ar local-path
.Op Ar remote-path
.Xc
Upload
.Ar local-path
and store it on the remote machine.
If the remote path name is not specified, it is given the same name it has
on the local machine.
.Ar local-path
may contain
.Xr glob 7
characters and may match multiple files.
If it does and
.Ar remote-path
is specified, then
.Ar remote-path
must specify a directory.
.Pp
If the
.Fl a
flag is specified, then attempt to resume partial
transfers of existing files.
Note that resumption assumes that any partial copy of the remote file
matches the local copy.
If the local file contents differ from the remote local copy then
the resultant file is likely to be corrupt.
.Pp
If the
.Fl f
flag is specified, then a request will be sent to the server to call
.Xr fsync 2
after the file has been transferred.
Note that this is only supported by servers that implement
the "fsync@openssh.com" extension.
.Pp
If the
.Fl p
.\" undocumented redundant alias
.\" or
.\" .Fl P
flag is specified, then full file permissions and access times are
copied too.
.Pp
If the
.Fl R
.\" undocumented redundant alias
.\" or
.\" .Fl r
flag is specified then directories will be copied recursively.
Note that
.Nm
does not follow symbolic links when performing recursive transfers.
.It Ic pwd
Display remote working directory.
.It Ic quit
Quit
.Nm sftp .
.It Xo Ic reget
.Op Fl fpR
.Ar remote-path
.Op Ar local-path
.Xc
Resume download of
.Ar remote-path .
Equivalent to
.Ic get
with the
.Fl a
flag set.
.It Xo Ic reput
.Op Fl fpR
.Ar local-path
.Op Ar remote-path
.Xc
Resume upload of
.Ar local-path .
Equivalent to
.Ic put
with the
.Fl a
flag set.
.It Ic rename Ar oldpath newpath
Rename remote file from
.Ar oldpath
to
.Ar newpath .
.It Ic rm Ar path
Delete remote file specified by
.Ar path .
.It Ic rmdir Ar path
Remove remote directory specified by
.Ar path .
.It Ic symlink Ar oldpath newpath
Create a symbolic link from
.Ar oldpath
to
.Ar newpath .
.It Ic version
Display the
.Nm
protocol version.
.It Ic \&! Ns Ar command
Execute
.Ar command
in local shell.
.It Ic \&!
Escape to local shell.
.It Ic \&?
Synonym for help.
.El
.Sh SEE ALSO
.Xr ftp 1 ,
.Xr ls 1 ,
.Xr scp 1 ,
.Xr ssh 1 ,
.Xr ssh-add 1 ,
.Xr ssh-keygen 1 ,
.Xr ssh_config 5 ,
.Xr glob 7 ,
.Xr sftp-server 8 ,
.Xr sshd 8
.Rs
.%A T. Ylonen
.%A S. Lehtinen
.%T "SSH File Transfer Protocol"
.%N draft-ietf-secsh-filexfer-00.txt
.%D January 2001
.%O work in progress material
.Re
diff --git a/crypto/openssh/sftp.c b/crypto/openssh/sftp.c
index c3c347e087e4..b3616c15cd09 100644
--- a/crypto/openssh/sftp.c
+++ b/crypto/openssh/sftp.c
@@ -1,2656 +1,2682 @@
-/* $OpenBSD: sftp.c,v 1.222 2022/09/19 10:46:00 djm Exp $ */
+/* $OpenBSD: sftp.c,v 1.225 2023/01/05 05:49:13 djm Exp $ */
/*
* Copyright (c) 2001-2004 Damien Miller <djm@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/types.h>
#include <sys/ioctl.h>
#ifdef HAVE_SYS_STAT_H
# include <sys/stat.h>
#endif
#include <sys/socket.h>
#include <sys/wait.h>
#ifdef HAVE_SYS_STATVFS_H
#include <sys/statvfs.h>
#endif
#include <ctype.h>
#include <errno.h>
#ifdef HAVE_PATHS_H
# include <paths.h>
#endif
#ifdef HAVE_LIBGEN_H
#include <libgen.h>
#endif
#ifdef HAVE_LOCALE_H
# include <locale.h>
#endif
#ifdef USE_LIBEDIT
#include <histedit.h>
#else
typedef void EditLine;
#endif
#include <limits.h>
#include <signal.h>
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#ifdef HAVE_UTIL_H
# include <util.h>
#endif
#include "xmalloc.h"
#include "log.h"
#include "pathnames.h"
#include "misc.h"
#include "utf8.h"
#include "sftp.h"
#include "ssherr.h"
#include "sshbuf.h"
#include "sftp-common.h"
#include "sftp-client.h"
#include "sftp-usergroup.h"
/* File to read commands from */
FILE* infile;
/* Are we in batchfile mode? */
int batchmode = 0;
/* PID of ssh transport process */
static volatile pid_t sshpid = -1;
/* Suppress diagnostic messages */
int quiet = 0;
/* This is set to 0 if the progressmeter is not desired. */
int showprogress = 1;
/* When this option is set, we always recursively download/upload directories */
int global_rflag = 0;
/* When this option is set, we resume download or upload if possible */
int global_aflag = 0;
/* When this option is set, the file transfers will always preserve times */
int global_pflag = 0;
/* When this option is set, transfers will have fsync() called on each file */
int global_fflag = 0;
/* SIGINT received during command processing */
volatile sig_atomic_t interrupted = 0;
/* I wish qsort() took a separate ctx for the comparison function...*/
int sort_flag;
glob_t *sort_glob;
/* Context used for commandline completion */
struct complete_ctx {
struct sftp_conn *conn;
char **remote_pathp;
};
int remote_glob(struct sftp_conn *, const char *, int,
int (*)(const char *, int), glob_t *); /* proto for sftp-glob.c */
extern char *__progname;
/* Separators for interactive commands */
#define WHITESPACE " \t\r\n"
/* ls flags */
#define LS_LONG_VIEW 0x0001 /* Full view ala ls -l */
#define LS_SHORT_VIEW 0x0002 /* Single row view ala ls -1 */
#define LS_NUMERIC_VIEW 0x0004 /* Long view with numeric uid/gid */
#define LS_NAME_SORT 0x0008 /* Sort by name (default) */
#define LS_TIME_SORT 0x0010 /* Sort by mtime */
#define LS_SIZE_SORT 0x0020 /* Sort by file size */
#define LS_REVERSE_SORT 0x0040 /* Reverse sort order */
#define LS_SHOW_ALL 0x0080 /* Don't skip filenames starting with '.' */
#define LS_SI_UNITS 0x0100 /* Display sizes as K, M, G, etc. */
#define VIEW_FLAGS (LS_LONG_VIEW|LS_SHORT_VIEW|LS_NUMERIC_VIEW|LS_SI_UNITS)
#define SORT_FLAGS (LS_NAME_SORT|LS_TIME_SORT|LS_SIZE_SORT)
/* Commands for interactive mode */
enum sftp_command {
I_CHDIR = 1,
I_CHGRP,
I_CHMOD,
I_CHOWN,
I_COPY,
I_DF,
I_GET,
I_HELP,
I_LCHDIR,
I_LINK,
I_LLS,
I_LMKDIR,
I_LPWD,
I_LS,
I_LUMASK,
I_MKDIR,
I_PUT,
I_PWD,
I_QUIT,
I_REGET,
I_RENAME,
I_REPUT,
I_RM,
I_RMDIR,
I_SHELL,
I_SYMLINK,
I_VERSION,
I_PROGRESS,
};
struct CMD {
const char *c;
const int n;
const int t; /* Completion type for the first argument */
const int t2; /* completion type for the optional second argument */
};
/* Type of completion */
#define NOARGS 0
#define REMOTE 1
#define LOCAL 2
static const struct CMD cmds[] = {
{ "bye", I_QUIT, NOARGS, NOARGS },
{ "cd", I_CHDIR, REMOTE, NOARGS },
{ "chdir", I_CHDIR, REMOTE, NOARGS },
{ "chgrp", I_CHGRP, REMOTE, NOARGS },
{ "chmod", I_CHMOD, REMOTE, NOARGS },
{ "chown", I_CHOWN, REMOTE, NOARGS },
{ "copy", I_COPY, REMOTE, LOCAL },
{ "cp", I_COPY, REMOTE, LOCAL },
{ "df", I_DF, REMOTE, NOARGS },
{ "dir", I_LS, REMOTE, NOARGS },
{ "exit", I_QUIT, NOARGS, NOARGS },
{ "get", I_GET, REMOTE, LOCAL },
{ "help", I_HELP, NOARGS, NOARGS },
{ "lcd", I_LCHDIR, LOCAL, NOARGS },
{ "lchdir", I_LCHDIR, LOCAL, NOARGS },
{ "lls", I_LLS, LOCAL, NOARGS },
{ "lmkdir", I_LMKDIR, LOCAL, NOARGS },
{ "ln", I_LINK, REMOTE, REMOTE },
{ "lpwd", I_LPWD, LOCAL, NOARGS },
{ "ls", I_LS, REMOTE, NOARGS },
{ "lumask", I_LUMASK, NOARGS, NOARGS },
{ "mkdir", I_MKDIR, REMOTE, NOARGS },
{ "mget", I_GET, REMOTE, LOCAL },
{ "mput", I_PUT, LOCAL, REMOTE },
{ "progress", I_PROGRESS, NOARGS, NOARGS },
{ "put", I_PUT, LOCAL, REMOTE },
{ "pwd", I_PWD, REMOTE, NOARGS },
{ "quit", I_QUIT, NOARGS, NOARGS },
{ "reget", I_REGET, REMOTE, LOCAL },
{ "rename", I_RENAME, REMOTE, REMOTE },
{ "reput", I_REPUT, LOCAL, REMOTE },
{ "rm", I_RM, REMOTE, NOARGS },
{ "rmdir", I_RMDIR, REMOTE, NOARGS },
{ "symlink", I_SYMLINK, REMOTE, REMOTE },
{ "version", I_VERSION, NOARGS, NOARGS },
{ "!", I_SHELL, NOARGS, NOARGS },
{ "?", I_HELP, NOARGS, NOARGS },
{ NULL, -1, -1, -1 }
};
/* ARGSUSED */
static void
killchild(int signo)
{
pid_t pid;
pid = sshpid;
if (pid > 1) {
kill(pid, SIGTERM);
waitpid(pid, NULL, 0);
}
_exit(1);
}
/* ARGSUSED */
static void
suspchild(int signo)
{
if (sshpid > 1) {
kill(sshpid, signo);
while (waitpid(sshpid, NULL, WUNTRACED) == -1 && errno == EINTR)
continue;
}
kill(getpid(), SIGSTOP);
}
/* ARGSUSED */
static void
cmd_interrupt(int signo)
{
const char msg[] = "\rInterrupt \n";
int olderrno = errno;
(void)write(STDERR_FILENO, msg, sizeof(msg) - 1);
interrupted = 1;
errno = olderrno;
}
/* ARGSUSED */
static void
read_interrupt(int signo)
{
interrupted = 1;
}
/*ARGSUSED*/
static void
sigchld_handler(int sig)
{
int save_errno = errno;
pid_t pid;
const char msg[] = "\rConnection closed. \n";
/* Report if ssh transport process dies. */
while ((pid = waitpid(sshpid, NULL, WNOHANG)) == -1 && errno == EINTR)
continue;
if (pid == sshpid) {
- (void)write(STDERR_FILENO, msg, sizeof(msg) - 1);
+ if (!quiet)
+ (void)write(STDERR_FILENO, msg, sizeof(msg) - 1);
sshpid = -1;
}
errno = save_errno;
}
static void
help(void)
{
printf("Available commands:\n"
"bye Quit sftp\n"
"cd path Change remote directory to 'path'\n"
"chgrp [-h] grp path Change group of file 'path' to 'grp'\n"
"chmod [-h] mode path Change permissions of file 'path' to 'mode'\n"
"chown [-h] own path Change owner of file 'path' to 'own'\n"
"copy oldpath newpath Copy remote file\n"
"cp oldpath newpath Copy remote file\n"
"df [-hi] [path] Display statistics for current directory or\n"
" filesystem containing 'path'\n"
"exit Quit sftp\n"
"get [-afpR] remote [local] Download file\n"
"help Display this help text\n"
"lcd path Change local directory to 'path'\n"
"lls [ls-options [path]] Display local directory listing\n"
"lmkdir path Create local directory\n"
"ln [-s] oldpath newpath Link remote file (-s for symlink)\n"
"lpwd Print local working directory\n"
"ls [-1afhlnrSt] [path] Display remote directory listing\n"
"lumask umask Set local umask to 'umask'\n"
"mkdir path Create remote directory\n"
"progress Toggle display of progress meter\n"
"put [-afpR] local [remote] Upload file\n"
"pwd Display remote working directory\n"
"quit Quit sftp\n"
"reget [-fpR] remote [local] Resume download file\n"
"rename oldpath newpath Rename remote file\n"
"reput [-fpR] local [remote] Resume upload file\n"
"rm path Delete remote file\n"
"rmdir path Remove remote directory\n"
"symlink oldpath newpath Symlink remote file\n"
"version Show SFTP version\n"
"!command Execute 'command' in local shell\n"
"! Escape to local shell\n"
"? Synonym for help\n");
}
static void
local_do_shell(const char *args)
{
int status;
char *shell;
pid_t pid;
if (!*args)
args = NULL;
if ((shell = getenv("SHELL")) == NULL || *shell == '\0')
shell = _PATH_BSHELL;
if ((pid = fork()) == -1)
fatal("Couldn't fork: %s", strerror(errno));
if (pid == 0) {
/* XXX: child has pipe fds to ssh subproc open - issue? */
if (args) {
debug3("Executing %s -c \"%s\"", shell, args);
execl(shell, shell, "-c", args, (char *)NULL);
} else {
debug3("Executing %s", shell);
execl(shell, shell, (char *)NULL);
}
fprintf(stderr, "Couldn't execute \"%s\": %s\n", shell,
strerror(errno));
_exit(1);
}
while (waitpid(pid, &status, 0) == -1)
if (errno != EINTR)
fatal("Couldn't wait for child: %s", strerror(errno));
if (!WIFEXITED(status))
error("Shell exited abnormally");
else if (WEXITSTATUS(status))
error("Shell exited with status %d", WEXITSTATUS(status));
}
static void
local_do_ls(const char *args)
{
if (!args || !*args)
local_do_shell(_PATH_LS);
else {
int len = strlen(_PATH_LS " ") + strlen(args) + 1;
char *buf = xmalloc(len);
/* XXX: quoting - rip quoting code from ftp? */
snprintf(buf, len, _PATH_LS " %s", args);
local_do_shell(buf);
free(buf);
}
}
/* Strip one path (usually the pwd) from the start of another */
static char *
path_strip(const char *path, const char *strip)
{
size_t len;
if (strip == NULL)
return (xstrdup(path));
len = strlen(strip);
if (strncmp(path, strip, len) == 0) {
if (strip[len - 1] != '/' && path[len] == '/')
len++;
return (xstrdup(path + len));
}
return (xstrdup(path));
}
static int
parse_getput_flags(const char *cmd, char **argv, int argc,
int *aflag, int *fflag, int *pflag, int *rflag)
{
extern int opterr, optind, optopt, optreset;
int ch;
optind = optreset = 1;
opterr = 0;
*aflag = *fflag = *rflag = *pflag = 0;
while ((ch = getopt(argc, argv, "afPpRr")) != -1) {
switch (ch) {
case 'a':
*aflag = 1;
break;
case 'f':
*fflag = 1;
break;
case 'p':
case 'P':
*pflag = 1;
break;
case 'r':
case 'R':
*rflag = 1;
break;
default:
error("%s: Invalid flag -%c", cmd, optopt);
return -1;
}
}
return optind;
}
static int
parse_link_flags(const char *cmd, char **argv, int argc, int *sflag)
{
extern int opterr, optind, optopt, optreset;
int ch;
optind = optreset = 1;
opterr = 0;
*sflag = 0;
while ((ch = getopt(argc, argv, "s")) != -1) {
switch (ch) {
case 's':
*sflag = 1;
break;
default:
error("%s: Invalid flag -%c", cmd, optopt);
return -1;
}
}
return optind;
}
static int
parse_rename_flags(const char *cmd, char **argv, int argc, int *lflag)
{
extern int opterr, optind, optopt, optreset;
int ch;
optind = optreset = 1;
opterr = 0;
*lflag = 0;
while ((ch = getopt(argc, argv, "l")) != -1) {
switch (ch) {
case 'l':
*lflag = 1;
break;
default:
error("%s: Invalid flag -%c", cmd, optopt);
return -1;
}
}
return optind;
}
static int
parse_ls_flags(char **argv, int argc, int *lflag)
{
extern int opterr, optind, optopt, optreset;
int ch;
optind = optreset = 1;
opterr = 0;
*lflag = LS_NAME_SORT;
while ((ch = getopt(argc, argv, "1Safhlnrt")) != -1) {
switch (ch) {
case '1':
*lflag &= ~VIEW_FLAGS;
*lflag |= LS_SHORT_VIEW;
break;
case 'S':
*lflag &= ~SORT_FLAGS;
*lflag |= LS_SIZE_SORT;
break;
case 'a':
*lflag |= LS_SHOW_ALL;
break;
case 'f':
*lflag &= ~SORT_FLAGS;
break;
case 'h':
*lflag |= LS_SI_UNITS;
break;
case 'l':
*lflag &= ~LS_SHORT_VIEW;
*lflag |= LS_LONG_VIEW;
break;
case 'n':
*lflag &= ~LS_SHORT_VIEW;
*lflag |= LS_NUMERIC_VIEW|LS_LONG_VIEW;
break;
case 'r':
*lflag |= LS_REVERSE_SORT;
break;
case 't':
*lflag &= ~SORT_FLAGS;
*lflag |= LS_TIME_SORT;
break;
default:
error("ls: Invalid flag -%c", optopt);
return -1;
}
}
return optind;
}
static int
parse_df_flags(const char *cmd, char **argv, int argc, int *hflag, int *iflag)
{
extern int opterr, optind, optopt, optreset;
int ch;
optind = optreset = 1;
opterr = 0;
*hflag = *iflag = 0;
while ((ch = getopt(argc, argv, "hi")) != -1) {
switch (ch) {
case 'h':
*hflag = 1;
break;
case 'i':
*iflag = 1;
break;
default:
error("%s: Invalid flag -%c", cmd, optopt);
return -1;
}
}
return optind;
}
static int
parse_ch_flags(const char *cmd, char **argv, int argc, int *hflag)
{
extern int opterr, optind, optopt, optreset;
int ch;
optind = optreset = 1;
opterr = 0;
*hflag = 0;
while ((ch = getopt(argc, argv, "h")) != -1) {
switch (ch) {
case 'h':
*hflag = 1;
break;
default:
error("%s: Invalid flag -%c", cmd, optopt);
return -1;
}
}
return optind;
}
static int
parse_no_flags(const char *cmd, char **argv, int argc)
{
extern int opterr, optind, optopt, optreset;
int ch;
optind = optreset = 1;
opterr = 0;
while ((ch = getopt(argc, argv, "")) != -1) {
switch (ch) {
default:
error("%s: Invalid flag -%c", cmd, optopt);
return -1;
}
}
return optind;
}
static char *
escape_glob(const char *s)
{
size_t i, o, len;
char *ret;
len = strlen(s);
ret = xcalloc(2, len + 1);
for (i = o = 0; i < len; i++) {
if (strchr("[]?*\\", s[i]) != NULL)
ret[o++] = '\\';
ret[o++] = s[i];
}
ret[o++] = '\0';
return ret;
}
static char *
make_absolute_pwd_glob(const char *p, const char *pwd)
{
char *ret, *escpwd;
escpwd = escape_glob(pwd);
if (p == NULL)
return escpwd;
ret = make_absolute(xstrdup(p), escpwd);
free(escpwd);
return ret;
}
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)
{
char *filename, *abs_src = NULL, *abs_dst = NULL, *tmp = NULL;
glob_t g;
int i, r, err = 0;
abs_src = make_absolute_pwd_glob(src, pwd);
memset(&g, 0, sizeof(g));
debug3("Looking up %s", abs_src);
if ((r = remote_glob(conn, abs_src, GLOB_MARK, NULL, &g)) != 0) {
if (r == GLOB_NOSPACE) {
error("Too many matches for \"%s\".", abs_src);
} else {
error("File \"%s\" not found.", abs_src);
}
err = -1;
goto out;
}
/*
* If multiple matches then dst must be a directory or
* unspecified.
*/
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;
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));
free(tmp);
err = -1;
goto out;
}
if (g.gl_matchc == 1 && dst) {
if (local_is_dir(dst)) {
abs_dst = path_append(dst, filename);
} else {
abs_dst = xstrdup(dst);
}
} else if (dst) {
abs_dst = path_append(dst, filename);
} else {
abs_dst = xstrdup(filename);
}
free(tmp);
resume |= global_aflag;
if (!quiet && resume)
mprintf("Resuming %s to %s\n",
g.gl_pathv[i], abs_dst);
else if (!quiet && !resume)
mprintf("Fetching %s to %s\n",
g.gl_pathv[i], abs_dst);
/* 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, 0, 0) == -1)
err = -1;
} else {
if (do_download(conn, g.gl_pathv[i], abs_dst, NULL,
pflag || global_pflag, resume,
fflag || global_fflag, 0) == -1)
err = -1;
}
free(abs_dst);
abs_dst = NULL;
}
out:
free(abs_src);
globfree(&g);
return(err);
}
static int
process_put(struct sftp_conn *conn, const char *src, const char *dst,
const char *pwd, int pflag, int rflag, int resume, int fflag)
{
char *tmp_dst = NULL;
char *abs_dst = NULL;
char *tmp = NULL, *filename = NULL;
glob_t g;
int err = 0;
int i, dst_is_dir = 1;
struct stat sb;
if (dst) {
tmp_dst = xstrdup(dst);
tmp_dst = make_absolute(tmp_dst, pwd);
}
memset(&g, 0, sizeof(g));
debug3("Looking up %s", src);
if (glob(src, GLOB_NOCHECK | GLOB_MARK, NULL, &g)) {
error("File \"%s\" not found.", src);
err = -1;
goto out;
}
/* If we aren't fetching to pwd then stash this status for later */
if (tmp_dst != NULL)
dst_is_dir = remote_is_dir(conn, tmp_dst);
/* If multiple matches, dst may be directory or unspecified */
if (g.gl_matchc > 1 && tmp_dst && !dst_is_dir) {
error("Multiple paths match, but destination "
"\"%s\" is not a directory", tmp_dst);
err = -1;
goto out;
}
for (i = 0; g.gl_pathv[i] && !interrupted; i++) {
if (stat(g.gl_pathv[i], &sb) == -1) {
err = -1;
error("stat %s: %s", g.gl_pathv[i], strerror(errno));
continue;
}
tmp = xstrdup(g.gl_pathv[i]);
if ((filename = basename(tmp)) == NULL) {
error("basename %s: %s", tmp, strerror(errno));
free(tmp);
err = -1;
goto out;
}
if (g.gl_matchc == 1 && tmp_dst) {
/* If directory specified, append filename */
if (dst_is_dir)
abs_dst = path_append(tmp_dst, filename);
else
abs_dst = xstrdup(tmp_dst);
} else if (tmp_dst) {
abs_dst = path_append(tmp_dst, filename);
} else {
abs_dst = make_absolute(xstrdup(filename), pwd);
}
free(tmp);
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);
/* 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, 0, 0) == -1)
err = -1;
} else {
if (do_upload(conn, g.gl_pathv[i], abs_dst,
pflag || global_pflag, resume,
fflag || global_fflag, 0) == -1)
err = -1;
}
}
out:
free(abs_dst);
free(tmp_dst);
globfree(&g);
return(err);
}
static int
sdirent_comp(const void *aa, const void *bb)
{
SFTP_DIRENT *a = *(SFTP_DIRENT **)aa;
SFTP_DIRENT *b = *(SFTP_DIRENT **)bb;
int rmul = sort_flag & LS_REVERSE_SORT ? -1 : 1;
#define NCMP(a,b) (a == b ? 0 : (a < b ? 1 : -1))
if (sort_flag & LS_NAME_SORT)
return (rmul * strcmp(a->filename, b->filename));
else if (sort_flag & LS_TIME_SORT)
return (rmul * NCMP(a->a.mtime, b->a.mtime));
else if (sort_flag & LS_SIZE_SORT)
return (rmul * NCMP(a->a.size, b->a.size));
fatal("Unknown ls sort type");
}
/* sftp ls.1 replacement for directories */
static int
do_ls_dir(struct sftp_conn *conn, const char *path,
const char *strip_path, int lflag)
{
int n;
u_int c = 1, colspace = 0, columns = 1;
SFTP_DIRENT **d;
if ((n = do_readdir(conn, path, &d)) != 0)
return (n);
if (!(lflag & LS_SHORT_VIEW)) {
u_int m = 0, width = 80;
struct winsize ws;
char *tmp;
/* Count entries for sort and find longest filename */
for (n = 0; d[n] != NULL; n++) {
if (d[n]->filename[0] != '.' || (lflag & LS_SHOW_ALL))
m = MAXIMUM(m, strlen(d[n]->filename));
}
/* Add any subpath that also needs to be counted */
tmp = path_strip(path, strip_path);
m += strlen(tmp);
free(tmp);
if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) != -1)
width = ws.ws_col;
columns = width / (m + 2);
columns = MAXIMUM(columns, 1);
colspace = width / columns;
colspace = MINIMUM(colspace, width);
}
if (lflag & SORT_FLAGS) {
for (n = 0; d[n] != NULL; n++)
; /* count entries */
sort_flag = lflag & (SORT_FLAGS|LS_REVERSE_SORT);
qsort(d, n, sizeof(*d), sdirent_comp);
}
get_remote_user_groups_from_dirents(conn, d);
for (n = 0; d[n] != NULL && !interrupted; n++) {
char *tmp, *fname;
if (d[n]->filename[0] == '.' && !(lflag & LS_SHOW_ALL))
continue;
tmp = path_append(path, d[n]->filename);
fname = path_strip(tmp, strip_path);
free(tmp);
if (lflag & LS_LONG_VIEW) {
if ((lflag & (LS_NUMERIC_VIEW|LS_SI_UNITS)) != 0 ||
can_get_users_groups_by_id(conn)) {
char *lname;
struct stat sb;
memset(&sb, 0, sizeof(sb));
attrib_to_stat(&d[n]->a, &sb);
lname = ls_file(fname, &sb, 1,
(lflag & LS_SI_UNITS),
ruser_name(sb.st_uid),
rgroup_name(sb.st_gid));
mprintf("%s\n", lname);
free(lname);
} else
mprintf("%s\n", d[n]->longname);
} else {
mprintf("%-*s", colspace, fname);
if (c >= columns) {
printf("\n");
c = 1;
} else
c++;
}
free(fname);
}
if (!(lflag & LS_LONG_VIEW) && (c != 1))
printf("\n");
free_sftp_dirents(d);
return (0);
}
static int
sglob_comp(const void *aa, const void *bb)
{
u_int a = *(const u_int *)aa;
u_int b = *(const u_int *)bb;
const char *ap = sort_glob->gl_pathv[a];
const char *bp = sort_glob->gl_pathv[b];
const struct stat *as = sort_glob->gl_statv[a];
const struct stat *bs = sort_glob->gl_statv[b];
int rmul = sort_flag & LS_REVERSE_SORT ? -1 : 1;
#define NCMP(a,b) (a == b ? 0 : (a < b ? 1 : -1))
if (sort_flag & LS_NAME_SORT)
return (rmul * strcmp(ap, bp));
else if (sort_flag & LS_TIME_SORT) {
#if defined(HAVE_STRUCT_STAT_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
return rmul * 1;
#endif
} else if (sort_flag & LS_SIZE_SORT)
return (rmul * NCMP(as->st_size, bs->st_size));
fatal("Unknown ls sort type");
}
/* sftp ls.1 replacement which handles path globs */
static int
do_globbed_ls(struct sftp_conn *conn, const char *path,
const char *strip_path, int lflag)
{
char *fname, *lname;
glob_t g;
int err, r;
struct winsize ws;
u_int i, j, nentries, *indices = NULL, c = 1;
u_int colspace = 0, columns = 1, m = 0, width = 80;
memset(&g, 0, sizeof(g));
if ((r = remote_glob(conn, path,
GLOB_MARK|GLOB_NOCHECK|GLOB_BRACE|GLOB_KEEPSTAT|GLOB_NOSORT,
NULL, &g)) != 0 ||
(g.gl_pathc && !g.gl_matchc)) {
if (g.gl_pathc)
globfree(&g);
if (r == GLOB_NOSPACE) {
error("Can't ls: Too many matches for \"%s\"", path);
} else {
error("Can't ls: \"%s\" not found", path);
}
return -1;
}
if (interrupted)
goto out;
/*
* If the glob returns a single match and it is a directory,
* then just list its contents.
*/
if (g.gl_matchc == 1 && g.gl_statv[0] != NULL &&
S_ISDIR(g.gl_statv[0]->st_mode)) {
err = do_ls_dir(conn, g.gl_pathv[0], strip_path, lflag);
globfree(&g);
return err;
}
if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) != -1)
width = ws.ws_col;
if (!(lflag & LS_SHORT_VIEW)) {
/* Count entries for sort and find longest filename */
for (i = 0; g.gl_pathv[i]; i++)
m = MAXIMUM(m, strlen(g.gl_pathv[i]));
columns = width / (m + 2);
columns = MAXIMUM(columns, 1);
colspace = width / columns;
}
/*
* Sorting: rather than mess with the contents of glob_t, prepare
* an array of indices into it and sort that. For the usual
* unsorted case, the indices are just the identity 1=1, 2=2, etc.
*/
for (nentries = 0; g.gl_pathv[nentries] != NULL; nentries++)
; /* count entries */
indices = calloc(nentries, sizeof(*indices));
for (i = 0; i < nentries; i++)
indices[i] = i;
if (lflag & SORT_FLAGS) {
sort_glob = &g;
sort_flag = lflag & (SORT_FLAGS|LS_REVERSE_SORT);
qsort(indices, nentries, sizeof(*indices), sglob_comp);
sort_glob = NULL;
}
get_remote_user_groups_from_glob(conn, &g);
for (j = 0; j < nentries && !interrupted; j++) {
i = indices[j];
fname = path_strip(g.gl_pathv[i], strip_path);
if (lflag & LS_LONG_VIEW) {
if (g.gl_statv[i] == NULL) {
error("no stat information for %s", fname);
continue;
}
lname = ls_file(fname, g.gl_statv[i], 1,
(lflag & LS_SI_UNITS),
ruser_name(g.gl_statv[i]->st_uid),
rgroup_name(g.gl_statv[i]->st_gid));
mprintf("%s\n", lname);
free(lname);
} else {
mprintf("%-*s", colspace, fname);
if (c >= columns) {
printf("\n");
c = 1;
} else
c++;
}
free(fname);
}
if (!(lflag & LS_LONG_VIEW) && (c != 1))
printf("\n");
out:
if (g.gl_pathc)
globfree(&g);
free(indices);
return 0;
}
static int
do_df(struct sftp_conn *conn, const char *path, int hflag, int iflag)
{
struct sftp_statvfs st;
char s_used[FMT_SCALED_STRSIZE], s_avail[FMT_SCALED_STRSIZE];
char s_root[FMT_SCALED_STRSIZE], s_total[FMT_SCALED_STRSIZE];
char s_icapacity[16], s_dcapacity[16];
if (do_statvfs(conn, path, &st, 1) == -1)
return -1;
if (st.f_files == 0)
strlcpy(s_icapacity, "ERR", sizeof(s_icapacity));
else {
snprintf(s_icapacity, sizeof(s_icapacity), "%3llu%%",
(unsigned long long)(100 * (st.f_files - st.f_ffree) /
st.f_files));
}
if (st.f_blocks == 0)
strlcpy(s_dcapacity, "ERR", sizeof(s_dcapacity));
else {
snprintf(s_dcapacity, sizeof(s_dcapacity), "%3llu%%",
(unsigned long long)(100 * (st.f_blocks - st.f_bfree) /
st.f_blocks));
}
if (iflag) {
printf(" Inodes Used Avail "
"(root) %%Capacity\n");
printf("%11llu %11llu %11llu %11llu %s\n",
(unsigned long long)st.f_files,
(unsigned long long)(st.f_files - st.f_ffree),
(unsigned long long)st.f_favail,
(unsigned long long)st.f_ffree, s_icapacity);
} else if (hflag) {
strlcpy(s_used, "error", sizeof(s_used));
strlcpy(s_avail, "error", sizeof(s_avail));
strlcpy(s_root, "error", sizeof(s_root));
strlcpy(s_total, "error", sizeof(s_total));
fmt_scaled((st.f_blocks - st.f_bfree) * st.f_frsize, s_used);
fmt_scaled(st.f_bavail * st.f_frsize, s_avail);
fmt_scaled(st.f_bfree * st.f_frsize, s_root);
fmt_scaled(st.f_blocks * st.f_frsize, s_total);
printf(" Size Used Avail (root) %%Capacity\n");
printf("%7sB %7sB %7sB %7sB %s\n",
s_total, s_used, s_avail, s_root, s_dcapacity);
} else {
printf(" Size Used Avail "
"(root) %%Capacity\n");
printf("%12llu %12llu %12llu %12llu %s\n",
(unsigned long long)(st.f_frsize * st.f_blocks / 1024),
(unsigned long long)(st.f_frsize *
(st.f_blocks - st.f_bfree) / 1024),
(unsigned long long)(st.f_frsize * st.f_bavail / 1024),
(unsigned long long)(st.f_frsize * st.f_bfree / 1024),
s_dcapacity);
}
return 0;
}
/*
* Undo escaping of glob sequences in place. Used to undo extra escaping
* applied in makeargv() when the string is destined for a function that
* does not glob it.
*/
static void
undo_glob_escape(char *s)
{
size_t i, j;
for (i = j = 0;;) {
if (s[i] == '\0') {
s[j] = '\0';
return;
}
if (s[i] != '\\') {
s[j++] = s[i++];
continue;
}
/* s[i] == '\\' */
++i;
switch (s[i]) {
case '?':
case '[':
case '*':
case '\\':
s[j++] = s[i++];
break;
case '\0':
s[j++] = '\\';
s[j] = '\0';
return;
default:
s[j++] = '\\';
s[j++] = s[i++];
break;
}
}
}
/*
* Split a string into an argument vector using sh(1)-style quoting,
* comment and escaping rules, but with some tweaks to handle glob(3)
* wildcards.
* The "sloppy" flag allows for recovery from missing terminating quote, for
* use in parsing incomplete commandlines during tab autocompletion.
*
* Returns NULL on error or a NULL-terminated array of arguments.
*
* If "lastquote" is not NULL, the quoting character used for the last
* argument is placed in *lastquote ("\0", "'" or "\"").
*
* If "terminated" is not NULL, *terminated will be set to 1 when the
* 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 MAXARGLEN 8192
static char **
makeargv(const char *arg, int *argcp, int sloppy, char *lastquote,
u_int *terminated)
{
int argc, quot;
size_t i, j;
static char argvs[MAXARGLEN];
static char *argv[MAXARGS + 1];
enum { MA_START, MA_SQUOTE, MA_DQUOTE, MA_UNQUOTED } state, q;
*argcp = argc = 0;
if (strlen(arg) > sizeof(argvs) - 1) {
args_too_longs:
error("string too long");
return NULL;
}
if (terminated != NULL)
*terminated = 1;
if (lastquote != NULL)
*lastquote = '\0';
state = MA_START;
i = j = 0;
for (;;) {
if ((size_t)argc >= sizeof(argv) / sizeof(*argv)){
error("Too many arguments.");
return NULL;
}
if (isspace((unsigned char)arg[i])) {
if (state == MA_UNQUOTED) {
/* Terminate current argument */
argvs[j++] = '\0';
argc++;
state = MA_START;
} else if (state != MA_START)
argvs[j++] = arg[i];
} else if (arg[i] == '"' || arg[i] == '\'') {
q = arg[i] == '"' ? MA_DQUOTE : MA_SQUOTE;
if (state == MA_START) {
argv[argc] = argvs + j;
state = q;
if (lastquote != NULL)
*lastquote = arg[i];
} else if (state == MA_UNQUOTED)
state = q;
else if (state == q)
state = MA_UNQUOTED;
else
argvs[j++] = arg[i];
} else if (arg[i] == '\\') {
if (state == MA_SQUOTE || state == MA_DQUOTE) {
quot = state == MA_SQUOTE ? '\'' : '"';
/* Unescape quote we are in */
/* XXX support \n and friends? */
if (arg[i + 1] == quot) {
i++;
argvs[j++] = arg[i];
} else if (arg[i + 1] == '?' ||
arg[i + 1] == '[' || arg[i + 1] == '*') {
/*
* Special case for sftp: append
* double-escaped glob sequence -
* glob will undo one level of
* escaping. NB. string can grow here.
*/
if (j >= sizeof(argvs) - 5)
goto args_too_longs;
argvs[j++] = '\\';
argvs[j++] = arg[i++];
argvs[j++] = '\\';
argvs[j++] = arg[i];
} else {
argvs[j++] = arg[i++];
argvs[j++] = arg[i];
}
} else {
if (state == MA_START) {
argv[argc] = argvs + j;
state = MA_UNQUOTED;
if (lastquote != NULL)
*lastquote = '\0';
}
if (arg[i + 1] == '?' || arg[i + 1] == '[' ||
arg[i + 1] == '*' || arg[i + 1] == '\\') {
/*
* Special case for sftp: append
* escaped glob sequence -
* glob will undo one level of
* escaping.
*/
argvs[j++] = arg[i++];
argvs[j++] = arg[i];
} else {
/* Unescape everything */
/* XXX support \n and friends? */
i++;
argvs[j++] = arg[i];
}
}
} else if (arg[i] == '#') {
if (state == MA_SQUOTE || state == MA_DQUOTE)
argvs[j++] = arg[i];
else
goto string_done;
} else if (arg[i] == '\0') {
if (state == MA_SQUOTE || state == MA_DQUOTE) {
if (sloppy) {
state = MA_UNQUOTED;
if (terminated != NULL)
*terminated = 0;
goto string_done;
}
error("Unterminated quoted argument");
return NULL;
}
string_done:
if (state == MA_UNQUOTED) {
argvs[j++] = '\0';
argc++;
}
break;
} else {
if (state == MA_START) {
argv[argc] = argvs + j;
state = MA_UNQUOTED;
if (lastquote != NULL)
*lastquote = '\0';
}
if ((state == MA_SQUOTE || state == MA_DQUOTE) &&
(arg[i] == '?' || arg[i] == '[' || arg[i] == '*')) {
/*
* Special case for sftp: escape quoted
* glob(3) wildcards. NB. string can grow
* here.
*/
if (j >= sizeof(argvs) - 3)
goto args_too_longs;
argvs[j++] = '\\';
argvs[j++] = arg[i];
} else
argvs[j++] = arg[i];
}
i++;
}
*argcp = argc;
return argv;
}
static int
parse_args(const char **cpp, int *ignore_errors, int *disable_echo, int *aflag,
int *fflag, int *hflag, int *iflag, int *lflag, int *pflag,
int *rflag, int *sflag,
unsigned long *n_arg, char **path1, char **path2)
{
const char *cmd, *cp = *cpp;
char *cp2, **argv;
int base = 0;
long long ll;
int path1_mandatory = 0, i, cmdnum, optidx, argc;
/* Skip leading whitespace */
cp = cp + strspn(cp, WHITESPACE);
/*
* Check for leading '-' (disable error processing) and '@' (suppress
* command echo)
*/
*ignore_errors = 0;
*disable_echo = 0;
for (;*cp != '\0'; cp++) {
if (*cp == '-') {
*ignore_errors = 1;
} else if (*cp == '@') {
*disable_echo = 1;
} else {
/* all other characters terminate prefix processing */
break;
}
}
cp = cp + strspn(cp, WHITESPACE);
/* Ignore blank lines and lines which begin with comment '#' char */
if (*cp == '\0' || *cp == '#')
return (0);
if ((argv = makeargv(cp, &argc, 0, NULL, NULL)) == NULL)
return -1;
/* Figure out which command we have */
for (i = 0; cmds[i].c != NULL; i++) {
if (argv[0] != NULL && strcasecmp(cmds[i].c, argv[0]) == 0)
break;
}
cmdnum = cmds[i].n;
cmd = cmds[i].c;
/* Special case */
if (*cp == '!') {
cp++;
cmdnum = I_SHELL;
} else if (cmdnum == -1) {
error("Invalid command.");
return -1;
}
/* Get arguments and parse flags */
*aflag = *fflag = *hflag = *iflag = *lflag = *pflag = 0;
*rflag = *sflag = 0;
*path1 = *path2 = NULL;
optidx = 1;
switch (cmdnum) {
case I_GET:
case I_REGET:
case I_REPUT:
case I_PUT:
if ((optidx = parse_getput_flags(cmd, argv, argc,
aflag, fflag, pflag, rflag)) == -1)
return -1;
/* Get first pathname (mandatory) */
if (argc - optidx < 1) {
error("You must specify at least one path after a "
"%s command.", cmd);
return -1;
}
*path1 = xstrdup(argv[optidx]);
/* Get second pathname (optional) */
if (argc - optidx > 1) {
*path2 = xstrdup(argv[optidx + 1]);
/* Destination is not globbed */
undo_glob_escape(*path2);
}
break;
case I_LINK:
if ((optidx = parse_link_flags(cmd, argv, argc, sflag)) == -1)
return -1;
goto parse_two_paths;
case I_COPY:
if ((optidx = parse_no_flags(cmd, argv, argc)) == -1)
return -1;
goto parse_two_paths;
case I_RENAME:
if ((optidx = parse_rename_flags(cmd, argv, argc, lflag)) == -1)
return -1;
goto parse_two_paths;
case I_SYMLINK:
if ((optidx = parse_no_flags(cmd, argv, argc)) == -1)
return -1;
parse_two_paths:
if (argc - optidx < 2) {
error("You must specify two paths after a %s "
"command.", cmd);
return -1;
}
*path1 = xstrdup(argv[optidx]);
*path2 = xstrdup(argv[optidx + 1]);
/* Paths are not globbed */
undo_glob_escape(*path1);
undo_glob_escape(*path2);
break;
case I_RM:
case I_MKDIR:
case I_RMDIR:
case I_LMKDIR:
path1_mandatory = 1;
/* FALLTHROUGH */
case I_CHDIR:
case I_LCHDIR:
if ((optidx = parse_no_flags(cmd, argv, argc)) == -1)
return -1;
/* Get pathname (mandatory) */
if (argc - optidx < 1) {
if (!path1_mandatory)
break; /* return a NULL path1 */
error("You must specify a path after a %s command.",
cmd);
return -1;
}
*path1 = xstrdup(argv[optidx]);
/* Only "rm" globs */
if (cmdnum != I_RM)
undo_glob_escape(*path1);
break;
case I_DF:
if ((optidx = parse_df_flags(cmd, argv, argc, hflag,
iflag)) == -1)
return -1;
/* Default to current directory if no path specified */
if (argc - optidx < 1)
*path1 = NULL;
else {
*path1 = xstrdup(argv[optidx]);
undo_glob_escape(*path1);
}
break;
case I_LS:
if ((optidx = parse_ls_flags(argv, argc, lflag)) == -1)
return(-1);
/* Path is optional */
if (argc - optidx > 0)
*path1 = xstrdup(argv[optidx]);
break;
case I_LLS:
/* Skip ls command and following whitespace */
cp = cp + strlen(cmd) + strspn(cp, WHITESPACE);
case I_SHELL:
/* Uses the rest of the line */
break;
case I_LUMASK:
case I_CHMOD:
base = 8;
/* FALLTHROUGH */
case I_CHOWN:
case I_CHGRP:
if ((optidx = parse_ch_flags(cmd, argv, argc, hflag)) == -1)
return -1;
/* Get numeric arg (mandatory) */
if (argc - optidx < 1)
goto need_num_arg;
errno = 0;
ll = strtoll(argv[optidx], &cp2, base);
if (cp2 == argv[optidx] || *cp2 != '\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 = ll;
if (cmdnum == I_LUMASK)
break;
/* Get pathname (mandatory) */
if (argc - optidx < 2) {
error("You must specify a path after a %s command.",
cmd);
return -1;
}
*path1 = xstrdup(argv[optidx + 1]);
break;
case I_QUIT:
case I_PWD:
case I_LPWD:
case I_HELP:
case I_VERSION:
case I_PROGRESS:
if ((optidx = parse_no_flags(cmd, argv, argc)) == -1)
return -1;
break;
default:
fatal("Command not implemented");
}
*cpp = cp;
return(cmdnum);
}
static int
parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
const char *startdir, int err_abort, int echo_command)
{
const char *ocmd = cmd;
char *path1, *path2, *tmp;
int ignore_errors = 0, disable_echo = 1;
int aflag = 0, fflag = 0, hflag = 0, iflag = 0;
int lflag = 0, pflag = 0, rflag = 0, sflag = 0;
int cmdnum, i;
unsigned long n_arg = 0;
Attrib a, *aa;
char path_buf[PATH_MAX];
int err = 0;
glob_t g;
path1 = path2 = NULL;
cmdnum = parse_args(&cmd, &ignore_errors, &disable_echo, &aflag, &fflag,
&hflag, &iflag, &lflag, &pflag, &rflag, &sflag, &n_arg,
&path1, &path2);
if (ignore_errors != 0)
err_abort = 0;
if (echo_command && !disable_echo)
mprintf("sftp> %s\n", ocmd);
memset(&g, 0, sizeof(g));
/* Perform command */
switch (cmdnum) {
case 0:
/* Blank line */
break;
case -1:
/* Unrecognized command */
err = -1;
break;
case I_REGET:
aflag = 1;
/* FALLTHROUGH */
case I_GET:
err = process_get(conn, path1, path2, *pwd, pflag,
rflag, aflag, fflag);
break;
case I_REPUT:
aflag = 1;
/* FALLTHROUGH */
case I_PUT:
err = process_put(conn, path1, path2, *pwd, pflag,
rflag, aflag, fflag);
break;
case I_COPY:
path1 = make_absolute(path1, *pwd);
path2 = make_absolute(path2, *pwd);
err = do_copy(conn, path1, path2);
break;
case I_RENAME:
path1 = make_absolute(path1, *pwd);
path2 = make_absolute(path2, *pwd);
err = do_rename(conn, path1, path2, lflag);
break;
case I_SYMLINK:
sflag = 1;
/* FALLTHROUGH */
case I_LINK:
if (!sflag)
path1 = make_absolute(path1, *pwd);
path2 = make_absolute(path2, *pwd);
err = (sflag ? do_symlink : do_hardlink)(conn, path1, path2);
break;
case I_RM:
path1 = make_absolute_pwd_glob(path1, *pwd);
remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g);
for (i = 0; g.gl_pathv[i] && !interrupted; i++) {
if (!quiet)
mprintf("Removing %s\n", g.gl_pathv[i]);
err = do_rm(conn, g.gl_pathv[i]);
if (err != 0 && err_abort)
break;
}
break;
case I_MKDIR:
path1 = make_absolute(path1, *pwd);
attrib_clear(&a);
a.flags |= SSH2_FILEXFER_ATTR_PERMISSIONS;
a.perm = 0777;
err = do_mkdir(conn, path1, &a, 1);
break;
case I_RMDIR:
path1 = make_absolute(path1, *pwd);
err = do_rmdir(conn, path1);
break;
case I_CHDIR:
if (path1 == NULL || *path1 == '\0')
path1 = xstrdup(startdir);
path1 = make_absolute(path1, *pwd);
if ((tmp = do_realpath(conn, path1)) == NULL) {
err = 1;
break;
}
if ((aa = do_stat(conn, tmp, 0)) == NULL) {
free(tmp);
err = 1;
break;
}
if (!(aa->flags & SSH2_FILEXFER_ATTR_PERMISSIONS)) {
error("Can't change directory: Can't check target");
free(tmp);
err = 1;
break;
}
if (!S_ISDIR(aa->perm)) {
error("Can't change directory: \"%s\" is not "
"a directory", tmp);
free(tmp);
err = 1;
break;
}
free(*pwd);
*pwd = tmp;
break;
case I_LS:
if (!path1) {
do_ls_dir(conn, *pwd, *pwd, lflag);
break;
}
/* Strip pwd off beginning of non-absolute paths */
tmp = NULL;
if (!path_absolute(path1))
tmp = *pwd;
path1 = make_absolute_pwd_glob(path1, *pwd);
err = do_globbed_ls(conn, path1, tmp, lflag);
break;
case I_DF:
/* Default to current directory if no path specified */
if (path1 == NULL)
path1 = xstrdup(*pwd);
path1 = make_absolute(path1, *pwd);
err = do_df(conn, path1, hflag, iflag);
break;
case I_LCHDIR:
if (path1 == NULL || *path1 == '\0')
path1 = xstrdup("~");
tmp = tilde_expand_filename(path1, getuid());
free(path1);
path1 = tmp;
if (chdir(path1) == -1) {
error("Couldn't change local directory to "
"\"%s\": %s", path1, strerror(errno));
err = 1;
}
break;
case I_LMKDIR:
if (mkdir(path1, 0777) == -1) {
error("Couldn't create local directory "
"\"%s\": %s", path1, strerror(errno));
err = 1;
}
break;
case I_LLS:
local_do_ls(cmd);
break;
case I_SHELL:
local_do_shell(cmd);
break;
case I_LUMASK:
umask(n_arg);
printf("Local umask: %03lo\n", n_arg);
break;
case I_CHMOD:
path1 = make_absolute_pwd_glob(path1, *pwd);
attrib_clear(&a);
a.flags |= SSH2_FILEXFER_ATTR_PERMISSIONS;
a.perm = n_arg;
remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g);
for (i = 0; g.gl_pathv[i] && !interrupted; i++) {
if (!quiet)
mprintf("Changing mode on %s\n",
g.gl_pathv[i]);
err = (hflag ? do_lsetstat : do_setstat)(conn,
g.gl_pathv[i], &a);
if (err != 0 && err_abort)
break;
}
break;
case I_CHOWN:
case I_CHGRP:
path1 = make_absolute_pwd_glob(path1, *pwd);
remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g);
for (i = 0; g.gl_pathv[i] && !interrupted; i++) {
if (!(aa = (hflag ? do_lstat : do_stat)(conn,
g.gl_pathv[i], 0))) {
if (err_abort) {
err = -1;
break;
} else
continue;
}
if (!(aa->flags & SSH2_FILEXFER_ATTR_UIDGID)) {
error("Can't get current ownership of "
"remote file \"%s\"", g.gl_pathv[i]);
if (err_abort) {
err = -1;
break;
} else
continue;
}
aa->flags &= SSH2_FILEXFER_ATTR_UIDGID;
if (cmdnum == I_CHOWN) {
if (!quiet)
mprintf("Changing owner on %s\n",
g.gl_pathv[i]);
aa->uid = n_arg;
} else {
if (!quiet)
mprintf("Changing group on %s\n",
g.gl_pathv[i]);
aa->gid = n_arg;
}
err = (hflag ? do_lsetstat : do_setstat)(conn,
g.gl_pathv[i], aa);
if (err != 0 && err_abort)
break;
}
break;
case I_PWD:
mprintf("Remote working directory: %s\n", *pwd);
break;
case I_LPWD:
if (!getcwd(path_buf, sizeof(path_buf))) {
error("Couldn't get local cwd: %s", strerror(errno));
err = -1;
break;
}
mprintf("Local working directory: %s\n", path_buf);
break;
case I_QUIT:
/* Processed below */
break;
case I_HELP:
help();
break;
case I_VERSION:
printf("SFTP protocol version %u\n", sftp_proto_version(conn));
break;
case I_PROGRESS:
showprogress = !showprogress;
if (showprogress)
printf("Progress meter enabled\n");
else
printf("Progress meter disabled\n");
break;
default:
fatal("%d is not implemented", cmdnum);
}
if (g.gl_pathc)
globfree(&g);
free(path1);
free(path2);
/* If an unignored error occurs in batch mode we should abort. */
if (err_abort && err != 0)
return (-1);
else if (cmdnum == I_QUIT)
return (1);
return (0);
}
#ifdef USE_LIBEDIT
static char *
prompt(EditLine *el)
{
return ("sftp> ");
}
/* Display entries in 'list' after skipping the first 'len' chars */
static void
complete_display(char **list, u_int len)
{
u_int y, m = 0, width = 80, columns = 1, colspace = 0, llen;
struct winsize ws;
char *tmp;
/* Count entries for sort and find longest */
for (y = 0; list[y]; y++)
m = MAXIMUM(m, strlen(list[y]));
if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) != -1)
width = ws.ws_col;
m = m > len ? m - len : 0;
columns = width / (m + 2);
columns = MAXIMUM(columns, 1);
colspace = width / columns;
colspace = MINIMUM(colspace, width);
printf("\n");
m = 1;
for (y = 0; list[y]; y++) {
llen = strlen(list[y]);
tmp = llen > len ? list[y] + len : "";
mprintf("%-*s", colspace, tmp);
if (m >= columns) {
printf("\n");
m = 1;
} else
m++;
}
printf("\n");
}
/*
* Given a "list" of words that begin with a common prefix of "word",
* attempt to find an autocompletion to extends "word" by the next
* characters common to all entries in "list".
*/
static char *
complete_ambiguous(const char *word, char **list, size_t count)
{
if (word == NULL)
return NULL;
if (count > 0) {
u_int y, matchlen = strlen(list[0]);
/* Find length of common stem */
for (y = 1; list[y]; y++) {
u_int x;
for (x = 0; x < matchlen; x++)
if (list[0][x] != list[y][x])
break;
matchlen = x;
}
if (matchlen > strlen(word)) {
char *tmp = xstrdup(list[0]);
tmp[matchlen] = '\0';
return tmp;
}
}
return xstrdup(word);
}
/* Autocomplete a sftp command */
static int
complete_cmd_parse(EditLine *el, char *cmd, int lastarg, char quote,
int terminated)
{
u_int y, count = 0, cmdlen, tmplen;
char *tmp, **list, argterm[3];
const LineInfo *lf;
list = xcalloc((sizeof(cmds) / sizeof(*cmds)) + 1, sizeof(char *));
/* No command specified: display all available commands */
if (cmd == NULL) {
for (y = 0; cmds[y].c; y++)
list[count++] = xstrdup(cmds[y].c);
list[count] = NULL;
complete_display(list, 0);
for (y = 0; list[y] != NULL; y++)
free(list[y]);
free(list);
return count;
}
/* Prepare subset of commands that start with "cmd" */
cmdlen = strlen(cmd);
for (y = 0; cmds[y].c; y++) {
if (!strncasecmp(cmd, cmds[y].c, cmdlen))
list[count++] = xstrdup(cmds[y].c);
}
list[count] = NULL;
if (count == 0) {
free(list);
return 0;
}
/* Complete ambiguous command */
tmp = complete_ambiguous(cmd, list, count);
if (count > 1)
complete_display(list, 0);
for (y = 0; list[y]; y++)
free(list[y]);
free(list);
if (tmp != NULL) {
tmplen = strlen(tmp);
cmdlen = strlen(cmd);
/* If cmd may be extended then do so */
if (tmplen > cmdlen)
if (el_insertstr(el, tmp + cmdlen) == -1)
fatal("el_insertstr failed.");
lf = el_line(el);
/* Terminate argument cleanly */
if (count == 1) {
y = 0;
if (!terminated)
argterm[y++] = quote;
if (lastarg || *(lf->cursor) != ' ')
argterm[y++] = ' ';
argterm[y] = '\0';
if (y > 0 && el_insertstr(el, argterm) == -1)
fatal("el_insertstr failed.");
}
free(tmp);
}
return count;
}
/*
* Determine whether a particular sftp command's arguments (if any) represent
* local or remote files. The "cmdarg" argument specifies the actual argument
* and accepts values 1 or 2.
*/
static int
complete_is_remote(char *cmd, int cmdarg) {
int i;
if (cmd == NULL)
return -1;
for (i = 0; cmds[i].c; i++) {
if (!strncasecmp(cmd, cmds[i].c, strlen(cmds[i].c))) {
if (cmdarg == 1)
return cmds[i].t;
else if (cmdarg == 2)
return cmds[i].t2;
break;
}
}
return -1;
}
/* Autocomplete a filename "file" */
static int
complete_match(EditLine *el, struct sftp_conn *conn, char *remote_path,
char *file, int remote, int lastarg, char quote, int terminated)
{
glob_t g;
char *tmp, *tmp2, ins[8];
u_int i, hadglob, pwdlen, len, tmplen, filelen, cesc, isesc, isabs;
int clen;
const LineInfo *lf;
/* Glob from "file" location */
if (file == NULL)
tmp = xstrdup("*");
else
xasprintf(&tmp, "%s*", file);
/* Check if the path is absolute. */
isabs = path_absolute(tmp);
memset(&g, 0, sizeof(g));
if (remote != LOCAL) {
tmp = make_absolute_pwd_glob(tmp, remote_path);
remote_glob(conn, tmp, GLOB_DOOFFS|GLOB_MARK, NULL, &g);
} else
glob(tmp, GLOB_DOOFFS|GLOB_MARK, NULL, &g);
/* Determine length of pwd so we can trim completion display */
for (hadglob = tmplen = pwdlen = 0; tmp[tmplen] != 0; tmplen++) {
/* Terminate counting on first unescaped glob metacharacter */
if (tmp[tmplen] == '*' || tmp[tmplen] == '?') {
if (tmp[tmplen] != '*' || tmp[tmplen + 1] != '\0')
hadglob = 1;
break;
}
if (tmp[tmplen] == '\\' && tmp[tmplen + 1] != '\0')
tmplen++;
if (tmp[tmplen] == '/')
pwdlen = tmplen + 1; /* track last seen '/' */
}
free(tmp);
tmp = NULL;
if (g.gl_matchc == 0)
goto out;
if (g.gl_matchc > 1)
complete_display(g.gl_pathv, pwdlen);
/* Don't try to extend globs */
if (file == NULL || hadglob)
goto out;
tmp2 = complete_ambiguous(file, g.gl_pathv, g.gl_matchc);
tmp = path_strip(tmp2, isabs ? NULL : remote_path);
free(tmp2);
if (tmp == NULL)
goto out;
tmplen = strlen(tmp);
filelen = strlen(file);
/* Count the number of escaped characters in the input string. */
cesc = isesc = 0;
for (i = 0; i < filelen; i++) {
if (!isesc && file[i] == '\\' && i + 1 < filelen){
isesc = 1;
cesc++;
} else
isesc = 0;
}
if (tmplen > (filelen - cesc)) {
tmp2 = tmp + filelen - cesc;
len = strlen(tmp2);
/* quote argument on way out */
for (i = 0; i < len; i += clen) {
if ((clen = mblen(tmp2 + i, len - i)) < 0 ||
(size_t)clen > sizeof(ins) - 2)
fatal("invalid multibyte character");
ins[0] = '\\';
memcpy(ins + 1, tmp2 + i, clen);
ins[clen + 1] = '\0';
switch (tmp2[i]) {
case '\'':
case '"':
case '\\':
case '\t':
case '[':
case ' ':
case '#':
case '*':
if (quote == '\0' || tmp2[i] == quote) {
if (el_insertstr(el, ins) == -1)
fatal("el_insertstr "
"failed.");
break;
}
/* FALLTHROUGH */
default:
if (el_insertstr(el, ins + 1) == -1)
fatal("el_insertstr failed.");
break;
}
}
}
lf = el_line(el);
if (g.gl_matchc == 1) {
i = 0;
if (!terminated && quote != '\0')
ins[i++] = quote;
if (*(lf->cursor - 1) != '/' &&
(lastarg || *(lf->cursor) != ' '))
ins[i++] = ' ';
ins[i] = '\0';
if (i > 0 && el_insertstr(el, ins) == -1)
fatal("el_insertstr failed.");
}
free(tmp);
out:
globfree(&g);
return g.gl_matchc;
}
/* tab-completion hook function, called via libedit */
static unsigned char
complete(EditLine *el, int ch)
{
char **argv, *line, quote;
int argc, carg;
u_int cursor, len, terminated, ret = CC_ERROR;
const LineInfo *lf;
struct complete_ctx *complete_ctx;
lf = el_line(el);
if (el_get(el, EL_CLIENTDATA, (void**)&complete_ctx) != 0)
fatal_f("el_get failed");
/* Figure out which argument the cursor points to */
cursor = lf->cursor - lf->buffer;
line = xmalloc(cursor + 1);
memcpy(line, lf->buffer, cursor);
line[cursor] = '\0';
argv = makeargv(line, &carg, 1, &quote, &terminated);
free(line);
/* Get all the arguments on the line */
len = lf->lastchar - lf->buffer;
line = xmalloc(len + 1);
memcpy(line, lf->buffer, len);
line[len] = '\0';
argv = makeargv(line, &argc, 1, NULL, NULL);
/* Ensure cursor is at EOL or a argument boundary */
if (line[cursor] != ' ' && line[cursor] != '\0' &&
line[cursor] != '\n') {
free(line);
return ret;
}
if (carg == 0) {
/* Show all available commands */
complete_cmd_parse(el, NULL, argc == carg, '\0', 1);
ret = CC_REDISPLAY;
} else if (carg == 1 && cursor > 0 && line[cursor - 1] != ' ') {
/* Handle the command parsing */
if (complete_cmd_parse(el, argv[0], argc == carg,
quote, terminated) != 0)
ret = CC_REDISPLAY;
} else if (carg >= 1) {
/* Handle file parsing */
int remote = 0;
int i = 0, cmdarg = 0;
char *filematch = NULL;
if (carg > 1 && line[cursor-1] != ' ')
filematch = argv[carg - 1];
for (i = 1; i < carg; i++) {
/* Skip flags */
if (argv[i][0] != '-')
cmdarg++;
}
/*
* If previous argument is complete, then offer completion
* on the next one.
*/
if (line[cursor - 1] == ' ')
cmdarg++;
remote = complete_is_remote(argv[0], cmdarg);
if ((remote == REMOTE || remote == LOCAL) &&
complete_match(el, complete_ctx->conn,
*complete_ctx->remote_pathp, filematch,
remote, carg == argc, quote, terminated) != 0)
ret = CC_REDISPLAY;
}
free(line);
return ret;
}
#endif /* USE_LIBEDIT */
static int
interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
{
char *remote_path;
char *dir = NULL, *startdir = NULL;
char cmd[2048];
int err, interactive;
EditLine *el = NULL;
#ifdef USE_LIBEDIT
History *hl = NULL;
HistEvent hev;
extern char *__progname;
struct complete_ctx complete_ctx;
if (!batchmode && isatty(STDIN_FILENO)) {
if ((el = el_init(__progname, stdin, stdout, stderr)) == NULL)
fatal("Couldn't initialise editline");
if ((hl = history_init()) == NULL)
fatal("Couldn't initialise editline history");
history(hl, &hev, H_SETSIZE, 100);
el_set(el, EL_HIST, history, hl);
el_set(el, EL_PROMPT, prompt);
el_set(el, EL_EDITOR, "emacs");
el_set(el, EL_TERMINAL, NULL);
el_set(el, EL_SIGNAL, 1);
el_source(el, NULL);
/* Tab Completion */
el_set(el, EL_ADDFN, "ftp-complete",
"Context sensitive argument completion", complete);
complete_ctx.conn = conn;
complete_ctx.remote_pathp = &remote_path;
el_set(el, EL_CLIENTDATA, (void*)&complete_ctx);
el_set(el, EL_BIND, "^I", "ftp-complete", NULL);
/* enable ctrl-left-arrow and ctrl-right-arrow */
el_set(el, EL_BIND, "\\e[1;5C", "em-next-word", NULL);
el_set(el, EL_BIND, "\\e\\e[C", "em-next-word", NULL);
el_set(el, EL_BIND, "\\e[1;5D", "ed-prev-word", NULL);
el_set(el, EL_BIND, "\\e\\e[D", "ed-prev-word", NULL);
/* make ^w match ksh behaviour */
el_set(el, EL_BIND, "^w", "ed-delete-prev-word", NULL);
}
#endif /* USE_LIBEDIT */
remote_path = do_realpath(conn, ".");
if (remote_path == NULL)
fatal("Need cwd");
startdir = xstrdup(remote_path);
if (file1 != NULL) {
dir = xstrdup(file1);
dir = make_absolute(dir, remote_path);
if (remote_is_dir(conn, dir) && file2 == NULL) {
if (!quiet)
mprintf("Changing to: %s\n", dir);
snprintf(cmd, sizeof cmd, "cd \"%s\"", dir);
if (parse_dispatch_command(conn, cmd,
&remote_path, startdir, 1, 0) != 0) {
free(dir);
free(startdir);
free(remote_path);
free(conn);
return (-1);
}
} else {
/* XXX this is wrong wrt quoting */
snprintf(cmd, sizeof cmd, "get%s %s%s%s",
global_aflag ? " -a" : "", dir,
file2 == NULL ? "" : " ",
file2 == NULL ? "" : file2);
err = parse_dispatch_command(conn, cmd,
&remote_path, startdir, 1, 0);
free(dir);
free(startdir);
free(remote_path);
free(conn);
return (err);
}
free(dir);
}
setvbuf(stdout, NULL, _IOLBF, 0);
setvbuf(infile, NULL, _IOLBF, 0);
interactive = !batchmode && isatty(STDIN_FILENO);
err = 0;
for (;;) {
struct sigaction sa;
interrupted = 0;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = interactive ? read_interrupt : killchild;
if (sigaction(SIGINT, &sa, NULL) == -1) {
debug3("sigaction(%s): %s", strsignal(SIGINT),
strerror(errno));
break;
}
if (el == NULL) {
if (interactive)
printf("sftp> ");
if (fgets(cmd, sizeof(cmd), infile) == NULL) {
if (interactive)
printf("\n");
if (interrupted)
continue;
break;
}
} else {
#ifdef USE_LIBEDIT
const char *line;
int count = 0;
if ((line = el_gets(el, &count)) == NULL ||
count <= 0) {
printf("\n");
if (interrupted)
continue;
break;
}
history(hl, &hev, H_ENTER, line);
if (strlcpy(cmd, line, sizeof(cmd)) >= sizeof(cmd)) {
fprintf(stderr, "Error: input line too long\n");
continue;
}
#endif /* USE_LIBEDIT */
}
cmd[strcspn(cmd, "\n")] = '\0';
/* Handle user interrupts gracefully during commands */
interrupted = 0;
ssh_signal(SIGINT, cmd_interrupt);
err = parse_dispatch_command(conn, cmd, &remote_path,
startdir, batchmode, !interactive && el == NULL);
if (err != 0)
break;
}
ssh_signal(SIGCHLD, SIG_DFL);
free(remote_path);
free(startdir);
free(conn);
#ifdef USE_LIBEDIT
if (el != NULL)
el_end(el);
#endif /* USE_LIBEDIT */
/* err == 1 signifies normal "quit" exit */
return (err >= 0 ? 0 : -1);
}
static void
connect_to_server(char *path, char **args, int *in, int *out)
{
int c_in, c_out;
#ifdef USE_PIPES
int pin[2], pout[2];
if ((pipe(pin) == -1) || (pipe(pout) == -1))
fatal("pipe: %s", strerror(errno));
*in = pin[0];
*out = pout[1];
c_in = pout[0];
c_out = pin[1];
#else /* USE_PIPES */
int inout[2];
if (socketpair(AF_UNIX, SOCK_STREAM, 0, inout) == -1)
fatal("socketpair: %s", strerror(errno));
*in = *out = inout[0];
c_in = c_out = inout[1];
#endif /* USE_PIPES */
if ((sshpid = fork()) == -1)
fatal("fork: %s", strerror(errno));
else if (sshpid == 0) {
if ((dup2(c_in, STDIN_FILENO) == -1) ||
(dup2(c_out, STDOUT_FILENO) == -1)) {
fprintf(stderr, "dup2: %s\n", strerror(errno));
_exit(1);
}
close(*in);
close(*out);
close(c_in);
close(c_out);
/*
* The underlying ssh is in the same process group, so we must
* ignore SIGINT if we want to gracefully abort commands,
* otherwise the signal will make it to the ssh process and
* kill it too. Contrawise, since sftp sends SIGTERMs to the
* underlying ssh, it must *not* ignore that signal.
*/
ssh_signal(SIGINT, SIG_IGN);
ssh_signal(SIGTERM, SIG_DFL);
execvp(path, args);
fprintf(stderr, "exec: %s: %s\n", path, strerror(errno));
_exit(1);
}
ssh_signal(SIGTERM, killchild);
ssh_signal(SIGINT, killchild);
ssh_signal(SIGHUP, killchild);
ssh_signal(SIGTSTP, suspchild);
ssh_signal(SIGTTIN, suspchild);
ssh_signal(SIGTTOU, suspchild);
ssh_signal(SIGCHLD, sigchld_handler);
close(c_in);
close(c_out);
}
static void
usage(void)
{
extern char *__progname;
fprintf(stderr,
"usage: %s [-46AaCfNpqrv] [-B buffer_size] [-b batchfile] [-c cipher]\n"
" [-D sftp_server_command] [-F ssh_config] [-i identity_file]\n"
" [-J destination] [-l limit] [-o ssh_option] [-P port]\n"
" [-R num_requests] [-S program] [-s subsystem | sftp_server]\n"
- " destination\n",
+ " [-X sftp_option] destination\n",
__progname);
exit(1);
}
int
main(int argc, char **argv)
{
int r, in, out, ch, err, tmp, port = -1, noisy = 0;
char *host = NULL, *user, *cp, **cpp, *file2 = NULL;
int debug_level = 0;
char *file1 = NULL, *sftp_server = NULL;
char *ssh_program = _PATH_SSH_PROGRAM, *sftp_direct = NULL;
const char *errstr;
LogLevel ll = SYSLOG_LEVEL_INFO;
arglist args;
extern int optind;
extern char *optarg;
struct sftp_conn *conn;
size_t copy_buffer_len = 0;
size_t num_requests = 0;
- long long limit_kbps = 0;
+ long long llv, limit_kbps = 0;
/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
sanitise_stdfd();
msetlocale();
__progname = ssh_get_progname(argv[0]);
memset(&args, '\0', sizeof(args));
args.list = NULL;
addargs(&args, "%s", ssh_program);
addargs(&args, "-oForwardX11 no");
addargs(&args, "-oPermitLocalCommand no");
addargs(&args, "-oClearAllForwardings yes");
ll = SYSLOG_LEVEL_INFO;
infile = stdin;
while ((ch = getopt(argc, argv,
- "1246AafhNpqrvCc:D:i:l:o:s:S:b:B:F:J:P:R:")) != -1) {
+ "1246AafhNpqrvCc:D:i:l:o:s:S:b:B:F:J:P:R:X:")) != -1) {
switch (ch) {
/* Passed through to ssh(1) */
case 'A':
case '4':
case '6':
case 'C':
addargs(&args, "-%c", ch);
break;
/* Passed through to ssh(1) with argument */
case 'F':
case 'J':
case 'c':
case 'i':
case 'o':
addargs(&args, "-%c", ch);
addargs(&args, "%s", optarg);
break;
case 'q':
ll = SYSLOG_LEVEL_ERROR;
quiet = 1;
showprogress = 0;
addargs(&args, "-%c", ch);
break;
case 'P':
port = a2port(optarg);
if (port <= 0)
fatal("Bad port \"%s\"\n", optarg);
break;
case 'v':
if (debug_level < 3) {
addargs(&args, "-v");
ll = SYSLOG_LEVEL_DEBUG1 + debug_level;
}
debug_level++;
break;
case '1':
fatal("SSH protocol v.1 is no longer supported");
break;
case '2':
/* accept silently */
break;
case 'a':
global_aflag = 1;
break;
case 'B':
copy_buffer_len = strtol(optarg, &cp, 10);
if (copy_buffer_len == 0 || *cp != '\0')
fatal("Invalid buffer size \"%s\"", optarg);
break;
case 'b':
if (batchmode)
fatal("Batch file already specified.");
/* Allow "-" as stdin */
if (strcmp(optarg, "-") != 0 &&
(infile = fopen(optarg, "r")) == NULL)
fatal("%s (%s).", strerror(errno), optarg);
showprogress = 0;
quiet = batchmode = 1;
addargs(&args, "-obatchmode yes");
break;
case 'f':
global_fflag = 1;
break;
case 'N':
noisy = 1; /* Used to clear quiet mode after getopt */
break;
case 'p':
global_pflag = 1;
break;
case 'D':
sftp_direct = optarg;
break;
case 'l':
limit_kbps = strtonum(optarg, 1, 100 * 1024 * 1024,
&errstr);
if (errstr != NULL)
usage();
limit_kbps *= 1024; /* kbps */
break;
case 'r':
global_rflag = 1;
break;
case 'R':
num_requests = strtol(optarg, &cp, 10);
if (num_requests == 0 || *cp != '\0')
fatal("Invalid number of requests \"%s\"",
optarg);
break;
case 's':
sftp_server = optarg;
break;
case 'S':
ssh_program = optarg;
replacearg(&args, 0, "%s", ssh_program);
break;
+ case 'X':
+ /* Please keep in sync with ssh.c -X */
+ if (strncmp(optarg, "buffer=", 7) == 0) {
+ r = scan_scaled(optarg + 7, &llv);
+ if (r == 0 && (llv <= 0 || llv > 256 * 1024)) {
+ r = -1;
+ errno = EINVAL;
+ }
+ if (r == -1) {
+ fatal("Invalid buffer size \"%s\": %s",
+ optarg + 7, strerror(errno));
+ }
+ copy_buffer_len = (size_t)llv;
+ } else if (strncmp(optarg, "nrequests=", 10) == 0) {
+ llv = strtonum(optarg + 10, 1, 256 * 1024,
+ &errstr);
+ if (errstr != NULL) {
+ fatal("Invalid number of requests "
+ "\"%s\": %s", optarg + 10, errstr);
+ }
+ num_requests = (size_t)llv;
+ } else {
+ fatal("Invalid -X option");
+ }
+ break;
case 'h':
default:
usage();
}
}
/* Do this last because we want the user to be able to override it */
addargs(&args, "-oForwardAgent no");
if (!isatty(STDERR_FILENO))
showprogress = 0;
if (noisy)
quiet = 0;
log_init(argv[0], ll, SYSLOG_FACILITY_USER, 1);
if (sftp_direct == NULL) {
if (optind == argc || argc > (optind + 2))
usage();
argv += optind;
switch (parse_uri("sftp", *argv, &user, &host, &tmp, &file1)) {
case -1:
usage();
break;
case 0:
if (tmp != -1)
port = tmp;
break;
default:
/* Try with user, host and path. */
if (parse_user_host_path(*argv, &user, &host,
&file1) == 0)
break;
/* Try with user and host. */
if (parse_user_host_port(*argv, &user, &host, NULL)
== 0)
break;
/* Treat as a plain hostname. */
host = xstrdup(*argv);
host = cleanhostname(host);
break;
}
file2 = *(argv + 1);
if (!*host) {
fprintf(stderr, "Missing hostname\n");
usage();
}
if (port != -1)
addargs(&args, "-oPort %d", port);
if (user != NULL) {
addargs(&args, "-l");
addargs(&args, "%s", user);
}
/* no subsystem if the server-spec contains a '/' */
if (sftp_server == NULL || strchr(sftp_server, '/') == NULL)
addargs(&args, "-s");
addargs(&args, "--");
addargs(&args, "%s", host);
addargs(&args, "%s", (sftp_server != NULL ?
sftp_server : "sftp"));
connect_to_server(ssh_program, args.list, &in, &out);
} else {
if ((r = argv_split(sftp_direct, &tmp, &cpp, 1)) != 0)
fatal_r(r, "Parse -D arguments");
if (cpp[0] == 0)
fatal("No sftp server specified via -D");
connect_to_server(cpp[0], cpp, &in, &out);
argv_free(cpp, tmp);
}
freeargs(&args);
conn = do_init(in, out, copy_buffer_len, num_requests, limit_kbps);
if (conn == NULL)
fatal("Couldn't initialise connection to server");
if (!quiet) {
if (sftp_direct == NULL)
fprintf(stderr, "Connected to %s.\n", host);
else
fprintf(stderr, "Attached to %s.\n", sftp_direct);
}
err = interactive_loop(conn, file1, file2);
#if !defined(USE_PIPES)
shutdown(in, SHUT_RDWR);
shutdown(out, SHUT_RDWR);
#endif
close(in);
close(out);
if (batchmode)
fclose(infile);
while (waitpid(sshpid, NULL, 0) == -1 && sshpid > 1)
if (errno != EINTR)
fatal("Couldn't wait for ssh process: %s",
strerror(errno));
exit(err == 0 ? 0 : 1);
}
diff --git a/crypto/openssh/sntrup761.c b/crypto/openssh/sntrup761.c
index c63e600fb5b4..57368bd80610 100644
--- a/crypto/openssh/sntrup761.c
+++ b/crypto/openssh/sntrup761.c
@@ -1,1273 +1,1273 @@
-/* $OpenBSD: sntrup761.c,v 1.5 2021/01/08 02:33:13 dtucker Exp $ */
+/* $OpenBSD: sntrup761.c,v 1.6 2023/01/11 02:13:52 djm 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.
+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;
+
+ delta = 1;
for (loop = 0;loop < 2*p-1;++loop) {
for (i = p;i > 0;--i) v[i] = v[i-1];
v[0] = 0;
-
+
sign = -g[0]*f[0];
swap = int16_negative_mask(-delta) & int16_nonzero_mask(g[0]);
delta ^= swap&(delta^-delta);
delta += 1;
-
+
for (i = 0;i < p+1;++i) {
t = swap&(f[i]^g[i]); f[i] ^= t; g[i] ^= t;
t = swap&(v[i]^r[i]); v[i] ^= t; r[i] ^= t;
}
-
+
for (i = 0;i < p+1;++i) g[i] = F3_freeze(g[i]+sign*f[i]);
for (i = 0;i < p+1;++i) r[i] = F3_freeze(r[i]+sign*v[i]);
for (i = 0;i < p;++i) g[i] = g[i+1];
g[p] = 0;
}
-
+
sign = f[0];
for (i = 0;i < p;++i) out[i] = sign*v[p-1-i];
-
+
return int16_nonzero_mask(delta);
-}
+}
#endif
/* ----- polynomials mod q */
/* h = f*g in the ring Rq */
static void Rq_mult_small(Fq *h,const Fq *f,const small *g)
{
Fq fg[p+p-1];
Fq result;
int i,j;
for (i = 0;i < p;++i) {
result = 0;
for (j = 0;j <= i;++j) result = Fq_freeze(result+f[j]*(int32)g[i-j]);
fg[i] = result;
}
for (i = p;i < p+p-1;++i) {
result = 0;
for (j = i-p+1;j < p;++j) result = Fq_freeze(result+f[j]*(int32)g[i-j]);
fg[i] = result;
}
for (i = p+p-2;i >= p;--i) {
fg[i-p] = Fq_freeze(fg[i-p]+fg[i]);
fg[i-p+1] = Fq_freeze(fg[i-p+1]+fg[i]);
}
for (i = 0;i < p;++i) h[i] = fg[i];
}
#ifndef LPR
/* h = 3f in Rq */
static void Rq_mult3(Fq *h,const Fq *f)
{
int i;
-
+
for (i = 0;i < p;++i) h[i] = Fq_freeze(3*f[i]);
}
/* out = 1/(3*in) in Rq */
/* returns 0 if recip succeeded; else -1 */
static int Rq_recip3(Fq *out,const small *in)
-{
+{
Fq f[p+1],g[p+1],v[p+1],r[p+1];
int i,loop,delta;
int swap,t;
int32 f0,g0;
Fq scale;
for (i = 0;i < p+1;++i) v[i] = 0;
for (i = 0;i < p+1;++i) r[i] = 0;
r[0] = Fq_recip(3);
for (i = 0;i < p;++i) f[i] = 0;
f[0] = 1; f[p-1] = f[p] = -1;
for (i = 0;i < p;++i) g[p-1-i] = in[i];
g[p] = 0;
delta = 1;
for (loop = 0;loop < 2*p-1;++loop) {
for (i = p;i > 0;--i) v[i] = v[i-1];
v[0] = 0;
swap = int16_negative_mask(-delta) & int16_nonzero_mask(g[0]);
delta ^= swap&(delta^-delta);
delta += 1;
for (i = 0;i < p+1;++i) {
t = swap&(f[i]^g[i]); f[i] ^= t; g[i] ^= t;
t = swap&(v[i]^r[i]); v[i] ^= t; r[i] ^= t;
}
f0 = f[0];
g0 = g[0];
for (i = 0;i < p+1;++i) g[i] = Fq_freeze(f0*g[i]-g0*f[i]);
for (i = 0;i < p+1;++i) r[i] = Fq_freeze(f0*r[i]-g0*v[i]);
for (i = 0;i < p;++i) g[i] = g[i+1];
g[p] = 0;
}
scale = Fq_recip(f[0]);
for (i = 0;i < p;++i) out[i] = Fq_freeze(scale*(int32)v[p-1-i]);
return int16_nonzero_mask(delta);
}
#endif
/* ----- rounded polynomials mod q */
static void Round(Fq *out,const Fq *a)
{
int i;
for (i = 0;i < p;++i) out[i] = a[i]-F3_freeze(a[i]);
}
/* ----- sorting to generate short polynomial */
static void Short_fromlist(small *out,const uint32 *in)
{
uint32 L[p];
int i;
for (i = 0;i < w;++i) L[i] = in[i]&(uint32)-2;
for (i = w;i < p;++i) L[i] = (in[i]&(uint32)-3)|1;
crypto_sort_uint32(L,p);
for (i = 0;i < p;++i) out[i] = (L[i]&3)-1;
}
/* ----- underlying hash function */
#define Hash_bytes 32
/* e.g., b = 0 means out = Hash0(in) */
static void Hash_prefix(unsigned char *out,int b,const unsigned char *in,int inlen)
{
unsigned char x[inlen+1];
unsigned char h[64];
int i;
x[0] = b;
for (i = 0;i < inlen;++i) x[i+1] = in[i];
crypto_hash_sha512(h,x,inlen+1);
for (i = 0;i < 32;++i) out[i] = h[i];
}
/* ----- higher-level randomness */
static uint32 urandom32(void)
{
unsigned char c[4];
uint32 out[4];
randombytes(c,4);
out[0] = (uint32)c[0];
out[1] = ((uint32)c[1])<<8;
out[2] = ((uint32)c[2])<<16;
out[3] = ((uint32)c[3])<<24;
return out[0]+out[1]+out[2]+out[3];
}
static void Short_random(small *out)
{
uint32 L[p];
int i;
for (i = 0;i < p;++i) L[i] = urandom32();
Short_fromlist(out,L);
}
#ifndef LPR
static void Small_random(small *out)
{
int i;
for (i = 0;i < p;++i) out[i] = (((urandom32()&0x3fffffff)*3)>>30)-1;
}
#endif
/* ----- Streamlined NTRU Prime Core */
#ifndef LPR
/* h,(f,ginv) = KeyGen() */
static void KeyGen(Fq *h,small *f,small *ginv)
{
small g[p];
Fq finv[p];
-
+
for (;;) {
Small_random(g);
if (R3_recip(ginv,g) == 0) break;
}
Short_random(f);
Rq_recip3(finv,f); /* always works */
Rq_mult_small(h,finv,g);
}
/* c = Encrypt(r,h) */
static void Encrypt(Fq *c,const small *r,const Fq *h)
{
Fq hr[p];
Rq_mult_small(hr,h,r);
Round(c,hr);
}
/* r = Decrypt(c,(f,ginv)) */
static void Decrypt(small *r,const Fq *c,const small *f,const small *ginv)
{
Fq cf[p];
Fq cf3[p];
small e[p];
small ev[p];
int mask;
int i;
Rq_mult_small(cf,c,f);
Rq_mult3(cf3,cf);
R3_fromRq(e,cf3);
R3_mult(ev,e,ginv);
mask = Weightw_mask(ev); /* 0 if weight w, else -1 */
for (i = 0;i < w;++i) r[i] = ((ev[i]^1)&~mask)^1;
for (i = w;i < p;++i) r[i] = ev[i]&~mask;
}
-
+
#endif
/* ----- NTRU LPRime Core */
#ifdef LPR
/* (G,A),a = KeyGen(G); leaves G unchanged */
static void KeyGen(Fq *A,small *a,const Fq *G)
{
Fq aG[p];
Short_random(a);
Rq_mult_small(aG,G,a);
Round(A,aG);
}
/* B,T = Encrypt(r,(G,A),b) */
static void Encrypt(Fq *B,int8 *T,const int8 *r,const Fq *G,const Fq *A,const small *b)
{
Fq bG[p];
Fq bA[p];
int i;
Rq_mult_small(bG,G,b);
Round(B,bG);
Rq_mult_small(bA,A,b);
for (i = 0;i < I;++i) T[i] = Top(Fq_freeze(bA[i]+r[i]*q12));
}
/* r = Decrypt((B,T),a) */
static void Decrypt(int8 *r,const Fq *B,const int8 *T,const small *a)
{
Fq aB[p];
int i;
Rq_mult_small(aB,B,a);
for (i = 0;i < I;++i)
r[i] = -int16_negative_mask(Fq_freeze(Right(T[i])-aB[i]+4*w+1));
}
-
+
#endif
/* ----- encoding I-bit inputs */
#ifdef LPR
#define Inputs_bytes (I/8)
typedef int8 Inputs[I]; /* passed by reference */
static void Inputs_encode(unsigned char *s,const Inputs r)
{
int i;
for (i = 0;i < Inputs_bytes;++i) s[i] = 0;
for (i = 0;i < I;++i) s[i>>3] |= r[i]<<(i&7);
}
#endif
/* ----- Expand */
#ifdef LPR
static const unsigned char aes_nonce[16] = {0};
static void Expand(uint32 *L,const unsigned char *k)
{
int i;
crypto_stream_aes256ctr((unsigned char *) L,4*p,aes_nonce,k);
for (i = 0;i < p;++i) {
uint32 L0 = ((unsigned char *) L)[4*i];
uint32 L1 = ((unsigned char *) L)[4*i+1];
uint32 L2 = ((unsigned char *) L)[4*i+2];
uint32 L3 = ((unsigned char *) L)[4*i+3];
L[i] = L0+(L1<<8)+(L2<<16)+(L3<<24);
}
}
#endif
/* ----- Seeds */
#ifdef LPR
#define Seeds_bytes 32
static void Seeds_random(unsigned char *s)
{
randombytes(s,Seeds_bytes);
}
#endif
/* ----- Generator, HashShort */
#ifdef LPR
/* G = Generator(k) */
static void Generator(Fq *G,const unsigned char *k)
{
uint32 L[p];
int i;
Expand(L,k);
for (i = 0;i < p;++i) G[i] = uint32_mod_uint14(L[i],q)-q12;
}
/* out = HashShort(r) */
static void HashShort(small *out,const Inputs r)
{
unsigned char s[Inputs_bytes];
unsigned char h[Hash_bytes];
uint32 L[p];
Inputs_encode(s,r);
Hash_prefix(h,5,s,sizeof s);
Expand(L,h);
Short_fromlist(out,L);
}
#endif
-
+
/* ----- NTRU LPRime Expand */
#ifdef LPR
/* (S,A),a = XKeyGen() */
static void XKeyGen(unsigned char *S,Fq *A,small *a)
{
Fq G[p];
Seeds_random(S);
Generator(G,S);
KeyGen(A,a,G);
}
/* B,T = XEncrypt(r,(S,A)) */
static void XEncrypt(Fq *B,int8 *T,const int8 *r,const unsigned char *S,const Fq *A)
{
Fq G[p];
small b[p];
Generator(G,S);
HashShort(b,r);
Encrypt(B,T,r,G,A,b);
}
#define XDecrypt Decrypt
#endif
/* ----- encoding small polynomials (including short polynomials) */
#define Small_bytes ((p+3)/4)
/* these are the only functions that rely on p mod 4 = 1 */
static void Small_encode(unsigned char *s,const small *f)
{
small x;
int i;
for (i = 0;i < p/4;++i) {
x = *f++ + 1;
x += (*f++ + 1)<<2;
x += (*f++ + 1)<<4;
x += (*f++ + 1)<<6;
*s++ = x;
}
x = *f++ + 1;
*s++ = x;
}
static void Small_decode(small *f,const unsigned char *s)
{
unsigned char x;
int i;
for (i = 0;i < p/4;++i) {
x = *s++;
*f++ = ((small)(x&3))-1; x >>= 2;
*f++ = ((small)(x&3))-1; x >>= 2;
*f++ = ((small)(x&3))-1; x >>= 2;
*f++ = ((small)(x&3))-1;
}
x = *s++;
*f++ = ((small)(x&3))-1;
}
/* ----- encoding general polynomials */
#ifndef LPR
static void Rq_encode(unsigned char *s,const Fq *r)
{
uint16 R[p],M[p];
int i;
-
+
for (i = 0;i < p;++i) R[i] = r[i]+q12;
for (i = 0;i < p;++i) M[i] = q;
Encode(s,R,M,p);
}
static void Rq_decode(Fq *r,const unsigned char *s)
{
uint16 R[p],M[p];
int i;
for (i = 0;i < p;++i) M[i] = q;
Decode(R,s,M,p);
for (i = 0;i < p;++i) r[i] = ((Fq)R[i])-q12;
}
-
+
#endif
/* ----- encoding rounded polynomials */
static void Rounded_encode(unsigned char *s,const Fq *r)
{
uint16 R[p],M[p];
int i;
for (i = 0;i < p;++i) R[i] = ((r[i]+q12)*10923)>>15;
for (i = 0;i < p;++i) M[i] = (q+2)/3;
Encode(s,R,M,p);
}
static void Rounded_decode(Fq *r,const unsigned char *s)
{
uint16 R[p],M[p];
int i;
for (i = 0;i < p;++i) M[i] = (q+2)/3;
Decode(R,s,M,p);
for (i = 0;i < p;++i) r[i] = R[i]*3-q12;
}
/* ----- encoding top polynomials */
#ifdef LPR
#define Top_bytes (I/2)
static void Top_encode(unsigned char *s,const int8 *T)
{
int i;
for (i = 0;i < Top_bytes;++i)
s[i] = T[2*i]+(T[2*i+1]<<4);
}
static void Top_decode(int8 *T,const unsigned char *s)
{
int i;
for (i = 0;i < Top_bytes;++i) {
T[2*i] = s[i]&15;
T[2*i+1] = s[i]>>4;
}
}
#endif
/* ----- Streamlined NTRU Prime Core plus encoding */
#ifndef LPR
typedef small Inputs[p]; /* passed by reference */
#define Inputs_random Short_random
#define Inputs_encode Small_encode
#define Inputs_bytes Small_bytes
#define Ciphertexts_bytes Rounded_bytes
#define SecretKeys_bytes (2*Small_bytes)
#define PublicKeys_bytes Rq_bytes
/* pk,sk = ZKeyGen() */
static void ZKeyGen(unsigned char *pk,unsigned char *sk)
{
Fq h[p];
small f[p],v[p];
KeyGen(h,f,v);
Rq_encode(pk,h);
Small_encode(sk,f); sk += Small_bytes;
Small_encode(sk,v);
}
/* C = ZEncrypt(r,pk) */
static void ZEncrypt(unsigned char *C,const Inputs r,const unsigned char *pk)
{
Fq h[p];
Fq c[p];
Rq_decode(h,pk);
Encrypt(c,r,h);
Rounded_encode(C,c);
}
/* r = ZDecrypt(C,sk) */
static void ZDecrypt(Inputs r,const unsigned char *C,const unsigned char *sk)
{
small f[p],v[p];
Fq c[p];
Small_decode(f,sk); sk += Small_bytes;
Small_decode(v,sk);
Rounded_decode(c,C);
Decrypt(r,c,f,v);
}
#endif
/* ----- NTRU LPRime Expand plus encoding */
#ifdef LPR
#define Ciphertexts_bytes (Rounded_bytes+Top_bytes)
#define SecretKeys_bytes Small_bytes
#define PublicKeys_bytes (Seeds_bytes+Rounded_bytes)
static void Inputs_random(Inputs r)
{
unsigned char s[Inputs_bytes];
int i;
randombytes(s,sizeof s);
for (i = 0;i < I;++i) r[i] = 1&(s[i>>3]>>(i&7));
}
/* pk,sk = ZKeyGen() */
static void ZKeyGen(unsigned char *pk,unsigned char *sk)
{
Fq A[p];
small a[p];
XKeyGen(pk,A,a); pk += Seeds_bytes;
Rounded_encode(pk,A);
Small_encode(sk,a);
}
/* c = ZEncrypt(r,pk) */
static void ZEncrypt(unsigned char *c,const Inputs r,const unsigned char *pk)
{
Fq A[p];
Fq B[p];
int8 T[I];
Rounded_decode(A,pk+Seeds_bytes);
XEncrypt(B,T,r,pk,A);
Rounded_encode(c,B); c += Rounded_bytes;
Top_encode(c,T);
}
/* r = ZDecrypt(C,sk) */
static void ZDecrypt(Inputs r,const unsigned char *c,const unsigned char *sk)
{
small a[p];
Fq B[p];
int8 T[I];
Small_decode(a,sk);
Rounded_decode(B,c);
Top_decode(T,c+Rounded_bytes);
XDecrypt(r,B,T,a);
}
#endif
/* ----- confirmation hash */
#define Confirm_bytes 32
/* h = HashConfirm(r,pk,cache); cache is Hash4(pk) */
static void HashConfirm(unsigned char *h,const unsigned char *r,const unsigned char *pk,const unsigned char *cache)
{
#ifndef LPR
unsigned char x[Hash_bytes*2];
int i;
Hash_prefix(x,3,r,Inputs_bytes);
for (i = 0;i < Hash_bytes;++i) x[Hash_bytes+i] = cache[i];
#else
unsigned char x[Inputs_bytes+Hash_bytes];
int i;
for (i = 0;i < Inputs_bytes;++i) x[i] = r[i];
for (i = 0;i < Hash_bytes;++i) x[Inputs_bytes+i] = cache[i];
#endif
Hash_prefix(h,2,x,sizeof x);
}
/* ----- session-key hash */
/* k = HashSession(b,y,z) */
static void HashSession(unsigned char *k,int b,const unsigned char *y,const unsigned char *z)
{
#ifndef LPR
unsigned char x[Hash_bytes+Ciphertexts_bytes+Confirm_bytes];
int i;
Hash_prefix(x,3,y,Inputs_bytes);
for (i = 0;i < Ciphertexts_bytes+Confirm_bytes;++i) x[Hash_bytes+i] = z[i];
#else
unsigned char x[Inputs_bytes+Ciphertexts_bytes+Confirm_bytes];
int i;
for (i = 0;i < Inputs_bytes;++i) x[i] = y[i];
for (i = 0;i < Ciphertexts_bytes+Confirm_bytes;++i) x[Inputs_bytes+i] = z[i];
#endif
Hash_prefix(k,b,x,sizeof x);
}
/* ----- Streamlined NTRU Prime and NTRU LPRime */
/* pk,sk = KEM_KeyGen() */
static void KEM_KeyGen(unsigned char *pk,unsigned char *sk)
{
int i;
ZKeyGen(pk,sk); sk += SecretKeys_bytes;
for (i = 0;i < PublicKeys_bytes;++i) *sk++ = pk[i];
randombytes(sk,Inputs_bytes); sk += Inputs_bytes;
Hash_prefix(sk,4,pk,PublicKeys_bytes);
}
/* c,r_enc = Hide(r,pk,cache); cache is Hash4(pk) */
static void Hide(unsigned char *c,unsigned char *r_enc,const Inputs r,const unsigned char *pk,const unsigned char *cache)
{
Inputs_encode(r_enc,r);
ZEncrypt(c,r,pk); c += Ciphertexts_bytes;
HashConfirm(c,r_enc,pk,cache);
}
/* c,k = Encap(pk) */
static void Encap(unsigned char *c,unsigned char *k,const unsigned char *pk)
{
Inputs r;
unsigned char r_enc[Inputs_bytes];
unsigned char cache[Hash_bytes];
Hash_prefix(cache,4,pk,PublicKeys_bytes);
Inputs_random(r);
Hide(c,r_enc,r,pk,cache);
HashSession(k,1,r_enc,c);
}
/* 0 if matching ciphertext+confirm, else -1 */
static int Ciphertexts_diff_mask(const unsigned char *c,const unsigned char *c2)
{
uint16 differentbits = 0;
int len = Ciphertexts_bytes+Confirm_bytes;
while (len-- > 0) differentbits |= (*c++)^(*c2++);
return (1&((differentbits-1)>>8))-1;
}
/* k = Decap(c,sk) */
static void Decap(unsigned char *k,const unsigned char *c,const unsigned char *sk)
{
const unsigned char *pk = sk + SecretKeys_bytes;
const unsigned char *rho = pk + PublicKeys_bytes;
const unsigned char *cache = rho + Inputs_bytes;
Inputs r;
unsigned char r_enc[Inputs_bytes];
unsigned char cnew[Ciphertexts_bytes+Confirm_bytes];
int mask;
int i;
ZDecrypt(r,c,sk);
Hide(cnew,r_enc,r,pk,cache);
mask = Ciphertexts_diff_mask(c,cnew);
for (i = 0;i < Inputs_bytes;++i) r_enc[i] ^= mask&(r_enc[i]^rho[i]);
HashSession(k,1+mask,r_enc,c);
}
/* ----- crypto_kem API */
int crypto_kem_sntrup761_keypair(unsigned char *pk,unsigned char *sk)
{
KEM_KeyGen(pk,sk);
return 0;
}
int crypto_kem_sntrup761_enc(unsigned char *c,unsigned char *k,const unsigned char *pk)
{
Encap(c,k,pk);
return 0;
}
int crypto_kem_sntrup761_dec(unsigned char *k,const unsigned char *c,const unsigned char *sk)
{
Decap(k,c,sk);
return 0;
}
#endif /* USE_SNTRUP761X25519 */
diff --git a/crypto/openssh/sntrup761.sh b/crypto/openssh/sntrup761.sh
index 5cd5f92c31d7..db4e9aed08ac 100644
--- a/crypto/openssh/sntrup761.sh
+++ b/crypto/openssh/sntrup761.sh
@@ -1,85 +1,86 @@
#!/bin/sh
-# $OpenBSD: sntrup761.sh,v 1.5 2021/01/08 02:33:13 dtucker Exp $
+# $OpenBSD: sntrup761.sh,v 1.7 2023/01/11 02:13:52 djm 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.
+ # - remove unnecessary 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" \
+ -e 's/[ ]*$//' \
$i | \
case "$i" in
# Use int64_t for intermediate values in int32_MINMAX to prevent signed
# 32-bit integer overflow when called by crypto_sort_uint32.
*/int32_minmax.inc)
sed -e "s/int32 ab = b ^ a/int64_t ab = (int64_t)b ^ (int64_t)a/" \
-e "s/int32 c = b - a/int64_t c = (int64_t)b - (int64_t)a/"
;;
*/int32/portable4/sort.c)
sed -e "s/void crypto_sort/void crypto_sort_int32/g"
;;
*/uint32/useint32/sort.c)
sed -e "s/void crypto_sort/void crypto_sort_uint32/g"
;;
# Remove unused function to prevent warning.
*/crypto_kem/sntrup761/ref/int32.c)
sed -e '/ int32_div_uint14/,/^}$/d'
;;
# Remove unused function to prevent warning.
*/crypto_kem/sntrup761/ref/uint32.c)
sed -e '/ uint32_div_uint14/,/^}$/d'
;;
# Default: pass through.
*)
cat
;;
esac
echo
done
diff --git a/crypto/openssh/ssh-agent.1 b/crypto/openssh/ssh-agent.1
index e918691ba9f7..e1fe387ebaf5 100644
--- a/crypto/openssh/ssh-agent.1
+++ b/crypto/openssh/ssh-agent.1
@@ -1,235 +1,258 @@
-.\" $OpenBSD: ssh-agent.1,v 1.73 2022/03/31 17:27:27 naddy Exp $
+.\" $OpenBSD: ssh-agent.1,v 1.75 2022/10/07 06:00:58 jmc Exp $
.\"
.\" Author: Tatu Ylonen <ylo@cs.hut.fi>
.\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
.\" All rights reserved
.\"
.\" As far as I am concerned, the code I have written for this software
.\" can be used freely for any purpose. Any derived versions of this
.\" software must be clearly marked as such, and if the derived work is
.\" incompatible with the protocol description in the RFC file, it must be
.\" called by a name other than "ssh" or "Secure Shell".
.\"
.\" Copyright (c) 1999,2000 Markus Friedl. All rights reserved.
.\" Copyright (c) 1999 Aaron Campbell. All rights reserved.
.\" Copyright (c) 1999 Theo de Raadt. All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd $Mdocdate: March 31 2022 $
+.Dd $Mdocdate: October 7 2022 $
.Dt SSH-AGENT 1
.Os
.Sh NAME
.Nm ssh-agent
.Nd OpenSSH authentication agent
.Sh SYNOPSIS
.Nm ssh-agent
.Op Fl c | s
.Op Fl \&Ddx
.Op Fl a Ar bind_address
.Op Fl E Ar fingerprint_hash
+.Op Fl O Ar option
.Op Fl P Ar allowed_providers
.Op Fl t Ar life
.Nm ssh-agent
.Op Fl a Ar bind_address
.Op Fl E Ar fingerprint_hash
+.Op Fl O Ar option
.Op Fl P Ar allowed_providers
.Op Fl t Ar life
.Ar command Op Ar arg ...
.Nm ssh-agent
.Op Fl c | s
.Fl k
.Sh DESCRIPTION
.Nm
is a program to hold private keys used for public key authentication.
Through use of environment variables the agent can be located
and automatically used for authentication when logging in to other
machines using
.Xr ssh 1 .
.Pp
The options are as follows:
.Bl -tag -width Ds
.It Fl a Ar bind_address
Bind the agent to the
.Ux Ns -domain
socket
.Ar bind_address .
The default is
.Pa $TMPDIR/ssh-XXXXXXXXXX/agent.\*(Ltppid\*(Gt .
.It Fl c
Generate C-shell commands on
.Dv stdout .
This is the default if
.Ev SHELL
looks like it's a csh style of shell.
.It Fl D
Foreground mode.
When this option is specified,
.Nm
will not fork.
.It Fl d
Debug mode.
When this option is specified,
.Nm
will not fork and will write debug information to standard error.
.It Fl E Ar fingerprint_hash
Specifies the hash algorithm used when displaying key fingerprints.
Valid options are:
.Dq md5
and
.Dq sha256 .
The default is
.Dq sha256 .
.It Fl k
Kill the current agent (given by the
.Ev SSH_AGENT_PID
environment variable).
+.It Fl O Ar option
+Specify an option when starting
+.Nm .
+Currently only one option is supported:
+.Cm no-restrict-websafe .
+This instructs
+.Nm
+to permit signatures using FIDO keys that might be web authentication
+requests.
+By default,
+.Nm
+refuses signature requests for FIDO keys where the key application string
+does not start with
+.Dq ssh:
+and when the data to be signed does not appear to be a
+.Xr ssh 1
+user authentication request or a
+.Xr ssh-keygen 1
+signature.
+The default behaviour prevents forwarded access to a FIDO key from also
+implicitly forwarding the ability to authenticate to websites.
.It Fl P Ar allowed_providers
Specify a pattern-list of acceptable paths for PKCS#11 provider and FIDO
authenticator middleware shared libraries that may be used with the
.Fl S
or
.Fl s
options to
.Xr ssh-add 1 .
Libraries that do not match the pattern list will be refused.
See PATTERNS in
.Xr ssh_config 5
for a description of pattern-list syntax.
The default list is
.Dq /usr/lib/*,/usr/local/lib/* .
.It Fl s
Generate Bourne shell commands on
.Dv stdout .
This is the default if
.Ev SHELL
does not look like it's a csh style of shell.
.It Fl t Ar life
Set a default value for the maximum lifetime of identities added to the agent.
The lifetime may be specified in seconds or in a time format specified in
.Xr sshd_config 5 .
A lifetime specified for an identity with
.Xr ssh-add 1
overrides this value.
Without this option the default maximum lifetime is forever.
.It Fl x
Exit after the last client has disconnected.
.It Ar command Op Ar arg ...
If a command (and optional arguments) is given,
this is executed as a subprocess of the agent.
The agent exits automatically when the command given on the command
line terminates.
.El
.Pp
There are two main ways to get an agent set up.
The first is at the start of an X session,
where all other windows or programs are started as children of the
.Nm
program.
The agent starts a command under which its environment
variables are exported, for example
.Cm ssh-agent xterm & .
When the command terminates, so does the agent.
.Pp
The second method is used for a login session.
When
.Nm
is started,
it prints the shell commands required to set its environment variables,
which in turn can be evaluated in the calling shell, for example
.Cm eval `ssh-agent -s` .
.Pp
In both cases,
.Xr ssh 1
looks at these 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
.Xr ssh-add 1
or by
.Xr ssh 1
when
.Cm AddKeysToAgent
is set in
.Xr ssh_config 5 .
Multiple identities may be stored in
.Nm
concurrently and
.Xr ssh 1
will automatically use them if present.
.Xr ssh-add 1
is also used to remove keys from
.Nm
and to query the keys that are held in one.
.Pp
Connections to
.Nm
may be forwarded from further remote hosts using the
.Fl A
option to
.Xr ssh 1
(but see the caveats documented therein),
avoiding the need for authentication data to be stored on other machines.
Authentication passphrases and private keys never go over the network:
the connection to the agent is forwarded over SSH remote connections
and the result is returned to the requester,
allowing the user access to their identities anywhere in the network
in a secure fashion.
.Sh ENVIRONMENT
.Bl -tag -width "SSH_AGENT_PID"
.It Ev SSH_AGENT_PID
When
.Nm
starts, it stores the name of the agent's process ID (PID) in this variable.
.It Ev SSH_AUTH_SOCK
When
.Nm
starts, it creates a
.Ux Ns -domain
socket and stores its pathname in this variable.
It is accessible only to the current user,
but is easily abused by root or another instance of the same user.
.El
.Sh FILES
.Bl -tag -width Ds
.It Pa $TMPDIR/ssh-XXXXXXXXXX/agent.<ppid>
.Ux Ns -domain
sockets used to contain the connection to the authentication agent.
These sockets should only be readable by the owner.
The sockets should get automatically removed when the agent exits.
.El
.Sh SEE ALSO
.Xr ssh 1 ,
.Xr ssh-add 1 ,
.Xr ssh-keygen 1 ,
.Xr ssh_config 5 ,
.Xr sshd 8
.Sh AUTHORS
.An -nosplit
OpenSSH is a derivative of the original and free ssh 1.2.12 release by
.An Tatu Ylonen .
.An Aaron Campbell , Bob Beck , Markus Friedl , Niels Provos , Theo de Raadt
and
.An Dug Song
removed many bugs, re-added newer features and created OpenSSH.
.An Markus Friedl
contributed the support for SSH protocol versions 1.5 and 2.0.
diff --git a/crypto/openssh/ssh-agent.c b/crypto/openssh/ssh-agent.c
index 9db1d353ccfd..f1e9247547e6 100644
--- a/crypto/openssh/ssh-agent.c
+++ b/crypto/openssh/ssh-agent.c
@@ -1,2299 +1,2298 @@
-/* $OpenBSD: ssh-agent.c,v 1.292 2022/09/17 10:11:29 djm Exp $ */
+/* $OpenBSD: ssh-agent.c,v 1.294 2022/12/04 11:03:11 dtucker Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
* The authentication agent program.
*
* As far as I am concerned, the code I have written for this software
* can be used freely for any purpose. Any derived versions of this
* software must be clearly marked as such, and if the derived work is
* incompatible with the protocol description in the RFC file, it must be
* called by a name other than "ssh" or "Secure Shell".
*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "includes.h"
#include <sys/types.h>
#include <sys/resource.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/wait.h>
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
#endif
#ifdef HAVE_SYS_UN_H
# include <sys/un.h>
#endif
#include "openbsd-compat/sys-queue.h"
#ifdef WITH_OPENSSL
#include <openssl/evp.h>
#include "openbsd-compat/openssl-compat.h"
#endif
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#ifdef HAVE_PATHS_H
# include <paths.h>
#endif
#ifdef HAVE_POLL_H
# include <poll.h>
#endif
#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <unistd.h>
#ifdef HAVE_UTIL_H
# include <util.h>
#endif
#include "xmalloc.h"
#include "ssh.h"
#include "ssh2.h"
#include "sshbuf.h"
#include "sshkey.h"
#include "authfd.h"
#include "compat.h"
#include "log.h"
#include "misc.h"
#include "digest.h"
#include "ssherr.h"
#include "match.h"
#include "msg.h"
-#include "ssherr.h"
#include "pathnames.h"
#include "ssh-pkcs11.h"
#include "sk-api.h"
#include "myproposal.h"
#ifndef DEFAULT_ALLOWED_PROVIDERS
# define DEFAULT_ALLOWED_PROVIDERS "/usr/lib*/*,/usr/local/lib*/*"
#endif
/* Maximum accepted message length */
#define AGENT_MAX_LEN (256*1024)
/* Maximum bytes to read from client socket */
#define AGENT_RBUF_LEN (4096)
/* Maximum number of recorded session IDs/hostkeys per connection */
#define AGENT_MAX_SESSION_IDS 16
/* Maximum size of session ID */
#define AGENT_MAX_SID_LEN 128
/* Maximum number of destination constraints to accept on a key */
#define AGENT_MAX_DEST_CONSTRAINTS 1024
/* XXX store hostkey_sid in a refcounted tree */
typedef enum {
AUTH_UNUSED = 0,
AUTH_SOCKET = 1,
AUTH_CONNECTION = 2,
} sock_type;
struct hostkey_sid {
struct sshkey *key;
struct sshbuf *sid;
int forwarded;
};
typedef struct socket_entry {
int fd;
sock_type type;
struct sshbuf *input;
struct sshbuf *output;
struct sshbuf *request;
size_t nsession_ids;
struct hostkey_sid *session_ids;
} SocketEntry;
u_int sockets_alloc = 0;
SocketEntry *sockets = NULL;
typedef struct identity {
TAILQ_ENTRY(identity) next;
struct sshkey *key;
char *comment;
char *provider;
time_t death;
u_int confirm;
char *sk_provider;
struct dest_constraint *dest_constraints;
size_t ndest_constraints;
} Identity;
struct idtable {
int nentries;
TAILQ_HEAD(idqueue, identity) idlist;
};
/* private key table */
struct idtable *idtab;
int max_fd = 0;
/* pid of shell == parent of agent */
pid_t parent_pid = -1;
time_t parent_alive_interval = 0;
/* pid of process for which cleanup_socket is applicable */
pid_t cleanup_pid = 0;
/* pathname and directory for AUTH_SOCKET */
char socket_name[PATH_MAX];
char socket_dir[PATH_MAX];
/* Pattern-list of allowed PKCS#11/Security key paths */
static char *allowed_providers;
/* locking */
#define LOCK_SIZE 32
#define LOCK_SALT_SIZE 16
#define LOCK_ROUNDS 1
int locked = 0;
u_char lock_pwhash[LOCK_SIZE];
u_char lock_salt[LOCK_SALT_SIZE];
extern char *__progname;
/* Default lifetime in seconds (0 == forever) */
static int lifetime = 0;
static int fingerprint_hash = SSH_FP_HASH_DEFAULT;
/* Refuse signing of non-SSH messages for web-origin FIDO keys */
static int restrict_websafe = 1;
/*
* Client connection count; incremented in new_socket() and decremented in
* close_socket(). When it reaches 0, ssh-agent will exit. Since it is
* normally initialized to 1, it will never reach 0. However, if the -x
* option is specified, it is initialized to 0 in main(); in that case,
* ssh-agent will exit as soon as it has had at least one client but no
* longer has any.
*/
static int xcount = 1;
static void
close_socket(SocketEntry *e)
{
size_t i;
int last = 0;
if (e->type == AUTH_CONNECTION) {
debug("xcount %d -> %d", xcount, xcount - 1);
if (--xcount == 0)
last = 1;
}
close(e->fd);
sshbuf_free(e->input);
sshbuf_free(e->output);
sshbuf_free(e->request);
for (i = 0; i < e->nsession_ids; i++) {
sshkey_free(e->session_ids[i].key);
sshbuf_free(e->session_ids[i].sid);
}
free(e->session_ids);
memset(e, '\0', sizeof(*e));
e->fd = -1;
e->type = AUTH_UNUSED;
if (last)
cleanup_exit(0);
}
static void
idtab_init(void)
{
idtab = xcalloc(1, sizeof(*idtab));
TAILQ_INIT(&idtab->idlist);
idtab->nentries = 0;
}
static void
free_dest_constraint_hop(struct dest_constraint_hop *dch)
{
u_int i;
if (dch == NULL)
return;
free(dch->user);
free(dch->hostname);
for (i = 0; i < dch->nkeys; i++)
sshkey_free(dch->keys[i]);
free(dch->keys);
free(dch->key_is_ca);
}
static void
free_dest_constraints(struct dest_constraint *dcs, size_t ndcs)
{
size_t i;
for (i = 0; i < ndcs; i++) {
free_dest_constraint_hop(&dcs[i].from);
free_dest_constraint_hop(&dcs[i].to);
}
free(dcs);
}
static void
free_identity(Identity *id)
{
sshkey_free(id->key);
free(id->provider);
free(id->comment);
free(id->sk_provider);
free_dest_constraints(id->dest_constraints, id->ndest_constraints);
free(id);
}
/*
* Match 'key' against the key/CA list in a destination constraint hop
* Returns 0 on success or -1 otherwise.
*/
static int
match_key_hop(const char *tag, const struct sshkey *key,
const struct dest_constraint_hop *dch)
{
const char *reason = NULL;
const char *hostname = dch->hostname ? dch->hostname : "(ORIGIN)";
u_int i;
char *fp;
if (key == NULL)
return -1;
/* XXX logspam */
if ((fp = sshkey_fingerprint(key, SSH_FP_HASH_DEFAULT,
SSH_FP_DEFAULT)) == NULL)
fatal_f("fingerprint failed");
debug3_f("%s: entering hostname %s, requested key %s %s, %u keys avail",
tag, hostname, sshkey_type(key), fp, dch->nkeys);
free(fp);
for (i = 0; i < dch->nkeys; i++) {
if (dch->keys[i] == NULL)
return -1;
/* XXX logspam */
if ((fp = sshkey_fingerprint(dch->keys[i], SSH_FP_HASH_DEFAULT,
SSH_FP_DEFAULT)) == NULL)
fatal_f("fingerprint failed");
debug3_f("%s: key %u: %s%s %s", tag, i,
dch->key_is_ca[i] ? "CA " : "",
sshkey_type(dch->keys[i]), fp);
free(fp);
if (!sshkey_is_cert(key)) {
/* plain key */
if (dch->key_is_ca[i] ||
!sshkey_equal(key, dch->keys[i]))
continue;
return 0;
}
/* certificate */
if (!dch->key_is_ca[i])
continue;
if (key->cert == NULL || key->cert->signature_key == NULL)
return -1; /* shouldn't happen */
if (!sshkey_equal(key->cert->signature_key, dch->keys[i]))
continue;
if (sshkey_cert_check_host(key, hostname, 1,
SSH_ALLOWED_CA_SIGALGS, &reason) != 0) {
debug_f("cert %s / hostname %s rejected: %s",
key->cert->key_id, hostname, reason);
continue;
}
return 0;
}
return -1;
}
/* Check destination constraints on an identity against the hostkey/user */
static int
permitted_by_dest_constraints(const struct sshkey *fromkey,
const struct sshkey *tokey, Identity *id, const char *user,
const char **hostnamep)
{
size_t i;
struct dest_constraint *d;
if (hostnamep != NULL)
*hostnamep = NULL;
for (i = 0; i < id->ndest_constraints; i++) {
d = id->dest_constraints + i;
/* XXX remove logspam */
debug2_f("constraint %zu %s%s%s (%u keys) > %s%s%s (%u keys)",
i, d->from.user ? d->from.user : "",
d->from.user ? "@" : "",
d->from.hostname ? d->from.hostname : "(ORIGIN)",
d->from.nkeys,
d->to.user ? d->to.user : "", d->to.user ? "@" : "",
d->to.hostname ? d->to.hostname : "(ANY)", d->to.nkeys);
/* Match 'from' key */
if (fromkey == NULL) {
/* We are matching the first hop */
if (d->from.hostname != NULL || d->from.nkeys != 0)
continue;
} else if (match_key_hop("from", fromkey, &d->from) != 0)
continue;
/* Match 'to' key */
if (tokey != NULL && match_key_hop("to", tokey, &d->to) != 0)
continue;
/* Match user if specified */
if (d->to.user != NULL && user != NULL &&
!match_pattern(user, d->to.user))
continue;
/* successfully matched this constraint */
if (hostnamep != NULL)
*hostnamep = d->to.hostname;
debug2_f("allowed for hostname %s",
d->to.hostname == NULL ? "*" : d->to.hostname);
return 0;
}
/* no match */
debug2_f("%s identity \"%s\" not permitted for this destination",
sshkey_type(id->key), id->comment);
return -1;
}
/*
* Check whether hostkeys on a SocketEntry and the optionally specified user
* are permitted by the destination constraints on the Identity.
* Returns 0 on success or -1 otherwise.
*/
static int
identity_permitted(Identity *id, SocketEntry *e, char *user,
const char **forward_hostnamep, const char **last_hostnamep)
{
size_t i;
const char **hp;
struct hostkey_sid *hks;
const struct sshkey *fromkey = NULL;
const char *test_user;
char *fp1, *fp2;
/* XXX remove logspam */
debug3_f("entering: key %s comment \"%s\", %zu socket bindings, "
"%zu constraints", sshkey_type(id->key), id->comment,
e->nsession_ids, id->ndest_constraints);
if (id->ndest_constraints == 0)
return 0; /* unconstrained */
if (e->nsession_ids == 0)
return 0; /* local use */
/*
* Walk through the hops recorded by session_id and try to find a
* constraint that satisfies each.
*/
for (i = 0; i < e->nsession_ids; i++) {
hks = e->session_ids + i;
if (hks->key == NULL)
fatal_f("internal error: no bound key");
/* XXX remove logspam */
fp1 = fp2 = NULL;
if (fromkey != NULL &&
(fp1 = sshkey_fingerprint(fromkey, SSH_FP_HASH_DEFAULT,
SSH_FP_DEFAULT)) == NULL)
fatal_f("fingerprint failed");
if ((fp2 = sshkey_fingerprint(hks->key, SSH_FP_HASH_DEFAULT,
SSH_FP_DEFAULT)) == NULL)
fatal_f("fingerprint failed");
debug3_f("socketentry fd=%d, entry %zu %s, "
"from hostkey %s %s to user %s hostkey %s %s",
e->fd, i, hks->forwarded ? "FORWARD" : "AUTH",
fromkey ? sshkey_type(fromkey) : "(ORIGIN)",
fromkey ? fp1 : "", user ? user : "(ANY)",
sshkey_type(hks->key), fp2);
free(fp1);
free(fp2);
/*
* Record the hostnames for the initial forwarding and
* the final destination.
*/
hp = NULL;
if (i == e->nsession_ids - 1)
hp = last_hostnamep;
else if (i == 0)
hp = forward_hostnamep;
/* Special handling for final recorded binding */
test_user = NULL;
if (i == e->nsession_ids - 1) {
/* Can only check user at final hop */
test_user = user;
/*
* user is only presented for signature requests.
* If this is the case, make sure last binding is not
* for a forwarding.
*/
if (hks->forwarded && user != NULL) {
error_f("tried to sign on forwarding hop");
return -1;
}
} else if (!hks->forwarded) {
error_f("tried to forward though signing bind");
return -1;
}
if (permitted_by_dest_constraints(fromkey, hks->key, id,
test_user, hp) != 0)
return -1;
fromkey = hks->key;
}
/*
* Another special case: if the last bound session ID was for a
* forwarding, and this function is not being called to check a sign
* request (i.e. no 'user' supplied), then only permit the key if
* there is a permission that would allow it to be used at another
* destination. This hides keys that are allowed to be used to
* authenticate *to* a host but not permitted for *use* beyond it.
*/
hks = &e->session_ids[e->nsession_ids - 1];
if (hks->forwarded && user == NULL &&
permitted_by_dest_constraints(hks->key, NULL, id,
NULL, NULL) != 0) {
debug3_f("key permitted at host but not after");
return -1;
}
/* success */
return 0;
}
/* return matching private key for given public key */
static Identity *
lookup_identity(struct sshkey *key)
{
Identity *id;
TAILQ_FOREACH(id, &idtab->idlist, next) {
if (sshkey_equal(key, id->key))
return (id);
}
return (NULL);
}
/* Check confirmation of keysign request */
static int
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.%s%s",
id->comment, p,
extra == NULL ? "" : "\n", extra == NULL ? "" : extra))
ret = 0;
free(p);
return (ret);
}
static void
send_status(SocketEntry *e, int success)
{
int r;
if ((r = sshbuf_put_u32(e->output, 1)) != 0 ||
(r = sshbuf_put_u8(e->output, success ?
SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE)) != 0)
fatal_fr(r, "compose");
}
/* send list of supported public keys to 'client' */
static void
process_request_identities(SocketEntry *e)
{
Identity *id;
struct sshbuf *msg, *keys;
int r;
u_int nentries = 0;
debug2_f("entering");
if ((msg = sshbuf_new()) == NULL || (keys = sshbuf_new()) == NULL)
fatal_f("sshbuf_new failed");
TAILQ_FOREACH(id, &idtab->idlist, next) {
/* identity not visible, don't include in response */
if (identity_permitted(id, e, NULL, NULL, NULL) != 0)
continue;
if ((r = sshkey_puts_opts(id->key, keys,
SSHKEY_SERIALIZE_INFO)) != 0 ||
(r = sshbuf_put_cstring(keys, id->comment)) != 0) {
error_fr(r, "compose key/comment");
continue;
}
nentries++;
}
debug2_f("replying with %u allowed of %u available keys",
nentries, idtab->nentries);
if ((r = sshbuf_put_u8(msg, SSH2_AGENT_IDENTITIES_ANSWER)) != 0 ||
(r = sshbuf_put_u32(msg, nentries)) != 0 ||
(r = sshbuf_putb(msg, keys)) != 0)
fatal_fr(r, "compose");
if ((r = sshbuf_put_stringb(e->output, msg)) != 0)
fatal_fr(r, "enqueue");
sshbuf_free(msg);
sshbuf_free(keys);
}
static char *
agent_decode_alg(struct sshkey *key, u_int flags)
{
if (key->type == KEY_RSA) {
if (flags & SSH_AGENT_RSA_SHA2_256)
return "rsa-sha2-256";
else if (flags & SSH_AGENT_RSA_SHA2_512)
return "rsa-sha2-512";
} else if (key->type == KEY_RSA_CERT) {
if (flags & SSH_AGENT_RSA_SHA2_256)
return "rsa-sha2-256-cert-v01@openssh.com";
else if (flags & SSH_AGENT_RSA_SHA2_512)
return "rsa-sha2-512-cert-v01@openssh.com";
}
return NULL;
}
/*
* Attempt to parse the contents of a buffer as a SSH publickey userauth
* request, checking its contents for consistency and matching the embedded
* key against the one that is being used for signing.
* Note: does not modify msg buffer.
* Optionally extract the username, session ID and/or hostkey from the request.
*/
static int
parse_userauth_request(struct sshbuf *msg, const struct sshkey *expected_key,
char **userp, struct sshbuf **sess_idp, struct sshkey **hostkeyp)
{
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, *hostkey = NULL;
if (userp != NULL)
*userp = NULL;
if (sess_idp != NULL)
*sess_idp = NULL;
if (hostkeyp != NULL)
*hostkeyp = NULL;
if ((b = sshbuf_fromb(msg)) == NULL)
fatal_f("sshbuf_fromb");
/* SSH userauth request */
if ((r = sshbuf_froms(b, &sess_id)) != 0)
goto out;
if (sshbuf_len(sess_id) == 0) {
r = SSH_ERR_INVALID_FORMAT;
goto out;
}
if ((r = sshbuf_get_u8(b, &t)) != 0 || /* SSH2_MSG_USERAUTH_REQUEST */
(r = sshbuf_get_cstring(b, &user, NULL)) != 0 || /* server user */
(r = sshbuf_get_cstring(b, &service, NULL)) != 0 || /* service */
(r = sshbuf_get_cstring(b, &method, NULL)) != 0 || /* method */
(r = sshbuf_get_u8(b, &sig_follows)) != 0 || /* sig-follows */
(r = sshbuf_get_cstring(b, &pkalg, NULL)) != 0 || /* alg */
(r = sshkey_froms(b, &mkey)) != 0) /* key */
goto out;
if (t != SSH2_MSG_USERAUTH_REQUEST ||
sig_follows != 1 ||
strcmp(service, "ssh-connection") != 0 ||
!sshkey_equal(expected_key, mkey) ||
sshkey_type_from_name(pkalg) != expected_key->type) {
r = SSH_ERR_INVALID_FORMAT;
goto out;
}
if (strcmp(method, "publickey-hostbound-v00@openssh.com") == 0) {
if ((r = sshkey_froms(b, &hostkey)) != 0)
goto out;
} else 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;
}
if (hostkeyp != NULL) {
*hostkeyp = hostkey;
hostkey = NULL;
}
out:
sshbuf_free(b);
sshbuf_free(sess_id);
free(user);
free(service);
free(method);
free(pkalg);
sshkey_free(mkey);
sshkey_free(hostkey);
return r;
}
/*
* Attempt to parse the contents of a buffer as a SSHSIG signature request.
* Note: does not modify buffer.
*/
static int
parse_sshsig_request(struct sshbuf *msg)
{
int r;
struct sshbuf *b;
if ((b = sshbuf_fromb(msg)) == NULL)
fatal_f("sshbuf_fromb");
if ((r = sshbuf_cmp(b, 0, "SSHSIG", 6)) != 0 ||
(r = sshbuf_consume(b, 6)) != 0 ||
(r = sshbuf_get_cstring(b, NULL, NULL)) != 0 || /* namespace */
(r = sshbuf_get_string_direct(b, NULL, NULL)) != 0 || /* reserved */
(r = sshbuf_get_cstring(b, NULL, NULL)) != 0 || /* hashalg */
(r = sshbuf_get_string_direct(b, NULL, NULL)) != 0) /* H(msg) */
goto out;
if (sshbuf_len(b) != 0) {
r = SSH_ERR_INVALID_FORMAT;
goto out;
}
/* success */
r = 0;
out:
sshbuf_free(b);
return r;
}
/*
* This function inspects a message to be signed by a FIDO key that has a
* web-like application string (i.e. one that does not begin with "ssh:".
* It checks that the message is one of those expected for SSH operations
* (pubkey userauth, sshsig, CA key signing) to exclude signing challenges
* for the web.
*/
static int
check_websafe_message_contents(struct sshkey *key, struct sshbuf *data)
{
if (parse_userauth_request(data, key, NULL, NULL, NULL) == 0) {
debug_f("signed data matches public key userauth request");
return 1;
}
if (parse_sshsig_request(data) == 0) {
debug_f("signed data matches SSHSIG signature request");
return 1;
}
/* XXX check CA signature operation */
error("web-origin key attempting to sign non-SSH message");
return 0;
}
static int
buf_equal(const struct sshbuf *a, const struct sshbuf *b)
{
if (sshbuf_ptr(a) == NULL || sshbuf_ptr(b) == NULL)
return SSH_ERR_INVALID_ARGUMENT;
if (sshbuf_len(a) != sshbuf_len(b))
return SSH_ERR_INVALID_FORMAT;
if (timingsafe_bcmp(sshbuf_ptr(a), sshbuf_ptr(b), sshbuf_len(a)) != 0)
return SSH_ERR_INVALID_FORMAT;
return 0;
}
/* ssh2 only */
static void
process_sign_request2(SocketEntry *e)
{
u_char *signature = NULL;
size_t slen = 0;
u_int compat = 0, flags;
int r, ok = -1, retried = 0;
char *fp = NULL, *pin = NULL, *prompt = NULL;
char *user = NULL, *sig_dest = NULL;
const char *fwd_host = NULL, *dest_host = NULL;
struct sshbuf *msg = NULL, *data = NULL, *sid = NULL;
struct sshkey *key = NULL, *hostkey = NULL;
struct identity *id;
struct notifier_ctx *notifier = NULL;
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_stringb(e->request, data)) != 0 ||
(r = sshbuf_get_u32(e->request, &flags)) != 0) {
error_fr(r, "parse");
goto send;
}
if ((id = lookup_identity(key)) == NULL) {
verbose_f("%s key not found", sshkey_type(key));
goto send;
}
if ((fp = sshkey_fingerprint(key, SSH_FP_HASH_DEFAULT,
SSH_FP_DEFAULT)) == NULL)
fatal_f("fingerprint failed");
if (id->ndest_constraints != 0) {
if (e->nsession_ids == 0) {
logit_f("refusing use of destination-constrained key "
"to sign on unbound connection");
goto send;
}
if (parse_userauth_request(data, key, &user, &sid,
&hostkey) != 0) {
logit_f("refusing use of destination-constrained key "
"to sign an unidentified signature");
goto send;
}
/* XXX logspam */
debug_f("user=%s", user);
if (identity_permitted(id, e, user, &fwd_host, &dest_host) != 0)
goto send;
/* XXX display fwd_host/dest_host in askpass UI */
/*
* Ensure that the session ID is the most recent one
* registered on the socket - it should have been bound by
* ssh immediately before userauth.
*/
if (buf_equal(sid,
e->session_ids[e->nsession_ids - 1].sid) != 0) {
error_f("unexpected session ID (%zu listed) on "
"signature request for target user %s with "
"key %s %s", e->nsession_ids, user,
sshkey_type(id->key), fp);
goto send;
}
/*
* Ensure that the hostkey embedded in the signature matches
* the one most recently bound to the socket. An exception is
* made for the initial forwarding hop.
*/
if (e->nsession_ids > 1 && hostkey == NULL) {
error_f("refusing use of destination-constrained key: "
"no hostkey recorded in signature for forwarded "
"connection");
goto send;
}
if (hostkey != NULL && !sshkey_equal(hostkey,
e->session_ids[e->nsession_ids - 1].key)) {
error_f("refusing use of destination-constrained key: "
"mismatch between hostkey in request and most "
"recently bound session");
goto send;
}
xasprintf(&sig_dest, "public key authentication request for "
"user \"%s\" to listed host", user);
}
if (id->confirm && confirm_key(id, sig_dest) != 0) {
verbose_f("user refused key");
goto send;
}
if (sshkey_is_sk(id->key)) {
if (restrict_websafe &&
strncmp(id->key->sk_application, "ssh:", 4) != 0 &&
!check_websafe_message_contents(key, data)) {
/* error already logged */
goto send;
}
if (id->key->sk_flags & SSH_SK_USER_PRESENCE_REQD) {
notifier = notify_start(0,
"Confirm user presence for key %s %s%s%s",
sshkey_type(id->key), fp,
sig_dest == NULL ? "" : "\n",
sig_dest == NULL ? "" : sig_dest);
}
}
retry_pin:
if ((r = sshkey_sign(id->key, &signature, &slen,
sshbuf_ptr(data), sshbuf_len(data), agent_decode_alg(key, flags),
id->sk_provider, pin, compat)) != 0) {
debug_fr(r, "sshkey_sign");
if (pin == NULL && !retried && sshkey_is_sk(id->key) &&
r == SSH_ERR_KEY_WRONG_PASSPHRASE) {
notify_complete(notifier, NULL);
notifier = NULL;
/* XXX include sig_dest */
xasprintf(&prompt, "Enter PIN%sfor %s key %s: ",
(id->key->sk_flags & SSH_SK_USER_PRESENCE_REQD) ?
" and confirm user presence " : " ",
sshkey_type(id->key), fp);
pin = read_passphrase(prompt, RP_USE_ASKPASS);
retried = 1;
goto retry_pin;
}
error_fr(r, "sshkey_sign");
goto send;
}
/* Success */
ok = 0;
send:
debug_f("good signature");
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_fr(r, "compose");
} else if ((r = sshbuf_put_u8(msg, SSH_AGENT_FAILURE)) != 0)
fatal_fr(r, "compose failure");
if ((r = sshbuf_put_stringb(e->output, msg)) != 0)
fatal_fr(r, "enqueue");
sshbuf_free(sid);
sshbuf_free(data);
sshbuf_free(msg);
sshkey_free(key);
sshkey_free(hostkey);
free(fp);
free(signature);
free(sig_dest);
free(user);
free(prompt);
if (pin != NULL)
freezero(pin, strlen(pin));
}
/* shared */
static void
process_remove_identity(SocketEntry *e)
{
int r, success = 0;
struct sshkey *key = NULL;
Identity *id;
debug2_f("entering");
if ((r = sshkey_froms(e->request, &key)) != 0) {
error_fr(r, "parse key");
goto done;
}
if ((id = lookup_identity(key)) == NULL) {
debug_f("key not found");
goto done;
}
/* identity not visible, cannot be removed */
if (identity_permitted(id, e, NULL, NULL, NULL) != 0)
goto done; /* error already logged */
/* We have this key, free it. */
if (idtab->nentries < 1)
fatal_f("internal error: nentries %d", idtab->nentries);
TAILQ_REMOVE(&idtab->idlist, id, next);
free_identity(id);
idtab->nentries--;
success = 1;
done:
sshkey_free(key);
send_status(e, success);
}
static void
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)) {
TAILQ_REMOVE(&idtab->idlist, id, next);
free_identity(id);
}
/* Mark that there are no identities. */
idtab->nentries = 0;
/* Send success. */
send_status(e, 1);
}
/* removes expired keys and returns number of seconds until the next expiry */
static time_t
reaper(void)
{
time_t deadline = 0, now = monotime();
Identity *id, *nxt;
for (id = TAILQ_FIRST(&idtab->idlist); id; id = nxt) {
nxt = TAILQ_NEXT(id, next);
if (id->death == 0)
continue;
if (now >= id->death) {
debug("expiring key '%s'", id->comment);
TAILQ_REMOVE(&idtab->idlist, id, next);
free_identity(id);
idtab->nentries--;
} else
deadline = (deadline == 0) ? id->death :
MINIMUM(deadline, id->death);
}
if (deadline == 0 || deadline <= now)
return 0;
else
return (deadline - now);
}
static int
parse_dest_constraint_hop(struct sshbuf *b, struct dest_constraint_hop *dch)
{
u_char key_is_ca;
size_t elen = 0;
int r;
struct sshkey *k = NULL;
char *fp;
memset(dch, '\0', sizeof(*dch));
if ((r = sshbuf_get_cstring(b, &dch->user, NULL)) != 0 ||
(r = sshbuf_get_cstring(b, &dch->hostname, NULL)) != 0 ||
(r = sshbuf_get_string_direct(b, NULL, &elen)) != 0) {
error_fr(r, "parse");
goto out;
}
if (elen != 0) {
error_f("unsupported extensions (len %zu)", elen);
r = SSH_ERR_FEATURE_UNSUPPORTED;
goto out;
}
if (*dch->hostname == '\0') {
free(dch->hostname);
dch->hostname = NULL;
}
if (*dch->user == '\0') {
free(dch->user);
dch->user = NULL;
}
while (sshbuf_len(b) != 0) {
dch->keys = xrecallocarray(dch->keys, dch->nkeys,
dch->nkeys + 1, sizeof(*dch->keys));
dch->key_is_ca = xrecallocarray(dch->key_is_ca, dch->nkeys,
dch->nkeys + 1, sizeof(*dch->key_is_ca));
if ((r = sshkey_froms(b, &k)) != 0 ||
(r = sshbuf_get_u8(b, &key_is_ca)) != 0)
goto out;
if ((fp = sshkey_fingerprint(k, SSH_FP_HASH_DEFAULT,
SSH_FP_DEFAULT)) == NULL)
fatal_f("fingerprint failed");
debug3_f("%s%s%s: adding %skey %s %s",
dch->user == NULL ? "" : dch->user,
dch->user == NULL ? "" : "@",
dch->hostname, key_is_ca ? "CA " : "", sshkey_type(k), fp);
free(fp);
dch->keys[dch->nkeys] = k;
dch->key_is_ca[dch->nkeys] = key_is_ca != 0;
dch->nkeys++;
k = NULL; /* transferred */
}
/* success */
r = 0;
out:
sshkey_free(k);
return r;
}
static int
parse_dest_constraint(struct sshbuf *m, struct dest_constraint *dc)
{
struct sshbuf *b = NULL, *frombuf = NULL, *tobuf = NULL;
int r;
size_t elen = 0;
debug3_f("entering");
memset(dc, '\0', sizeof(*dc));
if ((r = sshbuf_froms(m, &b)) != 0 ||
(r = sshbuf_froms(b, &frombuf)) != 0 ||
(r = sshbuf_froms(b, &tobuf)) != 0 ||
(r = sshbuf_get_string_direct(b, NULL, &elen)) != 0) {
error_fr(r, "parse");
goto out;
}
if ((r = parse_dest_constraint_hop(frombuf, &dc->from) != 0) ||
(r = parse_dest_constraint_hop(tobuf, &dc->to) != 0))
goto out; /* already logged */
if (elen != 0) {
error_f("unsupported extensions (len %zu)", elen);
r = SSH_ERR_FEATURE_UNSUPPORTED;
goto out;
}
debug2_f("parsed %s (%u keys) > %s%s%s (%u keys)",
dc->from.hostname ? dc->from.hostname : "(ORIGIN)", dc->from.nkeys,
dc->to.user ? dc->to.user : "", dc->to.user ? "@" : "",
dc->to.hostname ? dc->to.hostname : "(ANY)", dc->to.nkeys);
/* check consistency */
if ((dc->from.hostname == NULL) != (dc->from.nkeys == 0) ||
dc->from.user != NULL) {
error_f("inconsistent \"from\" specification");
r = SSH_ERR_INVALID_FORMAT;
goto out;
}
if (dc->to.hostname == NULL || dc->to.nkeys == 0) {
error_f("incomplete \"to\" specification");
r = SSH_ERR_INVALID_FORMAT;
goto out;
}
/* success */
r = 0;
out:
sshbuf_free(b);
sshbuf_free(frombuf);
sshbuf_free(tobuf);
return r;
}
static int
parse_key_constraint_extension(struct sshbuf *m, char **sk_providerp,
struct dest_constraint **dcsp, size_t *ndcsp)
{
char *ext_name = NULL;
int r;
struct sshbuf *b = NULL;
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 if (strcmp(ext_name,
"restrict-destination-v00@openssh.com") == 0) {
if (*dcsp != NULL) {
error_f("%s already set", ext_name);
goto out;
}
if ((r = sshbuf_froms(m, &b)) != 0) {
error_fr(r, "parse %s outer", ext_name);
goto out;
}
while (sshbuf_len(b) != 0) {
if (*ndcsp >= AGENT_MAX_DEST_CONSTRAINTS) {
error_f("too many %s constraints", ext_name);
goto out;
}
*dcsp = xrecallocarray(*dcsp, *ndcsp, *ndcsp + 1,
sizeof(**dcsp));
if ((r = parse_dest_constraint(b,
*dcsp + (*ndcsp)++)) != 0)
goto out; /* error already logged */
}
} else {
error_f("unsupported constraint \"%s\"", ext_name);
r = SSH_ERR_FEATURE_UNSUPPORTED;
goto out;
}
/* success */
r = 0;
out:
free(ext_name);
sshbuf_free(b);
return r;
}
static int
parse_key_constraints(struct sshbuf *m, struct sshkey *k, time_t *deathp,
u_int *secondsp, int *confirmp, char **sk_providerp,
struct dest_constraint **dcsp, size_t *ndcsp)
{
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 (*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;
}
*deathp = monotime() + seconds;
*secondsp = seconds;
break;
case SSH_AGENT_CONSTRAIN_CONFIRM:
if (*confirmp != 0) {
error_f("confirm already set");
r = SSH_ERR_INVALID_FORMAT;
goto out;
}
*confirmp = 1;
break;
case SSH_AGENT_CONSTRAIN_MAXSIGN:
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_fr(r, "enable maxsign");
goto out;
}
break;
case SSH_AGENT_CONSTRAIN_EXTENSION:
if ((r = parse_key_constraint_extension(m,
sk_providerp, dcsp, ndcsp)) != 0)
goto out; /* error already logged */
break;
default:
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 dest_constraint *dest_constraints = NULL;
size_t ndest_constraints = 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, &dest_constraints, &ndest_constraints) != 0) {
error_f("failed to parse constraints");
sshbuf_reset(e->request);
goto out;
}
if (sk_provider != NULL) {
if (!sshkey_is_sk(k)) {
error("Cannot add provider: %s is not an "
"authenticator-hosted key", sshkey_type(k));
goto out;
}
if (strcasecmp(sk_provider, "internal") == 0) {
debug_f("internal provider");
} else {
if (realpath(sk_provider, canonical_provider) == NULL) {
verbose("failed provider \"%.100s\": "
"realpath: %s", sk_provider,
strerror(errno));
goto out;
}
free(sk_provider);
sk_provider = xstrdup(canonical_provider);
if (match_pattern_list(sk_provider,
allowed_providers, 0) != 1) {
error("Refusing add key: "
"provider %s not allowed", sk_provider);
goto out;
}
}
}
if ((r = sshkey_shield_private(k)) != 0) {
error_fr(r, "shield private");
goto out;
}
if (lifetime && !death)
death = monotime() + lifetime;
if ((id = lookup_identity(k)) == NULL) {
id = xcalloc(1, sizeof(Identity));
TAILQ_INSERT_TAIL(&idtab->idlist, id, next);
/* Increment the number of identities. */
idtab->nentries++;
} else {
/* identity not visible, do not update */
if (identity_permitted(id, e, NULL, NULL, NULL) != 0)
goto out; /* error already logged */
/* key state might have been updated */
sshkey_free(id->key);
free(id->comment);
free(id->sk_provider);
free_dest_constraints(id->dest_constraints,
id->ndest_constraints);
}
/* success */
id->key = k;
id->comment = comment;
id->death = death;
id->confirm = confirm;
id->sk_provider = sk_provider;
id->dest_constraints = dest_constraints;
id->ndest_constraints = ndest_constraints;
if ((fp = sshkey_fingerprint(k, SSH_FP_HASH_DEFAULT,
SSH_FP_DEFAULT)) == NULL)
fatal_f("sshkey_fingerprint failed");
debug_f("add %s %s \"%.100s\" (life: %u) (confirm: %u) "
"(provider: %s) (destination constraints: %zu)",
sshkey_ssh_name(k), fp, comment, seconds, confirm,
sk_provider == NULL ? "none" : sk_provider, ndest_constraints);
free(fp);
/* transferred */
k = NULL;
comment = NULL;
sk_provider = NULL;
dest_constraints = NULL;
ndest_constraints = 0;
success = 1;
out:
free(sk_provider);
free(comment);
sshkey_free(k);
free_dest_constraints(dest_constraints, ndest_constraints);
send_status(e, success);
}
/* XXX todo: encrypt sensitive data with passphrase */
static void
process_lock_agent(SocketEntry *e, int lock)
{
int r, success = 0, delay;
char *passwd;
u_char passwdhash[LOCK_SIZE];
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_fr(r, "parse");
if (pwlen == 0) {
debug("empty password not supported");
} else if (locked && !lock) {
if (bcrypt_pbkdf(passwd, pwlen, lock_salt, sizeof(lock_salt),
passwdhash, sizeof(passwdhash), LOCK_ROUNDS) < 0)
fatal("bcrypt_pbkdf");
if (timingsafe_bcmp(passwdhash, lock_pwhash, LOCK_SIZE) == 0) {
debug("agent unlocked");
locked = 0;
fail_count = 0;
explicit_bzero(lock_pwhash, sizeof(lock_pwhash));
success = 1;
} else {
/* delay in 0.1s increments up to 10s */
if (fail_count < 100)
fail_count++;
delay = 100000 * fail_count;
debug("unlock failed, delaying %0.1lf seconds",
(double)delay/1000000);
usleep(delay);
}
explicit_bzero(passwdhash, sizeof(passwdhash));
} else if (!locked && lock) {
debug("agent locked");
locked = 1;
arc4random_buf(lock_salt, sizeof(lock_salt));
if (bcrypt_pbkdf(passwd, pwlen, lock_salt, sizeof(lock_salt),
lock_pwhash, sizeof(lock_pwhash), LOCK_ROUNDS) < 0)
fatal("bcrypt_pbkdf");
success = 1;
}
freezero(passwd, pwlen);
send_status(e, success);
}
static void
no_identities(SocketEntry *e)
{
struct sshbuf *msg;
int r;
if ((msg = sshbuf_new()) == NULL)
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_fr(r, "compose");
sshbuf_free(msg);
}
#ifdef ENABLE_PKCS11
static void
process_add_smartcard_key(SocketEntry *e)
{
char *provider = NULL, *pin = NULL, canonical_provider[PATH_MAX];
char **comments = NULL;
int r, i, count = 0, success = 0, confirm = 0;
u_int seconds = 0;
time_t death = 0;
struct sshkey **keys = NULL, *k;
Identity *id;
struct dest_constraint *dest_constraints = NULL;
size_t ndest_constraints = 0;
debug2_f("entering");
if ((r = sshbuf_get_cstring(e->request, &provider, NULL)) != 0 ||
(r = sshbuf_get_cstring(e->request, &pin, NULL)) != 0) {
error_fr(r, "parse");
goto send;
}
if (parse_key_constraints(e->request, NULL, &death, &seconds, &confirm,
NULL, &dest_constraints, &ndest_constraints) != 0) {
error_f("failed to parse constraints");
goto send;
}
if (realpath(provider, canonical_provider) == NULL) {
verbose("failed PKCS#11 add of \"%.100s\": realpath: %s",
provider, strerror(errno));
goto send;
}
if (match_pattern_list(canonical_provider, allowed_providers, 0) != 1) {
verbose("refusing PKCS#11 add of \"%.100s\": "
"provider not allowed", canonical_provider);
goto send;
}
debug_f("add %.100s", canonical_provider);
if (lifetime && !death)
death = monotime() + lifetime;
count = pkcs11_add_provider(canonical_provider, pin, &keys, &comments);
for (i = 0; i < count; i++) {
k = keys[i];
if (lookup_identity(k) == NULL) {
id = xcalloc(1, sizeof(Identity));
id->key = k;
keys[i] = NULL; /* transferred */
id->provider = xstrdup(canonical_provider);
if (*comments[i] != '\0') {
id->comment = comments[i];
comments[i] = NULL; /* transferred */
} else {
id->comment = xstrdup(canonical_provider);
}
id->death = death;
id->confirm = confirm;
id->dest_constraints = dest_constraints;
id->ndest_constraints = ndest_constraints;
dest_constraints = NULL; /* transferred */
ndest_constraints = 0;
TAILQ_INSERT_TAIL(&idtab->idlist, id, next);
idtab->nentries++;
success = 1;
}
/* XXX update constraints for existing keys */
sshkey_free(keys[i]);
free(comments[i]);
}
send:
free(pin);
free(provider);
free(keys);
free(comments);
free_dest_constraints(dest_constraints, ndest_constraints);
send_status(e, success);
}
static void
process_remove_smartcard_key(SocketEntry *e)
{
char *provider = NULL, *pin = NULL, canonical_provider[PATH_MAX];
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_fr(r, "parse");
goto send;
}
free(pin);
if (realpath(provider, canonical_provider) == NULL) {
verbose("failed PKCS#11 add of \"%.100s\": realpath: %s",
provider, strerror(errno));
goto send;
}
debug_f("remove %.100s", canonical_provider);
for (id = TAILQ_FIRST(&idtab->idlist); id; id = nxt) {
nxt = TAILQ_NEXT(id, next);
/* Skip file--based keys */
if (id->provider == NULL)
continue;
if (!strcmp(canonical_provider, id->provider)) {
TAILQ_REMOVE(&idtab->idlist, id, next);
free_identity(id);
idtab->nentries--;
}
}
if (pkcs11_del_provider(canonical_provider) == 0)
success = 1;
else
error_f("pkcs11_del_provider failed");
send:
free(provider);
send_status(e, success);
}
#endif /* ENABLE_PKCS11 */
static int
process_ext_session_bind(SocketEntry *e)
{
int r, sid_match, key_match;
struct sshkey *key = NULL;
struct sshbuf *sid = NULL, *sig = NULL;
char *fp = NULL;
size_t i;
u_char fwd = 0;
debug2_f("entering");
if ((r = sshkey_froms(e->request, &key)) != 0 ||
(r = sshbuf_froms(e->request, &sid)) != 0 ||
(r = sshbuf_froms(e->request, &sig)) != 0 ||
(r = sshbuf_get_u8(e->request, &fwd)) != 0) {
error_fr(r, "parse");
goto out;
}
if ((fp = sshkey_fingerprint(key, SSH_FP_HASH_DEFAULT,
SSH_FP_DEFAULT)) == NULL)
fatal_f("fingerprint failed");
/* check signature with hostkey on session ID */
if ((r = sshkey_verify(key, sshbuf_ptr(sig), sshbuf_len(sig),
sshbuf_ptr(sid), sshbuf_len(sid), NULL, 0, NULL)) != 0) {
error_fr(r, "sshkey_verify for %s %s", sshkey_type(key), fp);
goto out;
}
/* check whether sid/key already recorded */
for (i = 0; i < e->nsession_ids; i++) {
if (!e->session_ids[i].forwarded) {
error_f("attempt to bind session ID to socket "
"previously bound for authentication attempt");
r = -1;
goto out;
}
sid_match = buf_equal(sid, e->session_ids[i].sid) == 0;
key_match = sshkey_equal(key, e->session_ids[i].key);
if (sid_match && key_match) {
debug_f("session ID already recorded for %s %s",
sshkey_type(key), fp);
r = 0;
goto out;
} else if (sid_match) {
error_f("session ID recorded against different key "
"for %s %s", sshkey_type(key), fp);
r = -1;
goto out;
}
/*
* new sid with previously-seen key can happen, e.g. multiple
* connections to the same host.
*/
}
/* record new key/sid */
if (e->nsession_ids >= AGENT_MAX_SESSION_IDS) {
error_f("too many session IDs recorded");
goto out;
}
e->session_ids = xrecallocarray(e->session_ids, e->nsession_ids,
e->nsession_ids + 1, sizeof(*e->session_ids));
i = e->nsession_ids++;
debug_f("recorded %s %s (slot %zu of %d)", sshkey_type(key), fp, i,
AGENT_MAX_SESSION_IDS);
e->session_ids[i].key = key;
e->session_ids[i].forwarded = fwd != 0;
key = NULL; /* transferred */
/* can't transfer sid; it's refcounted and scoped to request's life */
if ((e->session_ids[i].sid = sshbuf_new()) == NULL)
fatal_f("sshbuf_new");
if ((r = sshbuf_putb(e->session_ids[i].sid, sid)) != 0)
fatal_fr(r, "sshbuf_putb session ID");
/* success */
r = 0;
out:
free(fp);
sshkey_free(key);
sshbuf_free(sid);
sshbuf_free(sig);
return r == 0 ? 1 : 0;
}
static void
process_extension(SocketEntry *e)
{
int r, success = 0;
char *name;
debug2_f("entering");
if ((r = sshbuf_get_cstring(e->request, &name, NULL)) != 0) {
error_fr(r, "parse");
goto send;
}
if (strcmp(name, "session-bind@openssh.com") == 0)
success = process_ext_session_bind(e);
else
debug_f("unsupported extension \"%s\"", name);
free(name);
send:
send_status(e, success);
}
/*
* dispatch incoming message.
* returns 1 on success, 0 for incomplete messages or -1 on error.
*/
static int
process_message(u_int socknum)
{
u_int msg_len;
u_char type;
const u_char *cp;
int r;
SocketEntry *e;
if (socknum >= sockets_alloc)
fatal_f("sock %u >= allocated %u", socknum, sockets_alloc);
e = &sockets[socknum];
if (sshbuf_len(e->input) < 5)
return 0; /* Incomplete message header. */
cp = sshbuf_ptr(e->input);
msg_len = PEEK_U32(cp);
if (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)
return 0; /* Incomplete message body. */
/* move the current input to e->request */
sshbuf_reset(e->request);
if ((r = sshbuf_get_stringb(e->input, e->request)) != 0 ||
(r = sshbuf_get_u8(e->request, &type)) != 0) {
if (r == SSH_ERR_MESSAGE_INCOMPLETE ||
r == SSH_ERR_STRING_TOO_LARGE) {
error_fr(r, "parse");
return -1;
}
fatal_fr(r, "parse");
}
debug_f("socket %u (fd=%d) type %d", socknum, e->fd, type);
/* check whether agent is locked */
if (locked && type != SSH_AGENTC_UNLOCK) {
sshbuf_reset(e->request);
switch (type) {
case SSH2_AGENTC_REQUEST_IDENTITIES:
/* send empty lists */
no_identities(e);
break;
default:
/* send a fail message for all other request types */
send_status(e, 0);
}
return 1;
}
switch (type) {
case SSH_AGENTC_LOCK:
case SSH_AGENTC_UNLOCK:
process_lock_agent(e, type == SSH_AGENTC_LOCK);
break;
case SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES:
process_remove_all_identities(e); /* safe for !WITH_SSH1 */
break;
/* ssh2 */
case SSH2_AGENTC_SIGN_REQUEST:
process_sign_request2(e);
break;
case SSH2_AGENTC_REQUEST_IDENTITIES:
process_request_identities(e);
break;
case SSH2_AGENTC_ADD_IDENTITY:
case SSH2_AGENTC_ADD_ID_CONSTRAINED:
process_add_identity(e);
break;
case SSH2_AGENTC_REMOVE_IDENTITY:
process_remove_identity(e);
break;
case SSH2_AGENTC_REMOVE_ALL_IDENTITIES:
process_remove_all_identities(e);
break;
#ifdef ENABLE_PKCS11
case SSH_AGENTC_ADD_SMARTCARD_KEY:
case SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED:
process_add_smartcard_key(e);
break;
case SSH_AGENTC_REMOVE_SMARTCARD_KEY:
process_remove_smartcard_key(e);
break;
#endif /* ENABLE_PKCS11 */
case SSH_AGENTC_EXTENSION:
process_extension(e);
break;
default:
/* Unknown message. Respond with failure. */
error("Unknown message %d", type);
sshbuf_reset(e->request);
send_status(e, 0);
break;
}
return 1;
}
static void
new_socket(sock_type type, int fd)
{
u_int i, old_alloc, new_alloc;
debug_f("type = %s", type == AUTH_CONNECTION ? "CONNECTION" :
(type == AUTH_SOCKET ? "SOCKET" : "UNKNOWN"));
if (type == AUTH_CONNECTION) {
debug("xcount %d -> %d", xcount, xcount + 1);
++xcount;
}
set_nonblock(fd);
if (fd > max_fd)
max_fd = 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 ||
(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 = 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 ||
(sockets[old_alloc].output = sshbuf_new()) == NULL ||
(sockets[old_alloc].request = sshbuf_new()) == NULL)
fatal_f("sshbuf_new failed");
sockets[old_alloc].type = type;
}
static int
handle_socket_read(u_int socknum)
{
struct sockaddr_un sunaddr;
socklen_t slen;
uid_t euid;
gid_t egid;
int fd;
slen = sizeof(sunaddr);
fd = accept(sockets[socknum].fd, (struct sockaddr *)&sunaddr, &slen);
if (fd == -1) {
error("accept from AUTH_SOCKET: %s", strerror(errno));
return -1;
}
if (getpeereid(fd, &euid, &egid) == -1) {
error("getpeereid %d failed: %s", fd, strerror(errno));
close(fd);
return -1;
}
if ((euid != 0) && (getuid() != euid)) {
error("uid mismatch: peer euid %u != uid %u",
(u_int) euid, (u_int) getuid());
close(fd);
return -1;
}
new_socket(AUTH_CONNECTION, fd);
return 0;
}
static int
handle_conn_read(u_int socknum)
{
char buf[AGENT_RBUF_LEN];
ssize_t len;
int r;
if ((len = read(sockets[socknum].fd, buf, sizeof(buf))) <= 0) {
if (len == -1) {
if (errno == EAGAIN || errno == EINTR)
return 0;
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_fr(r, "compose");
explicit_bzero(buf, sizeof(buf));
for (;;) {
if ((r = process_message(socknum)) == -1)
return -1;
else if (r == 0)
break;
}
return 0;
}
static int
handle_conn_write(u_int socknum)
{
ssize_t len;
int r;
if (sshbuf_len(sockets[socknum].output) == 0)
return 0; /* shouldn't happen */
if ((len = write(sockets[socknum].fd,
sshbuf_ptr(sockets[socknum].output),
sshbuf_len(sockets[socknum].output))) <= 0) {
if (len == -1) {
if (errno == EAGAIN || errno == EINTR)
return 0;
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_fr(r, "consume");
return 0;
}
static void
after_poll(struct pollfd *pfd, size_t npfd, u_int maxfds)
{
size_t i;
u_int socknum, activefds = npfd;
for (i = 0; i < npfd; i++) {
if (pfd[i].revents == 0)
continue;
/* Find sockets entry */
for (socknum = 0; socknum < sockets_alloc; socknum++) {
if (sockets[socknum].type != AUTH_SOCKET &&
sockets[socknum].type != AUTH_CONNECTION)
continue;
if (pfd[i].fd == sockets[socknum].fd)
break;
}
if (socknum >= sockets_alloc) {
error_f("no socket for fd %d", pfd[i].fd);
continue;
}
/* Process events */
switch (sockets[socknum].type) {
case AUTH_SOCKET:
if ((pfd[i].revents & (POLLIN|POLLERR)) == 0)
break;
if (npfd > maxfds) {
debug3("out of fds (active %u >= limit %u); "
"skipping accept", activefds, maxfds);
break;
}
if (handle_socket_read(socknum) == 0)
activefds++;
break;
case AUTH_CONNECTION:
if ((pfd[i].revents & (POLLIN|POLLHUP|POLLERR)) != 0 &&
handle_conn_read(socknum) != 0)
goto close_sock;
if ((pfd[i].revents & (POLLOUT|POLLHUP)) != 0 &&
handle_conn_write(socknum) != 0) {
close_sock:
if (activefds == 0)
fatal("activefds == 0 at close_sock");
close_socket(&sockets[socknum]);
activefds--;
break;
}
break;
default:
break;
}
}
}
static int
prepare_poll(struct pollfd **pfdp, size_t *npfdp, int *timeoutp, u_int maxfds)
{
struct pollfd *pfd = *pfdp;
size_t i, j, npfd = 0;
time_t deadline;
int r;
/* Count active sockets */
for (i = 0; i < sockets_alloc; i++) {
switch (sockets[i].type) {
case AUTH_SOCKET:
case AUTH_CONNECTION:
npfd++;
break;
case AUTH_UNUSED:
break;
default:
fatal("Unknown socket type %d", sockets[i].type);
break;
}
}
if (npfd != *npfdp &&
(pfd = recallocarray(pfd, *npfdp, npfd, sizeof(*pfd))) == NULL)
fatal_f("recallocarray failed");
*pfdp = pfd;
*npfdp = npfd;
for (i = j = 0; i < sockets_alloc; i++) {
switch (sockets[i].type) {
case AUTH_SOCKET:
if (npfd > maxfds) {
debug3("out of fds (active %zu >= limit %u); "
"skipping arming listener", npfd, maxfds);
break;
}
pfd[j].fd = sockets[i].fd;
pfd[j].revents = 0;
pfd[j].events = POLLIN;
j++;
break;
case AUTH_CONNECTION:
pfd[j].fd = sockets[i].fd;
pfd[j].revents = 0;
/*
* Only prepare to read if we can handle a full-size
* input read buffer and enqueue a max size reply..
*/
if ((r = sshbuf_check_reserve(sockets[i].input,
AGENT_RBUF_LEN)) == 0 &&
(r = sshbuf_check_reserve(sockets[i].output,
AGENT_MAX_LEN)) == 0)
pfd[j].events = POLLIN;
else if (r != SSH_ERR_NO_BUFFER_SPACE)
fatal_fr(r, "reserve");
if (sshbuf_len(sockets[i].output) > 0)
pfd[j].events |= POLLOUT;
j++;
break;
default:
break;
}
}
deadline = reaper();
if (parent_alive_interval != 0)
deadline = (deadline == 0) ? parent_alive_interval :
MINIMUM(deadline, parent_alive_interval);
if (deadline == 0) {
*timeoutp = -1; /* INFTIM */
} else {
if (deadline > INT_MAX / 1000)
*timeoutp = INT_MAX / 1000;
else
*timeoutp = deadline * 1000;
}
return (1);
}
static void
cleanup_socket(void)
{
if (cleanup_pid != 0 && getpid() != cleanup_pid)
return;
debug_f("cleanup");
if (socket_name[0])
unlink(socket_name);
if (socket_dir[0])
rmdir(socket_dir);
}
void
cleanup_exit(int i)
{
cleanup_socket();
_exit(i);
}
/*ARGSUSED*/
static void
cleanup_handler(int sig)
{
cleanup_socket();
#ifdef ENABLE_PKCS11
pkcs11_terminate();
#endif
_exit(2);
}
static void
check_parent_exists(void)
{
/*
* If our parent has exited then getppid() will return (pid_t)1,
* so testing for that should be safe.
*/
if (parent_pid != -1 && getppid() != parent_pid) {
/* printf("Parent has died - Authentication agent exiting.\n"); */
cleanup_socket();
_exit(2);
}
}
static void
usage(void)
{
fprintf(stderr,
"usage: ssh-agent [-c | -s] [-Ddx] [-a bind_address] [-E fingerprint_hash]\n"
- " [-P allowed_providers] [-t life]\n"
- " ssh-agent [-a bind_address] [-E fingerprint_hash] [-P allowed_providers]\n"
- " [-t life] command [arg ...]\n"
+ " [-O option] [-P allowed_providers] [-t life]\n"
+ " ssh-agent [-a bind_address] [-E fingerprint_hash] [-O option]\n"
+ " [-P allowed_providers] [-t life] command [arg ...]\n"
" ssh-agent [-c | -s] -k\n");
exit(1);
}
int
main(int ac, char **av)
{
int c_flag = 0, d_flag = 0, D_flag = 0, k_flag = 0, s_flag = 0;
int sock, ch, result, saved_errno;
char *shell, *format, *pidstr, *agentsocket = NULL;
#ifdef HAVE_SETRLIMIT
struct rlimit rlim;
#endif
extern int optind;
extern char *optarg;
pid_t pid;
char pidstrbuf[1 + 3 * sizeof pid];
size_t len;
mode_t prev_mask;
int timeout = -1; /* INFTIM */
struct pollfd *pfd = NULL;
size_t npfd = 0;
u_int maxfds;
/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
sanitise_stdfd();
/* drop */
setegid(getgid());
setgid(getgid());
setuid(geteuid());
platform_disable_tracing(0); /* strict=no */
#ifdef RLIMIT_NOFILE
if (getrlimit(RLIMIT_NOFILE, &rlim) == -1)
fatal("%s: getrlimit: %s", __progname, strerror(errno));
#endif
__progname = ssh_get_progname(av[0]);
seed_rng();
while ((ch = getopt(ac, av, "cDdksE:a:O:P:t:x")) != -1) {
switch (ch) {
case 'E':
fingerprint_hash = ssh_digest_alg_by_name(optarg);
if (fingerprint_hash == -1)
fatal("Invalid hash algorithm \"%s\"", optarg);
break;
case 'c':
if (s_flag)
usage();
c_flag++;
break;
case 'k':
k_flag++;
break;
case 'O':
if (strcmp(optarg, "no-restrict-websafe") == 0)
restrict_websafe = 0;
else
fatal("Unknown -O option");
break;
case 'P':
if (allowed_providers != NULL)
fatal("-P option already specified");
allowed_providers = xstrdup(optarg);
break;
case 's':
if (c_flag)
usage();
s_flag++;
break;
case 'd':
if (d_flag || D_flag)
usage();
d_flag++;
break;
case 'D':
if (d_flag || D_flag)
usage();
D_flag++;
break;
case 'a':
agentsocket = optarg;
break;
case 't':
if ((lifetime = convtime(optarg)) == -1) {
fprintf(stderr, "Invalid lifetime\n");
usage();
}
break;
case 'x':
xcount = 0;
break;
default:
usage();
}
}
ac -= optind;
av += optind;
if (ac > 0 && (c_flag || k_flag || s_flag || d_flag || D_flag))
usage();
if (allowed_providers == NULL)
allowed_providers = xstrdup(DEFAULT_ALLOWED_PROVIDERS);
if (ac == 0 && !c_flag && !s_flag) {
shell = getenv("SHELL");
if (shell != NULL && (len = strlen(shell)) > 2 &&
strncmp(shell + len - 3, "csh", 3) == 0)
c_flag = 1;
}
if (k_flag) {
const char *errstr = NULL;
pidstr = getenv(SSH_AGENTPID_ENV_NAME);
if (pidstr == NULL) {
fprintf(stderr, "%s not set, cannot kill agent\n",
SSH_AGENTPID_ENV_NAME);
exit(1);
}
pid = (int)strtonum(pidstr, 2, INT_MAX, &errstr);
if (errstr) {
fprintf(stderr,
"%s=\"%s\", which is not a good PID: %s\n",
SSH_AGENTPID_ENV_NAME, pidstr, errstr);
exit(1);
}
if (kill(pid, SIGTERM) == -1) {
perror("kill");
exit(1);
}
format = c_flag ? "unsetenv %s;\n" : "unset %s;\n";
printf(format, SSH_AUTHSOCKET_ENV_NAME);
printf(format, SSH_AGENTPID_ENV_NAME);
printf("echo Agent pid %ld killed;\n", (long)pid);
exit(0);
}
/*
* Minimum file descriptors:
* stdio (3) + listener (1) + syslog (1 maybe) + connection (1) +
* a few spare for libc / stack protectors / sanitisers, etc.
*/
#define SSH_AGENT_MIN_FDS (3+1+1+1+4)
if (rlim.rlim_cur < SSH_AGENT_MIN_FDS)
fatal("%s: file descriptor rlimit %lld too low (minimum %u)",
__progname, (long long)rlim.rlim_cur, SSH_AGENT_MIN_FDS);
maxfds = rlim.rlim_cur - SSH_AGENT_MIN_FDS;
parent_pid = getpid();
if (agentsocket == NULL) {
/* Create private directory for agent socket */
mktemp_proto(socket_dir, sizeof(socket_dir));
if (mkdtemp(socket_dir) == NULL) {
perror("mkdtemp: private socket dir");
exit(1);
}
snprintf(socket_name, sizeof socket_name, "%s/agent.%ld", socket_dir,
(long)parent_pid);
} else {
/* Try to use specified agent socket */
socket_dir[0] = '\0';
strlcpy(socket_name, agentsocket, sizeof socket_name);
}
/*
* Create socket early so it will exist before command gets run from
* the parent.
*/
prev_mask = umask(0177);
sock = unix_listener(socket_name, SSH_LISTEN_BACKLOG, 0);
if (sock < 0) {
/* XXX - unix_listener() calls error() not perror() */
*socket_name = '\0'; /* Don't unlink any existing file */
cleanup_exit(1);
}
umask(prev_mask);
/*
* Fork, and have the parent execute the command, if any, or present
* the socket data. The child continues as the authentication agent.
*/
if (D_flag || d_flag) {
log_init(__progname,
d_flag ? SYSLOG_LEVEL_DEBUG3 : SYSLOG_LEVEL_INFO,
SYSLOG_FACILITY_AUTH, 1);
format = c_flag ? "setenv %s %s;\n" : "%s=%s; export %s;\n";
printf(format, SSH_AUTHSOCKET_ENV_NAME, socket_name,
SSH_AUTHSOCKET_ENV_NAME);
printf("echo Agent pid %ld;\n", (long)parent_pid);
fflush(stdout);
goto skip;
}
pid = fork();
if (pid == -1) {
perror("fork");
cleanup_exit(1);
}
if (pid != 0) { /* Parent - execute the given command. */
close(sock);
snprintf(pidstrbuf, sizeof pidstrbuf, "%ld", (long)pid);
if (ac == 0) {
format = c_flag ? "setenv %s %s;\n" : "%s=%s; export %s;\n";
printf(format, SSH_AUTHSOCKET_ENV_NAME, socket_name,
SSH_AUTHSOCKET_ENV_NAME);
printf(format, SSH_AGENTPID_ENV_NAME, pidstrbuf,
SSH_AGENTPID_ENV_NAME);
printf("echo Agent pid %ld;\n", (long)pid);
exit(0);
}
if (setenv(SSH_AUTHSOCKET_ENV_NAME, socket_name, 1) == -1 ||
setenv(SSH_AGENTPID_ENV_NAME, pidstrbuf, 1) == -1) {
perror("setenv");
exit(1);
}
execvp(av[0], av);
perror(av[0]);
exit(1);
}
/* child */
log_init(__progname, SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_AUTH, 0);
if (setsid() == -1) {
error("setsid: %s", strerror(errno));
cleanup_exit(1);
}
(void)chdir("/");
if (stdfd_devnull(1, 1, 1) == -1)
error_f("stdfd_devnull failed");
#ifdef HAVE_SETRLIMIT
/* deny core dumps, since memory contains unencrypted private keys */
rlim.rlim_cur = rlim.rlim_max = 0;
if (setrlimit(RLIMIT_CORE, &rlim) == -1) {
error("setrlimit RLIMIT_CORE: %s", strerror(errno));
cleanup_exit(1);
}
#endif
skip:
cleanup_pid = getpid();
#ifdef ENABLE_PKCS11
pkcs11_init(0);
#endif
new_socket(AUTH_SOCKET, sock);
if (ac > 0)
parent_alive_interval = 10;
idtab_init();
ssh_signal(SIGPIPE, SIG_IGN);
ssh_signal(SIGINT, (d_flag | D_flag) ? cleanup_handler : SIG_IGN);
ssh_signal(SIGHUP, cleanup_handler);
ssh_signal(SIGTERM, cleanup_handler);
if (pledge("stdio rpath cpath unix id proc exec", NULL) == -1)
fatal("%s: pledge: %s", __progname, strerror(errno));
platform_pledge_agent();
while (1) {
prepare_poll(&pfd, &npfd, &timeout, maxfds);
result = poll(pfd, npfd, timeout);
saved_errno = errno;
if (parent_alive_interval != 0)
check_parent_exists();
(void) reaper(); /* remove expired keys */
if (result == -1) {
if (saved_errno == EINTR)
continue;
fatal("poll: %s", strerror(saved_errno));
} else if (result > 0)
after_poll(pfd, npfd, maxfds);
}
/* NOTREACHED */
}
diff --git a/crypto/openssh/ssh-dss.c b/crypto/openssh/ssh-dss.c
index fddc29cc9173..2ea0c0a55760 100644
--- a/crypto/openssh/ssh-dss.c
+++ b/crypto/openssh/ssh-dss.c
@@ -1,207 +1,457 @@
-/* $OpenBSD: ssh-dss.c,v 1.39 2020/02/26 13:40:09 jsg Exp $ */
+/* $OpenBSD: ssh-dss.c,v 1.48 2022/10/28 00:44:44 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "includes.h"
#ifdef WITH_OPENSSL
#include <sys/types.h>
#include <openssl/bn.h>
#include <openssl/dsa.h>
#include <openssl/evp.h>
#include <stdarg.h>
#include <string.h>
#include "sshbuf.h"
#include "compat.h"
#include "ssherr.h"
#include "digest.h"
#define SSHKEY_INTERNAL
#include "sshkey.h"
#include "openbsd-compat/openssl-compat.h"
#define INTBLOB_LEN 20
#define SIGBLOB_LEN (2*INTBLOB_LEN)
-int
-ssh_dss_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
- const u_char *data, size_t datalen, u_int compat)
+static u_int
+ssh_dss_size(const struct sshkey *key)
+{
+ const BIGNUM *dsa_p;
+
+ if (key->dsa == NULL)
+ return 0;
+ DSA_get0_pqg(key->dsa, &dsa_p, NULL, NULL);
+ return BN_num_bits(dsa_p);
+}
+
+static int
+ssh_dss_alloc(struct sshkey *k)
+{
+ if ((k->dsa = DSA_new()) == NULL)
+ return SSH_ERR_ALLOC_FAIL;
+ return 0;
+}
+
+static void
+ssh_dss_cleanup(struct sshkey *k)
+{
+ DSA_free(k->dsa);
+ k->dsa = NULL;
+}
+
+static int
+ssh_dss_equal(const struct sshkey *a, const struct sshkey *b)
+{
+ const BIGNUM *dsa_p_a, *dsa_q_a, *dsa_g_a, *dsa_pub_key_a;
+ const BIGNUM *dsa_p_b, *dsa_q_b, *dsa_g_b, *dsa_pub_key_b;
+
+ if (a->dsa == NULL || b->dsa == NULL)
+ return 0;
+ DSA_get0_pqg(a->dsa, &dsa_p_a, &dsa_q_a, &dsa_g_a);
+ DSA_get0_pqg(b->dsa, &dsa_p_b, &dsa_q_b, &dsa_g_b);
+ DSA_get0_key(a->dsa, &dsa_pub_key_a, NULL);
+ DSA_get0_key(b->dsa, &dsa_pub_key_b, NULL);
+ if (dsa_p_a == NULL || dsa_p_b == NULL ||
+ dsa_q_a == NULL || dsa_q_b == NULL ||
+ dsa_g_a == NULL || dsa_g_b == NULL ||
+ dsa_pub_key_a == NULL || dsa_pub_key_b == NULL)
+ return 0;
+ if (BN_cmp(dsa_p_a, dsa_p_b) != 0)
+ return 0;
+ if (BN_cmp(dsa_q_a, dsa_q_b) != 0)
+ return 0;
+ if (BN_cmp(dsa_g_a, dsa_g_b) != 0)
+ return 0;
+ if (BN_cmp(dsa_pub_key_a, dsa_pub_key_b) != 0)
+ return 0;
+ return 1;
+}
+
+static int
+ssh_dss_serialize_public(const struct sshkey *key, struct sshbuf *b,
+ enum sshkey_serialize_rep opts)
+{
+ int r;
+ const BIGNUM *dsa_p, *dsa_q, *dsa_g, *dsa_pub_key;
+
+ if (key->dsa == NULL)
+ return SSH_ERR_INVALID_ARGUMENT;
+ DSA_get0_pqg(key->dsa, &dsa_p, &dsa_q, &dsa_g);
+ DSA_get0_key(key->dsa, &dsa_pub_key, NULL);
+ if (dsa_p == NULL || dsa_q == NULL ||
+ dsa_g == NULL || dsa_pub_key == NULL)
+ return SSH_ERR_INTERNAL_ERROR;
+ if ((r = sshbuf_put_bignum2(b, dsa_p)) != 0 ||
+ (r = sshbuf_put_bignum2(b, dsa_q)) != 0 ||
+ (r = sshbuf_put_bignum2(b, dsa_g)) != 0 ||
+ (r = sshbuf_put_bignum2(b, dsa_pub_key)) != 0)
+ return r;
+
+ return 0;
+}
+
+static int
+ssh_dss_serialize_private(const struct sshkey *key, struct sshbuf *b,
+ enum sshkey_serialize_rep opts)
+{
+ int r;
+ const BIGNUM *dsa_priv_key;
+
+ DSA_get0_key(key->dsa, NULL, &dsa_priv_key);
+ if (!sshkey_is_cert(key)) {
+ if ((r = ssh_dss_serialize_public(key, b, opts)) != 0)
+ return r;
+ }
+ if ((r = sshbuf_put_bignum2(b, dsa_priv_key)) != 0)
+ return r;
+
+ return 0;
+}
+
+static int
+ssh_dss_generate(struct sshkey *k, int bits)
+{
+ DSA *private;
+
+ if (bits != 1024)
+ return SSH_ERR_KEY_LENGTH;
+ if ((private = DSA_new()) == NULL)
+ return SSH_ERR_ALLOC_FAIL;
+ if (!DSA_generate_parameters_ex(private, bits, NULL, 0, NULL,
+ NULL, NULL) || !DSA_generate_key(private)) {
+ DSA_free(private);
+ return SSH_ERR_LIBCRYPTO_ERROR;
+ }
+ k->dsa = private;
+ return 0;
+}
+
+static int
+ssh_dss_copy_public(const struct sshkey *from, struct sshkey *to)
+{
+ const BIGNUM *dsa_p, *dsa_q, *dsa_g, *dsa_pub_key;
+ BIGNUM *dsa_p_dup = NULL, *dsa_q_dup = NULL, *dsa_g_dup = NULL;
+ BIGNUM *dsa_pub_key_dup = NULL;
+ int r = SSH_ERR_INTERNAL_ERROR;
+
+ DSA_get0_pqg(from->dsa, &dsa_p, &dsa_q, &dsa_g);
+ DSA_get0_key(from->dsa, &dsa_pub_key, NULL);
+ if ((dsa_p_dup = BN_dup(dsa_p)) == NULL ||
+ (dsa_q_dup = BN_dup(dsa_q)) == NULL ||
+ (dsa_g_dup = BN_dup(dsa_g)) == NULL ||
+ (dsa_pub_key_dup = BN_dup(dsa_pub_key)) == NULL) {
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ if (!DSA_set0_pqg(to->dsa, dsa_p_dup, dsa_q_dup, dsa_g_dup)) {
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ dsa_p_dup = dsa_q_dup = dsa_g_dup = NULL; /* transferred */
+ if (!DSA_set0_key(to->dsa, dsa_pub_key_dup, NULL)) {
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ dsa_pub_key_dup = NULL; /* transferred */
+ /* success */
+ r = 0;
+ out:
+ BN_clear_free(dsa_p_dup);
+ BN_clear_free(dsa_q_dup);
+ BN_clear_free(dsa_g_dup);
+ BN_clear_free(dsa_pub_key_dup);
+ return r;
+}
+
+static int
+ssh_dss_deserialize_public(const char *ktype, struct sshbuf *b,
+ struct sshkey *key)
+{
+ int ret = SSH_ERR_INTERNAL_ERROR;
+ BIGNUM *dsa_p = NULL, *dsa_q = NULL, *dsa_g = NULL, *dsa_pub_key = NULL;
+
+ if (sshbuf_get_bignum2(b, &dsa_p) != 0 ||
+ sshbuf_get_bignum2(b, &dsa_q) != 0 ||
+ sshbuf_get_bignum2(b, &dsa_g) != 0 ||
+ sshbuf_get_bignum2(b, &dsa_pub_key) != 0) {
+ ret = SSH_ERR_INVALID_FORMAT;
+ goto out;
+ }
+ if (!DSA_set0_pqg(key->dsa, dsa_p, dsa_q, dsa_g)) {
+ ret = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ dsa_p = dsa_q = dsa_g = NULL; /* transferred */
+ if (!DSA_set0_key(key->dsa, dsa_pub_key, NULL)) {
+ ret = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ dsa_pub_key = NULL; /* transferred */
+#ifdef DEBUG_PK
+ DSA_print_fp(stderr, key->dsa, 8);
+#endif
+ /* success */
+ ret = 0;
+ out:
+ BN_clear_free(dsa_p);
+ BN_clear_free(dsa_q);
+ BN_clear_free(dsa_g);
+ BN_clear_free(dsa_pub_key);
+ return ret;
+}
+
+static int
+ssh_dss_deserialize_private(const char *ktype, struct sshbuf *b,
+ struct sshkey *key)
+{
+ int r;
+ BIGNUM *dsa_priv_key = NULL;
+
+ if (!sshkey_is_cert(key)) {
+ if ((r = ssh_dss_deserialize_public(ktype, b, key)) != 0)
+ return r;
+ }
+
+ if ((r = sshbuf_get_bignum2(b, &dsa_priv_key)) != 0)
+ return r;
+ if (!DSA_set0_key(key->dsa, NULL, dsa_priv_key)) {
+ BN_clear_free(dsa_priv_key);
+ return SSH_ERR_LIBCRYPTO_ERROR;
+ }
+ return 0;
+}
+
+static int
+ssh_dss_sign(struct sshkey *key,
+ u_char **sigp, size_t *lenp,
+ const u_char *data, size_t datalen,
+ const char *alg, const char *sk_provider, const char *sk_pin, u_int compat)
{
DSA_SIG *sig = NULL;
const BIGNUM *sig_r, *sig_s;
u_char digest[SSH_DIGEST_MAX_LENGTH], sigblob[SIGBLOB_LEN];
size_t rlen, slen, len, dlen = ssh_digest_bytes(SSH_DIGEST_SHA1);
struct sshbuf *b = NULL;
int ret = SSH_ERR_INVALID_ARGUMENT;
if (lenp != NULL)
*lenp = 0;
if (sigp != NULL)
*sigp = NULL;
if (key == NULL || key->dsa == NULL ||
sshkey_type_plain(key->type) != KEY_DSA)
return SSH_ERR_INVALID_ARGUMENT;
if (dlen == 0)
return SSH_ERR_INTERNAL_ERROR;
if ((ret = ssh_digest_memory(SSH_DIGEST_SHA1, data, datalen,
digest, sizeof(digest))) != 0)
goto out;
if ((sig = DSA_do_sign(digest, dlen, key->dsa)) == NULL) {
ret = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
DSA_SIG_get0(sig, &sig_r, &sig_s);
rlen = BN_num_bytes(sig_r);
slen = BN_num_bytes(sig_s);
if (rlen > INTBLOB_LEN || slen > INTBLOB_LEN) {
ret = SSH_ERR_INTERNAL_ERROR;
goto out;
}
explicit_bzero(sigblob, SIGBLOB_LEN);
BN_bn2bin(sig_r, sigblob + SIGBLOB_LEN - INTBLOB_LEN - rlen);
BN_bn2bin(sig_s, sigblob + SIGBLOB_LEN - slen);
if ((b = sshbuf_new()) == NULL) {
ret = SSH_ERR_ALLOC_FAIL;
goto out;
}
if ((ret = sshbuf_put_cstring(b, "ssh-dss")) != 0 ||
(ret = sshbuf_put_string(b, sigblob, SIGBLOB_LEN)) != 0)
goto out;
len = sshbuf_len(b);
if (sigp != NULL) {
if ((*sigp = malloc(len)) == NULL) {
ret = SSH_ERR_ALLOC_FAIL;
goto out;
}
memcpy(*sigp, sshbuf_ptr(b), len);
}
if (lenp != NULL)
*lenp = len;
ret = 0;
out:
explicit_bzero(digest, sizeof(digest));
DSA_SIG_free(sig);
sshbuf_free(b);
return ret;
}
-int
+static int
ssh_dss_verify(const struct sshkey *key,
- const u_char *signature, size_t signaturelen,
- const u_char *data, size_t datalen, u_int compat)
+ const u_char *sig, size_t siglen,
+ const u_char *data, size_t dlen, const char *alg, u_int compat,
+ struct sshkey_sig_details **detailsp)
{
- DSA_SIG *sig = NULL;
+ DSA_SIG *dsig = NULL;
BIGNUM *sig_r = NULL, *sig_s = NULL;
u_char digest[SSH_DIGEST_MAX_LENGTH], *sigblob = NULL;
- size_t len, dlen = ssh_digest_bytes(SSH_DIGEST_SHA1);
+ size_t len, hlen = ssh_digest_bytes(SSH_DIGEST_SHA1);
int ret = SSH_ERR_INTERNAL_ERROR;
struct sshbuf *b = NULL;
char *ktype = NULL;
if (key == NULL || key->dsa == NULL ||
sshkey_type_plain(key->type) != KEY_DSA ||
- signature == NULL || signaturelen == 0)
+ sig == NULL || siglen == 0)
return SSH_ERR_INVALID_ARGUMENT;
- if (dlen == 0)
+ if (hlen == 0)
return SSH_ERR_INTERNAL_ERROR;
/* fetch signature */
- if ((b = sshbuf_from(signature, signaturelen)) == NULL)
+ if ((b = sshbuf_from(sig, siglen)) == NULL)
return SSH_ERR_ALLOC_FAIL;
if (sshbuf_get_cstring(b, &ktype, NULL) != 0 ||
sshbuf_get_string(b, &sigblob, &len) != 0) {
ret = SSH_ERR_INVALID_FORMAT;
goto out;
}
if (strcmp("ssh-dss", ktype) != 0) {
ret = SSH_ERR_KEY_TYPE_MISMATCH;
goto out;
}
if (sshbuf_len(b) != 0) {
ret = SSH_ERR_UNEXPECTED_TRAILING_DATA;
goto out;
}
if (len != SIGBLOB_LEN) {
ret = SSH_ERR_INVALID_FORMAT;
goto out;
}
/* parse signature */
- if ((sig = DSA_SIG_new()) == NULL ||
+ if ((dsig = DSA_SIG_new()) == NULL ||
(sig_r = BN_new()) == NULL ||
(sig_s = BN_new()) == NULL) {
ret = SSH_ERR_ALLOC_FAIL;
goto out;
}
if ((BN_bin2bn(sigblob, INTBLOB_LEN, sig_r) == NULL) ||
(BN_bin2bn(sigblob + INTBLOB_LEN, INTBLOB_LEN, sig_s) == NULL)) {
ret = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
- if (!DSA_SIG_set0(sig, sig_r, sig_s)) {
+ if (!DSA_SIG_set0(dsig, sig_r, sig_s)) {
ret = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
sig_r = sig_s = NULL; /* transferred */
/* sha1 the data */
- if ((ret = ssh_digest_memory(SSH_DIGEST_SHA1, data, datalen,
+ if ((ret = ssh_digest_memory(SSH_DIGEST_SHA1, data, dlen,
digest, sizeof(digest))) != 0)
goto out;
- switch (DSA_do_verify(digest, dlen, sig, key->dsa)) {
+ switch (DSA_do_verify(digest, hlen, dsig, key->dsa)) {
case 1:
ret = 0;
break;
case 0:
ret = SSH_ERR_SIGNATURE_INVALID;
goto out;
default:
ret = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
out:
explicit_bzero(digest, sizeof(digest));
- DSA_SIG_free(sig);
+ DSA_SIG_free(dsig);
BN_clear_free(sig_r);
BN_clear_free(sig_s);
sshbuf_free(b);
free(ktype);
if (sigblob != NULL)
freezero(sigblob, len);
return ret;
}
+
+static const struct sshkey_impl_funcs sshkey_dss_funcs = {
+ /* .size = */ ssh_dss_size,
+ /* .alloc = */ ssh_dss_alloc,
+ /* .cleanup = */ ssh_dss_cleanup,
+ /* .equal = */ ssh_dss_equal,
+ /* .ssh_serialize_public = */ ssh_dss_serialize_public,
+ /* .ssh_deserialize_public = */ ssh_dss_deserialize_public,
+ /* .ssh_serialize_private = */ ssh_dss_serialize_private,
+ /* .ssh_deserialize_private = */ ssh_dss_deserialize_private,
+ /* .generate = */ ssh_dss_generate,
+ /* .copy_public = */ ssh_dss_copy_public,
+ /* .sign = */ ssh_dss_sign,
+ /* .verify = */ ssh_dss_verify,
+};
+
+const struct sshkey_impl sshkey_dss_impl = {
+ /* .name = */ "ssh-dss",
+ /* .shortname = */ "DSA",
+ /* .sigalg = */ NULL,
+ /* .type = */ KEY_DSA,
+ /* .nid = */ 0,
+ /* .cert = */ 0,
+ /* .sigonly = */ 0,
+ /* .keybits = */ 0,
+ /* .funcs = */ &sshkey_dss_funcs,
+};
+
+const struct sshkey_impl sshkey_dsa_cert_impl = {
+ /* .name = */ "ssh-dss-cert-v01@openssh.com",
+ /* .shortname = */ "DSA-CERT",
+ /* .sigalg = */ NULL,
+ /* .type = */ KEY_DSA_CERT,
+ /* .nid = */ 0,
+ /* .cert = */ 1,
+ /* .sigonly = */ 0,
+ /* .keybits = */ 0,
+ /* .funcs = */ &sshkey_dss_funcs,
+};
#endif /* WITH_OPENSSL */
diff --git a/crypto/openssh/ssh-ecdsa-sk.c b/crypto/openssh/ssh-ecdsa-sk.c
index c6927ecb27c8..729e5487c9f5 100644
--- a/crypto/openssh/ssh-ecdsa-sk.c
+++ b/crypto/openssh/ssh-ecdsa-sk.c
@@ -1,324 +1,468 @@
-/* $OpenBSD: ssh-ecdsa-sk.c,v 1.8 2020/06/22 23:44:27 djm Exp $ */
+/* $OpenBSD: ssh-ecdsa-sk.c,v 1.17 2022/10/28 00:44:44 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
* Copyright (c) 2010 Damien Miller. All rights reserved.
* Copyright (c) 2019 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* #define DEBUG_SK 1 */
#include "includes.h"
#include <sys/types.h>
#ifdef WITH_OPENSSL
#include <openssl/bn.h>
#include <openssl/ec.h>
#include <openssl/ecdsa.h>
#include <openssl/evp.h>
#endif
#include <string.h>
#include <stdio.h> /* needed for DEBUG_SK only */
#include "openbsd-compat/openssl-compat.h"
#include "sshbuf.h"
#include "ssherr.h"
#include "digest.h"
#define SSHKEY_INTERNAL
#include "sshkey.h"
#ifndef OPENSSL_HAS_ECC
/* ARGSUSED */
int
ssh_ecdsa_sk_verify(const struct sshkey *key,
const u_char *signature, size_t signaturelen,
const u_char *data, size_t datalen, u_int compat,
struct sshkey_sig_details **detailsp)
{
return SSH_ERR_FEATURE_UNSUPPORTED;
}
#else /* OPENSSL_HAS_ECC */
+/* Reuse some ECDSA internals */
+extern struct sshkey_impl_funcs sshkey_ecdsa_funcs;
+
+static void
+ssh_ecdsa_sk_cleanup(struct sshkey *k)
+{
+ sshkey_sk_cleanup(k);
+ sshkey_ecdsa_funcs.cleanup(k);
+}
+
+static int
+ssh_ecdsa_sk_equal(const struct sshkey *a, const struct sshkey *b)
+{
+ if (!sshkey_sk_fields_equal(a, b))
+ return 0;
+ if (!sshkey_ecdsa_funcs.equal(a, b))
+ return 0;
+ return 1;
+}
+
+static int
+ssh_ecdsa_sk_serialize_public(const struct sshkey *key, struct sshbuf *b,
+ enum sshkey_serialize_rep opts)
+{
+ int r;
+
+ if ((r = sshkey_ecdsa_funcs.serialize_public(key, b, opts)) != 0)
+ return r;
+ if ((r = sshkey_serialize_sk(key, b)) != 0)
+ return r;
+
+ return 0;
+}
+
+static int
+ssh_ecdsa_sk_serialize_private(const struct sshkey *key, struct sshbuf *b,
+ enum sshkey_serialize_rep opts)
+{
+ int r;
+
+ if (!sshkey_is_cert(key)) {
+ if ((r = sshkey_ecdsa_funcs.serialize_public(key,
+ b, opts)) != 0)
+ return r;
+ }
+ if ((r = sshkey_serialize_private_sk(key, b)) != 0)
+ return r;
+
+ return 0;
+}
+
+static int
+ssh_ecdsa_sk_copy_public(const struct sshkey *from, struct sshkey *to)
+{
+ int r;
+
+ if ((r = sshkey_ecdsa_funcs.copy_public(from, to)) != 0)
+ return r;
+ if ((r = sshkey_copy_public_sk(from, to)) != 0)
+ return r;
+ return 0;
+}
+
+static int
+ssh_ecdsa_sk_deserialize_public(const char *ktype, struct sshbuf *b,
+ struct sshkey *key)
+{
+ int r;
+
+ if ((r = sshkey_ecdsa_funcs.deserialize_public(ktype, b, key)) != 0)
+ return r;
+ if ((r = sshkey_deserialize_sk(b, key)) != 0)
+ return r;
+ return 0;
+}
+
+static int
+ssh_ecdsa_sk_deserialize_private(const char *ktype, struct sshbuf *b,
+ struct sshkey *key)
+{
+ int r;
+
+ if (!sshkey_is_cert(key)) {
+ if ((r = sshkey_ecdsa_funcs.deserialize_public(ktype,
+ b, key)) != 0)
+ return r;
+ }
+ if ((r = sshkey_private_deserialize_sk(b, key)) != 0)
+ return r;
+
+ return 0;
+}
+
/*
* Check FIDO/W3C webauthn signatures clientData field against the expected
* format and prepare a hash of it for use in signature verification.
*
* webauthn signatures do not sign the hash of the message directly, but
* instead sign a JSON-like "clientData" wrapper structure that contains the
* message hash along with a other information.
*
* Fortunately this structure has a fixed format so it is possible to verify
* that the hash of the signed message is present within the clientData
* structure without needing to implement any JSON parsing.
*/
static int
webauthn_check_prepare_hash(const u_char *data, size_t datalen,
const char *origin, const struct sshbuf *wrapper,
uint8_t flags, const struct sshbuf *extensions,
u_char *msghash, size_t msghashlen)
{
int r = SSH_ERR_INTERNAL_ERROR;
struct sshbuf *chall = NULL, *m = NULL;
if ((m = sshbuf_new()) == NULL ||
(chall = sshbuf_from(data, datalen)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
/*
* Ensure origin contains no quote character and that the flags are
* consistent with what we received
*/
if (strchr(origin, '\"') != NULL ||
(flags & 0x40) != 0 /* AD */ ||
((flags & 0x80) == 0 /* ED */) != (sshbuf_len(extensions) == 0)) {
r = SSH_ERR_INVALID_FORMAT;
goto out;
}
/*
* Prepare the preamble to clientData that we expect, poking the
* challenge and origin into their canonical positions in the
* structure. The crossOrigin flag and any additional extension
* fields present are ignored.
*/
#define WEBAUTHN_0 "{\"type\":\"webauthn.get\",\"challenge\":\""
#define WEBAUTHN_1 "\",\"origin\":\""
#define WEBAUTHN_2 "\""
if ((r = sshbuf_put(m, WEBAUTHN_0, sizeof(WEBAUTHN_0) - 1)) != 0 ||
(r = sshbuf_dtourlb64(chall, m, 0)) != 0 ||
(r = sshbuf_put(m, WEBAUTHN_1, sizeof(WEBAUTHN_1) - 1)) != 0 ||
(r = sshbuf_put(m, origin, strlen(origin))) != 0 ||
(r = sshbuf_put(m, WEBAUTHN_2, sizeof(WEBAUTHN_2) - 1)) != 0)
goto out;
#ifdef DEBUG_SK
fprintf(stderr, "%s: received origin: %s\n", __func__, origin);
fprintf(stderr, "%s: received clientData:\n", __func__);
sshbuf_dump(wrapper, stderr);
fprintf(stderr, "%s: expected clientData premable:\n", __func__);
sshbuf_dump(m, stderr);
#endif
/* Check that the supplied clientData has the preamble we expect */
if ((r = sshbuf_cmp(wrapper, 0, sshbuf_ptr(m), sshbuf_len(m))) != 0)
goto out;
/* Prepare hash of clientData */
if ((r = ssh_digest_buffer(SSH_DIGEST_SHA256, wrapper,
msghash, msghashlen)) != 0)
goto out;
/* success */
r = 0;
out:
sshbuf_free(chall);
sshbuf_free(m);
return r;
}
/* ARGSUSED */
-int
+static int
ssh_ecdsa_sk_verify(const struct sshkey *key,
- const u_char *signature, size_t signaturelen,
- const u_char *data, size_t datalen, u_int compat,
+ const u_char *sig, size_t siglen,
+ const u_char *data, size_t dlen, const char *alg, u_int compat,
struct sshkey_sig_details **detailsp)
{
- ECDSA_SIG *sig = NULL;
+ ECDSA_SIG *esig = NULL;
BIGNUM *sig_r = NULL, *sig_s = NULL;
u_char sig_flags;
u_char msghash[32], apphash[32], sighash[32];
u_int sig_counter;
int is_webauthn = 0, ret = SSH_ERR_INTERNAL_ERROR;
struct sshbuf *b = NULL, *sigbuf = NULL, *original_signed = NULL;
struct sshbuf *webauthn_wrapper = NULL, *webauthn_exts = NULL;
char *ktype = NULL, *webauthn_origin = NULL;
struct sshkey_sig_details *details = NULL;
#ifdef DEBUG_SK
char *tmp = NULL;
#endif
if (detailsp != NULL)
*detailsp = NULL;
if (key == NULL || key->ecdsa == NULL ||
sshkey_type_plain(key->type) != KEY_ECDSA_SK ||
- signature == NULL || signaturelen == 0)
+ sig == NULL || siglen == 0)
return SSH_ERR_INVALID_ARGUMENT;
if (key->ecdsa_nid != NID_X9_62_prime256v1)
return SSH_ERR_INTERNAL_ERROR;
/* fetch signature */
- if ((b = sshbuf_from(signature, signaturelen)) == NULL)
+ if ((b = sshbuf_from(sig, siglen)) == NULL)
return SSH_ERR_ALLOC_FAIL;
if ((details = calloc(1, sizeof(*details))) == NULL) {
ret = SSH_ERR_ALLOC_FAIL;
goto out;
}
if (sshbuf_get_cstring(b, &ktype, NULL) != 0) {
ret = SSH_ERR_INVALID_FORMAT;
goto out;
}
if (strcmp(ktype, "webauthn-sk-ecdsa-sha2-nistp256@openssh.com") == 0)
is_webauthn = 1;
else if (strcmp(ktype, "sk-ecdsa-sha2-nistp256@openssh.com") != 0) {
ret = SSH_ERR_INVALID_FORMAT;
goto out;
}
if (sshbuf_froms(b, &sigbuf) != 0 ||
sshbuf_get_u8(b, &sig_flags) != 0 ||
sshbuf_get_u32(b, &sig_counter) != 0) {
ret = SSH_ERR_INVALID_FORMAT;
goto out;
}
if (is_webauthn) {
if (sshbuf_get_cstring(b, &webauthn_origin, NULL) != 0 ||
sshbuf_froms(b, &webauthn_wrapper) != 0 ||
sshbuf_froms(b, &webauthn_exts) != 0) {
ret = SSH_ERR_INVALID_FORMAT;
goto out;
}
}
if (sshbuf_len(b) != 0) {
ret = SSH_ERR_UNEXPECTED_TRAILING_DATA;
goto out;
}
/* parse signature */
if (sshbuf_get_bignum2(sigbuf, &sig_r) != 0 ||
sshbuf_get_bignum2(sigbuf, &sig_s) != 0) {
ret = SSH_ERR_INVALID_FORMAT;
goto out;
}
if (sshbuf_len(sigbuf) != 0) {
ret = SSH_ERR_UNEXPECTED_TRAILING_DATA;
goto out;
}
#ifdef DEBUG_SK
fprintf(stderr, "%s: data: (len %zu)\n", __func__, datalen);
/* sshbuf_dump_data(data, datalen, stderr); */
fprintf(stderr, "%s: sig_r: %s\n", __func__, (tmp = BN_bn2hex(sig_r)));
free(tmp);
fprintf(stderr, "%s: sig_s: %s\n", __func__, (tmp = BN_bn2hex(sig_s)));
free(tmp);
fprintf(stderr, "%s: sig_flags = 0x%02x, sig_counter = %u\n",
__func__, sig_flags, sig_counter);
if (is_webauthn) {
fprintf(stderr, "%s: webauthn origin: %s\n", __func__,
webauthn_origin);
fprintf(stderr, "%s: webauthn_wrapper:\n", __func__);
sshbuf_dump(webauthn_wrapper, stderr);
}
#endif
- if ((sig = ECDSA_SIG_new()) == NULL) {
+ if ((esig = ECDSA_SIG_new()) == NULL) {
ret = SSH_ERR_ALLOC_FAIL;
goto out;
}
- if (!ECDSA_SIG_set0(sig, sig_r, sig_s)) {
+ if (!ECDSA_SIG_set0(esig, sig_r, sig_s)) {
ret = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
sig_r = sig_s = NULL; /* transferred */
/* Reconstruct data that was supposedly signed */
if ((original_signed = sshbuf_new()) == NULL) {
ret = SSH_ERR_ALLOC_FAIL;
goto out;
}
if (is_webauthn) {
- if ((ret = webauthn_check_prepare_hash(data, datalen,
+ if ((ret = webauthn_check_prepare_hash(data, dlen,
webauthn_origin, webauthn_wrapper, sig_flags, webauthn_exts,
msghash, sizeof(msghash))) != 0)
goto out;
- } else if ((ret = ssh_digest_memory(SSH_DIGEST_SHA256, data, datalen,
+ } else if ((ret = ssh_digest_memory(SSH_DIGEST_SHA256, data, dlen,
msghash, sizeof(msghash))) != 0)
goto out;
/* Application value is hashed before signature */
if ((ret = ssh_digest_memory(SSH_DIGEST_SHA256, key->sk_application,
strlen(key->sk_application), apphash, sizeof(apphash))) != 0)
goto out;
#ifdef DEBUG_SK
fprintf(stderr, "%s: hashed application:\n", __func__);
sshbuf_dump_data(apphash, sizeof(apphash), stderr);
fprintf(stderr, "%s: hashed message:\n", __func__);
sshbuf_dump_data(msghash, sizeof(msghash), stderr);
#endif
if ((ret = sshbuf_put(original_signed,
apphash, sizeof(apphash))) != 0 ||
(ret = sshbuf_put_u8(original_signed, sig_flags)) != 0 ||
(ret = sshbuf_put_u32(original_signed, sig_counter)) != 0 ||
(ret = sshbuf_putb(original_signed, webauthn_exts)) != 0 ||
(ret = sshbuf_put(original_signed, msghash, sizeof(msghash))) != 0)
goto out;
/* Signature is over H(original_signed) */
if ((ret = ssh_digest_buffer(SSH_DIGEST_SHA256, original_signed,
sighash, sizeof(sighash))) != 0)
goto out;
details->sk_counter = sig_counter;
details->sk_flags = sig_flags;
#ifdef DEBUG_SK
fprintf(stderr, "%s: signed buf:\n", __func__);
sshbuf_dump(original_signed, stderr);
fprintf(stderr, "%s: signed hash:\n", __func__);
sshbuf_dump_data(sighash, sizeof(sighash), stderr);
#endif
/* Verify it */
- switch (ECDSA_do_verify(sighash, sizeof(sighash), sig, key->ecdsa)) {
+ switch (ECDSA_do_verify(sighash, sizeof(sighash), esig, key->ecdsa)) {
case 1:
ret = 0;
break;
case 0:
ret = SSH_ERR_SIGNATURE_INVALID;
goto out;
default:
ret = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
/* success */
if (detailsp != NULL) {
*detailsp = details;
details = NULL;
}
out:
explicit_bzero(&sig_flags, sizeof(sig_flags));
explicit_bzero(&sig_counter, sizeof(sig_counter));
explicit_bzero(msghash, sizeof(msghash));
explicit_bzero(sighash, sizeof(msghash));
explicit_bzero(apphash, sizeof(apphash));
sshkey_sig_details_free(details);
sshbuf_free(webauthn_wrapper);
sshbuf_free(webauthn_exts);
free(webauthn_origin);
sshbuf_free(original_signed);
sshbuf_free(sigbuf);
sshbuf_free(b);
- ECDSA_SIG_free(sig);
+ ECDSA_SIG_free(esig);
BN_clear_free(sig_r);
BN_clear_free(sig_s);
free(ktype);
return ret;
}
+static const struct sshkey_impl_funcs sshkey_ecdsa_sk_funcs = {
+ /* .size = */ NULL,
+ /* .alloc = */ NULL,
+ /* .cleanup = */ ssh_ecdsa_sk_cleanup,
+ /* .equal = */ ssh_ecdsa_sk_equal,
+ /* .ssh_serialize_public = */ ssh_ecdsa_sk_serialize_public,
+ /* .ssh_deserialize_public = */ ssh_ecdsa_sk_deserialize_public,
+ /* .ssh_serialize_private = */ ssh_ecdsa_sk_serialize_private,
+ /* .ssh_deserialize_private = */ ssh_ecdsa_sk_deserialize_private,
+ /* .generate = */ NULL,
+ /* .copy_public = */ ssh_ecdsa_sk_copy_public,
+ /* .sign = */ NULL,
+ /* .verify = */ ssh_ecdsa_sk_verify,
+};
+
+const struct sshkey_impl sshkey_ecdsa_sk_impl = {
+ /* .name = */ "sk-ecdsa-sha2-nistp256@openssh.com",
+ /* .shortname = */ "ECDSA-SK",
+ /* .sigalg = */ NULL,
+ /* .type = */ KEY_ECDSA_SK,
+ /* .nid = */ NID_X9_62_prime256v1,
+ /* .cert = */ 0,
+ /* .sigonly = */ 0,
+ /* .keybits = */ 256,
+ /* .funcs = */ &sshkey_ecdsa_sk_funcs,
+};
+
+const struct sshkey_impl sshkey_ecdsa_sk_cert_impl = {
+ /* .name = */ "sk-ecdsa-sha2-nistp256-cert-v01@openssh.com",
+ /* .shortname = */ "ECDSA-SK-CERT",
+ /* .sigalg = */ NULL,
+ /* .type = */ KEY_ECDSA_SK_CERT,
+ /* .nid = */ NID_X9_62_prime256v1,
+ /* .cert = */ 1,
+ /* .sigonly = */ 0,
+ /* .keybits = */ 256,
+ /* .funcs = */ &sshkey_ecdsa_sk_funcs,
+};
+
+const struct sshkey_impl sshkey_ecdsa_sk_webauthn_impl = {
+ /* .name = */ "webauthn-sk-ecdsa-sha2-nistp256@openssh.com",
+ /* .shortname = */ "ECDSA-SK",
+ /* .sigalg = */ NULL,
+ /* .type = */ KEY_ECDSA_SK,
+ /* .nid = */ NID_X9_62_prime256v1,
+ /* .cert = */ 0,
+ /* .sigonly = */ 1,
+ /* .keybits = */ 256,
+ /* .funcs = */ &sshkey_ecdsa_sk_funcs,
+};
+
#endif /* OPENSSL_HAS_ECC */
diff --git a/crypto/openssh/ssh-ecdsa.c b/crypto/openssh/ssh-ecdsa.c
index 599c7199db19..4bcb89baf517 100644
--- a/crypto/openssh/ssh-ecdsa.c
+++ b/crypto/openssh/ssh-ecdsa.c
@@ -1,200 +1,470 @@
-/* $OpenBSD: ssh-ecdsa.c,v 1.16 2019/01/21 09:54:11 djm Exp $ */
+/* $OpenBSD: ssh-ecdsa.c,v 1.25 2022/10/28 00:44:44 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
* Copyright (c) 2010 Damien Miller. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "includes.h"
#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC)
#include <sys/types.h>
#include <openssl/bn.h>
#include <openssl/ec.h>
#include <openssl/ecdsa.h>
#include <openssl/evp.h>
#include <string.h>
#include "sshbuf.h"
#include "ssherr.h"
#include "digest.h"
#define SSHKEY_INTERNAL
#include "sshkey.h"
#include "openbsd-compat/openssl-compat.h"
+static u_int
+ssh_ecdsa_size(const struct sshkey *key)
+{
+ switch (key->ecdsa_nid) {
+ case NID_X9_62_prime256v1:
+ return 256;
+ case NID_secp384r1:
+ return 384;
+#ifdef OPENSSL_HAS_NISTP521
+ case NID_secp521r1:
+ return 521;
+#endif
+ default:
+ return 0;
+ }
+}
+
+static void
+ssh_ecdsa_cleanup(struct sshkey *k)
+{
+ EC_KEY_free(k->ecdsa);
+ k->ecdsa = NULL;
+}
+
+static int
+ssh_ecdsa_equal(const struct sshkey *a, const struct sshkey *b)
+{
+ const EC_GROUP *grp_a, *grp_b;
+ const EC_POINT *pub_a, *pub_b;
+
+ if (a->ecdsa == NULL || b->ecdsa == NULL)
+ return 0;
+ if ((grp_a = EC_KEY_get0_group(a->ecdsa)) == NULL ||
+ (grp_b = EC_KEY_get0_group(b->ecdsa)) == NULL)
+ return 0;
+ if ((pub_a = EC_KEY_get0_public_key(a->ecdsa)) == NULL ||
+ (pub_b = EC_KEY_get0_public_key(b->ecdsa)) == NULL)
+ return 0;
+ if (EC_GROUP_cmp(grp_a, grp_b, NULL) != 0)
+ return 0;
+ if (EC_POINT_cmp(grp_a, pub_a, pub_b, NULL) != 0)
+ return 0;
+
+ return 1;
+}
+
+static int
+ssh_ecdsa_serialize_public(const struct sshkey *key, struct sshbuf *b,
+ enum sshkey_serialize_rep opts)
+{
+ int r;
+
+ if (key->ecdsa == NULL)
+ return SSH_ERR_INVALID_ARGUMENT;
+ if ((r = sshbuf_put_cstring(b,
+ sshkey_curve_nid_to_name(key->ecdsa_nid))) != 0 ||
+ (r = sshbuf_put_eckey(b, key->ecdsa)) != 0)
+ return r;
+
+ return 0;
+}
+
+static int
+ssh_ecdsa_serialize_private(const struct sshkey *key, struct sshbuf *b,
+ enum sshkey_serialize_rep opts)
+{
+ int r;
+
+ if (!sshkey_is_cert(key)) {
+ if ((r = ssh_ecdsa_serialize_public(key, b, opts)) != 0)
+ return r;
+ }
+ if ((r = sshbuf_put_bignum2(b,
+ EC_KEY_get0_private_key(key->ecdsa))) != 0)
+ return r;
+ return 0;
+}
+
+static int
+ssh_ecdsa_generate(struct sshkey *k, int bits)
+{
+ EC_KEY *private;
+
+ if ((k->ecdsa_nid = sshkey_ecdsa_bits_to_nid(bits)) == -1)
+ return SSH_ERR_KEY_LENGTH;
+ if ((private = EC_KEY_new_by_curve_name(k->ecdsa_nid)) == NULL)
+ return SSH_ERR_ALLOC_FAIL;
+ if (EC_KEY_generate_key(private) != 1) {
+ EC_KEY_free(private);
+ return SSH_ERR_LIBCRYPTO_ERROR;
+ }
+ EC_KEY_set_asn1_flag(private, OPENSSL_EC_NAMED_CURVE);
+ k->ecdsa = private;
+ return 0;
+}
+
+static int
+ssh_ecdsa_copy_public(const struct sshkey *from, struct sshkey *to)
+{
+ to->ecdsa_nid = from->ecdsa_nid;
+ if ((to->ecdsa = EC_KEY_new_by_curve_name(from->ecdsa_nid)) == NULL)
+ return SSH_ERR_ALLOC_FAIL;
+ if (EC_KEY_set_public_key(to->ecdsa,
+ EC_KEY_get0_public_key(from->ecdsa)) != 1)
+ return SSH_ERR_LIBCRYPTO_ERROR; /* caller will free k->ecdsa */
+ return 0;
+}
+
+static int
+ssh_ecdsa_deserialize_public(const char *ktype, struct sshbuf *b,
+ struct sshkey *key)
+{
+ int r;
+ char *curve = NULL;
+
+ if ((key->ecdsa_nid = sshkey_ecdsa_nid_from_name(ktype)) == -1)
+ return SSH_ERR_INVALID_ARGUMENT;
+ if ((r = sshbuf_get_cstring(b, &curve, NULL)) != 0)
+ goto out;
+ if (key->ecdsa_nid != sshkey_curve_name_to_nid(curve)) {
+ r = SSH_ERR_EC_CURVE_MISMATCH;
+ goto out;
+ }
+ EC_KEY_free(key->ecdsa);
+ key->ecdsa = NULL;
+ if ((key->ecdsa = EC_KEY_new_by_curve_name(key->ecdsa_nid)) == NULL) {
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ if ((r = sshbuf_get_eckey(b, key->ecdsa)) != 0)
+ goto out;
+ if (sshkey_ec_validate_public(EC_KEY_get0_group(key->ecdsa),
+ EC_KEY_get0_public_key(key->ecdsa)) != 0) {
+ r = SSH_ERR_KEY_INVALID_EC_VALUE;
+ goto out;
+ }
+ /* success */
+ r = 0;
+#ifdef DEBUG_PK
+ sshkey_dump_ec_point(EC_KEY_get0_group(key->ecdsa),
+ EC_KEY_get0_public_key(key->ecdsa));
+#endif
+ out:
+ free(curve);
+ if (r != 0) {
+ EC_KEY_free(key->ecdsa);
+ key->ecdsa = NULL;
+ }
+ return r;
+}
+
+static int
+ssh_ecdsa_deserialize_private(const char *ktype, struct sshbuf *b,
+ struct sshkey *key)
+{
+ int r;
+ BIGNUM *exponent = NULL;
+
+ if (!sshkey_is_cert(key)) {
+ if ((r = ssh_ecdsa_deserialize_public(ktype, b, key)) != 0)
+ return r;
+ }
+ if ((r = sshbuf_get_bignum2(b, &exponent)) != 0)
+ goto out;
+ if (EC_KEY_set_private_key(key->ecdsa, exponent) != 1) {
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ if ((r = sshkey_ec_validate_private(key->ecdsa)) != 0)
+ goto out;
+ /* success */
+ r = 0;
+ out:
+ BN_clear_free(exponent);
+ return r;
+}
+
/* ARGSUSED */
-int
-ssh_ecdsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
- const u_char *data, size_t datalen, u_int compat)
+static int
+ssh_ecdsa_sign(struct sshkey *key,
+ u_char **sigp, size_t *lenp,
+ const u_char *data, size_t dlen,
+ const char *alg, const char *sk_provider, const char *sk_pin, u_int compat)
{
- ECDSA_SIG *sig = NULL;
+ ECDSA_SIG *esig = NULL;
const BIGNUM *sig_r, *sig_s;
int hash_alg;
u_char digest[SSH_DIGEST_MAX_LENGTH];
- size_t len, dlen;
+ size_t len, hlen;
struct sshbuf *b = NULL, *bb = NULL;
int ret = SSH_ERR_INTERNAL_ERROR;
if (lenp != NULL)
*lenp = 0;
if (sigp != NULL)
*sigp = NULL;
if (key == NULL || key->ecdsa == NULL ||
sshkey_type_plain(key->type) != KEY_ECDSA)
return SSH_ERR_INVALID_ARGUMENT;
if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1 ||
- (dlen = ssh_digest_bytes(hash_alg)) == 0)
+ (hlen = ssh_digest_bytes(hash_alg)) == 0)
return SSH_ERR_INTERNAL_ERROR;
- if ((ret = ssh_digest_memory(hash_alg, data, datalen,
+ if ((ret = ssh_digest_memory(hash_alg, data, dlen,
digest, sizeof(digest))) != 0)
goto out;
- if ((sig = ECDSA_do_sign(digest, dlen, key->ecdsa)) == NULL) {
+ if ((esig = ECDSA_do_sign(digest, hlen, key->ecdsa)) == NULL) {
ret = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
if ((bb = sshbuf_new()) == NULL || (b = sshbuf_new()) == NULL) {
ret = SSH_ERR_ALLOC_FAIL;
goto out;
}
- ECDSA_SIG_get0(sig, &sig_r, &sig_s);
+ ECDSA_SIG_get0(esig, &sig_r, &sig_s);
if ((ret = sshbuf_put_bignum2(bb, sig_r)) != 0 ||
(ret = sshbuf_put_bignum2(bb, sig_s)) != 0)
goto out;
if ((ret = sshbuf_put_cstring(b, sshkey_ssh_name_plain(key))) != 0 ||
(ret = sshbuf_put_stringb(b, bb)) != 0)
goto out;
len = sshbuf_len(b);
if (sigp != NULL) {
if ((*sigp = malloc(len)) == NULL) {
ret = SSH_ERR_ALLOC_FAIL;
goto out;
}
memcpy(*sigp, sshbuf_ptr(b), len);
}
if (lenp != NULL)
*lenp = len;
ret = 0;
out:
explicit_bzero(digest, sizeof(digest));
sshbuf_free(b);
sshbuf_free(bb);
- ECDSA_SIG_free(sig);
+ ECDSA_SIG_free(esig);
return ret;
}
/* ARGSUSED */
-int
+static int
ssh_ecdsa_verify(const struct sshkey *key,
- const u_char *signature, size_t signaturelen,
- const u_char *data, size_t datalen, u_int compat)
+ const u_char *sig, size_t siglen,
+ const u_char *data, size_t dlen, const char *alg, u_int compat,
+ struct sshkey_sig_details **detailsp)
{
- ECDSA_SIG *sig = NULL;
+ ECDSA_SIG *esig = NULL;
BIGNUM *sig_r = NULL, *sig_s = NULL;
int hash_alg;
u_char digest[SSH_DIGEST_MAX_LENGTH];
- size_t dlen;
+ size_t hlen;
int ret = SSH_ERR_INTERNAL_ERROR;
struct sshbuf *b = NULL, *sigbuf = NULL;
char *ktype = NULL;
if (key == NULL || key->ecdsa == NULL ||
sshkey_type_plain(key->type) != KEY_ECDSA ||
- signature == NULL || signaturelen == 0)
+ sig == NULL || siglen == 0)
return SSH_ERR_INVALID_ARGUMENT;
if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1 ||
- (dlen = ssh_digest_bytes(hash_alg)) == 0)
+ (hlen = ssh_digest_bytes(hash_alg)) == 0)
return SSH_ERR_INTERNAL_ERROR;
/* fetch signature */
- if ((b = sshbuf_from(signature, signaturelen)) == NULL)
+ if ((b = sshbuf_from(sig, siglen)) == NULL)
return SSH_ERR_ALLOC_FAIL;
if (sshbuf_get_cstring(b, &ktype, NULL) != 0 ||
sshbuf_froms(b, &sigbuf) != 0) {
ret = SSH_ERR_INVALID_FORMAT;
goto out;
}
if (strcmp(sshkey_ssh_name_plain(key), ktype) != 0) {
ret = SSH_ERR_KEY_TYPE_MISMATCH;
goto out;
}
if (sshbuf_len(b) != 0) {
ret = SSH_ERR_UNEXPECTED_TRAILING_DATA;
goto out;
}
/* parse signature */
if (sshbuf_get_bignum2(sigbuf, &sig_r) != 0 ||
sshbuf_get_bignum2(sigbuf, &sig_s) != 0) {
ret = SSH_ERR_INVALID_FORMAT;
goto out;
}
- if ((sig = ECDSA_SIG_new()) == NULL) {
+ if ((esig = ECDSA_SIG_new()) == NULL) {
ret = SSH_ERR_ALLOC_FAIL;
goto out;
}
- if (!ECDSA_SIG_set0(sig, sig_r, sig_s)) {
+ if (!ECDSA_SIG_set0(esig, sig_r, sig_s)) {
ret = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
sig_r = sig_s = NULL; /* transferred */
if (sshbuf_len(sigbuf) != 0) {
ret = SSH_ERR_UNEXPECTED_TRAILING_DATA;
goto out;
}
- if ((ret = ssh_digest_memory(hash_alg, data, datalen,
+ if ((ret = ssh_digest_memory(hash_alg, data, dlen,
digest, sizeof(digest))) != 0)
goto out;
- switch (ECDSA_do_verify(digest, dlen, sig, key->ecdsa)) {
+ switch (ECDSA_do_verify(digest, hlen, esig, key->ecdsa)) {
case 1:
ret = 0;
break;
case 0:
ret = SSH_ERR_SIGNATURE_INVALID;
goto out;
default:
ret = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
out:
explicit_bzero(digest, sizeof(digest));
sshbuf_free(sigbuf);
sshbuf_free(b);
- ECDSA_SIG_free(sig);
+ ECDSA_SIG_free(esig);
BN_clear_free(sig_r);
BN_clear_free(sig_s);
free(ktype);
return ret;
}
+/* NB. not static; used by ECDSA-SK */
+const struct sshkey_impl_funcs sshkey_ecdsa_funcs = {
+ /* .size = */ ssh_ecdsa_size,
+ /* .alloc = */ NULL,
+ /* .cleanup = */ ssh_ecdsa_cleanup,
+ /* .equal = */ ssh_ecdsa_equal,
+ /* .ssh_serialize_public = */ ssh_ecdsa_serialize_public,
+ /* .ssh_deserialize_public = */ ssh_ecdsa_deserialize_public,
+ /* .ssh_serialize_private = */ ssh_ecdsa_serialize_private,
+ /* .ssh_deserialize_private = */ ssh_ecdsa_deserialize_private,
+ /* .generate = */ ssh_ecdsa_generate,
+ /* .copy_public = */ ssh_ecdsa_copy_public,
+ /* .sign = */ ssh_ecdsa_sign,
+ /* .verify = */ ssh_ecdsa_verify,
+};
+
+const struct sshkey_impl sshkey_ecdsa_nistp256_impl = {
+ /* .name = */ "ecdsa-sha2-nistp256",
+ /* .shortname = */ "ECDSA",
+ /* .sigalg = */ NULL,
+ /* .type = */ KEY_ECDSA,
+ /* .nid = */ NID_X9_62_prime256v1,
+ /* .cert = */ 0,
+ /* .sigonly = */ 0,
+ /* .keybits = */ 0,
+ /* .funcs = */ &sshkey_ecdsa_funcs,
+};
+
+const struct sshkey_impl sshkey_ecdsa_nistp256_cert_impl = {
+ /* .name = */ "ecdsa-sha2-nistp256-cert-v01@openssh.com",
+ /* .shortname = */ "ECDSA-CERT",
+ /* .sigalg = */ NULL,
+ /* .type = */ KEY_ECDSA_CERT,
+ /* .nid = */ NID_X9_62_prime256v1,
+ /* .cert = */ 1,
+ /* .sigonly = */ 0,
+ /* .keybits = */ 0,
+ /* .funcs = */ &sshkey_ecdsa_funcs,
+};
+
+const struct sshkey_impl sshkey_ecdsa_nistp384_impl = {
+ /* .name = */ "ecdsa-sha2-nistp384",
+ /* .shortname = */ "ECDSA",
+ /* .sigalg = */ NULL,
+ /* .type = */ KEY_ECDSA,
+ /* .nid = */ NID_secp384r1,
+ /* .cert = */ 0,
+ /* .sigonly = */ 0,
+ /* .keybits = */ 0,
+ /* .funcs = */ &sshkey_ecdsa_funcs,
+};
+
+const struct sshkey_impl sshkey_ecdsa_nistp384_cert_impl = {
+ /* .name = */ "ecdsa-sha2-nistp384-cert-v01@openssh.com",
+ /* .shortname = */ "ECDSA-CERT",
+ /* .sigalg = */ NULL,
+ /* .type = */ KEY_ECDSA_CERT,
+ /* .nid = */ NID_secp384r1,
+ /* .cert = */ 1,
+ /* .sigonly = */ 0,
+ /* .keybits = */ 0,
+ /* .funcs = */ &sshkey_ecdsa_funcs,
+};
+
+#ifdef OPENSSL_HAS_NISTP521
+const struct sshkey_impl sshkey_ecdsa_nistp521_impl = {
+ /* .name = */ "ecdsa-sha2-nistp521",
+ /* .shortname = */ "ECDSA",
+ /* .sigalg = */ NULL,
+ /* .type = */ KEY_ECDSA,
+ /* .nid = */ NID_secp521r1,
+ /* .cert = */ 0,
+ /* .sigonly = */ 0,
+ /* .keybits = */ 0,
+ /* .funcs = */ &sshkey_ecdsa_funcs,
+};
+
+const struct sshkey_impl sshkey_ecdsa_nistp521_cert_impl = {
+ /* .name = */ "ecdsa-sha2-nistp521-cert-v01@openssh.com",
+ /* .shortname = */ "ECDSA-CERT",
+ /* .sigalg = */ NULL,
+ /* .type = */ KEY_ECDSA_CERT,
+ /* .nid = */ NID_secp521r1,
+ /* .cert = */ 1,
+ /* .sigonly = */ 0,
+ /* .keybits = */ 0,
+ /* .funcs = */ &sshkey_ecdsa_funcs,
+};
+#endif
+
#endif /* WITH_OPENSSL && OPENSSL_HAS_ECC */
diff --git a/crypto/openssh/ssh-ed25519-sk.c b/crypto/openssh/ssh-ed25519-sk.c
index 4393ca669e17..c6bc5e72b1d2 100644
--- a/crypto/openssh/ssh-ed25519-sk.c
+++ b/crypto/openssh/ssh-ed25519-sk.c
@@ -1,163 +1,288 @@
-/* $OpenBSD: ssh-ed25519-sk.c,v 1.6 2020/10/18 11:32:02 djm Exp $ */
+/* $OpenBSD: ssh-ed25519-sk.c,v 1.15 2022/10/28 00:44:44 djm Exp $ */
/*
* Copyright (c) 2019 Markus Friedl. All rights reserved.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* #define DEBUG_SK 1 */
#include "includes.h"
#define SSHKEY_INTERNAL
#include <sys/types.h>
#include <limits.h>
#include "crypto_api.h"
#include <string.h>
#include <stdarg.h>
#include "log.h"
#include "sshbuf.h"
#include "sshkey.h"
#include "ssherr.h"
#include "ssh.h"
#include "digest.h"
-int
+/* Reuse some ED25519 internals */
+extern struct sshkey_impl_funcs sshkey_ed25519_funcs;
+
+static void
+ssh_ed25519_sk_cleanup(struct sshkey *k)
+{
+ sshkey_sk_cleanup(k);
+ sshkey_ed25519_funcs.cleanup(k);
+}
+
+static int
+ssh_ed25519_sk_equal(const struct sshkey *a, const struct sshkey *b)
+{
+ if (!sshkey_sk_fields_equal(a, b))
+ return 0;
+ if (!sshkey_ed25519_funcs.equal(a, b))
+ return 0;
+ return 1;
+}
+
+static int
+ssh_ed25519_sk_serialize_public(const struct sshkey *key, struct sshbuf *b,
+ enum sshkey_serialize_rep opts)
+{
+ int r;
+
+ if ((r = sshkey_ed25519_funcs.serialize_public(key, b, opts)) != 0)
+ return r;
+ if ((r = sshkey_serialize_sk(key, b)) != 0)
+ return r;
+
+ return 0;
+}
+
+static int
+ssh_ed25519_sk_serialize_private(const struct sshkey *key, struct sshbuf *b,
+ enum sshkey_serialize_rep opts)
+{
+ int r;
+
+ if ((r = sshkey_ed25519_funcs.serialize_public(key, b, opts)) != 0)
+ return r;
+ if ((r = sshkey_serialize_private_sk(key, b)) != 0)
+ return r;
+
+ return 0;
+}
+
+static int
+ssh_ed25519_sk_copy_public(const struct sshkey *from, struct sshkey *to)
+{
+ int r;
+
+ if ((r = sshkey_ed25519_funcs.copy_public(from, to)) != 0)
+ return r;
+ if ((r = sshkey_copy_public_sk(from, to)) != 0)
+ return r;
+ return 0;
+}
+
+static int
+ssh_ed25519_sk_deserialize_public(const char *ktype, struct sshbuf *b,
+ struct sshkey *key)
+{
+ int r;
+
+ if ((r = sshkey_ed25519_funcs.deserialize_public(ktype, b, key)) != 0)
+ return r;
+ if ((r = sshkey_deserialize_sk(b, key)) != 0)
+ return r;
+ return 0;
+}
+
+static int
+ssh_ed25519_sk_deserialize_private(const char *ktype, struct sshbuf *b,
+ struct sshkey *key)
+{
+ int r;
+
+ if ((r = sshkey_ed25519_funcs.deserialize_public(ktype, b, key)) != 0)
+ return r;
+ if ((r = sshkey_private_deserialize_sk(b, key)) != 0)
+ return r;
+ return 0;
+}
+
+static int
ssh_ed25519_sk_verify(const struct sshkey *key,
- const u_char *signature, size_t signaturelen,
- const u_char *data, size_t datalen, u_int compat,
+ const u_char *sig, size_t siglen,
+ const u_char *data, size_t dlen, const char *alg, u_int compat,
struct sshkey_sig_details **detailsp)
{
struct sshbuf *b = NULL;
struct sshbuf *encoded = NULL;
char *ktype = NULL;
const u_char *sigblob;
const u_char *sm;
u_char *m = NULL;
u_char apphash[32];
u_char msghash[32];
u_char sig_flags;
u_int sig_counter;
size_t len;
unsigned long long smlen = 0, mlen = 0;
int r = SSH_ERR_INTERNAL_ERROR;
int ret;
struct sshkey_sig_details *details = NULL;
if (detailsp != NULL)
*detailsp = NULL;
if (key == NULL ||
sshkey_type_plain(key->type) != KEY_ED25519_SK ||
key->ed25519_pk == NULL ||
- signature == NULL || signaturelen == 0)
+ sig == NULL || siglen == 0)
return SSH_ERR_INVALID_ARGUMENT;
- if ((b = sshbuf_from(signature, signaturelen)) == NULL)
+ if ((b = sshbuf_from(sig, siglen)) == NULL)
return SSH_ERR_ALLOC_FAIL;
if (sshbuf_get_cstring(b, &ktype, NULL) != 0 ||
sshbuf_get_string_direct(b, &sigblob, &len) != 0 ||
sshbuf_get_u8(b, &sig_flags) != 0 ||
sshbuf_get_u32(b, &sig_counter) != 0) {
r = SSH_ERR_INVALID_FORMAT;
goto out;
}
#ifdef DEBUG_SK
fprintf(stderr, "%s: data:\n", __func__);
/* sshbuf_dump_data(data, datalen, stderr); */
fprintf(stderr, "%s: sigblob:\n", __func__);
sshbuf_dump_data(sigblob, len, stderr);
fprintf(stderr, "%s: sig_flags = 0x%02x, sig_counter = %u\n",
__func__, sig_flags, sig_counter);
#endif
if (strcmp(sshkey_ssh_name_plain(key), ktype) != 0) {
r = SSH_ERR_KEY_TYPE_MISMATCH;
goto out;
}
if (sshbuf_len(b) != 0) {
r = SSH_ERR_UNEXPECTED_TRAILING_DATA;
goto out;
}
if (len > crypto_sign_ed25519_BYTES) {
r = SSH_ERR_INVALID_FORMAT;
goto out;
}
if (ssh_digest_memory(SSH_DIGEST_SHA256, key->sk_application,
strlen(key->sk_application), apphash, sizeof(apphash)) != 0 ||
- ssh_digest_memory(SSH_DIGEST_SHA256, data, datalen,
+ ssh_digest_memory(SSH_DIGEST_SHA256, data, dlen,
msghash, sizeof(msghash)) != 0) {
r = SSH_ERR_INVALID_ARGUMENT;
goto out;
}
#ifdef DEBUG_SK
fprintf(stderr, "%s: hashed application:\n", __func__);
sshbuf_dump_data(apphash, sizeof(apphash), stderr);
fprintf(stderr, "%s: hashed message:\n", __func__);
sshbuf_dump_data(msghash, sizeof(msghash), stderr);
#endif
if ((details = calloc(1, sizeof(*details))) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
details->sk_counter = sig_counter;
details->sk_flags = sig_flags;
if ((encoded = sshbuf_new()) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
if (sshbuf_put(encoded, sigblob, len) != 0 ||
sshbuf_put(encoded, apphash, sizeof(apphash)) != 0 ||
sshbuf_put_u8(encoded, sig_flags) != 0 ||
sshbuf_put_u32(encoded, sig_counter) != 0 ||
sshbuf_put(encoded, msghash, sizeof(msghash)) != 0) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
#ifdef DEBUG_SK
fprintf(stderr, "%s: signed buf:\n", __func__);
sshbuf_dump(encoded, stderr);
#endif
sm = sshbuf_ptr(encoded);
smlen = sshbuf_len(encoded);
mlen = smlen;
if ((m = malloc(smlen)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
if ((ret = crypto_sign_ed25519_open(m, &mlen, sm, smlen,
key->ed25519_pk)) != 0) {
debug2_f("crypto_sign_ed25519_open failed: %d", ret);
}
if (ret != 0 || mlen != smlen - len) {
r = SSH_ERR_SIGNATURE_INVALID;
goto out;
}
/* XXX compare 'm' and 'sm + len' ? */
/* success */
r = 0;
if (detailsp != NULL) {
*detailsp = details;
details = NULL;
}
out:
if (m != NULL)
freezero(m, smlen); /* NB mlen may be invalid if r != 0 */
sshkey_sig_details_free(details);
sshbuf_free(b);
sshbuf_free(encoded);
free(ktype);
return r;
}
+
+static const struct sshkey_impl_funcs sshkey_ed25519_sk_funcs = {
+ /* .size = */ NULL,
+ /* .alloc = */ NULL,
+ /* .cleanup = */ ssh_ed25519_sk_cleanup,
+ /* .equal = */ ssh_ed25519_sk_equal,
+ /* .ssh_serialize_public = */ ssh_ed25519_sk_serialize_public,
+ /* .ssh_deserialize_public = */ ssh_ed25519_sk_deserialize_public,
+ /* .ssh_serialize_private = */ ssh_ed25519_sk_serialize_private,
+ /* .ssh_deserialize_private = */ ssh_ed25519_sk_deserialize_private,
+ /* .generate = */ NULL,
+ /* .copy_public = */ ssh_ed25519_sk_copy_public,
+ /* .sign = */ NULL,
+ /* .verify = */ ssh_ed25519_sk_verify,
+};
+
+const struct sshkey_impl sshkey_ed25519_sk_impl = {
+ /* .name = */ "sk-ssh-ed25519@openssh.com",
+ /* .shortname = */ "ED25519-SK",
+ /* .sigalg = */ NULL,
+ /* .type = */ KEY_ED25519_SK,
+ /* .nid = */ 0,
+ /* .cert = */ 0,
+ /* .sigonly = */ 0,
+ /* .keybits = */ 256,
+ /* .funcs = */ &sshkey_ed25519_sk_funcs,
+};
+
+const struct sshkey_impl sshkey_ed25519_sk_cert_impl = {
+ /* .name = */ "sk-ssh-ed25519-cert-v01@openssh.com",
+ /* .shortname = */ "ED25519-SK-CERT",
+ /* .sigalg = */ NULL,
+ /* .type = */ KEY_ED25519_SK_CERT,
+ /* .nid = */ 0,
+ /* .cert = */ 1,
+ /* .sigonly = */ 0,
+ /* .keybits = */ 256,
+ /* .funcs = */ &sshkey_ed25519_sk_funcs,
+};
diff --git a/crypto/openssh/ssh-ed25519.c b/crypto/openssh/ssh-ed25519.c
index 4861628cb524..22d8db026b4c 100644
--- a/crypto/openssh/ssh-ed25519.c
+++ b/crypto/openssh/ssh-ed25519.c
@@ -1,160 +1,313 @@
-/* $OpenBSD: ssh-ed25519.c,v 1.10 2022/08/26 08:12:56 djm Exp $ */
+/* $OpenBSD: ssh-ed25519.c,v 1.19 2022/10/28 00:44:44 djm Exp $ */
/*
* Copyright (c) 2013 Markus Friedl <markus@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/types.h>
#include <limits.h>
#include "crypto_api.h"
#include <string.h>
#include <stdarg.h>
#include "log.h"
#include "sshbuf.h"
#define SSHKEY_INTERNAL
#include "sshkey.h"
#include "ssherr.h"
#include "ssh.h"
-int
-ssh_ed25519_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
- const u_char *data, size_t datalen, u_int compat)
+static void
+ssh_ed25519_cleanup(struct sshkey *k)
+{
+ freezero(k->ed25519_pk, ED25519_PK_SZ);
+ freezero(k->ed25519_sk, ED25519_SK_SZ);
+ k->ed25519_pk = NULL;
+ k->ed25519_sk = NULL;
+}
+
+static int
+ssh_ed25519_equal(const struct sshkey *a, const struct sshkey *b)
+{
+ if (a->ed25519_pk == NULL || b->ed25519_pk == NULL)
+ return 0;
+ if (memcmp(a->ed25519_pk, b->ed25519_pk, ED25519_PK_SZ) != 0)
+ return 0;
+ return 1;
+}
+
+static int
+ssh_ed25519_serialize_public(const struct sshkey *key, struct sshbuf *b,
+ enum sshkey_serialize_rep opts)
+{
+ int r;
+
+ if (key->ed25519_pk == NULL)
+ return SSH_ERR_INVALID_ARGUMENT;
+ if ((r = sshbuf_put_string(b, key->ed25519_pk, ED25519_PK_SZ)) != 0)
+ return r;
+
+ return 0;
+}
+
+static int
+ssh_ed25519_serialize_private(const struct sshkey *key, struct sshbuf *b,
+ enum sshkey_serialize_rep opts)
+{
+ int r;
+
+ if ((r = sshbuf_put_string(b, key->ed25519_pk, ED25519_PK_SZ)) != 0 ||
+ (r = sshbuf_put_string(b, key->ed25519_sk, ED25519_SK_SZ)) != 0)
+ return r;
+
+ return 0;
+}
+
+static int
+ssh_ed25519_generate(struct sshkey *k, int bits)
+{
+ if ((k->ed25519_pk = malloc(ED25519_PK_SZ)) == NULL ||
+ (k->ed25519_sk = malloc(ED25519_SK_SZ)) == NULL)
+ return SSH_ERR_ALLOC_FAIL;
+ crypto_sign_ed25519_keypair(k->ed25519_pk, k->ed25519_sk);
+ return 0;
+}
+
+static int
+ssh_ed25519_copy_public(const struct sshkey *from, struct sshkey *to)
+{
+ if (from->ed25519_pk == NULL)
+ return 0; /* XXX SSH_ERR_INTERNAL_ERROR ? */
+ if ((to->ed25519_pk = malloc(ED25519_PK_SZ)) == NULL)
+ return SSH_ERR_ALLOC_FAIL;
+ memcpy(to->ed25519_pk, from->ed25519_pk, ED25519_PK_SZ);
+ return 0;
+}
+
+static int
+ssh_ed25519_deserialize_public(const char *ktype, struct sshbuf *b,
+ struct sshkey *key)
+{
+ u_char *pk = NULL;
+ size_t len = 0;
+ int r;
+
+ if ((r = sshbuf_get_string(b, &pk, &len)) != 0)
+ return r;
+ if (len != ED25519_PK_SZ) {
+ freezero(pk, len);
+ return SSH_ERR_INVALID_FORMAT;
+ }
+ key->ed25519_pk = pk;
+ return 0;
+}
+
+static int
+ssh_ed25519_deserialize_private(const char *ktype, struct sshbuf *b,
+ struct sshkey *key)
+{
+ int r;
+ size_t sklen = 0;
+ u_char *ed25519_sk = NULL;
+
+ if ((r = ssh_ed25519_deserialize_public(NULL, b, key)) != 0)
+ goto out;
+ if ((r = sshbuf_get_string(b, &ed25519_sk, &sklen)) != 0)
+ goto out;
+ if (sklen != ED25519_SK_SZ) {
+ r = SSH_ERR_INVALID_FORMAT;
+ goto out;
+ }
+ key->ed25519_sk = ed25519_sk;
+ ed25519_sk = NULL; /* transferred */
+ /* success */
+ r = 0;
+ out:
+ freezero(ed25519_sk, sklen);
+ return r;
+}
+
+static int
+ssh_ed25519_sign(struct sshkey *key,
+ u_char **sigp, size_t *lenp,
+ const u_char *data, size_t datalen,
+ const char *alg, const char *sk_provider, const char *sk_pin, u_int compat)
{
u_char *sig = NULL;
size_t slen = 0, len;
unsigned long long smlen;
int r, ret;
struct sshbuf *b = NULL;
if (lenp != NULL)
*lenp = 0;
if (sigp != NULL)
*sigp = NULL;
if (key == NULL ||
sshkey_type_plain(key->type) != KEY_ED25519 ||
key->ed25519_sk == NULL ||
datalen >= INT_MAX - crypto_sign_ed25519_BYTES)
return SSH_ERR_INVALID_ARGUMENT;
smlen = slen = datalen + crypto_sign_ed25519_BYTES;
if ((sig = malloc(slen)) == NULL)
return SSH_ERR_ALLOC_FAIL;
if ((ret = crypto_sign_ed25519(sig, &smlen, data, datalen,
key->ed25519_sk)) != 0 || smlen <= datalen) {
r = SSH_ERR_INVALID_ARGUMENT; /* XXX better error? */
goto out;
}
/* encode signature */
if ((b = sshbuf_new()) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
if ((r = sshbuf_put_cstring(b, "ssh-ed25519")) != 0 ||
(r = sshbuf_put_string(b, sig, smlen - datalen)) != 0)
goto out;
len = sshbuf_len(b);
if (sigp != NULL) {
if ((*sigp = malloc(len)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
memcpy(*sigp, sshbuf_ptr(b), len);
}
if (lenp != NULL)
*lenp = len;
/* success */
r = 0;
out:
sshbuf_free(b);
if (sig != NULL)
freezero(sig, slen);
return r;
}
-int
+static int
ssh_ed25519_verify(const struct sshkey *key,
- const u_char *signature, size_t signaturelen,
- const u_char *data, size_t datalen, u_int compat)
+ const u_char *sig, size_t siglen,
+ const u_char *data, size_t dlen, const char *alg, u_int compat,
+ struct sshkey_sig_details **detailsp)
{
struct sshbuf *b = NULL;
char *ktype = NULL;
const u_char *sigblob;
u_char *sm = NULL, *m = NULL;
size_t len;
unsigned long long smlen = 0, mlen = 0;
int r, ret;
if (key == NULL ||
sshkey_type_plain(key->type) != KEY_ED25519 ||
key->ed25519_pk == NULL ||
- datalen >= INT_MAX - crypto_sign_ed25519_BYTES ||
- signature == NULL || signaturelen == 0)
+ dlen >= INT_MAX - crypto_sign_ed25519_BYTES ||
+ sig == NULL || siglen == 0)
return SSH_ERR_INVALID_ARGUMENT;
- if ((b = sshbuf_from(signature, signaturelen)) == NULL)
+ if ((b = sshbuf_from(sig, siglen)) == NULL)
return SSH_ERR_ALLOC_FAIL;
if ((r = sshbuf_get_cstring(b, &ktype, NULL)) != 0 ||
(r = sshbuf_get_string_direct(b, &sigblob, &len)) != 0)
goto out;
if (strcmp("ssh-ed25519", ktype) != 0) {
r = SSH_ERR_KEY_TYPE_MISMATCH;
goto out;
}
if (sshbuf_len(b) != 0) {
r = SSH_ERR_UNEXPECTED_TRAILING_DATA;
goto out;
}
if (len > crypto_sign_ed25519_BYTES) {
r = SSH_ERR_INVALID_FORMAT;
goto out;
}
- if (datalen >= SIZE_MAX - len) {
+ if (dlen >= SIZE_MAX - len) {
r = SSH_ERR_INVALID_ARGUMENT;
goto out;
}
- smlen = len + datalen;
+ smlen = len + dlen;
mlen = smlen;
if ((sm = malloc(smlen)) == NULL || (m = malloc(mlen)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
memcpy(sm, sigblob, len);
- memcpy(sm+len, data, datalen);
+ memcpy(sm+len, data, dlen);
if ((ret = crypto_sign_ed25519_open(m, &mlen, sm, smlen,
key->ed25519_pk)) != 0) {
debug2_f("crypto_sign_ed25519_open failed: %d", ret);
}
- if (ret != 0 || mlen != datalen) {
+ if (ret != 0 || mlen != dlen) {
r = SSH_ERR_SIGNATURE_INVALID;
goto out;
}
/* XXX compare 'm' and 'data' ? */
/* success */
r = 0;
out:
if (sm != NULL)
freezero(sm, smlen);
if (m != NULL)
freezero(m, smlen); /* NB mlen may be invalid if r != 0 */
sshbuf_free(b);
free(ktype);
return r;
}
+
+/* NB. not static; used by ED25519-SK */
+const struct sshkey_impl_funcs sshkey_ed25519_funcs = {
+ /* .size = */ NULL,
+ /* .alloc = */ NULL,
+ /* .cleanup = */ ssh_ed25519_cleanup,
+ /* .equal = */ ssh_ed25519_equal,
+ /* .ssh_serialize_public = */ ssh_ed25519_serialize_public,
+ /* .ssh_deserialize_public = */ ssh_ed25519_deserialize_public,
+ /* .ssh_serialize_private = */ ssh_ed25519_serialize_private,
+ /* .ssh_deserialize_private = */ ssh_ed25519_deserialize_private,
+ /* .generate = */ ssh_ed25519_generate,
+ /* .copy_public = */ ssh_ed25519_copy_public,
+ /* .sign = */ ssh_ed25519_sign,
+ /* .verify = */ ssh_ed25519_verify,
+};
+
+const struct sshkey_impl sshkey_ed25519_impl = {
+ /* .name = */ "ssh-ed25519",
+ /* .shortname = */ "ED25519",
+ /* .sigalg = */ NULL,
+ /* .type = */ KEY_ED25519,
+ /* .nid = */ 0,
+ /* .cert = */ 0,
+ /* .sigonly = */ 0,
+ /* .keybits = */ 256,
+ /* .funcs = */ &sshkey_ed25519_funcs,
+};
+
+const struct sshkey_impl sshkey_ed25519_cert_impl = {
+ /* .name = */ "ssh-ed25519-cert-v01@openssh.com",
+ /* .shortname = */ "ED25519-CERT",
+ /* .sigalg = */ NULL,
+ /* .type = */ KEY_ED25519_CERT,
+ /* .nid = */ 0,
+ /* .cert = */ 1,
+ /* .sigonly = */ 0,
+ /* .keybits = */ 256,
+ /* .funcs = */ &sshkey_ed25519_funcs,
+};
diff --git a/crypto/openssh/ssh-keygen.c b/crypto/openssh/ssh-keygen.c
index 1255957d0e67..ae05440f68bf 100644
--- a/crypto/openssh/ssh-keygen.c
+++ b/crypto/openssh/ssh-keygen.c
@@ -1,3932 +1,3931 @@
-/* $OpenBSD: ssh-keygen.c,v 1.459 2022/08/11 01:56:51 djm Exp $ */
+/* $OpenBSD: ssh-keygen.c,v 1.461 2022/12/04 23:50:49 cheloha Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
* Identity and host key generation and maintenance.
*
* As far as I am concerned, the code I have written for this software
* can be used freely for any purpose. Any derived versions of this
* software must be clearly marked as such, and if the derived work is
* incompatible with the protocol description in the RFC file, it must be
* called by a name other than "ssh" or "Secure Shell".
*/
#include "includes.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#ifdef WITH_OPENSSL
#include <openssl/evp.h>
#include <openssl/pem.h>
#include "openbsd-compat/openssl-compat.h"
#endif
#ifdef HAVE_STDINT_H
# include <stdint.h>
#endif
#include <errno.h>
#include <fcntl.h>
#include <netdb.h>
#ifdef HAVE_PATHS_H
# include <paths.h>
#endif
#include <pwd.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <limits.h>
#include <locale.h>
#include <time.h>
#include "xmalloc.h"
#include "sshkey.h"
#include "authfile.h"
#include "sshbuf.h"
#include "pathnames.h"
#include "log.h"
#include "misc.h"
#include "match.h"
#include "hostfile.h"
#include "dns.h"
#include "ssh.h"
#include "ssh2.h"
#include "ssherr.h"
#include "ssh-pkcs11.h"
#include "atomicio.h"
#include "krl.h"
#include "digest.h"
#include "utf8.h"
#include "authfd.h"
#include "sshsig.h"
#include "ssh-sk.h"
#include "sk-api.h" /* XXX for SSH_SK_USER_PRESENCE_REQD; remove */
#include "cipher.h"
#ifdef WITH_OPENSSL
# define DEFAULT_KEY_TYPE_NAME "rsa"
#else
# define DEFAULT_KEY_TYPE_NAME "ed25519"
#endif
/*
* Default number of bits in the RSA, DSA and ECDSA keys. These value can be
* overridden on the command line.
*
* These values, with the exception of DSA, provide security equivalent to at
* least 128 bits of security according to NIST Special Publication 800-57:
* Recommendation for Key Management Part 1 rev 4 section 5.6.1.
* For DSA it (and FIPS-186-4 section 4.2) specifies that the only size for
* which a 160bit hash is acceptable is 1kbit, and since ssh-dss specifies only
* SHA1 we limit the DSA key size 1k bits.
*/
#define DEFAULT_BITS 3072
#define DEFAULT_BITS_DSA 1024
#define DEFAULT_BITS_ECDSA 256
static int quiet = 0;
/* Flag indicating that we just want to see the key fingerprint */
static int print_fingerprint = 0;
static int print_bubblebabble = 0;
/* Hash algorithm to use for fingerprints. */
static int fingerprint_hash = SSH_FP_HASH_DEFAULT;
/* The identity file name, given on the command line or entered by the user. */
static char identity_file[PATH_MAX];
static int have_identity = 0;
/* This is set to the passphrase if given on the command line. */
static char *identity_passphrase = NULL;
/* This is set to the new passphrase if given on the command line. */
static char *identity_new_passphrase = NULL;
/* Key type when certifying */
static u_int cert_key_type = SSH2_CERT_TYPE_USER;
/* "key ID" of signed key */
static char *cert_key_id = NULL;
/* Comma-separated list of principal names for certifying keys */
static char *cert_principals = NULL;
/* Validity period for certificates */
static u_int64_t cert_valid_from = 0;
static u_int64_t cert_valid_to = ~0ULL;
/* Certificate options */
#define CERTOPT_X_FWD (1)
#define CERTOPT_AGENT_FWD (1<<1)
#define CERTOPT_PORT_FWD (1<<2)
#define CERTOPT_PTY (1<<3)
#define CERTOPT_USER_RC (1<<4)
#define CERTOPT_NO_REQUIRE_USER_PRESENCE (1<<5)
#define CERTOPT_REQUIRE_VERIFY (1<<6)
#define CERTOPT_DEFAULT (CERTOPT_X_FWD|CERTOPT_AGENT_FWD| \
CERTOPT_PORT_FWD|CERTOPT_PTY|CERTOPT_USER_RC)
static u_int32_t certflags_flags = CERTOPT_DEFAULT;
static char *certflags_command = NULL;
static char *certflags_src_addr = NULL;
/* Arbitrary extensions specified by user */
struct cert_ext {
char *key;
char *val;
int crit;
};
static struct cert_ext *cert_ext;
static size_t ncert_ext;
/* Conversion to/from various formats */
enum {
FMT_RFC4716,
FMT_PKCS8,
FMT_PEM
} convert_format = FMT_RFC4716;
static char *key_type_name = NULL;
/* Load key from this PKCS#11 provider */
static char *pkcs11provider = NULL;
/* FIDO/U2F provider to use */
static char *sk_provider = NULL;
/* Format for writing private keys */
static int private_key_format = SSHKEY_PRIVATE_OPENSSH;
/* Cipher for new-format private keys */
static char *openssh_format_cipher = NULL;
/* Number of KDF rounds to derive new format keys. */
static int rounds = 0;
/* argv0 */
extern char *__progname;
static char hostname[NI_MAXHOST];
#ifdef WITH_OPENSSL
/* moduli.c */
int gen_candidates(FILE *, u_int32_t, u_int32_t, BIGNUM *);
int prime_test(FILE *, FILE *, u_int32_t, u_int32_t, char *, unsigned long,
unsigned long);
#endif
static void
type_bits_valid(int type, const char *name, u_int32_t *bitsp)
{
if (type == KEY_UNSPEC)
fatal("unknown key type %s", key_type_name);
if (*bitsp == 0) {
#ifdef WITH_OPENSSL
int nid;
switch(type) {
case KEY_DSA:
*bitsp = DEFAULT_BITS_DSA;
break;
case KEY_ECDSA:
if (name != NULL &&
(nid = sshkey_ecdsa_nid_from_name(name)) > 0)
*bitsp = sshkey_curve_nid_to_bits(nid);
if (*bitsp == 0)
*bitsp = DEFAULT_BITS_ECDSA;
break;
case KEY_RSA:
*bitsp = DEFAULT_BITS;
break;
}
#endif
}
#ifdef WITH_OPENSSL
switch (type) {
case KEY_DSA:
if (*bitsp != 1024)
fatal("Invalid DSA key length: must be 1024 bits");
break;
case KEY_RSA:
if (*bitsp < SSH_RSA_MINIMUM_MODULUS_SIZE)
fatal("Invalid RSA key length: minimum is %d bits",
SSH_RSA_MINIMUM_MODULUS_SIZE);
else if (*bitsp > OPENSSL_RSA_MAX_MODULUS_BITS)
fatal("Invalid RSA key length: maximum is %d bits",
OPENSSL_RSA_MAX_MODULUS_BITS);
break;
case KEY_ECDSA:
if (sshkey_ecdsa_bits_to_nid(*bitsp) == -1)
#ifdef OPENSSL_HAS_NISTP521
fatal("Invalid ECDSA key length: valid lengths are "
"256, 384 or 521 bits");
#else
fatal("Invalid ECDSA key length: valid lengths are "
"256 or 384 bits");
#endif
}
#endif
}
/*
* Checks whether a file exists and, if so, asks the user whether they wish
* to overwrite it.
* Returns nonzero if the file does not already exist or if the user agrees to
* overwrite, or zero otherwise.
*/
static int
confirm_overwrite(const char *filename)
{
char yesno[3];
struct stat st;
if (stat(filename, &st) != 0)
return 1;
printf("%s already exists.\n", filename);
printf("Overwrite (y/n)? ");
fflush(stdout);
if (fgets(yesno, sizeof(yesno), stdin) == NULL)
return 0;
if (yesno[0] != 'y' && yesno[0] != 'Y')
return 0;
return 1;
}
static void
ask_filename(struct passwd *pw, const char *prompt)
{
char buf[1024];
char *name = NULL;
if (key_type_name == NULL)
name = _PATH_SSH_CLIENT_ID_RSA;
else {
switch (sshkey_type_from_name(key_type_name)) {
case KEY_DSA_CERT:
case KEY_DSA:
name = _PATH_SSH_CLIENT_ID_DSA;
break;
#ifdef OPENSSL_HAS_ECC
case KEY_ECDSA_CERT:
case KEY_ECDSA:
name = _PATH_SSH_CLIENT_ID_ECDSA;
break;
case KEY_ECDSA_SK_CERT:
case KEY_ECDSA_SK:
name = _PATH_SSH_CLIENT_ID_ECDSA_SK;
break;
#endif
case KEY_RSA_CERT:
case KEY_RSA:
name = _PATH_SSH_CLIENT_ID_RSA;
break;
case KEY_ED25519:
case KEY_ED25519_CERT:
name = _PATH_SSH_CLIENT_ID_ED25519;
break;
case KEY_ED25519_SK:
case KEY_ED25519_SK_CERT:
name = _PATH_SSH_CLIENT_ID_ED25519_SK;
break;
case KEY_XMSS:
case KEY_XMSS_CERT:
name = _PATH_SSH_CLIENT_ID_XMSS;
break;
default:
fatal("bad key type");
}
}
snprintf(identity_file, sizeof(identity_file),
"%s/%s", pw->pw_dir, name);
printf("%s (%s): ", prompt, identity_file);
fflush(stdout);
if (fgets(buf, sizeof(buf), stdin) == NULL)
exit(1);
buf[strcspn(buf, "\n")] = '\0';
if (strcmp(buf, "") != 0)
strlcpy(identity_file, buf, sizeof(identity_file));
have_identity = 1;
}
static struct sshkey *
load_identity(const char *filename, char **commentp)
{
char *pass;
struct sshkey *prv;
int r;
if (commentp != NULL)
*commentp = NULL;
if ((r = sshkey_load_private(filename, "", &prv, commentp)) == 0)
return prv;
if (r != SSH_ERR_KEY_WRONG_PASSPHRASE)
fatal_r(r, "Load key \"%s\"", filename);
if (identity_passphrase)
pass = xstrdup(identity_passphrase);
else
pass = read_passphrase("Enter passphrase: ", RP_ALLOW_STDIN);
r = sshkey_load_private(filename, pass, &prv, commentp);
freezero(pass, strlen(pass));
if (r != 0)
fatal_r(r, "Load key \"%s\"", filename);
return prv;
}
#define SSH_COM_PUBLIC_BEGIN "---- BEGIN SSH2 PUBLIC KEY ----"
#define SSH_COM_PUBLIC_END "---- END SSH2 PUBLIC KEY ----"
#define SSH_COM_PRIVATE_BEGIN "---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----"
#define SSH_COM_PRIVATE_KEY_MAGIC 0x3f6ff9eb
#ifdef WITH_OPENSSL
static void
do_convert_to_ssh2(struct passwd *pw, struct sshkey *k)
{
struct sshbuf *b;
char comment[61], *b64;
int r;
if ((b = sshbuf_new()) == NULL)
fatal_f("sshbuf_new failed");
if ((r = sshkey_putb(k, b)) != 0)
fatal_fr(r, "put key");
if ((b64 = sshbuf_dtob64_string(b, 1)) == NULL)
fatal_f("sshbuf_dtob64_string failed");
/* Comment + surrounds must fit into 72 chars (RFC 4716 sec 3.3) */
snprintf(comment, sizeof(comment),
"%u-bit %s, converted by %s@%s from OpenSSH",
sshkey_size(k), sshkey_type(k),
pw->pw_name, hostname);
sshkey_free(k);
sshbuf_free(b);
fprintf(stdout, "%s\n", SSH_COM_PUBLIC_BEGIN);
fprintf(stdout, "Comment: \"%s\"\n%s", comment, b64);
fprintf(stdout, "%s\n", SSH_COM_PUBLIC_END);
free(b64);
exit(0);
}
static void
do_convert_to_pkcs8(struct sshkey *k)
{
switch (sshkey_type_plain(k->type)) {
case KEY_RSA:
if (!PEM_write_RSA_PUBKEY(stdout, k->rsa))
fatal("PEM_write_RSA_PUBKEY failed");
break;
case KEY_DSA:
if (!PEM_write_DSA_PUBKEY(stdout, k->dsa))
fatal("PEM_write_DSA_PUBKEY failed");
break;
#ifdef OPENSSL_HAS_ECC
case KEY_ECDSA:
if (!PEM_write_EC_PUBKEY(stdout, k->ecdsa))
fatal("PEM_write_EC_PUBKEY failed");
break;
#endif
default:
fatal_f("unsupported key type %s", sshkey_type(k));
}
exit(0);
}
static void
do_convert_to_pem(struct sshkey *k)
{
switch (sshkey_type_plain(k->type)) {
case KEY_RSA:
if (!PEM_write_RSAPublicKey(stdout, k->rsa))
fatal("PEM_write_RSAPublicKey failed");
break;
case KEY_DSA:
if (!PEM_write_DSA_PUBKEY(stdout, k->dsa))
fatal("PEM_write_DSA_PUBKEY failed");
break;
#ifdef OPENSSL_HAS_ECC
case KEY_ECDSA:
if (!PEM_write_EC_PUBKEY(stdout, k->ecdsa))
fatal("PEM_write_EC_PUBKEY failed");
break;
#endif
default:
fatal_f("unsupported key type %s", sshkey_type(k));
}
exit(0);
}
static void
do_convert_to(struct passwd *pw)
{
struct sshkey *k;
struct stat st;
int r;
if (!have_identity)
ask_filename(pw, "Enter file in which the key is");
if (stat(identity_file, &st) == -1)
fatal("%s: %s: %s", __progname, identity_file, strerror(errno));
if ((r = sshkey_load_public(identity_file, &k, NULL)) != 0)
k = load_identity(identity_file, NULL);
switch (convert_format) {
case FMT_RFC4716:
do_convert_to_ssh2(pw, k);
break;
case FMT_PKCS8:
do_convert_to_pkcs8(k);
break;
case FMT_PEM:
do_convert_to_pem(k);
break;
default:
fatal_f("unknown key format %d", convert_format);
}
exit(0);
}
/*
* This is almost exactly the bignum1 encoding, but with 32 bit for length
* instead of 16.
*/
static void
buffer_get_bignum_bits(struct sshbuf *b, BIGNUM *value)
{
u_int bytes, bignum_bits;
int r;
if ((r = sshbuf_get_u32(b, &bignum_bits)) != 0)
fatal_fr(r, "parse");
bytes = (bignum_bits + 7) / 8;
if (sshbuf_len(b) < bytes)
fatal_f("input buffer too small: need %d have %zu",
bytes, sshbuf_len(b));
if (BN_bin2bn(sshbuf_ptr(b), bytes, value) == NULL)
fatal_f("BN_bin2bn failed");
if ((r = sshbuf_consume(b, bytes)) != 0)
fatal_fr(r, "consume");
}
static struct sshkey *
do_convert_private_ssh2(struct sshbuf *b)
{
struct sshkey *key = NULL;
char *type, *cipher;
u_char e1, e2, e3, *sig = NULL, data[] = "abcde12345";
int r, rlen, ktype;
u_int magic, i1, i2, i3, i4;
size_t slen;
u_long e;
BIGNUM *dsa_p = NULL, *dsa_q = NULL, *dsa_g = NULL;
BIGNUM *dsa_pub_key = NULL, *dsa_priv_key = NULL;
BIGNUM *rsa_n = NULL, *rsa_e = NULL, *rsa_d = NULL;
BIGNUM *rsa_p = NULL, *rsa_q = NULL, *rsa_iqmp = NULL;
if ((r = sshbuf_get_u32(b, &magic)) != 0)
fatal_fr(r, "parse magic");
if (magic != SSH_COM_PRIVATE_KEY_MAGIC) {
error("bad magic 0x%x != 0x%x", magic,
SSH_COM_PRIVATE_KEY_MAGIC);
return NULL;
}
if ((r = sshbuf_get_u32(b, &i1)) != 0 ||
(r = sshbuf_get_cstring(b, &type, NULL)) != 0 ||
(r = sshbuf_get_cstring(b, &cipher, NULL)) != 0 ||
(r = sshbuf_get_u32(b, &i2)) != 0 ||
(r = sshbuf_get_u32(b, &i3)) != 0 ||
(r = sshbuf_get_u32(b, &i4)) != 0)
fatal_fr(r, "parse");
debug("ignore (%d %d %d %d)", i1, i2, i3, i4);
if (strcmp(cipher, "none") != 0) {
error("unsupported cipher %s", cipher);
free(cipher);
free(type);
return NULL;
}
free(cipher);
if (strstr(type, "dsa")) {
ktype = KEY_DSA;
} else if (strstr(type, "rsa")) {
ktype = KEY_RSA;
} else {
free(type);
return NULL;
}
if ((key = sshkey_new(ktype)) == NULL)
fatal("sshkey_new failed");
free(type);
switch (key->type) {
case KEY_DSA:
if ((dsa_p = BN_new()) == NULL ||
(dsa_q = BN_new()) == NULL ||
(dsa_g = BN_new()) == NULL ||
(dsa_pub_key = BN_new()) == NULL ||
(dsa_priv_key = BN_new()) == NULL)
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_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_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_fr(r, "parse RSA");
e = e1;
debug("e %lx", e);
if (e < 30) {
e <<= 8;
e += e2;
debug("e %lx", e);
e <<= 8;
e += e3;
debug("e %lx", e);
}
if ((rsa_e = BN_new()) == NULL)
fatal_f("BN_new");
if (!BN_set_word(rsa_e, e)) {
BN_clear_free(rsa_e);
sshkey_free(key);
return NULL;
}
if ((rsa_n = BN_new()) == NULL ||
(rsa_d = BN_new()) == NULL ||
(rsa_p = BN_new()) == NULL ||
(rsa_q = BN_new()) == NULL ||
(rsa_iqmp = BN_new()) == NULL)
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_f("RSA_set0_key failed");
rsa_n = rsa_e = rsa_d = NULL; /* transferred */
if (!RSA_set0_factors(key->rsa, rsa_p, rsa_q))
fatal_f("RSA_set0_factors failed");
rsa_p = rsa_q = NULL; /* transferred */
if ((r = ssh_rsa_complete_crt_parameters(key, rsa_iqmp)) != 0)
fatal_fr(r, "generate RSA parameters");
BN_clear_free(rsa_iqmp);
break;
}
rlen = sshbuf_len(b);
if (rlen != 0)
error_f("remaining bytes in key blob %d", rlen);
/* try the key */
if ((r = sshkey_sign(key, &sig, &slen, data, sizeof(data),
NULL, NULL, NULL, 0)) != 0)
error_fr(r, "signing with converted key failed");
else if ((r = sshkey_verify(key, sig, slen, data, sizeof(data),
NULL, 0, NULL)) != 0)
error_fr(r, "verification with converted key failed");
if (r != 0) {
sshkey_free(key);
free(sig);
return NULL;
}
free(sig);
return key;
}
static int
get_line(FILE *fp, char *line, size_t len)
{
int c;
size_t pos = 0;
line[0] = '\0';
while ((c = fgetc(fp)) != EOF) {
if (pos >= len - 1)
fatal("input line too long.");
switch (c) {
case '\r':
c = fgetc(fp);
if (c != EOF && c != '\n' && ungetc(c, fp) == EOF)
fatal("unget: %s", strerror(errno));
return pos;
case '\n':
return pos;
}
line[pos++] = c;
line[pos] = '\0';
}
/* We reached EOF */
return -1;
}
static void
do_convert_from_ssh2(struct passwd *pw, struct sshkey **k, int *private)
{
int r, blen, escaped = 0;
u_int len;
char line[1024];
struct sshbuf *buf;
char encoded[8096];
FILE *fp;
if ((buf = sshbuf_new()) == NULL)
fatal("sshbuf_new failed");
if ((fp = fopen(identity_file, "r")) == NULL)
fatal("%s: %s: %s", __progname, identity_file, strerror(errno));
encoded[0] = '\0';
while ((blen = get_line(fp, line, sizeof(line))) != -1) {
if (blen > 0 && line[blen - 1] == '\\')
escaped++;
if (strncmp(line, "----", 4) == 0 ||
strstr(line, ": ") != NULL) {
if (strstr(line, SSH_COM_PRIVATE_BEGIN) != NULL)
*private = 1;
if (strstr(line, " END ") != NULL) {
break;
}
/* fprintf(stderr, "ignore: %s", line); */
continue;
}
if (escaped) {
escaped--;
/* fprintf(stderr, "escaped: %s", line); */
continue;
}
strlcat(encoded, line, sizeof(encoded));
}
len = strlen(encoded);
if (((len % 4) == 3) &&
(encoded[len-1] == '=') &&
(encoded[len-2] == '=') &&
(encoded[len-3] == '='))
encoded[len-3] = '\0';
if ((r = sshbuf_b64tod(buf, encoded)) != 0)
fatal_fr(r, "base64 decode");
if (*private) {
if ((*k = do_convert_private_ssh2(buf)) == NULL)
fatal_f("private key conversion failed");
} else if ((r = sshkey_fromb(buf, k)) != 0)
fatal_fr(r, "parse key");
sshbuf_free(buf);
fclose(fp);
}
static void
do_convert_from_pkcs8(struct sshkey **k, int *private)
{
EVP_PKEY *pubkey;
FILE *fp;
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_f("%s is not a recognised public key format",
identity_file);
}
fclose(fp);
switch (EVP_PKEY_base_id(pubkey)) {
case EVP_PKEY_RSA:
if ((*k = sshkey_new(KEY_UNSPEC)) == NULL)
fatal("sshkey_new failed");
(*k)->type = KEY_RSA;
(*k)->rsa = EVP_PKEY_get1_RSA(pubkey);
break;
case EVP_PKEY_DSA:
if ((*k = sshkey_new(KEY_UNSPEC)) == NULL)
fatal("sshkey_new failed");
(*k)->type = KEY_DSA;
(*k)->dsa = EVP_PKEY_get1_DSA(pubkey);
break;
#ifdef OPENSSL_HAS_ECC
case EVP_PKEY_EC:
if ((*k = sshkey_new(KEY_UNSPEC)) == NULL)
fatal("sshkey_new failed");
(*k)->type = KEY_ECDSA;
(*k)->ecdsa = EVP_PKEY_get1_EC_KEY(pubkey);
(*k)->ecdsa_nid = sshkey_ecdsa_key_to_nid((*k)->ecdsa);
break;
#endif
default:
fatal_f("unsupported pubkey type %d",
EVP_PKEY_base_id(pubkey));
}
EVP_PKEY_free(pubkey);
return;
}
static void
do_convert_from_pem(struct sshkey **k, int *private)
{
FILE *fp;
RSA *rsa;
if ((fp = fopen(identity_file, "r")) == NULL)
fatal("%s: %s: %s", __progname, identity_file, strerror(errno));
if ((rsa = PEM_read_RSAPublicKey(fp, NULL, NULL, NULL)) != NULL) {
if ((*k = sshkey_new(KEY_UNSPEC)) == NULL)
fatal("sshkey_new failed");
(*k)->type = KEY_RSA;
(*k)->rsa = rsa;
fclose(fp);
return;
}
fatal_f("unrecognised raw private key format");
}
static void
do_convert_from(struct passwd *pw)
{
struct sshkey *k = NULL;
int r, private = 0, ok = 0;
struct stat st;
if (!have_identity)
ask_filename(pw, "Enter file in which the key is");
if (stat(identity_file, &st) == -1)
fatal("%s: %s: %s", __progname, identity_file, strerror(errno));
switch (convert_format) {
case FMT_RFC4716:
do_convert_from_ssh2(pw, &k, &private);
break;
case FMT_PKCS8:
do_convert_from_pkcs8(&k, &private);
break;
case FMT_PEM:
do_convert_from_pem(&k, &private);
break;
default:
fatal_f("unknown key format %d", convert_format);
}
if (!private) {
if ((r = sshkey_write(k, stdout)) == 0)
ok = 1;
if (ok)
fprintf(stdout, "\n");
} else {
switch (k->type) {
case KEY_DSA:
ok = PEM_write_DSAPrivateKey(stdout, k->dsa, NULL,
NULL, 0, NULL, NULL);
break;
#ifdef OPENSSL_HAS_ECC
case KEY_ECDSA:
ok = PEM_write_ECPrivateKey(stdout, k->ecdsa, NULL,
NULL, 0, NULL, NULL);
break;
#endif
case KEY_RSA:
ok = PEM_write_RSAPrivateKey(stdout, k->rsa, NULL,
NULL, 0, NULL, NULL);
break;
default:
fatal_f("unsupported key type %s", sshkey_type(k));
}
}
if (!ok)
fatal("key write failed");
sshkey_free(k);
exit(0);
}
#endif
static void
do_print_public(struct passwd *pw)
{
struct sshkey *prv;
struct stat st;
int r;
char *comment = NULL;
if (!have_identity)
ask_filename(pw, "Enter file in which the key is");
if (stat(identity_file, &st) == -1)
fatal("%s: %s", identity_file, strerror(errno));
prv = load_identity(identity_file, &comment);
if ((r = sshkey_write(prv, stdout)) != 0)
fatal_fr(r, "write key");
if (comment != NULL && *comment != '\0')
fprintf(stdout, " %s", comment);
fprintf(stdout, "\n");
if (sshkey_is_sk(prv)) {
debug("sk_application: \"%s\", sk_flags 0x%02x",
prv->sk_application, prv->sk_flags);
}
sshkey_free(prv);
free(comment);
exit(0);
}
static void
do_download(struct passwd *pw)
{
#ifdef ENABLE_PKCS11
struct sshkey **keys = NULL;
int i, nkeys;
enum sshkey_fp_rep rep;
int fptype;
char *fp, *ra, **comments = NULL;
fptype = print_bubblebabble ? SSH_DIGEST_SHA1 : fingerprint_hash;
rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_DEFAULT;
pkcs11_init(1);
nkeys = pkcs11_add_provider(pkcs11provider, NULL, &keys, &comments);
if (nkeys <= 0)
fatal("cannot read public key from pkcs11");
for (i = 0; i < nkeys; i++) {
if (print_fingerprint) {
fp = sshkey_fingerprint(keys[i], fptype, rep);
ra = sshkey_fingerprint(keys[i], fingerprint_hash,
SSH_FP_RANDOMART);
if (fp == NULL || ra == NULL)
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)
printf("%s\n", ra);
free(ra);
free(fp);
} else {
(void) sshkey_write(keys[i], stdout); /* XXX check */
fprintf(stdout, "%s%s\n",
*(comments[i]) == '\0' ? "" : " ", comments[i]);
}
free(comments[i]);
sshkey_free(keys[i]);
}
free(comments);
free(keys);
pkcs11_terminate();
exit(0);
#else
fatal("no pkcs11 support");
#endif /* ENABLE_PKCS11 */
}
static struct sshkey *
try_read_key(char **cpp)
{
struct sshkey *ret;
int r;
if ((ret = sshkey_new(KEY_UNSPEC)) == NULL)
fatal("sshkey_new failed");
if ((r = sshkey_read(ret, cpp)) == 0)
return ret;
/* Not a key */
sshkey_free(ret);
return NULL;
}
static void
fingerprint_one_key(const struct sshkey *public, const char *comment)
{
char *fp = NULL, *ra = NULL;
enum sshkey_fp_rep rep;
int fptype;
fptype = print_bubblebabble ? SSH_DIGEST_SHA1 : fingerprint_hash;
rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_DEFAULT;
fp = sshkey_fingerprint(public, fptype, rep);
ra = sshkey_fingerprint(public, fingerprint_hash, SSH_FP_RANDOMART);
if (fp == NULL || ra == NULL)
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)
printf("%s\n", ra);
free(ra);
free(fp);
}
static void
fingerprint_private(const char *path)
{
struct stat st;
char *comment = NULL;
struct sshkey *privkey = NULL, *pubkey = NULL;
int r;
if (stat(identity_file, &st) == -1)
fatal("%s: %s", path, strerror(errno));
if ((r = sshkey_load_public(path, &pubkey, &comment)) != 0)
debug_r(r, "load public \"%s\"", path);
if (pubkey == NULL || comment == NULL || *comment == '\0') {
free(comment);
if ((r = sshkey_load_private(path, NULL,
&privkey, &comment)) != 0)
debug_r(r, "load private \"%s\"", path);
}
if (pubkey == NULL && privkey == NULL)
fatal("%s is not a key file.", path);
fingerprint_one_key(pubkey == NULL ? privkey : pubkey, comment);
sshkey_free(pubkey);
sshkey_free(privkey);
free(comment);
}
static void
do_fingerprint(struct passwd *pw)
{
FILE *f;
struct sshkey *public = NULL;
char *comment = NULL, *cp, *ep, *line = NULL;
size_t linesize = 0;
int i, invalid = 1;
const char *path;
u_long lnum = 0;
if (!have_identity)
ask_filename(pw, "Enter file in which the key is");
path = identity_file;
if (strcmp(identity_file, "-") == 0) {
f = stdin;
path = "(stdin)";
} else if ((f = fopen(path, "r")) == NULL)
fatal("%s: %s: %s", __progname, path, strerror(errno));
while (getline(&line, &linesize, f) != -1) {
lnum++;
cp = line;
cp[strcspn(cp, "\n")] = '\0';
/* Trim leading space and comments */
cp = line + strspn(line, " \t");
if (*cp == '#' || *cp == '\0')
continue;
/*
* Input may be plain keys, private keys, authorized_keys
* or known_hosts.
*/
/*
* Try private keys first. Assume a key is private if
* "SSH PRIVATE KEY" appears on the first line and we're
* not reading from stdin (XXX support private keys on stdin).
*/
if (lnum == 1 && strcmp(identity_file, "-") != 0 &&
strstr(cp, "PRIVATE KEY") != NULL) {
free(line);
fclose(f);
fingerprint_private(path);
exit(0);
}
/*
* If it's not a private key, then this must be prepared to
* accept a public key prefixed with a hostname or options.
* Try a bare key first, otherwise skip the leading stuff.
*/
if ((public = try_read_key(&cp)) == NULL) {
i = strtol(cp, &ep, 10);
if (i == 0 || ep == NULL ||
(*ep != ' ' && *ep != '\t')) {
int quoted = 0;
comment = cp;
for (; *cp && (quoted || (*cp != ' ' &&
*cp != '\t')); cp++) {
if (*cp == '\\' && cp[1] == '"')
cp++; /* Skip both */
else if (*cp == '"')
quoted = !quoted;
}
if (!*cp)
continue;
*cp++ = '\0';
}
}
/* Retry after parsing leading hostname/key options */
if (public == NULL && (public = try_read_key(&cp)) == NULL) {
debug("%s:%lu: not a public key", path, lnum);
continue;
}
/* Find trailing comment, if any */
for (; *cp == ' ' || *cp == '\t'; cp++)
;
if (*cp != '\0' && *cp != '#')
comment = cp;
fingerprint_one_key(public, comment);
sshkey_free(public);
invalid = 0; /* One good key in the file is sufficient */
}
fclose(f);
free(line);
if (invalid)
fatal("%s is not a public key file.", path);
exit(0);
}
static void
do_gen_all_hostkeys(struct passwd *pw)
{
struct {
char *key_type;
char *key_type_display;
char *path;
} key_types[] = {
#ifdef WITH_OPENSSL
{ "rsa", "RSA" ,_PATH_HOST_RSA_KEY_FILE },
#ifdef OPENSSL_HAS_ECC
{ "ecdsa", "ECDSA",_PATH_HOST_ECDSA_KEY_FILE },
#endif /* OPENSSL_HAS_ECC */
#endif /* WITH_OPENSSL */
{ "ed25519", "ED25519",_PATH_HOST_ED25519_KEY_FILE },
#ifdef WITH_XMSS
{ "xmss", "XMSS",_PATH_HOST_XMSS_KEY_FILE },
#endif /* WITH_XMSS */
{ NULL, NULL, NULL }
};
u_int32_t bits = 0;
int first = 0;
struct stat st;
struct sshkey *private, *public;
char comment[1024], *prv_tmp, *pub_tmp, *prv_file, *pub_file;
int i, type, fd, r;
for (i = 0; key_types[i].key_type; i++) {
public = private = NULL;
prv_tmp = pub_tmp = prv_file = pub_file = NULL;
xasprintf(&prv_file, "%s%s",
identity_file, key_types[i].path);
/* Check whether private key exists and is not zero-length */
if (stat(prv_file, &st) == 0) {
if (st.st_size != 0)
goto next;
} else if (errno != ENOENT) {
error("Could not stat %s: %s", key_types[i].path,
strerror(errno));
goto failnext;
}
/*
* Private key doesn't exist or is invalid; proceed with
* key generation.
*/
xasprintf(&prv_tmp, "%s%s.XXXXXXXXXX",
identity_file, key_types[i].path);
xasprintf(&pub_tmp, "%s%s.pub.XXXXXXXXXX",
identity_file, key_types[i].path);
xasprintf(&pub_file, "%s%s.pub",
identity_file, key_types[i].path);
if (first == 0) {
first = 1;
printf("%s: generating new host keys: ", __progname);
}
printf("%s ", key_types[i].key_type_display);
fflush(stdout);
type = sshkey_type_from_name(key_types[i].key_type);
if ((fd = mkstemp(prv_tmp)) == -1) {
error("Could not save your private key in %s: %s",
prv_tmp, strerror(errno));
goto failnext;
}
(void)close(fd); /* just using mkstemp() to reserve a name */
bits = 0;
type_bits_valid(type, NULL, &bits);
if ((r = sshkey_generate(type, bits, &private)) != 0) {
error_r(r, "sshkey_generate failed");
goto failnext;
}
if ((r = sshkey_from_private(private, &public)) != 0)
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_r(r, "Saving key \"%s\" failed", prv_tmp);
goto failnext;
}
if ((fd = mkstemp(pub_tmp)) == -1) {
error("Could not save your public key in %s: %s",
pub_tmp, strerror(errno));
goto failnext;
}
(void)fchmod(fd, 0644);
(void)close(fd);
if ((r = sshkey_save_public(public, pub_tmp, comment)) != 0) {
error_r(r, "Unable to save public key to %s",
identity_file);
goto failnext;
}
/* Rename temporary files to their permanent locations. */
if (rename(pub_tmp, pub_file) != 0) {
error("Unable to move %s into position: %s",
pub_file, strerror(errno));
goto failnext;
}
if (rename(prv_tmp, prv_file) != 0) {
error("Unable to move %s into position: %s",
key_types[i].path, strerror(errno));
failnext:
first = 0;
goto next;
}
next:
sshkey_free(private);
sshkey_free(public);
free(prv_tmp);
free(pub_tmp);
free(prv_file);
free(pub_file);
}
if (first != 0)
printf("\n");
}
struct known_hosts_ctx {
const char *host; /* Hostname searched for in find/delete case */
FILE *out; /* Output file, stdout for find_hosts case */
int has_unhashed; /* When hashing, original had unhashed hosts */
int found_key; /* For find/delete, host was found */
int invalid; /* File contained invalid items; don't delete */
int hash_hosts; /* Hash hostnames as we go */
int find_host; /* Search for specific hostname */
int delete_host; /* Delete host from known_hosts */
};
static int
known_hosts_hash(struct hostkey_foreach_line *l, void *_ctx)
{
struct known_hosts_ctx *ctx = (struct known_hosts_ctx *)_ctx;
char *hashed, *cp, *hosts, *ohosts;
int has_wild = l->hosts && strcspn(l->hosts, "*?!") != strlen(l->hosts);
int was_hashed = l->hosts && l->hosts[0] == HASH_DELIM;
switch (l->status) {
case HKF_STATUS_OK:
case HKF_STATUS_MATCHED:
/*
* Don't hash hosts already already hashed, with wildcard
* characters or a CA/revocation marker.
*/
if (was_hashed || has_wild || l->marker != MRK_NONE) {
fprintf(ctx->out, "%s\n", l->line);
if (has_wild && !ctx->find_host) {
logit("%s:%lu: ignoring host name "
"with wildcard: %.64s", l->path,
l->linenum, l->hosts);
}
return 0;
}
/*
* Split any comma-separated hostnames from the host list,
* hash and store separately.
*/
ohosts = hosts = xstrdup(l->hosts);
while ((cp = strsep(&hosts, ",")) != NULL && *cp != '\0') {
lowercase(cp);
if ((hashed = host_hash(cp, NULL, 0)) == NULL)
fatal("hash_host failed");
fprintf(ctx->out, "%s %s\n", hashed, l->rawkey);
free(hashed);
ctx->has_unhashed = 1;
}
free(ohosts);
return 0;
case HKF_STATUS_INVALID:
/* Retain invalid lines, but mark file as invalid. */
ctx->invalid = 1;
logit("%s:%lu: invalid line", l->path, l->linenum);
/* FALLTHROUGH */
default:
fprintf(ctx->out, "%s\n", l->line);
return 0;
}
/* NOTREACHED */
return -1;
}
static int
known_hosts_find_delete(struct hostkey_foreach_line *l, void *_ctx)
{
struct known_hosts_ctx *ctx = (struct known_hosts_ctx *)_ctx;
enum sshkey_fp_rep rep;
int fptype;
char *fp = NULL, *ra = NULL;
fptype = print_bubblebabble ? SSH_DIGEST_SHA1 : fingerprint_hash;
rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_DEFAULT;
if (l->status == HKF_STATUS_MATCHED) {
if (ctx->delete_host) {
if (l->marker != MRK_NONE) {
/* Don't remove CA and revocation lines */
fprintf(ctx->out, "%s\n", l->line);
} else {
/*
* Hostname matches and has no CA/revoke
* marker, delete it by *not* writing the
* line to ctx->out.
*/
ctx->found_key = 1;
if (!quiet)
printf("# Host %s found: line %lu\n",
ctx->host, l->linenum);
}
return 0;
} else if (ctx->find_host) {
ctx->found_key = 1;
if (!quiet) {
printf("# Host %s found: line %lu %s\n",
ctx->host,
l->linenum, l->marker == MRK_CA ? "CA" :
(l->marker == MRK_REVOKE ? "REVOKED" : ""));
}
if (ctx->hash_hosts)
known_hosts_hash(l, ctx);
else if (print_fingerprint) {
fp = sshkey_fingerprint(l->key, fptype, rep);
ra = sshkey_fingerprint(l->key,
fingerprint_hash, SSH_FP_RANDOMART);
if (fp == NULL || ra == NULL)
fatal_f("sshkey_fingerprint failed");
mprintf("%s %s %s%s%s\n", ctx->host,
sshkey_type(l->key), fp,
l->comment[0] ? " " : "",
l->comment);
if (log_level_get() >= SYSLOG_LEVEL_VERBOSE)
printf("%s\n", ra);
free(ra);
free(fp);
} else
fprintf(ctx->out, "%s\n", l->line);
return 0;
}
} else if (ctx->delete_host) {
/* Retain non-matching hosts when deleting */
if (l->status == HKF_STATUS_INVALID) {
ctx->invalid = 1;
logit("%s:%lu: invalid line", l->path, l->linenum);
}
fprintf(ctx->out, "%s\n", l->line);
}
return 0;
}
static void
do_known_hosts(struct passwd *pw, const char *name, int find_host,
int delete_host, int hash_hosts)
{
char *cp, tmp[PATH_MAX], old[PATH_MAX];
int r, fd, oerrno, inplace = 0;
struct known_hosts_ctx ctx;
u_int foreach_options;
struct stat sb;
if (!have_identity) {
cp = tilde_expand_filename(_PATH_SSH_USER_HOSTFILE, pw->pw_uid);
if (strlcpy(identity_file, cp, sizeof(identity_file)) >=
sizeof(identity_file))
fatal("Specified known hosts path too long");
free(cp);
have_identity = 1;
}
if (stat(identity_file, &sb) != 0)
fatal("Cannot stat %s: %s", identity_file, strerror(errno));
memset(&ctx, 0, sizeof(ctx));
ctx.out = stdout;
ctx.host = name;
ctx.hash_hosts = hash_hosts;
ctx.find_host = find_host;
ctx.delete_host = delete_host;
/*
* Find hosts goes to stdout, hash and deletions happen in-place
* A corner case is ssh-keygen -HF foo, which should go to stdout
*/
if (!find_host && (hash_hosts || delete_host)) {
if (strlcpy(tmp, identity_file, sizeof(tmp)) >= sizeof(tmp) ||
strlcat(tmp, ".XXXXXXXXXX", sizeof(tmp)) >= sizeof(tmp) ||
strlcpy(old, identity_file, sizeof(old)) >= sizeof(old) ||
strlcat(old, ".old", sizeof(old)) >= sizeof(old))
fatal("known_hosts path too long");
umask(077);
if ((fd = mkstemp(tmp)) == -1)
fatal("mkstemp: %s", strerror(errno));
if ((ctx.out = fdopen(fd, "w")) == NULL) {
oerrno = errno;
unlink(tmp);
fatal("fdopen: %s", strerror(oerrno));
}
fchmod(fd, sb.st_mode & 0644);
inplace = 1;
}
/* XXX support identity_file == "-" for stdin */
foreach_options = find_host ? HKF_WANT_MATCH : 0;
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)) != 0) {
if (inplace)
unlink(tmp);
fatal_fr(r, "hostkeys_foreach");
}
if (inplace)
fclose(ctx.out);
if (ctx.invalid) {
error("%s is not a valid known_hosts file.", identity_file);
if (inplace) {
error("Not replacing existing known_hosts "
"file because of errors");
unlink(tmp);
}
exit(1);
} else if (delete_host && !ctx.found_key) {
logit("Host %s not found in %s", name, identity_file);
if (inplace)
unlink(tmp);
} else if (inplace) {
/* Backup existing file */
if (unlink(old) == -1 && errno != ENOENT)
fatal("unlink %.100s: %s", old, strerror(errno));
if (link(identity_file, old) == -1)
fatal("link %.100s to %.100s: %s", identity_file, old,
strerror(errno));
/* Move new one into place */
if (rename(tmp, identity_file) == -1) {
error("rename\"%s\" to \"%s\": %s", tmp, identity_file,
strerror(errno));
unlink(tmp);
unlink(old);
exit(1);
}
printf("%s updated.\n", identity_file);
printf("Original contents retained as %s\n", old);
if (ctx.has_unhashed) {
logit("WARNING: %s contains unhashed entries", old);
logit("Delete this file to ensure privacy "
"of hostnames");
}
}
exit (find_host && !ctx.found_key);
}
/*
* Perform changing a passphrase. The argument is the passwd structure
* for the current user.
*/
static void
do_change_passphrase(struct passwd *pw)
{
char *comment;
char *old_passphrase, *passphrase1, *passphrase2;
struct stat st;
struct sshkey *private;
int r;
if (!have_identity)
ask_filename(pw, "Enter file in which the key is");
if (stat(identity_file, &st) == -1)
fatal("%s: %s", identity_file, strerror(errno));
/* Try to load the file with empty passphrase. */
r = sshkey_load_private(identity_file, "", &private, &comment);
if (r == SSH_ERR_KEY_WRONG_PASSPHRASE) {
if (identity_passphrase)
old_passphrase = xstrdup(identity_passphrase);
else
old_passphrase =
read_passphrase("Enter old passphrase: ",
RP_ALLOW_STDIN);
r = sshkey_load_private(identity_file, old_passphrase,
&private, &comment);
freezero(old_passphrase, strlen(old_passphrase));
if (r != 0)
goto badkey;
} else if (r != 0) {
badkey:
fatal_r(r, "Failed to load key %s", identity_file);
}
if (comment)
mprintf("Key has comment '%s'\n", comment);
/* Ask the new passphrase (twice). */
if (identity_new_passphrase) {
passphrase1 = xstrdup(identity_new_passphrase);
passphrase2 = NULL;
} else {
passphrase1 =
read_passphrase("Enter new passphrase (empty for no "
"passphrase): ", RP_ALLOW_STDIN);
passphrase2 = read_passphrase("Enter same passphrase again: ",
RP_ALLOW_STDIN);
/* Verify that they are the same. */
if (strcmp(passphrase1, passphrase2) != 0) {
explicit_bzero(passphrase1, strlen(passphrase1));
explicit_bzero(passphrase2, strlen(passphrase2));
free(passphrase1);
free(passphrase2);
printf("Pass phrases do not match. Try again.\n");
exit(1);
}
/* Destroy the other copy. */
freezero(passphrase2, strlen(passphrase2));
}
/* 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_r(r, "Saving key \"%s\" failed", identity_file);
freezero(passphrase1, strlen(passphrase1));
sshkey_free(private);
free(comment);
exit(1);
}
/* Destroy the passphrase and the copy of the key in memory. */
freezero(passphrase1, strlen(passphrase1));
sshkey_free(private); /* Destroys contents */
free(comment);
printf("Your identification has been saved with the new passphrase.\n");
exit(0);
}
/*
* Print the SSHFP RR.
*/
static int
do_print_resource_record(struct passwd *pw, char *fname, char *hname,
int print_generic)
{
struct sshkey *public;
char *comment = NULL;
struct stat st;
int r;
if (fname == NULL)
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_r(r, "Failed to read v2 public key from \"%s\"", fname);
export_dns_rr(hname, public, stdout, print_generic);
sshkey_free(public);
free(comment);
return 1;
}
/*
* Change the comment of a private key file.
*/
static void
do_change_comment(struct passwd *pw, const char *identity_comment)
{
char new_comment[1024], *comment, *passphrase;
struct sshkey *private;
struct sshkey *public;
struct stat st;
int r;
if (!have_identity)
ask_filename(pw, "Enter file in which the key is");
if (stat(identity_file, &st) == -1)
fatal("%s: %s", identity_file, strerror(errno));
if ((r = sshkey_load_private(identity_file, "",
&private, &comment)) == 0)
passphrase = xstrdup("");
else if (r != SSH_ERR_KEY_WRONG_PASSPHRASE)
fatal_r(r, "Cannot load private key \"%s\"", identity_file);
else {
if (identity_passphrase)
passphrase = xstrdup(identity_passphrase);
else if (identity_new_passphrase)
passphrase = xstrdup(identity_new_passphrase);
else
passphrase = read_passphrase("Enter passphrase: ",
RP_ALLOW_STDIN);
/* Try to load using the passphrase. */
if ((r = sshkey_load_private(identity_file, passphrase,
&private, &comment)) != 0) {
freezero(passphrase, strlen(passphrase));
fatal_r(r, "Cannot load private key \"%s\"",
identity_file);
}
}
if (private->type != KEY_ED25519 && private->type != KEY_XMSS &&
private_key_format != SSHKEY_PRIVATE_OPENSSH) {
error("Comments are only supported for keys stored in "
"the new format (-o).");
explicit_bzero(passphrase, strlen(passphrase));
sshkey_free(private);
exit(1);
}
if (comment)
printf("Old comment: %s\n", comment);
else
printf("No existing comment\n");
if (identity_comment) {
strlcpy(new_comment, identity_comment, sizeof(new_comment));
} else {
printf("New comment: ");
fflush(stdout);
if (!fgets(new_comment, sizeof(new_comment), stdin)) {
explicit_bzero(passphrase, strlen(passphrase));
sshkey_free(private);
exit(1);
}
new_comment[strcspn(new_comment, "\n")] = '\0';
}
if (comment != NULL && strcmp(comment, new_comment) == 0) {
printf("No change to comment\n");
free(passphrase);
sshkey_free(private);
free(comment);
exit(0);
}
/* Save the file using the new passphrase. */
if ((r = sshkey_save_private(private, identity_file, passphrase,
new_comment, private_key_format, openssh_format_cipher,
rounds)) != 0) {
error_r(r, "Saving key \"%s\" failed", identity_file);
freezero(passphrase, strlen(passphrase));
sshkey_free(private);
free(comment);
exit(1);
}
freezero(passphrase, strlen(passphrase));
if ((r = sshkey_from_private(private, &public)) != 0)
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_r(r, "Unable to save public key to %s", identity_file);
sshkey_free(public);
free(comment);
if (strlen(new_comment) > 0)
printf("Comment '%s' applied\n", new_comment);
else
printf("Comment removed\n");
exit(0);
}
static void
cert_ext_add(const char *key, const char *value, int iscrit)
{
cert_ext = xreallocarray(cert_ext, ncert_ext + 1, sizeof(*cert_ext));
cert_ext[ncert_ext].key = xstrdup(key);
cert_ext[ncert_ext].val = value == NULL ? NULL : xstrdup(value);
cert_ext[ncert_ext].crit = iscrit;
ncert_ext++;
}
/* qsort(3) comparison function for certificate extensions */
static int
cert_ext_cmp(const void *_a, const void *_b)
{
const struct cert_ext *a = (const struct cert_ext *)_a;
const struct cert_ext *b = (const struct cert_ext *)_b;
int r;
if (a->crit != b->crit)
return (a->crit < b->crit) ? -1 : 1;
if ((r = strcmp(a->key, b->key)) != 0)
return r;
if ((a->val == NULL) != (b->val == NULL))
return (a->val == NULL) ? -1 : 1;
if (a->val != NULL && (r = strcmp(a->val, b->val)) != 0)
return r;
return 0;
}
#define OPTIONS_CRITICAL 1
#define OPTIONS_EXTENSIONS 2
static void
prepare_options_buf(struct sshbuf *c, int which)
{
struct sshbuf *b;
size_t i;
int r;
const struct cert_ext *ext;
if ((b = sshbuf_new()) == NULL)
fatal_f("sshbuf_new failed");
sshbuf_reset(c);
for (i = 0; i < ncert_ext; i++) {
ext = &cert_ext[i];
if ((ext->crit && (which & OPTIONS_EXTENSIONS)) ||
(!ext->crit && (which & OPTIONS_CRITICAL)))
continue;
if (ext->val == NULL) {
/* flag option */
debug3_f("%s", ext->key);
if ((r = sshbuf_put_cstring(c, ext->key)) != 0 ||
(r = sshbuf_put_string(c, NULL, 0)) != 0)
fatal_fr(r, "prepare flag");
} else {
/* key/value option */
debug3_f("%s=%s", ext->key, ext->val);
sshbuf_reset(b);
if ((r = sshbuf_put_cstring(c, ext->key)) != 0 ||
(r = sshbuf_put_cstring(b, ext->val)) != 0 ||
(r = sshbuf_put_stringb(c, b)) != 0)
fatal_fr(r, "prepare k/v");
}
}
sshbuf_free(b);
}
static void
finalise_cert_exts(void)
{
/* critical options */
if (certflags_command != NULL)
cert_ext_add("force-command", certflags_command, 1);
if (certflags_src_addr != NULL)
cert_ext_add("source-address", certflags_src_addr, 1);
if ((certflags_flags & CERTOPT_REQUIRE_VERIFY) != 0)
cert_ext_add("verify-required", NULL, 1);
/* extensions */
if ((certflags_flags & CERTOPT_X_FWD) != 0)
cert_ext_add("permit-X11-forwarding", NULL, 0);
if ((certflags_flags & CERTOPT_AGENT_FWD) != 0)
cert_ext_add("permit-agent-forwarding", NULL, 0);
if ((certflags_flags & CERTOPT_PORT_FWD) != 0)
cert_ext_add("permit-port-forwarding", NULL, 0);
if ((certflags_flags & CERTOPT_PTY) != 0)
cert_ext_add("permit-pty", NULL, 0);
if ((certflags_flags & CERTOPT_USER_RC) != 0)
cert_ext_add("permit-user-rc", NULL, 0);
if ((certflags_flags & CERTOPT_NO_REQUIRE_USER_PRESENCE) != 0)
cert_ext_add("no-touch-required", NULL, 0);
/* order lexically by key */
if (ncert_ext > 0)
qsort(cert_ext, ncert_ext, sizeof(*cert_ext), cert_ext_cmp);
}
static struct sshkey *
load_pkcs11_key(char *path)
{
#ifdef ENABLE_PKCS11
struct sshkey **keys = NULL, *public, *private = NULL;
int r, i, nkeys;
if ((r = sshkey_load_public(path, &public, NULL)) != 0)
fatal_r(r, "Couldn't load CA public key \"%s\"", path);
nkeys = pkcs11_add_provider(pkcs11provider, identity_passphrase,
&keys, NULL);
debug3_f("%d keys", nkeys);
if (nkeys <= 0)
fatal("cannot read public key from pkcs11");
for (i = 0; i < nkeys; i++) {
if (sshkey_equal_public(public, keys[i])) {
private = keys[i];
continue;
}
sshkey_free(keys[i]);
}
free(keys);
sshkey_free(public);
return private;
#else
fatal("no pkcs11 support");
#endif /* ENABLE_PKCS11 */
}
/* Signer for sshkey_certify_custom that uses the agent */
static int
agent_signer(struct sshkey *key, u_char **sigp, size_t *lenp,
const u_char *data, size_t datalen,
const char *alg, const char *provider, const char *pin,
u_int compat, void *ctx)
{
int *agent_fdp = (int *)ctx;
return ssh_agent_sign(*agent_fdp, key, sigp, lenp,
data, datalen, alg, compat);
}
static void
do_ca_sign(struct passwd *pw, const char *ca_key_path, int prefer_agent,
unsigned long long cert_serial, int cert_serial_autoinc,
int argc, char **argv)
{
int r, i, found, agent_fd = -1;
u_int n;
struct sshkey *ca, *public;
char valid[64], *otmp, *tmp, *cp, *out, *comment;
char *ca_fp = NULL, **plist = NULL, *pin = NULL;
struct ssh_identitylist *agent_ids;
size_t j;
struct notifier_ctx *notifier = NULL;
#ifdef ENABLE_PKCS11
pkcs11_init(1);
#endif
tmp = tilde_expand_filename(ca_key_path, pw->pw_uid);
if (pkcs11provider != NULL) {
/* If a PKCS#11 token was specified then try to use it */
if ((ca = load_pkcs11_key(tmp)) == NULL)
fatal("No PKCS#11 key matching %s found", ca_key_path);
} else if (prefer_agent) {
/*
* Agent signature requested. Try to use agent after making
* sure the public key specified is actually present in the
* agent.
*/
if ((r = sshkey_load_public(tmp, &ca, NULL)) != 0)
fatal_r(r, "Cannot load CA public key %s", tmp);
if ((r = ssh_get_authentication_socket(&agent_fd)) != 0)
fatal_r(r, "Cannot use public key for CA signature");
if ((r = ssh_fetch_identitylist(agent_fd, &agent_ids)) != 0)
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])) {
found = 1;
break;
}
}
if (!found)
fatal("CA key %s not found in agent", tmp);
ssh_free_identitylist(agent_ids);
ca->flags |= SSHKEY_FLAG_EXT;
} else {
/* CA key is assumed to be a private key on the filesystem */
ca = load_identity(tmp, NULL);
if (sshkey_is_sk(ca) &&
(ca->sk_flags & SSH_SK_USER_VERIFICATION_REQD)) {
if ((pin = read_passphrase("Enter PIN for CA key: ",
RP_ALLOW_STDIN)) == NULL)
fatal_f("couldn't read PIN");
}
}
free(tmp);
if (key_type_name != NULL) {
if (sshkey_type_from_name(key_type_name) != ca->type) {
fatal("CA key type %s doesn't match specified %s",
sshkey_ssh_name(ca), key_type_name);
}
} else if (ca->type == KEY_RSA) {
/* Default to a good signature algorithm */
key_type_name = "rsa-sha2-512";
}
ca_fp = sshkey_fingerprint(ca, fingerprint_hash, SSH_FP_DEFAULT);
finalise_cert_exts();
for (i = 0; i < argc; i++) {
/* Split list of principals */
n = 0;
if (cert_principals != NULL) {
otmp = tmp = xstrdup(cert_principals);
plist = NULL;
for (; (cp = strsep(&tmp, ",")) != NULL; n++) {
plist = xreallocarray(plist, n + 1, sizeof(*plist));
if (*(plist[n] = xstrdup(cp)) == '\0')
fatal("Empty principal name");
}
free(otmp);
}
if (n > SSHKEY_CERT_MAX_PRINCIPALS)
fatal("Too many certificate principals specified");
tmp = tilde_expand_filename(argv[i], pw->pw_uid);
if ((r = sshkey_load_public(tmp, &public, &comment)) != 0)
fatal_r(r, "load pubkey \"%s\"", tmp);
if (sshkey_is_cert(public))
fatal_f("key \"%s\" type %s cannot be certified",
tmp, sshkey_type(public));
/* Prepare certificate to sign */
if ((r = sshkey_to_certified(public)) != 0)
fatal_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);
public->cert->nprincipals = n;
public->cert->principals = plist;
public->cert->valid_after = cert_valid_from;
public->cert->valid_before = cert_valid_to;
prepare_options_buf(public->cert->critical, OPTIONS_CRITICAL);
prepare_options_buf(public->cert->extensions,
OPTIONS_EXTENSIONS);
if ((r = sshkey_from_private(ca,
&public->cert->signature_key)) != 0)
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_r(r, "Couldn't certify %s via agent", tmp);
} else {
if (sshkey_is_sk(ca) &&
(ca->sk_flags & SSH_SK_USER_PRESENCE_REQD)) {
notifier = notify_start(0,
"Confirm user presence for key %s %s",
sshkey_type(ca), ca_fp);
}
r = sshkey_certify(public, ca, key_type_name,
sk_provider, pin);
notify_complete(notifier, "User presence confirmed");
if (r != 0)
fatal_r(r, "Couldn't certify key %s", tmp);
}
if ((cp = strrchr(tmp, '.')) != NULL && strcmp(cp, ".pub") == 0)
*cp = '\0';
xasprintf(&out, "%s-cert.pub", tmp);
free(tmp);
if ((r = sshkey_save_public(public, out, comment)) != 0) {
fatal_r(r, "Unable to save public key to %s",
identity_file);
}
if (!quiet) {
sshkey_format_cert_validity(public->cert,
valid, sizeof(valid));
logit("Signed %s key %s: id \"%s\" serial %llu%s%s "
"valid %s", sshkey_cert_type(public),
out, public->cert->key_id,
(unsigned long long)public->cert->serial,
cert_principals != NULL ? " for " : "",
cert_principals != NULL ? cert_principals : "",
valid);
}
sshkey_free(public);
free(out);
if (cert_serial_autoinc)
cert_serial++;
}
if (pin != NULL)
freezero(pin, strlen(pin));
free(ca_fp);
#ifdef ENABLE_PKCS11
pkcs11_terminate();
#endif
exit(0);
}
static u_int64_t
parse_relative_time(const char *s, time_t now)
{
int64_t mul, secs;
mul = *s == '-' ? -1 : 1;
if ((secs = convtime(s + 1)) == -1)
fatal("Invalid relative certificate time %s", s);
if (mul == -1 && secs > now)
fatal("Certificate time %s cannot be represented", s);
return now + (u_int64_t)(secs * mul);
}
static void
parse_hex_u64(const char *s, uint64_t *up)
{
char *ep;
unsigned long long ull;
errno = 0;
ull = strtoull(s, &ep, 16);
if (*s == '\0' || *ep != '\0')
fatal("Invalid certificate time: not a number");
if (errno == ERANGE && ull == ULONG_MAX)
fatal_fr(SSH_ERR_SYSTEM_ERROR, "Invalid certificate time");
*up = (uint64_t)ull;
}
static void
parse_cert_times(char *timespec)
{
char *from, *to;
time_t now = time(NULL);
int64_t secs;
/* +timespec relative to now */
if (*timespec == '+' && strchr(timespec, ':') == NULL) {
if ((secs = convtime(timespec + 1)) == -1)
fatal("Invalid relative certificate life %s", timespec);
cert_valid_to = now + secs;
/*
* Backdate certificate one minute to avoid problems on hosts
* with poorly-synchronised clocks.
*/
cert_valid_from = ((now - 59)/ 60) * 60;
return;
}
/*
* from:to, where
* from := [+-]timespec | YYYYMMDD | YYYYMMDDHHMMSS | 0x... | "always"
* to := [+-]timespec | YYYYMMDD | YYYYMMDDHHMMSS | 0x... | "forever"
*/
from = xstrdup(timespec);
to = strchr(from, ':');
if (to == NULL || from == to || *(to + 1) == '\0')
fatal("Invalid certificate life specification %s", timespec);
*to++ = '\0';
if (*from == '-' || *from == '+')
cert_valid_from = parse_relative_time(from, now);
else if (strcmp(from, "always") == 0)
cert_valid_from = 0;
else if (strncmp(from, "0x", 2) == 0)
parse_hex_u64(from, &cert_valid_from);
else if (parse_absolute_time(from, &cert_valid_from) != 0)
fatal("Invalid from time \"%s\"", from);
if (*to == '-' || *to == '+')
cert_valid_to = parse_relative_time(to, now);
else if (strcmp(to, "forever") == 0)
cert_valid_to = ~(u_int64_t)0;
else if (strncmp(to, "0x", 2) == 0)
parse_hex_u64(to, &cert_valid_to);
else if (parse_absolute_time(to, &cert_valid_to) != 0)
fatal("Invalid to time \"%s\"", to);
if (cert_valid_to <= cert_valid_from)
fatal("Empty certificate validity interval");
free(from);
}
static void
add_cert_option(char *opt)
{
char *val, *cp;
int iscrit = 0;
if (strcasecmp(opt, "clear") == 0)
certflags_flags = 0;
else if (strcasecmp(opt, "no-x11-forwarding") == 0)
certflags_flags &= ~CERTOPT_X_FWD;
else if (strcasecmp(opt, "permit-x11-forwarding") == 0)
certflags_flags |= CERTOPT_X_FWD;
else if (strcasecmp(opt, "no-agent-forwarding") == 0)
certflags_flags &= ~CERTOPT_AGENT_FWD;
else if (strcasecmp(opt, "permit-agent-forwarding") == 0)
certflags_flags |= CERTOPT_AGENT_FWD;
else if (strcasecmp(opt, "no-port-forwarding") == 0)
certflags_flags &= ~CERTOPT_PORT_FWD;
else if (strcasecmp(opt, "permit-port-forwarding") == 0)
certflags_flags |= CERTOPT_PORT_FWD;
else if (strcasecmp(opt, "no-pty") == 0)
certflags_flags &= ~CERTOPT_PTY;
else if (strcasecmp(opt, "permit-pty") == 0)
certflags_flags |= CERTOPT_PTY;
else if (strcasecmp(opt, "no-user-rc") == 0)
certflags_flags &= ~CERTOPT_USER_RC;
else if (strcasecmp(opt, "permit-user-rc") == 0)
certflags_flags |= CERTOPT_USER_RC;
else if (strcasecmp(opt, "touch-required") == 0)
certflags_flags &= ~CERTOPT_NO_REQUIRE_USER_PRESENCE;
else if (strcasecmp(opt, "no-touch-required") == 0)
certflags_flags |= CERTOPT_NO_REQUIRE_USER_PRESENCE;
else if (strcasecmp(opt, "no-verify-required") == 0)
certflags_flags &= ~CERTOPT_REQUIRE_VERIFY;
else if (strcasecmp(opt, "verify-required") == 0)
certflags_flags |= CERTOPT_REQUIRE_VERIFY;
else if (strncasecmp(opt, "force-command=", 14) == 0) {
val = opt + 14;
if (*val == '\0')
fatal("Empty force-command option");
if (certflags_command != NULL)
fatal("force-command already specified");
certflags_command = xstrdup(val);
} else if (strncasecmp(opt, "source-address=", 15) == 0) {
val = opt + 15;
if (*val == '\0')
fatal("Empty source-address option");
if (certflags_src_addr != NULL)
fatal("source-address already specified");
if (addr_match_cidr_list(NULL, val) != 0)
fatal("Invalid source-address list");
certflags_src_addr = xstrdup(val);
} else if (strncasecmp(opt, "extension:", 10) == 0 ||
(iscrit = (strncasecmp(opt, "critical:", 9) == 0))) {
val = xstrdup(strchr(opt, ':') + 1);
if ((cp = strchr(val, '=')) != NULL)
*cp++ = '\0';
cert_ext_add(val, cp, iscrit);
free(val);
} else
fatal("Unsupported certificate option \"%s\"", opt);
}
static void
show_options(struct sshbuf *optbuf, int in_critical)
{
char *name, *arg, *hex;
struct sshbuf *options, *option = NULL;
int r;
if ((options = sshbuf_fromb(optbuf)) == NULL)
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_fr(r, "parse option");
printf(" %s", name);
if (!in_critical &&
(strcmp(name, "permit-X11-forwarding") == 0 ||
strcmp(name, "permit-agent-forwarding") == 0 ||
strcmp(name, "permit-port-forwarding") == 0 ||
strcmp(name, "permit-pty") == 0 ||
strcmp(name, "permit-user-rc") == 0 ||
strcmp(name, "no-touch-required") == 0)) {
printf("\n");
} else if (in_critical &&
(strcmp(name, "force-command") == 0 ||
strcmp(name, "source-address") == 0)) {
if ((r = sshbuf_get_cstring(option, &arg, NULL)) != 0)
fatal_fr(r, "parse critical");
printf(" %s\n", arg);
free(arg);
} else if (in_critical &&
strcmp(name, "verify-required") == 0) {
printf("\n");
} else if (sshbuf_len(option) > 0) {
hex = sshbuf_dtob16(option);
printf(" UNKNOWN OPTION: %s (len %zu)\n",
hex, sshbuf_len(option));
sshbuf_reset(option);
free(hex);
} else
printf(" UNKNOWN FLAG OPTION\n");
free(name);
if (sshbuf_len(option) != 0)
fatal("Option corrupt: extra data at end");
}
sshbuf_free(option);
sshbuf_free(options);
}
static void
print_cert(struct sshkey *key)
{
char valid[64], *key_fp, *ca_fp;
u_int i;
key_fp = sshkey_fingerprint(key, fingerprint_hash, SSH_FP_DEFAULT);
ca_fp = sshkey_fingerprint(key->cert->signature_key,
fingerprint_hash, SSH_FP_DEFAULT);
if (key_fp == NULL || ca_fp == NULL)
fatal_f("sshkey_fingerprint fail");
sshkey_format_cert_validity(key->cert, valid, sizeof(valid));
printf(" Type: %s %s certificate\n", sshkey_ssh_name(key),
sshkey_cert_type(key));
printf(" Public key: %s %s\n", sshkey_type(key), key_fp);
printf(" Signing CA: %s %s (using %s)\n",
sshkey_type(key->cert->signature_key), ca_fp,
key->cert->signature_type);
printf(" Key ID: \"%s\"\n", key->cert->key_id);
printf(" Serial: %llu\n", (unsigned long long)key->cert->serial);
printf(" Valid: %s\n", valid);
printf(" Principals: ");
if (key->cert->nprincipals == 0)
printf("(none)\n");
else {
for (i = 0; i < key->cert->nprincipals; i++)
printf("\n %s",
key->cert->principals[i]);
printf("\n");
}
printf(" Critical Options: ");
if (sshbuf_len(key->cert->critical) == 0)
printf("(none)\n");
else {
printf("\n");
show_options(key->cert->critical, 1);
}
printf(" Extensions: ");
if (sshbuf_len(key->cert->extensions) == 0)
printf("(none)\n");
else {
printf("\n");
show_options(key->cert->extensions, 0);
}
}
static void
do_show_cert(struct passwd *pw)
{
struct sshkey *key = NULL;
struct stat st;
int r, is_stdin = 0, ok = 0;
FILE *f;
char *cp, *line = NULL;
const char *path;
size_t linesize = 0;
u_long lnum = 0;
if (!have_identity)
ask_filename(pw, "Enter file in which the key is");
if (strcmp(identity_file, "-") != 0 && stat(identity_file, &st) == -1)
fatal("%s: %s: %s", __progname, identity_file, strerror(errno));
path = identity_file;
if (strcmp(path, "-") == 0) {
f = stdin;
path = "(stdin)";
is_stdin = 1;
} else if ((f = fopen(identity_file, "r")) == NULL)
fatal("fopen %s: %s", identity_file, strerror(errno));
while (getline(&line, &linesize, f) != -1) {
lnum++;
sshkey_free(key);
key = NULL;
/* Trim leading space and comments */
cp = line + strspn(line, " \t");
if (*cp == '#' || *cp == '\0')
continue;
if ((key = sshkey_new(KEY_UNSPEC)) == NULL)
fatal("sshkey_new");
if ((r = sshkey_read(key, &cp)) != 0) {
error_r(r, "%s:%lu: invalid key", path, lnum);
continue;
}
if (!sshkey_is_cert(key)) {
error("%s:%lu is not a certificate", path, lnum);
continue;
}
ok = 1;
if (!is_stdin && lnum == 1)
printf("%s:\n", path);
else
printf("%s:%lu:\n", path, lnum);
print_cert(key);
}
free(line);
sshkey_free(key);
fclose(f);
exit(ok ? 0 : 1);
}
static void
load_krl(const char *path, struct ssh_krl **krlp)
{
struct sshbuf *krlbuf;
int r;
if ((r = sshbuf_load_file(path, &krlbuf)) != 0)
fatal_r(r, "Unable to load KRL %s", path);
/* XXX check sigs */
if ((r = ssh_krl_from_blob(krlbuf, krlp, NULL, 0)) != 0 ||
*krlp == NULL)
fatal_r(r, "Invalid KRL file %s", path);
sshbuf_free(krlbuf);
}
static void
hash_to_blob(const char *cp, u_char **blobp, size_t *lenp,
const char *file, u_long lnum)
{
char *tmp;
size_t tlen;
struct sshbuf *b;
int r;
if (strncmp(cp, "SHA256:", 7) != 0)
fatal("%s:%lu: unsupported hash algorithm", file, lnum);
cp += 7;
/*
* OpenSSH base64 hashes omit trailing '='
* characters; put them back for decode.
*/
tlen = strlen(cp);
tmp = xmalloc(tlen + 4 + 1);
strlcpy(tmp, cp, tlen + 1);
while ((tlen % 4) != 0) {
tmp[tlen++] = '=';
tmp[tlen] = '\0';
}
if ((b = sshbuf_new()) == NULL)
fatal_f("sshbuf_new failed");
if ((r = sshbuf_b64tod(b, tmp)) != 0)
fatal_r(r, "%s:%lu: decode hash failed", file, lnum);
free(tmp);
*lenp = sshbuf_len(b);
*blobp = xmalloc(*lenp);
memcpy(*blobp, sshbuf_ptr(b), *lenp);
sshbuf_free(b);
}
static void
update_krl_from_file(struct passwd *pw, const char *file, int wild_ca,
const struct sshkey *ca, struct ssh_krl *krl)
{
struct sshkey *key = NULL;
u_long lnum = 0;
char *path, *cp, *ep, *line = NULL;
u_char *blob = NULL;
size_t blen = 0, linesize = 0;
unsigned long long serial, serial2;
int i, was_explicit_key, was_sha1, was_sha256, was_hash, r;
FILE *krl_spec;
path = tilde_expand_filename(file, pw->pw_uid);
if (strcmp(path, "-") == 0) {
krl_spec = stdin;
free(path);
path = xstrdup("(standard input)");
} else if ((krl_spec = fopen(path, "r")) == NULL)
fatal("fopen %s: %s", path, strerror(errno));
if (!quiet)
printf("Revoking from %s\n", path);
while (getline(&line, &linesize, krl_spec) != -1) {
lnum++;
was_explicit_key = was_sha1 = was_sha256 = was_hash = 0;
cp = line + strspn(line, " \t");
/* Trim trailing space, comments and strip \n */
for (i = 0, r = -1; cp[i] != '\0'; i++) {
if (cp[i] == '#' || cp[i] == '\n') {
cp[i] = '\0';
break;
}
if (cp[i] == ' ' || cp[i] == '\t') {
/* Remember the start of a span of whitespace */
if (r == -1)
r = i;
} else
r = -1;
}
if (r != -1)
cp[r] = '\0';
if (*cp == '\0')
continue;
if (strncasecmp(cp, "serial:", 7) == 0) {
if (ca == NULL && !wild_ca) {
fatal("revoking certificates by serial number "
"requires specification of a CA key");
}
cp += 7;
cp = cp + strspn(cp, " \t");
errno = 0;
serial = strtoull(cp, &ep, 0);
if (*cp == '\0' || (*ep != '\0' && *ep != '-'))
fatal("%s:%lu: invalid serial \"%s\"",
path, lnum, cp);
if (errno == ERANGE && serial == ULLONG_MAX)
fatal("%s:%lu: serial out of range",
path, lnum);
serial2 = serial;
if (*ep == '-') {
cp = ep + 1;
errno = 0;
serial2 = strtoull(cp, &ep, 0);
if (*cp == '\0' || *ep != '\0')
fatal("%s:%lu: invalid serial \"%s\"",
path, lnum, cp);
if (errno == ERANGE && serial2 == ULLONG_MAX)
fatal("%s:%lu: serial out of range",
path, lnum);
if (serial2 <= serial)
fatal("%s:%lu: invalid serial range "
"%llu:%llu", path, lnum,
(unsigned long long)serial,
(unsigned long long)serial2);
}
if (ssh_krl_revoke_cert_by_serial_range(krl,
ca, serial, serial2) != 0) {
fatal_f("revoke serial failed");
}
} else if (strncasecmp(cp, "id:", 3) == 0) {
if (ca == NULL && !wild_ca) {
fatal("revoking certificates by key ID "
"requires specification of a CA key");
}
cp += 3;
cp = cp + strspn(cp, " \t");
if (ssh_krl_revoke_cert_by_key_id(krl, ca, cp) != 0)
fatal_f("revoke key ID failed");
} else if (strncasecmp(cp, "hash:", 5) == 0) {
cp += 5;
cp = cp + strspn(cp, " \t");
hash_to_blob(cp, &blob, &blen, file, lnum);
r = ssh_krl_revoke_key_sha256(krl, blob, blen);
if (r != 0)
fatal_fr(r, "revoke key failed");
} else {
if (strncasecmp(cp, "key:", 4) == 0) {
cp += 4;
cp = cp + strspn(cp, " \t");
was_explicit_key = 1;
} else if (strncasecmp(cp, "sha1:", 5) == 0) {
cp += 5;
cp = cp + strspn(cp, " \t");
was_sha1 = 1;
} else if (strncasecmp(cp, "sha256:", 7) == 0) {
cp += 7;
cp = cp + strspn(cp, " \t");
was_sha256 = 1;
/*
* Just try to process the line as a key.
* Parsing will fail if it isn't.
*/
}
if ((key = sshkey_new(KEY_UNSPEC)) == NULL)
fatal("sshkey_new");
if ((r = sshkey_read(key, &cp)) != 0)
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) {
if (sshkey_fingerprint_raw(key,
SSH_DIGEST_SHA1, &blob, &blen) != 0) {
fatal("%s:%lu: fingerprint failed",
file, lnum);
}
r = ssh_krl_revoke_key_sha1(krl, blob, blen);
} else if (was_sha256) {
if (sshkey_fingerprint_raw(key,
SSH_DIGEST_SHA256, &blob, &blen) != 0) {
fatal("%s:%lu: fingerprint failed",
file, lnum);
}
r = ssh_krl_revoke_key_sha256(krl, blob, blen);
} else
r = ssh_krl_revoke_key(krl, key);
if (r != 0)
fatal_fr(r, "revoke key failed");
freezero(blob, blen);
blob = NULL;
blen = 0;
sshkey_free(key);
}
}
if (strcmp(path, "-") != 0)
fclose(krl_spec);
free(line);
free(path);
}
static void
do_gen_krl(struct passwd *pw, int updating, const char *ca_key_path,
unsigned long long krl_version, const char *krl_comment,
int argc, char **argv)
{
struct ssh_krl *krl;
struct stat sb;
struct sshkey *ca = NULL;
int i, r, wild_ca = 0;
char *tmp;
struct sshbuf *kbuf;
if (*identity_file == '\0')
fatal("KRL generation requires an output file");
if (stat(identity_file, &sb) == -1) {
if (errno != ENOENT)
fatal("Cannot access KRL \"%s\": %s",
identity_file, strerror(errno));
if (updating)
fatal("KRL \"%s\" does not exist", identity_file);
}
if (ca_key_path != NULL) {
if (strcasecmp(ca_key_path, "none") == 0)
wild_ca = 1;
else {
tmp = tilde_expand_filename(ca_key_path, pw->pw_uid);
if ((r = sshkey_load_public(tmp, &ca, NULL)) != 0)
fatal_r(r, "Cannot load CA public key %s", tmp);
free(tmp);
}
}
if (updating)
load_krl(identity_file, &krl);
else if ((krl = ssh_krl_init()) == NULL)
fatal("couldn't create KRL");
if (krl_version != 0)
ssh_krl_set_version(krl, krl_version);
if (krl_comment != NULL)
ssh_krl_set_comment(krl, krl_comment);
for (i = 0; i < argc; i++)
update_krl_from_file(pw, argv[i], wild_ca, ca, krl);
if ((kbuf = sshbuf_new()) == NULL)
fatal("sshbuf_new failed");
if (ssh_krl_to_blob(krl, kbuf, NULL, 0) != 0)
fatal("Couldn't generate KRL");
if ((r = sshbuf_write_file(identity_file, kbuf)) != 0)
fatal("write %s: %s", identity_file, strerror(errno));
sshbuf_free(kbuf);
ssh_krl_free(krl);
sshkey_free(ca);
}
static void
do_check_krl(struct passwd *pw, int print_krl, int argc, char **argv)
{
int i, r, ret = 0;
char *comment;
struct ssh_krl *krl;
struct sshkey *k;
if (*identity_file == '\0')
fatal("KRL checking requires an input file");
load_krl(identity_file, &krl);
if (print_krl)
krl_dump(krl, stdout);
for (i = 0; i < argc; i++) {
if ((r = sshkey_load_public(argv[i], &k, &comment)) != 0)
fatal_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 ? ")" : "",
r == 0 ? "ok" : "REVOKED");
if (r != 0)
ret = 1;
sshkey_free(k);
free(comment);
}
ssh_krl_free(krl);
exit(ret);
}
static struct sshkey *
load_sign_key(const char *keypath, const struct sshkey *pubkey)
{
size_t i, slen, plen = strlen(keypath);
char *privpath = xstrdup(keypath);
static const char * const suffixes[] = { "-cert.pub", ".pub", NULL };
struct sshkey *ret = NULL, *privkey = NULL;
int r, waspub = 0;
struct stat st;
/*
* If passed a public key filename, then try to locate the corresponding
* private key. This lets us specify certificates on the command-line
* and have ssh-keygen find the appropriate private key.
*/
for (i = 0; suffixes[i]; i++) {
slen = strlen(suffixes[i]);
if (plen <= slen ||
strcmp(privpath + plen - slen, suffixes[i]) != 0)
continue;
privpath[plen - slen] = '\0';
debug_f("%s looks like a public key, using private key "
"path %s instead", keypath, privpath);
waspub = 1;
}
if (waspub && stat(privpath, &st) != 0 && errno == ENOENT)
fatal("No private key found for public key \"%s\"", keypath);
if ((r = sshkey_load_private(privpath, "", &privkey, NULL)) != 0 &&
(r != SSH_ERR_KEY_WRONG_PASSPHRASE)) {
debug_fr(r, "load private key \"%s\"", privpath);
fatal("No private key found for \"%s\"", privpath);
} else if (privkey == NULL)
privkey = load_identity(privpath, NULL);
if (!sshkey_equal_public(pubkey, privkey)) {
error("Public key %s doesn't match private %s",
keypath, privpath);
goto done;
}
if (sshkey_is_cert(pubkey) && !sshkey_is_cert(privkey)) {
/*
* Graft the certificate onto the private key to make
* it capable of signing.
*/
if ((r = sshkey_to_certified(privkey)) != 0) {
error_fr(r, "sshkey_to_certified");
goto done;
}
if ((r = sshkey_cert_copy(pubkey, privkey)) != 0) {
error_fr(r, "sshkey_cert_copy");
goto done;
}
}
/* success */
ret = privkey;
privkey = NULL;
done:
sshkey_free(privkey);
free(privpath);
return ret;
}
static int
sign_one(struct sshkey *signkey, const char *filename, int fd,
const char *sig_namespace, const char *hashalg, sshsig_signer *signer,
void *signer_ctx)
{
struct sshbuf *sigbuf = NULL, *abuf = NULL;
int r = SSH_ERR_INTERNAL_ERROR, wfd = -1, oerrno;
char *wfile = NULL, *asig = NULL, *fp = NULL;
char *pin = NULL, *prompt = NULL;
if (!quiet) {
if (fd == STDIN_FILENO)
fprintf(stderr, "Signing data on standard input\n");
else
fprintf(stderr, "Signing file %s\n", filename);
}
if (signer == NULL && sshkey_is_sk(signkey)) {
if ((signkey->sk_flags & SSH_SK_USER_VERIFICATION_REQD)) {
xasprintf(&prompt, "Enter PIN for %s key: ",
sshkey_type(signkey));
if ((pin = read_passphrase(prompt,
RP_ALLOW_STDIN)) == NULL)
fatal_f("couldn't read PIN");
}
if ((signkey->sk_flags & SSH_SK_USER_PRESENCE_REQD)) {
if ((fp = sshkey_fingerprint(signkey, fingerprint_hash,
SSH_FP_DEFAULT)) == NULL)
fatal_f("fingerprint failed");
fprintf(stderr, "Confirm user presence for key %s %s\n",
sshkey_type(signkey), fp);
free(fp);
}
}
if ((r = sshsig_sign_fd(signkey, hashalg, sk_provider, pin,
fd, sig_namespace, &sigbuf, signer, signer_ctx)) != 0) {
error_r(r, "Signing %s failed", filename);
goto out;
}
if ((r = sshsig_armor(sigbuf, &abuf)) != 0) {
error_fr(r, "sshsig_armor");
goto out;
}
if ((asig = sshbuf_dup_string(abuf)) == NULL) {
error_f("buffer error");
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
if (fd == STDIN_FILENO) {
fputs(asig, stdout);
fflush(stdout);
} else {
xasprintf(&wfile, "%s.sig", filename);
if (confirm_overwrite(wfile)) {
if ((wfd = open(wfile, O_WRONLY|O_CREAT|O_TRUNC,
0666)) == -1) {
oerrno = errno;
error("Cannot open %s: %s",
wfile, strerror(errno));
errno = oerrno;
r = SSH_ERR_SYSTEM_ERROR;
goto out;
}
if (atomicio(vwrite, wfd, asig,
strlen(asig)) != strlen(asig)) {
oerrno = errno;
error("Cannot write to %s: %s",
wfile, strerror(errno));
errno = oerrno;
r = SSH_ERR_SYSTEM_ERROR;
goto out;
}
if (!quiet) {
fprintf(stderr, "Write signature to %s\n",
wfile);
}
}
}
/* success */
r = 0;
out:
free(wfile);
free(prompt);
free(asig);
if (pin != NULL)
freezero(pin, strlen(pin));
sshbuf_free(abuf);
sshbuf_free(sigbuf);
if (wfd != -1)
close(wfd);
return r;
}
static int
sig_process_opts(char * const *opts, size_t nopts, char **hashalgp,
uint64_t *verify_timep, int *print_pubkey)
{
size_t i;
time_t now;
if (verify_timep != NULL)
*verify_timep = 0;
if (print_pubkey != NULL)
*print_pubkey = 0;
if (hashalgp != NULL)
*hashalgp = NULL;
for (i = 0; i < nopts; i++) {
if (hashalgp != NULL &&
strncasecmp(opts[i], "hashalg=", 8) == 0) {
*hashalgp = xstrdup(opts[i] + 8);
} else if (verify_timep &&
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 && *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_sign(const char *keypath, const char *sig_namespace, int require_agent,
int argc, char **argv, char * const *opts, size_t nopts)
{
int i, fd = -1, r, ret = -1;
int agent_fd = -1;
struct sshkey *pubkey = NULL, *privkey = NULL, *signkey = NULL;
sshsig_signer *signer = NULL;
char *hashalg = NULL;
/* Check file arguments. */
for (i = 0; i < argc; i++) {
if (strcmp(argv[i], "-") != 0)
continue;
if (i > 0 || argc > 1)
fatal("Cannot sign mix of paths and standard input");
}
if (sig_process_opts(opts, nopts, &hashalg, NULL, NULL) != 0)
goto done; /* error already logged */
if ((r = sshkey_load_public(keypath, &pubkey, NULL)) != 0) {
error_r(r, "Couldn't load public key %s", keypath);
goto done;
}
if ((r = ssh_get_authentication_socket(&agent_fd)) != 0) {
if (require_agent)
fatal("Couldn't get agent socket");
debug_r(r, "Couldn't get agent socket");
} else {
if ((r = ssh_agent_has_key(agent_fd, pubkey)) == 0)
signer = agent_signer;
else {
if (require_agent)
fatal("Couldn't find key in agent");
debug_r(r, "Couldn't find key in agent");
}
}
if (signer == NULL) {
/* Not using agent - try to load private key */
if ((privkey = load_sign_key(keypath, pubkey)) == NULL)
goto done;
signkey = privkey;
} else {
/* Will use key in agent */
signkey = pubkey;
}
if (argc == 0) {
if ((r = sign_one(signkey, "(stdin)", STDIN_FILENO,
sig_namespace, hashalg, signer, &agent_fd)) != 0)
goto done;
} else {
for (i = 0; i < argc; i++) {
if (strcmp(argv[i], "-") == 0)
fd = STDIN_FILENO;
else if ((fd = open(argv[i], O_RDONLY)) == -1) {
error("Cannot open %s for signing: %s",
argv[i], strerror(errno));
goto done;
}
if ((r = sign_one(signkey, argv[i], fd, sig_namespace,
hashalg, signer, &agent_fd)) != 0)
goto done;
if (fd != STDIN_FILENO)
close(fd);
fd = -1;
}
}
ret = 0;
done:
if (fd != -1 && fd != STDIN_FILENO)
close(fd);
sshkey_free(pubkey);
sshkey_free(privkey);
free(hashalg);
return ret;
}
static int
sig_verify(const char *signature, const char *sig_namespace,
const char *principal, const char *allowed_keys, const char *revoked_keys,
char * const *opts, size_t nopts)
{
int r, ret = -1;
int print_pubkey = 0;
struct sshbuf *sigbuf = NULL, *abuf = NULL;
struct sshkey *sign_key = NULL;
char *fp = NULL;
struct sshkey_sig_details *sig_details = NULL;
uint64_t verify_time = 0;
if (sig_process_opts(opts, nopts, NULL, &verify_time,
&print_pubkey) != 0)
goto done; /* error already logged */
memset(&sig_details, 0, sizeof(sig_details));
if ((r = sshbuf_load_file(signature, &abuf)) != 0) {
error_r(r, "Couldn't read signature file");
goto done;
}
if ((r = sshsig_dearmor(abuf, &sigbuf)) != 0) {
error_fr(r, "sshsig_armor");
goto done;
}
if ((r = sshsig_verify_fd(sigbuf, STDIN_FILENO, sig_namespace,
&sign_key, &sig_details)) != 0)
goto done; /* sshsig_verify() prints error */
if ((fp = sshkey_fingerprint(sign_key, fingerprint_hash,
SSH_FP_DEFAULT)) == NULL)
fatal_f("sshkey_fingerprint failed");
debug("Valid (unverified) signature from key %s", fp);
if (sig_details != NULL) {
debug2_f("signature details: counter = %u, flags = 0x%02x",
sig_details->sk_counter, sig_details->sk_flags);
}
free(fp);
fp = NULL;
if (revoked_keys != NULL) {
if ((r = sshkey_check_revoked(sign_key, revoked_keys)) != 0) {
debug3_fr(r, "sshkey_check_revoked");
goto done;
}
}
if (allowed_keys != NULL && (r = sshsig_check_allowed_keys(allowed_keys,
sign_key, principal, sig_namespace, verify_time)) != 0) {
debug3_fr(r, "sshsig_check_allowed_keys");
goto done;
}
/* success */
ret = 0;
done:
if (!quiet) {
if (ret == 0) {
if ((fp = sshkey_fingerprint(sign_key, fingerprint_hash,
SSH_FP_DEFAULT)) == NULL)
fatal_f("sshkey_fingerprint failed");
if (principal == NULL) {
printf("Good \"%s\" signature with %s key %s\n",
sig_namespace, sshkey_type(sign_key), fp);
} else {
printf("Good \"%s\" signature for %s with %s key %s\n",
sig_namespace, principal,
sshkey_type(sign_key), fp);
}
} else {
printf("Could not verify signature.\n");
}
}
/* Print the signature key if requested */
if (ret == 0 && print_pubkey && sign_key != NULL) {
if ((r = sshkey_write(sign_key, stdout)) == 0)
fputc('\n', stdout);
else {
error_r(r, "Could not print public key.\n");
ret = -1;
}
}
sshbuf_free(sigbuf);
sshbuf_free(abuf);
sshkey_free(sign_key);
sshkey_sig_details_free(sig_details);
free(fp);
return ret;
}
static int
sig_find_principals(const char *signature, const char *allowed_keys,
char * const *opts, size_t nopts)
{
int r, ret = -1;
struct sshbuf *sigbuf = NULL, *abuf = NULL;
struct sshkey *sign_key = NULL;
char *principals = NULL, *cp, *tmp;
uint64_t verify_time = 0;
if (sig_process_opts(opts, nopts, NULL, &verify_time, NULL) != 0)
goto done; /* error already logged */
if ((r = sshbuf_load_file(signature, &abuf)) != 0) {
error_r(r, "Couldn't read signature file");
goto done;
}
if ((r = sshsig_dearmor(abuf, &sigbuf)) != 0) {
error_fr(r, "sshsig_armor");
goto done;
}
if ((r = sshsig_get_pubkey(sigbuf, &sign_key)) != 0) {
error_fr(r, "sshsig_get_pubkey");
goto done;
}
if ((r = sshsig_find_principals(allowed_keys, sign_key,
verify_time, &principals)) != 0) {
if (r != SSH_ERR_KEY_NOT_FOUND)
error_fr(r, "sshsig_find_principal");
goto done;
}
ret = 0;
done:
if (ret == 0 ) {
/* Emit matching principals one per line */
tmp = principals;
while ((cp = strsep(&tmp, ",")) != NULL && *cp != '\0')
puts(cp);
} else {
fprintf(stderr, "No principal matched.\n");
}
sshbuf_free(sigbuf);
sshbuf_free(abuf);
sshkey_free(sign_key);
free(principals);
return ret;
}
static int
sig_match_principals(const char *allowed_keys, char *principal,
char * const *opts, size_t nopts)
{
int r;
char **principals = NULL;
size_t i, nprincipals = 0;
if ((r = sig_process_opts(opts, nopts, NULL, NULL, NULL)) != 0)
return r; /* error already logged */
if ((r = sshsig_match_principals(allowed_keys, principal,
&principals, &nprincipals)) != 0) {
debug_f("match: %s", ssh_err(r));
fprintf(stderr, "No principal matched.\n");
return r;
}
for (i = 0; i < nprincipals; i++) {
printf("%s\n", principals[i]);
free(principals[i]);
}
free(principals);
return 0;
}
static void
do_moduli_gen(const char *out_file, char **opts, size_t nopts)
{
#ifdef WITH_OPENSSL
/* Moduli generation/screening */
u_int32_t memory = 0;
BIGNUM *start = NULL;
int moduli_bits = 0;
FILE *out;
size_t i;
const char *errstr;
/* Parse options */
for (i = 0; i < nopts; i++) {
if (strncmp(opts[i], "memory=", 7) == 0) {
memory = (u_int32_t)strtonum(opts[i]+7, 1,
UINT_MAX, &errstr);
if (errstr) {
fatal("Memory limit is %s: %s",
errstr, opts[i]+7);
}
} else if (strncmp(opts[i], "start=", 6) == 0) {
/* XXX - also compare length against bits */
if (BN_hex2bn(&start, opts[i]+6) == 0)
fatal("Invalid start point.");
} else if (strncmp(opts[i], "bits=", 5) == 0) {
moduli_bits = (int)strtonum(opts[i]+5, 1,
INT_MAX, &errstr);
if (errstr) {
fatal("Invalid number: %s (%s)",
opts[i]+12, errstr);
}
} else {
fatal("Option \"%s\" is unsupported for moduli "
"generation", opts[i]);
}
}
if ((out = fopen(out_file, "w")) == NULL) {
fatal("Couldn't open modulus candidate file \"%s\": %s",
out_file, strerror(errno));
}
setvbuf(out, NULL, _IOLBF, 0);
if (moduli_bits == 0)
moduli_bits = DEFAULT_BITS;
if (gen_candidates(out, memory, moduli_bits, start) != 0)
fatal("modulus candidate generation failed");
#else /* WITH_OPENSSL */
fatal("Moduli generation is not supported");
#endif /* WITH_OPENSSL */
}
static void
do_moduli_screen(const char *out_file, char **opts, size_t nopts)
{
#ifdef WITH_OPENSSL
/* Moduli generation/screening */
char *checkpoint = NULL;
u_int32_t generator_wanted = 0;
unsigned long start_lineno = 0, lines_to_process = 0;
int prime_tests = 0;
FILE *out, *in = stdin;
size_t i;
const char *errstr;
/* Parse options */
for (i = 0; i < nopts; i++) {
if (strncmp(opts[i], "lines=", 6) == 0) {
lines_to_process = strtoul(opts[i]+6, NULL, 10);
} else if (strncmp(opts[i], "start-line=", 11) == 0) {
start_lineno = strtoul(opts[i]+11, NULL, 10);
} else if (strncmp(opts[i], "checkpoint=", 11) == 0) {
checkpoint = xstrdup(opts[i]+11);
} else if (strncmp(opts[i], "generator=", 10) == 0) {
generator_wanted = (u_int32_t)strtonum(
opts[i]+10, 1, UINT_MAX, &errstr);
if (errstr != NULL) {
fatal("Generator invalid: %s (%s)",
opts[i]+10, errstr);
}
} else if (strncmp(opts[i], "prime-tests=", 12) == 0) {
prime_tests = (int)strtonum(opts[i]+12, 1,
INT_MAX, &errstr);
if (errstr) {
fatal("Invalid number: %s (%s)",
opts[i]+12, errstr);
}
} else {
fatal("Option \"%s\" is unsupported for moduli "
"screening", opts[i]);
}
}
if (have_identity && strcmp(identity_file, "-") != 0) {
if ((in = fopen(identity_file, "r")) == NULL) {
fatal("Couldn't open modulus candidate "
"file \"%s\": %s", identity_file,
strerror(errno));
}
}
if ((out = fopen(out_file, "a")) == NULL) {
fatal("Couldn't open moduli file \"%s\": %s",
out_file, strerror(errno));
}
setvbuf(out, NULL, _IOLBF, 0);
if (prime_test(in, out, prime_tests == 0 ? 100 : prime_tests,
generator_wanted, checkpoint,
start_lineno, lines_to_process) != 0)
fatal("modulus screening failed");
#else /* WITH_OPENSSL */
fatal("Moduli screening is not supported");
#endif /* WITH_OPENSSL */
}
/* Read and confirm a passphrase */
static char *
read_check_passphrase(const char *prompt1, const char *prompt2,
const char *retry_prompt)
{
char *passphrase1, *passphrase2;
for (;;) {
passphrase1 = read_passphrase(prompt1, RP_ALLOW_STDIN);
passphrase2 = read_passphrase(prompt2, RP_ALLOW_STDIN);
if (strcmp(passphrase1, passphrase2) == 0) {
freezero(passphrase2, strlen(passphrase2));
return passphrase1;
}
/* The passphrases do not match. Clear them and retry. */
freezero(passphrase1, strlen(passphrase1));
freezero(passphrase2, strlen(passphrase2));
fputs(retry_prompt, stdout);
fputc('\n', stdout);
fflush(stdout);
}
/* NOTREACHED */
return NULL;
}
static char *
private_key_passphrase(void)
{
if (identity_passphrase)
return xstrdup(identity_passphrase);
if (identity_new_passphrase)
return xstrdup(identity_new_passphrase);
return read_check_passphrase(
"Enter passphrase (empty for no passphrase): ",
"Enter same passphrase again: ",
"Passphrases do not match. Try again.");
}
static char *
sk_suffix(const char *application, const uint8_t *user, size_t userlen)
{
char *ret, *cp;
size_t slen, i;
/* Trim off URL-like preamble */
if (strncmp(application, "ssh://", 6) == 0)
ret = xstrdup(application + 6);
else if (strncmp(application, "ssh:", 4) == 0)
ret = xstrdup(application + 4);
else
ret = xstrdup(application);
/* Count trailing zeros in user */
for (i = 0; i < userlen; i++) {
if (user[userlen - i - 1] != 0)
break;
}
if (i >= userlen)
return ret; /* user-id was default all-zeros */
/* Append user-id, escaping non-UTF-8 characters */
slen = userlen - i;
if (asmprintf(&cp, INT_MAX, NULL, "%.*s", (int)slen, user) == -1)
fatal_f("asmprintf failed");
/* Don't emit a user-id that contains path or control characters */
if (strchr(cp, '/') != NULL || strstr(cp, "..") != NULL ||
strchr(cp, '\\') != NULL) {
free(cp);
cp = tohex(user, slen);
}
xextendf(&ret, "_", "%s", cp);
free(cp);
return ret;
}
static int
do_download_sk(const char *skprovider, const char *device)
{
struct sshsk_resident_key **srks;
size_t nsrks, i;
int r, ret = -1;
char *fp, *pin = NULL, *pass = NULL, *path, *pubpath;
const char *ext;
struct sshkey *key;
if (skprovider == NULL)
fatal("Cannot download keys without provider");
pin = read_passphrase("Enter PIN for authenticator: ", RP_ALLOW_STDIN);
if (!quiet) {
printf("You may need to touch your authenticator "
"to authorize key download.\n");
}
if ((r = sshsk_load_resident(skprovider, device, pin, 0,
&srks, &nsrks)) != 0) {
if (pin != NULL)
freezero(pin, strlen(pin));
error_r(r, "Unable to load resident keys");
return -1;
}
if (nsrks == 0)
logit("No keys to download");
if (pin != NULL)
freezero(pin, strlen(pin));
for (i = 0; i < nsrks; i++) {
key = srks[i]->key;
if (key->type != KEY_ECDSA_SK && key->type != KEY_ED25519_SK) {
error("Unsupported key type %s (%d)",
sshkey_type(key), key->type);
continue;
}
if ((fp = sshkey_fingerprint(key, fingerprint_hash,
SSH_FP_DEFAULT)) == NULL)
fatal_f("sshkey_fingerprint failed");
debug_f("key %zu: %s %s %s (flags 0x%02x)", i,
sshkey_type(key), fp, key->sk_application, key->sk_flags);
ext = sk_suffix(key->sk_application,
srks[i]->user_id, srks[i]->user_id_len);
xasprintf(&path, "id_%s_rk%s%s",
key->type == KEY_ECDSA_SK ? "ecdsa_sk" : "ed25519_sk",
*ext == '\0' ? "" : "_", ext);
/* If the file already exists, ask the user to confirm. */
if (!confirm_overwrite(path)) {
free(path);
break;
}
/* Save the key with the application string as the comment */
if (pass == NULL)
pass = private_key_passphrase();
if ((r = sshkey_save_private(key, path, pass,
key->sk_application, private_key_format,
openssh_format_cipher, rounds)) != 0) {
error_r(r, "Saving key \"%s\" failed", path);
free(path);
break;
}
if (!quiet) {
printf("Saved %s key%s%s to %s\n", sshkey_type(key),
*ext != '\0' ? " " : "",
*ext != '\0' ? key->sk_application : "",
path);
}
/* Save public key too */
xasprintf(&pubpath, "%s.pub", path);
free(path);
if ((r = sshkey_save_public(key, pubpath,
key->sk_application)) != 0) {
error_r(r, "Saving public key \"%s\" failed", pubpath);
free(pubpath);
break;
}
free(pubpath);
}
if (i >= nsrks)
ret = 0; /* success */
if (pass != NULL)
freezero(pass, strlen(pass));
sshsk_free_resident_keys(srks, nsrks);
return ret;
}
static void
save_attestation(struct sshbuf *attest, const char *path)
{
mode_t omask;
int r;
if (path == NULL)
return; /* nothing to do */
if (attest == NULL || sshbuf_len(attest) == 0)
fatal("Enrollment did not return attestation data");
omask = umask(077);
r = sshbuf_write_file(path, attest);
umask(omask);
if (r != 0)
fatal_r(r, "Unable to write attestation data \"%s\"", path);
if (!quiet)
printf("Your FIDO attestation certificate has been saved in "
"%s\n", path);
}
static int
confirm_sk_overwrite(const char *application, const char *user)
{
char yesno[3];
printf("A resident key scoped to '%s' with user id '%s' already "
"exists.\n", application == NULL ? "ssh:" : application,
user == NULL ? "null" : user);
printf("Overwrite key in token (y/n)? ");
fflush(stdout);
if (fgets(yesno, sizeof(yesno), stdin) == NULL)
return 0;
if (yesno[0] != 'y' && yesno[0] != 'Y')
return 0;
return 1;
}
static void
usage(void)
{
fprintf(stderr,
"usage: ssh-keygen [-q] [-a rounds] [-b bits] [-C comment] [-f output_keyfile]\n"
" [-m format] [-N new_passphrase] [-O option]\n"
" [-t dsa | ecdsa | ecdsa-sk | ed25519 | ed25519-sk | rsa]\n"
" [-w provider] [-Z cipher]\n"
" ssh-keygen -p [-a rounds] [-f keyfile] [-m format] [-N new_passphrase]\n"
" [-P old_passphrase] [-Z cipher]\n"
#ifdef WITH_OPENSSL
" ssh-keygen -i [-f input_keyfile] [-m key_format]\n"
" ssh-keygen -e [-f input_keyfile] [-m key_format]\n"
#endif
" ssh-keygen -y [-f input_keyfile]\n"
" ssh-keygen -c [-a rounds] [-C comment] [-f keyfile] [-P passphrase]\n"
" ssh-keygen -l [-v] [-E fingerprint_hash] [-f input_keyfile]\n"
" ssh-keygen -B [-f input_keyfile]\n");
#ifdef ENABLE_PKCS11
fprintf(stderr,
" ssh-keygen -D pkcs11\n");
#endif
fprintf(stderr,
" ssh-keygen -F hostname [-lv] [-f known_hosts_file]\n"
" ssh-keygen -H [-f known_hosts_file]\n"
" ssh-keygen -K [-a rounds] [-w provider]\n"
" ssh-keygen -R hostname [-f known_hosts_file]\n"
" ssh-keygen -r hostname [-g] [-f input_keyfile]\n"
#ifdef WITH_OPENSSL
" ssh-keygen -M generate [-O option] output_file\n"
" ssh-keygen -M screen [-f input_file] [-O option] output_file\n"
#endif
" ssh-keygen -I certificate_identity -s ca_key [-hU] [-D pkcs11_provider]\n"
" [-n principals] [-O option] [-V validity_interval]\n"
" [-z serial_number] file ...\n"
" ssh-keygen -L [-f input_keyfile]\n"
" ssh-keygen -A [-a rounds] [-f prefix_path]\n"
" ssh-keygen -k -f krl_file [-u] [-s ca_public] [-z version_number]\n"
" file ...\n"
" ssh-keygen -Q [-l] -f krl_file [file ...]\n"
" ssh-keygen -Y find-principals -s signature_file -f allowed_signers_file\n"
" ssh-keygen -Y match-principals -I signer_identity -f allowed_signers_file\n"
" ssh-keygen -Y check-novalidate -n namespace -s signature_file\n"
" ssh-keygen -Y sign -f key_file -n namespace file [-O option] ...\n"
" ssh-keygen -Y verify -f allowed_signers_file -I signer_identity\n"
" -n namespace -s signature_file [-r krl_file] [-O option]\n");
exit(1);
}
/*
* Main program for key management.
*/
int
main(int argc, char **argv)
{
char comment[1024], *passphrase = NULL;
char *rr_hostname = NULL, *ep, *fp, *ra;
struct sshkey *private, *public;
struct passwd *pw;
int r, opt, type;
int change_passphrase = 0, change_comment = 0, show_cert = 0;
int find_host = 0, delete_host = 0, hash_hosts = 0;
int gen_all_hostkeys = 0, gen_krl = 0, update_krl = 0, check_krl = 0;
int prefer_agent = 0, convert_to = 0, convert_from = 0;
int print_public = 0, print_generic = 0, cert_serial_autoinc = 0;
int do_gen_candidates = 0, do_screen_candidates = 0, download_sk = 0;
unsigned long long cert_serial = 0;
char *identity_comment = NULL, *ca_key_path = NULL, **opts = NULL;
char *sk_application = NULL, *sk_device = NULL, *sk_user = NULL;
char *sk_attestation_path = NULL;
struct sshbuf *challenge = NULL, *attest = NULL;
size_t i, nopts = 0;
u_int32_t bits = 0;
uint8_t sk_flags = SSH_SK_USER_PRESENCE_REQD;
const char *errstr;
int log_level = SYSLOG_LEVEL_INFO;
char *sign_op = NULL;
extern int optind;
extern char *optarg;
/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
sanitise_stdfd();
__progname = ssh_get_progname(argv[0]);
seed_rng();
log_init(argv[0], SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_USER, 1);
msetlocale();
/* we need this for the home * directory. */
pw = getpwuid(getuid());
if (!pw)
fatal("No user exists for uid %lu", (u_long)getuid());
pw = pwcopy(pw);
if (gethostname(hostname, sizeof(hostname)) == -1)
fatal("gethostname: %s", strerror(errno));
sk_provider = getenv("SSH_SK_PROVIDER");
/* Remaining characters: dGjJSTWx */
while ((opt = getopt(argc, argv, "ABHKLQUXceghiklopquvy"
"C:D:E:F:I:M:N:O:P:R:V:Y:Z:"
"a:b:f:g:m:n:r:s:t:w:z:")) != -1) {
switch (opt) {
case 'A':
gen_all_hostkeys = 1;
break;
case 'b':
bits = (u_int32_t)strtonum(optarg, 1, UINT32_MAX,
&errstr);
if (errstr)
fatal("Bits has bad value %s (%s)",
optarg, errstr);
break;
case 'E':
fingerprint_hash = ssh_digest_alg_by_name(optarg);
if (fingerprint_hash == -1)
fatal("Invalid hash algorithm \"%s\"", optarg);
break;
case 'F':
find_host = 1;
rr_hostname = optarg;
break;
case 'H':
hash_hosts = 1;
break;
case 'I':
cert_key_id = optarg;
break;
case 'R':
delete_host = 1;
rr_hostname = optarg;
break;
case 'L':
show_cert = 1;
break;
case 'l':
print_fingerprint = 1;
break;
case 'B':
print_bubblebabble = 1;
break;
case 'm':
if (strcasecmp(optarg, "RFC4716") == 0 ||
strcasecmp(optarg, "ssh2") == 0) {
convert_format = FMT_RFC4716;
break;
}
if (strcasecmp(optarg, "PKCS8") == 0) {
convert_format = FMT_PKCS8;
private_key_format = SSHKEY_PRIVATE_PKCS8;
break;
}
if (strcasecmp(optarg, "PEM") == 0) {
convert_format = FMT_PEM;
private_key_format = SSHKEY_PRIVATE_PEM;
break;
}
fatal("Unsupported conversion format \"%s\"", optarg);
case 'n':
cert_principals = optarg;
break;
case 'o':
/* no-op; new format is already the default */
break;
case 'p':
change_passphrase = 1;
break;
case 'c':
change_comment = 1;
break;
case 'f':
if (strlcpy(identity_file, optarg,
sizeof(identity_file)) >= sizeof(identity_file))
fatal("Identity filename too long");
have_identity = 1;
break;
case 'g':
print_generic = 1;
break;
case 'K':
download_sk = 1;
break;
case 'P':
identity_passphrase = optarg;
break;
case 'N':
identity_new_passphrase = optarg;
break;
case 'Q':
check_krl = 1;
break;
case 'O':
opts = xrecallocarray(opts, nopts, nopts + 1,
sizeof(*opts));
opts[nopts++] = xstrdup(optarg);
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;
break;
case 'q':
quiet = 1;
break;
case 'e':
/* export key */
convert_to = 1;
break;
case 'h':
cert_key_type = SSH2_CERT_TYPE_HOST;
certflags_flags = 0;
break;
case 'k':
gen_krl = 1;
break;
case 'i':
case 'X':
/* import key */
convert_from = 1;
break;
case 'y':
print_public = 1;
break;
case 's':
ca_key_path = optarg;
break;
case 't':
key_type_name = optarg;
break;
case 'D':
pkcs11provider = optarg;
break;
case 'U':
prefer_agent = 1;
break;
case 'u':
update_krl = 1;
break;
case 'v':
if (log_level == SYSLOG_LEVEL_INFO)
log_level = SYSLOG_LEVEL_DEBUG1;
else {
if (log_level >= SYSLOG_LEVEL_DEBUG1 &&
log_level < SYSLOG_LEVEL_DEBUG3)
log_level++;
}
break;
case 'r':
rr_hostname = optarg;
break;
case 'a':
rounds = (int)strtonum(optarg, 1, INT_MAX, &errstr);
if (errstr)
fatal("Invalid number: %s (%s)",
optarg, errstr);
break;
case 'V':
parse_cert_times(optarg);
break;
case 'Y':
sign_op = optarg;
break;
case 'w':
sk_provider = optarg;
break;
case 'z':
errno = 0;
if (*optarg == '+') {
cert_serial_autoinc = 1;
optarg++;
}
cert_serial = strtoull(optarg, &ep, 10);
if (*optarg < '0' || *optarg > '9' || *ep != '\0' ||
(errno == ERANGE && cert_serial == ULLONG_MAX))
fatal("Invalid serial number \"%s\"", optarg);
break;
case 'M':
if (strcmp(optarg, "generate") == 0)
do_gen_candidates = 1;
else if (strcmp(optarg, "screen") == 0)
do_screen_candidates = 1;
else
fatal("Unsupported moduli option %s", optarg);
break;
- case '?':
default:
usage();
}
}
#ifdef ENABLE_SK_INTERNAL
if (sk_provider == NULL)
sk_provider = "internal";
#endif
/* reinit */
log_init(argv[0], log_level, SYSLOG_FACILITY_USER, 1);
argv += optind;
argc -= optind;
if (sign_op != NULL) {
if (strncmp(sign_op, "find-principals", 15) == 0) {
if (ca_key_path == NULL) {
error("Too few arguments for find-principals:"
"missing signature file");
exit(1);
}
if (!have_identity) {
error("Too few arguments for find-principals:"
"missing allowed keys file");
exit(1);
}
return sig_find_principals(ca_key_path, identity_file,
opts, nopts);
} else if (strncmp(sign_op, "match-principals", 16) == 0) {
if (!have_identity) {
error("Too few arguments for match-principals:"
"missing allowed keys file");
exit(1);
}
if (cert_key_id == NULL) {
error("Too few arguments for match-principals: "
"missing principal ID");
exit(1);
}
return sig_match_principals(identity_file, cert_key_id,
opts, nopts);
} else if (strncmp(sign_op, "sign", 4) == 0) {
/* NB. cert_principals is actually namespace, via -n */
if (cert_principals == NULL ||
*cert_principals == '\0') {
error("Too few arguments for sign: "
"missing namespace");
exit(1);
}
if (!have_identity) {
error("Too few arguments for sign: "
"missing key");
exit(1);
}
return sig_sign(identity_file, cert_principals,
prefer_agent, argc, argv, opts, nopts);
} else if (strncmp(sign_op, "check-novalidate", 16) == 0) {
/* NB. cert_principals is actually namespace, via -n */
if (cert_principals == NULL ||
*cert_principals == '\0') {
error("Too few arguments for check-novalidate: "
"missing namespace");
exit(1);
}
if (ca_key_path == NULL) {
error("Too few arguments for check-novalidate: "
"missing signature file");
exit(1);
}
return sig_verify(ca_key_path, cert_principals,
NULL, NULL, NULL, opts, nopts);
} else if (strncmp(sign_op, "verify", 6) == 0) {
/* NB. cert_principals is actually namespace, via -n */
if (cert_principals == NULL ||
*cert_principals == '\0') {
error("Too few arguments for verify: "
"missing namespace");
exit(1);
}
if (ca_key_path == NULL) {
error("Too few arguments for verify: "
"missing signature file");
exit(1);
}
if (!have_identity) {
error("Too few arguments for sign: "
"missing allowed keys file");
exit(1);
}
if (cert_key_id == NULL) {
error("Too few arguments for verify: "
"missing principal identity");
exit(1);
}
return sig_verify(ca_key_path, cert_principals,
cert_key_id, identity_file, rr_hostname,
opts, nopts);
}
error("Unsupported operation for -Y: \"%s\"", sign_op);
usage();
/* NOTREACHED */
}
if (ca_key_path != NULL) {
if (argc < 1 && !gen_krl) {
error("Too few arguments.");
usage();
}
} else if (argc > 0 && !gen_krl && !check_krl &&
!do_gen_candidates && !do_screen_candidates) {
error("Too many arguments.");
usage();
}
if (change_passphrase && change_comment) {
error("Can only have one of -p and -c.");
usage();
}
if (print_fingerprint && (delete_host || hash_hosts)) {
error("Cannot use -l with -H or -R.");
usage();
}
if (gen_krl) {
do_gen_krl(pw, update_krl, ca_key_path,
cert_serial, identity_comment, argc, argv);
return (0);
}
if (check_krl) {
do_check_krl(pw, print_fingerprint, argc, argv);
return (0);
}
if (ca_key_path != NULL) {
if (cert_key_id == NULL)
fatal("Must specify key id (-I) when certifying");
for (i = 0; i < nopts; i++)
add_cert_option(opts[i]);
do_ca_sign(pw, ca_key_path, prefer_agent,
cert_serial, cert_serial_autoinc, argc, argv);
}
if (show_cert)
do_show_cert(pw);
if (delete_host || hash_hosts || find_host) {
do_known_hosts(pw, rr_hostname, find_host,
delete_host, hash_hosts);
}
if (pkcs11provider != NULL)
do_download(pw);
if (download_sk) {
for (i = 0; i < nopts; i++) {
if (strncasecmp(opts[i], "device=", 7) == 0) {
sk_device = xstrdup(opts[i] + 7);
} else {
fatal("Option \"%s\" is unsupported for "
"FIDO authenticator download", opts[i]);
}
}
return do_download_sk(sk_provider, sk_device);
}
if (print_fingerprint || print_bubblebabble)
do_fingerprint(pw);
if (change_passphrase)
do_change_passphrase(pw);
if (change_comment)
do_change_comment(pw, identity_comment);
#ifdef WITH_OPENSSL
if (convert_to)
do_convert_to(pw);
if (convert_from)
do_convert_from(pw);
#else /* WITH_OPENSSL */
if (convert_to || convert_from)
fatal("key conversion disabled at compile time");
#endif /* WITH_OPENSSL */
if (print_public)
do_print_public(pw);
if (rr_hostname != NULL) {
unsigned int n = 0;
if (have_identity) {
n = do_print_resource_record(pw, identity_file,
rr_hostname, print_generic);
if (n == 0)
fatal("%s: %s", identity_file, strerror(errno));
exit(0);
} else {
n += do_print_resource_record(pw,
_PATH_HOST_RSA_KEY_FILE, rr_hostname,
print_generic);
n += do_print_resource_record(pw,
_PATH_HOST_DSA_KEY_FILE, rr_hostname,
print_generic);
n += do_print_resource_record(pw,
_PATH_HOST_ECDSA_KEY_FILE, rr_hostname,
print_generic);
n += do_print_resource_record(pw,
_PATH_HOST_ED25519_KEY_FILE, rr_hostname,
print_generic);
n += do_print_resource_record(pw,
_PATH_HOST_XMSS_KEY_FILE, rr_hostname,
print_generic);
if (n == 0)
fatal("no keys found.");
exit(0);
}
}
if (do_gen_candidates || do_screen_candidates) {
if (argc <= 0)
fatal("No output file specified");
else if (argc > 1)
fatal("Too many output files specified");
}
if (do_gen_candidates) {
do_moduli_gen(argv[0], opts, nopts);
return 0;
}
if (do_screen_candidates) {
do_moduli_screen(argv[0], opts, nopts);
return 0;
}
if (gen_all_hostkeys) {
do_gen_all_hostkeys(pw);
return (0);
}
if (key_type_name == NULL)
key_type_name = DEFAULT_KEY_TYPE_NAME;
type = sshkey_type_from_name(key_type_name);
type_bits_valid(type, key_type_name, &bits);
if (!quiet)
printf("Generating public/private %s key pair.\n",
key_type_name);
switch (type) {
case KEY_ECDSA_SK:
case KEY_ED25519_SK:
for (i = 0; i < nopts; i++) {
if (strcasecmp(opts[i], "no-touch-required") == 0) {
sk_flags &= ~SSH_SK_USER_PRESENCE_REQD;
} else if (strcasecmp(opts[i], "verify-required") == 0) {
sk_flags |= SSH_SK_USER_VERIFICATION_REQD;
} else if (strcasecmp(opts[i], "resident") == 0) {
sk_flags |= SSH_SK_RESIDENT_KEY;
} else if (strncasecmp(opts[i], "device=", 7) == 0) {
sk_device = xstrdup(opts[i] + 7);
} else if (strncasecmp(opts[i], "user=", 5) == 0) {
sk_user = xstrdup(opts[i] + 5);
} else if (strncasecmp(opts[i], "challenge=", 10) == 0) {
if ((r = sshbuf_load_file(opts[i] + 10,
&challenge)) != 0) {
fatal_r(r, "Unable to load FIDO "
"enrollment challenge \"%s\"",
opts[i] + 10);
}
} else if (strncasecmp(opts[i],
"write-attestation=", 18) == 0) {
sk_attestation_path = opts[i] + 18;
} else if (strncasecmp(opts[i],
"application=", 12) == 0) {
sk_application = xstrdup(opts[i] + 12);
if (strncmp(sk_application, "ssh:", 4) != 0) {
fatal("FIDO application string must "
"begin with \"ssh:\"");
}
} else {
fatal("Option \"%s\" is unsupported for "
"FIDO authenticator enrollment", opts[i]);
}
}
if ((attest = sshbuf_new()) == NULL)
fatal("sshbuf_new failed");
r = 0;
for (i = 0 ;;) {
if (!quiet) {
printf("You may need to touch your "
"authenticator%s to authorize key "
"generation.\n",
r == 0 ? "" : " again");
}
fflush(stdout);
r = sshsk_enroll(type, sk_provider, sk_device,
sk_application == NULL ? "ssh:" : sk_application,
sk_user, sk_flags, passphrase, challenge,
&private, attest);
if (r == 0)
break;
if (r == SSH_ERR_KEY_BAD_PERMISSIONS &&
(sk_flags & SSH_SK_RESIDENT_KEY) != 0 &&
(sk_flags & SSH_SK_FORCE_OPERATION) == 0 &&
confirm_sk_overwrite(sk_application, sk_user)) {
sk_flags |= SSH_SK_FORCE_OPERATION;
continue;
}
if (r != SSH_ERR_KEY_WRONG_PASSPHRASE)
fatal_r(r, "Key enrollment failed");
else if (passphrase != NULL) {
error("PIN incorrect");
freezero(passphrase, strlen(passphrase));
passphrase = NULL;
}
if (++i >= 3)
fatal("Too many incorrect PINs");
passphrase = read_passphrase("Enter PIN for "
"authenticator: ", RP_ALLOW_STDIN);
}
if (passphrase != NULL) {
freezero(passphrase, strlen(passphrase));
passphrase = NULL;
}
break;
default:
if ((r = sshkey_generate(type, bits, &private)) != 0)
fatal("sshkey_generate failed");
break;
}
if ((r = sshkey_from_private(private, &public)) != 0)
fatal_r(r, "sshkey_from_private");
if (!have_identity)
ask_filename(pw, "Enter file in which to save the key");
/* Create ~/.ssh directory if it doesn't already exist. */
hostfile_create_user_ssh_dir(identity_file, !quiet);
/* If the file already exists, ask the user to confirm. */
if (!confirm_overwrite(identity_file))
exit(1);
/* Determine the passphrase for the private key */
passphrase = private_key_passphrase();
if (identity_comment) {
strlcpy(comment, identity_comment, sizeof(comment));
} else {
/* Create default comment field for the passphrase. */
snprintf(comment, sizeof comment, "%s@%s", pw->pw_name, hostname);
}
/* 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_r(r, "Saving key \"%s\" failed", identity_file);
freezero(passphrase, strlen(passphrase));
exit(1);
}
freezero(passphrase, strlen(passphrase));
sshkey_free(private);
if (!quiet) {
printf("Your identification has been saved in %s\n",
identity_file);
}
strlcat(identity_file, ".pub", sizeof(identity_file));
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,
SSH_FP_DEFAULT);
ra = sshkey_fingerprint(public, fingerprint_hash,
SSH_FP_RANDOMART);
if (fp == NULL || ra == NULL)
fatal("sshkey_fingerprint failed");
printf("Your public key has been saved in %s\n",
identity_file);
printf("The key fingerprint is:\n");
printf("%s %s\n", fp, comment);
printf("The key's randomart image is:\n");
printf("%s\n", ra);
free(ra);
free(fp);
}
if (sk_attestation_path != NULL)
save_attestation(attest, sk_attestation_path);
sshbuf_free(attest);
sshkey_free(public);
exit(0);
}
diff --git a/crypto/openssh/ssh-keyscan.1 b/crypto/openssh/ssh-keyscan.1
index 4eb0bea09168..ca4feea2a9e0 100644
--- a/crypto/openssh/ssh-keyscan.1
+++ b/crypto/openssh/ssh-keyscan.1
@@ -1,162 +1,178 @@
-.\" $OpenBSD: ssh-keyscan.1,v 1.46 2022/06/03 04:00:15 dtucker Exp $
+.\" $OpenBSD: ssh-keyscan.1,v 1.47 2022/10/28 02:29:34 djm Exp $
.\"
.\" Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>.
.\"
.\" Modification and redistribution in source and binary forms is
.\" permitted provided that due credit is given to the author and the
.\" OpenBSD project by leaving this copyright notice intact.
.\"
-.Dd $Mdocdate: June 3 2022 $
+.Dd $Mdocdate: October 28 2022 $
.Dt SSH-KEYSCAN 1
.Os
.Sh NAME
.Nm ssh-keyscan
.Nd gather SSH public keys from servers
.Sh SYNOPSIS
.Nm ssh-keyscan
.Op Fl 46cDHv
.Op Fl f Ar file
.Op Fl p Ar port
.Op Fl T Ar timeout
.Op Fl t Ar type
.Op Ar host | addrlist namelist
.Sh DESCRIPTION
.Nm
is a utility for gathering the public SSH host keys of a number of
hosts.
It was designed to aid in building and verifying
.Pa ssh_known_hosts
files,
the format of which is documented in
.Xr sshd 8 .
.Nm
provides a minimal interface suitable for use by shell and perl
scripts.
.Pp
.Nm
uses non-blocking socket I/O to contact as many hosts as possible in
parallel, so it is very efficient.
The keys from a domain of 1,000
hosts can be collected in tens of seconds, even when some of those
hosts are down or do not run
.Xr sshd 8 .
For scanning, one does not need
login access to the machines that are being scanned, nor does the
scanning process involve any encryption.
.Pp
+Hosts to be scanned may be specified by hostname, address or by CIDR
+network range (e.g. 192.168.16/28).
+If a network range is specified, then all addresses in that range will
+be scanned.
+.Pp
The options are as follows:
.Bl -tag -width Ds
.It Fl 4
Force
.Nm
to use IPv4 addresses only.
.It Fl 6
Force
.Nm
to use IPv6 addresses only.
.It Fl c
Request certificates from target hosts instead of plain keys.
.It Fl D
Print keys found as SSHFP DNS records.
The default is to print keys in a format usable as a
.Xr ssh 1
.Pa known_hosts
file.
.It Fl f Ar file
Read hosts or
.Dq addrlist namelist
pairs from
.Ar file ,
one per line.
If
.Sq -
is supplied instead of a filename,
.Nm
will read from the standard input.
-Input is expected in the format:
+Names read from a file must start with an address, hostname or CIDR network
+range to be scanned.
+Addresses and hostnames may optionally be followed by comma-separated name
+or address aliases that will be copied to the output.
+For example:
.Bd -literal
-1.2.3.4,1.2.4.4 name.my.domain,name,n.my.domain,n,1.2.3.4,1.2.4.4
+192.168.11.0/24
+10.20.1.1
+happy.example.org
+10.0.0.1,sad.example.org
.Ed
.It Fl H
Hash all hostnames and addresses in the output.
Hashed names may be used normally by
.Xr ssh 1
and
.Xr sshd 8 ,
but they do not reveal identifying information should the file's contents
be disclosed.
.It Fl p Ar port
Connect to
.Ar port
on the remote host.
.It Fl T Ar timeout
Set the timeout for connection attempts.
If
.Ar timeout
seconds have elapsed since a connection was initiated to a host or since the
last time anything was read from that host, the connection is
closed and the host in question considered unavailable.
The default is 5 seconds.
.It Fl t Ar type
Specify the type of the key to fetch from the scanned hosts.
The possible values are
.Dq dsa ,
.Dq ecdsa ,
.Dq ed25519 ,
.Dq ecdsa-sk ,
.Dq ed25519-sk ,
or
.Dq rsa .
Multiple values may be specified by separating them with commas.
The default is to fetch
.Dq rsa ,
.Dq ecdsa ,
.Dq ed25519 ,
.Dq ecdsa-sk ,
and
.Dq ed25519-sk
keys.
.It Fl v
Verbose mode:
print debugging messages about progress.
.El
.Pp
If an ssh_known_hosts file is constructed using
.Nm
without verifying the keys, users will be vulnerable to
.Em man in the middle
attacks.
On the other hand, if the security model allows such a risk,
.Nm
can help in the detection of tampered keyfiles or man in the middle
attacks which have begun after the ssh_known_hosts file was created.
.Sh FILES
.Pa /etc/ssh/ssh_known_hosts
.Sh EXAMPLES
Print the RSA host key for machine
.Ar hostname :
.Pp
.Dl $ ssh-keyscan -t rsa hostname
.Pp
+Search a network range, printing all supported key types:
+.Pp
+.Dl $ ssh-keyscan 192.168.0.64/25
+.Pp
Find all hosts from the file
.Pa ssh_hosts
which have new or different keys from those in the sorted file
.Pa ssh_known_hosts :
.Bd -literal -offset indent
$ ssh-keyscan -t rsa,dsa,ecdsa,ed25519 -f ssh_hosts | \e
sort -u - ssh_known_hosts | diff ssh_known_hosts -
.Ed
.Sh SEE ALSO
.Xr ssh 1 ,
.Xr sshd 8
.Rs
.%D 2006
.%R RFC 4255
.%T Using DNS to Securely Publish Secure Shell (SSH) Key Fingerprints
.Re
.Sh AUTHORS
.An -nosplit
.An David Mazieres Aq Mt dm@lcs.mit.edu
wrote the initial version, and
.An Wayne Davison Aq Mt wayned@users.sourceforge.net
added support for protocol version 2.
diff --git a/crypto/openssh/ssh-keyscan.c b/crypto/openssh/ssh-keyscan.c
index d7283136c7d2..1318c2fa6fb7 100644
--- a/crypto/openssh/ssh-keyscan.c
+++ b/crypto/openssh/ssh-keyscan.c
@@ -1,836 +1,872 @@
-/* $OpenBSD: ssh-keyscan.c,v 1.146 2022/08/19 04:02:46 dtucker Exp $ */
+/* $OpenBSD: ssh-keyscan.c,v 1.149 2022/12/26 19:16:03 jmc Exp $ */
/*
* Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>.
*
* Modification and redistribution in source and binary forms is
* permitted provided that due credit is given to the author and the
* OpenBSD project by leaving this copyright notice intact.
*/
#include "includes.h"
#include <sys/types.h>
#include "openbsd-compat/sys-queue.h"
#include <sys/resource.h>
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
#endif
#include <netinet/in.h>
#include <arpa/inet.h>
#ifdef WITH_OPENSSL
#include <openssl/bn.h>
#endif
#include <netdb.h>
#include <errno.h>
#ifdef HAVE_POLL_H
#include <poll.h>
#endif
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include <unistd.h>
#include "xmalloc.h"
#include "ssh.h"
#include "sshbuf.h"
#include "sshkey.h"
#include "cipher.h"
#include "kex.h"
#include "compat.h"
#include "myproposal.h"
#include "packet.h"
#include "dispatch.h"
#include "log.h"
#include "atomicio.h"
#include "misc.h"
#include "hostfile.h"
#include "ssherr.h"
#include "ssh_api.h"
#include "dns.h"
+#include "addr.h"
/* Flag indicating whether IPv4 or IPv6. This can be set on the command line.
Default value is AF_UNSPEC means both IPv4 and IPv6. */
int IPv4or6 = AF_UNSPEC;
int ssh_port = SSH_DEFAULT_PORT;
#define KT_DSA (1)
#define KT_RSA (1<<1)
#define KT_ECDSA (1<<2)
#define KT_ED25519 (1<<3)
#define KT_XMSS (1<<4)
#define KT_ECDSA_SK (1<<5)
#define KT_ED25519_SK (1<<6)
#define KT_MIN KT_DSA
#define KT_MAX KT_ED25519_SK
int get_cert = 0;
int get_keytypes = KT_RSA|KT_ECDSA|KT_ED25519|KT_ECDSA_SK|KT_ED25519_SK;
int hash_hosts = 0; /* Hash hostname on output */
int print_sshfp = 0; /* Print SSHFP records instead of known_hosts */
int found_one = 0; /* Successfully found a key */
#define MAXMAXFD 256
/* The number of seconds after which to give up on a TCP connection */
int timeout = 5;
int maxfd;
#define MAXCON (maxfd - 10)
extern char *__progname;
struct pollfd *read_wait;
int ncon;
/*
* Keep a connection structure for each file descriptor. The state
* associated with file descriptor n is held in fdcon[n].
*/
typedef struct Connection {
u_char c_status; /* State of connection on this file desc. */
#define CS_UNUSED 0 /* File descriptor unused */
#define CS_CON 1 /* Waiting to connect/read greeting */
#define CS_SIZE 2 /* Waiting to read initial packet size */
#define CS_KEYS 3 /* Waiting to read public key packet */
int c_fd; /* Quick lookup: c->c_fd == c - fdcon */
int c_plen; /* Packet length field for ssh packet */
int c_len; /* Total bytes which must be read. */
int c_off; /* Length of data read so far. */
int c_keytype; /* Only one of KT_* */
sig_atomic_t c_done; /* SSH2 done */
char *c_namebase; /* Address to free for c_name and c_namelist */
char *c_name; /* Hostname of connection for errors */
char *c_namelist; /* Pointer to other possible addresses */
char *c_output_name; /* Hostname of connection for output */
char *c_data; /* Data read from this fd */
struct ssh *c_ssh; /* SSH-connection */
struct timespec c_ts; /* Time at which connection gets aborted */
TAILQ_ENTRY(Connection) c_link; /* List of connections in timeout order. */
} con;
TAILQ_HEAD(conlist, Connection) tq; /* Timeout Queue */
con *fdcon;
static void keyprint(con *c, struct sshkey *key);
static int
fdlim_get(int hard)
{
#if defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE)
struct rlimit rlfd;
if (getrlimit(RLIMIT_NOFILE, &rlfd) == -1)
return (-1);
if ((hard ? rlfd.rlim_max : rlfd.rlim_cur) == RLIM_INFINITY)
return SSH_SYSFDMAX;
else
return hard ? rlfd.rlim_max : rlfd.rlim_cur;
#else
return SSH_SYSFDMAX;
#endif
}
static int
fdlim_set(int lim)
{
#if defined(HAVE_SETRLIMIT) && defined(RLIMIT_NOFILE)
struct rlimit rlfd;
#endif
if (lim <= 0)
return (-1);
#if defined(HAVE_SETRLIMIT) && defined(RLIMIT_NOFILE)
if (getrlimit(RLIMIT_NOFILE, &rlfd) == -1)
return (-1);
rlfd.rlim_cur = lim;
if (setrlimit(RLIMIT_NOFILE, &rlfd) == -1)
return (-1);
#elif defined (HAVE_SETDTABLESIZE)
setdtablesize(lim);
#endif
return (0);
}
/*
* This is an strsep function that returns a null field for adjacent
* separators. This is the same as the 4.4BSD strsep, but different from the
* one in the GNU libc.
*/
static char *
xstrsep(char **str, const char *delim)
{
char *s, *e;
if (!**str)
return (NULL);
s = *str;
e = s + strcspn(s, delim);
if (*e != '\0')
*e++ = '\0';
*str = e;
return (s);
}
/*
* Get the next non-null token (like GNU strsep). Strsep() will return a
* null token for two adjacent separators, so we may have to loop.
*/
static char *
strnnsep(char **stringp, char *delim)
{
char *tok;
do {
tok = xstrsep(stringp, delim);
} while (tok && *tok == '\0');
return (tok);
}
static int
key_print_wrapper(struct sshkey *hostkey, struct ssh *ssh)
{
con *c;
if ((c = ssh_get_app_data(ssh)) != NULL)
keyprint(c, hostkey);
/* always abort key exchange */
return -1;
}
static int
ssh2_capable(int remote_major, int remote_minor)
{
switch (remote_major) {
case 1:
if (remote_minor == 99)
return 1;
break;
case 2:
return 1;
default:
break;
}
return 0;
}
static void
keygrab_ssh2(con *c)
{
char *myproposal[PROPOSAL_MAX] = { KEX_CLIENT };
int r;
switch (c->c_keytype) {
case KT_DSA:
myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = get_cert ?
"ssh-dss-cert-v01@openssh.com" : "ssh-dss";
break;
case KT_RSA:
myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = get_cert ?
"rsa-sha2-512-cert-v01@openssh.com,"
"rsa-sha2-256-cert-v01@openssh.com,"
"ssh-rsa-cert-v01@openssh.com" :
"rsa-sha2-512,"
"rsa-sha2-256,"
"ssh-rsa";
break;
case KT_ED25519:
myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = get_cert ?
"ssh-ed25519-cert-v01@openssh.com" : "ssh-ed25519";
break;
case KT_XMSS:
myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = get_cert ?
"ssh-xmss-cert-v01@openssh.com" : "ssh-xmss@openssh.com";
break;
case KT_ECDSA:
myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = get_cert ?
"ecdsa-sha2-nistp256-cert-v01@openssh.com,"
"ecdsa-sha2-nistp384-cert-v01@openssh.com,"
"ecdsa-sha2-nistp521-cert-v01@openssh.com" :
"ecdsa-sha2-nistp256,"
"ecdsa-sha2-nistp384,"
"ecdsa-sha2-nistp521";
break;
case KT_ECDSA_SK:
myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = get_cert ?
"sk-ecdsa-sha2-nistp256-cert-v01@openssh.com" :
"sk-ecdsa-sha2-nistp256@openssh.com";
break;
case KT_ED25519_SK:
myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = get_cert ?
"sk-ssh-ed25519-cert-v01@openssh.com" :
"sk-ssh-ed25519@openssh.com";
break;
default:
fatal("unknown key type %d", c->c_keytype);
break;
}
if ((r = kex_setup(c->c_ssh, myproposal)) != 0) {
free(c->c_ssh);
fprintf(stderr, "kex_setup: %s\n", ssh_err(r));
exit(1);
}
#ifdef WITH_OPENSSL
c->c_ssh->kex->kex[KEX_DH_GRP1_SHA1] = kex_gen_client;
c->c_ssh->kex->kex[KEX_DH_GRP14_SHA1] = kex_gen_client;
c->c_ssh->kex->kex[KEX_DH_GRP14_SHA256] = kex_gen_client;
c->c_ssh->kex->kex[KEX_DH_GRP16_SHA512] = kex_gen_client;
c->c_ssh->kex->kex[KEX_DH_GRP18_SHA512] = kex_gen_client;
c->c_ssh->kex->kex[KEX_DH_GEX_SHA1] = kexgex_client;
c->c_ssh->kex->kex[KEX_DH_GEX_SHA256] = kexgex_client;
# ifdef OPENSSL_HAS_ECC
c->c_ssh->kex->kex[KEX_ECDH_SHA2] = kex_gen_client;
# endif
#endif
c->c_ssh->kex->kex[KEX_C25519_SHA256] = kex_gen_client;
c->c_ssh->kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_client;
ssh_set_verify_host_key_callback(c->c_ssh, key_print_wrapper);
/*
* do the key-exchange until an error occurs or until
* the key_print_wrapper() callback sets c_done.
*/
ssh_dispatch_run(c->c_ssh, DISPATCH_BLOCK, &c->c_done);
}
static void
keyprint_one(const char *host, struct sshkey *key)
{
char *hostport = NULL, *hashed = NULL;
const char *known_host;
found_one = 1;
if (print_sshfp) {
export_dns_rr(host, key, stdout, 0);
return;
}
hostport = put_host_port(host, ssh_port);
lowercase(hostport);
if (hash_hosts && (hashed = host_hash(hostport, NULL, 0)) == NULL)
fatal("host_hash failed");
known_host = hash_hosts ? hashed : hostport;
if (!get_cert)
fprintf(stdout, "%s ", known_host);
sshkey_write(key, stdout);
fputs("\n", stdout);
free(hashed);
free(hostport);
}
static void
keyprint(con *c, struct sshkey *key)
{
char *hosts = c->c_output_name ? c->c_output_name : c->c_name;
char *host, *ohosts;
if (key == NULL)
return;
if (get_cert || (!hash_hosts && ssh_port == SSH_DEFAULT_PORT)) {
keyprint_one(hosts, key);
return;
}
ohosts = hosts = xstrdup(hosts);
while ((host = strsep(&hosts, ",")) != NULL)
keyprint_one(host, key);
free(ohosts);
}
static int
tcpconnect(char *host)
{
struct addrinfo hints, *ai, *aitop;
char strport[NI_MAXSERV];
int gaierr, s = -1;
snprintf(strport, sizeof strport, "%d", ssh_port);
memset(&hints, 0, sizeof(hints));
hints.ai_family = IPv4or6;
hints.ai_socktype = SOCK_STREAM;
if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0) {
error("getaddrinfo %s: %s", host, ssh_gai_strerror(gaierr));
return -1;
}
for (ai = aitop; ai; ai = ai->ai_next) {
s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
if (s == -1) {
error("socket: %s", strerror(errno));
continue;
}
if (set_nonblock(s) == -1)
fatal_f("set_nonblock(%d)", s);
if (connect(s, ai->ai_addr, ai->ai_addrlen) == -1 &&
errno != EINPROGRESS)
error("connect (`%s'): %s", host, strerror(errno));
else
break;
close(s);
s = -1;
}
freeaddrinfo(aitop);
return s;
}
static int
-conalloc(char *iname, char *oname, int keytype)
+conalloc(const char *iname, const char *oname, int keytype)
{
char *namebase, *name, *namelist;
int s;
namebase = namelist = xstrdup(iname);
do {
name = xstrsep(&namelist, ",");
if (!name) {
free(namebase);
return (-1);
}
} while ((s = tcpconnect(name)) < 0);
if (s >= maxfd)
fatal("conalloc: fdno %d too high", s);
if (fdcon[s].c_status)
fatal("conalloc: attempt to reuse fdno %d", s);
debug3_f("oname %s kt %d", oname, keytype);
fdcon[s].c_fd = s;
fdcon[s].c_status = CS_CON;
fdcon[s].c_namebase = namebase;
fdcon[s].c_name = name;
fdcon[s].c_namelist = namelist;
fdcon[s].c_output_name = xstrdup(oname);
fdcon[s].c_data = (char *) &fdcon[s].c_plen;
fdcon[s].c_len = 4;
fdcon[s].c_off = 0;
fdcon[s].c_keytype = keytype;
monotime_ts(&fdcon[s].c_ts);
fdcon[s].c_ts.tv_sec += timeout;
TAILQ_INSERT_TAIL(&tq, &fdcon[s], c_link);
read_wait[s].fd = s;
read_wait[s].events = POLLIN;
ncon++;
return (s);
}
static void
confree(int s)
{
if (s >= maxfd || fdcon[s].c_status == CS_UNUSED)
fatal("confree: attempt to free bad fdno %d", s);
free(fdcon[s].c_namebase);
free(fdcon[s].c_output_name);
if (fdcon[s].c_status == CS_KEYS)
free(fdcon[s].c_data);
fdcon[s].c_status = CS_UNUSED;
fdcon[s].c_keytype = 0;
if (fdcon[s].c_ssh) {
ssh_packet_close(fdcon[s].c_ssh);
free(fdcon[s].c_ssh);
fdcon[s].c_ssh = NULL;
} else
close(s);
TAILQ_REMOVE(&tq, &fdcon[s], c_link);
read_wait[s].fd = -1;
read_wait[s].events = 0;
ncon--;
}
static void
contouch(int s)
{
TAILQ_REMOVE(&tq, &fdcon[s], c_link);
monotime_ts(&fdcon[s].c_ts);
fdcon[s].c_ts.tv_sec += timeout;
TAILQ_INSERT_TAIL(&tq, &fdcon[s], c_link);
}
static int
conrecycle(int s)
{
con *c = &fdcon[s];
int ret;
ret = conalloc(c->c_namelist, c->c_output_name, c->c_keytype);
confree(s);
return (ret);
}
static void
congreet(int s)
{
int n = 0, remote_major = 0, remote_minor = 0;
char buf[256], *cp;
char remote_version[sizeof buf];
size_t bufsiz;
con *c = &fdcon[s];
/* send client banner */
n = snprintf(buf, sizeof buf, "SSH-%d.%d-OpenSSH-keyscan\r\n",
PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2);
if (n < 0 || (size_t)n >= sizeof(buf)) {
error("snprintf: buffer too small");
confree(s);
return;
}
if (atomicio(vwrite, s, buf, n) != (size_t)n) {
error("write (%s): %s", c->c_name, strerror(errno));
confree(s);
return;
}
/*
* Read the server banner as per RFC4253 section 4.2. The "SSH-"
- * protocol identification string may be preceeded by an arbitarily
+ * protocol identification string may be preceeded by an arbitrarily
* large banner which we must read and ignore. Loop while reading
* newline-terminated lines until we have one starting with "SSH-".
* The ID string cannot be longer than 255 characters although the
* preceeding banner lines may (in which case they'll be discarded
* in multiple iterations of the outer loop).
*/
for (;;) {
memset(buf, '\0', sizeof(buf));
bufsiz = sizeof(buf);
cp = buf;
while (bufsiz-- &&
(n = atomicio(read, s, cp, 1)) == 1 && *cp != '\n') {
if (*cp == '\r')
*cp = '\n';
cp++;
}
if (n != 1 || strncmp(buf, "SSH-", 4) == 0)
break;
}
if (n == 0) {
switch (errno) {
case EPIPE:
error("%s: Connection closed by remote host", c->c_name);
break;
case ECONNREFUSED:
break;
default:
error("read (%s): %s", c->c_name, strerror(errno));
break;
}
conrecycle(s);
return;
}
if (cp >= buf + sizeof(buf)) {
error("%s: greeting exceeds allowable length", c->c_name);
confree(s);
return;
}
if (*cp != '\n' && *cp != '\r') {
error("%s: bad greeting", c->c_name);
confree(s);
return;
}
*cp = '\0';
if ((c->c_ssh = ssh_packet_set_connection(NULL, s, s)) == NULL)
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)
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);
return;
}
fprintf(stderr, "%c %s:%d %s\n", print_sshfp ? ';' : '#',
c->c_name, ssh_port, chop(buf));
keygrab_ssh2(c);
confree(s);
}
static void
conread(int s)
{
con *c = &fdcon[s];
size_t n;
if (c->c_status == CS_CON) {
congreet(s);
return;
}
n = atomicio(read, s, c->c_data + c->c_off, c->c_len - c->c_off);
if (n == 0) {
error("read (%s): %s", c->c_name, strerror(errno));
confree(s);
return;
}
c->c_off += n;
if (c->c_off == c->c_len)
switch (c->c_status) {
case CS_SIZE:
c->c_plen = htonl(c->c_plen);
c->c_len = c->c_plen + 8 - (c->c_plen & 7);
c->c_off = 0;
c->c_data = xmalloc(c->c_len);
c->c_status = CS_KEYS;
break;
default:
fatal("conread: invalid status %d", c->c_status);
break;
}
contouch(s);
}
static void
conloop(void)
{
struct timespec seltime, now;
con *c;
int i;
monotime_ts(&now);
c = TAILQ_FIRST(&tq);
if (c && timespeccmp(&c->c_ts, &now, >))
timespecsub(&c->c_ts, &now, &seltime);
else
timespecclear(&seltime);
while (ppoll(read_wait, maxfd, &seltime, NULL) == -1) {
if (errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK)
continue;
error("poll error");
}
for (i = 0; i < maxfd; i++) {
if (read_wait[i].revents & (POLLHUP|POLLERR|POLLNVAL))
confree(i);
else if (read_wait[i].revents & (POLLIN|POLLHUP))
conread(i);
}
c = TAILQ_FIRST(&tq);
while (c && timespeccmp(&c->c_ts, &now, <)) {
int s = c->c_fd;
c = TAILQ_NEXT(c, c_link);
conrecycle(s);
}
}
static void
-do_host(char *host)
+do_one_host(char *host)
{
char *name = strnnsep(&host, " \t\n");
int j;
if (name == NULL)
return;
for (j = KT_MIN; j <= KT_MAX; j *= 2) {
if (get_keytypes & j) {
while (ncon >= MAXCON)
conloop();
conalloc(name, *host ? host : name, j);
}
}
}
+static void
+do_host(char *host)
+{
+ char daddr[128];
+ struct xaddr addr, end_addr;
+ u_int masklen;
+
+ if (host == NULL)
+ return;
+ if (addr_pton_cidr(host, &addr, &masklen) != 0) {
+ /* Assume argument is a hostname */
+ do_one_host(host);
+ } else {
+ /* Argument is a CIDR range */
+ debug("CIDR range %s", host);
+ end_addr = addr;
+ if (addr_host_to_all1s(&end_addr, masklen) != 0)
+ goto badaddr;
+ /*
+ * Note: we deliberately include the all-zero/ones addresses.
+ */
+ for (;;) {
+ if (addr_ntop(&addr, daddr, sizeof(daddr)) != 0) {
+ badaddr:
+ error("Invalid address %s", host);
+ return;
+ }
+ debug("CIDR expand: address %s", daddr);
+ do_one_host(daddr);
+ if (addr_cmp(&addr, &end_addr) == 0)
+ break;
+ addr_increment(&addr);
+ };
+ }
+}
+
void
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);
sshlogv(file, func, line, showfunc, level, suffix, fmt, args);
va_end(args);
cleanup_exit(255);
}
static void
usage(void)
{
fprintf(stderr,
"usage: %s [-46cDHv] [-f file] [-p port] [-T timeout] [-t type]\n"
"\t\t [host | addrlist namelist]\n",
__progname);
exit(1);
}
int
main(int argc, char **argv)
{
int debug_flag = 0, log_level = SYSLOG_LEVEL_INFO;
int opt, fopt_count = 0, j;
char *tname, *cp, *line = NULL;
size_t linesize = 0;
FILE *fp;
extern int optind;
extern char *optarg;
__progname = ssh_get_progname(argv[0]);
seed_rng();
TAILQ_INIT(&tq);
/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
sanitise_stdfd();
if (argc <= 1)
usage();
while ((opt = getopt(argc, argv, "cDHv46p:T:t:f:")) != -1) {
switch (opt) {
case 'H':
hash_hosts = 1;
break;
case 'c':
get_cert = 1;
break;
case 'D':
print_sshfp = 1;
break;
case 'p':
ssh_port = a2port(optarg);
if (ssh_port <= 0) {
fprintf(stderr, "Bad port '%s'\n", optarg);
exit(1);
}
break;
case 'T':
timeout = convtime(optarg);
if (timeout == -1 || timeout == 0) {
fprintf(stderr, "Bad timeout '%s'\n", optarg);
usage();
}
break;
case 'v':
if (!debug_flag) {
debug_flag = 1;
log_level = SYSLOG_LEVEL_DEBUG1;
}
else if (log_level < SYSLOG_LEVEL_DEBUG3)
log_level++;
else
fatal("Too high debugging level.");
break;
case 'f':
if (strcmp(optarg, "-") == 0)
optarg = NULL;
argv[fopt_count++] = optarg;
break;
case 't':
get_keytypes = 0;
tname = strtok(optarg, ",");
while (tname) {
int type = sshkey_type_from_name(tname);
switch (type) {
case KEY_DSA:
get_keytypes |= KT_DSA;
break;
case KEY_ECDSA:
get_keytypes |= KT_ECDSA;
break;
case KEY_RSA:
get_keytypes |= KT_RSA;
break;
case KEY_ED25519:
get_keytypes |= KT_ED25519;
break;
case KEY_XMSS:
get_keytypes |= KT_XMSS;
break;
case KEY_ED25519_SK:
get_keytypes |= KT_ED25519_SK;
break;
case KEY_ECDSA_SK:
get_keytypes |= KT_ECDSA_SK;
break;
case KEY_UNSPEC:
default:
fatal("Unknown key type \"%s\"", tname);
}
tname = strtok(NULL, ",");
}
break;
case '4':
IPv4or6 = AF_INET;
break;
case '6':
IPv4or6 = AF_INET6;
break;
- case '?':
default:
usage();
}
}
if (optind == argc && !fopt_count)
usage();
log_init("ssh-keyscan", log_level, SYSLOG_FACILITY_USER, 1);
maxfd = fdlim_get(1);
if (maxfd < 0)
fatal("%s: fdlim_get: bad value", __progname);
if (maxfd > MAXMAXFD)
maxfd = MAXMAXFD;
if (MAXCON <= 0)
fatal("%s: not enough file descriptors", __progname);
if (maxfd > fdlim_get(0))
fdlim_set(maxfd);
fdcon = xcalloc(maxfd, sizeof(con));
read_wait = xcalloc(maxfd, sizeof(struct pollfd));
for (j = 0; j < maxfd; j++)
read_wait[j].fd = -1;
for (j = 0; j < fopt_count; j++) {
if (argv[j] == NULL)
fp = stdin;
else if ((fp = fopen(argv[j], "r")) == NULL)
fatal("%s: %s: %s", __progname, argv[j], strerror(errno));
while (getline(&line, &linesize, fp) != -1) {
/* Chomp off trailing whitespace and comments */
if ((cp = strchr(line, '#')) == NULL)
cp = line + strlen(line) - 1;
while (cp >= line) {
if (*cp == ' ' || *cp == '\t' ||
*cp == '\n' || *cp == '#')
*cp-- = '\0';
else
break;
}
/* Skip empty lines */
if (*line == '\0')
continue;
do_host(line);
}
if (ferror(fp))
fatal("%s: %s: %s", __progname, argv[j], strerror(errno));
fclose(fp);
}
free(line);
while (optind < argc)
do_host(argv[optind++]);
while (ncon > 0)
conloop();
return found_one ? 0 : 1;
}
diff --git a/crypto/openssh/ssh-rsa.c b/crypto/openssh/ssh-rsa.c
index 9b14f9a9a715..6516ddc13acd 100644
--- a/crypto/openssh/ssh-rsa.c
+++ b/crypto/openssh/ssh-rsa.c
@@ -1,449 +1,769 @@
-/* $OpenBSD: ssh-rsa.c,v 1.67 2018/07/03 11:39:54 djm Exp $ */
+/* $OpenBSD: ssh-rsa.c,v 1.78 2022/10/28 02:47:04 djm Exp $ */
/*
* Copyright (c) 2000, 2003 Markus Friedl <markus@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"
#ifdef WITH_OPENSSL
#include <sys/types.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include <stdarg.h>
#include <string.h>
#include "sshbuf.h"
#include "compat.h"
#include "ssherr.h"
#define SSHKEY_INTERNAL
#include "sshkey.h"
#include "digest.h"
#include "log.h"
#include "openbsd-compat/openssl-compat.h"
static int openssh_RSA_verify(int, u_char *, size_t, u_char *, size_t, RSA *);
+static u_int
+ssh_rsa_size(const struct sshkey *key)
+{
+ const BIGNUM *rsa_n;
+
+ if (key->rsa == NULL)
+ return 0;
+ RSA_get0_key(key->rsa, &rsa_n, NULL, NULL);
+ return BN_num_bits(rsa_n);
+}
+
+static int
+ssh_rsa_alloc(struct sshkey *k)
+{
+ if ((k->rsa = RSA_new()) == NULL)
+ return SSH_ERR_ALLOC_FAIL;
+ return 0;
+}
+
+static void
+ssh_rsa_cleanup(struct sshkey *k)
+{
+ RSA_free(k->rsa);
+ k->rsa = NULL;
+}
+
+static int
+ssh_rsa_equal(const struct sshkey *a, const struct sshkey *b)
+{
+ const BIGNUM *rsa_e_a, *rsa_n_a;
+ const BIGNUM *rsa_e_b, *rsa_n_b;
+
+ if (a->rsa == NULL || b->rsa == NULL)
+ return 0;
+ RSA_get0_key(a->rsa, &rsa_n_a, &rsa_e_a, NULL);
+ RSA_get0_key(b->rsa, &rsa_n_b, &rsa_e_b, NULL);
+ if (rsa_e_a == NULL || rsa_e_b == NULL)
+ return 0;
+ if (rsa_n_a == NULL || rsa_n_b == NULL)
+ return 0;
+ if (BN_cmp(rsa_e_a, rsa_e_b) != 0)
+ return 0;
+ if (BN_cmp(rsa_n_a, rsa_n_b) != 0)
+ return 0;
+ return 1;
+}
+
+static int
+ssh_rsa_serialize_public(const struct sshkey *key, struct sshbuf *b,
+ enum sshkey_serialize_rep opts)
+{
+ int r;
+ const BIGNUM *rsa_n, *rsa_e;
+
+ if (key->rsa == NULL)
+ return SSH_ERR_INVALID_ARGUMENT;
+ RSA_get0_key(key->rsa, &rsa_n, &rsa_e, NULL);
+ if ((r = sshbuf_put_bignum2(b, rsa_e)) != 0 ||
+ (r = sshbuf_put_bignum2(b, rsa_n)) != 0)
+ return r;
+
+ return 0;
+}
+
+static int
+ssh_rsa_serialize_private(const struct sshkey *key, struct sshbuf *b,
+ enum sshkey_serialize_rep opts)
+{
+ int r;
+ const BIGNUM *rsa_n, *rsa_e, *rsa_d, *rsa_iqmp, *rsa_p, *rsa_q;
+
+ RSA_get0_key(key->rsa, &rsa_n, &rsa_e, &rsa_d);
+ RSA_get0_factors(key->rsa, &rsa_p, &rsa_q);
+ RSA_get0_crt_params(key->rsa, NULL, NULL, &rsa_iqmp);
+
+ if (!sshkey_is_cert(key)) {
+ /* Note: can't reuse ssh_rsa_serialize_public: e, n vs. n, e */
+ if ((r = sshbuf_put_bignum2(b, rsa_n)) != 0 ||
+ (r = sshbuf_put_bignum2(b, rsa_e)) != 0)
+ return r;
+ }
+ if ((r = sshbuf_put_bignum2(b, rsa_d)) != 0 ||
+ (r = sshbuf_put_bignum2(b, rsa_iqmp)) != 0 ||
+ (r = sshbuf_put_bignum2(b, rsa_p)) != 0 ||
+ (r = sshbuf_put_bignum2(b, rsa_q)) != 0)
+ return r;
+
+ return 0;
+}
+
+static int
+ssh_rsa_generate(struct sshkey *k, int bits)
+{
+ RSA *private = NULL;
+ BIGNUM *f4 = NULL;
+ int ret = SSH_ERR_INTERNAL_ERROR;
+
+ if (bits < SSH_RSA_MINIMUM_MODULUS_SIZE ||
+ bits > SSHBUF_MAX_BIGNUM * 8)
+ return SSH_ERR_KEY_LENGTH;
+ if ((private = RSA_new()) == NULL || (f4 = BN_new()) == NULL) {
+ ret = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ if (!BN_set_word(f4, RSA_F4) ||
+ !RSA_generate_key_ex(private, bits, f4, NULL)) {
+ ret = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ k->rsa = private;
+ private = NULL;
+ ret = 0;
+ out:
+ RSA_free(private);
+ BN_free(f4);
+ return ret;
+}
+
+static int
+ssh_rsa_copy_public(const struct sshkey *from, struct sshkey *to)
+{
+ const BIGNUM *rsa_n, *rsa_e;
+ BIGNUM *rsa_n_dup = NULL, *rsa_e_dup = NULL;
+ int r = SSH_ERR_INTERNAL_ERROR;
+
+ RSA_get0_key(from->rsa, &rsa_n, &rsa_e, NULL);
+ if ((rsa_n_dup = BN_dup(rsa_n)) == NULL ||
+ (rsa_e_dup = BN_dup(rsa_e)) == NULL) {
+ r = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ if (!RSA_set0_key(to->rsa, rsa_n_dup, rsa_e_dup, NULL)) {
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ rsa_n_dup = rsa_e_dup = NULL; /* transferred */
+ /* success */
+ r = 0;
+ out:
+ BN_clear_free(rsa_n_dup);
+ BN_clear_free(rsa_e_dup);
+ return r;
+}
+
+static int
+ssh_rsa_deserialize_public(const char *ktype, struct sshbuf *b,
+ struct sshkey *key)
+{
+ int ret = SSH_ERR_INTERNAL_ERROR;
+ BIGNUM *rsa_n = NULL, *rsa_e = NULL;
+
+ if (sshbuf_get_bignum2(b, &rsa_e) != 0 ||
+ sshbuf_get_bignum2(b, &rsa_n) != 0) {
+ ret = SSH_ERR_INVALID_FORMAT;
+ goto out;
+ }
+ if (!RSA_set0_key(key->rsa, rsa_n, rsa_e, NULL)) {
+ ret = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ rsa_n = rsa_e = NULL; /* transferred */
+ if ((ret = sshkey_check_rsa_length(key, 0)) != 0)
+ goto out;
+#ifdef DEBUG_PK
+ RSA_print_fp(stderr, key->rsa, 8);
+#endif
+ /* success */
+ ret = 0;
+ out:
+ BN_clear_free(rsa_n);
+ BN_clear_free(rsa_e);
+ return ret;
+}
+
+static int
+ssh_rsa_deserialize_private(const char *ktype, struct sshbuf *b,
+ struct sshkey *key)
+{
+ int r;
+ BIGNUM *rsa_n = NULL, *rsa_e = NULL, *rsa_d = NULL;
+ BIGNUM *rsa_iqmp = NULL, *rsa_p = NULL, *rsa_q = NULL;
+
+ /* Note: can't reuse ssh_rsa_deserialize_public: e, n vs. n, e */
+ if (!sshkey_is_cert(key)) {
+ if ((r = sshbuf_get_bignum2(b, &rsa_n)) != 0 ||
+ (r = sshbuf_get_bignum2(b, &rsa_e)) != 0)
+ goto out;
+ if (!RSA_set0_key(key->rsa, rsa_n, rsa_e, NULL)) {
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ rsa_n = rsa_e = NULL; /* transferred */
+ }
+ if ((r = sshbuf_get_bignum2(b, &rsa_d)) != 0 ||
+ (r = sshbuf_get_bignum2(b, &rsa_iqmp)) != 0 ||
+ (r = sshbuf_get_bignum2(b, &rsa_p)) != 0 ||
+ (r = sshbuf_get_bignum2(b, &rsa_q)) != 0)
+ goto out;
+ if (!RSA_set0_key(key->rsa, NULL, NULL, rsa_d)) {
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ rsa_d = NULL; /* transferred */
+ if (!RSA_set0_factors(key->rsa, rsa_p, rsa_q)) {
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ rsa_p = rsa_q = NULL; /* transferred */
+ if ((r = sshkey_check_rsa_length(key, 0)) != 0)
+ goto out;
+ if ((r = ssh_rsa_complete_crt_parameters(key, rsa_iqmp)) != 0)
+ goto out;
+ if (RSA_blinding_on(key->rsa, NULL) != 1) {
+ r = SSH_ERR_LIBCRYPTO_ERROR;
+ goto out;
+ }
+ /* success */
+ r = 0;
+ out:
+ BN_clear_free(rsa_n);
+ BN_clear_free(rsa_e);
+ BN_clear_free(rsa_d);
+ BN_clear_free(rsa_p);
+ BN_clear_free(rsa_q);
+ BN_clear_free(rsa_iqmp);
+ return r;
+}
+
static const char *
rsa_hash_alg_ident(int hash_alg)
{
switch (hash_alg) {
case SSH_DIGEST_SHA1:
return "ssh-rsa";
case SSH_DIGEST_SHA256:
return "rsa-sha2-256";
case SSH_DIGEST_SHA512:
return "rsa-sha2-512";
}
return NULL;
}
/*
* Returns the hash algorithm ID for a given algorithm identifier as used
* inside the signature blob,
*/
static int
rsa_hash_id_from_ident(const char *ident)
{
if (strcmp(ident, "ssh-rsa") == 0)
return SSH_DIGEST_SHA1;
if (strcmp(ident, "rsa-sha2-256") == 0)
return SSH_DIGEST_SHA256;
if (strcmp(ident, "rsa-sha2-512") == 0)
return SSH_DIGEST_SHA512;
return -1;
}
/*
* Return the hash algorithm ID for the specified key name. This includes
* all the cases of rsa_hash_id_from_ident() but also the certificate key
* types.
*/
static int
rsa_hash_id_from_keyname(const char *alg)
{
int r;
if ((r = rsa_hash_id_from_ident(alg)) != -1)
return r;
if (strcmp(alg, "ssh-rsa-cert-v01@openssh.com") == 0)
return SSH_DIGEST_SHA1;
if (strcmp(alg, "rsa-sha2-256-cert-v01@openssh.com") == 0)
return SSH_DIGEST_SHA256;
if (strcmp(alg, "rsa-sha2-512-cert-v01@openssh.com") == 0)
return SSH_DIGEST_SHA512;
return -1;
}
static int
rsa_hash_alg_nid(int type)
{
switch (type) {
case SSH_DIGEST_SHA1:
return NID_sha1;
case SSH_DIGEST_SHA256:
return NID_sha256;
case SSH_DIGEST_SHA512:
return NID_sha512;
default:
return -1;
}
}
int
ssh_rsa_complete_crt_parameters(struct sshkey *key, const BIGNUM *iqmp)
{
const BIGNUM *rsa_p, *rsa_q, *rsa_d;
BIGNUM *aux = NULL, *d_consttime = NULL;
BIGNUM *rsa_dmq1 = NULL, *rsa_dmp1 = NULL, *rsa_iqmp = NULL;
BN_CTX *ctx = NULL;
int r;
if (key == NULL || key->rsa == NULL ||
sshkey_type_plain(key->type) != KEY_RSA)
return SSH_ERR_INVALID_ARGUMENT;
RSA_get0_key(key->rsa, NULL, NULL, &rsa_d);
RSA_get0_factors(key->rsa, &rsa_p, &rsa_q);
if ((ctx = BN_CTX_new()) == NULL)
return SSH_ERR_ALLOC_FAIL;
if ((aux = BN_new()) == NULL ||
(rsa_dmq1 = BN_new()) == NULL ||
(rsa_dmp1 = BN_new()) == NULL)
return SSH_ERR_ALLOC_FAIL;
if ((d_consttime = BN_dup(rsa_d)) == NULL ||
(rsa_iqmp = BN_dup(iqmp)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
BN_set_flags(aux, BN_FLG_CONSTTIME);
BN_set_flags(d_consttime, BN_FLG_CONSTTIME);
if ((BN_sub(aux, rsa_q, BN_value_one()) == 0) ||
(BN_mod(rsa_dmq1, d_consttime, aux, ctx) == 0) ||
(BN_sub(aux, rsa_p, BN_value_one()) == 0) ||
(BN_mod(rsa_dmp1, d_consttime, aux, ctx) == 0)) {
r = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
if (!RSA_set0_crt_params(key->rsa, rsa_dmp1, rsa_dmq1, rsa_iqmp)) {
r = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
rsa_dmp1 = rsa_dmq1 = rsa_iqmp = NULL; /* transferred */
/* success */
r = 0;
out:
BN_clear_free(aux);
BN_clear_free(d_consttime);
BN_clear_free(rsa_dmp1);
BN_clear_free(rsa_dmq1);
BN_clear_free(rsa_iqmp);
BN_CTX_free(ctx);
return r;
}
/* RSASSA-PKCS1-v1_5 (PKCS #1 v2.0 signature) with SHA1 */
-int
-ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
- const u_char *data, size_t datalen, const char *alg_ident)
+static int
+ssh_rsa_sign(struct sshkey *key,
+ u_char **sigp, size_t *lenp,
+ const u_char *data, size_t datalen,
+ const char *alg, const char *sk_provider, const char *sk_pin, u_int compat)
{
const BIGNUM *rsa_n;
u_char digest[SSH_DIGEST_MAX_LENGTH], *sig = NULL;
size_t slen = 0;
- u_int dlen, len;
+ u_int hlen, len;
int nid, hash_alg, ret = SSH_ERR_INTERNAL_ERROR;
struct sshbuf *b = NULL;
if (lenp != NULL)
*lenp = 0;
if (sigp != NULL)
*sigp = NULL;
- if (alg_ident == NULL || strlen(alg_ident) == 0)
+ if (alg == NULL || strlen(alg) == 0)
hash_alg = SSH_DIGEST_SHA1;
else
- hash_alg = rsa_hash_id_from_keyname(alg_ident);
+ hash_alg = rsa_hash_id_from_keyname(alg);
if (key == NULL || key->rsa == NULL || hash_alg == -1 ||
sshkey_type_plain(key->type) != KEY_RSA)
return SSH_ERR_INVALID_ARGUMENT;
RSA_get0_key(key->rsa, &rsa_n, NULL, NULL);
if (BN_num_bits(rsa_n) < SSH_RSA_MINIMUM_MODULUS_SIZE)
return SSH_ERR_KEY_LENGTH;
slen = RSA_size(key->rsa);
if (slen <= 0 || slen > SSHBUF_MAX_BIGNUM)
return SSH_ERR_INVALID_ARGUMENT;
/* hash the data */
nid = rsa_hash_alg_nid(hash_alg);
- if ((dlen = ssh_digest_bytes(hash_alg)) == 0)
+ if ((hlen = ssh_digest_bytes(hash_alg)) == 0)
return SSH_ERR_INTERNAL_ERROR;
if ((ret = ssh_digest_memory(hash_alg, data, datalen,
digest, sizeof(digest))) != 0)
goto out;
if ((sig = malloc(slen)) == NULL) {
ret = SSH_ERR_ALLOC_FAIL;
goto out;
}
- if (RSA_sign(nid, digest, dlen, sig, &len, key->rsa) != 1) {
+ if (RSA_sign(nid, digest, hlen, sig, &len, key->rsa) != 1) {
ret = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
if (len < slen) {
size_t diff = slen - len;
memmove(sig + diff, sig, len);
explicit_bzero(sig, diff);
} else if (len > slen) {
ret = SSH_ERR_INTERNAL_ERROR;
goto out;
}
/* encode signature */
if ((b = sshbuf_new()) == NULL) {
ret = SSH_ERR_ALLOC_FAIL;
goto out;
}
if ((ret = sshbuf_put_cstring(b, rsa_hash_alg_ident(hash_alg))) != 0 ||
(ret = sshbuf_put_string(b, sig, slen)) != 0)
goto out;
len = sshbuf_len(b);
if (sigp != NULL) {
if ((*sigp = malloc(len)) == NULL) {
ret = SSH_ERR_ALLOC_FAIL;
goto out;
}
memcpy(*sigp, sshbuf_ptr(b), len);
}
if (lenp != NULL)
*lenp = len;
ret = 0;
out:
explicit_bzero(digest, sizeof(digest));
freezero(sig, slen);
sshbuf_free(b);
return ret;
}
-int
+static int
ssh_rsa_verify(const struct sshkey *key,
- const u_char *sig, size_t siglen, const u_char *data, size_t datalen,
- const char *alg)
+ const u_char *sig, size_t siglen,
+ const u_char *data, size_t dlen, const char *alg, u_int compat,
+ struct sshkey_sig_details **detailsp)
{
const BIGNUM *rsa_n;
char *sigtype = NULL;
int hash_alg, want_alg, ret = SSH_ERR_INTERNAL_ERROR;
- size_t len = 0, diff, modlen, dlen;
+ size_t len = 0, diff, modlen, hlen;
struct sshbuf *b = NULL;
u_char digest[SSH_DIGEST_MAX_LENGTH], *osigblob, *sigblob = NULL;
if (key == NULL || key->rsa == NULL ||
sshkey_type_plain(key->type) != KEY_RSA ||
sig == NULL || siglen == 0)
return SSH_ERR_INVALID_ARGUMENT;
RSA_get0_key(key->rsa, &rsa_n, NULL, NULL);
if (BN_num_bits(rsa_n) < SSH_RSA_MINIMUM_MODULUS_SIZE)
return SSH_ERR_KEY_LENGTH;
if ((b = sshbuf_from(sig, siglen)) == NULL)
return SSH_ERR_ALLOC_FAIL;
if (sshbuf_get_cstring(b, &sigtype, NULL) != 0) {
ret = SSH_ERR_INVALID_FORMAT;
goto out;
}
if ((hash_alg = rsa_hash_id_from_ident(sigtype)) == -1) {
ret = SSH_ERR_KEY_TYPE_MISMATCH;
goto out;
}
/*
* Allow ssh-rsa-cert-v01 certs to generate SHA2 signatures for
* legacy reasons, but otherwise the signature type should match.
*/
if (alg != NULL && strcmp(alg, "ssh-rsa-cert-v01@openssh.com") != 0) {
if ((want_alg = rsa_hash_id_from_keyname(alg)) == -1) {
ret = SSH_ERR_INVALID_ARGUMENT;
goto out;
}
if (hash_alg != want_alg) {
ret = SSH_ERR_SIGNATURE_INVALID;
goto out;
}
}
if (sshbuf_get_string(b, &sigblob, &len) != 0) {
ret = SSH_ERR_INVALID_FORMAT;
goto out;
}
if (sshbuf_len(b) != 0) {
ret = SSH_ERR_UNEXPECTED_TRAILING_DATA;
goto out;
}
/* RSA_verify expects a signature of RSA_size */
modlen = RSA_size(key->rsa);
if (len > modlen) {
ret = SSH_ERR_KEY_BITS_MISMATCH;
goto out;
} else if (len < modlen) {
diff = modlen - len;
osigblob = sigblob;
if ((sigblob = realloc(sigblob, modlen)) == NULL) {
sigblob = osigblob; /* put it back for clear/free */
ret = SSH_ERR_ALLOC_FAIL;
goto out;
}
memmove(sigblob + diff, sigblob, len);
explicit_bzero(sigblob, diff);
len = modlen;
}
- if ((dlen = ssh_digest_bytes(hash_alg)) == 0) {
+ if ((hlen = ssh_digest_bytes(hash_alg)) == 0) {
ret = SSH_ERR_INTERNAL_ERROR;
goto out;
}
- if ((ret = ssh_digest_memory(hash_alg, data, datalen,
+ if ((ret = ssh_digest_memory(hash_alg, data, dlen,
digest, sizeof(digest))) != 0)
goto out;
- ret = openssh_RSA_verify(hash_alg, digest, dlen, sigblob, len,
+ ret = openssh_RSA_verify(hash_alg, digest, hlen, sigblob, len,
key->rsa);
out:
freezero(sigblob, len);
free(sigtype);
sshbuf_free(b);
explicit_bzero(digest, sizeof(digest));
return ret;
}
/*
* See:
* http://www.rsasecurity.com/rsalabs/pkcs/pkcs-1/
* ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1.asn
*/
/*
* id-sha1 OBJECT IDENTIFIER ::= { iso(1) identified-organization(3)
* oiw(14) secsig(3) algorithms(2) 26 }
*/
static const u_char id_sha1[] = {
0x30, 0x21, /* type Sequence, length 0x21 (33) */
0x30, 0x09, /* type Sequence, length 0x09 */
0x06, 0x05, /* type OID, length 0x05 */
0x2b, 0x0e, 0x03, 0x02, 0x1a, /* id-sha1 OID */
0x05, 0x00, /* NULL */
0x04, 0x14 /* Octet string, length 0x14 (20), followed by sha1 hash */
};
/*
* See http://csrc.nist.gov/groups/ST/crypto_apps_infra/csor/algorithms.html
* id-sha256 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840)
* organization(1) gov(101) csor(3) nistAlgorithm(4) hashAlgs(2)
* id-sha256(1) }
*/
static const u_char id_sha256[] = {
0x30, 0x31, /* type Sequence, length 0x31 (49) */
0x30, 0x0d, /* type Sequence, length 0x0d (13) */
0x06, 0x09, /* type OID, length 0x09 */
0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, /* id-sha256 */
0x05, 0x00, /* NULL */
0x04, 0x20 /* Octet string, length 0x20 (32), followed by sha256 hash */
};
/*
* See http://csrc.nist.gov/groups/ST/crypto_apps_infra/csor/algorithms.html
* id-sha512 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840)
* organization(1) gov(101) csor(3) nistAlgorithm(4) hashAlgs(2)
* id-sha256(3) }
*/
static const u_char id_sha512[] = {
0x30, 0x51, /* type Sequence, length 0x51 (81) */
0x30, 0x0d, /* type Sequence, length 0x0d (13) */
0x06, 0x09, /* type OID, length 0x09 */
0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, /* id-sha512 */
0x05, 0x00, /* NULL */
0x04, 0x40 /* Octet string, length 0x40 (64), followed by sha512 hash */
};
static int
rsa_hash_alg_oid(int hash_alg, const u_char **oidp, size_t *oidlenp)
{
switch (hash_alg) {
case SSH_DIGEST_SHA1:
*oidp = id_sha1;
*oidlenp = sizeof(id_sha1);
break;
case SSH_DIGEST_SHA256:
*oidp = id_sha256;
*oidlenp = sizeof(id_sha256);
break;
case SSH_DIGEST_SHA512:
*oidp = id_sha512;
*oidlenp = sizeof(id_sha512);
break;
default:
return SSH_ERR_INVALID_ARGUMENT;
}
return 0;
}
static int
openssh_RSA_verify(int hash_alg, u_char *hash, size_t hashlen,
u_char *sigbuf, size_t siglen, RSA *rsa)
{
size_t rsasize = 0, oidlen = 0, hlen = 0;
int ret, len, oidmatch, hashmatch;
const u_char *oid = NULL;
u_char *decrypted = NULL;
if ((ret = rsa_hash_alg_oid(hash_alg, &oid, &oidlen)) != 0)
return ret;
ret = SSH_ERR_INTERNAL_ERROR;
hlen = ssh_digest_bytes(hash_alg);
if (hashlen != hlen) {
ret = SSH_ERR_INVALID_ARGUMENT;
goto done;
}
rsasize = RSA_size(rsa);
if (rsasize <= 0 || rsasize > SSHBUF_MAX_BIGNUM ||
siglen == 0 || siglen > rsasize) {
ret = SSH_ERR_INVALID_ARGUMENT;
goto done;
}
if ((decrypted = malloc(rsasize)) == NULL) {
ret = SSH_ERR_ALLOC_FAIL;
goto done;
}
if ((len = RSA_public_decrypt(siglen, sigbuf, decrypted, rsa,
RSA_PKCS1_PADDING)) < 0) {
ret = SSH_ERR_LIBCRYPTO_ERROR;
goto done;
}
if (len < 0 || (size_t)len != hlen + oidlen) {
ret = SSH_ERR_INVALID_FORMAT;
goto done;
}
oidmatch = timingsafe_bcmp(decrypted, oid, oidlen) == 0;
hashmatch = timingsafe_bcmp(decrypted + oidlen, hash, hlen) == 0;
if (!oidmatch || !hashmatch) {
ret = SSH_ERR_SIGNATURE_INVALID;
goto done;
}
ret = 0;
done:
freezero(decrypted, rsasize);
return ret;
}
+
+static const struct sshkey_impl_funcs sshkey_rsa_funcs = {
+ /* .size = */ ssh_rsa_size,
+ /* .alloc = */ ssh_rsa_alloc,
+ /* .cleanup = */ ssh_rsa_cleanup,
+ /* .equal = */ ssh_rsa_equal,
+ /* .ssh_serialize_public = */ ssh_rsa_serialize_public,
+ /* .ssh_deserialize_public = */ ssh_rsa_deserialize_public,
+ /* .ssh_serialize_private = */ ssh_rsa_serialize_private,
+ /* .ssh_deserialize_private = */ ssh_rsa_deserialize_private,
+ /* .generate = */ ssh_rsa_generate,
+ /* .copy_public = */ ssh_rsa_copy_public,
+ /* .sign = */ ssh_rsa_sign,
+ /* .verify = */ ssh_rsa_verify,
+};
+
+const struct sshkey_impl sshkey_rsa_impl = {
+ /* .name = */ "ssh-rsa",
+ /* .shortname = */ "RSA",
+ /* .sigalg = */ NULL,
+ /* .type = */ KEY_RSA,
+ /* .nid = */ 0,
+ /* .cert = */ 0,
+ /* .sigonly = */ 0,
+ /* .keybits = */ 0,
+ /* .funcs = */ &sshkey_rsa_funcs,
+};
+
+const struct sshkey_impl sshkey_rsa_cert_impl = {
+ /* .name = */ "ssh-rsa-cert-v01@openssh.com",
+ /* .shortname = */ "RSA-CERT",
+ /* .sigalg = */ NULL,
+ /* .type = */ KEY_RSA_CERT,
+ /* .nid = */ 0,
+ /* .cert = */ 1,
+ /* .sigonly = */ 0,
+ /* .keybits = */ 0,
+ /* .funcs = */ &sshkey_rsa_funcs,
+};
+
+/* SHA2 signature algorithms */
+
+const struct sshkey_impl sshkey_rsa_sha256_impl = {
+ /* .name = */ "rsa-sha2-256",
+ /* .shortname = */ "RSA",
+ /* .sigalg = */ NULL,
+ /* .type = */ KEY_RSA,
+ /* .nid = */ 0,
+ /* .cert = */ 0,
+ /* .sigonly = */ 1,
+ /* .keybits = */ 0,
+ /* .funcs = */ &sshkey_rsa_funcs,
+};
+
+const struct sshkey_impl sshkey_rsa_sha512_impl = {
+ /* .name = */ "rsa-sha2-512",
+ /* .shortname = */ "RSA",
+ /* .sigalg = */ NULL,
+ /* .type = */ KEY_RSA,
+ /* .nid = */ 0,
+ /* .cert = */ 0,
+ /* .sigonly = */ 1,
+ /* .keybits = */ 0,
+ /* .funcs = */ &sshkey_rsa_funcs,
+};
+
+const struct sshkey_impl sshkey_rsa_sha256_cert_impl = {
+ /* .name = */ "rsa-sha2-256-cert-v01@openssh.com",
+ /* .shortname = */ "RSA-CERT",
+ /* .sigalg = */ "rsa-sha2-256",
+ /* .type = */ KEY_RSA_CERT,
+ /* .nid = */ 0,
+ /* .cert = */ 1,
+ /* .sigonly = */ 1,
+ /* .keybits = */ 0,
+ /* .funcs = */ &sshkey_rsa_funcs,
+};
+
+const struct sshkey_impl sshkey_rsa_sha512_cert_impl = {
+ /* .name = */ "rsa-sha2-512-cert-v01@openssh.com",
+ /* .shortname = */ "RSA-CERT",
+ /* .sigalg = */ "rsa-sha2-512",
+ /* .type = */ KEY_RSA_CERT,
+ /* .nid = */ 0,
+ /* .cert = */ 1,
+ /* .sigonly = */ 1,
+ /* .keybits = */ 0,
+ /* .funcs = */ &sshkey_rsa_funcs,
+};
#endif /* WITH_OPENSSL */
diff --git a/crypto/openssh/ssh-sk-helper.c b/crypto/openssh/ssh-sk-helper.c
index bd9b410a6974..9857b632bfcb 100644
--- a/crypto/openssh/ssh-sk-helper.c
+++ b/crypto/openssh/ssh-sk-helper.c
@@ -1,368 +1,367 @@
-/* $OpenBSD: ssh-sk-helper.c,v 1.13 2022/04/29 03:16:48 dtucker Exp $ */
+/* $OpenBSD: ssh-sk-helper.c,v 1.14 2022/12/04 11:03:11 dtucker Exp $ */
/*
* Copyright (c) 2019 Google LLC
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*
* This is a tiny program used to isolate the address space used for
* security key middleware signing operations from ssh-agent. It is similar
* to ssh-pkcs11-helper.c but considerably simpler as the operations for
* security keys are stateless.
*
* Please crank SSH_SK_HELPER_VERSION in sshkey.h for any incompatible
* protocol changes.
*/
#include "includes.h"
#include <limits.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include "xmalloc.h"
#include "log.h"
#include "sshkey.h"
#include "authfd.h"
#include "misc.h"
#include "sshbuf.h"
#include "msg.h"
#include "uidswap.h"
-#include "sshkey.h"
#include "ssherr.h"
#include "ssh-sk.h"
#ifdef ENABLE_SK
extern char *__progname;
static struct sshbuf *reply_error(int r, char *fmt, ...)
__attribute__((__format__ (printf, 2, 3)));
static struct sshbuf *
reply_error(int r, char *fmt, ...)
{
char *msg;
va_list ap;
struct sshbuf *resp;
va_start(ap, fmt);
xvasprintf(&msg, fmt, ap);
va_end(ap);
debug("%s: %s", __progname, msg);
free(msg);
if (r >= 0)
fatal_f("invalid error code %d", r);
if ((resp = sshbuf_new()) == NULL)
fatal("%s: sshbuf_new failed", __progname);
if (sshbuf_put_u32(resp, SSH_SK_HELPER_ERROR) != 0 ||
sshbuf_put_u32(resp, (u_int)-r) != 0)
fatal("%s: buffer error", __progname);
return resp;
}
/* If the specified string is zero length, then free it and replace with NULL */
static void
null_empty(char **s)
{
if (s == NULL || *s == NULL || **s != '\0')
return;
free(*s);
*s = NULL;
}
static struct sshbuf *
process_sign(struct sshbuf *req)
{
int r = SSH_ERR_INTERNAL_ERROR;
struct sshbuf *resp, *kbuf;
struct sshkey *key = NULL;
uint32_t compat;
const u_char *message;
u_char *sig = NULL;
size_t msglen, siglen = 0;
char *provider = NULL, *pin = NULL;
if ((r = sshbuf_froms(req, &kbuf)) != 0 ||
(r = sshbuf_get_cstring(req, &provider, NULL)) != 0 ||
(r = sshbuf_get_string_direct(req, &message, &msglen)) != 0 ||
(r = sshbuf_get_cstring(req, NULL, NULL)) != 0 || /* alg */
(r = sshbuf_get_u32(req, &compat)) != 0 ||
(r = sshbuf_get_cstring(req, &pin, NULL)) != 0)
fatal_r(r, "%s: parse", __progname);
if (sshbuf_len(req) != 0)
fatal("%s: trailing data in request", __progname);
if ((r = sshkey_private_deserialize(kbuf, &key)) != 0)
fatal_r(r, "%s: Unable to parse private key", __progname);
if (!sshkey_is_sk(key)) {
fatal("%s: Unsupported key type %s",
__progname, sshkey_ssh_name(key));
}
debug_f("ready to sign with key %s, provider %s: "
"msg len %zu, compat 0x%lx", sshkey_type(key),
provider, msglen, (u_long)compat);
null_empty(&pin);
if ((r = sshsk_sign(provider, key, &sig, &siglen,
message, msglen, compat, pin)) != 0) {
resp = reply_error(r, "Signing failed: %s", ssh_err(r));
goto out;
}
if ((resp = sshbuf_new()) == NULL)
fatal("%s: sshbuf_new failed", __progname);
if ((r = sshbuf_put_u32(resp, SSH_SK_HELPER_SIGN)) != 0 ||
(r = sshbuf_put_string(resp, sig, siglen)) != 0)
fatal_r(r, "%s: compose", __progname);
out:
sshkey_free(key);
sshbuf_free(kbuf);
free(provider);
if (sig != NULL)
freezero(sig, siglen);
if (pin != NULL)
freezero(pin, strlen(pin));
return resp;
}
static struct sshbuf *
process_enroll(struct sshbuf *req)
{
int r;
u_int type;
char *provider, *application, *pin, *device, *userid;
uint8_t flags;
struct sshbuf *challenge, *attest, *kbuf, *resp;
struct sshkey *key;
if ((attest = sshbuf_new()) == NULL ||
(kbuf = sshbuf_new()) == NULL)
fatal("%s: sshbuf_new failed", __progname);
if ((r = sshbuf_get_u32(req, &type)) != 0 ||
(r = sshbuf_get_cstring(req, &provider, NULL)) != 0 ||
(r = sshbuf_get_cstring(req, &device, NULL)) != 0 ||
(r = sshbuf_get_cstring(req, &application, NULL)) != 0 ||
(r = sshbuf_get_cstring(req, &userid, NULL)) != 0 ||
(r = sshbuf_get_u8(req, &flags)) != 0 ||
(r = sshbuf_get_cstring(req, &pin, NULL)) != 0 ||
(r = sshbuf_froms(req, &challenge)) != 0)
fatal_r(r, "%s: parse", __progname);
if (sshbuf_len(req) != 0)
fatal("%s: trailing data in request", __progname);
if (type > INT_MAX)
fatal("%s: bad type %u", __progname, type);
if (sshbuf_len(challenge) == 0) {
sshbuf_free(challenge);
challenge = NULL;
}
null_empty(&device);
null_empty(&userid);
null_empty(&pin);
if ((r = sshsk_enroll((int)type, provider, device, application, userid,
flags, pin, challenge, &key, attest)) != 0) {
resp = reply_error(r, "Enrollment failed: %s", ssh_err(r));
goto out;
}
if ((resp = sshbuf_new()) == NULL)
fatal("%s: sshbuf_new failed", __progname);
if ((r = sshkey_private_serialize(key, kbuf)) != 0)
fatal_r(r, "%s: encode key", __progname);
if ((r = sshbuf_put_u32(resp, SSH_SK_HELPER_ENROLL)) != 0 ||
(r = sshbuf_put_stringb(resp, kbuf)) != 0 ||
(r = sshbuf_put_stringb(resp, attest)) != 0)
fatal_r(r, "%s: compose", __progname);
out:
sshkey_free(key);
sshbuf_free(kbuf);
sshbuf_free(attest);
sshbuf_free(challenge);
free(provider);
free(application);
if (pin != NULL)
freezero(pin, strlen(pin));
return resp;
}
static struct sshbuf *
process_load_resident(struct sshbuf *req)
{
int r;
char *provider, *pin, *device;
struct sshbuf *kbuf, *resp;
struct sshsk_resident_key **srks = NULL;
size_t nsrks = 0, i;
u_int flags;
if ((kbuf = sshbuf_new()) == NULL)
fatal("%s: sshbuf_new failed", __progname);
if ((r = sshbuf_get_cstring(req, &provider, NULL)) != 0 ||
(r = sshbuf_get_cstring(req, &device, NULL)) != 0 ||
(r = sshbuf_get_cstring(req, &pin, NULL)) != 0 ||
(r = sshbuf_get_u32(req, &flags)) != 0)
fatal_r(r, "%s: parse", __progname);
if (sshbuf_len(req) != 0)
fatal("%s: trailing data in request", __progname);
null_empty(&device);
null_empty(&pin);
if ((r = sshsk_load_resident(provider, device, pin, flags,
&srks, &nsrks)) != 0) {
resp = reply_error(r, "sshsk_load_resident failed: %s",
ssh_err(r));
goto out;
}
if ((resp = sshbuf_new()) == NULL)
fatal("%s: sshbuf_new failed", __progname);
if ((r = sshbuf_put_u32(resp, SSH_SK_HELPER_LOAD_RESIDENT)) != 0)
fatal_r(r, "%s: compose", __progname);
for (i = 0; i < nsrks; i++) {
debug_f("key %zu %s %s uidlen %zu", i,
sshkey_type(srks[i]->key), srks[i]->key->sk_application,
srks[i]->user_id_len);
sshbuf_reset(kbuf);
if ((r = sshkey_private_serialize(srks[i]->key, kbuf)) != 0)
fatal_r(r, "%s: encode key", __progname);
if ((r = sshbuf_put_stringb(resp, kbuf)) != 0 ||
(r = sshbuf_put_cstring(resp, "")) != 0 || /* comment */
(r = sshbuf_put_string(resp, srks[i]->user_id,
srks[i]->user_id_len)) != 0)
fatal_r(r, "%s: compose key", __progname);
}
out:
sshsk_free_resident_keys(srks, nsrks);
sshbuf_free(kbuf);
free(provider);
free(device);
if (pin != NULL)
freezero(pin, strlen(pin));
return resp;
}
int
main(int argc, char **argv)
{
SyslogFacility log_facility = SYSLOG_FACILITY_AUTH;
LogLevel log_level = SYSLOG_LEVEL_ERROR;
struct sshbuf *req, *resp;
int in, out, ch, r, vflag = 0;
u_int rtype, ll = 0;
uint8_t version, log_stderr = 0;
sanitise_stdfd();
log_init(__progname, log_level, log_facility, log_stderr);
while ((ch = getopt(argc, argv, "v")) != -1) {
switch (ch) {
case 'v':
vflag = 1;
if (log_level == SYSLOG_LEVEL_ERROR)
log_level = SYSLOG_LEVEL_DEBUG1;
else if (log_level < SYSLOG_LEVEL_DEBUG3)
log_level++;
break;
default:
fprintf(stderr, "usage: %s [-v]\n", __progname);
exit(1);
}
}
log_init(__progname, log_level, log_facility, vflag);
/*
* Rearrange our file descriptors a little; we don't trust the
* providers not to fiddle with stdin/out.
*/
closefrom(STDERR_FILENO + 1);
if ((in = dup(STDIN_FILENO)) == -1 || (out = dup(STDOUT_FILENO)) == -1)
fatal("%s: dup: %s", __progname, strerror(errno));
close(STDIN_FILENO);
close(STDOUT_FILENO);
sanitise_stdfd(); /* resets to /dev/null */
if ((req = sshbuf_new()) == NULL)
fatal("%s: sshbuf_new failed", __progname);
if (ssh_msg_recv(in, req) < 0)
fatal("ssh_msg_recv failed");
close(in);
debug_f("received message len %zu", sshbuf_len(req));
if ((r = sshbuf_get_u8(req, &version)) != 0)
fatal_r(r, "%s: parse version", __progname);
if (version != SSH_SK_HELPER_VERSION) {
fatal("unsupported version: received %d, expected %d",
version, SSH_SK_HELPER_VERSION);
}
if ((r = sshbuf_get_u32(req, &rtype)) != 0 ||
(r = sshbuf_get_u8(req, &log_stderr)) != 0 ||
(r = sshbuf_get_u32(req, &ll)) != 0)
fatal_r(r, "%s: parse", __progname);
if (!vflag && log_level_name((LogLevel)ll) != NULL)
log_init(__progname, (LogLevel)ll, log_facility, log_stderr);
switch (rtype) {
case SSH_SK_HELPER_SIGN:
resp = process_sign(req);
break;
case SSH_SK_HELPER_ENROLL:
resp = process_enroll(req);
break;
case SSH_SK_HELPER_LOAD_RESIDENT:
resp = process_load_resident(req);
break;
default:
fatal("%s: unsupported request type %u", __progname, rtype);
}
sshbuf_free(req);
debug_f("reply len %zu", sshbuf_len(resp));
if (ssh_msg_send(out, SSH_SK_HELPER_VERSION, resp) == -1)
fatal("ssh_msg_send failed");
sshbuf_free(resp);
close(out);
return (0);
}
#else /* ENABLE_SK */
#include <stdio.h>
int
main(int argc, char **argv)
{
fprintf(stderr, "ssh-sk-helper: disabled at compile time\n");
return -1;
}
#endif /* ENABLE_SK */
diff --git a/crypto/openssh/ssh-xmss.c b/crypto/openssh/ssh-xmss.c
index 41ede29607c0..b3aec0f72df0 100644
--- a/crypto/openssh/ssh-xmss.c
+++ b/crypto/openssh/ssh-xmss.c
@@ -1,187 +1,387 @@
-/* $OpenBSD: ssh-xmss.c,v 1.5 2022/04/20 15:59:18 millert Exp $*/
+/* $OpenBSD: ssh-xmss.c,v 1.14 2022/10/28 00:44:44 djm Exp $*/
/*
* Copyright (c) 2017 Stefan-Lukas Gazdag.
* Copyright (c) 2017 Markus Friedl.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "includes.h"
#ifdef WITH_XMSS
#define SSHKEY_INTERNAL
#include <sys/types.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <stdint.h>
#include <unistd.h>
#include "log.h"
#include "sshbuf.h"
#include "sshkey.h"
#include "sshkey-xmss.h"
#include "ssherr.h"
#include "ssh.h"
#include "xmss_fast.h"
-int
-ssh_xmss_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
- const u_char *data, size_t datalen, u_int compat)
+static void
+ssh_xmss_cleanup(struct sshkey *k)
+{
+ freezero(k->xmss_pk, sshkey_xmss_pklen(k));
+ freezero(k->xmss_sk, sshkey_xmss_sklen(k));
+ sshkey_xmss_free_state(k);
+ free(k->xmss_name);
+ free(k->xmss_filename);
+ k->xmss_pk = NULL;
+ k->xmss_sk = NULL;
+ k->xmss_name = NULL;
+ k->xmss_filename = NULL;
+}
+
+static int
+ssh_xmss_equal(const struct sshkey *a, const struct sshkey *b)
+{
+ if (a->xmss_pk == NULL || b->xmss_pk == NULL)
+ return 0;
+ if (sshkey_xmss_pklen(a) != sshkey_xmss_pklen(b))
+ return 0;
+ if (memcmp(a->xmss_pk, b->xmss_pk, sshkey_xmss_pklen(a)) != 0)
+ return 0;
+ return 1;
+}
+
+static int
+ssh_xmss_serialize_public(const struct sshkey *key, struct sshbuf *b,
+ enum sshkey_serialize_rep opts)
+{
+ int r;
+
+ if (key->xmss_name == NULL || key->xmss_pk == NULL ||
+ sshkey_xmss_pklen(key) == 0)
+ return SSH_ERR_INVALID_ARGUMENT;
+ if ((r = sshbuf_put_cstring(b, key->xmss_name)) != 0 ||
+ (r = sshbuf_put_string(b, key->xmss_pk,
+ sshkey_xmss_pklen(key))) != 0 ||
+ (r = sshkey_xmss_serialize_pk_info(key, b, opts)) != 0)
+ return r;
+
+ return 0;
+}
+
+static int
+ssh_xmss_serialize_private(const struct sshkey *key, struct sshbuf *b,
+ enum sshkey_serialize_rep opts)
+{
+ int r;
+
+ if (key->xmss_name == NULL)
+ return SSH_ERR_INVALID_ARGUMENT;
+ /* Note: can't reuse ssh_xmss_serialize_public because of sk order */
+ if ((r = sshbuf_put_cstring(b, key->xmss_name)) != 0 ||
+ (r = sshbuf_put_string(b, key->xmss_pk,
+ sshkey_xmss_pklen(key))) != 0 ||
+ (r = sshbuf_put_string(b, key->xmss_sk,
+ sshkey_xmss_sklen(key))) != 0 ||
+ (r = sshkey_xmss_serialize_state_opt(key, b, opts)) != 0)
+ return r;
+
+ return 0;
+}
+
+static int
+ssh_xmss_copy_public(const struct sshkey *from, struct sshkey *to)
+{
+ int r = SSH_ERR_INTERNAL_ERROR;
+ u_int32_t left;
+ size_t pklen;
+
+ if ((r = sshkey_xmss_init(to, from->xmss_name)) != 0)
+ return r;
+ if (from->xmss_pk == NULL)
+ return 0; /* XXX SSH_ERR_INTERNAL_ERROR ? */
+
+ if ((pklen = sshkey_xmss_pklen(from)) == 0 ||
+ sshkey_xmss_pklen(to) != pklen)
+ return SSH_ERR_INTERNAL_ERROR;
+ if ((to->xmss_pk = malloc(pklen)) == NULL)
+ return SSH_ERR_ALLOC_FAIL;
+ memcpy(to->xmss_pk, from->xmss_pk, pklen);
+ /* simulate number of signatures left on pubkey */
+ left = sshkey_xmss_signatures_left(from);
+ if (left)
+ sshkey_xmss_enable_maxsign(to, left);
+ return 0;
+}
+
+static int
+ssh_xmss_deserialize_public(const char *ktype, struct sshbuf *b,
+ struct sshkey *key)
+{
+ size_t len = 0;
+ char *xmss_name = NULL;
+ u_char *pk = NULL;
+ int ret = SSH_ERR_INTERNAL_ERROR;
+
+ if ((ret = sshbuf_get_cstring(b, &xmss_name, NULL)) != 0)
+ goto out;
+ if ((ret = sshkey_xmss_init(key, xmss_name)) != 0)
+ goto out;
+ if ((ret = sshbuf_get_string(b, &pk, &len)) != 0)
+ goto out;
+ if (len == 0 || len != sshkey_xmss_pklen(key)) {
+ ret = SSH_ERR_INVALID_FORMAT;
+ goto out;
+ }
+ key->xmss_pk = pk;
+ pk = NULL;
+ if (!sshkey_is_cert(key) &&
+ (ret = sshkey_xmss_deserialize_pk_info(key, b)) != 0)
+ goto out;
+ /* success */
+ ret = 0;
+ out:
+ free(xmss_name);
+ freezero(pk, len);
+ return ret;
+}
+
+static int
+ssh_xmss_deserialize_private(const char *ktype, struct sshbuf *b,
+ struct sshkey *key)
+{
+ int r;
+ char *xmss_name = NULL;
+ size_t pklen = 0, sklen = 0;
+ u_char *xmss_pk = NULL, *xmss_sk = NULL;
+
+ /* Note: can't reuse ssh_xmss_deserialize_public because of sk order */
+ if ((r = sshbuf_get_cstring(b, &xmss_name, NULL)) != 0 ||
+ (r = sshbuf_get_string(b, &xmss_pk, &pklen)) != 0 ||
+ (r = sshbuf_get_string(b, &xmss_sk, &sklen)) != 0)
+ goto out;
+ if (!sshkey_is_cert(key) &&
+ (r = sshkey_xmss_init(key, xmss_name)) != 0)
+ goto out;
+ if (pklen != sshkey_xmss_pklen(key) ||
+ sklen != sshkey_xmss_sklen(key)) {
+ r = SSH_ERR_INVALID_FORMAT;
+ goto out;
+ }
+ key->xmss_pk = xmss_pk;
+ key->xmss_sk = xmss_sk;
+ xmss_pk = xmss_sk = NULL;
+ /* optional internal state */
+ if ((r = sshkey_xmss_deserialize_state_opt(key, b)) != 0)
+ goto out;
+ /* success */
+ r = 0;
+ out:
+ free(xmss_name);
+ freezero(xmss_pk, pklen);
+ freezero(xmss_sk, sklen);
+ return r;
+}
+
+static int
+ssh_xmss_sign(struct sshkey *key,
+ u_char **sigp, size_t *lenp,
+ const u_char *data, size_t datalen,
+ const char *alg, const char *sk_provider, const char *sk_pin, u_int compat)
{
u_char *sig = NULL;
size_t slen = 0, len = 0, required_siglen;
unsigned long long smlen;
int r, ret;
struct sshbuf *b = NULL;
if (lenp != NULL)
*lenp = 0;
if (sigp != NULL)
*sigp = NULL;
if (key == NULL ||
sshkey_type_plain(key->type) != KEY_XMSS ||
key->xmss_sk == NULL ||
sshkey_xmss_params(key) == NULL)
return SSH_ERR_INVALID_ARGUMENT;
if ((r = sshkey_xmss_siglen(key, &required_siglen)) != 0)
return r;
if (datalen >= INT_MAX - required_siglen)
return SSH_ERR_INVALID_ARGUMENT;
smlen = slen = datalen + required_siglen;
if ((sig = malloc(slen)) == NULL)
return SSH_ERR_ALLOC_FAIL;
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) {
r = SSH_ERR_INVALID_ARGUMENT; /* XXX better error? */
goto out;
}
/* encode signature */
if ((b = sshbuf_new()) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
if ((r = sshbuf_put_cstring(b, "ssh-xmss@openssh.com")) != 0 ||
(r = sshbuf_put_string(b, sig, smlen - datalen)) != 0)
goto out;
len = sshbuf_len(b);
if (sigp != NULL) {
if ((*sigp = malloc(len)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
memcpy(*sigp, sshbuf_ptr(b), len);
}
if (lenp != NULL)
*lenp = len;
/* success */
r = 0;
out:
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);
free(*sigp);
}
if (sigp != NULL)
*sigp = NULL;
if (lenp != NULL)
*lenp = 0;
r = ret;
}
sshbuf_free(b);
if (sig != NULL)
freezero(sig, slen);
return r;
}
-int
+static int
ssh_xmss_verify(const struct sshkey *key,
- const u_char *signature, size_t signaturelen,
- const u_char *data, size_t datalen, u_int compat)
+ const u_char *sig, size_t siglen,
+ const u_char *data, size_t dlen, const char *alg, u_int compat,
+ struct sshkey_sig_details **detailsp)
{
struct sshbuf *b = NULL;
char *ktype = NULL;
const u_char *sigblob;
u_char *sm = NULL, *m = NULL;
size_t len, required_siglen;
unsigned long long smlen = 0, mlen = 0;
int r, ret;
if (key == NULL ||
sshkey_type_plain(key->type) != KEY_XMSS ||
key->xmss_pk == NULL ||
sshkey_xmss_params(key) == NULL ||
- signature == NULL || signaturelen == 0)
+ sig == NULL || siglen == 0)
return SSH_ERR_INVALID_ARGUMENT;
if ((r = sshkey_xmss_siglen(key, &required_siglen)) != 0)
return r;
- if (datalen >= INT_MAX - required_siglen)
+ if (dlen >= INT_MAX - required_siglen)
return SSH_ERR_INVALID_ARGUMENT;
- if ((b = sshbuf_from(signature, signaturelen)) == NULL)
+ if ((b = sshbuf_from(sig, siglen)) == NULL)
return SSH_ERR_ALLOC_FAIL;
if ((r = sshbuf_get_cstring(b, &ktype, NULL)) != 0 ||
(r = sshbuf_get_string_direct(b, &sigblob, &len)) != 0)
goto out;
if (strcmp("ssh-xmss@openssh.com", ktype) != 0) {
r = SSH_ERR_KEY_TYPE_MISMATCH;
goto out;
}
if (sshbuf_len(b) != 0) {
r = SSH_ERR_UNEXPECTED_TRAILING_DATA;
goto out;
}
if (len != required_siglen) {
r = SSH_ERR_INVALID_FORMAT;
goto out;
}
- if (datalen >= SIZE_MAX - len) {
+ if (dlen >= SIZE_MAX - len) {
r = SSH_ERR_INVALID_ARGUMENT;
goto out;
}
- smlen = len + datalen;
+ smlen = len + dlen;
mlen = smlen;
if ((sm = malloc(smlen)) == NULL || (m = malloc(mlen)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
memcpy(sm, sigblob, len);
- memcpy(sm+len, data, datalen);
+ memcpy(sm+len, data, dlen);
if ((ret = xmss_sign_open(m, &mlen, sm, smlen,
key->xmss_pk, sshkey_xmss_params(key))) != 0) {
debug2_f("xmss_sign_open failed: %d", ret);
}
- if (ret != 0 || mlen != datalen) {
+ if (ret != 0 || mlen != dlen) {
r = SSH_ERR_SIGNATURE_INVALID;
goto out;
}
/* XXX compare 'm' and 'data' ? */
/* success */
r = 0;
out:
if (sm != NULL)
freezero(sm, smlen);
if (m != NULL)
freezero(m, smlen);
sshbuf_free(b);
free(ktype);
return r;
}
+
+static const struct sshkey_impl_funcs sshkey_xmss_funcs = {
+ /* .size = */ NULL,
+ /* .alloc = */ NULL,
+ /* .cleanup = */ ssh_xmss_cleanup,
+ /* .equal = */ ssh_xmss_equal,
+ /* .ssh_serialize_public = */ ssh_xmss_serialize_public,
+ /* .ssh_deserialize_public = */ ssh_xmss_deserialize_public,
+ /* .ssh_serialize_private = */ ssh_xmss_serialize_private,
+ /* .ssh_deserialize_private = */ ssh_xmss_deserialize_private,
+ /* .generate = */ sshkey_xmss_generate_private_key,
+ /* .copy_public = */ ssh_xmss_copy_public,
+ /* .sign = */ ssh_xmss_sign,
+ /* .verify = */ ssh_xmss_verify,
+};
+
+const struct sshkey_impl sshkey_xmss_impl = {
+ /* .name = */ "ssh-xmss@openssh.com",
+ /* .shortname = */ "XMSS",
+ /* .sigalg = */ NULL,
+ /* .type = */ KEY_XMSS,
+ /* .nid = */ 0,
+ /* .cert = */ 0,
+ /* .sigonly = */ 0,
+ /* .keybits = */ 256,
+ /* .funcs = */ &sshkey_xmss_funcs,
+};
+
+const struct sshkey_impl sshkey_xmss_cert_impl = {
+ /* .name = */ "ssh-xmss-cert-v01@openssh.com",
+ /* .shortname = */ "XMSS-CERT",
+ /* .sigalg = */ NULL,
+ /* .type = */ KEY_XMSS_CERT,
+ /* .nid = */ 0,
+ /* .cert = */ 1,
+ /* .sigonly = */ 0,
+ /* .keybits = */ 256,
+ /* .funcs = */ &sshkey_xmss_funcs,
+};
#endif /* WITH_XMSS */
diff --git a/crypto/openssh/ssh.1 b/crypto/openssh/ssh.1
index b622ea5d9797..8ee98dc79eac 100644
--- a/crypto/openssh/ssh.1
+++ b/crypto/openssh/ssh.1
@@ -1,1783 +1,1784 @@
.\"
.\" Author: Tatu Ylonen <ylo@cs.hut.fi>
.\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
.\" All rights reserved
.\"
.\" As far as I am concerned, the code I have written for this software
.\" can be used freely for any purpose. Any derived versions of this
.\" software must be clearly marked as such, and if the derived work is
.\" incompatible with the protocol description in the RFC file, it must be
.\" called by a name other than "ssh" or "Secure Shell".
.\"
.\" Copyright (c) 1999,2000 Markus Friedl. All rights reserved.
.\" Copyright (c) 1999 Aaron Campbell. All rights reserved.
.\" Copyright (c) 1999 Theo de Raadt. All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.\" $OpenBSD: ssh.1,v 1.432 2022/09/17 10:33:18 djm Exp $
-.Dd $Mdocdate: September 17 2022 $
+.\" $OpenBSD: ssh.1,v 1.433 2022/11/28 01:37:36 djm Exp $
+.Dd $Mdocdate: November 28 2022 $
.Dt SSH 1
.Os
.Sh NAME
.Nm ssh
.Nd OpenSSH remote login client
.Sh SYNOPSIS
.Nm ssh
.Op Fl 46AaCfGgKkMNnqsTtVvXxYy
.Op Fl B Ar bind_interface
.Op Fl b Ar bind_address
.Op Fl c Ar cipher_spec
.Op Fl D Oo Ar bind_address : Oc Ns Ar port
.Op Fl E Ar log_file
.Op Fl e Ar escape_char
.Op Fl F Ar configfile
.Op Fl I Ar pkcs11
.Op Fl i Ar identity_file
.Op Fl J Ar destination
.Op Fl L Ar address
.Op Fl l Ar login_name
.Op Fl m Ar mac_spec
.Op Fl O Ar ctl_cmd
.Op Fl o Ar option
.Op Fl p Ar port
.Op Fl Q Ar query_option
.Op Fl R Ar address
.Op Fl S Ar ctl_path
.Op Fl W Ar host : Ns Ar port
.Op Fl w Ar local_tun Ns Op : Ns Ar remote_tun
.Ar destination
.Op Ar command Op Ar argument ...
.Sh DESCRIPTION
.Nm
(SSH client) is a program for logging into a remote machine and for
executing commands on a remote machine.
It is intended to provide secure encrypted communications between
two untrusted hosts over an insecure network.
X11 connections, arbitrary TCP ports and
.Ux Ns -domain
sockets can also be forwarded over the secure channel.
.Pp
.Nm
connects and logs into the specified
.Ar destination ,
which may be specified as either
.Sm off
.Oo user @ Oc hostname
.Sm on
or a URI of the form
.Sm off
.No ssh:// Oo user @ Oc hostname Op : port .
.Sm on
The user must prove
their identity to the remote machine using one of several methods
(see below).
.Pp
If a
.Ar command
is specified,
it will be executed on the remote host instead of a login shell.
A complete command line may be specified as
.Ar command ,
or it may have additional arguments.
If supplied, the arguments will be appended to the command, separated by
spaces, before it is sent to the server to be executed.
.Pp
The options are as follows:
.Pp
.Bl -tag -width Ds -compact
.It Fl 4
Forces
.Nm
to use IPv4 addresses only.
.Pp
.It Fl 6
Forces
.Nm
to use IPv6 addresses only.
.Pp
.It Fl A
Enables forwarding of connections from an authentication agent such as
.Xr ssh-agent 1 .
This can also be specified on a per-host basis in a configuration file.
.Pp
Agent forwarding should be enabled with caution.
Users with the ability to bypass file permissions on the remote host
(for the agent's
.Ux Ns -domain
socket) can access the local agent through the forwarded connection.
An attacker cannot obtain key material from the agent,
however they can perform operations on the keys that enable them to
authenticate using the identities loaded into the agent.
A safer alternative may be to use a jump host
(see
.Fl J ) .
.Pp
.It Fl a
Disables forwarding of the authentication agent connection.
.Pp
.It Fl B Ar bind_interface
Bind to the address of
.Ar bind_interface
before attempting to connect to the destination host.
This is only useful on systems with more than one address.
.Pp
.It Fl b Ar bind_address
Use
.Ar bind_address
on the local machine as the source address
of the connection.
Only useful on systems with more than one address.
.Pp
.It Fl C
Requests compression of all data (including stdin, stdout, stderr, and
data for forwarded X11, TCP and
.Ux Ns -domain
connections).
The compression algorithm is the same used by
.Xr gzip 1 .
Compression is desirable on modem lines and other
slow connections, but will only slow down things on fast networks.
The default value can be set on a host-by-host basis in the
configuration files; see the
.Cm Compression
option in
.Xr ssh_config 5 .
.Pp
.It Fl c Ar cipher_spec
Selects the cipher specification for encrypting the session.
.Ar cipher_spec
is a comma-separated list of ciphers
listed in order of preference.
See the
.Cm Ciphers
keyword in
.Xr ssh_config 5
for more information.
.Pp
.It Fl D Xo
.Sm off
.Oo Ar bind_address : Oc
.Ar port
.Sm on
.Xc
Specifies a local
.Dq dynamic
application-level port forwarding.
This works by allocating a socket to listen to
.Ar port
on the local side, optionally bound to the specified
.Ar bind_address .
Whenever a connection is made to this port, the
connection is forwarded over the secure channel, and the application
protocol is then used to determine where to connect to from the
remote machine.
Currently the SOCKS4 and SOCKS5 protocols are supported, and
.Nm
will act as a SOCKS server.
Only root can forward privileged ports.
Dynamic port forwardings can also be specified in the configuration file.
.Pp
IPv6 addresses can be specified by enclosing the address in square brackets.
Only the superuser can forward privileged ports.
By default, the local port is bound in accordance with the
.Cm GatewayPorts
setting.
However, an explicit
.Ar bind_address
may be used to bind the connection to a specific address.
The
.Ar bind_address
of
.Dq localhost
indicates that the listening port be bound for local use only, while an
empty address or
.Sq *
indicates that the port should be available from all interfaces.
.Pp
.It Fl E Ar log_file
Append debug logs to
.Ar log_file
instead of standard error.
.Pp
.It Fl e Ar escape_char
Sets the escape character for sessions with a pty (default:
.Ql ~ ) .
The escape character is only recognized at the beginning of a line.
The escape character followed by a dot
.Pq Ql \&.
closes the connection;
followed by control-Z suspends the connection;
and followed by itself sends the escape character once.
Setting the character to
.Dq none
disables any escapes and makes the session fully transparent.
.Pp
.It Fl F Ar configfile
Specifies an alternative per-user configuration file.
If a configuration file is given on the command line,
the system-wide configuration file
.Pq Pa /etc/ssh/ssh_config
will be ignored.
The default for the per-user configuration file is
.Pa ~/.ssh/config .
If set to
.Dq none ,
no configuration files will be read.
.Pp
.It Fl f
Requests
.Nm
to go to background just before command execution.
This is useful if
.Nm
is going to ask for passwords or passphrases, but the user
wants it in the background.
This implies
.Fl n .
The recommended way to start X11 programs at a remote site is with
something like
.Ic ssh -f host xterm .
.Pp
If the
.Cm ExitOnForwardFailure
configuration option is set to
.Dq yes ,
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
.Nm
to print its configuration after evaluating
.Cm Host
and
.Cm Match
blocks and exit.
.Pp
.It Fl g
Allows remote hosts to connect to local forwarded ports.
If used on a multiplexed connection, then this option must be specified
on the master process.
.Pp
.It Fl I Ar pkcs11
Specify the PKCS#11 shared library
.Nm
should use to communicate with a PKCS#11 token providing keys for user
authentication.
.Pp
.It Fl i Ar identity_file
Selects a file from which the identity (private key) for
public key authentication is read.
You can also specify a public key file to use the corresponding
private key that is loaded in
.Xr ssh-agent 1
when the private key file is not present locally.
The default is
.Pa ~/.ssh/id_rsa ,
.Pa ~/.ssh/id_ecdsa ,
.Pa ~/.ssh/id_ecdsa_sk ,
.Pa ~/.ssh/id_ed25519 ,
.Pa ~/.ssh/id_ed25519_sk
and
.Pa ~/.ssh/id_dsa .
Identity files may also be specified on
a per-host basis in the configuration file.
It is possible to have multiple
.Fl i
options (and multiple identities specified in
configuration files).
If no certificates have been explicitly specified by the
.Cm CertificateFile
directive,
.Nm
will also try to load certificate information from the filename obtained
by appending
.Pa -cert.pub
to identity filenames.
.Pp
.It Fl J Ar destination
Connect to the target host by first making a
.Nm
connection to the jump host described by
.Ar destination
and then establishing a TCP forwarding to the ultimate destination from
there.
Multiple jump hops may be specified separated by comma characters.
This is a shortcut to specify a
.Cm ProxyJump
configuration directive.
Note that configuration directives supplied on the command-line generally
apply to the destination host and not any specified jump hosts.
Use
.Pa ~/.ssh/config
to specify configuration for jump hosts.
.Pp
.It Fl K
Enables GSSAPI-based authentication and forwarding (delegation) of GSSAPI
credentials to the server.
.Pp
.It Fl k
Disables forwarding (delegation) of GSSAPI credentials to the server.
.Pp
.It Fl L Xo
.Sm off
.Oo Ar bind_address : Oc
.Ar port : host : hostport
.Sm on
.Xc
.It Fl L Xo
.Sm off
.Oo Ar bind_address : Oc
.Ar port : remote_socket
.Sm on
.Xc
.It Fl L Xo
.Sm off
.Ar local_socket : host : hostport
.Sm on
.Xc
.It Fl L Xo
.Sm off
.Ar local_socket : remote_socket
.Sm on
.Xc
Specifies that connections to the given TCP port or Unix socket on the local
(client) host are to be forwarded to the given host and port, or Unix socket,
on the remote side.
This works by allocating a socket to listen to either a TCP
.Ar port
on the local side, optionally bound to the specified
.Ar bind_address ,
or to a Unix socket.
Whenever a connection is made to the local port or socket, the
connection is forwarded over the secure channel, and a connection is
made to either
.Ar host
port
.Ar hostport ,
or the Unix socket
.Ar remote_socket ,
from the remote machine.
.Pp
Port forwardings can also be specified in the configuration file.
Only the superuser can forward privileged ports.
IPv6 addresses can be specified by enclosing the address in square brackets.
.Pp
By default, the local port is bound in accordance with the
.Cm GatewayPorts
setting.
However, an explicit
.Ar bind_address
may be used to bind the connection to a specific address.
The
.Ar bind_address
of
.Dq localhost
indicates that the listening port be bound for local use only, while an
empty address or
.Sq *
indicates that the port should be available from all interfaces.
.Pp
.It Fl l Ar login_name
Specifies the user to log in as on the remote machine.
This also may be specified on a per-host basis in the configuration file.
.Pp
.It Fl M
Places the
.Nm
client into
.Dq master
mode for connection sharing.
Multiple
.Fl M
options places
.Nm
into
.Dq master
mode but with confirmation required using
.Xr ssh-askpass 1
before each operation that changes the multiplexing state
(e.g. opening a new session).
Refer to the description of
.Cm ControlMaster
in
.Xr ssh_config 5
for details.
.Pp
.It Fl m Ar mac_spec
A comma-separated list of MAC (message authentication code) algorithms,
specified in order of preference.
See the
.Cm MACs
keyword in
.Xr ssh_config 5
for more information.
.Pp
.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
.Pa /dev/null
(actually, prevents reading from stdin).
This must be used when
.Nm
is run in the background.
A common trick is to use this to run X11 programs on a remote machine.
For example,
.Ic ssh -n shadows.cs.hut.fi emacs &
will start an emacs on shadows.cs.hut.fi, and the X11
connection will be automatically forwarded over an encrypted channel.
The
.Nm
program will be put in the background.
(This does not work if
.Nm
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.
When the
.Fl O
option is specified, the
.Ar ctl_cmd
argument is interpreted and passed to the master process.
Valid commands are:
.Dq check
(check that the master process is running),
.Dq forward
(request forwardings without command execution),
.Dq cancel
(cancel forwardings),
.Dq exit
(request the master to exit), and
.Dq stop
(request the master to stop accepting further multiplexing requests).
.Pp
.It Fl o Ar option
Can be used to give options in the format used in the configuration file.
This is useful for specifying options for which there is no separate
command-line flag.
For full details of the options listed below, and their possible values, see
.Xr ssh_config 5 .
.Pp
.Bl -tag -width Ds -offset indent -compact
.It AddKeysToAgent
.It AddressFamily
.It BatchMode
.It BindAddress
.It CanonicalDomains
.It CanonicalizeFallbackLocal
.It CanonicalizeHostname
.It CanonicalizeMaxDots
.It CanonicalizePermittedCNAMEs
.It CASignatureAlgorithms
.It CertificateFile
.It CheckHostIP
.It Ciphers
.It ClearAllForwardings
.It Compression
.It ConnectionAttempts
.It ConnectTimeout
.It ControlMaster
.It ControlPath
.It ControlPersist
.It DynamicForward
+.It EnableEscapeCommandline
.It EscapeChar
.It ExitOnForwardFailure
.It FingerprintHash
.It ForkAfterAuthentication
.It ForwardAgent
.It ForwardX11
.It ForwardX11Timeout
.It ForwardX11Trusted
.It GatewayPorts
.It GlobalKnownHostsFile
.It GSSAPIAuthentication
.It GSSAPIDelegateCredentials
.It HashKnownHosts
.It Host
.It HostbasedAcceptedAlgorithms
.It HostbasedAuthentication
.It HostKeyAlgorithms
.It HostKeyAlias
.It Hostname
.It IdentitiesOnly
.It IdentityAgent
.It IdentityFile
.It IPQoS
.It KbdInteractiveAuthentication
.It KbdInteractiveDevices
.It KexAlgorithms
.It KnownHostsCommand
.It LocalCommand
.It LocalForward
.It LogLevel
.It MACs
.It Match
.It NoHostAuthenticationForLocalhost
.It NumberOfPasswordPrompts
.It PasswordAuthentication
.It PermitLocalCommand
.It PermitRemoteOpen
.It PKCS11Provider
.It Port
.It PreferredAuthentications
.It ProxyCommand
.It ProxyJump
.It ProxyUseFdpass
.It PubkeyAcceptedAlgorithms
.It PubkeyAuthentication
.It RekeyLimit
.It RemoteCommand
.It RemoteForward
.It RequestTTY
.It RequiredRSASize
.It SendEnv
.It ServerAliveInterval
.It ServerAliveCountMax
.It SessionType
.It SetEnv
.It StdinNull
.It StreamLocalBindMask
.It StreamLocalBindUnlink
.It StrictHostKeyChecking
.It TCPKeepAlive
.It Tunnel
.It TunnelDevice
.It UpdateHostKeys
.It User
.It UserKnownHostsFile
.It VerifyHostKeyDNS
.It VersionAddendum
.It VisualHostKey
.It XAuthLocation
.El
.Pp
.It Fl p Ar port
Port to connect to on the remote host.
This can be specified on a
per-host basis in the configuration file.
.Pp
.It Fl Q Ar query_option
Queries for the algorithms supported by one of the following features:
.Ar cipher
(supported symmetric ciphers),
.Ar cipher-auth
(supported symmetric ciphers that support authenticated encryption),
.Ar help
(supported query terms for use with the
.Fl Q
flag),
.Ar mac
(supported message integrity codes),
.Ar kex
(key exchange algorithms),
.Ar key
(key types),
.Ar key-cert
(certificate key types),
.Ar key-plain
(non-certificate key types),
.Ar key-sig
(all key types and signature algorithms),
.Ar protocol-version
(supported SSH protocol versions), and
.Ar sig
(supported signature algorithms).
Alternatively, any keyword from
.Xr ssh_config 5
or
.Xr sshd_config 5
that takes an algorithm list may be used as an alias for the corresponding
query_option.
.Pp
.It Fl q
Quiet mode.
Causes most warning and diagnostic messages to be suppressed.
.Pp
.It Fl R Xo
.Sm off
.Oo Ar bind_address : Oc
.Ar port : host : hostport
.Sm on
.Xc
.It Fl R Xo
.Sm off
.Oo Ar bind_address : Oc
.Ar port : local_socket
.Sm on
.Xc
.It Fl R Xo
.Sm off
.Ar remote_socket : host : hostport
.Sm on
.Xc
.It Fl R Xo
.Sm off
.Ar remote_socket : local_socket
.Sm on
.Xc
.It Fl R Xo
.Sm off
.Oo Ar bind_address : Oc
.Ar port
.Sm on
.Xc
Specifies that connections to the given TCP port or Unix socket on the remote
(server) host are to be forwarded to the local side.
.Pp
This works by allocating a socket to listen to either a TCP
.Ar port
or to a Unix socket on the remote side.
Whenever a connection is made to this port or Unix socket, the
connection is forwarded over the secure channel, and a connection
is made from the local machine to either an explicit destination specified by
.Ar host
port
.Ar hostport ,
or
.Ar local_socket ,
or, if no explicit destination was specified,
.Nm
will act as a SOCKS 4/5 proxy and forward connections to the destinations
requested by the remote SOCKS client.
.Pp
Port forwardings can also be specified in the configuration file.
Privileged ports can be forwarded only when
logging in as root on the remote machine.
IPv6 addresses can be specified by enclosing the address in square brackets.
.Pp
By default, TCP listening sockets on the server will be bound to the loopback
interface only.
This may be overridden by specifying a
.Ar bind_address .
An empty
.Ar bind_address ,
or the address
.Ql * ,
indicates that the remote socket should listen on all interfaces.
Specifying a remote
.Ar bind_address
will only succeed if the server's
.Cm GatewayPorts
option is enabled (see
.Xr sshd_config 5 ) .
.Pp
If the
.Ar port
argument is
.Ql 0 ,
the listen port will be dynamically allocated on the server and reported
to the client at run time.
When used together with
.Ic -O forward ,
the allocated port will be printed to the standard output.
.Pp
.It Fl S Ar ctl_path
Specifies the location of a control socket for connection sharing,
or the string
.Dq none
to disable connection sharing.
Refer to the description of
.Cm ControlPath
and
.Cm ControlMaster
in
.Xr ssh_config 5
for details.
.Pp
.It Fl 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.\&
.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.
.Pp
.It Fl t
Force pseudo-terminal allocation.
This can be used to execute arbitrary
screen-based programs on a remote machine, which can be very useful,
e.g. when implementing menu services.
Multiple
.Fl t
options force tty allocation, even if
.Nm
has no local tty.
.Pp
.It Fl V
Display the version number and exit.
.Pp
.It Fl v
Verbose mode.
Causes
.Nm
to print debugging messages about its progress.
This is helpful in
debugging connection, authentication, and configuration problems.
Multiple
.Fl v
options increase the verbosity.
The maximum is 3.
.Pp
.It Fl W Ar host : Ns Ar port
Requests that standard input and output on the client be forwarded to
.Ar host
on
.Ar port
over the secure channel.
Implies
.Fl N ,
.Fl T ,
.Cm ExitOnForwardFailure
and
.Cm ClearAllForwardings ,
though these can be overridden in the configuration file or using
.Fl o
command line options.
.Pp
.It Fl w Xo
.Ar local_tun Ns Op : Ns Ar remote_tun
.Xc
Requests
tunnel
device forwarding with the specified
.Xr tun 4
devices between the client
.Pq Ar local_tun
and the server
.Pq Ar remote_tun .
.Pp
The devices may be specified by numerical ID or the keyword
.Dq any ,
which uses the next available tunnel device.
If
.Ar remote_tun
is not specified, it defaults to
.Dq any .
See also the
.Cm Tunnel
and
.Cm TunnelDevice
directives in
.Xr ssh_config 5 .
.Pp
If the
.Cm Tunnel
directive is unset, it will be set to the default tunnel mode, which is
.Dq point-to-point .
If a different
.Cm Tunnel
forwarding mode it desired, then it should be specified before
.Fl w .
.Pp
.It Fl X
Enables X11 forwarding.
This can also be specified on a per-host basis in a configuration file.
.Pp
X11 forwarding should be enabled with caution.
Users with the ability to bypass file permissions on the remote host
(for the user's X authorization database)
can access the local X11 display through the forwarded connection.
An attacker may then be able to perform activities such as keystroke monitoring.
.Pp
For this reason, X11 forwarding is subjected to X11 SECURITY extension
restrictions by default.
Refer to the
.Nm
.Fl Y
option and the
.Cm ForwardX11Trusted
directive in
.Xr ssh_config 5
for more information.
.Pp
.It Fl x
Disables X11 forwarding.
.Pp
.It Fl Y
Enables trusted X11 forwarding.
Trusted X11 forwardings are not subjected to the X11 SECURITY extension
controls.
.Pp
.It Fl y
Send log information using the
.Xr syslog 3
system module.
By default this information is sent to stderr.
.El
.Pp
.Nm
may additionally obtain configuration data from
a per-user configuration file and a system-wide configuration file.
The file format and configuration options are described in
.Xr ssh_config 5 .
.Sh AUTHENTICATION
The OpenSSH SSH client supports SSH protocol 2.
.Pp
The methods available for authentication are:
GSSAPI-based authentication,
host-based authentication,
public key authentication,
keyboard-interactive authentication,
and password authentication.
Authentication methods are tried in the order specified above,
though
.Cm PreferredAuthentications
can be used to change the default order.
.Pp
Host-based authentication works as follows:
If the machine the user logs in from is listed in
.Pa /etc/hosts.equiv
or
.Pa /etc/shosts.equiv
on the remote machine, the user is non-root and the user names are
the same on both sides, or if the files
.Pa ~/.rhosts
or
.Pa ~/.shosts
exist in the user's home directory on the
remote machine and contain a line containing the name of the client
machine and the name of the user on that machine, the user is
considered for login.
Additionally, the server
.Em must
be able to verify the client's
host key (see the description of
.Pa /etc/ssh/ssh_known_hosts
and
.Pa ~/.ssh/known_hosts ,
below)
for login to be permitted.
This authentication method closes security holes due to IP
spoofing, DNS spoofing, and routing spoofing.
[Note to the administrator:
.Pa /etc/hosts.equiv ,
.Pa ~/.rhosts ,
and the rlogin/rsh protocol in general, are inherently insecure and should be
disabled if security is desired.]
.Pp
Public key authentication works as follows:
The scheme is based on public-key cryptography,
using cryptosystems
where encryption and decryption are done using separate keys,
and it is unfeasible to derive the decryption key from the encryption key.
The idea is that each user creates a public/private
key pair for authentication purposes.
The server knows the public key, and only the user knows the private key.
.Nm
implements public key authentication protocol automatically,
using one of the DSA, ECDSA, Ed25519 or RSA algorithms.
The HISTORY section of
.Xr ssl 8
contains a brief discussion of the DSA and RSA algorithms.
.Pp
The file
.Pa ~/.ssh/authorized_keys
lists the public keys that are permitted for logging in.
When the user logs in, the
.Nm
program tells the server which key pair it would like to use for
authentication.
The client proves that it has access to the private key
and the server checks that the corresponding public key
is authorized to accept the account.
.Pp
The server may inform the client of errors that prevented public key
authentication from succeeding after authentication completes using a
different method.
These may be viewed by increasing the
.Cm LogLevel
to
.Cm DEBUG
or higher (e.g. by using the
.Fl v
flag).
.Pp
The user creates their key pair by running
.Xr ssh-keygen 1 .
This stores the private key in
.Pa ~/.ssh/id_dsa
(DSA),
.Pa ~/.ssh/id_ecdsa
(ECDSA),
.Pa ~/.ssh/id_ecdsa_sk
(authenticator-hosted ECDSA),
.Pa ~/.ssh/id_ed25519
(Ed25519),
.Pa ~/.ssh/id_ed25519_sk
(authenticator-hosted Ed25519),
or
.Pa ~/.ssh/id_rsa
(RSA)
and stores the public key in
.Pa ~/.ssh/id_dsa.pub
(DSA),
.Pa ~/.ssh/id_ecdsa.pub
(ECDSA),
.Pa ~/.ssh/id_ecdsa_sk.pub
(authenticator-hosted ECDSA),
.Pa ~/.ssh/id_ed25519.pub
(Ed25519),
.Pa ~/.ssh/id_ed25519_sk.pub
(authenticator-hosted Ed25519),
or
.Pa ~/.ssh/id_rsa.pub
(RSA)
in the user's home directory.
The user should then copy the public key
to
.Pa ~/.ssh/authorized_keys
in their home directory on the remote machine.
The
.Pa authorized_keys
file corresponds to the conventional
.Pa ~/.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.
.Pp
A variation on public key authentication
is available in the form of certificate authentication:
instead of a set of public/private keys,
signed certificates are used.
This has the advantage that a single trusted certification authority
can be used in place of many public/private keys.
See the CERTIFICATES section of
.Xr ssh-keygen 1
for more information.
.Pp
The most convenient way to use public key or certificate authentication
may be with an authentication agent.
See
.Xr ssh-agent 1
and (optionally) the
.Cm AddKeysToAgent
directive in
.Xr ssh_config 5
for more information.
.Pp
Keyboard-interactive authentication works as follows:
The server sends an arbitrary
.Qq challenge
text and prompts for a response, possibly multiple times.
Examples of keyboard-interactive authentication include
.Bx
Authentication (see
.Xr login.conf 5 )
and PAM (some
.Pf non- Ox
systems).
.Pp
Finally, if other authentication methods fail,
.Nm
prompts the user for a password.
The password is sent to the remote
host for checking; however, since all communications are encrypted,
the password cannot be seen by someone listening on the network.
.Pp
.Nm
automatically maintains and checks a database containing
identification for all hosts it has ever been used with.
Host keys are stored in
.Pa ~/.ssh/known_hosts
in the user's home directory.
Additionally, the file
.Pa /etc/ssh/ssh_known_hosts
is automatically checked for known hosts.
Any new hosts are automatically added to the user's file.
If a host's identification ever changes,
.Nm
warns about this and disables password authentication to prevent
server spoofing or man-in-the-middle attacks,
which could otherwise be used to circumvent the encryption.
The
.Cm StrictHostKeyChecking
option can be used to control logins to machines whose
host key is not known or has changed.
.Pp
When the user's identity has been accepted by the server, the server
either executes the given command in a non-interactive session or,
if no command has been specified, logs into the machine and gives
the user a normal shell as an interactive session.
All communication with
the remote command or shell will be automatically encrypted.
.Pp
If an interactive session is requested,
.Nm
by default will only request a pseudo-terminal (pty) for interactive
sessions when the client has one.
The flags
.Fl T
and
.Fl t
can be used to override this behaviour.
.Pp
If a pseudo-terminal has been allocated, the
user may use the escape characters noted below.
.Pp
If no pseudo-terminal has been allocated,
the session is transparent and can be used to reliably transfer binary data.
On most systems, setting the escape character to
.Dq none
will also make the session transparent even if a tty is used.
.Pp
The session terminates when the command or shell on the remote
machine exits and all X11 and TCP connections have been closed.
.Sh ESCAPE CHARACTERS
When a pseudo-terminal has been requested,
.Nm
supports a number of functions through the use of an escape character.
.Pp
A single tilde character can be sent as
.Ic ~~
or by following the tilde by a character other than those described below.
The escape character must always follow a newline to be interpreted as
special.
The escape character can be changed in configuration files using the
.Cm EscapeChar
configuration directive or on the command line by the
.Fl e
option.
.Pp
The supported escapes (assuming the default
.Ql ~ )
are:
.Bl -tag -width Ds
.It Cm ~.
Disconnect.
.It Cm ~^Z
Background
.Nm .
.It Cm ~#
List forwarded connections.
.It Cm ~&
Background
.Nm
at logout when waiting for forwarded connection / X11 sessions to terminate.
.It Cm ~?
Display a list of escape characters.
.It Cm ~B
Send a BREAK to the remote system
(only useful if the peer supports it).
.It Cm ~C
Open command line.
Currently this allows the addition of port forwardings using the
.Fl L ,
.Fl R
and
.Fl D
options (see above).
It also allows the cancellation of existing port-forwardings
with
.Sm off
.Fl KL Oo Ar bind_address : Oc Ar port
.Sm on
for local,
.Sm off
.Fl KR Oo Ar bind_address : Oc Ar port
.Sm on
for remote and
.Sm off
.Fl KD Oo Ar bind_address : Oc Ar port
.Sm on
for dynamic port-forwardings.
.Ic !\& Ns Ar command
allows the user to execute a local command if the
.Ic PermitLocalCommand
option is enabled in
.Xr ssh_config 5 .
Basic help is available, using the
.Fl h
option.
.It Cm ~R
Request rekeying of the connection
(only useful if the peer supports it).
.It Cm ~V
Decrease the verbosity
.Pq Ic LogLevel
when errors are being written to stderr.
.It Cm ~v
Increase the verbosity
.Pq Ic LogLevel
when errors are being written to stderr.
.El
.Sh TCP FORWARDING
Forwarding of arbitrary TCP connections over a secure channel
can be specified either on the command line or in a configuration file.
One possible application of TCP forwarding is a secure connection to a
mail server; another is going through firewalls.
.Pp
In the example below, we look at encrypting communication for an IRC client,
even though the IRC server it connects to does not directly
support encrypted communication.
This works as follows:
the user connects to the remote host using
.Nm ,
specifying the ports to be used to forward the connection.
After that it is possible to start the program locally,
and
.Nm
will encrypt and forward the connection to the remote server.
.Pp
The following example tunnels an IRC session from the client
to an IRC server at
.Dq server.example.com ,
joining channel
.Dq #users ,
nickname
.Dq pinky ,
using the standard IRC port, 6667:
.Bd -literal -offset 4n
$ ssh -f -L 6667:localhost:6667 server.example.com sleep 10
$ irc -c '#users' pinky IRC/127.0.0.1
.Ed
.Pp
The
.Fl f
option backgrounds
.Nm
and the remote command
.Dq sleep 10
is specified to allow an amount of time
(10 seconds, in the example)
to start the program which is going to use the tunnel.
If no connections are made within the time specified,
.Nm
will exit.
.Sh X11 FORWARDING
If the
.Cm ForwardX11
variable is set to
.Dq yes
(or see the description of the
.Fl X ,
.Fl x ,
and
.Fl Y
options above)
and the user is using X11 (the
.Ev DISPLAY
environment variable is set), the connection to the X11 display is
automatically forwarded to the remote side in such a way that any X11
programs started from the shell (or command) will go through the
encrypted channel, and the connection to the real X server will be made
from the local machine.
The user should not manually set
.Ev DISPLAY .
Forwarding of X11 connections can be
configured on the command line or in configuration files.
.Pp
The
.Ev DISPLAY
value set by
.Nm
will point to the server machine, but with a display number greater than zero.
This is normal, and happens because
.Nm
creates a
.Dq proxy
X server on the server machine for forwarding the
connections over the encrypted channel.
.Pp
.Nm
will also automatically set up Xauthority data on the server machine.
For this purpose, it will generate a random authorization cookie,
store it in Xauthority on the server, and verify that any forwarded
connections carry this cookie and replace it by the real cookie when
the connection is opened.
The real authentication cookie is never
sent to the server machine (and no cookies are sent in the plain).
.Pp
If the
.Cm ForwardAgent
variable is set to
.Dq yes
(or see the description of the
.Fl A
and
.Fl a
options above) and
the user is using an authentication agent, the connection to the agent
is automatically forwarded to the remote side.
.Sh VERIFYING HOST KEYS
When connecting to a server for the first time,
a fingerprint of the server's public key is presented to the user
(unless the option
.Cm StrictHostKeyChecking
has been disabled).
Fingerprints can be determined using
.Xr ssh-keygen 1 :
.Pp
.Dl $ ssh-keygen -l -f /etc/ssh/ssh_host_rsa_key
.Pp
If the fingerprint is already known, it can be matched
and the key can be accepted or rejected.
If only legacy (MD5) fingerprints for the server are available, the
.Xr ssh-keygen 1
.Fl E
option may be used to downgrade the fingerprint algorithm to match.
.Pp
Because of the difficulty of comparing host keys
just by looking at fingerprint strings,
there is also support to compare host keys visually,
using
.Em random art .
By setting the
.Cm VisualHostKey
option to
.Dq yes ,
a small ASCII graphic gets displayed on every login to a server, no matter
if the session itself is interactive or not.
By learning the pattern a known server produces, a user can easily
find out that the host key has changed when a completely different pattern
is displayed.
Because these patterns are not unambiguous however, a pattern that looks
similar to the pattern remembered only gives a good probability that the
host key is the same, not guaranteed proof.
.Pp
To get a listing of the fingerprints along with their random art for
all known hosts, the following command line can be used:
.Pp
.Dl $ ssh-keygen -lv -f ~/.ssh/known_hosts
.Pp
If the fingerprint is unknown,
an alternative method of verification is available:
SSH fingerprints verified by DNS.
An additional resource record (RR),
SSHFP,
is added to a zonefile
and the connecting client is able to match the fingerprint
with that of the key presented.
.Pp
In this example, we are connecting a client to a server,
.Dq host.example.com .
The SSHFP resource records should first be added to the zonefile for
host.example.com:
.Bd -literal -offset indent
$ ssh-keygen -r host.example.com.
.Ed
.Pp
The output lines will have to be added to the zonefile.
To check that the zone is answering fingerprint queries:
.Pp
.Dl $ dig -t SSHFP host.example.com
.Pp
Finally the client connects:
.Bd -literal -offset indent
$ ssh -o "VerifyHostKeyDNS ask" host.example.com
[...]
Matching host key fingerprint found in DNS.
Are you sure you want to continue connecting (yes/no)?
.Ed
.Pp
See the
.Cm VerifyHostKeyDNS
option in
.Xr ssh_config 5
for more information.
.Sh SSH-BASED VIRTUAL PRIVATE NETWORKS
.Nm
contains support for Virtual Private Network (VPN) tunnelling
using the
.Xr tun 4
network pseudo-device,
allowing two networks to be joined securely.
The
.Xr sshd_config 5
configuration option
.Cm PermitTunnel
controls whether the server supports this,
and at what level (layer 2 or 3 traffic).
.Pp
The following example would connect client network 10.0.50.0/24
with remote network 10.0.99.0/24 using a point-to-point connection
from 10.1.1.1 to 10.1.1.2,
provided that the SSH server running on the gateway to the remote network,
at 192.168.1.15, allows it.
.Pp
On the client:
.Bd -literal -offset indent
# ssh -f -w 0:1 192.168.1.15 true
# ifconfig tun0 10.1.1.1 10.1.1.2 netmask 255.255.255.252
# route add 10.0.99.0/24 10.1.1.2
.Ed
.Pp
On the server:
.Bd -literal -offset indent
# ifconfig tun1 10.1.1.2 10.1.1.1 netmask 255.255.255.252
# route add 10.0.50.0/24 10.1.1.1
.Ed
.Pp
Client access may be more finely tuned via the
.Pa /root/.ssh/authorized_keys
file (see below) and the
.Cm PermitRootLogin
server option.
The following entry would permit connections on
.Xr tun 4
device 1 from user
.Dq jane
and on tun device 2 from user
.Dq john ,
if
.Cm PermitRootLogin
is set to
.Dq forced-commands-only :
.Bd -literal -offset 2n
tunnel="1",command="sh /etc/netstart tun1" ssh-rsa ... jane
tunnel="2",command="sh /etc/netstart tun2" ssh-rsa ... john
.Ed
.Pp
Since an SSH-based setup entails a fair amount of overhead,
it may be more suited to temporary setups,
such as for wireless VPNs.
More permanent VPNs are better provided by tools such as
.Xr ipsecctl 8
and
.Xr isakmpd 8 .
.Sh ENVIRONMENT
.Nm
will normally set the following environment variables:
.Bl -tag -width "SSH_ORIGINAL_COMMAND"
.It Ev DISPLAY
The
.Ev DISPLAY
variable indicates the location of the X11 server.
It is automatically set by
.Nm
to point to a value of the form
.Dq hostname:n ,
where
.Dq hostname
indicates the host where the shell runs, and
.Sq n
is an integer \*(Ge 1.
.Nm
uses this special value to forward X11 connections over the secure
channel.
The user should normally not set
.Ev DISPLAY
explicitly, as that
will render the X11 connection insecure (and will require the user to
manually copy any required authorization cookies).
.It Ev HOME
Set to the path of the user's home directory.
.It Ev LOGNAME
Synonym for
.Ev USER ;
set for compatibility with systems that use this variable.
.It Ev MAIL
Set to the path of the user's mailbox.
.It Ev PATH
Set to the default
.Ev PATH ,
as specified when compiling
.Nm .
.It Ev SSH_ASKPASS
If
.Nm
needs a passphrase, it will read the passphrase from the current
terminal if it was run from a terminal.
If
.Nm
does not have a terminal associated with it but
.Ev DISPLAY
and
.Ev SSH_ASKPASS
are set, it will execute the program specified by
.Ev SSH_ASKPASS
and open an X11 window to read the passphrase.
This is particularly useful when calling
.Nm
from a
.Pa .xsession
or related script.
(Note that on some machines it
may be necessary to redirect the input from
.Pa /dev/null
to make this work.)
.It Ev SSH_ASKPASS_REQUIRE
Allows further control over the use of an askpass program.
If this variable is set to
.Dq never
then
.Nm
will never attempt to use one.
If it is set to
.Dq prefer ,
then
.Nm
will prefer to use the askpass program instead of the TTY when requesting
passwords.
Finally, if the variable is set to
.Dq force ,
then the askpass program will be used for all passphrase input regardless
of whether
.Ev DISPLAY
is set.
.It Ev SSH_AUTH_SOCK
Identifies the path of a
.Ux Ns -domain
socket used to communicate with the agent.
.It Ev SSH_CONNECTION
Identifies the client and server ends of the connection.
The variable contains
four space-separated values: client IP address, client port number,
server IP address, and server port number.
.It Ev SSH_ORIGINAL_COMMAND
This variable contains the original command line if a forced command
is executed.
It can be used to extract the original arguments.
.It Ev SSH_TTY
This is set to the name of the tty (path to the device) associated
with the current shell or command.
If the current session has no tty,
this variable is not set.
.It Ev SSH_TUNNEL
Optionally set by
.Xr sshd 8
to contain the interface names assigned if tunnel forwarding was
requested by the client.
.It Ev SSH_USER_AUTH
Optionally set by
.Xr sshd 8 ,
this variable may contain a pathname to a file that lists the authentication
methods successfully used when the session was established, including any
public keys that were used.
.It Ev TZ
This variable is set to indicate the present time zone if it
was set when the daemon was started (i.e. the daemon passes the value
on to new connections).
.It Ev USER
Set to the name of the user logging in.
.El
.Pp
Additionally,
.Nm
reads
.Pa ~/.ssh/environment ,
and adds lines of the format
.Dq VARNAME=value
to the environment if the file exists and users are allowed to
change their environment.
For more information, see the
.Cm PermitUserEnvironment
option in
.Xr sshd_config 5 .
.Sh FILES
.Bl -tag -width Ds -compact
.It Pa ~/.rhosts
This file is used for host-based authentication (see above).
On some machines this file may need to be
world-readable if the user's home directory is on an NFS partition,
because
.Xr sshd 8
reads it as root.
Additionally, this file must be owned by the user,
and must not have write permissions for anyone else.
The recommended
permission for most machines is read/write for the user, and not
accessible by others.
.Pp
.It Pa ~/.shosts
This file is used in exactly the same way as
.Pa .rhosts ,
but allows host-based authentication without permitting login with
rlogin/rsh.
.Pp
.It Pa ~/.ssh/
This directory is the default location for all user-specific configuration
and authentication information.
There is no general requirement to keep the entire contents of this directory
secret, but the recommended permissions are read/write/execute for the user,
and not accessible by others.
.Pp
.It Pa ~/.ssh/authorized_keys
Lists the public keys (DSA, ECDSA, Ed25519, RSA)
that can be used for logging in as this user.
The format of this file is described in the
.Xr sshd 8
manual page.
This file is not highly sensitive, but the recommended
permissions are read/write for the user, and not accessible by others.
.Pp
.It Pa ~/.ssh/config
This is the per-user configuration file.
The file format and configuration options are described in
.Xr ssh_config 5 .
Because of the potential for abuse, this file must have strict permissions:
read/write for the user, and not writable by others.
.Pp
.It Pa ~/.ssh/environment
Contains additional definitions for environment variables; see
.Sx ENVIRONMENT ,
above.
.Pp
.It Pa ~/.ssh/id_dsa
.It Pa ~/.ssh/id_ecdsa
.It Pa ~/.ssh/id_ecdsa_sk
.It Pa ~/.ssh/id_ed25519
.It Pa ~/.ssh/id_ed25519_sk
.It Pa ~/.ssh/id_rsa
Contains the private key for authentication.
These files
contain sensitive data and should be readable by the user but not
accessible by others (read/write/execute).
.Nm
will simply ignore a private key file if it is accessible by others.
It is possible to specify a passphrase when
generating the key which will be used to encrypt the
sensitive part of this file using AES-128.
.Pp
.It Pa ~/.ssh/id_dsa.pub
.It Pa ~/.ssh/id_ecdsa.pub
.It Pa ~/.ssh/id_ecdsa_sk.pub
.It Pa ~/.ssh/id_ed25519.pub
.It Pa ~/.ssh/id_ed25519_sk.pub
.It Pa ~/.ssh/id_rsa.pub
Contains the public key for authentication.
These files are not
sensitive and can (but need not) be readable by anyone.
.Pp
.It Pa ~/.ssh/known_hosts
Contains a list of host keys for all hosts the user has logged into
that are not already in the systemwide list of known host keys.
See
.Xr sshd 8
for further details of the format of this file.
.Pp
.It Pa ~/.ssh/rc
Commands in this file are executed by
.Nm
when the user logs in, just before the user's shell (or command) is
started.
See the
.Xr sshd 8
manual page for more information.
.Pp
.It Pa /etc/hosts.equiv
This file is for host-based authentication (see above).
It should only be writable by root.
.Pp
.It Pa /etc/shosts.equiv
This file is used in exactly the same way as
.Pa hosts.equiv ,
but allows host-based authentication without permitting login with
rlogin/rsh.
.Pp
.It Pa /etc/ssh/ssh_config
Systemwide configuration file.
The file format and configuration options are described in
.Xr ssh_config 5 .
.Pp
.It Pa /etc/ssh/ssh_host_key
.It Pa /etc/ssh/ssh_host_dsa_key
.It Pa /etc/ssh/ssh_host_ecdsa_key
.It Pa /etc/ssh/ssh_host_ed25519_key
.It Pa /etc/ssh/ssh_host_rsa_key
These files contain the private parts of the host keys
and are used for host-based authentication.
.Pp
.It Pa /etc/ssh/ssh_known_hosts
Systemwide list of known host keys.
This file should be prepared by the
system administrator to contain the public host keys of all machines in the
organization.
It should be world-readable.
See
.Xr sshd 8
for further details of the format of this file.
.Pp
.It Pa /etc/ssh/sshrc
Commands in this file are executed by
.Nm
when the user logs in, just before the user's shell (or command) is started.
See the
.Xr sshd 8
manual page for more information.
.El
.Sh EXIT STATUS
.Nm
exits with the exit status of the remote command or with 255
if an error occurred.
.Sh SEE ALSO
.Xr scp 1 ,
.Xr sftp 1 ,
.Xr ssh-add 1 ,
.Xr ssh-agent 1 ,
.Xr ssh-keygen 1 ,
.Xr ssh-keyscan 1 ,
.Xr tun 4 ,
.Xr ssh_config 5 ,
.Xr ssh-keysign 8 ,
.Xr sshd 8
.Sh STANDARDS
.Rs
.%A S. Lehtinen
.%A C. Lonvick
.%D January 2006
.%R RFC 4250
.%T The Secure Shell (SSH) Protocol Assigned Numbers
.Re
.Pp
.Rs
.%A T. Ylonen
.%A C. Lonvick
.%D January 2006
.%R RFC 4251
.%T The Secure Shell (SSH) Protocol Architecture
.Re
.Pp
.Rs
.%A T. Ylonen
.%A C. Lonvick
.%D January 2006
.%R RFC 4252
.%T The Secure Shell (SSH) Authentication Protocol
.Re
.Pp
.Rs
.%A T. Ylonen
.%A C. Lonvick
.%D January 2006
.%R RFC 4253
.%T The Secure Shell (SSH) Transport Layer Protocol
.Re
.Pp
.Rs
.%A T. Ylonen
.%A C. Lonvick
.%D January 2006
.%R RFC 4254
.%T The Secure Shell (SSH) Connection Protocol
.Re
.Pp
.Rs
.%A J. Schlyter
.%A W. Griffin
.%D January 2006
.%R RFC 4255
.%T Using DNS to Securely Publish Secure Shell (SSH) Key Fingerprints
.Re
.Pp
.Rs
.%A F. Cusack
.%A M. Forssen
.%D January 2006
.%R RFC 4256
.%T Generic Message Exchange Authentication for the Secure Shell Protocol (SSH)
.Re
.Pp
.Rs
.%A J. Galbraith
.%A P. Remaker
.%D January 2006
.%R RFC 4335
.%T The Secure Shell (SSH) Session Channel Break Extension
.Re
.Pp
.Rs
.%A M. Bellare
.%A T. Kohno
.%A C. Namprempre
.%D January 2006
.%R RFC 4344
.%T The Secure Shell (SSH) Transport Layer Encryption Modes
.Re
.Pp
.Rs
.%A B. Harris
.%D January 2006
.%R RFC 4345
.%T Improved Arcfour Modes for the Secure Shell (SSH) Transport Layer Protocol
.Re
.Pp
.Rs
.%A M. Friedl
.%A N. Provos
.%A W. Simpson
.%D March 2006
.%R RFC 4419
.%T Diffie-Hellman Group Exchange for the Secure Shell (SSH) Transport Layer Protocol
.Re
.Pp
.Rs
.%A J. Galbraith
.%A R. Thayer
.%D November 2006
.%R RFC 4716
.%T The Secure Shell (SSH) Public Key File Format
.Re
.Pp
.Rs
.%A D. Stebila
.%A J. Green
.%D December 2009
.%R RFC 5656
.%T Elliptic Curve Algorithm Integration in the Secure Shell Transport Layer
.Re
.Pp
.Rs
.%A A. Perrig
.%A D. Song
.%D 1999
.%O International Workshop on Cryptographic Techniques and E-Commerce (CrypTEC '99)
.%T Hash Visualization: a New Technique to improve Real-World Security
.Re
.Sh AUTHORS
OpenSSH is a derivative of the original and free
ssh 1.2.12 release by Tatu Ylonen.
Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos,
Theo de Raadt and Dug Song
removed many bugs, re-added newer features and
created OpenSSH.
Markus Friedl contributed the support for SSH
protocol versions 1.5 and 2.0.
diff --git a/crypto/openssh/ssh.c b/crypto/openssh/ssh.c
index 549686b7798f..37a0eeddc302 100644
--- a/crypto/openssh/ssh.c
+++ b/crypto/openssh/ssh.c
@@ -1,2404 +1,2412 @@
-/* $OpenBSD: ssh.c,v 1.579 2022/10/24 22:43:36 djm Exp $ */
+/* $OpenBSD: ssh.c,v 1.584 2023/01/17 18:52:44 millert Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
* Ssh client program. This program can be used to log into a remote machine.
* The software supports strong authentication, encryption, and forwarding
* of X11, TCP/IP, and authentication connections.
*
* As far as I am concerned, the code I have written for this software
* can be used freely for any purpose. Any derived versions of this
* software must be clearly marked as such, and if the derived work is
* incompatible with the protocol description in the RFC file, it must be
* called by a name other than "ssh" or "Secure Shell".
*
* Copyright (c) 1999 Niels Provos. All rights reserved.
* Copyright (c) 2000, 2001, 2002, 2003 Markus Friedl. All rights reserved.
*
* Modified to work with SSLeay by Niels Provos <provos@citi.umich.edu>
* in Canada (German citizen).
*
* Redistribution and use in source and binary forms, with or without
* 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>
#ifdef HAVE_SYS_STAT_H
# include <sys/stat.h>
#endif
#include <sys/resource.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <netdb.h>
#ifdef HAVE_PATHS_H
#include <paths.h>
#endif
#include <pwd.h>
#include <signal.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <unistd.h>
#include <limits.h>
#include <locale.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#ifdef WITH_OPENSSL
#include <openssl/evp.h>
#include <openssl/err.h>
#endif
#include "openbsd-compat/openssl-compat.h"
#include "openbsd-compat/sys-queue.h"
#include "xmalloc.h"
#include "ssh.h"
#include "ssh2.h"
#include "canohost.h"
#include "compat.h"
#include "cipher.h"
#include "packet.h"
#include "sshbuf.h"
#include "channels.h"
#include "sshkey.h"
#include "authfd.h"
#include "authfile.h"
#include "pathnames.h"
#include "dispatch.h"
#include "clientloop.h"
#include "log.h"
#include "misc.h"
#include "readconf.h"
#include "sshconnect.h"
#include "kex.h"
#include "mac.h"
#include "sshpty.h"
#include "match.h"
#include "msg.h"
#include "version.h"
#include "ssherr.h"
#include "myproposal.h"
#include "utf8.h"
#ifdef ENABLE_PKCS11
#include "ssh-pkcs11.h"
#endif
extern char *__progname;
/* Saves a copy of argv for setproctitle emulation */
#ifndef HAVE_SETPROCTITLE
static char **saved_av;
#endif
/* Flag indicating whether debug mode is on. May be set on the command line. */
int debug_flag = 0;
/* Flag indicating whether a tty should be requested */
int tty_flag = 0;
/*
* Flag indicating that the current process should be backgrounded and
* a new mux-client launched in the foreground for ControlPersist.
*/
int need_controlpersist_detach = 0;
/* Copies of flags for ControlPersist foreground mux-client */
int ostdin_null_flag, osession_type, otty_flag, orequest_tty;
/*
* General data structure for command line options and options configurable
* in configuration files. See readconf.h.
*/
Options options;
/* optional user configfile */
char *config = NULL;
/*
* Name of the host we are connecting to. This is the name given on the
* command line, or the Hostname specified for the user-supplied name in a
* configuration file.
*/
char *host;
/*
* A config can specify a path to forward, overriding SSH_AUTH_SOCK. If this is
* not NULL, forward the socket at this path instead.
*/
char *forward_agent_sock_path = NULL;
/* socket address the host resolves to */
struct sockaddr_storage hostaddr;
/* Private host keys. */
Sensitive sensitive_data;
/* command to be executed */
struct sshbuf *command;
/* # of replies received for global requests */
static int forward_confirms_pending = -1;
/* mux.c */
extern int muxserver_sock;
extern u_int muxclient_command;
/* Prints a help message to the user. This function never returns. */
static void
usage(void)
{
fprintf(stderr,
"usage: ssh [-46AaCfGgKkMNnqsTtVvXxYy] [-B bind_interface]\n"
" [-b bind_address] [-c cipher_spec] [-D [bind_address:]port]\n"
" [-E log_file] [-e escape_char] [-F configfile] [-I pkcs11]\n"
" [-i identity_file] [-J [user@]host[:port]] [-L address]\n"
" [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]\n"
" [-Q query_option] [-R address] [-S ctl_path] [-W host:port]\n"
" [-w local_tun[:remote_tun]] destination [command [argument ...]]\n"
);
exit(255);
}
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. */
static void
tilde_expand_paths(char **paths, u_int num_paths)
{
u_int i;
char *cp;
for (i = 0; i < num_paths; i++) {
cp = tilde_expand_filename(paths[i], getuid());
free(paths[i]);
paths[i] = cp;
}
}
/*
* Expands the set of percent_expand options used by the majority of keywords
* in the client that support percent expansion.
* Caller must free returned string.
*/
static char *
default_client_percent_expand(const char *str,
const struct ssh_conn_info *cinfo)
{
return percent_expand(str,
DEFAULT_CLIENT_PERCENT_EXPAND_ARGS(cinfo),
(char *)NULL);
}
/*
* Expands the set of percent_expand options used by the majority of keywords
* AND perform environment variable substitution.
* Caller must free returned string.
*/
static char *
default_client_percent_dollar_expand(const char *str,
const struct ssh_conn_info *cinfo)
{
char *ret;
ret = percent_dollar_expand(str,
DEFAULT_CLIENT_PERCENT_EXPAND_ARGS(cinfo),
(char *)NULL);
if (ret == NULL)
fatal("invalid environment variable expansion");
return ret;
}
/*
* Attempt to resolve a host name / port to a set of addresses and
* optionally return any CNAMEs encountered along the way.
* Returns NULL on failure.
* NB. this function must operate with a options having undefined members.
*/
static struct addrinfo *
resolve_host(const char *name, int port, int logerr, char *cname, size_t clen)
{
char strport[NI_MAXSERV];
const char *errstr = NULL;
struct addrinfo hints, *res;
int gaierr;
LogLevel loglevel = SYSLOG_LEVEL_DEBUG1;
if (port <= 0)
port = default_ssh_port();
if (cname != NULL)
*cname = '\0';
debug3_f("lookup %s:%d", name, port);
snprintf(strport, sizeof strport, "%d", port);
memset(&hints, 0, sizeof(hints));
hints.ai_family = options.address_family == -1 ?
AF_UNSPEC : options.address_family;
hints.ai_socktype = SOCK_STREAM;
if (cname != NULL)
hints.ai_flags = AI_CANONNAME;
if ((gaierr = getaddrinfo(name, strport, &hints, &res)) != 0) {
if (logerr || (gaierr != EAI_NONAME && gaierr != EAI_NODATA))
loglevel = SYSLOG_LEVEL_ERROR;
do_log2(loglevel, "%s: Could not resolve hostname %.100s: %s",
__progname, name, ssh_gai_strerror(gaierr));
return NULL;
}
if (cname != NULL && res->ai_canonname != NULL) {
if (!valid_domain(res->ai_canonname, 0, &errstr)) {
error("ignoring bad CNAME \"%s\" for host \"%s\": %s",
res->ai_canonname, name, errstr);
} else if (strlcpy(cname, res->ai_canonname, clen) >= clen) {
error_f("host \"%s\" cname \"%s\" too long (max %lu)",
name, res->ai_canonname, (u_long)clen);
if (clen > 0)
*cname = '\0';
}
}
return res;
}
/* Returns non-zero if name can only be an address and not a hostname */
static int
is_addr_fast(const char *name)
{
return (strchr(name, '%') != NULL || strchr(name, ':') != NULL ||
strspn(name, "0123456789.") == strlen(name));
}
/* Returns non-zero if name represents a valid, single address */
static int
is_addr(const char *name)
{
char strport[NI_MAXSERV];
struct addrinfo hints, *res;
if (is_addr_fast(name))
return 1;
snprintf(strport, sizeof strport, "%u", default_ssh_port());
memset(&hints, 0, sizeof(hints));
hints.ai_family = options.address_family == -1 ?
AF_UNSPEC : options.address_family;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_NUMERICHOST|AI_NUMERICSERV;
if (getaddrinfo(name, strport, &hints, &res) != 0)
return 0;
if (res == NULL || res->ai_next != NULL) {
freeaddrinfo(res);
return 0;
}
freeaddrinfo(res);
return 1;
}
/*
* Attempt to resolve a numeric host address / port to a single address.
* Returns a canonical address string.
* Returns NULL on failure.
* NB. this function must operate with a options having undefined members.
*/
static struct addrinfo *
resolve_addr(const char *name, int port, char *caddr, size_t clen)
{
char addr[NI_MAXHOST], strport[NI_MAXSERV];
struct addrinfo hints, *res;
int gaierr;
if (port <= 0)
port = default_ssh_port();
snprintf(strport, sizeof strport, "%u", port);
memset(&hints, 0, sizeof(hints));
hints.ai_family = options.address_family == -1 ?
AF_UNSPEC : options.address_family;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_NUMERICHOST|AI_NUMERICSERV;
if ((gaierr = getaddrinfo(name, strport, &hints, &res)) != 0) {
debug2_f("could not resolve name %.100s as address: %s",
name, ssh_gai_strerror(gaierr));
return NULL;
}
if (res == NULL) {
debug_f("getaddrinfo %.100s returned no addresses", name);
return NULL;
}
if (res->ai_next != NULL) {
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_f("Could not format address for name %.100s: %s",
name, ssh_gai_strerror(gaierr));
goto fail;
}
if (strlcpy(caddr, addr, clen) >= clen) {
error_f("host \"%s\" addr \"%s\" too long (max %lu)",
name, addr, (u_long)clen);
if (clen > 0)
*caddr = '\0';
fail:
freeaddrinfo(res);
return NULL;
}
return res;
}
/*
* Check whether the cname is a permitted replacement for the hostname
* and perform the replacement if it is.
* NB. this function must operate with a options having undefined members.
*/
static int
check_follow_cname(int direct, char **namep, const char *cname)
{
int i;
struct allowed_cname *rule;
if (*cname == '\0' || !config_has_permitted_cnames(&options) ||
strcmp(*namep, cname) == 0)
return 0;
if (options.canonicalize_hostname == SSH_CANONICALISE_NO)
return 0;
/*
* Don't attempt to canonicalize names that will be interpreted by
* a proxy or jump host unless the user specifically requests so.
*/
if (!direct &&
options.canonicalize_hostname != SSH_CANONICALISE_ALWAYS)
return 0;
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 ||
match_pattern_list(cname, rule->target_list, 1) != 1)
continue;
verbose("Canonicalized DNS aliased hostname "
"\"%s\" => \"%s\"", *namep, cname);
free(*namep);
*namep = xstrdup(cname);
return 1;
}
return 0;
}
/*
* Attempt to resolve the supplied hostname after applying the user's
* canonicalization rules. Returns the address list for the host or NULL
* if no name was found after canonicalization.
* NB. this function must operate with a options having undefined members.
*/
static struct addrinfo *
resolve_canonicalize(char **hostp, int port)
{
int i, direct, ndots;
char *cp, *fullhost, newname[NI_MAXHOST];
struct addrinfo *addrs;
/*
* Attempt to canonicalise addresses, regardless of
* whether hostname canonicalisation was requested
*/
if ((addrs = resolve_addr(*hostp, port,
newname, sizeof(newname))) != NULL) {
debug2_f("hostname %.100s is address", *hostp);
if (strcasecmp(*hostp, newname) != 0) {
debug2_f("canonicalised address \"%s\" => \"%s\"",
*hostp, newname);
free(*hostp);
*hostp = xstrdup(newname);
}
return addrs;
}
/*
* If this looks like an address but didn't parse as one, it might
* be an address with an invalid interface scope. Skip further
* attempts at canonicalisation.
*/
if (is_addr_fast(*hostp)) {
debug_f("hostname %.100s is an unrecognised address", *hostp);
return NULL;
}
if (options.canonicalize_hostname == SSH_CANONICALISE_NO)
return NULL;
/*
* Don't attempt to canonicalize names that will be interpreted by
* a proxy unless the user specifically requests so.
*/
direct = option_clear_or_none(options.proxy_command) &&
options.jump_host == NULL;
if (!direct &&
options.canonicalize_hostname != SSH_CANONICALISE_ALWAYS)
return NULL;
/* If domain name is anchored, then resolve it now */
if ((*hostp)[strlen(*hostp) - 1] == '.') {
debug3_f("name is fully qualified");
fullhost = xstrdup(*hostp);
if ((addrs = resolve_host(fullhost, port, 0,
newname, sizeof(newname))) != NULL)
goto found;
free(fullhost);
goto notfound;
}
/* Don't apply canonicalization to sufficiently-qualified hostnames */
ndots = 0;
for (cp = *hostp; *cp != '\0'; cp++) {
if (*cp == '.')
ndots++;
}
if (ndots > 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_f("attempting \"%s\" => \"%s\"", *hostp, fullhost);
if ((addrs = resolve_host(fullhost, port, 0,
newname, sizeof(newname))) == NULL) {
free(fullhost);
continue;
}
found:
/* Remove trailing '.' */
fullhost[strlen(fullhost) - 1] = '\0';
/* Follow CNAME if requested */
if (!check_follow_cname(direct, &fullhost, newname)) {
debug("Canonicalized hostname \"%s\" => \"%s\"",
*hostp, fullhost);
}
free(*hostp);
*hostp = fullhost;
return addrs;
}
notfound:
if (!options.canonicalize_fallback_local)
fatal("%s: Could not resolve host \"%s\"", __progname, *hostp);
debug2_f("host %s not found in any suffix", *hostp);
return NULL;
}
/*
* Check the result of hostkey loading, ignoring some errors and either
* discarding the key or fatal()ing for others.
*/
static void
check_load(int r, struct sshkey **k, const char *path, const char *message)
{
switch (r) {
case 0:
/* Check RSA keys size and discard if undersized */
if (k != NULL && *k != NULL &&
(r = sshkey_check_rsa_length(*k,
options.required_rsa_size)) != 0) {
error_r(r, "load %s \"%s\"", message, path);
free(*k);
*k = NULL;
}
break;
case SSH_ERR_INTERNAL_ERROR:
case SSH_ERR_ALLOC_FAIL:
fatal_r(r, "load %s \"%s\"", message, path);
case SSH_ERR_SYSTEM_ERROR:
/* Ignore missing files */
if (errno == ENOENT)
break;
/* FALLTHROUGH */
default:
error_r(r, "load %s \"%s\"", message, path);
break;
}
}
/*
* Read per-user configuration file. Ignore the system wide config
* file if the user specifies a config file on the command line.
*/
static void
process_config_files(const char *host_name, struct passwd *pw, int final_pass,
int *want_final_pass)
{
char buf[PATH_MAX];
int r;
if (config != NULL) {
if (strcasecmp(config, "none") != 0 &&
!read_config_file(config, pw, host, host_name, &options,
SSHCONF_USERCONF | (final_pass ? SSHCONF_FINAL : 0),
want_final_pass))
fatal("Can't open user config file %.100s: "
"%.100s", config, strerror(errno));
} else {
r = snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir,
_PATH_SSH_USER_CONFFILE);
if (r > 0 && (size_t)r < sizeof(buf))
(void)read_config_file(buf, pw, host, host_name,
&options, SSHCONF_CHECKPERM | SSHCONF_USERCONF |
(final_pass ? SSHCONF_FINAL : 0), want_final_pass);
/* Read systemwide configuration file after user config. */
(void)read_config_file(_PATH_HOST_CONFIG_FILE, pw,
host, host_name, &options,
final_pass ? SSHCONF_FINAL : 0, want_final_pass);
}
}
/* Rewrite the port number in an addrinfo list of addresses */
static void
set_addrinfo_port(struct addrinfo *addrs, int port)
{
struct addrinfo *addr;
for (addr = addrs; addr != NULL; addr = addr->ai_next) {
switch (addr->ai_family) {
case AF_INET:
((struct sockaddr_in *)addr->ai_addr)->
sin_port = htons(port);
break;
case AF_INET6:
((struct sockaddr_in6 *)addr->ai_addr)->
sin6_port = htons(port);
break;
}
}
}
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.
*/
int
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, *host_arg;
+ char *p, *cp, *line, *argv0, *logfile;
char cname[NI_MAXHOST], thishost[NI_MAXHOST];
struct stat st;
struct passwd *pw;
extern int optind, optreset;
extern char *optarg;
struct Forward fwd;
struct addrinfo *addrs = NULL;
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
/* Prepare for later setproctitle emulation */
/* Save argv so it isn't clobbered by setproctitle() emulation */
saved_av = xcalloc(ac + 1, sizeof(*saved_av));
for (i = 0; i < ac; i++)
saved_av[i] = xstrdup(av[i]);
saved_av[i] = NULL;
compat_init_setproctitle(ac, av);
av = saved_av;
#endif
seed_rng();
/* Get user data. */
pw = getpwuid(getuid());
if (!pw) {
logit("No user exists for uid %lu", (u_long)getuid());
exit(255);
}
/* Take a copy of the returned structure. */
pw = pwcopy(pw);
/*
* Set our umask to something reasonable, as some files are created
* with the default umask. This will make them world-readable but
* writable only by the owner, which is ok for all files for which we
* don't set the modes explicitly.
*/
- umask(022);
+ umask(022 | umask(077));
msetlocale();
/*
* Initialize option structure to indicate that no values have been
* set.
*/
initialize_options(&options);
/*
* Prepare main ssh transport/connection structures
*/
if ((ssh = ssh_alloc_session_state()) == NULL)
fatal("Couldn't allocate session state");
channel_init_channels(ssh);
/* Parse command-line arguments. */
host = NULL;
use_syslog = 0;
logfile = NULL;
argv0 = av[0];
again:
while ((opt = getopt(ac, av, "1246ab:c:e:fgi:kl:m:no:p:qstvx"
"AB:CD:E:F:GI:J:KL:MNO:PQ:R:S:TVw:W:XYy")) != -1) { /* HUZdhjruz */
switch (opt) {
case '1':
fatal("SSH protocol v.1 is no longer supported");
break;
case '2':
/* Ignored */
break;
case '4':
options.address_family = AF_INET;
break;
case '6':
options.address_family = AF_INET6;
break;
case 'n':
options.stdin_null = 1;
break;
case 'f':
options.fork_after_authentication = 1;
options.stdin_null = 1;
break;
case 'x':
options.forward_x11 = 0;
break;
case 'X':
options.forward_x11 = 1;
break;
case 'y':
use_syslog = 1;
break;
case 'E':
logfile = optarg;
break;
case 'G':
config_test = 1;
break;
case 'Y':
options.forward_x11 = 1;
options.forward_x11_trusted = 1;
break;
case 'g':
options.fwd_opts.gateway_ports = 1;
break;
case 'O':
if (options.stdio_forward_host != NULL)
fatal("Cannot specify multiplexing "
"command with -W");
else if (muxclient_command != 0)
fatal("Multiplexing command already specified");
if (strcmp(optarg, "check") == 0)
muxclient_command = SSHMUX_COMMAND_ALIVE_CHECK;
else if (strcmp(optarg, "forward") == 0)
muxclient_command = SSHMUX_COMMAND_FORWARD;
else if (strcmp(optarg, "exit") == 0)
muxclient_command = SSHMUX_COMMAND_TERMINATE;
else if (strcmp(optarg, "stop") == 0)
muxclient_command = SSHMUX_COMMAND_STOP;
else if (strcmp(optarg, "cancel") == 0)
muxclient_command = SSHMUX_COMMAND_CANCEL_FWD;
else if (strcmp(optarg, "proxy") == 0)
muxclient_command = SSHMUX_COMMAND_PROXY;
else
fatal("Invalid multiplex command.");
break;
case 'P': /* deprecated */
break;
case 'Q':
cp = NULL;
if (strcmp(optarg, "cipher") == 0 ||
strcasecmp(optarg, "Ciphers") == 0)
cp = cipher_alg_list('\n', 0);
else if (strcmp(optarg, "cipher-auth") == 0)
cp = cipher_alg_list('\n', 1);
else if (strcmp(optarg, "mac") == 0 ||
strcasecmp(optarg, "MACs") == 0)
cp = mac_alg_list('\n');
else if (strcmp(optarg, "kex") == 0 ||
strcasecmp(optarg, "KexAlgorithms") == 0)
cp = kex_alg_list('\n');
else if (strcmp(optarg, "key") == 0)
cp = sshkey_alg_list(0, 0, 0, '\n');
else if (strcmp(optarg, "key-cert") == 0)
cp = sshkey_alg_list(1, 0, 0, '\n');
else if (strcmp(optarg, "key-plain") == 0)
cp = sshkey_alg_list(0, 1, 0, '\n');
else if (strcmp(optarg, "key-sig") == 0 ||
strcasecmp(optarg, "PubkeyAcceptedKeyTypes") == 0 || /* deprecated name */
strcasecmp(optarg, "PubkeyAcceptedAlgorithms") == 0 ||
strcasecmp(optarg, "HostKeyAlgorithms") == 0 ||
strcasecmp(optarg, "HostbasedKeyTypes") == 0 || /* deprecated name */
strcasecmp(optarg, "HostbasedAcceptedKeyTypes") == 0 || /* deprecated name */
strcasecmp(optarg, "HostbasedAcceptedAlgorithms") == 0)
cp = sshkey_alg_list(0, 0, 1, '\n');
else if (strcmp(optarg, "sig") == 0)
cp = sshkey_alg_list(0, 1, 1, '\n');
else if (strcmp(optarg, "protocol-version") == 0)
cp = xstrdup("2");
else if (strcmp(optarg, "compression") == 0) {
cp = xstrdup(compression_alg_list(0));
len = strlen(cp);
for (n = 0; n < len; n++)
if (cp[n] == ',')
cp[n] = '\n';
} else if (strcmp(optarg, "help") == 0) {
cp = xstrdup(
"cipher\ncipher-auth\ncompression\nkex\n"
"key\nkey-cert\nkey-plain\nkey-sig\nmac\n"
"protocol-version\nsig");
}
if (cp == NULL)
fatal("Unsupported query \"%s\"", optarg);
printf("%s\n", cp);
free(cp);
exit(0);
break;
case 'a':
options.forward_agent = 0;
break;
case 'A':
options.forward_agent = 1;
break;
case 'k':
options.gss_deleg_creds = 0;
break;
case 'K':
options.gss_authentication = 1;
options.gss_deleg_creds = 1;
break;
case 'i':
p = tilde_expand_filename(optarg, getuid());
if (stat(p, &st) == -1)
fprintf(stderr, "Warning: Identity file %s "
"not accessible: %s.\n", p,
strerror(errno));
else
add_identity_file(&options, NULL, p, 1);
free(p);
break;
case 'I':
#ifdef ENABLE_PKCS11
free(options.pkcs11_provider);
options.pkcs11_provider = xstrdup(optarg);
#else
fprintf(stderr, "no support for PKCS#11.\n");
#endif
break;
case 'J':
if (options.jump_host != NULL) {
fatal("Only a single -J option is permitted "
"(use commas to separate multiple "
"jump hops)");
}
if (options.proxy_command != NULL)
fatal("Cannot specify -J with ProxyCommand");
if (parse_jump(optarg, &options, 1) == -1)
fatal("Invalid -J argument");
options.proxy_command = xstrdup("none");
break;
case 't':
if (options.request_tty == REQUEST_TTY_YES)
options.request_tty = REQUEST_TTY_FORCE;
else
options.request_tty = REQUEST_TTY_YES;
break;
case 'v':
if (debug_flag == 0) {
debug_flag = 1;
options.log_level = SYSLOG_LEVEL_DEBUG1;
} else {
if (options.log_level < SYSLOG_LEVEL_DEBUG3) {
debug_flag++;
options.log_level++;
}
}
break;
case 'V':
if (options.version_addendum != NULL &&
*options.version_addendum != '\0')
fprintf(stderr, "%s %s, %s\n", SSH_RELEASE,
options.version_addendum,
SSH_OPENSSL_VERSION);
else
fprintf(stderr, "%s, %s\n", SSH_RELEASE,
SSH_OPENSSL_VERSION);
- if (opt == 'V')
- exit(0);
+ exit(0);
break;
case 'w':
if (options.tun_open == -1)
options.tun_open = SSH_TUNMODE_DEFAULT;
options.tun_local = a2tun(optarg, &options.tun_remote);
if (options.tun_local == SSH_TUNID_ERR) {
fprintf(stderr,
"Bad tun device '%s'\n", optarg);
exit(255);
}
break;
case 'W':
if (options.stdio_forward_host != NULL)
fatal("stdio forward already specified");
if (muxclient_command != 0)
fatal("Cannot specify stdio forward with -O");
if (parse_forward(&fwd, optarg, 1, 0)) {
options.stdio_forward_host = fwd.listen_host;
options.stdio_forward_port = fwd.listen_port;
free(fwd.connect_host);
} else {
fprintf(stderr,
"Bad stdio forwarding specification '%s'\n",
optarg);
exit(255);
}
options.request_tty = REQUEST_TTY_NO;
options.session_type = SESSION_TYPE_NONE;
break;
case 'q':
options.log_level = SYSLOG_LEVEL_QUIET;
break;
case 'e':
if (optarg[0] == '^' && optarg[2] == 0 &&
(u_char) optarg[1] >= 64 &&
(u_char) optarg[1] < 128)
options.escape_char = (u_char) optarg[1] & 31;
else if (strlen(optarg) == 1)
options.escape_char = (u_char) optarg[0];
else if (strcmp(optarg, "none") == 0)
options.escape_char = SSH_ESCAPECHAR_NONE;
else {
fprintf(stderr, "Bad escape character '%s'.\n",
optarg);
exit(255);
}
break;
case 'c':
if (!ciphers_valid(*optarg == '+' || *optarg == '^' ?
optarg + 1 : optarg)) {
fprintf(stderr, "Unknown cipher type '%s'\n",
optarg);
exit(255);
}
free(options.ciphers);
options.ciphers = xstrdup(optarg);
break;
case 'm':
if (mac_valid(optarg)) {
free(options.macs);
options.macs = xstrdup(optarg);
} else {
fprintf(stderr, "Unknown mac type '%s'\n",
optarg);
exit(255);
}
break;
case 'M':
if (options.control_master == SSHCTL_MASTER_YES)
options.control_master = SSHCTL_MASTER_ASK;
else
options.control_master = SSHCTL_MASTER_YES;
break;
case 'p':
if (options.port == -1) {
options.port = a2port(optarg);
if (options.port <= 0) {
fprintf(stderr, "Bad port '%s'\n",
optarg);
exit(255);
}
}
break;
case 'l':
if (options.user == NULL)
options.user = optarg;
break;
case 'L':
if (parse_forward(&fwd, optarg, 0, 0))
add_local_forward(&options, &fwd);
else {
fprintf(stderr,
"Bad local forwarding specification '%s'\n",
optarg);
exit(255);
}
break;
case 'R':
if (parse_forward(&fwd, optarg, 0, 1) ||
parse_forward(&fwd, optarg, 1, 1)) {
add_remote_forward(&options, &fwd);
} else {
fprintf(stderr,
"Bad remote forwarding specification "
"'%s'\n", optarg);
exit(255);
}
break;
case 'D':
if (parse_forward(&fwd, optarg, 1, 0)) {
add_local_forward(&options, &fwd);
} else {
fprintf(stderr,
"Bad dynamic forwarding specification "
"'%s'\n", optarg);
exit(255);
}
break;
case 'C':
#ifdef WITH_ZLIB
options.compression = 1;
#else
error("Compression not supported, disabling.");
#endif
break;
case 'N':
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':
options.request_tty = REQUEST_TTY_NO;
break;
case 'o':
line = xstrdup(optarg);
if (process_config_line(&options, pw,
host ? host : "", host ? host : "", line,
"command-line", 0, NULL, SSHCONF_USERCONF) != 0)
exit(255);
free(line);
break;
case 's':
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);
options.control_path = xstrdup(optarg);
break;
case 'b':
options.bind_address = optarg;
break;
case 'B':
options.bind_interface = optarg;
break;
case 'F':
config = optarg;
break;
default:
usage();
}
}
if (optind > 1 && strcmp(av[optind - 1], "--") == 0)
opt_terminated = 1;
ac -= optind;
av += optind;
if (ac > 0 && !host) {
int tport;
char *tuser;
switch (parse_ssh_uri(*av, &tuser, &host, &tport)) {
case -1:
usage();
break;
case 0:
if (options.user == NULL) {
options.user = tuser;
tuser = NULL;
}
free(tuser);
if (options.port == -1 && tport != -1)
options.port = tport;
break;
default:
p = xstrdup(*av);
cp = strrchr(p, '@');
if (cp != NULL) {
if (cp == p)
usage();
if (options.user == NULL) {
options.user = p;
p = NULL;
}
*cp++ = '\0';
host = xstrdup(cp);
free(p);
} else
host = p;
break;
}
if (ac > 1 && !opt_terminated) {
optind = optreset = 1;
goto again;
}
ac--, av++;
}
/* Check that we got a host name. */
if (!host)
usage();
- host_arg = xstrdup(host);
+ options.host_arg = xstrdup(host);
/* Initialize the command to execute on remote host. */
if ((command = sshbuf_new()) == NULL)
fatal("sshbuf_new failed");
/*
* Save the command to execute on the remote host in a buffer. There
* is no limit on the length of the command, except by the maximum
* packet size. Also sets the tty flag if there is no command.
*/
if (!ac) {
/* No command specified - execute shell on a tty. */
if (options.session_type == SESSION_TYPE_SUBSYSTEM) {
fprintf(stderr,
"You must specify a subsystem to invoke.\n");
usage();
}
} else {
/* A command has been specified. Store it into the buffer. */
for (i = 0; i < ac; i++) {
if ((r = sshbuf_putf(command, "%s%s",
i ? " " : "", av[i])) != 0)
fatal_fr(r, "buffer error");
}
}
ssh_signal(SIGPIPE, SIG_IGN); /* ignore SIGPIPE early */
/*
* Initialize "log" output. Since we are the client all output
* goes to stderr unless otherwise specified by -y or -E.
*/
if (use_syslog && logfile != NULL)
fatal("Can't specify both -y and -E");
if (logfile != NULL)
log_redirect_stderr_to(logfile);
log_init(argv0,
options.log_level == SYSLOG_LEVEL_NOT_SET ?
SYSLOG_LEVEL_INFO : options.log_level,
options.log_facility == SYSLOG_FACILITY_NOT_SET ?
SYSLOG_FACILITY_USER : options.log_facility,
!use_syslog);
if (debug_flag)
/* version_addendum is always NULL at this point */
logit("%s, %s", SSH_RELEASE, SSH_OPENSSL_VERSION);
/* Parse the configuration files */
- process_config_files(host_arg, pw, 0, &want_final_pass);
+ process_config_files(options.host_arg, pw, 0, &want_final_pass);
if (want_final_pass)
debug("configuration requests final Match pass");
/* Hostname canonicalisation needs a few options filled. */
fill_default_options_for_canonicalization(&options);
/* If the user has replaced the hostname then take it into use now */
if (options.hostname != NULL) {
/* NB. Please keep in sync with readconf.c:match_cfg_line() */
cp = percent_expand(options.hostname,
"h", host, (char *)NULL);
free(host);
host = cp;
free(options.hostname);
options.hostname = xstrdup(host);
}
/* Don't lowercase addresses, they will be explicitly canonicalised */
if ((was_addr = is_addr(host)) == 0)
lowercase(host);
/*
* Try to canonicalize if requested by configuration or the
* hostname is an address.
*/
if (options.canonicalize_hostname != SSH_CANONICALISE_NO || was_addr)
addrs = resolve_canonicalize(&host, options.port);
/*
* If CanonicalizePermittedCNAMEs have been specified but
* other canonicalization did not happen (by not being requested
* or by failing with fallback) then the hostname may still be changed
* as a result of CNAME following.
*
* Try to resolve the bare hostname name using the system resolver's
* usual search rules and then apply the CNAME follow rules.
*
* Skip the lookup if a ProxyCommand is being used unless the user
* has specifically requested canonicalisation for this case via
* CanonicalizeHostname=always
*/
direct = option_clear_or_none(options.proxy_command) &&
options.jump_host == NULL;
if (addrs == NULL && config_has_permitted_cnames(&options) && (direct ||
options.canonicalize_hostname == SSH_CANONICALISE_ALWAYS)) {
if ((addrs = resolve_host(host, options.port,
direct, cname, sizeof(cname))) == NULL) {
/* Don't fatal proxied host names not in the DNS */
if (direct)
cleanup_exit(255); /* logged in resolve_host */
} else
check_follow_cname(direct, &host, cname);
}
/*
* If canonicalisation is enabled then re-parse the configuration
* files as new stanzas may match.
*/
if (options.canonicalize_hostname != 0 && !want_final_pass) {
debug("hostname canonicalisation enabled, "
"will re-parse configuration");
want_final_pass = 1;
}
if (want_final_pass) {
debug("re-parsing configuration");
free(options.hostname);
options.hostname = xstrdup(host);
- process_config_files(host_arg, pw, 1, NULL);
+ process_config_files(options.host_arg, pw, 1, NULL);
/*
* Address resolution happens early with canonicalisation
* enabled and the port number may have changed since, so
* reset it in address list
*/
if (addrs != NULL && options.port > 0)
set_addrinfo_port(addrs, options.port);
}
/* Fill configuration defaults. */
if (fill_default_options(&options) != 0)
cleanup_exit(255);
if (options.user == NULL)
options.user = xstrdup(pw->pw_name);
/*
* If ProxyJump option specified, then construct a ProxyCommand now.
*/
if (options.jump_host != NULL) {
char port_s[8];
const char *jumpuser = options.jump_user, *sshbin = argv0;
int port = options.port, jumpport = options.jump_port;
if (port <= 0)
port = default_ssh_port();
if (jumpport <= 0)
jumpport = default_ssh_port();
if (jumpuser == NULL)
jumpuser = options.user;
if (strcmp(options.jump_host, host) == 0 && port == jumpport &&
strcmp(options.user, jumpuser) == 0)
fatal("jumphost loop via %s", options.jump_host);
/*
* Try to use SSH indicated by argv[0], but fall back to
* "ssh" if it appears unavailable.
*/
if (strchr(argv0, '/') != NULL && access(argv0, X_OK) != 0)
sshbin = "ssh";
/* Consistency check */
if (options.proxy_command != NULL)
fatal("inconsistent options: ProxyCommand+ProxyJump");
/* Never use FD passing for ProxyJump */
options.proxy_use_fdpass = 0;
snprintf(port_s, sizeof(port_s), "%d", options.jump_port);
xasprintf(&options.proxy_command,
"%s%s%s%s%s%s%s%s%s%s%.*s -W '[%%h]:%%p' %s",
sshbin,
/* Optional "-l user" argument if jump_user set */
options.jump_user == NULL ? "" : " -l ",
options.jump_user == NULL ? "" : options.jump_user,
/* Optional "-p port" argument if jump_port set */
options.jump_port <= 0 ? "" : " -p ",
options.jump_port <= 0 ? "" : port_s,
/* Optional additional jump hosts ",..." */
options.jump_extra == NULL ? "" : " -J ",
options.jump_extra == NULL ? "" : options.jump_extra,
/* Optional "-F" argument if -F specified */
config == NULL ? "" : " -F ",
config == NULL ? "" : config,
/* Optional "-v" arguments if -v set */
debug_flag ? " -" : "",
debug_flag, "vvv",
/* Mandatory hostname */
options.jump_host);
debug("Setting implicit ProxyCommand from ProxyJump: %s",
options.proxy_command);
}
if (options.port == 0)
options.port = default_ssh_port();
channel_set_af(ssh, options.address_family);
/* Tidy and check options */
if (options.host_key_alias != NULL)
lowercase(options.host_key_alias);
if (options.proxy_command != NULL &&
strcmp(options.proxy_command, "-") == 0 &&
options.proxy_use_fdpass)
fatal("ProxyCommand=- and ProxyUseFDPass are incompatible");
if (options.update_hostkeys == SSH_UPDATE_HOSTKEYS_ASK) {
if (options.control_persist && options.control_path != NULL) {
debug("UpdateHostKeys=ask is incompatible with "
"ControlPersist; disabling");
options.update_hostkeys = 0;
} else if (sshbuf_len(command) != 0 ||
options.remote_command != NULL ||
options.request_tty == REQUEST_TTY_NO) {
debug("UpdateHostKeys=ask is incompatible with "
"remote command execution; disabling");
options.update_hostkeys = 0;
} else if (options.log_level < SYSLOG_LEVEL_INFO) {
/* no point logging anything; user won't see it */
options.update_hostkeys = 0;
}
}
if (options.connection_attempts <= 0)
fatal("Invalid number of ConnectionAttempts");
if (sshbuf_len(command) != 0 && options.remote_command != NULL)
fatal("Cannot execute command-line and remote command.");
/* Cannot fork to background if no command. */
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)
tty_flag = 1;
/* Allocate a tty by default if no command specified. */
if (sshbuf_len(command) == 0 && options.remote_command == NULL)
tty_flag = options.request_tty != REQUEST_TTY_NO;
/* Force no tty */
if (options.request_tty == REQUEST_TTY_NO ||
(muxclient_command && muxclient_command != SSHMUX_COMMAND_PROXY) ||
options.session_type == SESSION_TYPE_NONE)
tty_flag = 0;
/* Do not allocate a tty if stdin is not a tty. */
if ((!isatty(fileno(stdin)) || options.stdin_null) &&
options.request_tty != REQUEST_TTY_FORCE) {
if (tty_flag)
logit("Pseudo-terminal will not be allocated because "
"stdin is not a terminal.");
tty_flag = 0;
}
/* Set up strings used to percent_expand() arguments */
cinfo = xcalloc(1, sizeof(*cinfo));
if (gethostname(thishost, sizeof(thishost)) == -1)
fatal("gethostname: %s", strerror(errno));
cinfo->thishost = xstrdup(thishost);
thishost[strcspn(thishost, ".")] = '\0';
cinfo->shorthost = xstrdup(thishost);
xasprintf(&cinfo->portstr, "%d", options.port);
xasprintf(&cinfo->uidstr, "%llu",
(unsigned long long)pw->pw_uid);
cinfo->keyalias = xstrdup(options.host_key_alias ?
- options.host_key_alias : host_arg);
+ options.host_key_alias : options.host_arg);
cinfo->conn_hash_hex = ssh_connection_hash(cinfo->thishost, host,
cinfo->portstr, options.user);
- cinfo->host_arg = xstrdup(host_arg);
+ cinfo->host_arg = xstrdup(options.host_arg);
cinfo->remhost = xstrdup(host);
cinfo->remuser = xstrdup(options.user);
cinfo->homedir = xstrdup(pw->pw_dir);
cinfo->locuser = xstrdup(pw->pw_name);
/* Find canonic host name. */
if (strchr(host, '.') == 0) {
struct addrinfo hints;
struct addrinfo *ai = NULL;
int errgai;
memset(&hints, 0, sizeof(hints));
hints.ai_family = options.address_family;
hints.ai_flags = AI_CANONNAME;
hints.ai_socktype = SOCK_STREAM;
errgai = getaddrinfo(host, NULL, &hints, &ai);
if (errgai == 0) {
if (ai->ai_canonname != NULL)
host = xstrdup(ai->ai_canonname);
freeaddrinfo(ai);
}
}
/*
* Expand tokens in arguments. NB. LocalCommand is expanded later,
* after port-forwarding is set up, so it may pick up any local
* tunnel interface name allocated.
*/
if (options.remote_command != NULL) {
debug3("expanding RemoteCommand: %s", options.remote_command);
cp = options.remote_command;
options.remote_command = default_client_percent_expand(cp,
cinfo);
debug3("expanded RemoteCommand: %s", options.remote_command);
free(cp);
if ((r = sshbuf_put(command, options.remote_command,
strlen(options.remote_command))) != 0)
fatal_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,
cinfo);
free(cp);
}
if (options.identity_agent != NULL) {
p = tilde_expand_filename(options.identity_agent, getuid());
cp = default_client_percent_dollar_expand(p, cinfo);
free(p);
free(options.identity_agent);
options.identity_agent = cp;
}
if (options.forward_agent_sock_path != NULL) {
p = tilde_expand_filename(options.forward_agent_sock_path,
getuid());
cp = default_client_percent_dollar_expand(p, cinfo);
free(p);
free(options.forward_agent_sock_path);
options.forward_agent_sock_path = cp;
if (stat(options.forward_agent_sock_path, &st) != 0) {
error("Cannot forward agent socket path \"%s\": %s",
options.forward_agent_sock_path, strerror(errno));
if (options.exit_on_forward_failure)
cleanup_exit(255);
}
}
if (options.num_system_hostfiles > 0 &&
strcasecmp(options.system_hostfiles[0], "none") == 0) {
if (options.num_system_hostfiles > 1)
fatal("Invalid GlobalKnownHostsFiles: \"none\" "
"appears with other entries");
free(options.system_hostfiles[0]);
options.system_hostfiles[0] = NULL;
options.num_system_hostfiles = 0;
}
if (options.num_user_hostfiles > 0 &&
strcasecmp(options.user_hostfiles[0], "none") == 0) {
if (options.num_user_hostfiles > 1)
fatal("Invalid UserKnownHostsFiles: \"none\" "
"appears with other entries");
free(options.user_hostfiles[0]);
options.user_hostfiles[0] = NULL;
options.num_user_hostfiles = 0;
}
for (j = 0; j < options.num_user_hostfiles; j++) {
if (options.user_hostfiles[j] == NULL)
continue;
cp = tilde_expand_filename(options.user_hostfiles[j], getuid());
p = default_client_percent_dollar_expand(cp, cinfo);
if (strcmp(options.user_hostfiles[j], p) != 0)
debug3("expanded UserKnownHostsFile '%s' -> "
"'%s'", options.user_hostfiles[j], p);
free(options.user_hostfiles[j]);
free(cp);
options.user_hostfiles[j] = p;
}
for (i = 0; i < options.num_local_forwards; i++) {
if (options.local_forwards[i].listen_path != NULL) {
cp = options.local_forwards[i].listen_path;
p = options.local_forwards[i].listen_path =
default_client_percent_expand(cp, cinfo);
if (strcmp(cp, p) != 0)
debug3("expanded LocalForward listen path "
"'%s' -> '%s'", cp, p);
free(cp);
}
if (options.local_forwards[i].connect_path != NULL) {
cp = options.local_forwards[i].connect_path;
p = options.local_forwards[i].connect_path =
default_client_percent_expand(cp, cinfo);
if (strcmp(cp, p) != 0)
debug3("expanded LocalForward connect path "
"'%s' -> '%s'", cp, p);
free(cp);
}
}
for (i = 0; i < options.num_remote_forwards; i++) {
if (options.remote_forwards[i].listen_path != NULL) {
cp = options.remote_forwards[i].listen_path;
p = options.remote_forwards[i].listen_path =
default_client_percent_expand(cp, cinfo);
if (strcmp(cp, p) != 0)
debug3("expanded RemoteForward listen path "
"'%s' -> '%s'", cp, p);
free(cp);
}
if (options.remote_forwards[i].connect_path != NULL) {
cp = options.remote_forwards[i].connect_path;
p = options.remote_forwards[i].connect_path =
default_client_percent_expand(cp, cinfo);
if (strcmp(cp, p) != 0)
debug3("expanded RemoteForward connect path "
"'%s' -> '%s'", cp, p);
free(cp);
}
}
if (config_test) {
dump_client_config(&options, host);
exit(0);
}
/* Expand SecurityKeyProvider if it refers to an environment variable */
if (options.sk_provider != NULL && *options.sk_provider == '$' &&
strlen(options.sk_provider) > 1) {
if ((cp = getenv(options.sk_provider + 1)) == NULL) {
debug("Authenticator provider %s did not resolve; "
"disabling", options.sk_provider);
free(options.sk_provider);
options.sk_provider = NULL;
} else {
debug2("resolved SecurityKeyProvider %s => %s",
options.sk_provider, cp);
free(options.sk_provider);
options.sk_provider = xstrdup(cp);
}
}
if (muxclient_command != 0 && options.control_path == NULL)
fatal("No ControlPath specified for \"-O\" command");
if (options.control_path != NULL) {
int sock;
if ((sock = muxclient(options.control_path)) >= 0) {
ssh_packet_set_connection(ssh, sock, sock);
ssh_packet_set_mux(ssh);
goto skip_connect;
}
}
/*
* If hostname canonicalisation was not enabled, then we may not
* have yet resolved the hostname. Do so now.
*/
if (addrs == NULL && options.proxy_command == NULL) {
debug2("resolving \"%s\" port %d", host, options.port);
if ((addrs = resolve_host(host, options.port, 1,
cname, sizeof(cname))) == NULL)
cleanup_exit(255); /* resolve_host logs the error */
}
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.connection_attempts,
+ if (ssh_connect(ssh, host, options.host_arg, addrs, &hostaddr,
+ options.port, options.connection_attempts,
&timeout_ms, options.tcp_keep_alive) != 0)
exit(255);
if (addrs != NULL)
freeaddrinfo(addrs);
ssh_packet_set_timeout(ssh, options.server_alive_interval,
options.server_alive_count_max);
if (timeout_ms > 0)
debug3("timeout: %d ms remain after connect", timeout_ms);
/*
* If we successfully made the connection and we have hostbased auth
* enabled, load the public keys so we can later use the ssh-keysign
* helper to sign challenges.
*/
sensitive_data.nkeys = 0;
sensitive_data.keys = NULL;
if (options.hostbased_authentication) {
+ int loaded = 0;
+
sensitive_data.nkeys = 10;
sensitive_data.keys = xcalloc(sensitive_data.nkeys,
- sizeof(struct sshkey));
+ sizeof(*sensitive_data.keys));
/* XXX check errors? */
#define L_PUBKEY(p,o) do { \
if ((o) >= sensitive_data.nkeys) \
fatal_f("pubkey out of array bounds"); \
check_load(sshkey_load_public(p, &(sensitive_data.keys[o]), NULL), \
&(sensitive_data.keys[o]), p, "pubkey"); \
- if (sensitive_data.keys[o] != NULL) \
+ if (sensitive_data.keys[o] != NULL) { \
debug2("hostbased key %d: %s key from \"%s\"", o, \
sshkey_ssh_name(sensitive_data.keys[o]), p); \
+ loaded++; \
+ } \
} while (0)
#define L_CERT(p,o) do { \
if ((o) >= sensitive_data.nkeys) \
fatal_f("cert out of array bounds"); \
check_load(sshkey_load_cert(p, &(sensitive_data.keys[o])), \
&(sensitive_data.keys[o]), p, "cert"); \
- if (sensitive_data.keys[o] != NULL) \
+ if (sensitive_data.keys[o] != NULL) { \
debug2("hostbased key %d: %s cert from \"%s\"", o, \
sshkey_ssh_name(sensitive_data.keys[o]), p); \
+ loaded++; \
+ } \
} while (0)
if (options.hostbased_authentication == 1) {
L_CERT(_PATH_HOST_ECDSA_KEY_FILE, 0);
L_CERT(_PATH_HOST_ED25519_KEY_FILE, 1);
L_CERT(_PATH_HOST_RSA_KEY_FILE, 2);
L_CERT(_PATH_HOST_DSA_KEY_FILE, 3);
L_PUBKEY(_PATH_HOST_ECDSA_KEY_FILE, 4);
L_PUBKEY(_PATH_HOST_ED25519_KEY_FILE, 5);
L_PUBKEY(_PATH_HOST_RSA_KEY_FILE, 6);
L_PUBKEY(_PATH_HOST_DSA_KEY_FILE, 7);
L_CERT(_PATH_HOST_XMSS_KEY_FILE, 8);
L_PUBKEY(_PATH_HOST_XMSS_KEY_FILE, 9);
+ if (loaded == 0)
+ debug("HostbasedAuthentication enabled but no "
+ "local public host keys could be loaded.");
}
}
/* load options.identity_files */
load_public_identity_files(cinfo);
/* optionally set the SSH_AUTHSOCKET_ENV_NAME variable */
if (options.identity_agent &&
strcmp(options.identity_agent, SSH_AUTHSOCKET_ENV_NAME) != 0) {
if (strcmp(options.identity_agent, "none") == 0) {
unsetenv(SSH_AUTHSOCKET_ENV_NAME);
} else {
cp = options.identity_agent;
/* legacy (limited) format */
if (cp[0] == '$' && cp[1] != '{') {
if (!valid_env_name(cp + 1)) {
fatal("Invalid IdentityAgent "
"environment variable name %s", cp);
}
if ((p = getenv(cp + 1)) == NULL)
unsetenv(SSH_AUTHSOCKET_ENV_NAME);
else
setenv(SSH_AUTHSOCKET_ENV_NAME, p, 1);
} else {
/* identity_agent specifies a path directly */
setenv(SSH_AUTHSOCKET_ENV_NAME, cp, 1);
}
}
}
if (options.forward_agent && options.forward_agent_sock_path != NULL) {
cp = options.forward_agent_sock_path;
if (cp[0] == '$') {
if (!valid_env_name(cp + 1)) {
fatal("Invalid ForwardAgent environment variable name %s", cp);
}
if ((p = getenv(cp + 1)) != NULL)
forward_agent_sock_path = xstrdup(p);
else
options.forward_agent = 0;
free(cp);
} else {
forward_agent_sock_path = cp;
}
}
/* Expand ~ in known host file names. */
tilde_expand_paths(options.system_hostfiles,
options.num_system_hostfiles);
tilde_expand_paths(options.user_hostfiles, options.num_user_hostfiles);
ssh_signal(SIGCHLD, main_sigchld_handler);
/* 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, cinfo);
/* We no longer need the private host keys. Clear them now. */
if (sensitive_data.nkeys != 0) {
for (i = 0; i < sensitive_data.nkeys; i++) {
if (sensitive_data.keys[i] != NULL) {
/* Destroys contents safely */
debug3("clear hostkey %d", i);
sshkey_free(sensitive_data.keys[i]);
sensitive_data.keys[i] = NULL;
}
}
free(sensitive_data.keys);
}
for (i = 0; i < options.num_identity_files; i++) {
free(options.identity_files[i]);
options.identity_files[i] = NULL;
if (options.identity_keys[i]) {
sshkey_free(options.identity_keys[i]);
options.identity_keys[i] = NULL;
}
}
for (i = 0; i < options.num_certificate_files; i++) {
free(options.certificate_files[i]);
options.certificate_files[i] = NULL;
}
#ifdef ENABLE_PKCS11
(void)pkcs11_del_provider(options.pkcs11_provider);
#endif
skip_connect:
exit_status = ssh_session2(ssh, cinfo);
ssh_conn_info_free(cinfo);
ssh_packet_close(ssh);
if (options.control_path != NULL && muxserver_sock != -1)
unlink(options.control_path);
/* Kill ProxyCommand if it is running. */
ssh_kill_proxy_command();
return exit_status;
}
static void
control_persist_detach(void)
{
pid_t pid;
debug_f("backgrounding master process");
/*
* master (current process) into the background, and make the
* foreground process a client of the backgrounded master.
*/
switch ((pid = fork())) {
case -1:
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_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;
muxclient(options.control_path);
/* muxclient() doesn't return on success. */
fatal("Failed to connect to new control master");
}
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);
}
/* Do fork() after authentication. Used by "ssh -f" */
static void
fork_postauth(void)
{
if (need_controlpersist_detach)
control_persist_detach();
debug("forking to background");
options.fork_after_authentication = 0;
if (daemon(1, 1) == -1)
fatal("daemon() failed: %.200s", strerror(errno));
if (stdfd_devnull(1, 1, !(log_is_on_stderr() && debug_flag)) == -1)
error_f("stdfd_devnull failed");
}
static void
forwarding_success(void)
{
if (forward_confirms_pending == -1)
return;
if (--forward_confirms_pending == 0) {
debug_f("all expected forwarding replies received");
if (options.fork_after_authentication)
fork_postauth();
} else {
debug2_f("%d expected forwarding replies remaining",
forward_confirms_pending);
}
}
/* Callback for remote forward global requests */
static void
ssh_confirm_remote_forward(struct ssh *ssh, int type, u_int32_t seq, void *ctxt)
{
struct Forward *rfwd = (struct Forward *)ctxt;
u_int port;
int r;
/* XXX verbose() on failure? */
debug("remote forward %s for: listen %s%s%d, connect %s:%d",
type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure",
rfwd->listen_path ? rfwd->listen_path :
rfwd->listen_host ? rfwd->listen_host : "",
(rfwd->listen_path || rfwd->listen_host) ? ":" : "",
rfwd->listen_port, rfwd->connect_path ? rfwd->connect_path :
rfwd->connect_host, rfwd->connect_port);
if (rfwd->listen_path == NULL && rfwd->listen_port == 0) {
if (type == SSH2_MSG_REQUEST_SUCCESS) {
if ((r = sshpkt_get_u32(ssh, &port)) != 0)
fatal_fr(r, "parse packet");
if (port > 65535) {
error("Invalid allocated port %u for remote "
"forward to %s:%d", port,
rfwd->connect_host, rfwd->connect_port);
/* Ensure failure processing runs below */
type = SSH2_MSG_REQUEST_FAILURE;
channel_update_permission(ssh,
rfwd->handle, -1);
} else {
rfwd->allocated_port = (int)port;
logit("Allocated port %u for remote "
"forward to %s:%d",
rfwd->allocated_port, rfwd->connect_path ?
rfwd->connect_path : rfwd->connect_host,
rfwd->connect_port);
channel_update_permission(ssh,
rfwd->handle, rfwd->allocated_port);
}
} else {
channel_update_permission(ssh, rfwd->handle, -1);
}
}
if (type == SSH2_MSG_REQUEST_FAILURE) {
if (options.exit_on_forward_failure) {
if (rfwd->listen_path != NULL)
fatal("Error: remote port forwarding failed "
"for listen path %s", rfwd->listen_path);
else
fatal("Error: remote port forwarding failed "
"for listen port %d", rfwd->listen_port);
} else {
if (rfwd->listen_path != NULL)
logit("Warning: remote port forwarding failed "
"for listen path %s", rfwd->listen_path);
else
logit("Warning: remote port forwarding failed "
"for listen port %d", rfwd->listen_port);
}
}
forwarding_success();
}
static void
-client_cleanup_stdio_fwd(struct ssh *ssh, int id, void *arg)
+client_cleanup_stdio_fwd(struct ssh *ssh, int id, int force, void *arg)
{
debug("stdio forwarding: done");
cleanup_exit(0);
}
static void
ssh_stdio_confirm(struct ssh *ssh, int id, int success, void *arg)
{
if (!success)
fatal("stdio forwarding failed");
}
static void
ssh_tun_confirm(struct ssh *ssh, int id, int success, void *arg)
{
if (!success) {
error("Tunnel forwarding failed");
if (options.exit_on_forward_failure)
cleanup_exit(255);
}
debug_f("tunnel forward established, id=%d", id);
forwarding_success();
}
static void
ssh_init_stdio_forwarding(struct ssh *ssh)
{
Channel *c;
int in, out;
if (options.stdio_forward_host == NULL)
return;
debug3_f("%s:%d", options.stdio_forward_host,
options.stdio_forward_port);
if ((in = dup(STDIN_FILENO)) == -1 ||
(out = dup(STDOUT_FILENO)) == -1)
fatal_f("dup() in/out failed");
if ((c = channel_connect_stdio_fwd(ssh, options.stdio_forward_host,
options.stdio_forward_port, in, out,
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;
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]);
addr = hpdelim(&arg);
if (addr == NULL)
fatal_f("missing host in %s", what);
addr = cleanhostname(addr);
if (arg == NULL || ((port = permitopen_port(arg)) < 0))
fatal_f("bad port number in %s", what);
/* Send it to channels layer */
channel_add_permission(ssh, FORWARD_ADM,
where, addr, port);
free(oarg);
}
}
static void
ssh_init_forwarding(struct ssh *ssh, char **ifname)
{
int success = 0;
int i;
ssh_init_forward_permissions(ssh, "permitremoteopen",
options.permitted_remote_opens,
options.num_permitted_remote_opens);
if (options.exit_on_forward_failure)
forward_confirms_pending = 0; /* track pending requests */
/* Initiate local TCP/IP port forwardings. */
for (i = 0; i < options.num_local_forwards; i++) {
debug("Local connections to %.200s:%d forwarded to remote "
"address %.200s:%d",
(options.local_forwards[i].listen_path != NULL) ?
options.local_forwards[i].listen_path :
(options.local_forwards[i].listen_host == NULL) ?
(options.fwd_opts.gateway_ports ? "*" : "LOCALHOST") :
options.local_forwards[i].listen_host,
options.local_forwards[i].listen_port,
(options.local_forwards[i].connect_path != NULL) ?
options.local_forwards[i].connect_path :
options.local_forwards[i].connect_host,
options.local_forwards[i].connect_port);
success += channel_setup_local_fwd_listener(ssh,
&options.local_forwards[i], &options.fwd_opts);
}
if (i > 0 && success != i && options.exit_on_forward_failure)
fatal("Could not request local forwarding.");
if (i > 0 && success == 0)
error("Could not request local forwarding.");
/* Initiate remote TCP/IP port forwardings. */
for (i = 0; i < options.num_remote_forwards; i++) {
debug("Remote connections from %.200s:%d forwarded to "
"local address %.200s:%d",
(options.remote_forwards[i].listen_path != NULL) ?
options.remote_forwards[i].listen_path :
(options.remote_forwards[i].listen_host == NULL) ?
"LOCALHOST" : options.remote_forwards[i].listen_host,
options.remote_forwards[i].listen_port,
(options.remote_forwards[i].connect_path != NULL) ?
options.remote_forwards[i].connect_path :
options.remote_forwards[i].connect_host,
options.remote_forwards[i].connect_port);
if ((options.remote_forwards[i].handle =
channel_request_remote_forwarding(ssh,
&options.remote_forwards[i])) >= 0) {
client_register_global_confirm(
ssh_confirm_remote_forward,
&options.remote_forwards[i]);
forward_confirms_pending++;
} else if (options.exit_on_forward_failure)
fatal("Could not request remote forwarding.");
else
logit("Warning: Could not request remote forwarding.");
}
/* Initiate tunnel forwarding. */
if (options.tun_open != SSH_TUNMODE_NO) {
if ((*ifname = client_request_tun_fwd(ssh,
options.tun_open, options.tun_local,
options.tun_remote, ssh_tun_confirm, NULL)) != NULL)
forward_confirms_pending++;
else if (options.exit_on_forward_failure)
fatal("Could not request tunnel forwarding.");
else
error("Could not request tunnel forwarding.");
}
if (forward_confirms_pending > 0) {
debug_f("expecting replies for %d forwards",
forward_confirms_pending);
}
}
static void
check_agent_present(void)
{
int r;
if (options.forward_agent) {
/* Clear agent forwarding if we don't have an agent. */
if ((r = ssh_get_authentication_socket(NULL)) != 0) {
options.forward_agent = 0;
if (r != SSH_ERR_AGENT_NOT_PRESENT)
debug_r(r, "ssh_get_authentication_socket");
}
}
}
static void
ssh_session2_setup(struct ssh *ssh, int id, int success, void *arg)
{
extern char **environ;
const char *display, *term;
int r, interactive = tty_flag;
char *proto = NULL, *data = NULL;
if (!success)
- return; /* No need for error message, channels code sens one */
+ return; /* No need for error message, channels code sends one */
display = getenv("DISPLAY");
if (display == NULL && options.forward_x11)
debug("X11 forwarding requested but DISPLAY not set");
if (options.forward_x11 && client_x11_get_proto(ssh, display,
options.xauth_location, options.forward_x11_trusted,
options.forward_x11_timeout, &proto, &data) == 0) {
/* Request forwarding with authentication spoofing. */
debug("Requesting X11 forwarding with authentication "
"spoofing.");
x11_request_forwarding_with_spoofing(ssh, id, display, proto,
data, 1);
client_expect_confirm(ssh, id, "X11 forwarding", CONFIRM_WARN);
/* XXX exit_on_forward_failure */
interactive = 1;
}
check_agent_present();
if (options.forward_agent) {
debug("Requesting authentication agent forwarding.");
channel_request_start(ssh, id, "auth-agent-req@openssh.com", 0);
if ((r = sshpkt_send(ssh)) != 0)
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);
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);
}
/* open new channel for a session */
static int
ssh_session2_open(struct ssh *ssh)
{
Channel *c;
int window, packetmax, in, out, err;
if (options.stdin_null) {
in = open(_PATH_DEVNULL, O_RDONLY);
} else {
in = dup(STDIN_FILENO);
}
out = dup(STDOUT_FILENO);
err = dup(STDERR_FILENO);
if (in == -1 || out == -1 || err == -1)
fatal("dup() in/out/err failed");
window = CHAN_SES_WINDOW_DEFAULT;
packetmax = CHAN_SES_PACKET_DEFAULT;
if (tty_flag) {
window >>= 1;
packetmax >>= 1;
}
c = channel_new(ssh,
"session", SSH_CHANNEL_OPENING, in, out, err,
window, packetmax, CHAN_EXTENDED_WRITE,
"client-session", CHANNEL_NONBLOCK_STDIO);
debug3_f("channel_new: %d", c->self);
channel_send_open(ssh, c->self);
if (options.session_type != SESSION_TYPE_NONE)
channel_register_open_confirm(ssh, c->self,
ssh_session2_setup, NULL);
return c->self;
}
static int
ssh_session2(struct ssh *ssh, const struct ssh_conn_info *cinfo)
{
int r, id = -1;
char *cp, *tun_fwd_ifname = NULL;
/* XXX should be pre-session */
if (!options.control_persist)
ssh_init_stdio_forwarding(ssh);
ssh_init_forwarding(ssh, &tun_fwd_ifname);
if (options.local_command != NULL) {
debug3("expanding LocalCommand: %s", options.local_command);
cp = options.local_command;
options.local_command = percent_expand(cp,
DEFAULT_CLIENT_PERCENT_EXPAND_ARGS(cinfo),
"T", tun_fwd_ifname == NULL ? "NONE" : tun_fwd_ifname,
(char *)NULL);
debug3("expanded LocalCommand: %s", options.local_command);
free(cp);
}
/* Start listening for multiplex clients */
if (!ssh_packet_get_mux(ssh))
muxserver_listen(ssh);
/*
* If we are in control persist mode and have a working mux listen
* socket, then prepare to background ourselves and have a foreground
* client attach as a control client.
* NB. we must save copies of the flags that we override for
* the backgrounding, since we defer attachment of the client until
* after the connection is fully established (in particular,
* async rfwd replies have been received for ExitOnForwardFailure).
*/
if (options.control_persist && muxserver_sock != -1) {
ostdin_null_flag = options.stdin_null;
osession_type = options.session_type;
orequest_tty = options.request_tty;
otty_flag = tty_flag;
options.stdin_null = 1;
options.session_type = SESSION_TYPE_NONE;
tty_flag = 0;
if (!options.fork_after_authentication &&
(osession_type != SESSION_TYPE_NONE ||
options.stdio_forward_host != NULL))
need_controlpersist_detach = 1;
options.fork_after_authentication = 1;
}
/*
* ControlPersist mux listen socket setup failed, attempt the
* stdio forward setup that we skipped earlier.
*/
if (options.control_persist && muxserver_sock == -1)
ssh_init_stdio_forwarding(ssh);
if (options.session_type != SESSION_TYPE_NONE)
id = ssh_session2_open(ssh);
else {
ssh_packet_set_interactive(ssh,
options.control_master == SSHCTL_MASTER_NO,
options.ip_qos_interactive, options.ip_qos_bulk);
}
/* If we don't expect to open a new session, then disallow it */
if (options.control_master == SSHCTL_MASTER_NO &&
(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_fr(r, "send packet");
}
/* Execute a local command */
if (options.local_command != NULL &&
options.permit_local_command)
ssh_local_cmd(options.local_command);
/*
* stdout is now owned by the session channel; clobber it here
* so future channel closes are propagated to the local fd.
* NB. this can only happen after LocalCommand has completed,
* as it may want to write to stdout.
*/
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 (options.fork_after_authentication) {
if (options.exit_on_forward_failure &&
options.num_remote_forwards > 0) {
debug("deferring postauth fork until remote forward "
"confirmation received");
} else
fork_postauth();
}
return client_loop(ssh, tty_flag, tty_flag ?
options.escape_char : SSH_ESCAPECHAR_NONE, id);
}
/* Loads all IdentityFile and CertificateFile keys */
static void
load_public_identity_files(const struct ssh_conn_info *cinfo)
{
char *filename, *cp;
struct sshkey *public;
int i;
u_int n_ids, n_certs;
char *identity_files[SSH_MAX_IDENTITY_FILES];
struct sshkey *identity_keys[SSH_MAX_IDENTITY_FILES];
int identity_file_userprovided[SSH_MAX_IDENTITY_FILES];
char *certificate_files[SSH_MAX_CERTIFICATE_FILES];
struct sshkey *certificates[SSH_MAX_CERTIFICATE_FILES];
int certificate_file_userprovided[SSH_MAX_CERTIFICATE_FILES];
#ifdef ENABLE_PKCS11
struct sshkey **keys = NULL;
char **comments = NULL;
int nkeys;
#endif /* PKCS11 */
n_ids = n_certs = 0;
memset(identity_files, 0, sizeof(identity_files));
memset(identity_keys, 0, sizeof(identity_keys));
memset(identity_file_userprovided, 0,
sizeof(identity_file_userprovided));
memset(certificate_files, 0, sizeof(certificate_files));
memset(certificates, 0, sizeof(certificates));
memset(certificate_file_userprovided, 0,
sizeof(certificate_file_userprovided));
#ifdef ENABLE_PKCS11
if (options.pkcs11_provider != NULL &&
options.num_identity_files < SSH_MAX_IDENTITY_FILES &&
(pkcs11_init(!options.batch_mode) == 0) &&
(nkeys = pkcs11_add_provider(options.pkcs11_provider, NULL,
&keys, &comments)) > 0) {
for (i = 0; i < nkeys; i++) {
if (n_ids >= SSH_MAX_IDENTITY_FILES) {
sshkey_free(keys[i]);
free(comments[i]);
continue;
}
identity_keys[n_ids] = keys[i];
identity_files[n_ids] = comments[i]; /* transferred */
n_ids++;
}
free(keys);
free(comments);
}
#endif /* ENABLE_PKCS11 */
for (i = 0; i < options.num_identity_files; i++) {
if (n_ids >= SSH_MAX_IDENTITY_FILES ||
strcasecmp(options.identity_files[i], "none") == 0) {
free(options.identity_files[i]);
options.identity_files[i] = NULL;
continue;
}
cp = tilde_expand_filename(options.identity_files[i], getuid());
filename = default_client_percent_dollar_expand(cp, cinfo);
free(cp);
check_load(sshkey_load_public(filename, &public, NULL),
&public, filename, "pubkey");
debug("identity file %s type %d", filename,
public ? public->type : -1);
free(options.identity_files[i]);
identity_files[n_ids] = filename;
identity_keys[n_ids] = public;
identity_file_userprovided[n_ids] =
options.identity_file_userprovided[i];
if (++n_ids >= SSH_MAX_IDENTITY_FILES)
continue;
/*
* If no certificates have been explicitly listed then try
* to add the default certificate variant too.
*/
if (options.num_certificate_files != 0)
continue;
xasprintf(&cp, "%s-cert", filename);
check_load(sshkey_load_public(cp, &public, NULL),
&public, filename, "pubkey");
debug("identity file %s type %d", cp,
public ? public->type : -1);
if (public == NULL) {
free(cp);
continue;
}
if (!sshkey_is_cert(public)) {
debug_f("key %s type %s is not a certificate",
cp, sshkey_type(public));
sshkey_free(public);
free(cp);
continue;
}
/* NB. leave filename pointing to private key */
identity_files[n_ids] = xstrdup(filename);
identity_keys[n_ids] = public;
identity_file_userprovided[n_ids] =
options.identity_file_userprovided[i];
n_ids++;
}
if (options.num_certificate_files > SSH_MAX_CERTIFICATE_FILES)
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, cinfo);
free(cp);
check_load(sshkey_load_public(filename, &public, NULL),
&public, filename, "certificate");
debug("certificate file %s type %d", filename,
public ? public->type : -1);
free(options.certificate_files[i]);
options.certificate_files[i] = NULL;
if (public == NULL) {
free(filename);
continue;
}
if (!sshkey_is_cert(public)) {
debug_f("key %s type %s is not a certificate",
filename, sshkey_type(public));
sshkey_free(public);
free(filename);
continue;
}
certificate_files[n_certs] = filename;
certificates[n_certs] = public;
certificate_file_userprovided[n_certs] =
options.certificate_file_userprovided[i];
++n_certs;
}
options.num_identity_files = n_ids;
memcpy(options.identity_files, identity_files, sizeof(identity_files));
memcpy(options.identity_keys, identity_keys, sizeof(identity_keys));
memcpy(options.identity_file_userprovided,
identity_file_userprovided, sizeof(identity_file_userprovided));
options.num_certificate_files = n_certs;
memcpy(options.certificate_files,
certificate_files, sizeof(certificate_files));
memcpy(options.certificates, certificates, sizeof(certificates));
memcpy(options.certificate_file_userprovided,
certificate_file_userprovided,
sizeof(certificate_file_userprovided));
}
static void
main_sigchld_handler(int sig)
{
int save_errno = errno;
pid_t pid;
int status;
while ((pid = waitpid(-1, &status, WNOHANG)) > 0 ||
(pid == -1 && errno == EINTR))
;
errno = save_errno;
}
diff --git a/crypto/openssh/ssh_config.5 b/crypto/openssh/ssh_config.5
index bf23e3099b20..b642c5a6b17a 100644
--- a/crypto/openssh/ssh_config.5
+++ b/crypto/openssh/ssh_config.5
@@ -1,2209 +1,2224 @@
.\"
.\" Author: Tatu Ylonen <ylo@cs.hut.fi>
.\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
.\" All rights reserved
.\"
.\" As far as I am concerned, the code I have written for this software
.\" can be used freely for any purpose. Any derived versions of this
.\" software must be clearly marked as such, and if the derived work is
.\" incompatible with the protocol description in the RFC file, it must be
.\" called by a name other than "ssh" or "Secure Shell".
.\"
.\" Copyright (c) 1999,2000 Markus Friedl. All rights reserved.
.\" Copyright (c) 1999 Aaron Campbell. All rights reserved.
.\" Copyright (c) 1999 Theo de Raadt. All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.\" $OpenBSD: ssh_config.5,v 1.374 2022/09/17 10:33:18 djm Exp $
-.Dd $Mdocdate: September 17 2022 $
+.\" $OpenBSD: ssh_config.5,v 1.378 2023/01/13 07:13:40 jmc Exp $
+.Dd $Mdocdate: January 13 2023 $
.Dt SSH_CONFIG 5
.Os
.Sh NAME
.Nm ssh_config
.Nd OpenSSH client configuration file
.Sh DESCRIPTION
.Xr ssh 1
obtains configuration data from the following sources in
the following order:
.Pp
.Bl -enum -offset indent -compact
.It
command-line options
.It
user's configuration file
.Pq Pa ~/.ssh/config
.It
system-wide configuration file
.Pq Pa /etc/ssh/ssh_config
.El
.Pp
For each parameter, the first obtained value
will be used.
The configuration files contain sections separated by
.Cm Host
specifications, and that section is only applied for hosts that
match one of the patterns given in the specification.
The matched host name is usually the one given on the command line
(see the
.Cm CanonicalizeHostname
option for exceptions).
.Pp
Since the first obtained value for each parameter is used, more
host-specific declarations should be given near the beginning of the
file, and general defaults at the end.
.Pp
The file contains keyword-argument pairs, one per line.
Lines starting with
.Ql #
and empty lines are interpreted as comments.
Arguments may optionally be enclosed in double quotes
.Pq \&"
in order to represent arguments containing spaces.
Configuration options may be separated by whitespace or
optional whitespace and exactly one
.Ql = ;
the latter format is useful to avoid the need to quote whitespace
when specifying configuration options using the
.Nm ssh ,
.Nm scp ,
and
.Nm sftp
.Fl o
option.
.Pp
The possible
keywords and their meanings are as follows (note that
keywords are case-insensitive and arguments are case-sensitive):
.Bl -tag -width Ds
.It Cm Host
Restricts the following declarations (up to the next
.Cm Host
or
.Cm Match
keyword) to be only for those hosts that match one of the patterns
given after the keyword.
If more than one pattern is provided, they should be separated by whitespace.
A single
.Ql *
as a pattern can be used to provide global
defaults for all hosts.
The host is usually the
.Ar hostname
argument given on the command line
(see the
.Cm CanonicalizeHostname
keyword for exceptions).
.Pp
A pattern entry may be negated by prefixing it with an exclamation mark
.Pq Sq !\& .
If a negated entry is matched, then the
.Cm Host
entry is ignored, regardless of whether any other patterns on the line
match.
Negated matches are therefore useful to provide exceptions for wildcard
matches.
.Pp
See
.Sx PATTERNS
for more information on patterns.
.It Cm Match
Restricts the following declarations (up to the next
.Cm Host
or
.Cm Match
keyword) to be used only when the conditions following the
.Cm Match
keyword are satisfied.
Match conditions are specified using one or more criteria
or the single token
.Cm all
which always matches.
The available criteria keywords are:
.Cm canonical ,
.Cm final ,
.Cm exec ,
.Cm host ,
.Cm originalhost ,
.Cm user ,
and
.Cm localuser .
The
.Cm all
criteria must appear alone or immediately after
.Cm canonical
or
.Cm final .
Other criteria may be combined arbitrarily.
All criteria but
.Cm all ,
.Cm canonical ,
and
.Cm final
require an argument.
Criteria may be negated by prepending an exclamation mark
.Pq Sq !\& .
.Pp
The
.Cm canonical
keyword matches only when the configuration file is being re-parsed
after hostname canonicalization (see the
.Cm CanonicalizeHostname
option).
This may be useful to specify conditions that work with canonical host
names only.
.Pp
The
.Cm final
keyword requests that the configuration be re-parsed (regardless of whether
.Cm CanonicalizeHostname
is enabled), and matches only during this final pass.
If
.Cm CanonicalizeHostname
is enabled, then
.Cm canonical
and
.Cm final
match during the same pass.
.Pp
The
.Cm exec
keyword executes the specified command under the user's shell.
If the command returns a zero exit status then the condition is considered true.
Commands containing whitespace characters must be quoted.
Arguments to
.Cm exec
accept the tokens described in the
.Sx TOKENS
section.
.Pp
The other keywords' criteria must be single entries or comma-separated
lists and may use the wildcard and negation operators described in the
.Sx PATTERNS
section.
The criteria for the
.Cm host
keyword are matched against the target hostname, after any substitution
by the
.Cm Hostname
or
.Cm CanonicalizeHostname
options.
The
.Cm originalhost
keyword matches against the hostname as it was specified on the command-line.
The
.Cm user
keyword matches against the target username on the remote host.
The
.Cm localuser
keyword matches against the name of the local user running
.Xr ssh 1
(this keyword may be useful in system-wide
.Nm
files).
.It Cm AddKeysToAgent
Specifies whether keys should be automatically added to a running
.Xr ssh-agent 1 .
If this option is set to
.Cm yes
and a key is loaded from a file, the key and its passphrase are added to
the agent with the default lifetime, as if by
.Xr ssh-add 1 .
If this option is set to
.Cm ask ,
.Xr ssh 1
will require confirmation using the
.Ev SSH_ASKPASS
program before adding a key (see
.Xr ssh-add 1
for details).
If this option is set to
.Cm confirm ,
each use of the key must be confirmed, as if the
.Fl c
option was specified to
.Xr ssh-add 1 .
If this option is set to
.Cm no ,
no keys are added to the agent.
Alternately, this option may be specified as a time interval
using the format described in the
.Sx TIME FORMATS
section of
.Xr sshd_config 5
to specify the key's lifetime in
.Xr ssh-agent 1 ,
after which it will automatically be removed.
The argument must be
.Cm no
(the default),
.Cm yes ,
.Cm confirm
(optionally followed by a time interval),
.Cm ask
or a time interval.
.It Cm AddressFamily
Specifies which address family to use when connecting.
Valid arguments are
.Cm any
(the default),
.Cm inet
(use IPv4 only), or
.Cm inet6
(use IPv6 only).
.It Cm BatchMode
If set to
.Cm yes ,
user interaction such as password prompts and host key confirmation requests
will be disabled.
This option is useful in scripts and other batch jobs where no user
is present to interact with
.Xr ssh 1 .
The argument must be
.Cm yes
or
.Cm no
(the default).
.It Cm BindAddress
Use the specified address on the local machine as the source address of
the connection.
Only useful on systems with more than one address.
.It Cm BindInterface
Use the address of the specified interface on the local machine as the
source address of the connection.
.It Cm CanonicalDomains
When
.Cm CanonicalizeHostname
is enabled, this option specifies the list of domain suffixes in which to
search for the specified destination host.
.It Cm CanonicalizeFallbackLocal
Specifies whether to fail with an error when hostname canonicalization fails.
The default,
.Cm yes ,
will attempt to look up the unqualified hostname using the system resolver's
search rules.
A value of
.Cm no
will cause
.Xr ssh 1
to fail instantly if
.Cm CanonicalizeHostname
is enabled and the target hostname cannot be found in any of the domains
specified by
.Cm CanonicalDomains .
.It Cm CanonicalizeHostname
Controls whether explicit hostname canonicalization is performed.
The default,
.Cm no ,
is not to perform any name rewriting and let the system resolver handle all
hostname lookups.
If set to
.Cm yes
then, for connections that do not use a
.Cm ProxyCommand
or
.Cm ProxyJump ,
.Xr ssh 1
will attempt to canonicalize the hostname specified on the command line
using the
.Cm CanonicalDomains
suffixes and
.Cm CanonicalizePermittedCNAMEs
rules.
If
.Cm CanonicalizeHostname
is set to
.Cm always ,
then canonicalization is applied to proxied connections too.
.Pp
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
.Cm Host
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.
The default, 1,
allows a single dot (i.e. hostname.subdomain).
.It Cm CanonicalizePermittedCNAMEs
Specifies rules to determine whether CNAMEs should be followed when
canonicalizing hostnames.
The rules consist of one or more arguments of
.Ar source_domain_list : Ns Ar target_domain_list ,
where
.Ar source_domain_list
is a pattern-list of domains that may follow CNAMEs in canonicalization,
and
.Ar target_domain_list
is a pattern-list of domains that they may resolve to.
.Pp
For example,
.Qq *.a.example.com:*.b.example.com,*.c.example.com
will allow hostnames matching
.Qq *.a.example.com
to be canonicalized to names in the
.Qq *.b.example.com
or
.Qq *.c.example.com
domains.
.Pp
A single argument of
.Qq none
causes no CNAMEs to be considered for canonicalization.
This is the default behaviour.
.It Cm CASignatureAlgorithms
Specifies which algorithms are allowed for signing of certificates
by certificate authorities (CAs).
The default is:
.Bd -literal -offset indent
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.
.It Cm CertificateFile
Specifies a file from which the user's certificate is read.
A corresponding private key must be provided separately in order
to use this certificate either
from an
.Cm IdentityFile
directive or
.Fl i
flag to
.Xr ssh 1 ,
via
.Xr ssh-agent 1 ,
or via a
.Cm PKCS11Provider
or
.Cm SecurityKeyProvider .
.Pp
Arguments to
.Cm CertificateFile
may use the tilde syntax to refer to a user's home directory,
the tokens described in the
.Sx TOKENS
section and environment variables as described in the
.Sx ENVIRONMENT VARIABLES
section.
.Pp
It is possible to have multiple certificate files specified in
configuration files; these certificates will be tried in sequence.
Multiple
.Cm CertificateFile
directives will add to the list of certificates used for
authentication.
.It Cm CheckHostIP
If set to
.Cm yes ,
.Xr ssh 1
will additionally check the host IP address in the
.Pa 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
.Pa ~/.ssh/known_hosts
in the process, regardless of the setting of
.Cm StrictHostKeyChecking .
If the option is set to
.Cm no
(the default),
the check will not be executed.
The default is
.Cm no .
.It Cm Ciphers
Specifies the ciphers allowed and their order of preference.
Multiple ciphers must be comma-separated.
If the specified list begins with a
.Sq +
character, then the specified ciphers will be appended to the default set
instead of replacing them.
If the specified list begins with a
.Sq -
character, then the specified ciphers (including wildcards) will be removed
from the default set instead of replacing them.
If the specified list begins with a
.Sq ^
character, then the specified ciphers will be placed at the head of the
default set.
.Pp
The supported ciphers are:
.Bd -literal -offset indent
3des-cbc
aes128-cbc
aes192-cbc
aes256-cbc
aes128-ctr
aes192-ctr
aes256-ctr
aes128-gcm@openssh.com
aes256-gcm@openssh.com
chacha20-poly1305@openssh.com
.Ed
.Pp
The default is:
.Bd -literal -offset indent
chacha20-poly1305@openssh.com,
aes128-ctr,aes192-ctr,aes256-ctr,
aes128-gcm@openssh.com,aes256-gcm@openssh.com
.Ed
.Pp
The list of available ciphers may also be obtained using
.Qq ssh -Q cipher .
.It Cm ClearAllForwardings
Specifies that all local, remote, and dynamic port forwardings
specified in the configuration files or on the command line be
cleared.
This option is primarily useful when used from the
.Xr ssh 1
command line to clear port forwardings set in
configuration files, and is automatically set by
.Xr scp 1
and
.Xr sftp 1 .
The argument must be
.Cm yes
or
.Cm no
(the default).
.It Cm Compression
Specifies whether to use compression.
The argument must be
.Cm yes
or
.Cm no
(the default).
.It Cm ConnectionAttempts
Specifies the number of tries (one per second) to make before exiting.
The argument must be an integer.
This may be useful in scripts if the connection sometimes fails.
The default is 1.
.It Cm ConnectTimeout
Specifies the timeout (in seconds) used when connecting to the
SSH server, instead of using the default system TCP timeout.
This timeout is applied both to establishing the connection and to performing
the initial SSH protocol handshake and key exchange.
.It Cm ControlMaster
Enables the sharing of multiple sessions over a single network connection.
When set to
.Cm yes ,
.Xr ssh 1
will listen for connections on a control socket specified using the
.Cm ControlPath
argument.
Additional sessions can connect to this socket using the same
.Cm ControlPath
with
.Cm ControlMaster
set to
.Cm no
(the default).
These sessions will try to reuse the master instance's network connection
rather than initiating new ones, but will fall back to connecting normally
if the control socket does not exist, or is not listening.
.Pp
Setting this to
.Cm ask
will cause
.Xr ssh 1
to listen for control connections, but require confirmation using
.Xr ssh-askpass 1 .
If the
.Cm ControlPath
cannot be opened,
.Xr ssh 1
will continue without connecting to a master instance.
.Pp
X11 and
.Xr ssh-agent 1
forwarding is supported over these multiplexed connections, however the
display and agent forwarded will be the one belonging to the master
connection i.e. it is not possible to forward multiple displays or agents.
.Pp
Two additional options allow for opportunistic multiplexing: try to use a
master connection but fall back to creating a new one if one does not already
exist.
These options are:
.Cm auto
and
.Cm autoask .
The latter requires confirmation like the
.Cm ask
option.
.It Cm ControlPath
Specify the path to the control socket used for connection sharing as described
in the
.Cm ControlMaster
section above or the string
.Cm none
to disable connection sharing.
Arguments to
.Cm ControlPath
may use the tilde syntax to refer to a user's home directory,
the tokens described in the
.Sx TOKENS
section and environment variables as described in the
.Sx ENVIRONMENT VARIABLES
section.
It is recommended that any
.Cm ControlPath
used for opportunistic connection sharing include
at least %h, %p, and %r (or alternatively %C) and be placed in a directory
that is not writable by other users.
This ensures that shared connections are uniquely identified.
.It Cm ControlPersist
When used in conjunction with
.Cm ControlMaster ,
specifies that the master connection should remain open
in the background (waiting for future client connections)
after the initial client connection has been closed.
If set to
.Cm no
(the default),
then the master connection will not be placed into the background,
and will close as soon as the initial client connection is closed.
If set to
.Cm yes
or 0,
then the master connection will remain in the background indefinitely
(until killed or closed via a mechanism such as the
.Qq ssh -O exit ) .
If set to a time in seconds, or a time in any of the formats documented in
.Xr sshd_config 5 ,
then the backgrounded master connection will automatically terminate
after it has remained idle (with no client connections) for the
specified time.
.It Cm DynamicForward
Specifies that a TCP port on the local machine be forwarded
over the secure channel, and the application
protocol is then used to determine where to connect to from the
remote machine.
.Pp
The argument must be
.Sm off
.Oo Ar bind_address : Oc Ar port .
.Sm on
IPv6 addresses can be specified by enclosing addresses in square brackets.
By default, the local port is bound in accordance with the
.Cm GatewayPorts
setting.
However, an explicit
.Ar bind_address
may be used to bind the connection to a specific address.
The
.Ar bind_address
of
.Cm localhost
indicates that the listening port be bound for local use only, while an
empty address or
.Sq *
indicates that the port should be available from all interfaces.
.Pp
Currently the SOCKS4 and SOCKS5 protocols are supported, and
.Xr ssh 1
will act as a SOCKS server.
Multiple forwardings may be specified, and
additional forwardings can be given on the command line.
Only the superuser can forward privileged ports.
+.It Cm EnableEscapeCommandline
+Enables the command line option in the
+.Cm EscapeChar
+menu for interactive sessions (default
+.Ql ~C ) .
+By default, the command line is disabled.
.It Cm EnableSSHKeysign
Setting this option to
.Cm yes
in the global client configuration file
.Pa /etc/ssh/ssh_config
enables the use of the helper program
.Xr ssh-keysign 8
during
.Cm HostbasedAuthentication .
The argument must be
.Cm yes
or
.Cm no
(the default).
This option should be placed in the non-hostspecific section.
See
.Xr ssh-keysign 8
for more information.
.It Cm EscapeChar
Sets the escape character (default:
.Ql ~ ) .
The escape character can also
be set on the command line.
The argument should be a single character,
.Ql ^
followed by a letter, or
.Cm none
to disable the escape
character entirely (making the connection transparent for binary
data).
.It Cm ExitOnForwardFailure
Specifies whether
.Xr ssh 1
should terminate the connection if it cannot set up all requested
dynamic, tunnel, local, and remote port forwardings, (e.g.\&
if either end is unable to bind and listen on a specified port).
Note that
.Cm ExitOnForwardFailure
does not apply to connections made over port forwardings and will not,
for example, cause
.Xr ssh 1
to exit if TCP connections to the ultimate forwarding destination fail.
The argument must be
.Cm yes
or
.Cm no
(the default).
.It Cm FingerprintHash
Specifies the hash algorithm used when displaying key fingerprints.
Valid options are:
.Cm md5
and
.Cm sha256
(the default).
.It Cm ForkAfterAuthentication
Requests
.Nm ssh
to go to background just before command execution.
This is useful if
.Nm ssh
is going to ask for passwords or passphrases, but the user
wants it in the background.
This implies the
.Cm StdinNull
configuration option being set to
.Dq yes .
The recommended way to start X11 programs at a remote site is with
something like
.Ic ssh -f host xterm ,
which is the same as
.Ic ssh host xterm
if the
.Cm ForkAfterAuthentication
configuration option is set to
.Dq yes .
.Pp
If the
.Cm ExitOnForwardFailure
configuration option is set to
.Dq yes ,
then a client started with the
.Cm ForkAfterAuthentication
configuration option being set to
.Dq yes
will wait for all remote port forwards to be successfully established
before placing itself in the background.
The argument to this keyword must be
.Cm yes
(same as the
.Fl f
option) or
.Cm no
(the default).
.It Cm ForwardAgent
Specifies whether the connection to the authentication agent (if any)
will be forwarded to the remote machine.
The argument may be
.Cm yes ,
.Cm no
(the default),
an explicit path to an agent socket or the name of an environment variable
(beginning with
.Sq $ )
in which to find the path.
.Pp
Agent forwarding should be enabled with caution.
Users with the ability to bypass file permissions on the remote host
(for the agent's Unix-domain socket)
can access the local agent through the forwarded connection.
An attacker cannot obtain key material from the agent,
however they can perform operations on the keys that enable them to
authenticate using the identities loaded into the agent.
.It Cm ForwardX11
Specifies whether X11 connections will be automatically redirected
over the secure channel and
.Ev DISPLAY
set.
The argument must be
.Cm yes
or
.Cm no
(the default).
.Pp
X11 forwarding should be enabled with caution.
Users with the ability to bypass file permissions on the remote host
(for the user's X11 authorization database)
can access the local X11 display through the forwarded connection.
An attacker may then be able to perform activities such as keystroke monitoring
if the
.Cm ForwardX11Trusted
option is also enabled.
.It Cm ForwardX11Timeout
Specify a timeout for untrusted X11 forwarding
using the format described in the
.Sx TIME FORMATS
section of
.Xr sshd_config 5 .
X11 connections received by
.Xr ssh 1
after this time will be refused.
Setting
.Cm ForwardX11Timeout
to zero will disable the timeout and permit X11 forwarding for the life
of the connection.
The default is to disable untrusted X11 forwarding after twenty minutes has
elapsed.
.It Cm ForwardX11Trusted
If this option is set to
.Cm yes ,
remote X11 clients will have full access to the original X11 display.
.Pp
If this option is set to
.Cm no
(the default),
remote X11 clients will be considered untrusted and prevented
from stealing or tampering with data belonging to trusted X11
clients.
Furthermore, the
.Xr xauth 1
token used for the session will be set to expire after 20 minutes.
Remote clients will be refused access after this time.
.Pp
See the X11 SECURITY extension specification for full details on
the restrictions imposed on untrusted clients.
.It Cm GatewayPorts
Specifies whether remote hosts are allowed to connect to local
forwarded ports.
By default,
.Xr ssh 1
binds local port forwardings to the loopback address.
This prevents other remote hosts from connecting to forwarded ports.
.Cm GatewayPorts
can be used to specify that ssh
should bind local port forwardings to the wildcard address,
thus allowing remote hosts to connect to forwarded ports.
The argument must be
.Cm yes
or
.Cm no
(the default).
.It Cm GlobalKnownHostsFile
Specifies one or more files to use for the global
host key database, separated by whitespace.
The default is
.Pa /etc/ssh/ssh_known_hosts ,
.Pa /etc/ssh/ssh_known_hosts2 .
.It Cm GSSAPIAuthentication
Specifies whether user authentication based on GSSAPI is allowed.
The default is
.Cm no .
.It Cm GSSAPIDelegateCredentials
Forward (delegate) credentials to the server.
The default is
.Cm no .
.It Cm HashKnownHosts
Indicates that
.Xr ssh 1
should hash host names and addresses when they are added to
.Pa ~/.ssh/known_hosts .
These hashed names may be used normally by
.Xr ssh 1
and
.Xr sshd 8 ,
but they do not visually reveal identifying information if the
file's contents are disclosed.
The default is
.Cm no .
Note that existing names and addresses in known hosts files
will not be converted automatically,
but may be manually hashed using
.Xr ssh-keygen 1 .
.It Cm 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 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 signature algorithms (including wildcards)
will be removed from the default set instead of replacing them.
If the specified list begins with a
.Sq ^
character, then the specified signature algorithms will be placed
at the head of the default set.
The default for this option is:
.Bd -literal -offset 3n
ssh-ed25519-cert-v01@openssh.com,
ecdsa-sha2-nistp256-cert-v01@openssh.com,
ecdsa-sha2-nistp384-cert-v01@openssh.com,
ecdsa-sha2-nistp521-cert-v01@openssh.com,
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,
rsa-sha2-512,rsa-sha2-256,ssh-rsa
.Ed
.Pp
The
.Fl Q
option of
.Xr ssh 1
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 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 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 signature algorithms (including wildcards)
will be removed from the default set instead of replacing them.
If the specified list begins with a
.Sq ^
character, then the specified signature algorithms will be placed
at the head of the default set.
The default for this option is:
.Bd -literal -offset 3n
ssh-ed25519-cert-v01@openssh.com,
ecdsa-sha2-nistp256-cert-v01@openssh.com,
ecdsa-sha2-nistp384-cert-v01@openssh.com,
ecdsa-sha2-nistp521-cert-v01@openssh.com,
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,
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 signature algorithms may also be obtained using
.Qq ssh -Q HostKeyAlgorithms .
.It Cm HostKeyAlias
Specifies an alias that should be used instead of the
real host name when looking up or saving the host key
in the host key database files and when validating host certificates.
This option is useful for tunneling SSH connections
or for multiple servers running on a single host.
.It Cm Hostname
Specifies the real host name to log into.
This can be used to specify nicknames or abbreviations for hosts.
Arguments to
.Cm Hostname
accept the tokens described in the
.Sx TOKENS
section.
Numeric IP addresses are also permitted (both on the command line and in
.Cm Hostname
specifications).
The default is the name given on the command line.
.It Cm IdentitiesOnly
Specifies that
.Xr ssh 1
should only use the configured authentication identity and certificate files
(either the default files, or those explicitly configured in the
.Nm
files
or passed on the
.Xr ssh 1
command-line),
even if
.Xr ssh-agent 1
or a
.Cm PKCS11Provider
or
.Cm SecurityKeyProvider
offers more identities.
The argument to this keyword must be
.Cm yes
or
.Cm no
(the default).
This option is intended for situations where ssh-agent
offers many different identities.
.It Cm IdentityAgent
Specifies the
.Ux Ns -domain
socket used to communicate with the authentication agent.
.Pp
This option overrides the
.Ev SSH_AUTH_SOCK
environment variable and can be used to select a specific agent.
Setting the socket name to
.Cm none
disables the use of an authentication agent.
If the string
.Qq SSH_AUTH_SOCK
is specified, the location of the socket will be read from the
.Ev SSH_AUTH_SOCK
environment variable.
Otherwise if the specified value begins with a
.Sq $
character, then it will be treated as an environment variable containing
the location of the socket.
.Pp
Arguments to
.Cm IdentityAgent
may use the tilde syntax to refer to a user's home directory,
the tokens described in the
.Sx TOKENS
section and environment variables as described in the
.Sx ENVIRONMENT VARIABLES
section.
.It Cm IdentityFile
Specifies a file from which the user's DSA, ECDSA, authenticator-hosted ECDSA,
Ed25519, authenticator-hosted Ed25519 or RSA authentication identity is read.
+You can also specify a public key file to use the corresponding
+private key that is loaded in
+.Xr ssh-agent 1
+when the private key file is not present locally.
The default is
.Pa ~/.ssh/id_rsa ,
.Pa ~/.ssh/id_ecdsa ,
.Pa ~/.ssh/id_ecdsa_sk ,
.Pa ~/.ssh/id_ed25519 ,
.Pa ~/.ssh/id_ed25519_sk
and
.Pa ~/.ssh/id_dsa .
Additionally, any identities represented by the authentication agent
will be used for authentication unless
.Cm IdentitiesOnly
is set.
If no certificates have been explicitly specified by
.Cm CertificateFile ,
.Xr ssh 1
will try to load certificate information from the filename obtained by
appending
.Pa -cert.pub
to the path of a specified
.Cm IdentityFile .
.Pp
Arguments to
.Cm IdentityFile
may use the tilde syntax to refer to a user's home directory
or the tokens described in the
.Sx TOKENS
section.
.Pp
It is possible to have
multiple identity files specified in configuration files; all these
identities will be tried in sequence.
Multiple
.Cm IdentityFile
directives will add to the list of identities tried (this behaviour
differs from that of other configuration directives).
.Pp
.Cm IdentityFile
may be used in conjunction with
.Cm IdentitiesOnly
to select which identities in an agent are offered during authentication.
.Cm IdentityFile
may also be used in conjunction with
.Cm CertificateFile
in order to provide any certificate also needed for authentication with
the identity.
.It Cm IgnoreUnknown
Specifies a pattern-list of unknown options to be ignored if they are
encountered in configuration parsing.
This may be used to suppress errors if
.Nm
contains options that are unrecognised by
.Xr ssh 1 .
It is recommended that
.Cm IgnoreUnknown
be listed early in the configuration file as it will not be applied
to unknown options that appear before it.
.It Cm Include
Include the specified configuration file(s).
Multiple pathnames may be specified and each pathname may contain
.Xr glob 7
wildcards and, for user configurations, shell-like
.Sq ~
references to user home directories.
Wildcards will be expanded and processed in lexical order.
Files without absolute paths are assumed to be in
.Pa ~/.ssh
if included in a user configuration file or
.Pa /etc/ssh
if included from the system configuration file.
.Cm Include
directive may appear inside a
.Cm Match
or
.Cm Host
block
to perform conditional inclusion.
.It Cm IPQoS
Specifies the IPv4 type-of-service or DSCP class for connections.
Accepted values are
.Cm af11 ,
.Cm af12 ,
.Cm af13 ,
.Cm af21 ,
.Cm af22 ,
.Cm af23 ,
.Cm af31 ,
.Cm af32 ,
.Cm af33 ,
.Cm af41 ,
.Cm af42 ,
.Cm af43 ,
.Cm cs0 ,
.Cm cs1 ,
.Cm cs2 ,
.Cm cs3 ,
.Cm cs4 ,
.Cm cs5 ,
.Cm cs6 ,
.Cm cs7 ,
.Cm ef ,
.Cm le ,
.Cm lowdelay ,
.Cm throughput ,
.Cm reliability ,
a numeric value, or
.Cm none
to use the operating system default.
This option may take one or two arguments, separated by whitespace.
If one argument is specified, it is used as the packet class unconditionally.
If two values are specified, the first is automatically selected for
interactive sessions and the second for non-interactive sessions.
The default is
.Cm af21
(Low-Latency Data)
for interactive sessions and
.Cm cs1
(Lower Effort)
for non-interactive sessions.
.It Cm KbdInteractiveAuthentication
Specifies whether to use keyboard-interactive authentication.
The argument to this keyword must be
.Cm yes
(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.
The default is to use the server specified list.
The methods available vary depending on what the server supports.
For an OpenSSH server,
it may be zero or more of:
.Cm bsdauth
and
.Cm pam .
.It Cm KexAlgorithms
Specifies the available KEX (Key Exchange) algorithms.
Multiple algorithms must be comma-separated.
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.
If the specified list begins with a
.Sq ^
character, then the specified algorithms will be placed at the head of the
default set.
The default is:
.Bd -literal -offset indent
sntrup761x25519-sha512@openssh.com,
curve25519-sha256,curve25519-sha256@libssh.org,
ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,
diffie-hellman-group-exchange-sha256,
diffie-hellman-group16-sha512,
diffie-hellman-group18-sha512,
diffie-hellman-group14-sha256
.Ed
.Pp
The list of available key exchange algorithms may also be obtained using
.Qq ssh -Q kex .
.It Cm KnownHostsCommand
Specifies a command to use to obtain a list of host keys, in addition to
those listed in
.Cm UserKnownHostsFile
and
.Cm GlobalKnownHostsFile .
This command is executed after the files have been read.
It may write host key lines to standard output in identical format to the
usual files (described in the
.Sx VERIFYING HOST KEYS
section in
.Xr ssh 1 ) .
Arguments to
.Cm KnownHostsCommand
accept the tokens described in the
.Sx TOKENS
section.
The command may be invoked multiple times per connection: once when preparing
the preference list of host key algorithms to use, again to obtain the
host key for the requested host name and, if
.Cm CheckHostIP
is enabled, one more time to obtain the host key matching the server's
address.
If the command exits abnormally or returns a non-zero exit status then the
connection is terminated.
.It Cm LocalCommand
Specifies a command to execute on the local machine after successfully
connecting to the server.
The command string extends to the end of the line, and is executed with
the user's shell.
Arguments to
.Cm LocalCommand
accept the tokens described in the
.Sx TOKENS
section.
.Pp
The command is run synchronously and does not have access to the
session of the
.Xr ssh 1
that spawned it.
It should not be used for interactive commands.
.Pp
This directive is ignored unless
.Cm PermitLocalCommand
has been enabled.
.It Cm LocalForward
Specifies that a TCP port on the local machine be forwarded over
the secure channel to the specified host and port from the remote machine.
The first argument specifies the listener and may be
.Sm off
.Oo Ar bind_address : Oc Ar port
.Sm on
or a Unix domain socket path.
The second argument is the destination and may be
.Ar host : Ns Ar hostport
or a Unix domain socket path if the remote host supports it.
.Pp
IPv6 addresses can be specified by enclosing addresses in square brackets.
Multiple forwardings may be specified, and additional forwardings can be
given on the command line.
Only the superuser can forward privileged ports.
By default, the local port is bound in accordance with the
.Cm GatewayPorts
setting.
However, an explicit
.Ar bind_address
may be used to bind the connection to a specific address.
The
.Ar bind_address
of
.Cm localhost
indicates that the listening port be bound for local use only, while an
empty address or
.Sq *
indicates that the port should be available from all interfaces.
Unix domain socket paths may use the tokens described in the
.Sx TOKENS
section and environment variables as described in the
.Sx ENVIRONMENT VARIABLES
section.
.It Cm LogLevel
Gives the verbosity level that is used when logging messages from
.Xr ssh 1 .
The possible values are:
QUIET, FATAL, ERROR, INFO, VERBOSE, DEBUG, DEBUG1, DEBUG2, and DEBUG3.
The default is INFO.
DEBUG and DEBUG1 are equivalent.
DEBUG2 and DEBUG3 each specify higher levels of verbose output.
.It Cm LogVerbose
Specify one or more overrides to LogLevel.
An override consists of a pattern lists that matches the source file, function
and line number to force detailed logging for.
For example, an override pattern of:
.Bd -literal -offset indent
kex.c:*:1000,*:kex_exchange_identification():*,packet.c:*
.Ed
.Pp
would enable detailed logging for line 1000 of
.Pa kex.c ,
everything in the
.Fn kex_exchange_identification
function, and all code in the
.Pa packet.c
file.
This option is intended for debugging and no overrides are enabled by default.
.It Cm MACs
Specifies the MAC (message authentication code) algorithms
in order of preference.
The MAC algorithm is used for data integrity protection.
Multiple algorithms must be comma-separated.
If the specified 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.
If the specified list begins with a
.Sq ^
character, then the specified algorithms will be placed at the head of the
default set.
.Pp
The algorithms that contain
.Qq -etm
calculate the MAC after encryption (encrypt-then-mac).
These are considered safer and their use recommended.
.Pp
The default is:
.Bd -literal -offset indent
umac-64-etm@openssh.com,umac-128-etm@openssh.com,
hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,
hmac-sha1-etm@openssh.com,
umac-64@openssh.com,umac-128@openssh.com,
hmac-sha2-256,hmac-sha2-512,hmac-sha1
.Ed
.Pp
The list of available MAC algorithms may also be obtained using
.Qq ssh -Q mac .
.It Cm NoHostAuthenticationForLocalhost
Disable host authentication for localhost (loopback addresses).
The argument to this keyword must be
.Cm yes
or
.Cm no
(the default).
.It Cm NumberOfPasswordPrompts
Specifies the number of password prompts before giving up.
The argument to this keyword must be an integer.
The default is 3.
.It Cm PasswordAuthentication
Specifies whether to use password authentication.
The argument to this keyword must be
.Cm yes
(the default)
or
.Cm no .
.It Cm PermitLocalCommand
Allow local command execution via the
.Ic LocalCommand
option or using the
.Ic !\& Ns Ar command
escape sequence in
.Xr ssh 1 .
The argument must be
.Cm yes
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
to indicate that no provider should be used (the default).
The argument to this keyword is a path to the PKCS#11 shared library
.Xr ssh 1
should use to communicate with a PKCS#11 token providing keys for user
authentication.
.It Cm Port
Specifies the port number to connect on the remote host.
The default is 22.
.It Cm PreferredAuthentications
Specifies the order in which the client should try authentication methods.
This allows a client to prefer one method (e.g.\&
.Cm keyboard-interactive )
over another method (e.g.\&
.Cm password ) .
The default is:
.Bd -literal -offset indent
gssapi-with-mic,hostbased,publickey,
keyboard-interactive,password
.Ed
.It Cm ProxyCommand
Specifies the command to use to connect to the server.
The command
string extends to the end of the line, and is executed
using the user's shell
.Ql exec
directive to avoid a lingering shell process.
.Pp
Arguments to
.Cm ProxyCommand
accept the tokens described in the
.Sx TOKENS
section.
The command can be basically anything,
and should read from its standard input and write to its standard output.
It should eventually connect an
.Xr sshd 8
server running on some machine, or execute
.Ic sshd -i
somewhere.
Host key management will be done using the
.Cm Hostname
of the host being connected (defaulting to the name typed by the user).
Setting the command to
.Cm none
disables this option entirely.
Note that
.Cm CheckHostIP
is not available for connects with a proxy command.
.Pp
This directive is useful in conjunction with
.Xr nc 1
and its proxy support.
For example, the following directive would connect via an HTTP proxy at
192.0.2.0:
.Bd -literal -offset 3n
ProxyCommand /usr/bin/nc -X connect -x 192.0.2.0:8080 %h %p
.Ed
.It Cm ProxyJump
Specifies one or more jump proxies as either
.Xo
.Sm off
.Op Ar user No @
.Ar host
.Op : Ns Ar port
.Sm on
or an ssh URI
.Xc .
Multiple proxies may be separated by comma characters and will be visited
sequentially.
Setting this option will cause
.Xr ssh 1
to connect to the target host by first making a
.Xr ssh 1
connection to the specified
.Cm ProxyJump
host and then establishing a
TCP forwarding to the ultimate target from there.
Setting the host to
.Cm none
disables this option entirely.
.Pp
Note that this option will compete with the
.Cm ProxyCommand
option - whichever is specified first will prevent later instances of the
other from taking effect.
.Pp
Note also that the configuration for the destination host (either supplied
via the command-line or the configuration file) is not generally applied
to jump hosts.
.Pa ~/.ssh/config
should be used if specific configuration is required for jump hosts.
.It Cm ProxyUseFdpass
Specifies that
.Cm ProxyCommand
will pass a connected file descriptor back to
.Xr ssh 1
instead of continuing to execute and pass data.
The default is
.Cm no .
.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 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 algorithms (including wildcards) will be removed
from the default set instead of replacing them.
If the specified list begins with a
.Sq ^
character, then the specified algorithms will be placed at the head of the
default set.
The default for this option is:
.Bd -literal -offset 3n
ssh-ed25519-cert-v01@openssh.com,
ecdsa-sha2-nistp256-cert-v01@openssh.com,
ecdsa-sha2-nistp384-cert-v01@openssh.com,
ecdsa-sha2-nistp521-cert-v01@openssh.com,
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,
rsa-sha2-512,rsa-sha2-256,ssh-rsa
.Ed
.Pp
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
.Cm yes
(the default),
.Cm no ,
.Cm unbound
or
.Cm host-bound .
The final two options enable public key authentication while respectively
disabling or enabling the OpenSSH host-bound authentication protocol
extension required for restricted
.Xr ssh-agent 1
forwarding.
.It Cm RekeyLimit
Specifies the maximum amount of data that may be transmitted or received
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
.Sq K ,
.Sq M ,
or
.Sq G
to indicate Kilobytes, Megabytes, or Gigabytes, respectively.
The default is between
.Sq 1G
and
.Sq 4G ,
depending on the cipher.
The optional second value is specified in seconds and may use any of the
units documented in the TIME FORMATS section of
.Xr sshd_config 5 .
The default value for
.Cm RekeyLimit
is
.Cm default none ,
which means that rekeying is performed after the cipher's default amount
of data has been sent or received and no time based rekeying is done.
.It Cm RemoteCommand
Specifies a command to execute on the remote machine after successfully
connecting to the server.
The command string extends to the end of the line, and is executed with
the user's shell.
Arguments to
.Cm RemoteCommand
accept the tokens described in the
.Sx TOKENS
section.
.It Cm RemoteForward
Specifies that a TCP port on the remote machine be forwarded over
the secure channel.
The remote port may either be forwarded to a specified host and port
from the local machine, or may act as a SOCKS 4/5 proxy that allows a remote
client to connect to arbitrary destinations from the local machine.
The first argument is the listening specification and may be
.Sm off
.Oo Ar bind_address : Oc Ar port
.Sm on
or, if the remote host supports it, a Unix domain socket path.
If forwarding to a specific destination then the second argument must be
.Ar host : Ns Ar hostport
or a Unix domain socket path,
otherwise if no destination argument is specified then the remote forwarding
will be established as a SOCKS proxy.
When acting as a SOCKS proxy, the destination of the connection can be
restricted by
.Cm PermitRemoteOpen .
.Pp
IPv6 addresses can be specified by enclosing addresses in square brackets.
Multiple forwardings may be specified, and additional
forwardings can be given on the command line.
Privileged ports can be forwarded only when
logging in as root on the remote machine.
Unix domain socket paths may use the tokens described in the
.Sx TOKENS
section and environment variables as described in the
.Sx ENVIRONMENT VARIABLES
section.
.Pp
If the
.Ar port
argument is 0,
the listen port will be dynamically allocated on the server and reported
to the client at run time.
.Pp
If the
.Ar bind_address
is not specified, the default is to only bind to loopback addresses.
If the
.Ar bind_address
is
.Ql *
or an empty string, then the forwarding is requested to listen on all
interfaces.
Specifying a remote
.Ar bind_address
will only succeed if the server's
.Cm GatewayPorts
option is enabled (see
.Xr sshd_config 5 ) .
.It Cm RequestTTY
Specifies whether to request a pseudo-tty for the session.
The argument may be one of:
.Cm no
(never request a TTY),
.Cm yes
(always request a TTY when standard input is a TTY),
.Cm force
(always request a TTY) or
.Cm auto
(request a TTY when opening a login session).
This option mirrors the
.Fl t
and
.Fl T
flags for
.Xr ssh 1 .
.It Cm RequiredRSASize
Specifies the minimum RSA key size (in bits) that
.Xr ssh 1
will accept.
User authentication keys smaller than this limit will be ignored.
Servers that present host keys smaller than this limit will cause the
connection to be terminated.
The default is
.Cm 1024
bits.
Note that this limit may only be raised from the default.
.It Cm RevokedHostKeys
Specifies revoked host public keys.
Keys listed in this file will be refused for host authentication.
Note that if this file does not exist or is not readable,
then host authentication will be refused for all hosts.
Keys may be specified as a text file, listing one public key per line, or as
an OpenSSH Key Revocation List (KRL) as generated by
.Xr ssh-keygen 1 .
For more information on KRLs, see the KEY REVOCATION LISTS section in
.Xr ssh-keygen 1 .
.It Cm SecurityKeyProvider
Specifies a path to a library that will be used when loading any
FIDO authenticator-hosted keys, overriding the default of using
the built-in USB HID support.
.Pp
If the specified value begins with a
.Sq $
character, then it will be treated as an environment variable containing
the path to the library.
.It Cm SendEnv
Specifies what variables from the local
.Xr environ 7
should be sent to the server.
The server must also support it, and the server must be configured to
accept these environment variables.
Note that the
.Ev TERM
environment variable is always sent whenever a
pseudo-terminal is requested as it is required by the protocol.
Refer to
.Cm AcceptEnv
in
.Xr sshd_config 5
for how to configure the server.
Variables are specified by name, which may contain wildcard characters.
Multiple environment variables may be separated by whitespace or spread
across multiple
.Cm SendEnv
directives.
.Pp
See
.Sx PATTERNS
for more information on patterns.
.Pp
It is possible to clear previously set
.Cm SendEnv
variable names by prefixing patterns with
.Pa - .
The default is not to send any environment variables.
.It Cm ServerAliveCountMax
Sets the number of server alive messages (see below) which may be
sent without
.Xr ssh 1
receiving any messages back from the server.
If this threshold is reached while server alive messages are being sent,
ssh will disconnect from the server, terminating the session.
It is important to note that the use of server alive messages is very
different from
.Cm TCPKeepAlive
(below).
The server alive messages are sent through the encrypted channel
and therefore will not be spoofable.
The TCP keepalive option enabled by
.Cm TCPKeepAlive
is spoofable.
The server alive mechanism is valuable when the client or
server depend on knowing when a connection has become unresponsive.
.Pp
The default value is 3.
If, for example,
.Cm ServerAliveInterval
(see below) is set to 15 and
.Cm ServerAliveCountMax
is left at the default, if the server becomes unresponsive,
ssh will disconnect after approximately 45 seconds.
.It Cm ServerAliveInterval
Sets a timeout interval in seconds after which if no data has been received
from the server,
.Xr ssh 1
will send a message through the encrypted
channel to request a response from the server.
The default
is 0, indicating that these messages will not be sent to the server.
.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 ,
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
used when creating a Unix-domain socket file for local or remote
port forwarding.
This option is only used for port forwarding to a Unix-domain socket file.
.Pp
The default value is 0177, which creates a Unix-domain socket file that is
readable and writable only by the owner.
Note that not all operating systems honor the file mode on Unix-domain
socket files.
.It Cm StreamLocalBindUnlink
Specifies whether to remove an existing Unix-domain socket file for local
or remote port forwarding before creating a new one.
If the socket file already exists and
.Cm StreamLocalBindUnlink
is not enabled,
.Nm ssh
will be unable to forward the port to the Unix-domain socket file.
This option is only used for port forwarding to a Unix-domain socket file.
.Pp
The argument must be
.Cm yes
or
.Cm no
(the default).
.It Cm StrictHostKeyChecking
If this flag is set to
.Cm yes ,
.Xr ssh 1
will never automatically add host keys to the
.Pa ~/.ssh/known_hosts
file, and refuses to connect to hosts whose host key has changed.
This provides maximum protection against man-in-the-middle (MITM) attacks,
though it can be annoying when the
.Pa /etc/ssh/ssh_known_hosts
file is poorly maintained or when connections to new hosts are
frequently made.
This option forces the user to manually
add all new hosts.
.Pp
If this flag is set to
.Cm accept-new
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
.Cm no
or
.Cm off ,
ssh will automatically add new host keys to the user known hosts files
and allow connections to hosts with changed hostkeys to proceed,
subject to some restrictions.
If this flag is set to
.Cm ask
(the default),
new host keys
will be added to the user known host files only after the user
has confirmed that is what they really want to do, and
ssh will refuse to connect to hosts whose host key has changed.
The host keys of
known hosts will be verified automatically in all cases.
.It Cm SyslogFacility
Gives the facility code that is used when logging messages from
.Xr ssh 1 .
The possible values are: DAEMON, USER, AUTH, LOCAL0, LOCAL1, LOCAL2,
LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7.
The default is USER.
.It Cm TCPKeepAlive
Specifies whether the system should send TCP keepalive messages to the
other side.
If they are sent, death of the connection or crash of one
of the machines will be properly noticed.
However, this means that
connections will die if the route is down temporarily, and some people
find it annoying.
.Pp
The default is
.Cm yes
(to send TCP keepalive messages), and the client will notice
if the network goes down or the remote host dies.
This is important in scripts, and many users want it too.
.Pp
To disable TCP keepalive messages, the value should be set to
.Cm no .
See also
.Cm ServerAliveInterval
for protocol-level keepalives.
.It Cm Tunnel
Request
.Xr tun 4
device forwarding between the client and the server.
The argument must be
.Cm yes ,
.Cm point-to-point
(layer 3),
.Cm ethernet
(layer 2),
or
.Cm no
(the default).
Specifying
.Cm yes
requests the default tunnel mode, which is
.Cm point-to-point .
.It Cm TunnelDevice
Specifies the
.Xr tun 4
devices to open on the client
.Pq Ar local_tun
and the server
.Pq Ar remote_tun .
.Pp
The argument must be
.Sm off
.Ar local_tun Op : Ar remote_tun .
.Sm on
The devices may be specified by numerical ID or the keyword
.Cm any ,
which uses the next available tunnel device.
If
.Ar remote_tun
is not specified, it defaults to
.Cm any .
The default is
.Cm any:any .
.It Cm UpdateHostKeys
Specifies whether
.Xr ssh 1
should accept notifications of additional hostkeys from the server sent
after authentication has completed and add them to
.Cm UserKnownHostsFile .
The argument must be
.Cm yes ,
.Cm no
or
.Cm 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.
.Pp
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
.Cm UserKnownHostsFile
(i.e. not
.Cm GlobalKnownHostsFile )
and the host was authenticated using a plain key and not a certificate.
.Pp
.Cm UpdateHostKeys
is enabled by default if the user has not overridden the default
.Cm UserKnownHostsFile
setting and has not enabled
.Cm VerifyHostKeyDNS ,
otherwise
.Cm UpdateHostKeys
will be set to
.Cm no .
.Pp
If
.Cm UpdateHostKeys
is set to
.Cm ask ,
then the user is asked to confirm the modifications to the known_hosts file.
Confirmation is currently incompatible with
.Cm ControlPersist ,
and will be disabled if it is enabled.
.Pp
Presently, only
.Xr sshd 8
from OpenSSH 6.8 and greater support the
.Qq hostkeys@openssh.com
protocol extension used to inform the client of all the server's hostkeys.
.It Cm User
Specifies the user to log in as.
This can be useful when a different user name is used on different machines.
This saves the trouble of
having to remember to give the user name on the command line.
.It Cm UserKnownHostsFile
Specifies one or more files to use for the user
host key database, separated by whitespace.
Each filename may use tilde notation to refer to the user's home directory,
the tokens described in the
.Sx TOKENS
section and environment variables as described in the
.Sx ENVIRONMENT VARIABLES
section.
+A value of
+.Cm none
+causes
+.Xr ssh 1
+to ignore any user-specific known hosts files.
The default is
.Pa ~/.ssh/known_hosts ,
.Pa ~/.ssh/known_hosts2 .
.It Cm VerifyHostKeyDNS
Specifies whether to verify the remote key using DNS and SSHFP resource
records.
If this option is set to
.Cm yes ,
the client will implicitly trust keys that match a secure fingerprint
from DNS.
Insecure fingerprints will be handled as if this option was set to
.Cm ask .
If this option is set to
.Cm ask ,
information on fingerprint match will be displayed, but the user will still
need to confirm new host keys according to the
.Cm StrictHostKeyChecking
option.
The default is
.Cm yes
if compiled with LDNS and
.Cm no
otherwise.
.Pp
See also
.Sx VERIFYING HOST KEYS
in
.Xr ssh 1 .
.It Cm VersionAddendum
Specifies a string to append to the regular version string to identify
OS- or site-specific modifications.
The default is
.Dq FreeBSD-20220415 .
The value
.Cm none
may be used to disable this.
.It Cm VisualHostKey
If this flag is set to
.Cm yes ,
an ASCII art representation of the remote host key fingerprint is
printed in addition to the fingerprint string at login and
for unknown host keys.
If this flag is set to
.Cm no
(the default),
no fingerprint strings are printed at login and
only the fingerprint string will be printed for unknown host keys.
.It Cm XAuthLocation
Specifies the full pathname of the
.Xr xauth 1
program.
The default is
.Pa /usr/local/bin/xauth .
.El
.Sh PATTERNS
A
.Em pattern
consists of zero or more non-whitespace characters,
.Sq *
(a wildcard that matches zero or more characters),
or
.Sq ?\&
(a wildcard that matches exactly one character).
For example, to specify a set of declarations for any host in the
.Qq .co.uk
set of domains,
the following pattern could be used:
.Pp
.Dl Host *.co.uk
.Pp
The following pattern
would match any host in the 192.168.0.[0-9] network range:
.Pp
.Dl Host 192.168.0.?
.Pp
A
.Em pattern-list
is a comma-separated list of patterns.
Patterns within pattern-lists may be negated
by preceding them with an exclamation mark
.Pq Sq !\& .
For example,
to allow a key to be used from anywhere within an organization
except from the
.Qq dialup
pool,
the following entry (in authorized_keys) could be used:
.Pp
.Dl from=\&"!*.dialup.example.com,*.example.com\&"
.Pp
Note that a negated match will never produce a positive result by itself.
For example, attempting to match
.Qq host3
against the following pattern-list will fail:
.Pp
.Dl from=\&"!host1,!host2\&"
.Pp
The solution here is to include a term that will yield a positive match,
such as a wildcard:
.Pp
.Dl from=\&"!host1,!host2,*\&"
.Sh TOKENS
Arguments to some keywords can make use of tokens,
which are expanded at runtime:
.Pp
.Bl -tag -width XXXX -offset indent -compact
.It %%
A literal
.Sq % .
.It \&%C
Hash of %l%h%p%r.
.It %d
Local user's home directory.
.It %f
The fingerprint of the server's host key.
.It %H
The
.Pa known_hosts
hostname or address that is being searched for.
.It %h
The remote hostname.
.It \%%I
A string describing the reason for a
.Cm KnownHostsCommand
execution: either
.Cm ADDRESS
when looking up a host by address (only when
.Cm CheckHostIP
is enabled),
.Cm HOSTNAME
when searching by hostname, or
.Cm ORDER
when preparing the host key algorithm preference list to use for the
destination host.
.It %i
The local user ID.
.It %K
The base64 encoded host key.
.It %k
The host key alias if specified, otherwise the original remote hostname given
on the command line.
.It %L
The local hostname.
.It %l
The local hostname, including the domain name.
.It %n
The original remote hostname, as given on the command line.
.It %p
The remote port.
.It %r
The remote username.
.It \&%T
The local
.Xr tun 4
or
.Xr tap 4
network interface assigned if
tunnel forwarding was requested, or
.Qq NONE
otherwise.
.It %t
The type of the server host key, e.g.
.Cm ssh-ed25519 .
.It %u
The local username.
.El
.Pp
.Cm CertificateFile ,
.Cm ControlPath ,
.Cm IdentityAgent ,
.Cm IdentityFile ,
.Cm KnownHostsCommand ,
.Cm LocalForward ,
.Cm Match exec ,
.Cm RemoteCommand ,
.Cm RemoteForward ,
and
.Cm UserKnownHostsFile
accept the tokens %%, %C, %d, %h, %i, %k, %L, %l, %n, %p, %r, and %u.
.Pp
.Cm KnownHostsCommand
additionally accepts the tokens %f, %H, %I, %K and %t.
.Pp
.Cm Hostname
accepts the tokens %% and %h.
.Pp
.Cm LocalCommand
accepts all tokens.
.Pp
.Cm ProxyCommand
and
.Cm ProxyJump
accept the tokens %%, %h, %n, %p, and %r.
.Sh ENVIRONMENT VARIABLES
Arguments to some keywords can be expanded at runtime from environment
variables on the client by enclosing them in
.Ic ${} ,
for example
.Ic ${HOME}/.ssh
would refer to the user's .ssh directory.
If a specified environment variable does not exist then an error will be
returned and the setting for that keyword will be ignored.
.Pp
The keywords
.Cm CertificateFile ,
.Cm ControlPath ,
.Cm IdentityAgent ,
.Cm IdentityFile ,
.Cm KnownHostsCommand ,
and
.Cm UserKnownHostsFile
support environment variables.
The keywords
.Cm LocalForward
and
.Cm RemoteForward
support environment variables only for Unix domain socket paths.
.Sh FILES
.Bl -tag -width Ds
.It Pa ~/.ssh/config
This is the per-user configuration file.
The format of this file is described above.
This file is used by the SSH client.
Because of the potential for abuse, this file must have strict permissions:
read/write for the user, and not writable by others.
.It Pa /etc/ssh/ssh_config
Systemwide configuration file.
This file provides defaults for those
values that are not specified in the user's configuration file, and
for those users who do not have a configuration file.
This file must be world-readable.
.El
.Sh SEE ALSO
.Xr ssh 1
.Sh AUTHORS
.An -nosplit
OpenSSH is a derivative of the original and free
ssh 1.2.12 release by
.An Tatu Ylonen .
.An Aaron Campbell , Bob Beck , Markus Friedl ,
.An Niels Provos , Theo de Raadt
and
.An Dug Song
removed many bugs, re-added newer features and
created OpenSSH.
.An Markus Friedl
contributed the support for SSH protocol versions 1.5 and 2.0.
diff --git a/crypto/openssh/ssh_namespace.h b/crypto/openssh/ssh_namespace.h
index 2fd4613743f6..cfbc9d9fbcba 100644
--- a/crypto/openssh/ssh_namespace.h
+++ b/crypto/openssh/ssh_namespace.h
@@ -1,970 +1,1013 @@
/*
* This file was machine-@generated. Do not edit manually.
* Run crypto/openssh/freebsd-namespace.sh to regenerate.
*/
#define Blowfish_decipher Fssh_Blowfish_decipher
#define Blowfish_encipher Fssh_Blowfish_encipher
#define Blowfish_expand0state Fssh_Blowfish_expand0state
#define Blowfish_expandstate Fssh_Blowfish_expandstate
#define Blowfish_initstate Fssh_Blowfish_initstate
#define Blowfish_stream2word Fssh_Blowfish_stream2word
#define Decode Fssh_Decode
#define EVP_CIPHER_CTX_get_iv Fssh_EVP_CIPHER_CTX_get_iv
#define EVP_CIPHER_CTX_set_iv Fssh_EVP_CIPHER_CTX_set_iv
#define Encode Fssh_Encode
#define Hide Fssh_Hide
#define Rq_mult_small Fssh_Rq_mult_small
#define Short_random Fssh_Short_random
#define _ssh__compat_glob Fssh__ssh__compat_glob
#define _ssh__compat_globfree Fssh__ssh__compat_globfree
#define _ssh_exchange_banner Fssh__ssh_exchange_banner
#define _ssh_host_key_sign Fssh__ssh_host_key_sign
#define _ssh_host_private_key Fssh__ssh_host_private_key
#define _ssh_host_public_key Fssh__ssh_host_public_key
#define _ssh_order_hostkeyalgs Fssh__ssh_order_hostkeyalgs
#define _ssh_read_banner Fssh__ssh_read_banner
#define _ssh_send_banner Fssh__ssh_send_banner
#define _ssh_verify_host_key Fssh__ssh_verify_host_key
#define a2port Fssh_a2port
#define a2tun Fssh_a2tun
#define add_host_to_hostfile Fssh_add_host_to_hostfile
#define add_p1p1 Fssh_add_p1p1
#define addargs Fssh_addargs
#define addr_and Fssh_addr_and
#define addr_cmp Fssh_addr_cmp
#define addr_host_is_all0s Fssh_addr_host_is_all0s
+#define addr_host_to_all1s Fssh_addr_host_to_all1s
#define addr_hostmask Fssh_addr_hostmask
+#define addr_increment Fssh_addr_increment
#define addr_invert Fssh_addr_invert
#define addr_is_all0s Fssh_addr_is_all0s
#define addr_match_cidr_list Fssh_addr_match_cidr_list
#define addr_match_list Fssh_addr_match_list
#define addr_netmask Fssh_addr_netmask
#define addr_netmatch Fssh_addr_netmatch
#define addr_ntop Fssh_addr_ntop
+#define addr_or Fssh_addr_or
#define addr_pton Fssh_addr_pton
#define addr_pton_cidr Fssh_addr_pton_cidr
#define addr_sa_pton Fssh_addr_sa_pton
#define addr_sa_to_xaddr Fssh_addr_sa_to_xaddr
#define addr_unicast_masklen Fssh_addr_unicast_masklen
#define addr_xaddr_to_sa Fssh_addr_xaddr_to_sa
#define argv_assemble Fssh_argv_assemble
#define argv_consume Fssh_argv_consume
#define argv_free Fssh_argv_free
#define argv_next Fssh_argv_next
#define argv_split Fssh_argv_split
#define ask_permission Fssh_ask_permission
#define asmprintf Fssh_asmprintf
#define atoi_err Fssh_atoi_err
#define atomicio Fssh_atomicio
#define atomicio6 Fssh_atomicio6
#define atomiciov Fssh_atomiciov
#define atomiciov6 Fssh_atomiciov6
#define bandwidth_limit Fssh_bandwidth_limit
#define bandwidth_limit_init Fssh_bandwidth_limit_init
#define barrett_reduce Fssh_barrett_reduce
#define baud_to_speed Fssh_baud_to_speed
#define bcrypt_hash Fssh_bcrypt_hash
#define bcrypt_pbkdf Fssh_bcrypt_pbkdf
#define bitmap_clear_bit Fssh_bitmap_clear_bit
#define bitmap_free Fssh_bitmap_free
#define bitmap_from_string Fssh_bitmap_from_string
#define bitmap_nbits Fssh_bitmap_nbits
#define bitmap_nbytes Fssh_bitmap_nbytes
#define bitmap_new Fssh_bitmap_new
#define bitmap_set_bit Fssh_bitmap_set_bit
#define bitmap_test_bit Fssh_bitmap_test_bit
#define bitmap_to_string Fssh_bitmap_to_string
#define bitmap_zero Fssh_bitmap_zero
#define blf_cbc_decrypt Fssh_blf_cbc_decrypt
#define blf_cbc_encrypt Fssh_blf_cbc_encrypt
#define blf_dec Fssh_blf_dec
#define blf_ecb_decrypt Fssh_blf_ecb_decrypt
#define blf_ecb_encrypt Fssh_blf_ecb_encrypt
#define blf_enc Fssh_blf_enc
#define blf_key Fssh_blf_key
#define blob_section Fssh_blob_section
#define cert_free Fssh_cert_free
#define cert_parse Fssh_cert_parse
#define chacha_encrypt_bytes Fssh_chacha_encrypt_bytes
#define chacha_ivsetup Fssh_chacha_ivsetup
#define chacha_keysetup Fssh_chacha_keysetup
#define chachapoly_crypt Fssh_chachapoly_crypt
#define chachapoly_free Fssh_chachapoly_free
#define chachapoly_get_length Fssh_chachapoly_get_length
#define chachapoly_new Fssh_chachapoly_new
#define chan_ibuf_empty Fssh_chan_ibuf_empty
#define chan_is_dead Fssh_chan_is_dead
#define chan_mark_dead Fssh_chan_mark_dead
#define chan_obuf_empty Fssh_chan_obuf_empty
#define chan_rcvd_eow Fssh_chan_rcvd_eow
#define chan_rcvd_ieof Fssh_chan_rcvd_ieof
#define chan_rcvd_oclose Fssh_chan_rcvd_oclose
#define chan_read_failed Fssh_chan_read_failed
#define chan_send_close2 Fssh_chan_send_close2
#define chan_send_eof2 Fssh_chan_send_eof2
#define chan_shutdown_extended_read Fssh_chan_shutdown_extended_read
#define chan_shutdown_read Fssh_chan_shutdown_read
#define chan_shutdown_write Fssh_chan_shutdown_write
#define chan_write_failed Fssh_chan_write_failed
#define channel_add_permission Fssh_channel_add_permission
+#define channel_add_timeout Fssh_channel_add_timeout
#define channel_after_poll Fssh_channel_after_poll
#define channel_by_id Fssh_channel_by_id
#define channel_by_remote_id Fssh_channel_by_remote_id
#define channel_cancel_cleanup Fssh_channel_cancel_cleanup
#define channel_cancel_lport_listener Fssh_channel_cancel_lport_listener
#define channel_cancel_rport_listener Fssh_channel_cancel_rport_listener
#define channel_clear_permission Fssh_channel_clear_permission
+#define channel_clear_timeouts Fssh_channel_clear_timeouts
#define channel_close_all Fssh_channel_close_all
#define channel_close_fd Fssh_channel_close_fd
#define channel_connect_by_listen_address Fssh_channel_connect_by_listen_address
#define channel_connect_by_listen_path Fssh_channel_connect_by_listen_path
#define channel_connect_stdio_fwd Fssh_channel_connect_stdio_fwd
#define channel_connect_to_path Fssh_channel_connect_to_path
#define channel_connect_to_port Fssh_channel_connect_to_port
#define channel_decode_socks4 Fssh_channel_decode_socks4
#define channel_decode_socks5 Fssh_channel_decode_socks5
#define channel_disable_admin Fssh_channel_disable_admin
#define channel_find_open Fssh_channel_find_open
+#define channel_force_close Fssh_channel_force_close
#define channel_format_extended_usage Fssh_channel_format_extended_usage
#define channel_free Fssh_channel_free
#define channel_free_all Fssh_channel_free_all
#define channel_fwd_bind_addr Fssh_channel_fwd_bind_addr
#define channel_handler Fssh_channel_handler
#define channel_init_channels Fssh_channel_init_channels
#define channel_input_data Fssh_channel_input_data
#define channel_input_extended_data Fssh_channel_input_extended_data
#define channel_input_ieof Fssh_channel_input_ieof
#define channel_input_oclose Fssh_channel_input_oclose
#define channel_input_open_confirmation Fssh_channel_input_open_confirmation
#define channel_input_open_failure Fssh_channel_input_open_failure
#define channel_input_status_confirm Fssh_channel_input_status_confirm
#define channel_input_window_adjust Fssh_channel_input_window_adjust
#define channel_lookup Fssh_channel_lookup
#define channel_new Fssh_channel_new
#define channel_not_very_much_buffered_data Fssh_channel_not_very_much_buffered_data
#define channel_open_message Fssh_channel_open_message
#define channel_output_poll Fssh_channel_output_poll
#define channel_parse_id Fssh_channel_parse_id
#define channel_permit_all Fssh_channel_permit_all
#define channel_post_auth_listener Fssh_channel_post_auth_listener
#define channel_post_connecting Fssh_channel_post_connecting
#define channel_post_mux_client Fssh_channel_post_mux_client
#define channel_post_mux_listener Fssh_channel_post_mux_listener
#define channel_post_open Fssh_channel_post_open
#define channel_post_port_listener Fssh_channel_post_port_listener
#define channel_post_x11_listener Fssh_channel_post_x11_listener
#define channel_pre_connecting Fssh_channel_pre_connecting
#define channel_pre_dynamic Fssh_channel_pre_dynamic
#define channel_pre_listener Fssh_channel_pre_listener
#define channel_pre_mux_client Fssh_channel_pre_mux_client
#define channel_pre_open Fssh_channel_pre_open
#define channel_pre_x11_open Fssh_channel_pre_x11_open
#define channel_prepare_poll Fssh_channel_prepare_poll
#define channel_proxy_downstream Fssh_channel_proxy_downstream
#define channel_proxy_upstream Fssh_channel_proxy_upstream
#define channel_register_cleanup Fssh_channel_register_cleanup
#define channel_register_fds Fssh_channel_register_fds
#define channel_register_filter Fssh_channel_register_filter
#define channel_register_open_confirm Fssh_channel_register_open_confirm
#define channel_register_status_confirm Fssh_channel_register_status_confirm
#define channel_request_remote_forwarding Fssh_channel_request_remote_forwarding
#define channel_request_rforward_cancel Fssh_channel_request_rforward_cancel
#define channel_request_start Fssh_channel_request_start
#define channel_send_open Fssh_channel_send_open
#define channel_send_window_changes Fssh_channel_send_window_changes
#define channel_set_af Fssh_channel_set_af
#define channel_set_fds Fssh_channel_set_fds
#define channel_set_x11_refuse_time Fssh_channel_set_x11_refuse_time
+#define channel_set_xtype Fssh_channel_set_xtype
#define channel_setup_fwd_listener_streamlocal Fssh_channel_setup_fwd_listener_streamlocal
#define channel_setup_fwd_listener_tcpip Fssh_channel_setup_fwd_listener_tcpip
#define channel_setup_local_fwd_listener Fssh_channel_setup_local_fwd_listener
#define channel_setup_remote_fwd_listener Fssh_channel_setup_remote_fwd_listener
#define channel_still_open Fssh_channel_still_open
#define channel_stop_listening Fssh_channel_stop_listening
#define channel_update_permission Fssh_channel_update_permission
#define check_hostkeys_by_key_or_type Fssh_check_hostkeys_by_key_or_type
#define check_key_in_hostkeys Fssh_check_key_in_hostkeys
#define child_set_env Fssh_child_set_env
#define choose_dh Fssh_choose_dh
#define choose_t Fssh_choose_t
#define chop Fssh_chop
#define cipher_alg_list Fssh_cipher_alg_list
#define cipher_authlen Fssh_cipher_authlen
#define cipher_blocksize Fssh_cipher_blocksize
#define cipher_by_name Fssh_cipher_by_name
#define cipher_crypt Fssh_cipher_crypt
#define cipher_ctx_is_plaintext Fssh_cipher_ctx_is_plaintext
#define cipher_free Fssh_cipher_free
#define cipher_get_keyiv Fssh_cipher_get_keyiv
#define cipher_get_keyiv_len Fssh_cipher_get_keyiv_len
#define cipher_get_length Fssh_cipher_get_length
#define cipher_init Fssh_cipher_init
#define cipher_is_cbc Fssh_cipher_is_cbc
#define cipher_ivlen Fssh_cipher_ivlen
#define cipher_keylen Fssh_cipher_keylen
#define cipher_seclen Fssh_cipher_seclen
#define cipher_set_keyiv Fssh_cipher_set_keyiv
#define cipher_warning_message Fssh_cipher_warning_message
#define ciphers_valid Fssh_ciphers_valid
#define cleanhostname Fssh_cleanhostname
#define cleanup_exit Fssh_cleanup_exit
#define client_converse Fssh_client_converse
#define colon Fssh_colon
#define compare Fssh_compare
#define compare_gps Fssh_compare_gps
#define compat_banner Fssh_compat_banner
#define compat_cipher_proposal Fssh_compat_cipher_proposal
#define compat_kex_proposal Fssh_compat_kex_proposal
#define compat_pkalg_proposal Fssh_compat_pkalg_proposal
#define compression_alg_list Fssh_compression_alg_list
#define connect_next Fssh_connect_next
+#define connect_to Fssh_connect_to
#define connect_to_helper Fssh_connect_to_helper
#define convtime Fssh_convtime
#define crypto_hash_sha512 Fssh_crypto_hash_sha512
#define crypto_kem_sntrup761_dec Fssh_crypto_kem_sntrup761_dec
#define crypto_kem_sntrup761_enc Fssh_crypto_kem_sntrup761_enc
#define crypto_kem_sntrup761_keypair Fssh_crypto_kem_sntrup761_keypair
#define crypto_scalarmult_curve25519 Fssh_crypto_scalarmult_curve25519
#define crypto_sign_ed25519 Fssh_crypto_sign_ed25519
#define crypto_sign_ed25519_keypair Fssh_crypto_sign_ed25519_keypair
#define crypto_sign_ed25519_open Fssh_crypto_sign_ed25519_open
-#define crypto_sign_ed25519_ref_double_scalarmult_vartime Fssh_crypto_sign_ed25519_ref_double_scalarmult_vartime
-#define crypto_sign_ed25519_ref_fe25519_add Fssh_crypto_sign_ed25519_ref_fe25519_add
-#define crypto_sign_ed25519_ref_fe25519_cmov Fssh_crypto_sign_ed25519_ref_fe25519_cmov
-#define crypto_sign_ed25519_ref_fe25519_freeze Fssh_crypto_sign_ed25519_ref_fe25519_freeze
#define crypto_sign_ed25519_ref_fe25519_getparity Fssh_crypto_sign_ed25519_ref_fe25519_getparity
-#define crypto_sign_ed25519_ref_fe25519_invert Fssh_crypto_sign_ed25519_ref_fe25519_invert
#define crypto_sign_ed25519_ref_fe25519_iseq_vartime Fssh_crypto_sign_ed25519_ref_fe25519_iseq_vartime
-#define crypto_sign_ed25519_ref_fe25519_iszero Fssh_crypto_sign_ed25519_ref_fe25519_iszero
#define crypto_sign_ed25519_ref_fe25519_mul Fssh_crypto_sign_ed25519_ref_fe25519_mul
-#define crypto_sign_ed25519_ref_fe25519_neg Fssh_crypto_sign_ed25519_ref_fe25519_neg
-#define crypto_sign_ed25519_ref_fe25519_pack Fssh_crypto_sign_ed25519_ref_fe25519_pack
-#define crypto_sign_ed25519_ref_fe25519_pow2523 Fssh_crypto_sign_ed25519_ref_fe25519_pow2523
-#define crypto_sign_ed25519_ref_fe25519_setone Fssh_crypto_sign_ed25519_ref_fe25519_setone
-#define crypto_sign_ed25519_ref_fe25519_setzero Fssh_crypto_sign_ed25519_ref_fe25519_setzero
-#define crypto_sign_ed25519_ref_fe25519_square Fssh_crypto_sign_ed25519_ref_fe25519_square
-#define crypto_sign_ed25519_ref_fe25519_sub Fssh_crypto_sign_ed25519_ref_fe25519_sub
-#define crypto_sign_ed25519_ref_fe25519_unpack Fssh_crypto_sign_ed25519_ref_fe25519_unpack
#define crypto_sign_ed25519_ref_isneutral_vartime Fssh_crypto_sign_ed25519_ref_isneutral_vartime
#define crypto_sign_ed25519_ref_pack Fssh_crypto_sign_ed25519_ref_pack
-#define crypto_sign_ed25519_ref_sc25519_2interleave2 Fssh_crypto_sign_ed25519_ref_sc25519_2interleave2
-#define crypto_sign_ed25519_ref_sc25519_add Fssh_crypto_sign_ed25519_ref_sc25519_add
-#define crypto_sign_ed25519_ref_sc25519_from32bytes Fssh_crypto_sign_ed25519_ref_sc25519_from32bytes
-#define crypto_sign_ed25519_ref_sc25519_from64bytes Fssh_crypto_sign_ed25519_ref_sc25519_from64bytes
-#define crypto_sign_ed25519_ref_sc25519_from_shortsc Fssh_crypto_sign_ed25519_ref_sc25519_from_shortsc
-#define crypto_sign_ed25519_ref_sc25519_isshort_vartime Fssh_crypto_sign_ed25519_ref_sc25519_isshort_vartime
-#define crypto_sign_ed25519_ref_sc25519_iszero_vartime Fssh_crypto_sign_ed25519_ref_sc25519_iszero_vartime
-#define crypto_sign_ed25519_ref_sc25519_lt_vartime Fssh_crypto_sign_ed25519_ref_sc25519_lt_vartime
-#define crypto_sign_ed25519_ref_sc25519_mul Fssh_crypto_sign_ed25519_ref_sc25519_mul
-#define crypto_sign_ed25519_ref_sc25519_mul_shortsc Fssh_crypto_sign_ed25519_ref_sc25519_mul_shortsc
-#define crypto_sign_ed25519_ref_sc25519_sub_nored Fssh_crypto_sign_ed25519_ref_sc25519_sub_nored
-#define crypto_sign_ed25519_ref_sc25519_to32bytes Fssh_crypto_sign_ed25519_ref_sc25519_to32bytes
-#define crypto_sign_ed25519_ref_sc25519_window3 Fssh_crypto_sign_ed25519_ref_sc25519_window3
-#define crypto_sign_ed25519_ref_sc25519_window5 Fssh_crypto_sign_ed25519_ref_sc25519_window5
#define crypto_sign_ed25519_ref_scalarmult_base Fssh_crypto_sign_ed25519_ref_scalarmult_base
-#define crypto_sign_ed25519_ref_shortsc25519_from16bytes Fssh_crypto_sign_ed25519_ref_shortsc25519_from16bytes
#define crypto_sign_ed25519_ref_unpackneg_vartime Fssh_crypto_sign_ed25519_ref_unpackneg_vartime
-#define crypto_verify_32 Fssh_crypto_verify_32
#define daemonized Fssh_daemonized
#define dangerous_locale Fssh_dangerous_locale
#define dbl_p1p1 Fssh_dbl_p1p1
#define default_key_sign Fssh_default_key_sign
#define deserialise_identity2 Fssh_deserialise_identity2
#define dh_estimate Fssh_dh_estimate
#define dh_gen_key Fssh_dh_gen_key
#define dh_new_group Fssh_dh_new_group
#define dh_new_group1 Fssh_dh_new_group1
#define dh_new_group14 Fssh_dh_new_group14
#define dh_new_group16 Fssh_dh_new_group16
#define dh_new_group18 Fssh_dh_new_group18
#define dh_new_group_asc Fssh_dh_new_group_asc
#define dh_new_group_fallback Fssh_dh_new_group_fallback
#define dh_pub_is_valid Fssh_dh_pub_is_valid
#define dh_set_moduli_file Fssh_dh_set_moduli_file
#define dispatch_protocol_error Fssh_dispatch_protocol_error
#define dispatch_protocol_ignore Fssh_dispatch_protocol_ignore
#define do_log Fssh_do_log
#define dollar_expand Fssh_dollar_expand
#define ecdsa_do_sign Fssh_ecdsa_do_sign
#define encode_constraints Fssh_encode_constraints
#define encode_dest_constraint_hop Fssh_encode_dest_constraint_hop
#define exited_cleanly Fssh_exited_cleanly
#define export_dns_rr Fssh_export_dns_rr
#define fd_ready Fssh_fd_ready
+#define fe25519_reduce_add_sub Fssh_fe25519_reduce_add_sub
#define filter_list Fssh_filter_list
#define fingerprint_b64 Fssh_fingerprint_b64
#define fingerprint_hex Fssh_fingerprint_hex
#define fmprintf Fssh_fmprintf
#define fmt_scaled Fssh_fmt_scaled
#define fmt_timeframe Fssh_fmt_timeframe
#define format_absolute_time Fssh_format_absolute_time
#define format_timestamp Fssh_format_timestamp
#define forward_equals Fssh_forward_equals
#define free_hostkeys Fssh_free_hostkeys
#define freeargs Fssh_freeargs
#define freerrset Fssh_freerrset
#define freezero Fssh_freezero
#define fwd_ident Fssh_fwd_ident
#define g_opendir Fssh_g_opendir
#define g_stat Fssh_g_stat
#define gen_candidates Fssh_gen_candidates
-#define get_hram Fssh_get_hram
#define get_local_ipaddr Fssh_get_local_ipaddr
#define get_local_name Fssh_get_local_name
#define get_local_port Fssh_get_local_port
#define get_peer_ipaddr Fssh_get_peer_ipaddr
#define get_peer_port Fssh_get_peer_port
#define get_rdomain Fssh_get_rdomain
#define get_sock_af Fssh_get_sock_af
#define get_sock_port Fssh_get_sock_port
#define get_socket_address Fssh_get_socket_address
#define get_u16 Fssh_get_u16
#define get_u32 Fssh_get_u32
#define get_u32_le Fssh_get_u32_le
#define get_u64 Fssh_get_u64
#define getrrsetbyname Fssh_getrrsetbyname
#define glob0 Fssh_glob0
#define glob2 Fssh_glob2
#define globexp1 Fssh_globexp1
#define globextend Fssh_globextend
#define host_delete Fssh_host_delete
#define host_hash Fssh_host_hash
#define hostfile_create_user_ssh_dir Fssh_hostfile_create_user_ssh_dir
#define hostfile_read_key Fssh_hostfile_read_key
#define hostfile_replace_entries Fssh_hostfile_replace_entries
#define hostkeys_foreach Fssh_hostkeys_foreach
#define hostkeys_foreach_file Fssh_hostkeys_foreach_file
#define hpdelim Fssh_hpdelim
#define hpdelim2 Fssh_hpdelim2
#define init_hostkeys Fssh_init_hostkeys
#define input_kex_dh_gex_group Fssh_input_kex_dh_gex_group
#define input_kex_dh_gex_init Fssh_input_kex_dh_gex_init
#define input_kex_dh_gex_reply Fssh_input_kex_dh_gex_reply
#define input_kex_dh_gex_request Fssh_input_kex_dh_gex_request
#define input_kex_gen_init Fssh_input_kex_gen_init
#define input_kex_gen_reply Fssh_input_kex_gen_reply
#define iptos2str Fssh_iptos2str
#define ipv64_normalise_mapped Fssh_ipv64_normalise_mapped
#define is_cert_revoked Fssh_is_cert_revoked
#define is_key_revoked Fssh_is_key_revoked
#define kex_alg_by_name Fssh_kex_alg_by_name
#define kex_alg_list Fssh_kex_alg_list
#define kex_assemble_names Fssh_kex_assemble_names
#define kex_buf2prop Fssh_kex_buf2prop
#define kex_c25519_dec Fssh_kex_c25519_dec
#define kex_c25519_enc Fssh_kex_c25519_enc
#define kex_c25519_keypair Fssh_kex_c25519_keypair
#define kex_choose_conf Fssh_kex_choose_conf
#define kex_derive_keys Fssh_kex_derive_keys
#define kex_dh_compute_key Fssh_kex_dh_compute_key
#define kex_dh_dec Fssh_kex_dh_dec
#define kex_dh_enc Fssh_kex_dh_enc
#define kex_dh_keygen Fssh_kex_dh_keygen
#define kex_dh_keypair Fssh_kex_dh_keypair
#define kex_ecdh_dec Fssh_kex_ecdh_dec
#define kex_ecdh_dec_key_group Fssh_kex_ecdh_dec_key_group
#define kex_ecdh_enc Fssh_kex_ecdh_enc
#define kex_ecdh_keypair Fssh_kex_ecdh_keypair
#define kex_exchange_identification Fssh_kex_exchange_identification
#define kex_free Fssh_kex_free
#define kex_free_newkeys Fssh_kex_free_newkeys
#define kex_gen_client Fssh_kex_gen_client
#define kex_gen_hash Fssh_kex_gen_hash
#define kex_gen_server Fssh_kex_gen_server
#define kex_input_ext_info Fssh_kex_input_ext_info
#define kex_input_kexinit Fssh_kex_input_kexinit
#define kex_input_newkeys Fssh_kex_input_newkeys
#define kex_kem_sntrup761x25519_dec Fssh_kex_kem_sntrup761x25519_dec
#define kex_kem_sntrup761x25519_enc Fssh_kex_kem_sntrup761x25519_enc
#define kex_kem_sntrup761x25519_keypair Fssh_kex_kem_sntrup761x25519_keypair
#define kex_load_hostkey Fssh_kex_load_hostkey
#define kex_names_cat Fssh_kex_names_cat
#define kex_names_valid Fssh_kex_names_valid
#define kex_new Fssh_kex_new
#define kex_prop2buf Fssh_kex_prop2buf
#define kex_prop_free Fssh_kex_prop_free
#define kex_protocol_error Fssh_kex_protocol_error
#define kex_ready Fssh_kex_ready
#define kex_send_kexinit Fssh_kex_send_kexinit
#define kex_send_newkeys Fssh_kex_send_newkeys
#define kex_setup Fssh_kex_setup
#define kex_start_rekex Fssh_kex_start_rekex
#define kex_verify_host_key Fssh_kex_verify_host_key
#define kexc25519_keygen Fssh_kexc25519_keygen
#define kexc25519_shared_key Fssh_kexc25519_shared_key
#define kexc25519_shared_key_ext Fssh_kexc25519_shared_key_ext
#define kexgex_client Fssh_kexgex_client
#define kexgex_hash Fssh_kexgex_hash
#define kexgex_server Fssh_kexgex_server
#define krl_dump Fssh_krl_dump
#define load_hostkeys Fssh_load_hostkeys
#define load_hostkeys_file Fssh_load_hostkeys_file
#define log_change_level Fssh_log_change_level
#define log_facility_name Fssh_log_facility_name
#define log_facility_number Fssh_log_facility_number
#define log_init Fssh_log_init
#define log_is_on_stderr Fssh_log_is_on_stderr
#define log_level_get Fssh_log_level_get
#define log_level_name Fssh_log_level_name
#define log_level_number Fssh_log_level_number
#define log_redirect_stderr_to Fssh_log_redirect_stderr_to
#define log_verbose_add Fssh_log_verbose_add
#define log_verbose_reset Fssh_log_verbose_reset
#define lookup_env_in_list Fssh_lookup_env_in_list
#define lookup_key_in_hostkeys_by_type Fssh_lookup_key_in_hostkeys_by_type
#define lookup_marker_in_hostkeys Fssh_lookup_marker_in_hostkeys
#define lookup_setenv_in_list Fssh_lookup_setenv_in_list
#define lowercase Fssh_lowercase
#define mac_alg_list Fssh_mac_alg_list
#define mac_check Fssh_mac_check
#define mac_clear Fssh_mac_clear
#define mac_compute Fssh_mac_compute
#define mac_init Fssh_mac_init
#define mac_setup Fssh_mac_setup
#define mac_valid Fssh_mac_valid
#define match_filter_allowlist Fssh_match_filter_allowlist
#define match_filter_denylist Fssh_match_filter_denylist
#define match_host_and_ip Fssh_match_host_and_ip
#define match_hostname Fssh_match_hostname
#define match_list Fssh_match_list
#define match_maybe_hashed Fssh_match_maybe_hashed
#define match_pattern Fssh_match_pattern
#define match_pattern_list Fssh_match_pattern_list
#define match_user Fssh_match_user
#define match_usergroup_pattern_list Fssh_match_usergroup_pattern_list
#define mktemp_proto Fssh_mktemp_proto
#define mm_choose_dh Fssh_mm_choose_dh
#define mm_receive_fd Fssh_mm_receive_fd
#define mm_send_fd Fssh_mm_send_fd
#define mm_sshkey_sign Fssh_mm_sshkey_sign
#define monotime Fssh_monotime
#define monotime_double Fssh_monotime_double
#define monotime_ts Fssh_monotime_ts
#define monotime_tv Fssh_monotime_tv
#define mprintf Fssh_mprintf
#define ms_subtract_diff Fssh_ms_subtract_diff
#define ms_to_timespec Fssh_ms_to_timespec
#define msetlocale Fssh_msetlocale
#define newkeys_from_blob Fssh_newkeys_from_blob
#define newkeys_to_blob Fssh_newkeys_to_blob
#define nh_aux Fssh_nh_aux
#define nh_final Fssh_nh_final
#define note_key Fssh_note_key
#define notify_complete Fssh_notify_complete
#define notify_start Fssh_notify_start
#define open_preamble Fssh_open_preamble
#define openssh_RSA_verify Fssh_openssh_RSA_verify
#define opt_array_append Fssh_opt_array_append
#define opt_array_append2 Fssh_opt_array_append2
#define opt_dequote Fssh_opt_dequote
#define opt_flag Fssh_opt_flag
#define opt_match Fssh_opt_match
#define ossl_error Fssh_ossl_error
#define parse_absolute_time Fssh_parse_absolute_time
#define parse_ipqos Fssh_parse_ipqos
#define parse_prime Fssh_parse_prime
#define parse_revoked_certs Fssh_parse_revoked_certs
#define parse_uri Fssh_parse_uri
#define parse_user_host_path Fssh_parse_user_host_path
#define parse_user_host_port Fssh_parse_user_host_port
#define path_absolute Fssh_path_absolute
#define pem_passphrase_cb Fssh_pem_passphrase_cb
#define percent_dollar_expand Fssh_percent_dollar_expand
#define percent_expand Fssh_percent_expand
#define permission_set_add Fssh_permission_set_add
#define permitopen_port Fssh_permitopen_port
#define pkcs11_add_provider Fssh_pkcs11_add_provider
#define pkcs11_del_provider Fssh_pkcs11_del_provider
#define pkcs11_ecdsa_wrap Fssh_pkcs11_ecdsa_wrap
#define pkcs11_fetch_certs Fssh_pkcs11_fetch_certs
#define pkcs11_fetch_keys Fssh_pkcs11_fetch_keys
#define pkcs11_find Fssh_pkcs11_find
#define pkcs11_get_key Fssh_pkcs11_get_key
#define pkcs11_init Fssh_pkcs11_init
#define pkcs11_k11_free Fssh_pkcs11_k11_free
#define pkcs11_login_slot Fssh_pkcs11_login_slot
#define pkcs11_provider_finalize Fssh_pkcs11_provider_finalize
#define pkcs11_provider_unref Fssh_pkcs11_provider_unref
#define pkcs11_rsa_private_decrypt Fssh_pkcs11_rsa_private_decrypt
#define pkcs11_rsa_private_encrypt Fssh_pkcs11_rsa_private_encrypt
#define pkcs11_rsa_wrap Fssh_pkcs11_rsa_wrap
#define pkcs11_terminate Fssh_pkcs11_terminate
#define plain_key_blob Fssh_plain_key_blob
#define platform_disable_tracing Fssh_platform_disable_tracing
#define platform_pledge_agent Fssh_platform_pledge_agent
#define platform_pledge_mux Fssh_platform_pledge_mux
#define platform_pledge_sftp_server Fssh_platform_pledge_sftp_server
#define platform_sys_dir_uid Fssh_platform_sys_dir_uid
#define pledge Fssh_pledge
#define poly1305_auth Fssh_poly1305_auth
-#define poly64 Fssh_poly64
#define poly_hash Fssh_poly_hash
#define port_open_helper Fssh_port_open_helper
#define prime_test Fssh_prime_test
#define private2_check_padding Fssh_private2_check_padding
#define private2_uudecode Fssh_private2_uudecode
#define proposals_match Fssh_proposals_match
+#define ptimeout_deadline_monotime Fssh_ptimeout_deadline_monotime
+#define ptimeout_deadline_ms Fssh_ptimeout_deadline_ms
+#define ptimeout_deadline_sec Fssh_ptimeout_deadline_sec
+#define ptimeout_get_ms Fssh_ptimeout_get_ms
+#define ptimeout_get_tsp Fssh_ptimeout_get_tsp
+#define ptimeout_init Fssh_ptimeout_init
+#define ptimeout_isset Fssh_ptimeout_isset
#define put_bitmap Fssh_put_bitmap
#define put_host_port Fssh_put_host_port
#define put_u16 Fssh_put_u16
#define put_u32 Fssh_put_u32
#define put_u32_le Fssh_put_u32_le
#define put_u64 Fssh_put_u64
#define pwcopy Fssh_pwcopy
#define qfileout Fssh_qfileout
#define read_mux Fssh_read_mux
#define read_passphrase Fssh_read_passphrase
#define recallocarray Fssh_recallocarray
-#define recip Fssh_recip
#define record_hostkey Fssh_record_hostkey
-#define reduce_add_sub Fssh_reduce_add_sub
#define refresh_progress_meter Fssh_refresh_progress_meter
#define replacearg Fssh_replacearg
#define revoke_blob Fssh_revoke_blob
#define revoked_blob_tree_RB_FIND Fssh_revoked_blob_tree_RB_FIND
#define revoked_blob_tree_RB_NEXT Fssh_revoked_blob_tree_RB_NEXT
#define revoked_blob_tree_RB_REMOVE Fssh_revoked_blob_tree_RB_REMOVE
#define revoked_certs_for_ca_key Fssh_revoked_certs_for_ca_key
#define revoked_certs_generate Fssh_revoked_certs_generate
#define revoked_serial_tree_RB_REMOVE Fssh_revoked_serial_tree_RB_REMOVE
#define rijndaelEncrypt Fssh_rijndaelEncrypt
#define rijndaelKeySetupEnc Fssh_rijndaelKeySetupEnc
#define rsa_hash_id_from_keyname Fssh_rsa_hash_id_from_keyname
#define rtrim Fssh_rtrim
#define safe_path Fssh_safe_path
#define safe_path_fd Fssh_safe_path_fd
#define sanitise_stdfd Fssh_sanitise_stdfd
#define scan_scaled Fssh_scan_scaled
#define seed_rng Fssh_seed_rng
#define send_error Fssh_send_error
#define set_log_handler Fssh_set_log_handler
#define set_nodelay Fssh_set_nodelay
#define set_nonblock Fssh_set_nonblock
#define set_rdomain Fssh_set_rdomain
#define set_reuseaddr Fssh_set_reuseaddr
#define set_sock_tos Fssh_set_sock_tos
#define sftp_realpath Fssh_sftp_realpath
#define shadow_pw Fssh_shadow_pw
#define sieve_large Fssh_sieve_large
#define sig_alarm Fssh_sig_alarm
#define sig_winch Fssh_sig_winch
#define skip_space Fssh_skip_space
#define snmprintf Fssh_snmprintf
#define sock_set_v6only Fssh_sock_set_v6only
#define speed_to_baud Fssh_speed_to_baud
+#define square Fssh_square
#define ssh_add_hostkey Fssh_ssh_add_hostkey
#define ssh_add_identity_constrained Fssh_ssh_add_identity_constrained
#define ssh_agent_bind_hostkey Fssh_ssh_agent_bind_hostkey
#define ssh_agent_has_key Fssh_ssh_agent_has_key
#define ssh_agent_sign Fssh_ssh_agent_sign
#define ssh_alloc_session_state Fssh_ssh_alloc_session_state
#define ssh_clear_newkeys Fssh_ssh_clear_newkeys
#define ssh_close_authentication_socket Fssh_ssh_close_authentication_socket
#define ssh_compatible_openssl Fssh_ssh_compatible_openssl
#define ssh_digest_alg_by_name Fssh_ssh_digest_alg_by_name
#define ssh_digest_alg_name Fssh_ssh_digest_alg_name
#define ssh_digest_blocksize Fssh_ssh_digest_blocksize
#define ssh_digest_buffer Fssh_ssh_digest_buffer
#define ssh_digest_bytes Fssh_ssh_digest_bytes
#define ssh_digest_copy_state Fssh_ssh_digest_copy_state
#define ssh_digest_final Fssh_ssh_digest_final
#define ssh_digest_free Fssh_ssh_digest_free
#define ssh_digest_memory Fssh_ssh_digest_memory
#define ssh_digest_start Fssh_ssh_digest_start
#define ssh_digest_update Fssh_ssh_digest_update
#define ssh_digest_update_buffer Fssh_ssh_digest_update_buffer
#define ssh_dispatch_init Fssh_ssh_dispatch_init
#define ssh_dispatch_range Fssh_ssh_dispatch_range
#define ssh_dispatch_run Fssh_ssh_dispatch_run
#define ssh_dispatch_run_fatal Fssh_ssh_dispatch_run_fatal
#define ssh_dispatch_set Fssh_ssh_dispatch_set
+#define ssh_dss_alloc Fssh_ssh_dss_alloc
+#define ssh_dss_cleanup Fssh_ssh_dss_cleanup
+#define ssh_dss_copy_public Fssh_ssh_dss_copy_public
+#define ssh_dss_deserialize_private Fssh_ssh_dss_deserialize_private
+#define ssh_dss_deserialize_public Fssh_ssh_dss_deserialize_public
+#define ssh_dss_equal Fssh_ssh_dss_equal
+#define ssh_dss_generate Fssh_ssh_dss_generate
+#define ssh_dss_serialize_private Fssh_ssh_dss_serialize_private
+#define ssh_dss_serialize_public Fssh_ssh_dss_serialize_public
#define ssh_dss_sign Fssh_ssh_dss_sign
+#define ssh_dss_size Fssh_ssh_dss_size
#define ssh_dss_verify Fssh_ssh_dss_verify
+#define ssh_ecdsa_cleanup Fssh_ssh_ecdsa_cleanup
+#define ssh_ecdsa_copy_public Fssh_ssh_ecdsa_copy_public
+#define ssh_ecdsa_deserialize_private Fssh_ssh_ecdsa_deserialize_private
+#define ssh_ecdsa_deserialize_public Fssh_ssh_ecdsa_deserialize_public
+#define ssh_ecdsa_equal Fssh_ssh_ecdsa_equal
+#define ssh_ecdsa_generate Fssh_ssh_ecdsa_generate
+#define ssh_ecdsa_serialize_private Fssh_ssh_ecdsa_serialize_private
+#define ssh_ecdsa_serialize_public Fssh_ssh_ecdsa_serialize_public
#define ssh_ecdsa_sign Fssh_ssh_ecdsa_sign
+#define ssh_ecdsa_size Fssh_ssh_ecdsa_size
+#define ssh_ecdsa_sk_cleanup Fssh_ssh_ecdsa_sk_cleanup
+#define ssh_ecdsa_sk_copy_public Fssh_ssh_ecdsa_sk_copy_public
+#define ssh_ecdsa_sk_deserialize_private Fssh_ssh_ecdsa_sk_deserialize_private
+#define ssh_ecdsa_sk_deserialize_public Fssh_ssh_ecdsa_sk_deserialize_public
+#define ssh_ecdsa_sk_equal Fssh_ssh_ecdsa_sk_equal
+#define ssh_ecdsa_sk_serialize_private Fssh_ssh_ecdsa_sk_serialize_private
+#define ssh_ecdsa_sk_serialize_public Fssh_ssh_ecdsa_sk_serialize_public
#define ssh_ecdsa_sk_verify Fssh_ssh_ecdsa_sk_verify
#define ssh_ecdsa_verify Fssh_ssh_ecdsa_verify
+#define ssh_ed25519_cleanup Fssh_ssh_ed25519_cleanup
+#define ssh_ed25519_copy_public Fssh_ssh_ed25519_copy_public
+#define ssh_ed25519_deserialize_private Fssh_ssh_ed25519_deserialize_private
+#define ssh_ed25519_deserialize_public Fssh_ssh_ed25519_deserialize_public
+#define ssh_ed25519_equal Fssh_ssh_ed25519_equal
+#define ssh_ed25519_generate Fssh_ssh_ed25519_generate
+#define ssh_ed25519_serialize_private Fssh_ssh_ed25519_serialize_private
+#define ssh_ed25519_serialize_public Fssh_ssh_ed25519_serialize_public
#define ssh_ed25519_sign Fssh_ssh_ed25519_sign
+#define ssh_ed25519_sk_cleanup Fssh_ssh_ed25519_sk_cleanup
+#define ssh_ed25519_sk_copy_public Fssh_ssh_ed25519_sk_copy_public
+#define ssh_ed25519_sk_deserialize_private Fssh_ssh_ed25519_sk_deserialize_private
+#define ssh_ed25519_sk_deserialize_public Fssh_ssh_ed25519_sk_deserialize_public
+#define ssh_ed25519_sk_equal Fssh_ssh_ed25519_sk_equal
+#define ssh_ed25519_sk_serialize_private Fssh_ssh_ed25519_sk_serialize_private
+#define ssh_ed25519_sk_serialize_public Fssh_ssh_ed25519_sk_serialize_public
#define ssh_ed25519_sk_verify Fssh_ssh_ed25519_sk_verify
#define ssh_ed25519_verify Fssh_ssh_ed25519_verify
#define ssh_err Fssh_ssh_err
#define ssh_fetch_identitylist Fssh_ssh_fetch_identitylist
#define ssh_free Fssh_ssh_free
#define ssh_free_identitylist Fssh_ssh_free_identitylist
#define ssh_gai_strerror Fssh_ssh_gai_strerror
#define ssh_get_app_data Fssh_ssh_get_app_data
#define ssh_get_authentication_socket Fssh_ssh_get_authentication_socket
#define ssh_get_authentication_socket_path Fssh_ssh_get_authentication_socket_path
#define ssh_get_progname Fssh_ssh_get_progname
#define ssh_hmac_bytes Fssh_ssh_hmac_bytes
#define ssh_hmac_final Fssh_ssh_hmac_final
#define ssh_hmac_free Fssh_ssh_hmac_free
#define ssh_hmac_init Fssh_ssh_hmac_init
#define ssh_hmac_start Fssh_ssh_hmac_start
#define ssh_hmac_update Fssh_ssh_hmac_update
#define ssh_hmac_update_buffer Fssh_ssh_hmac_update_buffer
#define ssh_init Fssh_ssh_init
#define ssh_input_append Fssh_ssh_input_append
#define ssh_input_space Fssh_ssh_input_space
#define ssh_krl_check_key Fssh_ssh_krl_check_key
#define ssh_krl_file_contains_key Fssh_ssh_krl_file_contains_key
#define ssh_krl_free Fssh_ssh_krl_free
#define ssh_krl_from_blob Fssh_ssh_krl_from_blob
#define ssh_krl_init Fssh_ssh_krl_init
#define ssh_krl_revoke_cert_by_key_id Fssh_ssh_krl_revoke_cert_by_key_id
#define ssh_krl_revoke_cert_by_serial Fssh_ssh_krl_revoke_cert_by_serial
#define ssh_krl_revoke_cert_by_serial_range Fssh_ssh_krl_revoke_cert_by_serial_range
#define ssh_krl_revoke_key Fssh_ssh_krl_revoke_key
#define ssh_krl_revoke_key_explicit Fssh_ssh_krl_revoke_key_explicit
#define ssh_krl_revoke_key_sha1 Fssh_ssh_krl_revoke_key_sha1
#define ssh_krl_revoke_key_sha256 Fssh_ssh_krl_revoke_key_sha256
#define ssh_krl_set_comment Fssh_ssh_krl_set_comment
#define ssh_krl_set_version Fssh_ssh_krl_set_version
#define ssh_krl_to_blob Fssh_ssh_krl_to_blob
#define ssh_libcrypto_init Fssh_ssh_libcrypto_init
#define ssh_local_ipaddr Fssh_ssh_local_ipaddr
#define ssh_local_port Fssh_ssh_local_port
#define ssh_lock_agent Fssh_ssh_lock_agent
#define ssh_msg_recv Fssh_ssh_msg_recv
#define ssh_msg_send Fssh_ssh_msg_send
#define ssh_output_consume Fssh_ssh_output_consume
#define ssh_output_ptr Fssh_ssh_output_ptr
#define ssh_output_space Fssh_ssh_output_space
#define ssh_packet_check_rekey Fssh_ssh_packet_check_rekey
#define ssh_packet_clear_keys Fssh_ssh_packet_clear_keys
#define ssh_packet_close Fssh_ssh_packet_close
#define ssh_packet_close_internal Fssh_ssh_packet_close_internal
#define ssh_packet_connection_af Fssh_ssh_packet_connection_af
#define ssh_packet_connection_is_on_socket Fssh_ssh_packet_connection_is_on_socket
#define ssh_packet_disconnect Fssh_ssh_packet_disconnect
#define ssh_packet_enable_delayed_compress Fssh_ssh_packet_enable_delayed_compress
#define ssh_packet_get_bytes Fssh_ssh_packet_get_bytes
#define ssh_packet_get_connection_in Fssh_ssh_packet_get_connection_in
#define ssh_packet_get_connection_out Fssh_ssh_packet_get_connection_out
#define ssh_packet_get_input Fssh_ssh_packet_get_input
#define ssh_packet_get_maxsize Fssh_ssh_packet_get_maxsize
#define ssh_packet_get_mux Fssh_ssh_packet_get_mux
#define ssh_packet_get_output Fssh_ssh_packet_get_output
#define ssh_packet_get_protocol_flags Fssh_ssh_packet_get_protocol_flags
#define ssh_packet_get_rekey_timeout Fssh_ssh_packet_get_rekey_timeout
#define ssh_packet_get_state Fssh_ssh_packet_get_state
#define ssh_packet_have_data_to_write Fssh_ssh_packet_have_data_to_write
#define ssh_packet_inc_alive_timeouts Fssh_ssh_packet_inc_alive_timeouts
#define ssh_packet_is_interactive Fssh_ssh_packet_is_interactive
#define ssh_packet_is_rekeying Fssh_ssh_packet_is_rekeying
#define ssh_packet_log_type Fssh_ssh_packet_log_type
#define ssh_packet_need_rekeying Fssh_ssh_packet_need_rekeying
#define ssh_packet_next Fssh_ssh_packet_next
#define ssh_packet_not_very_much_data_to_write Fssh_ssh_packet_not_very_much_data_to_write
#define ssh_packet_payload Fssh_ssh_packet_payload
#define ssh_packet_process_incoming Fssh_ssh_packet_process_incoming
#define ssh_packet_process_read Fssh_ssh_packet_process_read
#define ssh_packet_put Fssh_ssh_packet_put
#define ssh_packet_rdomain_in Fssh_ssh_packet_rdomain_in
#define ssh_packet_read Fssh_ssh_packet_read
#define ssh_packet_read_expect Fssh_ssh_packet_read_expect
#define ssh_packet_read_poll2 Fssh_ssh_packet_read_poll2
#define ssh_packet_read_poll_seqnr Fssh_ssh_packet_read_poll_seqnr
#define ssh_packet_read_seqnr Fssh_ssh_packet_read_seqnr
#define ssh_packet_remaining Fssh_ssh_packet_remaining
#define ssh_packet_send2 Fssh_ssh_packet_send2
#define ssh_packet_send2_wrapped Fssh_ssh_packet_send2_wrapped
#define ssh_packet_send_debug Fssh_ssh_packet_send_debug
#define ssh_packet_set_alive_timeouts Fssh_ssh_packet_set_alive_timeouts
#define ssh_packet_set_authenticated Fssh_ssh_packet_set_authenticated
#define ssh_packet_set_connection Fssh_ssh_packet_set_connection
#define ssh_packet_set_input_hook Fssh_ssh_packet_set_input_hook
#define ssh_packet_set_interactive Fssh_ssh_packet_set_interactive
#define ssh_packet_set_log_preamble Fssh_ssh_packet_set_log_preamble
#define ssh_packet_set_maxsize Fssh_ssh_packet_set_maxsize
#define ssh_packet_set_mux Fssh_ssh_packet_set_mux
#define ssh_packet_set_nonblocking Fssh_ssh_packet_set_nonblocking
#define ssh_packet_set_postauth Fssh_ssh_packet_set_postauth
#define ssh_packet_set_protocol_flags Fssh_ssh_packet_set_protocol_flags
#define ssh_packet_set_rekey_limits Fssh_ssh_packet_set_rekey_limits
#define ssh_packet_set_server Fssh_ssh_packet_set_server
#define ssh_packet_set_state Fssh_ssh_packet_set_state
#define ssh_packet_set_timeout Fssh_ssh_packet_set_timeout
#define ssh_packet_set_tos Fssh_ssh_packet_set_tos
#define ssh_packet_start_discard Fssh_ssh_packet_start_discard
#define ssh_packet_stop_discard Fssh_ssh_packet_stop_discard
#define ssh_packet_write_poll Fssh_ssh_packet_write_poll
#define ssh_packet_write_wait Fssh_ssh_packet_write_wait
#define ssh_remote_ipaddr Fssh_ssh_remote_ipaddr
#define ssh_remote_port Fssh_ssh_remote_port
#define ssh_remove_all_identities Fssh_ssh_remove_all_identities
#define ssh_remove_identity Fssh_ssh_remove_identity
#define ssh_request_reply Fssh_ssh_request_reply
#define ssh_request_reply_decode Fssh_ssh_request_reply_decode
+#define ssh_rsa_alloc Fssh_ssh_rsa_alloc
+#define ssh_rsa_cleanup Fssh_ssh_rsa_cleanup
#define ssh_rsa_complete_crt_parameters Fssh_ssh_rsa_complete_crt_parameters
+#define ssh_rsa_copy_public Fssh_ssh_rsa_copy_public
+#define ssh_rsa_deserialize_private Fssh_ssh_rsa_deserialize_private
+#define ssh_rsa_deserialize_public Fssh_ssh_rsa_deserialize_public
+#define ssh_rsa_equal Fssh_ssh_rsa_equal
+#define ssh_rsa_generate Fssh_ssh_rsa_generate
+#define ssh_rsa_serialize_private Fssh_ssh_rsa_serialize_private
+#define ssh_rsa_serialize_public Fssh_ssh_rsa_serialize_public
#define ssh_rsa_sign Fssh_ssh_rsa_sign
+#define ssh_rsa_size Fssh_ssh_rsa_size
#define ssh_rsa_verify Fssh_ssh_rsa_verify
#define ssh_set_app_data Fssh_ssh_set_app_data
#define ssh_set_newkeys Fssh_ssh_set_newkeys
#define ssh_set_verify_host_key_callback Fssh_ssh_set_verify_host_key_callback
#define ssh_signal Fssh_ssh_signal
#define ssh_tty_make_modes Fssh_ssh_tty_make_modes
#define ssh_tty_parse_modes Fssh_ssh_tty_parse_modes
#define ssh_update_card Fssh_ssh_update_card
#define sshbuf_alloc Fssh_sshbuf_alloc
#define sshbuf_allocate Fssh_sshbuf_allocate
#define sshbuf_avail Fssh_sshbuf_avail
#define sshbuf_b64tod Fssh_sshbuf_b64tod
#define sshbuf_check_reserve Fssh_sshbuf_check_reserve
#define sshbuf_cmp Fssh_sshbuf_cmp
#define sshbuf_consume Fssh_sshbuf_consume
#define sshbuf_consume_end Fssh_sshbuf_consume_end
#define sshbuf_dtob16 Fssh_sshbuf_dtob16
#define sshbuf_dtob64 Fssh_sshbuf_dtob64
#define sshbuf_dtob64_string Fssh_sshbuf_dtob64_string
#define sshbuf_dtourlb64 Fssh_sshbuf_dtourlb64
#define sshbuf_dump Fssh_sshbuf_dump
#define sshbuf_dump_data Fssh_sshbuf_dump_data
#define sshbuf_dup_string Fssh_sshbuf_dup_string
#define sshbuf_find Fssh_sshbuf_find
#define sshbuf_free Fssh_sshbuf_free
#define sshbuf_from Fssh_sshbuf_from
#define sshbuf_fromb Fssh_sshbuf_fromb
#define sshbuf_froms Fssh_sshbuf_froms
#define sshbuf_get Fssh_sshbuf_get
#define sshbuf_get_bignum2 Fssh_sshbuf_get_bignum2
#define sshbuf_get_bignum2_bytes_direct Fssh_sshbuf_get_bignum2_bytes_direct
#define sshbuf_get_cstring Fssh_sshbuf_get_cstring
#define sshbuf_get_ec Fssh_sshbuf_get_ec
#define sshbuf_get_eckey Fssh_sshbuf_get_eckey
#define sshbuf_get_string Fssh_sshbuf_get_string
#define sshbuf_get_string_direct Fssh_sshbuf_get_string_direct
#define sshbuf_get_stringb Fssh_sshbuf_get_stringb
#define sshbuf_get_u16 Fssh_sshbuf_get_u16
#define sshbuf_get_u32 Fssh_sshbuf_get_u32
#define sshbuf_get_u64 Fssh_sshbuf_get_u64
#define sshbuf_get_u8 Fssh_sshbuf_get_u8
#define sshbuf_len Fssh_sshbuf_len
#define sshbuf_load_fd Fssh_sshbuf_load_fd
#define sshbuf_load_file Fssh_sshbuf_load_file
#define sshbuf_max_size Fssh_sshbuf_max_size
#define sshbuf_maybe_pack Fssh_sshbuf_maybe_pack
#define sshbuf_mutable_ptr Fssh_sshbuf_mutable_ptr
#define sshbuf_new Fssh_sshbuf_new
#define sshbuf_parent Fssh_sshbuf_parent
#define sshbuf_peek_string_direct Fssh_sshbuf_peek_string_direct
#define sshbuf_peek_u16 Fssh_sshbuf_peek_u16
#define sshbuf_peek_u32 Fssh_sshbuf_peek_u32
#define sshbuf_peek_u64 Fssh_sshbuf_peek_u64
#define sshbuf_peek_u8 Fssh_sshbuf_peek_u8
#define sshbuf_poke Fssh_sshbuf_poke
#define sshbuf_poke_u16 Fssh_sshbuf_poke_u16
#define sshbuf_poke_u32 Fssh_sshbuf_poke_u32
#define sshbuf_poke_u64 Fssh_sshbuf_poke_u64
#define sshbuf_poke_u8 Fssh_sshbuf_poke_u8
#define sshbuf_ptr Fssh_sshbuf_ptr
#define sshbuf_put Fssh_sshbuf_put
#define sshbuf_put_bignum2 Fssh_sshbuf_put_bignum2
#define sshbuf_put_bignum2_bytes Fssh_sshbuf_put_bignum2_bytes
#define sshbuf_put_cstring Fssh_sshbuf_put_cstring
#define sshbuf_put_ec Fssh_sshbuf_put_ec
#define sshbuf_put_eckey Fssh_sshbuf_put_eckey
#define sshbuf_put_string Fssh_sshbuf_put_string
#define sshbuf_put_stringb Fssh_sshbuf_put_stringb
#define sshbuf_put_u16 Fssh_sshbuf_put_u16
#define sshbuf_put_u32 Fssh_sshbuf_put_u32
#define sshbuf_put_u64 Fssh_sshbuf_put_u64
#define sshbuf_put_u8 Fssh_sshbuf_put_u8
#define sshbuf_putb Fssh_sshbuf_putb
#define sshbuf_putf Fssh_sshbuf_putf
#define sshbuf_putfv Fssh_sshbuf_putfv
#define sshbuf_read Fssh_sshbuf_read
#define sshbuf_refcount Fssh_sshbuf_refcount
#define sshbuf_reserve Fssh_sshbuf_reserve
#define sshbuf_reset Fssh_sshbuf_reset
#define sshbuf_set_max_size Fssh_sshbuf_set_max_size
#define sshbuf_set_parent Fssh_sshbuf_set_parent
#define sshbuf_write_file Fssh_sshbuf_write_file
#define sshfatal Fssh_sshfatal
#define sshkey_advance_past_options Fssh_sshkey_advance_past_options
#define sshkey_alg_list Fssh_sshkey_alg_list
#define sshkey_cert_check_authority Fssh_sshkey_cert_check_authority
#define sshkey_cert_check_authority_now Fssh_sshkey_cert_check_authority_now
#define sshkey_cert_check_host Fssh_sshkey_cert_check_host
#define sshkey_cert_copy Fssh_sshkey_cert_copy
#define sshkey_cert_type Fssh_sshkey_cert_type
#define sshkey_certify Fssh_sshkey_certify
#define sshkey_certify_custom Fssh_sshkey_certify_custom
#define sshkey_check_cert_sigtype Fssh_sshkey_check_cert_sigtype
#define sshkey_check_revoked Fssh_sshkey_check_revoked
#define sshkey_check_rsa_length Fssh_sshkey_check_rsa_length
#define sshkey_check_sigtype Fssh_sshkey_check_sigtype
+#define sshkey_copy_public_sk Fssh_sshkey_copy_public_sk
#define sshkey_curve_name_to_nid Fssh_sshkey_curve_name_to_nid
#define sshkey_curve_nid_to_bits Fssh_sshkey_curve_nid_to_bits
#define sshkey_curve_nid_to_name Fssh_sshkey_curve_nid_to_name
+#define sshkey_deserialize_sk Fssh_sshkey_deserialize_sk
#define sshkey_drop_cert Fssh_sshkey_drop_cert
#define sshkey_dump_ec_key Fssh_sshkey_dump_ec_key
#define sshkey_dump_ec_point Fssh_sshkey_dump_ec_point
#define sshkey_ec_nid_to_hash_alg Fssh_sshkey_ec_nid_to_hash_alg
#define sshkey_ec_validate_private Fssh_sshkey_ec_validate_private
#define sshkey_ec_validate_public Fssh_sshkey_ec_validate_public
#define sshkey_ecdsa_bits_to_nid Fssh_sshkey_ecdsa_bits_to_nid
#define sshkey_ecdsa_key_to_nid Fssh_sshkey_ecdsa_key_to_nid
#define sshkey_ecdsa_nid_from_name Fssh_sshkey_ecdsa_nid_from_name
#define sshkey_enable_maxsign Fssh_sshkey_enable_maxsign
#define sshkey_equal Fssh_sshkey_equal
#define sshkey_equal_public Fssh_sshkey_equal_public
#define sshkey_fingerprint Fssh_sshkey_fingerprint
#define sshkey_fingerprint_raw Fssh_sshkey_fingerprint_raw
#define sshkey_format_cert_validity Fssh_sshkey_format_cert_validity
#define sshkey_format_text Fssh_sshkey_format_text
#define sshkey_free Fssh_sshkey_free
+#define sshkey_free_contents Fssh_sshkey_free_contents
#define sshkey_from_blob Fssh_sshkey_from_blob
#define sshkey_from_blob_internal Fssh_sshkey_from_blob_internal
#define sshkey_from_private Fssh_sshkey_from_private
#define sshkey_fromb Fssh_sshkey_fromb
#define sshkey_froms Fssh_sshkey_froms
#define sshkey_generate Fssh_sshkey_generate
#define sshkey_get_sigtype Fssh_sshkey_get_sigtype
+#define sshkey_impl_from_type Fssh_sshkey_impl_from_type
#define sshkey_in_file Fssh_sshkey_in_file
#define sshkey_is_cert Fssh_sshkey_is_cert
#define sshkey_is_shielded Fssh_sshkey_is_shielded
#define sshkey_is_sk Fssh_sshkey_is_sk
#define sshkey_load_cert Fssh_sshkey_load_cert
#define sshkey_load_private Fssh_sshkey_load_private
#define sshkey_load_private_cert Fssh_sshkey_load_private_cert
#define sshkey_load_private_type Fssh_sshkey_load_private_type
#define sshkey_load_private_type_fd Fssh_sshkey_load_private_type_fd
#define sshkey_load_public Fssh_sshkey_load_public
#define sshkey_match_keyname_to_sigalgs Fssh_sshkey_match_keyname_to_sigalgs
#define sshkey_names_valid2 Fssh_sshkey_names_valid2
#define sshkey_new Fssh_sshkey_new
#define sshkey_parse_private2 Fssh_sshkey_parse_private2
#define sshkey_parse_private_fileblob Fssh_sshkey_parse_private_fileblob
#define sshkey_parse_private_fileblob_type Fssh_sshkey_parse_private_fileblob_type
#define sshkey_parse_pubkey_from_private_fileblob_type Fssh_sshkey_parse_pubkey_from_private_fileblob_type
#define sshkey_perm_ok Fssh_sshkey_perm_ok
#define sshkey_plain_to_blob Fssh_sshkey_plain_to_blob
#define sshkey_private_deserialize Fssh_sshkey_private_deserialize
+#define sshkey_private_deserialize_sk Fssh_sshkey_private_deserialize_sk
#define sshkey_private_serialize Fssh_sshkey_private_serialize
#define sshkey_private_serialize_maxsign Fssh_sshkey_private_serialize_maxsign
#define sshkey_private_serialize_opt Fssh_sshkey_private_serialize_opt
#define sshkey_private_to_blob2 Fssh_sshkey_private_to_blob2
#define sshkey_private_to_fileblob Fssh_sshkey_private_to_fileblob
#define sshkey_putb Fssh_sshkey_putb
#define sshkey_putb_plain Fssh_sshkey_putb_plain
#define sshkey_puts Fssh_sshkey_puts
#define sshkey_puts_opts Fssh_sshkey_puts_opts
#define sshkey_read Fssh_sshkey_read
#define sshkey_save_private Fssh_sshkey_save_private
#define sshkey_save_public Fssh_sshkey_save_public
+#define sshkey_serialize_private_sk Fssh_sshkey_serialize_private_sk
+#define sshkey_serialize_sk Fssh_sshkey_serialize_sk
#define sshkey_set_filename Fssh_sshkey_set_filename
#define sshkey_shield_private Fssh_sshkey_shield_private
#define sshkey_sig_details_free Fssh_sshkey_sig_details_free
#define sshkey_sigalg_by_name Fssh_sshkey_sigalg_by_name
#define sshkey_sign Fssh_sshkey_sign
#define sshkey_signatures_left Fssh_sshkey_signatures_left
#define sshkey_size Fssh_sshkey_size
+#define sshkey_sk_cleanup Fssh_sshkey_sk_cleanup
+#define sshkey_sk_fields_equal Fssh_sshkey_sk_fields_equal
#define sshkey_ssh_name Fssh_sshkey_ssh_name
#define sshkey_ssh_name_plain Fssh_sshkey_ssh_name_plain
#define sshkey_to_base64 Fssh_sshkey_to_base64
#define sshkey_to_blob Fssh_sshkey_to_blob
#define sshkey_to_certified Fssh_sshkey_to_certified
#define sshkey_try_load_public Fssh_sshkey_try_load_public
#define sshkey_type Fssh_sshkey_type
#define sshkey_type_from_name Fssh_sshkey_type_from_name
#define sshkey_type_is_cert Fssh_sshkey_type_is_cert
#define sshkey_type_plain Fssh_sshkey_type_plain
#define sshkey_unshield_private Fssh_sshkey_unshield_private
#define sshkey_verify Fssh_sshkey_verify
#define sshkey_write Fssh_sshkey_write
#define sshlog Fssh_sshlog
#define sshlogdie Fssh_sshlogdie
#define sshlogdirect Fssh_sshlogdirect
#define sshlogv Fssh_sshlogv
#define sshpkt_add_padding Fssh_sshpkt_add_padding
#define sshpkt_disconnect Fssh_sshpkt_disconnect
#define sshpkt_fatal Fssh_sshpkt_fatal
#define sshpkt_fmt_connection_id Fssh_sshpkt_fmt_connection_id
#define sshpkt_get Fssh_sshpkt_get
#define sshpkt_get_bignum2 Fssh_sshpkt_get_bignum2
#define sshpkt_get_cstring Fssh_sshpkt_get_cstring
#define sshpkt_get_ec Fssh_sshpkt_get_ec
#define sshpkt_get_end Fssh_sshpkt_get_end
#define sshpkt_get_string Fssh_sshpkt_get_string
#define sshpkt_get_string_direct Fssh_sshpkt_get_string_direct
#define sshpkt_get_u32 Fssh_sshpkt_get_u32
#define sshpkt_get_u64 Fssh_sshpkt_get_u64
#define sshpkt_get_u8 Fssh_sshpkt_get_u8
#define sshpkt_getb_froms Fssh_sshpkt_getb_froms
#define sshpkt_msg_ignore Fssh_sshpkt_msg_ignore
#define sshpkt_peek_string_direct Fssh_sshpkt_peek_string_direct
#define sshpkt_ptr Fssh_sshpkt_ptr
#define sshpkt_put Fssh_sshpkt_put
#define sshpkt_put_bignum2 Fssh_sshpkt_put_bignum2
#define sshpkt_put_cstring Fssh_sshpkt_put_cstring
#define sshpkt_put_ec Fssh_sshpkt_put_ec
#define sshpkt_put_string Fssh_sshpkt_put_string
#define sshpkt_put_stringb Fssh_sshpkt_put_stringb
#define sshpkt_put_u32 Fssh_sshpkt_put_u32
#define sshpkt_put_u64 Fssh_sshpkt_put_u64
#define sshpkt_put_u8 Fssh_sshpkt_put_u8
#define sshpkt_putb Fssh_sshpkt_putb
#define sshpkt_send Fssh_sshpkt_send
#define sshpkt_start Fssh_sshpkt_start
#define sshpkt_vfatal Fssh_sshpkt_vfatal
#define sshsigdie Fssh_sshsigdie
#define sshsk_enroll Fssh_sshsk_enroll
#define sshsk_free_resident_keys Fssh_sshsk_free_resident_keys
#define sshsk_load_resident Fssh_sshsk_load_resident
#define sshsk_sign Fssh_sshsk_sign
#define start_compression_in Fssh_start_compression_in
#define start_compression_out Fssh_start_compression_out
#define start_progress_meter Fssh_start_progress_meter
#define stdfd_devnull Fssh_stdfd_devnull
#define stop_progress_meter Fssh_stop_progress_meter
#define stravis Fssh_stravis
#define strdelim Fssh_strdelim
#define strdelim_internal Fssh_strdelim_internal
#define strdelimw Fssh_strdelimw
#define strnvis Fssh_strnvis
#define strvis Fssh_strvis
#define strvisx Fssh_strvisx
#define subprocess Fssh_subprocess
#define sys_tun_open Fssh_sys_tun_open
#define tilde_expand Fssh_tilde_expand
#define tilde_expand_filename Fssh_tilde_expand_filename
#define timeout_connect Fssh_timeout_connect
#define to_blob Fssh_to_blob
#define to_blob_buf Fssh_to_blob_buf
#define tohex Fssh_tohex
#define tun_open Fssh_tun_open
#define umac128_delete Fssh_umac128_delete
#define umac128_final Fssh_umac128_final
#define umac128_new Fssh_umac128_new
#define umac128_update Fssh_umac128_update
#define umac_delete Fssh_umac_delete
#define umac_final Fssh_umac_final
#define umac_new Fssh_umac_new
#define umac_update Fssh_umac_update
#define uncompress_buffer Fssh_uncompress_buffer
#define unix_listener Fssh_unix_listener
#define unset_nonblock Fssh_unset_nonblock
#define urldecode Fssh_urldecode
#define valid_domain Fssh_valid_domain
#define valid_env_name Fssh_valid_env_name
#define vasnmprintf Fssh_vasnmprintf
#define vdollar_percent_expand Fssh_vdollar_percent_expand
#define verify_host_key_dns Fssh_verify_host_key_dns
#define vfmprintf Fssh_vfmprintf
#define vis Fssh_vis
#define waitfd Fssh_waitfd
#define waitrfd Fssh_waitrfd
#define webauthn_check_prepare_hash Fssh_webauthn_check_prepare_hash
#define write_host_entry Fssh_write_host_entry
#define x11_connect_display Fssh_x11_connect_display
#define x11_create_display_inet Fssh_x11_create_display_inet
#define x11_request_forwarding_with_spoofing Fssh_x11_request_forwarding_with_spoofing
#define xasprintf Fssh_xasprintf
#define xcalloc Fssh_xcalloc
#define xcrypt Fssh_xcrypt
#define xextendf Fssh_xextendf
#define xmalloc Fssh_xmalloc
#define xreallocarray Fssh_xreallocarray
#define xrecallocarray Fssh_xrecallocarray
#define xstrdup Fssh_xstrdup
#define xvasprintf Fssh_xvasprintf
diff --git a/crypto/openssh/sshbuf.c b/crypto/openssh/sshbuf.c
index d5757b7264ed..d7f4e4ab6504 100644
--- a/crypto/openssh/sshbuf.c
+++ b/crypto/openssh/sshbuf.c
@@ -1,404 +1,427 @@
-/* $OpenBSD: sshbuf.c,v 1.18 2022/05/25 06:03:44 djm Exp $ */
+/* $OpenBSD: sshbuf.c,v 1.19 2022/12/02 04:40:27 djm Exp $ */
/*
* Copyright (c) 2011 Damien Miller
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#define SSHBUF_INTERNAL
#include "includes.h"
#include <sys/types.h>
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "ssherr.h"
+#define SSHBUF_INTERNAL
#include "sshbuf.h"
#include "misc.h"
+#ifdef SSHBUF_DEBUG
+# define SSHBUF_TELL(what) do { \
+ printf("%s:%d %s: %s size %zu alloc %zu off %zu max %zu\n", \
+ __FILE__, __LINE__, __func__, what, \
+ buf->size, buf->alloc, buf->off, buf->max_size); \
+ fflush(stdout); \
+ } while (0)
+#else
+# define SSHBUF_TELL(what)
+#endif
+
+struct sshbuf {
+ u_char *d; /* Data */
+ const u_char *cd; /* Const data */
+ size_t off; /* First available byte is buf->d + buf->off */
+ size_t size; /* Last byte is buf->d + buf->size - 1 */
+ size_t max_size; /* Maximum size of buffer */
+ size_t alloc; /* Total bytes allocated to buf->d */
+ int readonly; /* Refers to external, const data */
+ u_int refcount; /* Tracks self and number of child buffers */
+ struct sshbuf *parent; /* If child, pointer to parent */
+};
+
static inline int
sshbuf_check_sanity(const struct sshbuf *buf)
{
SSHBUF_TELL("sanity");
if (__predict_false(buf == NULL ||
(!buf->readonly && buf->d != buf->cd) ||
buf->refcount < 1 || buf->refcount > SSHBUF_REFS_MAX ||
buf->cd == NULL ||
buf->max_size > SSHBUF_SIZE_MAX ||
buf->alloc > buf->max_size ||
buf->size > buf->alloc ||
buf->off > buf->size)) {
/* Do not try to recover from corrupted buffer internals */
SSHBUF_DBG(("SSH_ERR_INTERNAL_ERROR"));
ssh_signal(SIGSEGV, SIG_DFL);
raise(SIGSEGV);
return SSH_ERR_INTERNAL_ERROR;
}
return 0;
}
static void
sshbuf_maybe_pack(struct sshbuf *buf, int force)
{
SSHBUF_DBG(("force %d", force));
SSHBUF_TELL("pre-pack");
if (buf->off == 0 || buf->readonly || buf->refcount > 1)
return;
if (force ||
(buf->off >= SSHBUF_PACK_MIN && buf->off >= buf->size / 2)) {
memmove(buf->d, buf->d + buf->off, buf->size - buf->off);
buf->size -= buf->off;
buf->off = 0;
SSHBUF_TELL("packed");
}
}
struct sshbuf *
sshbuf_new(void)
{
struct sshbuf *ret;
if ((ret = calloc(sizeof(*ret), 1)) == NULL)
return NULL;
ret->alloc = SSHBUF_SIZE_INIT;
ret->max_size = SSHBUF_SIZE_MAX;
ret->readonly = 0;
ret->refcount = 1;
ret->parent = NULL;
if ((ret->cd = ret->d = calloc(1, ret->alloc)) == NULL) {
free(ret);
return NULL;
}
return ret;
}
struct sshbuf *
sshbuf_from(const void *blob, size_t len)
{
struct sshbuf *ret;
if (blob == NULL || len > SSHBUF_SIZE_MAX ||
(ret = calloc(sizeof(*ret), 1)) == NULL)
return NULL;
ret->alloc = ret->size = ret->max_size = len;
ret->readonly = 1;
ret->refcount = 1;
ret->parent = NULL;
ret->cd = blob;
ret->d = NULL;
return ret;
}
int
sshbuf_set_parent(struct sshbuf *child, struct sshbuf *parent)
{
int r;
if ((r = sshbuf_check_sanity(child)) != 0 ||
(r = sshbuf_check_sanity(parent)) != 0)
return r;
if (child->parent != NULL && child->parent != parent)
return SSH_ERR_INTERNAL_ERROR;
child->parent = parent;
child->parent->refcount++;
return 0;
}
struct sshbuf *
sshbuf_fromb(struct sshbuf *buf)
{
struct sshbuf *ret;
if (sshbuf_check_sanity(buf) != 0)
return NULL;
if ((ret = sshbuf_from(sshbuf_ptr(buf), sshbuf_len(buf))) == NULL)
return NULL;
if (sshbuf_set_parent(ret, buf) != 0) {
sshbuf_free(ret);
return NULL;
}
return ret;
}
void
sshbuf_free(struct sshbuf *buf)
{
if (buf == NULL)
return;
/*
* The following will leak on insane buffers, but this is the safest
* course of action - an invalid pointer or already-freed pointer may
* have been passed to us and continuing to scribble over memory would
* be bad.
*/
if (sshbuf_check_sanity(buf) != 0)
return;
/*
* If we are a parent with still-extant children, then don't free just
* yet. The last child's call to sshbuf_free should decrement our
* refcount to 0 and trigger the actual free.
*/
buf->refcount--;
if (buf->refcount > 0)
return;
/*
* If we are a child, the free our parent to decrement its reference
* count and possibly free it.
*/
sshbuf_free(buf->parent);
buf->parent = NULL;
if (!buf->readonly) {
explicit_bzero(buf->d, buf->alloc);
free(buf->d);
}
freezero(buf, sizeof(*buf));
}
void
sshbuf_reset(struct sshbuf *buf)
{
u_char *d;
if (buf->readonly || buf->refcount > 1) {
/* Nonsensical. Just make buffer appear empty */
buf->off = buf->size;
return;
}
if (sshbuf_check_sanity(buf) != 0)
return;
buf->off = buf->size = 0;
if (buf->alloc != SSHBUF_SIZE_INIT) {
if ((d = recallocarray(buf->d, buf->alloc, SSHBUF_SIZE_INIT,
1)) != NULL) {
buf->cd = buf->d = d;
buf->alloc = SSHBUF_SIZE_INIT;
}
}
explicit_bzero(buf->d, buf->alloc);
}
size_t
sshbuf_max_size(const struct sshbuf *buf)
{
return buf->max_size;
}
size_t
sshbuf_alloc(const struct sshbuf *buf)
{
return buf->alloc;
}
const struct sshbuf *
sshbuf_parent(const struct sshbuf *buf)
{
return buf->parent;
}
u_int
sshbuf_refcount(const struct sshbuf *buf)
{
return buf->refcount;
}
int
sshbuf_set_max_size(struct sshbuf *buf, size_t max_size)
{
size_t rlen;
u_char *dp;
int r;
SSHBUF_DBG(("set max buf = %p len = %zu", buf, max_size));
if ((r = sshbuf_check_sanity(buf)) != 0)
return r;
if (max_size == buf->max_size)
return 0;
if (buf->readonly || buf->refcount > 1)
return SSH_ERR_BUFFER_READ_ONLY;
if (max_size > SSHBUF_SIZE_MAX)
return SSH_ERR_NO_BUFFER_SPACE;
/* pack and realloc if necessary */
sshbuf_maybe_pack(buf, max_size < buf->size);
if (max_size < buf->alloc && max_size > buf->size) {
if (buf->size < SSHBUF_SIZE_INIT)
rlen = SSHBUF_SIZE_INIT;
else
rlen = ROUNDUP(buf->size, SSHBUF_SIZE_INC);
if (rlen > max_size)
rlen = max_size;
SSHBUF_DBG(("new alloc = %zu", rlen));
if ((dp = recallocarray(buf->d, buf->alloc, rlen, 1)) == NULL)
return SSH_ERR_ALLOC_FAIL;
buf->cd = buf->d = dp;
buf->alloc = rlen;
}
SSHBUF_TELL("new-max");
if (max_size < buf->alloc)
return SSH_ERR_NO_BUFFER_SPACE;
buf->max_size = max_size;
return 0;
}
size_t
sshbuf_len(const struct sshbuf *buf)
{
if (sshbuf_check_sanity(buf) != 0)
return 0;
return buf->size - buf->off;
}
size_t
sshbuf_avail(const struct sshbuf *buf)
{
if (sshbuf_check_sanity(buf) != 0 || buf->readonly || buf->refcount > 1)
return 0;
return buf->max_size - (buf->size - buf->off);
}
const u_char *
sshbuf_ptr(const struct sshbuf *buf)
{
if (sshbuf_check_sanity(buf) != 0)
return NULL;
return buf->cd + buf->off;
}
u_char *
sshbuf_mutable_ptr(const struct sshbuf *buf)
{
if (sshbuf_check_sanity(buf) != 0 || buf->readonly || buf->refcount > 1)
return NULL;
return buf->d + buf->off;
}
int
sshbuf_check_reserve(const struct sshbuf *buf, size_t len)
{
int r;
if ((r = sshbuf_check_sanity(buf)) != 0)
return r;
if (buf->readonly || buf->refcount > 1)
return SSH_ERR_BUFFER_READ_ONLY;
SSHBUF_TELL("check");
/* Check that len is reasonable and that max_size + available < len */
if (len > buf->max_size || buf->max_size - len < buf->size - buf->off)
return SSH_ERR_NO_BUFFER_SPACE;
return 0;
}
int
sshbuf_allocate(struct sshbuf *buf, size_t len)
{
size_t rlen, need;
u_char *dp;
int r;
SSHBUF_DBG(("allocate buf = %p len = %zu", buf, len));
if ((r = sshbuf_check_reserve(buf, len)) != 0)
return r;
/*
* If the requested allocation appended would push us past max_size
* then pack the buffer, zeroing buf->off.
*/
sshbuf_maybe_pack(buf, buf->size + len > buf->max_size);
SSHBUF_TELL("allocate");
if (len + buf->size <= buf->alloc)
return 0; /* already have it. */
/*
* Prefer to alloc in SSHBUF_SIZE_INC units, but
* allocate less if doing so would overflow max_size.
*/
need = len + buf->size - buf->alloc;
rlen = ROUNDUP(buf->alloc + need, SSHBUF_SIZE_INC);
SSHBUF_DBG(("need %zu initial rlen %zu", need, rlen));
if (rlen > buf->max_size)
rlen = buf->alloc + need;
SSHBUF_DBG(("adjusted rlen %zu", rlen));
if ((dp = recallocarray(buf->d, buf->alloc, rlen, 1)) == NULL) {
SSHBUF_DBG(("realloc fail"));
return SSH_ERR_ALLOC_FAIL;
}
buf->alloc = rlen;
buf->cd = buf->d = dp;
if ((r = sshbuf_check_reserve(buf, len)) < 0) {
/* shouldn't fail */
return r;
}
SSHBUF_TELL("done");
return 0;
}
int
sshbuf_reserve(struct sshbuf *buf, size_t len, u_char **dpp)
{
u_char *dp;
int r;
if (dpp != NULL)
*dpp = NULL;
SSHBUF_DBG(("reserve buf = %p len = %zu", buf, len));
if ((r = sshbuf_allocate(buf, len)) != 0)
return r;
dp = buf->d + buf->size;
buf->size += len;
if (dpp != NULL)
*dpp = dp;
return 0;
}
int
sshbuf_consume(struct sshbuf *buf, size_t len)
{
int r;
SSHBUF_DBG(("len = %zu", len));
if ((r = sshbuf_check_sanity(buf)) != 0)
return r;
if (len == 0)
return 0;
if (len > sshbuf_len(buf))
return SSH_ERR_MESSAGE_INCOMPLETE;
buf->off += len;
/* deal with empty buffer */
if (buf->off == buf->size)
buf->off = buf->size = 0;
SSHBUF_TELL("done");
return 0;
}
int
sshbuf_consume_end(struct sshbuf *buf, size_t len)
{
int r;
SSHBUF_DBG(("len = %zu", len));
if ((r = sshbuf_check_sanity(buf)) != 0)
return r;
if (len == 0)
return 0;
if (len > sshbuf_len(buf))
return SSH_ERR_MESSAGE_INCOMPLETE;
buf->size -= len;
SSHBUF_TELL("done");
return 0;
}
diff --git a/crypto/openssh/sshbuf.h b/crypto/openssh/sshbuf.h
index feb91f762b9d..e2155f9a4d7e 100644
--- a/crypto/openssh/sshbuf.h
+++ b/crypto/openssh/sshbuf.h
@@ -1,415 +1,393 @@
-/* $OpenBSD: sshbuf.h,v 1.27 2022/05/25 06:03:44 djm Exp $ */
+/* $OpenBSD: sshbuf.h,v 1.28 2022/12/02 04:40:27 djm Exp $ */
/*
* Copyright (c) 2011 Damien Miller
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _SSHBUF_H
#define _SSHBUF_H
#include <sys/types.h>
#include <stdarg.h>
#include <stdio.h>
#ifdef WITH_OPENSSL
# include <openssl/bn.h>
# ifdef OPENSSL_HAS_ECC
# include <openssl/ec.h>
# endif /* OPENSSL_HAS_ECC */
#endif /* WITH_OPENSSL */
#define SSHBUF_SIZE_MAX 0x8000000 /* Hard maximum size */
#define SSHBUF_REFS_MAX 0x100000 /* Max child buffers */
#define SSHBUF_MAX_BIGNUM (16384 / 8) /* Max bignum *bytes* */
#define SSHBUF_MAX_ECPOINT ((528 * 2 / 8) + 1) /* Max EC point *bytes* */
-/*
- * NB. do not depend on the internals of this. It will be made opaque
- * one day.
- */
-struct sshbuf {
- u_char *d; /* Data */
- const u_char *cd; /* Const data */
- size_t off; /* First available byte is buf->d + buf->off */
- size_t size; /* Last byte is buf->d + buf->size - 1 */
- size_t max_size; /* Maximum size of buffer */
- size_t alloc; /* Total bytes allocated to buf->d */
- int readonly; /* Refers to external, const data */
- int dont_free; /* Kludge to support sshbuf_init */
- u_int refcount; /* Tracks self and number of child buffers */
- struct sshbuf *parent; /* If child, pointer to parent */
-};
+struct sshbuf;
/*
* Create a new sshbuf buffer.
* Returns pointer to buffer on success, or NULL on allocation failure.
*/
struct sshbuf *sshbuf_new(void);
/*
* Create a new, read-only sshbuf buffer from existing data.
* Returns pointer to buffer on success, or NULL on allocation failure.
*/
struct sshbuf *sshbuf_from(const void *blob, size_t len);
/*
* Create a new, read-only sshbuf buffer from the contents of an existing
* buffer. The contents of "buf" must not change in the lifetime of the
* resultant buffer.
* Returns pointer to buffer on success, or NULL on allocation failure.
*/
struct sshbuf *sshbuf_fromb(struct sshbuf *buf);
/*
* Create a new, read-only sshbuf buffer from the contents of a string in
* an existing buffer (the string is consumed in the process).
* The contents of "buf" must not change in the lifetime of the resultant
* buffer.
* Returns pointer to buffer on success, or NULL on allocation failure.
*/
int sshbuf_froms(struct sshbuf *buf, struct sshbuf **bufp);
/*
* Clear and free buf
*/
void sshbuf_free(struct sshbuf *buf);
/*
* Reset buf, clearing its contents. NB. max_size is preserved.
*/
void sshbuf_reset(struct sshbuf *buf);
/*
* Return the maximum size of buf
*/
size_t sshbuf_max_size(const struct sshbuf *buf);
/*
* Set the maximum size of buf
* Returns 0 on success, or a negative SSH_ERR_* error code on failure.
*/
int sshbuf_set_max_size(struct sshbuf *buf, size_t max_size);
/*
* Returns the length of data in buf
*/
size_t sshbuf_len(const struct sshbuf *buf);
/*
* Returns number of bytes left in buffer before hitting max_size.
*/
size_t sshbuf_avail(const struct sshbuf *buf);
/*
* Returns a read-only pointer to the start of the data in buf
*/
const u_char *sshbuf_ptr(const struct sshbuf *buf);
/*
* Returns a mutable pointer to the start of the data in buf, or
* NULL if the buffer is read-only.
*/
u_char *sshbuf_mutable_ptr(const struct sshbuf *buf);
/*
* Check whether a reservation of size len will succeed in buf
* Safer to use than direct comparisons again sshbuf_avail as it copes
* with unsigned overflows correctly.
* Returns 0 on success, or a negative SSH_ERR_* error code on failure.
*/
int sshbuf_check_reserve(const struct sshbuf *buf, size_t len);
/*
* Preallocates len additional bytes in buf.
* Useful for cases where the caller knows how many bytes will ultimately be
* required to avoid realloc in the buffer code.
* Returns 0 on success, or a negative SSH_ERR_* error code on failure.
*/
int sshbuf_allocate(struct sshbuf *buf, size_t len);
/*
* Reserve len bytes in buf.
* Returns 0 on success and a pointer to the first reserved byte via the
* optional dpp parameter or a negative SSH_ERR_* error code on failure.
*/
int sshbuf_reserve(struct sshbuf *buf, size_t len, u_char **dpp);
/*
* Consume len bytes from the start of buf
* Returns 0 on success, or a negative SSH_ERR_* error code on failure.
*/
int sshbuf_consume(struct sshbuf *buf, size_t len);
/*
* Consume len bytes from the end of buf
* Returns 0 on success, or a negative SSH_ERR_* error code on failure.
*/
int sshbuf_consume_end(struct sshbuf *buf, size_t len);
/* Extract or deposit some bytes */
int sshbuf_get(struct sshbuf *buf, void *v, size_t len);
int sshbuf_put(struct sshbuf *buf, const void *v, size_t len);
int sshbuf_putb(struct sshbuf *buf, const struct sshbuf *v);
/* Append using a printf(3) format */
int sshbuf_putf(struct sshbuf *buf, const char *fmt, ...)
__attribute__((format(printf, 2, 3)));
int sshbuf_putfv(struct sshbuf *buf, const char *fmt, va_list ap);
/* Functions to extract or store big-endian words of various sizes */
int sshbuf_get_u64(struct sshbuf *buf, u_int64_t *valp);
int sshbuf_get_u32(struct sshbuf *buf, u_int32_t *valp);
int sshbuf_get_u16(struct sshbuf *buf, u_int16_t *valp);
int sshbuf_get_u8(struct sshbuf *buf, u_char *valp);
int sshbuf_put_u64(struct sshbuf *buf, u_int64_t val);
int sshbuf_put_u32(struct sshbuf *buf, u_int32_t val);
int sshbuf_put_u16(struct sshbuf *buf, u_int16_t val);
int sshbuf_put_u8(struct sshbuf *buf, u_char val);
/* Functions to peek at the contents of a buffer without modifying it. */
int sshbuf_peek_u64(const struct sshbuf *buf, size_t offset,
u_int64_t *valp);
int sshbuf_peek_u32(const struct sshbuf *buf, size_t offset,
u_int32_t *valp);
int sshbuf_peek_u16(const struct sshbuf *buf, size_t offset,
u_int16_t *valp);
int sshbuf_peek_u8(const struct sshbuf *buf, size_t offset,
u_char *valp);
/*
* Functions to poke values into an existing buffer (e.g. a length header
* to a packet). The destination bytes must already exist in the buffer.
*/
int sshbuf_poke_u64(struct sshbuf *buf, size_t offset, u_int64_t val);
int sshbuf_poke_u32(struct sshbuf *buf, size_t offset, u_int32_t val);
int sshbuf_poke_u16(struct sshbuf *buf, size_t offset, u_int16_t val);
int sshbuf_poke_u8(struct sshbuf *buf, size_t offset, u_char val);
int sshbuf_poke(struct sshbuf *buf, size_t offset, void *v, size_t len);
/*
* Functions to extract or store SSH wire encoded strings (u32 len || data)
* The "cstring" variants admit no \0 characters in the string contents.
* Caller must free *valp.
*/
int sshbuf_get_string(struct sshbuf *buf, u_char **valp, size_t *lenp);
int sshbuf_get_cstring(struct sshbuf *buf, char **valp, size_t *lenp);
int sshbuf_get_stringb(struct sshbuf *buf, struct sshbuf *v);
int sshbuf_put_string(struct sshbuf *buf, const void *v, size_t len);
int sshbuf_put_cstring(struct sshbuf *buf, const char *v);
int sshbuf_put_stringb(struct sshbuf *buf, const struct sshbuf *v);
/*
* "Direct" variant of sshbuf_get_string, returns pointer into the sshbuf to
* avoid an malloc+memcpy. The pointer is guaranteed to be valid until the
* next sshbuf-modifying function call. Caller does not free.
*/
int sshbuf_get_string_direct(struct sshbuf *buf, const u_char **valp,
size_t *lenp);
/* Skip past a string */
#define sshbuf_skip_string(buf) sshbuf_get_string_direct(buf, NULL, NULL)
/* Another variant: "peeks" into the buffer without modifying it */
int sshbuf_peek_string_direct(const struct sshbuf *buf, const u_char **valp,
size_t *lenp);
/*
* Functions to extract or store SSH wire encoded bignums and elliptic
* curve points.
*/
int sshbuf_put_bignum2_bytes(struct sshbuf *buf, const void *v, size_t len);
int sshbuf_get_bignum2_bytes_direct(struct sshbuf *buf,
const u_char **valp, size_t *lenp);
#ifdef WITH_OPENSSL
int sshbuf_get_bignum2(struct sshbuf *buf, BIGNUM **valp);
int sshbuf_put_bignum2(struct sshbuf *buf, const BIGNUM *v);
# ifdef OPENSSL_HAS_ECC
int sshbuf_get_ec(struct sshbuf *buf, EC_POINT *v, const EC_GROUP *g);
int sshbuf_get_eckey(struct sshbuf *buf, EC_KEY *v);
int sshbuf_put_ec(struct sshbuf *buf, const EC_POINT *v, const EC_GROUP *g);
int sshbuf_put_eckey(struct sshbuf *buf, const EC_KEY *v);
# endif /* OPENSSL_HAS_ECC */
#endif /* WITH_OPENSSL */
/* Dump the contents of the buffer in a human-readable format */
void sshbuf_dump(const struct sshbuf *buf, FILE *f);
/* Dump specified memory in a human-readable format */
void sshbuf_dump_data(const void *s, size_t len, FILE *f);
/* Return the hexadecimal representation of the contents of the buffer */
char *sshbuf_dtob16(struct sshbuf *buf);
/* Encode the contents of the buffer as base64 */
char *sshbuf_dtob64_string(const struct sshbuf *buf, int wrap);
int sshbuf_dtob64(const struct sshbuf *d, struct sshbuf *b64, int wrap);
/* RFC4648 "base64url" encoding variant */
int sshbuf_dtourlb64(const struct sshbuf *d, struct sshbuf *b64, int wrap);
/* Decode base64 data and append it to the buffer */
int sshbuf_b64tod(struct sshbuf *buf, const char *b64);
/*
* Tests whether the buffer contains the specified byte sequence at the
* specified offset. Returns 0 on successful match, or a ssherr.h code
* otherwise. SSH_ERR_INVALID_FORMAT indicates sufficient bytes were
* present but the buffer contents did not match those supplied. Zero-
* length comparisons are not allowed.
*
* If sufficient data is present to make a comparison, then it is
* performed with timing independent of the value of the data. If
* insufficient data is present then the comparison is not attempted at
* all.
*/
int sshbuf_cmp(const struct sshbuf *b, size_t offset,
const void *s, size_t len);
/*
* Searches the buffer for the specified string. Returns 0 on success
* and updates *offsetp with the offset of the first match, relative to
* the start of the buffer. Otherwise sshbuf_find will return a ssherr.h
* error code. SSH_ERR_INVALID_FORMAT indicates sufficient bytes were
* present in the buffer for a match to be possible but none was found.
* Searches for zero-length data are not allowed.
*/
int
sshbuf_find(const struct sshbuf *b, size_t start_offset,
const void *s, size_t len, size_t *offsetp);
/*
* Duplicate the contents of a buffer to a string (caller to free).
* Returns NULL on buffer error, or if the buffer contains a premature
* nul character.
*/
char *sshbuf_dup_string(struct sshbuf *buf);
/*
* Fill a buffer from a file descriptor or filename. Both allocate the
* buffer for the caller.
*/
int sshbuf_load_fd(int, struct sshbuf **)
__attribute__((__nonnull__ (2)));
int sshbuf_load_file(const char *, struct sshbuf **)
__attribute__((__nonnull__ (2)));
/*
* Write a buffer to a path, creating/truncating as needed (mode 0644,
* subject to umask). The buffer contents are not modified.
*/
int sshbuf_write_file(const char *path, struct sshbuf *buf)
__attribute__((__nonnull__ (2)));
/* Read up to maxlen bytes from a fd directly to a buffer */
int sshbuf_read(int, struct sshbuf *, size_t, size_t *)
__attribute__((__nonnull__ (2)));
/* Macros for decoding/encoding integers */
#define PEEK_U64(p) \
(((u_int64_t)(((const u_char *)(p))[0]) << 56) | \
((u_int64_t)(((const u_char *)(p))[1]) << 48) | \
((u_int64_t)(((const u_char *)(p))[2]) << 40) | \
((u_int64_t)(((const u_char *)(p))[3]) << 32) | \
((u_int64_t)(((const u_char *)(p))[4]) << 24) | \
((u_int64_t)(((const u_char *)(p))[5]) << 16) | \
((u_int64_t)(((const u_char *)(p))[6]) << 8) | \
(u_int64_t)(((const u_char *)(p))[7]))
#define PEEK_U32(p) \
(((u_int32_t)(((const u_char *)(p))[0]) << 24) | \
((u_int32_t)(((const u_char *)(p))[1]) << 16) | \
((u_int32_t)(((const u_char *)(p))[2]) << 8) | \
(u_int32_t)(((const u_char *)(p))[3]))
#define PEEK_U16(p) \
(((u_int16_t)(((const u_char *)(p))[0]) << 8) | \
(u_int16_t)(((const u_char *)(p))[1]))
#define POKE_U64(p, v) \
do { \
const u_int64_t __v = (v); \
((u_char *)(p))[0] = (__v >> 56) & 0xff; \
((u_char *)(p))[1] = (__v >> 48) & 0xff; \
((u_char *)(p))[2] = (__v >> 40) & 0xff; \
((u_char *)(p))[3] = (__v >> 32) & 0xff; \
((u_char *)(p))[4] = (__v >> 24) & 0xff; \
((u_char *)(p))[5] = (__v >> 16) & 0xff; \
((u_char *)(p))[6] = (__v >> 8) & 0xff; \
((u_char *)(p))[7] = __v & 0xff; \
} while (0)
#define POKE_U32(p, v) \
do { \
const u_int32_t __v = (v); \
((u_char *)(p))[0] = (__v >> 24) & 0xff; \
((u_char *)(p))[1] = (__v >> 16) & 0xff; \
((u_char *)(p))[2] = (__v >> 8) & 0xff; \
((u_char *)(p))[3] = __v & 0xff; \
} while (0)
#define POKE_U16(p, v) \
do { \
const u_int16_t __v = (v); \
((u_char *)(p))[0] = (__v >> 8) & 0xff; \
((u_char *)(p))[1] = __v & 0xff; \
} while (0)
/* Internal definitions follow. Exposed for regress tests */
#ifdef SSHBUF_INTERNAL
/*
* Return the allocation size of buf
*/
size_t sshbuf_alloc(const struct sshbuf *buf);
/*
* Increment the reference count of buf.
*/
int sshbuf_set_parent(struct sshbuf *child, struct sshbuf *parent);
/*
* Return the parent buffer of buf, or NULL if it has no parent.
*/
const struct sshbuf *sshbuf_parent(const struct sshbuf *buf);
/*
* Return the reference count of buf
*/
u_int sshbuf_refcount(const struct sshbuf *buf);
# define SSHBUF_SIZE_INIT 256 /* Initial allocation */
# define SSHBUF_SIZE_INC 256 /* Preferred increment length */
# define SSHBUF_PACK_MIN 8192 /* Minimum packable offset */
/* # define SSHBUF_ABORT abort */
/* # define SSHBUF_DEBUG */
# ifndef SSHBUF_ABORT
# define SSHBUF_ABORT()
# endif
# ifdef SSHBUF_DEBUG
-# define SSHBUF_TELL(what) do { \
- printf("%s:%d %s: %s size %zu alloc %zu off %zu max %zu\n", \
- __FILE__, __LINE__, __func__, what, \
- buf->size, buf->alloc, buf->off, buf->max_size); \
- fflush(stdout); \
- } while (0)
# define SSHBUF_DBG(x) do { \
printf("%s:%d %s: ", __FILE__, __LINE__, __func__); \
printf x; \
printf("\n"); \
fflush(stdout); \
} while (0)
# else
-# define SSHBUF_TELL(what)
# define SSHBUF_DBG(x)
# endif
#endif /* SSHBUF_INTERNAL */
#endif /* _SSHBUF_H */
diff --git a/crypto/openssh/sshconnect.c b/crypto/openssh/sshconnect.c
index b44518d7acc7..c01d542820c3 100644
--- a/crypto/openssh/sshconnect.c
+++ b/crypto/openssh/sshconnect.c
@@ -1,1720 +1,1723 @@
-/* $OpenBSD: sshconnect.c,v 1.360 2022/11/03 21:59:20 djm Exp $ */
+/* $OpenBSD: sshconnect.c,v 1.361 2023/01/13 02:44:02 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
* Code to connect to a remote host, and to perform the client side of the
* login (authentication) dialog.
*
* As far as I am concerned, the code I have written for this software
* can be used freely for any purpose. Any derived versions of this
* software must be clearly marked as such, and if the derived work is
* incompatible with the protocol description in the RFC file, it must be
* called by a name other than "ssh" or "Secure Shell".
*/
#include "includes.h"
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/socket.h>
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
#endif
#include <net/if.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <netdb.h>
#ifdef HAVE_PATHS_H
#include <paths.h>
#endif
#include <pwd.h>
#ifdef HAVE_POLL_H
#include <poll.h>
#endif
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
#ifdef HAVE_IFADDRS_H
# include <ifaddrs.h>
#endif
#include "xmalloc.h"
#include "hostfile.h"
#include "ssh.h"
#include "sshbuf.h"
#include "packet.h"
#include "compat.h"
#include "sshkey.h"
#include "sshconnect.h"
#include "log.h"
#include "misc.h"
#include "readconf.h"
#include "atomicio.h"
#include "dns.h"
#include "monitor_fdpass.h"
#include "ssh2.h"
#include "version.h"
#include "authfile.h"
#include "ssherr.h"
#include "authfd.h"
#include "kex.h"
struct sshkey *previous_host_key = NULL;
static int matching_host_key_dns = 0;
static pid_t proxy_command_pid = 0;
/* import */
extern int debug_flag;
extern Options options;
extern char *__progname;
static int show_other_keys(struct hostkeys *, struct sshkey *);
static void warn_changed_key(struct sshkey *);
/* Expand a proxy command */
static char *
expand_proxy_command(const char *proxy_command, const char *user,
const char *host, const char *host_arg, int port)
{
char *tmp, *ret, strport[NI_MAXSERV];
const char *keyalias = options.host_key_alias ?
options.host_key_alias : host_arg;
snprintf(strport, sizeof strport, "%d", port);
xasprintf(&tmp, "exec %s", proxy_command);
ret = percent_expand(tmp,
"h", host,
"k", keyalias,
"n", host_arg,
"p", strport,
"r", options.user,
(char *)NULL);
free(tmp);
return ret;
}
/*
* Connect to the given ssh server using a proxy command that passes a
* a connected fd back to us.
*/
static int
ssh_proxy_fdpass_connect(struct ssh *ssh, const char *host,
const char *host_arg, u_short port, const char *proxy_command)
{
char *command_string;
int sp[2], sock;
pid_t pid;
char *shell;
if ((shell = getenv("SHELL")) == NULL)
shell = _PATH_BSHELL;
if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp) == -1)
fatal("Could not create socketpair to communicate with "
"proxy dialer: %.100s", strerror(errno));
command_string = expand_proxy_command(proxy_command, options.user,
host, host_arg, port);
debug("Executing proxy dialer command: %.500s", command_string);
/* Fork and execute the proxy command. */
if ((pid = fork()) == 0) {
char *argv[10];
close(sp[1]);
/* Redirect stdin and stdout. */
if (sp[0] != 0) {
if (dup2(sp[0], 0) == -1)
perror("dup2 stdin");
}
if (sp[0] != 1) {
if (dup2(sp[0], 1) == -1)
perror("dup2 stdout");
}
if (sp[0] >= 2)
close(sp[0]);
/*
* Stderr is left for non-ControlPersist connections is so
* error messages may be printed on the user's terminal.
*/
if (!debug_flag && options.control_path != NULL &&
options.control_persist && stdfd_devnull(0, 0, 1) == -1)
error_f("stdfd_devnull failed");
argv[0] = shell;
argv[1] = "-c";
argv[2] = command_string;
argv[3] = NULL;
/*
* Execute the proxy command.
* Note that we gave up any extra privileges above.
*/
execv(argv[0], argv);
perror(argv[0]);
exit(1);
}
/* Parent. */
if (pid == -1)
fatal("fork failed: %.100s", strerror(errno));
close(sp[0]);
free(command_string);
if ((sock = mm_receive_fd(sp[1])) == -1)
fatal("proxy dialer did not pass back a connection");
close(sp[1]);
while (waitpid(pid, NULL, 0) == -1)
if (errno != EINTR)
fatal("Couldn't wait for child: %s", strerror(errno));
/* Set the connection file descriptors. */
if (ssh_packet_set_connection(ssh, sock, sock) == NULL)
return -1; /* ssh_packet_set_connection logs error */
return 0;
}
/*
* Connect to the given ssh server using a proxy command.
*/
static int
ssh_proxy_connect(struct ssh *ssh, const char *host, const char *host_arg,
u_short port, const char *proxy_command)
{
char *command_string;
int pin[2], pout[2];
pid_t pid;
char *shell;
if ((shell = getenv("SHELL")) == NULL || *shell == '\0')
shell = _PATH_BSHELL;
/* Create pipes for communicating with the proxy. */
if (pipe(pin) == -1 || pipe(pout) == -1)
fatal("Could not create pipes to communicate with the proxy: %.100s",
strerror(errno));
command_string = expand_proxy_command(proxy_command, options.user,
host, host_arg, port);
debug("Executing proxy command: %.500s", command_string);
/* Fork and execute the proxy command. */
if ((pid = fork()) == 0) {
char *argv[10];
/* Redirect stdin and stdout. */
close(pin[1]);
if (pin[0] != 0) {
if (dup2(pin[0], 0) == -1)
perror("dup2 stdin");
close(pin[0]);
}
close(pout[0]);
if (dup2(pout[1], 1) == -1)
perror("dup2 stdout");
/* Cannot be 1 because pin allocated two descriptors. */
close(pout[1]);
/*
* Stderr is left for non-ControlPersist connections is so
* error messages may be printed on the user's terminal.
*/
if (!debug_flag && options.control_path != NULL &&
options.control_persist && stdfd_devnull(0, 0, 1) == -1)
error_f("stdfd_devnull failed");
argv[0] = shell;
argv[1] = "-c";
argv[2] = command_string;
argv[3] = NULL;
/*
* Execute the proxy command. Note that we gave up any
* extra privileges above.
*/
ssh_signal(SIGPIPE, SIG_DFL);
execv(argv[0], argv);
perror(argv[0]);
exit(1);
}
/* Parent. */
if (pid == -1)
fatal("fork failed: %.100s", strerror(errno));
else
proxy_command_pid = pid; /* save pid to clean up later */
/* Close child side of the descriptors. */
close(pin[0]);
close(pout[1]);
/* Free the command name. */
free(command_string);
/* Set the connection file descriptors. */
if (ssh_packet_set_connection(ssh, pout[0], pin[1]) == NULL)
return -1; /* ssh_packet_set_connection logs error */
return 0;
}
void
ssh_kill_proxy_command(void)
{
/*
* Send SIGHUP to proxy command if used. We don't wait() in
* case it hangs and instead rely on init to reap the child
*/
if (proxy_command_pid > 1)
kill(proxy_command_pid, SIGHUP);
}
#ifdef HAVE_IFADDRS_H
/*
* Search a interface address list (returned from getifaddrs(3)) for an
* address that matches the desired address family on the specified interface.
* Returns 0 and fills in *resultp and *rlenp on success. Returns -1 on failure.
*/
static int
check_ifaddrs(const char *ifname, int af, const struct ifaddrs *ifaddrs,
struct sockaddr_storage *resultp, socklen_t *rlenp)
{
struct sockaddr_in6 *sa6;
struct sockaddr_in *sa;
struct in6_addr *v6addr;
const struct ifaddrs *ifa;
int allow_local;
/*
* Prefer addresses that are not loopback or linklocal, but use them
* if nothing else matches.
*/
for (allow_local = 0; allow_local < 2; allow_local++) {
for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {
if (ifa->ifa_addr == NULL || ifa->ifa_name == NULL ||
(ifa->ifa_flags & IFF_UP) == 0 ||
ifa->ifa_addr->sa_family != af ||
strcmp(ifa->ifa_name, options.bind_interface) != 0)
continue;
switch (ifa->ifa_addr->sa_family) {
case AF_INET:
sa = (struct sockaddr_in *)ifa->ifa_addr;
if (!allow_local && sa->sin_addr.s_addr ==
htonl(INADDR_LOOPBACK))
continue;
if (*rlenp < sizeof(struct sockaddr_in)) {
error_f("v4 addr doesn't fit");
return -1;
}
*rlenp = sizeof(struct sockaddr_in);
memcpy(resultp, sa, *rlenp);
return 0;
case AF_INET6:
sa6 = (struct sockaddr_in6 *)ifa->ifa_addr;
v6addr = &sa6->sin6_addr;
if (!allow_local &&
(IN6_IS_ADDR_LINKLOCAL(v6addr) ||
IN6_IS_ADDR_LOOPBACK(v6addr)))
continue;
if (*rlenp < sizeof(struct sockaddr_in6)) {
error_f("v6 addr doesn't fit");
return -1;
}
*rlenp = sizeof(struct sockaddr_in6);
memcpy(resultp, sa6, *rlenp);
return 0;
}
}
}
return -1;
}
#endif
/*
* Creates a socket for use as the ssh connection.
*/
static int
ssh_create_socket(struct addrinfo *ai)
{
int sock, r;
struct sockaddr_storage bindaddr;
socklen_t bindaddrlen = 0;
struct addrinfo hints, *res = NULL;
#ifdef HAVE_IFADDRS_H
struct ifaddrs *ifaddrs = NULL;
#endif
char ntop[NI_MAXHOST];
sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
if (sock == -1) {
error("socket: %s", strerror(errno));
return -1;
}
fcntl(sock, F_SETFD, FD_CLOEXEC);
/* Use interactive QOS (if specified) until authentication completed */
if (options.ip_qos_interactive != INT_MAX)
set_sock_tos(sock, options.ip_qos_interactive);
/* Bind the socket to an alternative local IP address */
if (options.bind_address == NULL && options.bind_interface == NULL)
return sock;
if (options.bind_address != NULL) {
memset(&hints, 0, sizeof(hints));
hints.ai_family = ai->ai_family;
hints.ai_socktype = ai->ai_socktype;
hints.ai_protocol = ai->ai_protocol;
hints.ai_flags = AI_PASSIVE;
if ((r = getaddrinfo(options.bind_address, NULL,
&hints, &res)) != 0) {
error("getaddrinfo: %s: %s", options.bind_address,
ssh_gai_strerror(r));
goto fail;
}
if (res == NULL) {
error("getaddrinfo: no addrs");
goto fail;
}
memcpy(&bindaddr, res->ai_addr, res->ai_addrlen);
bindaddrlen = res->ai_addrlen;
} else if (options.bind_interface != NULL) {
#ifdef HAVE_IFADDRS_H
if ((r = getifaddrs(&ifaddrs)) != 0) {
error("getifaddrs: %s: %s", options.bind_interface,
strerror(errno));
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);
goto fail;
}
#else
error("BindInterface not supported on this platform.");
#endif
}
if ((r = getnameinfo((struct sockaddr *)&bindaddr, bindaddrlen,
ntop, sizeof(ntop), NULL, 0, NI_NUMERICHOST)) != 0) {
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_f("bound to %s", ntop);
/* success */
goto out;
fail:
close(sock);
sock = -1;
out:
if (res != NULL)
freeaddrinfo(res);
#ifdef HAVE_IFADDRS_H
if (ifaddrs != NULL)
freeifaddrs(ifaddrs);
#endif
return sock;
}
/*
* Opens a TCP/IP connection to the remote server on the given host.
* The address of the remote host will be returned in hostaddr.
* If port is 0, the default port will be used.
* Connection_attempts specifies the maximum number of tries (one per
* second). If proxy_command is non-NULL, it specifies the command (with %h
* and %p substituted for host and port, respectively) to use to contact
* the daemon.
*/
static int
ssh_connect_direct(struct ssh *ssh, const char *host, struct addrinfo *aitop,
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;
debug3_f("entering");
memset(ntop, 0, sizeof(ntop));
memset(strport, 0, sizeof(strport));
for (attempt = 0; attempt < connection_attempts; attempt++) {
if (attempt > 0) {
/* Sleep a moment before retrying. */
sleep(1);
debug("Trying again...");
}
/*
* Loop through addresses for this host, and try each one in
* sequence until the connection succeeds.
*/
for (ai = aitop; ai; ai = ai->ai_next) {
if (ai->ai_family != AF_INET &&
ai->ai_family != AF_INET6) {
errno = EAFNOSUPPORT;
continue;
}
if (getnameinfo(ai->ai_addr, ai->ai_addrlen,
ntop, sizeof(ntop), strport, sizeof(strport),
NI_NUMERICHOST|NI_NUMERICSERV) != 0) {
oerrno = errno;
error_f("getnameinfo failed");
errno = oerrno;
continue;
}
debug("Connecting to %.200s [%.100s] port %s.",
host, ntop, strport);
/* Create a socket for connecting. */
sock = ssh_create_socket(ai);
if (sock < 0) {
/* Any error is already output */
errno = 0;
continue;
}
*timeout_ms = saved_timeout_ms;
if (timeout_connect(sock, ai->ai_addr, ai->ai_addrlen,
timeout_ms) >= 0) {
/* Successful connection. */
memcpy(hostaddr, ai->ai_addr, ai->ai_addrlen);
break;
} else {
oerrno = errno;
debug("connect to address %s port %s: %s",
ntop, strport, strerror(errno));
close(sock);
sock = -1;
errno = oerrno;
}
}
if (sock != -1)
break; /* Successful connection. */
}
/* Return failure if we didn't get a successful connection. */
if (sock == -1) {
error("ssh: connect to host %s port %s: %s",
host, strport, errno == 0 ? "failure" : strerror(errno));
return -1;
}
debug("Connection established.");
/* Set SO_KEEPALIVE if requested. */
if (want_keepalive &&
setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&on,
sizeof(on)) == -1)
error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno));
/* Set the connection. */
if (ssh_packet_set_connection(ssh, sock, sock) == NULL)
return -1; /* ssh_packet_set_connection logs error */
return 0;
}
int
ssh_connect(struct ssh *ssh, const char *host, const char *host_arg,
struct addrinfo *addrs, struct sockaddr_storage *hostaddr, u_short port,
int connection_attempts, int *timeout_ms, int want_keepalive)
{
int in, out;
if (options.proxy_command == NULL) {
return ssh_connect_direct(ssh, host, addrs, hostaddr, port,
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_f("dup() in/out failed");
return -1; /* ssh_packet_set_connection logs error */
}
if ((ssh_packet_set_connection(ssh, in, out)) == NULL)
return -1; /* ssh_packet_set_connection logs error */
return 0;
} else if (options.proxy_use_fdpass) {
return ssh_proxy_fdpass_connect(ssh, host, host_arg, port,
options.proxy_command);
}
return ssh_proxy_connect(ssh, host, host_arg, port,
options.proxy_command);
}
/* defaults to 'no' */
static int
confirm(const char *prompt, const char *fingerprint)
{
const char *msg, *again = "Please type 'yes' or 'no': ";
const char *again_fp = "Please type 'yes', 'no' or the fingerprint: ";
char *p, *cp;
int ret = -1;
if (options.batch_mode)
return 0;
for (msg = prompt;;msg = fingerprint ? again_fp : again) {
cp = p = read_passphrase(msg, RP_ECHO);
if (p == NULL)
return 0;
p += strspn(p, " \t"); /* skip leading whitespace */
p[strcspn(p, " \t\n")] = '\0'; /* remove trailing whitespace */
if (p[0] == '\0' || strcasecmp(p, "no") == 0)
ret = 0;
else if (strcasecmp(p, "yes") == 0 || (fingerprint != NULL &&
strcmp(p, fingerprint) == 0))
ret = 1;
free(cp);
if (ret != -1)
return ret;
}
}
static int
sockaddr_is_local(struct sockaddr *hostaddr)
{
switch (hostaddr->sa_family) {
case AF_INET:
return (ntohl(((struct sockaddr_in *)hostaddr)->
sin_addr.s_addr) >> 24) == IN_LOOPBACKNET;
case AF_INET6:
return IN6_IS_ADDR_LOOPBACK(
&(((struct sockaddr_in6 *)hostaddr)->sin6_addr));
default:
return 0;
}
}
/*
* Prepare the hostname and ip address strings that are used to lookup
* host keys in known_hosts files. These may have a port number appended.
*/
void
get_hostfile_hostname_ipaddr(char *hostname, struct sockaddr *hostaddr,
u_short port, char **hostfile_hostname, char **hostfile_ipaddr)
{
char ntop[NI_MAXHOST];
socklen_t addrlen;
switch (hostaddr == NULL ? -1 : hostaddr->sa_family) {
case -1:
addrlen = 0;
break;
case AF_INET:
addrlen = sizeof(struct sockaddr_in);
break;
case AF_INET6:
addrlen = sizeof(struct sockaddr_in6);
break;
default:
addrlen = sizeof(struct sockaddr);
break;
}
/*
* We don't have the remote ip-address for connections
* using a proxy command
*/
if (hostfile_ipaddr != NULL) {
if (options.proxy_command == NULL) {
if (getnameinfo(hostaddr, addrlen,
ntop, sizeof(ntop), NULL, 0, NI_NUMERICHOST) != 0)
fatal_f("getnameinfo failed");
*hostfile_ipaddr = put_host_port(ntop, port);
} else {
*hostfile_ipaddr = xstrdup("<no hostip for proxy "
"command>");
}
}
/*
* Allow the user to record the key under a different name or
* differentiate a non-standard port. This is useful for ssh
* tunneling over forwarded connections or if you run multiple
* sshd's on different ports on the same machine.
*/
if (hostfile_hostname != NULL) {
if (options.host_key_alias != NULL) {
*hostfile_hostname = xstrdup(options.host_key_alias);
debug("using hostkeyalias: %s", *hostfile_hostname);
} else {
*hostfile_hostname = put_host_port(hostname, port);
}
}
}
/* 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.
*/
#define RDRW 0
#define RDONLY 1
#define ROQUIET 2
static int
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,
const char *hostfile_command)
{
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, *fail_reason = NULL;
const struct hostkey_entry *host_found = NULL, *ip_found = NULL;
int len, cancelled_forwarding = 0, confirmed;
int local = sockaddr_is_local(hostaddr);
int r, want_cert = sshkey_is_cert(host_key), host_ip_differ = 0;
int hostkey_trusted = 0; /* Known or explicitly accepted by user */
struct hostkeys *host_hostkeys, *ip_hostkeys;
u_int i;
/*
* Force accepting of the host key for loopback/localhost. The
* problem is that if the home directory is NFS-mounted to multiple
* machines, localhost will refer to a different machine in each of
* them, and the user will get bogus HOST_CHANGED warnings. This
* essentially disables host authentication for localhost; however,
* this is probably not a real problem.
*/
if (options.no_host_authentication_for_localhost == 1 && local &&
options.host_key_alias == NULL) {
debug("Forcing accepting of host key for "
"loopback/localhost.");
options.update_hostkeys = 0;
return 0;
}
/*
* Don't ever try to write an invalid name to a known hosts file.
* Note: do this before get_hostfile_hostname_ipaddr() to catch
* '[' or ']' in the name before they are added.
*/
if (strcspn(hostname, "@?*#[]|'\'\"\\") != strlen(hostname)) {
debug_f("invalid hostname \"%s\"; will not record: %s",
hostname, fail_reason);
readonly = RDONLY;
}
/*
* 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,
clobber_port ? 0 : port, &host, &ip);
/*
* Turn off check_host_ip if the connection is to localhost, via proxy
* command or if we don't have a hostname to compare with
*/
if (options.check_host_ip && (local ||
strcmp(hostname, ip) == 0 || options.proxy_command != NULL))
options.check_host_ip = 0;
host_hostkeys = init_hostkeys();
for (i = 0; i < num_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], 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], 0);
for (i = 0; i < num_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:
/* Reload these as they may have changed on cert->key downgrade */
want_cert = sshkey_is_cert(host_key);
type = sshkey_type(host_key);
/*
* Check if the host key is present in the user's list of known
* hosts or in the systemwide list.
*/
host_status = check_key_in_hostkeys(host_hostkeys, host_key,
&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.
*/
if (!want_cert && ip_hostkeys != NULL) {
ip_status = check_key_in_hostkeys(ip_hostkeys, host_key,
&ip_found);
if (host_status == HOST_CHANGED &&
(ip_status != HOST_CHANGED ||
(ip_found != NULL &&
!sshkey_equal(ip_found->key, host_found->key))))
host_ip_differ = 1;
} else
ip_status = host_status;
switch (host_status) {
case HOST_OK:
/* The host is known and the key matches. */
debug("Host '%.200s' is known and matches the %s host %s.",
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) {
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 "
"'%.128s' not in list of known hosts.",
type, ip);
else if (!add_host_to_hostfile(user_hostfiles[0], ip,
host_key, options.hash_known_hosts))
logit("Failed to add the %s host key for IP "
"address '%.128s' to the list of known "
"hosts (%.500s).", type, ip,
user_hostfiles[0]);
else
logit("Warning: Permanently added the %s host "
"key for IP address '%.128s' to the list "
"of known hosts.", type, ip);
} else if (options.visual_host_key) {
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_f("sshkey_fingerprint failed");
logit("Host key fingerprint is %s\n%s", fp, ra);
free(ra);
free(fp);
}
hostkey_trusted = 1;
break;
case HOST_NEW:
if (options.host_key_alias == NULL && port != 0 &&
port != SSH_DEFAULT_PORT && !clobber_port) {
debug("checking without port identifier");
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;
}
}
if (readonly || want_cert)
goto fail;
/* The host is new. */
if (options.strict_host_key_checking ==
SSH_STRICT_HOSTKEY_YES) {
/*
* User has requested strict host key checking. We
* will not add the host key automatically. The only
* alternative left is to abort.
*/
error("No %s host key is known for %.200s and you "
"have requested strict checking.", type, host);
goto fail;
} else if (options.strict_host_key_checking ==
SSH_STRICT_HOSTKEY_ASK) {
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, "", ".");
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_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) {
xextendf(&msg1, "\n",
"%s host key fingerprint found in DNS.",
matching_host_key_dns ?
"Matching" : "No matching");
}
/* 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])? ");
confirmed = confirm(msg1, fp);
free(ra);
free(fp);
free(msg1);
free(msg2);
if (!confirmed)
goto fail;
hostkey_trusted = 1; /* user explicitly confirmed */
}
/*
* If in "new" or "off" strict mode, add the key automatically
* to the local known_hosts file.
*/
if (options.check_host_ip && ip_status == HOST_NEW) {
snprintf(hostline, sizeof(hostline), "%s,%s", host, ip);
hostp = hostline;
if (options.hash_known_hosts) {
/* Add hash of host and IP separately */
r = add_host_to_hostfile(user_hostfiles[0],
host, host_key, options.hash_known_hosts) &&
add_host_to_hostfile(user_hostfiles[0], ip,
host_key, options.hash_known_hosts);
} else {
/* Add unhashed "host,ip" */
r = add_host_to_hostfile(user_hostfiles[0],
hostline, host_key,
options.hash_known_hosts);
}
} else {
r = add_host_to_hostfile(user_hostfiles[0], host,
host_key, options.hash_known_hosts);
hostp = host;
}
if (!r)
logit("Failed to add the host to the list of known "
"hosts (%.500s).", user_hostfiles[0]);
else
logit("Warning: Permanently added '%.200s' (%s) to the "
"list of known hosts.", hostp, type);
break;
case HOST_REVOKED:
error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
error("@ WARNING: REVOKED HOST KEY DETECTED! @");
error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
error("The %s host key for %s is marked as revoked.", type, host);
error("This could mean that a stolen key is being used to");
error("impersonate this host.");
/*
* If strict host key checking is in use, the user will have
* to edit the key manually and we can only abort.
*/
if (options.strict_host_key_checking !=
SSH_STRICT_HOSTKEY_OFF) {
error("%s host key for %.200s was revoked and you have "
"requested strict checking.", type, host);
goto fail;
}
goto continue_unsafe;
case HOST_CHANGED:
if (want_cert) {
/*
* This is only a debug() since it is valid to have
* CAs with wildcard DNS matches that don't match
* all hosts that one might visit.
*/
debug("Host certificate authority does not "
"match %s in %s:%lu", CA_MARKER,
host_found->file, host_found->line);
goto fail;
}
if (readonly == ROQUIET)
goto fail;
if (options.check_host_ip && host_ip_differ) {
char *key_msg;
if (ip_status == HOST_NEW)
key_msg = "is unknown";
else if (ip_status == HOST_OK)
key_msg = "is unchanged";
else
key_msg = "has a different value";
error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
error("@ WARNING: POSSIBLE DNS SPOOFING DETECTED! @");
error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
error("The %s host key for %s has changed,", type, host);
error("and the key for the corresponding IP address %s", ip);
error("%s. This could either mean that", key_msg);
error("DNS SPOOFING is happening or the IP address for the host");
error("and its host key have changed at the same time.");
if (ip_status != HOST_NEW)
error("Offending key for IP in %s:%lu",
ip_found->file, ip_found->line);
}
/* The host key has changed. */
warn_changed_key(host_key);
- error("Add correct host key in %.100s to get rid of this message.",
- user_hostfiles[0]);
+ if (num_user_hostfiles > 0 || num_system_hostfiles > 0) {
+ error("Add correct host key in %.100s to get rid "
+ "of this message.", num_user_hostfiles > 0 ?
+ user_hostfiles[0] : system_hostfiles[0]);
+ }
error("Offending %s key in %s:%lu",
sshkey_type(host_found->key),
host_found->file, host_found->line);
/*
* If strict host key checking is in use, the user will have
* to edit the key manually and we can only abort.
*/
if (options.strict_host_key_checking !=
SSH_STRICT_HOSTKEY_OFF) {
error("Host key for %.200s has changed and you have "
"requested strict checking.", host);
goto fail;
}
continue_unsafe:
/*
* If strict host key checking has not been requested, allow
* the connection but without MITM-able authentication or
* forwarding.
*/
if (options.password_authentication) {
error("Password authentication is disabled to avoid "
"man-in-the-middle attacks.");
options.password_authentication = 0;
cancelled_forwarding = 1;
}
if (options.kbd_interactive_authentication) {
error("Keyboard-interactive authentication is disabled"
" to avoid man-in-the-middle attacks.");
options.kbd_interactive_authentication = 0;
cancelled_forwarding = 1;
}
if (options.forward_agent) {
error("Agent forwarding is disabled to avoid "
"man-in-the-middle attacks.");
options.forward_agent = 0;
cancelled_forwarding = 1;
}
if (options.forward_x11) {
error("X11 forwarding is disabled to avoid "
"man-in-the-middle attacks.");
options.forward_x11 = 0;
cancelled_forwarding = 1;
}
if (options.num_local_forwards > 0 ||
options.num_remote_forwards > 0) {
error("Port forwarding is disabled to avoid "
"man-in-the-middle attacks.");
options.num_local_forwards =
options.num_remote_forwards = 0;
cancelled_forwarding = 1;
}
if (options.tun_open != SSH_TUNMODE_NO) {
error("Tunnel forwarding is disabled to avoid "
"man-in-the-middle attacks.");
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");
/*
* 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 they wish to
* accept the authentication.
*/
break;
case HOST_FOUND:
fatal("internal error");
break;
}
if (options.check_host_ip && host_status != HOST_CHANGED &&
ip_status == HOST_CHANGED) {
snprintf(msg, sizeof(msg),
"Warning: the %s host key for '%.200s' "
"differs from the key for the IP address '%.128s'"
"\nOffending key for IP in %s:%lu",
type, host, ip, ip_found->file, ip_found->line);
if (host_status == HOST_OK) {
len = strlen(msg);
snprintf(msg + len, sizeof(msg) - len,
"\nMatching host key in %s:%lu",
host_found->file, host_found->line);
}
if (options.strict_host_key_checking ==
SSH_STRICT_HOSTKEY_ASK) {
strlcat(msg, "\nAre you sure you want "
"to continue connecting (yes/no)? ", sizeof(msg));
if (!confirm(msg, NULL))
goto fail;
} else if (options.strict_host_key_checking !=
SSH_STRICT_HOSTKEY_OFF) {
logit("%s", msg);
error("Exiting, you have requested strict checking.");
goto fail;
} else {
logit("%s", msg);
}
}
if (!hostkey_trusted && options.update_hostkeys) {
debug_f("hostkey not known or explicitly trusted: "
"disabling UpdateHostkeys");
options.update_hostkeys = 0;
}
free(ip);
free(host);
if (host_hostkeys != NULL)
free_hostkeys(host_hostkeys);
if (ip_hostkeys != NULL)
free_hostkeys(ip_hostkeys);
return 0;
fail:
if (want_cert && host_status != HOST_REVOKED) {
/*
* No matching certificate. Downgrade cert to raw key and
* search normally.
*/
debug("No matching CA found. Retry with plain key");
if ((r = sshkey_from_private(host_key, &raw_key)) != 0)
fatal_fr(r, "decode key");
if ((r = sshkey_drop_cert(raw_key)) != 0)
fatal_r(r, "Couldn't drop certificate");
host_key = raw_key;
goto retry;
}
sshkey_free(raw_key);
free(ip);
free(host);
if (host_hostkeys != NULL)
free_hostkeys(host_hostkeys);
if (ip_hostkeys != NULL)
free_hostkeys(ip_hostkeys);
return -1;
}
/* 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,
const struct ssh_conn_info *cinfo)
{
u_int i;
int r = -1, flags = 0;
char valid[64], *fp = NULL, *cafp = NULL;
struct sshkey *plain = NULL;
if ((fp = sshkey_fingerprint(host_key,
options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) {
error_fr(r, "fingerprint host key");
r = -1;
goto out;
}
if (sshkey_is_cert(host_key)) {
if ((cafp = sshkey_fingerprint(host_key->cert->signature_key,
options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) {
error_fr(r, "fingerprint CA key");
r = -1;
goto out;
}
sshkey_format_cert_validity(host_key->cert,
valid, sizeof(valid));
debug("Server host certificate: %s %s, serial %llu "
"ID \"%s\" CA %s %s valid %s",
sshkey_ssh_name(host_key), fp,
(unsigned long long)host_key->cert->serial,
host_key->cert->key_id,
sshkey_ssh_name(host_key->cert->signature_key), cafp,
valid);
for (i = 0; i < host_key->cert->nprincipals; i++) {
debug2("Server host certificate hostname: %s",
host_key->cert->principals[i]);
}
} else {
debug("Server host key: %s %s", sshkey_ssh_name(host_key), fp);
}
if (sshkey_equal(previous_host_key, host_key)) {
debug2_f("server host key %s %s matches cached key",
sshkey_type(host_key), fp);
r = 0;
goto out;
}
/* Check in RevokedHostKeys file if specified */
if (options.revoked_host_keys != NULL) {
r = sshkey_check_revoked(host_key, options.revoked_host_keys);
switch (r) {
case 0:
break; /* not revoked */
case SSH_ERR_KEY_REVOKED:
error("Host key %s %s revoked by file %s",
sshkey_type(host_key), fp,
options.revoked_host_keys);
r = -1;
goto out;
default:
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;
}
}
if (options.verify_host_key_dns) {
/*
* XXX certs are not yet supported for DNS, so downgrade
* them and try the plain key.
*/
if ((r = sshkey_from_private(host_key, &plain)) != 0)
goto out;
if (sshkey_is_cert(plain))
sshkey_drop_cert(plain);
if (verify_host_key_dns(host, hostaddr, plain, &flags) == 0) {
if (flags & DNS_VERIFY_FOUND) {
if (options.verify_host_key_dns == 1 &&
flags & DNS_VERIFY_MATCH &&
flags & DNS_VERIFY_SECURE) {
r = 0;
goto out;
}
if (flags & DNS_VERIFY_MATCH) {
matching_host_key_dns = 1;
} else {
warn_changed_key(plain);
error("Update the SSHFP RR in DNS "
"with the new host key to get rid "
"of this message.");
}
}
}
}
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);
free(fp);
free(cafp);
if (r == 0 && host_key != NULL) {
sshkey_free(previous_host_key);
r = sshkey_from_private(host_key, &previous_host_key);
}
return r;
}
/*
* Starts a dialog with the server, and authenticates the current user on the
* server. This does not need any extra privileges. The basic connection
* to the server must already have been established before this is called.
* If login fails, this function prints an error and never returns.
* This function does not require super-user privileges.
*/
void
ssh_login(struct ssh *ssh, Sensitive *sensitive, const char *orighost,
struct sockaddr *hostaddr, u_short port, struct passwd *pw, int timeout_ms,
const struct ssh_conn_info *cinfo)
{
char *host;
char *server_user, *local_user;
int r;
local_user = xstrdup(pw->pw_name);
server_user = options.user ? options.user : local_user;
/* Convert the user-supplied hostname into all lowercase. */
host = xstrdup(orighost);
lowercase(host);
/* Exchange protocol version identification strings with the server. */
if ((r = kex_exchange_identification(ssh, timeout_ms,
options.version_addendum)) != 0)
sshpkt_fatal(ssh, r, "banner exchange");
/* Put the connection into non-blocking mode. */
ssh_packet_set_nonblocking(ssh);
/* key exchange */
/* authenticate user */
debug("Authenticating to %s:%d as '%s'", host, port, server_user);
ssh_kex2(ssh, host, hostaddr, port, cinfo);
ssh_userauth2(ssh, local_user, server_user, host, sensitive);
free(local_user);
free(host);
}
/* print all known host keys for a given host, but skip keys of given type */
static int
show_other_keys(struct hostkeys *hostkeys, struct sshkey *key)
{
int type[] = {
KEY_RSA,
KEY_DSA,
KEY_ECDSA,
KEY_ED25519,
KEY_XMSS,
-1
};
int i, ret = 0;
char *fp, *ra;
const struct hostkey_entry *found;
for (i = 0; type[i] != -1; i++) {
if (type[i] == key->type)
continue;
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_f("sshkey_fingerprint fail");
logit("WARNING: %s key found for host %s\n"
"in %s:%lu\n"
"%s key fingerprint %s.",
sshkey_type(found->key),
found->host, found->file, found->line,
sshkey_type(found->key), fp);
if (options.visual_host_key)
logit("%s", ra);
free(ra);
free(fp);
ret = 1;
}
return ret;
}
static void
warn_changed_key(struct sshkey *host_key)
{
char *fp;
fp = sshkey_fingerprint(host_key, options.fingerprint_hash,
SSH_FP_DEFAULT);
if (fp == NULL)
fatal_f("sshkey_fingerprint fail");
error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
error("@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @");
error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
error("IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!");
error("Someone could be eavesdropping on you right now (man-in-the-middle attack)!");
error("It is also possible that a host key has just been changed.");
error("The fingerprint for the %s key sent by the remote host is\n%s.",
sshkey_type(host_key), fp);
error("Please contact your system administrator.");
free(fp);
}
/*
* Execute a local command
*/
int
ssh_local_cmd(const char *args)
{
char *shell;
pid_t pid;
int status;
void (*osighand)(int);
if (!options.permit_local_command ||
args == NULL || !*args)
return (1);
if ((shell = getenv("SHELL")) == NULL || *shell == '\0')
shell = _PATH_BSHELL;
osighand = ssh_signal(SIGCHLD, SIG_DFL);
pid = fork();
if (pid == 0) {
ssh_signal(SIGPIPE, SIG_DFL);
debug3("Executing %s -c \"%s\"", shell, args);
execl(shell, shell, "-c", args, (char *)NULL);
error("Couldn't execute %s -c \"%s\": %s",
shell, args, strerror(errno));
_exit(1);
} else if (pid == -1)
fatal("fork failed: %.100s", strerror(errno));
while (waitpid(pid, &status, 0) == -1)
if (errno != EINTR)
fatal("Couldn't wait for child: %s", strerror(errno));
ssh_signal(SIGCHLD, osighand);
if (!WIFEXITED(status))
return (1);
return (WEXITSTATUS(status));
}
void
maybe_add_key_to_agent(const char *authfile, struct sshkey *private,
const char *comment, const char *passphrase)
{
int auth_sock = -1, r;
const char *skprovider = NULL;
if (options.add_keys_to_agent == 0)
return;
if ((r = ssh_get_authentication_socket(&auth_sock)) != 0) {
debug3("no authentication agent, not adding key");
return;
}
if (options.add_keys_to_agent == 2 &&
!ask_permission("Add key %s (%s) to agent?", authfile, comment)) {
debug3("user denied adding this key");
close(auth_sock);
return;
}
if (sshkey_is_sk(private))
skprovider = options.sk_provider;
if ((r = ssh_add_identity_constrained(auth_sock, private,
comment == NULL ? authfile : comment,
options.add_keys_to_agent_lifespan,
(options.add_keys_to_agent == 3), 0, skprovider, NULL, 0)) == 0)
debug("identity added to agent: %s", authfile);
else
debug("could not add identity to agent: %s (%d)", authfile, r);
close(auth_sock);
}
diff --git a/crypto/openssh/sshd.8 b/crypto/openssh/sshd.8
index 5836ef7d54e2..3c37c88f3ea6 100644
--- a/crypto/openssh/sshd.8
+++ b/crypto/openssh/sshd.8
@@ -1,1036 +1,1038 @@
.\"
.\" Author: Tatu Ylonen <ylo@cs.hut.fi>
.\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
.\" All rights reserved
.\"
.\" As far as I am concerned, the code I have written for this software
.\" can be used freely for any purpose. Any derived versions of this
.\" software must be clearly marked as such, and if the derived work is
.\" incompatible with the protocol description in the RFC file, it must be
.\" called by a name other than "ssh" or "Secure Shell".
.\"
.\" Copyright (c) 1999,2000 Markus Friedl. All rights reserved.
.\" Copyright (c) 1999 Aaron Campbell. All rights reserved.
.\" Copyright (c) 1999 Theo de Raadt. All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.\" $OpenBSD: sshd.8,v 1.321 2022/09/11 06:38:11 jmc Exp $
-.Dd $Mdocdate: September 11 2022 $
+.\" $OpenBSD: sshd.8,v 1.322 2023/01/18 01:50:21 millert Exp $
+.Dd $Mdocdate: January 18 2023 $
.Dt SSHD 8
.Os
.Sh NAME
.Nm sshd
.Nd OpenSSH daemon
.Sh SYNOPSIS
.Nm sshd
.Bk -words
-.Op Fl 46DdeiqTt
+.Op Fl 46DdeiqTtV
.Op Fl C Ar connection_spec
.Op Fl c Ar host_certificate_file
.Op Fl E Ar log_file
.Op Fl f Ar config_file
.Op Fl g Ar login_grace_time
.Op Fl h Ar host_key_file
.Op Fl o Ar option
.Op Fl p Ar port
.Op Fl u Ar len
.Ek
.Sh DESCRIPTION
.Nm
(OpenSSH Daemon) is the daemon program for
.Xr ssh 1 .
It provides secure encrypted communications between two untrusted hosts
over an insecure network.
.Pp
.Nm
listens for connections from clients.
It is normally started at boot from
.Pa /etc/rc.d/sshd .
It forks a new
daemon for each incoming connection.
The forked daemons handle
key exchange, encryption, authentication, command execution,
and data exchange.
.Pp
.Nm
can be configured using command-line options or a configuration file
(by default
.Xr sshd_config 5 ) ;
command-line options override values specified in the
configuration file.
.Nm
rereads its configuration file when it receives a hangup signal,
.Dv SIGHUP ,
by executing itself with the name and options it was started with, e.g.\&
.Pa /usr/sbin/sshd .
.Pp
The options are as follows:
.Bl -tag -width Ds
.It Fl 4
Forces
.Nm
to use IPv4 addresses only.
.It Fl 6
Forces
.Nm
to use IPv6 addresses only.
.It Fl C Ar connection_spec
Specify the connection parameters to use for the
.Fl T
extended test mode.
If provided, any
.Cm Match
directives in the configuration file that would apply are applied before the
configuration is written to standard output.
The connection parameters are supplied as keyword=value pairs and may be
supplied in any order, either with multiple
.Fl C
options or as a comma-separated list.
The keywords are
.Dq addr ,
.Dq user ,
.Dq host ,
.Dq laddr ,
.Dq lport ,
and
.Dq rdomain
and correspond to source address, user, resolved source host name,
local address, local port number and routing domain respectively.
.It Fl c Ar host_certificate_file
Specifies a path to a certificate file to identify
.Nm
during key exchange.
The certificate file must match a host key file specified using the
.Fl h
option or the
.Cm HostKey
configuration directive.
.It Fl D
When this option is specified,
.Nm
will not detach and does not become a daemon.
This allows easy monitoring of
.Nm sshd .
.It Fl 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
.Xr fork 2
and will only process one connection.
This option is only intended for debugging for the server.
Multiple
.Fl d
options increase the debugging level.
Maximum is 3.
.It Fl E Ar log_file
Append debug logs to
.Ar log_file
instead of the system log.
.It Fl e
Write debug logs to standard error instead of the system log.
.It Fl f Ar config_file
Specifies the name of the configuration file.
The default is
.Pa /etc/ssh/sshd_config .
.Nm
refuses to start if there is no configuration file.
.It Fl g Ar login_grace_time
Gives the grace time for clients to authenticate themselves (default
120 seconds).
If the client fails to authenticate the user within
this many seconds, the server disconnects and exits.
A value of zero indicates no limit.
.It Fl h Ar host_key_file
Specifies a file from which a host key is read.
This option must be given if
.Nm
is not run as root (as the normal
host key files are normally not readable by anyone but root).
The default is
.Pa /etc/ssh/ssh_host_ecdsa_key ,
.Pa /etc/ssh/ssh_host_ed25519_key
and
.Pa /etc/ssh/ssh_host_rsa_key .
It is possible to have multiple host key files for
the different host key algorithms.
.It Fl i
Specifies that
.Nm
is being run from
.Xr inetd 8 .
.It Fl o Ar option
Can be used to give options in the format used in the configuration file.
This is useful for specifying options for which there is no separate
command-line flag.
For full details of the options, and their values, see
.Xr sshd_config 5 .
.It Fl p Ar port
Specifies the port on which the server listens for connections
(default 22).
Multiple port options are permitted.
Ports specified in the configuration file with the
.Cm Port
option are ignored when a command-line port is specified.
Ports specified using the
.Cm ListenAddress
option override command-line ports.
.It Fl q
Quiet mode.
Nothing is sent to the system log.
Normally the beginning,
authentication, and termination of each connection is logged.
.It Fl T
Extended test mode.
Check the validity of the configuration file, output the effective configuration
to stdout and then exit.
Optionally,
.Cm Match
rules may be applied by specifying the connection parameters using one or more
.Fl C
options.
.It Fl t
Test mode.
Only check the validity of the configuration file and sanity of the keys.
This is useful for updating
.Nm
reliably as configuration options may change.
.It Fl u Ar len
This option is used to specify the size of the field
in the
.Vt utmp
structure that holds the remote host name.
If the resolved host name is longer than
.Ar len ,
the dotted decimal value will be used instead.
This allows hosts with very long host names that
overflow this field to still be uniquely identified.
Specifying
.Fl u0
indicates that only dotted decimal addresses
should be put into the
.Pa utmp
file.
.Fl u0
may also be used to prevent
.Nm
from making DNS requests unless the authentication
mechanism or configuration requires it.
Authentication mechanisms that may require DNS include
.Cm HostbasedAuthentication
and using a
.Cm from="pattern-list"
option in a key file.
Configuration options that require DNS include using a
USER@HOST pattern in
.Cm AllowUsers
or
.Cm DenyUsers .
+.It Fl V
+Display the version number and exit.
.El
.Sh AUTHENTICATION
The OpenSSH SSH daemon supports SSH protocol 2 only.
Each host has a host-specific key,
used to identify the host.
Whenever a client connects, the daemon responds with its public
host key.
The client compares the
host key against its own database to verify that it has not changed.
Forward secrecy is provided through a Diffie-Hellman key agreement.
This key agreement results in a shared session key.
The rest of the session is encrypted using a symmetric cipher.
The client selects the encryption algorithm
to use from those offered by the server.
Additionally, session integrity is provided
through a cryptographic message authentication code (MAC).
.Pp
Finally, the server and the client enter an authentication dialog.
The client tries to authenticate itself using
host-based authentication,
public key authentication,
challenge-response authentication,
or password authentication.
.Pp
Regardless of the authentication type, the account is checked to
ensure that it is accessible. An account is not accessible if it is
locked, listed in
.Cm DenyUsers
or its group is listed in
.Cm DenyGroups
\&. The definition of a locked account is system dependent. Some platforms
have their own account database (eg AIX) and some modify the passwd field (
.Ql \&*LK\&*
on Solaris and UnixWare,
.Ql \&*
on HP-UX, containing
.Ql Nologin
on Tru64,
a leading
.Ql \&*LOCKED\&*
on FreeBSD and a leading
.Ql \&!
on most Linuxes).
If there is a requirement to disable password authentication
for the account while allowing still public-key, then the passwd field
should be set to something other than these values (eg
.Ql NP
or
.Ql \&*NP\&*
).
.Pp
If the client successfully authenticates itself, a dialog for
preparing the session is entered.
At this time the client may request
things like allocating a pseudo-tty, forwarding X11 connections,
forwarding TCP connections, or forwarding the authentication agent
connection over the secure channel.
.Pp
After this, the client either requests an interactive shell or execution
or a non-interactive command, which
.Nm
will execute via the user's shell using its
.Fl c
option.
The sides then enter session mode.
In this mode, either side may send
data at any time, and such data is forwarded to/from the shell or
command on the server side, and the user terminal in the client side.
.Pp
When the user program terminates and all forwarded X11 and other
connections have been closed, the server sends command exit status to
the client, and both sides exit.
.Sh LOGIN PROCESS
When a user successfully logs in,
.Nm
does the following:
.Bl -enum -offset indent
.It
If the login is on a tty, and no command has been specified,
prints last login time and
.Pa /etc/motd
(unless prevented in the configuration file or by
.Pa ~/.hushlogin ;
see the
.Sx FILES
section).
.It
If the login is on a tty, records login time.
.It
Checks
.Pa /etc/nologin and
.Pa /var/run/nologin ;
if one exists, it prints the contents and quits
(unless root).
.It
Changes to run with normal user privileges.
.It
Sets up basic environment.
.It
Reads the file
.Pa ~/.ssh/environment ,
if it exists, and users are allowed to change their environment.
See the
.Cm PermitUserEnvironment
option in
.Xr sshd_config 5 .
.It
Changes to user's home directory.
.It
If
.Pa ~/.ssh/rc
exists and the
.Xr sshd_config 5
.Cm PermitUserRC
option is set, runs it; else if
.Pa /etc/ssh/sshrc
exists, runs
it; otherwise runs
.Xr xauth 1 .
The
.Dq rc
files are given the X11
authentication protocol and cookie in standard input.
See
.Sx SSHRC ,
below.
.It
Runs user's shell or command.
All commands are run under the user's login shell as specified in the
system password database.
.El
.Sh SSHRC
If the file
.Pa ~/.ssh/rc
exists,
.Xr sh 1
runs it after reading the
environment files but before starting the user's shell or command.
It must not produce any output on stdout; stderr must be used
instead.
If X11 forwarding is in use, it will receive the "proto cookie" pair in
its standard input (and
.Ev DISPLAY
in its environment).
The script must call
.Xr xauth 1
because
.Nm
will not run xauth automatically to add X11 cookies.
.Pp
The primary purpose of this file is to run any initialization routines
which may be needed before the user's home directory becomes
accessible; AFS is a particular example of such an environment.
.Pp
This file will probably contain some initialization code followed by
something similar to:
.Bd -literal -offset 3n
if read proto cookie && [ -n "$DISPLAY" ]; then
if [ `echo $DISPLAY | cut -c1-10` = 'localhost:' ]; then
# X11UseLocalhost=yes
echo add unix:`echo $DISPLAY |
cut -c11-` $proto $cookie
else
# X11UseLocalhost=no
echo add $DISPLAY $proto $cookie
fi | xauth -q -
fi
.Ed
.Pp
If this file does not exist,
.Pa /etc/ssh/sshrc
is run, and if that
does not exist either, xauth is used to add the cookie.
.Sh AUTHORIZED_KEYS FILE FORMAT
.Cm AuthorizedKeysFile
specifies the files containing public keys for
public key authentication;
if this option is not specified, the default is
.Pa ~/.ssh/authorized_keys
and
.Pa ~/.ssh/authorized_keys2 .
Each line of the file contains one
key (empty lines and lines starting with a
.Ql #
are ignored as
comments).
Public keys consist of the following space-separated fields:
options, keytype, base64-encoded key, comment.
The options field is optional.
The supported key types are:
.Pp
.Bl -item -compact -offset indent
.It
sk-ecdsa-sha2-nistp256@openssh.com
.It
ecdsa-sha2-nistp256
.It
ecdsa-sha2-nistp384
.It
ecdsa-sha2-nistp521
.It
sk-ssh-ed25519@openssh.com
.It
ssh-ed25519
.It
ssh-dss
.It
ssh-rsa
.El
.Pp
The comment field is not used for anything (but may be convenient for the
user to identify the key).
.Pp
Note that lines in this file can be several hundred bytes long
(because of the size of the public key encoding) up to a limit of
8 kilobytes, which permits RSA keys up to 16 kilobits.
You don't want to type them in; instead, copy the
.Pa id_dsa.pub ,
.Pa id_ecdsa.pub ,
.Pa id_ecdsa_sk.pub ,
.Pa id_ed25519.pub ,
.Pa id_ed25519_sk.pub ,
or the
.Pa id_rsa.pub
file and edit it.
.Pp
.Nm
enforces a minimum RSA key modulus size of 1024 bits.
.Pp
The options (if present) consist of comma-separated option
specifications.
No spaces are permitted, except within double quotes.
The following option specifications are supported (note
that option keywords are case-insensitive):
.Bl -tag -width Ds
.It Cm agent-forwarding
Enable authentication agent forwarding previously disabled by the
.Cm restrict
option.
.It Cm cert-authority
Specifies that the listed key is a certification authority (CA) that is
trusted to validate signed certificates for user authentication.
.Pp
Certificates may encode access restrictions similar to these key options.
If both certificate restrictions and key options are present, the most
restrictive union of the two is applied.
.It Cm command="command"
Specifies that the command is executed whenever this key is used for
authentication.
The command supplied by the user (if any) is ignored.
The command is run on a pty if the client requests a pty;
otherwise it is run without a tty.
If an 8-bit clean channel is required,
one must not request a pty or should specify
.Cm no-pty .
A quote may be included in the command by quoting it with a backslash.
.Pp
This option might be useful
to restrict certain public keys to perform just a specific operation.
An example might be a key that permits remote backups but nothing else.
Note that the client may specify TCP and/or X11
forwarding unless they are explicitly prohibited, e.g. using the
.Cm restrict
key option.
.Pp
The command originally supplied by the client is available in the
.Ev SSH_ORIGINAL_COMMAND
environment variable.
Note that this option applies to shell, command or subsystem execution.
Also note that this command may be superseded by a
.Xr sshd_config 5
.Cm ForceCommand
directive.
.Pp
If a command is specified and a forced-command is embedded in a certificate
used for authentication, then the certificate will be accepted only if the
two commands are identical.
.It Cm environment="NAME=value"
Specifies that the string is to be added to the environment when
logging in using this key.
Environment variables set this way
override other default environment values.
Multiple options of this type are permitted.
Environment processing is disabled by default and is
controlled via the
.Cm PermitUserEnvironment
option.
.It Cm expiry-time="timespec"
Specifies a time after which the key will not be accepted.
The time may be specified as a YYYYMMDD[Z] date or a YYYYMMDDHHMM[SS][Z] time.
Dates and times will be interpreted in the system time zone unless suffixed
by a Z character, in which case they will be interpreted in the UTC time zone.
.It Cm from="pattern-list"
Specifies that in addition to public key authentication, either the canonical
name of the remote host or its IP address must be present in the
comma-separated list of patterns.
See PATTERNS in
.Xr ssh_config 5
for more information on patterns.
.Pp
In addition to the wildcard matching that may be applied to hostnames or
addresses, a
.Cm from
stanza may match IP addresses using CIDR address/masklen notation.
.Pp
The purpose of this option is to optionally increase security: public key
authentication by itself does not trust the network or name servers or
anything (but the key); however, if somebody somehow steals the key, the key
permits an intruder to log in from anywhere in the world.
This additional option makes using a stolen key more difficult (name
servers and/or routers would have to be compromised in addition to
just the key).
.It Cm no-agent-forwarding
Forbids authentication agent forwarding when this key is used for
authentication.
.It Cm no-port-forwarding
Forbids TCP forwarding when this key is used for authentication.
Any port forward requests by the client will return an error.
This might be used, e.g. in connection with the
.Cm command
option.
.It Cm no-pty
Prevents tty allocation (a request to allocate a pty will fail).
.It Cm no-user-rc
Disables execution of
.Pa ~/.ssh/rc .
.It Cm no-X11-forwarding
Forbids X11 forwarding when this key is used for authentication.
Any X11 forward requests by the client will return an error.
.It Cm permitlisten="[host:]port"
Limit remote port forwarding with the
.Xr ssh 1
.Fl R
option such that it may only listen on the specified host (optional) and port.
IPv6 addresses can be specified by enclosing the address in square brackets.
Multiple
.Cm permitlisten
options may be applied separated by commas.
Hostnames may include wildcards as described in the PATTERNS section in
.Xr ssh_config 5 .
A port specification of
.Cm *
matches any port.
Note that the setting of
.Cm GatewayPorts
may further restrict listen addresses.
Note that
.Xr ssh 1
will send a hostname of
.Dq localhost
if a listen host was not specified when the forwarding was requested, and
that this name is treated differently to the explicit localhost addresses
.Dq 127.0.0.1
and
.Dq ::1 .
.It Cm permitopen="host:port"
Limit local port forwarding with the
.Xr ssh 1
.Fl L
option such that it may only connect to the specified host and port.
IPv6 addresses can be specified by enclosing the address in square brackets.
Multiple
.Cm permitopen
options may be applied separated by commas.
No pattern matching or name lookup is performed on the
specified hostnames, they must be literal host names and/or addresses.
A port specification of
.Cm *
matches any port.
.It Cm port-forwarding
Enable port forwarding previously disabled by the
.Cm restrict
option.
.It Cm principals="principals"
On a
.Cm cert-authority
line, specifies allowed principals for certificate authentication as a
comma-separated list.
At least one name from the list must appear in the certificate's
list of principals for the certificate to be accepted.
This option is ignored for keys that are not marked as trusted certificate
signers using the
.Cm cert-authority
option.
.It Cm pty
Permits tty allocation previously disabled by the
.Cm restrict
option.
.It Cm no-touch-required
Do not require demonstration of user presence
for signatures made using this key.
This option only makes sense for the FIDO authenticator algorithms
.Cm ecdsa-sk
and
.Cm ed25519-sk .
.It Cm verify-required
Require that signatures made using this key attest that they verified
the user, e.g. via a PIN.
This option only makes sense for the FIDO authenticator algorithms
.Cm ecdsa-sk
and
.Cm ed25519-sk .
.It Cm restrict
Enable all restrictions, i.e. disable port, agent and X11 forwarding,
as well as disabling PTY allocation
and execution of
.Pa ~/.ssh/rc .
If any future restriction capabilities are added to authorized_keys files,
they will be included in this set.
.It Cm tunnel="n"
Force a
.Xr tun 4
device on the server.
Without this option, the next available device will be used if
the client requests a tunnel.
.It Cm user-rc
Enables execution of
.Pa ~/.ssh/rc
previously disabled by the
.Cm restrict
option.
.It Cm X11-forwarding
Permits X11 forwarding previously disabled by the
.Cm restrict
option.
.El
.Pp
An example authorized_keys file:
.Bd -literal -offset 3n
# 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
.Pa /etc/ssh/ssh_known_hosts
and
.Pa ~/.ssh/known_hosts
files contain host public keys for all known hosts.
The global file should
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: marker (optional),
hostnames, keytype, base64-encoded key, comment.
The fields are separated by spaces.
.Pp
The marker is optional, but if it is present then it must be one of
.Dq @cert-authority ,
to indicate that the line contains a certification authority (CA) key,
or
.Dq @revoked ,
to indicate that the key contained on the line is revoked and must not ever
be accepted.
Only one marker should be used on a key line.
.Pp
Hostnames is a comma-separated list of patterns
.Pf ( Ql *
and
.Ql \&?
act as
wildcards); each pattern in turn is matched against the host name.
When
.Nm sshd
is authenticating a client, such as when using
.Cm HostbasedAuthentication ,
this will be the canonical client host name.
When
.Xr ssh 1
is authenticating a server, this will be the host name
given by the user, the value of the
.Xr ssh 1
.Cm HostkeyAlias
if it was specified, or the canonical server hostname if the
.Xr ssh 1
.Cm CanonicalizeHostname
option was used.
.Pp
A pattern may also be preceded by
.Ql \&!
to indicate negation: if the host name matches a negated
pattern, it is not accepted (by that line) even if it matched another
pattern on the line.
A hostname or address may optionally be enclosed within
.Ql \&[
and
.Ql \&]
brackets then followed by
.Ql \&:
and a non-standard port number.
.Pp
Alternately, hostnames may be stored in a hashed form which hides host names
and addresses should the file's contents be disclosed.
Hashed hostnames start with a
.Ql |
character.
Only one hashed hostname may appear on a single line and none of the above
negation or wildcard operators may be applied.
.Pp
The keytype and base64-encoded key are taken directly from the host key; they
can be obtained, for example, from
.Pa /etc/ssh/ssh_host_rsa_key.pub .
The optional comment field continues to the end of the line, and is not used.
.Pp
Lines starting with
.Ql #
and empty lines are ignored as comments.
.Pp
When performing host authentication, authentication is accepted if any
matching line has the proper key; either one that matches exactly or,
if the server has presented a certificate for authentication, the key
of the certification authority that signed the certificate.
For a key to be trusted as a certification authority, it must use the
.Dq @cert-authority
marker described above.
.Pp
The known hosts file also provides a facility to mark keys as revoked,
for example when it is known that the associated private key has been
stolen.
Revoked keys are specified by including the
.Dq @revoked
marker at the beginning of the key line, and are never accepted for
authentication or as certification authorities, but instead will
produce a warning from
.Xr ssh 1
when they are encountered.
.Pp
It is permissible (but not
recommended) to have several lines or different host keys for the same
names.
This will inevitably happen when short forms of host names
from different domains are put in the file.
It is possible
that the files contain conflicting information; authentication is
accepted if valid information can be found from either file.
.Pp
Note that the lines in these files are typically hundreds of characters
long, and you definitely don't want to type in the host keys by hand.
Rather, generate them by a script,
.Xr ssh-keyscan 1
or by taking, for example,
.Pa /etc/ssh/ssh_host_rsa_key.pub
and adding the host names at the front.
.Xr ssh-keygen 1
also offers some basic automated editing for
.Pa ~/.ssh/known_hosts
including removing hosts matching a host name and converting all host
names to their hashed representations.
.Pp
An example ssh_known_hosts file:
.Bd -literal -offset 3n
# Comments allowed at start of line
cvs.example.net,192.0.2.10 ssh-rsa AAAA1234.....=
# A hashed hostname
|1|JfKTdBh7rNbXkVAQCRp4OQoPfmI=|USECr3SWf1JUPsms5AqfD5QfxkM= ssh-rsa
AAAA1234.....=
# A revoked key
@revoked * ssh-rsa AAAAB5W...
# A CA key, accepted for any host in *.mydomain.com or *.mydomain.org
@cert-authority *.mydomain.org,*.mydomain.com ssh-rsa AAAAB5W...
.Ed
.Sh FILES
.Bl -tag -width Ds -compact
.It Pa ~/.hushlogin
This file is used to suppress printing the last login time and
.Pa /etc/motd ,
if
.Cm PrintLastLog
and
.Cm PrintMotd ,
respectively,
are enabled.
It does not suppress printing of the banner specified by
.Cm Banner .
.Pp
.It Pa ~/.rhosts
This file is used for host-based authentication (see
.Xr ssh 1
for more information).
On some machines this file may need to be
world-readable if the user's home directory is on an NFS partition,
because
.Nm
reads it as root.
Additionally, this file must be owned by the user,
and must not have write permissions for anyone else.
The recommended
permission for most machines is read/write for the user, and not
accessible by others.
.Pp
.It Pa ~/.shosts
This file is used in exactly the same way as
.Pa .rhosts ,
but allows host-based authentication without permitting login with
rlogin/rsh.
.Pp
.It Pa ~/.ssh/
This directory is the default location for all user-specific configuration
and authentication information.
There is no general requirement to keep the entire contents of this directory
secret, but the recommended permissions are read/write/execute for the user,
and not accessible by others.
.Pp
.It Pa ~/.ssh/authorized_keys
Lists the public keys (DSA, ECDSA, Ed25519, RSA)
that can be used for logging in as this user.
The format of this file is described above.
The content of the file is not highly sensitive, but the recommended
permissions are read/write for the user, and not accessible by others.
.Pp
If this file, the
.Pa ~/.ssh
directory, or the user's home directory are writable
by other users, then the file could be modified or replaced by unauthorized
users.
In this case,
.Nm
will not allow it to be used unless the
.Cm StrictModes
option has been set to
.Dq no .
.Pp
.It Pa ~/.ssh/environment
This file is read into the environment at login (if it exists).
It can only contain empty lines, comment lines (that start with
.Ql # ) ,
and assignment lines of the form name=value.
The file should be writable
only by the user; it need not be readable by anyone else.
Environment processing is disabled by default and is
controlled via the
.Cm PermitUserEnvironment
option.
.Pp
.It Pa ~/.ssh/known_hosts
Contains a list of host keys for all hosts the user has logged into
that are not already in the systemwide list of known host keys.
The format of this file is described above.
This file should be writable only by root/the owner and
can, but need not be, world-readable.
.Pp
.It Pa ~/.ssh/rc
Contains initialization routines to be run before
the user's home directory becomes accessible.
This file should be writable only by the user, and need not be
readable by anyone else.
.Pp
.It Pa /etc/hosts.allow
.It Pa /etc/hosts.deny
Access controls that should be enforced by tcp-wrappers are defined here.
Further details are described in
.Xr hosts_access 5 .
.Pp
.It Pa /etc/hosts.equiv
This file is for host-based authentication (see
.Xr ssh 1 ) .
It should only be writable by root.
.Pp
.It Pa /etc/moduli
Contains Diffie-Hellman groups used for the "Diffie-Hellman Group Exchange"
key exchange method.
The file format is described in
.Xr moduli 5 .
If no usable groups are found in this file then fixed internal groups will
be used.
.Pp
.It Pa /etc/motd
See
.Xr motd 5 .
.Pp
.It Pa /etc/nologin
If this file exists,
.Nm
refuses to let anyone except root log in.
The contents of the file
are displayed to anyone trying to log in, and non-root connections are
refused.
The file should be world-readable.
.Pp
.It Pa /etc/shosts.equiv
This file is used in exactly the same way as
.Pa hosts.equiv ,
but allows host-based authentication without permitting login with
rlogin/rsh.
.Pp
.It Pa /etc/ssh/ssh_host_ecdsa_key
.It Pa /etc/ssh/ssh_host_ed25519_key
.It Pa /etc/ssh/ssh_host_rsa_key
These files contain the private parts of the host keys.
These files should only be owned by root, readable only by root, and not
accessible to others.
Note that
.Nm
does not start if these files are group/world-accessible.
.Pp
.It Pa /etc/ssh/ssh_host_ecdsa_key.pub
.It Pa /etc/ssh/ssh_host_ed25519_key.pub
.It Pa /etc/ssh/ssh_host_rsa_key.pub
These files contain the public parts of the host keys.
These files should be world-readable but writable only by
root.
Their contents should match the respective private parts.
These files are not
really used for anything; they are provided for the convenience of
the user so their contents can be copied to known hosts files.
These files are created using
.Xr ssh-keygen 1 .
.Pp
.It Pa /etc/ssh/ssh_known_hosts
Systemwide list of known host keys.
This file should be prepared by the
system administrator to contain the public host keys of all machines in the
organization.
The format of this file is described above.
This file should be writable only by root/the owner and
should be world-readable.
.Pp
.It Pa /etc/ssh/sshd_config
Contains configuration data for
.Nm sshd .
The file format and configuration options are described in
.Xr sshd_config 5 .
.Pp
.It Pa /etc/ssh/sshrc
Similar to
.Pa ~/.ssh/rc ,
it can be used to specify
machine-specific login-time initializations globally.
This file should be writable only by root, and should be world-readable.
.Pp
.It Pa /var/empty
.Xr chroot 2
directory used by
.Nm
during privilege separation in the pre-authentication phase.
The directory should not contain any files and must be owned by root
and not group or world-writable.
.Pp
.It Pa /var/run/sshd.pid
Contains the process ID of the
.Nm
listening for connections (if there are several daemons running
concurrently for different ports, this contains the process ID of the one
started last).
The content of this file is not sensitive; it can be world-readable.
.El
.Sh SEE ALSO
.Xr scp 1 ,
.Xr sftp 1 ,
.Xr ssh 1 ,
.Xr ssh-add 1 ,
.Xr ssh-agent 1 ,
.Xr ssh-keygen 1 ,
.Xr ssh-keyscan 1 ,
.Xr chroot 2 ,
.Xr hosts_access 5 ,
.Xr login.conf 5 ,
.Xr moduli 5 ,
.Xr sshd_config 5 ,
.Xr inetd 8 ,
.Xr sftp-server 8
.Sh AUTHORS
OpenSSH is a derivative of the original and free
ssh 1.2.12 release by Tatu Ylonen.
Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos,
Theo de Raadt and Dug Song
removed many bugs, re-added newer features and
created OpenSSH.
Markus Friedl contributed the support for SSH
protocol versions 1.5 and 2.0.
Niels Provos and Markus Friedl contributed support
for privilege separation.
diff --git a/crypto/openssh/sshd.c b/crypto/openssh/sshd.c
index a7f26cb97d6e..b8ef1664d70d 100644
--- a/crypto/openssh/sshd.c
+++ b/crypto/openssh/sshd.c
@@ -1,2561 +1,2561 @@
-/* $OpenBSD: sshd.c,v 1.591 2022/09/17 10:34:29 djm Exp $ */
+/* $OpenBSD: sshd.c,v 1.596 2023/01/18 01:50:21 millert Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
* This program is the ssh daemon. It listens for connections from clients,
* and performs authentication, executes use commands or shell, and forwards
* information to/from the application to the user client over an encrypted
* connection. This can also handle forwarding of X11, TCP/IP, and
* authentication agent connections.
*
* As far as I am concerned, the code I have written for this software
* can be used freely for any purpose. Any derived versions of this
* software must be clearly marked as such, and if the derived work is
* incompatible with the protocol description in the RFC file, it must be
* called by a name other than "ssh" or "Secure Shell".
*
* SSH2 implementation:
* Privilege Separation:
*
* Copyright (c) 2000, 2001, 2002 Markus Friedl. All rights reserved.
* Copyright (c) 2002 Niels Provos. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "includes.h"
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/socket.h>
#ifdef HAVE_SYS_STAT_H
# include <sys/stat.h>
#endif
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
#endif
#include "openbsd-compat/sys-tree.h"
#include "openbsd-compat/sys-queue.h"
#include <sys/wait.h>
#include <errno.h>
#include <fcntl.h>
#include <netdb.h>
#ifdef HAVE_PATHS_H
#include <paths.h>
#endif
#include <grp.h>
#ifdef HAVE_POLL_H
#include <poll.h>
#endif
#include <pwd.h>
#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <limits.h>
#ifdef WITH_OPENSSL
#include <openssl/dh.h>
#include <openssl/bn.h>
#include <openssl/rand.h>
#include "openbsd-compat/openssl-compat.h"
#endif
#ifdef HAVE_SECUREWARE
#include <sys/security.h>
#include <prot.h>
#endif
#ifdef __FreeBSD__
#include <resolv.h>
#if defined(GSSAPI) && defined(HAVE_GSSAPI_GSSAPI_H)
#include <gssapi/gssapi.h>
#elif defined(GSSAPI) && defined(HAVE_GSSAPI_H)
#include <gssapi.h>
#endif
#endif
#include "xmalloc.h"
#include "ssh.h"
#include "ssh2.h"
#include "sshpty.h"
#include "packet.h"
#include "log.h"
#include "sshbuf.h"
#include "misc.h"
#include "match.h"
#include "servconf.h"
#include "uidswap.h"
#include "compat.h"
#include "cipher.h"
#include "digest.h"
#include "sshkey.h"
#include "kex.h"
#include "myproposal.h"
#include "authfile.h"
#include "pathnames.h"
#include "atomicio.h"
#include "canohost.h"
#include "hostfile.h"
#include "auth.h"
#include "authfd.h"
#include "msg.h"
#include "dispatch.h"
#include "channels.h"
#include "session.h"
#include "monitor.h"
#ifdef GSSAPI
#include "ssh-gss.h"
#endif
#include "monitor_wrap.h"
#include "ssh-sandbox.h"
#include "auth-options.h"
#include "version.h"
#include "ssherr.h"
#include "sk-api.h"
#include "srclimit.h"
#include "dh.h"
#include "blacklist_client.h"
#ifdef LIBWRAP
#include <tcpd.h>
#include <syslog.h>
extern int allow_severity;
extern int deny_severity;
#endif /* LIBWRAP */
/* Re-exec fds */
#define REEXEC_DEVCRYPTO_RESERVED_FD (STDERR_FILENO + 1)
#define REEXEC_STARTUP_PIPE_FD (STDERR_FILENO + 2)
#define REEXEC_CONFIG_PASS_FD (STDERR_FILENO + 3)
#define REEXEC_MIN_FREE_FD (STDERR_FILENO + 4)
extern char *__progname;
/* Server configuration options. */
ServerOptions options;
/* Name of the server configuration file. */
char *config_file_name = _PATH_SERVER_CONFIG_FILE;
/*
* Debug mode flag. This can be set on the command line. If debug
* mode is enabled, extra debugging output will be sent to the system
* log, the daemon will not go to background, and will exit after processing
* the first connection.
*/
int debug_flag = 0;
/*
* Indicating that the daemon should only test the configuration and keys.
* If test_flag > 1 ("-T" flag), then sshd will also dump the effective
* configuration, optionally using connection information provided by the
* "-C" flag.
*/
static int test_flag = 0;
/* Flag indicating that the daemon is being started from inetd. */
static int inetd_flag = 0;
/* Flag indicating that sshd should not detach and become a daemon. */
static int no_daemon_flag = 0;
/* debug goes to stderr unless inetd_flag is set */
static int log_stderr = 0;
/* Saved arguments to main(). */
static char **saved_argv;
static int saved_argc;
/* re-exec */
static int rexeced_flag = 0;
static int rexec_flag = 1;
static int rexec_argc = 0;
static char **rexec_argv;
/*
* The sockets that the server is listening; this is used in the SIGHUP
* signal handler.
*/
#define MAX_LISTEN_SOCKS 16
static int listen_socks[MAX_LISTEN_SOCKS];
static int num_listen_socks = 0;
/* Daemon's agent connection */
int auth_sock = -1;
static int have_agent = 0;
/*
* Any really sensitive data in the application is contained in this
* structure. The idea is that this structure could be locked into memory so
* that the pages do not get written into swap. However, there are some
* problems. The private key contains BIGNUMs, and we do not (in principle)
* have access to the internals of them, and locking just the structure is
* not very useful. Currently, memory locking is not implemented.
*/
struct {
struct sshkey **host_keys; /* all private host keys */
struct sshkey **host_pubkeys; /* all public host keys */
struct sshkey **host_certificates; /* all public host certificates */
int have_ssh2_key;
} sensitive_data;
/* This is set to true when a signal is received. */
static volatile sig_atomic_t received_sighup = 0;
static volatile sig_atomic_t received_sigterm = 0;
/* record remote hostname or ip */
u_int utmp_len = HOST_NAME_MAX+1;
/*
* startup_pipes/flags are used for tracking children of the listening sshd
* process early in their lifespans. This tracking is needed for three things:
*
* 1) Implementing the MaxStartups limit of concurrent unauthenticated
* connections.
* 2) Avoiding a race condition for SIGHUP processing, where child processes
* may have listen_socks open that could collide with main listener process
* after it restarts.
* 3) Ensuring that rexec'd sshd processes have received their initial state
* from the parent listen process before handling SIGHUP.
*
* Child processes signal that they have completed closure of the listen_socks
* and (if applicable) received their rexec state by sending a char over their
* sock. Child processes signal that authentication has completed by closing
* the sock (or by exiting).
*/
static int *startup_pipes = NULL;
static int *startup_flags = NULL; /* Indicates child closed listener */
static int startup_pipe = -1; /* in child */
/* variables used for privilege separation */
int use_privsep = -1;
struct monitor *pmonitor = NULL;
int privsep_is_preauth = 1;
static int privsep_chroot = 1;
/* global connection state and authentication contexts */
Authctxt *the_authctxt = NULL;
struct ssh *the_active_state;
/* global key/cert auth options. XXX move to permanent ssh->authctxt? */
struct sshauthopt *auth_opts = NULL;
/* sshd_config buffer */
struct sshbuf *cfg;
/* Included files from the configuration file */
struct include_list includes = TAILQ_HEAD_INITIALIZER(includes);
/* message to be displayed after login */
struct sshbuf *loginmsg;
/* Unprivileged user */
struct passwd *privsep_pw = NULL;
/* Prototypes for various functions defined later in this file. */
void destroy_sensitive_data(void);
void demote_sensitive_data(void);
static void do_ssh2_kex(struct ssh *);
static char *listener_proctitle;
/*
* Close all listening sockets
*/
static void
close_listen_socks(void)
{
int i;
for (i = 0; i < num_listen_socks; i++)
close(listen_socks[i]);
num_listen_socks = 0;
}
static void
close_startup_pipes(void)
{
int i;
if (startup_pipes)
for (i = 0; i < options.max_startups; i++)
if (startup_pipes[i] != -1)
close(startup_pipes[i]);
}
/*
* Signal handler for SIGHUP. Sshd execs itself when it receives SIGHUP;
* the effect is to reread the configuration file (and to regenerate
* the server key).
*/
/*ARGSUSED*/
static void
sighup_handler(int sig)
{
received_sighup = 1;
}
/*
* Called from the main program after receiving SIGHUP.
* Restarts the server.
*/
static void
sighup_restart(void)
{
logit("Received SIGHUP; restarting.");
if (options.pid_file != NULL)
unlink(options.pid_file);
platform_pre_restart();
close_listen_socks();
close_startup_pipes();
ssh_signal(SIGHUP, SIG_IGN); /* will be restored after exec */
execv(saved_argv[0], saved_argv);
logit("RESTART FAILED: av[0]='%.100s', error: %.100s.", saved_argv[0],
strerror(errno));
exit(1);
}
/*
* Generic signal handler for terminating signals in the master daemon.
*/
/*ARGSUSED*/
static void
sigterm_handler(int sig)
{
received_sigterm = sig;
}
/*
* SIGCHLD handler. This is called whenever a child dies. This will then
* reap any zombies left by exited children.
*/
/*ARGSUSED*/
static void
main_sigchld_handler(int sig)
{
int save_errno = errno;
pid_t pid;
int status;
while ((pid = waitpid(-1, &status, WNOHANG)) > 0 ||
(pid == -1 && errno == EINTR))
;
errno = save_errno;
}
/*
* Signal handler for the alarm after the login grace period has expired.
*/
/*ARGSUSED*/
static void
grace_alarm_handler(int sig)
{
/*
* Try to kill any processes that we have spawned, E.g. authorized
* keys command helpers or privsep children.
*/
if (getpgid(0) == getpid()) {
ssh_signal(SIGTERM, SIG_IGN);
kill(0, SIGTERM);
}
BLACKLIST_NOTIFY(the_active_state, BLACKLIST_AUTH_FAIL, "ssh");
/* Log error and exit. */
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. */
void
destroy_sensitive_data(void)
{
u_int i;
for (i = 0; i < options.num_host_key_files; i++) {
if (sensitive_data.host_keys[i]) {
sshkey_free(sensitive_data.host_keys[i]);
sensitive_data.host_keys[i] = NULL;
}
if (sensitive_data.host_certificates[i]) {
sshkey_free(sensitive_data.host_certificates[i]);
sensitive_data.host_certificates[i] = NULL;
}
}
}
/* Demote private to public keys for network child */
void
demote_sensitive_data(void)
{
struct sshkey *tmp;
u_int i;
int r;
for (i = 0; i < options.num_host_key_files; i++) {
if (sensitive_data.host_keys[i]) {
if ((r = sshkey_from_private(
sensitive_data.host_keys[i], &tmp)) != 0)
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;
}
/* Certs do not need demotion */
}
}
static void
reseed_prngs(void)
{
u_int32_t rnd[256];
#ifdef WITH_OPENSSL
RAND_poll();
#endif
arc4random_stir(); /* noop on recent arc4random() implementations */
arc4random_buf(rnd, sizeof(rnd)); /* let arc4random notice PID change */
#ifdef WITH_OPENSSL
RAND_seed(rnd, sizeof(rnd));
/* give libcrypto a chance to notice the PID change */
if ((RAND_bytes((u_char *)rnd, 1)) != 1)
fatal("%s: RAND_bytes failed", __func__);
#endif
explicit_bzero(rnd, sizeof(rnd));
}
static void
privsep_preauth_child(void)
{
gid_t gidset[1];
/* Enable challenge-response authentication for privilege separation */
privsep_challenge_enable();
#ifdef GSSAPI
/* Cache supported mechanism OIDs for later use */
ssh_gssapi_prepare_supported_oids();
#endif
reseed_prngs();
/* Demote the private keys to public keys. */
demote_sensitive_data();
/* Demote the child */
if (privsep_chroot) {
/* Change our root directory */
if (chroot(_PATH_PRIVSEP_CHROOT_DIR) == -1)
fatal("chroot(\"%s\"): %s", _PATH_PRIVSEP_CHROOT_DIR,
strerror(errno));
if (chdir("/") == -1)
fatal("chdir(\"/\"): %s", strerror(errno));
/* Drop our privileges */
debug3("privsep user:group %u:%u", (u_int)privsep_pw->pw_uid,
(u_int)privsep_pw->pw_gid);
gidset[0] = privsep_pw->pw_gid;
if (setgroups(1, gidset) == -1)
fatal("setgroups: %.100s", strerror(errno));
permanently_set_uid(privsep_pw);
}
}
static int
privsep_preauth(struct ssh *ssh)
{
int status, r;
pid_t pid;
struct ssh_sandbox *box = NULL;
/* Set up unprivileged child process to deal with network data */
pmonitor = monitor_init();
/* Store a pointer to the kex for later rekeying */
pmonitor->m_pkex = &ssh->kex;
if (use_privsep == PRIVSEP_ON)
box = ssh_sandbox_init(pmonitor);
pid = fork();
if (pid == -1) {
fatal("fork of unprivileged child failed");
} else if (pid != 0) {
debug2("Network child is on pid %ld", (long)pid);
pmonitor->m_pid = pid;
if (have_agent) {
r = ssh_get_authentication_socket(&auth_sock);
if (r != 0) {
error_r(r, "Could not get agent socket");
have_agent = 0;
}
}
if (box != NULL)
ssh_sandbox_parent_preauth(box, pid);
monitor_child_preauth(ssh, pmonitor);
/* Wait for the child's exit status */
while (waitpid(pid, &status, 0) == -1) {
if (errno == EINTR)
continue;
pmonitor->m_pid = -1;
fatal_f("waitpid: %s", strerror(errno));
}
privsep_is_preauth = 0;
pmonitor->m_pid = -1;
if (WIFEXITED(status)) {
if (WEXITSTATUS(status) != 0)
fatal_f("preauth child exited with status %d",
WEXITSTATUS(status));
} else if (WIFSIGNALED(status))
fatal_f("preauth child terminated by signal %d",
WTERMSIG(status));
if (box != NULL)
ssh_sandbox_parent_finish(box);
return 1;
} else {
/* child */
close(pmonitor->m_sendfd);
close(pmonitor->m_log_recvfd);
/* Arrange for logging to be sent to the monitor */
set_log_handler(mm_log_handler, pmonitor);
privsep_preauth_child();
setproctitle("%s", "[net]");
if (box != NULL)
ssh_sandbox_child(box);
return 0;
}
}
static void
privsep_postauth(struct ssh *ssh, Authctxt *authctxt)
{
#ifdef DISABLE_FD_PASSING
if (1) {
#else
if (authctxt->pw->pw_uid == 0) {
#endif
/* File descriptor passing is broken or root login */
use_privsep = 0;
goto skip;
}
/* New socket pair */
monitor_reinit(pmonitor);
pmonitor->m_pid = fork();
if (pmonitor->m_pid == -1)
fatal("fork of unprivileged child failed");
else if (pmonitor->m_pid != 0) {
verbose("User child is on pid %ld", (long)pmonitor->m_pid);
sshbuf_reset(loginmsg);
monitor_clear_keystate(ssh, pmonitor);
monitor_child_postauth(ssh, pmonitor);
/* NEVERREACHED */
exit(0);
}
/* child */
close(pmonitor->m_sendfd);
pmonitor->m_sendfd = -1;
/* Demote the private keys to public keys. */
demote_sensitive_data();
reseed_prngs();
/* Drop privileges */
do_setusercontext(authctxt->pw);
skip:
/* It is safe now to apply the key state */
monitor_apply_keystate(ssh, pmonitor);
/*
* Tell the packet layer that authentication was successful, since
* this information is not part of the key state.
*/
ssh_packet_set_authenticated(ssh);
}
static void
append_hostkey_type(struct sshbuf *b, const char *s)
{
int r;
if (match_pattern_list(s, options.hostkeyalgorithms, 0) != 1) {
debug3_f("%s key not permitted by HostkeyAlgorithms", s);
return;
}
if ((r = sshbuf_putf(b, "%s%s", sshbuf_len(b) > 0 ? "," : "", s)) != 0)
fatal_fr(r, "sshbuf_putf");
}
static char *
list_hostkey_types(void)
{
struct sshbuf *b;
struct sshkey *key;
char *ret;
u_int i;
if ((b = sshbuf_new()) == NULL)
fatal_f("sshbuf_new failed");
for (i = 0; i < options.num_host_key_files; i++) {
key = sensitive_data.host_keys[i];
if (key == NULL)
key = sensitive_data.host_pubkeys[i];
if (key == NULL)
continue;
switch (key->type) {
case KEY_RSA:
/* for RSA we also support SHA2 signatures */
append_hostkey_type(b, "rsa-sha2-512");
append_hostkey_type(b, "rsa-sha2-256");
/* FALLTHROUGH */
case KEY_DSA:
case KEY_ECDSA:
case KEY_ED25519:
case KEY_ECDSA_SK:
case KEY_ED25519_SK:
case KEY_XMSS:
append_hostkey_type(b, sshkey_ssh_name(key));
break;
}
/* If the private key has a cert peer, then list that too */
key = sensitive_data.host_certificates[i];
if (key == NULL)
continue;
switch (key->type) {
case KEY_RSA_CERT:
/* for RSA we also support SHA2 signatures */
append_hostkey_type(b,
"rsa-sha2-512-cert-v01@openssh.com");
append_hostkey_type(b,
"rsa-sha2-256-cert-v01@openssh.com");
/* FALLTHROUGH */
case KEY_DSA_CERT:
case KEY_ECDSA_CERT:
case KEY_ED25519_CERT:
case KEY_ECDSA_SK_CERT:
case KEY_ED25519_SK_CERT:
case KEY_XMSS_CERT:
append_hostkey_type(b, sshkey_ssh_name(key));
break;
}
}
if ((ret = sshbuf_dup_string(b)) == NULL)
fatal_f("sshbuf_dup_string failed");
sshbuf_free(b);
debug_f("%s", ret);
return ret;
}
static struct sshkey *
get_hostkey_by_type(int type, int nid, int need_private, struct ssh *ssh)
{
u_int i;
struct sshkey *key;
for (i = 0; i < options.num_host_key_files; i++) {
switch (type) {
case KEY_RSA_CERT:
case KEY_DSA_CERT:
case KEY_ECDSA_CERT:
case KEY_ED25519_CERT:
case KEY_ECDSA_SK_CERT:
case KEY_ED25519_SK_CERT:
case KEY_XMSS_CERT:
key = sensitive_data.host_certificates[i];
break;
default:
key = sensitive_data.host_keys[i];
if (key == NULL && !need_private)
key = sensitive_data.host_pubkeys[i];
break;
}
if (key == NULL || key->type != type)
continue;
switch (type) {
case KEY_ECDSA:
case KEY_ECDSA_SK:
case KEY_ECDSA_CERT:
case KEY_ECDSA_SK_CERT:
if (key->ecdsa_nid != nid)
continue;
/* FALLTHROUGH */
default:
return need_private ?
sensitive_data.host_keys[i] : key;
}
}
return NULL;
}
struct sshkey *
get_hostkey_public_by_type(int type, int nid, struct ssh *ssh)
{
return get_hostkey_by_type(type, nid, 0, ssh);
}
struct sshkey *
get_hostkey_private_by_type(int type, int nid, struct ssh *ssh)
{
return get_hostkey_by_type(type, nid, 1, ssh);
}
struct sshkey *
get_hostkey_by_index(int ind)
{
if (ind < 0 || (u_int)ind >= options.num_host_key_files)
return (NULL);
return (sensitive_data.host_keys[ind]);
}
struct sshkey *
get_hostkey_public_by_index(int ind, struct ssh *ssh)
{
if (ind < 0 || (u_int)ind >= options.num_host_key_files)
return (NULL);
return (sensitive_data.host_pubkeys[ind]);
}
int
get_hostkey_index(struct sshkey *key, int compare, struct ssh *ssh)
{
u_int i;
for (i = 0; i < options.num_host_key_files; i++) {
if (sshkey_is_cert(key)) {
if (key == sensitive_data.host_certificates[i] ||
(compare && sensitive_data.host_certificates[i] &&
sshkey_equal(key,
sensitive_data.host_certificates[i])))
return (i);
} else {
if (key == sensitive_data.host_keys[i] ||
(compare && sensitive_data.host_keys[i] &&
sshkey_equal(key, sensitive_data.host_keys[i])))
return (i);
if (key == sensitive_data.host_pubkeys[i] ||
(compare && sensitive_data.host_pubkeys[i] &&
sshkey_equal(key, sensitive_data.host_pubkeys[i])))
return (i);
}
}
return (-1);
}
/* Inform the client of all hostkeys */
static void
notify_hostkeys(struct ssh *ssh)
{
struct sshbuf *buf;
struct sshkey *key;
u_int i, nkeys;
int r;
char *fp;
/* Some clients cannot cope with the hostkeys message, skip those. */
if (ssh->compat & SSH_BUG_HOSTKEYS)
return;
if ((buf = sshbuf_new()) == NULL)
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 ||
sshkey_is_cert(key))
continue;
fp = sshkey_fingerprint(key, options.fingerprint_hash,
SSH_FP_DEFAULT);
debug3_f("key %d: %s %s", i, sshkey_ssh_name(key), fp);
free(fp);
if (nkeys == 0) {
/*
* Start building the request when we find the
* first usable key.
*/
if ((r = sshpkt_start(ssh, SSH2_MSG_GLOBAL_REQUEST)) != 0 ||
(r = sshpkt_put_cstring(ssh, "hostkeys-00@openssh.com")) != 0 ||
(r = sshpkt_put_u8(ssh, 0)) != 0) /* want reply */
sshpkt_fatal(ssh, r, "%s: start request", __func__);
}
/* Append the key to the request */
sshbuf_reset(buf);
if ((r = sshkey_putb(key, buf)) != 0)
fatal_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_f("sent %u hostkeys", nkeys);
if (nkeys == 0)
fatal_f("no hostkeys");
if ((r = sshpkt_send(ssh)) != 0)
sshpkt_fatal(ssh, r, "%s: send", __func__);
sshbuf_free(buf);
}
/*
* returns 1 if connection should be dropped, 0 otherwise.
* dropping starts at connection #max_startups_begin with a probability
* of (max_startups_rate/100). the probability increases linearly until
* all connections are dropped for startups > max_startups
*/
static int
should_drop_connection(int startups)
{
int p, r;
if (startups < options.max_startups_begin)
return 0;
if (startups >= options.max_startups)
return 1;
if (options.max_startups_rate == 100)
return 1;
p = 100 - options.max_startups_rate;
p *= startups - options.max_startups_begin;
p /= options.max_startups - options.max_startups_begin;
p += options.max_startups_rate;
r = arc4random_uniform(100);
debug_f("p %d, r %d", p, r);
return (r < p) ? 1 : 0;
}
/*
* Check whether connection should be accepted by MaxStartups.
* Returns 0 if the connection is accepted. If the connection is refused,
* returns 1 and attempts to send notification to client.
* Logs when the MaxStartups condition is entered or exited, and periodically
* while in that state.
*/
static int
drop_connection(int sock, int startups, int notify_pipe)
{
char *laddr, *raddr;
const char msg[] = "Exceeded MaxStartups\r\n";
static time_t last_drop, first_drop;
static u_int ndropped;
LogLevel drop_level = SYSLOG_LEVEL_VERBOSE;
time_t now;
now = monotime();
if (!should_drop_connection(startups) &&
srclimit_check_allow(sock, notify_pipe) == 1) {
if (last_drop != 0 &&
startups < options.max_startups_begin - 1) {
/* XXX maybe need better hysteresis here */
logit("exited MaxStartups throttling after %s, "
"%u connections dropped",
fmt_timeframe(now - first_drop), ndropped);
last_drop = 0;
}
return 0;
}
#define SSHD_MAXSTARTUPS_LOG_INTERVAL (5 * 60)
if (last_drop == 0) {
error("beginning MaxStartups throttling");
drop_level = SYSLOG_LEVEL_INFO;
first_drop = now;
ndropped = 0;
} else if (last_drop + SSHD_MAXSTARTUPS_LOG_INTERVAL < now) {
/* Periodic logs */
error("in MaxStartups throttling for %s, "
"%u connections dropped",
fmt_timeframe(now - first_drop), ndropped + 1);
drop_level = SYSLOG_LEVEL_INFO;
}
last_drop = now;
ndropped++;
laddr = get_local_ipaddr(sock);
raddr = get_peer_ipaddr(sock);
do_log2(drop_level, "drop connection #%d from [%s]:%d on [%s]:%d "
"past MaxStartups", startups, raddr, get_peer_port(sock),
laddr, get_local_port(sock));
free(laddr);
free(raddr);
/* best-effort notification to client */
(void)write(sock, msg, sizeof(msg) - 1);
return 1;
}
static void
usage(void)
{
if (options.version_addendum != NULL &&
*options.version_addendum != '\0')
fprintf(stderr, "%s %s, %s\n",
SSH_RELEASE,
options.version_addendum, SSH_OPENSSL_VERSION);
else
fprintf(stderr, "%s, %s\n",
SSH_RELEASE, SSH_OPENSSL_VERSION);
fprintf(stderr,
-"usage: sshd [-46DdeiqTt] [-C connection_spec] [-c host_cert_file]\n"
+"usage: sshd [-46DdeiqTtV] [-C connection_spec] [-c host_cert_file]\n"
" [-E log_file] [-f config_file] [-g login_grace_time]\n"
" [-h host_key_file] [-o option] [-p port] [-u len]\n"
);
exit(1);
}
static void
send_rexec_state(int fd, struct sshbuf *conf)
{
struct sshbuf *m = NULL, *inc = NULL;
struct include_item *item = NULL;
int r;
debug3_f("entering fd = %d config len %zu", fd,
sshbuf_len(conf));
if ((m = sshbuf_new()) == NULL || (inc = sshbuf_new()) == NULL)
fatal_f("sshbuf_new failed");
/* pack includes into a string */
TAILQ_FOREACH(item, &includes, entry) {
if ((r = sshbuf_put_cstring(inc, item->selector)) != 0 ||
(r = sshbuf_put_cstring(inc, item->filename)) != 0 ||
(r = sshbuf_put_stringb(inc, item->contents)) != 0)
fatal_fr(r, "compose includes");
}
/*
* Protocol from reexec master to child:
* string configuration
* string included_files[] {
* string selector
* string filename
* string contents
* }
- * string rng_seed (if required)
*/
if ((r = sshbuf_put_stringb(m, conf)) != 0 ||
(r = sshbuf_put_stringb(m, inc)) != 0)
fatal_fr(r, "compose config");
-#if defined(WITH_OPENSSL) && !defined(OPENSSL_PRNG_ONLY)
- rexec_send_rng_seed(m);
-#endif
if (ssh_msg_send(fd, 0, m) == -1)
error_f("ssh_msg_send failed");
sshbuf_free(m);
sshbuf_free(inc);
debug3_f("done");
}
static void
recv_rexec_state(int fd, struct sshbuf *conf)
{
struct sshbuf *m, *inc;
u_char *cp, ver;
size_t len;
int r;
struct include_item *item;
debug3_f("entering fd = %d", fd);
if ((m = sshbuf_new()) == NULL || (inc = sshbuf_new()) == NULL)
fatal_f("sshbuf_new failed");
if (ssh_msg_recv(fd, m) == -1)
fatal_f("ssh_msg_recv failed");
if ((r = sshbuf_get_u8(m, &ver)) != 0)
fatal_fr(r, "parse version");
if (ver != 0)
fatal_f("rexec version mismatch");
if ((r = sshbuf_get_string(m, &cp, &len)) != 0 ||
(r = sshbuf_get_stringb(m, inc)) != 0)
fatal_fr(r, "parse config");
-#if defined(WITH_OPENSSL) && !defined(OPENSSL_PRNG_ONLY)
- rexec_recv_rng_seed(m);
-#endif
-
if (conf != NULL && (r = sshbuf_put(conf, cp, len)))
fatal_fr(r, "sshbuf_put");
while (sshbuf_len(inc) != 0) {
item = xcalloc(1, sizeof(*item));
if ((item->contents = sshbuf_new()) == NULL)
fatal_f("sshbuf_new failed");
if ((r = sshbuf_get_cstring(inc, &item->selector, NULL)) != 0 ||
(r = sshbuf_get_cstring(inc, &item->filename, NULL)) != 0 ||
(r = sshbuf_get_stringb(inc, item->contents)) != 0)
fatal_fr(r, "parse includes");
TAILQ_INSERT_TAIL(&includes, item, entry);
}
free(cp);
sshbuf_free(m);
debug3_f("done");
}
/* Accept a connection from inetd */
static void
server_accept_inetd(int *sock_in, int *sock_out)
{
if (rexeced_flag) {
close(REEXEC_CONFIG_PASS_FD);
*sock_in = *sock_out = dup(STDIN_FILENO);
} else {
*sock_in = dup(STDIN_FILENO);
*sock_out = dup(STDOUT_FILENO);
}
/*
* We intentionally do not close the descriptors 0, 1, and 2
* as our code for setting the descriptors won't work if
* ttyfd happens to be one of those.
*/
if (stdfd_devnull(1, 1, !log_stderr) == -1)
error_f("stdfd_devnull failed");
debug("inetd sockets after dupping: %d, %d", *sock_in, *sock_out);
}
/*
* Listen for TCP connections
*/
static void
listen_on_addrs(struct listenaddr *la)
{
int ret, listen_sock;
struct addrinfo *ai;
char ntop[NI_MAXHOST], strport[NI_MAXSERV];
for (ai = la->addrs; ai; ai = ai->ai_next) {
if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
continue;
if (num_listen_socks >= MAX_LISTEN_SOCKS)
fatal("Too many listen sockets. "
"Enlarge MAX_LISTEN_SOCKS");
if ((ret = getnameinfo(ai->ai_addr, ai->ai_addrlen,
ntop, sizeof(ntop), strport, sizeof(strport),
NI_NUMERICHOST|NI_NUMERICSERV)) != 0) {
error("getnameinfo failed: %.100s",
ssh_gai_strerror(ret));
continue;
}
/* Create socket for listening. */
listen_sock = socket(ai->ai_family, ai->ai_socktype,
ai->ai_protocol);
if (listen_sock == -1) {
/* kernel may not support ipv6 */
verbose("socket: %.100s", strerror(errno));
continue;
}
if (set_nonblock(listen_sock) == -1) {
close(listen_sock);
continue;
}
if (fcntl(listen_sock, F_SETFD, FD_CLOEXEC) == -1) {
verbose("socket: CLOEXEC: %s", strerror(errno));
close(listen_sock);
continue;
}
/* Socket options */
set_reuseaddr(listen_sock);
if (la->rdomain != NULL &&
set_rdomain(listen_sock, la->rdomain) == -1) {
close(listen_sock);
continue;
}
/* Only communicate in IPv6 over AF_INET6 sockets. */
if (ai->ai_family == AF_INET6)
sock_set_v6only(listen_sock);
debug("Bind to port %s on %s.", strport, ntop);
/* Bind the socket to the desired port. */
if (bind(listen_sock, ai->ai_addr, ai->ai_addrlen) == -1) {
error("Bind to port %s on %s failed: %.200s.",
strport, ntop, strerror(errno));
close(listen_sock);
continue;
}
listen_socks[num_listen_socks] = listen_sock;
num_listen_socks++;
/* Start listening on the port. */
if (listen(listen_sock, SSH_LISTEN_BACKLOG) == -1)
fatal("listen on [%s]:%s: %.100s",
ntop, strport, strerror(errno));
logit("Server listening on %s port %s%s%s.",
ntop, strport,
la->rdomain == NULL ? "" : " rdomain ",
la->rdomain == NULL ? "" : la->rdomain);
}
}
static void
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);
free(options.listen_addrs[i].rdomain);
memset(&options.listen_addrs[i], 0,
sizeof(options.listen_addrs[i]));
}
free(options.listen_addrs);
options.listen_addrs = NULL;
options.num_listen_addrs = 0;
if (!num_listen_socks)
fatal("Cannot bind any address.");
}
/*
* The main TCP accept loop. Note that, for the non-debug case, returns
* from this function are in a forked subprocess.
*/
static void
server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s)
{
struct pollfd *pfd = NULL;
int i, j, ret, npfd;
int ostartups = -1, startups = 0, listening = 0, lameduck = 0;
int startup_p[2] = { -1 , -1 }, *startup_pollfd;
char c = 0;
struct sockaddr_storage from;
socklen_t fromlen;
pid_t pid;
u_char rnd[256];
sigset_t nsigset, osigset;
#ifdef LIBWRAP
struct request_info req;
request_init(&req, RQ_DAEMON, __progname, 0);
#endif
/* pipes connected to unauthenticated child sshd processes */
startup_pipes = xcalloc(options.max_startups, sizeof(int));
startup_flags = xcalloc(options.max_startups, sizeof(int));
startup_pollfd = xcalloc(options.max_startups, sizeof(int));
for (i = 0; i < options.max_startups; i++)
startup_pipes[i] = -1;
/*
* Prepare signal mask that we use to block signals that might set
* received_sigterm or received_sighup, so that we are guaranteed
* to immediately wake up the ppoll if a signal is received after
* the flag is checked.
*/
sigemptyset(&nsigset);
sigaddset(&nsigset, SIGHUP);
sigaddset(&nsigset, SIGCHLD);
sigaddset(&nsigset, SIGTERM);
sigaddset(&nsigset, SIGQUIT);
/* sized for worst-case */
pfd = xcalloc(num_listen_socks + options.max_startups,
sizeof(struct pollfd));
/*
* 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,
options.max_startups_begin, options.max_startups);
ostartups = startups;
}
if (received_sighup) {
if (!lameduck) {
debug("Received SIGHUP; waiting for children");
close_listen_socks();
lameduck = 1;
}
if (listening <= 0) {
sigprocmask(SIG_SETMASK, &osigset, NULL);
sighup_restart();
}
}
for (i = 0; i < num_listen_socks; i++) {
pfd[i].fd = listen_socks[i];
pfd[i].events = POLLIN;
}
npfd = num_listen_socks;
for (i = 0; i < options.max_startups; i++) {
startup_pollfd[i] = -1;
if (startup_pipes[i] != -1) {
pfd[npfd].fd = startup_pipes[i];
pfd[npfd].events = POLLIN;
startup_pollfd[i] = npfd++;
}
}
/* Wait until a connection arrives or a child exits. */
ret = ppoll(pfd, npfd, NULL, &osigset);
if (ret == -1 && errno != EINTR) {
error("ppoll: %.100s", strerror(errno));
if (errno == EINVAL)
cleanup_exit(1); /* can't recover */
}
sigprocmask(SIG_SETMASK, &osigset, NULL);
if (ret == -1)
continue;
for (i = 0; i < options.max_startups; i++) {
if (startup_pipes[i] == -1 ||
startup_pollfd[i] == -1 ||
!(pfd[startup_pollfd[i]].revents & (POLLIN|POLLHUP)))
continue;
switch (read(startup_pipes[i], &c, sizeof(c))) {
case -1:
if (errno == EINTR || errno == EAGAIN)
continue;
if (errno != EPIPE) {
error_f("startup pipe %d (fd=%d): "
"read %s", i, startup_pipes[i],
strerror(errno));
}
/* FALLTHROUGH */
case 0:
/* child exited or completed auth */
close(startup_pipes[i]);
srclimit_done(startup_pipes[i]);
startup_pipes[i] = -1;
startups--;
if (startup_flags[i])
listening--;
break;
case 1:
/* child has finished preliminaries */
if (startup_flags[i]) {
listening--;
startup_flags[i] = 0;
}
break;
}
}
for (i = 0; i < num_listen_socks; i++) {
if (!(pfd[i].revents & POLLIN))
continue;
fromlen = sizeof(from);
*newsock = accept(listen_socks[i],
(struct sockaddr *)&from, &fromlen);
if (*newsock == -1) {
if (errno != EINTR && errno != EWOULDBLOCK &&
errno != ECONNABORTED && errno != EAGAIN)
error("accept: %.100s",
strerror(errno));
if (errno == EMFILE || errno == ENFILE)
usleep(100 * 1000);
continue;
}
#ifdef LIBWRAP
/* Check whether logins are denied from this host. */
request_set(&req, RQ_FILE, *newsock,
RQ_CLIENT_NAME, "", RQ_CLIENT_ADDR, "", 0);
sock_host(&req);
if (!hosts_access(&req)) {
const struct linger l = { .l_onoff = 1,
.l_linger = 0 };
(void )setsockopt(*newsock, SOL_SOCKET,
SO_LINGER, &l, sizeof(l));
(void )close(*newsock);
/*
* Mimic message from libwrap's refuse()
* exactly. sshguard, and supposedly lots
* of custom made scripts rely on it.
*/
syslog(deny_severity,
"refused connect from %s (%s)",
eval_client(&req),
eval_hostaddr(req.client));
debug("Connection refused by tcp wrapper");
continue;
}
#endif /* LIBWRAP */
if (unset_nonblock(*newsock) == -1) {
close(*newsock);
continue;
}
if (pipe(startup_p) == -1) {
error_f("pipe(startup_p): %s", strerror(errno));
close(*newsock);
continue;
}
if (drop_connection(*newsock, startups, startup_p[0])) {
close(*newsock);
close(startup_p[0]);
close(startup_p[1]);
continue;
}
if (rexec_flag && socketpair(AF_UNIX,
SOCK_STREAM, 0, config_s) == -1) {
error("reexec socketpair: %s",
strerror(errno));
close(*newsock);
close(startup_p[0]);
close(startup_p[1]);
continue;
}
for (j = 0; j < options.max_startups; j++)
if (startup_pipes[j] == -1) {
startup_pipes[j] = startup_p[0];
startups++;
startup_flags[j] = 1;
break;
}
/*
* Got connection. Fork a child to handle it, unless
* we are in debugging mode.
*/
if (debug_flag) {
/*
* In debugging mode. Close the listening
* socket, and start processing the
* connection without forking.
*/
debug("Server will not fork when running in debugging mode.");
close_listen_socks();
*sock_in = *newsock;
*sock_out = *newsock;
close(startup_p[0]);
close(startup_p[1]);
startup_pipe = -1;
pid = getpid();
if (rexec_flag) {
send_rexec_state(config_s[0], cfg);
close(config_s[0]);
}
free(pfd);
return;
}
/*
* Normal production daemon. Fork, and have
* the child process the connection. The
* parent continues listening.
*/
platform_pre_fork();
listening++;
if ((pid = fork()) == 0) {
/*
* Child. Close the listening and
* max_startup sockets. Start using
* the accepted socket. Reinitialize
* logging (since our pid has changed).
* We return from this function to handle
* the connection.
*/
platform_post_fork_child();
startup_pipe = startup_p[1];
close_startup_pipes();
close_listen_socks();
*sock_in = *newsock;
*sock_out = *newsock;
log_init(__progname,
options.log_level,
options.log_facility,
log_stderr);
if (rexec_flag)
close(config_s[0]);
else {
/*
* Signal parent that the preliminaries
* for this child are complete. For the
* re-exec case, this happens after the
* child has received the rexec state
* from the server.
*/
(void)atomicio(vwrite, startup_pipe,
"\0", 1);
}
free(pfd);
return;
}
/* Parent. Stay in the loop. */
platform_post_fork_parent(pid);
if (pid == -1)
error("fork: %.100s", strerror(errno));
else
debug("Forked child %ld.", (long)pid);
close(startup_p[1]);
if (rexec_flag) {
close(config_s[1]);
send_rexec_state(config_s[0], cfg);
close(config_s[0]);
}
close(*newsock);
/*
* Ensure that our random state differs
* from that of the child
*/
arc4random_stir();
arc4random_buf(rnd, sizeof(rnd));
#ifdef WITH_OPENSSL
RAND_seed(rnd, sizeof(rnd));
if ((RAND_bytes((u_char *)rnd, 1)) != 1)
fatal("%s: RAND_bytes failed", __func__);
#endif
explicit_bzero(rnd, sizeof(rnd));
}
}
}
/*
* If IP options are supported, make sure there are none (log and
* return an error if any are found). Basically we are worried about
* source routing; it can be used to pretend you are somebody
* (ip-address) you are not. That itself may be "almost acceptable"
* under certain circumstances, but rhosts authentication is useless
* if source routing is accepted. Notice also that if we just dropped
* source routing here, the other side could use IP spoofing to do
* rest of the interaction and could still bypass security. So we
* exit here if we detect any IP options.
*/
static void
check_ip_options(struct ssh *ssh)
{
#ifdef IP_OPTIONS
int sock_in = ssh_packet_get_connection_in(ssh);
struct sockaddr_storage from;
u_char opts[200];
socklen_t i, option_size = sizeof(opts), fromlen = sizeof(from);
char text[sizeof(opts) * 3 + 1];
memset(&from, 0, sizeof(from));
if (getpeername(sock_in, (struct sockaddr *)&from,
&fromlen) == -1)
return;
if (from.ss_family != AF_INET)
return;
/* XXX IPv6 options? */
if (getsockopt(sock_in, IPPROTO_IP, IP_OPTIONS, opts,
&option_size) >= 0 && option_size != 0) {
text[0] = '\0';
for (i = 0; i < option_size; i++)
snprintf(text + i*3, sizeof(text) - i*3,
" %2.2x", opts[i]);
fatal("Connection from %.100s port %d with IP opts: %.800s",
ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), text);
}
return;
#endif /* IP_OPTIONS */
}
/* Set the routing domain for this process */
static void
set_process_rdomain(struct ssh *ssh, const char *name)
{
#if defined(HAVE_SYS_SET_PROCESS_RDOMAIN)
if (name == NULL)
return; /* default */
if (strcmp(name, "%D") == 0) {
/* "expands" to routing domain of connection */
if ((name = ssh_packet_rdomain_in(ssh)) == NULL)
return;
}
/* NB. We don't pass 'ssh' to sys_set_process_rdomain() */
return sys_set_process_rdomain(name);
#elif defined(__OpenBSD__)
int rtable, ortable = getrtable();
const char *errstr;
if (name == NULL)
return; /* default */
if (strcmp(name, "%D") == 0) {
/* "expands" to routing domain of connection */
if ((name = ssh_packet_rdomain_in(ssh)) == NULL)
return;
}
rtable = (int)strtonum(name, 0, 255, &errstr);
if (errstr != NULL) /* Shouldn't happen */
fatal("Invalid routing domain \"%s\": %s", name, errstr);
if (rtable != ortable && setrtable(rtable) != 0)
fatal("Unable to set routing domain %d: %s",
rtable, strerror(errno));
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
}
static void
accumulate_host_timing_secret(struct sshbuf *server_cfg,
struct sshkey *key)
{
static struct ssh_digest_ctx *ctx;
u_char *hash;
size_t len;
struct sshbuf *buf;
int r;
if (ctx == NULL && (ctx = ssh_digest_start(SSH_DIGEST_SHA512)) == NULL)
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_f("ssh_digest_update");
len = ssh_digest_bytes(SSH_DIGEST_SHA512);
hash = xmalloc(len);
if (ssh_digest_final(ctx, hash, len) != 0)
fatal_f("ssh_digest_final");
options.timing_secret = PEEK_U64(hash);
freezero(hash, len);
ssh_digest_free(ctx);
ctx = NULL;
return;
}
if ((buf = sshbuf_new()) == NULL)
fatal_f("could not allocate buffer");
if ((r = sshkey_private_serialize(key, buf)) != 0)
- fatal_fr(r, "decode key");
+ fatal_fr(r, "encode %s key", sshkey_ssh_name(key));
if (ssh_digest_update(ctx, sshbuf_ptr(buf), sshbuf_len(buf)) != 0)
fatal_f("ssh_digest_update");
sshbuf_reset(buf);
sshbuf_free(buf);
}
static char *
prepare_proctitle(int ac, char **av)
{
char *ret = NULL;
int i;
for (i = 0; i < ac; i++)
xextendf(&ret, " ", "%s", av[i]);
return ret;
}
/*
* Main program for the daemon.
*/
int
main(int ac, char **av)
{
struct ssh *ssh = NULL;
extern char *optarg;
extern int optind;
int r, opt, on = 1, already_daemon, remote_port;
int sock_in = -1, sock_out = -1, newsock = -1;
const char *remote_ip, *rdomain;
char *fp, *line, *laddr, *logfile = NULL;
int config_s[2] = { -1 , -1 };
u_int i, j;
u_int64_t ibytes, obytes;
mode_t new_umask;
struct sshkey *key;
struct sshkey *pubkey;
int keytype;
Authctxt *authctxt;
struct connection_info *connection_info = NULL;
+ sigset_t sigmask;
#ifdef HAVE_SECUREWARE
(void)set_auth_parameters(ac, av);
#endif
__progname = ssh_get_progname(av[0]);
+ sigemptyset(&sigmask);
+ sigprocmask(SIG_SETMASK, &sigmask, NULL);
+
/* Save argv. Duplicate so setproctitle emulation doesn't clobber it */
saved_argc = ac;
rexec_argc = ac;
saved_argv = xcalloc(ac + 1, sizeof(*saved_argv));
for (i = 0; (int)i < ac; i++)
saved_argv[i] = xstrdup(av[i]);
saved_argv[i] = NULL;
#ifndef HAVE_SETPROCTITLE
/* Prepare for later setproctitle emulation */
compat_init_setproctitle(ac, av);
av = saved_argv;
#endif
if (geteuid() == 0 && setgroups(0, NULL) == -1)
debug("setgroups(): %.200s", strerror(errno));
/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
sanitise_stdfd();
- seed_rng();
-
/* Initialize configuration options to their default values. */
initialize_server_options(&options);
/* Parse command-line arguments. */
while ((opt = getopt(ac, av,
- "C:E:b:c:f:g:h:k:o:p:u:46DQRTdeiqrt")) != -1) {
+ "C:E:b:c:f:g:h:k:o:p:u:46DQRTdeiqrtV")) != -1) {
switch (opt) {
case '4':
options.address_family = AF_INET;
break;
case '6':
options.address_family = AF_INET6;
break;
case 'f':
config_file_name = optarg;
break;
case 'c':
servconf_add_hostcert("[command-line]", 0,
&options, optarg);
break;
case 'd':
if (debug_flag == 0) {
debug_flag = 1;
options.log_level = SYSLOG_LEVEL_DEBUG1;
} else if (options.log_level < SYSLOG_LEVEL_DEBUG3)
options.log_level++;
break;
case 'D':
no_daemon_flag = 1;
break;
case 'E':
logfile = optarg;
/* FALLTHROUGH */
case 'e':
log_stderr = 1;
break;
case 'i':
inetd_flag = 1;
break;
case 'r':
rexec_flag = 0;
break;
case 'R':
rexeced_flag = 1;
inetd_flag = 1;
break;
case 'Q':
/* ignored */
break;
case 'q':
options.log_level = SYSLOG_LEVEL_QUIET;
break;
case 'b':
/* protocol 1, ignored */
break;
case 'p':
options.ports_from_cmdline = 1;
if (options.num_ports >= MAX_PORTS) {
fprintf(stderr, "too many ports.\n");
exit(1);
}
options.ports[options.num_ports++] = a2port(optarg);
if (options.ports[options.num_ports-1] <= 0) {
fprintf(stderr, "Bad port number.\n");
exit(1);
}
break;
case 'g':
if ((options.login_grace_time = convtime(optarg)) == -1) {
fprintf(stderr, "Invalid login grace time.\n");
exit(1);
}
break;
case 'k':
/* protocol 1, ignored */
break;
case 'h':
servconf_add_hostkey("[command-line]", 0,
&options, optarg, 1);
break;
case 't':
test_flag = 1;
break;
case 'T':
test_flag = 2;
break;
case 'C':
connection_info = get_connection_info(ssh, 0, 0);
if (parse_server_match_testspec(connection_info,
optarg) == -1)
exit(1);
break;
case 'u':
utmp_len = (u_int)strtonum(optarg, 0, HOST_NAME_MAX+1+1, NULL);
if (utmp_len > HOST_NAME_MAX+1) {
fprintf(stderr, "Invalid utmp length.\n");
exit(1);
}
break;
case 'o':
line = xstrdup(optarg);
if (process_server_config_line(&options, line,
"command-line", 0, NULL, NULL, &includes) != 0)
exit(1);
free(line);
break;
- case '?':
+ case 'V':
+ fprintf(stderr, "%s, %s\n",
+ SSH_VERSION, SSH_OPENSSL_VERSION);
+ exit(0);
default:
usage();
break;
}
}
if (rexeced_flag || inetd_flag)
rexec_flag = 0;
if (!test_flag && rexec_flag && !path_absolute(av[0]))
fatal("sshd re-exec requires execution with an absolute path");
if (rexeced_flag)
closefrom(REEXEC_MIN_FREE_FD);
else
closefrom(REEXEC_DEVCRYPTO_RESERVED_FD);
+ seed_rng();
+
/* If requested, redirect the logs to the specified logfile. */
if (logfile != NULL)
log_redirect_stderr_to(logfile);
/*
* Force logging to stderr until we have loaded the private host
* key (unless started from inetd)
*/
log_init(__progname,
options.log_level == SYSLOG_LEVEL_NOT_SET ?
SYSLOG_LEVEL_INFO : options.log_level,
options.log_facility == SYSLOG_FACILITY_NOT_SET ?
SYSLOG_FACILITY_AUTH : options.log_facility,
log_stderr || !inetd_flag || debug_flag);
/*
* Unset KRB5CCNAME, otherwise the user's session may inherit it from
* root's environment
*/
if (getenv("KRB5CCNAME") != NULL)
(void) unsetenv("KRB5CCNAME");
sensitive_data.have_ssh2_key = 0;
/*
* If we're not doing an extended test do not silently ignore connection
* test params.
*/
if (test_flag < 2 && connection_info != NULL)
fatal("Config test connection parameter (-C) provided without "
"test mode (-T)");
/* Fetch our configuration */
if ((cfg = sshbuf_new()) == NULL)
fatal_f("sshbuf_new failed");
if (rexeced_flag) {
setproctitle("%s", "[rexeced]");
recv_rexec_state(REEXEC_CONFIG_PASS_FD, cfg);
if (!debug_flag) {
startup_pipe = dup(REEXEC_STARTUP_PIPE_FD);
close(REEXEC_STARTUP_PIPE_FD);
/*
* Signal parent that this child is at a point where
* they can go away if they have a SIGHUP pending.
*/
(void)atomicio(vwrite, startup_pipe, "\0", 1);
}
} else if (strcasecmp(config_file_name, "none") != 0)
load_server_config(config_file_name, cfg);
parse_server_config(&options, rexeced_flag ? "rexec" : config_file_name,
cfg, &includes, NULL, rexeced_flag);
#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);
/* Check that options are sensible */
if (options.authorized_keys_command_user == NULL &&
(options.authorized_keys_command != NULL &&
strcasecmp(options.authorized_keys_command, "none") != 0))
fatal("AuthorizedKeysCommand set without "
"AuthorizedKeysCommandUser");
if (options.authorized_principals_command_user == NULL &&
(options.authorized_principals_command != NULL &&
strcasecmp(options.authorized_principals_command, "none") != 0))
fatal("AuthorizedPrincipalsCommand set without "
"AuthorizedPrincipalsCommandUser");
/*
* Check whether there is any path through configured auth methods.
* Unfortunately it is not possible to verify this generally before
* daemonisation in the presence of Match block, but this catches
* and warns for trivial misconfigurations that could break login.
*/
if (options.num_auth_methods != 0) {
for (i = 0; i < options.num_auth_methods; i++) {
if (auth2_methods_valid(options.auth_methods[i],
1) == 0)
break;
}
if (i >= options.num_auth_methods)
fatal("AuthenticationMethods cannot be satisfied by "
"enabled authentication methods");
}
/* Check that there are no remaining arguments. */
if (optind < ac) {
fprintf(stderr, "Extra argument %s.\n", av[optind]);
exit(1);
}
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);
if ((privsep_pw = getpwnam(SSH_PRIVSEP_USER)) == NULL) {
if (privsep_chroot || options.kerberos_authentication)
fatal("Privilege separation user %s does not exist",
SSH_PRIVSEP_USER);
} else {
privsep_pw = pwcopy(privsep_pw);
freezero(privsep_pw->pw_passwd, strlen(privsep_pw->pw_passwd));
privsep_pw->pw_passwd = xstrdup("*");
}
endpwent();
/* load host keys */
sensitive_data.host_keys = xcalloc(options.num_host_key_files,
sizeof(struct sshkey *));
sensitive_data.host_pubkeys = xcalloc(options.num_host_key_files,
sizeof(struct sshkey *));
if (options.host_key_agent) {
if (strcmp(options.host_key_agent, SSH_AUTHSOCKET_ENV_NAME))
setenv(SSH_AUTHSOCKET_ENV_NAME,
options.host_key_agent, 1);
if ((r = ssh_get_authentication_socket(NULL)) == 0)
have_agent = 1;
else
error_r(r, "Could not connect to agent \"%s\"",
options.host_key_agent);
}
for (i = 0; i < options.num_host_key_files; i++) {
int ll = options.host_key_file_userprovided[i] ?
SYSLOG_LEVEL_ERROR : SYSLOG_LEVEL_DEBUG1;
if (options.host_key_files[i] == NULL)
continue;
if ((r = sshkey_load_private(options.host_key_files[i], "",
&key, NULL)) != 0 && r != SSH_ERR_SYSTEM_ERROR)
do_log2_r(r, ll, "Unable to load host key \"%s\"",
options.host_key_files[i]);
if (sshkey_is_sk(key) &&
key->sk_flags & SSH_SK_USER_PRESENCE_REQD) {
debug("host key %s requires user presence, ignoring",
options.host_key_files[i]);
key->sk_flags &= ~SSH_SK_USER_PRESENCE_REQD;
}
if (r == 0 && key != NULL &&
(r = sshkey_shield_private(key)) != 0) {
do_log2_r(r, ll, "Unable to shield host key \"%s\"",
options.host_key_files[i]);
sshkey_free(key);
key = NULL;
}
if ((r = sshkey_load_public(options.host_key_files[i],
&pubkey, NULL)) != 0 && r != SSH_ERR_SYSTEM_ERROR)
do_log2_r(r, ll, "Unable to load host key \"%s\"",
options.host_key_files[i]);
if (pubkey != NULL && key != NULL) {
if (!sshkey_equal(pubkey, key)) {
error("Public key for %s does not match "
"private key", options.host_key_files[i]);
sshkey_free(pubkey);
pubkey = NULL;
}
}
if (pubkey == NULL && key != NULL) {
if ((r = sshkey_from_private(key, &pubkey)) != 0)
fatal_r(r, "Could not demote key: \"%s\"",
options.host_key_files[i]);
}
if (pubkey != NULL && (r = sshkey_check_rsa_length(pubkey,
options.required_rsa_size)) != 0) {
error_fr(r, "Host key %s", options.host_key_files[i]);
sshkey_free(pubkey);
sshkey_free(key);
continue;
}
sensitive_data.host_keys[i] = key;
sensitive_data.host_pubkeys[i] = pubkey;
if (key == NULL && pubkey != NULL && have_agent) {
debug("will rely on agent for hostkey %s",
options.host_key_files[i]);
keytype = pubkey->type;
} else if (key != NULL) {
keytype = key->type;
accumulate_host_timing_secret(cfg, key);
} else {
do_log2(ll, "Unable to load host key: %s",
options.host_key_files[i]);
sensitive_data.host_keys[i] = NULL;
sensitive_data.host_pubkeys[i] = NULL;
continue;
}
switch (keytype) {
case KEY_RSA:
case KEY_DSA:
case KEY_ECDSA:
case KEY_ED25519:
case KEY_ECDSA_SK:
case KEY_ED25519_SK:
case KEY_XMSS:
if (have_agent || key != NULL)
sensitive_data.have_ssh2_key = 1;
break;
}
if ((fp = sshkey_fingerprint(pubkey, options.fingerprint_hash,
SSH_FP_DEFAULT)) == NULL)
fatal("sshkey_fingerprint failed");
debug("%s host key #%d: %s %s",
key ? "private" : "agent", i, sshkey_ssh_name(pubkey), fp);
free(fp);
}
accumulate_host_timing_secret(cfg, NULL);
if (!sensitive_data.have_ssh2_key) {
logit("sshd: no hostkeys available -- exiting.");
exit(1);
}
/*
* Load certificates. They are stored in an array at identical
* indices to the public keys that they relate to.
*/
sensitive_data.host_certificates = xcalloc(options.num_host_key_files,
sizeof(struct sshkey *));
for (i = 0; i < options.num_host_key_files; i++)
sensitive_data.host_certificates[i] = NULL;
for (i = 0; i < options.num_host_cert_files; i++) {
if (options.host_cert_files[i] == NULL)
continue;
if ((r = sshkey_load_public(options.host_cert_files[i],
&key, NULL)) != 0) {
error_r(r, "Could not load host certificate \"%s\"",
options.host_cert_files[i]);
continue;
}
if (!sshkey_is_cert(key)) {
error("Certificate file is not a certificate: %s",
options.host_cert_files[i]);
sshkey_free(key);
continue;
}
/* Find matching private key */
for (j = 0; j < options.num_host_key_files; j++) {
if (sshkey_equal_public(key,
sensitive_data.host_pubkeys[j])) {
sensitive_data.host_certificates[j] = key;
break;
}
}
if (j >= options.num_host_key_files) {
error("No matching private key for certificate: %s",
options.host_cert_files[i]);
sshkey_free(key);
continue;
}
sensitive_data.host_certificates[j] = key;
debug("host certificate: #%u type %d %s", j, key->type,
sshkey_type(key));
}
if (privsep_chroot) {
struct stat st;
if ((stat(_PATH_PRIVSEP_CHROOT_DIR, &st) == -1) ||
(S_ISDIR(st.st_mode) == 0))
fatal("Missing privilege separation directory: %s",
_PATH_PRIVSEP_CHROOT_DIR);
#ifdef HAVE_CYGWIN
if (check_ntsec(_PATH_PRIVSEP_CHROOT_DIR) &&
(st.st_uid != getuid () ||
(st.st_mode & (S_IWGRP|S_IWOTH)) != 0))
#else
if (st.st_uid != 0 || (st.st_mode & (S_IWGRP|S_IWOTH)) != 0)
#endif
fatal("%s must be owned by root and not group or "
"world-writable.", _PATH_PRIVSEP_CHROOT_DIR);
}
if (test_flag > 1) {
/*
* If no connection info was provided by -C then use
* use a blank one that will cause no predicate to match.
*/
if (connection_info == NULL)
connection_info = get_connection_info(ssh, 0, 0);
connection_info->test = 1;
parse_server_match_config(&options, &includes, connection_info);
dump_config(&options);
}
/* Configuration looks good, so exit if in test mode. */
if (test_flag)
exit(0);
/*
* Clear out any supplemental groups we may have inherited. This
* prevents inadvertent creation of files with bad modes (in the
* portable version at least, it's certainly possible for PAM
* to create a file, and we can't control the code in every
* module which might be used).
*/
if (setgroups(0, NULL) < 0)
debug("setgroups() failed: %.200s", strerror(errno));
if (rexec_flag) {
if (rexec_argc < 0)
fatal("rexec_argc %d < 0", rexec_argc);
rexec_argv = xcalloc(rexec_argc + 2, sizeof(char *));
for (i = 0; i < (u_int)rexec_argc; i++) {
debug("rexec_argv[%d]='%s'", i, saved_argv[i]);
rexec_argv[i] = saved_argv[i];
}
rexec_argv[rexec_argc] = "-R";
rexec_argv[rexec_argc + 1] = NULL;
}
listener_proctitle = prepare_proctitle(ac, av);
/* Ensure that umask disallows at least group and world write */
new_umask = umask(0077) | 0022;
(void) umask(new_umask);
/* 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);
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
* daemonized (eg re-exec via SIGHUP), disconnect from the controlling
* terminal, and fork. The original process exits.
*/
already_daemon = daemonized();
if (!(debug_flag || inetd_flag || no_daemon_flag || already_daemon)) {
if (daemon(0, 0) == -1)
fatal("daemon() failed: %.200s", strerror(errno));
disconnect_controlling_tty();
}
/* Reinitialize the log (because of the fork above). */
log_init(__progname, options.log_level, options.log_facility, log_stderr);
#ifdef LIBWRAP
/*
* We log refusals ourselves. However, libwrap will report
* syntax errors in hosts.allow via syslog(3).
*/
allow_severity = options.log_facility|LOG_INFO;
deny_severity = options.log_facility|LOG_WARNING;
#endif
/* Avoid killing the process in high-pressure swapping environments. */
if (!inetd_flag && madvise(NULL, 0, MADV_PROTECT) != 0)
debug("madvise(): %.200s", strerror(errno));
/*
* Chdir to the root directory so that the current disk can be
* unmounted if desired.
*/
if (chdir("/") == -1)
error("chdir(\"/\"): %s", strerror(errno));
/* ignore SIGPIPE */
ssh_signal(SIGPIPE, SIG_IGN);
/* Get a connection, either from inetd or a listening TCP socket */
if (inetd_flag) {
server_accept_inetd(&sock_in, &sock_out);
} else {
platform_pre_listen();
server_listen();
ssh_signal(SIGHUP, sighup_handler);
ssh_signal(SIGCHLD, main_sigchld_handler);
ssh_signal(SIGTERM, sigterm_handler);
ssh_signal(SIGQUIT, sigterm_handler);
/*
* Write out the pid file after the sigterm handler
* is setup and the listen sockets are bound
*/
if (options.pid_file != NULL && !debug_flag) {
FILE *f = fopen(options.pid_file, "w");
if (f == NULL) {
error("Couldn't create pid file \"%s\": %s",
options.pid_file, strerror(errno));
} else {
fprintf(f, "%ld\n", (long) getpid());
fclose(f);
}
}
/* Accept a connection and return in a forked child */
server_accept_loop(&sock_in, &sock_out,
&newsock, config_s);
}
/* This is the child processing a new connection. */
setproctitle("%s", "[accepted]");
/*
* Create a new session and process group since the 4.4BSD
* setlogin() affects the entire process group. We don't
* want the child to be able to affect the parent.
*/
if (!debug_flag && !inetd_flag && setsid() == -1)
error("setsid: %.100s", strerror(errno));
if (rexec_flag) {
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);
dup2(STDIN_FILENO, STDOUT_FILENO);
if (startup_pipe == -1)
close(REEXEC_STARTUP_PIPE_FD);
else if (startup_pipe != REEXEC_STARTUP_PIPE_FD) {
dup2(startup_pipe, REEXEC_STARTUP_PIPE_FD);
close(startup_pipe);
startup_pipe = REEXEC_STARTUP_PIPE_FD;
}
dup2(config_s[1], REEXEC_CONFIG_PASS_FD);
close(config_s[1]);
ssh_signal(SIGHUP, SIG_IGN); /* avoid reset to SIG_DFL */
execv(rexec_argv[0], rexec_argv);
/* Reexec has failed, fall back and continue */
error("rexec of %s failed: %s", rexec_argv[0], strerror(errno));
recv_rexec_state(REEXEC_CONFIG_PASS_FD, NULL);
log_init(__progname, options.log_level,
options.log_facility, log_stderr);
/* Clean up fds */
close(REEXEC_CONFIG_PASS_FD);
newsock = sock_out = sock_in = dup(STDIN_FILENO);
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]);
}
/* Executed child processes don't need these. */
fcntl(sock_out, F_SETFD, FD_CLOEXEC);
fcntl(sock_in, F_SETFD, FD_CLOEXEC);
/* We will not restart on SIGHUP since it no longer makes sense. */
ssh_signal(SIGALRM, SIG_DFL);
ssh_signal(SIGHUP, SIG_DFL);
ssh_signal(SIGTERM, SIG_DFL);
ssh_signal(SIGQUIT, SIG_DFL);
ssh_signal(SIGCHLD, SIG_DFL);
ssh_signal(SIGINT, SIG_DFL);
#ifdef __FreeBSD__
/*
* Initialize the resolver. This may not happen automatically
* before privsep chroot().
*/
if ((_res.options & RES_INIT) == 0) {
debug("res_init()");
res_init();
}
#ifdef GSSAPI
/*
* Force GSS-API to parse its configuration and load any
* mechanism plugins.
*/
{
gss_OID_set mechs;
OM_uint32 minor_status;
gss_indicate_mechs(&minor_status, &mechs);
gss_release_oid_set(&minor_status, &mechs);
}
#endif
#endif
/*
* Register our connection. This turns encryption off because we do
* not have a key.
*/
if ((ssh = ssh_packet_set_connection(NULL, sock_in, sock_out)) == NULL)
fatal("Unable to create connection");
the_active_state = ssh;
ssh_packet_set_server(ssh);
check_ip_options(ssh);
/* Prepare the channels layer */
channel_init_channels(ssh);
channel_set_af(ssh, options.address_family);
+ process_channel_timeouts(ssh, &options);
process_permitopen(ssh, &options);
/* Set SO_KEEPALIVE if requested. */
if (options.tcp_keep_alive && ssh_packet_connection_is_on_socket(ssh) &&
setsockopt(sock_in, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)) == -1)
error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno));
if ((remote_port = ssh_remote_port(ssh)) < 0) {
debug("ssh_remote_port failed");
cleanup_exit(255);
}
if (options.routing_domain != NULL)
set_process_rdomain(ssh, options.routing_domain);
/*
* The rest of the code depends on the fact that
* ssh_remote_ipaddr() caches the remote ip, even if
* the socket goes away.
*/
remote_ip = ssh_remote_ipaddr(ssh);
#ifdef HAVE_LOGIN_CAP
/* Also caches remote hostname for sandboxed child. */
auth_get_canonical_hostname(ssh, options.use_dns);
#endif
#ifdef SSH_AUDIT_EVENTS
audit_connection_from(remote_ip, remote_port);
#endif
rdomain = ssh_packet_rdomain_in(ssh);
/* Log the connection. */
laddr = get_local_ipaddr(sock_in);
verbose("Connection from %s port %d on %s port %d%s%s%s",
remote_ip, remote_port, laddr, ssh_local_port(ssh),
rdomain == NULL ? "" : " rdomain \"",
rdomain == NULL ? "" : rdomain,
rdomain == NULL ? "" : "\"");
free(laddr);
/*
* We don't want to listen forever unless the other side
* successfully authenticates itself. So we set up an alarm which is
* cleared after successful authentication. A limit of zero
* indicates no limit. Note that we don't set the alarm in debugging
* mode; it is just annoying to have the server exit just when you
* are about to discover the bug.
*/
ssh_signal(SIGALRM, grace_alarm_handler);
if (!debug_flag)
alarm(options.login_grace_time);
if ((r = kex_exchange_identification(ssh, -1,
options.version_addendum)) != 0)
sshpkt_fatal(ssh, r, "banner exchange");
ssh_packet_set_nonblocking(ssh);
/* allocate authentication context */
authctxt = xcalloc(1, sizeof(*authctxt));
ssh->authctxt = authctxt;
authctxt->loginmsg = loginmsg;
/* XXX global for cleanup, access from other modules */
the_authctxt = authctxt;
/* Set default key authentication options */
if ((auth_opts = sshauthopt_new_with_keys_defaults()) == NULL)
fatal("allocation failed");
/* prepare buffer to collect messages to display to user after login */
if ((loginmsg = sshbuf_new()) == NULL)
fatal_f("sshbuf_new failed");
auth_debug_reset();
BLACKLIST_INIT();
if (use_privsep) {
if (privsep_preauth(ssh) == 1)
goto authenticated;
} else if (have_agent) {
if ((r = ssh_get_authentication_socket(&auth_sock)) != 0) {
error_r(r, "Unable to get agent socket");
have_agent = 0;
}
}
/* perform the key exchange */
/* authenticate user and start session */
do_ssh2_kex(ssh);
do_authentication2(ssh);
/*
* If we use privilege separation, the unprivileged child transfers
* the current keystate and exits
*/
if (use_privsep) {
mm_send_keystate(ssh, pmonitor);
ssh_packet_clear_keys(ssh);
exit(0);
}
authenticated:
/*
* Cancel the alarm we set to limit the time taken for
* authentication.
*/
alarm(0);
ssh_signal(SIGALRM, SIG_DFL);
authctxt->authenticated = 1;
if (startup_pipe != -1) {
close(startup_pipe);
startup_pipe = -1;
}
#ifdef SSH_AUDIT_EVENTS
audit_event(ssh, SSH_AUTH_SUCCESS);
#endif
#ifdef GSSAPI
if (options.gss_authentication) {
temporarily_use_uid(authctxt->pw);
ssh_gssapi_storecreds();
restore_uid();
}
#endif
#ifdef USE_PAM
if (options.use_pam) {
do_pam_setcred(1);
do_pam_session(ssh);
}
#endif
/*
* In privilege separation, we fork another child and prepare
* file descriptor passing.
*/
if (use_privsep) {
privsep_postauth(ssh, authctxt);
/* the monitor process [priv] will not return */
}
ssh_packet_set_timeout(ssh, options.client_alive_interval,
options.client_alive_count_max);
/* Try to send all our hostkeys to the client */
notify_hostkeys(ssh);
/* Start session. */
do_authenticated(ssh, authctxt);
/* The connection has been terminated. */
ssh_packet_get_bytes(ssh, &ibytes, &obytes);
verbose("Transferred: sent %llu, received %llu bytes",
(unsigned long long)obytes, (unsigned long long)ibytes);
verbose("Closing connection to %.500s port %d", remote_ip, remote_port);
#ifdef USE_PAM
if (options.use_pam)
finish_pam();
#endif /* USE_PAM */
#ifdef SSH_AUDIT_EVENTS
PRIVSEP(audit_event(ssh, SSH_CONNECTION_CLOSE));
#endif
ssh_packet_close(ssh);
if (use_privsep)
mm_terminate();
exit(0);
}
int
sshd_hostkey_sign(struct ssh *ssh, struct sshkey *privkey,
struct sshkey *pubkey, u_char **signature, size_t *slenp,
const u_char *data, size_t dlen, const char *alg)
{
int r;
if (use_privsep) {
if (privkey) {
if (mm_sshkey_sign(ssh, privkey, signature, slenp,
data, dlen, alg, options.sk_provider, NULL,
ssh->compat) < 0)
fatal_f("privkey sign failed");
} else {
if (mm_sshkey_sign(ssh, pubkey, signature, slenp,
data, dlen, alg, options.sk_provider, NULL,
ssh->compat) < 0)
fatal_f("pubkey sign failed");
}
} else {
if (privkey) {
if (sshkey_sign(privkey, signature, slenp, data, dlen,
alg, options.sk_provider, NULL, ssh->compat) < 0)
fatal_f("privkey sign failed");
} else {
if ((r = ssh_agent_sign(auth_sock, pubkey,
signature, slenp, data, dlen, alg,
ssh->compat)) != 0) {
fatal_fr(r, "agent sign failed");
}
}
}
return 0;
}
/* SSH2 key exchange */
static void
do_ssh2_kex(struct ssh *ssh)
{
char *myproposal[PROPOSAL_MAX] = { KEX_SERVER };
struct kex *kex;
char *prop_kex = NULL, *prop_enc = NULL, *prop_hostkey = NULL;
int r;
myproposal[PROPOSAL_KEX_ALGS] = prop_kex = compat_kex_proposal(ssh,
options.kex_algorithms);
myproposal[PROPOSAL_ENC_ALGS_CTOS] =
myproposal[PROPOSAL_ENC_ALGS_STOC] = prop_enc =
compat_cipher_proposal(ssh, options.ciphers);
myproposal[PROPOSAL_MAC_ALGS_CTOS] =
myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs;
if (options.compression == COMP_NONE) {
myproposal[PROPOSAL_COMP_ALGS_CTOS] =
myproposal[PROPOSAL_COMP_ALGS_STOC] = "none";
}
if (options.rekey_limit || options.rekey_interval)
ssh_packet_set_rekey_limits(ssh, options.rekey_limit,
options.rekey_interval);
myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = prop_hostkey =
compat_pkalg_proposal(ssh, list_hostkey_types());
/* start key exchange */
if ((r = kex_setup(ssh, myproposal)) != 0)
fatal_r(r, "kex_setup");
kex = ssh->kex;
#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;
# ifdef OPENSSL_HAS_ECC
kex->kex[KEX_ECDH_SHA2] = kex_gen_server;
# endif
#endif
kex->kex[KEX_C25519_SHA256] = kex_gen_server;
kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_server;
kex->load_host_public_key=&get_hostkey_public_by_type;
kex->load_host_private_key=&get_hostkey_private_by_type;
kex->host_key_index=&get_hostkey_index;
kex->sign = sshd_hostkey_sign;
ssh_dispatch_run_fatal(ssh, DISPATCH_BLOCK, &kex->done);
#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_fr(r, "send test");
#endif
free(prop_kex);
free(prop_enc);
free(prop_hostkey);
debug("KEX done");
}
/* server specific fatal cleanup */
void
cleanup_exit(int i)
{
if (the_active_state != NULL && the_authctxt != NULL) {
do_cleanup(the_active_state, the_authctxt);
if (use_privsep && privsep_is_preauth &&
pmonitor != NULL && pmonitor->m_pid > 1) {
debug("Killing privsep child %d", pmonitor->m_pid);
if (kill(pmonitor->m_pid, SIGKILL) != 0 &&
errno != ESRCH) {
error_f("kill(%d): %s", pmonitor->m_pid,
strerror(errno));
}
}
}
#ifdef SSH_AUDIT_EVENTS
/* done after do_cleanup so it can cancel the PAM auth 'thread' */
if (the_active_state != NULL && (!use_privsep || mm_is_monitor()))
audit_event(the_active_state, SSH_CONNECTION_ABANDON);
#endif
_exit(i);
}
diff --git a/crypto/openssh/sshd_config b/crypto/openssh/sshd_config
index 4e9fb5e766d2..5e7cdbdfe04f 100644
--- a/crypto/openssh/sshd_config
+++ b/crypto/openssh/sshd_config
@@ -1,121 +1,121 @@
# $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.
# This sshd was compiled with PATH=/usr/bin:/bin:/usr/sbin:/sbin
# The strategy used for options in the default sshd_config shipped with
# OpenSSH is to specify options with their default value where
# possible, but leave them commented. Uncommented options override the
# default value.
# Note that some of FreeBSD's defaults differ from OpenBSD's, and
# FreeBSD has a few additional options.
#Port 22
#AddressFamily any
#ListenAddress 0.0.0.0
#ListenAddress ::
#HostKey /etc/ssh/ssh_host_rsa_key
#HostKey /etc/ssh/ssh_host_ecdsa_key
#HostKey /etc/ssh/ssh_host_ed25519_key
# Ciphers and keying
#RekeyLimit default none
# Logging
#SyslogFacility AUTH
#LogLevel INFO
# Authentication:
#LoginGraceTime 2m
#PermitRootLogin no
#StrictModes yes
#MaxAuthTries 6
#MaxSessions 10
#PubkeyAuthentication yes
# The default is to check both .ssh/authorized_keys and .ssh/authorized_keys2
# but this is overridden so installations will only check .ssh/authorized_keys
AuthorizedKeysFile .ssh/authorized_keys
#AuthorizedPrincipalsFile none
#AuthorizedKeysCommand none
#AuthorizedKeysCommandUser nobody
# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
#HostbasedAuthentication no
# Change to yes if you don't trust ~/.ssh/known_hosts for
# HostbasedAuthentication
#IgnoreUserKnownHosts no
# Don't read the user's ~/.rhosts and ~/.shosts files
#IgnoreRhosts yes
# Change to yes to enable built-in password authentication.
# Note that passwords may also be accepted via KbdInteractiveAuthentication.
#PasswordAuthentication no
#PermitEmptyPasswords no
# Change to no to disable PAM authentication
#KbdInteractiveAuthentication yes
# Kerberos options
#KerberosAuthentication no
#KerberosOrLocalPasswd yes
#KerberosTicketCleanup yes
#KerberosGetAFSToken no
# GSSAPI options
#GSSAPIAuthentication no
#GSSAPICleanupCredentials yes
# Set this to 'no' to disable PAM authentication, account processing,
# and session processing. If this is enabled, PAM authentication will
# be allowed through the KbdInteractiveAuthentication and
# PasswordAuthentication. Depending on your PAM configuration,
# PAM authentication via KbdInteractiveAuthentication may bypass
# the setting of "PermitRootLogin prohibit-password".
# If you just want the PAM account and session checks to run without
# PAM authentication, then enable this but set PasswordAuthentication
# and KbdInteractiveAuthentication to 'no'.
#UsePAM yes
#AllowAgentForwarding yes
#AllowTcpForwarding yes
#GatewayPorts no
#X11Forwarding yes
#X11DisplayOffset 10
#X11UseLocalhost yes
#PermitTTY yes
#PrintMotd yes
#PrintLastLog yes
#TCPKeepAlive yes
#PermitUserEnvironment no
#Compression delayed
#ClientAliveInterval 0
#ClientAliveCountMax 3
#UseDNS yes
#PidFile /var/run/sshd.pid
#MaxStartups 10:30:100
#PermitTunnel no
#ChrootDirectory none
#UseBlacklist no
-#VersionAddendum FreeBSD-20221019
+#VersionAddendum FreeBSD-20230205
# no default banner path
#Banner none
# override default of no subsystems
Subsystem sftp /usr/libexec/sftp-server
# Example of overriding settings on a per-user basis
#Match User anoncvs
# X11Forwarding no
# AllowTcpForwarding no
# PermitTTY no
# ForceCommand cvs server
diff --git a/crypto/openssh/sshd_config.5 b/crypto/openssh/sshd_config.5
index fa941b529bf6..2c1ef0e7a56c 100644
--- a/crypto/openssh/sshd_config.5
+++ b/crypto/openssh/sshd_config.5
@@ -1,2017 +1,2115 @@
.\"
.\" Author: Tatu Ylonen <ylo@cs.hut.fi>
.\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
.\" All rights reserved
.\"
.\" As far as I am concerned, the code I have written for this software
.\" can be used freely for any purpose. Any derived versions of this
.\" software must be clearly marked as such, and if the derived work is
.\" incompatible with the protocol description in the RFC file, it must be
.\" called by a name other than "ssh" or "Secure Shell".
.\"
.\" Copyright (c) 1999,2000 Markus Friedl. All rights reserved.
.\" Copyright (c) 1999 Aaron Campbell. All rights reserved.
.\" Copyright (c) 1999 Theo de Raadt. All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.\" $OpenBSD: sshd_config.5,v 1.343 2022/09/17 10:34:29 djm Exp $
-.Dd $Mdocdate: September 17 2022 $
+.\" $OpenBSD: sshd_config.5,v 1.347 2023/01/18 06:55:32 jmc Exp $
+.Dd $Mdocdate: January 18 2023 $
.Dt SSHD_CONFIG 5
.Os
.Sh NAME
.Nm sshd_config
.Nd OpenSSH daemon configuration file
.Sh DESCRIPTION
.Xr sshd 8
reads configuration data from
.Pa /etc/ssh/sshd_config
(or the file specified with
.Fl f
on the command line).
The file contains keyword-argument pairs, one per line.
For each keyword, the first obtained value will be used.
Lines starting with
.Ql #
and empty lines are interpreted as comments.
Arguments may optionally be enclosed in double quotes
.Pq \&"
in order to represent arguments containing spaces.
.Pp
The possible
keywords and their meanings are as follows (note that
keywords are case-insensitive and arguments are case-sensitive):
.Bl -tag -width Ds
.It Cm AcceptEnv
Specifies what environment variables sent by the client will be copied into
the session's
.Xr environ 7 .
See
.Cm SendEnv
and
.Cm SetEnv
in
.Xr ssh_config 5
for how to configure the client.
The
.Ev TERM
environment variable is always accepted whenever the client
requests a pseudo-terminal as it is required by the protocol.
Variables are specified by name, which may contain the wildcard characters
.Ql *
and
.Ql \&? .
Multiple environment variables may be separated by whitespace or spread
across multiple
.Cm AcceptEnv
directives.
Be warned that some environment variables could be used to bypass restricted
user environments.
For this reason, care should be taken in the use of this directive.
The default is not to accept any environment variables.
.It Cm AddressFamily
Specifies which address family should be used by
.Xr sshd 8 .
Valid arguments are
.Cm any
(the default),
.Cm inet
(use IPv4 only), or
.Cm inet6
(use IPv6 only).
.It Cm AllowAgentForwarding
Specifies whether
.Xr ssh-agent 1
forwarding is permitted.
The default is
.Cm yes .
Note that disabling agent forwarding does not improve security
unless users are also denied shell access, as they can always install
their own forwarders.
.It Cm AllowGroups
This keyword can be followed by a list of group name patterns, separated
by spaces.
If specified, login is allowed only for users whose primary
group or supplementary group list matches one of the patterns.
Only group names are valid; a numerical group ID is not recognized.
By default, login is allowed for all groups.
The allow/deny groups directives are processed in the following order:
.Cm DenyGroups ,
.Cm AllowGroups .
.Pp
See PATTERNS in
.Xr ssh_config 5
for more information on patterns.
.It Cm AllowStreamLocalForwarding
Specifies whether StreamLocal (Unix-domain socket) forwarding is permitted.
The available options are
.Cm yes
(the default)
or
.Cm all
to allow StreamLocal forwarding,
.Cm no
to prevent all StreamLocal forwarding,
.Cm local
to allow local (from the perspective of
.Xr ssh 1 )
forwarding only or
.Cm remote
to allow remote forwarding only.
Note that disabling StreamLocal forwarding does not improve security unless
users are also denied shell access, as they can always install their
own forwarders.
.It Cm AllowTcpForwarding
Specifies whether TCP forwarding is permitted.
The available options are
.Cm yes
(the default)
or
.Cm all
to allow TCP forwarding,
.Cm no
to prevent all TCP forwarding,
.Cm local
to allow local (from the perspective of
.Xr ssh 1 )
forwarding only or
.Cm remote
to allow remote forwarding only.
Note that disabling TCP forwarding does not improve security unless
users are also denied shell access, as they can always install their
own forwarders.
.It Cm AllowUsers
This keyword can be followed by a list of user name patterns, separated
by spaces.
If specified, login is allowed only for user names that
match one of the patterns.
Only user names are valid; a numerical user ID is not recognized.
By default, login is allowed for all users.
If the pattern takes the form USER@HOST then USER and HOST
are separately checked, restricting logins to particular
users from particular hosts.
HOST criteria may additionally contain addresses to match in CIDR
address/masklen format.
The allow/deny users directives are processed in the following order:
.Cm DenyUsers ,
.Cm AllowUsers .
.Pp
See PATTERNS in
.Xr ssh_config 5
for more information on patterns.
.It Cm AuthenticationMethods
Specifies the authentication methods that must be successfully completed
for a user to be granted access.
This option must be followed by one or more lists of comma-separated
authentication method names, or by the single string
.Cm any
to indicate the default behaviour of accepting any single authentication
method.
If the default is overridden, then successful authentication requires
completion of every method in at least one of these lists.
.Pp
For example,
.Qq publickey,password publickey,keyboard-interactive
would require the user to complete public key authentication, followed by
either password or keyboard interactive authentication.
Only methods that are next in one or more lists are offered at each stage,
so for this example it would not be possible to attempt password or
keyboard-interactive authentication before public key.
.Pp
For keyboard interactive authentication it is also possible to
restrict authentication to a specific device by appending a
colon followed by the device identifier
.Cm bsdauth
or
.Cm pam .
depending on the server configuration.
For example,
.Qq keyboard-interactive:bsdauth
would restrict keyboard interactive authentication to the
.Cm bsdauth
device.
.Pp
If the publickey method is listed more than once,
.Xr sshd 8
verifies that keys that have been used successfully are not reused for
subsequent authentications.
For example,
.Qq publickey,publickey
requires successful authentication using two different public keys.
.Pp
Note that each authentication method listed should also be explicitly enabled
in the configuration.
.Pp
The available authentication methods are:
.Qq gssapi-with-mic ,
.Qq hostbased ,
.Qq keyboard-interactive ,
.Qq none
(used for access to password-less accounts when
.Cm PermitEmptyPasswords
is enabled),
.Qq password
and
.Qq publickey .
.It Cm AuthorizedKeysCommand
Specifies a program to be used to look up the user's public keys.
The program must be owned by root, not writable by group or others and
specified by an absolute path.
Arguments to
.Cm AuthorizedKeysCommand
accept the tokens described in the
.Sx TOKENS
section.
If no arguments are specified then the username of the target user is used.
.Pp
The program should produce on standard output zero or
more lines of authorized_keys output (see
.Sx AUTHORIZED_KEYS
in
.Xr sshd 8 ) .
.Cm AuthorizedKeysCommand
is tried after the usual
.Cm AuthorizedKeysFile
files and will not be executed if a matching key is found there.
By default, no
.Cm AuthorizedKeysCommand
is run.
.It Cm AuthorizedKeysCommandUser
Specifies the user under whose account the
.Cm AuthorizedKeysCommand
is run.
It is recommended to use a dedicated user that has no other role on the host
than running authorized keys commands.
If
.Cm AuthorizedKeysCommand
is specified but
.Cm AuthorizedKeysCommandUser
is not, then
.Xr sshd 8
will refuse to start.
.It Cm AuthorizedKeysFile
Specifies the file that contains the public keys used for user authentication.
The format is described in the AUTHORIZED_KEYS FILE FORMAT section of
.Xr sshd 8 .
Arguments to
.Cm AuthorizedKeysFile
accept the tokens described in the
.Sx TOKENS
section.
After expansion,
.Cm AuthorizedKeysFile
is taken to be an absolute path or one relative to the user's home
directory.
Multiple files may be listed, separated by whitespace.
Alternately this option may be set to
.Cm none
to skip checking for user keys in files.
The default is
.Qq .ssh/authorized_keys .ssh/authorized_keys2 .
.It Cm AuthorizedPrincipalsCommand
Specifies a program to be used to generate the list of allowed
certificate principals as per
.Cm AuthorizedPrincipalsFile .
The program must be owned by root, not writable by group or others and
specified by an absolute path.
Arguments to
.Cm AuthorizedPrincipalsCommand
accept the tokens described in the
.Sx TOKENS
section.
If no arguments are specified then the username of the target user is used.
.Pp
The program should produce on standard output zero or
more lines of
.Cm AuthorizedPrincipalsFile
output.
If either
.Cm AuthorizedPrincipalsCommand
or
.Cm AuthorizedPrincipalsFile
is specified, then certificates offered by the client for authentication
must contain a principal that is listed.
By default, no
.Cm AuthorizedPrincipalsCommand
is run.
.It Cm AuthorizedPrincipalsCommandUser
Specifies the user under whose account the
.Cm AuthorizedPrincipalsCommand
is run.
It is recommended to use a dedicated user that has no other role on the host
than running authorized principals commands.
If
.Cm AuthorizedPrincipalsCommand
is specified but
.Cm AuthorizedPrincipalsCommandUser
is not, then
.Xr sshd 8
will refuse to start.
.It Cm AuthorizedPrincipalsFile
Specifies a file that lists principal names that are accepted for
certificate authentication.
When using certificates signed by a key listed in
.Cm TrustedUserCAKeys ,
this file lists names, one of which must appear in the certificate for it
to be accepted for authentication.
Names are listed one per line preceded by key options (as described in
.Sx AUTHORIZED_KEYS FILE FORMAT
in
.Xr sshd 8 ) .
Empty lines and comments starting with
.Ql #
are ignored.
.Pp
Arguments to
.Cm AuthorizedPrincipalsFile
accept the tokens described in the
.Sx TOKENS
section.
After expansion,
.Cm AuthorizedPrincipalsFile
is taken to be an absolute path or one relative to the user's home directory.
The default is
.Cm none ,
i.e. not to use a principals file \(en in this case, the username
of the user must appear in a certificate's principals list for it to be
accepted.
.Pp
Note that
.Cm AuthorizedPrincipalsFile
is only used when authentication proceeds using a CA listed in
.Cm TrustedUserCAKeys
and is not consulted for certification authorities trusted via
.Pa ~/.ssh/authorized_keys ,
though the
.Cm principals=
key option offers a similar facility (see
.Xr sshd 8
for details).
.It Cm Banner
The contents of the specified file are sent to the remote user before
authentication is allowed.
If the argument is
.Cm none
then no banner is displayed.
By default, no banner is displayed.
.It Cm CASignatureAlgorithms
Specifies which algorithms are allowed for signing of certificates
by certificate authorities (CAs).
The default is:
.Bd -literal -offset indent
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 ChannelTimeout
+Specifies whether and how quickly
+.Xr sshd 8
+should close inactive channels.
+Timeouts are specified as one or more
+.Dq type=interval
+pairs separated by whitespace, where the
+.Dq type
+must be a channel type name (as described in the table below), optionally
+containing wildcard characters.
+.Pp
+The timeout value
+.Dq interval
+is specified in seconds or may use any of the units documented in the
+.Sx TIME FORMATS
+section.
+For example,
+.Dq session:*=5m
+would cause all sessions to terminate after five minutes of inactivity.
+Specifying a zero value disables the inactivity timeout.
+.Pp
+The available channel types include:
+.Bl -tag -width Ds
+.It Cm agent-connection
+Open connections to
+.Xr ssh-agent 1 .
+.It Cm direct-tcpip , Cm direct-streamlocal@openssh.com
+Open TCP or Unix socket (respectively) connections that have
+been established from a
+.Xr ssh 1
+local forwarding, i.e.\&
+.Cm LocalForward
+or
+.Cm DynamicForward .
+.It Cm forwarded-tcpip , Cm forwarded-streamlocal@openssh.com
+Open TCP or Unix socket (respectively) connections that have been
+established to a
+.Xr sshd 8
+listening on behalf of a
+.Xr ssh 1
+remote forwarding, i.e.\&
+.Cm RemoteForward .
+.It Cm session:command
+Command execution sessions.
+.It Cm session:shell
+Interactive shell sessions.
+.It Cm session:subsystem:...
+Subsystem sessions, e.g. for
+.Xr sftp 1 ,
+which could be identified as
+.Cm session:subsystem:sftp .
+.It Cm x11-connection
+Open X11 forwarding sessions.
+.El
+.Pp
+Note that in all the above cases, terminating an inactive session does not
+guarantee to remove all resources associated with the session, e.g. shell
+processes or X11 clients relating to the session may continue to execute.
+.Pp
+Moreover, terminating an inactive channel or session does not necessarily
+close the SSH connection, nor does it prevent a client from
+requesting another channel of the same type.
+In particular, expiring an inactive forwarding session does not prevent
+another identical forwarding from being subsequently created.
+See also
+.Cm UnusedConnectionTimeout ,
+which may be used in conjunction with this option.
+.Pp
+The default is not to expire channels of any type for inactivity.
.It Cm ChrootDirectory
Specifies the pathname of a directory to
.Xr chroot 2
to after authentication.
At session startup
.Xr sshd 8
checks that all components of the pathname are root-owned directories
which are not writable by any other user or group.
After the chroot,
.Xr sshd 8
changes the working directory to the user's home directory.
Arguments to
.Cm ChrootDirectory
accept the tokens described in the
.Sx TOKENS
section.
.Pp
The
.Cm ChrootDirectory
must contain the necessary files and directories to support the
user's session.
For an interactive session this requires at least a shell, typically
.Xr sh 1 ,
and basic
.Pa /dev
nodes such as
.Xr null 4 ,
.Xr zero 4 ,
.Xr stdin 4 ,
.Xr stdout 4 ,
.Xr stderr 4 ,
and
.Xr tty 4
devices.
For file transfer sessions using SFTP
no additional configuration of the environment is necessary if the in-process
sftp-server is used,
though sessions which use logging may require
.Pa /dev/log
inside the chroot directory on some operating systems (see
.Xr sftp-server 8
for details).
.Pp
For safety, it is very important that the directory hierarchy be
prevented from modification by other processes on the system (especially
those outside the jail).
Misconfiguration can lead to unsafe environments which
.Xr sshd 8
cannot detect.
.Pp
The default is
.Cm none ,
indicating not to
.Xr chroot 2 .
.It Cm Ciphers
Specifies the ciphers allowed.
Multiple ciphers must be comma-separated.
If the specified list begins with a
.Sq +
character, then the specified ciphers will be appended to the default set
instead of replacing them.
If the specified list begins with a
.Sq -
character, then the specified ciphers (including wildcards) will be removed
from the default set instead of replacing them.
If the specified list begins with a
.Sq ^
character, then the specified ciphers will be placed at the head of the
default set.
.Pp
The supported ciphers are:
.Pp
.Bl -item -compact -offset indent
.It
3des-cbc
.It
aes128-cbc
.It
aes192-cbc
.It
aes256-cbc
.It
aes128-ctr
.It
aes192-ctr
.It
aes256-ctr
.It
aes128-gcm@openssh.com
.It
aes256-gcm@openssh.com
.It
chacha20-poly1305@openssh.com
.El
.Pp
The default is:
.Bd -literal -offset indent
chacha20-poly1305@openssh.com,
aes128-ctr,aes192-ctr,aes256-ctr,
aes128-gcm@openssh.com,aes256-gcm@openssh.com
.Ed
.Pp
The list of available ciphers may also be obtained using
.Qq ssh -Q cipher .
.It Cm ClientAliveCountMax
Sets the number of client alive messages which may be sent without
.Xr sshd 8
receiving any messages back from the client.
If this threshold is reached while client alive messages are being sent,
sshd will disconnect the client, terminating the session.
It is important to note that the use of client alive messages is very
different from
.Cm TCPKeepAlive .
The client alive messages are sent through the encrypted channel
and therefore will not be spoofable.
The TCP keepalive option enabled by
.Cm TCPKeepAlive
is spoofable.
The client alive mechanism is valuable when the client or
server depend on knowing when a connection has become unresponsive.
.Pp
The default value is 3.
If
.Cm ClientAliveInterval
is set to 15, and
.Cm ClientAliveCountMax
is left at the default, unresponsive SSH clients
will be disconnected after approximately 45 seconds.
Setting a zero
.Cm ClientAliveCountMax
disables connection termination.
.It Cm ClientAliveInterval
Sets a timeout interval in seconds after which if no data has been received
from the client,
.Xr sshd 8
will send a message through the encrypted
channel to request a response from the client.
The default
is 0, indicating that these messages will not be sent to the client.
.It Cm Compression
Specifies whether compression is enabled after
the user has authenticated successfully.
The argument must be
.Cm yes ,
.Cm delayed
(a legacy synonym for
.Cm yes )
or
.Cm no .
The default is
.Cm yes .
.It Cm DenyGroups
This keyword can be followed by a list of group name patterns, separated
by spaces.
Login is disallowed for users whose primary group or supplementary
group list matches one of the patterns.
Only group names are valid; a numerical group ID is not recognized.
By default, login is allowed for all groups.
The allow/deny groups directives are processed in the following order:
.Cm DenyGroups ,
.Cm AllowGroups .
.Pp
See PATTERNS in
.Xr ssh_config 5
for more information on patterns.
.It Cm DenyUsers
This keyword can be followed by a list of user name patterns, separated
by spaces.
Login is disallowed for user names that match one of the patterns.
Only user names are valid; a numerical user ID is not recognized.
By default, login is allowed for all users.
If the pattern takes the form USER@HOST then USER and HOST
are separately checked, restricting logins to particular
users from particular hosts.
HOST criteria may additionally contain addresses to match in CIDR
address/masklen format.
The allow/deny users directives are processed in the following order:
.Cm DenyUsers ,
.Cm AllowUsers .
.Pp
See PATTERNS in
.Xr ssh_config 5
for more information on patterns.
.It Cm DisableForwarding
Disables all forwarding features, including X11,
.Xr ssh-agent 1 ,
TCP and StreamLocal.
This option overrides all other forwarding-related options and may
simplify restricted configurations.
.It Cm ExposeAuthInfo
Writes a temporary file containing a list of authentication methods and
public credentials (e.g. keys) used to authenticate the user.
The location of the file is exposed to the user session through the
.Ev SSH_USER_AUTH
environment variable.
The default is
.Cm no .
.It Cm FingerprintHash
Specifies the hash algorithm used when logging key fingerprints.
Valid options are:
.Cm md5
and
.Cm sha256 .
The default is
.Cm sha256 .
.It Cm ForceCommand
Forces the execution of the command specified by
.Cm ForceCommand ,
ignoring any command supplied by the client and
.Pa ~/.ssh/rc
if present.
The command is invoked by using the user's login shell with the -c option.
This applies to shell, command, or subsystem execution.
It is most useful inside a
.Cm Match
block.
The command originally supplied by the client is available in the
.Ev SSH_ORIGINAL_COMMAND
environment variable.
Specifying a command of
.Cm internal-sftp
will force the use of an in-process SFTP server that requires no support
files when used with
.Cm ChrootDirectory .
The default is
.Cm none .
.It Cm GatewayPorts
Specifies whether remote hosts are allowed to connect to ports
forwarded for the client.
By default,
.Xr sshd 8
binds remote port forwardings to the loopback address.
This prevents other remote hosts from connecting to forwarded ports.
.Cm GatewayPorts
can be used to specify that sshd
should allow remote port forwardings to bind to non-loopback addresses, thus
allowing other hosts to connect.
The argument may be
.Cm no
to force remote port forwardings to be available to the local host only,
.Cm yes
to force remote port forwardings to bind to the wildcard address, or
.Cm clientspecified
to allow the client to select the address to which the forwarding is bound.
The default is
.Cm no .
.It Cm GSSAPIAuthentication
Specifies whether user authentication based on GSSAPI is allowed.
The default is
.Cm no .
.It Cm GSSAPICleanupCredentials
Specifies whether to automatically destroy the user's credentials cache
on logout.
The default is
.Cm yes .
.It Cm GSSAPIStrictAcceptorCheck
Determines whether to be strict about the identity of the GSSAPI acceptor
a client authenticates against.
If set to
.Cm yes
then the client must authenticate against the host
service on the current hostname.
If set to
.Cm no
then the client may authenticate against any service key stored in the
machine's default store.
This facility is provided to assist with operation on multi homed machines.
The default is
.Cm yes .
.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 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 signature algorithms (including wildcards)
will be removed from the default set instead of replacing them.
If the specified list begins with a
.Sq ^
character, then the specified signature algorithms will be placed at
the head of the default set.
The default for this option is:
.Bd -literal -offset 3n
ssh-ed25519-cert-v01@openssh.com,
ecdsa-sha2-nistp256-cert-v01@openssh.com,
ecdsa-sha2-nistp384-cert-v01@openssh.com,
ecdsa-sha2-nistp521-cert-v01@openssh.com,
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,
rsa-sha2-512,rsa-sha2-256,ssh-rsa
.Ed
.Pp
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
(host-based authentication).
The default is
.Cm no .
.It Cm HostbasedUsesNameFromPacketOnly
Specifies whether or not the server will attempt to perform a reverse
name lookup when matching the name in the
.Pa ~/.shosts ,
.Pa ~/.rhosts ,
and
.Pa /etc/hosts.equiv
files during
.Cm HostbasedAuthentication .
A setting of
.Cm yes
means that
.Xr sshd 8
uses the name supplied by the client rather than
attempting to resolve the name from the TCP connection itself.
The default is
.Cm no .
.It Cm HostCertificate
Specifies a file containing a public host certificate.
The certificate's public key must match a private host key already specified
by
.Cm HostKey .
The default behaviour of
.Xr sshd 8
is not to load any certificates.
.It Cm HostKey
Specifies a file containing a private host key
used by SSH.
The defaults are
.Pa /etc/ssh/ssh_host_ecdsa_key ,
.Pa /etc/ssh/ssh_host_ed25519_key
and
.Pa /etc/ssh/ssh_host_rsa_key .
.Pp
Note that
.Xr sshd 8
will refuse to use a file if it is group/world-accessible
and that the
.Cm HostKeyAlgorithms
option restricts which of the keys are actually used by
.Xr sshd 8 .
.Pp
It is possible to have multiple host key files.
It is also possible to specify public host key files instead.
In this case operations on the private key will be delegated
to an
.Xr ssh-agent 1 .
.It Cm HostKeyAgent
Identifies the UNIX-domain socket used to communicate
with an agent that has access to the private host keys.
If the string
.Qq SSH_AUTH_SOCK
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 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-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,
rsa-sha2-512,rsa-sha2-256,ssh-rsa
.Ed
.Pp
The list of available signature algorithms may also be obtained using
.Qq ssh -Q HostKeyAlgorithms .
.It Cm IgnoreRhosts
Specifies whether to ignore per-user
.Pa .rhosts
and
.Pa .shosts
files during
.Cm HostbasedAuthentication .
The system-wide
.Pa /etc/hosts.equiv
and
.Pa /etc/ssh/shosts.equiv
are still used regardless of this setting.
.Pp
Accepted values are
.Cm yes
(the default) to ignore all per-user files,
.Cm shosts-only
to allow the use of
.Pa .shosts
but to ignore
.Pa .rhosts
or
.Cm no
to allow both
.Pa .shosts
and
.Pa rhosts .
.It Cm IgnoreUserKnownHosts
Specifies whether
.Xr sshd 8
should ignore the user's
.Pa ~/.ssh/known_hosts
during
.Cm HostbasedAuthentication
and use only the system-wide known hosts file
.Pa /etc/ssh/ssh_known_hosts .
The default is
.Dq no .
.It Cm Include
Include the specified configuration file(s).
Multiple pathnames may be specified and each pathname may contain
.Xr glob 7
wildcards that will be expanded and processed in lexical order.
Files without absolute paths are assumed to be in
.Pa /etc/ssh .
An
.Cm Include
directive may appear inside a
.Cm Match
block
to perform conditional inclusion.
.It Cm IPQoS
Specifies the IPv4 type-of-service or DSCP class for the connection.
Accepted values are
.Cm af11 ,
.Cm af12 ,
.Cm af13 ,
.Cm af21 ,
.Cm af22 ,
.Cm af23 ,
.Cm af31 ,
.Cm af32 ,
.Cm af33 ,
.Cm af41 ,
.Cm af42 ,
.Cm af43 ,
.Cm cs0 ,
.Cm cs1 ,
.Cm cs2 ,
.Cm cs3 ,
.Cm cs4 ,
.Cm cs5 ,
.Cm cs6 ,
.Cm cs7 ,
.Cm ef ,
.Cm le ,
.Cm lowdelay ,
.Cm throughput ,
.Cm reliability ,
a numeric value, or
.Cm none
to use the operating system default.
This option may take one or two arguments, separated by whitespace.
If one argument is specified, it is used as the packet class unconditionally.
If two values are specified, the first is automatically selected for
interactive sessions and the second for non-interactive sessions.
The default is
.Cm af21
(Low-Latency Data)
for interactive sessions and
.Cm cs1
(Lower Effort)
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 .
.Cm ChallengeResponseAuthentication
is a deprecated alias for this.
.It Cm KerberosAuthentication
Specifies whether the password provided by the user for
.Cm PasswordAuthentication
will be validated through the Kerberos KDC.
To use this option, the server needs a
Kerberos servtab which allows the verification of the KDC's identity.
The default is
.Cm no .
.It Cm KerberosGetAFSToken
If AFS is active and the user has a Kerberos 5 TGT, attempt to acquire
an AFS token before accessing the user's home directory.
The default is
.Cm no .
.It Cm KerberosOrLocalPasswd
If password authentication through Kerberos fails then
the password will be validated via any additional local mechanism
such as
.Pa /etc/passwd .
The default is
.Cm yes .
.It Cm KerberosTicketCleanup
Specifies whether to automatically destroy the user's ticket cache
file on logout.
The default is
.Cm yes .
.It Cm KexAlgorithms
Specifies the available KEX (Key Exchange) algorithms.
Multiple algorithms must be comma-separated.
Alternately 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.
If the specified list begins with a
.Sq ^
character, then the specified algorithms will be placed at the head of the
default set.
The supported algorithms are:
.Pp
.Bl -item -compact -offset indent
.It
curve25519-sha256
.It
curve25519-sha256@libssh.org
.It
diffie-hellman-group1-sha1
.It
diffie-hellman-group14-sha1
.It
diffie-hellman-group14-sha256
.It
diffie-hellman-group16-sha512
.It
diffie-hellman-group18-sha512
.It
diffie-hellman-group-exchange-sha1
.It
diffie-hellman-group-exchange-sha256
.It
ecdh-sha2-nistp256
.It
ecdh-sha2-nistp384
.It
ecdh-sha2-nistp521
.It
sntrup761x25519-sha512@openssh.com
.El
.Pp
The default is:
.Bd -literal -offset indent
sntrup761x25519-sha512@openssh.com,
curve25519-sha256,curve25519-sha256@libssh.org,
ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,
diffie-hellman-group-exchange-sha256,
diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,
diffie-hellman-group14-sha256
.Ed
.Pp
The list of available key exchange algorithms may also be obtained using
.Qq ssh -Q KexAlgorithms .
.It Cm ListenAddress
Specifies the local addresses
.Xr sshd 8
should listen on.
The following forms may be used:
.Pp
.Bl -item -offset indent -compact
.It
.Cm ListenAddress
.Sm off
.Ar hostname | address
.Sm on
.Op Cm rdomain Ar domain
.It
.Cm ListenAddress
.Sm off
.Ar hostname : port
.Sm on
.Op Cm rdomain Ar domain
.It
.Cm ListenAddress
.Sm off
.Ar IPv4_address : port
.Sm on
.Op Cm rdomain Ar domain
.It
.Cm ListenAddress
.Sm off
.Oo Ar hostname | address Oc : Ar port
.Sm on
.Op Cm rdomain Ar domain
.El
.Pp
The optional
.Cm rdomain
qualifier requests
.Xr sshd 8
listen in an explicit routing domain.
If
.Ar port
is not specified,
sshd will listen on the address and all
.Cm Port
options specified.
The default is to listen on all local addresses on the current default
routing domain.
Multiple
.Cm ListenAddress
options are permitted.
For more information on routing domains, see
.Xr rdomain 4 .
.It Cm LoginGraceTime
The server disconnects after this time if the user has not
successfully logged in.
If the value is 0, there is no time limit.
The default is 120 seconds.
.It Cm LogLevel
Gives the verbosity level that is used when logging messages from
.Xr sshd 8 .
The possible values are:
QUIET, FATAL, ERROR, INFO, VERBOSE, DEBUG, DEBUG1, DEBUG2, and DEBUG3.
The default is INFO.
DEBUG and DEBUG1 are equivalent.
DEBUG2 and DEBUG3 each specify higher levels of debugging output.
Logging with a DEBUG level violates the privacy of users and is not recommended.
.It Cm LogVerbose
Specify one or more overrides to LogLevel.
An override consists of a pattern lists that matches the source file, function
and line number to force detailed logging for.
For example, an override pattern of:
.Bd -literal -offset indent
kex.c:*:1000,*:kex_exchange_identification():*,packet.c:*
.Ed
.Pp
would enable detailed logging for line 1000 of
.Pa kex.c ,
everything in the
.Fn kex_exchange_identification
function, and all code in the
.Pa packet.c
file.
This option is intended for debugging and no overrides are enabled by default.
.It Cm MACs
Specifies the available MAC (message authentication code) algorithms.
The MAC algorithm is used for data integrity protection.
Multiple algorithms must be comma-separated.
If the specified 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.
If the specified list begins with a
.Sq ^
character, then the specified algorithms will be placed at the head of the
default set.
.Pp
The algorithms that contain
.Qq -etm
calculate the MAC after encryption (encrypt-then-mac).
These are considered safer and their use recommended.
The supported MACs are:
.Pp
.Bl -item -compact -offset indent
.It
hmac-md5
.It
hmac-md5-96
.It
hmac-sha1
.It
hmac-sha1-96
.It
hmac-sha2-256
.It
hmac-sha2-512
.It
umac-64@openssh.com
.It
umac-128@openssh.com
.It
hmac-md5-etm@openssh.com
.It
hmac-md5-96-etm@openssh.com
.It
hmac-sha1-etm@openssh.com
.It
hmac-sha1-96-etm@openssh.com
.It
hmac-sha2-256-etm@openssh.com
.It
hmac-sha2-512-etm@openssh.com
.It
umac-64-etm@openssh.com
.It
umac-128-etm@openssh.com
.El
.Pp
The default is:
.Bd -literal -offset indent
umac-64-etm@openssh.com,umac-128-etm@openssh.com,
hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,
hmac-sha1-etm@openssh.com,
umac-64@openssh.com,umac-128@openssh.com,
hmac-sha2-256,hmac-sha2-512,hmac-sha1
.Ed
.Pp
The list of available MAC algorithms may also be obtained using
.Qq ssh -Q mac .
.It Cm Match
Introduces a conditional block.
If all of the criteria on the
.Cm Match
line are satisfied, the keywords on the following lines override those
set in the global section of the config file, until either another
.Cm Match
line or the end of the file.
If a keyword appears in multiple
.Cm Match
blocks that are satisfied, only the first instance of the keyword is
applied.
.Pp
The arguments to
.Cm Match
are one or more criteria-pattern pairs or the single token
.Cm All
which matches all criteria.
The available criteria are
.Cm User ,
.Cm Group ,
.Cm Host ,
.Cm LocalAddress ,
.Cm LocalPort ,
.Cm RDomain ,
and
.Cm Address
(with
.Cm RDomain
representing the
.Xr rdomain 4
on which the connection was received).
.Pp
The match patterns may consist of single entries or comma-separated
lists and may use the wildcard and negation operators described in the
.Sx PATTERNS
section of
.Xr ssh_config 5 .
.Pp
The patterns in an
.Cm Address
criteria may additionally contain addresses to match in CIDR
address/masklen format,
such as 192.0.2.0/24 or 2001:db8::/32.
Note that the mask length provided must be consistent with the address -
it is an error to specify a mask length that is too long for the address
or one with bits set in this host portion of the address.
For example, 192.0.2.0/33 and 192.0.2.0/8, respectively.
.Pp
Only a subset of keywords may be used on the lines following a
.Cm Match
keyword.
Available keywords are
.Cm AcceptEnv ,
.Cm AllowAgentForwarding ,
.Cm AllowGroups ,
.Cm AllowStreamLocalForwarding ,
.Cm AllowTcpForwarding ,
.Cm AllowUsers ,
.Cm AuthenticationMethods ,
.Cm AuthorizedKeysCommand ,
.Cm AuthorizedKeysCommandUser ,
.Cm AuthorizedKeysFile ,
.Cm AuthorizedPrincipalsCommand ,
.Cm AuthorizedPrincipalsCommandUser ,
.Cm AuthorizedPrincipalsFile ,
.Cm Banner ,
.Cm CASignatureAlgorithms ,
+.Cm ChannelTimeout ,
.Cm ChrootDirectory ,
.Cm ClientAliveCountMax ,
.Cm ClientAliveInterval ,
.Cm DenyGroups ,
.Cm DenyUsers ,
.Cm DisableForwarding ,
.Cm ExposeAuthInfo ,
.Cm ForceCommand ,
.Cm GatewayPorts ,
.Cm GSSAPIAuthentication ,
.Cm HostbasedAcceptedAlgorithms ,
.Cm HostbasedAuthentication ,
.Cm HostbasedUsesNameFromPacketOnly ,
.Cm IgnoreRhosts ,
.Cm Include ,
.Cm IPQoS ,
.Cm KbdInteractiveAuthentication ,
.Cm KerberosAuthentication ,
.Cm LogLevel ,
.Cm MaxAuthTries ,
.Cm MaxSessions ,
.Cm PasswordAuthentication ,
.Cm PermitEmptyPasswords ,
.Cm PermitListen ,
.Cm PermitOpen ,
.Cm PermitRootLogin ,
.Cm PermitTTY ,
.Cm PermitTunnel ,
.Cm PermitUserRC ,
.Cm PubkeyAcceptedAlgorithms ,
.Cm PubkeyAuthentication ,
.Cm PubkeyAuthOptions ,
.Cm RekeyLimit ,
.Cm RevokedKeys ,
.Cm RDomain ,
.Cm SetEnv ,
.Cm StreamLocalBindMask ,
.Cm StreamLocalBindUnlink ,
.Cm TrustedUserCAKeys ,
+.Cm UnusedConnectionTimeout ,
.Cm X11DisplayOffset ,
.Cm X11Forwarding
and
.Cm X11UseLocalhost .
.It Cm MaxAuthTries
Specifies the maximum number of authentication attempts permitted per
connection.
Once the number of failures reaches half this value,
additional failures are logged.
The default is 6.
.It Cm MaxSessions
Specifies the maximum number of open shell, login or subsystem (e.g. sftp)
sessions permitted per network connection.
Multiple sessions may be established by clients that support connection
multiplexing.
Setting
.Cm MaxSessions
to 1 will effectively disable session multiplexing, whereas setting it to 0
will prevent all shell, login and subsystem sessions while still permitting
forwarding.
The default is 10.
.It Cm MaxStartups
Specifies the maximum number of concurrent unauthenticated connections to the
SSH daemon.
Additional connections will be dropped until authentication succeeds or the
.Cm LoginGraceTime
expires for a connection.
The default is 10:30:100.
.Pp
Alternatively, random early drop can be enabled by specifying
the three colon separated values
start:rate:full (e.g. "10:30:60").
.Xr sshd 8
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.
Note that passwords may also be accepted via
.Cm KbdInteractiveAuthentication .
See also
.Cm UsePAM .
The default is
.Cm no .
.It Cm PermitEmptyPasswords
When password authentication is allowed, it specifies whether the
server allows login to accounts with empty password strings.
The default is
.Cm no .
.It Cm PermitListen
Specifies the addresses/ports on which a remote TCP port forwarding may listen.
The listen specification must be one of the following forms:
.Pp
.Bl -item -offset indent -compact
.It
.Cm PermitListen
.Sm off
.Ar port
.Sm on
.It
.Cm PermitListen
.Sm off
.Ar host : port
.Sm on
.El
.Pp
Multiple permissions may be specified by separating them with whitespace.
An argument of
.Cm any
can be used to remove all restrictions and permit any listen requests.
An argument of
.Cm none
can be used to prohibit all listen requests.
The host name may contain wildcards as described in the PATTERNS section in
.Xr ssh_config 5 .
The wildcard
.Sq *
can also be used in place of a port number to allow all ports.
By default all port forwarding listen requests are permitted.
Note that the
.Cm GatewayPorts
option may further restrict which addresses may be listened on.
Note also that
.Xr ssh 1
will request a listen host of
.Dq localhost
if no listen host was specifically requested, and this name is
treated differently to explicit localhost addresses of
.Dq 127.0.0.1
and
.Dq ::1 .
.It Cm PermitOpen
Specifies the destinations to which TCP port forwarding is permitted.
The forwarding specification must be one of the following forms:
.Pp
.Bl -item -offset indent -compact
.It
.Cm PermitOpen
.Sm off
.Ar host : port
.Sm on
.It
.Cm PermitOpen
.Sm off
.Ar IPv4_addr : port
.Sm on
.It
.Cm PermitOpen
.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.
By default all port forwarding requests are permitted.
.It Cm PermitRootLogin
Specifies whether root can log in using
.Xr ssh 1 .
The argument must be
.Cm yes ,
.Cm prohibit-password ,
.Cm forced-commands-only ,
or
.Cm no .
The default is
.Cm no .
Note that if
.Cm ChallengeResponseAuthentication
and
.Cm UsePAM
are both
.Cm yes ,
this setting may be overridden by the PAM policy.
.Pp
If this option is set to
.Cm prohibit-password
(or its deprecated alias,
.Cm without-password ) ,
password and keyboard-interactive authentication are disabled for root.
.Pp
If this option is set to
.Cm forced-commands-only ,
root login with public key authentication will be allowed,
but only if the
.Ar command
option has been specified
(which may be useful for taking remote backups even if root login is
normally not allowed).
All other authentication methods are disabled for root.
.Pp
If this option is set to
.Cm no ,
root is not allowed to log in.
.It Cm PermitTTY
Specifies whether
.Xr pty 4
allocation is permitted.
The default is
.Cm yes .
.It Cm PermitTunnel
Specifies whether
.Xr tun 4
device forwarding is allowed.
The argument must be
.Cm yes ,
.Cm point-to-point
(layer 3),
.Cm ethernet
(layer 2), or
.Cm no .
Specifying
.Cm yes
permits both
.Cm point-to-point
and
.Cm ethernet .
The default is
.Cm no .
.Pp
Independent of this setting, the permissions of the selected
.Xr tun 4
device must allow access to the user.
.It Cm PermitUserEnvironment
Specifies whether
.Pa ~/.ssh/environment
and
.Cm environment=
options in
.Pa ~/.ssh/authorized_keys
are processed by
.Xr sshd 8 .
Valid options are
.Cm yes ,
.Cm no
or a pattern-list specifying which environment variable names to accept
(for example
.Qq LANG,LC_* ) .
The default is
.Cm no .
Enabling environment processing may enable users to bypass access
restrictions in some configurations using mechanisms such as
.Ev LD_PRELOAD .
.It Cm PermitUserRC
Specifies whether any
.Pa ~/.ssh/rc
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
.Cm none
to not write one.
The default is
.Pa /var/run/sshd.pid .
.It Cm Port
Specifies the port number that
.Xr sshd 8
listens on.
The default is 22.
Multiple options of this type are permitted.
See also
.Cm ListenAddress .
.It Cm PrintLastLog
Specifies whether
.Xr sshd 8
should print the date and time of the last user login when a user logs
in interactively.
The default is
.Cm yes .
.It Cm PrintMotd
Specifies whether
.Xr sshd 8
should print
.Pa /etc/motd
when a user logs in interactively.
(On some systems it is also printed by the shell,
.Pa /etc/profile ,
or equivalent.)
The default is
.Cm yes .
.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 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.
If the specified list begins with a
.Sq ^
character, then the specified algorithms will be placed at the head of the
default set.
The default for this option is:
.Bd -literal -offset 3n
ssh-ed25519-cert-v01@openssh.com,
ecdsa-sha2-nistp256-cert-v01@openssh.com,
ecdsa-sha2-nistp384-cert-v01@openssh.com,
ecdsa-sha2-nistp521-cert-v01@openssh.com,
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,
rsa-sha2-512,rsa-sha2-256,ssh-rsa
.Ed
.Pp
The list of available signature algorithms may also be obtained using
.Qq ssh -Q PubkeyAcceptedAlgorithms .
.It Cm PubkeyAuthOptions
Sets one or more public key authentication options.
The supported keywords are:
.Cm none
(the default; indicating no additional options are enabled),
.Cm touch-required
and
.Cm verify-required .
.Pp
The
.Cm touch-required
option causes public key authentication using a FIDO authenticator algorithm
(i.e.\&
.Cm ecdsa-sk
or
.Cm ed25519-sk )
to always require the signature to attest that a physically present user
explicitly confirmed the authentication (usually by touching the authenticator).
By default,
.Xr sshd 8
requires user presence unless overridden with an authorized_keys option.
The
.Cm touch-required
flag disables this override.
.Pp
The
.Cm verify-required
option requires a FIDO key signature attest that the user was verified,
e.g. via a PIN.
.Pp
Neither the
.Cm touch-required
or
.Cm verify-required
options have any effect for other, non-FIDO, public key types.
.It Cm PubkeyAuthentication
Specifies whether public key authentication is allowed.
The default is
.Cm yes .
.It Cm RekeyLimit
Specifies the maximum amount of data that may be transmitted or received
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
.Sq K ,
.Sq M ,
or
.Sq G
to indicate Kilobytes, Megabytes, or Gigabytes, respectively.
The default is between
.Sq 1G
and
.Sq 4G ,
depending on the cipher.
The optional second value is specified in seconds and may use any of the
units documented in the
.Sx TIME FORMATS
section.
The default value for
.Cm RekeyLimit
is
.Cm default none ,
which means that rekeying is performed after the cipher's default amount
of data has been sent or received and no time based rekeying is done.
.It Cm RequiredRSASize
Specifies the minimum RSA key size (in bits) that
.Xr sshd 8
will accept.
User and host-based authentication keys smaller than this limit will be
refused.
The default is
.Cm 1024
bits.
Note that this limit may only be raised from the default.
.It Cm RevokedKeys
Specifies revoked public keys file, or
.Cm none
to not use one.
Keys listed in this file will be refused for public key authentication.
Note that if this file is not readable, then public key authentication will
be refused for all users.
Keys may be specified as a text file, listing one public key per line, or as
an OpenSSH Key Revocation List (KRL) as generated by
.Xr ssh-keygen 1 .
For more information on KRLs, see the KEY REVOCATION LISTS section in
.Xr ssh-keygen 1 .
.It Cm RDomain
Specifies an explicit routing domain that is applied after authentication
has completed.
The user session, as well as any forwarded or listening IP sockets,
will be bound to this
.Xr rdomain 4 .
If the routing domain is set to
.Cm \&%D ,
then the domain in which the incoming connection was received will be applied.
.It Cm SecurityKeyProvider
Specifies a path to a library that will be used when loading
FIDO authenticator-hosted keys, overriding the default of using
the built-in USB HID support.
.It Cm SetEnv
Specifies one or more environment variables to set in child sessions started
by
.Xr sshd 8
as
.Dq NAME=VALUE .
The environment value may be quoted (e.g. if it contains whitespace
characters).
Environment variables set by
.Cm SetEnv
override the default environment and any variables specified by the user
via
.Cm AcceptEnv
or
.Cm PermitUserEnvironment .
.It Cm StreamLocalBindMask
Sets the octal file creation mode mask
.Pq umask
used when creating a Unix-domain socket file for local or remote
port forwarding.
This option is only used for port forwarding to a Unix-domain socket file.
.Pp
The default value is 0177, which creates a Unix-domain socket file that is
readable and writable only by the owner.
Note that not all operating systems honor the file mode on Unix-domain
socket files.
.It Cm StreamLocalBindUnlink
Specifies whether to remove an existing Unix-domain socket file for local
or remote port forwarding before creating a new one.
If the socket file already exists and
.Cm StreamLocalBindUnlink
is not enabled,
.Nm sshd
will be unable to forward the port to the Unix-domain socket file.
This option is only used for port forwarding to a Unix-domain socket file.
.Pp
The argument must be
.Cm yes
or
.Cm no .
The default is
.Cm no .
.It Cm StrictModes
Specifies whether
.Xr sshd 8
should check file modes and ownership of the
user's files and home directory before accepting login.
This is normally desirable because novices sometimes accidentally leave their
directory or files world-writable.
The default is
.Cm yes .
Note that this does not apply to
.Cm ChrootDirectory ,
whose permissions and ownership are checked unconditionally.
.It Cm Subsystem
Configures an external subsystem (e.g. file transfer daemon).
Arguments should be a subsystem name and a command (with optional arguments)
to execute upon subsystem request.
.Pp
The command
.Cm sftp-server
implements the SFTP file transfer subsystem.
.Pp
Alternately the name
.Cm internal-sftp
implements an in-process SFTP server.
This may simplify configurations using
.Cm ChrootDirectory
to force a different filesystem root on clients.
.Pp
By default no subsystems are defined.
.It Cm SyslogFacility
Gives the facility code that is used when logging messages from
.Xr sshd 8 .
The possible values are: DAEMON, USER, AUTH, LOCAL0, LOCAL1, LOCAL2,
LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7.
The default is AUTH.
.It Cm TCPKeepAlive
Specifies whether the system should send TCP keepalive messages to the
other side.
If they are sent, death of the connection or crash of one
of the machines will be properly noticed.
However, this means that
connections will die if the route is down temporarily, and some people
find it annoying.
On the other hand, if TCP keepalives are not sent,
sessions may hang indefinitely on the server, leaving
.Qq ghost
users and consuming server resources.
.Pp
The default is
.Cm yes
(to send TCP keepalive messages), and the server will notice
if the network goes down or the client host crashes.
This avoids infinitely hanging sessions.
.Pp
To disable TCP keepalive messages, the value should be set to
.Cm no .
.It Cm TrustedUserCAKeys
Specifies a file containing public keys of certificate authorities that are
trusted to sign user certificates for authentication, or
.Cm none
to not use one.
Keys are listed one per line; empty lines and comments starting with
.Ql #
are allowed.
If a certificate is presented for authentication and has its signing CA key
listed in this file, then it may be used for authentication for any user
listed in the certificate's principals list.
Note that certificates that lack a list of principals will not be permitted
for authentication using
.Cm TrustedUserCAKeys .
For more details on certificates, see the CERTIFICATES section in
.Xr ssh-keygen 1 .
+.It Cm UnusedConnectionTimeout
+Specifies whether and how quickly
+.Xr sshd 8
+should close client connections with no open channels.
+Open channels include active shell, command execution or subsystem
+sessions, connected network, socket, agent or X11 forwardings.
+Forwarding listeners, such as those from the
+.Xr ssh 1
+.Fl R
+flag, are not considered as open channels and do not prevent the timeout.
+The timeout value
+is specified in seconds or may use any of the units documented in the
+.Sx TIME FORMATS
+section.
+.Pp
+Note that this timeout starts when the client connection completes
+user authentication but before the client has an opportunity to open any
+channels.
+Caution should be used when using short timeout values, as they may not
+provide sufficient time for the client to request and open its channels
+before terminating the connection.
+.Pp
+The default
+.Cm none
+is to never expire connections for having no open channels.
+This option may be useful in conjunction with
+.Cm ChannelTimeout .
.It Cm UseBlacklist
Specifies whether
.Xr sshd 8
attempts to send authentication success and failure messages
to the
.Xr blacklistd 8
daemon.
The default is
.Cm no .
For forward compatibility with an upcoming
.Xr blacklistd
rename, the
.Cm UseBlocklist
alias can be used instead.
.It Cm UseDNS
Specifies whether
.Xr sshd 8
should look up the remote host name, and to check that
the resolved host name for the remote IP address maps back to the
very same IP address.
.Pp
If this option is set to
.Cm no ,
then only addresses and not host names may be used in
.Pa ~/.ssh/authorized_keys
.Cm from
and
.Nm
.Cm Match
.Cm Host
directives.
The default is
.Dq yes .
.It Cm UsePAM
Enables the Pluggable Authentication Module interface.
If set to
.Cm yes
this will enable PAM authentication using
.Cm KbdInteractiveAuthentication
and
.Cm PasswordAuthentication
in addition to PAM account and session module processing for all
authentication types.
.Pp
Because PAM keyboard-interactive authentication usually serves an equivalent
role to password authentication, you should disable either
.Cm PasswordAuthentication
or
.Cm KbdInteractiveAuthentication .
.Pp
If
.Cm UsePAM
is enabled, you will not be able to run
.Xr sshd 8
as a non-root user.
The default is
.Cm yes .
.It Cm VersionAddendum
Optionally specifies additional text to append to the SSH protocol banner
sent by the server upon connection.
The default is
-.Qq FreeBSD-20221019 .
+.Qq FreeBSD-20230205 .
The value
.Cm none
may be used to disable this.
.It Cm X11DisplayOffset
Specifies the first display number available for
.Xr sshd 8 Ns 's
X11 forwarding.
This prevents sshd from interfering with real X11 servers.
The default is 10.
.It Cm X11Forwarding
Specifies whether X11 forwarding is permitted.
The argument must be
.Cm yes
or
.Cm no .
The default is
.Cm yes .
.Pp
When X11 forwarding is enabled, there may be additional exposure to
the server and to client displays if the
.Xr sshd 8
proxy display is configured to listen on the wildcard address (see
.Cm X11UseLocalhost ) ,
though this is not the default.
Additionally, the authentication spoofing and authentication data
verification and substitution occur on the client side.
The security risk of using X11 forwarding is that the client's X11
display server may be exposed to attack when the SSH client requests
forwarding (see the warnings for
.Cm ForwardX11
in
.Xr ssh_config 5 ) .
A system administrator may have a stance in which they want to
protect clients that may expose themselves to attack by unwittingly
requesting X11 forwarding, which can warrant a
.Cm no
setting.
.Pp
Note that disabling X11 forwarding does not prevent users from
forwarding X11 traffic, as users can always install their own forwarders.
.It Cm X11UseLocalhost
Specifies whether
.Xr sshd 8
should bind the X11 forwarding server to the loopback address or to
the wildcard address.
By default,
sshd binds the forwarding server to the loopback address and sets the
hostname part of the
.Ev DISPLAY
environment variable to
.Cm localhost .
This prevents remote hosts from connecting to the proxy display.
However, some older X11 clients may not function with this
configuration.
.Cm X11UseLocalhost
may be set to
.Cm no
to specify that the forwarding server should be bound to the wildcard
address.
The argument must be
.Cm yes
or
.Cm no .
The default is
.Cm yes .
.It Cm XAuthLocation
Specifies the full pathname of the
.Xr xauth 1
program, or
.Cm none
to not use one.
The default is
.Pa /usr/local/bin/xauth .
.El
.Sh TIME FORMATS
.Xr sshd 8
command-line arguments and configuration file options that specify time
may be expressed using a sequence of the form:
.Sm off
.Ar time Op Ar qualifier ,
.Sm on
where
.Ar time
is a positive integer value and
.Ar qualifier
is one of the following:
.Pp
.Bl -tag -width Ds -compact -offset indent
.It Aq Cm none
seconds
.It Cm s | Cm S
seconds
.It Cm m | Cm M
minutes
.It Cm h | Cm H
hours
.It Cm d | Cm D
days
.It Cm w | Cm W
weeks
.El
.Pp
Each member of the sequence is added together to calculate
the total time value.
.Pp
Time format examples:
.Pp
.Bl -tag -width Ds -compact -offset indent
.It 600
600 seconds (10 minutes)
.It 10m
10 minutes
.It 1h30m
1 hour 30 minutes (90 minutes)
.El
.Sh TOKENS
Arguments to some keywords can make use of tokens,
which are expanded at runtime:
.Pp
.Bl -tag -width XXXX -offset indent -compact
.It %%
A literal
.Sq % .
.It \&%D
The routing domain in which the incoming connection was received.
.It %F
The fingerprint of the CA key.
.It %f
The fingerprint of the key or certificate.
.It %h
The home directory of the user.
.It %i
The key ID in the certificate.
.It %K
The base64-encoded CA key.
.It %k
The base64-encoded key or certificate for authentication.
.It %s
The serial number of the certificate.
.It \&%T
The type of the CA key.
.It %t
The key or certificate type.
.It \&%U
The numeric user ID of the target user.
.It %u
The username.
.El
.Pp
.Cm AuthorizedKeysCommand
accepts the tokens %%, %f, %h, %k, %t, %U, and %u.
.Pp
.Cm AuthorizedKeysFile
accepts the tokens %%, %h, %U, and %u.
.Pp
.Cm AuthorizedPrincipalsCommand
accepts the tokens %%, %F, %f, %h, %i, %K, %k, %s, %T, %t, %U, and %u.
.Pp
.Cm AuthorizedPrincipalsFile
accepts the tokens %%, %h, %U, and %u.
.Pp
.Cm ChrootDirectory
accepts the tokens %%, %h, %U, and %u.
.Pp
.Cm RoutingDomain
accepts the token %D.
.Sh FILES
.Bl -tag -width Ds
.It Pa /etc/ssh/sshd_config
Contains configuration data for
.Xr sshd 8 .
This file should be writable by root only, but it is recommended
(though not necessary) that it be world-readable.
.El
.Sh SEE ALSO
.Xr sftp-server 8 ,
.Xr sshd 8
.Sh AUTHORS
.An -nosplit
OpenSSH is a derivative of the original and free
ssh 1.2.12 release by
.An Tatu Ylonen .
.An Aaron Campbell , Bob Beck , Markus Friedl , Niels Provos ,
.An Theo de Raadt
and
.An Dug Song
removed many bugs, re-added newer features and
created OpenSSH.
.An Markus Friedl
contributed the support for SSH protocol versions 1.5 and 2.0.
.An Niels Provos
and
.An Markus Friedl
contributed support for privilege separation.
diff --git a/crypto/openssh/sshkey-xmss.c b/crypto/openssh/sshkey-xmss.c
index f5235ef2fbd8..818aba9059df 100644
--- a/crypto/openssh/sshkey-xmss.c
+++ b/crypto/openssh/sshkey-xmss.c
@@ -1,1113 +1,1113 @@
-/* $OpenBSD: sshkey-xmss.c,v 1.11 2021/04/03 06:18:41 djm Exp $ */
+/* $OpenBSD: sshkey-xmss.c,v 1.12 2022/10/28 00:39:29 djm Exp $ */
/*
* Copyright (c) 2017 Markus Friedl. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "includes.h"
#ifdef WITH_XMSS
#include <sys/types.h>
#include <sys/uio.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#ifdef HAVE_SYS_FILE_H
# include <sys/file.h>
#endif
#include "ssh2.h"
#include "ssherr.h"
#include "sshbuf.h"
#include "cipher.h"
#include "sshkey.h"
#include "sshkey-xmss.h"
#include "atomicio.h"
#include "log.h"
#include "xmss_fast.h"
/* opaque internal XMSS state */
#define XMSS_MAGIC "xmss-state-v1"
#define XMSS_CIPHERNAME "aes256-gcm@openssh.com"
struct ssh_xmss_state {
xmss_params params;
u_int32_t n, w, h, k;
bds_state bds;
u_char *stack;
u_int32_t stackoffset;
u_char *stacklevels;
u_char *auth;
u_char *keep;
u_char *th_nodes;
u_char *retain;
treehash_inst *treehash;
u_int32_t idx; /* state read from file */
u_int32_t maxidx; /* restricted # of signatures */
int have_state; /* .state file exists */
int lockfd; /* locked in sshkey_xmss_get_state() */
u_char allow_update; /* allow sshkey_xmss_update_state() */
char *enc_ciphername;/* encrypt state with cipher */
u_char *enc_keyiv; /* encrypt state with key */
u_int32_t enc_keyiv_len; /* length of enc_keyiv */
};
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 *, int);
int sshkey_xmss_encrypt_state(const struct sshkey *, struct sshbuf *,
struct sshbuf **);
int sshkey_xmss_decrypt_state(const struct sshkey *, struct sshbuf *,
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(...) 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)
{
struct ssh_xmss_state *state;
if (key->xmss_state != NULL)
return SSH_ERR_INVALID_FORMAT;
if (name == NULL)
return SSH_ERR_INVALID_FORMAT;
state = calloc(sizeof(struct ssh_xmss_state), 1);
if (state == NULL)
return SSH_ERR_ALLOC_FAIL;
if (strcmp(name, XMSS_SHA2_256_W16_H10_NAME) == 0) {
state->n = 32;
state->w = 16;
state->h = 10;
} else if (strcmp(name, XMSS_SHA2_256_W16_H16_NAME) == 0) {
state->n = 32;
state->w = 16;
state->h = 16;
} else if (strcmp(name, XMSS_SHA2_256_W16_H20_NAME) == 0) {
state->n = 32;
state->w = 16;
state->h = 20;
} else {
free(state);
return SSH_ERR_KEY_TYPE_UNKNOWN;
}
if ((key->xmss_name = strdup(name)) == NULL) {
free(state);
return SSH_ERR_ALLOC_FAIL;
}
state->k = 2; /* XXX hardcoded */
state->lockfd = -1;
if (xmss_set_params(&state->params, state->n, state->h, state->w,
state->k) != 0) {
free(state);
return SSH_ERR_INVALID_FORMAT;
}
key->xmss_state = state;
return 0;
}
void
sshkey_xmss_free_state(struct sshkey *key)
{
struct ssh_xmss_state *state = key->xmss_state;
sshkey_xmss_free_bds(key);
if (state) {
if (state->enc_keyiv) {
explicit_bzero(state->enc_keyiv, state->enc_keyiv_len);
free(state->enc_keyiv);
}
free(state->enc_ciphername);
free(state);
}
key->xmss_state = NULL;
}
#define SSH_XMSS_K2_MAGIC "k=2"
#define num_stack(x) ((x->h+1)*(x->n))
#define num_stacklevels(x) (x->h+1)
#define num_auth(x) ((x->h)*(x->n))
#define num_keep(x) ((x->h >> 1)*(x->n))
#define num_th_nodes(x) ((x->h - x->k)*(x->n))
#define num_retain(x) (((1ULL << x->k) - x->k - 1) * (x->n))
#define num_treehash(x) ((x->h) - (x->k))
int
sshkey_xmss_init_bds_state(struct sshkey *key)
{
struct ssh_xmss_state *state = key->xmss_state;
u_int32_t i;
state->stackoffset = 0;
if ((state->stack = calloc(num_stack(state), 1)) == NULL ||
(state->stacklevels = calloc(num_stacklevels(state), 1))== NULL ||
(state->auth = calloc(num_auth(state), 1)) == NULL ||
(state->keep = calloc(num_keep(state), 1)) == NULL ||
(state->th_nodes = calloc(num_th_nodes(state), 1)) == NULL ||
(state->retain = calloc(num_retain(state), 1)) == NULL ||
(state->treehash = calloc(num_treehash(state),
sizeof(treehash_inst))) == NULL) {
sshkey_xmss_free_bds(key);
return SSH_ERR_ALLOC_FAIL;
}
for (i = 0; i < state->h - state->k; i++)
state->treehash[i].node = &state->th_nodes[state->n*i];
xmss_set_bds_state(&state->bds, state->stack, state->stackoffset,
state->stacklevels, state->auth, state->keep, state->treehash,
state->retain, 0);
return 0;
}
void
sshkey_xmss_free_bds(struct sshkey *key)
{
struct ssh_xmss_state *state = key->xmss_state;
if (state == NULL)
return;
free(state->stack);
free(state->stacklevels);
free(state->auth);
free(state->keep);
free(state->th_nodes);
free(state->retain);
free(state->treehash);
state->stack = NULL;
state->stacklevels = NULL;
state->auth = NULL;
state->keep = NULL;
state->th_nodes = NULL;
state->retain = NULL;
state->treehash = NULL;
}
void *
sshkey_xmss_params(const struct sshkey *key)
{
struct ssh_xmss_state *state = key->xmss_state;
if (state == NULL)
return NULL;
return &state->params;
}
void *
sshkey_xmss_bds_state(const struct sshkey *key)
{
struct ssh_xmss_state *state = key->xmss_state;
if (state == NULL)
return NULL;
return &state->bds;
}
int
sshkey_xmss_siglen(const struct sshkey *key, size_t *lenp)
{
struct ssh_xmss_state *state = key->xmss_state;
if (lenp == NULL)
return SSH_ERR_INVALID_ARGUMENT;
if (state == NULL)
return SSH_ERR_INVALID_FORMAT;
*lenp = 4 + state->n +
state->params.wots_par.keysize +
state->h * state->n;
return 0;
}
size_t
sshkey_xmss_pklen(const struct sshkey *key)
{
struct ssh_xmss_state *state = key->xmss_state;
if (state == NULL)
return 0;
return state->n * 2;
}
size_t
sshkey_xmss_sklen(const struct sshkey *key)
{
struct ssh_xmss_state *state = key->xmss_state;
if (state == NULL)
return 0;
return state->n * 4 + 4;
}
int
sshkey_xmss_init_enc_key(struct sshkey *k, const char *ciphername)
{
struct ssh_xmss_state *state = k->xmss_state;
const struct sshcipher *cipher;
size_t keylen = 0, ivlen = 0;
if (state == NULL)
return SSH_ERR_INVALID_ARGUMENT;
if ((cipher = cipher_by_name(ciphername)) == NULL)
return SSH_ERR_INTERNAL_ERROR;
if ((state->enc_ciphername = strdup(ciphername)) == NULL)
return SSH_ERR_ALLOC_FAIL;
keylen = cipher_keylen(cipher);
ivlen = cipher_ivlen(cipher);
state->enc_keyiv_len = keylen + ivlen;
if ((state->enc_keyiv = calloc(state->enc_keyiv_len, 1)) == NULL) {
free(state->enc_ciphername);
state->enc_ciphername = NULL;
return SSH_ERR_ALLOC_FAIL;
}
arc4random_buf(state->enc_keyiv, state->enc_keyiv_len);
return 0;
}
int
sshkey_xmss_serialize_enc_key(const struct sshkey *k, struct sshbuf *b)
{
struct ssh_xmss_state *state = k->xmss_state;
int r;
if (state == NULL || state->enc_keyiv == NULL ||
state->enc_ciphername == NULL)
return SSH_ERR_INVALID_ARGUMENT;
if ((r = sshbuf_put_cstring(b, state->enc_ciphername)) != 0 ||
(r = sshbuf_put_string(b, state->enc_keyiv,
state->enc_keyiv_len)) != 0)
return r;
return 0;
}
int
sshkey_xmss_deserialize_enc_key(struct sshkey *k, struct sshbuf *b)
{
struct ssh_xmss_state *state = k->xmss_state;
size_t len;
int r;
if (state == NULL)
return SSH_ERR_INVALID_ARGUMENT;
if ((r = sshbuf_get_cstring(b, &state->enc_ciphername, NULL)) != 0 ||
(r = sshbuf_get_string(b, &state->enc_keyiv, &len)) != 0)
return r;
state->enc_keyiv_len = len;
return 0;
}
int
sshkey_xmss_serialize_pk_info(const struct sshkey *k, struct sshbuf *b,
enum sshkey_serialize_rep opts)
{
struct ssh_xmss_state *state = k->xmss_state;
u_char have_info = 1;
u_int32_t idx;
int r;
if (state == NULL)
return SSH_ERR_INVALID_ARGUMENT;
if (opts != SSHKEY_SERIALIZE_INFO)
return 0;
idx = k->xmss_sk ? PEEK_U32(k->xmss_sk) : state->idx;
if ((r = sshbuf_put_u8(b, have_info)) != 0 ||
(r = sshbuf_put_u32(b, idx)) != 0 ||
(r = sshbuf_put_u32(b, state->maxidx)) != 0)
return r;
return 0;
}
int
sshkey_xmss_deserialize_pk_info(struct sshkey *k, struct sshbuf *b)
{
struct ssh_xmss_state *state = k->xmss_state;
u_char have_info;
int r;
if (state == NULL)
return SSH_ERR_INVALID_ARGUMENT;
/* optional */
if (sshbuf_len(b) == 0)
return 0;
if ((r = sshbuf_get_u8(b, &have_info)) != 0)
return r;
if (have_info != 1)
return SSH_ERR_INVALID_ARGUMENT;
if ((r = sshbuf_get_u32(b, &state->idx)) != 0 ||
(r = sshbuf_get_u32(b, &state->maxidx)) != 0)
return r;
return 0;
}
int
-sshkey_xmss_generate_private_key(struct sshkey *k, u_int bits)
+sshkey_xmss_generate_private_key(struct sshkey *k, int bits)
{
int r;
const char *name;
if (bits == 10) {
name = XMSS_SHA2_256_W16_H10_NAME;
} else if (bits == 16) {
name = XMSS_SHA2_256_W16_H16_NAME;
} else if (bits == 20) {
name = XMSS_SHA2_256_W16_H20_NAME;
} else {
name = XMSS_DEFAULT_NAME;
}
if ((r = sshkey_xmss_init(k, name)) != 0 ||
(r = sshkey_xmss_init_bds_state(k)) != 0 ||
(r = sshkey_xmss_init_enc_key(k, XMSS_CIPHERNAME)) != 0)
return r;
if ((k->xmss_pk = malloc(sshkey_xmss_pklen(k))) == NULL ||
(k->xmss_sk = malloc(sshkey_xmss_sklen(k))) == NULL) {
return SSH_ERR_ALLOC_FAIL;
}
xmss_keypair(k->xmss_pk, k->xmss_sk, sshkey_xmss_bds_state(k),
sshkey_xmss_params(k));
return 0;
}
int
sshkey_xmss_get_state_from_file(struct sshkey *k, const char *filename,
int *have_file, int printerror)
{
struct sshbuf *b = NULL, *enc = NULL;
int ret = SSH_ERR_SYSTEM_ERROR, r, fd = -1;
u_int32_t len;
unsigned char buf[4], *data = NULL;
*have_file = 0;
if ((fd = open(filename, O_RDONLY)) >= 0) {
*have_file = 1;
if (atomicio(read, fd, buf, sizeof(buf)) != sizeof(buf)) {
PRINT("corrupt state file: %s", filename);
goto done;
}
len = PEEK_U32(buf);
if ((data = calloc(len, 1)) == NULL) {
ret = SSH_ERR_ALLOC_FAIL;
goto done;
}
if (atomicio(read, fd, data, len) != len) {
PRINT("cannot read blob: %s", filename);
goto done;
}
if ((enc = sshbuf_from(data, len)) == NULL) {
ret = SSH_ERR_ALLOC_FAIL;
goto done;
}
sshkey_xmss_free_bds(k);
if ((r = sshkey_xmss_decrypt_state(k, enc, &b)) != 0) {
ret = r;
goto done;
}
if ((r = sshkey_xmss_deserialize_state(k, b)) != 0) {
ret = r;
goto done;
}
ret = 0;
}
done:
if (fd != -1)
close(fd);
free(data);
sshbuf_free(enc);
sshbuf_free(b);
return ret;
}
int
sshkey_xmss_get_state(const struct sshkey *k, int printerror)
{
struct ssh_xmss_state *state = k->xmss_state;
u_int32_t idx = 0;
char *filename = NULL;
char *statefile = NULL, *ostatefile = NULL, *lockfile = NULL;
int lockfd = -1, have_state = 0, have_ostate, tries = 0;
int ret = SSH_ERR_INVALID_ARGUMENT, r;
if (state == NULL)
goto done;
/*
* If maxidx is set, then we are allowed a limited number
* of signatures, but don't need to access the disk.
* Otherwise we need to deal with the on-disk state.
*/
if (state->maxidx) {
/* xmss_sk always contains the current state */
idx = PEEK_U32(k->xmss_sk);
if (idx < state->maxidx) {
state->allow_update = 1;
return 0;
}
return SSH_ERR_INVALID_ARGUMENT;
}
if ((filename = k->xmss_filename) == NULL)
goto done;
if (asprintf(&lockfile, "%s.lock", filename) == -1 ||
asprintf(&statefile, "%s.state", filename) == -1 ||
asprintf(&ostatefile, "%s.ostate", filename) == -1) {
ret = SSH_ERR_ALLOC_FAIL;
goto done;
}
if ((lockfd = open(lockfile, O_CREAT|O_RDONLY, 0600)) == -1) {
ret = SSH_ERR_SYSTEM_ERROR;
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("cannot lock: %s", lockfile);
goto done;
}
if (++tries > 10) {
ret = SSH_ERR_SYSTEM_ERROR;
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, printerror)) != 0) {
if ((r = sshkey_xmss_get_state_from_file((struct sshkey *)k,
ostatefile, &have_ostate, printerror)) == 0) {
state->allow_update = 1;
r = sshkey_xmss_forward_state(k, 1);
state->idx = PEEK_U32(k->xmss_sk);
state->allow_update = 0;
}
}
if (!have_state && !have_ostate) {
/* check that bds state is initialized */
if (state->bds.auth == NULL)
goto done;
PRINT("start from scratch idx 0: %u", state->idx);
} else if (r != 0) {
ret = r;
goto done;
}
if (state->idx + 1 < state->idx) {
PRINT("state wrap: %u", state->idx);
goto done;
}
state->have_state = have_state;
state->lockfd = lockfd;
state->allow_update = 1;
lockfd = -1;
ret = 0;
done:
if (lockfd != -1)
close(lockfd);
free(lockfile);
free(statefile);
free(ostatefile);
return ret;
}
int
sshkey_xmss_forward_state(const struct sshkey *k, u_int32_t reserve)
{
struct ssh_xmss_state *state = k->xmss_state;
u_char *sig = NULL;
size_t required_siglen;
unsigned long long smlen;
u_char data;
int ret, r;
if (state == NULL || !state->allow_update)
return SSH_ERR_INVALID_ARGUMENT;
if (reserve == 0)
return SSH_ERR_INVALID_ARGUMENT;
if (state->idx + reserve <= state->idx)
return SSH_ERR_INVALID_ARGUMENT;
if ((r = sshkey_xmss_siglen(k, &required_siglen)) != 0)
return r;
if ((sig = malloc(required_siglen)) == NULL)
return SSH_ERR_ALLOC_FAIL;
while (reserve-- > 0) {
state->idx = PEEK_U32(k->xmss_sk);
smlen = required_siglen;
if ((ret = xmss_sign(k->xmss_sk, sshkey_xmss_bds_state(k),
sig, &smlen, &data, 0, sshkey_xmss_params(k))) != 0) {
r = SSH_ERR_INVALID_ARGUMENT;
break;
}
}
free(sig);
return r;
}
int
sshkey_xmss_update_state(const struct sshkey *k, int printerror)
{
struct ssh_xmss_state *state = k->xmss_state;
struct sshbuf *b = NULL, *enc = NULL;
u_int32_t idx = 0;
unsigned char buf[4];
char *filename = NULL;
char *statefile = NULL, *ostatefile = NULL, *nstatefile = NULL;
int fd = -1;
int ret = SSH_ERR_INVALID_ARGUMENT;
if (state == NULL || !state->allow_update)
return ret;
if (state->maxidx) {
/* no update since the number of signatures is limited */
ret = 0;
goto done;
}
idx = PEEK_U32(k->xmss_sk);
if (idx == state->idx) {
/* no signature happened, no need to update */
ret = 0;
goto done;
} else if (idx != state->idx + 1) {
PRINT("more than one signature happened: idx %u state %u",
idx, state->idx);
goto done;
}
state->idx = idx;
if ((filename = k->xmss_filename) == NULL)
goto done;
if (asprintf(&statefile, "%s.state", filename) == -1 ||
asprintf(&ostatefile, "%s.ostate", filename) == -1 ||
asprintf(&nstatefile, "%s.nstate", filename) == -1) {
ret = SSH_ERR_ALLOC_FAIL;
goto done;
}
unlink(nstatefile);
if ((b = sshbuf_new()) == NULL) {
ret = SSH_ERR_ALLOC_FAIL;
goto done;
}
if ((ret = sshkey_xmss_serialize_state(k, b)) != 0) {
PRINT("SERLIALIZE FAILED: %d", ret);
goto done;
}
if ((ret = sshkey_xmss_encrypt_state(k, b, &enc)) != 0) {
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("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("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("write new state file data: %s", nstatefile);
close(fd);
goto done;
}
if (fsync(fd) == -1) {
ret = SSH_ERR_SYSTEM_ERROR;
PRINT("sync new state file: %s", nstatefile);
close(fd);
goto done;
}
if (close(fd) == -1) {
ret = SSH_ERR_SYSTEM_ERROR;
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("backup state %s to %s", statefile, ostatefile);
goto done;
}
}
if (rename(nstatefile, statefile) == -1) {
ret = SSH_ERR_SYSTEM_ERROR;
PRINT("rename %s to %s", nstatefile, statefile);
goto done;
}
ret = 0;
done:
if (state->lockfd != -1) {
close(state->lockfd);
state->lockfd = -1;
}
if (nstatefile)
unlink(nstatefile);
free(statefile);
free(ostatefile);
free(nstatefile);
sshbuf_free(b);
sshbuf_free(enc);
return ret;
}
int
sshkey_xmss_serialize_state(const struct sshkey *k, struct sshbuf *b)
{
struct ssh_xmss_state *state = k->xmss_state;
treehash_inst *th;
u_int32_t i, node;
int r;
if (state == NULL)
return SSH_ERR_INVALID_ARGUMENT;
if (state->stack == NULL)
return SSH_ERR_INVALID_ARGUMENT;
state->stackoffset = state->bds.stackoffset; /* copy back */
if ((r = sshbuf_put_cstring(b, SSH_XMSS_K2_MAGIC)) != 0 ||
(r = sshbuf_put_u32(b, state->idx)) != 0 ||
(r = sshbuf_put_string(b, state->stack, num_stack(state))) != 0 ||
(r = sshbuf_put_u32(b, state->stackoffset)) != 0 ||
(r = sshbuf_put_string(b, state->stacklevels, num_stacklevels(state))) != 0 ||
(r = sshbuf_put_string(b, state->auth, num_auth(state))) != 0 ||
(r = sshbuf_put_string(b, state->keep, num_keep(state))) != 0 ||
(r = sshbuf_put_string(b, state->th_nodes, num_th_nodes(state))) != 0 ||
(r = sshbuf_put_string(b, state->retain, num_retain(state))) != 0 ||
(r = sshbuf_put_u32(b, num_treehash(state))) != 0)
return r;
for (i = 0; i < num_treehash(state); i++) {
th = &state->treehash[i];
node = th->node - state->th_nodes;
if ((r = sshbuf_put_u32(b, th->h)) != 0 ||
(r = sshbuf_put_u32(b, th->next_idx)) != 0 ||
(r = sshbuf_put_u32(b, th->stackusage)) != 0 ||
(r = sshbuf_put_u8(b, th->completed)) != 0 ||
(r = sshbuf_put_u32(b, node)) != 0)
return r;
}
return 0;
}
int
sshkey_xmss_serialize_state_opt(const struct sshkey *k, struct sshbuf *b,
enum sshkey_serialize_rep opts)
{
struct ssh_xmss_state *state = k->xmss_state;
int r = SSH_ERR_INVALID_ARGUMENT;
u_char have_stack, have_filename, have_enc;
if (state == NULL)
return SSH_ERR_INVALID_ARGUMENT;
if ((r = sshbuf_put_u8(b, opts)) != 0)
return r;
switch (opts) {
case SSHKEY_SERIALIZE_STATE:
r = sshkey_xmss_serialize_state(k, b);
break;
case SSHKEY_SERIALIZE_FULL:
if ((r = sshkey_xmss_serialize_enc_key(k, b)) != 0)
return r;
r = sshkey_xmss_serialize_state(k, b);
break;
case SSHKEY_SERIALIZE_SHIELD:
/* all of stack/filename/enc are optional */
have_stack = state->stack != NULL;
if ((r = sshbuf_put_u8(b, have_stack)) != 0)
return r;
if (have_stack) {
state->idx = PEEK_U32(k->xmss_sk); /* update */
if ((r = sshkey_xmss_serialize_state(k, b)) != 0)
return r;
}
have_filename = k->xmss_filename != NULL;
if ((r = sshbuf_put_u8(b, have_filename)) != 0)
return r;
if (have_filename &&
(r = sshbuf_put_cstring(b, k->xmss_filename)) != 0)
return r;
have_enc = state->enc_keyiv != NULL;
if ((r = sshbuf_put_u8(b, have_enc)) != 0)
return r;
if (have_enc &&
(r = sshkey_xmss_serialize_enc_key(k, b)) != 0)
return r;
if ((r = sshbuf_put_u32(b, state->maxidx)) != 0 ||
(r = sshbuf_put_u8(b, state->allow_update)) != 0)
return r;
break;
case SSHKEY_SERIALIZE_DEFAULT:
r = 0;
break;
default:
r = SSH_ERR_INVALID_ARGUMENT;
break;
}
return r;
}
int
sshkey_xmss_deserialize_state(struct sshkey *k, struct sshbuf *b)
{
struct ssh_xmss_state *state = k->xmss_state;
treehash_inst *th;
u_int32_t i, lh, node;
size_t ls, lsl, la, lk, ln, lr;
char *magic;
int r = SSH_ERR_INTERNAL_ERROR;
if (state == NULL)
return SSH_ERR_INVALID_ARGUMENT;
if (k->xmss_sk == NULL)
return SSH_ERR_INVALID_ARGUMENT;
if ((state->treehash = calloc(num_treehash(state),
sizeof(treehash_inst))) == NULL)
return SSH_ERR_ALLOC_FAIL;
if ((r = sshbuf_get_cstring(b, &magic, NULL)) != 0 ||
(r = sshbuf_get_u32(b, &state->idx)) != 0 ||
(r = sshbuf_get_string(b, &state->stack, &ls)) != 0 ||
(r = sshbuf_get_u32(b, &state->stackoffset)) != 0 ||
(r = sshbuf_get_string(b, &state->stacklevels, &lsl)) != 0 ||
(r = sshbuf_get_string(b, &state->auth, &la)) != 0 ||
(r = sshbuf_get_string(b, &state->keep, &lk)) != 0 ||
(r = sshbuf_get_string(b, &state->th_nodes, &ln)) != 0 ||
(r = sshbuf_get_string(b, &state->retain, &lr)) != 0 ||
(r = sshbuf_get_u32(b, &lh)) != 0)
goto out;
if (strcmp(magic, SSH_XMSS_K2_MAGIC) != 0) {
r = SSH_ERR_INVALID_ARGUMENT;
goto out;
}
/* XXX check stackoffset */
if (ls != num_stack(state) ||
lsl != num_stacklevels(state) ||
la != num_auth(state) ||
lk != num_keep(state) ||
ln != num_th_nodes(state) ||
lr != num_retain(state) ||
lh != num_treehash(state)) {
r = SSH_ERR_INVALID_ARGUMENT;
goto out;
}
for (i = 0; i < num_treehash(state); i++) {
th = &state->treehash[i];
if ((r = sshbuf_get_u32(b, &th->h)) != 0 ||
(r = sshbuf_get_u32(b, &th->next_idx)) != 0 ||
(r = sshbuf_get_u32(b, &th->stackusage)) != 0 ||
(r = sshbuf_get_u8(b, &th->completed)) != 0 ||
(r = sshbuf_get_u32(b, &node)) != 0)
goto out;
if (node < num_th_nodes(state))
th->node = &state->th_nodes[node];
}
POKE_U32(k->xmss_sk, state->idx);
xmss_set_bds_state(&state->bds, state->stack, state->stackoffset,
state->stacklevels, state->auth, state->keep, state->treehash,
state->retain, 0);
/* success */
r = 0;
out:
free(magic);
return r;
}
int
sshkey_xmss_deserialize_state_opt(struct sshkey *k, struct sshbuf *b)
{
struct ssh_xmss_state *state = k->xmss_state;
enum sshkey_serialize_rep opts;
u_char have_state, have_stack, have_filename, have_enc;
int r;
if ((r = sshbuf_get_u8(b, &have_state)) != 0)
return r;
opts = have_state;
switch (opts) {
case SSHKEY_SERIALIZE_DEFAULT:
r = 0;
break;
case SSHKEY_SERIALIZE_SHIELD:
if ((r = sshbuf_get_u8(b, &have_stack)) != 0)
return r;
if (have_stack &&
(r = sshkey_xmss_deserialize_state(k, b)) != 0)
return r;
if ((r = sshbuf_get_u8(b, &have_filename)) != 0)
return r;
if (have_filename &&
(r = sshbuf_get_cstring(b, &k->xmss_filename, NULL)) != 0)
return r;
if ((r = sshbuf_get_u8(b, &have_enc)) != 0)
return r;
if (have_enc &&
(r = sshkey_xmss_deserialize_enc_key(k, b)) != 0)
return r;
if ((r = sshbuf_get_u32(b, &state->maxidx)) != 0 ||
(r = sshbuf_get_u8(b, &state->allow_update)) != 0)
return r;
break;
case SSHKEY_SERIALIZE_STATE:
if ((r = sshkey_xmss_deserialize_state(k, b)) != 0)
return r;
break;
case SSHKEY_SERIALIZE_FULL:
if ((r = sshkey_xmss_deserialize_enc_key(k, b)) != 0 ||
(r = sshkey_xmss_deserialize_state(k, b)) != 0)
return r;
break;
default:
r = SSH_ERR_INVALID_FORMAT;
break;
}
return r;
}
int
sshkey_xmss_encrypt_state(const struct sshkey *k, struct sshbuf *b,
struct sshbuf **retp)
{
struct ssh_xmss_state *state = k->xmss_state;
struct sshbuf *encrypted = NULL, *encoded = NULL, *padded = NULL;
struct sshcipher_ctx *ciphercontext = NULL;
const struct sshcipher *cipher;
u_char *cp, *key, *iv = NULL;
size_t i, keylen, ivlen, blocksize, authlen, encrypted_len, aadlen;
int r = SSH_ERR_INTERNAL_ERROR;
if (retp != NULL)
*retp = NULL;
if (state == NULL ||
state->enc_keyiv == NULL ||
state->enc_ciphername == NULL)
return SSH_ERR_INTERNAL_ERROR;
if ((cipher = cipher_by_name(state->enc_ciphername)) == NULL) {
r = SSH_ERR_INTERNAL_ERROR;
goto out;
}
blocksize = cipher_blocksize(cipher);
keylen = cipher_keylen(cipher);
ivlen = cipher_ivlen(cipher);
authlen = cipher_authlen(cipher);
if (state->enc_keyiv_len != keylen + ivlen) {
r = SSH_ERR_INVALID_FORMAT;
goto out;
}
key = state->enc_keyiv;
if ((encrypted = sshbuf_new()) == NULL ||
(encoded = sshbuf_new()) == NULL ||
(padded = sshbuf_new()) == NULL ||
(iv = malloc(ivlen)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
/* replace first 4 bytes of IV with index to ensure uniqueness */
memcpy(iv, key + keylen, ivlen);
POKE_U32(iv, state->idx);
if ((r = sshbuf_put(encoded, XMSS_MAGIC, sizeof(XMSS_MAGIC))) != 0 ||
(r = sshbuf_put_u32(encoded, state->idx)) != 0)
goto out;
/* padded state will be encrypted */
if ((r = sshbuf_putb(padded, b)) != 0)
goto out;
i = 0;
while (sshbuf_len(padded) % blocksize) {
if ((r = sshbuf_put_u8(padded, ++i & 0xff)) != 0)
goto out;
}
encrypted_len = sshbuf_len(padded);
/* header including the length of state is used as AAD */
if ((r = sshbuf_put_u32(encoded, encrypted_len)) != 0)
goto out;
aadlen = sshbuf_len(encoded);
/* concat header and state */
if ((r = sshbuf_putb(encoded, padded)) != 0)
goto out;
/* reserve space for encryption of encoded data plus auth tag */
/* encrypt at offset addlen */
if ((r = sshbuf_reserve(encrypted,
encrypted_len + aadlen + authlen, &cp)) != 0 ||
(r = cipher_init(&ciphercontext, cipher, key, keylen,
iv, ivlen, 1)) != 0 ||
(r = cipher_crypt(ciphercontext, 0, cp, sshbuf_ptr(encoded),
encrypted_len, aadlen, authlen)) != 0)
goto out;
/* success */
r = 0;
out:
if (retp != NULL) {
*retp = encrypted;
encrypted = NULL;
}
sshbuf_free(padded);
sshbuf_free(encoded);
sshbuf_free(encrypted);
cipher_free(ciphercontext);
free(iv);
return r;
}
int
sshkey_xmss_decrypt_state(const struct sshkey *k, struct sshbuf *encoded,
struct sshbuf **retp)
{
struct ssh_xmss_state *state = k->xmss_state;
struct sshbuf *copy = NULL, *decrypted = NULL;
struct sshcipher_ctx *ciphercontext = NULL;
const struct sshcipher *cipher = NULL;
u_char *key, *iv = NULL, *dp;
size_t keylen, ivlen, authlen, aadlen;
u_int blocksize, encrypted_len, index;
int r = SSH_ERR_INTERNAL_ERROR;
if (retp != NULL)
*retp = NULL;
if (state == NULL ||
state->enc_keyiv == NULL ||
state->enc_ciphername == NULL)
return SSH_ERR_INTERNAL_ERROR;
if ((cipher = cipher_by_name(state->enc_ciphername)) == NULL) {
r = SSH_ERR_INVALID_FORMAT;
goto out;
}
blocksize = cipher_blocksize(cipher);
keylen = cipher_keylen(cipher);
ivlen = cipher_ivlen(cipher);
authlen = cipher_authlen(cipher);
if (state->enc_keyiv_len != keylen + ivlen) {
r = SSH_ERR_INTERNAL_ERROR;
goto out;
}
key = state->enc_keyiv;
if ((copy = sshbuf_fromb(encoded)) == NULL ||
(decrypted = sshbuf_new()) == NULL ||
(iv = malloc(ivlen)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
/* check magic */
if (sshbuf_len(encoded) < sizeof(XMSS_MAGIC) ||
memcmp(sshbuf_ptr(encoded), XMSS_MAGIC, sizeof(XMSS_MAGIC))) {
r = SSH_ERR_INVALID_FORMAT;
goto out;
}
/* parse public portion */
if ((r = sshbuf_consume(encoded, sizeof(XMSS_MAGIC))) != 0 ||
(r = sshbuf_get_u32(encoded, &index)) != 0 ||
(r = sshbuf_get_u32(encoded, &encrypted_len)) != 0)
goto out;
/* check size of encrypted key blob */
if (encrypted_len < blocksize || (encrypted_len % blocksize) != 0) {
r = SSH_ERR_INVALID_FORMAT;
goto out;
}
/* check that an appropriate amount of auth data is present */
if (sshbuf_len(encoded) < authlen ||
sshbuf_len(encoded) - authlen < encrypted_len) {
r = SSH_ERR_INVALID_FORMAT;
goto out;
}
aadlen = sshbuf_len(copy) - sshbuf_len(encoded);
/* replace first 4 bytes of IV with index to ensure uniqueness */
memcpy(iv, key + keylen, ivlen);
POKE_U32(iv, index);
/* decrypt private state of key */
if ((r = sshbuf_reserve(decrypted, aadlen + encrypted_len, &dp)) != 0 ||
(r = cipher_init(&ciphercontext, cipher, key, keylen,
iv, ivlen, 0)) != 0 ||
(r = cipher_crypt(ciphercontext, 0, dp, sshbuf_ptr(copy),
encrypted_len, aadlen, authlen)) != 0)
goto out;
/* there should be no trailing data */
if ((r = sshbuf_consume(encoded, encrypted_len + authlen)) != 0)
goto out;
if (sshbuf_len(encoded) != 0) {
r = SSH_ERR_INVALID_FORMAT;
goto out;
}
/* remove AAD */
if ((r = sshbuf_consume(decrypted, aadlen)) != 0)
goto out;
/* XXX encrypted includes unchecked padding */
/* success */
r = 0;
if (retp != NULL) {
*retp = decrypted;
decrypted = NULL;
}
out:
cipher_free(ciphercontext);
sshbuf_free(copy);
sshbuf_free(decrypted);
free(iv);
return r;
}
u_int32_t
sshkey_xmss_signatures_left(const struct sshkey *k)
{
struct ssh_xmss_state *state = k->xmss_state;
u_int32_t idx;
if (sshkey_type_plain(k->type) == KEY_XMSS && state &&
state->maxidx) {
idx = k->xmss_sk ? PEEK_U32(k->xmss_sk) : state->idx;
if (idx < state->maxidx)
return state->maxidx - idx;
}
return 0;
}
int
sshkey_xmss_enable_maxsign(struct sshkey *k, u_int32_t maxsign)
{
struct ssh_xmss_state *state = k->xmss_state;
if (sshkey_type_plain(k->type) != KEY_XMSS)
return SSH_ERR_INVALID_ARGUMENT;
if (maxsign == 0)
return 0;
if (state->idx + maxsign < state->idx)
return SSH_ERR_INVALID_ARGUMENT;
state->maxidx = state->idx + maxsign;
return 0;
}
#endif /* WITH_XMSS */
diff --git a/crypto/openssh/sshkey-xmss.h b/crypto/openssh/sshkey-xmss.h
index 32a12be620b1..ab8b9c905a96 100644
--- a/crypto/openssh/sshkey-xmss.h
+++ b/crypto/openssh/sshkey-xmss.h
@@ -1,56 +1,56 @@
-/* $OpenBSD: sshkey-xmss.h,v 1.3 2021/04/03 06:18:41 djm Exp $ */
+/* $OpenBSD: sshkey-xmss.h,v 1.4 2022/10/28 00:39:29 djm Exp $ */
/*
* Copyright (c) 2017 Markus Friedl. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef 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
size_t sshkey_xmss_pklen(const struct sshkey *);
size_t sshkey_xmss_sklen(const struct sshkey *);
int sshkey_xmss_init(struct sshkey *, const char *);
void sshkey_xmss_free_state(struct sshkey *);
-int sshkey_xmss_generate_private_key(struct sshkey *, u_int);
+int sshkey_xmss_generate_private_key(struct sshkey *, 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);
int sshkey_xmss_serialize_pk_info(const struct sshkey *, struct sshbuf *,
enum sshkey_serialize_rep);
int sshkey_xmss_deserialize_state(struct sshkey *, struct sshbuf *);
int sshkey_xmss_deserialize_state_opt(struct sshkey *, struct sshbuf *);
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 *, 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 *, int);
u_int32_t sshkey_xmss_signatures_left(const struct sshkey *);
#endif /* SSHKEY_XMSS_H */
diff --git a/crypto/openssh/sshkey.c b/crypto/openssh/sshkey.c
index 770932357139..43712253d72b 100644
--- a/crypto/openssh/sshkey.c
+++ b/crypto/openssh/sshkey.c
@@ -1,4856 +1,3663 @@
-/* $OpenBSD: sshkey.c,v 1.122 2022/09/17 10:30:45 djm Exp $ */
+/* $OpenBSD: sshkey.c,v 1.134 2022/10/28 02:47:04 djm Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
* Copyright (c) 2008 Alexander von Gernler. All rights reserved.
* Copyright (c) 2010,2011 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 <netinet/in.h>
#ifdef WITH_OPENSSL
#include <openssl/evp.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#endif
#include "crypto_api.h"
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <resolv.h>
#include <time.h>
#ifdef HAVE_UTIL_H
#include <util.h>
#endif /* HAVE_UTIL_H */
#include "ssh2.h"
#include "ssherr.h"
#include "misc.h"
#include "sshbuf.h"
#include "cipher.h"
#include "digest.h"
#define SSHKEY_INTERNAL
#include "sshkey.h"
#include "match.h"
#include "ssh-sk.h"
#ifdef WITH_XMSS
#include "sshkey-xmss.h"
#include "xmss_fast.h"
#endif
#include "openbsd-compat/openssl-compat.h"
/* openssh private key file format */
#define MARK_BEGIN "-----BEGIN OPENSSH PRIVATE KEY-----\n"
#define MARK_END "-----END OPENSSH PRIVATE KEY-----\n"
#define MARK_BEGIN_LEN (sizeof(MARK_BEGIN) - 1)
#define MARK_END_LEN (sizeof(MARK_END) - 1)
#define KDFNAME "bcrypt"
#define AUTH_MAGIC "openssh-key-v1"
#define SALT_LEN 16
#define DEFAULT_CIPHERNAME "aes256-ctr"
#define DEFAULT_ROUNDS 16
/* Version identification string for SSH v1 identity files. */
#define LEGACY_BEGIN "SSH PRIVATE KEY FILE FORMAT 1.1\n"
/*
* Constants relating to "shielding" support; protection of keys expected
* to remain in memory for long durations
*/
#define SSHKEY_SHIELD_PREKEY_LEN (16 * 1024)
#define SSHKEY_SHIELD_CIPHER "aes256-ctr" /* XXX want AES-EME* */
#define SSHKEY_SHIELD_PREKEY_HASH SSH_DIGEST_SHA512
int sshkey_private_serialize_opt(struct sshkey *key,
struct sshbuf *buf, enum sshkey_serialize_rep);
static int sshkey_from_blob_internal(struct sshbuf *buf,
struct sshkey **keyp, int allow_cert);
/* Supported key types */
-struct keytype {
- const char *name;
- const char *shortname;
- const char *sigalg;
- int type;
- int nid;
- int cert;
- int sigonly;
-};
-static const struct keytype keytypes[] = {
- { "ssh-ed25519", "ED25519", NULL, KEY_ED25519, 0, 0, 0 },
- { "ssh-ed25519-cert-v01@openssh.com", "ED25519-CERT", NULL,
- KEY_ED25519_CERT, 0, 1, 0 },
-#ifdef ENABLE_SK
- { "sk-ssh-ed25519@openssh.com", "ED25519-SK", NULL,
- KEY_ED25519_SK, 0, 0, 0 },
- { "sk-ssh-ed25519-cert-v01@openssh.com", "ED25519-SK-CERT", NULL,
- KEY_ED25519_SK_CERT, 0, 1, 0 },
-#endif
-#ifdef WITH_XMSS
- { "ssh-xmss@openssh.com", "XMSS", NULL, KEY_XMSS, 0, 0, 0 },
- { "ssh-xmss-cert-v01@openssh.com", "XMSS-CERT", NULL,
- KEY_XMSS_CERT, 0, 1, 0 },
-#endif /* WITH_XMSS */
+extern const struct sshkey_impl sshkey_ed25519_impl;
+extern const struct sshkey_impl sshkey_ed25519_cert_impl;
+extern const struct sshkey_impl sshkey_ed25519_sk_impl;
+extern const struct sshkey_impl sshkey_ed25519_sk_cert_impl;
#ifdef WITH_OPENSSL
- { "ssh-rsa", "RSA", NULL, KEY_RSA, 0, 0, 0 },
- { "rsa-sha2-256", "RSA", NULL, KEY_RSA, 0, 0, 1 },
- { "rsa-sha2-512", "RSA", NULL, KEY_RSA, 0, 0, 1 },
- { "ssh-dss", "DSA", NULL, KEY_DSA, 0, 0, 0 },
# ifdef OPENSSL_HAS_ECC
- { "ecdsa-sha2-nistp256", "ECDSA", NULL,
- KEY_ECDSA, NID_X9_62_prime256v1, 0, 0 },
- { "ecdsa-sha2-nistp384", "ECDSA", NULL,
- KEY_ECDSA, NID_secp384r1, 0, 0 },
-# ifdef OPENSSL_HAS_NISTP521
- { "ecdsa-sha2-nistp521", "ECDSA", NULL,
- KEY_ECDSA, NID_secp521r1, 0, 0 },
-# endif /* OPENSSL_HAS_NISTP521 */
# ifdef ENABLE_SK
- { "sk-ecdsa-sha2-nistp256@openssh.com", "ECDSA-SK", NULL,
- KEY_ECDSA_SK, NID_X9_62_prime256v1, 0, 0 },
- { "webauthn-sk-ecdsa-sha2-nistp256@openssh.com", "ECDSA-SK", NULL,
- KEY_ECDSA_SK, NID_X9_62_prime256v1, 0, 1 },
+extern const struct sshkey_impl sshkey_ecdsa_sk_impl;
+extern const struct sshkey_impl sshkey_ecdsa_sk_cert_impl;
+extern const struct sshkey_impl sshkey_ecdsa_sk_webauthn_impl;
# endif /* ENABLE_SK */
+extern const struct sshkey_impl sshkey_ecdsa_nistp256_impl;
+extern const struct sshkey_impl sshkey_ecdsa_nistp256_cert_impl;
+extern const struct sshkey_impl sshkey_ecdsa_nistp384_impl;
+extern const struct sshkey_impl sshkey_ecdsa_nistp384_cert_impl;
+# ifdef OPENSSL_HAS_NISTP521
+extern const struct sshkey_impl sshkey_ecdsa_nistp521_impl;
+extern const struct sshkey_impl sshkey_ecdsa_nistp521_cert_impl;
+# endif /* OPENSSL_HAS_NISTP521 */
# endif /* OPENSSL_HAS_ECC */
- { "ssh-rsa-cert-v01@openssh.com", "RSA-CERT", NULL,
- KEY_RSA_CERT, 0, 1, 0 },
- { "rsa-sha2-256-cert-v01@openssh.com", "RSA-CERT",
- "rsa-sha2-256", KEY_RSA_CERT, 0, 1, 1 },
- { "rsa-sha2-512-cert-v01@openssh.com", "RSA-CERT",
- "rsa-sha2-512", KEY_RSA_CERT, 0, 1, 1 },
- { "ssh-dss-cert-v01@openssh.com", "DSA-CERT", NULL,
- KEY_DSA_CERT, 0, 1, 0 },
+extern const struct sshkey_impl sshkey_rsa_impl;
+extern const struct sshkey_impl sshkey_rsa_cert_impl;
+extern const struct sshkey_impl sshkey_rsa_sha256_impl;
+extern const struct sshkey_impl sshkey_rsa_sha256_cert_impl;
+extern const struct sshkey_impl sshkey_rsa_sha512_impl;
+extern const struct sshkey_impl sshkey_rsa_sha512_cert_impl;
+extern const struct sshkey_impl sshkey_dss_impl;
+extern const struct sshkey_impl sshkey_dsa_cert_impl;
+#endif /* WITH_OPENSSL */
+#ifdef WITH_XMSS
+extern const struct sshkey_impl sshkey_xmss_impl;
+extern const struct sshkey_impl sshkey_xmss_cert_impl;
+#endif
+
+const struct sshkey_impl * const keyimpls[] = {
+ &sshkey_ed25519_impl,
+ &sshkey_ed25519_cert_impl,
+#ifdef ENABLE_SK
+ &sshkey_ed25519_sk_impl,
+ &sshkey_ed25519_sk_cert_impl,
+#endif
+#ifdef WITH_OPENSSL
# ifdef OPENSSL_HAS_ECC
- { "ecdsa-sha2-nistp256-cert-v01@openssh.com", "ECDSA-CERT", NULL,
- KEY_ECDSA_CERT, NID_X9_62_prime256v1, 1, 0 },
- { "ecdsa-sha2-nistp384-cert-v01@openssh.com", "ECDSA-CERT", NULL,
- KEY_ECDSA_CERT, NID_secp384r1, 1, 0 },
+ &sshkey_ecdsa_nistp256_impl,
+ &sshkey_ecdsa_nistp256_cert_impl,
+ &sshkey_ecdsa_nistp384_impl,
+ &sshkey_ecdsa_nistp384_cert_impl,
# ifdef OPENSSL_HAS_NISTP521
- { "ecdsa-sha2-nistp521-cert-v01@openssh.com", "ECDSA-CERT", NULL,
- KEY_ECDSA_CERT, NID_secp521r1, 1, 0 },
+ &sshkey_ecdsa_nistp521_impl,
+ &sshkey_ecdsa_nistp521_cert_impl,
# endif /* OPENSSL_HAS_NISTP521 */
# ifdef ENABLE_SK
- { "sk-ecdsa-sha2-nistp256-cert-v01@openssh.com", "ECDSA-SK-CERT", NULL,
- KEY_ECDSA_SK_CERT, NID_X9_62_prime256v1, 1, 0 },
+ &sshkey_ecdsa_sk_impl,
+ &sshkey_ecdsa_sk_cert_impl,
+ &sshkey_ecdsa_sk_webauthn_impl,
# endif /* ENABLE_SK */
# endif /* OPENSSL_HAS_ECC */
+ &sshkey_dss_impl,
+ &sshkey_dsa_cert_impl,
+ &sshkey_rsa_impl,
+ &sshkey_rsa_cert_impl,
+ &sshkey_rsa_sha256_impl,
+ &sshkey_rsa_sha256_cert_impl,
+ &sshkey_rsa_sha512_impl,
+ &sshkey_rsa_sha512_cert_impl,
#endif /* WITH_OPENSSL */
- { NULL, NULL, NULL, -1, -1, 0, 0 }
+#ifdef WITH_XMSS
+ &sshkey_xmss_impl,
+ &sshkey_xmss_cert_impl,
+#endif
+ NULL
};
+static const struct sshkey_impl *
+sshkey_impl_from_type(int type)
+{
+ int i;
+
+ for (i = 0; keyimpls[i] != NULL; i++) {
+ if (keyimpls[i]->type == type)
+ return keyimpls[i];
+ }
+ return NULL;
+}
+
+static const struct sshkey_impl *
+sshkey_impl_from_type_nid(int type, int nid)
+{
+ int i;
+
+ for (i = 0; keyimpls[i] != NULL; i++) {
+ if (keyimpls[i]->type == type &&
+ (keyimpls[i]->nid == 0 || keyimpls[i]->nid == nid))
+ return keyimpls[i];
+ }
+ return NULL;
+}
+
+static const struct sshkey_impl *
+sshkey_impl_from_key(const struct sshkey *k)
+{
+ if (k == NULL)
+ return NULL;
+ return sshkey_impl_from_type_nid(k->type, k->ecdsa_nid);
+}
+
const char *
sshkey_type(const struct sshkey *k)
{
- const struct keytype *kt;
+ const struct sshkey_impl *impl;
- for (kt = keytypes; kt->type != -1; kt++) {
- if (kt->type == k->type)
- return kt->shortname;
- }
- return "unknown";
+ if ((impl = sshkey_impl_from_key(k)) == NULL)
+ return "unknown";
+ return impl->shortname;
}
static const char *
sshkey_ssh_name_from_type_nid(int type, int nid)
{
- const struct keytype *kt;
+ const struct sshkey_impl *impl;
- for (kt = keytypes; kt->type != -1; kt++) {
- if (kt->type == type && (kt->nid == 0 || kt->nid == nid))
- return kt->name;
- }
- return "ssh-unknown";
+ if ((impl = sshkey_impl_from_type_nid(type, nid)) == NULL)
+ return "ssh-unknown";
+ return impl->name;
}
int
sshkey_type_is_cert(int type)
{
- const struct keytype *kt;
+ const struct sshkey_impl *impl;
- for (kt = keytypes; kt->type != -1; kt++) {
- if (kt->type == type)
- return kt->cert;
- }
- return 0;
+ if ((impl = sshkey_impl_from_type(type)) == NULL)
+ return 0;
+ return impl->cert;
}
const char *
sshkey_ssh_name(const struct sshkey *k)
{
return sshkey_ssh_name_from_type_nid(k->type, k->ecdsa_nid);
}
const char *
sshkey_ssh_name_plain(const struct sshkey *k)
{
return sshkey_ssh_name_from_type_nid(sshkey_type_plain(k->type),
k->ecdsa_nid);
}
int
sshkey_type_from_name(const char *name)
{
- const struct keytype *kt;
+ int i;
+ const struct sshkey_impl *impl;
- for (kt = keytypes; kt->type != -1; kt++) {
+ for (i = 0; keyimpls[i] != NULL; i++) {
+ impl = keyimpls[i];
/* Only allow shortname matches for plain key types */
- if ((kt->name != NULL && strcmp(name, kt->name) == 0) ||
- (!kt->cert && strcasecmp(kt->shortname, name) == 0))
- return kt->type;
+ if ((impl->name != NULL && strcmp(name, impl->name) == 0) ||
+ (!impl->cert && strcasecmp(impl->shortname, name) == 0))
+ return impl->type;
}
return KEY_UNSPEC;
}
static int
key_type_is_ecdsa_variant(int type)
{
switch (type) {
case KEY_ECDSA:
case KEY_ECDSA_CERT:
case KEY_ECDSA_SK:
case KEY_ECDSA_SK_CERT:
return 1;
}
return 0;
}
int
sshkey_ecdsa_nid_from_name(const char *name)
{
- const struct keytype *kt;
+ int i;
- for (kt = keytypes; kt->type != -1; kt++) {
- if (!key_type_is_ecdsa_variant(kt->type))
+ for (i = 0; keyimpls[i] != NULL; i++) {
+ if (!key_type_is_ecdsa_variant(keyimpls[i]->type))
continue;
- if (kt->name != NULL && strcmp(name, kt->name) == 0)
- return kt->nid;
+ if (keyimpls[i]->name != NULL &&
+ strcmp(name, keyimpls[i]->name) == 0)
+ return keyimpls[i]->nid;
}
return -1;
}
int
sshkey_match_keyname_to_sigalgs(const char *keyname, const char *sigalgs)
{
int ktype;
if (sigalgs == NULL || *sigalgs == '\0' ||
(ktype = sshkey_type_from_name(keyname)) == KEY_UNSPEC)
return 0;
else if (ktype == KEY_RSA) {
return match_pattern_list("ssh-rsa", sigalgs, 0) == 1 ||
match_pattern_list("rsa-sha2-256", sigalgs, 0) == 1 ||
match_pattern_list("rsa-sha2-512", sigalgs, 0) == 1;
} else if (ktype == KEY_RSA_CERT) {
return match_pattern_list("ssh-rsa-cert-v01@openssh.com",
sigalgs, 0) == 1 ||
match_pattern_list("rsa-sha2-256-cert-v01@openssh.com",
sigalgs, 0) == 1 ||
match_pattern_list("rsa-sha2-512-cert-v01@openssh.com",
sigalgs, 0) == 1;
} else
return match_pattern_list(keyname, sigalgs, 0) == 1;
}
char *
sshkey_alg_list(int certs_only, int plain_only, int include_sigonly, char sep)
{
char *tmp, *ret = NULL;
- size_t nlen, rlen = 0;
- const struct keytype *kt;
+ size_t i, nlen, rlen = 0;
+ const struct sshkey_impl *impl;
- for (kt = keytypes; kt->type != -1; kt++) {
- if (kt->name == NULL)
+ for (i = 0; keyimpls[i] != NULL; i++) {
+ impl = keyimpls[i];
+ if (impl->name == NULL)
continue;
- if (!include_sigonly && kt->sigonly)
+ if (!include_sigonly && impl->sigonly)
continue;
- if ((certs_only && !kt->cert) || (plain_only && kt->cert))
+ if ((certs_only && !impl->cert) || (plain_only && impl->cert))
continue;
if (ret != NULL)
ret[rlen++] = sep;
- nlen = strlen(kt->name);
+ nlen = strlen(impl->name);
if ((tmp = realloc(ret, rlen + nlen + 2)) == NULL) {
free(ret);
return NULL;
}
ret = tmp;
- memcpy(ret + rlen, kt->name, nlen + 1);
+ memcpy(ret + rlen, impl->name, nlen + 1);
rlen += nlen;
}
return ret;
}
int
sshkey_names_valid2(const char *names, int allow_wildcard)
{
char *s, *cp, *p;
- const struct keytype *kt;
- int type;
+ const struct sshkey_impl *impl;
+ int i, type;
if (names == NULL || strcmp(names, "") == 0)
return 0;
if ((s = cp = strdup(names)) == NULL)
return 0;
for ((p = strsep(&cp, ",")); p && *p != '\0';
(p = strsep(&cp, ","))) {
type = sshkey_type_from_name(p);
if (type == KEY_UNSPEC) {
if (allow_wildcard) {
/*
* Try matching key types against the string.
* If any has a positive or negative match then
* the component is accepted.
*/
- for (kt = keytypes; kt->type != -1; kt++) {
- if (match_pattern_list(kt->name,
- p, 0) != 0)
+ impl = NULL;
+ for (i = 0; keyimpls[i] != NULL; i++) {
+ if (match_pattern_list(
+ keyimpls[i]->name, p, 0) != 0) {
+ impl = keyimpls[i];
break;
+ }
}
- if (kt->type != -1)
+ if (impl != NULL)
continue;
}
free(s);
return 0;
}
}
free(s);
return 1;
}
u_int
sshkey_size(const struct sshkey *k)
{
-#ifdef WITH_OPENSSL
- const BIGNUM *rsa_n, *dsa_p;
-#endif /* WITH_OPENSSL */
+ const struct sshkey_impl *impl;
- switch (k->type) {
-#ifdef WITH_OPENSSL
- case KEY_RSA:
- case KEY_RSA_CERT:
- if (k->rsa == NULL)
- return 0;
- RSA_get0_key(k->rsa, &rsa_n, NULL, NULL);
- return BN_num_bits(rsa_n);
- case KEY_DSA:
- case KEY_DSA_CERT:
- if (k->dsa == NULL)
- return 0;
- DSA_get0_pqg(k->dsa, &dsa_p, NULL, NULL);
- return BN_num_bits(dsa_p);
- case KEY_ECDSA:
- case KEY_ECDSA_CERT:
- case KEY_ECDSA_SK:
- case KEY_ECDSA_SK_CERT:
- return sshkey_curve_nid_to_bits(k->ecdsa_nid);
-#endif /* WITH_OPENSSL */
- case KEY_ED25519:
- case KEY_ED25519_CERT:
- case KEY_ED25519_SK:
- case KEY_ED25519_SK_CERT:
- case KEY_XMSS:
- case KEY_XMSS_CERT:
- return 256; /* XXX */
- }
- return 0;
+ if ((impl = sshkey_impl_from_key(k)) == NULL)
+ return 0;
+ if (impl->funcs->size != NULL)
+ return impl->funcs->size(k);
+ return impl->keybits;
}
static int
sshkey_type_is_valid_ca(int type)
{
- switch (type) {
- case KEY_RSA:
- case KEY_DSA:
- case KEY_ECDSA:
- case KEY_ECDSA_SK:
- case KEY_ED25519:
- case KEY_ED25519_SK:
- case KEY_XMSS:
- return 1;
- default:
+ const struct sshkey_impl *impl;
+
+ if ((impl = sshkey_impl_from_type(type)) == NULL)
return 0;
- }
+ /* All non-certificate types may act as CAs */
+ return !impl->cert;
}
int
sshkey_is_cert(const struct sshkey *k)
{
if (k == NULL)
return 0;
return sshkey_type_is_cert(k->type);
}
int
sshkey_is_sk(const struct sshkey *k)
{
if (k == NULL)
return 0;
switch (sshkey_type_plain(k->type)) {
case KEY_ECDSA_SK:
case KEY_ED25519_SK:
return 1;
default:
return 0;
}
}
/* Return the cert-less equivalent to a certified key type */
int
sshkey_type_plain(int type)
{
switch (type) {
case KEY_RSA_CERT:
return KEY_RSA;
case KEY_DSA_CERT:
return KEY_DSA;
case KEY_ECDSA_CERT:
return KEY_ECDSA;
case KEY_ECDSA_SK_CERT:
return KEY_ECDSA_SK;
case KEY_ED25519_CERT:
return KEY_ED25519;
case KEY_ED25519_SK_CERT:
return KEY_ED25519_SK;
case KEY_XMSS_CERT:
return KEY_XMSS;
default:
return type;
}
}
+/* Return the cert equivalent to a plain key type */
+static int
+sshkey_type_certified(int type)
+{
+ switch (type) {
+ case KEY_RSA:
+ return KEY_RSA_CERT;
+ case KEY_DSA:
+ return KEY_DSA_CERT;
+ case KEY_ECDSA:
+ return KEY_ECDSA_CERT;
+ case KEY_ECDSA_SK:
+ return KEY_ECDSA_SK_CERT;
+ case KEY_ED25519:
+ return KEY_ED25519_CERT;
+ case KEY_ED25519_SK:
+ return KEY_ED25519_SK_CERT;
+ case KEY_XMSS:
+ return KEY_XMSS_CERT;
+ default:
+ return -1;
+ }
+}
+
#ifdef WITH_OPENSSL
/* XXX: these are really begging for a table-driven approach */
int
sshkey_curve_name_to_nid(const char *name)
{
if (strcmp(name, "nistp256") == 0)
return NID_X9_62_prime256v1;
else if (strcmp(name, "nistp384") == 0)
return NID_secp384r1;
# ifdef OPENSSL_HAS_NISTP521
else if (strcmp(name, "nistp521") == 0)
return NID_secp521r1;
# endif /* OPENSSL_HAS_NISTP521 */
else
return -1;
}
u_int
sshkey_curve_nid_to_bits(int nid)
{
switch (nid) {
case NID_X9_62_prime256v1:
return 256;
case NID_secp384r1:
return 384;
# ifdef OPENSSL_HAS_NISTP521
case NID_secp521r1:
return 521;
# endif /* OPENSSL_HAS_NISTP521 */
default:
return 0;
}
}
int
sshkey_ecdsa_bits_to_nid(int bits)
{
switch (bits) {
case 256:
return NID_X9_62_prime256v1;
case 384:
return NID_secp384r1;
# ifdef OPENSSL_HAS_NISTP521
case 521:
return NID_secp521r1;
# endif /* OPENSSL_HAS_NISTP521 */
default:
return -1;
}
}
const char *
sshkey_curve_nid_to_name(int nid)
{
switch (nid) {
case NID_X9_62_prime256v1:
return "nistp256";
case NID_secp384r1:
return "nistp384";
# ifdef OPENSSL_HAS_NISTP521
case NID_secp521r1:
return "nistp521";
# endif /* OPENSSL_HAS_NISTP521 */
default:
return NULL;
}
}
int
sshkey_ec_nid_to_hash_alg(int nid)
{
int kbits = sshkey_curve_nid_to_bits(nid);
if (kbits <= 0)
return -1;
/* RFC5656 section 6.2.1 */
if (kbits <= 256)
return SSH_DIGEST_SHA256;
else if (kbits <= 384)
return SSH_DIGEST_SHA384;
else
return SSH_DIGEST_SHA512;
}
#endif /* WITH_OPENSSL */
static void
cert_free(struct sshkey_cert *cert)
{
u_int i;
if (cert == NULL)
return;
sshbuf_free(cert->certblob);
sshbuf_free(cert->critical);
sshbuf_free(cert->extensions);
free(cert->key_id);
for (i = 0; i < cert->nprincipals; i++)
free(cert->principals[i]);
free(cert->principals);
sshkey_free(cert->signature_key);
free(cert->signature_type);
freezero(cert, sizeof(*cert));
}
static struct sshkey_cert *
cert_new(void)
{
struct sshkey_cert *cert;
if ((cert = calloc(1, sizeof(*cert))) == NULL)
return NULL;
if ((cert->certblob = sshbuf_new()) == NULL ||
(cert->critical = sshbuf_new()) == NULL ||
(cert->extensions = sshbuf_new()) == NULL) {
cert_free(cert);
return NULL;
}
cert->key_id = NULL;
cert->principals = NULL;
cert->signature_key = NULL;
cert->signature_type = NULL;
return cert;
}
struct sshkey *
sshkey_new(int type)
{
struct sshkey *k;
-#ifdef WITH_OPENSSL
- RSA *rsa;
- DSA *dsa;
-#endif /* WITH_OPENSSL */
+ const struct sshkey_impl *impl = NULL;
+
+ if (type != KEY_UNSPEC &&
+ (impl = sshkey_impl_from_type(type)) == NULL)
+ return NULL;
+ /* All non-certificate types may act as CAs */
if ((k = calloc(1, sizeof(*k))) == NULL)
return NULL;
k->type = type;
- k->ecdsa = NULL;
k->ecdsa_nid = -1;
- k->dsa = NULL;
- k->rsa = NULL;
- k->cert = NULL;
- k->ed25519_sk = NULL;
- k->ed25519_pk = NULL;
- k->xmss_sk = NULL;
- k->xmss_pk = NULL;
- switch (k->type) {
-#ifdef WITH_OPENSSL
- case KEY_RSA:
- case KEY_RSA_CERT:
- if ((rsa = RSA_new()) == NULL) {
- free(k);
- return NULL;
- }
- k->rsa = rsa;
- break;
- case KEY_DSA:
- case KEY_DSA_CERT:
- if ((dsa = DSA_new()) == NULL) {
+ if (impl != NULL && impl->funcs->alloc != NULL) {
+ if (impl->funcs->alloc(k) != 0) {
free(k);
return NULL;
}
- k->dsa = dsa;
- break;
- case KEY_ECDSA:
- case KEY_ECDSA_CERT:
- case KEY_ECDSA_SK:
- case KEY_ECDSA_SK_CERT:
- /* Cannot do anything until we know the group */
- break;
-#endif /* WITH_OPENSSL */
- case KEY_ED25519:
- case KEY_ED25519_CERT:
- case KEY_ED25519_SK:
- case KEY_ED25519_SK_CERT:
- case KEY_XMSS:
- case KEY_XMSS_CERT:
- /* no need to prealloc */
- break;
- case KEY_UNSPEC:
- break;
- default:
- free(k);
- return NULL;
}
-
if (sshkey_is_cert(k)) {
if ((k->cert = cert_new()) == NULL) {
sshkey_free(k);
return NULL;
}
}
return k;
}
+/* Frees common FIDO fields */
void
-sshkey_free(struct sshkey *k)
+sshkey_sk_cleanup(struct sshkey *k)
+{
+ free(k->sk_application);
+ sshbuf_free(k->sk_key_handle);
+ sshbuf_free(k->sk_reserved);
+ k->sk_application = NULL;
+ k->sk_key_handle = k->sk_reserved = NULL;
+}
+
+static void
+sshkey_free_contents(struct sshkey *k)
{
+ const struct sshkey_impl *impl;
+
if (k == NULL)
return;
- switch (k->type) {
-#ifdef WITH_OPENSSL
- case KEY_RSA:
- case KEY_RSA_CERT:
- RSA_free(k->rsa);
- k->rsa = NULL;
- break;
- case KEY_DSA:
- case KEY_DSA_CERT:
- DSA_free(k->dsa);
- k->dsa = NULL;
- break;
-# ifdef OPENSSL_HAS_ECC
- case KEY_ECDSA_SK:
- case KEY_ECDSA_SK_CERT:
- free(k->sk_application);
- sshbuf_free(k->sk_key_handle);
- sshbuf_free(k->sk_reserved);
- /* FALLTHROUGH */
- case KEY_ECDSA:
- case KEY_ECDSA_CERT:
- EC_KEY_free(k->ecdsa);
- k->ecdsa = NULL;
- break;
-# endif /* OPENSSL_HAS_ECC */
-#endif /* WITH_OPENSSL */
- case KEY_ED25519_SK:
- case KEY_ED25519_SK_CERT:
- free(k->sk_application);
- sshbuf_free(k->sk_key_handle);
- sshbuf_free(k->sk_reserved);
- /* FALLTHROUGH */
- case KEY_ED25519:
- case KEY_ED25519_CERT:
- freezero(k->ed25519_pk, ED25519_PK_SZ);
- k->ed25519_pk = NULL;
- freezero(k->ed25519_sk, ED25519_SK_SZ);
- k->ed25519_sk = NULL;
- break;
-#ifdef WITH_XMSS
- case KEY_XMSS:
- case KEY_XMSS_CERT:
- freezero(k->xmss_pk, sshkey_xmss_pklen(k));
- k->xmss_pk = NULL;
- freezero(k->xmss_sk, sshkey_xmss_sklen(k));
- k->xmss_sk = NULL;
- sshkey_xmss_free_state(k);
- free(k->xmss_name);
- k->xmss_name = NULL;
- free(k->xmss_filename);
- k->xmss_filename = NULL;
- break;
-#endif /* WITH_XMSS */
- case KEY_UNSPEC:
- break;
- default:
- break;
- }
+ if ((impl = sshkey_impl_from_type(k->type)) != NULL &&
+ impl->funcs->cleanup != NULL)
+ impl->funcs->cleanup(k);
if (sshkey_is_cert(k))
cert_free(k->cert);
freezero(k->shielded_private, k->shielded_len);
freezero(k->shield_prekey, k->shield_prekey_len);
+}
+
+void
+sshkey_free(struct sshkey *k)
+{
+ sshkey_free_contents(k);
freezero(k, sizeof(*k));
}
static int
cert_compare(struct sshkey_cert *a, struct sshkey_cert *b)
{
if (a == NULL && b == NULL)
return 1;
if (a == NULL || b == NULL)
return 0;
if (sshbuf_len(a->certblob) != sshbuf_len(b->certblob))
return 0;
if (timingsafe_bcmp(sshbuf_ptr(a->certblob), sshbuf_ptr(b->certblob),
sshbuf_len(a->certblob)) != 0)
return 0;
return 1;
}
+/* Compares FIDO-specific pubkey fields only */
+int
+sshkey_sk_fields_equal(const struct sshkey *a, const struct sshkey *b)
+{
+ if (a->sk_application == NULL || b->sk_application == NULL)
+ return 0;
+ if (strcmp(a->sk_application, b->sk_application) != 0)
+ return 0;
+ return 1;
+}
+
/*
* Compare public portions of key only, allowing comparisons between
* certificates and plain keys too.
*/
int
sshkey_equal_public(const struct sshkey *a, const struct sshkey *b)
{
-#if defined(WITH_OPENSSL)
- const BIGNUM *rsa_e_a, *rsa_n_a;
- const BIGNUM *rsa_e_b, *rsa_n_b;
- const BIGNUM *dsa_p_a, *dsa_q_a, *dsa_g_a, *dsa_pub_key_a;
- const BIGNUM *dsa_p_b, *dsa_q_b, *dsa_g_b, *dsa_pub_key_b;
-#endif /* WITH_OPENSSL */
+ const struct sshkey_impl *impl;
if (a == NULL || b == NULL ||
sshkey_type_plain(a->type) != sshkey_type_plain(b->type))
return 0;
-
- switch (a->type) {
-#ifdef WITH_OPENSSL
- case KEY_RSA_CERT:
- case KEY_RSA:
- if (a->rsa == NULL || b->rsa == NULL)
- return 0;
- RSA_get0_key(a->rsa, &rsa_n_a, &rsa_e_a, NULL);
- RSA_get0_key(b->rsa, &rsa_n_b, &rsa_e_b, NULL);
- return BN_cmp(rsa_e_a, rsa_e_b) == 0 &&
- BN_cmp(rsa_n_a, rsa_n_b) == 0;
- case KEY_DSA_CERT:
- case KEY_DSA:
- if (a->dsa == NULL || b->dsa == NULL)
- return 0;
- DSA_get0_pqg(a->dsa, &dsa_p_a, &dsa_q_a, &dsa_g_a);
- DSA_get0_pqg(b->dsa, &dsa_p_b, &dsa_q_b, &dsa_g_b);
- DSA_get0_key(a->dsa, &dsa_pub_key_a, NULL);
- DSA_get0_key(b->dsa, &dsa_pub_key_b, NULL);
- return BN_cmp(dsa_p_a, dsa_p_b) == 0 &&
- BN_cmp(dsa_q_a, dsa_q_b) == 0 &&
- BN_cmp(dsa_g_a, dsa_g_b) == 0 &&
- BN_cmp(dsa_pub_key_a, dsa_pub_key_b) == 0;
-# ifdef OPENSSL_HAS_ECC
- case KEY_ECDSA_SK:
- case KEY_ECDSA_SK_CERT:
- if (a->sk_application == NULL || b->sk_application == NULL)
- return 0;
- if (strcmp(a->sk_application, b->sk_application) != 0)
- return 0;
- /* FALLTHROUGH */
- case KEY_ECDSA_CERT:
- case KEY_ECDSA:
- if (a->ecdsa == NULL || b->ecdsa == NULL ||
- EC_KEY_get0_public_key(a->ecdsa) == NULL ||
- EC_KEY_get0_public_key(b->ecdsa) == NULL)
- return 0;
- if (EC_GROUP_cmp(EC_KEY_get0_group(a->ecdsa),
- EC_KEY_get0_group(b->ecdsa), NULL) != 0 ||
- EC_POINT_cmp(EC_KEY_get0_group(a->ecdsa),
- EC_KEY_get0_public_key(a->ecdsa),
- EC_KEY_get0_public_key(b->ecdsa), NULL) != 0)
- return 0;
- return 1;
-# endif /* OPENSSL_HAS_ECC */
-#endif /* WITH_OPENSSL */
- case KEY_ED25519_SK:
- case KEY_ED25519_SK_CERT:
- if (a->sk_application == NULL || b->sk_application == NULL)
- return 0;
- if (strcmp(a->sk_application, b->sk_application) != 0)
- return 0;
- /* FALLTHROUGH */
- case KEY_ED25519:
- case KEY_ED25519_CERT:
- return a->ed25519_pk != NULL && b->ed25519_pk != NULL &&
- memcmp(a->ed25519_pk, b->ed25519_pk, ED25519_PK_SZ) == 0;
-#ifdef WITH_XMSS
- case KEY_XMSS:
- case KEY_XMSS_CERT:
- return a->xmss_pk != NULL && b->xmss_pk != NULL &&
- sshkey_xmss_pklen(a) == sshkey_xmss_pklen(b) &&
- memcmp(a->xmss_pk, b->xmss_pk, sshkey_xmss_pklen(a)) == 0;
-#endif /* WITH_XMSS */
- default:
+ if ((impl = sshkey_impl_from_type(a->type)) == NULL)
return 0;
- }
- /* NOTREACHED */
+ return impl->funcs->equal(a, b);
}
int
sshkey_equal(const struct sshkey *a, const struct sshkey *b)
{
if (a == NULL || b == NULL || a->type != b->type)
return 0;
if (sshkey_is_cert(a)) {
if (!cert_compare(a->cert, b->cert))
return 0;
}
return sshkey_equal_public(a, b);
}
+
+/* Serialise common FIDO key parts */
+int
+sshkey_serialize_sk(const struct sshkey *key, struct sshbuf *b)
+{
+ int r;
+
+ if ((r = sshbuf_put_cstring(b, key->sk_application)) != 0)
+ return r;
+
+ return 0;
+}
+
static int
to_blob_buf(const struct sshkey *key, struct sshbuf *b, int force_plain,
enum sshkey_serialize_rep opts)
{
int type, ret = SSH_ERR_INTERNAL_ERROR;
const char *typename;
-#ifdef WITH_OPENSSL
- const BIGNUM *rsa_n, *rsa_e, *dsa_p, *dsa_q, *dsa_g, *dsa_pub_key;
-#endif /* WITH_OPENSSL */
+ const struct sshkey_impl *impl;
if (key == NULL)
return SSH_ERR_INVALID_ARGUMENT;
- if (sshkey_is_cert(key)) {
+ type = force_plain ? sshkey_type_plain(key->type) : key->type;
+
+ if (sshkey_type_is_cert(type)) {
if (key->cert == NULL)
return SSH_ERR_EXPECTED_CERT;
if (sshbuf_len(key->cert->certblob) == 0)
return SSH_ERR_KEY_LACKS_CERTBLOB;
- }
- type = force_plain ? sshkey_type_plain(key->type) : key->type;
- typename = sshkey_ssh_name_from_type_nid(type, key->ecdsa_nid);
-
- switch (type) {
-#ifdef WITH_OPENSSL
- case KEY_DSA_CERT:
- case KEY_ECDSA_CERT:
- case KEY_ECDSA_SK_CERT:
- case KEY_RSA_CERT:
-#endif /* WITH_OPENSSL */
- case KEY_ED25519_CERT:
- case KEY_ED25519_SK_CERT:
-#ifdef WITH_XMSS
- case KEY_XMSS_CERT:
-#endif /* WITH_XMSS */
/* Use the existing blob */
- /* XXX modified flag? */
if ((ret = sshbuf_putb(b, key->cert->certblob)) != 0)
return ret;
- break;
-#ifdef WITH_OPENSSL
- case KEY_DSA:
- if (key->dsa == NULL)
- return SSH_ERR_INVALID_ARGUMENT;
- DSA_get0_pqg(key->dsa, &dsa_p, &dsa_q, &dsa_g);
- DSA_get0_key(key->dsa, &dsa_pub_key, NULL);
- if ((ret = sshbuf_put_cstring(b, typename)) != 0 ||
- (ret = sshbuf_put_bignum2(b, dsa_p)) != 0 ||
- (ret = sshbuf_put_bignum2(b, dsa_q)) != 0 ||
- (ret = sshbuf_put_bignum2(b, dsa_g)) != 0 ||
- (ret = sshbuf_put_bignum2(b, dsa_pub_key)) != 0)
- return ret;
- break;
-# ifdef OPENSSL_HAS_ECC
- case KEY_ECDSA:
- case KEY_ECDSA_SK:
- if (key->ecdsa == NULL)
- return SSH_ERR_INVALID_ARGUMENT;
- if ((ret = sshbuf_put_cstring(b, typename)) != 0 ||
- (ret = sshbuf_put_cstring(b,
- sshkey_curve_nid_to_name(key->ecdsa_nid))) != 0 ||
- (ret = sshbuf_put_eckey(b, key->ecdsa)) != 0)
- return ret;
- if (type == KEY_ECDSA_SK) {
- if ((ret = sshbuf_put_cstring(b,
- key->sk_application)) != 0)
- return ret;
- }
- break;
-# endif
- case KEY_RSA:
- if (key->rsa == NULL)
- return SSH_ERR_INVALID_ARGUMENT;
- RSA_get0_key(key->rsa, &rsa_n, &rsa_e, NULL);
- if ((ret = sshbuf_put_cstring(b, typename)) != 0 ||
- (ret = sshbuf_put_bignum2(b, rsa_e)) != 0 ||
- (ret = sshbuf_put_bignum2(b, rsa_n)) != 0)
- return ret;
- break;
-#endif /* WITH_OPENSSL */
- case KEY_ED25519:
- case KEY_ED25519_SK:
- if (key->ed25519_pk == NULL)
- return SSH_ERR_INVALID_ARGUMENT;
- if ((ret = sshbuf_put_cstring(b, typename)) != 0 ||
- (ret = sshbuf_put_string(b,
- key->ed25519_pk, ED25519_PK_SZ)) != 0)
- return ret;
- if (type == KEY_ED25519_SK) {
- if ((ret = sshbuf_put_cstring(b,
- key->sk_application)) != 0)
- return ret;
- }
- break;
-#ifdef WITH_XMSS
- case KEY_XMSS:
- if (key->xmss_name == NULL || key->xmss_pk == NULL ||
- sshkey_xmss_pklen(key) == 0)
- return SSH_ERR_INVALID_ARGUMENT;
- if ((ret = sshbuf_put_cstring(b, typename)) != 0 ||
- (ret = sshbuf_put_cstring(b, key->xmss_name)) != 0 ||
- (ret = sshbuf_put_string(b,
- key->xmss_pk, sshkey_xmss_pklen(key))) != 0 ||
- (ret = sshkey_xmss_serialize_pk_info(key, b, opts)) != 0)
- return ret;
- break;
-#endif /* WITH_XMSS */
- default:
- return SSH_ERR_KEY_TYPE_UNKNOWN;
+ return 0;
}
- return 0;
+ if ((impl = sshkey_impl_from_type(type)) == NULL)
+ return SSH_ERR_KEY_TYPE_UNKNOWN;
+
+ typename = sshkey_ssh_name_from_type_nid(type, key->ecdsa_nid);
+ if ((ret = sshbuf_put_cstring(b, typename)) != 0)
+ return ret;
+ return impl->funcs->serialize_public(key, b, opts);
}
int
sshkey_putb(const struct sshkey *key, struct sshbuf *b)
{
return to_blob_buf(key, b, 0, SSHKEY_SERIALIZE_DEFAULT);
}
int
sshkey_puts_opts(const struct sshkey *key, struct sshbuf *b,
enum sshkey_serialize_rep opts)
{
struct sshbuf *tmp;
int r;
if ((tmp = sshbuf_new()) == NULL)
return SSH_ERR_ALLOC_FAIL;
r = to_blob_buf(key, tmp, 0, opts);
if (r == 0)
r = sshbuf_put_stringb(b, tmp);
sshbuf_free(tmp);
return r;
}
int
sshkey_puts(const struct sshkey *key, struct sshbuf *b)
{
return sshkey_puts_opts(key, b, SSHKEY_SERIALIZE_DEFAULT);
}
int
sshkey_putb_plain(const struct sshkey *key, struct sshbuf *b)
{
return to_blob_buf(key, b, 1, SSHKEY_SERIALIZE_DEFAULT);
}
static int
to_blob(const struct sshkey *key, u_char **blobp, size_t *lenp, int force_plain,
enum sshkey_serialize_rep opts)
{
int ret = SSH_ERR_INTERNAL_ERROR;
size_t len;
struct sshbuf *b = NULL;
if (lenp != NULL)
*lenp = 0;
if (blobp != NULL)
*blobp = NULL;
if ((b = sshbuf_new()) == NULL)
return SSH_ERR_ALLOC_FAIL;
if ((ret = to_blob_buf(key, b, force_plain, opts)) != 0)
goto out;
len = sshbuf_len(b);
if (lenp != NULL)
*lenp = len;
if (blobp != NULL) {
if ((*blobp = malloc(len)) == NULL) {
ret = SSH_ERR_ALLOC_FAIL;
goto out;
}
memcpy(*blobp, sshbuf_ptr(b), len);
}
ret = 0;
out:
sshbuf_free(b);
return ret;
}
int
sshkey_to_blob(const struct sshkey *key, u_char **blobp, size_t *lenp)
{
return to_blob(key, blobp, lenp, 0, SSHKEY_SERIALIZE_DEFAULT);
}
int
sshkey_plain_to_blob(const struct sshkey *key, u_char **blobp, size_t *lenp)
{
return to_blob(key, blobp, lenp, 1, SSHKEY_SERIALIZE_DEFAULT);
}
int
sshkey_fingerprint_raw(const struct sshkey *k, int dgst_alg,
u_char **retp, size_t *lenp)
{
u_char *blob = NULL, *ret = NULL;
size_t blob_len = 0;
int r = SSH_ERR_INTERNAL_ERROR;
if (retp != NULL)
*retp = NULL;
if (lenp != NULL)
*lenp = 0;
if (ssh_digest_bytes(dgst_alg) == 0) {
r = SSH_ERR_INVALID_ARGUMENT;
goto out;
}
if ((r = to_blob(k, &blob, &blob_len, 1, SSHKEY_SERIALIZE_DEFAULT))
!= 0)
goto out;
if ((ret = calloc(1, SSH_DIGEST_MAX_LENGTH)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
if ((r = ssh_digest_memory(dgst_alg, blob, blob_len,
ret, SSH_DIGEST_MAX_LENGTH)) != 0)
goto out;
/* success */
if (retp != NULL) {
*retp = ret;
ret = NULL;
}
if (lenp != NULL)
*lenp = ssh_digest_bytes(dgst_alg);
r = 0;
out:
free(ret);
if (blob != NULL)
freezero(blob, blob_len);
return r;
}
static char *
fingerprint_b64(const char *alg, u_char *dgst_raw, size_t dgst_raw_len)
{
char *ret;
size_t plen = strlen(alg) + 1;
size_t rlen = ((dgst_raw_len + 2) / 3) * 4 + plen + 1;
if (dgst_raw_len > 65536 || (ret = calloc(1, rlen)) == NULL)
return NULL;
strlcpy(ret, alg, rlen);
strlcat(ret, ":", rlen);
if (dgst_raw_len == 0)
return ret;
if (b64_ntop(dgst_raw, dgst_raw_len, ret + plen, rlen - plen) == -1) {
freezero(ret, rlen);
return NULL;
}
/* Trim padding characters from end */
ret[strcspn(ret, "=")] = '\0';
return ret;
}
static char *
fingerprint_hex(const char *alg, u_char *dgst_raw, size_t dgst_raw_len)
{
char *retval, hex[5];
size_t i, rlen = dgst_raw_len * 3 + strlen(alg) + 2;
if (dgst_raw_len > 65536 || (retval = calloc(1, rlen)) == NULL)
return NULL;
strlcpy(retval, alg, rlen);
strlcat(retval, ":", rlen);
for (i = 0; i < dgst_raw_len; i++) {
snprintf(hex, sizeof(hex), "%s%02x",
i > 0 ? ":" : "", dgst_raw[i]);
strlcat(retval, hex, rlen);
}
return retval;
}
static char *
fingerprint_bubblebabble(u_char *dgst_raw, size_t dgst_raw_len)
{
char vowels[] = { 'a', 'e', 'i', 'o', 'u', 'y' };
char consonants[] = { 'b', 'c', 'd', 'f', 'g', 'h', 'k', 'l', 'm',
'n', 'p', 'r', 's', 't', 'v', 'z', 'x' };
u_int i, j = 0, rounds, seed = 1;
char *retval;
rounds = (dgst_raw_len / 2) + 1;
if ((retval = calloc(rounds, 6)) == NULL)
return NULL;
retval[j++] = 'x';
for (i = 0; i < rounds; i++) {
u_int idx0, idx1, idx2, idx3, idx4;
if ((i + 1 < rounds) || (dgst_raw_len % 2 != 0)) {
idx0 = (((((u_int)(dgst_raw[2 * i])) >> 6) & 3) +
seed) % 6;
idx1 = (((u_int)(dgst_raw[2 * i])) >> 2) & 15;
idx2 = ((((u_int)(dgst_raw[2 * i])) & 3) +
(seed / 6)) % 6;
retval[j++] = vowels[idx0];
retval[j++] = consonants[idx1];
retval[j++] = vowels[idx2];
if ((i + 1) < rounds) {
idx3 = (((u_int)(dgst_raw[(2 * i) + 1])) >> 4) & 15;
idx4 = (((u_int)(dgst_raw[(2 * i) + 1]))) & 15;
retval[j++] = consonants[idx3];
retval[j++] = '-';
retval[j++] = consonants[idx4];
seed = ((seed * 5) +
((((u_int)(dgst_raw[2 * i])) * 7) +
((u_int)(dgst_raw[(2 * i) + 1])))) % 36;
}
} else {
idx0 = seed % 6;
idx1 = 16;
idx2 = seed / 6;
retval[j++] = vowels[idx0];
retval[j++] = consonants[idx1];
retval[j++] = vowels[idx2];
}
}
retval[j++] = 'x';
retval[j++] = '\0';
return retval;
}
/*
* Draw an ASCII-Art representing the fingerprint so human brain can
* profit from its built-in pattern recognition ability.
* This technique is called "random art" and can be found in some
* scientific publications like this original paper:
*
* "Hash Visualization: a New Technique to improve Real-World Security",
* Perrig A. and Song D., 1999, International Workshop on Cryptographic
* Techniques and E-Commerce (CrypTEC '99)
* sparrow.ece.cmu.edu/~adrian/projects/validation/validation.pdf
*
* The subject came up in a talk by Dan Kaminsky, too.
*
* If you see the picture is different, the key is different.
* If the picture looks the same, you still know nothing.
*
* The algorithm used here is a worm crawling over a discrete plane,
* leaving a trace (augmenting the field) everywhere it goes.
* Movement is taken from dgst_raw 2bit-wise. Bumping into walls
* makes the respective movement vector be ignored for this turn.
* Graphs are not unambiguous, because circles in graphs can be
* walked in either direction.
*/
/*
* Field sizes for the random art. Have to be odd, so the starting point
* can be in the exact middle of the picture, and FLDBASE should be >=8 .
* Else pictures would be too dense, and drawing the frame would
* fail, too, because the key type would not fit in anymore.
*/
#define FLDBASE 8
#define FLDSIZE_Y (FLDBASE + 1)
#define FLDSIZE_X (FLDBASE * 2 + 1)
static char *
fingerprint_randomart(const char *alg, u_char *dgst_raw, size_t dgst_raw_len,
const struct sshkey *k)
{
/*
* Chars to be used after each other every time the worm
* intersects with itself. Matter of taste.
*/
char *augmentation_string = " .o+=*BOX@%&#/^SE";
char *retval, *p, title[FLDSIZE_X], hash[FLDSIZE_X];
u_char field[FLDSIZE_X][FLDSIZE_Y];
size_t i, tlen, hlen;
u_int b;
int x, y, r;
size_t len = strlen(augmentation_string) - 1;
if ((retval = calloc((FLDSIZE_X + 3), (FLDSIZE_Y + 2))) == NULL)
return NULL;
/* initialize field */
memset(field, 0, FLDSIZE_X * FLDSIZE_Y * sizeof(char));
x = FLDSIZE_X / 2;
y = FLDSIZE_Y / 2;
/* process raw key */
for (i = 0; i < dgst_raw_len; i++) {
int input;
/* each byte conveys four 2-bit move commands */
input = dgst_raw[i];
for (b = 0; b < 4; b++) {
/* evaluate 2 bit, rest is shifted later */
x += (input & 0x1) ? 1 : -1;
y += (input & 0x2) ? 1 : -1;
/* assure we are still in bounds */
x = MAXIMUM(x, 0);
y = MAXIMUM(y, 0);
x = MINIMUM(x, FLDSIZE_X - 1);
y = MINIMUM(y, FLDSIZE_Y - 1);
/* augment the field */
if (field[x][y] < len - 2)
field[x][y]++;
input = input >> 2;
}
}
/* mark starting point and end point*/
field[FLDSIZE_X / 2][FLDSIZE_Y / 2] = len - 1;
field[x][y] = len;
/* assemble title */
r = snprintf(title, sizeof(title), "[%s %u]",
sshkey_type(k), sshkey_size(k));
/* If [type size] won't fit, then try [type]; fits "[ED25519-CERT]" */
if (r < 0 || r > (int)sizeof(title))
r = snprintf(title, sizeof(title), "[%s]", sshkey_type(k));
tlen = (r <= 0) ? 0 : strlen(title);
/* assemble hash ID. */
r = snprintf(hash, sizeof(hash), "[%s]", alg);
hlen = (r <= 0) ? 0 : strlen(hash);
/* output upper border */
p = retval;
*p++ = '+';
for (i = 0; i < (FLDSIZE_X - tlen) / 2; i++)
*p++ = '-';
memcpy(p, title, tlen);
p += tlen;
for (i += tlen; i < FLDSIZE_X; i++)
*p++ = '-';
*p++ = '+';
*p++ = '\n';
/* output content */
for (y = 0; y < FLDSIZE_Y; y++) {
*p++ = '|';
for (x = 0; x < FLDSIZE_X; x++)
*p++ = augmentation_string[MINIMUM(field[x][y], len)];
*p++ = '|';
*p++ = '\n';
}
/* output lower border */
*p++ = '+';
for (i = 0; i < (FLDSIZE_X - hlen) / 2; i++)
*p++ = '-';
memcpy(p, hash, hlen);
p += hlen;
for (i += hlen; i < FLDSIZE_X; i++)
*p++ = '-';
*p++ = '+';
return retval;
}
char *
sshkey_fingerprint(const struct sshkey *k, int dgst_alg,
enum sshkey_fp_rep dgst_rep)
{
char *retval = NULL;
u_char *dgst_raw;
size_t dgst_raw_len;
if (sshkey_fingerprint_raw(k, dgst_alg, &dgst_raw, &dgst_raw_len) != 0)
return NULL;
switch (dgst_rep) {
case SSH_FP_DEFAULT:
if (dgst_alg == SSH_DIGEST_MD5) {
retval = fingerprint_hex(ssh_digest_alg_name(dgst_alg),
dgst_raw, dgst_raw_len);
} else {
retval = fingerprint_b64(ssh_digest_alg_name(dgst_alg),
dgst_raw, dgst_raw_len);
}
break;
case SSH_FP_HEX:
retval = fingerprint_hex(ssh_digest_alg_name(dgst_alg),
dgst_raw, dgst_raw_len);
break;
case SSH_FP_BASE64:
retval = fingerprint_b64(ssh_digest_alg_name(dgst_alg),
dgst_raw, dgst_raw_len);
break;
case SSH_FP_BUBBLEBABBLE:
retval = fingerprint_bubblebabble(dgst_raw, dgst_raw_len);
break;
case SSH_FP_RANDOMART:
retval = fingerprint_randomart(ssh_digest_alg_name(dgst_alg),
dgst_raw, dgst_raw_len, k);
break;
default:
freezero(dgst_raw, dgst_raw_len);
return NULL;
}
freezero(dgst_raw, dgst_raw_len);
return retval;
}
static int
peek_type_nid(const char *s, size_t l, int *nid)
{
- const struct keytype *kt;
+ const struct sshkey_impl *impl;
+ int i;
- for (kt = keytypes; kt->type != -1; kt++) {
- if (kt->name == NULL || strlen(kt->name) != l)
+ for (i = 0; keyimpls[i] != NULL; i++) {
+ impl = keyimpls[i];
+ if (impl->name == NULL || strlen(impl->name) != l)
continue;
- if (memcmp(s, kt->name, l) == 0) {
+ if (memcmp(s, impl->name, l) == 0) {
*nid = -1;
- if (key_type_is_ecdsa_variant(kt->type))
- *nid = kt->nid;
- return kt->type;
+ if (key_type_is_ecdsa_variant(impl->type))
+ *nid = impl->nid;
+ return impl->type;
}
}
return KEY_UNSPEC;
}
/* XXX this can now be made const char * */
int
sshkey_read(struct sshkey *ret, char **cpp)
{
struct sshkey *k;
char *cp, *blobcopy;
size_t space;
int r, type, curve_nid = -1;
struct sshbuf *blob;
if (ret == NULL)
return SSH_ERR_INVALID_ARGUMENT;
-
- switch (ret->type) {
- case KEY_UNSPEC:
- case KEY_RSA:
- case KEY_DSA:
- case KEY_ECDSA:
- case KEY_ECDSA_SK:
- case KEY_ED25519:
- case KEY_ED25519_SK:
- case KEY_DSA_CERT:
- case KEY_ECDSA_CERT:
- case KEY_ECDSA_SK_CERT:
- case KEY_RSA_CERT:
- case KEY_ED25519_CERT:
- case KEY_ED25519_SK_CERT:
-#ifdef WITH_XMSS
- case KEY_XMSS:
- case KEY_XMSS_CERT:
-#endif /* WITH_XMSS */
- break; /* ok */
- default:
+ if (ret->type != KEY_UNSPEC && sshkey_impl_from_type(ret->type) == NULL)
return SSH_ERR_INVALID_ARGUMENT;
- }
/* Decode type */
cp = *cpp;
space = strcspn(cp, " \t");
if (space == strlen(cp))
return SSH_ERR_INVALID_FORMAT;
if ((type = peek_type_nid(cp, space, &curve_nid)) == KEY_UNSPEC)
return SSH_ERR_INVALID_FORMAT;
/* skip whitespace */
for (cp += space; *cp == ' ' || *cp == '\t'; cp++)
;
if (*cp == '\0')
return SSH_ERR_INVALID_FORMAT;
if (ret->type != KEY_UNSPEC && ret->type != type)
return SSH_ERR_KEY_TYPE_MISMATCH;
if ((blob = sshbuf_new()) == NULL)
return SSH_ERR_ALLOC_FAIL;
/* find end of keyblob and decode */
space = strcspn(cp, " \t");
if ((blobcopy = strndup(cp, space)) == NULL) {
sshbuf_free(blob);
return SSH_ERR_ALLOC_FAIL;
}
if ((r = sshbuf_b64tod(blob, blobcopy)) != 0) {
free(blobcopy);
sshbuf_free(blob);
return r;
}
free(blobcopy);
if ((r = sshkey_fromb(blob, &k)) != 0) {
sshbuf_free(blob);
return r;
}
sshbuf_free(blob);
/* skip whitespace and leave cp at start of comment */
for (cp += space; *cp == ' ' || *cp == '\t'; cp++)
;
/* ensure type of blob matches type at start of line */
if (k->type != type) {
sshkey_free(k);
return SSH_ERR_KEY_TYPE_MISMATCH;
}
if (key_type_is_ecdsa_variant(type) && curve_nid != k->ecdsa_nid) {
sshkey_free(k);
return SSH_ERR_EC_CURVE_MISMATCH;
}
/* Fill in ret from parsed key */
- ret->type = type;
- if (sshkey_is_cert(ret)) {
- if (!sshkey_is_cert(k)) {
- sshkey_free(k);
- return SSH_ERR_EXPECTED_CERT;
- }
- if (ret->cert != NULL)
- cert_free(ret->cert);
- ret->cert = k->cert;
- k->cert = NULL;
- }
- switch (sshkey_type_plain(ret->type)) {
-#ifdef WITH_OPENSSL
- case KEY_RSA:
- RSA_free(ret->rsa);
- ret->rsa = k->rsa;
- k->rsa = NULL;
-#ifdef DEBUG_PK
- RSA_print_fp(stderr, ret->rsa, 8);
-#endif
- break;
- case KEY_DSA:
- DSA_free(ret->dsa);
- ret->dsa = k->dsa;
- k->dsa = NULL;
-#ifdef DEBUG_PK
- DSA_print_fp(stderr, ret->dsa, 8);
-#endif
- break;
-# ifdef OPENSSL_HAS_ECC
- case KEY_ECDSA:
- EC_KEY_free(ret->ecdsa);
- ret->ecdsa = k->ecdsa;
- ret->ecdsa_nid = k->ecdsa_nid;
- k->ecdsa = NULL;
- k->ecdsa_nid = -1;
-#ifdef DEBUG_PK
- sshkey_dump_ec_key(ret->ecdsa);
-#endif
- break;
- case KEY_ECDSA_SK:
- EC_KEY_free(ret->ecdsa);
- ret->ecdsa = k->ecdsa;
- ret->ecdsa_nid = k->ecdsa_nid;
- ret->sk_application = k->sk_application;
- k->ecdsa = NULL;
- k->ecdsa_nid = -1;
- k->sk_application = NULL;
-#ifdef DEBUG_PK
- sshkey_dump_ec_key(ret->ecdsa);
- fprintf(stderr, "App: %s\n", ret->sk_application);
-#endif
- break;
-# endif /* OPENSSL_HAS_ECC */
-#endif /* WITH_OPENSSL */
- case KEY_ED25519:
- freezero(ret->ed25519_pk, ED25519_PK_SZ);
- ret->ed25519_pk = k->ed25519_pk;
- k->ed25519_pk = NULL;
-#ifdef DEBUG_PK
- /* XXX */
-#endif
- break;
- case KEY_ED25519_SK:
- freezero(ret->ed25519_pk, ED25519_PK_SZ);
- ret->ed25519_pk = k->ed25519_pk;
- ret->sk_application = k->sk_application;
- k->ed25519_pk = NULL;
- k->sk_application = NULL;
- break;
-#ifdef WITH_XMSS
- case KEY_XMSS:
- free(ret->xmss_pk);
- ret->xmss_pk = k->xmss_pk;
- k->xmss_pk = NULL;
- free(ret->xmss_state);
- ret->xmss_state = k->xmss_state;
- k->xmss_state = NULL;
- free(ret->xmss_name);
- ret->xmss_name = k->xmss_name;
- k->xmss_name = NULL;
- free(ret->xmss_filename);
- ret->xmss_filename = k->xmss_filename;
- k->xmss_filename = NULL;
-#ifdef DEBUG_PK
- /* XXX */
-#endif
- break;
-#endif /* WITH_XMSS */
- default:
- sshkey_free(k);
- return SSH_ERR_INTERNAL_ERROR;
- }
- sshkey_free(k);
+ sshkey_free_contents(ret);
+ *ret = *k;
+ freezero(k, sizeof(*k));
/* success */
*cpp = cp;
return 0;
}
-
int
sshkey_to_base64(const struct sshkey *key, char **b64p)
{
int r = SSH_ERR_INTERNAL_ERROR;
struct sshbuf *b = NULL;
char *uu = NULL;
if (b64p != NULL)
*b64p = NULL;
if ((b = sshbuf_new()) == NULL)
return SSH_ERR_ALLOC_FAIL;
if ((r = sshkey_putb(key, b)) != 0)
goto out;
if ((uu = sshbuf_dtob64_string(b, 0)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
/* Success */
if (b64p != NULL) {
*b64p = uu;
uu = NULL;
}
r = 0;
out:
sshbuf_free(b);
free(uu);
return r;
}
int
sshkey_format_text(const struct sshkey *key, struct sshbuf *b)
{
int r = SSH_ERR_INTERNAL_ERROR;
char *uu = NULL;
if ((r = sshkey_to_base64(key, &uu)) != 0)
goto out;
if ((r = sshbuf_putf(b, "%s %s",
sshkey_ssh_name(key), uu)) != 0)
goto out;
r = 0;
out:
free(uu);
return r;
}
int
sshkey_write(const struct sshkey *key, FILE *f)
{
struct sshbuf *b = NULL;
int r = SSH_ERR_INTERNAL_ERROR;
if ((b = sshbuf_new()) == NULL)
return SSH_ERR_ALLOC_FAIL;
if ((r = sshkey_format_text(key, b)) != 0)
goto out;
if (fwrite(sshbuf_ptr(b), sshbuf_len(b), 1, f) != 1) {
if (feof(f))
errno = EPIPE;
r = SSH_ERR_SYSTEM_ERROR;
goto out;
}
/* Success */
r = 0;
out:
sshbuf_free(b);
return r;
}
const char *
sshkey_cert_type(const struct sshkey *k)
{
switch (k->cert->type) {
case SSH2_CERT_TYPE_USER:
return "user";
case SSH2_CERT_TYPE_HOST:
return "host";
default:
return "unknown";
}
}
-#ifdef WITH_OPENSSL
-static int
-rsa_generate_private_key(u_int bits, RSA **rsap)
-{
- RSA *private = NULL;
- BIGNUM *f4 = NULL;
- int ret = SSH_ERR_INTERNAL_ERROR;
-
- if (rsap == NULL)
- return SSH_ERR_INVALID_ARGUMENT;
- if (bits < SSH_RSA_MINIMUM_MODULUS_SIZE ||
- bits > SSHBUF_MAX_BIGNUM * 8)
- return SSH_ERR_KEY_LENGTH;
- *rsap = NULL;
- if ((private = RSA_new()) == NULL || (f4 = BN_new()) == NULL) {
- ret = SSH_ERR_ALLOC_FAIL;
- goto out;
- }
- if (!BN_set_word(f4, RSA_F4) ||
- !RSA_generate_key_ex(private, bits, f4, NULL)) {
- ret = SSH_ERR_LIBCRYPTO_ERROR;
- goto out;
- }
- *rsap = private;
- private = NULL;
- ret = 0;
- out:
- RSA_free(private);
- BN_free(f4);
- return ret;
-}
-
-static int
-dsa_generate_private_key(u_int bits, DSA **dsap)
+int
+sshkey_check_rsa_length(const struct sshkey *k, int min_size)
{
- DSA *private;
- int ret = SSH_ERR_INTERNAL_ERROR;
+#ifdef WITH_OPENSSL
+ const BIGNUM *rsa_n;
+ int nbits;
- if (dsap == NULL)
- return SSH_ERR_INVALID_ARGUMENT;
- if (bits != 1024)
+ if (k == NULL || k->rsa == NULL ||
+ (k->type != KEY_RSA && k->type != KEY_RSA_CERT))
+ return 0;
+ RSA_get0_key(k->rsa, &rsa_n, NULL, NULL);
+ nbits = BN_num_bits(rsa_n);
+ if (nbits < SSH_RSA_MINIMUM_MODULUS_SIZE ||
+ (min_size > 0 && nbits < min_size))
return SSH_ERR_KEY_LENGTH;
- if ((private = DSA_new()) == NULL) {
- ret = SSH_ERR_ALLOC_FAIL;
- goto out;
- }
- *dsap = NULL;
- if (!DSA_generate_parameters_ex(private, bits, NULL, 0, NULL,
- NULL, NULL) || !DSA_generate_key(private)) {
- ret = SSH_ERR_LIBCRYPTO_ERROR;
- goto out;
- }
- *dsap = private;
- private = NULL;
- ret = 0;
- out:
- DSA_free(private);
- return ret;
+#endif /* WITH_OPENSSL */
+ return 0;
}
+#ifdef WITH_OPENSSL
# ifdef OPENSSL_HAS_ECC
int
sshkey_ecdsa_key_to_nid(EC_KEY *k)
{
EC_GROUP *eg;
int nids[] = {
NID_X9_62_prime256v1,
NID_secp384r1,
# ifdef OPENSSL_HAS_NISTP521
NID_secp521r1,
# endif /* OPENSSL_HAS_NISTP521 */
-1
};
int nid;
u_int i;
const EC_GROUP *g = EC_KEY_get0_group(k);
/*
* The group may be stored in a ASN.1 encoded private key in one of two
* ways: as a "named group", which is reconstituted by ASN.1 object ID
* or explicit group parameters encoded into the key blob. Only the
* "named group" case sets the group NID for us, but we can figure
* it out for the other case by comparing against all the groups that
* are supported.
*/
if ((nid = EC_GROUP_get_curve_name(g)) > 0)
return nid;
for (i = 0; nids[i] != -1; i++) {
if ((eg = EC_GROUP_new_by_curve_name(nids[i])) == NULL)
return -1;
if (EC_GROUP_cmp(g, eg, NULL) == 0)
break;
EC_GROUP_free(eg);
}
if (nids[i] != -1) {
/* Use the group with the NID attached */
EC_GROUP_set_asn1_flag(eg, OPENSSL_EC_NAMED_CURVE);
if (EC_KEY_set_group(k, eg) != 1) {
EC_GROUP_free(eg);
return -1;
}
}
return nids[i];
}
-
-static int
-ecdsa_generate_private_key(u_int bits, int *nid, EC_KEY **ecdsap)
-{
- EC_KEY *private;
- int ret = SSH_ERR_INTERNAL_ERROR;
-
- if (nid == NULL || ecdsap == NULL)
- return SSH_ERR_INVALID_ARGUMENT;
- if ((*nid = sshkey_ecdsa_bits_to_nid(bits)) == -1)
- return SSH_ERR_KEY_LENGTH;
- *ecdsap = NULL;
- if ((private = EC_KEY_new_by_curve_name(*nid)) == NULL) {
- ret = SSH_ERR_ALLOC_FAIL;
- goto out;
- }
- if (EC_KEY_generate_key(private) != 1) {
- ret = SSH_ERR_LIBCRYPTO_ERROR;
- goto out;
- }
- EC_KEY_set_asn1_flag(private, OPENSSL_EC_NAMED_CURVE);
- *ecdsap = private;
- private = NULL;
- ret = 0;
- out:
- EC_KEY_free(private);
- return ret;
-}
# endif /* OPENSSL_HAS_ECC */
#endif /* WITH_OPENSSL */
int
sshkey_generate(int type, u_int bits, struct sshkey **keyp)
{
struct sshkey *k;
int ret = SSH_ERR_INTERNAL_ERROR;
+ const struct sshkey_impl *impl;
- if (keyp == NULL)
+ if (keyp == NULL || sshkey_type_is_cert(type))
return SSH_ERR_INVALID_ARGUMENT;
*keyp = NULL;
+ if ((impl = sshkey_impl_from_type(type)) == NULL)
+ return SSH_ERR_KEY_TYPE_UNKNOWN;
+ if (impl->funcs->generate == NULL)
+ return SSH_ERR_FEATURE_UNSUPPORTED;
if ((k = sshkey_new(KEY_UNSPEC)) == NULL)
return SSH_ERR_ALLOC_FAIL;
- switch (type) {
- case KEY_ED25519:
- if ((k->ed25519_pk = malloc(ED25519_PK_SZ)) == NULL ||
- (k->ed25519_sk = malloc(ED25519_SK_SZ)) == NULL) {
- ret = SSH_ERR_ALLOC_FAIL;
- break;
- }
- crypto_sign_ed25519_keypair(k->ed25519_pk, k->ed25519_sk);
- ret = 0;
- break;
-#ifdef WITH_XMSS
- case KEY_XMSS:
- ret = sshkey_xmss_generate_private_key(k, bits);
- break;
-#endif /* WITH_XMSS */
-#ifdef WITH_OPENSSL
- case KEY_DSA:
- ret = dsa_generate_private_key(bits, &k->dsa);
- break;
-# ifdef OPENSSL_HAS_ECC
- case KEY_ECDSA:
- ret = ecdsa_generate_private_key(bits, &k->ecdsa_nid,
- &k->ecdsa);
- break;
-# endif /* OPENSSL_HAS_ECC */
- case KEY_RSA:
- ret = rsa_generate_private_key(bits, &k->rsa);
- break;
-#endif /* WITH_OPENSSL */
- default:
- ret = SSH_ERR_INVALID_ARGUMENT;
- }
- if (ret == 0) {
- k->type = type;
- *keyp = k;
- } else
+ k->type = type;
+ if ((ret = impl->funcs->generate(k, bits)) != 0) {
sshkey_free(k);
- return ret;
+ return ret;
+ }
+ /* success */
+ *keyp = k;
+ return 0;
}
int
sshkey_cert_copy(const struct sshkey *from_key, struct sshkey *to_key)
{
u_int i;
const struct sshkey_cert *from;
struct sshkey_cert *to;
int r = SSH_ERR_INTERNAL_ERROR;
if (to_key == NULL || (from = from_key->cert) == NULL)
return SSH_ERR_INVALID_ARGUMENT;
if ((to = cert_new()) == NULL)
return SSH_ERR_ALLOC_FAIL;
if ((r = sshbuf_putb(to->certblob, from->certblob)) != 0 ||
(r = sshbuf_putb(to->critical, from->critical)) != 0 ||
(r = sshbuf_putb(to->extensions, from->extensions)) != 0)
goto out;
to->serial = from->serial;
to->type = from->type;
if (from->key_id == NULL)
to->key_id = NULL;
else if ((to->key_id = strdup(from->key_id)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
to->valid_after = from->valid_after;
to->valid_before = from->valid_before;
if (from->signature_key == NULL)
to->signature_key = NULL;
else if ((r = sshkey_from_private(from->signature_key,
&to->signature_key)) != 0)
goto out;
if (from->signature_type != NULL &&
(to->signature_type = strdup(from->signature_type)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
if (from->nprincipals > SSHKEY_CERT_MAX_PRINCIPALS) {
r = SSH_ERR_INVALID_ARGUMENT;
goto out;
}
if (from->nprincipals > 0) {
if ((to->principals = calloc(from->nprincipals,
sizeof(*to->principals))) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
for (i = 0; i < from->nprincipals; i++) {
to->principals[i] = strdup(from->principals[i]);
if (to->principals[i] == NULL) {
to->nprincipals = i;
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
}
}
to->nprincipals = from->nprincipals;
/* success */
cert_free(to_key->cert);
to_key->cert = to;
to = NULL;
r = 0;
out:
cert_free(to);
return r;
}
+int
+sshkey_copy_public_sk(const struct sshkey *from, struct sshkey *to)
+{
+ /* Append security-key application string */
+ if ((to->sk_application = strdup(from->sk_application)) == NULL)
+ return SSH_ERR_ALLOC_FAIL;
+ return 0;
+}
+
int
sshkey_from_private(const struct sshkey *k, struct sshkey **pkp)
{
struct sshkey *n = NULL;
int r = SSH_ERR_INTERNAL_ERROR;
-#ifdef WITH_OPENSSL
- const BIGNUM *rsa_n, *rsa_e;
- BIGNUM *rsa_n_dup = NULL, *rsa_e_dup = NULL;
- const BIGNUM *dsa_p, *dsa_q, *dsa_g, *dsa_pub_key;
- BIGNUM *dsa_p_dup = NULL, *dsa_q_dup = NULL, *dsa_g_dup = NULL;
- BIGNUM *dsa_pub_key_dup = NULL;
-#endif /* WITH_OPENSSL */
+ const struct sshkey_impl *impl;
*pkp = NULL;
+ if ((impl = sshkey_impl_from_key(k)) == NULL)
+ return SSH_ERR_KEY_TYPE_UNKNOWN;
if ((n = sshkey_new(k->type)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
- switch (k->type) {
-#ifdef WITH_OPENSSL
- case KEY_DSA:
- case KEY_DSA_CERT:
- DSA_get0_pqg(k->dsa, &dsa_p, &dsa_q, &dsa_g);
- DSA_get0_key(k->dsa, &dsa_pub_key, NULL);
- if ((dsa_p_dup = BN_dup(dsa_p)) == NULL ||
- (dsa_q_dup = BN_dup(dsa_q)) == NULL ||
- (dsa_g_dup = BN_dup(dsa_g)) == NULL ||
- (dsa_pub_key_dup = BN_dup(dsa_pub_key)) == NULL) {
- r = SSH_ERR_ALLOC_FAIL;
- goto out;
- }
- if (!DSA_set0_pqg(n->dsa, dsa_p_dup, dsa_q_dup, dsa_g_dup)) {
- r = SSH_ERR_LIBCRYPTO_ERROR;
- goto out;
- }
- dsa_p_dup = dsa_q_dup = dsa_g_dup = NULL; /* transferred */
- if (!DSA_set0_key(n->dsa, dsa_pub_key_dup, NULL)) {
- r = SSH_ERR_LIBCRYPTO_ERROR;
- goto out;
- }
- dsa_pub_key_dup = NULL; /* transferred */
-
- break;
-# ifdef OPENSSL_HAS_ECC
- case KEY_ECDSA:
- case KEY_ECDSA_CERT:
- case KEY_ECDSA_SK:
- case KEY_ECDSA_SK_CERT:
- n->ecdsa_nid = k->ecdsa_nid;
- n->ecdsa = EC_KEY_new_by_curve_name(k->ecdsa_nid);
- if (n->ecdsa == NULL) {
- r = SSH_ERR_ALLOC_FAIL;
- goto out;
- }
- if (EC_KEY_set_public_key(n->ecdsa,
- EC_KEY_get0_public_key(k->ecdsa)) != 1) {
- r = SSH_ERR_LIBCRYPTO_ERROR;
- goto out;
- }
- if (k->type != KEY_ECDSA_SK && k->type != KEY_ECDSA_SK_CERT)
- break;
- /* Append security-key application string */
- if ((n->sk_application = strdup(k->sk_application)) == NULL)
- goto out;
- break;
-# endif /* OPENSSL_HAS_ECC */
- case KEY_RSA:
- case KEY_RSA_CERT:
- RSA_get0_key(k->rsa, &rsa_n, &rsa_e, NULL);
- if ((rsa_n_dup = BN_dup(rsa_n)) == NULL ||
- (rsa_e_dup = BN_dup(rsa_e)) == NULL) {
- r = SSH_ERR_ALLOC_FAIL;
- goto out;
- }
- if (!RSA_set0_key(n->rsa, rsa_n_dup, rsa_e_dup, NULL)) {
- r = SSH_ERR_LIBCRYPTO_ERROR;
- goto out;
- }
- rsa_n_dup = rsa_e_dup = NULL; /* transferred */
- break;
-#endif /* WITH_OPENSSL */
- case KEY_ED25519:
- case KEY_ED25519_CERT:
- case KEY_ED25519_SK:
- case KEY_ED25519_SK_CERT:
- if (k->ed25519_pk != NULL) {
- if ((n->ed25519_pk = malloc(ED25519_PK_SZ)) == NULL) {
- r = SSH_ERR_ALLOC_FAIL;
- goto out;
- }
- memcpy(n->ed25519_pk, k->ed25519_pk, ED25519_PK_SZ);
- }
- if (k->type != KEY_ED25519_SK &&
- k->type != KEY_ED25519_SK_CERT)
- break;
- /* Append security-key application string */
- if ((n->sk_application = strdup(k->sk_application)) == NULL)
- goto out;
- break;
-#ifdef WITH_XMSS
- case KEY_XMSS:
- case KEY_XMSS_CERT:
- if ((r = sshkey_xmss_init(n, k->xmss_name)) != 0)
- goto out;
- if (k->xmss_pk != NULL) {
- u_int32_t left;
- size_t pklen = sshkey_xmss_pklen(k);
- if (pklen == 0 || sshkey_xmss_pklen(n) != pklen) {
- r = SSH_ERR_INTERNAL_ERROR;
- goto out;
- }
- if ((n->xmss_pk = malloc(pklen)) == NULL) {
- r = SSH_ERR_ALLOC_FAIL;
- goto out;
- }
- memcpy(n->xmss_pk, k->xmss_pk, pklen);
- /* simulate number of signatures left on pubkey */
- left = sshkey_xmss_signatures_left(k);
- if (left)
- sshkey_xmss_enable_maxsign(n, left);
- }
- break;
-#endif /* WITH_XMSS */
- default:
- r = SSH_ERR_KEY_TYPE_UNKNOWN;
+ if ((r = impl->funcs->copy_public(k, n)) != 0)
goto out;
- }
if (sshkey_is_cert(k) && (r = sshkey_cert_copy(k, n)) != 0)
goto out;
/* success */
*pkp = n;
n = NULL;
r = 0;
out:
sshkey_free(n);
-#ifdef WITH_OPENSSL
- BN_clear_free(rsa_n_dup);
- BN_clear_free(rsa_e_dup);
- BN_clear_free(dsa_p_dup);
- BN_clear_free(dsa_q_dup);
- BN_clear_free(dsa_g_dup);
- BN_clear_free(dsa_pub_key_dup);
-#endif
-
return r;
}
int
sshkey_is_shielded(struct sshkey *k)
{
return k != NULL && k->shielded_private != NULL;
}
int
sshkey_shield_private(struct sshkey *k)
{
struct sshbuf *prvbuf = NULL;
u_char *prekey = NULL, *enc = NULL, keyiv[SSH_DIGEST_MAX_LENGTH];
struct sshcipher_ctx *cctx = NULL;
const struct sshcipher *cipher;
size_t i, enclen = 0;
struct sshkey *kswap = NULL, tmp;
int r = SSH_ERR_INTERNAL_ERROR;
#ifdef DEBUG_PK
fprintf(stderr, "%s: entering for %s\n", __func__, sshkey_ssh_name(k));
#endif
if ((cipher = cipher_by_name(SSHKEY_SHIELD_CIPHER)) == NULL) {
r = SSH_ERR_INVALID_ARGUMENT;
goto out;
}
if (cipher_keylen(cipher) + cipher_ivlen(cipher) >
ssh_digest_bytes(SSHKEY_SHIELD_PREKEY_HASH)) {
r = SSH_ERR_INTERNAL_ERROR;
goto out;
}
/* Prepare a random pre-key, and from it an ephemeral key */
if ((prekey = malloc(SSHKEY_SHIELD_PREKEY_LEN)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
arc4random_buf(prekey, SSHKEY_SHIELD_PREKEY_LEN);
if ((r = ssh_digest_memory(SSHKEY_SHIELD_PREKEY_HASH,
prekey, SSHKEY_SHIELD_PREKEY_LEN,
keyiv, SSH_DIGEST_MAX_LENGTH)) != 0)
goto out;
#ifdef DEBUG_PK
fprintf(stderr, "%s: key+iv\n", __func__);
sshbuf_dump_data(keyiv, ssh_digest_bytes(SSHKEY_SHIELD_PREKEY_HASH),
stderr);
#endif
if ((r = cipher_init(&cctx, cipher, keyiv, cipher_keylen(cipher),
keyiv + cipher_keylen(cipher), cipher_ivlen(cipher), 1)) != 0)
goto out;
/* Serialise and encrypt the private key using the ephemeral key */
if ((prvbuf = sshbuf_new()) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
if (sshkey_is_shielded(k) && (r = sshkey_unshield_private(k)) != 0)
goto out;
if ((r = sshkey_private_serialize_opt(k, prvbuf,
SSHKEY_SERIALIZE_SHIELD)) != 0)
goto out;
/* pad to cipher blocksize */
i = 0;
while (sshbuf_len(prvbuf) % cipher_blocksize(cipher)) {
if ((r = sshbuf_put_u8(prvbuf, ++i & 0xff)) != 0)
goto out;
}
#ifdef DEBUG_PK
fprintf(stderr, "%s: serialised\n", __func__);
sshbuf_dump(prvbuf, stderr);
#endif
/* encrypt */
enclen = sshbuf_len(prvbuf);
if ((enc = malloc(enclen)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
if ((r = cipher_crypt(cctx, 0, enc,
sshbuf_ptr(prvbuf), sshbuf_len(prvbuf), 0, 0)) != 0)
goto out;
#ifdef DEBUG_PK
fprintf(stderr, "%s: encrypted\n", __func__);
sshbuf_dump_data(enc, enclen, stderr);
#endif
/* Make a scrubbed, public-only copy of our private key argument */
if ((r = sshkey_from_private(k, &kswap)) != 0)
goto out;
/* Swap the private key out (it will be destroyed below) */
tmp = *kswap;
*kswap = *k;
*k = tmp;
/* Insert the shielded key into our argument */
k->shielded_private = enc;
k->shielded_len = enclen;
k->shield_prekey = prekey;
k->shield_prekey_len = SSHKEY_SHIELD_PREKEY_LEN;
enc = prekey = NULL; /* transferred */
enclen = 0;
/* preserve key fields that are required for correct operation */
k->sk_flags = kswap->sk_flags;
/* success */
r = 0;
out:
/* XXX behaviour on error - invalidate original private key? */
cipher_free(cctx);
explicit_bzero(keyiv, sizeof(keyiv));
explicit_bzero(&tmp, sizeof(tmp));
freezero(enc, enclen);
freezero(prekey, SSHKEY_SHIELD_PREKEY_LEN);
sshkey_free(kswap);
sshbuf_free(prvbuf);
return r;
}
/* Check deterministic padding after private key */
static int
private2_check_padding(struct sshbuf *decrypted)
{
u_char pad;
size_t i;
int r;
i = 0;
while (sshbuf_len(decrypted)) {
if ((r = sshbuf_get_u8(decrypted, &pad)) != 0)
goto out;
if (pad != (++i & 0xff)) {
r = SSH_ERR_INVALID_FORMAT;
goto out;
}
}
/* success */
r = 0;
out:
explicit_bzero(&pad, sizeof(pad));
explicit_bzero(&i, sizeof(i));
return r;
}
int
sshkey_unshield_private(struct sshkey *k)
{
struct sshbuf *prvbuf = NULL;
u_char *cp, keyiv[SSH_DIGEST_MAX_LENGTH];
struct sshcipher_ctx *cctx = NULL;
const struct sshcipher *cipher;
struct sshkey *kswap = NULL, tmp;
int r = SSH_ERR_INTERNAL_ERROR;
#ifdef DEBUG_PK
fprintf(stderr, "%s: entering for %s\n", __func__, sshkey_ssh_name(k));
#endif
if (!sshkey_is_shielded(k))
return 0; /* nothing to do */
if ((cipher = cipher_by_name(SSHKEY_SHIELD_CIPHER)) == NULL) {
r = SSH_ERR_INVALID_ARGUMENT;
goto out;
}
if (cipher_keylen(cipher) + cipher_ivlen(cipher) >
ssh_digest_bytes(SSHKEY_SHIELD_PREKEY_HASH)) {
r = SSH_ERR_INTERNAL_ERROR;
goto out;
}
/* check size of shielded key blob */
if (k->shielded_len < cipher_blocksize(cipher) ||
(k->shielded_len % cipher_blocksize(cipher)) != 0) {
r = SSH_ERR_INVALID_FORMAT;
goto out;
}
/* Calculate the ephemeral key from the prekey */
if ((r = ssh_digest_memory(SSHKEY_SHIELD_PREKEY_HASH,
k->shield_prekey, k->shield_prekey_len,
keyiv, SSH_DIGEST_MAX_LENGTH)) != 0)
goto out;
if ((r = cipher_init(&cctx, cipher, keyiv, cipher_keylen(cipher),
keyiv + cipher_keylen(cipher), cipher_ivlen(cipher), 0)) != 0)
goto out;
#ifdef DEBUG_PK
fprintf(stderr, "%s: key+iv\n", __func__);
sshbuf_dump_data(keyiv, ssh_digest_bytes(SSHKEY_SHIELD_PREKEY_HASH),
stderr);
#endif
/* Decrypt and parse the shielded private key using the ephemeral key */
if ((prvbuf = sshbuf_new()) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
if ((r = sshbuf_reserve(prvbuf, k->shielded_len, &cp)) != 0)
goto out;
/* decrypt */
#ifdef DEBUG_PK
fprintf(stderr, "%s: encrypted\n", __func__);
sshbuf_dump_data(k->shielded_private, k->shielded_len, stderr);
#endif
if ((r = cipher_crypt(cctx, 0, cp,
k->shielded_private, k->shielded_len, 0, 0)) != 0)
goto out;
#ifdef DEBUG_PK
fprintf(stderr, "%s: serialised\n", __func__);
sshbuf_dump(prvbuf, stderr);
#endif
/* Parse private key */
if ((r = sshkey_private_deserialize(prvbuf, &kswap)) != 0)
goto out;
if ((r = private2_check_padding(prvbuf)) != 0)
goto out;
/* Swap the parsed key back into place */
tmp = *kswap;
*kswap = *k;
*k = tmp;
/* success */
r = 0;
out:
cipher_free(cctx);
explicit_bzero(keyiv, sizeof(keyiv));
explicit_bzero(&tmp, sizeof(tmp));
sshkey_free(kswap);
sshbuf_free(prvbuf);
return r;
}
static int
cert_parse(struct sshbuf *b, struct sshkey *key, struct sshbuf *certbuf)
{
struct sshbuf *principals = NULL, *crit = NULL;
struct sshbuf *exts = NULL, *ca = NULL;
u_char *sig = NULL;
size_t signed_len = 0, slen = 0, kidlen = 0;
int ret = SSH_ERR_INTERNAL_ERROR;
/* Copy the entire key blob for verification and later serialisation */
if ((ret = sshbuf_putb(key->cert->certblob, certbuf)) != 0)
return ret;
/* Parse body of certificate up to signature */
if ((ret = sshbuf_get_u64(b, &key->cert->serial)) != 0 ||
(ret = sshbuf_get_u32(b, &key->cert->type)) != 0 ||
(ret = sshbuf_get_cstring(b, &key->cert->key_id, &kidlen)) != 0 ||
(ret = sshbuf_froms(b, &principals)) != 0 ||
(ret = sshbuf_get_u64(b, &key->cert->valid_after)) != 0 ||
(ret = sshbuf_get_u64(b, &key->cert->valid_before)) != 0 ||
(ret = sshbuf_froms(b, &crit)) != 0 ||
(ret = sshbuf_froms(b, &exts)) != 0 ||
(ret = sshbuf_get_string_direct(b, NULL, NULL)) != 0 ||
(ret = sshbuf_froms(b, &ca)) != 0) {
/* XXX debug print error for ret */
ret = SSH_ERR_INVALID_FORMAT;
goto out;
}
/* Signature is left in the buffer so we can calculate this length */
signed_len = sshbuf_len(key->cert->certblob) - sshbuf_len(b);
if ((ret = sshbuf_get_string(b, &sig, &slen)) != 0) {
ret = SSH_ERR_INVALID_FORMAT;
goto out;
}
if (key->cert->type != SSH2_CERT_TYPE_USER &&
key->cert->type != SSH2_CERT_TYPE_HOST) {
ret = SSH_ERR_KEY_CERT_UNKNOWN_TYPE;
goto out;
}
/* Parse principals section */
while (sshbuf_len(principals) > 0) {
char *principal = NULL;
char **oprincipals = NULL;
if (key->cert->nprincipals >= SSHKEY_CERT_MAX_PRINCIPALS) {
ret = SSH_ERR_INVALID_FORMAT;
goto out;
}
if ((ret = sshbuf_get_cstring(principals, &principal,
NULL)) != 0) {
ret = SSH_ERR_INVALID_FORMAT;
goto out;
}
oprincipals = key->cert->principals;
key->cert->principals = recallocarray(key->cert->principals,
key->cert->nprincipals, key->cert->nprincipals + 1,
sizeof(*key->cert->principals));
if (key->cert->principals == NULL) {
free(principal);
key->cert->principals = oprincipals;
ret = SSH_ERR_ALLOC_FAIL;
goto out;
}
key->cert->principals[key->cert->nprincipals++] = principal;
}
/*
* Stash a copies of the critical options and extensions sections
* for later use.
*/
if ((ret = sshbuf_putb(key->cert->critical, crit)) != 0 ||
(exts != NULL &&
(ret = sshbuf_putb(key->cert->extensions, exts)) != 0))
goto out;
/*
* Validate critical options and extensions sections format.
*/
while (sshbuf_len(crit) != 0) {
if ((ret = sshbuf_get_string_direct(crit, NULL, NULL)) != 0 ||
(ret = sshbuf_get_string_direct(crit, NULL, NULL)) != 0) {
sshbuf_reset(key->cert->critical);
ret = SSH_ERR_INVALID_FORMAT;
goto out;
}
}
while (exts != NULL && sshbuf_len(exts) != 0) {
if ((ret = sshbuf_get_string_direct(exts, NULL, NULL)) != 0 ||
(ret = sshbuf_get_string_direct(exts, NULL, NULL)) != 0) {
sshbuf_reset(key->cert->extensions);
ret = SSH_ERR_INVALID_FORMAT;
goto out;
}
}
/* Parse CA key and check signature */
if (sshkey_from_blob_internal(ca, &key->cert->signature_key, 0) != 0) {
ret = SSH_ERR_KEY_CERT_INVALID_SIGN_KEY;
goto out;
}
if (!sshkey_type_is_valid_ca(key->cert->signature_key->type)) {
ret = SSH_ERR_KEY_CERT_INVALID_SIGN_KEY;
goto out;
}
if ((ret = sshkey_verify(key->cert->signature_key, sig, slen,
sshbuf_ptr(key->cert->certblob), signed_len, NULL, 0, NULL)) != 0)
goto out;
if ((ret = sshkey_get_sigtype(sig, slen,
&key->cert->signature_type)) != 0)
goto out;
/* Success */
ret = 0;
out:
sshbuf_free(ca);
sshbuf_free(crit);
sshbuf_free(exts);
sshbuf_free(principals);
free(sig);
return ret;
}
int
-sshkey_check_rsa_length(const struct sshkey *k, int min_size)
+sshkey_deserialize_sk(struct sshbuf *b, struct sshkey *key)
{
-#ifdef WITH_OPENSSL
- const BIGNUM *rsa_n;
- int nbits;
-
- if (k == NULL || k->rsa == NULL ||
- (k->type != KEY_RSA && k->type != KEY_RSA_CERT))
- return 0;
- RSA_get0_key(k->rsa, &rsa_n, NULL, NULL);
- nbits = BN_num_bits(rsa_n);
- if (nbits < SSH_RSA_MINIMUM_MODULUS_SIZE ||
- (min_size > 0 && nbits < min_size))
- return SSH_ERR_KEY_LENGTH;
-#endif /* WITH_OPENSSL */
+ /* Parse additional security-key application string */
+ if (sshbuf_get_cstring(b, &key->sk_application, NULL) != 0)
+ return SSH_ERR_INVALID_FORMAT;
return 0;
}
static int
sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp,
int allow_cert)
{
int type, ret = SSH_ERR_INTERNAL_ERROR;
- char *ktype = NULL, *curve = NULL, *xmss_name = NULL;
+ char *ktype = NULL;
struct sshkey *key = NULL;
- size_t len;
- u_char *pk = NULL;
struct sshbuf *copy;
-#if defined(WITH_OPENSSL)
- BIGNUM *rsa_n = NULL, *rsa_e = NULL;
- BIGNUM *dsa_p = NULL, *dsa_q = NULL, *dsa_g = NULL, *dsa_pub_key = NULL;
-# if defined(OPENSSL_HAS_ECC)
- EC_POINT *q = NULL;
-# endif /* OPENSSL_HAS_ECC */
-#endif /* WITH_OPENSSL */
+ const struct sshkey_impl *impl;
#ifdef DEBUG_PK /* XXX */
sshbuf_dump(b, stderr);
#endif
if (keyp != NULL)
*keyp = NULL;
if ((copy = sshbuf_fromb(b)) == NULL) {
ret = SSH_ERR_ALLOC_FAIL;
goto out;
}
if (sshbuf_get_cstring(b, &ktype, NULL) != 0) {
ret = SSH_ERR_INVALID_FORMAT;
goto out;
}
type = sshkey_type_from_name(ktype);
if (!allow_cert && sshkey_type_is_cert(type)) {
ret = SSH_ERR_KEY_CERT_INVALID_SIGN_KEY;
goto out;
}
- switch (type) {
-#ifdef WITH_OPENSSL
- case KEY_RSA_CERT:
- /* Skip nonce */
- if (sshbuf_get_string_direct(b, NULL, NULL) != 0) {
- ret = SSH_ERR_INVALID_FORMAT;
- goto out;
- }
- /* FALLTHROUGH */
- case KEY_RSA:
- if ((key = sshkey_new(type)) == NULL) {
- ret = SSH_ERR_ALLOC_FAIL;
- goto out;
- }
- if (sshbuf_get_bignum2(b, &rsa_e) != 0 ||
- sshbuf_get_bignum2(b, &rsa_n) != 0) {
- ret = SSH_ERR_INVALID_FORMAT;
- goto out;
- }
- if (!RSA_set0_key(key->rsa, rsa_n, rsa_e, NULL)) {
- ret = SSH_ERR_LIBCRYPTO_ERROR;
- goto out;
- }
- rsa_n = rsa_e = NULL; /* transferred */
- if ((ret = sshkey_check_rsa_length(key, 0)) != 0)
- goto out;
-#ifdef DEBUG_PK
- RSA_print_fp(stderr, key->rsa, 8);
-#endif
- break;
- case KEY_DSA_CERT:
- /* Skip nonce */
- if (sshbuf_get_string_direct(b, NULL, NULL) != 0) {
- ret = SSH_ERR_INVALID_FORMAT;
- goto out;
- }
- /* FALLTHROUGH */
- case KEY_DSA:
- if ((key = sshkey_new(type)) == NULL) {
- ret = SSH_ERR_ALLOC_FAIL;
- goto out;
- }
- if (sshbuf_get_bignum2(b, &dsa_p) != 0 ||
- sshbuf_get_bignum2(b, &dsa_q) != 0 ||
- sshbuf_get_bignum2(b, &dsa_g) != 0 ||
- sshbuf_get_bignum2(b, &dsa_pub_key) != 0) {
- ret = SSH_ERR_INVALID_FORMAT;
- goto out;
- }
- if (!DSA_set0_pqg(key->dsa, dsa_p, dsa_q, dsa_g)) {
- ret = SSH_ERR_LIBCRYPTO_ERROR;
- goto out;
- }
- dsa_p = dsa_q = dsa_g = NULL; /* transferred */
- if (!DSA_set0_key(key->dsa, dsa_pub_key, NULL)) {
- ret = SSH_ERR_LIBCRYPTO_ERROR;
- goto out;
- }
- dsa_pub_key = NULL; /* transferred */
-#ifdef DEBUG_PK
- DSA_print_fp(stderr, key->dsa, 8);
-#endif
- break;
-# ifdef OPENSSL_HAS_ECC
- case KEY_ECDSA_CERT:
- case KEY_ECDSA_SK_CERT:
- /* Skip nonce */
- if (sshbuf_get_string_direct(b, NULL, NULL) != 0) {
- ret = SSH_ERR_INVALID_FORMAT;
- goto out;
- }
- /* FALLTHROUGH */
- case KEY_ECDSA:
- case KEY_ECDSA_SK:
- if ((key = sshkey_new(type)) == NULL) {
- ret = SSH_ERR_ALLOC_FAIL;
- goto out;
- }
- key->ecdsa_nid = sshkey_ecdsa_nid_from_name(ktype);
- if (sshbuf_get_cstring(b, &curve, NULL) != 0) {
- ret = SSH_ERR_INVALID_FORMAT;
- goto out;
- }
- if (key->ecdsa_nid != sshkey_curve_name_to_nid(curve)) {
- ret = SSH_ERR_EC_CURVE_MISMATCH;
- goto out;
- }
- EC_KEY_free(key->ecdsa);
- if ((key->ecdsa = EC_KEY_new_by_curve_name(key->ecdsa_nid))
- == NULL) {
- ret = SSH_ERR_EC_CURVE_INVALID;
- goto out;
- }
- if ((q = EC_POINT_new(EC_KEY_get0_group(key->ecdsa))) == NULL) {
- ret = SSH_ERR_ALLOC_FAIL;
- goto out;
- }
- if (sshbuf_get_ec(b, q, EC_KEY_get0_group(key->ecdsa)) != 0) {
- ret = SSH_ERR_INVALID_FORMAT;
- goto out;
- }
- if (sshkey_ec_validate_public(EC_KEY_get0_group(key->ecdsa),
- q) != 0) {
- ret = SSH_ERR_KEY_INVALID_EC_VALUE;
- goto out;
- }
- if (EC_KEY_set_public_key(key->ecdsa, q) != 1) {
- /* XXX assume it is a allocation error */
- ret = SSH_ERR_ALLOC_FAIL;
- goto out;
- }
-#ifdef DEBUG_PK
- sshkey_dump_ec_point(EC_KEY_get0_group(key->ecdsa), q);
-#endif
- if (type == KEY_ECDSA_SK || type == KEY_ECDSA_SK_CERT) {
- /* Parse additional security-key application string */
- if (sshbuf_get_cstring(b, &key->sk_application,
- NULL) != 0) {
- ret = SSH_ERR_INVALID_FORMAT;
- goto out;
- }
-#ifdef DEBUG_PK
- fprintf(stderr, "App: %s\n", key->sk_application);
-#endif
- }
- break;
-# endif /* OPENSSL_HAS_ECC */
-#endif /* WITH_OPENSSL */
- case KEY_ED25519_CERT:
- case KEY_ED25519_SK_CERT:
- /* Skip nonce */
- if (sshbuf_get_string_direct(b, NULL, NULL) != 0) {
- ret = SSH_ERR_INVALID_FORMAT;
- goto out;
- }
- /* FALLTHROUGH */
- case KEY_ED25519:
- case KEY_ED25519_SK:
- if ((ret = sshbuf_get_string(b, &pk, &len)) != 0)
- goto out;
- if (len != ED25519_PK_SZ) {
- ret = SSH_ERR_INVALID_FORMAT;
- goto out;
- }
- if ((key = sshkey_new(type)) == NULL) {
- ret = SSH_ERR_ALLOC_FAIL;
- goto out;
- }
- if (type == KEY_ED25519_SK || type == KEY_ED25519_SK_CERT) {
- /* Parse additional security-key application string */
- if (sshbuf_get_cstring(b, &key->sk_application,
- NULL) != 0) {
- ret = SSH_ERR_INVALID_FORMAT;
- goto out;
- }
-#ifdef DEBUG_PK
- fprintf(stderr, "App: %s\n", key->sk_application);
-#endif
- }
- key->ed25519_pk = pk;
- pk = NULL;
- break;
-#ifdef WITH_XMSS
- case KEY_XMSS_CERT:
- /* Skip nonce */
+ if ((impl = sshkey_impl_from_type(type)) == NULL) {
+ ret = SSH_ERR_KEY_TYPE_UNKNOWN;
+ goto out;
+ }
+ if ((key = sshkey_new(type)) == NULL) {
+ ret = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
+ if (sshkey_type_is_cert(type)) {
+ /* Skip nonce that preceeds all certificates */
if (sshbuf_get_string_direct(b, NULL, NULL) != 0) {
ret = SSH_ERR_INVALID_FORMAT;
goto out;
}
- /* FALLTHROUGH */
- case KEY_XMSS:
- if ((ret = sshbuf_get_cstring(b, &xmss_name, NULL)) != 0)
- goto out;
- if ((key = sshkey_new(type)) == NULL) {
- ret = SSH_ERR_ALLOC_FAIL;
- goto out;
- }
- if ((ret = sshkey_xmss_init(key, xmss_name)) != 0)
- goto out;
- if ((ret = sshbuf_get_string(b, &pk, &len)) != 0)
- goto out;
- if (len == 0 || len != sshkey_xmss_pklen(key)) {
- ret = SSH_ERR_INVALID_FORMAT;
- goto out;
- }
- key->xmss_pk = pk;
- pk = NULL;
- if (type != KEY_XMSS_CERT &&
- (ret = sshkey_xmss_deserialize_pk_info(key, b)) != 0)
- goto out;
- break;
-#endif /* WITH_XMSS */
- case KEY_UNSPEC:
- default:
- ret = SSH_ERR_KEY_TYPE_UNKNOWN;
- goto out;
}
+ if ((ret = impl->funcs->deserialize_public(ktype, b, key)) != 0)
+ goto out;
/* Parse certificate potion */
if (sshkey_is_cert(key) && (ret = cert_parse(b, key, copy)) != 0)
goto out;
if (key != NULL && sshbuf_len(b) != 0) {
ret = SSH_ERR_INVALID_FORMAT;
goto out;
}
ret = 0;
if (keyp != NULL) {
*keyp = key;
key = NULL;
}
out:
sshbuf_free(copy);
sshkey_free(key);
- free(xmss_name);
free(ktype);
- free(curve);
- free(pk);
-#if defined(WITH_OPENSSL)
- BN_clear_free(rsa_n);
- BN_clear_free(rsa_e);
- BN_clear_free(dsa_p);
- BN_clear_free(dsa_q);
- BN_clear_free(dsa_g);
- BN_clear_free(dsa_pub_key);
-# if defined(OPENSSL_HAS_ECC)
- EC_POINT_free(q);
-# endif /* OPENSSL_HAS_ECC */
-#endif /* WITH_OPENSSL */
return ret;
}
int
sshkey_from_blob(const u_char *blob, size_t blen, struct sshkey **keyp)
{
struct sshbuf *b;
int r;
if ((b = sshbuf_from(blob, blen)) == NULL)
return SSH_ERR_ALLOC_FAIL;
r = sshkey_from_blob_internal(b, keyp, 1);
sshbuf_free(b);
return r;
}
int
sshkey_fromb(struct sshbuf *b, struct sshkey **keyp)
{
return sshkey_from_blob_internal(b, keyp, 1);
}
int
sshkey_froms(struct sshbuf *buf, struct sshkey **keyp)
{
struct sshbuf *b;
int r;
if ((r = sshbuf_froms(buf, &b)) != 0)
return r;
r = sshkey_from_blob_internal(b, keyp, 1);
sshbuf_free(b);
return r;
}
int
sshkey_get_sigtype(const u_char *sig, size_t siglen, char **sigtypep)
{
int r;
struct sshbuf *b = NULL;
char *sigtype = NULL;
if (sigtypep != NULL)
*sigtypep = NULL;
if ((b = sshbuf_from(sig, siglen)) == NULL)
return SSH_ERR_ALLOC_FAIL;
if ((r = sshbuf_get_cstring(b, &sigtype, NULL)) != 0)
goto out;
/* success */
if (sigtypep != NULL) {
*sigtypep = sigtype;
sigtype = NULL;
}
r = 0;
out:
free(sigtype);
sshbuf_free(b);
return r;
}
/*
*
* Checks whether a certificate's signature type is allowed.
* Returns 0 (success) if the certificate signature type appears in the
* "allowed" pattern-list, or the key is not a certificate to begin with.
* Otherwise returns a ssherr.h code.
*/
int
sshkey_check_cert_sigtype(const struct sshkey *key, const char *allowed)
{
if (key == NULL || allowed == NULL)
return SSH_ERR_INVALID_ARGUMENT;
if (!sshkey_type_is_cert(key->type))
return 0;
if (key->cert == NULL || key->cert->signature_type == NULL)
return SSH_ERR_INVALID_ARGUMENT;
if (match_pattern_list(key->cert->signature_type, allowed, 0) != 1)
return SSH_ERR_SIGN_ALG_UNSUPPORTED;
return 0;
}
/*
* Returns the expected signature algorithm for a given public key algorithm.
*/
const char *
sshkey_sigalg_by_name(const char *name)
{
- const struct keytype *kt;
+ const struct sshkey_impl *impl;
+ int i;
- for (kt = keytypes; kt->type != -1; kt++) {
- if (strcmp(kt->name, name) != 0)
+ for (i = 0; keyimpls[i] != NULL; i++) {
+ impl = keyimpls[i];
+ if (strcmp(impl->name, name) != 0)
continue;
- if (kt->sigalg != NULL)
- return kt->sigalg;
- if (!kt->cert)
- return kt->name;
+ if (impl->sigalg != NULL)
+ return impl->sigalg;
+ if (!impl->cert)
+ return impl->name;
return sshkey_ssh_name_from_type_nid(
- sshkey_type_plain(kt->type), kt->nid);
+ sshkey_type_plain(impl->type), impl->nid);
}
return NULL;
}
/*
* Verifies that the signature algorithm appearing inside the signature blob
* matches that which was requested.
*/
int
sshkey_check_sigtype(const u_char *sig, size_t siglen,
const char *requested_alg)
{
const char *expected_alg;
char *sigtype = NULL;
int r;
if (requested_alg == NULL)
return 0;
if ((expected_alg = sshkey_sigalg_by_name(requested_alg)) == NULL)
return SSH_ERR_INVALID_ARGUMENT;
if ((r = sshkey_get_sigtype(sig, siglen, &sigtype)) != 0)
return r;
r = strcmp(expected_alg, sigtype) == 0;
free(sigtype);
return r ? 0 : SSH_ERR_SIGN_ALG_UNSUPPORTED;
}
int
sshkey_sign(struct sshkey *key,
u_char **sigp, size_t *lenp,
const u_char *data, size_t datalen,
const char *alg, const char *sk_provider, const char *sk_pin, u_int compat)
{
int was_shielded = sshkey_is_shielded(key);
int r2, r = SSH_ERR_INTERNAL_ERROR;
+ const struct sshkey_impl *impl;
if (sigp != NULL)
*sigp = NULL;
if (lenp != NULL)
*lenp = 0;
if (datalen > SSH_KEY_MAX_SIGN_DATA_SIZE)
return SSH_ERR_INVALID_ARGUMENT;
+ if ((impl = sshkey_impl_from_key(key)) == NULL)
+ return SSH_ERR_KEY_TYPE_UNKNOWN;
if ((r = sshkey_unshield_private(key)) != 0)
return r;
- switch (key->type) {
-#ifdef WITH_OPENSSL
- case KEY_DSA_CERT:
- case KEY_DSA:
- r = ssh_dss_sign(key, sigp, lenp, data, datalen, compat);
- break;
-# ifdef OPENSSL_HAS_ECC
- case KEY_ECDSA_CERT:
- case KEY_ECDSA:
- r = ssh_ecdsa_sign(key, sigp, lenp, data, datalen, compat);
- break;
-# endif /* OPENSSL_HAS_ECC */
- case KEY_RSA_CERT:
- case KEY_RSA:
- r = ssh_rsa_sign(key, sigp, lenp, data, datalen, alg);
- break;
-#endif /* WITH_OPENSSL */
- case KEY_ED25519:
- case KEY_ED25519_CERT:
- r = ssh_ed25519_sign(key, sigp, lenp, data, datalen, compat);
- break;
- case KEY_ED25519_SK:
- case KEY_ED25519_SK_CERT:
- case KEY_ECDSA_SK_CERT:
- case KEY_ECDSA_SK:
+ if (sshkey_is_sk(key)) {
r = sshsk_sign(sk_provider, key, sigp, lenp, data,
datalen, compat, sk_pin);
- break;
-#ifdef WITH_XMSS
- case KEY_XMSS:
- case KEY_XMSS_CERT:
- r = ssh_xmss_sign(key, sigp, lenp, data, datalen, compat);
- break;
-#endif /* WITH_XMSS */
- default:
- r = SSH_ERR_KEY_TYPE_UNKNOWN;
- break;
+ } else {
+ if (impl->funcs->sign == NULL)
+ r = SSH_ERR_SIGN_ALG_UNSUPPORTED;
+ else {
+ r = impl->funcs->sign(key, sigp, lenp, data, datalen,
+ alg, sk_provider, sk_pin, compat);
+ }
}
if (was_shielded && (r2 = sshkey_shield_private(key)) != 0)
return r2;
return r;
}
/*
* ssh_key_verify returns 0 for a correct signature and < 0 on error.
* If "alg" specified, then the signature must use that algorithm.
*/
int
sshkey_verify(const struct sshkey *key,
const u_char *sig, size_t siglen,
const u_char *data, size_t dlen, const char *alg, u_int compat,
struct sshkey_sig_details **detailsp)
{
+ const struct sshkey_impl *impl;
+
if (detailsp != NULL)
*detailsp = NULL;
if (siglen == 0 || dlen > SSH_KEY_MAX_SIGN_DATA_SIZE)
return SSH_ERR_INVALID_ARGUMENT;
- switch (key->type) {
-#ifdef WITH_OPENSSL
- case KEY_DSA_CERT:
- case KEY_DSA:
- return ssh_dss_verify(key, sig, siglen, data, dlen, compat);
-# ifdef OPENSSL_HAS_ECC
- case KEY_ECDSA_CERT:
- case KEY_ECDSA:
- return ssh_ecdsa_verify(key, sig, siglen, data, dlen, compat);
- case KEY_ECDSA_SK_CERT:
- case KEY_ECDSA_SK:
- return ssh_ecdsa_sk_verify(key, sig, siglen, data, dlen,
- compat, detailsp);
-# endif /* OPENSSL_HAS_ECC */
- case KEY_RSA_CERT:
- case KEY_RSA:
- return ssh_rsa_verify(key, sig, siglen, data, dlen, alg);
-#endif /* WITH_OPENSSL */
- case KEY_ED25519:
- case KEY_ED25519_CERT:
- return ssh_ed25519_verify(key, sig, siglen, data, dlen, compat);
- case KEY_ED25519_SK:
- case KEY_ED25519_SK_CERT:
- return ssh_ed25519_sk_verify(key, sig, siglen, data, dlen,
- compat, detailsp);
-#ifdef WITH_XMSS
- case KEY_XMSS:
- case KEY_XMSS_CERT:
- return ssh_xmss_verify(key, sig, siglen, data, dlen, compat);
-#endif /* WITH_XMSS */
- default:
+ if ((impl = sshkey_impl_from_key(key)) == NULL)
return SSH_ERR_KEY_TYPE_UNKNOWN;
- }
+ return impl->funcs->verify(key, sig, siglen, data, dlen,
+ alg, compat, detailsp);
}
/* Convert a plain key to their _CERT equivalent */
int
sshkey_to_certified(struct sshkey *k)
{
int newtype;
- switch (k->type) {
-#ifdef WITH_OPENSSL
- case KEY_RSA:
- newtype = KEY_RSA_CERT;
- break;
- case KEY_DSA:
- newtype = KEY_DSA_CERT;
- break;
- case KEY_ECDSA:
- newtype = KEY_ECDSA_CERT;
- break;
- case KEY_ECDSA_SK:
- newtype = KEY_ECDSA_SK_CERT;
- break;
-#endif /* WITH_OPENSSL */
- case KEY_ED25519_SK:
- newtype = KEY_ED25519_SK_CERT;
- break;
- case KEY_ED25519:
- newtype = KEY_ED25519_CERT;
- break;
-#ifdef WITH_XMSS
- case KEY_XMSS:
- newtype = KEY_XMSS_CERT;
- break;
-#endif /* WITH_XMSS */
- default:
+ if ((newtype = sshkey_type_certified(k->type)) == -1)
return SSH_ERR_INVALID_ARGUMENT;
- }
if ((k->cert = cert_new()) == NULL)
return SSH_ERR_ALLOC_FAIL;
k->type = newtype;
return 0;
}
/* Convert a certificate to its raw key equivalent */
int
sshkey_drop_cert(struct sshkey *k)
{
if (!sshkey_type_is_cert(k->type))
return SSH_ERR_KEY_TYPE_UNKNOWN;
cert_free(k->cert);
k->cert = NULL;
k->type = sshkey_type_plain(k->type);
return 0;
}
/* Sign a certified key, (re-)generating the signed certblob. */
int
sshkey_certify_custom(struct sshkey *k, struct sshkey *ca, const char *alg,
const char *sk_provider, const char *sk_pin,
sshkey_certify_signer *signer, void *signer_ctx)
{
+ const struct sshkey_impl *impl;
struct sshbuf *principals = NULL;
u_char *ca_blob = NULL, *sig_blob = NULL, nonce[32];
size_t i, ca_len, sig_len;
int ret = SSH_ERR_INTERNAL_ERROR;
struct sshbuf *cert = NULL;
char *sigtype = NULL;
-#ifdef WITH_OPENSSL
- const BIGNUM *rsa_n, *rsa_e, *dsa_p, *dsa_q, *dsa_g, *dsa_pub_key;
-#endif /* WITH_OPENSSL */
if (k == NULL || k->cert == NULL ||
k->cert->certblob == NULL || ca == NULL)
return SSH_ERR_INVALID_ARGUMENT;
if (!sshkey_is_cert(k))
return SSH_ERR_KEY_TYPE_UNKNOWN;
if (!sshkey_type_is_valid_ca(ca->type))
return SSH_ERR_KEY_CERT_INVALID_SIGN_KEY;
+ if ((impl = sshkey_impl_from_key(k)) == NULL)
+ return SSH_ERR_INTERNAL_ERROR;
/*
* If no alg specified as argument but a signature_type was set,
* then prefer that. If both were specified, then they must match.
*/
if (alg == NULL)
alg = k->cert->signature_type;
else if (k->cert->signature_type != NULL &&
strcmp(alg, k->cert->signature_type) != 0)
return SSH_ERR_INVALID_ARGUMENT;
/*
* If no signing algorithm or signature_type was specified and we're
* using a RSA key, then default to a good signature algorithm.
*/
if (alg == NULL && ca->type == KEY_RSA)
alg = "rsa-sha2-512";
if ((ret = sshkey_to_blob(ca, &ca_blob, &ca_len)) != 0)
return SSH_ERR_KEY_CERT_INVALID_SIGN_KEY;
cert = k->cert->certblob; /* for readability */
sshbuf_reset(cert);
if ((ret = sshbuf_put_cstring(cert, sshkey_ssh_name(k))) != 0)
goto out;
/* -v01 certs put nonce first */
arc4random_buf(&nonce, sizeof(nonce));
if ((ret = sshbuf_put_string(cert, nonce, sizeof(nonce))) != 0)
goto out;
- /* XXX this substantially duplicates to_blob(); refactor */
- switch (k->type) {
-#ifdef WITH_OPENSSL
- case KEY_DSA_CERT:
- DSA_get0_pqg(k->dsa, &dsa_p, &dsa_q, &dsa_g);
- DSA_get0_key(k->dsa, &dsa_pub_key, NULL);
- if ((ret = sshbuf_put_bignum2(cert, dsa_p)) != 0 ||
- (ret = sshbuf_put_bignum2(cert, dsa_q)) != 0 ||
- (ret = sshbuf_put_bignum2(cert, dsa_g)) != 0 ||
- (ret = sshbuf_put_bignum2(cert, dsa_pub_key)) != 0)
- goto out;
- break;
-# ifdef OPENSSL_HAS_ECC
- case KEY_ECDSA_CERT:
- case KEY_ECDSA_SK_CERT:
- if ((ret = sshbuf_put_cstring(cert,
- sshkey_curve_nid_to_name(k->ecdsa_nid))) != 0 ||
- (ret = sshbuf_put_ec(cert,
- EC_KEY_get0_public_key(k->ecdsa),
- EC_KEY_get0_group(k->ecdsa))) != 0)
- goto out;
- if (k->type == KEY_ECDSA_SK_CERT) {
- if ((ret = sshbuf_put_cstring(cert,
- k->sk_application)) != 0)
- goto out;
- }
- break;
-# endif /* OPENSSL_HAS_ECC */
- case KEY_RSA_CERT:
- RSA_get0_key(k->rsa, &rsa_n, &rsa_e, NULL);
- if ((ret = sshbuf_put_bignum2(cert, rsa_e)) != 0 ||
- (ret = sshbuf_put_bignum2(cert, rsa_n)) != 0)
- goto out;
- break;
-#endif /* WITH_OPENSSL */
- case KEY_ED25519_CERT:
- case KEY_ED25519_SK_CERT:
- if ((ret = sshbuf_put_string(cert,
- k->ed25519_pk, ED25519_PK_SZ)) != 0)
- goto out;
- if (k->type == KEY_ED25519_SK_CERT) {
- if ((ret = sshbuf_put_cstring(cert,
- k->sk_application)) != 0)
- goto out;
- }
- break;
-#ifdef WITH_XMSS
- case KEY_XMSS_CERT:
- if (k->xmss_name == NULL) {
- ret = SSH_ERR_INVALID_ARGUMENT;
- goto out;
- }
- if ((ret = sshbuf_put_cstring(cert, k->xmss_name)) ||
- (ret = sshbuf_put_string(cert,
- k->xmss_pk, sshkey_xmss_pklen(k))) != 0)
- goto out;
- break;
-#endif /* WITH_XMSS */
- default:
- ret = SSH_ERR_INVALID_ARGUMENT;
+ /* Public key next */
+ if ((ret = impl->funcs->serialize_public(k, cert,
+ SSHKEY_SERIALIZE_DEFAULT)) != 0)
goto out;
- }
+ /* Then remaining cert fields */
if ((ret = sshbuf_put_u64(cert, k->cert->serial)) != 0 ||
(ret = sshbuf_put_u32(cert, k->cert->type)) != 0 ||
(ret = sshbuf_put_cstring(cert, k->cert->key_id)) != 0)
goto out;
if ((principals = sshbuf_new()) == NULL) {
ret = SSH_ERR_ALLOC_FAIL;
goto out;
}
for (i = 0; i < k->cert->nprincipals; i++) {
if ((ret = sshbuf_put_cstring(principals,
k->cert->principals[i])) != 0)
goto out;
}
if ((ret = sshbuf_put_stringb(cert, principals)) != 0 ||
(ret = sshbuf_put_u64(cert, k->cert->valid_after)) != 0 ||
(ret = sshbuf_put_u64(cert, k->cert->valid_before)) != 0 ||
(ret = sshbuf_put_stringb(cert, k->cert->critical)) != 0 ||
(ret = sshbuf_put_stringb(cert, k->cert->extensions)) != 0 ||
(ret = sshbuf_put_string(cert, NULL, 0)) != 0 || /* Reserved */
(ret = sshbuf_put_string(cert, ca_blob, ca_len)) != 0)
goto out;
/* Sign the whole mess */
if ((ret = signer(ca, &sig_blob, &sig_len, sshbuf_ptr(cert),
sshbuf_len(cert), alg, sk_provider, sk_pin, 0, signer_ctx)) != 0)
goto out;
/* Check and update signature_type against what was actually used */
if ((ret = sshkey_get_sigtype(sig_blob, sig_len, &sigtype)) != 0)
goto out;
if (alg != NULL && strcmp(alg, sigtype) != 0) {
ret = SSH_ERR_SIGN_ALG_UNSUPPORTED;
goto out;
}
if (k->cert->signature_type == NULL) {
k->cert->signature_type = sigtype;
sigtype = NULL;
}
/* Append signature and we are done */
if ((ret = sshbuf_put_string(cert, sig_blob, sig_len)) != 0)
goto out;
ret = 0;
out:
if (ret != 0)
sshbuf_reset(cert);
free(sig_blob);
free(ca_blob);
free(sigtype);
sshbuf_free(principals);
return ret;
}
static int
default_key_sign(struct sshkey *key, u_char **sigp, size_t *lenp,
const u_char *data, size_t datalen,
const char *alg, const char *sk_provider, const char *sk_pin,
u_int compat, void *ctx)
{
if (ctx != NULL)
return SSH_ERR_INVALID_ARGUMENT;
return sshkey_sign(key, sigp, lenp, data, datalen, alg,
sk_provider, sk_pin, compat);
}
int
sshkey_certify(struct sshkey *k, struct sshkey *ca, const char *alg,
const char *sk_provider, const char *sk_pin)
{
return sshkey_certify_custom(k, ca, alg, sk_provider, sk_pin,
default_key_sign, NULL);
}
int
sshkey_cert_check_authority(const struct sshkey *k,
int want_host, int require_principal, int wildcard_pattern,
uint64_t verify_time, const char *name, const char **reason)
{
u_int i, principal_matches;
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";
return SSH_ERR_KEY_CERT_INVALID;
}
} else {
if (k->cert->type != SSH2_CERT_TYPE_USER) {
*reason = "Certificate invalid: not a user certificate";
return SSH_ERR_KEY_CERT_INVALID;
}
}
if (verify_time < k->cert->valid_after) {
*reason = "Certificate invalid: not yet valid";
return SSH_ERR_KEY_CERT_INVALID;
}
if (verify_time >= k->cert->valid_before) {
*reason = "Certificate invalid: expired";
return SSH_ERR_KEY_CERT_INVALID;
}
if (k->cert->nprincipals == 0) {
if (require_principal) {
*reason = "Certificate lacks principal list";
return SSH_ERR_KEY_CERT_INVALID;
}
} else if (name != NULL) {
principal_matches = 0;
for (i = 0; i < k->cert->nprincipals; i++) {
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;
}
}
if (!principal_matches) {
*reason = "Certificate invalid: name is not a listed "
"principal";
return SSH_ERR_KEY_CERT_INVALID;
}
}
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[128];
*from = *to = '\0';
if (cert->valid_after == 0 &&
cert->valid_before == 0xffffffffffffffffULL)
return strlcpy(s, "forever", l);
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);
else if (cert->valid_before == 0xffffffffffffffffULL)
snprintf(ret, sizeof(ret), "after %s", from);
else
snprintf(ret, sizeof(ret), "from %s to %s", from, to);
return strlcpy(s, ret, l);
}
+/* Common serialization for FIDO private keys */
+int
+sshkey_serialize_private_sk(const struct sshkey *key, struct sshbuf *b)
+{
+ int r;
+
+ if ((r = sshbuf_put_cstring(b, key->sk_application)) != 0 ||
+ (r = sshbuf_put_u8(b, key->sk_flags)) != 0 ||
+ (r = sshbuf_put_stringb(b, key->sk_key_handle)) != 0 ||
+ (r = sshbuf_put_stringb(b, key->sk_reserved)) != 0)
+ return r;
+
+ return 0;
+}
+
int
sshkey_private_serialize_opt(struct sshkey *key, struct sshbuf *buf,
enum sshkey_serialize_rep opts)
{
int r = SSH_ERR_INTERNAL_ERROR;
int was_shielded = sshkey_is_shielded(key);
struct sshbuf *b = NULL;
-#ifdef WITH_OPENSSL
- const BIGNUM *rsa_n, *rsa_e, *rsa_d, *rsa_iqmp, *rsa_p, *rsa_q;
- const BIGNUM *dsa_p, *dsa_q, *dsa_g, *dsa_pub_key, *dsa_priv_key;
-#endif /* WITH_OPENSSL */
+ const struct sshkey_impl *impl;
+ if ((impl = sshkey_impl_from_key(key)) == NULL)
+ return SSH_ERR_INTERNAL_ERROR;
if ((r = sshkey_unshield_private(key)) != 0)
return r;
if ((b = sshbuf_new()) == NULL)
return SSH_ERR_ALLOC_FAIL;
if ((r = sshbuf_put_cstring(b, sshkey_ssh_name(key))) != 0)
goto out;
- switch (key->type) {
-#ifdef WITH_OPENSSL
- case KEY_RSA:
- RSA_get0_key(key->rsa, &rsa_n, &rsa_e, &rsa_d);
- RSA_get0_factors(key->rsa, &rsa_p, &rsa_q);
- RSA_get0_crt_params(key->rsa, NULL, NULL, &rsa_iqmp);
- if ((r = sshbuf_put_bignum2(b, rsa_n)) != 0 ||
- (r = sshbuf_put_bignum2(b, rsa_e)) != 0 ||
- (r = sshbuf_put_bignum2(b, rsa_d)) != 0 ||
- (r = sshbuf_put_bignum2(b, rsa_iqmp)) != 0 ||
- (r = sshbuf_put_bignum2(b, rsa_p)) != 0 ||
- (r = sshbuf_put_bignum2(b, rsa_q)) != 0)
- goto out;
- break;
- case KEY_RSA_CERT:
- if (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0) {
- r = SSH_ERR_INVALID_ARGUMENT;
- goto out;
- }
- RSA_get0_key(key->rsa, NULL, NULL, &rsa_d);
- RSA_get0_factors(key->rsa, &rsa_p, &rsa_q);
- RSA_get0_crt_params(key->rsa, NULL, NULL, &rsa_iqmp);
- if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 ||
- (r = sshbuf_put_bignum2(b, rsa_d)) != 0 ||
- (r = sshbuf_put_bignum2(b, rsa_iqmp)) != 0 ||
- (r = sshbuf_put_bignum2(b, rsa_p)) != 0 ||
- (r = sshbuf_put_bignum2(b, rsa_q)) != 0)
- goto out;
- break;
- case KEY_DSA:
- DSA_get0_pqg(key->dsa, &dsa_p, &dsa_q, &dsa_g);
- DSA_get0_key(key->dsa, &dsa_pub_key, &dsa_priv_key);
- if ((r = sshbuf_put_bignum2(b, dsa_p)) != 0 ||
- (r = sshbuf_put_bignum2(b, dsa_q)) != 0 ||
- (r = sshbuf_put_bignum2(b, dsa_g)) != 0 ||
- (r = sshbuf_put_bignum2(b, dsa_pub_key)) != 0 ||
- (r = sshbuf_put_bignum2(b, dsa_priv_key)) != 0)
- goto out;
- break;
- case KEY_DSA_CERT:
- if (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0) {
- r = SSH_ERR_INVALID_ARGUMENT;
- goto out;
- }
- DSA_get0_key(key->dsa, NULL, &dsa_priv_key);
- if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 ||
- (r = sshbuf_put_bignum2(b, dsa_priv_key)) != 0)
- goto out;
- break;
-# ifdef OPENSSL_HAS_ECC
- case KEY_ECDSA:
- if ((r = sshbuf_put_cstring(b,
- sshkey_curve_nid_to_name(key->ecdsa_nid))) != 0 ||
- (r = sshbuf_put_eckey(b, key->ecdsa)) != 0 ||
- (r = sshbuf_put_bignum2(b,
- EC_KEY_get0_private_key(key->ecdsa))) != 0)
- goto out;
- break;
- case KEY_ECDSA_CERT:
- if (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0) {
- r = SSH_ERR_INVALID_ARGUMENT;
- goto out;
- }
- if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 ||
- (r = sshbuf_put_bignum2(b,
- EC_KEY_get0_private_key(key->ecdsa))) != 0)
- goto out;
- break;
- case KEY_ECDSA_SK:
- if ((r = sshbuf_put_cstring(b,
- sshkey_curve_nid_to_name(key->ecdsa_nid))) != 0 ||
- (r = sshbuf_put_eckey(b, key->ecdsa)) != 0 ||
- (r = sshbuf_put_cstring(b, key->sk_application)) != 0 ||
- (r = sshbuf_put_u8(b, key->sk_flags)) != 0 ||
- (r = sshbuf_put_stringb(b, key->sk_key_handle)) != 0 ||
- (r = sshbuf_put_stringb(b, key->sk_reserved)) != 0)
- goto out;
- break;
- case KEY_ECDSA_SK_CERT:
- if (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0) {
- r = SSH_ERR_INVALID_ARGUMENT;
- goto out;
- }
- if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 ||
- (r = sshbuf_put_cstring(b, key->sk_application)) != 0 ||
- (r = sshbuf_put_u8(b, key->sk_flags)) != 0 ||
- (r = sshbuf_put_stringb(b, key->sk_key_handle)) != 0 ||
- (r = sshbuf_put_stringb(b, key->sk_reserved)) != 0)
- goto out;
- break;
-# endif /* OPENSSL_HAS_ECC */
-#endif /* WITH_OPENSSL */
- case KEY_ED25519:
- if ((r = sshbuf_put_string(b, key->ed25519_pk,
- ED25519_PK_SZ)) != 0 ||
- (r = sshbuf_put_string(b, key->ed25519_sk,
- ED25519_SK_SZ)) != 0)
- goto out;
- break;
- case KEY_ED25519_CERT:
- if (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0) {
- r = SSH_ERR_INVALID_ARGUMENT;
- goto out;
- }
- if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 ||
- (r = sshbuf_put_string(b, key->ed25519_pk,
- ED25519_PK_SZ)) != 0 ||
- (r = sshbuf_put_string(b, key->ed25519_sk,
- ED25519_SK_SZ)) != 0)
- goto out;
- break;
- case KEY_ED25519_SK:
- if ((r = sshbuf_put_string(b, key->ed25519_pk,
- ED25519_PK_SZ)) != 0 ||
- (r = sshbuf_put_cstring(b, key->sk_application)) != 0 ||
- (r = sshbuf_put_u8(b, key->sk_flags)) != 0 ||
- (r = sshbuf_put_stringb(b, key->sk_key_handle)) != 0 ||
- (r = sshbuf_put_stringb(b, key->sk_reserved)) != 0)
- goto out;
- break;
- case KEY_ED25519_SK_CERT:
- if (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0) {
- r = SSH_ERR_INVALID_ARGUMENT;
- goto out;
- }
- if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 ||
- (r = sshbuf_put_string(b, key->ed25519_pk,
- ED25519_PK_SZ)) != 0 ||
- (r = sshbuf_put_cstring(b, key->sk_application)) != 0 ||
- (r = sshbuf_put_u8(b, key->sk_flags)) != 0 ||
- (r = sshbuf_put_stringb(b, key->sk_key_handle)) != 0 ||
- (r = sshbuf_put_stringb(b, key->sk_reserved)) != 0)
- goto out;
- break;
-#ifdef WITH_XMSS
- case KEY_XMSS:
- if (key->xmss_name == NULL) {
- r = SSH_ERR_INVALID_ARGUMENT;
- goto out;
- }
- if ((r = sshbuf_put_cstring(b, key->xmss_name)) != 0 ||
- (r = sshbuf_put_string(b, key->xmss_pk,
- sshkey_xmss_pklen(key))) != 0 ||
- (r = sshbuf_put_string(b, key->xmss_sk,
- sshkey_xmss_sklen(key))) != 0 ||
- (r = sshkey_xmss_serialize_state_opt(key, b, opts)) != 0)
- goto out;
- break;
- case KEY_XMSS_CERT:
- if (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0 ||
- key->xmss_name == NULL) {
+ if (sshkey_is_cert(key)) {
+ if (key->cert == NULL ||
+ sshbuf_len(key->cert->certblob) == 0) {
r = SSH_ERR_INVALID_ARGUMENT;
goto out;
}
- if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 ||
- (r = sshbuf_put_cstring(b, key->xmss_name)) != 0 ||
- (r = sshbuf_put_string(b, key->xmss_pk,
- sshkey_xmss_pklen(key))) != 0 ||
- (r = sshbuf_put_string(b, key->xmss_sk,
- sshkey_xmss_sklen(key))) != 0 ||
- (r = sshkey_xmss_serialize_state_opt(key, b, opts)) != 0)
+ if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0)
goto out;
- break;
-#endif /* WITH_XMSS */
- default:
- r = SSH_ERR_INVALID_ARGUMENT;
- goto out;
}
+ if ((r = impl->funcs->serialize_private(key, b, opts)) != 0)
+ goto out;
+
/*
* success (but we still need to append the output to buf after
* possibly re-shielding the private key)
*/
r = 0;
out:
if (was_shielded)
r = sshkey_shield_private(key);
if (r == 0)
r = sshbuf_putb(buf, b);
sshbuf_free(b);
return r;
}
int
sshkey_private_serialize(struct sshkey *key, struct sshbuf *b)
{
return sshkey_private_serialize_opt(key, b,
SSHKEY_SERIALIZE_DEFAULT);
}
+/* Shared deserialization of FIDO private key components */
+int
+sshkey_private_deserialize_sk(struct sshbuf *buf, struct sshkey *k)
+{
+ int r;
+
+ if ((k->sk_key_handle = sshbuf_new()) == NULL ||
+ (k->sk_reserved = sshbuf_new()) == NULL)
+ return SSH_ERR_ALLOC_FAIL;
+ if ((r = sshbuf_get_cstring(buf, &k->sk_application, NULL)) != 0 ||
+ (r = sshbuf_get_u8(buf, &k->sk_flags)) != 0 ||
+ (r = sshbuf_get_stringb(buf, k->sk_key_handle)) != 0 ||
+ (r = sshbuf_get_stringb(buf, k->sk_reserved)) != 0)
+ return r;
+
+ return 0;
+}
+
int
sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp)
{
- char *tname = NULL, *curve = NULL, *xmss_name = NULL;
+ const struct sshkey_impl *impl;
+ char *tname = NULL;
char *expect_sk_application = NULL;
+ u_char *expect_ed25519_pk = 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;
- BIGNUM *rsa_n = NULL, *rsa_e = NULL, *rsa_d = NULL;
- BIGNUM *rsa_iqmp = NULL, *rsa_p = NULL, *rsa_q = NULL;
- BIGNUM *dsa_p = NULL, *dsa_q = NULL, *dsa_g = NULL;
- BIGNUM *dsa_pub_key = NULL, *dsa_priv_key = NULL;
-#endif /* WITH_OPENSSL */
if (kp != NULL)
*kp = NULL;
if ((r = sshbuf_get_cstring(buf, &tname, NULL)) != 0)
goto out;
type = sshkey_type_from_name(tname);
if (sshkey_type_is_cert(type)) {
/*
* Certificate key private keys begin with the certificate
* itself. Make sure this matches the type of the enclosing
* private key.
*/
if ((r = sshkey_froms(buf, &k)) != 0)
goto out;
if (k->type != type) {
r = SSH_ERR_KEY_CERT_MISMATCH;
goto out;
}
/* For ECDSA keys, the group must match too */
if (k->type == KEY_ECDSA &&
k->ecdsa_nid != sshkey_ecdsa_nid_from_name(tname)) {
r = SSH_ERR_KEY_CERT_MISMATCH;
goto out;
}
/*
* 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;
+ /* XXX xmss too or refactor */
} else {
if ((k = sshkey_new(type)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
}
- switch (type) {
-#ifdef WITH_OPENSSL
- case KEY_DSA:
- if ((r = sshbuf_get_bignum2(buf, &dsa_p)) != 0 ||
- (r = sshbuf_get_bignum2(buf, &dsa_q)) != 0 ||
- (r = sshbuf_get_bignum2(buf, &dsa_g)) != 0 ||
- (r = sshbuf_get_bignum2(buf, &dsa_pub_key)) != 0)
- goto out;
- if (!DSA_set0_pqg(k->dsa, dsa_p, dsa_q, dsa_g)) {
- r = SSH_ERR_LIBCRYPTO_ERROR;
- goto out;
- }
- dsa_p = dsa_q = dsa_g = NULL; /* transferred */
- if (!DSA_set0_key(k->dsa, dsa_pub_key, NULL)) {
- r = SSH_ERR_LIBCRYPTO_ERROR;
- goto out;
- }
- dsa_pub_key = NULL; /* transferred */
- /* FALLTHROUGH */
- case KEY_DSA_CERT:
- if ((r = sshbuf_get_bignum2(buf, &dsa_priv_key)) != 0)
- goto out;
- if (!DSA_set0_key(k->dsa, NULL, dsa_priv_key)) {
- r = SSH_ERR_LIBCRYPTO_ERROR;
- goto out;
- }
- dsa_priv_key = NULL; /* transferred */
- break;
-# ifdef OPENSSL_HAS_ECC
- case KEY_ECDSA:
- if ((k->ecdsa_nid = sshkey_ecdsa_nid_from_name(tname)) == -1) {
- r = SSH_ERR_INVALID_ARGUMENT;
- goto out;
- }
- if ((r = sshbuf_get_cstring(buf, &curve, NULL)) != 0)
- goto out;
- if (k->ecdsa_nid != sshkey_curve_name_to_nid(curve)) {
- r = SSH_ERR_EC_CURVE_MISMATCH;
- goto out;
- }
- k->ecdsa = EC_KEY_new_by_curve_name(k->ecdsa_nid);
- if (k->ecdsa == NULL) {
- r = SSH_ERR_LIBCRYPTO_ERROR;
- goto out;
- }
- if ((r = sshbuf_get_eckey(buf, k->ecdsa)) != 0)
- goto out;
- /* FALLTHROUGH */
- case KEY_ECDSA_CERT:
- if ((r = sshbuf_get_bignum2(buf, &exponent)) != 0)
- goto out;
- if (EC_KEY_set_private_key(k->ecdsa, exponent) != 1) {
- r = SSH_ERR_LIBCRYPTO_ERROR;
- goto out;
- }
- if ((r = sshkey_ec_validate_public(EC_KEY_get0_group(k->ecdsa),
- EC_KEY_get0_public_key(k->ecdsa))) != 0 ||
- (r = sshkey_ec_validate_private(k->ecdsa)) != 0)
- goto out;
- break;
- case KEY_ECDSA_SK:
- if ((k->ecdsa_nid = sshkey_ecdsa_nid_from_name(tname)) == -1) {
- r = SSH_ERR_INVALID_ARGUMENT;
- goto out;
- }
- if ((r = sshbuf_get_cstring(buf, &curve, NULL)) != 0)
- goto out;
- if (k->ecdsa_nid != sshkey_curve_name_to_nid(curve)) {
- r = SSH_ERR_EC_CURVE_MISMATCH;
- goto out;
- }
- if ((k->sk_key_handle = sshbuf_new()) == NULL ||
- (k->sk_reserved = sshbuf_new()) == NULL) {
- r = SSH_ERR_ALLOC_FAIL;
- goto out;
- }
- k->ecdsa = EC_KEY_new_by_curve_name(k->ecdsa_nid);
- if (k->ecdsa == NULL) {
- r = SSH_ERR_LIBCRYPTO_ERROR;
- goto out;
- }
- if ((r = sshbuf_get_eckey(buf, k->ecdsa)) != 0 ||
- (r = sshbuf_get_cstring(buf, &k->sk_application,
- NULL)) != 0 ||
- (r = sshbuf_get_u8(buf, &k->sk_flags)) != 0 ||
- (r = sshbuf_get_stringb(buf, k->sk_key_handle)) != 0 ||
- (r = sshbuf_get_stringb(buf, k->sk_reserved)) != 0)
- goto out;
- if ((r = sshkey_ec_validate_public(EC_KEY_get0_group(k->ecdsa),
- EC_KEY_get0_public_key(k->ecdsa))) != 0)
- goto out;
- break;
- case KEY_ECDSA_SK_CERT:
- if ((k->sk_key_handle = sshbuf_new()) == NULL ||
- (k->sk_reserved = sshbuf_new()) == NULL) {
- r = SSH_ERR_ALLOC_FAIL;
- goto out;
- }
- if ((r = sshbuf_get_cstring(buf, &k->sk_application,
- NULL)) != 0 ||
- (r = sshbuf_get_u8(buf, &k->sk_flags)) != 0 ||
- (r = sshbuf_get_stringb(buf, k->sk_key_handle)) != 0 ||
- (r = sshbuf_get_stringb(buf, k->sk_reserved)) != 0)
- goto out;
- if ((r = sshkey_ec_validate_public(EC_KEY_get0_group(k->ecdsa),
- EC_KEY_get0_public_key(k->ecdsa))) != 0)
- goto out;
- break;
-# endif /* OPENSSL_HAS_ECC */
- case KEY_RSA:
- if ((r = sshbuf_get_bignum2(buf, &rsa_n)) != 0 ||
- (r = sshbuf_get_bignum2(buf, &rsa_e)) != 0)
- goto out;
- if (!RSA_set0_key(k->rsa, rsa_n, rsa_e, NULL)) {
- r = SSH_ERR_LIBCRYPTO_ERROR;
- goto out;
- }
- rsa_n = rsa_e = NULL; /* transferred */
- /* FALLTHROUGH */
- case KEY_RSA_CERT:
- if ((r = sshbuf_get_bignum2(buf, &rsa_d)) != 0 ||
- (r = sshbuf_get_bignum2(buf, &rsa_iqmp)) != 0 ||
- (r = sshbuf_get_bignum2(buf, &rsa_p)) != 0 ||
- (r = sshbuf_get_bignum2(buf, &rsa_q)) != 0)
- goto out;
- if (!RSA_set0_key(k->rsa, NULL, NULL, rsa_d)) {
- r = SSH_ERR_LIBCRYPTO_ERROR;
- goto out;
- }
- rsa_d = NULL; /* transferred */
- if (!RSA_set0_factors(k->rsa, rsa_p, rsa_q)) {
- r = SSH_ERR_LIBCRYPTO_ERROR;
- goto out;
- }
- rsa_p = rsa_q = NULL; /* transferred */
- if ((r = sshkey_check_rsa_length(k, 0)) != 0)
- goto out;
- if ((r = ssh_rsa_complete_crt_parameters(k, rsa_iqmp)) != 0)
- goto out;
- break;
-#endif /* WITH_OPENSSL */
- case KEY_ED25519:
- case KEY_ED25519_CERT:
- if ((r = sshbuf_get_string(buf, &ed25519_pk, &pklen)) != 0 ||
- (r = sshbuf_get_string(buf, &ed25519_sk, &sklen)) != 0)
- goto out;
- if (pklen != ED25519_PK_SZ || sklen != ED25519_SK_SZ) {
- r = SSH_ERR_INVALID_FORMAT;
- goto out;
- }
- k->ed25519_pk = ed25519_pk;
- k->ed25519_sk = ed25519_sk;
- ed25519_pk = ed25519_sk = NULL; /* transferred */
- break;
- case KEY_ED25519_SK:
- case KEY_ED25519_SK_CERT:
- if ((r = sshbuf_get_string(buf, &ed25519_pk, &pklen)) != 0)
- goto out;
- if (pklen != ED25519_PK_SZ) {
- r = SSH_ERR_INVALID_FORMAT;
- goto out;
- }
- if ((k->sk_key_handle = sshbuf_new()) == NULL ||
- (k->sk_reserved = sshbuf_new()) == NULL) {
- r = SSH_ERR_ALLOC_FAIL;
- goto out;
- }
- if ((r = sshbuf_get_cstring(buf, &k->sk_application,
- NULL)) != 0 ||
- (r = sshbuf_get_u8(buf, &k->sk_flags)) != 0 ||
- (r = sshbuf_get_stringb(buf, k->sk_key_handle)) != 0 ||
- (r = sshbuf_get_stringb(buf, k->sk_reserved)) != 0)
- goto out;
- k->ed25519_pk = ed25519_pk;
- ed25519_pk = NULL; /* transferred */
- break;
-#ifdef WITH_XMSS
- case KEY_XMSS:
- case KEY_XMSS_CERT:
- if ((r = sshbuf_get_cstring(buf, &xmss_name, NULL)) != 0 ||
- (r = sshbuf_get_string(buf, &xmss_pk, &pklen)) != 0 ||
- (r = sshbuf_get_string(buf, &xmss_sk, &sklen)) != 0)
- goto out;
- if (type == KEY_XMSS &&
- (r = sshkey_xmss_init(k, xmss_name)) != 0)
- goto out;
- if (pklen != sshkey_xmss_pklen(k) ||
- sklen != sshkey_xmss_sklen(k)) {
- r = SSH_ERR_INVALID_FORMAT;
- goto out;
- }
- k->xmss_pk = xmss_pk;
- k->xmss_sk = xmss_sk;
- xmss_pk = xmss_sk = NULL;
- /* optional internal state */
- if ((r = sshkey_xmss_deserialize_state_opt(k, buf)) != 0)
- goto out;
- break;
-#endif /* WITH_XMSS */
- default:
- r = SSH_ERR_KEY_TYPE_UNKNOWN;
+ if ((impl = sshkey_impl_from_type(type)) == NULL) {
+ r = SSH_ERR_INTERNAL_ERROR;
goto out;
}
-#ifdef WITH_OPENSSL
- /* enable blinding */
- switch (k->type) {
- case KEY_RSA:
- case KEY_RSA_CERT:
- if (RSA_blinding_on(k->rsa, NULL) != 1) {
- r = SSH_ERR_LIBCRYPTO_ERROR;
- goto out;
- }
- break;
- }
-#endif /* WITH_OPENSSL */
+ if ((r = impl->funcs->deserialize_private(tname, buf, k)) != 0)
+ goto out;
+
+ /* XXX xmss too or refactor */
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) {
*kp = k;
k = NULL;
}
out:
free(tname);
- free(curve);
-#ifdef WITH_OPENSSL
- BN_clear_free(exponent);
- BN_clear_free(dsa_p);
- BN_clear_free(dsa_q);
- BN_clear_free(dsa_g);
- BN_clear_free(dsa_pub_key);
- BN_clear_free(dsa_priv_key);
- BN_clear_free(rsa_n);
- BN_clear_free(rsa_e);
- BN_clear_free(rsa_d);
- BN_clear_free(rsa_p);
- BN_clear_free(rsa_q);
- BN_clear_free(rsa_iqmp);
-#endif /* WITH_OPENSSL */
sshkey_free(k);
- freezero(ed25519_pk, pklen);
- freezero(ed25519_sk, sklen);
- free(xmss_name);
- freezero(xmss_pk, pklen);
- freezero(xmss_sk, sklen);
free(expect_sk_application);
free(expect_ed25519_pk);
return r;
}
#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC)
int
sshkey_ec_validate_public(const EC_GROUP *group, const EC_POINT *public)
{
EC_POINT *nq = NULL;
BIGNUM *order = NULL, *x = NULL, *y = NULL, *tmp = NULL;
int ret = SSH_ERR_KEY_INVALID_EC_VALUE;
/*
* NB. This assumes OpenSSL has already verified that the public
* point lies on the curve. This is done by EC_POINT_oct2point()
* implicitly calling EC_POINT_is_on_curve(). If this code is ever
* reachable with public points not unmarshalled using
* EC_POINT_oct2point then the caller will need to explicitly check.
*/
/*
* We shouldn't ever hit this case because bignum_get_ecpoint()
* refuses to load GF2m points.
*/
if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
NID_X9_62_prime_field)
goto out;
/* Q != infinity */
if (EC_POINT_is_at_infinity(group, public))
goto out;
if ((x = BN_new()) == NULL ||
(y = BN_new()) == NULL ||
(order = BN_new()) == NULL ||
(tmp = BN_new()) == NULL) {
ret = SSH_ERR_ALLOC_FAIL;
goto out;
}
/* log2(x) > log2(order)/2, log2(y) > log2(order)/2 */
if (EC_GROUP_get_order(group, order, NULL) != 1 ||
EC_POINT_get_affine_coordinates_GFp(group, public,
x, y, NULL) != 1) {
ret = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
if (BN_num_bits(x) <= BN_num_bits(order) / 2 ||
BN_num_bits(y) <= BN_num_bits(order) / 2)
goto out;
/* nQ == infinity (n == order of subgroup) */
if ((nq = EC_POINT_new(group)) == NULL) {
ret = SSH_ERR_ALLOC_FAIL;
goto out;
}
if (EC_POINT_mul(group, nq, NULL, public, order, NULL) != 1) {
ret = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
if (EC_POINT_is_at_infinity(group, nq) != 1)
goto out;
/* x < order - 1, y < order - 1 */
if (!BN_sub(tmp, order, BN_value_one())) {
ret = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
if (BN_cmp(x, tmp) >= 0 || BN_cmp(y, tmp) >= 0)
goto out;
ret = 0;
out:
BN_clear_free(x);
BN_clear_free(y);
BN_clear_free(order);
BN_clear_free(tmp);
EC_POINT_free(nq);
return ret;
}
int
sshkey_ec_validate_private(const EC_KEY *key)
{
BIGNUM *order = NULL, *tmp = NULL;
int ret = SSH_ERR_KEY_INVALID_EC_VALUE;
if ((order = BN_new()) == NULL || (tmp = BN_new()) == NULL) {
ret = SSH_ERR_ALLOC_FAIL;
goto out;
}
/* log2(private) > log2(order)/2 */
if (EC_GROUP_get_order(EC_KEY_get0_group(key), order, NULL) != 1) {
ret = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
if (BN_num_bits(EC_KEY_get0_private_key(key)) <=
BN_num_bits(order) / 2)
goto out;
/* private < order - 1 */
if (!BN_sub(tmp, order, BN_value_one())) {
ret = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
if (BN_cmp(EC_KEY_get0_private_key(key), tmp) >= 0)
goto out;
ret = 0;
out:
BN_clear_free(order);
BN_clear_free(tmp);
return ret;
}
void
sshkey_dump_ec_point(const EC_GROUP *group, const EC_POINT *point)
{
BIGNUM *x = NULL, *y = NULL;
if (point == NULL) {
fputs("point=(NULL)\n", stderr);
return;
}
if ((x = BN_new()) == NULL || (y = BN_new()) == NULL) {
fprintf(stderr, "%s: BN_new failed\n", __func__);
goto out;
}
if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
NID_X9_62_prime_field) {
fprintf(stderr, "%s: group is not a prime field\n", __func__);
goto out;
}
if (EC_POINT_get_affine_coordinates_GFp(group, point,
x, y, NULL) != 1) {
fprintf(stderr, "%s: EC_POINT_get_affine_coordinates_GFp\n",
__func__);
goto out;
}
fputs("x=", stderr);
BN_print_fp(stderr, x);
fputs("\ny=", stderr);
BN_print_fp(stderr, y);
fputs("\n", stderr);
out:
BN_clear_free(x);
BN_clear_free(y);
}
void
sshkey_dump_ec_key(const EC_KEY *key)
{
const BIGNUM *exponent;
sshkey_dump_ec_point(EC_KEY_get0_group(key),
EC_KEY_get0_public_key(key));
fputs("exponent=", stderr);
if ((exponent = EC_KEY_get0_private_key(key)) == NULL)
fputs("(NULL)", stderr);
else
BN_print_fp(stderr, EC_KEY_get0_private_key(key));
fputs("\n", stderr);
}
#endif /* WITH_OPENSSL && OPENSSL_HAS_ECC */
static int
sshkey_private_to_blob2(struct sshkey *prv, struct sshbuf *blob,
const char *passphrase, const char *comment, const char *ciphername,
int rounds)
{
u_char *cp, *key = NULL, *pubkeyblob = NULL;
u_char salt[SALT_LEN];
char *b64 = NULL;
size_t i, pubkeylen, keylen, ivlen, blocksize, authlen;
u_int check;
int r = SSH_ERR_INTERNAL_ERROR;
struct sshcipher_ctx *ciphercontext = NULL;
const struct sshcipher *cipher;
const char *kdfname = KDFNAME;
struct sshbuf *encoded = NULL, *encrypted = NULL, *kdf = NULL;
if (rounds <= 0)
rounds = DEFAULT_ROUNDS;
if (passphrase == NULL || !strlen(passphrase)) {
ciphername = "none";
kdfname = "none";
} else if (ciphername == NULL)
ciphername = DEFAULT_CIPHERNAME;
if ((cipher = cipher_by_name(ciphername)) == NULL) {
r = SSH_ERR_INVALID_ARGUMENT;
goto out;
}
if ((kdf = sshbuf_new()) == NULL ||
(encoded = sshbuf_new()) == NULL ||
(encrypted = sshbuf_new()) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
blocksize = cipher_blocksize(cipher);
keylen = cipher_keylen(cipher);
ivlen = cipher_ivlen(cipher);
authlen = cipher_authlen(cipher);
if ((key = calloc(1, keylen + ivlen)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
if (strcmp(kdfname, "bcrypt") == 0) {
arc4random_buf(salt, SALT_LEN);
if (bcrypt_pbkdf(passphrase, strlen(passphrase),
salt, SALT_LEN, key, keylen + ivlen, rounds) < 0) {
r = SSH_ERR_INVALID_ARGUMENT;
goto out;
}
if ((r = sshbuf_put_string(kdf, salt, SALT_LEN)) != 0 ||
(r = sshbuf_put_u32(kdf, rounds)) != 0)
goto out;
} else if (strcmp(kdfname, "none") != 0) {
/* Unsupported KDF type */
r = SSH_ERR_KEY_UNKNOWN_CIPHER;
goto out;
}
if ((r = cipher_init(&ciphercontext, cipher, key, keylen,
key + keylen, ivlen, 1)) != 0)
goto out;
if ((r = sshbuf_put(encoded, AUTH_MAGIC, sizeof(AUTH_MAGIC))) != 0 ||
(r = sshbuf_put_cstring(encoded, ciphername)) != 0 ||
(r = sshbuf_put_cstring(encoded, kdfname)) != 0 ||
(r = sshbuf_put_stringb(encoded, kdf)) != 0 ||
(r = sshbuf_put_u32(encoded, 1)) != 0 || /* number of keys */
(r = sshkey_to_blob(prv, &pubkeyblob, &pubkeylen)) != 0 ||
(r = sshbuf_put_string(encoded, pubkeyblob, pubkeylen)) != 0)
goto out;
/* set up the buffer that will be encrypted */
/* Random check bytes */
check = arc4random();
if ((r = sshbuf_put_u32(encrypted, check)) != 0 ||
(r = sshbuf_put_u32(encrypted, check)) != 0)
goto out;
/* append private key and comment*/
if ((r = sshkey_private_serialize_opt(prv, encrypted,
SSHKEY_SERIALIZE_FULL)) != 0 ||
(r = sshbuf_put_cstring(encrypted, comment)) != 0)
goto out;
/* padding */
i = 0;
while (sshbuf_len(encrypted) % blocksize) {
if ((r = sshbuf_put_u8(encrypted, ++i & 0xff)) != 0)
goto out;
}
/* length in destination buffer */
if ((r = sshbuf_put_u32(encoded, sshbuf_len(encrypted))) != 0)
goto out;
/* encrypt */
if ((r = sshbuf_reserve(encoded,
sshbuf_len(encrypted) + authlen, &cp)) != 0)
goto out;
if ((r = cipher_crypt(ciphercontext, 0, cp,
sshbuf_ptr(encrypted), sshbuf_len(encrypted), 0, authlen)) != 0)
goto out;
sshbuf_reset(blob);
/* assemble uuencoded key */
if ((r = sshbuf_put(blob, MARK_BEGIN, MARK_BEGIN_LEN)) != 0 ||
(r = sshbuf_dtob64(encoded, blob, 1)) != 0 ||
(r = sshbuf_put(blob, MARK_END, MARK_END_LEN)) != 0)
goto out;
/* success */
r = 0;
out:
sshbuf_free(kdf);
sshbuf_free(encoded);
sshbuf_free(encrypted);
cipher_free(ciphercontext);
explicit_bzero(salt, sizeof(salt));
if (key != NULL)
freezero(key, keylen + ivlen);
if (pubkeyblob != NULL)
freezero(pubkeyblob, pubkeylen);
if (b64 != NULL)
freezero(b64, strlen(b64));
return r;
}
static int
private2_uudecode(struct sshbuf *blob, struct sshbuf **decodedp)
{
const u_char *cp;
size_t encoded_len;
int r;
u_char last;
struct sshbuf *encoded = NULL, *decoded = NULL;
if (blob == NULL || decodedp == NULL)
return SSH_ERR_INVALID_ARGUMENT;
*decodedp = NULL;
if ((encoded = sshbuf_new()) == NULL ||
(decoded = sshbuf_new()) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
/* check preamble */
cp = sshbuf_ptr(blob);
encoded_len = sshbuf_len(blob);
if (encoded_len < (MARK_BEGIN_LEN + MARK_END_LEN) ||
memcmp(cp, MARK_BEGIN, MARK_BEGIN_LEN) != 0) {
r = SSH_ERR_INVALID_FORMAT;
goto out;
}
cp += MARK_BEGIN_LEN;
encoded_len -= MARK_BEGIN_LEN;
/* Look for end marker, removing whitespace as we go */
while (encoded_len > 0) {
if (*cp != '\n' && *cp != '\r') {
if ((r = sshbuf_put_u8(encoded, *cp)) != 0)
goto out;
}
last = *cp;
encoded_len--;
cp++;
if (last == '\n') {
if (encoded_len >= MARK_END_LEN &&
memcmp(cp, MARK_END, MARK_END_LEN) == 0) {
/* \0 terminate */
if ((r = sshbuf_put_u8(encoded, 0)) != 0)
goto out;
break;
}
}
}
if (encoded_len == 0) {
r = SSH_ERR_INVALID_FORMAT;
goto out;
}
/* decode base64 */
if ((r = sshbuf_b64tod(decoded, (char *)sshbuf_ptr(encoded))) != 0)
goto out;
/* check magic */
if (sshbuf_len(decoded) < sizeof(AUTH_MAGIC) ||
memcmp(sshbuf_ptr(decoded), AUTH_MAGIC, sizeof(AUTH_MAGIC))) {
r = SSH_ERR_INVALID_FORMAT;
goto out;
}
/* success */
*decodedp = decoded;
decoded = NULL;
r = 0;
out:
sshbuf_free(encoded);
sshbuf_free(decoded);
return r;
}
static int
private2_decrypt(struct sshbuf *decoded, const char *passphrase,
struct sshbuf **decryptedp, struct sshkey **pubkeyp)
{
char *ciphername = NULL, *kdfname = NULL;
const struct sshcipher *cipher = NULL;
int r = SSH_ERR_INTERNAL_ERROR;
size_t keylen = 0, ivlen = 0, authlen = 0, slen = 0;
struct sshbuf *kdf = NULL, *decrypted = NULL;
struct sshcipher_ctx *ciphercontext = NULL;
struct sshkey *pubkey = NULL;
u_char *key = NULL, *salt = NULL, *dp;
u_int blocksize, rounds, nkeys, encrypted_len, check1, check2;
if (decoded == NULL || decryptedp == NULL || pubkeyp == NULL)
return SSH_ERR_INVALID_ARGUMENT;
*decryptedp = NULL;
*pubkeyp = NULL;
if ((decrypted = sshbuf_new()) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
/* parse public portion of key */
if ((r = sshbuf_consume(decoded, sizeof(AUTH_MAGIC))) != 0 ||
(r = sshbuf_get_cstring(decoded, &ciphername, NULL)) != 0 ||
(r = sshbuf_get_cstring(decoded, &kdfname, NULL)) != 0 ||
(r = sshbuf_froms(decoded, &kdf)) != 0 ||
(r = sshbuf_get_u32(decoded, &nkeys)) != 0)
goto out;
if (nkeys != 1) {
/* XXX only one key supported at present */
r = SSH_ERR_INVALID_FORMAT;
goto out;
}
if ((r = sshkey_froms(decoded, &pubkey)) != 0 ||
(r = sshbuf_get_u32(decoded, &encrypted_len)) != 0)
goto out;
if ((cipher = cipher_by_name(ciphername)) == NULL) {
r = SSH_ERR_KEY_UNKNOWN_CIPHER;
goto out;
}
if (strcmp(kdfname, "none") != 0 && strcmp(kdfname, "bcrypt") != 0) {
r = SSH_ERR_KEY_UNKNOWN_CIPHER;
goto out;
}
if (strcmp(kdfname, "none") == 0 && strcmp(ciphername, "none") != 0) {
r = SSH_ERR_INVALID_FORMAT;
goto out;
}
if ((passphrase == NULL || strlen(passphrase) == 0) &&
strcmp(kdfname, "none") != 0) {
/* passphrase required */
r = SSH_ERR_KEY_WRONG_PASSPHRASE;
goto out;
}
/* check size of encrypted key blob */
blocksize = cipher_blocksize(cipher);
if (encrypted_len < blocksize || (encrypted_len % blocksize) != 0) {
r = SSH_ERR_INVALID_FORMAT;
goto out;
}
/* setup key */
keylen = cipher_keylen(cipher);
ivlen = cipher_ivlen(cipher);
authlen = cipher_authlen(cipher);
if ((key = calloc(1, keylen + ivlen)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
if (strcmp(kdfname, "bcrypt") == 0) {
if ((r = sshbuf_get_string(kdf, &salt, &slen)) != 0 ||
(r = sshbuf_get_u32(kdf, &rounds)) != 0)
goto out;
if (bcrypt_pbkdf(passphrase, strlen(passphrase), salt, slen,
key, keylen + ivlen, rounds) < 0) {
r = SSH_ERR_INVALID_FORMAT;
goto out;
}
}
/* check that an appropriate amount of auth data is present */
if (sshbuf_len(decoded) < authlen ||
sshbuf_len(decoded) - authlen < encrypted_len) {
r = SSH_ERR_INVALID_FORMAT;
goto out;
}
/* decrypt private portion of key */
if ((r = sshbuf_reserve(decrypted, encrypted_len, &dp)) != 0 ||
(r = cipher_init(&ciphercontext, cipher, key, keylen,
key + keylen, ivlen, 0)) != 0)
goto out;
if ((r = cipher_crypt(ciphercontext, 0, dp, sshbuf_ptr(decoded),
encrypted_len, 0, authlen)) != 0) {
/* an integrity error here indicates an incorrect passphrase */
if (r == SSH_ERR_MAC_INVALID)
r = SSH_ERR_KEY_WRONG_PASSPHRASE;
goto out;
}
if ((r = sshbuf_consume(decoded, encrypted_len + authlen)) != 0)
goto out;
/* there should be no trailing data */
if (sshbuf_len(decoded) != 0) {
r = SSH_ERR_INVALID_FORMAT;
goto out;
}
/* check check bytes */
if ((r = sshbuf_get_u32(decrypted, &check1)) != 0 ||
(r = sshbuf_get_u32(decrypted, &check2)) != 0)
goto out;
if (check1 != check2) {
r = SSH_ERR_KEY_WRONG_PASSPHRASE;
goto out;
}
/* success */
*decryptedp = decrypted;
decrypted = NULL;
*pubkeyp = pubkey;
pubkey = NULL;
r = 0;
out:
cipher_free(ciphercontext);
free(ciphername);
free(kdfname);
sshkey_free(pubkey);
if (salt != NULL) {
explicit_bzero(salt, slen);
free(salt);
}
if (key != NULL) {
explicit_bzero(key, keylen + ivlen);
free(key);
}
sshbuf_free(kdf);
sshbuf_free(decrypted);
return r;
}
static int
sshkey_parse_private2(struct sshbuf *blob, int type, const char *passphrase,
struct sshkey **keyp, char **commentp)
{
char *comment = NULL;
int r = SSH_ERR_INTERNAL_ERROR;
struct sshbuf *decoded = NULL, *decrypted = NULL;
struct sshkey *k = NULL, *pubkey = NULL;
if (keyp != NULL)
*keyp = NULL;
if (commentp != NULL)
*commentp = NULL;
/* Undo base64 encoding and decrypt the private section */
if ((r = private2_uudecode(blob, &decoded)) != 0 ||
(r = private2_decrypt(decoded, passphrase,
&decrypted, &pubkey)) != 0)
goto out;
if (type != KEY_UNSPEC &&
sshkey_type_plain(type) != sshkey_type_plain(pubkey->type)) {
r = SSH_ERR_KEY_TYPE_MISMATCH;
goto out;
}
/* Load the private key and comment */
if ((r = sshkey_private_deserialize(decrypted, &k)) != 0 ||
(r = sshbuf_get_cstring(decrypted, &comment, NULL)) != 0)
goto out;
/* Check deterministic padding after private section */
if ((r = private2_check_padding(decrypted)) != 0)
goto out;
/* Check that the public key in the envelope matches the private key */
if (!sshkey_equal(pubkey, k)) {
r = SSH_ERR_INVALID_FORMAT;
goto out;
}
/* success */
r = 0;
if (keyp != NULL) {
*keyp = k;
k = NULL;
}
if (commentp != NULL) {
*commentp = comment;
comment = NULL;
}
out:
free(comment);
sshbuf_free(decoded);
sshbuf_free(decrypted);
sshkey_free(k);
sshkey_free(pubkey);
return r;
}
static int
sshkey_parse_private2_pubkey(struct sshbuf *blob, int type,
struct sshkey **keyp)
{
int r = SSH_ERR_INTERNAL_ERROR;
struct sshbuf *decoded = NULL;
struct sshkey *pubkey = NULL;
u_int nkeys = 0;
if (keyp != NULL)
*keyp = NULL;
if ((r = private2_uudecode(blob, &decoded)) != 0)
goto out;
/* parse public key from unencrypted envelope */
if ((r = sshbuf_consume(decoded, sizeof(AUTH_MAGIC))) != 0 ||
(r = sshbuf_skip_string(decoded)) != 0 || /* cipher */
(r = sshbuf_skip_string(decoded)) != 0 || /* KDF alg */
(r = sshbuf_skip_string(decoded)) != 0 || /* KDF hint */
(r = sshbuf_get_u32(decoded, &nkeys)) != 0)
goto out;
if (nkeys != 1) {
/* XXX only one key supported at present */
r = SSH_ERR_INVALID_FORMAT;
goto out;
}
/* Parse the public key */
if ((r = sshkey_froms(decoded, &pubkey)) != 0)
goto out;
if (type != KEY_UNSPEC &&
sshkey_type_plain(type) != sshkey_type_plain(pubkey->type)) {
r = SSH_ERR_KEY_TYPE_MISMATCH;
goto out;
}
/* success */
r = 0;
if (keyp != NULL) {
*keyp = pubkey;
pubkey = NULL;
}
out:
sshbuf_free(decoded);
sshkey_free(pubkey);
return r;
}
#ifdef WITH_OPENSSL
/* convert SSH v2 key to PEM or PKCS#8 format */
static int
sshkey_private_to_blob_pem_pkcs8(struct sshkey *key, struct sshbuf *buf,
int format, const char *_passphrase, const char *comment)
{
int was_shielded = sshkey_is_shielded(key);
int success, r;
int blen, len = strlen(_passphrase);
u_char *passphrase = (len > 0) ? (u_char *)_passphrase : NULL;
const EVP_CIPHER *cipher = (len > 0) ? EVP_aes_128_cbc() : NULL;
char *bptr;
BIO *bio = NULL;
struct sshbuf *blob;
EVP_PKEY *pkey = NULL;
if (len > 0 && len <= 4)
return SSH_ERR_PASSPHRASE_TOO_SHORT;
if ((blob = sshbuf_new()) == NULL)
return SSH_ERR_ALLOC_FAIL;
if ((bio = BIO_new(BIO_s_mem())) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
if (format == SSHKEY_PRIVATE_PKCS8 && (pkey = EVP_PKEY_new()) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
if ((r = sshkey_unshield_private(key)) != 0)
goto out;
switch (key->type) {
case KEY_DSA:
if (format == SSHKEY_PRIVATE_PEM) {
success = PEM_write_bio_DSAPrivateKey(bio, key->dsa,
cipher, passphrase, len, NULL, NULL);
} else {
success = EVP_PKEY_set1_DSA(pkey, key->dsa);
}
break;
#ifdef OPENSSL_HAS_ECC
case KEY_ECDSA:
if (format == SSHKEY_PRIVATE_PEM) {
success = PEM_write_bio_ECPrivateKey(bio, key->ecdsa,
cipher, passphrase, len, NULL, NULL);
} else {
success = EVP_PKEY_set1_EC_KEY(pkey, key->ecdsa);
}
break;
#endif
case KEY_RSA:
if (format == SSHKEY_PRIVATE_PEM) {
success = PEM_write_bio_RSAPrivateKey(bio, key->rsa,
cipher, passphrase, len, NULL, NULL);
} else {
success = EVP_PKEY_set1_RSA(pkey, key->rsa);
}
break;
default:
success = 0;
break;
}
if (success == 0) {
r = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
if (format == SSHKEY_PRIVATE_PKCS8) {
if ((success = PEM_write_bio_PrivateKey(bio, pkey, cipher,
passphrase, len, NULL, NULL)) == 0) {
r = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
}
if ((blen = BIO_get_mem_data(bio, &bptr)) <= 0) {
r = SSH_ERR_INTERNAL_ERROR;
goto out;
}
if ((r = sshbuf_put(blob, bptr, blen)) != 0)
goto out;
r = 0;
out:
if (was_shielded)
r = sshkey_shield_private(key);
if (r == 0)
r = sshbuf_putb(buf, blob);
EVP_PKEY_free(pkey);
sshbuf_free(blob);
BIO_free(bio);
return r;
}
#endif /* WITH_OPENSSL */
/* Serialise "key" to buffer "blob" */
int
sshkey_private_to_fileblob(struct sshkey *key, struct sshbuf *blob,
const char *passphrase, const char *comment,
int format, const char *openssh_format_cipher, int openssh_format_rounds)
{
switch (key->type) {
#ifdef WITH_OPENSSL
case KEY_DSA:
case KEY_ECDSA:
case KEY_RSA:
break; /* see below */
#endif /* WITH_OPENSSL */
case KEY_ED25519:
case KEY_ED25519_SK:
#ifdef WITH_XMSS
case KEY_XMSS:
#endif /* WITH_XMSS */
#ifdef WITH_OPENSSL
case KEY_ECDSA_SK:
#endif /* WITH_OPENSSL */
return sshkey_private_to_blob2(key, blob, passphrase,
comment, openssh_format_cipher, openssh_format_rounds);
default:
return SSH_ERR_KEY_TYPE_UNKNOWN;
}
#ifdef WITH_OPENSSL
switch (format) {
case SSHKEY_PRIVATE_OPENSSH:
return sshkey_private_to_blob2(key, blob, passphrase,
comment, openssh_format_cipher, openssh_format_rounds);
case SSHKEY_PRIVATE_PEM:
case SSHKEY_PRIVATE_PKCS8:
return sshkey_private_to_blob_pem_pkcs8(key, blob,
format, passphrase, comment);
default:
return SSH_ERR_INVALID_ARGUMENT;
}
#endif /* WITH_OPENSSL */
}
#ifdef WITH_OPENSSL
static int
translate_libcrypto_error(unsigned long pem_err)
{
int pem_reason = ERR_GET_REASON(pem_err);
switch (ERR_GET_LIB(pem_err)) {
case ERR_LIB_PEM:
switch (pem_reason) {
case PEM_R_BAD_PASSWORD_READ:
case PEM_R_PROBLEMS_GETTING_PASSWORD:
case PEM_R_BAD_DECRYPT:
return SSH_ERR_KEY_WRONG_PASSPHRASE;
default:
return SSH_ERR_INVALID_FORMAT;
}
case ERR_LIB_EVP:
switch (pem_reason) {
case EVP_R_BAD_DECRYPT:
return SSH_ERR_KEY_WRONG_PASSPHRASE;
#ifdef EVP_R_BN_DECODE_ERROR
case EVP_R_BN_DECODE_ERROR:
#endif
case EVP_R_DECODE_ERROR:
#ifdef EVP_R_PRIVATE_KEY_DECODE_ERROR
case EVP_R_PRIVATE_KEY_DECODE_ERROR:
#endif
return SSH_ERR_INVALID_FORMAT;
default:
return SSH_ERR_LIBCRYPTO_ERROR;
}
case ERR_LIB_ASN1:
return SSH_ERR_INVALID_FORMAT;
}
return SSH_ERR_LIBCRYPTO_ERROR;
}
static void
clear_libcrypto_errors(void)
{
while (ERR_get_error() != 0)
;
}
/*
* Translate OpenSSL error codes to determine whether
* passphrase is required/incorrect.
*/
static int
convert_libcrypto_error(void)
{
/*
* Some password errors are reported at the beginning
* of the error queue.
*/
if (translate_libcrypto_error(ERR_peek_error()) ==
SSH_ERR_KEY_WRONG_PASSPHRASE)
return SSH_ERR_KEY_WRONG_PASSPHRASE;
return translate_libcrypto_error(ERR_peek_last_error());
}
static int
pem_passphrase_cb(char *buf, int size, int rwflag, void *u)
{
char *p = (char *)u;
size_t len;
if (p == NULL || (len = strlen(p)) == 0)
return -1;
if (size < 0 || len > (size_t)size)
return -1;
memcpy(buf, p, len);
return (int)len;
}
static int
sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type,
const char *passphrase, struct sshkey **keyp)
{
EVP_PKEY *pk = NULL;
struct sshkey *prv = NULL;
BIO *bio = NULL;
int r;
if (keyp != NULL)
*keyp = NULL;
if ((bio = BIO_new(BIO_s_mem())) == NULL || sshbuf_len(blob) > INT_MAX)
return SSH_ERR_ALLOC_FAIL;
if (BIO_write(bio, sshbuf_ptr(blob), sshbuf_len(blob)) !=
(int)sshbuf_len(blob)) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
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.
*/
if (passphrase != NULL && *passphrase != '\0')
r = SSH_ERR_KEY_WRONG_PASSPHRASE;
else
r = convert_libcrypto_error();
goto out;
}
if (EVP_PKEY_base_id(pk) == EVP_PKEY_RSA &&
(type == KEY_UNSPEC || type == KEY_RSA)) {
if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
prv->rsa = EVP_PKEY_get1_RSA(pk);
prv->type = KEY_RSA;
#ifdef DEBUG_PK
RSA_print_fp(stderr, prv->rsa, 8);
#endif
if (RSA_blinding_on(prv->rsa, NULL) != 1) {
r = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
if ((r = sshkey_check_rsa_length(prv, 0)) != 0)
goto out;
} else if (EVP_PKEY_base_id(pk) == EVP_PKEY_DSA &&
(type == KEY_UNSPEC || type == KEY_DSA)) {
if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
prv->dsa = EVP_PKEY_get1_DSA(pk);
prv->type = KEY_DSA;
#ifdef DEBUG_PK
DSA_print_fp(stderr, prv->dsa, 8);
#endif
#ifdef OPENSSL_HAS_ECC
} else if (EVP_PKEY_base_id(pk) == EVP_PKEY_EC &&
(type == KEY_UNSPEC || type == KEY_ECDSA)) {
if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
prv->ecdsa = EVP_PKEY_get1_EC_KEY(pk);
prv->type = KEY_ECDSA;
prv->ecdsa_nid = sshkey_ecdsa_key_to_nid(prv->ecdsa);
if (prv->ecdsa_nid == -1 ||
sshkey_curve_nid_to_name(prv->ecdsa_nid) == NULL ||
sshkey_ec_validate_public(EC_KEY_get0_group(prv->ecdsa),
EC_KEY_get0_public_key(prv->ecdsa)) != 0 ||
sshkey_ec_validate_private(prv->ecdsa) != 0) {
r = SSH_ERR_INVALID_FORMAT;
goto out;
}
# ifdef DEBUG_PK
if (prv != NULL && prv->ecdsa != NULL)
sshkey_dump_ec_key(prv->ecdsa);
# endif
#endif /* OPENSSL_HAS_ECC */
} else {
r = SSH_ERR_INVALID_FORMAT;
goto out;
}
r = 0;
if (keyp != NULL) {
*keyp = prv;
prv = NULL;
}
out:
BIO_free(bio);
EVP_PKEY_free(pk);
sshkey_free(prv);
return r;
}
#endif /* WITH_OPENSSL */
int
sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type,
const char *passphrase, struct sshkey **keyp, char **commentp)
{
int r = SSH_ERR_INTERNAL_ERROR;
if (keyp != NULL)
*keyp = NULL;
if (commentp != NULL)
*commentp = NULL;
switch (type) {
case KEY_ED25519:
case KEY_XMSS:
/* No fallback for new-format-only keys */
return sshkey_parse_private2(blob, type, passphrase,
keyp, commentp);
default:
r = sshkey_parse_private2(blob, type, passphrase, keyp,
commentp);
/* Only fallback to PEM parser if a format error occurred. */
if (r != SSH_ERR_INVALID_FORMAT)
return r;
#ifdef WITH_OPENSSL
return sshkey_parse_private_pem_fileblob(blob, type,
passphrase, keyp);
#else
return SSH_ERR_INVALID_FORMAT;
#endif /* WITH_OPENSSL */
}
}
int
sshkey_parse_private_fileblob(struct sshbuf *buffer, const char *passphrase,
struct sshkey **keyp, char **commentp)
{
if (keyp != NULL)
*keyp = NULL;
if (commentp != NULL)
*commentp = NULL;
return sshkey_parse_private_fileblob_type(buffer, KEY_UNSPEC,
passphrase, keyp, commentp);
}
void
sshkey_sig_details_free(struct sshkey_sig_details *details)
{
freezero(details, sizeof(*details));
}
int
sshkey_parse_pubkey_from_private_fileblob_type(struct sshbuf *blob, int type,
struct sshkey **pubkeyp)
{
int r = SSH_ERR_INTERNAL_ERROR;
if (pubkeyp != NULL)
*pubkeyp = NULL;
/* only new-format private keys bundle a public key inside */
if ((r = sshkey_parse_private2_pubkey(blob, type, pubkeyp)) != 0)
return r;
return 0;
}
#ifdef WITH_XMSS
/*
* serialize the key with the current state and forward the state
* maxsign times.
*/
int
sshkey_private_serialize_maxsign(struct sshkey *k, struct sshbuf *b,
u_int32_t maxsign, int printerror)
{
int r, rupdate;
if (maxsign == 0 ||
sshkey_type_plain(k->type) != KEY_XMSS)
return sshkey_private_serialize_opt(k, b,
SSHKEY_SERIALIZE_DEFAULT);
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, printerror)) != 0) {
if (r == 0)
r = rupdate;
}
return r;
}
u_int32_t
sshkey_signatures_left(const struct sshkey *k)
{
if (sshkey_type_plain(k->type) == KEY_XMSS)
return sshkey_xmss_signatures_left(k);
return 0;
}
int
sshkey_enable_maxsign(struct sshkey *k, u_int32_t maxsign)
{
if (sshkey_type_plain(k->type) != KEY_XMSS)
return SSH_ERR_INVALID_ARGUMENT;
return sshkey_xmss_enable_maxsign(k, maxsign);
}
int
sshkey_set_filename(struct sshkey *k, const char *filename)
{
if (k == NULL)
return SSH_ERR_INVALID_ARGUMENT;
if (sshkey_type_plain(k->type) != KEY_XMSS)
return 0;
if (filename == NULL)
return SSH_ERR_INVALID_ARGUMENT;
if ((k->xmss_filename = strdup(filename)) == NULL)
return SSH_ERR_ALLOC_FAIL;
return 0;
}
#else
int
sshkey_private_serialize_maxsign(struct sshkey *k, struct sshbuf *b,
u_int32_t maxsign, int printerror)
{
return sshkey_private_serialize_opt(k, b, SSHKEY_SERIALIZE_DEFAULT);
}
u_int32_t
sshkey_signatures_left(const struct sshkey *k)
{
return 0;
}
int
sshkey_enable_maxsign(struct sshkey *k, u_int32_t maxsign)
{
return SSH_ERR_INVALID_ARGUMENT;
}
int
sshkey_set_filename(struct sshkey *k, const char *filename)
{
if (k == NULL)
return SSH_ERR_INVALID_ARGUMENT;
return 0;
}
#endif /* WITH_XMSS */
diff --git a/crypto/openssh/sshkey.h b/crypto/openssh/sshkey.h
index be254e6be9dc..771c4bceeae2 100644
--- a/crypto/openssh/sshkey.h
+++ b/crypto/openssh/sshkey.h
@@ -1,339 +1,351 @@
-/* $OpenBSD: sshkey.h,v 1.52 2022/09/17 10:30:45 djm Exp $ */
+/* $OpenBSD: sshkey.h,v 1.61 2022/10/28 00:44:44 djm Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SSHKEY_H
#define SSHKEY_H
#include <sys/types.h>
#ifdef WITH_OPENSSL
#include <openssl/rsa.h>
#include <openssl/dsa.h>
# ifdef OPENSSL_HAS_ECC
# include <openssl/ec.h>
# include <openssl/ecdsa.h>
# else /* OPENSSL_HAS_ECC */
# define EC_KEY void
# define EC_GROUP void
# define EC_POINT void
# endif /* OPENSSL_HAS_ECC */
#define SSH_OPENSSL_VERSION OpenSSL_version(OPENSSL_VERSION)
#else /* WITH_OPENSSL */
# define BIGNUM void
# define RSA void
# define DSA void
# 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
#define SSH_KEY_MAX_SIGN_DATA_SIZE (1 << 20)
struct sshbuf;
/* Key types */
enum sshkey_types {
KEY_RSA,
KEY_DSA,
KEY_ECDSA,
KEY_ED25519,
KEY_RSA_CERT,
KEY_DSA_CERT,
KEY_ECDSA_CERT,
KEY_ED25519_CERT,
KEY_XMSS,
KEY_XMSS_CERT,
KEY_ECDSA_SK,
KEY_ECDSA_SK_CERT,
KEY_ED25519_SK,
KEY_ED25519_SK_CERT,
KEY_UNSPEC
};
/* Default fingerprint hash */
#define SSH_FP_HASH_DEFAULT SSH_DIGEST_SHA256
/* Fingerprint representation formats */
enum sshkey_fp_rep {
SSH_FP_DEFAULT = 0,
SSH_FP_HEX,
SSH_FP_BASE64,
SSH_FP_BUBBLEBABBLE,
SSH_FP_RANDOMART
};
/* Private key serialisation formats, used on the wire */
enum sshkey_serialize_rep {
SSHKEY_SERIALIZE_DEFAULT = 0,
SSHKEY_SERIALIZE_STATE = 1, /* only state is serialized */
SSHKEY_SERIALIZE_FULL = 2, /* include keys for saving to disk */
SSHKEY_SERIALIZE_SHIELD = 3, /* everything, for encrypting in ram */
SSHKEY_SERIALIZE_INFO = 254, /* minimal information */
};
/* Private key disk formats */
enum sshkey_private_format {
SSHKEY_PRIVATE_OPENSSH = 0,
SSHKEY_PRIVATE_PEM = 1,
SSHKEY_PRIVATE_PKCS8 = 2,
};
/* key is stored in external hardware */
#define SSHKEY_FLAG_EXT 0x0001
#define SSHKEY_CERT_MAX_PRINCIPALS 256
/* XXX opaquify? */
struct sshkey_cert {
struct sshbuf *certblob; /* Kept around for use on wire */
u_int type; /* SSH2_CERT_TYPE_USER or SSH2_CERT_TYPE_HOST */
u_int64_t serial;
char *key_id;
u_int nprincipals;
char **principals;
u_int64_t valid_after, valid_before;
struct sshbuf *critical;
struct sshbuf *extensions;
struct sshkey *signature_key;
char *signature_type;
};
/* XXX opaquify? */
struct sshkey {
int type;
int flags;
/* KEY_RSA */
RSA *rsa;
/* KEY_DSA */
DSA *dsa;
/* KEY_ECDSA and KEY_ECDSA_SK */
int ecdsa_nid; /* NID of curve */
EC_KEY *ecdsa;
/* KEY_ED25519 and KEY_ED25519_SK */
u_char *ed25519_sk;
u_char *ed25519_pk;
/* KEY_XMSS */
char *xmss_name;
char *xmss_filename; /* for state file updates */
void *xmss_state; /* depends on xmss_name, opaque */
u_char *xmss_sk;
u_char *xmss_pk;
/* KEY_ECDSA_SK and KEY_ED25519_SK */
char *sk_application;
uint8_t sk_flags;
struct sshbuf *sk_key_handle;
struct sshbuf *sk_reserved;
/* Certificates */
struct sshkey_cert *cert;
/* Private key shielding */
u_char *shielded_private;
size_t shielded_len;
u_char *shield_prekey;
size_t shield_prekey_len;
};
#define ED25519_SK_SZ crypto_sign_ed25519_SECRETKEYBYTES
#define ED25519_PK_SZ crypto_sign_ed25519_PUBLICKEYBYTES
/* Additional fields contained in signature */
struct sshkey_sig_details {
uint32_t sk_counter; /* U2F signature counter */
uint8_t sk_flags; /* U2F signature flags; see ssh-sk.h */
};
+struct sshkey_impl_funcs {
+ u_int (*size)(const struct sshkey *); /* optional */
+ int (*alloc)(struct sshkey *); /* optional */
+ void (*cleanup)(struct sshkey *); /* optional */
+ int (*equal)(const struct sshkey *, const struct sshkey *);
+ int (*serialize_public)(const struct sshkey *, struct sshbuf *,
+ enum sshkey_serialize_rep);
+ int (*deserialize_public)(const char *, struct sshbuf *,
+ struct sshkey *);
+ int (*serialize_private)(const struct sshkey *, struct sshbuf *,
+ enum sshkey_serialize_rep);
+ int (*deserialize_private)(const char *, struct sshbuf *,
+ struct sshkey *);
+ int (*generate)(struct sshkey *, int); /* optional */
+ int (*copy_public)(const struct sshkey *, struct sshkey *);
+ int (*sign)(struct sshkey *, u_char **, size_t *,
+ const u_char *, size_t, const char *,
+ const char *, const char *, u_int); /* optional */
+ int (*verify)(const struct sshkey *, const u_char *, size_t,
+ const u_char *, size_t, const char *, u_int,
+ struct sshkey_sig_details **);
+};
+
+struct sshkey_impl {
+ const char *name;
+ const char *shortname;
+ const char *sigalg;
+ int type;
+ int nid;
+ int cert;
+ int sigonly;
+ int keybits;
+ const struct sshkey_impl_funcs *funcs;
+};
+
struct sshkey *sshkey_new(int);
void sshkey_free(struct sshkey *);
int sshkey_equal_public(const struct sshkey *,
const struct sshkey *);
int sshkey_equal(const struct sshkey *, const struct sshkey *);
char *sshkey_fingerprint(const struct sshkey *,
int, enum sshkey_fp_rep);
int sshkey_fingerprint_raw(const struct sshkey *k,
int, u_char **retp, size_t *lenp);
const char *sshkey_type(const struct sshkey *);
const char *sshkey_cert_type(const struct sshkey *);
int sshkey_format_text(const struct sshkey *, struct sshbuf *);
int sshkey_write(const struct sshkey *, FILE *);
int sshkey_read(struct sshkey *, char **);
u_int sshkey_size(const struct sshkey *);
int sshkey_generate(int type, u_int bits, struct sshkey **keyp);
int sshkey_from_private(const struct sshkey *, struct sshkey **);
int sshkey_is_shielded(struct sshkey *);
int sshkey_shield_private(struct sshkey *);
int sshkey_unshield_private(struct sshkey *);
int sshkey_type_from_name(const char *);
int sshkey_is_cert(const struct sshkey *);
int sshkey_is_sk(const struct sshkey *);
int sshkey_type_is_cert(int);
int sshkey_type_plain(int);
/* Returns non-zero if key name match sigalgs pattern list. (handles RSA) */
int sshkey_match_keyname_to_sigalgs(const char *, const char *);
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,
uint64_t, const char *, const char **);
int sshkey_cert_check_authority_now(const struct sshkey *, int, int, int,
const char *, const char **);
int sshkey_cert_check_host(const struct sshkey *, const char *,
int , const char *, const char **);
size_t sshkey_format_cert_validity(const struct sshkey_cert *,
char *, size_t) __attribute__((__bounded__(__string__, 2, 3)));
int sshkey_check_cert_sigtype(const struct sshkey *, const char *);
int sshkey_certify(struct sshkey *, struct sshkey *,
const char *, const char *, const char *);
/* Variant allowing use of a custom signature function (e.g. for ssh-agent) */
typedef int sshkey_certify_signer(struct sshkey *, u_char **, size_t *,
const u_char *, size_t, const char *, const char *, const char *,
u_int, void *);
int sshkey_certify_custom(struct sshkey *, struct sshkey *, const char *,
const char *, const char *, sshkey_certify_signer *, void *);
int sshkey_ecdsa_nid_from_name(const char *);
int sshkey_curve_name_to_nid(const char *);
const char * sshkey_curve_nid_to_name(int);
u_int sshkey_curve_nid_to_bits(int);
int sshkey_ecdsa_bits_to_nid(int);
int sshkey_ecdsa_key_to_nid(EC_KEY *);
int sshkey_ec_nid_to_hash_alg(int nid);
int sshkey_ec_validate_public(const EC_GROUP *, const EC_POINT *);
int sshkey_ec_validate_private(const EC_KEY *);
const char *sshkey_ssh_name(const struct sshkey *);
const char *sshkey_ssh_name_plain(const struct sshkey *);
int sshkey_names_valid2(const char *, int);
char *sshkey_alg_list(int, int, int, char);
int sshkey_from_blob(const u_char *, size_t, struct sshkey **);
int sshkey_fromb(struct sshbuf *, struct sshkey **);
int sshkey_froms(struct sshbuf *, struct sshkey **);
int sshkey_to_blob(const struct sshkey *, u_char **, size_t *);
int sshkey_to_base64(const struct sshkey *, char **);
int sshkey_putb(const struct sshkey *, struct sshbuf *);
int sshkey_puts(const struct sshkey *, struct sshbuf *);
int sshkey_puts_opts(const struct sshkey *, struct sshbuf *,
enum sshkey_serialize_rep);
int sshkey_plain_to_blob(const struct sshkey *, u_char **, size_t *);
int sshkey_putb_plain(const struct sshkey *, struct sshbuf *);
int sshkey_sign(struct sshkey *, u_char **, size_t *,
const u_char *, size_t, const char *, const char *, const char *, u_int);
int sshkey_verify(const struct sshkey *, const u_char *, size_t,
const u_char *, size_t, const char *, u_int, struct sshkey_sig_details **);
int sshkey_check_sigtype(const u_char *, size_t, const char *);
const char *sshkey_sigalg_by_name(const char *);
int sshkey_get_sigtype(const u_char *, size_t, char **);
/* for debug */
void sshkey_dump_ec_point(const EC_GROUP *, const EC_POINT *);
void sshkey_dump_ec_key(const EC_KEY *);
/* private key parsing and serialisation */
int sshkey_private_serialize(struct sshkey *key, struct sshbuf *buf);
int sshkey_private_serialize_opt(struct sshkey *key, struct sshbuf *buf,
enum sshkey_serialize_rep);
int sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **keyp);
/* private key file format parsing and serialisation */
int sshkey_private_to_fileblob(struct sshkey *key, struct sshbuf *blob,
const char *passphrase, const char *comment,
int format, const char *openssh_format_cipher, int openssh_format_rounds);
int sshkey_parse_private_fileblob(struct sshbuf *buffer,
const char *passphrase, struct sshkey **keyp, char **commentp);
int sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type,
const char *passphrase, struct sshkey **keyp, char **commentp);
int sshkey_parse_pubkey_from_private_fileblob_type(struct sshbuf *blob,
int type, struct sshkey **pubkeyp);
int sshkey_check_rsa_length(const struct sshkey *, int);
/* XXX should be internal, but used by ssh-keygen */
int ssh_rsa_complete_crt_parameters(struct sshkey *, const BIGNUM *);
/* stateful keys (e.g. XMSS) */
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, int);
int sshkey_private_serialize_maxsign(struct sshkey *key,
struct sshbuf *buf, u_int32_t maxsign, int);
void sshkey_sig_details_free(struct sshkey_sig_details *);
#ifdef SSHKEY_INTERNAL
-int ssh_rsa_sign(const struct sshkey *key,
- u_char **sigp, size_t *lenp, const u_char *data, size_t datalen,
- const char *ident);
-int ssh_rsa_verify(const struct sshkey *key,
- const u_char *sig, size_t siglen, const u_char *data, size_t datalen,
- const char *alg);
-int ssh_dss_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
- const u_char *data, size_t datalen, u_int compat);
-int ssh_dss_verify(const struct sshkey *key,
- const u_char *signature, size_t signaturelen,
- const u_char *data, size_t datalen, u_int compat);
-int ssh_ecdsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
- const u_char *data, size_t datalen, u_int compat);
-int ssh_ecdsa_verify(const struct sshkey *key,
- const u_char *signature, size_t signaturelen,
- const u_char *data, size_t datalen, u_int compat);
-int ssh_ecdsa_sk_verify(const struct sshkey *key,
- const u_char *signature, size_t signaturelen,
- const u_char *data, size_t datalen, u_int compat,
- struct sshkey_sig_details **detailsp);
-int ssh_ed25519_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
- const u_char *data, size_t datalen, u_int compat);
-int ssh_ed25519_verify(const struct sshkey *key,
- const u_char *signature, size_t signaturelen,
- const u_char *data, size_t datalen, u_int compat);
-int ssh_ed25519_sk_verify(const struct sshkey *key,
- const u_char *signature, size_t signaturelen,
- const u_char *data, size_t datalen, u_int compat,
- struct sshkey_sig_details **detailsp);
-int ssh_xmss_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
- const u_char *data, size_t datalen, u_int compat);
-int ssh_xmss_verify(const struct sshkey *key,
- const u_char *signature, size_t signaturelen,
- const u_char *data, size_t datalen, u_int compat);
+int sshkey_sk_fields_equal(const struct sshkey *a, const struct sshkey *b);
+void sshkey_sk_cleanup(struct sshkey *k);
+int sshkey_serialize_sk(const struct sshkey *key, struct sshbuf *b);
+int sshkey_copy_public_sk(const struct sshkey *from, struct sshkey *to);
+int sshkey_deserialize_sk(struct sshbuf *b, struct sshkey *key);
+int sshkey_serialize_private_sk(const struct sshkey *key,
+ struct sshbuf *buf);
+int sshkey_private_deserialize_sk(struct sshbuf *buf, struct sshkey *k);
+#ifdef WITH_OPENSSL
+int check_rsa_length(const RSA *rsa); /* XXX remove */
+#endif
#endif
#if !defined(WITH_OPENSSL)
# undef RSA
# undef DSA
# undef EC_KEY
# undef EC_GROUP
# undef EC_POINT
#elif !defined(OPENSSL_HAS_ECC)
# undef EC_KEY
# undef EC_GROUP
# undef EC_POINT
#endif
#endif /* SSHKEY_H */
diff --git a/crypto/openssh/verify.c b/crypto/openssh/verify.c
deleted file mode 100644
index 1671a4132c9e..000000000000
--- a/crypto/openssh/verify.c
+++ /dev/null
@@ -1,49 +0,0 @@
-/* $OpenBSD: verify.c,v 1.3 2013/12/09 11:03:45 markus Exp $ */
-
-/*
- * Public Domain, Author: Daniel J. Bernstein
- * Copied from nacl-20110221/crypto_verify/32/ref/verify.c
- */
-
-#include "includes.h"
-
-#include "crypto_api.h"
-
-int crypto_verify_32(const unsigned char *x,const unsigned char *y)
-{
- unsigned int differentbits = 0;
-#define F(i) differentbits |= x[i] ^ y[i];
- F(0)
- F(1)
- F(2)
- F(3)
- F(4)
- F(5)
- F(6)
- F(7)
- F(8)
- F(9)
- F(10)
- F(11)
- F(12)
- F(13)
- F(14)
- F(15)
- F(16)
- F(17)
- F(18)
- F(19)
- F(20)
- F(21)
- F(22)
- F(23)
- F(24)
- F(25)
- F(26)
- F(27)
- F(28)
- F(29)
- F(30)
- F(31)
- return (1 & ((differentbits - 1) >> 8)) - 1;
-}
diff --git a/crypto/openssh/version.h b/crypto/openssh/version.h
index 71f1aee650e2..1a3fc7bc82e6 100644
--- a/crypto/openssh/version.h
+++ b/crypto/openssh/version.h
@@ -1,8 +1,8 @@
-/* $OpenBSD: version.h,v 1.95 2022/09/26 22:18:40 djm Exp $ */
+/* $OpenBSD: version.h,v 1.96 2023/02/02 12:10:22 djm Exp $ */
-#define SSH_VERSION "OpenSSH_9.1"
+#define SSH_VERSION "OpenSSH_9.2"
#define SSH_PORTABLE "p1"
#define SSH_RELEASE SSH_VERSION SSH_PORTABLE
-#define SSH_VERSION_FREEBSD "FreeBSD-20221019"
+#define SSH_VERSION_FREEBSD "FreeBSD-20230205"
diff --git a/secure/lib/libssh/Makefile b/secure/lib/libssh/Makefile
index ee0cdf6dfa24..2b1a76f185f8 100644
--- a/secure/lib/libssh/Makefile
+++ b/secure/lib/libssh/Makefile
@@ -1,69 +1,69 @@
# $FreeBSD$
.include <src.opts.mk>
.include "${SRCTOP}/secure/ssh.mk"
LIB= ssh
PRIVATELIB= true
SHLIB_MAJOR= 5
SRCS= ssh_api.c ssherr.c \
sshbuf.c sshkey.c sshbuf-getput-basic.c \
sshbuf-misc.c sshbuf-getput-crypto.c krl.c bitmap.c
SRCS+= authfd.c authfile.c \
canohost.c channels.c cipher.c cipher-aes.c cipher-aesctr.c \
cleanup.c \
compat.c fatal.c hostfile.c \
log.c match.c moduli.c nchan.c packet.c \
readpass.c ttymodes.c xmalloc.c addr.c addrmatch.c \
atomicio.c dispatch.c mac.c misc.c utf8.c \
monitor_fdpass.c rijndael.c ssh-dss.c ssh-ecdsa.c ssh-ecdsa-sk.c \
ssh-ed25519-sk.c ssh-rsa.c dh.c \
msg.c progressmeter.c dns.c entropy.c umac.c umac128.c \
ssh-pkcs11.c smult_curve25519_ref.c \
poly1305.c chacha.c cipher-chachapoly.c cipher-chachapoly-libcrypto.c \
ssh-ed25519.c digest-openssl.c digest-libc.c \
- hmac.c sc25519.c ge25519.c fe25519.c ed25519.c verify.c hash.c \
+ hmac.c ed25519.c hash.c \
kex.c kexdh.c kexgex.c kexecdh.c kexc25519.c \
kexgexc.c kexgexs.c \
kexsntrup761x25519.c sntrup761.c kexgen.c \
sftp-realpath.c platform-pledge.c platform-tracing.c platform-misc.c \
sshbuf-io.c
SRCS+= ssh-sk-client.c
PACKAGE= ssh
# gss-genr.c should be in $SRCS but causes linking problems, so it is
# compiled directly into sshd instead.
# Portability layer
SRCS+= bcrypt_pbkdf.c blowfish.c bsd-misc.c bsd-signal.c explicit_bzero.c \
fmt_scaled.c freezero.c glob.c \
libressl-api-compat.c \
openssl-compat.c port-net.c \
recallocarray.c strtonum.c timingsafe_bcmp.c vis.c xcrypt.c
.if ${MK_LDNS} == "no"
SRCS+= getrrsetbyname.c
.else
LDNSDIR= ${SRCTOP}/contrib/ldns
CFLAGS+= -DHAVE_LDNS=1 -I${LDNSDIR}
SRCS+= getrrsetbyname-ldns.c
LIBADD+= ldns
.endif
.if ${MK_GSSAPI} != "no" && ${MK_KERBEROS_SUPPORT} != "no"
CFLAGS+= -include krb5_config.h
SRCS+= krb5_config.h
.endif
.if defined(LOCALBASE)
CFLAGS+= -D_PATH_SSH_ASKPASS_DEFAULT='"${LOCALBASE}/bin/ssh-askpass"'
.endif
NO_LINT=
LIBADD+= crypto crypt z
.include <bsd.lib.mk>
.PATH: ${SSHDIR} ${SSHDIR}/openbsd-compat

File Metadata

Mime Type
application/octet-stream
Expires
Mon, Sep 30, 7:05 PM (2 d)
Storage Engine
chunks
Storage Format
Chunks
Storage Handle
0fU5Hwq.oRo_
Default Alt Text
(5 MB)

Event Timeline