diff --git a/.depend b/.depend index 45fc6b9..660f515 100644 --- a/.depend +++ b/.depend @@ -26,8 +26,8 @@ auth2-kbdint.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd- auth2-methods.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-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 xmalloc.h hostfile.h auth.h auth-pam.h audit.h loginrec.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 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-pubkey.o: audit.h loginrec.h pathnames.h uidswap.h auth-options.h canohost.h monitor_wrap.h authfile.h match.h channels.h session.h sk-api.h +auth2-pubkey.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-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 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 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 sshkey.h digest.h hostfile.h auth.h auth-pam.h audit.h loginrec.h auth-options.h authfile.h match.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 sshkey.h hostfile.h auth.h auth-pam.h audit.h loginrec.h pathnames.h monitor_wrap.h digest.h kex.h auth2.o: mac.h crypto_api.h @@ -79,6 +79,7 @@ loginrec.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-comp 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-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 digest.h log.h ssherr.h misc.h pathnames.h ssh.h xmalloc.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 srclimit.h @@ -99,24 +100,22 @@ platform.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-comp 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 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 uidswap.h -readconf.o: myproposal.h digest.h +readconf.o: myproposal.h digest.h version.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 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 pathnames.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h sshkey.h kex.h -servconf.o: mac.h crypto_api.h match.h channels.h groupaccess.h canohost.h packet.h dispatch.h hostfile.h auth.h auth-pam.h audit.h loginrec.h myproposal.h digest.h +servconf.o: 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 version.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 ssh2.h sshkey.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h serverloop.o: rijndael.h kex.h mac.h crypto_api.h hostfile.h auth.h auth-pam.h audit.h loginrec.h session.h auth-options.h serverloop.h -session.o: 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 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 channels.h sshkey.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h +session.o: kex.h mac.h crypto_api.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 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 @@ -130,24 +129,22 @@ sntrup761.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-com 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 ./openbsd-compat/sys-tree.h addr.h canohost.h log.h ssherr.h misc.h srclimit.h xmalloc.h servconf.h openbsd-compat/sys-queue.h match.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 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-keygen.o: 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 atomicio.h krl.h digest.h utf8.h authfd.h sshsig.h ssh-sk.h sk-api.h cipher.h cipher-chachapoly.h ssh-keyscan.o: dispatch.h log.h ssherr.h atomicio.h misc.h hostfile.h ssh_api.h ssh2.h dns.h addr.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 digest.h kex.h mac.h crypto_api.h compat.h myproposal.h packet.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-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 pathnames.h xmalloc.h sshbuf.h log.h ssherr.h misc.h sshkey.h authfd.h atomicio.h ssh-pkcs11.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 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-pkcs11.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-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-pkcs11.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 dh.h misc.h version.h myproposal.h sshbuf.h openbsd-compat/openssl-compat.h @@ -161,13 +158,14 @@ 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 sshkey.h sshconnect.h log.h ssherr.h match.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: 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-session.o: chacha.h poly1305.h cipher-aesctr.h rijndael.h digest.h sshkey.h kex.h mac.h crypto_api.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 +sshd-auth.o: chacha.h poly1305.h cipher-aesctr.h rijndael.h digest.h sshkey.h kex.h mac.h crypto_api.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 auth-options.h version.h sk-api.h srclimit.h ssh-sandbox.h dh.h +sshd-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 ./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 +sshd-session.o: chacha.h poly1305.h cipher-aesctr.h rijndael.h digest.h sshkey.h kex.h mac.h crypto_api.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 auth-options.h version.h sk-api.h srclimit.h dh.h sshd-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-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 -sshd.o: audit.h loginrec.h authfd.h msg.h version.h sk-api.h addr.h srclimit.h +sshd.o: audit.h loginrec.h authfd.h msg.h version.h sk-api.h addr.h srclimit.h atomicio.h monitor_wrap.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 sshpty.h log.h ssherr.h sshbuf.h misc.h servconf.h compat.h digest.h sshkey.h authfile.h pathnames.h canohost.h hostfile.h auth.h auth-pam.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 +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 ssh-pkcs11.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 @@ -178,8 +176,3 @@ umac.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.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 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/.git_allowed_signers b/.git_allowed_signers index 2a5fdc6..04fe425 100644 --- a/.git_allowed_signers +++ b/.git_allowed_signers @@ -1,7 +1,11 @@ -dtucker@dtucker.net ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKecyjh9aNmD4rb8WblA8v91JjRb0Cd2JtkzqxcggGeG +dtucker@dtucker.net valid-before="20241206" ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKecyjh9aNmD4rb8WblA8v91JjRb0Cd2JtkzqxcggGeG dtucker@dtucker.net sk-ecdsa-sha2-nistp256@openssh.com AAAAInNrLWVjZHNhLXNoYTItbmlzdHAyNTZAb3BlbnNzaC5jb20AAAAIbmlzdHAyNTYAAABBBDV81zWQ1+XVfWH5z4L4klDQ/z/6l2GLphfSTX/Rmq6kL5H8mkfzUlryxLlkN8cD9srtVJBAmwJWfJBNsCo958YAAAAEc3NoOg== +dtucker@dtucker.net sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIElSYahCw60CGct39Eg9EY8OLV9Ppr7tsudvSiMyNHOhAAAABHNzaDo= djm@mindrot.org sk-ecdsa-sha2-nistp256@openssh.com AAAAInNrLWVjZHNhLXNoYTItbmlzdHAyNTZAb3BlbnNzaC5jb20AAAAIbmlzdHAyNTYAAABBBLnJo3ZVDENYZGXm5uO9lU7b0iDFq5gHpTu1MaHPWTEfPdvw+AjFQQ/q5YizuMJkXGsMdYmblJEJZYHpm9IS7ZkAAAAEc3NoOg== djm@mindrot.org sk-ecdsa-sha2-nistp256@openssh.com AAAAInNrLWVjZHNhLXNoYTItbmlzdHAyNTZAb3BlbnNzaC5jb20AAAAIbmlzdHAyNTYAAABBBJoAXBTQalfg+kC5wy1vE7HkIHtVnmV6AUuuIo9KQ1P+70juHwvsFKpsGaqQbrHJkTVgYDGVP02XHj8+Fb18yBIAAAAEc3NoOg== djm@mindrot.org sk-ecdsa-sha2-nistp256@openssh.com AAAAInNrLWVjZHNhLXNoYTItbmlzdHAyNTZAb3BlbnNzaC5jb20AAAAIbmlzdHAyNTYAAABBBH+z1I48s6ydOhP5SJmI02zVCLf0K15B+UMHgoTIKVfUIv5oDoVX7e9f+7QiRmTeEOdZfQydiaVqsfi7qPSve+0AAAAEc3NoOg== djm@mindrot.org sk-ecdsa-sha2-nistp256@openssh.com AAAAInNrLWVjZHNhLXNoYTItbmlzdHAyNTZAb3BlbnNzaC5jb20AAAAIbmlzdHAyNTYAAABBBPM4BmUg/fMnsl42JwktTekk/mB8Be3M+yK2ayg6lqYsqEri8yhRx84gey51OHKVk1TwlGbJjcMHI4URreDBEMQAAAAEc3NoOg== + +tim@multitalents.net ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIC/L8E1DfiZ9cHzygqx0IzRCSAlmh4tXH7mZPwWZEY1L + diff --git a/.gitignore b/.gitignore index 41d505c..df0f2ce 100644 --- a/.gitignore +++ b/.gitignore @@ -6,12 +6,15 @@ config.log config.status openbsd-compat/Makefile openbsd-compat/regress/Makefile +openbsd-compat/include openssh.xml opensshd.init survey.sh **/*.o **/*.lo **/*.so +**/*.dylib +**/*.dll **/*.out **/*.a **/*.un~ @@ -29,7 +32,9 @@ ssh-keysign ssh-pkcs11-helper ssh-sk-helper sshd -!regress/misc/fuzz-harness/Makefile -!regress/unittests/sshsig/Makefile +sshd-session +sshd-auth +!regress/misc/**/Makefile +!regress/unittests/**/Makefile tags diff --git a/.skipped-commit-ids b/.skipped-commit-ids index ec7831e..138ca3d 100644 --- a/.skipped-commit-ids +++ b/.skipped-commit-ids @@ -1,3 +1,5 @@ +747219d54565030ff7c45298b9f5e971801f6cb2 moduli-gen Makefile tweak +c2eb57285424f819f9520fa33e0d6d3c4a361a5e moduli-gen.sh tweak 509bb19bb9762a4b3b589af98bac2e730541b6d4 clean sshd random relinking kit 5317f294d63a876bfc861e19773b1575f96f027d remove libssh from makefiles a337e886a49f96701ccbc4832bed086a68abfa85 Makefile changes @@ -37,6 +39,13 @@ ef9341d5a50f0d33e3a6fbe995e92964bc7ef2d3 Makefile relinking changes fb39324748824cb0387e9d67c41d1bef945c54ea Makefile change 5f378c38ad8976d507786dc4db9283a879ec8cd0 Makefile change 112aacedd3b61cc5c34b1fa6d9fb759214179172 Makefile change +a959fc45ea3431b36f52eda04faefc58bcde00db groupaccess.c changes +6d07e4606997e36b860621a14dd41975f2902f8f Makefile.inc +c7246a6b519ac390ca550719f91acfdaef1fa0f0 Makefile relink change +ef7ecdb6dd2542f42fa7236d17ac0b144851f0b5 ssh-keygen, fixup'ed into 21682417 +da414a364c25b187fc686da7aacec2c35d29238a ssh-keygen, fixup'ed into 21682417 +a05e13a7e2c0b65bb4b47184fef731243431c6ff Makefile.inc +7e8178786157e863f6ff63c5d55200d7b6b04f9e remove old sandbox files Old upstream tree: diff --git a/ChangeLog b/ChangeLog index 2ef1164..83b4cec 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6764 +1,9440 @@ -commit 6ebc4dd77a479892d5ca0cd2a567a651f70aad82 +commit 2d8a388de215d9959d72bb11f03e07a6eb2e4614 Author: Damien Miller -Date: Tue Feb 18 19:03:42 2025 +1100 +Date: Fri Oct 10 13:37:07 2025 +1100 - openssh-9.9p2 + depend -commit 38df39ecf278a7ab5794fb03c01286f2cfe82c0d -Author: djm@openbsd.org -Date: Tue Feb 18 08:02:48 2025 +0000 +commit 1d2676f4ffae35e2db37a35c385efaf2932cd639 +Author: Damien Miller +Date: Thu Oct 9 14:53:04 2025 +1100 - upstream: Fix cases where error codes were not correctly set - - Reported by the Qualys Security Advisory team. ok markus@ - - OpenBSD-Commit-ID: 7bcd4ffe0fa1e27ff98d451fb9c22f5fae6e610d + update versions -commit 5e07dee272c34e193362fba8eda0e3c453f3c773 +commit ecd65a492bd0ed3a44a1c07428107b2e148bfee4 Author: djm@openbsd.org -Date: Tue Feb 18 08:02:12 2025 +0000 +Date: Wed Oct 8 00:32:52 2025 +0000 - upstream: Don't reply to PING in preauth phase or during KEX + upstream: openssh-10.2 - Reported by the Qualys Security Advisory team. ok markus@ + The only change since 10.1 is the channels.c fix - OpenBSD-Commit-ID: c656ac4abd1504389d1733d85152044b15830217 + OpenBSD-Commit-ID: 5eebeb0db14c694efd4ee96b5f16112e3e5d5ba9 -commit fb071011fb843142282b8b8a69cbb15e9b0b9485 +commit ea9af2921cb6af8e65341531db3a7351917f0a92 Author: djm@openbsd.org -Date: Mon Feb 10 23:00:29 2025 +0000 +Date: Wed Oct 8 21:02:16 2025 +0000 - upstream: fix "Match invalid-user" from incorrectly being activated + upstream: fix crash at exit (visible via ssh-keygen -D) when - in initial configuration pass when no other predicates were present on the - match line + multiple keys loaded. ok markus deraadt dtucker - OpenBSD-Commit-ID: 02703b4bd207fafd03788bc4e7774bf80be6c9a8 + OpenBSD-Commit-ID: baa9763ec69d162108dafd962792ec5610ff45c9 -commit 729a26a978dd39db60d4625bdfb5405baa629e59 +commit e49013576074ccd2d7ae75fb824170c739ce97a1 Author: Damien Miller -Date: Wed Oct 30 14:25:14 2024 +1100 +Date: Thu Oct 9 10:07:40 2025 +1100 - fix uint64_t types; reported by Tom G. Christensen + link ssh-keygen directly against ssh-pkcs11.c + + Matches what OpenBSD does and fixes ssh-keygen regression in + certifying keys using a CA key hosted via ssh-agent (bz3877) -commit 33c5f384ae03a5d1a0bd46ca0fac3c62e4eaf784 +commit 684f2ceff8c0eeb775e8653cf32609f8fbfe07b1 Author: Damien Miller -Date: Sun Oct 27 13:28:11 2024 +1100 +Date: Thu Oct 9 13:10:27 2025 +1100 - htole64() etc for systems without endian.h - -commit fe8d28a7ebbaa35cfc04a21263627f05c237e460 -Author: djm@openbsd.org -Date: Sun Oct 27 02:06:59 2024 +0000 - - upstream: explicitly include endian.h + some fixes to p11_setup - OpenBSD-Commit-ID: 13511fdef7535bdbc35b644c90090013da43a318 + 1. Use the ssh-keygen under test and not the one in $PATH + 2. Include a test PKCS#11 operation to ensure that the P11 stack is + working correctly. + + Previously, it was possible for p11_setup to return success on + configurations with PKCS#11 support disabled. -commit 11f348196b3fb51c3d8d1f4f36db9d73f03149ed -Author: djm@openbsd.org -Date: Sun Oct 27 02:06:01 2024 +0000 +commit af17ae64a5cfee42334883d2802f40f779131740 +Author: Damien Miller +Date: Thu Oct 9 13:12:15 2025 +1100 - upstream: fix ML-KEM768x25519 KEX on big-endian systems; spotted by + complete PKCS#11 stubs and move to ssh-pkcs11.c - jsg@ feedback/ok deraadt@ - - OpenBSD-Commit-ID: 26d81a430811672bc762687166986cad40d28cc0 + Should unbreak --disable-pkcs11 builds -commit 19bcb2d90c6caf14abf386b644fb24eb7afab889 -Author: djm@openbsd.org -Date: Thu Sep 26 23:55:08 2024 +0000 +commit bcf7c05a473f92a35f4f3b561fd7a1e339e0a30f +Author: Darren Tucker +Date: Wed Oct 8 11:26:52 2025 +1100 - upstream: fix previous change to ssh_config Match, which broken on - - negated Matches; spotted by phessler@ ok deraadt@ + Fix header name and move return outside of ifdef. - OpenBSD-Commit-ID: b1c6acec66cd5bd1252feff1d02ad7129ced37c7 + Fixes from Mike Frysinger via Github PR#597. -commit 66878e12a207fa9746dee3e2bdcca29b704cf035 -Author: djm@openbsd.org -Date: Wed Sep 25 01:24:04 2024 +0000 +commit b937061fe4922caced7b91442b3233c0bd763492 +Author: Darren Tucker +Date: Tue Oct 7 21:10:33 2025 +1100 - upstream: fix regression introduced when I switched the "Match" - - criteria tokeniser to a more shell-like one. Apparently the old tokeniser - (accidentally?) allowed "Match criteria=argument" as well as the "Match - criteria argument" syntax that we tested for. - - People were using this syntax so this adds back support for - "Match criteria=argument" - - bz3739 ok dtucker - - OpenBSD-Commit-ID: d1eebedb8c902002b75b75debfe1eeea1801f58a + Check HAVE_MMAP too now that configure sets it. -commit ff2cd1dd5711ff88efdf26662d6189d980439a1f -Author: Damien Miller -Date: Wed Sep 25 11:15:45 2024 +1000 +commit 8d57083c062f03098c9f767ec8d6278dc549a2f6 +Author: Darren Tucker +Date: Tue Oct 7 21:07:05 2025 +1100 - gss-serv.c needs sys/param.h + Use calloc for sshkeys if mmap is not supported. - From Void Linux + Based on Github PR#597 from Mike Frysinger, any bugs added by me. -commit 2c12ae8cf9b0b7549ae097c4123abeda0ee63e5b -Author: Damien Miller -Date: Wed Sep 25 11:13:05 2024 +1000 +commit c97b931bffa481c72ff4bfddd9d59a2110899289 +Author: Darren Tucker +Date: Tue Oct 7 20:25:07 2025 +1100 - build construct_utmp() when USE_BTMP is set + Add fcntl.h to includes. - Fixes compile error on Void Linux/Musl + From FreeBSD via bz#3874: "This was previously included due to nested + includes in Heimdal's headers. Without this, the build fails with an + error due to redefining AT_FDCWD." -commit c7fda601186ff28128cfe3eab9c9c0622de096e1 -Author: Christoph Ostarek -Date: Wed Jul 3 12:46:59 2024 +0200 +commit 8aa13832315e52c4404c993a59c6139b44ac6114 +Author: Daan De Meyer +Date: Mon Mar 20 20:22:14 2023 +0100 - fix utmpx ifdef + Only set PAM_RHOST if the remote host is not "UNKNOWN" - 02e16ad95fb1f56ab004b01a10aab89f7103c55d did a copy-paste for - utmpx, but forgot to change the ifdef appropriately + When using sshd's -i option with stdio that is not a AF_INET/AF_INET6 + socket, auth_get_canonical_hostname() returns "UNKNOWN" which is then + set as the value of PAM_RHOST, causing pam to try to do a reverse DNS + query of "UNKNOWN", which times out multiple times, causing a + substantial slowdown when logging in. + + To fix this, let's only set PAM_RHOST if the hostname is not "UNKNOWN". -commit 7cf4dc414de689c467e58e49fb83f6609c3ed36b +commit 0bd6649ea80ead0cd6404dbc25b64937421b556e Author: Darren Tucker -Date: Mon Sep 23 20:54:26 2024 +1000 +Date: Tue Oct 7 20:10:56 2025 +1100 - Remove non-9.9 branch statuses. + Don't copy native host keys for hostbased test. + + Some github runners (notably macos-14) seem to have host keys where + public and private do not match, so generate our own keys for testing + purposes. -commit 8513f4d30ae85d17b3b08da6bc3be76f8c73123c +commit 33b63718d40ccc555b8c7a24331a3790b2efc6c5 Author: Darren Tucker -Date: Mon Sep 23 20:52:31 2024 +1000 - - Add 9.9 branch to CI status console. - -commit 53a80baaebda180f46e6e8571f3ff800e1f5c496 -Author: Damien Miller -Date: Fri Sep 20 08:20:48 2024 +1000 +Date: Tue Oct 7 20:10:07 2025 +1100 - autogenerated files for release + Add 10.1 branch to ci-status page. -commit 46d1fb16b20e971b9ac15e86a3d3e350b49c9ad6 -Author: Damien Miller -Date: Fri Sep 20 08:20:13 2024 +1000 +commit 52411f15353257e9ec883fc044b7a56b6fca242d +Author: Darren Tucker +Date: Tue Oct 7 20:04:40 2025 +1100 - update version numbers + Add clock_gettime compat shim. + + This fixes the build on macOS prior to 10.12 Sierra, since it does not + have it. Found and tested by Sevan Janiyan. -commit 0bdca1f218971b38728a0a129f482476baff0968 +commit beae06f56e0d0a66ca535896149d5fb0b2e8a1b4 Author: djm@openbsd.org -Date: Thu Sep 19 22:17:44 2024 +0000 +Date: Tue Oct 7 08:02:32 2025 +0000 - upstream: openssh-9.9 + upstream: don't reuse c->isatty for signalling that the remote channel - OpenBSD-Commit-ID: 303417285f1a73b9cb7a2ae78d3f493bbbe31f98 + has a tty attached as this causes side effects, e.g. in channel_handle_rfd(). + bz3872 + + ok markus@ + + OpenBSD-Commit-ID: 4cd8a9f641498ca6089442e59bad0fd3dcbe85f8 -commit ef2d7f2d3e1b4c9ae71bacf963e76a92ab8be543 +commit 476bab6259d5a6ea0402ec79bc47ed61e2c15e86 Author: Damien Miller -Date: Wed Sep 18 16:03:23 2024 +1000 +Date: Mon Oct 6 12:52:25 2025 +1100 - include openbsd-compat/base64.c license in LICENSE + depend -commit 7ef362b989c8d1f7596f557f22e5924b9c08f0ea +commit af956575eba6bf6b6d6bc817e1aa6ed73a365984 Author: Damien Miller -Date: Wed Sep 18 09:01:23 2024 +1000 +Date: Mon Oct 6 12:51:13 2025 +1100 - conditionally include mman.h in arc4random code + update versions -commit 5fb2b5ad0e748732a27fd8cc16a7ca3c21770806 +commit 2fd0945913a30fbbe7c02503347961df03f28e66 Author: Damien Miller -Date: Tue Sep 17 11:53:24 2024 +1000 +Date: Mon Oct 6 12:48:16 2025 +1100 - fix bug in recently-added sntrup761 fuzzer - - key values need to be static to persist across invocations; - spotted by the Qualys Security Advisory team. + sync ssh-copy-id to upstream version 527be673f4d -commit 0ca128c9ee894f1b0067abd473bfb33171df67f8 +commit 981bb32bc6062fa5d6f11de7ffb732967463bf57 Author: djm@openbsd.org -Date: Mon Sep 16 05:37:05 2024 +0000 +Date: Mon Oct 6 01:45:22 2025 +0000 - upstream: use 64 bit math to avoid signed underflow. upstream code + upstream: openssh-10.1 - relies on using -fwrapv to provide defined over/underflow behaviour, but we - use -ftrapv to catch integer errors and abort the program. ok dtucker@ + OpenBSD-Commit-ID: 2a232c2d2fc05a23519f69bc29e6d8c076b97d97 + +commit b9a640a1a0dccfb56be684cc7ade402f57cf7ebd +Author: dtucker@openbsd.org +Date: Fri Oct 3 01:03:45 2025 +0000 + + upstream: If write() returned short, the subsequent write would restart - OpenBSD-Commit-ID: 8933369b33c17b5f02479503d0a92d87bc3a574b + from the beginning of the buffer not the end of what was written. Fix, since + we want modpipe to corrupt data for testing purposes deliberately not + accidentally. ok djm@ + + OpenBSD-Regress-ID: 50ca74d287445c58944f070bb92dc13b1d054b43 -commit f82e5e22cad88c81d8a117de74241328c7b101c3 -Author: jmc@openbsd.org -Date: Sun Sep 15 08:27:38 2024 +0000 +commit a0e5446ac85aca5a3ef9844eeedf787300fdb8b3 +Author: naddy@openbsd.org +Date: Sat Oct 4 21:41:35 2025 +0000 - upstream: minor grammar/sort fixes for refuseconnection; ok djm + upstream: typos: a ssh* -> an ssh* - OpenBSD-Commit-ID: 1c81f37b138b8b66abba811fec836388a0f3e6da + ok dtucker@ + + OpenBSD-Commit-ID: a70fd2e1b23089260e8f5a7921b0debc06b011cb -commit 0c1165fc78e8fe69b5df71f81a8f944554a68b53 -Author: Damien Miller -Date: Sun Sep 15 13:30:13 2024 +1000 +commit ade92f53c3bd4ad7dcd95334a194add57ec9ff71 +Author: djm@openbsd.org +Date: Fri Oct 3 00:09:26 2025 +0000 - avoid gcc warning in fuzz test + upstream: stray newline + + OpenBSD-Commit-ID: b47ed4fa93b781c7ec8ae2936526a290f4e17e1f -commit ce171d0718104b643854b53443ff72f7283d33f2 +commit a9cbe10da2be5be76755af0cea029db0f9c1f263 Author: djm@openbsd.org -Date: Sun Sep 15 03:09:44 2024 +0000 +Date: Fri Oct 3 00:08:02 2025 +0000 - upstream: bad whitespace in config dump output + upstream: include openssl/bn.h explicitly in files where we use BN_* - OpenBSD-Commit-ID: d899c13b0e8061d209298eaf58fe53e3643e967c + makes things simpler for portable; from Mike Frysinger + + OpenBSD-Commit-ID: 717e93403fd1108e175afd7451b5a4ab46a598fe -commit 671c440786a5a66216922f15d0007b60f1e6733f -Author: Damien Miller -Date: Sun Sep 15 12:53:59 2024 +1000 +commit 3957cc2914cdc88932c972413853f8b68c1ffba5 +Author: dtucker@openbsd.org +Date: Thu Oct 2 08:38:43 2025 +0000 - use construct_utmp to construct btmp records + upstream: Relax array check slightly. Prevents compiler warnings - Simpler and removes some code with the old-style BSD license. + in -portable when there are no kbdint devices present. ok djm@ + + OpenBSD-Commit-ID: c1c050cecd642d6073c792201908fd225191df93 -commit 930cb02b6113df72fbc732b9feb8e4f490952a81 +commit 6a239b057be2897d7a597daaf5394f2e7312dc65 Author: djm@openbsd.org -Date: Sun Sep 15 02:20:51 2024 +0000 +Date: Thu Oct 2 04:23:11 2025 +0000 - upstream: update the Streamlined NTRU Prime code from the "ref" + upstream: backout r1.243 (fix for fatal during tab-completion with - implementation in SUPERCOP 20201130 to the "compact" implementation in - SUPERCOP 20240808. The new version is substantially faster. Thanks to Daniel - J Bernstein for pointing out the new implementation (and of course for - writing it). + some multibyte sequences) as it breaks the common case for tab completion. - tested in snaps/ok deraadt@ + Will deal with it properly after release. - OpenBSD-Commit-ID: bf1a77924c125ecdbf03e2f3df8ad13bd3dafdcb + OpenBSD-Commit-ID: 196d00f5ff19579214de45357f16a1fb2d624be1 -commit 9306d6017e0ce5dea6824c29ca5ba5673c2923ad -Author: djm@openbsd.org -Date: Sun Sep 15 01:19:56 2024 +0000 +commit b9f6a84ea383d811216de38219472214963c10b2 +Author: Darren Tucker +Date: Thu Oct 2 10:48:04 2025 +1000 - upstream: document Match invalid-user + Pass COMPATINCLUDES down to openbsd-compat too. - OpenBSD-Commit-ID: 2c84a9b517283e9711e2812c1f268081dcb02081 + Fixes build on Solaris, AIX and probably others. -commit 0118a4da21147a88a56dc8b90bbc2849fefd5c1e -Author: djm@openbsd.org -Date: Sun Sep 15 01:18:26 2024 +0000 +commit 047e0221eaf9815775e8ea78c6d6add5ab0f68c7 +Author: Darren Tucker +Date: Wed Oct 1 14:34:02 2025 +1000 - upstream: add a "Match invalid-user" predicate to sshd_config Match - - options. + Pass new "compat includes" path via AC_SUBST. - This allows writing Match conditions that trigger for invalid username. - E.g. + This fixes the build when the directory path containing a space. + Found by Sevan Janiyan, tested by Job Snijders. This doesn't fix + "make tests", however that is a different, pre-existing problem + that needs to be addressed separately. + +commit 5c50ddbe4deac83995edc1d014e9ba0d5efa18a6 +Author: Darren Tucker +Date: Wed Oct 1 13:37:35 2025 +1000 + + Remove compat "include" dir during distclean. + +commit aceabd62ce5833716dd2e99d4be4fcb603d263cc +Author: dtucker@openbsd.org +Date: Wed Oct 1 00:33:37 2025 +0000 + + upstream: Set keys to NULL after freeing in tests where the - PerSourcePenalties refuseconnection:90s - Match invalid-user - RefuseConnection yes + variables will be used again. Should prevent Coverity "potential use after + free" warnings. - Will effectively penalise bots try to guess passwords for bogus accounts, - at the cost of implicitly revealing which accounts are invalid. + OpenBSD-Regress-ID: 24d141657d25977e41dfb0c58e9b74ab093972bf + +commit eb30a0d1493a97b5c14728846576dc6af5d442da +Author: dtucker@openbsd.org +Date: Wed Oct 1 00:30:19 2025 +0000 + + upstream: Get rid of utf8 droppings in commment since it confuses - feedback markus@ + older shells. From Sevan Janiyan via openssh-unix-dev. - OpenBSD-Commit-ID: 93d3a46ca04bbd9d84a94d1e1d9d3a21073fbb07 + OpenBSD-Regress-ID: 67c11a5cff6ef23538c77e9b29d538e175e6cfe3 -commit 7875975136f275619427604900cb0ffd7020e845 +commit d478e250230e917eeb5032238df0b9af357404ee +Author: Darren Tucker +Date: Wed Oct 1 12:17:54 2025 +1000 + + Update OpenSSL & LibreSSL versions we test against. + +commit 2c504a74ed81d13c8198a89ed1040d0fc5f73129 Author: djm@openbsd.org -Date: Sun Sep 15 01:11:26 2024 +0000 +Date: Tue Sep 30 00:10:42 2025 +0000 - upstream: Add a "refuseconnection" penalty class to sshd_config + upstream: during sftp uploads, avoid a condition where a failed write - PerSourcePenalties + could be ignored if a subsequent write succeeded. - This allows penalising connection sources that have had connections - dropped by the RefuseConnection option. ok markus@ + This is unlikely but technically possible because sftp servers are + allowed to reorder requests. - OpenBSD-Commit-ID: 3c8443c427470bb3eac1880aa075cb4864463cb6 + Reported by Graziano Stefani, ok tb@ + + OpenBSD-Commit-ID: 03904bce2c7f787223d01d7e1179fde15753eca3 -commit 8d21713b669b8516ca6d43424a356fccc37212bb +commit 1f7556753869654ba5e2bf61e384c5da2db5ca6a Author: djm@openbsd.org -Date: Sun Sep 15 01:09:40 2024 +0000 +Date: Tue Sep 30 00:06:06 2025 +0000 - upstream: Add a sshd_config "RefuseConnection" option + upstream: avoid a fatal() when sftp tab-completes filenames that - If set, this will terminate the connection at the first authentication - request (this is the earliest we can evaluate sshd_config Match blocks) + share common utf-8 characters that don't encode to a complete codepoint - ok markus@ + from menthu.zhou via GHPR#587; ok dtucker@ - OpenBSD-Commit-ID: 43cc2533984074c44d0d2f92eb93f661e7a0b09c + OpenBSD-Commit-ID: e07e4d8a8cac032ab536570b8214e6ef6839b585 -commit acad117e66018fe1fa5caf41b36e6dfbd61f76a1 +commit 42b14ff1e06fd683c7d15a6b2816c16108873a5a Author: djm@openbsd.org -Date: Sun Sep 15 00:58:01 2024 +0000 +Date: Tue Sep 30 00:03:09 2025 +0000 - upstream: switch sshd_config Match processing to the argv tokeniser + upstream: fix memory leak in mux_client_request_stdio_fwd GHPR#575 - too; ok markus@ + by Boris Tonofa; ok dtucker - OpenBSD-Commit-ID: b74b5b0385f2e0379670e2b869318a65b0bc3923 + OpenBSD-Commit-ID: 410cdd05242304bd0196b9172ce5fcaf89d2d8ce -commit baec3f7f4c60cd5aa1bb9adbeb6dfa4a172502a8 -Author: djm@openbsd.org -Date: Sun Sep 15 00:57:36 2024 +0000 +commit e5055ef26abcffd3f99669e411ea6b35ca166111 +Author: Allison Karlitskaya +Date: Wed Sep 3 20:07:55 2025 +0200 - upstream: switch "Match" directive processing over to the argv + Don't log audit messages with UNKNOWN hostname - string tokeniser, making it possible to use shell-like quoting in Match - directives, particularly "Match exec". ok markus@ + The `host` parameter to audit_log_acct_message() is documented as + follows: - OpenBSD-Commit-ID: 0877309650b76f624b2194c35dbacaf065e769a5 + host - The hostname if known. If not available pass a NULL. + + but we pass the string "UNKNOWN" in case we don't know the hostname. + Make sure we pass NULL instead. + + This avoids having the audit system attempt to perform a DNS lookup on + the hostname "UNKNOWN", which tends to result in long delays when + attempting to login. -commit dd424d7c382c2074ab70f1b8ad4f169a10f60ee7 -Author: djm@openbsd.org -Date: Sun Sep 15 00:47:01 2024 +0000 +commit d343df4019b4369ce7f87e9bf6bbc80b81cd263d +Author: zhangjun +Date: Fri Aug 22 16:49:07 2025 +0800 - upstream: include pathname in some of the ssh-keygen passphrase - - prompts. Helps the user know what's going on when ssh-keygen is invoked via - other tools. Requested in GHPR503 + ensure struct passwd fields are non-NULL in pwcopy - OpenBSD-Commit-ID: 613b0bb6cf845b7e787d69a5b314057ceda6a8b6 + Android libc can return NULL pw_gecos, for example. -commit 62bbf8f825cc390ecb0523752ddac1435006f206 -Author: djm@openbsd.org -Date: Sun Sep 15 00:41:18 2024 +0000 +commit 893a579e4b37e6bd89d206dc8e7ac2a906ccf114 +Author: dtucker@openbsd.org +Date: Mon Sep 29 21:37:52 2025 +0000 - upstream: Do not apply authorized_keys options when signature + upstream: Add explicit check for array overflow. - verification fails. Prevents restrictive key options being incorrectly - applied to subsequent keys in authorized_keys. bz3733, ok markus@ + The array is bounded by a NULL sentinel which already prevents this, + however since we check the bit vector for overflow Coverity assumes that + check is for the devices array and flags it as a potential overflow. + Adding this additional check on the array placates CID 896018. ok djm@ + deraadt@ - OpenBSD-Commit-ID: ba3776d9da4642443c19dbc015a1333622eb5a4e + OpenBSD-Commit-ID: e92fff41341b38e4206a70655cc9acaaa032ebee -commit 49f325fd47af4e53fcd7aafdbcc280e53f5aa5ce -Author: Wu Weixin -Date: Fri Aug 2 22:16:40 2024 +0800 +commit 90f49a185ac1a786d9f7e9a710b369afb3692a65 +Author: dtucker@openbsd.org +Date: Mon Sep 29 21:30:15 2025 +0000 - Fix without_openssl always being set to 1 + upstream: Move ifdef to start of file. Removes diff vs portable. - In Fedora systems, %{?rhel} is empty. In RHEL systems, %{?fedora} is - empty. Therefore, the original code always sets without_openssl to 1. + OpenBSD-Commit-ID: 55058ac3d477e4c696575039f5b275522b99ffea -commit c21c3a2419bbc1c59cb1a16ea356e703e99a90d9 -Author: djm@openbsd.org -Date: Thu Sep 12 00:36:27 2024 +0000 +commit 2f71b44d48dc8da7fb743d6ffe609aea5a645edb +Author: dtucker@openbsd.org +Date: Mon Sep 29 21:29:22 2025 +0000 - upstream: Relax absolute path requirement back to what it was prior to - - OpenSSH 9.8, which incorrectly required that sshd was started with an - absolute path in inetd mode. bz3717, patch from Colin Wilson + upstream: Include misc.h. Removes diff vs portable. - OpenBSD-Commit-ID: 25c57f22764897242d942853f8cccc5e991ea058 + OpenBSD-Commit-ID: 8aa48451fe5c37f04a339450c4ed9cfb8f4c288f -commit 1bc426f51b0a5cfdcfbd205218f0b6839ffe91e9 -Author: naddy@openbsd.org -Date: Mon Sep 9 14:41:21 2024 +0000 +commit dfb991bdd826517bbce1cf62ce07bcb3e48a2f27 +Author: dtucker@openbsd.org +Date: Mon Sep 29 21:28:33 2025 +0000 - upstream: document the mlkem768x25519-sha256 key exchange algorithm + upstream: Sort headers as per KNF. Removes diff vs portable. - OpenBSD-Commit-ID: fa18dccdd9753dd287e62ecab189b3de45672521 + OpenBSD-Commit-ID: 55f5b9eaeb826a25cfb506a78136094275a71bcb -commit 0a2db61a5ffc64d2e2961c52964f933879952fc7 -Author: Darren Tucker -Date: Tue Sep 10 21:11:14 2024 +1000 +commit c82f4dd6b723a8365b4c538d7c99fe8e46985ed0 +Author: dtucker@openbsd.org +Date: Mon Sep 29 07:40:55 2025 +0000 - Spell omnios test host correctly. + upstream: Null out keys after freeing in tests in the case where we + + potentially reuse the variable. Fixes Coverity CID 405057. + + OpenBSD-Regress-ID: c52e86502b33bfa6e448448a74a0217dd519dd58 -commit 059ed698a47c9af541a49cf754fd09f984ac5a21 -Author: Darren Tucker -Date: Tue Sep 10 18:52:02 2024 +1000 +commit fda31e1e5179b4e70c27094ebb303ee47c11a5a7 +Author: djm@openbsd.org +Date: Mon Sep 29 03:17:54 2025 +0000 - Add omnios test target. + upstream: avoid spurious error message when loading certificates + + only bz3869 + + OpenBSD-Commit-ID: e7848fec50d15cc142fed946aa8f79abef3c5be7 -commit f4ff91575a448b19176ceaa8fd6843a25f39d572 -Author: Darren Tucker -Date: Tue Sep 10 18:45:55 2024 +1000 +commit bcd88ded2fff97652d4236405a3354ca66f90f7e +Author: djm@openbsd.org +Date: Mon Sep 29 02:32:15 2025 +0000 - Wrap stdint.h in ifdef. + upstream: kbd-interactive device names should be matched against + + the full device name, not a prefix. Doesn't matter in practice as there is + only one kbd-int device supported (PAM xor BSD auth), and an attacker would + still need to successfully authenticate against an incorrectly-selected + device. + + reported by ashamedbit, NobleMathews; ok deraadt@ + + OpenBSD-Commit-ID: cf75d4f99405fbb41354c4ae724a3b39a3b58f82 -commit ff714f001d20a9c843ee1fd9d92a16d40567d264 +commit b1c4bf5c2f1c2b30698dbaadc5d823862213f1fc +Author: jsg@openbsd.org +Date: Thu Sep 25 12:52:21 2025 +0000 + + upstream: avoid use-after-free in update_krl_from_file() found with + + clang scan-build, ok dtucker@ + + OpenBSD-Commit-ID: 8ec86eca573740c94d5bc7e252959174555f4eb8 + +commit b06a150bc903a0cf898406384d5a34059d0f2d8f Author: Darren Tucker -Date: Mon Sep 9 19:31:54 2024 +1000 +Date: Sat Sep 27 20:20:34 2025 +1000 - Also test PAM on dfly64. + Stop testing OpenBSD ubsan until fixed upstream. -commit 509b757c052ea969b3a41fc36818b44801caf1cf -Author: Damien Miller -Date: Mon Sep 9 21:50:14 2024 +1000 +commit 97b32fa2af25c16aec4de85c5cbb63fd038b4dfa +Author: dtucker@openbsd.org +Date: Fri Sep 26 04:40:45 2025 +0000 - stubs for ML-KEM KEX functions + upstream: Use $OBJ for temp file in maxstartups idempotence test. - used for C89 compilers + Fixes test in -portable when run out-of-tree. + + OpenBSD-Regress-ID: 8578be08238af4abe2dc91af1c199f7f71f1a7a2 -commit 273581210c99ce7275b8efdefbb9f89e1c22e341 -Author: Damien Miller -Date: Mon Sep 9 17:30:38 2024 +1000 +commit b4ceca952b85752958d849508294afdc56dfcb9f +Author: Darren Tucker +Date: Fri Sep 26 22:28:13 2025 +1000 - declare defeat trying to detect C89 compilers - - I can't find a reliable way to detect the features the ML-KEM code - requires in configure. Give up for now and use VLA support (that we - can detect) as a proxy for "old compiler" and turn off ML-KEM if - it isn't supported. + Shorten workflow names to fit in a single line. -commit e8a0f19b56dfa20f98ea9876d7171ec315fb338a -Author: Damien Miller -Date: Mon Sep 9 16:46:40 2024 +1000 +commit 9824ec515ed6256c1a98d66049471053f965b75e +Author: Darren Tucker +Date: Fri Sep 26 22:26:33 2025 +1000 - fix previous; check for C99 compound literals + Update link to oss-fuzz bug tracker. - The previous commit was incorrect (or at least insufficient), the - ML-KEM code is actually using compound literals, so test for them. + Remove 9.8 branch. -commit 7c07bec1446978bebe0780ed822c8fedfb377ae8 -Author: Damien Miller -Date: Mon Sep 9 16:06:21 2024 +1000 +commit 37d996bd0537837f15fc540d5aebb1ef2faf2268 +Author: dtucker@openbsd.org +Date: Thu Sep 25 22:17:29 2025 +0000 - test for compiler feature needed for ML-KEM + upstream: Check return codes of sshbuf functions. - The ML-KEM implementation we uses need the compiler to support - C99-style named struct initialisers (e.g foo = {.bar = 1}). We - still support (barely) building OpenSSH with older compilers, so - add a configure test for this. + Fixes Coverity CIDs 405059 and 405061. + + OpenBSD-Regress-ID: defa55d32892172251bbd5efd15731ce55888247 -commit d469d5f348772058789d35332d1ccb0b109c28ef -Author: djm@openbsd.org -Date: Mon Sep 9 03:13:39 2024 +0000 +commit 6c3c9f03c3c2cc4e40decbb49b8486abfb9e57df +Author: Darren Tucker +Date: Fri Sep 26 08:23:21 2025 +1000 - upstream: test mlkem768x25519-sha256 + Replace hand-rolled modulo with arc4random_uniform. - OpenBSD-Regress-ID: 7baf6bc39ae55648db1a2bfdc55a624954847611 + Fixes potential modulo-by-zero UB flagged by Coverity CID 405068 -commit 62fb2b51bb7f6863c3ab697f397b2068da1c993f -Author: djm@openbsd.org -Date: Mon Sep 9 02:39:57 2024 +0000 +commit e914e61eb88e22e5b725c399698256c54589ca32 +Author: Darren Tucker +Date: Thu Sep 25 17:50:07 2025 +1000 - upstream: pull post-quantum ML-KEM/x25519 key exchange out from - - compile-time flag now than an IANA codepoint has been assigned for the - algorithm. + Remove status bits from OpenSSL >=3 version check. - Add mlkem768x25519-sha256 in 2nd KexAlgorithms preference slot. + OpenSSL traditionally did not guarantee ABI compatibility across release + (and development) versions. Because of this, OpenSSH checked the lower 4 + "status" bits returned by OpenSSL_version_num(), which were originally + set to 0 for development versions and 0xf for release versions and, if + they did not match, would report the discrepancy and exit. - ok markus@ + OpenSSL (unintentionally) changed these bits in the 3.0.0 and subsequent + 3.x releases, setting them to zero in the release versions (which happened + to also match the documentation), then changed them back in the 3.5.3 + release. If OpenSSL was upgraded to (or from) this version without + recompiling OpenSSH, it would cause OpenSSH flag it as potentially + incompatible and refuse to use it. Ultimately OpenSSL rolled this + back, but the check now has no value so is being removed for OpenSSL + versions >=3. - OpenBSD-Commit-ID: 9f50a0fae7d7ae8b27fcca11f8dc6f979207451a + bz#3865 and https://github.com/openssl/openssl/issues/28575, ok djm@ -commit a8ad7a2952111c6ce32949a775df94286550af6b -Author: djm@openbsd.org -Date: Fri Sep 6 02:30:44 2024 +0000 +commit 35f3e2a41c2afe7a68a8a4efb3eb385e7f8d247d +Author: Darren Tucker +Date: Thu Sep 25 18:06:55 2025 +1000 - upstream: make parsing user@host consistently look for the last '@' in - - the string rather than the first. This makes it possible to use usernames - that contain '@' characters. - MIME-Version: 1.0 - Content-Type: text/plain; charset=UTF-8 - Content-Transfer-Encoding: 8bit - - Prompted by Max Zettlmeißl; feedback/ok millert@ + Update pledge() interface to match current OpenBSD. - OpenBSD-Commit-ID: 0b16eec246cda15469ebdcf3b1e2479810e394c5 + ok djm@ -commit 13cc78d016b67a74a67f1c97c7c348084cd9212c -Author: djm@openbsd.org -Date: Wed Sep 4 05:33:34 2024 +0000 +commit 7ce3823547578a3b083085744c1fea39237197a2 +Author: Darren Tucker +Date: Tue Sep 23 22:12:19 2025 +1000 - upstream: be more strict in parsing key type names. Only allow + Merge all putty tests into a single test. - shortnames (e.g "rsa") in user-interface code and require full SSH protocol - names (e.g. "ssh-rsa") everywhere else. - - Prompted by bz3725; ok markus@ + The lets us reuse the built OpenSSH binaries and replaces 12*4min of + tests with a single 14min one. + +commit 1362f6c0f4ca3306a201a6572bb9ec0d47d8edb3 +Author: Darren Tucker +Date: Thu Sep 25 18:20:53 2025 +1000 + + Add #ifdefs in pwfree to match those in pwcopy. - OpenBSD-Commit-ID: b3d8de9dac37992eab78adbf84fab2fe0d84b187 + Fixes build on many platforms. -commit ef8472309a68e319018def6f8ea47aeb40d806f5 +commit 8235dc3d82c0ac347a3600df0907c6573720fbaa Author: djm@openbsd.org -Date: Wed Sep 4 05:11:33 2024 +0000 +Date: Thu Sep 25 07:05:11 2025 +0000 - upstream: fix RCSID in output + upstream: fix some one-off leaks in ssh.c; ok dtucker@ - OpenBSD-Commit-ID: 889ae07f2d2193ddc4351711919134664951dd76 + OpenBSD-Commit-ID: bf3c27ffe4b3cccb6553b554ec4c04929065a2bc -commit ba2ef20c75c5268d4d1257adfc2ac11c930d31e1 -Author: jmc@openbsd.org -Date: Tue Sep 3 06:17:48 2024 +0000 +commit 846987d1233f24bbe87ebed347e328f45525388a +Author: djm@openbsd.org +Date: Thu Sep 25 07:04:38 2025 +0000 - upstream: envrionment -> environment; + upstream: fix some one-off leaks in ssh-keygen; ok dtucker@ - OpenBSD-Commit-ID: b719f39c20e8c671ec6135c832d6cc67a595af9c + OpenBSD-Commit-ID: 32f51289c93246474659aa49067926fcab9e02e8 -commit e66c0c5673a4304a3a9fbf8305c6a19f8653740f -Author: Damien Miller -Date: Wed Sep 4 15:35:29 2024 +1000 +commit a1a7df8b3694fdd7b55ad6bb8fa7b3d5d7f5b89a +Author: djm@openbsd.org +Date: Thu Sep 25 07:00:43 2025 +0000 - add basic fuzzers for our import of sntrup761 + upstream: fix some leaks in ssh-add; feedback/ok dtucker@ + + OpenBSD-Commit-ID: 441302917de31a128c1d6d63acccc67042fcf349 -commit d19dea6330ecd4eb403fef2423bd7e127f4c9828 +commit a8a2702bcd9e81a086e6d2c278f1b62f9d8bf3a1 Author: djm@openbsd.org -Date: Tue Sep 3 05:58:56 2024 +0000 +Date: Thu Sep 25 06:57:54 2025 +0000 - upstream: regression test for Include variable expansion + upstream: fix some leaks; feedback/ok dtucker@ - OpenBSD-Regress-ID: 35477da3ba1abd9ca64bc49080c50a9c1350c6ca + OpenBSD-Commit-ID: 05bdbc2e494b87a4a79e509020bd8249c86a4ff0 -commit 8c4d6a628051e318bae2f283e8dc38b896400862 +commit a071af0682d686de85cf471f5e04deaee4d90adb Author: djm@openbsd.org -Date: Tue Sep 3 05:29:55 2024 +0000 +Date: Thu Sep 25 06:45:50 2025 +0000 - upstream: allow the "Include" directive to expand the same set of + upstream: wait for the unprivileged sshd-auth process to exit - %-tokens that "Match Exec" and environment variables. + before closing the fd it uses to report log messages + + This avoids a race where the child process notices the + fd was closed before exiting and spams the logs. ok dtucker@ - OpenBSD-Commit-ID: 12ef521eaa966a9241e684258564f52f1f3c5d37 + OpenBSD-Commit-ID: 7cddaa41be3b955e6bed570900db7ab8817b1e76 -commit 51b82648b6827675fc0cde21175fd1ed8e89aab2 +commit 4fddebe7f524b3403c876c3b399d5ce7ce3390a6 Author: djm@openbsd.org -Date: Mon Sep 2 12:18:35 2024 +0000 +Date: Thu Sep 25 06:33:19 2025 +0000 - upstream: missing ifdef + upstream: add some functions to free various structs, including - OpenBSD-Commit-ID: 85f09da957dd39fd0abe08fe5ee19393f25c2021 + channels data and packet state; ok dtucker@ tb@ + + OpenBSD-Commit-ID: a8b3705309d632cdae370d4147a03e703087b0d1 -commit f68312eb593943127b39ba79a4d7fa438c34c153 +commit d0c1e73d408a24b2db18c0aa1a0108bea0f24210 Author: djm@openbsd.org -Date: Mon Sep 2 12:13:56 2024 +0000 +Date: Thu Sep 25 06:31:42 2025 +0000 - upstream: Add experimental support for hybrid post-quantum key exchange - - ML-KEM768 with ECDH/X25519 from the Internet-draft: - https://datatracker.ietf.org/doc/html/draft-kampanakis-curdle-ssh-pq-ke-03 + upstream: fix leaks of config objects in - This is based on previous patches from markus@ but adapted to use the - final FIPS203 standard ML-KEM using a formally-verified implementation - from libcrux. + mm_decode_activate_server_options ok dtucker@ tb@ - Note this key exchange method is still a draft and thus subject to - change. It is therefore disabled by default; set MLKEM=yes to build it. - We're making it available now to make it easy for other SSH - implementations to test against it. + OpenBSD-Commit-ID: 211f4d7d02e847bd1bcb460f6beb11658809a742 + +commit b62aa85dcbc8f03bf91d26d14fbf8fd5e172d882 +Author: djm@openbsd.org +Date: Thu Sep 25 06:25:38 2025 +0000 + + upstream: clarify intent and avoid (harmess, defined behaviour) - ok markus@ deraadt@ + unsigned underflow. ok tb@ - OpenBSD-Commit-ID: 02a8730a570b63fa8acd9913ec66353735dea42c + OpenBSD-Commit-ID: b73bf5f1f381c3e4561a6cc706fb1cd77c939cd8 -commit 05f2b141cfcc60c7cdedf9450d2b9d390c19eaad -Author: Antonio Larrosa -Date: Fri Aug 23 12:21:06 2024 +0200 +commit 6f28a935cc7d073e6647643e81d98b5831df204f +Author: jsg@openbsd.org +Date: Thu Sep 25 06:23:19 2025 +0000 - Don't skip audit before exitting cleanup_exit + upstream: consistently use NULL for null pointer constants found - This fixes an issue where the SSH_CONNECTION_ABANDON event is not - audited because cleanup_exit overrides the regular _exit too soon and - as a result, failed auth attempts are not logged correctly. + with sparse, ok djm@ - The problem was introduced in 81c1099d22b81ebfd20a334ce986c4f753b0db29 - where the code from upstream was merged before the audit_event call when - it should have been merged right before the _exit call in order to honor - the comment that just mentions an override of the exit value. + OpenBSD-Commit-ID: 1067504b63732d809d0d57ad4bc626818d112772 -commit 16eaf9d401e70996f89f3f417738a8db421aa959 -Author: djm@openbsd.org -Date: Wed Aug 28 12:08:26 2024 +0000 +commit 0af7e5b690e2cfe8824f04f154b0e543509dbefd +Author: jsg@openbsd.org +Date: Thu Sep 25 02:15:39 2025 +0000 - upstream: fix test: -F is the argument to specify a non-default - - ssh_config, not -f (this is sadly not a new bug) + upstream: remove unneeded externs ok djm@ - OpenBSD-Regress-ID: 45a7bda4cf33f2cea218507d8b6a55cddbcfb322 + OpenBSD-Commit-ID: fe553193e910a122505142a4e1db7358cc1ae653 -commit 10ccf611ab8ecba9ce6b0548c5ccd8c1220baf92 -Author: deraadt@openbsd.org -Date: Fri Aug 23 04:51:00 2024 +0000 +commit ae62a16118bb96a8e449ef25f5e55ef86a52cefb +Author: jsg@openbsd.org +Date: Thu Sep 25 02:12:16 2025 +0000 - upstream: As defined in the RFC, the SSH protocol has negotiable + upstream: remove prototype for removed ssh_packet_set_tos() ok - compression support (which is requested as the name "zlib"). Compression - starts very early in the session. Relative early in OpenSSH lifetime, privsep - was added to sshd, and this required a shared-memory hack so the two - processes could see what was going on in the dataflow. This shared-memory - hack was soon recognized as a tremendous complexity risk, because it put libz - (which very much trusts it's memory) in a dangerous place, and a new option - ("zlib@openssh.com") was added begins compression after authentication (aka - delayed-compression). That change also permitted removal of the - shared-memory hack. Despite removal from the server, the old "zlib" support - remained in the client, to allow negotiation with non-OpenSSH daemons which - lack the delayed-compression option. This commit deletes support for the - older "zlib" option in the client. It reduces our featureset in a small way, - and encourages other servers to move to a better design. The SSH protocol is - different enough that compressed-key-material attacks like BEAST are - unlikely, but who wants to take the chance? We encourage other ssh servers - who care about optional compression support to add delayed-zlib support. - (Some already do "zlib@openssh.com") ok djm markus + djm@ - OpenBSD-Commit-ID: 6df986f38e4ab389f795a6e39e7c6857a763ba72 + OpenBSD-Commit-ID: 396f82995074ef4d7b9ce44168266ef4640d9985 -commit aee54878255d71bf93aa6e91bbd4eb1825c0d1b9 -Author: djm@openbsd.org -Date: Thu Aug 22 23:11:30 2024 +0000 +commit d8588478850463f8945aa18d0358b2b227f8b57a +Author: jsg@openbsd.org +Date: Wed Sep 24 00:51:28 2025 +0000 - upstream: sntrup761x25519-sha512 now has an IANA codepoint assigned, so - - we can make the algorithm available without the @openssh.com suffix too. ok - markus@ deraadt@ + upstream: spelling; ok dtucker@ - OpenBSD-Commit-ID: eeed8fcde688143a737729d3d56d20ab4353770f + OpenBSD-Commit-ID: 93870117b0153859dd8baa80b97e44d4558c786b -commit a76a6b85108e3032c8175611ecc5746e7131f876 +commit eff358890a7cab1e7c2fec62e5b9914d2c1c8703 Author: Darren Tucker -Date: Thu Aug 22 20:36:12 2024 +1000 +Date: Tue Sep 23 16:51:34 2025 +1000 - Move rekey test into valgrind-2. + Merge VM tests into a single workflow file. - Now that the rekey test has been optimized it's fast enough to not be in - its own valgrind test, so move it into valgrind-2, which is currently - the quickest of the others, bringing all of them to roughly the same - runtime of ~1.1 hours. + Should make it easier to manage, although it may cause a few extra runs. -commit 7e75e3f57c41b9a6e6401e7674d7c2ff5c33975b -Author: dtucker@openbsd.org -Date: Thu Aug 22 10:21:02 2024 +0000 +commit d00015d21190517a1f505eb8120f716b1c2e4055 +Author: Darren Tucker +Date: Tue Sep 23 16:38:45 2025 +1000 - upstream: Use aes128-ctr for MAC tests since default has implicit MAC. - - Also verify that the Cipher or MAC we intended to use is actually the one - selected during the test. - - OpenBSD-Regress-ID: ff43fed30552afe23d1364526fe8cf88cbfafe1d + Test openssl-3.6 branch not beta1. -commit ebc890b8b4ba08c84cd1066b7b94b2b11f6c4cb4 -Author: Damien Miller -Date: Thu Aug 22 09:45:49 2024 +1000 +commit 31fce4fc5aaf79b9a4bccf09467e86c56b482bde +Author: Darren Tucker +Date: Tue Sep 23 15:51:14 2025 +1000 - fix incorrect default for PasswordAuthentication - - merge botch spotted by gsgleason + Test openssl-3.6.0-beta1. -commit 15ace435ea1c2fab2a1cc7d9c3157fe20c776b80 -Author: dtucker@openbsd.org -Date: Wed Aug 21 10:33:27 2024 +0000 +commit b94e7251a17a497669e825cb70ac79c96bdc3472 +Author: Darren Tucker +Date: Tue Sep 23 11:32:57 2025 +1000 - upstream: Some awks won't match on the \r so delete it instead. Fixes - - regress in portable on, eg Solaris. - - OpenBSD-Regress-ID: 44a96d6d2f8341d89b7d5fff777502b92ac9e9ba + Specify rpath when building OpenSSL. -commit 51c96b6ed627779a04493a8fe25747996a37f3c2 -Author: dtucker@openbsd.org -Date: Wed Aug 21 07:06:27 2024 +0000 +commit 83853aa5e35f3da0690bccd2983764d4e749a670 +Author: Darren Tucker +Date: Mon Sep 22 15:26:17 2025 +1000 - upstream: Import regenerated moduli. + Factor out OpenSSL install and test more versions. - OpenBSD-Commit-ID: 5db7049ad5558dee5b2079d3422e8ddab187c1cc + Move OpenSSL installation into its own script with a "-a" option to + install the "next" version to test for ABI compatibility. -commit 25c52f37a82c4da48ec537de37d7c168982b8d6d -Author: dtucker@openbsd.org -Date: Wed Aug 21 06:59:08 2024 +0000 +commit 2c1d38f7ffc8b8ec244bfe17ec8a85b3d737dcab +Author: Darren Tucker +Date: Mon Sep 22 16:55:49 2025 +1000 - upstream: Use curve25519-sha256 kex where possible. - - Except where we're explicitly testing a different kex, use - curve25519-sha256 since it's faster than the default and supported even - when configured without OpenSSL. Add a check to ensure that the kex we - intended to test is the one we actually tested. Speeds test up by ~5%. - - OpenBSD-Regress-ID: 3b27fcc2ae953cb08fd82a0d3155c498b226d6e0 + Exclude generated openbsd-compat/include directory. -commit 3eb62b7ba49483c309b483eb9002a679014f3887 -Author: dtucker@openbsd.org -Date: Tue Aug 20 12:36:59 2024 +0000 +commit 67b3ed101a18348b564507f55e3ed4b7e0d23ff9 +Author: Darren Tucker +Date: Sat Sep 20 15:07:36 2025 +1000 - upstream: Send only as much data as needed to trigger rekeying. Speeds - - up tests by about 10% in the common case, hopefully more when instrumented - with something like valgrind. - - OpenBSD-Regress-ID: 7bf9292b4803357efcf0baf7cfbdc8521f212da1 + Add OpenSSL 3.x ABI cross-compatibility test. -commit cbd3f034bbf7853618fac99d7d868a2250154ea7 -Author: Damien Miller -Date: Wed Aug 21 09:18:29 2024 +1000 +commit c682c9f45a10ee0dc37fd716cfccd42271f92ddc +Author: Darren Tucker +Date: Sat Sep 20 15:05:19 2025 +1000 - simplify sshkey_prekey_alloc(); always use mmap + Add tests for OpenSSL 3.4 and 3.5 versions. -commit 4442bbc2fc661277a6dabfedb756a7e15ee8b8b8 -Author: dtucker@openbsd.org -Date: Tue Aug 20 09:15:49 2024 +0000 +commit 1659d0ac095608b809fd3173d2c48b7b39d40b02 +Author: Darren Tucker +Date: Sat Sep 20 15:53:04 2025 +1000 - upstream: Merge AEAD test into main test loop. + Build OpenSSL with -j4 to speed it up. + +commit ca9ac1109e2c875ea33da6818c1841aa2181e962 +Author: Darren Tucker +Date: Sat Sep 20 15:16:30 2025 +1000 + + Rerun tests if run_tests.sh changes. + +commit bc328144f149af07139a0f2c1329018cd85b86b7 +Author: djm@openbsd.org +Date: Fri Sep 19 01:32:45 2025 +0000 + + upstream: log at level INFO when PerSourcePenalties actually blocks - Removes 3 duplicate tests and speeds overall test up by about 1%. + access to a source address range. Previously this was logged at level + VERBOSE, which hid enforcement actions under default config settings. - OpenBSD-Regress-ID: 5e5c9ff3f7588091ed369e34ac28520490ad2619 + ok dtucker, markus + + OpenBSD-Commit-ID: ea2b0d7c2253ff5205719d74b526cf2870df894d -commit 829976a63fd1efae3a4c3e7c16fded59d92edb67 -Author: dtucker@openbsd.org -Date: Tue Aug 20 09:02:45 2024 +0000 +commit 80993390bed15bbd1c348f3352e55d0db01ca0fd +Author: Darren Tucker +Date: Wed Sep 17 17:41:41 2025 +1000 - upstream: Set a default RekeyLimit of 256k. + Whitespace. + +commit fc704057ce6b75637645a4b9c917565b3563e21b +Author: Darren Tucker +Date: Wed Sep 17 17:33:25 2025 +1000 + + Move Gihub VMs to their own status line. + +commit 2202e5f9008003044cac01ed70d83deec42ad4e0 +Author: Darren Tucker +Date: Tue Sep 16 23:00:14 2025 +1000 + + Use relative URLs for status + +commit 7c32e09ea3e5c7e1fa0b7e2d4ddc83f8beadafed +Author: Darren Tucker +Date: Mon Sep 15 17:21:15 2025 +1000 + + Add VM test targets via vmaction on Github. + +commit a4aa090a3d40dddb07d5ebebc501f6457541a501 +Author: djm@openbsd.org +Date: Mon Sep 15 03:00:22 2025 +0000 + + upstream: memory leaks in unit tests - Used unless overridden by a command-line flag, which simplifies some of - the ssh command lines. + OpenBSD-Regress-ID: af11ac7b8034b99ca324af4dae1ef5cd7700b273 + +commit 6f5942454ad6756355f3b4983ab882cf15e44440 +Author: djm@openbsd.org +Date: Mon Sep 15 05:17:37 2025 +0000 + + upstream: fix leaks of struct sftp_conn in scp; ok dtucker@ - OpenBSD-Regress-ID: e7cffa57027088e10336e412b34113969f88cb87 + OpenBSD-Commit-ID: 76bea50b5b87b750c3771bf80feb6067d994a9d2 -commit 57d02c9ea36aebad4e7146d46e041b6b2e582f7f -Author: dtucker@openbsd.org -Date: Tue Aug 20 07:52:43 2024 +0000 +commit 52f38c76fcb38dfe619d8caa3bb4bb782c785026 +Author: djm@openbsd.org +Date: Mon Sep 15 04:52:41 2025 +0000 - upstream: Add Compression=no to default ssh_config. + upstream: leak of principals file lines; ok dtucker@ - All of the rekey tests use it (otherwise the encrypted byte counts would - not match) so this lets us simplify the command lines. + OpenBSD-Commit-ID: 918bf1b70e5a969059300f3c23d45911690d9015 + +commit b9464cee0fd084d89d91696a17b3621b4cf512bf +Author: djm@openbsd.org +Date: Mon Sep 15 04:52:12 2025 +0000 + + upstream: leak of authentication options at exit; ok dtucker@ - OpenBSD-Regress-ID: dab7ce10f4cf6c68827eb8658141272aab3ea262 + OpenBSD-Commit-ID: ba559799c2ff9b10afc3abefb1797c0843a6ff24 -commit 7254eb26f7c0772c4b47c3b32f6d1b15855cdd8c -Author: dtucker@openbsd.org -Date: Tue Aug 20 07:41:35 2024 +0000 +commit 0bb37080c86674de7cdfb56c80add3cd316c68a8 +Author: djm@openbsd.org +Date: Mon Sep 15 04:51:35 2025 +0000 - upstream: Remove duplicate curve25519-sha256 kex. + upstream: memleak of keys not used for authentication; ok - curve25519-sha256@libssh.org is the pre-standardization name for the same - thing, so remove it as a duplicate. Speeds up test by a tiny amount. + dtucker@ - OpenBSD-Regress-ID: 5a5ee5fa1595a6e140b1cc16040bedf5996a5715 + OpenBSD-Commit-ID: ddfda79d243150fbd382d8f2cd75a90a072b3669 -commit 749896b874928c2785256cae4d75161dc3bfcc7d -Author: dtucker@openbsd.org -Date: Tue Aug 20 07:27:25 2024 +0000 +commit ee99f6e93e0ee90eedbd27ffb9b7f9fef7b98010 +Author: djm@openbsd.org +Date: Mon Sep 15 04:50:42 2025 +0000 - upstream: Unnest rekey param parsing test and use ssh not sshd. - - ssh uses the same parsing code, now has "-G" to dump its config and is - slightly faster to start up. This speeds up the test slightly (~5%) in the - common case but should help more during instrumented tests, eg under - valgrind, where startup costs are magnified. + upstream: memleak of certificate path; ok dtucker@ - OpenBSD-Regress-ID: 07c3acaf4c728e641033071f4441afc88141b0d0 + OpenBSD-Commit-ID: 90dc5390f2756ba339e2e6df54d4b8651d64c1e7 -commit 2b1762115481ff2b7a60fd4db2ae69b725437462 +commit 42fc6b6f9fbf58293b070f4de377c7695c275a8a Author: djm@openbsd.org -Date: Tue Aug 20 11:10:04 2024 +0000 +Date: Mon Sep 15 04:49:41 2025 +0000 - upstream: actually use the length parameter that was passed in rather + upstream: memleak of hostkey when downgrading host cert->key; ok - than a constant (this makes no difference in practice because the length is - always the same); reported by martin AT nmkd.net + dtucker - OpenBSD-Commit-ID: 4aecce232c2fe9b16e9217ff6bcb3c848d853e7e + OpenBSD-Commit-ID: f6f1f38a8ec144fb615434f6877066cf4610b826 -commit d922762ca16a7381131b242f49d7376c41fabcb5 -Author: Damien Miller -Date: Tue Aug 20 13:55:30 2024 +1000 +commit bc60bd55cbc1f8139c840668733b51475cbefd93 +Author: djm@openbsd.org +Date: Mon Sep 15 04:49:00 2025 +0000 - private key coredump protection for Linux/FreeBSD + upstream: memleak of editline history; ok dtucker@ - platforms not supporting coredump exclusion using mmap/madvise flags - fall back to plain old malloc(3). + OpenBSD-Commit-ID: a244c54eb074cf7fbe28f7ac4f03ace270f7a999 -commit cc048ca536d6bed6f2285b07040b0d57cd559ba5 +commit ee77ab9b2ca2d70daf8d4352f5daffa8036ece64 Author: djm@openbsd.org -Date: Tue Aug 20 03:48:30 2024 +0000 +Date: Mon Sep 15 04:48:29 2025 +0000 - upstream: place shielded keys (i.e. keys at rest in RAM) into memory + upstream: memleak of rfwd callback context; ok dtucker@ - allocated using mmap(3) with MAP_CONCEAL set. This prevents exposure of the - key material in coredumps, etc (this is in addition to other measures we take - in this area). - - ok deraadt@ - - OpenBSD-Commit-ID: cbbae59f337a00c9858d6358bc65f74e62261369 + OpenBSD-Commit-ID: 70b2aafeaace90703dd16a44a2a0b723d9155f33 -commit a0b35c791cad1f85481b23ba46373060292e1c80 +commit 0088b3f0ab2c615ae95b9f374963abaa0ab837ec Author: djm@openbsd.org -Date: Sat Aug 17 08:35:04 2024 +0000 +Date: Mon Sep 15 04:47:49 2025 +0000 - upstream: mention that ed25519 is the default key type generated and + upstream: memleaks of request packet and hostkeys blob; ok - clarify that rsa-sha2-512 is the default signature scheme when RSA is in use. - Based on GHPR505 from SebastianRzk + dtucker@ - OpenBSD-Commit-ID: 1d90df71636a04601685d2a10a8233bcc8d4f4c5 + OpenBSD-Commit-ID: 313b13a8e36b4ca8e064ee56792e67e0670a386a -commit 127a50f2c80572ed1a021feb11ecf941e92cbbef +commit d68451a25808c4eee74b898873cd4761f73651ed Author: djm@openbsd.org -Date: Sat Aug 17 08:23:04 2024 +0000 +Date: Mon Sep 15 04:41:20 2025 +0000 - upstream: fix minor memory leak in Subsystem option parsing; from + upstream: memleak of KRL revoked certs struct; ok dtucker - Antonio Larrosa via GHPR515 + OpenBSD-Commit-ID: f319868e0b2de49c41c735e75b87c403f009f5f9 + +commit 67940cc2f329427d3acb64d4893faf4527e58d5c +Author: djm@openbsd.org +Date: Mon Sep 15 04:40:34 2025 +0000 + + upstream: memleak of kex->server_sig_algs; ok dtucker@ - OpenBSD-Commit-ID: fff3bbefd1b2c45c98cbe45c6b857b15d8a2d364 + OpenBSD-Commit-ID: 41a3f64edd2c9b8addb2e445514ae25c24819e2c -commit 171427261d2079941eb1041079dbae875da37cbc +commit fae8e41741d23298c94a1ea3ef8704a1cc186cb5 Author: djm@openbsd.org -Date: Sat Aug 17 08:09:50 2024 +0000 +Date: Mon Sep 15 04:39:58 2025 +0000 - upstream: fix swapping of source and destination addresses in some sshd + upstream: fix memleak of channel forwarding permissions; ok - log messages + dtucker@ - OpenBSD-Commit-ID: 24d4cbb86325275df1f037545aa3b91456e52d25 + OpenBSD-Commit-ID: 069745547109bc8fcc09fab5b19c53599cae99fd -commit 2a50a8f1fa57857a5e124a2280bcf61cc63c77f7 -Author: Darren Tucker -Date: Sat Aug 17 11:10:19 2024 +1000 +commit 03872018c14ed943bc01a4e88be59195a742f106 +Author: djm@openbsd.org +Date: Mon Sep 15 04:39:15 2025 +0000 - Add compat functions for EVP_Digest{Sign,Verify}. + upstream: when merging auth options into the active set, don't - This should make LibreSSL 3.1.x through 3.3.x work again. Code from - tb@, ok djm@. Restore the test configs covering those. + leak the old struct sshauthopt; ok dtucker@ + + OpenBSD-Commit-ID: c6bfd7bc2932e37f811b3c53272c3b919d33e75b -commit 1c3a7145260e03037cc18715b883880836fd122d -Author: Philip Hands -Date: Thu Aug 8 13:03:51 2024 +0200 +commit efed5da4ced88170cf474246eff771dd16c7092f +Author: djm@openbsd.org +Date: Mon Sep 15 04:38:00 2025 +0000 - make sure that usage & man page match + upstream: fix memleak when applying certificate options; ok - SSH-Copy-ID-Upstream: da5b1abe55b72a16e0430e7598e1573da01779c0 + dtucker + + OpenBSD-Commit-ID: 36c219dcc05f4df82a0f9c500bdf5dbfea925289 -commit cd0d681645b9adcf2467e7838bfd9d5142de4c4e -Author: Philip Hands -Date: Thu Aug 8 13:01:47 2024 +0200 +commit edc601707b583a2c900e49621e048c26574edd3a +Author: djm@openbsd.org +Date: Thu Sep 11 07:23:32 2025 +0000 - update copyright notices + upstream: disable ssh-add autoexpiry of certificates when testing - Bump the year to 2024, but also reflect the fact that hands.com Ltd. has - been wound up in the UK, and its assets (including this copyright) have - now reverted to its owner, Philip Hands. + expired certificates - SSH-Copy-ID-Upstream: 0e4c4d072747a6568b11a790c29dd1b4ce663d7f + OpenBSD-Regress-ID: 64aadd23d37fd0b3a06498151f2cf83be7ac342c -commit 7fc9ccdce18841ebd0a97e31e43258512ab32a32 -Author: Philip Hands -Date: Sun Aug 4 20:45:00 2024 +0200 +commit c60153e4878f3a6700af69adbdd1863003e78abf +Author: djm@openbsd.org +Date: Thu Sep 11 07:22:37 2025 +0000 - restore optionality of -i's argument + upstream: correct getopt() string - SSH-Copy-ID-Upstream: f70e3abb510e4eeb040b47894e41828246c1b720 + OpenBSD-Commit-ID: 05ef9581a3dab32ec93aa5b9c3349ed1e7da9ec8 -commit c37aa7012b1a3c2c322fd19e71310aadc90fc674 -Author: Philip Hands -Date: Fri Aug 2 15:52:07 2024 +0200 +commit 7a4738af45201c115a9e20f830f30ed38ce6be76 +Author: djm@openbsd.org +Date: Thu Sep 11 03:29:58 2025 +0000 - avoid exploring .ssh/id*.pub subdirectories + upstream: need time.h for time(3) - SSH-Copy-ID-Upstream: 0b9e08b7707ad16de3c8e6a0410d9f42fbd56997 + OpenBSD-Commit-ID: 530964039cccab679432b6c5b28d2b0aa9760b00 -commit 777dce9e2e0d12f7e81e162f77749f30899869fe -Author: Philip Hands -Date: Fri Aug 2 10:07:11 2024 +0200 +commit 0c719c6aabc061f02a907fc96c390d0449b49f26 +Author: djm@openbsd.org +Date: Thu Sep 11 02:54:42 2025 +0000 - ensure that we're always told the source of keys + upstream: When adding certificates to an agent, set the expiry to - SSH-Copy-ID-Upstream: 1bee96f4793e8ec3fab9f9361204ae58f5cc7cae + the certificate expiry time plus a short (5 min) grace period. + + This will cause the agent to automtically remove certificates shortly + after they expire. + + A new ssh-add -N option disables this behaviour. + + Feedback/ok deraadt@ + + OpenBSD-Commit-ID: 92fed1bba1025069ad45deebb534be7530e181df -commit fb94fd2339848e40cad6c9bb42b822244cc1a7bc -Author: Philip Hands -Date: Wed Jul 31 23:19:51 2024 +0200 +commit e9dcccc3541b0ae1c43581ed26215d5cc82e4be0 +Author: jsg@openbsd.org +Date: Mon Sep 8 00:31:54 2025 +0000 - add $HOME to ERROR if one cannot write to ~/.ssh + upstream: remove unused 0-sized files; ok deraadt@ - SSH-Copy-ID-Upstream: ebef3e9c06e0447bff06e9d84b33023cf592e0ba + OpenBSD-Commit-ID: 7e8178786157e863f6ff63c5d55200d7b6b04f9e -commit eb5aafa1ffaeee75799141ec5ded406a65ec7d18 -Author: Philip Hands -Date: Wed Jul 31 23:19:03 2024 +0200 +commit d16b1b484a024ee6b35094e7d9d55bf96b96253b +Author: dtucker@openbsd.org +Date: Fri Sep 5 10:34:35 2025 +0000 - assert that SCRATCH_DIR is a writable directory + upstream: Tabs->spaces. Removes diff vs portable. - SSH-Copy-ID-Upstream: ecb2b9d10883b9a16df56c83896c9bb47a80cde2 + OpenBSD-Commit-ID: 06598021a9f08188dab29ac956b2baa002a0ff85 -commit abcc460a2af46f0d812f8433d97a8eae1d80724c -Author: Philip Hands -Date: Wed Jul 31 23:17:54 2024 +0200 +commit 3d8ae7f235b96da604b08c44ae83420e367eeab4 +Author: Tim Rice +Date: Mon Sep 8 12:53:10 2025 -0700 - quote to avoid potential for word splitting + modified: regress/rekey.sh + Fix for when building out of tree. + +commit 54abadd3f286efea0dbbdbfea8011d5e1e30c074 +Author: Darren Tucker +Date: Sun Sep 7 13:35:22 2025 +1000 + + Accept OpenSSL 4.0.0-dev versions. - SSH-Copy-ID-Upstream: f379adbe06ac2ef1daf0f130752234c7f8b97e3c + They seem to work, at least for now. -commit b3f91411fd1473605f74c40c1a91a024c7171e27 -Author: Philip Hands -Date: Wed Jul 31 23:15:11 2024 +0200 +commit 67a8bf4e4057597170bfa923fe2ce5bf90c43974 +Author: Maxim Khon +Date: Mon Aug 18 12:05:42 2025 +0000 - ensure ERROR output goes to STDERR + Use SSH_TUN_COMPAT_AF on FreeBSD. - SSH-Copy-ID-Upstream: ac394b05eead3b91feb7c2ae4129a3e9b892f1e2 + Otherwise tun forwarding from other OSes fails as soon as the first IPv6 + message is sent by the other side (which is usually a Router Solicitation + ICMPv6 message which is sent as soon as the interface is up): all other + OS'es use SSH_TUN_COMPAT_AF or SSH_TUN_PREPEND_AF which effectively uses + OpenBSD AF_INET/AF_INET6 values. -commit 674b8f30f0dbacd787eb1e4e7e1ece34b5543d8f -Author: Philip Hands -Date: Thu Aug 1 14:03:06 2024 +0200 +commit 3ca274e44cb2c2351376fc14e4c3e92ba4a8f87b +Author: Darren Tucker +Date: Fri Sep 5 21:32:30 2025 +1000 - avoid extra space when no arg given to -i option + Check for nlist function. - SSH-Copy-ID-Upstream: feca9e67e6e37c5653445d1c733569d7abb1770e + Check for nlist function presence before attenmpting to use it instead + of relying on the presence of the nlist.h header. Mac OS X, in particular + has the header, but only has the function in the 32bit libraries. -commit 0efa0e1c41427c0c6ba839a18c72c1afcd7b7cc0 -Author: Philip Hands -Date: Wed Jul 31 23:28:36 2024 +0200 +commit ee32a36c62424f13907023595bfa8b23a528ced1 +Author: dtucker@openbsd.org +Date: Fri Sep 5 10:23:55 2025 +0000 - put the -i before -[pP] (matching man pages) + upstream: Order includes as per KNF and add time.h. Removes diff - The man pages (ssh, sftp & ssh-copy-id) all list -i before the port - setting, so make the output match that order, which also seems more - natural with the port being next to the server. + vs portable. - SSH-Copy-ID-Upstream: 34d5d614172c78f9a42249466c4b81975b8883a1 + OpenBSD-Commit-ID: 38043f0bfa17c48ef6d1a744c2834b4405bc9311 -commit 87831345e9745f2d13bd7a4a7972809f6788f331 -Author: Shreyas Mahangade -Date: Mon Jul 29 15:26:05 2024 +0000 +commit 0ac179c9540e2b05b4c1194db69ce01306c253d3 +Author: dtucker@openbsd.org +Date: Fri Sep 5 10:17:21 2025 +0000 - Minor space issue fixed + upstream: Order headers as per KNF. Removes diff vs portable. - SSH-Copy-ID-Upstream: 335e44d7be78b03962a54c3a5c99a2ff45294a54 + OpenBSD-Commit-ID: 4df519fd9fa13ce9653adf7a3d1076e20591d886 -commit 2f3010f4736b4b3f5c10a4be97a24e90ff04c5e7 -Author: Shreyas Mahangade -Date: Mon Jul 29 16:55:28 2024 +0530 +commit e80322284f3ee70b6b760a9f83179470d675e5ba +Author: dtucker@openbsd.org +Date: Fri Sep 5 10:01:35 2025 +0000 - Show identity file in 'ssh' command - - - Previously no identity file is shown in "ssh" command output on the line "Now try logging into the..." - - This commit makes sure whenever "ssh-copy-id" with "-i" is invoked, it also reflects in "ssh" command + upstream: Order headers as per KNF. - SSH-Copy-ID-Upstream: 58e022ec26cb2315eb3be581d01e0ba787082428 + OpenBSD-Commit-ID: 7156b69b0364c68e181e0f6fa17c0f05c72e8670 -commit a13856374b894397a7682b32257ed0bf67cfede9 -Author: Damien Miller -Date: Fri Aug 16 08:30:20 2024 +1000 +commit bb8ac0515e68cab63db2d026eb60127185a3d2b8 +Author: Darren Tucker +Date: Fri Sep 5 20:39:16 2025 +1000 - more OPENSSL_HAS_ECC + Resync header order with upstream. -commit 4da2a1a7f648979bea6eaf3b17f5f250faed4afc -Author: Damien Miller -Date: Thu Aug 15 23:35:54 2024 +1000 +commit 024b694249482698b0c73d24da0eaec696fca8c8 +Author: Darren Tucker +Date: Fri Sep 5 20:37:04 2025 +1000 - fix merge botch that broke !OPENSSL_HAS_ECC + Resync header order with upstream. -commit 2c53d2f32b8e3992b61682c909ae5bc5122b6e5d -Author: Damien Miller -Date: Thu Aug 15 15:09:45 2024 +1000 +commit aed6a958bc108faab64bc2855d6ed93894cfc6ff +Author: Darren Tucker +Date: Fri Sep 5 20:30:20 2025 +1000 - missed OPENSSL_HAS_ECC case + Sync includes with upstream. -commit 342dd7a219f39119b8b686b5aaa99c8e15ede368 -Author: Damien Miller -Date: Thu Aug 15 15:06:55 2024 +1000 +commit 22cfd2dd32f34f0cea218dd651f3aa9544b6e3b5 +Author: Darren Tucker +Date: Fri Sep 5 20:26:14 2025 +1000 - retire testing aginst older LibreSSL versions - - libressl prior to 3.4.x lack support for the EVP_DigestSign and - EVP_DigestVerify APIs that we need now that sshkey is converted - to EVP_PKEY. - - If someone makes a good case for why we should support these versions - then we could bring back support with wrappers. - -commit a7c6ea8eebe0f179141ec5dbf0c9e5354417930f -Author: Damien Miller -Date: Thu Aug 15 12:44:17 2024 +1000 - - sync TEST_MALLOC_OPTIONS for OpenBSD + Move ssh-pkcs11.h include to match upstream. -commit 60c2cf22e8f64f35d8b1175e4671257313f2e4d3 -Author: Damien Miller -Date: Thu Aug 15 12:43:47 2024 +1000 +commit b34c16bc4cac2962cc6a7517efbc4fed2c8a2d9a +Author: Darren Tucker +Date: Fri Sep 5 20:20:27 2025 +1000 - remove gratuitious difference from OpenBSD + Reorder includes to match upstream. -commit 339c4fc60a6250429d41fa8713f783d82aad4551 -Author: djm@openbsd.org -Date: Thu Aug 15 00:52:23 2024 +0000 +commit 441a8fa9a0178704bce497bff92ca43fcf04bf7a +Author: dtucker@openbsd.org +Date: Fri Sep 5 09:58:08 2025 +0000 - upstream: adapt to EVP_PKEY conversion + upstream: Order headers as per KNF. Removes diff vs portable. - OpenBSD-Regress-ID: 0e2d4efb0ed0e392e23cd8fda183fe56531ac446 + OpenBSD-Commit-ID: db72be57429418f6a4319bbe34c98fc103e11ce0 -commit 63a94f99b9d7c8a48182a40192e45879d1ba8791 -Author: djm@openbsd.org -Date: Fri Jul 19 04:33:36 2024 +0000 +commit 19d6a7afb256c4afc571dbf56a013ef91cd9596f +Author: dtucker@openbsd.org +Date: Fri Sep 5 09:49:26 2025 +0000 - upstream: test transfers in mux proxy mode too + upstream: Order headers as per KNF. Also removes diff vs - OpenBSD-Regress-ID: 2edfc980628cfef3550649cab8d69fa23b5cd6c4 + -portable. + + OpenBSD-Commit-ID: 2061307dc938712e524bc9da48a52f545e43670e -commit 7bdfc20516e288b58c8c847958059c7b141eeff9 -Author: djm@openbsd.org -Date: Thu Aug 15 00:51:51 2024 +0000 +commit 932e9f200bd48b7568eb21ec456c67ec92d517e2 +Author: dtucker@openbsd.org +Date: Fri Sep 5 09:31:31 2025 +0000 - upstream: Convert RSA and ECDSA key to the libcrypto EVP_PKEY API. - - DSA remains unconverted as it will be removed within six months. - - Based on patches originally from Dmitry Belyavskiy, but significantly - reworked based on feedback from Bob Beck, Joel Sing and especially - Theo Buehler (apologies to anyone I've missed). + upstream: Remove unused rmd160.h header. ripemd160 support was - ok tb@ + removed in 2017. - OpenBSD-Commit-ID: d098744e89f1dc7e5952a6817bef234eced648b5 + OpenBSD-Commit-ID: 937fca21498b921adf6e04bac120f4a2e7975b3c -commit 0af06e2c5b898992a18c74333e75a0136506acc6 -Author: tobias@openbsd.org -Date: Wed Aug 14 15:42:18 2024 +0000 +commit f93de828b9b0f29bff51d38ea92d0759595ec30b +Author: Darren Tucker +Date: Fri Sep 5 20:07:16 2025 +1000 - upstream: Reorder calloc arguments - - The first argument should be the amount, the second argument should be the - element size. Fixing this also silences some gcc compiler warnings for - portable. - - Spotted with Benny Baumann (BenBE at geshi dot org). - - ok djm@ + Create replacement nlist.h if needed. - OpenBSD-Commit-ID: 711ad6f7bd7fb48bf52208f2cf9f108cddb6d41a + Remove #ifdef HAVE_NLIST_H wrapper. ok djm@ -commit 56ce0aa3c6cf28d9fcbce3207457abeac91b5050 -Author: tobias@openbsd.org -Date: Wed Aug 14 15:40:30 2024 +0000 +commit 6aac2beaa53467e83f6a137376b6dcf423ab6f6c +Author: Darren Tucker +Date: Fri Sep 5 19:55:20 2025 +1000 - upstream: Extend sshbuf validation - - Multiple sshbuf structs can be linked through a parent/child relationship. - Make sure that a single sshbuf cannot be its own parent. If this would ever - happen, it would result in reference counting issues. - - This is a cheap way of testing this with very little overhead. It does not - detect A->B->A linkages though for performance reason and the fact that it - takes a programming error for this to occur anyway. - - Authored with Benny Baumann (BenBE at geshi dot org). + Create replacement endian.h if needed. - ok djm@ + Remove #ifdef HAVE_ENDIAN_H wrapper. ok djm@ + +commit a60721c894f0a2ce973876d0f55617e187e6fab1 +Author: Darren Tucker +Date: Fri Sep 5 19:52:48 2025 +1000 + + Add /* WITH_OPENSSL */ comments. - OpenBSD-Commit-ID: fb3fa9ee2cad3c7e842ebadfd7f5db220c4aaf16 + Removes diffs vs upstream. -commit fc48ddf6998188517af42dce807e2088b6a0c0be -Author: tobias@openbsd.org -Date: Wed Aug 14 15:37:11 2024 +0000 +commit c729a833298d9d55ffb22771cf1400dfdc640164 +Author: Darren Tucker +Date: Fri Sep 5 19:22:37 2025 +1000 - upstream: Use freezero for better readability + Move sys/time.h include to match upstream. + +commit caa973dd06a7be43c29353b256c9a473f5ad9882 +Author: Darren Tucker +Date: Fri Sep 5 19:13:52 2025 +1000 + + Create replacement netgroup.h if needed. - It has the same meaning as the current pair of calling explicit_bzero - and free. Spotted with Benny Baumann (BenBE at geshi dot org). + Remove #ifdef HAVE_NETGROUP_H wrapper. ok djm@ + +commit 7d30526b7df14d960a5de63d6af823ffdab86518 +Author: Darren Tucker +Date: Fri Sep 5 18:24:59 2025 +1000 + + Remove stray #endif left from previous. + +commit 4911f2600fdbb1959311bb1886bfe51f7dd4a74e +Author: Darren Tucker +Date: Fri Sep 5 18:08:51 2025 +1000 + + Create replacement libgen.h if needed. - ok djm@ + Remove #ifdef HAVE_LIBGEN_H wrapper. ok djm@ + +commit 65dcdb56f5daee519ec824ae17e64412d2492f90 +Author: Darren Tucker +Date: Fri Sep 5 18:05:15 2025 +1000 + + Create replacement sys/un.h if needed. - OpenBSD-Commit-ID: 939fbe9ccf52d0d48c5fa53694d6f3bb9927970c + Remove #ifdef HAVE_SYS_UN_H wrapper. ok djm@ -commit 1ff6907ec26dac6ac59fe9fe232899a63b4c14d8 -Author: tobias@openbsd.org -Date: Wed Aug 14 15:35:23 2024 +0000 +commit 60334af5a908ac3b263d2ec696f9977e20b739cb +Author: Darren Tucker +Date: Fri Sep 5 18:03:55 2025 +1000 - upstream: Fix typo in comment + Reformat replacement header check one per line. + +commit cd9ba068e36b0f37374d2eba2d19dacc7ea9a167 +Author: Darren Tucker +Date: Fri Sep 5 17:55:33 2025 +1000 + + Create replacement time.h if needed. - Spotted with Benny Baumann (BenBE at geshi dot org). + Remove #ifdef HAVE_TIME_H wrapper. ok djm@ + +commit ea586edbcbec7089f768ed682a79a399eaa1e5b1 +Author: Darren Tucker +Date: Fri Sep 5 17:50:18 2025 +1000 + + Create replacement sys/stat.h if needed. - ok djm@ + Remove #ifdef HAVE_SYS_STAT_H wrapper. ok djm@ + +commit 59b80707c6cf45230597a800e7d2ce6b00ce35b5 +Author: Darren Tucker +Date: Fri Sep 5 17:44:07 2025 +1000 + + Create replacement sys/time.h if needed. - OpenBSD-Commit-ID: 829160ac8ef3ad3409695ce3a3ade835061cae57 + Remove #ifdef HAVE_SYS_TIME_H wrapper. ok djm@ -commit 487faaed8f3bb9ffb19e8f807a3da72895b16421 -Author: dlg@openbsd.org -Date: Wed Jul 31 12:00:18 2024 +0000 +commit 82fed5110fe09e9af258a8f5a2f92ffb397fff5b +Author: Darren Tucker +Date: Fri Sep 5 17:31:15 2025 +1000 - upstream: add a random amount of time (up to 4 seconds) to the + Create replacement ifaddrs.h if needed. - grace login time. + Remove #ifdef HAVE_IFADDRS_H wrapper. ok djm@ + +commit 53887d8ebc583b51e996cb2bdeb11e054d36343b +Author: Darren Tucker +Date: Fri Sep 5 17:27:43 2025 +1000 + + Create replacement util.h if needed. - ok deraadt@ djm@ + Remove #ifdef HAVE_UTIL_H wrapper. ok djm@ + +commit 5f09983d1e724097bd577097fb0f2c00c2436f21 +Author: Darren Tucker +Date: Fri Sep 5 17:24:50 2025 +1000 + + Create replacement paths.h if needed. - OpenBSD-Commit-ID: abd3c57aaa5861517529b322df79b6be35ee67f4 + Remove #ifdef HAVE_PATHS_H wrapper. ok djm@ -commit 2865f5b7520bed3e74fbbb5f8d7a44193d7a4314 -Author: naddy@openbsd.org -Date: Fri Jul 26 15:24:49 2024 +0000 +commit d45b17dc5a0598dda2b11dc89598203408d2d59c +Author: Darren Tucker +Date: Fri Sep 5 17:17:52 2025 +1000 - upstream: document the reduced logingrace penalty + Create replacement poll.h if needed. - OpenBSD-Commit-ID: 9b63e0e3599d524ddc10edc4f978081382c3548b + Remove #ifdef HAVE_POLL_H wrapper. ok djm@ -commit 1ec0a64c5dc57b8a2053a93b5ef0d02ff8598e5c +commit 9b2c5a2db0650e394597839ef00d797f57568937 Author: Darren Tucker -Date: Sun Jul 28 21:26:51 2024 +1000 +Date: Fri Sep 5 17:06:14 2025 +1000 - Explicitly install libssl-devel cygwin. + Fill in missing system header files. - Should fix CI tests for cygwin default config. + Create replacement header files inside openbsd-compat for common headers + that are missing on a given platform. Usually these are just empty, + but in some cases they'll include the equivalent file. This avoids + having to wrap those includes in '#ifdef HAVE_FOO_H' and reduces the + diff vs OpenBSD. + + If we create any such headers, add the path to includes. + + Initially just stdint.h, more to follow. + + ok djm@ -commit 0bf6e5bb750b66b25c20a1c5a471f91850de3748 +commit f64701ca25795548a61614d0b13391d6dfa7f38c Author: djm@openbsd.org -Date: Thu Jul 25 23:44:01 2024 +0000 +Date: Thu Sep 4 03:04:44 2025 +0000 - upstream: reduce logingrace penalty. + upstream: repair test after changes to percent expansion of usernames - A single forgotton login that times out should be below the penalty - threshold. + on the commandline. - ok deraadt/claudio + Test more cases that should/shouldn't expand and lightly test + username validity checks. - OpenBSD-Commit-ID: cee1f7d17597c97bff8e5092af5d136fdb08f81d + OpenBSD-Regress-ID: ad4c12c70bdf1f959abfebd1637ecff1b49a484c -commit 29fb6f6d46b67770084b4f12bcf8a01bd535041b +commit 45698669d49949868b1f3d13dfda1b7cb70060ad Author: djm@openbsd.org -Date: Thu Jul 25 22:40:08 2024 +0000 +Date: Thu Sep 4 00:37:10 2025 +0000 - upstream: Fix proxy multiplexing (-O proxy) bug + upstream: unit tests for sshbuf_equals and sshbuf_dtourlb64; ok - If a mux started with ControlPersist then later has a forwarding added using - mux proxy connection and the forwarding was used, then when the mux proxy - session terminates, the mux master process will send a channel close to the - server with a bad channel ID and crash the connection. + deraadt@ - This was caused by my stupidly reusing c->remote_id for mux channel - associations when I should have just added another member to struct channel. - - ok markus@ + OpenBSD-Regress-ID: bab54e2d4caa813036a63ee67e92c93e6712a5b9 + +commit 4be445116f1b56f14254b98d8b132bb25777e160 +Author: djm@openbsd.org +Date: Thu Sep 4 00:34:17 2025 +0000 + + upstream: unit tests for a bunch of misc.c functions; ok deraadt@ - OpenBSD-Commit-ID: c9f474e0124e3fe456c5e43749b97d75e65b82b2 + OpenBSD-Regress-ID: 886cf142605405e777ee77a96b48694dc2e9235d -commit 53d1d307438517805989c7d5616d752739a97e03 +commit e3699ff47df336f57da2e78188d0057f8368af56 Author: djm@openbsd.org -Date: Thu Jul 18 01:47:27 2024 +0000 +Date: Thu Sep 4 00:32:31 2025 +0000 - upstream: mention mux proxy mode + upstream: fix sshbuf_dtourlb64() to not choke on empty buffers; - OpenBSD-Commit-ID: fd77a77779f06d316a314e4540dc57c93fc3369a + previously it incorrectly returned an error in this situation; ok deraadt + + OpenBSD-Commit-ID: e62773d6e8cb95a19aab54f0af0edbcd47b345c0 -commit a9b90859d252c2f5a24142f985d38610ac74685f -Author: jsg@openbsd.org -Date: Sun Jul 14 10:19:23 2024 +0000 +commit 8e85ad33cfcc71e03594e53f2e19d8ce2e27dcc6 +Author: djm@openbsd.org +Date: Thu Sep 4 00:31:49 2025 +0000 - upstream: fix double word; ok dtucker@ + upstream: fix rtrim() function to not attempt to delete whitespace - OpenBSD-Commit-ID: e6aff005914fa350b896d2be030be3d3b56ec0e8 + inside a string, just at the end. ok deraadt@ + + OpenBSD-Commit-ID: d44deaa43580cd88de978dd5509b14e905b67b84 -commit b05fda224bbcd2f641254534ed2175c42487f3c8 -Author: Darren Tucker -Date: Thu Jul 25 17:59:35 2024 +1000 +commit 43b3bff47bb029f2299bacb6a36057981b39fdb0 +Author: djm@openbsd.org +Date: Thu Sep 4 00:30:06 2025 +0000 - Check for SA_RESTART before using it. + upstream: don't allow \0 characters in url-encoded strings. - ok djm@ + Suggested by David Leadbeater, ok deraadt@ + + OpenBSD-Commit-ID: c92196cef0f970ceabc1e8007a80b01e9b7cd49c -commit c276672fc0e99f0c4389988d54a84c203ce325b6 -Author: Yuichiro Naito -Date: Wed Sep 1 10:19:32 2021 +0900 +commit 35d5917652106aede47621bb3f64044604164043 +Author: djm@openbsd.org +Date: Thu Sep 4 00:29:09 2025 +0000 - Class-imposed login restrictions + upstream: Improve rules for %-expansion of username. - If the following functions are available, - add an additional check if users are allowed to login imposed by login class. + Usernames passed on the commandline will no longer be subject to + % expansion. Some tools invoke ssh with connection information + (i.e. usernames and host names) supplied from untrusted sources. + These may contain % expansion sequences which could yield + unexpected results. - * auth_hostok(3) - * auth_timeok(3) + Since openssh-9.6, all usernames have been subject to validity + checking. This change tightens the validity checks by refusing + usernames that include control characters (again, these can cause + surprises when supplied adversarially). - These functions are implemented on FreeBSD. + This change also relaxes the validity checks in one small way: + usernames supplied via the configuration file as literals (i.e. + include no % expansion characters) are not subject to these + validity checks. This allows usernames that contain arbitrary + characters to be used, but only via configuration files. This + is done on the basis that ssh's configuration is trusted. + + Pointed out by David Leadbeater, ok deraadt@ + + OpenBSD-Commit-ID: e2f0c871fbe664aba30607321575e7c7fc798362 -commit 7717b9e9155209916cc6b4b4b54f4e8fa578e889 +commit f38a552dc71f20df2544338099e3fe2563f1a9ca +Author: Damien Miller +Date: Wed Sep 3 09:42:39 2025 +1000 + + missing header + +commit cc4eb3d6943cb57e08ab3abbcf92644deb429e46 Author: djm@openbsd.org -Date: Wed Jul 10 21:58:34 2024 +0000 +Date: Tue Sep 2 11:08:34 2025 +0000 - upstream: correct keyword; from Yatao Su via GHPR509 + upstream: simplify algorithm list functions using xextendf(); ok - OpenBSD-Commit-ID: 81c778c76dea7ef407603caa157eb0c381c52ad2 + dtucker@ + + OpenBSD-Commit-ID: ffc5f8d0c25b95705a8a66c8b634f98d23bd92dc -commit f2b78bb8f149d6b4d1f62c21aa1f06995dccf4ce +commit 8866d24cdd1d6e73bb3220b753f94e255c49ff96 Author: djm@openbsd.org -Date: Mon Jul 8 03:04:34 2024 +0000 +Date: Tue Sep 2 11:04:58 2025 +0000 - upstream: don't need return at end of void function + upstream: unit test for xextendf() - OpenBSD-Commit-ID: 42d322d37f13aa075ae7b1ad9eef591e20b89717 + OpenBSD-Regress-ID: ddb3b4db1a52dda23696b967470882fe2b9c3af7 -commit a395d37a813c0177cb5bfc4bebf5a52badb73cf0 +commit 2f369d3fd0ff3715c2b32dff5cb35c0330272445 Author: djm@openbsd.org -Date: Thu Jul 4 22:53:59 2024 +0000 +Date: Tue Sep 2 09:41:23 2025 +0000 - upstream: fix grammar: "a pattern lists" -> "one or more pattern + upstream: fix comment on sshbuf_froms() - it *returns* an error - lists" + code, the allocated buffer is passed via argument - OpenBSD-Commit-ID: f3c844763398faa9800687e8ff6621225498202a + OpenBSD-Commit-ID: b2b0a76df71328f39c3e2ad941a4d87085d8335d -commit 8b664df75966e5aed8dabea00b8838303d3488b8 -Author: Darren Tucker -Date: Sun Jul 7 18:46:19 2024 +1000 +commit 6fd93060bb2ec35a7f0bf96d1a74104bab49e017 +Author: djm@openbsd.org +Date: Tue Sep 2 09:40:19 2025 +0000 - Cast to sockaddr * in systemd interface. + upstream: GssStrictAcceptor was missing from sshd -T output; fix - Fixes build with musl libx. bz#3707. + OpenBSD-Commit-ID: 6014049ccfedc48a208e37d5488ade6bdc2d1c44 -commit 30c8c81da2169e78357d08dbb0ddd823b60e93bc -Author: Darren Tucker -Date: Thu Jul 4 20:12:26 2024 +1000 +commit d94a9a8c54e9036961c1100c6f445c50ab9b6b40 +Author: Damien Miller +Date: Tue Sep 2 19:38:39 2025 +1000 - Add 9.8 branch to ci-status page. + portable-specific comment grammer/spelling fixes -commit ee6b9e661633fcefd29dba0c811cecbc4d027f6f -Author: Samuel Thibault -Date: Tue Mar 26 22:15:08 2024 +0100 +commit a0b095fa03d3c08d723a803ce25540fddd955c53 +Author: djm@openbsd.org +Date: Tue Sep 2 09:34:48 2025 +0000 - Fix detection of setres*id on GNU/Hurd + upstream: grammar and typos in comments - Like Linux, proper _SOURCE macros need to be set to get declarations of - various standard functions, notably setres*id. Now that Debian is using - -Werror=implicit-function-declaration this is really required. While at - it, define other _SOURCE macros like on GNU/Linux, since GNU/Hurd uses - the same glibc. + OpenBSD-Commit-ID: de954daffcd0147ce142d55e8a374810cd19d7ed -commit fa41f6592ff1b6ead4a652ac75af31eabb05b912 +commit 23a2bb750547a9a5251cbc44c5ceb1d05303befe Author: Damien Miller -Date: Mon Jul 1 14:33:26 2024 +1000 +Date: Tue Sep 2 19:30:07 2025 +1000 - version numbers + replace remaining manual logging of __func__ + + Use the appropriate log macro that prepends the function name + (e.g. logit_f/debug2_f/etc). -commit bfebb8a5130a792c5356bd06e1ddef72a0a0449f +commit a9b0b69f15e63bc4e8c8b38e24ee85ea076a7e11 Author: djm@openbsd.org -Date: Mon Jul 1 04:31:59 2024 +0000 +Date: Tue Sep 2 09:26:21 2025 +0000 - upstream: openssh-9.8 + upstream: replace remaining cases where we manually included __func__ - OpenBSD-Commit-ID: 5f8b89e38a4c5f7c6d52ffa19f796d49f36fab19 + in a debug or error log with the respective *_f log variant + + OpenBSD-Commit-ID: 46a280d78bcc0bc98f28e65a30b613366600328f -commit 146c420d29d055cc75c8606327a1cf8439fe3a08 +commit 19f7cb39eecb4b8f768f37e8294dc3a9142e022b Author: djm@openbsd.org -Date: Mon Jul 1 04:31:17 2024 +0000 +Date: Mon Sep 1 23:55:29 2025 +0000 - upstream: when sending ObscureKeystrokeTiming chaff packets, we - - can't rely on channel_did_enqueue to tell that there is data to send. This - flag indicates that the channels code enqueued a packet on _this_ ppoll() - iteration, not that data was enqueued in _any_ ppoll() iteration in the - timeslice. ok markus@ + upstream: test MaxStatups idempotency; ok dtucker@ - OpenBSD-Commit-ID: 009b74fd2769b36b5284a0188ade182f00564136 + OpenBSD-Regress-ID: b5d713c2709000fa5e41d82c0cf8627e13cb43f9 -commit 637e4dfea4ed81264e264b6200172ce319c64ead +commit c357c4a1e626feba9a968b5f0cb832b989b2d433 Author: djm@openbsd.org -Date: Mon Jul 1 03:10:19 2024 +0000 +Date: Thu Aug 21 05:55:30 2025 +0000 - upstream: use "lcd" to change directory before "lls" rather then "cd", + upstream: benchmark more diffie-hellman-group* KEXs - since the directory we're trying to list is local. Spotted by Corinna - Vinschen + use current KEX names, i.e. remove the "@openssh.com" where the KEX + has been standardised - OpenBSD-Regress-ID: 821feca4a4bebe491944e624c8f7f2990b891415 + OpenBSD-Regress-ID: a67e9da4efd9a971d39cb2481093f836046f9b7f -commit c8cfe258cee0b8466ea84597bf15e1fcff3bc328 +commit 9313233a735733821dfd170b70782fb7da492962 Author: djm@openbsd.org -Date: Thu Jun 27 23:01:15 2024 +0000 +Date: Tue Sep 2 01:03:43 2025 +0000 - upstream: delete obsolete comment + upstream: fix previous - OpenBSD-Commit-ID: 5fb04f298ed155053f3fbfdf0c6fe7cdf84bbfa2 + OpenBSD-Commit-ID: 09d95dfb5e064a1d0e74afba8d77474cc1d110a4 -commit 94b9d37100f6fa536aaa1d1a0e4926fe44fbf04d +commit 683d0abe596b069a896f1688f86256f1beeb0cdc Author: djm@openbsd.org -Date: Thu Jun 27 22:36:44 2024 +0000 +Date: Mon Sep 1 23:53:16 2025 +0000 - upstream: retire unused API + upstream: Make MaxStartups and PerSourceNetBlockSize first-match-wins - OpenBSD-Commit-ID: 3e30d7b0615e2707f6bbe70f61b1c2f72f78161b - -commit 268c3a7f5783e731ed60f4e28da66ee3743581d3 -Author: jmc@openbsd.org -Date: Thu Jun 27 21:02:16 2024 +0000 - - upstream: ssl(8) no longer contains a HISTORY section; + as advertised. bz3859 reported by jan.v.hofmann; ok dtucker - OpenBSD-Commit-ID: 83b7ff34433d79595e9c2a5d2a561a6660251245 + OpenBSD-Commit-ID: 08f7786f1b3b4a05a106cdbd2dc5f1f2d8299447 -commit 12b6cc09ce6c430681f03af2a8069e37a664690b +commit a9a3f025d76f06a6601e6e8d52b468ec467865d9 Author: djm@openbsd.org -Date: Wed Jun 26 23:47:46 2024 +0000 +Date: Fri Aug 29 03:50:38 2025 +0000 - upstream: move child process waitpid() loop out of SIGCHLD handler; + upstream: remove experimental support for XMSS keys; - ok deraadt + ok deraadt markus - OpenBSD-Commit-ID: 65815a39564e431414aed7c5ace8076f4e9ca741 + OpenBSD-Commit-ID: 38eaf4df6189acad9e46eddf7cf32d7f6d07df35 -commit d6bcd13297c2ab8b528df5a6898f994734849031 -Author: deraadt@openbsd.org -Date: Wed Jun 26 23:16:52 2024 +0000 +commit 908e9d55139bed19ed87d6fec749974eb42702c6 +Author: caspar@openbsd.org +Date: Mon Aug 18 18:39:33 2025 +0000 - upstream: Instead of using possibly complex ssh_signal(), write all - - the parts of the grace_alarm_handler() using the exact things allowed by the - signal-safe rules. This is a good rule of thumb: Handlers should be written - to either set a global volatile sig_atomic_t inspected from outside, and/or - directly perform only safe operations listed in our sigaction(2) manual page. - ok djm markus + upstream: ssh_config.5: say "post-quantum" instead of "post quantum - OpenBSD-Commit-ID: 14168ae8368aab76e4ed79e17a667cb46f404ecd - -commit b8793e2b0851f7d71b97554fa5260b23796d6277 -Author: deraadt@openbsd.org -Date: Wed Jun 26 23:14:14 2024 +0000 - - upstream: save_errno wrappers inside two small signal handlers that + safe", and rephrase the sentence to make it easier to read. - perform system calls, for systems with libc that do perform libc sigtramps. - ok djm markus + Input djm@, input and OK deraadt@, OK dtucker@ - OpenBSD-Commit-ID: 7749b56419a7c9dcfe4c6c04811e429813346c62 + OpenBSD-Commit-ID: c3ee4d1cafdcfc20cc0d2f086021efce4b19c075 -commit f23e9332c4c8df37465c4a4f38275ea98980ed7e -Author: jmc@openbsd.org -Date: Mon Jun 24 06:59:39 2024 +0000 +commit ceca966bde4ab38b2434876416da12fe16747459 +Author: job@openbsd.org +Date: Mon Aug 18 09:16:36 2025 +0000 - upstream: - uppercase start of sentence - correct sentence grammar + upstream: Delete unused accessor function - ok djm + OK dtucker@ - OpenBSD-Commit-ID: 1ec4b0fdb633a43667f2c8fff1d600bd647dde25 + OpenBSD-Commit-ID: 93b59ac088fb254e1189729ece5bb9656d6e810b -commit 1839e3eb71a759aa795602c1e4196300f4ac2615 -Author: djm@openbsd.org -Date: Mon Jun 24 04:05:11 2024 +0000 +commit 3ef1a87d0a29eac94f32371af628e81eb2e2d817 +Author: Damien Miller +Date: Mon Aug 18 17:00:26 2025 +1000 - upstream: mention SshdSessionPath option + Fix pledge(2) special casing - OpenBSD-Commit-ID: c29734d36c21003973b15c1c9965c35f36cef30c - -commit 603193e32aef5db7d60c58066d5de89806e79312 -Author: Darren Tucker -Date: Thu Jun 20 18:45:14 2024 +1000 - - Rerun upstream tests on .sh file changes too. + Unbreaks non-OpenBSD platforms -commit dbbf9337c19381786a8e5a8a49152fe6b80c780d -Author: dtucker@openbsd.org -Date: Thu Jun 20 08:23:18 2024 +0000 +commit 5e9ca80fe65e407428dc46ed45804724d08b91b7 +Author: Damien Miller +Date: Mon Aug 18 16:47:23 2025 +1000 - upstream: Work around dbclient cipher/mac query bug. + Match version instead of groups in connect-bigconf - Unlike earlier versions, recent Dropbear (at least v2024.85) requires - a host arg when querying supported ciphers and macs via "-c/-m - help". Earlier versions accept but do not require it, so always - provide it. If these queries fail, skip the test with a warning. + The connect-bigconf makes a giant config file to test config passing + between the sshd subprocesses. Previously it used a bunch of "Match + group" lines to construct a large file. However checking group + membership can be expensive (e.g. if a large groups database is + present or if group lookup is remote via NSS). This could be slow + enough to exceed LoginGraceTime. - OpenBSD-Regress-ID: 98eb863a3f0363416922efb273885e6b3c7f68d4 + This switches it to "Match version" which is just a string compare + and does just as well for making a giant nonsense config file. -commit 8de2c8cebc46bbdb94b7a2c120fcadfb66a3cccc -Author: dtucker@openbsd.org -Date: Thu Jun 20 08:18:34 2024 +0000 +commit 6c84609e5f9ddd49e250d5cf190b2820dbeca178 +Author: Damien Miller +Date: Mon Aug 18 16:47:00 2025 +1000 - upstream: Remove dropbear key types not supported + depend + +commit 9184fa363687fcb5dac056b093fb3b8e9d327242 +Author: Damien Miller +Date: Mon Aug 18 16:45:15 2025 +1000 + + check for setsockopt IP_TOS in OpenBSD pledge - by current OpenSSH. Allows subsequent test runs to work if OpenSSH is - rebuilt w/out OpenSSL. + OpenBSD has recently relaxed the pledge(2) sandbox to allow some + setsockopt options to be changed without the "inet" promise. - OpenBSD-Regress-ID: e0129eb2b1d31771105903a8055216fbba20a770 + This adds compatibility for OpenBSD that predates this relaxation. -commit e9b6471c59b21e5d9ef1b3832d4bf727338add85 +commit ae44cd74f3a4ac711152f50b2712803ccf785593 Author: djm@openbsd.org -Date: Thu Jun 20 00:18:05 2024 +0000 +Date: Mon Aug 18 04:50:35 2025 +0000 - upstream: stricter check for overfull tables in penalty record path + upstream: cast - OpenBSD-Commit-ID: 7df01e648a0723418c554e64a9f2b6d38db060a6 + OpenBSD-Commit-ID: d69bd2328513c2dcd99f4f346b77e2bd90cf1964 -commit d9336d344eb2a1e898c5e66147b3f108c7214694 +commit c2c8bae39380392449ac3297061cbfc486126ad5 Author: djm@openbsd.org -Date: Wed Jun 19 23:24:47 2024 +0000 +Date: Mon Aug 18 04:38:21 2025 +0000 - upstream: put back reaping of preauth child process when writes + upstream: missing set_log_handler() call in ssh-auth.c, exposed after - from the monitor fail. Not sure how this got lost in the avalanche of - patches. + last commit - OpenBSD-Commit-ID: eb7eb36371e1ac01050b32b70fb2b3e5d98e72f5 + OpenBSD-Commit-ID: 09f5c3cf33c18b8ad321edbf96c30ae3deada2b0 -commit 579d9adb70ec0206a788eb5c63804c31a67e9310 -Author: naddy@openbsd.org -Date: Mon Jun 17 13:50:18 2024 +0000 +commit 056022261e6cf7eb65bbacac72afe5f4d5945f2c +Author: Damien Miller +Date: Mon Aug 18 14:22:32 2025 +1000 - upstream: remove one more mention of DSA - - OpenBSD-Commit-ID: 8515f55a15f02836ba657df341415f63c60526ca + depend -commit 7089b5f8436ef0b8d3d3ad9ce01045fb9e7aab15 -Author: Darren Tucker -Date: Wed Jun 19 23:09:05 2024 +1000 +commit b7ee13fbbb4ebafcf71f29685f053ecb97d1bcef +Author: Damien Miller +Date: Mon Aug 18 14:22:18 2025 +1000 - Move -f to the place needed to restart sshd. + wrap SIGINFO in ifdef -commit d5f83cfd852b14a25f347f082ab539a9454702ad -Author: Darren Tucker -Date: Wed Jun 19 21:04:01 2024 +1000 +commit 289239046b2c4b0076c14394ae9703a879e78706 +Author: djm@openbsd.org +Date: Mon Aug 18 03:43:01 2025 +0000 - Need to supply "-f" to restart sshd. + upstream: Make ssh(1) and sshd(8) set IP QoS (aka IP_TOS, IPV6_TCLASS) + + continually at runtime based on what sessions/channels are open. + + Previously, ssh(1) and sshd(8) would pick a QoS value when they + were started and use it for the whole connection. This could + produce suboptimal choices for the QoS value, e.g. for multiplexed + sessions that started interactive but picked up a sftp client, + or sessions that moved large amounts of data via port forwarding. + + Now the QoS value will change to the non-interactive IPQoS whenever + a "non-interactive" channel is open; basically any channel that lacks + a tty other than agent forwarding. + + This is important now that the default interactive IPQoS is EF + (Expedited Forwarding), as many networks are configured to allow + only relatively small amounts of traffic of this class and they will + aggressively deprioritise the entire connection if this is exceeded. + + NB. because ssh(1) and sshd(8) now change IP_TOS/IPV6_TCLASS + continually via setsockopt(), this commit requires a recent pledge(2) + change that landed recently in the OpenBSD kernel. Please ensure + you have updated to a kernel from within the last two weeks before + updating OpenSSH. + + with job@ deraadt@ + + OpenBSD-Commit-ID: 325fc41717eecdf5e4b534bfa8d66817425b840f -commit fad34b4ca25c0ef31e5aa841d461b6f21da5b8c1 -Author: dtucker@openbsd.org -Date: Wed Jun 19 10:15:51 2024 +0000 +commit dc5147028ff19213a32281dad07bba02e58da3fa +Author: djm@openbsd.org +Date: Mon Aug 18 03:29:11 2025 +0000 - upstream: Provide defaults for ciphers and macs + upstream: SIGINFO handler for sshd(8) to dump active - if querying for them fails since on some versions of Dropbear (at least - v2024.85) "-m help" doesn't seem to work. Enable all supported pubkey - algorithms in the server. + channels/sessions ok deraadt@ - OpenBSD-Regress-ID: 4f95556a49ee9f621789f25217c367a33d2745ca + OpenBSD-Commit-ID: 9955cb6d157c6d7aa23a819e8ef61b1edabc8b7d -commit 5521060e35ada9f957cecdddc06d0524e75409ef -Author: dtucker@openbsd.org -Date: Wed Jun 19 10:10:46 2024 +0000 +commit f807a598c96be683d97810481e954ec9db6b0027 +Author: djm@openbsd.org +Date: Mon Aug 18 03:28:36 2025 +0000 - upstream: Use ed25519 keys for kex tests + upstream: SIGINFO handler for ssh(1) to dump active - since that's supported by OpenSSH even when built without OpenSSL. - Only test diffie-hellman kex if OpenSSH is compiled with support for it. + channels/sessions ok deraadt@ - OpenBSD-Regress-ID: a5d09ef9bbd171f9e4ec73ed0d9eeb49a8878e97 + OpenBSD-Commit-ID: 12f88a5044bca40ef5f41ff61b1755d0e25df901 -commit dbd3b833f6e3815e58f2dc6e14f61a51bcd4d6bd -Author: dtucker@openbsd.org -Date: Wed Jun 19 10:08:34 2024 +0000 +commit 9b61679d73a8a001c25ab308db8a3162456010cf +Author: djm@openbsd.org +Date: Mon Aug 18 03:28:02 2025 +0000 - upstream: Rework dropbear key setup + upstream: add channel_report_open() to report (to logs) open - to always generate ed25519 keys, other types only if OpenSSH has support - for the corresponding key type. + channels; ok deraadt@ (as part of bigger diff) - OpenBSD-Regress-ID: 8f91f12604cddb9f8d93aa34f3f93a3f6074395d + OpenBSD-Commit-ID: 7f691e25366c5621d7ed6f7f9018d868f7511c0d -commit d6218504e11ae9148adf410fc69b0710a052be36 -Author: Darren Tucker -Date: Wed Jun 19 20:20:24 2024 +1000 +commit 80b5ffd22abd4093201939e31d1ea6dc8cc7913a +Author: djm@openbsd.org +Date: Mon Aug 18 01:59:53 2025 +0000 - Restart sshd after installing it for testing. + upstream: make -E a no-op in sshd-auth. Redirecting logging to a - When installing an sshd built without OpenSSL the mismatch between - the running sshd and newly installed sshd-session will cause the - remainder of the test to fail. + file doesn't work in this program as logging already goes via the parent + sshd-session process. ok dtucker@ + + OpenBSD-Commit-ID: 73325b9e69364117c18305f896c620a3abcf4f87 -commit 786a4465b6bb702daf4fb17b7c3bcb42b52f0b46 -Author: Darren Tucker -Date: Tue Jun 18 19:59:59 2024 +1000 +commit 3a039108bd25ff10047d7fa64750ed7df10c717c +Author: Damien Miller +Date: Mon Aug 18 13:46:37 2025 +1000 - Remove macos-11 runner. + allow some socket syscalls in seccomp sandbox - Github is retiring them soon. + Allow getsockname(2), getpeername(2) and getsockopt(2). + + Also allow setsockopt(2) but only IP_TOS and IPV6_TCLASS. + + Note that systems that use the older socketcall(2) mux syscall will + not have IP_TOS and IPV6_TCLASS allowlisted. On these platforms, + these calls will be soft-blocked (i.e. will fail rather than + terminate the whole process with a sandbox violation). + + Needed for upcoming IPQoS change; ok dtucker@ -commit df1c72a55edbebac14363b57de66ac6a147ecc67 +commit a00f5b02e171bc6d6fb130050afb7a08f5ece1d8 Author: Damien Miller -Date: Wed Jun 19 09:34:34 2024 +1000 +Date: Mon Aug 18 13:44:53 2025 +1000 - PAMServiceName may appear in a Match block + handle futex_time64 properly in seccomp sandbox + + Previously we only allowed __NR_futex, but some 32-bit systems + apparently support __NR_futex_time64. We had support for this + in the sandbox, but because of a macro error only __NR_futex was + allowlisted. + + ok dtucker@ -commit de1c2e70e5a5dc3c8d2fe04b24cc93d8ef6930e7 +commit 32deb00b38b4ee2b3302f261ea1e68c04e020a08 Author: dtucker@openbsd.org -Date: Tue Jun 18 08:11:48 2024 +0000 +Date: Thu Aug 14 10:03:44 2025 +0000 - upstream: Re-enable ssh-dss tests + upstream: Cast serial no for %lld to prevent compiler warnings on some - ... if ssh is compiled with DSA support + platforms. - OpenBSD-Regress-ID: bbfaf8c17f2b50a2d46ac35cb97af99b990c990d + OpenBSD-Commit-ID: afadd741622f16c6733d461c0d6053ed52868a57 -commit dabc2c7cf3c141e8e5d5a1a60d6c1d2d2422cf43 -Author: anton@openbsd.org -Date: Tue Jun 18 06:14:27 2024 +0000 +commit 883886c959ecab152650e231335857eb3193c662 +Author: dtucker@openbsd.org +Date: Thu Aug 14 09:44:39 2025 +0000 - upstream: Stop using DSA in dropbear interop tests. + upstream: Cast serial no for %lld to prevent compiler warnings on some - OpenBSD-Regress-ID: abfd4457d99d8cc1417fd22ca2c570270f74c1cf + platforms. + + OpenBSD-Commit-ID: 46c6063284d318f7e4dc922479a3e394c94b0588 -commit 761438012710169445acc179e3870c53c862bda0 -Author: Damien Miller -Date: Tue Jun 18 12:29:45 2024 +1000 +commit fde5a4d2cd01bea700439fa6d5bbad88e65c99bd +Author: dtucker@openbsd.org +Date: Thu Aug 14 09:26:53 2025 +0000 - missed a bit of DSA in the fuzzer + upstream: Cast serial no for %lld to prevent compiler warnings on some + + platforms. + + OpenBSD-Commit-ID: 15644234b58abc9c6da2994f0422a5aa344a9e89 -commit 3f9cc47da588e8de520720e59f98438043fdaf93 -Author: Damien Miller -Date: Tue Jun 18 09:35:53 2024 +1000 +commit ab5074dfb614e3801fecbd376d8ed4cea613c629 +Author: sthen@openbsd.org +Date: Tue Aug 12 11:09:48 2025 +0000 - DSA support is disabled, so remove from fuzzers + upstream: fix typo, ok markus dtucker + + OpenBSD-Commit-ID: 8f223da7633752162c64a659c6cf55202703d870 -commit 00eb95957dea5484b2c7c043f7d2bbc87301bef2 -Author: djm@openbsd.org -Date: Mon Jun 17 08:30:29 2024 +0000 +commit 8b6c1f402feb9eb6438003a312d7ffe8d5669896 +Author: deraadt@openbsd.org +Date: Mon Aug 11 14:37:43 2025 +0000 - upstream: disable the DSA signature algorithm by default; ok + upstream: Handle localtime_r() failure by return "UNKNOWN-TIME" - markus@ - - (yes, I know this expands to "the Digitial Signature Algorithm - signature algorithm) + which is only used in user-visible contexts. freebsd 288773 shows their + localtime_r() has failed at least once for unknown reason. discussed with djm - OpenBSD-Commit-ID: 961ef594e46dd2dcade8dd5721fa565cee79ffed + OpenBSD-Commit-ID: 68f4c92d46b2578d4594b0ed940958d597fd61ac -commit 5603befe11c9464ea26fe77cbacc95a7cc0b1ea7 +commit 0e1b8aa27f7c86d412c9e54ad9e2cae30d9ddab4 Author: djm@openbsd.org -Date: Mon Jun 17 08:28:31 2024 +0000 +Date: Mon Aug 11 10:55:38 2025 +0000 - upstream: promote connection-closed messages from verbose to info + upstream: ssh(1): add a warning when the connection negotiates a - log level; they could be the only record of the connection terminating if the - client doesn't send a SSH2_MSG_DISCONNECT message. ok dtucker@ + non-post quantum safe key agreement algorithm. - OpenBSD-Commit-ID: 0c8bfaf5e9fdff945cee09ac21e641f6c5d65d3c - -commit b00331402fe5c60d577f3ffcc35e49286cdc6b47 -Author: Damien Miller -Date: Mon Jun 17 17:02:18 2024 +1000 - - propagate PAM crashes to PerSourcePenalties + Controlled via a new WarnWeakCrypto ssh_config option, defaulting + to on. This option might grow additional weak crypto warnings in + the future. - If the PAM subprocess crashes, exit with a crash status that will be - picked up by the sshd(8) listener process where it can be used by - PerSourcePenalties to block the client. This is similar handling to - the privsep preauth process. - -commit 1c207f456ace38987deda047758d13fbf857f948 -Author: Damien Miller -Date: Mon Jun 17 15:06:01 2024 +1000 - - minix doesn't have loopback, so skip penalty tests + More details at https://openssh.com/pq.html - pointed out by dtucker@ + mostly by deraadt@ feedback dtucker@ ok deraadt@ + + OpenBSD-Commit-ID: 974ff243a1eccceac6a1a9d8fab3bcc89d74a2a4 -commit 48443d202eaec52d4d39defdd709a4499a7140c6 +commit 2ebc6384258b58ace0ad2adb2593744f62749235 Author: djm@openbsd.org -Date: Sun Jun 16 11:54:49 2024 +0000 +Date: Wed Aug 6 23:44:09 2025 +0000 - upstream: same treatment for this test + upstream: all state related to the ssh connection should live in - OpenBSD-Regress-ID: d0cc9efca7833e673ea7b0cb3a679a3acee8d4c7 + struct ssh or struct packet_state; one static int escaped this rule, so move + it to struct packet_state now. + + ok millert tb + + OpenBSD-Commit-ID: bd6737168bf61a836ffbdc99ee4803468db90a53 -commit 45562a95ea11d328c22d97bf39401cd29684fb1f -Author: djm@openbsd.org -Date: Sun Jun 16 08:18:06 2024 +0000 +commit 60b909fb110f77c1ffd15cceb5d09b8e3f79b27e +Author: dtucker@openbsd.org +Date: Wed Aug 6 11:22:53 2025 +0000 - upstream: penalty test is still a bit racy + upstream: Improve sentence. ok djm@ - OpenBSD-Regress-ID: 90c9ac224db454637baf1ebee5857e007321e824 + OpenBSD-Commit-ID: 9c481ddd6bad110af7e530ba90db41f6d5fe2273 -commit 8d0f7eb147ef72d18acb16c0b18672d44941a8ca +commit 9ffa98111dbe53bf86d07da8e01ded8c5c25456b Author: djm@openbsd.org -Date: Sat Jun 15 03:59:10 2024 +0000 +Date: Wed Aug 6 04:53:04 2025 +0000 - upstream: crank up penalty timeouts so this should work on even the + upstream: when refusing a certificate for user authentication, log - slowest of test builders + enough information to identify the certificate in addition to the reason why + it was being denied. Makes debugging certificate authz problems a bit easier. - OpenBSD-Regress-ID: 70bda39c83e3fc9d0f3c1fad4542ed33e173d468 + ok dlg@ + + OpenBSD-Commit-ID: 4c4621b2e70412754b3fe7540af8f4bf02b722b1 -commit 93c75471a1202ab3e29db6938648d4e2602c0475 -Author: jmc@openbsd.org -Date: Fri Jun 14 05:20:34 2024 +0000 +commit 2a31009c36eb2da412c2784fe131fcb6ba800978 +Author: job@openbsd.org +Date: Tue Aug 5 09:08:16 2025 +0000 - upstream: sort -q in the options list; + upstream: Use the operating system default DSCP marking for - OpenBSD-Commit-ID: 6839b38378f38f754de638a5e988c13b4164cc7c + non-interactive traffic + + It seems the CS1 traffic class mark is considered ambiguous and therefore + somewhat unhelpful (see RFC 8622 for more considerations). But, the new + 'LE' scavenger class (also proposed in RFC 8622) offers high probability + of excessive delays & high packet loss, which would be inappropriate + for use with, for example, X11 forwardings. In fact, it is not known to + SSH what's appropriate because SSH is not aware of the content of what + passing through session forwardings. Therefore, no marking is appropriate. + Non-interactive traffic simply is best effort. + + OK djm@ deraadt@ + + OpenBSD-Commit-ID: db1da1a432ecd53fc28feb84287aedb6bec80b01 -commit dd7807bbe80a93ffb4616f2bd5cf83ad5a5595fb +commit 6ebd472c391a73574abe02771712d407c48e130d Author: djm@openbsd.org -Date: Fri Jun 14 05:01:22 2024 +0000 +Date: Tue Aug 5 04:00:15 2025 +0000 - upstream: clarify KEXAlgorithms supported vs available. Inspired by + upstream: a bunch of the protocol extensions we support now have RFCs - bz3701 from Colin Watson. + and I-Ds that are more complete and detailed than what we have in the + PROTOCOL.* files. Refer to these when possible instead of documenting them + here. - OpenBSD-Commit-ID: e698e69bea19bd52971d253f2b1094490c4701f7 + OpenBSD-Commit-ID: 4fa5b0fcf5d5f24093d33d9e82c7ca4850d50d70 -commit d172ad56df85b68316dbadbedad16761a1265874 -Author: djm@openbsd.org -Date: Fri Jun 14 05:00:42 2024 +0000 +commit ec3465f59c651405e395092f3ad606f8992328d8 +Author: job@openbsd.org +Date: Thu Jul 31 11:23:39 2025 +0000 - upstream: ssh-keyscan -q man bits + upstream: Deprecate support for IPv4 type-of-service (TOS) IPQoS - OpenBSD-Commit-ID: ba28d0e1ac609a4c99c453e57e86560c79079db1 - -commit 092e4ff9ccaacbe035f286feb1b56ed499604743 -Author: Damien Miller -Date: Fri Jun 14 14:46:35 2024 +1000 - - skip penalty-expire test in valgrind test env + keywords + + Type of Service (ToS) was deprecated in the late nineties and replaced + with the Differentiated Services architecture. Diffserv has significant + advantages for operators because this mechanism offers more granularity. + + OpenSSH switched its default IPQoS from ToS to DSCP values in 2018. + + IPQoS configurations with 'lowdelay', 'reliability', or 'throughput' will be + ignored and instead the system default QoS settings apply. Additionally, a + debug message is logged about the deprecation with a suggestion to use DSCP. + + with/OK deraadt@ sthen@ djm@ + + OpenBSD-Commit-ID: 40c8c0c5cb20151a348728703536af2ec1c754ba -commit 2866ad08a9c50d7b67ce9424ca990532b806a21a -Author: djm@openbsd.org -Date: Fri Jun 14 04:43:11 2024 +0000 +commit 65909fa114e7dd7511800db2b7bacb8774afe887 +Author: job@openbsd.org +Date: Thu Jul 31 09:38:41 2025 +0000 - upstream: split the PerSourcePenalties test in two: one tests penalty + upstream: Set default IPQoS for interactive sessions to Expedited - enforcement but not penalty expiry, the other tests penalty expiry. + Forwarding (EF) - This lets us disable the expiry testing in certain CI test environments. + Marking interactive session data with DSCP value EF (RFC3246, RFC3247) + helps inform the network on relative priority compared to other traffic. + This is especially useful for differentiated treatment over wireless media. - OpenBSD-Regress-ID: f56811064f3e3cb52ee73a206b8c2a06af1c8791 + Following the reconciled IETF Diffserv to IEEE 802.11 mappings (RFC 8325), + traffic marked with DSCP value EF maps to User Priority 6 in QoS Control, + in turn mapping to the high priority WMM AC_VO access category. + + OK djm@ + + OpenBSD-Commit-ID: aadda7b9da794d70d7c6b381a861a0610afce1b3 -commit b2c64bc170d75823622a37cab3ca1804ca87ad16 -Author: Damien Miller -Date: Fri Jun 14 14:19:23 2024 +1000 +commit d1c6c67a50fc957010fa027c6ab970424e9b9142 +Author: Darren Tucker +Date: Sat Aug 2 14:49:00 2025 +1000 - add a sshd_config PamServiceName option + Disable security key tests for bigendian interop + +commit e85248df3f1073343da87a6b00512e6a1e4a863d +Author: Darren Tucker +Date: Sat Aug 2 12:51:42 2025 +1000 + + Comment out atime restore test. - Allows selecting which PAM service name to use when UsePAM is - enabled. Defaults to "sshd" unless overridden at compile time - by defining SSHD_PAM_SERVICE. + This works on filesystems mounted 'noatime', but on others the stat() + resets atime causing the test to fail. + +commit b1c4cedbee107dc611ce091f27ea9f1de28ee378 +Author: Darren Tucker +Date: Fri Aug 1 19:29:00 2025 +1000 + + Replace fbsd64ppc VM with physical host. - bz2102, ok dtucker@ + Run 64bit bigendian interop test on NetBSD arm64be instead. -commit 9f032a4dd17bf0ae6066223d82aa5e784285d987 -Author: djm@openbsd.org -Date: Fri Jun 14 00:26:12 2024 +0000 +commit 284abbed9a8d815b1ec5e96aff885d77e26537e7 +Author: dtucker@openbsd.org +Date: Wed Jul 30 10:17:13 2025 +0000 - upstream: don't redirect stderr for ssh-keyscan we expect to succeed + upstream: Plug leak in case where sigp is passed as NULL. Coverity CID - OpenBSD-Regress-ID: 8878b8eb4e070ed2e343166d3eb86db4a08a216c + 483725, ok djm@ + + OpenBSD-Commit-ID: 47cf7b399c84e102b670b9f97ab6926c9a7256b5 -commit 1e84d0cf40e94ae3a77d6a7ca8c036d8e3d55a40 +commit dc630e6d81be8aa495254839731e4f3521cf9e31 Author: djm@openbsd.org -Date: Fri Jun 14 00:25:25 2024 +0000 +Date: Wed Jul 30 04:27:42 2025 +0000 - upstream: make host/banner comments go to stderr instead of stdout, - - so they are useful as comments without extra shell redirection and so they - don't clutter actual errors on stderr. + upstream: unbreak WITH_OPENSSL=no builds, also allowing ed25519 - Add a -q flag to shut them up. + keys to be used via PKCS#11 when OpenSSH is built without libcrypto. - ok dtucker@ + OpenBSD-Commit-ID: ecf26fdf7591bf2c98bac5136fbc36e0b59c3fc2 + +commit a5bec2cdfc4f38ddb6211809851aae29ba99a35a +Author: djm@openbsd.org +Date: Wed Jul 30 04:19:17 2025 +0000 + + upstream: fix variable name in disabled code - OpenBSD-Commit-ID: bec813de56a71adb5c1a76adcf49621130d24264 + OpenBSD-Commit-ID: 5612e979575d5da933c8b720d296423fd84392f5 -commit 3e806d011855d6bd648ec95b9df630ebbd11c3bf -Author: naddy@openbsd.org -Date: Thu Jun 13 15:06:33 2024 +0000 +commit 5e4bfe6c16924b1c21a733f3e218cfcba98e301e +Author: Damien Miller +Date: Sat Jul 26 19:19:46 2025 +1000 - upstream: separate keywords with comma + more ec/ed25519 fixing + +commit 2603098959eff55cbe188c3dfcbe5302808a80fc +Author: Damien Miller +Date: Sat Jul 26 14:27:53 2025 +1000 + + repair build for libcrypto without ed25519 support + +commit a729163c56ecc002c0cb04db56e7d86ceec2e8b0 +Author: djm@openbsd.org +Date: Sat Jul 26 01:53:31 2025 +0000 + + upstream: regression tests for Ed25519 keys in PKCS#11 tokens - OpenBSD-Commit-ID: d65a99666202a8188c4991c18d14374a229f7be5 + OpenBSD-Regress-ID: 50067c0716abfea3a526b4a0c8f1fe15e7665c0f -commit abfd1f7a3cbd0a92581a0febba254b2f6649c0d9 +commit 361ff0ca308ac02449e71689fc5ea72114db43db Author: djm@openbsd.org -Date: Fri Jun 14 00:23:55 2024 +0000 +Date: Sat Jul 26 01:51:44 2025 +0000 - upstream: specify an algorithm for ssh-keyscan, otherwise it will make + upstream: Support ed25519 keys hosted on PKCS#11 tokens. - multiple attempts simultaneously and confuse the test + Tested on Yubikeys and against SoftHSM2. - OpenBSD-Regress-ID: 6e910f3315c4345053db1bf5cbf61826b194d0b9 + feedback/ok tb@ + + OpenBSD-Commit-ID: 90ddb6529f2e12e98e8bba21d8592e60579ce2e4 -commit a8fbe2f7d0d96d299ee8e69769e3b51067978748 -Author: Damien Miller -Date: Thu Jun 13 16:41:29 2024 +1000 +commit 2b530cc3005a71c5ba6b712978872fc9c147439c +Author: djm@openbsd.org +Date: Fri Jul 25 13:06:07 2025 +0000 - sshd: don't use argv[0] as PAM service name - - sshd would implicitly use argv[0] as the PAM service name to - allow people to select different PAM service names by making - differently-named copies/links to the sshd binary. + upstream: update our PKCS#11 API header to v3.0; - Splitting sshd into sshd/sshd-session broke this, as the process - that starts PAM is always sshd-session and the user has no control - over this. + feedback/ok tb@ - Hardcode "sshd" as the default PAM service name unless/until we - figure out a better way. Should unbreak OSX integration tests. + OpenBSD-Commit-ID: e67fa6a26e515c2b1fb7b0d1519d138aafb3e017 -commit bf204bd05c3ae650f87e2b96527688579f59774c +commit 550d2a4a66c50f7641563a63b900761d99efb24a Author: Damien Miller -Date: Thu Jun 13 15:00:28 2024 +1000 +Date: Fri Jul 25 23:04:33 2025 +1000 - prepare for checking in autogenerated files + another attempt at fixing !EC builds + +commit ed1e370d84e9dc39bc31c19cca12222d991fdc6f +Author: dtucker@openbsd.org +Date: Fri Jul 25 11:50:45 2025 +0000 + + upstream: Don't snprintf a NULL since not all platforms support it. - We plan to check in automatically generated files (config.h.in, etc) on - release branches. These files are normally ignored by .gitignore, but - this shuffles the contents of this file to make it easy to un-ignore - them. + OpenBSD-Commit-ID: 6e0c268e40047e96fab6bc56dc340580b537183b -commit 425f79a837489904c343b349ef00e09aeaa4e752 +commit eedab8db12d57c4f4583f6b60e48a4ce25b47b9c Author: Damien Miller -Date: Thu Jun 13 14:41:33 2024 +1000 +Date: Fri Jul 25 16:21:43 2025 +1000 - typo in comment + unbreak !EC builds -commit afe10313c1fa8d478af399ee7d54c8f85503013b -Author: Damien Miller -Date: Thu Jun 13 14:35:25 2024 +1000 +commit 203f5ac6cfa0e257db7509d4bb830e8a4bba6211 +Author: djm@openbsd.org +Date: Thu Jul 24 06:04:47 2025 +0000 - fix PTY allocation on Cygwin, broken by sshd split - - Cygwin doesn't support FD passing and so used to disable post-auth - privilege separation entirely because privsep requires PTY allocation - to happen in the privileged monitor process with the PTY file - descriptors being passed back to the unprivileged process. - - This brings back a minimal version of the previous special treatment - for Cygwin (and any other platform that sets DISABLE_FD_PASSING): - privilege separation remains enabled, but PTY allocation happens in - the post-auth user process rather than the monitor. + upstream: test code now needs to link ssh-pkcs11-client.c any time - This either requires PTY allocation to not need privilege to begin - with (this appears to be the case on Cygwin), or the post-auth - privsep process retain privilege (other platforms that set the - DISABLE_FD_PASSING option). + sshkey.c is included - Keeping privileges here is bad, but the non-Cygwin systems that set - DISABLE_FD_PASSING are so deeply legacy that this is likely to be the - least of their problems. + OpenBSD-Regress-ID: 9d07188eae9a96801c3150b3433bb220626d4443 -commit f66d4df5749551380a8c4ae642347675a0b6a2e9 +commit 33b4f05c8ddab24aa6c47afb313b8cbd0d4b77f4 Author: Damien Miller -Date: Thu Jun 13 11:33:09 2024 +1000 +Date: Fri Jul 25 12:47:17 2025 +1000 - delay lookup of privsep user until config loaded - - sshd-session attempting to use options.kerberos_authentication to - decide whether it needed to lookup the privsep user before the - configuration was loaded. This caused it to get a placeholder value - that caused it always to try to lookup the privsep user, breaking at - least one test environment. + update clang-16 -> clang-19 -commit f1c42858b94f5d9b58867b34dce3afb39c6b56a8 +commit 03e9e993ef1ef5accc6457152278cab5988f9b3d Author: Damien Miller -Date: Thu Jun 13 11:16:57 2024 +1000 +Date: Fri Jul 25 12:46:59 2025 +1000 - missing file for PerSourcePenalties regress test + include ssh-pkcs11-client.o as common dep -commit 4de80ff4e6fab5a6bb0028e7d57c6c23d1485adb -Author: djm@openbsd.org -Date: Wed Jun 12 22:36:00 2024 +0000 +commit 2f5269938a8e4769f484c9d45419a86529078ede +Author: Damien Miller +Date: Fri Jul 25 12:46:10 2025 +1000 - upstream: split PerSourcePenalties address tracking. Previously it - - used one shared table and overflow policy for IPv4 and IPv6 addresses, now it - will use separate tables and optionally different overflow policies. - - This prevents misbehaviour from IPv6 addresses (which are vastly easier - to obtain many of) from affecting IPv4 connections and may allow for - stricter overflow policies. - - ok deraadt@ - - OpenBSD-Commit-ID: 12637ed0aa4d5f1f3e702da42ea967cbd8bfdfd9 + remove vestigial stub -commit 06ab4c6931b0aaa4334db2faaa7e1069e76d0df6 -Author: jmc@openbsd.org -Date: Tue Jun 11 05:24:39 2024 +0000 +commit bf33a73c40522ce60961d4fff316a7187fb06ca0 +Author: djm@openbsd.org +Date: Thu Jul 24 23:27:04 2025 +0000 - upstream: do not mark up "(default: 20ms)"; + upstream: this should include stdlib.h explicitly - OpenBSD-Commit-ID: 54151ecdecfa1b67dcdda4fd24826ef6e2148ad4 + OpenBSD-Commit-ID: 1c0cc5c3838344b33ae4ab7aa62c01530357bf29 -commit cfe243cd9fde148ed060637876e27bb55ac78be9 +commit 9f8ccc3b81b53324cc489f3fe00f03c329c0acb2 Author: djm@openbsd.org -Date: Tue Jun 11 02:54:51 2024 +0000 +Date: Thu Jul 24 06:59:51 2025 +0000 - upstream: reap preauth net child if it hangs up during privsep message + upstream: less stale reference to PKCS#1 1.5 hash OIDs; feedback - send, not just message receive + from tb@ - OpenBSD-Commit-ID: 02a093f4ab4f8f83f0cd1ea2bb35b9ca420448f0 + OpenBSD-Commit-ID: 9fda77978491a130a7b77d87d40c79277b796721 -commit b0a711c00b9c64afd1c9d6fb538275c6604a2676 +commit 1641ab8744f500f55f12155d03f1a3116aaea374 Author: djm@openbsd.org -Date: Tue Jun 11 01:58:27 2024 +0000 +Date: Thu Jul 24 06:12:08 2025 +0000 - upstream: fix PIDFILE handling, broken for SUDO=doas in last commit + upstream: factor out encoding of a raw ed25519 signature into its - here + ssh form into a separate function - OpenBSD-Regress-ID: 96fec579af228f87a036e94801eb294af9074625 + OpenBSD-Commit-ID: 3711c6d6b52dde0bd1f17884da5cddb8716f1b64 -commit 90fb801e2d9241be50a2a7ff79428386442a041f +commit a8c0e5c871c0c7ee5ae93e353b1499a53c09c71d Author: djm@openbsd.org -Date: Tue Jun 11 02:00:30 2024 +0000 +Date: Thu Jul 24 05:44:55 2025 +0000 - upstream: reap the pre-auth [net] child if it hangs up during privsep + upstream: Help OpenSSH's PKCS#11 support kick its meth habit. - message sending, not just receiving + The PKCS#11 code in OpenSSH used the libcrypto public key method API + (e.g. the delightfully named RSA_meth_free()) to delegate signing + operations to external keys. This had one advantage - that it was + basically transparent to callers, but also had a big disadvantage - + that we'd manually have to track the method implementations, their + state and their relationships to the underlying PKCS#11 objects. - OpenBSD-Commit-ID: f7341605bf08c4c15830910446e6775323f2f8cb + This rips this out and replaces it with explicit delegation to + PKCS#11 code for externally hosted keys via the ssh-pkcs11-helper + subprocess. This is very similar to how we handle FIDO keys in + OpenSSH (i.e. via ssh-sk-helper). All we need to track now is a + much simpler mapping of public key -> helper subprocess. + + Kicking our libcrypto meth dependency also makes it much easier + to support Ed25519 keys in PKCS#11, which will happen in a subsequent + commit. + + feedback / ok tb@ + + OpenBSD-Commit-ID: a5a1eaf57971cf15e0cdc5a513e313541c8a35f0 -commit ef878d58798f6688c7f4d4e417dc0c29023ea831 -Author: djm@openbsd.org -Date: Tue Jun 11 01:23:25 2024 +0000 +commit 259c66aebe4e1f9d60e548f728ff74083bcccddf +Author: Darren Tucker +Date: Thu Jul 24 22:02:49 2025 +1000 - upstream: a little more RB_TREE paranoia + Remove DEBUG_ACTIONS variable. - OpenBSD-Commit-ID: 8dc2fd21eebd8830c4a4d25461ac4fe228e11156 + If needed it can be set in github if needed. -commit fc4e96b2174d6a894d2033421699d091679baced +commit 40fb2dc4ece76c8f0c624d90a17bc1bbf47f3729 Author: djm@openbsd.org -Date: Tue Jun 11 01:22:25 2024 +0000 +Date: Wed Jul 23 05:07:19 2025 +0000 - upstream: fix off-by-one comparison for PerSourcePenalty + upstream: add a ssh_config RefuseConnection option that, when - OpenBSD-Commit-ID: af4f5d01c41ef870b23e55655bfbf73474a6c02b + encountered while processing an active section in a configuration file, + terminates ssh(1) with an error message that contains the argument to the + option. + + This may be useful for expressing reminders or warnings in config + files, for example: + + Match host foo + RefuseConnection "foo is deprecated, use splork instead" + + ok djg + + OpenBSD-Commit-ID: 5b0072fcd08ad3932ab21e27bbaa66b008d44237 -commit 82c836df4ff41145553cd7adb11c5b985aeaa06f -Author: djm@openbsd.org -Date: Tue Jun 11 01:21:41 2024 +0000 +commit defc806574d2256036d69a291caf0f3484844de6 +Author: miod@openbsd.org +Date: Sat Jul 12 05:28:33 2025 +0000 - upstream: move tree init before possible early return + upstream: Add missing inter-library dependencies to LDADD and - OpenBSD-Commit-ID: 72e2c5b69f151c08a7c5bf5ad929b97a92c273df + DPADD. ok tb@ deraadt@ + + OpenBSD-Commit-ID: a05e13a7e2c0b65bb4b47184fef731243431c6ff -commit a2300f015cc4939c4d9c564b58b74e71202dc978 -Author: djm@openbsd.org -Date: Tue Jun 11 01:07:35 2024 +0000 +commit e6805e2a6b33e001e1a7257b85ab779fd592a578 +Author: Jan Tojnar +Date: Thu May 18 16:30:35 2023 +0200 - upstream: update to mention that PerSourcePenalties default to + Add gnome-ssh-askpass4 for GNOME 40+ - being enabled and document the default values for each parameter. + GTK 3 has been in maintenance mode for a while now, and it is on the road + to being abandoned. As a result, the dialogue looks out of place on modern + systems. - OpenBSD-Commit-ID: b981288bddfb097aad269f62df4081c688ce0034 + We could port it to GTK 4 but without the program being registered as an + application (i.e. having a .desktop file), GNOME Shell would ask for + permission to grab input every time. + + Let’s instead use the GNOME Shell’s native prompt through the unstable + Gcr API. -commit 41987efd356d3fc30139aeab4b09374acf8f91a0 -Author: djm@openbsd.org -Date: Tue Jun 11 00:44:52 2024 +0000 +commit f9dc519259804702cab0fa0ca8b193a360e3ec38 +Author: Damien Miller +Date: Fri Jul 11 17:20:27 2025 -0700 - upstream: reap the [net] child if it hangs up while writing privsep + let ga_init() fail gracefully if getgrouplist does - message payloads, not just the message header + Apparently getgrouplist() can fail on OSX for when passed a non-existent + group name. Other platforms seem to return a group list consisting of + the numeric gid passed to the function. - OpenBSD-Commit-ID: 24dbd400aa381ac96be7ed2dd49018487dfef6ce + This makes ga_init() handle this failure case gracefully, where it will + return success but with an empty group list array. + + bz3848; ok dtucker@ -commit 6211aa085fa91155a24922e5329576ac9a8f3175 +commit f01a899b92ab8c5e6ff71214658bd09636c47e87 Author: djm@openbsd.org -Date: Tue Jun 11 00:40:21 2024 +0000 +Date: Fri Jul 11 23:26:59 2025 +0000 - upstream: log waitpid() status for abnormal exits + upstream: add a "Match Group NoSuchGroup" to exercise groupaccess.c - OpenBSD-Commit-ID: b317930e06b51819c1a2bc6a4359764fecfb1c2d + OpenBSD-Regress-ID: 7ff58e6f0eb21eb9064dd0cfa78c3b6f34b5f713 -commit a59634c7adb9ae988748d99963dfafb3070d8d41 +commit 1052fa62b35e0bb25b0c1efb9fdd7870e4a68ab6 +Author: Damien Miller +Date: Fri Jul 11 15:36:49 2025 -0700 + + more diagnostics when getgrouplist fails + +commit eddd1d2daa64a6ab1a915ca88436fa41aede44d4 Author: djm@openbsd.org -Date: Tue Jun 11 00:36:20 2024 +0000 +Date: Fri Jul 4 09:51:01 2025 +0000 - upstream: correct error message + upstream: Fix mistracking of MaxStartups process exits in some - OpenBSD-Commit-ID: 581f60f73099083392887206860229ab104620ed + situations. At worst, this can cause all MaxStartups slots to fill and sshd + to refuse new connections. + + Diagnosis by xnor; ok dtucker@ + + OpenBSD-Commit-ID: 10273033055552557196730f898ed6308b36a78d -commit fa7d7a667f2ee031e72873e36de2d2a36bca973b -Author: deraadt@openbsd.org -Date: Fri Jun 7 13:23:30 2024 +0000 +commit c971f3d93efe4c00d73b276cdbab66e7c66c9b5c +Author: Darren Tucker +Date: Sat Jul 5 20:50:50 2025 +1000 - upstream: avoid shadowing issues which some compilers won't accept - - ok djm + Add include for gssapi definitions. - OpenBSD-Commit-ID: 1e89572397dda83433d58c4fa6333a08f51170d4 + Patch from dbelyavs at redhat.com via bz#3846. -commit 3ad4cd9eeca5c9bc6706db44b6de88e2e4513fd6 -Author: jmc@openbsd.org -Date: Thu Jun 6 21:14:49 2024 +0000 +commit 007b69f21cf9e64125b241d4411a5e47f5028aa8 +Author: djm@openbsd.org +Date: Fri Jul 4 07:52:17 2025 +0000 - upstream: escape the final dot at eol in "e.g." to avoid double + upstream: add a regress test for configurations > 256KB - spacing; + mostly by Dmitry Belyavskiy - OpenBSD-Commit-ID: 0a9fb10bc9f7d577afe2da3f498a08bc431115b9 + OpenBSD-Regress-ID: fcedb249e4cf2447e078a839877f99730ee79024 -commit 0e0c69761a4c33ccd4a256560f522784a753d1a8 +commit 0cf38d74463bcf80510e7fd1b3d9328e7d91eb00 Author: djm@openbsd.org -Date: Thu Jun 6 20:25:48 2024 +0000 +Date: Fri Jul 4 07:47:35 2025 +0000 - upstream: enable PerSourcePenalties by default. + upstream: the messaging layer between sshd-session and sshd-auth had a - ok markus + maximum message size of 256KB. Some people apparently have configurations + larger than this and would hit this limit. - NB. if you run a sshd that accepts connections from behind large NAT - blocks, proxies or anything else that aggregates many possible users - behind few IP addresses, then this change may cause legitimate traffic - to be denied. + Worse, there was no good logging that could help diagnose what was + going wrong. - Please read the PerSourcePenalties, PerSourcePenaltyExemptList and - PerSourceNetBlockSize options in sshd_config(5) for how to tune your - sshd(8) for your specific circumstances. + So this bumps the maximum message size to 4MB and implements an early + check (usable via the sshd -t test mode) that will report it to the + user where it is hopefully more visible. - OpenBSD-Commit-ID: 24a0e5c23d37e5a63e16d2c6da3920a51078f6ce + bz3808, reported by Dmitry Belyavskiy, ok dtucker@ + + OpenBSD-Commit-ID: 69c303fb68cbd1a4735936835d67a71e7b57f63b -commit bd1f74741daabeaf20939a85cd8cec08c76d0bec +commit fd10cea0f16e928ae2b52fbeadccd475d0438eb4 Author: djm@openbsd.org -Date: Thu Jun 6 20:20:42 2024 +0000 +Date: Fri Jul 4 00:17:55 2025 +0000 - upstream: mention that PerSourcePenalties don't affect concurrent + upstream: mux: fix incorrect return value check in local forward - in-progress connections. + cancellation - OpenBSD-Commit-ID: 20389da6264f2c97ac3463edfaa1182c212d420c - -commit 9774b938578327d88a651f4c63c504809717590a -Author: djm@openbsd.org -Date: Thu Jun 6 19:49:25 2024 +0000 - - upstream: regress test for PerSourcePenalties + channel_cancel_lport_listener() returns 1 on success and 0 on failure. + The previous code incorrectly checked for `== -1`, a value the function + never returns, so failure was not detected and the "port not found" + error message was never shown when cancelling dynamic or local port + forwards. - OpenBSD-Regress-ID: a1af13d411b25a727742644459d26480b9a1b0f1 + From: Boris Tonofa + + OpenBSD-Commit-ID: 3e9d2252a4d0bd318d4f25e2b518afb44acea170 -commit b8ebd86cefe9812204a10c028dc90de29918667d -Author: djm@openbsd.org -Date: Thu Jun 6 19:48:40 2024 +0000 +commit 29cf521486bf97ab9de5b9b356f812107e0671bc +Author: Damien Miller +Date: Wed Jul 2 13:47:38 2025 +1000 - upstream: make sure logs are saved from sshd run via start_sshd + wrap some autoconf macros in AC_CACHE_CHECK - OpenBSD-Regress-ID: de4ef0e32e3ab85ff3a6c36eb08d1909c0dd1b4a + This allows skipping/overriding the OSSH_CHECK_CFLAG_COMPILE and + OSSH_CHECK_CFLAG_LINK macros used to discover supported compiler + or linker flags. E.g. + + $ ./configure ossh_cv_cflag__fzero_call_used_regs_used=no + [...] + checking if cc supports compile flag -ftrapv and linking succeeds... yes + checking if cc supports compile flag -fzero-call-used-regs=used and linking succeeds... (cached) no + checking if cc supports compile flag -ftrivial-auto-var-init=zero... yes + + Patch from Colin Watson, ok dtucker@ -commit d7b2070bdaa4ebbfafb9975c1d5a62b73289d31f -Author: djm@openbsd.org -Date: Thu Jun 6 19:47:48 2024 +0000 +commit b28e91aff80fd24341de8cb3c34dc454d6b75228 +Author: dtucker@openbsd.org +Date: Sun Jun 29 08:20:21 2025 +0000 - upstream: simplify + upstream: Add shebang path to askpass script. Required for exec on - OpenBSD-Regress-ID: 50316e0d1ae0c0a057a45af042253e54ce23d11c + some platforms (musl, probably others). + + OpenBSD-Regress-ID: 35cdeed12ae701afcb812f800c04d817325cd22a -commit e6ea3d224513b6bfb93818809d4c7397f5995ba2 -Author: djm@openbsd.org -Date: Thu Jun 6 18:48:13 2024 +0000 +commit 83d3ffc0fc0f5e4473ab43f0d42a1cf9497ce0b5 +Author: dtucker@openbsd.org +Date: Sun Jun 29 05:35:00 2025 +0000 - upstream: prepare for PerSourcePenalties being enabled by default + upstream: Check dropbear server version for required features. - in future + Dropbear added the '-D' flag in version 2025.87. We need that for the + dropbear-server test, so skip on older versions. - OpenBSD-Regress-ID: 5236c6d1c823997aac5a35e2915da30f1903bec7 + OpenBSD-Regress-ID: 9db0b84edd54d3c00ab17db1dc6d62af4644c550 -commit c0cb3b8c837761816a60a3cdb54062668df09652 -Author: djm@openbsd.org -Date: Thu Jun 6 19:50:01 2024 +0000 +commit 0b17d564cfae82f2a52e9b4d588657da47ea4e43 +Author: Darren Tucker +Date: Sun Jun 29 14:34:48 2025 +1000 - upstream: disable stderr redirection before closing fds + Encrypt temporary password we're setting. - OpenBSD-Commit-ID: d42cb895ee4542098050367fc35321c9303f003a + Now that we want to actually use the random password for tests, we need + to correctly encrypt it, instead of just setting it to a random string + that's not the "locked" value. -commit 81c1099d22b81ebfd20a334ce986c4f753b0db29 -Author: djm@openbsd.org -Date: Thu Jun 6 17:15:25 2024 +0000 +commit 700205bd861c25cc7564010cf63d984d8db5098a +Author: Darren Tucker +Date: Sun Jun 29 11:27:17 2025 +1000 - upstream: Add a facility to sshd(8) to penalise particular - - problematic client behaviours, controlled by two new sshd_config(5) options: - PerSourcePenalties and PerSourcePenaltyExemptList. + Fix env again. + +commit 223a1beac7b7be9252f69055781c9c15f4d8a607 +Author: Darren Tucker +Date: Sun Jun 29 11:24:42 2025 +1000 + + Move env again. + +commit d32614b448528ac08a65caac323a34b4f559a204 +Author: Darren Tucker +Date: Sun Jun 29 11:22:00 2025 +1000 + + Move env to where it (hopefully) belongs. + +commit 8a9384de483b8fb69a800e0347273686a5715fc3 +Author: Darren Tucker +Date: Sun Jun 29 11:14:18 2025 +1000 + + Enable password tests on Github ephemeral VMs. + +commit bcfe7340d9b622ecd978c87dbf885c8b5a503ca2 +Author: dtucker@openbsd.org +Date: Sat Jun 28 13:34:08 2025 +0000 + + upstream: Add simple regression test for dropbear as a server. - When PerSourcePenalties are enabled, sshd(8) will monitor the exit - status of its child pre-auth session processes. Through the exit - status, it can observe situations where the session did not - authenticate as expected. These conditions include when the client - repeatedly attempted authentication unsucessfully (possibly indicating - an attack against one or more accounts, e.g. password guessing), or - when client behaviour caused sshd to crash (possibly indicating - attempts to exploit sshd). + OpenBSD-Regress-ID: 7abe1f6607d0cd49839918aade8f135d2462d389 + +commit 838d5ec4b12fb519ed9db76e5beccf11b7ee212f +Author: dtucker@openbsd.org +Date: Tue Jun 24 12:28:23 2025 +0000 + + upstream: Add simple test for password auth. Requires some setup - When such a condition is observed, sshd will record a penalty of some - duration (e.g. 30 seconds) against the client's address. If this time - is above a minimum threshold specified by the PerSourcePenalties, then - connections from the client address will be refused (along with any - others in the same PerSourceNetBlockSize CIDR range). + so does not run by default. - Repeated offenses by the same client address will accrue greater - penalties, up to a configurable maximum. A PerSourcePenaltyExemptList - option allows certain address ranges to be exempt from all penalties. + OpenBSD-Regress-ID: d5ded47a266b031fc91f99882f07161ab6d1bb70 + +commit 57fb460165ae3b2d591f2468d7fe13cc1abda26d +Author: djm@openbsd.org +Date: Tue Jun 17 01:24:32 2025 +0000 + + upstream: add RCS ID - We hope these options will make it significantly more difficult for - attackers to find accounts with weak/guessable passwords or exploit - bugs in sshd(8) itself. + OpenBSD-Regress-ID: 6e30094e3bf0a1c65efb75c67a87093304a3e619 + +commit 688fa02728f2efbf18388bc1a8e94e7ba7ee4f11 +Author: djm@openbsd.org +Date: Tue Jun 24 09:22:03 2025 +0000 + + upstream: make "Match !final" not trigger a 2nd pass ssh_config - PerSourcePenalties is off by default, but we expect to enable it - automatically in the near future. + parsing pass (unless hostname canonicalisation or a separate "Match final" + does). bz3843 - much feedback markus@ and others, ok markus@ + ok dtucker@ - OpenBSD-Commit-ID: 89ded70eccb2b4926ef0366a4d58a693de366cca - -commit 916b0b6174e203cf2c5ec9bcf409472eb7ffbf43 -Author: Damien Miller -Date: Fri Jun 7 03:31:02 2024 +1000 - - whitespace + OpenBSD-Commit-ID: ce82b6034828888f0f3f1c812e08f5e87400d802 -commit 49b55e44182b8294419aa580cbf043d5b9e3d953 -Author: deraadt@openbsd.org -Date: Tue Jun 4 15:14:45 2024 +0000 +commit 5ba8391d697740a838fd8811434f707f0e079baa +Author: djm@openbsd.org +Date: Thu Jun 19 05:49:05 2025 +0000 - upstream: enable -fret-clean on amd64, for libc libcrypto ld.so + upstream: better debug diagnostics when loading keys. Will now list - kernel, and all the ssh tools. The dynamic objects are entirely ret-clean, - static binaries will contain a blend of cleaning and non-cleaning callers. + key fingerprint and algorithm (not just algorithm number) as well as making + it explicit which keys didn't load. - OpenBSD-Commit-ID: 112aacedd3b61cc5c34b1fa6d9fb759214179172 + OpenBSD-Commit-ID: ee3e77a0271ab502e653922c6d161b1e091f8fee -commit cc80d51d034bcb24fd0f2564a4bdf1612000a2a2 -Author: Damien Miller -Date: Wed Jun 5 02:21:30 2024 +1000 +commit b360f3a675e24b0dbb2ec30d985e3b6756996c0d +Author: djm@openbsd.org +Date: Tue Jun 17 01:20:17 2025 +0000 - remove PRIVSEP macros for osx + upstream: whitespace + + OpenBSD-Commit-ID: 6e96814bcf70d0edbb0749ec61cc4fd8707f286d -commit 8785491123d4d722b310c20f383570be758f8263 +commit ad38ec5f1b6768944d64ed7709da8706538b5509 Author: djm@openbsd.org -Date: Sat Jun 1 07:03:37 2024 +0000 +Date: Tue Jun 17 01:19:27 2025 +0000 - upstream: be really strict with fds reserved for communication with the - - separate sshd-session process - reserve them early and fatal if we can't - dup2(2) them later. The pre-split fallback to re-reading the configuration - files is not possible, so sshd-session absolutely requires the fd the - configuration is passed over to be in order. - - ok deraadt@ + upstream: fix leak on error path; Coverity CID 481976 - OpenBSD-Commit-ID: 308a98ef3c8a6665ebf92c7c9a0fc9600ccd7065 + OpenBSD-Commit-ID: 963dba2c804e2fd8efea2256092899874d0dbc7b -commit f1c8918cb98459910fb159373baea053ba4108c0 -Author: Damien Miller -Date: Fri May 31 19:12:26 2024 +1000 +commit 5f761cdb2331a12318bde24db5ca84ee144a51d1 +Author: Darren Tucker +Date: Tue Jun 17 21:46:37 2025 +1000 - depend + Update obsd tests to use current images. -commit 94b4866cb1f4b0ed29a9f367047b30f81002316f +commit 1e8347e3543a415067ccc556aefea97656ecafb7 Author: Damien Miller -Date: Fri May 31 19:11:14 2024 +1000 +Date: Tue Jun 17 09:48:47 2025 +1000 - rename need_privsep to need_chroot - - privsep is mandatory, chroot is optional (disabled when running - sshd as non-root) + add sshd-auth to RPM spec files -commit e68a95142e5024b144f8eeccd5ffdee42c34f44c -Author: Damien Miller -Date: Fri May 31 19:05:34 2024 +1000 +commit dd800444943bd64913507f6005586136d49f63db +Author: dtucker@openbsd.org +Date: Mon Jun 16 09:09:42 2025 +0000 - remove remaining use_privsep mention + upstream: Limit each moduli size to a max of 100 entries. + + OpenBSD-Commit-ID: 747219d54565030ff7c45298b9f5e971801f6cb2 -commit b21d271f651d2536dca819cc6d74032fe98634db -Author: djm@openbsd.org -Date: Fri May 31 09:01:08 2024 +0000 +commit 05f7bf46d1e2c101e9cbdd3df2ccee484bed969f +Author: dtucker@openbsd.org +Date: Mon Jun 16 09:07:08 2025 +0000 - upstream: warn when -r (deprecated option to disable re-exec) is + upstream: Now that ssh-keygen defaults to the maximum memory for - passed + moduli generation we no longer need to run it twice to get enough. Use mkdir + -p instead of a conditional, which allows "make -jN" to work without error. - OpenBSD-Commit-ID: 73145ef5150edbe3ce7889f0844ed8fa6155f551 + OpenBSD-Commit-ID: c2eb57285424f819f9520fa33e0d6d3c4a361a5e -commit a4b5bc246cbca476deeeb4462aa31746a56e3021 -Author: djm@openbsd.org -Date: Fri May 31 08:49:35 2024 +0000 +commit df3f903d616763a105570610a616dacf0f83438e +Author: dtucker@openbsd.org +Date: Mon Jun 16 09:02:19 2025 +0000 - upstream: typos + upstream: Fix overflow check in sshbuf_dup_string. It's already - OpenBSD-Commit-ID: edfa72eb06bfa65da30fabf7d2fe76d2d33f77bf + constrained by SSHBUF_SIZE_MAX, but still worth fixing the check. Patch from + afonot via github PR#573, with & ok djm@ + + OpenBSD-Commit-ID: 438888498e66472fc6a48133196d6538d27bff18 -commit 8054b906983ceaed01fabd8188d3dac24c05ba39 -Author: djm@openbsd.org -Date: Mon May 27 01:52:26 2024 +0000 +commit 80916d0d3794e2f92dd6998d7c45daba484e4f18 +Author: dtucker@openbsd.org +Date: Mon Jun 16 08:53:04 2025 +0000 - upstream: don't need sys/queue.h here + upstream: Plug mem leak. Patch from afonot via github PR#574, ok djm@ - OpenBSD-Commit-ID: dd137396828171eb19e4911581812ca58de6c578 + OpenBSD-Commit-ID: 65619f14ef206028ce39bc31f704b832a0609688 -commit 210d4239733da6180ce853538aeb9413d5c62ad5 -Author: naddy@openbsd.org -Date: Sun May 26 20:35:12 2024 +0000 +commit bd1bd7e8296aa51a4b3958cef2fbb17894ba94e9 +Author: dtucker@openbsd.org +Date: Mon Jun 16 08:49:27 2025 +0000 - upstream: remove references to SSH1 and DSA server keys + upstream: Save return value from sshbuf_len instead of calling it - OpenBSD-Commit-ID: 57cc1c98d4f998981473734f144b904af7d178a2 + multiple times. Fixes Coverity CID 470521. + + OpenBSD-Regress-ID: 356b8b43c8a232deaf445c1ff7526577b177a8e9 -commit f0b9261d7fdd0ef86806b49fe76344bd16770cd0 -Author: jsg@openbsd.org -Date: Thu May 23 23:47:16 2024 +0000 +commit 2827b6ac304ded8f99e8fbc12e7299133fadb2c2 +Author: dtucker@openbsd.org +Date: Fri Jun 13 07:35:14 2025 +0000 - upstream: remove unused struct fwd_perm_list, no decl with complete - - type ok djm@ + upstream: Plug leak. Coverity CID 405058. - OpenBSD-Commit-ID: 416fb3970b7e73c76d2963c4f00cf96f2b2ee2fb + OpenBSD-Regress-ID: 7fb2fce68d2cb063cdb94d5d66f84fa3a2902792 -commit 2477a98c3ef78e63b11a1393656e00288f52ae97 -Author: naddy@openbsd.org -Date: Wed May 22 15:24:55 2024 +0000 +commit 9cdc72b829e9f0e24dedc533cbe87291d8a88c9e +Author: dtucker@openbsd.org +Date: Fri Jun 13 07:23:07 2025 +0000 - upstream: Do not pass -Werror twice when building with clang. + upstream: Remove dead code flagged by Coverity CID 307783. ok djm@ - OpenBSD-Commit-ID: 5f378c38ad8976d507786dc4db9283a879ec8cd0 + OpenBSD-Regress-ID: e579f5ec2fd2eb2fe2bad654d16f2ba655a3e035 -commit 435844f5675245b4271f8581f15e6d1f34fde3bc -Author: miod@openbsd.org -Date: Wed May 22 11:49:36 2024 +0000 +commit 930a45ee759728c8ba711c45a2a985b8191bd297 +Author: dtucker@openbsd.org +Date: Thu Jun 12 10:09:39 2025 +0000 - upstream: Do not pass -Werror if building with gcc 3, for asn1.h + upstream: Set user, host and path to NULL immediately before calling - and bio.h cause (admittedly bogus) warnings with gcc 3. + parse_user_host_path in tests. This ensures that we don't accidentally use + the previous value if the function under test doesn't set them Also fixes + Coverity CIDs 405056 405065 405066. - OpenBSD-Commit-ID: fb39324748824cb0387e9d67c41d1bef945c54ea + OpenBSD-Regress-ID: 43678ff59001712f32214fe303b1c21c163c2960 -commit fc5dc092830de23767c6ef67baa18310a64ee533 -Author: djm@openbsd.org -Date: Wed May 22 04:20:00 2024 +0000 +commit 2314d87f9b8b430532111fd6e5e8df0cf9068c9c +Author: dtucker@openbsd.org +Date: Thu Jun 12 09:26:57 2025 +0000 - upstream: this test has been broken since 2014, and has been + upstream: Plug mem leak on error path here too. - testing the same key exchange algorithm repeatedly instead of testing all of - them. Spotted by nreilly AT blackberry.com in bz3692 + Coverity CID 307781. - Who broke the test? me. + OpenBSD-Regress-ID: 18e053d9b661fbb4227d3db03172077c1216bb2e + +commit 567ef4e7ddc5c1e7a461560963a1dc759669821d +Author: dtucker@openbsd.org +Date: Thu Jun 12 09:19:43 2025 +0000 + + upstream: Plug mem leak on error path. - OpenBSD-Regress-ID: 48f4f5946276f975667141957d25441b3c9a50e2 + Coverity CID 307776. + + OpenBSD-Regress-ID: c44246690973e1b8643e51079a2faa7ace26490c -commit fd4816791beaed2fdae7eea3e1494d1972b2a39d -Author: anton@openbsd.org -Date: Sun May 19 19:10:01 2024 +0000 +commit 5d415897ac04e237f1fa73b9dcb9ba8fb3ac812b +Author: dtucker@openbsd.org +Date: Wed Jun 11 13:27:11 2025 +0000 - upstream: Add missing kex-names.c source file required since the + upstream: Remove dead code ternary. We always report at least - ssh split. + KB/s, so B/s is never used. Coverity CID 291809, ok djm@ - OpenBSD-Regress-ID: ca666223f828fc4b069cb9016bff1eb50faf9fbb + OpenBSD-Commit-ID: a67c5bcc9e19c8965bfeace0e337b13660efa058 -commit beccb7319c5449f6454889013403c336446d622e -Author: naddy@openbsd.org -Date: Fri May 17 14:42:00 2024 +0000 +commit 4b3d27032ba88dd089b721f3bbe3e4a8d23b4ae1 +Author: dtucker@openbsd.org +Date: Wed Jun 11 13:24:05 2025 +0000 - upstream: remove duplicate copy of relink kit for sshd-session + upstream: Improve termination condition of while loop to compare - OpenBSD-Commit-ID: 6d2ded4cd91d4d727c2b26e099b91ea935bed504 + size_t's. Assuming read() does what it's supposed to this shouldn't matter, + but should be more robust. Flagged by Coverity CID 470514, ok djm@ + + OpenBSD-Commit-ID: d7b5ad60feb797b3464964b9ea67fd78fb9d6cc6 -commit dcd79fa141311c287e0595ede684b7116122fae0 -Author: jsg@openbsd.org -Date: Fri May 17 06:42:04 2024 +0000 +commit 5530e5f83b3cd3425ea3dbab02da15140befdd91 +Author: Darren Tucker +Date: Tue Jun 10 18:40:56 2025 +1000 - upstream: remove prototypes with no matching function; ok djm@ + Replace Windows 2019 runners with 2025 ones. - OpenBSD-Commit-ID: 6d9065dadea5f14a01bece0dbfe2fba1be31c693 + The windows-2019 runners are being decomissioned. -commit 6454a05e7c6574d70adf17efe505a8581a86ca4f -Author: jsg@openbsd.org -Date: Fri May 17 06:38:00 2024 +0000 +commit a22ff3c6f11edd00c19981f9cb85d3b25d305a56 +Author: Darren Tucker +Date: Wed Jun 4 18:33:52 2025 +1000 - upstream: remove externs for removed vars; ok djm@ + Disable _FORTIFY_SOURCE during snprintf test. - OpenBSD-Commit-ID: f51ea791d45c15d4927eb4ae7d877ccc1e5a2aab + Prevents mistakenly detecting snprintf as broken on FreeBSD 15 with + _FORTIFY_SOURCE enabled. bz#3809, patch from jlduran at gmail.com -commit f3e4db4601ef7d2feb1d6f7447e432aaf353a616 -Author: deraadt@openbsd.org -Date: Fri May 17 06:11:17 2024 +0000 +commit 203bb886797677aa5d61b57be83cfdc1b634bc9c +Author: dtucker@openbsd.org +Date: Mon Jun 2 14:09:34 2025 +0000 - upstream: -Werror was turned on (probably just for development), + upstream: Fix x11_channel_used_recently() to return true when channel - and this is a simple way to satisfy older gcc. + has been used within the last second, instead of more than a second ago. + Should fix ~5s delay on X client startup when ObscureKeystrokeTiming is + enabled. bz#3820, ok (& sigh) djm@ - OpenBSD-Commit-ID: 7f698df54384b437ce33ab7405f0b86c87019e86 + OpenBSD-Commit-ID: b741011e81fb3e3d42711d9bd3ed8a959924dee4 -commit 24a1f3e5ad6f4a49377d4c74c36637e9a239efd0 -Author: Damien Miller -Date: Fri May 17 14:50:43 2024 +1000 +commit dc6c134b48ba4bcfadedcea17b4eddac329601d9 +Author: dtucker@openbsd.org +Date: Thu May 29 13:27:27 2025 +0000 - attempt at updating RPM specs for sshd-session + upstream: When there's more than one x11 channel in use, return + + lastused of most recently used x11 channel instead of the last one found. ok + djm@ + + OpenBSD-Commit-ID: 94a72bf988d40a5bae2e38608f4e117f712569fe -commit 17b566eeb7a0c6acc9c48b35c08885901186f861 +commit 73ef0563a59f90324f8426c017f38e20341b555f Author: djm@openbsd.org -Date: Fri May 17 04:42:13 2024 +0000 +Date: Sat May 24 11:41:51 2025 +0000 - upstream: g/c unused variable + upstream: replace xmalloc+memset(0) with xcalloc(); from AZero13 via - OpenBSD-Commit-ID: aa6ef0778a1f1bde0d73efba72a777c48d2bd010 + GHPR417 + + OpenBSD-Commit-ID: 921079436a4900325d22bd3b6a90c8d0d54f62f8 -commit 01fb82eb2aa0a4eaf5c394ea8bb37ea4c26f8a3f -Author: jsg@openbsd.org -Date: Fri May 17 02:39:11 2024 +0000 - - upstream: spelling; ok djm@ - - OpenBSD-Commit-ID: bdea29bb3ed2a5a7782999c4c663b219d2270483 - -commit b88b690e99145a021fc1a1a116a11e0bce0594e7 +commit 3a61f5ed66231881bee432c7e7c6add066c086af Author: djm@openbsd.org -Date: Fri May 17 01:45:22 2024 +0000 +Date: Sat May 24 09:46:16 2025 +0000 - upstream: allow overriding the sshd-session binary path + upstream: fix punctuation around host key fingerprints to make them - OpenBSD-Regress-ID: 5058cd1c4b6ca1a15474e33546142931d9f964da + easier to copy and paste. + + Patch from Till Maas via GHPR556; ok dtucker@ + + OpenBSD-Commit-ID: c0100182a30b6925c8cdb2225b18140264594b7b -commit a68f80f2511f0e0c5cef737a8284cc2dfabad818 -Author: anton@openbsd.org -Date: Wed Apr 3 06:01:11 2024 +0000 +commit b12d4ab1e16f57c6c348b483b1dbdd4530aaaddd +Author: dtucker@openbsd.org +Date: Sat May 24 08:13:29 2025 +0000 - upstream: Since ssh-agent(1) is only readable by root by now, use + upstream: Replace strncmp + byte count with strprefix in Penalty - ssh(1) while generating data in tests. + config parsing. ok kn@, djm@ - OpenBSD-Regress-ID: 24eb40de2e6b0ace185caaba35e2d470331ffe68 + OpenBSD-Commit-ID: 34a41bb1b9ba37fb6c7eb29a7ea909547bf02a5a -commit 92e55890314ce2b0be21a43ebcbc043b4abc232f -Author: djm@openbsd.org -Date: Fri May 17 01:17:40 2024 +0000 +commit a356d978e30dd9870c0b3a7d8edca535b0cd2809 +Author: dtucker@openbsd.org +Date: Sat May 24 08:09:32 2025 +0000 - upstream: fix incorrect debug option name introduce in previous + upstream: Make the display number check relative to - commit + X11DisplayOffset. - OpenBSD-Commit-ID: 66d69e22b1c072c694a7267c847f212284614ed3 + This will allows people to use X11DisplayOffset to configure much higher + port ranges if they really want, while not changing the default behaviour. + Patch from Roman Gubarev via github PR#559, ok djm@ + + OpenBSD-Commit-ID: e0926af5dc0c11e364452b624c3ad0cda88550b5 -commit 4ad72878af7b6ec28da6e230e36a91650ebe84c1 -Author: deraadt@openbsd.org -Date: Fri May 17 00:33:25 2024 +0000 +commit e18983d03ab969e2f12485d5c0ee61e6d745a649 +Author: Darren Tucker +Date: Sat May 24 17:20:57 2025 +1000 - upstream: construct and install a relink-kit for sshd-session ok - - djm + Remove progressmeter.o from libssh.a. - OpenBSD-Commit-ID: 8b3820adb4da4e139c4b3cffbcc0bde9f08bf0c6 + It's now explicitly included by the binaries that need it (scp & sftp). + bz#3810, patch from jlduran at gmail.com -commit 02e679a2cb3f6df8e9dbb1519ed578226485157f -Author: Damien Miller -Date: Fri May 17 12:21:27 2024 +1000 +commit f8967045ad9d588bc11426642070bf8549065e62 +Author: dtucker@openbsd.org +Date: Sat May 24 06:50:28 2025 +0000 - Makefile support for sshd-session + upstream: Null out keys between test runs. + + BENCH_START and BENCH_FINISH are actually a while() loop in disguise, + so if sshkey_generate does not reset the key pointer on failure the test + may incorrectly pass. It also confuses Coverity (CID 551234). + + OpenBSD-Regress-ID: bf4d32079fc6df6dce1f26c2025f4ed492f13936 -commit c0416035c5eaf70a8450d11c8833c5f7068ee7ad +commit a26091ecdb2a3d72b77baf3c253e676a3c835a24 Author: djm@openbsd.org -Date: Fri May 17 00:32:32 2024 +0000 +Date: Sat May 24 04:41:12 2025 +0000 - upstream: missing files from previous + upstream: add some verbosity - OpenBSD-Commit-ID: 4b7be4434d8799f02365552b641a7a70a7ebeb2f + OpenBSD-Regress-ID: 11c86cda4435b5f9ab6172c4742b95899666c977 -commit 03e3de416ed7c34faeb692967737be4a7bbe2eb5 +commit 484563ec70e30472ab4484d49bca9a83771d785c Author: djm@openbsd.org -Date: Fri May 17 00:30:23 2024 +0000 +Date: Sat May 24 04:41:03 2025 +0000 - upstream: Start the process of splitting sshd into separate + upstream: use start_ssh_agent() to ensure we get logging - binaries. This step splits sshd into a listener and a session binary. More - splits are planned. - - After this changes, the listener binary will validate the configuration, - load the hostkeys, listen on port 22 and manage MaxStartups only. All - session handling will be performed by a new sshd-session binary that the - listener fork+execs. - - This reduces the listener process to the minimum necessary and sets us - up for future work on the sshd-session binary. - - feedback/ok markus@ deraadt@ + add some verbosity - NB. if you're updating via source, please restart sshd after installing, - otherwise you run the risk of locking yourself out. - - OpenBSD-Commit-ID: 43c04a1ab96cdbdeb53d2df0125a6d42c5f19934 + OpenBSD-Regress-ID: a89bf64696b9fb1b91be318e6b8940c9ab21c616 -commit 1c0d81357921f8d3bab06841df649edac515ae5b +commit e3c58113ebb3397b252ff26e0e94f726b7db7a8a Author: djm@openbsd.org -Date: Thu May 9 09:46:47 2024 +0000 +Date: Sat May 24 04:40:37 2025 +0000 - upstream: simplify exit message handling, which was more complicated + upstream: add a start_ssh_agent() function that sets up an agent - than it needed to be because of unexpunged ssh1 remnants. ok markus@ + with logging - OpenBSD-Commit-ID: 8b0cd2c0dee75fb053718f442aa89510b684610b + OpenBSD-Regress-ID: 7f9f30f9c64acbd4b418a5e1a19140cc988071a8 -commit cbbbf76aa6cd54fce32eacce1300e7abcf9461d4 -Author: tobias@openbsd.org -Date: Mon May 6 19:26:17 2024 +0000 +commit 3de011ef7a761751afe28ac7ef97fe330d784595 +Author: dtucker@openbsd.org +Date: Sat May 24 06:43:37 2025 +0000 - upstream: remove SSH1 leftovers - - Authored with Space Meyer + upstream: Plug leak of startup_pollfd in debug and child paths. - ok djm + Coverity CID 405024, ok djm@ - OpenBSD-Commit-ID: 81db602e4cb407baae472689db1c222ed7b2afa3 + OpenBSD-Commit-ID: db46047229253e9c4470c8bbf5f82706ac021377 -commit bc5dcb8ab9a4e8af54a724883732af378f42ea78 -Author: tobias@openbsd.org -Date: Tue Apr 30 15:40:43 2024 +0000 +commit d0245389bc55f16082cadd0a39dda5af1c415dfa +Author: Darren Tucker +Date: Sat May 24 17:11:38 2025 +1000 - upstream: never close stdin - - The sanitise_stdfd call makes sure that standard file descriptors are - open (if they were closed, they are connected with /dev/null). + ssh-keygen changes were fixup'ed into single commit. + +commit 140bae1df2b7246bb43439d039bf994159973585 +Author: Marco Trevisan (Treviño) +Date: Mon Sep 30 13:14:11 2024 +0200 + + auth-pam: Check the user didn't change during PAM transaction - Do not close stdin in any case to prevent error messages when stdin is - read multiple times and to prevent later usage of fd 0 for connections, - e.g. + PAM modules can change the user during their execution, in such case ssh + would still use the user that has been provided giving potentially + access to another user with the credentials of another one. - echo localhost | ssh-keyscan -f - -f - + So prevent this to happen, by ensuring that the final PAM user is + matching the one that initiated the transaction. + +commit 216824172724a50a4a75439fb2b4b8edccf5b733 +Author: dtucker@openbsd.org +Date: Sat May 24 03:37:40 2025 +0000 + + upstream: Remove ssh-keygen's moduli screen -Omemory option. - While at it, make stdin-related error messages nicer. + This vaguely made sense 20 years ago, but these days you'd be hard + pressed to *find* a machine small enough to not support the maximum + (127MB), and no one is screening moduli on such machines anyway, + so just use the max. This also fixes Coverity CID 470522 by deleting + code in question. "kill it with fire" djm@. - Authored with Max Kunzelmann + OpenBSD-Commit-ID: 39036aa406a99f0a91923aa3a96afff1205558e6 + +commit f5cd14e81fa29b4924959cb2e1f9c206aae2d502 +Author: dtucker@openbsd.org +Date: Sat May 24 02:33:33 2025 +0000 + + upstream: Fix compile error on 32bit platforms. - ok djm + Spotted by & ok tb@ - OpenBSD-Commit-ID: 48e9b7938e2fa2f9bd47e6de6df66a31e0b375d3 + OpenBSD-Commit-ID: cbcf518247886f3c7518fc54cb3bd911ffc69db7 -commit 6a42b70e56bef1aacdcdf06352396e837883e84f -Author: Damien Miller -Date: Wed May 8 09:43:59 2024 +1000 +commit eccc15014fe146e8590568e6737a3097bfac3415 +Author: dtucker@openbsd.org +Date: Sat May 24 02:01:28 2025 +0000 - sync getrrsetbyname.c with recent upstream changes + upstream: Use pointer from strprefix in error message, + + missed in previous. + + OpenBSD-Commit-ID: d2cdec6cf0fcd4b0ee25e4e3fad8bc8cf0ee657d -commit 385ecb31e147dfea59c1c488a1d2011d3867e60e -Author: djm@openbsd.org -Date: Tue Apr 30 06:23:51 2024 +0000 +commit 91903511d0597c3bea218167f9ca5a176fa0dc20 +Author: dtucker@openbsd.org +Date: Fri May 23 12:52:45 2025 +0000 - upstream: fix home-directory extension implementation, it always - - returned the current user's home directory contrary to the spec. + upstream: Replace strncmp and strncasecmp with hand-counting bytes - Patch from Jakub Jelen via GHPR477 + with strprefix. nits lucas@, ok lucas@ djm@ - OpenBSD-Commit-ID: 5afd775eab7f9cbe222d7fbae4c793de6c3b3d28 + OpenBSD-Commit-ID: f0888807f151ea2bdaf6fed36303ae81f259d1d4 -commit 14e2b16bc67ffcc188906f65008667e22f73d103 -Author: djm@openbsd.org -Date: Tue Apr 30 06:16:55 2024 +0000 +commit 0c64d69e4e24a3ab06f7922ef389e7399c4dfb88 +Author: dtucker@openbsd.org +Date: Fri May 23 11:54:50 2025 +0000 - upstream: flush stdout after writing "sftp>" prompt when not using + upstream: Include stdint.h for UINT32_MAX. - editline. + OpenBSD-Commit-ID: edc29ed67e8bd03bac729d9b4849066d1d3a8cb9 + +commit 3e11478f585408888defa56fa47e8dc6567378d0 +Author: dtucker@openbsd.org +Date: Fri May 23 11:25:35 2025 +0000 + + upstream: Ensure args to nh_update() fit within uint32, which it - From Alpine Linux via GHPR480 + should always anyway. Placates Coverity CID 470520. While there, fix the + upstream URL. ok djm@ - OpenBSD-Commit-ID: 80bdc7ffe0358dc090eb9b93e6dedb2b087b24cd + OpenBSD-Commit-ID: 2478e89fde089a49fa02f9faf6287d35959c9f92 -commit 2e69a724051488e3fb3cd11531c4b5bc1764945b -Author: djm@openbsd.org -Date: Tue Apr 30 05:53:03 2024 +0000 +commit f097d7bd07da4634c1a723d1dc4fcf56e7d0e147 +Author: dtucker@openbsd.org +Date: Fri May 23 09:26:25 2025 +0000 - upstream: stricter validation of messaging socket fd number; disallow + upstream: Don't leak the args list. Coverity CIDs 481569 & 481570, - usage of stderr. Based on GHPR492 by RealHurrison + ok job@ tb@. - OpenBSD-Commit-ID: 73dbbe82ea16f73ce1d044d3232bc869ae2f2ce8 + OpenBSD-Commit-ID: becabcd00513d13d1435b68b7ccffa7151b72393 -commit da757b022bf18c6f7d04e685a10cd96ed00f83da -Author: djm@openbsd.org -Date: Tue Apr 30 05:45:56 2024 +0000 +commit a4ea7f6042f25b41061a83445016a1ea4f470f7b +Author: dtucker@openbsd.org +Date: Fri May 23 08:40:13 2025 +0000 - upstream: add missing reserved fields to key constraint protocol - - documentation. + upstream: Explictly set LC_ALL=C on each sort invocation. - from Wiktor Kwapisiewicz via GHPR487 + Remove it from sshd_config (where it could be overridden by shell startup + scripts, eg on macos-15) causing random test failures. with & ok djm@ - OpenBSD-Commit-ID: 0dfb69998cfdb3fa00cbb0e7809e7d2f6126e3df + OpenBSD-Regress-ID: ad0a6678964784096e9a9e6d15ead36beed92f18 -commit 16d0b82fa08038f35f1b3630c70116979f49784f -Author: Damien Miller -Date: Tue Apr 30 12:39:34 2024 +1000 +commit 7674c03caed80cb3565d14690c92068a14051967 +Author: Darren Tucker +Date: Fri May 23 16:39:18 2025 +1000 - depend + Allow setting LTESTS in repo variables. -commit 66aaa678dbe59aa21d0d9d89a3596ecedde0254b -Author: djm@openbsd.org -Date: Tue Apr 30 02:14:10 2024 +0000 +commit d8b5bd36078e5b6d78da4633f0cc9b90ffda8b50 +Author: Darren Tucker +Date: Fri May 23 16:26:20 2025 +1000 - upstream: correctly restore sigprocmask around ppoll() reported - - by Tõivo Leedjärv; ok deraadt@ + Rename debugging variable RUN_ONLY_TEST. - OpenBSD-Commit-ID: c0c0f89de5294a166578f071eade2501929c4686 + to RUN_ONLY_TARGET_CONFIG to make it more obvious what it matches. -commit 80fb0eb21551aed3aebb009ab20aeffeb01e44e0 -Author: djm@openbsd.org -Date: Tue Apr 30 02:10:49 2024 +0000 +commit a79a2c1190bd3124da21d9e1582dd94877c7f972 +Author: Darren Tucker +Date: Fri May 23 16:11:48 2025 +1000 - upstream: add explict check for server hostkey type against - - HostkeyAlgorithms. Allows HostkeyAlgorithms to disable implicit fallback from - certificate keys to plain keys. ok markus@ - - OpenBSD-Commit-ID: 364087e4a395ff9b2f42bf3aefdb2090bb23643a + chown regress logs before uploading. -commit 5b28096d31ff7d80748fc845553a4aef5bb05d86 -Author: jsg@openbsd.org -Date: Tue Apr 23 13:34:50 2024 +0000 +commit 24889a33071086b6f1f62568b0c2bd0a4955ac49 +Author: dtucker@openbsd.org +Date: Fri May 23 01:14:35 2025 +0000 - upstream: correct indentation; no functional change ok tb@ + upstream: Import regenerated moduli. - OpenBSD-Commit-ID: dd9702fd43de546bc6a3f4f025c74d6f3692a0d4 + OpenBSD-Commit-ID: 07e29dc891e29b31e03e2e5493658b4a9ac19431 -commit fd3cb8a82784e05f621dea5b56ac6f89bc53c067 -Author: semarie@openbsd.org -Date: Thu Apr 4 16:00:51 2024 +0000 +commit 4b8bee62d72ffb3c419c9ead6c9fb1a586283868 +Author: deraadt@openbsd.org +Date: Fri May 23 00:40:45 2025 +0000 - upstream: set right mode on ssh-agent at boot-time + upstream: use "const char * const" for malloc_options here also - which sthen@ - ok deraadt@ - - OpenBSD-Commit-ID: 662b5056a2c6171563e1626f9c69f27862b5e7af + OpenBSD-Commit-ID: 869715b9c7e1dd5b85efd07814e7e53f0286eea2 -commit 54343a260e3aa4bceca1852dde31cd08e2abd82b -Author: deraadt@openbsd.org -Date: Tue Apr 2 12:22:38 2024 +0000 +commit 6629eee21ca9d0a597a04dcac744a1ad882f912e +Author: dtucker@openbsd.org +Date: Thu May 22 12:14:19 2025 +0000 - upstream: Oops, incorrect hex conversion spotted by claudio. + upstream: Adjust debug message to prevent (unsigned) integer overflow. - While here try to improve how it reads a bit better. Surprising the - regression tests didn't spot this error, maybe it fails to roundtrip the - values. + Fixes Coverity CID 481110, ok djm@ - OpenBSD-Commit-ID: 866cfcc1955aef8f3fc32da0b70c353a1b859f2e + OpenBSD-Commit-ID: 26178bf3b812707fb498ea85d076cadd1f2eb686 -commit ec78c31409590ad74efc194f886273ed080a545a -Author: deraadt@openbsd.org -Date: Tue Apr 2 10:02:08 2024 +0000 +commit 7acb70e05e9977ceca7b33df84ceaea337b1efef +Author: bluhm@openbsd.org +Date: Thu May 22 04:34:18 2025 +0000 - upstream: for parse_ipqos(), use strtonum() instead of mostly - - idiomatic strtoul(), but wow it's so gross. ok djm + upstream: Fix OpenBSD RCS ID typos. from Andrius V - OpenBSD-Commit-ID: cec14a76af2eb7b225300c80fc0e21052be67b05 + OpenBSD-Regress-ID: 5c03a2ef5323969fc4978f2eec4f1a25c48c572a -commit 8176e1a6c2e6da9361a7abb6fbf6c23c299f495b -Author: deraadt@openbsd.org -Date: Tue Apr 2 09:56:58 2024 +0000 +commit 2b2a7a2a0d70023b439080bb2770ff36522dbea8 +Author: Darren Tucker +Date: Thu May 22 22:09:48 2025 +1000 - upstream: can shortcut by returning strtonum() value directly; ok - - djm + Remove debug change accidentally commited. - OpenBSD-Commit-ID: 7bb2dd3d6d1f288dac14247d1de446e3d7ba8b8e + Fixes Coverity CID 481160. -commit 9f543d7022a781f80bb696f9d73f1d1c6f9e31d6 -Author: deraadt@openbsd.org -Date: Tue Apr 2 09:52:14 2024 +0000 +commit 450a8a1df1577ddbe68fe8da1fb8514d3781ef32 +Author: Darren Tucker +Date: Thu May 22 21:16:37 2025 +1000 - upstream: rewrite convtime() to use a isdigit-scanner and + Collect all of regress dir on failure. - strtonum() instead of strange strtoul can might be fooled by garage - characters. passes regress/usr.bin/ssh/unittests/misc ok djm + This may allow us to sort through its entrails and determine the cause + of some types of failures. + +commit de25e739781c4c09d20abd410f50f0a6f192dc72 +Author: Damien Miller +Date: Thu May 22 18:42:44 2025 +1000 + + minimal shims for fstatat(2)/unlinkat(2) in agent - OpenBSD-Commit-ID: 4b1ef826bb16047aea3f3bdcb385b72ffd450abc + Add some very minimal and task-specific replacements for + fstatat(2) and unlinkat(2) in the ssh-agent socket cleanup + loop, for platforms that lack these functions. ok dtucker@ -commit 8673137f780d8d9e4cda3c4605cb5d88d5cea271 -Author: claudio@openbsd.org -Date: Tue Apr 2 09:48:24 2024 +0000 +commit 6d192645a613aa814d51050b0458f37265b90d6c +Author: dtucker@openbsd.org +Date: Thu May 22 04:22:03 2025 +0000 - upstream: Remove unused ptr[3] char array in pkcs11_decode_hex. + upstream: Output the current name for PermitRootLogin's - OK deraadt@ + "prohibit-password" in sshd -T instead of its deprecated alias + "without-password". bz#3788, patch from cjwatson at debian.org. - OpenBSD-Commit-ID: 3d14433e39fd558f662d3b0431c4c555ef920481 + OpenBSD-Commit-ID: 2d5df18d5ad33a9b6c7547ec78a8e6ea13813df9 -commit c7fec708f331f108343d69e4d74c9a5d86d6cfe7 -Author: deraadt@openbsd.org -Date: Tue Apr 2 09:32:28 2024 +0000 +commit 1ccf42378df202472e7254f37f7dabb2f5723955 +Author: dtucker@openbsd.org +Date: Thu May 22 03:53:46 2025 +0000 - upstream: Replace non-idiomatic strtoul(, 16) to parse a region + upstream: Copy arg to be passed to dirname(). - of 2-character hex sequences with a low-level replacement designed just for - the task. ok djm + POSIX allows dirname() to modify its args and return a pointer into it, + so this prevents an overlapping strlcpy. bz#3819, patch from cjwatson + at debian.org - OpenBSD-Commit-ID: 67bab8b8a4329a19a0add5085eacd6f4cc215e85 + OpenBSD-Commit-ID: c32e496e6a1618aba31c8b7a9d4e1376c5ea6aa1 -commit 019a5f483b0f588da6270ec401d0b4bb35032f3f -Author: deraadt@openbsd.org -Date: Tue Apr 2 09:29:31 2024 +0000 +commit b5877b7b3e597f47578ade9dbe7e4332f112dfc4 +Author: dtucker@openbsd.org +Date: Thu May 22 03:41:10 2025 +0000 - upstream: Use strtonum() instead of severely non-idomatic - - strtoul() In particular this will now reject trailing garbage, ie. - '12garbage'. ok djm + upstream: Add $OpenBSD$ marker for easier syncing. - OpenBSD-Commit-ID: c82d95e3ccbfedfc91a8041c2f8bf0cf987d1501 + OpenBSD-Commit-ID: 27ff3e1e2e6610d9981ebe43ae9b783236800035 -commit 8231ca046fa39ea4eb99b79e0a6e09dec50ac952 -Author: deraadt@openbsd.org -Date: Mon Apr 1 15:50:17 2024 +0000 +commit 58d094c7cb974d7bd3ba6eb1059b186a2ac3dd55 +Author: djm@openbsd.org +Date: Wed May 21 12:12:20 2025 +0000 - upstream: also create a relink kit for ssh-agent, since it is a + upstream: Correct FILES section to mention new default path to - long-running setgid program carrying keys with some (not very powerful) - communication channels. solution for testing the binary from dtucker. - agreement from djm. Will add it into /etc/rc in a few days. + agent sockets. Spotted by / ok jmc@ - OpenBSD-Commit-ID: 2fe8d707ae35ba23c7916adcb818bb5b66837ba0 + OpenBSD-Commit-ID: 91d736d78d71a4276c9cbb075b1462bbc3df55a6 -commit bf7bf50bd6a14e49c9c243cb8f4de31e555a5a2e -Author: deraadt@openbsd.org -Date: Mon Apr 1 15:48:16 2024 +0000 +commit d1d5c8b9b8de8283618c18d0dafdec6a209911cc +Author: Darren Tucker +Date: Thu May 22 12:25:35 2025 +1000 - upstream: new-style relink kit for sshd. The old scheme created - - a Makefile by concatenating two Makefiles and was incredibly fragile. In the - new way a narrow-purposed install.sh script is created and shipped with the - objects. A recently commited /etc/rc script understands these files. - - OpenBSD-Commit-ID: ef9341d5a50f0d33e3a6fbe995e92964bc7ef2d3 - -commit 00e63688920905e326d8667cb47f17a156b6dc8f -Author: renmingshuai -Date: Fri Apr 12 10:20:49 2024 +0800 - - Shell syntax fix (leftover from a sync). - - Signed-off-by: renmingshuai + Fix nc install some more. -commit 2eded551ba96e66bc3afbbcc883812c2eac02bd7 +commit 49a2412ad23162e44be9e0b2cb12f6daf6b666d7 Author: Darren Tucker -Date: Thu Apr 25 13:20:19 2024 +1000 +Date: Thu May 22 12:21:11 2025 +1000 - Merge flags for OpenSSL 3.x versions. - - OpenSSL has moved to 3.4 which we don't currently accept. Based on - the OpenSSL versioning policy[0] it looks like all of the 3.x versions - should work with OpenSSH, so remove the distinction in configure and - accept all of them. - - [0] https://openssl.org/policies/general/versioning-policy.html + Fix cvs up of nc. -commit 8673245918081c6d1dc7fb3733c8eb2c5a902c5e +commit df22801b3f0ae245f825cf9c9dbb4543e41a7c5c Author: Darren Tucker -Date: Thu Apr 25 13:19:03 2024 +1000 +Date: Thu May 22 11:34:04 2025 +1000 - Remove 9.6 branch from status page. + Install nc during upstream test. + + This ensures that the installed nc matches the expectations of the + regress tests. -commit 70d43049747fa3c66cf876d52271859407cec2fa +commit e391c5289c2b687ff886cf780dc8fcb426e4d5d2 Author: Darren Tucker -Date: Thu Apr 25 13:16:58 2024 +1000 +Date: Thu May 22 10:52:31 2025 +1000 - Update LibreSSL and OpenSSL versions tested. + Remove 9.7 branch from CI status page. - Update LibreSSL versions to current releases (3.8.4 & 3.9.1). - Add newly-released OpenSSL 3.3.0, and add tests against the 3.1 and - 3.3 branches. - -commit 88351eca17dcc55189991ba60e50819b6d4193c1 -Author: 90 -Date: Fri Apr 5 19:36:06 2024 +0100 - - Fix missing header for systemd notification + It's been obsolete long enough that github no longer reports its + status. -commit 08f579231cd38a1c657aaa6ddeb8ab57a1fd4f5c +commit b71773c20d566fa5dcaf9edf3139bdcb3f2c4bc2 Author: Damien Miller -Date: Wed Apr 3 14:40:32 2024 +1100 - - notify systemd on listen and reload - - Standalone implementation that does not depend on libsystemd. - With assistance from Luca Boccassi, and feedback/testing from Colin - Watson. bz2641 - -commit 43e7c1c07cf6aae7f4394ca8ae91a3efc46514e2 -Author: Darren Tucker -Date: Sun Mar 31 21:51:57 2024 +1100 +Date: Wed May 21 19:14:47 2025 +1000 - Port changes from selfhosted to upstream tests. - - Should get them working again. + pull a small netcat SOCKS4A fix from upstream -commit 281ea25a44bff53eefb4af7bab7aa670b1f8b6b2 -Author: Darren Tucker -Date: Sat Mar 30 18:20:16 2024 +1100 +commit 0adb2db25eff3fe1c90c55654387ae1e4e18a396 +Author: djm@openbsd.org +Date: Wed May 21 08:41:52 2025 +0000 - Check if OpenSSL implementation supports DSA. + upstream: test SOCKS4A; ok tb - If --enable/disable-dsa-keys is not specified, set based on what OpenSSL - supports. If specified as enabled, but not supported by OpenSSL error - out. ok djm@ + OpenBSD-Regress-ID: d880b75280295cd581a86e39bb0996d347f122d2 -commit 2d2c068de8d696fe3246f390b146197f51ea1e83 +commit 5699f4e9553c6a228fd9dc578d99e3aa6451c014 Author: djm@openbsd.org -Date: Sat Mar 30 05:56:22 2024 +0000 +Date: Wed May 21 08:36:39 2025 +0000 - upstream: in OpenSSH private key format, correct type for subsequent + upstream: remove log tarballing "it seemed like a good idea at the - private keys in blob. From Jakub Jelen via GHPR430 + time" - dtucker@ - OpenBSD-Commit-ID: d17dbf47554de2d752061592f95b5d772baab50b + ensure that log files have correct perms when running under sudo/doas + + ok dtucker@ + + OpenBSD-Regress-ID: 20588c14b05de9519f85d638b374b66ae0678c89 -commit c2c0bdd3e96b3ef66d77fccb85ff4962dc76caf0 -Author: Eero Häkkinen -Date: Sat Sep 16 00:55:08 2023 +0300 +commit 0c14e6b69a20f20d602e0e72559ca3f4dbc797fb +Author: djm@openbsd.org +Date: Wed May 21 06:44:24 2025 +0000 - Expose SSH_AUTH_INFO_0 always to PAM auth modules. + upstream: use logit_f("...") instead of logit("func: ...") - This changes SSH_AUTH_INFO_0 to be exposed to PAM auth modules also - when a password authentication method is in use and not only - when a keyboard-interactive authentication method is in use. + OpenBSD-Commit-ID: c8d49eb39a9abff3cbcaeaf7df9d48468a5a0695 -commit 02c5ad23124ae801cf248d99ea5068fc4331ca01 -Author: Darren Tucker -Date: Wed Mar 27 17:42:58 2024 +1100 +commit 1743589d038476f28dc4dfb1f69317649ae22ac5 +Author: djm@openbsd.org +Date: Wed May 21 06:43:48 2025 +0000 - Rearrange selfhosted VM scheduling. - - Instead of trying to infer the type of the self hosted tests in each of - the driver scripts (inconsistently...), set one of the following - variables to "true" in the workflow: + upstream: function to make a sshbuf from a hex string; useful in - VM: tests run in a virtual machine. - EPHEMERAL: tests run on an ephemeral virtual machine. - PERSISTENT: tests run on a persistent virtual machine - REMOTE: tests run on a physical remote host. + tests - EPHEMERAL VMs can have multiple instances of any given VM can exist - simultaneously and are run by a runner pool. The other types have a - dedicated runner instance and can only run a single test at a time. + also constify some arguments - Other settings: - SSHFS: We need to sshfs mount over the repo so the workflow can collect - build artifacts. This also implies the tests must be run over ssh. - DEBUG_ACTIONS: enable "set -x" in scripts for debugging. + OpenBSD-Commit-ID: 00f9c25b256be0efd73f2d8268ff041bc45ffb2c -commit cd8a72707c02615365d0851ac51063ab6bfe258f +commit 83729cf503289104d7e64a69be14579523988cb6 Author: Damien Miller -Date: Sat Mar 30 16:05:59 2024 +1100 - - add new token-based signing key for dtucker@ - - Verified in person and via signature with old key. - Will remove old key in a bit. - -commit 8d0e46c1ddb5b7f0992591b0dc5d8aaa77cc9dba -Author: Alkaid -Date: Tue Mar 12 03:59:12 2024 -0700 +Date: Wed May 21 18:47:46 2025 +1000 - Fix OpenSSL ED25519 support detection + merge netcat SOCKS4A support from OpenBSD - Wrong function signature in configure.ac prevents openssh from enabling - the recently new support for ED25519 priv keys in PEM PKCS8 format. + Not a full sync of this file as we have diverged substantially + from upstream (it has libtls support, etc.) -commit 697359be9c23ee43618243cdbcc9c7981e766752 -Author: djm@openbsd.org -Date: Sat Mar 30 04:27:44 2024 +0000 +commit 750f1867476bda36879f69e25e8f52cb45c58807 +Author: Darren Tucker +Date: Tue May 20 22:17:02 2025 +1000 - upstream: allow WAYLAND_DISPLAY to enable SSH_ASKPASS - - From dkg via GHPR479; ok dtucker@ - - OpenBSD-Commit-ID: 1ac1f9c45da44eabbae89375393c662349239257 + Include OpenSSL compat shim where needed. -commit 7844705b0364574cc70b941be72036c2c2966363 -Author: dtucker@openbsd.org -Date: Fri Mar 29 10:40:07 2024 +0000 +commit 6fb728df50c1afd338cb0223a84ce24579577eff +Author: Darren Tucker +Date: Tue May 20 19:28:55 2025 +1000 - upstream: Use egrep instead of grep -E. + Run all tests on Cygwin again. - Some plaforms don't have the latter so this makes things easier - in -portable. - - OpenBSD-Regress-ID: ff82260eb0db1f11130200b25d820cf73753bbe3 + ... now that we've fixed ci-setup on Cygwin. -commit 22b2b6c555334bffdf357a2e4aa74308b03b83c3 -Author: dtucker@openbsd.org -Date: Tue Mar 26 08:09:16 2024 +0000 +commit 648a3a008cf1cfa54631d2f0457b5313c455f484 +Author: Darren Tucker +Date: Tue May 20 18:48:23 2025 +1000 - upstream: test -h is the POSIXly way of testing for a symlink. Reduces - - diff vs Portable. + Use USERNAME rather than LOGNAME on Cygwin. - OpenBSD-Regress-ID: 6f31cd6e231e3b8c5c2ca0307573ccb7484bff7d + LOGNAME is specified by POSIX, but Windows (or at least, github's + Windows images) don't set it. -commit edcff77f82c2bb2b5653b36f1e47274c5ef3e8be +commit 0214e53124c09528b6ee29b9a551442b5611a454 Author: Darren Tucker -Date: Tue Mar 26 18:58:58 2024 +1100 +Date: Tue May 20 18:28:52 2025 +1000 - Fix name of OpenBSD upstream CI jobs. + Add debug output when setting up CI environment. -commit 861b084429940e024f1b6e9c2779eac95d7a45db +commit 9d9a2c0369419f3b4952e597db7b8696f54e7f3a Author: Darren Tucker -Date: Tue Mar 26 18:55:33 2024 +1100 - - Resync with upstream: ${} around DATAFILE. - -commit 63f248c7693e7f0a3b9a13d2980ac9a7e37f2aea -Author: djm@openbsd.org -Date: Mon Mar 25 19:28:09 2024 +0000 +Date: Tue May 20 19:16:38 2025 +1000 - upstream: optional debugging + Include openssl compat shims in test. - OpenBSD-Regress-ID: b4852bf97ac8fb2e3530f2d5f999edd66058d7bc + Fixes tests on platforms using older LibreSSL releases prior to 3.4. -commit 16e2ebe06a62f09d4877b769876d92d6008a896f -Author: dtucker@openbsd.org -Date: Mon Mar 25 06:05:42 2024 +0000 +commit 1a9b1cfa4e8b807c7f82fdba8f730c2abdbba071 +Author: Darren Tucker +Date: Tue May 20 18:14:06 2025 +1000 - upstream: Verify string returned from local shell command. + Add compat shims for EC_POINT affine_coordinates - OpenBSD-Regress-ID: 5039bde24d33d809aebfa8d3ad7fe9053224e6f8 + LibreSSL <3.4 does not have EC_POINT_[gs]et_affine_coordinates + but does have the now-deprecated _GFp variantes. We still support + LibreSSL back as far as 3.2.x so add a compat shim. -commit b326f7a1f39ff31324cc3fe2735178fb474c04a4 -Author: dtucker@openbsd.org -Date: Mon Mar 25 03:30:31 2024 +0000 +commit cff2175200b412a9207a4fe5c1bdcc54e8a73d07 +Author: tb@openbsd.org +Date: Mon May 12 05:42:02 2025 +0000 - upstream: Improve shell portability: grep -q is not portable so + upstream: Use EC_POINT_[sg]et_affine_coordinates() - redirect stdout, and use printf instead of relying on echo to do \n - substitution. Reduces diff vs Portable. + It is available in all supported OpenSSL flavors/versions and the _GFp + variants will be removed from LibreSSL. - Also resync somewhat with upstream. + ok hshoexer jsing - OpenBSD-Regress-ID: 9ae876a8ec4c4725f1e9820a0667360ee2398337 + OpenBSD-Regress-ID: 66cf1561e7b6c49002978f2d6720956f33a882f0 -commit dbf2e319f0c582613fa45a735ea3c242ce56946b -Author: dtucker@openbsd.org -Date: Mon Mar 25 02:07:08 2024 +0000 +commit 2d35e24739b515394017b74465a0996c384cf28f +Author: tb@openbsd.org +Date: Mon May 12 05:41:20 2025 +0000 - upstream: Save error code from SSH for use inside case statement, + upstream: Use EC_POINT_[sg]et_affine_coordinates() - from portable. In some shells, "case" will reset the value of $?, so save it - first. + It is available in all supported OpenSSL flavors/versions and the _GFp + variants will be removed from LibreSSL. - OpenBSD-Regress-ID: da32e5be19299cb4f0f7de7f29c11257a62d6949 + ok hshoexer jsing + + OpenBSD-Commit-ID: ecedca0e1ffa80e0c9ef7c787bc6a972882c596b -commit d2c8c4fa7def4fb057ed05b3db57b62c810a26f6 -Author: dtucker@openbsd.org -Date: Mon Mar 25 01:40:47 2024 +0000 +commit 17003b9f1cd7b7bf1f52493cc4a1ab95727c3ed7 +Author: djm@openbsd.org +Date: Fri May 9 02:42:03 2025 +0000 - upstream: Increase timeout. Resyncs with portable where some of + upstream: make the progress-meter code safe against being called - the test VMs are slow enough for this to matter. + when not initialised; spotted by tb@ feedback/ok tb@ deraadt@ - OpenBSD-Regress-ID: 6a83a693602eb0312f06a4ad2cd6f40d99d24b26 + OpenBSD-Commit-ID: a9fda1ee08a24c62e0981ff6d15ca93b63467038 -commit 83621b63514a84791623db3efb59d38bc4bf9563 -Author: dtucker@openbsd.org -Date: Mon Mar 25 01:28:29 2024 +0000 +commit 2d023e7a95d673e93ccc1978bf8931f7335b2b53 +Author: tedu@openbsd.org +Date: Thu May 8 17:32:53 2025 +0000 - upstream: In PuTTY interop test, don't assume the PuTTY major + upstream: convert a last quad_t to int64_t. ok deraadt djm - version is 0. Patch from cjwatson at debian.org via bz#3671. + OpenBSD-Commit-ID: 1c9e01ba1a9ccf442a9cdf10f222077f66885f1f + +commit fc8c56ade809f66f7df4b5153a4d92593631c12a +Author: Darren Tucker +Date: Tue May 20 15:01:29 2025 +1000 + + Set runner pasword to random string. - OpenBSD-Regress-ID: 835ed03c1b04ad46be82e674495521f11b840191 + The most recent version of the Github ubuntu-latest image sets the + password field to "!" which sshd considers to be a locked account, + breaking most of the tests. -commit 8a421b927700f3834b4d985778e252b8e3299f83 +commit c404686c17daeda7e95ca6fc14c8a4a570cf975d Author: Darren Tucker -Date: Tue Mar 26 18:38:14 2024 +1100 +Date: Sun May 11 22:54:13 2025 +1000 - Really mkdir /usr/local/etc in CI tests. + Debug log for why an account is considered locked. -commit 2946ed522c47ce045314533d426b4e379f745e59 +commit ee1d31781cf0d292a50b4df4cb8cb6ffcbfbe9af Author: Darren Tucker -Date: Tue Mar 26 17:19:09 2024 +1100 +Date: Sun May 11 16:35:31 2025 +1000 - Better short name for OpenBSD upstream CI jobs too. + Move debug log output into separate workflow step. + + Should reduce the need to scroll back to find out which test actually + failed. -commit 18dbe8eff647aacb82d7e86b4ce63d5beee11f25 +commit ddfb78a15f57a33427d462b9c401de5c8e6799da Author: Darren Tucker -Date: Tue Mar 26 17:13:52 2024 +1100 +Date: Sat May 10 21:48:06 2025 +1000 - Ensure /usr/local/etc exists before using in tests. + Skip sftp-perm on Cygwin too. -commit 5fc1085128e3348bb1b5ee4d955cc767b019b3ad +commit 8846caccb86b3f5a4f1c10bfffcc9cf1adc17925 Author: Darren Tucker -Date: Tue Mar 26 16:50:46 2024 +1100 +Date: Sat May 10 10:23:30 2025 +1000 - Be more specific about when to rerun workflows. + Remove CYGWIN binmode as it's now obsolete. -commit 5516923e8ae3da0823fea0d7d28aa813627142c0 +commit cf795d55437e6c1ffe85e90e0fae00e885e50036 Author: Darren Tucker -Date: Tue Mar 26 16:35:27 2024 +1100 +Date: Sat May 10 09:25:18 2025 +1000 - Add short names for test jobs on github CI. + Also skip sftp-cmds test on Cygwin. + + Fails at the hardlink step. -commit dc37d2d2470b4a9cedcee9ac926b7362214e3305 +commit d1b28639c1cb382943bd92c68992ea74af9b5773 Author: Darren Tucker -Date: Tue Mar 26 16:26:14 2024 +1100 +Date: Sat May 10 08:52:11 2025 +1000 - If we're using xpg4's id, remember to pass args. + Tell Cygwin to use native symlinks. -commit fe169487937780392b23d3ff3c00e5898c10f784 -Author: dtucker@openbsd.org -Date: Tue Mar 26 01:23:11 2024 +0000 +commit 56782dad7d7f96b4943951227515bd7904ac3cf7 +Author: Darren Tucker +Date: Sat May 10 08:26:37 2025 +1000 - upstream: Import regenerated moduli. + Skip keygen-knownhost test on Cygwin. - OpenBSD-Commit-ID: ad3d1486d105b008c93e952d158e5af4d9d4c531 + It fails but at this time it's not clear why. -commit 151146f03b490d19145cd421763aa7d42f5c50e2 -Author: job@openbsd.org -Date: Thu Mar 14 06:23:14 2024 +0000 +commit d5cbac2364b03e55b733a2422a07e78e16d2a118 +Author: Darren Tucker +Date: Sat May 10 07:59:44 2025 +1000 - upstream: Clarify how literal IPv6 addresses can be used in -J mode + Pass Cygwin setup location to CI setup. - OK djm@ - - OpenBSD-Commit-ID: 524ddae97746b3563ad4a887dfd0a6e6ba114c50 + (instead of hard coding it, wrongly). -commit 0d5bdc87a675271862b67eb6a9fb13a202fb4894 +commit 82f1f52c5582f005761e4e200c279ddd9c6781e4 Author: Darren Tucker -Date: Mon Mar 25 16:14:21 2024 +1100 +Date: Sat May 10 06:37:24 2025 +1000 - Add Mac OS X 14 test targets. + Add RUN_ONLY_TEST to limit which tests are run. + + For testing, you can set the repo variable RUN_ONLY_TEST in your repo + (Repo -> Settings -> Security -> Actions -> Variables) to run only that test. -commit 2d7964a03e1f50a48040ec6912c0a956df909d21 +commit 140ba45895de8ebfb3e2517b0ddee58729979c29 Author: Darren Tucker -Date: Mon Mar 25 14:05:40 2024 +1100 +Date: Fri May 9 19:32:06 2025 +1000 - Move xpg4 'id' handling into test-exec.sh. + Move misc-agent.o to LIBSSH_OBJS. - Handle replacement of 'id' the same way as we do other Portable specific - replacements in test-exec.sh. This brings percent.sh back into sync - with upstream. + It's needed by the fuzzer. -commit 75d1d49ed10d978171cdafad28bdbffdbd48f41e +commit 3357bf2fe2d11b6ed4465c1ed2871bd1099cbbc5 Author: Darren Tucker -Date: Mon Mar 25 10:38:03 2024 +1100 +Date: Fri May 9 19:08:36 2025 +1000 - Update branches shown on ci-status to 9.7 and 9.6. + Put PRIV_ECDSA back, it's still used. + + Should fix oss-fuzz test. -commit f9193f03db0029fc9c31fbdb5c66a2737446bd8f +commit f5726215957bb34e18bb872d527845c2f64e2389 Author: Darren Tucker -Date: Mon Mar 25 09:28:02 2024 +1100 +Date: Thu May 8 18:56:39 2025 +1000 - Improve detection of -fzero-call-used-regs=used. + Since it's unused, make dirfd() take void *. - Should better detect problems with gcc 13 on m68k. bz#3673 from Colin - Watson via bz#3673 and https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110934 - - Signed-off-by: Darren Tucker + Some platforms (eg Old BSDs) in some configurations define DIR to "void + *", which causes compile errors in the no-op implementation. -commit 86bdd3853f4d32c85e295e6216a2fe0953ad93f0 -Author: Damien Miller -Date: Mon Mar 11 16:20:49 2024 +1100 +commit 1511f113a27d8aafe080aa6493cb3c0cf2b5abe0 +Author: Darren Tucker +Date: Thu May 8 11:38:24 2025 +1000 - version number in README + Add no-op implmentation of dirfd(). + + Fixes build on pre-POSIX.1 2008 systems. -commit 282721418e6465bc39ccfd39bb0133e670ee4423 -Author: Damien Miller -Date: Mon Mar 11 16:20:08 2024 +1100 - - crank RPM spec versions - -commit 3876a3bbd2ca84d23ba20f8b69ba83270c04ce3a -Author: djm@openbsd.org -Date: Mon Mar 11 04:59:47 2024 +0000 +commit 086369736a9496b39af0d9f09443fa81b59b7f05 +Author: Daniel Kahn Gillmor +Date: Wed Apr 16 10:18:34 2025 +1000 - upstream: openssh-9.7 + ssh-agent: exit 0 from SIGTERM under systemd socket-activation - OpenBSD-Commit-ID: 618ececf58b8cdae016b149787af06240f7b0cbc + When the ssh-agent service is configured to be launched under systemd + socket-activation, the user can inspect the status of the agent with + something like: + + systemctl --user status ssh-agent.service + + If the user does: + + systemctl --user stop ssh-agent.service + + it causes the `systemd --user` supervisor to send a SIGTERM to the + agent, which terminates while leaving the systemd-managed socket in + place. That's good, and as expected. (If the user wants to close the + socket, they can do "systemctl --user stop ssh-agent.socket" instead) + + But because ssh-agent exits with code 2 in response to a SIGTERM, the + supervisor marks the service as "failed", even though the state of the + supervised service is exactly the same as during session startup (not + running, ready to launch when a client connects to the socket). + + This change makes ssh-agent exit cleanly (code 0) in response to a + SIGTERM when launched under socket activation. This aligns the systemd + supervisor's understanding of the state of supervised ssh-agent with + reality. + + Signed-off-by: Daniel Kahn Gillmor -commit 8fc109cc614954a8eb2738c48c0db36a62af9a06 +commit 755c3d082e59e6884f28d30e6333a1444e9173d1 Author: Darren Tucker -Date: Mon Mar 11 12:59:26 2024 +1100 +Date: Wed May 7 21:05:06 2025 +1000 - Test against current OpenSSL and LibreSSL releases. + Skip d_type check on platforms that don't have it. - Add LibreSSL 3.9.0, bump older branches to their respective current - releases. + On those, the subsequent stat() should catch the sockets. -commit 26b09b45fec7b88ba09042c09be4157e58e231e2 -Author: Damien Miller -Date: Sun Mar 10 16:24:57 2024 +1100 +commit 207289a5663bdf49903e1aeb938dcc0924e2ac63 +Author: dtucker@openbsd.org +Date: Wed May 7 10:44:26 2025 +0000 - quote regexes used to test for algorithm support + upstream: Rename sockaddr_un sun -> sunaddr. - Fixes test failures on Solaris 8 reported by Tom G. Christensen + This makes things easier in -portable, where on Solaris an derivatives + "sun" is defined to "1", causing compilation errors. ok deraadt@. + + OpenBSD-Commit-ID: 0669043afb49856b57b382f0489221bd98305d3b -commit a6a740a4948d10a622b505135bb485c10f21db5e +commit 7cc8e150d51a4545b86d996692b541419b35d1a3 Author: djm@openbsd.org -Date: Sat Mar 9 05:12:13 2024 +0000 +Date: Tue May 6 06:05:48 2025 +0000 - upstream: avoid logging in signal handler by converting mainloop to - - ppoll() bz3670, reported by Ben Hamilton; ok dtucker@ + upstream: remove DSA from the regression/unit test suite too. - OpenBSD-Commit-ID: e58f18042b86425405ca09e6e9d7dfa1df9f5f7f + OpenBSD-Regress-ID: 4424d2eaf0bce3887318ef6d18de6c06f3617d6e -commit cd82f7526e0481720567ae41db7849ab1c27e27b +commit 0404fa799746c283325a463c363436eb152daefc Author: djm@openbsd.org -Date: Fri Mar 8 22:16:32 2024 +0000 +Date: Tue Apr 15 05:31:24 2025 +0000 - upstream: skip more whitespace, fixes find-principals on - - allowed_signers files with blank lines; reported by Wiktor Kwapisiewicz + upstream: another missing ifdef - OpenBSD-Commit-ID: b3a22a2afd753d70766f34bc7f309c03706b5298 + OpenBSD-Regress-ID: 4f71f8f122eac4cbf7f1d2088a9be45317dd3e4a -commit 2f9d2af5cb19905d87f37d1e11c9f035ac5daf3b -Author: dtucker@openbsd.org -Date: Fri Mar 8 11:34:10 2024 +0000 +commit c5dbbe8805caaee132545ab4cffd3b2221e80975 +Author: djm@openbsd.org +Date: Tue Apr 15 05:00:13 2025 +0000 - upstream: Invoke ProxyCommand that uses stderr redirection via + upstream: missing ifdef - $TEST_SHELL. Fixes test when run by a user whose login shell is tcsh. - Found by vinschen at redhat.com. + OpenBSD-Regress-ID: 7260fb672de5738c17dec06c71a5be0186bb2b09 + +commit 93e904a673a632604525fdc98b940b7996f1ce54 +Author: djm@openbsd.org +Date: Wed May 7 04:10:21 2025 +0000 + + upstream: memory leak on error path; bz3821 - OpenBSD-Regress-ID: f68d79e7f00caa8d216ebe00ee5f0adbb944062a + OpenBSD-Commit-ID: 65577596a15ad6dd9a1ab3fc24c1c31303ee6e2b -commit 9b3f0beb4007a7e01dfedabb429097fb593deae6 -Author: Darren Tucker -Date: Thu Mar 7 17:18:14 2024 +1100 +commit 55b38ff4d7286c8fac2a472da664462e0f2d75e0 +Author: deraadt@openbsd.org +Date: Tue May 6 15:15:05 2025 +0000 - Prefer openssl binary from --with-ssl-dir directory. + upstream: test ssh-agent with the -T flag to force the old /tmp - Use openssl in the directory specified by --with-ssl-dir as long - as it's functional. Reported by The Doctor. + location rather than inside the homedir. During relink operation, + /.ssh/agent was created which is surprising. This test sequence could use + some improvement so this is a temporary fix. observed by florian, change ok + semarie + + OpenBSD-Commit-ID: c7246a6b519ac390ca550719f91acfdaef1fa0f0 -commit c47e1c9c7911f38b2fc2fb01b1f6ae3a3121a838 +commit a32d28d792567253bb601362f36391f155f8f772 Author: djm@openbsd.org -Date: Wed Mar 6 02:59:59 2024 +0000 +Date: Tue May 6 05:40:56 2025 +0000 - upstream: fix memory leak in mux proxy mode when requesting forwarding. + upstream: finally remove DSA signature support from OpenSSH. - found by RASU JSC, reported by Maks Mishin in GHPR#467 + feedback/ok tb@, ok deraadt@ - OpenBSD-Commit-ID: 97d96a166b1ad4b8d229864a553e3e56d3116860 + OpenBSD-Commit-ID: bfe6ee73c1b676c81a2901030c791f8ec888228f -commit 242742827fea4508e68097c128e802edc79addb5 +commit 928f8dcc1bb622c25be409c34374b655d0149373 Author: djm@openbsd.org -Date: Wed Mar 6 00:31:04 2024 +0000 +Date: Mon May 5 05:51:11 2025 +0000 - upstream: wrap a few PKCS#11-specific bits in ENABLE_PKCS11 + upstream: Now that there's an I-D for certificate keys, refer to - OpenBSD-Commit-ID: 463e4a69eef3426a43a2b922c4e7b2011885d923 + that instead of the much more basic format description we had previously. + + OpenBSD-Commit-ID: cf01e0727a813fee8626ad7b3aa240621cc92014 -commit d52b6509210e2043f33e5a1de58dd4a0d5d48c2a -Author: Damien Miller -Date: Wed Mar 6 11:31:36 2024 +1100 +commit fe883543bece18c975fa53aa02104f0433645d99 +Author: jmc@openbsd.org +Date: Mon May 5 05:47:28 2025 +0000 - disable RSA tests when algorithm is not supported + upstream: - add full stop to the text in -a - move the -U and -u - Unbreaks "make test" when compiled --without-openssl. + text to the correct place - Similar treatment to how we do DSA and ECDSA. + OpenBSD-Commit-ID: 2fb484337a0978c703f61983bb14bc5cbaf898c2 -commit 668d270a6c77e8b5a1da26ecad2e6de9f62c8fe4 -Author: Damien Miller -Date: Wed Mar 6 10:33:20 2024 +1100 +commit 5fd6ef297dec23e3574646b6334087131230d0a6 +Author: Darren Tucker +Date: Tue May 6 19:01:00 2025 +1000 - add a --without-retpoline configure option + Add minimal implementations of fstatat and unlinkat. - discussed with deraadt and dtucker a while ago + Fixes build on some pre-POSIX.1-2008 platforms. -commit 3deb501f86fc47e175ef6a3eaba9b9846a80d444 -Author: djm@openbsd.org -Date: Mon Mar 4 04:13:18 2024 +0000 +commit d2480827b3ef6ec119965822afdff35d734b2dee +Author: Darren Tucker +Date: Tue May 6 08:15:34 2025 +1000 - upstream: fix leak of CanonicalizePermittedCNAMEs on error path; - - spotted by Coverity (CID 438039) - - OpenBSD-Commit-ID: 208839699939721f452a4418afc028a9f9d3d8af + New location of cygwin setup. -commit 65a44a8a4f7d902a64d4e60eda84384b2e2a24a2 -Author: djm@openbsd.org -Date: Mon Mar 4 02:16:11 2024 +0000 +commit 57eb87b15bd0343372f99d661ce95efb25a16f1e +Author: Darren Tucker +Date: Tue May 6 08:07:23 2025 +1000 - upstream: Separate parsing of string array options from applying them - - to the active configuration. This fixes the config parser from erroneously - rejecting cases like: - - AuthenticationMethods password - Match User ivy - AuthenticationMethods any - - bz3657 ok markus@ + Boringssl now puts libcrypto in a different place. + +commit 61525ba967ac1bb7394ea0792aa6030bcbbad049 +Author: Darren Tucker +Date: Mon May 5 20:45:42 2025 +1000 + + Handle systems that don't have st_mtim. - OpenBSD-Commit-ID: 7f196cba634c2a3dba115f3fac3c4635a2199491 + Ignores nanoseconds, but it's checking for >1h old so a few nanoseconds + shouldn't matter much. Fixes build on Mac OS X. -commit 6886e1b1f55c90942e4e6deed930f8ac32e0f938 +commit 27861e9b15151898841097c14ee974c026093131 Author: Darren Tucker -Date: Thu Feb 22 17:59:35 2024 +1100 +Date: Mon May 5 19:09:25 2025 +1000 - Add nbsd10 test target. + Supply timespecsub if needed. -commit d86bf8a3f6ea4fa7887406c2aa9959db71fa41be -Author: Damien Miller -Date: Thu Feb 22 12:06:10 2024 +1100 +commit 7c0e6626e4be53efcfbb92f0c6382a76f1138e38 +Author: Darren Tucker +Date: Mon May 5 19:08:48 2025 +1000 - more descriptive configure test name + includes.h for compat, time.h for clock_gettime. -commit 9ee335aacc9f5bdc4cc2c19fafb45e27be7d234e -Author: djm@openbsd.org -Date: Wed Feb 21 06:17:29 2024 +0000 +commit 7a7cc3cf721fe7fe9f4925d92bb7c694b8550a7f +Author: Darren Tucker +Date: Mon May 5 18:51:34 2025 +1000 - upstream: explain arguments of internal-sftp GHPR#454 from Niklas - - Hambüchen - MIME-Version: 1.0 - Content-Type: text/plain; charset=UTF-8 - Content-Transfer-Encoding: 8bit - - OpenBSD-Commit-ID: 0335d641ae6b5b6201b9ffd5dd06345ebbd0a3f3 + Cygwin install in back on D: -commit d1164cb1001dd208fee88aaa9b43d5e6fd917274 -Author: djm@openbsd.org -Date: Wed Feb 21 06:06:43 2024 +0000 +commit 6ab8133c067a8e91ba69ce7ca04f95b50f2f2d7b +Author: Damien Miller +Date: Mon May 5 14:59:30 2025 +1000 - upstream: clarify permissions requirements for ChrootDirectory Part - - of GHPR#454 from Niklas Hambüchen - MIME-Version: 1.0 - Content-Type: text/plain; charset=UTF-8 - Content-Transfer-Encoding: 8bit - - OpenBSD-Commit-ID: d37bc8786317a11649c62ff5e2936441186ef7a0 + depend -commit d410e17d186552d0717f18217d0d049486754365 +commit 12912429cf39cfeca97dd18a8f875ad9824d1751 Author: djm@openbsd.org -Date: Wed Feb 21 06:05:06 2024 +0000 +Date: Mon May 5 03:35:06 2025 +0000 - upstream: .Cm for a keyword. Part of GHPR#454 from Niklas Hambüchen + upstream: missing file in previous commit - OpenBSD-Commit-ID: d59c52559f926fa82859035d79749fbb4a3ce18a + OpenBSD-Commit-ID: e526c97fcb2fd9f0b7b229720972426ab437d7eb -commit ab73f9678ebf06b32d6361b88b50b42775e0565b +commit 80162f9d7e7eadca4ffd0bd1c015d38cb1821ab6 Author: djm@openbsd.org -Date: Wed Feb 21 06:01:13 2024 +0000 +Date: Mon May 5 02:48:06 2025 +0000 - upstream: fix typo in match directive predicate (s/tagged/tag) GHPR#462 + upstream: Move agent listener sockets from /tmp to under - from Tobias Manske + ~/.ssh/agent for both ssh-agent(1) and forwarded sockets in sshd(8). - OpenBSD-Commit-ID: 05b23b772677d48aa82eefd7ebebd369ae758908 - -commit 9844aa2521ccfb1a2d73745680327b79e0574445 -Author: djm@openbsd.org -Date: Wed Feb 21 05:57:34 2024 +0000 - - upstream: fix proxy multiplexing mode, broken when keystroke timing + This ensures processes (such as Firefox) that have restricted + filesystem access that includes /tmp (via unveil(3)) do not have the + ability to use keys in an agent. - obfuscation was added. GHPR#463 from montag451 + Moving the default directory has the consequence that the OS will no + longer clean up stale agent sockets, so ssh-agent now gains this + ability. - OpenBSD-Commit-ID: 4e412d59b3f557d431f1d81c715a3bc0491cc677 + To support $HOME on NFS, the socket path includes a truncated hash of + the hostname. ssh-agent will by default only clean up sockets from + the same hostname. + + ssh-agent gains some new flags: -U suppresses the automatic cleanup + of stale sockets when it starts. -u forces a cleanup without + keeping a running agent, -uu forces a cleanup that ignores the + hostname. -T makes ssh-agent put the socket back in /tmp. + + feedback deraadt@ naddy@, doitdoitdoit deraadt@ + + OpenBSD-Commit-ID: 8383dabd98092fe5498d5f7f15c7d314b03a93e1 -commit ee6d932acb532f80b11bb7cf161668c70ec8a117 +commit 566443b5f5d7bc4c5310313b4e46232760850c7a Author: djm@openbsd.org -Date: Tue Feb 20 04:10:03 2024 +0000 +Date: Mon May 5 02:40:30 2025 +0000 - upstream: don't append a gratuitous space to the end of subsystem + upstream: correct log messages; the reap function is used for more - arguments; bz3667 + than just the preauth process now - OpenBSD-Commit-ID: e11023aeb3f30b77a674e37b8292c862926d5dc6 + OpenBSD-Commit-ID: 768c5b674bd77802bb197c31dba78559f1174c02 -commit e27f032aa8fcbae9b2e7c451baaf4b8ac6fa3d45 -Author: dtucker@openbsd.org -Date: Mon Feb 19 09:25:52 2024 +0000 +commit e048230106fb3f5e7cc07abc311c6feb5f52fd05 +Author: djm@openbsd.org +Date: Wed Apr 30 05:26:15 2025 +0000 - upstream: Always define puttysetup function. + upstream: make writing known_hosts lines more atomic, by writing - OpenBSD-Regress-ID: b4c0ccfa4006a1bc5dfd99ccf21c854d3ce2aee0 - -commit 84046f9991abef5f46b040b10cf3d494f933a17b -Author: dtucker@openbsd.org -Date: Fri Feb 9 08:56:59 2024 +0000 - - upstream: Exapnd PuTTY test coverage. + the entire line in one operation and using unbuffered stdio. - Expand the set of ciphers, MACs and KEX methods in the PuTTY interop - tests. + Usually writes to this file are serialised on the "Are you sure you + want to continue connecting?" prompt, but if host key checking is + disabled and connections were being made with high concurrency + then interleaved writes might have been possible. - OpenBSD-Regress-ID: dd28d97d48efe7329a396d0d505ee2907bf7fc57 + feedback/ok deraadt@ millert@ + + OpenBSD-Commit-ID: d11222b49dabe5cfe0937b49cb439ba3d4847b08 -commit bbf541ee2afe07b08a8b56fa0dc6f38fcfceef2a -Author: dtucker@openbsd.org -Date: Fri Feb 9 08:47:42 2024 +0000 +commit c991273c18afc490313a9f282383eaf59d9c13b9 +Author: djm@openbsd.org +Date: Wed Apr 30 05:23:15 2025 +0000 - upstream: Factor out PuTTY setup. + upstream: fix a out-of-bounds read if the known_hosts file is - Factor out PuTTY and call only when needed. + truncated after the hostname. - This allows us to avoid PuTTY key setup when it's not needed, which - speeds up the overall test run by a couple of percent. + Reported by the OpenAI Security Research Team - OpenBSD-Regress-ID: c25eaccc3c91bc874400f7c85ce40e9032358c1c + ok deraadt@ + + OpenBSD-Commit-ID: c0b516d7c80c4779a403826f73bcd8adbbc54ebd -commit d31c21c57fb4245271680a1e5043cf6470a96766 -Author: naddy@openbsd.org -Date: Sat Feb 10 11:28:52 2024 +0000 +commit b5b405fee7f3e79d44e2d2971a4b6b4cc53f112e +Author: Darren Tucker +Date: Sun Apr 20 09:07:57 2025 +1000 - upstream: clean sshd random relinking kit; ok miod@ + Set Windows permssions on regress dir. - OpenBSD-Commit-ID: 509bb19bb9762a4b3b589af98bac2e730541b6d4 + Prevents "unprotected private key file" error when running tests. -commit 4dbc5a363ff53a2fcecf6bc3bcc038badc12f118 -Author: djm@openbsd.org -Date: Fri Feb 2 00:13:34 2024 +0000 +commit 76631fdd04824c3e50ea6551d3611b1fe0216a41 +Author: Darren Tucker +Date: Fri Apr 18 08:18:52 2025 +1000 - upstream: whitespace - - OpenBSD-Commit-ID: b24680bc755b621ea801ff8edf6f0f02b68edae1 + Add 10.0 branch to test status page. -commit efde85dda2130272af24cc346f6c3cd326182ff1 +commit c627b468d3b99e487e2b24c90958ae57e633d681 Author: Darren Tucker -Date: Mon Feb 19 17:29:31 2024 +1100 +Date: Fri Apr 18 08:14:16 2025 +1000 - Improve error message for OpenSSL header check. - - bz#3668, ok djm@ + cygwin-install-action now puts setup.exe on D: -commit cbbdf868bce431a59e2fa36ca244d5739429408d +commit 52bddbc1a7f53a1e5c871767913648eb639ac6d5 Author: Darren Tucker -Date: Wed Feb 7 13:45:02 2024 +1100 +Date: Fri Apr 18 08:10:32 2025 +1000 - Interop test against PuTTY snapshot and releases. + Include time.h for clock_gettime(). -commit 91898bf786b0f149f962c4c96c08a46f29888c10 +commit 9b50cb171b5c56184ce6fa3994ce62f9882d2daf Author: Darren Tucker -Date: Tue Feb 6 16:21:05 2024 +1100 +Date: Thu Apr 17 16:51:14 2025 +1000 - Put privsep dir on OS X on /usr/local. + Add includes.h for new tests. - On some runners we can't create /var/empty, so put it some place we can - write. Should fix test breakage on Max OS X 11. + Fixes builds on older platforms. -commit be5ed8ebed8388c5056bfde4688308cc873c18b9 +commit 46e52fdae08b89264a0b23f94391c2bf637def34 Author: Darren Tucker -Date: Tue Feb 6 11:19:42 2024 +1100 +Date: Wed Apr 16 22:29:17 2025 +1000 - Add --disable-fd-passing option. + Provide INFINITY if it's not provided. - .. and enable for the minix3 test VM. This will cause it to more reliably - skip tests that need FD passing and should fix the current test breakage. + INFINITY is specified in c99, so define if not provided. -commit 0f6a8a0d0a518fd78c4cbebfdac990a57a1c4e41 +commit 849c2fd894aa87a7e40c71e8d5bda5392b1205be Author: Darren Tucker -Date: Tue Feb 6 11:18:44 2024 +1100 +Date: Tue Apr 15 21:58:49 2025 +1000 - Use "skip" function instead doing it ourselves. + Look for sqrt(), possibly in libm. + + The unit tests now use sqrt(), which in some platforms (notably + DragonFlyBSD and Solaris) is not in libc but rather libm. Since only + the unit tests use this, add TESTLIBS and if necessary put libm in it. -commit 3ad669f81aabbd2ba9fbd472903f680f598e1e99 -Author: Damien Miller -Date: Thu Feb 1 14:01:18 2024 +1100 +commit 1ec5b39f1f673beac039bb42c98a11aa2b08a0b2 +Author: dtucker@openbsd.org +Date: Tue Apr 15 09:22:25 2025 +0000 - ignore some vim droppings + upstream: Cast signalled_keydrop to int when logging to prevent warning + + on platforms where sig_atomic_t is not the same as int. bz#3811, patch from + jlduran at gmail com. + + OpenBSD-Commit-ID: b6bc9e9006e7f81ade57d41a48623a4323deca6c -commit c283f29d23611a06bbee06bcf458f2fffad721d9 +commit f3d465530e75cb6c02e2cde1d15e6c4bb51ebfd9 Author: djm@openbsd.org -Date: Thu Feb 1 02:37:33 2024 +0000 +Date: Tue Apr 15 04:00:42 2025 +0000 - upstream: whitespace + upstream: basic benchmarking support for the unit test framework enable - OpenBSD-Commit-ID: bf9e4a1049562ee4322684fbdce07142f04fdbb7 - -commit 0d96b1506b2f4757fefa5d1f884d49e96a6fd4c3 -Author: Damien Miller -Date: Tue Jan 16 14:40:18 2024 +1100 - - skip tests that use multiplexing on Windows + with "make UNITTEST_BENCHMARK=yes" - Some tests here use multiplexing, skip these if DISABLE_FD_PASSING - is set. Should unbreak tests on Windows. + ok dtucker@ + + OpenBSD-Regress-ID: 7f16a2e247f860897ca46ff87bccbe6002a32564 -commit 50080fa42f5f744b798ee29400c0710f1b59f50e -Author: djm@openbsd.org -Date: Thu Jan 11 04:50:28 2024 +0000 +commit 609fe2cae2459d721ac11d23cd27b8a94397ef3c +Author: jmc@openbsd.org +Date: Mon Apr 14 05:41:42 2025 +0000 - upstream: don't disable RSA test when DSA is disabled; bug introduced + upstream: rework the text for -3 to make it clearer what default - in last commit + behaviour is, and adjust the text for -R to make them more consistent; - OpenBSD-Regress-ID: 8780a7250bf742b33010e9336359a1c516f2d7b5 + issue raised by mikhail mp39590; + behaviour explained by naddy + + ok djm + + OpenBSD-Commit-ID: 15ff3bd1518d86c84fa8e91d7aa72cfdb41dccc8 -commit 415c94ce17288e0cdcb9e58cc91fba78d33c8457 +commit 8725dbc5b5fcc3e326fc71189ef8dba4333362cc +Author: Damien Miller +Date: Wed Apr 9 17:02:17 2025 +1000 + + update version numbers + +commit cc7feb9458ad3b893b53dc9c7500d1affd208bde Author: djm@openbsd.org -Date: Thu Jan 11 01:45:58 2024 +0000 +Date: Wed Apr 9 07:00:21 2025 +0000 - upstream: make DSA testing optional, defaulting to on + upstream: openssh-10.0 - ok markus - - OpenBSD-Regress-ID: dfc27b5574e3f19dc4043395594cea5f90b8572a + OpenBSD-Commit-ID: db5b4a1f1c9e988f8f166b56dc5643606294b403 -commit f9311e8921d92c5efca767227a497ab63280ac39 +commit fc86875e6acb36401dfc1dfb6b628a9d1460f367 Author: djm@openbsd.org -Date: Thu Jan 11 01:51:16 2024 +0000 +Date: Wed Apr 9 07:00:03 2025 +0000 - upstream: ensure key_fd is filled when DSA is disabled; spotted by + upstream: Fix logic error in DisableForwarding option. This option - tb@ + was documented as disabling X11 and agent forwarding but it failed to do so. + Spotted by Tim Rice. - OpenBSD-Commit-ID: 9dd417b6eec3cf67e870f147464a8d93f076dce7 + OpenBSD-Commit-ID: fffc89195968f7eedd2fc57f0b1f1ef3193f5ed1 -commit 4e838120a759d187b036036610402cbda33f3203 +commit dd73459e351b0a2908aed90910c8ff9b0b381c6d Author: djm@openbsd.org -Date: Thu Jan 11 01:45:36 2024 +0000 +Date: Wed Apr 9 01:24:40 2025 +0000 - upstream: make DSA key support compile-time optional, defaulting to - - on - - ok markus@ + upstream: oops, I accidentally backed out the typo fix - OpenBSD-Commit-ID: 4f8e98fc1fd6de399d0921d5b31b3127a03f581d + OpenBSD-Commit-ID: f485f79bf3e9ebbe1de13ac96150cf458956cfd8 -commit afcc9028bfc411bc26d20bba803b83f90cb84e26 -Author: jmc@openbsd.org -Date: Wed Jan 10 06:33:13 2024 +0000 +commit 0cb945891944bada5850e85d60afa3c807cf1af6 +Author: djm@openbsd.org +Date: Wed Apr 9 01:23:47 2025 +0000 - upstream: fix incorrect capitalisation; + upstream: typo - OpenBSD-Commit-ID: cb07eb06e15fa2334660ac73e98f29b6a1931984 + OpenBSD-Commit-ID: f912725c7d303720706b3ccfb2cb846d46296d13 -commit 9707c8170c0c1baeb1e06e5a53f604498193885f +commit cd4a6bd50b658d707867caa1f5aa40b35c2b6c19 +Author: Damien Miller +Date: Wed Apr 9 09:49:55 2025 +1000 + + initialise websafe_allowlist in agent fuzzer + +commit 55b7cb48af96c1102ef8ab5a73bb329cbed30945 Author: djm@openbsd.org -Date: Tue Jan 9 22:19:36 2024 +0000 +Date: Tue Apr 8 23:10:46 2025 +0000 - upstream: extend ChannelTimeout regression test to exercise multiplexed + upstream: typo - connections and the new "global" timeout type. ok dtucker@ - - OpenBSD-Regress-ID: f10d19f697024e9941acad7c2057f73d6eacb8a2 + OpenBSD-Regress-ID: 08477b936d1d0c1e8a98aa1c0e1bdde8871894c9 -commit b31b12d28de96e1d43581d32f34da8db27e11c03 +commit 985d8cbcd3438cc36b4e709476f1783e358ddfb1 Author: djm@openbsd.org -Date: Tue Jan 9 22:19:00 2024 +0000 +Date: Tue Apr 8 23:10:08 2025 +0000 - upstream: add a "global" ChannelTimeout type to ssh(1) and sshd(8) - - that watches all open channels and will close all open channels if there is - no traffic on any of them for the specified interval. This is in addition to - the existing per-channel timeouts added a few releases ago. + upstream: typo - This supports use-cases like having a session + x11 forwarding channel - open where one may be idle for an extended period but the other is - actively used. The global timeout would allow closing both channels when - both have been idle for too long. + OpenBSD-Commit-ID: 6e683e13e72bf1e43bbd3bbc6a8332d5a98bdc99 + +commit 000c3d14e94d8f7597087c457260ea9417045b65 +Author: dtucker@openbsd.org +Date: Mon Apr 7 08:12:22 2025 +0000 + + upstream: Include time.h for time(). - ok dtucker@ + Fixes warning on some platforms when building without openssl. - OpenBSD-Commit-ID: 0054157d24d2eaa5dc1a9a9859afefc13d1d7eb3 + OpenBSD-Commit-ID: 04ca29b8eaae1860c7adde3e770baa1866e30a54 -commit 602f4beeeda5bb0eca181f8753d923a2997d0a51 -Author: djm@openbsd.org -Date: Tue Jan 9 21:39:14 2024 +0000 +commit 49b8b9bf829e08af22366530614a5e59ac341ca9 +Author: tb@openbsd.org +Date: Wed Apr 2 04:28:03 2025 +0000 - upstream: adapt ssh_api.c code for kex-strict + upstream: Wrap #include in #ifdef WITH_DSA - from markus@ ok me + ok djm - OpenBSD-Commit-ID: 4d9f256852af2a5b882b12cae9447f8f00f933ac + OpenBSD-Commit-ID: ed01a7c102243f84e4a317aefb431916d98aab15 -commit 42ba34aba8708cf96583ff52975d95a8b47d990d +commit f80fb819e5521e13f167edbcc3eed66e22ad0c2a Author: Damien Miller -Date: Mon Jan 8 16:26:37 2024 +1100 +Date: Thu Apr 3 09:10:19 2025 +1100 - nite that recent OSX tun/tap is unsupported + remove all instances of -pie from LDFLAGS + + Previously only the first instance of this flag was removed. + Unbreaks build on OpenSUSE Tumbleweed. Patch from Antonio Larrosa -commit 690bc125f9a3b20e47745fa8f5b5e1fd5820247f -Author: Sevan Janiyan -Date: Wed Dec 27 04:57:49 2023 +0000 +commit 6c9872faa1c297a84c6d3e3b95a927be99eadbf6 +Author: djm@openbsd.org +Date: Tue Apr 1 23:23:20 2025 +0000 - README.platform: update tuntap url + upstream: remove ability to enable DSA support. Actual code will be + + g/c'd separately. ok deraadt@ + + OpenBSD-Commit-ID: 2a032b75156c4d922e8343fa97ff6bc227f09819 -commit 6b8be2ccd7dd091808f86af52066b0c2ec30483a -Author: Rose <83477269+AtariDreams@users.noreply.github.com> -Date: Tue Dec 19 11:48:20 2023 -0500 +commit 8460aaa4e1f8680f03cc5334556b9440b401f010 +Author: dtucker@openbsd.org +Date: Fri Mar 28 21:45:55 2025 +0000 - Fix compilation error in ssh-pcks11-client.c + upstream: Add TEST_SSH_SSHD_ENV to sshd lines here too. - Compilation fails becaus of an undefined reference to helper_by_ec, - because we forgot the preprocessor conditional that excludes that function - from being called in unsupported configurations. + OpenBSD-Regress-ID: 045f2c88b42d694b404db51c5de5eca20d748ff1 -commit 219c8134157744886ee6ac5b8c1650abcd981f4c -Author: djm@openbsd.org -Date: Mon Jan 8 05:11:18 2024 +0000 +commit 5e60f5937b9c33190b9d7614f72d85d4a9b38d3d +Author: dtucker@openbsd.org +Date: Fri Mar 28 06:04:07 2025 +0000 - upstream: Remove outdated note from PROTOCOL.mux + upstream: Pass "ControlMaster no" to ssh when invoked by scp & sftp. - Port forward close by control master is already implemented - by `mux_master_process_close_fwd` in `mux.c` + If you have ControlMaster auto (or yes) in your config, and the + first connection you make is via scp or sftp, then you may get a + few unexpected options applied to it (eg ForwardX11 no), since sftp + and sftp explicitly disable those for reasons. These effects will + persist beyond the initial scp or sftp command. - GHPR442 from bigb4ng + This explicitly disables persistent session *creation* by scp and sftp. + It will not prevent them from using an existing session if one has + already been created. - OpenBSD-Commit-ID: ad0734fe5916d2dc7dd02b588906cea4df0482fb + From Github PR#557, ok djm@ kn@ + + OpenBSD-Commit-ID: 9dad7c737466837e0150c4318920f46d844770c4 -commit 4c3cf362631ccc4ffd422e572f075d5d594feace -Author: djm@openbsd.org -Date: Mon Jan 8 05:05:15 2024 +0000 +commit bbd36869dfb4b770cc9e6a345c04a585a0955aec +Author: dtucker@openbsd.org +Date: Fri Mar 28 05:41:15 2025 +0000 - upstream: fix missing field in users-groups-by-id@openssh.com reply + upstream: Set sshd environment variables during sshd test run too. - documentation + OpenBSD-Regress-ID: 50cb325d92c390a2909662c901f6ac5d80b6f74d + +commit 98f05b1484daddef2f56b79e24540523b5016143 +Author: dtucker@openbsd.org +Date: Fri Mar 28 05:36:24 2025 +0000 + + upstream: Add TEST_SSH_SSHD_ENV variable which is added to sshd's - GHPR441 from TJ Saunders + environment. Will be used in Portable to tweak behaviour of tcmalloc's + debugging. - OpenBSD-Commit-ID: ff5733ff6ef4cd24e0758ebeed557aa91184c674 + OpenBSD-Regress-ID: 67e38c3c4517ddb72c8a3549a3325a166d7bb6d6 -commit f64cede2a3c298b50a2659a8b53eb3ab2c0b8d23 -Author: djm@openbsd.org -Date: Mon Jan 8 04:10:03 2024 +0000 +commit 8cd9ed4df0eccc825eca0c45354a37332e125e38 +Author: dtucker@openbsd.org +Date: Fri Mar 28 05:33:30 2025 +0000 - upstream: make kex-strict section more explicit about its intent: + upstream: chown log directory in addition to log files. - banning all messages not strictly required in KEX - - OpenBSD-Commit-ID: fc33a2d7f3b7013a7fb7500bdbaa8254ebc88116 + OpenBSD-Regress-ID: b520d54a0bbf2c6554413c798218bda26b385ad9 -commit 698fe6fd61cbcb8e3e0e874a561d4335a49fbde5 -Author: Damien Miller -Date: Mon Jan 8 14:46:19 2024 +1100 +commit e32de6bf4f3229d4838beb127de45eed1377ccc5 +Author: Darren Tucker +Date: Fri Mar 28 16:47:58 2025 +1100 - update fuzzer example makefile to clang16 + Be explicit about environment variables for tests. + + This will make it easier to reproduce a test failure by cut-and-paste of + the corresponding line from the github log. -commit fc332cb2d602c60983a8ec9f89412754ace06425 -Author: Damien Miller -Date: Mon Jan 8 14:45:49 2024 +1100 +commit 77a3e6ba47381547b3fe4b29223256f276fbd07e +Author: Darren Tucker +Date: Fri Mar 28 16:46:40 2025 +1100 - unbreak fuzzers - missing pkcs11_make_cert() + Add tcmalloc flags to TEST_SSH_SSHD_ENV. - provide stub for use in fuzzer harness + This will get passed to sshd via test-exec.sh. -commit 9ea0a4524ae3276546248a926b6641b2fbc8421b -Author: Damien Miller -Date: Mon Jan 8 14:45:14 2024 +1100 +commit a73890e340fbd6121251854b658a72d738b86c84 +Author: Darren Tucker +Date: Thu Mar 27 23:04:44 2025 +1100 - unbreak fuzzers for clang16 + Add PuTTY 0.81, 0.82 and 0.83 to tests. + +commit 90a28de0d49570324d1695c0b4686354ef3bcae0 +Author: Darren Tucker +Date: Thu Mar 27 22:30:40 2025 +1100 + + Include TCMALLOC_STACKTRACE_METHOD in output. - getopt() needs a throw() attribute to compile, so supply one when compiling - things with C++ + If TCMALLOC_STACKTRACE_METHOD happens to be set, include it in the debug + output to make reproducing test cases easier. -commit a72833d00788ef91100c643536ac08ada46440e1 -Author: djm@openbsd.org -Date: Mon Jan 8 00:34:33 2024 +0000 +commit fd5a6bb6dd7657c4bd8cd0ee11d5c8ddf0d927b2 +Author: Darren Tucker +Date: Thu Mar 27 20:15:11 2025 +1100 - upstream: remove ext-info-* in the kex.c code, not in callers; + Test with-linux-memlock-onfault in kitchensink. + +commit 22330711e2459c23d9736ee16e0e2ee0fcc30b9a +Author: Collin Funk +Date: Wed Mar 26 18:24:59 2025 -0700 + + Include fcntl.h so AT_FDCWD does not get redefined. + +commit 6c49e5f7dcaf886b4a702a6c003cae9dca04d3ea +Author: Daniil Tatianin +Date: Thu Feb 27 11:37:13 2025 +0300 + + Add support for locking memory on Linux - with/ok markus@ + Linux wakes up kcompactd threads in order to make more contiguous memory + available on the system, it does this by migrating live movable pages + (actively modifying live processes' page tables and constantly flooding + them with page invalidation IPIs, which can be up to millions per + second), which causes the process to become unresponsive for up to + seconds or even minutes in some severe cases. In case of sshd, we want + to always be able to connect to the system, even if it's under heavy + kcompactd load. - OpenBSD-Commit-ID: c06fe2d3a0605c517ff7d65e38ec7b2d1b0b2799 + Introduce an option to protect sshd and its children sessions from being + compacted by kcompactd (this works in cojunction with + compact_unevictable_allowed = 0). Note that we depend on MCL_ONFAULT + being available, which was introduced in linux 4.4. MCL_ONFAULT allows + the system to lock pages lazily, thus drastically reducing memory usage + of a locked process (without MCL_ONFAULT, every existing mapping in the + process is instantly write-faulted). -commit 86f9e96d9bcfd1f5cd4bf8fb57a9b4c242df67df -Author: djm@openbsd.org -Date: Mon Jan 8 00:30:39 2024 +0000 +commit fdc4853c5b1567934d43ab13282f03033cc21325 +Author: Daniil Tatianin +Date: Thu Feb 27 11:46:25 2025 +0300 - upstream: fix typo; spotted by Albert Chin + platform: introduce a way to hook new session start - OpenBSD-Commit-ID: 77140b520a43375b886e535eb8bd842a268f9368 + Previously this was possible via post_fork_child, but ever since sshd + was split into multiple binaries, this is now no longer possible becase + of execv. -commit f0cbd26ec91bd49719fb3eea7ca44d2380318b9a +commit 1b311b6b17be81577514c38e8be4f5740d7df496 Author: dtucker@openbsd.org -Date: Thu Jan 4 09:51:49 2024 +0000 +Date: Wed Mar 19 06:11:15 2025 +0000 - upstream: Import regenerated moduli. + upstream: Prevent theoretical NULL deref in throughlocal_sftp. - OpenBSD-Commit-ID: 5a636f6ca7f25bfe775df4952f7aac90a7fcbbee + Coverity CID 405019, although at the moment it's not reachable. ok djm@ + + OpenBSD-Commit-ID: 630d46c1021b69fbb470e349976c70e9a48b7644 -commit 64ddf776531ca4933832beecc8b7ebe1b937e081 -Author: jsg@openbsd.org -Date: Wed Dec 20 00:06:25 2023 +0000 +commit 96493ebd6ff48bbb802576e208794a26928569b0 +Author: Darren Tucker +Date: Wed Mar 19 17:35:10 2025 +1100 - upstream: spelling; ok markus@ - - OpenBSD-Commit-ID: 9d01f2e9d59a999d5d42fc3b3efcf8dfb892e31b + Fix workflow syntax again. -commit 503fbe9ea238a4637e8778208bde8c09bcf78475 -Author: jmc@openbsd.org -Date: Tue Dec 19 06:57:34 2023 +0000 +commit 575c43fd4c44d376b1771c0fdaf4941021ba88c9 +Author: Darren Tucker +Date: Tue Mar 18 20:54:48 2025 +1100 - upstream: sort -C, and add to usage(); ok djm - - OpenBSD-Commit-ID: 80141b2a5d60c8593e3c65ca3c53c431262c812f + Differentiate logfiles better. -commit 5413b1c7ff5a19c6a7d44bd98c5a83eb47819ba6 -Author: djm@openbsd.org -Date: Tue Dec 19 06:41:14 2023 +0000 +commit 8a1294638f3a47d46263ea574fa85c8e115ea893 +Author: Darren Tucker +Date: Tue Mar 18 20:27:46 2025 +1100 - upstream: correct section numbers; from Ed Maste - - OpenBSD-Commit-ID: e289576ee5651528404cb2fb68945556052cf83f + Fix another typo in workflow. -commit 430ef864645cff83a4022f5b050174c840e275da +commit bd9e6bbcc864b3e10c4e11f5aec1b3a5e3a89b55 +Author: Darren Tucker +Date: Tue Mar 18 18:16:12 2025 +1100 + + Fix syntax error in workflow. + +commit ce88a1bb4a2e6425752094f7a2eb4adfb0ca7971 +Author: Darren Tucker +Date: Tue Mar 18 18:13:14 2025 +1100 + + Identify each logfile while printing them. + +commit b58e429960c4791fc4e30bb7c70d1f77d538b546 Author: djm@openbsd.org -Date: Mon Dec 18 15:58:56 2023 +0000 +Date: Tue Mar 18 04:53:14 2025 +0000 - upstream: match flag type (s/int/u_int) + upstream: fix NULL dereference for Match conditions missing - OpenBSD-Commit-ID: 9422289747c35ccb7b31d0e1888ccd5e74ad566a + arguments, e.g. "Match user". Spotted by Coverity (CID 477813) + + OpenBSD-Commit-ID: 13584281cfa23b8ebc41f9d128a6b9464ae960d4 -commit 1036d77b34a5fa15e56f516b81b9928006848cbd -Author: Damien Miller -Date: Fri Dec 22 17:56:26 2023 +1100 +commit 0ce5281f017c3ad7bdcc2bbd9745119a73e0cbb8 +Author: tb@openbsd.org +Date: Fri Mar 14 09:49:49 2025 +0000 - better detection of broken -fzero-call-used-regs + upstream: Fix EVP_CIPHER_CTX_ctrl() return checks - gcc 13.2.0 on ppc64le refuses to compile some function, including - cipher.c:compression_alg_list() with an error: + While this API tries to translate negative return values (i.e. -1) to 0 + in BoringSSL and LibreSSL, it is still possible for it to return negative + values in prinicple. We even incorrectly document that -1 can be returned + while Boring and OpenSSL plead the Fifth. - > sorry, unimplemented: argument ‘used’ is not supportedcw - > for ‘-fzero-call-used-regs’ on this target + In OpenSSL 3 there are now code paths that explicitly return -1 and they + started shifting their return checks to <= 0 - of course they do this in + inconsistent and sometimes incorrect manner. While these paths aren't + reachable from ssh right now, who can really tell what happens in the two + hundred lines of inscrutable bloated mess this has become. - This extends the autoconf will-it-work test with a similarly- - structured function that seems to catch this. + So error check with <= 0 to ensure that we don't accidentally translate an + error to success. - Spotted/tested by Colin Watson; bz3645 + ok markus schwarze + + OpenBSD-Commit-ID: a855c833cf4ecfce43bedc761f26ad924f70483c -commit 8241b9c0529228b4b86d88b1a6076fb9f97e4a99 -Author: Damien Miller -Date: Tue Dec 19 01:59:50 2023 +1100 +commit 2e81100763d5885e500f065b04c16ed87ce74318 +Author: Darren Tucker +Date: Mon Mar 17 21:35:55 2025 +1100 - crank versions + Fix debug log path. -commit 2f2c65cb5f1518a9c556d3e8efa27ea0ca305c6b -Author: Damien Miller -Date: Tue Dec 19 01:59:06 2023 +1100 +commit 442a44970179d70ebb62bba792699eaec978a1db +Author: Darren Tucker +Date: Fri Mar 14 16:24:06 2025 +1100 - depend + Also lazily unmount workspace in case of straggers. -commit e48cdee8e19059203b1aeeabec2350b8375fa61f -Author: djm@openbsd.org -Date: Mon Dec 18 14:50:08 2023 +0000 +commit 20427f6735fe5ddab31911ce5315adc71acf47d8 +Author: Darren Tucker +Date: Fri Mar 14 16:17:39 2025 +1100 - upstream: regress test for agent PKCS#11-backed certificates - - OpenBSD-Regress-ID: 38f681777cb944a8cc3bf9d0ad62959a16764df9 + Make sure upstream tests run on correct hardware. -commit 2f512f862df1d5f456f82a0334c9e8cc7208a2a1 -Author: djm@openbsd.org -Date: Mon Dec 18 14:49:39 2023 +0000 +commit 91a2f70a56827ae31649baf17227b0914ac5aa36 +Author: Darren Tucker +Date: Fri Mar 14 13:47:27 2025 +1100 - upstream: regress test for constrained PKCS#11 keys - - OpenBSD-Regress-ID: b2f26ae95d609d12257b43aef7cd7714c82618ff + Add OpenBSD upstream test on obsdsnap-arm64. -commit cdddd66412ca5920ed4d3ebbfa6ace12dbd9b82f -Author: djm@openbsd.org -Date: Mon Dec 18 14:48:44 2023 +0000 +commit c20f7413525602b0ea786d8974d03a81f7ca2a92 +Author: Damien Miller +Date: Thu Mar 13 10:45:53 2025 +1100 - upstream: openssh-9.6 - - OpenBSD-Commit-ID: 21759837cf0e0092d9a2079f8fb562071c11016b + rebuild .depend -commit 6d51feab157cedf1e7ef5b3f8781ca8ff9c4ab1b +commit d47ef958b89c6fa809302d654009d3dfabe11b75 Author: djm@openbsd.org -Date: Mon Dec 18 14:48:08 2023 +0000 +Date: Wed Mar 12 22:43:44 2025 +0000 - upstream: ssh-agent: record failed session-bind attempts - - Record failed attempts to session-bind a connection and refuse signing - operations on that connection henceforth. + upstream: remove assumption that the sshd_config and any configs - Prevents a future situation where we add a new hostkey type that is not - recognised by an older ssh-agent, that consequently causes session-bind - to fail (this situation is only likely to arise when people mix ssh(1) - and ssh-agent(1) of different versions on the same host). Previously, - after such a failure the agent socket would be considered unbound and - not subject to restriction. + included from it can fit in a (possibly enlarged) socket buffer, by having + the sshd listener mainloop actively manage sending the configuration to the + sshd-session subprocess. - Spotted by Jann Horn + work by markus@ w/ a little feedback from me; + ok me and committing on his behalf - OpenBSD-Commit-ID: b0fdd023e920aa4831413f640de4c5307b53552e + OpenBSD-Commit-ID: 8f54451483f64951853074adb76bc4f838eaf3ae -commit 7ef3787c84b6b524501211b11a26c742f829af1a -Author: djm@openbsd.org -Date: Mon Dec 18 14:47:44 2023 +0000 +commit 9c90b563943c16418d737433ac478974b8761ee5 +Author: dtucker@openbsd.org +Date: Tue Mar 11 11:46:44 2025 +0000 - upstream: ban user/hostnames with most shell metacharacters + upstream: Prime caches for DNS names needed for tests. - This makes ssh(1) refuse user or host names provided on the - commandline that contain most shell metacharacters. + When running the SSHFP tests, particularly on an ephemeral VM, the first + query or two can fail for some reason, presumably because something isn't + fully initialized or something. To work around this, issue queries for the + names we'll need before we need them. - Some programs that invoke ssh(1) using untrusted data do not filter - metacharacters in arguments they supply. This could create - interactions with user-specified ProxyCommand and other directives - that allow shell injection attacks to occur. - - It's a mistake to invoke ssh(1) with arbitrary untrusted arguments, - but getting this stuff right can be tricky, so this should prevent - most obvious ways of creating risky situations. It however is not - and cannot be perfect: ssh(1) has no practical way of interpreting - what shell quoting rules are in use and how they interact with the - user's specified ProxyCommand. - - To allow configurations that use strange user or hostnames to - continue to work, this strictness is applied only to names coming - from the commandline. Names specified using User or Hostname - directives in ssh_config(5) are not affected. + OpenBSD-Regress-ID: 900841133540e7dead253407db5a874a6ed09eca + +commit 10124eefe875a3e4e1cfb84ebe6a613ed3213b78 +Author: dtucker@openbsd.org +Date: Tue Mar 11 09:06:50 2025 +0000 + + upstream: Some dd's don't understand "1m", so handle seperately. - feedback/ok millert@ markus@ dtucker@ deraadt@ + OpenBSD-Regress-ID: 1d983b27c96f28f69d3a288c19e8d8c58e1b2ee3 + +commit c21c8fc319376c2f5e0da166e9e89a97a245ae72 +Author: Darren Tucker +Date: Tue Mar 11 19:17:46 2025 +1100 + + Lazily unmount github workspace at end of workflow. - OpenBSD-Commit-ID: 3b487348b5964f3e77b6b4d3da4c3b439e94b2d9 + Sometimes when a test times out the workspace is still busy when we try + to unmount it, which leaves the runner unusable until it's cleaned up + manually. We try to unmount this in the first step, but that usually + doesn't work since it fails during setup before it starts our workflow. + Move it to the end and make it a lazy unmount so it hopefully works + eventually. -commit 0cb50eefdd29f0fec31d0e71cc4b004a5f704e67 -Author: djm@openbsd.org -Date: Mon Dec 18 14:47:20 2023 +0000 +commit 4bcbac742968f5086cfd4c570a51de25ef77931f +Author: dtucker@openbsd.org +Date: Tue Mar 11 07:50:20 2025 +0000 - upstream: stricter handling of channel window limits + upstream: Add regress test for sftp resume. - This makes ssh/sshd more strict in handling non-compliant peers that - send more data than the advertised channel window allows. Previously - the additional data would be silently discarded. This change will - cause ssh/sshd to terminate the connection if the channel window is - exceeded by more than a small grace allowance. + OpenBSD-Regress-ID: 37f629b3014338fa23a85df1e1bb320ea12282e1 + +commit e2c4f070b43a4fd7d59a9350e2fe78df605830b5 +Author: dtucker@openbsd.org +Date: Tue Mar 11 07:46:02 2025 +0000 + + upstream: Use ssh binary instead of the (smaller) script when - ok markus@ + preparing test data files since it's faster. - OpenBSD-Commit-ID: 811e21b41831eba3dd7f67b3d409a438f20d3037 + OpenBSD-Regress-ID: 4215e42682fdb73e131e10645d4a1a23a91d64f5 -commit 4448a2938abc76e6bd33ba09b2ec17a216dfb491 -Author: djm@openbsd.org -Date: Mon Dec 18 14:46:56 2023 +0000 +commit 62f02e95ba5cda4649c482d30f4370e2360eb94d +Author: dtucker@openbsd.org +Date: Tue Mar 11 07:43:45 2025 +0000 - upstream: Make it possible to load certs from PKCS#11 tokens - - Adds a protocol extension to allow grafting certificates supplied by - ssh-add to keys loaded from PKCS#11 tokens in the agent. + upstream: Set up dbclient's known_hosts as it expects. - feedback/ok markus@ + OpenBSD-Regress-ID: 9e0898e8423237ce5023be53787bb4062e0d0418 + +commit 395284bd52887dbaf7e78200c857d7f2d9ce398e +Author: dtucker@openbsd.org +Date: Tue Mar 11 07:43:03 2025 +0000 + + upstream: Use $DBCLIENT to access dbclient for consistency. - OpenBSD-Commit-ID: bb5433cd28ede2bc910996eb3c0b53e20f86037f + OpenBSD-Regress-ID: 81e1b41e1ffc49aba1e6fcaeb6242f3b7875ea3c -commit 881d9c6af9da4257c69c327c4e2f1508b2fa754b -Author: djm@openbsd.org -Date: Mon Dec 18 14:46:12 2023 +0000 +commit 97e10c0005a784622c61cb4e8bb7858b410bbcc6 +Author: dtucker@openbsd.org +Date: Tue Mar 11 07:42:08 2025 +0000 - upstream: apply destination constraints to all p11 keys + upstream: Check if dbclient supports SHA1 before trying SHA1-based - Previously applied only to the first key returned from each token. + KEX. - ok markus@ + Dropbear 2025.87 removed SHA1 support by default, which means + diffie-hellman-group14-sha1 is not available. Unfortunately there isn't a + flag to query supported KEX, so instead check MACs and if it doesn't have + SHA1 methods, assuming SHA1 based KEXes are likewise not available. Spotted + by anton@. - OpenBSD-Commit-ID: 36df3afb8eb94eec6b2541f063d0d164ef8b488d + OpenBSD-Regress-ID: acfa8e26c001cb18b9fb81a27271c3b51288d304 -commit a7ed931caeb68947d30af8a795f4108b6efad761 -Author: djm@openbsd.org -Date: Mon Dec 18 14:45:49 2023 +0000 +commit 29a5127f808d00aa539fd27d83a65c2c56179b0e +Author: dtucker@openbsd.org +Date: Tue Mar 11 07:48:51 2025 +0000 - upstream: add "ext-info-in-auth@openssh.com" extension + upstream: Set highwater when resuming a "put". Prevents bogus "server - This adds another transport protocol extension to allow a sshd to send - SSH2_MSG_EXT_INFO during user authentication, after the server has - learned the username that is being logged in to. - - This lets sshd to update the acceptable signature algoritms for public - key authentication, and allows these to be varied via sshd_config(5) - "Match" directives, which are evaluated after the server learns the - username being authenticated. + reordered acks" debug message. ok djm@ - Full details in the PROTOCOL file - - OpenBSD-Commit-ID: 1de7da7f2b6c32a46043d75fcd49b0cbb7db7779 + OpenBSD-Commit-ID: aa7f6d0fc2e893c8c278ea3e6e0974c2eca83f5d -commit 1edb00c58f8a6875fad6a497aa2bacf37f9e6cd5 -Author: djm@openbsd.org -Date: Mon Dec 18 14:45:17 2023 +0000 +commit 6575859d7acb110acf408707f98ed9744ca7d692 +Author: dtucker@openbsd.org +Date: Mon Mar 3 06:54:37 2025 +0000 - upstream: implement "strict key exchange" in ssh and sshd + upstream: Test for %-token and env var expansion in SetEnv. - This adds a protocol extension to improve the integrity of the SSH - transport protocol, particular in and around the initial key exchange - (KEX) phase. - - Full details of the extension are in the PROTOCOL file. + OpenBSD-Regress-ID: bd6139a6177ac4afb29a0ce4afc23567b22ef9f9 + +commit fd7ad8d7bf7dbdeb8f11a8b51aa9d31df1a17e52 +Author: dtucker@openbsd.org +Date: Sun Mar 2 07:41:06 2025 +0000 + + upstream: Also test User expansions when supplied via -l option and - with markus@ + user@host. - OpenBSD-Commit-ID: 2a66ac962f0a630d7945fee54004ed9e9c439f14 + OpenBSD-Regress-ID: 56415859260b53ef0dd20f71225ba5fdf6320f50 -commit 59d691b886c79e70b1d1c4ab744e81fd176222fd -Author: Damien Miller -Date: Mon Dec 18 14:49:11 2023 +1100 +commit e6cfd783f1491b502db9322aa970822c63f1667d +Author: dtucker@openbsd.org +Date: Sat Mar 1 06:12:47 2025 +0000 - better detection of broken -fzero-call-used-regs + upstream: Tests for User expansion of %-tokens and environment - Use OSSH_CHECK_CFLAG_LINK() for detection of these flags and extend - test program to exercise varargs, which seems to catch more stuff. + variables. - ok dtucker@ + OpenBSD-Regress-ID: 7ed21dd0e09fb1f3537b8b177f171018aa501628 -commit aa7b21708511a6d4aed3839fc9f6e82e849dd4a1 +commit 197e503b8e4b642ce0f405a5d65da4256fa96431 Author: djm@openbsd.org -Date: Wed Dec 13 03:28:19 2023 +0000 +Date: Fri Dec 6 16:25:58 2024 +0000 - upstream: when invoking KnownHostsCommand to determine the order of - - host key algorithms to request, ensure that the hostname passed to the - command is decorated with the port number for ports other than 22. + upstream: use glob(3) wildcards in AuthorizedKeys/PrincipalsFile - This matches the behaviour of KnownHostsCommand when invoked to look - up the actual host key. + tests to exercise this feature; ok dtucker - bz3643, ok dtucker@ + OpenBSD-Regress-ID: 7f7b19c0b05b1862cc6521ce61b2b301a3f9cc3b + +commit 396202180180a4ac16788d469508a348789dafa1 +Author: djm@openbsd.org +Date: Fri Dec 6 10:37:42 2024 +0000 + + upstream: implement attestation verification for ED25519 keys - OpenBSD-Commit-ID: 5cfabc0b7c6c7ab473666df314f377b1f15420b1 + OpenBSD-Regress-ID: c44fa5cdb434375a8b5545fdb4fc651061afca1f -commit 4086bd6652c0badccc020218a62190a7798fb72c -Author: markus@openbsd.org -Date: Fri Dec 8 09:18:39 2023 +0000 +commit b49875428cda9c16c5bd52552100da2b419cda5f +Author: dtucker@openbsd.org +Date: Mon Mar 3 06:53:09 2025 +0000 - upstream: prevent leak in sshsig_match_principals; ok djm@ + upstream: Add %-token and environment variable expansion to SetEnv. - OpenBSD-Commit-ID: 594f61ad4819ff5c72dfe99ba666a17f0e1030ae + feedback deraadt@ jmc@, nits and ok djm@ + + OpenBSD-Commit-ID: 2f6e5070481cb73e6f35fd1c6608c1eeff88a5c1 -commit 19d3ee2f3adf7d9a606ff015c1e153744702c4c9 +commit b6bba67e6c31d268480773e4fed16d0a32b4218e Author: djm@openbsd.org -Date: Wed Dec 6 21:06:48 2023 +0000 +Date: Sun Mar 2 22:44:00 2025 +0000 - upstream: short circuit debug log processing early if we're not going + upstream: fix PerSourcePenalty incorrectly using "crash" penalty when - to log anything. From Kobe Housen + LoginGraceTime was exceeded. Reported by irwin AT princeton.edu via bz3797 - OpenBSD-Commit-ID: 2bcddd695872a1bef137cfff7823044dcded90ea + OpenBSD-Commit-ID: 1ba3e490a5a9451359618c550d995380af454d25 -commit 947affad4831df015c498c00c6351ea6f13895d5 -Author: Darren Tucker -Date: Mon Nov 27 09:37:28 2023 +1100 +commit 38d69fee1b06948f160d94abd07b6b297630d30a +Author: Damien Miller +Date: Sun Mar 2 22:06:53 2025 +1100 - Add tests for OpenSSL 3.2.0 and 3.2 stable branch. + include __builtin_popcount replacement function + + Some systems/compilers lack __builtin_popcount(), so replace it as + necessary. Reported by Dennis Clarke; ok dtucker@ -commit 747dce36206675ca6b885010a835733df469351b -Author: Darren Tucker -Date: Sat Nov 25 09:03:38 2023 +1100 +commit c94138d02a45dda5015f38f5a60b0bdde29019c1 +Author: djm@openbsd.org +Date: Sun Mar 2 11:03:13 2025 +0000 - Use non-zero arg in compiler test program. + upstream: whitespace - Now that we're running the test program, passing zero to the test function - can cause divide-by-zero exceptions which might show up in logs. + OpenBSD-Commit-ID: 1bd8953a37451ef7e0991f9fceec5e8005fe986a -commit 3d44a5c56585d1c351dbc006240a591b6da502b1 +commit 65d2c59628e68e166046efa69e76c1d395a8df6e Author: dtucker@openbsd.org -Date: Fri Nov 24 00:31:30 2023 +0000 +Date: Sun Mar 2 07:02:49 2025 +0000 - upstream: Plug mem leak of msg when processing a quit message. + upstream: Make a copy of the user when handling ssh -l, so that - Coverity CID#427852, ok djm@ + later during User token expansion we don't end up freeing a member of argv. + Spotted by anton@'s regress tests. - OpenBSD-Commit-ID: bf85362addbe2134c3d8c4b80f16601fbff823b7 + OpenBSD-Commit-ID: 2f671a4f5726b66d123b88b1fdd1a90581339955 -commit 1d7f9b6e297877bd00973e6dc5c0642dbefc3b5f +commit bd30cf784d6e825ef71592fb723c41d4f2fd407b Author: dtucker@openbsd.org -Date: Thu Nov 23 03:37:05 2023 +0000 +Date: Sat Mar 1 06:11:26 2025 +0000 - upstream: Include existing mux path in debug message. + upstream: Allow %-token and environment variable expansion in User, - OpenBSD-Commit-ID: 1c3641be10c2f4fbad2a1b088a441d072e18bf16 + with the exception of %r and %C which are self-referential. Requested in + bz#3477, ok djm@, man page improvements jmc@ + + OpenBSD-Commit-ID: caeb46251ee073662f6f5864c6f7b92d8ac80fa8 -commit f29934066bd0e561a2e516b7e584fb92d2eedee0 +commit 94f59dcfc57f95ae044f75c3ce544329c8956c35 Author: Darren Tucker -Date: Thu Nov 23 19:41:27 2023 +1100 +Date: Sat Mar 1 10:28:59 2025 +1100 - Add an Ubuntu 22.04 test VM. + Rebuild config files if Makefile changes. - This is the same version as Github's runners so most of the testing on - it is over there, but having a local VM makes debugging much easier. + This ensures paths are updated if they are changed by re-running configure. + Patch from rapier at psc.edu. -commit a93284a780cd3972afe5f89086b75d564ba157f3 +commit dfd9880585db1570656022f9fe1519df673f7b8a Author: Darren Tucker -Date: Thu Nov 23 19:36:22 2023 +1100 +Date: Wed Feb 26 18:16:03 2025 +1100 - Add gcc-12 -Werror test on Ubuntu 22.04. + Check for le32toh, le64toh, htole64 individually. - Explictly specify gcc-11 on Ubuntu 22.04 (it's the system compiler). + It appears that at least some versions of endian.h in glibc do not have + the latter two, so check for and replace each one individually. + bz#3794, ok djm@ -commit 670f5a647e98b6fd95ad64f789f87ee3274b481b -Author: Darren Tucker -Date: Thu Nov 23 19:34:57 2023 +1100 +commit cb99e8eb228df366af33f4fe88d7a9dd0dbf0756 +Author: djm@openbsd.org +Date: Tue Feb 25 06:25:30 2025 +0000 - Check return value from write to prevent warning. + upstream: ressurect fix for "match invalid-user" that got clobbered - ... and since we're testing for flags with -Werror, this caused - configure to mis-detect compiler flags. + by 1.423 + + OpenBSD-Commit-ID: d18bf0945976e0f3467d710d4bc8bdbe181c0567 -commit cea007d691cfedfa07a5b8599f97ce0511f53fc9 -Author: Darren Tucker -Date: Wed Nov 22 21:18:55 2023 +1100 +commit 487cf4c18c123b66c1f3f733398cd37e6b2ab6ab +Author: deraadt@openbsd.org +Date: Fri Feb 21 18:22:41 2025 +0000 - Run compiler test program when compiling natively. + upstream: Also prohibit , (comma) in hostnames, proposed by David - ok djm@ + Leadbeater ok djm millert + + OpenBSD-Commit-ID: 2837fa31dc6e81976f510f0a259edaa559b20b07 -commit ee0d305828f13536c0a416bbf9c3e81039d9ea55 -Author: Darren Tucker -Date: Wed Nov 22 21:18:07 2023 +1100 +commit 3bc6de98c830bd5207f6c371ba69c5874f06305b +Author: Damien Miller +Date: Mon Feb 24 17:27:50 2025 +1100 - Factor out compiler test program into a macro. + Try to fix github tcmalloc target failure - ok djm@ + tcmalloc may, depending on the stacktrace generator it uses, create + pipe(2) fds during shared library initialisation. These will later + get clobbered by ssh/sshd calling closefrom() and chaos will ensue. + Tell tcmalloc to use an unwinder that doesn't pull this stuff. -commit de304c76316b029df460673725a9104224b9959b -Author: Darren Tucker -Date: Wed Nov 22 08:55:36 2023 +1100 +commit 922e54bbfe8c8479453693ef52350338f0c19124 +Author: Damien Miller +Date: Fri Feb 21 13:44:35 2025 +1100 - Add fbsd14 VM to test pool. + cleanup last mention of ubuntu-20.04 -commit 99a2df5e1994cdcb44ba2187b5f34d0e9190be91 -Author: Darren Tucker -Date: Tue Nov 21 16:19:29 2023 +1100 +commit bc4b3f6dc1738d389e5c9dcca8c56d7e153fee49 +Author: Damien Miller +Date: Fri Feb 21 13:44:13 2025 +1100 - Expand -fzero-call-used-regs test to cover gcc 11. + prune gcc/clang versions to be tested - It turns out that gcc also has some problems with -fzero-call-used-regs, - at least v11 on mips. Previously the test in OSSH_CHECK_CFLAG_COMPILE - was sufficient to catch it with "=all", but not sufficient for "=used". - Expand the testcase and include it in the other tests for good measure. - See bz#3629. ok djm@. + Test only the oldest and latest versions of each -commit ff220d4010717f7bfbbc02a2400666fb9d24f250 -Author: Darren Tucker -Date: Tue Nov 21 14:04:34 2023 +1100 +commit 94b73755f931d592a612ef5cb998694643eab5ff +Author: Damien Miller +Date: Fri Feb 21 11:30:22 2025 +1100 - Stop using -fzero-call-used-regs=all + Update AWS-LC version number - ... since it seems to be problematic with several different versions of - clang. Only use -fzero-call-used-regs=used which is less - problematic, except with Apple's clang where we don't use it at all. - bz#3629, ok djm@ + Patch from Shubham Mittal bz bz3792 -commit 2a19e02f36b16f0f6cc915f7d1e60ead5e36303b -Author: Darren Tucker -Date: Tue Nov 21 14:02:18 2023 +1100 +commit 6887099fae6d9f3482e1075d034e9343dc413200 +Author: Damien Miller +Date: Fri Feb 21 11:22:34 2025 +1100 - Allow for vendor prefix on clang version numbers. + adjust workflows for ubuntu version transition - Correctly detects the version of OpenBSD's native clang, as well as - Apple's. Spotted tb@, ok djm@. + remove workflows for unsupported compilers, add a few for additional + supported compilers, move some workflows to run on ubuntu-latest -commit c52db0114826d73eff6cdbf205e9c1fa4f7ca6c6 -Author: djm@openbsd.org -Date: Mon Nov 20 02:50:00 2023 +0000 +commit 33bb47e6f74f2ca8093946e6f462d655a9ae46d3 +Author: Damien Miller +Date: Thu Feb 20 17:10:32 2025 +1100 - upstream: set errno=EAFNOSUPPORT when filtering addresses that don't + Add ubuntu-*-arm test runners + +commit a0c95fbb215b2168fa51b15906e2d6990d7fef6b +Author: Damien Miller +Date: Thu Feb 20 17:03:28 2025 +1100 + + remove ubuntu-20.04 Github action runners - match AddressFamily; yields slightly better error message if no address - matches. bz#3526 + ubuntu-20.04 is deprecated now, so migrate all its unique runners + to ubuntu-22.04. - OpenBSD-Commit-ID: 29cea900ddd8b04a4d1968da5c4a893be2ebd9e6 + ok dtucker@ -commit 26f3f3bbc69196d908cad6558c8c7dc5beb8d74a +commit 0cbeedba81b57c56379e1d202b9ccd3b72af7ddc +Author: Damien Miller +Date: Tue Feb 18 19:03:42 2025 +1100 + + openssh-9.9p2 + +commit 0832aac79517611dd4de93ad0a83577994d9c907 Author: djm@openbsd.org -Date: Wed Nov 15 23:03:38 2023 +0000 +Date: Tue Feb 18 08:02:48 2025 +0000 - upstream: when connecting via socket (the default case), filter + upstream: Fix cases where error codes were not correctly set - addresses by AddressFamily if one was specified. Fixes the case where, if - CanonicalizeHostname is enabled, ssh may ignore AddressFamily. bz5326; ok - dtucker + Reported by the Qualys Security Advisory team. ok markus@ - OpenBSD-Commit-ID: 6c7d7751f6cd055126b2b268a7b64dcafa447439 + OpenBSD-Commit-ID: 7bcd4ffe0fa1e27ff98d451fb9c22f5fae6e610d -commit 050c335c8da43741ed0df2570ebfbd5d1dfd0a31 +commit 6ce00f0c2ecbb9f75023dbe627ee6460bcec78c2 Author: djm@openbsd.org -Date: Wed Nov 15 22:51:49 2023 +0000 +Date: Tue Feb 18 08:02:12 2025 +0000 - upstream: when deciding whether to enable keystroke timing - - obfuscation, only consider enabling it when a channel with a tty is open. + upstream: Don't reply to PING in preauth phase or during KEX - Avoids turning on the obfucation when X11 forwarding only is in use, - which slows it right down. Reported by Roger Marsh + Reported by the Qualys Security Advisory team. ok markus@ - OpenBSD-Commit-ID: c292f738db410f729190f92de100c39ec931a4f1 + OpenBSD-Commit-ID: c656ac4abd1504389d1733d85152044b15830217 -commit 676377ce67807a24e08a54cd60ec832946cc6cae -Author: tobhe@openbsd.org -Date: Mon Nov 13 09:18:19 2023 +0000 +commit 9e5bd74a85192c00a842f63d7ab788713b4284c3 +Author: jmc@openbsd.org +Date: Sat Feb 15 06:48:56 2025 +0000 - upstream: Make sure sftp_get_limits() only returns 0 if 'limits' + upstream: - use \& when contructs like "e.g." end a line, to avoid - was initialized. This fixes a potential uninitialized use of 'limits' in - sftp_init() if sftp_get_limits() returned early because of an unexpected - message type. + double spacing - macro is Qq not Oq - ok djm@ - - OpenBSD-Commit-ID: 1c177d7c3becc1d71bc8763eecf61873a1d3884c + OpenBSD-Commit-ID: 17e5d2d7f288cc7fc536e3af252224525f9fb43a -commit 64e0600f23c6dec36c3875392ac95b8a9100c2d6 -Author: Darren Tucker -Date: Mon Nov 13 20:03:31 2023 +1100 +commit f519e71fb7a46314ae16e2a75490649dc0bd01a2 +Author: Damien Miller +Date: Sat Feb 15 13:12:40 2025 +1100 - Test current releases of LibreSSL and OpenSSL. - - Retire some of the older releases. + depend -commit c8ed7cc545879ac15f6ce428be4b29c35598bb2a -Author: dtucker@openbsd.org -Date: Wed Nov 1 02:08:38 2023 +0000 +commit 9131ac64b0ebe66dc1de9d44bf8d1bd64a24c350 +Author: djm@openbsd.org +Date: Sat Feb 15 01:52:07 2025 +0000 - upstream: Specify ssh binary to use + upstream: add "Match version" support to ssh_config. Allows - ... instead of relying on installed one. Fixes test failures in -portable - when running tests prior to installation. + matching on the local version of OpenSSH, e.g. "Match version OpenSSH_10.*" - OpenBSD-Regress-ID: b6d6ba71c23209c616efc805a60d9a445d53a685 - -commit e9fc2c48121cada1b4dcc5dadea5d447fe0093c3 -Author: Darren Tucker -Date: Wed Nov 1 13:11:31 2023 +1100 - - Put long-running test targets on hipri runners. + ok markus@ - Some of the selfhosted test targets take a long time to run for various - reasons, so label them for "libvirt-hipri" runners so that they can - start immediately. This should reduce the time to complete all tests. + OpenBSD-Commit-ID: c0cb504d0b9e43ccf12e68a544a7cd625e89758d -commit 7ddf27668f0e21233f08c0ab2fe9ee3fdd6ab1e2 +commit 192a20df00c8a56fe7d92ffa23d959c865d7fb9e Author: djm@openbsd.org -Date: Wed Nov 1 00:29:46 2023 +0000 +Date: Sat Feb 15 01:50:47 2025 +0000 - upstream: add some tests of forced commands overriding Subsystem + upstream: Add support for "Match sessiontype" to ssh_config. Allows - directives + matching on the type of session requested, either "shell" for interactive + sessions, "exec" for command execution sessions, "subsystem" for subsystem + requests, such as sftp, or "none" for transport/forwarding-only sessions. - OpenBSD-Regress-ID: eb48610282f6371672bdf2a8b5d2aa33cfbd322b + ok markus@ + + OpenBSD-Commit-ID: eff5c001aecb2283d36639cfb28c0935a8bfd468 -commit fb06f9b5a065dfbbef5916fc4accc03c0bf026dd -Author: dtucker@openbsd.org -Date: Tue Oct 31 04:15:40 2023 +0000 +commit caa3c0c77082888236b0b0c4feb3e6879731b3ba +Author: djm@openbsd.org +Date: Sat Feb 15 01:48:30 2025 +0000 - upstream: Don't try to use sudo inside sshd log wrapper. + upstream: "Match command ..." support for ssh_config to allow - We still need to check if we're using sudo since we don't want to chown - unecessarily, as on some platforms this causes an error which pollutes - stderr. We also don't want to unnecessarily invoke sudo, since it's - running in the context of the proxycommand, on *other* platforms it - may not be able to authenticate, and if we're using SUDO then it should - already be privileged. + matching on the remote command specified on the commandline. - OpenBSD-Regress-ID: 70d58df7503db699de579a9479300e5f3735f4ee + Also relaxes matching rules for `Match tagged` to allow + `Match tagged ""` to match an empty tag value. This also works + for command. + + ok markus@ + + OpenBSD-Commit-ID: 00dcfea425bf58d824bf5e3464cfc2409121b60d -commit fc3cc33e88c242c704781c6c48087838f1dcfa2a -Author: dtucker@openbsd.org -Date: Tue Oct 31 02:58:45 2023 +0000 +commit 38f6000e9851a00e2e4b8e1eb4ea6a243ef7e6a3 +Author: Damien Miller +Date: Tue Feb 11 10:32:26 2025 +1100 - upstream: Only try to chmod logfile if we have sudo. If we don't have + depend + +commit aa1409e7a0a5605f0127651a3ba5a348666325bc +Author: djm@openbsd.org +Date: Mon Feb 10 23:19:26 2025 +0000 + + upstream: include arguments the command was invoked with, and - sudo then we won't need to chmod. + operating system name, version and architecture in startup debugging output; + ok dtucker - OpenBSD-Regress-ID: dbad2f5ece839658ef8af3376cb1fb1cabe2e324 + OpenBSD-Commit-ID: 2a509d319aaf31a6bf9998e1842832883fbc3edd -commit 3a506598fddd3f18f9095af3fe917f24cbdd32e0 +commit 857ac20f5fe19f183defba5dbf4b7d9e6400230c Author: djm@openbsd.org -Date: Mon Oct 30 23:00:25 2023 +0000 +Date: Mon Feb 10 23:16:51 2025 +0000 - upstream: move PKCS#11 setup code to test-exec.sh so it can be reused + upstream: include line number in Match debug messages, makes it a - elsewhere + little easier to see what's going on - OpenBSD-Regress-ID: 1d29e6be40f994419795d9e660a8d07f538f0acb + OpenBSD-Commit-ID: 1fcf4aa2ee667711b9497ded0fa52d757c69b1df -commit f82fa227a52661c37404a6d33bbabf14fed05db0 +commit af49d474e481d2d78b2f06b06a06b0b37629358e Author: djm@openbsd.org -Date: Mon Oct 30 17:32:00 2023 +0000 +Date: Mon Feb 10 23:00:29 2025 +0000 - upstream: tidy and refactor PKCS#11 setup code + upstream: fix "Match invalid-user" from incorrectly being activated - Replace the use of a perl script to delete the controlling TTY with a - SSH_ASKPASS script to directly load the PIN. + in initial configuration pass when no other predicates were present on the + match line - Move PKCS#11 setup code to functions in anticipation of it being used - elsewhere in additional tests. + OpenBSD-Commit-ID: 02703b4bd207fafd03788bc4e7774bf80be6c9a8 + +commit 1c67bae3f5834e48ded71c406f2039dea6e536db +Author: schwarze@openbsd.org +Date: Sun Feb 9 18:24:08 2025 +0000 + + upstream: In a section 1 manual, use the plain English words - Reduce stdout spam + "standard output" rather than the overly technical abbreviation "stdout" - we + are not talking about a device file or a FILE * object here. Issue reported + by on the groff mailing list. - OpenBSD-Regress-ID: 07705c31de30bab9601a95daf1ee6bef821dd262 + OpenBSD-Commit-ID: a0816999f970e6159523bed8484f62c42ec93109 -commit 3cf698c6d4ffa9be1da55672a3519e2135a6366a -Author: Darren Tucker -Date: Mon Oct 30 21:35:03 2023 +1100 +commit 85b3d68dd931416ede657f371f1d60cdc3a66f34 +Author: dtucker@openbsd.org +Date: Fri Jan 17 00:09:41 2025 +0000 - Add obsd74 test VM and retire obsd69 and obsd70. + upstream: Fix debug logging of user specific delay. Patch from + + Achim Leitner (fjl5) via github PR#552. + + OpenBSD-Commit-ID: 834a869ed9b15058d3c1ef0cd75402ef989255d8 -commit 3e21d58a09894acb38dc69ed615d101131f473d0 -Author: Darren Tucker -Date: Mon Oct 30 18:34:12 2023 +1100 +commit e4e5b06fdf4532705669c0ae944b364022d16b9d +Author: dtucker@openbsd.org +Date: Thu Jan 16 06:37:10 2025 +0000 - Add OpenSSL 3.3.0 as a known dev version. + upstream: Call log_init in sshd-auth and sshd-session immediately + + after parsing the config file so that any log settings set in the config file + take effect immediately. Move version banners to immediately after that, and + make them distinct per binary. ok djm@ + + OpenBSD-Commit-ID: acf3d090638edf9b6e6f78eed96b537fe671f0f5 -commit 917ba181c2cbdb250a443589ec732aa36fd51ffa -Author: Darren Tucker -Date: Mon Oct 30 13:32:03 2023 +1100 +commit 0643994b20f2cc54bca80842a984b3052ff1a6a9 +Author: dtucker@openbsd.org +Date: Wed Jan 15 22:23:13 2025 +0000 - Restore nopasswd sudo rule on Mac OS X. + upstream: Use strprefix helper when processing sshd -C test args - This seems to be missing from some (but not all) github runners, so - restore it if it seems to be missing. + instead of counting bytes by hand. ok djm@ + + OpenBSD-Commit-ID: 2866d369d96fe04bf76112260ac37e489f98a9a9 -commit c5698abad6d4ec98ca20bcaaabaeacd5e1ec3f4f -Author: Darren Tucker -Date: Mon Oct 30 13:26:52 2023 +1100 +commit 66efd0fbb6b8b95f8a520f2cdf8ede14e62b30b3 +Author: Damien Miller +Date: Thu Feb 6 09:38:09 2025 +1100 - Don't exit early when setting up on Mac OS X. + add support for AWS-LC (AWS libcrypto) - We probably need some of the other bits in there (specifically, setting - the perms on the home directory) so make it less of a special snowflake. + Patch from Shubham Mittal via bz3784; ok dtucker -commit 1d6a878ceba60b9dc14037dddc8f036070c0065f +commit 826483d51a9fee60703298bbf839d9ce37943474 +Author: Tim Rice +Date: Mon Dec 16 15:36:54 2024 -0800 + + fix old typo (s/SYSVINITSTOPT/SYSVINITSTOP/) + +commit 1a8ce460f1d0c3f7304edba0733783b57b430e21 Author: dtucker@openbsd.org -Date: Sun Oct 29 06:22:07 2023 +0000 +Date: Thu Dec 12 09:09:09 2024 +0000 - upstream: Only try to chown logfiles that exist to prevent spurious + upstream: Plug leak on error path, spotted by Coverity. ok djm@ - errors. + OpenBSD-Commit-ID: b1859959374b4709569760cae0866d22a16606d3 + +commit 924f996144fc0ae1a659fadcfc2237d1ae935fc4 +Author: Xavier Hsinyuan +Date: Mon Dec 9 11:21:05 2024 +0800 + + Add $(srcdir) for standalone sk-libfido2 make target. - OpenBSD-Regress-ID: f1b20a476734e885078c481f1324c9ea03af991e + Fix out-of-tree build failure due to incorrect path for `sk-usbhid.c`. -commit e612376427a66f835e284f6b426d16d7c85301bc -Author: anton@openbsd.org -Date: Thu Oct 26 18:52:45 2023 +0000 +commit bbc9c18e84de29c83fa03e69290979fcca54a2b2 +Author: djm@openbsd.org +Date: Sat Dec 7 10:12:19 2024 +0000 - upstream: make use of bsd.regress.mk in extra and interop targets; ok + upstream: replace bespoke logging of MaxSessions enforcement with - dtucker@ + new ratelimited logging infrastructure. - OpenBSD-Regress-ID: 7ea21b5f6fc4506165093b2123d88d20ff13a4f0 + Add ratelimits to logging of connections dropped by PerSourcePenalties + + ok dtucker + + OpenBSD-Commit-ID: f22fe7c39607e4361aadf95e33773ffd68c59489 -commit ea0039173957d0edcd6469b9614dcedb44dcb4f9 -Author: dtucker@openbsd.org -Date: Thu Oct 26 12:44:07 2023 +0000 +commit 5a6ddf946cf105189c2c99a04f86ce95edc55fc5 +Author: djm@openbsd.org +Date: Sat Dec 7 10:05:36 2024 +0000 - upstream: Skip conch interop tests when not enabled instead of fatal. + upstream: add infrastructure for ratelimited logging; feedback/ok - OpenBSD-Regress-ID: b0abf81c24ac6c21f367233663228ba16fa96a46 + dtucker + + OpenBSD-Commit-ID: 18a83e5ac09d59aaf1e834fd6b796db89dd842e7 -commit d220b9ed5494252b26b95f05be118472bc3ab5c0 -Author: dtucker@openbsd.org -Date: Wed Oct 25 05:38:08 2023 +0000 +commit 85f0c1e75e8f6c5d83b8070918ee2f6ab16d403e +Author: djm@openbsd.org +Date: Fri Dec 6 16:24:27 2024 +0000 - upstream: Import regenerated moduli. + upstream: allow glob(3) patterns for sshd_config AuthorizedKeysFile - OpenBSD-Commit-ID: 95f5dd6107e8902b87dc5b005ef2b53f1ff378b8 + and AuthorizedPrincipalsFile directives; bz2755 ok dtucker + + OpenBSD-Commit-ID: 3e3e05a17fca39bba78b993a07b44664519adf7f -commit a611e4db4009447a0151f31a44e235ca32ed4429 -Author: anton@openbsd.org -Date: Wed Oct 25 08:01:59 2023 +0000 +commit 9a9ffee6e10bcd039f1f9385599577441ebe542a +Author: djm@openbsd.org +Date: Fri Dec 6 16:21:48 2024 +0000 - upstream: ssh conch interop tests requires a controlling terminal; + upstream: support VersionAddendum in the client, mirroring the - ok dtucker@ + option of the same name in the server; bz2745 ok dtucker@ - OpenBSD-Regress-ID: cbf2701bc347c2f19d907f113779c666f1ecae4a + OpenBSD-Commit-ID: 6ff7905b3f9806649bde750515786553fb89cdf4 -commit da951b5e08c167acb5d6e2eec6f146502f5d6ed8 -Author: anton@openbsd.org -Date: Mon Oct 23 11:30:49 2023 +0000 +commit 41ab0ccecd68232e196efae5e224b31ca104c423 +Author: djm@openbsd.org +Date: Fri Dec 6 16:02:12 2024 +0000 - upstream: Use private key that is allowed by sshd defaults in conch + upstream: clarify encoding of options/extensions; bz2389 - interop tests. + OpenBSD-Commit-ID: c4e92356d44dfe6d0a4416deecb33d1d1eba016c + +commit 5488810359f0fd91e2f7b919c70a3798e46376cb +Author: djm@openbsd.org +Date: Fri Dec 6 15:17:15 2024 +0000 + + upstream: ignore SIGPIPE here; some downstreams have had this for - ok dtucker@ + years... - OpenBSD-Regress-ID: 3b7f65c8f409c328bcd4b704f60cb3d31746f045 + OpenBSD-Commit-ID: 73674ee4f8ceb8fc9cb8de71d8ddea0c721eb035 -commit 1ca166dbb3c0ce632b98869cd955f69320aa6fe8 -Author: Darren Tucker -Date: Fri Oct 20 20:43:00 2023 +1100 +commit 4389a792d9078212366eba124a3eed36e009d09e +Author: djm@openbsd.org +Date: Fri Dec 6 15:12:56 2024 +0000 - Install Dropbear for interop testing. + upstream: sync -o option lists with ssh.1; requested jmc@ + + OpenBSD-Commit-ID: a7ac295b444da7b2ca7a33a52370594f6897f6bb -commit f993bb58351c5cb71e61aede63805a34a6d4daea -Author: Darren Tucker -Date: Fri Oct 20 20:39:03 2023 +1100 +commit 6b9cd095565ddc5402d5096dce248fa0521dbda3 +Author: Fabio Pedretti +Date: Mon Oct 16 17:12:24 2023 +0200 - Resync PuTTY and Conch path handling with upstream. + Remove ancient RHL 6.x config in RPM spec. - Now that configure finds these for us we can remove these -portable - specific changes. + It looks like build6x options were intended for RHL 6.x + (the Red Hat distro predating Fedora, not RHEL), but were + then applied to RHEL. + + Completely remove support for this ancient configuration. + + Successfully built, installed and run on RHEL 6. This also + remove a build warning about deprecation of PreReq. -commit ff85becd5f5f06a76efa45d30fb204a3c5e5215c +commit 5cacfa798f92b707491375fed748d1d1bcb33ec9 Author: Darren Tucker -Date: Fri Oct 20 20:35:46 2023 +1100 +Date: Fri Dec 6 23:54:45 2024 +1100 - Have configure find PuTTY and Conch binaries. + Add new hardware-backed signing key for myself. - This will let us remove some -portable specific changes from - test-exec.sh. + Retire old non-hardware based signing key. -commit c54a50359b9cecddbf3ffcdc26efcb3cd6071ec1 +commit f129b6ee1d4361799e65307216e3a4d5544356b7 +Author: Jonas 'Sortie' Termansen +Date: Sat Nov 2 22:05:45 2024 +0100 + + Fix configure implicit declaration and format warnings. + +commit 11a5e5179077f73c2d45bcdf3f60153ae3f17815 Author: dtucker@openbsd.org -Date: Fri Oct 20 07:37:07 2023 +0000 +Date: Fri Dec 6 07:05:54 2024 +0000 - upstream: Allow overriding the locations of the Dropbear binaries + upstream: Expand $SSH to absolute path if it's not already. - similar to what we do for the PuTTY ones. + Prevents problem later in increase_datafile_size if ssh is not in + the path. Patch from quaresmajose via GHPR#510. - OpenBSD-Regress-ID: 7de0e00518fb0c8fdc5f243b7f82f523c936049c + OpenBSD-Regress-ID: 2670a66af8b827410ca7139f0a89f4501cece77b -commit fbaa707d455a61d0aef8ae65e02a25bac5351e5c +commit dc2ef8f0944a4ff7ba19e52fd17b4654e6bd9b93 Author: dtucker@openbsd.org -Date: Fri Oct 20 06:56:45 2023 +0000 +Date: Fri Dec 6 06:55:28 2024 +0000 - upstream: Add interop test with Dropbear. + upstream: Change "login again" to "log in again" - Right now this is only dbclient not the Dropbear server since it won't - currently run as a ProxyCommand. + in password change message. From ThinLinc-Zeijlon via github PR#532. - OpenBSD-Regress-ID: 8cb898c414fcdb252ca6328896b0687acdaee496 + OpenBSD-Commit-ID: fea5e9bc04caf613a118c419f16863733b340cf1 -commit c2003d0dbdcdb61ca336c3f90c5c2b4a09c8e73f -Author: Fabio Pedretti -Date: Mon Oct 16 11:59:53 2023 +0200 +commit 8252f346eb21cd6b30816f905b7d94f10962373e +Author: naddy@openbsd.org +Date: Thu Dec 5 22:45:03 2024 +0000 - Update openssl-devel dependency in RPM spec. + upstream: catch up documentation: AES-GCM is preferred to AES-CTR - Since openssh 9.4p1, openssl >= 1.1.1 is required, so - build with --without-openssl elsewhere. - According to https://repology.org/project/openssl/versions - openssl 1.1.1 is available on fedora >= 29 and rhel >= 8. - Successfully build tested, installed and run on rhel 6 + OpenBSD-Commit-ID: 63360924b6834507fe70020edb936f5075043a9e -commit 064e09cd632721c7e6889904e07767443ee23821 -Author: Fabio Pedretti -Date: Mon Oct 16 10:13:06 2023 +0200 +commit 9a2f4c75081769bd45eba2bf3fab0a32b25f1879 +Author: Darren Tucker +Date: Fri Dec 6 17:56:17 2024 +1100 - Remove reference of dropped sshd.pam.old file + Change text from "login to" to "log in to". - The file was removed in openssh 8.8 + From ThinLinc-Zeijlon via GHPR#532. -commit 62db354b696b378a164b6e478cb6b0171dcb0c3d +commit 24dcf368d816b06136a02845ebd0c7846bf18927 +Author: Xavier Hsinyuan +Date: Fri Dec 6 11:56:34 2024 +0800 + + Fix configure message typo in sk-libfido2 standalone. + +commit 1a0cac2f3411a22d69ae6918eff48456b805e73b +Author: Alexander Kanavin +Date: Thu Dec 5 16:26:46 2024 +0100 + + Skip 2038 key expiry test on 64 bit time_t systems. + + This allows testing Y2038 with system time set to after that (i.e. 2040), + so that actual Y2038 issues can be exposed, and not masked by key expiry + errors. + + Signed-off-by: Alexander Kanavin + +commit 6b4611dc1232c5d2c8e43201f580f19aab320c87 +Author: Darren Tucker +Date: Fri Dec 6 01:45:52 2024 +1100 + + Skip 64bit expiry time test on 32bit time_t. + +commit c9b7866a7dc5e6c30f5aa9d22dd0bbafda0d496f Author: dtucker@openbsd.org -Date: Mon Oct 16 08:40:00 2023 +0000 +Date: Thu Dec 5 14:28:39 2024 +0000 - upstream: Move declaration of "len" into the block where it's used. + upstream: Add key expiry test in the 64bit time_t range for additional - This lets us compile Portable with -Werror with when OpenSSL doesn't have - Ed25519 support. + coverage. From Alexander Kanavin via bz#3684. - OpenBSD-Commit-ID: e02e4b4af351946562a7caee905da60eff16ba29 + OpenBSD-Regress-ID: bdf6eb3c2421f2e1e11483d03b34c7931d1bccf7 -commit 6eee8c972d5901d10e80634a006b4e346b2c8c19 +commit 790c913b5fc6ee93ae14793443dc85a0f574b7eb Author: Damien Miller -Date: Fri Oct 13 15:15:05 2023 +1100 +Date: Thu Dec 5 19:24:56 2024 +1100 - run t-extra regress tests + typo + +commit d23a23aaeeabc228792e3fd7eb5f2fa6ae13c482 +Author: Damien Miller +Date: Thu Dec 5 08:47:02 2024 +1100 + + add a Makefile target for ssh-verify-attestation - This exposes the t-extra regress tests (including agent-pkcs11.sh) as - a new extra-tests target in the top level Makefile and runs them by - default. ok dtucker@ + Not built by default, but easier than doing it by hand -commit 637624dbbac13f2bc3c8ec5b15c9d627d07f2935 -Author: Darren Tucker -Date: Thu Oct 12 22:01:23 2023 +1100 +commit d0ac63d0f8b5f778d5fd326701ef4489bc27635e +Author: dtucker@openbsd.org +Date: Thu Dec 5 06:49:26 2024 +0000 - Don't use make -j2. + upstream: De-magic the x11 base port number into a define. ok djm@ - While we have 2 cores available on github runners, not using it means - that the most recent log message is the actual failure, rather than - having to search back through the log for it. + OpenBSD-Commit-ID: 23b85ca9d222cb739b9c33ee5e4d6ac9fdeecbfa -commit 971e0cfcfd52ef1d73cf5244074c306a60006e89 -Author: Darren Tucker -Date: Thu Oct 12 16:23:05 2023 +1100 +commit 9998c93d57bf0f1df2bc93e0bc2d8112c6f8c720 +Author: dtucker@openbsd.org +Date: Thu Dec 5 06:47:00 2024 +0000 - Correct arg order for ED255519 AC_LINK_IFELSE test. + upstream: Prevent integer overflow in x11 port handling. These are + + theoretically possible if the admin misconfigures X11DisplayOffset or the + user misconfigures their own $DISPLAY, but don't happen in normal operation. + From Suhov Roman via bz#3730, ok djm@ + + OpenBSD-Commit-ID: e9e3860f1a19b862ccf07dc8ecbe8f1e1034f4ed -commit c616e64688b2a0c1b4daad69b056099be998d121 +commit 8c9ee046d40e4254c6c1711783ea11027b72c3e9 Author: djm@openbsd.org -Date: Thu Oct 12 03:51:08 2023 +0000 +Date: Wed Dec 4 16:42:49 2024 +0000 - upstream: typos and extra debug trace calls + upstream: add a work-in-progress tool to verify FIDO attestation - OpenBSD-Regress-ID: 98a2a6b9333743274359e3c0f0e65cf919a591d1 + blobs that ssh-keygen can write when enrolling FIDO keys. + + OpenBSD-Regress-ID: 6c97bf3f46e48866677ad69f54b77683eb92437f -commit c49a3fbf10162128c67c59562348de2041188974 -Author: djm@openbsd.org -Date: Thu Oct 12 03:48:53 2023 +0000 +commit 50c640d874d0246dd0a0d949398c3d7f757c716a +Author: dtucker@openbsd.org +Date: Wed Dec 4 10:51:13 2024 +0000 - upstream: ensure logs are owned by correct user; feedback/ok + upstream: Don't assume existence of SK provider in test. Patch from - dtucker@ + balu.gajjala at gmail via bz#3402. - OpenBSD-Regress-ID: c3297af8f07717f1d400a5d34529962f1a76b5a3 + OpenBSD-Regress-ID: d571932016d07d135b54433d07520b9e1901db43 -commit 5ec0ed79ac074c3437b25f6cba8b8cf21c8d4587 +commit 73d782693144262570d3585b62f16b183170c014 Author: djm@openbsd.org -Date: Thu Oct 12 03:36:32 2023 +0000 +Date: Wed Dec 4 14:37:55 2024 +0000 - upstream: 64 %-expansion keys ought to be enough for anybody; ok + upstream: sync the list of options accepted by -o with ssh_config.5 - dtucker (we just hit the previous limit in some cases) + prompted by bz3455 - OpenBSD-Commit-ID: 84070f8001ec22ff5d669f836b62f206e08c5787 + OpenBSD-Commit-ID: 0ecbfa70aea6c769bcc259defe07182edf461f57 -commit f59a94e22e46db2c23eddeb871aa9e8d93ab0016 +commit 6993d9f0959534b0b7d52e17b95e9e79fb0b3d0a Author: djm@openbsd.org -Date: Thu Oct 12 02:48:43 2023 +0000 +Date: Wed Dec 4 14:24:20 2024 +0000 - upstream: don't dereference NULL pointer when hashing jumphost + upstream: don't screw up ssh-keygen -l output when the file - OpenBSD-Commit-ID: 251c0263e1759a921341c7efe7f1d4c73e1c70f4 + contains CR characters; GHPR236 bz3385, fix from Dmitry Belyavskiy + + OpenBSD-Commit-ID: e458cf6b0adcea5b69ef4c7ba38e590841d02ef4 -commit 281c79168edcc303abfd5bca983616eaa24c5f32 -Author: Damien Miller -Date: Thu Oct 12 13:20:01 2023 +1100 +commit c0b03c2534946fc114880092177aa4a3683ced2d +Author: jsg@openbsd.org +Date: Tue Dec 3 22:30:03 2024 +0000 - Solaris: prefer PRIV_XPOLICY to PRIV_LIMIT + upstream: spelling; ok djm@ - If the system support PRIV_XPOLICY and one is set, then don't - modify PRIV_LIMIT. bz2833, patch from Ron Jordan, ok dtucker@ + OpenBSD-Commit-ID: c8ff3f70020451eef214e598117b7ce1a29853ef -commit 98fc34df837f3a3b79d2a111b96fe8a39adcab55 -Author: djm@openbsd.org -Date: Thu Oct 12 02:18:18 2023 +0000 +commit 97eb247f40167f44324e88a537d5b4fe771a63b2 +Author: dtucker@openbsd.org +Date: Tue Dec 3 16:27:53 2024 +0000 - upstream: add %j token that expands to the configured ProxyJump + upstream: Remove fallback to compiled-in gropup for dhgex when the - hostname (or the empty string if this option is not being used). bz3610, ok - dtucker + moduli file exists, but does not contain moduli within the client-requested + range. The fallback behaviour remains for the case where the moduli file does + not exist (typically, running tests prior to installing). From bz#2793, based + in part on patch from Joe Testa, ok djm@ - OpenBSD-Commit-ID: ce9983f7efe6a178db90dc5c1698df025df5e339 + OpenBSD-Commit-ID: b1a8c5dbbedf249b42474679ebaf14db7332b1ab -commit 7f3180be8a85320b5d3221714b40c16e66881249 -Author: djm@openbsd.org -Date: Thu Oct 12 02:15:53 2023 +0000 +commit 30c746265ebde29806dba77c92fb1fd3803cbf5c +Author: tb@openbsd.org +Date: Tue Dec 3 15:53:51 2024 +0000 - upstream: release GSS OIDs only at end of authentication; bz2982, + upstream: Remove redundant field of definition check - ok dtucker@ + This will allow us to get rid of EC_GROUP_method_of() in the near future. - OpenBSD-Commit-ID: 0daa41e0525ae63cae4483519ecaa37ac485d94c + ok djm + + OpenBSD-Commit-ID: b4a3d2e00990cf5c2ec6881c21ddca67327c2df8 -commit a612b93de5d86e955bfb6e24278f621118eea500 -Author: djm@openbsd.org -Date: Thu Oct 12 02:12:53 2023 +0000 +commit eaa1744f34c30740328fd0a0d84b5f2f9e6918c1 +Author: Damien Miller +Date: Thu Dec 5 00:59:19 2024 +1100 - upstream: mask SIGINT/TERM/QUIT/HUP before checking quit_pending + don't ignore changes in regress Makefiles - and use ppoll() to unmask them in the mainloop. Avoids race condition between - signaling ssh to exit and polling. bz3531; ok dtucker + reported by Torben Hansen in bz2880 + +commit 66e986880b2472fefaad781f10113b138b65ff27 +Author: Damien Miller +Date: Thu Dec 5 00:01:33 2024 +1100 + + Support systemd-style socket activation in agent - OpenBSD-Commit-ID: 5c14e1aabcddedb95cdf972283d9c0d5083229e7 + Adds support for systemd LISTEN_PID/LISTEN_FDS socket activation to + ssh-agent. Activated when these environment variables are set and + the agent is started with the -d or -D option and no socket path + is set. + + Based on GHPR502 by Daniel Kahn Gillmor, ok dtucker -commit 531b27a006116fe7aff325510aaa576f24844452 -Author: djm@openbsd.org -Date: Wed Oct 11 23:23:58 2023 +0000 +commit 9b57c099f57152e6c94f633c114f544087f4bdaa +Author: Darren Tucker +Date: Wed Dec 4 21:36:01 2024 +1100 - upstream: sync usage() with ssh.1; spotted by kn@ + Update readme files to better reflect reality. - OpenBSD-Commit-ID: 191a85639477dcb5fa1616d270d93b7c8d5c1dfd + Prompted by bz#3738, ok djm@. -commit 64f7ca881b19be754425dca60d1590d306c9d1d0 -Author: djm@openbsd.org -Date: Wed Oct 11 23:14:33 2023 +0000 +commit ffa885db1b960451d426455045d2f51288e48ee8 +Author: dtucker@openbsd.org +Date: Tue Dec 3 14:12:47 2024 +0000 - upstream: ssh -Q does not make sense with other command-line options, + upstream: Improve description of KbdInteractiveAuthentication. - so give it its own line in the manpage + Based on bz#3658, fixes jmc@ ok markus@ djm@. - OpenBSD-Commit-ID: 00a747f0655c12122bbb77c2796be0013c105361 + OpenBSD-Commit-ID: 9fadb56b9afed554d501acbba911c685acd6ffc2 -commit a752a6c0e1001f93696d7025f0c867f0376e2ecf -Author: djm@openbsd.org -Date: Wed Oct 11 22:42:26 2023 +0000 +commit b460f82a67795bba37c6cc6c78f788e5b435b4cb +Author: Jonas 'Sortie' Termansen +Date: Sat Nov 2 17:53:23 2024 +0100 - upstream: add ChannelTimeout support to the client, mirroring the - - same option in the server. ok markus@ + Inherit DESTDIR from the environment. - OpenBSD-Commit-ID: 55630b26f390ac063980cfe7ad8c54b03284ef02 + autoconf packages conventionally inherit the DESTDIR variable from the + environment. -commit 76e91e7238cdc5662bc818e2a48d466283840d23 +commit 9da7fa7c7464df241ae5d17da94e4ebed9013719 +Author: Jonas 'Sortie' Termansen +Date: Sat Nov 2 22:10:39 2024 +0100 + + Define u_short and u_long if needed. + +commit d3a7ff7cecbc23cc37044bdf02e7118d05bf3c35 Author: djm@openbsd.org -Date: Wed Oct 11 22:41:05 2023 +0000 +Date: Tue Dec 3 08:31:49 2024 +0000 - upstream: add support for reading ED25519 private keys in PEM PKCS8 + upstream: support FIDO tokens that return no attestation data, e.g. - format; ok markus@ tb@ + recent WinHello. From Michael Braun via GHPR542 - OpenBSD-Commit-ID: 01b85c91757e6b057e9b23b8a23f96415c3c7174 + OpenBSD-Commit-ID: a71b0542f2f7819ba0e33a88908e01b6fc49e4ce -commit fc77c8e352c0f44125425c05265e3a00c183d78a +commit 96b64056c812620014b65371a9e3ac86bfcd08d5 +Author: Thorsten Kukuk +Date: Tue Nov 19 10:53:28 2024 +0100 + + Add wtmpdb support as Y2038 safe wtmp replacement + +commit 1d9563a56f2ad5b0c0aeef20e19c1a03ad54f88a Author: djm@openbsd.org -Date: Wed Oct 11 06:40:54 2023 +0000 +Date: Mon Dec 2 14:06:42 2024 +0000 - upstream: mention "none" is a valid argument to IdentityFile; bz3080 + upstream: unbreak - OpenBSD-Commit-ID: 1b4fb590ef731099349a7d468b77f02b240ac926 + OpenBSD-Commit-ID: 05b6c31f4a6e385338f43cc0e08776cea75802a1 -commit c97520d23d1fe53d30725a2af25d2dddd6f2faff +commit d75837b9f6d0d6cc18ed5078789ea0f3dad08f00 Author: djm@openbsd.org -Date: Wed Oct 11 05:42:08 2023 +0000 +Date: Mon Dec 2 13:37:18 2024 +0000 - upstream: in olde rcp/scp protocol mode, when rejecting a path from the - - server as not matching the glob that the client sent, log (at debug level) - the received pathname as well as the list of possible expected paths expanded - from the glob. bz2966 + upstream: prefer AES-GCM to AES-CTR; ok deraadt markus - OpenBSD-Commit-ID: 0bd8db8a595334ca86bca8f36e23fc0395315765 + OpenBSD-Commit-ID: 8366a72e0f300ee31c5dab2c95025387ec15bbc9 -commit 208c2b719879805983398160791d6a1ef9c2c3fc -Author: djm@openbsd.org -Date: Wed Oct 11 04:46:29 2023 +0000 +commit e19cd494b567a73dc390e09b47c1e21545e6116b +Author: Shiva Kaul +Date: Mon Dec 2 02:04:20 2024 -0500 - upstream: s/%.100s/%s/ in SSH- banner construction as there's no + Fix compilation with DEBUG_SK enabled - reason to limit its size: the version string bring included is a compile time - constant going into an allocated banner string. + In `ssh_ecdsa_sk_verify`, the `datalen` variable was renamed to `dlen` -- but not in this debugging block. + +commit 67ace92be0718df7e0f52c0a76684fc2ebae4089 +Author: dtucker@openbsd.org +Date: Fri Nov 29 00:13:36 2024 +0000 + + upstream: Import regenerated moduli. - OpenBSD-Commit-ID: 0ef73304b9bf3e534c60900cd84ab699f859ebcd + OpenBSD-Commit-ID: 311d271bf0fab8a119e84f4f696d8cd40731692f -commit 0354790826b97c41bbd171a965574e159b58d83e -Author: tb@openbsd.org -Date: Tue Oct 10 06:49:54 2023 +0000 +commit ca0697a90e5720ba4d76cb0ae9d5572b5260a16c +Author: Jeremy Stott +Date: Sat Oct 19 12:10:52 2024 +1300 - upstream: Garbage collect cipher_get_keyiv_len() + Add make target for standalone sk-libfido2 - This is a compat20 leftover, unused since 2017. + Add a Makefile target for sk-libfido2, the standalone fido2 security + key shared library, suitable for use with the SecurityKeyProvider + option. - ok djm + Add a new configure option `--with-security-key-standalone` that + optionally sets the shared library target sk-libfido2$(SHLIBEXT), and + adds it to $(TARGETS). - OpenBSD-Commit-ID: 91fa5497c9dc6883064624ac27813a567883fdce + misc.h is required when SK_STANDALONE is defined, because of the use + of `monotime_tv` in `sk_select_by_touch`. + + Sets the shared library extension for sk-libfido2 is by setting + `SHLIBEXT` depending on the platform in configure.ac. + + Add the shared library to the CI builds in the `sk` target config to + make sure it can compile under the same conditions as + `--with-security-key-builtin`. + + Add a libssh-pic.a static library that compiles with `-fPIC` reusing + .c.lo method in sk-dummy.so for use in the shared library sk-libfido2. + + Note, a separate static library libssh-pic.a is needed, since defining + -DSK_STANDALONE excludes some symbols needed in sshkey.lo. -commit 8d29ee4115001a02641386ae394992c65ed279e0 -Author: djm@openbsd.org -Date: Tue Oct 10 03:57:45 2023 +0000 +commit 74d70841efbf41b9fcc8e6f6f4777d2e9d7e2004 +Author: Arnout Engelen +Date: Fri Oct 18 13:42:38 2024 +0200 - upstream: Reserve a range of "local extension" message numbers that + mdoc2man: balance nested square brackets - OpenSSH promises not to use (comment change only) + I noticed the square brackets in `destination [command [argument...]` + in the synopsis for the `ssh.1` manpage were not balanced, + this balances them. - OpenBSD-Commit-ID: e61795b453d4892d2c99ce1039112c4a00250e03 + Signed-off-by: Arnout Engelen -commit 90b0d73d63a706e85f6431f05a62d2ce1b476472 +commit 8eabd2ae2ca1d7756417a1ee5b41f09c5d997634 Author: djm@openbsd.org -Date: Fri Oct 6 03:32:15 2023 +0000 +Date: Wed Nov 27 16:07:08 2024 +0000 - upstream: typo in error message + upstream: fix argument of "Compression" directive in ssh -G config - OpenBSD-Regress-ID: 6a8edf0dc39941298e3780b147b10c0a600b4fee + dump, which used to work but broke in 9.8 + + OpenBSD-Commit-ID: c79936242d29c70d01941b28d2d07fd0b85fe46f -commit e84517f51532ec913d8fb01a8aab7307134774bb +commit 53c03961769d8879a81398074ea3cb36253d4f2e Author: djm@openbsd.org -Date: Fri Oct 6 03:25:14 2023 +0000 +Date: Wed Nov 27 13:27:34 2024 +0000 - upstream: Perform the softhsm2 setup as discrete steps rather than - - as a long shell pipeline. Makes it easier to figure out what has happened - when it breaks. + upstream: new name/link for agent I-D - OpenBSD-Regress-ID: b3f1292115fed65765d0a95414df16e27772d81c + OpenBSD-Commit-ID: e3420f3925a297a1b2ab7dfe7c7d274cfc8e1193 -commit cb54becff4d776238e0e9072943ba0872260535d -Author: claudio@openbsd.org -Date: Sun Sep 24 08:14:13 2023 +0000 +commit 785e3c9110df8f2d30e42ce8b45969c49700f35b +Author: djm@openbsd.org +Date: Wed Nov 27 13:00:23 2024 +0000 - upstream: REGRESS_FAIL_EARLY defaults to yes now. So no need to + upstream: mention that biometrics may be used for FIDO key user - overload the value here anymore. OK tb@ bluhm@ + verification as well as PIN. Prompted by Zack Newman, ok jmc@ - OpenBSD-Regress-ID: f063330f1bebbcd373100afccebc91a965b14496 + OpenBSD-Commit-ID: b774a4438c9be70012661ee278450790d21277b8 -commit f01f5137ceba65baf34ceac5a298c12ac01b1fef -Author: jmc@openbsd.org -Date: Wed Oct 4 05:42:10 2023 +0000 +commit fd2e64c9ec9ea3e89e396be0db41aaf982ae1210 +Author: djm@openbsd.org +Date: Tue Nov 26 22:05:51 2024 +0000 - upstream: spelling fix; + upstream: g/c outdated XXX comments - OpenBSD-Commit-ID: 493f95121567e5ab0d9dd1150f873b5535ca0195 + OpenBSD-Commit-ID: 74d0c0b74994d9a4343c4d7ea4948cb34f609a6c -commit 80a2f64b8c1d27383cc83d182b73920d1e6a91f1 -Author: Damien Miller -Date: Wed Oct 4 15:34:10 2023 +1100 +commit 0ad34a6193357d286042322ea7347262a6fb0778 +Author: djm@openbsd.org +Date: Tue Nov 26 22:02:28 2024 +0000 - crank version numbers + upstream: regression test for UpdateHostkeys with multiple keys backed + + by ssh-agent. Patch from Maxime Rey. + + OpenBSD-Regress-ID: 1777ab6e639e57c0e20cbcb6df60455b49fd8bb3 -commit f65f187b105d9b5c12fd750a211397d08c17c6d4 +commit 84023656d91b78f1ef86c8321ec563f2e90f7227 Author: djm@openbsd.org -Date: Wed Oct 4 04:04:09 2023 +0000 +Date: Tue Nov 26 22:01:37 2024 +0000 - upstream: openssh-9.5 + upstream: Explicitly specify the signature algorithm when signing - OpenBSD-Commit-ID: 5e0af680480bd3b6f5560cf840ad032d48fd6b16 + hostkeys-prove requests. + + Fixes a corner-case triggered by UpdateHostKeys with one or more unknown + host keys stored in ssh-agent where sshd refuses to accept the signature + coming back from the agent. + + Report/fix from Maxime Rey + + OpenBSD-Commit-ID: 460c7d527a24f92b7e5f68ca1a2fa242ebf0d086 -commit ffe27e54a4bb18d5d3bbd3f4cc93a41b8d94dfd2 +commit d1c1cfc5e4e9b43593d4642810ea8135e4c7db49 Author: djm@openbsd.org -Date: Wed Oct 4 04:03:50 2023 +0000 +Date: Tue Nov 26 21:23:35 2024 +0000 - upstream: add some cautionary text about % token expansion and + upstream: when using RSA keys to sign messages, select the + + signature algorithm based on the requested hash algorithm ("-Ohashalg=xxx"). - shell metacharacters; based on report from vinci AT protonmail.ch + This allows using something other than rsa-sha2-512, which may not + be supported on all signing backends, e.g. some smartcards only + support SHA256. - OpenBSD-Commit-ID: aa1450a54fcee2f153ef70368d90edb1e7019113 + Patch from Morten Linderud; ok markus@ + + OpenBSD-Commit-ID: 246353fac24e92629263996558c6788348363ad7 -commit 60ec3d54fd1ebfe2dda75893fa1e870b8dffbb0d +commit ac7544654441280071b90a4129a47467d40f2389 Author: djm@openbsd.org -Date: Tue Oct 3 23:56:10 2023 +0000 +Date: Sun Nov 24 23:47:50 2024 +0000 - upstream: fix link to agent draft; spotted by Jann Horn + upstream: turn off CDIAGFLAGS and turn back on INSTALL_STRIP + + accidentally changed in last commit - OpenBSD-Commit-ID: ff5bda21a83ec013db683e282256a85201d2dc4b + OpenBSD-Commit-ID: 6d07e4606997e36b860621a14dd41975f2902f8f -commit 12e2d4b13f6f63ce2de13cbfcc9e4d0d4b4ab231 -Author: Damien Miller -Date: Wed Oct 4 10:54:04 2023 +1100 +commit 953fa5b59afb04c3c74ed82d7bace65c13cd8baa +Author: Darren Tucker +Date: Sat Nov 9 11:41:44 2024 +1100 - use portable provider allowlist path in manpage + Disable security key for bigendian interop. - spotted by Jann Horn + It doesn't currently work. It's not clear why, but I suspect + sk-dummy.so ends up being built for the wrong architecture. -commit 6c2c6ffde75df95fd838039850d3dd3d84956d87 -Author: deraadt@openbsd.org -Date: Tue Sep 19 20:37:07 2023 +0000 +commit a80eb71c428c474098087c672398f200be8fabdf +Author: Darren Tucker +Date: Sat Nov 9 05:14:16 2024 +1100 - upstream: typo; from Jim Spath + Reshuffle OpenWRT test configs. - OpenBSD-Commit-ID: 2f5fba917b5d4fcf93d9e0b0756c7f63189e228e + Move the the flags used by the OpenWRT distro to mipsel target and + enable OpenSSL on all targets to improve coverage. + + Explicitly disable security key and openssl on mips target so that host + end of the bigendian interop tests don't attempt them and fail (since + they're not enabled on the target side). -commit b6b49130a0089b297245ee39e769231d7c763014 -Author: djm@openbsd.org -Date: Sun Sep 10 23:12:32 2023 +0000 +commit d2709c461359e4129311cdff81ee05242d6c53cd +Author: Darren Tucker +Date: Sat Nov 9 03:26:08 2024 +1100 - upstream: rename remote_glob() -> sftp_glob() to match other API - - OpenBSD-Commit-ID: d9dfb3708d824ec02970a84d96cf5937e0887229 + Add keytype to bigendian interop test. -commit 21b79af6c8d2357c822c84cef3fbdb8001ed263b -Author: djm@openbsd.org -Date: Sun Sep 10 03:51:55 2023 +0000 +commit 50ac0f0e0627d29fd9becf5e15e8ceca5ad18078 +Author: Darren Tucker +Date: Sat Nov 9 03:24:29 2024 +1100 - upstream: typo in comment - - OpenBSD-Commit-ID: 69285e0ce962a7c6b0ab5f17a293c60a0a360a18 + Ignore chown failure, eg due to dangling symlinks. -commit 41232d25532b4d2ef6c5db62efc0cf50a79d26ca +commit 9e528e65a03245cf28e814f09b88c701bec935d1 Author: Darren Tucker -Date: Sun Sep 10 15:45:38 2023 +1000 +Date: Sat Nov 2 18:05:41 2024 +1100 - Use zero-call-used-regs=used with Apple compilers. + Test bigendian interop. - Apple's versions of clang have version numbers that do not match the - corresponding upstream clang versions. Unfortunately, they do still - have the clang-15 zero-call-used-regs=all bug, so for now use the value - that doesn't result in segfaults. We could allowlist future versions - that are known to work. bz#3584 (and probably also our github CI - failures). + Where our test target is a bigendian system, do an additional build on + the runner host (which is little endian) and test interop between the two. + Should hopefully catch obvious endianness bugs. -commit 90ccc5918ea505bf156c31148b6b59a1bf5d6dc6 -Author: djm@openbsd.org -Date: Sun Sep 10 03:25:53 2023 +0000 +commit dd416f5bfa96ac1ff44b27a93f7b55ee627c6baf +Author: Darren Tucker +Date: Fri Nov 1 19:44:29 2024 +1100 - upstream: randomise keystroke obfuscation intervals and average - - interval rate. ok dtucker@ + Allow overridding TEST_SSH_SSHD. - OpenBSD-Commit-ID: 05f61d051ab418fcfc4857ff306e420037502382 + This will allow tests to specify an alternative sshd, eg on a remote + machine with different endianness. -commit bd1b9e52f5fa94d87223c90905c5fdc1a7c32aa6 +commit 82662d562cf54829df8a941cdfb2fd307e1d9a90 Author: djm@openbsd.org -Date: Fri Sep 8 06:34:24 2023 +0000 +Date: Wed Nov 6 22:51:26 2024 +0000 - upstream: fix sizeof(*ptr) instead sizeof(ptr) in realloc (pointer here + upstream: ssh-agent implemented an all-or-nothing allow-list of - is char**, so harmless); spotted in CID 416964 + FIDO application IDs for security key-backed keys, to prevent web key handles + from being used remotely as this would likely lead to unpleasant surprises. + By default, only application IDs that start with "ssh:*" are allowed. - OpenBSD-Commit-ID: c61caa4a5a667ee20bb1042098861e6c72c69002 + This adds a -Owebsafe-allow=... argument that can override the default + list with a more or less restrictive one. The default remains unchanged. + + ok markus@ + + OpenBSD-Commit-ID: 957c1ed92a8d7c87453b9341f70cb3f4e6b23e8d -commit c4f966482983e18601eec70a1563115de836616f -Author: djm@openbsd.org -Date: Fri Sep 8 06:10:57 2023 +0000 +commit 593a0b65c55c1e06a8c22b084aefc395aedb0127 +Author: jca@openbsd.org +Date: Mon Nov 4 21:59:15 2024 +0000 - upstream: regress test recursive remote-remote directories copies where + upstream: Ignore extra groups that don't fit in the buffer passed - the directory contains a symlink to another directory. + to getgrouplist(3) - also remove errant `set -x` that snuck in at some point + Our kernel supports 16 groups (NGROUPS_MAX), but nothing prevents + an admin from adding a user to more groups. With that tweak we'll keep + on ignoring them instead of potentially reading past the buffer passed to + getgrouplist(3). That behavior is explicitely described in initgroups(3). - OpenBSD-Regress-ID: 1c94a48bdbd633ef2285954ee257725cd7bc456f + ok millert@ gilles@ + + OpenBSD-Commit-ID: a959fc45ea3431b36f52eda04faefc58bcde00db -commit 5e1dfe5014ebc194641678303e22ab3bba15f4e5 -Author: djm@openbsd.org -Date: Fri Sep 8 06:10:02 2023 +0000 +commit e7adebeff3a9d038d0eaeeb0fcefedf29acb7e90 +Author: Damien Miller +Date: Mon Nov 4 14:39:27 2024 +1100 - upstream: fix recursive remote-remote copies of directories that - - contain symlinks to other directories (similar to bz3611) - - OpenBSD-Commit-ID: 7e19d2ae09b4f941bf8eecc3955c9120171da37f + Add git signing key for Tim Rice -commit 7c0ce2bf98b303b6ad91493ee3247d96c18ba1f6 -Author: djm@openbsd.org -Date: Fri Sep 8 05:50:57 2023 +0000 +commit da4b84845e874f12af7e0686170fa391c919d1df +Author: Darren Tucker +Date: Fri Nov 1 18:51:22 2024 +1100 - upstream: regress test for recursive copies of directories containing - - symlinks to other directories. bz3611, ok dtucker@ - - OpenBSD-Regress-ID: eaa4c29cc5cddff4e72a16bcce14aeb1ecfc94b9 + Correct path to c-cpp.yml file in workflow config. -commit 2de990142a83bf60ef694378b8598706bc654b08 -Author: djm@openbsd.org -Date: Fri Sep 8 05:56:13 2023 +0000 +commit 28740aa2c75392a9c4191eb9523f9b20853e2932 +Author: Darren Tucker +Date: Fri Nov 1 18:44:42 2024 +1100 - upstream: the sftp code was one of my first contributions to - - OpenSSH and it shows - the function names are terrible. - - Rename do_blah() to sftp_blah() to make them less so. - - Completely mechanical except for sftp_stat() and sftp_lstat() which - change from returning a pointer to a static variable (error-prone) to - taking a pointer to a caller-provided receiver. - - OpenBSD-Commit-ID: eb54d6a72d0bbba4d623e2175cf5cc4c75dc2ba4 + Test new OpenSSL and LibreSSL releases.` -commit 249d8bd0472b53e3a2a0e138b4c030a31e83346a -Author: djm@openbsd.org -Date: Fri Sep 8 05:50:12 2023 +0000 +commit a74809fe06540f16231b354ffe21fcbf39e81f73 +Author: Darren Tucker +Date: Fri Nov 1 18:44:00 2024 +1100 - upstream: fix scp in SFTP mode recursive upload and download of - - directories that contain symlinks to other directories. In scp mode, the - links would be followed, but in SFTP mode they were not. bz3611, ok dtucker@ - - OpenBSD-Commit-ID: 9760fda668eaa94a992250d7670dfbc62a45197c + Add nbsd10 default test config. + +commit 88b35cbdc1500efece65cd6a9a20a72cf7e46eaa +Author: Damien Miller +Date: Wed Oct 30 14:25:14 2024 +1100 + + fix uint64_t types; reported by Tom G. Christensen -commit 0e1f4401c466fa4fdaea81b6dadc8dd1fc4cf0af +commit ef7c26cd2f0f9a8222f851d1e551f6dfd3113f8b +Author: Damien Miller +Date: Sun Oct 27 13:28:11 2024 +1100 + + htole64() etc for systems without endian.h + +commit 0c3927c45f8a57b511c874c4d51a8c89414f74ef Author: djm@openbsd.org -Date: Wed Sep 6 23:36:09 2023 +0000 +Date: Sun Oct 27 02:06:59 2024 +0000 - upstream: regression test for override of subsystem in match blocks + upstream: explicitly include endian.h - OpenBSD-Regress-ID: 5f8135da3bfda71067084c048d717b0e8793e87c + OpenBSD-Commit-ID: 13511fdef7535bdbc35b644c90090013da43a318 -commit 8a1450c62035e834d8a79a5d0d1c904236f9dcfe +commit cf3e48ee8ba1beeccddd2f203b558fa102be67a2 Author: djm@openbsd.org -Date: Wed Sep 6 23:35:35 2023 +0000 +Date: Sun Oct 27 02:06:01 2024 +0000 - upstream: allow override of Sybsystem directives in sshd Match + upstream: fix ML-KEM768x25519 KEX on big-endian systems; spotted by - blocks + jsg@ feedback/ok deraadt@ - OpenBSD-Commit-ID: 3911d18a826a2d2fe7e4519075cf3e57af439722 + OpenBSD-Commit-ID: 26d81a430811672bc762687166986cad40d28cc0 -commit 6e52826e2a74d077147a82ead8d4fbd5b54f4e3b -Author: djm@openbsd.org -Date: Wed Sep 6 23:26:37 2023 +0000 +commit ae566d51b64fa3dce7063e7745b9b35f8f47abde +Author: naddy@openbsd.org +Date: Fri Oct 25 21:53:24 2024 +0000 - upstream: allocate the subsystems array as necessary and remove the + upstream: mlkem768x25519-sha256 has been promoted to default key - fixed limit of subsystems. Saves a few kb of memory in the server and makes - it more like the other options. + exchange - OpenBSD-Commit-ID: e683dfca6bdcbc3cc339bb6c6517c0c4736a547f + OpenBSD-Commit-ID: 5a3259a193fd42108a869ebf650b95b5f2d08dcf -commit e19069c9fac4c111d6496b19c7f7db43b4f07b4f -Author: djm@openbsd.org -Date: Wed Sep 6 23:23:53 2023 +0000 +commit 3af1dba1384ca896df6e973c70398c41d36de1ea +Author: Darren Tucker +Date: Fri Oct 25 19:04:30 2024 +1100 - upstream: preserve quoting of Subsystem commands and arguments. + Retire the minix3 test config. - This may change behaviour of exotic configurations, but the most common - subsystem configuration (sftp-server) is unlikely to be affected. + It got broken by the sshd-auth change, it's not obvious why, and the + platform lacks the debugging tools (eg gdb, strace) to figure it out. + The upstream project seems effectively dead (6 years since the last + commit, 10 since the last release). It was useful while it lasted + (we found a real bug because of it) but its time seems to have passed. + +commit 3b240cc44b8de9175280ddbe59331317d427b0e3 +Author: Preetish Amballi +Date: Mon Oct 21 14:07:02 2024 +0000 + + Updated gitignore to ignore sshd-session and sshd-auth targets + +commit 326495744f06a0ab18ee0d16f87b3fe91cac92fb +Author: Darren Tucker +Date: Fri Oct 25 19:01:02 2024 +1100 + + Simplify pselect shim and remove side effects. - OpenBSD-Commit-ID: 8ffa296aeca981de5b0945242ce75aa6dee479bf + Instead of maintaing state (pipe descriptors, signal handlers) across + pselect-on-select invocations, set up and restore them each call. + This prevents outside factors (eg a closefrom or signal handler + installation) from potentially causing problems. This does result in a + drop in throughput of a couple of percent on geriatric platforms without + a native pselect due to the extra overhead. Tweaks & ok djm@ -commit 52dfe3c72d98503d8b7c6f64fc7e19d685636c0b +commit e53b615f3934ffac1efb3c1e491d126b9b09fd24 Author: djm@openbsd.org -Date: Wed Sep 6 23:21:36 2023 +0000 +Date: Fri Oct 25 01:34:18 2024 +0000 - upstream: downgrade duplicate Subsystem directives from being a + upstream: promote mlkem768x25519-sha256 to be the default key exchange; - fatal error to being a debug message to match behaviour with just about all - other directives. + ok markus@ - OpenBSD-Commit-ID: fc90ed2cc0c18d4eb8e33d2c5e98d25f282588ce + OpenBSD-Commit-ID: fc673065e6505bb06b2e2b9362f78ccb4200a828 -commit 1ee0a16e07b6f0847ff463d7b5221c4bf1876e25 +commit de644b1831b970f6655f871c051774cc871e8e74 Author: djm@openbsd.org -Date: Wed Sep 6 23:18:15 2023 +0000 +Date: Thu Oct 24 03:28:34 2024 +0000 - upstream: handle cr+lf (instead of just cr) in sshsig signature + upstream: test SIGUSR1 dropping all keys from ssh-agent - files - - OpenBSD-Commit-ID: 647460a212b916540016d066568816507375fd7f + OpenBSD-Regress-ID: 8654b9aa8eb695b1499fffc408c25319592bf0e0 -commit e1c284d60a928bcdd60bc575c6f9604663502770 -Author: job@openbsd.org -Date: Mon Sep 4 10:29:58 2023 +0000 +commit e86d7a077ce9a2b9ee9d4138c358a17cbdb786f9 +Author: djm@openbsd.org +Date: Thu Oct 24 03:15:47 2024 +0000 - upstream: Generate Ed25519 keys when invoked without arguments + upstream: amake ssh-agent drop all keys when it receives SIGUSR1; - Ed25519 public keys are very convenient due to their small size. - OpenSSH has supported Ed25519 since version 6.5 (January 2014). + let's users zap keys without access to $SSH_AUTH_SOCK - OK djm@ markus@ sthen@ deraadt@ + ok deraadt@ - OpenBSD-Commit-ID: f498beaad19c8cdcc357381a60df4a9c69858b3f + OpenBSD-Commit-ID: dae9db0516b1011e5ba8c655ac702fce42e6c023 -commit 694150ad92765574ff82a18f4e86322bd3231e68 +commit 94cdfebec852a2429c008cc2a55f8e4183f36972 Author: djm@openbsd.org -Date: Mon Sep 4 00:08:14 2023 +0000 +Date: Thu Oct 24 03:14:37 2024 +0000 - upstream: trigger keystroke timing obfucation only if the channels + upstream: relax valid_domain() checks to allow an underscore as the - layer enqueud some data in the last poll() cycle; this avoids triggering the - obfuscatior for non-channels data like ClientAlive probes and also fixes a - related problem were the obfucations would be triggered on fully quiescent - connections. + first character. ok deraadt@ - Based on / tested by naddy@ - - OpenBSD-Commit-ID: d98f32dc62d7663ff4660e4556e184032a0db123 + OpenBSD-Commit-ID: 3f8be6d32496e5596dd8b14e19cb067ddd7969ef -commit b5fd97896b59a3a46245cf438cc8b16c795d9f74 -Author: djm@openbsd.org -Date: Mon Sep 4 00:04:02 2023 +0000 +commit 1b05d5437bf45bee5e3104772dea06ed51764f1b +Author: dtucker@openbsd.org +Date: Tue Oct 22 07:13:28 2024 +0000 - upstream: avoid bogus "obfuscate_keystroke_timing: stopping ..." + upstream: Remove sshd logfile in start_sshd - debug messages when keystroke timing obfuscation was never started; spotted - by naddy@ + ... and ssh and sshd log wrappers before recreating them. Prevents "can't + create" errors during tests when running tests without SUDO after having + run them with SUDO. - OpenBSD-Commit-ID: 5c270d35f7d2974db5c1646e9c64188f9393be31 + OpenBSD-Regress-ID: 2f0a83532e3dccd673a9bf0291090277268c69a6 -commit ccf7d913db34e49b7a6db1b8331bd402004c840d -Author: djm@openbsd.org -Date: Mon Sep 4 00:01:46 2023 +0000 +commit 307ab3c7720f8879b835614b02687358ee4df9b9 +Author: dtucker@openbsd.org +Date: Tue Oct 22 06:16:26 2024 +0000 - upstream: make channel_output_poll() return a flag indicating + upstream: Add a sshd debug wrapper - whether channel data was enqueued. Will be used to improve keystroke timing - obfuscation. Problem spotted by / tested by naddy@ + ... to run all of the subprograms from the build directory while + developing and debugging. Should help prevent accidentally testing + against unchanged installed sshd-auth and sshd-session binaries. ok djm@ - OpenBSD-Commit-ID: f9776c7b0065ba7c3bbe50431fd3b629f44314d0 + OpenBSD-Commit-ID: 61760cdc98c2bc8f1e9f83a6f97cca0f66b52e69 -commit 43254b326ac6e2131dbd750f9464dc62c14bd5a7 -Author: djm@openbsd.org -Date: Sun Sep 3 23:59:32 2023 +0000 +commit 87bd1cb3ccba5e91d2650eb7f753c898ee43858e +Author: dtucker@openbsd.org +Date: Tue Oct 22 06:13:00 2024 +0000 - upstream: set interactive mode for ControlPersist sessions if they + upstream: Make debug call printf("%s", NULL) safe. - originally requested a tty; enables keystroke timing obfuscation for most - ControlPersist sessions. Spotted by naddy@ + Prevents problems on platforms where this isn't safe (which it's not + required to be). ok djm@ - OpenBSD-Commit-ID: 72783a26254202e2f3f41a2818a19956fe49a772 + OpenBSD-Commit-ID: 8fa4ce3ad90915c925b81b99a79ab920b0523387 -commit ff3eda68ceb2e2bb8f48e3faceb96076c3e85c20 +commit c44c349edd157b2c00c42bd5ef5f9dfb37de26f3 Author: Darren Tucker -Date: Thu Aug 31 23:02:35 2023 +1000 +Date: Tue Oct 22 17:48:32 2024 +1100 - Set LLONG_MAX for C89 test. - - If we don't have LLONG_MAX, configure will figure out that it can get it - by setting -std=gnu99, at which point we won't be testing C89 any more. - To avoid this, feed it in via CFLAGS. + Resync cvsid missed in commit 6072e4c9. -commit f98031773db361424d59e3301aa92aacf423d920 +commit fe4305c37ffe53540a67586854e25f05cf615849 Author: djm@openbsd.org -Date: Tue Aug 29 02:50:10 2023 +0000 +Date: Fri Oct 18 05:53:26 2024 +0000 - upstream: make PerSourceMaxStartups first-match-wins; ok dtucker@ + upstream: mention that LocalForward and RemoteForward can accept Unix - OpenBSD-Commit-ID: dac0c24cb709e3c595b8b4f422a0355dc5a3b4e7 + domain socket paths; GHPR115 + + OpenBSD-Commit-ID: a8a34d0a0c51a9ddab3dfce615f9878fa76ef842 -commit cfa66857db90cd908de131e0041a50ffc17c7df8 +commit 9c97b6af8e052ab5ffe0f9096fadc8f9a4d0ed0f Author: djm@openbsd.org -Date: Mon Aug 28 09:52:09 2023 +0000 +Date: Fri Oct 18 05:45:40 2024 +0000 - upstream: descriptive text shouldn't be under .Cm + upstream: remove duplicate check; GHPR392 from Pedro Martelletto - OpenBSD-Commit-ID: b1afaeb456a52bc8a58f4f9f8b2f9fa8f6bf651b + OpenBSD-Commit-ID: 597ab7dd3f0e78939d2659fc1904d0f39ee95487 -commit 01dbf3d46651b7d6ddf5e45d233839bbfffaeaec +commit d9cd208e89a471a3ff8adfcec68d6210af9e9fd5 Author: djm@openbsd.org -Date: Mon Aug 28 09:48:11 2023 +0000 +Date: Fri Oct 18 05:37:24 2024 +0000 - upstream: limit artificial login delay to a reasonable maximum (5s) - - and don't delay at all for the "none" authentication mechanism. Patch by - Dmitry Belyavskiy in bz3602 with polish/ok dtucker@ + upstream: allow "-" as output file for moduli screening - OpenBSD-Commit-ID: 85b364676dd84cf1de0e98fc2fbdcb1a844ce515 - -commit 528da5b9d7c5da01ed7a73ff21c722e1b5326006 -Author: jmc@openbsd.org -Date: Mon Aug 28 05:32:28 2023 +0000 - - upstream: add spacing for punctuation when macro args; + based on GHPR393 - OpenBSD-Commit-ID: e80343c16ce0420b2aec98701527cf90371bd0db + OpenBSD-Commit-ID: 1517763764eb55d03a6092dd120d2909c6fef0e1 -commit 3867361ca691d0956ef7d5fb8181cf554a91d84a +commit 5eb5c4b2820d0636b1eccee646fb32ec946c4a95 Author: djm@openbsd.org -Date: Mon Aug 28 04:06:52 2023 +0000 +Date: Fri Oct 18 05:32:51 2024 +0000 - upstream: explicit long long type in timing calculations (doesn't + upstream: ssh-keyscan doesn't need it's own sshfatal() definition, it + + can use the shared one from fatal.c - matter, since the range is pre-clamped) + based on GHPR401 from lengyijun - OpenBSD-Commit-ID: f786ed902d04a5b8ecc581d068fea1a79aa772de + OpenBSD-Commit-ID: 8ea75ea99f27f464c9223cbc89cb046ccf9cd5c4 -commit 7603ba71264e7fa938325c37eca993e2fa61272f +commit 0a1e75499e2c6fc258ee903645c878480949f362 Author: djm@openbsd.org -Date: Mon Aug 28 03:31:16 2023 +0000 +Date: Fri Oct 18 05:14:51 2024 +0000 - upstream: Add keystroke timing obfuscation to the client. + upstream: in _ssh_order_hostkeyalgs() consider ECDSA curve type when - This attempts to hide inter-keystroke timings by sending interactive - traffic at fixed intervals (default: every 20ms) when there is only a - small amount of data being sent. It also sends fake "chaff" keystrokes - for a random interval after the last real keystroke. These are - controlled by a new ssh_config ObscureKeystrokeTiming keyword/ + arranging the hostkey algorithms. AFAIK this code is unused in OpenSSH, but I + guess others are using it - feedback/ok markus@ + based on GHPR387 from Pawel Jakub Dawidek - OpenBSD-Commit-ID: 02231ddd4f442212820976068c34a36e3c1b15be + OpenBSD-Commit-ID: 4d462495ac0c40f7b7dd66178e0005b9b2128225 -commit dce6d80d2ed3cad2c516082682d5f6ca877ef714 +commit d01ee7a88c5f4b1aa8c75a7c739f8f3bc1ad8bde Author: djm@openbsd.org -Date: Mon Aug 28 03:28:43 2023 +0000 +Date: Fri Oct 18 05:03:34 2024 +0000 - upstream: Introduce a transport-level ping facility + upstream: require control-escape character sequences passed via the '-e - This adds a pair of SSH transport protocol messages SSH2_MSG_PING/PONG - to implement a ping capability. These messages use numbers in the "local - extensions" number space and are advertised using a "ping@openssh.com" - ext-info message with a string version number of "0". + ^x' commandline to be exactly two characters long. Avoids one by OOB read if + ssh is invoked as "ssh -e^ ..." - ok markus@ + Spotted by Maciej Domanski in GHPR368 - OpenBSD-Commit-ID: b6b3c4cb2084c62f85a8dc67cf74954015eb547f + OpenBSD-Commit-ID: baa72bc60898fc5639e6c62de7493a202c95823d -commit d2d247938b38b928f8a6e1a47a330c5584d3a358 -Author: tobhe@openbsd.org -Date: Mon Aug 21 21:16:18 2023 +0000 +commit 74ff6382f5743e09930e6cbd195dac65cd6062c9 +Author: djm@openbsd.org +Date: Fri Oct 18 04:30:09 2024 +0000 - upstream: Log errors in kex_exchange_identification() with level + upstream: remove addr.[ch] functions that are unused and - verbose instead of error to reduce preauth log spam. All of those get logged - with a more generic error message by sshpkt_fatal(). + visbility-restrict ones that are unused outside the implementation itself; + based on GHPR#282 by tobias@ - feedback from sthen@ - ok djm@ + OpenBSD-Commit-ID: a0140f2418b4d46cfaa7b33febc0a0931f9b2744 + +commit a9d6d7d93c533fa729f08b405e786d912553f33e +Author: djm@openbsd.org +Date: Fri Oct 18 04:14:59 2024 +0000 + + upstream: unreachable POLLERR case; from ya0guang via GHPR485 - OpenBSD-Commit-ID: bd47dab4695b134a44c379f0e9a39eed33047809 + OpenBSD-Commit-ID: b3c82655190532b01eb817e532742cfaa4687eff -commit 9d7193a8359639801193ad661a59d1ae4dc3d302 +commit d76424bf279ff951383e21213eb3759ea4090674 Author: djm@openbsd.org -Date: Mon Aug 21 04:59:54 2023 +0000 +Date: Fri Oct 18 04:11:54 2024 +0000 - upstream: correct math for ClientAliveInterval that caused the + upstream: s/Sx/Cm/ for external references; from Domen Puncer - probes to be sent less frequently than configured; from Dawid Majchrzak + Kugler via GHPR501 - OpenBSD-Commit-ID: 641153e7c05117436ddfc58267aa267ca8b80038 + OpenBSD-Commit-ID: f864a34feb5d5ff17160cf7c42ad0f7744fe8a3f -commit 3c6ab63b383b0b7630da175941e01de9db32a256 -Author: Darren Tucker -Date: Fri Aug 25 14:48:02 2023 +1000 +commit ca204b994e2981e7bf95627b3105408917105649 +Author: naddy@openbsd.org +Date: Mon Oct 14 23:53:34 2024 +0000 - Include Portable version in sshd version string. + upstream: mention SshdAuthPath option; ok djm@ - bz#3608, ok djm@ + OpenBSD-Commit-ID: 9a5d3add25e4e77bd3805bc5583a842ecf34d85c -commit 17fa6cd10a26e193bb6f65d21264d2fe553bcd87 +commit be27770e840c4dd9d9fcad1aa879400c727d7c2f Author: Darren Tucker -Date: Mon Aug 21 19:47:58 2023 +1000 +Date: Fri Oct 18 13:37:55 2024 +1100 - obsd-arm64 host is real hardware... + Remove references to systrace and pledge sandboxes. - so put in the correct config location. + ok djm@ -commit 598ca75c85acaaacee5ef954251e489cc20d7be9 -Author: Darren Tucker -Date: Mon Aug 21 18:38:36 2023 +1000 +commit 49e64bf63fbf2f14961062dafe8ef08cb816bb08 +Author: Pavel Miadzvedzeu +Date: Wed Apr 24 10:19:56 2024 +0300 - Add OpenBSD ARM64 test host. + Fix "undeclared 'ut'" error by replacing it with 'utx' -commit 1acac79bfbe207e8db639e8043524962037c8feb +commit 67f684733f60f66479854a2867b953de731e71b2 Author: Darren Tucker -Date: Mon Aug 21 18:05:26 2023 +1000 +Date: Thu Oct 17 20:50:29 2024 +1100 - Add test for zlib development branch. - -commit 84efebf352fc700e9040c8065707c63caedd36a3 -Author: djm@openbsd.org -Date: Mon Aug 21 04:36:46 2023 +0000 - - upstream: want stdlib.h for free(3) + Seed RNG when starting up sshd-auth. - OpenBSD-Commit-ID: 743af3c6e3ce5e6cecd051668f0327a01f44af29 + Makes builds configured --without-openssl work again since otherwise + the first use of the RNG comes after the sandbox init and it can't + open /dev/random. -commit cb4ed12ffc332d1f72d054ed92655b5f1c38f621 +commit c06c681aeebbe8e84e7410095514e7ee91f7e6cb Author: Darren Tucker -Date: Sat Aug 19 07:39:08 2023 +1000 +Date: Thu Oct 17 19:18:23 2024 +1100 - Fix zlib version check for 1.3 and future version. - - bz#3604. + MacOS 12 runners are deprecated, replace with 15. -commit 25b75e21f16bccdaa472ea1889b293c9bd51a87b -Author: Darren Tucker -Date: Mon Aug 14 11:10:08 2023 +1000 +commit 39db1f23bafb48a7c0cc9c65c716a0370f4cc677 +Author: Damien Miller +Date: Thu Oct 17 13:28:47 2024 +1100 - Add 9.4 branch to CI status page. + Fix lookup path for sshd-auth; bz3745 -commit 803e22eabd3ba75485eedd8b7b44d6ace79f2052 -Author: djm@openbsd.org -Date: Fri Aug 18 01:37:41 2023 +0000 +commit c537eeb1ae5f069450053b0027e64efe5bdb37d2 +Author: Damien Miller +Date: Wed Oct 16 08:28:21 2024 +1100 - upstream: fix regression in OpenSSH 9.4 (mux.c r1.99) that caused - - multiplexed sessions to ignore SIGINT under some circumstances. Reported by / - feedback naddy@, ok dtucker@ - - OpenBSD-Commit-ID: 4d5c6c894664f50149153fd4764f21f43e7d7e5a + fix breakage; missing saved_argc symbol -commit e706bca324a70f68dadfd0ec69edfdd486eed23a -Author: djm@openbsd.org -Date: Wed Aug 16 16:14:11 2023 +0000 +commit 98a0883bdef28a06c7e017f27adf21ba57898bf4 +Author: Damien Miller +Date: Mon Oct 14 17:17:50 2024 +1100 - upstream: defence-in-depth MaxAuthTries check in monitor; ok markus - - OpenBSD-Commit-ID: 65a4225dc708e2dae71315adf93677edace46c21 + fix capsicum sandbox -commit d1ab7eb90474df656d5e9935bae6df0bd000d343 -Author: djm@openbsd.org -Date: Mon Aug 14 03:37:00 2023 +0000 +commit 164ea4380564a2a83713eacf71908e3946e5e4e4 +Author: Damien Miller +Date: Mon Oct 14 17:16:41 2024 +1100 - upstream: add message number of SSH2_MSG_NEWCOMPRESS defined in RFC8308 - - OpenBSD-Commit-ID: 6c984171c96ed67effd7b5092f3d3975d55d6028 + put back some portable bits for sshd-auth.c -commit fa8da52934cb7dff6f660a143276bdb28bb9bbe1 -Author: Darren Tucker -Date: Sun Aug 13 15:01:27 2023 +1000 +commit f8edf08c258ee2918689872c4702302052729726 +Author: Damien Miller +Date: Mon Oct 14 14:49:25 2024 +1100 - Add obsd72 and obsd73 test targets. + there's only one sandbox, move to a static global -commit f9f18006678d2eac8b0c5a5dddf17ab7c50d1e9f -Author: djm@openbsd.org -Date: Thu Aug 10 23:05:48 2023 +0000 - - upstream: better debug logging of sessions' exit status - - OpenBSD-Commit-ID: 82237567fcd4098797cbdd17efa6ade08e1a36b0 - -commit a8c57bcb077f0cfdffcf9f23866bf73bb93e185c -Author: naddy@openbsd.org -Date: Thu Aug 10 14:37:32 2023 +0000 - - upstream: drop a wayward comma, ok jmc@ - - OpenBSD-Commit-ID: 5c11fbb9592a29b37bbf36f66df50db9d38182c6 - -commit e962f9b318a238db1becc53c2bf79dd3a49095b4 -Author: Damien Miller -Date: Thu Aug 10 11:10:22 2023 +1000 +commit 4482f0042b41d3d63c3845d7ba9fcf47c9252a84 +Author: Damien Miller +Date: Mon Oct 14 14:49:20 2024 +1100 depend -commit 0fcb60bf83130dfa428bc4422b3a3ac20fb528af -Author: Damien Miller -Date: Thu Aug 10 11:05:42 2023 +1000 - - update versions in RPM specs - -commit d0cee4298491314f09afa1c4383a66d913150b26 -Author: Damien Miller -Date: Thu Aug 10 11:05:14 2023 +1000 - - update version in README - -commit 78b4dc6684f4d35943b46b24ee645edfdb9974f5 +commit 74856204a353a187dc6e7706c6cf84b7f14d775d Author: djm@openbsd.org -Date: Thu Aug 10 01:01:07 2023 +0000 +Date: Mon Oct 14 03:02:08 2024 +0000 - upstream: openssh-9.4 + upstream: regress support for split sshd-auth binary - OpenBSD-Commit-ID: 71fc1e01a4c4ea061b252bd399cda7be757e6e35 - -commit 58ca4f0aa8c4306ac0a629c9a85fb1efaf4ff092 -Author: Darren Tucker -Date: Thu Aug 10 11:30:24 2023 +1000 + OpenBSD-Regress-ID: df7d18a87b475f70004770f0f4e404adba5f6ab7 - Only include unistd.h once. - -commit 3961ed02dc578517a9d2535128cff5c3a5460d28 -Author: Damien Miller -Date: Thu Aug 10 09:08:49 2023 +1000 - - wrap poll.h include in HAVE_POLL_H - -commit e535fbe2af893046c28adfcd787c1fdbae36a24a -Author: dtucker@openbsd.org -Date: Fri Aug 4 06:32:40 2023 +0000 +commit 461741083d7254595fecea274e60fe3ebf3ce3f9 +Author: djm@openbsd.org +Date: Fri Sep 27 01:05:54 2024 +0000 - upstream: Apply ConnectTimeout to multiplexing local socket + upstream: test some more Match syntax, including criteria=arg and - connections. If the multiplex socket exists but the connection times out, - ssh will fall back to a direct connection the same way it would if the socket - did not exist at all. ok djm@ - - OpenBSD-Commit-ID: 2fbe1a36d4a24b98531b2d298a6557c8285dc1b4 - -commit 9d92e7b24848fcc605945f7c2e3460c7c31832ce -Author: Darren Tucker -Date: Thu Aug 3 19:35:33 2023 +1000 - - Fix RNG seeding for OpenSSL w/out self seeding. + negations - When sshd is built with an OpenSSL that does not self-seed, it would - fail in the preauth privsep process while handling a new connection. - Sanity checked by djm@ + OpenBSD-Regress-ID: 67476baccc60bf1a255fd4e329ada950047b8b8d -commit f70010d9b0b3e7e95de8aa0b961e1d74362cfb5d +commit 6072e4c9385713e9c166f32cfca6a7e603d4f0b8 Author: djm@openbsd.org -Date: Wed Aug 2 23:04:38 2023 +0000 +Date: Mon Oct 14 01:57:50 2024 +0000 - upstream: CheckHostIP has defaulted to 'no' for a while; make the + upstream: Split per-connection sshd-session binary - commented- out config option match. From Ed Maste - - OpenBSD-Commit-ID: e66e934c45a9077cb1d51fc4f8d3df4505db58d9 - -commit c88a8788f9865d02b986d00405b9f0be65ad0b5a -Author: dtucker@openbsd.org -Date: Tue Aug 1 08:15:04 2023 +0000 - - upstream: remove unnecessary if statement. + This splits the user authentication code from the sshd-session + binary into a separate sshd-auth binary. This will be executed by + sshd-session to complete the user authentication phase of the + protocol only. - github PR#422 from eyalasulin999, ok djm@ + Splitting this code into a separate binary ensures that the crucial + pre-authentication attack surface has an entirely disjoint address + space from the code used for the rest of the connection. It also + yields a small runtime memory saving as the authentication code will + be unloaded after thhe authentication phase completes. - OpenBSD-Commit-ID: 2b6b0dde4407e039f58f86c8d2ff584a8205ea55 - -commit 77b8b865cd5a8c79a47605c0c5b2bacf4692c4d5 -Author: jmc@openbsd.org -Date: Fri Jul 28 05:42:36 2023 +0000 - - upstream: %C is a callable macro in mdoc(7) + Joint work with markus@ feedback deraadt@ - so, as we do for %D, escape it; + Tested in snaps since last week - OpenBSD-Commit-ID: 538cfcddbbb59dc3a8739604319491dcb8e0c0c9 + OpenBSD-Commit-ID: 9c3b2087ae08626ec31b4177b023db600e986d9c -commit e0f91aa9c2fbfc951e9ced7e1305455fc614d3f2 +commit fe6c6330c1a94c7a537efe9069853ce7a275c50a Author: djm@openbsd.org -Date: Fri Jul 28 05:33:15 2023 +0000 +Date: Sun Oct 13 22:20:06 2024 +0000 - upstream: don't need to start a command here; use ssh -N instead. - - Fixes failure on cygwin spotted by Darren + upstream: don't start the ObscureKeystrokeTiming mitigations if - OpenBSD-Regress-ID: ff678a8cc69160a3b862733d935ec4a383f93cfb - -commit f446a44f30bc680e0d026a4204844b02646c1c2d -Author: djm@openbsd.org -Date: Wed May 17 05:52:01 2023 +0000 - - upstream: add LTESTS_FROM variable to allow skipping of tests up to + there has been traffic on a X11 forwarding channel recently. - a specific point. e.g. "make LTESTS_FROM=t-sftp" will only run the sftp.sh - test and subsequent ones. ok dtucker@ + Should fix X11 forwarding performance problems when this setting is + enabled. Patch from Antonio Larrosa via bz3655 - OpenBSD-Regress-ID: 07f653de731def074b29293db946042706fcead3 + OpenBSD-Commit-ID: 820284a92eb4592fcd3d181a62c1b86b08a4a7ab -commit 8eb8899d612440a9b608bee7f916081d3d0b7812 -Author: djm@openbsd.org -Date: Fri May 12 06:37:42 2023 +0000 +commit 538cd28598ae942c94b99855b06fdd937e2e7381 +Author: jsg@openbsd.org +Date: Sat Oct 12 10:50:37 2024 +0000 - upstream: test ChrootDirectory in Match block + upstream: remove duplicate misc.h include ok dtucker@ - OpenBSD-Regress-ID: a6150262f39065939f025e546af2a346ffe674c1 + OpenBSD-Commit-ID: fdd056e7854294834d54632b4282b877cfe4c12e -commit e43f43d3f19516222e9a143468ea0dc1b3ab67b6 +commit 0051381a8c33740a77a1eca6859efa1c78887d80 Author: djm@openbsd.org -Date: Fri May 12 06:36:27 2023 +0000 +Date: Sun Oct 6 23:37:17 2024 +0000 - upstream: better error messages + upstream: Turn off finite field (a.k.a modp) Diffie-Hellman key + + exchange in sshd by default. Specifically, this removes the + diffie-hellman-group* and diffie-hellman-group-exchange-* methods. The client + is unchanged and continues to support these methods by default. - OpenBSD-Regress-ID: 55e4186604e80259496d841e690ea2090981bc7a + Finite field Diffie Hellman is slow and computationally expensive for + the same security level as Elliptic Curve DH or PQ key agreement while + offering no redeeming advantages. + + ECDH has been specified for the SSH protocol for 15 years and some + form of ECDH has been the default key exchange in OpenSSH for the last + 14 years. + + ok markus@ + + OpenBSD-Commit-ID: 4e238ad480a33312667cc10ae0eb6393abaec8da -commit 6958f00acf3b9e0b3730f7287e69996bcf3ceda4 +commit 67a115e7a56dbdc3f5a58c64b29231151f3670f5 Author: djm@openbsd.org -Date: Thu Jul 27 22:26:49 2023 +0000 +Date: Thu Sep 26 23:55:08 2024 +0000 - upstream: don't incorrectly truncate logged strings retrieved from + upstream: fix previous change to ssh_config Match, which broken on - PKCS#11 modules; based on GHPR406 by Jakub Jelen; ok markus + negated Matches; spotted by phessler@ ok deraadt@ - OpenBSD-Commit-ID: 7ed1082f23a13b38c373008f856fd301d50012f9 + OpenBSD-Commit-ID: b1c6acec66cd5bd1252feff1d02ad7129ced37c7 -commit d1ffde6b55170cd4b9a72bfd9a3f17508e6cf714 -Author: djm@openbsd.org -Date: Thu Jul 27 22:25:17 2023 +0000 +commit 220b6c1290042acd5180d783dea01efe1365c265 +Author: jsg@openbsd.org +Date: Wed Sep 25 23:01:39 2024 +0000 - upstream: make sshd_config AuthorizedPrincipalsCommand and + upstream: remove some unused defines; ok djm@ - AuthorizedKeysCommand accept the %D (routing domain) and a new %C (connection - address/port 4-tuple) as expansion sequences; ok markus - - OpenBSD-Commit-ID: ee9a48bf1a74c4ace71b69de69cfdaa2a7388565 + OpenBSD-Commit-ID: 3a63e4e11d455704f684c28715d61b17f91e0996 -commit 999a2886ca1844a7a74b905e5f2c8c701f9838cd -Author: djm@openbsd.org -Date: Thu Jul 27 22:23:05 2023 +0000 +commit 3ef4f6e8a4d774f73852391fdccbb95f39fc71bf +Author: jmc@openbsd.org +Date: Wed Sep 25 06:13:01 2024 +0000 - upstream: increase default KDF work-factor for OpenSSH format + upstream: remove some unneeded Xo/Xc calls; from evan silberman the - private keys from 16 to 24; { feedback ok } x { deraadt markus } + original diff had a couple of errors, which i've fixed - OpenBSD-Commit-ID: a3afb1383f8ff0a49613d449f02395d9e8d4a9ec + OpenBSD-Commit-ID: f37ad5888adbc0d4e1cd6b6de237841f4b1e650d -commit 0fa803a1dd1c7b546c166000e23a869cf6c4ec10 -Author: Darren Tucker -Date: Thu Jul 27 02:25:09 2023 +1000 +commit 3f02368e8e9121847727c46b280efc280e5eb615 +Author: djm@openbsd.org +Date: Wed Sep 25 01:24:04 2024 +0000 - Prefer OpenSSL's SHA256 in sk-dummy.so + upstream: fix regression introduced when I switched the "Match" - Previously sk-dummy.so used libc's (or compat's) SHA256 since it may be - built without OpenSSL. In many cases, however, including both libc's - and OpenSSL's headers together caused conflicting definitions. + criteria tokeniser to a more shell-like one. Apparently the old tokeniser + (accidentally?) allowed "Match criteria=argument" as well as the "Match + criteria argument" syntax that we tested for. - We tried working around this (on OpenSSL <1.1 you could define - OPENSSL_NO_SHA, NetBSD had USE_LIBC_SHA2, various #define hacks) with - varying levels of success. Since OpenSSL >=1.1 removed OPENSSL_NO_SHA - and including most OpenSSL headers would bring sha.h in, even if it - wasn't used directly this was a constant hassle. + People were using this syntax so this adds back support for + "Match criteria=argument" - Admit defeat and use OpenSSL's SHA256 unless we aren't using OpenSSL at - all. ok djm@ - -commit 36cdb5dbf55c99c0faad06066f56a7c341258c1f -Author: Darren Tucker -Date: Thu Jul 27 10:29:44 2023 +1000 - - Retire dfly58 test VM. Add dfly64. + bz3739 ok dtucker + + OpenBSD-Commit-ID: d1eebedb8c902002b75b75debfe1eeea1801f58a -commit 2d34205dab08ede9b0676efa57647fc49e6decbe +commit 9517cc58577f85a0ba5f8bb46778dff625f0688f Author: djm@openbsd.org -Date: Wed Jul 26 23:06:00 2023 +0000 +Date: Tue Sep 24 02:28:17 2024 +0000 - upstream: make ssh -f (fork after authentication) work properly in + upstream: some extra paranoia, reminded by jsg@ - multiplexed cases (inc. ControlPersist). bz3589 bz3589 Based on patches by - Peter Chubb; ok dtucker@ - - OpenBSD-Commit-ID: a7a2976a54b93e6767dc846b85647e6ec26969ac + OpenBSD-Commit-ID: 22072bfa1df1391858ae7768a6c627e08593a91e -commit 076aeda86a7ee9be8fd2f0181ec7b9729a6ceb37 -Author: naddy@openbsd.org -Date: Sun Jul 23 20:04:45 2023 +0000 +commit 815a94e86a68c1000b8310cb47695cea9329516c +Author: Damien Miller +Date: Wed Sep 25 11:15:45 2024 +1000 - upstream: man page typos; ok jmc@ + gss-serv.c needs sys/param.h - OpenBSD-Commit-ID: e6ddfef94b0eb867ad88abe07cedc8ed581c07f0 + From Void Linux -commit 135e7d5fe31f700e6dfc61ce914970c5ee7175ba -Author: jmc@openbsd.org -Date: Thu Jul 20 05:43:39 2023 +0000 +commit 76a618d2842c34c16cd21a4efc7230e2f459008d +Author: Damien Miller +Date: Wed Sep 25 11:13:05 2024 +1000 - upstream: tweak the allow-remote-pkcs11 text; + build construct_utmp() when USE_BTMP is set - OpenBSD-Commit-ID: bc965460a89edf76865b7279b45cf9cbdebd558a + Fixes compile error on Void Linux/Musl -commit 5f83342b61d1f76c141de608ed2bd293990416bd +commit d3aee17f6d395202eaa42a0c449b6da41f61527c Author: Darren Tucker -Date: Tue Jul 25 13:00:22 2023 +1000 +Date: Tue Sep 24 18:41:44 2024 +1000 - Handle a couple more OpenSSL no-ecc cases. - - ok djm@ + Test the flags from OpenWRT's package. -commit edc2ef4e418e514c99701451fae4428ec04ce538 -Author: Damien Miller -Date: Thu Jul 20 12:53:44 2023 +1000 +commit 0f5d19e6fe4b58a89e6dc8c71a2aae30365d193e +Author: Christoph Ostarek +Date: Wed Jul 3 12:46:59 2024 +0200 - depend + fix utmpx ifdef + + 02e16ad95fb1f56ab004b01a10aab89f7103c55d did a copy-paste for + utmpx, but forgot to change the ifdef appropriately -commit 51fda734e0d3c2df256fc03e8b060c4305be6e59 -Author: Damien Miller -Date: Thu Jul 20 12:53:21 2023 +1000 +commit e03239f999acf9dc3da0f2f72bde36abbe678911 +Author: jsg@openbsd.org +Date: Sun Sep 22 12:56:21 2024 +0000 - Bring back OPENSSL_HAS_ECC to ssh-pkcs11-client + upstream: remove some unused defines; ok djm@ + + OpenBSD-Commit-ID: 81869ee6356fdbff19dae6ff757095e6b24de712 -commit 099cdf59ce1e72f55d421c8445bf6321b3004755 -Author: djm@openbsd.org -Date: Wed Jul 19 14:03:45 2023 +0000 +commit a35f543d3a6275fef781e515c262d1c687c3bc28 +Author: jsg@openbsd.org +Date: Fri Sep 20 02:00:46 2024 +0000 - upstream: Separate ssh-pkcs11-helpers for each p11 module - - Make ssh-pkcs11-client start an independent helper for each provider, - providing better isolation between modules and reliability if a single - module misbehaves. - - This also implements reference counting of PKCS#11-hosted keys, - allowing ssh-pkcs11-helper subprocesses to be automatically reaped - when no remaining keys reference them. This fixes some bugs we have - that make PKCS11 keys unusable after they have been deleted, e.g. - https://bugzilla.mindrot.org/show_bug.cgi?id=3125 + upstream: remove unneeded semicolons; checked by millert@ - ok markus@ - - OpenBSD-Commit-ID: 0ce188b14fe271ab0568f4500070d96c5657244e + OpenBSD-Commit-ID: 3fb621a58e04b759a875ad6a33f35bb57ca80231 -commit 29ef8a04866ca14688d5b7fed7b8b9deab851f77 -Author: djm@openbsd.org -Date: Wed Jul 19 14:02:27 2023 +0000 +commit 1641f2d4d6e05d2147913442864cae546e64f08b +Author: Darren Tucker +Date: Mon Sep 23 20:52:31 2024 +1000 - upstream: Ensure FIDO/PKCS11 libraries contain expected symbols - - This checks via nlist(3) that candidate provider libraries contain one - of the symbols that we will require prior to dlopen(), which can cause - a number of side effects, including execution of constructors. - - Feedback deraadt; ok markus - - OpenBSD-Commit-ID: 1508a5fbd74e329e69a55b56c453c292029aefbe + Add 9.9 branch to CI status console. -commit 1f2731f5d7a8f8a8385c6031667ed29072c0d92a -Author: djm@openbsd.org -Date: Wed Jul 19 13:56:33 2023 +0000 +commit 46d1fb16b20e971b9ac15e86a3d3e350b49c9ad6 +Author: Damien Miller +Date: Fri Sep 20 08:20:13 2024 +1000 - upstream: Disallow remote addition of FIDO/PKCS11 provider - - libraries to ssh-agent by default. - - The old behaviour of allowing remote clients from loading providers - can be restored using `ssh-agent -O allow-remote-pkcs11`. - - Detection of local/remote clients requires a ssh(1) that supports - the `session-bind@openssh.com` extension. Forwarding access to a - ssh-agent socket using non-OpenSSH tools may circumvent this control. - - ok markus@ - - OpenBSD-Commit-ID: 4c2bdf79b214ae7e60cc8c39a45501344fa7bd7c + update version numbers -commit 892506b13654301f69f9545f48213fc210e5c5cc +commit 0bdca1f218971b38728a0a129f482476baff0968 Author: djm@openbsd.org -Date: Wed Jul 19 13:55:53 2023 +0000 +Date: Thu Sep 19 22:17:44 2024 +0000 - upstream: terminate process if requested to load a PKCS#11 provider - - that isn't a PKCS#11 provider; from / ok markus@ + upstream: openssh-9.9 - OpenBSD-Commit-ID: 39532cf18b115881bb4cfaee32084497aadfa05c + OpenBSD-Commit-ID: 303417285f1a73b9cb7a2ae78d3f493bbbe31f98 -commit f3f56df8ec476b2de6cbdbdfdb77a2a61087829d +commit ef2d7f2d3e1b4c9ae71bacf963e76a92ab8be543 Author: Damien Miller -Date: Wed Jul 19 12:07:18 2023 +1000 +Date: Wed Sep 18 16:03:23 2024 +1000 - agent_fuzz doesn't want stdint.h conditionalised + include openbsd-compat/base64.c license in LICENSE -commit 750911fd31d307a767cc86e3bfa90bbbb77b1a25 +commit 7ef362b989c8d1f7596f557f22e5924b9c08f0ea Author: Damien Miller -Date: Tue Jul 18 15:41:12 2023 +1000 +Date: Wed Sep 18 09:01:23 2024 +1000 - conditionalise stdint.h inclusion on HAVE_STDINT_H - - fixes build on AIX5 at least + conditionally include mman.h in arc4random code -commit ff047504fa6e008c4092f8929881816b8993bea0 +commit 5fb2b5ad0e748732a27fd8cc16a7ca3c21770806 Author: Damien Miller -Date: Tue Jul 18 15:30:45 2023 +1000 +Date: Tue Sep 17 11:53:24 2024 +1000 - conditionalise match localnetwork on ifaddrs.h + fix bug in recently-added sntrup761 fuzzer - Fixes build breakage on platforms that lack getifaddrs() + key values need to be static to persist across invocations; + spotted by the Qualys Security Advisory team. -commit b87b03282e466ca2927954ce93f5dbf0bfdc68f6 +commit 0ca128c9ee894f1b0067abd473bfb33171df67f8 Author: djm@openbsd.org -Date: Mon Jul 17 06:16:33 2023 +0000 - - upstream: missing match localnetwork negation check - - OpenBSD-Commit-ID: 9a08ed8dae27d3f38cf280f1b28d4e0ff41a737a - -commit 6d6e185ba29ef4274164b77eab4dc763907f8821 -Author: jmc@openbsd.org -Date: Mon Jul 17 05:41:53 2023 +0000 +Date: Mon Sep 16 05:37:05 2024 +0000 - upstream: - add -P to usage() - sync the arg name to -J in usage() + upstream: use 64 bit math to avoid signed underflow. upstream code - with that in ssh.1 - reformat usage() to match what "man ssh" does on 80width + relies on using -fwrapv to provide defined over/underflow behaviour, but we + use -ftrapv to catch integer errors and abort the program. ok dtucker@ - OpenBSD-Commit-ID: 5235dd7aa42e5bf90ae54579d519f92fc107036e + OpenBSD-Commit-ID: 8933369b33c17b5f02479503d0a92d87bc3a574b -commit f1a9898283a0638667b587ee4a950afd61ab51b0 +commit f82e5e22cad88c81d8a117de74241328c7b101c3 Author: jmc@openbsd.org -Date: Mon Jul 17 05:38:10 2023 +0000 +Date: Sun Sep 15 08:27:38 2024 +0000 - upstream: -P before -p in SYNOPSIS; + upstream: minor grammar/sort fixes for refuseconnection; ok djm - OpenBSD-Commit-ID: 535f5257c779e26c6a662a038d241b017f8cab7c + OpenBSD-Commit-ID: 1c81f37b138b8b66abba811fec836388a0f3e6da -commit eef4d7e873568e1c84c36bb4034e2c3378250a61 -Author: jsg@openbsd.org -Date: Mon Jul 17 05:36:14 2023 +0000 +commit 0c1165fc78e8fe69b5df71f81a8f944554a68b53 +Author: Damien Miller +Date: Sun Sep 15 13:30:13 2024 +1000 - upstream: configuation -> configuration - - OpenBSD-Commit-ID: 4776ced33b780f1db0b2902faec99312f26a726b + avoid gcc warning in fuzz test -commit dc1dbe94cf6532bd546a3373ad436404f8850e5f +commit ce171d0718104b643854b53443ff72f7283d33f2 Author: djm@openbsd.org -Date: Mon Jul 17 05:26:38 2023 +0000 +Date: Sun Sep 15 03:09:44 2024 +0000 - upstream: move other RCSIDs to before their respective license blocks - - too no code change + upstream: bad whitespace in config dump output - OpenBSD-Commit-ID: ef5bf46b57726e4260a63b032b0b5ac3b4fe9cd4 + OpenBSD-Commit-ID: d899c13b0e8061d209298eaf58fe53e3643e967c -commit ebe11044681caff78834ca6b78311ad19c1860b8 -Author: djm@openbsd.org -Date: Mon Jul 17 05:22:30 2023 +0000 +commit 671c440786a5a66216922f15d0007b60f1e6733f +Author: Damien Miller +Date: Sun Sep 15 12:53:59 2024 +1000 - upstream: Move RCSID to before license block and away from #includes, - - where it caused merge conflict in -portable for each commit :( + use construct_utmp to construct btmp records - OpenBSD-Commit-ID: 756ebac963df3245258b962e88150ebab9d5fc20 + Simpler and removes some code with the old-style BSD license. -commit 05c08e5f628de3ecf6f7ea20947735bcfa3201e0 +commit 930cb02b6113df72fbc732b9feb8e4f490952a81 Author: djm@openbsd.org -Date: Mon Jul 17 05:20:15 2023 +0000 +Date: Sun Sep 15 02:20:51 2024 +0000 - upstream: return SSH_ERR_KRL_BAD_MAGIC when a KRL doesn't contain a + upstream: update the Streamlined NTRU Prime code from the "ref" - valid magic number and not SSH_ERR_MESSAGE_INCOMPLETE; the former is needed - to fall back to text revocation lists in some cases; fixes t-cert-hostkey. + implementation in SUPERCOP 20201130 to the "compact" implementation in + SUPERCOP 20240808. The new version is substantially faster. Thanks to Daniel + J Bernstein for pointing out the new implementation (and of course for + writing it). - OpenBSD-Commit-ID: 5c670a6c0f027e99b7774ef29f18ba088549c7e1 + tested in snaps/ok deraadt@ + + OpenBSD-Commit-ID: bf1a77924c125ecdbf03e2f3df8ad13bd3dafdcb -commit c6fad2c3d19b74f0bd0af1ef040fc74f3a1d9ebb -Author: Damien Miller -Date: Mon Jul 17 14:56:14 2023 +1000 +commit 9306d6017e0ce5dea6824c29ca5ba5673c2923ad +Author: djm@openbsd.org +Date: Sun Sep 15 01:19:56 2024 +0000 - avoid AF_LINK on platforms that don't define it + upstream: document Match invalid-user + + OpenBSD-Commit-ID: 2c84a9b517283e9711e2812c1f268081dcb02081 -commit 919bc3d3b712c920de1ae6be5ac6561c98886d7e +commit 0118a4da21147a88a56dc8b90bbc2849fefd5c1e Author: djm@openbsd.org -Date: Mon Jul 17 04:08:31 2023 +0000 +Date: Sun Sep 15 01:18:26 2024 +0000 - upstream: Add support for configuration tags to ssh(1). + upstream: add a "Match invalid-user" predicate to sshd_config Match - This adds a ssh_config(5) "Tag" directive and corresponding - "Match tag" predicate that may be used to select blocks of - configuration similar to the pf.conf(5) keywords of the same - name. + options. - ok markus + This allows writing Match conditions that trigger for invalid username. + E.g. - OpenBSD-Commit-ID: dc08358e70e702b59ac3e591827e5a96141b06a3 - -commit 3071d85a47061c1bdaf11a0ac233b501ecba862c -Author: djm@openbsd.org -Date: Mon Jul 17 04:04:36 2023 +0000 - - upstream: add a "match localnetwork" predicate. + PerSourcePenalties refuseconnection:90s + Match invalid-user + RefuseConnection yes - This allows matching on the addresses of available network interfaces - and may be used to vary the effective client configuration based on - network location (e.g. to use a ProxyJump when not on a particular - network). + Will effectively penalise bots try to guess passwords for bogus accounts, + at the cost of implicitly revealing which accounts are invalid. - ok markus@ + feedback markus@ - OpenBSD-Commit-ID: cffb6ff9a3803abfc52b5cad0aa190c5e424c139 + OpenBSD-Commit-ID: 93d3a46ca04bbd9d84a94d1e1d9d3a21073fbb07 -commit beec17bb311365b75a0a5941418d4b96df7d7888 +commit 7875975136f275619427604900cb0ffd7020e845 Author: djm@openbsd.org -Date: Mon Jul 17 04:01:10 2023 +0000 +Date: Sun Sep 15 01:11:26 2024 +0000 - upstream: remove vestigal support for KRL signatures - - When the KRL format was originally defined, it included support for - signing of KRL objects. However, the code to sign KRLs and verify KRL - signatues was never completed in OpenSSH. + upstream: Add a "refuseconnection" penalty class to sshd_config - Now, some years later, we have SSHSIG support in ssh-keygen that is - more general, well tested and actually works. So this removes the - semi-finished KRL signing/verification support from OpenSSH and - refactors the remaining code to realise the benefit - primarily, we - no longer need to perform multiple parsing passes over KRL objects. + PerSourcePenalties - ok markus@ + This allows penalising connection sources that have had connections + dropped by the RefuseConnection option. ok markus@ - OpenBSD-Commit-ID: 517437bab3d8180f695c775410c052340e038804 + OpenBSD-Commit-ID: 3c8443c427470bb3eac1880aa075cb4864463cb6 -commit 449566f64c21b4578d5c0c431badd0328adc53ed +commit 8d21713b669b8516ca6d43424a356fccc37212bb Author: djm@openbsd.org -Date: Mon Jul 17 03:57:21 2023 +0000 +Date: Sun Sep 15 01:09:40 2024 +0000 - upstream: Support for KRL extensions. + upstream: Add a sshd_config "RefuseConnection" option - This defines wire formats for optional KRL extensions and implements - parsing of the new submessages. No actual extensions are supported at - this point. + If set, this will terminate the connection at the first authentication + request (this is the earliest we can evaluate sshd_config Match blocks) - ok markus + ok markus@ - OpenBSD-Commit-ID: ae2fcde9a22a9ba7f765bd4f36b3f5901d8c3fa7 + OpenBSD-Commit-ID: 43cc2533984074c44d0d2f92eb93f661e7a0b09c -commit 18ea857770e84825a3a6238bb37f54864487b59f -Author: dtucker@openbsd.org -Date: Fri Jul 14 07:44:21 2023 +0000 +commit acad117e66018fe1fa5caf41b36e6dfbd61f76a1 +Author: djm@openbsd.org +Date: Sun Sep 15 00:58:01 2024 +0000 - upstream: Include stdint.h for SIZE_MAX. Fixes OPENSSL=no build. + upstream: switch sshd_config Match processing to the argv tokeniser - OpenBSD-Commit-ID: e7c31034a5434f2ead3579b13a7892960651e6b0 - -commit 20b768fcd13effe0f2d3619661b6c8592c773553 -Author: Darren Tucker -Date: Fri Jul 14 17:07:32 2023 +1000 - - Fix typo in declaration of nmesg. - -commit 4b94d09542e36ebde2eb9ad89bc68431609932de -Author: Damien Miller -Date: Fri Jul 14 15:34:47 2023 +1000 - - portable-specific int overflow defence-in-depth + too; ok markus@ - These too are unreachable, but we want the code to be safe regardless of - context. Reported by Yair Mizrahi @ JFrog + OpenBSD-Commit-ID: b74b5b0385f2e0379670e2b869318a65b0bc3923 -commit 2ee48adb9fc8692e8d6ac679dcc9f35e89ad68f0 +commit baec3f7f4c60cd5aa1bb9adbeb6dfa4a172502a8 Author: djm@openbsd.org -Date: Fri Jul 14 05:31:44 2023 +0000 +Date: Sun Sep 15 00:57:36 2024 +0000 - upstream: add defence-in-depth checks for some unreachable integer + upstream: switch "Match" directive processing over to the argv - overflows reported by Yair Mizrahi @ JFrog; feedback/ok millert@ + string tokeniser, making it possible to use shell-like quoting in Match + directives, particularly "Match exec". ok markus@ - OpenBSD-Commit-ID: 52af085f4e7ef9f9d8423d8c1840a6a88bda90bd + OpenBSD-Commit-ID: 0877309650b76f624b2194c35dbacaf065e769a5 -commit 4b43bc358ae6f6b19a973679246dc5172f6ac41b +commit dd424d7c382c2074ab70f1b8ad4f169a10f60ee7 Author: djm@openbsd.org -Date: Mon Jul 10 04:51:26 2023 +0000 - - upstream: misplaced debug message - - OpenBSD-Commit-ID: d0f12af0a5067a756aa707bc39a83fa6f58bf7e5 - -commit 8c7203bcee4c4f98a22487b4631fe068b992099b -Author: Damien Miller -Date: Wed Jul 12 11:41:19 2023 +1000 +Date: Sun Sep 15 00:47:01 2024 +0000 - replace deprecate selinux matchpathcon function + upstream: include pathname in some of the ssh-keygen passphrase - This function is apparently deprecated. Documentation on what is the - supposed replacement is is non-existent, so this follows the approach - glibc used https://sourceware.org/git/?p=glibc.git;a=patch;h=f278835f59 + prompts. Helps the user know what's going on when ssh-keygen is invoked via + other tools. Requested in GHPR503 - ok dtucker@ + OpenBSD-Commit-ID: 613b0bb6cf845b7e787d69a5b314057ceda6a8b6 -commit 7e8800f5d701efffa39ccb63ca1e095ea777c31a -Author: dtucker@openbsd.org -Date: Thu Jul 6 22:17:59 2023 +0000 +commit 62bbf8f825cc390ecb0523752ddac1435006f206 +Author: djm@openbsd.org +Date: Sun Sep 15 00:41:18 2024 +0000 - upstream: minleft and maxsign are u_int so cast appropriately. Prompted + upstream: Do not apply authorized_keys options when signature - by github PR#410, ok deraadt. + verification fails. Prevents restrictive key options being incorrectly + applied to subsequent keys in authorized_keys. bz3733, ok markus@ - OpenBSD-Commit-ID: 0514cd51db3ec60239966622a0d3495b15406ddd + OpenBSD-Commit-ID: ba3776d9da4642443c19dbc015a1333622eb5a4e -commit 94842bfe9b09fc93189c6ed0dc9bbebc1d44a426 -Author: dlg@openbsd.org -Date: Tue Jul 4 03:59:21 2023 +0000 +commit 49f325fd47af4e53fcd7aafdbcc280e53f5aa5ce +Author: Wu Weixin +Date: Fri Aug 2 22:16:40 2024 +0800 - upstream: add support for unix domain sockets to ssh -W - - ok djm@ dtucker@ + Fix without_openssl always being set to 1 - OpenBSD-Commit-ID: 3e6d47567b895c7c28855c7bd614e106c987a6d8 + In Fedora systems, %{?rhel} is empty. In RHEL systems, %{?fedora} is + empty. Therefore, the original code always sets without_openssl to 1. -commit a95fc5eed09a0238fb127b6c50e8498432b79dae -Author: David Seifert -Date: Fri May 12 14:06:01 2023 +0200 +commit c21c3a2419bbc1c59cb1a16ea356e703e99a90d9 +Author: djm@openbsd.org +Date: Thu Sep 12 00:36:27 2024 +0000 - gss-serv.c: `MAXHOSTNAMELEN` -> `HOST_NAME_MAX` + upstream: Relax absolute path requirement back to what it was prior to + + OpenSSH 9.8, which incorrectly required that sshd was started with an + absolute path in inetd mode. bz3717, patch from Colin Wilson - `MAXHOSTNAMELEN` is not defined in POSIX, which breaks on musl: - https://pubs.opengroup.org/onlinepubs/9699919799/functions/gethostname.html + OpenBSD-Commit-ID: 25c57f22764897242d942853f8cccc5e991ea058 + +commit 1bc426f51b0a5cfdcfbd205218f0b6839ffe91e9 +Author: naddy@openbsd.org +Date: Mon Sep 9 14:41:21 2024 +0000 + + upstream: document the mlkem768x25519-sha256 key exchange algorithm - Bug: https://bugs.gentoo.org/834044 + OpenBSD-Commit-ID: fa18dccdd9753dd287e62ecab189b3de45672521 + +commit 0a2db61a5ffc64d2e2961c52964f933879952fc7 +Author: Darren Tucker +Date: Tue Sep 10 21:11:14 2024 +1000 + + Spell omnios test host correctly. + +commit 059ed698a47c9af541a49cf754fd09f984ac5a21 +Author: Darren Tucker +Date: Tue Sep 10 18:52:02 2024 +1000 -commit 8a6cd08850f576e7527c52a1b086cae82fab290e + Add omnios test target. + +commit f4ff91575a448b19176ceaa8fd6843a25f39d572 +Author: Darren Tucker +Date: Tue Sep 10 18:45:55 2024 +1000 + + Wrap stdint.h in ifdef. + +commit ff714f001d20a9c843ee1fd9d92a16d40567d264 Author: Darren Tucker -Date: Fri Jun 23 09:49:02 2023 +1000 +Date: Mon Sep 9 19:31:54 2024 +1000 + + Also test PAM on dfly64. + +commit 509b757c052ea969b3a41fc36818b44801caf1cf +Author: Damien Miller +Date: Mon Sep 9 21:50:14 2024 +1000 + + stubs for ML-KEM KEX functions + + used for C89 compilers + +commit 273581210c99ce7275b8efdefbb9f89e1c22e341 +Author: Damien Miller +Date: Mon Sep 9 17:30:38 2024 +1000 + + declare defeat trying to detect C89 compilers + + I can't find a reliable way to detect the features the ML-KEM code + requires in configure. Give up for now and use VLA support (that we + can detect) as a proxy for "old compiler" and turn off ML-KEM if + it isn't supported. + +commit e8a0f19b56dfa20f98ea9876d7171ec315fb338a +Author: Damien Miller +Date: Mon Sep 9 16:46:40 2024 +1000 - Update runner OS version for hardenedmalloc test. + fix previous; check for C99 compound literals - Hardenedmalloc dropped support for "legacy glibc" versions in their - 64dad0a69 so use a newer Ubuntu version for the runner for that test. + The previous commit was incorrect (or at least insufficient), the + ML-KEM code is actually using compound literals, so test for them. -commit cfca6f17e64baed6822bb927ed9f372ce64d9c5b +commit 7c07bec1446978bebe0780ed822c8fedfb377ae8 Author: Damien Miller -Date: Thu Jun 22 15:04:03 2023 +1000 +Date: Mon Sep 9 16:06:21 2024 +1000 + + test for compiler feature needed for ML-KEM + + The ML-KEM implementation we uses need the compiler to support + C99-style named struct initialisers (e.g foo = {.bar = 1}). We + still support (barely) building OpenSSH with older compilers, so + add a configure test for this. + +commit d469d5f348772058789d35332d1ccb0b109c28ef +Author: djm@openbsd.org +Date: Mon Sep 9 03:13:39 2024 +0000 + + upstream: test mlkem768x25519-sha256 + + OpenBSD-Regress-ID: 7baf6bc39ae55648db1a2bfdc55a624954847611 + +commit 62fb2b51bb7f6863c3ab697f397b2068da1c993f +Author: djm@openbsd.org +Date: Mon Sep 9 02:39:57 2024 +0000 - handle sysconf(SC_OPEN_MAX) returning > INT_MAX; + upstream: pull post-quantum ML-KEM/x25519 key exchange out from + + compile-time flag now than an IANA codepoint has been assigned for the + algorithm. + + Add mlkem768x25519-sha256 in 2nd KexAlgorithms preference slot. + + ok markus@ - bz3581; ok dtucker + OpenBSD-Commit-ID: 9f50a0fae7d7ae8b27fcca11f8dc6f979207451a -commit c1c2ca1365b3f7b626683690bd2c68265f6d8ffd +commit a8ad7a2952111c6ce32949a775df94286550af6b Author: djm@openbsd.org -Date: Wed Jun 21 05:10:26 2023 +0000 +Date: Fri Sep 6 02:30:44 2024 +0000 - upstream: better validate CASignatureAlgorithms in ssh_config and + upstream: make parsing user@host consistently look for the last '@' in + + the string rather than the first. This makes it possible to use usernames + that contain '@' characters. + MIME-Version: 1.0 + Content-Type: text/plain; charset=UTF-8 + Content-Transfer-Encoding: 8bit + + Prompted by Max Zettlmeißl; feedback/ok millert@ - sshd_config. + OpenBSD-Commit-ID: 0b16eec246cda15469ebdcf3b1e2479810e394c5 + +commit 13cc78d016b67a74a67f1c97c7c348084cd9212c +Author: djm@openbsd.org +Date: Wed Sep 4 05:33:34 2024 +0000 + + upstream: be more strict in parsing key type names. Only allow - Previously this directive would accept certificate algorithm names, but - these were unusable in practice as OpenSSH does not support CA chains. + shortnames (e.g "rsa") in user-interface code and require full SSH protocol + names (e.g. "ssh-rsa") everywhere else. - part of bz3577; ok dtucker@ + Prompted by bz3725; ok markus@ - OpenBSD-Commit-ID: a992d410c8a78ec982701bc3f91043dbdb359912 + OpenBSD-Commit-ID: b3d8de9dac37992eab78adbf84fab2fe0d84b187 -commit 4e73cd0f4ab3e5b576c56cac9732da62c8fc0565 +commit ef8472309a68e319018def6f8ea47aeb40d806f5 Author: djm@openbsd.org -Date: Wed Jun 21 05:08:32 2023 +0000 +Date: Wed Sep 4 05:11:33 2024 +0000 + + upstream: fix RCSID in output + + OpenBSD-Commit-ID: 889ae07f2d2193ddc4351711919134664951dd76 - upstream: make `ssh -Q CASignatureAlgorithms` only list signature +commit ba2ef20c75c5268d4d1257adfc2ac11c930d31e1 +Author: jmc@openbsd.org +Date: Tue Sep 3 06:17:48 2024 +0000 + + upstream: envrionment -> environment; - algorithms that are valid for CA signing. Previous behaviour was to list all - signing algorithms, including certificate algorithms (OpenSSH certificates do - not support CA chains). part of bz3577; ok dtucker@ + OpenBSD-Commit-ID: b719f39c20e8c671ec6135c832d6cc67a595af9c + +commit e66c0c5673a4304a3a9fbf8305c6a19f8653740f +Author: Damien Miller +Date: Wed Sep 4 15:35:29 2024 +1000 + + add basic fuzzers for our import of sntrup761 + +commit d19dea6330ecd4eb403fef2423bd7e127f4c9828 +Author: djm@openbsd.org +Date: Tue Sep 3 05:58:56 2024 +0000 + + upstream: regression test for Include variable expansion - OpenBSD-Commit-ID: 99c2b072dbac0f44fd1f2269e3ff6c1b5d7d3e59 + OpenBSD-Regress-ID: 35477da3ba1abd9ca64bc49080c50a9c1350c6ca -commit a69062f1695ac9c3c3dea29d3044c72aaa6af0ea +commit 8c4d6a628051e318bae2f283e8dc38b896400862 Author: djm@openbsd.org -Date: Wed Jun 21 05:06:04 2023 +0000 +Date: Tue Sep 3 05:29:55 2024 +0000 - upstream: handle rlimits > INT_MAX (rlim_t is u64); ok dtucker + upstream: allow the "Include" directive to expand the same set of + + %-tokens that "Match Exec" and environment variables. - bz3581 + ok dtucker@ + + OpenBSD-Commit-ID: 12ef521eaa966a9241e684258564f52f1f3c5d37 + +commit 51b82648b6827675fc0cde21175fd1ed8e89aab2 +Author: djm@openbsd.org +Date: Mon Sep 2 12:18:35 2024 +0000 + + upstream: missing ifdef - OpenBSD-Commit-ID: 31cf59c041becc0e5ccb0a77106f812c4cd1cd74 + OpenBSD-Commit-ID: 85f09da957dd39fd0abe08fe5ee19393f25c2021 -commit 8d33f2aa6bb895a7f85a47189913639086347b75 +commit f68312eb593943127b39ba79a4d7fa438c34c153 Author: djm@openbsd.org -Date: Tue Jun 20 23:59:33 2023 +0000 +Date: Mon Sep 2 12:13:56 2024 +0000 + + upstream: Add experimental support for hybrid post-quantum key exchange + + ML-KEM768 with ECDH/X25519 from the Internet-draft: + https://datatracker.ietf.org/doc/html/draft-kampanakis-curdle-ssh-pq-ke-03 + + This is based on previous patches from markus@ but adapted to use the + final FIPS203 standard ML-KEM using a formally-verified implementation + from libcrux. + + Note this key exchange method is still a draft and thus subject to + change. It is therefore disabled by default; set MLKEM=yes to build it. + We're making it available now to make it easy for other SSH + implementations to test against it. + + ok markus@ deraadt@ + + OpenBSD-Commit-ID: 02a8730a570b63fa8acd9913ec66353735dea42c + +commit 05f2b141cfcc60c7cdedf9450d2b9d390c19eaad +Author: Antonio Larrosa +Date: Fri Aug 23 12:21:06 2024 +0200 - upstream: prepare for support for connecting to unix domain sockets + Don't skip audit before exitting cleanup_exit - using ssh -W by explicitly decoding PORT_STREAMLOCAL (a negative number) from - the u32 that's passed over the multiplexing socket; previously code would - just cast, which is UB. + This fixes an issue where the SSH_CONNECTION_ABANDON event is not + audited because cleanup_exit overrides the regular _exit too soon and + as a result, failed auth attempts are not logged correctly. - OpenBSD-Commit-ID: e5ac5f40d354096c51e8c118a5c1b2d2b7a31384 + The problem was introduced in 81c1099d22b81ebfd20a334ce986c4f753b0db29 + where the code from upstream was merged before the audit_event call when + it should have been merged right before the _exit call in order to honor + the comment that just mentions an override of the exit value. -commit b4ac435b4e67f8eb5932d8f59eb5b3cf7dc38df0 +commit 16eaf9d401e70996f89f3f417738a8db421aa959 Author: djm@openbsd.org -Date: Tue Jun 20 00:05:09 2023 +0000 +Date: Wed Aug 28 12:08:26 2024 +0000 - upstream: reset comment=NULL for each key in do_fingerprint(); + upstream: fix test: -F is the argument to specify a non-default - fixes "no comment" not showing on when running `ssh-keygen -l` on multiple - keys where one has a comment and other following keys do not. Patch from - Markus Kuhn via GHPR407, bz3580 + ssh_config, not -f (this is sadly not a new bug) - OpenBSD-Commit-ID: 3cce84456fdcd67dc6b84e369f92c6686d111d9b + OpenBSD-Regress-ID: 45a7bda4cf33f2cea218507d8b6a55cddbcfb322 -commit b53a809a549dcd4fbde554c6aa283e597b15ea33 -Author: millert@openbsd.org -Date: Mon Jun 5 13:24:36 2023 +0000 +commit 10ccf611ab8ecba9ce6b0548c5ccd8c1220baf92 +Author: deraadt@openbsd.org +Date: Fri Aug 23 04:51:00 2024 +0000 - upstream: Store timeouts as int, not u_int as they are limited to + upstream: As defined in the RFC, the SSH protocol has negotiable - INT_MAX. Fixes sign compare warnings systems with 32-bit time_t due to type - promotion. OK djm@ + compression support (which is requested as the name "zlib"). Compression + starts very early in the session. Relative early in OpenSSH lifetime, privsep + was added to sshd, and this required a shared-memory hack so the two + processes could see what was going on in the dataflow. This shared-memory + hack was soon recognized as a tremendous complexity risk, because it put libz + (which very much trusts it's memory) in a dangerous place, and a new option + ("zlib@openssh.com") was added begins compression after authentication (aka + delayed-compression). That change also permitted removal of the + shared-memory hack. Despite removal from the server, the old "zlib" support + remained in the client, to allow negotiation with non-OpenSSH daemons which + lack the delayed-compression option. This commit deletes support for the + older "zlib" option in the client. It reduces our featureset in a small way, + and encourages other servers to move to a better design. The SSH protocol is + different enough that compressed-key-material attacks like BEAST are + unlikely, but who wants to take the chance? We encourage other ssh servers + who care about optional compression support to add delayed-zlib support. + (Some already do "zlib@openssh.com") ok djm markus - OpenBSD-Commit-ID: 48081e9ad35705c5f1705711704a4c2ff94e87b7 + OpenBSD-Commit-ID: 6df986f38e4ab389f795a6e39e7c6857a763ba72 -commit 2709809fd616a0991dc18e3a58dea10fb383c3f0 -Author: Philip Hands -Date: Wed May 24 19:41:14 2023 +0200 +commit aee54878255d71bf93aa6e91bbd4eb1825c0d1b9 +Author: djm@openbsd.org +Date: Thu Aug 22 23:11:30 2024 +0000 - fixup! if -s & -p specified, mention 'sftp -P' on + upstream: sntrup761x25519-sha512 now has an IANA codepoint assigned, so - success + we can make the algorithm available without the @openssh.com suffix too. ok + markus@ deraadt@ - SSH-Copy-ID-Upstream: 32686e7c65b4fa2846e474d3315102dfa0f043b0 + OpenBSD-Commit-ID: eeed8fcde688143a737729d3d56d20ab4353770f -commit 204e0bf05161b7641500d7ab266c21217412379f +commit a76a6b85108e3032c8175611ecc5746e7131f876 Author: Darren Tucker -Date: Tue Aug 3 21:25:48 2021 +1000 +Date: Thu Aug 22 20:36:12 2024 +1000 - Make ssh-copy-id(1) consistent with OpenSSH. + Move rekey test into valgrind-2. - This makes the ssh-copy-id man page more consistent with the rest of the - OpenSSH man pages: - - new sentence, new line - - no sentences >80 - - N.B. -> NB - - zap unused .Pp - - zap trailing whitespace + Now that the rekey test has been optimized it's fast enough to not be in + its own valgrind test, so move it into valgrind-2, which is currently + the quickest of the others, bringing all of them to roughly the same + runtime of ~1.1 hours. + +commit 7e75e3f57c41b9a6e6401e7674d7c2ff5c33975b +Author: dtucker@openbsd.org +Date: Thu Aug 22 10:21:02 2024 +0000 + + upstream: Use aes128-ctr for MAC tests since default has implicit MAC. - Report from Debian via mindrot bz#3331, diff from jmc at openbsd.org. + Also verify that the Cipher or MAC we intended to use is actually the one + selected during the test. - SSH-Copy-ID-Upstream: d8974cfb6242316460ed22a1ccc662800a50c5d3 + OpenBSD-Regress-ID: ff43fed30552afe23d1364526fe8cf88cbfafe1d -commit 9de79df66d1430d290fab670bb4b18612875e518 -Author: Philip Hands -Date: Wed May 24 11:45:43 2023 +0200 +commit ebc890b8b4ba08c84cd1066b7b94b2b11f6c4cb4 +Author: Damien Miller +Date: Thu Aug 22 09:45:49 2024 +1000 - if -s & -p specified, mention 'sftp -P' on success + fix incorrect default for PasswordAuthentication - This was inspired by this: - https://github.com/openssh/openssh-portable/pull/321 - but I thought that it was better to not do the sed patching. + merge botch spotted by gsgleason + +commit 15ace435ea1c2fab2a1cc7d9c3157fe20c776b80 +Author: dtucker@openbsd.org +Date: Wed Aug 21 10:33:27 2024 +0000 + + upstream: Some awks won't match on the \r so delete it instead. Fixes + + regress in portable on, eg Solaris. + + OpenBSD-Regress-ID: 44a96d6d2f8341d89b7d5fff777502b92ac9e9ba + +commit 51c96b6ed627779a04493a8fe25747996a37f3c2 +Author: dtucker@openbsd.org +Date: Wed Aug 21 07:06:27 2024 +0000 + + upstream: Import regenerated moduli. + + OpenBSD-Commit-ID: 5db7049ad5558dee5b2079d3422e8ddab187c1cc + +commit 25c52f37a82c4da48ec537de37d7c168982b8d6d +Author: dtucker@openbsd.org +Date: Wed Aug 21 06:59:08 2024 +0000 + + upstream: Use curve25519-sha256 kex where possible. + + Except where we're explicitly testing a different kex, use + curve25519-sha256 since it's faster than the default and supported even + when configured without OpenSSL. Add a check to ensure that the kex we + intended to test is the one we actually tested. Speeds test up by ~5%. + + OpenBSD-Regress-ID: 3b27fcc2ae953cb08fd82a0d3155c498b226d6e0 + +commit 3eb62b7ba49483c309b483eb9002a679014f3887 +Author: dtucker@openbsd.org +Date: Tue Aug 20 12:36:59 2024 +0000 + + upstream: Send only as much data as needed to trigger rekeying. Speeds + + up tests by about 10% in the common case, hopefully more when instrumented + with something like valgrind. + + OpenBSD-Regress-ID: 7bf9292b4803357efcf0baf7cfbdc8521f212da1 + +commit cbd3f034bbf7853618fac99d7d868a2250154ea7 +Author: Damien Miller +Date: Wed Aug 21 09:18:29 2024 +1000 + + simplify sshkey_prekey_alloc(); always use mmap + +commit 4442bbc2fc661277a6dabfedb756a7e15ee8b8b8 +Author: dtucker@openbsd.org +Date: Tue Aug 20 09:15:49 2024 +0000 + + upstream: Merge AEAD test into main test loop. + + Removes 3 duplicate tests and speeds overall test up by about 1%. + + OpenBSD-Regress-ID: 5e5c9ff3f7588091ed369e34ac28520490ad2619 + +commit 829976a63fd1efae3a4c3e7c16fded59d92edb67 +Author: dtucker@openbsd.org +Date: Tue Aug 20 09:02:45 2024 +0000 + + upstream: Set a default RekeyLimit of 256k. + + Used unless overridden by a command-line flag, which simplifies some of + the ssh command lines. + + OpenBSD-Regress-ID: e7cffa57027088e10336e412b34113969f88cb87 + +commit 57d02c9ea36aebad4e7146d46e041b6b2e582f7f +Author: dtucker@openbsd.org +Date: Tue Aug 20 07:52:43 2024 +0000 + + upstream: Add Compression=no to default ssh_config. + + All of the rekey tests use it (otherwise the encrypted byte counts would + not match) so this lets us simplify the command lines. + + OpenBSD-Regress-ID: dab7ce10f4cf6c68827eb8658141272aab3ea262 + +commit 7254eb26f7c0772c4b47c3b32f6d1b15855cdd8c +Author: dtucker@openbsd.org +Date: Tue Aug 20 07:41:35 2024 +0000 + + upstream: Remove duplicate curve25519-sha256 kex. + + curve25519-sha256@libssh.org is the pre-standardization name for the same + thing, so remove it as a duplicate. Speeds up test by a tiny amount. + + OpenBSD-Regress-ID: 5a5ee5fa1595a6e140b1cc16040bedf5996a5715 + +commit 749896b874928c2785256cae4d75161dc3bfcc7d +Author: dtucker@openbsd.org +Date: Tue Aug 20 07:27:25 2024 +0000 + + upstream: Unnest rekey param parsing test and use ssh not sshd. + + ssh uses the same parsing code, now has "-G" to dump its config and is + slightly faster to start up. This speeds up the test slightly (~5%) in the + common case but should help more during instrumented tests, eg under + valgrind, where startup costs are magnified. + + OpenBSD-Regress-ID: 07c3acaf4c728e641033071f4441afc88141b0d0 + +commit 2b1762115481ff2b7a60fd4db2ae69b725437462 +Author: djm@openbsd.org +Date: Tue Aug 20 11:10:04 2024 +0000 + + upstream: actually use the length parameter that was passed in rather + + than a constant (this makes no difference in practice because the length is + always the same); reported by martin AT nmkd.net + + OpenBSD-Commit-ID: 4aecce232c2fe9b16e9217ff6bcb3c848d853e7e + +commit d922762ca16a7381131b242f49d7376c41fabcb5 +Author: Damien Miller +Date: Tue Aug 20 13:55:30 2024 +1000 + + private key coredump protection for Linux/FreeBSD + + platforms not supporting coredump exclusion using mmap/madvise flags + fall back to plain old malloc(3). + +commit cc048ca536d6bed6f2285b07040b0d57cd559ba5 +Author: djm@openbsd.org +Date: Tue Aug 20 03:48:30 2024 +0000 + + upstream: place shielded keys (i.e. keys at rest in RAM) into memory + + allocated using mmap(3) with MAP_CONCEAL set. This prevents exposure of the + key material in coredumps, etc (this is in addition to other measures we take + in this area). + + ok deraadt@ + + OpenBSD-Commit-ID: cbbae59f337a00c9858d6358bc65f74e62261369 + +commit a0b35c791cad1f85481b23ba46373060292e1c80 +Author: djm@openbsd.org +Date: Sat Aug 17 08:35:04 2024 +0000 + + upstream: mention that ed25519 is the default key type generated and + + clarify that rsa-sha2-512 is the default signature scheme when RSA is in use. + Based on GHPR505 from SebastianRzk + + OpenBSD-Commit-ID: 1d90df71636a04601685d2a10a8233bcc8d4f4c5 + +commit 127a50f2c80572ed1a021feb11ecf941e92cbbef +Author: djm@openbsd.org +Date: Sat Aug 17 08:23:04 2024 +0000 + + upstream: fix minor memory leak in Subsystem option parsing; from + + Antonio Larrosa via GHPR515 + + OpenBSD-Commit-ID: fff3bbefd1b2c45c98cbe45c6b857b15d8a2d364 + +commit 171427261d2079941eb1041079dbae875da37cbc +Author: djm@openbsd.org +Date: Sat Aug 17 08:09:50 2024 +0000 + + upstream: fix swapping of source and destination addresses in some sshd + + log messages + + OpenBSD-Commit-ID: 24d4cbb86325275df1f037545aa3b91456e52d25 + +commit 2a50a8f1fa57857a5e124a2280bcf61cc63c77f7 +Author: Darren Tucker +Date: Sat Aug 17 11:10:19 2024 +1000 + + Add compat functions for EVP_Digest{Sign,Verify}. + + This should make LibreSSL 3.1.x through 3.3.x work again. Code from + tb@, ok djm@. Restore the test configs covering those. + +commit 1c3a7145260e03037cc18715b883880836fd122d +Author: Philip Hands +Date: Thu Aug 8 13:03:51 2024 +0200 + + make sure that usage & man page match + + SSH-Copy-ID-Upstream: da5b1abe55b72a16e0430e7598e1573da01779c0 + +commit cd0d681645b9adcf2467e7838bfd9d5142de4c4e +Author: Philip Hands +Date: Thu Aug 8 13:01:47 2024 +0200 + + update copyright notices + + Bump the year to 2024, but also reflect the fact that hands.com Ltd. has + been wound up in the UK, and its assets (including this copyright) have + now reverted to its owner, Philip Hands. + + SSH-Copy-ID-Upstream: 0e4c4d072747a6568b11a790c29dd1b4ce663d7f + +commit 7fc9ccdce18841ebd0a97e31e43258512ab32a32 +Author: Philip Hands +Date: Sun Aug 4 20:45:00 2024 +0200 + + restore optionality of -i's argument + + SSH-Copy-ID-Upstream: f70e3abb510e4eeb040b47894e41828246c1b720 + +commit c37aa7012b1a3c2c322fd19e71310aadc90fc674 +Author: Philip Hands +Date: Fri Aug 2 15:52:07 2024 +0200 + + avoid exploring .ssh/id*.pub subdirectories + + SSH-Copy-ID-Upstream: 0b9e08b7707ad16de3c8e6a0410d9f42fbd56997 + +commit 777dce9e2e0d12f7e81e162f77749f30899869fe +Author: Philip Hands +Date: Fri Aug 2 10:07:11 2024 +0200 + + ensure that we're always told the source of keys + + SSH-Copy-ID-Upstream: 1bee96f4793e8ec3fab9f9361204ae58f5cc7cae + +commit fb94fd2339848e40cad6c9bb42b822244cc1a7bc +Author: Philip Hands +Date: Wed Jul 31 23:19:51 2024 +0200 + + add $HOME to ERROR if one cannot write to ~/.ssh + + SSH-Copy-ID-Upstream: ebef3e9c06e0447bff06e9d84b33023cf592e0ba + +commit eb5aafa1ffaeee75799141ec5ded406a65ec7d18 +Author: Philip Hands +Date: Wed Jul 31 23:19:03 2024 +0200 + + assert that SCRATCH_DIR is a writable directory + + SSH-Copy-ID-Upstream: ecb2b9d10883b9a16df56c83896c9bb47a80cde2 + +commit abcc460a2af46f0d812f8433d97a8eae1d80724c +Author: Philip Hands +Date: Wed Jul 31 23:17:54 2024 +0200 + + quote to avoid potential for word splitting + + SSH-Copy-ID-Upstream: f379adbe06ac2ef1daf0f130752234c7f8b97e3c + +commit b3f91411fd1473605f74c40c1a91a024c7171e27 +Author: Philip Hands +Date: Wed Jul 31 23:15:11 2024 +0200 + + ensure ERROR output goes to STDERR + + SSH-Copy-ID-Upstream: ac394b05eead3b91feb7c2ae4129a3e9b892f1e2 + +commit 674b8f30f0dbacd787eb1e4e7e1ece34b5543d8f +Author: Philip Hands +Date: Thu Aug 1 14:03:06 2024 +0200 + + avoid extra space when no arg given to -i option + + SSH-Copy-ID-Upstream: feca9e67e6e37c5653445d1c733569d7abb1770e + +commit 0efa0e1c41427c0c6ba839a18c72c1afcd7b7cc0 +Author: Philip Hands +Date: Wed Jul 31 23:28:36 2024 +0200 + + put the -i before -[pP] (matching man pages) + + The man pages (ssh, sftp & ssh-copy-id) all list -i before the port + setting, so make the output match that order, which also seems more + natural with the port being next to the server. + + SSH-Copy-ID-Upstream: 34d5d614172c78f9a42249466c4b81975b8883a1 + +commit 87831345e9745f2d13bd7a4a7972809f6788f331 +Author: Shreyas Mahangade +Date: Mon Jul 29 15:26:05 2024 +0000 + + Minor space issue fixed + + SSH-Copy-ID-Upstream: 335e44d7be78b03962a54c3a5c99a2ff45294a54 + +commit 2f3010f4736b4b3f5c10a4be97a24e90ff04c5e7 +Author: Shreyas Mahangade +Date: Mon Jul 29 16:55:28 2024 +0530 + + Show identity file in 'ssh' command + + - Previously no identity file is shown in "ssh" command output on the line "Now try logging into the..." + - This commit makes sure whenever "ssh-copy-id" with "-i" is invoked, it also reflects in "ssh" command + + SSH-Copy-ID-Upstream: 58e022ec26cb2315eb3be581d01e0ba787082428 + +commit a13856374b894397a7682b32257ed0bf67cfede9 +Author: Damien Miller +Date: Fri Aug 16 08:30:20 2024 +1000 + + more OPENSSL_HAS_ECC + +commit 4da2a1a7f648979bea6eaf3b17f5f250faed4afc +Author: Damien Miller +Date: Thu Aug 15 23:35:54 2024 +1000 + + fix merge botch that broke !OPENSSL_HAS_ECC + +commit 2c53d2f32b8e3992b61682c909ae5bc5122b6e5d +Author: Damien Miller +Date: Thu Aug 15 15:09:45 2024 +1000 + + missed OPENSSL_HAS_ECC case + +commit 342dd7a219f39119b8b686b5aaa99c8e15ede368 +Author: Damien Miller +Date: Thu Aug 15 15:06:55 2024 +1000 + + retire testing aginst older LibreSSL versions + + libressl prior to 3.4.x lack support for the EVP_DigestSign and + EVP_DigestVerify APIs that we need now that sshkey is converted + to EVP_PKEY. + + If someone makes a good case for why we should support these versions + then we could bring back support with wrappers. + +commit a7c6ea8eebe0f179141ec5dbf0c9e5354417930f +Author: Damien Miller +Date: Thu Aug 15 12:44:17 2024 +1000 + + sync TEST_MALLOC_OPTIONS for OpenBSD + +commit 60c2cf22e8f64f35d8b1175e4671257313f2e4d3 +Author: Damien Miller +Date: Thu Aug 15 12:43:47 2024 +1000 + + remove gratuitious difference from OpenBSD + +commit 339c4fc60a6250429d41fa8713f783d82aad4551 +Author: djm@openbsd.org +Date: Thu Aug 15 00:52:23 2024 +0000 + + upstream: adapt to EVP_PKEY conversion + + OpenBSD-Regress-ID: 0e2d4efb0ed0e392e23cd8fda183fe56531ac446 + +commit 63a94f99b9d7c8a48182a40192e45879d1ba8791 +Author: djm@openbsd.org +Date: Fri Jul 19 04:33:36 2024 +0000 + + upstream: test transfers in mux proxy mode too + + OpenBSD-Regress-ID: 2edfc980628cfef3550649cab8d69fa23b5cd6c4 + +commit 7bdfc20516e288b58c8c847958059c7b141eeff9 +Author: djm@openbsd.org +Date: Thu Aug 15 00:51:51 2024 +0000 + + upstream: Convert RSA and ECDSA key to the libcrypto EVP_PKEY API. + + DSA remains unconverted as it will be removed within six months. + + Based on patches originally from Dmitry Belyavskiy, but significantly + reworked based on feedback from Bob Beck, Joel Sing and especially + Theo Buehler (apologies to anyone I've missed). + + ok tb@ + + OpenBSD-Commit-ID: d098744e89f1dc7e5952a6817bef234eced648b5 + +commit 0af06e2c5b898992a18c74333e75a0136506acc6 +Author: tobias@openbsd.org +Date: Wed Aug 14 15:42:18 2024 +0000 + + upstream: Reorder calloc arguments + + The first argument should be the amount, the second argument should be the + element size. Fixing this also silences some gcc compiler warnings for + portable. + + Spotted with Benny Baumann (BenBE at geshi dot org). + + ok djm@ + + OpenBSD-Commit-ID: 711ad6f7bd7fb48bf52208f2cf9f108cddb6d41a + +commit 56ce0aa3c6cf28d9fcbce3207457abeac91b5050 +Author: tobias@openbsd.org +Date: Wed Aug 14 15:40:30 2024 +0000 + + upstream: Extend sshbuf validation + + Multiple sshbuf structs can be linked through a parent/child relationship. + Make sure that a single sshbuf cannot be its own parent. If this would ever + happen, it would result in reference counting issues. + + This is a cheap way of testing this with very little overhead. It does not + detect A->B->A linkages though for performance reason and the fact that it + takes a programming error for this to occur anyway. + + Authored with Benny Baumann (BenBE at geshi dot org). + + ok djm@ + + OpenBSD-Commit-ID: fb3fa9ee2cad3c7e842ebadfd7f5db220c4aaf16 + +commit fc48ddf6998188517af42dce807e2088b6a0c0be +Author: tobias@openbsd.org +Date: Wed Aug 14 15:37:11 2024 +0000 + + upstream: Use freezero for better readability + + It has the same meaning as the current pair of calling explicit_bzero + and free. Spotted with Benny Baumann (BenBE at geshi dot org). + + ok djm@ + + OpenBSD-Commit-ID: 939fbe9ccf52d0d48c5fa53694d6f3bb9927970c + +commit 1ff6907ec26dac6ac59fe9fe232899a63b4c14d8 +Author: tobias@openbsd.org +Date: Wed Aug 14 15:35:23 2024 +0000 + + upstream: Fix typo in comment + + Spotted with Benny Baumann (BenBE at geshi dot org). + + ok djm@ + + OpenBSD-Commit-ID: 829160ac8ef3ad3409695ce3a3ade835061cae57 + +commit 487faaed8f3bb9ffb19e8f807a3da72895b16421 +Author: dlg@openbsd.org +Date: Wed Jul 31 12:00:18 2024 +0000 + + upstream: add a random amount of time (up to 4 seconds) to the + + grace login time. + + ok deraadt@ djm@ + + OpenBSD-Commit-ID: abd3c57aaa5861517529b322df79b6be35ee67f4 + +commit 2865f5b7520bed3e74fbbb5f8d7a44193d7a4314 +Author: naddy@openbsd.org +Date: Fri Jul 26 15:24:49 2024 +0000 + + upstream: document the reduced logingrace penalty + + OpenBSD-Commit-ID: 9b63e0e3599d524ddc10edc4f978081382c3548b + +commit 1ec0a64c5dc57b8a2053a93b5ef0d02ff8598e5c +Author: Darren Tucker +Date: Sun Jul 28 21:26:51 2024 +1000 + + Explicitly install libssl-devel cygwin. + + Should fix CI tests for cygwin default config. + +commit 0bf6e5bb750b66b25c20a1c5a471f91850de3748 +Author: djm@openbsd.org +Date: Thu Jul 25 23:44:01 2024 +0000 + + upstream: reduce logingrace penalty. + + A single forgotton login that times out should be below the penalty + threshold. + + ok deraadt/claudio + + OpenBSD-Commit-ID: cee1f7d17597c97bff8e5092af5d136fdb08f81d + +commit 29fb6f6d46b67770084b4f12bcf8a01bd535041b +Author: djm@openbsd.org +Date: Thu Jul 25 22:40:08 2024 +0000 + + upstream: Fix proxy multiplexing (-O proxy) bug + + If a mux started with ControlPersist then later has a forwarding added using + mux proxy connection and the forwarding was used, then when the mux proxy + session terminates, the mux master process will send a channel close to the + server with a bad channel ID and crash the connection. + + This was caused by my stupidly reusing c->remote_id for mux channel + associations when I should have just added another member to struct channel. + + ok markus@ + + OpenBSD-Commit-ID: c9f474e0124e3fe456c5e43749b97d75e65b82b2 + +commit 53d1d307438517805989c7d5616d752739a97e03 +Author: djm@openbsd.org +Date: Thu Jul 18 01:47:27 2024 +0000 + + upstream: mention mux proxy mode + + OpenBSD-Commit-ID: fd77a77779f06d316a314e4540dc57c93fc3369a + +commit a9b90859d252c2f5a24142f985d38610ac74685f +Author: jsg@openbsd.org +Date: Sun Jul 14 10:19:23 2024 +0000 + + upstream: fix double word; ok dtucker@ + + OpenBSD-Commit-ID: e6aff005914fa350b896d2be030be3d3b56ec0e8 + +commit b05fda224bbcd2f641254534ed2175c42487f3c8 +Author: Darren Tucker +Date: Thu Jul 25 17:59:35 2024 +1000 + + Check for SA_RESTART before using it. + + ok djm@ + +commit c276672fc0e99f0c4389988d54a84c203ce325b6 +Author: Yuichiro Naito +Date: Wed Sep 1 10:19:32 2021 +0900 + + Class-imposed login restrictions + + If the following functions are available, + add an additional check if users are allowed to login imposed by login class. + + * auth_hostok(3) + * auth_timeok(3) + + These functions are implemented on FreeBSD. + +commit 7717b9e9155209916cc6b4b4b54f4e8fa578e889 +Author: djm@openbsd.org +Date: Wed Jul 10 21:58:34 2024 +0000 + + upstream: correct keyword; from Yatao Su via GHPR509 + + OpenBSD-Commit-ID: 81c778c76dea7ef407603caa157eb0c381c52ad2 + +commit f2b78bb8f149d6b4d1f62c21aa1f06995dccf4ce +Author: djm@openbsd.org +Date: Mon Jul 8 03:04:34 2024 +0000 + + upstream: don't need return at end of void function + + OpenBSD-Commit-ID: 42d322d37f13aa075ae7b1ad9eef591e20b89717 + +commit a395d37a813c0177cb5bfc4bebf5a52badb73cf0 +Author: djm@openbsd.org +Date: Thu Jul 4 22:53:59 2024 +0000 + + upstream: fix grammar: "a pattern lists" -> "one or more pattern + + lists" + + OpenBSD-Commit-ID: f3c844763398faa9800687e8ff6621225498202a + +commit 8b664df75966e5aed8dabea00b8838303d3488b8 +Author: Darren Tucker +Date: Sun Jul 7 18:46:19 2024 +1000 + + Cast to sockaddr * in systemd interface. + + Fixes build with musl libx. bz#3707. + +commit 30c8c81da2169e78357d08dbb0ddd823b60e93bc +Author: Darren Tucker +Date: Thu Jul 4 20:12:26 2024 +1000 + + Add 9.8 branch to ci-status page. + +commit ee6b9e661633fcefd29dba0c811cecbc4d027f6f +Author: Samuel Thibault +Date: Tue Mar 26 22:15:08 2024 +0100 + + Fix detection of setres*id on GNU/Hurd + + Like Linux, proper _SOURCE macros need to be set to get declarations of + various standard functions, notably setres*id. Now that Debian is using + -Werror=implicit-function-declaration this is really required. While at + it, define other _SOURCE macros like on GNU/Linux, since GNU/Hurd uses + the same glibc. + +commit fa41f6592ff1b6ead4a652ac75af31eabb05b912 +Author: Damien Miller +Date: Mon Jul 1 14:33:26 2024 +1000 + + version numbers + +commit bfebb8a5130a792c5356bd06e1ddef72a0a0449f +Author: djm@openbsd.org +Date: Mon Jul 1 04:31:59 2024 +0000 + + upstream: openssh-9.8 + + OpenBSD-Commit-ID: 5f8b89e38a4c5f7c6d52ffa19f796d49f36fab19 + +commit 146c420d29d055cc75c8606327a1cf8439fe3a08 +Author: djm@openbsd.org +Date: Mon Jul 1 04:31:17 2024 +0000 + + upstream: when sending ObscureKeystrokeTiming chaff packets, we + + can't rely on channel_did_enqueue to tell that there is data to send. This + flag indicates that the channels code enqueued a packet on _this_ ppoll() + iteration, not that data was enqueued in _any_ ppoll() iteration in the + timeslice. ok markus@ + + OpenBSD-Commit-ID: 009b74fd2769b36b5284a0188ade182f00564136 + +commit 637e4dfea4ed81264e264b6200172ce319c64ead +Author: djm@openbsd.org +Date: Mon Jul 1 03:10:19 2024 +0000 + + upstream: use "lcd" to change directory before "lls" rather then "cd", + + since the directory we're trying to list is local. Spotted by Corinna + Vinschen + + OpenBSD-Regress-ID: 821feca4a4bebe491944e624c8f7f2990b891415 + +commit c8cfe258cee0b8466ea84597bf15e1fcff3bc328 +Author: djm@openbsd.org +Date: Thu Jun 27 23:01:15 2024 +0000 + + upstream: delete obsolete comment + + OpenBSD-Commit-ID: 5fb04f298ed155053f3fbfdf0c6fe7cdf84bbfa2 + +commit 94b9d37100f6fa536aaa1d1a0e4926fe44fbf04d +Author: djm@openbsd.org +Date: Thu Jun 27 22:36:44 2024 +0000 + + upstream: retire unused API + + OpenBSD-Commit-ID: 3e30d7b0615e2707f6bbe70f61b1c2f72f78161b + +commit 268c3a7f5783e731ed60f4e28da66ee3743581d3 +Author: jmc@openbsd.org +Date: Thu Jun 27 21:02:16 2024 +0000 + + upstream: ssl(8) no longer contains a HISTORY section; + + OpenBSD-Commit-ID: 83b7ff34433d79595e9c2a5d2a561a6660251245 + +commit 12b6cc09ce6c430681f03af2a8069e37a664690b +Author: djm@openbsd.org +Date: Wed Jun 26 23:47:46 2024 +0000 + + upstream: move child process waitpid() loop out of SIGCHLD handler; + + ok deraadt + + OpenBSD-Commit-ID: 65815a39564e431414aed7c5ace8076f4e9ca741 + +commit d6bcd13297c2ab8b528df5a6898f994734849031 +Author: deraadt@openbsd.org +Date: Wed Jun 26 23:16:52 2024 +0000 + + upstream: Instead of using possibly complex ssh_signal(), write all + + the parts of the grace_alarm_handler() using the exact things allowed by the + signal-safe rules. This is a good rule of thumb: Handlers should be written + to either set a global volatile sig_atomic_t inspected from outside, and/or + directly perform only safe operations listed in our sigaction(2) manual page. + ok djm markus + + OpenBSD-Commit-ID: 14168ae8368aab76e4ed79e17a667cb46f404ecd + +commit b8793e2b0851f7d71b97554fa5260b23796d6277 +Author: deraadt@openbsd.org +Date: Wed Jun 26 23:14:14 2024 +0000 + + upstream: save_errno wrappers inside two small signal handlers that + + perform system calls, for systems with libc that do perform libc sigtramps. + ok djm markus + + OpenBSD-Commit-ID: 7749b56419a7c9dcfe4c6c04811e429813346c62 + +commit f23e9332c4c8df37465c4a4f38275ea98980ed7e +Author: jmc@openbsd.org +Date: Mon Jun 24 06:59:39 2024 +0000 + + upstream: - uppercase start of sentence - correct sentence grammar + + ok djm + + OpenBSD-Commit-ID: 1ec4b0fdb633a43667f2c8fff1d600bd647dde25 + +commit 1839e3eb71a759aa795602c1e4196300f4ac2615 +Author: djm@openbsd.org +Date: Mon Jun 24 04:05:11 2024 +0000 + + upstream: mention SshdSessionPath option + + OpenBSD-Commit-ID: c29734d36c21003973b15c1c9965c35f36cef30c + +commit 603193e32aef5db7d60c58066d5de89806e79312 +Author: Darren Tucker +Date: Thu Jun 20 18:45:14 2024 +1000 + + Rerun upstream tests on .sh file changes too. + +commit dbbf9337c19381786a8e5a8a49152fe6b80c780d +Author: dtucker@openbsd.org +Date: Thu Jun 20 08:23:18 2024 +0000 + + upstream: Work around dbclient cipher/mac query bug. + + Unlike earlier versions, recent Dropbear (at least v2024.85) requires + a host arg when querying supported ciphers and macs via "-c/-m + help". Earlier versions accept but do not require it, so always + provide it. If these queries fail, skip the test with a warning. + + OpenBSD-Regress-ID: 98eb863a3f0363416922efb273885e6b3c7f68d4 + +commit 8de2c8cebc46bbdb94b7a2c120fcadfb66a3cccc +Author: dtucker@openbsd.org +Date: Thu Jun 20 08:18:34 2024 +0000 + + upstream: Remove dropbear key types not supported + + by current OpenSSH. Allows subsequent test runs to work if OpenSSH is + rebuilt w/out OpenSSL. + + OpenBSD-Regress-ID: e0129eb2b1d31771105903a8055216fbba20a770 + +commit e9b6471c59b21e5d9ef1b3832d4bf727338add85 +Author: djm@openbsd.org +Date: Thu Jun 20 00:18:05 2024 +0000 + + upstream: stricter check for overfull tables in penalty record path + + OpenBSD-Commit-ID: 7df01e648a0723418c554e64a9f2b6d38db060a6 + +commit d9336d344eb2a1e898c5e66147b3f108c7214694 +Author: djm@openbsd.org +Date: Wed Jun 19 23:24:47 2024 +0000 + + upstream: put back reaping of preauth child process when writes + + from the monitor fail. Not sure how this got lost in the avalanche of + patches. + + OpenBSD-Commit-ID: eb7eb36371e1ac01050b32b70fb2b3e5d98e72f5 + +commit 579d9adb70ec0206a788eb5c63804c31a67e9310 +Author: naddy@openbsd.org +Date: Mon Jun 17 13:50:18 2024 +0000 + + upstream: remove one more mention of DSA + + OpenBSD-Commit-ID: 8515f55a15f02836ba657df341415f63c60526ca + +commit 7089b5f8436ef0b8d3d3ad9ce01045fb9e7aab15 +Author: Darren Tucker +Date: Wed Jun 19 23:09:05 2024 +1000 + + Move -f to the place needed to restart sshd. + +commit d5f83cfd852b14a25f347f082ab539a9454702ad +Author: Darren Tucker +Date: Wed Jun 19 21:04:01 2024 +1000 + + Need to supply "-f" to restart sshd. + +commit fad34b4ca25c0ef31e5aa841d461b6f21da5b8c1 +Author: dtucker@openbsd.org +Date: Wed Jun 19 10:15:51 2024 +0000 + + upstream: Provide defaults for ciphers and macs + + if querying for them fails since on some versions of Dropbear (at least + v2024.85) "-m help" doesn't seem to work. Enable all supported pubkey + algorithms in the server. + + OpenBSD-Regress-ID: 4f95556a49ee9f621789f25217c367a33d2745ca + +commit 5521060e35ada9f957cecdddc06d0524e75409ef +Author: dtucker@openbsd.org +Date: Wed Jun 19 10:10:46 2024 +0000 + + upstream: Use ed25519 keys for kex tests + + since that's supported by OpenSSH even when built without OpenSSL. + Only test diffie-hellman kex if OpenSSH is compiled with support for it. + + OpenBSD-Regress-ID: a5d09ef9bbd171f9e4ec73ed0d9eeb49a8878e97 + +commit dbd3b833f6e3815e58f2dc6e14f61a51bcd4d6bd +Author: dtucker@openbsd.org +Date: Wed Jun 19 10:08:34 2024 +0000 + + upstream: Rework dropbear key setup + + to always generate ed25519 keys, other types only if OpenSSH has support + for the corresponding key type. + + OpenBSD-Regress-ID: 8f91f12604cddb9f8d93aa34f3f93a3f6074395d + +commit d6218504e11ae9148adf410fc69b0710a052be36 +Author: Darren Tucker +Date: Wed Jun 19 20:20:24 2024 +1000 + + Restart sshd after installing it for testing. + + When installing an sshd built without OpenSSL the mismatch between + the running sshd and newly installed sshd-session will cause the + remainder of the test to fail. + +commit 786a4465b6bb702daf4fb17b7c3bcb42b52f0b46 +Author: Darren Tucker +Date: Tue Jun 18 19:59:59 2024 +1000 + + Remove macos-11 runner. + + Github is retiring them soon. + +commit df1c72a55edbebac14363b57de66ac6a147ecc67 +Author: Damien Miller +Date: Wed Jun 19 09:34:34 2024 +1000 + + PAMServiceName may appear in a Match block + +commit de1c2e70e5a5dc3c8d2fe04b24cc93d8ef6930e7 +Author: dtucker@openbsd.org +Date: Tue Jun 18 08:11:48 2024 +0000 + + upstream: Re-enable ssh-dss tests + + ... if ssh is compiled with DSA support + + OpenBSD-Regress-ID: bbfaf8c17f2b50a2d46ac35cb97af99b990c990d + +commit dabc2c7cf3c141e8e5d5a1a60d6c1d2d2422cf43 +Author: anton@openbsd.org +Date: Tue Jun 18 06:14:27 2024 +0000 + + upstream: Stop using DSA in dropbear interop tests. + + OpenBSD-Regress-ID: abfd4457d99d8cc1417fd22ca2c570270f74c1cf + +commit 761438012710169445acc179e3870c53c862bda0 +Author: Damien Miller +Date: Tue Jun 18 12:29:45 2024 +1000 + + missed a bit of DSA in the fuzzer + +commit 3f9cc47da588e8de520720e59f98438043fdaf93 +Author: Damien Miller +Date: Tue Jun 18 09:35:53 2024 +1000 + + DSA support is disabled, so remove from fuzzers + +commit 00eb95957dea5484b2c7c043f7d2bbc87301bef2 +Author: djm@openbsd.org +Date: Mon Jun 17 08:30:29 2024 +0000 + + upstream: disable the DSA signature algorithm by default; ok + + markus@ + + (yes, I know this expands to "the Digitial Signature Algorithm + signature algorithm) + + OpenBSD-Commit-ID: 961ef594e46dd2dcade8dd5721fa565cee79ffed + +commit 5603befe11c9464ea26fe77cbacc95a7cc0b1ea7 +Author: djm@openbsd.org +Date: Mon Jun 17 08:28:31 2024 +0000 + + upstream: promote connection-closed messages from verbose to info + + log level; they could be the only record of the connection terminating if the + client doesn't send a SSH2_MSG_DISCONNECT message. ok dtucker@ + + OpenBSD-Commit-ID: 0c8bfaf5e9fdff945cee09ac21e641f6c5d65d3c + +commit b00331402fe5c60d577f3ffcc35e49286cdc6b47 +Author: Damien Miller +Date: Mon Jun 17 17:02:18 2024 +1000 + + propagate PAM crashes to PerSourcePenalties + + If the PAM subprocess crashes, exit with a crash status that will be + picked up by the sshd(8) listener process where it can be used by + PerSourcePenalties to block the client. This is similar handling to + the privsep preauth process. + +commit 1c207f456ace38987deda047758d13fbf857f948 +Author: Damien Miller +Date: Mon Jun 17 15:06:01 2024 +1000 + + minix doesn't have loopback, so skip penalty tests + + pointed out by dtucker@ + +commit 48443d202eaec52d4d39defdd709a4499a7140c6 +Author: djm@openbsd.org +Date: Sun Jun 16 11:54:49 2024 +0000 + + upstream: same treatment for this test + + OpenBSD-Regress-ID: d0cc9efca7833e673ea7b0cb3a679a3acee8d4c7 + +commit 45562a95ea11d328c22d97bf39401cd29684fb1f +Author: djm@openbsd.org +Date: Sun Jun 16 08:18:06 2024 +0000 + + upstream: penalty test is still a bit racy + + OpenBSD-Regress-ID: 90c9ac224db454637baf1ebee5857e007321e824 + +commit 8d0f7eb147ef72d18acb16c0b18672d44941a8ca +Author: djm@openbsd.org +Date: Sat Jun 15 03:59:10 2024 +0000 + + upstream: crank up penalty timeouts so this should work on even the + + slowest of test builders + + OpenBSD-Regress-ID: 70bda39c83e3fc9d0f3c1fad4542ed33e173d468 + +commit 93c75471a1202ab3e29db6938648d4e2602c0475 +Author: jmc@openbsd.org +Date: Fri Jun 14 05:20:34 2024 +0000 + + upstream: sort -q in the options list; + + OpenBSD-Commit-ID: 6839b38378f38f754de638a5e988c13b4164cc7c + +commit dd7807bbe80a93ffb4616f2bd5cf83ad5a5595fb +Author: djm@openbsd.org +Date: Fri Jun 14 05:01:22 2024 +0000 + + upstream: clarify KEXAlgorithms supported vs available. Inspired by + + bz3701 from Colin Watson. + + OpenBSD-Commit-ID: e698e69bea19bd52971d253f2b1094490c4701f7 + +commit d172ad56df85b68316dbadbedad16761a1265874 +Author: djm@openbsd.org +Date: Fri Jun 14 05:00:42 2024 +0000 + + upstream: ssh-keyscan -q man bits + + OpenBSD-Commit-ID: ba28d0e1ac609a4c99c453e57e86560c79079db1 + +commit 092e4ff9ccaacbe035f286feb1b56ed499604743 +Author: Damien Miller +Date: Fri Jun 14 14:46:35 2024 +1000 + + skip penalty-expire test in valgrind test env + +commit 2866ad08a9c50d7b67ce9424ca990532b806a21a +Author: djm@openbsd.org +Date: Fri Jun 14 04:43:11 2024 +0000 + + upstream: split the PerSourcePenalties test in two: one tests penalty + + enforcement but not penalty expiry, the other tests penalty expiry. + + This lets us disable the expiry testing in certain CI test environments. + + OpenBSD-Regress-ID: f56811064f3e3cb52ee73a206b8c2a06af1c8791 + +commit b2c64bc170d75823622a37cab3ca1804ca87ad16 +Author: Damien Miller +Date: Fri Jun 14 14:19:23 2024 +1000 + + add a sshd_config PamServiceName option + + Allows selecting which PAM service name to use when UsePAM is + enabled. Defaults to "sshd" unless overridden at compile time + by defining SSHD_PAM_SERVICE. + + bz2102, ok dtucker@ + +commit 9f032a4dd17bf0ae6066223d82aa5e784285d987 +Author: djm@openbsd.org +Date: Fri Jun 14 00:26:12 2024 +0000 + + upstream: don't redirect stderr for ssh-keyscan we expect to succeed + + OpenBSD-Regress-ID: 8878b8eb4e070ed2e343166d3eb86db4a08a216c + +commit 1e84d0cf40e94ae3a77d6a7ca8c036d8e3d55a40 +Author: djm@openbsd.org +Date: Fri Jun 14 00:25:25 2024 +0000 + + upstream: make host/banner comments go to stderr instead of stdout, + + so they are useful as comments without extra shell redirection and so they + don't clutter actual errors on stderr. + + Add a -q flag to shut them up. + + ok dtucker@ + + OpenBSD-Commit-ID: bec813de56a71adb5c1a76adcf49621130d24264 + +commit 3e806d011855d6bd648ec95b9df630ebbd11c3bf +Author: naddy@openbsd.org +Date: Thu Jun 13 15:06:33 2024 +0000 + + upstream: separate keywords with comma + + OpenBSD-Commit-ID: d65a99666202a8188c4991c18d14374a229f7be5 + +commit abfd1f7a3cbd0a92581a0febba254b2f6649c0d9 +Author: djm@openbsd.org +Date: Fri Jun 14 00:23:55 2024 +0000 + + upstream: specify an algorithm for ssh-keyscan, otherwise it will make + + multiple attempts simultaneously and confuse the test + + OpenBSD-Regress-ID: 6e910f3315c4345053db1bf5cbf61826b194d0b9 + +commit a8fbe2f7d0d96d299ee8e69769e3b51067978748 +Author: Damien Miller +Date: Thu Jun 13 16:41:29 2024 +1000 + + sshd: don't use argv[0] as PAM service name + + sshd would implicitly use argv[0] as the PAM service name to + allow people to select different PAM service names by making + differently-named copies/links to the sshd binary. + + Splitting sshd into sshd/sshd-session broke this, as the process + that starts PAM is always sshd-session and the user has no control + over this. + + Hardcode "sshd" as the default PAM service name unless/until we + figure out a better way. Should unbreak OSX integration tests. + +commit bf204bd05c3ae650f87e2b96527688579f59774c +Author: Damien Miller +Date: Thu Jun 13 15:00:28 2024 +1000 + + prepare for checking in autogenerated files + + We plan to check in automatically generated files (config.h.in, etc) on + release branches. These files are normally ignored by .gitignore, but + this shuffles the contents of this file to make it easy to un-ignore + them. + +commit 425f79a837489904c343b349ef00e09aeaa4e752 +Author: Damien Miller +Date: Thu Jun 13 14:41:33 2024 +1000 + + typo in comment + +commit afe10313c1fa8d478af399ee7d54c8f85503013b +Author: Damien Miller +Date: Thu Jun 13 14:35:25 2024 +1000 + + fix PTY allocation on Cygwin, broken by sshd split + + Cygwin doesn't support FD passing and so used to disable post-auth + privilege separation entirely because privsep requires PTY allocation + to happen in the privileged monitor process with the PTY file + descriptors being passed back to the unprivileged process. + + This brings back a minimal version of the previous special treatment + for Cygwin (and any other platform that sets DISABLE_FD_PASSING): + privilege separation remains enabled, but PTY allocation happens in + the post-auth user process rather than the monitor. + + This either requires PTY allocation to not need privilege to begin + with (this appears to be the case on Cygwin), or the post-auth + privsep process retain privilege (other platforms that set the + DISABLE_FD_PASSING option). + + Keeping privileges here is bad, but the non-Cygwin systems that set + DISABLE_FD_PASSING are so deeply legacy that this is likely to be the + least of their problems. + +commit f66d4df5749551380a8c4ae642347675a0b6a2e9 +Author: Damien Miller +Date: Thu Jun 13 11:33:09 2024 +1000 + + delay lookup of privsep user until config loaded + + sshd-session attempting to use options.kerberos_authentication to + decide whether it needed to lookup the privsep user before the + configuration was loaded. This caused it to get a placeholder value + that caused it always to try to lookup the privsep user, breaking at + least one test environment. + +commit f1c42858b94f5d9b58867b34dce3afb39c6b56a8 +Author: Damien Miller +Date: Thu Jun 13 11:16:57 2024 +1000 + + missing file for PerSourcePenalties regress test + +commit 4de80ff4e6fab5a6bb0028e7d57c6c23d1485adb +Author: djm@openbsd.org +Date: Wed Jun 12 22:36:00 2024 +0000 + + upstream: split PerSourcePenalties address tracking. Previously it + + used one shared table and overflow policy for IPv4 and IPv6 addresses, now it + will use separate tables and optionally different overflow policies. + + This prevents misbehaviour from IPv6 addresses (which are vastly easier + to obtain many of) from affecting IPv4 connections and may allow for + stricter overflow policies. + + ok deraadt@ + + OpenBSD-Commit-ID: 12637ed0aa4d5f1f3e702da42ea967cbd8bfdfd9 + +commit 06ab4c6931b0aaa4334db2faaa7e1069e76d0df6 +Author: jmc@openbsd.org +Date: Tue Jun 11 05:24:39 2024 +0000 + + upstream: do not mark up "(default: 20ms)"; + + OpenBSD-Commit-ID: 54151ecdecfa1b67dcdda4fd24826ef6e2148ad4 + +commit cfe243cd9fde148ed060637876e27bb55ac78be9 +Author: djm@openbsd.org +Date: Tue Jun 11 02:54:51 2024 +0000 + + upstream: reap preauth net child if it hangs up during privsep message + + send, not just message receive + + OpenBSD-Commit-ID: 02a093f4ab4f8f83f0cd1ea2bb35b9ca420448f0 + +commit b0a711c00b9c64afd1c9d6fb538275c6604a2676 +Author: djm@openbsd.org +Date: Tue Jun 11 01:58:27 2024 +0000 + + upstream: fix PIDFILE handling, broken for SUDO=doas in last commit + + here + + OpenBSD-Regress-ID: 96fec579af228f87a036e94801eb294af9074625 + +commit 90fb801e2d9241be50a2a7ff79428386442a041f +Author: djm@openbsd.org +Date: Tue Jun 11 02:00:30 2024 +0000 + + upstream: reap the pre-auth [net] child if it hangs up during privsep + + message sending, not just receiving + + OpenBSD-Commit-ID: f7341605bf08c4c15830910446e6775323f2f8cb + +commit ef878d58798f6688c7f4d4e417dc0c29023ea831 +Author: djm@openbsd.org +Date: Tue Jun 11 01:23:25 2024 +0000 + + upstream: a little more RB_TREE paranoia + + OpenBSD-Commit-ID: 8dc2fd21eebd8830c4a4d25461ac4fe228e11156 + +commit fc4e96b2174d6a894d2033421699d091679baced +Author: djm@openbsd.org +Date: Tue Jun 11 01:22:25 2024 +0000 + + upstream: fix off-by-one comparison for PerSourcePenalty + + OpenBSD-Commit-ID: af4f5d01c41ef870b23e55655bfbf73474a6c02b + +commit 82c836df4ff41145553cd7adb11c5b985aeaa06f +Author: djm@openbsd.org +Date: Tue Jun 11 01:21:41 2024 +0000 + + upstream: move tree init before possible early return + + OpenBSD-Commit-ID: 72e2c5b69f151c08a7c5bf5ad929b97a92c273df + +commit a2300f015cc4939c4d9c564b58b74e71202dc978 +Author: djm@openbsd.org +Date: Tue Jun 11 01:07:35 2024 +0000 + + upstream: update to mention that PerSourcePenalties default to + + being enabled and document the default values for each parameter. + + OpenBSD-Commit-ID: b981288bddfb097aad269f62df4081c688ce0034 + +commit 41987efd356d3fc30139aeab4b09374acf8f91a0 +Author: djm@openbsd.org +Date: Tue Jun 11 00:44:52 2024 +0000 + + upstream: reap the [net] child if it hangs up while writing privsep + + message payloads, not just the message header + + OpenBSD-Commit-ID: 24dbd400aa381ac96be7ed2dd49018487dfef6ce + +commit 6211aa085fa91155a24922e5329576ac9a8f3175 +Author: djm@openbsd.org +Date: Tue Jun 11 00:40:21 2024 +0000 + + upstream: log waitpid() status for abnormal exits + + OpenBSD-Commit-ID: b317930e06b51819c1a2bc6a4359764fecfb1c2d + +commit a59634c7adb9ae988748d99963dfafb3070d8d41 +Author: djm@openbsd.org +Date: Tue Jun 11 00:36:20 2024 +0000 + + upstream: correct error message + + OpenBSD-Commit-ID: 581f60f73099083392887206860229ab104620ed + +commit fa7d7a667f2ee031e72873e36de2d2a36bca973b +Author: deraadt@openbsd.org +Date: Fri Jun 7 13:23:30 2024 +0000 + + upstream: avoid shadowing issues which some compilers won't accept + + ok djm + + OpenBSD-Commit-ID: 1e89572397dda83433d58c4fa6333a08f51170d4 + +commit 3ad4cd9eeca5c9bc6706db44b6de88e2e4513fd6 +Author: jmc@openbsd.org +Date: Thu Jun 6 21:14:49 2024 +0000 + + upstream: escape the final dot at eol in "e.g." to avoid double + + spacing; + + OpenBSD-Commit-ID: 0a9fb10bc9f7d577afe2da3f498a08bc431115b9 + +commit 0e0c69761a4c33ccd4a256560f522784a753d1a8 +Author: djm@openbsd.org +Date: Thu Jun 6 20:25:48 2024 +0000 + + upstream: enable PerSourcePenalties by default. + + ok markus + + NB. if you run a sshd that accepts connections from behind large NAT + blocks, proxies or anything else that aggregates many possible users + behind few IP addresses, then this change may cause legitimate traffic + to be denied. + + Please read the PerSourcePenalties, PerSourcePenaltyExemptList and + PerSourceNetBlockSize options in sshd_config(5) for how to tune your + sshd(8) for your specific circumstances. + + OpenBSD-Commit-ID: 24a0e5c23d37e5a63e16d2c6da3920a51078f6ce + +commit bd1f74741daabeaf20939a85cd8cec08c76d0bec +Author: djm@openbsd.org +Date: Thu Jun 6 20:20:42 2024 +0000 + + upstream: mention that PerSourcePenalties don't affect concurrent + + in-progress connections. + + OpenBSD-Commit-ID: 20389da6264f2c97ac3463edfaa1182c212d420c + +commit 9774b938578327d88a651f4c63c504809717590a +Author: djm@openbsd.org +Date: Thu Jun 6 19:49:25 2024 +0000 + + upstream: regress test for PerSourcePenalties + + OpenBSD-Regress-ID: a1af13d411b25a727742644459d26480b9a1b0f1 + +commit b8ebd86cefe9812204a10c028dc90de29918667d +Author: djm@openbsd.org +Date: Thu Jun 6 19:48:40 2024 +0000 + + upstream: make sure logs are saved from sshd run via start_sshd + + OpenBSD-Regress-ID: de4ef0e32e3ab85ff3a6c36eb08d1909c0dd1b4a + +commit d7b2070bdaa4ebbfafb9975c1d5a62b73289d31f +Author: djm@openbsd.org +Date: Thu Jun 6 19:47:48 2024 +0000 + + upstream: simplify + + OpenBSD-Regress-ID: 50316e0d1ae0c0a057a45af042253e54ce23d11c + +commit e6ea3d224513b6bfb93818809d4c7397f5995ba2 +Author: djm@openbsd.org +Date: Thu Jun 6 18:48:13 2024 +0000 + + upstream: prepare for PerSourcePenalties being enabled by default + + in future + + OpenBSD-Regress-ID: 5236c6d1c823997aac5a35e2915da30f1903bec7 + +commit c0cb3b8c837761816a60a3cdb54062668df09652 +Author: djm@openbsd.org +Date: Thu Jun 6 19:50:01 2024 +0000 + + upstream: disable stderr redirection before closing fds + + OpenBSD-Commit-ID: d42cb895ee4542098050367fc35321c9303f003a + +commit 81c1099d22b81ebfd20a334ce986c4f753b0db29 +Author: djm@openbsd.org +Date: Thu Jun 6 17:15:25 2024 +0000 + + upstream: Add a facility to sshd(8) to penalise particular + + problematic client behaviours, controlled by two new sshd_config(5) options: + PerSourcePenalties and PerSourcePenaltyExemptList. + + When PerSourcePenalties are enabled, sshd(8) will monitor the exit + status of its child pre-auth session processes. Through the exit + status, it can observe situations where the session did not + authenticate as expected. These conditions include when the client + repeatedly attempted authentication unsucessfully (possibly indicating + an attack against one or more accounts, e.g. password guessing), or + when client behaviour caused sshd to crash (possibly indicating + attempts to exploit sshd). + + When such a condition is observed, sshd will record a penalty of some + duration (e.g. 30 seconds) against the client's address. If this time + is above a minimum threshold specified by the PerSourcePenalties, then + connections from the client address will be refused (along with any + others in the same PerSourceNetBlockSize CIDR range). + + Repeated offenses by the same client address will accrue greater + penalties, up to a configurable maximum. A PerSourcePenaltyExemptList + option allows certain address ranges to be exempt from all penalties. + + We hope these options will make it significantly more difficult for + attackers to find accounts with weak/guessable passwords or exploit + bugs in sshd(8) itself. + + PerSourcePenalties is off by default, but we expect to enable it + automatically in the near future. + + much feedback markus@ and others, ok markus@ + + OpenBSD-Commit-ID: 89ded70eccb2b4926ef0366a4d58a693de366cca + +commit 916b0b6174e203cf2c5ec9bcf409472eb7ffbf43 +Author: Damien Miller +Date: Fri Jun 7 03:31:02 2024 +1000 + + whitespace + +commit 49b55e44182b8294419aa580cbf043d5b9e3d953 +Author: deraadt@openbsd.org +Date: Tue Jun 4 15:14:45 2024 +0000 + + upstream: enable -fret-clean on amd64, for libc libcrypto ld.so + + kernel, and all the ssh tools. The dynamic objects are entirely ret-clean, + static binaries will contain a blend of cleaning and non-cleaning callers. + + OpenBSD-Commit-ID: 112aacedd3b61cc5c34b1fa6d9fb759214179172 + +commit cc80d51d034bcb24fd0f2564a4bdf1612000a2a2 +Author: Damien Miller +Date: Wed Jun 5 02:21:30 2024 +1000 + + remove PRIVSEP macros for osx + +commit 8785491123d4d722b310c20f383570be758f8263 +Author: djm@openbsd.org +Date: Sat Jun 1 07:03:37 2024 +0000 + + upstream: be really strict with fds reserved for communication with the + + separate sshd-session process - reserve them early and fatal if we can't + dup2(2) them later. The pre-split fallback to re-reading the configuration + files is not possible, so sshd-session absolutely requires the fd the + configuration is passed over to be in order. + + ok deraadt@ + + OpenBSD-Commit-ID: 308a98ef3c8a6665ebf92c7c9a0fc9600ccd7065 + +commit f1c8918cb98459910fb159373baea053ba4108c0 +Author: Damien Miller +Date: Fri May 31 19:12:26 2024 +1000 + + depend + +commit 94b4866cb1f4b0ed29a9f367047b30f81002316f +Author: Damien Miller +Date: Fri May 31 19:11:14 2024 +1000 + + rename need_privsep to need_chroot + + privsep is mandatory, chroot is optional (disabled when running + sshd as non-root) + +commit e68a95142e5024b144f8eeccd5ffdee42c34f44c +Author: Damien Miller +Date: Fri May 31 19:05:34 2024 +1000 + + remove remaining use_privsep mention + +commit b21d271f651d2536dca819cc6d74032fe98634db +Author: djm@openbsd.org +Date: Fri May 31 09:01:08 2024 +0000 + + upstream: warn when -r (deprecated option to disable re-exec) is + + passed + + OpenBSD-Commit-ID: 73145ef5150edbe3ce7889f0844ed8fa6155f551 + +commit a4b5bc246cbca476deeeb4462aa31746a56e3021 +Author: djm@openbsd.org +Date: Fri May 31 08:49:35 2024 +0000 + + upstream: typos + + OpenBSD-Commit-ID: edfa72eb06bfa65da30fabf7d2fe76d2d33f77bf + +commit 8054b906983ceaed01fabd8188d3dac24c05ba39 +Author: djm@openbsd.org +Date: Mon May 27 01:52:26 2024 +0000 + + upstream: don't need sys/queue.h here + + OpenBSD-Commit-ID: dd137396828171eb19e4911581812ca58de6c578 + +commit 210d4239733da6180ce853538aeb9413d5c62ad5 +Author: naddy@openbsd.org +Date: Sun May 26 20:35:12 2024 +0000 + + upstream: remove references to SSH1 and DSA server keys + + OpenBSD-Commit-ID: 57cc1c98d4f998981473734f144b904af7d178a2 + +commit f0b9261d7fdd0ef86806b49fe76344bd16770cd0 +Author: jsg@openbsd.org +Date: Thu May 23 23:47:16 2024 +0000 + + upstream: remove unused struct fwd_perm_list, no decl with complete + + type ok djm@ + + OpenBSD-Commit-ID: 416fb3970b7e73c76d2963c4f00cf96f2b2ee2fb + +commit 2477a98c3ef78e63b11a1393656e00288f52ae97 +Author: naddy@openbsd.org +Date: Wed May 22 15:24:55 2024 +0000 + + upstream: Do not pass -Werror twice when building with clang. + + OpenBSD-Commit-ID: 5f378c38ad8976d507786dc4db9283a879ec8cd0 + +commit 435844f5675245b4271f8581f15e6d1f34fde3bc +Author: miod@openbsd.org +Date: Wed May 22 11:49:36 2024 +0000 + + upstream: Do not pass -Werror if building with gcc 3, for asn1.h + + and bio.h cause (admittedly bogus) warnings with gcc 3. + + OpenBSD-Commit-ID: fb39324748824cb0387e9d67c41d1bef945c54ea + +commit fc5dc092830de23767c6ef67baa18310a64ee533 +Author: djm@openbsd.org +Date: Wed May 22 04:20:00 2024 +0000 + + upstream: this test has been broken since 2014, and has been + + testing the same key exchange algorithm repeatedly instead of testing all of + them. Spotted by nreilly AT blackberry.com in bz3692 + + Who broke the test? me. + + OpenBSD-Regress-ID: 48f4f5946276f975667141957d25441b3c9a50e2 + +commit fd4816791beaed2fdae7eea3e1494d1972b2a39d +Author: anton@openbsd.org +Date: Sun May 19 19:10:01 2024 +0000 + + upstream: Add missing kex-names.c source file required since the + + ssh split. + + OpenBSD-Regress-ID: ca666223f828fc4b069cb9016bff1eb50faf9fbb + +commit beccb7319c5449f6454889013403c336446d622e +Author: naddy@openbsd.org +Date: Fri May 17 14:42:00 2024 +0000 + + upstream: remove duplicate copy of relink kit for sshd-session + + OpenBSD-Commit-ID: 6d2ded4cd91d4d727c2b26e099b91ea935bed504 + +commit dcd79fa141311c287e0595ede684b7116122fae0 +Author: jsg@openbsd.org +Date: Fri May 17 06:42:04 2024 +0000 + + upstream: remove prototypes with no matching function; ok djm@ + + OpenBSD-Commit-ID: 6d9065dadea5f14a01bece0dbfe2fba1be31c693 + +commit 6454a05e7c6574d70adf17efe505a8581a86ca4f +Author: jsg@openbsd.org +Date: Fri May 17 06:38:00 2024 +0000 + + upstream: remove externs for removed vars; ok djm@ + + OpenBSD-Commit-ID: f51ea791d45c15d4927eb4ae7d877ccc1e5a2aab + +commit f3e4db4601ef7d2feb1d6f7447e432aaf353a616 +Author: deraadt@openbsd.org +Date: Fri May 17 06:11:17 2024 +0000 + + upstream: -Werror was turned on (probably just for development), + + and this is a simple way to satisfy older gcc. + + OpenBSD-Commit-ID: 7f698df54384b437ce33ab7405f0b86c87019e86 + +commit 24a1f3e5ad6f4a49377d4c74c36637e9a239efd0 +Author: Damien Miller +Date: Fri May 17 14:50:43 2024 +1000 + + attempt at updating RPM specs for sshd-session + +commit 17b566eeb7a0c6acc9c48b35c08885901186f861 +Author: djm@openbsd.org +Date: Fri May 17 04:42:13 2024 +0000 + + upstream: g/c unused variable + + OpenBSD-Commit-ID: aa6ef0778a1f1bde0d73efba72a777c48d2bd010 + +commit 01fb82eb2aa0a4eaf5c394ea8bb37ea4c26f8a3f +Author: jsg@openbsd.org +Date: Fri May 17 02:39:11 2024 +0000 + + upstream: spelling; ok djm@ + + OpenBSD-Commit-ID: bdea29bb3ed2a5a7782999c4c663b219d2270483 + +commit b88b690e99145a021fc1a1a116a11e0bce0594e7 +Author: djm@openbsd.org +Date: Fri May 17 01:45:22 2024 +0000 + + upstream: allow overriding the sshd-session binary path + + OpenBSD-Regress-ID: 5058cd1c4b6ca1a15474e33546142931d9f964da + +commit a68f80f2511f0e0c5cef737a8284cc2dfabad818 +Author: anton@openbsd.org +Date: Wed Apr 3 06:01:11 2024 +0000 + + upstream: Since ssh-agent(1) is only readable by root by now, use + + ssh(1) while generating data in tests. + + OpenBSD-Regress-ID: 24eb40de2e6b0ace185caaba35e2d470331ffe68 + +commit 92e55890314ce2b0be21a43ebcbc043b4abc232f +Author: djm@openbsd.org +Date: Fri May 17 01:17:40 2024 +0000 + + upstream: fix incorrect debug option name introduce in previous + + commit + + OpenBSD-Commit-ID: 66d69e22b1c072c694a7267c847f212284614ed3 + +commit 4ad72878af7b6ec28da6e230e36a91650ebe84c1 +Author: deraadt@openbsd.org +Date: Fri May 17 00:33:25 2024 +0000 + + upstream: construct and install a relink-kit for sshd-session ok + + djm + + OpenBSD-Commit-ID: 8b3820adb4da4e139c4b3cffbcc0bde9f08bf0c6 + +commit 02e679a2cb3f6df8e9dbb1519ed578226485157f +Author: Damien Miller +Date: Fri May 17 12:21:27 2024 +1000 + + Makefile support for sshd-session + +commit c0416035c5eaf70a8450d11c8833c5f7068ee7ad +Author: djm@openbsd.org +Date: Fri May 17 00:32:32 2024 +0000 + + upstream: missing files from previous + + OpenBSD-Commit-ID: 4b7be4434d8799f02365552b641a7a70a7ebeb2f + +commit 03e3de416ed7c34faeb692967737be4a7bbe2eb5 +Author: djm@openbsd.org +Date: Fri May 17 00:30:23 2024 +0000 + + upstream: Start the process of splitting sshd into separate + + binaries. This step splits sshd into a listener and a session binary. More + splits are planned. + + After this changes, the listener binary will validate the configuration, + load the hostkeys, listen on port 22 and manage MaxStartups only. All + session handling will be performed by a new sshd-session binary that the + listener fork+execs. + + This reduces the listener process to the minimum necessary and sets us + up for future work on the sshd-session binary. + + feedback/ok markus@ deraadt@ + + NB. if you're updating via source, please restart sshd after installing, + otherwise you run the risk of locking yourself out. + + OpenBSD-Commit-ID: 43c04a1ab96cdbdeb53d2df0125a6d42c5f19934 + +commit 1c0d81357921f8d3bab06841df649edac515ae5b +Author: djm@openbsd.org +Date: Thu May 9 09:46:47 2024 +0000 + + upstream: simplify exit message handling, which was more complicated + + than it needed to be because of unexpunged ssh1 remnants. ok markus@ + + OpenBSD-Commit-ID: 8b0cd2c0dee75fb053718f442aa89510b684610b + +commit cbbbf76aa6cd54fce32eacce1300e7abcf9461d4 +Author: tobias@openbsd.org +Date: Mon May 6 19:26:17 2024 +0000 + + upstream: remove SSH1 leftovers + + Authored with Space Meyer + + ok djm + + OpenBSD-Commit-ID: 81db602e4cb407baae472689db1c222ed7b2afa3 + +commit bc5dcb8ab9a4e8af54a724883732af378f42ea78 +Author: tobias@openbsd.org +Date: Tue Apr 30 15:40:43 2024 +0000 + + upstream: never close stdin + + The sanitise_stdfd call makes sure that standard file descriptors are + open (if they were closed, they are connected with /dev/null). + + Do not close stdin in any case to prevent error messages when stdin is + read multiple times and to prevent later usage of fd 0 for connections, + e.g. + + echo localhost | ssh-keyscan -f - -f - + + While at it, make stdin-related error messages nicer. + + Authored with Max Kunzelmann + + ok djm + + OpenBSD-Commit-ID: 48e9b7938e2fa2f9bd47e6de6df66a31e0b375d3 + +commit 6a42b70e56bef1aacdcdf06352396e837883e84f +Author: Damien Miller +Date: Wed May 8 09:43:59 2024 +1000 + + sync getrrsetbyname.c with recent upstream changes + +commit 385ecb31e147dfea59c1c488a1d2011d3867e60e +Author: djm@openbsd.org +Date: Tue Apr 30 06:23:51 2024 +0000 + + upstream: fix home-directory extension implementation, it always + + returned the current user's home directory contrary to the spec. + + Patch from Jakub Jelen via GHPR477 + + OpenBSD-Commit-ID: 5afd775eab7f9cbe222d7fbae4c793de6c3b3d28 + +commit 14e2b16bc67ffcc188906f65008667e22f73d103 +Author: djm@openbsd.org +Date: Tue Apr 30 06:16:55 2024 +0000 + + upstream: flush stdout after writing "sftp>" prompt when not using + + editline. + + From Alpine Linux via GHPR480 + + OpenBSD-Commit-ID: 80bdc7ffe0358dc090eb9b93e6dedb2b087b24cd + +commit 2e69a724051488e3fb3cd11531c4b5bc1764945b +Author: djm@openbsd.org +Date: Tue Apr 30 05:53:03 2024 +0000 + + upstream: stricter validation of messaging socket fd number; disallow + + usage of stderr. Based on GHPR492 by RealHurrison + + OpenBSD-Commit-ID: 73dbbe82ea16f73ce1d044d3232bc869ae2f2ce8 + +commit da757b022bf18c6f7d04e685a10cd96ed00f83da +Author: djm@openbsd.org +Date: Tue Apr 30 05:45:56 2024 +0000 + + upstream: add missing reserved fields to key constraint protocol + + documentation. + + from Wiktor Kwapisiewicz via GHPR487 + + OpenBSD-Commit-ID: 0dfb69998cfdb3fa00cbb0e7809e7d2f6126e3df + +commit 16d0b82fa08038f35f1b3630c70116979f49784f +Author: Damien Miller +Date: Tue Apr 30 12:39:34 2024 +1000 + + depend + +commit 66aaa678dbe59aa21d0d9d89a3596ecedde0254b +Author: djm@openbsd.org +Date: Tue Apr 30 02:14:10 2024 +0000 + + upstream: correctly restore sigprocmask around ppoll() reported + + by Tõivo Leedjärv; ok deraadt@ + + OpenBSD-Commit-ID: c0c0f89de5294a166578f071eade2501929c4686 + +commit 80fb0eb21551aed3aebb009ab20aeffeb01e44e0 +Author: djm@openbsd.org +Date: Tue Apr 30 02:10:49 2024 +0000 + + upstream: add explict check for server hostkey type against + + HostkeyAlgorithms. Allows HostkeyAlgorithms to disable implicit fallback from + certificate keys to plain keys. ok markus@ + + OpenBSD-Commit-ID: 364087e4a395ff9b2f42bf3aefdb2090bb23643a + +commit 5b28096d31ff7d80748fc845553a4aef5bb05d86 +Author: jsg@openbsd.org +Date: Tue Apr 23 13:34:50 2024 +0000 + + upstream: correct indentation; no functional change ok tb@ + + OpenBSD-Commit-ID: dd9702fd43de546bc6a3f4f025c74d6f3692a0d4 + +commit fd3cb8a82784e05f621dea5b56ac6f89bc53c067 +Author: semarie@openbsd.org +Date: Thu Apr 4 16:00:51 2024 +0000 + + upstream: set right mode on ssh-agent at boot-time + + which sthen@ + ok deraadt@ + + OpenBSD-Commit-ID: 662b5056a2c6171563e1626f9c69f27862b5e7af + +commit 54343a260e3aa4bceca1852dde31cd08e2abd82b +Author: deraadt@openbsd.org +Date: Tue Apr 2 12:22:38 2024 +0000 + + upstream: Oops, incorrect hex conversion spotted by claudio. + + While here try to improve how it reads a bit better. Surprising the + regression tests didn't spot this error, maybe it fails to roundtrip the + values. + + OpenBSD-Commit-ID: 866cfcc1955aef8f3fc32da0b70c353a1b859f2e + +commit ec78c31409590ad74efc194f886273ed080a545a +Author: deraadt@openbsd.org +Date: Tue Apr 2 10:02:08 2024 +0000 + + upstream: for parse_ipqos(), use strtonum() instead of mostly + + idiomatic strtoul(), but wow it's so gross. ok djm + + OpenBSD-Commit-ID: cec14a76af2eb7b225300c80fc0e21052be67b05 + +commit 8176e1a6c2e6da9361a7abb6fbf6c23c299f495b +Author: deraadt@openbsd.org +Date: Tue Apr 2 09:56:58 2024 +0000 + + upstream: can shortcut by returning strtonum() value directly; ok + + djm + + OpenBSD-Commit-ID: 7bb2dd3d6d1f288dac14247d1de446e3d7ba8b8e + +commit 9f543d7022a781f80bb696f9d73f1d1c6f9e31d6 +Author: deraadt@openbsd.org +Date: Tue Apr 2 09:52:14 2024 +0000 + + upstream: rewrite convtime() to use a isdigit-scanner and + + strtonum() instead of strange strtoul can might be fooled by garage + characters. passes regress/usr.bin/ssh/unittests/misc ok djm + + OpenBSD-Commit-ID: 4b1ef826bb16047aea3f3bdcb385b72ffd450abc + +commit 8673137f780d8d9e4cda3c4605cb5d88d5cea271 +Author: claudio@openbsd.org +Date: Tue Apr 2 09:48:24 2024 +0000 + + upstream: Remove unused ptr[3] char array in pkcs11_decode_hex. + + OK deraadt@ + + OpenBSD-Commit-ID: 3d14433e39fd558f662d3b0431c4c555ef920481 + +commit c7fec708f331f108343d69e4d74c9a5d86d6cfe7 +Author: deraadt@openbsd.org +Date: Tue Apr 2 09:32:28 2024 +0000 + + upstream: Replace non-idiomatic strtoul(, 16) to parse a region + + of 2-character hex sequences with a low-level replacement designed just for + the task. ok djm + + OpenBSD-Commit-ID: 67bab8b8a4329a19a0add5085eacd6f4cc215e85 + +commit 019a5f483b0f588da6270ec401d0b4bb35032f3f +Author: deraadt@openbsd.org +Date: Tue Apr 2 09:29:31 2024 +0000 + + upstream: Use strtonum() instead of severely non-idomatic + + strtoul() In particular this will now reject trailing garbage, ie. + '12garbage'. ok djm + + OpenBSD-Commit-ID: c82d95e3ccbfedfc91a8041c2f8bf0cf987d1501 + +commit 8231ca046fa39ea4eb99b79e0a6e09dec50ac952 +Author: deraadt@openbsd.org +Date: Mon Apr 1 15:50:17 2024 +0000 + + upstream: also create a relink kit for ssh-agent, since it is a + + long-running setgid program carrying keys with some (not very powerful) + communication channels. solution for testing the binary from dtucker. + agreement from djm. Will add it into /etc/rc in a few days. + + OpenBSD-Commit-ID: 2fe8d707ae35ba23c7916adcb818bb5b66837ba0 + +commit bf7bf50bd6a14e49c9c243cb8f4de31e555a5a2e +Author: deraadt@openbsd.org +Date: Mon Apr 1 15:48:16 2024 +0000 + + upstream: new-style relink kit for sshd. The old scheme created + + a Makefile by concatenating two Makefiles and was incredibly fragile. In the + new way a narrow-purposed install.sh script is created and shipped with the + objects. A recently commited /etc/rc script understands these files. + + OpenBSD-Commit-ID: ef9341d5a50f0d33e3a6fbe995e92964bc7ef2d3 + +commit 00e63688920905e326d8667cb47f17a156b6dc8f +Author: renmingshuai +Date: Fri Apr 12 10:20:49 2024 +0800 + + Shell syntax fix (leftover from a sync). + + Signed-off-by: renmingshuai + +commit 2eded551ba96e66bc3afbbcc883812c2eac02bd7 +Author: Darren Tucker +Date: Thu Apr 25 13:20:19 2024 +1000 + + Merge flags for OpenSSL 3.x versions. + + OpenSSL has moved to 3.4 which we don't currently accept. Based on + the OpenSSL versioning policy[0] it looks like all of the 3.x versions + should work with OpenSSH, so remove the distinction in configure and + accept all of them. + + [0] https://openssl.org/policies/general/versioning-policy.html + +commit 8673245918081c6d1dc7fb3733c8eb2c5a902c5e +Author: Darren Tucker +Date: Thu Apr 25 13:19:03 2024 +1000 + + Remove 9.6 branch from status page. + +commit 70d43049747fa3c66cf876d52271859407cec2fa +Author: Darren Tucker +Date: Thu Apr 25 13:16:58 2024 +1000 + + Update LibreSSL and OpenSSL versions tested. + + Update LibreSSL versions to current releases (3.8.4 & 3.9.1). + Add newly-released OpenSSL 3.3.0, and add tests against the 3.1 and + 3.3 branches. + +commit 88351eca17dcc55189991ba60e50819b6d4193c1 +Author: 90 +Date: Fri Apr 5 19:36:06 2024 +0100 + + Fix missing header for systemd notification + +commit 08f579231cd38a1c657aaa6ddeb8ab57a1fd4f5c +Author: Damien Miller +Date: Wed Apr 3 14:40:32 2024 +1100 + + notify systemd on listen and reload + + Standalone implementation that does not depend on libsystemd. + With assistance from Luca Boccassi, and feedback/testing from Colin + Watson. bz2641 + +commit 43e7c1c07cf6aae7f4394ca8ae91a3efc46514e2 +Author: Darren Tucker +Date: Sun Mar 31 21:51:57 2024 +1100 + + Port changes from selfhosted to upstream tests. + + Should get them working again. + +commit 281ea25a44bff53eefb4af7bab7aa670b1f8b6b2 +Author: Darren Tucker +Date: Sat Mar 30 18:20:16 2024 +1100 + + Check if OpenSSL implementation supports DSA. + + If --enable/disable-dsa-keys is not specified, set based on what OpenSSL + supports. If specified as enabled, but not supported by OpenSSL error + out. ok djm@ + +commit 2d2c068de8d696fe3246f390b146197f51ea1e83 +Author: djm@openbsd.org +Date: Sat Mar 30 05:56:22 2024 +0000 + + upstream: in OpenSSH private key format, correct type for subsequent + + private keys in blob. From Jakub Jelen via GHPR430 + + OpenBSD-Commit-ID: d17dbf47554de2d752061592f95b5d772baab50b + +commit c2c0bdd3e96b3ef66d77fccb85ff4962dc76caf0 +Author: Eero Häkkinen +Date: Sat Sep 16 00:55:08 2023 +0300 + + Expose SSH_AUTH_INFO_0 always to PAM auth modules. + + This changes SSH_AUTH_INFO_0 to be exposed to PAM auth modules also + when a password authentication method is in use and not only + when a keyboard-interactive authentication method is in use. + +commit 02c5ad23124ae801cf248d99ea5068fc4331ca01 +Author: Darren Tucker +Date: Wed Mar 27 17:42:58 2024 +1100 + + Rearrange selfhosted VM scheduling. + + Instead of trying to infer the type of the self hosted tests in each of + the driver scripts (inconsistently...), set one of the following + variables to "true" in the workflow: + + VM: tests run in a virtual machine. + EPHEMERAL: tests run on an ephemeral virtual machine. + PERSISTENT: tests run on a persistent virtual machine + REMOTE: tests run on a physical remote host. + + EPHEMERAL VMs can have multiple instances of any given VM can exist + simultaneously and are run by a runner pool. The other types have a + dedicated runner instance and can only run a single test at a time. + + Other settings: + SSHFS: We need to sshfs mount over the repo so the workflow can collect + build artifacts. This also implies the tests must be run over ssh. + DEBUG_ACTIONS: enable "set -x" in scripts for debugging. + +commit cd8a72707c02615365d0851ac51063ab6bfe258f +Author: Damien Miller +Date: Sat Mar 30 16:05:59 2024 +1100 + + add new token-based signing key for dtucker@ + + Verified in person and via signature with old key. + Will remove old key in a bit. + +commit 8d0e46c1ddb5b7f0992591b0dc5d8aaa77cc9dba +Author: Alkaid +Date: Tue Mar 12 03:59:12 2024 -0700 + + Fix OpenSSL ED25519 support detection + + Wrong function signature in configure.ac prevents openssh from enabling + the recently new support for ED25519 priv keys in PEM PKCS8 format. + +commit 697359be9c23ee43618243cdbcc9c7981e766752 +Author: djm@openbsd.org +Date: Sat Mar 30 04:27:44 2024 +0000 + + upstream: allow WAYLAND_DISPLAY to enable SSH_ASKPASS + + From dkg via GHPR479; ok dtucker@ + + OpenBSD-Commit-ID: 1ac1f9c45da44eabbae89375393c662349239257 + +commit 7844705b0364574cc70b941be72036c2c2966363 +Author: dtucker@openbsd.org +Date: Fri Mar 29 10:40:07 2024 +0000 + + upstream: Use egrep instead of grep -E. + + Some plaforms don't have the latter so this makes things easier + in -portable. + + OpenBSD-Regress-ID: ff82260eb0db1f11130200b25d820cf73753bbe3 + +commit 22b2b6c555334bffdf357a2e4aa74308b03b83c3 +Author: dtucker@openbsd.org +Date: Tue Mar 26 08:09:16 2024 +0000 + + upstream: test -h is the POSIXly way of testing for a symlink. Reduces + + diff vs Portable. + + OpenBSD-Regress-ID: 6f31cd6e231e3b8c5c2ca0307573ccb7484bff7d + +commit edcff77f82c2bb2b5653b36f1e47274c5ef3e8be +Author: Darren Tucker +Date: Tue Mar 26 18:58:58 2024 +1100 + + Fix name of OpenBSD upstream CI jobs. + +commit 861b084429940e024f1b6e9c2779eac95d7a45db +Author: Darren Tucker +Date: Tue Mar 26 18:55:33 2024 +1100 + + Resync with upstream: ${} around DATAFILE. + +commit 63f248c7693e7f0a3b9a13d2980ac9a7e37f2aea +Author: djm@openbsd.org +Date: Mon Mar 25 19:28:09 2024 +0000 + + upstream: optional debugging + + OpenBSD-Regress-ID: b4852bf97ac8fb2e3530f2d5f999edd66058d7bc + +commit 16e2ebe06a62f09d4877b769876d92d6008a896f +Author: dtucker@openbsd.org +Date: Mon Mar 25 06:05:42 2024 +0000 + + upstream: Verify string returned from local shell command. + + OpenBSD-Regress-ID: 5039bde24d33d809aebfa8d3ad7fe9053224e6f8 + +commit b326f7a1f39ff31324cc3fe2735178fb474c04a4 +Author: dtucker@openbsd.org +Date: Mon Mar 25 03:30:31 2024 +0000 + + upstream: Improve shell portability: grep -q is not portable so + + redirect stdout, and use printf instead of relying on echo to do \n + substitution. Reduces diff vs Portable. + + Also resync somewhat with upstream. + + OpenBSD-Regress-ID: 9ae876a8ec4c4725f1e9820a0667360ee2398337 + +commit dbf2e319f0c582613fa45a735ea3c242ce56946b +Author: dtucker@openbsd.org +Date: Mon Mar 25 02:07:08 2024 +0000 + + upstream: Save error code from SSH for use inside case statement, + + from portable. In some shells, "case" will reset the value of $?, so save it + first. + + OpenBSD-Regress-ID: da32e5be19299cb4f0f7de7f29c11257a62d6949 + +commit d2c8c4fa7def4fb057ed05b3db57b62c810a26f6 +Author: dtucker@openbsd.org +Date: Mon Mar 25 01:40:47 2024 +0000 + + upstream: Increase timeout. Resyncs with portable where some of + + the test VMs are slow enough for this to matter. + + OpenBSD-Regress-ID: 6a83a693602eb0312f06a4ad2cd6f40d99d24b26 + +commit 83621b63514a84791623db3efb59d38bc4bf9563 +Author: dtucker@openbsd.org +Date: Mon Mar 25 01:28:29 2024 +0000 + + upstream: In PuTTY interop test, don't assume the PuTTY major + + version is 0. Patch from cjwatson at debian.org via bz#3671. + + OpenBSD-Regress-ID: 835ed03c1b04ad46be82e674495521f11b840191 + +commit 8a421b927700f3834b4d985778e252b8e3299f83 +Author: Darren Tucker +Date: Tue Mar 26 18:38:14 2024 +1100 + + Really mkdir /usr/local/etc in CI tests. + +commit 2946ed522c47ce045314533d426b4e379f745e59 +Author: Darren Tucker +Date: Tue Mar 26 17:19:09 2024 +1100 + + Better short name for OpenBSD upstream CI jobs too. + +commit 18dbe8eff647aacb82d7e86b4ce63d5beee11f25 +Author: Darren Tucker +Date: Tue Mar 26 17:13:52 2024 +1100 + + Ensure /usr/local/etc exists before using in tests. + +commit 5fc1085128e3348bb1b5ee4d955cc767b019b3ad +Author: Darren Tucker +Date: Tue Mar 26 16:50:46 2024 +1100 + + Be more specific about when to rerun workflows. + +commit 5516923e8ae3da0823fea0d7d28aa813627142c0 +Author: Darren Tucker +Date: Tue Mar 26 16:35:27 2024 +1100 + + Add short names for test jobs on github CI. + +commit dc37d2d2470b4a9cedcee9ac926b7362214e3305 +Author: Darren Tucker +Date: Tue Mar 26 16:26:14 2024 +1100 + + If we're using xpg4's id, remember to pass args. + +commit fe169487937780392b23d3ff3c00e5898c10f784 +Author: dtucker@openbsd.org +Date: Tue Mar 26 01:23:11 2024 +0000 + + upstream: Import regenerated moduli. + + OpenBSD-Commit-ID: ad3d1486d105b008c93e952d158e5af4d9d4c531 + +commit 151146f03b490d19145cd421763aa7d42f5c50e2 +Author: job@openbsd.org +Date: Thu Mar 14 06:23:14 2024 +0000 + + upstream: Clarify how literal IPv6 addresses can be used in -J mode + + OK djm@ + + OpenBSD-Commit-ID: 524ddae97746b3563ad4a887dfd0a6e6ba114c50 + +commit 0d5bdc87a675271862b67eb6a9fb13a202fb4894 +Author: Darren Tucker +Date: Mon Mar 25 16:14:21 2024 +1100 + + Add Mac OS X 14 test targets. + +commit 2d7964a03e1f50a48040ec6912c0a956df909d21 +Author: Darren Tucker +Date: Mon Mar 25 14:05:40 2024 +1100 + + Move xpg4 'id' handling into test-exec.sh. + + Handle replacement of 'id' the same way as we do other Portable specific + replacements in test-exec.sh. This brings percent.sh back into sync + with upstream. + +commit 75d1d49ed10d978171cdafad28bdbffdbd48f41e +Author: Darren Tucker +Date: Mon Mar 25 10:38:03 2024 +1100 + + Update branches shown on ci-status to 9.7 and 9.6. + +commit f9193f03db0029fc9c31fbdb5c66a2737446bd8f +Author: Darren Tucker +Date: Mon Mar 25 09:28:02 2024 +1100 + + Improve detection of -fzero-call-used-regs=used. + + Should better detect problems with gcc 13 on m68k. bz#3673 from Colin + Watson via bz#3673 and https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110934 + + Signed-off-by: Darren Tucker + +commit 86bdd3853f4d32c85e295e6216a2fe0953ad93f0 +Author: Damien Miller +Date: Mon Mar 11 16:20:49 2024 +1100 + + version number in README + +commit 282721418e6465bc39ccfd39bb0133e670ee4423 +Author: Damien Miller +Date: Mon Mar 11 16:20:08 2024 +1100 + + crank RPM spec versions + +commit 3876a3bbd2ca84d23ba20f8b69ba83270c04ce3a +Author: djm@openbsd.org +Date: Mon Mar 11 04:59:47 2024 +0000 + + upstream: openssh-9.7 + + OpenBSD-Commit-ID: 618ececf58b8cdae016b149787af06240f7b0cbc + +commit 8fc109cc614954a8eb2738c48c0db36a62af9a06 +Author: Darren Tucker +Date: Mon Mar 11 12:59:26 2024 +1100 + + Test against current OpenSSL and LibreSSL releases. + + Add LibreSSL 3.9.0, bump older branches to their respective current + releases. + +commit 26b09b45fec7b88ba09042c09be4157e58e231e2 +Author: Damien Miller +Date: Sun Mar 10 16:24:57 2024 +1100 + + quote regexes used to test for algorithm support + + Fixes test failures on Solaris 8 reported by Tom G. Christensen + +commit a6a740a4948d10a622b505135bb485c10f21db5e +Author: djm@openbsd.org +Date: Sat Mar 9 05:12:13 2024 +0000 + + upstream: avoid logging in signal handler by converting mainloop to + + ppoll() bz3670, reported by Ben Hamilton; ok dtucker@ + + OpenBSD-Commit-ID: e58f18042b86425405ca09e6e9d7dfa1df9f5f7f + +commit cd82f7526e0481720567ae41db7849ab1c27e27b +Author: djm@openbsd.org +Date: Fri Mar 8 22:16:32 2024 +0000 + + upstream: skip more whitespace, fixes find-principals on + + allowed_signers files with blank lines; reported by Wiktor Kwapisiewicz + + OpenBSD-Commit-ID: b3a22a2afd753d70766f34bc7f309c03706b5298 + +commit 2f9d2af5cb19905d87f37d1e11c9f035ac5daf3b +Author: dtucker@openbsd.org +Date: Fri Mar 8 11:34:10 2024 +0000 + + upstream: Invoke ProxyCommand that uses stderr redirection via + + $TEST_SHELL. Fixes test when run by a user whose login shell is tcsh. + Found by vinschen at redhat.com. + + OpenBSD-Regress-ID: f68d79e7f00caa8d216ebe00ee5f0adbb944062a + +commit 9b3f0beb4007a7e01dfedabb429097fb593deae6 +Author: Darren Tucker +Date: Thu Mar 7 17:18:14 2024 +1100 + + Prefer openssl binary from --with-ssl-dir directory. + + Use openssl in the directory specified by --with-ssl-dir as long + as it's functional. Reported by The Doctor. + +commit c47e1c9c7911f38b2fc2fb01b1f6ae3a3121a838 +Author: djm@openbsd.org +Date: Wed Mar 6 02:59:59 2024 +0000 + + upstream: fix memory leak in mux proxy mode when requesting forwarding. + + found by RASU JSC, reported by Maks Mishin in GHPR#467 + + OpenBSD-Commit-ID: 97d96a166b1ad4b8d229864a553e3e56d3116860 + +commit 242742827fea4508e68097c128e802edc79addb5 +Author: djm@openbsd.org +Date: Wed Mar 6 00:31:04 2024 +0000 + + upstream: wrap a few PKCS#11-specific bits in ENABLE_PKCS11 + + OpenBSD-Commit-ID: 463e4a69eef3426a43a2b922c4e7b2011885d923 + +commit d52b6509210e2043f33e5a1de58dd4a0d5d48c2a +Author: Damien Miller +Date: Wed Mar 6 11:31:36 2024 +1100 + + disable RSA tests when algorithm is not supported + + Unbreaks "make test" when compiled --without-openssl. + + Similar treatment to how we do DSA and ECDSA. + +commit 668d270a6c77e8b5a1da26ecad2e6de9f62c8fe4 +Author: Damien Miller +Date: Wed Mar 6 10:33:20 2024 +1100 + + add a --without-retpoline configure option + + discussed with deraadt and dtucker a while ago + +commit 3deb501f86fc47e175ef6a3eaba9b9846a80d444 +Author: djm@openbsd.org +Date: Mon Mar 4 04:13:18 2024 +0000 + + upstream: fix leak of CanonicalizePermittedCNAMEs on error path; + + spotted by Coverity (CID 438039) + + OpenBSD-Commit-ID: 208839699939721f452a4418afc028a9f9d3d8af + +commit 65a44a8a4f7d902a64d4e60eda84384b2e2a24a2 +Author: djm@openbsd.org +Date: Mon Mar 4 02:16:11 2024 +0000 + + upstream: Separate parsing of string array options from applying them + + to the active configuration. This fixes the config parser from erroneously + rejecting cases like: + + AuthenticationMethods password + Match User ivy + AuthenticationMethods any - BTW the reason one can get away with using $SSH_OPTS throughout, despite - the lowercase -p in there, even if sftp is in use, is that the sftp call - is using the already-established ssh master connection, so the port was - passed to the earlier ssh. + bz3657 ok markus@ - SSH-Copy-ID-Upstream: 1c124d9bfafdbe28a00b683367ebf5750ce12eb2 + OpenBSD-Commit-ID: 7f196cba634c2a3dba115f3fac3c4635a2199491 -commit 801cda54c00e0f4e7d89345a90874c8d05dc233a -Author: Philip Hands -Date: Tue May 23 23:07:11 2023 +0200 +commit 6886e1b1f55c90942e4e6deed930f8ac32e0f938 +Author: Darren Tucker +Date: Thu Feb 22 17:59:35 2024 +1100 - drop whitespace - - SSH-Copy-ID-Upstream: e604fae1cdee35c18055d35dcec530cf12ef00ad + Add nbsd10 test target. -commit 288482f53613f3e74544eb92deeb24f7c7f1f371 -Author: Philip Hands -Date: Tue May 23 20:52:13 2023 +0200 +commit d86bf8a3f6ea4fa7887406c2aa9959db71fa41be +Author: Damien Miller +Date: Thu Feb 22 12:06:10 2024 +1100 - make -x also apply to the target script - - SSH-Copy-ID-Upstream: 3c4214704f427bd0654adf9b0fc079253db21cf4 + more descriptive configure test name -commit b79e7b88ed44f0e4339f0ff35c96c78a92175a8d -Author: Philip Hands -Date: Tue May 23 16:46:42 2023 +0200 +commit 9ee335aacc9f5bdc4cc2c19fafb45e27be7d234e +Author: djm@openbsd.org +Date: Wed Feb 21 06:17:29 2024 +0000 - add -t option to specify the target path + upstream: explain arguments of internal-sftp GHPR#454 from Niklas - Allow the default target path (.ssh/authorized_files) to be over-riden + Hambüchen + MIME-Version: 1.0 + Content-Type: text/plain; charset=UTF-8 + Content-Transfer-Encoding: 8bit - This was inspired by this MR from Panagiotis Cheilaris + OpenBSD-Commit-ID: 0335d641ae6b5b6201b9ffd5dd06345ebbd0a3f3 + +commit d1164cb1001dd208fee88aaa9b43d5e6fd917274 +Author: djm@openbsd.org +Date: Wed Feb 21 06:06:43 2024 +0000 + + upstream: clarify permissions requirements for ChrootDirectory Part - https://gitlab.com/phil_hands/ssh-copy-id/-/merge_requests/8 + of GHPR#454 from Niklas Hambüchen + MIME-Version: 1.0 + Content-Type: text/plain; charset=UTF-8 + Content-Transfer-Encoding: 8bit - SSH-Copy-ID-Upstream: a942a0e076874adb6d8b2f0fb76d6c7918190fcd + OpenBSD-Commit-ID: d37bc8786317a11649c62ff5e2936441186ef7a0 -commit 914f4ad138714c471ba72fb6d5496b6235320edd -Author: Carlos Rodríguez Gili -Date: Tue Apr 20 19:23:57 2021 +0200 +commit d410e17d186552d0717f18217d0d049486754365 +Author: djm@openbsd.org +Date: Wed Feb 21 06:05:06 2024 +0000 - Fix test error for /bin/sh on Solaris 10 and older - - On Solaris 10 and older targets /bin/sh is not POSIX-compliant. - Test -z `...` fails with error 'sh: test: argument expected'. - Using quotes around backticks fixes this and doesn't break - POSIX compatibility. + upstream: .Cm for a keyword. Part of GHPR#454 from Niklas Hambüchen - SSH-Copy-ID-Upstream: 98394072a3f985b2650c1e8eab2fef84e38cc065 + OpenBSD-Commit-ID: d59c52559f926fa82859035d79749fbb4a3ce18a -commit bd382dca316c721aed1e45edcf4c4e0f6374afb0 -Author: Jakub Jelen -Date: Tue Mar 2 21:34:05 2021 +0000 +commit ab73f9678ebf06b32d6361b88b50b42775e0565b +Author: djm@openbsd.org +Date: Wed Feb 21 06:01:13 2024 +0000 - Remove outdated comment + upstream: fix typo in match directive predicate (s/tagged/tag) GHPR#462 - The commit b068122 removed the code dropping the trailing colon, but the comment stayed leaving the code confusing for future readers + from Tobias Manske - SSH-Copy-ID-Upstream: 930d39f238117cd53810240ec989d0356aa1c1f6 + OpenBSD-Commit-ID: 05b23b772677d48aa82eefd7ebebd369ae758908 -commit bdcaf7939029433635d63aade8f9ac762aca2bbe -Author: Darren Tucker -Date: Wed May 10 18:50:46 2023 +1000 +commit 9844aa2521ccfb1a2d73745680327b79e0574445 +Author: djm@openbsd.org +Date: Wed Feb 21 05:57:34 2024 +0000 - Special case OpenWrt instead of Dropbear. + upstream: fix proxy multiplexing mode, broken when keystroke timing - OpenWrt overrides the location of authorized_keys for root. Currently we - assume that all Dropbear installations behave this way, which is not the - case. Check for OpenWrt and root user before using that location instead - of assuming that for all Dropbear servers. Prompted by Github PR#250. + obfuscation was added. GHPR#463 from montag451 - SSH-Copy-ID-Upstream: 0e1f5d443a9967483c33945793107ae3f3e4af2d + OpenBSD-Commit-ID: 4e412d59b3f557d431f1d81c715a3bc0491cc677 -commit cf84498f67abe93f813a296167b406a0db7b288e -Author: Philip Hands -Date: Thu May 18 18:20:55 2023 +0200 +commit ee6d932acb532f80b11bb7cf161668c70ec8a117 +Author: djm@openbsd.org +Date: Tue Feb 20 04:10:03 2024 +0000 - ssh-copy-id: add -x option (for debugging) + upstream: don't append a gratuitous space to the end of subsystem - This option causes the ssh-copy-id to run with set -x + arguments; bz3667 - SSH-Copy-ID-Upstream: a0ee367ea8c0a29c8b4515245e408d2d349e7844 + OpenBSD-Commit-ID: e11023aeb3f30b77a674e37b8292c862926d5dc6 -commit b4a1efdcb88f03394c08e7f68ed4e11676830002 -Author: Philip Hands -Date: Thu May 18 17:14:41 2023 +0200 +commit e27f032aa8fcbae9b2e7c451baaf4b8ac6fa3d45 +Author: dtucker@openbsd.org +Date: Mon Feb 19 09:25:52 2024 +0000 - update copyright notices + upstream: Always define puttysetup function. - SSH-Copy-ID-Upstream: c284ed33b361814ea48ff68cbd01ca525b2bf117 + OpenBSD-Regress-ID: b4c0ccfa4006a1bc5dfd99ccf21c854d3ce2aee0 -commit fcd78e31cdd45a7e69ccfe6d8a3b1037dc1de290 -Author: djm@openbsd.org -Date: Wed May 24 23:01:06 2023 +0000 +commit 84046f9991abef5f46b040b10cf3d494f933a17b +Author: dtucker@openbsd.org +Date: Fri Feb 9 08:56:59 2024 +0000 - upstream: fix AuthorizedPrincipalsCommand when AuthorizedKeysCommand + upstream: Exapnd PuTTY test coverage. - appears previously in configuration. Reported by John Meyers in bz3574 ok - dtucker@ + Expand the set of ciphers, MACs and KEX methods in the PuTTY interop + tests. - OpenBSD-Commit-ID: 1c92e4517284386703936e1d3abaa36cfacf1951 + OpenBSD-Regress-ID: dd28d97d48efe7329a396d0d505ee2907bf7fc57 -commit 5ec5504f1d328d5bfa64280cd617c3efec4f78f3 +commit bbf541ee2afe07b08a8b56fa0dc6f38fcfceef2a Author: dtucker@openbsd.org -Date: Wed May 10 10:04:20 2023 +0000 +Date: Fri Feb 9 08:47:42 2024 +0000 - upstream: Remove unused prototypes for ssh1 RSA functions. + upstream: Factor out PuTTY setup. + + Factor out PuTTY and call only when needed. - From lengyijun via github PR#396. + This allows us to avoid PuTTY key setup when it's not needed, which + speeds up the overall test run by a couple of percent. - OpenBSD-Commit-ID: 379a5afa8b7a0f3cba0c8a9bcceb4e5e33a5c1ef + OpenBSD-Regress-ID: c25eaccc3c91bc874400f7c85ce40e9032358c1c -commit fbf362b3891ae4b36052d1b39f37fc618b41c476 -Author: Darren Tucker -Date: Tue May 9 19:26:56 2023 +1000 +commit d31c21c57fb4245271680a1e5043cf6470a96766 +Author: naddy@openbsd.org +Date: Sat Feb 10 11:28:52 2024 +0000 - main(void) to prevent unused variable warning. + upstream: clean sshd random relinking kit; ok miod@ + + OpenBSD-Commit-ID: 509bb19bb9762a4b3b589af98bac2e730541b6d4 -commit baf854c8bb0a6d0af5c696c801e631a48dabbaba -Author: Darren Tucker -Date: Tue May 9 19:25:45 2023 +1000 +commit 4dbc5a363ff53a2fcecf6bc3bcc038badc12f118 +Author: djm@openbsd.org +Date: Fri Feb 2 00:13:34 2024 +0000 - Remove warning pragma since clang doesn't like it. + upstream: whitespace + + OpenBSD-Commit-ID: b24680bc755b621ea801ff8edf6f0f02b68edae1 -commit 5fbb7a1349fbbb48ccb1b8cafff2c1854370d87d +commit efde85dda2130272af24cc346f6c3cd326182ff1 Author: Darren Tucker -Date: Tue May 9 17:13:33 2023 +1000 +Date: Mon Feb 19 17:29:31 2024 +1100 - Suppress warning for snprintf truncation test. + Improve error message for OpenSSL header check. + + bz#3668, ok djm@ -commit 47742c513e4e045ecc985c6483fc5c8b050acda2 +commit cbbdf868bce431a59e2fa36ca244d5739429408d Author: Darren Tucker -Date: Tue May 9 17:12:50 2023 +1000 +Date: Wed Feb 7 13:45:02 2024 +1100 - Update OpenSSL compat test for 3.x. + Interop test against PuTTY snapshot and releases. -commit 86ad25d455a2313126125540e61e0f9314283f88 +commit 91898bf786b0f149f962c4c96c08a46f29888c10 Author: Darren Tucker -Date: Mon May 8 20:23:08 2023 +1000 +Date: Tue Feb 6 16:21:05 2024 +1100 - Add macos13 PAM test target. + Put privsep dir on OS X on /usr/local. + + On some runners we can't create /var/empty, so put it some place we can + write. Should fix test breakage on Max OS X 11. -commit 77cca2c4b13bc6e5f389565583b6202b0d1bccc2 +commit be5ed8ebed8388c5056bfde4688308cc873c18b9 Author: Darren Tucker -Date: Mon May 8 20:14:46 2023 +1000 +Date: Tue Feb 6 11:19:42 2024 +1100 - Skip agent-peereid test on macos13. + Add --disable-fd-passing option. - sudo -S nobody doesn't work on the github runners (probably a - permission issue) so skip that test. + .. and enable for the minix3 test VM. This will cause it to more reliably + skip tests that need FD passing and should fix the current test breakage. -commit b356b8e91678ea295bcf44df5248c3fbf499fdcf +commit 0f6a8a0d0a518fd78c4cbebfdac990a57a1c4e41 Author: Darren Tucker -Date: Mon May 8 20:14:28 2023 +1000 +Date: Tue Feb 6 11:18:44 2024 +1100 - Include config.guess in debug output. + Use "skip" function instead doing it ourselves. -commit b7afd8a4ecaca8afd3179b55e9db79c0ff210237 -Author: Darren Tucker -Date: Mon May 8 20:12:59 2023 +1000 +commit 3ad669f81aabbd2ba9fbd472903f680f598e1e99 +Author: Damien Miller +Date: Thu Feb 1 14:01:18 2024 +1100 - Handle OpenSSL >=3 ABI compatibility. - - Beyond OpenSSL 3.0, the ABI compatibility guarantees are wider (only - major must match instead of major and minor in earlier versions). - bz#3548, ok djm@ + ignore some vim droppings -commit 0e9e2663eb2c6e9c3e10d15d70418312ae67e542 -Author: dtucker@openbsd.org -Date: Mon May 1 08:57:29 2023 +0000 +commit c283f29d23611a06bbee06bcf458f2fffad721d9 +Author: djm@openbsd.org +Date: Thu Feb 1 02:37:33 2024 +0000 - upstream: Import regenerated moduli. + upstream: whitespace - OpenBSD-Commit-ID: 3d5f811cfcaed8cc4a97e1db49ac61bdf118113c + OpenBSD-Commit-ID: bf9e4a1049562ee4322684fbdce07142f04fdbb7 -commit d9687f49682e1e93383fc15ab2018850b2ef38c3 -Author: Darren Tucker -Date: Mon May 1 11:45:14 2023 +1000 +commit 0d96b1506b2f4757fefa5d1f884d49e96a6fd4c3 +Author: Damien Miller +Date: Tue Jan 16 14:40:18 2024 +1100 - Add macos-13 test target. + skip tests that use multiplexing on Windows - Also flatten OS list for clarity. + Some tests here use multiplexing, skip these if DISABLE_FD_PASSING + is set. Should unbreak tests on Windows. -commit aacfd6767497b8fa6d41ecdd3f8e265d1e9ef1f6 +commit 50080fa42f5f744b798ee29400c0710f1b59f50e Author: djm@openbsd.org -Date: Sun Apr 30 22:54:22 2023 +0000 +Date: Thu Jan 11 04:50:28 2024 +0000 - upstream: adjust ftruncate() logic to handle servers that reorder - - requests. - - sftp/scp will ftruncate the destination file after a transfer completes, - to deal with the case where a longer destination file already existed. - We tracked the highest contiguous block transferred to deal with this - case, but our naive tracking doesn't deal with servers that reorder - requests - a misfeature strictly permitted by the protocol but seldom - implemented. - - Adjust the logic to ftruncate() at the highest absolute block received - when the transfer is successful. feedback deraadt@ ok markus@ + upstream: don't disable RSA test when DSA is disabled; bug introduced - prompted by https://github.com/openssh/openssh-portable/commit/9b733#commitcomment-110679778 + in last commit - OpenBSD-Commit-ID: 4af7fac75958ad8507b4fea58706f3ff0cfddb1b + OpenBSD-Regress-ID: 8780a7250bf742b33010e9336359a1c516f2d7b5 -commit c8eb3941758615c8284a48fff47872db926da63c +commit 415c94ce17288e0cdcb9e58cc91fba78d33c8457 Author: djm@openbsd.org -Date: Wed Apr 26 01:36:03 2023 +0000 +Date: Thu Jan 11 01:45:58 2024 +0000 - upstream: Check for ProxyJump=none in CanonicalizeHostname logic. - - Previously ssh would incorrectly refuse to canonicalise the hostname - if ProxyJump was explicitly set to "none" when CanonicalizeHostname=yes - - bz3567; ok dtucker + upstream: make DSA testing optional, defaulting to on - OpenBSD-Commit-ID: 80a58e43c3a32f97361282f756ec8d3f37989efd - -commit ac383f3a5c6f529a2e8a5bc44af79a08c7da294e -Author: jsg@openbsd.org -Date: Wed Apr 12 14:22:04 2023 +0000 - - upstream: remove duplicate signal.h include + ok markus - OpenBSD-Commit-ID: 30c0a34d74d91ddd0e6992525da70d3293392f70 + OpenBSD-Regress-ID: dfc27b5574e3f19dc4043395594cea5f90b8572a -commit 740dafa20f3f3d325f6f5d44e990b8c8a6d3d816 -Author: jsg@openbsd.org -Date: Wed Apr 12 08:53:54 2023 +0000 +commit f9311e8921d92c5efca767227a497ab63280ac39 +Author: djm@openbsd.org +Date: Thu Jan 11 01:51:16 2024 +0000 - upstream: fix double words ok dtucker@ + upstream: ensure key_fd is filled when DSA is disabled; spotted by - OpenBSD-Commit-ID: 44d3223902fbce5276422bdc8063ab72a4078489 - -commit 6452f89577ec4f22440c31b8e19b061d1a7c4b2a -Author: Darren Tucker -Date: Tue Apr 11 16:49:19 2023 +1000 - - Test against LibreSSL 3.7.2. - -commit 2138f6be595ca106fe4805a1e3ab9c4d8acc697b -Author: Damien Miller -Date: Thu Apr 6 14:33:10 2023 +1000 - - remove unused upper-case const strings in fmtfp + tb@ - no float format that uses upper-case is supported nor are hex floats. - ok dtucker + OpenBSD-Commit-ID: 9dd417b6eec3cf67e870f147464a8d93f076dce7 -commit 484c5e6168fdb22cbcd73c4ff987cf9ca47989ca +commit 4e838120a759d187b036036610402cbda33f3203 Author: djm@openbsd.org -Date: Thu Apr 6 03:56:02 2023 +0000 +Date: Thu Jan 11 01:45:36 2024 +0000 - upstream: simplify sshsig_find_principals() similar to what happened to + upstream: make DSA key support compile-time optional, defaulting to + + on - sshsig_check_allowed_keys() in r1.31, removing some dead code + ok markus@ - OpenBSD-Commit-ID: a493e628d4d6c08f878c276d998f4313ba61702d + OpenBSD-Commit-ID: 4f8e98fc1fd6de399d0921d5b31b3127a03f581d -commit 3a7b110fbc7e096423f8f7b459deffe4c65d70f4 -Author: djm@openbsd.org -Date: Thu Apr 6 03:21:31 2023 +0000 +commit afcc9028bfc411bc26d20bba803b83f90cb84e26 +Author: jmc@openbsd.org +Date: Wed Jan 10 06:33:13 2024 +0000 - upstream: remove redundant ssh!=NULL check; we'd already - - dereferenced it + upstream: fix incorrect capitalisation; - OpenBSD-Commit-ID: 852bf12591ec5a9fb12dcbde9b1fd3945ad0df3c + OpenBSD-Commit-ID: cb07eb06e15fa2334660ac73e98f29b6a1931984 -commit 2519110659a1efac6c976895a86659d1b341c91b +commit 9707c8170c0c1baeb1e06e5a53f604498193885f Author: djm@openbsd.org -Date: Thu Apr 6 03:19:32 2023 +0000 +Date: Tue Jan 9 22:19:36 2024 +0000 - upstream: match_user() shouldn't be called with user==NULL unless + upstream: extend ChannelTimeout regression test to exercise multiplexed - host and ipaddr are also NULL + connections and the new "global" timeout type. ok dtucker@ - OpenBSD-Commit-ID: fa3518346c21483e9e01a2e4b9436ae501daf8ea + OpenBSD-Regress-ID: f10d19f697024e9941acad7c2057f73d6eacb8a2 -commit 3b9ceaad7ad63c1c03c2a89e148340ad3a62a482 +commit b31b12d28de96e1d43581d32f34da8db27e11c03 Author: djm@openbsd.org -Date: Thu Apr 6 03:12:32 2023 +0000 - - upstream: don't care about glob() return value here. - - OpenBSD-Commit-ID: 85bb82fea90478a482e9f65a1bec0aa24227fd66 - -commit 09d8da0849e2791b2500267cda333cd238f38754 -Author: dtucker@openbsd.org -Date: Mon Apr 3 08:10:54 2023 +0000 +Date: Tue Jan 9 22:19:00 2024 +0000 - upstream: Move up null check and simplify process_escapes. + upstream: add a "global" ChannelTimeout type to ssh(1) and sshd(8) - Based on Coverity CID 291863 which points out we check the channel - pointer for NULLness after dereferencing it. Move this to the start - of the function, and while there simplify initialization of efc a bit. - ok djm@ + that watches all open channels and will close all open channels if there is + no traffic on any of them for the specified interval. This is in addition to + the existing per-channel timeouts added a few releases ago. - OpenBSD-Commit-ID: de36e5ad6fde0fe263ca134e986b9095dc59380a - -commit b36b162be5e6206f12b734222b7bc517c13a6bc8 -Author: Damien Miller -Date: Fri Mar 31 14:51:20 2023 +1100 - - need va_end() after va_copy(); ok dtucker + This supports use-cases like having a session + x11 forwarding channel + open where one may be idle for an extended period but the other is + actively used. The global timeout would allow closing both channels when + both have been idle for too long. - spotted by Coverity - -commit f703757234a5c585553e72bba279b255a272750a -Author: dtucker@openbsd.org -Date: Fri Mar 31 05:56:36 2023 +0000 - - upstream: Explicitly ignore return from waitpid here too. + ok dtucker@ - OpenBSD-Commit-ID: eef2403df083c61028969fc679ee370373eacacb + OpenBSD-Commit-ID: 0054157d24d2eaa5dc1a9a9859afefc13d1d7eb3 -commit 6b73aa29035991d1448a1a76f63ac152a6bf931c -Author: dtucker@openbsd.org -Date: Fri Mar 31 04:45:08 2023 +0000 +commit 602f4beeeda5bb0eca181f8753d923a2997d0a51 +Author: djm@openbsd.org +Date: Tue Jan 9 21:39:14 2024 +0000 - upstream: Explictly ignore return codes + upstream: adapt ssh_api.c code for kex-strict - where we don't check them. + from markus@ ok me - OpenBSD-Commit-ID: 1ffb03038ba1b6b72667be50cf5e5e396b5f2740 + OpenBSD-Commit-ID: 4d9f256852af2a5b882b12cae9447f8f00f933ac -commit 6f0308a3e717ebe68eeb3f95253612fab5dbf20e -Author: dtucker@openbsd.org -Date: Fri Mar 31 04:42:29 2023 +0000 +commit 42ba34aba8708cf96583ff52975d95a8b47d990d +Author: Damien Miller +Date: Mon Jan 8 16:26:37 2024 +1100 - upstream: Return immediately from get_sock_port - - if sock <0 so we don't call getsockname on a negative FD. From Coverity - CID 291840, ok djm@ - - OpenBSD-Commit-ID: de1c1130646230c2eda559831fc6bfd1b61d9618 + nite that recent OSX tun/tap is unsupported -commit 1c1124dc901fca1ea2cb762044b8f1a5793a2bed -Author: djm@openbsd.org -Date: Fri Mar 31 04:23:02 2023 +0000 +commit 690bc125f9a3b20e47745fa8f5b5e1fd5820247f +Author: Sevan Janiyan +Date: Wed Dec 27 04:57:49 2023 +0000 - upstream: don't leak arg2 on parse_pubkey_algos error path; ok - - dtucker@ - - OpenBSD-Commit-ID: 7d0270ad3dd102412ca76add2b3760518abdef75 + README.platform: update tuntap url -commit 8ba2d4764bb6a4701cd447d8b52604622ffe65f4 -Author: djm@openbsd.org -Date: Fri Mar 31 04:22:27 2023 +0000 +commit 6b8be2ccd7dd091808f86af52066b0c2ec30483a +Author: Rose <83477269+AtariDreams@users.noreply.github.com> +Date: Tue Dec 19 11:48:20 2023 -0500 - upstream: clamp max number of GSSAPI mechanisms to 2048; ok dtucker + Fix compilation error in ssh-pcks11-client.c - OpenBSD-Commit-ID: ce66db603a913d3dd57063e330cb5494d70722c4 + Compilation fails becaus of an undefined reference to helper_by_ec, + because we forgot the preprocessor conditional that excludes that function + from being called in unsupported configurations. -commit 1883841fc13d0eada8743cac5d3abe142ee2efa7 +commit 219c8134157744886ee6ac5b8c1650abcd981f4c Author: djm@openbsd.org -Date: Fri Mar 31 04:21:56 2023 +0000 +Date: Mon Jan 8 05:11:18 2024 +0000 - upstream: don't print key if printing hostname failed; with/ok + upstream: Remove outdated note from PROTOCOL.mux - dtucker@ + Port forward close by control master is already implemented + by `mux_master_process_close_fwd` in `mux.c` - OpenBSD-Commit-ID: ad42971a6ee5a46feab2d79f7f656f8cf4b119f3 - -commit c6011129cafe4c411f6ef670a4cf271314708eb8 -Author: djm@openbsd.org -Date: Fri Mar 31 04:04:15 2023 +0000 - - upstream: remove redundant test + GHPR442 from bigb4ng - OpenBSD-Commit-ID: 6a0b719f9b1ae9d42ad8c5b144c7962c93792f7c + OpenBSD-Commit-ID: ad0734fe5916d2dc7dd02b588906cea4df0482fb -commit 4fb29eeafb40a2076c0dbe54e46b687c318f87aa +commit 4c3cf362631ccc4ffd422e572f075d5d594feace Author: djm@openbsd.org -Date: Fri Mar 31 04:00:37 2023 +0000 +Date: Mon Jan 8 05:05:15 2024 +0000 - upstream: don't attempt to decode a ridiculous number of + upstream: fix missing field in users-groups-by-id@openssh.com reply + + documentation - attributes; harmless because of bounds elsewhere, but better to be explicit + GHPR441 from TJ Saunders - OpenBSD-Commit-ID: 1a34f4b6896155b80327d15dc7ccf294b538a9f2 + OpenBSD-Commit-ID: ff5733ff6ef4cd24e0758ebeed557aa91184c674 -commit fc437c154ef724621a4af236de9bc7e51a8381ae +commit f64cede2a3c298b50a2659a8b53eb3ab2c0b8d23 Author: djm@openbsd.org -Date: Fri Mar 31 03:22:49 2023 +0000 +Date: Mon Jan 8 04:10:03 2024 +0000 - upstream: remove unused variable; prompted by Coverity CID 291879 + upstream: make kex-strict section more explicit about its intent: - OpenBSD-Commit-ID: 4c7d20ef776887b0ba1aabcfc1b14690e4ad0a40 + banning all messages not strictly required in KEX + + OpenBSD-Commit-ID: fc33a2d7f3b7013a7fb7500bdbaa8254ebc88116 -commit 0eb8131e4a53b33a8fc9b9ab694e6b6778b87ade -Author: dtucker@openbsd.org -Date: Fri Mar 31 00:44:29 2023 +0000 +commit 698fe6fd61cbcb8e3e0e874a561d4335a49fbde5 +Author: Damien Miller +Date: Mon Jan 8 14:46:19 2024 +1100 - upstream: Check fd against >=0 instead of >0 in error path. The - - dup could in theory return fd 0 although currently it doesn't in practice. - From Dmitry Belyavskiy vi github PR#238. - - OpenBSD-Commit-ID: 4a95f3f7330394dffee5c749d52713cbf3b54846 + update fuzzer example makefile to clang16 -commit 7174ba6f8a431ca4257767a260fc50e204068242 -Author: dtucker@openbsd.org -Date: Thu Mar 30 07:19:50 2023 +0000 +commit fc332cb2d602c60983a8ec9f89412754ace06425 +Author: Damien Miller +Date: Mon Jan 8 14:45:49 2024 +1100 - upstream: Ignore return value from muxclient(). It normally loops - - without returning, but it if returns on failure we immediately exit. - Coverity CID 405050. + unbreak fuzzers - missing pkcs11_make_cert() - OpenBSD-Commit-ID: ab3fde6da384ea588226037c38635a6b2e015295 + provide stub for use in fuzzer harness -commit a4c1c2513e36f111eeaa1322c510067930e5e51e +commit 9ea0a4524ae3276546248a926b6641b2fbc8421b Author: Damien Miller -Date: Fri Mar 31 14:17:22 2023 +1100 +Date: Mon Jan 8 14:45:14 2024 +1100 - don't call connect() on negative socket + unbreak fuzzers for clang16 - Coverity CID 405037 + getopt() needs a throw() attribute to compile, so supply one when compiling + things with C++ -commit 34ee842cdd981a759fe8f0d4a37521f9a1c63170 +commit a72833d00788ef91100c643536ac08ada46440e1 Author: djm@openbsd.org -Date: Thu Mar 30 03:05:01 2023 +0000 +Date: Mon Jan 8 00:34:33 2024 +0000 - upstream: return SSH_ERR_KEY_NOT_FOUND if the allowed_signers file + upstream: remove ext-info-* in the kex.c code, not in callers; - is empty, not SSH_ERR_INTERNAL_ERROR. Also remove some dead code spotted - by Coverity; with/ok dtucker@ + with/ok markus@ - OpenBSD-Commit-ID: 898a1e817cda9869554b1f586a434f67bcc3b650 + OpenBSD-Commit-ID: c06fe2d3a0605c517ff7d65e38ec7b2d1b0b2799 -commit f108e77a9dc9852e72215af1bf27731c48434557 -Author: dtucker@openbsd.org -Date: Thu Mar 30 00:49:37 2023 +0000 +commit 86f9e96d9bcfd1f5cd4bf8fb57a9b4c242df67df +Author: djm@openbsd.org +Date: Mon Jan 8 00:30:39 2024 +0000 - upstream: Remove dead code from inside if block. - - The only way the if statement can be true is if both dup()s fail, and - in that case the tmp2 can never be set. Coverity CID 291805, ok djm@ + upstream: fix typo; spotted by Albert Chin - OpenBSD-Commit-ID: c0d6089b3fb725015462040cd94e23237449f0c8 + OpenBSD-Commit-ID: 77140b520a43375b886e535eb8bd842a268f9368 -commit 05b8e88ebe23db690abbfb1a91111abea09cde08 -Author: Darren Tucker -Date: Thu Mar 30 13:53:29 2023 +1100 +commit f0cbd26ec91bd49719fb3eea7ca44d2380318b9a +Author: dtucker@openbsd.org +Date: Thu Jan 4 09:51:49 2024 +0000 - child_set_eng: verify both env pointer and count. + upstream: Import regenerated moduli. - If child_set env was called with a NULL env pointer and a non-zero count - it would end up in a null deref, although we don't currently do this. - Prompted by Coverity CID 291850, tweak & ok djm@ + OpenBSD-Commit-ID: 5a636f6ca7f25bfe775df4952f7aac90a7fcbbee -commit 28f1b8ef9b84b8cd2f6c9889a0c60aa4a90dadfa -Author: dtucker@openbsd.org -Date: Wed Mar 29 01:07:48 2023 +0000 +commit 64ddf776531ca4933832beecc8b7ebe1b937e081 +Author: jsg@openbsd.org +Date: Wed Dec 20 00:06:25 2023 +0000 - upstream: Ignore return from sshpkt_disconnect - - since we set our own return value for the function. Coverity CID 291797, - ok djm@ + upstream: spelling; ok markus@ - OpenBSD-Commit-ID: 710b57ba954c139240895e23feea41f203201f04 + OpenBSD-Commit-ID: 9d01f2e9d59a999d5d42fc3b3efcf8dfb892e31b -commit c3da05d95922f5550bcc7815e799474d6a160175 -Author: dtucker@openbsd.org -Date: Wed Mar 29 00:59:08 2023 +0000 +commit 503fbe9ea238a4637e8778208bde8c09bcf78475 +Author: jmc@openbsd.org +Date: Tue Dec 19 06:57:34 2023 +0000 - upstream: Plug potential mem leak in process_put. - - It allocates abs_dst inside a loop but only frees it on exit, so free - inside the loop if necessary. Coverity CID 291837, ok djm@ + upstream: sort -C, and add to usage(); ok djm - OpenBSD-Commit-ID: a01616503a185519b16f00dde25d34ceaf4ae1a3 + OpenBSD-Commit-ID: 80141b2a5d60c8593e3c65ca3c53c431262c812f -commit 13ae327eae598b1043e5ec30e4b170edb3c898a5 +commit 5413b1c7ff5a19c6a7d44bd98c5a83eb47819ba6 Author: djm@openbsd.org -Date: Wed Mar 29 00:18:35 2023 +0000 +Date: Tue Dec 19 06:41:14 2023 +0000 - upstream: fix memory leak; Coverity CID 291848 - - with/ok dtucker@ + upstream: correct section numbers; from Ed Maste - OpenBSD-Commit-ID: 37f80cb5d075ead5a00ad1b74175684ab1156ff8 + OpenBSD-Commit-ID: e289576ee5651528404cb2fb68945556052cf83f -commit 9ffa76e1284c85bf459c3dcb8e995733a8967e1b -Author: dtucker@openbsd.org -Date: Tue Mar 28 07:44:32 2023 +0000 +commit 430ef864645cff83a4022f5b050174c840e275da +Author: djm@openbsd.org +Date: Mon Dec 18 15:58:56 2023 +0000 - upstream: Plug more mem leaks in sftp by making - - make_absolute_pwd_glob work in the same way as make_absolute: you - pass it a dynamically allocated string and it either returns it, or - frees it and allocates a new one. Patch from emaste at freebsd.org and - https://reviews.freebsd.org/D37253 ok djm@ + upstream: match flag type (s/int/u_int) - OpenBSD-Commit-ID: 85f7404e9d47fd28b222fbc412678f3361d2dffc + OpenBSD-Commit-ID: 9422289747c35ccb7b31d0e1888ccd5e74ad566a -commit 82b2b8326962b1a98af279bc5bbbbbcab15b3e45 -Author: dtucker@openbsd.org -Date: Tue Mar 28 06:12:38 2023 +0000 +commit 1036d77b34a5fa15e56f516b81b9928006848cbd +Author: Damien Miller +Date: Fri Dec 22 17:56:26 2023 +1100 - upstream: Remove compat code for OpenSSL < 1.1.* + better detection of broken -fzero-call-used-regs - since -portable no longer supports them. + gcc 13.2.0 on ppc64le refuses to compile some function, including + cipher.c:compression_alg_list() with an error: - OpenBSD-Commit-ID: ea2893783331947cd29a67612b4e56f818f185ff - -commit b500afcf00ae1b6b73b2ccf171111dfbfeaef74d -Author: dtucker@openbsd.org -Date: Mon Mar 27 23:56:54 2023 +0000 - - upstream: Remove compat code for OpenSSL 1.0.* + > sorry, unimplemented: argument ‘used’ is not supportedcw + > for ‘-fzero-call-used-regs’ on this target - versions now that -portable has dropped support for those versions. + This extends the autoconf will-it-work test with a similarly- + structured function that seems to catch this. - OpenBSD-Regress-ID: 82a8eacd87aec28e4aa19f17246ddde9d5ce7fe7 + Spotted/tested by Colin Watson; bz3645 -commit 727560e6011efcb36d2f3ac6910444bc775abaa1 -Author: Darren Tucker -Date: Tue Mar 28 18:06:42 2023 +1100 +commit 8241b9c0529228b4b86d88b1a6076fb9f97e4a99 +Author: Damien Miller +Date: Tue Dec 19 01:59:50 2023 +1100 - Prevent conflicts between Solaris SHA2 and OpenSSL. - - We used to prevent conflicts between native SHA2 headers and OpenSSL's - by setting OPENSSL_NO_SHA but that was removed prior to OpenSSL 1.1.0 + crank versions -commit 46db8e14b7f186d32173dcdecd5b785334429b8b -Author: Darren Tucker -Date: Tue Mar 28 12:44:03 2023 +1100 +commit 2f2c65cb5f1518a9c556d3e8efa27ea0ca305c6b +Author: Damien Miller +Date: Tue Dec 19 01:59:06 2023 +1100 - Remove HEADER_SHA_H from previous... - - since it causes more problems than it solves. + depend -commit 72bd68d37387aa5f81da928f6e82f1c88ed8f674 -Author: Darren Tucker -Date: Tue Mar 28 10:35:18 2023 +1100 +commit e48cdee8e19059203b1aeeabec2350b8375fa61f +Author: djm@openbsd.org +Date: Mon Dec 18 14:50:08 2023 +0000 - Replace OPENSSL_NO_SHA with HEADER_SHA_H. + upstream: regress test for agent PKCS#11-backed certificates - Since this test doesn't use OpenSSL's SHA2 and may cause conflicts we - don't want to include it, but OPENSSL_NO_SHA was removed beginning in - OpenSSL's 1.1 series. - -commit 99668f2e6e0deb833e46cfab56db59ff0fc28c7e -Author: Darren Tucker -Date: Tue Mar 28 09:50:06 2023 +1100 - - Configure with --target instead of deprecated form. - -commit f751d9306c62cd1061f966e6a7483d9bab9c379b -Author: Darren Tucker -Date: Mon Mar 27 22:05:29 2023 +1100 - - Pass rpath when building 64bit Solaris. + OpenBSD-Regress-ID: 38f681777cb944a8cc3bf9d0ad62959a16764df9 -commit a64b935cd450ee8d04c26c9cd728629cf9ca5c91 -Author: Darren Tucker -Date: Mon Mar 27 19:21:19 2023 +1100 +commit 2f512f862df1d5f456f82a0334c9e8cc7208a2a1 +Author: djm@openbsd.org +Date: Mon Dec 18 14:49:39 2023 +0000 - Explicitly disable OpenSSL on AIX test VM. + upstream: regress test for constrained PKCS#11 keys + + OpenBSD-Regress-ID: b2f26ae95d609d12257b43aef7cd7714c82618ff -commit 7ebc6f060fc2f70495a56e16d210baae6424cd96 -Author: dtucker@openbsd.org -Date: Mon Mar 27 03:56:50 2023 +0000 +commit cdddd66412ca5920ed4d3ebbfa6ace12dbd9b82f +Author: djm@openbsd.org +Date: Mon Dec 18 14:48:44 2023 +0000 - upstream: Add RevokedHostKeys to percent expansion test. + upstream: openssh-9.6 - OpenBSD-Regress-ID: c077fd12a38005dd53d878c5b944154dec88d2ff + OpenBSD-Commit-ID: 21759837cf0e0092d9a2079f8fb562071c11016b -commit f1a17de150f8d309d0c52f9abfaebf11c51a8537 -Author: dtucker@openbsd.org -Date: Mon Mar 27 03:56:11 2023 +0000 +commit 6d51feab157cedf1e7ef5b3f8781ca8ff9c4ab1b +Author: djm@openbsd.org +Date: Mon Dec 18 14:48:08 2023 +0000 - upstream: Add tilde and environment variable expansion to + upstream: ssh-agent: record failed session-bind attempts + + Record failed attempts to session-bind a connection and refuse signing + operations on that connection henceforth. + + Prevents a future situation where we add a new hostkey type that is not + recognised by an older ssh-agent, that consequently causes session-bind + to fail (this situation is only likely to arise when people mix ssh(1) + and ssh-agent(1) of different versions on the same host). Previously, + after such a failure the agent socket would be considered unbound and + not subject to restriction. - RevokedHostKeys. bz#3552, ok djm@ + Spotted by Jann Horn - OpenBSD-Commit-ID: ce5d8e0219b63cded594c17d4c2958c06918ec0d + OpenBSD-Commit-ID: b0fdd023e920aa4831413f640de4c5307b53552e -commit 009eb4cb48a9708ab9174684dcbcc0f942907abe +commit 7ef3787c84b6b524501211b11a26c742f829af1a Author: djm@openbsd.org -Date: Mon Mar 27 03:31:05 2023 +0000 +Date: Mon Dec 18 14:47:44 2023 +0000 - upstream: fix test: getnameinfo returns a non-zero value on error, not + upstream: ban user/hostnames with most shell metacharacters + + This makes ssh(1) refuse user or host names provided on the + commandline that contain most shell metacharacters. + + Some programs that invoke ssh(1) using untrusted data do not filter + metacharacters in arguments they supply. This could create + interactions with user-specified ProxyCommand and other directives + that allow shell injection attacks to occur. + + It's a mistake to invoke ssh(1) with arbitrary untrusted arguments, + but getting this stuff right can be tricky, so this should prevent + most obvious ways of creating risky situations. It however is not + and cannot be perfect: ssh(1) has no practical way of interpreting + what shell quoting rules are in use and how they interact with the + user's specified ProxyCommand. + + To allow configurations that use strange user or hostnames to + continue to work, this strictness is applied only to names coming + from the commandline. Names specified using User or Hostname + directives in ssh_config(5) are not affected. - (neccessarily) -1. From GHPR#384 + feedback/ok millert@ markus@ dtucker@ deraadt@ - OpenBSD-Commit-ID: d35e2b71268f66f5543a7ea68751972b3ae22b25 + OpenBSD-Commit-ID: 3b487348b5964f3e77b6b4d3da4c3b439e94b2d9 -commit 4f0a676486700f10a4788f7e9426e94e39c1c89e +commit 0cb50eefdd29f0fec31d0e71cc4b004a5f704e67 Author: djm@openbsd.org -Date: Mon Mar 27 03:25:08 2023 +0000 +Date: Mon Dec 18 14:47:20 2023 +0000 - upstream: scp: when copying local->remote, check that source file + upstream: stricter handling of channel window limits - exists before opening SFTP connection to the server. Based on GHPR#370 ok - dtucker, markus + This makes ssh/sshd more strict in handling non-compliant peers that + send more data than the advertised channel window allows. Previously + the additional data would be silently discarded. This change will + cause ssh/sshd to terminate the connection if the channel window is + exceeded by more than a small grace allowance. - OpenBSD-Commit-ID: b4dd68e15bfe22ce4fac9960a1066a2b721e54fb - -commit 154d8baf631327163571760c2c524bc93c37567c -Author: Darren Tucker -Date: Mon Mar 27 12:22:30 2023 +1100 - - Also look for gdb error message from OpenIndiana. - -commit fbd3811ddb2b6ce2e6dba91fde7352c8978e5412 -Author: Darren Tucker -Date: Mon Mar 27 11:08:00 2023 +1100 - - Explicitly disable security key test on aix51 VM. + ok markus@ - We don't know how to build the shared objects required for the security - key tests so skip them. + OpenBSD-Commit-ID: 811e21b41831eba3dd7f67b3d409a438f20d3037 -commit 4922ac3be8a996780ef3dc220411da2e27c29d9c -Author: Darren Tucker -Date: Sun Mar 26 14:49:43 2023 +1100 +commit 4448a2938abc76e6bd33ba09b2ec17a216dfb491 +Author: djm@openbsd.org +Date: Mon Dec 18 14:46:56 2023 +0000 - Split libcrypto and other config flags. + upstream: Make it possible to load certs from PKCS#11 tokens - This should allow the automatic OpenSSL version selection in the tests - to work better. - -commit 4a948b1469f185e871160a2d70e2a0fce2858f9e -Author: Darren Tucker -Date: Sun Mar 26 14:39:45 2023 +1100 - - Specify test target if we build without OpenSSL. + Adds a protocol extension to allow grafting certificates supplied by + ssh-add to keys loaded from PKCS#11 tokens in the agent. - When we decide we can't use the versions of OpenSSL available, also - restrict the tests we run to avoid the ones that need OpenSSL. - -commit b308c636f5b5d89eecb98be00b3d56306a005a09 -Author: Darren Tucker -Date: Sun Mar 26 14:22:53 2023 +1100 - - Find suitable OpenSSL version. + feedback/ok markus@ - Check the installed OpenSSL versions for a suitable one, and if there - isn't (and we don't have a specific version configured) then build - without OpenSSL. - -commit 021ea5c2860f133f44790970968e0e73208b3a87 -Author: Damien Miller -Date: Fri Mar 24 15:02:52 2023 +1100 - - Github testing support for BoringSSL + OpenBSD-Commit-ID: bb5433cd28ede2bc910996eb3c0b53e20f86037f -commit 9a97cd106466a2a9bda2bfaa4c48c4f1b2cc9c1b -Author: Damien Miller -Date: Fri Mar 24 15:34:29 2023 +1100 +commit 881d9c6af9da4257c69c327c4e2f1508b2fa754b +Author: djm@openbsd.org +Date: Mon Dec 18 14:46:12 2023 +0000 - BoringSSL doesn't support EC_POINT_point2bn() + upstream: apply destination constraints to all p11 keys - so don't invoke it in unittest - -commit cc5969c033a032d126ff78e5d95cf20abbede4c7 -Author: Damien Miller -Date: Fri Mar 24 15:34:05 2023 +1100 - - another ERR_load_CRYPTO_strings() vestige - -commit 4974293899a068133e976f81d6693670d2b576ca -Author: Damien Miller -Date: Fri Mar 24 15:24:05 2023 +1100 - - don't use obsolete ERR_load_CRYPTO_strings() + Previously applied only to the first key returned from each token. - OpenSSL (and elsewhere in OpenSSH) uses ERR_load_crypto_strings() - -commit 3c527d55f906e6970d17c4cab6db90ae9e013235 -Author: Damien Miller -Date: Fri Mar 24 15:23:05 2023 +1100 - - Allow building with BoringSSL - -commit b7e27cfd7f163fc16b4c5d041cc28ee488a5eeec -Author: Damien Miller -Date: Fri Mar 24 15:21:18 2023 +1100 - - put back SSLeay_version compat in configure test + ok markus@ - Needed to detect old versions and give good "your version is bad" - messages at configure time; spotted by dtucker@ + OpenBSD-Commit-ID: 36df3afb8eb94eec6b2541f063d0d164ef8b488d -commit 7280401bdd77ca54be6867a154cc01e0d72612e0 -Author: Damien Miller -Date: Fri Mar 24 13:56:25 2023 +1100 +commit a7ed931caeb68947d30af8a795f4108b6efad761 +Author: djm@openbsd.org +Date: Mon Dec 18 14:45:49 2023 +0000 - remove support for old libcrypto + upstream: add "ext-info-in-auth@openssh.com" extension - OpenSSH now requires LibreSSL 3.1.0 or greater or - OpenSSL 1.1.1 or greater + This adds another transport protocol extension to allow a sshd to send + SSH2_MSG_EXT_INFO during user authentication, after the server has + learned the username that is being logged in to. - with/ok dtucker@ - -commit abda22fb48302f2142233f71d27c74040288c518 -Author: Darren Tucker -Date: Sun Mar 19 15:36:13 2023 +1100 - - Test latest OpenSSL 1.1, 3.0 and LibreSSL 3.7. - -commit 610ac1cb077cd5a1ebfc21612154bfa13d2ec825 -Author: Darren Tucker -Date: Thu Mar 16 21:38:04 2023 +1100 - - Show 9.3 branch instead of 9.2. + This lets sshd to update the acceptable signature algoritms for public + key authentication, and allows these to be varied via sshd_config(5) + "Match" directives, which are evaluated after the server learns the + username being authenticated. + + Full details in the PROTOCOL file + + OpenBSD-Commit-ID: 1de7da7f2b6c32a46043d75fcd49b0cbb7db7779 -commit cb30fbdbee869f1ce11f06aa97e1cb8717a0b645 -Author: Damien Miller -Date: Thu Mar 16 08:28:19 2023 +1100 +commit 1edb00c58f8a6875fad6a497aa2bacf37f9e6cd5 +Author: djm@openbsd.org +Date: Mon Dec 18 14:45:17 2023 +0000 - depend + upstream: implement "strict key exchange" in ssh and sshd + + This adds a protocol extension to improve the integrity of the SSH + transport protocol, particular in and around the initial key exchange + (KEX) phase. + + Full details of the extension are in the PROTOCOL file. + + with markus@ + + OpenBSD-Commit-ID: 2a66ac962f0a630d7945fee54004ed9e9c439f14 -commit 1dba63eb10c40b6fda9f5012ed6ae87e2d3d028e +commit 59d691b886c79e70b1d1c4ab744e81fd176222fd Author: Damien Miller -Date: Thu Mar 16 08:27:54 2023 +1100 +Date: Mon Dec 18 14:49:11 2023 +1100 - crank version + better detection of broken -fzero-call-used-regs + + Use OSSH_CHECK_CFLAG_LINK() for detection of these flags and extend + test program to exercise varargs, which seems to catch more stuff. + + ok dtucker@ -commit ba7532d0dac9aaf0ad7270664c43837fc9f64a5f +commit aa7b21708511a6d4aed3839fc9f6e82e849dd4a1 Author: djm@openbsd.org -Date: Wed Mar 15 21:19:57 2023 +0000 +Date: Wed Dec 13 03:28:19 2023 +0000 - upstream: openssh-9.3 + upstream: when invoking KnownHostsCommand to determine the order of - OpenBSD-Commit-ID: 8011495f2449c1029bb316bd015eab2e00509848 - -commit 6fd4daafb949b66bf555f3100f715a9ec64c3390 -Author: dtucker@openbsd.org -Date: Tue Mar 14 07:28:47 2023 +0000 - - upstream: Free KRL ptr in addition to its contents. + host key algorithms to request, ensure that the hostname passed to the + command is decorated with the port number for ports other than 22. + + This matches the behaviour of KnownHostsCommand when invoked to look + up the actual host key. - From Coverity CID 291841, ok djm@ + bz3643, ok dtucker@ - OpenBSD-Commit-ID: f146ba08b1b43af4e0d7ad8c4dae3748b4fa31b6 + OpenBSD-Commit-ID: 5cfabc0b7c6c7ab473666df314f377b1f15420b1 -commit 1d270bd303afaf6d94e9098cbbf18e5e539e2088 -Author: dtucker@openbsd.org -Date: Tue Mar 14 07:26:25 2023 +0000 +commit 4086bd6652c0badccc020218a62190a7798fb72c +Author: markus@openbsd.org +Date: Fri Dec 8 09:18:39 2023 +0000 - upstream: Check pointer for NULL before deref. - - None of the existing callers seem to do that, but it's worth checking. - From Coverity CID 291834, ok djm@ + upstream: prevent leak in sshsig_match_principals; ok djm@ - OpenBSD-Commit-ID: a0a97113f192a7cb1a2c97b932f677f573cda7a4 + OpenBSD-Commit-ID: 594f61ad4819ff5c72dfe99ba666a17f0e1030ae -commit d95af508e78c0cd3dce56b83853baaa59ae295cf -Author: dtucker@openbsd.org -Date: Sun Mar 12 10:40:39 2023 +0000 +commit 19d3ee2f3adf7d9a606ff015c1e153744702c4c9 +Author: djm@openbsd.org +Date: Wed Dec 6 21:06:48 2023 +0000 - upstream: Limit number of entries in SSH2_MSG_EXT_INFO + upstream: short circuit debug log processing early if we're not going - request. This is already constrained by the maximum SSH packet size but this - makes it explicit. Prompted by Coverity CID 291868, ok djm@ markus@ + to log anything. From Kobe Housen - OpenBSD-Commit-ID: aea023819aa44a2dcb9dd0fbec10561896fc3a09 + OpenBSD-Commit-ID: 2bcddd695872a1bef137cfff7823044dcded90ea -commit 8f287ba60d342b3e2f750e7332d2131e3ec7ecd0 -Author: dtucker@openbsd.org -Date: Sun Mar 12 09:41:18 2023 +0000 +commit 947affad4831df015c498c00c6351ea6f13895d5 +Author: Darren Tucker +Date: Mon Nov 27 09:37:28 2023 +1100 - upstream: calloc can return NULL but xcalloc can't. - - From Coverity CID 291881, ok djm@ - - OpenBSD-Commit-ID: 50204b755f66b2ec7ac3cfe379d07d85ca161d2b + Add tests for OpenSSL 3.2.0 and 3.2 stable branch. -commit 83a56a49fd50f4acf900f934279482e4ef329715 -Author: dtucker@openbsd.org -Date: Fri Mar 10 07:17:08 2023 +0000 +commit 747dce36206675ca6b885010a835733df469351b +Author: Darren Tucker +Date: Sat Nov 25 09:03:38 2023 +1100 - upstream: Explicitly ignore return from fcntl - - (... FD_CLOEXEC) here too. Coverity CID 291853. + Use non-zero arg in compiler test program. - OpenBSD-Commit-ID: 99d8b3da9d0be1d07ca8dd8e98800a890349e9b5 + Now that we're running the test program, passing zero to the test function + can cause divide-by-zero exceptions which might show up in logs. -commit 0fda9d704d3bbf54a5e64ce02a6fecb11fe7f047 -Author: Damien Miller -Date: Fri Mar 10 15:59:46 2023 +1100 +commit 3d44a5c56585d1c351dbc006240a591b6da502b1 +Author: dtucker@openbsd.org +Date: Fri Nov 24 00:31:30 2023 +0000 - bounds checking for getrrsetbyname() replacement; + upstream: Plug mem leak of msg when processing a quit message. - Spotted by Coverity in CID 405033; ok millert@ + Coverity CID#427852, ok djm@ + + OpenBSD-Commit-ID: bf85362addbe2134c3d8c4b80f16601fbff823b7 -commit 89b8df518f21677045599df0ad3e5dd0f39909b5 +commit 1d7f9b6e297877bd00973e6dc5c0642dbefc3b5f Author: dtucker@openbsd.org -Date: Fri Mar 10 04:06:21 2023 +0000 +Date: Thu Nov 23 03:37:05 2023 +0000 - upstream: Plug mem leak on error path. Coverity CID 405026, ok djm@. + upstream: Include existing mux path in debug message. - OpenBSD-Commit-ID: 8212ca05d01966fb5e72205c592b2257708a2aac + OpenBSD-Commit-ID: 1c3641be10c2f4fbad2a1b088a441d072e18bf16 -commit bf4dae0ad192c3e2f03f7223834b00d88ace3d3e +commit f29934066bd0e561a2e516b7e584fb92d2eedee0 Author: Darren Tucker -Date: Fri Mar 10 14:46:57 2023 +1100 +Date: Thu Nov 23 19:41:27 2023 +1100 - Add prototypes for mkstemp replacements. + Add an Ubuntu 22.04 test VM. - Should prevent warnings due to our wrapper function. + This is the same version as Github's runners so most of the testing on + it is over there, but having a local VM makes debugging much easier. -commit 4e04d68d6a33cdc73b831fd4b5e6124175555d3d -Author: dtucker@openbsd.org -Date: Fri Mar 10 03:01:51 2023 +0000 +commit a93284a780cd3972afe5f89086b75d564ba157f3 +Author: Darren Tucker +Date: Thu Nov 23 19:36:22 2023 +1100 - upstream: Expliticly ignore return code from fcntl(.. FD_CLOEXEC) since - - there's not much we can do anyway. From Coverity CID 291857, ok djm@ + Add gcc-12 -Werror test on Ubuntu 22.04. - OpenBSD-Commit-ID: 051429dd07af8db3fec10d82cdc78d90bb051729 + Explictly specify gcc-11 on Ubuntu 22.04 (it's the system compiler). -commit d6d38fd77cbe091c59e1bb720c3a494df4990640 -Author: djm@openbsd.org -Date: Fri Mar 10 02:32:04 2023 +0000 +commit 670f5a647e98b6fd95ad64f789f87ee3274b481b +Author: Darren Tucker +Date: Thu Nov 23 19:34:57 2023 +1100 - upstream: Like sshd_config, some ssh_config options are not - - first-match-wins. sshd_config.5 was fixed in r1.348, this is the same for - this file + Check return value from write to prevent warning. - OpenBSD-Commit-ID: 7be55b9351cde449b136afcc52d07aa4113b215e + ... and since we're testing for flags with -Werror, this caused + configure to mis-detect compiler flags. -commit 7187d3f86bf8f2066cc9941f217d23b0cacae25e -Author: dtucker@openbsd.org -Date: Fri Mar 10 02:24:56 2023 +0000 +commit cea007d691cfedfa07a5b8599f97ce0511f53fc9 +Author: Darren Tucker +Date: Wed Nov 22 21:18:55 2023 +1100 - upstream: Remove no-op (int) > INT_MAX checks - - since they can never be true. From Coverity CID 405031, ok djm@ + Run compiler test program when compiling natively. - OpenBSD-Commit-ID: 9df3783b181e056595e2bb9edf7ed41d61cf8e84 + ok djm@ -commit 77adde4305542ebe3005dd456122624fe2347b01 +commit ee0d305828f13536c0a416bbf9c3e81039d9ea55 Author: Darren Tucker -Date: Fri Mar 10 13:27:29 2023 +1100 +Date: Wed Nov 22 21:18:07 2023 +1100 - Wrap mkstemp calls with umask set/restore. + Factor out compiler test program into a macro. - glibc versions 2.06 and earlier did not set a umask on files created by - mkstemp created the world-writable. Wrap mkstemp to set and restore - the umask. From Coverity (CIDs 291826 291886 291891), ok djm@ + ok djm@ -commit 633d3dc2a1e9e2a013d019a0576a0771c8423713 -Author: jcs@openbsd.org -Date: Thu Mar 9 21:06:24 2023 +0000 +commit de304c76316b029df460673725a9104224b9959b +Author: Darren Tucker +Date: Wed Nov 22 08:55:36 2023 +1100 - upstream: modify parentheses in conditionals to make it clearer what is - - being assigned and what is being checked - - ok djm dtucker - - OpenBSD-Commit-ID: 19c10baa46ae559474409f75a5cb3d0eade7a9b8 + Add fbsd14 VM to test pool. -commit 733030840c4772f858de95d5940ec0c37663e8b0 -Author: dtucker@openbsd.org -Date: Thu Mar 9 07:11:05 2023 +0000 +commit 99a2df5e1994cdcb44ba2187b5f34d0e9190be91 +Author: Darren Tucker +Date: Tue Nov 21 16:19:29 2023 +1100 - upstream: Re-split the merge of the reorder-hostkeys test. - - In the kex_proposal_populate_entries change I merged the the check for - reordering hostkeys with the actual reordering, but kex_assemble_names - mutates options.hostkeyalgorithms which renders the check ineffective. - Put the check back where it was. Spotted and tested by jsg@, ok djm@ + Expand -fzero-call-used-regs test to cover gcc 11. - OpenBSD-Commit-ID: a7469f25a738db5567395d1881e32479a7ffc9de + It turns out that gcc also has some problems with -fzero-call-used-regs, + at least v11 on mips. Previously the test in OSSH_CHECK_CFLAG_COMPILE + was sufficient to catch it with "=all", but not sufficient for "=used". + Expand the testcase and include it in the other tests for good measure. + See bz#3629. ok djm@. -commit 54ac4ab2b53ce9fcb66b8250dee91c070e4167ed -Author: djm@openbsd.org -Date: Thu Mar 9 06:58:26 2023 +0000 +commit ff220d4010717f7bfbbc02a2400666fb9d24f250 +Author: Darren Tucker +Date: Tue Nov 21 14:04:34 2023 +1100 - upstream: include destination constraints for smartcard keys too. - - Spotted by Luci Stanescu; ok deraadt@ markus@ + Stop using -fzero-call-used-regs=all - OpenBSD-Commit-ID: add879fac6903a1cb1d1e42c4309e5359c3d870f + ... since it seems to be problematic with several different versions of + clang. Only use -fzero-call-used-regs=used which is less + problematic, except with Apple's clang where we don't use it at all. + bz#3629, ok djm@ -commit bfd1ad01d974a316b60622759ad17537fa2d92b4 +commit 2a19e02f36b16f0f6cc915f7d1e60ead5e36303b Author: Darren Tucker -Date: Thu Mar 9 18:24:54 2023 +1100 +Date: Tue Nov 21 14:02:18 2023 +1100 - Limit the number of PAM environment variables. + Allow for vendor prefix on clang version numbers. - xcalloc has its own limits, but these are specific to PAM. From - Coverity CID 405198, ok djm@ + Correctly detects the version of OpenBSD's native clang, as well as + Apple's. Spotted tb@, ok djm@. -commit a231414970e01a35f45a295d5f93698fa1249b28 -Author: Darren Tucker -Date: Thu Mar 9 18:19:44 2023 +1100 +commit c52db0114826d73eff6cdbf205e9c1fa4f7ca6c6 +Author: djm@openbsd.org +Date: Mon Nov 20 02:50:00 2023 +0000 - Limit the number of PAM environment variables. + upstream: set errno=EAFNOSUPPORT when filtering addresses that don't - From Coverity CID 405194, tweaks and ok djm@ + match AddressFamily; yields slightly better error message if no address + matches. bz#3526 + + OpenBSD-Commit-ID: 29cea900ddd8b04a4d1968da5c4a893be2ebd9e6 -commit 36c6c3eff5e4a669ff414b9daf85f919666e8e03 -Author: dtucker@openbsd.org -Date: Wed Mar 8 06:21:32 2023 +0000 +commit 26f3f3bbc69196d908cad6558c8c7dc5beb8d74a +Author: djm@openbsd.org +Date: Wed Nov 15 23:03:38 2023 +0000 - upstream: Plug mem leak. Coverity CID 405196, ok djm@ + upstream: when connecting via socket (the default case), filter + + addresses by AddressFamily if one was specified. Fixes the case where, if + CanonicalizeHostname is enabled, ssh may ignore AddressFamily. bz5326; ok + dtucker - OpenBSD-Commit-ID: 175f09349387c292f626da68f65f334faaa085f2 + OpenBSD-Commit-ID: 6c7d7751f6cd055126b2b268a7b64dcafa447439 -commit dfb9b736e1ccf9e6b03eea21cd961f4fd0634c98 -Author: tb@openbsd.org -Date: Wed Mar 8 05:33:53 2023 +0000 +commit 050c335c8da43741ed0df2570ebfbd5d1dfd0a31 +Author: djm@openbsd.org +Date: Wed Nov 15 22:51:49 2023 +0000 - upstream: ssh-pkcs11: synchronize error messages with errors + upstream: when deciding whether to enable keystroke timing - A handful of error messages contained incorrect function names or - otherwise inaccurate descriptions. Fix them to match reality. + obfuscation, only consider enabling it when a channel with a tty is open. - input/ok djm + Avoids turning on the obfucation when X11 forwarding only is in use, + which slows it right down. Reported by Roger Marsh - OpenBSD-Commit-ID: 165a15db52f75b31e1804b043480c36af09f3411 + OpenBSD-Commit-ID: c292f738db410f729190f92de100c39ec931a4f1 -commit 51875897b81b5c21b80c256a29597916edbde454 -Author: guenther@openbsd.org -Date: Wed Mar 8 04:43:12 2023 +0000 +commit 676377ce67807a24e08a54cd60ec832946cc6cae +Author: tobhe@openbsd.org +Date: Mon Nov 13 09:18:19 2023 +0000 - upstream: Delete obsolete /* ARGSUSED */ lint comments. + upstream: Make sure sftp_get_limits() only returns 0 if 'limits' + + was initialized. This fixes a potential uninitialized use of 'limits' in + sftp_init() if sftp_get_limits() returned early because of an unexpected + message type. - ok miod@ millert@ + ok djm@ - OpenBSD-Commit-ID: 7be168a570264d59e96a7d2d22e927d45fee0e4c + OpenBSD-Commit-ID: 1c177d7c3becc1d71bc8763eecf61873a1d3884c -commit a76085bda883c2104afb33ab0334eca190927362 +commit 64e0600f23c6dec36c3875392ac95b8a9100c2d6 Author: Darren Tucker -Date: Wed Mar 8 17:25:37 2023 +1100 +Date: Mon Nov 13 20:03:31 2023 +1100 - Extra brackets to prevent warning. + Test current releases of LibreSSL and OpenSSL. + + Retire some of the older releases. -commit 147ae57d4dfa0508109f93b78a7d8b92819e1f83 -Author: djm@openbsd.org -Date: Wed Mar 8 00:05:58 2023 +0000 +commit c8ed7cc545879ac15f6ce428be4b29c35598bb2a +Author: dtucker@openbsd.org +Date: Wed Nov 1 02:08:38 2023 +0000 - upstream: use RSA/SHA256 when testing usability of private key in + upstream: Specify ssh binary to use - agent; with/ok dtucker + ... instead of relying on installed one. Fixes test failures in -portable + when running tests prior to installation. - OpenBSD-Commit-ID: fe1382e2fdf23fcae631308e72342bad56066a56 + OpenBSD-Regress-ID: b6d6ba71c23209c616efc805a60d9a445d53a685 -commit 27fd251bc906a763e70ce0f27c8abdf8bbd1e416 -Author: djm@openbsd.org -Date: Wed Mar 8 00:05:37 2023 +0000 +commit e9fc2c48121cada1b4dcc5dadea5d447fe0093c3 +Author: Darren Tucker +Date: Wed Nov 1 13:11:31 2023 +1100 - upstream: use RSA/SHA256 when testing usability of private key; - - based on fix in bz3546 by Dmitry Belyavskiy; with/ok dtucker + Put long-running test targets on hipri runners. - OpenBSD-Commit-ID: 0ef414cc363a832f9fab92a5da0234448bce2eba + Some of the selfhosted test targets take a long time to run for various + reasons, so label them for "libvirt-hipri" runners so that they can + start immediately. This should reduce the time to complete all tests. -commit eee9f3fc3d52ae7d2106929bb06b7f291fb0b81a +commit 7ddf27668f0e21233f08c0ab2fe9ee3fdd6ab1e2 Author: djm@openbsd.org -Date: Tue Mar 7 21:47:42 2023 +0000 +Date: Wed Nov 1 00:29:46 2023 +0000 - upstream: refactor to be more readable top to bottom. Prompted by + upstream: add some tests of forced commands overriding Subsystem - Coverity CID 405048 which was a false-positive fd leak; ok dtucker@ + directives - OpenBSD-Commit-ID: fc55ec2af622a017defb9b768bf26faefc792c00 - -commit 42a06b29a4c99272bf690f9b3be520b08b448dc5 -Author: Darren Tucker -Date: Tue Mar 7 18:34:41 2023 +1100 - - Add header changes missed in previous. + OpenBSD-Regress-ID: eb48610282f6371672bdf2a8b5d2aa33cfbd322b -commit 4710077096edff2e6926dd5b15bf586491d317db +commit fb06f9b5a065dfbbef5916fc4accc03c0bf026dd Author: dtucker@openbsd.org -Date: Tue Mar 7 06:09:14 2023 +0000 +Date: Tue Oct 31 04:15:40 2023 +0000 - upstream: Fix mem leak in environment setup. + upstream: Don't try to use sudo inside sshd log wrapper. - From jjelen at redhat.com via bz#2687, ok djm@ + We still need to check if we're using sudo since we don't want to chown + unecessarily, as on some platforms this causes an error which pollutes + stderr. We also don't want to unnecessarily invoke sudo, since it's + running in the context of the proxycommand, on *other* platforms it + may not be able to authenticate, and if we're using SUDO then it should + already be privileged. - OpenBSD-Commit-ID: 9f9e4ba3cac003e6f81da3bcebd1b9ec43e7f353 + OpenBSD-Regress-ID: 70d58df7503db699de579a9479300e5f3735f4ee -commit 03acc50d0ccb78fc91d1570de1cd0fdfea646028 +commit fc3cc33e88c242c704781c6c48087838f1dcfa2a Author: dtucker@openbsd.org -Date: Mon Mar 6 12:15:47 2023 +0000 +Date: Tue Oct 31 02:58:45 2023 +0000 - upstream: Unit test for kex_proposal_populate_entries. + upstream: Only try to chmod logfile if we have sudo. If we don't have - OpenBSD-Regress-ID: bdb211d80d572a08bf14b49fe2a58b9ff265c006 + sudo then we won't need to chmod. + + OpenBSD-Regress-ID: dbad2f5ece839658ef8af3376cb1fb1cabe2e324 -commit 3f9231c2e1f374ebb08016ba00ea97b47c0ed20b +commit 3a506598fddd3f18f9095af3fe917f24cbdd32e0 Author: djm@openbsd.org -Date: Tue Mar 7 05:37:26 2023 +0000 +Date: Mon Oct 30 23:00:25 2023 +0000 - upstream: fix memory leak in process_read() path; Spotted by James + upstream: move PKCS#11 setup code to test-exec.sh so it can be reused - Robinson in GHPR363; ok markus@ + elsewhere - OpenBSD-Commit-ID: cdc2d98e6478b7e7f3a36976845adae3820429d8 + OpenBSD-Regress-ID: 1d29e6be40f994419795d9e660a8d07f538f0acb -commit c5e6e890839ec520ab9301a92cba56303749dea2 +commit f82fa227a52661c37404a6d33bbabf14fed05db0 Author: djm@openbsd.org -Date: Tue Mar 7 01:30:52 2023 +0000 +Date: Mon Oct 30 17:32:00 2023 +0000 - upstream: correct size for array argument when changing + upstream: tidy and refactor PKCS#11 setup code - UMAC_OUTPUT_LEN Coverity CID 291845; ok dtucker@ + Replace the use of a perl script to delete the controlling TTY with a + SSH_ASKPASS script to directly load the PIN. - OpenBSD-Commit-ID: 2eb017d10705bb623d4418691f961c930eafaec0 - -commit 9641753e0fd146204d57b2a4165f552a81afade4 -Author: dtucker@openbsd.org -Date: Mon Mar 6 12:14:48 2023 +0000 - - upstream: Refactor creation of KEX proposal. + Move PKCS#11 setup code to functions in anticipation of it being used + elsewhere in additional tests. - This adds kex_proposal_populate_entries (and corresponding free) which - populates the KEX proposal array with dynamically allocated strings. - This replaces the previous mix of static and dynamic that has been the - source of previous leaks and bugs. Remove unused compat functions. - With & ok djm@. + Reduce stdout spam - OpenBSD-Commit-ID: f2f99da4aae2233cb18bf9c749320c5e040a9c7b + OpenBSD-Regress-ID: 07705c31de30bab9601a95daf1ee6bef821dd262 -commit aa59d6a489fb20973fa461d0fdb1110db412947b -Author: dtucker@openbsd.org -Date: Sun Mar 5 09:24:35 2023 +0000 +commit 3cf698c6d4ffa9be1da55672a3519e2135a6366a +Author: Darren Tucker +Date: Mon Oct 30 21:35:03 2023 +1100 - upstream: Fix mem and FILE leaks in moduli screening. - - If multiple -Ocheckpoint= options are passed, the earlier ones would - be overwritten and leaked. If we use an input file that wasn't stdin, - close that. From Coverity CIDs 291884 and 291894. + Add obsd74 test VM and retire obsd69 and obsd70. + +commit 3e21d58a09894acb38dc69ed615d101131f473d0 +Author: Darren Tucker +Date: Mon Oct 30 18:34:12 2023 +1100 + + Add OpenSSL 3.3.0 as a known dev version. + +commit 917ba181c2cbdb250a443589ec732aa36fd51ffa +Author: Darren Tucker +Date: Mon Oct 30 13:32:03 2023 +1100 + + Restore nopasswd sudo rule on Mac OS X. - OpenBSD-Commit-ID: a4d9d15f572926f841788912e2b282485ad09e8b + This seems to be missing from some (but not all) github runners, so + restore it if it seems to be missing. -commit 23b8cb41767af99a1aac24589d1882d9c8c2c205 -Author: dtucker@openbsd.org -Date: Sun Mar 5 08:18:58 2023 +0000 +commit c5698abad6d4ec98ca20bcaaabaeacd5e1ec3f4f +Author: Darren Tucker +Date: Mon Oct 30 13:26:52 2023 +1100 - upstream: Plug mem leak in moduli checkpoint option parsing. - - From Coverity CID 291894. + Don't exit early when setting up on Mac OS X. - OpenBSD-Commit-ID: 9b1aba2d049741ae21c8dc4560a7e29ab17310f4 + We probably need some of the other bits in there (specifically, setting + the perms on the home directory) so make it less of a special snowflake. -commit fc7f8f2188d4a4fc8ba77eddbe863c7665666db5 +commit 1d6a878ceba60b9dc14037dddc8f036070c0065f Author: dtucker@openbsd.org -Date: Sun Mar 5 05:34:09 2023 +0000 +Date: Sun Oct 29 06:22:07 2023 +0000 - upstream: Remove unused compat.h includes. + upstream: Only try to chown logfiles that exist to prevent spurious - We've previously removed a lot of the really old compatibility code, - and with it went the need to include compat.h in most of the files that - have it. + errors. - OpenBSD-Commit-ID: 5af8baa194be00a3092d17598e88a5b29f7ea2b4 + OpenBSD-Regress-ID: f1b20a476734e885078c481f1324c9ea03af991e -commit 6c165c36246d8004c20e1df5cec4961a5ac422d6 -Author: dtucker@openbsd.org -Date: Sat Mar 4 03:22:59 2023 +0000 +commit e612376427a66f835e284f6b426d16d7c85301bc +Author: anton@openbsd.org +Date: Thu Oct 26 18:52:45 2023 +0000 - upstream: Use time_t for x11 timeout. + upstream: make use of bsd.regress.mk in extra and interop targets; ok - Use time_t instead of u_int for remaining x11 timeout checks for 64bit - time_t safety. From Coverity CIDs 405197 and 405028, ok djm@ + dtucker@ - OpenBSD-Commit-ID: 356685bfa1fc3d81bd95722d3fc47101cc1a4972 + OpenBSD-Regress-ID: 7ea21b5f6fc4506165093b2123d88d20ff13a4f0 -commit 4a3918f51bd2d968387e7aa87e33b32c78077fb4 +commit ea0039173957d0edcd6469b9614dcedb44dcb4f9 Author: dtucker@openbsd.org -Date: Fri Mar 3 10:23:42 2023 +0000 +Date: Thu Oct 26 12:44:07 2023 +0000 - upstream: Ensure ms_remain is always initialized - - similar to what we do in ssh_packet_write_wait. bz#2687, from jjelen - at redhat.com. + upstream: Skip conch interop tests when not enabled instead of fatal. - OpenBSD-Commit-ID: a50e0541cf823f8d1c72f71ccde925d3dbe6dfac + OpenBSD-Regress-ID: b0abf81c24ac6c21f367233663228ba16fa96a46 -commit e44846a4487d2885ac7f2610be09b1e2bf52249b +commit d220b9ed5494252b26b95f05be118472bc3ab5c0 Author: dtucker@openbsd.org -Date: Fri Mar 3 09:48:51 2023 +0000 +Date: Wed Oct 25 05:38:08 2023 +0000 - upstream: Check for non-NULL before string - - comparison. From jjelen at redhat.com via bz#2687. + upstream: Import regenerated moduli. - OpenBSD-Commit-ID: 0d9b2e0cac88a311b5766b1aef737082583c285f + OpenBSD-Commit-ID: 95f5dd6107e8902b87dc5b005ef2b53f1ff378b8 -commit 1842d523fae63b862ce8e60725c9b606cddb86a6 -Author: djm@openbsd.org -Date: Fri Mar 3 05:00:34 2023 +0000 +commit a611e4db4009447a0151f31a44e235ca32ed4429 +Author: anton@openbsd.org +Date: Wed Oct 25 08:01:59 2023 +0000 - upstream: guard against getsockname(-1, ...) from Coverity CID + upstream: ssh conch interop tests requires a controlling terminal; - 291832 + ok dtucker@ - OpenBSD-Commit-ID: e58d5227327917d189229b7f0b37d2780f360d5f + OpenBSD-Regress-ID: cbf2701bc347c2f19d907f113779c666f1ecae4a -commit 78571a5fe9847d40d7f220c92b707574ae9ec4ce -Author: djm@openbsd.org -Date: Fri Mar 3 04:36:20 2023 +0000 +commit da951b5e08c167acb5d6e2eec6f146502f5d6ed8 +Author: anton@openbsd.org +Date: Mon Oct 23 11:30:49 2023 +0000 - upstream: some options are not first-match-wins. Mention that there - - are exceptions at the start of the manpage and label some of them in the - option description. + upstream: Use private key that is allowed by sshd defaults in conch - OpenBSD-Commit-ID: 3b74728446fa6fc8742769eeb8c3674e233e84c4 - -commit d1c1b3272e8895a96c4f5889bd6e07a8525bd9f1 -Author: djm@openbsd.org -Date: Fri Mar 3 04:34:49 2023 +0000 - - upstream: actually print "channeltimeout none" in config dump mode; + interop tests. - spotted via Coverity CID 405022 + ok dtucker@ - OpenBSD-Commit-ID: b074b52bf138b75f08264e8da15880b29c7a630f + OpenBSD-Regress-ID: 3b7f65c8f409c328bcd4b704f60cb3d31746f045 -commit 8bf61e95610b48192d4e1720cc15d9004617301d +commit 1ca166dbb3c0ce632b98869cd955f69320aa6fe8 Author: Darren Tucker -Date: Fri Mar 3 14:50:03 2023 +1100 +Date: Fri Oct 20 20:43:00 2023 +1100 - Add Coverity badges. + Install Dropbear for interop testing. -commit 93291bd723959adf462b1df958106cf07a7734dd -Author: dtucker@openbsd.org -Date: Fri Mar 3 03:12:24 2023 +0000 +commit f993bb58351c5cb71e61aede63805a34a6d4daea +Author: Darren Tucker +Date: Fri Oct 20 20:39:03 2023 +1100 - upstream: Check return values of dup2. Spotted by Coverity, ok djm@ + Resync PuTTY and Conch path handling with upstream. - OpenBSD-Commit-ID: 19fb1b53072826d00c67df677731d2f6c1dd602b + Now that configure finds these for us we can remove these -portable + specific changes. -commit e37261dff33af23f37202cfce0848d36f5c1055c -Author: dtucker@openbsd.org -Date: Fri Mar 3 02:37:58 2023 +0000 +commit ff85becd5f5f06a76efa45d30fb204a3c5e5215c +Author: Darren Tucker +Date: Fri Oct 20 20:35:46 2023 +1100 - upstream: Use time_t for x11_refuse_time timeout. We need - - SSH_TIME_T_MAX for this, so move from misc.c to misc.h so it's available. - Fixes a Coverity warning for 64bit time_t safety, ok djm@ + Have configure find PuTTY and Conch binaries. - OpenBSD-Commit-ID: c69c4c3152cdaab953706db4ccf4d5fd682f7d8d + This will let us remove some -portable specific changes from + test-exec.sh. -commit 32755a98c29114b13f4c9d47454bbb265b932ad7 +commit c54a50359b9cecddbf3ffcdc26efcb3cd6071ec1 Author: dtucker@openbsd.org -Date: Fri Mar 3 02:34:29 2023 +0000 +Date: Fri Oct 20 07:37:07 2023 +0000 - upstream: Check return value from fctnl and warn on failure. + upstream: Allow overriding the locations of the Dropbear binaries - Spotted by Coverity, ok djm@ + similar to what we do for the PuTTY ones. - OpenBSD-Commit-ID: 2097c7db3cf657f1e3a6c5077041bacc63143cab + OpenBSD-Regress-ID: 7de0e00518fb0c8fdc5f243b7f82f523c936049c -commit 5fc60e8246c36b8255f72a937ebe9787b39648c6 +commit fbaa707d455a61d0aef8ae65e02a25bac5351e5c Author: dtucker@openbsd.org -Date: Thu Mar 2 11:10:27 2023 +0000 +Date: Fri Oct 20 06:56:45 2023 +0000 - upstream: Remove SUDO in proxy command wrapper. Anything that needs + upstream: Add interop test with Dropbear. - sudo is already run by it, and it breaks if root isn't in sudoers. + Right now this is only dbclient not the Dropbear server since it won't + currently run as a ProxyCommand. - OpenBSD-Regress-ID: 6cf22fda32a89c16915f31a6ed9bbdbef2a3bac9 + OpenBSD-Regress-ID: 8cb898c414fcdb252ca6328896b0687acdaee496 -commit 0d514659b23a257247491179cfbb53a6dd64e164 -Author: dtucker@openbsd.org -Date: Thu Mar 2 08:24:41 2023 +0000 +commit c2003d0dbdcdb61ca336c3f90c5c2b4a09c8e73f +Author: Fabio Pedretti +Date: Mon Oct 16 11:59:53 2023 +0200 - upstream: Fix breakage on dhgex test. - - This was due to the sshd logs being written to the wrong log file. - While there, make save_debug_logs less verbose, write the name of the - tarball to regress.log and use $SUDO to remove the old symlinks (which - shouldn't be needed, but won't hurt). Initial problem spotted by anton@. + Update openssl-devel dependency in RPM spec. - OpenBSD-Regress-ID: 9c44fb9cd418e6ff31165e7a6c1f9f11a6d19f5b + Since openssh 9.4p1, openssl >= 1.1.1 is required, so + build with --without-openssl elsewhere. + According to https://repology.org/project/openssl/versions + openssl 1.1.1 is available on fedora >= 29 and rhel >= 8. + Successfully build tested, installed and run on rhel 6 -commit 860201201d4ae655702807966901682cff30a171 -Author: dtucker@openbsd.org -Date: Thu Mar 2 08:14:52 2023 +0000 +commit 064e09cd632721c7e6889904e07767443ee23821 +Author: Fabio Pedretti +Date: Mon Oct 16 10:13:06 2023 +0200 - upstream: Quote grep and log message better. + Remove reference of dropped sshd.pam.old file - OpenBSD-Regress-ID: 3823d9063127169736aa274b1784cb28e15b64d4 + The file was removed in openssh 8.8 -commit 03a03c6002525f5ad9c8fc874a5d5826a35d9858 +commit 62db354b696b378a164b6e478cb6b0171dcb0c3d Author: dtucker@openbsd.org -Date: Thu Mar 2 06:41:56 2023 +0000 +Date: Mon Oct 16 08:40:00 2023 +0000 - upstream: Always call fclose on checkpoints. + upstream: Move declaration of "len" into the block where it's used. - In the case of an fprintf failure we would not call fclose which would - leak the FILE pointer. While we're there, try to clean up the temp file - on failure. Spotted by Coverity, ok djm@ + This lets us compile Portable with -Werror with when OpenSSL doesn't have + Ed25519 support. - OpenBSD-Commit-ID: 73c7ccc5d4fcc235f54c6b20767a2815408525ef + OpenBSD-Commit-ID: e02e4b4af351946562a7caee905da60eff16ba29 -commit 13fe8f9785e6d90400ce548939a0b0ddc11fcb3c -Author: dtucker@openbsd.org -Date: Wed Mar 1 21:54:50 2023 +0000 +commit 6eee8c972d5901d10e80634a006b4e346b2c8c19 +Author: Damien Miller +Date: Fri Oct 13 15:15:05 2023 +1100 - upstream: Remove old log symlinks + run t-extra regress tests - before creating new ones. In -portable some platforms don't like - overwriting existing symlinks. + This exposes the t-extra regress tests (including agent-pkcs11.sh) as + a new extra-tests target in the top level Makefile and runs them by + default. ok dtucker@ + +commit 637624dbbac13f2bc3c8ec5b15c9d627d07f2935 +Author: Darren Tucker +Date: Thu Oct 12 22:01:23 2023 +1100 + + Don't use make -j2. - OpenBSD-Regress-ID: 7e7ddc0beb73e945e1c4c58d51c8a125b518120f + While we have 2 cores available on github runners, not using it means + that the most recent log message is the actual failure, rather than + having to search back through the log for it. -commit 131fcbcaffd1e3bcf5ab766ec497b5d768955310 +commit 971e0cfcfd52ef1d73cf5244074c306a60006e89 Author: Darren Tucker -Date: Wed Mar 1 23:23:02 2023 +1100 +Date: Thu Oct 12 16:23:05 2023 +1100 - Adjust test jobs for new log directory. + Correct arg order for ED255519 AC_LINK_IFELSE test. -commit a6f4ac8a2baf77e5361cfa017d0dc250d1409bec -Author: dtucker@openbsd.org -Date: Wed Mar 1 09:29:32 2023 +0000 +commit c616e64688b2a0c1b4daad69b056099be998d121 +Author: djm@openbsd.org +Date: Thu Oct 12 03:51:08 2023 +0000 - upstream: Rework logging for the regression tests. - - Previously we would log to ssh.log and sshd.log, but that is insufficient - for tests that have more than one concurent ssh/sshd. - - Instead, we'll log to separate datestamped files in a $OBJ/log/ and - leave a symlink at the previous location pointing at the most recent - instance with an entry in regress.log showing which files were created - at each point. This should be sufficient to reconstruct what happened - even for tests that use multiple instances of each program. If the test - fails, tar up all of the logs for later analysis. - - This will let us also capture the output from some of the other tools - which was previously sent to /dev/null although most of those will be - in future commits. + upstream: typos and extra debug trace calls - OpenBSD-Regress-ID: f802aa9e7fa51d1a01225c05fb0412d015c33e24 + OpenBSD-Regress-ID: 98a2a6b9333743274359e3c0f0e65cf919a591d1 -commit 8ead62ed5e86c7df597d8604f332f49cd1527b85 -Author: dtucker@openbsd.org -Date: Tue Feb 28 21:31:50 2023 +0000 +commit c49a3fbf10162128c67c59562348de2041188974 +Author: djm@openbsd.org +Date: Thu Oct 12 03:48:53 2023 +0000 - upstream: fatal out if allocating banner string fails to avoid + upstream: ensure logs are owned by correct user; feedback/ok - potential null deref later in sscanf. Spotted by Coverity, ok deraadt@ + dtucker@ - OpenBSD-Commit-ID: 74e8d228ac00552e96e9e968dfcccf8dd1f46ad5 + OpenBSD-Regress-ID: c3297af8f07717f1d400a5d34529962f1a76b5a3 -commit 44ca56ba0b3f531f1d85730cc701097cd49e6868 -Author: dtucker@openbsd.org -Date: Tue Feb 28 08:45:24 2023 +0000 +commit 5ec0ed79ac074c3437b25f6cba8b8cf21c8d4587 +Author: djm@openbsd.org +Date: Thu Oct 12 03:36:32 2023 +0000 - upstream: Explicitly ignore return from fchmod + upstream: 64 %-expansion keys ought to be enough for anybody; ok - similar to other calls to prevent warning. + dtucker (we just hit the previous limit in some cases) - OpenBSD-Commit-ID: fdc5287dcee0860b5a493186414226c655b0eb0a + OpenBSD-Commit-ID: 84070f8001ec22ff5d669f836b62f206e08c5787 -commit 803392933a3a6f09f834aa5f0c2aab06a3b382f4 -Author: dtucker@openbsd.org -Date: Mon Feb 27 22:12:40 2023 +0000 +commit f59a94e22e46db2c23eddeb871aa9e8d93ab0016 +Author: djm@openbsd.org +Date: Thu Oct 12 02:48:43 2023 +0000 - upstream: Plug mem leak on globbed ls error path. - - Spotted by Coverity, ok deraadt@ + upstream: don't dereference NULL pointer when hashing jumphost - OpenBSD-Commit-ID: de28476025db29820a9a2e56e98b964d8a02861c + OpenBSD-Commit-ID: 251c0263e1759a921341c7efe7f1d4c73e1c70f4 -commit aa33b4d396abf47a2a45f982f28d054fb1dcb5c3 -Author: Darren Tucker -Date: Mon Feb 27 21:04:22 2023 +1100 +commit 281c79168edcc303abfd5bca983616eaa24c5f32 +Author: Damien Miller +Date: Thu Oct 12 13:20:01 2023 +1100 - Cast time_t's in debug output to long long. + Solaris: prefer PRIV_XPOLICY to PRIV_LIMIT - Should fix Coverity warning about truncation of 64bit time_t. + If the system support PRIV_XPOLICY and one is set, then don't + modify PRIV_LIMIT. bz2833, patch from Ron Jordan, ok dtucker@ -commit b0fd60a9de62a03189ad57d0c07f0ac51dc00e95 -Author: Darren Tucker -Date: Mon Feb 27 17:28:59 2023 +1100 +commit 98fc34df837f3a3b79d2a111b96fe8a39adcab55 +Author: djm@openbsd.org +Date: Thu Oct 12 02:18:18 2023 +0000 - Do shadow expiry calcs using "long long". + upstream: add %j token that expands to the configured ProxyJump + + hostname (or the empty string if this option is not being used). bz3610, ok + dtucker - Coverity flags these as potentially not 64bit time_t safe so use - long long for the calculations and debug output. ok djm@ + OpenBSD-Commit-ID: ce9983f7efe6a178db90dc5c1698df025df5e339 -commit 01dbeb3084d714bbd001ff9d03b9de542e8cdf58 -Author: Damien Miller -Date: Mon Feb 27 17:07:52 2023 +1100 +commit 7f3180be8a85320b5d3221714b40c16e66881249 +Author: djm@openbsd.org +Date: Thu Oct 12 02:15:53 2023 +0000 - avoid clash between for getopt's struct option - - Since we don't use getopt_long() nothing outside the getopt() - implementation itself uses this structure, so move it into the - source to remove it from visibility and clashes with libc's + upstream: release GSS OIDs only at end of authentication; bz2982, ok dtucker@ + + OpenBSD-Commit-ID: 0daa41e0525ae63cae4483519ecaa37ac485d94c -commit eb88d07c43afe407094e7d609248d85a15e148ef -Author: Darren Tucker -Date: Sat Feb 25 14:45:41 2023 +1100 +commit a612b93de5d86e955bfb6e24278f621118eea500 +Author: djm@openbsd.org +Date: Thu Oct 12 02:12:53 2023 +0000 - Revert explicit chmods on private keys. + upstream: mask SIGINT/TERM/QUIT/HUP before checking quit_pending - This should no longer be needed on Cygwin test runners due to previous - commit. + and use ppoll() to unmask them in the mainloop. Avoids race condition between + signaling ssh to exit and polling. bz3531; ok dtucker + + OpenBSD-Commit-ID: 5c14e1aabcddedb95cdf972283d9c0d5083229e7 -commit 52b75db61030a6c8baf66b73644380cf3f58e26a -Author: Darren Tucker -Date: Sat Feb 25 14:43:28 2023 +1100 +commit 531b27a006116fe7aff325510aaa576f24844452 +Author: djm@openbsd.org +Date: Wed Oct 11 23:23:58 2023 +0000 - Remove extended ACLs from working dirs. + upstream: sync usage() with ssh.1; spotted by kn@ - This should allow umask to work as expected and prevent tests from - failing due to excessive permissions on private keys. + OpenBSD-Commit-ID: 191a85639477dcb5fa1616d270d93b7c8d5c1dfd -commit 0c5d4c843df5605b043a758d69f9a611ef63c479 -Author: Darren Tucker -Date: Fri Feb 24 13:44:13 2023 +1100 +commit 64f7ca881b19be754425dca60d1590d306c9d1d0 +Author: djm@openbsd.org +Date: Wed Oct 11 23:14:33 2023 +0000 - Explicitly set permissions on user and host keys. + upstream: ssh -Q does not make sense with other command-line options, - On cygwin, the umask might not be sufficient. Should fix tests on - Github runners. + so give it its own line in the manpage + + OpenBSD-Commit-ID: 00a747f0655c12122bbb77c2796be0013c105361 -commit 6c9fc9d7a9f7abf82c3294d74e6d4a25735862ce +commit a752a6c0e1001f93696d7025f0c867f0376e2ecf Author: djm@openbsd.org -Date: Wed Feb 22 03:56:43 2023 +0000 +Date: Wed Oct 11 22:42:26 2023 +0000 - upstream: fix progressmeter corruption on wide displays; bz3534 + upstream: add ChannelTimeout support to the client, mirroring the - feedback/ok dtucker@ + same option in the server. ok markus@ - OpenBSD-Commit-ID: f4affee067cec7c182f3e0b307d758e0472762a3 + OpenBSD-Commit-ID: 55630b26f390ac063980cfe7ad8c54b03284ef02 -commit fe0bd3cde9665d364e5eedd2c2c2e60d4cdc3786 -Author: dtucker@openbsd.org -Date: Tue Feb 21 06:48:18 2023 +0000 +commit 76e91e7238cdc5662bc818e2a48d466283840d23 +Author: djm@openbsd.org +Date: Wed Oct 11 22:41:05 2023 +0000 - upstream: fseek to end of known_hosts before writing to it. + upstream: add support for reading ED25519 private keys in PEM PKCS8 - POSIX and ANSI C require that applications call fseek or similar between - read and writing to a RW file. OpenBSD doesn't enforce this, but some - (System V derived) platforms need this to prevent it from writing a - spurious extra byte (in this case, a newline). ok djm@ deraadt@ + format; ok markus@ tb@ - OpenBSD-Commit-ID: 33e680dcd8110582a93a40a8491024e961f45137 + OpenBSD-Commit-ID: 01b85c91757e6b057e9b23b8a23f96415c3c7174 -commit 357fb8ae14c07cd025eeed66e73de91bab569849 -Author: Darren Tucker -Date: Tue Feb 21 17:51:09 2023 +1100 +commit fc77c8e352c0f44125425c05265e3a00c183d78a +Author: djm@openbsd.org +Date: Wed Oct 11 06:40:54 2023 +0000 - Also run unit tests on AIX VMs. + upstream: mention "none" is a valid argument to IdentityFile; bz3080 - In the past these tests took too long, but these days it only adds - about 5 min to the run. + OpenBSD-Commit-ID: 1b4fb590ef731099349a7d468b77f02b240ac926 -commit 17781aaa5188ee1477f7779b280d105512e3dbed -Author: Darren Tucker -Date: Tue Feb 21 17:38:55 2023 +1100 +commit c97520d23d1fe53d30725a2af25d2dddd6f2faff +Author: djm@openbsd.org +Date: Wed Oct 11 05:42:08 2023 +0000 + + upstream: in olde rcp/scp protocol mode, when rejecting a path from the + + server as not matching the glob that the client sent, log (at debug level) + the received pathname as well as the list of possible expected paths expanded + from the glob. bz2966 + + OpenBSD-Commit-ID: 0bd8db8a595334ca86bca8f36e23fc0395315765 + +commit 208c2b719879805983398160791d6a1ef9c2c3fc +Author: djm@openbsd.org +Date: Wed Oct 11 04:46:29 2023 +0000 - Wrap stdint.h inside ifdef. + upstream: s/%.100s/%s/ in SSH- banner construction as there's no + + reason to limit its size: the version string bring included is a compile time + constant going into an allocated banner string. + + OpenBSD-Commit-ID: 0ef73304b9bf3e534c60900cd84ab699f859ebcd -commit ef798bad38505f7bf1b5fa5c0843dfc5a2b192b9 -Author: Mayank Sharma -Date: Mon Feb 20 17:37:15 2023 +0530 +commit 0354790826b97c41bbd171a965574e159b58d83e +Author: tb@openbsd.org +Date: Tue Oct 10 06:49:54 2023 +0000 - Add includes to ptimeout test. + upstream: Garbage collect cipher_get_keyiv_len() + + This is a compat20 leftover, unused since 2017. + + ok djm - Fixes test failures on AIX due to type mismatches. + OpenBSD-Commit-ID: 91fa5497c9dc6883064624ac27813a567883fdce -commit ab69dda05d5268454209f529fa80f477e60d846a -Author: Darren Tucker -Date: Mon Feb 20 18:24:39 2023 +1100 +commit 8d29ee4115001a02641386ae394992c65ed279e0 +Author: djm@openbsd.org +Date: Tue Oct 10 03:57:45 2023 +0000 - Always use the openssl binary configure tells us. + upstream: Reserve a range of "local extension" message numbers that + + OpenSSH promises not to use (comment change only) - This fixes tests on platforms that do not have the openssl tool - installed at all. + OpenBSD-Commit-ID: e61795b453d4892d2c99ce1039112c4a00250e03 diff --git a/INSTALL b/INSTALL index f99d1e2..56e351a 100644 --- a/INSTALL +++ b/INSTALL @@ -41,15 +41,17 @@ 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. +Jaenicke's PRNGd is recommended. If you are using libcrypto it requires +that the libcrypto is configured to support it. If you are building +--without-openssl then the --with-prngd-socket option must match the +socket provided by prngd. 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. +The same caveats about configuration for prngd also apply. http://egd.sourceforge.net/ @@ -94,8 +96,8 @@ 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 +the main git branch) then you will need autoconf-2.69 and automake-1.16.1 +or newer 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/ @@ -243,7 +245,7 @@ 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 +for each of the types you wish to generate (rsa, ed25519 or ecdsa) or ssh-keygen -A diff --git a/Makefile.in b/Makefile.in index 4243006..ba17a79 100644 --- a/Makefile.in +++ b/Makefile.in @@ -18,13 +18,13 @@ 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 SSHD_SESSION=$(libexecdir)/sshd-session +SSHD_AUTH=$(libexecdir)/sshd-auth SSH_PKCS11_HELPER=$(libexecdir)/ssh-pkcs11-helper SSH_SK_HELPER=$(libexecdir)/ssh-sk-helper PRIVSEP_PATH=@PRIVSEP_PATH@ @@ -32,6 +32,8 @@ SSH_PRIVSEP_USER=@SSH_PRIVSEP_USER@ STRIP_OPT=@STRIP_OPT@ TEST_SHELL=@TEST_SHELL@ BUILDDIR=@abs_top_builddir@ +SK_STANDALONE=@SK_STANDALONE@ +COMPATINCLUDES="$(BUILDDIR)/@COMPATINCLUDES@" PATHS= -DSSHDIR=\"$(sysconfdir)\" \ -D_PATH_SSH_PROGRAM=\"$(SSH_PROGRAM)\" \ @@ -39,6 +41,7 @@ PATHS= -DSSHDIR=\"$(sysconfdir)\" \ -D_PATH_SFTP_SERVER=\"$(SFTP_SERVER)\" \ -D_PATH_SSH_KEY_SIGN=\"$(SSH_KEYSIGN)\" \ -D_PATH_SSHD_SESSION=\"$(SSHD_SESSION)\" \ + -D_PATH_SSHD_AUTH=\"$(SSHD_AUTH)\" \ -D_PATH_SSH_PKCS11_HELPER=\"$(SSH_PKCS11_HELPER)\" \ -D_PATH_SSH_SK_HELPER=\"$(SSH_SK_HELPER)\" \ -D_PATH_SSH_PIDDIR=\"$(piddir)\" \ @@ -48,7 +51,7 @@ CC=@CC@ LD=@LD@ CFLAGS=@CFLAGS@ CFLAGS_NOPIE=@CFLAGS_NOPIE@ -CPPFLAGS=-I. -I$(srcdir) @CPPFLAGS@ $(PATHS) @DEFS@ +CPPFLAGS=-I. -I$(srcdir) -I$(COMPATINCLUDES) @CPPFLAGS@ $(PATHS) @DEFS@ PICFLAG=@PICFLAG@ LIBS=@LIBS@ CHANNELLIBS=@CHANNELLIBS@ @@ -57,6 +60,7 @@ GSSLIBS=@GSSLIBS@ SSHDLIBS=@SSHDLIBS@ LIBEDIT=@LIBEDIT@ LIBFIDO2=@LIBFIDO2@ +LIBWTMPDB=@LIBWTMPDB@ AR=@AR@ AWK=@AWK@ RANLIB=@RANLIB@ @@ -71,16 +75,7 @@ MKDIR_P=@MKDIR_P@ .SUFFIXES: .lo -TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) sshd-session$(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 +TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) sshd-session$(EXEEXT) sshd-auth$(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) $(SK_STANDALONE) LIBOPENSSH_OBJS=\ ssh_api.o \ @@ -91,8 +86,7 @@ LIBOPENSSH_OBJS=\ sshbuf-misc.o \ sshbuf-getput-crypto.o \ krl.o \ - bitmap.o \ - ${XMSS_OBJS} + bitmap.o LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ authfd.o authfile.o \ @@ -102,10 +96,10 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ 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 \ + monitor_fdpass.o rijndael.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 \ + msg.o dns.o entropy.o gss-genr.o umac.o umac128.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 ed25519.o hash.o \ @@ -113,18 +107,20 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ kexgexc.o kexgexs.o \ kexsntrup761x25519.o kexmlkem768x25519.o sntrup761.o kexgen.o \ sftp-realpath.o platform-pledge.o platform-tracing.o platform-misc.o \ - sshbuf-io.o + sshbuf-io.o misc-agent.o + +P11OBJS= ssh-pkcs11-client.o SKOBJS= ssh-sk-client.o SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \ - sshconnect.o sshconnect2.o mux.o $(SKOBJS) + sshconnect.o sshconnect2.o mux.o $(P11OBJS) $(SKOBJS) SSHDOBJS=sshd.o \ platform-listen.o \ servconf.o sshpty.o srclimit.o groupaccess.o auth2-methods.o \ dns.o fatal.o compat.o utf8.o authfd.o canohost.o \ - $(SKOBJS) + $(P11OBJS) $(SKOBJS) SSHD_SESSION_OBJS=sshd-session.o auth-rhosts.o auth-passwd.o \ audit.o audit-bsm.o audit-linux.o platform.o \ @@ -137,27 +133,40 @@ SSHD_SESSION_OBJS=sshd-session.o auth-rhosts.o auth-passwd.o \ auth2-gss.o gss-serv.o gss-serv-krb5.o \ loginrec.o auth-pam.o auth-shadow.o auth-sia.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) + uidswap.o platform-listen.o $(P11OBJS) $(SKOBJS) + +SSHD_AUTH_OBJS=sshd-auth.o \ + auth2-methods.o \ + auth-rhosts.o auth-passwd.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 \ + auth2-gss.o gss-serv.o gss-serv-krb5.o \ + monitor_wrap.o auth-krb5.o \ + audit.o audit-bsm.o audit-linux.o platform.o \ + loginrec.o auth-pam.o auth-shadow.o auth-sia.o \ + sandbox-null.o sandbox-rlimit.o sandbox-darwin.o \ + sandbox-seccomp-filter.o sandbox-capsicum.o sandbox-solaris.o \ + sftp-server.o sftp-common.o \ + uidswap.o $(P11OBJS) $(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) +SSHADD_OBJS= ssh-add.o $(P11OBJS) $(SKOBJS) -SSHAGENT_OBJS= ssh-agent.o ssh-pkcs11-client.o $(SKOBJS) +SSHAGENT_OBJS= ssh-agent.o $(P11OBJS) $(SKOBJS) -SSHKEYGEN_OBJS= ssh-keygen.o sshsig.o $(SKOBJS) +SSHKEYGEN_OBJS= ssh-keygen.o sshsig.o ssh-pkcs11.o $(SKOBJS) -SSHKEYSIGN_OBJS=ssh-keysign.o readconf.o uidswap.o $(SKOBJS) +SSHKEYSIGN_OBJS=ssh-keysign.o readconf.o uidswap.o $(P11OBJS) $(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) +SSHKEYSCAN_OBJS=ssh-keyscan.o $(P11OBJS) $(SKOBJS) SFTPSERVER_OBJS=sftp-common.o sftp-server.o sftp-server-main.o @@ -178,7 +187,6 @@ PATHSUBS = \ -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' \ @@ -218,7 +226,10 @@ sshd$(EXEEXT): libssh.a $(LIBCOMPAT) $(SSHDOBJS) $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(CHANNELLIBS) sshd-session$(EXEEXT): libssh.a $(LIBCOMPAT) $(SSHD_SESSION_OBJS) - $(LD) -o $@ $(SSHD_SESSION_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) $(CHANNELLIBS) + $(LD) -o $@ $(SSHD_SESSION_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) $(CHANNELLIBS) $(LIBWTMPDB) + +sshd-auth$(EXEEXT): libssh.a $(LIBCOMPAT) $(SSHD_AUTH_OBJS) + $(LD) -o $@ $(SSHD_AUTH_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) $(CHANNELLIBS) $(LIBWTMPDB) scp$(EXEEXT): $(LIBCOMPAT) libssh.a $(SCP_OBJS) $(LD) -o $@ $(SCP_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) @@ -254,6 +265,16 @@ sftp$(EXEEXT): $(LIBCOMPAT) libssh.a $(SFTP_OBJS) logintest: logintest.o $(LIBCOMPAT) libssh.a loginrec.o $(LD) -o $@ logintest.o $(LDFLAGS) loginrec.o -lopenbsd-compat -lssh $(LIBS) +# compile libssh objects with -fPIC for use in the sk_libfido2 shared library +LIBSSH_PIC_OBJS=$(LIBSSH_OBJS:.o=.lo) +libssh-pic.a: $(LIBSSH_PIC_OBJS) + $(AR) rv $@ $(LIBSSH_PIC_OBJS) + $(RANLIB) $@ + +$(SK_STANDALONE): $(srcdir)/sk-usbhid.c $(LIBCOMPAT) libssh-pic.a + $(CC) -o $@ -shared $(CFLAGS_NOPIE) $(CPPFLAGS) -DSK_STANDALONE $(PICFLAG) $(srcdir)/sk-usbhid.c \ + libssh-pic.a $(LDFLAGS_NOPIE) -lopenbsd-compat $(LIBS) $(LIBFIDO2) $(CHANNELLIBS) + $(MANPAGES): $(MANPAGES_IN) if test "$(MANTYPE)" = "cat"; then \ manpage=$(srcdir)/`echo $@ | sed 's/\.[1-9]\.out$$/\.0/'`; \ @@ -267,7 +288,7 @@ $(MANPAGES): $(MANPAGES_IN) $(FIXPATHSCMD) $${manpage} | $(FIXALGORITHMSCMD) > $@; \ fi -$(CONFIGFILES): $(CONFIGFILES_IN) +$(CONFIGFILES): $(CONFIGFILES_IN) Makefile conffile=`echo $@ | sed 's/.out$$//'`; \ $(FIXPATHSCMD) $(srcdir)/$${conffile} > $@ @@ -306,7 +327,8 @@ clean: regressclean 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 + rm -f regress/misc/ssh-verify-attestation/ssh-verify-attestation$(EXEEXT) + rm -f regress/misc/ssh-verify-attestation/*.o (cd openbsd-compat && $(MAKE) clean) distclean: regressclean @@ -344,6 +366,8 @@ distclean: regressclean rm -f regress/misc/sk-dummy/*.o rm -f regress/misc/sk-dummy/*.lo rm -f regress/misc/sk-dummy/sk-dummy.so + rm -f regress/misc/ssh-verify-attestation/ssh-verify-attestation$(EXEEXT) + rm -f regress/misc/ssh-verify-attestation/*.o (cd openbsd-compat && $(MAKE) distclean) if test -d pkg ; then \ rm -fr pkg ; \ @@ -411,6 +435,7 @@ install-files: $(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 0755 $(STRIP_OPT) sshd-session$(EXEEXT) $(DESTDIR)$(SSHD_SESSION)$(EXEEXT) + $(INSTALL) -m 0755 $(STRIP_OPT) sshd-auth$(EXEEXT) $(DESTDIR)$(SSHD_AUTH)$(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) @@ -461,7 +486,6 @@ host-key: ssh-keygen$(EXEEXT) 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 \ @@ -519,11 +543,12 @@ regress-prep: $(MKDIR_P) `pwd`/regress/unittests/sshsig $(MKDIR_P) `pwd`/regress/unittests/utf8 $(MKDIR_P) `pwd`/regress/misc/sk-dummy + $(MKDIR_P) `pwd`/regress/misc/ssh-verify-attestation [ -f `pwd`/regress/Makefile ] || \ ln -s `cd $(srcdir) && pwd`/regress/Makefile `pwd`/regress/Makefile REGRESSLIBS=libssh.a $(LIBCOMPAT) -TESTLIBS=$(LIBS) $(CHANNELLIBS) +TESTLIBS=$(LIBS) $(CHANNELLIBS) @TESTLIBS@ regress/modpipe$(EXEEXT): $(srcdir)/regress/modpipe.c $(REGRESSLIBS) $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $(srcdir)/regress/modpipe.c \ @@ -579,7 +604,7 @@ UNITTESTS_TEST_SSHKEY_OBJS=\ regress/unittests/sshkey/common.o \ regress/unittests/sshkey/test_file.o \ regress/unittests/sshkey/test_sshkey.o \ - $(SKOBJS) + $(P11OBJS) $(SKOBJS) regress/unittests/sshkey/test_sshkey$(EXEEXT): ${UNITTESTS_TEST_SSHKEY_OBJS} \ regress/unittests/test_helper/libtest_helper.a libssh.a @@ -590,7 +615,7 @@ regress/unittests/sshkey/test_sshkey$(EXEEXT): ${UNITTESTS_TEST_SSHKEY_OBJS} \ UNITTESTS_TEST_SSHSIG_OBJS=\ sshsig.o \ regress/unittests/sshsig/tests.o \ - $(SKOBJS) + $(P11OBJS) $(SKOBJS) regress/unittests/sshsig/test_sshsig$(EXEEXT): ${UNITTESTS_TEST_SSHSIG_OBJS} \ regress/unittests/test_helper/libtest_helper.a libssh.a @@ -610,7 +635,7 @@ regress/unittests/bitmap/test_bitmap$(EXEEXT): ${UNITTESTS_TEST_BITMAP_OBJS} \ UNITTESTS_TEST_AUTHOPT_OBJS=\ regress/unittests/authopt/tests.o \ auth-options.o \ - $(SKOBJS) + $(P11OBJS) $(SKOBJS) regress/unittests/authopt/test_authopt$(EXEEXT): \ ${UNITTESTS_TEST_AUTHOPT_OBJS} \ @@ -633,7 +658,7 @@ UNITTESTS_TEST_KEX_OBJS=\ regress/unittests/kex/tests.o \ regress/unittests/kex/test_kex.o \ regress/unittests/kex/test_proposal.o \ - $(SKOBJS) + $(P11OBJS) $(SKOBJS) regress/unittests/kex/test_kex$(EXEEXT): ${UNITTESTS_TEST_KEX_OBJS} \ regress/unittests/test_helper/libtest_helper.a libssh.a @@ -644,7 +669,7 @@ regress/unittests/kex/test_kex$(EXEEXT): ${UNITTESTS_TEST_KEX_OBJS} \ UNITTESTS_TEST_HOSTKEYS_OBJS=\ regress/unittests/hostkeys/tests.o \ regress/unittests/hostkeys/test_iterate.o \ - $(SKOBJS) + $(P11OBJS) $(SKOBJS) regress/unittests/hostkeys/test_hostkeys$(EXEEXT): \ ${UNITTESTS_TEST_HOSTKEYS_OBJS} \ @@ -671,7 +696,9 @@ UNITTESTS_TEST_MISC_OBJS=\ regress/unittests/misc/test_argv.o \ regress/unittests/misc/test_strdelim.o \ regress/unittests/misc/test_hpdelim.o \ - regress/unittests/misc/test_ptimeout.o + regress/unittests/misc/test_ptimeout.o \ + regress/unittests/misc/test_xextendf.o \ + regress/unittests/misc/test_misc.o regress/unittests/misc/test_misc$(EXEEXT): \ ${UNITTESTS_TEST_MISC_OBJS} \ @@ -705,6 +732,16 @@ 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) +SSH_VERIFY_ATTESTATION_OBJS=\ + regress/misc/ssh-verify-attestation/ssh-verify-attestation.o \ + $(P11OBJS) $(SKOBJS) + +ssh-verify-attestation: regress/misc/ssh-verify-attestation/ssh-verify-attestation$(EXEEXT) + +regress/misc/ssh-verify-attestation/ssh-verify-attestation$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSH_VERIFY_ATTESTATION_OBJS) + $(LD) -o $@ $(SSH_VERIFY_ATTESTATION_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) $(CHANNELLIBS) $(LIBFIDO2) + + regress-binaries: regress-prep $(LIBCOMPAT) \ regress/modpipe$(EXEEXT) \ regress/timestamp$(EXEEXT) \ @@ -738,6 +775,15 @@ unit: regress-unit-binaries OBJ="$(BUILDDIR)/regress" \ $@ && echo $@ tests passed +unit-bench: regress-unit-binaries + cd $(srcdir)/regress || exit $$?; \ + $(MAKE) \ + .CURDIR="$(abs_top_srcdir)/regress" \ + .OBJDIR="$(BUILDDIR)/regress" \ + OBJ="$(BUILDDIR)/regress" $@ + +TEST_SSH_SSHD="$(BUILDDIR)/sshd" + interop-tests t-exec file-tests extra-tests: regress-prep regress-binaries $(TARGETS) cd $(srcdir)/regress || exit $$?; \ EGREP='@EGREP@' \ @@ -752,8 +798,9 @@ interop-tests t-exec file-tests extra-tests: regress-prep regress-binaries $(TAR TEST_MALLOC_OPTIONS="@TEST_MALLOC_OPTIONS@" \ TEST_SSH_SCP="$(BUILDDIR)/scp" \ TEST_SSH_SSH="$(BUILDDIR)/ssh" \ - TEST_SSH_SSHD="$(BUILDDIR)/sshd" \ + TEST_SSH_SSHD="$(TEST_SSH_SSHD)" \ TEST_SSH_SSHD_SESSION="$(BUILDDIR)/sshd-session" \ + TEST_SSH_SSHD_AUTH="$(BUILDDIR)/sshd-auth" \ TEST_SSH_SSHAGENT="$(BUILDDIR)/ssh-agent" \ TEST_SSH_SSHADD="$(BUILDDIR)/ssh-add" \ TEST_SSH_SSHKEYGEN="$(BUILDDIR)/ssh-keygen" \ diff --git a/PROTOCOL b/PROTOCOL index 2638779..a94b36b 100644 --- a/PROTOCOL +++ b/PROTOCOL @@ -33,15 +33,11 @@ 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" +1.3. transport: Certificate key algorithms OpenSSH introduces new public key algorithms to support certificate authentication for users and host keys. These methods are documented -in the file PROTOCOL.certkeys +in at https://datatracker.ietf.org/doc/draft-miller-ssh-cert/ 1.4. transport: Elliptic Curve cryptography @@ -82,29 +78,20 @@ contains: 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: +Because of problems with the design of the algorithm negotiation in this +RFC, OpenSSH (and other SSH implementations) use different rules as +described in: -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. +https://datatracker.ietf.org/doc/draft-miller-sshm-aes-gcm/ 1.7 transport: chacha20-poly1305@openssh.com authenticated encryption OpenSSH supports authenticated encryption using ChaCha20 and Poly1305 -as described in PROTOCOL.chacha20poly1305. +as described in: -1.8 transport: curve25519-sha256@libssh.org key exchange algorithm +https://datatracker.ietf.org/doc/draft-ietf-sshm-chacha20-poly1305/ -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. - -1.9 transport: ping facility +1.8 transport: ping facility OpenSSH implements a transport level ping message SSH2_MSG_PING and a corresponding SSH2_MSG_PONG reply. @@ -137,34 +124,16 @@ than as a named global or channel request to allow pings with very short packet lengths, which would not be possible with other approaches. -1.10 transport: strict key exchange extension - -OpenSSH supports a number of transport-layer hardening measures under -a "strict KEX" feature. This feature is signalled similarly to the -RFC8308 ext-info feature: by including a additional algorithm in the -initial SSH2_MSG_KEXINIT kex_algorithms field. The client may append -"kex-strict-c-v00@openssh.com" to its kex_algorithms and the server -may append "kex-strict-s-v00@openssh.com". These pseudo-algorithms -are only valid in the initial SSH2_MSG_KEXINIT and MUST be ignored -if they are present in subsequent SSH2_MSG_KEXINIT packets. - -When an endpoint that supports this extension observes this algorithm -name in a peer's KEXINIT packet, it MUST make the following changes to -the protocol: - -a) During initial KEX, terminate the connection if out-of-sequence - packet or any message that is not strictly required by KEX is - received. This includes terminating the connection if the first - packet received is not SSH2_MSG_KEXINIT. Unexpected packets for - the purpose of strict KEX include messages that are otherwise - valid at any time during the connection such as SSH2_MSG_DEBUG, - SSH2_MSG_IGNORE or SSH2_MSG_UNIMPLEMENTED. -b) After sending or receiving a SSH2_MSG_NEWKEYS message, reset the - packet sequence number to zero. This behaviour persists for the - duration of the connection (i.e. not just the first - SSH2_MSG_NEWKEYS). - -1.11 transport: SSH2_MSG_EXT_INFO during user authentication +1.9 transport: strict key exchange extension + +OpenSSH supports a number of transport-layer hardening measures +designed to thwart the so-called "Terrapin" attack against the +early SSH protocol. These are collectively referred to as +"strict KEX" and documented in an Internet-Draft: + +https://datatracker.ietf.org/doc/draft-miller-sshm-strict-kex/ + +1.10 transport: SSH2_MSG_EXT_INFO during user authentication This protocol extension allows the SSH2_MSG_EXT_INFO to be sent during user authentication. RFC8308 does allow a second @@ -369,52 +338,9 @@ 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. +has completed. This is documented in an Internet-Draft -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. +https://datatracker.ietf.org/doc/draft-miller-sshm-hostkey-update/ 2.6. connection: SIGINFO support for "signal" channel request @@ -765,15 +691,15 @@ 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. +section 6.6 for RSA keys, RFC5656 section 3.1 for ECDSA keys and +https://datatracker.ietf.org/doc/draft-miller-ssh-cert/ +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 +(RFC7468) private keys are also supported for RSA and ECDSA keys and were the default format before OpenSSH 7.8. 5.3 KRL format @@ -792,4 +718,4 @@ master instance and later clients. OpenSSH extends the usual agent protocol. These changes are documented in the PROTOCOL.agent file. -$OpenBSD: PROTOCOL,v 1.55 2024/01/08 05:05:15 djm Exp $ +$OpenBSD: PROTOCOL,v 1.59 2025/08/06 11:22:53 dtucker Exp $ diff --git a/PROTOCOL.agent b/PROTOCOL.agent index 9ae16bf..2af749b 100644 --- a/PROTOCOL.agent +++ b/PROTOCOL.agent @@ -1,5 +1,5 @@ The SSH agent protocol is described in -https://tools.ietf.org/html/draft-miller-ssh-agent +https://datatracker.ietf.org/doc/draft-ietf-sshm-ssh-agent/ This file documents OpenSSH's extensions to the agent protocol. @@ -73,17 +73,6 @@ identities and, in particular, signature requests will check the key constraints against the session-bind@openssh.com bindings recorded for the agent connection over which they were received. -3. SSH_AGENT_CONSTRAIN_MAXSIGN key constraint - -This key constraint allows communication to an agent of the maximum -number of signatures that may be made with an XMSS key. The format of -the constraint is: - - byte SSH_AGENT_CONSTRAIN_MAXSIGN (0x03) - uint32 max_signatures - -This option is only valid for XMSS keys. - 3. associated-certs-v00@openssh.com key constraint extension The key constraint extension allows certificates to be associated @@ -115,4 +104,4 @@ A SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED will return SSH_AGENT_SUCCESS if any key (plain private or certificate) was successfully loaded, or SSH_AGENT_FAILURE if no key was loaded. -$OpenBSD: PROTOCOL.agent,v 1.23 2024/04/30 05:45:56 djm Exp $ +$OpenBSD: PROTOCOL.agent,v 1.25 2025/08/29 03:50:38 djm Exp $ diff --git a/PROTOCOL.certkeys b/PROTOCOL.certkeys deleted file mode 100644 index 68622e6..0000000 --- a/PROTOCOL.certkeys +++ /dev/null @@ -1,321 +0,0 @@ -This document describes a simple public-key certificate authentication -system for use by SSH. - -Background ----------- - -The SSH protocol currently supports a simple public key authentication -mechanism. Unlike other public key implementations, SSH eschews the use -of X.509 certificates and uses raw keys. This approach has some benefits -relating to simplicity of configuration and minimisation of attack -surface, but it does not support the important use-cases of centrally -managed, passwordless authentication and centrally certified host keys. - -These protocol extensions build on the simple public key authentication -system already in SSH to allow certificate-based authentication. The -certificates used are not traditional X.509 certificates, with numerous -options and complex encoding rules, but something rather more minimal: a -key, some identity information and usage options that have been signed -with some other trusted key. - -A sshd server may be configured to allow authentication via certified -keys, by extending the existing ~/.ssh/authorized_keys mechanism to -allow specification of certification authority keys in addition to -raw user keys. The ssh client will support automatic verification of -acceptance of certified host keys, by adding a similar ability to -specify CA keys in ~/.ssh/known_hosts. - -All certificate types include certification information along with the -public key that is used to sign challenges. In OpenSSH, ssh-keygen -performs the CA signing operation. - -Certified keys are represented using new key types: - - ssh-rsa-cert-v01@openssh.com - ssh-dss-cert-v01@openssh.com - ecdsa-sha2-nistp256-cert-v01@openssh.com - ecdsa-sha2-nistp384-cert-v01@openssh.com - ecdsa-sha2-nistp521-cert-v01@openssh.com - ssh-ed25519-cert-v01@openssh.com - -Two additional types exist for RSA certificates to force use of -SHA-2 signatures (SHA-256 and SHA-512 respectively): - - rsa-sha2-256-cert-v01@openssh.com - rsa-sha2-512-cert-v01@openssh.com - -These RSA/SHA-2 types should not appear in keys at rest or transmitted -on the wire, but do appear in a SSH_MSG_KEXINIT's host-key algorithms -field or in the "public key algorithm name" field of a "publickey" -SSH_USERAUTH_REQUEST to indicate that the signature will use the -specified algorithm. - -Protocol extensions -------------------- - -The SSH wire protocol includes several extensibility mechanisms. -These modifications shall take advantage of namespaced public key -algorithm names to add support for certificate authentication without -breaking the protocol - implementations that do not support the -extensions will simply ignore them. - -Authentication using the new key formats described below proceeds -using the existing SSH "publickey" authentication method described -in RFC4252 section 7. - -New public key formats ----------------------- - -The certificate key types take a similar high-level format (note: data -types and encoding are as per RFC4251 section 5). The serialised wire -encoding of these certificates is also used for storing them on disk. - -#define SSH_CERT_TYPE_USER 1 -#define SSH_CERT_TYPE_HOST 2 - -RSA certificate - - string "ssh-rsa-cert-v01@openssh.com" - string nonce - mpint e - mpint n - uint64 serial - uint32 type - string key id - string valid principals - uint64 valid after - uint64 valid before - string critical options - string extensions - string reserved - string signature key - string signature - -DSA certificate - - string "ssh-dss-cert-v01@openssh.com" - string nonce - mpint p - mpint q - mpint g - mpint y - uint64 serial - uint32 type - string key id - string valid principals - uint64 valid after - uint64 valid before - string critical options - string extensions - string reserved - string signature key - string signature - -ECDSA certificate - - string "ecdsa-sha2-nistp256-cert-v01@openssh.com" | - "ecdsa-sha2-nistp384-cert-v01@openssh.com" | - "ecdsa-sha2-nistp521-cert-v01@openssh.com" - string nonce - string curve - string public_key - uint64 serial - uint32 type - string key id - string valid principals - uint64 valid after - uint64 valid before - string critical options - string extensions - string reserved - string signature key - string signature - -ED25519 certificate - - string "ssh-ed25519-cert-v01@openssh.com" - string nonce - string pk - uint64 serial - uint32 type - string key id - string valid principals - uint64 valid after - uint64 valid before - string critical options - string extensions - string reserved - string signature key - string signature - -The nonce field is a CA-provided random bitstring of arbitrary length -(but typically 16 or 32 bytes) included to make attacks that depend on -inducing collisions in the signature hash infeasible. - -e and n are the RSA exponent and public modulus respectively. - -p, q, g, y are the DSA parameters as described in FIPS-186-2. - -curve and public key are respectively the ECDSA "[identifier]" and "Q" -defined in section 3.1 of RFC5656. - -pk is the encoded Ed25519 public key as defined by RFC8032. - -serial is an optional certificate serial number set by the CA to -provide an abbreviated way to refer to certificates from that CA. -If a CA does not wish to number its certificates, it must set this -field to zero. - -type specifies whether this certificate is for identification of a user -or a host using a SSH_CERT_TYPE_... value. - -key id is a free-form text field that is filled in by the CA at the time -of signing; the intention is that the contents of this field are used to -identify the identity principal in log messages. - -"valid principals" is a string containing zero or more principals as -strings packed inside it. These principals list the names for which this -certificate is valid; hostnames for SSH_CERT_TYPE_HOST certificates and -usernames for SSH_CERT_TYPE_USER certificates. As a special case, a -zero-length "valid principals" field means the certificate is valid for -any principal of the specified type. - -"valid after" and "valid before" specify a validity period for the -certificate. Each represents a time in seconds since 1970-01-01 -00:00:00. A certificate is considered valid if: - - valid after <= current time < valid before - -critical options is a set of zero or more key options encoded as -below. All such options are "critical" in the sense that an implementation -must refuse to authorise a key that has an unrecognised option. - -extensions is a set of zero or more optional extensions. These extensions -are not critical, and an implementation that encounters one that it does -not recognise may safely ignore it. - -Generally, critical options are used to control features that restrict -access where extensions are used to enable features that grant access. -This ensures that certificates containing unknown restrictions do not -inadvertently grant access while allowing new protocol features to be -enabled via extensions without breaking certificates' backwards -compatibility. - -The reserved field is currently unused and is ignored in this version of -the protocol. - -The signature key field contains the CA key used to sign the -certificate. The valid key types for CA keys are ssh-rsa, -ssh-dss, ssh-ed25519 and the ECDSA types ecdsa-sha2-nistp256, -ecdsa-sha2-nistp384, ecdsa-sha2-nistp521. "Chained" certificates, where -the signature key type is a certificate type itself are NOT supported. -Note that it is possible for a RSA certificate key to be signed by a -Ed25519 or ECDSA CA key and vice-versa. - -signature is computed over all preceding fields from the initial string -up to, and including the signature key. Signatures are computed and -encoded according to the rules defined for the CA's public key algorithm -(RFC4253 section 6.6 for ssh-rsa and ssh-dss, RFC5656 for the ECDSA -types, and RFC8032 for Ed25519). - -Critical options ----------------- - -The critical options section of the certificate specifies zero or more -options on the certificate's validity. The format of this field -is a sequence of zero or more tuples: - - string name - string data - -Options must be lexically ordered by "name" if they appear in the -sequence. Each named option may only appear once in a certificate. - -The name field identifies the option and the data field encodes -option-specific information (see below). All options are -"critical"; if an implementation does not recognise a option, -then the validating party should refuse to accept the certificate. - -Custom options should append the originating author or organisation's -domain name to the option name, e.g. "my-option@example.com". - -No critical options are defined for host certificates at present. The -supported user certificate options and the contents and structure of -their data fields are: - -Name Format Description ------------------------------------------------------------------------------ -force-command string Specifies a command that is executed - (replacing any the user specified on the - ssh command-line) whenever this key is - used for authentication. - -source-address string Comma-separated list of source addresses - from which this certificate is accepted - for authentication. Addresses are - specified in CIDR format (nn.nn.nn.nn/nn - or hhhh::hhhh/nn). - If this option is not present, then - certificates may be presented from any - source address. - -verify-required empty Flag indicating that signatures made - with this certificate must assert FIDO - user verification (e.g. PIN or - biometric). This option only makes sense - for the U2F/FIDO security key types that - support this feature in their signature - formats. - -Extensions ----------- - -The extensions section of the certificate specifies zero or more -non-critical certificate extensions. The encoding and ordering of -extensions in this field is identical to that of the critical options, -as is the requirement that each name appear only once. - -If an implementation does not recognise an extension, then it should -ignore it. - -Custom options should append the originating author or organisation's -domain name to the option name, e.g. "my-option@example.com". - -No extensions are defined for host certificates at present. The -supported user certificate extensions and the contents and structure of -their data fields are: - -Name Format Description ------------------------------------------------------------------------------ -no-touch-required empty Flag indicating that signatures made - with this certificate need not assert - FIDO user presence. This option only - makes sense for the U2F/FIDO security - key types that support this feature in - their signature formats. - -permit-X11-forwarding empty Flag indicating that X11 forwarding - should be permitted. X11 forwarding will - be refused if this option is absent. - -permit-agent-forwarding empty Flag indicating that agent forwarding - should be allowed. Agent forwarding - must not be permitted unless this - option is present. - -permit-port-forwarding empty Flag indicating that port-forwarding - should be allowed. If this option is - not present, then no port forwarding will - be allowed. - -permit-pty empty Flag indicating that PTY allocation - should be permitted. In the absence of - this option PTY allocation will be - disabled. - -permit-user-rc empty Flag indicating that execution of - ~/.ssh/rc should be permitted. Execution - of this script will not be permitted if - this option is not present. - -$OpenBSD: PROTOCOL.certkeys,v 1.19 2021/06/05 13:47:00 naddy Exp $ diff --git a/PROTOCOL.chacha20poly1305 b/PROTOCOL.chacha20poly1305 deleted file mode 100644 index 0bfff28..0000000 --- a/PROTOCOL.chacha20poly1305 +++ /dev/null @@ -1,107 +0,0 @@ -This document describes the chacha20-poly1305@openssh.com authenticated -encryption cipher supported by OpenSSH. - -Background ----------- - -ChaCha20 is a stream cipher designed by Daniel Bernstein and described -in [1]. It operates by permuting 128 fixed bits, 128 or 256 bits of key, -a 64 bit nonce and a 64 bit counter into 64 bytes of output. This output -is used as a keystream, with any unused bytes simply discarded. - -Poly1305[2], also by Daniel Bernstein, is a one-time Carter-Wegman MAC -that computes a 128 bit integrity tag given a message and a single-use -256 bit secret key. - -The chacha20-poly1305@openssh.com combines these two primitives into an -authenticated encryption mode. The construction used is based on that -proposed for TLS by Adam Langley in [3], but differs in the layout of -data passed to the MAC and in the addition of encryption of the packet -lengths. - -Negotiation ------------ - -The chacha20-poly1305@openssh.com offers both encryption and -authentication. As such, no separate MAC is required. If the -chacha20-poly1305@openssh.com cipher is selected in key exchange, -the offered MAC algorithms are ignored and no MAC is required to be -negotiated. - -Detailed Construction ---------------------- - -The chacha20-poly1305@openssh.com cipher requires 512 bits of key -material as output from the SSH key exchange. This forms two 256 bit -keys (K_1 and K_2), used by two separate instances of chacha20. -The first 256 bits constitute K_2 and the second 256 bits become -K_1. - -The instance keyed by K_1 is a stream cipher that is used only -to encrypt the 4 byte packet length field. The second instance, -keyed by K_2, is used in conjunction with poly1305 to build an AEAD -(Authenticated Encryption with Associated Data) that is used to encrypt -and authenticate the entire packet. - -Two separate cipher instances are used here so as to keep the packet -lengths confidential but not create an oracle for the packet payload -cipher by decrypting and using the packet length prior to checking -the MAC. By using an independently-keyed cipher instance to encrypt the -length, an active attacker seeking to exploit the packet input handling -as a decryption oracle can learn nothing about the payload contents or -its MAC (assuming key derivation, ChaCha20 and Poly1305 are secure). - -The AEAD is constructed as follows: for each packet, generate a Poly1305 -key by taking the first 256 bits of ChaCha20 stream output generated -using K_2, an IV consisting of the packet sequence number encoded as an -uint64 under the SSH wire encoding rules and a ChaCha20 block counter of -zero. The K_2 ChaCha20 block counter is then set to the little-endian -encoding of 1 (i.e. {1, 0, 0, 0, 0, 0, 0, 0}) and this instance is used -for encryption of the packet payload. - -Packet Handling ---------------- - -When receiving a packet, the length must be decrypted first. When 4 -bytes of ciphertext length have been received, they may be decrypted -using the K_1 key, a nonce consisting of the packet sequence number -encoded as a uint64 under the usual SSH wire encoding and a zero block -counter to obtain the plaintext length. - -Once the entire packet has been received, the MAC MUST be checked -before decryption. A per-packet Poly1305 key is generated as described -above and the MAC tag calculated using Poly1305 with this key over the -ciphertext of the packet length and the payload together. The calculated -MAC is then compared in constant time with the one appended to the -packet and the packet decrypted using ChaCha20 as described above (with -K_2, the packet sequence number as nonce and a starting block counter of -1). - -To send a packet, first encode the 4 byte length and encrypt it using -K_1. Encrypt the packet payload (using K_2) and append it to the -encrypted length. Finally, calculate a MAC tag and append it. - -Rekeying --------- - -ChaCha20 must never reuse a {key, nonce} for encryption nor may it be -used to encrypt more than 2^70 bytes under the same {key, nonce}. The -SSH Transport protocol (RFC4253) recommends a far more conservative -rekeying every 1GB of data sent or received. If this recommendation -is followed, then chacha20-poly1305@openssh.com requires no special -handling in this area. - -References ----------- - -[1] "ChaCha, a variant of Salsa20", Daniel Bernstein - http://cr.yp.to/chacha/chacha-20080128.pdf - -[2] "The Poly1305-AES message-authentication code", Daniel Bernstein - http://cr.yp.to/mac/poly1305-20050329.pdf - -[3] "ChaCha20 and Poly1305 based Cipher Suites for TLS", Adam Langley - http://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-03 - -$OpenBSD: PROTOCOL.chacha20poly1305,v 1.5 2020/02/21 00:04:43 dtucker Exp $ - diff --git a/README b/README index 8593619..41ecba1 100644 --- a/README +++ b/README @@ -1,19 +1,19 @@ -See https://www.openssh.com/releasenotes.html#9.9p2 for the release +See https://www.openssh.com/releasenotes.html#10.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. +instructions and note that we do not use Github for bug reporting. 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/ +implementation with all patent-encumbered algorithms removed (to external +libraries), all known security bugs fixed, new features reintroduced and +many other clean-ups. OpenSSH was created by Aaron Campbell, Bob Beck, +Markus Friedl, Niels Provos, Theo de Raadt, and Dug Song, and has been +developed and maintained by Andre Lucas, Ben Lindstom, Damien Miller, +Darren Tucker and Tim Rice. 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 @@ -23,10 +23,6 @@ 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. diff --git a/README.md b/README.md index 9431b0f..2ad6471 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ In addition, certain platforms and build-time options may require additional dep ### Building a release -Releases include a pre-built copy of the ``configure`` script and may be built using: +Release tarballs and release branches in git include a pre-built copy of the ``configure`` script and may be built using: ``` tar zxvf openssh-X.YpZ.tar.gz @@ -54,7 +54,7 @@ See the [Build-time Customisation](#build-time-customisation) section below for ### 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: +If building from the git master branch, 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 diff --git a/TODO b/TODO index b76529c..e9e2d96 100644 --- a/TODO +++ b/TODO @@ -7,7 +7,7 @@ Documentation: - Install FAQ? -- General FAQ on S/Key, TIS, RSA, RSA2, DSA, etc and suggestions on when it +- General FAQ on S/Key, TIS, RSA, RSA2, etc and suggestions on when it would be best to use them. - Create a Documentation/ directory? diff --git a/addr.c b/addr.c index 0e7cb1d..e207287 100644 --- a/addr.c +++ b/addr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: addr.c,v 1.8 2024/04/02 09:29:31 deraadt Exp $ */ +/* $OpenBSD: addr.c,v 1.9 2024/10/18 04:30:09 djm Exp $ */ /* * Copyright (c) 2004-2008 Damien Miller @@ -33,7 +33,7 @@ #define _SA(x) ((struct sockaddr *)(x)) -int +static int addr_unicast_masklen(int af) { switch (af) { @@ -59,7 +59,7 @@ masklen_valid(int af, u_int masklen) } } -int +static int addr_xaddr_to_sa(const struct xaddr *xa, struct sockaddr *sa, socklen_t *len, u_int16_t port) { @@ -138,7 +138,7 @@ addr_sa_to_xaddr(struct sockaddr *sa, socklen_t slen, struct xaddr *xa) return 0; } -int +static int addr_invert(struct xaddr *n) { int i; @@ -193,7 +193,7 @@ addr_netmask(int af, u_int l, struct xaddr *n) } } -int +static int addr_hostmask(int af, u_int l, struct xaddr *n) { if (addr_netmask(af, l, n) == -1 || addr_invert(n) == -1) @@ -228,7 +228,7 @@ addr_and(struct xaddr *dst, const struct xaddr *a, const struct xaddr *b) } } -int +static int addr_or(struct xaddr *dst, const struct xaddr *a, const struct xaddr *b) { int i; @@ -283,7 +283,7 @@ addr_cmp(const struct xaddr *a, const struct xaddr *b) } } -int +static int addr_is_all0s(const struct xaddr *a) { int i; @@ -330,7 +330,7 @@ addr_increment(struct xaddr *a) * Returns 0 if host portion of address is all-zeros, * -1 if not all zeros or on failure. */ -int +static int addr_host_is_all0s(const struct xaddr *a, u_int masklen) { struct xaddr tmp_addr, tmp_mask, tmp_result; @@ -344,7 +344,7 @@ addr_host_is_all0s(const struct xaddr *a, u_int masklen) } #if 0 -int +static int addr_host_to_all0s(struct xaddr *a, u_int masklen) { struct xaddr tmp_mask; @@ -402,7 +402,8 @@ addr_pton(const char *p, struct xaddr *n) return 0; } -int +#if 0 +static int addr_sa_pton(const char *h, const char *s, struct sockaddr *sa, socklen_t slen) { struct addrinfo hints, *ai; @@ -432,6 +433,7 @@ addr_sa_pton(const char *h, const char *s, struct sockaddr *sa, socklen_t slen) freeaddrinfo(ai); return 0; } +#endif int addr_ntop(const struct xaddr *n, char *p, size_t len) diff --git a/addr.h b/addr.h index 180e9fd..29438df 100644 --- a/addr.h +++ b/addr.h @@ -39,24 +39,13 @@ struct xaddr { #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); diff --git a/atomicio.c b/atomicio.c index 7650733..58a9512 100644 --- a/atomicio.c +++ b/atomicio.c @@ -31,13 +31,7 @@ #include #include -#ifdef HAVE_POLL_H #include -#else -# ifdef HAVE_SYS_POLL_H -# include -# endif -#endif #include #include #include diff --git a/audit-bsm.c b/audit-bsm.c index ccfcf6f..4bce22c 100644 --- a/audit-bsm.c +++ b/audit-bsm.c @@ -449,7 +449,7 @@ audit_event(struct ssh *ssh, ssh_audit_event_t event) break; default: - debug("%s: unhandled event %d", __func__, event); + debug_f("unhandled event %d", event); } } #endif /* BSM */ diff --git a/audit-linux.c b/audit-linux.c index 3fcbe5c..954eabe 100644 --- a/audit-linux.c +++ b/audit-linux.c @@ -51,6 +51,8 @@ linux_audit_record_event(int uid, const char *username, const char *hostname, else return 0; /* Must prevent login */ } + if (hostname != NULL && strcmp(hostname, "UNKNOWN") == 0) + hostname = NULL; rc = audit_log_acct_message(audit_fd, AUDIT_USER_LOGIN, NULL, "login", username ? username : "(unknown)", username == NULL ? uid : -1, hostname, ip, ttyn, success); @@ -117,7 +119,7 @@ audit_event(struct ssh *ssh, ssh_audit_event_t event) ssh_remote_ipaddr(ssh), "sshd", 0); break; default: - debug("%s: unhandled event %d", __func__, event); + debug_f("unhandled event %d", event); break; } } diff --git a/auth-krb5.c b/auth-krb5.c index c99e4e4..9d2f1f0 100644 --- a/auth-krb5.c +++ b/auth-krb5.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth-krb5.c,v 1.24 2021/04/03 06:18:40 djm Exp $ */ +/* $OpenBSD: auth-krb5.c,v 1.25 2025/09/29 21:29:22 dtucker Exp $ */ /* * Kerberos v5 authentication and ticket-passing routines. * diff --git a/auth-options.c b/auth-options.c index c89b1ee..90be7b0 100644 --- a/auth-options.c +++ b/auth-options.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth-options.c,v 1.101 2023/07/14 07:44:21 dtucker Exp $ */ +/* $OpenBSD: auth-options.c,v 1.102 2025/09/15 04:38:00 djm Exp $ */ /* * Copyright (c) 2018 Damien Miller * @@ -24,9 +24,7 @@ #include #include #include -#ifdef HAVE_STDINT_H -# include -#endif +#include #include #include #include @@ -157,6 +155,7 @@ cert_option_list(struct sshauthopt *opts, struct sshbuf *oblob, if (addr_match_cidr_list(NULL, allowed) == -1) { error("Certificate source-address " "contents invalid"); + free(allowed); goto out; } opts->required_from_host_cert = allowed; diff --git a/auth-pam.c b/auth-pam.c index 13c0a79..5591f09 100644 --- a/auth-pam.c +++ b/auth-pam.c @@ -229,7 +229,7 @@ pthread_join(sp_pthread_t thread, void **value) while (waitpid(thread, &status, 0) == -1) { if (errno == EINTR) continue; - fatal("%s: waitpid: %s", __func__, strerror(errno)); + fatal_f("waitpid: %s", strerror(errno)); } return (status); } @@ -287,10 +287,10 @@ sshpam_chauthtok_ruid(pam_handle_t *pamh, int flags) 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)); + fatal_f("setreuid failed: %s", strerror(errno)); result = pam_chauthtok(pamh, flags); if (setreuid(0, -1) == -1) - fatal("%s: setreuid failed: %s", __func__, strerror(errno)); + fatal_f("setreuid failed: %s", strerror(errno)); return result; } # define pam_chauthtok(a,b) (sshpam_chauthtok_ruid((a), (b))) @@ -302,9 +302,9 @@ sshpam_password_change_required(int reqd) extern struct sshauthopt *auth_opts; static int saved_port, saved_agent, saved_x11; - debug3("%s %d", __func__, reqd); + debug3_f("reqd=%d", reqd); if (sshpam_authctxt == NULL) - fatal("%s: PAM authctxt not initialized", __func__); + fatal_f("PAM authctxt not initialized"); sshpam_authctxt->force_pwchange = reqd; if (reqd) { saved_port = auth_opts->permit_port_forwarding_flag; @@ -331,22 +331,22 @@ import_environments(struct sshbuf *b) u_int n, i, num_env; int r; - debug3("PAM: %s entering", __func__); + debug3_f("entering"); #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)); + fatal_fr(r, "buffer error"); if (n > INT_MAX) - fatal("%s: invalid PAM account status %u", __func__, n); + fatal_f("invalid PAM account status %u", n); sshpam_account_status = (int)n; if ((r = sshbuf_get_u32(b, &n)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "buffer error"); 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)); + fatal_fr(r, "buffer error"); if (num_env > 1024) { fatal_f("received %u environment variables, expected <= 1024", num_env); @@ -355,13 +355,13 @@ import_environments(struct sshbuf *b) debug3("PAM: num env strings %u", 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)); + fatal_fr(r, "buffer error"); } 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)); + fatal_fr(r, "buffer error"); if (num_env > 1024) { fatal_f("received %u PAM env variables, expected <= 1024", num_env); @@ -369,7 +369,7 @@ import_environments(struct sshbuf *b) debug("PAM: num PAM env strings %u", 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)); + fatal_fr(r, "buffer error"); /* Errors are not fatal here */ if ((r = pam_putenv(sshpam_handle, env)) != PAM_SUCCESS) { error("PAM: pam_putenv: %s", @@ -378,7 +378,7 @@ import_environments(struct sshbuf *b) /* * 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. + * take ownership? We don't know, so it's safest just to leak. */ } #endif @@ -397,7 +397,7 @@ sshpam_thread_conv(int n, sshpam_const struct pam_message **msg, int r, i; u_char status; - debug3("PAM: %s entering, %d messages", __func__, n); + debug3_f("PAM: entering, %d messages", n); *resp = NULL; if (data == NULL) { @@ -467,6 +467,32 @@ sshpam_thread_conv(int n, sshpam_const struct pam_message **msg, return (PAM_CONV_ERR); } +static int +check_pam_user(Authctxt *authctxt) +{ + const char *pam_user; + + if (authctxt == NULL || authctxt->pw == NULL || + authctxt->pw->pw_name == NULL) + fatal_f("PAM authctxt user not initialized"); + + if ((sshpam_err = pam_get_item(sshpam_handle, PAM_USER, + (sshpam_const void **) &pam_user)) != PAM_SUCCESS) + return sshpam_err; + + if (pam_user == NULL) { + debug("PAM error: PAM_USER is NULL"); + return PAM_USER_UNKNOWN; + } + + if (strcmp(authctxt->pw->pw_name, pam_user) != 0) { + debug("PAM user \"%s\" does not match expected \"%s\"", + pam_user, authctxt->pw->pw_name); + return PAM_USER_UNKNOWN; + } + return PAM_SUCCESS; +} + /* * Authentication thread. */ @@ -507,10 +533,10 @@ sshpam_thread(void *ctxtp) sshpam_conv.appdata_ptr = ctxt; if (sshpam_authctxt == NULL) - fatal("%s: PAM authctxt not initialized", __func__); + fatal_f("PAM authctxt not initialized"); if ((buffer = sshbuf_new()) == NULL) - fatal("%s: sshbuf_new failed", __func__); + fatal_f("sshbuf_new failed"); sshpam_err = pam_set_item(sshpam_handle, PAM_CONV, (const void *)&sshpam_conv); @@ -521,6 +547,8 @@ sshpam_thread(void *ctxtp) sshpam_set_maxtries_reached(1); if (sshpam_err != PAM_SUCCESS) goto auth_fail; + if ((sshpam_err = check_pam_user(sshpam_authctxt)) != PAM_SUCCESS) + goto auth_fail; if (!do_pam_account()) { sshpam_err = PAM_ACCT_EXPIRED; @@ -535,38 +563,38 @@ sshpam_thread(void *ctxtp) } if ((r = sshbuf_put_cstring(buffer, "OK")) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "buffer error"); #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)); + fatal_fr(r, "buffer error"); /* 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__); + fatal_f("too many environment strings"); } if ((r = sshbuf_put_u32(buffer, i)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "buffer error"); 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)); + fatal_fr(r, "buffer error"); } /* 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__); + fatal_f("too many PAM environment strings"); } if ((r = sshbuf_put_u32(buffer, i)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "buffer error"); 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)); + fatal_fr(r, "buffer error"); } #endif /* UNSUPPORTED_POSIX_THREADS_HACK */ @@ -578,7 +606,7 @@ sshpam_thread(void *ctxtp) auth_fail: if ((r = sshbuf_put_cstring(buffer, pam_strerror(sshpam_handle, sshpam_err))) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "buffer error"); /* 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); @@ -597,7 +625,7 @@ sshpam_thread_cleanup(void) { struct pam_ctxt *ctxt = cleanup_ctxt; - debug3("PAM: %s entering", __func__); + debug3_f("entering"); if (ctxt != NULL && ctxt->pam_thread != 0) { pthread_cancel(ctxt->pam_thread); pthread_join(ctxt->pam_thread, NULL); @@ -612,7 +640,7 @@ 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); + debug3_f("PAM: entering, %d messages", n); return (PAM_CONV_ERR); } @@ -625,7 +653,7 @@ sshpam_store_conv(int n, sshpam_const struct pam_message **msg, struct pam_response *reply; int r, i; - debug3("PAM: %s called with %d messages", __func__, n); + debug3_f("PAM: called with %d messages", n); *resp = NULL; if (n <= 0 || n > PAM_MAX_NUM_MSG) @@ -686,8 +714,7 @@ sshpam_cleanup(void) static int sshpam_init(struct ssh *ssh, Authctxt *authctxt) { - const char *pam_user, *user = authctxt->user; - const char **ptr_pam_user = &pam_user; + const char *user = authctxt->user; int r; if (options.pam_service_name == NULL) @@ -706,12 +733,8 @@ sshpam_init(struct ssh *ssh, Authctxt *authctxt) } 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; + if ((sshpam_err = check_pam_user(authctxt)) != PAM_SUCCESS) + fatal("PAM user mismatch"); } debug("PAM: initializing for \"%s\" with service \"%s\"", user, options.pam_service_name); @@ -735,7 +758,7 @@ sshpam_init(struct ssh *ssh, Authctxt *authctxt) sshpam_laddr = get_local_ipaddr( ssh_packet_get_connection_in(ssh)); } - if (sshpam_rhost != NULL) { + if (sshpam_rhost != NULL && strcmp(sshpam_rhost, "UNKNOWN") != 0) { debug("PAM: setting PAM_RHOST to \"%s\"", sshpam_rhost); sshpam_err = pam_set_item(sshpam_handle, PAM_RHOST, sshpam_rhost); @@ -788,7 +811,7 @@ expose_authinfo(const char *caller) auth_info = xstrdup(""); else if ((auth_info = sshbuf_dup_string( sshpam_authctxt->session_info)) == NULL) - fatal("%s: sshbuf_dup_string failed", __func__); + fatal_f("sshbuf_dup_string failed"); debug2("%s: auth information in SSH_AUTH_INFO_0", caller); do_pam_putenv("SSH_AUTH_INFO_0", auth_info); @@ -801,7 +824,7 @@ sshpam_init_ctx(Authctxt *authctxt) struct pam_ctxt *ctxt; int result, socks[2]; - debug3("PAM: %s entering", __func__); + debug3_f("entering"); /* * Refuse to start if we don't have PAM enabled or do_pam_account * has previously failed. @@ -851,9 +874,9 @@ sshpam_query(void *ctx, char **name, char **info, size_t len, mlen, nmesg = 0; int r; - debug3("PAM: %s entering", __func__); + debug3_f("entering"); if ((buffer = sshbuf_new()) == NULL) - fatal("%s: sshbuf_new failed", __func__); + fatal_f("sshbuf_new failed"); *name = xstrdup(""); *info = xstrdup(""); *prompts = xmalloc(sizeof(char *)); @@ -865,7 +888,7 @@ sshpam_query(void *ctx, char **name, char **info, fatal_f("too many query messages"); 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)); + fatal_fr(r, "buffer error"); switch (type) { case PAM_PROMPT_ECHO_ON: case PAM_PROMPT_ECHO_OFF: @@ -966,7 +989,7 @@ fake_password(const char *wire_password) size_t i, l = wire_password != NULL ? strlen(wire_password) : 0; if (l >= INT_MAX) - fatal("%s: password length too long: %zu", __func__, l); + fatal_f("password length too long: %zu", l); ret = malloc(l + 1); if (ret == NULL) @@ -986,7 +1009,7 @@ sshpam_respond(void *ctx, u_int num, char **resp) char *fake; int r; - debug2("PAM: %s entering, %u responses", __func__, num); + debug2_f("PAM: entering, %u responses", num); switch (ctxt->pam_done) { case 1: sshpam_authenticated = 1; @@ -1001,16 +1024,16 @@ sshpam_respond(void *ctx, u_int num, char **resp) return (-1); } if ((buffer = sshbuf_new()) == NULL) - fatal("%s: sshbuf_new failed", __func__); + fatal_f("sshbuf_new failed"); 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)); + fatal_fr(r, "buffer error"); } else { fake = fake_password(*resp); if ((r = sshbuf_put_cstring(buffer, fake)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "buffer error"); free(fake); } if (ssh_msg_send(ctxt->pam_psock, PAM_AUTHTOK, buffer) == -1) { @@ -1026,7 +1049,7 @@ sshpam_free_ctx(void *ctxtp) { struct pam_ctxt *ctxt = ctxtp; - debug3("PAM: %s entering", __func__); + debug3_f("entering"); sshpam_thread_cleanup(); free(ctxt); /* @@ -1078,7 +1101,7 @@ finish_pam(void) u_int do_pam_account(void) { - debug("%s: called", __func__); + debug_f("called"); if (sshpam_account_status != -1) return (sshpam_account_status); @@ -1131,7 +1154,7 @@ sshpam_tty_conv(int n, sshpam_const struct pam_message **msg, struct pam_response *reply; int i; - debug3("PAM: %s called with %d messages", __func__, n); + debug3_f("PAM: called with %d messages", n); *resp = NULL; @@ -1292,7 +1315,7 @@ sshpam_passwd_conv(int n, sshpam_const struct pam_message **msg, int r, i; size_t len; - debug3("PAM: %s called with %d messages", __func__, n); + debug3_f("PAM: called with %d messages", n); *resp = NULL; @@ -1378,6 +1401,8 @@ sshpam_auth_passwd(Authctxt *authctxt, const char *password) sshpam_err = pam_authenticate(sshpam_handle, flags); sshpam_password = NULL; free(fake); + if (sshpam_err == PAM_SUCCESS) + sshpam_err = check_pam_user(authctxt); if (sshpam_err == PAM_MAXTRIES) sshpam_set_maxtries_reached(1); if (sshpam_err == PAM_SUCCESS && authctxt->valid) { diff --git a/auth-passwd.c b/auth-passwd.c index 347d91e..a9d7688 100644 --- a/auth-passwd.c +++ b/auth-passwd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth-passwd.c,v 1.48 2020/10/18 11:32:01 djm Exp $ */ +/* $OpenBSD: auth-passwd.c,v 1.49 2025/05/08 17:32:53 tedu Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -133,7 +133,7 @@ static void warn_expiry(Authctxt *authctxt, auth_session_t *as) { int r; - quad_t pwtimeleft, actimeleft, daysleft, pwwarntime, acwarntime; + int64_t pwtimeleft, actimeleft, daysleft, pwwarntime, acwarntime; pwwarntime = acwarntime = TWO_WEEKS; diff --git a/auth-rhosts.c b/auth-rhosts.c index d5d2c7a..031186f 100644 --- a/auth-rhosts.c +++ b/auth-rhosts.c @@ -21,9 +21,7 @@ #include #include -#ifdef HAVE_NETGROUP_H -# include -#endif +#include #include #include #include diff --git a/auth-shadow.c b/auth-shadow.c index b1e3aa9..81b31b5 100644 --- a/auth-shadow.c +++ b/auth-shadow.c @@ -74,7 +74,7 @@ auth_shadow_acctexpired(struct spwd *spw) if ((r = sshbuf_putf(loginmsg, "Your account will expire in %lld day%s.\n", daysleft, daysleft == 1 ? "" : "s")) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "buffer error"); } return 0; @@ -133,7 +133,7 @@ auth_shadow_pwexpired(Authctxt *ctxt) if ((r = sshbuf_putf(loginmsg, "Your password will expire in %d day%s.\n", daysleft, daysleft == 1 ? "" : "s")) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "buffer error"); } return 0; diff --git a/auth.c b/auth.c index 9a6e5a3..8d94047 100644 --- a/auth.c +++ b/auth.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth.c,v 1.162 2024/09/15 01:18:26 djm Exp $ */ +/* $OpenBSD: auth.c,v 1.163 2025/09/15 04:39:15 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -35,9 +35,7 @@ #include #include #include -#ifdef HAVE_PATHS_H -# include -#endif +#include #include #ifdef HAVE_LOGIN_H #include @@ -758,6 +756,7 @@ auth_activate_options(struct ssh *ssh, struct sshauthopt *opts) error("Inconsistent authentication options: %s", emsg); return -1; } + sshauthopt_free(old); return 0; } diff --git a/auth2-chall.c b/auth2-chall.c index 021df82..a6d9165 100644 --- a/auth2-chall.c +++ b/auth2-chall.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth2-chall.c,v 1.54 2020/10/18 11:32:01 djm Exp $ */ +/* $OpenBSD: auth2-chall.c,v 1.57 2025/10/02 08:38:43 dtucker Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. * Copyright (c) 2001 Per Allansson. All rights reserved. @@ -154,7 +154,7 @@ kbdint_next_device(Authctxt *authctxt, KbdintAuthctxt *kbdintctxt) { size_t len; char *t; - int i; + size_t i; if (kbdintctxt->device) kbdint_reset_device(kbdintctxt); @@ -165,11 +165,15 @@ kbdint_next_device(Authctxt *authctxt, KbdintAuthctxt *kbdintctxt) if (len == 0) break; for (i = 0; devices[i]; i++) { + if (i >= sizeof(kbdintctxt->devices_done) * 8 || + i >= sizeof(devices) / sizeof(devices[0])) + fatal_f("internal error: too may devices"); if ((kbdintctxt->devices_done & (1 << i)) != 0 || !auth2_method_allowed(authctxt, "keyboard-interactive", devices[i]->name)) continue; - if (strncmp(kbdintctxt->devices, devices[i]->name, + if (strlen(devices[i]->name) == len && + memcmp(kbdintctxt->devices, devices[i]->name, len) == 0) { kbdintctxt->device = devices[i]; kbdintctxt->devices_done |= 1 << i; diff --git a/auth2-hostbased.c b/auth2-hostbased.c index eb21479..9d8b860 100644 --- a/auth2-hostbased.c +++ b/auth2-hostbased.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth2-hostbased.c,v 1.53 2024/05/17 00:30:23 djm Exp $ */ +/* $OpenBSD: auth2-hostbased.c,v 1.55 2025/08/14 09:26:53 dtucker Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -213,8 +213,17 @@ hostbased_key_allowed(struct ssh *ssh, struct passwd *pw, if (sshkey_is_cert(key) && sshkey_cert_check_authority_now(key, 1, 0, 0, lookup, &reason)) { - error("%s", reason); - auth_debug_add("%s", reason); + if ((fp = sshkey_fingerprint(key->cert->signature_key, + options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) + fatal_f("sshkey_fingerprint fail"); + error("Refusing certificate ID \"%s\" serial=%llu signed by " + "%s CA %s: %s", key->cert->key_id, + (unsigned long long)key->cert->serial, + sshkey_type(key->cert->signature_key), fp, reason); + auth_debug_add("Refused Certificate ID \"%s\" serial=%llu: %s", + key->cert->key_id, (unsigned long long)key->cert->serial, + reason); + free(fp); return 0; } diff --git a/auth2-pubkey.c b/auth2-pubkey.c index 7580db7..15ad300 100644 --- a/auth2-pubkey.c +++ b/auth2-pubkey.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth2-pubkey.c,v 1.120 2024/05/17 00:30:23 djm Exp $ */ +/* $OpenBSD: auth2-pubkey.c,v 1.124 2025/08/14 09:44:39 dtucker Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2010 Damien Miller. All rights reserved. @@ -30,9 +30,7 @@ #include #include -#ifdef HAVE_PATHS_H -# include -#endif +#include #include #include #include @@ -41,6 +39,11 @@ #include #include #include +#ifdef USE_SYSTEM_GLOB +# include +#else +# include "openbsd-compat/glob.h" +#endif #include "xmalloc.h" #include "ssh.h" @@ -319,20 +322,51 @@ match_principals_file(struct passwd *pw, char *file, struct sshkey_cert *cert, struct sshauthopt **authoptsp) { FILE *f; - int success; + int r, success = 0; + size_t i; + glob_t gl; + struct sshauthopt *opts = NULL; if (authoptsp != NULL) *authoptsp = NULL; temporarily_use_uid(pw); - debug("trying authorized principals file %s", file); - if ((f = auth_openprincipals(file, pw, options.strict_modes)) == NULL) { - restore_uid(); + r = glob(file, 0, NULL, &gl); + restore_uid(); + if (r != 0) { + if (r != GLOB_NOMATCH) { + logit_f("glob \"%s\" failed", file); + } return 0; + } else if (gl.gl_pathc > INT_MAX) { + fatal_f("too many glob results for \"%s\"", file); + } else if (gl.gl_pathc > 1) { + debug2_f("glob \"%s\" returned %zu matches", file, + gl.gl_pathc); + } + for (i = 0; !success && i < gl.gl_pathc; i++) { + temporarily_use_uid(pw); + debug("trying authorized principals file %s", file); + if ((f = auth_openprincipals(gl.gl_pathv[i], pw, + options.strict_modes)) == NULL) { + restore_uid(); + continue; + } + success = auth_process_principals(f, gl.gl_pathv[i], + cert, &opts); + fclose(f); + restore_uid(); + if (!success) { + sshauthopt_free(opts); + opts = NULL; + } } - success = auth_process_principals(f, file, cert, authoptsp); - fclose(f); - restore_uid(); + globfree(&gl); + if (success && authoptsp != NULL) { + *authoptsp = opts; + opts = NULL; + } + sshauthopt_free(opts); return success; } @@ -554,8 +588,14 @@ user_cert_trusted_ca(struct passwd *pw, struct sshkey *key, if ((final_opts = sshauthopt_merge(principals_opts, cert_opts, &reason)) == NULL) { fail_reason: - error("%s", reason); - auth_debug_add("%s", reason); + error("Refusing certificate ID \"%s\" serial=%llu " + "signed by %s CA %s: %s", key->cert->key_id, + (unsigned long long)key->cert->serial, + sshkey_type(key->cert->signature_key), ca_fp, + reason); + auth_debug_add("Refused Certificate ID \"%s\" " + "serial=%llu: %s", key->cert->key_id, + (unsigned long long)key->cert->serial, reason); goto out; } } @@ -753,8 +793,8 @@ int user_key_allowed(struct ssh *ssh, struct passwd *pw, struct sshkey *key, int auth_attempt, struct sshauthopt **authoptsp) { - u_int success = 0, i; - char *file, *conn_id; + u_int success = 0, i, j; + char *file = NULL, *conn_id; struct sshauthopt *opts = NULL; const char *rdomain, *remote_ip, *remote_host; @@ -776,17 +816,40 @@ user_key_allowed(struct ssh *ssh, struct passwd *pw, struct sshkey *key, remote_ip, ssh_remote_port(ssh)); for (i = 0; !success && i < options.num_authkeys_files; i++) { + int r; + glob_t gl; + if (strcasecmp(options.authorized_keys_files[i], "none") == 0) continue; file = expand_authorized_keys( options.authorized_keys_files[i], pw); - success = user_key_allowed2(pw, key, file, - remote_ip, remote_host, &opts); - free(file); - if (!success) { - sshauthopt_free(opts); - opts = NULL; + temporarily_use_uid(pw); + r = glob(file, 0, NULL, &gl); + restore_uid(); + if (r != 0) { + if (r != GLOB_NOMATCH) { + logit_f("glob \"%s\" failed", file); + } + free(file); + file = NULL; + continue; + } else if (gl.gl_pathc > INT_MAX) { + fatal_f("too many glob results for \"%s\"", file); + } else if (gl.gl_pathc > 1) { + debug2_f("glob \"%s\" returned %zu matches", file, + gl.gl_pathc); + } + for (j = 0; !success && j < gl.gl_pathc; j++) { + success = user_key_allowed2(pw, key, gl.gl_pathv[j], + remote_ip, remote_host, &opts); + if (!success) { + sshauthopt_free(opts); + opts = NULL; + } } + free(file); + file = NULL; + globfree(&gl); } if (success) goto out; diff --git a/auth2-pubkeyfile.c b/auth2-pubkeyfile.c index 31e7481..9d59e56 100644 --- a/auth2-pubkeyfile.c +++ b/auth2-pubkeyfile.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth2-pubkeyfile.c,v 1.4 2023/03/05 05:34:09 dtucker Exp $ */ +/* $OpenBSD: auth2-pubkeyfile.c,v 1.6 2025/08/14 10:03:44 dtucker Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2010 Damien Miller. All rights reserved. @@ -344,15 +344,15 @@ auth_check_authkey_line(struct passwd *pw, struct sshkey *key, /* Parse and check options present in certificate */ if ((certopts = sshauthopt_from_cert(key)) == NULL) { reason = "Invalid certificate options"; - goto fail_reason; + goto cert_fail_reason; } if (auth_authorise_keyopts(pw, certopts, 0, remote_ip, remote_host, loc) != 0) { reason = "Refused by certificate options"; - goto fail_reason; + goto cert_fail_reason; } if ((finalopts = sshauthopt_merge(keyopts, certopts, &reason)) == NULL) - goto fail_reason; + goto cert_fail_reason; /* * If the user has specified a list of principals as @@ -362,12 +362,12 @@ auth_check_authkey_line(struct passwd *pw, struct sshkey *key, if (keyopts->cert_principals != NULL && !match_principals_option(keyopts->cert_principals, key->cert)) { reason = "Certificate does not contain an authorized principal"; - goto fail_reason; + goto cert_fail_reason; } if (sshkey_cert_check_authority_now(key, 0, 0, 0, keyopts->cert_principals == NULL ? pw->pw_name : NULL, &reason) != 0) - goto fail_reason; + goto cert_fail_reason; verbose("Accepted certificate ID \"%s\" (serial %llu) " "signed by CA %s %s found at %s", @@ -386,8 +386,17 @@ auth_check_authkey_line(struct passwd *pw, struct sshkey *key, ret = 0; goto out; + cert_fail_reason: + error("Refusing certificate ID \"%s\" serial=%llu " + "signed by %s CA %s via %s: %s", key->cert->key_id, + (unsigned long long)key->cert->serial, + sshkey_type(key->cert->signature_key), fp, loc, reason); + auth_debug_add("Refused Certificate ID \"%s\" serial=%llu: %s", + key->cert->key_id, (unsigned long long)key->cert->serial, reason); + goto out; + fail_reason: - error("%s", reason); + error("%s at %s", reason, loc); auth_debug_add("%s", reason); out: free(fp); diff --git a/auth2.c b/auth2.c index 67dec88..b9bb46f 100644 --- a/auth2.c +++ b/auth2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth2.c,v 1.169 2024/05/17 00:30:23 djm Exp $ */ +/* $OpenBSD: auth2.c,v 1.170 2025/01/17 00:09:41 dtucker Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -145,7 +145,7 @@ userauth_send_banner(struct ssh *ssh, const char *msg) (r = sshpkt_put_cstring(ssh, "")) != 0 || /* language, unused */ (r = sshpkt_send(ssh)) != 0) fatal_fr(r, "send packet"); - debug("%s: sent", __func__); + debug_f("sent"); } static void @@ -238,7 +238,7 @@ user_specific_delay(const char *user) /* 0-4.2 ms of delay */ delay = (double)PEEK_U32(hash) / 1000 / 1000 / 1000 / 1000; freezero(hash, len); - debug3_f("user specific delay %0.3lfms", delay/1000); + debug3_f("user specific delay %0.3lfms", delay*1000); return MIN_FAIL_DELAY_SECONDS + delay; } diff --git a/authfd.c b/authfd.c index e04ad0c..2bbe646 100644 --- a/authfd.c +++ b/authfd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: authfd.c,v 1.134 2023/12/18 14:46:56 djm Exp $ */ +/* $OpenBSD: authfd.c,v 1.136 2025/08/29 03:50:38 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -505,7 +505,7 @@ encode_dest_constraint(struct sshbuf *m, const struct dest_constraint *dc) static int encode_constraints(struct sshbuf *m, u_int life, u_int confirm, - u_int maxsign, const char *provider, + const char *provider, struct dest_constraint **dest_constraints, size_t ndest_constraints, int cert_only, struct sshkey **certs, size_t ncerts) { @@ -522,11 +522,6 @@ encode_constraints(struct sshbuf *m, u_int life, u_int confirm, if ((r = sshbuf_put_u8(m, SSH_AGENT_CONSTRAIN_CONFIRM)) != 0) goto out; } - if (maxsign != 0) { - if ((r = sshbuf_put_u8(m, SSH_AGENT_CONSTRAIN_MAXSIGN)) != 0 || - (r = sshbuf_put_u32(m, maxsign)) != 0) - goto out; - } if (provider != NULL) { if ((r = sshbuf_put_u8(m, SSH_AGENT_CONSTRAIN_EXTENSION)) != 0 || @@ -585,13 +580,12 @@ encode_constraints(struct sshbuf *m, u_int life, u_int confirm, */ int ssh_add_identity_constrained(int sock, struct sshkey *key, - const char *comment, u_int life, u_int confirm, u_int maxsign, + const char *comment, u_int life, u_int confirm, const char *provider, struct dest_constraint **dest_constraints, size_t ndest_constraints) { struct sshbuf *msg; - int r, constrained = (life || confirm || maxsign || - provider || dest_constraints); + int r, constrained = (life || confirm || provider || dest_constraints); u_char type; if ((msg = sshbuf_new()) == NULL) @@ -601,8 +595,6 @@ ssh_add_identity_constrained(int sock, struct sshkey *key, #ifdef WITH_OPENSSL case KEY_RSA: case KEY_RSA_CERT: - case KEY_DSA: - case KEY_DSA_CERT: case KEY_ECDSA: case KEY_ECDSA_CERT: case KEY_ECDSA_SK: @@ -612,14 +604,11 @@ ssh_add_identity_constrained(int sock, struct sshkey *key, case KEY_ED25519_CERT: case KEY_ED25519_SK: case KEY_ED25519_SK_CERT: - case KEY_XMSS: - case KEY_XMSS_CERT: type = constrained ? SSH2_AGENTC_ADD_ID_CONSTRAINED : SSH2_AGENTC_ADD_IDENTITY; if ((r = sshbuf_put_u8(msg, type)) != 0 || - (r = sshkey_private_serialize_maxsign(key, msg, maxsign, - 0)) != 0 || + (r = sshkey_private_serialize(key, msg)) != 0 || (r = sshbuf_put_cstring(msg, comment)) != 0) goto out; break; @@ -628,8 +617,8 @@ ssh_add_identity_constrained(int sock, struct sshkey *key, goto out; } if (constrained && - (r = encode_constraints(msg, life, confirm, maxsign, - provider, dest_constraints, ndest_constraints, 0, NULL, 0)) != 0) + (r = encode_constraints(msg, life, confirm, provider, + dest_constraints, ndest_constraints, 0, NULL, 0)) != 0) goto out; if ((r = ssh_request_reply_decode(sock, msg)) != 0) goto out; @@ -705,7 +694,7 @@ ssh_update_card(int sock, int add, const char *reader_id, const char *pin, (r = sshbuf_put_cstring(msg, pin)) != 0) goto out; if (constrained && - (r = encode_constraints(msg, life, confirm, 0, NULL, + (r = encode_constraints(msg, life, confirm, NULL, dest_constraints, ndest_constraints, cert_only, certs, ncerts)) != 0) goto out; diff --git a/authfd.h b/authfd.h index c1e4b40..958d480 100644 --- a/authfd.h +++ b/authfd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: authfd.h,v 1.52 2023/12/18 14:46:56 djm Exp $ */ +/* $OpenBSD: authfd.h,v 1.53 2025/08/29 03:50:38 djm Exp $ */ /* * Author: Tatu Ylonen @@ -48,9 +48,8 @@ int ssh_lock_agent(int sock, int lock, const char *password); int ssh_fetch_identitylist(int sock, struct ssh_identitylist **idlp); void ssh_free_identitylist(struct ssh_identitylist *idl); int ssh_add_identity_constrained(int sock, struct sshkey *key, - const char *comment, u_int life, u_int confirm, u_int maxsign, - const char *provider, struct dest_constraint **dest_constraints, - size_t ndest_constraints); + const char *comment, u_int life, u_int confirm, const char *provider, + struct dest_constraint **dest_constraints, size_t ndest_constraints); int ssh_agent_has_key(int sock, const struct sshkey *key); int ssh_remove_identity(int sock, const struct sshkey *key); int ssh_update_card(int sock, int add, const char *reader_id, @@ -106,7 +105,6 @@ int ssh_agent_bind_hostkey(int sock, const struct sshkey *key, #define SSH_AGENT_CONSTRAIN_LIFETIME 1 #define SSH_AGENT_CONSTRAIN_CONFIRM 2 -#define SSH_AGENT_CONSTRAIN_MAXSIGN 3 #define SSH_AGENT_CONSTRAIN_EXTENSION 255 /* extended failure messages */ diff --git a/authfile.c b/authfile.c index 445f2dd..16e02d9 100644 --- a/authfile.c +++ b/authfile.c @@ -1,4 +1,4 @@ -/* $OpenBSD: authfile.c,v 1.144 2023/03/14 07:26:25 dtucker Exp $ */ +/* $OpenBSD: authfile.c,v 1.147 2025/08/29 03:50:38 djm Exp $ */ /* * Copyright (c) 2000, 2013 Markus Friedl. All rights reserved. * @@ -49,8 +49,6 @@ #include "ssherr.h" #include "krl.h" -#define MAX_KEY_FILE_SIZE (1024 * 1024) - /* Save a key blob to a file */ static int sshkey_save_private_blob(struct sshbuf *keybuf, const char *filename) @@ -133,8 +131,6 @@ sshkey_load_private_type(int type, const char *filename, const char *passphrase, goto out; r = sshkey_load_private_type_fd(fd, type, passphrase, keyp, commentp); - if (r == 0 && keyp && *keyp) - r = sshkey_set_filename(*keyp, filename); out: close(fd); return r; @@ -186,8 +182,6 @@ sshkey_load_pubkey_from_private(const char *filename, struct sshkey **pubkeyp) (r = sshkey_parse_pubkey_from_private_fileblob_type(buffer, KEY_UNSPEC, &pubkey)) != 0) goto out; - if ((r = sshkey_set_filename(pubkey, filename)) != 0) - goto out; /* success */ if (pubkeyp != NULL) { *pubkeyp = pubkey; @@ -330,11 +324,9 @@ sshkey_load_private_cert(int type, const char *filename, const char *passphrase, switch (type) { #ifdef WITH_OPENSSL case KEY_RSA: - case KEY_DSA: case KEY_ECDSA: #endif /* WITH_OPENSSL */ case KEY_ED25519: - case KEY_XMSS: case KEY_UNSPEC: break; default: diff --git a/buildpkg.sh.in b/buildpkg.sh.in index 15555cd..9a3bd1d 100644 --- a/buildpkg.sh.in +++ b/buildpkg.sh.in @@ -34,7 +34,7 @@ SSHDGID=67 # Default privsep gid #USR_LOCAL_IS_SYMLINK=yes # System V init run levels SYSVINITSTART=S98 -SYSVINITSTOPT=K30 +SYSVINITSTOP=K30 # We will source these if they exist POST_MAKE_INSTALL_FIXES=./pkg-post-make-install-fixes.sh POST_PROTOTYPE_EDITS=./pkg-post-prototype-edit.sh @@ -270,13 +270,13 @@ else cat > space << _EOF # extra space required by start/stop links added by installf # in postinstall -$TEST_DIR/etc/rc0.d/${SYSVINITSTOPT}${SYSVINIT_NAME} 0 1 +$TEST_DIR/etc/rc0.d/${SYSVINITSTOP}${SYSVINIT_NAME} 0 1 $TEST_DIR/etc/rc2.d/${SYSVINITSTART}${SYSVINIT_NAME} 0 1 _EOF [ "$RC1_D" = no ] || \ - echo "$TEST_DIR/etc/rc1.d/${SYSVINITSTOPT}${SYSVINIT_NAME} 0 1" >> space + echo "$TEST_DIR/etc/rc1.d/${SYSVINITSTOP}${SYSVINIT_NAME} 0 1" >> space [ "$RCS_D" = yes ] && \ - echo "$TEST_DIR/etc/rcS.d/${SYSVINITSTOPT}${SYSVINIT_NAME} 0 1" >> space + echo "$TEST_DIR/etc/rcS.d/${SYSVINITSTOP}${SYSVINIT_NAME} 0 1" >> space fi ## Build preinstall file @@ -338,17 +338,17 @@ else if [ "\${USE_SYM_LINKS}" = yes ] then [ "$RCS_D" = yes ] && \\ - installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rcS.d/${SYSVINITSTOPT}${SYSVINIT_NAME}=../init.d/${SYSVINIT_NAME} s - installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rc0.d/${SYSVINITSTOPT}${SYSVINIT_NAME}=../init.d/${SYSVINIT_NAME} s + installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rcS.d/${SYSVINITSTOP}${SYSVINIT_NAME}=../init.d/${SYSVINIT_NAME} s + installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rc0.d/${SYSVINITSTOP}${SYSVINIT_NAME}=../init.d/${SYSVINIT_NAME} s [ "$RC1_D" = no ] || \\ - installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rc1.d/${SYSVINITSTOPT}${SYSVINIT_NAME}=../init.d/${SYSVINIT_NAME} s + installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rc1.d/${SYSVINITSTOP}${SYSVINIT_NAME}=../init.d/${SYSVINIT_NAME} s installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rc2.d/${SYSVINITSTART}${SYSVINIT_NAME}=../init.d/${SYSVINIT_NAME} s else [ "$RCS_D" = yes ] && \\ - installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rcS.d/${SYSVINITSTOPT}${SYSVINIT_NAME}=\${PKG_INSTALL_ROOT}$TEST_DIR/etc/init.d/${SYSVINIT_NAME} l - installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rc0.d/${SYSVINITSTOPT}${SYSVINIT_NAME}=\${PKG_INSTALL_ROOT}$TEST_DIR/etc/init.d/${SYSVINIT_NAME} l + installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rcS.d/${SYSVINITSTOP}${SYSVINIT_NAME}=\${PKG_INSTALL_ROOT}$TEST_DIR/etc/init.d/${SYSVINIT_NAME} l + installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rc0.d/${SYSVINITSTOP}${SYSVINIT_NAME}=\${PKG_INSTALL_ROOT}$TEST_DIR/etc/init.d/${SYSVINIT_NAME} l [ "$RC1_D" = no ] || \\ - installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rc1.d/${SYSVINITSTOPT}${SYSVINIT_NAME}=\${PKG_INSTALL_ROOT}$TEST_DIR/etc/init.d/${SYSVINIT_NAME} l + installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rc1.d/${SYSVINITSTOP}${SYSVINIT_NAME}=\${PKG_INSTALL_ROOT}$TEST_DIR/etc/init.d/${SYSVINIT_NAME} l installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rc2.d/${SYSVINITSTART}${SYSVINIT_NAME}=\${PKG_INSTALL_ROOT}$TEST_DIR/etc/init.d/${SYSVINIT_NAME} l fi fi diff --git a/channels.c b/channels.c index a23fde4..80014ff 100644 --- a/channels.c +++ b/channels.c @@ -1,4 +1,4 @@ -/* $OpenBSD: channels.c,v 1.439 2024/07/25 22:40:08 djm Exp $ */ +/* $OpenBSD: channels.c,v 1.452 2025/10/07 08:02:32 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -46,9 +46,7 @@ #include #include #include -#ifdef HAVE_SYS_TIME_H -# include -#endif +#include #include #include @@ -57,13 +55,9 @@ #include #include #include -#ifdef HAVE_POLL_H #include -#endif #include -#ifdef HAVE_STDINT_H -# include -#endif +#include #include #include #include @@ -94,6 +88,8 @@ #define NUM_SOCKS 10 /* -- X11 forwarding */ +/* X11 port for display :0 */ +#define X11_BASE_PORT 6000 /* Maximum number of fake X11 displays to try. */ #define MAX_DISPLAYS 1000 @@ -210,6 +206,10 @@ struct ssh_channels { /* Global timeout for all OPEN channels */ int global_deadline; time_t lastused; + /* pattern-lists used to classify channels as bulk */ + char *bulk_classifier_tty, *bulk_classifier_notty; + /* Number of active bulk channels (set by channel_handler) */ + u_int nbulk; }; /* helper */ @@ -237,6 +237,8 @@ channel_init_channels(struct ssh *ssh) sc->channels_alloc = 10; sc->channels = xcalloc(sc->channels_alloc, sizeof(*sc->channels)); sc->IPv4or6 = AF_UNSPEC; + sc->bulk_classifier_tty = xstrdup(CHANNEL_BULK_TTY); + sc->bulk_classifier_notty = xstrdup(CHANNEL_BULK_NOTTY); channel_handler_init(sc); ssh->chanctxt = sc; @@ -355,6 +357,17 @@ lookup_timeout(struct ssh *ssh, const char *type) return 0; } +static void +channel_classify(struct ssh *ssh, Channel *c) +{ + struct ssh_channels *sc = ssh->chanctxt; + const char *type = c->xctype == NULL ? c->ctype : c->xctype; + const char *classifier = (c->isatty || c->remote_has_tty) ? + sc->bulk_classifier_tty : sc->bulk_classifier_notty; + + c->bulk = type != NULL && match_pattern_list(type, classifier, 0) == 1; +} + /* * 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 @@ -373,6 +386,7 @@ channel_set_xtype(struct ssh *ssh, int id, const char *xctype) c->xctype = xstrdup(xctype); /* Type has changed, so look up inactivity deadline again */ c->inactive_deadline = lookup_timeout(ssh, c->xctype); + channel_classify(ssh, c); debug2_f("labeled channel %d as %s (inactive timeout %u)", id, xctype, c->inactive_deadline); } @@ -409,6 +423,13 @@ channel_get_expiry(struct ssh *ssh, Channel *c) return expiry; } +/* Returns non-zero if there is an open, non-interactive channel */ +int +channel_has_bulk(struct ssh *ssh) +{ + return ssh->chanctxt != NULL && ssh->chanctxt->nbulk != 0; +} + /* * Register filedescriptors for a channel, used when allocating a channel or * when the channel consumer/producer is ready, e.g. shell exec'd @@ -476,6 +497,7 @@ channel_register_fds(struct ssh *ssh, Channel *c, int rfd, int wfd, int efd, } /* channel might be entering a larval state, so reset global timeout */ channel_set_used_time(ssh, NULL); + channel_classify(ssh, c); } /* @@ -535,11 +557,19 @@ channel_new(struct ssh *ssh, char *ctype, int type, int rfd, int wfd, int efd, c->delayed = 1; /* prevent call to channel_post handler */ c->inactive_deadline = lookup_timeout(ssh, c->ctype); TAILQ_INIT(&c->status_confirms); + channel_classify(ssh, c); debug("channel %d: new %s [%s] (inactive timeout: %u)", found, c->ctype, remote_name, c->inactive_deadline); return c; } +void +channel_set_tty(struct ssh *ssh, Channel *c) +{ + c->remote_has_tty = 1; + channel_classify(ssh, c); +} + int channel_close_fd(struct ssh *ssh, Channel *c, int *fdp) { @@ -825,6 +855,27 @@ channel_free_all(struct ssh *ssh) sc->x11_fake_data_len = 0; } +void +channel_free_channels(struct ssh *ssh) +{ + struct ssh_channels *sc; + + if (ssh == NULL || ssh->chanctxt == NULL) + return; + channel_free_all(ssh); + channel_clear_permission(ssh, FORWARD_USER, FORWARD_LOCAL); + channel_clear_permission(ssh, FORWARD_USER, FORWARD_REMOTE); + channel_clear_permission(ssh, FORWARD_ADM, FORWARD_LOCAL); + channel_clear_permission(ssh, FORWARD_ADM, FORWARD_REMOTE); + sc = ssh->chanctxt; + free(sc->bulk_classifier_tty); + free(sc->bulk_classifier_notty); + free(sc->channel_pre); + free(sc->channel_post); + freezero(sc, sizeof(*sc)); + ssh->chanctxt = NULL; +} + /* * Closes the sockets/fds of all channels. This is used to close extra file * descriptors after a fork. @@ -1017,7 +1068,7 @@ channel_format_status(const Channel *c) char *ret = NULL; xasprintf(&ret, "t%d [%s] %s%u %s%u i%u/%zu o%u/%zu e[%s]/%zu " - "fd %d/%d/%d sock %d cc %d %s%u io 0x%02x/0x%02x", + "fd %d/%d/%d sock %d cc %d %s%u io 0x%02x/0x%02x %s%s", c->type, c->xctype != NULL ? c->xctype : c->ctype, c->have_remote_id ? "r" : "nr", c->remote_id, c->mux_ctx != NULL ? "m" : "nm", c->mux_downstream_id, @@ -1026,7 +1077,9 @@ channel_format_status(const Channel *c) channel_format_extended_usage(c), sshbuf_len(c->extended), c->rfd, c->wfd, c->efd, c->sock, c->ctl_chan, c->have_ctl_child_id ? "c" : "nc", c->ctl_child_id, - c->io_want, c->io_ready); + c->io_want, c->io_ready, + c->isatty ? "T" : (c->remote_has_tty ? "RT" : ""), + c->bulk ? "B" : "I"); return ret; } @@ -1094,6 +1147,21 @@ channel_open_message(struct ssh *ssh) return ret; } +void +channel_report_open(struct ssh *ssh, int level) +{ + char *open, *oopen, *cp, ident[256]; + + sshpkt_fmt_connection_id(ssh, ident, sizeof(ident)); + do_log2(level, "Connection: %s (pid %ld)", ident, (long)getpid()); + open = oopen = channel_open_message(ssh); + while ((cp = strsep(&open, "\r\n")) != NULL) { + if (*cp != '\0') + do_log2(level, "%s", cp); + } + free(oopen); +} + static void open_preamble(struct ssh *ssh, const char *where, Channel *c, const char *type) { @@ -2604,10 +2672,13 @@ channel_handler(struct ssh *ssh, int table, struct timespec *timeout) time_t now; now = monotime(); - for (i = 0, oalloc = sc->channels_alloc; i < oalloc; i++) { + for (sc->nbulk = i = 0, oalloc = sc->channels_alloc; i < oalloc; i++) { c = sc->channels[i]; if (c == NULL) continue; + /* Count open channels in bulk state */ + if (c->type == SSH_CHANNEL_OPEN && c->bulk) + sc->nbulk++; /* Try to keep IO going while rekeying */ if (ssh_packet_is_rekeying(ssh) && c->type != SSH_CHANNEL_OPEN) continue; @@ -4516,7 +4587,7 @@ channel_add_permission(struct ssh *ssh, int who, int where, * host/port_to_connect. */ permission_set_add(ssh, who, where, - local ? host : 0, local ? port : 0, + local ? host : NULL, local ? port : 0, local ? NULL : host, NULL, local ? 0 : port, NULL); pset->all_permitted = 0; } @@ -4539,10 +4610,13 @@ void channel_clear_permission(struct ssh *ssh, int who, int where) { struct permission **permp; - u_int *npermp; + u_int i, *npermp; permission_set_get_array(ssh, who, where, &permp, &npermp); - *permp = xrecallocarray(*permp, *npermp, 0, sizeof(**permp)); + for (i = 0; i < *npermp; i++) + fwd_perm_clear((*permp) + i); + free(*permp); + *permp = NULL; *npermp = 0; } @@ -4675,8 +4749,7 @@ connect_to_helper(struct ssh *ssh, const char *name, int port, int socktype, * 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 = xcalloc(1, sizeof(*ai) + sizeof(*sunaddr)); ai->ai_addr = (struct sockaddr *)(ai + 1); ai->ai_addrlen = sizeof(*sunaddr); ai->ai_family = AF_UNIX; @@ -4998,19 +5071,19 @@ x11_create_display_inet(struct ssh *ssh, int x11_display_offset, u_int *display_numberp, int **chanids) { Channel *nc = NULL; - int display_number, sock; - u_short port; + int display_number, sock, port; struct addrinfo hints, *ai, *aitop; char strport[NI_MAXSERV]; int gaierr, n, num_socks = 0, socks[NUM_SOCKS]; - if (chanids == NULL) + if (chanids == NULL || x11_display_offset < 0 || + x11_display_offset > UINT16_MAX - X11_BASE_PORT - MAX_DISPLAYS) return -1; for (display_number = x11_display_offset; - display_number < MAX_DISPLAYS; + display_number < x11_display_offset + MAX_DISPLAYS; display_number++) { - port = 6000 + display_number; + port = X11_BASE_PORT + display_number; memset(&hints, 0, sizeof(hints)); hints.ai_family = ssh->chanctxt->IPv4or6; hints.ai_flags = x11_use_localhost ? 0: AI_PASSIVE; @@ -5063,7 +5136,7 @@ x11_create_display_inet(struct ssh *ssh, int x11_display_offset, if (num_socks > 0) break; } - if (display_number >= MAX_DISPLAYS) { + if (display_number >= x11_display_offset + MAX_DISPLAYS) { error("Failed to allocate internet-domain X11 display socket."); return -1; } @@ -5131,7 +5204,7 @@ 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__); + error_f("display path too long"); return 0; } if (display[0] != '/') @@ -5226,7 +5299,8 @@ x11_connect_display(struct ssh *ssh) * buf now contains the host name. But first we parse the * display number. */ - if (sscanf(cp + 1, "%u", &display_number) != 1) { + if (sscanf(cp + 1, "%u", &display_number) != 1 || + display_number > UINT16_MAX - X11_BASE_PORT) { error("Could not parse display number from DISPLAY: %.100s", display); return -1; @@ -5236,7 +5310,7 @@ x11_connect_display(struct ssh *ssh) memset(&hints, 0, sizeof(hints)); hints.ai_family = ssh->chanctxt->IPv4or6; hints.ai_socktype = SOCK_STREAM; - snprintf(strport, sizeof strport, "%u", 6000 + display_number); + snprintf(strport, sizeof strport, "%u", X11_BASE_PORT + display_number); if ((gaierr = getaddrinfo(buf, strport, &hints, &aitop)) != 0) { error("%.100s: unknown host. (%s)", buf, ssh_gai_strerror(gaierr)); @@ -5252,7 +5326,7 @@ x11_connect_display(struct ssh *ssh) /* 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)); + X11_BASE_PORT + display_number, strerror(errno)); close(sock); continue; } @@ -5262,7 +5336,7 @@ x11_connect_display(struct ssh *ssh) freeaddrinfo(aitop); if (!ai) { error("connect %.100s port %u: %.100s", buf, - 6000 + display_number, strerror(errno)); + X11_BASE_PORT + display_number, strerror(errno)); return -1; } set_nodelay(sock); @@ -5336,3 +5410,23 @@ x11_request_forwarding_with_spoofing(struct ssh *ssh, int client_session_id, fatal_fr(r, "send x11-req"); free(new_data); } + +/* + * Returns whether an x11 channel was used recently (less than a second ago) + */ +int +x11_channel_used_recently(struct ssh *ssh) { + u_int i; + Channel *c; + time_t lastused = 0; + + for (i = 0; i < ssh->chanctxt->channels_alloc; i++) { + c = ssh->chanctxt->channels[i]; + if (c == NULL || c->ctype == NULL || c->lastused == 0 || + strcmp(c->ctype, "x11-connection") != 0) + continue; + if (c->lastused > lastused) + lastused = c->lastused; + } + return lastused != 0 && monotime() <= lastused + 1; +} diff --git a/channels.h b/channels.h index 3ac5e83..7456541 100644 --- a/channels.h +++ b/channels.h @@ -1,4 +1,4 @@ -/* $OpenBSD: channels.h,v 1.157 2024/07/25 22:40:08 djm Exp $ */ +/* $OpenBSD: channels.h,v 1.162 2025/10/07 08:02:32 djm Exp $ */ /* * Author: Tatu Ylonen @@ -82,6 +82,10 @@ #define FORWARD_ADM 0x100 #define FORWARD_USER 0x101 +/* default pattern-lists used to classify channel types as bulk */ +#define CHANNEL_BULK_TTY "" +#define CHANNEL_BULK_NOTTY "direct-*,forwarded-*,tun-*,x11-*,session*" + struct ssh; struct Channel; typedef struct Channel Channel; @@ -141,6 +145,7 @@ struct Channel { int ctl_chan; /* control channel (multiplexed connections) */ uint32_t ctl_child_id; /* child session for mux controllers */ int have_ctl_child_id;/* non-zero if ctl_child_id is valid */ + int remote_has_tty; /* remote side has a tty */ int isatty; /* rfd is a tty */ #ifdef _AIX int wfd_isatty; /* wfd is a tty */ @@ -180,6 +185,7 @@ struct Channel { char *ctype; /* const type - NB. not freed on channel_free */ char *xctype; /* extended type */ + int bulk; /* channel is non-interactive */ /* callback */ channel_open_fn *open_confirm; @@ -277,8 +283,9 @@ struct Channel { c->efd != -1 && (!(c->flags & (CHAN_EOF_RCVD|CHAN_CLOSE_RCVD)) || \ sshbuf_len(c->extended) > 0)) -/* Add channel management structures to SSH transport instance */ +/* Add/remove channel management structures to/from SSH transport instance */ void channel_init_channels(struct ssh *ssh); +void channel_free_channels(struct ssh *ssh); /* channel management */ @@ -289,6 +296,7 @@ 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_set_tty(struct ssh *, Channel *); void channel_free(struct ssh *, Channel *); void channel_free_all(struct ssh *); void channel_stop_listening(struct ssh *); @@ -308,6 +316,7 @@ void channel_register_status_confirm(struct ssh *, int, void channel_cancel_cleanup(struct ssh *, int); int channel_close_fd(struct ssh *, Channel *, int *); void channel_send_window_changes(struct ssh *); +int channel_has_bulk(struct ssh *); /* channel inactivity timeouts */ void channel_add_timeout(struct ssh *, const char *, int); @@ -344,6 +353,7 @@ int channel_still_open(struct ssh *); int channel_tty_open(struct ssh *); const char *channel_format_extended_usage(const Channel *); char *channel_open_message(struct ssh *); +void channel_report_open(struct ssh *, int); int channel_find_open(struct ssh *); /* tcp forwarding */ @@ -382,6 +392,7 @@ 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); +int x11_channel_used_recently(struct ssh *ssh); /* channel close */ diff --git a/cipher.c b/cipher.c index 7d6e7d8..5e096ce 100644 --- a/cipher.c +++ b/cipher.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cipher.c,v 1.123 2024/08/23 04:51:00 deraadt Exp $ */ +/* $OpenBSD: cipher.c,v 1.125 2025/09/02 11:08:34 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -116,25 +116,16 @@ static const struct sshcipher ciphers[] = { char * cipher_alg_list(char sep, int auth_only) { - char *tmp, *ret = NULL; - size_t nlen, rlen = 0; + char *ret = NULL; const struct sshcipher *c; + char sep_str[2] = {sep, '\0'}; for (c = ciphers; c->name != NULL; c++) { if ((c->flags & CFLAG_INTERNAL) != 0) continue; if (auth_only && c->auth_len == 0) continue; - if (ret != NULL) - ret[rlen++] = sep; - nlen = strlen(c->name); - if ((tmp = realloc(ret, rlen + nlen + 2)) == NULL) { - free(ret); - return NULL; - } - ret = tmp; - memcpy(ret + rlen, c->name, nlen + 1); - rlen += nlen; + xextendf(&ret, sep_str, "%s", c->name); } return ret; } @@ -298,8 +289,8 @@ cipher_init(struct sshcipher_ctx **ccp, const struct sshcipher *cipher, goto out; } if (cipher_authlen(cipher) && - !EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_SET_IV_FIXED, - -1, (u_char *)iv)) { + EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_SET_IV_FIXED, + -1, (u_char *)iv) <= 0) { ret = SSH_ERR_LIBCRYPTO_ERROR; goto out; } @@ -369,13 +360,13 @@ cipher_crypt(struct sshcipher_ctx *cc, u_int seqnr, u_char *dest, if (authlen != cipher_authlen(cc->cipher)) return SSH_ERR_INVALID_ARGUMENT; /* increment IV */ - if (!EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_IV_GEN, - 1, lastiv)) + if (EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_IV_GEN, + 1, lastiv) <= 0) return SSH_ERR_LIBCRYPTO_ERROR; /* set tag on decryption */ if (!cc->encrypt && - !EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_SET_TAG, - authlen, (u_char *)src + aadlen + len)) + EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_SET_TAG, + authlen, (u_char *)src + aadlen + len) <= 0) return SSH_ERR_LIBCRYPTO_ERROR; } if (aadlen) { @@ -395,8 +386,8 @@ cipher_crypt(struct sshcipher_ctx *cc, u_int seqnr, u_char *dest, return cc->encrypt ? SSH_ERR_LIBCRYPTO_ERROR : SSH_ERR_MAC_INVALID; if (cc->encrypt && - !EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_GET_TAG, - authlen, dest + aadlen + len)) + EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_GET_TAG, + authlen, dest + aadlen + len) <= 0) return SSH_ERR_LIBCRYPTO_ERROR; } return 0; @@ -465,10 +456,10 @@ cipher_get_keyiv(struct sshcipher_ctx *cc, u_char *iv, size_t len) if ((size_t)evplen != len) return SSH_ERR_INVALID_ARGUMENT; if (cipher_authlen(c)) { - if (!EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_IV_GEN, - len, iv)) + if (EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_IV_GEN, len, + iv) <= 0) return SSH_ERR_LIBCRYPTO_ERROR; - } else if (!EVP_CIPHER_CTX_get_iv(cc->evp, iv, len)) + } else if (EVP_CIPHER_CTX_get_iv(cc->evp, iv, len) <= 0) return SSH_ERR_LIBCRYPTO_ERROR; #endif return 0; @@ -495,8 +486,8 @@ cipher_set_keyiv(struct sshcipher_ctx *cc, const u_char *iv, size_t len) return SSH_ERR_INVALID_ARGUMENT; if (cipher_authlen(c)) { /* XXX iv arg is const, but EVP_CIPHER_CTX_ctrl isn't */ - if (!EVP_CIPHER_CTX_ctrl(cc->evp, - EVP_CTRL_GCM_SET_IV_FIXED, -1, (void *)iv)) + if (EVP_CIPHER_CTX_ctrl(cc->evp, + EVP_CTRL_GCM_SET_IV_FIXED, -1, (void *)iv) <= 0) return SSH_ERR_LIBCRYPTO_ERROR; } else if (!EVP_CIPHER_CTX_set_iv(cc->evp, iv, evplen)) return SSH_ERR_LIBCRYPTO_ERROR; diff --git a/clientloop.c b/clientloop.c index 8ed8b1c..49d048d 100644 --- a/clientloop.c +++ b/clientloop.c @@ -1,4 +1,4 @@ -/* $OpenBSD: clientloop.c,v 1.408 2024/07/01 04:31:17 djm Exp $ */ +/* $OpenBSD: clientloop.c,v 1.415 2025/09/25 06:23:19 jsg Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -63,22 +63,14 @@ #include #include -#ifdef HAVE_SYS_STAT_H -# include -#endif -#ifdef HAVE_SYS_TIME_H -# include -#endif +#include #include +#include #include #include -#ifdef HAVE_PATHS_H #include -#endif -#ifdef HAVE_POLL_H #include -#endif #include #include #include @@ -147,7 +139,8 @@ extern char *forward_agent_sock_path; * 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; +static volatile sig_atomic_t siginfo_received = 0; +static volatile sig_atomic_t received_signal = 0; /* exit signals */ /* Time when backgrounded control master using ControlPersist should exit */ static time_t control_persist_exit_time = 0; @@ -224,6 +217,15 @@ window_change_handler(int sig) received_window_change_signal = 1; } +#ifdef SIGINFO +/* Signal handler for SIGINFO */ +static void +siginfo_handler(int sig) +{ + siginfo_received = 1; +} +#endif + /* * Signal handler for signals that cause the program to terminate. These * signals must be trapped to restore terminal modes. @@ -659,9 +661,10 @@ obfuscate_keystroke_timing(struct ssh *ssh, struct timespec *timeout, if (just_started) return 1; - /* Don't arm output fd for poll until the timing interval has elapsed */ + /* Don't arm output fd for poll until the timing interval has elapsed... */ if (timespeccmp(&now, &next_interval, <)) - return 0; + /* ...unless there's x11 communication happening */ + return x11_channel_used_recently(ssh); /* Calculate number of intervals missed since the last check */ n = (now.tv_sec - next_interval.tv_sec) * 1000LL * 1000 * 1000; @@ -964,11 +967,11 @@ client_repledge(void) } 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) + if (pledge(PLEDGE_EXTRA_INET "stdio unix proc tty", NULL) == -1) fatal_f("pledge(): %s", strerror(errno)); } else { debug("pledge: fork"); - if (pledge("stdio proc tty", NULL) == -1) + if (pledge(PLEDGE_EXTRA_INET "stdio proc tty", NULL) == -1) fatal_f("pledge(): %s", strerror(errno)); } /* XXX further things to do: @@ -1446,7 +1449,7 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg, struct pollfd *pfd = NULL; u_int npfd_alloc = 0, npfd_active = 0; double start_time, total_time; - int channel_did_enqueue = 0, r; + int interactive = -1, channel_did_enqueue = 0, r; u_int64_t ibytes, obytes; int conn_in_ready, conn_out_ready; sigset_t bsigset, osigset; @@ -1513,6 +1516,9 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg, if (ssh_signal(SIGTERM, SIG_IGN) != SIG_IGN) ssh_signal(SIGTERM, signal_handler); ssh_signal(SIGWINCH, window_change_handler); +#ifdef SIGINFO + ssh_signal(SIGINFO, siginfo_handler); +#endif if (have_pty) enter_raw_mode(options.request_tty == REQUEST_TTY_FORCE); @@ -1537,6 +1543,10 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg, sigaddset(&bsigset, SIGQUIT) == -1 || sigaddset(&bsigset, SIGTERM) == -1) error_f("bsigset setup: %s", strerror(errno)); +#ifdef SIGINFO + if (sigaddset(&bsigset, SIGINFO) == -1) + error_f("bsigset setup: %s", strerror(errno)); +#endif /* Main loop of the client for the interactive session mode. */ while (!quit_pending) { @@ -1576,6 +1586,10 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg, */ if (sigprocmask(SIG_BLOCK, &bsigset, &osigset) == -1) error_f("bsigset sigprocmask: %s", strerror(errno)); + if (siginfo_received) { + siginfo_received = 0; + channel_report_open(ssh, SYSLOG_LEVEL_INFO); + } if (quit_pending) break; client_wait_until_can_do_something(ssh, &pfd, &npfd_alloc, @@ -1606,6 +1620,12 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg, * sender. */ if (conn_out_ready) { + if (interactive != !channel_has_bulk(ssh)) { + interactive = !channel_has_bulk(ssh); + debug2_f("session QoS is now %s", interactive ? + "interactive" : "non-interactive"); + ssh_packet_set_interactive(ssh, interactive); + } if ((r = ssh_packet_write_poll(ssh)) != 0) { sshpkt_fatal(ssh, r, "%s: ssh_packet_write_poll", __func__); @@ -1848,7 +1868,7 @@ client_request_tun_fwd(struct ssh *ssh, int tun_mode, char *ifname = NULL; if (tun_mode == SSH_TUNMODE_NO) - return 0; + return NULL; debug("Requesting tun unit %d in mode %d", local_tun, tun_mode); @@ -2419,6 +2439,7 @@ client_global_hostkeys_prove_confirm(struct ssh *ssh, int type, /* Make the edits to known_hosts */ update_known_hosts(ctx); out: + sshbuf_free(signdata); hostkeys_update_ctx_free(ctx); hostkeys_update_complete = 1; client_repledge(); @@ -2690,9 +2711,6 @@ client_session2_setup(struct ssh *ssh, int id, int want_tty, int want_subsystem, 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; diff --git a/config.h.in b/config.h.in index 14bee60..eeb1466 100644 --- a/config.h.in +++ b/config.h.in @@ -363,10 +363,26 @@ don't. */ #undef HAVE_DECL_HOWMANY +/* Define to 1 if you have the declaration of `htole64', and to 0 if you + don't. */ +#undef HAVE_DECL_HTOLE64 + /* Define to 1 if you have the declaration of `h_errno', and to 0 if you don't. */ #undef HAVE_DECL_H_ERRNO +/* Define to 1 if you have the declaration of `INFINITY', and to 0 if you + don't. */ +#undef HAVE_DECL_INFINITY + +/* Define to 1 if you have the declaration of `le32toh', and to 0 if you + don't. */ +#undef HAVE_DECL_LE32TOH + +/* Define to 1 if you have the declaration of `le64toh', and to 0 if you + don't. */ +#undef HAVE_DECL_LE64TOH + /* Define to 1 if you have the declaration of `loginfailed', and to 0 if you don't. */ #undef HAVE_DECL_LOGINFAILED @@ -395,14 +411,6 @@ don't. */ #undef HAVE_DECL_OFFSETOF -/* Define to 1 if you have the declaration of `OPENSSL_IS_BORINGSSL', and to 0 - if you don't. */ -#undef HAVE_DECL_OPENSSL_IS_BORINGSSL - -/* Define to 1 if you have the declaration of `OPENSSL_NO_DSA', and to 0 if - you don't. */ -#undef HAVE_DECL_OPENSSL_NO_DSA - /* Define to 1 if you have the declaration of `O_NONBLOCK', and to 0 if you don't. */ #undef HAVE_DECL_O_NONBLOCK @@ -439,6 +447,10 @@ don't. */ #undef HAVE_DECL__GETSHORT +/* Define to 1 if you have the declaration of `__builtin_inff', and to 0 if + you don't. */ +#undef HAVE_DECL___BUILTIN_INFF + /* Define to 1 if you have the `DES_crypt' function. */ #undef HAVE_DES_CRYPT @@ -460,12 +472,23 @@ /* Define to 1 if you have the `dlopen' function. */ #undef HAVE_DLOPEN -/* Define to 1 if you have the `DSA_generate_parameters_ex' function. */ -#undef HAVE_DSA_GENERATE_PARAMETERS_EX - /* Define to 1 if you have the `EC_KEY_METHOD_new' function. */ #undef HAVE_EC_KEY_METHOD_NEW +/* Define to 1 if you have the `EC_POINT_get_affine_coordinates' function. */ +#undef HAVE_EC_POINT_GET_AFFINE_COORDINATES + +/* Define to 1 if you have the `EC_POINT_get_affine_coordinates_GFp' function. + */ +#undef HAVE_EC_POINT_GET_AFFINE_COORDINATES_GFP + +/* Define to 1 if you have the `EC_POINT_set_affine_coordinates' function. */ +#undef HAVE_EC_POINT_SET_AFFINE_COORDINATES + +/* Define to 1 if you have the `EC_POINT_set_affine_coordinates_GFp' function. + */ +#undef HAVE_EC_POINT_SET_AFFINE_COORDINATES_GFP + /* Define to 1 if you have the header file. */ #undef HAVE_ELF_H @@ -631,6 +654,9 @@ /* Define to 1 if the system has the type `fsfilcnt_t'. */ #undef HAVE_FSFILCNT_T +/* Define to 1 if you have the `fstatat' function. */ +#undef HAVE_FSTATAT + /* Define to 1 if you have the `fstatfs' function. */ #undef HAVE_FSTATFS @@ -968,6 +994,9 @@ /* Define to 1 if you have the `mkdtemp' function. */ #undef HAVE_MKDTEMP +/* Define to 1 if you have the `mmap' function. */ +#undef HAVE_MMAP + /* define if you have mode_t data type */ #undef HAVE_MODE_T @@ -998,6 +1027,12 @@ /* Define to 1 if you have the `ngetaddrinfo' function. */ #undef HAVE_NGETADDRINFO +/* Define to 1 if you have the `nlist' function. */ +#undef HAVE_NLIST + +/* Define to 1 if you have the header file. */ +#undef HAVE_NLIST_H + /* Define to 1 if you have the `nl_langinfo' function. */ #undef HAVE_NL_LANGINFO @@ -1357,6 +1392,9 @@ /* define if you have struct addrinfo data type */ #undef HAVE_STRUCT_ADDRINFO +/* Define to 1 if `d_type' is a member of `struct dirent'. */ +#undef HAVE_STRUCT_DIRENT_D_TYPE + /* define if you have struct in6_addr data type */ #undef HAVE_STRUCT_IN6_ADDR @@ -1576,6 +1614,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H +/* Define to 1 if you have the `unlinkat' function. */ +#undef HAVE_UNLINKAT + /* Define to 1 if you have the `unsetenv' function. */ #undef HAVE_UNSETENV @@ -1712,6 +1753,9 @@ EOPNOTSUPP. */ #undef LINK_OPNOTSUPP_ERRNO +/* Lock all memory to protect sshd against Linux kcompactd */ +#undef LINUX_MEMLOCK_ONFAULT + /* Adjust Linux out-of-memory killer */ #undef LINUX_OOM_ADJUST @@ -1736,6 +1780,9 @@ /* Set this to your mail directory if you do not have _PATH_MAILDIR */ #undef MAIL_DIRECTORY +/* Define if your compiler lacks __builtin_popcount */ +#undef MISSING_BUILTIN_POPCOUNT + /* Need setpgrp to for controlling tty */ #undef NEED_SETPGRP @@ -1809,6 +1856,9 @@ /* System dirs owned by bin (uid 2) */ #undef PLATFORM_SYS_DIR_UID +/* need inet in pledge for setsockopt IP_TOS */ +#undef PLEDGE_EXTRA_INET + /* Port number of PRNGD/EGD random number socket */ #undef PRNGD_PORT @@ -1827,9 +1877,6 @@ /* no privsep sandboxing */ #undef SANDBOX_NULL -/* Sandbox using pledge(2) */ -#undef SANDBOX_PLEDGE - /* Sandbox using setrlimit(2) */ #undef SANDBOX_RLIMIT @@ -1845,9 +1892,6 @@ /* 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 @@ -1971,6 +2015,9 @@ /* Define if you have Solaris projects */ #undef USE_SOLARIS_PROJECTS +/* Use libwtmpdb for sshd */ +#undef USE_WTMPDB + /* compiler variable declarations after code */ #undef VARIABLE_DECLARATION_AFTER_CODE @@ -1983,9 +2030,6 @@ /* Define if you want to enable AIX4's authenticate function */ #undef WITH_AIXAUTHENTICATE -/* DSA keys explicitly enabled */ -#undef WITH_DSA - /* Define if you have/want arrays (cluster-wide session management, not C arrays) */ #undef WITH_IRIX_ARRAY diff --git a/configure b/configure index b4d33b7..652d7e1 100755 --- a/configure +++ b/configure @@ -678,14 +678,18 @@ GSSLIBS KRB5CONF SSHDLIBS SSH_PRIVSEP_USER +SK_STANDALONE LIBFIDO2 SK_DUMMY_LIBRARY OPENSSL_BIN openssl_bin PICFLAG +LIBWTMPDB LIBEDIT LDNSCONFIG LIBOBJS +TESTLIBS +COMPATINCLUDES LD PATH_PASSWD_PROG STARTUP_SCRIPT_SHELL @@ -784,6 +788,7 @@ with_ldflags with_ldflags_after with_libs with_Werror +with_linux_memlock_onfault with_solaris_contracts with_solaris_projects with_solaris_privs @@ -792,12 +797,13 @@ with_zlib with_zlib_version_check with_ldns with_libedit +with_wtmpdb with_audit with_pie enable_pkcs11 enable_security_key with_security_key_builtin -enable_dsa_keys +with_security_key_standalone with_ssl_dir with_openssl_header_check with_ssl_engine @@ -1467,7 +1473,6 @@ Optional Features: --disable-largefile omit support for large files --disable-pkcs11 disable PKCS#11 support code [no] --disable-security-key disable U2F/FIDO support code no - --enable-dsa-keys enable DSA key support no --disable-strip Disable calling strip(1) on install --disable-etc-default-login Disable using PATH from /etc/default/login no --disable-fd-passing disable file descriptor passsing no @@ -1495,6 +1500,7 @@ Optional Packages: --with-ldflags-after Specify additional flags to pass to linker after configure --with-libs Specify additional libraries to link with --with-Werror Build main code with -Werror + --with-linux-memlock-onfault Enables memory locking on Linux --with-solaris-contracts Enable Solaris process contracts (experimental) --with-solaris-projects Enable Solaris projects (experimental) --with-solaris-privs Enable Solaris/Illumos privileges (experimental) @@ -1503,9 +1509,11 @@ Optional Packages: --without-zlib-version-check Disable zlib version check --with-ldns[=PATH] Use ldns for DNSSEC support (optionally in PATH) --with-libedit[=PATH] Enable libedit support for sftp + --with-wtmpdb[=PATH] Enable wtmpdb support for sshd --with-audit=module Enable audit support (modules=debug,bsm,linux) --with-pie Build Position Independent Executables if possible --with-security-key-builtin include builtin U2F/FIDO support + --with-security-key-standalone build standalone sk-libfido2 SecurityKeyProvider --with-ssl-dir=PATH Specify path to OpenSSL installation --without-openssl-header-check Disable OpenSSL version consistency check --with-ssl-engine Enable OpenSSL (hardware) ENGINE support @@ -1514,7 +1522,7 @@ Optional Packages: --with-pam Enable PAM support --with-pam-service=name Specify PAM service name --with-privsep-user=user Specify non-privileged user for privilege separation - --with-sandbox=style Specify privilege separation sandbox (no, capsicum, darwin, rlimit, seccomp_filter, systrace, pledge) + --with-sandbox=style Specify privilege separation sandbox (no, capsicum, darwin, rlimit, seccomp_filter) --with-selinux Enable SELinux support --with-kerberos5=PATH Enable Kerberos 5 support --with-privsep-path=xxx Path for privilege separation chroot (default=/var/empty) @@ -1935,122 +1943,122 @@ printf "%s\n" "$ac_res" >&6; } } # ac_fn_c_check_func -# ac_fn_c_check_type LINENO TYPE VAR INCLUDES -# ------------------------------------------- -# Tests whether TYPE exists after having included INCLUDES, setting cache -# variable VAR accordingly. -ac_fn_c_check_type () +# ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES +# ---------------------------------------------------- +# Tries to find if the field MEMBER exists in type AGGR, after including +# INCLUDES, setting cache variable VAR accordingly. +ac_fn_c_check_member () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -printf %s "checking for $2... " >&6; } -if eval test \${$3+y} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5 +printf %s "checking for $2.$3... " >&6; } +if eval test \${$4+y} then : printf %s "(cached) " >&6 else $as_nop - eval "$3=no" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -$4 +$5 int main (void) { -if (sizeof ($2)) - return 0; +static $2 ac_aggr; +if (ac_aggr.$3) +return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : + eval "$4=yes" +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -$4 +$5 int main (void) { -if (sizeof (($2))) - return 0; +static $2 ac_aggr; +if (sizeof ac_aggr.$3) +return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : - + eval "$4=yes" else $as_nop - eval "$3=yes" + eval "$4=no" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi -eval ac_res=\$$3 +eval ac_res=\$$4 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno -} # ac_fn_c_check_type +} # ac_fn_c_check_member -# ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES -# ---------------------------------------------------- -# Tries to find if the field MEMBER exists in type AGGR, after including -# INCLUDES, setting cache variable VAR accordingly. -ac_fn_c_check_member () +# ac_fn_c_check_type LINENO TYPE VAR INCLUDES +# ------------------------------------------- +# Tests whether TYPE exists after having included INCLUDES, setting cache +# variable VAR accordingly. +ac_fn_c_check_type () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5 -printf %s "checking for $2.$3... " >&6; } -if eval test \${$4+y} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +printf %s "checking for $2... " >&6; } +if eval test \${$3+y} then : printf %s "(cached) " >&6 else $as_nop + eval "$3=no" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -$5 +$4 int main (void) { -static $2 ac_aggr; -if (ac_aggr.$3) -return 0; +if (sizeof ($2)) + return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : - eval "$4=yes" -else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -$5 +$4 int main (void) { -static $2 ac_aggr; -if (sizeof ac_aggr.$3) -return 0; +if (sizeof (($2))) + return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : - eval "$4=yes" + else $as_nop - eval "$4=no" + eval "$3=yes" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi -eval ac_res=\$$4 +eval ac_res=\$$3 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno -} # ac_fn_c_check_member +} # ac_fn_c_check_type # ac_fn_c_compute_int LINENO EXPR VAR INCLUDES # -------------------------------------------- @@ -5974,16 +5982,6 @@ if test "x$ac_cv_have_decl_LONG_LONG_MAX" = xyes then : have_long_long_max=1 fi -ac_fn_check_decl "$LINENO" "SYSTR_POLICY_KILL" "ac_cv_have_decl_SYSTR_POLICY_KILL" " - #include - #include - #include - -" "$ac_c_undeclared_builtin_options" "CFLAGS" -if test "x$ac_cv_have_decl_SYSTR_POLICY_KILL" = xyes -then : - have_systr_policy_kill=1 -fi ac_fn_check_decl "$LINENO" "RLIMIT_NPROC" "ac_cv_have_decl_RLIMIT_NPROC" " #include #include @@ -6119,8 +6117,14 @@ printf %s "checking clang version... " >&6; } printf "%s\n" "$CLANG_VER" >&6; } { - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -pipe" >&5 + ossh_cache_var=ossh_cv_cflag__pipe + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -pipe" >&5 printf %s "checking if $CC supports compile flag -pipe... " >&6; } +if eval test \${$ossh_cache_var+y} +then : + printf %s "(cached) " >&6 +else $as_nop + saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -pipe" _define_flag="" @@ -6185,14 +6189,12 @@ then : if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" else if test "$cross_compiling" = yes then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -6252,12 +6254,10 @@ int main(int argc, char **argv) { _ACEOF if ac_fn_c_try_run "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, fails at run time" >&5 -printf "%s\n" "no, fails at run time" >&6; } + eval "$ossh_cache_var='no, fails at run time'" CFLAGS="$saved_CFLAGS" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -6266,16 +6266,26 @@ fi fi else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +fi +eval ac_res=\$$ossh_cache_var + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } } { - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wunknown-warning-option" >&5 + ossh_cache_var=ossh_cv_cflag__Wunknown_warning_option + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wunknown-warning-option" >&5 printf %s "checking if $CC supports compile flag -Wunknown-warning-option... " >&6; } +if eval test \${$ossh_cache_var+y} +then : + printf %s "(cached) " >&6 +else $as_nop + saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -Wunknown-warning-option" _define_flag="" @@ -6340,14 +6350,12 @@ then : if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" else if test "$cross_compiling" = yes then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -6407,12 +6415,10 @@ int main(int argc, char **argv) { _ACEOF if ac_fn_c_try_run "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, fails at run time" >&5 -printf "%s\n" "no, fails at run time" >&6; } + eval "$ossh_cache_var='no, fails at run time'" CFLAGS="$saved_CFLAGS" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -6421,16 +6427,26 @@ fi fi else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +fi +eval ac_res=\$$ossh_cache_var + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } } { - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wno-error=format-truncation" >&5 + ossh_cache_var=ossh_cv_cflag__Wno_error_format_truncation + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wno-error=format-truncation" >&5 printf %s "checking if $CC supports compile flag -Wno-error=format-truncation... " >&6; } +if eval test \${$ossh_cache_var+y} +then : + printf %s "(cached) " >&6 +else $as_nop + saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -Wno-error=format-truncation" _define_flag="" @@ -6495,14 +6511,12 @@ then : if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" else if test "$cross_compiling" = yes then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -6562,12 +6576,10 @@ int main(int argc, char **argv) { _ACEOF if ac_fn_c_try_run "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, fails at run time" >&5 -printf "%s\n" "no, fails at run time" >&6; } + eval "$ossh_cache_var='no, fails at run time'" CFLAGS="$saved_CFLAGS" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -6576,16 +6588,26 @@ fi fi else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +fi +eval ac_res=\$$ossh_cache_var + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } } { - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Qunused-arguments" >&5 + ossh_cache_var=ossh_cv_cflag__Qunused_arguments + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Qunused-arguments" >&5 printf %s "checking if $CC supports compile flag -Qunused-arguments... " >&6; } +if eval test \${$ossh_cache_var+y} +then : + printf %s "(cached) " >&6 +else $as_nop + saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -Qunused-arguments" _define_flag="" @@ -6650,14 +6672,12 @@ then : if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" else if test "$cross_compiling" = yes then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -6717,12 +6737,10 @@ int main(int argc, char **argv) { _ACEOF if ac_fn_c_try_run "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, fails at run time" >&5 -printf "%s\n" "no, fails at run time" >&6; } + eval "$ossh_cache_var='no, fails at run time'" CFLAGS="$saved_CFLAGS" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -6731,16 +6749,26 @@ fi fi else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +fi +eval ac_res=\$$ossh_cache_var + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } } { - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wall" >&5 + ossh_cache_var=ossh_cv_cflag__Wall + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wall" >&5 printf %s "checking if $CC supports compile flag -Wall... " >&6; } +if eval test \${$ossh_cache_var+y} +then : + printf %s "(cached) " >&6 +else $as_nop + saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -Wall" _define_flag="" @@ -6805,14 +6833,12 @@ then : if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" else if test "$cross_compiling" = yes then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -6872,12 +6898,10 @@ int main(int argc, char **argv) { _ACEOF if ac_fn_c_try_run "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, fails at run time" >&5 -printf "%s\n" "no, fails at run time" >&6; } + eval "$ossh_cache_var='no, fails at run time'" CFLAGS="$saved_CFLAGS" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -6886,16 +6910,26 @@ fi fi else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +fi +eval ac_res=\$$ossh_cache_var + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } } { - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wextra" >&5 + ossh_cache_var=ossh_cv_cflag__Wextra + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wextra" >&5 printf %s "checking if $CC supports compile flag -Wextra... " >&6; } +if eval test \${$ossh_cache_var+y} +then : + printf %s "(cached) " >&6 +else $as_nop + saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -Wextra" _define_flag="" @@ -6960,14 +6994,12 @@ then : if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" else if test "$cross_compiling" = yes then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -7027,12 +7059,10 @@ int main(int argc, char **argv) { _ACEOF if ac_fn_c_try_run "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, fails at run time" >&5 -printf "%s\n" "no, fails at run time" >&6; } + eval "$ossh_cache_var='no, fails at run time'" CFLAGS="$saved_CFLAGS" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -7041,16 +7071,26 @@ fi fi else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +fi +eval ac_res=\$$ossh_cache_var + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } } { - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wpointer-arith" >&5 + ossh_cache_var=ossh_cv_cflag__Wpointer_arith + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wpointer-arith" >&5 printf %s "checking if $CC supports compile flag -Wpointer-arith... " >&6; } +if eval test \${$ossh_cache_var+y} +then : + printf %s "(cached) " >&6 +else $as_nop + saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -Wpointer-arith" _define_flag="" @@ -7115,14 +7155,12 @@ then : if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" else if test "$cross_compiling" = yes then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -7182,12 +7220,10 @@ int main(int argc, char **argv) { _ACEOF if ac_fn_c_try_run "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, fails at run time" >&5 -printf "%s\n" "no, fails at run time" >&6; } + eval "$ossh_cache_var='no, fails at run time'" CFLAGS="$saved_CFLAGS" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -7196,16 +7232,26 @@ fi fi else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +fi +eval ac_res=\$$ossh_cache_var + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } } { - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wuninitialized" >&5 + ossh_cache_var=ossh_cv_cflag__Wuninitialized + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wuninitialized" >&5 printf %s "checking if $CC supports compile flag -Wuninitialized... " >&6; } +if eval test \${$ossh_cache_var+y} +then : + printf %s "(cached) " >&6 +else $as_nop + saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -Wuninitialized" _define_flag="" @@ -7270,14 +7316,12 @@ then : if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" else if test "$cross_compiling" = yes then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -7337,12 +7381,10 @@ int main(int argc, char **argv) { _ACEOF if ac_fn_c_try_run "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, fails at run time" >&5 -printf "%s\n" "no, fails at run time" >&6; } + eval "$ossh_cache_var='no, fails at run time'" CFLAGS="$saved_CFLAGS" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -7351,16 +7393,26 @@ fi fi else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +fi +eval ac_res=\$$ossh_cache_var + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } } { - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wsign-compare" >&5 + ossh_cache_var=ossh_cv_cflag__Wsign_compare + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wsign-compare" >&5 printf %s "checking if $CC supports compile flag -Wsign-compare... " >&6; } +if eval test \${$ossh_cache_var+y} +then : + printf %s "(cached) " >&6 +else $as_nop + saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -Wsign-compare" _define_flag="" @@ -7425,14 +7477,12 @@ then : if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" else if test "$cross_compiling" = yes then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -7492,12 +7542,10 @@ int main(int argc, char **argv) { _ACEOF if ac_fn_c_try_run "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, fails at run time" >&5 -printf "%s\n" "no, fails at run time" >&6; } + eval "$ossh_cache_var='no, fails at run time'" CFLAGS="$saved_CFLAGS" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -7506,16 +7554,26 @@ fi fi else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +fi +eval ac_res=\$$ossh_cache_var + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } } { - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wformat-security" >&5 + ossh_cache_var=ossh_cv_cflag__Wformat_security + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wformat-security" >&5 printf %s "checking if $CC supports compile flag -Wformat-security... " >&6; } +if eval test \${$ossh_cache_var+y} +then : + printf %s "(cached) " >&6 +else $as_nop + saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -Wformat-security" _define_flag="" @@ -7580,14 +7638,12 @@ then : if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" else if test "$cross_compiling" = yes then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -7647,12 +7703,10 @@ int main(int argc, char **argv) { _ACEOF if ac_fn_c_try_run "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, fails at run time" >&5 -printf "%s\n" "no, fails at run time" >&6; } + eval "$ossh_cache_var='no, fails at run time'" CFLAGS="$saved_CFLAGS" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -7661,16 +7715,26 @@ fi fi else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +fi +eval ac_res=\$$ossh_cache_var + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } } { - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wsizeof-pointer-memaccess" >&5 + ossh_cache_var=ossh_cv_cflag__Wsizeof_pointer_memaccess + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wsizeof-pointer-memaccess" >&5 printf %s "checking if $CC supports compile flag -Wsizeof-pointer-memaccess... " >&6; } +if eval test \${$ossh_cache_var+y} +then : + printf %s "(cached) " >&6 +else $as_nop + saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -Wsizeof-pointer-memaccess" _define_flag="" @@ -7735,14 +7799,12 @@ then : if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" else if test "$cross_compiling" = yes then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -7802,12 +7864,10 @@ int main(int argc, char **argv) { _ACEOF if ac_fn_c_try_run "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, fails at run time" >&5 -printf "%s\n" "no, fails at run time" >&6; } + eval "$ossh_cache_var='no, fails at run time'" CFLAGS="$saved_CFLAGS" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -7816,16 +7876,26 @@ fi fi else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +fi +eval ac_res=\$$ossh_cache_var + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } } { - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wpointer-sign" >&5 + ossh_cache_var=ossh_cv_cflag__Wpointer_sign + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wpointer-sign" >&5 printf %s "checking if $CC supports compile flag -Wpointer-sign... " >&6; } +if eval test \${$ossh_cache_var+y} +then : + printf %s "(cached) " >&6 +else $as_nop + saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -Wpointer-sign" _define_flag="-Wno-pointer-sign" @@ -7890,14 +7960,12 @@ then : if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" else if test "$cross_compiling" = yes then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -7957,12 +8025,10 @@ int main(int argc, char **argv) { _ACEOF if ac_fn_c_try_run "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, fails at run time" >&5 -printf "%s\n" "no, fails at run time" >&6; } + eval "$ossh_cache_var='no, fails at run time'" CFLAGS="$saved_CFLAGS" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -7971,16 +8037,26 @@ fi fi else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +fi +eval ac_res=\$$ossh_cache_var + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } } { - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wunused-parameter" >&5 + ossh_cache_var=ossh_cv_cflag__Wunused_parameter + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wunused-parameter" >&5 printf %s "checking if $CC supports compile flag -Wunused-parameter... " >&6; } +if eval test \${$ossh_cache_var+y} +then : + printf %s "(cached) " >&6 +else $as_nop + saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -Wunused-parameter" _define_flag="-Wno-unused-parameter" @@ -8045,14 +8121,12 @@ then : if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" else if test "$cross_compiling" = yes then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -8112,12 +8186,10 @@ int main(int argc, char **argv) { _ACEOF if ac_fn_c_try_run "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, fails at run time" >&5 -printf "%s\n" "no, fails at run time" >&6; } + eval "$ossh_cache_var='no, fails at run time'" CFLAGS="$saved_CFLAGS" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -8126,16 +8198,26 @@ fi fi else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +fi +eval ac_res=\$$ossh_cache_var + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } } { - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wunused-result" >&5 + ossh_cache_var=ossh_cv_cflag__Wunused_result + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wunused-result" >&5 printf %s "checking if $CC supports compile flag -Wunused-result... " >&6; } +if eval test \${$ossh_cache_var+y} +then : + printf %s "(cached) " >&6 +else $as_nop + saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -Wunused-result" _define_flag="-Wno-unused-result" @@ -8200,14 +8282,12 @@ then : if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" else if test "$cross_compiling" = yes then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -8267,12 +8347,10 @@ int main(int argc, char **argv) { _ACEOF if ac_fn_c_try_run "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, fails at run time" >&5 -printf "%s\n" "no, fails at run time" >&6; } + eval "$ossh_cache_var='no, fails at run time'" CFLAGS="$saved_CFLAGS" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -8281,16 +8359,26 @@ fi fi else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +fi +eval ac_res=\$$ossh_cache_var + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } } { - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wimplicit-fallthrough" >&5 + ossh_cache_var=ossh_cv_cflag__Wimplicit_fallthrough + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wimplicit-fallthrough" >&5 printf %s "checking if $CC supports compile flag -Wimplicit-fallthrough... " >&6; } +if eval test \${$ossh_cache_var+y} +then : + printf %s "(cached) " >&6 +else $as_nop + saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -Wimplicit-fallthrough" _define_flag="" @@ -8355,14 +8443,12 @@ then : if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" else if test "$cross_compiling" = yes then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -8422,12 +8508,10 @@ int main(int argc, char **argv) { _ACEOF if ac_fn_c_try_run "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, fails at run time" >&5 -printf "%s\n" "no, fails at run time" >&6; } + eval "$ossh_cache_var='no, fails at run time'" CFLAGS="$saved_CFLAGS" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -8436,16 +8520,26 @@ fi fi else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +fi +eval ac_res=\$$ossh_cache_var + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } } { - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wmisleading-indentation" >&5 + ossh_cache_var=ossh_cv_cflag__Wmisleading_indentation + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wmisleading-indentation" >&5 printf %s "checking if $CC supports compile flag -Wmisleading-indentation... " >&6; } +if eval test \${$ossh_cache_var+y} +then : + printf %s "(cached) " >&6 +else $as_nop + saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -Wmisleading-indentation" _define_flag="" @@ -8510,14 +8604,12 @@ then : if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" else if test "$cross_compiling" = yes then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -8577,12 +8669,10 @@ int main(int argc, char **argv) { _ACEOF if ac_fn_c_try_run "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, fails at run time" >&5 -printf "%s\n" "no, fails at run time" >&6; } + eval "$ossh_cache_var='no, fails at run time'" CFLAGS="$saved_CFLAGS" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -8591,16 +8681,26 @@ fi fi else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +fi +eval ac_res=\$$ossh_cache_var + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } } { - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wbitwise-instead-of-logical" >&5 + ossh_cache_var=ossh_cv_cflag__Wbitwise_instead_of_logical + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wbitwise-instead-of-logical" >&5 printf %s "checking if $CC supports compile flag -Wbitwise-instead-of-logical... " >&6; } +if eval test \${$ossh_cache_var+y} +then : + printf %s "(cached) " >&6 +else $as_nop + saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -Wbitwise-instead-of-logical" _define_flag="" @@ -8665,14 +8765,12 @@ then : if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" else if test "$cross_compiling" = yes then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -8732,12 +8830,10 @@ int main(int argc, char **argv) { _ACEOF if ac_fn_c_try_run "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, fails at run time" >&5 -printf "%s\n" "no, fails at run time" >&6; } + eval "$ossh_cache_var='no, fails at run time'" CFLAGS="$saved_CFLAGS" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -8746,16 +8842,26 @@ fi fi else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +fi +eval ac_res=\$$ossh_cache_var + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } } { - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -fno-strict-aliasing" >&5 + ossh_cache_var=ossh_cv_cflag__fno_strict_aliasing + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -fno-strict-aliasing" >&5 printf %s "checking if $CC supports compile flag -fno-strict-aliasing... " >&6; } +if eval test \${$ossh_cache_var+y} +then : + printf %s "(cached) " >&6 +else $as_nop + saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -fno-strict-aliasing" _define_flag="" @@ -8820,14 +8926,12 @@ then : if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" else if test "$cross_compiling" = yes then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -8887,12 +8991,10 @@ int main(int argc, char **argv) { _ACEOF if ac_fn_c_try_run "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, fails at run time" >&5 -printf "%s\n" "no, fails at run time" >&6; } + eval "$ossh_cache_var='no, fails at run time'" CFLAGS="$saved_CFLAGS" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -8901,17 +9003,27 @@ fi fi else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +fi +eval ac_res=\$$ossh_cache_var + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } } if test "x$use_toolchain_hardening" = "x1"; then { - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -D_FORTIFY_SOURCE=2" >&5 + ossh_cache_var=ossh_cv_cflag__D_FORTIFY_SOURCE_2 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -D_FORTIFY_SOURCE=2" >&5 printf %s "checking if $CC supports compile flag -D_FORTIFY_SOURCE=2... " >&6; } +if eval test \${$ossh_cache_var+y} +then : + printf %s "(cached) " >&6 +else $as_nop + saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -D_FORTIFY_SOURCE=2" _define_flag="" @@ -8976,14 +9088,12 @@ then : if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" else if test "$cross_compiling" = yes then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -9043,12 +9153,10 @@ int main(int argc, char **argv) { _ACEOF if ac_fn_c_try_run "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, fails at run time" >&5 -printf "%s\n" "no, fails at run time" >&6; } + eval "$ossh_cache_var='no, fails at run time'" CFLAGS="$saved_CFLAGS" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -9057,16 +9165,26 @@ fi fi else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +fi +eval ac_res=\$$ossh_cache_var + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } } { - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $LD supports link flag -Wl,-z,relro" >&5 + ossh_cache_var=ossh_cv_ldflag__Wl__z_relro + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $LD supports link flag -Wl,-z,relro" >&5 printf %s "checking if $LD supports link flag -Wl,-z,relro... " >&6; } +if eval test \${$ossh_cache_var+y} +then : + printf %s "(cached) " >&6 +else $as_nop + saved_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $WERROR -Wl,-z,relro" _define_flag="" @@ -9131,14 +9249,12 @@ then : if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" LDFLAGS="$saved_LDFLAGS" else if test "$cross_compiling" = yes then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" LDFLAGS="$saved_LDFLAGS $_define_flag" else $as_nop @@ -9199,12 +9315,10 @@ int main(int argc, char **argv) { _ACEOF if ac_fn_c_try_run "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" LDFLAGS="$saved_LDFLAGS $_define_flag" else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, fails at run time" >&5 -printf "%s\n" "no, fails at run time" >&6; } + eval "$ossh_cache_var='no, fails at run time'" LDFLAGS="$saved_LDFLAGS" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -9213,17 +9327,27 @@ fi fi else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" LDFLAGS="$saved_LDFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext + +fi +eval ac_res=\$$ossh_cache_var + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } } { - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $LD supports link flag -Wl,-z,now" >&5 + ossh_cache_var=ossh_cv_ldflag__Wl__z_now + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $LD supports link flag -Wl,-z,now" >&5 printf %s "checking if $LD supports link flag -Wl,-z,now... " >&6; } +if eval test \${$ossh_cache_var+y} +then : + printf %s "(cached) " >&6 +else $as_nop + saved_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $WERROR -Wl,-z,now" _define_flag="" @@ -9288,14 +9412,12 @@ then : if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" LDFLAGS="$saved_LDFLAGS" else if test "$cross_compiling" = yes then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" LDFLAGS="$saved_LDFLAGS $_define_flag" else $as_nop @@ -9356,12 +9478,10 @@ int main(int argc, char **argv) { _ACEOF if ac_fn_c_try_run "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" LDFLAGS="$saved_LDFLAGS $_define_flag" else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, fails at run time" >&5 -printf "%s\n" "no, fails at run time" >&6; } + eval "$ossh_cache_var='no, fails at run time'" LDFLAGS="$saved_LDFLAGS" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -9370,17 +9490,27 @@ fi fi else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" LDFLAGS="$saved_LDFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext + +fi +eval ac_res=\$$ossh_cache_var + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } } { - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $LD supports link flag -Wl,-z,noexecstack" >&5 + ossh_cache_var=ossh_cv_ldflag__Wl__z_noexecstack + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $LD supports link flag -Wl,-z,noexecstack" >&5 printf %s "checking if $LD supports link flag -Wl,-z,noexecstack... " >&6; } +if eval test \${$ossh_cache_var+y} +then : + printf %s "(cached) " >&6 +else $as_nop + saved_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $WERROR -Wl,-z,noexecstack" _define_flag="" @@ -9445,14 +9575,12 @@ then : if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" LDFLAGS="$saved_LDFLAGS" else if test "$cross_compiling" = yes then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" LDFLAGS="$saved_LDFLAGS $_define_flag" else $as_nop @@ -9513,12 +9641,10 @@ int main(int argc, char **argv) { _ACEOF if ac_fn_c_try_run "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" LDFLAGS="$saved_LDFLAGS $_define_flag" else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, fails at run time" >&5 -printf "%s\n" "no, fails at run time" >&6; } + eval "$ossh_cache_var='no, fails at run time'" LDFLAGS="$saved_LDFLAGS" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -9527,13 +9653,17 @@ fi fi else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" LDFLAGS="$saved_LDFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext + +fi +eval ac_res=\$$ossh_cache_var + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } } # NB. -ftrapv expects certain support functions to be present in # the compiler library (libgcc or similar) to detect integer operations @@ -9541,8 +9671,14 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam \ # actually links. The test program compiled/linked includes a number # of integer operations that should exercise this. { - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -ftrapv and linking succeeds" >&5 + ossh_cache_var=ossh_cv_cflag__ftrapv + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -ftrapv and linking succeeds" >&5 printf %s "checking if $CC supports compile flag -ftrapv and linking succeeds... " >&6; } +if eval test \${$ossh_cache_var+y} +then : + printf %s "(cached) " >&6 +else $as_nop + saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -ftrapv" _define_flag="" @@ -9607,14 +9743,12 @@ then : if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" else if test "$cross_compiling" = yes then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -9674,12 +9808,10 @@ int main(int argc, char **argv) { _ACEOF if ac_fn_c_try_run "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, fails at run time" >&5 -printf "%s\n" "no, fails at run time" >&6; } + eval "$ossh_cache_var='no, fails at run time'" CFLAGS="$saved_CFLAGS" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -9688,13 +9820,17 @@ fi fi else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext + +fi +eval ac_res=\$$ossh_cache_var + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } } # clang 15 seems to have a bug in -fzero-call-used-regs=all. See # https://bugzilla.mindrot.org/show_bug.cgi?id=3475 and @@ -9703,8 +9839,14 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam \ # flag at all (https://bugzilla.mindrot.org/show_bug.cgi?id=3629) case "$CLANG_VER" in apple-15*) { - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -fzero-call-used-regs=used and linking succeeds" >&5 + ossh_cache_var=ossh_cv_cflag__fzero_call_used_regs_used + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -fzero-call-used-regs=used and linking succeeds" >&5 printf %s "checking if $CC supports compile flag -fzero-call-used-regs=used and linking succeeds... " >&6; } +if eval test \${$ossh_cache_var+y} +then : + printf %s "(cached) " >&6 +else $as_nop + saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -fzero-call-used-regs=used" _define_flag="" @@ -9769,14 +9911,12 @@ then : if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" else if test "$cross_compiling" = yes then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -9836,12 +9976,10 @@ int main(int argc, char **argv) { _ACEOF if ac_fn_c_try_run "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, fails at run time" >&5 -printf "%s\n" "no, fails at run time" >&6; } + eval "$ossh_cache_var='no, fails at run time'" CFLAGS="$saved_CFLAGS" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -9850,18 +9988,28 @@ fi fi else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext + +fi +eval ac_res=\$$ossh_cache_var + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } } ;; 17*) ;; *) { - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -fzero-call-used-regs=used and linking succeeds" >&5 + ossh_cache_var=ossh_cv_cflag__fzero_call_used_regs_used + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -fzero-call-used-regs=used and linking succeeds" >&5 printf %s "checking if $CC supports compile flag -fzero-call-used-regs=used and linking succeeds... " >&6; } +if eval test \${$ossh_cache_var+y} +then : + printf %s "(cached) " >&6 +else $as_nop + saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -fzero-call-used-regs=used" _define_flag="" @@ -9926,14 +10074,12 @@ then : if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" else if test "$cross_compiling" = yes then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -9993,12 +10139,10 @@ int main(int argc, char **argv) { _ACEOF if ac_fn_c_try_run "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, fails at run time" >&5 -printf "%s\n" "no, fails at run time" >&6; } + eval "$ossh_cache_var='no, fails at run time'" CFLAGS="$saved_CFLAGS" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -10007,18 +10151,28 @@ fi fi else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext + +fi +eval ac_res=\$$ossh_cache_var + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } } ;; esac { - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -ftrivial-auto-var-init=zero" >&5 + ossh_cache_var=ossh_cv_cflag__ftrivial_auto_var_init_zero + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -ftrivial-auto-var-init=zero" >&5 printf %s "checking if $CC supports compile flag -ftrivial-auto-var-init=zero... " >&6; } +if eval test \${$ossh_cache_var+y} +then : + printf %s "(cached) " >&6 +else $as_nop + saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -ftrivial-auto-var-init=zero" _define_flag="" @@ -10083,14 +10237,12 @@ then : if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" else if test "$cross_compiling" = yes then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -10150,12 +10302,10 @@ int main(int argc, char **argv) { _ACEOF if ac_fn_c_try_run "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, fails at run time" >&5 -printf "%s\n" "no, fails at run time" >&6; } + eval "$ossh_cache_var='no, fails at run time'" CFLAGS="$saved_CFLAGS" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -10164,18 +10314,28 @@ fi fi else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +fi +eval ac_res=\$$ossh_cache_var + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } } fi if test "x$use_retpoline" = "x1"; then { - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -mretpoline" >&5 + ossh_cache_var=ossh_cv_cflag__mretpoline + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -mretpoline" >&5 printf %s "checking if $CC supports compile flag -mretpoline... " >&6; } +if eval test \${$ossh_cache_var+y} +then : + printf %s "(cached) " >&6 +else $as_nop + saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -mretpoline" _define_flag="" @@ -10240,14 +10400,12 @@ then : if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" else if test "$cross_compiling" = yes then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -10307,12 +10465,10 @@ int main(int argc, char **argv) { _ACEOF if ac_fn_c_try_run "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, fails at run time" >&5 -printf "%s\n" "no, fails at run time" >&6; } + eval "$ossh_cache_var='no, fails at run time'" CFLAGS="$saved_CFLAGS" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -10321,16 +10477,26 @@ fi fi else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +fi +eval ac_res=\$$ossh_cache_var + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } } # clang { - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $LD supports link flag -Wl,-z,retpolineplt" >&5 + ossh_cache_var=ossh_cv_ldflag__Wl__z_retpolineplt + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $LD supports link flag -Wl,-z,retpolineplt" >&5 printf %s "checking if $LD supports link flag -Wl,-z,retpolineplt... " >&6; } +if eval test \${$ossh_cache_var+y} +then : + printf %s "(cached) " >&6 +else $as_nop + saved_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $WERROR -Wl,-z,retpolineplt" _define_flag="" @@ -10395,14 +10561,12 @@ then : if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" LDFLAGS="$saved_LDFLAGS" else if test "$cross_compiling" = yes then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" LDFLAGS="$saved_LDFLAGS $_define_flag" else $as_nop @@ -10463,12 +10627,10 @@ int main(int argc, char **argv) { _ACEOF if ac_fn_c_try_run "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" LDFLAGS="$saved_LDFLAGS $_define_flag" else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, fails at run time" >&5 -printf "%s\n" "no, fails at run time" >&6; } + eval "$ossh_cache_var='no, fails at run time'" LDFLAGS="$saved_LDFLAGS" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -10477,13 +10639,17 @@ fi fi else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" LDFLAGS="$saved_LDFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext + +fi +eval ac_res=\$$ossh_cache_var + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } } fi @@ -10890,12 +11056,6 @@ if test "x$ac_cv_header_dirent_h" = xyes then : printf "%s\n" "#define HAVE_DIRENT_H 1" >>confdefs.h -fi -ac_fn_c_check_header_compile "$LINENO" "endian.h" "ac_cv_header_endian_h" "$ac_includes_default" -if test "x$ac_cv_header_endian_h" = xyes -then : - printf "%s\n" "#define HAVE_ENDIAN_H 1" >>confdefs.h - fi ac_fn_c_check_header_compile "$LINENO" "elf.h" "ac_cv_header_elf_h" "$ac_includes_default" if test "x$ac_cv_header_elf_h" = xyes @@ -10956,12 +11116,6 @@ if test "x$ac_cv_header_iaf_h" = xyes then : printf "%s\n" "#define HAVE_IAF_H 1" >>confdefs.h -fi -ac_fn_c_check_header_compile "$LINENO" "ifaddrs.h" "ac_cv_header_ifaddrs_h" "$ac_includes_default" -if test "x$ac_cv_header_ifaddrs_h" = xyes -then : - printf "%s\n" "#define HAVE_IFADDRS_H 1" >>confdefs.h - fi ac_fn_c_check_header_compile "$LINENO" "inttypes.h" "ac_cv_header_inttypes_h" "$ac_includes_default" if test "x$ac_cv_header_inttypes_h" = xyes @@ -11016,30 +11170,12 @@ if test "x$ac_cv_header_netdb_h" = xyes then : printf "%s\n" "#define HAVE_NETDB_H 1" >>confdefs.h -fi -ac_fn_c_check_header_compile "$LINENO" "netgroup.h" "ac_cv_header_netgroup_h" "$ac_includes_default" -if test "x$ac_cv_header_netgroup_h" = xyes -then : - printf "%s\n" "#define HAVE_NETGROUP_H 1" >>confdefs.h - fi ac_fn_c_check_header_compile "$LINENO" "pam/pam_appl.h" "ac_cv_header_pam_pam_appl_h" "$ac_includes_default" if test "x$ac_cv_header_pam_pam_appl_h" = xyes then : printf "%s\n" "#define HAVE_PAM_PAM_APPL_H 1" >>confdefs.h -fi -ac_fn_c_check_header_compile "$LINENO" "paths.h" "ac_cv_header_paths_h" "$ac_includes_default" -if test "x$ac_cv_header_paths_h" = xyes -then : - printf "%s\n" "#define HAVE_PATHS_H 1" >>confdefs.h - -fi -ac_fn_c_check_header_compile "$LINENO" "poll.h" "ac_cv_header_poll_h" "$ac_includes_default" -if test "x$ac_cv_header_poll_h" = xyes -then : - printf "%s\n" "#define HAVE_POLL_H 1" >>confdefs.h - fi ac_fn_c_check_header_compile "$LINENO" "pty.h" "ac_cv_header_pty_h" "$ac_includes_default" if test "x$ac_cv_header_pty_h" = xyes @@ -11082,12 +11218,6 @@ if test "x$ac_cv_header_stddef_h" = xyes then : printf "%s\n" "#define HAVE_STDDEF_H 1" >>confdefs.h -fi -ac_fn_c_check_header_compile "$LINENO" "stdint.h" "ac_cv_header_stdint_h" "$ac_includes_default" -if test "x$ac_cv_header_stdint_h" = xyes -then : - printf "%s\n" "#define HAVE_STDINT_H 1" >>confdefs.h - fi ac_fn_c_check_header_compile "$LINENO" "string.h" "ac_cv_header_string_h" "$ac_includes_default" if test "x$ac_cv_header_string_h" = xyes @@ -11232,12 +11362,6 @@ if test "x$ac_cv_header_sys_sysmacros_h" = xyes then : printf "%s\n" "#define HAVE_SYS_SYSMACROS_H 1" >>confdefs.h -fi -ac_fn_c_check_header_compile "$LINENO" "sys/time.h" "ac_cv_header_sys_time_h" "$ac_includes_default" -if test "x$ac_cv_header_sys_time_h" = xyes -then : - printf "%s\n" "#define HAVE_SYS_TIME_H 1" >>confdefs.h - fi ac_fn_c_check_header_compile "$LINENO" "sys/timers.h" "ac_cv_header_sys_timers_h" "$ac_includes_default" if test "x$ac_cv_header_sys_timers_h" = xyes @@ -11250,12 +11374,6 @@ if test "x$ac_cv_header_sys_vfs_h" = xyes then : printf "%s\n" "#define HAVE_SYS_VFS_H 1" >>confdefs.h -fi -ac_fn_c_check_header_compile "$LINENO" "time.h" "ac_cv_header_time_h" "$ac_includes_default" -if test "x$ac_cv_header_time_h" = xyes -then : - printf "%s\n" "#define HAVE_TIME_H 1" >>confdefs.h - fi ac_fn_c_check_header_compile "$LINENO" "tmpdir.h" "ac_cv_header_tmpdir_h" "$ac_includes_default" if test "x$ac_cv_header_tmpdir_h" = xyes @@ -11286,12 +11404,6 @@ if test "x$ac_cv_header_usersec_h" = xyes then : printf "%s\n" "#define HAVE_USERSEC_H 1" >>confdefs.h -fi -ac_fn_c_check_header_compile "$LINENO" "util.h" "ac_cv_header_util_h" "$ac_includes_default" -if test "x$ac_cv_header_util_h" = xyes -then : - printf "%s\n" "#define HAVE_UTIL_H 1" >>confdefs.h - fi ac_fn_c_check_header_compile "$LINENO" "utime.h" "ac_cv_header_utime_h" "$ac_includes_default" if test "x$ac_cv_header_utime_h" = xyes @@ -11325,6 +11437,98 @@ then : fi +# Create replacement header files for common headers that are missing on this +# platform. Usually these are just empty, but in some cases they'll include +# the equivalent file. This avoids having to wrap those includes in +# '#ifdef HAVE_FOO_H'. If we create any such headers, add the path to includes. +COMPATINCLUDES="" + for ac_header in endian.h ifaddrs.h libgen.h paths.h netgroup.h nlist.h poll.h stdint.h sys/mman.h sys/stat.h sys/time.h sys/un.h time.h util.h +do : + as_ac_Header=`printf "%s\n" "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes" +then : + cat >>confdefs.h <<_ACEOF +#define `printf "%s\n" "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +else $as_nop + + COMPATINCLUDES="openbsd-compat/include" + header="$COMPATINCLUDES/$ac_header" + dir=`dirname "$header"` + mkdir -p "$dir" + case "$ac_header" in + poll.h) echo '#ifdef HAVE_SYS_POLL_H' + echo '#include ' + echo '#endif' ;; + *) ;; + esac >"$header" + +fi + +done + + +ac_fn_check_decl "$LINENO" "le32toh" "ac_cv_have_decl_le32toh" " +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_ENDIAN_H +# include +#endif + +" "$ac_c_undeclared_builtin_options" "CFLAGS" +if test "x$ac_cv_have_decl_le32toh" = xyes +then : + ac_have_decl=1 +else $as_nop + ac_have_decl=0 +fi +printf "%s\n" "#define HAVE_DECL_LE32TOH $ac_have_decl" >>confdefs.h +ac_fn_check_decl "$LINENO" "le64toh" "ac_cv_have_decl_le64toh" " +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_ENDIAN_H +# include +#endif + +" "$ac_c_undeclared_builtin_options" "CFLAGS" +if test "x$ac_cv_have_decl_le64toh" = xyes +then : + ac_have_decl=1 +else $as_nop + ac_have_decl=0 +fi +printf "%s\n" "#define HAVE_DECL_LE64TOH $ac_have_decl" >>confdefs.h +ac_fn_check_decl "$LINENO" "htole64" "ac_cv_have_decl_htole64" " +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_ENDIAN_H +# include +#endif + +" "$ac_c_undeclared_builtin_options" "CFLAGS" +if test "x$ac_cv_have_decl_htole64" = xyes +then : + ac_have_decl=1 +else $as_nop + ac_have_decl=0 +fi +printf "%s\n" "#define HAVE_DECL_HTOLE64 $ac_have_decl" >>confdefs.h + + # On some platforms (eg SunOS4) sys/audit.h requires sys/[time|types|label.h] # to be included first. ac_fn_c_check_header_compile "$LINENO" "sys/audit.h" "ac_cv_header_sys_audit_h" " @@ -11506,6 +11710,12 @@ SPP_MSG="no" # the --with-solaris-privs option and --with-sandbox=solaris). SOLARIS_PRIVS="no" +# Default shared library extension +SHLIBEXT=".so" + +# See OpenBSD section in $host case below. +need_pledge_inet="" + # Check for some target-specific stuff case "$host" in *-*-aix*) @@ -11519,6 +11729,7 @@ printf %s "checking if compiler allows macro redefinitions... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ +#include #define testmacro foo #define testmacro bar int @@ -11820,8 +12031,14 @@ printf "%s\n" "#define FILESYSTEM_NO_BACKSLASH 1" >>confdefs.h # Cygwin defines optargs, optargs as declspec(dllimport) for historical # reasons which cause compile warnings, so we disable those warnings. { - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wno-attributes" >&5 + ossh_cache_var=ossh_cv_cflag__Wno_attributes + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wno-attributes" >&5 printf %s "checking if $CC supports compile flag -Wno-attributes... " >&6; } +if eval test \${$ossh_cache_var+y} +then : + printf %s "(cached) " >&6 +else $as_nop + saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -Wno-attributes" _define_flag="" @@ -11886,14 +12103,12 @@ then : if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" else if test "$cross_compiling" = yes then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -11953,12 +12168,10 @@ int main(int argc, char **argv) { _ACEOF if ac_fn_c_try_run "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, fails at run time" >&5 -printf "%s\n" "no, fails at run time" >&6; } + eval "$ossh_cache_var='no, fails at run time'" CFLAGS="$saved_CFLAGS" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -11967,13 +12180,18 @@ fi fi else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +fi +eval ac_res=\$$ossh_cache_var + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } } + SHLIBEXT=".dll" ;; *-*-dgux*) @@ -12138,6 +12356,7 @@ fi printf "%s\n" "#define BROKEN_POLL 1" >>confdefs.h + SHLIBEXT=".dylib" ;; *-*-dragonfly*) SSHDLIBS="$SSHDLIBS" @@ -12390,6 +12609,46 @@ printf "%s\n" "#define _PATH_BTMP \"/var/log/btmp\"" >>confdefs.h printf "%s\n" "#define LINUX_OOM_ADJUST 1" >>confdefs.h +# Check whether --with-linux-memlock-onfault was given. +if test ${with_linux_memlock_onfault+y} +then : + withval=$with_linux_memlock_onfault; + if test "x$withval" != "xno" ; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for MCL_ONFAULT" >&5 +printf %s "checking for MCL_ONFAULT... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + #include +int +main (void) +{ + mlockall(MCL_FUTURE | MCL_ONFAULT); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: supported" >&5 +printf "%s\n" "supported" >&6; } + +printf "%s\n" "#define LINUX_MEMLOCK_ONFAULT 1" >>confdefs.h + +else $as_nop + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: not supported" >&5 +printf "%s\n" "not supported" >&6; } + as_fn_error $? "MCL_ONFAULT is not available on your system" "$LINENO" 5 + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + fi + +fi + + + printf "%s\n" "#define SYSTEMD_NOTIFY 1" >>confdefs.h inet6_default_4in6=yes @@ -12645,6 +12904,9 @@ printf "%s\n" "#define LOCKED_PASSWD_PREFIX \"*LOCKED*\"" >>confdefs.h printf "%s\n" "#define SSH_TUN_FREEBSD 1" >>confdefs.h + +printf "%s\n" "#define SSH_TUN_COMPAT_AF 1" >>confdefs.h + ac_fn_c_check_header_compile "$LINENO" "net/if_tap.h" "ac_cv_header_net_if_tap_h" "$ac_includes_default" if test "x$ac_cv_header_net_if_tap_h" = xyes then : @@ -12707,6 +12969,53 @@ printf "%s\n" "#define SSH_TUN_OPENBSD 1" >>confdefs.h printf "%s\n" "#define SYSLOG_R_SAFE_IN_SIGHAND 1" >>confdefs.h TEST_MALLOC_OPTIONS="SJRU" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether pledge(2) allows IP_TOS" >&5 +printf %s "checking whether pledge(2) allows IP_TOS... " >&6; } + if test "$cross_compiling" = yes +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cross compiling: cannot test" >&5 +printf "%s\n" "$as_me: WARNING: cross compiling: cannot test" >&2;} +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +#include +#include +#include + +int +main (void) +{ + +int s, one = 1; +if ((s = socket(AF_INET, SOCK_STREAM, 0)) == -1) + err(1, "socket"); +if (pledge("stdio", NULL) == -1) + err(1, "pledge"); +if (setsockopt(s, IPPROTO_IP, IP_TOS, &one, sizeof(one)) == -1) + err(1, "setsockopt"); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO" +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +else $as_nop + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + need_pledge_inet=1 + +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + ;; *-*-solaris*) if test "x$withval" != "xno" ; then @@ -13357,6 +13666,15 @@ rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ fi +if test -z "$need_pledge_inet" ; then + printf "%s\n" "#define PLEDGE_EXTRA_INET /**/" >>confdefs.h + +else + +printf "%s\n" "#define PLEDGE_EXTRA_INET \"inet \"" >>confdefs.h + +fi + # Checks for libraries. ac_fn_c_check_func "$LINENO" "setsockopt" "ac_cv_func_setsockopt" if test "x$ac_cv_func_setsockopt" = xyes @@ -13621,25 +13939,74 @@ fi done if test ${ac_cv_search_basename+y} then : - + +else $as_nop + ac_cv_search_basename=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_basename" >&5 +printf "%s\n" "$ac_cv_search_basename" >&6; } +ac_res=$ac_cv_search_basename +if test "$ac_res" != no +then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +printf "%s\n" "#define HAVE_BASENAME 1" >>confdefs.h + +fi + + +ac_fn_c_check_func "$LINENO" "sqrt" "ac_cv_func_sqrt" +if test "x$ac_cv_func_sqrt" = xyes +then : + +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sqrt in -lm" >&5 +printf %s "checking for sqrt in -lm... " >&6; } +if test ${ac_cv_lib_m_sqrt+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_check_lib_save_LIBS=$LIBS +LIBS="-lm $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char sqrt (); +int +main (void) +{ +return sqrt (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_m_sqrt=yes else $as_nop - ac_cv_search_basename=no + ac_cv_lib_m_sqrt=no fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_basename" >&5 -printf "%s\n" "$ac_cv_search_basename" >&6; } -ac_res=$ac_cv_search_basename -if test "$ac_res" != no +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_sqrt" >&5 +printf "%s\n" "$ac_cv_lib_m_sqrt" >&6; } +if test "x$ac_cv_lib_m_sqrt" = xyes then : - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - -printf "%s\n" "#define HAVE_BASENAME 1" >>confdefs.h + TESTLIBS="$TESTLIBS -lm" +fi fi + zlib=yes # Check whether --with-zlib was given. @@ -15021,6 +15388,21 @@ rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ fi +ac_fn_c_check_member "$LINENO" "struct dirent" "d_type" "ac_cv_member_struct_dirent_d_type" " +#ifdef HAVE_DIRENT_H +#include +#endif + +" +if test "x$ac_cv_member_struct_dirent_d_type" = xyes +then : + +printf "%s\n" "#define HAVE_STRUCT_DIRENT_D_TYPE 1" >>confdefs.h + + +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for /proc/pid/fd directory" >&5 printf %s "checking for /proc/pid/fd directory... " >&6; } if test -d "/proc/$$/fd" ; then @@ -15324,6 +15706,95 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi +# Check whether user wants wtmpdb support +WTMPDB_MSG="no" + +# Check whether --with-wtmpdb was given. +if test ${with_wtmpdb+y} +then : + withval=$with_wtmpdb; if test "x$withval" != "xno" ; then + if test "x$withval" = "xyes" ; then + if test "x$PKGCONFIG" != "xno"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $PKGCONFIG knows about wtmpdb" >&5 +printf %s "checking if $PKGCONFIG knows about wtmpdb... " >&6; } + if "$PKGCONFIG" libwtmpdb; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + use_pkgconfig_for_libwtmpdb=yes + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + 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_libwtmpdb" = "xyes"; then + LIBWTMPDB=`$PKGCONFIG --libs libwtmpdb` + CPPFLAGS="$CPPFLAGS `$PKGCONFIG --cflags libwtmpdb`" + else + LIBWTMPDB="-lwtmpdb" + fi + OTHERLIBS=`echo $LIBWTMPDB | sed 's/-lwtmpdb//'` + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for wtmpdb_login in -lwtmpdb" >&5 +printf %s "checking for wtmpdb_login in -lwtmpdb... " >&6; } +if test ${ac_cv_lib_wtmpdb_wtmpdb_login+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_check_lib_save_LIBS=$LIBS +LIBS="-lwtmpdb $OTHERLIBS + $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char wtmpdb_login (); +int +main (void) +{ +return wtmpdb_login (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_wtmpdb_wtmpdb_login=yes +else $as_nop + ac_cv_lib_wtmpdb_wtmpdb_login=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_wtmpdb_wtmpdb_login" >&5 +printf "%s\n" "$ac_cv_lib_wtmpdb_wtmpdb_login" >&6; } +if test "x$ac_cv_lib_wtmpdb_wtmpdb_login" = xyes +then : + +printf "%s\n" "#define USE_WTMPDB 1" >>confdefs.h + + WTMPDB_MSG="yes" + + +else $as_nop + as_fn_error $? "libwtmpdb not found" "$LINENO" 5 +fi + + fi + +fi + + + AUDIT_MODULE=none # Check whether --with-audit was given. @@ -15523,8 +15994,14 @@ if test "x$use_pie" != "xno"; then SAVED_CFLAGS="$CFLAGS" SAVED_LDFLAGS="$LDFLAGS" { - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -fPIE" >&5 + ossh_cache_var=ossh_cv_cflag__fPIE + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -fPIE" >&5 printf %s "checking if $CC supports compile flag -fPIE... " >&6; } +if eval test \${$ossh_cache_var+y} +then : + printf %s "(cached) " >&6 +else $as_nop + saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -fPIE" _define_flag="" @@ -15589,14 +16066,12 @@ then : if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" else if test "$cross_compiling" = yes then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -15656,12 +16131,10 @@ int main(int argc, char **argv) { _ACEOF if ac_fn_c_try_run "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, fails at run time" >&5 -printf "%s\n" "no, fails at run time" >&6; } + eval "$ossh_cache_var='no, fails at run time'" CFLAGS="$saved_CFLAGS" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -15670,16 +16143,26 @@ fi fi else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +fi +eval ac_res=\$$ossh_cache_var + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } } { - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $LD supports link flag -pie" >&5 + ossh_cache_var=ossh_cv_ldflag__pie + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $LD supports link flag -pie" >&5 printf %s "checking if $LD supports link flag -pie... " >&6; } +if eval test \${$ossh_cache_var+y} +then : + printf %s "(cached) " >&6 +else $as_nop + saved_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $WERROR -pie" _define_flag="" @@ -15744,14 +16227,12 @@ then : if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" LDFLAGS="$saved_LDFLAGS" else if test "$cross_compiling" = yes then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" LDFLAGS="$saved_LDFLAGS $_define_flag" else $as_nop @@ -15812,12 +16293,10 @@ int main(int argc, char **argv) { _ACEOF if ac_fn_c_try_run "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + eval "$ossh_cache_var=yes" LDFLAGS="$saved_LDFLAGS $_define_flag" else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, fails at run time" >&5 -printf "%s\n" "no, fails at run time" >&6; } + eval "$ossh_cache_var='no, fails at run time'" LDFLAGS="$saved_LDFLAGS" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -15826,13 +16305,17 @@ fi fi else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } + eval "$ossh_cache_var=no" LDFLAGS="$saved_LDFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext + +fi +eval ac_res=\$$ossh_cache_var + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } } # We use both -fPIE and -pie or neither. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether both -fPIE and -pie are supported" >&5 @@ -16099,6 +16582,12 @@ if test "x$ac_cv_func_freezero" = xyes then : printf "%s\n" "#define HAVE_FREEZERO 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "fstatat" "ac_cv_func_fstatat" +if test "x$ac_cv_func_fstatat" = xyes +then : + printf "%s\n" "#define HAVE_FSTATAT 1" >>confdefs.h + fi ac_fn_c_check_func "$LINENO" "fstatfs" "ac_cv_func_fstatfs" if test "x$ac_cv_func_fstatfs" = xyes @@ -16303,12 +16792,24 @@ if test "x$ac_cv_func_mkdtemp" = xyes then : printf "%s\n" "#define HAVE_MKDTEMP 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "mmap" "ac_cv_func_mmap" +if test "x$ac_cv_func_mmap" = xyes +then : + printf "%s\n" "#define HAVE_MMAP 1" >>confdefs.h + fi ac_fn_c_check_func "$LINENO" "ngetaddrinfo" "ac_cv_func_ngetaddrinfo" if test "x$ac_cv_func_ngetaddrinfo" = xyes then : printf "%s\n" "#define HAVE_NGETADDRINFO 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "nlist" "ac_cv_func_nlist" +if test "x$ac_cv_func_nlist" = xyes +then : + printf "%s\n" "#define HAVE_NLIST 1" >>confdefs.h + fi ac_fn_c_check_func "$LINENO" "nsleep" "ac_cv_func_nsleep" if test "x$ac_cv_func_nsleep" = xyes @@ -16669,6 +17170,12 @@ if test "x$ac_cv_func_truncate" = xyes then : printf "%s\n" "#define HAVE_TRUNCATE 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "unlinkat" "ac_cv_func_unlinkat" +if test "x$ac_cv_func_unlinkat" = xyes +then : + printf "%s\n" "#define HAVE_UNLINKAT 1" >>confdefs.h + fi ac_fn_c_check_func "$LINENO" "unsetenv" "ac_cv_func_unsetenv" if test "x$ac_cv_func_unsetenv" = xyes @@ -16726,6 +17233,40 @@ then : fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether compiler supports __builtin_popcount" >&5 +printf %s "checking whether compiler supports __builtin_popcount... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include + +int +main (void) +{ + int x = 123, y; + y = __builtin_popcount(123); + exit(y == 6 ? 0 : -1); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +else $as_nop + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + +printf "%s\n" "#define MISSING_BUILTIN_POPCOUNT 1" >>confdefs.h + + + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + ac_fn_check_decl "$LINENO" "bzero" "ac_cv_have_decl_bzero" "$ac_includes_default" "$ac_c_undeclared_builtin_options" "CFLAGS" if test "x$ac_cv_have_decl_bzero" = xyes then : @@ -16868,15 +17409,12 @@ then : fi -enable_dsa= -# Check whether --enable-dsa-keys was given. -if test ${enable_dsa_keys+y} -then : - enableval=$enable_dsa_keys; - if test "x$enableval" != "xno" ; then - enable_dsa=1 - fi +enable_sk_standalone= +# Check whether --with-security-key-standalone was given. +if test ${with_security_key_standalone+y} +then : + withval=$with_security_key_standalone; enable_sk_standalone=$withval fi @@ -17315,6 +17853,32 @@ fi printf "%s\n" "#define HAVE_DECL_OFFSETOF $ac_have_decl" >>confdefs.h +ac_fn_check_decl "$LINENO" "INFINITY" "ac_cv_have_decl_INFINITY" "#include + +" "$ac_c_undeclared_builtin_options" "CFLAGS" +if test "x$ac_cv_have_decl_INFINITY" = xyes +then : + ac_have_decl=1 +else $as_nop + ac_have_decl=0 +fi +printf "%s\n" "#define HAVE_DECL_INFINITY $ac_have_decl" >>confdefs.h +if test $ac_have_decl = 1 +then : + +else $as_nop + ac_fn_check_decl "$LINENO" "__builtin_inff" "ac_cv_have_decl___builtin_inff" "$ac_includes_default" "$ac_c_undeclared_builtin_options" "CFLAGS" +if test "x$ac_cv_have_decl___builtin_inff" = xyes +then : + ac_have_decl=1 +else $as_nop + ac_have_decl=0 +fi +printf "%s\n" "#define HAVE_DECL___BUILTIN_INFF $ac_have_decl" >>confdefs.h + +fi + + # extra bits for select(2) ac_fn_check_decl "$LINENO" "howmany" "ac_cv_have_decl_howmany" " #include @@ -17938,6 +18502,9 @@ printf %s "checking whether snprintf can declare const char *fmt... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ +#ifdef _FORTIFY_SOURCE +#undef _FORTIFY_SOURCE +#endif #include int snprintf(char *a, size_t b, const char *c, ...) { return 0; } @@ -18783,8 +19350,8 @@ then : *) ;; # Assume all other versions are good. esac ;; - 30*) - # OpenSSL 3; we use the 1.1x API + 30*|40*) + # OpenSSL 3 & 4; we use the 1.1x API # https://openssl.org/policies/general/versioning-policy.html CPPFLAGS="$CPPFLAGS -DOPENSSL_API_COMPAT=0x10100000L" ;; @@ -18947,12 +19514,6 @@ if test "x$ac_cv_func_DES_crypt" = xyes then : printf "%s\n" "#define HAVE_DES_CRYPT 1" >>confdefs.h -fi -ac_fn_c_check_func "$LINENO" "DSA_generate_parameters_ex" "ac_cv_func_DSA_generate_parameters_ex" -if test "x$ac_cv_func_DSA_generate_parameters_ex" = xyes -then : - printf "%s\n" "#define HAVE_DSA_GENERATE_PARAMETERS_EX 1" >>confdefs.h - fi ac_fn_c_check_func "$LINENO" "EVP_DigestSign" "ac_cv_func_EVP_DigestSign" if test "x$ac_cv_func_EVP_DigestSign" = xyes @@ -19038,7 +19599,31 @@ fi # LibreSSL/OpenSSL API differences - ac_fn_c_check_func "$LINENO" "EVP_CIPHER_CTX_iv" "ac_cv_func_EVP_CIPHER_CTX_iv" + ac_fn_c_check_func "$LINENO" "EC_POINT_get_affine_coordinates" "ac_cv_func_EC_POINT_get_affine_coordinates" +if test "x$ac_cv_func_EC_POINT_get_affine_coordinates" = xyes +then : + printf "%s\n" "#define HAVE_EC_POINT_GET_AFFINE_COORDINATES 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "EC_POINT_get_affine_coordinates_GFp" "ac_cv_func_EC_POINT_get_affine_coordinates_GFp" +if test "x$ac_cv_func_EC_POINT_get_affine_coordinates_GFp" = xyes +then : + printf "%s\n" "#define HAVE_EC_POINT_GET_AFFINE_COORDINATES_GFP 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "EC_POINT_set_affine_coordinates" "ac_cv_func_EC_POINT_set_affine_coordinates" +if test "x$ac_cv_func_EC_POINT_set_affine_coordinates" = xyes +then : + printf "%s\n" "#define HAVE_EC_POINT_SET_AFFINE_COORDINATES 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "EC_POINT_set_affine_coordinates_GFp" "ac_cv_func_EC_POINT_set_affine_coordinates_GFp" +if test "x$ac_cv_func_EC_POINT_set_affine_coordinates_GFp" = xyes +then : + printf "%s\n" "#define HAVE_EC_POINT_SET_AFFINE_COORDINATES_GFP 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "EVP_CIPHER_CTX_iv" "ac_cv_func_EVP_CIPHER_CTX_iv" if test "x$ac_cv_func_EVP_CIPHER_CTX_iv" = xyes then : printf "%s\n" "#define HAVE_EVP_CIPHER_CTX_IV 1" >>confdefs.h @@ -19463,63 +20048,18 @@ printf "%s\n" "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext - - openssl_dsa=no - if test ! -z "$enable_dsa" ; then - ac_fn_check_decl "$LINENO" "OPENSSL_NO_DSA" "ac_cv_have_decl_OPENSSL_NO_DSA" " #include - -" "$ac_c_undeclared_builtin_options" "CFLAGS" -if test "x$ac_cv_have_decl_OPENSSL_NO_DSA" = xyes -then : - ac_have_decl=1 -else $as_nop - ac_have_decl=0 fi -printf "%s\n" "#define HAVE_DECL_OPENSSL_NO_DSA $ac_have_decl" >>confdefs.h -if test $ac_have_decl = 1 -then : -else $as_nop +# PKCS11/U2F depend on OpenSSL and dlopen(). +enable_pkcs11=yes +enable_sk=yes - ac_fn_check_decl "$LINENO" "OPENSSL_IS_BORINGSSL" "ac_cv_have_decl_OPENSSL_IS_BORINGSSL" " #include +ac_fn_check_decl "$LINENO" "OPENSSL_IS_AWSLC" "ac_cv_have_decl_OPENSSL_IS_AWSLC" "#include " "$ac_c_undeclared_builtin_options" "CFLAGS" -if test "x$ac_cv_have_decl_OPENSSL_IS_BORINGSSL" = xyes -then : - ac_have_decl=1 -else $as_nop - ac_have_decl=0 -fi -printf "%s\n" "#define HAVE_DECL_OPENSSL_IS_BORINGSSL $ac_have_decl" >>confdefs.h -if test $ac_have_decl = 1 +if test "x$ac_cv_have_decl_OPENSSL_IS_AWSLC" = xyes then : - -else $as_nop - openssl_dsa=yes -fi - - -fi - - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable DSA key support" >&5 -printf %s "checking whether to enable DSA key support... " >&6; } - if test "x$openssl_dsa" = "xno"; then - as_fn_error $? "DSA requested but not supported by OpenSSL" "$LINENO" 5 - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - -printf "%s\n" "#define WITH_DSA 1" >>confdefs.h - - fi - 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" + enable_pkcs11="disabled; PKCS#11 not supported with AWS-LC" fi if test "x$ac_cv_func_dlopen" != "xyes" ; then enable_pkcs11="disabled; missing dlopen(3)" @@ -19718,6 +20258,21 @@ fi fi fi +# Check for standalone SecurityKeyProvider +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to build standalone sk-libfido2" >&5 +printf %s "checking whether to build standalone sk-libfido2... " >&6; } +if test "x$enable_sk_standalone" = "xyes" ; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + SK_STANDALONE=sk-libfido2$SHLIBEXT + +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + SK_STANDALONE="" + +fi + ac_fn_c_check_func "$LINENO" "arc4random" "ac_cv_func_arc4random" if test "x$ac_cv_func_arc4random" = xyes then : @@ -20536,23 +21091,7 @@ fi 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" && \ - as_fn_error $? "pledge sandbox requires pledge(2) support" "$LINENO" 5 - SANDBOX_STYLE="pledge" - -printf "%s\n" "#define SANDBOX_PLEDGE 1" >>confdefs.h - -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" && \ - as_fn_error $? "systrace sandbox requires systrace headers and SYSTR_POLICY_KILL support" "$LINENO" 5 - SANDBOX_STYLE="systrace" - -printf "%s\n" "#define SANDBOX_SYSTRACE 1" >>confdefs.h - -elif test "x$sandbox_arg" = "xdarwin" || \ +if 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 \ @@ -22226,7 +22765,11 @@ int main(void) long long num = 0x7fffffffffffffffll; #endif strcpy(expected_out, "9223372036854775807"); +#if (SIZEOF_LONG_INT == 8) + snprintf(buf, mazsize, "%ld", num); +#else snprintf(buf, mazsize, "%lld", num); +#endif if(strcmp(buf, expected_out) != 0) exit(1); exit(0); @@ -26312,8 +26855,8 @@ 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//'` +LDFLAGS_NOPIE=`echo "$LDFLAGS" | sed 's/^-pie //;s/ -pie//g'` +CFLAGS_NOPIE=`echo "$CFLAGS" | sed 's/^-fPIE //;s/ -fPIE//g'` diff --git a/configure.ac b/configure.ac index 9053a9a..db52110 100644 --- a/configure.ac +++ b/configure.ac @@ -114,11 +114,6 @@ AC_C_INLINE AC_CHECK_DECL([LLONG_MAX], [have_llong_max=1], , [#include ]) AC_CHECK_DECL([LONG_LONG_MAX], [have_long_long_max=1], , [#include ]) -AC_CHECK_DECL([SYSTR_POLICY_KILL], [have_systr_policy_kill=1], , [ - #include - #include - #include -]) AC_CHECK_DECL([RLIMIT_NPROC], [AC_DEFINE([HAVE_RLIMIT_NPROC], [], [sys/resource.h has RLIMIT_NPROC])], , [ #include @@ -462,7 +457,6 @@ AC_CHECK_HEADERS([ \ crypt.h \ crypto/sha2.h \ dirent.h \ - endian.h \ elf.h \ err.h \ features.h \ @@ -473,7 +467,6 @@ AC_CHECK_HEADERS([ \ glob.h \ ia.h \ iaf.h \ - ifaddrs.h \ inttypes.h \ langinfo.h \ limits.h \ @@ -483,10 +476,7 @@ AC_CHECK_HEADERS([ \ 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 \ @@ -494,7 +484,6 @@ AC_CHECK_HEADERS([ \ sha2.h \ shadow.h \ stddef.h \ - stdint.h \ string.h \ strings.h \ sys/bitypes.h \ @@ -519,16 +508,13 @@ AC_CHECK_HEADERS([ \ 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 \ @@ -536,6 +522,51 @@ AC_CHECK_HEADERS([ \ wchar.h \ ]) +# Create replacement header files for common headers that are missing on this +# platform. Usually these are just empty, but in some cases they'll include +# the equivalent file. This avoids having to wrap those includes in +# '#ifdef HAVE_FOO_H'. If we create any such headers, add the path to includes. +COMPATINCLUDES="" +AC_CHECK_HEADERS([ \ + endian.h \ + ifaddrs.h \ + libgen.h \ + paths.h \ + netgroup.h \ + nlist.h \ + poll.h \ + stdint.h \ + sys/mman.h \ + sys/stat.h \ + sys/time.h \ + sys/un.h \ + time.h \ + util.h], [], [ + COMPATINCLUDES="openbsd-compat/include" + header="$COMPATINCLUDES/$ac_header" + dir=`dirname "$header"` + mkdir -p "$dir" + case "$ac_header" in + poll.h) echo '#ifdef HAVE_SYS_POLL_H' + echo '#include ' + echo '#endif' ;; + *) ;; + esac >"$header" +]) +AC_SUBST([COMPATINCLUDES]) + +AC_CHECK_DECLS([le32toh, le64toh, htole64], [], [], [ +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_ENDIAN_H +# include +#endif +]) + # On some platforms (eg SunOS4) sys/audit.h requires sys/[time|types|label.h] # to be included first. AC_CHECK_HEADERS([sys/audit.h], [], [], [ @@ -619,6 +650,12 @@ SPP_MSG="no" # the --with-solaris-privs option and --with-sandbox=solaris). SOLARIS_PRIVS="no" +# Default shared library extension +SHLIBEXT=".so" + +# See OpenBSD section in $host case below. +need_pledge_inet="" + # Check for some target-specific stuff case "$host" in *-*-aix*) @@ -630,6 +667,7 @@ case "$host" in AC_MSG_CHECKING([if compiler allows macro redefinitions]) AC_COMPILE_IFELSE( [AC_LANG_PROGRAM([[ +#include #define testmacro foo #define testmacro bar]], [[ exit(0); ]])], @@ -737,6 +775,7 @@ case "$host" in # 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]) + SHLIBEXT=".dll" ;; *-*-dgux*) AC_DEFINE([IP_TOS_IS_BROKEN], [1], @@ -796,6 +835,7 @@ int main(void) { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) # cf. Apple bug 3710161 (not public, but searchable) AC_DEFINE([BROKEN_POLL], [1], [System poll(2) implementation is broken]) + SHLIBEXT=".dylib" ;; *-*-dragonfly*) SSHDLIBS="$SSHDLIBS" @@ -915,6 +955,27 @@ int main(void) { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) 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]) + AC_ARG_WITH([linux-memlock-onfault], + [ --with-linux-memlock-onfault Enables memory locking on Linux], + [ + if test "x$withval" != "xno" ; then + AC_MSG_CHECKING([for MCL_ONFAULT]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM( + [[ #include ]], + [[ mlockall(MCL_FUTURE | MCL_ONFAULT); ]], + )], + [ + AC_MSG_RESULT([supported]) + AC_DEFINE([LINUX_MEMLOCK_ONFAULT], [1], + [Lock all memory to protect sshd against Linux kcompactd] )], + [ + AC_MSG_RESULT([not supported]) + AC_MSG_ERROR([MCL_ONFAULT is not available on your system]) + ]) + fi + ], + ) + AC_DEFINE([SYSTEMD_NOTIFY], [1], [Have sshd notify systemd on start/reload]) inet6_default_4in6=yes case `uname -r` in @@ -1058,6 +1119,8 @@ mips-sony-bsd|mips-sony-newsos4) *-*-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_DEFINE([SSH_TUN_COMPAT_AF], [1], + [Use tunnel device compatibility to OpenBSD]) 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]) @@ -1094,6 +1157,28 @@ mips-sony-bsd|mips-sony-newsos4) AC_DEFINE([SYSLOG_R_SAFE_IN_SIGHAND], [1], [syslog_r function is safe to use in in a signal handler]) TEST_MALLOC_OPTIONS="SJRU" + AC_MSG_CHECKING([whether pledge(2) allows IP_TOS]) + AC_RUN_IFELSE( + [AC_LANG_PROGRAM([[ +#include +#include +#include +#include +#include + ]], [[ +int s, one = 1; +if ((s = socket(AF_INET, SOCK_STREAM, 0)) == -1) + err(1, "socket"); +if (pledge("stdio", NULL) == -1) + err(1, "pledge"); +if (setsockopt(s, IPPROTO_IP, IP_TOS, &one, sizeof(one)) == -1) + err(1, "setsockopt"); + ]])], + [ AC_MSG_RESULT([yes]) ], [ + AC_MSG_RESULT([no]) + need_pledge_inet=1 + ], + [ AC_MSG_WARN([cross compiling: cannot test]) ]) ;; *-*-solaris*) if test "x$withval" != "xno" ; then @@ -1367,6 +1452,14 @@ AC_RUN_IFELSE([AC_LANG_PROGRAM([[ #include ]], [[ exit(0); ]])], [ AC_MSG_WARN([cross compiling: not checking compiler sanity]) ] ) +dnl Finish up special pledge(2) handling from above. +if test -z "$need_pledge_inet" ; then + AC_DEFINE_UNQUOTED([PLEDGE_EXTRA_INET], []) +else + AC_DEFINE_UNQUOTED([PLEDGE_EXTRA_INET], ["inet "], + [need inet in pledge for setsockopt IP_TOS]) +fi + dnl Checks for header files. # Checks for libraries. AC_CHECK_FUNC([setsockopt], , [AC_CHECK_LIB([socket], [setsockopt])]) @@ -1415,6 +1508,11 @@ AC_CHECK_FUNC([getspnam], , AC_SEARCH_LIBS([basename], [gen], [AC_DEFINE([HAVE_BASENAME], [1], [Define if you have the basename function.])]) +dnl sqrt() only used in unit tests. +AC_CHECK_FUNC([sqrt], , + [AC_CHECK_LIB([m], [sqrt], [TESTLIBS="$TESTLIBS -lm"])]) +AC_SUBST([TESTLIBS]) + dnl zlib defaults to enabled zlib=yes AC_ARG_WITH([zlib], @@ -1661,6 +1759,12 @@ AC_RUN_IFELSE( ] ) +AC_CHECK_MEMBERS([struct dirent.d_type], [], [], [[ +#ifdef HAVE_DIRENT_H +#include +#endif +]]) + 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]) @@ -1772,6 +1876,48 @@ AC_ARG_WITH([libedit], fi ] ) +# Check whether user wants wtmpdb support +WTMPDB_MSG="no" +AC_ARG_WITH([wtmpdb], + [ --with-wtmpdb[[=PATH]] Enable wtmpdb support for sshd], + [ 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 wtmpdb]) + if "$PKGCONFIG" libwtmpdb; then + AC_MSG_RESULT([yes]) + use_pkgconfig_for_libwtmpdb=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_libwtmpdb" = "xyes"; then + LIBWTMPDB=`$PKGCONFIG --libs libwtmpdb` + CPPFLAGS="$CPPFLAGS `$PKGCONFIG --cflags libwtmpdb`" + else + LIBWTMPDB="-lwtmpdb" + fi + OTHERLIBS=`echo $LIBWTMPDB | sed 's/-lwtmpdb//'` + AC_CHECK_LIB([wtmpdb], [wtmpdb_login], + [ AC_DEFINE([USE_WTMPDB], [1], [Use libwtmpdb for sshd]) + WTMPDB_MSG="yes" + AC_SUBST([LIBWTMPDB]) + ], + [ AC_MSG_ERROR([libwtmpdb not found]) ], + [ $OTHERLIBS ] + ) + fi ] +) + + AUDIT_MODULE=none AC_ARG_WITH([audit], [ --with-audit=module Enable audit support (modules=debug,bsm,linux)], @@ -1923,6 +2069,7 @@ AC_CHECK_FUNCS([ \ fnmatch \ freeaddrinfo \ freezero \ + fstatat \ fstatfs \ fstatvfs \ futimes \ @@ -1957,7 +2104,9 @@ AC_CHECK_FUNCS([ \ memmove \ memset_s \ mkdtemp \ + mmap \ ngetaddrinfo \ + nlist \ nsleep \ ogetaddrinfo \ openlog_r \ @@ -2018,6 +2167,7 @@ AC_CHECK_FUNCS([ \ timegm \ timingsafe_bcmp \ truncate \ + unlinkat \ unsetenv \ updwtmpx \ utimensat \ @@ -2029,6 +2179,19 @@ AC_CHECK_FUNCS([ \ warn \ ]) +AC_MSG_CHECKING([whether compiler supports __builtin_popcount]) +AC_LINK_IFELSE([AC_LANG_PROGRAM([[ + #include + ]], + [[ int x = 123, y; + y = __builtin_popcount(123); + exit(y == 6 ? 0 : -1); ]])], + [ AC_MSG_RESULT([yes]) ], [ + AC_MSG_RESULT([no]) + AC_DEFINE([MISSING_BUILTIN_POPCOUNT], [1], [Define if your compiler lacks __builtin_popcount]) + ] +) + AC_CHECK_DECLS([bzero, memmem]) dnl Wide character support. @@ -2084,14 +2247,10 @@ AC_ARG_WITH([security-key-builtin], [ enable_sk_internal=$withval ] ) -enable_dsa= -AC_ARG_ENABLE([dsa-keys], - [ --enable-dsa-keys enable DSA key support [no]], - [ - if test "x$enableval" != "xno" ; then - enable_dsa=1 - fi - ] +enable_sk_standalone= +AC_ARG_WITH([security-key-standalone], + [ --with-security-key-standalone build standalone sk-libfido2 SecurityKeyProvider], + [ enable_sk_standalone=$withval ] ) AC_SEARCH_LIBS([dlopen], [dl]) @@ -2190,6 +2349,11 @@ AC_CHECK_DECLS([offsetof], , , [ #include ]) +AC_CHECK_DECLS([INFINITY], , + AC_CHECK_DECLS(__builtin_inff), + [#include ] +) + # extra bits for select(2) AC_CHECK_DECLS([howmany, NFDBITS], [], [], [[ #include @@ -2400,6 +2564,9 @@ fi # This is only useful for when BROKEN_SNPRINTF AC_MSG_CHECKING([whether snprintf can declare const char *fmt]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#ifdef _FORTIFY_SOURCE +#undef _FORTIFY_SOURCE +#endif #include int snprintf(char *a, size_t b, const char *c, ...) { return 0; } ]], [[ @@ -2890,8 +3057,8 @@ if test "x$openssl" = "xyes" ; then *) ;; # Assume all other versions are good. esac ;; - 30*) - # OpenSSL 3; we use the 1.1x API + 30*|40*) + # OpenSSL 3 & 4; we use the 1.1x API # https://openssl.org/policies/general/versioning-policy.html CPPFLAGS="$CPPFLAGS -DOPENSSL_API_COMPAT=0x10100000L" ;; @@ -2981,7 +3148,6 @@ if test "x$openssl" = "xyes" ; then AC_CHECK_FUNCS([ \ BN_is_prime_ex \ DES_crypt \ - DSA_generate_parameters_ex \ EVP_DigestSign \ EVP_DigestVerify \ EVP_DigestFinal_ex \ @@ -3005,6 +3171,10 @@ if test "x$openssl" = "xyes" ; then # LibreSSL/OpenSSL API differences AC_CHECK_FUNCS([ \ + EC_POINT_get_affine_coordinates \ + EC_POINT_get_affine_coordinates_GFp \ + EC_POINT_set_affine_coordinates \ + EC_POINT_set_affine_coordinates_GFp \ EVP_CIPHER_CTX_iv \ EVP_CIPHER_CTX_iv_noconst \ EVP_CIPHER_CTX_get_iv \ @@ -3202,34 +3372,17 @@ if test "x$openssl" = "xyes" ; then AC_MSG_RESULT([no]) ] ) - - openssl_dsa=no - if test ! -z "$enable_dsa" ; then - AC_CHECK_DECLS([OPENSSL_NO_DSA], [], [ - AC_CHECK_DECLS([OPENSSL_IS_BORINGSSL], [], - [ openssl_dsa=yes ], - [ #include ] - ) - ], - [ #include ] - ) - AC_MSG_CHECKING([whether to enable DSA key support]) - if test "x$openssl_dsa" = "xno"; then - AC_MSG_ERROR([DSA requested but not supported by OpenSSL]) - else - AC_MSG_RESULT([yes]) - AC_DEFINE([WITH_DSA], [1], - [DSA keys explicitly enabled]) - fi - 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 + +AC_CHECK_DECL([OPENSSL_IS_AWSLC], + [enable_pkcs11="disabled; PKCS#11 not supported with AWS-LC"], + [], + [#include ] +) if test "x$ac_cv_func_dlopen" != "xyes" ; then enable_pkcs11="disabled; missing dlopen(3)" enable_sk="disabled; missing dlopen(3)" @@ -3321,6 +3474,16 @@ if test "x$enable_sk" = "xyes" -a "x$enable_sk_internal" != "xno" ; then fi fi +# Check for standalone SecurityKeyProvider +AC_MSG_CHECKING([whether to build standalone sk-libfido2]) +if test "x$enable_sk_standalone" = "xyes" ; then + AC_MSG_RESULT([yes]) + AC_SUBST([SK_STANDALONE], [sk-libfido2$SHLIBEXT]) +else + AC_MSG_RESULT([no]) + AC_SUBST([SK_STANDALONE], [""]) +fi + AC_CHECK_FUNCS([ \ arc4random \ arc4random_buf \ @@ -3613,7 +3776,7 @@ AC_CHECK_TYPES([nfds_t], , , [ # 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)], + [ --with-sandbox=style Specify privilege separation sandbox (no, capsicum, darwin, rlimit, seccomp_filter)], [ if test "x$withval" = "xyes" ; then sandbox_arg="" @@ -3730,19 +3893,7 @@ if test "x$sandbox_arg" != "xno"; then ) 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" || \ +if 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 \ @@ -4361,7 +4512,11 @@ int main(void) long long num = 0x7fffffffffffffffll; #endif strcpy(expected_out, "9223372036854775807"); +#if (SIZEOF_LONG_INT == 8) + snprintf(buf, mazsize, "%ld", num); +#else snprintf(buf, mazsize, "%lld", num); +#endif if(strcmp(buf, expected_out) != 0) exit(1); exit(0); @@ -5657,8 +5812,8 @@ 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//'` +LDFLAGS_NOPIE=`echo "$LDFLAGS" | sed 's/^-pie //;s/ -pie//g'` +CFLAGS_NOPIE=`echo "$CFLAGS" | sed 's/^-fPIE //;s/ -fPIE//g'` AC_SUBST([LDFLAGS_NOPIE]) AC_SUBST([CFLAGS_NOPIE]) diff --git a/contrib/Makefile b/contrib/Makefile index 45d878b..1482783 100644 --- a/contrib/Makefile +++ b/contrib/Makefile @@ -1,7 +1,7 @@ PKG_CONFIG = pkg-config all: - @echo "Valid targets: gnome-ssh-askpass1 gnome-ssh-askpass2 gnome-ssk-askpass3" + @echo "Valid targets: gnome-ssh-askpass1 gnome-ssh-askpass2 gnome-ssk-askpass3 gnome-ssh-askpass4" gnome-ssh-askpass1: gnome-ssh-askpass1.c $(CC) $(CFLAGS) `gnome-config --cflags gnome gnomeui` \ @@ -18,5 +18,10 @@ gnome-ssh-askpass3: gnome-ssh-askpass3.c gnome-ssh-askpass3.c -o gnome-ssh-askpass3 \ `$(PKG_CONFIG) --libs gtk+-3.0 x11` +gnome-ssh-askpass4: gnome-ssh-askpass4.c + $(CC) $(CFLAGS) `$(PKG_CONFIG) --cflags gcr-4 gio-2.0` \ + gnome-ssh-askpass4.c -o gnome-ssh-askpass4 \ + `$(PKG_CONFIG) --libs gcr-4 gio-2.0` + clean: rm -f *.o gnome-ssh-askpass gnome-ssh-askpass[123] diff --git a/contrib/README b/contrib/README index 60e19ba..614152a 100644 --- a/contrib/README +++ b/contrib/README @@ -30,10 +30,12 @@ ssh-copy-id: Phil Hands' shell script to automate the process of adding your public key to a remote machine's ~/.ssh/authorized_keys file. -gnome-ssh-askpass[12]: +gnome-ssh-askpass[1234]: -A GNOME and Gtk2 passphrase requesters. Use "make gnome-ssh-askpass1" or -"make gnome-ssh-askpass2" to build. +Graphical passhrase requesters. Use "make gnome-ssh-askpass1" to build +a variant for ancient GNOME desktop, "make gnome-ssh-askpass2" +for a GTK 2-based one, "make gnome-ssh-askpass3" for a GTK 3-based one, +or "make gnome-ssh-askpass4" for a version for modern GNOME. sshd.pam.generic: diff --git a/contrib/cygwin/ssh-user-config b/contrib/cygwin/ssh-user-config index 6fa4bb3..35802d0 100644 --- a/contrib/cygwin/ssh-user-config +++ b/contrib/cygwin/ssh-user-config @@ -58,7 +58,7 @@ create_identity() { else ssh-keygen -t "${type}" -f "${pwdhome}/.ssh/${file}" > /dev/null fi - if csih_request "Do you want to use this identity to login to this machine?" + if csih_request "Do you want to use this identity to log in to this machine?" then csih_inform "Adding to ${pwdhome}/.ssh/authorized_keys" cat "${pwdhome}/.ssh/${file}.pub" >> "${pwdhome}/.ssh/authorized_keys" @@ -246,9 +246,8 @@ done check_user_homedir check_user_dot_ssh_dir create_identity id_rsa rsa "SSH2 RSA" -create_identity id_dsa dsa "SSH2 DSA" +create_identity id_ed25519 ed25519 "SSH2 Ed25519" create_identity id_ecdsa ecdsa "SSH2 ECDSA" -create_identity identity rsa1 "(deprecated) SSH1 RSA" fix_authorized_keys_perms echo diff --git a/contrib/gnome-ssh-askpass4.c b/contrib/gnome-ssh-askpass4.c new file mode 100644 index 0000000..182bce0 --- /dev/null +++ b/contrib/gnome-ssh-askpass4.c @@ -0,0 +1,249 @@ +/* + * Copyright (c) 2000-2002 Damien Miller. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* GCR support by Jan Tojnar */ + +/* + * This is a simple SSH passphrase grabber for GNOME. To use it, set the + * environment variable SSH_ASKPASS to point to the location of + * gnome-ssh-askpass before calling "ssh-add < /dev/null". + */ + +/* + * Known problems: + * - This depends on unstable libgcr features + * - long key fingerprints may be truncted: + * https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/6781 + */ + +/* + * Compile with: + * + * cc -Wall `pkg-config --cflags gcr-4 gio-2.0` \ + * gnome-ssh-askpass4.c -o gnome-ssh-askpass \ + * `pkg-config --libs gcr-4 gio-2.0` + * + */ + +#include +#include + +#include + +#define GCR_API_SUBJECT_TO_CHANGE 1 +#include + +typedef enum _PromptType { + PROMPT_ENTRY, + PROMPT_CONFIRM, + PROMPT_NONE, +} PromptType; + +typedef struct _PromptState { + GApplication *app; + char* message; + PromptType type; + int exit_status; +} PromptState; + +static PromptState * +prompt_state_new(GApplication *app, char* message, PromptType type) +{ + PromptState *state = g_malloc(sizeof(PromptState)); + state->app = g_object_ref(app); + state->message = g_strdup(message); + state->type = type; + state->exit_status = -1; + return state; +} + +static void +prompt_state_free(PromptState *state) +{ + g_clear_object(&state->app); + g_free(state->message); + g_free(state); +} + +G_DEFINE_AUTOPTR_CLEANUP_FUNC(PromptState, prompt_state_free) + +static void +prompt_password_done(GObject *source_object, GAsyncResult *res, + gpointer user_data) +{ + GcrPrompt *prompt = GCR_PROMPT(source_object); + PromptState *state = user_data; + g_autoptr(GError) error = NULL; + + /* + * “The returned password is valid until the next time a method + * is called to display another prompt.” + */ + const char *pw = gcr_prompt_password_finish(prompt, res, &error); + + if ((!pw && !error) || (error && error->code == G_IO_ERROR_CANCELLED)) { + /* Operation was cancelled or timed out. */ + state->exit_status = -1; + } else if (error) { + warnx("Failed to prompt for ssh-askpass: %s", error->message); + state->exit_status = 1; + } else { + /* Report passphrase if user selected Continue. */ + g_autofree char *local = g_locale_from_utf8(pw, strlen(pw), + NULL, NULL, NULL); + + if (local != NULL) { + puts(local); + memset(local, '\0', strlen(local)); + } else { + puts(pw); + } + state->exit_status = 0; + } + + g_application_release(state->app); +} + +static void +prompt_confirm_done(GObject *source_object, GAsyncResult *res, + gpointer user_data) +{ + GcrPrompt *prompt = GCR_PROMPT(source_object); + PromptState *state = user_data; + g_autoptr(GError) error = NULL; + + GcrPromptReply reply = gcr_prompt_confirm_finish(prompt, res, &error); + if (error) { + if (error->code == G_IO_ERROR_CANCELLED) { + /* Operation was cancelled or timed out. */ + state->exit_status = -1; + } else { + state->exit_status = 1; + warnx("Failed to prompt for ssh-askpass: %s", + error->message); + } + } else if (reply == GCR_PROMPT_REPLY_CONTINUE || + state->type == PROMPT_NONE) { + /* + * Since Gcr doesn’t yet support one button message + * boxes treat Cancel the same as Continue. + */ + state->exit_status = 0; + } else { + /* GCR_PROMPT_REPLY_CANCEL */ + state->exit_status = -1; + } + + g_application_release(state->app); +} + +static int +command_line(GApplication* app, G_GNUC_UNUSED GApplicationCommandLine *cmdline, + gpointer user_data) +{ + PromptState *state = user_data; + + /* Prevent app from exiting while waiting for the async callback. */ + g_application_hold(app); + + /* Wait indefinitely. */ + int timeout_seconds = -1; + g_autoptr(GError) error = NULL; + GcrPrompt* prompt = gcr_system_prompt_open(timeout_seconds, NULL, &error); + + if (!prompt) { + if (error->code == GCR_SYSTEM_PROMPT_IN_PROGRESS) { + /* + * This means the timeout elapsed, but no prompt + * was ever shown. + */ + warnx("Timeout: the Gcr system prompter was " + "already in use."); + } else { + warnx("Couldn’t create prompt for ssh-askpass: %s", + error->message); + } + + return 1; + } + + gcr_prompt_set_message(prompt, "OpenSSH"); + gcr_prompt_set_description(prompt, state->message); + + /* + * XXX: Remove the Cancel button for PROMPT_NONE when GCR + * supports that. + */ + if (state->type == PROMPT_ENTRY) { + gcr_prompt_password_async(prompt, NULL, prompt_password_done, state); + } else { + gcr_prompt_confirm_async(prompt, NULL, prompt_confirm_done, state); + } + + /* The exit status will be changed in the async callbacks. */ + return 1; +} + +int +main(int argc, char **argv) +{ + g_autoptr(GApplication) app = g_application_new( + "com.openssh.gnome-ssh-askpass4", + G_APPLICATION_HANDLES_COMMAND_LINE); + g_autofree char *message = NULL; + + if (argc > 1) { + message = g_strjoinv(" ", argv + 1); + } else { + message = g_strdup("Enter your OpenSSH passphrase:"); + } + + const char *prompt_mode = getenv("SSH_ASKPASS_PROMPT"); + PromptType type = PROMPT_ENTRY; + if (prompt_mode != NULL) { + if (strcasecmp(prompt_mode, "confirm") == 0) { + type = PROMPT_CONFIRM; + } else if (strcasecmp(prompt_mode, "none") == 0) { + type = PROMPT_NONE; + } + } + + g_autoptr(PromptState) state = prompt_state_new(app, message, type); + + g_signal_connect(app, "command-line", G_CALLBACK(command_line), state); + + /* + * Since we are calling g_application_hold, we cannot use + * g_application_command_line_set_exit_status. + * To change the exit status returned by g_application_run: + * “If the commandline invocation results in the mainloop running + * (ie: because the use-count of the application increased to a + * non-zero value) then the application is considered to have been + * ‘successful’ in a certain sense, and the exit status is always + * zero.” + */ + (void)(g_application_run(app, argc, argv)); + + return state->exit_status; +} diff --git a/contrib/redhat/openssh.spec b/contrib/redhat/openssh.spec index 34fce8c..9a84728 100644 --- a/contrib/redhat/openssh.spec +++ b/contrib/redhat/openssh.spec @@ -1,4 +1,4 @@ -%global ver 9.9p2 +%global ver 10.2p1 %global rel 1%{?dist} # OpenSSH privilege separation requires a user & group ID @@ -23,14 +23,6 @@ # 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 - %global without_openssl 0 # build without openssl where 1.1.1 is not available %if %{defined fedora} && 0%{?fedora} <= 28 @@ -53,14 +45,6 @@ # 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} @@ -93,21 +77,13 @@ 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 ! %{without_openssl} BuildRequires: openssl-devel >= 1.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 @@ -136,9 +112,7 @@ 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. @@ -307,20 +281,6 @@ 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 @@ -393,6 +353,7 @@ fi %defattr(-,root,root) %dir %attr(0111,root,root) %{_var}/empty/sshd %attr(0755,root,root) %{_sbindir}/sshd +%attr(0755,root,root) %{_libexecdir}/openssh/sshd-auth %attr(0755,root,root) %{_libexecdir}/openssh/sshd-session %attr(0755,root,root) %{_libexecdir}/openssh/sftp-server %attr(0644,root,root) %{_mandir}/man8/sshd.8* @@ -427,6 +388,8 @@ fi - Remove reference of dropped sshd.pam.old file - Update openssl-devel dependency to require >= 1.1.1 - Build with --without-openssl elsewhere +- Remove ancient build6x config, intended for RHL 6.x + (the distro predating Fedora, not RHEL) * Thu Oct 28 2021 Damien Miller - Remove remaining traces of --with-md5-passwords diff --git a/contrib/redhat/sshd.init b/contrib/redhat/sshd.init index 8ee5fcd..b825459 100755 --- a/contrib/redhat/sshd.init +++ b/contrib/redhat/sshd.init @@ -41,7 +41,7 @@ start() /usr/bin/ssh-keygen -A if [ -x /sbin/restorecon ]; then /sbin/restorecon /etc/ssh/ssh_host_rsa_key.pub - /sbin/restorecon /etc/ssh/ssh_host_dsa_key.pub + /sbin/restorecon /etc/ssh/ssh_host_ed25519_key.pub /sbin/restorecon /etc/ssh/ssh_host_ecdsa_key.pub fi diff --git a/contrib/ssh-copy-id b/contrib/ssh-copy-id index dcf5798..afb9bec 100644 --- a/contrib/ssh-copy-id +++ b/contrib/ssh-copy-id @@ -1,12 +1,14 @@ #!/bin/sh -# Copyright (c) 1999-2024 Philip Hands +# Copyright (c) 1999-2025 Philip Hands +# 2025 Denis Ovsienko +# 2024 Frank Fischer # 2021 Carlos Rodríguez Gili # 2020 Matthias Blümel # 2017 Sebastien Boyron # 2013 Martin Kletzander # 2010 Adeodato =?iso-8859-1?Q?Sim=F3?= -# 2010 Eric Moret +# 2010 Eric Moret # 2009 Xr # 2007 Justin Pryzby # 2004 Reini Urban @@ -284,14 +286,17 @@ installkeys_sh() { # the -z `tail ...` checks for a trailing newline. The echo adds one if was missing # the cat adds the keys we're getting via STDIN # and if available restorecon is used to restore the SELinux context - # OpenWrt has a special case for root only. - INSTALLKEYS_SH=$(tr '\t\n' ' ' <<-EOF + # OpenWrt has a special case for root/UID:0. Haiku is also special. + INSTALLKEYS_SH=$(tr -s '\t\n' ' ' <<-EOF $SET_X cd; umask 077; AUTH_KEY_FILE="${TARGET_PATH}"; - [ -f /etc/openwrt_release ] && [ "\$LOGNAME" = "root" ] && + [ -f /etc/openwrt_release ] && + { [ "\$LOGNAME" = "root" ] || [ "\$(id -u)" = "0" ]; } && AUTH_KEY_FILE=/etc/dropbear/authorized_keys; + [ "\`uname -s\`" = "Haiku" ] && + AUTH_KEY_FILE=config/settings/ssh/authorized_keys; AUTH_KEY_DIR=\`dirname "\${AUTH_KEY_FILE}"\`; mkdir -p "\${AUTH_KEY_DIR}" && { [ -z "\`tail -1c "\${AUTH_KEY_FILE}" 2>/dev/null\`" ] || diff --git a/contrib/suse/openssh.spec b/contrib/suse/openssh.spec index 1a4b7d9..4651423 100644 --- a/contrib/suse/openssh.spec +++ b/contrib/suse/openssh.spec @@ -13,7 +13,7 @@ Summary: OpenSSH, a free Secure Shell (SSH) protocol implementation Name: openssh -Version: 9.9p2 +Version: 10.2p1 URL: https://www.openssh.com/ Release: 1 Source0: openssh-%{version}.tar.gz @@ -211,6 +211,7 @@ rm -rf $RPM_BUILD_ROOT %attr(0755,root,root) %{_sbindir}/sshd %attr(0755,root,root) %dir %{_libdir}/ssh %attr(0755,root,root) %{_libdir}/ssh/sftp-server +%attr(0755,root,root) %{_libdir}/ssh/sshd-auth %attr(0755,root,root) %{_libdir}/ssh/sshd-session %attr(4711,root,root) %{_libdir}/ssh/ssh-keysign %attr(0755,root,root) %{_libdir}/ssh/ssh-pkcs11-helper diff --git a/crypto_api.h b/crypto_api.h index 8bbc3a0..693b67b 100644 --- a/crypto_api.h +++ b/crypto_api.h @@ -10,9 +10,7 @@ #include "includes.h" -#ifdef HAVE_STDINT_H -# include -#endif +#include #include typedef int8_t crypto_int8; diff --git a/debian/.git-dpm b/debian/.git-dpm index ca05761..1286553 100644 --- a/debian/.git-dpm +++ b/debian/.git-dpm @@ -1,12 +1,12 @@ # see git-dpm(1) from git-dpm package -b966dccd427fba8f70e77cb1bed10e8f7393b3e3 -b966dccd427fba8f70e77cb1bed10e8f7393b3e3 -7721b4ff7705034e809e2130d1a11be2bf42dbe9 -7721b4ff7705034e809e2130d1a11be2bf42dbe9 -openssh_9.9p1.orig.tar.gz -5ded7eb0add0b02b5d1a1c4bf5cb2c89d2117b53 -1964864 +84464406c27b4dc83f5c8bc7f622b44c6746e946 +84464406c27b4dc83f5c8bc7f622b44c6746e946 +ec3a38459ea2e2277374fd0b549e58f7e797e681 +ec3a38459ea2e2277374fd0b549e58f7e797e681 +openssh_10.2p1.orig.tar.gz +c34efade16109f065ec8c834f237bcedd8d7ef5c +1974519 debianTag="debian/%e%%%V" patchedTag="patched/%e%%%V" upstreamTag="upstream/%U" -signature:6f100e4757e1942d7b5e01310fcaf624b71f6740:833:openssh_9.9p1.orig.tar.gz.asc +signature:a2363ac9ef437e7eadbd550cd272a5285e02c7de:833:openssh_10.2p1.orig.tar.gz.asc diff --git a/debian/NEWS b/debian/NEWS index 2ed0d9c..edad475 100644 --- a/debian/NEWS +++ b/debian/NEWS @@ -1,3 +1,118 @@ +openssh (1:10.1p1-1) unstable; urgency=medium + + OpenSSH 10.1p1 includes a number of changes that may affect existing + configurations: + + * ssh(1): add a warning when the connection negotiates a non-post quantum + key agreement algorithm. + + This warning has been added due to the risk of "store now, decrypt + later" attacks. More details at https://openssh.com/pq.html + + This warning may be controlled via a new WarnWeakCrypto ssh_config + option, defaulting to on. This option is likely to control additional + weak crypto warnings in the future. + + * ssh(1), sshd(8): major changes to handling of DSCP marking/IPQoS + + In both client and server the default DSCP (a.k.a IPQoS) values were + revised and the way these values are used during runtime has changed. + + Interactive traffic is now assigned to the EF (Expedited Forwarding) + class by default. This provides more appropriate packet prioritisation + information for the intermediate network, such as wireless media (cf. + RFC 8325). Non-interactive traffic will now use the operating system + default DSCP marking. Both the interactive and non-interactive DSCP + values may be overridden via the IPQoS keyword, described in + ssh_config(5) and sshd_config(5). + + The appropriate DSCP marking is now automatically selected and updated + as needed over the course of a connection's lifetime. ssh(1) and + sshd(8) will switch between the interactive and non-interactive IPQoS + values depending on the type of SSH channels open at the time. For + example, if an sftp session is using the connection alongside a shell + session, then the non- interactive value will be used for the duration + of the sftp. A connection which contains only interactive sessions is + marked EF. + + * ssh(1), sshd(8): deprecate support for IPv4 type-of-service (ToS) + keywords in the IPQoS configuration directive. + + Type of Service (ToS) was deprecated in the late nineties and replaced + with the Differentiated Services architecture, which has significant + advantages for operators because it offers more granularity. + + OpenSSH switched its default IPQoS from ToS to DSCP values in 2018 + (openssh-7.7). + + IPQoS configurations with 'lowdelay', 'reliability', or 'throughput' + will be ignored and will instead use the system default QoS settings. + Additionally, a debug message will be logged about the deprecation with + a suggestion to use DSCP QoS instead. + + * ssh-add(1): when adding certificates to an agent, set the expiry to the + certificate expiry time plus a short (5 min) grace period. + + This will cause the agent to automatically remove certificates shortly + after they expire. A new ssh-add -N option disables this behaviour. + + * All: remove experimental support for XMSS keys. This was never enabled + by default. We expect to implement a new post-quantum signature scheme + in the near future. + + * ssh-agent(1), sshd(8): move agent listener sockets from /tmp to under + ~/.ssh/agent for both ssh-agent(1) and forwarded sockets in sshd(8). + + This ensures processes that have restricted filesystem access that + includes /tmp do not ambiently have the ability to use keys in an + agent. + + Moving the default directory has the consequence that the OS will no + longer clean up stale agent sockets, so ssh-agent now gains this + ability. + + To support $HOME on NFS, the socket path includes a truncated hash of + the hostname. ssh-agent will, by default, only clean up sockets from + the same hostname. + + ssh-agent(1) gains some new flags: -U suppresses the automatic cleanup + of stale sockets when it starts. -u forces a cleanup without keeping a + running agent, -uu forces a cleanup that ignores the hostname. -T makes + ssh-agent put the socket back in /tmp. + + -- Colin Watson Tue, 07 Oct 2025 22:07:19 +0100 + +openssh (1:10.0p1-1) unstable; urgency=medium + + OpenSSH 10.0p1 includes a number of changes that may affect existing + configurations: + + * This release removes support for the weak DSA signature algorithm, + completing the deprecation process that began in 2015 (when DSA was + disabled by default) and repeatedly warned over the last 12 months. + + * scp(1), sftp(1): pass "ControlMaster no" to ssh when invoked by scp & + sftp. This disables implicit session creation by these tools when + ControlMaster was set to yes/auto by configuration, which some users + found surprising. This change will not prevent scp/sftp from using an + existing multiplexing session if one had already been created. + + * sshd(8): this release disables finite field (a.k.a modp) Diffie-Hellman + key exchange in sshd by default. Specifically, this removes the + "diffie-hellman-group*" and "diffie-hellman-group-exchange-*" methods + from the default KEXAlgorithms list. The client is unchanged and + continues to support these methods by default. + + * sshd(8): this release removes the implicit fallback to compiled-in + groups for Diffie-Hellman Group Exchange KEX when the moduli file + exists but does not contain moduli within the client-requested range. + The fallback behaviour remains for the case where the moduli file does + not exist at all. This allows administrators more explicit control over + which DH groups will be selected, but can lead to connection failures + if the moduli file is edited incorrectly. + + -- Colin Watson Fri, 11 Apr 2025 11:16:19 +0100 + openssh (1:9.9p1-1) unstable; urgency=medium OpenSSH 9.9p1 includes a number of changes that may affect existing diff --git a/debian/agent-launch b/debian/agent-launch deleted file mode 100755 index 637f8cd..0000000 --- a/debian/agent-launch +++ /dev/null @@ -1,47 +0,0 @@ -#!/bin/sh -# helper script for launching ssh-agent, used by systemd unit -set -e - -options="$(getopt -o '' -l help -- "$@")" || exit 1 -eval set -- "$options" - -if [ ! -d "$XDG_RUNTIME_DIR" ]; then - # shellcheck disable=SC2016 - echo 'This needs $XDG_RUNTIME_DIR to be set' >&2 - exit 1 -fi - -while :; do - case $1 in - --help) - echo 'Usage:' >&2 - echo " $0 start [-- ssh-agent options]" >&2 - echo " $0 stop" - exit 0 - ;; - --) - shift - break - ;; - *) - echo "Unexpected argument: $1" >&2 - exit 1 - ;; - esac -done - -if [ "$1" = start ]; then - shift - if [ -z "$SSH_AUTH_SOCK" ] && grep -s -q '^use-ssh-agent$' /etc/X11/Xsession.options; then - S="$XDG_RUNTIME_DIR/openssh_agent" - dbus-update-activation-environment --verbose --systemd SSH_AUTH_SOCK="$S" SSH_AGENT_LAUNCHER=openssh - exec ssh-agent -D -a "$S" "$@" - fi -elif [ "$1" = stop ]; then - if [ "$SSH_AGENT_LAUNCHER" = openssh ]; then - dbus-update-activation-environment --systemd SSH_AUTH_SOCK= - fi -else - echo "Unknown command $1" >&2 - exit 1 -fi diff --git a/debian/changelog b/debian/changelog index ed4aacd..39908ee 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,46 +1,349 @@ -openssh (1:9.9p2-0deepin4) unstable; urgency=medium +openssh (1:10.2p1-2) unstable; urgency=medium - * fix: filter Uos or uos for lsb_release -is. + * ssh-session-cleanup: Update pattern for sshd-session split in 9.8 + (closes: #1117965). + * Link ssh against ssh-pkcs11.o directly (closes: #1117638, #1117720). - -- liujianqiang Thu, 18 Sep 2025 13:47:33 +0800 + -- Colin Watson Fri, 17 Oct 2025 10:14:14 +0100 -openssh (1:9.9p2-0deepin3) unstable; urgency=medium +openssh (1:10.2p1-1) unstable; urgency=medium - * feat: add sm support + * New upstream release: + - ssh-keygen(1): fix download of keys from PKCS#11 tokens. + + -- Colin Watson Fri, 10 Oct 2025 14:50:27 +0100 - -- Liang Bo Fri, 01 Aug 2025 17:31:26 +0800 +openssh (1:10.1p1-2) unstable; urgency=medium -openssh (1:9.9p2-0deepin2) unstable; urgency=medium + * Don't reuse c->isatty for signalling that the remote channel has a tty + attached (closes: #1117574, #1117594). + * Link ssh-keygen directly against ssh-pkcs11.c. - * feat: add sw64 support + -- Colin Watson Thu, 09 Oct 2025 00:54:25 +0100 - -- Deepin Packages Builder Wed, 18 Jun 2025 13:59:48 +0800 +openssh (1:10.1p1-1) unstable; urgency=medium -openssh (1:9.9p2-0deepin1) unstable; urgency=medium + [ Allison Karlitskaya ] + * sshd@.service: Support ephemeral keys from VM/container hosts. - * Update to 9.9p2, fixes CVE-2025-26465, CVE-2025-26466 - * Refresh patches (mlkem768x25519-big-endian-{1,2}.patch) + [ Colin Watson ] + * New upstream release: + - ssh(1): add a warning when the connection negotiates a non-post + quantum key agreement algorithm. + - ssh(1), sshd(8): major changes to handling of DSCP marking/IPQoS: by + default, interactive traffic is assigned to the EF (Expedited + Forwarding) class, while non-interactive traffic uses the operating + system default DSCP marking. + - ssh(1), sshd(8): deprecate support for IPv4 type-of-service (ToS) + keywords in the IPQoS configuration directive. + - ssh-add(1): when adding certificates to an agent, set the expiry to + the certificate expiry time plus a short (5 min) grace period. + - All: remove experimental support for XMSS keys. + - ssh-agent(1), sshd(8): move agent listener sockets from /tmp to under + ~/.ssh/agent for both ssh-agent(1) and forwarded sockets in sshd(8). + - CVE-2025-61984: ssh(1): disallow control characters in usernames + passed via the commandline or expanded using %-sequences from the + configuration file (closes: #1117529), + - CVE-2025-61985: ssh(1): disallow \0 characters in ssh:// URIs (closes: + #1117530). + - ssh(1), sshd(8): add SIGINFO handlers to log active channel and + session information. + - sshd(8): when refusing a certificate for user authentication, log + enough information to identify the certificate in addition to the + reason why it was being denied. Makes debugging certificate + authorisation problems a bit easier. + - ssh(1), ssh-agent(1): support ed25519 keys hosted on PKCS#11 tokens. + - ssh(1): add an ssh_config(5) RefuseConnection option that, when + encountered while processing an active section in a configuration, + terminates ssh(1) with an error message that contains the argument to + the option. + - sshd(8): make the X11 display number check relative to + X11DisplayOffset. This will allow people to use X11DisplayOffset to + configure much higher port ranges if they really want, while not + changing the default behaviour. + - ssh(1): fix delay on X client startup when ObscureKeystrokeTiming is + enabled. + - sshd(8): increase the maximum size of the supported configuration from + 256KB to 4MB, which ought to be enough for anybody. Fail early and + visibly when this limit is breached. + - sftp(1): during sftp uploads, avoid a condition where a failed write + could be ignored if a subsequent write succeeded. This is unlikely but + technically possible because sftp servers are allowed to reorder + requests. + - sshd(8): avoid a race condition when the sshd-auth process exits that + could cause a spurious error message to be logged. + - sshd(8): log at level INFO when PerSourcePenalties actually blocks + access to a source address range. Previously this was logged at level + VERBOSE, which hid enforcement actions under default config settings. + - sshd(8): Make the MaxStartups and PerSourceNetBlockSize options + first-match-wins as advertised. + - ssh(1): fix an incorrect return value check in the local forward + cancellation path that would cause failed cancellations not to be + logged. + - sshd(8): make "Match !final" not trigger a second parsing pass of + ssh_config (unless hostname canonicalisation or a separate "Match + final" does). + - ssh(1): better debug diagnostics when loading keys. Will now list key + fingerprint and algorithm (not just algorithm number) as well as + making it explicit which keys didn't load. + - All: fix a number of memory leaks found by LeakSanitizer, Coverity and + manual inspection. + - sshd(8): Output the current name for PermitRootLogin's + "prohibit-password" in sshd -T instead of its deprecated alias + "without-password" (closes: #1095922). + - ssh(1): make writing known_hosts lines more atomic by writing the + entire line in one operation and using unbuffered stdio. + - sshd(8): check the username didn't change during the PAM transactions. + - sshd(8): don't log audit messages with UNKNOWN hostname to avoid slow + DNS lookups in the audit subsystem. + - All: when making a copy of struct passwd, ensure struct fields are + non-NULL. + - sshd(8): handle futex_time64 properly in seccomp sandbox. + - Add contrib/gnome-ssh-askpass4 for GNOME 40+ using the GCR API. + - ssh-agent(1): exit 0 from SIGTERM under systemd socket-activation, + preventing a graceful shutdown of an agent via systemd from + incorrectly marking the service as "failed". + * Drop patches: + - no-openssl-version-status.patch: Mostly applied upstream; the rest + only applied to OpenSSL < 3, which isn't relevant to current Debian + releases. + - revert-ipqos-defaults.patch: This new upstream release reworks IPQoS, + so let's see how that works in Debian (closes: #1111446). + * debian/run-tests: Fix path to dropbear. + + -- Colin Watson Tue, 07 Oct 2025 22:07:19 +0100 + +openssh (1:10.0p1-8) unstable; urgency=medium + + * Remove some long-obsolete Conflicts (closes: #54243). + * Fix mistracking of MaxStartups process exits in some situations (closes: + #1080350). + + -- Colin Watson Sun, 10 Aug 2025 00:07:55 +0100 + +openssh (1:10.0p1-7) unstable; urgency=medium + + * Make postinst logic for cleaning up the sshd diversion more robust. + + -- Colin Watson Fri, 01 Aug 2025 16:02:27 +0100 + +openssh (1:10.0p1-6) unstable; urgency=medium + + * Temporarily divert /usr/sbin/sshd during upgrades from before + 1:9.8p1-1~, to avoid new connections failing between unpack and + configure (closes: #1109742). + + -- Colin Watson Mon, 28 Jul 2025 12:17:42 +0100 + +openssh (1:10.0p1-5) unstable; urgency=medium + + * Ensure that configure knows the path to passwd; fixes reproducibility of + openssh-tests. + + -- Colin Watson Fri, 09 May 2025 13:40:49 +0100 + +openssh (1:10.0p1-4) unstable; urgency=medium - -- Tianyu Chen Tue, 18 Feb 2025 18:13:26 +0800 + [ Daniel Kahn Gillmor ] + * Add Requires=ssh-agent.socket to ssh-agent.service (closes: #1103522). -openssh (1:9.9p1-3deepin2) unstable; urgency=medium + -- Colin Watson Fri, 09 May 2025 10:16:45 +0100 - [ liujianqiang ] - * ssh.service is disabled by default. - * update ChannelTimeout config to implement auto close inactive - connections. +openssh (1:10.0p1-3) unstable; urgency=medium - -- Tianyu Chen Wed, 15 Jan 2025 14:50:47 +0800 + * Disable --with-linux-memlock-onfault again, since it causes + RLIMIT_MEMLOCK to be exceeded with some combinations of PAM modules + (closes: #1103418). -openssh (1:9.9p1-3deepin1) unstable; urgency=medium + -- Colin Watson Wed, 07 May 2025 16:18:43 +0100 - * Refresh and re-apply deepin patches: - deepin-extra-version.patch - deepin-ssh-connect-idle-timeout.patch - deepin-ssh-keygen-privatekey-file-perm.patch - * Update openssh-server.ucf-md5sum. +openssh (1:10.0p1-2) unstable; urgency=medium - -- Tianyu Chen Wed, 15 Jan 2025 14:42:25 +0800 + [ Colin Watson ] + * Disable --with-linux-memlock-onfault on riscv64. + * Build with wtmpdb (see #1102643). + * Stop writing /var/log/btmp, since nothing reads it any more (closes: + #1072184). + * Restore some rdomain references in sshd_config(5) where they're + supported on Linux, referring to ip-vrf(8) (closes: #1095686). + + [ Daniel Kahn Gillmor ] + * Improve systemd user service socket activation (closes: #961311, + #1039919, #1103037). + + [ Luca Boccassi ] + * Switch from adduser to sysusers.d. + * Add sshd-keygen service. + + -- Colin Watson Tue, 15 Apr 2025 14:19:35 +0100 + +openssh (1:10.0p1-1) unstable; urgency=medium + + [ Luca Boccassi ] + * Add COLORTERM NO_COLOR to SendEnv and AcceptEnv. + + [ Colin Watson ] + * New upstream release: + - This release removes support for the weak DSA signature algorithm. + - scp(1), sftp(1): pass "ControlMaster no" to ssh when invoked by scp & + sftp. + - This release has the version number 10.0 and announces itself as + "SSH-2.0-OpenSSH_10.0". Software that naively matches versions using + patterns like "OpenSSH_1*" may be confused by this. + - sshd(8): this release removes the code responsible for the user + authentication phase of the protocol from the per-connection + sshd-session binary to a new sshd-auth binary. Splitting this code + into a separate binary ensures that the crucial pre-authentication + attack surface has an entirely disjoint address space from the code + used for the rest of the connection. It also yields a small runtime + memory saving as the authentication code will be unloaded after the + authentication phase completes. This change should be largely + invisible to users, though some log messages may now come from + "sshd-auth" instead of "sshd-session". + - sshd(8): this release disables finite field (a.k.a modp) + Diffie-Hellman key exchange in sshd by default. Specifically, this + removes the "diffie-hellman-group*" and + "diffie-hellman-group-exchange-*" methods from the default + KEXAlgorithms list. The client is unchanged and continues to support + these methods by default. + - sshd(8): this release removes the implicit fallback to compiled-in + groups for Diffie-Hellman Group Exchange KEX when the moduli file + exists but does not contain moduli within the client-requested range. + The fallback behaviour remains for the case where the moduli file does + not exist at all. This allows administrators more explicit control + over which DH groups will be selected, but can lead to connection + failures if the moduli file is edited incorrectly. + - CVE-2025-32728: sshd(8): fix the DisableForwarding directive, which + was failing to disable X11 forwarding and agent forwarding as + documented (closes: #1102603). X11 forwarding is disabled by default + in the server and agent forwarding is off by default in the client. + - ssh(1): the hybrid post-quantum algorithm mlkem768x25519-sha256 is now + used by default for key agreement. This algorithm is considered to be + safe against attack by quantum computers, is guaranteed to be no less + strong than the popular curve25519-sha256 algorithm, has been + standardised by NIST and is considerably faster than the previous + default. + - ssh(1): prefer AES-GCM to AES-CTR mode when selecting a cipher for the + connection. The default cipher preference list is now + Chacha20/Poly1305, AES-GCM (128/256) followed by AES-CTR + (128/192/256). + - ssh(1): add %-token and environment variable expansion to the + ssh_config SetEnv directive. + - ssh(1): allow %-token and environment variable expansion in the + ssh_config User directive, with the exception of %r and %C which would + be self-referential. + - ssh(1), sshd(8): add "Match version" support to ssh_config and + sshd_config. Allows matching on the local version of OpenSSH, e.g. + "Match version OpenSSH_10.*". + - ssh(1): add support for "Match sessiontype" to ssh_config. Allows + matching on the type of session initially requested, either "shell" + for interactive sessions, "exec" for command execution sessions, + "subsystem" for subsystem requests, such as sftp, or "none" for + transport/forwarding-only sessions. + - ssh(1): add support for "Match command ..." support to ssh_config, + allowing matching on the remote command as specified on the + command-line. + - ssh(1): allow 'Match tagged ""' and 'Match command ""' to match empty + tag and command values respectively. + - sshd(8): allow glob(3) patterns to be used in sshd_config + AuthorizedKeysFile and AuthorizedPrincipalsFile directives. + - sshd(1): support the VersionAddendum in the client, mirroring the + option of the same name in the server. + - ssh-agent(1): the agent will now delete all loaded keys when signaled + with SIGUSR1. This allows deletion of keys without having access to + $SSH_AUTH_SOCK. + - Portable OpenSSH, ssh-agent(1): support systemd-style socket + activation in ssh-agent using the LISTEN_PID/LISTEN_FDS mechanism. + Activated when these environment variables are set, the agent is + started with the -d or -D option and no socket path is set. + - ssh-keygen(1): support FIDO tokens that return no attestation data, + e.g. recent WinHello. + - ssh-agent(1): add a "-Owebsafe-allow=..." option to allow the default + FIDO application ID allow-list to be overridden. + - ssh-keygen(1): allow "-" as output file for moduli screening. + - sshd(8): remove assumption that the sshd_config and any configs it + includes can fit in a (possibly enlarged) socket buffer. Previously it + was possible to create a sufficiently large configuration that could + cause sshd to fail to accept any connection. sshd(8) will now actively + manage sending its config to the sshd-session sub-process. + - ssh(1): don't start the ObscureKeystrokeTiming mitigations if there + has been traffic on a X11 forwarding channel recently. Should fix X11 + forwarding performance problems when this setting is enabled. + - ssh(1): prohibit the comma character in hostnames accepted, but allow + an underscore as the first character in a hostname. + - sftp(1): set high-water when resuming a "put". Prevents bogus "server + reordered acks" debug message. + - ssh(1), sshd(8): fix regression in openssh-9.8, which would fail to + accept "Match criteria=argument" as well as the documented "Match + criteria argument" syntax in ssh_config and sshd_config. + - sftp(1), ssh(1): fix a number of possible NULL dereference bugs, + including Coverity CIDs 405019 and 477813. + - sshd(8): fix PerSourcePenalty incorrectly using "crash" penalty when + LoginGraceTime was exceeded. + - sshd(8): fix "Match invalid-user" from incorrectly being activated in + initial configuration pass when no other predicates were present on + the match line. + - sshd(8): fix debug logging of user specific delay. + - sshd(8): improve debug logging across sub-process boundaries. + Previously some log messages were lost early in the sshd-auth and + sshd-session processes' life. + - ssh(1): require control-escape character sequences passed via the '-e + ^x' command-line to be exactly two characters long. Avoids one byte + out-of-bounds read if ssh is invoked as "ssh -e^ ...". + - ssh(1), sshd(8): prevent integer overflow in x11 port handling. These + are theoretically possible if the admin misconfigured X11DisplayOffset + or the user misconfigures their own $DISPLAY, but don't happen in + normal operation. + - ssh-keygen(1): don't mess up ssh-keygen -l output when the file + contains CR characters. + - sshd(8): add rate limits to logging of connections dropped by + PerSourcePenalties. Previously these could be noisy in logs. + - ssh(1): fix argument of "Compression" directive in ssh -G config dump, + which regressed in openssh-9.8. + - sshd(8): fix a corner-case triggered by UpdateHostKeys when sshd + refuses to accept the signature returned by an agent holding host keys + during the hostkey rotation sub-protocol. This situation could occur + in situations where a PKCS#11 smartcard that lacked support for + particular signature algorithms was used to store host keys. + - ssh-keygen(1): when using RSA keys to sign messages with "ssh-keygen + -Y", select the signature algorithm based on the requested hash + algorithm ("-Ohashalg=xxx"). This allows using something other than + the default of rsa-sha2-512, which may not be supported on all signing + backends, e.g. some smartcards only support SHA256. + - sshd(8): add wtmpdb support as a Y2038 safe wtmp replacement. + - sshd(8): add support for locking sshd into memory, enabled with the + --with-linux-memlock-onfault configure flag. + * Configure --with-linux-memlock-onfault on Linux. + + -- Colin Watson Fri, 11 Apr 2025 16:00:55 +0100 + +openssh (1:9.9p2-2) unstable; urgency=medium + + * Simplify most autopkgtests using needs-sudo restriction. + * Remove obsolete slogin symlink (closes: #1098760). + * Check if dbclient supports SHA1 before trying SHA1-based KEX (closes: + #1100948). + + -- Colin Watson Thu, 20 Mar 2025 23:12:58 +0000 + +openssh (1:9.9p2-1) unstable; urgency=medium + + * New upstream release: + - CVE-2025-26465: ssh(1) in OpenSSH versions 6.8p1 to 9.9p1 (inclusive) + contained a logic error that allowed an on-path attacker (a.k.a MITM) + to impersonate any server when the VerifyHostKeyDNS option is enabled. + This option is off by default. + - CVE-2025-26466: sshd(8) in OpenSSH versions 9.5p1 to 9.9p1 (inclusive) + is vulnerable to a memory/CPU denial-of-service related to the + handling of SSH2_MSG_PING packets. This condition may be mitigated + using the existing PerSourcePenalties feature. + - ssh(1), sshd(8): fix regression in Match directive that caused + failures when predicates and their arguments were separated by '=' + characters instead of whitespace (bz3739). + - sshd(8): fix the "Match invalid-user" predicate, which was matching + incorrectly in the initial pass of config evaluation. + + -- Colin Watson Tue, 18 Feb 2025 10:13:10 +0000 openssh (1:9.9p1-3) unstable; urgency=medium diff --git a/debian/control b/debian/control index a74bfd0..59fea82 100644 --- a/debian/control +++ b/debian/control @@ -17,9 +17,9 @@ Build-Depends: libselinux1-dev [linux-any], libssl-dev (>= 1.1.1), libwrap0-dev | libwrap-dev, + libwtmpdb-dev, pkgconf, zlib1g-dev, - lsb-release, Standards-Version: 4.6.2 Uploaders: Colin Watson , @@ -34,13 +34,12 @@ Package: openssh-client Architecture: any Depends: adduser, + init-system-helpers (>= 1.66~), passwd, ${misc:Depends}, ${shlibs:Depends}, Recommends: xauth, -Conflicts: - sftp, Breaks: openssh-sk-helper, Replaces: @@ -111,7 +110,6 @@ Architecture: any Pre-Depends: ${misc:Pre-Depends}, Depends: - adduser, libpam-modules, libpam-runtime, lsb-base, @@ -126,10 +124,6 @@ Recommends: ncurses-term, xauth, ${openssh-server:Recommends}, -Conflicts: - sftp, - ssh-socks, - ssh2, Replaces: openssh-client (<< 1:7.9p1-8), ssh, diff --git a/debian/openssh-client.install b/debian/openssh-client.install index 96c8dea..d668540 100755 --- a/debian/openssh-client.install +++ b/debian/openssh-client.install @@ -26,11 +26,10 @@ usr/share/man/man8/ssh-sk-helper.8 contrib/ssh-copy-id usr/bin debian/ssh-argv0 usr/bin -debian/agent-launch usr/lib/openssh - # dh_apport would be neater, but at the time of writing it isn't in unstable # yet. debian/openssh-client.apport => usr/share/apport/package-hooks/openssh-client.py # systemd user unit (only used under sessions) debian/systemd/ssh-agent.service usr/lib/systemd/user +debian/systemd/ssh-agent.socket usr/lib/systemd/user diff --git a/debian/openssh-client.links b/debian/openssh-client.links index 85bd299..957336c 100644 --- a/debian/openssh-client.links +++ b/debian/openssh-client.links @@ -1,3 +1,2 @@ -usr/share/man/man1/ssh.1 usr/share/man/man1/slogin.1 # enable systemd user unit for graphical sessions that use systemd usr/lib/systemd/user/ssh-agent.service usr/lib/systemd/user/graphical-session-pre.target.wants/ssh-agent.service diff --git a/debian/openssh-client.postinst b/debian/openssh-client.postinst index dd4d95a..54e3175 100644 --- a/debian/openssh-client.postinst +++ b/debian/openssh-client.postinst @@ -41,6 +41,13 @@ if [ "$action" = configure ]; then if dpkg --compare-versions "$2" lt-nl 1:9.1p1-1~; then remove_obsolete_alternatives fi + + # debhelper compatibility level 14 may supersede this with something + # more complete; in the meantime, just reload systemd's state so + # that it at least has the current ssh-agent.* unit files. + if [ -z "$DPKG_ROOT" ] && [ -d /run/systemd/system ]; then + deb-systemd-invoke --user daemon-reload >/dev/null || true + fi fi #DEBHELPER# diff --git a/debian/openssh-server-udeb.install b/debian/openssh-server-udeb.install index 900d909..f2a55b7 100644 --- a/debian/openssh-server-udeb.install +++ b/debian/openssh-server-udeb.install @@ -1,3 +1,4 @@ sshd usr/sbin +sshd-auth usr/lib/openssh sshd-session usr/lib/openssh ssh-keygen usr/bin diff --git a/debian/openssh-server.install b/debian/openssh-server.install index 7936d27..b364a18 100755 --- a/debian/openssh-server.install +++ b/debian/openssh-server.install @@ -1,6 +1,7 @@ #! /usr/bin/dh-exec etc/ssh/moduli +usr/lib/openssh/sshd-auth usr/lib/openssh/sshd-session usr/sbin/sshd usr/share/man/man5/authorized_keys.5 @@ -16,6 +17,7 @@ debian/systemd/ssh.service lib/systemd/system debian/systemd/ssh.socket lib/systemd/system debian/systemd/rescue-ssh.target lib/systemd/system debian/systemd/sshd@.service lib/systemd/system +debian/systemd/sshd-keygen.service lib/systemd/system debian/systemd/ssh-session-cleanup usr/lib/openssh # dh_apport would be neater, but at the time of writing it isn't in unstable diff --git a/debian/openssh-server.lintian-overrides b/debian/openssh-server.lintian-overrides index ea3c041..70043ee 100644 --- a/debian/openssh-server.lintian-overrides +++ b/debian/openssh-server.lintian-overrides @@ -2,3 +2,9 @@ # partial upgrades on non-default init systems. See # https://lists.debian.org/debian-devel/2023/01/msg00158.html and thread. openssh-server: depends-on-obsolete-package Depends: lsb-base + +# Deliberate special cases for a helper service. +openssh-server: systemd-service-file-refers-to-unusual-wantedby-target ssh.service [usr/lib/systemd/system/sshd-keygen.service] +openssh-server: systemd-service-file-refers-to-unusual-wantedby-target ssh.socket [usr/lib/systemd/system/sshd-keygen.service] +openssh-server: systemd-service-file-refers-to-unusual-wantedby-target sshd.service [usr/lib/systemd/system/sshd-keygen.service] +openssh-server: systemd-service-file-refers-to-unusual-wantedby-target sshd@.service [usr/lib/systemd/system/sshd-keygen.service] diff --git a/debian/openssh-server.postinst b/debian/openssh-server.postinst index a871eb1..498777a 100644 --- a/debian/openssh-server.postinst +++ b/debian/openssh-server.postinst @@ -11,10 +11,16 @@ umask 022 get_config_option() { option="$1" + sshd_path=/usr/sbin/sshd [ -f /etc/ssh/sshd_config ] || return - /usr/sbin/sshd -G | sed -n "s/^$option //Ip" + # begin-remove-after: released:forky + if [ -e /usr/sbin/sshd.session-split ]; then + sshd_path=/usr/sbin/sshd.session-split + fi + # end-remove-after + "$sshd_path" -G | sed -n "s/^$option //Ip" } @@ -88,16 +94,9 @@ create_sshdconfig() { ucfr openssh-server /etc/ssh/sshd_config } -setup_sshd_user() { - if ! getent passwd sshd >/dev/null; then - adduser --quiet --system --no-create-home --home /run/sshd --shell /usr/sbin/nologin sshd - fi -} - if [ "$action" = configure ]; then create_sshdconfig create_keys - setup_sshd_user if dpkg --compare-versions "$2" lt-nl 1:7.9p1-5 && \ [ -f /etc/ssh/moduli.dpkg-bak ]; then # Handle /etc/ssh/moduli being moved from openssh-client to @@ -116,6 +115,23 @@ if [ "$action" = configure ]; then systemctl unmask ssh.service systemctl disable ssh.service fi + # begin-remove-after: released:forky + if [ -e /usr/sbin/sshd.session-split ]; then + # We're ready to restart the listener process so that it + # executes sshd-session rather than sshd for new + # connections, so we can remove this diversion now. This + # starts a brief window where new connections will fail + # (ending when the service is restarted), but at least it's + # all contained within this postinst. + # + # See openssh-server.preinst for why we use this odd package + # name. + echo "Finishing upgrade from pre-9.8 monolithic sshd ..." + dpkg-divert --package openssh-client --remove --no-rename \ + --divert /usr/sbin/sshd.session-split /usr/sbin/sshd + mv -f /usr/sbin/sshd.session-split /usr/sbin/sshd + fi + # end-remove-after fi #DEBHELPER# diff --git a/debian/openssh-server.preinst b/debian/openssh-server.preinst new file mode 100755 index 0000000..e6eff90 --- /dev/null +++ b/debian/openssh-server.preinst @@ -0,0 +1,21 @@ +#!/bin/sh +set -e + +# begin-remove-after: released:forky +if [ "$1" = upgrade ] && dpkg --compare-versions "$2" lt-nl 1:9.8p1-1~; then + # Temporarily divert the new sshd binary, since OpenSSH 9.8 moved + # part of its responsibilities to sshd-session, and unpacking the + # new sshd to its normal path would break new connections. We'll + # remove this diversion when we're ready to restart the listener + # process. + # + # Since we're trying to divert a file shipped in this package, we + # use a package name that we know doesn't ship /usr/sbin/sshd. + dpkg-divert --package openssh-client --add --no-rename \ + --divert /usr/sbin/sshd.session-split /usr/sbin/sshd +fi +# end-remove-after + +#DEBHELPER# + +exit 0 diff --git a/debian/openssh-server.sysusers b/debian/openssh-server.sysusers new file mode 100644 index 0000000..82da157 --- /dev/null +++ b/debian/openssh-server.sysusers @@ -0,0 +1 @@ +u sshd -:nogroup "sshd user" /run/sshd diff --git a/debian/openssh-server.ucf-md5sum b/debian/openssh-server.ucf-md5sum index 1e0caef..652d79b 100644 --- a/debian/openssh-server.ucf-md5sum +++ b/debian/openssh-server.ucf-md5sum @@ -110,13 +110,19 @@ d96ecd9064ea650c44372a5a33d3e497 4e03b4df60cd00c651777ec14ff76aef # From 1:9.2p1-1: -a2cdc592eacf8a884829729418005d27 -84066063a3f2c9412d5df7a7a0e6e293 -8933d57d77504756fdde370bbdd08ee1 -49d53e44b746ec2ad2103ac2860f97ff +b8e751f62cf86a18bc30cdaae494b03f +b89c8626d43128cdb233536439e00566 +5f589fb3658df8cb7cce8505cf821e40 +8d7588b06f81ef23bea8d84442af8e68 -# From 1:9.7p1-4deepin3 -34f13e3344c394d1e9b8f36d55afd5e6 -c94aa65d347d95e3c30aba50187b4417 -3fecc6a74e3e70b0e65cdd8520c86aba -cc97f6a047873d4d9f3f962239601c74 +# From 1:9.9p2-3: +a28c3e7d6c8f1293d5dacd70157872f6 +08c279b9cb7685877107ac781fd166bd +abf26bfd692dada3111bea33dc4cc268 +509c39a0ee41efa32c76a96c525b183e + +# From 1:10.0p1-1: +b3d7f2a64f6ad1fc763321167a3435d5 +29f3b6afc6b7b84e9e084fe10d27ede3 +16d925db19c47346e642578c8a68fae9 +98d17cfbc85c1ced1fa458699ffc1ee1 diff --git a/debian/patches/add-sm-support.patch b/debian/patches/add-sm-support.patch deleted file mode 100644 index 4c1f909..0000000 --- a/debian/patches/add-sm-support.patch +++ /dev/null @@ -1,1504 +0,0 @@ -diff --git a/Makefile.in b/Makefile.in -index eeea954..7c84b60 100644 ---- a/Makefile.in -+++ b/Makefile.in -@@ -102,14 +102,14 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ - 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 \ -+ monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-sm2.o ssh-ecdsa-sk.o \ - ssh-ed25519-sk.o ssh-rsa.o ssh-null.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 ed25519.o hash.o \ -- kex.o kex-names.o kexdh.o kexgex.o kexecdh.o kexc25519.o \ -+ kex.o kex-names.o kexdh.o kexgex.o kexecdh.o kexc25519.o kexsm2.o \ - kexgexc.o kexgexs.o kexgssc.o \ - kexsntrup761x25519.o kexmlkem768x25519.o sntrup761.o kexgen.o \ - sftp-realpath.o platform-pledge.o platform-tracing.o platform-misc.o \ -diff --git a/authfd.c b/authfd.c -index e04ad0c..58dd76c 100644 ---- a/authfd.c -+++ b/authfd.c -@@ -605,6 +605,8 @@ ssh_add_identity_constrained(int sock, struct sshkey *key, - case KEY_DSA_CERT: - case KEY_ECDSA: - case KEY_ECDSA_CERT: -+ case KEY_SM2: -+ case KEY_SM2_CERT: - case KEY_ECDSA_SK: - case KEY_ECDSA_SK_CERT: - #endif -diff --git a/authfile.c b/authfile.c -index 445f2dd..3884031 100644 ---- a/authfile.c -+++ b/authfile.c -@@ -332,6 +332,7 @@ sshkey_load_private_cert(int type, const char *filename, const char *passphrase, - case KEY_RSA: - case KEY_DSA: - case KEY_ECDSA: -+ case KEY_SM2: - #endif /* WITH_OPENSSL */ - case KEY_ED25519: - case KEY_XMSS: -diff --git a/cipher.c b/cipher.c -index 7d6e7d8..979db51 100644 ---- a/cipher.c -+++ b/cipher.c -@@ -105,6 +105,7 @@ static const struct sshcipher ciphers[] = { - #endif - { "chacha20-poly1305@openssh.com", - 8, 64, 0, 16, CFLAG_CHACHAPOLY, NULL }, -+ { "sm4-ctr", 16, 16, 0, 0, 0, EVP_sm4_ctr }, - { "none", 8, 0, 0, 0, CFLAG_NONE, NULL }, - - { NULL, 0, 0, 0, 0, 0, NULL } -diff --git a/digest-openssl.c b/digest-openssl.c -index e073a80..f60db09 100644 ---- a/digest-openssl.c -+++ b/digest-openssl.c -@@ -61,6 +61,7 @@ const struct ssh_digest digests[] = { - { SSH_DIGEST_SHA256, "SHA256", 32, EVP_sha256 }, - { SSH_DIGEST_SHA384, "SHA384", 48, EVP_sha384 }, - { SSH_DIGEST_SHA512, "SHA512", 64, EVP_sha512 }, -+ { SSH_DIGEST_SM3, "SM3", 32, EVP_sm3 }, - { -1, NULL, 0, NULL }, - }; - -diff --git a/digest.h b/digest.h -index 274574d..8bedd6c 100644 ---- a/digest.h -+++ b/digest.h -@@ -27,7 +27,8 @@ - #define SSH_DIGEST_SHA256 2 - #define SSH_DIGEST_SHA384 3 - #define SSH_DIGEST_SHA512 4 --#define SSH_DIGEST_MAX 5 -+#define SSH_DIGEST_SM3 5 -+#define SSH_DIGEST_MAX 6 - - struct sshbuf; - struct ssh_digest_ctx; -diff --git a/kex-names.c b/kex-names.c -index 081f78c..56067ce 100644 ---- a/kex-names.c -+++ b/kex-names.c -@@ -91,6 +91,7 @@ static const struct kexalg kexalgs[] = { - SSH_DIGEST_SHA256 }, - #endif - #endif /* HAVE_EVP_SHA256 || !WITH_OPENSSL */ -+ { "sm2-sm3", KEX_SM2_SM3, NID_sm2, SSH_DIGEST_SM3 }, - { NULL, 0, -1, -1}, - }; - static const struct kexalg gss_kexalgs[] = { -diff --git a/kex.h b/kex.h -index 6a08023..21ef65c 100644 ---- a/kex.h -+++ b/kex.h -@@ -103,6 +103,7 @@ enum kex_exchange { - KEX_C25519_SHA256, - KEX_KEM_SNTRUP761X25519_SHA512, - KEX_KEM_MLKEM768X25519_SHA256, -+ KEX_SM2_SM3, - #ifdef GSSAPI - KEX_GSS_GRP1_SHA1, - KEX_GSS_GRP14_SHA1, -@@ -305,6 +306,8 @@ int kexc25519_shared_key_ext(const u_char key[CURVE25519_SIZE], - __attribute__((__bounded__(__minbytes__, 1, CURVE25519_SIZE))) - __attribute__((__bounded__(__minbytes__, 2, CURVE25519_SIZE))); - -+int SM2KAP_compute_key(void *out, size_t outlen, const EC_POINT *pub_key, const EC_KEY *eckey, int server); -+ - #if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) || defined(DEBUG_KEXECDH) - void dump_digest(const char *, const u_char *, int); - #endif -diff --git a/kexecdh.c b/kexecdh.c -index efb2e55..69ec13b 100644 ---- a/kexecdh.c -+++ b/kexecdh.c -@@ -44,7 +44,7 @@ - - static int - kex_ecdh_dec_key_group(struct kex *, const struct sshbuf *, EC_KEY *key, -- const EC_GROUP *, struct sshbuf **); -+ const EC_GROUP *, struct sshbuf **, int server); - - int - kex_ecdh_keypair(struct kex *kex) -@@ -124,7 +124,7 @@ kex_ecdh_enc(struct kex *kex, const struct sshbuf *client_blob, - (r = sshbuf_get_u32(server_blob, NULL)) != 0) - goto out; - if ((r = kex_ecdh_dec_key_group(kex, client_blob, server_key, group, -- shared_secretp)) != 0) -+ shared_secretp, 1)) != 0) - goto out; - *server_blobp = server_blob; - server_blob = NULL; -@@ -136,7 +136,7 @@ kex_ecdh_enc(struct kex *kex, const struct sshbuf *client_blob, - - static int - kex_ecdh_dec_key_group(struct kex *kex, const struct sshbuf *ec_blob, -- EC_KEY *key, const EC_GROUP *group, struct sshbuf **shared_secretp) -+ EC_KEY *key, const EC_GROUP *group, struct sshbuf **shared_secretp, int server) - { - struct sshbuf *buf = NULL; - BIGNUM *shared_secret = NULL; -@@ -176,11 +176,20 @@ kex_ecdh_dec_key_group(struct kex *kex, const struct sshbuf *ec_blob, - r = SSH_ERR_ALLOC_FAIL; - goto out; - } -- if (ECDH_compute_key(kbuf, klen, dh_pub, key, NULL) != (int)klen || -+ if (kex->ec_nid == NID_sm2) { -+ if (SM2KAP_compute_key(kbuf, klen, dh_pub, key, server) != (int)klen || - BN_bin2bn(kbuf, klen, shared_secret) == NULL) { -- r = SSH_ERR_LIBCRYPTO_ERROR; -- goto out; -+ r = SSH_ERR_LIBCRYPTO_ERROR; -+ goto out; -+ } -+ } else { -+ if (ECDH_compute_key(kbuf, klen, dh_pub, key, NULL) != (int)klen || -+ BN_bin2bn(kbuf, klen, shared_secret) == NULL) { -+ r = SSH_ERR_LIBCRYPTO_ERROR; -+ goto out; -+ } - } -+ - #ifdef DEBUG_KEXECDH - dump_digest("shared secret", kbuf, klen); - #endif -@@ -203,7 +212,7 @@ kex_ecdh_dec(struct kex *kex, const struct sshbuf *server_blob, - int r; - - r = kex_ecdh_dec_key_group(kex, server_blob, kex->ec_client_key, -- kex->ec_group, shared_secretp); -+ kex->ec_group, shared_secretp, 0); - EC_KEY_free(kex->ec_client_key); - kex->ec_client_key = NULL; - return r; -diff --git a/kexgen.c b/kexgen.c -index 15df591..08b9b93 100644 ---- a/kexgen.c -+++ b/kexgen.c -@@ -111,6 +111,7 @@ kex_gen_client(struct ssh *ssh) - r = kex_dh_keypair(kex); - break; - case KEX_ECDH_SHA2: -+ case KEX_SM2_SM3: - r = kex_ecdh_keypair(kex); - break; - #endif -@@ -185,6 +186,7 @@ input_kex_gen_reply(int type, u_int32_t seq, struct ssh *ssh) - r = kex_dh_dec(kex, server_blob, &shared_secret); - break; - case KEX_ECDH_SHA2: -+ case KEX_SM2_SM3: - r = kex_ecdh_dec(kex, server_blob, &shared_secret); - break; - #endif -@@ -307,6 +309,7 @@ input_kex_gen_init(int type, u_int32_t seq, struct ssh *ssh) - &shared_secret); - break; - case KEX_ECDH_SHA2: -+ case KEX_SM2_SM3: - r = kex_ecdh_enc(kex, client_pubkey, &server_pubkey, - &shared_secret); - break; -diff --git a/kexsm2.c b/kexsm2.c -new file mode 100644 -index 0000000..f507557 ---- /dev/null -+++ b/kexsm2.c -@@ -0,0 +1,406 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+int sm2_compute_z_digest(uint8_t *out, -+ const EVP_MD *digest, -+ const uint8_t *id, -+ const size_t id_len, -+ const EC_KEY *key) -+{ -+ int rc = 0; -+ const EC_GROUP *group = EC_KEY_get0_group(key); -+ BN_CTX *ctx = NULL; -+ EVP_MD_CTX *hash = NULL; -+ BIGNUM *p = NULL; -+ BIGNUM *a = NULL; -+ BIGNUM *b = NULL; -+ BIGNUM *xG = NULL; -+ BIGNUM *yG = NULL; -+ BIGNUM *xA = NULL; -+ BIGNUM *yA = NULL; -+ int p_bytes = 0; -+ uint8_t *buf = NULL; -+ uint16_t entl = 0; -+ uint8_t e_byte = 0; -+ -+ hash = EVP_MD_CTX_new(); -+ ctx = BN_CTX_new(); -+ if (hash == NULL || ctx == NULL) { -+ goto done; -+ } -+ -+ p = BN_CTX_get(ctx); -+ a = BN_CTX_get(ctx); -+ b = BN_CTX_get(ctx); -+ xG = BN_CTX_get(ctx); -+ yG = BN_CTX_get(ctx); -+ xA = BN_CTX_get(ctx); -+ yA = BN_CTX_get(ctx); -+ -+ if (yA == NULL) { -+ goto done; -+ } -+ -+ if (!EVP_DigestInit(hash, digest)) { -+ goto done; -+ } -+ -+ /* Z = h(ENTL || ID || a || b || xG || yG || xA || yA) */ -+ -+ if (id_len >= (UINT16_MAX / 8)) { -+ /* too large */ -+ goto done; -+ } -+ -+ entl = (uint16_t)(8 * id_len); -+ -+ e_byte = entl >> 8; -+ if (!EVP_DigestUpdate(hash, &e_byte, 1)) { -+ goto done; -+ } -+ e_byte = entl & 0xFF; -+ if (!EVP_DigestUpdate(hash, &e_byte, 1)) { -+ goto done; -+ } -+ -+ if (id_len > 0 && !EVP_DigestUpdate(hash, id, id_len)) { -+ goto done; -+ } -+ -+ if (!EC_GROUP_get_curve(group, p, a, b, ctx)) { -+ goto done; -+ } -+ -+ p_bytes = BN_num_bytes(p); -+ buf = OPENSSL_zalloc(p_bytes); -+ if (buf == NULL) { -+ goto done; -+ } -+ -+ if (BN_bn2binpad(a, buf, p_bytes) < 0 -+ || !EVP_DigestUpdate(hash, buf, p_bytes) -+ || BN_bn2binpad(b, buf, p_bytes) < 0 -+ || !EVP_DigestUpdate(hash, buf, p_bytes) -+ || !EC_POINT_get_affine_coordinates(group, -+ EC_GROUP_get0_generator(group), -+ xG, yG, ctx) -+ || BN_bn2binpad(xG, buf, p_bytes) < 0 -+ || !EVP_DigestUpdate(hash, buf, p_bytes) -+ || BN_bn2binpad(yG, buf, p_bytes) < 0 -+ || !EVP_DigestUpdate(hash, buf, p_bytes) -+ || !EC_POINT_get_affine_coordinates(group, -+ EC_KEY_get0_public_key(key), -+ xA, yA, ctx) -+ || BN_bn2binpad(xA, buf, p_bytes) < 0 -+ || !EVP_DigestUpdate(hash, buf, p_bytes) -+ || BN_bn2binpad(yA, buf, p_bytes) < 0 -+ || !EVP_DigestUpdate(hash, buf, p_bytes) -+ || !EVP_DigestFinal(hash, out, NULL)) { -+ goto done; -+ } -+ -+ rc = 1; -+ -+ done: -+ OPENSSL_free(buf); -+ BN_CTX_free(ctx); -+ EVP_MD_CTX_free(hash); -+ return rc; -+} -+ -+ -+/* GM/T003_2012 Defined Key Derive Function */ -+int kdf_gmt003_2012(unsigned char *out, size_t outlen, const unsigned char *Z, size_t Zlen, const unsigned char *SharedInfo, size_t SharedInfolen, const EVP_MD *md) -+{ -+ EVP_MD_CTX *mctx = NULL; -+ unsigned int counter; -+ unsigned char ctr[4]; -+ size_t mdlen; -+ int retval = 0; -+ unsigned char dgst[EVP_MAX_MD_SIZE]; -+ -+ if (!out || !outlen) return retval; -+ if (md == NULL) { -+ md = EVP_sm3(); -+ } -+ mdlen = EVP_MD_size(md); -+ mctx = EVP_MD_CTX_new(); -+ if (mctx == NULL) { -+ goto err; -+ } -+ -+ for (counter = 1;; counter++) { -+ if (!EVP_DigestInit(mctx, md)) { -+ goto err; -+ } -+ ctr[0] = (unsigned char)((counter >> 24) & 0xFF); -+ ctr[1] = (unsigned char)((counter >> 16) & 0xFF); -+ ctr[2] = (unsigned char)((counter >> 8) & 0xFF); -+ ctr[3] = (unsigned char)(counter & 0xFF); -+ -+ if (!EVP_DigestUpdate(mctx, Z, Zlen)) { -+ goto err; -+ } -+ if (!EVP_DigestUpdate(mctx, ctr, sizeof(ctr))) { -+ goto err; -+ } -+ if (!EVP_DigestUpdate(mctx, SharedInfo, SharedInfolen)) { -+ goto err; -+ } -+ if (!EVP_DigestFinal(mctx, dgst, NULL)) { -+ goto err; -+ } -+ -+ if (outlen > mdlen) { -+ memcpy(out, dgst, mdlen); -+ out += mdlen; -+ outlen -= mdlen; -+ } else { -+ memcpy(out, dgst, outlen); -+ memset(dgst, 0, mdlen); -+ break; -+ } -+ } -+ -+ retval = 1; -+ -+err: -+ EVP_MD_CTX_free(mctx); -+ return retval; -+} -+ -+int sm2_kap_compute_key(void *out, size_t outlen, int server,\ -+ const uint8_t *peer_uid, int peer_uid_len, const uint8_t *self_uid, int self_uid_len, \ -+ const EC_KEY *peer_ecdhe_key, const EC_KEY *self_ecdhe_key, const EC_KEY *peer_pub_key, const EC_KEY *self_eckey, \ -+ const EVP_MD *md) -+{ -+ BN_CTX *ctx = NULL; -+ EC_POINT *UorV = NULL; -+ const EC_POINT *Rs, *Rp; -+ BIGNUM *Xs = NULL, *Xp = NULL, *h = NULL, *t = NULL, *two_power_w = NULL, *order = NULL; -+ const BIGNUM *priv_key, *r; -+ const EC_GROUP *group; -+ int w; -+ int ret = -1; -+ size_t buflen, len; -+ unsigned char *buf = NULL; -+ -+ if (outlen > INT_MAX) { -+ goto err; -+ } -+ -+ if (!peer_pub_key || !self_eckey) { -+ goto err; -+ } -+ -+ priv_key = EC_KEY_get0_private_key(self_eckey); -+ if (!priv_key) { -+ goto err; -+ } -+ -+ if (!peer_ecdhe_key || !self_ecdhe_key) { -+ goto err; -+ } -+ -+ Rs = EC_KEY_get0_public_key(self_ecdhe_key); -+ Rp = EC_KEY_get0_public_key(peer_ecdhe_key); -+ r = EC_KEY_get0_private_key(self_ecdhe_key); -+ -+ if (!Rs || !Rp || !r) { -+ goto err; -+ } -+ -+ ctx = BN_CTX_new(); -+ Xs = BN_new(); -+ Xp = BN_new(); -+ h = BN_new(); -+ t = BN_new(); -+ two_power_w = BN_new(); -+ order = BN_new(); -+ if (!Xs || !Xp || !h || !t || !two_power_w || !order) { -+ goto err; -+ } -+ -+ group = EC_KEY_get0_group(self_eckey); -+ -+ /*Second: Caculate -- w*/ -+ if (!EC_GROUP_get_order(group, order, ctx) || !EC_GROUP_get_cofactor(group, h, ctx)) { -+ goto err; -+ } -+ -+ w = (BN_num_bits(order) + 1) / 2 - 1; -+ if (!BN_lshift(two_power_w, BN_value_one(), w)) { -+ goto err; -+ } -+ -+ /*Third: Caculate -- X = 2 ^ w + (x & (2 ^ w - 1)) = 2 ^ w + (x mod 2 ^ w)*/ -+ UorV = EC_POINT_new(group); -+ -+ if (!UorV) { -+ goto err; -+ } -+ -+ /*Test peer public key On curve*/ -+ if (!EC_POINT_is_on_curve(group, Rp, ctx)) { -+ goto err; -+ } -+ -+ /*Get x*/ -+ if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) { -+ if (!EC_POINT_get_affine_coordinates_GFp(group, Rs, Xs, NULL, ctx)) { -+ goto err; -+ } -+ -+ if (!EC_POINT_get_affine_coordinates_GFp(group, Rp, Xp, NULL, ctx)) { -+ goto err; -+ } -+ } -+ -+ /*x mod 2 ^ w*/ -+ /*Caculate Self x*/ -+ if (!BN_nnmod(Xs, Xs, two_power_w, ctx)) { -+ goto err; -+ } -+ -+ if (!BN_add(Xs, Xs, two_power_w)) { -+ goto err; -+ } -+ -+ /*Caculate Peer x*/ -+ if (!BN_nnmod(Xp, Xp, two_power_w, ctx)) { -+ goto err; -+ } -+ -+ if (!BN_add(Xp, Xp, two_power_w)) { -+ goto err; -+ } -+ -+ /*Forth: Caculate t*/ -+ if (!BN_mod_mul(t, Xs, r, order, ctx)) { -+ goto err; -+ } -+ -+ if (!BN_mod_add(t, t, priv_key, order, ctx)) { -+ goto err; -+ } -+ -+ /*Fifth: Caculate V or U*/ -+ if (!BN_mul(t, t, h, ctx)) { -+ goto err; -+ } -+ -+ /* [x]R */ -+ if (!EC_POINT_mul(group, UorV, NULL, Rp, Xp, ctx)) { -+ goto err; -+ } -+ -+ /* P + [x]R */ -+ if (!EC_POINT_add(group, UorV, UorV, EC_KEY_get0_public_key(peer_pub_key), ctx)) { -+ goto err; -+ } -+ -+ if (!EC_POINT_mul(group, UorV, NULL, UorV, t, ctx)) { -+ goto err; -+ } -+ -+ /* Detect UorV is in */ -+ if (EC_POINT_is_at_infinity(group, UorV)) { -+ goto err; -+ } -+ -+ /*Sixth: Caculate Key -- Need Xuorv, Yuorv, Zc, Zs, klen*/ -+ { -+ /* -+ size_t buflen, len; -+ unsigned char *buf = NULL; -+ */ -+ size_t elemet_len, idx; -+ -+ elemet_len = (size_t)((EC_GROUP_get_degree(group) + 7) / 8); -+ buflen = elemet_len * 2 + 32 * 2 + 1; /*add 1 byte tag*/ -+ buf = (unsigned char *)OPENSSL_malloc(buflen + 10); -+ if (!buf) { -+ goto err; -+ } -+ memset(buf, 0, buflen + 10); -+ /*1 : Get public key for UorV, Notice: the first byte is a tag, not a valid char*/ -+ idx = EC_POINT_point2oct(group, UorV, 4, buf, buflen, ctx); -+ if (!idx) { -+ goto err; -+ } -+ -+ if (!server) { -+ /*SIDE A*/ -+ len = buflen - idx; -+ if (!sm2_compute_z_digest( (unsigned char *)(buf + idx), md, (const uint8_t *)self_uid, self_uid_len, self_eckey)) { -+ goto err; -+ } -+ len = 32; -+ idx += len; -+ } -+ -+ /*Caculate Peer Z*/ -+ len = buflen - idx; -+ if (!sm2_compute_z_digest( (unsigned char *)(buf + idx), md, (const uint8_t *)peer_uid, peer_uid_len, peer_pub_key)) { -+ goto err; -+ } -+ len = 32; -+ idx += len; -+ -+ if (server) { -+ /*SIDE B*/ -+ len = buflen - idx; -+ if (!sm2_compute_z_digest( (unsigned char *)(buf + idx), md, (const uint8_t *)self_uid, self_uid_len, self_eckey)) { -+ goto err; -+ } -+ len = 32; -+ idx += len; -+ } -+ -+ len = outlen; -+ if (!kdf_gmt003_2012(out, len, (const unsigned char *)(buf + 1), idx - 1, NULL, 0, md)) { -+ goto err; -+ } -+ } -+ -+ ret = outlen; -+ -+err: -+ if (Xs) BN_free(Xs); -+ if (Xp) BN_free(Xp); -+ if (h) BN_free(h); -+ if (t) BN_free(t); -+ if (two_power_w) BN_free(two_power_w); -+ if (order) BN_free(order); -+ if (UorV) EC_POINT_free(UorV); -+ if (buf) OPENSSL_free(buf); -+ if (ctx) BN_CTX_free(ctx); -+ -+ return ret; -+} -+ -+int SM2KAP_compute_key(void *out, size_t outlen, const EC_POINT *pub_key, const EC_KEY *eckey, int server) -+{ -+ int ret = 0; -+ EC_KEY *pubkey = NULL; -+ unsigned char id[16] = {1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8}; -+ -+ if ((pubkey = EC_KEY_new_by_curve_name(NID_sm2)) == NULL) { -+ return ret; -+ } -+ -+ if (EC_KEY_set_public_key(pubkey, pub_key) != 1) { -+ ret = 0; -+ goto out; -+ } -+ -+ ret = sm2_kap_compute_key(out, outlen, server, id, sizeof(id), id, sizeof(id), pubkey, eckey, pubkey, eckey, (EVP_MD*)EVP_sm3()); -+ -+out: -+ EC_KEY_free(pubkey); -+ return ret; -+} -diff --git a/mac.c b/mac.c -index f3dda66..9f22f81 100644 ---- a/mac.c -+++ b/mac.c -@@ -65,6 +65,7 @@ static const struct macalg macs[] = { - { "hmac-md5-96", SSH_DIGEST, SSH_DIGEST_MD5, 96, 0, 0, 0 }, - { "umac-64@openssh.com", SSH_UMAC, 0, 0, 128, 64, 0 }, - { "umac-128@openssh.com", SSH_UMAC128, 0, 0, 128, 128, 0 }, -+ { "hmac-sm3", SSH_DIGEST, SSH_DIGEST_SM3, 0, 0, 0, 0 }, - - /* Encrypt-then-MAC variants */ - { "hmac-sha1-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_SHA1, 0, 0, 0, 1 }, -diff --git a/pathnames.h b/pathnames.h -index 61c5f84..e20f840 100644 ---- a/pathnames.h -+++ b/pathnames.h -@@ -84,6 +84,7 @@ - #define _PATH_SSH_CLIENT_ID_XMSS _PATH_SSH_USER_DIR "/id_xmss" - #define _PATH_SSH_CLIENT_ID_ECDSA_SK _PATH_SSH_USER_DIR "/id_ecdsa_sk" - #define _PATH_SSH_CLIENT_ID_ED25519_SK _PATH_SSH_USER_DIR "/id_ed25519_sk" -+#define _PATH_SSH_CLIENT_ID_SM2 _PATH_SSH_USER_DIR "/id_sm2" - - /* - * Configuration file in user's home directory. This file need not be -diff --git a/regress/agent.sh b/regress/agent.sh -index 5f10606..3ab40b4 100644 ---- a/regress/agent.sh -+++ b/regress/agent.sh -@@ -87,9 +87,18 @@ fi - for t in ${SSH_KEYTYPES}; do - trace "connect via agent using $t key" - if [ "$t" = "ssh-dss" ]; then -+ sed -i "/PubkeyAcceptedAlgorithms/d" $OBJ/ssh_proxy -+ sed -i "/PubkeyAcceptedAlgorithms/d" $OBJ/sshd_proxy - echo "PubkeyAcceptedAlgorithms +ssh-dss" >> $OBJ/ssh_proxy - echo "PubkeyAcceptedAlgorithms +ssh-dss" >> $OBJ/sshd_proxy - fi -+ if [ "$t" = "sm2" ]; then -+ sed -i "/PubkeyAcceptedAlgorithms/d" $OBJ/ssh_proxy -+ sed -i "/PubkeyAcceptedAlgorithms/d" $OBJ/sshd_proxy -+ echo "PubkeyAcceptedAlgorithms +sm2,sm2-cert" >> $OBJ/ssh_proxy -+ echo "PubkeyAcceptedAlgorithms +sm2,sm2-cert" >> $OBJ/sshd_proxy -+ fi -+ - ${SSH} -F $OBJ/ssh_proxy -i $OBJ/$t-agent.pub -oIdentitiesOnly=yes \ - somehost exit 52 - r=$? -diff --git a/regress/keytype.sh b/regress/keytype.sh -index f1c0451..2665bd6 100644 ---- a/regress/keytype.sh -+++ b/regress/keytype.sh -@@ -18,6 +18,7 @@ for i in ${SSH_KEYTYPES}; do - ecdsa-sha2-nistp521) ktypes="$ktypes ecdsa-521" ;; - sk-ssh-ed25519*) ktypes="$ktypes ed25519-sk" ;; - sk-ecdsa-sha2-nistp256*) ktypes="$ktypes ecdsa-sk" ;; -+ sm2) ktypes="$ktypes sm2-256" ;; - esac - done - -@@ -44,6 +45,7 @@ kname_to_ktype() { - rsa-*) echo rsa-sha2-512,rsa-sha2-256,ssh-rsa;; - ed25519-sk) echo sk-ssh-ed25519@openssh.com;; - ecdsa-sk) echo sk-ecdsa-sha2-nistp256@openssh.com;; -+ sm2-256) echo sm2;; - esac - } - -diff --git a/regress/knownhosts-command.sh b/regress/knownhosts-command.sh -index 8472ec8..7f56fb1 100644 ---- a/regress/knownhosts-command.sh -+++ b/regress/knownhosts-command.sh -@@ -41,6 +41,7 @@ ${SSH} -F $OBJ/ssh_proxy x true && fail "ssh connect succeeded with bad exit" - for keytype in ${SSH_HOSTKEY_TYPES} ; do - algs=$keytype - test "x$keytype" = "xssh-dss" && continue -+ test "x$keytype" = "xsm2" && continue - test "x$keytype" = "xssh-rsa" && algs=ssh-rsa,rsa-sha2-256,rsa-sha2-512 - verbose "keytype $keytype" - cat > $OBJ/knownhosts_command << _EOF -diff --git a/regress/misc/fuzz-harness/sig_fuzz.cc b/regress/misc/fuzz-harness/sig_fuzz.cc -index 639e4d2..2945717 100644 ---- a/regress/misc/fuzz-harness/sig_fuzz.cc -+++ b/regress/misc/fuzz-harness/sig_fuzz.cc -@@ -29,6 +29,7 @@ int LLVMFuzzerTestOneInput(const uint8_t* sig, size_t slen) - static struct sshkey *ecdsa256 = generate_or_die(KEY_ECDSA, 256); - static struct sshkey *ecdsa384 = generate_or_die(KEY_ECDSA, 384); - static struct sshkey *ecdsa521 = generate_or_die(KEY_ECDSA, 521); -+ static struct sshkey *sm2 = generate_or_die(KEY_SM2, 256); - #endif - struct sshkey_sig_details *details = NULL; - static struct sshkey *ed25519 = generate_or_die(KEY_ED25519, 0); -@@ -52,6 +53,9 @@ int LLVMFuzzerTestOneInput(const uint8_t* sig, size_t slen) - sshkey_verify(ecdsa521, sig, slen, (const u_char *)data, dlen, NULL, 0, &details); - sshkey_sig_details_free(details); - details = NULL; -+ sshkey_verify(sm2, sig, slen, (const u_char *)data, dlen, NULL, 0, &details); -+ sshkey_sig_details_free(details); -+ details = NULL; - #endif - - sshkey_verify(ed25519, sig, slen, (const u_char *)data, dlen, NULL, 0, &details); -diff --git a/regress/unittests/kex/test_kex.c b/regress/unittests/kex/test_kex.c -index caf8f57..48fef08 100644 ---- a/regress/unittests/kex/test_kex.c -+++ b/regress/unittests/kex/test_kex.c -@@ -152,6 +152,7 @@ do_kex_with_key(char *kex, int keytype, int bits) - #endif /* OPENSSL_HAS_ECC */ - #endif /* WITH_OPENSSL */ - server2->kex->kex[KEX_C25519_SHA256] = kex_gen_server; -+ server2->kex->kex[KEX_SM2_SM3] = kex_gen_server; - server2->kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_server; - server2->kex->kex[KEX_KEM_MLKEM768X25519_SHA256] = kex_gen_server; - server2->kex->load_host_public_key = server->kex->load_host_public_key; -@@ -192,6 +193,7 @@ do_kex(char *kex) - #endif /* OPENSSL_HAS_ECC */ - #endif /* WITH_OPENSSL */ - do_kex_with_key(kex, KEY_ED25519, 256); -+ do_kex_with_key(kex, KEY_SM2, 256); - } - - void -@@ -208,6 +210,7 @@ kex_tests(void) - do_kex("diffie-hellman-group-exchange-sha1"); - do_kex("diffie-hellman-group14-sha1"); - do_kex("diffie-hellman-group1-sha1"); -+ do_kex("sm2-sm3"); - # ifdef USE_MLKEM768X25519 - do_kex("mlkem768x25519-sha256"); - # endif /* USE_MLKEM768X25519 */ -diff --git a/ssh-ecdsa.c b/ssh-ecdsa.c -index 695ed45..3b2c98b 100644 ---- a/ssh-ecdsa.c -+++ b/ssh-ecdsa.c -@@ -54,6 +54,7 @@ sshkey_ecdsa_fixup_group(EVP_PKEY *k) - #ifdef OPENSSL_HAS_NISTP521 - NID_secp521r1, - #endif -+ NID_sm2 - -1 - }; - int nid = -1; -@@ -337,7 +338,8 @@ ssh_ecdsa_sign(struct sshkey *key, - *sigp = NULL; - - if (key == NULL || key->pkey == NULL || -- sshkey_type_plain(key->type) != KEY_ECDSA) -+ (sshkey_type_plain(key->type) != KEY_ECDSA && -+ sshkey_type_plain(key->type) != KEY_SM2)) - return SSH_ERR_INVALID_ARGUMENT; - - if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1) -@@ -397,7 +399,8 @@ ssh_ecdsa_verify(const struct sshkey *key, - unsigned char *sigb = NULL, *cp; - - if (key == NULL || key->pkey == NULL || -- sshkey_type_plain(key->type) != KEY_ECDSA || -+ (sshkey_type_plain(key->type) != KEY_ECDSA && -+ sshkey_type_plain(key->type) != KEY_SM2) || - sig == NULL || siglen == 0) - return SSH_ERR_INVALID_ARGUMENT; - -diff --git a/ssh-keygen.c b/ssh-keygen.c -index 8396c40..04f38e3 100644 ---- a/ssh-keygen.c -+++ b/ssh-keygen.c -@@ -189,6 +189,7 @@ type_bits_valid(int type, const char *name, u_int32_t *bitsp) - *bitsp = DEFAULT_BITS_DSA; - break; - case KEY_ECDSA: -+ case KEY_SM2: - if (name != NULL && - (nid = sshkey_ecdsa_nid_from_name(name)) > 0) - *bitsp = sshkey_curve_nid_to_bits(nid); -@@ -215,6 +216,10 @@ type_bits_valid(int type, const char *name, u_int32_t *bitsp) - fatal("Invalid RSA key length: maximum is %d bits", - OPENSSL_RSA_MAX_MODULUS_BITS); - break; -+ case KEY_SM2: -+ if (*bitsp != 256) -+ fatal("Invalid SM2 key length: must be 256 bits"); -+ break; - case KEY_ECDSA: - if (sshkey_ecdsa_bits_to_nid(*bitsp) == -1) - #ifdef OPENSSL_HAS_NISTP521 -@@ -273,6 +278,9 @@ ask_filename(struct passwd *pw, const char *prompt) - case KEY_ECDSA: - name = _PATH_SSH_CLIENT_ID_ECDSA; - break; -+ case KEY_SM2: -+ name = _PATH_SSH_CLIENT_ID_SM2; -+ break; - case KEY_ECDSA_SK_CERT: - case KEY_ECDSA_SK: - name = _PATH_SSH_CLIENT_ID_ECDSA_SK; -@@ -390,6 +398,7 @@ do_convert_to_pkcs8(struct sshkey *k) - #endif - #ifdef OPENSSL_HAS_ECC - case KEY_ECDSA: -+ case KEY_SM2: - if (!PEM_write_EC_PUBKEY(stdout, - EVP_PKEY_get0_EC_KEY(k->pkey))) - fatal("PEM_write_EC_PUBKEY failed"); -@@ -418,6 +427,7 @@ do_convert_to_pem(struct sshkey *k) - #endif - #ifdef OPENSSL_HAS_ECC - case KEY_ECDSA: -+ case KEY_SM2: - if (!PEM_write_EC_PUBKEY(stdout, - EVP_PKEY_get0_EC_KEY(k->pkey))) - fatal("PEM_write_EC_PUBKEY failed"); -@@ -3325,7 +3335,7 @@ 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" -+ " [-t dsa | ecdsa | ecdsa-sk | ed25519 | ed25519-sk | rsa | sm2]\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" -diff --git a/ssh-keyscan.c b/ssh-keyscan.c -index f34e056..6210faf 100644 ---- a/ssh-keyscan.c -+++ b/ssh-keyscan.c -@@ -69,9 +69,10 @@ int ssh_port = SSH_DEFAULT_PORT; - #define KT_XMSS (1<<4) - #define KT_ECDSA_SK (1<<5) - #define KT_ED25519_SK (1<<6) -+#define KT_SM2 (1<<7) - - #define KT_MIN KT_DSA --#define KT_MAX KT_ED25519_SK -+#define KT_MAX KT_SM2 - - int get_cert = 0; - int get_keytypes = KT_RSA|KT_ECDSA|KT_ED25519|KT_ECDSA_SK|KT_ED25519_SK; -@@ -270,6 +271,11 @@ keygrab_ssh2(con *c) - "ecdsa-sha2-nistp384," - "ecdsa-sha2-nistp521"; - break; -+ case KT_SM2: -+ myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = get_cert ? -+ "sm2-cert" : -+ "sm2"; -+ break; - case KT_ECDSA_SK: - myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = get_cert ? - "sk-ecdsa-sha2-nistp256-cert-v01@openssh.com" : -@@ -299,6 +305,7 @@ keygrab_ssh2(con *c) - 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; -+ c->c_ssh->kex->kex[KEX_SM2_SM3] = kex_gen_client; - # endif - #endif - c->c_ssh->kex->kex[KEX_C25519_SHA256] = kex_gen_client; -@@ -763,6 +770,9 @@ main(int argc, char **argv) - case KEY_ECDSA: - get_keytypes |= KT_ECDSA; - break; -+ case KEY_SM2: -+ get_keytypes |= KT_SM2; -+ break; - case KEY_RSA: - get_keytypes |= KT_RSA; - break; -diff --git a/ssh-sm2.c b/ssh-sm2.c -new file mode 100644 -index 0000000..a374406 ---- /dev/null -+++ b/ssh-sm2.c -@@ -0,0 +1,397 @@ -+#include "includes.h" -+#include -+#include -+#include -+#include -+ -+#include -+#include "sshbuf.h" -+#include "ssherr.h" -+#include "digest.h" -+#include "sshkey.h" -+ -+#include "openbsd-compat/openssl-compat.h" -+ -+/* Reuse some ECDSA internals */ -+extern struct sshkey_impl_funcs sshkey_ecdsa_funcs; -+ -+const unsigned char *sm2_id = (const unsigned char *)"1234567812345678"; -+ -+static void -+ssh_sm2_cleanup(struct sshkey *k) -+{ -+ EVP_PKEY_free(k->pkey); -+ k->pkey = NULL; -+} -+ -+static int -+ssh_sm2_equal(const struct sshkey *a, const struct sshkey *b) -+{ -+ if (!sshkey_ecdsa_funcs.equal(a, b)) -+ return 0; -+ return 1; -+} -+ -+static int -+ssh_sm2_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; -+ -+ return 0; -+} -+ -+static int -+ssh_sm2_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; -+ return 0; -+} -+ -+static int -+ssh_sm2_serialize_private(const struct sshkey *key, struct sshbuf *b, -+ enum sshkey_serialize_rep opts) -+{ -+ int r; -+ -+ if ((r = sshkey_ecdsa_funcs.serialize_private(key, b, opts)) != 0) -+ return r; -+ -+ return 0; -+} -+ -+static int -+ssh_sm2_deserialize_private(const char *ktype, struct sshbuf *b, -+ struct sshkey *key) -+{ -+ int r; -+ -+ if ((r = sshkey_ecdsa_funcs.deserialize_private(ktype, b, key)) != 0) -+ return r; -+ -+ return 0; -+} -+ -+static int -+ssh_sm2_generate(struct sshkey *k, int bits) -+{ -+ EC_KEY *private; -+ -+ k->ecdsa_nid = NID_sm2; -+ 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; -+ EVP_PKEY *p = EVP_PKEY_new(); -+ if (!p) { -+ EC_KEY_free(private); -+ return SSH_ERR_LIBCRYPTO_ERROR; -+ } -+ -+ if (EVP_PKEY_set1_EC_KEY(p, private) != 1) { -+ EVP_PKEY_free(p); -+ EC_KEY_free(private); -+ return SSH_ERR_LIBCRYPTO_ERROR; -+ } -+ EC_KEY_free(private); -+ k->pkey = p; -+ -+ return 0; -+} -+ -+static int -+ssh_sm2_copy_public(const struct sshkey *from, struct sshkey *to) -+{ -+ int r; -+ -+ if ((r = sshkey_ecdsa_funcs.copy_public(from, to)) != 0) -+ return r; -+ return 0; -+} -+ -+static int -+sm2_get_sig(EVP_PKEY *pkey, const u_char *data, -+ size_t datalen, u_char *sig, size_t *slen) -+{ -+ EVP_PKEY_CTX *pctx = NULL; -+ EVP_MD_CTX *mctx = NULL; -+ int ret = SSH_ERR_INTERNAL_ERROR; -+ -+ if ((pctx = EVP_PKEY_CTX_new(pkey, NULL)) == NULL) { -+ ret = SSH_ERR_ALLOC_FAIL; -+ goto out; -+ } -+ if ((mctx = EVP_MD_CTX_new()) == NULL) { -+ ret = SSH_ERR_ALLOC_FAIL; -+ goto out; -+ } -+ if (EVP_PKEY_CTX_set1_id(pctx, sm2_id, 16) != 1) { -+ ret = SSH_ERR_INTERNAL_ERROR; -+ goto out; -+ } -+ -+ EVP_MD_CTX_set_pkey_ctx(mctx, pctx); -+ -+ if ((EVP_DigestSignInit(mctx, NULL, EVP_sm3(), NULL, pkey)) != 1) { -+ ret = SSH_ERR_INTERNAL_ERROR; -+ goto out; -+ } -+ -+ if ((EVP_DigestSignUpdate(mctx, data, datalen)) != 1) { -+ ret = SSH_ERR_INTERNAL_ERROR; -+ goto out; -+ } -+ -+ if ((EVP_DigestSignFinal(mctx, sig, slen)) != 1) { -+ ret = SSH_ERR_INTERNAL_ERROR; -+ goto out; -+ } -+ ret = 0; -+ -+out: -+ EVP_PKEY_CTX_free(pctx); -+ EVP_MD_CTX_free(mctx); -+ return ret; -+} -+ -+static int -+ssh_sm2_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; -+ int pkey_len = 0; -+ int r = 0; -+ int len = 0; -+ EVP_PKEY *key_sm2 = NULL; -+ struct sshbuf *b = NULL; -+ int ret = SSH_ERR_INTERNAL_ERROR; -+ -+ if (lenp != NULL) -+ *lenp = 0; -+ if (sigp != NULL) -+ *sigp = NULL; -+ -+ if (key == NULL || key->pkey == NULL || -+ sshkey_type_plain(key->type) != KEY_SM2) -+ return SSH_ERR_INVALID_ARGUMENT; -+ -+ // if ((key_sm2 = EVP_PKEY_new()) == NULL) { -+ // return SSH_ERR_ALLOC_FAIL; -+ // } -+ -+ // if ((EVP_PKEY_set1_EC_KEY(key_sm2, key->ecdsa)) != 1) { -+ // ret = SSH_ERR_INTERNAL_ERROR; -+ // goto out; -+ // } -+ key_sm2 = key->pkey; -+ -+ if ((pkey_len = EVP_PKEY_size(key_sm2)) == 0) { -+ ret = SSH_ERR_INVALID_ARGUMENT; -+ goto out; -+ } -+ -+ slen = pkey_len; -+ -+ if ((sig = OPENSSL_malloc(pkey_len)) == NULL) { -+ ret = SSH_ERR_ALLOC_FAIL; -+ goto out; -+ } -+ -+ if (ret = sm2_get_sig(key_sm2, data, datalen, sig, &slen)) { -+ goto out; -+ } -+ -+ if ((b = sshbuf_new()) == NULL) { -+ ret = SSH_ERR_ALLOC_FAIL; -+ goto out; -+ } -+ -+ if ((r = sshbuf_put_cstring(b, "sm2")) != 0 || -+ (r = 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: -+ // EVP_PKEY_free(key_sm2); -+ if (sig != NULL) { -+ explicit_bzero(sig, slen); -+ OPENSSL_free(sig); -+ } -+ sshbuf_free(b); -+ return ret; -+} -+ -+static int -+sm2_verify_sig(EVP_PKEY *pkey, const u_char *data, -+ size_t datalen, const u_char *sig, size_t slen) -+{ -+ EVP_PKEY_CTX *pctx = NULL; -+ EVP_MD_CTX *mctx = NULL; -+ int ret = SSH_ERR_INTERNAL_ERROR; -+ -+ if ((pctx = EVP_PKEY_CTX_new(pkey, NULL)) == NULL) { -+ ret = SSH_ERR_ALLOC_FAIL; -+ goto out; -+ } -+ -+ if ((mctx = EVP_MD_CTX_new()) == NULL) { -+ ret = SSH_ERR_ALLOC_FAIL; -+ goto out; -+ } -+ -+ if (EVP_PKEY_CTX_set1_id(pctx, sm2_id, 16) != 1) { -+ ret = SSH_ERR_INTERNAL_ERROR; -+ goto out; -+ } -+ EVP_MD_CTX_set_pkey_ctx(mctx, pctx); -+ -+ if ((EVP_DigestVerifyInit(mctx, NULL, EVP_sm3(), NULL, pkey)) != 1) { -+ ret = SSH_ERR_INTERNAL_ERROR; -+ goto out; -+ } -+ -+ if ((EVP_DigestVerifyUpdate(mctx, data, datalen)) != 1) { -+ ret = SSH_ERR_INTERNAL_ERROR; -+ goto out; -+ } -+ -+ if ((EVP_DigestVerifyFinal(mctx, sig, slen)) != 1) { -+ ret = SSH_ERR_INTERNAL_ERROR; -+ goto out; -+ } -+ -+ ret = 0; -+out: -+ EVP_PKEY_CTX_free(pctx); -+ EVP_MD_CTX_free(mctx); -+ return ret; -+} -+ -+static int -+ssh_sm2_verify(const struct sshkey *key, -+ const u_char *signature, size_t signaturelen, -+ const u_char *data, size_t datalen, const char *alg, u_int compat, -+ struct sshkey_sig_details **detailsp) -+{ -+ const u_char *sig = NULL; -+ char *ktype = NULL; -+ size_t slen = 0; -+ int pkey_len = 0; -+ int r = 0; -+ int len = 0; -+ EVP_PKEY *key_sm2 = NULL; -+ struct sshbuf *b = NULL; -+ int ret = SSH_ERR_INTERNAL_ERROR; -+ -+ if (key == NULL || -+ sshkey_type_plain(key->type) != KEY_SM2 || -+ signature == NULL || signaturelen == 0) -+ return SSH_ERR_INVALID_ARGUMENT; -+ -+ if ((b = sshbuf_from(signature, signaturelen)) == NULL) -+ return SSH_ERR_ALLOC_FAIL; -+ -+ if ((r = sshbuf_get_cstring(b, &ktype, NULL)) != 0 || -+ (r = sshbuf_get_string_direct(b, &sig, &slen)) != 0) -+ goto out; -+ -+ if (strcmp("sm2", ktype) != 0) { -+ ret = SSH_ERR_KEY_TYPE_MISMATCH; -+ goto out; -+ } -+ -+ if (sshbuf_len(b) != 0) { -+ ret = SSH_ERR_UNEXPECTED_TRAILING_DATA; -+ goto out; -+ } -+ -+ // if ((key_sm2 = EVP_PKEY_new()) == NULL) { -+ // ret = SSH_ERR_ALLOC_FAIL; -+ // goto out; -+ // } -+ -+ // if ((EVP_PKEY_set1_EC_KEY(key_sm2, key->ecdsa)) != 1) { -+ // ret = SSH_ERR_INTERNAL_ERROR; -+ // goto out; -+ // } -+ key_sm2 = key->pkey; -+ -+ if ((pkey_len = EVP_PKEY_size(key_sm2)) == 0) { -+ ret = SSH_ERR_INVALID_ARGUMENT; -+ goto out; -+ } -+ -+ if (ret = sm2_verify_sig(key_sm2, data, datalen, sig, slen)) { -+ goto out; -+ } -+ -+ ret = 0; -+out: -+ // EVP_PKEY_free(key_sm2); -+ sshbuf_free(b); -+ free(ktype); -+ return ret; -+} -+ -+static const struct sshkey_impl_funcs sshkey_sm2_funcs = { -+ /* .size = */ NULL, -+ /* .alloc = */ NULL, -+ /* .cleanup = */ ssh_sm2_cleanup, -+ /* .equal = */ ssh_sm2_equal, -+ /* .ssh_serialize_public = */ ssh_sm2_serialize_public, -+ /* .ssh_deserialize_public = */ ssh_sm2_deserialize_public, -+ /* .ssh_serialize_private = */ ssh_sm2_serialize_private, -+ /* .ssh_deserialize_private = */ssh_sm2_deserialize_private, -+ /* .generate = */ ssh_sm2_generate, -+ /* .copy_public = */ ssh_sm2_copy_public, -+ /* .sign = */ ssh_sm2_sign, -+ /* .verify = */ ssh_sm2_verify, -+}; -+ -+const struct sshkey_impl sshkey_sm2_impl = { -+ /* .name = */ "sm2", -+ /* .shortname = */ "SM2", -+ /* .sigalg = */ NULL, -+ /* .type = */ KEY_SM2, -+ /* .nid = */ NID_sm2, -+ /* .cert = */ 0, -+ /* .sigonly = */ 0, -+ /* .keybits = */ 256, -+ /* .funcs = */ &sshkey_sm2_funcs, -+}; -+ -+const struct sshkey_impl sshkey_sm2_cert_impl = { -+ /* .name = */ "sm2-cert", -+ /* .shortname = */ "SM2-CERT", -+ /* .sigalg = */ NULL, -+ /* .type = */ KEY_SM2_CERT, -+ /* .nid = */ NID_sm2, -+ /* .cert = */ 1, -+ /* .sigonly = */ 0, -+ /* .keybits = */ 256, -+ /* .funcs = */ &sshkey_sm2_funcs, -+}; -diff --git a/ssh_api.c b/ssh_api.c -index 5faaffd..1746bfb 100644 ---- a/ssh_api.c -+++ b/ssh_api.c -@@ -130,6 +130,7 @@ ssh_init(struct ssh **sshp, int is_server, struct kex_params *kex_params) - ssh->kex->kex[KEX_DH_GEX_SHA256] = kexgex_server; - # ifdef OPENSSL_HAS_ECC - ssh->kex->kex[KEX_ECDH_SHA2] = kex_gen_server; -+ ssh->kex->kex[KEX_SM2_SM3] = kex_gen_server; - # endif - #endif /* WITH_OPENSSL */ - ssh->kex->kex[KEX_C25519_SHA256] = kex_gen_server; -@@ -149,6 +150,7 @@ ssh_init(struct ssh **sshp, int is_server, struct kex_params *kex_params) - ssh->kex->kex[KEX_DH_GEX_SHA256] = kexgex_client; - # ifdef OPENSSL_HAS_ECC - ssh->kex->kex[KEX_ECDH_SHA2] = kex_gen_client; -+ ssh->kex->kex[KEX_SM2_SM3] = kex_gen_client; - # endif - #endif /* WITH_OPENSSL */ - ssh->kex->kex[KEX_C25519_SHA256] = kex_gen_client; -diff --git a/sshconnect2.c b/sshconnect2.c -index 7304ba5..0b97cf7 100644 ---- a/sshconnect2.c -+++ b/sshconnect2.c -@@ -311,6 +311,7 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port, - ssh->kex->kex[KEX_DH_GEX_SHA256] = kexgex_client; - # ifdef OPENSSL_HAS_ECC - ssh->kex->kex[KEX_ECDH_SHA2] = kex_gen_client; -+ ssh->kex->kex[KEX_SM2_SM3] = kex_gen_client; - # endif - # ifdef GSSAPI - if (options.gss_keyex) { -diff --git a/sshd-session.c b/sshd-session.c -index a9e1cf4..a27e130 100644 ---- a/sshd-session.c -+++ b/sshd-session.c -@@ -489,6 +489,7 @@ list_hostkey_types(void) - /* FALLTHROUGH */ - case KEY_DSA: - case KEY_ECDSA: -+ case KEY_SM2: - case KEY_ED25519: - case KEY_ECDSA_SK: - case KEY_ED25519_SK: -@@ -510,6 +511,7 @@ list_hostkey_types(void) - /* FALLTHROUGH */ - case KEY_DSA_CERT: - case KEY_ECDSA_CERT: -+ case KEY_SM2_CERT: - case KEY_ED25519_CERT: - case KEY_ECDSA_SK_CERT: - case KEY_ED25519_SK_CERT: -@@ -536,6 +538,7 @@ get_hostkey_by_type(int type, int nid, int need_private, struct ssh *ssh) - case KEY_RSA_CERT: - case KEY_DSA_CERT: - case KEY_ECDSA_CERT: -+ case KEY_SM2_CERT: - case KEY_ED25519_CERT: - case KEY_ECDSA_SK_CERT: - case KEY_ED25519_SK_CERT: -@@ -552,6 +555,7 @@ get_hostkey_by_type(int type, int nid, int need_private, struct ssh *ssh) - continue; - switch (type) { - case KEY_ECDSA: -+ case KEY_SM2: - case KEY_ECDSA_SK: - case KEY_ECDSA_CERT: - case KEY_ECDSA_SK_CERT: -@@ -1528,6 +1532,7 @@ do_ssh2_kex(struct ssh *ssh) - kex->kex[KEX_DH_GEX_SHA256] = kexgex_server; - #ifdef OPENSSL_HAS_ECC - kex->kex[KEX_ECDH_SHA2] = kex_gen_server; -+ kex->kex[KEX_SM2_SM3] = kex_gen_server; - #endif - # ifdef GSSAPI - if (options.gss_keyex) { -diff --git a/sshd.c b/sshd.c -index 142310c..28b2b94 100644 ---- a/sshd.c -+++ b/sshd.c -@@ -1645,6 +1645,7 @@ main(int ac, char **av) - case KEY_RSA: - case KEY_DSA: - case KEY_ECDSA: -+ case KEY_SM2: - case KEY_ED25519: - case KEY_ECDSA_SK: - case KEY_ED25519_SK: -diff --git a/sshkey.c b/sshkey.c -index c3acd4e..ad8848b 100644 ---- a/sshkey.c -+++ b/sshkey.c -@@ -65,6 +65,8 @@ - #include "sshkey-xmss.h" - #include "xmss_fast.h" - #endif -+extern const struct sshkey_impl sshkey_sm2_impl; -+extern const struct sshkey_impl sshkey_sm2_cert_impl; - - #include "openbsd-compat/openssl-compat.h" - -@@ -176,6 +178,9 @@ const struct sshkey_impl * const keyimpls[] = { - #ifdef GSSAPI - &sshkey_null_impl, - #endif /* GSSAPI */ -+ -+ &sshkey_sm2_impl, -+ &sshkey_sm2_cert_impl, - NULL - }; - -@@ -293,6 +298,8 @@ key_type_is_ecdsa_variant(int type) - case KEY_ECDSA_CERT: - case KEY_ECDSA_SK: - case KEY_ECDSA_SK_CERT: -+ case KEY_SM2: -+ case KEY_SM2_CERT: - return 1; - } - return 0; -@@ -472,6 +479,8 @@ sshkey_type_plain(int type) - return KEY_ED25519_SK; - case KEY_XMSS_CERT: - return KEY_XMSS; -+ case KEY_SM2_CERT: -+ return KEY_SM2; - default: - return type; - } -@@ -488,6 +497,8 @@ sshkey_type_certified(int type) - return KEY_DSA_CERT; - case KEY_ECDSA: - return KEY_ECDSA_CERT; -+ case KEY_SM2: -+ return KEY_SM2_CERT; - case KEY_ECDSA_SK: - return KEY_ECDSA_SK_CERT; - case KEY_ED25519: -@@ -606,6 +617,8 @@ sshkey_curve_name_to_nid(const char *name) - else if (strcmp(name, "nistp521") == 0) - return NID_secp521r1; - # endif /* OPENSSL_HAS_NISTP521 */ -+ else if (strcmp(name, "sm2") == 0) -+ return NID_sm2; - else - return -1; - } -@@ -622,6 +635,8 @@ sshkey_curve_nid_to_bits(int nid) - case NID_secp521r1: - return 521; - # endif /* OPENSSL_HAS_NISTP521 */ -+ case NID_sm2: -+ return 256; - default: - return 0; - } -@@ -656,6 +671,8 @@ sshkey_curve_nid_to_name(int nid) - case NID_secp521r1: - return "nistp521"; - # endif /* OPENSSL_HAS_NISTP521 */ -+ case NID_sm2: -+ return "sm2"; - default: - return NULL; - } -@@ -3360,6 +3377,7 @@ sshkey_private_to_blob_pem_pkcs8(struct sshkey *key, struct sshbuf *buf, - #endif - #ifdef OPENSSL_HAS_ECC - case KEY_ECDSA: -+ case KEY_SM2: - if (format == SSHKEY_PRIVATE_PEM) { - success = PEM_write_bio_ECPrivateKey(bio, - EVP_PKEY_get0_EC_KEY(key->pkey), -@@ -3427,6 +3445,7 @@ sshkey_private_to_fileblob(struct sshkey *key, struct sshbuf *blob, - #ifdef WITH_OPENSSL - case KEY_DSA: - case KEY_ECDSA: -+ case KEY_SM2: - case KEY_RSA: - break; /* see below */ - #endif /* WITH_OPENSSL */ -@@ -3614,8 +3633,8 @@ sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type, - #endif - #endif - #ifdef OPENSSL_HAS_ECC -- } else if (EVP_PKEY_base_id(pk) == EVP_PKEY_EC && -- (type == KEY_UNSPEC || type == KEY_ECDSA)) { -+ } else if ((EVP_PKEY_base_id(pk) == EVP_PKEY_EC || EVP_PKEY_base_id(pk) == EVP_PKEY_SM2) && -+ (type == KEY_UNSPEC || type == KEY_ECDSA || type == KEY_SM2)) { - if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) { - r = SSH_ERR_ALLOC_FAIL; - goto out; -@@ -3626,6 +3645,9 @@ sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type, - goto out; - } - prv->type = KEY_ECDSA; -+ if (prv->ecdsa_nid == NID_sm2) { -+ prv->type = KEY_SM2; -+ } - if (sshkey_curve_nid_to_name(prv->ecdsa_nid) == NULL || - sshkey_ec_validate_public(EC_KEY_get0_group(ecdsa), - EC_KEY_get0_public_key(ecdsa)) != 0 || -diff --git a/sshkey.h b/sshkey.h -index cce4b93..3963909 100644 ---- a/sshkey.h -+++ b/sshkey.h -@@ -67,6 +67,8 @@ enum sshkey_types { - KEY_DSA_CERT, - KEY_ECDSA_CERT, - KEY_ED25519_CERT, -+ KEY_SM2, -+ KEY_SM2_CERT, - KEY_XMSS, - KEY_XMSS_CERT, - KEY_ECDSA_SK, diff --git a/debian/patches/authorized-keys-man-symlink.patch b/debian/patches/authorized-keys-man-symlink.patch index e9f8fe7..f86f4c0 100644 --- a/debian/patches/authorized-keys-man-symlink.patch +++ b/debian/patches/authorized-keys-man-symlink.patch @@ -1,4 +1,4 @@ -From a9fcf8497c9a34523f834e0982fee41daad78bc4 Mon Sep 17 00:00:00 2001 +From e69bb05c4592053012cf6d1ee785ae8200cc3e79 Mon Sep 17 00:00:00 2001 From: Tomas Pospisek Date: Sun, 9 Feb 2014 16:10:07 +0000 Subject: Install authorized_keys(5) as a symlink to sshd(8) @@ -13,10 +13,10 @@ Patch-Name: authorized-keys-man-symlink.patch 1 file changed, 1 insertion(+) diff --git a/Makefile.in b/Makefile.in -index e92bf3e31..eeea95410 100644 +index 6d453e859..6ad81e78b 100644 --- a/Makefile.in +++ b/Makefile.in -@@ -426,6 +426,7 @@ install-files: +@@ -451,6 +451,7 @@ install-files: $(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 diff --git a/debian/patches/configure-cache-vars.patch b/debian/patches/configure-cache-vars.patch deleted file mode 100644 index d79e128..0000000 --- a/debian/patches/configure-cache-vars.patch +++ /dev/null @@ -1,137 +0,0 @@ -From 83dc570f464527322534494bcb75ad068c8d39e5 Mon Sep 17 00:00:00 2001 -From: Colin Watson -Date: Wed, 3 Apr 2024 11:52:04 +0100 -Subject: Add Autoconf cache variables for OSSH_CHECK_*FLAG_* - -This allows overriding them on configure's command line in case the -automatic checks go wrong somehow. bz#3673 - -Forwarded: https://bugzilla.mindrot.org/show_bug.cgi?id=3673#c3 -Last-Update: 2024-04-03 - -Patch-Name: configure-cache-vars.patch ---- - m4/openssh.m4 | 42 ++++++++++++++++++++++++------------------ - 1 file changed, 24 insertions(+), 18 deletions(-) - -diff --git a/m4/openssh.m4 b/m4/openssh.m4 -index 176a8d1c9..f420146f1 100644 ---- a/m4/openssh.m4 -+++ b/m4/openssh.m4 -@@ -62,7 +62,8 @@ dnl Check that $CC accepts a flag 'check_flag'. If it is supported append - dnl 'define_flag' to $CFLAGS. If 'define_flag' is not specified, then append - dnl 'check_flag'. - AC_DEFUN([OSSH_CHECK_CFLAG_COMPILE], [{ -- AC_MSG_CHECKING([if $CC supports compile flag $1]) -+ ossh_cache_var=AS_TR_SH([ossh_cv_cflag_$1]) -+ AC_CACHE_CHECK([if $CC supports compile flag $1], [$ossh_cache_var], [ - saved_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $WERROR $1" - _define_flag="$2" -@@ -71,22 +72,23 @@ AC_DEFUN([OSSH_CHECK_CFLAG_COMPILE], [{ - [ - if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null - then -- AC_MSG_RESULT([no]) -+ eval "$ossh_cache_var=no" - CFLAGS="$saved_CFLAGS" - else - dnl If we are compiling natively, try running the program. - AC_RUN_IFELSE([OSSH_COMPILER_FLAG_TEST_PROGRAM], -- [ AC_MSG_RESULT([yes]) -+ [ eval "$ossh_cache_var=yes" - CFLAGS="$saved_CFLAGS $_define_flag" ], -- [ AC_MSG_RESULT([no, fails at run time]) -+ [ eval "$ossh_cache_var='no, fails at run time'" - CFLAGS="$saved_CFLAGS" ], -- [ AC_MSG_RESULT([yes]) -+ [ eval "$ossh_cache_var=yes" - CFLAGS="$saved_CFLAGS $_define_flag" ], - ) - fi], -- [ AC_MSG_RESULT([no]) -+ [ eval "$ossh_cache_var=no" - CFLAGS="$saved_CFLAGS" ] - ) -+ ]) - }]) - - dnl OSSH_CHECK_CFLAG_LINK(check_flag[, define_flag]) -@@ -94,7 +96,8 @@ dnl Check that $CC accepts a flag 'check_flag'. If it is supported append - dnl 'define_flag' to $CFLAGS. If 'define_flag' is not specified, then append - dnl 'check_flag'. - AC_DEFUN([OSSH_CHECK_CFLAG_LINK], [{ -- AC_MSG_CHECKING([if $CC supports compile flag $1 and linking succeeds]) -+ ossh_cache_var=AS_TR_SH([ossh_cv_cflag_$1]) -+ AC_CACHE_CHECK([if $CC supports compile flag $1 and linking succeeds], [$ossh_cache_var], [ - saved_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $WERROR $1" - _define_flag="$2" -@@ -103,22 +106,23 @@ AC_DEFUN([OSSH_CHECK_CFLAG_LINK], [{ - [ - if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null - then -- AC_MSG_RESULT([no]) -+ eval "$ossh_cache_var=no" - CFLAGS="$saved_CFLAGS" - else - dnl If we are compiling natively, try running the program. - AC_RUN_IFELSE([OSSH_COMPILER_FLAG_TEST_PROGRAM], -- [ AC_MSG_RESULT([yes]) -+ [ eval "$ossh_cache_var=yes" - CFLAGS="$saved_CFLAGS $_define_flag" ], -- [ AC_MSG_RESULT([no, fails at run time]) -+ [ eval "$ossh_cache_var='no, fails at run time'" - CFLAGS="$saved_CFLAGS" ], -- [ AC_MSG_RESULT([yes]) -+ [ eval "$ossh_cache_var=yes" - CFLAGS="$saved_CFLAGS $_define_flag" ], - ) - fi], -- [ AC_MSG_RESULT([no]) -+ [ eval "$ossh_cache_var=no" - CFLAGS="$saved_CFLAGS" ] - ) -+ ]) - }]) - - dnl OSSH_CHECK_LDFLAG_LINK(check_flag[, define_flag]) -@@ -126,7 +130,8 @@ dnl Check that $LD accepts a flag 'check_flag'. If it is supported append - dnl 'define_flag' to $LDFLAGS. If 'define_flag' is not specified, then append - dnl 'check_flag'. - AC_DEFUN([OSSH_CHECK_LDFLAG_LINK], [{ -- AC_MSG_CHECKING([if $LD supports link flag $1]) -+ ossh_cache_var=AS_TR_SH([ossh_cv_ldflag_$1]) -+ AC_CACHE_CHECK([if $LD supports link flag $1], [$ossh_cache_var], [ - saved_LDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS $WERROR $1" - _define_flag="$2" -@@ -135,22 +140,23 @@ AC_DEFUN([OSSH_CHECK_LDFLAG_LINK], [{ - [ - if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null - then -- AC_MSG_RESULT([no]) -+ eval "$ossh_cache_var=no" - LDFLAGS="$saved_LDFLAGS" - else - dnl If we are compiling natively, try running the program. - AC_RUN_IFELSE([OSSH_COMPILER_FLAG_TEST_PROGRAM], -- [ AC_MSG_RESULT([yes]) -+ [ eval "$ossh_cache_var=yes" - LDFLAGS="$saved_LDFLAGS $_define_flag" ], -- [ AC_MSG_RESULT([no, fails at run time]) -+ [ eval "$ossh_cache_var='no, fails at run time'" - LDFLAGS="$saved_LDFLAGS" ], -- [ AC_MSG_RESULT([yes]) -+ [ eval "$ossh_cache_var=yes" - LDFLAGS="$saved_LDFLAGS $_define_flag" ] - ) - fi ], -- [ AC_MSG_RESULT([no]) -+ [ eval "$ossh_cache_var=no" - LDFLAGS="$saved_LDFLAGS" ] - ) -+ ]) - }]) - - dnl OSSH_CHECK_HEADER_FOR_FIELD(field, header, symbol) diff --git a/debian/patches/debian-banner.patch b/debian/patches/debian-banner.patch index dd604f8..816dfca 100644 --- a/debian/patches/debian-banner.patch +++ b/debian/patches/debian-banner.patch @@ -1,4 +1,4 @@ -From acf273b1eb60544826e13ffbd9967772c4f13e13 Mon Sep 17 00:00:00 2001 +From d4774f747a113dabaaaec12e001afc71bdf65161 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Sun, 9 Feb 2014 16:10:06 +0000 Subject: Add DebianBanner server configuration option @@ -8,7 +8,7 @@ initial protocol handshake, for those scared by package-versioning.patch. Bug-Debian: http://bugs.debian.org/562048 Forwarded: not-needed -Last-Update: 2024-09-22 +Last-Update: 2025-04-11 Patch-Name: debian-banner.patch --- @@ -22,10 +22,10 @@ Patch-Name: debian-banner.patch 7 files changed, 23 insertions(+), 5 deletions(-) diff --git a/kex.c b/kex.c -index 19b1fcaa8..ca6d5b53d 100644 +index a19303633..0df4f2f3f 100644 --- a/kex.c +++ b/kex.c -@@ -1237,7 +1237,7 @@ send_error(struct ssh *ssh, char *msg) +@@ -1236,7 +1236,7 @@ send_error(struct ssh *ssh, char *msg) */ int kex_exchange_identification(struct ssh *ssh, int timeout_ms, @@ -34,7 +34,7 @@ index 19b1fcaa8..ca6d5b53d 100644 { int remote_major, remote_minor, mismatch, oerrno = 0; size_t len, n; -@@ -1255,7 +1255,8 @@ kex_exchange_identification(struct ssh *ssh, int timeout_ms, +@@ -1254,7 +1254,8 @@ kex_exchange_identification(struct ssh *ssh, int timeout_ms, if (version_addendum != NULL && *version_addendum == '\0') version_addendum = NULL; if ((r = sshbuf_putf(our_version, "SSH-%d.%d-%s%s%s\r\n", @@ -45,10 +45,10 @@ index 19b1fcaa8..ca6d5b53d 100644 version_addendum == NULL ? "" : version_addendum)) != 0) { oerrno = errno; diff --git a/kex.h b/kex.h -index cd6a40333..6a08023d0 100644 +index 56ad54c41..c7b254d0c 100644 --- a/kex.h +++ b/kex.h -@@ -215,7 +215,7 @@ void kex_proposal_populate_entries(struct ssh *, char *prop[PROPOSAL_MAX], +@@ -220,7 +220,7 @@ void kex_proposal_populate_entries(struct ssh *, char *prop[PROPOSAL_MAX], const char *, const char *, const char *, const char *, const char *); void kex_proposal_free_entries(char *prop[PROPOSAL_MAX]); @@ -58,19 +58,19 @@ index cd6a40333..6a08023d0 100644 struct kex *kex_new(void); int kex_ready(struct ssh *, char *[PROPOSAL_MAX]); diff --git a/servconf.c b/servconf.c -index 1d5c143ba..49a066df8 100644 +index a7a4a0098..b0ea7ceb1 100644 --- a/servconf.c +++ b/servconf.c @@ -219,6 +219,7 @@ initialize_server_options(ServerOptions *options) - options->unused_connection_timeout = -1; options->sshd_session_path = NULL; + options->sshd_auth_path = NULL; options->refuse_connection = -1; + options->debian_banner = -1; } /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */ -@@ -507,6 +508,8 @@ fill_default_server_options(ServerOptions *options) - options->sshd_session_path = xstrdup(_PATH_SSHD_SESSION); +@@ -505,6 +506,8 @@ fill_default_server_options(ServerOptions *options) + options->sshd_auth_path = xstrdup(_PATH_SSHD_AUTH); if (options->refuse_connection == -1) options->refuse_connection = 0; + if (options->debian_banner == -1) @@ -78,23 +78,23 @@ index 1d5c143ba..49a066df8 100644 assemble_algorithms(options); -@@ -591,6 +594,7 @@ typedef enum { +@@ -589,6 +592,7 @@ typedef enum { sExposeAuthInfo, sRDomain, sPubkeyAuthOptions, sSecurityKeyProvider, sRequiredRSASize, sChannelTimeout, sUnusedConnectionTimeout, - sSshdSessionPath, sRefuseConnection, + sSshdSessionPath, sSshdAuthPath, sRefuseConnection, + sDebianBanner, sDeprecated, sIgnore, sUnsupported } ServerOpCodes; -@@ -770,6 +774,7 @@ static struct { - { "unusedconnectiontimeout", sUnusedConnectionTimeout, SSHCFG_ALL }, +@@ -769,6 +773,7 @@ static struct { { "sshdsessionpath", sSshdSessionPath, SSHCFG_GLOBAL }, + { "sshdauthpath", sSshdAuthPath, SSHCFG_GLOBAL }, { "refuseconnection", sRefuseConnection, SSHCFG_ALL }, + { "debianbanner", sDebianBanner, SSHCFG_GLOBAL }, { NULL, sBadOption, 0 } }; -@@ -2725,6 +2730,10 @@ process_server_config_line_depth(ServerOptions *options, char *line, +@@ -2775,6 +2780,10 @@ process_server_config_line_depth(ServerOptions *options, char *line, multistate_ptr = multistate_flag; goto parse_multistate; @@ -105,7 +105,7 @@ index 1d5c143ba..49a066df8 100644 case sDeprecated: case sIgnore: case sUnsupported: -@@ -3278,6 +3287,7 @@ dump_config(ServerOptions *o) +@@ -3330,6 +3339,7 @@ dump_config(ServerOptions *o) dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash); dump_cfg_fmtint(sExposeAuthInfo, o->expose_userauth_info); dump_cfg_fmtint(sRefuseConnection, o->refuse_connection); @@ -114,11 +114,11 @@ index 1d5c143ba..49a066df8 100644 /* string arguments */ dump_cfg_string(sPidFile, o->pid_file); diff --git a/servconf.h b/servconf.h -index 26819aa92..00c834403 100644 +index c3f501400..b510992e3 100644 --- a/servconf.h +++ b/servconf.h -@@ -254,6 +254,8 @@ typedef struct { - char *sshd_session_path; +@@ -255,6 +255,8 @@ typedef struct { + char *sshd_auth_path; int refuse_connection; + @@ -127,23 +127,23 @@ index 26819aa92..00c834403 100644 /* Information about the incoming connection as used by Match */ diff --git a/sshconnect.c b/sshconnect.c -index cbfc20735..f9d3a1ff2 100644 +index b125d9202..dc3b7b4b8 100644 --- a/sshconnect.c +++ b/sshconnect.c -@@ -1611,7 +1611,7 @@ ssh_login(struct ssh *ssh, Sensitive *sensitive, const char *orighost, +@@ -1612,7 +1612,7 @@ ssh_login(struct ssh *ssh, Sensitive *sensitive, const char *orighost, lowercase(host); /* Exchange protocol version identification strings with the server. */ -- if ((r = kex_exchange_identification(ssh, timeout_ms, NULL)) != 0) -+ if ((r = kex_exchange_identification(ssh, timeout_ms, 1, NULL)) != 0) +- if ((r = kex_exchange_identification(ssh, timeout_ms, ++ if ((r = kex_exchange_identification(ssh, timeout_ms, 1, + options.version_addendum)) != 0) sshpkt_fatal(ssh, r, "banner exchange"); - /* Put the connection into non-blocking mode. */ diff --git a/sshd-session.c b/sshd-session.c -index 1d7cdd00a..a9e1cf4f6 100644 +index 307088717..2de08287f 100644 --- a/sshd-session.c +++ b/sshd-session.c -@@ -1314,7 +1314,7 @@ main(int ac, char **av) +@@ -1273,7 +1273,7 @@ main(int ac, char **av) fatal("login grace time setitimer failed"); } @@ -153,7 +153,7 @@ index 1d7cdd00a..a9e1cf4f6 100644 sshpkt_fatal(ssh, r, "banner exchange"); diff --git a/sshd_config.5 b/sshd_config.5 -index 11a8e922f..ed2f74060 100644 +index ceaeddc9d..d7b60308a 100644 --- a/sshd_config.5 +++ b/sshd_config.5 @@ -629,6 +629,11 @@ or diff --git a/debian/patches/debian-config.patch b/debian/patches/debian-config.patch index 5d18b45..0ce5f20 100644 --- a/debian/patches/debian-config.patch +++ b/debian/patches/debian-config.patch @@ -1,4 +1,4 @@ -From bcafde3235b00794b6d7ee62b8687a786aa08d4f Mon Sep 17 00:00:00 2001 +From 757a376cd0e12c19e9fc5772f506431803be717f Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Sun, 9 Feb 2014 16:10:18 +0000 Subject: Various Debian-specific configuration changes @@ -6,7 +6,8 @@ Subject: Various Debian-specific configuration changes ssh: Enable ForwardX11Trusted, returning to earlier semantics which cause fewer problems with existing setups (http://bugs.debian.org/237021). -ssh: Set 'SendEnv LANG LC_*' by default (http://bugs.debian.org/264024). +ssh: Set 'SendEnv LANG LC_* COLORTERM NO_COLOR' by default +(http://bugs.debian.org/264024). ssh: Enable HashKnownHosts by default to try to limit the spread of ssh worms. @@ -20,21 +21,22 @@ PrintMotd. sshd: Enable X11Forwarding. -sshd: Set 'AcceptEnv LANG LC_*' by default. +sshd: Set 'AcceptEnv LANG LC_* COLORTERM NO_COLOR' by default. sshd: Change sftp subsystem path to /usr/lib/openssh/sftp-server. sshd: Include /etc/ssh/sshd_config.d/*.conf. -sshd: Document Debian's default for SshdSessionPath. +sshd: Document Debian's defaults for SshdAuthPath and SshdSessionPath. regress: Run tests with 'UsePAM yes', to match sshd_config. Document all of this. Author: Russ Allbery +Author: Luca Boccassi Forwarded: not-needed -Last-Update: 2024-07-03 +Last-Update: 2025-04-11 Patch-Name: debian-config.patch --- @@ -44,14 +46,14 @@ Patch-Name: debian-config.patch ssh_config | 8 +++++++- ssh_config.5 | 26 +++++++++++++++++++++++++- sshd_config | 18 ++++++++++++------ - sshd_config.5 | 31 ++++++++++++++++++++++++++++++- - 7 files changed, 100 insertions(+), 10 deletions(-) + sshd_config.5 | 33 +++++++++++++++++++++++++++++++-- + 7 files changed, 101 insertions(+), 11 deletions(-) diff --git a/readconf.c b/readconf.c -index d3c3056ef..90bf74f32 100644 +index c568697cf..82a91cc30 100644 --- a/readconf.c +++ b/readconf.c -@@ -2773,7 +2773,7 @@ fill_default_options(Options * options) +@@ -2897,7 +2897,7 @@ fill_default_options(Options * options) if (options->forward_x11 == -1) options->forward_x11 = 0; if (options->forward_x11_trusted == -1) @@ -61,22 +63,22 @@ index d3c3056ef..90bf74f32 100644 options->forward_x11_timeout = 1200; /* diff --git a/regress/test-exec.sh b/regress/test-exec.sh -index 7afc28072..02b122a85 100644 +index 34fb58fda..a1db94af1 100644 --- a/regress/test-exec.sh +++ b/regress/test-exec.sh @@ -622,6 +622,7 @@ cat << EOF > $OBJ/sshd_config - Subsystem sftp $SFTPSERVER SshdSessionPath $SSHD_SESSION + SshdAuthPath $SSHD_AUTH PerSourcePenalties no + UsePAM yes EOF # This may be necessary if /usr/src and/or /usr/obj are group-writable, diff --git a/ssh.1 b/ssh.1 -index 3ad246c27..9ca6e18e2 100644 +index 3d849f02c..56bdfa3d9 100644 --- a/ssh.1 +++ b/ssh.1 -@@ -863,6 +863,16 @@ directive in +@@ -873,6 +873,16 @@ directive in .Xr ssh_config 5 for more information. .Pp @@ -93,7 +95,7 @@ index 3ad246c27..9ca6e18e2 100644 .It Fl x Disables X11 forwarding. .Pp -@@ -871,6 +881,20 @@ Enables trusted X11 forwarding. +@@ -881,6 +891,20 @@ Enables trusted X11 forwarding. Trusted X11 forwardings are not subjected to the X11 SECURITY extension controls. .Pp @@ -115,7 +117,7 @@ index 3ad246c27..9ca6e18e2 100644 Send log information using the .Xr syslog 3 diff --git a/ssh_config b/ssh_config -index 16197d15d..92d06ef38 100644 +index 3ae9025ff..1c528ea65 100644 --- a/ssh_config +++ b/ssh_config @@ -17,9 +17,12 @@ @@ -132,15 +134,15 @@ index 16197d15d..92d06ef38 100644 # PasswordAuthentication yes # HostbasedAuthentication no # GSSAPIAuthentication no -@@ -46,3 +49,6 @@ +@@ -45,3 +48,6 @@ # ProxyCommand ssh -q -W %h:%p gateway.example.com # RekeyLimit 1G 1h # UserKnownHostsFile ~/.ssh/known_hosts.d/%k -+ SendEnv LANG LC_* ++ SendEnv LANG LC_* COLORTERM NO_COLOR + HashKnownHosts yes + GSSAPIAuthentication yes diff --git a/ssh_config.5 b/ssh_config.5 -index 86258eb4f..9adc0fdb7 100644 +index 9e3ebac9b..20fee59fb 100644 --- a/ssh_config.5 +++ b/ssh_config.5 @@ -71,6 +71,29 @@ Since the first obtained value for each parameter is used, more @@ -158,7 +160,7 @@ index 86258eb4f..9adc0fdb7 100644 +.It +.Cm Include /etc/ssh/ssh_config.d/*.conf +.It -+.Cm SendEnv No LANG LC_* ++.Cm SendEnv No LANG LC_* COLORTERM NO_COLOR +.It +.Cm HashKnownHosts No yes +.It @@ -173,7 +175,7 @@ index 86258eb4f..9adc0fdb7 100644 The file contains keyword-argument pairs, one per line. Lines starting with .Ql # -@@ -903,11 +926,12 @@ elapsed. +@@ -941,11 +964,12 @@ elapsed. .It Cm ForwardX11Trusted If this option is set to .Cm yes , @@ -188,7 +190,7 @@ index 86258eb4f..9adc0fdb7 100644 from stealing or tampering with data belonging to trusted X11 clients. diff --git a/sshd_config b/sshd_config -index ecfe8d026..677f97d5d 100644 +index 6ddae0370..01e8d9098 100644 --- a/sshd_config +++ b/sshd_config @@ -10,6 +10,8 @@ @@ -200,19 +202,21 @@ index ecfe8d026..677f97d5d 100644 #Port 22 #AddressFamily any #ListenAddress 0.0.0.0 -@@ -57,8 +59,9 @@ AuthorizedKeysFile .ssh/authorized_keys +@@ -57,10 +59,11 @@ AuthorizedKeysFile .ssh/authorized_keys #PasswordAuthentication yes #PermitEmptyPasswords no --# Change to no to disable s/key passwords +-# Change to "no" to disable keyboard-interactive authentication. Depending on ++# Change to "yes" to enable keyboard-interactive authentication. Depending on + # the system's configuration, this may involve passwords, challenge-response, + # one-time passwords or some combination of these and other methods. -#KbdInteractiveAuthentication yes -+# Change to yes to enable challenge-response passwords (beware issues with -+# some PAM modules and threads) ++# Beware issues with some PAM modules and threads. +KbdInteractiveAuthentication no # Kerberos options #KerberosAuthentication no -@@ -81,16 +84,16 @@ AuthorizedKeysFile .ssh/authorized_keys +@@ -83,16 +86,16 @@ AuthorizedKeysFile .ssh/authorized_keys # 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'. @@ -232,12 +236,12 @@ index ecfe8d026..677f97d5d 100644 #PrintLastLog yes #TCPKeepAlive yes #PermitUserEnvironment no -@@ -107,8 +110,11 @@ AuthorizedKeysFile .ssh/authorized_keys +@@ -109,8 +112,11 @@ AuthorizedKeysFile .ssh/authorized_keys # no default banner path #Banner none -+# Allow client to pass locale environment variables -+AcceptEnv LANG LC_* ++# Allow client to pass locale and color environment variables ++AcceptEnv LANG LC_* COLORTERM NO_COLOR + # override default of no subsystems -Subsystem sftp /usr/libexec/sftp-server @@ -246,7 +250,7 @@ index ecfe8d026..677f97d5d 100644 # Example of overriding settings on a per-user basis #Match User anoncvs diff --git a/sshd_config.5 b/sshd_config.5 -index e177e4af8..2887ed531 100644 +index c8b364139..40728dfaf 100644 --- a/sshd_config.5 +++ b/sshd_config.5 @@ -56,6 +56,35 @@ Arguments may optionally be enclosed in double quotes @@ -270,7 +274,7 @@ index e177e4af8..2887ed531 100644 +.It +.Cm PrintMotd No no +.It -+.Cm AcceptEnv No LANG LC_* ++.Cm AcceptEnv No LANG LC_* COLORTERM NO_COLOR +.It +.Cm Subsystem No sftp /usr/lib/openssh/sftp-server +.It @@ -285,7 +289,15 @@ index e177e4af8..2887ed531 100644 The possible keywords and their meanings are as follows (note that keywords are case-insensitive and arguments are case-sensitive): -@@ -1865,7 +1894,7 @@ Overrides the default path to the +@@ -1888,14 +1917,14 @@ Overrides the default path to the + .Cm sshd-auth + binary that is invoked to complete user authentication. + The default is +-.Pa /usr/libexec/sshd-auth . ++.Pa /usr/lib/openssh/sshd-auth . + This option is intended for use by tests. + .It Cm SshdSessionPath + Overrides the default path to the .Cm sshd-session binary that is invoked to handle each connection. The default is diff --git a/debian/patches/deepin-extra-version.patch b/debian/patches/deepin-extra-version.patch deleted file mode 100644 index 6d57d4e..0000000 --- a/debian/patches/deepin-extra-version.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/version.h -+++ b/version.h -@@ -5,7 +5,7 @@ - #define SSH_PORTABLE "p2" - #define SSH_RELEASE_MINIMUM SSH_VERSION SSH_PORTABLE - #ifdef SSH_EXTRAVERSION --#define SSH_RELEASE SSH_RELEASE_MINIMUM " " SSH_EXTRAVERSION -+#define SSH_RELEASE SSH_RELEASE_MINIMUM " " "Deepin" - #else - #define SSH_RELEASE SSH_RELEASE_MINIMUM - #endif diff --git a/debian/patches/deepin-ssh-connect-idle-timeout.patch b/debian/patches/deepin-ssh-connect-idle-timeout.patch deleted file mode 100644 index 08ea714..0000000 --- a/debian/patches/deepin-ssh-connect-idle-timeout.patch +++ /dev/null @@ -1,20 +0,0 @@ -Description: 完成 ssh、tty登录超时自动退出需求实现 - 增加sshd默认配置项,ssh连接之后900秒无操作,自动退出 - -Origin: https://gerrit.uniontech.com/plugins/gitiles/base/openssh/+/202f13d0e50e7d3fe478ad39be7c59ab3ed30b52 -Task: https://pms.uniontech.com/zentao/task-view-60279.html -Last-Update: 2022-05-19 - ---- openssh-9.0p1.orig/sshd_config -+++ openssh-9.0p1/sshd_config -@@ -97,8 +97,8 @@ PrintMotd no - #TCPKeepAlive yes - #PermitUserEnvironment no - #Compression delayed --#ClientAliveInterval 0 --#ClientAliveCountMax 3 -+# set inactive timeout for shell & subsystem connections -+ChannelTimeout session:shell=900 session:subsystem*=900 - #UseDNS no - #PidFile /var/run/sshd.pid - #MaxStartups 10:30:100 diff --git a/debian/patches/deepin-ssh-keygen-privatekey-file-perm.patch b/debian/patches/deepin-ssh-keygen-privatekey-file-perm.patch deleted file mode 100644 index 635829e..0000000 --- a/debian/patches/deepin-ssh-keygen-privatekey-file-perm.patch +++ /dev/null @@ -1,18 +0,0 @@ -Description: - TODO: Put a short summary on the line above and replace this paragraph - -Origin: https://gerrit.uniontech.com/plugins/gitiles/base/openssh/+/1aaa80cba01428f8738878a826db83fd1aeed6c4 -Task: https://pms.uniontech.com/zentao/task-view-60275.html -Last-Update: 2022-05-20 - ---- openssh-9.0p1.orig/sshbuf-io.c -+++ openssh-9.0p1/sshbuf-io.c -@@ -102,7 +102,7 @@ sshbuf_write_file(const char *path, stru - { - int fd, oerrno; - -- if ((fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644)) == -1) -+ if ((fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0400)) == -1) - return SSH_ERR_SYSTEM_ERROR; - if (atomicio(vwrite, fd, sshbuf_mutable_ptr(buf), - sshbuf_len(buf)) != sshbuf_len(buf) || close(fd) != 0) { diff --git a/debian/patches/dnssec-sshfp.patch b/debian/patches/dnssec-sshfp.patch index ad695cc..bd227ad 100644 --- a/debian/patches/dnssec-sshfp.patch +++ b/debian/patches/dnssec-sshfp.patch @@ -1,4 +1,4 @@ -From d4727dbc1b6618e4087fd35f15adee1a971cc92c Mon Sep 17 00:00:00 2001 +From d8b36e7b6b84d21d74dd4c65fe796266b45c5018 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Sun, 9 Feb 2014 16:10:01 +0000 Subject: Force use of DNSSEC even if "options edns0" isn't in resolv.conf @@ -18,10 +18,10 @@ Patch-Name: dnssec-sshfp.patch 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/dns.c b/dns.c -index 939241440..bf47a079f 100644 +index e8693cee8..36ab1a677 100644 --- a/dns.c +++ b/dns.c -@@ -198,6 +198,7 @@ verify_host_key_dns(const char *hostname, struct sockaddr *address, +@@ -192,6 +192,7 @@ verify_host_key_dns(const char *hostname, struct sockaddr *address, { u_int counter; int result; @@ -29,7 +29,7 @@ index 939241440..bf47a079f 100644 struct rrsetinfo *fingerprints = NULL; u_int8_t hostkey_algorithm; -@@ -220,8 +221,19 @@ verify_host_key_dns(const char *hostname, struct sockaddr *address, +@@ -214,8 +215,19 @@ verify_host_key_dns(const char *hostname, struct sockaddr *address, return -1; } diff --git a/debian/patches/doc-hash-tab-completion.patch b/debian/patches/doc-hash-tab-completion.patch index 900d1b1..e049e28 100644 --- a/debian/patches/doc-hash-tab-completion.patch +++ b/debian/patches/doc-hash-tab-completion.patch @@ -1,4 +1,4 @@ -From e0f5ef4ccd951f2c8dc30639019c2e45451389c3 Mon Sep 17 00:00:00 2001 +From 8a48608d75dd6625d4001a89daaa601993a29dd6 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Sun, 9 Feb 2014 16:10:11 +0000 Subject: Document that HashKnownHosts may break tab-completion @@ -13,10 +13,10 @@ Patch-Name: doc-hash-tab-completion.patch 1 file changed, 3 insertions(+) diff --git a/ssh_config.5 b/ssh_config.5 -index 073ef69e2..86258eb4f 100644 +index c947aba0a..9e3ebac9b 100644 --- a/ssh_config.5 +++ b/ssh_config.5 -@@ -1022,6 +1022,9 @@ Note that existing names and addresses in known hosts files +@@ -1060,6 +1060,9 @@ 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 . diff --git a/debian/patches/downgrade-pkcs11-error.patch b/debian/patches/downgrade-pkcs11-error.patch new file mode 100644 index 0000000..ebe52d2 --- /dev/null +++ b/debian/patches/downgrade-pkcs11-error.patch @@ -0,0 +1,43 @@ +From 8b4743d817c93570ddddff9d98e61e9067a87aef Mon Sep 17 00:00:00 2001 +From: "djm@openbsd.org" +Date: Thu, 9 Oct 2025 23:25:23 +0000 +Subject: upstream: downgrade a useless error() -> debug() + +OpenBSD-Commit-ID: 5b0c9bcddb324f8bed2c8e8ffe9c92d263adc2d9 + +Origin: https://anongit.mindrot.org/openssh.git/commit/?h=V_10_2&id=607f337637f2077b34a9f6f96fc24237255fe175 +Last-Update: 2025-10-17 + +Patch-Name: downgrade-pkcs11-error.patch +--- + ssh-pkcs11.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/ssh-pkcs11.c b/ssh-pkcs11.c +index c88179473..5e956208b 100644 +--- a/ssh-pkcs11.c ++++ b/ssh-pkcs11.c +@@ -1,4 +1,4 @@ +-/* $OpenBSD: ssh-pkcs11.c,v 1.73 2025/10/08 21:02:16 djm Exp $ */ ++/* $OpenBSD: ssh-pkcs11.c,v 1.74 2025/10/09 23:25:23 djm Exp $ */ + /* + * Copyright (c) 2010 Markus Friedl. All rights reserved. + * Copyright (c) 2014 Pedro Martelletto. All rights reserved. +@@ -1486,7 +1486,7 @@ pkcs11_fetch_certs(struct pkcs11_provider *p, CK_ULONG slotidx, + case CKC_X_509: + if (pkcs11_fetch_x509_pubkey(p, slotidx, &obj, + &key, &label) != 0) { +- error("failed to fetch key"); ++ debug_f("failed to fetch key"); + continue; + } + break; +@@ -1613,7 +1613,7 @@ pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, + } + + if (key == NULL) { +- error("failed to fetch key"); ++ debug_f("failed to fetch key"); + continue; + } + note_key(p, slotidx, __func__, key); diff --git a/debian/patches/gnome-ssh-askpass2-icon.patch b/debian/patches/gnome-ssh-askpass2-icon.patch index bca17af..f1a88db 100644 --- a/debian/patches/gnome-ssh-askpass2-icon.patch +++ b/debian/patches/gnome-ssh-askpass2-icon.patch @@ -1,4 +1,4 @@ -From 8542c03bc3d4325d9e8b03c7fb0340ff743e70e1 Mon Sep 17 00:00:00 2001 +From 8f3f3b0e449c85fa544fe562b6d1bdb147ab8b96 Mon Sep 17 00:00:00 2001 From: Vincent Untz Date: Sun, 9 Feb 2014 16:10:16 +0000 Subject: Give the ssh-askpass-gnome window a default icon diff --git a/debian/patches/gssapi.patch b/debian/patches/gssapi.patch index 9fae3b1..0037682 100644 --- a/debian/patches/gssapi.patch +++ b/debian/patches/gssapi.patch @@ -1,4 +1,4 @@ -From 160d97105023e620b623f2f337327aa820bd0e5a Mon Sep 17 00:00:00 2001 +From 13a4a4e22141677c78ab05960d7eb0d014e11f4e Mon Sep 17 00:00:00 2001 From: Simon Wilkinson Date: Sun, 9 Feb 2014 16:09:48 +0000 Subject: GSSAPI key exchange support @@ -21,11 +21,11 @@ Author: Colin Watson Author: Jakub Jelen Origin: other, https://github.com/openssh-gsskex/openssh-gsskex/pull/23 Bug: https://bugzilla.mindrot.org/show_bug.cgi?id=1242 -Last-Updated: 2024-10-14 +Last-Updated: 2025-10-06 Patch-Name: gssapi.patch --- - Makefile.in | 6 +- + Makefile.in | 8 +- README.md | 36 +++ auth.c | 3 +- auth2-gss.c | 54 ++++- @@ -35,7 +35,7 @@ Patch-Name: gssapi.patch configure.ac | 24 ++ gss-genr.c | 297 +++++++++++++++++++++++- gss-serv-krb5.c | 87 ++++++- - gss-serv.c | 200 ++++++++++++++-- + gss-serv.c | 202 ++++++++++++++-- kex-names.c | 62 ++++- kex.c | 4 + kex.h | 29 +++ @@ -49,7 +49,7 @@ Patch-Name: gssapi.patch monitor_wrap.h | 4 +- readconf.c | 74 ++++++ readconf.h | 6 + - servconf.c | 47 ++++ + servconf.c | 46 ++++ servconf.h | 3 + session.c | 10 +- ssh-gss.h | 54 ++++- @@ -59,29 +59,30 @@ Patch-Name: gssapi.patch ssh_config | 2 + ssh_config.5 | 57 +++++ sshconnect2.c | 148 +++++++++++- - sshd-session.c | 59 ++++- + sshd-auth.c | 53 +++++ + sshd-session.c | 4 +- sshd.c | 3 +- sshd_config | 2 + sshd_config.5 | 30 +++ sshkey.c | 8 +- sshkey.h | 1 + - 40 files changed, 2670 insertions(+), 73 deletions(-) + 41 files changed, 2670 insertions(+), 74 deletions(-) create mode 100644 kexgssc.c create mode 100644 kexgsss.c create mode 100644 ssh-null.c diff --git a/Makefile.in b/Makefile.in -index 4243006b0..e92bf3e31 100644 +index ba17a79f0..6d453e859 100644 --- a/Makefile.in +++ b/Makefile.in -@@ -103,14 +103,14 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ +@@ -97,14 +97,14 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ 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 \ + monitor_fdpass.o rijndael.o ssh-ecdsa.o ssh-ecdsa-sk.o \ - ssh-ed25519-sk.o ssh-rsa.o dh.o \ + ssh-ed25519-sk.o ssh-rsa.o ssh-null.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 \ + msg.o dns.o entropy.o gss-genr.o umac.o umac128.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 ed25519.o hash.o \ @@ -90,8 +91,8 @@ index 4243006b0..e92bf3e31 100644 + kexgexc.o kexgexs.o kexgssc.o \ kexsntrup761x25519.o kexmlkem768x25519.o sntrup761.o kexgen.o \ sftp-realpath.o platform-pledge.o platform-tracing.o platform-misc.o \ - sshbuf-io.o -@@ -134,7 +134,7 @@ SSHD_SESSION_OBJS=sshd-session.o auth-rhosts.o auth-passwd.o \ + sshbuf-io.o misc-agent.o +@@ -130,7 +130,7 @@ SSHD_SESSION_OBJS=sshd-session.o auth-rhosts.o auth-passwd.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 \ @@ -99,9 +100,18 @@ index 4243006b0..e92bf3e31 100644 + auth2-gss.o gss-serv.o gss-serv-krb5.o kexgsss.o \ loginrec.o auth-pam.o auth-shadow.o auth-sia.o \ sftp-server.o sftp-common.o \ - sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ + uidswap.o platform-listen.o $(P11OBJS) $(SKOBJS) +@@ -141,7 +141,7 @@ SSHD_AUTH_OBJS=sshd-auth.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 \ +- auth2-gss.o gss-serv.o gss-serv-krb5.o \ ++ auth2-gss.o gss-serv.o gss-serv-krb5.o kexgsss.o \ + monitor_wrap.o auth-krb5.o \ + audit.o audit-bsm.o audit-linux.o platform.o \ + loginrec.o auth-pam.o auth-shadow.o auth-sia.o \ diff --git a/README.md b/README.md -index 9431b0ffd..e5051828c 100644 +index 2ad647138..371081e1a 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,39 @@ @@ -145,10 +155,10 @@ index 9431b0ffd..e5051828c 100644 [![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) diff --git a/auth.c b/auth.c -index 9a6e5a319..e4578169b 100644 +index 8d9404743..d25653ee4 100644 --- a/auth.c +++ b/auth.c -@@ -356,7 +356,8 @@ auth_root_allowed(struct ssh *ssh, const char *method) +@@ -354,7 +354,8 @@ auth_root_allowed(struct ssh *ssh, const char *method) case PERMIT_NO_PASSWD: if (strcmp(method, "publickey") == 0 || strcmp(method, "hostbased") == 0 || @@ -283,7 +293,7 @@ index 99637a89b..a05908cf3 100644 #endif &methodcfg_passwd, diff --git a/auth2.c b/auth2.c -index 67dec88c3..f75f1d20d 100644 +index b9bb46f59..03a126ba4 100644 --- a/auth2.c +++ b/auth2.c @@ -71,6 +71,7 @@ extern Authmethod method_passwd; @@ -303,10 +313,10 @@ index 67dec88c3..f75f1d20d 100644 #endif &method_passwd, diff --git a/clientloop.c b/clientloop.c -index 8ed8b1c34..6d57339a1 100644 +index 49d048d85..dcad9ec6b 100644 --- a/clientloop.c +++ b/clientloop.c -@@ -115,6 +115,10 @@ +@@ -107,6 +107,10 @@ #include "ssherr.h" #include "hostfile.h" @@ -317,7 +327,7 @@ index 8ed8b1c34..6d57339a1 100644 /* Permitted RSA signature algorithms for UpdateHostkeys proofs */ #define HOSTKEY_PROOF_RSA_ALGS "rsa-sha2-512,rsa-sha2-256" -@@ -1590,6 +1594,15 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg, +@@ -1604,6 +1608,15 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg, /* Do channel operations. */ channel_after_poll(ssh, pfd, npfd_active); @@ -334,10 +344,10 @@ index 8ed8b1c34..6d57339a1 100644 if (conn_in_ready) client_process_net_input(ssh); diff --git a/configure.ac b/configure.ac -index 591d5a388..6a0140a9d 100644 +index db5211013..53112bdac 100644 --- a/configure.ac +++ b/configure.ac -@@ -774,6 +774,30 @@ int main(void) { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) +@@ -813,6 +813,30 @@ int main(void) { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) [Use tunnel device compatibility to OpenBSD]) AC_DEFINE([SSH_TUN_PREPEND_AF], [1], [Prepend the address family to IP tunnel traffic]) @@ -369,11 +379,11 @@ index 591d5a388..6a0140a9d 100644 AC_CHECK_DECL([AU_IPv4], [], AC_DEFINE([AU_IPv4], [0], [System only supports IPv4 audit records]) diff --git a/gss-genr.c b/gss-genr.c -index aa34b71c5..3aa14333a 100644 +index 8f1f54afb..32fc395a5 100644 --- a/gss-genr.c +++ b/gss-genr.c @@ -1,7 +1,7 @@ - /* $OpenBSD: gss-genr.c,v 1.29 2024/02/01 02:37:33 djm Exp $ */ + /* $OpenBSD: gss-genr.c,v 1.30 2025/09/29 21:28:33 dtucker Exp $ */ /* - * Copyright (c) 2001-2007 Simon Wilkinson. All rights reserved. @@ -876,11 +886,11 @@ index a151bc1e4..ef20401ec 100644 #endif /* KRB5 */ diff --git a/gss-serv.c b/gss-serv.c -index 00e3d118b..b761d12aa 100644 +index b0e9c3b49..6bac42931 100644 --- a/gss-serv.c +++ b/gss-serv.c @@ -1,7 +1,7 @@ - /* $OpenBSD: gss-serv.c,v 1.32 2020/03/13 03:17:07 djm Exp $ */ + /* $OpenBSD: gss-serv.c,v 1.33 2025/09/29 21:30:15 dtucker Exp $ */ /* - * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. @@ -888,7 +898,7 @@ index 00e3d118b..b761d12aa 100644 * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions -@@ -44,17 +44,19 @@ +@@ -45,17 +45,19 @@ #include "session.h" #include "misc.h" #include "servconf.h" @@ -911,7 +921,7 @@ index 00e3d118b..b761d12aa 100644 #ifdef KRB5 extern ssh_gssapi_mech gssapi_kerberos_mech; -@@ -140,6 +142,29 @@ ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID oid) +@@ -141,6 +143,29 @@ ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID oid) return (ssh_gssapi_acquire_cred(*ctx)); } @@ -941,7 +951,7 @@ index 00e3d118b..b761d12aa 100644 /* Unprivileged */ void ssh_gssapi_supported_oids(gss_OID_set *oidset) -@@ -150,7 +175,9 @@ ssh_gssapi_supported_oids(gss_OID_set *oidset) +@@ -151,7 +176,9 @@ ssh_gssapi_supported_oids(gss_OID_set *oidset) gss_OID_set supported; gss_create_empty_oid_set(&min_status, oidset); @@ -952,14 +962,15 @@ index 00e3d118b..b761d12aa 100644 while (supported_mechs[i]->name != NULL) { if (GSS_ERROR(gss_test_oid_set_member(&min_status, -@@ -276,8 +303,48 @@ OM_uint32 +@@ -277,8 +304,48 @@ OM_uint32 ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) { int i = 0; + int equal = 0; + gss_name_t new_name = GSS_C_NO_NAME; + gss_buffer_desc ename = GSS_C_EMPTY_BUFFER; -+ + +- gss_buffer_desc ename; + if (options.gss_store_rekey && client->used && ctx->client_creds) { + if (client->mech->oid.length != ctx->oid->length || + (memcmp(client->mech->oid.elements, @@ -967,8 +978,7 @@ index 00e3d118b..b761d12aa 100644 + debug("Rekeyed credentials have different mechanism"); + return GSS_S_COMPLETE; + } - -- gss_buffer_desc ename; ++ + if ((ctx->major = gss_inquire_cred_by_mech(&ctx->minor, + ctx->client_creds, ctx->oid, &new_name, + NULL, NULL, NULL))) { @@ -1002,7 +1012,7 @@ index 00e3d118b..b761d12aa 100644 client->mech = NULL; -@@ -292,6 +359,13 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) +@@ -293,6 +360,13 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) if (client->mech == NULL) return GSS_S_FAILURE; @@ -1016,7 +1026,7 @@ index 00e3d118b..b761d12aa 100644 if ((ctx->major = gss_display_name(&ctx->minor, ctx->client, &client->displayname, NULL))) { ssh_gssapi_error(ctx); -@@ -309,6 +383,8 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) +@@ -310,6 +384,8 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) return (ctx->major); } @@ -1025,7 +1035,7 @@ index 00e3d118b..b761d12aa 100644 /* We can't copy this structure, so we just move the pointer to it */ client->creds = ctx->client_creds; ctx->client_creds = GSS_C_NO_CREDENTIAL; -@@ -319,11 +395,20 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) +@@ -320,11 +396,20 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) void ssh_gssapi_cleanup_creds(void) { @@ -1051,7 +1061,7 @@ index 00e3d118b..b761d12aa 100644 } } -@@ -356,19 +441,23 @@ ssh_gssapi_do_child(char ***envp, u_int *envsizep) +@@ -357,19 +442,23 @@ ssh_gssapi_do_child(char ***envp, u_int *envsizep) /* Privileged */ int @@ -1078,13 +1088,16 @@ index 00e3d118b..b761d12aa 100644 /* Destroy delegated credentials if userok fails */ gss_release_buffer(&lmin, &gssapi_client.displayname); gss_release_buffer(&lmin, &gssapi_client.exportedname); -@@ -382,14 +471,85 @@ ssh_gssapi_userok(char *user) +@@ -383,14 +472,85 @@ ssh_gssapi_userok(char *user) return (0); } -/* Privileged */ -OM_uint32 -ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic) +-{ +- ctx->major = gss_verify_mic(&ctx->minor, ctx->context, +- gssbuf, gssmic, NULL); +/* These bits are only used for rekeying. The unpriviledged child is running + * as the user, the monitor is root. + * @@ -1092,20 +1105,18 @@ index 00e3d118b..b761d12aa 100644 + * *) Ask the monitor to store our credentials into the store we specify + * *) If it succeeds, maybe do a PAM update + */ -+ + +- return (ctx->major); +/* Stuff for PAM */ + +#ifdef USE_PAM +static int ssh_gssapi_simple_conv(int n, const struct pam_message **msg, + struct pam_response **resp, void *data) - { -- ctx->major = gss_verify_mic(&ctx->minor, ctx->context, -- gssbuf, gssmic, NULL); ++{ + return (PAM_CONV_ERR); +} +#endif - -- return (ctx->major); ++ +void +ssh_gssapi_rekey_creds(void) { + int ok; @@ -1171,7 +1182,7 @@ index 00e3d118b..b761d12aa 100644 /* Privileged */ diff --git a/kex-names.c b/kex-names.c -index ec840c1f9..081f78c94 100644 +index a20ce602a..bc655e09a 100644 --- a/kex-names.c +++ b/kex-names.c @@ -45,6 +45,10 @@ @@ -1185,9 +1196,9 @@ index ec840c1f9..081f78c94 100644 struct kexalg { char *name; u_int type; -@@ -89,15 +93,28 @@ static const struct kexalg kexalgs[] = { +@@ -90,20 +94,45 @@ static const struct kexalg kexalgs[] = { #endif /* HAVE_EVP_SHA256 || !WITH_OPENSSL */ - { NULL, 0, -1, -1}, + { NULL, 0, -1, -1, 0 }, }; +static const struct kexalg gss_kexalgs[] = { +#ifdef GSSAPI @@ -1208,16 +1219,14 @@ index ec840c1f9..081f78c94 100644 +static char * +kex_alg_list_internal(char sep, const struct kexalg *algs) { - char *ret = NULL, *tmp; - size_t nlen, rlen = 0; + char *ret = NULL; const struct kexalg *k; + char sep_str[2] = {sep, '\0'}; + +- for (k = kexalgs; k->name != NULL; k++) ++ for (k = algs; k->name != NULL; k++) + xextendf(&ret, sep_str, "%s", k->name); -- for (k = kexalgs; k->name != NULL; k++) { -+ for (k = algs; k->name != NULL; k++) { - if (ret != NULL) - ret[rlen++] = sep; - nlen = strlen(k->name); -@@ -112,6 +129,18 @@ kex_alg_list(char sep) return ret; } @@ -1236,7 +1245,7 @@ index ec840c1f9..081f78c94 100644 static const struct kexalg * kex_alg_by_name(const char *name) { -@@ -121,6 +150,10 @@ kex_alg_by_name(const char *name) +@@ -113,6 +142,10 @@ kex_alg_by_name(const char *name) if (strcmp(k->name, name) == 0) return k; } @@ -1247,7 +1256,7 @@ index ec840c1f9..081f78c94 100644 return NULL; } -@@ -183,6 +216,29 @@ kex_names_valid(const char *names) +@@ -185,6 +218,29 @@ kex_names_valid(const char *names) return 1; } @@ -1278,10 +1287,10 @@ index ec840c1f9..081f78c94 100644 int kex_has_any_alg(const char *proposal, const char *algs) diff --git a/kex.c b/kex.c -index 6b957e5e1..f09e79e6b 100644 +index 814fad947..0f68fda32 100644 --- a/kex.c +++ b/kex.c -@@ -58,6 +58,7 @@ +@@ -56,6 +56,7 @@ #include "dispatch.h" #include "monitor.h" #include "myproposal.h" @@ -1289,7 +1298,7 @@ index 6b957e5e1..f09e79e6b 100644 #include "ssherr.h" #include "sshbuf.h" -@@ -739,6 +740,9 @@ kex_free(struct kex *kex) +@@ -737,6 +738,9 @@ kex_free(struct kex *kex) sshbuf_free(kex->session_id); sshbuf_free(kex->initial_sig); sshkey_free(kex->initial_hostkey); @@ -1300,7 +1309,7 @@ index 6b957e5e1..f09e79e6b 100644 free(kex->hostkey_alg); free(kex->name); diff --git a/kex.h b/kex.h -index d08988b3e..cd6a40333 100644 +index 55baa6a1e..56ad54c41 100644 --- a/kex.h +++ b/kex.h @@ -103,6 +103,15 @@ enum kex_exchange { @@ -1319,7 +1328,7 @@ index d08988b3e..cd6a40333 100644 KEX_MAX }; -@@ -165,6 +174,12 @@ struct kex { +@@ -169,6 +178,12 @@ struct kex { u_int flags; int hash_alg; int ec_nid; @@ -1332,9 +1341,9 @@ index d08988b3e..cd6a40333 100644 char *failed_choice; int (*verify_host_key)(struct sshkey *, struct ssh *); struct sshkey *(*load_host_public_key)(int, int, struct ssh *); -@@ -190,7 +205,9 @@ u_int kex_type_from_name(const char *); - int kex_hash_from_name(const char *); +@@ -195,7 +210,9 @@ int kex_hash_from_name(const char *); int kex_nid_from_name(const char *); + int kex_is_pq_from_name(const char *); int kex_names_valid(const char *); +int kex_gss_names_valid(const char *); char *kex_alg_list(char); @@ -1342,7 +1351,7 @@ index d08988b3e..cd6a40333 100644 char *kex_names_cat(const char *, const char *); int kex_has_any_alg(const char *, const char *); int kex_assemble_names(char **, const char *, const char *); -@@ -226,6 +243,12 @@ int kexgex_client(struct ssh *); +@@ -231,6 +248,12 @@ int kexgex_client(struct ssh *); int kexgex_server(struct ssh *); int kex_gen_client(struct ssh *); int kex_gen_server(struct ssh *); @@ -1355,7 +1364,7 @@ index d08988b3e..cd6a40333 100644 int kex_dh_keypair(struct kex *); int kex_dh_enc(struct kex *, const struct sshbuf *, struct sshbuf **, -@@ -264,6 +287,12 @@ int kexgex_hash(int, const struct sshbuf *, const struct sshbuf *, +@@ -269,6 +292,12 @@ int kexgex_hash(int, const struct sshbuf *, const struct sshbuf *, const BIGNUM *, const u_char *, size_t, u_char *, size_t *); @@ -1369,10 +1378,10 @@ index d08988b3e..cd6a40333 100644 __attribute__((__bounded__(__minbytes__, 1, CURVE25519_SIZE))) __attribute__((__bounded__(__minbytes__, 2, CURVE25519_SIZE))); diff --git a/kexdh.c b/kexdh.c -index c1084f214..0faab21b0 100644 +index 191bdced0..6d5a7813d 100644 --- a/kexdh.c +++ b/kexdh.c -@@ -49,13 +49,23 @@ kex_dh_keygen(struct kex *kex) +@@ -50,13 +50,23 @@ kex_dh_keygen(struct kex *kex) { switch (kex->kex_type) { case KEX_DH_GRP1_SHA1: @@ -1397,7 +1406,7 @@ index c1084f214..0faab21b0 100644 break; case KEX_DH_GRP18_SHA512: diff --git a/kexgen.c b/kexgen.c -index 40d688d62..15df591ca 100644 +index 494d4b233..58edc79ad 100644 --- a/kexgen.c +++ b/kexgen.c @@ -44,7 +44,7 @@ @@ -2502,10 +2511,10 @@ index 000000000..1fd1d1e48 +} +#endif /* defined(GSSAPI) && defined(WITH_OPENSSL) */ diff --git a/monitor.c b/monitor.c -index 5966b4f96..ad7fef5a9 100644 +index a9e854bec..51dcdb66e 100644 --- a/monitor.c +++ b/monitor.c -@@ -141,6 +141,8 @@ int mm_answer_gss_setup_ctx(struct ssh *, int, struct sshbuf *); +@@ -134,6 +134,8 @@ int mm_answer_gss_setup_ctx(struct ssh *, int, struct sshbuf *); int mm_answer_gss_accept_ctx(struct ssh *, int, struct sshbuf *); int mm_answer_gss_userok(struct ssh *, int, struct sshbuf *); int mm_answer_gss_checkmic(struct ssh *, int, struct sshbuf *); @@ -2514,7 +2523,7 @@ index 5966b4f96..ad7fef5a9 100644 #endif #ifdef SSH_AUDIT_EVENTS -@@ -214,11 +216,18 @@ struct mon_table mon_dispatch_proto20[] = { +@@ -208,12 +210,19 @@ struct mon_table mon_dispatch_proto20[] = { {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx}, {MONITOR_REQ_GSSUSEROK, MON_ONCE|MON_AUTHDECIDE, mm_answer_gss_userok}, {MONITOR_REQ_GSSCHECKMIC, MON_ONCE, mm_answer_gss_checkmic}, @@ -2524,6 +2533,7 @@ index 5966b4f96..ad7fef5a9 100644 }; struct mon_table mon_dispatch_postauth20[] = { + {MONITOR_REQ_STATE, MON_ONCE, mm_answer_state}, +#ifdef GSSAPI + {MONITOR_REQ_GSSSETUP, 0, mm_answer_gss_setup_ctx}, + {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx}, @@ -2533,8 +2543,8 @@ index 5966b4f96..ad7fef5a9 100644 #ifdef WITH_OPENSSL {MONITOR_REQ_MODULI, 0, mm_answer_moduli}, #endif -@@ -287,6 +296,10 @@ monitor_child_preauth(struct ssh *ssh, struct monitor *pmonitor) - /* Permit requests for moduli and signatures */ +@@ -283,6 +292,10 @@ monitor_child_preauth(struct ssh *ssh, struct monitor *pmonitor) + monitor_permit(mon_dispatch, MONITOR_REQ_STATE, 1); monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); +#ifdef GSSAPI @@ -2544,7 +2554,7 @@ index 5966b4f96..ad7fef5a9 100644 /* The first few requests do not require asynchronous access */ while (!authenticated) { -@@ -408,6 +421,10 @@ monitor_child_postauth(struct ssh *ssh, struct monitor *pmonitor) +@@ -423,6 +436,10 @@ monitor_child_postauth(struct ssh *ssh, struct monitor *pmonitor) monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); @@ -2555,7 +2565,7 @@ index 5966b4f96..ad7fef5a9 100644 if (auth_opts->permit_pty_flag) { monitor_permit(mon_dispatch, MONITOR_REQ_PTY, 1); -@@ -1770,6 +1787,17 @@ monitor_apply_keystate(struct ssh *ssh, struct monitor *pmonitor) +@@ -1863,6 +1880,17 @@ monitor_apply_keystate(struct ssh *ssh, struct monitor *pmonitor) # ifdef OPENSSL_HAS_ECC kex->kex[KEX_ECDH_SHA2] = kex_gen_server; # endif @@ -2573,7 +2583,7 @@ index 5966b4f96..ad7fef5a9 100644 #endif /* WITH_OPENSSL */ kex->kex[KEX_C25519_SHA256] = kex_gen_server; kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_server; -@@ -1863,8 +1891,8 @@ mm_answer_gss_setup_ctx(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -1954,8 +1982,8 @@ mm_answer_gss_setup_ctx(struct ssh *ssh, int sock, struct sshbuf *m) u_char *p; int r; @@ -2584,7 +2594,7 @@ index 5966b4f96..ad7fef5a9 100644 if ((r = sshbuf_get_string(m, &p, &len)) != 0) fatal_fr(r, "parse"); -@@ -1896,8 +1924,8 @@ mm_answer_gss_accept_ctx(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -1987,8 +2015,8 @@ mm_answer_gss_accept_ctx(struct ssh *ssh, int sock, struct sshbuf *m) OM_uint32 flags = 0; /* GSI needs this */ int r; @@ -2595,7 +2605,7 @@ index 5966b4f96..ad7fef5a9 100644 if ((r = ssh_gssapi_get_buffer_desc(m, &in)) != 0) fatal_fr(r, "ssh_gssapi_get_buffer_desc"); -@@ -1917,6 +1945,7 @@ mm_answer_gss_accept_ctx(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -2008,6 +2036,7 @@ mm_answer_gss_accept_ctx(struct ssh *ssh, int sock, struct sshbuf *m) monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0); monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1); monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1); @@ -2603,7 +2613,7 @@ index 5966b4f96..ad7fef5a9 100644 } return (0); } -@@ -1928,8 +1957,8 @@ mm_answer_gss_checkmic(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -2019,8 +2048,8 @@ mm_answer_gss_checkmic(struct ssh *ssh, int sock, struct sshbuf *m) OM_uint32 ret; int r; @@ -2614,7 +2624,7 @@ index 5966b4f96..ad7fef5a9 100644 if ((r = ssh_gssapi_get_buffer_desc(m, &gssbuf)) != 0 || (r = ssh_gssapi_get_buffer_desc(m, &mic)) != 0) -@@ -1955,13 +1984,17 @@ mm_answer_gss_checkmic(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -2046,13 +2075,17 @@ mm_answer_gss_checkmic(struct ssh *ssh, int sock, struct sshbuf *m) int mm_answer_gss_userok(struct ssh *ssh, int sock, struct sshbuf *m) { @@ -2636,7 +2646,7 @@ index 5966b4f96..ad7fef5a9 100644 sshbuf_reset(m); if ((r = sshbuf_put_u32(m, authenticated)) != 0) -@@ -1970,7 +2003,11 @@ mm_answer_gss_userok(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -2061,7 +2094,11 @@ mm_answer_gss_userok(struct ssh *ssh, int sock, struct sshbuf *m) debug3_f("sending result %d", authenticated); mm_request_send(sock, MONITOR_ANS_GSSUSEROK, m); @@ -2649,7 +2659,7 @@ index 5966b4f96..ad7fef5a9 100644 if ((displayname = ssh_gssapi_displayname()) != NULL) auth2_record_info(authctxt, "%s", displayname); -@@ -1978,5 +2015,83 @@ mm_answer_gss_userok(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -2069,5 +2106,83 @@ mm_answer_gss_userok(struct ssh *ssh, int sock, struct sshbuf *m) /* Monitor loop will terminate if authenticated */ return (authenticated); } @@ -2735,10 +2745,10 @@ index 5966b4f96..ad7fef5a9 100644 + +#endif /* GSSAPI */ diff --git a/monitor.h b/monitor.h -index fa48fc69b..7d8f3c6fa 100644 +index 3f8a9bea3..4076f71ea 100644 --- a/monitor.h +++ b/monitor.h -@@ -63,6 +63,8 @@ enum monitor_reqtype { +@@ -64,6 +64,8 @@ enum monitor_reqtype { MONITOR_REQ_PAM_FREE_CTX = 110, MONITOR_ANS_PAM_FREE_CTX = 111, MONITOR_REQ_AUDIT_EVENT = 112, MONITOR_REQ_AUDIT_COMMAND = 113, @@ -2748,10 +2758,10 @@ index fa48fc69b..7d8f3c6fa 100644 struct ssh; diff --git a/monitor_wrap.c b/monitor_wrap.c -index 5358c77a1..cb3261b4d 100644 +index 33494b73f..13bd07bfd 100644 --- a/monitor_wrap.c +++ b/monitor_wrap.c -@@ -1054,13 +1054,15 @@ mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic) +@@ -1121,13 +1121,15 @@ mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic) } int @@ -2768,7 +2778,7 @@ index 5358c77a1..cb3261b4d 100644 mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUSEROK, m); mm_request_receive_expect(pmonitor->m_recvfd, -@@ -1073,6 +1075,59 @@ mm_ssh_gssapi_userok(char *user) +@@ -1140,6 +1142,59 @@ mm_ssh_gssapi_userok(char *user) debug3_f("user %sauthenticated", authenticated ? "" : "not "); return (authenticated); } @@ -2829,10 +2839,10 @@ index 5358c77a1..cb3261b4d 100644 /* diff --git a/monitor_wrap.h b/monitor_wrap.h -index e768036ed..09b0ccaaa 100644 +index c87295388..7493cd01b 100644 --- a/monitor_wrap.h +++ b/monitor_wrap.h -@@ -64,8 +64,10 @@ void mm_decode_activate_server_options(struct ssh *ssh, struct sshbuf *m); +@@ -68,8 +68,10 @@ void mm_decode_activate_server_options(struct ssh *ssh, struct sshbuf *m); OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID); OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *, gss_buffer_desc *, gss_buffer_desc *, OM_uint32 *); @@ -2845,18 +2855,18 @@ index e768036ed..09b0ccaaa 100644 #ifdef USE_PAM diff --git a/readconf.c b/readconf.c -index 3d9cc6dbb..0ce392538 100644 +index d99205944..0ae88a8f9 100644 --- a/readconf.c +++ b/readconf.c -@@ -70,6 +70,7 @@ +@@ -64,6 +64,7 @@ #include "uidswap.h" #include "myproposal.h" #include "digest.h" +#include "ssh-gss.h" + #include "version.h" /* Format of the configuration file: - -@@ -164,6 +165,8 @@ typedef enum { +@@ -159,6 +160,8 @@ typedef enum { oClearAllForwardings, oNoHostAuthenticationForLocalhost, oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout, oAddressFamily, oGssAuthentication, oGssDelegateCreds, @@ -2865,7 +2875,7 @@ index 3d9cc6dbb..0ce392538 100644 oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, oSendEnv, oSetEnv, oControlPath, oControlMaster, oControlPersist, oHashKnownHosts, -@@ -210,10 +213,22 @@ static struct { +@@ -206,10 +209,22 @@ static struct { /* Sometimes-unsupported options */ #if defined(GSSAPI) { "gssapiauthentication", oGssAuthentication }, @@ -2888,7 +2898,7 @@ index 3d9cc6dbb..0ce392538 100644 #endif #ifdef ENABLE_PKCS11 { "pkcs11provider", oPKCS11Provider }, -@@ -1256,10 +1271,46 @@ parse_time: +@@ -1326,10 +1341,46 @@ parse_time: intptr = &options->gss_authentication; goto parse_flag; @@ -2935,7 +2945,7 @@ index 3d9cc6dbb..0ce392538 100644 case oBatchMode: intptr = &options->batch_mode; goto parse_flag; -@@ -2576,7 +2627,13 @@ initialize_options(Options * options) +@@ -2698,7 +2749,13 @@ initialize_options(Options * options) options->fwd_opts.streamlocal_bind_unlink = -1; options->pubkey_authentication = -1; options->gss_authentication = -1; @@ -2949,7 +2959,7 @@ index 3d9cc6dbb..0ce392538 100644 options->password_authentication = -1; options->kbd_interactive_authentication = -1; options->kbd_interactive_devices = NULL; -@@ -2739,8 +2796,18 @@ fill_default_options(Options * options) +@@ -2863,8 +2920,18 @@ fill_default_options(Options * options) options->pubkey_authentication = SSH_PUBKEY_AUTH_ALL; if (options->gss_authentication == -1) options->gss_authentication = 0; @@ -2968,7 +2978,7 @@ index 3d9cc6dbb..0ce392538 100644 if (options->password_authentication == -1) options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) -@@ -3567,7 +3634,14 @@ dump_client_config(Options *o, const char *host) +@@ -3692,7 +3759,14 @@ dump_client_config(Options *o, const char *host) dump_cfg_fmtint(oGatewayPorts, o->fwd_opts.gateway_ports); #ifdef GSSAPI dump_cfg_fmtint(oGssAuthentication, o->gss_authentication); @@ -2984,10 +2994,10 @@ index 3d9cc6dbb..0ce392538 100644 dump_cfg_fmtint(oHashKnownHosts, o->hash_known_hosts); dump_cfg_fmtint(oHostbasedAuthentication, o->hostbased_authentication); diff --git a/readconf.h b/readconf.h -index 9447d5d6e..f039c11bd 100644 +index 942149f9a..b96e3279e 100644 --- a/readconf.h +++ b/readconf.h -@@ -40,7 +40,13 @@ typedef struct { +@@ -39,7 +39,13 @@ typedef struct { int pubkey_authentication; /* Try ssh2 pubkey authentication. */ int hostbased_authentication; /* ssh2's rhosts_rsa */ int gss_authentication; /* Try GSS authentication */ @@ -3002,18 +3012,18 @@ index 9447d5d6e..f039c11bd 100644 * authentication. */ int kbd_interactive_authentication; /* Try keyboard-interactive auth. */ diff --git a/servconf.c b/servconf.c -index 89b8413e8..731f208be 100644 +index 48ec8c4ec..3283e2648 100644 --- a/servconf.c +++ b/servconf.c -@@ -68,6 +68,7 @@ +@@ -66,6 +66,7 @@ #include "auth.h" #include "myproposal.h" #include "digest.h" +#include "ssh-gss.h" + #include "version.h" #if !defined(SSHD_PAM_SERVICE) - # define SSHD_PAM_SERVICE "sshd" -@@ -137,8 +138,11 @@ initialize_server_options(ServerOptions *options) +@@ -136,8 +137,11 @@ initialize_server_options(ServerOptions *options) options->kerberos_ticket_cleanup = -1; options->kerberos_get_afs_token = -1; options->gss_authentication=-1; @@ -3025,7 +3035,7 @@ index 89b8413e8..731f208be 100644 options->password_authentication = -1; options->kbd_interactive_authentication = -1; options->permit_empty_passwd = -1; -@@ -378,10 +382,18 @@ fill_default_server_options(ServerOptions *options) +@@ -374,10 +378,18 @@ fill_default_server_options(ServerOptions *options) options->kerberos_get_afs_token = 0; if (options->gss_authentication == -1) options->gss_authentication = 0; @@ -3044,7 +3054,7 @@ index 89b8413e8..731f208be 100644 if (options->password_authentication == -1) options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) -@@ -564,6 +576,7 @@ typedef enum { +@@ -562,6 +574,7 @@ typedef enum { sPerSourcePenalties, sPerSourcePenaltyExemptList, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor, @@ -3052,7 +3062,7 @@ index 89b8413e8..731f208be 100644 sAcceptEnv, sSetEnv, sPermitTunnel, sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory, sUsePrivilegeSeparation, sAllowAgentForwarding, -@@ -649,12 +662,22 @@ static struct { +@@ -647,12 +660,22 @@ static struct { #ifdef GSSAPI { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL }, @@ -3075,7 +3085,7 @@ index 89b8413e8..731f208be 100644 { "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL }, { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, { "challengeresponseauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, /* alias */ -@@ -1605,6 +1628,10 @@ process_server_config_line_depth(ServerOptions *options, char *line, +@@ -1643,6 +1666,10 @@ process_server_config_line_depth(ServerOptions *options, char *line, intptr = &options->gss_authentication; goto parse_flag; @@ -3086,7 +3096,7 @@ index 89b8413e8..731f208be 100644 case sGssCleanupCreds: intptr = &options->gss_cleanup_creds; goto parse_flag; -@@ -1613,6 +1640,22 @@ process_server_config_line_depth(ServerOptions *options, char *line, +@@ -1651,6 +1678,22 @@ process_server_config_line_depth(ServerOptions *options, char *line, intptr = &options->gss_strict_acceptor; goto parse_flag; @@ -3109,19 +3119,18 @@ index 89b8413e8..731f208be 100644 case sPasswordAuthentication: intptr = &options->password_authentication; goto parse_flag; -@@ -3204,6 +3247,10 @@ dump_config(ServerOptions *o) - #ifdef GSSAPI +@@ -3257,6 +3300,9 @@ dump_config(ServerOptions *o) dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds); + dump_cfg_fmtint(sGssStrictAcceptor, o->gss_strict_acceptor); + dump_cfg_fmtint(sGssKeyEx, o->gss_keyex); -+ dump_cfg_fmtint(sGssStrictAcceptor, o->gss_strict_acceptor); + dump_cfg_fmtint(sGssStoreRekey, o->gss_store_rekey); + dump_cfg_string(sGssKexAlgorithms, o->gss_kex_algorithms); #endif dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication); dump_cfg_fmtint(sKbdInteractiveAuthentication, diff --git a/servconf.h b/servconf.h -index 5089bc9ea..26819aa92 100644 +index 9beb90fae..c3f501400 100644 --- a/servconf.h +++ b/servconf.h @@ -150,8 +150,11 @@ typedef struct { @@ -3137,10 +3146,10 @@ index 5089bc9ea..26819aa92 100644 * authentication. */ int kbd_interactive_authentication; /* If true, permit */ diff --git a/session.c b/session.c -index c9415114d..3d9a16b1e 100644 +index f265fdc3e..b8f0c1a58 100644 --- a/session.c +++ b/session.c -@@ -2672,13 +2672,19 @@ do_cleanup(struct ssh *ssh, Authctxt *authctxt) +@@ -2630,13 +2630,19 @@ do_cleanup(struct ssh *ssh, Authctxt *authctxt) #ifdef KRB5 if (options.kerberos_ticket_cleanup && @@ -3401,12 +3410,12 @@ index 000000000..a934bda77 + +#endif /* GSSAPI */ diff --git a/ssh.1 b/ssh.1 -index 710d3d4e6..8f78b3a1e 100644 +index 697f4e42a..f83514c8f 100644 --- a/ssh.1 +++ b/ssh.1 -@@ -538,7 +538,13 @@ For full details of the options listed below, and their possible values, see - .It GatewayPorts - .It GlobalKnownHostsFile +@@ -539,7 +539,13 @@ For full details of the options listed below, and their possible values, see + .It ForwardX11Timeout + .It ForwardX11Trusted .It GSSAPIAuthentication +.It GSSAPIKeyExchange +.It GSSAPIClientIdentity @@ -3415,10 +3424,10 @@ index 710d3d4e6..8f78b3a1e 100644 +.It GSSAPIRenewalForcesRekey +.It GSSAPIServerIdentity +.It GSSAPITrustDns + .It GatewayPorts + .It GlobalKnownHostsFile .It HashKnownHosts - .It Host - .It HostbasedAcceptedAlgorithms -@@ -626,6 +632,8 @@ flag), +@@ -636,6 +642,8 @@ flag), (supported message integrity codes), .Ar kex (key exchange algorithms), @@ -3428,10 +3437,10 @@ index 710d3d4e6..8f78b3a1e 100644 (key types), .Ar key-ca-sign diff --git a/ssh.c b/ssh.c -index 0019281f4..484a26528 100644 +index 3b03108db..8d27f6379 100644 --- a/ssh.c +++ b/ssh.c -@@ -827,6 +827,8 @@ main(int ac, char **av) +@@ -847,6 +847,8 @@ main(int ac, char **av) else if (strcmp(optarg, "kex") == 0 || strcasecmp(optarg, "KexAlgorithms") == 0) cp = kex_alg_list('\n'); @@ -3440,7 +3449,7 @@ index 0019281f4..484a26528 100644 else if (strcmp(optarg, "key") == 0) cp = sshkey_alg_list(0, 0, 0, '\n'); else if (strcmp(optarg, "key-cert") == 0) -@@ -857,8 +859,8 @@ main(int ac, char **av) +@@ -877,8 +879,8 @@ main(int ac, char **av) } else if (strcmp(optarg, "help") == 0) { cp = xstrdup( "cipher\ncipher-auth\ncompression\nkex\n" @@ -3452,7 +3461,7 @@ index 0019281f4..484a26528 100644 if (cp == NULL) fatal("Unsupported query \"%s\"", optarg); diff --git a/ssh_config b/ssh_config -index cc5663562..16197d15d 100644 +index 238a0c5e3..3ae9025ff 100644 --- a/ssh_config +++ b/ssh_config @@ -24,6 +24,8 @@ @@ -3465,10 +3474,10 @@ index cc5663562..16197d15d 100644 # CheckHostIP no # AddressFamily any diff --git a/ssh_config.5 b/ssh_config.5 -index 7c7c5c50d..4a48c5775 100644 +index f7066cbaa..a4589885c 100644 --- a/ssh_config.5 +++ b/ssh_config.5 -@@ -938,10 +938,67 @@ The default is +@@ -976,10 +976,67 @@ The default is Specifies whether user authentication based on GSSAPI is allowed. The default is .Cm no . @@ -3537,7 +3546,7 @@ index 7c7c5c50d..4a48c5775 100644 Indicates that .Xr ssh 1 diff --git a/sshconnect2.c b/sshconnect2.c -index 11fcdea8a..068da7f94 100644 +index b3679c9d7..d7d085475 100644 --- a/sshconnect2.c +++ b/sshconnect2.c @@ -222,6 +222,11 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port, @@ -3649,7 +3658,7 @@ index 11fcdea8a..068da7f94 100644 {"gssapi-with-mic", userauth_gssapi, userauth_gssapi_cleanup, -@@ -756,12 +823,32 @@ userauth_gssapi(struct ssh *ssh) +@@ -759,12 +826,32 @@ userauth_gssapi(struct ssh *ssh) OM_uint32 min; int r, ok = 0; gss_OID mech = NULL; @@ -3683,7 +3692,7 @@ index 11fcdea8a..068da7f94 100644 /* Check to see whether the mechanism is usable before we offer it */ while (authctxt->mech_tried < authctxt->gss_supported_mechs->count && -@@ -770,13 +857,15 @@ userauth_gssapi(struct ssh *ssh) +@@ -773,13 +860,15 @@ userauth_gssapi(struct ssh *ssh) elements[authctxt->mech_tried]; /* My DER encoding requires length<128 */ if (mech->length < 128 && ssh_gssapi_check_mechanism(&gssctxt, @@ -3700,7 +3709,7 @@ index 11fcdea8a..068da7f94 100644 if (!ok || mech == NULL) return 0; -@@ -1010,6 +1099,55 @@ input_gssapi_error(int type, u_int32_t plen, struct ssh *ssh) +@@ -1013,6 +1102,55 @@ input_gssapi_error(int type, u_int32_t plen, struct ssh *ssh) free(lang); return r; } @@ -3756,7 +3765,7 @@ index 11fcdea8a..068da7f94 100644 #endif /* GSSAPI */ static int -@@ -1319,7 +1457,9 @@ sign_and_send_pubkey(struct ssh *ssh, Identity *id) +@@ -1322,7 +1460,9 @@ sign_and_send_pubkey(struct ssh *ssh, Identity *id) /* prefer host-bound pubkey signatures if supported by server */ if ((ssh->kex->flags & KEX_HAS_PUBKEY_HOSTBOUND) != 0 && @@ -3767,22 +3776,11 @@ index 11fcdea8a..068da7f94 100644 hostbound = 1; method = "publickey-hostbound-v00@openssh.com"; } -diff --git a/sshd-session.c b/sshd-session.c -index 4b79b9ba6..03a028c82 100644 ---- a/sshd-session.c -+++ b/sshd-session.c -@@ -658,8 +658,8 @@ notify_hostkeys(struct ssh *ssh) - } - debug3_f("sent %u hostkeys", nkeys); - if (nkeys == 0) -- fatal_f("no hostkeys"); -- if ((r = sshpkt_send(ssh)) != 0) -+ debug3_f("no hostkeys"); -+ else if ((r = sshpkt_send(ssh)) != 0) - sshpkt_fatal(ssh, r, "%s: send", __func__); - sshbuf_free(buf); - } -@@ -1445,6 +1445,48 @@ do_ssh2_kex(struct ssh *ssh) +diff --git a/sshd-auth.c b/sshd-auth.c +index 9c31515de..3b7344b25 100644 +--- a/sshd-auth.c ++++ b/sshd-auth.c +@@ -819,6 +819,48 @@ do_ssh2_kex(struct ssh *ssh) free(hkalgs); @@ -3831,11 +3829,10 @@ index 4b79b9ba6..03a028c82 100644 /* start key exchange */ if ((r = kex_setup(ssh, myproposal)) != 0) fatal_r(r, "kex_setup"); -@@ -1462,7 +1504,18 @@ do_ssh2_kex(struct ssh *ssh) - #ifdef OPENSSL_HAS_ECC +@@ -836,6 +878,17 @@ do_ssh2_kex(struct ssh *ssh) + # ifdef OPENSSL_HAS_ECC kex->kex[KEX_ECDH_SHA2] = kex_gen_server; - #endif --#endif + # endif /* OPENSSL_HAS_ECC */ +# ifdef GSSAPI + if (options.gss_keyex) { + kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server; @@ -3847,15 +3844,29 @@ index 4b79b9ba6..03a028c82 100644 + kex->kex[KEX_GSS_C25519_SHA256] = kexgss_server; + } +# endif -+#endif /* WITH_OPENSSL */ + #endif /* WITH_OPENSSL */ kex->kex[KEX_C25519_SHA256] = kex_gen_server; kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_server; - kex->kex[KEX_KEM_MLKEM768X25519_SHA256] = kex_gen_server; +diff --git a/sshd-session.c b/sshd-session.c +index 8979f743b..3ea9da40c 100644 +--- a/sshd-session.c ++++ b/sshd-session.c +@@ -592,8 +592,8 @@ notify_hostkeys(struct ssh *ssh) + } + debug3_f("sent %u hostkeys", nkeys); + if (nkeys == 0) +- fatal_f("no hostkeys"); +- if ((r = sshpkt_send(ssh)) != 0) ++ debug3_f("no hostkeys"); ++ else if ((r = sshpkt_send(ssh)) != 0) + sshpkt_fatal(ssh, r, "%s: send", __func__); + sshbuf_free(buf); + } diff --git a/sshd.c b/sshd.c -index df76dc78c..48b334c68 100644 +index 3c76b60b0..3ab81e268 100644 --- a/sshd.c +++ b/sshd.c -@@ -1558,7 +1558,8 @@ main(int ac, char **av) +@@ -1676,7 +1676,8 @@ main(int ac, char **av) free(fp); } accumulate_host_timing_secret(cfg, NULL); @@ -3866,10 +3877,10 @@ index df76dc78c..48b334c68 100644 exit(1); } diff --git a/sshd_config b/sshd_config -index 36894ace5..ecfe8d026 100644 +index 0f4a3a724..6ddae0370 100644 --- a/sshd_config +++ b/sshd_config -@@ -69,6 +69,8 @@ AuthorizedKeysFile .ssh/authorized_keys +@@ -71,6 +71,8 @@ AuthorizedKeysFile .ssh/authorized_keys # GSSAPI options #GSSAPIAuthentication no #GSSAPICleanupCredentials yes @@ -3879,7 +3890,7 @@ index 36894ace5..ecfe8d026 100644 # Set this to 'yes' to enable PAM authentication, account processing, # and session processing. If this is enabled, PAM authentication will diff --git a/sshd_config.5 b/sshd_config.5 -index dbed44f2a..6959d5f6c 100644 +index 6ae606f1e..301c6be90 100644 --- a/sshd_config.5 +++ b/sshd_config.5 @@ -739,6 +739,11 @@ Specifies whether to automatically destroy the user's credentials cache @@ -3927,30 +3938,30 @@ index dbed44f2a..6959d5f6c 100644 Specifies the signature algorithms that will be accepted for hostbased authentication as a list of comma-separated patterns. diff --git a/sshkey.c b/sshkey.c -index 1db83788d..c3acd4e09 100644 +index afd7822c4..1b71b47c9 100644 --- a/sshkey.c +++ b/sshkey.c -@@ -131,6 +131,9 @@ extern const struct sshkey_impl sshkey_dsa_cert_impl; - extern const struct sshkey_impl sshkey_xmss_impl; - extern const struct sshkey_impl sshkey_xmss_cert_impl; - #endif +@@ -113,6 +113,9 @@ 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; + #endif /* WITH_OPENSSL */ +#ifdef GSSAPI +extern const struct sshkey_impl sshkey_null_impl; +#endif /* GSSAPI */ const struct sshkey_impl * const keyimpls[] = { &sshkey_ed25519_impl, -@@ -170,6 +173,9 @@ const struct sshkey_impl * const keyimpls[] = { - &sshkey_xmss_impl, - &sshkey_xmss_cert_impl, - #endif +@@ -144,6 +147,9 @@ const struct sshkey_impl * const keyimpls[] = { + &sshkey_rsa_sha512_impl, + &sshkey_rsa_sha512_cert_impl, + #endif /* WITH_OPENSSL */ +#ifdef GSSAPI + &sshkey_null_impl, +#endif /* GSSAPI */ NULL }; -@@ -339,7 +345,7 @@ sshkey_alg_list(int certs_only, int plain_only, int include_sigonly, char sep) +@@ -314,7 +320,7 @@ sshkey_alg_list(int certs_only, int plain_only, int include_sigonly, char sep) for (i = 0; keyimpls[i] != NULL; i++) { impl = keyimpls[i]; @@ -3960,10 +3971,10 @@ index 1db83788d..c3acd4e09 100644 if (!include_sigonly && impl->sigonly) continue; diff --git a/sshkey.h b/sshkey.h -index d0cdea0ce..cce4b93c0 100644 +index c3262b896..931d1f79b 100644 --- a/sshkey.h +++ b/sshkey.h -@@ -73,6 +73,7 @@ enum sshkey_types { +@@ -67,6 +67,7 @@ enum sshkey_types { KEY_ECDSA_SK_CERT, KEY_ED25519_SK, KEY_ED25519_SK_CERT, diff --git a/debian/patches/keepalive-extensions.patch b/debian/patches/keepalive-extensions.patch index 1c61c7c..3021c49 100644 --- a/debian/patches/keepalive-extensions.patch +++ b/debian/patches/keepalive-extensions.patch @@ -1,4 +1,4 @@ -From d927628a5a54212ba64b7a703a25d63aab0fb3a3 Mon Sep 17 00:00:00 2001 +From 52f98425101dc955f2919f6e60974c4fb4032de1 Mon Sep 17 00:00:00 2001 From: Richard Kettlewell Date: Sun, 9 Feb 2014 16:09:52 +0000 Subject: Various keepalive extensions @@ -16,7 +16,7 @@ keepalives. Author: Ian Jackson Author: Matthew Vernon Author: Colin Watson -Last-Update: 2024-09-13 +Last-Update: 2025-10-06 Patch-Name: keepalive-extensions.patch --- @@ -26,27 +26,27 @@ Patch-Name: keepalive-extensions.patch 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/readconf.c b/readconf.c -index 08342f2a2..f78786964 100644 +index 0e91bb243..95d497938 100644 --- a/readconf.c +++ b/readconf.c -@@ -182,6 +182,7 @@ typedef enum { - oPubkeyAcceptedAlgorithms, oCASignatureAlgorithms, oProxyJump, +@@ -178,6 +178,7 @@ typedef enum { oSecurityKeyProvider, oKnownHostsCommand, oRequiredRSASize, oEnableEscapeCommandline, oObscureKeystrokeTiming, oChannelTimeout, + oVersionAddendum, oRefuseConnection, oWarnWeakCrypto, + oProtocolKeepAlives, oSetupTimeOut, oIgnore, oIgnoredUnknownOption, oDeprecated, oUnsupported } OpCodes; -@@ -345,6 +346,8 @@ static struct { - { "enableescapecommandline", oEnableEscapeCommandline }, - { "obscurekeystroketiming", oObscureKeystrokeTiming }, - { "channeltimeout", oChannelTimeout }, +@@ -344,6 +345,8 @@ static struct { + { "versionaddendum", oVersionAddendum }, + { "refuseconnection", oRefuseConnection }, + { "warnweakcrypto", oWarnWeakCrypto }, + { "protocolkeepalives", oProtocolKeepAlives }, + { "setuptimeout", oSetupTimeOut }, { NULL, oBadOption } }; -@@ -1166,6 +1169,7 @@ process_config_line_depth(Options *options, struct passwd *pw, const char *host, +@@ -1236,6 +1239,7 @@ process_config_line_depth(Options *options, struct passwd *pw, const char *host, argv_consume(&ac); break; case oConnectTimeout: @@ -54,7 +54,7 @@ index 08342f2a2..f78786964 100644 intptr = &options->connection_timeout; parse_time: arg = argv_next(&ac, &av); -@@ -1908,6 +1912,7 @@ parse_pubkey_algos: +@@ -1978,6 +1982,7 @@ parse_pubkey_algos: goto parse_flag; case oServerAliveInterval: @@ -62,7 +62,7 @@ index 08342f2a2..f78786964 100644 intptr = &options->server_alive_interval; goto parse_time; -@@ -2893,8 +2898,13 @@ fill_default_options(Options * options) +@@ -3013,8 +3018,13 @@ fill_default_options(Options * options) options->rekey_interval = 0; if (options->verify_host_key_dns == -1) options->verify_host_key_dns = 0; @@ -79,10 +79,10 @@ index 08342f2a2..f78786964 100644 options->server_alive_count_max = 3; if (options->control_master == -1) diff --git a/ssh_config.5 b/ssh_config.5 -index 4a48c5775..31142f8c5 100644 +index a4589885c..718c870f8 100644 --- a/ssh_config.5 +++ b/ssh_config.5 -@@ -297,9 +297,13 @@ If set to +@@ -335,9 +335,13 @@ If set to .Cm yes , user interaction such as password prompts and host key confirmation requests will be disabled. @@ -97,7 +97,7 @@ index 4a48c5775..31142f8c5 100644 The argument must be .Cm yes or -@@ -620,6 +624,8 @@ Specifies the timeout (in seconds) used when connecting to the +@@ -658,6 +662,8 @@ 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. @@ -106,7 +106,7 @@ index 4a48c5775..31142f8c5 100644 .It Cm ControlMaster Enables the sharing of multiple sessions over a single network connection. When set to -@@ -1933,7 +1939,12 @@ from the server, +@@ -1990,7 +1996,12 @@ from the server, will send a message through the encrypted channel to request a response from the server. The default @@ -120,7 +120,7 @@ index 4a48c5775..31142f8c5 100644 .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. -@@ -2047,6 +2058,12 @@ Specifies whether the system should send TCP keepalive messages to the +@@ -2113,6 +2124,12 @@ 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. @@ -134,10 +134,10 @@ index 4a48c5775..31142f8c5 100644 connections will die if the route is down temporarily, and some people find it annoying. diff --git a/sshd_config.5 b/sshd_config.5 -index 6959d5f6c..11a8e922f 100644 +index 301c6be90..ceaeddc9d 100644 --- a/sshd_config.5 +++ b/sshd_config.5 -@@ -1984,6 +1984,9 @@ This avoids infinitely hanging sessions. +@@ -1995,6 +1995,9 @@ This avoids infinitely hanging sessions. .Pp To disable TCP keepalive messages, the value should be set to .Cm no . diff --git a/debian/patches/link-ssh-against-ssh-pkcs11.patch b/debian/patches/link-ssh-against-ssh-pkcs11.patch new file mode 100644 index 0000000..8ec593e --- /dev/null +++ b/debian/patches/link-ssh-against-ssh-pkcs11.patch @@ -0,0 +1,32 @@ +From 84464406c27b4dc83f5c8bc7f622b44c6746e946 Mon Sep 17 00:00:00 2001 +From: Damien Miller +Date: Thu, 16 Oct 2025 11:15:16 +1100 +Subject: link ssh against ssh-pkcs11.o + +Should fix PIN entry for direct use of PKCS11Provider in ssh(1) +bz3879 + +Origin: https://anongit.mindrot.org/openssh.git/commit/?h=V_10_2&id=434ba7684054c0637ce8f2486aaacafe65d9b8aa +Bug: https://bugzilla.mindrot.org/show_bug.cgi?id=3879 +Bug-Debian: https://bugs.debian.org/1117638 +Bug-Debian: https://bugs.debian.org/1117720 +Last-Update: 2025-10-17 + +Patch-Name: link-ssh-against-ssh-pkcs11.patch +--- + Makefile.in | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Makefile.in b/Makefile.in +index 6ad81e78b..b8a389a59 100644 +--- a/Makefile.in ++++ b/Makefile.in +@@ -114,7 +114,7 @@ P11OBJS= ssh-pkcs11-client.o + SKOBJS= ssh-sk-client.o + + SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \ +- sshconnect.o sshconnect2.o mux.o $(P11OBJS) $(SKOBJS) ++ sshconnect.o sshconnect2.o mux.o ssh-pkcs11.o $(SKOBJS) + + SSHDOBJS=sshd.o \ + platform-listen.o \ diff --git a/debian/patches/mention-ssh-keygen-on-keychange.patch b/debian/patches/mention-ssh-keygen-on-keychange.patch index b0e9297..54b605b 100644 --- a/debian/patches/mention-ssh-keygen-on-keychange.patch +++ b/debian/patches/mention-ssh-keygen-on-keychange.patch @@ -1,4 +1,4 @@ -From 32e848548c722c9db2bf3ae50b1f13f1fd45619c Mon Sep 17 00:00:00 2001 +From f8af76c69ebb7cc93c70a411497002b777d176aa Mon Sep 17 00:00:00 2001 From: Scott Moser Date: Sun, 9 Feb 2014 16:10:03 +0000 Subject: Mention ssh-keygen in ssh fingerprint changed warning @@ -14,10 +14,10 @@ Patch-Name: mention-ssh-keygen-on-keychange.patch 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/sshconnect.c b/sshconnect.c -index 1b7e804fb..cbfc20735 100644 +index b21b7cb68..b125d9202 100644 --- a/sshconnect.c +++ b/sshconnect.c -@@ -1307,9 +1307,13 @@ check_host_key(char *hostname, const struct ssh_conn_info *cinfo, +@@ -1299,9 +1299,13 @@ check_host_key(char *hostname, const struct ssh_conn_info *cinfo, 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."); @@ -32,7 +32,7 @@ index 1b7e804fb..cbfc20735 100644 } /* The host key has changed. */ warn_changed_key(host_key); -@@ -1321,6 +1325,9 @@ check_host_key(char *hostname, const struct ssh_conn_info *cinfo, +@@ -1313,6 +1317,9 @@ check_host_key(char *hostname, const struct ssh_conn_info *cinfo, error("Offending %s key in %s:%lu", sshkey_type(host_found->key), host_found->file, host_found->line); diff --git a/debian/patches/no-openssl-version-status.patch b/debian/patches/no-openssl-version-status.patch deleted file mode 100644 index 8db7ff6..0000000 --- a/debian/patches/no-openssl-version-status.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 30154cd7eb49b9a5dafbdfd2d730fde5d2a9ea16 Mon Sep 17 00:00:00 2001 -From: Kurt Roeckx -Date: Sun, 9 Feb 2014 16:10:14 +0000 -Subject: Don't check the status field of the OpenSSL version - -There is no reason to check the version of OpenSSL (in Debian). If it's -not compatible the soname will change. OpenSSH seems to want to do a -check for the soname based on the version number, but wants to keep the -status of the release the same. Remove that check on the status since -it doesn't tell you anything about how compatible that version is. - -Author: Colin Watson -Bug-Debian: https://bugs.debian.org/93581 -Bug-Debian: https://bugs.debian.org/664383 -Bug-Debian: https://bugs.debian.org/732940 -Forwarded: not-needed -Last-Update: 2023-09-02 - -Patch-Name: no-openssl-version-status.patch ---- - openbsd-compat/openssl-compat.c | 8 ++++---- - openbsd-compat/regress/opensslvertest.c | 2 ++ - 2 files changed, 6 insertions(+), 4 deletions(-) - -diff --git a/openbsd-compat/openssl-compat.c b/openbsd-compat/openssl-compat.c -index 14865077e..0cea08c03 100644 ---- a/openbsd-compat/openssl-compat.c -+++ b/openbsd-compat/openssl-compat.c -@@ -49,18 +49,18 @@ ssh_compatible_openssl(long headerver, long libver) - return 1; - - /* -- * For versions >= 3.0, only the major and status must match. -+ * For versions >= 3.0, only the major must match. - */ - if (headerver >= 0x3000000f) { -- mask = 0xf000000fL; /* major,status */ -+ mask = 0xf0000000L; /* major */ - return (headerver & mask) == (libver & mask); - } - - /* -- * For versions >= 1.0.0, but <3, major,minor,status must match and -+ * For versions >= 1.0.0, but <3, major,minor must match and - * library fix version must be equal to or newer than the header. - */ -- mask = 0xfff0000fL; /* major,minor,status */ -+ mask = 0xfff00000L; /* major,minor */ - hfix = (headerver & 0x000ff000) >> 12; - lfix = (libver & 0x000ff000) >> 12; - if ( (headerver & mask) == (libver & mask) && lfix >= hfix) -diff --git a/openbsd-compat/regress/opensslvertest.c b/openbsd-compat/regress/opensslvertest.c -index 99c894418..351df4374 100644 ---- a/openbsd-compat/regress/opensslvertest.c -+++ b/openbsd-compat/regress/opensslvertest.c -@@ -28,6 +28,7 @@ struct version_test { - } version_tests[] = { - /* built with 1.0.1b release headers */ - { 0x1000101fL, 0x1000101fL, 1},/* exact match */ -+ { 0x1000101fL, 0x10001010L, 1}, /* different status: ok */ - { 0x1000101fL, 0x1000102fL, 1}, /* newer library patch version: ok */ - { 0x1000101fL, 0x1000100fL, 1}, /* older library patch version: ok */ - { 0x1000101fL, 0x1000201fL, 1}, /* newer library fix version: ok */ -@@ -48,6 +49,7 @@ struct version_test { - - /* built with 3.0.1 release headers */ - { 0x3010101fL, 0x3010101fL, 1},/* exact match */ -+ { 0x3010101fL, 0x30101010L, 1}, /* different status: ok */ - { 0x3010101fL, 0x3010102fL, 1}, /* newer library patch version: ok */ - { 0x3010101fL, 0x3010100fL, 1}, /* older library patch version: ok */ - { 0x3010101fL, 0x3010201fL, 1}, /* newer library fix version: ok */ diff --git a/debian/patches/openbsd-docs.patch b/debian/patches/openbsd-docs.patch index 9947dd5..920c196 100644 --- a/debian/patches/openbsd-docs.patch +++ b/debian/patches/openbsd-docs.patch @@ -1,4 +1,4 @@ -From e868160317622303dd192460a186162dfa4b6c2e Mon Sep 17 00:00:00 2001 +From d1fb4b9bf892b05a9414c24c55dbc843cd514002 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Sun, 9 Feb 2014 16:10:09 +0000 Subject: Adjust various OpenBSD-specific references in manual pages @@ -6,18 +6,18 @@ Subject: Adjust various OpenBSD-specific references in manual pages No single bug reference for this patch, but history includes: https://bugs.debian.org/154434 (login.conf(5)) https://bugs.debian.org/513417 (/etc/rc) - https://bugs.debian.org/998069 (rdomain(4)) + https://bugs.debian.org/998069, https://bugs.debian.org/1095686 (rdomain(4)) Forwarded: not-needed -Last-Update: 2024-07-03 +Last-Update: 2025-04-15 Patch-Name: openbsd-docs.patch --- moduli.5 | 4 ++-- ssh-keygen.1 | 12 ++++-------- sshd.8 | 5 ++--- - sshd_config.5 | 40 ++-------------------------------------- - 4 files changed, 10 insertions(+), 51 deletions(-) + sshd_config.5 | 27 ++++++--------------------- + 4 files changed, 14 insertions(+), 34 deletions(-) diff --git a/moduli.5 b/moduli.5 index 5086a6d42..6dffdc7e6 100644 @@ -42,7 +42,7 @@ index 5086a6d42..6dffdc7e6 100644 .Sh SEE ALSO .Xr ssh-keygen 1 , diff --git a/ssh-keygen.1 b/ssh-keygen.1 -index 06f0555a4..76239bcdf 100644 +index 7ceb1db95..43f9a8ef0 100644 --- a/ssh-keygen.1 +++ b/ssh-keygen.1 @@ -211,9 +211,7 @@ key in @@ -76,7 +76,7 @@ index 06f0555a4..76239bcdf 100644 It is important that this file contains moduli of a range of bit lengths. .Pp A number of options are available for moduli generation and screening via the -@@ -1316,7 +1312,7 @@ on all machines +@@ -1311,7 +1307,7 @@ on all machines where the user wishes to log in using public key authentication. There is no need to keep the contents of this file secret. .Pp @@ -86,7 +86,7 @@ index 06f0555a4..76239bcdf 100644 The file format is described in .Xr moduli 5 . diff --git a/sshd.8 b/sshd.8 -index 464d402f6..bd1117bfe 100644 +index 1cec2fd2c..ef9be614c 100644 --- a/sshd.8 +++ b/sshd.8 @@ -64,7 +64,7 @@ over an insecure network. @@ -116,10 +116,10 @@ index 464d402f6..bd1117bfe 100644 .Xr sshd_config 5 , .Xr inetd 8 , diff --git a/sshd_config.5 b/sshd_config.5 -index ed2f74060..e177e4af8 100644 +index d7b60308a..c8b364139 100644 --- a/sshd_config.5 +++ b/sshd_config.5 -@@ -1001,9 +1001,6 @@ for interactive sessions and +@@ -1000,9 +1000,6 @@ for interactive sessions and for non-interactive sessions. .It Cm KbdInteractiveAuthentication Specifies whether to allow keyboard-interactive authentication. @@ -129,70 +129,32 @@ index ed2f74060..e177e4af8 100644 The default is .Cm yes . The argument to this keyword must be -@@ -1117,45 +1114,33 @@ The following forms may be used: - .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. -+The default is to listen on all local addresses. +@@ -1150,8 +1147,10 @@ routing domain. Multiple .Cm ListenAddress options are permitted. -For more information on routing domains, see -.Xr rdomain 4 . ++.Pp ++On Linux, routing domains are implemented using Virtual Routing and ++Forwarding domains (VRFs); for more information, see ++.Xr ip-vrf 8 . .It Cm LoginGraceTime The server disconnects after this time if the user has not successfully logged in. -@@ -1283,14 +1268,8 @@ The available criteria are - .Cm Host , - .Cm LocalAddress , - .Cm LocalPort , --.Cm RDomain , - and --.Cm Address --(with --.Cm RDomain +@@ -1285,9 +1284,8 @@ and + .Cm Address + (with + .Cm RDomain -representing the -.Xr rdomain 4 -on which the connection was received). -+.Cm Address . ++representing the routing domain on which the connection was received; see ++.Xr ip-vrf 8 ) . .Pp The match patterns may consist of single entries or comma-separated lists and may use the wildcard and negation operators described in the -@@ -1364,7 +1343,6 @@ Available keywords are +@@ -1368,7 +1366,6 @@ Available keywords are .Cm RefuseConnection , .Cm RekeyLimit , .Cm RevokedKeys , @@ -200,7 +162,7 @@ index ed2f74060..e177e4af8 100644 .Cm SetEnv , .Cm StreamLocalBindMask , .Cm StreamLocalBindUnlink , -@@ -1863,15 +1841,6 @@ an OpenSSH Key Revocation List (KRL) as generated by +@@ -1867,15 +1864,6 @@ 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 . @@ -216,16 +178,7 @@ index ed2f74060..e177e4af8 100644 .It Cm SecurityKeyProvider Specifies a path to a library that will be used when loading FIDO authenticator-hosted keys, overriding the default of using -@@ -2205,8 +2174,6 @@ A literal - Identifies the connection endpoints, containing - four space-separated values: client address, client port number, - server address, and server port number. --.It \&%D --The routing domain in which the incoming connection was received. - .It %F - The fingerprint of the CA key. - .It %f -@@ -2245,9 +2212,6 @@ accepts the tokens %%, %h, %U, and %u. +@@ -2256,9 +2244,6 @@ accepts the tokens %%, %h, %U, and %u. .Pp .Cm ChrootDirectory accepts the tokens %%, %h, %U, and %u. diff --git a/debian/patches/package-versioning.patch b/debian/patches/package-versioning.patch index a4ac5fb..1709227 100644 --- a/debian/patches/package-versioning.patch +++ b/debian/patches/package-versioning.patch @@ -1,4 +1,4 @@ -From 5aeb7a317738bafded850091cb310274388d498f Mon Sep 17 00:00:00 2001 +From cde8258c81906a8dd1eb0e76e9daa2e2d258f8df Mon Sep 17 00:00:00 2001 From: Matthew Vernon Date: Sun, 9 Feb 2014 16:10:05 +0000 Subject: Include the Debian version in our identification @@ -9,7 +9,7 @@ generally just try attacks rather than bothering to scan for vulnerable-looking version strings. (However, see debian-banner.patch.) Forwarded: not-needed -Last-Update: 2023-12-18 +Last-Update: 2025-10-06 Patch-Name: package-versioning.patch --- @@ -18,10 +18,10 @@ Patch-Name: package-versioning.patch 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/kex.c b/kex.c -index f09e79e6b..19b1fcaa8 100644 +index 0f68fda32..a19303633 100644 --- a/kex.c +++ b/kex.c -@@ -1255,7 +1255,7 @@ kex_exchange_identification(struct ssh *ssh, int timeout_ms, +@@ -1254,7 +1254,7 @@ kex_exchange_identification(struct ssh *ssh, int timeout_ms, if (version_addendum != NULL && *version_addendum == '\0') version_addendum = NULL; if ((r = sshbuf_putf(our_version, "SSH-%d.%d-%s%s%s\r\n", @@ -31,13 +31,13 @@ index f09e79e6b..19b1fcaa8 100644 version_addendum == NULL ? "" : version_addendum)) != 0) { oerrno = errno; diff --git a/version.h b/version.h -index 8c7e37e7d..7e0cac99f 100644 +index 086cdba98..0cf7f464f 100644 --- a/version.h +++ b/version.h @@ -3,4 +3,9 @@ - #define SSH_VERSION "OpenSSH_9.9" + #define SSH_VERSION "OpenSSH_10.2" - #define SSH_PORTABLE "p2" + #define SSH_PORTABLE "p1" -#define SSH_RELEASE SSH_VERSION SSH_PORTABLE +#define SSH_RELEASE_MINIMUM SSH_VERSION SSH_PORTABLE +#ifdef SSH_EXTRAVERSION diff --git a/debian/patches/pam-avoid-unknown-host.patch b/debian/patches/pam-avoid-unknown-host.patch deleted file mode 100644 index d6cdb4a..0000000 --- a/debian/patches/pam-avoid-unknown-host.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 2308e489f6a8aae2087c68eb5c33d19cdbbdf4ba Mon Sep 17 00:00:00 2001 -From: Daan De Meyer -Date: Mon, 20 Mar 2023 20:22:14 +0100 -Subject: Only set PAM_RHOST if the remote host is not "UNKNOWN" - -When using sshd's -i option with stdio that is not a AF_INET/AF_INET6 -socket, auth_get_canonical_hostname() returns "UNKNOWN" which is then -set as the value of PAM_RHOST, causing pam to try to do a reverse DNS -query of "UNKNOWN", which times out multiple times, causing a -substantial slowdown when logging in. - -To fix this, let's only set PAM_RHOST if the hostname is not "UNKNOWN". - -Author: Daan De Meyer -Last-Update: 2024-04-03 - -Patch-Name: pam-avoid-unknown-host.patch ---- - auth-pam.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/auth-pam.c b/auth-pam.c -index 13c0a792e..b22883b95 100644 ---- a/auth-pam.c -+++ b/auth-pam.c -@@ -735,7 +735,7 @@ sshpam_init(struct ssh *ssh, Authctxt *authctxt) - sshpam_laddr = get_local_ipaddr( - ssh_packet_get_connection_in(ssh)); - } -- if (sshpam_rhost != NULL) { -+ if (sshpam_rhost != NULL && strcmp(sshpam_rhost, "UNKNOWN") != 0) { - debug("PAM: setting PAM_RHOST to \"%s\"", sshpam_rhost); - sshpam_err = pam_set_item(sshpam_handle, PAM_RHOST, - sshpam_rhost); diff --git a/debian/patches/regress-conch-dev-zero.patch b/debian/patches/regress-conch-dev-zero.patch index 3825c86..f646a05 100644 --- a/debian/patches/regress-conch-dev-zero.patch +++ b/debian/patches/regress-conch-dev-zero.patch @@ -1,4 +1,4 @@ -From 8e6bbc0c94cd203b23c13c344f46d47cfd19f31d Mon Sep 17 00:00:00 2001 +From 0d77cb7768dfbb23abf73510b0ec1562b2ca3c7d Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Sun, 31 Mar 2024 00:24:11 +0000 Subject: regress: Redirect conch stdin from /dev/zero diff --git a/debian/patches/restore-authorized_keys2.patch b/debian/patches/restore-authorized_keys2.patch index 5020275..bbf4d21 100644 --- a/debian/patches/restore-authorized_keys2.patch +++ b/debian/patches/restore-authorized_keys2.patch @@ -1,4 +1,4 @@ -From d6bfcde360768009d66ecc052fa5d3e1a89fa5ce Mon Sep 17 00:00:00 2001 +From 184c109edaa7713aaf9e4510d9fb77f98fb146a7 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Sun, 5 Mar 2017 02:02:11 +0000 Subject: Restore reading authorized_keys2 by default @@ -18,7 +18,7 @@ Patch-Name: restore-authorized_keys2.patch 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/sshd_config b/sshd_config -index 677f97d5d..d500d18cd 100644 +index 01e8d9098..481dc4137 100644 --- a/sshd_config +++ b/sshd_config @@ -38,9 +38,8 @@ Include /etc/ssh/sshd_config.d/*.conf diff --git a/debian/patches/restore-tcp-wrappers.patch b/debian/patches/restore-tcp-wrappers.patch index 5c57063..4bc27d8 100644 --- a/debian/patches/restore-tcp-wrappers.patch +++ b/debian/patches/restore-tcp-wrappers.patch @@ -1,4 +1,4 @@ -From c4f6a4d2c7ce9dcd29df3d447e7bc8ddf1b5c592 Mon Sep 17 00:00:00 2001 +From 490a288a8bb2586646956f08a23599c9af758e18 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 7 Oct 2014 13:22:41 +0100 Subject: Restore TCP wrappers support @@ -28,10 +28,10 @@ Patch-Name: restore-tcp-wrappers.patch 3 files changed, 89 insertions(+) diff --git a/configure.ac b/configure.ac -index 6a0140a9d..90548dcfc 100644 +index 53112bdac..d6783774b 100644 --- a/configure.ac +++ b/configure.ac -@@ -1693,6 +1693,62 @@ else +@@ -1797,6 +1797,62 @@ else AC_MSG_RESULT([no]) fi @@ -94,7 +94,7 @@ index 6a0140a9d..90548dcfc 100644 # Check whether user wants to use ldns LDNS_MSG="no" AC_ARG_WITH(ldns, -@@ -5734,6 +5790,7 @@ echo " PAM support: $PAM_MSG" +@@ -5888,6 +5944,7 @@ echo " PAM support: $PAM_MSG" echo " OSF SIA support: $SIA_MSG" echo " KerberosV support: $KRB5_MSG" echo " SELinux support: $SELINUX_MSG" @@ -103,10 +103,10 @@ index 6a0140a9d..90548dcfc 100644 echo " libldns support: $LDNS_MSG" echo " Solaris process contract support: $SPC_MSG" diff --git a/sshd-session.c b/sshd-session.c -index 03a028c82..f36d58b1b 100644 +index 3ea9da40c..8e0fe2cd5 100644 --- a/sshd-session.c +++ b/sshd-session.c -@@ -110,6 +110,13 @@ +@@ -103,6 +103,13 @@ #include "srclimit.h" #include "dh.h" @@ -119,8 +119,8 @@ index 03a028c82..f36d58b1b 100644 + /* Re-exec fds */ #define REEXEC_DEVCRYPTO_RESERVED_FD (STDERR_FILENO + 1) - #define REEXEC_STARTUP_PIPE_FD (STDERR_FILENO + 2) -@@ -1256,6 +1263,24 @@ main(int ac, char **av) + #define REEXEC_CONFIG_PASS_FD (STDERR_FILENO + 2) +@@ -1215,6 +1222,24 @@ main(int ac, char **av) #ifdef SSH_AUDIT_EVENTS audit_connection_from(remote_ip, remote_port); #endif @@ -146,7 +146,7 @@ index 03a028c82..f36d58b1b 100644 rdomain = ssh_packet_rdomain_in(ssh); diff --git a/sshd.8 b/sshd.8 -index 08ebf53a1..464d402f6 100644 +index 7fbca776a..1cec2fd2c 100644 --- a/sshd.8 +++ b/sshd.8 @@ -925,6 +925,12 @@ the user's home directory becomes accessible. diff --git a/debian/patches/revert-ipqos-defaults.patch b/debian/patches/revert-ipqos-defaults.patch deleted file mode 100644 index cf61453..0000000 --- a/debian/patches/revert-ipqos-defaults.patch +++ /dev/null @@ -1,93 +0,0 @@ -From bef41555f2e735bffe89e91d4e9f5b4b157d7663 Mon Sep 17 00:00:00 2001 -From: Colin Watson -Date: Mon, 8 Apr 2019 10:46:29 +0100 -Subject: Revert "upstream: Update default IPQoS in ssh(1), sshd(8) to DSCP - AF21 for" - -This reverts commit 5ee8448ad7c306f05a9f56769f95336a8269f379. - -The IPQoS default changes have some unfortunate interactions with -iptables (see https://bugs.debian.org/923880) and VMware, so I'm -temporarily reverting them until those have been fixed. - -Bug-Debian: https://bugs.debian.org/923879 -Bug-Debian: https://bugs.debian.org/926229 -Bug-Ubuntu: https://bugs.launchpad.net/bugs/1822370 -Last-Update: 2019-04-08 - -Patch-Name: revert-ipqos-defaults.patch ---- - readconf.c | 4 ++-- - servconf.c | 4 ++-- - ssh_config.5 | 6 ++---- - sshd_config.5 | 6 ++---- - 4 files changed, 8 insertions(+), 12 deletions(-) - -diff --git a/readconf.c b/readconf.c -index 90bf74f32..a321e6d8f 100644 ---- a/readconf.c -+++ b/readconf.c -@@ -2925,9 +2925,9 @@ fill_default_options(Options * options) - if (options->visual_host_key == -1) - options->visual_host_key = 0; - if (options->ip_qos_interactive == -1) -- options->ip_qos_interactive = IPTOS_DSCP_AF21; -+ options->ip_qos_interactive = IPTOS_LOWDELAY; - if (options->ip_qos_bulk == -1) -- options->ip_qos_bulk = IPTOS_DSCP_CS1; -+ options->ip_qos_bulk = IPTOS_THROUGHPUT; - if (options->request_tty == -1) - options->request_tty = REQUEST_TTY_AUTO; - if (options->session_type == -1) -diff --git a/servconf.c b/servconf.c -index 49a066df8..3c7ca3287 100644 ---- a/servconf.c -+++ b/servconf.c -@@ -483,9 +483,9 @@ fill_default_server_options(ServerOptions *options) - if (options->permit_tun == -1) - options->permit_tun = SSH_TUNMODE_NO; - if (options->ip_qos_interactive == -1) -- options->ip_qos_interactive = IPTOS_DSCP_AF21; -+ options->ip_qos_interactive = IPTOS_LOWDELAY; - if (options->ip_qos_bulk == -1) -- options->ip_qos_bulk = IPTOS_DSCP_CS1; -+ options->ip_qos_bulk = IPTOS_THROUGHPUT; - if (options->version_addendum == NULL) - options->version_addendum = xstrdup(""); - if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1) -diff --git a/ssh_config.5 b/ssh_config.5 -index 9adc0fdb7..14042dce5 100644 ---- a/ssh_config.5 -+++ b/ssh_config.5 -@@ -1329,11 +1329,9 @@ 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) -+.Cm lowdelay - for interactive sessions and --.Cm cs1 --(Lower Effort) -+.Cm throughput - for non-interactive sessions. - .It Cm KbdInteractiveAuthentication - Specifies whether to use keyboard-interactive authentication. -diff --git a/sshd_config.5 b/sshd_config.5 -index 2887ed531..70d57bfdb 100644 ---- a/sshd_config.5 -+++ b/sshd_config.5 -@@ -1022,11 +1022,9 @@ 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) -+.Cm lowdelay - for interactive sessions and --.Cm cs1 --(Lower Effort) -+.Cm throughput - for non-interactive sessions. - .It Cm KbdInteractiveAuthentication - Specifies whether to allow keyboard-interactive authentication. diff --git a/debian/patches/scp-quoting.patch b/debian/patches/scp-quoting.patch index c564c14..a10b8a2 100644 --- a/debian/patches/scp-quoting.patch +++ b/debian/patches/scp-quoting.patch @@ -1,4 +1,4 @@ -From 7df75a1b544e1ac75377d4968b1171e005a3625e Mon Sep 17 00:00:00 2001 +From 431f2e26ceab9ec5cc4447c254cfaf0a0d6939cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20Valc=C3=A1rcel?= Date: Sun, 9 Feb 2014 16:09:59 +0000 Subject: Adjust scp quoting in verbose mode @@ -17,10 +17,10 @@ Patch-Name: scp-quoting.patch 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/scp.c b/scp.c -index 0779c3c2b..4f8c691b3 100644 +index c5f573cc1..9ac23096d 100644 --- a/scp.c +++ b/scp.c -@@ -241,8 +241,16 @@ do_local_cmd(arglist *a) +@@ -225,8 +225,16 @@ do_local_cmd(arglist *a) if (verbose_mode) { fprintf(stderr, "Executing:"); diff --git a/debian/patches/selinux-role.patch b/debian/patches/selinux-role.patch index 1a531a0..2a2cd77 100644 --- a/debian/patches/selinux-role.patch +++ b/debian/patches/selinux-role.patch @@ -1,4 +1,4 @@ -From c787621f9bfda401c9a289a8e0cfd00f242aad86 Mon Sep 17 00:00:00 2001 +From 702e3e70e2ac70b523043abc9918a22450d69ae4 Mon Sep 17 00:00:00 2001 From: Manoj Srivastava Date: Sun, 9 Feb 2014 16:09:49 +0000 Subject: Handle SELinux authorisation roles @@ -43,7 +43,7 @@ index 98bb23d4c..59799a812 100644 /* Method lists for multiple authentication */ char **auth_methods; /* modified from server config */ diff --git a/auth2.c b/auth2.c -index f75f1d20d..44558851e 100644 +index 03a126ba4..8e3595ab6 100644 --- a/auth2.c +++ b/auth2.c @@ -272,7 +272,7 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh) @@ -80,10 +80,10 @@ index f75f1d20d..44558851e 100644 if ((r = kex_server_update_ext_info(ssh)) != 0) fatal_fr(r, "kex_server_update_ext_info failed"); diff --git a/monitor.c b/monitor.c -index ad7fef5a9..05d63a8ee 100644 +index 51dcdb66e..7c568778d 100644 --- a/monitor.c +++ b/monitor.c -@@ -118,6 +118,7 @@ int mm_answer_sign(struct ssh *, int, struct sshbuf *); +@@ -110,6 +110,7 @@ int mm_answer_sign(struct ssh *, int, struct sshbuf *); int mm_answer_pwnamallow(struct ssh *, int, struct sshbuf *); int mm_answer_auth2_read_banner(struct ssh *, int, struct sshbuf *); int mm_answer_authserv(struct ssh *, int, struct sshbuf *); @@ -91,7 +91,7 @@ index ad7fef5a9..05d63a8ee 100644 int mm_answer_authpassword(struct ssh *, int, struct sshbuf *); int mm_answer_bsdauthquery(struct ssh *, int, struct sshbuf *); int mm_answer_bsdauthrespond(struct ssh *, int, struct sshbuf *); -@@ -192,6 +193,7 @@ struct mon_table mon_dispatch_proto20[] = { +@@ -186,6 +187,7 @@ struct mon_table mon_dispatch_proto20[] = { {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign}, {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow}, {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv}, @@ -99,7 +99,7 @@ index ad7fef5a9..05d63a8ee 100644 {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner}, {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, #ifdef USE_PAM -@@ -842,6 +844,7 @@ mm_answer_pwnamallow(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -936,6 +938,7 @@ mm_answer_pwnamallow(struct ssh *ssh, int sock, struct sshbuf *m) /* Allow service/style information on the auth context */ monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1); @@ -107,7 +107,7 @@ index ad7fef5a9..05d63a8ee 100644 monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1); #ifdef USE_PAM -@@ -875,15 +878,42 @@ mm_answer_authserv(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -969,15 +972,42 @@ mm_answer_authserv(struct ssh *ssh, int sock, struct sshbuf *m) monitor_permit_authentications(1); if ((r = sshbuf_get_cstring(m, &authctxt->service, NULL)) != 0 || @@ -152,7 +152,7 @@ index ad7fef5a9..05d63a8ee 100644 return (0); } -@@ -1604,7 +1634,7 @@ mm_answer_pty(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -1697,7 +1727,7 @@ mm_answer_pty(struct ssh *ssh, int sock, struct sshbuf *m) res = pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty)); if (res == 0) goto error; @@ -162,10 +162,10 @@ index ad7fef5a9..05d63a8ee 100644 if ((r = sshbuf_put_u32(m, 1)) != 0 || (r = sshbuf_put_cstring(m, s->tty)) != 0) diff --git a/monitor.h b/monitor.h -index 7d8f3c6fa..d84415fe2 100644 +index 4076f71ea..1eda94540 100644 --- a/monitor.h +++ b/monitor.h -@@ -65,6 +65,8 @@ enum monitor_reqtype { +@@ -66,6 +66,8 @@ enum monitor_reqtype { MONITOR_REQ_GSSSIGN = 150, MONITOR_ANS_GSSSIGN = 151, MONITOR_REQ_GSSUPCREDS = 152, MONITOR_ANS_GSSUPCREDS = 153, @@ -175,10 +175,10 @@ index 7d8f3c6fa..d84415fe2 100644 struct ssh; diff --git a/monitor_wrap.c b/monitor_wrap.c -index cb3261b4d..60c339d02 100644 +index 13bd07bfd..be9d26dcb 100644 --- a/monitor_wrap.c +++ b/monitor_wrap.c -@@ -431,10 +431,10 @@ mm_auth2_read_banner(void) +@@ -432,10 +432,10 @@ mm_auth2_read_banner(void) return (banner); } @@ -191,7 +191,7 @@ index cb3261b4d..60c339d02 100644 { struct sshbuf *m; int r; -@@ -444,7 +444,8 @@ mm_inform_authserv(char *service, char *style) +@@ -445,7 +445,8 @@ mm_inform_authserv(char *service, char *style) if ((m = sshbuf_new()) == NULL) fatal_f("sshbuf_new failed"); if ((r = sshbuf_put_cstring(m, service)) != 0 || @@ -201,7 +201,7 @@ index cb3261b4d..60c339d02 100644 fatal_fr(r, "assemble"); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHSERV, m); -@@ -452,6 +453,26 @@ mm_inform_authserv(char *service, char *style) +@@ -453,6 +454,26 @@ mm_inform_authserv(char *service, char *style) sshbuf_free(m); } @@ -229,10 +229,10 @@ index cb3261b4d..60c339d02 100644 int mm_auth_password(struct ssh *ssh, char *password) diff --git a/monitor_wrap.h b/monitor_wrap.h -index 09b0ccaaa..2493da591 100644 +index 7493cd01b..345df0bc4 100644 --- a/monitor_wrap.h +++ b/monitor_wrap.h -@@ -45,7 +45,8 @@ DH *mm_choose_dh(int, int, int); +@@ -49,7 +49,8 @@ DH *mm_choose_dh(int, int, int); int mm_sshkey_sign(struct ssh *, struct sshkey *, u_char **, size_t *, const u_char *, size_t, const char *, const char *, const char *, u_int compat); @@ -243,7 +243,7 @@ index 09b0ccaaa..2493da591 100644 char *mm_auth2_read_banner(void); int mm_auth_password(struct ssh *, char *); diff --git a/openbsd-compat/port-linux.c b/openbsd-compat/port-linux.c -index 8adfec5a7..61e239561 100644 +index c1d54f38d..1fd3bfa81 100644 --- a/openbsd-compat/port-linux.c +++ b/openbsd-compat/port-linux.c @@ -65,7 +65,7 @@ ssh_selinux_enabled(void) @@ -311,7 +311,7 @@ index 8adfec5a7..61e239561 100644 /* XXX: should these calls fatal() upon failure in enforcing mode? */ diff --git a/openbsd-compat/port-linux.h b/openbsd-compat/port-linux.h -index 14064f87d..6c4c37115 100644 +index 959430de1..7f9a7c195 100644 --- a/openbsd-compat/port-linux.h +++ b/openbsd-compat/port-linux.h @@ -19,8 +19,8 @@ @@ -326,7 +326,7 @@ index 14064f87d..6c4c37115 100644 void ssh_selinux_setfscreatecon(const char *); #endif diff --git a/platform.c b/platform.c -index 4c4fe57ea..f3dc7c3a8 100644 +index fd1a7a7c2..3e7028cff 100644 --- a/platform.c +++ b/platform.c @@ -99,7 +99,7 @@ platform_setusercontext(struct passwd *pw) @@ -348,11 +348,11 @@ index 4c4fe57ea..f3dc7c3a8 100644 } diff --git a/platform.h b/platform.h -index 5dec23276..1b77c3e3d 100644 +index 08cbd225d..2a7364578 100644 --- a/platform.h +++ b/platform.h -@@ -26,7 +26,7 @@ void platform_post_fork_parent(pid_t child_pid); - void platform_post_fork_child(void); +@@ -27,7 +27,7 @@ void platform_post_fork_child(void); + void platform_pre_session_start(void); int platform_privileged_uidswap(void); void platform_setusercontext(struct passwd *); -void platform_setusercontext_post_groups(struct passwd *); @@ -361,10 +361,10 @@ index 5dec23276..1b77c3e3d 100644 char *platform_krb5_get_principal_name(const char *); int platform_locked_account(struct passwd *); diff --git a/session.c b/session.c -index 3d9a16b1e..1c67f9fd1 100644 +index b8f0c1a58..e6c4b8781 100644 --- a/session.c +++ b/session.c -@@ -1344,7 +1344,7 @@ safely_chroot(const char *path, uid_t uid) +@@ -1306,7 +1306,7 @@ safely_chroot(const char *path, uid_t uid) /* Set login name, uid, gid, and groups. */ void @@ -373,7 +373,7 @@ index 3d9a16b1e..1c67f9fd1 100644 { char uidstr[32], *chroot_path, *tmp; -@@ -1372,7 +1372,7 @@ do_setusercontext(struct passwd *pw) +@@ -1334,7 +1334,7 @@ do_setusercontext(struct passwd *pw) endgrent(); #endif @@ -382,7 +382,7 @@ index 3d9a16b1e..1c67f9fd1 100644 if (!in_chroot && options.chroot_directory != NULL && strcasecmp(options.chroot_directory, "none") != 0) { -@@ -1516,7 +1516,7 @@ do_child(struct ssh *ssh, Session *s, const char *command) +@@ -1477,7 +1477,7 @@ do_child(struct ssh *ssh, Session *s, const char *command) /* Force a password change */ if (s->authctxt->force_pwchange) { @@ -391,7 +391,7 @@ index 3d9a16b1e..1c67f9fd1 100644 child_close_fds(ssh); do_pwchange(s); exit(1); -@@ -1534,7 +1534,7 @@ do_child(struct ssh *ssh, Session *s, const char *command) +@@ -1495,7 +1495,7 @@ do_child(struct ssh *ssh, Session *s, const char *command) /* When PAM is enabled we rely on it to do the nologin check */ if (!options.use_pam) do_nologin(pw); @@ -414,10 +414,10 @@ index 344a1ddf9..20ea822a7 100644 const char *session_get_remote_name_or_ip(struct ssh *, u_int, int); diff --git a/sshd-session.c b/sshd-session.c -index f36d58b1b..1d7cdd00a 100644 +index 8e0fe2cd5..307088717 100644 --- a/sshd-session.c +++ b/sshd-session.c -@@ -440,7 +440,7 @@ privsep_postauth(struct ssh *ssh, Authctxt *authctxt) +@@ -449,7 +449,7 @@ privsep_postauth(struct ssh *ssh, Authctxt *authctxt) /* Drop privileges */ if (!skip_privdrop) @@ -427,10 +427,10 @@ index f36d58b1b..1d7cdd00a 100644 /* It is safe now to apply the key state */ monitor_apply_keystate(ssh, pmonitor); diff --git a/sshpty.c b/sshpty.c -index cae0b977a..7870c6482 100644 +index 0a82b7d3b..7dff5486c 100644 --- a/sshpty.c +++ b/sshpty.c -@@ -163,7 +163,7 @@ pty_change_window_size(int ptyfd, u_int row, u_int col, +@@ -159,7 +159,7 @@ pty_change_window_size(int ptyfd, u_int row, u_int col, } void @@ -439,7 +439,7 @@ index cae0b977a..7870c6482 100644 { struct group *grp; gid_t gid; -@@ -187,7 +187,7 @@ pty_setowner(struct passwd *pw, const char *tty) +@@ -183,7 +183,7 @@ pty_setowner(struct passwd *pw, const char *tty) strerror(errno)); #ifdef WITH_SELINUX diff --git a/debian/patches/series b/debian/patches/series index 9f05c67..05e2f09 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -16,19 +16,11 @@ openbsd-docs.patch ssh-argv0.patch doc-hash-tab-completion.patch ssh-agent-setgid.patch -no-openssl-version-status.patch gnome-ssh-askpass2-icon.patch debian-config.patch restore-authorized_keys2.patch -revert-ipqos-defaults.patch systemd-socket-activation.patch skip-utimensat-test-on-zfs.patch regress-conch-dev-zero.patch -configure-cache-vars.patch -pam-avoid-unknown-host.patch -# mlkem768x25519-big-endian-1.patch -# mlkem768x25519-big-endian-2.patch -deepin-extra-version.patch -deepin-ssh-connect-idle-timeout.patch -deepin-ssh-keygen-privatekey-file-perm.patch -add-sm-support.patch +downgrade-pkcs11-error.patch +link-ssh-against-ssh-pkcs11.patch diff --git a/debian/patches/shell-path.patch b/debian/patches/shell-path.patch index e4f84ed..123500e 100644 --- a/debian/patches/shell-path.patch +++ b/debian/patches/shell-path.patch @@ -1,4 +1,4 @@ -From db03f4eab3e6e03b8568629aee068e7221d03c51 Mon Sep 17 00:00:00 2001 +From ab202be6b58b0946159f826cdf00d3a61c31670e Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Sun, 9 Feb 2014 16:10:00 +0000 Subject: Look for $SHELL on the path for ProxyCommand/LocalCommand @@ -16,10 +16,10 @@ Patch-Name: shell-path.patch 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sshconnect.c b/sshconnect.c -index 7cf6b6386..1b7e804fb 100644 +index 912a520c5..b21b7cb68 100644 --- a/sshconnect.c +++ b/sshconnect.c -@@ -248,7 +248,7 @@ ssh_proxy_connect(struct ssh *ssh, const char *host, const char *host_arg, +@@ -240,7 +240,7 @@ ssh_proxy_connect(struct ssh *ssh, const char *host, const char *host_arg, * extra privileges above. */ ssh_signal(SIGPIPE, SIG_DFL); @@ -28,7 +28,7 @@ index 7cf6b6386..1b7e804fb 100644 perror(argv[0]); exit(1); } -@@ -1710,7 +1710,7 @@ ssh_local_cmd(const char *args) +@@ -1712,7 +1712,7 @@ ssh_local_cmd(const char *args) if (pid == 0) { ssh_signal(SIGPIPE, SIG_DFL); debug3("Executing %s -c \"%s\"", shell, args); diff --git a/debian/patches/skip-utimensat-test-on-zfs.patch b/debian/patches/skip-utimensat-test-on-zfs.patch index ced2069..abbc523 100644 --- a/debian/patches/skip-utimensat-test-on-zfs.patch +++ b/debian/patches/skip-utimensat-test-on-zfs.patch @@ -1,4 +1,4 @@ -From 956df1764a7c31f5250122ee0642adf561b6ca41 Mon Sep 17 00:00:00 2001 +From 3c0f5dd2c5d06d13dec414a39107a86f28be8ecb Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 11 Mar 2024 16:24:49 +0000 Subject: Skip utimensat test on ZFS @@ -15,7 +15,7 @@ Patch-Name: skip-utimensat-test-on-zfs.patch 1 file changed, 17 insertions(+) diff --git a/openbsd-compat/regress/utimensattest.c b/openbsd-compat/regress/utimensattest.c -index bbc66c485..662d58146 100644 +index b4405e464..1bd72f5c7 100644 --- a/openbsd-compat/regress/utimensattest.c +++ b/openbsd-compat/regress/utimensattest.c @@ -33,6 +33,12 @@ diff --git a/debian/patches/ssh-agent-setgid.patch b/debian/patches/ssh-agent-setgid.patch index 7799528..fdc3864 100644 --- a/debian/patches/ssh-agent-setgid.patch +++ b/debian/patches/ssh-agent-setgid.patch @@ -1,4 +1,4 @@ -From da7a6ece81d3c8ed572e9b8188975c0f787ee57a Mon Sep 17 00:00:00 2001 +From ba86d5eae8b1aaefddcbdbe867b5b613c0821788 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Sun, 9 Feb 2014 16:10:13 +0000 Subject: Document consequences of ssh-agent being setgid in ssh-agent(1) @@ -13,10 +13,10 @@ Patch-Name: ssh-agent-setgid.patch 1 file changed, 15 insertions(+) diff --git a/ssh-agent.1 b/ssh-agent.1 -index 0b93d03a3..1ab7d729d 100644 +index f77a6cdd5..3498be25e 100644 --- a/ssh-agent.1 +++ b/ssh-agent.1 -@@ -248,6 +248,21 @@ socket and stores its pathname in this variable. +@@ -306,6 +306,21 @@ 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 @@ -37,4 +37,4 @@ index 0b93d03a3..1ab7d729d 100644 +so in the program executed by ssh-agent. .Sh FILES .Bl -tag -width Ds - .It Pa $TMPDIR/ssh-XXXXXXXXXX/agent. + .It Pa $HOME/.ssh/agent/s.* diff --git a/debian/patches/ssh-argv0.patch b/debian/patches/ssh-argv0.patch index 6cac7ba..140d008 100644 --- a/debian/patches/ssh-argv0.patch +++ b/debian/patches/ssh-argv0.patch @@ -1,4 +1,4 @@ -From 9c28130b8475e321fb7f5d83f54de7725e53238e Mon Sep 17 00:00:00 2001 +From f1df848391c33659f71d6302396635e2163f67d4 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Sun, 9 Feb 2014 16:10:10 +0000 Subject: ssh(1): Refer to ssh-argv0(1) @@ -18,10 +18,10 @@ Patch-Name: ssh-argv0.patch 1 file changed, 1 insertion(+) diff --git a/ssh.1 b/ssh.1 -index d80ce6bfc..3ad246c27 100644 +index 62bb40a50..3d849f02c 100644 --- a/ssh.1 +++ b/ssh.1 -@@ -1668,6 +1668,7 @@ if an error occurred. +@@ -1678,6 +1678,7 @@ if an error occurred. .Xr sftp 1 , .Xr ssh-add 1 , .Xr ssh-agent 1 , diff --git a/debian/patches/ssh-vulnkey-compat.patch b/debian/patches/ssh-vulnkey-compat.patch index 7b23f6b..fe91004 100644 --- a/debian/patches/ssh-vulnkey-compat.patch +++ b/debian/patches/ssh-vulnkey-compat.patch @@ -1,4 +1,4 @@ -From 9082cd8deab422393c5eee898a77f7dd2b505711 Mon Sep 17 00:00:00 2001 +From d0b87a587249b641701f44590599b72140d7c6dc Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Sun, 9 Feb 2014 16:09:50 +0000 Subject: Accept obsolete ssh-vulnkey configuration options @@ -17,10 +17,10 @@ Patch-Name: ssh-vulnkey-compat.patch 2 files changed, 2 insertions(+) diff --git a/readconf.c b/readconf.c -index 0ce392538..08342f2a2 100644 +index 0ae88a8f9..0e91bb243 100644 --- a/readconf.c +++ b/readconf.c -@@ -197,6 +197,7 @@ static struct { +@@ -193,6 +193,7 @@ static struct { { "fallbacktorsh", oDeprecated }, { "globalknownhostsfile2", oDeprecated }, { "rhostsauthentication", oDeprecated }, @@ -29,10 +29,10 @@ index 0ce392538..08342f2a2 100644 { "useroaming", oDeprecated }, { "usersh", oDeprecated }, diff --git a/servconf.c b/servconf.c -index 731f208be..1d5c143ba 100644 +index 3283e2648..a7a4a0098 100644 --- a/servconf.c +++ b/servconf.c -@@ -698,6 +698,7 @@ static struct { +@@ -696,6 +696,7 @@ static struct { { "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL }, { "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL }, { "strictmodes", sStrictModes, SSHCFG_GLOBAL }, diff --git a/debian/patches/syslog-level-silent.patch b/debian/patches/syslog-level-silent.patch index a533947..a874b49 100644 --- a/debian/patches/syslog-level-silent.patch +++ b/debian/patches/syslog-level-silent.patch @@ -1,4 +1,4 @@ -From fd1b38447970e7a0d5d567571f3bad35db4da90d Mon Sep 17 00:00:00 2001 +From a2728f68b4934d480c80474cab91fda0aa9928f5 Mon Sep 17 00:00:00 2001 From: Natalie Amery Date: Sun, 9 Feb 2014 16:09:54 +0000 Subject: "LogLevel SILENT" compatibility @@ -21,10 +21,10 @@ Patch-Name: syslog-level-silent.patch 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/log.c b/log.c -index 23ad10c02..133b5fa7d 100644 +index 5969c4a16..ffc304527 100644 --- a/log.c +++ b/log.c -@@ -96,6 +96,7 @@ static struct { +@@ -98,6 +98,7 @@ static struct { LogLevel val; } log_levels[] = { @@ -33,10 +33,10 @@ index 23ad10c02..133b5fa7d 100644 { "FATAL", SYSLOG_LEVEL_FATAL }, { "ERROR", SYSLOG_LEVEL_ERROR }, diff --git a/ssh.c b/ssh.c -index 484a26528..925d5c0f6 100644 +index 8d27f6379..7eabc7370 100644 --- a/ssh.c +++ b/ssh.c -@@ -1412,7 +1412,7 @@ main(int ac, char **av) +@@ -1445,7 +1445,7 @@ main(int ac, char **av) /* Do not allocate a tty if stdin is not a tty. */ if ((!isatty(fileno(stdin)) || options.stdin_null) && options.request_tty != REQUEST_TTY_FORCE) { diff --git a/debian/patches/systemd-socket-activation.patch b/debian/patches/systemd-socket-activation.patch index e3462ae..c89f9d9 100644 --- a/debian/patches/systemd-socket-activation.patch +++ b/debian/patches/systemd-socket-activation.patch @@ -1,4 +1,4 @@ -From ea15be5452914d4dcf291228c73e7dfa4550537b Mon Sep 17 00:00:00 2001 +From 9504e97e8a60f45edcea3831ee52c5c641ca4181 Mon Sep 17 00:00:00 2001 From: Steve Langasek Date: Thu, 1 Sep 2022 16:03:37 +0100 Subject: Support systemd socket activation @@ -10,38 +10,37 @@ of the sshd daemon without becoming incompatible with config options like ClientAliveCountMax. Author: Colin Watson -Last-Update: 2024-08-02 +Last-Update: 2025-04-11 Patch-Name: systemd-socket-activation.patch --- configure.ac | 1 + - sshd.c | 133 +++++++++++++++++++++++++++++++++++++++++++++------ - 2 files changed, 119 insertions(+), 15 deletions(-) + sshd.c | 131 +++++++++++++++++++++++++++++++++++++++++++++------ + 2 files changed, 118 insertions(+), 14 deletions(-) diff --git a/configure.ac b/configure.ac -index 90548dcfc..8b3a9776b 100644 +index d6783774b..9854ffd28 100644 --- a/configure.ac +++ b/configure.ac -@@ -940,6 +940,7 @@ int main(void) { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) - AC_DEFINE([USE_BTMP]) - AC_DEFINE([LINUX_OOM_ADJUST], [1], [Adjust Linux out-of-memory killer]) +@@ -1001,6 +1001,7 @@ int main(void) { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) + ) + AC_DEFINE([SYSTEMD_NOTIFY], [1], [Have sshd notify systemd on start/reload]) + AC_DEFINE([SYSTEMD_SOCKET_ACTIVATION], [1], [Have sshd accept systemd socket activation]) inet6_default_4in6=yes case `uname -r` in 1.*|2.0.*) diff --git a/sshd.c b/sshd.c -index 48b334c68..142310c07 100644 +index 3ab81e268..7ba0f753a 100644 --- a/sshd.c +++ b/sshd.c -@@ -93,10 +93,18 @@ - #include "srclimit.h" +@@ -92,9 +92,17 @@ + #include "monitor_wrap.h" /* 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) +-#define REEXEC_CONFIG_PASS_FD (STDERR_FILENO + 2) +-#define REEXEC_MIN_FREE_FD (STDERR_FILENO + 3) +#ifdef SYSTEMD_SOCKET_ACTIVATION +static int get_systemd_listen_fds(void); +#define SYSTEMD_OFFSET get_systemd_listen_fds() @@ -51,14 +50,13 @@ index 48b334c68..142310c07 100644 +#endif + +#define REEXEC_DEVCRYPTO_RESERVED_FD (STDERR_FILENO + 1 + SYSTEMD_OFFSET) -+#define REEXEC_STARTUP_PIPE_FD (STDERR_FILENO + 2 + SYSTEMD_OFFSET) -+#define REEXEC_CONFIG_PASS_FD (STDERR_FILENO + 3 + SYSTEMD_OFFSET) -+#define REEXEC_MIN_FREE_FD (STDERR_FILENO + 4 + SYSTEMD_OFFSET) ++#define REEXEC_CONFIG_PASS_FD (STDERR_FILENO + 2 + SYSTEMD_OFFSET) ++#define REEXEC_MIN_FREE_FD (STDERR_FILENO + 3 + SYSTEMD_OFFSET) extern char *__progname; -@@ -740,6 +748,88 @@ send_rexec_state(int fd, struct sshbuf *conf) - debug3_f("done"); +@@ -801,6 +809,88 @@ send_rexec_state(int fd) + exit(0); } +#ifdef SYSTEMD_SOCKET_ACTIVATION @@ -146,7 +144,7 @@ index 48b334c68..142310c07 100644 /* * Listen for TCP connections */ -@@ -819,6 +909,9 @@ static void +@@ -880,6 +970,9 @@ static void server_listen(void) { u_int i; @@ -156,7 +154,7 @@ index 48b334c68..142310c07 100644 /* Initialise per-source limit tracking. */ srclimit_init(options.max_startups, -@@ -828,17 +921,27 @@ server_listen(void) +@@ -889,17 +982,27 @@ server_listen(void) &options.per_source_penalty, options.per_source_penalty_exempt); @@ -194,7 +192,7 @@ index 48b334c68..142310c07 100644 if (!num_listen_socks) fatal("Cannot bind any address."); } -@@ -1351,7 +1454,7 @@ main(int ac, char **av) +@@ -1463,7 +1566,7 @@ main(int ac, char **av) if (!test_flag && !inetd_flag && !do_dump_cfg && !path_absolute(av[0])) fatal("sshd requires execution with an absolute path"); diff --git a/debian/patches/user-group-modes.patch b/debian/patches/user-group-modes.patch index a67bca8..28e5d2a 100644 --- a/debian/patches/user-group-modes.patch +++ b/debian/patches/user-group-modes.patch @@ -1,4 +1,4 @@ -From a3be0a7259302fe037d63546c78c5d3ca7fe3609 Mon Sep 17 00:00:00 2001 +From b6c8da512960cfc7e202d02bb94ced87a9b92bd0 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Sun, 9 Feb 2014 16:09:58 +0000 Subject: Allow harmless group-writability @@ -13,24 +13,24 @@ default. Bug: https://bugzilla.mindrot.org/show_bug.cgi?id=1060 Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=314347 -Last-Update: 2022-02-23 +Last-Update: 2025-10-06 Patch-Name: user-group-modes.patch --- auth-rhosts.c | 6 ++---- auth.c | 3 +-- - misc.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++----- + misc.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++---- misc.h | 2 ++ readconf.c | 3 +-- ssh.1 | 2 ++ ssh_config.5 | 2 ++ - 7 files changed, 62 insertions(+), 13 deletions(-) + 7 files changed, 61 insertions(+), 12 deletions(-) diff --git a/auth-rhosts.c b/auth-rhosts.c -index d5d2c7a12..13c3c201b 100644 +index 031186f24..560a0b894 100644 --- a/auth-rhosts.c +++ b/auth-rhosts.c -@@ -265,8 +265,7 @@ auth_rhosts2(struct passwd *pw, const char *client_user, const char *hostname, +@@ -263,8 +263,7 @@ auth_rhosts2(struct passwd *pw, const char *client_user, const char *hostname, return 0; } if (options.strict_modes && @@ -40,7 +40,7 @@ index d5d2c7a12..13c3c201b 100644 logit("Rhosts authentication refused for %.100s: " "bad ownership or modes for home directory.", pw->pw_name); auth_debug_add("Rhosts authentication refused for %.100s: " -@@ -295,8 +294,7 @@ auth_rhosts2(struct passwd *pw, const char *client_user, const char *hostname, +@@ -293,8 +292,7 @@ auth_rhosts2(struct passwd *pw, const char *client_user, const char *hostname, * allowing access to their account by anyone. */ if (options.strict_modes && @@ -51,10 +51,10 @@ index d5d2c7a12..13c3c201b 100644 "bad modes for %.200s", pw->pw_name, path); auth_debug_add("Bad file modes for %.200s", path); diff --git a/auth.c b/auth.c -index e4578169b..4b878865f 100644 +index d25653ee4..f075355e7 100644 --- a/auth.c +++ b/auth.c -@@ -430,8 +430,7 @@ check_key_in_hostfiles(struct passwd *pw, struct sshkey *key, const char *host, +@@ -428,8 +428,7 @@ check_key_in_hostfiles(struct passwd *pw, struct sshkey *key, const char *host, user_hostfile = tilde_expand_filename(userfile, pw->pw_uid); if (options.strict_modes && (stat(user_hostfile, &st) == 0) && @@ -65,21 +65,10 @@ index e4578169b..4b878865f 100644 "bad owner or modes for %.200s", pw->pw_name, user_hostfile); diff --git a/misc.c b/misc.c -index afdf5142e..8776fc1dc 100644 +index ce77ec943..3c1a6751f 100644 --- a/misc.c +++ b/misc.c -@@ -62,9 +62,9 @@ - #include - #ifdef HAVE_PATHS_H - # include -+#endif - #include - #include --#endif - #ifdef SSH_TUN_OPENBSD - #include - #endif -@@ -1428,6 +1428,55 @@ percent_dollar_expand(const char *string, ...) +@@ -1466,6 +1466,55 @@ percent_dollar_expand(const char *string, ...) return ret; } @@ -135,7 +124,7 @@ index afdf5142e..8776fc1dc 100644 int tun_open(int tun, int mode, char **ifname) { -@@ -2250,8 +2299,7 @@ safe_path(const char *name, struct stat *stp, const char *pw_dir, +@@ -2288,8 +2337,7 @@ safe_path(const char *name, struct stat *stp, const char *pw_dir, snprintf(err, errlen, "%s is not a regular file", buf); return -1; } @@ -145,7 +134,7 @@ index afdf5142e..8776fc1dc 100644 snprintf(err, errlen, "bad ownership or modes for file %s", buf); return -1; -@@ -2266,8 +2314,7 @@ safe_path(const char *name, struct stat *stp, const char *pw_dir, +@@ -2309,8 +2357,7 @@ safe_path(const char *name, struct stat *stp, const char *pw_dir, strlcpy(buf, cp, sizeof(buf)); if (stat(buf, &st) == -1 || @@ -156,10 +145,10 @@ index afdf5142e..8776fc1dc 100644 "bad ownership or modes for directory %s", buf); return -1; diff --git a/misc.h b/misc.h -index 113403896..4681f79f7 100644 +index f3c5a18c6..aad15dfbd 100644 --- a/misc.h +++ b/misc.h -@@ -246,6 +246,8 @@ struct notifier_ctx *notify_start(int, const char *, ...) +@@ -254,6 +254,8 @@ struct notifier_ctx *notify_start(int, const char *, ...) void notify_complete(struct notifier_ctx *, const char *, ...) __attribute__((format(printf, 2, 3))); @@ -169,10 +158,10 @@ index 113403896..4681f79f7 100644 #define MAXIMUM(a, b) (((a) > (b)) ? (a) : (b)) #define ROUNDUP(x, y) ((((x)+((y)-1))/(y))*(y)) diff --git a/readconf.c b/readconf.c -index f78786964..d3c3056ef 100644 +index 95d497938..c568697cf 100644 --- a/readconf.c +++ b/readconf.c -@@ -2552,8 +2552,7 @@ read_config_file_depth(const char *filename, struct passwd *pw, +@@ -2674,8 +2674,7 @@ read_config_file_depth(const char *filename, struct passwd *pw, if (fstat(fileno(f), &sb) == -1) fatal("fstat %s: %s", filename, strerror(errno)); @@ -183,10 +172,10 @@ index f78786964..d3c3056ef 100644 } diff --git a/ssh.1 b/ssh.1 -index 8f78b3a1e..d80ce6bfc 100644 +index f83514c8f..62bb40a50 100644 --- a/ssh.1 +++ b/ssh.1 -@@ -1572,6 +1572,8 @@ The file format and configuration options are described in +@@ -1582,6 +1582,8 @@ 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. @@ -196,10 +185,10 @@ index 8f78b3a1e..d80ce6bfc 100644 .It Pa ~/.ssh/environment Contains additional definitions for environment variables; see diff --git a/ssh_config.5 b/ssh_config.5 -index 31142f8c5..073ef69e2 100644 +index 718c870f8..c947aba0a 100644 --- a/ssh_config.5 +++ b/ssh_config.5 -@@ -2417,6 +2417,8 @@ The format of this file is described above. +@@ -2512,6 +2512,8 @@ 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. diff --git a/debian/rules b/debian/rules index e327d0f..38c142b 100755 --- a/debian/rules +++ b/debian/rules @@ -32,10 +32,6 @@ else RUN_TESTS := endif -ifeq ($(DEB_BUILD_ARCH), sw64) - CFLAGS += -fwrapv -fno-strict-overflow -endif - # Change the version string to reflect distribution SSH_EXTRAVERSION := $(DEB_VENDOR)-$(shell echo '$(DEB_VERSION)' | sed -e 's/.*-//; s/+salsaci+.*/+salsaci/') @@ -78,6 +74,10 @@ ifeq ($(DEB_HOST_ARCH),ppc64el) confflags += ossh_cv_cflag__fzero_call_used_regs_used=no endif +# passwd isn't otherwise needed and may not be installed at build time. +# Ensure that sshd knows its path. +confflags += PATH_PASSWD_PROG=/usr/bin/passwd + # Everything above here is common to the deb and udeb builds. confflags_udeb := $(confflags) @@ -87,6 +87,7 @@ confflags += --with-pam confflags += --with-libedit confflags += --with-kerberos5=/usr confflags += --with-ssl-engine +confflags += --with-wtmpdb ifeq ($(DEB_HOST_ARCH_OS),linux) confflags += --with-selinux confflags += --with-audit=linux @@ -131,6 +132,13 @@ ifeq ($(filter noudeb,$(DEB_BUILD_PROFILES)),) cd debian/build-udeb && ./config.status endif + # Nothing reads /var/log/btmp any more (see + # https://bugs.debian.org/1072184). + perl -pi -e 's,.*#define USE_BTMP .*,/* #undef USE_BTMP */,' debian/build-deb/config.h +ifeq ($(filter noudeb,$(DEB_BUILD_PROFILES)),) + perl -pi -e 's,.*#define USE_BTMP .*,/* #undef USE_BTMP */,' debian/build-udeb/config.h +endif + override_dh_auto_configure-indep: override_dh_auto_build-arch: @@ -138,7 +146,7 @@ override_dh_auto_build-arch: $(MAKE) -C debian/build-deb regress-prep $(MAKE) -C debian/build-deb $(PARALLEL) regress-binaries regress-unit-binaries ifeq ($(filter noudeb,$(DEB_BUILD_PROFILES)),) - $(MAKE) -C debian/build-udeb $(PARALLEL) ASKPASS_PROGRAM='/usr/bin/ssh-askpass' ssh scp sftp sshd ssh-keygen sshd-session + $(MAKE) -C debian/build-udeb $(PARALLEL) ASKPASS_PROGRAM='/usr/bin/ssh-askpass' ssh scp sftp sshd ssh-keygen sshd-auth sshd-session endif ifeq ($(filter pkg.openssh.nognome,$(DEB_BUILD_PROFILES)),) @@ -182,10 +190,6 @@ ifeq ($(filter noudeb,$(DEB_BUILD_PROFILES)),) --sourcedir=debian/build-udeb endif - # This can't be done using dh_link, because it's needed earlier by - # dh_installalternatives. - ln -sf ssh debian/openssh-client/usr/bin/slogin - rm -f debian/openssh-tests/usr/lib/openssh/regress/misc/sk-dummy/*.lo override_dh_installdocs: @@ -198,14 +202,15 @@ override_dh_installdocs: override_dh_installinit: dh_installinit -R --name ssh +# Can be dropped in compat level 14 +execute_after_dh_installinit: + dh_installsysusers + override_dh_installsystemd: -ifneq (,$(filter uos Uos,$(shell lsb_release -i -s))) - dh_installsystemd -popenssh-server --no-enable ssh.service -else dh_installsystemd -popenssh-server ssh.service -endif dh_installsystemd -popenssh-server --no-enable ssh.socket dh_installsystemd -popenssh-server --no-start rescue-ssh.target + dh_installsystemd -popenssh-server sshd-keygen.service debian/openssh-server.sshd.pam: debian/openssh-server.sshd.pam.in ifeq ($(DEB_HOST_ARCH_OS),linux) diff --git a/debian/run-tests b/debian/run-tests index df76b7f..aa6dee2 100755 --- a/debian/run-tests +++ b/debian/run-tests @@ -27,12 +27,13 @@ make -C "$tmp/regress" \ SUDO=sudo \ TEST_SHELL=/bin/sh \ TEST_SSH_SSH=/usr/bin/ssh \ + TEST_SSH_SSHD_AUTH=/usr/lib/openssh/sshd-auth \ TEST_SSH_SSHD_SESSION=/usr/lib/openssh/sshd-session \ TEST_SSH_SFTPSERVER=/usr/lib/openssh/sftp-server \ TEST_SSH_PLINK=/usr/bin/plink \ TEST_SSH_PUTTYGEN=/usr/bin/puttygen \ TEST_SSH_CONCH=/usr/bin/conch3 \ - TEST_SSH_DROPBEAR=/usr/bin/dropbear \ + TEST_SSH_DROPBEAR=/usr/sbin/dropbear \ TEST_SSH_DROPBEARKEY=/usr/bin/dropbearkey \ TEST_SSH_DROPBEARCONVERT=/usr/bin/dropbearconvert \ TEST_SSH_DBCLIENT=/usr/bin/dbclient \ diff --git a/debian/systemd/ssh-agent.service b/debian/systemd/ssh-agent.service index 68273bd..de83fe7 100644 --- a/debian/systemd/ssh-agent.service +++ b/debian/systemd/ssh-agent.service @@ -1,17 +1,14 @@ [Unit] Description=OpenSSH Agent Documentation=man:ssh-agent(1) -Before=graphical-session-pre.target -ConditionPathExists=/etc/X11/Xsession.options -Wants=dbus.socket -After=dbus.socket +Requires=ssh-agent.socket [Service] +Environment=SSH_ASKPASS_REQUIRE=force # If you need to pass extra arguments to ssh-agent, you can use "systemctl # --user edit ssh-agent.service" to add a drop-in unit with contents along # these lines: # [Service] # ExecStart= -# ExecStart=/usr/lib/openssh/agent-launch start -- -t 1200 -ExecStart=/usr/lib/openssh/agent-launch start -ExecStopPost=/usr/lib/openssh/agent-launch stop +# ExecStart=/usr/bin/ssh-agent -D -t 1200 +ExecStart=/usr/bin/ssh-agent -D diff --git a/debian/systemd/ssh-agent.socket b/debian/systemd/ssh-agent.socket new file mode 100644 index 0000000..9980c36 --- /dev/null +++ b/debian/systemd/ssh-agent.socket @@ -0,0 +1,13 @@ +[Unit] +Description=OpenSSH Agent socket +Documentation=man:ssh-agent(1) +Before=graphical-session-pre.target + +[Socket] +SocketMode=0600 +ListenStream=%t/openssh_agent +ExecStartPost=/usr/bin/systemctl --user set-environment SSH_AUTH_SOCK=%t/openssh_agent +ExecStopPre=/usr/bin/systemctl --user unset-environment SSH_AUTH_SOCK + +[Install] +WantedBy=sockets.target diff --git a/debian/systemd/ssh-session-cleanup b/debian/systemd/ssh-session-cleanup index f283cc9..3968725 100755 --- a/debian/systemd/ssh-session-cleanup +++ b/debian/systemd/ssh-session-cleanup @@ -1,6 +1,6 @@ #! /bin/sh -ssh_session_pattern='sshd: \S.*@pts/[0-9]+' +ssh_session_pattern='sshd-session: \S.*@pts/[0-9]+' IFS="$IFS@" pgrep -a -f "$ssh_session_pattern" | while read pid daemon user pty; do diff --git a/debian/systemd/sshd-keygen.service b/debian/systemd/sshd-keygen.service new file mode 100644 index 0000000..7ad0460 --- /dev/null +++ b/debian/systemd/sshd-keygen.service @@ -0,0 +1,14 @@ +[Unit] +Description=Generate sshd host keys on first boot +ConditionFirstBoot=yes +ConditionPathIsReadWrite=/etc/ssh +ConditionPathIsSymbolicLink=!/etc/ssh +Before=ssh.service sshd.service sshd@.service + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=ssh-keygen -A + +[Install] +WantedBy=ssh.service sshd.service sshd@.service ssh.socket diff --git a/debian/systemd/sshd@.service b/debian/systemd/sshd@.service index 38ff431..fbdf9ea 100644 --- a/debian/systemd/sshd@.service +++ b/debian/systemd/sshd@.service @@ -5,8 +5,9 @@ After=nss-user-lookup.target auditd.service [Service] EnvironmentFile=-/etc/default/ssh -ExecStart=-/usr/sbin/sshd -i $SSHD_OPTS +ExecStart=-/usr/sbin/sshd -i $SSHD_OPTS -o "AuthorizedKeysFile ${CREDENTIALS_DIRECTORY}/ssh.ephemeral-authorized_keys-all .ssh/authorized_keys" StandardInput=socket RuntimeDirectory=sshd RuntimeDirectoryPreserve=yes RuntimeDirectoryMode=0755 +ImportCredential=ssh.ephemeral-authorized_keys-all diff --git a/debian/tests/control b/debian/tests/control index e138981..56db9fb 100644 --- a/debian/tests/control +++ b/debian/tests/control @@ -3,7 +3,7 @@ Tests: Restrictions: allow-stderr, isolation-container, - needs-root, + needs-sudo, Depends: devscripts, dropbear, @@ -22,6 +22,7 @@ Restrictions: isolation-container, needs-root, Depends: + adduser, krb5-admin-server, krb5-kdc, openssh-server-gssapi, @@ -31,7 +32,7 @@ Tests: Restrictions: allow-stderr, isolation-container, - needs-root, + needs-sudo, Depends: openssh-server, @@ -40,7 +41,7 @@ Tests: Restrictions: allow-stderr, isolation-container, - needs-root, + needs-sudo, Depends: openssh-server, xinetd, diff --git a/debian/tests/regress b/debian/tests/regress index 681f82f..fe1babf 100755 --- a/debian/tests/regress +++ b/debian/tests/regress @@ -1,84 +1,70 @@ #! /bin/sh set -e -if [ "$(id -un)" != openssh-tests ]; then - TMP="$AUTOPKGTEST_TMP/user" - CREATED_RUN_SSHD=false - STARTED_HAVEGED=false - ADDED_HOST=false +# Make sure sshd is on $PATH. +export PATH="/usr/sbin:$PATH" - cleanup () { - if $ADDED_HOST; then - sed -i '/[[:space:]]UNKNOWN$/d' /etc/hosts - fi +CREATED_RUN_SSHD=false +STARTED_HAVEGED=false +ADDED_HOST=false - if $STARTED_HAVEGED; then - if [ -d /run/systemd/system ] && \ - which systemctl >/dev/null 2>&1; then - systemctl disable haveged || true - systemctl stop haveged || true - else - start-stop-daemon --stop --quiet --oknodo \ - --retry=TERM/30/KILL/5 \ - --pidfile "$AUTOPKGTEST_TMP/haveged.pid" \ - --name haveged - fi - fi - rm -f /etc/sudoers.d/openssh-tests - if id openssh-tests >/dev/null 2>&1; then - deluser --remove-home openssh-tests - fi +cleanup () { + if $ADDED_HOST; then + sudo sed -i '/[[:space:]]UNKNOWN$/d' /etc/hosts + fi - if $CREATED_RUN_SSHD; then - rm -rf /run/sshd + if $STARTED_HAVEGED; then + if [ -d /run/systemd/system ] && \ + which systemctl >/dev/null 2>&1; then + sudo systemctl disable haveged || true + sudo systemctl stop haveged || true + else + sudo start-stop-daemon --stop --quiet --oknodo \ + --retry=TERM/30/KILL/5 \ + --pidfile "$AUTOPKGTEST_TMP/haveged.pid" \ + --name haveged fi - } - trap cleanup EXIT - - adduser --disabled-password --gecos 'OpenSSH tests' openssh-tests - usermod -p '*' openssh-tests - cat >/etc/sudoers.d/openssh-tests </dev/null 2>&1; then - systemctl enable haveged || true - systemctl start haveged || true - STARTED_HAVEGED=: - elif ! pidof haveged >/dev/null; then - start-stop-daemon --start --quiet \ - --pidfile "$AUTOPKGTEST_TMP/haveged.pid" \ - --exec /usr/sbin/haveged -- \ - -p "$AUTOPKGTEST_TMP/haveged.pid" - STARTED_HAVEGED=: + if $CREATED_RUN_SSHD; then + sudo rm -rf /run/sshd fi +} +trap cleanup EXIT - # ssh ends up setting PAM_RHOST to "UNKNOWN" during a number of - # regression tests, which causes DNS resolution delays, slowing down - # the test suite substantially and causing the connection-timeout - # tests to fail. The only way to work around this while running - # tests with "UsePAM yes" appears to be to make "UNKNOWN" - # resolvable. - if ! grep -q '[[:space:]]UNKNOWN$' /etc/hosts; then - echo '127.0.0.2 UNKNOWN' >>/etc/hosts - ADDED_HOST=: - fi +sudo chsh -s /bin/bash "$(id -un)" + +# Depending on how the environment is configured, our test dependency on +# openssh-server may not actually started sshd and thus may not have caused +# /run/sshd to be created. +if [ ! -d /run/sshd ]; then + sudo mkdir -m755 /run/sshd + CREATED_RUN_SSHD=: +fi + +# If we're running in a container, haveged may not have started +# automatically. +if [ -d /run/systemd/system ] && which systemctl >/dev/null 2>&1; then + sudo systemctl enable haveged || true + sudo systemctl start haveged || true + STARTED_HAVEGED=: +elif ! pidof haveged >/dev/null; then + sudo start-stop-daemon --start --quiet \ + --pidfile "$AUTOPKGTEST_TMP/haveged.pid" \ + --exec /usr/sbin/haveged -- \ + -p "$AUTOPKGTEST_TMP/haveged.pid" + STARTED_HAVEGED=: +fi - runuser -u openssh-tests env TMP="$TMP" "$0" "$@" - exit "$?" +# ssh ends up setting PAM_RHOST to "UNKNOWN" during a number of regression +# tests, which causes DNS resolution delays, slowing down the test suite +# substantially and causing the connection-timeout tests to fail. The only +# way to work around this while running tests with "UsePAM yes" appears to +# be to make "UNKNOWN" resolvable. +if ! grep -q '[[:space:]]UNKNOWN$' /etc/hosts; then + echo '127.0.0.2 UNKNOWN' | sudo tee -a /etc/hosts >/dev/null + ADDED_HOST=: fi -annotate-output +%H:%M:%S.%N /usr/lib/openssh/regress/run-tests "$TMP" "$@" +annotate-output +%H:%M:%S.%N \ + /usr/lib/openssh/regress/run-tests "$AUTOPKGTEST_TMP" "$@" diff --git a/debian/tests/socket-activation b/debian/tests/socket-activation index 7ee4a92..f5f2ebf 100755 --- a/debian/tests/socket-activation +++ b/debian/tests/socket-activation @@ -1,27 +1,22 @@ #! /bin/sh set -e -testuser="testuser$$" -adduser --quiet --disabled-password --gecos "" "$testuser" -runuser -u "$testuser" -- mkdir -m700 "/home/$testuser/.ssh" -runuser -u "$testuser" -- \ - ssh-keygen -t ed25519 -N '' -f "/home/$testuser/.ssh/id_ed25519" -runuser -u "$testuser" -- \ - cp "/home/$testuser/.ssh/id_ed25519.pub" \ - "/home/$testuser/.ssh/authorized_keys" +sudo chsh -s /bin/bash "$(id -un)" +mkdir -m700 "$HOME/.ssh" +ssh-keygen -t ed25519 -N '' -f "$HOME/.ssh/id_ed25519" +cp "$HOME/.ssh/id_ed25519.pub" "$HOME/.ssh/authorized_keys" cleanup () { if [ $? -ne 0 ]; then echo "## Something failed" echo echo "## ssh server log" - journalctl -b -u ssh.service --lines 100 + sudo journalctl -b -u ssh.service --lines 100 fi } trap cleanup EXIT -systemctl disable --now ssh.service -systemctl enable --now ssh.socket -runuser -u "$testuser" -- \ - ssh -oStrictHostKeyChecking=accept-new "$testuser@localhost" date +sudo systemctl disable --now ssh.service +sudo systemctl enable --now ssh.socket +ssh -oStrictHostKeyChecking=accept-new "$(id -un)@localhost" date diff --git a/debian/tests/xinetd b/debian/tests/xinetd index 4617ce1..caaee77 100755 --- a/debian/tests/xinetd +++ b/debian/tests/xinetd @@ -1,27 +1,23 @@ #! /bin/sh set -e -testuser="testuser$$" -adduser --quiet --disabled-password --gecos "" "$testuser" -runuser -u "$testuser" -- mkdir -m700 "/home/$testuser/.ssh" -runuser -u "$testuser" -- \ - ssh-keygen -t ed25519 -N '' -f "/home/$testuser/.ssh/id_ed25519" -runuser -u "$testuser" -- \ - cp "/home/$testuser/.ssh/id_ed25519.pub" \ - "/home/$testuser/.ssh/authorized_keys" +sudo chsh -s /bin/bash "$(id -un)" +mkdir -m700 "$HOME/.ssh" +ssh-keygen -t ed25519 -N '' -f "$HOME/.ssh/id_ed25519" +cp "$HOME/.ssh/id_ed25519.pub" "$HOME/.ssh/authorized_keys" cleanup () { if [ $? -ne 0 ]; then echo "## Something failed" echo echo "## ssh server log" - journalctl -b -u ssh.service --lines 100 + sudo journalctl -b -u ssh.service --lines 100 fi } trap cleanup EXIT -cat >/etc/xinetd.d/sshd </dev/null </etc/systemd/system/xinetd.service.d/sshd.conf </dev/null <tv_sec == (usp)->tv_sec) ? \ + ((tsp)->tv_nsec cmp (usp)->tv_nsec) : \ + ((tsp)->tv_sec cmp (usp)->tv_sec)) +#endif + #ifndef TIMEVAL_TO_TIMESPEC #define TIMEVAL_TO_TIMESPEC(tv, ts) { \ (ts)->tv_sec = (tv)->tv_sec; \ @@ -646,7 +655,9 @@ struct winsize { # endif /* WORDS_BIGENDIAN */ #endif /* BYTE_ORDER */ -#ifndef HAVE_ENDIAN_H +#if (defined(HAVE_DECL_LE32TOH) && HAVE_DECL_LE32TOH == 0) || \ + (defined(HAVE_DECL_LE64TOH) && HAVE_DECL_LE64TOH == 0) || \ + (defined(HAVE_DECL_HTOLE64) && HAVE_DECL_HTOLE64 == 0) # define openssh_swap32(v) \ (uint32_t)(((uint32_t)(v) & 0xff) << 24 | \ ((uint32_t)(v) & 0xff00) << 8 | \ @@ -662,13 +673,25 @@ struct winsize { ((uint64_t)(v) & 0xff000000000000ULL) >> 40 | \ ((uint64_t)(v) & 0xff00000000000000ULL) >> 56) # ifdef WORDS_BIGENDIAN -# define le32toh(v) (openssh_swap32(v)) -# define le64toh(v) (openssh_swap64(v)) -# define htole64(v) (openssh_swap64(v)) +# if defined(HAVE_DECL_LE32TOH) && HAVE_DECL_LE32TOH == 0 +# define le32toh(v) (openssh_swap32(v)) +# endif +# if defined(HAVE_DECL_LE64TOH) && HAVE_DECL_LE64TOH == 0 +# define le64toh(v) (openssh_swap64(v)) +# endif +# if defined(HAVE_DECL_HTOLE64) && HAVE_DECL_HTOLE64 == 0 +# define htole64(v) (openssh_swap64(v)) +# endif # else -# define le32toh(v) ((uint32_t)v) -# define le64toh(v) ((uint64_t)v) -# define htole64(v) ((uint64_t)v) +# if defined(HAVE_DECL_LE32TOH) && HAVE_DECL_LE32TOH == 0 +# define le32toh(v) ((uint32_t)v) +# endif +# if defined(HAVE_DECL_LE64TOH) && HAVE_DECL_LE64TOH == 0 +# define le64toh(v) ((uint64_t)v) +# endif +# if defined(HAVE_DECL_HTOLE64) && HAVE_DECL_HTOLE64 == 0 +# define htole64(v) ((uint64_t)v) +# endif # endif #endif @@ -970,4 +993,11 @@ struct winsize { /* The ML-KEM768 implementation also uses C89 features */ # define USE_MLKEM768X25519 1 #endif + +#if defined(HAVE_DECL_INFINITY) && HAVE_DECL_INFINITY == 0 +# if defined(HAVE_DECL___BUILTIN_INFF) && HAVE_DECL___BUILTIN_INFF == 1 +# define INFINITY __builtin_inff() +# endif +#endif + #endif /* _DEFINES_H */ diff --git a/dh.c b/dh.c index ce2eb47..168dea1 100644 --- a/dh.c +++ b/dh.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dh.c,v 1.74 2021/04/03 06:18:40 djm Exp $ */ +/* $OpenBSD: dh.c,v 1.75 2024/12/03 16:27:53 dtucker Exp $ */ /* * Copyright (c) 2000 Niels Provos. All rights reserved. * @@ -197,9 +197,9 @@ choose_dh(int min, int wantbits, int max) if (bestcount == 0) { fclose(f); - logit("WARNING: no suitable primes in %s", - get_moduli_filename()); - return (dh_new_group_fallback(max)); + logit("WARNING: no suitable primes (size %d/%d/%d) in %s", + min, wantbits, max, get_moduli_filename()); + return NULL; } which = arc4random_uniform(bestcount); diff --git a/digest-libc.c b/digest-libc.c index 6e77a44..b187bc9 100644 --- a/digest-libc.c +++ b/digest-libc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: digest-libc.c,v 1.7 2020/02/26 13:40:09 jsg Exp $ */ +/* $OpenBSD: digest-libc.c,v 1.8 2025/09/05 09:31:31 dtucker Exp $ */ /* * Copyright (c) 2013 Damien Miller * Copyright (c) 2014 Markus Friedl. All rights reserved. @@ -27,7 +27,6 @@ #if 0 #include -#include #endif #ifdef HAVE_SHA1_H #include diff --git a/dispatch.c b/dispatch.c index 6118147..430b6af 100644 --- a/dispatch.c +++ b/dispatch.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dispatch.c,v 1.33 2023/03/05 05:34:09 dtucker Exp $ */ +/* $OpenBSD: dispatch.c,v 1.34 2025/05/21 06:44:24 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -41,7 +41,7 @@ dispatch_protocol_error(int type, u_int32_t seq, struct ssh *ssh) { int r; - logit("dispatch_protocol_error: type %d seq %u", type, seq); + logit_f("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 || @@ -53,7 +53,7 @@ dispatch_protocol_error(int type, u_int32_t seq, struct ssh *ssh) int dispatch_protocol_ignore(int type, u_int32_t seq, struct ssh *ssh) { - logit("dispatch_protocol_ignore: type %d seq %u", type, seq); + logit_f("type %d seq %u", type, seq); return 0; } diff --git a/dns.c b/dns.c index 9392414..e8693ce 100644 --- a/dns.c +++ b/dns.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dns.c,v 1.44 2023/03/10 04:06:21 dtucker Exp $ */ +/* $OpenBSD: dns.c,v 1.46 2025/08/29 03:50:38 djm Exp $ */ /* * Copyright (c) 2003 Wesley Griffin. All rights reserved. @@ -88,18 +88,12 @@ dns_read_key(u_int8_t *algorithm, u_int8_t *digest_type, case KEY_RSA: *algorithm = SSHFP_KEY_RSA; break; - case KEY_DSA: - *algorithm = SSHFP_KEY_DSA; - break; case KEY_ECDSA: *algorithm = SSHFP_KEY_ECDSA; break; case KEY_ED25519: *algorithm = SSHFP_KEY_ED25519; break; - case KEY_XMSS: - *algorithm = SSHFP_KEY_XMSS; - break; default: *algorithm = SSHFP_KEY_RESERVED; /* 0 */ } diff --git a/dns.h b/dns.h index 864ab7d..ab2df06 100644 --- a/dns.h +++ b/dns.h @@ -1,4 +1,4 @@ -/* $OpenBSD: dns.h,v 1.20 2023/02/10 04:56:30 djm Exp $ */ +/* $OpenBSD: dns.h,v 1.21 2025/08/29 03:50:38 djm Exp $ */ /* * Copyright (c) 2003 Wesley Griffin. All rights reserved. @@ -33,8 +33,7 @@ enum sshfp_types { SSHFP_KEY_RSA = 1, SSHFP_KEY_DSA = 2, SSHFP_KEY_ECDSA = 3, - SSHFP_KEY_ED25519 = 4, - SSHFP_KEY_XMSS = 5 + SSHFP_KEY_ED25519 = 4 }; enum sshfp_hashes { diff --git a/groupaccess.c b/groupaccess.c index 80d3019..046d0e6 100644 --- a/groupaccess.c +++ b/groupaccess.c @@ -1,4 +1,4 @@ -/* $OpenBSD: groupaccess.c,v 1.17 2019/03/06 22:14:23 dtucker Exp $ */ +/* $OpenBSD: groupaccess.c,v 1.18 2024/11/04 21:59:15 jca Exp $ */ /* * Copyright (c) 2001 Kevin Steves. All rights reserved. * @@ -50,21 +50,32 @@ int ga_init(const char *user, gid_t base) { gid_t *groups_bygid; - int i, j, retry = 0; + int ongroups, i, j, retry = 0; struct group *gr; if (ngroups > 0) ga_free(); - ngroups = NGROUPS_MAX; + ongroups = ngroups = NGROUPS_MAX; #if defined(HAVE_SYSCONF) && defined(_SC_NGROUPS_MAX) - ngroups = MAX(NGROUPS_MAX, sysconf(_SC_NGROUPS_MAX)); + ongroups = ngroups = MAX(NGROUPS_MAX, sysconf(_SC_NGROUPS_MAX)); #endif groups_bygid = xcalloc(ngroups, sizeof(*groups_bygid)); while (getgrouplist(user, base, groups_bygid, &ngroups) == -1) { - if (retry++ > 0) - fatal("getgrouplist: groups list too small"); + if (ngroups <= ongroups) { + error("getgrouplist(\"%s\", %ld): failed", + user, (long)base); + free(groups_bygid); + groups_bygid = NULL; + ngroups = 0; + return 0; + } + if (retry++ > 0) { + fatal("getgrouplist(\"%s\", %ld): groups list too big " + "(have %ld, need %ld)", user, (long)base, + (long)ongroups, (long)ngroups); + } groups_bygid = xreallocarray(groups_bygid, ngroups, sizeof(*groups_bygid)); } diff --git a/gss-genr.c b/gss-genr.c index aa34b71..8f1f54a 100644 --- a/gss-genr.c +++ b/gss-genr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: gss-genr.c,v 1.29 2024/02/01 02:37:33 djm Exp $ */ +/* $OpenBSD: gss-genr.c,v 1.30 2025/09/29 21:28:33 dtucker Exp $ */ /* * Copyright (c) 2001-2007 Simon Wilkinson. All rights reserved. diff --git a/gss-serv.c b/gss-serv.c index 025a118..b0e9c3b 100644 --- a/gss-serv.c +++ b/gss-serv.c @@ -1,4 +1,4 @@ -/* $OpenBSD: gss-serv.c,v 1.32 2020/03/13 03:17:07 djm Exp $ */ +/* $OpenBSD: gss-serv.c,v 1.33 2025/09/29 21:30:15 dtucker Exp $ */ /* * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. diff --git a/hmac.c b/hmac.c index 7b58801..8641edf 100644 --- a/hmac.c +++ b/hmac.c @@ -1,4 +1,4 @@ -/* $OpenBSD: hmac.c,v 1.14 2020/02/26 13:40:09 jsg Exp $ */ +/* $OpenBSD: hmac.c,v 1.15 2025/09/05 09:49:26 dtucker Exp $ */ /* * Copyright (c) 2014 Markus Friedl. All rights reserved. * diff --git a/hostfile.c b/hostfile.c index c5669c7..4cec57d 100644 --- a/hostfile.c +++ b/hostfile.c @@ -1,4 +1,4 @@ -/* $OpenBSD: hostfile.c,v 1.95 2023/02/21 06:48:18 dtucker Exp $ */ +/* $OpenBSD: hostfile.c,v 1.99 2025/05/06 05:40:56 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -150,8 +150,8 @@ host_hash(const char *host, const char *name_from_hostfile, u_int src_len) } /* - * Parses an RSA (number of bits, e, n) or DSA key from a string. Moves the - * pointer over the key. Skips any whitespace at the beginning and at end. + * Parses an RSA key from a string. Moves the pointer over the key. + * Skips any whitespace at the beginning and at end. */ int @@ -434,7 +434,7 @@ lookup_marker_in_hostkeys(struct hostkeys *hostkeys, int want_marker) } static int -write_host_entry(FILE *f, const char *host, const char *ip, +format_host_entry(struct sshbuf *entry, const char *host, const char *ip, const struct sshkey *key, int store_hash) { int r, success = 0; @@ -449,22 +449,50 @@ write_host_entry(FILE *f, const char *host, const char *ip, free(lhost); return 0; } - fprintf(f, "%s ", hashed_host); - } else if (ip != NULL) - fprintf(f, "%s,%s ", lhost, ip); - else { - fprintf(f, "%s ", lhost); + if ((r = sshbuf_putf(entry, "%s ", hashed_host)) != 0) + fatal_fr(r, "sshbuf_putf"); + } else if (ip != NULL) { + if ((r = sshbuf_putf(entry, "%s,%s ", lhost, ip)) != 0) + fatal_fr(r, "sshbuf_putf"); + } else { + if ((r = sshbuf_putf(entry, "%s ", lhost)) != 0) + fatal_fr(r, "sshbuf_putf"); } free(hashed_host); free(lhost); - if ((r = sshkey_write(key, f)) == 0) + if ((r = sshkey_format_text(key, entry)) == 0) success = 1; else error_fr(r, "sshkey_write"); - fputc('\n', f); + if ((r = sshbuf_putf(entry, "\n")) != 0) + fatal_fr(r, "sshbuf_putf"); + /* If hashing is enabled, the IP address needs to go on its own line */ if (success && store_hash && ip != NULL) - success = write_host_entry(f, ip, NULL, key, 1); + success = format_host_entry(entry, ip, NULL, key, 1); + return success; +} + +static int +write_host_entry(FILE *f, const char *host, const char *ip, + const struct sshkey *key, int store_hash) +{ + int r, success = 0; + struct sshbuf *entry = NULL; + + if ((entry = sshbuf_new()) == NULL) + fatal_f("allocation failed"); + if ((r = format_host_entry(entry, host, ip, key, store_hash)) != 1) { + debug_f("failed to format host entry"); + goto out; + } + if ((r = fwrite(sshbuf_ptr(entry), sshbuf_len(entry), 1, f)) != 1) { + error_f("fwrite: %s", strerror(errno)); + goto out; + } + success = 1; + out: + sshbuf_free(entry); return success; } @@ -520,9 +548,9 @@ add_host_to_hostfile(const char *filename, const char *host, if (key == NULL) return 1; /* XXX ? */ hostfile_create_user_ssh_dir(filename, 0); - f = fopen(filename, "a+"); - if (!f) + if ((f = fopen(filename, "a+")) == NULL) return 0; + setvbuf(f, NULL, _IONBF, 0); /* Make sure we have a terminating newline. */ if (fseek(f, -1L, SEEK_END) == 0 && fgetc(f) != '\n') addnl = 1; @@ -810,6 +838,12 @@ hostkeys_foreach_file(const char *path, FILE *f, hostkeys_foreach_fn *callback, /* Find the end of the host name portion. */ for (cp2 = cp; *cp2 && *cp2 != ' ' && *cp2 != '\t'; cp2++) ; + if (*cp2 == '\0') { + verbose_f("truncated line at %s:%lu", path, linenum); + if ((options & HKF_WANT_MATCH) == 0) + goto bad; + continue; + } lineinfo.hosts = cp; *cp2++ = '\0'; diff --git a/includes.h b/includes.h index 6d17ef6..96cddbc 100644 --- a/includes.h +++ b/includes.h @@ -34,6 +34,9 @@ #ifdef HAVE_ENDIAN_H # include #endif +#ifdef HAVE_FCNTL_H +# include +#endif #ifdef HAVE_TTYENT_H # include #endif @@ -49,6 +52,9 @@ #ifdef HAVE_PATHS_H # include #endif +#ifdef HAVE_FCNTL_H +# include /* For AT_FDCWD */ +#endif /* *-*-nto-qnx needs these headers for strcasecmp and LASTLOG_FILE respectively diff --git a/kex-names.c b/kex-names.c index ec840c1..a20ce60 100644 --- a/kex-names.c +++ b/kex-names.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kex-names.c,v 1.4 2024/09/09 02:39:57 djm Exp $ */ +/* $OpenBSD: kex-names.c,v 1.6 2025/09/02 11:08:34 djm Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. * @@ -50,65 +50,57 @@ struct kexalg { u_int type; int ec_nid; int hash_alg; + int pq_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 }, + { KEX_DH1, KEX_DH_GRP1_SHA1, 0, SSH_DIGEST_SHA1, KEX_NOT_PQ }, + { KEX_DH14_SHA1, KEX_DH_GRP14_SHA1, 0, SSH_DIGEST_SHA1, KEX_NOT_PQ }, + { KEX_DH14_SHA256, KEX_DH_GRP14_SHA256, 0, SSH_DIGEST_SHA256, KEX_NOT_PQ }, + { KEX_DH16_SHA512, KEX_DH_GRP16_SHA512, 0, SSH_DIGEST_SHA512, KEX_NOT_PQ }, + { KEX_DH18_SHA512, KEX_DH_GRP18_SHA512, 0, SSH_DIGEST_SHA512, KEX_NOT_PQ }, + { KEX_DHGEX_SHA1, KEX_DH_GEX_SHA1, 0, SSH_DIGEST_SHA1, KEX_NOT_PQ }, #ifdef HAVE_EVP_SHA256 - { KEX_DHGEX_SHA256, KEX_DH_GEX_SHA256, 0, SSH_DIGEST_SHA256 }, + { KEX_DHGEX_SHA256, KEX_DH_GEX_SHA256, 0, SSH_DIGEST_SHA256, KEX_NOT_PQ }, #endif /* HAVE_EVP_SHA256 */ #ifdef OPENSSL_HAS_ECC { KEX_ECDH_SHA2_NISTP256, KEX_ECDH_SHA2, - NID_X9_62_prime256v1, SSH_DIGEST_SHA256 }, + NID_X9_62_prime256v1, SSH_DIGEST_SHA256, KEX_NOT_PQ }, { KEX_ECDH_SHA2_NISTP384, KEX_ECDH_SHA2, NID_secp384r1, - SSH_DIGEST_SHA384 }, + SSH_DIGEST_SHA384, KEX_NOT_PQ }, # ifdef OPENSSL_HAS_NISTP521 { KEX_ECDH_SHA2_NISTP521, KEX_ECDH_SHA2, NID_secp521r1, - SSH_DIGEST_SHA512 }, + SSH_DIGEST_SHA512, KEX_NOT_PQ }, # 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 }, + { KEX_CURVE25519_SHA256, KEX_C25519_SHA256, 0, SSH_DIGEST_SHA256, KEX_NOT_PQ }, + { KEX_CURVE25519_SHA256_OLD, KEX_C25519_SHA256, 0, SSH_DIGEST_SHA256, KEX_NOT_PQ }, #ifdef USE_SNTRUP761X25519 { KEX_SNTRUP761X25519_SHA512, KEX_KEM_SNTRUP761X25519_SHA512, 0, - SSH_DIGEST_SHA512 }, + SSH_DIGEST_SHA512, KEX_IS_PQ }, { KEX_SNTRUP761X25519_SHA512_OLD, KEX_KEM_SNTRUP761X25519_SHA512, 0, - SSH_DIGEST_SHA512 }, + SSH_DIGEST_SHA512, KEX_IS_PQ }, #endif #ifdef USE_MLKEM768X25519 { KEX_MLKEM768X25519_SHA256, KEX_KEM_MLKEM768X25519_SHA256, 0, - SSH_DIGEST_SHA256 }, + SSH_DIGEST_SHA256, KEX_IS_PQ }, #endif #endif /* HAVE_EVP_SHA256 || !WITH_OPENSSL */ - { NULL, 0, -1, -1}, + { NULL, 0, -1, -1, 0 }, }; char * kex_alg_list(char sep) { - char *ret = NULL, *tmp; - size_t nlen, rlen = 0; + char *ret = NULL; const struct kexalg *k; + char sep_str[2] = {sep, '\0'}; + + for (k = kexalgs; k->name != NULL; k++) + xextendf(&ret, sep_str, "%s", k->name); - 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; } @@ -130,6 +122,16 @@ kex_name_valid(const char *name) return kex_alg_by_name(name) != NULL; } +int +kex_is_pq_from_name(const char *name) +{ + const struct kexalg *k; + + if ((k = kex_alg_by_name(name)) == NULL) + return 0; + return k->pq_alg == KEX_IS_PQ; +} + u_int kex_type_from_name(const char *name) { diff --git a/kex.c b/kex.c index 6b957e5..814fad9 100644 --- a/kex.c +++ b/kex.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kex.c,v 1.187 2024/08/23 04:51:00 deraadt Exp $ */ +/* $OpenBSD: kex.c,v 1.189 2025/09/15 04:40:34 djm Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. * @@ -33,9 +33,7 @@ #include #include #include -#ifdef HAVE_POLL_H #include -#endif #ifdef WITH_OPENSSL #include @@ -563,8 +561,6 @@ kex_input_newkeys(int type, u_int32_t seq, struct ssh *ssh) kex->flags &= ~KEX_INITIAL; sshbuf_reset(kex->peer); kex->flags &= ~KEX_INIT_SENT; - free(kex->name); - kex->name = NULL; return 0; } @@ -620,6 +616,8 @@ kex_input_kexinit(int type, u_int32_t seq, struct ssh *ssh) error_f("no kex"); return SSH_ERR_INTERNAL_ERROR; } + free(kex->name); + kex->name = NULL; ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, &kex_protocol_error); ptr = sshpkt_ptr(ssh, &dlen); if ((r = sshbuf_put(kex->peer, ptr, dlen)) != 0) @@ -742,6 +740,7 @@ kex_free(struct kex *kex) free(kex->failed_choice); free(kex->hostkey_alg); free(kex->name); + free(kex->server_sig_algs); free(kex); } diff --git a/kex.h b/kex.h index d08988b..55baa6a 100644 --- a/kex.h +++ b/kex.h @@ -1,4 +1,4 @@ -/* $OpenBSD: kex.h,v 1.126 2024/09/02 12:13:56 djm Exp $ */ +/* $OpenBSD: kex.h,v 1.127 2025/08/11 10:55:38 djm Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. @@ -115,6 +115,10 @@ enum kex_exchange { #define KEX_HAS_PING 0x0020 #define KEX_HAS_EXT_INFO_IN_AUTH 0x0040 +/* kex->pq */ +#define KEX_NOT_PQ 0 +#define KEX_IS_PQ 1 + struct sshenc { char *name; const struct sshcipher *cipher; @@ -189,6 +193,7 @@ int kex_name_valid(const char *); u_int kex_type_from_name(const char *); int kex_hash_from_name(const char *); int kex_nid_from_name(const char *); +int kex_is_pq_from_name(const char *); int kex_names_valid(const char *); char *kex_alg_list(char); char *kex_names_cat(const char *, const char *); diff --git a/kexdh.c b/kexdh.c index c1084f2..191bdce 100644 --- a/kexdh.c +++ b/kexdh.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kexdh.c,v 1.34 2020/12/04 02:29:25 djm Exp $ */ +/* $OpenBSD: kexdh.c,v 1.35 2025/10/03 00:08:02 djm Exp $ */ /* * Copyright (c) 2019 Markus Friedl. All rights reserved. * @@ -34,6 +34,7 @@ #include #include "openbsd-compat/openssl-compat.h" +#include #include #include "sshkey.h" diff --git a/kexecdh.c b/kexecdh.c index efb2e55..500ec57 100644 --- a/kexecdh.c +++ b/kexecdh.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kexecdh.c,v 1.10 2019/01/21 10:40:11 djm Exp $ */ +/* $OpenBSD: kexecdh.c,v 1.11 2025/10/03 00:08:02 djm Exp $ */ /* * Copyright (c) 2010 Damien Miller. All rights reserved. * Copyright (c) 2019 Markus Friedl. All rights reserved. @@ -34,6 +34,7 @@ #include #include +#include #include #include "sshkey.h" diff --git a/kexgen.c b/kexgen.c index 40d688d..494d4b2 100644 --- a/kexgen.c +++ b/kexgen.c @@ -113,7 +113,7 @@ kex_gen_client(struct ssh *ssh) case KEX_ECDH_SHA2: r = kex_ecdh_keypair(kex); break; -#endif +#endif /* WITH_OPENSSL */ case KEX_C25519_SHA256: r = kex_c25519_keypair(kex); break; @@ -187,7 +187,7 @@ input_kex_gen_reply(int type, u_int32_t seq, struct ssh *ssh) case KEX_ECDH_SHA2: r = kex_ecdh_dec(kex, server_blob, &shared_secret); break; -#endif +#endif /* WITH_OPENSSL */ case KEX_C25519_SHA256: r = kex_c25519_dec(kex, server_blob, &shared_secret); break; @@ -310,7 +310,7 @@ input_kex_gen_init(int type, u_int32_t seq, struct ssh *ssh) r = kex_ecdh_enc(kex, client_pubkey, &server_pubkey, &shared_secret); break; -#endif +#endif /* WITH_OPENSSL */ case KEX_C25519_SHA256: r = kex_c25519_enc(kex, client_pubkey, &server_pubkey, &shared_secret); diff --git a/kexgexc.c b/kexgexc.c index e99e0cf..097d83f 100644 --- a/kexgexc.c +++ b/kexgexc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kexgexc.c,v 1.38 2021/12/19 22:08:06 djm Exp $ */ +/* $OpenBSD: kexgexc.c,v 1.39 2025/10/03 00:08:02 djm Exp $ */ /* * Copyright (c) 2000 Niels Provos. All rights reserved. * Copyright (c) 2001 Markus Friedl. All rights reserved. @@ -30,6 +30,8 @@ #include +#include "openbsd-compat/openssl-compat.h" +#include #include #include @@ -37,8 +39,6 @@ #include #include -#include "openbsd-compat/openssl-compat.h" - #include "sshkey.h" #include "cipher.h" #include "digest.h" diff --git a/kexgexs.c b/kexgexs.c index 100be03..d02cca6 100644 --- a/kexgexs.c +++ b/kexgexs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kexgexs.c,v 1.47 2024/05/17 00:30:23 djm Exp $ */ +/* $OpenBSD: kexgexs.c,v 1.49 2025/10/03 00:09:26 djm Exp $ */ /* * Copyright (c) 2000 Niels Provos. All rights reserved. * Copyright (c) 2001 Markus Friedl. All rights reserved. @@ -28,15 +28,14 @@ #ifdef WITH_OPENSSL - #include #include #include #include -#include - #include "openbsd-compat/openssl-compat.h" +#include +#include #include "sshkey.h" #include "cipher.h" diff --git a/kexmlkem768x25519.c b/kexmlkem768x25519.c index 2b5d396..2585d1d 100644 --- a/kexmlkem768x25519.c +++ b/kexmlkem768x25519.c @@ -28,15 +28,11 @@ #include #include -#ifdef HAVE_STDINT_H #include -#endif #include #include #include -#ifdef HAVE_ENDIAN_H -# include -#endif +#include #include "sshkey.h" #include "kex.h" diff --git a/krl.c b/krl.c index 0d0f695..bea5b1b 100644 --- a/krl.c +++ b/krl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: krl.c,v 1.60 2025/02/18 08:02:48 djm Exp $ */ +/* $OpenBSD: krl.c,v 1.62 2025/09/15 04:41:20 djm Exp $ */ /* * Copyright (c) 2012 Damien Miller * @@ -149,6 +149,8 @@ revoked_certs_free(struct revoked_certs *rc) struct revoked_serial *rs, *trs; struct revoked_key_id *rki, *trki; + if (rc == NULL) + return; RB_FOREACH_SAFE(rs, revoked_serial_tree, &rc->revoked_serials, trs) { RB_REMOVE(revoked_serial_tree, &rc->revoked_serials, rs); free(rs); @@ -159,6 +161,7 @@ revoked_certs_free(struct revoked_certs *rc) free(rki); } sshkey_free(rc->ca_key); + freezero(rc, sizeof(*rc)); } void diff --git a/libcrux_mlkem768_sha3.h b/libcrux_mlkem768_sha3.h index b8ac143..885e82b 100644 --- a/libcrux_mlkem768_sha3.h +++ b/libcrux_mlkem768_sha3.h @@ -177,10 +177,14 @@ static inline uint32_t core_num__u32_8__from_le_bytes(uint8_t buf[4]) { } static inline uint32_t core_num__u8_6__count_ones(uint8_t x0) { -#ifdef _MSC_VER +#if defined(_MSC_VER) return __popcnt(x0); -#else +#elif !defined(MISSING_BUILTIN_POPCOUNT) return __builtin_popcount(x0); +#else + const uint8_t v[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 }; + return v[x0 & 0xf] + v[(x0 >> 4) & 0xf]; + #endif } diff --git a/log.c b/log.c index 23ad10c..5969c4a 100644 --- a/log.c +++ b/log.c @@ -1,4 +1,4 @@ -/* $OpenBSD: log.c,v 1.62 2024/06/27 22:36:44 djm Exp $ */ +/* $OpenBSD: log.c,v 1.65 2025/09/02 09:34:48 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -38,14 +38,16 @@ #include +#include #include +#include #include #include #include #include #include +#include #include -#include #if defined(HAVE_STRNVIS) && defined(HAVE_VIS_H) && !defined(BROKEN_STRNVIS) # include #endif @@ -460,9 +462,9 @@ sshlogv(const char *file, const char *func, int line, int showfunc, if (nlog_verbose == 0 && level > log_level) return; - snprintf(tag, sizeof(tag), "%.48s:%.48s():%d (pid=%ld)", + snprintf(tag, sizeof(tag), "%.48s:%.48s():%d (bin=%s, pid=%ld)", (cp = strrchr(file, '/')) == NULL ? file : cp + 1, func, line, - (long)getpid()); + argv0 == NULL ? "UNKNOWN" : argv0, (long)getpid()); for (i = 0; i < nlog_verbose; i++) { if (match_pattern_list(tag, log_verbose[i], 0) == 1) { forced = 1; @@ -489,3 +491,167 @@ sshlogdirect(LogLevel level, int forced, const char *fmt, ...) do_log(level, forced, NULL, fmt, args); va_end(args); } + + +/* + * A simple system for ratelimiting aperiodic events such as logs, without + * needing to be hooked into a mainloop/timer. A running total of events is + * maintained and when it exceeds a threshold further events are dropped + * until the rate falls back below that threshold. + * + * To prevent flipping in and out of rate-limiting, there is a hysteresis + * timer that delays leaving the rate-limited state. + * + * While in the rate-limited state, events can be periodically allowed through + * and the number of dropped events since the last log obtained. + * + * XXX a moving average rate of events might be a better approach here rather + * than linear decay, which can suppress events for a while after large + * bursts. + */ + +/* #define RATELIMIT_DEBUG 1 */ + +#ifdef RATELIMIT_DEBUG +# define RLDBG(x) do { \ + printf("%s:%d %s: ", __FILE__, __LINE__, __func__); \ + printf x; \ + printf("\n"); \ + fflush(stdout); \ + } while (0) +#else +# define RLDBG(x) +#endif + +/* set up a ratelimit */ +void +log_ratelimit_init(struct log_ratelimit_ctx *rl, u_int threshold, + u_int max_accum, u_int hysteresis, u_int log_every) +{ + memset(rl, 0, sizeof(*rl)); + rl->threshold = threshold; + rl->max_accum = max_accum; + rl->hysteresis = hysteresis; + rl->log_every = log_every; + RLDBG(("called: rl=%p thresh=%u max=%u hys=%u log_every=%u", + rl, rl->threshold, rl->max_accum, rl->hysteresis, rl->log_every)); +} + +/* + * check whether a log event should be dropped because of rate-limiting. + * returns non-zero if the event should be dropped. If events_since_last + * is supplied then, for periodic logs, it will be set to the number of + * dropped events since the last message. + */ +int +log_ratelimit(struct log_ratelimit_ctx *rl, time_t now, int *active, + u_int *events_dropped) +{ + time_t olast_event; + + RLDBG(("called: rl=%p thresh=%u max=%u hys=%u log_every=%u " + "accum=%u since=%ld since_last=%u", rl, rl->threshold, + rl->max_accum, rl->hysteresis, + rl->log_every, rl->accumulated_events, + rl->last_event == 0 ? -1 : (long)(now - rl->last_event), + rl->ratelimited_events)); + + if (now < 0) + return 0; + if (events_dropped != NULL) + *events_dropped = 0; + if (active != NULL) + *active = rl->ratelimit_active; + + /* First, decay accumulated events */ + if (rl->last_event <= 0) + rl->last_event = now; + if (now > rl->last_event) { + uint64_t n = now - rl->last_event; + + if (n > UINT_MAX) + n = UINT_MAX; + if (rl->accumulated_events < (u_int)n) + rl->accumulated_events = 0; + else + rl->accumulated_events -= (u_int)n; + RLDBG(("decay: accum=%u", rl->accumulated_events)); + } + rl->accumulated_events++; /* add this event */ + if (rl->accumulated_events > rl->max_accum) + rl->accumulated_events = rl->max_accum; + olast_event = rl->last_event; + rl->last_event = now; + RLDBG(("check threshold: accum=%u vs thresh=%u", + rl->accumulated_events, rl->threshold)); + + /* Are we under threshold? */ + if (rl->accumulated_events < rl->threshold) { + if (!rl->ratelimit_active) + return 0; + RLDBG(("under threshold: hys=%u since_hys=%ld since_last=%ld", + rl->hysteresis, rl->hysteresis_start == 0 ? -1 : + (long)(now - rl->hysteresis_start), + olast_event == 0 ? -1 : (long)(now - olast_event))); + if (rl->hysteresis_start == 0) { + /* active, but under threshold; hysteresis */ + if (olast_event + rl->hysteresis < now) { + /* hysteresis expired before this event */ + RLDBG(("hysteresis preexpired")); + goto inactive; + } + RLDBG(("start hysteresis")); + rl->hysteresis_start = now; + } else if (rl->hysteresis_start + rl->hysteresis < now) { + /* Hysteresis period expired, transition to inactive */ + RLDBG(("complete hysteresis")); + inactive: + if (events_dropped != NULL) + *events_dropped = rl->ratelimited_events; + if (active != NULL) + *active = 0; + rl->ratelimit_active = 0; + rl->ratelimit_start = 0; + rl->last_log = 0; + rl->hysteresis_start = 0; + rl->ratelimited_events = 0; + return 0; + } + /* ratelimiting active, but in hysteresis period */ + } else if (!rl->ratelimit_active) { + /* Transition to rate-limiting */ + RLDBG(("start ratelimit")); + rl->ratelimit_active = 1; + rl->ratelimit_start = now; + rl->last_log = now; + rl->hysteresis_start = 0; + rl->ratelimited_events = 1; + if (active != NULL) + *active = 1; + return 1; + } else if (rl->hysteresis_start != 0) { + /* active and over threshold; reset hysteresis timer */ + RLDBG(("clear hysteresis")); + rl->hysteresis_start = 0; + } + + /* over threshold or in hysteresis period; log periodically */ + if (active != NULL) + *active = 1; + RLDBG(("log_every=%u since_log=%ld", rl->log_every, + (long)(now - rl->last_log))); + if (rl->log_every > 0 && now >= rl->last_log + rl->log_every) { + RLDBG(("periodic: since_last=%u", rl->ratelimited_events)); + rl->last_log = now; + if (events_dropped != NULL) { + *events_dropped = rl->ratelimited_events; + rl->ratelimited_events = 0; + } + return 0; + } + + /* drop event */ + rl->ratelimited_events++; + RLDBG(("drop: ratelimited_events=%u", rl->ratelimited_events)); + return 1; +} diff --git a/log.h b/log.h index 8fe350b..8e8dfc2 100644 --- a/log.h +++ b/log.h @@ -1,4 +1,4 @@ -/* $OpenBSD: log.h,v 1.34 2024/06/27 22:36:44 djm Exp $ */ +/* $OpenBSD: log.h,v 1.35 2024/12/07 10:05:37 djm Exp $ */ /* * Author: Tatu Ylonen @@ -81,6 +81,30 @@ void sshfatal(const char *, const char *, int, int, void sshlogdirect(LogLevel, int, const char *, ...) __attribute__((format(printf, 3, 4))); +struct log_ratelimit_ctx { + /* configuration */ + u_int threshold; /* events per second */ + u_int max_accum; /* max events to accumulate */ + u_int hysteresis; /* seconds */ + u_int log_every; /* seconds */ + + /* state */ + time_t last_event; + u_int accumulated_events; /* used for threshold comparisons */ + + /* state while actively rate-limiting */ + int ratelimit_active; + time_t ratelimit_start; + time_t last_log; + time_t hysteresis_start; + u_int ratelimited_events; +}; + +void log_ratelimit_init(struct log_ratelimit_ctx *rl, u_int threshold, + u_int max_accum, u_int hysteresis, u_int log_every); +int log_ratelimit(struct log_ratelimit_ctx *rl, time_t now, int *active, + u_int *events_dropped); + #define do_log2(level, ...) sshlog(__FILE__, __func__, __LINE__, 0, level, NULL, __VA_ARGS__) #define debug3(...) sshlog(__FILE__, __func__, __LINE__, 0, SYSLOG_LEVEL_DEBUG3, NULL, __VA_ARGS__) #define debug2(...) sshlog(__FILE__, __func__, __LINE__, 0, SYSLOG_LEVEL_DEBUG2, NULL, __VA_ARGS__) diff --git a/loginrec.c b/loginrec.c index 7b1818b..7d1c9dd 100644 --- a/loginrec.c +++ b/loginrec.c @@ -129,18 +129,14 @@ #include #include #include -#ifdef HAVE_SYS_TIME_H -# include -#endif +#include #include #include #include #include -#ifdef HAVE_PATHS_H -# include -#endif +#include #include #include #include @@ -162,8 +158,10 @@ #include "ssherr.h" #include "misc.h" -#ifdef HAVE_UTIL_H # include + +#ifdef USE_WTMPDB +# include #endif /** @@ -186,6 +184,9 @@ int wtmp_write_entry(struct logininfo *li); int wtmpx_write_entry(struct logininfo *li); int lastlog_write_entry(struct logininfo *li); int syslogin_write_entry(struct logininfo *li); +#ifdef USE_WTMPDB +int wtmpdb_write_entry(struct logininfo *li); +#endif int getlast_entry(struct logininfo *li); int lastlog_get_entry(struct logininfo *li); @@ -446,6 +447,9 @@ login_write(struct logininfo *li) #ifdef USE_WTMPX wtmpx_write_entry(li); #endif +#ifdef USE_WTMPDB + wtmpdb_write_entry(li); +#endif #ifdef CUSTOM_SYS_AUTH_RECORD_LOGIN if (li->type == LTYPE_LOGIN && !sys_auth_record_login(li->username,li->hostname,li->line, @@ -843,7 +847,7 @@ utmp_write_direct(struct logininfo *li, struct utmp *ut) endttyent(); if (NULL == ty) { - logit("%s: tty not found", __func__); + logit_f("tty not found"); return (0); } #else /* FIXME */ @@ -857,7 +861,7 @@ utmp_write_direct(struct logininfo *li, struct utmp *ut) pos = (off_t)tty * sizeof(struct utmp); if ((ret = lseek(fd, pos, SEEK_SET)) == -1) { - logit("%s: lseek: %s", __func__, strerror(errno)); + logit_f("lseek: %s", strerror(errno)); close(fd); return (0); } @@ -879,7 +883,7 @@ utmp_write_direct(struct logininfo *li, struct utmp *ut) memcpy(ut->ut_host, old_ut.ut_host, sizeof(ut->ut_host)); if ((ret = lseek(fd, pos, SEEK_SET)) == -1) { - logit("%s: lseek: %s", __func__, strerror(errno)); + logit_f("lseek: %s", strerror(errno)); close(fd); return (0); } @@ -912,12 +916,12 @@ utmp_perform_login(struct logininfo *li) construct_utmp(li, &ut); # ifdef UTMP_USE_LIBRARY if (!utmp_write_library(li, &ut)) { - logit("%s: utmp_write_library() failed", __func__); + logit_f("utmp_write_library() failed"); return (0); } # else if (!utmp_write_direct(li, &ut)) { - logit("%s: utmp_write_direct() failed", __func__); + logit_f("utmp_write_direct() failed"); return (0); } # endif @@ -933,12 +937,12 @@ utmp_perform_logout(struct logininfo *li) construct_utmp(li, &ut); # ifdef UTMP_USE_LIBRARY if (!utmp_write_library(li, &ut)) { - logit("%s: utmp_write_library() failed", __func__); + logit_f("utmp_write_library() failed"); return (0); } # else if (!utmp_write_direct(li, &ut)) { - logit("%s: utmp_write_direct() failed", __func__); + logit_f("utmp_write_direct() failed"); return (0); } # endif @@ -957,7 +961,7 @@ utmp_write_entry(struct logininfo *li) return (utmp_perform_logout(li)); default: - logit("%s: invalid type field", __func__); + logit_f("invalid type field"); return (0); } } @@ -998,7 +1002,7 @@ utmpx_write_library(struct logininfo *li, struct utmpx *utx) static int utmpx_write_direct(struct logininfo *li, struct utmpx *utx) { - logit("%s: not implemented!", __func__); + logit_f("not implemented!"); return (0); } # endif /* UTMPX_USE_LIBRARY */ @@ -1011,12 +1015,12 @@ utmpx_perform_login(struct logininfo *li) construct_utmpx(li, &utx); # ifdef UTMPX_USE_LIBRARY if (!utmpx_write_library(li, &utx)) { - logit("%s: utmp_write_library() failed", __func__); + logit_f("utmp_write_library() failed"); return (0); } # else - if (!utmpx_write_direct(li, &ut)) { - logit("%s: utmp_write_direct() failed", __func__); + if (!utmpx_write_direct(li, &utx)) { + logit_f("utmp_write_direct() failed"); return (0); } # endif @@ -1054,7 +1058,7 @@ utmpx_write_entry(struct logininfo *li) case LTYPE_LOGOUT: return (utmpx_perform_logout(li)); default: - logit("%s: invalid type field", __func__); + logit_f("invalid type field"); return (0); } } @@ -1122,7 +1126,7 @@ wtmp_write_entry(struct logininfo *li) case LTYPE_LOGOUT: return (wtmp_perform_logout(li)); default: - logit("%s: invalid type field", __func__); + logit_f("invalid type field"); return (0); } } @@ -1301,7 +1305,7 @@ wtmpx_write_entry(struct logininfo *li) case LTYPE_LOGOUT: return (wtmpx_perform_logout(li)); default: - logit("%s: invalid type field", __func__); + logit_f("invalid type field"); return (0); } } @@ -1391,6 +1395,64 @@ wtmpx_get_entry(struct logininfo *li) } #endif /* USE_WTMPX */ +#ifdef USE_WTMPDB +static int +wtmpdb_perform_login(struct logininfo *li) +{ + uint64_t login_time = li->tv_sec * ((uint64_t) 1000000ULL) + + li->tv_usec; + const char *tty; + + if (strncmp(li->line, "/dev/", 5) == 0) + tty = &(li->line[5]); + else + tty = li->line; + + li->wtmpdb_id = wtmpdb_login(NULL, USER_PROCESS, li->username, + login_time, tty, li->hostname, 0, 0); + + if (li->wtmpdb_id < 0) + return (0); + + return (1); +} + +static int +wtmpdb_perform_logout(struct logininfo *li) +{ + uint64_t logout_time = li->tv_sec * ((uint64_t) 1000000ULL) + + li->tv_usec; + + if (li->wtmpdb_id == 0) { + const char *tty; + + if (strncmp(li->line, "/dev/", 5) == 0) + tty = &(li->line[5]); + else + tty = li->line; + + li->wtmpdb_id = wtmpdb_get_id(NULL, tty, NULL); + } + wtmpdb_logout(NULL, li->wtmpdb_id, logout_time, NULL); + + return (1); +} + +int +wtmpdb_write_entry(struct logininfo *li) +{ + switch(li->type) { + case LTYPE_LOGIN: + return (wtmpdb_perform_login(li)); + case LTYPE_LOGOUT: + return (wtmpdb_perform_logout(li)); + default: + logit_f("invalid type field"); + return (0); + } +} +#endif + /** ** Low-level libutil login() functions **/ @@ -1418,7 +1480,7 @@ syslogin_perform_logout(struct logininfo *li) (void)line_stripname(line, li->line, sizeof(line)); if (!logout(line)) - logit("%s: logout() returned an error", __func__); + logit_f("logout() returned an error"); # ifdef HAVE_LOGWTMP else logwtmp(line, "", ""); @@ -1440,7 +1502,7 @@ syslogin_write_entry(struct logininfo *li) case LTYPE_LOGOUT: return (syslogin_perform_logout(li)); default: - logit("%s: Invalid type field", __func__); + logit_f("Invalid type field"); return (0); } } @@ -1529,10 +1591,10 @@ lastlog_write_entry(struct logininfo *li) strlcpy(last.ll_host, li->hostname, MIN_SIZEOF(last.ll_host, li->hostname)); last.ll_time = li->tv_sec; - + if (!lastlog_openseek(li, &fd, O_RDWR|O_CREAT)) return (0); - + /* write the entry */ if (atomicio(vwrite, fd, &last, sizeof(last)) != sizeof(last)) { close(fd); @@ -1540,11 +1602,11 @@ lastlog_write_entry(struct logininfo *li) LASTLOG_FILE, strerror(errno)); return (0); } - + close(fd); return (1); default: - logit("%s: Invalid type field", __func__); + logit_f("Invalid type field"); return (0); } } @@ -1636,7 +1698,7 @@ utmpx_get_entry(struct logininfo *li) /* * Logs failed login attempts in _PATH_BTMP if that exists. * The most common login failure is to give password instead of username. - * So the _PATH_BTMP file checked for the correct permission, so that only + * So the _PATH_BTMP file is checked for the correct permission, so that only * root can read it. */ void diff --git a/loginrec.h b/loginrec.h index 02bceb6..62ddd01 100644 --- a/loginrec.h +++ b/loginrec.h @@ -79,6 +79,9 @@ struct logininfo { unsigned int tv_sec; unsigned int tv_usec; union login_netinfo hostaddr; /* caller's host address(es) */ +#ifdef USE_WTMPDB + int64_t wtmpdb_id; /* ID for wtmpdb_logout */ +#endif }; /* struct logininfo */ /* diff --git a/logintest.c b/logintest.c index 6ee1cdc..1056bba 100644 --- a/logintest.c +++ b/logintest.c @@ -41,9 +41,7 @@ #include #include #include -#ifdef HAVE_TIME_H #include -#endif #include "loginrec.h" diff --git a/m4/openssh.m4 b/m4/openssh.m4 index 176a8d1..f420146 100644 --- a/m4/openssh.m4 +++ b/m4/openssh.m4 @@ -62,7 +62,8 @@ dnl Check that $CC accepts a flag 'check_flag'. If it is supported append dnl 'define_flag' to $CFLAGS. If 'define_flag' is not specified, then append dnl 'check_flag'. AC_DEFUN([OSSH_CHECK_CFLAG_COMPILE], [{ - AC_MSG_CHECKING([if $CC supports compile flag $1]) + ossh_cache_var=AS_TR_SH([ossh_cv_cflag_$1]) + AC_CACHE_CHECK([if $CC supports compile flag $1], [$ossh_cache_var], [ saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR $1" _define_flag="$2" @@ -71,22 +72,23 @@ AC_DEFUN([OSSH_CHECK_CFLAG_COMPILE], [{ [ if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null then - AC_MSG_RESULT([no]) + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" else dnl If we are compiling natively, try running the program. AC_RUN_IFELSE([OSSH_COMPILER_FLAG_TEST_PROGRAM], - [ AC_MSG_RESULT([yes]) + [ eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" ], - [ AC_MSG_RESULT([no, fails at run time]) + [ eval "$ossh_cache_var='no, fails at run time'" CFLAGS="$saved_CFLAGS" ], - [ AC_MSG_RESULT([yes]) + [ eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" ], ) fi], - [ AC_MSG_RESULT([no]) + [ eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" ] ) + ]) }]) dnl OSSH_CHECK_CFLAG_LINK(check_flag[, define_flag]) @@ -94,7 +96,8 @@ dnl Check that $CC accepts a flag 'check_flag'. If it is supported append dnl 'define_flag' to $CFLAGS. If 'define_flag' is not specified, then append dnl 'check_flag'. AC_DEFUN([OSSH_CHECK_CFLAG_LINK], [{ - AC_MSG_CHECKING([if $CC supports compile flag $1 and linking succeeds]) + ossh_cache_var=AS_TR_SH([ossh_cv_cflag_$1]) + AC_CACHE_CHECK([if $CC supports compile flag $1 and linking succeeds], [$ossh_cache_var], [ saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR $1" _define_flag="$2" @@ -103,22 +106,23 @@ AC_DEFUN([OSSH_CHECK_CFLAG_LINK], [{ [ if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null then - AC_MSG_RESULT([no]) + eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" else dnl If we are compiling natively, try running the program. AC_RUN_IFELSE([OSSH_COMPILER_FLAG_TEST_PROGRAM], - [ AC_MSG_RESULT([yes]) + [ eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" ], - [ AC_MSG_RESULT([no, fails at run time]) + [ eval "$ossh_cache_var='no, fails at run time'" CFLAGS="$saved_CFLAGS" ], - [ AC_MSG_RESULT([yes]) + [ eval "$ossh_cache_var=yes" CFLAGS="$saved_CFLAGS $_define_flag" ], ) fi], - [ AC_MSG_RESULT([no]) + [ eval "$ossh_cache_var=no" CFLAGS="$saved_CFLAGS" ] ) + ]) }]) dnl OSSH_CHECK_LDFLAG_LINK(check_flag[, define_flag]) @@ -126,7 +130,8 @@ dnl Check that $LD accepts a flag 'check_flag'. If it is supported append dnl 'define_flag' to $LDFLAGS. If 'define_flag' is not specified, then append dnl 'check_flag'. AC_DEFUN([OSSH_CHECK_LDFLAG_LINK], [{ - AC_MSG_CHECKING([if $LD supports link flag $1]) + ossh_cache_var=AS_TR_SH([ossh_cv_ldflag_$1]) + AC_CACHE_CHECK([if $LD supports link flag $1], [$ossh_cache_var], [ saved_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $WERROR $1" _define_flag="$2" @@ -135,22 +140,23 @@ AC_DEFUN([OSSH_CHECK_LDFLAG_LINK], [{ [ if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null then - AC_MSG_RESULT([no]) + eval "$ossh_cache_var=no" LDFLAGS="$saved_LDFLAGS" else dnl If we are compiling natively, try running the program. AC_RUN_IFELSE([OSSH_COMPILER_FLAG_TEST_PROGRAM], - [ AC_MSG_RESULT([yes]) + [ eval "$ossh_cache_var=yes" LDFLAGS="$saved_LDFLAGS $_define_flag" ], - [ AC_MSG_RESULT([no, fails at run time]) + [ eval "$ossh_cache_var='no, fails at run time'" LDFLAGS="$saved_LDFLAGS" ], - [ AC_MSG_RESULT([yes]) + [ eval "$ossh_cache_var=yes" LDFLAGS="$saved_LDFLAGS $_define_flag" ] ) fi ], - [ AC_MSG_RESULT([no]) + [ eval "$ossh_cache_var=no" LDFLAGS="$saved_LDFLAGS" ] ) + ]) }]) dnl OSSH_CHECK_HEADER_FOR_FIELD(field, header, symbol) diff --git a/mac.c b/mac.c index f3dda66..c95f5ea 100644 --- a/mac.c +++ b/mac.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mac.c,v 1.35 2019/09/06 04:53:27 djm Exp $ */ +/* $OpenBSD: mac.c,v 1.37 2025/09/05 10:01:35 dtucker Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. * @@ -27,9 +27,9 @@ #include +#include #include #include -#include #include "digest.h" #include "hmac.h" @@ -83,22 +83,13 @@ static const struct macalg macs[] = { char * mac_alg_list(char sep) { - char *ret = NULL, *tmp; - size_t nlen, rlen = 0; + char *ret = NULL; const struct macalg *m; + char sep_str[2] = {sep, '\0'}; + + for (m = macs; m->name != NULL; m++) + xextendf(&ret, sep_str, "%s", m->name); - for (m = macs; m->name != NULL; m++) { - if (ret != NULL) - ret[rlen++] = sep; - nlen = strlen(m->name); - if ((tmp = realloc(ret, rlen + nlen + 2)) == NULL) { - free(ret); - return NULL; - } - ret = tmp; - memcpy(ret + rlen, m->name, nlen + 1); - rlen += nlen; - } return ret; } diff --git a/mdoc2man.awk b/mdoc2man.awk index d393ae6..02a04f7 100644 --- a/mdoc2man.awk +++ b/mdoc2man.awk @@ -239,7 +239,7 @@ function add(str) { while(w") - if(option) + for(;option;option--) add("]") if(ext&&!extopt&&!match(line," $")) add(OFS) diff --git a/misc-agent.c b/misc-agent.c new file mode 100644 index 0000000..07c8fb1 --- /dev/null +++ b/misc-agent.c @@ -0,0 +1,357 @@ +/* $OpenBSD: misc-agent.c,v 1.6 2025/06/17 01:19:27 djm Exp $ */ +/* + * Copyright (c) 2025 Damien Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "includes.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "digest.h" +#include "log.h" +#include "misc.h" +#include "pathnames.h" +#include "ssh.h" +#include "xmalloc.h" + +/* stuff shared by agent listeners (ssh-agent and sshd agent forwarding) */ + +#define SOCKET_HOSTNAME_HASHLEN 10 /* length of hostname hash in socket path */ + +/* used for presenting random strings in unix_listener_tmp and hostname_hash */ +static const char presentation_chars[] = + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + +/* returns a text-encoded hash of the hostname of specified length (max 64) */ +static char * +hostname_hash(size_t len) +{ + char hostname[NI_MAXHOST], p[65]; + u_char hash[64]; + int r; + size_t l, i; + + l = ssh_digest_bytes(SSH_DIGEST_SHA512); + if (len > 64) { + error_f("bad length %zu >= max %zd", len, l); + return NULL; + } + if (gethostname(hostname, sizeof(hostname)) == -1) { + error_f("gethostname: %s", strerror(errno)); + return NULL; + } + if ((r = ssh_digest_memory(SSH_DIGEST_SHA512, + hostname, strlen(hostname), hash, sizeof(hash))) != 0) { + error_fr(r, "ssh_digest_memory"); + return NULL; + } + memset(p, '\0', sizeof(p)); + for (i = 0; i < l; i++) + p[i] = presentation_chars[ + hash[i] % (sizeof(presentation_chars) - 1)]; + /* debug3_f("hostname \"%s\" => hash \"%s\"", hostname, p); */ + p[len] = '\0'; + return xstrdup(p); +} + +char * +agent_hostname_hash(void) +{ + return hostname_hash(SOCKET_HOSTNAME_HASHLEN); +} + +/* + * Creates a unix listener at a mkstemp(3)-style path, e.g. "/dir/sock.XXXXXX" + * Supplied path is modified to the actual one used. + */ +static int +unix_listener_tmp(char *path, int backlog) +{ + struct sockaddr_un sunaddr; + int good, sock = -1; + size_t i, xstart; + mode_t prev_mask; + + /* Find first 'X' template character back from end of string */ + xstart = strlen(path); + while (xstart > 0 && path[xstart - 1] == 'X') + xstart--; + + memset(&sunaddr, 0, sizeof(sunaddr)); + sunaddr.sun_family = AF_UNIX; + prev_mask = umask(0177); + for (good = 0; !good;) { + sock = -1; + /* Randomise path suffix */ + for (i = xstart; path[i] != '\0'; i++) { + path[i] = presentation_chars[ + arc4random_uniform(sizeof(presentation_chars)-1)]; + } + debug_f("trying path \"%s\"", path); + + 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); + break; + } + + if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) == -1) { + error_f("socket: %.100s", strerror(errno)); + break; + } + if (bind(sock, (struct sockaddr *)&sunaddr, + sizeof(sunaddr)) == -1) { + if (errno == EADDRINUSE) { + error_f("bind \"%s\": %.100s", + path, strerror(errno)); + close(sock); + sock = -1; + continue; + } + error_f("bind \"%s\": %.100s", path, strerror(errno)); + break; + } + if (listen(sock, backlog) == -1) { + error_f("listen \"%s\": %s", path, strerror(errno)); + break; + } + good = 1; + } + umask(prev_mask); + if (good) { + debug3_f("listening on unix socket \"%s\" as fd=%d", + path, sock); + } else if (sock != -1) { + close(sock); + sock = -1; + } + return sock; +} + +/* + * Create a subdirectory under the supplied home directory if it + * doesn't already exist + */ +static int +ensure_mkdir(const char *homedir, const char *subdir) +{ + char *path; + + xasprintf(&path, "%s/%s", homedir, subdir); + if (mkdir(path, 0700) == 0) + debug("created directory %s", path); + else if (errno != EEXIST) { + error_f("mkdir %s: %s", path, strerror(errno)); + free(path); + return -1; + } + free(path); + return 0; +} + +static int +agent_prepare_sockdir(const char *homedir) +{ + if (homedir == NULL || *homedir == '\0' || + ensure_mkdir(homedir, _PATH_SSH_USER_DIR) != 0 || + ensure_mkdir(homedir, _PATH_SSH_AGENT_SOCKET_DIR) != 0) + return -1; + return 0; +} + + +/* Get a path template for an agent socket in the user's homedir */ +static char * +agent_socket_template(const char *homedir, const char *tag) +{ + char *hostnamehash, *ret; + + if ((hostnamehash = hostname_hash(SOCKET_HOSTNAME_HASHLEN)) == NULL) + return NULL; + xasprintf(&ret, "%s/%s/s.%s.%s.XXXXXXXXXX", + homedir, _PATH_SSH_AGENT_SOCKET_DIR, hostnamehash, tag); + free(hostnamehash); + return ret; +} + +int +agent_listener(const char *homedir, const char *tag, int *sockp, char **pathp) +{ + int sock; + char *path; + + *sockp = -1; + *pathp = NULL; + + if (agent_prepare_sockdir(homedir) != 0) + return -1; /* error already logged */ + if ((path = agent_socket_template(homedir, tag)) == NULL) + return -1; /* error already logged */ + if ((sock = unix_listener_tmp(path, SSH_LISTEN_BACKLOG)) == -1) { + free(path); + return -1; /* error already logged */ + } + /* success */ + *sockp = sock; + *pathp = path; + return 0; +} + +static int +socket_is_stale(const char *path) +{ + int fd, r; + struct sockaddr_un sunaddr; + socklen_t l = sizeof(r); + + /* attempt non-blocking connect on socket */ + memset(&sunaddr, '\0', sizeof(sunaddr)); + sunaddr.sun_family = AF_UNIX; + if (strlcpy(sunaddr.sun_path, path, + sizeof(sunaddr.sun_path)) >= sizeof(sunaddr.sun_path)) { + debug_f("path for \"%s\" too long for sockaddr_un", path); + return 0; + } + if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) == -1) { + error_f("socket: %s", strerror(errno)); + return 0; + } + set_nonblock(fd); + /* a socket without a listener should yield an error immediately */ + if (connect(fd, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) == -1) { + debug_f("connect \"%s\": %s", path, strerror(errno)); + close(fd); + return 1; + } + if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &r, &l) == -1) { + debug_f("getsockopt: %s", strerror(errno)); + close(fd); + return 0; + } + if (r != 0) { + debug_f("socket error on %s: %s", path, strerror(errno)); + close(fd); + return 1; + } + close(fd); + debug_f("socket %s seems still active", path); + return 0; +} + +#ifndef HAVE_FSTATAT +# define fstatat(x, y, buf, z) lstat(path, buf) +#endif +#ifndef HAVE_UNLINKAT +# define unlinkat(x, y, z) unlink(path) +#endif + +void +agent_cleanup_stale(const char *homedir, int ignore_hosthash) +{ + DIR *d = NULL; + struct dirent *dp; + struct stat sb; + char *prefix = NULL, *dirpath = NULL, *path = NULL; + struct timespec now, sub, *mtimp = NULL; + + /* Only consider sockets last modified > 1 hour ago */ + if (clock_gettime(CLOCK_REALTIME, &now) != 0) { + error_f("clock_gettime: %s", strerror(errno)); + return; + } + sub.tv_sec = 60 * 60; + sub.tv_nsec = 0; + timespecsub(&now, &sub, &now); + + /* Only consider sockets from the same hostname */ + if (!ignore_hosthash) { + if ((path = agent_hostname_hash()) == NULL) { + error_f("couldn't get hostname hash"); + return; + } + xasprintf(&prefix, "s.%s.", path); + free(path); + path = NULL; + } + + xasprintf(&dirpath, "%s/%s", homedir, _PATH_SSH_AGENT_SOCKET_DIR); + if ((d = opendir(dirpath)) == NULL) { + if (errno != ENOENT) + error_f("opendir \"%s\": %s", dirpath, strerror(errno)); + goto out; + } + + path = NULL; + while ((dp = readdir(d)) != NULL) { + free(path); + xasprintf(&path, "%s/%s", dirpath, dp->d_name); +#ifdef HAVE_DIRENT_D_TYPE + if (dp->d_type != DT_SOCK && dp->d_type != DT_UNKNOWN) + continue; +#endif + if (fstatat(dirfd(d), dp->d_name, + &sb, AT_SYMLINK_NOFOLLOW) != 0 && errno != ENOENT) { + error_f("stat \"%s/%s\": %s", + dirpath, dp->d_name, strerror(errno)); + continue; + } + if (!S_ISSOCK(sb.st_mode)) + continue; +#ifdef HAVE_STRUCT_STAT_ST_MTIM + mtimp = &sb.st_mtim; +#else + sub.tv_sec = sb.st_mtime; + sub.tv_nsec = 0; + mtimp = ⊂ +#endif + if (timespeccmp(mtimp, &now, >)) { + debug3_f("Ignoring recent socket \"%s/%s\"", + dirpath, dp->d_name); + continue; + } + if (!ignore_hosthash && + strncmp(dp->d_name, prefix, strlen(prefix)) != 0) { + debug3_f("Ignoring socket \"%s/%s\" " + "from different host", dirpath, dp->d_name); + continue; + } + if (socket_is_stale(path)) { + debug_f("cleanup stale socket %s", path); + unlinkat(dirfd(d), dp->d_name, 0); + } + } + out: + if (d != NULL) + closedir(d); + free(path); + free(dirpath); + free(prefix); +} + +#undef unlinkat +#undef fstatat diff --git a/misc.c b/misc.c index 1b4b55c..ce77ec9 100644 --- a/misc.c +++ b/misc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: misc.c,v 1.197 2024/09/25 01:24:04 djm Exp $ */ +/* $OpenBSD: misc.c,v 1.208 2025/09/25 06:33:19 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2005-2020 Damien Miller. All rights reserved. @@ -30,21 +30,13 @@ #include #include -#ifdef HAVE_LIBGEN_H -# include -#endif -#ifdef HAVE_POLL_H +#include #include -#endif -#ifdef HAVE_NLIST_H #include -#endif #include #include #include -#ifdef HAVE_STDINT_H -# include -#endif +#include #include #include #include @@ -60,11 +52,9 @@ #include #include #include -#ifdef HAVE_PATHS_H -# include +#include #include #include -#endif #ifdef SSH_TUN_OPENBSD #include #endif @@ -101,10 +91,13 @@ rtrim(char *s) if ((i = strlen(s)) == 0) return; - for (i--; i > 0; i--) { + do { + i--; if (isspace((unsigned char)s[i])) s[i] = '\0'; - } + else + break; + } while (i > 0); } /* @@ -297,6 +290,10 @@ set_sock_tos(int fd, int tos) #ifndef IP_TOS_IS_BROKEN int af; + if (tos < 0 || tos == INT_MAX) { + debug_f("invalid TOS %d", tos); + return; + } switch ((af = get_sock_af(fd))) { case -1: /* assume not a socket */ @@ -483,7 +480,7 @@ strdelim_internal(char **s, int split_equals) } /* - * Return next token in configuration line; splts on whitespace or a + * Return next token in configuration line; splits on whitespace or a * single '=' character. */ char * @@ -493,7 +490,7 @@ strdelim(char **s) } /* - * Return next token in configuration line; splts on whitespace only. + * Return next token in configuration line; splits on whitespace only. */ char * strdelimw(char **s) @@ -509,7 +506,7 @@ pwcopy(struct passwd *pw) 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); + copy->pw_gecos = xstrdup(pw->pw_gecos == NULL ? "" : pw->pw_gecos); #endif copy->pw_uid = pw->pw_uid; copy->pw_gid = pw->pw_gid; @@ -520,13 +517,32 @@ pwcopy(struct passwd *pw) copy->pw_change = pw->pw_change; #endif #ifdef HAVE_STRUCT_PASSWD_PW_CLASS - copy->pw_class = xstrdup(pw->pw_class); + copy->pw_class = xstrdup(pw->pw_class == NULL ? "" : pw->pw_class); #endif - copy->pw_dir = xstrdup(pw->pw_dir); - copy->pw_shell = xstrdup(pw->pw_shell); + copy->pw_dir = xstrdup(pw->pw_dir == NULL ? "" : pw->pw_dir); + copy->pw_shell = xstrdup(pw->pw_shell == NULL ? "" : pw->pw_shell); return copy; } +void +pwfree(struct passwd *pw) +{ + if (pw == NULL) + return; + free(pw->pw_name); + freezero(pw->pw_passwd, + pw->pw_passwd == NULL ? 0 : strlen(pw->pw_passwd)); +#ifdef HAVE_STRUCT_PASSWD_PW_GECOS + free(pw->pw_gecos); +#endif +#ifdef HAVE_STRUCT_PASSWD_PW_CLASS + free(pw->pw_class); +#endif + free(pw->pw_dir); + free(pw->pw_shell); + freezero(pw, sizeof(*pw)); +} + /* * Convert ASCII string to TCP/IP port number. * Port must be >=0 and <=65535. @@ -990,7 +1006,7 @@ urldecode(const char *src) size_t srclen; if ((srclen = strlen(src)) >= SIZE_MAX) - fatal_f("input too large"); + return NULL; ret = xmalloc(srclen + 1); for (dst = ret; *src != '\0'; src++) { switch (*src) { @@ -998,9 +1014,10 @@ urldecode(const char *src) *dst++ = ' '; break; case '%': + /* note: don't allow \0 characters */ if (!isxdigit((unsigned char)src[1]) || !isxdigit((unsigned char)src[2]) || - (ch = hexchar(src + 1)) == -1) { + (ch = hexchar(src + 1)) == -1 || ch == 0) { free(ret); return NULL; } @@ -1885,9 +1902,9 @@ static const struct { { "cs7", IPTOS_DSCP_CS7 }, { "ef", IPTOS_DSCP_EF }, { "le", IPTOS_DSCP_LE }, - { "lowdelay", IPTOS_LOWDELAY }, - { "throughput", IPTOS_THROUGHPUT }, - { "reliability", IPTOS_RELIABILITY }, + { "lowdelay", INT_MIN }, /* deprecated */ + { "throughput", INT_MIN }, /* deprecated */ + { "reliability", INT_MIN }, /* deprecated */ { NULL, -1 } }; @@ -1982,7 +1999,7 @@ sock_set_v6only(int s) #if defined(IPV6_V6ONLY) && !defined(__OpenBSD__) int on = 1; - debug3("%s: set socket %d IPV6_V6ONLY", __func__, s); + debug3_f("set socket %d IPV6_V6ONLY", s); if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) == -1) error("setsockopt IPV6_V6ONLY: %s", strerror(errno)); #endif @@ -2254,7 +2271,7 @@ 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 buf[PATH_MAX], buf2[PATH_MAX], homedir[PATH_MAX]; char *cp; int comparehome = 0; struct stat st; @@ -2280,7 +2297,12 @@ safe_path(const char *name, struct stat *stp, const char *pw_dir, /* for each component of the canonical path, walking upwards */ for (;;) { - if ((cp = dirname(buf)) == NULL) { + /* + * POSIX allows dirname to modify its argument and return a + * pointer into it, so make a copy to avoid overlapping strlcpy. + */ + strlcpy(buf2, buf, sizeof(buf2)); + if ((cp = dirname(buf2)) == NULL) { snprintf(err, errlen, "dirname() failed"); return -1; } @@ -2406,7 +2428,8 @@ valid_domain(char *name, int makelower, const char **errstr) strlcpy(errbuf, "empty domain name", sizeof(errbuf)); goto bad; } - if (!isalpha((u_char)name[0]) && !isdigit((u_char)name[0])) { + if (!isalpha((u_char)name[0]) && !isdigit((u_char)name[0]) && + name[0] != '_' /* technically invalid, but common */) { snprintf(errbuf, sizeof(errbuf), "domain name \"%.100s\" " "starts with invalid character", name); goto bad; @@ -2534,8 +2557,10 @@ 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); + if (localtime_r(&tt, &tm) == NULL) + strlcpy(buf, "UNKNOWN-TIME", len); + else + strftime(buf, len, "%Y-%m-%dT%H:%M:%S", &tm); } /* @@ -3057,7 +3082,7 @@ ptimeout_isset(struct timespec *pt) int lib_contains_symbol(const char *path, const char *s) { -#ifdef HAVE_NLIST_H +#ifdef HAVE_NLIST struct nlist nl[2]; int ret = -1, r; @@ -3077,7 +3102,7 @@ lib_contains_symbol(const char *path, const char *s) out: free(nl[0].n_name); return ret; -#else /* HAVE_NLIST_H */ +#else /* HAVE_NLIST */ int fd, ret = -1; struct stat st; void *m = NULL; @@ -3119,7 +3144,7 @@ lib_contains_symbol(const char *path, const char *s) munmap(m, sz); close(fd); return ret; -#endif /* HAVE_NLIST_H */ +#endif /* HAVE_NLIST */ } int @@ -3137,3 +3162,18 @@ signal_is_crash(int sig) } return 0; } + +char * +get_homedir(void) +{ + char *cp; + struct passwd *pw; + + if ((cp = getenv("HOME")) != NULL && *cp != '\0') + return xstrdup(cp); + + if ((pw = getpwuid(getuid())) != NULL && *pw->pw_dir != '\0') + return xstrdup(pw->pw_dir); + + return NULL; +} diff --git a/misc.h b/misc.h index efecdf1..f3c5a18 100644 --- a/misc.h +++ b/misc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: misc.h,v 1.110 2024/09/25 01:24:04 djm Exp $ */ +/* $OpenBSD: misc.h,v 1.112 2025/09/25 06:33:19 djm Exp $ */ /* * Author: Tatu Ylonen @@ -108,10 +108,12 @@ int parse_pattern_interval(const char *, char **, int *); int path_absolute(const char *); int stdfd_devnull(int, int, int); int lib_contains_symbol(const char *, const char *); +char *get_homedir(void); void sock_set_v6only(int); struct passwd *pwcopy(struct passwd *); +void pwfree(struct passwd *); /* NB. only use with pwcopy */ const char *ssh_gai_strerror(int); typedef void privdrop_fn(struct passwd *); @@ -231,6 +233,11 @@ int ptimeout_get_ms(struct timespec *pt); struct timespec *ptimeout_get_tsp(struct timespec *pt); int ptimeout_isset(struct timespec *pt); +/* misc-agent.c */ +char *agent_hostname_hash(void); +int agent_listener(const char *, const char *, int *, char **); +void agent_cleanup_stale(const char *, int); + /* readpass.c */ #define RP_ECHO 0x0001 diff --git a/mlkem768.sh b/mlkem768.sh index 3d12b2e..cbc3d14 100644 --- a/mlkem768.sh +++ b/mlkem768.sh @@ -49,6 +49,11 @@ echo '#define KRML_HOST_EPRINTF(...)' echo '#define KRML_HOST_EXIT(x) fatal_f("internal error")' echo +__builtin_popcount_replacement=' + const uint8_t v[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 }; + return v[x0 & 0xf] + v[(x0 >> 4) & 0xf]; +' + for i in $FILES; do echo "/* from $i */" # Changes to all files: @@ -62,7 +67,10 @@ for i in $FILES; do # Replace endian functions with versions that work. perl -0777 -pe 's/(static inline void core_num__u64_9__to_le_bytes.*\n)([^}]*\n)/\1 v = htole64(v);\n\2/' | perl -0777 -pe 's/(static inline uint64_t core_num__u64_9__from_le_bytes.*?)return v;/\1return le64toh(v);/s' | - perl -0777 -pe 's/(static inline uint32_t core_num__u32_8__from_le_bytes.*?)return v;/\1return le32toh(v);/s' + perl -0777 -pe 's/(static inline uint32_t core_num__u32_8__from_le_bytes.*?)return v;/\1return le32toh(v);/s' | + # Compat for popcount. + perl -0777 -pe 's/\#ifdef (_MSC_VER)(.*?return __popcnt\(x0\);)/\#if defined(\1)\2/s' | + perl -0777 -pe "s/\\#else(\\n\\s+return __builtin_popcount\\(x0\\);)/\\#elif !defined(MISSING_BUILTIN_POPCOUNT)\\1\\n#else$__builtin_popcount_replacement/s" ;; # Default: pass through. *) diff --git a/moduli b/moduli index bebd3a9..2fe04ab 100644 --- a/moduli +++ b/moduli @@ -1,412 +1,427 @@ -# $OpenBSD: moduli,v 1.38 2024/08/21 07:06:27 dtucker Exp $ +# $OpenBSD: moduli,v 1.40 2025/05/23 01:14:35 dtucker Exp $ # Time Type Tests Tries Size Generator Modulus -20240326013051 2 6 100 2047 2 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A85DDC5DFB -20240326013055 2 6 100 2047 5 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A85DF8EE9F -20240326013100 2 6 100 2047 5 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A85E15B2AF -20240326013115 2 6 100 2047 2 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A85E8800BB -20240326013121 2 6 100 2047 5 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A85EA93D9F -20240326013127 2 6 100 2047 5 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A85ED33B77 -20240326013129 2 6 100 2047 2 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A85EDE96FB -20240326013133 2 6 100 2047 2 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A85EFDC7AB -20240326013135 2 6 100 2047 5 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A85F004B07 -20240326013147 2 6 100 2047 2 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A85F5A20FB -20240326013151 2 6 100 2047 5 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A85F780007 -20240326013154 2 6 100 2047 5 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A85F873847 -20240326013155 2 6 100 2047 5 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A85F8792BF -20240326013158 2 6 100 2047 2 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A85F99602B -20240326013212 2 6 100 2047 5 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A85FFDCCE7 -20240326013219 2 6 100 2047 5 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A86033F8F7 -20240326013239 2 6 100 2047 5 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A860C92607 -20240326013244 2 6 100 2047 5 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A860EACC9F -20240326013252 2 6 100 2047 2 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A8612623A3 -20240326013254 2 6 100 2047 2 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A86131122B -20240326013256 2 6 100 2047 2 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A86137AE5B -20240326013316 2 6 100 2047 2 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A861CE9FAB -20240326013319 2 6 100 2047 2 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A861DDF033 -20240326013322 2 6 100 2047 5 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A861F71477 -20240326013330 2 6 100 2047 5 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A8622DF73F -20240326013333 2 6 100 2047 2 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A8623FA97B -20240326013347 2 6 100 2047 2 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A862A6F8D3 -20240326013357 2 6 100 2047 2 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A862EDADB3 -20240326013401 2 6 100 2047 5 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A86306A44F -20240326013402 2 6 100 2047 5 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A8630A4F4F -20240326013406 2 6 100 2047 5 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A86329C6AF -20240326013412 2 6 100 2047 5 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A8634D56D7 -20240326013433 2 6 100 2047 5 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A863ECB6D7 -20240326013438 2 6 100 2047 5 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A8640E99FF -20240326013448 2 6 100 2047 2 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A86456D45B -20240326013455 2 6 100 2047 5 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A8648DB9CF -20240326013456 2 6 100 2047 2 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A86490C78B -20240326013506 2 6 100 2047 5 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A864D48787 -20240326013511 2 6 100 2047 2 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A864F4C14B -20240326013522 2 6 100 2047 5 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A86546E877 -20240326013524 2 6 100 2047 2 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A8654FB6D3 -20240326013529 2 6 100 2047 2 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A865742D0B -20240326013534 2 6 100 2047 2 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A8659900A3 -20240326013537 2 6 100 2047 5 D221068E02C30ED0DB86E4A0861A1E810B7BB629273F85D3706B90056B2CF34C342FF875ACADDDF5E49A87B1B038567EB05D77EADB0905CD24ECC8240F5EF15DCF197BBF61895F00DDD75D949C9BFF7066625602DBD460D9EA7D9E06F70AA721011BE246139444E9AB4ABFCCCB1A5943E67BF7D3AA5ADCF214945B1E7D8E40E44BD60D9ECD3C5E151944467F1B3DD3CFEDEA7C15CAD12F4F9AC78C7E0DEE2E15713C13FAFDC297DF06F3FB0BEBD1F481C642527085FAF48A29CB1BE20D5FE235E29345BF213C475F5A20CFA960E716987614825120EA968864837EEB68DB47A1F3336927BB9ADCC54A4341228289F92F9E23F1FFFB1E59DFCA8017A865A3FE37 -20240326013538 2 6 100 2047 5 F7B6DB1359F90C032532089BF3BAE4A2ED1209EE181E517D24238A7EDF32489C1E6F3DBA19C01489FF3B6A2764E932B108218462111D8C834EB642726F08FDBEEBC08DC25A2ABD10D72DE4053EF4B48AD385A0EB97F1EF96F01BAA45AA914BAD8096B97919F724C1075FCFBA43119006C61A5F4E991B791E1056730CF19E9215B482F6047104269C1122AA14A76B5537621C0A620CE4BD63A70B898E002D19BD2897A1D036B6283EF9CB8ADF92806CAEA8AEFCDE63F945C5F098E11824BE3493225F9848E08F4AAB4E4C3621D8AF209C02058683332CE1163D158C484ECF99095C889B900127DE4367D2A8433E5D23DAB5F5AEBDA97C425F8B169759F049F51F -20240326013547 2 6 100 2047 2 F7B6DB1359F90C032532089BF3BAE4A2ED1209EE181E517D24238A7EDF32489C1E6F3DBA19C01489FF3B6A2764E932B108218462111D8C834EB642726F08FDBEEBC08DC25A2ABD10D72DE4053EF4B48AD385A0EB97F1EF96F01BAA45AA914BAD8096B97919F724C1075FCFBA43119006C61A5F4E991B791E1056730CF19E9215B482F6047104269C1122AA14A76B5537621C0A620CE4BD63A70B898E002D19BD2897A1D036B6283EF9CB8ADF92806CAEA8AEFCDE63F945C5F098E11824BE3493225F9848E08F4AAB4E4C3621D8AF209C02058683332CE1163D158C484ECF99095C889B900127DE4367D2A8433E5D23DAB5F5AEBDA97C425F8B169759F0859D0B -20240326013554 2 6 100 2047 5 F7B6DB1359F90C032532089BF3BAE4A2ED1209EE181E517D24238A7EDF32489C1E6F3DBA19C01489FF3B6A2764E932B108218462111D8C834EB642726F08FDBEEBC08DC25A2ABD10D72DE4053EF4B48AD385A0EB97F1EF96F01BAA45AA914BAD8096B97919F724C1075FCFBA43119006C61A5F4E991B791E1056730CF19E9215B482F6047104269C1122AA14A76B5537621C0A620CE4BD63A70B898E002D19BD2897A1D036B6283EF9CB8ADF92806CAEA8AEFCDE63F945C5F098E11824BE3493225F9848E08F4AAB4E4C3621D8AF209C02058683332CE1163D158C484ECF99095C889B900127DE4367D2A8433E5D23DAB5F5AEBDA97C425F8B169759F0BBD077 -20240326013607 2 6 100 2047 2 F7B6DB1359F90C032532089BF3BAE4A2ED1209EE181E517D24238A7EDF32489C1E6F3DBA19C01489FF3B6A2764E932B108218462111D8C834EB642726F08FDBEEBC08DC25A2ABD10D72DE4053EF4B48AD385A0EB97F1EF96F01BAA45AA914BAD8096B97919F724C1075FCFBA43119006C61A5F4E991B791E1056730CF19E9215B482F6047104269C1122AA14A76B5537621C0A620CE4BD63A70B898E002D19BD2897A1D036B6283EF9CB8ADF92806CAEA8AEFCDE63F945C5F098E11824BE3493225F9848E08F4AAB4E4C3621D8AF209C02058683332CE1163D158C484ECF99095C889B900127DE4367D2A8433E5D23DAB5F5AEBDA97C425F8B169759F11279FB -20240326013628 2 6 100 2047 2 F7B6DB1359F90C032532089BF3BAE4A2ED1209EE181E517D24238A7EDF32489C1E6F3DBA19C01489FF3B6A2764E932B108218462111D8C834EB642726F08FDBEEBC08DC25A2ABD10D72DE4053EF4B48AD385A0EB97F1EF96F01BAA45AA914BAD8096B97919F724C1075FCFBA43119006C61A5F4E991B791E1056730CF19E9215B482F6047104269C1122AA14A76B5537621C0A620CE4BD63A70B898E002D19BD2897A1D036B6283EF9CB8ADF92806CAEA8AEFCDE63F945C5F098E11824BE3493225F9848E08F4AAB4E4C3621D8AF209C02058683332CE1163D158C484ECF99095C889B900127DE4367D2A8433E5D23DAB5F5AEBDA97C425F8B169759F1B2B0DB -20240326013645 2 6 100 2047 5 F7B6DB1359F90C032532089BF3BAE4A2ED1209EE181E517D24238A7EDF32489C1E6F3DBA19C01489FF3B6A2764E932B108218462111D8C834EB642726F08FDBEEBC08DC25A2ABD10D72DE4053EF4B48AD385A0EB97F1EF96F01BAA45AA914BAD8096B97919F724C1075FCFBA43119006C61A5F4E991B791E1056730CF19E9215B482F6047104269C1122AA14A76B5537621C0A620CE4BD63A70B898E002D19BD2897A1D036B6283EF9CB8ADF92806CAEA8AEFCDE63F945C5F098E11824BE3493225F9848E08F4AAB4E4C3621D8AF209C02058683332CE1163D158C484ECF99095C889B900127DE4367D2A8433E5D23DAB5F5AEBDA97C425F8B169759F22EA4A7 -20240326013653 2 6 100 2047 2 F7B6DB1359F90C032532089BF3BAE4A2ED1209EE181E517D24238A7EDF32489C1E6F3DBA19C01489FF3B6A2764E932B108218462111D8C834EB642726F08FDBEEBC08DC25A2ABD10D72DE4053EF4B48AD385A0EB97F1EF96F01BAA45AA914BAD8096B97919F724C1075FCFBA43119006C61A5F4E991B791E1056730CF19E9215B482F6047104269C1122AA14A76B5537621C0A620CE4BD63A70B898E002D19BD2897A1D036B6283EF9CB8ADF92806CAEA8AEFCDE63F945C5F098E11824BE3493225F9848E08F4AAB4E4C3621D8AF209C02058683332CE1163D158C484ECF99095C889B900127DE4367D2A8433E5D23DAB5F5AEBDA97C425F8B169759F266CCCB -20240326013656 2 6 100 2047 2 F7B6DB1359F90C032532089BF3BAE4A2ED1209EE181E517D24238A7EDF32489C1E6F3DBA19C01489FF3B6A2764E932B108218462111D8C834EB642726F08FDBEEBC08DC25A2ABD10D72DE4053EF4B48AD385A0EB97F1EF96F01BAA45AA914BAD8096B97919F724C1075FCFBA43119006C61A5F4E991B791E1056730CF19E9215B482F6047104269C1122AA14A76B5537621C0A620CE4BD63A70B898E002D19BD2897A1D036B6283EF9CB8ADF92806CAEA8AEFCDE63F945C5F098E11824BE3493225F9848E08F4AAB4E4C3621D8AF209C02058683332CE1163D158C484ECF99095C889B900127DE4367D2A8433E5D23DAB5F5AEBDA97C425F8B169759F27B8CC3 -20240326013704 2 6 100 2047 2 F7B6DB1359F90C032532089BF3BAE4A2ED1209EE181E517D24238A7EDF32489C1E6F3DBA19C01489FF3B6A2764E932B108218462111D8C834EB642726F08FDBEEBC08DC25A2ABD10D72DE4053EF4B48AD385A0EB97F1EF96F01BAA45AA914BAD8096B97919F724C1075FCFBA43119006C61A5F4E991B791E1056730CF19E9215B482F6047104269C1122AA14A76B5537621C0A620CE4BD63A70B898E002D19BD2897A1D036B6283EF9CB8ADF92806CAEA8AEFCDE63F945C5F098E11824BE3493225F9848E08F4AAB4E4C3621D8AF209C02058683332CE1163D158C484ECF99095C889B900127DE4367D2A8433E5D23DAB5F5AEBDA97C425F8B169759F2B6898B -20240326013728 2 6 100 2047 5 F7B6DB1359F90C032532089BF3BAE4A2ED1209EE181E517D24238A7EDF32489C1E6F3DBA19C01489FF3B6A2764E932B108218462111D8C834EB642726F08FDBEEBC08DC25A2ABD10D72DE4053EF4B48AD385A0EB97F1EF96F01BAA45AA914BAD8096B97919F724C1075FCFBA43119006C61A5F4E991B791E1056730CF19E9215B482F6047104269C1122AA14A76B5537621C0A620CE4BD63A70B898E002D19BD2897A1D036B6283EF9CB8ADF92806CAEA8AEFCDE63F945C5F098E11824BE3493225F9848E08F4AAB4E4C3621D8AF209C02058683332CE1163D158C484ECF99095C889B900127DE4367D2A8433E5D23DAB5F5AEBDA97C425F8B169759F3661F27 -20240326013732 2 6 100 2047 5 F7B6DB1359F90C032532089BF3BAE4A2ED1209EE181E517D24238A7EDF32489C1E6F3DBA19C01489FF3B6A2764E932B108218462111D8C834EB642726F08FDBEEBC08DC25A2ABD10D72DE4053EF4B48AD385A0EB97F1EF96F01BAA45AA914BAD8096B97919F724C1075FCFBA43119006C61A5F4E991B791E1056730CF19E9215B482F6047104269C1122AA14A76B5537621C0A620CE4BD63A70B898E002D19BD2897A1D036B6283EF9CB8ADF92806CAEA8AEFCDE63F945C5F098E11824BE3493225F9848E08F4AAB4E4C3621D8AF209C02058683332CE1163D158C484ECF99095C889B900127DE4367D2A8433E5D23DAB5F5AEBDA97C425F8B169759F382F33F -20240326013755 2 6 100 2047 2 F7B6DB1359F90C032532089BF3BAE4A2ED1209EE181E517D24238A7EDF32489C1E6F3DBA19C01489FF3B6A2764E932B108218462111D8C834EB642726F08FDBEEBC08DC25A2ABD10D72DE4053EF4B48AD385A0EB97F1EF96F01BAA45AA914BAD8096B97919F724C1075FCFBA43119006C61A5F4E991B791E1056730CF19E9215B482F6047104269C1122AA14A76B5537621C0A620CE4BD63A70B898E002D19BD2897A1D036B6283EF9CB8ADF92806CAEA8AEFCDE63F945C5F098E11824BE3493225F9848E08F4AAB4E4C3621D8AF209C02058683332CE1163D158C484ECF99095C889B900127DE4367D2A8433E5D23DAB5F5AEBDA97C425F8B169759F42B19A3 -20240326013815 2 6 100 2047 5 F7B6DB1359F90C032532089BF3BAE4A2ED1209EE181E517D24238A7EDF32489C1E6F3DBA19C01489FF3B6A2764E932B108218462111D8C834EB642726F08FDBEEBC08DC25A2ABD10D72DE4053EF4B48AD385A0EB97F1EF96F01BAA45AA914BAD8096B97919F724C1075FCFBA43119006C61A5F4E991B791E1056730CF19E9215B482F6047104269C1122AA14A76B5537621C0A620CE4BD63A70B898E002D19BD2897A1D036B6283EF9CB8ADF92806CAEA8AEFCDE63F945C5F098E11824BE3493225F9848E08F4AAB4E4C3621D8AF209C02058683332CE1163D158C484ECF99095C889B900127DE4367D2A8433E5D23DAB5F5AEBDA97C425F8B169759F4BFFC7F -20240326013816 2 6 100 2047 2 F7B6DB1359F90C032532089BF3BAE4A2ED1209EE181E517D24238A7EDF32489C1E6F3DBA19C01489FF3B6A2764E932B108218462111D8C834EB642726F08FDBEEBC08DC25A2ABD10D72DE4053EF4B48AD385A0EB97F1EF96F01BAA45AA914BAD8096B97919F724C1075FCFBA43119006C61A5F4E991B791E1056730CF19E9215B482F6047104269C1122AA14A76B5537621C0A620CE4BD63A70B898E002D19BD2897A1D036B6283EF9CB8ADF92806CAEA8AEFCDE63F945C5F098E11824BE3493225F9848E08F4AAB4E4C3621D8AF209C02058683332CE1163D158C484ECF99095C889B900127DE4367D2A8433E5D23DAB5F5AEBDA97C425F8B169759F4C4D313 -20240326013818 2 6 100 2047 5 F7B6DB1359F90C032532089BF3BAE4A2ED1209EE181E517D24238A7EDF32489C1E6F3DBA19C01489FF3B6A2764E932B108218462111D8C834EB642726F08FDBEEBC08DC25A2ABD10D72DE4053EF4B48AD385A0EB97F1EF96F01BAA45AA914BAD8096B97919F724C1075FCFBA43119006C61A5F4E991B791E1056730CF19E9215B482F6047104269C1122AA14A76B5537621C0A620CE4BD63A70B898E002D19BD2897A1D036B6283EF9CB8ADF92806CAEA8AEFCDE63F945C5F098E11824BE3493225F9848E08F4AAB4E4C3621D8AF209C02058683332CE1163D158C484ECF99095C889B900127DE4367D2A8433E5D23DAB5F5AEBDA97C425F8B169759F4CB895F -20240326013838 2 6 100 2047 2 F7B6DB1359F90C032532089BF3BAE4A2ED1209EE181E517D24238A7EDF32489C1E6F3DBA19C01489FF3B6A2764E932B108218462111D8C834EB642726F08FDBEEBC08DC25A2ABD10D72DE4053EF4B48AD385A0EB97F1EF96F01BAA45AA914BAD8096B97919F724C1075FCFBA43119006C61A5F4E991B791E1056730CF19E9215B482F6047104269C1122AA14A76B5537621C0A620CE4BD63A70B898E002D19BD2897A1D036B6283EF9CB8ADF92806CAEA8AEFCDE63F945C5F098E11824BE3493225F9848E08F4AAB4E4C3621D8AF209C02058683332CE1163D158C484ECF99095C889B900127DE4367D2A8433E5D23DAB5F5AEBDA97C425F8B169759F55F34E3 -20240326013843 2 6 100 2047 2 F7B6DB1359F90C032532089BF3BAE4A2ED1209EE181E517D24238A7EDF32489C1E6F3DBA19C01489FF3B6A2764E932B108218462111D8C834EB642726F08FDBEEBC08DC25A2ABD10D72DE4053EF4B48AD385A0EB97F1EF96F01BAA45AA914BAD8096B97919F724C1075FCFBA43119006C61A5F4E991B791E1056730CF19E9215B482F6047104269C1122AA14A76B5537621C0A620CE4BD63A70B898E002D19BD2897A1D036B6283EF9CB8ADF92806CAEA8AEFCDE63F945C5F098E11824BE3493225F9848E08F4AAB4E4C3621D8AF209C02058683332CE1163D158C484ECF99095C889B900127DE4367D2A8433E5D23DAB5F5AEBDA97C425F8B169759F581582B -20240326013845 2 6 100 2047 5 F7B6DB1359F90C032532089BF3BAE4A2ED1209EE181E517D24238A7EDF32489C1E6F3DBA19C01489FF3B6A2764E932B108218462111D8C834EB642726F08FDBEEBC08DC25A2ABD10D72DE4053EF4B48AD385A0EB97F1EF96F01BAA45AA914BAD8096B97919F724C1075FCFBA43119006C61A5F4E991B791E1056730CF19E9215B482F6047104269C1122AA14A76B5537621C0A620CE4BD63A70B898E002D19BD2897A1D036B6283EF9CB8ADF92806CAEA8AEFCDE63F945C5F098E11824BE3493225F9848E08F4AAB4E4C3621D8AF209C02058683332CE1163D158C484ECF99095C889B900127DE4367D2A8433E5D23DAB5F5AEBDA97C425F8B169759F58BB9BF -20240326013904 2 6 100 2047 2 F7B6DB1359F90C032532089BF3BAE4A2ED1209EE181E517D24238A7EDF32489C1E6F3DBA19C01489FF3B6A2764E932B108218462111D8C834EB642726F08FDBEEBC08DC25A2ABD10D72DE4053EF4B48AD385A0EB97F1EF96F01BAA45AA914BAD8096B97919F724C1075FCFBA43119006C61A5F4E991B791E1056730CF19E9215B482F6047104269C1122AA14A76B5537621C0A620CE4BD63A70B898E002D19BD2897A1D036B6283EF9CB8ADF92806CAEA8AEFCDE63F945C5F098E11824BE3493225F9848E08F4AAB4E4C3621D8AF209C02058683332CE1163D158C484ECF99095C889B900127DE4367D2A8433E5D23DAB5F5AEBDA97C425F8B169759F61FCE5B -20240326013920 2 6 100 2047 5 F7B6DB1359F90C032532089BF3BAE4A2ED1209EE181E517D24238A7EDF32489C1E6F3DBA19C01489FF3B6A2764E932B108218462111D8C834EB642726F08FDBEEBC08DC25A2ABD10D72DE4053EF4B48AD385A0EB97F1EF96F01BAA45AA914BAD8096B97919F724C1075FCFBA43119006C61A5F4E991B791E1056730CF19E9215B482F6047104269C1122AA14A76B5537621C0A620CE4BD63A70B898E002D19BD2897A1D036B6283EF9CB8ADF92806CAEA8AEFCDE63F945C5F098E11824BE3493225F9848E08F4AAB4E4C3621D8AF209C02058683332CE1163D158C484ECF99095C889B900127DE4367D2A8433E5D23DAB5F5AEBDA97C425F8B169759F69490CF -20240326013923 2 6 100 2047 2 F7B6DB1359F90C032532089BF3BAE4A2ED1209EE181E517D24238A7EDF32489C1E6F3DBA19C01489FF3B6A2764E932B108218462111D8C834EB642726F08FDBEEBC08DC25A2ABD10D72DE4053EF4B48AD385A0EB97F1EF96F01BAA45AA914BAD8096B97919F724C1075FCFBA43119006C61A5F4E991B791E1056730CF19E9215B482F6047104269C1122AA14A76B5537621C0A620CE4BD63A70B898E002D19BD2897A1D036B6283EF9CB8ADF92806CAEA8AEFCDE63F945C5F098E11824BE3493225F9848E08F4AAB4E4C3621D8AF209C02058683332CE1163D158C484ECF99095C889B900127DE4367D2A8433E5D23DAB5F5AEBDA97C425F8B169759F6A8041B -20240326013953 2 6 100 2047 2 F7B6DB1359F90C032532089BF3BAE4A2ED1209EE181E517D24238A7EDF32489C1E6F3DBA19C01489FF3B6A2764E932B108218462111D8C834EB642726F08FDBEEBC08DC25A2ABD10D72DE4053EF4B48AD385A0EB97F1EF96F01BAA45AA914BAD8096B97919F724C1075FCFBA43119006C61A5F4E991B791E1056730CF19E9215B482F6047104269C1122AA14A76B5537621C0A620CE4BD63A70B898E002D19BD2897A1D036B6283EF9CB8ADF92806CAEA8AEFCDE63F945C5F098E11824BE3493225F9848E08F4AAB4E4C3621D8AF209C02058683332CE1163D158C484ECF99095C889B900127DE4367D2A8433E5D23DAB5F5AEBDA97C425F8B169759F7815AF3 -20240326014006 2 6 100 2047 5 F7B6DB1359F90C032532089BF3BAE4A2ED1209EE181E517D24238A7EDF32489C1E6F3DBA19C01489FF3B6A2764E932B108218462111D8C834EB642726F08FDBEEBC08DC25A2ABD10D72DE4053EF4B48AD385A0EB97F1EF96F01BAA45AA914BAD8096B97919F724C1075FCFBA43119006C61A5F4E991B791E1056730CF19E9215B482F6047104269C1122AA14A76B5537621C0A620CE4BD63A70B898E002D19BD2897A1D036B6283EF9CB8ADF92806CAEA8AEFCDE63F945C5F098E11824BE3493225F9848E08F4AAB4E4C3621D8AF209C02058683332CE1163D158C484ECF99095C889B900127DE4367D2A8433E5D23DAB5F5AEBDA97C425F8B169759F7E1576F -20240326014014 2 6 100 2047 5 F7B6DB1359F90C032532089BF3BAE4A2ED1209EE181E517D24238A7EDF32489C1E6F3DBA19C01489FF3B6A2764E932B108218462111D8C834EB642726F08FDBEEBC08DC25A2ABD10D72DE4053EF4B48AD385A0EB97F1EF96F01BAA45AA914BAD8096B97919F724C1075FCFBA43119006C61A5F4E991B791E1056730CF19E9215B482F6047104269C1122AA14A76B5537621C0A620CE4BD63A70B898E002D19BD2897A1D036B6283EF9CB8ADF92806CAEA8AEFCDE63F945C5F098E11824BE3493225F9848E08F4AAB4E4C3621D8AF209C02058683332CE1163D158C484ECF99095C889B900127DE4367D2A8433E5D23DAB5F5AEBDA97C425F8B169759F818E747 -20240326014019 2 6 100 2047 5 F7B6DB1359F90C032532089BF3BAE4A2ED1209EE181E517D24238A7EDF32489C1E6F3DBA19C01489FF3B6A2764E932B108218462111D8C834EB642726F08FDBEEBC08DC25A2ABD10D72DE4053EF4B48AD385A0EB97F1EF96F01BAA45AA914BAD8096B97919F724C1075FCFBA43119006C61A5F4E991B791E1056730CF19E9215B482F6047104269C1122AA14A76B5537621C0A620CE4BD63A70B898E002D19BD2897A1D036B6283EF9CB8ADF92806CAEA8AEFCDE63F945C5F098E11824BE3493225F9848E08F4AAB4E4C3621D8AF209C02058683332CE1163D158C484ECF99095C889B900127DE4367D2A8433E5D23DAB5F5AEBDA97C425F8B169759F83E49A7 -20240326014532 2 6 100 3071 5 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A3425DB7F -20240326014544 2 6 100 3071 5 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A34464EAF -20240326014614 2 6 100 3071 2 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A349D1663 -20240326014629 2 6 100 3071 2 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A34C39EC3 -20240326014710 2 6 100 3071 5 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A3544B6B7 -20240326014727 2 6 100 3071 2 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A3574A89B -20240326014741 2 6 100 3071 5 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A359DA947 -20240326014823 2 6 100 3071 5 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A361FBA5F -20240326014832 2 6 100 3071 2 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A36377BB3 -20240326015023 2 6 100 3071 5 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A37A19A47 -20240326015025 2 6 100 3071 2 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A37A30F2B -20240326015030 2 6 100 3071 5 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A37AD1B0F -20240326015038 2 6 100 3071 5 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A37C0B3FF -20240326015116 2 6 100 3071 2 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A38348BB3 -20240326015159 2 6 100 3071 5 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A38BA81C7 -20240326015331 2 6 100 3071 2 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A39D93F9B -20240326015416 2 6 100 3071 5 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A3A61FCDF -20240326015505 2 6 100 3071 5 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A3AFA877F -20240326015516 2 6 100 3071 2 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A3B1796B3 -20240326015601 2 6 100 3071 5 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A3BA5A777 -20240326015813 2 6 100 3071 5 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A3D516827 -20240326020106 2 6 100 3071 5 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A3F7A7897 -20240326020108 2 6 100 3071 2 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A3F7B337B -20240326020156 2 6 100 3071 2 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A4012DDF3 -20240326020241 2 6 100 3071 5 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A409D1FB7 -20240326020357 2 6 100 3071 5 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A418A36C7 -20240326020359 2 6 100 3071 5 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A418AC37F -20240326020434 2 6 100 3071 2 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A41F5DCD3 -20240326020621 2 6 100 3071 5 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A434E3E3F -20240326020642 2 6 100 3071 2 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A438BE4BB -20240326020655 2 6 100 3071 5 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A43ADA137 -20240326020708 2 6 100 3071 2 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A43D0D1CB -20240326020800 2 6 100 3071 2 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A44709DB3 -20240326020836 2 6 100 3071 2 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A44DBD6DB -20240326020854 2 6 100 3071 2 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A450CF663 -20240326020934 2 6 100 3071 2 E5EBD573C64E8C90F57D2EA3086FE8A0553F6E71A29D8C629C3AA54B6648F45B3CE898928396A4E07340D3B08C83DDF2DFD73A938E8716E633EFF84055EF653423B67B0C98C1BB45E6D24662B5EC5F04E90EEB4FE7EFC4F2EE41AACB0FE5712DEF846A2454C0FAB58061046FB8EEEB7FB351ABF70069E22A9901246EF9A8640AF80DA998506C749DED56E421DCC0FFC09F2E011C237573CDE365CE2E7D41C2614602CACDA3706EF919ACD82FF79FC1DC48C2F724EF8781281F67CA0E0835455A8D2142F2A820C2A57B7E9EA2936E76044F09655E2B5EC40BCD6198DEB10DBCF87C2CBA659431D54921A880F79DCB5C9D4B7CFC688A2BFB84D40199A41461A8FD2A0EFD68F72358311886D7FA3EB29F627133C892E1E27626D476A271BC1C3970C7B52C996089A16798D2E4B7D43E6233450A89F356D9A4AB9C00E4D7683480F7618DFF43DBE5D8324B95A49F4E71874BBD0245D30B2E57DEC68E85D176122EAC0D398A0DAE7A1880BE551B47E28898FED4C40A38365830967BA1423A458A51DB -20240326021106 2 6 100 3071 5 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A3512585539C8487 -20240326021134 2 6 100 3071 5 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A351258553F5040F -20240326021206 2 6 100 3071 5 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A35125855453B76F -20240326021324 2 6 100 3071 2 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A35125855546DBDB -20240326021407 2 6 100 3071 2 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A351258555BDDCF3 -20240326021424 2 6 100 3071 5 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A351258555F11B9F -20240326021450 2 6 100 3071 2 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A35125855644DDE3 -20240326021458 2 6 100 3071 5 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A35125855656D6E7 -20240326021614 2 6 100 3071 2 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A351258557488DE3 -20240326021659 2 6 100 3071 2 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A351258557D16D53 -20240326021718 2 6 100 3071 2 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A3512585580918BB -20240326021822 2 6 100 3071 2 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A351258558D0013B -20240326021836 2 6 100 3071 2 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A351258558F7A96B -20240326021921 2 6 100 3071 5 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A35125855982467F -20240326021932 2 6 100 3071 5 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A351258559A0BC87 -20240326022009 2 6 100 3071 2 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A35125855A12A95B -20240326022029 2 6 100 3071 5 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A35125855A4C1027 -20240326022038 2 6 100 3071 2 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A35125855A608723 -20240326022102 2 6 100 3071 5 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A35125855AA76F27 -20240326022132 2 6 100 3071 2 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A35125855B050E7B -20240326022301 2 6 100 3071 2 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A35125855C2121F3 -20240326022441 2 6 100 3071 2 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A35125855D60DD03 -20240326022451 2 6 100 3071 5 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A35125855D7D2637 -20240326022516 2 6 100 3071 5 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A35125855DC6F6EF -20240326022530 2 6 100 3071 2 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A35125855DEDE3DB -20240326022711 2 6 100 3071 5 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A35125855F35973F -20240326022824 2 6 100 3071 5 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A35125856017684F -20240326022834 2 6 100 3071 2 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A35125856032C153 -20240326022854 2 6 100 3071 5 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A3512585606C9E9F -20240326022919 2 6 100 3071 2 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A351258560B97F3B -20240326023041 2 6 100 3071 2 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A351258561B88E3B -20240326023119 2 6 100 3071 2 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A3512585622F17B3 -20240326023135 2 6 100 3071 2 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A3512585625E20DB -20240326023142 2 6 100 3071 5 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A3512585626E1567 -20240326023229 2 6 100 3071 2 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A3512585630054CB -20240326023255 2 6 100 3071 2 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A3512585634C7DFB -20240326023307 2 6 100 3071 2 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A3512585636F2A3B -20240326023310 2 6 100 3071 5 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A35125856371CA8F -20240326023417 2 6 100 3071 2 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A351258564487EA3 -20240326023451 2 6 100 3071 2 FF64FA2B9B9C1232EEECB2CB61C177D9714DAEAB27DB484855D95D7851B1CCD86068CCADB2EE0DF3C4FD76B2D7B8963DC5FBB49B5A003C23F423141B9E8FFFD771F5A40D47B74B8DC9704D7F3023637905DCE2000F5F85CE9699626BA067C7693A5CBC03598D402679D874A38904AB699D08F4E6BD73830B57BE87F9A10858EC3C342033B25D1DD6AD29D3CCB4AF01BC721AC75082CCFD5B098B15F5F154F222C33F580980904EAFE0BE926F740A3165BCC89C47E74C9B713CA0332947D1F9A5D05A52117EDABF7316C54605FEA3AE7EB7587E05EBC98A2A3ABA708E85DABC10BF48B64A6381730FA722A3FBFCA80817E1F0EDE608EAA6CF1FADDD8FABDF59825DC0DEF002BE804A59E70AD94C576E049D445656644CF2AF384220DDBEC013C0F532BC9AB8283902F8E8D6CEEBFA8E1CB4CA576A2B0500E26CF967603A69084F9D877953034E38AE87ABA7D08926790B1A37A613401CE8D42CF4384118F6CAAEA1C6B28A10DD710F681F328D73EB3E43B3EABC74C5EA8133A351258564AFE53B -20240326024347 2 6 100 4095 2 D0D3C82A946A66A83A8CC225EE93B60D6260A5167B1476B41D8FE172E9EE15CE394E23C7F35D6BB24C0D3A5266A4F21DF8FF23134101FDA61F9D92F70AF32EFBABC5408226C6F931149BF40FD4B166B21B87F0E76B95A9095E0ECED05C7F81900F7216E7DDFE22FA3E4EAD74992DB6FE68F539AAAF285CE869BDD819AF650DAE192DC217EB6988E92601FAF7FEF564AB4A01C7E24E38F7B6EF0CC17CA220E6269AB1E837FBF694B3961E5AEC0C85D4800B3334CE6E8716F94557B081927267D33F1E7A3DD7FC965718956E2364E956076C23CAF13A5145F1BD62DC073C8170BFA98D8A405717190A95C98E598613AEA578B5FC4A9A08B80782D9A3EF49A6A464DA9D5A3B14F1CDAADAC4143FA77C9FB73FD5DD650CF078010A8FC6C6946A4D991E75A0AC709DF3D028DB86995A2007913522632092292537BEB34196EBF1E2ACBD4A697056CEBA4DEEA8F7AEBC11963601C12C33B0FEA90102D87ECB40277B32067CBA52DD74CBDCE68597DAF04C4635AD5918E7AE99008008DDCC49713B68CA567D1F46C3C0A0A1403E722408647E072F6A3C543F9CCE36A025427211721D377ABFE15806AD07EBD60B5BCB23C50EC37B06F47D2AA941E3DF5AFB749C0E325ED8A4157E7695696B08015BAEDA784B3503F42019AA96CCBA41CB72E0CF3491F440116B5BA679355835BAC1164676279FA026655D285CA0F094CF8181186E03B3 -20240326024508 2 6 100 4095 2 D0D3C82A946A66A83A8CC225EE93B60D6260A5167B1476B41D8FE172E9EE15CE394E23C7F35D6BB24C0D3A5266A4F21DF8FF23134101FDA61F9D92F70AF32EFBABC5408226C6F931149BF40FD4B166B21B87F0E76B95A9095E0ECED05C7F81900F7216E7DDFE22FA3E4EAD74992DB6FE68F539AAAF285CE869BDD819AF650DAE192DC217EB6988E92601FAF7FEF564AB4A01C7E24E38F7B6EF0CC17CA220E6269AB1E837FBF694B3961E5AEC0C85D4800B3334CE6E8716F94557B081927267D33F1E7A3DD7FC965718956E2364E956076C23CAF13A5145F1BD62DC073C8170BFA98D8A405717190A95C98E598613AEA578B5FC4A9A08B80782D9A3EF49A6A464DA9D5A3B14F1CDAADAC4143FA77C9FB73FD5DD650CF078010A8FC6C6946A4D991E75A0AC709DF3D028DB86995A2007913522632092292537BEB34196EBF1E2ACBD4A697056CEBA4DEEA8F7AEBC11963601C12C33B0FEA90102D87ECB40277B32067CBA52DD74CBDCE68597DAF04C4635AD5918E7AE99008008DDCC49713B68CA567D1F46C3C0A0A1403E722408647E072F6A3C543F9CCE36A025427211721D377ABFE15806AD07EBD60B5BCB23C50EC37B06F47D2AA941E3DF5AFB749C0E325ED8A4157E7695696B08015BAEDA784B3503F42019AA96CCBA41CB72E0CF3491F440116B5BA679355835BAC1164676279FA026655D285CA0F094CF818118EEB0A3 -20240326024849 2 6 100 4095 2 D0D3C82A946A66A83A8CC225EE93B60D6260A5167B1476B41D8FE172E9EE15CE394E23C7F35D6BB24C0D3A5266A4F21DF8FF23134101FDA61F9D92F70AF32EFBABC5408226C6F931149BF40FD4B166B21B87F0E76B95A9095E0ECED05C7F81900F7216E7DDFE22FA3E4EAD74992DB6FE68F539AAAF285CE869BDD819AF650DAE192DC217EB6988E92601FAF7FEF564AB4A01C7E24E38F7B6EF0CC17CA220E6269AB1E837FBF694B3961E5AEC0C85D4800B3334CE6E8716F94557B081927267D33F1E7A3DD7FC965718956E2364E956076C23CAF13A5145F1BD62DC073C8170BFA98D8A405717190A95C98E598613AEA578B5FC4A9A08B80782D9A3EF49A6A464DA9D5A3B14F1CDAADAC4143FA77C9FB73FD5DD650CF078010A8FC6C6946A4D991E75A0AC709DF3D028DB86995A2007913522632092292537BEB34196EBF1E2ACBD4A697056CEBA4DEEA8F7AEBC11963601C12C33B0FEA90102D87ECB40277B32067CBA52DD74CBDCE68597DAF04C4635AD5918E7AE99008008DDCC49713B68CA567D1F46C3C0A0A1403E722408647E072F6A3C543F9CCE36A025427211721D377ABFE15806AD07EBD60B5BCB23C50EC37B06F47D2AA941E3DF5AFB749C0E325ED8A4157E7695696B08015BAEDA784B3503F42019AA96CCBA41CB72E0CF3491F440116B5BA679355835BAC1164676279FA026655D285CA0F094CF81811A4ECE4B -20240326025526 2 6 100 4095 2 D0D3C82A946A66A83A8CC225EE93B60D6260A5167B1476B41D8FE172E9EE15CE394E23C7F35D6BB24C0D3A5266A4F21DF8FF23134101FDA61F9D92F70AF32EFBABC5408226C6F931149BF40FD4B166B21B87F0E76B95A9095E0ECED05C7F81900F7216E7DDFE22FA3E4EAD74992DB6FE68F539AAAF285CE869BDD819AF650DAE192DC217EB6988E92601FAF7FEF564AB4A01C7E24E38F7B6EF0CC17CA220E6269AB1E837FBF694B3961E5AEC0C85D4800B3334CE6E8716F94557B081927267D33F1E7A3DD7FC965718956E2364E956076C23CAF13A5145F1BD62DC073C8170BFA98D8A405717190A95C98E598613AEA578B5FC4A9A08B80782D9A3EF49A6A464DA9D5A3B14F1CDAADAC4143FA77C9FB73FD5DD650CF078010A8FC6C6946A4D991E75A0AC709DF3D028DB86995A2007913522632092292537BEB34196EBF1E2ACBD4A697056CEBA4DEEA8F7AEBC11963601C12C33B0FEA90102D87ECB40277B32067CBA52DD74CBDCE68597DAF04C4635AD5918E7AE99008008DDCC49713B68CA567D1F46C3C0A0A1403E722408647E072F6A3C543F9CCE36A025427211721D377ABFE15806AD07EBD60B5BCB23C50EC37B06F47D2AA941E3DF5AFB749C0E325ED8A4157E7695696B08015BAEDA784B3503F42019AA96CCBA41CB72E0CF3491F440116B5BA679355835BAC1164676279FA026655D285CA0F094CF81811CD141E3 -20240326025628 2 6 100 4095 2 D0D3C82A946A66A83A8CC225EE93B60D6260A5167B1476B41D8FE172E9EE15CE394E23C7F35D6BB24C0D3A5266A4F21DF8FF23134101FDA61F9D92F70AF32EFBABC5408226C6F931149BF40FD4B166B21B87F0E76B95A9095E0ECED05C7F81900F7216E7DDFE22FA3E4EAD74992DB6FE68F539AAAF285CE869BDD819AF650DAE192DC217EB6988E92601FAF7FEF564AB4A01C7E24E38F7B6EF0CC17CA220E6269AB1E837FBF694B3961E5AEC0C85D4800B3334CE6E8716F94557B081927267D33F1E7A3DD7FC965718956E2364E956076C23CAF13A5145F1BD62DC073C8170BFA98D8A405717190A95C98E598613AEA578B5FC4A9A08B80782D9A3EF49A6A464DA9D5A3B14F1CDAADAC4143FA77C9FB73FD5DD650CF078010A8FC6C6946A4D991E75A0AC709DF3D028DB86995A2007913522632092292537BEB34196EBF1E2ACBD4A697056CEBA4DEEA8F7AEBC11963601C12C33B0FEA90102D87ECB40277B32067CBA52DD74CBDCE68597DAF04C4635AD5918E7AE99008008DDCC49713B68CA567D1F46C3C0A0A1403E722408647E072F6A3C543F9CCE36A025427211721D377ABFE15806AD07EBD60B5BCB23C50EC37B06F47D2AA941E3DF5AFB749C0E325ED8A4157E7695696B08015BAEDA784B3503F42019AA96CCBA41CB72E0CF3491F440116B5BA679355835BAC1164676279FA026655D285CA0F094CF81811D32676B -20240326030110 2 6 100 4095 2 D0D3C82A946A66A83A8CC225EE93B60D6260A5167B1476B41D8FE172E9EE15CE394E23C7F35D6BB24C0D3A5266A4F21DF8FF23134101FDA61F9D92F70AF32EFBABC5408226C6F931149BF40FD4B166B21B87F0E76B95A9095E0ECED05C7F81900F7216E7DDFE22FA3E4EAD74992DB6FE68F539AAAF285CE869BDD819AF650DAE192DC217EB6988E92601FAF7FEF564AB4A01C7E24E38F7B6EF0CC17CA220E6269AB1E837FBF694B3961E5AEC0C85D4800B3334CE6E8716F94557B081927267D33F1E7A3DD7FC965718956E2364E956076C23CAF13A5145F1BD62DC073C8170BFA98D8A405717190A95C98E598613AEA578B5FC4A9A08B80782D9A3EF49A6A464DA9D5A3B14F1CDAADAC4143FA77C9FB73FD5DD650CF078010A8FC6C6946A4D991E75A0AC709DF3D028DB86995A2007913522632092292537BEB34196EBF1E2ACBD4A697056CEBA4DEEA8F7AEBC11963601C12C33B0FEA90102D87ECB40277B32067CBA52DD74CBDCE68597DAF04C4635AD5918E7AE99008008DDCC49713B68CA567D1F46C3C0A0A1403E722408647E072F6A3C543F9CCE36A025427211721D377ABFE15806AD07EBD60B5BCB23C50EC37B06F47D2AA941E3DF5AFB749C0E325ED8A4157E7695696B08015BAEDA784B3503F42019AA96CCBA41CB72E0CF3491F440116B5BA679355835BAC1164676279FA026655D285CA0F094CF81811EF7F1E3 -20240326030518 2 6 100 4095 5 D0D3C82A946A66A83A8CC225EE93B60D6260A5167B1476B41D8FE172E9EE15CE394E23C7F35D6BB24C0D3A5266A4F21DF8FF23134101FDA61F9D92F70AF32EFBABC5408226C6F931149BF40FD4B166B21B87F0E76B95A9095E0ECED05C7F81900F7216E7DDFE22FA3E4EAD74992DB6FE68F539AAAF285CE869BDD819AF650DAE192DC217EB6988E92601FAF7FEF564AB4A01C7E24E38F7B6EF0CC17CA220E6269AB1E837FBF694B3961E5AEC0C85D4800B3334CE6E8716F94557B081927267D33F1E7A3DD7FC965718956E2364E956076C23CAF13A5145F1BD62DC073C8170BFA98D8A405717190A95C98E598613AEA578B5FC4A9A08B80782D9A3EF49A6A464DA9D5A3B14F1CDAADAC4143FA77C9FB73FD5DD650CF078010A8FC6C6946A4D991E75A0AC709DF3D028DB86995A2007913522632092292537BEB34196EBF1E2ACBD4A697056CEBA4DEEA8F7AEBC11963601C12C33B0FEA90102D87ECB40277B32067CBA52DD74CBDCE68597DAF04C4635AD5918E7AE99008008DDCC49713B68CA567D1F46C3C0A0A1403E722408647E072F6A3C543F9CCE36A025427211721D377ABFE15806AD07EBD60B5BCB23C50EC37B06F47D2AA941E3DF5AFB749C0E325ED8A4157E7695696B08015BAEDA784B3503F42019AA96CCBA41CB72E0CF3491F440116B5BA679355835BAC1164676279FA026655D285CA0F094CF818120788D47 -20240326031719 2 6 100 4095 2 D0D3C82A946A66A83A8CC225EE93B60D6260A5167B1476B41D8FE172E9EE15CE394E23C7F35D6BB24C0D3A5266A4F21DF8FF23134101FDA61F9D92F70AF32EFBABC5408226C6F931149BF40FD4B166B21B87F0E76B95A9095E0ECED05C7F81900F7216E7DDFE22FA3E4EAD74992DB6FE68F539AAAF285CE869BDD819AF650DAE192DC217EB6988E92601FAF7FEF564AB4A01C7E24E38F7B6EF0CC17CA220E6269AB1E837FBF694B3961E5AEC0C85D4800B3334CE6E8716F94557B081927267D33F1E7A3DD7FC965718956E2364E956076C23CAF13A5145F1BD62DC073C8170BFA98D8A405717190A95C98E598613AEA578B5FC4A9A08B80782D9A3EF49A6A464DA9D5A3B14F1CDAADAC4143FA77C9FB73FD5DD650CF078010A8FC6C6946A4D991E75A0AC709DF3D028DB86995A2007913522632092292537BEB34196EBF1E2ACBD4A697056CEBA4DEEA8F7AEBC11963601C12C33B0FEA90102D87ECB40277B32067CBA52DD74CBDCE68597DAF04C4635AD5918E7AE99008008DDCC49713B68CA567D1F46C3C0A0A1403E722408647E072F6A3C543F9CCE36A025427211721D377ABFE15806AD07EBD60B5BCB23C50EC37B06F47D2AA941E3DF5AFB749C0E325ED8A4157E7695696B08015BAEDA784B3503F42019AA96CCBA41CB72E0CF3491F440116B5BA679355835BAC1164676279FA026655D285CA0F094CF818125002673 -20240326031926 2 6 100 4095 2 D0D3C82A946A66A83A8CC225EE93B60D6260A5167B1476B41D8FE172E9EE15CE394E23C7F35D6BB24C0D3A5266A4F21DF8FF23134101FDA61F9D92F70AF32EFBABC5408226C6F931149BF40FD4B166B21B87F0E76B95A9095E0ECED05C7F81900F7216E7DDFE22FA3E4EAD74992DB6FE68F539AAAF285CE869BDD819AF650DAE192DC217EB6988E92601FAF7FEF564AB4A01C7E24E38F7B6EF0CC17CA220E6269AB1E837FBF694B3961E5AEC0C85D4800B3334CE6E8716F94557B081927267D33F1E7A3DD7FC965718956E2364E956076C23CAF13A5145F1BD62DC073C8170BFA98D8A405717190A95C98E598613AEA578B5FC4A9A08B80782D9A3EF49A6A464DA9D5A3B14F1CDAADAC4143FA77C9FB73FD5DD650CF078010A8FC6C6946A4D991E75A0AC709DF3D028DB86995A2007913522632092292537BEB34196EBF1E2ACBD4A697056CEBA4DEEA8F7AEBC11963601C12C33B0FEA90102D87ECB40277B32067CBA52DD74CBDCE68597DAF04C4635AD5918E7AE99008008DDCC49713B68CA567D1F46C3C0A0A1403E722408647E072F6A3C543F9CCE36A025427211721D377ABFE15806AD07EBD60B5BCB23C50EC37B06F47D2AA941E3DF5AFB749C0E325ED8A4157E7695696B08015BAEDA784B3503F42019AA96CCBA41CB72E0CF3491F440116B5BA679355835BAC1164676279FA026655D285CA0F094CF818125C6B433 -20240326031951 2 6 100 4095 2 D0D3C82A946A66A83A8CC225EE93B60D6260A5167B1476B41D8FE172E9EE15CE394E23C7F35D6BB24C0D3A5266A4F21DF8FF23134101FDA61F9D92F70AF32EFBABC5408226C6F931149BF40FD4B166B21B87F0E76B95A9095E0ECED05C7F81900F7216E7DDFE22FA3E4EAD74992DB6FE68F539AAAF285CE869BDD819AF650DAE192DC217EB6988E92601FAF7FEF564AB4A01C7E24E38F7B6EF0CC17CA220E6269AB1E837FBF694B3961E5AEC0C85D4800B3334CE6E8716F94557B081927267D33F1E7A3DD7FC965718956E2364E956076C23CAF13A5145F1BD62DC073C8170BFA98D8A405717190A95C98E598613AEA578B5FC4A9A08B80782D9A3EF49A6A464DA9D5A3B14F1CDAADAC4143FA77C9FB73FD5DD650CF078010A8FC6C6946A4D991E75A0AC709DF3D028DB86995A2007913522632092292537BEB34196EBF1E2ACBD4A697056CEBA4DEEA8F7AEBC11963601C12C33B0FEA90102D87ECB40277B32067CBA52DD74CBDCE68597DAF04C4635AD5918E7AE99008008DDCC49713B68CA567D1F46C3C0A0A1403E722408647E072F6A3C543F9CCE36A025427211721D377ABFE15806AD07EBD60B5BCB23C50EC37B06F47D2AA941E3DF5AFB749C0E325ED8A4157E7695696B08015BAEDA784B3503F42019AA96CCBA41CB72E0CF3491F440116B5BA679355835BAC1164676279FA026655D285CA0F094CF818125E6335B -20240326032742 2 6 100 4095 5 D0D3C82A946A66A83A8CC225EE93B60D6260A5167B1476B41D8FE172E9EE15CE394E23C7F35D6BB24C0D3A5266A4F21DF8FF23134101FDA61F9D92F70AF32EFBABC5408226C6F931149BF40FD4B166B21B87F0E76B95A9095E0ECED05C7F81900F7216E7DDFE22FA3E4EAD74992DB6FE68F539AAAF285CE869BDD819AF650DAE192DC217EB6988E92601FAF7FEF564AB4A01C7E24E38F7B6EF0CC17CA220E6269AB1E837FBF694B3961E5AEC0C85D4800B3334CE6E8716F94557B081927267D33F1E7A3DD7FC965718956E2364E956076C23CAF13A5145F1BD62DC073C8170BFA98D8A405717190A95C98E598613AEA578B5FC4A9A08B80782D9A3EF49A6A464DA9D5A3B14F1CDAADAC4143FA77C9FB73FD5DD650CF078010A8FC6C6946A4D991E75A0AC709DF3D028DB86995A2007913522632092292537BEB34196EBF1E2ACBD4A697056CEBA4DEEA8F7AEBC11963601C12C33B0FEA90102D87ECB40277B32067CBA52DD74CBDCE68597DAF04C4635AD5918E7AE99008008DDCC49713B68CA567D1F46C3C0A0A1403E722408647E072F6A3C543F9CCE36A025427211721D377ABFE15806AD07EBD60B5BCB23C50EC37B06F47D2AA941E3DF5AFB749C0E325ED8A4157E7695696B08015BAEDA784B3503F42019AA96CCBA41CB72E0CF3491F440116B5BA679355835BAC1164676279FA026655D285CA0F094CF818128EAC3E7 -20240326032936 2 6 100 4095 2 D0D3C82A946A66A83A8CC225EE93B60D6260A5167B1476B41D8FE172E9EE15CE394E23C7F35D6BB24C0D3A5266A4F21DF8FF23134101FDA61F9D92F70AF32EFBABC5408226C6F931149BF40FD4B166B21B87F0E76B95A9095E0ECED05C7F81900F7216E7DDFE22FA3E4EAD74992DB6FE68F539AAAF285CE869BDD819AF650DAE192DC217EB6988E92601FAF7FEF564AB4A01C7E24E38F7B6EF0CC17CA220E6269AB1E837FBF694B3961E5AEC0C85D4800B3334CE6E8716F94557B081927267D33F1E7A3DD7FC965718956E2364E956076C23CAF13A5145F1BD62DC073C8170BFA98D8A405717190A95C98E598613AEA578B5FC4A9A08B80782D9A3EF49A6A464DA9D5A3B14F1CDAADAC4143FA77C9FB73FD5DD650CF078010A8FC6C6946A4D991E75A0AC709DF3D028DB86995A2007913522632092292537BEB34196EBF1E2ACBD4A697056CEBA4DEEA8F7AEBC11963601C12C33B0FEA90102D87ECB40277B32067CBA52DD74CBDCE68597DAF04C4635AD5918E7AE99008008DDCC49713B68CA567D1F46C3C0A0A1403E722408647E072F6A3C543F9CCE36A025427211721D377ABFE15806AD07EBD60B5BCB23C50EC37B06F47D2AA941E3DF5AFB749C0E325ED8A4157E7695696B08015BAEDA784B3503F42019AA96CCBA41CB72E0CF3491F440116B5BA679355835BAC1164676279FA026655D285CA0F094CF818129980033 -20240326032952 2 6 100 4095 2 D0D3C82A946A66A83A8CC225EE93B60D6260A5167B1476B41D8FE172E9EE15CE394E23C7F35D6BB24C0D3A5266A4F21DF8FF23134101FDA61F9D92F70AF32EFBABC5408226C6F931149BF40FD4B166B21B87F0E76B95A9095E0ECED05C7F81900F7216E7DDFE22FA3E4EAD74992DB6FE68F539AAAF285CE869BDD819AF650DAE192DC217EB6988E92601FAF7FEF564AB4A01C7E24E38F7B6EF0CC17CA220E6269AB1E837FBF694B3961E5AEC0C85D4800B3334CE6E8716F94557B081927267D33F1E7A3DD7FC965718956E2364E956076C23CAF13A5145F1BD62DC073C8170BFA98D8A405717190A95C98E598613AEA578B5FC4A9A08B80782D9A3EF49A6A464DA9D5A3B14F1CDAADAC4143FA77C9FB73FD5DD650CF078010A8FC6C6946A4D991E75A0AC709DF3D028DB86995A2007913522632092292537BEB34196EBF1E2ACBD4A697056CEBA4DEEA8F7AEBC11963601C12C33B0FEA90102D87ECB40277B32067CBA52DD74CBDCE68597DAF04C4635AD5918E7AE99008008DDCC49713B68CA567D1F46C3C0A0A1403E722408647E072F6A3C543F9CCE36A025427211721D377ABFE15806AD07EBD60B5BCB23C50EC37B06F47D2AA941E3DF5AFB749C0E325ED8A4157E7695696B08015BAEDA784B3503F42019AA96CCBA41CB72E0CF3491F440116B5BA679355835BAC1164676279FA026655D285CA0F094CF818129AAC3DB -20240326033059 2 6 100 4095 2 D0D3C82A946A66A83A8CC225EE93B60D6260A5167B1476B41D8FE172E9EE15CE394E23C7F35D6BB24C0D3A5266A4F21DF8FF23134101FDA61F9D92F70AF32EFBABC5408226C6F931149BF40FD4B166B21B87F0E76B95A9095E0ECED05C7F81900F7216E7DDFE22FA3E4EAD74992DB6FE68F539AAAF285CE869BDD819AF650DAE192DC217EB6988E92601FAF7FEF564AB4A01C7E24E38F7B6EF0CC17CA220E6269AB1E837FBF694B3961E5AEC0C85D4800B3334CE6E8716F94557B081927267D33F1E7A3DD7FC965718956E2364E956076C23CAF13A5145F1BD62DC073C8170BFA98D8A405717190A95C98E598613AEA578B5FC4A9A08B80782D9A3EF49A6A464DA9D5A3B14F1CDAADAC4143FA77C9FB73FD5DD650CF078010A8FC6C6946A4D991E75A0AC709DF3D028DB86995A2007913522632092292537BEB34196EBF1E2ACBD4A697056CEBA4DEEA8F7AEBC11963601C12C33B0FEA90102D87ECB40277B32067CBA52DD74CBDCE68597DAF04C4635AD5918E7AE99008008DDCC49713B68CA567D1F46C3C0A0A1403E722408647E072F6A3C543F9CCE36A025427211721D377ABFE15806AD07EBD60B5BCB23C50EC37B06F47D2AA941E3DF5AFB749C0E325ED8A4157E7695696B08015BAEDA784B3503F42019AA96CCBA41CB72E0CF3491F440116B5BA679355835BAC1164676279FA026655D285CA0F094CF81812A0B8603 -20240326033458 2 6 100 4095 5 D0D3C82A946A66A83A8CC225EE93B60D6260A5167B1476B41D8FE172E9EE15CE394E23C7F35D6BB24C0D3A5266A4F21DF8FF23134101FDA61F9D92F70AF32EFBABC5408226C6F931149BF40FD4B166B21B87F0E76B95A9095E0ECED05C7F81900F7216E7DDFE22FA3E4EAD74992DB6FE68F539AAAF285CE869BDD819AF650DAE192DC217EB6988E92601FAF7FEF564AB4A01C7E24E38F7B6EF0CC17CA220E6269AB1E837FBF694B3961E5AEC0C85D4800B3334CE6E8716F94557B081927267D33F1E7A3DD7FC965718956E2364E956076C23CAF13A5145F1BD62DC073C8170BFA98D8A405717190A95C98E598613AEA578B5FC4A9A08B80782D9A3EF49A6A464DA9D5A3B14F1CDAADAC4143FA77C9FB73FD5DD650CF078010A8FC6C6946A4D991E75A0AC709DF3D028DB86995A2007913522632092292537BEB34196EBF1E2ACBD4A697056CEBA4DEEA8F7AEBC11963601C12C33B0FEA90102D87ECB40277B32067CBA52DD74CBDCE68597DAF04C4635AD5918E7AE99008008DDCC49713B68CA567D1F46C3C0A0A1403E722408647E072F6A3C543F9CCE36A025427211721D377ABFE15806AD07EBD60B5BCB23C50EC37B06F47D2AA941E3DF5AFB749C0E325ED8A4157E7695696B08015BAEDA784B3503F42019AA96CCBA41CB72E0CF3491F440116B5BA679355835BAC1164676279FA026655D285CA0F094CF81812B8E0D07 -20240326033533 2 6 100 4095 5 D0D3C82A946A66A83A8CC225EE93B60D6260A5167B1476B41D8FE172E9EE15CE394E23C7F35D6BB24C0D3A5266A4F21DF8FF23134101FDA61F9D92F70AF32EFBABC5408226C6F931149BF40FD4B166B21B87F0E76B95A9095E0ECED05C7F81900F7216E7DDFE22FA3E4EAD74992DB6FE68F539AAAF285CE869BDD819AF650DAE192DC217EB6988E92601FAF7FEF564AB4A01C7E24E38F7B6EF0CC17CA220E6269AB1E837FBF694B3961E5AEC0C85D4800B3334CE6E8716F94557B081927267D33F1E7A3DD7FC965718956E2364E956076C23CAF13A5145F1BD62DC073C8170BFA98D8A405717190A95C98E598613AEA578B5FC4A9A08B80782D9A3EF49A6A464DA9D5A3B14F1CDAADAC4143FA77C9FB73FD5DD650CF078010A8FC6C6946A4D991E75A0AC709DF3D028DB86995A2007913522632092292537BEB34196EBF1E2ACBD4A697056CEBA4DEEA8F7AEBC11963601C12C33B0FEA90102D87ECB40277B32067CBA52DD74CBDCE68597DAF04C4635AD5918E7AE99008008DDCC49713B68CA567D1F46C3C0A0A1403E722408647E072F6A3C543F9CCE36A025427211721D377ABFE15806AD07EBD60B5BCB23C50EC37B06F47D2AA941E3DF5AFB749C0E325ED8A4157E7695696B08015BAEDA784B3503F42019AA96CCBA41CB72E0CF3491F440116B5BA679355835BAC1164676279FA026655D285CA0F094CF81812BBB8B97 -20240326033606 2 6 100 4095 5 D0D3C82A946A66A83A8CC225EE93B60D6260A5167B1476B41D8FE172E9EE15CE394E23C7F35D6BB24C0D3A5266A4F21DF8FF23134101FDA61F9D92F70AF32EFBABC5408226C6F931149BF40FD4B166B21B87F0E76B95A9095E0ECED05C7F81900F7216E7DDFE22FA3E4EAD74992DB6FE68F539AAAF285CE869BDD819AF650DAE192DC217EB6988E92601FAF7FEF564AB4A01C7E24E38F7B6EF0CC17CA220E6269AB1E837FBF694B3961E5AEC0C85D4800B3334CE6E8716F94557B081927267D33F1E7A3DD7FC965718956E2364E956076C23CAF13A5145F1BD62DC073C8170BFA98D8A405717190A95C98E598613AEA578B5FC4A9A08B80782D9A3EF49A6A464DA9D5A3B14F1CDAADAC4143FA77C9FB73FD5DD650CF078010A8FC6C6946A4D991E75A0AC709DF3D028DB86995A2007913522632092292537BEB34196EBF1E2ACBD4A697056CEBA4DEEA8F7AEBC11963601C12C33B0FEA90102D87ECB40277B32067CBA52DD74CBDCE68597DAF04C4635AD5918E7AE99008008DDCC49713B68CA567D1F46C3C0A0A1403E722408647E072F6A3C543F9CCE36A025427211721D377ABFE15806AD07EBD60B5BCB23C50EC37B06F47D2AA941E3DF5AFB749C0E325ED8A4157E7695696B08015BAEDA784B3503F42019AA96CCBA41CB72E0CF3491F440116B5BA679355835BAC1164676279FA026655D285CA0F094CF81812BE87FF7 -20240326033629 2 6 100 4095 5 D0D3C82A946A66A83A8CC225EE93B60D6260A5167B1476B41D8FE172E9EE15CE394E23C7F35D6BB24C0D3A5266A4F21DF8FF23134101FDA61F9D92F70AF32EFBABC5408226C6F931149BF40FD4B166B21B87F0E76B95A9095E0ECED05C7F81900F7216E7DDFE22FA3E4EAD74992DB6FE68F539AAAF285CE869BDD819AF650DAE192DC217EB6988E92601FAF7FEF564AB4A01C7E24E38F7B6EF0CC17CA220E6269AB1E837FBF694B3961E5AEC0C85D4800B3334CE6E8716F94557B081927267D33F1E7A3DD7FC965718956E2364E956076C23CAF13A5145F1BD62DC073C8170BFA98D8A405717190A95C98E598613AEA578B5FC4A9A08B80782D9A3EF49A6A464DA9D5A3B14F1CDAADAC4143FA77C9FB73FD5DD650CF078010A8FC6C6946A4D991E75A0AC709DF3D028DB86995A2007913522632092292537BEB34196EBF1E2ACBD4A697056CEBA4DEEA8F7AEBC11963601C12C33B0FEA90102D87ECB40277B32067CBA52DD74CBDCE68597DAF04C4635AD5918E7AE99008008DDCC49713B68CA567D1F46C3C0A0A1403E722408647E072F6A3C543F9CCE36A025427211721D377ABFE15806AD07EBD60B5BCB23C50EC37B06F47D2AA941E3DF5AFB749C0E325ED8A4157E7695696B08015BAEDA784B3503F42019AA96CCBA41CB72E0CF3491F440116B5BA679355835BAC1164676279FA026655D285CA0F094CF81812C03788F -20240326033712 2 6 100 4095 5 D0D3C82A946A66A83A8CC225EE93B60D6260A5167B1476B41D8FE172E9EE15CE394E23C7F35D6BB24C0D3A5266A4F21DF8FF23134101FDA61F9D92F70AF32EFBABC5408226C6F931149BF40FD4B166B21B87F0E76B95A9095E0ECED05C7F81900F7216E7DDFE22FA3E4EAD74992DB6FE68F539AAAF285CE869BDD819AF650DAE192DC217EB6988E92601FAF7FEF564AB4A01C7E24E38F7B6EF0CC17CA220E6269AB1E837FBF694B3961E5AEC0C85D4800B3334CE6E8716F94557B081927267D33F1E7A3DD7FC965718956E2364E956076C23CAF13A5145F1BD62DC073C8170BFA98D8A405717190A95C98E598613AEA578B5FC4A9A08B80782D9A3EF49A6A464DA9D5A3B14F1CDAADAC4143FA77C9FB73FD5DD650CF078010A8FC6C6946A4D991E75A0AC709DF3D028DB86995A2007913522632092292537BEB34196EBF1E2ACBD4A697056CEBA4DEEA8F7AEBC11963601C12C33B0FEA90102D87ECB40277B32067CBA52DD74CBDCE68597DAF04C4635AD5918E7AE99008008DDCC49713B68CA567D1F46C3C0A0A1403E722408647E072F6A3C543F9CCE36A025427211721D377ABFE15806AD07EBD60B5BCB23C50EC37B06F47D2AA941E3DF5AFB749C0E325ED8A4157E7695696B08015BAEDA784B3503F42019AA96CCBA41CB72E0CF3491F440116B5BA679355835BAC1164676279FA026655D285CA0F094CF81812C3FAF07 -20240326034008 2 6 100 4095 2 D0D3C82A946A66A83A8CC225EE93B60D6260A5167B1476B41D8FE172E9EE15CE394E23C7F35D6BB24C0D3A5266A4F21DF8FF23134101FDA61F9D92F70AF32EFBABC5408226C6F931149BF40FD4B166B21B87F0E76B95A9095E0ECED05C7F81900F7216E7DDFE22FA3E4EAD74992DB6FE68F539AAAF285CE869BDD819AF650DAE192DC217EB6988E92601FAF7FEF564AB4A01C7E24E38F7B6EF0CC17CA220E6269AB1E837FBF694B3961E5AEC0C85D4800B3334CE6E8716F94557B081927267D33F1E7A3DD7FC965718956E2364E956076C23CAF13A5145F1BD62DC073C8170BFA98D8A405717190A95C98E598613AEA578B5FC4A9A08B80782D9A3EF49A6A464DA9D5A3B14F1CDAADAC4143FA77C9FB73FD5DD650CF078010A8FC6C6946A4D991E75A0AC709DF3D028DB86995A2007913522632092292537BEB34196EBF1E2ACBD4A697056CEBA4DEEA8F7AEBC11963601C12C33B0FEA90102D87ECB40277B32067CBA52DD74CBDCE68597DAF04C4635AD5918E7AE99008008DDCC49713B68CA567D1F46C3C0A0A1403E722408647E072F6A3C543F9CCE36A025427211721D377ABFE15806AD07EBD60B5BCB23C50EC37B06F47D2AA941E3DF5AFB749C0E325ED8A4157E7695696B08015BAEDA784B3503F42019AA96CCBA41CB72E0CF3491F440116B5BA679355835BAC1164676279FA026655D285CA0F094CF81812D534F8B -20240326034204 2 6 100 4095 2 D0D3C82A946A66A83A8CC225EE93B60D6260A5167B1476B41D8FE172E9EE15CE394E23C7F35D6BB24C0D3A5266A4F21DF8FF23134101FDA61F9D92F70AF32EFBABC5408226C6F931149BF40FD4B166B21B87F0E76B95A9095E0ECED05C7F81900F7216E7DDFE22FA3E4EAD74992DB6FE68F539AAAF285CE869BDD819AF650DAE192DC217EB6988E92601FAF7FEF564AB4A01C7E24E38F7B6EF0CC17CA220E6269AB1E837FBF694B3961E5AEC0C85D4800B3334CE6E8716F94557B081927267D33F1E7A3DD7FC965718956E2364E956076C23CAF13A5145F1BD62DC073C8170BFA98D8A405717190A95C98E598613AEA578B5FC4A9A08B80782D9A3EF49A6A464DA9D5A3B14F1CDAADAC4143FA77C9FB73FD5DD650CF078010A8FC6C6946A4D991E75A0AC709DF3D028DB86995A2007913522632092292537BEB34196EBF1E2ACBD4A697056CEBA4DEEA8F7AEBC11963601C12C33B0FEA90102D87ECB40277B32067CBA52DD74CBDCE68597DAF04C4635AD5918E7AE99008008DDCC49713B68CA567D1F46C3C0A0A1403E722408647E072F6A3C543F9CCE36A025427211721D377ABFE15806AD07EBD60B5BCB23C50EC37B06F47D2AA941E3DF5AFB749C0E325ED8A4157E7695696B08015BAEDA784B3503F42019AA96CCBA41CB72E0CF3491F440116B5BA679355835BAC1164676279FA026655D285CA0F094CF81812E080CA3 -20240326034508 2 6 100 4095 2 D0D3C82A946A66A83A8CC225EE93B60D6260A5167B1476B41D8FE172E9EE15CE394E23C7F35D6BB24C0D3A5266A4F21DF8FF23134101FDA61F9D92F70AF32EFBABC5408226C6F931149BF40FD4B166B21B87F0E76B95A9095E0ECED05C7F81900F7216E7DDFE22FA3E4EAD74992DB6FE68F539AAAF285CE869BDD819AF650DAE192DC217EB6988E92601FAF7FEF564AB4A01C7E24E38F7B6EF0CC17CA220E6269AB1E837FBF694B3961E5AEC0C85D4800B3334CE6E8716F94557B081927267D33F1E7A3DD7FC965718956E2364E956076C23CAF13A5145F1BD62DC073C8170BFA98D8A405717190A95C98E598613AEA578B5FC4A9A08B80782D9A3EF49A6A464DA9D5A3B14F1CDAADAC4143FA77C9FB73FD5DD650CF078010A8FC6C6946A4D991E75A0AC709DF3D028DB86995A2007913522632092292537BEB34196EBF1E2ACBD4A697056CEBA4DEEA8F7AEBC11963601C12C33B0FEA90102D87ECB40277B32067CBA52DD74CBDCE68597DAF04C4635AD5918E7AE99008008DDCC49713B68CA567D1F46C3C0A0A1403E722408647E072F6A3C543F9CCE36A025427211721D377ABFE15806AD07EBD60B5BCB23C50EC37B06F47D2AA941E3DF5AFB749C0E325ED8A4157E7695696B08015BAEDA784B3503F42019AA96CCBA41CB72E0CF3491F440116B5BA679355835BAC1164676279FA026655D285CA0F094CF81812F2F5493 -20240326034751 2 6 100 4095 5 D0D3C82A946A66A83A8CC225EE93B60D6260A5167B1476B41D8FE172E9EE15CE394E23C7F35D6BB24C0D3A5266A4F21DF8FF23134101FDA61F9D92F70AF32EFBABC5408226C6F931149BF40FD4B166B21B87F0E76B95A9095E0ECED05C7F81900F7216E7DDFE22FA3E4EAD74992DB6FE68F539AAAF285CE869BDD819AF650DAE192DC217EB6988E92601FAF7FEF564AB4A01C7E24E38F7B6EF0CC17CA220E6269AB1E837FBF694B3961E5AEC0C85D4800B3334CE6E8716F94557B081927267D33F1E7A3DD7FC965718956E2364E956076C23CAF13A5145F1BD62DC073C8170BFA98D8A405717190A95C98E598613AEA578B5FC4A9A08B80782D9A3EF49A6A464DA9D5A3B14F1CDAADAC4143FA77C9FB73FD5DD650CF078010A8FC6C6946A4D991E75A0AC709DF3D028DB86995A2007913522632092292537BEB34196EBF1E2ACBD4A697056CEBA4DEEA8F7AEBC11963601C12C33B0FEA90102D87ECB40277B32067CBA52DD74CBDCE68597DAF04C4635AD5918E7AE99008008DDCC49713B68CA567D1F46C3C0A0A1403E722408647E072F6A3C543F9CCE36A025427211721D377ABFE15806AD07EBD60B5BCB23C50EC37B06F47D2AA941E3DF5AFB749C0E325ED8A4157E7695696B08015BAEDA784B3503F42019AA96CCBA41CB72E0CF3491F440116B5BA679355835BAC1164676279FA026655D285CA0F094CF8181302AABC7 -20240326034806 2 6 100 4095 2 D0D3C82A946A66A83A8CC225EE93B60D6260A5167B1476B41D8FE172E9EE15CE394E23C7F35D6BB24C0D3A5266A4F21DF8FF23134101FDA61F9D92F70AF32EFBABC5408226C6F931149BF40FD4B166B21B87F0E76B95A9095E0ECED05C7F81900F7216E7DDFE22FA3E4EAD74992DB6FE68F539AAAF285CE869BDD819AF650DAE192DC217EB6988E92601FAF7FEF564AB4A01C7E24E38F7B6EF0CC17CA220E6269AB1E837FBF694B3961E5AEC0C85D4800B3334CE6E8716F94557B081927267D33F1E7A3DD7FC965718956E2364E956076C23CAF13A5145F1BD62DC073C8170BFA98D8A405717190A95C98E598613AEA578B5FC4A9A08B80782D9A3EF49A6A464DA9D5A3B14F1CDAADAC4143FA77C9FB73FD5DD650CF078010A8FC6C6946A4D991E75A0AC709DF3D028DB86995A2007913522632092292537BEB34196EBF1E2ACBD4A697056CEBA4DEEA8F7AEBC11963601C12C33B0FEA90102D87ECB40277B32067CBA52DD74CBDCE68597DAF04C4635AD5918E7AE99008008DDCC49713B68CA567D1F46C3C0A0A1403E722408647E072F6A3C543F9CCE36A025427211721D377ABFE15806AD07EBD60B5BCB23C50EC37B06F47D2AA941E3DF5AFB749C0E325ED8A4157E7695696B08015BAEDA784B3503F42019AA96CCBA41CB72E0CF3491F440116B5BA679355835BAC1164676279FA026655D285CA0F094CF8181303CD8D3 -20240326034823 2 6 100 4095 2 D0D3C82A946A66A83A8CC225EE93B60D6260A5167B1476B41D8FE172E9EE15CE394E23C7F35D6BB24C0D3A5266A4F21DF8FF23134101FDA61F9D92F70AF32EFBABC5408226C6F931149BF40FD4B166B21B87F0E76B95A9095E0ECED05C7F81900F7216E7DDFE22FA3E4EAD74992DB6FE68F539AAAF285CE869BDD819AF650DAE192DC217EB6988E92601FAF7FEF564AB4A01C7E24E38F7B6EF0CC17CA220E6269AB1E837FBF694B3961E5AEC0C85D4800B3334CE6E8716F94557B081927267D33F1E7A3DD7FC965718956E2364E956076C23CAF13A5145F1BD62DC073C8170BFA98D8A405717190A95C98E598613AEA578B5FC4A9A08B80782D9A3EF49A6A464DA9D5A3B14F1CDAADAC4143FA77C9FB73FD5DD650CF078010A8FC6C6946A4D991E75A0AC709DF3D028DB86995A2007913522632092292537BEB34196EBF1E2ACBD4A697056CEBA4DEEA8F7AEBC11963601C12C33B0FEA90102D87ECB40277B32067CBA52DD74CBDCE68597DAF04C4635AD5918E7AE99008008DDCC49713B68CA567D1F46C3C0A0A1403E722408647E072F6A3C543F9CCE36A025427211721D377ABFE15806AD07EBD60B5BCB23C50EC37B06F47D2AA941E3DF5AFB749C0E325ED8A4157E7695696B08015BAEDA784B3503F42019AA96CCBA41CB72E0CF3491F440116B5BA679355835BAC1164676279FA026655D285CA0F094CF8181304F3DCB -20240326035043 2 6 100 4095 5 D0D3C82A946A66A83A8CC225EE93B60D6260A5167B1476B41D8FE172E9EE15CE394E23C7F35D6BB24C0D3A5266A4F21DF8FF23134101FDA61F9D92F70AF32EFBABC5408226C6F931149BF40FD4B166B21B87F0E76B95A9095E0ECED05C7F81900F7216E7DDFE22FA3E4EAD74992DB6FE68F539AAAF285CE869BDD819AF650DAE192DC217EB6988E92601FAF7FEF564AB4A01C7E24E38F7B6EF0CC17CA220E6269AB1E837FBF694B3961E5AEC0C85D4800B3334CE6E8716F94557B081927267D33F1E7A3DD7FC965718956E2364E956076C23CAF13A5145F1BD62DC073C8170BFA98D8A405717190A95C98E598613AEA578B5FC4A9A08B80782D9A3EF49A6A464DA9D5A3B14F1CDAADAC4143FA77C9FB73FD5DD650CF078010A8FC6C6946A4D991E75A0AC709DF3D028DB86995A2007913522632092292537BEB34196EBF1E2ACBD4A697056CEBA4DEEA8F7AEBC11963601C12C33B0FEA90102D87ECB40277B32067CBA52DD74CBDCE68597DAF04C4635AD5918E7AE99008008DDCC49713B68CA567D1F46C3C0A0A1403E722408647E072F6A3C543F9CCE36A025427211721D377ABFE15806AD07EBD60B5BCB23C50EC37B06F47D2AA941E3DF5AFB749C0E325ED8A4157E7695696B08015BAEDA784B3503F42019AA96CCBA41CB72E0CF3491F440116B5BA679355835BAC1164676279FA026655D285CA0F094CF8181312A3FE7 -20240326035348 2 6 100 4095 2 D0D3C82A946A66A83A8CC225EE93B60D6260A5167B1476B41D8FE172E9EE15CE394E23C7F35D6BB24C0D3A5266A4F21DF8FF23134101FDA61F9D92F70AF32EFBABC5408226C6F931149BF40FD4B166B21B87F0E76B95A9095E0ECED05C7F81900F7216E7DDFE22FA3E4EAD74992DB6FE68F539AAAF285CE869BDD819AF650DAE192DC217EB6988E92601FAF7FEF564AB4A01C7E24E38F7B6EF0CC17CA220E6269AB1E837FBF694B3961E5AEC0C85D4800B3334CE6E8716F94557B081927267D33F1E7A3DD7FC965718956E2364E956076C23CAF13A5145F1BD62DC073C8170BFA98D8A405717190A95C98E598613AEA578B5FC4A9A08B80782D9A3EF49A6A464DA9D5A3B14F1CDAADAC4143FA77C9FB73FD5DD650CF078010A8FC6C6946A4D991E75A0AC709DF3D028DB86995A2007913522632092292537BEB34196EBF1E2ACBD4A697056CEBA4DEEA8F7AEBC11963601C12C33B0FEA90102D87ECB40277B32067CBA52DD74CBDCE68597DAF04C4635AD5918E7AE99008008DDCC49713B68CA567D1F46C3C0A0A1403E722408647E072F6A3C543F9CCE36A025427211721D377ABFE15806AD07EBD60B5BCB23C50EC37B06F47D2AA941E3DF5AFB749C0E325ED8A4157E7695696B08015BAEDA784B3503F42019AA96CCBA41CB72E0CF3491F440116B5BA679355835BAC1164676279FA026655D285CA0F094CF8181324BFA5B -20240326035602 2 6 100 4095 2 D0D3C82A946A66A83A8CC225EE93B60D6260A5167B1476B41D8FE172E9EE15CE394E23C7F35D6BB24C0D3A5266A4F21DF8FF23134101FDA61F9D92F70AF32EFBABC5408226C6F931149BF40FD4B166B21B87F0E76B95A9095E0ECED05C7F81900F7216E7DDFE22FA3E4EAD74992DB6FE68F539AAAF285CE869BDD819AF650DAE192DC217EB6988E92601FAF7FEF564AB4A01C7E24E38F7B6EF0CC17CA220E6269AB1E837FBF694B3961E5AEC0C85D4800B3334CE6E8716F94557B081927267D33F1E7A3DD7FC965718956E2364E956076C23CAF13A5145F1BD62DC073C8170BFA98D8A405717190A95C98E598613AEA578B5FC4A9A08B80782D9A3EF49A6A464DA9D5A3B14F1CDAADAC4143FA77C9FB73FD5DD650CF078010A8FC6C6946A4D991E75A0AC709DF3D028DB86995A2007913522632092292537BEB34196EBF1E2ACBD4A697056CEBA4DEEA8F7AEBC11963601C12C33B0FEA90102D87ECB40277B32067CBA52DD74CBDCE68597DAF04C4635AD5918E7AE99008008DDCC49713B68CA567D1F46C3C0A0A1403E722408647E072F6A3C543F9CCE36A025427211721D377ABFE15806AD07EBD60B5BCB23C50EC37B06F47D2AA941E3DF5AFB749C0E325ED8A4157E7695696B08015BAEDA784B3503F42019AA96CCBA41CB72E0CF3491F440116B5BA679355835BAC1164676279FA026655D285CA0F094CF8181331F2E53 -20240326035702 2 6 100 4095 2 D0D3C82A946A66A83A8CC225EE93B60D6260A5167B1476B41D8FE172E9EE15CE394E23C7F35D6BB24C0D3A5266A4F21DF8FF23134101FDA61F9D92F70AF32EFBABC5408226C6F931149BF40FD4B166B21B87F0E76B95A9095E0ECED05C7F81900F7216E7DDFE22FA3E4EAD74992DB6FE68F539AAAF285CE869BDD819AF650DAE192DC217EB6988E92601FAF7FEF564AB4A01C7E24E38F7B6EF0CC17CA220E6269AB1E837FBF694B3961E5AEC0C85D4800B3334CE6E8716F94557B081927267D33F1E7A3DD7FC965718956E2364E956076C23CAF13A5145F1BD62DC073C8170BFA98D8A405717190A95C98E598613AEA578B5FC4A9A08B80782D9A3EF49A6A464DA9D5A3B14F1CDAADAC4143FA77C9FB73FD5DD650CF078010A8FC6C6946A4D991E75A0AC709DF3D028DB86995A2007913522632092292537BEB34196EBF1E2ACBD4A697056CEBA4DEEA8F7AEBC11963601C12C33B0FEA90102D87ECB40277B32067CBA52DD74CBDCE68597DAF04C4635AD5918E7AE99008008DDCC49713B68CA567D1F46C3C0A0A1403E722408647E072F6A3C543F9CCE36A025427211721D377ABFE15806AD07EBD60B5BCB23C50EC37B06F47D2AA941E3DF5AFB749C0E325ED8A4157E7695696B08015BAEDA784B3503F42019AA96CCBA41CB72E0CF3491F440116B5BA679355835BAC1164676279FA026655D285CA0F094CF818133769453 -20240326035737 2 6 100 4095 2 D0D3C82A946A66A83A8CC225EE93B60D6260A5167B1476B41D8FE172E9EE15CE394E23C7F35D6BB24C0D3A5266A4F21DF8FF23134101FDA61F9D92F70AF32EFBABC5408226C6F931149BF40FD4B166B21B87F0E76B95A9095E0ECED05C7F81900F7216E7DDFE22FA3E4EAD74992DB6FE68F539AAAF285CE869BDD819AF650DAE192DC217EB6988E92601FAF7FEF564AB4A01C7E24E38F7B6EF0CC17CA220E6269AB1E837FBF694B3961E5AEC0C85D4800B3334CE6E8716F94557B081927267D33F1E7A3DD7FC965718956E2364E956076C23CAF13A5145F1BD62DC073C8170BFA98D8A405717190A95C98E598613AEA578B5FC4A9A08B80782D9A3EF49A6A464DA9D5A3B14F1CDAADAC4143FA77C9FB73FD5DD650CF078010A8FC6C6946A4D991E75A0AC709DF3D028DB86995A2007913522632092292537BEB34196EBF1E2ACBD4A697056CEBA4DEEA8F7AEBC11963601C12C33B0FEA90102D87ECB40277B32067CBA52DD74CBDCE68597DAF04C4635AD5918E7AE99008008DDCC49713B68CA567D1F46C3C0A0A1403E722408647E072F6A3C543F9CCE36A025427211721D377ABFE15806AD07EBD60B5BCB23C50EC37B06F47D2AA941E3DF5AFB749C0E325ED8A4157E7695696B08015BAEDA784B3503F42019AA96CCBA41CB72E0CF3491F440116B5BA679355835BAC1164676279FA026655D285CA0F094CF818133AA336B -20240326035756 2 6 100 4095 2 D0D3C82A946A66A83A8CC225EE93B60D6260A5167B1476B41D8FE172E9EE15CE394E23C7F35D6BB24C0D3A5266A4F21DF8FF23134101FDA61F9D92F70AF32EFBABC5408226C6F931149BF40FD4B166B21B87F0E76B95A9095E0ECED05C7F81900F7216E7DDFE22FA3E4EAD74992DB6FE68F539AAAF285CE869BDD819AF650DAE192DC217EB6988E92601FAF7FEF564AB4A01C7E24E38F7B6EF0CC17CA220E6269AB1E837FBF694B3961E5AEC0C85D4800B3334CE6E8716F94557B081927267D33F1E7A3DD7FC965718956E2364E956076C23CAF13A5145F1BD62DC073C8170BFA98D8A405717190A95C98E598613AEA578B5FC4A9A08B80782D9A3EF49A6A464DA9D5A3B14F1CDAADAC4143FA77C9FB73FD5DD650CF078010A8FC6C6946A4D991E75A0AC709DF3D028DB86995A2007913522632092292537BEB34196EBF1E2ACBD4A697056CEBA4DEEA8F7AEBC11963601C12C33B0FEA90102D87ECB40277B32067CBA52DD74CBDCE68597DAF04C4635AD5918E7AE99008008DDCC49713B68CA567D1F46C3C0A0A1403E722408647E072F6A3C543F9CCE36A025427211721D377ABFE15806AD07EBD60B5BCB23C50EC37B06F47D2AA941E3DF5AFB749C0E325ED8A4157E7695696B08015BAEDA784B3503F42019AA96CCBA41CB72E0CF3491F440116B5BA679355835BAC1164676279FA026655D285CA0F094CF818133C16B8B -20240326040216 2 6 100 4095 5 D0D3C82A946A66A83A8CC225EE93B60D6260A5167B1476B41D8FE172E9EE15CE394E23C7F35D6BB24C0D3A5266A4F21DF8FF23134101FDA61F9D92F70AF32EFBABC5408226C6F931149BF40FD4B166B21B87F0E76B95A9095E0ECED05C7F81900F7216E7DDFE22FA3E4EAD74992DB6FE68F539AAAF285CE869BDD819AF650DAE192DC217EB6988E92601FAF7FEF564AB4A01C7E24E38F7B6EF0CC17CA220E6269AB1E837FBF694B3961E5AEC0C85D4800B3334CE6E8716F94557B081927267D33F1E7A3DD7FC965718956E2364E956076C23CAF13A5145F1BD62DC073C8170BFA98D8A405717190A95C98E598613AEA578B5FC4A9A08B80782D9A3EF49A6A464DA9D5A3B14F1CDAADAC4143FA77C9FB73FD5DD650CF078010A8FC6C6946A4D991E75A0AC709DF3D028DB86995A2007913522632092292537BEB34196EBF1E2ACBD4A697056CEBA4DEEA8F7AEBC11963601C12C33B0FEA90102D87ECB40277B32067CBA52DD74CBDCE68597DAF04C4635AD5918E7AE99008008DDCC49713B68CA567D1F46C3C0A0A1403E722408647E072F6A3C543F9CCE36A025427211721D377ABFE15806AD07EBD60B5BCB23C50EC37B06F47D2AA941E3DF5AFB749C0E325ED8A4157E7695696B08015BAEDA784B3503F42019AA96CCBA41CB72E0CF3491F440116B5BA679355835BAC1164676279FA026655D285CA0F094CF81813553AD37 -20240326040447 2 6 100 4095 5 D0D3C82A946A66A83A8CC225EE93B60D6260A5167B1476B41D8FE172E9EE15CE394E23C7F35D6BB24C0D3A5266A4F21DF8FF23134101FDA61F9D92F70AF32EFBABC5408226C6F931149BF40FD4B166B21B87F0E76B95A9095E0ECED05C7F81900F7216E7DDFE22FA3E4EAD74992DB6FE68F539AAAF285CE869BDD819AF650DAE192DC217EB6988E92601FAF7FEF564AB4A01C7E24E38F7B6EF0CC17CA220E6269AB1E837FBF694B3961E5AEC0C85D4800B3334CE6E8716F94557B081927267D33F1E7A3DD7FC965718956E2364E956076C23CAF13A5145F1BD62DC073C8170BFA98D8A405717190A95C98E598613AEA578B5FC4A9A08B80782D9A3EF49A6A464DA9D5A3B14F1CDAADAC4143FA77C9FB73FD5DD650CF078010A8FC6C6946A4D991E75A0AC709DF3D028DB86995A2007913522632092292537BEB34196EBF1E2ACBD4A697056CEBA4DEEA8F7AEBC11963601C12C33B0FEA90102D87ECB40277B32067CBA52DD74CBDCE68597DAF04C4635AD5918E7AE99008008DDCC49713B68CA567D1F46C3C0A0A1403E722408647E072F6A3C543F9CCE36A025427211721D377ABFE15806AD07EBD60B5BCB23C50EC37B06F47D2AA941E3DF5AFB749C0E325ED8A4157E7695696B08015BAEDA784B3503F42019AA96CCBA41CB72E0CF3491F440116B5BA679355835BAC1164676279FA026655D285CA0F094CF81813644788F -20240326040552 2 6 100 4095 5 D0D3C82A946A66A83A8CC225EE93B60D6260A5167B1476B41D8FE172E9EE15CE394E23C7F35D6BB24C0D3A5266A4F21DF8FF23134101FDA61F9D92F70AF32EFBABC5408226C6F931149BF40FD4B166B21B87F0E76B95A9095E0ECED05C7F81900F7216E7DDFE22FA3E4EAD74992DB6FE68F539AAAF285CE869BDD819AF650DAE192DC217EB6988E92601FAF7FEF564AB4A01C7E24E38F7B6EF0CC17CA220E6269AB1E837FBF694B3961E5AEC0C85D4800B3334CE6E8716F94557B081927267D33F1E7A3DD7FC965718956E2364E956076C23CAF13A5145F1BD62DC073C8170BFA98D8A405717190A95C98E598613AEA578B5FC4A9A08B80782D9A3EF49A6A464DA9D5A3B14F1CDAADAC4143FA77C9FB73FD5DD650CF078010A8FC6C6946A4D991E75A0AC709DF3D028DB86995A2007913522632092292537BEB34196EBF1E2ACBD4A697056CEBA4DEEA8F7AEBC11963601C12C33B0FEA90102D87ECB40277B32067CBA52DD74CBDCE68597DAF04C4635AD5918E7AE99008008DDCC49713B68CA567D1F46C3C0A0A1403E722408647E072F6A3C543F9CCE36A025427211721D377ABFE15806AD07EBD60B5BCB23C50EC37B06F47D2AA941E3DF5AFB749C0E325ED8A4157E7695696B08015BAEDA784B3503F42019AA96CCBA41CB72E0CF3491F440116B5BA679355835BAC1164676279FA026655D285CA0F094CF818136A4C7F7 -20240326040951 2 6 100 4095 2 F52D556E0D75D910A1C4DF0D571DBCEBCAB3513CA78923277BA6240C1BB579A73E56739548C0F6882B5C8BF03A15C36CA58355E6EE2170ACDFBB13CF60BA34BD92FFDC091D9AC86141CAC874E1615508A2B1A1B4A31E81B2E1982AA3ED676B3DFBD0962400B188F56C6DFCDE7CDDBCEA57654D61272C585EDBBE0449D1AF74C537F8A022BADDCFC2E6F3050B586A6761CFD444DF39CC585715A0CC863B9B225499B3097CE62B7645485754A1A8B3010FCEF13EA07D29161D1F3E701B5BC3D99B1EF2F8916F862B4815BC0D0A3385B33FEDF1B7FBC85F615E051B8A31F32A6B4213754A5F8E4BBFCE77A292BCF482B7FC30E817A591170E72696359B3635CB393BEF4075DDD7D0734E358DB2A803EE621CBB04010EAC75F810D72C41A3D7013EE2799A59D7A8ADAB73E0FD5EE4A6498CA8DF000AC152C0F6CA1C57660D0DD750A6A5F788F89CC424FD19FBD42E9C7E2A949FBF43FC67528AFD879A37A0D1D38E05328C5216BA938C058A341AAEA8D8EACBA42610B0E7823E74CAB6CA791F17AECB532DA5BF80C056B67BDFDED51A97C95AFCD32509C87600A2D734F23944552727CF726068C04F339D206BAF472A0C2E2F22D7CF939B7A6FB3D5C67B0564537A33E6802DBD07AEE817BAD37B5287BA678E962EB3B8B5BEFAC937241725A1B8789C1609706B24C7266FAE9195B9536151FE3D65684AACF304BC664F4D80EA89E4B -20240326042517 2 6 100 4095 2 F52D556E0D75D910A1C4DF0D571DBCEBCAB3513CA78923277BA6240C1BB579A73E56739548C0F6882B5C8BF03A15C36CA58355E6EE2170ACDFBB13CF60BA34BD92FFDC091D9AC86141CAC874E1615508A2B1A1B4A31E81B2E1982AA3ED676B3DFBD0962400B188F56C6DFCDE7CDDBCEA57654D61272C585EDBBE0449D1AF74C537F8A022BADDCFC2E6F3050B586A6761CFD444DF39CC585715A0CC863B9B225499B3097CE62B7645485754A1A8B3010FCEF13EA07D29161D1F3E701B5BC3D99B1EF2F8916F862B4815BC0D0A3385B33FEDF1B7FBC85F615E051B8A31F32A6B4213754A5F8E4BBFCE77A292BCF482B7FC30E817A591170E72696359B3635CB393BEF4075DDD7D0734E358DB2A803EE621CBB04010EAC75F810D72C41A3D7013EE2799A59D7A8ADAB73E0FD5EE4A6498CA8DF000AC152C0F6CA1C57660D0DD750A6A5F788F89CC424FD19FBD42E9C7E2A949FBF43FC67528AFD879A37A0D1D38E05328C5216BA938C058A341AAEA8D8EACBA42610B0E7823E74CAB6CA791F17AECB532DA5BF80C056B67BDFDED51A97C95AFCD32509C87600A2D734F23944552727CF726068C04F339D206BAF472A0C2E2F22D7CF939B7A6FB3D5C67B0564537A33E6802DBD07AEE817BAD37B5287BA678E962EB3B8B5BEFAC937241725A1B8789C1609706B24C7266FAE9195B9536151FE3D65684AACF304BC664F4D8147E15B3 -20240326042616 2 6 100 4095 2 F52D556E0D75D910A1C4DF0D571DBCEBCAB3513CA78923277BA6240C1BB579A73E56739548C0F6882B5C8BF03A15C36CA58355E6EE2170ACDFBB13CF60BA34BD92FFDC091D9AC86141CAC874E1615508A2B1A1B4A31E81B2E1982AA3ED676B3DFBD0962400B188F56C6DFCDE7CDDBCEA57654D61272C585EDBBE0449D1AF74C537F8A022BADDCFC2E6F3050B586A6761CFD444DF39CC585715A0CC863B9B225499B3097CE62B7645485754A1A8B3010FCEF13EA07D29161D1F3E701B5BC3D99B1EF2F8916F862B4815BC0D0A3385B33FEDF1B7FBC85F615E051B8A31F32A6B4213754A5F8E4BBFCE77A292BCF482B7FC30E817A591170E72696359B3635CB393BEF4075DDD7D0734E358DB2A803EE621CBB04010EAC75F810D72C41A3D7013EE2799A59D7A8ADAB73E0FD5EE4A6498CA8DF000AC152C0F6CA1C57660D0DD750A6A5F788F89CC424FD19FBD42E9C7E2A949FBF43FC67528AFD879A37A0D1D38E05328C5216BA938C058A341AAEA8D8EACBA42610B0E7823E74CAB6CA791F17AECB532DA5BF80C056B67BDFDED51A97C95AFCD32509C87600A2D734F23944552727CF726068C04F339D206BAF472A0C2E2F22D7CF939B7A6FB3D5C67B0564537A33E6802DBD07AEE817BAD37B5287BA678E962EB3B8B5BEFAC937241725A1B8789C1609706B24C7266FAE9195B9536151FE3D65684AACF304BC664F4D814D61A3B -20240326043713 2 6 100 4095 2 F52D556E0D75D910A1C4DF0D571DBCEBCAB3513CA78923277BA6240C1BB579A73E56739548C0F6882B5C8BF03A15C36CA58355E6EE2170ACDFBB13CF60BA34BD92FFDC091D9AC86141CAC874E1615508A2B1A1B4A31E81B2E1982AA3ED676B3DFBD0962400B188F56C6DFCDE7CDDBCEA57654D61272C585EDBBE0449D1AF74C537F8A022BADDCFC2E6F3050B586A6761CFD444DF39CC585715A0CC863B9B225499B3097CE62B7645485754A1A8B3010FCEF13EA07D29161D1F3E701B5BC3D99B1EF2F8916F862B4815BC0D0A3385B33FEDF1B7FBC85F615E051B8A31F32A6B4213754A5F8E4BBFCE77A292BCF482B7FC30E817A591170E72696359B3635CB393BEF4075DDD7D0734E358DB2A803EE621CBB04010EAC75F810D72C41A3D7013EE2799A59D7A8ADAB73E0FD5EE4A6498CA8DF000AC152C0F6CA1C57660D0DD750A6A5F788F89CC424FD19FBD42E9C7E2A949FBF43FC67528AFD879A37A0D1D38E05328C5216BA938C058A341AAEA8D8EACBA42610B0E7823E74CAB6CA791F17AECB532DA5BF80C056B67BDFDED51A97C95AFCD32509C87600A2D734F23944552727CF726068C04F339D206BAF472A0C2E2F22D7CF939B7A6FB3D5C67B0564537A33E6802DBD07AEE817BAD37B5287BA678E962EB3B8B5BEFAC937241725A1B8789C1609706B24C7266FAE9195B9536151FE3D65684AACF304BC664F4D818FD20D3 -20240326043724 2 6 100 4095 2 F52D556E0D75D910A1C4DF0D571DBCEBCAB3513CA78923277BA6240C1BB579A73E56739548C0F6882B5C8BF03A15C36CA58355E6EE2170ACDFBB13CF60BA34BD92FFDC091D9AC86141CAC874E1615508A2B1A1B4A31E81B2E1982AA3ED676B3DFBD0962400B188F56C6DFCDE7CDDBCEA57654D61272C585EDBBE0449D1AF74C537F8A022BADDCFC2E6F3050B586A6761CFD444DF39CC585715A0CC863B9B225499B3097CE62B7645485754A1A8B3010FCEF13EA07D29161D1F3E701B5BC3D99B1EF2F8916F862B4815BC0D0A3385B33FEDF1B7FBC85F615E051B8A31F32A6B4213754A5F8E4BBFCE77A292BCF482B7FC30E817A591170E72696359B3635CB393BEF4075DDD7D0734E358DB2A803EE621CBB04010EAC75F810D72C41A3D7013EE2799A59D7A8ADAB73E0FD5EE4A6498CA8DF000AC152C0F6CA1C57660D0DD750A6A5F788F89CC424FD19FBD42E9C7E2A949FBF43FC67528AFD879A37A0D1D38E05328C5216BA938C058A341AAEA8D8EACBA42610B0E7823E74CAB6CA791F17AECB532DA5BF80C056B67BDFDED51A97C95AFCD32509C87600A2D734F23944552727CF726068C04F339D206BAF472A0C2E2F22D7CF939B7A6FB3D5C67B0564537A33E6802DBD07AEE817BAD37B5287BA678E962EB3B8B5BEFAC937241725A1B8789C1609706B24C7266FAE9195B9536151FE3D65684AACF304BC664F4D819078123 -20240326043742 2 6 100 4095 5 F52D556E0D75D910A1C4DF0D571DBCEBCAB3513CA78923277BA6240C1BB579A73E56739548C0F6882B5C8BF03A15C36CA58355E6EE2170ACDFBB13CF60BA34BD92FFDC091D9AC86141CAC874E1615508A2B1A1B4A31E81B2E1982AA3ED676B3DFBD0962400B188F56C6DFCDE7CDDBCEA57654D61272C585EDBBE0449D1AF74C537F8A022BADDCFC2E6F3050B586A6761CFD444DF39CC585715A0CC863B9B225499B3097CE62B7645485754A1A8B3010FCEF13EA07D29161D1F3E701B5BC3D99B1EF2F8916F862B4815BC0D0A3385B33FEDF1B7FBC85F615E051B8A31F32A6B4213754A5F8E4BBFCE77A292BCF482B7FC30E817A591170E72696359B3635CB393BEF4075DDD7D0734E358DB2A803EE621CBB04010EAC75F810D72C41A3D7013EE2799A59D7A8ADAB73E0FD5EE4A6498CA8DF000AC152C0F6CA1C57660D0DD750A6A5F788F89CC424FD19FBD42E9C7E2A949FBF43FC67528AFD879A37A0D1D38E05328C5216BA938C058A341AAEA8D8EACBA42610B0E7823E74CAB6CA791F17AECB532DA5BF80C056B67BDFDED51A97C95AFCD32509C87600A2D734F23944552727CF726068C04F339D206BAF472A0C2E2F22D7CF939B7A6FB3D5C67B0564537A33E6802DBD07AEE817BAD37B5287BA678E962EB3B8B5BEFAC937241725A1B8789C1609706B24C7266FAE9195B9536151FE3D65684AACF304BC664F4D8191EAEFF -20240326044025 2 6 100 4095 5 F52D556E0D75D910A1C4DF0D571DBCEBCAB3513CA78923277BA6240C1BB579A73E56739548C0F6882B5C8BF03A15C36CA58355E6EE2170ACDFBB13CF60BA34BD92FFDC091D9AC86141CAC874E1615508A2B1A1B4A31E81B2E1982AA3ED676B3DFBD0962400B188F56C6DFCDE7CDDBCEA57654D61272C585EDBBE0449D1AF74C537F8A022BADDCFC2E6F3050B586A6761CFD444DF39CC585715A0CC863B9B225499B3097CE62B7645485754A1A8B3010FCEF13EA07D29161D1F3E701B5BC3D99B1EF2F8916F862B4815BC0D0A3385B33FEDF1B7FBC85F615E051B8A31F32A6B4213754A5F8E4BBFCE77A292BCF482B7FC30E817A591170E72696359B3635CB393BEF4075DDD7D0734E358DB2A803EE621CBB04010EAC75F810D72C41A3D7013EE2799A59D7A8ADAB73E0FD5EE4A6498CA8DF000AC152C0F6CA1C57660D0DD750A6A5F788F89CC424FD19FBD42E9C7E2A949FBF43FC67528AFD879A37A0D1D38E05328C5216BA938C058A341AAEA8D8EACBA42610B0E7823E74CAB6CA791F17AECB532DA5BF80C056B67BDFDED51A97C95AFCD32509C87600A2D734F23944552727CF726068C04F339D206BAF472A0C2E2F22D7CF939B7A6FB3D5C67B0564537A33E6802DBD07AEE817BAD37B5287BA678E962EB3B8B5BEFAC937241725A1B8789C1609706B24C7266FAE9195B9536151FE3D65684AACF304BC664F4D81A204197 -20240326044258 2 6 100 4095 5 F52D556E0D75D910A1C4DF0D571DBCEBCAB3513CA78923277BA6240C1BB579A73E56739548C0F6882B5C8BF03A15C36CA58355E6EE2170ACDFBB13CF60BA34BD92FFDC091D9AC86141CAC874E1615508A2B1A1B4A31E81B2E1982AA3ED676B3DFBD0962400B188F56C6DFCDE7CDDBCEA57654D61272C585EDBBE0449D1AF74C537F8A022BADDCFC2E6F3050B586A6761CFD444DF39CC585715A0CC863B9B225499B3097CE62B7645485754A1A8B3010FCEF13EA07D29161D1F3E701B5BC3D99B1EF2F8916F862B4815BC0D0A3385B33FEDF1B7FBC85F615E051B8A31F32A6B4213754A5F8E4BBFCE77A292BCF482B7FC30E817A591170E72696359B3635CB393BEF4075DDD7D0734E358DB2A803EE621CBB04010EAC75F810D72C41A3D7013EE2799A59D7A8ADAB73E0FD5EE4A6498CA8DF000AC152C0F6CA1C57660D0DD750A6A5F788F89CC424FD19FBD42E9C7E2A949FBF43FC67528AFD879A37A0D1D38E05328C5216BA938C058A341AAEA8D8EACBA42610B0E7823E74CAB6CA791F17AECB532DA5BF80C056B67BDFDED51A97C95AFCD32509C87600A2D734F23944552727CF726068C04F339D206BAF472A0C2E2F22D7CF939B7A6FB3D5C67B0564537A33E6802DBD07AEE817BAD37B5287BA678E962EB3B8B5BEFAC937241725A1B8789C1609706B24C7266FAE9195B9536151FE3D65684AACF304BC664F4D81B145927 -20240326044447 2 6 100 4095 2 F52D556E0D75D910A1C4DF0D571DBCEBCAB3513CA78923277BA6240C1BB579A73E56739548C0F6882B5C8BF03A15C36CA58355E6EE2170ACDFBB13CF60BA34BD92FFDC091D9AC86141CAC874E1615508A2B1A1B4A31E81B2E1982AA3ED676B3DFBD0962400B188F56C6DFCDE7CDDBCEA57654D61272C585EDBBE0449D1AF74C537F8A022BADDCFC2E6F3050B586A6761CFD444DF39CC585715A0CC863B9B225499B3097CE62B7645485754A1A8B3010FCEF13EA07D29161D1F3E701B5BC3D99B1EF2F8916F862B4815BC0D0A3385B33FEDF1B7FBC85F615E051B8A31F32A6B4213754A5F8E4BBFCE77A292BCF482B7FC30E817A591170E72696359B3635CB393BEF4075DDD7D0734E358DB2A803EE621CBB04010EAC75F810D72C41A3D7013EE2799A59D7A8ADAB73E0FD5EE4A6498CA8DF000AC152C0F6CA1C57660D0DD750A6A5F788F89CC424FD19FBD42E9C7E2A949FBF43FC67528AFD879A37A0D1D38E05328C5216BA938C058A341AAEA8D8EACBA42610B0E7823E74CAB6CA791F17AECB532DA5BF80C056B67BDFDED51A97C95AFCD32509C87600A2D734F23944552727CF726068C04F339D206BAF472A0C2E2F22D7CF939B7A6FB3D5C67B0564537A33E6802DBD07AEE817BAD37B5287BA678E962EB3B8B5BEFAC937241725A1B8789C1609706B24C7266FAE9195B9536151FE3D65684AACF304BC664F4D81BB935AB -20240326044534 2 6 100 4095 5 F52D556E0D75D910A1C4DF0D571DBCEBCAB3513CA78923277BA6240C1BB579A73E56739548C0F6882B5C8BF03A15C36CA58355E6EE2170ACDFBB13CF60BA34BD92FFDC091D9AC86141CAC874E1615508A2B1A1B4A31E81B2E1982AA3ED676B3DFBD0962400B188F56C6DFCDE7CDDBCEA57654D61272C585EDBBE0449D1AF74C537F8A022BADDCFC2E6F3050B586A6761CFD444DF39CC585715A0CC863B9B225499B3097CE62B7645485754A1A8B3010FCEF13EA07D29161D1F3E701B5BC3D99B1EF2F8916F862B4815BC0D0A3385B33FEDF1B7FBC85F615E051B8A31F32A6B4213754A5F8E4BBFCE77A292BCF482B7FC30E817A591170E72696359B3635CB393BEF4075DDD7D0734E358DB2A803EE621CBB04010EAC75F810D72C41A3D7013EE2799A59D7A8ADAB73E0FD5EE4A6498CA8DF000AC152C0F6CA1C57660D0DD750A6A5F788F89CC424FD19FBD42E9C7E2A949FBF43FC67528AFD879A37A0D1D38E05328C5216BA938C058A341AAEA8D8EACBA42610B0E7823E74CAB6CA791F17AECB532DA5BF80C056B67BDFDED51A97C95AFCD32509C87600A2D734F23944552727CF726068C04F339D206BAF472A0C2E2F22D7CF939B7A6FB3D5C67B0564537A33E6802DBD07AEE817BAD37B5287BA678E962EB3B8B5BEFAC937241725A1B8789C1609706B24C7266FAE9195B9536151FE3D65684AACF304BC664F4D81BFCFA6F -20240326045348 2 6 100 4095 2 F52D556E0D75D910A1C4DF0D571DBCEBCAB3513CA78923277BA6240C1BB579A73E56739548C0F6882B5C8BF03A15C36CA58355E6EE2170ACDFBB13CF60BA34BD92FFDC091D9AC86141CAC874E1615508A2B1A1B4A31E81B2E1982AA3ED676B3DFBD0962400B188F56C6DFCDE7CDDBCEA57654D61272C585EDBBE0449D1AF74C537F8A022BADDCFC2E6F3050B586A6761CFD444DF39CC585715A0CC863B9B225499B3097CE62B7645485754A1A8B3010FCEF13EA07D29161D1F3E701B5BC3D99B1EF2F8916F862B4815BC0D0A3385B33FEDF1B7FBC85F615E051B8A31F32A6B4213754A5F8E4BBFCE77A292BCF482B7FC30E817A591170E72696359B3635CB393BEF4075DDD7D0734E358DB2A803EE621CBB04010EAC75F810D72C41A3D7013EE2799A59D7A8ADAB73E0FD5EE4A6498CA8DF000AC152C0F6CA1C57660D0DD750A6A5F788F89CC424FD19FBD42E9C7E2A949FBF43FC67528AFD879A37A0D1D38E05328C5216BA938C058A341AAEA8D8EACBA42610B0E7823E74CAB6CA791F17AECB532DA5BF80C056B67BDFDED51A97C95AFCD32509C87600A2D734F23944552727CF726068C04F339D206BAF472A0C2E2F22D7CF939B7A6FB3D5C67B0564537A33E6802DBD07AEE817BAD37B5287BA678E962EB3B8B5BEFAC937241725A1B8789C1609706B24C7266FAE9195B9536151FE3D65684AACF304BC664F4D81F0CEB6B -20240326045438 2 6 100 4095 2 F52D556E0D75D910A1C4DF0D571DBCEBCAB3513CA78923277BA6240C1BB579A73E56739548C0F6882B5C8BF03A15C36CA58355E6EE2170ACDFBB13CF60BA34BD92FFDC091D9AC86141CAC874E1615508A2B1A1B4A31E81B2E1982AA3ED676B3DFBD0962400B188F56C6DFCDE7CDDBCEA57654D61272C585EDBBE0449D1AF74C537F8A022BADDCFC2E6F3050B586A6761CFD444DF39CC585715A0CC863B9B225499B3097CE62B7645485754A1A8B3010FCEF13EA07D29161D1F3E701B5BC3D99B1EF2F8916F862B4815BC0D0A3385B33FEDF1B7FBC85F615E051B8A31F32A6B4213754A5F8E4BBFCE77A292BCF482B7FC30E817A591170E72696359B3635CB393BEF4075DDD7D0734E358DB2A803EE621CBB04010EAC75F810D72C41A3D7013EE2799A59D7A8ADAB73E0FD5EE4A6498CA8DF000AC152C0F6CA1C57660D0DD750A6A5F788F89CC424FD19FBD42E9C7E2A949FBF43FC67528AFD879A37A0D1D38E05328C5216BA938C058A341AAEA8D8EACBA42610B0E7823E74CAB6CA791F17AECB532DA5BF80C056B67BDFDED51A97C95AFCD32509C87600A2D734F23944552727CF726068C04F339D206BAF472A0C2E2F22D7CF939B7A6FB3D5C67B0564537A33E6802DBD07AEE817BAD37B5287BA678E962EB3B8B5BEFAC937241725A1B8789C1609706B24C7266FAE9195B9536151FE3D65684AACF304BC664F4D81F582F4B -20240326045630 2 6 100 4095 2 F52D556E0D75D910A1C4DF0D571DBCEBCAB3513CA78923277BA6240C1BB579A73E56739548C0F6882B5C8BF03A15C36CA58355E6EE2170ACDFBB13CF60BA34BD92FFDC091D9AC86141CAC874E1615508A2B1A1B4A31E81B2E1982AA3ED676B3DFBD0962400B188F56C6DFCDE7CDDBCEA57654D61272C585EDBBE0449D1AF74C537F8A022BADDCFC2E6F3050B586A6761CFD444DF39CC585715A0CC863B9B225499B3097CE62B7645485754A1A8B3010FCEF13EA07D29161D1F3E701B5BC3D99B1EF2F8916F862B4815BC0D0A3385B33FEDF1B7FBC85F615E051B8A31F32A6B4213754A5F8E4BBFCE77A292BCF482B7FC30E817A591170E72696359B3635CB393BEF4075DDD7D0734E358DB2A803EE621CBB04010EAC75F810D72C41A3D7013EE2799A59D7A8ADAB73E0FD5EE4A6498CA8DF000AC152C0F6CA1C57660D0DD750A6A5F788F89CC424FD19FBD42E9C7E2A949FBF43FC67528AFD879A37A0D1D38E05328C5216BA938C058A341AAEA8D8EACBA42610B0E7823E74CAB6CA791F17AECB532DA5BF80C056B67BDFDED51A97C95AFCD32509C87600A2D734F23944552727CF726068C04F339D206BAF472A0C2E2F22D7CF939B7A6FB3D5C67B0564537A33E6802DBD07AEE817BAD37B5287BA678E962EB3B8B5BEFAC937241725A1B8789C1609706B24C7266FAE9195B9536151FE3D65684AACF304BC664F4D82007A843 -20240326045745 2 6 100 4095 5 F52D556E0D75D910A1C4DF0D571DBCEBCAB3513CA78923277BA6240C1BB579A73E56739548C0F6882B5C8BF03A15C36CA58355E6EE2170ACDFBB13CF60BA34BD92FFDC091D9AC86141CAC874E1615508A2B1A1B4A31E81B2E1982AA3ED676B3DFBD0962400B188F56C6DFCDE7CDDBCEA57654D61272C585EDBBE0449D1AF74C537F8A022BADDCFC2E6F3050B586A6761CFD444DF39CC585715A0CC863B9B225499B3097CE62B7645485754A1A8B3010FCEF13EA07D29161D1F3E701B5BC3D99B1EF2F8916F862B4815BC0D0A3385B33FEDF1B7FBC85F615E051B8A31F32A6B4213754A5F8E4BBFCE77A292BCF482B7FC30E817A591170E72696359B3635CB393BEF4075DDD7D0734E358DB2A803EE621CBB04010EAC75F810D72C41A3D7013EE2799A59D7A8ADAB73E0FD5EE4A6498CA8DF000AC152C0F6CA1C57660D0DD750A6A5F788F89CC424FD19FBD42E9C7E2A949FBF43FC67528AFD879A37A0D1D38E05328C5216BA938C058A341AAEA8D8EACBA42610B0E7823E74CAB6CA791F17AECB532DA5BF80C056B67BDFDED51A97C95AFCD32509C87600A2D734F23944552727CF726068C04F339D206BAF472A0C2E2F22D7CF939B7A6FB3D5C67B0564537A33E6802DBD07AEE817BAD37B5287BA678E962EB3B8B5BEFAC937241725A1B8789C1609706B24C7266FAE9195B9536151FE3D65684AACF304BC664F4D820792B27 -20240326045949 2 6 100 4095 5 F52D556E0D75D910A1C4DF0D571DBCEBCAB3513CA78923277BA6240C1BB579A73E56739548C0F6882B5C8BF03A15C36CA58355E6EE2170ACDFBB13CF60BA34BD92FFDC091D9AC86141CAC874E1615508A2B1A1B4A31E81B2E1982AA3ED676B3DFBD0962400B188F56C6DFCDE7CDDBCEA57654D61272C585EDBBE0449D1AF74C537F8A022BADDCFC2E6F3050B586A6761CFD444DF39CC585715A0CC863B9B225499B3097CE62B7645485754A1A8B3010FCEF13EA07D29161D1F3E701B5BC3D99B1EF2F8916F862B4815BC0D0A3385B33FEDF1B7FBC85F615E051B8A31F32A6B4213754A5F8E4BBFCE77A292BCF482B7FC30E817A591170E72696359B3635CB393BEF4075DDD7D0734E358DB2A803EE621CBB04010EAC75F810D72C41A3D7013EE2799A59D7A8ADAB73E0FD5EE4A6498CA8DF000AC152C0F6CA1C57660D0DD750A6A5F788F89CC424FD19FBD42E9C7E2A949FBF43FC67528AFD879A37A0D1D38E05328C5216BA938C058A341AAEA8D8EACBA42610B0E7823E74CAB6CA791F17AECB532DA5BF80C056B67BDFDED51A97C95AFCD32509C87600A2D734F23944552727CF726068C04F339D206BAF472A0C2E2F22D7CF939B7A6FB3D5C67B0564537A33E6802DBD07AEE817BAD37B5287BA678E962EB3B8B5BEFAC937241725A1B8789C1609706B24C7266FAE9195B9536151FE3D65684AACF304BC664F4D82142CB8F -20240326045957 2 6 100 4095 2 F52D556E0D75D910A1C4DF0D571DBCEBCAB3513CA78923277BA6240C1BB579A73E56739548C0F6882B5C8BF03A15C36CA58355E6EE2170ACDFBB13CF60BA34BD92FFDC091D9AC86141CAC874E1615508A2B1A1B4A31E81B2E1982AA3ED676B3DFBD0962400B188F56C6DFCDE7CDDBCEA57654D61272C585EDBBE0449D1AF74C537F8A022BADDCFC2E6F3050B586A6761CFD444DF39CC585715A0CC863B9B225499B3097CE62B7645485754A1A8B3010FCEF13EA07D29161D1F3E701B5BC3D99B1EF2F8916F862B4815BC0D0A3385B33FEDF1B7FBC85F615E051B8A31F32A6B4213754A5F8E4BBFCE77A292BCF482B7FC30E817A591170E72696359B3635CB393BEF4075DDD7D0734E358DB2A803EE621CBB04010EAC75F810D72C41A3D7013EE2799A59D7A8ADAB73E0FD5EE4A6498CA8DF000AC152C0F6CA1C57660D0DD750A6A5F788F89CC424FD19FBD42E9C7E2A949FBF43FC67528AFD879A37A0D1D38E05328C5216BA938C058A341AAEA8D8EACBA42610B0E7823E74CAB6CA791F17AECB532DA5BF80C056B67BDFDED51A97C95AFCD32509C87600A2D734F23944552727CF726068C04F339D206BAF472A0C2E2F22D7CF939B7A6FB3D5C67B0564537A33E6802DBD07AEE817BAD37B5287BA678E962EB3B8B5BEFAC937241725A1B8789C1609706B24C7266FAE9195B9536151FE3D65684AACF304BC664F4D82148EA73 -20240326050355 2 6 100 4095 5 F52D556E0D75D910A1C4DF0D571DBCEBCAB3513CA78923277BA6240C1BB579A73E56739548C0F6882B5C8BF03A15C36CA58355E6EE2170ACDFBB13CF60BA34BD92FFDC091D9AC86141CAC874E1615508A2B1A1B4A31E81B2E1982AA3ED676B3DFBD0962400B188F56C6DFCDE7CDDBCEA57654D61272C585EDBBE0449D1AF74C537F8A022BADDCFC2E6F3050B586A6761CFD444DF39CC585715A0CC863B9B225499B3097CE62B7645485754A1A8B3010FCEF13EA07D29161D1F3E701B5BC3D99B1EF2F8916F862B4815BC0D0A3385B33FEDF1B7FBC85F615E051B8A31F32A6B4213754A5F8E4BBFCE77A292BCF482B7FC30E817A591170E72696359B3635CB393BEF4075DDD7D0734E358DB2A803EE621CBB04010EAC75F810D72C41A3D7013EE2799A59D7A8ADAB73E0FD5EE4A6498CA8DF000AC152C0F6CA1C57660D0DD750A6A5F788F89CC424FD19FBD42E9C7E2A949FBF43FC67528AFD879A37A0D1D38E05328C5216BA938C058A341AAEA8D8EACBA42610B0E7823E74CAB6CA791F17AECB532DA5BF80C056B67BDFDED51A97C95AFCD32509C87600A2D734F23944552727CF726068C04F339D206BAF472A0C2E2F22D7CF939B7A6FB3D5C67B0564537A33E6802DBD07AEE817BAD37B5287BA678E962EB3B8B5BEFAC937241725A1B8789C1609706B24C7266FAE9195B9536151FE3D65684AACF304BC664F4D822CAC6BF -20240326050713 2 6 100 4095 2 F52D556E0D75D910A1C4DF0D571DBCEBCAB3513CA78923277BA6240C1BB579A73E56739548C0F6882B5C8BF03A15C36CA58355E6EE2170ACDFBB13CF60BA34BD92FFDC091D9AC86141CAC874E1615508A2B1A1B4A31E81B2E1982AA3ED676B3DFBD0962400B188F56C6DFCDE7CDDBCEA57654D61272C585EDBBE0449D1AF74C537F8A022BADDCFC2E6F3050B586A6761CFD444DF39CC585715A0CC863B9B225499B3097CE62B7645485754A1A8B3010FCEF13EA07D29161D1F3E701B5BC3D99B1EF2F8916F862B4815BC0D0A3385B33FEDF1B7FBC85F615E051B8A31F32A6B4213754A5F8E4BBFCE77A292BCF482B7FC30E817A591170E72696359B3635CB393BEF4075DDD7D0734E358DB2A803EE621CBB04010EAC75F810D72C41A3D7013EE2799A59D7A8ADAB73E0FD5EE4A6498CA8DF000AC152C0F6CA1C57660D0DD750A6A5F788F89CC424FD19FBD42E9C7E2A949FBF43FC67528AFD879A37A0D1D38E05328C5216BA938C058A341AAEA8D8EACBA42610B0E7823E74CAB6CA791F17AECB532DA5BF80C056B67BDFDED51A97C95AFCD32509C87600A2D734F23944552727CF726068C04F339D206BAF472A0C2E2F22D7CF939B7A6FB3D5C67B0564537A33E6802DBD07AEE817BAD37B5287BA678E962EB3B8B5BEFAC937241725A1B8789C1609706B24C7266FAE9195B9536151FE3D65684AACF304BC664F4D8240BBCC3 -20240326050731 2 6 100 4095 2 F52D556E0D75D910A1C4DF0D571DBCEBCAB3513CA78923277BA6240C1BB579A73E56739548C0F6882B5C8BF03A15C36CA58355E6EE2170ACDFBB13CF60BA34BD92FFDC091D9AC86141CAC874E1615508A2B1A1B4A31E81B2E1982AA3ED676B3DFBD0962400B188F56C6DFCDE7CDDBCEA57654D61272C585EDBBE0449D1AF74C537F8A022BADDCFC2E6F3050B586A6761CFD444DF39CC585715A0CC863B9B225499B3097CE62B7645485754A1A8B3010FCEF13EA07D29161D1F3E701B5BC3D99B1EF2F8916F862B4815BC0D0A3385B33FEDF1B7FBC85F615E051B8A31F32A6B4213754A5F8E4BBFCE77A292BCF482B7FC30E817A591170E72696359B3635CB393BEF4075DDD7D0734E358DB2A803EE621CBB04010EAC75F810D72C41A3D7013EE2799A59D7A8ADAB73E0FD5EE4A6498CA8DF000AC152C0F6CA1C57660D0DD750A6A5F788F89CC424FD19FBD42E9C7E2A949FBF43FC67528AFD879A37A0D1D38E05328C5216BA938C058A341AAEA8D8EACBA42610B0E7823E74CAB6CA791F17AECB532DA5BF80C056B67BDFDED51A97C95AFCD32509C87600A2D734F23944552727CF726068C04F339D206BAF472A0C2E2F22D7CF939B7A6FB3D5C67B0564537A33E6802DBD07AEE817BAD37B5287BA678E962EB3B8B5BEFAC937241725A1B8789C1609706B24C7266FAE9195B9536151FE3D65684AACF304BC664F4D824214D3B -20240326050903 2 6 100 4095 2 F52D556E0D75D910A1C4DF0D571DBCEBCAB3513CA78923277BA6240C1BB579A73E56739548C0F6882B5C8BF03A15C36CA58355E6EE2170ACDFBB13CF60BA34BD92FFDC091D9AC86141CAC874E1615508A2B1A1B4A31E81B2E1982AA3ED676B3DFBD0962400B188F56C6DFCDE7CDDBCEA57654D61272C585EDBBE0449D1AF74C537F8A022BADDCFC2E6F3050B586A6761CFD444DF39CC585715A0CC863B9B225499B3097CE62B7645485754A1A8B3010FCEF13EA07D29161D1F3E701B5BC3D99B1EF2F8916F862B4815BC0D0A3385B33FEDF1B7FBC85F615E051B8A31F32A6B4213754A5F8E4BBFCE77A292BCF482B7FC30E817A591170E72696359B3635CB393BEF4075DDD7D0734E358DB2A803EE621CBB04010EAC75F810D72C41A3D7013EE2799A59D7A8ADAB73E0FD5EE4A6498CA8DF000AC152C0F6CA1C57660D0DD750A6A5F788F89CC424FD19FBD42E9C7E2A949FBF43FC67528AFD879A37A0D1D38E05328C5216BA938C058A341AAEA8D8EACBA42610B0E7823E74CAB6CA791F17AECB532DA5BF80C056B67BDFDED51A97C95AFCD32509C87600A2D734F23944552727CF726068C04F339D206BAF472A0C2E2F22D7CF939B7A6FB3D5C67B0564537A33E6802DBD07AEE817BAD37B5287BA678E962EB3B8B5BEFAC937241725A1B8789C1609706B24C7266FAE9195B9536151FE3D65684AACF304BC664F4D824ACACFB -20240326051214 2 6 100 4095 5 F52D556E0D75D910A1C4DF0D571DBCEBCAB3513CA78923277BA6240C1BB579A73E56739548C0F6882B5C8BF03A15C36CA58355E6EE2170ACDFBB13CF60BA34BD92FFDC091D9AC86141CAC874E1615508A2B1A1B4A31E81B2E1982AA3ED676B3DFBD0962400B188F56C6DFCDE7CDDBCEA57654D61272C585EDBBE0449D1AF74C537F8A022BADDCFC2E6F3050B586A6761CFD444DF39CC585715A0CC863B9B225499B3097CE62B7645485754A1A8B3010FCEF13EA07D29161D1F3E701B5BC3D99B1EF2F8916F862B4815BC0D0A3385B33FEDF1B7FBC85F615E051B8A31F32A6B4213754A5F8E4BBFCE77A292BCF482B7FC30E817A591170E72696359B3635CB393BEF4075DDD7D0734E358DB2A803EE621CBB04010EAC75F810D72C41A3D7013EE2799A59D7A8ADAB73E0FD5EE4A6498CA8DF000AC152C0F6CA1C57660D0DD750A6A5F788F89CC424FD19FBD42E9C7E2A949FBF43FC67528AFD879A37A0D1D38E05328C5216BA938C058A341AAEA8D8EACBA42610B0E7823E74CAB6CA791F17AECB532DA5BF80C056B67BDFDED51A97C95AFCD32509C87600A2D734F23944552727CF726068C04F339D206BAF472A0C2E2F22D7CF939B7A6FB3D5C67B0564537A33E6802DBD07AEE817BAD37B5287BA678E962EB3B8B5BEFAC937241725A1B8789C1609706B24C7266FAE9195B9536151FE3D65684AACF304BC664F4D825DF67F7 -20240326051332 2 6 100 4095 2 F52D556E0D75D910A1C4DF0D571DBCEBCAB3513CA78923277BA6240C1BB579A73E56739548C0F6882B5C8BF03A15C36CA58355E6EE2170ACDFBB13CF60BA34BD92FFDC091D9AC86141CAC874E1615508A2B1A1B4A31E81B2E1982AA3ED676B3DFBD0962400B188F56C6DFCDE7CDDBCEA57654D61272C585EDBBE0449D1AF74C537F8A022BADDCFC2E6F3050B586A6761CFD444DF39CC585715A0CC863B9B225499B3097CE62B7645485754A1A8B3010FCEF13EA07D29161D1F3E701B5BC3D99B1EF2F8916F862B4815BC0D0A3385B33FEDF1B7FBC85F615E051B8A31F32A6B4213754A5F8E4BBFCE77A292BCF482B7FC30E817A591170E72696359B3635CB393BEF4075DDD7D0734E358DB2A803EE621CBB04010EAC75F810D72C41A3D7013EE2799A59D7A8ADAB73E0FD5EE4A6498CA8DF000AC152C0F6CA1C57660D0DD750A6A5F788F89CC424FD19FBD42E9C7E2A949FBF43FC67528AFD879A37A0D1D38E05328C5216BA938C058A341AAEA8D8EACBA42610B0E7823E74CAB6CA791F17AECB532DA5BF80C056B67BDFDED51A97C95AFCD32509C87600A2D734F23944552727CF726068C04F339D206BAF472A0C2E2F22D7CF939B7A6FB3D5C67B0564537A33E6802DBD07AEE817BAD37B5287BA678E962EB3B8B5BEFAC937241725A1B8789C1609706B24C7266FAE9195B9536151FE3D65684AACF304BC664F4D826515C63 -20240326051747 2 6 100 4095 2 F52D556E0D75D910A1C4DF0D571DBCEBCAB3513CA78923277BA6240C1BB579A73E56739548C0F6882B5C8BF03A15C36CA58355E6EE2170ACDFBB13CF60BA34BD92FFDC091D9AC86141CAC874E1615508A2B1A1B4A31E81B2E1982AA3ED676B3DFBD0962400B188F56C6DFCDE7CDDBCEA57654D61272C585EDBBE0449D1AF74C537F8A022BADDCFC2E6F3050B586A6761CFD444DF39CC585715A0CC863B9B225499B3097CE62B7645485754A1A8B3010FCEF13EA07D29161D1F3E701B5BC3D99B1EF2F8916F862B4815BC0D0A3385B33FEDF1B7FBC85F615E051B8A31F32A6B4213754A5F8E4BBFCE77A292BCF482B7FC30E817A591170E72696359B3635CB393BEF4075DDD7D0734E358DB2A803EE621CBB04010EAC75F810D72C41A3D7013EE2799A59D7A8ADAB73E0FD5EE4A6498CA8DF000AC152C0F6CA1C57660D0DD750A6A5F788F89CC424FD19FBD42E9C7E2A949FBF43FC67528AFD879A37A0D1D38E05328C5216BA938C058A341AAEA8D8EACBA42610B0E7823E74CAB6CA791F17AECB532DA5BF80C056B67BDFDED51A97C95AFCD32509C87600A2D734F23944552727CF726068C04F339D206BAF472A0C2E2F22D7CF939B7A6FB3D5C67B0564537A33E6802DBD07AEE817BAD37B5287BA678E962EB3B8B5BEFAC937241725A1B8789C1609706B24C7266FAE9195B9536151FE3D65684AACF304BC664F4D827E42F0B -20240326051831 2 6 100 4095 2 F52D556E0D75D910A1C4DF0D571DBCEBCAB3513CA78923277BA6240C1BB579A73E56739548C0F6882B5C8BF03A15C36CA58355E6EE2170ACDFBB13CF60BA34BD92FFDC091D9AC86141CAC874E1615508A2B1A1B4A31E81B2E1982AA3ED676B3DFBD0962400B188F56C6DFCDE7CDDBCEA57654D61272C585EDBBE0449D1AF74C537F8A022BADDCFC2E6F3050B586A6761CFD444DF39CC585715A0CC863B9B225499B3097CE62B7645485754A1A8B3010FCEF13EA07D29161D1F3E701B5BC3D99B1EF2F8916F862B4815BC0D0A3385B33FEDF1B7FBC85F615E051B8A31F32A6B4213754A5F8E4BBFCE77A292BCF482B7FC30E817A591170E72696359B3635CB393BEF4075DDD7D0734E358DB2A803EE621CBB04010EAC75F810D72C41A3D7013EE2799A59D7A8ADAB73E0FD5EE4A6498CA8DF000AC152C0F6CA1C57660D0DD750A6A5F788F89CC424FD19FBD42E9C7E2A949FBF43FC67528AFD879A37A0D1D38E05328C5216BA938C058A341AAEA8D8EACBA42610B0E7823E74CAB6CA791F17AECB532DA5BF80C056B67BDFDED51A97C95AFCD32509C87600A2D734F23944552727CF726068C04F339D206BAF472A0C2E2F22D7CF939B7A6FB3D5C67B0564537A33E6802DBD07AEE817BAD37B5287BA678E962EB3B8B5BEFAC937241725A1B8789C1609706B24C7266FAE9195B9536151FE3D65684AACF304BC664F4D828243B8B -20240326051843 2 6 100 4095 2 F52D556E0D75D910A1C4DF0D571DBCEBCAB3513CA78923277BA6240C1BB579A73E56739548C0F6882B5C8BF03A15C36CA58355E6EE2170ACDFBB13CF60BA34BD92FFDC091D9AC86141CAC874E1615508A2B1A1B4A31E81B2E1982AA3ED676B3DFBD0962400B188F56C6DFCDE7CDDBCEA57654D61272C585EDBBE0449D1AF74C537F8A022BADDCFC2E6F3050B586A6761CFD444DF39CC585715A0CC863B9B225499B3097CE62B7645485754A1A8B3010FCEF13EA07D29161D1F3E701B5BC3D99B1EF2F8916F862B4815BC0D0A3385B33FEDF1B7FBC85F615E051B8A31F32A6B4213754A5F8E4BBFCE77A292BCF482B7FC30E817A591170E72696359B3635CB393BEF4075DDD7D0734E358DB2A803EE621CBB04010EAC75F810D72C41A3D7013EE2799A59D7A8ADAB73E0FD5EE4A6498CA8DF000AC152C0F6CA1C57660D0DD750A6A5F788F89CC424FD19FBD42E9C7E2A949FBF43FC67528AFD879A37A0D1D38E05328C5216BA938C058A341AAEA8D8EACBA42610B0E7823E74CAB6CA791F17AECB532DA5BF80C056B67BDFDED51A97C95AFCD32509C87600A2D734F23944552727CF726068C04F339D206BAF472A0C2E2F22D7CF939B7A6FB3D5C67B0564537A33E6802DBD07AEE817BAD37B5287BA678E962EB3B8B5BEFAC937241725A1B8789C1609706B24C7266FAE9195B9536151FE3D65684AACF304BC664F4D82831A223 -20240326052417 2 6 100 4095 2 F52D556E0D75D910A1C4DF0D571DBCEBCAB3513CA78923277BA6240C1BB579A73E56739548C0F6882B5C8BF03A15C36CA58355E6EE2170ACDFBB13CF60BA34BD92FFDC091D9AC86141CAC874E1615508A2B1A1B4A31E81B2E1982AA3ED676B3DFBD0962400B188F56C6DFCDE7CDDBCEA57654D61272C585EDBBE0449D1AF74C537F8A022BADDCFC2E6F3050B586A6761CFD444DF39CC585715A0CC863B9B225499B3097CE62B7645485754A1A8B3010FCEF13EA07D29161D1F3E701B5BC3D99B1EF2F8916F862B4815BC0D0A3385B33FEDF1B7FBC85F615E051B8A31F32A6B4213754A5F8E4BBFCE77A292BCF482B7FC30E817A591170E72696359B3635CB393BEF4075DDD7D0734E358DB2A803EE621CBB04010EAC75F810D72C41A3D7013EE2799A59D7A8ADAB73E0FD5EE4A6498CA8DF000AC152C0F6CA1C57660D0DD750A6A5F788F89CC424FD19FBD42E9C7E2A949FBF43FC67528AFD879A37A0D1D38E05328C5216BA938C058A341AAEA8D8EACBA42610B0E7823E74CAB6CA791F17AECB532DA5BF80C056B67BDFDED51A97C95AFCD32509C87600A2D734F23944552727CF726068C04F339D206BAF472A0C2E2F22D7CF939B7A6FB3D5C67B0564537A33E6802DBD07AEE817BAD37B5287BA678E962EB3B8B5BEFAC937241725A1B8789C1609706B24C7266FAE9195B9536151FE3D65684AACF304BC664F4D82A48CE23 -20240326052731 2 6 100 4095 2 F52D556E0D75D910A1C4DF0D571DBCEBCAB3513CA78923277BA6240C1BB579A73E56739548C0F6882B5C8BF03A15C36CA58355E6EE2170ACDFBB13CF60BA34BD92FFDC091D9AC86141CAC874E1615508A2B1A1B4A31E81B2E1982AA3ED676B3DFBD0962400B188F56C6DFCDE7CDDBCEA57654D61272C585EDBBE0449D1AF74C537F8A022BADDCFC2E6F3050B586A6761CFD444DF39CC585715A0CC863B9B225499B3097CE62B7645485754A1A8B3010FCEF13EA07D29161D1F3E701B5BC3D99B1EF2F8916F862B4815BC0D0A3385B33FEDF1B7FBC85F615E051B8A31F32A6B4213754A5F8E4BBFCE77A292BCF482B7FC30E817A591170E72696359B3635CB393BEF4075DDD7D0734E358DB2A803EE621CBB04010EAC75F810D72C41A3D7013EE2799A59D7A8ADAB73E0FD5EE4A6498CA8DF000AC152C0F6CA1C57660D0DD750A6A5F788F89CC424FD19FBD42E9C7E2A949FBF43FC67528AFD879A37A0D1D38E05328C5216BA938C058A341AAEA8D8EACBA42610B0E7823E74CAB6CA791F17AECB532DA5BF80C056B67BDFDED51A97C95AFCD32509C87600A2D734F23944552727CF726068C04F339D206BAF472A0C2E2F22D7CF939B7A6FB3D5C67B0564537A33E6802DBD07AEE817BAD37B5287BA678E962EB3B8B5BEFAC937241725A1B8789C1609706B24C7266FAE9195B9536151FE3D65684AACF304BC664F4D82B78A8F3 -20240326052959 2 6 100 4095 2 F52D556E0D75D910A1C4DF0D571DBCEBCAB3513CA78923277BA6240C1BB579A73E56739548C0F6882B5C8BF03A15C36CA58355E6EE2170ACDFBB13CF60BA34BD92FFDC091D9AC86141CAC874E1615508A2B1A1B4A31E81B2E1982AA3ED676B3DFBD0962400B188F56C6DFCDE7CDDBCEA57654D61272C585EDBBE0449D1AF74C537F8A022BADDCFC2E6F3050B586A6761CFD444DF39CC585715A0CC863B9B225499B3097CE62B7645485754A1A8B3010FCEF13EA07D29161D1F3E701B5BC3D99B1EF2F8916F862B4815BC0D0A3385B33FEDF1B7FBC85F615E051B8A31F32A6B4213754A5F8E4BBFCE77A292BCF482B7FC30E817A591170E72696359B3635CB393BEF4075DDD7D0734E358DB2A803EE621CBB04010EAC75F810D72C41A3D7013EE2799A59D7A8ADAB73E0FD5EE4A6498CA8DF000AC152C0F6CA1C57660D0DD750A6A5F788F89CC424FD19FBD42E9C7E2A949FBF43FC67528AFD879A37A0D1D38E05328C5216BA938C058A341AAEA8D8EACBA42610B0E7823E74CAB6CA791F17AECB532DA5BF80C056B67BDFDED51A97C95AFCD32509C87600A2D734F23944552727CF726068C04F339D206BAF472A0C2E2F22D7CF939B7A6FB3D5C67B0564537A33E6802DBD07AEE817BAD37B5287BA678E962EB3B8B5BEFAC937241725A1B8789C1609706B24C7266FAE9195B9536151FE3D65684AACF304BC664F4D82C5D399B -20240326053126 2 6 100 4095 2 F52D556E0D75D910A1C4DF0D571DBCEBCAB3513CA78923277BA6240C1BB579A73E56739548C0F6882B5C8BF03A15C36CA58355E6EE2170ACDFBB13CF60BA34BD92FFDC091D9AC86141CAC874E1615508A2B1A1B4A31E81B2E1982AA3ED676B3DFBD0962400B188F56C6DFCDE7CDDBCEA57654D61272C585EDBBE0449D1AF74C537F8A022BADDCFC2E6F3050B586A6761CFD444DF39CC585715A0CC863B9B225499B3097CE62B7645485754A1A8B3010FCEF13EA07D29161D1F3E701B5BC3D99B1EF2F8916F862B4815BC0D0A3385B33FEDF1B7FBC85F615E051B8A31F32A6B4213754A5F8E4BBFCE77A292BCF482B7FC30E817A591170E72696359B3635CB393BEF4075DDD7D0734E358DB2A803EE621CBB04010EAC75F810D72C41A3D7013EE2799A59D7A8ADAB73E0FD5EE4A6498CA8DF000AC152C0F6CA1C57660D0DD750A6A5F788F89CC424FD19FBD42E9C7E2A949FBF43FC67528AFD879A37A0D1D38E05328C5216BA938C058A341AAEA8D8EACBA42610B0E7823E74CAB6CA791F17AECB532DA5BF80C056B67BDFDED51A97C95AFCD32509C87600A2D734F23944552727CF726068C04F339D206BAF472A0C2E2F22D7CF939B7A6FB3D5C67B0564537A33E6802DBD07AEE817BAD37B5287BA678E962EB3B8B5BEFAC937241725A1B8789C1609706B24C7266FAE9195B9536151FE3D65684AACF304BC664F4D82CE5BB4B -20240326060038 2 6 100 6143 5 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A3C767FD7 -20240326060444 2 6 100 6143 2 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A3CF77C3B -20240326070240 2 6 100 6143 2 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A4448EF33 -20240326073131 2 6 100 6143 2 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A47DAE05B -20240326073415 2 6 100 6143 5 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A482BBA27 -20240326080953 2 6 100 6143 5 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A4CB6AE7F -20240326081127 2 6 100 6143 2 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A4CDF5A0B -20240326093032 2 6 100 6143 2 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A56B6523B -20240326093454 2 6 100 6143 2 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A573897EB -20240326093728 2 6 100 6143 2 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A57820693 -20240326094259 2 6 100 6143 5 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A5829EAF7 -20240326094948 2 6 100 6143 5 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A58FD0FEF -20240326101231 2 6 100 6143 2 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A5BDEBEE3 -20240326101412 2 6 100 6143 2 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A5C09FFB3 -20240326102704 2 6 100 6143 5 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A5DAD12BF -20240326103806 2 6 100 6143 5 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A5F05465F -20240326105506 2 6 100 6143 2 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A611EE2E3 -20240326112146 2 6 100 6143 2 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A647870E3 -20240326114154 2 6 100 6143 2 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A6707EC03 -20240326114315 2 6 100 6143 2 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A6729353B -20240326122735 2 6 100 6143 2 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A6CC0FBB3 -20240326123728 2 6 100 6143 5 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A6DF24D2F -20240326130541 2 6 100 6143 2 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A71768773 -20240326130743 2 6 100 6143 2 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A71AF6A1B -20240326132826 2 6 100 6143 2 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A743654E3 -20240326134513 2 6 100 6143 2 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A76478D13 -20240326134939 2 6 100 6143 5 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A76C9E817 -20240326135416 2 6 100 6143 5 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A7755E8B7 -20240326143409 2 6 100 6143 5 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A7C397F2F -20240326144117 2 6 100 6143 2 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A7D13AF93 -20240326150017 2 6 100 6143 5 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A7F704F7F -20240326150157 2 6 100 6143 5 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A7F9F468F -20240326150526 2 6 100 6143 2 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A8005826B -20240326150739 2 6 100 6143 5 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A8045FDAF -20240326151012 2 6 100 6143 5 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A808FF207 -20240326151536 2 6 100 6143 2 E0848AB4E94DE11B8BFF81622A26C6D2145529210F586E2C145E8E26243AD47D8FB09EC8A70E1DBC3C1360EB1E511BB8657803B33D9CBAEA50236234CFD5354B08A7F9ADAEE929E263FFDB2572D56BE935DB62E8BC56ABB4594F5C0E9944B002E3A1E4DB42DEFBFEFCFB6DC014B5E20B319AC14C08FF4881E1648B39853C2D02C12EC355531BD61DCB6DE2EF99EBE4960810D43EA00A4F4CDD1E6A4F6B8037A737A306443E0E7F5B121101114FB3859ADC3C1A162DC937E6789B130DCCE01BF013CB3E79FAE8A4F6D1BA8EC5D2014D5E807DC5B1837AA025AE5A1A104C3FBC676C595DB6D27EF9F417F29C7CE3C48D2CAF46B9B79B2DD203E51E15A455B44D7EE85467BA02F922CB10CEA99C61589041CDA67D8F48A80FEC7B68CBBEEBD9DB6A82B377FFDADD912FCFD17AF6A08563F6CE7EF94153C9666CEC4D4210801E9BE697B3EDAC935E13A7D490DA08EC4F86CB2DC4497B0B4F031366918CD0ADD7B28E3E29C258CC3550EDFF59D8BCE4699296A0625AF61BA1DD74107CAD7D7EED70F3CCA27FE27E1A56C7AFEC8F92FB33BA5B322978D941FC4B39D22B1D952D975C4B1478E09F4ED4E98C054B80AD8AA5E02B5F0F84711E1464587FCF94D06CF716BA68141C3EADD9B501FA73B9DC49C19E95CCFF50613417CF6C95824E9C108B094C9AADC3E2CD6D2FEACEE698800ECF9411EAB20CD2A308B6983B25F3741D5EB12E7C9D46505CB2B0AA00FBFCFDEEF158FB28B4A93BEAB3EB4079EA6C6F9AA618A5E80560EF8966FC202ADB571DC143082E3E444149DFB3B3DD7B325440563A67147F351BF8B4C480D2635B2C78EA102E42B894489A366FFC764B502F3D48EFA342E7F0D13B15EEE257BE326265740BA62CA2DC2E6E49CEF1B11EF903CC0E756E92BCF404997D56631C817F44FCD826C6C0140EF990DF1FAA8A0A288DF2DDE4D67214C9B27F6D97A89D2067D59D1FCE0B65A27EAE0E6F065F01F0B06CF951E5D62460947DADAFF0B339CBDE45D8E6BACF1FA59676D9F65FC202FB640F3CCE10C2A5F4923F73AB1F9BEBF68906F4F36F469C7996739440380E4D5F63FF3A81343BEB -20240326162321 2 6 100 6143 5 F133729818EAD55DC3D8CA6C2754D6A78304D3CE96232D084B090E615BEAB6C63EC4B94BB1E33816ABCAFA3A08568FAD186C8873FDB17D7F9A28555871790CDA450A6EE13E97123F9A0589A77927047CE8B41B24F5505D19A3C4C18E132AFE9671423749DE1E110FB172AA66A15E405BD5CF56BE3CC6A22B13C3E03E42CA5BC3D8DA5B228C9569D7C15A2AE749A0F884A558687C2B656D94C167B47D9E3DD0691744E0D48858D0A1991FFEAAFE7E00C6284DC1E31CE3CED715F6686408BAEED6597453030DC62D033EF5A10B72D5367F7F1558F632CA86797FEBC16BF862D5CA0966122A584259FA0277B166F64F91959CC1F21E66BF0F6FD4489A00E0FC2E5C443A7AF646F32A772414D29F7A8116264C089E7D8A436870F0BB98EB134383464E2583DC569C9FC7D779D8C51A6D8BFA498FF8CF0F3CCDB631D794F1330E4E27A922BF0B0CADD66C11C885977B0AD344910D930E9D22F800FBB5A3712A5581C13D0378F82B2481969FC22C6A82E522A271C5FCA7079EEB7718D67BAC06F6A83B094B4FCD95BA2BCDC50EB547C79AAD9392DB976298511E0C270411CB37E3C1228ED8B018B15D3E2B334756DBF219624F2A2C6226FBF2EA33B9AAEC961E6BD3D7B6C9625ECF7E649D5EC21792E0A3E75E998FF6464961E74DAFB9CF95CF1CD654E4906FB725B381A325BE2D967B756072194EBAF8A2A524660EFA430957F30BE266C1105474A41964A5F7D5C9782FA193221BA23D9150CB5A08A3E231C62088D42FAA95777ADCE5D63ACB49299FBB1B29448A63B683B5799EE8DEE56B56748B7F269B43C35200716D74B5010388CF17B082AB285AC0DC827AAFF482EEC13268514B4F45AF6E0F948D3F466CE07C38A1308ED781B89837EB7332748A1BDD7E75CC904C763D44B0BA7A404046F1422B29DEC63EE2A524A123B8F971A181E8169601EBF10AABB5B71649E00E3D4600E23D2C20096CE2DB122C82F15A85238AA2337B559E7E8D0A824929956AA2394746B03E36A401565C2048D3DBF0411A8D4BB1044A9904290D264256B9085DA6001E5C208A2FB2760E94B958B4B2D5AD9F98F93F -20240326163529 2 6 100 6143 2 F133729818EAD55DC3D8CA6C2754D6A78304D3CE96232D084B090E615BEAB6C63EC4B94BB1E33816ABCAFA3A08568FAD186C8873FDB17D7F9A28555871790CDA450A6EE13E97123F9A0589A77927047CE8B41B24F5505D19A3C4C18E132AFE9671423749DE1E110FB172AA66A15E405BD5CF56BE3CC6A22B13C3E03E42CA5BC3D8DA5B228C9569D7C15A2AE749A0F884A558687C2B656D94C167B47D9E3DD0691744E0D48858D0A1991FFEAAFE7E00C6284DC1E31CE3CED715F6686408BAEED6597453030DC62D033EF5A10B72D5367F7F1558F632CA86797FEBC16BF862D5CA0966122A584259FA0277B166F64F91959CC1F21E66BF0F6FD4489A00E0FC2E5C443A7AF646F32A772414D29F7A8116264C089E7D8A436870F0BB98EB134383464E2583DC569C9FC7D779D8C51A6D8BFA498FF8CF0F3CCDB631D794F1330E4E27A922BF0B0CADD66C11C885977B0AD344910D930E9D22F800FBB5A3712A5581C13D0378F82B2481969FC22C6A82E522A271C5FCA7079EEB7718D67BAC06F6A83B094B4FCD95BA2BCDC50EB547C79AAD9392DB976298511E0C270411CB37E3C1228ED8B018B15D3E2B334756DBF219624F2A2C6226FBF2EA33B9AAEC961E6BD3D7B6C9625ECF7E649D5EC21792E0A3E75E998FF6464961E74DAFB9CF95CF1CD654E4906FB725B381A325BE2D967B756072194EBAF8A2A524660EFA430957F30BE266C1105474A41964A5F7D5C9782FA193221BA23D9150CB5A08A3E231C62088D42FAA95777ADCE5D63ACB49299FBB1B29448A63B683B5799EE8DEE56B56748B7F269B43C35200716D74B5010388CF17B082AB285AC0DC827AAFF482EEC13268514B4F45AF6E0F948D3F466CE07C38A1308ED781B89837EB7332748A1BDD7E75CC904C763D44B0BA7A404046F1422B29DEC63EE2A524A123B8F971A181E8169601EBF10AABB5B71649E00E3D4600E23D2C20096CE2DB122C82F15A85238AA2337B559E7E8D0A824929956AA2394746B03E36A401565C2048D3DBF0411A8D4BB1044A9904290D264256B9085DA6001E5C208A2FB2760E94B958B4B2D5ADA11D7CC3 -20240326163654 2 6 100 6143 2 F133729818EAD55DC3D8CA6C2754D6A78304D3CE96232D084B090E615BEAB6C63EC4B94BB1E33816ABCAFA3A08568FAD186C8873FDB17D7F9A28555871790CDA450A6EE13E97123F9A0589A77927047CE8B41B24F5505D19A3C4C18E132AFE9671423749DE1E110FB172AA66A15E405BD5CF56BE3CC6A22B13C3E03E42CA5BC3D8DA5B228C9569D7C15A2AE749A0F884A558687C2B656D94C167B47D9E3DD0691744E0D48858D0A1991FFEAAFE7E00C6284DC1E31CE3CED715F6686408BAEED6597453030DC62D033EF5A10B72D5367F7F1558F632CA86797FEBC16BF862D5CA0966122A584259FA0277B166F64F91959CC1F21E66BF0F6FD4489A00E0FC2E5C443A7AF646F32A772414D29F7A8116264C089E7D8A436870F0BB98EB134383464E2583DC569C9FC7D779D8C51A6D8BFA498FF8CF0F3CCDB631D794F1330E4E27A922BF0B0CADD66C11C885977B0AD344910D930E9D22F800FBB5A3712A5581C13D0378F82B2481969FC22C6A82E522A271C5FCA7079EEB7718D67BAC06F6A83B094B4FCD95BA2BCDC50EB547C79AAD9392DB976298511E0C270411CB37E3C1228ED8B018B15D3E2B334756DBF219624F2A2C6226FBF2EA33B9AAEC961E6BD3D7B6C9625ECF7E649D5EC21792E0A3E75E998FF6464961E74DAFB9CF95CF1CD654E4906FB725B381A325BE2D967B756072194EBAF8A2A524660EFA430957F30BE266C1105474A41964A5F7D5C9782FA193221BA23D9150CB5A08A3E231C62088D42FAA95777ADCE5D63ACB49299FBB1B29448A63B683B5799EE8DEE56B56748B7F269B43C35200716D74B5010388CF17B082AB285AC0DC827AAFF482EEC13268514B4F45AF6E0F948D3F466CE07C38A1308ED781B89837EB7332748A1BDD7E75CC904C763D44B0BA7A404046F1422B29DEC63EE2A524A123B8F971A181E8169601EBF10AABB5B71649E00E3D4600E23D2C20096CE2DB122C82F15A85238AA2337B559E7E8D0A824929956AA2394746B03E36A401565C2048D3DBF0411A8D4BB1044A9904290D264256B9085DA6001E5C208A2FB2760E94B958B4B2D5ADA142310B -20240326165530 2 6 100 6143 2 F133729818EAD55DC3D8CA6C2754D6A78304D3CE96232D084B090E615BEAB6C63EC4B94BB1E33816ABCAFA3A08568FAD186C8873FDB17D7F9A28555871790CDA450A6EE13E97123F9A0589A77927047CE8B41B24F5505D19A3C4C18E132AFE9671423749DE1E110FB172AA66A15E405BD5CF56BE3CC6A22B13C3E03E42CA5BC3D8DA5B228C9569D7C15A2AE749A0F884A558687C2B656D94C167B47D9E3DD0691744E0D48858D0A1991FFEAAFE7E00C6284DC1E31CE3CED715F6686408BAEED6597453030DC62D033EF5A10B72D5367F7F1558F632CA86797FEBC16BF862D5CA0966122A584259FA0277B166F64F91959CC1F21E66BF0F6FD4489A00E0FC2E5C443A7AF646F32A772414D29F7A8116264C089E7D8A436870F0BB98EB134383464E2583DC569C9FC7D779D8C51A6D8BFA498FF8CF0F3CCDB631D794F1330E4E27A922BF0B0CADD66C11C885977B0AD344910D930E9D22F800FBB5A3712A5581C13D0378F82B2481969FC22C6A82E522A271C5FCA7079EEB7718D67BAC06F6A83B094B4FCD95BA2BCDC50EB547C79AAD9392DB976298511E0C270411CB37E3C1228ED8B018B15D3E2B334756DBF219624F2A2C6226FBF2EA33B9AAEC961E6BD3D7B6C9625ECF7E649D5EC21792E0A3E75E998FF6464961E74DAFB9CF95CF1CD654E4906FB725B381A325BE2D967B756072194EBAF8A2A524660EFA430957F30BE266C1105474A41964A5F7D5C9782FA193221BA23D9150CB5A08A3E231C62088D42FAA95777ADCE5D63ACB49299FBB1B29448A63B683B5799EE8DEE56B56748B7F269B43C35200716D74B5010388CF17B082AB285AC0DC827AAFF482EEC13268514B4F45AF6E0F948D3F466CE07C38A1308ED781B89837EB7332748A1BDD7E75CC904C763D44B0BA7A404046F1422B29DEC63EE2A524A123B8F971A181E8169601EBF10AABB5B71649E00E3D4600E23D2C20096CE2DB122C82F15A85238AA2337B559E7E8D0A824929956AA2394746B03E36A401565C2048D3DBF0411A8D4BB1044A9904290D264256B9085DA6001E5C208A2FB2760E94B958B4B2D5ADA394A593 -20240326171340 2 6 100 6143 2 F133729818EAD55DC3D8CA6C2754D6A78304D3CE96232D084B090E615BEAB6C63EC4B94BB1E33816ABCAFA3A08568FAD186C8873FDB17D7F9A28555871790CDA450A6EE13E97123F9A0589A77927047CE8B41B24F5505D19A3C4C18E132AFE9671423749DE1E110FB172AA66A15E405BD5CF56BE3CC6A22B13C3E03E42CA5BC3D8DA5B228C9569D7C15A2AE749A0F884A558687C2B656D94C167B47D9E3DD0691744E0D48858D0A1991FFEAAFE7E00C6284DC1E31CE3CED715F6686408BAEED6597453030DC62D033EF5A10B72D5367F7F1558F632CA86797FEBC16BF862D5CA0966122A584259FA0277B166F64F91959CC1F21E66BF0F6FD4489A00E0FC2E5C443A7AF646F32A772414D29F7A8116264C089E7D8A436870F0BB98EB134383464E2583DC569C9FC7D779D8C51A6D8BFA498FF8CF0F3CCDB631D794F1330E4E27A922BF0B0CADD66C11C885977B0AD344910D930E9D22F800FBB5A3712A5581C13D0378F82B2481969FC22C6A82E522A271C5FCA7079EEB7718D67BAC06F6A83B094B4FCD95BA2BCDC50EB547C79AAD9392DB976298511E0C270411CB37E3C1228ED8B018B15D3E2B334756DBF219624F2A2C6226FBF2EA33B9AAEC961E6BD3D7B6C9625ECF7E649D5EC21792E0A3E75E998FF6464961E74DAFB9CF95CF1CD654E4906FB725B381A325BE2D967B756072194EBAF8A2A524660EFA430957F30BE266C1105474A41964A5F7D5C9782FA193221BA23D9150CB5A08A3E231C62088D42FAA95777ADCE5D63ACB49299FBB1B29448A63B683B5799EE8DEE56B56748B7F269B43C35200716D74B5010388CF17B082AB285AC0DC827AAFF482EEC13268514B4F45AF6E0F948D3F466CE07C38A1308ED781B89837EB7332748A1BDD7E75CC904C763D44B0BA7A404046F1422B29DEC63EE2A524A123B8F971A181E8169601EBF10AABB5B71649E00E3D4600E23D2C20096CE2DB122C82F15A85238AA2337B559E7E8D0A824929956AA2394746B03E36A401565C2048D3DBF0411A8D4BB1044A9904290D264256B9085DA6001E5C208A2FB2760E94B958B4B2D5ADA5C7FE3B -20240326175630 2 6 100 6143 2 F133729818EAD55DC3D8CA6C2754D6A78304D3CE96232D084B090E615BEAB6C63EC4B94BB1E33816ABCAFA3A08568FAD186C8873FDB17D7F9A28555871790CDA450A6EE13E97123F9A0589A77927047CE8B41B24F5505D19A3C4C18E132AFE9671423749DE1E110FB172AA66A15E405BD5CF56BE3CC6A22B13C3E03E42CA5BC3D8DA5B228C9569D7C15A2AE749A0F884A558687C2B656D94C167B47D9E3DD0691744E0D48858D0A1991FFEAAFE7E00C6284DC1E31CE3CED715F6686408BAEED6597453030DC62D033EF5A10B72D5367F7F1558F632CA86797FEBC16BF862D5CA0966122A584259FA0277B166F64F91959CC1F21E66BF0F6FD4489A00E0FC2E5C443A7AF646F32A772414D29F7A8116264C089E7D8A436870F0BB98EB134383464E2583DC569C9FC7D779D8C51A6D8BFA498FF8CF0F3CCDB631D794F1330E4E27A922BF0B0CADD66C11C885977B0AD344910D930E9D22F800FBB5A3712A5581C13D0378F82B2481969FC22C6A82E522A271C5FCA7079EEB7718D67BAC06F6A83B094B4FCD95BA2BCDC50EB547C79AAD9392DB976298511E0C270411CB37E3C1228ED8B018B15D3E2B334756DBF219624F2A2C6226FBF2EA33B9AAEC961E6BD3D7B6C9625ECF7E649D5EC21792E0A3E75E998FF6464961E74DAFB9CF95CF1CD654E4906FB725B381A325BE2D967B756072194EBAF8A2A524660EFA430957F30BE266C1105474A41964A5F7D5C9782FA193221BA23D9150CB5A08A3E231C62088D42FAA95777ADCE5D63ACB49299FBB1B29448A63B683B5799EE8DEE56B56748B7F269B43C35200716D74B5010388CF17B082AB285AC0DC827AAFF482EEC13268514B4F45AF6E0F948D3F466CE07C38A1308ED781B89837EB7332748A1BDD7E75CC904C763D44B0BA7A404046F1422B29DEC63EE2A524A123B8F971A181E8169601EBF10AABB5B71649E00E3D4600E23D2C20096CE2DB122C82F15A85238AA2337B559E7E8D0A824929956AA2394746B03E36A401565C2048D3DBF0411A8D4BB1044A9904290D264256B9085DA6001E5C208A2FB2760E94B958B4B2D5ADAB35A653 -20240326175808 2 6 100 6143 5 F133729818EAD55DC3D8CA6C2754D6A78304D3CE96232D084B090E615BEAB6C63EC4B94BB1E33816ABCAFA3A08568FAD186C8873FDB17D7F9A28555871790CDA450A6EE13E97123F9A0589A77927047CE8B41B24F5505D19A3C4C18E132AFE9671423749DE1E110FB172AA66A15E405BD5CF56BE3CC6A22B13C3E03E42CA5BC3D8DA5B228C9569D7C15A2AE749A0F884A558687C2B656D94C167B47D9E3DD0691744E0D48858D0A1991FFEAAFE7E00C6284DC1E31CE3CED715F6686408BAEED6597453030DC62D033EF5A10B72D5367F7F1558F632CA86797FEBC16BF862D5CA0966122A584259FA0277B166F64F91959CC1F21E66BF0F6FD4489A00E0FC2E5C443A7AF646F32A772414D29F7A8116264C089E7D8A436870F0BB98EB134383464E2583DC569C9FC7D779D8C51A6D8BFA498FF8CF0F3CCDB631D794F1330E4E27A922BF0B0CADD66C11C885977B0AD344910D930E9D22F800FBB5A3712A5581C13D0378F82B2481969FC22C6A82E522A271C5FCA7079EEB7718D67BAC06F6A83B094B4FCD95BA2BCDC50EB547C79AAD9392DB976298511E0C270411CB37E3C1228ED8B018B15D3E2B334756DBF219624F2A2C6226FBF2EA33B9AAEC961E6BD3D7B6C9625ECF7E649D5EC21792E0A3E75E998FF6464961E74DAFB9CF95CF1CD654E4906FB725B381A325BE2D967B756072194EBAF8A2A524660EFA430957F30BE266C1105474A41964A5F7D5C9782FA193221BA23D9150CB5A08A3E231C62088D42FAA95777ADCE5D63ACB49299FBB1B29448A63B683B5799EE8DEE56B56748B7F269B43C35200716D74B5010388CF17B082AB285AC0DC827AAFF482EEC13268514B4F45AF6E0F948D3F466CE07C38A1308ED781B89837EB7332748A1BDD7E75CC904C763D44B0BA7A404046F1422B29DEC63EE2A524A123B8F971A181E8169601EBF10AABB5B71649E00E3D4600E23D2C20096CE2DB122C82F15A85238AA2337B559E7E8D0A824929956AA2394746B03E36A401565C2048D3DBF0411A8D4BB1044A9904290D264256B9085DA6001E5C208A2FB2760E94B958B4B2D5ADAB62C48F -20240326184011 2 6 100 6143 5 F133729818EAD55DC3D8CA6C2754D6A78304D3CE96232D084B090E615BEAB6C63EC4B94BB1E33816ABCAFA3A08568FAD186C8873FDB17D7F9A28555871790CDA450A6EE13E97123F9A0589A77927047CE8B41B24F5505D19A3C4C18E132AFE9671423749DE1E110FB172AA66A15E405BD5CF56BE3CC6A22B13C3E03E42CA5BC3D8DA5B228C9569D7C15A2AE749A0F884A558687C2B656D94C167B47D9E3DD0691744E0D48858D0A1991FFEAAFE7E00C6284DC1E31CE3CED715F6686408BAEED6597453030DC62D033EF5A10B72D5367F7F1558F632CA86797FEBC16BF862D5CA0966122A584259FA0277B166F64F91959CC1F21E66BF0F6FD4489A00E0FC2E5C443A7AF646F32A772414D29F7A8116264C089E7D8A436870F0BB98EB134383464E2583DC569C9FC7D779D8C51A6D8BFA498FF8CF0F3CCDB631D794F1330E4E27A922BF0B0CADD66C11C885977B0AD344910D930E9D22F800FBB5A3712A5581C13D0378F82B2481969FC22C6A82E522A271C5FCA7079EEB7718D67BAC06F6A83B094B4FCD95BA2BCDC50EB547C79AAD9392DB976298511E0C270411CB37E3C1228ED8B018B15D3E2B334756DBF219624F2A2C6226FBF2EA33B9AAEC961E6BD3D7B6C9625ECF7E649D5EC21792E0A3E75E998FF6464961E74DAFB9CF95CF1CD654E4906FB725B381A325BE2D967B756072194EBAF8A2A524660EFA430957F30BE266C1105474A41964A5F7D5C9782FA193221BA23D9150CB5A08A3E231C62088D42FAA95777ADCE5D63ACB49299FBB1B29448A63B683B5799EE8DEE56B56748B7F269B43C35200716D74B5010388CF17B082AB285AC0DC827AAFF482EEC13268514B4F45AF6E0F948D3F466CE07C38A1308ED781B89837EB7332748A1BDD7E75CC904C763D44B0BA7A404046F1422B29DEC63EE2A524A123B8F971A181E8169601EBF10AABB5B71649E00E3D4600E23D2C20096CE2DB122C82F15A85238AA2337B559E7E8D0A824929956AA2394746B03E36A401565C2048D3DBF0411A8D4BB1044A9904290D264256B9085DA6001E5C208A2FB2760E94B958B4B2D5ADB0B50FD7 -20240326184335 2 6 100 6143 5 F133729818EAD55DC3D8CA6C2754D6A78304D3CE96232D084B090E615BEAB6C63EC4B94BB1E33816ABCAFA3A08568FAD186C8873FDB17D7F9A28555871790CDA450A6EE13E97123F9A0589A77927047CE8B41B24F5505D19A3C4C18E132AFE9671423749DE1E110FB172AA66A15E405BD5CF56BE3CC6A22B13C3E03E42CA5BC3D8DA5B228C9569D7C15A2AE749A0F884A558687C2B656D94C167B47D9E3DD0691744E0D48858D0A1991FFEAAFE7E00C6284DC1E31CE3CED715F6686408BAEED6597453030DC62D033EF5A10B72D5367F7F1558F632CA86797FEBC16BF862D5CA0966122A584259FA0277B166F64F91959CC1F21E66BF0F6FD4489A00E0FC2E5C443A7AF646F32A772414D29F7A8116264C089E7D8A436870F0BB98EB134383464E2583DC569C9FC7D779D8C51A6D8BFA498FF8CF0F3CCDB631D794F1330E4E27A922BF0B0CADD66C11C885977B0AD344910D930E9D22F800FBB5A3712A5581C13D0378F82B2481969FC22C6A82E522A271C5FCA7079EEB7718D67BAC06F6A83B094B4FCD95BA2BCDC50EB547C79AAD9392DB976298511E0C270411CB37E3C1228ED8B018B15D3E2B334756DBF219624F2A2C6226FBF2EA33B9AAEC961E6BD3D7B6C9625ECF7E649D5EC21792E0A3E75E998FF6464961E74DAFB9CF95CF1CD654E4906FB725B381A325BE2D967B756072194EBAF8A2A524660EFA430957F30BE266C1105474A41964A5F7D5C9782FA193221BA23D9150CB5A08A3E231C62088D42FAA95777ADCE5D63ACB49299FBB1B29448A63B683B5799EE8DEE56B56748B7F269B43C35200716D74B5010388CF17B082AB285AC0DC827AAFF482EEC13268514B4F45AF6E0F948D3F466CE07C38A1308ED781B89837EB7332748A1BDD7E75CC904C763D44B0BA7A404046F1422B29DEC63EE2A524A123B8F971A181E8169601EBF10AABB5B71649E00E3D4600E23D2C20096CE2DB122C82F15A85238AA2337B559E7E8D0A824929956AA2394746B03E36A401565C2048D3DBF0411A8D4BB1044A9904290D264256B9085DA6001E5C208A2FB2760E94B958B4B2D5ADB1203D2F -20240326185246 2 6 100 6143 5 F133729818EAD55DC3D8CA6C2754D6A78304D3CE96232D084B090E615BEAB6C63EC4B94BB1E33816ABCAFA3A08568FAD186C8873FDB17D7F9A28555871790CDA450A6EE13E97123F9A0589A77927047CE8B41B24F5505D19A3C4C18E132AFE9671423749DE1E110FB172AA66A15E405BD5CF56BE3CC6A22B13C3E03E42CA5BC3D8DA5B228C9569D7C15A2AE749A0F884A558687C2B656D94C167B47D9E3DD0691744E0D48858D0A1991FFEAAFE7E00C6284DC1E31CE3CED715F6686408BAEED6597453030DC62D033EF5A10B72D5367F7F1558F632CA86797FEBC16BF862D5CA0966122A584259FA0277B166F64F91959CC1F21E66BF0F6FD4489A00E0FC2E5C443A7AF646F32A772414D29F7A8116264C089E7D8A436870F0BB98EB134383464E2583DC569C9FC7D779D8C51A6D8BFA498FF8CF0F3CCDB631D794F1330E4E27A922BF0B0CADD66C11C885977B0AD344910D930E9D22F800FBB5A3712A5581C13D0378F82B2481969FC22C6A82E522A271C5FCA7079EEB7718D67BAC06F6A83B094B4FCD95BA2BCDC50EB547C79AAD9392DB976298511E0C270411CB37E3C1228ED8B018B15D3E2B334756DBF219624F2A2C6226FBF2EA33B9AAEC961E6BD3D7B6C9625ECF7E649D5EC21792E0A3E75E998FF6464961E74DAFB9CF95CF1CD654E4906FB725B381A325BE2D967B756072194EBAF8A2A524660EFA430957F30BE266C1105474A41964A5F7D5C9782FA193221BA23D9150CB5A08A3E231C62088D42FAA95777ADCE5D63ACB49299FBB1B29448A63B683B5799EE8DEE56B56748B7F269B43C35200716D74B5010388CF17B082AB285AC0DC827AAFF482EEC13268514B4F45AF6E0F948D3F466CE07C38A1308ED781B89837EB7332748A1BDD7E75CC904C763D44B0BA7A404046F1422B29DEC63EE2A524A123B8F971A181E8169601EBF10AABB5B71649E00E3D4600E23D2C20096CE2DB122C82F15A85238AA2337B559E7E8D0A824929956AA2394746B03E36A401565C2048D3DBF0411A8D4BB1044A9904290D264256B9085DA6001E5C208A2FB2760E94B958B4B2D5ADB2435AB7 -20240326190020 2 6 100 6143 2 F133729818EAD55DC3D8CA6C2754D6A78304D3CE96232D084B090E615BEAB6C63EC4B94BB1E33816ABCAFA3A08568FAD186C8873FDB17D7F9A28555871790CDA450A6EE13E97123F9A0589A77927047CE8B41B24F5505D19A3C4C18E132AFE9671423749DE1E110FB172AA66A15E405BD5CF56BE3CC6A22B13C3E03E42CA5BC3D8DA5B228C9569D7C15A2AE749A0F884A558687C2B656D94C167B47D9E3DD0691744E0D48858D0A1991FFEAAFE7E00C6284DC1E31CE3CED715F6686408BAEED6597453030DC62D033EF5A10B72D5367F7F1558F632CA86797FEBC16BF862D5CA0966122A584259FA0277B166F64F91959CC1F21E66BF0F6FD4489A00E0FC2E5C443A7AF646F32A772414D29F7A8116264C089E7D8A436870F0BB98EB134383464E2583DC569C9FC7D779D8C51A6D8BFA498FF8CF0F3CCDB631D794F1330E4E27A922BF0B0CADD66C11C885977B0AD344910D930E9D22F800FBB5A3712A5581C13D0378F82B2481969FC22C6A82E522A271C5FCA7079EEB7718D67BAC06F6A83B094B4FCD95BA2BCDC50EB547C79AAD9392DB976298511E0C270411CB37E3C1228ED8B018B15D3E2B334756DBF219624F2A2C6226FBF2EA33B9AAEC961E6BD3D7B6C9625ECF7E649D5EC21792E0A3E75E998FF6464961E74DAFB9CF95CF1CD654E4906FB725B381A325BE2D967B756072194EBAF8A2A524660EFA430957F30BE266C1105474A41964A5F7D5C9782FA193221BA23D9150CB5A08A3E231C62088D42FAA95777ADCE5D63ACB49299FBB1B29448A63B683B5799EE8DEE56B56748B7F269B43C35200716D74B5010388CF17B082AB285AC0DC827AAFF482EEC13268514B4F45AF6E0F948D3F466CE07C38A1308ED781B89837EB7332748A1BDD7E75CC904C763D44B0BA7A404046F1422B29DEC63EE2A524A123B8F971A181E8169601EBF10AABB5B71649E00E3D4600E23D2C20096CE2DB122C82F15A85238AA2337B559E7E8D0A824929956AA2394746B03E36A401565C2048D3DBF0411A8D4BB1044A9904290D264256B9085DA6001E5C208A2FB2760E94B958B4B2D5ADB333EDAB -20240326190122 2 6 100 6143 5 F133729818EAD55DC3D8CA6C2754D6A78304D3CE96232D084B090E615BEAB6C63EC4B94BB1E33816ABCAFA3A08568FAD186C8873FDB17D7F9A28555871790CDA450A6EE13E97123F9A0589A77927047CE8B41B24F5505D19A3C4C18E132AFE9671423749DE1E110FB172AA66A15E405BD5CF56BE3CC6A22B13C3E03E42CA5BC3D8DA5B228C9569D7C15A2AE749A0F884A558687C2B656D94C167B47D9E3DD0691744E0D48858D0A1991FFEAAFE7E00C6284DC1E31CE3CED715F6686408BAEED6597453030DC62D033EF5A10B72D5367F7F1558F632CA86797FEBC16BF862D5CA0966122A584259FA0277B166F64F91959CC1F21E66BF0F6FD4489A00E0FC2E5C443A7AF646F32A772414D29F7A8116264C089E7D8A436870F0BB98EB134383464E2583DC569C9FC7D779D8C51A6D8BFA498FF8CF0F3CCDB631D794F1330E4E27A922BF0B0CADD66C11C885977B0AD344910D930E9D22F800FBB5A3712A5581C13D0378F82B2481969FC22C6A82E522A271C5FCA7079EEB7718D67BAC06F6A83B094B4FCD95BA2BCDC50EB547C79AAD9392DB976298511E0C270411CB37E3C1228ED8B018B15D3E2B334756DBF219624F2A2C6226FBF2EA33B9AAEC961E6BD3D7B6C9625ECF7E649D5EC21792E0A3E75E998FF6464961E74DAFB9CF95CF1CD654E4906FB725B381A325BE2D967B756072194EBAF8A2A524660EFA430957F30BE266C1105474A41964A5F7D5C9782FA193221BA23D9150CB5A08A3E231C62088D42FAA95777ADCE5D63ACB49299FBB1B29448A63B683B5799EE8DEE56B56748B7F269B43C35200716D74B5010388CF17B082AB285AC0DC827AAFF482EEC13268514B4F45AF6E0F948D3F466CE07C38A1308ED781B89837EB7332748A1BDD7E75CC904C763D44B0BA7A404046F1422B29DEC63EE2A524A123B8F971A181E8169601EBF10AABB5B71649E00E3D4600E23D2C20096CE2DB122C82F15A85238AA2337B559E7E8D0A824929956AA2394746B03E36A401565C2048D3DBF0411A8D4BB1044A9904290D264256B9085DA6001E5C208A2FB2760E94B958B4B2D5ADB34BD947 -20240326191114 2 6 100 6143 5 F133729818EAD55DC3D8CA6C2754D6A78304D3CE96232D084B090E615BEAB6C63EC4B94BB1E33816ABCAFA3A08568FAD186C8873FDB17D7F9A28555871790CDA450A6EE13E97123F9A0589A77927047CE8B41B24F5505D19A3C4C18E132AFE9671423749DE1E110FB172AA66A15E405BD5CF56BE3CC6A22B13C3E03E42CA5BC3D8DA5B228C9569D7C15A2AE749A0F884A558687C2B656D94C167B47D9E3DD0691744E0D48858D0A1991FFEAAFE7E00C6284DC1E31CE3CED715F6686408BAEED6597453030DC62D033EF5A10B72D5367F7F1558F632CA86797FEBC16BF862D5CA0966122A584259FA0277B166F64F91959CC1F21E66BF0F6FD4489A00E0FC2E5C443A7AF646F32A772414D29F7A8116264C089E7D8A436870F0BB98EB134383464E2583DC569C9FC7D779D8C51A6D8BFA498FF8CF0F3CCDB631D794F1330E4E27A922BF0B0CADD66C11C885977B0AD344910D930E9D22F800FBB5A3712A5581C13D0378F82B2481969FC22C6A82E522A271C5FCA7079EEB7718D67BAC06F6A83B094B4FCD95BA2BCDC50EB547C79AAD9392DB976298511E0C270411CB37E3C1228ED8B018B15D3E2B334756DBF219624F2A2C6226FBF2EA33B9AAEC961E6BD3D7B6C9625ECF7E649D5EC21792E0A3E75E998FF6464961E74DAFB9CF95CF1CD654E4906FB725B381A325BE2D967B756072194EBAF8A2A524660EFA430957F30BE266C1105474A41964A5F7D5C9782FA193221BA23D9150CB5A08A3E231C62088D42FAA95777ADCE5D63ACB49299FBB1B29448A63B683B5799EE8DEE56B56748B7F269B43C35200716D74B5010388CF17B082AB285AC0DC827AAFF482EEC13268514B4F45AF6E0F948D3F466CE07C38A1308ED781B89837EB7332748A1BDD7E75CC904C763D44B0BA7A404046F1422B29DEC63EE2A524A123B8F971A181E8169601EBF10AABB5B71649E00E3D4600E23D2C20096CE2DB122C82F15A85238AA2337B559E7E8D0A824929956AA2394746B03E36A401565C2048D3DBF0411A8D4BB1044A9904290D264256B9085DA6001E5C208A2FB2760E94B958B4B2D5ADB482E3D7 -20240326192702 2 6 100 6143 2 F133729818EAD55DC3D8CA6C2754D6A78304D3CE96232D084B090E615BEAB6C63EC4B94BB1E33816ABCAFA3A08568FAD186C8873FDB17D7F9A28555871790CDA450A6EE13E97123F9A0589A77927047CE8B41B24F5505D19A3C4C18E132AFE9671423749DE1E110FB172AA66A15E405BD5CF56BE3CC6A22B13C3E03E42CA5BC3D8DA5B228C9569D7C15A2AE749A0F884A558687C2B656D94C167B47D9E3DD0691744E0D48858D0A1991FFEAAFE7E00C6284DC1E31CE3CED715F6686408BAEED6597453030DC62D033EF5A10B72D5367F7F1558F632CA86797FEBC16BF862D5CA0966122A584259FA0277B166F64F91959CC1F21E66BF0F6FD4489A00E0FC2E5C443A7AF646F32A772414D29F7A8116264C089E7D8A436870F0BB98EB134383464E2583DC569C9FC7D779D8C51A6D8BFA498FF8CF0F3CCDB631D794F1330E4E27A922BF0B0CADD66C11C885977B0AD344910D930E9D22F800FBB5A3712A5581C13D0378F82B2481969FC22C6A82E522A271C5FCA7079EEB7718D67BAC06F6A83B094B4FCD95BA2BCDC50EB547C79AAD9392DB976298511E0C270411CB37E3C1228ED8B018B15D3E2B334756DBF219624F2A2C6226FBF2EA33B9AAEC961E6BD3D7B6C9625ECF7E649D5EC21792E0A3E75E998FF6464961E74DAFB9CF95CF1CD654E4906FB725B381A325BE2D967B756072194EBAF8A2A524660EFA430957F30BE266C1105474A41964A5F7D5C9782FA193221BA23D9150CB5A08A3E231C62088D42FAA95777ADCE5D63ACB49299FBB1B29448A63B683B5799EE8DEE56B56748B7F269B43C35200716D74B5010388CF17B082AB285AC0DC827AAFF482EEC13268514B4F45AF6E0F948D3F466CE07C38A1308ED781B89837EB7332748A1BDD7E75CC904C763D44B0BA7A404046F1422B29DEC63EE2A524A123B8F971A181E8169601EBF10AABB5B71649E00E3D4600E23D2C20096CE2DB122C82F15A85238AA2337B559E7E8D0A824929956AA2394746B03E36A401565C2048D3DBF0411A8D4BB1044A9904290D264256B9085DA6001E5C208A2FB2760E94B958B4B2D5ADB67FBDFB -20240326195941 2 6 100 6143 2 F133729818EAD55DC3D8CA6C2754D6A78304D3CE96232D084B090E615BEAB6C63EC4B94BB1E33816ABCAFA3A08568FAD186C8873FDB17D7F9A28555871790CDA450A6EE13E97123F9A0589A77927047CE8B41B24F5505D19A3C4C18E132AFE9671423749DE1E110FB172AA66A15E405BD5CF56BE3CC6A22B13C3E03E42CA5BC3D8DA5B228C9569D7C15A2AE749A0F884A558687C2B656D94C167B47D9E3DD0691744E0D48858D0A1991FFEAAFE7E00C6284DC1E31CE3CED715F6686408BAEED6597453030DC62D033EF5A10B72D5367F7F1558F632CA86797FEBC16BF862D5CA0966122A584259FA0277B166F64F91959CC1F21E66BF0F6FD4489A00E0FC2E5C443A7AF646F32A772414D29F7A8116264C089E7D8A436870F0BB98EB134383464E2583DC569C9FC7D779D8C51A6D8BFA498FF8CF0F3CCDB631D794F1330E4E27A922BF0B0CADD66C11C885977B0AD344910D930E9D22F800FBB5A3712A5581C13D0378F82B2481969FC22C6A82E522A271C5FCA7079EEB7718D67BAC06F6A83B094B4FCD95BA2BCDC50EB547C79AAD9392DB976298511E0C270411CB37E3C1228ED8B018B15D3E2B334756DBF219624F2A2C6226FBF2EA33B9AAEC961E6BD3D7B6C9625ECF7E649D5EC21792E0A3E75E998FF6464961E74DAFB9CF95CF1CD654E4906FB725B381A325BE2D967B756072194EBAF8A2A524660EFA430957F30BE266C1105474A41964A5F7D5C9782FA193221BA23D9150CB5A08A3E231C62088D42FAA95777ADCE5D63ACB49299FBB1B29448A63B683B5799EE8DEE56B56748B7F269B43C35200716D74B5010388CF17B082AB285AC0DC827AAFF482EEC13268514B4F45AF6E0F948D3F466CE07C38A1308ED781B89837EB7332748A1BDD7E75CC904C763D44B0BA7A404046F1422B29DEC63EE2A524A123B8F971A181E8169601EBF10AABB5B71649E00E3D4600E23D2C20096CE2DB122C82F15A85238AA2337B559E7E8D0A824929956AA2394746B03E36A401565C2048D3DBF0411A8D4BB1044A9904290D264256B9085DA6001E5C208A2FB2760E94B958B4B2D5ADBAA83D13 -20240326200115 2 6 100 6143 5 F133729818EAD55DC3D8CA6C2754D6A78304D3CE96232D084B090E615BEAB6C63EC4B94BB1E33816ABCAFA3A08568FAD186C8873FDB17D7F9A28555871790CDA450A6EE13E97123F9A0589A77927047CE8B41B24F5505D19A3C4C18E132AFE9671423749DE1E110FB172AA66A15E405BD5CF56BE3CC6A22B13C3E03E42CA5BC3D8DA5B228C9569D7C15A2AE749A0F884A558687C2B656D94C167B47D9E3DD0691744E0D48858D0A1991FFEAAFE7E00C6284DC1E31CE3CED715F6686408BAEED6597453030DC62D033EF5A10B72D5367F7F1558F632CA86797FEBC16BF862D5CA0966122A584259FA0277B166F64F91959CC1F21E66BF0F6FD4489A00E0FC2E5C443A7AF646F32A772414D29F7A8116264C089E7D8A436870F0BB98EB134383464E2583DC569C9FC7D779D8C51A6D8BFA498FF8CF0F3CCDB631D794F1330E4E27A922BF0B0CADD66C11C885977B0AD344910D930E9D22F800FBB5A3712A5581C13D0378F82B2481969FC22C6A82E522A271C5FCA7079EEB7718D67BAC06F6A83B094B4FCD95BA2BCDC50EB547C79AAD9392DB976298511E0C270411CB37E3C1228ED8B018B15D3E2B334756DBF219624F2A2C6226FBF2EA33B9AAEC961E6BD3D7B6C9625ECF7E649D5EC21792E0A3E75E998FF6464961E74DAFB9CF95CF1CD654E4906FB725B381A325BE2D967B756072194EBAF8A2A524660EFA430957F30BE266C1105474A41964A5F7D5C9782FA193221BA23D9150CB5A08A3E231C62088D42FAA95777ADCE5D63ACB49299FBB1B29448A63B683B5799EE8DEE56B56748B7F269B43C35200716D74B5010388CF17B082AB285AC0DC827AAFF482EEC13268514B4F45AF6E0F948D3F466CE07C38A1308ED781B89837EB7332748A1BDD7E75CC904C763D44B0BA7A404046F1422B29DEC63EE2A524A123B8F971A181E8169601EBF10AABB5B71649E00E3D4600E23D2C20096CE2DB122C82F15A85238AA2337B559E7E8D0A824929956AA2394746B03E36A401565C2048D3DBF0411A8D4BB1044A9904290D264256B9085DA6001E5C208A2FB2760E94B958B4B2D5ADBAD40AEF -20240326201633 2 6 100 6143 5 F133729818EAD55DC3D8CA6C2754D6A78304D3CE96232D084B090E615BEAB6C63EC4B94BB1E33816ABCAFA3A08568FAD186C8873FDB17D7F9A28555871790CDA450A6EE13E97123F9A0589A77927047CE8B41B24F5505D19A3C4C18E132AFE9671423749DE1E110FB172AA66A15E405BD5CF56BE3CC6A22B13C3E03E42CA5BC3D8DA5B228C9569D7C15A2AE749A0F884A558687C2B656D94C167B47D9E3DD0691744E0D48858D0A1991FFEAAFE7E00C6284DC1E31CE3CED715F6686408BAEED6597453030DC62D033EF5A10B72D5367F7F1558F632CA86797FEBC16BF862D5CA0966122A584259FA0277B166F64F91959CC1F21E66BF0F6FD4489A00E0FC2E5C443A7AF646F32A772414D29F7A8116264C089E7D8A436870F0BB98EB134383464E2583DC569C9FC7D779D8C51A6D8BFA498FF8CF0F3CCDB631D794F1330E4E27A922BF0B0CADD66C11C885977B0AD344910D930E9D22F800FBB5A3712A5581C13D0378F82B2481969FC22C6A82E522A271C5FCA7079EEB7718D67BAC06F6A83B094B4FCD95BA2BCDC50EB547C79AAD9392DB976298511E0C270411CB37E3C1228ED8B018B15D3E2B334756DBF219624F2A2C6226FBF2EA33B9AAEC961E6BD3D7B6C9625ECF7E649D5EC21792E0A3E75E998FF6464961E74DAFB9CF95CF1CD654E4906FB725B381A325BE2D967B756072194EBAF8A2A524660EFA430957F30BE266C1105474A41964A5F7D5C9782FA193221BA23D9150CB5A08A3E231C62088D42FAA95777ADCE5D63ACB49299FBB1B29448A63B683B5799EE8DEE56B56748B7F269B43C35200716D74B5010388CF17B082AB285AC0DC827AAFF482EEC13268514B4F45AF6E0F948D3F466CE07C38A1308ED781B89837EB7332748A1BDD7E75CC904C763D44B0BA7A404046F1422B29DEC63EE2A524A123B8F971A181E8169601EBF10AABB5B71649E00E3D4600E23D2C20096CE2DB122C82F15A85238AA2337B559E7E8D0A824929956AA2394746B03E36A401565C2048D3DBF0411A8D4BB1044A9904290D264256B9085DA6001E5C208A2FB2760E94B958B4B2D5ADBCB670E7 -20240326203821 2 6 100 6143 2 F133729818EAD55DC3D8CA6C2754D6A78304D3CE96232D084B090E615BEAB6C63EC4B94BB1E33816ABCAFA3A08568FAD186C8873FDB17D7F9A28555871790CDA450A6EE13E97123F9A0589A77927047CE8B41B24F5505D19A3C4C18E132AFE9671423749DE1E110FB172AA66A15E405BD5CF56BE3CC6A22B13C3E03E42CA5BC3D8DA5B228C9569D7C15A2AE749A0F884A558687C2B656D94C167B47D9E3DD0691744E0D48858D0A1991FFEAAFE7E00C6284DC1E31CE3CED715F6686408BAEED6597453030DC62D033EF5A10B72D5367F7F1558F632CA86797FEBC16BF862D5CA0966122A584259FA0277B166F64F91959CC1F21E66BF0F6FD4489A00E0FC2E5C443A7AF646F32A772414D29F7A8116264C089E7D8A436870F0BB98EB134383464E2583DC569C9FC7D779D8C51A6D8BFA498FF8CF0F3CCDB631D794F1330E4E27A922BF0B0CADD66C11C885977B0AD344910D930E9D22F800FBB5A3712A5581C13D0378F82B2481969FC22C6A82E522A271C5FCA7079EEB7718D67BAC06F6A83B094B4FCD95BA2BCDC50EB547C79AAD9392DB976298511E0C270411CB37E3C1228ED8B018B15D3E2B334756DBF219624F2A2C6226FBF2EA33B9AAEC961E6BD3D7B6C9625ECF7E649D5EC21792E0A3E75E998FF6464961E74DAFB9CF95CF1CD654E4906FB725B381A325BE2D967B756072194EBAF8A2A524660EFA430957F30BE266C1105474A41964A5F7D5C9782FA193221BA23D9150CB5A08A3E231C62088D42FAA95777ADCE5D63ACB49299FBB1B29448A63B683B5799EE8DEE56B56748B7F269B43C35200716D74B5010388CF17B082AB285AC0DC827AAFF482EEC13268514B4F45AF6E0F948D3F466CE07C38A1308ED781B89837EB7332748A1BDD7E75CC904C763D44B0BA7A404046F1422B29DEC63EE2A524A123B8F971A181E8169601EBF10AABB5B71649E00E3D4600E23D2C20096CE2DB122C82F15A85238AA2337B559E7E8D0A824929956AA2394746B03E36A401565C2048D3DBF0411A8D4BB1044A9904290D264256B9085DA6001E5C208A2FB2760E94B958B4B2D5ADBF6DC6B3 -20240326204751 2 6 100 6143 2 F133729818EAD55DC3D8CA6C2754D6A78304D3CE96232D084B090E615BEAB6C63EC4B94BB1E33816ABCAFA3A08568FAD186C8873FDB17D7F9A28555871790CDA450A6EE13E97123F9A0589A77927047CE8B41B24F5505D19A3C4C18E132AFE9671423749DE1E110FB172AA66A15E405BD5CF56BE3CC6A22B13C3E03E42CA5BC3D8DA5B228C9569D7C15A2AE749A0F884A558687C2B656D94C167B47D9E3DD0691744E0D48858D0A1991FFEAAFE7E00C6284DC1E31CE3CED715F6686408BAEED6597453030DC62D033EF5A10B72D5367F7F1558F632CA86797FEBC16BF862D5CA0966122A584259FA0277B166F64F91959CC1F21E66BF0F6FD4489A00E0FC2E5C443A7AF646F32A772414D29F7A8116264C089E7D8A436870F0BB98EB134383464E2583DC569C9FC7D779D8C51A6D8BFA498FF8CF0F3CCDB631D794F1330E4E27A922BF0B0CADD66C11C885977B0AD344910D930E9D22F800FBB5A3712A5581C13D0378F82B2481969FC22C6A82E522A271C5FCA7079EEB7718D67BAC06F6A83B094B4FCD95BA2BCDC50EB547C79AAD9392DB976298511E0C270411CB37E3C1228ED8B018B15D3E2B334756DBF219624F2A2C6226FBF2EA33B9AAEC961E6BD3D7B6C9625ECF7E649D5EC21792E0A3E75E998FF6464961E74DAFB9CF95CF1CD654E4906FB725B381A325BE2D967B756072194EBAF8A2A524660EFA430957F30BE266C1105474A41964A5F7D5C9782FA193221BA23D9150CB5A08A3E231C62088D42FAA95777ADCE5D63ACB49299FBB1B29448A63B683B5799EE8DEE56B56748B7F269B43C35200716D74B5010388CF17B082AB285AC0DC827AAFF482EEC13268514B4F45AF6E0F948D3F466CE07C38A1308ED781B89837EB7332748A1BDD7E75CC904C763D44B0BA7A404046F1422B29DEC63EE2A524A123B8F971A181E8169601EBF10AABB5B71649E00E3D4600E23D2C20096CE2DB122C82F15A85238AA2337B559E7E8D0A824929956AA2394746B03E36A401565C2048D3DBF0411A8D4BB1044A9904290D264256B9085DA6001E5C208A2FB2760E94B958B4B2D5ADC094E45B -20240326205334 2 6 100 6143 5 F133729818EAD55DC3D8CA6C2754D6A78304D3CE96232D084B090E615BEAB6C63EC4B94BB1E33816ABCAFA3A08568FAD186C8873FDB17D7F9A28555871790CDA450A6EE13E97123F9A0589A77927047CE8B41B24F5505D19A3C4C18E132AFE9671423749DE1E110FB172AA66A15E405BD5CF56BE3CC6A22B13C3E03E42CA5BC3D8DA5B228C9569D7C15A2AE749A0F884A558687C2B656D94C167B47D9E3DD0691744E0D48858D0A1991FFEAAFE7E00C6284DC1E31CE3CED715F6686408BAEED6597453030DC62D033EF5A10B72D5367F7F1558F632CA86797FEBC16BF862D5CA0966122A584259FA0277B166F64F91959CC1F21E66BF0F6FD4489A00E0FC2E5C443A7AF646F32A772414D29F7A8116264C089E7D8A436870F0BB98EB134383464E2583DC569C9FC7D779D8C51A6D8BFA498FF8CF0F3CCDB631D794F1330E4E27A922BF0B0CADD66C11C885977B0AD344910D930E9D22F800FBB5A3712A5581C13D0378F82B2481969FC22C6A82E522A271C5FCA7079EEB7718D67BAC06F6A83B094B4FCD95BA2BCDC50EB547C79AAD9392DB976298511E0C270411CB37E3C1228ED8B018B15D3E2B334756DBF219624F2A2C6226FBF2EA33B9AAEC961E6BD3D7B6C9625ECF7E649D5EC21792E0A3E75E998FF6464961E74DAFB9CF95CF1CD654E4906FB725B381A325BE2D967B756072194EBAF8A2A524660EFA430957F30BE266C1105474A41964A5F7D5C9782FA193221BA23D9150CB5A08A3E231C62088D42FAA95777ADCE5D63ACB49299FBB1B29448A63B683B5799EE8DEE56B56748B7F269B43C35200716D74B5010388CF17B082AB285AC0DC827AAFF482EEC13268514B4F45AF6E0F948D3F466CE07C38A1308ED781B89837EB7332748A1BDD7E75CC904C763D44B0BA7A404046F1422B29DEC63EE2A524A123B8F971A181E8169601EBF10AABB5B71649E00E3D4600E23D2C20096CE2DB122C82F15A85238AA2337B559E7E8D0A824929956AA2394746B03E36A401565C2048D3DBF0411A8D4BB1044A9904290D264256B9085DA6001E5C208A2FB2760E94B958B4B2D5ADC1441637 -20240326211827 2 6 100 6143 5 F133729818EAD55DC3D8CA6C2754D6A78304D3CE96232D084B090E615BEAB6C63EC4B94BB1E33816ABCAFA3A08568FAD186C8873FDB17D7F9A28555871790CDA450A6EE13E97123F9A0589A77927047CE8B41B24F5505D19A3C4C18E132AFE9671423749DE1E110FB172AA66A15E405BD5CF56BE3CC6A22B13C3E03E42CA5BC3D8DA5B228C9569D7C15A2AE749A0F884A558687C2B656D94C167B47D9E3DD0691744E0D48858D0A1991FFEAAFE7E00C6284DC1E31CE3CED715F6686408BAEED6597453030DC62D033EF5A10B72D5367F7F1558F632CA86797FEBC16BF862D5CA0966122A584259FA0277B166F64F91959CC1F21E66BF0F6FD4489A00E0FC2E5C443A7AF646F32A772414D29F7A8116264C089E7D8A436870F0BB98EB134383464E2583DC569C9FC7D779D8C51A6D8BFA498FF8CF0F3CCDB631D794F1330E4E27A922BF0B0CADD66C11C885977B0AD344910D930E9D22F800FBB5A3712A5581C13D0378F82B2481969FC22C6A82E522A271C5FCA7079EEB7718D67BAC06F6A83B094B4FCD95BA2BCDC50EB547C79AAD9392DB976298511E0C270411CB37E3C1228ED8B018B15D3E2B334756DBF219624F2A2C6226FBF2EA33B9AAEC961E6BD3D7B6C9625ECF7E649D5EC21792E0A3E75E998FF6464961E74DAFB9CF95CF1CD654E4906FB725B381A325BE2D967B756072194EBAF8A2A524660EFA430957F30BE266C1105474A41964A5F7D5C9782FA193221BA23D9150CB5A08A3E231C62088D42FAA95777ADCE5D63ACB49299FBB1B29448A63B683B5799EE8DEE56B56748B7F269B43C35200716D74B5010388CF17B082AB285AC0DC827AAFF482EEC13268514B4F45AF6E0F948D3F466CE07C38A1308ED781B89837EB7332748A1BDD7E75CC904C763D44B0BA7A404046F1422B29DEC63EE2A524A123B8F971A181E8169601EBF10AABB5B71649E00E3D4600E23D2C20096CE2DB122C82F15A85238AA2337B559E7E8D0A824929956AA2394746B03E36A401565C2048D3DBF0411A8D4BB1044A9904290D264256B9085DA6001E5C208A2FB2760E94B958B4B2D5ADC45F0E3F -20240326212459 2 6 100 6143 2 F133729818EAD55DC3D8CA6C2754D6A78304D3CE96232D084B090E615BEAB6C63EC4B94BB1E33816ABCAFA3A08568FAD186C8873FDB17D7F9A28555871790CDA450A6EE13E97123F9A0589A77927047CE8B41B24F5505D19A3C4C18E132AFE9671423749DE1E110FB172AA66A15E405BD5CF56BE3CC6A22B13C3E03E42CA5BC3D8DA5B228C9569D7C15A2AE749A0F884A558687C2B656D94C167B47D9E3DD0691744E0D48858D0A1991FFEAAFE7E00C6284DC1E31CE3CED715F6686408BAEED6597453030DC62D033EF5A10B72D5367F7F1558F632CA86797FEBC16BF862D5CA0966122A584259FA0277B166F64F91959CC1F21E66BF0F6FD4489A00E0FC2E5C443A7AF646F32A772414D29F7A8116264C089E7D8A436870F0BB98EB134383464E2583DC569C9FC7D779D8C51A6D8BFA498FF8CF0F3CCDB631D794F1330E4E27A922BF0B0CADD66C11C885977B0AD344910D930E9D22F800FBB5A3712A5581C13D0378F82B2481969FC22C6A82E522A271C5FCA7079EEB7718D67BAC06F6A83B094B4FCD95BA2BCDC50EB547C79AAD9392DB976298511E0C270411CB37E3C1228ED8B018B15D3E2B334756DBF219624F2A2C6226FBF2EA33B9AAEC961E6BD3D7B6C9625ECF7E649D5EC21792E0A3E75E998FF6464961E74DAFB9CF95CF1CD654E4906FB725B381A325BE2D967B756072194EBAF8A2A524660EFA430957F30BE266C1105474A41964A5F7D5C9782FA193221BA23D9150CB5A08A3E231C62088D42FAA95777ADCE5D63ACB49299FBB1B29448A63B683B5799EE8DEE56B56748B7F269B43C35200716D74B5010388CF17B082AB285AC0DC827AAFF482EEC13268514B4F45AF6E0F948D3F466CE07C38A1308ED781B89837EB7332748A1BDD7E75CC904C763D44B0BA7A404046F1422B29DEC63EE2A524A123B8F971A181E8169601EBF10AABB5B71649E00E3D4600E23D2C20096CE2DB122C82F15A85238AA2337B559E7E8D0A824929956AA2394746B03E36A401565C2048D3DBF0411A8D4BB1044A9904290D264256B9085DA6001E5C208A2FB2760E94B958B4B2D5ADC52DBD1B -20240326214659 2 6 100 6143 5 F133729818EAD55DC3D8CA6C2754D6A78304D3CE96232D084B090E615BEAB6C63EC4B94BB1E33816ABCAFA3A08568FAD186C8873FDB17D7F9A28555871790CDA450A6EE13E97123F9A0589A77927047CE8B41B24F5505D19A3C4C18E132AFE9671423749DE1E110FB172AA66A15E405BD5CF56BE3CC6A22B13C3E03E42CA5BC3D8DA5B228C9569D7C15A2AE749A0F884A558687C2B656D94C167B47D9E3DD0691744E0D48858D0A1991FFEAAFE7E00C6284DC1E31CE3CED715F6686408BAEED6597453030DC62D033EF5A10B72D5367F7F1558F632CA86797FEBC16BF862D5CA0966122A584259FA0277B166F64F91959CC1F21E66BF0F6FD4489A00E0FC2E5C443A7AF646F32A772414D29F7A8116264C089E7D8A436870F0BB98EB134383464E2583DC569C9FC7D779D8C51A6D8BFA498FF8CF0F3CCDB631D794F1330E4E27A922BF0B0CADD66C11C885977B0AD344910D930E9D22F800FBB5A3712A5581C13D0378F82B2481969FC22C6A82E522A271C5FCA7079EEB7718D67BAC06F6A83B094B4FCD95BA2BCDC50EB547C79AAD9392DB976298511E0C270411CB37E3C1228ED8B018B15D3E2B334756DBF219624F2A2C6226FBF2EA33B9AAEC961E6BD3D7B6C9625ECF7E649D5EC21792E0A3E75E998FF6464961E74DAFB9CF95CF1CD654E4906FB725B381A325BE2D967B756072194EBAF8A2A524660EFA430957F30BE266C1105474A41964A5F7D5C9782FA193221BA23D9150CB5A08A3E231C62088D42FAA95777ADCE5D63ACB49299FBB1B29448A63B683B5799EE8DEE56B56748B7F269B43C35200716D74B5010388CF17B082AB285AC0DC827AAFF482EEC13268514B4F45AF6E0F948D3F466CE07C38A1308ED781B89837EB7332748A1BDD7E75CC904C763D44B0BA7A404046F1422B29DEC63EE2A524A123B8F971A181E8169601EBF10AABB5B71649E00E3D4600E23D2C20096CE2DB122C82F15A85238AA2337B559E7E8D0A824929956AA2394746B03E36A401565C2048D3DBF0411A8D4BB1044A9904290D264256B9085DA6001E5C208A2FB2760E94B958B4B2D5ADC800E58F -20240326215635 2 6 100 6143 5 F133729818EAD55DC3D8CA6C2754D6A78304D3CE96232D084B090E615BEAB6C63EC4B94BB1E33816ABCAFA3A08568FAD186C8873FDB17D7F9A28555871790CDA450A6EE13E97123F9A0589A77927047CE8B41B24F5505D19A3C4C18E132AFE9671423749DE1E110FB172AA66A15E405BD5CF56BE3CC6A22B13C3E03E42CA5BC3D8DA5B228C9569D7C15A2AE749A0F884A558687C2B656D94C167B47D9E3DD0691744E0D48858D0A1991FFEAAFE7E00C6284DC1E31CE3CED715F6686408BAEED6597453030DC62D033EF5A10B72D5367F7F1558F632CA86797FEBC16BF862D5CA0966122A584259FA0277B166F64F91959CC1F21E66BF0F6FD4489A00E0FC2E5C443A7AF646F32A772414D29F7A8116264C089E7D8A436870F0BB98EB134383464E2583DC569C9FC7D779D8C51A6D8BFA498FF8CF0F3CCDB631D794F1330E4E27A922BF0B0CADD66C11C885977B0AD344910D930E9D22F800FBB5A3712A5581C13D0378F82B2481969FC22C6A82E522A271C5FCA7079EEB7718D67BAC06F6A83B094B4FCD95BA2BCDC50EB547C79AAD9392DB976298511E0C270411CB37E3C1228ED8B018B15D3E2B334756DBF219624F2A2C6226FBF2EA33B9AAEC961E6BD3D7B6C9625ECF7E649D5EC21792E0A3E75E998FF6464961E74DAFB9CF95CF1CD654E4906FB725B381A325BE2D967B756072194EBAF8A2A524660EFA430957F30BE266C1105474A41964A5F7D5C9782FA193221BA23D9150CB5A08A3E231C62088D42FAA95777ADCE5D63ACB49299FBB1B29448A63B683B5799EE8DEE56B56748B7F269B43C35200716D74B5010388CF17B082AB285AC0DC827AAFF482EEC13268514B4F45AF6E0F948D3F466CE07C38A1308ED781B89837EB7332748A1BDD7E75CC904C763D44B0BA7A404046F1422B29DEC63EE2A524A123B8F971A181E8169601EBF10AABB5B71649E00E3D4600E23D2C20096CE2DB122C82F15A85238AA2337B559E7E8D0A824929956AA2394746B03E36A401565C2048D3DBF0411A8D4BB1044A9904290D264256B9085DA6001E5C208A2FB2760E94B958B4B2D5ADC9314DBF -20240326221037 2 6 100 6143 5 F133729818EAD55DC3D8CA6C2754D6A78304D3CE96232D084B090E615BEAB6C63EC4B94BB1E33816ABCAFA3A08568FAD186C8873FDB17D7F9A28555871790CDA450A6EE13E97123F9A0589A77927047CE8B41B24F5505D19A3C4C18E132AFE9671423749DE1E110FB172AA66A15E405BD5CF56BE3CC6A22B13C3E03E42CA5BC3D8DA5B228C9569D7C15A2AE749A0F884A558687C2B656D94C167B47D9E3DD0691744E0D48858D0A1991FFEAAFE7E00C6284DC1E31CE3CED715F6686408BAEED6597453030DC62D033EF5A10B72D5367F7F1558F632CA86797FEBC16BF862D5CA0966122A584259FA0277B166F64F91959CC1F21E66BF0F6FD4489A00E0FC2E5C443A7AF646F32A772414D29F7A8116264C089E7D8A436870F0BB98EB134383464E2583DC569C9FC7D779D8C51A6D8BFA498FF8CF0F3CCDB631D794F1330E4E27A922BF0B0CADD66C11C885977B0AD344910D930E9D22F800FBB5A3712A5581C13D0378F82B2481969FC22C6A82E522A271C5FCA7079EEB7718D67BAC06F6A83B094B4FCD95BA2BCDC50EB547C79AAD9392DB976298511E0C270411CB37E3C1228ED8B018B15D3E2B334756DBF219624F2A2C6226FBF2EA33B9AAEC961E6BD3D7B6C9625ECF7E649D5EC21792E0A3E75E998FF6464961E74DAFB9CF95CF1CD654E4906FB725B381A325BE2D967B756072194EBAF8A2A524660EFA430957F30BE266C1105474A41964A5F7D5C9782FA193221BA23D9150CB5A08A3E231C62088D42FAA95777ADCE5D63ACB49299FBB1B29448A63B683B5799EE8DEE56B56748B7F269B43C35200716D74B5010388CF17B082AB285AC0DC827AAFF482EEC13268514B4F45AF6E0F948D3F466CE07C38A1308ED781B89837EB7332748A1BDD7E75CC904C763D44B0BA7A404046F1422B29DEC63EE2A524A123B8F971A181E8169601EBF10AABB5B71649E00E3D4600E23D2C20096CE2DB122C82F15A85238AA2337B559E7E8D0A824929956AA2394746B03E36A401565C2048D3DBF0411A8D4BB1044A9904290D264256B9085DA6001E5C208A2FB2760E94B958B4B2D5ADCAE8162F -20240326225055 2 6 100 6143 2 F133729818EAD55DC3D8CA6C2754D6A78304D3CE96232D084B090E615BEAB6C63EC4B94BB1E33816ABCAFA3A08568FAD186C8873FDB17D7F9A28555871790CDA450A6EE13E97123F9A0589A77927047CE8B41B24F5505D19A3C4C18E132AFE9671423749DE1E110FB172AA66A15E405BD5CF56BE3CC6A22B13C3E03E42CA5BC3D8DA5B228C9569D7C15A2AE749A0F884A558687C2B656D94C167B47D9E3DD0691744E0D48858D0A1991FFEAAFE7E00C6284DC1E31CE3CED715F6686408BAEED6597453030DC62D033EF5A10B72D5367F7F1558F632CA86797FEBC16BF862D5CA0966122A584259FA0277B166F64F91959CC1F21E66BF0F6FD4489A00E0FC2E5C443A7AF646F32A772414D29F7A8116264C089E7D8A436870F0BB98EB134383464E2583DC569C9FC7D779D8C51A6D8BFA498FF8CF0F3CCDB631D794F1330E4E27A922BF0B0CADD66C11C885977B0AD344910D930E9D22F800FBB5A3712A5581C13D0378F82B2481969FC22C6A82E522A271C5FCA7079EEB7718D67BAC06F6A83B094B4FCD95BA2BCDC50EB547C79AAD9392DB976298511E0C270411CB37E3C1228ED8B018B15D3E2B334756DBF219624F2A2C6226FBF2EA33B9AAEC961E6BD3D7B6C9625ECF7E649D5EC21792E0A3E75E998FF6464961E74DAFB9CF95CF1CD654E4906FB725B381A325BE2D967B756072194EBAF8A2A524660EFA430957F30BE266C1105474A41964A5F7D5C9782FA193221BA23D9150CB5A08A3E231C62088D42FAA95777ADCE5D63ACB49299FBB1B29448A63B683B5799EE8DEE56B56748B7F269B43C35200716D74B5010388CF17B082AB285AC0DC827AAFF482EEC13268514B4F45AF6E0F948D3F466CE07C38A1308ED781B89837EB7332748A1BDD7E75CC904C763D44B0BA7A404046F1422B29DEC63EE2A524A123B8F971A181E8169601EBF10AABB5B71649E00E3D4600E23D2C20096CE2DB122C82F15A85238AA2337B559E7E8D0A824929956AA2394746B03E36A401565C2048D3DBF0411A8D4BB1044A9904290D264256B9085DA6001E5C208A2FB2760E94B958B4B2D5ADCFEC8FA3 -20240326225519 2 6 100 6143 5 F133729818EAD55DC3D8CA6C2754D6A78304D3CE96232D084B090E615BEAB6C63EC4B94BB1E33816ABCAFA3A08568FAD186C8873FDB17D7F9A28555871790CDA450A6EE13E97123F9A0589A77927047CE8B41B24F5505D19A3C4C18E132AFE9671423749DE1E110FB172AA66A15E405BD5CF56BE3CC6A22B13C3E03E42CA5BC3D8DA5B228C9569D7C15A2AE749A0F884A558687C2B656D94C167B47D9E3DD0691744E0D48858D0A1991FFEAAFE7E00C6284DC1E31CE3CED715F6686408BAEED6597453030DC62D033EF5A10B72D5367F7F1558F632CA86797FEBC16BF862D5CA0966122A584259FA0277B166F64F91959CC1F21E66BF0F6FD4489A00E0FC2E5C443A7AF646F32A772414D29F7A8116264C089E7D8A436870F0BB98EB134383464E2583DC569C9FC7D779D8C51A6D8BFA498FF8CF0F3CCDB631D794F1330E4E27A922BF0B0CADD66C11C885977B0AD344910D930E9D22F800FBB5A3712A5581C13D0378F82B2481969FC22C6A82E522A271C5FCA7079EEB7718D67BAC06F6A83B094B4FCD95BA2BCDC50EB547C79AAD9392DB976298511E0C270411CB37E3C1228ED8B018B15D3E2B334756DBF219624F2A2C6226FBF2EA33B9AAEC961E6BD3D7B6C9625ECF7E649D5EC21792E0A3E75E998FF6464961E74DAFB9CF95CF1CD654E4906FB725B381A325BE2D967B756072194EBAF8A2A524660EFA430957F30BE266C1105474A41964A5F7D5C9782FA193221BA23D9150CB5A08A3E231C62088D42FAA95777ADCE5D63ACB49299FBB1B29448A63B683B5799EE8DEE56B56748B7F269B43C35200716D74B5010388CF17B082AB285AC0DC827AAFF482EEC13268514B4F45AF6E0F948D3F466CE07C38A1308ED781B89837EB7332748A1BDD7E75CC904C763D44B0BA7A404046F1422B29DEC63EE2A524A123B8F971A181E8169601EBF10AABB5B71649E00E3D4600E23D2C20096CE2DB122C82F15A85238AA2337B559E7E8D0A824929956AA2394746B03E36A401565C2048D3DBF0411A8D4BB1044A9904290D264256B9085DA6001E5C208A2FB2760E94B958B4B2D5ADD072DFCF -20240326231305 2 6 100 6143 5 F133729818EAD55DC3D8CA6C2754D6A78304D3CE96232D084B090E615BEAB6C63EC4B94BB1E33816ABCAFA3A08568FAD186C8873FDB17D7F9A28555871790CDA450A6EE13E97123F9A0589A77927047CE8B41B24F5505D19A3C4C18E132AFE9671423749DE1E110FB172AA66A15E405BD5CF56BE3CC6A22B13C3E03E42CA5BC3D8DA5B228C9569D7C15A2AE749A0F884A558687C2B656D94C167B47D9E3DD0691744E0D48858D0A1991FFEAAFE7E00C6284DC1E31CE3CED715F6686408BAEED6597453030DC62D033EF5A10B72D5367F7F1558F632CA86797FEBC16BF862D5CA0966122A584259FA0277B166F64F91959CC1F21E66BF0F6FD4489A00E0FC2E5C443A7AF646F32A772414D29F7A8116264C089E7D8A436870F0BB98EB134383464E2583DC569C9FC7D779D8C51A6D8BFA498FF8CF0F3CCDB631D794F1330E4E27A922BF0B0CADD66C11C885977B0AD344910D930E9D22F800FBB5A3712A5581C13D0378F82B2481969FC22C6A82E522A271C5FCA7079EEB7718D67BAC06F6A83B094B4FCD95BA2BCDC50EB547C79AAD9392DB976298511E0C270411CB37E3C1228ED8B018B15D3E2B334756DBF219624F2A2C6226FBF2EA33B9AAEC961E6BD3D7B6C9625ECF7E649D5EC21792E0A3E75E998FF6464961E74DAFB9CF95CF1CD654E4906FB725B381A325BE2D967B756072194EBAF8A2A524660EFA430957F30BE266C1105474A41964A5F7D5C9782FA193221BA23D9150CB5A08A3E231C62088D42FAA95777ADCE5D63ACB49299FBB1B29448A63B683B5799EE8DEE56B56748B7F269B43C35200716D74B5010388CF17B082AB285AC0DC827AAFF482EEC13268514B4F45AF6E0F948D3F466CE07C38A1308ED781B89837EB7332748A1BDD7E75CC904C763D44B0BA7A404046F1422B29DEC63EE2A524A123B8F971A181E8169601EBF10AABB5B71649E00E3D4600E23D2C20096CE2DB122C82F15A85238AA2337B559E7E8D0A824929956AA2394746B03E36A401565C2048D3DBF0411A8D4BB1044A9904290D264256B9085DA6001E5C208A2FB2760E94B958B4B2D5ADD2AFDE1F -20240326233946 2 6 100 6143 2 F133729818EAD55DC3D8CA6C2754D6A78304D3CE96232D084B090E615BEAB6C63EC4B94BB1E33816ABCAFA3A08568FAD186C8873FDB17D7F9A28555871790CDA450A6EE13E97123F9A0589A77927047CE8B41B24F5505D19A3C4C18E132AFE9671423749DE1E110FB172AA66A15E405BD5CF56BE3CC6A22B13C3E03E42CA5BC3D8DA5B228C9569D7C15A2AE749A0F884A558687C2B656D94C167B47D9E3DD0691744E0D48858D0A1991FFEAAFE7E00C6284DC1E31CE3CED715F6686408BAEED6597453030DC62D033EF5A10B72D5367F7F1558F632CA86797FEBC16BF862D5CA0966122A584259FA0277B166F64F91959CC1F21E66BF0F6FD4489A00E0FC2E5C443A7AF646F32A772414D29F7A8116264C089E7D8A436870F0BB98EB134383464E2583DC569C9FC7D779D8C51A6D8BFA498FF8CF0F3CCDB631D794F1330E4E27A922BF0B0CADD66C11C885977B0AD344910D930E9D22F800FBB5A3712A5581C13D0378F82B2481969FC22C6A82E522A271C5FCA7079EEB7718D67BAC06F6A83B094B4FCD95BA2BCDC50EB547C79AAD9392DB976298511E0C270411CB37E3C1228ED8B018B15D3E2B334756DBF219624F2A2C6226FBF2EA33B9AAEC961E6BD3D7B6C9625ECF7E649D5EC21792E0A3E75E998FF6464961E74DAFB9CF95CF1CD654E4906FB725B381A325BE2D967B756072194EBAF8A2A524660EFA430957F30BE266C1105474A41964A5F7D5C9782FA193221BA23D9150CB5A08A3E231C62088D42FAA95777ADCE5D63ACB49299FBB1B29448A63B683B5799EE8DEE56B56748B7F269B43C35200716D74B5010388CF17B082AB285AC0DC827AAFF482EEC13268514B4F45AF6E0F948D3F466CE07C38A1308ED781B89837EB7332748A1BDD7E75CC904C763D44B0BA7A404046F1422B29DEC63EE2A524A123B8F971A181E8169601EBF10AABB5B71649E00E3D4600E23D2C20096CE2DB122C82F15A85238AA2337B559E7E8D0A824929956AA2394746B03E36A401565C2048D3DBF0411A8D4BB1044A9904290D264256B9085DA6001E5C208A2FB2760E94B958B4B2D5ADD60F026B -20240327001519 2 6 100 6143 2 F133729818EAD55DC3D8CA6C2754D6A78304D3CE96232D084B090E615BEAB6C63EC4B94BB1E33816ABCAFA3A08568FAD186C8873FDB17D7F9A28555871790CDA450A6EE13E97123F9A0589A77927047CE8B41B24F5505D19A3C4C18E132AFE9671423749DE1E110FB172AA66A15E405BD5CF56BE3CC6A22B13C3E03E42CA5BC3D8DA5B228C9569D7C15A2AE749A0F884A558687C2B656D94C167B47D9E3DD0691744E0D48858D0A1991FFEAAFE7E00C6284DC1E31CE3CED715F6686408BAEED6597453030DC62D033EF5A10B72D5367F7F1558F632CA86797FEBC16BF862D5CA0966122A584259FA0277B166F64F91959CC1F21E66BF0F6FD4489A00E0FC2E5C443A7AF646F32A772414D29F7A8116264C089E7D8A436870F0BB98EB134383464E2583DC569C9FC7D779D8C51A6D8BFA498FF8CF0F3CCDB631D794F1330E4E27A922BF0B0CADD66C11C885977B0AD344910D930E9D22F800FBB5A3712A5581C13D0378F82B2481969FC22C6A82E522A271C5FCA7079EEB7718D67BAC06F6A83B094B4FCD95BA2BCDC50EB547C79AAD9392DB976298511E0C270411CB37E3C1228ED8B018B15D3E2B334756DBF219624F2A2C6226FBF2EA33B9AAEC961E6BD3D7B6C9625ECF7E649D5EC21792E0A3E75E998FF6464961E74DAFB9CF95CF1CD654E4906FB725B381A325BE2D967B756072194EBAF8A2A524660EFA430957F30BE266C1105474A41964A5F7D5C9782FA193221BA23D9150CB5A08A3E231C62088D42FAA95777ADCE5D63ACB49299FBB1B29448A63B683B5799EE8DEE56B56748B7F269B43C35200716D74B5010388CF17B082AB285AC0DC827AAFF482EEC13268514B4F45AF6E0F948D3F466CE07C38A1308ED781B89837EB7332748A1BDD7E75CC904C763D44B0BA7A404046F1422B29DEC63EE2A524A123B8F971A181E8169601EBF10AABB5B71649E00E3D4600E23D2C20096CE2DB122C82F15A85238AA2337B559E7E8D0A824929956AA2394746B03E36A401565C2048D3DBF0411A8D4BB1044A9904290D264256B9085DA6001E5C208A2FB2760E94B958B4B2D5ADDA879EA3 -20240327002618 2 6 100 6143 2 F133729818EAD55DC3D8CA6C2754D6A78304D3CE96232D084B090E615BEAB6C63EC4B94BB1E33816ABCAFA3A08568FAD186C8873FDB17D7F9A28555871790CDA450A6EE13E97123F9A0589A77927047CE8B41B24F5505D19A3C4C18E132AFE9671423749DE1E110FB172AA66A15E405BD5CF56BE3CC6A22B13C3E03E42CA5BC3D8DA5B228C9569D7C15A2AE749A0F884A558687C2B656D94C167B47D9E3DD0691744E0D48858D0A1991FFEAAFE7E00C6284DC1E31CE3CED715F6686408BAEED6597453030DC62D033EF5A10B72D5367F7F1558F632CA86797FEBC16BF862D5CA0966122A584259FA0277B166F64F91959CC1F21E66BF0F6FD4489A00E0FC2E5C443A7AF646F32A772414D29F7A8116264C089E7D8A436870F0BB98EB134383464E2583DC569C9FC7D779D8C51A6D8BFA498FF8CF0F3CCDB631D794F1330E4E27A922BF0B0CADD66C11C885977B0AD344910D930E9D22F800FBB5A3712A5581C13D0378F82B2481969FC22C6A82E522A271C5FCA7079EEB7718D67BAC06F6A83B094B4FCD95BA2BCDC50EB547C79AAD9392DB976298511E0C270411CB37E3C1228ED8B018B15D3E2B334756DBF219624F2A2C6226FBF2EA33B9AAEC961E6BD3D7B6C9625ECF7E649D5EC21792E0A3E75E998FF6464961E74DAFB9CF95CF1CD654E4906FB725B381A325BE2D967B756072194EBAF8A2A524660EFA430957F30BE266C1105474A41964A5F7D5C9782FA193221BA23D9150CB5A08A3E231C62088D42FAA95777ADCE5D63ACB49299FBB1B29448A63B683B5799EE8DEE56B56748B7F269B43C35200716D74B5010388CF17B082AB285AC0DC827AAFF482EEC13268514B4F45AF6E0F948D3F466CE07C38A1308ED781B89837EB7332748A1BDD7E75CC904C763D44B0BA7A404046F1422B29DEC63EE2A524A123B8F971A181E8169601EBF10AABB5B71649E00E3D4600E23D2C20096CE2DB122C82F15A85238AA2337B559E7E8D0A824929956AA2394746B03E36A401565C2048D3DBF0411A8D4BB1044A9904290D264256B9085DA6001E5C208A2FB2760E94B958B4B2D5ADDBDFC89B -20240327003415 2 6 100 6143 2 F133729818EAD55DC3D8CA6C2754D6A78304D3CE96232D084B090E615BEAB6C63EC4B94BB1E33816ABCAFA3A08568FAD186C8873FDB17D7F9A28555871790CDA450A6EE13E97123F9A0589A77927047CE8B41B24F5505D19A3C4C18E132AFE9671423749DE1E110FB172AA66A15E405BD5CF56BE3CC6A22B13C3E03E42CA5BC3D8DA5B228C9569D7C15A2AE749A0F884A558687C2B656D94C167B47D9E3DD0691744E0D48858D0A1991FFEAAFE7E00C6284DC1E31CE3CED715F6686408BAEED6597453030DC62D033EF5A10B72D5367F7F1558F632CA86797FEBC16BF862D5CA0966122A584259FA0277B166F64F91959CC1F21E66BF0F6FD4489A00E0FC2E5C443A7AF646F32A772414D29F7A8116264C089E7D8A436870F0BB98EB134383464E2583DC569C9FC7D779D8C51A6D8BFA498FF8CF0F3CCDB631D794F1330E4E27A922BF0B0CADD66C11C885977B0AD344910D930E9D22F800FBB5A3712A5581C13D0378F82B2481969FC22C6A82E522A271C5FCA7079EEB7718D67BAC06F6A83B094B4FCD95BA2BCDC50EB547C79AAD9392DB976298511E0C270411CB37E3C1228ED8B018B15D3E2B334756DBF219624F2A2C6226FBF2EA33B9AAEC961E6BD3D7B6C9625ECF7E649D5EC21792E0A3E75E998FF6464961E74DAFB9CF95CF1CD654E4906FB725B381A325BE2D967B756072194EBAF8A2A524660EFA430957F30BE266C1105474A41964A5F7D5C9782FA193221BA23D9150CB5A08A3E231C62088D42FAA95777ADCE5D63ACB49299FBB1B29448A63B683B5799EE8DEE56B56748B7F269B43C35200716D74B5010388CF17B082AB285AC0DC827AAFF482EEC13268514B4F45AF6E0F948D3F466CE07C38A1308ED781B89837EB7332748A1BDD7E75CC904C763D44B0BA7A404046F1422B29DEC63EE2A524A123B8F971A181E8169601EBF10AABB5B71649E00E3D4600E23D2C20096CE2DB122C82F15A85238AA2337B559E7E8D0A824929956AA2394746B03E36A401565C2048D3DBF0411A8D4BB1044A9904290D264256B9085DA6001E5C208A2FB2760E94B958B4B2D5ADDCD9388B -20240327012525 2 6 100 7679 2 EC85B1B812727C95C9C6D18B4F5700D62DBF698E4F4663A8C3298C2E301DF351147BB27E17982D2AF86FC969FB517AF57B10D864F23E8604341D97ECE9D33D31CA686CEEF872647B720A3010AFD4B85B0DBA65D3C9200D2C87BE4D4CAC50CAEBE0C92600F73FE5B5FD60D09762105BAA466DEB7809061EE3E4D0621D53DD39F5D7730324DF21FD9871E0BBCEBBB5450DBA4F30CA294BE8AE76D4318F8C543D9E6A032586BC29BE362311B3087657F3A068ED3221BA4EF3FF233C721D261FB9EE8245E171B32FFB8E7BA85ADFE304C784FF306AF7B2C8D9CDE0209AF5592BC33CAE85EAFB662808FA8B45405C4C0ED10DDC3B44C9A69AE6EFC86088D91C137046B2C2133EEAAA55EF5A55D4501B6357FEAC66EF33E521CCBCAA4BA4969EFAF7B41A2059C391AA92A387E75E02E8A018911D13899851C88B81F0592219032EB0538E6CB37E69A8FE2D7E759C7548556FF28B61F3DB0D1D945CF68BEC64497C803A4F8EB9B88F9872963A792480007310840F83966B386681071FAD8E5CF1502B6B2985C39E4D6CE509F086B53594B93A9AE3CA763C5CAD850FD1B1138B88E6741E7198ADC5768CC1737DEB702270FC8DE01042774E36AED88262D1C8B2166F84A3CEB5623B764CD85C808DB607837701D3F5BBEF83D19E927AEEF464079A9ABA5053CB0F2FD0942ABB568ACD050BF682809EAACD695F248D851CA0D7542BE8517BAEE4D0C8E22AA1C76E7650602723DD93A4834F4D87E74EEE8288F17175F481932E5FF012F903DDA99F74B547AF32937C7FD673ED79588C220D8EB60600747A32CFECC4E4E87001E6EEBB855EE56D47AFCD6B820D4130F6DB7E78948253A03E76CED6C399C058BB06253B799FD075DF738B7CEE5EF7AF153EFBA54A5A1EB9080A975B30262708B5E9CD283DCC8839CF10C28611B8D69A24A46DD926F755B84FF6C3D004313436C4E3E78A52D8FD8533DC2B1B7AFD1C3134B0AEBB0194844398262D56B442EEA1DD8731FE31FB785C2DFC32728AC502EF85A4A25EA2FA869172BDAE8872DA8EDA79020BF86E291EE8F383CCA7CFD3DAD66C92A734474A2AD7309BDB87C63F4FCD19E0C65912F9F054EB2E7A387CA81AB509E095C7331EE7DAA33E636663E0FF6DB66C3F3812C3CEC115B899FA6621B209E392DCB747F1800718A9ADAD04D48B5617D36AF518EF9A5A76FCCE8CE6BEFE567F1E91DA0FAEF318762B2E3D949C2D08A8544C80A841BF3DF01ACCF58700B804E7568F59F370DB76EEE625A7B380B38E4A1CC24F0DF6FD26C439B34B765DC4E04D6C0325DAF60A1C79057C0D94281E652E2C1CDCDCC304159440571F1B565F0A511647A54123BF06ED93 -20240327022256 2 6 100 7679 2 EC85B1B812727C95C9C6D18B4F5700D62DBF698E4F4663A8C3298C2E301DF351147BB27E17982D2AF86FC969FB517AF57B10D864F23E8604341D97ECE9D33D31CA686CEEF872647B720A3010AFD4B85B0DBA65D3C9200D2C87BE4D4CAC50CAEBE0C92600F73FE5B5FD60D09762105BAA466DEB7809061EE3E4D0621D53DD39F5D7730324DF21FD9871E0BBCEBBB5450DBA4F30CA294BE8AE76D4318F8C543D9E6A032586BC29BE362311B3087657F3A068ED3221BA4EF3FF233C721D261FB9EE8245E171B32FFB8E7BA85ADFE304C784FF306AF7B2C8D9CDE0209AF5592BC33CAE85EAFB662808FA8B45405C4C0ED10DDC3B44C9A69AE6EFC86088D91C137046B2C2133EEAAA55EF5A55D4501B6357FEAC66EF33E521CCBCAA4BA4969EFAF7B41A2059C391AA92A387E75E02E8A018911D13899851C88B81F0592219032EB0538E6CB37E69A8FE2D7E759C7548556FF28B61F3DB0D1D945CF68BEC64497C803A4F8EB9B88F9872963A792480007310840F83966B386681071FAD8E5CF1502B6B2985C39E4D6CE509F086B53594B93A9AE3CA763C5CAD850FD1B1138B88E6741E7198ADC5768CC1737DEB702270FC8DE01042774E36AED88262D1C8B2166F84A3CEB5623B764CD85C808DB607837701D3F5BBEF83D19E927AEEF464079A9ABA5053CB0F2FD0942ABB568ACD050BF682809EAACD695F248D851CA0D7542BE8517BAEE4D0C8E22AA1C76E7650602723DD93A4834F4D87E74EEE8288F17175F481932E5FF012F903DDA99F74B547AF32937C7FD673ED79588C220D8EB60600747A32CFECC4E4E87001E6EEBB855EE56D47AFCD6B820D4130F6DB7E78948253A03E76CED6C399C058BB06253B799FD075DF738B7CEE5EF7AF153EFBA54A5A1EB9080A975B30262708B5E9CD283DCC8839CF10C28611B8D69A24A46DD926F755B84FF6C3D004313436C4E3E78A52D8FD8533DC2B1B7AFD1C3134B0AEBB0194844398262D56B442EEA1DD8731FE31FB785C2DFC32728AC502EF85A4A25EA2FA869172BDAE8872DA8EDA79020BF86E291EE8F383CCA7CFD3DAD66C92A734474A2AD7309BDB87C63F4FCD19E0C65912F9F054EB2E7A387CA81AB509E095C7331EE7DAA33E636663E0FF6DB66C3F3812C3CEC115B899FA6621B209E392DCB747F1800718A9ADAD04D48B5617D36AF518EF9A5A76FCCE8CE6BEFE567F1E91DA0FAEF318762B2E3D949C2D08A8544C80A841BF3DF01ACCF58700B804E7568F59F370DB76EEE625A7B380B38E4A1CC24F0DF6FD26C439B34B765DC4E04D6C0325DAF60A1C79057C0D94281E652E2C1CDCDCC304159440571F1B565F0A511647A54123C2EB1D03 -20240327025321 2 6 100 7679 5 EC85B1B812727C95C9C6D18B4F5700D62DBF698E4F4663A8C3298C2E301DF351147BB27E17982D2AF86FC969FB517AF57B10D864F23E8604341D97ECE9D33D31CA686CEEF872647B720A3010AFD4B85B0DBA65D3C9200D2C87BE4D4CAC50CAEBE0C92600F73FE5B5FD60D09762105BAA466DEB7809061EE3E4D0621D53DD39F5D7730324DF21FD9871E0BBCEBBB5450DBA4F30CA294BE8AE76D4318F8C543D9E6A032586BC29BE362311B3087657F3A068ED3221BA4EF3FF233C721D261FB9EE8245E171B32FFB8E7BA85ADFE304C784FF306AF7B2C8D9CDE0209AF5592BC33CAE85EAFB662808FA8B45405C4C0ED10DDC3B44C9A69AE6EFC86088D91C137046B2C2133EEAAA55EF5A55D4501B6357FEAC66EF33E521CCBCAA4BA4969EFAF7B41A2059C391AA92A387E75E02E8A018911D13899851C88B81F0592219032EB0538E6CB37E69A8FE2D7E759C7548556FF28B61F3DB0D1D945CF68BEC64497C803A4F8EB9B88F9872963A792480007310840F83966B386681071FAD8E5CF1502B6B2985C39E4D6CE509F086B53594B93A9AE3CA763C5CAD850FD1B1138B88E6741E7198ADC5768CC1737DEB702270FC8DE01042774E36AED88262D1C8B2166F84A3CEB5623B764CD85C808DB607837701D3F5BBEF83D19E927AEEF464079A9ABA5053CB0F2FD0942ABB568ACD050BF682809EAACD695F248D851CA0D7542BE8517BAEE4D0C8E22AA1C76E7650602723DD93A4834F4D87E74EEE8288F17175F481932E5FF012F903DDA99F74B547AF32937C7FD673ED79588C220D8EB60600747A32CFECC4E4E87001E6EEBB855EE56D47AFCD6B820D4130F6DB7E78948253A03E76CED6C399C058BB06253B799FD075DF738B7CEE5EF7AF153EFBA54A5A1EB9080A975B30262708B5E9CD283DCC8839CF10C28611B8D69A24A46DD926F755B84FF6C3D004313436C4E3E78A52D8FD8533DC2B1B7AFD1C3134B0AEBB0194844398262D56B442EEA1DD8731FE31FB785C2DFC32728AC502EF85A4A25EA2FA869172BDAE8872DA8EDA79020BF86E291EE8F383CCA7CFD3DAD66C92A734474A2AD7309BDB87C63F4FCD19E0C65912F9F054EB2E7A387CA81AB509E095C7331EE7DAA33E636663E0FF6DB66C3F3812C3CEC115B899FA6621B209E392DCB747F1800718A9ADAD04D48B5617D36AF518EF9A5A76FCCE8CE6BEFE567F1E91DA0FAEF318762B2E3D949C2D08A8544C80A841BF3DF01ACCF58700B804E7568F59F370DB76EEE625A7B380B38E4A1CC24F0DF6FD26C439B34B765DC4E04D6C0325DAF60A1C79057C0D94281E652E2C1CDCDCC304159440571F1B565F0A511647A54123C4EE6D8F -20240327031901 2 6 100 7679 2 EC85B1B812727C95C9C6D18B4F5700D62DBF698E4F4663A8C3298C2E301DF351147BB27E17982D2AF86FC969FB517AF57B10D864F23E8604341D97ECE9D33D31CA686CEEF872647B720A3010AFD4B85B0DBA65D3C9200D2C87BE4D4CAC50CAEBE0C92600F73FE5B5FD60D09762105BAA466DEB7809061EE3E4D0621D53DD39F5D7730324DF21FD9871E0BBCEBBB5450DBA4F30CA294BE8AE76D4318F8C543D9E6A032586BC29BE362311B3087657F3A068ED3221BA4EF3FF233C721D261FB9EE8245E171B32FFB8E7BA85ADFE304C784FF306AF7B2C8D9CDE0209AF5592BC33CAE85EAFB662808FA8B45405C4C0ED10DDC3B44C9A69AE6EFC86088D91C137046B2C2133EEAAA55EF5A55D4501B6357FEAC66EF33E521CCBCAA4BA4969EFAF7B41A2059C391AA92A387E75E02E8A018911D13899851C88B81F0592219032EB0538E6CB37E69A8FE2D7E759C7548556FF28B61F3DB0D1D945CF68BEC64497C803A4F8EB9B88F9872963A792480007310840F83966B386681071FAD8E5CF1502B6B2985C39E4D6CE509F086B53594B93A9AE3CA763C5CAD850FD1B1138B88E6741E7198ADC5768CC1737DEB702270FC8DE01042774E36AED88262D1C8B2166F84A3CEB5623B764CD85C808DB607837701D3F5BBEF83D19E927AEEF464079A9ABA5053CB0F2FD0942ABB568ACD050BF682809EAACD695F248D851CA0D7542BE8517BAEE4D0C8E22AA1C76E7650602723DD93A4834F4D87E74EEE8288F17175F481932E5FF012F903DDA99F74B547AF32937C7FD673ED79588C220D8EB60600747A32CFECC4E4E87001E6EEBB855EE56D47AFCD6B820D4130F6DB7E78948253A03E76CED6C399C058BB06253B799FD075DF738B7CEE5EF7AF153EFBA54A5A1EB9080A975B30262708B5E9CD283DCC8839CF10C28611B8D69A24A46DD926F755B84FF6C3D004313436C4E3E78A52D8FD8533DC2B1B7AFD1C3134B0AEBB0194844398262D56B442EEA1DD8731FE31FB785C2DFC32728AC502EF85A4A25EA2FA869172BDAE8872DA8EDA79020BF86E291EE8F383CCA7CFD3DAD66C92A734474A2AD7309BDB87C63F4FCD19E0C65912F9F054EB2E7A387CA81AB509E095C7331EE7DAA33E636663E0FF6DB66C3F3812C3CEC115B899FA6621B209E392DCB747F1800718A9ADAD04D48B5617D36AF518EF9A5A76FCCE8CE6BEFE567F1E91DA0FAEF318762B2E3D949C2D08A8544C80A841BF3DF01ACCF58700B804E7568F59F370DB76EEE625A7B380B38E4A1CC24F0DF6FD26C439B34B765DC4E04D6C0325DAF60A1C79057C0D94281E652E2C1CDCDCC304159440571F1B565F0A511647A54123C6A6ECFB -20240327034252 2 6 100 7679 2 EC85B1B812727C95C9C6D18B4F5700D62DBF698E4F4663A8C3298C2E301DF351147BB27E17982D2AF86FC969FB517AF57B10D864F23E8604341D97ECE9D33D31CA686CEEF872647B720A3010AFD4B85B0DBA65D3C9200D2C87BE4D4CAC50CAEBE0C92600F73FE5B5FD60D09762105BAA466DEB7809061EE3E4D0621D53DD39F5D7730324DF21FD9871E0BBCEBBB5450DBA4F30CA294BE8AE76D4318F8C543D9E6A032586BC29BE362311B3087657F3A068ED3221BA4EF3FF233C721D261FB9EE8245E171B32FFB8E7BA85ADFE304C784FF306AF7B2C8D9CDE0209AF5592BC33CAE85EAFB662808FA8B45405C4C0ED10DDC3B44C9A69AE6EFC86088D91C137046B2C2133EEAAA55EF5A55D4501B6357FEAC66EF33E521CCBCAA4BA4969EFAF7B41A2059C391AA92A387E75E02E8A018911D13899851C88B81F0592219032EB0538E6CB37E69A8FE2D7E759C7548556FF28B61F3DB0D1D945CF68BEC64497C803A4F8EB9B88F9872963A792480007310840F83966B386681071FAD8E5CF1502B6B2985C39E4D6CE509F086B53594B93A9AE3CA763C5CAD850FD1B1138B88E6741E7198ADC5768CC1737DEB702270FC8DE01042774E36AED88262D1C8B2166F84A3CEB5623B764CD85C808DB607837701D3F5BBEF83D19E927AEEF464079A9ABA5053CB0F2FD0942ABB568ACD050BF682809EAACD695F248D851CA0D7542BE8517BAEE4D0C8E22AA1C76E7650602723DD93A4834F4D87E74EEE8288F17175F481932E5FF012F903DDA99F74B547AF32937C7FD673ED79588C220D8EB60600747A32CFECC4E4E87001E6EEBB855EE56D47AFCD6B820D4130F6DB7E78948253A03E76CED6C399C058BB06253B799FD075DF738B7CEE5EF7AF153EFBA54A5A1EB9080A975B30262708B5E9CD283DCC8839CF10C28611B8D69A24A46DD926F755B84FF6C3D004313436C4E3E78A52D8FD8533DC2B1B7AFD1C3134B0AEBB0194844398262D56B442EEA1DD8731FE31FB785C2DFC32728AC502EF85A4A25EA2FA869172BDAE8872DA8EDA79020BF86E291EE8F383CCA7CFD3DAD66C92A734474A2AD7309BDB87C63F4FCD19E0C65912F9F054EB2E7A387CA81AB509E095C7331EE7DAA33E636663E0FF6DB66C3F3812C3CEC115B899FA6621B209E392DCB747F1800718A9ADAD04D48B5617D36AF518EF9A5A76FCCE8CE6BEFE567F1E91DA0FAEF318762B2E3D949C2D08A8544C80A841BF3DF01ACCF58700B804E7568F59F370DB76EEE625A7B380B38E4A1CC24F0DF6FD26C439B34B765DC4E04D6C0325DAF60A1C79057C0D94281E652E2C1CDCDCC304159440571F1B565F0A511647A54123C84AA3F3 -20240327034558 2 6 100 7679 5 EC85B1B812727C95C9C6D18B4F5700D62DBF698E4F4663A8C3298C2E301DF351147BB27E17982D2AF86FC969FB517AF57B10D864F23E8604341D97ECE9D33D31CA686CEEF872647B720A3010AFD4B85B0DBA65D3C9200D2C87BE4D4CAC50CAEBE0C92600F73FE5B5FD60D09762105BAA466DEB7809061EE3E4D0621D53DD39F5D7730324DF21FD9871E0BBCEBBB5450DBA4F30CA294BE8AE76D4318F8C543D9E6A032586BC29BE362311B3087657F3A068ED3221BA4EF3FF233C721D261FB9EE8245E171B32FFB8E7BA85ADFE304C784FF306AF7B2C8D9CDE0209AF5592BC33CAE85EAFB662808FA8B45405C4C0ED10DDC3B44C9A69AE6EFC86088D91C137046B2C2133EEAAA55EF5A55D4501B6357FEAC66EF33E521CCBCAA4BA4969EFAF7B41A2059C391AA92A387E75E02E8A018911D13899851C88B81F0592219032EB0538E6CB37E69A8FE2D7E759C7548556FF28B61F3DB0D1D945CF68BEC64497C803A4F8EB9B88F9872963A792480007310840F83966B386681071FAD8E5CF1502B6B2985C39E4D6CE509F086B53594B93A9AE3CA763C5CAD850FD1B1138B88E6741E7198ADC5768CC1737DEB702270FC8DE01042774E36AED88262D1C8B2166F84A3CEB5623B764CD85C808DB607837701D3F5BBEF83D19E927AEEF464079A9ABA5053CB0F2FD0942ABB568ACD050BF682809EAACD695F248D851CA0D7542BE8517BAEE4D0C8E22AA1C76E7650602723DD93A4834F4D87E74EEE8288F17175F481932E5FF012F903DDA99F74B547AF32937C7FD673ED79588C220D8EB60600747A32CFECC4E4E87001E6EEBB855EE56D47AFCD6B820D4130F6DB7E78948253A03E76CED6C399C058BB06253B799FD075DF738B7CEE5EF7AF153EFBA54A5A1EB9080A975B30262708B5E9CD283DCC8839CF10C28611B8D69A24A46DD926F755B84FF6C3D004313436C4E3E78A52D8FD8533DC2B1B7AFD1C3134B0AEBB0194844398262D56B442EEA1DD8731FE31FB785C2DFC32728AC502EF85A4A25EA2FA869172BDAE8872DA8EDA79020BF86E291EE8F383CCA7CFD3DAD66C92A734474A2AD7309BDB87C63F4FCD19E0C65912F9F054EB2E7A387CA81AB509E095C7331EE7DAA33E636663E0FF6DB66C3F3812C3CEC115B899FA6621B209E392DCB747F1800718A9ADAD04D48B5617D36AF518EF9A5A76FCCE8CE6BEFE567F1E91DA0FAEF318762B2E3D949C2D08A8544C80A841BF3DF01ACCF58700B804E7568F59F370DB76EEE625A7B380B38E4A1CC24F0DF6FD26C439B34B765DC4E04D6C0325DAF60A1C79057C0D94281E652E2C1CDCDCC304159440571F1B565F0A511647A54123C876E36F -20240327035607 2 6 100 7679 5 EC85B1B812727C95C9C6D18B4F5700D62DBF698E4F4663A8C3298C2E301DF351147BB27E17982D2AF86FC969FB517AF57B10D864F23E8604341D97ECE9D33D31CA686CEEF872647B720A3010AFD4B85B0DBA65D3C9200D2C87BE4D4CAC50CAEBE0C92600F73FE5B5FD60D09762105BAA466DEB7809061EE3E4D0621D53DD39F5D7730324DF21FD9871E0BBCEBBB5450DBA4F30CA294BE8AE76D4318F8C543D9E6A032586BC29BE362311B3087657F3A068ED3221BA4EF3FF233C721D261FB9EE8245E171B32FFB8E7BA85ADFE304C784FF306AF7B2C8D9CDE0209AF5592BC33CAE85EAFB662808FA8B45405C4C0ED10DDC3B44C9A69AE6EFC86088D91C137046B2C2133EEAAA55EF5A55D4501B6357FEAC66EF33E521CCBCAA4BA4969EFAF7B41A2059C391AA92A387E75E02E8A018911D13899851C88B81F0592219032EB0538E6CB37E69A8FE2D7E759C7548556FF28B61F3DB0D1D945CF68BEC64497C803A4F8EB9B88F9872963A792480007310840F83966B386681071FAD8E5CF1502B6B2985C39E4D6CE509F086B53594B93A9AE3CA763C5CAD850FD1B1138B88E6741E7198ADC5768CC1737DEB702270FC8DE01042774E36AED88262D1C8B2166F84A3CEB5623B764CD85C808DB607837701D3F5BBEF83D19E927AEEF464079A9ABA5053CB0F2FD0942ABB568ACD050BF682809EAACD695F248D851CA0D7542BE8517BAEE4D0C8E22AA1C76E7650602723DD93A4834F4D87E74EEE8288F17175F481932E5FF012F903DDA99F74B547AF32937C7FD673ED79588C220D8EB60600747A32CFECC4E4E87001E6EEBB855EE56D47AFCD6B820D4130F6DB7E78948253A03E76CED6C399C058BB06253B799FD075DF738B7CEE5EF7AF153EFBA54A5A1EB9080A975B30262708B5E9CD283DCC8839CF10C28611B8D69A24A46DD926F755B84FF6C3D004313436C4E3E78A52D8FD8533DC2B1B7AFD1C3134B0AEBB0194844398262D56B442EEA1DD8731FE31FB785C2DFC32728AC502EF85A4A25EA2FA869172BDAE8872DA8EDA79020BF86E291EE8F383CCA7CFD3DAD66C92A734474A2AD7309BDB87C63F4FCD19E0C65912F9F054EB2E7A387CA81AB509E095C7331EE7DAA33E636663E0FF6DB66C3F3812C3CEC115B899FA6621B209E392DCB747F1800718A9ADAD04D48B5617D36AF518EF9A5A76FCCE8CE6BEFE567F1E91DA0FAEF318762B2E3D949C2D08A8544C80A841BF3DF01ACCF58700B804E7568F59F370DB76EEE625A7B380B38E4A1CC24F0DF6FD26C439B34B765DC4E04D6C0325DAF60A1C79057C0D94281E652E2C1CDCDCC304159440571F1B565F0A511647A54123C91E770F -20240327043824 2 6 100 7679 2 EC85B1B812727C95C9C6D18B4F5700D62DBF698E4F4663A8C3298C2E301DF351147BB27E17982D2AF86FC969FB517AF57B10D864F23E8604341D97ECE9D33D31CA686CEEF872647B720A3010AFD4B85B0DBA65D3C9200D2C87BE4D4CAC50CAEBE0C92600F73FE5B5FD60D09762105BAA466DEB7809061EE3E4D0621D53DD39F5D7730324DF21FD9871E0BBCEBBB5450DBA4F30CA294BE8AE76D4318F8C543D9E6A032586BC29BE362311B3087657F3A068ED3221BA4EF3FF233C721D261FB9EE8245E171B32FFB8E7BA85ADFE304C784FF306AF7B2C8D9CDE0209AF5592BC33CAE85EAFB662808FA8B45405C4C0ED10DDC3B44C9A69AE6EFC86088D91C137046B2C2133EEAAA55EF5A55D4501B6357FEAC66EF33E521CCBCAA4BA4969EFAF7B41A2059C391AA92A387E75E02E8A018911D13899851C88B81F0592219032EB0538E6CB37E69A8FE2D7E759C7548556FF28B61F3DB0D1D945CF68BEC64497C803A4F8EB9B88F9872963A792480007310840F83966B386681071FAD8E5CF1502B6B2985C39E4D6CE509F086B53594B93A9AE3CA763C5CAD850FD1B1138B88E6741E7198ADC5768CC1737DEB702270FC8DE01042774E36AED88262D1C8B2166F84A3CEB5623B764CD85C808DB607837701D3F5BBEF83D19E927AEEF464079A9ABA5053CB0F2FD0942ABB568ACD050BF682809EAACD695F248D851CA0D7542BE8517BAEE4D0C8E22AA1C76E7650602723DD93A4834F4D87E74EEE8288F17175F481932E5FF012F903DDA99F74B547AF32937C7FD673ED79588C220D8EB60600747A32CFECC4E4E87001E6EEBB855EE56D47AFCD6B820D4130F6DB7E78948253A03E76CED6C399C058BB06253B799FD075DF738B7CEE5EF7AF153EFBA54A5A1EB9080A975B30262708B5E9CD283DCC8839CF10C28611B8D69A24A46DD926F755B84FF6C3D004313436C4E3E78A52D8FD8533DC2B1B7AFD1C3134B0AEBB0194844398262D56B442EEA1DD8731FE31FB785C2DFC32728AC502EF85A4A25EA2FA869172BDAE8872DA8EDA79020BF86E291EE8F383CCA7CFD3DAD66C92A734474A2AD7309BDB87C63F4FCD19E0C65912F9F054EB2E7A387CA81AB509E095C7331EE7DAA33E636663E0FF6DB66C3F3812C3CEC115B899FA6621B209E392DCB747F1800718A9ADAD04D48B5617D36AF518EF9A5A76FCCE8CE6BEFE567F1E91DA0FAEF318762B2E3D949C2D08A8544C80A841BF3DF01ACCF58700B804E7568F59F370DB76EEE625A7B380B38E4A1CC24F0DF6FD26C439B34B765DC4E04D6C0325DAF60A1C79057C0D94281E652E2C1CDCDCC304159440571F1B565F0A511647A54123CBF90753 -20240327061734 2 6 100 7679 2 EC85B1B812727C95C9C6D18B4F5700D62DBF698E4F4663A8C3298C2E301DF351147BB27E17982D2AF86FC969FB517AF57B10D864F23E8604341D97ECE9D33D31CA686CEEF872647B720A3010AFD4B85B0DBA65D3C9200D2C87BE4D4CAC50CAEBE0C92600F73FE5B5FD60D09762105BAA466DEB7809061EE3E4D0621D53DD39F5D7730324DF21FD9871E0BBCEBBB5450DBA4F30CA294BE8AE76D4318F8C543D9E6A032586BC29BE362311B3087657F3A068ED3221BA4EF3FF233C721D261FB9EE8245E171B32FFB8E7BA85ADFE304C784FF306AF7B2C8D9CDE0209AF5592BC33CAE85EAFB662808FA8B45405C4C0ED10DDC3B44C9A69AE6EFC86088D91C137046B2C2133EEAAA55EF5A55D4501B6357FEAC66EF33E521CCBCAA4BA4969EFAF7B41A2059C391AA92A387E75E02E8A018911D13899851C88B81F0592219032EB0538E6CB37E69A8FE2D7E759C7548556FF28B61F3DB0D1D945CF68BEC64497C803A4F8EB9B88F9872963A792480007310840F83966B386681071FAD8E5CF1502B6B2985C39E4D6CE509F086B53594B93A9AE3CA763C5CAD850FD1B1138B88E6741E7198ADC5768CC1737DEB702270FC8DE01042774E36AED88262D1C8B2166F84A3CEB5623B764CD85C808DB607837701D3F5BBEF83D19E927AEEF464079A9ABA5053CB0F2FD0942ABB568ACD050BF682809EAACD695F248D851CA0D7542BE8517BAEE4D0C8E22AA1C76E7650602723DD93A4834F4D87E74EEE8288F17175F481932E5FF012F903DDA99F74B547AF32937C7FD673ED79588C220D8EB60600747A32CFECC4E4E87001E6EEBB855EE56D47AFCD6B820D4130F6DB7E78948253A03E76CED6C399C058BB06253B799FD075DF738B7CEE5EF7AF153EFBA54A5A1EB9080A975B30262708B5E9CD283DCC8839CF10C28611B8D69A24A46DD926F755B84FF6C3D004313436C4E3E78A52D8FD8533DC2B1B7AFD1C3134B0AEBB0194844398262D56B442EEA1DD8731FE31FB785C2DFC32728AC502EF85A4A25EA2FA869172BDAE8872DA8EDA79020BF86E291EE8F383CCA7CFD3DAD66C92A734474A2AD7309BDB87C63F4FCD19E0C65912F9F054EB2E7A387CA81AB509E095C7331EE7DAA33E636663E0FF6DB66C3F3812C3CEC115B899FA6621B209E392DCB747F1800718A9ADAD04D48B5617D36AF518EF9A5A76FCCE8CE6BEFE567F1E91DA0FAEF318762B2E3D949C2D08A8544C80A841BF3DF01ACCF58700B804E7568F59F370DB76EEE625A7B380B38E4A1CC24F0DF6FD26C439B34B765DC4E04D6C0325DAF60A1C79057C0D94281E652E2C1CDCDCC304159440571F1B565F0A511647A54123D2A46DE3 -20240327071503 2 6 100 7679 5 EC85B1B812727C95C9C6D18B4F5700D62DBF698E4F4663A8C3298C2E301DF351147BB27E17982D2AF86FC969FB517AF57B10D864F23E8604341D97ECE9D33D31CA686CEEF872647B720A3010AFD4B85B0DBA65D3C9200D2C87BE4D4CAC50CAEBE0C92600F73FE5B5FD60D09762105BAA466DEB7809061EE3E4D0621D53DD39F5D7730324DF21FD9871E0BBCEBBB5450DBA4F30CA294BE8AE76D4318F8C543D9E6A032586BC29BE362311B3087657F3A068ED3221BA4EF3FF233C721D261FB9EE8245E171B32FFB8E7BA85ADFE304C784FF306AF7B2C8D9CDE0209AF5592BC33CAE85EAFB662808FA8B45405C4C0ED10DDC3B44C9A69AE6EFC86088D91C137046B2C2133EEAAA55EF5A55D4501B6357FEAC66EF33E521CCBCAA4BA4969EFAF7B41A2059C391AA92A387E75E02E8A018911D13899851C88B81F0592219032EB0538E6CB37E69A8FE2D7E759C7548556FF28B61F3DB0D1D945CF68BEC64497C803A4F8EB9B88F9872963A792480007310840F83966B386681071FAD8E5CF1502B6B2985C39E4D6CE509F086B53594B93A9AE3CA763C5CAD850FD1B1138B88E6741E7198ADC5768CC1737DEB702270FC8DE01042774E36AED88262D1C8B2166F84A3CEB5623B764CD85C808DB607837701D3F5BBEF83D19E927AEEF464079A9ABA5053CB0F2FD0942ABB568ACD050BF682809EAACD695F248D851CA0D7542BE8517BAEE4D0C8E22AA1C76E7650602723DD93A4834F4D87E74EEE8288F17175F481932E5FF012F903DDA99F74B547AF32937C7FD673ED79588C220D8EB60600747A32CFECC4E4E87001E6EEBB855EE56D47AFCD6B820D4130F6DB7E78948253A03E76CED6C399C058BB06253B799FD075DF738B7CEE5EF7AF153EFBA54A5A1EB9080A975B30262708B5E9CD283DCC8839CF10C28611B8D69A24A46DD926F755B84FF6C3D004313436C4E3E78A52D8FD8533DC2B1B7AFD1C3134B0AEBB0194844398262D56B442EEA1DD8731FE31FB785C2DFC32728AC502EF85A4A25EA2FA869172BDAE8872DA8EDA79020BF86E291EE8F383CCA7CFD3DAD66C92A734474A2AD7309BDB87C63F4FCD19E0C65912F9F054EB2E7A387CA81AB509E095C7331EE7DAA33E636663E0FF6DB66C3F3812C3CEC115B899FA6621B209E392DCB747F1800718A9ADAD04D48B5617D36AF518EF9A5A76FCCE8CE6BEFE567F1E91DA0FAEF318762B2E3D949C2D08A8544C80A841BF3DF01ACCF58700B804E7568F59F370DB76EEE625A7B380B38E4A1CC24F0DF6FD26C439B34B765DC4E04D6C0325DAF60A1C79057C0D94281E652E2C1CDCDCC304159440571F1B565F0A511647A54123D6765ED7 -20240327080706 2 6 100 7679 2 EC85B1B812727C95C9C6D18B4F5700D62DBF698E4F4663A8C3298C2E301DF351147BB27E17982D2AF86FC969FB517AF57B10D864F23E8604341D97ECE9D33D31CA686CEEF872647B720A3010AFD4B85B0DBA65D3C9200D2C87BE4D4CAC50CAEBE0C92600F73FE5B5FD60D09762105BAA466DEB7809061EE3E4D0621D53DD39F5D7730324DF21FD9871E0BBCEBBB5450DBA4F30CA294BE8AE76D4318F8C543D9E6A032586BC29BE362311B3087657F3A068ED3221BA4EF3FF233C721D261FB9EE8245E171B32FFB8E7BA85ADFE304C784FF306AF7B2C8D9CDE0209AF5592BC33CAE85EAFB662808FA8B45405C4C0ED10DDC3B44C9A69AE6EFC86088D91C137046B2C2133EEAAA55EF5A55D4501B6357FEAC66EF33E521CCBCAA4BA4969EFAF7B41A2059C391AA92A387E75E02E8A018911D13899851C88B81F0592219032EB0538E6CB37E69A8FE2D7E759C7548556FF28B61F3DB0D1D945CF68BEC64497C803A4F8EB9B88F9872963A792480007310840F83966B386681071FAD8E5CF1502B6B2985C39E4D6CE509F086B53594B93A9AE3CA763C5CAD850FD1B1138B88E6741E7198ADC5768CC1737DEB702270FC8DE01042774E36AED88262D1C8B2166F84A3CEB5623B764CD85C808DB607837701D3F5BBEF83D19E927AEEF464079A9ABA5053CB0F2FD0942ABB568ACD050BF682809EAACD695F248D851CA0D7542BE8517BAEE4D0C8E22AA1C76E7650602723DD93A4834F4D87E74EEE8288F17175F481932E5FF012F903DDA99F74B547AF32937C7FD673ED79588C220D8EB60600747A32CFECC4E4E87001E6EEBB855EE56D47AFCD6B820D4130F6DB7E78948253A03E76CED6C399C058BB06253B799FD075DF738B7CEE5EF7AF153EFBA54A5A1EB9080A975B30262708B5E9CD283DCC8839CF10C28611B8D69A24A46DD926F755B84FF6C3D004313436C4E3E78A52D8FD8533DC2B1B7AFD1C3134B0AEBB0194844398262D56B442EEA1DD8731FE31FB785C2DFC32728AC502EF85A4A25EA2FA869172BDAE8872DA8EDA79020BF86E291EE8F383CCA7CFD3DAD66C92A734474A2AD7309BDB87C63F4FCD19E0C65912F9F054EB2E7A387CA81AB509E095C7331EE7DAA33E636663E0FF6DB66C3F3812C3CEC115B899FA6621B209E392DCB747F1800718A9ADAD04D48B5617D36AF518EF9A5A76FCCE8CE6BEFE567F1E91DA0FAEF318762B2E3D949C2D08A8544C80A841BF3DF01ACCF58700B804E7568F59F370DB76EEE625A7B380B38E4A1CC24F0DF6FD26C439B34B765DC4E04D6C0325DAF60A1C79057C0D94281E652E2C1CDCDCC304159440571F1B565F0A511647A54123D9FC24D3 -20240327091530 2 6 100 7679 2 EC85B1B812727C95C9C6D18B4F5700D62DBF698E4F4663A8C3298C2E301DF351147BB27E17982D2AF86FC969FB517AF57B10D864F23E8604341D97ECE9D33D31CA686CEEF872647B720A3010AFD4B85B0DBA65D3C9200D2C87BE4D4CAC50CAEBE0C92600F73FE5B5FD60D09762105BAA466DEB7809061EE3E4D0621D53DD39F5D7730324DF21FD9871E0BBCEBBB5450DBA4F30CA294BE8AE76D4318F8C543D9E6A032586BC29BE362311B3087657F3A068ED3221BA4EF3FF233C721D261FB9EE8245E171B32FFB8E7BA85ADFE304C784FF306AF7B2C8D9CDE0209AF5592BC33CAE85EAFB662808FA8B45405C4C0ED10DDC3B44C9A69AE6EFC86088D91C137046B2C2133EEAAA55EF5A55D4501B6357FEAC66EF33E521CCBCAA4BA4969EFAF7B41A2059C391AA92A387E75E02E8A018911D13899851C88B81F0592219032EB0538E6CB37E69A8FE2D7E759C7548556FF28B61F3DB0D1D945CF68BEC64497C803A4F8EB9B88F9872963A792480007310840F83966B386681071FAD8E5CF1502B6B2985C39E4D6CE509F086B53594B93A9AE3CA763C5CAD850FD1B1138B88E6741E7198ADC5768CC1737DEB702270FC8DE01042774E36AED88262D1C8B2166F84A3CEB5623B764CD85C808DB607837701D3F5BBEF83D19E927AEEF464079A9ABA5053CB0F2FD0942ABB568ACD050BF682809EAACD695F248D851CA0D7542BE8517BAEE4D0C8E22AA1C76E7650602723DD93A4834F4D87E74EEE8288F17175F481932E5FF012F903DDA99F74B547AF32937C7FD673ED79588C220D8EB60600747A32CFECC4E4E87001E6EEBB855EE56D47AFCD6B820D4130F6DB7E78948253A03E76CED6C399C058BB06253B799FD075DF738B7CEE5EF7AF153EFBA54A5A1EB9080A975B30262708B5E9CD283DCC8839CF10C28611B8D69A24A46DD926F755B84FF6C3D004313436C4E3E78A52D8FD8533DC2B1B7AFD1C3134B0AEBB0194844398262D56B442EEA1DD8731FE31FB785C2DFC32728AC502EF85A4A25EA2FA869172BDAE8872DA8EDA79020BF86E291EE8F383CCA7CFD3DAD66C92A734474A2AD7309BDB87C63F4FCD19E0C65912F9F054EB2E7A387CA81AB509E095C7331EE7DAA33E636663E0FF6DB66C3F3812C3CEC115B899FA6621B209E392DCB747F1800718A9ADAD04D48B5617D36AF518EF9A5A76FCCE8CE6BEFE567F1E91DA0FAEF318762B2E3D949C2D08A8544C80A841BF3DF01ACCF58700B804E7568F59F370DB76EEE625A7B380B38E4A1CC24F0DF6FD26C439B34B765DC4E04D6C0325DAF60A1C79057C0D94281E652E2C1CDCDCC304159440571F1B565F0A511647A54123DE8C18AB -20240327092725 2 6 100 7679 5 EC85B1B812727C95C9C6D18B4F5700D62DBF698E4F4663A8C3298C2E301DF351147BB27E17982D2AF86FC969FB517AF57B10D864F23E8604341D97ECE9D33D31CA686CEEF872647B720A3010AFD4B85B0DBA65D3C9200D2C87BE4D4CAC50CAEBE0C92600F73FE5B5FD60D09762105BAA466DEB7809061EE3E4D0621D53DD39F5D7730324DF21FD9871E0BBCEBBB5450DBA4F30CA294BE8AE76D4318F8C543D9E6A032586BC29BE362311B3087657F3A068ED3221BA4EF3FF233C721D261FB9EE8245E171B32FFB8E7BA85ADFE304C784FF306AF7B2C8D9CDE0209AF5592BC33CAE85EAFB662808FA8B45405C4C0ED10DDC3B44C9A69AE6EFC86088D91C137046B2C2133EEAAA55EF5A55D4501B6357FEAC66EF33E521CCBCAA4BA4969EFAF7B41A2059C391AA92A387E75E02E8A018911D13899851C88B81F0592219032EB0538E6CB37E69A8FE2D7E759C7548556FF28B61F3DB0D1D945CF68BEC64497C803A4F8EB9B88F9872963A792480007310840F83966B386681071FAD8E5CF1502B6B2985C39E4D6CE509F086B53594B93A9AE3CA763C5CAD850FD1B1138B88E6741E7198ADC5768CC1737DEB702270FC8DE01042774E36AED88262D1C8B2166F84A3CEB5623B764CD85C808DB607837701D3F5BBEF83D19E927AEEF464079A9ABA5053CB0F2FD0942ABB568ACD050BF682809EAACD695F248D851CA0D7542BE8517BAEE4D0C8E22AA1C76E7650602723DD93A4834F4D87E74EEE8288F17175F481932E5FF012F903DDA99F74B547AF32937C7FD673ED79588C220D8EB60600747A32CFECC4E4E87001E6EEBB855EE56D47AFCD6B820D4130F6DB7E78948253A03E76CED6C399C058BB06253B799FD075DF738B7CEE5EF7AF153EFBA54A5A1EB9080A975B30262708B5E9CD283DCC8839CF10C28611B8D69A24A46DD926F755B84FF6C3D004313436C4E3E78A52D8FD8533DC2B1B7AFD1C3134B0AEBB0194844398262D56B442EEA1DD8731FE31FB785C2DFC32728AC502EF85A4A25EA2FA869172BDAE8872DA8EDA79020BF86E291EE8F383CCA7CFD3DAD66C92A734474A2AD7309BDB87C63F4FCD19E0C65912F9F054EB2E7A387CA81AB509E095C7331EE7DAA33E636663E0FF6DB66C3F3812C3CEC115B899FA6621B209E392DCB747F1800718A9ADAD04D48B5617D36AF518EF9A5A76FCCE8CE6BEFE567F1E91DA0FAEF318762B2E3D949C2D08A8544C80A841BF3DF01ACCF58700B804E7568F59F370DB76EEE625A7B380B38E4A1CC24F0DF6FD26C439B34B765DC4E04D6C0325DAF60A1C79057C0D94281E652E2C1CDCDCC304159440571F1B565F0A511647A54123DF4D10AF -20240327100400 2 6 100 7679 2 EC85B1B812727C95C9C6D18B4F5700D62DBF698E4F4663A8C3298C2E301DF351147BB27E17982D2AF86FC969FB517AF57B10D864F23E8604341D97ECE9D33D31CA686CEEF872647B720A3010AFD4B85B0DBA65D3C9200D2C87BE4D4CAC50CAEBE0C92600F73FE5B5FD60D09762105BAA466DEB7809061EE3E4D0621D53DD39F5D7730324DF21FD9871E0BBCEBBB5450DBA4F30CA294BE8AE76D4318F8C543D9E6A032586BC29BE362311B3087657F3A068ED3221BA4EF3FF233C721D261FB9EE8245E171B32FFB8E7BA85ADFE304C784FF306AF7B2C8D9CDE0209AF5592BC33CAE85EAFB662808FA8B45405C4C0ED10DDC3B44C9A69AE6EFC86088D91C137046B2C2133EEAAA55EF5A55D4501B6357FEAC66EF33E521CCBCAA4BA4969EFAF7B41A2059C391AA92A387E75E02E8A018911D13899851C88B81F0592219032EB0538E6CB37E69A8FE2D7E759C7548556FF28B61F3DB0D1D945CF68BEC64497C803A4F8EB9B88F9872963A792480007310840F83966B386681071FAD8E5CF1502B6B2985C39E4D6CE509F086B53594B93A9AE3CA763C5CAD850FD1B1138B88E6741E7198ADC5768CC1737DEB702270FC8DE01042774E36AED88262D1C8B2166F84A3CEB5623B764CD85C808DB607837701D3F5BBEF83D19E927AEEF464079A9ABA5053CB0F2FD0942ABB568ACD050BF682809EAACD695F248D851CA0D7542BE8517BAEE4D0C8E22AA1C76E7650602723DD93A4834F4D87E74EEE8288F17175F481932E5FF012F903DDA99F74B547AF32937C7FD673ED79588C220D8EB60600747A32CFECC4E4E87001E6EEBB855EE56D47AFCD6B820D4130F6DB7E78948253A03E76CED6C399C058BB06253B799FD075DF738B7CEE5EF7AF153EFBA54A5A1EB9080A975B30262708B5E9CD283DCC8839CF10C28611B8D69A24A46DD926F755B84FF6C3D004313436C4E3E78A52D8FD8533DC2B1B7AFD1C3134B0AEBB0194844398262D56B442EEA1DD8731FE31FB785C2DFC32728AC502EF85A4A25EA2FA869172BDAE8872DA8EDA79020BF86E291EE8F383CCA7CFD3DAD66C92A734474A2AD7309BDB87C63F4FCD19E0C65912F9F054EB2E7A387CA81AB509E095C7331EE7DAA33E636663E0FF6DB66C3F3812C3CEC115B899FA6621B209E392DCB747F1800718A9ADAD04D48B5617D36AF518EF9A5A76FCCE8CE6BEFE567F1E91DA0FAEF318762B2E3D949C2D08A8544C80A841BF3DF01ACCF58700B804E7568F59F370DB76EEE625A7B380B38E4A1CC24F0DF6FD26C439B34B765DC4E04D6C0325DAF60A1C79057C0D94281E652E2C1CDCDCC304159440571F1B565F0A511647A54123E1BE884B -20240327102109 2 6 100 7679 5 EC85B1B812727C95C9C6D18B4F5700D62DBF698E4F4663A8C3298C2E301DF351147BB27E17982D2AF86FC969FB517AF57B10D864F23E8604341D97ECE9D33D31CA686CEEF872647B720A3010AFD4B85B0DBA65D3C9200D2C87BE4D4CAC50CAEBE0C92600F73FE5B5FD60D09762105BAA466DEB7809061EE3E4D0621D53DD39F5D7730324DF21FD9871E0BBCEBBB5450DBA4F30CA294BE8AE76D4318F8C543D9E6A032586BC29BE362311B3087657F3A068ED3221BA4EF3FF233C721D261FB9EE8245E171B32FFB8E7BA85ADFE304C784FF306AF7B2C8D9CDE0209AF5592BC33CAE85EAFB662808FA8B45405C4C0ED10DDC3B44C9A69AE6EFC86088D91C137046B2C2133EEAAA55EF5A55D4501B6357FEAC66EF33E521CCBCAA4BA4969EFAF7B41A2059C391AA92A387E75E02E8A018911D13899851C88B81F0592219032EB0538E6CB37E69A8FE2D7E759C7548556FF28B61F3DB0D1D945CF68BEC64497C803A4F8EB9B88F9872963A792480007310840F83966B386681071FAD8E5CF1502B6B2985C39E4D6CE509F086B53594B93A9AE3CA763C5CAD850FD1B1138B88E6741E7198ADC5768CC1737DEB702270FC8DE01042774E36AED88262D1C8B2166F84A3CEB5623B764CD85C808DB607837701D3F5BBEF83D19E927AEEF464079A9ABA5053CB0F2FD0942ABB568ACD050BF682809EAACD695F248D851CA0D7542BE8517BAEE4D0C8E22AA1C76E7650602723DD93A4834F4D87E74EEE8288F17175F481932E5FF012F903DDA99F74B547AF32937C7FD673ED79588C220D8EB60600747A32CFECC4E4E87001E6EEBB855EE56D47AFCD6B820D4130F6DB7E78948253A03E76CED6C399C058BB06253B799FD075DF738B7CEE5EF7AF153EFBA54A5A1EB9080A975B30262708B5E9CD283DCC8839CF10C28611B8D69A24A46DD926F755B84FF6C3D004313436C4E3E78A52D8FD8533DC2B1B7AFD1C3134B0AEBB0194844398262D56B442EEA1DD8731FE31FB785C2DFC32728AC502EF85A4A25EA2FA869172BDAE8872DA8EDA79020BF86E291EE8F383CCA7CFD3DAD66C92A734474A2AD7309BDB87C63F4FCD19E0C65912F9F054EB2E7A387CA81AB509E095C7331EE7DAA33E636663E0FF6DB66C3F3812C3CEC115B899FA6621B209E392DCB747F1800718A9ADAD04D48B5617D36AF518EF9A5A76FCCE8CE6BEFE567F1E91DA0FAEF318762B2E3D949C2D08A8544C80A841BF3DF01ACCF58700B804E7568F59F370DB76EEE625A7B380B38E4A1CC24F0DF6FD26C439B34B765DC4E04D6C0325DAF60A1C79057C0D94281E652E2C1CDCDCC304159440571F1B565F0A511647A54123E2D9E9AF -20240327111646 2 6 100 7679 2 EC85B1B812727C95C9C6D18B4F5700D62DBF698E4F4663A8C3298C2E301DF351147BB27E17982D2AF86FC969FB517AF57B10D864F23E8604341D97ECE9D33D31CA686CEEF872647B720A3010AFD4B85B0DBA65D3C9200D2C87BE4D4CAC50CAEBE0C92600F73FE5B5FD60D09762105BAA466DEB7809061EE3E4D0621D53DD39F5D7730324DF21FD9871E0BBCEBBB5450DBA4F30CA294BE8AE76D4318F8C543D9E6A032586BC29BE362311B3087657F3A068ED3221BA4EF3FF233C721D261FB9EE8245E171B32FFB8E7BA85ADFE304C784FF306AF7B2C8D9CDE0209AF5592BC33CAE85EAFB662808FA8B45405C4C0ED10DDC3B44C9A69AE6EFC86088D91C137046B2C2133EEAAA55EF5A55D4501B6357FEAC66EF33E521CCBCAA4BA4969EFAF7B41A2059C391AA92A387E75E02E8A018911D13899851C88B81F0592219032EB0538E6CB37E69A8FE2D7E759C7548556FF28B61F3DB0D1D945CF68BEC64497C803A4F8EB9B88F9872963A792480007310840F83966B386681071FAD8E5CF1502B6B2985C39E4D6CE509F086B53594B93A9AE3CA763C5CAD850FD1B1138B88E6741E7198ADC5768CC1737DEB702270FC8DE01042774E36AED88262D1C8B2166F84A3CEB5623B764CD85C808DB607837701D3F5BBEF83D19E927AEEF464079A9ABA5053CB0F2FD0942ABB568ACD050BF682809EAACD695F248D851CA0D7542BE8517BAEE4D0C8E22AA1C76E7650602723DD93A4834F4D87E74EEE8288F17175F481932E5FF012F903DDA99F74B547AF32937C7FD673ED79588C220D8EB60600747A32CFECC4E4E87001E6EEBB855EE56D47AFCD6B820D4130F6DB7E78948253A03E76CED6C399C058BB06253B799FD075DF738B7CEE5EF7AF153EFBA54A5A1EB9080A975B30262708B5E9CD283DCC8839CF10C28611B8D69A24A46DD926F755B84FF6C3D004313436C4E3E78A52D8FD8533DC2B1B7AFD1C3134B0AEBB0194844398262D56B442EEA1DD8731FE31FB785C2DFC32728AC502EF85A4A25EA2FA869172BDAE8872DA8EDA79020BF86E291EE8F383CCA7CFD3DAD66C92A734474A2AD7309BDB87C63F4FCD19E0C65912F9F054EB2E7A387CA81AB509E095C7331EE7DAA33E636663E0FF6DB66C3F3812C3CEC115B899FA6621B209E392DCB747F1800718A9ADAD04D48B5617D36AF518EF9A5A76FCCE8CE6BEFE567F1E91DA0FAEF318762B2E3D949C2D08A8544C80A841BF3DF01ACCF58700B804E7568F59F370DB76EEE625A7B380B38E4A1CC24F0DF6FD26C439B34B765DC4E04D6C0325DAF60A1C79057C0D94281E652E2C1CDCDCC304159440571F1B565F0A511647A54123E69B7CAB -20240327140134 2 6 100 7679 2 EC85B1B812727C95C9C6D18B4F5700D62DBF698E4F4663A8C3298C2E301DF351147BB27E17982D2AF86FC969FB517AF57B10D864F23E8604341D97ECE9D33D31CA686CEEF872647B720A3010AFD4B85B0DBA65D3C9200D2C87BE4D4CAC50CAEBE0C92600F73FE5B5FD60D09762105BAA466DEB7809061EE3E4D0621D53DD39F5D7730324DF21FD9871E0BBCEBBB5450DBA4F30CA294BE8AE76D4318F8C543D9E6A032586BC29BE362311B3087657F3A068ED3221BA4EF3FF233C721D261FB9EE8245E171B32FFB8E7BA85ADFE304C784FF306AF7B2C8D9CDE0209AF5592BC33CAE85EAFB662808FA8B45405C4C0ED10DDC3B44C9A69AE6EFC86088D91C137046B2C2133EEAAA55EF5A55D4501B6357FEAC66EF33E521CCBCAA4BA4969EFAF7B41A2059C391AA92A387E75E02E8A018911D13899851C88B81F0592219032EB0538E6CB37E69A8FE2D7E759C7548556FF28B61F3DB0D1D945CF68BEC64497C803A4F8EB9B88F9872963A792480007310840F83966B386681071FAD8E5CF1502B6B2985C39E4D6CE509F086B53594B93A9AE3CA763C5CAD850FD1B1138B88E6741E7198ADC5768CC1737DEB702270FC8DE01042774E36AED88262D1C8B2166F84A3CEB5623B764CD85C808DB607837701D3F5BBEF83D19E927AEEF464079A9ABA5053CB0F2FD0942ABB568ACD050BF682809EAACD695F248D851CA0D7542BE8517BAEE4D0C8E22AA1C76E7650602723DD93A4834F4D87E74EEE8288F17175F481932E5FF012F903DDA99F74B547AF32937C7FD673ED79588C220D8EB60600747A32CFECC4E4E87001E6EEBB855EE56D47AFCD6B820D4130F6DB7E78948253A03E76CED6C399C058BB06253B799FD075DF738B7CEE5EF7AF153EFBA54A5A1EB9080A975B30262708B5E9CD283DCC8839CF10C28611B8D69A24A46DD926F755B84FF6C3D004313436C4E3E78A52D8FD8533DC2B1B7AFD1C3134B0AEBB0194844398262D56B442EEA1DD8731FE31FB785C2DFC32728AC502EF85A4A25EA2FA869172BDAE8872DA8EDA79020BF86E291EE8F383CCA7CFD3DAD66C92A734474A2AD7309BDB87C63F4FCD19E0C65912F9F054EB2E7A387CA81AB509E095C7331EE7DAA33E636663E0FF6DB66C3F3812C3CEC115B899FA6621B209E392DCB747F1800718A9ADAD04D48B5617D36AF518EF9A5A76FCCE8CE6BEFE567F1E91DA0FAEF318762B2E3D949C2D08A8544C80A841BF3DF01ACCF58700B804E7568F59F370DB76EEE625A7B380B38E4A1CC24F0DF6FD26C439B34B765DC4E04D6C0325DAF60A1C79057C0D94281E652E2C1CDCDCC304159440571F1B565F0A511647A54123F1C97CDB -20240327144258 2 6 100 7679 2 EC85B1B812727C95C9C6D18B4F5700D62DBF698E4F4663A8C3298C2E301DF351147BB27E17982D2AF86FC969FB517AF57B10D864F23E8604341D97ECE9D33D31CA686CEEF872647B720A3010AFD4B85B0DBA65D3C9200D2C87BE4D4CAC50CAEBE0C92600F73FE5B5FD60D09762105BAA466DEB7809061EE3E4D0621D53DD39F5D7730324DF21FD9871E0BBCEBBB5450DBA4F30CA294BE8AE76D4318F8C543D9E6A032586BC29BE362311B3087657F3A068ED3221BA4EF3FF233C721D261FB9EE8245E171B32FFB8E7BA85ADFE304C784FF306AF7B2C8D9CDE0209AF5592BC33CAE85EAFB662808FA8B45405C4C0ED10DDC3B44C9A69AE6EFC86088D91C137046B2C2133EEAAA55EF5A55D4501B6357FEAC66EF33E521CCBCAA4BA4969EFAF7B41A2059C391AA92A387E75E02E8A018911D13899851C88B81F0592219032EB0538E6CB37E69A8FE2D7E759C7548556FF28B61F3DB0D1D945CF68BEC64497C803A4F8EB9B88F9872963A792480007310840F83966B386681071FAD8E5CF1502B6B2985C39E4D6CE509F086B53594B93A9AE3CA763C5CAD850FD1B1138B88E6741E7198ADC5768CC1737DEB702270FC8DE01042774E36AED88262D1C8B2166F84A3CEB5623B764CD85C808DB607837701D3F5BBEF83D19E927AEEF464079A9ABA5053CB0F2FD0942ABB568ACD050BF682809EAACD695F248D851CA0D7542BE8517BAEE4D0C8E22AA1C76E7650602723DD93A4834F4D87E74EEE8288F17175F481932E5FF012F903DDA99F74B547AF32937C7FD673ED79588C220D8EB60600747A32CFECC4E4E87001E6EEBB855EE56D47AFCD6B820D4130F6DB7E78948253A03E76CED6C399C058BB06253B799FD075DF738B7CEE5EF7AF153EFBA54A5A1EB9080A975B30262708B5E9CD283DCC8839CF10C28611B8D69A24A46DD926F755B84FF6C3D004313436C4E3E78A52D8FD8533DC2B1B7AFD1C3134B0AEBB0194844398262D56B442EEA1DD8731FE31FB785C2DFC32728AC502EF85A4A25EA2FA869172BDAE8872DA8EDA79020BF86E291EE8F383CCA7CFD3DAD66C92A734474A2AD7309BDB87C63F4FCD19E0C65912F9F054EB2E7A387CA81AB509E095C7331EE7DAA33E636663E0FF6DB66C3F3812C3CEC115B899FA6621B209E392DCB747F1800718A9ADAD04D48B5617D36AF518EF9A5A76FCCE8CE6BEFE567F1E91DA0FAEF318762B2E3D949C2D08A8544C80A841BF3DF01ACCF58700B804E7568F59F370DB76EEE625A7B380B38E4A1CC24F0DF6FD26C439B34B765DC4E04D6C0325DAF60A1C79057C0D94281E652E2C1CDCDCC304159440571F1B565F0A511647A54123F48C6AEB -20240327150511 2 6 100 7679 2 EC85B1B812727C95C9C6D18B4F5700D62DBF698E4F4663A8C3298C2E301DF351147BB27E17982D2AF86FC969FB517AF57B10D864F23E8604341D97ECE9D33D31CA686CEEF872647B720A3010AFD4B85B0DBA65D3C9200D2C87BE4D4CAC50CAEBE0C92600F73FE5B5FD60D09762105BAA466DEB7809061EE3E4D0621D53DD39F5D7730324DF21FD9871E0BBCEBBB5450DBA4F30CA294BE8AE76D4318F8C543D9E6A032586BC29BE362311B3087657F3A068ED3221BA4EF3FF233C721D261FB9EE8245E171B32FFB8E7BA85ADFE304C784FF306AF7B2C8D9CDE0209AF5592BC33CAE85EAFB662808FA8B45405C4C0ED10DDC3B44C9A69AE6EFC86088D91C137046B2C2133EEAAA55EF5A55D4501B6357FEAC66EF33E521CCBCAA4BA4969EFAF7B41A2059C391AA92A387E75E02E8A018911D13899851C88B81F0592219032EB0538E6CB37E69A8FE2D7E759C7548556FF28B61F3DB0D1D945CF68BEC64497C803A4F8EB9B88F9872963A792480007310840F83966B386681071FAD8E5CF1502B6B2985C39E4D6CE509F086B53594B93A9AE3CA763C5CAD850FD1B1138B88E6741E7198ADC5768CC1737DEB702270FC8DE01042774E36AED88262D1C8B2166F84A3CEB5623B764CD85C808DB607837701D3F5BBEF83D19E927AEEF464079A9ABA5053CB0F2FD0942ABB568ACD050BF682809EAACD695F248D851CA0D7542BE8517BAEE4D0C8E22AA1C76E7650602723DD93A4834F4D87E74EEE8288F17175F481932E5FF012F903DDA99F74B547AF32937C7FD673ED79588C220D8EB60600747A32CFECC4E4E87001E6EEBB855EE56D47AFCD6B820D4130F6DB7E78948253A03E76CED6C399C058BB06253B799FD075DF738B7CEE5EF7AF153EFBA54A5A1EB9080A975B30262708B5E9CD283DCC8839CF10C28611B8D69A24A46DD926F755B84FF6C3D004313436C4E3E78A52D8FD8533DC2B1B7AFD1C3134B0AEBB0194844398262D56B442EEA1DD8731FE31FB785C2DFC32728AC502EF85A4A25EA2FA869172BDAE8872DA8EDA79020BF86E291EE8F383CCA7CFD3DAD66C92A734474A2AD7309BDB87C63F4FCD19E0C65912F9F054EB2E7A387CA81AB509E095C7331EE7DAA33E636663E0FF6DB66C3F3812C3CEC115B899FA6621B209E392DCB747F1800718A9ADAD04D48B5617D36AF518EF9A5A76FCCE8CE6BEFE567F1E91DA0FAEF318762B2E3D949C2D08A8544C80A841BF3DF01ACCF58700B804E7568F59F370DB76EEE625A7B380B38E4A1CC24F0DF6FD26C439B34B765DC4E04D6C0325DAF60A1C79057C0D94281E652E2C1CDCDCC304159440571F1B565F0A511647A54123F6023BEB -20240327153839 2 6 100 7679 2 EC85B1B812727C95C9C6D18B4F5700D62DBF698E4F4663A8C3298C2E301DF351147BB27E17982D2AF86FC969FB517AF57B10D864F23E8604341D97ECE9D33D31CA686CEEF872647B720A3010AFD4B85B0DBA65D3C9200D2C87BE4D4CAC50CAEBE0C92600F73FE5B5FD60D09762105BAA466DEB7809061EE3E4D0621D53DD39F5D7730324DF21FD9871E0BBCEBBB5450DBA4F30CA294BE8AE76D4318F8C543D9E6A032586BC29BE362311B3087657F3A068ED3221BA4EF3FF233C721D261FB9EE8245E171B32FFB8E7BA85ADFE304C784FF306AF7B2C8D9CDE0209AF5592BC33CAE85EAFB662808FA8B45405C4C0ED10DDC3B44C9A69AE6EFC86088D91C137046B2C2133EEAAA55EF5A55D4501B6357FEAC66EF33E521CCBCAA4BA4969EFAF7B41A2059C391AA92A387E75E02E8A018911D13899851C88B81F0592219032EB0538E6CB37E69A8FE2D7E759C7548556FF28B61F3DB0D1D945CF68BEC64497C803A4F8EB9B88F9872963A792480007310840F83966B386681071FAD8E5CF1502B6B2985C39E4D6CE509F086B53594B93A9AE3CA763C5CAD850FD1B1138B88E6741E7198ADC5768CC1737DEB702270FC8DE01042774E36AED88262D1C8B2166F84A3CEB5623B764CD85C808DB607837701D3F5BBEF83D19E927AEEF464079A9ABA5053CB0F2FD0942ABB568ACD050BF682809EAACD695F248D851CA0D7542BE8517BAEE4D0C8E22AA1C76E7650602723DD93A4834F4D87E74EEE8288F17175F481932E5FF012F903DDA99F74B547AF32937C7FD673ED79588C220D8EB60600747A32CFECC4E4E87001E6EEBB855EE56D47AFCD6B820D4130F6DB7E78948253A03E76CED6C399C058BB06253B799FD075DF738B7CEE5EF7AF153EFBA54A5A1EB9080A975B30262708B5E9CD283DCC8839CF10C28611B8D69A24A46DD926F755B84FF6C3D004313436C4E3E78A52D8FD8533DC2B1B7AFD1C3134B0AEBB0194844398262D56B442EEA1DD8731FE31FB785C2DFC32728AC502EF85A4A25EA2FA869172BDAE8872DA8EDA79020BF86E291EE8F383CCA7CFD3DAD66C92A734474A2AD7309BDB87C63F4FCD19E0C65912F9F054EB2E7A387CA81AB509E095C7331EE7DAA33E636663E0FF6DB66C3F3812C3CEC115B899FA6621B209E392DCB747F1800718A9ADAD04D48B5617D36AF518EF9A5A76FCCE8CE6BEFE567F1E91DA0FAEF318762B2E3D949C2D08A8544C80A841BF3DF01ACCF58700B804E7568F59F370DB76EEE625A7B380B38E4A1CC24F0DF6FD26C439B34B765DC4E04D6C0325DAF60A1C79057C0D94281E652E2C1CDCDCC304159440571F1B565F0A511647A54123F8480A9B -20240327160724 2 6 100 7679 5 EC85B1B812727C95C9C6D18B4F5700D62DBF698E4F4663A8C3298C2E301DF351147BB27E17982D2AF86FC969FB517AF57B10D864F23E8604341D97ECE9D33D31CA686CEEF872647B720A3010AFD4B85B0DBA65D3C9200D2C87BE4D4CAC50CAEBE0C92600F73FE5B5FD60D09762105BAA466DEB7809061EE3E4D0621D53DD39F5D7730324DF21FD9871E0BBCEBBB5450DBA4F30CA294BE8AE76D4318F8C543D9E6A032586BC29BE362311B3087657F3A068ED3221BA4EF3FF233C721D261FB9EE8245E171B32FFB8E7BA85ADFE304C784FF306AF7B2C8D9CDE0209AF5592BC33CAE85EAFB662808FA8B45405C4C0ED10DDC3B44C9A69AE6EFC86088D91C137046B2C2133EEAAA55EF5A55D4501B6357FEAC66EF33E521CCBCAA4BA4969EFAF7B41A2059C391AA92A387E75E02E8A018911D13899851C88B81F0592219032EB0538E6CB37E69A8FE2D7E759C7548556FF28B61F3DB0D1D945CF68BEC64497C803A4F8EB9B88F9872963A792480007310840F83966B386681071FAD8E5CF1502B6B2985C39E4D6CE509F086B53594B93A9AE3CA763C5CAD850FD1B1138B88E6741E7198ADC5768CC1737DEB702270FC8DE01042774E36AED88262D1C8B2166F84A3CEB5623B764CD85C808DB607837701D3F5BBEF83D19E927AEEF464079A9ABA5053CB0F2FD0942ABB568ACD050BF682809EAACD695F248D851CA0D7542BE8517BAEE4D0C8E22AA1C76E7650602723DD93A4834F4D87E74EEE8288F17175F481932E5FF012F903DDA99F74B547AF32937C7FD673ED79588C220D8EB60600747A32CFECC4E4E87001E6EEBB855EE56D47AFCD6B820D4130F6DB7E78948253A03E76CED6C399C058BB06253B799FD075DF738B7CEE5EF7AF153EFBA54A5A1EB9080A975B30262708B5E9CD283DCC8839CF10C28611B8D69A24A46DD926F755B84FF6C3D004313436C4E3E78A52D8FD8533DC2B1B7AFD1C3134B0AEBB0194844398262D56B442EEA1DD8731FE31FB785C2DFC32728AC502EF85A4A25EA2FA869172BDAE8872DA8EDA79020BF86E291EE8F383CCA7CFD3DAD66C92A734474A2AD7309BDB87C63F4FCD19E0C65912F9F054EB2E7A387CA81AB509E095C7331EE7DAA33E636663E0FF6DB66C3F3812C3CEC115B899FA6621B209E392DCB747F1800718A9ADAD04D48B5617D36AF518EF9A5A76FCCE8CE6BEFE567F1E91DA0FAEF318762B2E3D949C2D08A8544C80A841BF3DF01ACCF58700B804E7568F59F370DB76EEE625A7B380B38E4A1CC24F0DF6FD26C439B34B765DC4E04D6C0325DAF60A1C79057C0D94281E652E2C1CDCDCC304159440571F1B565F0A511647A54123FA2AE0EF -20240327170619 2 6 100 7679 2 EC85B1B812727C95C9C6D18B4F5700D62DBF698E4F4663A8C3298C2E301DF351147BB27E17982D2AF86FC969FB517AF57B10D864F23E8604341D97ECE9D33D31CA686CEEF872647B720A3010AFD4B85B0DBA65D3C9200D2C87BE4D4CAC50CAEBE0C92600F73FE5B5FD60D09762105BAA466DEB7809061EE3E4D0621D53DD39F5D7730324DF21FD9871E0BBCEBBB5450DBA4F30CA294BE8AE76D4318F8C543D9E6A032586BC29BE362311B3087657F3A068ED3221BA4EF3FF233C721D261FB9EE8245E171B32FFB8E7BA85ADFE304C784FF306AF7B2C8D9CDE0209AF5592BC33CAE85EAFB662808FA8B45405C4C0ED10DDC3B44C9A69AE6EFC86088D91C137046B2C2133EEAAA55EF5A55D4501B6357FEAC66EF33E521CCBCAA4BA4969EFAF7B41A2059C391AA92A387E75E02E8A018911D13899851C88B81F0592219032EB0538E6CB37E69A8FE2D7E759C7548556FF28B61F3DB0D1D945CF68BEC64497C803A4F8EB9B88F9872963A792480007310840F83966B386681071FAD8E5CF1502B6B2985C39E4D6CE509F086B53594B93A9AE3CA763C5CAD850FD1B1138B88E6741E7198ADC5768CC1737DEB702270FC8DE01042774E36AED88262D1C8B2166F84A3CEB5623B764CD85C808DB607837701D3F5BBEF83D19E927AEEF464079A9ABA5053CB0F2FD0942ABB568ACD050BF682809EAACD695F248D851CA0D7542BE8517BAEE4D0C8E22AA1C76E7650602723DD93A4834F4D87E74EEE8288F17175F481932E5FF012F903DDA99F74B547AF32937C7FD673ED79588C220D8EB60600747A32CFECC4E4E87001E6EEBB855EE56D47AFCD6B820D4130F6DB7E78948253A03E76CED6C399C058BB06253B799FD075DF738B7CEE5EF7AF153EFBA54A5A1EB9080A975B30262708B5E9CD283DCC8839CF10C28611B8D69A24A46DD926F755B84FF6C3D004313436C4E3E78A52D8FD8533DC2B1B7AFD1C3134B0AEBB0194844398262D56B442EEA1DD8731FE31FB785C2DFC32728AC502EF85A4A25EA2FA869172BDAE8872DA8EDA79020BF86E291EE8F383CCA7CFD3DAD66C92A734474A2AD7309BDB87C63F4FCD19E0C65912F9F054EB2E7A387CA81AB509E095C7331EE7DAA33E636663E0FF6DB66C3F3812C3CEC115B899FA6621B209E392DCB747F1800718A9ADAD04D48B5617D36AF518EF9A5A76FCCE8CE6BEFE567F1E91DA0FAEF318762B2E3D949C2D08A8544C80A841BF3DF01ACCF58700B804E7568F59F370DB76EEE625A7B380B38E4A1CC24F0DF6FD26C439B34B765DC4E04D6C0325DAF60A1C79057C0D94281E652E2C1CDCDCC304159440571F1B565F0A511647A54123FE1F90CB -20240327201733 2 6 100 7679 5 EC85B1B812727C95C9C6D18B4F5700D62DBF698E4F4663A8C3298C2E301DF351147BB27E17982D2AF86FC969FB517AF57B10D864F23E8604341D97ECE9D33D31CA686CEEF872647B720A3010AFD4B85B0DBA65D3C9200D2C87BE4D4CAC50CAEBE0C92600F73FE5B5FD60D09762105BAA466DEB7809061EE3E4D0621D53DD39F5D7730324DF21FD9871E0BBCEBBB5450DBA4F30CA294BE8AE76D4318F8C543D9E6A032586BC29BE362311B3087657F3A068ED3221BA4EF3FF233C721D261FB9EE8245E171B32FFB8E7BA85ADFE304C784FF306AF7B2C8D9CDE0209AF5592BC33CAE85EAFB662808FA8B45405C4C0ED10DDC3B44C9A69AE6EFC86088D91C137046B2C2133EEAAA55EF5A55D4501B6357FEAC66EF33E521CCBCAA4BA4969EFAF7B41A2059C391AA92A387E75E02E8A018911D13899851C88B81F0592219032EB0538E6CB37E69A8FE2D7E759C7548556FF28B61F3DB0D1D945CF68BEC64497C803A4F8EB9B88F9872963A792480007310840F83966B386681071FAD8E5CF1502B6B2985C39E4D6CE509F086B53594B93A9AE3CA763C5CAD850FD1B1138B88E6741E7198ADC5768CC1737DEB702270FC8DE01042774E36AED88262D1C8B2166F84A3CEB5623B764CD85C808DB607837701D3F5BBEF83D19E927AEEF464079A9ABA5053CB0F2FD0942ABB568ACD050BF682809EAACD695F248D851CA0D7542BE8517BAEE4D0C8E22AA1C76E7650602723DD93A4834F4D87E74EEE8288F17175F481932E5FF012F903DDA99F74B547AF32937C7FD673ED79588C220D8EB60600747A32CFECC4E4E87001E6EEBB855EE56D47AFCD6B820D4130F6DB7E78948253A03E76CED6C399C058BB06253B799FD075DF738B7CEE5EF7AF153EFBA54A5A1EB9080A975B30262708B5E9CD283DCC8839CF10C28611B8D69A24A46DD926F755B84FF6C3D004313436C4E3E78A52D8FD8533DC2B1B7AFD1C3134B0AEBB0194844398262D56B442EEA1DD8731FE31FB785C2DFC32728AC502EF85A4A25EA2FA869172BDAE8872DA8EDA79020BF86E291EE8F383CCA7CFD3DAD66C92A734474A2AD7309BDB87C63F4FCD19E0C65912F9F054EB2E7A387CA81AB509E095C7331EE7DAA33E636663E0FF6DB66C3F3812C3CEC115B899FA6621B209E392DCB747F1800718A9ADAD04D48B5617D36AF518EF9A5A76FCCE8CE6BEFE567F1E91DA0FAEF318762B2E3D949C2D08A8544C80A841BF3DF01ACCF58700B804E7568F59F370DB76EEE625A7B380B38E4A1CC24F0DF6FD26C439B34B765DC4E04D6C0325DAF60A1C79057C0D94281E652E2C1CDCDCC304159440571F1B565F0A511647A541240B20240F -20240327202608 2 6 100 7679 5 EC85B1B812727C95C9C6D18B4F5700D62DBF698E4F4663A8C3298C2E301DF351147BB27E17982D2AF86FC969FB517AF57B10D864F23E8604341D97ECE9D33D31CA686CEEF872647B720A3010AFD4B85B0DBA65D3C9200D2C87BE4D4CAC50CAEBE0C92600F73FE5B5FD60D09762105BAA466DEB7809061EE3E4D0621D53DD39F5D7730324DF21FD9871E0BBCEBBB5450DBA4F30CA294BE8AE76D4318F8C543D9E6A032586BC29BE362311B3087657F3A068ED3221BA4EF3FF233C721D261FB9EE8245E171B32FFB8E7BA85ADFE304C784FF306AF7B2C8D9CDE0209AF5592BC33CAE85EAFB662808FA8B45405C4C0ED10DDC3B44C9A69AE6EFC86088D91C137046B2C2133EEAAA55EF5A55D4501B6357FEAC66EF33E521CCBCAA4BA4969EFAF7B41A2059C391AA92A387E75E02E8A018911D13899851C88B81F0592219032EB0538E6CB37E69A8FE2D7E759C7548556FF28B61F3DB0D1D945CF68BEC64497C803A4F8EB9B88F9872963A792480007310840F83966B386681071FAD8E5CF1502B6B2985C39E4D6CE509F086B53594B93A9AE3CA763C5CAD850FD1B1138B88E6741E7198ADC5768CC1737DEB702270FC8DE01042774E36AED88262D1C8B2166F84A3CEB5623B764CD85C808DB607837701D3F5BBEF83D19E927AEEF464079A9ABA5053CB0F2FD0942ABB568ACD050BF682809EAACD695F248D851CA0D7542BE8517BAEE4D0C8E22AA1C76E7650602723DD93A4834F4D87E74EEE8288F17175F481932E5FF012F903DDA99F74B547AF32937C7FD673ED79588C220D8EB60600747A32CFECC4E4E87001E6EEBB855EE56D47AFCD6B820D4130F6DB7E78948253A03E76CED6C399C058BB06253B799FD075DF738B7CEE5EF7AF153EFBA54A5A1EB9080A975B30262708B5E9CD283DCC8839CF10C28611B8D69A24A46DD926F755B84FF6C3D004313436C4E3E78A52D8FD8533DC2B1B7AFD1C3134B0AEBB0194844398262D56B442EEA1DD8731FE31FB785C2DFC32728AC502EF85A4A25EA2FA869172BDAE8872DA8EDA79020BF86E291EE8F383CCA7CFD3DAD66C92A734474A2AD7309BDB87C63F4FCD19E0C65912F9F054EB2E7A387CA81AB509E095C7331EE7DAA33E636663E0FF6DB66C3F3812C3CEC115B899FA6621B209E392DCB747F1800718A9ADAD04D48B5617D36AF518EF9A5A76FCCE8CE6BEFE567F1E91DA0FAEF318762B2E3D949C2D08A8544C80A841BF3DF01ACCF58700B804E7568F59F370DB76EEE625A7B380B38E4A1CC24F0DF6FD26C439B34B765DC4E04D6C0325DAF60A1C79057C0D94281E652E2C1CDCDCC304159440571F1B565F0A511647A541240BACBC77 -20240327204230 2 6 100 7679 2 EC85B1B812727C95C9C6D18B4F5700D62DBF698E4F4663A8C3298C2E301DF351147BB27E17982D2AF86FC969FB517AF57B10D864F23E8604341D97ECE9D33D31CA686CEEF872647B720A3010AFD4B85B0DBA65D3C9200D2C87BE4D4CAC50CAEBE0C92600F73FE5B5FD60D09762105BAA466DEB7809061EE3E4D0621D53DD39F5D7730324DF21FD9871E0BBCEBBB5450DBA4F30CA294BE8AE76D4318F8C543D9E6A032586BC29BE362311B3087657F3A068ED3221BA4EF3FF233C721D261FB9EE8245E171B32FFB8E7BA85ADFE304C784FF306AF7B2C8D9CDE0209AF5592BC33CAE85EAFB662808FA8B45405C4C0ED10DDC3B44C9A69AE6EFC86088D91C137046B2C2133EEAAA55EF5A55D4501B6357FEAC66EF33E521CCBCAA4BA4969EFAF7B41A2059C391AA92A387E75E02E8A018911D13899851C88B81F0592219032EB0538E6CB37E69A8FE2D7E759C7548556FF28B61F3DB0D1D945CF68BEC64497C803A4F8EB9B88F9872963A792480007310840F83966B386681071FAD8E5CF1502B6B2985C39E4D6CE509F086B53594B93A9AE3CA763C5CAD850FD1B1138B88E6741E7198ADC5768CC1737DEB702270FC8DE01042774E36AED88262D1C8B2166F84A3CEB5623B764CD85C808DB607837701D3F5BBEF83D19E927AEEF464079A9ABA5053CB0F2FD0942ABB568ACD050BF682809EAACD695F248D851CA0D7542BE8517BAEE4D0C8E22AA1C76E7650602723DD93A4834F4D87E74EEE8288F17175F481932E5FF012F903DDA99F74B547AF32937C7FD673ED79588C220D8EB60600747A32CFECC4E4E87001E6EEBB855EE56D47AFCD6B820D4130F6DB7E78948253A03E76CED6C399C058BB06253B799FD075DF738B7CEE5EF7AF153EFBA54A5A1EB9080A975B30262708B5E9CD283DCC8839CF10C28611B8D69A24A46DD926F755B84FF6C3D004313436C4E3E78A52D8FD8533DC2B1B7AFD1C3134B0AEBB0194844398262D56B442EEA1DD8731FE31FB785C2DFC32728AC502EF85A4A25EA2FA869172BDAE8872DA8EDA79020BF86E291EE8F383CCA7CFD3DAD66C92A734474A2AD7309BDB87C63F4FCD19E0C65912F9F054EB2E7A387CA81AB509E095C7331EE7DAA33E636663E0FF6DB66C3F3812C3CEC115B899FA6621B209E392DCB747F1800718A9ADAD04D48B5617D36AF518EF9A5A76FCCE8CE6BEFE567F1E91DA0FAEF318762B2E3D949C2D08A8544C80A841BF3DF01ACCF58700B804E7568F59F370DB76EEE625A7B380B38E4A1CC24F0DF6FD26C439B34B765DC4E04D6C0325DAF60A1C79057C0D94281E652E2C1CDCDCC304159440571F1B565F0A511647A541240CCB39CB -20240327220340 2 6 100 7679 2 EC85B1B812727C95C9C6D18B4F5700D62DBF698E4F4663A8C3298C2E301DF351147BB27E17982D2AF86FC969FB517AF57B10D864F23E8604341D97ECE9D33D31CA686CEEF872647B720A3010AFD4B85B0DBA65D3C9200D2C87BE4D4CAC50CAEBE0C92600F73FE5B5FD60D09762105BAA466DEB7809061EE3E4D0621D53DD39F5D7730324DF21FD9871E0BBCEBBB5450DBA4F30CA294BE8AE76D4318F8C543D9E6A032586BC29BE362311B3087657F3A068ED3221BA4EF3FF233C721D261FB9EE8245E171B32FFB8E7BA85ADFE304C784FF306AF7B2C8D9CDE0209AF5592BC33CAE85EAFB662808FA8B45405C4C0ED10DDC3B44C9A69AE6EFC86088D91C137046B2C2133EEAAA55EF5A55D4501B6357FEAC66EF33E521CCBCAA4BA4969EFAF7B41A2059C391AA92A387E75E02E8A018911D13899851C88B81F0592219032EB0538E6CB37E69A8FE2D7E759C7548556FF28B61F3DB0D1D945CF68BEC64497C803A4F8EB9B88F9872963A792480007310840F83966B386681071FAD8E5CF1502B6B2985C39E4D6CE509F086B53594B93A9AE3CA763C5CAD850FD1B1138B88E6741E7198ADC5768CC1737DEB702270FC8DE01042774E36AED88262D1C8B2166F84A3CEB5623B764CD85C808DB607837701D3F5BBEF83D19E927AEEF464079A9ABA5053CB0F2FD0942ABB568ACD050BF682809EAACD695F248D851CA0D7542BE8517BAEE4D0C8E22AA1C76E7650602723DD93A4834F4D87E74EEE8288F17175F481932E5FF012F903DDA99F74B547AF32937C7FD673ED79588C220D8EB60600747A32CFECC4E4E87001E6EEBB855EE56D47AFCD6B820D4130F6DB7E78948253A03E76CED6C399C058BB06253B799FD075DF738B7CEE5EF7AF153EFBA54A5A1EB9080A975B30262708B5E9CD283DCC8839CF10C28611B8D69A24A46DD926F755B84FF6C3D004313436C4E3E78A52D8FD8533DC2B1B7AFD1C3134B0AEBB0194844398262D56B442EEA1DD8731FE31FB785C2DFC32728AC502EF85A4A25EA2FA869172BDAE8872DA8EDA79020BF86E291EE8F383CCA7CFD3DAD66C92A734474A2AD7309BDB87C63F4FCD19E0C65912F9F054EB2E7A387CA81AB509E095C7331EE7DAA33E636663E0FF6DB66C3F3812C3CEC115B899FA6621B209E392DCB747F1800718A9ADAD04D48B5617D36AF518EF9A5A76FCCE8CE6BEFE567F1E91DA0FAEF318762B2E3D949C2D08A8544C80A841BF3DF01ACCF58700B804E7568F59F370DB76EEE625A7B380B38E4A1CC24F0DF6FD26C439B34B765DC4E04D6C0325DAF60A1C79057C0D94281E652E2C1CDCDCC304159440571F1B565F0A511647A5412412509EF3 -20240327230112 2 6 100 7679 5 EC85B1B812727C95C9C6D18B4F5700D62DBF698E4F4663A8C3298C2E301DF351147BB27E17982D2AF86FC969FB517AF57B10D864F23E8604341D97ECE9D33D31CA686CEEF872647B720A3010AFD4B85B0DBA65D3C9200D2C87BE4D4CAC50CAEBE0C92600F73FE5B5FD60D09762105BAA466DEB7809061EE3E4D0621D53DD39F5D7730324DF21FD9871E0BBCEBBB5450DBA4F30CA294BE8AE76D4318F8C543D9E6A032586BC29BE362311B3087657F3A068ED3221BA4EF3FF233C721D261FB9EE8245E171B32FFB8E7BA85ADFE304C784FF306AF7B2C8D9CDE0209AF5592BC33CAE85EAFB662808FA8B45405C4C0ED10DDC3B44C9A69AE6EFC86088D91C137046B2C2133EEAAA55EF5A55D4501B6357FEAC66EF33E521CCBCAA4BA4969EFAF7B41A2059C391AA92A387E75E02E8A018911D13899851C88B81F0592219032EB0538E6CB37E69A8FE2D7E759C7548556FF28B61F3DB0D1D945CF68BEC64497C803A4F8EB9B88F9872963A792480007310840F83966B386681071FAD8E5CF1502B6B2985C39E4D6CE509F086B53594B93A9AE3CA763C5CAD850FD1B1138B88E6741E7198ADC5768CC1737DEB702270FC8DE01042774E36AED88262D1C8B2166F84A3CEB5623B764CD85C808DB607837701D3F5BBEF83D19E927AEEF464079A9ABA5053CB0F2FD0942ABB568ACD050BF682809EAACD695F248D851CA0D7542BE8517BAEE4D0C8E22AA1C76E7650602723DD93A4834F4D87E74EEE8288F17175F481932E5FF012F903DDA99F74B547AF32937C7FD673ED79588C220D8EB60600747A32CFECC4E4E87001E6EEBB855EE56D47AFCD6B820D4130F6DB7E78948253A03E76CED6C399C058BB06253B799FD075DF738B7CEE5EF7AF153EFBA54A5A1EB9080A975B30262708B5E9CD283DCC8839CF10C28611B8D69A24A46DD926F755B84FF6C3D004313436C4E3E78A52D8FD8533DC2B1B7AFD1C3134B0AEBB0194844398262D56B442EEA1DD8731FE31FB785C2DFC32728AC502EF85A4A25EA2FA869172BDAE8872DA8EDA79020BF86E291EE8F383CCA7CFD3DAD66C92A734474A2AD7309BDB87C63F4FCD19E0C65912F9F054EB2E7A387CA81AB509E095C7331EE7DAA33E636663E0FF6DB66C3F3812C3CEC115B899FA6621B209E392DCB747F1800718A9ADAD04D48B5617D36AF518EF9A5A76FCCE8CE6BEFE567F1E91DA0FAEF318762B2E3D949C2D08A8544C80A841BF3DF01ACCF58700B804E7568F59F370DB76EEE625A7B380B38E4A1CC24F0DF6FD26C439B34B765DC4E04D6C0325DAF60A1C79057C0D94281E652E2C1CDCDCC304159440571F1B565F0A511647A54124164279BF -20240327231350 2 6 100 7679 5 EC85B1B812727C95C9C6D18B4F5700D62DBF698E4F4663A8C3298C2E301DF351147BB27E17982D2AF86FC969FB517AF57B10D864F23E8604341D97ECE9D33D31CA686CEEF872647B720A3010AFD4B85B0DBA65D3C9200D2C87BE4D4CAC50CAEBE0C92600F73FE5B5FD60D09762105BAA466DEB7809061EE3E4D0621D53DD39F5D7730324DF21FD9871E0BBCEBBB5450DBA4F30CA294BE8AE76D4318F8C543D9E6A032586BC29BE362311B3087657F3A068ED3221BA4EF3FF233C721D261FB9EE8245E171B32FFB8E7BA85ADFE304C784FF306AF7B2C8D9CDE0209AF5592BC33CAE85EAFB662808FA8B45405C4C0ED10DDC3B44C9A69AE6EFC86088D91C137046B2C2133EEAAA55EF5A55D4501B6357FEAC66EF33E521CCBCAA4BA4969EFAF7B41A2059C391AA92A387E75E02E8A018911D13899851C88B81F0592219032EB0538E6CB37E69A8FE2D7E759C7548556FF28B61F3DB0D1D945CF68BEC64497C803A4F8EB9B88F9872963A792480007310840F83966B386681071FAD8E5CF1502B6B2985C39E4D6CE509F086B53594B93A9AE3CA763C5CAD850FD1B1138B88E6741E7198ADC5768CC1737DEB702270FC8DE01042774E36AED88262D1C8B2166F84A3CEB5623B764CD85C808DB607837701D3F5BBEF83D19E927AEEF464079A9ABA5053CB0F2FD0942ABB568ACD050BF682809EAACD695F248D851CA0D7542BE8517BAEE4D0C8E22AA1C76E7650602723DD93A4834F4D87E74EEE8288F17175F481932E5FF012F903DDA99F74B547AF32937C7FD673ED79588C220D8EB60600747A32CFECC4E4E87001E6EEBB855EE56D47AFCD6B820D4130F6DB7E78948253A03E76CED6C399C058BB06253B799FD075DF738B7CEE5EF7AF153EFBA54A5A1EB9080A975B30262708B5E9CD283DCC8839CF10C28611B8D69A24A46DD926F755B84FF6C3D004313436C4E3E78A52D8FD8533DC2B1B7AFD1C3134B0AEBB0194844398262D56B442EEA1DD8731FE31FB785C2DFC32728AC502EF85A4A25EA2FA869172BDAE8872DA8EDA79020BF86E291EE8F383CCA7CFD3DAD66C92A734474A2AD7309BDB87C63F4FCD19E0C65912F9F054EB2E7A387CA81AB509E095C7331EE7DAA33E636663E0FF6DB66C3F3812C3CEC115B899FA6621B209E392DCB747F1800718A9ADAD04D48B5617D36AF518EF9A5A76FCCE8CE6BEFE567F1E91DA0FAEF318762B2E3D949C2D08A8544C80A841BF3DF01ACCF58700B804E7568F59F370DB76EEE625A7B380B38E4A1CC24F0DF6FD26C439B34B765DC4E04D6C0325DAF60A1C79057C0D94281E652E2C1CDCDCC304159440571F1B565F0A511647A5412417159137 -20240328011850 2 6 100 7679 5 EC85B1B812727C95C9C6D18B4F5700D62DBF698E4F4663A8C3298C2E301DF351147BB27E17982D2AF86FC969FB517AF57B10D864F23E8604341D97ECE9D33D31CA686CEEF872647B720A3010AFD4B85B0DBA65D3C9200D2C87BE4D4CAC50CAEBE0C92600F73FE5B5FD60D09762105BAA466DEB7809061EE3E4D0621D53DD39F5D7730324DF21FD9871E0BBCEBBB5450DBA4F30CA294BE8AE76D4318F8C543D9E6A032586BC29BE362311B3087657F3A068ED3221BA4EF3FF233C721D261FB9EE8245E171B32FFB8E7BA85ADFE304C784FF306AF7B2C8D9CDE0209AF5592BC33CAE85EAFB662808FA8B45405C4C0ED10DDC3B44C9A69AE6EFC86088D91C137046B2C2133EEAAA55EF5A55D4501B6357FEAC66EF33E521CCBCAA4BA4969EFAF7B41A2059C391AA92A387E75E02E8A018911D13899851C88B81F0592219032EB0538E6CB37E69A8FE2D7E759C7548556FF28B61F3DB0D1D945CF68BEC64497C803A4F8EB9B88F9872963A792480007310840F83966B386681071FAD8E5CF1502B6B2985C39E4D6CE509F086B53594B93A9AE3CA763C5CAD850FD1B1138B88E6741E7198ADC5768CC1737DEB702270FC8DE01042774E36AED88262D1C8B2166F84A3CEB5623B764CD85C808DB607837701D3F5BBEF83D19E927AEEF464079A9ABA5053CB0F2FD0942ABB568ACD050BF682809EAACD695F248D851CA0D7542BE8517BAEE4D0C8E22AA1C76E7650602723DD93A4834F4D87E74EEE8288F17175F481932E5FF012F903DDA99F74B547AF32937C7FD673ED79588C220D8EB60600747A32CFECC4E4E87001E6EEBB855EE56D47AFCD6B820D4130F6DB7E78948253A03E76CED6C399C058BB06253B799FD075DF738B7CEE5EF7AF153EFBA54A5A1EB9080A975B30262708B5E9CD283DCC8839CF10C28611B8D69A24A46DD926F755B84FF6C3D004313436C4E3E78A52D8FD8533DC2B1B7AFD1C3134B0AEBB0194844398262D56B442EEA1DD8731FE31FB785C2DFC32728AC502EF85A4A25EA2FA869172BDAE8872DA8EDA79020BF86E291EE8F383CCA7CFD3DAD66C92A734474A2AD7309BDB87C63F4FCD19E0C65912F9F054EB2E7A387CA81AB509E095C7331EE7DAA33E636663E0FF6DB66C3F3812C3CEC115B899FA6621B209E392DCB747F1800718A9ADAD04D48B5617D36AF518EF9A5A76FCCE8CE6BEFE567F1E91DA0FAEF318762B2E3D949C2D08A8544C80A841BF3DF01ACCF58700B804E7568F59F370DB76EEE625A7B380B38E4A1CC24F0DF6FD26C439B34B765DC4E04D6C0325DAF60A1C79057C0D94281E652E2C1CDCDCC304159440571F1B565F0A511647A541241F8FAF0F -20240328020121 2 6 100 7679 2 EC85B1B812727C95C9C6D18B4F5700D62DBF698E4F4663A8C3298C2E301DF351147BB27E17982D2AF86FC969FB517AF57B10D864F23E8604341D97ECE9D33D31CA686CEEF872647B720A3010AFD4B85B0DBA65D3C9200D2C87BE4D4CAC50CAEBE0C92600F73FE5B5FD60D09762105BAA466DEB7809061EE3E4D0621D53DD39F5D7730324DF21FD9871E0BBCEBBB5450DBA4F30CA294BE8AE76D4318F8C543D9E6A032586BC29BE362311B3087657F3A068ED3221BA4EF3FF233C721D261FB9EE8245E171B32FFB8E7BA85ADFE304C784FF306AF7B2C8D9CDE0209AF5592BC33CAE85EAFB662808FA8B45405C4C0ED10DDC3B44C9A69AE6EFC86088D91C137046B2C2133EEAAA55EF5A55D4501B6357FEAC66EF33E521CCBCAA4BA4969EFAF7B41A2059C391AA92A387E75E02E8A018911D13899851C88B81F0592219032EB0538E6CB37E69A8FE2D7E759C7548556FF28B61F3DB0D1D945CF68BEC64497C803A4F8EB9B88F9872963A792480007310840F83966B386681071FAD8E5CF1502B6B2985C39E4D6CE509F086B53594B93A9AE3CA763C5CAD850FD1B1138B88E6741E7198ADC5768CC1737DEB702270FC8DE01042774E36AED88262D1C8B2166F84A3CEB5623B764CD85C808DB607837701D3F5BBEF83D19E927AEEF464079A9ABA5053CB0F2FD0942ABB568ACD050BF682809EAACD695F248D851CA0D7542BE8517BAEE4D0C8E22AA1C76E7650602723DD93A4834F4D87E74EEE8288F17175F481932E5FF012F903DDA99F74B547AF32937C7FD673ED79588C220D8EB60600747A32CFECC4E4E87001E6EEBB855EE56D47AFCD6B820D4130F6DB7E78948253A03E76CED6C399C058BB06253B799FD075DF738B7CEE5EF7AF153EFBA54A5A1EB9080A975B30262708B5E9CD283DCC8839CF10C28611B8D69A24A46DD926F755B84FF6C3D004313436C4E3E78A52D8FD8533DC2B1B7AFD1C3134B0AEBB0194844398262D56B442EEA1DD8731FE31FB785C2DFC32728AC502EF85A4A25EA2FA869172BDAE8872DA8EDA79020BF86E291EE8F383CCA7CFD3DAD66C92A734474A2AD7309BDB87C63F4FCD19E0C65912F9F054EB2E7A387CA81AB509E095C7331EE7DAA33E636663E0FF6DB66C3F3812C3CEC115B899FA6621B209E392DCB747F1800718A9ADAD04D48B5617D36AF518EF9A5A76FCCE8CE6BEFE567F1E91DA0FAEF318762B2E3D949C2D08A8544C80A841BF3DF01ACCF58700B804E7568F59F370DB76EEE625A7B380B38E4A1CC24F0DF6FD26C439B34B765DC4E04D6C0325DAF60A1C79057C0D94281E652E2C1CDCDCC304159440571F1B565F0A511647A541242268881B -20240328020416 2 6 100 7679 5 EC85B1B812727C95C9C6D18B4F5700D62DBF698E4F4663A8C3298C2E301DF351147BB27E17982D2AF86FC969FB517AF57B10D864F23E8604341D97ECE9D33D31CA686CEEF872647B720A3010AFD4B85B0DBA65D3C9200D2C87BE4D4CAC50CAEBE0C92600F73FE5B5FD60D09762105BAA466DEB7809061EE3E4D0621D53DD39F5D7730324DF21FD9871E0BBCEBBB5450DBA4F30CA294BE8AE76D4318F8C543D9E6A032586BC29BE362311B3087657F3A068ED3221BA4EF3FF233C721D261FB9EE8245E171B32FFB8E7BA85ADFE304C784FF306AF7B2C8D9CDE0209AF5592BC33CAE85EAFB662808FA8B45405C4C0ED10DDC3B44C9A69AE6EFC86088D91C137046B2C2133EEAAA55EF5A55D4501B6357FEAC66EF33E521CCBCAA4BA4969EFAF7B41A2059C391AA92A387E75E02E8A018911D13899851C88B81F0592219032EB0538E6CB37E69A8FE2D7E759C7548556FF28B61F3DB0D1D945CF68BEC64497C803A4F8EB9B88F9872963A792480007310840F83966B386681071FAD8E5CF1502B6B2985C39E4D6CE509F086B53594B93A9AE3CA763C5CAD850FD1B1138B88E6741E7198ADC5768CC1737DEB702270FC8DE01042774E36AED88262D1C8B2166F84A3CEB5623B764CD85C808DB607837701D3F5BBEF83D19E927AEEF464079A9ABA5053CB0F2FD0942ABB568ACD050BF682809EAACD695F248D851CA0D7542BE8517BAEE4D0C8E22AA1C76E7650602723DD93A4834F4D87E74EEE8288F17175F481932E5FF012F903DDA99F74B547AF32937C7FD673ED79588C220D8EB60600747A32CFECC4E4E87001E6EEBB855EE56D47AFCD6B820D4130F6DB7E78948253A03E76CED6C399C058BB06253B799FD075DF738B7CEE5EF7AF153EFBA54A5A1EB9080A975B30262708B5E9CD283DCC8839CF10C28611B8D69A24A46DD926F755B84FF6C3D004313436C4E3E78A52D8FD8533DC2B1B7AFD1C3134B0AEBB0194844398262D56B442EEA1DD8731FE31FB785C2DFC32728AC502EF85A4A25EA2FA869172BDAE8872DA8EDA79020BF86E291EE8F383CCA7CFD3DAD66C92A734474A2AD7309BDB87C63F4FCD19E0C65912F9F054EB2E7A387CA81AB509E095C7331EE7DAA33E636663E0FF6DB66C3F3812C3CEC115B899FA6621B209E392DCB747F1800718A9ADAD04D48B5617D36AF518EF9A5A76FCCE8CE6BEFE567F1E91DA0FAEF318762B2E3D949C2D08A8544C80A841BF3DF01ACCF58700B804E7568F59F370DB76EEE625A7B380B38E4A1CC24F0DF6FD26C439B34B765DC4E04D6C0325DAF60A1C79057C0D94281E652E2C1CDCDCC304159440571F1B565F0A511647A5412422921477 -20240328035516 2 6 100 7679 2 EC85B1B812727C95C9C6D18B4F5700D62DBF698E4F4663A8C3298C2E301DF351147BB27E17982D2AF86FC969FB517AF57B10D864F23E8604341D97ECE9D33D31CA686CEEF872647B720A3010AFD4B85B0DBA65D3C9200D2C87BE4D4CAC50CAEBE0C92600F73FE5B5FD60D09762105BAA466DEB7809061EE3E4D0621D53DD39F5D7730324DF21FD9871E0BBCEBBB5450DBA4F30CA294BE8AE76D4318F8C543D9E6A032586BC29BE362311B3087657F3A068ED3221BA4EF3FF233C721D261FB9EE8245E171B32FFB8E7BA85ADFE304C784FF306AF7B2C8D9CDE0209AF5592BC33CAE85EAFB662808FA8B45405C4C0ED10DDC3B44C9A69AE6EFC86088D91C137046B2C2133EEAAA55EF5A55D4501B6357FEAC66EF33E521CCBCAA4BA4969EFAF7B41A2059C391AA92A387E75E02E8A018911D13899851C88B81F0592219032EB0538E6CB37E69A8FE2D7E759C7548556FF28B61F3DB0D1D945CF68BEC64497C803A4F8EB9B88F9872963A792480007310840F83966B386681071FAD8E5CF1502B6B2985C39E4D6CE509F086B53594B93A9AE3CA763C5CAD850FD1B1138B88E6741E7198ADC5768CC1737DEB702270FC8DE01042774E36AED88262D1C8B2166F84A3CEB5623B764CD85C808DB607837701D3F5BBEF83D19E927AEEF464079A9ABA5053CB0F2FD0942ABB568ACD050BF682809EAACD695F248D851CA0D7542BE8517BAEE4D0C8E22AA1C76E7650602723DD93A4834F4D87E74EEE8288F17175F481932E5FF012F903DDA99F74B547AF32937C7FD673ED79588C220D8EB60600747A32CFECC4E4E87001E6EEBB855EE56D47AFCD6B820D4130F6DB7E78948253A03E76CED6C399C058BB06253B799FD075DF738B7CEE5EF7AF153EFBA54A5A1EB9080A975B30262708B5E9CD283DCC8839CF10C28611B8D69A24A46DD926F755B84FF6C3D004313436C4E3E78A52D8FD8533DC2B1B7AFD1C3134B0AEBB0194844398262D56B442EEA1DD8731FE31FB785C2DFC32728AC502EF85A4A25EA2FA869172BDAE8872DA8EDA79020BF86E291EE8F383CCA7CFD3DAD66C92A734474A2AD7309BDB87C63F4FCD19E0C65912F9F054EB2E7A387CA81AB509E095C7331EE7DAA33E636663E0FF6DB66C3F3812C3CEC115B899FA6621B209E392DCB747F1800718A9ADAD04D48B5617D36AF518EF9A5A76FCCE8CE6BEFE567F1E91DA0FAEF318762B2E3D949C2D08A8544C80A841BF3DF01ACCF58700B804E7568F59F370DB76EEE625A7B380B38E4A1CC24F0DF6FD26C439B34B765DC4E04D6C0325DAF60A1C79057C0D94281E652E2C1CDCDCC304159440571F1B565F0A511647A541242A164FCB -20240328051250 2 6 100 7679 2 D4279A076EDA914DE80D14AF2DCB0B98294B99F706FBC061EF9007F2FA5897AEAF52D11A38EABEBA1EE590E35650894BA7669CE22689E6B50F11858063244F6BFBD664B19BA7ABD81CF1B65852069F215E8A1E1E72B3DFE09CAAFEC80797FF9F7AC81B6FB4A8813551385CD0D679E3F56BBFDC9069C7EB860A985C0170EA7899D76AD2D05AFD42205537E7BEB5782C27D2E6EF1532CEB5158BA23AC9E115AB472A1571A37E03439EFA47A04F61839D0DC47A8C7E2D13C9A018E87B5EB6B804AF7147814742D908212DBFB893171BC1713680CB1A036CBD0A6B6280F4D7B798913A9B59299E98F7553F202B0F33A2F67D6BB0071803DAD35595103E073F992321C4FFFCEB4F6AF4D3ADC9B53C41D8EFE7FE7AFE531E6485F8C087F18DD6B5A73101AE84737CAB85244E3FE085806104A9323907A94B06C437EE31D89AF7A584DE2F18DAD1A8E57FE1BAF5E2CC773EE57781F69A5D1EC4D8EB468BA9432394B5A9AD2F53B58A264B9C8E015F209DF60F865209482EDF309A575724A16E211CFC448799E4F05A9C2B1F09BDDECFB33FCC71211A646D8482F9A6EC20F10B38218A62182EB0E55BFF9BBA85585242B8BEFF20F1C88DFF9B20EA0C006D705B495750E2E78C4D1739347BF4628DF3F6A301DEDFCA7FA60D139B942338E8375471A1B33DF30316AF5584142D8B1E1F2C6966A08E2D70AED5DEC84968CAE5881587A734DEAD037A97EB384E4E07960EB4A64774579094763B71999D0783E95117BAB533C42516FE26A5F1C35F4FA2AF2B4F7A72E84B805DC31E8709BC36505F09954BDE0C86C918BC34FFD230491BECF307F1522AF4835C444D3CDBD0B00907B9CC3F483A51591659652378FF7C799373C2C40D238F8A2EBF6CDBC7FB26CE2748CCA89B85638CA12E7F5C477BB4FA0ED536BCCC7B3CFFC9E9D9126A8B1F56540A919A21439B66F3DF4C81A057B630176733B89AF3A29C297E2C0460265246AD68BF34E02391AD8C4601537B2B6BBD22C921D35574EFF85B1FE6C8A7BD6662CBF96D990929203D471F7648A7EDFC1E3AD551DFB688C6AC06E0F47844085C7485B00B5CDB3A3A449B26E104562531A12268ADC308F5095B066C0F82BD722D48A572EFC0F28865AE6EE37E39CAF2548C2B44780945AE573F8469ECC546FCEABCE9F518477ECC21B23B3E0532530795F1613B59C86EC0ACE047938CEC19C46CDCA59633F4712F989EFBDF065A5F64883C1E3960D7BCFE9FAB9B04A6DC4FB4BDA363E7A3967DF393799619DA22C6D2ECA276A6E9801CC1DCFBDBDD9985C09463B2F2CD57C922BF8FF65964A7B5EA4108F547F5D2FD328DD6A34C2B581AEDB7949AB8FCB60A9A5B -20240328061956 2 6 100 7679 2 D4279A076EDA914DE80D14AF2DCB0B98294B99F706FBC061EF9007F2FA5897AEAF52D11A38EABEBA1EE590E35650894BA7669CE22689E6B50F11858063244F6BFBD664B19BA7ABD81CF1B65852069F215E8A1E1E72B3DFE09CAAFEC80797FF9F7AC81B6FB4A8813551385CD0D679E3F56BBFDC9069C7EB860A985C0170EA7899D76AD2D05AFD42205537E7BEB5782C27D2E6EF1532CEB5158BA23AC9E115AB472A1571A37E03439EFA47A04F61839D0DC47A8C7E2D13C9A018E87B5EB6B804AF7147814742D908212DBFB893171BC1713680CB1A036CBD0A6B6280F4D7B798913A9B59299E98F7553F202B0F33A2F67D6BB0071803DAD35595103E073F992321C4FFFCEB4F6AF4D3ADC9B53C41D8EFE7FE7AFE531E6485F8C087F18DD6B5A73101AE84737CAB85244E3FE085806104A9323907A94B06C437EE31D89AF7A584DE2F18DAD1A8E57FE1BAF5E2CC773EE57781F69A5D1EC4D8EB468BA9432394B5A9AD2F53B58A264B9C8E015F209DF60F865209482EDF309A575724A16E211CFC448799E4F05A9C2B1F09BDDECFB33FCC71211A646D8482F9A6EC20F10B38218A62182EB0E55BFF9BBA85585242B8BEFF20F1C88DFF9B20EA0C006D705B495750E2E78C4D1739347BF4628DF3F6A301DEDFCA7FA60D139B942338E8375471A1B33DF30316AF5584142D8B1E1F2C6966A08E2D70AED5DEC84968CAE5881587A734DEAD037A97EB384E4E07960EB4A64774579094763B71999D0783E95117BAB533C42516FE26A5F1C35F4FA2AF2B4F7A72E84B805DC31E8709BC36505F09954BDE0C86C918BC34FFD230491BECF307F1522AF4835C444D3CDBD0B00907B9CC3F483A51591659652378FF7C799373C2C40D238F8A2EBF6CDBC7FB26CE2748CCA89B85638CA12E7F5C477BB4FA0ED536BCCC7B3CFFC9E9D9126A8B1F56540A919A21439B66F3DF4C81A057B630176733B89AF3A29C297E2C0460265246AD68BF34E02391AD8C4601537B2B6BBD22C921D35574EFF85B1FE6C8A7BD6662CBF96D990929203D471F7648A7EDFC1E3AD551DFB688C6AC06E0F47844085C7485B00B5CDB3A3A449B26E104562531A12268ADC308F5095B066C0F82BD722D48A572EFC0F28865AE6EE37E39CAF2548C2B44780945AE573F8469ECC546FCEABCE9F518477ECC21B23B3E0532530795F1613B59C86EC0ACE047938CEC19C46CDCA59633F4712F989EFBDF065A5F64883C1E3960D7BCFE9FAB9B04A6DC4FB4BDA363E7A3967DF393799619DA22C6D2ECA276A6E9801CC1DCFBDBDD9985C09463B2F2CD57C922BF8FF65964A7B5EA4108F547F5D2FD328DD6A34C2B581AEDB7949AB8FCBA8EE4D3 -20240328083541 2 6 100 7679 2 D4279A076EDA914DE80D14AF2DCB0B98294B99F706FBC061EF9007F2FA5897AEAF52D11A38EABEBA1EE590E35650894BA7669CE22689E6B50F11858063244F6BFBD664B19BA7ABD81CF1B65852069F215E8A1E1E72B3DFE09CAAFEC80797FF9F7AC81B6FB4A8813551385CD0D679E3F56BBFDC9069C7EB860A985C0170EA7899D76AD2D05AFD42205537E7BEB5782C27D2E6EF1532CEB5158BA23AC9E115AB472A1571A37E03439EFA47A04F61839D0DC47A8C7E2D13C9A018E87B5EB6B804AF7147814742D908212DBFB893171BC1713680CB1A036CBD0A6B6280F4D7B798913A9B59299E98F7553F202B0F33A2F67D6BB0071803DAD35595103E073F992321C4FFFCEB4F6AF4D3ADC9B53C41D8EFE7FE7AFE531E6485F8C087F18DD6B5A73101AE84737CAB85244E3FE085806104A9323907A94B06C437EE31D89AF7A584DE2F18DAD1A8E57FE1BAF5E2CC773EE57781F69A5D1EC4D8EB468BA9432394B5A9AD2F53B58A264B9C8E015F209DF60F865209482EDF309A575724A16E211CFC448799E4F05A9C2B1F09BDDECFB33FCC71211A646D8482F9A6EC20F10B38218A62182EB0E55BFF9BBA85585242B8BEFF20F1C88DFF9B20EA0C006D705B495750E2E78C4D1739347BF4628DF3F6A301DEDFCA7FA60D139B942338E8375471A1B33DF30316AF5584142D8B1E1F2C6966A08E2D70AED5DEC84968CAE5881587A734DEAD037A97EB384E4E07960EB4A64774579094763B71999D0783E95117BAB533C42516FE26A5F1C35F4FA2AF2B4F7A72E84B805DC31E8709BC36505F09954BDE0C86C918BC34FFD230491BECF307F1522AF4835C444D3CDBD0B00907B9CC3F483A51591659652378FF7C799373C2C40D238F8A2EBF6CDBC7FB26CE2748CCA89B85638CA12E7F5C477BB4FA0ED536BCCC7B3CFFC9E9D9126A8B1F56540A919A21439B66F3DF4C81A057B630176733B89AF3A29C297E2C0460265246AD68BF34E02391AD8C4601537B2B6BBD22C921D35574EFF85B1FE6C8A7BD6662CBF96D990929203D471F7648A7EDFC1E3AD551DFB688C6AC06E0F47844085C7485B00B5CDB3A3A449B26E104562531A12268ADC308F5095B066C0F82BD722D48A572EFC0F28865AE6EE37E39CAF2548C2B44780945AE573F8469ECC546FCEABCE9F518477ECC21B23B3E0532530795F1613B59C86EC0ACE047938CEC19C46CDCA59633F4712F989EFBDF065A5F64883C1E3960D7BCFE9FAB9B04A6DC4FB4BDA363E7A3967DF393799619DA22C6D2ECA276A6E9801CC1DCFBDBDD9985C09463B2F2CD57C922BF8FF65964A7B5EA4108F547F5D2FD328DD6A34C2B581AEDB7949AB8FCC39DE953 -20240328104001 2 6 100 7679 5 D4279A076EDA914DE80D14AF2DCB0B98294B99F706FBC061EF9007F2FA5897AEAF52D11A38EABEBA1EE590E35650894BA7669CE22689E6B50F11858063244F6BFBD664B19BA7ABD81CF1B65852069F215E8A1E1E72B3DFE09CAAFEC80797FF9F7AC81B6FB4A8813551385CD0D679E3F56BBFDC9069C7EB860A985C0170EA7899D76AD2D05AFD42205537E7BEB5782C27D2E6EF1532CEB5158BA23AC9E115AB472A1571A37E03439EFA47A04F61839D0DC47A8C7E2D13C9A018E87B5EB6B804AF7147814742D908212DBFB893171BC1713680CB1A036CBD0A6B6280F4D7B798913A9B59299E98F7553F202B0F33A2F67D6BB0071803DAD35595103E073F992321C4FFFCEB4F6AF4D3ADC9B53C41D8EFE7FE7AFE531E6485F8C087F18DD6B5A73101AE84737CAB85244E3FE085806104A9323907A94B06C437EE31D89AF7A584DE2F18DAD1A8E57FE1BAF5E2CC773EE57781F69A5D1EC4D8EB468BA9432394B5A9AD2F53B58A264B9C8E015F209DF60F865209482EDF309A575724A16E211CFC448799E4F05A9C2B1F09BDDECFB33FCC71211A646D8482F9A6EC20F10B38218A62182EB0E55BFF9BBA85585242B8BEFF20F1C88DFF9B20EA0C006D705B495750E2E78C4D1739347BF4628DF3F6A301DEDFCA7FA60D139B942338E8375471A1B33DF30316AF5584142D8B1E1F2C6966A08E2D70AED5DEC84968CAE5881587A734DEAD037A97EB384E4E07960EB4A64774579094763B71999D0783E95117BAB533C42516FE26A5F1C35F4FA2AF2B4F7A72E84B805DC31E8709BC36505F09954BDE0C86C918BC34FFD230491BECF307F1522AF4835C444D3CDBD0B00907B9CC3F483A51591659652378FF7C799373C2C40D238F8A2EBF6CDBC7FB26CE2748CCA89B85638CA12E7F5C477BB4FA0ED536BCCC7B3CFFC9E9D9126A8B1F56540A919A21439B66F3DF4C81A057B630176733B89AF3A29C297E2C0460265246AD68BF34E02391AD8C4601537B2B6BBD22C921D35574EFF85B1FE6C8A7BD6662CBF96D990929203D471F7648A7EDFC1E3AD551DFB688C6AC06E0F47844085C7485B00B5CDB3A3A449B26E104562531A12268ADC308F5095B066C0F82BD722D48A572EFC0F28865AE6EE37E39CAF2548C2B44780945AE573F8469ECC546FCEABCE9F518477ECC21B23B3E0532530795F1613B59C86EC0ACE047938CEC19C46CDCA59633F4712F989EFBDF065A5F64883C1E3960D7BCFE9FAB9B04A6DC4FB4BDA363E7A3967DF393799619DA22C6D2ECA276A6E9801CC1DCFBDBDD9985C09463B2F2CD57C922BF8FF65964A7B5EA4108F547F5D2FD328DD6A34C2B581AEDB7949AB8FCCBE8F2FF -20240328123936 2 6 100 7679 2 D4279A076EDA914DE80D14AF2DCB0B98294B99F706FBC061EF9007F2FA5897AEAF52D11A38EABEBA1EE590E35650894BA7669CE22689E6B50F11858063244F6BFBD664B19BA7ABD81CF1B65852069F215E8A1E1E72B3DFE09CAAFEC80797FF9F7AC81B6FB4A8813551385CD0D679E3F56BBFDC9069C7EB860A985C0170EA7899D76AD2D05AFD42205537E7BEB5782C27D2E6EF1532CEB5158BA23AC9E115AB472A1571A37E03439EFA47A04F61839D0DC47A8C7E2D13C9A018E87B5EB6B804AF7147814742D908212DBFB893171BC1713680CB1A036CBD0A6B6280F4D7B798913A9B59299E98F7553F202B0F33A2F67D6BB0071803DAD35595103E073F992321C4FFFCEB4F6AF4D3ADC9B53C41D8EFE7FE7AFE531E6485F8C087F18DD6B5A73101AE84737CAB85244E3FE085806104A9323907A94B06C437EE31D89AF7A584DE2F18DAD1A8E57FE1BAF5E2CC773EE57781F69A5D1EC4D8EB468BA9432394B5A9AD2F53B58A264B9C8E015F209DF60F865209482EDF309A575724A16E211CFC448799E4F05A9C2B1F09BDDECFB33FCC71211A646D8482F9A6EC20F10B38218A62182EB0E55BFF9BBA85585242B8BEFF20F1C88DFF9B20EA0C006D705B495750E2E78C4D1739347BF4628DF3F6A301DEDFCA7FA60D139B942338E8375471A1B33DF30316AF5584142D8B1E1F2C6966A08E2D70AED5DEC84968CAE5881587A734DEAD037A97EB384E4E07960EB4A64774579094763B71999D0783E95117BAB533C42516FE26A5F1C35F4FA2AF2B4F7A72E84B805DC31E8709BC36505F09954BDE0C86C918BC34FFD230491BECF307F1522AF4835C444D3CDBD0B00907B9CC3F483A51591659652378FF7C799373C2C40D238F8A2EBF6CDBC7FB26CE2748CCA89B85638CA12E7F5C477BB4FA0ED536BCCC7B3CFFC9E9D9126A8B1F56540A919A21439B66F3DF4C81A057B630176733B89AF3A29C297E2C0460265246AD68BF34E02391AD8C4601537B2B6BBD22C921D35574EFF85B1FE6C8A7BD6662CBF96D990929203D471F7648A7EDFC1E3AD551DFB688C6AC06E0F47844085C7485B00B5CDB3A3A449B26E104562531A12268ADC308F5095B066C0F82BD722D48A572EFC0F28865AE6EE37E39CAF2548C2B44780945AE573F8469ECC546FCEABCE9F518477ECC21B23B3E0532530795F1613B59C86EC0ACE047938CEC19C46CDCA59633F4712F989EFBDF065A5F64883C1E3960D7BCFE9FAB9B04A6DC4FB4BDA363E7A3967DF393799619DA22C6D2ECA276A6E9801CC1DCFBDBDD9985C09463B2F2CD57C922BF8FF65964A7B5EA4108F547F5D2FD328DD6A34C2B581AEDB7949AB8FCD40450AB -20240328131851 2 6 100 7679 5 D4279A076EDA914DE80D14AF2DCB0B98294B99F706FBC061EF9007F2FA5897AEAF52D11A38EABEBA1EE590E35650894BA7669CE22689E6B50F11858063244F6BFBD664B19BA7ABD81CF1B65852069F215E8A1E1E72B3DFE09CAAFEC80797FF9F7AC81B6FB4A8813551385CD0D679E3F56BBFDC9069C7EB860A985C0170EA7899D76AD2D05AFD42205537E7BEB5782C27D2E6EF1532CEB5158BA23AC9E115AB472A1571A37E03439EFA47A04F61839D0DC47A8C7E2D13C9A018E87B5EB6B804AF7147814742D908212DBFB893171BC1713680CB1A036CBD0A6B6280F4D7B798913A9B59299E98F7553F202B0F33A2F67D6BB0071803DAD35595103E073F992321C4FFFCEB4F6AF4D3ADC9B53C41D8EFE7FE7AFE531E6485F8C087F18DD6B5A73101AE84737CAB85244E3FE085806104A9323907A94B06C437EE31D89AF7A584DE2F18DAD1A8E57FE1BAF5E2CC773EE57781F69A5D1EC4D8EB468BA9432394B5A9AD2F53B58A264B9C8E015F209DF60F865209482EDF309A575724A16E211CFC448799E4F05A9C2B1F09BDDECFB33FCC71211A646D8482F9A6EC20F10B38218A62182EB0E55BFF9BBA85585242B8BEFF20F1C88DFF9B20EA0C006D705B495750E2E78C4D1739347BF4628DF3F6A301DEDFCA7FA60D139B942338E8375471A1B33DF30316AF5584142D8B1E1F2C6966A08E2D70AED5DEC84968CAE5881587A734DEAD037A97EB384E4E07960EB4A64774579094763B71999D0783E95117BAB533C42516FE26A5F1C35F4FA2AF2B4F7A72E84B805DC31E8709BC36505F09954BDE0C86C918BC34FFD230491BECF307F1522AF4835C444D3CDBD0B00907B9CC3F483A51591659652378FF7C799373C2C40D238F8A2EBF6CDBC7FB26CE2748CCA89B85638CA12E7F5C477BB4FA0ED536BCCC7B3CFFC9E9D9126A8B1F56540A919A21439B66F3DF4C81A057B630176733B89AF3A29C297E2C0460265246AD68BF34E02391AD8C4601537B2B6BBD22C921D35574EFF85B1FE6C8A7BD6662CBF96D990929203D471F7648A7EDFC1E3AD551DFB688C6AC06E0F47844085C7485B00B5CDB3A3A449B26E104562531A12268ADC308F5095B066C0F82BD722D48A572EFC0F28865AE6EE37E39CAF2548C2B44780945AE573F8469ECC546FCEABCE9F518477ECC21B23B3E0532530795F1613B59C86EC0ACE047938CEC19C46CDCA59633F4712F989EFBDF065A5F64883C1E3960D7BCFE9FAB9B04A6DC4FB4BDA363E7A3967DF393799619DA22C6D2ECA276A6E9801CC1DCFBDBDD9985C09463B2F2CD57C922BF8FF65964A7B5EA4108F547F5D2FD328DD6A34C2B581AEDB7949AB8FCD6B3842F -20240328133514 2 6 100 7679 2 D4279A076EDA914DE80D14AF2DCB0B98294B99F706FBC061EF9007F2FA5897AEAF52D11A38EABEBA1EE590E35650894BA7669CE22689E6B50F11858063244F6BFBD664B19BA7ABD81CF1B65852069F215E8A1E1E72B3DFE09CAAFEC80797FF9F7AC81B6FB4A8813551385CD0D679E3F56BBFDC9069C7EB860A985C0170EA7899D76AD2D05AFD42205537E7BEB5782C27D2E6EF1532CEB5158BA23AC9E115AB472A1571A37E03439EFA47A04F61839D0DC47A8C7E2D13C9A018E87B5EB6B804AF7147814742D908212DBFB893171BC1713680CB1A036CBD0A6B6280F4D7B798913A9B59299E98F7553F202B0F33A2F67D6BB0071803DAD35595103E073F992321C4FFFCEB4F6AF4D3ADC9B53C41D8EFE7FE7AFE531E6485F8C087F18DD6B5A73101AE84737CAB85244E3FE085806104A9323907A94B06C437EE31D89AF7A584DE2F18DAD1A8E57FE1BAF5E2CC773EE57781F69A5D1EC4D8EB468BA9432394B5A9AD2F53B58A264B9C8E015F209DF60F865209482EDF309A575724A16E211CFC448799E4F05A9C2B1F09BDDECFB33FCC71211A646D8482F9A6EC20F10B38218A62182EB0E55BFF9BBA85585242B8BEFF20F1C88DFF9B20EA0C006D705B495750E2E78C4D1739347BF4628DF3F6A301DEDFCA7FA60D139B942338E8375471A1B33DF30316AF5584142D8B1E1F2C6966A08E2D70AED5DEC84968CAE5881587A734DEAD037A97EB384E4E07960EB4A64774579094763B71999D0783E95117BAB533C42516FE26A5F1C35F4FA2AF2B4F7A72E84B805DC31E8709BC36505F09954BDE0C86C918BC34FFD230491BECF307F1522AF4835C444D3CDBD0B00907B9CC3F483A51591659652378FF7C799373C2C40D238F8A2EBF6CDBC7FB26CE2748CCA89B85638CA12E7F5C477BB4FA0ED536BCCC7B3CFFC9E9D9126A8B1F56540A919A21439B66F3DF4C81A057B630176733B89AF3A29C297E2C0460265246AD68BF34E02391AD8C4601537B2B6BBD22C921D35574EFF85B1FE6C8A7BD6662CBF96D990929203D471F7648A7EDFC1E3AD551DFB688C6AC06E0F47844085C7485B00B5CDB3A3A449B26E104562531A12268ADC308F5095B066C0F82BD722D48A572EFC0F28865AE6EE37E39CAF2548C2B44780945AE573F8469ECC546FCEABCE9F518477ECC21B23B3E0532530795F1613B59C86EC0ACE047938CEC19C46CDCA59633F4712F989EFBDF065A5F64883C1E3960D7BCFE9FAB9B04A6DC4FB4BDA363E7A3967DF393799619DA22C6D2ECA276A6E9801CC1DCFBDBDD9985C09463B2F2CD57C922BF8FF65964A7B5EA4108F547F5D2FD328DD6A34C2B581AEDB7949AB8FCD7C761BB -20240328163521 2 6 100 7679 2 D4279A076EDA914DE80D14AF2DCB0B98294B99F706FBC061EF9007F2FA5897AEAF52D11A38EABEBA1EE590E35650894BA7669CE22689E6B50F11858063244F6BFBD664B19BA7ABD81CF1B65852069F215E8A1E1E72B3DFE09CAAFEC80797FF9F7AC81B6FB4A8813551385CD0D679E3F56BBFDC9069C7EB860A985C0170EA7899D76AD2D05AFD42205537E7BEB5782C27D2E6EF1532CEB5158BA23AC9E115AB472A1571A37E03439EFA47A04F61839D0DC47A8C7E2D13C9A018E87B5EB6B804AF7147814742D908212DBFB893171BC1713680CB1A036CBD0A6B6280F4D7B798913A9B59299E98F7553F202B0F33A2F67D6BB0071803DAD35595103E073F992321C4FFFCEB4F6AF4D3ADC9B53C41D8EFE7FE7AFE531E6485F8C087F18DD6B5A73101AE84737CAB85244E3FE085806104A9323907A94B06C437EE31D89AF7A584DE2F18DAD1A8E57FE1BAF5E2CC773EE57781F69A5D1EC4D8EB468BA9432394B5A9AD2F53B58A264B9C8E015F209DF60F865209482EDF309A575724A16E211CFC448799E4F05A9C2B1F09BDDECFB33FCC71211A646D8482F9A6EC20F10B38218A62182EB0E55BFF9BBA85585242B8BEFF20F1C88DFF9B20EA0C006D705B495750E2E78C4D1739347BF4628DF3F6A301DEDFCA7FA60D139B942338E8375471A1B33DF30316AF5584142D8B1E1F2C6966A08E2D70AED5DEC84968CAE5881587A734DEAD037A97EB384E4E07960EB4A64774579094763B71999D0783E95117BAB533C42516FE26A5F1C35F4FA2AF2B4F7A72E84B805DC31E8709BC36505F09954BDE0C86C918BC34FFD230491BECF307F1522AF4835C444D3CDBD0B00907B9CC3F483A51591659652378FF7C799373C2C40D238F8A2EBF6CDBC7FB26CE2748CCA89B85638CA12E7F5C477BB4FA0ED536BCCC7B3CFFC9E9D9126A8B1F56540A919A21439B66F3DF4C81A057B630176733B89AF3A29C297E2C0460265246AD68BF34E02391AD8C4601537B2B6BBD22C921D35574EFF85B1FE6C8A7BD6662CBF96D990929203D471F7648A7EDFC1E3AD551DFB688C6AC06E0F47844085C7485B00B5CDB3A3A449B26E104562531A12268ADC308F5095B066C0F82BD722D48A572EFC0F28865AE6EE37E39CAF2548C2B44780945AE573F8469ECC546FCEABCE9F518477ECC21B23B3E0532530795F1613B59C86EC0ACE047938CEC19C46CDCA59633F4712F989EFBDF065A5F64883C1E3960D7BCFE9FAB9B04A6DC4FB4BDA363E7A3967DF393799619DA22C6D2ECA276A6E9801CC1DCFBDBDD9985C09463B2F2CD57C922BF8FF65964A7B5EA4108F547F5D2FD328DD6A34C2B581AEDB7949AB8FCE3D44693 -20240328184556 2 6 100 7679 5 D4279A076EDA914DE80D14AF2DCB0B98294B99F706FBC061EF9007F2FA5897AEAF52D11A38EABEBA1EE590E35650894BA7669CE22689E6B50F11858063244F6BFBD664B19BA7ABD81CF1B65852069F215E8A1E1E72B3DFE09CAAFEC80797FF9F7AC81B6FB4A8813551385CD0D679E3F56BBFDC9069C7EB860A985C0170EA7899D76AD2D05AFD42205537E7BEB5782C27D2E6EF1532CEB5158BA23AC9E115AB472A1571A37E03439EFA47A04F61839D0DC47A8C7E2D13C9A018E87B5EB6B804AF7147814742D908212DBFB893171BC1713680CB1A036CBD0A6B6280F4D7B798913A9B59299E98F7553F202B0F33A2F67D6BB0071803DAD35595103E073F992321C4FFFCEB4F6AF4D3ADC9B53C41D8EFE7FE7AFE531E6485F8C087F18DD6B5A73101AE84737CAB85244E3FE085806104A9323907A94B06C437EE31D89AF7A584DE2F18DAD1A8E57FE1BAF5E2CC773EE57781F69A5D1EC4D8EB468BA9432394B5A9AD2F53B58A264B9C8E015F209DF60F865209482EDF309A575724A16E211CFC448799E4F05A9C2B1F09BDDECFB33FCC71211A646D8482F9A6EC20F10B38218A62182EB0E55BFF9BBA85585242B8BEFF20F1C88DFF9B20EA0C006D705B495750E2E78C4D1739347BF4628DF3F6A301DEDFCA7FA60D139B942338E8375471A1B33DF30316AF5584142D8B1E1F2C6966A08E2D70AED5DEC84968CAE5881587A734DEAD037A97EB384E4E07960EB4A64774579094763B71999D0783E95117BAB533C42516FE26A5F1C35F4FA2AF2B4F7A72E84B805DC31E8709BC36505F09954BDE0C86C918BC34FFD230491BECF307F1522AF4835C444D3CDBD0B00907B9CC3F483A51591659652378FF7C799373C2C40D238F8A2EBF6CDBC7FB26CE2748CCA89B85638CA12E7F5C477BB4FA0ED536BCCC7B3CFFC9E9D9126A8B1F56540A919A21439B66F3DF4C81A057B630176733B89AF3A29C297E2C0460265246AD68BF34E02391AD8C4601537B2B6BBD22C921D35574EFF85B1FE6C8A7BD6662CBF96D990929203D471F7648A7EDFC1E3AD551DFB688C6AC06E0F47844085C7485B00B5CDB3A3A449B26E104562531A12268ADC308F5095B066C0F82BD722D48A572EFC0F28865AE6EE37E39CAF2548C2B44780945AE573F8469ECC546FCEABCE9F518477ECC21B23B3E0532530795F1613B59C86EC0ACE047938CEC19C46CDCA59633F4712F989EFBDF065A5F64883C1E3960D7BCFE9FAB9B04A6DC4FB4BDA363E7A3967DF393799619DA22C6D2ECA276A6E9801CC1DCFBDBDD9985C09463B2F2CD57C922BF8FF65964A7B5EA4108F547F5D2FD328DD6A34C2B581AEDB7949AB8FCECA94E8F -20240328185443 2 6 100 7679 2 D4279A076EDA914DE80D14AF2DCB0B98294B99F706FBC061EF9007F2FA5897AEAF52D11A38EABEBA1EE590E35650894BA7669CE22689E6B50F11858063244F6BFBD664B19BA7ABD81CF1B65852069F215E8A1E1E72B3DFE09CAAFEC80797FF9F7AC81B6FB4A8813551385CD0D679E3F56BBFDC9069C7EB860A985C0170EA7899D76AD2D05AFD42205537E7BEB5782C27D2E6EF1532CEB5158BA23AC9E115AB472A1571A37E03439EFA47A04F61839D0DC47A8C7E2D13C9A018E87B5EB6B804AF7147814742D908212DBFB893171BC1713680CB1A036CBD0A6B6280F4D7B798913A9B59299E98F7553F202B0F33A2F67D6BB0071803DAD35595103E073F992321C4FFFCEB4F6AF4D3ADC9B53C41D8EFE7FE7AFE531E6485F8C087F18DD6B5A73101AE84737CAB85244E3FE085806104A9323907A94B06C437EE31D89AF7A584DE2F18DAD1A8E57FE1BAF5E2CC773EE57781F69A5D1EC4D8EB468BA9432394B5A9AD2F53B58A264B9C8E015F209DF60F865209482EDF309A575724A16E211CFC448799E4F05A9C2B1F09BDDECFB33FCC71211A646D8482F9A6EC20F10B38218A62182EB0E55BFF9BBA85585242B8BEFF20F1C88DFF9B20EA0C006D705B495750E2E78C4D1739347BF4628DF3F6A301DEDFCA7FA60D139B942338E8375471A1B33DF30316AF5584142D8B1E1F2C6966A08E2D70AED5DEC84968CAE5881587A734DEAD037A97EB384E4E07960EB4A64774579094763B71999D0783E95117BAB533C42516FE26A5F1C35F4FA2AF2B4F7A72E84B805DC31E8709BC36505F09954BDE0C86C918BC34FFD230491BECF307F1522AF4835C444D3CDBD0B00907B9CC3F483A51591659652378FF7C799373C2C40D238F8A2EBF6CDBC7FB26CE2748CCA89B85638CA12E7F5C477BB4FA0ED536BCCC7B3CFFC9E9D9126A8B1F56540A919A21439B66F3DF4C81A057B630176733B89AF3A29C297E2C0460265246AD68BF34E02391AD8C4601537B2B6BBD22C921D35574EFF85B1FE6C8A7BD6662CBF96D990929203D471F7648A7EDFC1E3AD551DFB688C6AC06E0F47844085C7485B00B5CDB3A3A449B26E104562531A12268ADC308F5095B066C0F82BD722D48A572EFC0F28865AE6EE37E39CAF2548C2B44780945AE573F8469ECC546FCEABCE9F518477ECC21B23B3E0532530795F1613B59C86EC0ACE047938CEC19C46CDCA59633F4712F989EFBDF065A5F64883C1E3960D7BCFE9FAB9B04A6DC4FB4BDA363E7A3967DF393799619DA22C6D2ECA276A6E9801CC1DCFBDBDD9985C09463B2F2CD57C922BF8FF65964A7B5EA4108F547F5D2FD328DD6A34C2B581AEDB7949AB8FCED3C2EEB -20240328190404 2 6 100 7679 2 D4279A076EDA914DE80D14AF2DCB0B98294B99F706FBC061EF9007F2FA5897AEAF52D11A38EABEBA1EE590E35650894BA7669CE22689E6B50F11858063244F6BFBD664B19BA7ABD81CF1B65852069F215E8A1E1E72B3DFE09CAAFEC80797FF9F7AC81B6FB4A8813551385CD0D679E3F56BBFDC9069C7EB860A985C0170EA7899D76AD2D05AFD42205537E7BEB5782C27D2E6EF1532CEB5158BA23AC9E115AB472A1571A37E03439EFA47A04F61839D0DC47A8C7E2D13C9A018E87B5EB6B804AF7147814742D908212DBFB893171BC1713680CB1A036CBD0A6B6280F4D7B798913A9B59299E98F7553F202B0F33A2F67D6BB0071803DAD35595103E073F992321C4FFFCEB4F6AF4D3ADC9B53C41D8EFE7FE7AFE531E6485F8C087F18DD6B5A73101AE84737CAB85244E3FE085806104A9323907A94B06C437EE31D89AF7A584DE2F18DAD1A8E57FE1BAF5E2CC773EE57781F69A5D1EC4D8EB468BA9432394B5A9AD2F53B58A264B9C8E015F209DF60F865209482EDF309A575724A16E211CFC448799E4F05A9C2B1F09BDDECFB33FCC71211A646D8482F9A6EC20F10B38218A62182EB0E55BFF9BBA85585242B8BEFF20F1C88DFF9B20EA0C006D705B495750E2E78C4D1739347BF4628DF3F6A301DEDFCA7FA60D139B942338E8375471A1B33DF30316AF5584142D8B1E1F2C6966A08E2D70AED5DEC84968CAE5881587A734DEAD037A97EB384E4E07960EB4A64774579094763B71999D0783E95117BAB533C42516FE26A5F1C35F4FA2AF2B4F7A72E84B805DC31E8709BC36505F09954BDE0C86C918BC34FFD230491BECF307F1522AF4835C444D3CDBD0B00907B9CC3F483A51591659652378FF7C799373C2C40D238F8A2EBF6CDBC7FB26CE2748CCA89B85638CA12E7F5C477BB4FA0ED536BCCC7B3CFFC9E9D9126A8B1F56540A919A21439B66F3DF4C81A057B630176733B89AF3A29C297E2C0460265246AD68BF34E02391AD8C4601537B2B6BBD22C921D35574EFF85B1FE6C8A7BD6662CBF96D990929203D471F7648A7EDFC1E3AD551DFB688C6AC06E0F47844085C7485B00B5CDB3A3A449B26E104562531A12268ADC308F5095B066C0F82BD722D48A572EFC0F28865AE6EE37E39CAF2548C2B44780945AE573F8469ECC546FCEABCE9F518477ECC21B23B3E0532530795F1613B59C86EC0ACE047938CEC19C46CDCA59633F4712F989EFBDF065A5F64883C1E3960D7BCFE9FAB9B04A6DC4FB4BDA363E7A3967DF393799619DA22C6D2ECA276A6E9801CC1DCFBDBDD9985C09463B2F2CD57C922BF8FF65964A7B5EA4108F547F5D2FD328DD6A34C2B581AEDB7949AB8FCEDD4DEAB -20240328193132 2 6 100 7679 5 D4279A076EDA914DE80D14AF2DCB0B98294B99F706FBC061EF9007F2FA5897AEAF52D11A38EABEBA1EE590E35650894BA7669CE22689E6B50F11858063244F6BFBD664B19BA7ABD81CF1B65852069F215E8A1E1E72B3DFE09CAAFEC80797FF9F7AC81B6FB4A8813551385CD0D679E3F56BBFDC9069C7EB860A985C0170EA7899D76AD2D05AFD42205537E7BEB5782C27D2E6EF1532CEB5158BA23AC9E115AB472A1571A37E03439EFA47A04F61839D0DC47A8C7E2D13C9A018E87B5EB6B804AF7147814742D908212DBFB893171BC1713680CB1A036CBD0A6B6280F4D7B798913A9B59299E98F7553F202B0F33A2F67D6BB0071803DAD35595103E073F992321C4FFFCEB4F6AF4D3ADC9B53C41D8EFE7FE7AFE531E6485F8C087F18DD6B5A73101AE84737CAB85244E3FE085806104A9323907A94B06C437EE31D89AF7A584DE2F18DAD1A8E57FE1BAF5E2CC773EE57781F69A5D1EC4D8EB468BA9432394B5A9AD2F53B58A264B9C8E015F209DF60F865209482EDF309A575724A16E211CFC448799E4F05A9C2B1F09BDDECFB33FCC71211A646D8482F9A6EC20F10B38218A62182EB0E55BFF9BBA85585242B8BEFF20F1C88DFF9B20EA0C006D705B495750E2E78C4D1739347BF4628DF3F6A301DEDFCA7FA60D139B942338E8375471A1B33DF30316AF5584142D8B1E1F2C6966A08E2D70AED5DEC84968CAE5881587A734DEAD037A97EB384E4E07960EB4A64774579094763B71999D0783E95117BAB533C42516FE26A5F1C35F4FA2AF2B4F7A72E84B805DC31E8709BC36505F09954BDE0C86C918BC34FFD230491BECF307F1522AF4835C444D3CDBD0B00907B9CC3F483A51591659652378FF7C799373C2C40D238F8A2EBF6CDBC7FB26CE2748CCA89B85638CA12E7F5C477BB4FA0ED536BCCC7B3CFFC9E9D9126A8B1F56540A919A21439B66F3DF4C81A057B630176733B89AF3A29C297E2C0460265246AD68BF34E02391AD8C4601537B2B6BBD22C921D35574EFF85B1FE6C8A7BD6662CBF96D990929203D471F7648A7EDFC1E3AD551DFB688C6AC06E0F47844085C7485B00B5CDB3A3A449B26E104562531A12268ADC308F5095B066C0F82BD722D48A572EFC0F28865AE6EE37E39CAF2548C2B44780945AE573F8469ECC546FCEABCE9F518477ECC21B23B3E0532530795F1613B59C86EC0ACE047938CEC19C46CDCA59633F4712F989EFBDF065A5F64883C1E3960D7BCFE9FAB9B04A6DC4FB4BDA363E7A3967DF393799619DA22C6D2ECA276A6E9801CC1DCFBDBDD9985C09463B2F2CD57C922BF8FF65964A7B5EA4108F547F5D2FD328DD6A34C2B581AEDB7949AB8FCEFA3B567 -20240328194029 2 6 100 7679 5 D4279A076EDA914DE80D14AF2DCB0B98294B99F706FBC061EF9007F2FA5897AEAF52D11A38EABEBA1EE590E35650894BA7669CE22689E6B50F11858063244F6BFBD664B19BA7ABD81CF1B65852069F215E8A1E1E72B3DFE09CAAFEC80797FF9F7AC81B6FB4A8813551385CD0D679E3F56BBFDC9069C7EB860A985C0170EA7899D76AD2D05AFD42205537E7BEB5782C27D2E6EF1532CEB5158BA23AC9E115AB472A1571A37E03439EFA47A04F61839D0DC47A8C7E2D13C9A018E87B5EB6B804AF7147814742D908212DBFB893171BC1713680CB1A036CBD0A6B6280F4D7B798913A9B59299E98F7553F202B0F33A2F67D6BB0071803DAD35595103E073F992321C4FFFCEB4F6AF4D3ADC9B53C41D8EFE7FE7AFE531E6485F8C087F18DD6B5A73101AE84737CAB85244E3FE085806104A9323907A94B06C437EE31D89AF7A584DE2F18DAD1A8E57FE1BAF5E2CC773EE57781F69A5D1EC4D8EB468BA9432394B5A9AD2F53B58A264B9C8E015F209DF60F865209482EDF309A575724A16E211CFC448799E4F05A9C2B1F09BDDECFB33FCC71211A646D8482F9A6EC20F10B38218A62182EB0E55BFF9BBA85585242B8BEFF20F1C88DFF9B20EA0C006D705B495750E2E78C4D1739347BF4628DF3F6A301DEDFCA7FA60D139B942338E8375471A1B33DF30316AF5584142D8B1E1F2C6966A08E2D70AED5DEC84968CAE5881587A734DEAD037A97EB384E4E07960EB4A64774579094763B71999D0783E95117BAB533C42516FE26A5F1C35F4FA2AF2B4F7A72E84B805DC31E8709BC36505F09954BDE0C86C918BC34FFD230491BECF307F1522AF4835C444D3CDBD0B00907B9CC3F483A51591659652378FF7C799373C2C40D238F8A2EBF6CDBC7FB26CE2748CCA89B85638CA12E7F5C477BB4FA0ED536BCCC7B3CFFC9E9D9126A8B1F56540A919A21439B66F3DF4C81A057B630176733B89AF3A29C297E2C0460265246AD68BF34E02391AD8C4601537B2B6BBD22C921D35574EFF85B1FE6C8A7BD6662CBF96D990929203D471F7648A7EDFC1E3AD551DFB688C6AC06E0F47844085C7485B00B5CDB3A3A449B26E104562531A12268ADC308F5095B066C0F82BD722D48A572EFC0F28865AE6EE37E39CAF2548C2B44780945AE573F8469ECC546FCEABCE9F518477ECC21B23B3E0532530795F1613B59C86EC0ACE047938CEC19C46CDCA59633F4712F989EFBDF065A5F64883C1E3960D7BCFE9FAB9B04A6DC4FB4BDA363E7A3967DF393799619DA22C6D2ECA276A6E9801CC1DCFBDBDD9985C09463B2F2CD57C922BF8FF65964A7B5EA4108F547F5D2FD328DD6A34C2B581AEDB7949AB8FCF039E777 -20240328205320 2 6 100 7679 5 D4279A076EDA914DE80D14AF2DCB0B98294B99F706FBC061EF9007F2FA5897AEAF52D11A38EABEBA1EE590E35650894BA7669CE22689E6B50F11858063244F6BFBD664B19BA7ABD81CF1B65852069F215E8A1E1E72B3DFE09CAAFEC80797FF9F7AC81B6FB4A8813551385CD0D679E3F56BBFDC9069C7EB860A985C0170EA7899D76AD2D05AFD42205537E7BEB5782C27D2E6EF1532CEB5158BA23AC9E115AB472A1571A37E03439EFA47A04F61839D0DC47A8C7E2D13C9A018E87B5EB6B804AF7147814742D908212DBFB893171BC1713680CB1A036CBD0A6B6280F4D7B798913A9B59299E98F7553F202B0F33A2F67D6BB0071803DAD35595103E073F992321C4FFFCEB4F6AF4D3ADC9B53C41D8EFE7FE7AFE531E6485F8C087F18DD6B5A73101AE84737CAB85244E3FE085806104A9323907A94B06C437EE31D89AF7A584DE2F18DAD1A8E57FE1BAF5E2CC773EE57781F69A5D1EC4D8EB468BA9432394B5A9AD2F53B58A264B9C8E015F209DF60F865209482EDF309A575724A16E211CFC448799E4F05A9C2B1F09BDDECFB33FCC71211A646D8482F9A6EC20F10B38218A62182EB0E55BFF9BBA85585242B8BEFF20F1C88DFF9B20EA0C006D705B495750E2E78C4D1739347BF4628DF3F6A301DEDFCA7FA60D139B942338E8375471A1B33DF30316AF5584142D8B1E1F2C6966A08E2D70AED5DEC84968CAE5881587A734DEAD037A97EB384E4E07960EB4A64774579094763B71999D0783E95117BAB533C42516FE26A5F1C35F4FA2AF2B4F7A72E84B805DC31E8709BC36505F09954BDE0C86C918BC34FFD230491BECF307F1522AF4835C444D3CDBD0B00907B9CC3F483A51591659652378FF7C799373C2C40D238F8A2EBF6CDBC7FB26CE2748CCA89B85638CA12E7F5C477BB4FA0ED536BCCC7B3CFFC9E9D9126A8B1F56540A919A21439B66F3DF4C81A057B630176733B89AF3A29C297E2C0460265246AD68BF34E02391AD8C4601537B2B6BBD22C921D35574EFF85B1FE6C8A7BD6662CBF96D990929203D471F7648A7EDFC1E3AD551DFB688C6AC06E0F47844085C7485B00B5CDB3A3A449B26E104562531A12268ADC308F5095B066C0F82BD722D48A572EFC0F28865AE6EE37E39CAF2548C2B44780945AE573F8469ECC546FCEABCE9F518477ECC21B23B3E0532530795F1613B59C86EC0ACE047938CEC19C46CDCA59633F4712F989EFBDF065A5F64883C1E3960D7BCFE9FAB9B04A6DC4FB4BDA363E7A3967DF393799619DA22C6D2ECA276A6E9801CC1DCFBDBDD9985C09463B2F2CD57C922BF8FF65964A7B5EA4108F547F5D2FD328DD6A34C2B581AEDB7949AB8FCF523DF3F -20240328210032 2 6 100 7679 2 D4279A076EDA914DE80D14AF2DCB0B98294B99F706FBC061EF9007F2FA5897AEAF52D11A38EABEBA1EE590E35650894BA7669CE22689E6B50F11858063244F6BFBD664B19BA7ABD81CF1B65852069F215E8A1E1E72B3DFE09CAAFEC80797FF9F7AC81B6FB4A8813551385CD0D679E3F56BBFDC9069C7EB860A985C0170EA7899D76AD2D05AFD42205537E7BEB5782C27D2E6EF1532CEB5158BA23AC9E115AB472A1571A37E03439EFA47A04F61839D0DC47A8C7E2D13C9A018E87B5EB6B804AF7147814742D908212DBFB893171BC1713680CB1A036CBD0A6B6280F4D7B798913A9B59299E98F7553F202B0F33A2F67D6BB0071803DAD35595103E073F992321C4FFFCEB4F6AF4D3ADC9B53C41D8EFE7FE7AFE531E6485F8C087F18DD6B5A73101AE84737CAB85244E3FE085806104A9323907A94B06C437EE31D89AF7A584DE2F18DAD1A8E57FE1BAF5E2CC773EE57781F69A5D1EC4D8EB468BA9432394B5A9AD2F53B58A264B9C8E015F209DF60F865209482EDF309A575724A16E211CFC448799E4F05A9C2B1F09BDDECFB33FCC71211A646D8482F9A6EC20F10B38218A62182EB0E55BFF9BBA85585242B8BEFF20F1C88DFF9B20EA0C006D705B495750E2E78C4D1739347BF4628DF3F6A301DEDFCA7FA60D139B942338E8375471A1B33DF30316AF5584142D8B1E1F2C6966A08E2D70AED5DEC84968CAE5881587A734DEAD037A97EB384E4E07960EB4A64774579094763B71999D0783E95117BAB533C42516FE26A5F1C35F4FA2AF2B4F7A72E84B805DC31E8709BC36505F09954BDE0C86C918BC34FFD230491BECF307F1522AF4835C444D3CDBD0B00907B9CC3F483A51591659652378FF7C799373C2C40D238F8A2EBF6CDBC7FB26CE2748CCA89B85638CA12E7F5C477BB4FA0ED536BCCC7B3CFFC9E9D9126A8B1F56540A919A21439B66F3DF4C81A057B630176733B89AF3A29C297E2C0460265246AD68BF34E02391AD8C4601537B2B6BBD22C921D35574EFF85B1FE6C8A7BD6662CBF96D990929203D471F7648A7EDFC1E3AD551DFB688C6AC06E0F47844085C7485B00B5CDB3A3A449B26E104562531A12268ADC308F5095B066C0F82BD722D48A572EFC0F28865AE6EE37E39CAF2548C2B44780945AE573F8469ECC546FCEABCE9F518477ECC21B23B3E0532530795F1613B59C86EC0ACE047938CEC19C46CDCA59633F4712F989EFBDF065A5F64883C1E3960D7BCFE9FAB9B04A6DC4FB4BDA363E7A3967DF393799619DA22C6D2ECA276A6E9801CC1DCFBDBDD9985C09463B2F2CD57C922BF8FF65964A7B5EA4108F547F5D2FD328DD6A34C2B581AEDB7949AB8FCF59C775B -20240328221220 2 6 100 7679 2 D4279A076EDA914DE80D14AF2DCB0B98294B99F706FBC061EF9007F2FA5897AEAF52D11A38EABEBA1EE590E35650894BA7669CE22689E6B50F11858063244F6BFBD664B19BA7ABD81CF1B65852069F215E8A1E1E72B3DFE09CAAFEC80797FF9F7AC81B6FB4A8813551385CD0D679E3F56BBFDC9069C7EB860A985C0170EA7899D76AD2D05AFD42205537E7BEB5782C27D2E6EF1532CEB5158BA23AC9E115AB472A1571A37E03439EFA47A04F61839D0DC47A8C7E2D13C9A018E87B5EB6B804AF7147814742D908212DBFB893171BC1713680CB1A036CBD0A6B6280F4D7B798913A9B59299E98F7553F202B0F33A2F67D6BB0071803DAD35595103E073F992321C4FFFCEB4F6AF4D3ADC9B53C41D8EFE7FE7AFE531E6485F8C087F18DD6B5A73101AE84737CAB85244E3FE085806104A9323907A94B06C437EE31D89AF7A584DE2F18DAD1A8E57FE1BAF5E2CC773EE57781F69A5D1EC4D8EB468BA9432394B5A9AD2F53B58A264B9C8E015F209DF60F865209482EDF309A575724A16E211CFC448799E4F05A9C2B1F09BDDECFB33FCC71211A646D8482F9A6EC20F10B38218A62182EB0E55BFF9BBA85585242B8BEFF20F1C88DFF9B20EA0C006D705B495750E2E78C4D1739347BF4628DF3F6A301DEDFCA7FA60D139B942338E8375471A1B33DF30316AF5584142D8B1E1F2C6966A08E2D70AED5DEC84968CAE5881587A734DEAD037A97EB384E4E07960EB4A64774579094763B71999D0783E95117BAB533C42516FE26A5F1C35F4FA2AF2B4F7A72E84B805DC31E8709BC36505F09954BDE0C86C918BC34FFD230491BECF307F1522AF4835C444D3CDBD0B00907B9CC3F483A51591659652378FF7C799373C2C40D238F8A2EBF6CDBC7FB26CE2748CCA89B85638CA12E7F5C477BB4FA0ED536BCCC7B3CFFC9E9D9126A8B1F56540A919A21439B66F3DF4C81A057B630176733B89AF3A29C297E2C0460265246AD68BF34E02391AD8C4601537B2B6BBD22C921D35574EFF85B1FE6C8A7BD6662CBF96D990929203D471F7648A7EDFC1E3AD551DFB688C6AC06E0F47844085C7485B00B5CDB3A3A449B26E104562531A12268ADC308F5095B066C0F82BD722D48A572EFC0F28865AE6EE37E39CAF2548C2B44780945AE573F8469ECC546FCEABCE9F518477ECC21B23B3E0532530795F1613B59C86EC0ACE047938CEC19C46CDCA59633F4712F989EFBDF065A5F64883C1E3960D7BCFE9FAB9B04A6DC4FB4BDA363E7A3967DF393799619DA22C6D2ECA276A6E9801CC1DCFBDBDD9985C09463B2F2CD57C922BF8FF65964A7B5EA4108F547F5D2FD328DD6A34C2B581AEDB7949AB8FCFA7B3FEB -20240328221329 2 6 100 7679 2 D4279A076EDA914DE80D14AF2DCB0B98294B99F706FBC061EF9007F2FA5897AEAF52D11A38EABEBA1EE590E35650894BA7669CE22689E6B50F11858063244F6BFBD664B19BA7ABD81CF1B65852069F215E8A1E1E72B3DFE09CAAFEC80797FF9F7AC81B6FB4A8813551385CD0D679E3F56BBFDC9069C7EB860A985C0170EA7899D76AD2D05AFD42205537E7BEB5782C27D2E6EF1532CEB5158BA23AC9E115AB472A1571A37E03439EFA47A04F61839D0DC47A8C7E2D13C9A018E87B5EB6B804AF7147814742D908212DBFB893171BC1713680CB1A036CBD0A6B6280F4D7B798913A9B59299E98F7553F202B0F33A2F67D6BB0071803DAD35595103E073F992321C4FFFCEB4F6AF4D3ADC9B53C41D8EFE7FE7AFE531E6485F8C087F18DD6B5A73101AE84737CAB85244E3FE085806104A9323907A94B06C437EE31D89AF7A584DE2F18DAD1A8E57FE1BAF5E2CC773EE57781F69A5D1EC4D8EB468BA9432394B5A9AD2F53B58A264B9C8E015F209DF60F865209482EDF309A575724A16E211CFC448799E4F05A9C2B1F09BDDECFB33FCC71211A646D8482F9A6EC20F10B38218A62182EB0E55BFF9BBA85585242B8BEFF20F1C88DFF9B20EA0C006D705B495750E2E78C4D1739347BF4628DF3F6A301DEDFCA7FA60D139B942338E8375471A1B33DF30316AF5584142D8B1E1F2C6966A08E2D70AED5DEC84968CAE5881587A734DEAD037A97EB384E4E07960EB4A64774579094763B71999D0783E95117BAB533C42516FE26A5F1C35F4FA2AF2B4F7A72E84B805DC31E8709BC36505F09954BDE0C86C918BC34FFD230491BECF307F1522AF4835C444D3CDBD0B00907B9CC3F483A51591659652378FF7C799373C2C40D238F8A2EBF6CDBC7FB26CE2748CCA89B85638CA12E7F5C477BB4FA0ED536BCCC7B3CFFC9E9D9126A8B1F56540A919A21439B66F3DF4C81A057B630176733B89AF3A29C297E2C0460265246AD68BF34E02391AD8C4601537B2B6BBD22C921D35574EFF85B1FE6C8A7BD6662CBF96D990929203D471F7648A7EDFC1E3AD551DFB688C6AC06E0F47844085C7485B00B5CDB3A3A449B26E104562531A12268ADC308F5095B066C0F82BD722D48A572EFC0F28865AE6EE37E39CAF2548C2B44780945AE573F8469ECC546FCEABCE9F518477ECC21B23B3E0532530795F1613B59C86EC0ACE047938CEC19C46CDCA59633F4712F989EFBDF065A5F64883C1E3960D7BCFE9FAB9B04A6DC4FB4BDA363E7A3967DF393799619DA22C6D2ECA276A6E9801CC1DCFBDBDD9985C09463B2F2CD57C922BF8FF65964A7B5EA4108F547F5D2FD328DD6A34C2B581AEDB7949AB8FCFA863653 -20240328222505 2 6 100 7679 2 D4279A076EDA914DE80D14AF2DCB0B98294B99F706FBC061EF9007F2FA5897AEAF52D11A38EABEBA1EE590E35650894BA7669CE22689E6B50F11858063244F6BFBD664B19BA7ABD81CF1B65852069F215E8A1E1E72B3DFE09CAAFEC80797FF9F7AC81B6FB4A8813551385CD0D679E3F56BBFDC9069C7EB860A985C0170EA7899D76AD2D05AFD42205537E7BEB5782C27D2E6EF1532CEB5158BA23AC9E115AB472A1571A37E03439EFA47A04F61839D0DC47A8C7E2D13C9A018E87B5EB6B804AF7147814742D908212DBFB893171BC1713680CB1A036CBD0A6B6280F4D7B798913A9B59299E98F7553F202B0F33A2F67D6BB0071803DAD35595103E073F992321C4FFFCEB4F6AF4D3ADC9B53C41D8EFE7FE7AFE531E6485F8C087F18DD6B5A73101AE84737CAB85244E3FE085806104A9323907A94B06C437EE31D89AF7A584DE2F18DAD1A8E57FE1BAF5E2CC773EE57781F69A5D1EC4D8EB468BA9432394B5A9AD2F53B58A264B9C8E015F209DF60F865209482EDF309A575724A16E211CFC448799E4F05A9C2B1F09BDDECFB33FCC71211A646D8482F9A6EC20F10B38218A62182EB0E55BFF9BBA85585242B8BEFF20F1C88DFF9B20EA0C006D705B495750E2E78C4D1739347BF4628DF3F6A301DEDFCA7FA60D139B942338E8375471A1B33DF30316AF5584142D8B1E1F2C6966A08E2D70AED5DEC84968CAE5881587A734DEAD037A97EB384E4E07960EB4A64774579094763B71999D0783E95117BAB533C42516FE26A5F1C35F4FA2AF2B4F7A72E84B805DC31E8709BC36505F09954BDE0C86C918BC34FFD230491BECF307F1522AF4835C444D3CDBD0B00907B9CC3F483A51591659652378FF7C799373C2C40D238F8A2EBF6CDBC7FB26CE2748CCA89B85638CA12E7F5C477BB4FA0ED536BCCC7B3CFFC9E9D9126A8B1F56540A919A21439B66F3DF4C81A057B630176733B89AF3A29C297E2C0460265246AD68BF34E02391AD8C4601537B2B6BBD22C921D35574EFF85B1FE6C8A7BD6662CBF96D990929203D471F7648A7EDFC1E3AD551DFB688C6AC06E0F47844085C7485B00B5CDB3A3A449B26E104562531A12268ADC308F5095B066C0F82BD722D48A572EFC0F28865AE6EE37E39CAF2548C2B44780945AE573F8469ECC546FCEABCE9F518477ECC21B23B3E0532530795F1613B59C86EC0ACE047938CEC19C46CDCA59633F4712F989EFBDF065A5F64883C1E3960D7BCFE9FAB9B04A6DC4FB4BDA363E7A3967DF393799619DA22C6D2ECA276A6E9801CC1DCFBDBDD9985C09463B2F2CD57C922BF8FF65964A7B5EA4108F547F5D2FD328DD6A34C2B581AEDB7949AB8FCFB420393 -20240328224858 2 6 100 7679 5 D4279A076EDA914DE80D14AF2DCB0B98294B99F706FBC061EF9007F2FA5897AEAF52D11A38EABEBA1EE590E35650894BA7669CE22689E6B50F11858063244F6BFBD664B19BA7ABD81CF1B65852069F215E8A1E1E72B3DFE09CAAFEC80797FF9F7AC81B6FB4A8813551385CD0D679E3F56BBFDC9069C7EB860A985C0170EA7899D76AD2D05AFD42205537E7BEB5782C27D2E6EF1532CEB5158BA23AC9E115AB472A1571A37E03439EFA47A04F61839D0DC47A8C7E2D13C9A018E87B5EB6B804AF7147814742D908212DBFB893171BC1713680CB1A036CBD0A6B6280F4D7B798913A9B59299E98F7553F202B0F33A2F67D6BB0071803DAD35595103E073F992321C4FFFCEB4F6AF4D3ADC9B53C41D8EFE7FE7AFE531E6485F8C087F18DD6B5A73101AE84737CAB85244E3FE085806104A9323907A94B06C437EE31D89AF7A584DE2F18DAD1A8E57FE1BAF5E2CC773EE57781F69A5D1EC4D8EB468BA9432394B5A9AD2F53B58A264B9C8E015F209DF60F865209482EDF309A575724A16E211CFC448799E4F05A9C2B1F09BDDECFB33FCC71211A646D8482F9A6EC20F10B38218A62182EB0E55BFF9BBA85585242B8BEFF20F1C88DFF9B20EA0C006D705B495750E2E78C4D1739347BF4628DF3F6A301DEDFCA7FA60D139B942338E8375471A1B33DF30316AF5584142D8B1E1F2C6966A08E2D70AED5DEC84968CAE5881587A734DEAD037A97EB384E4E07960EB4A64774579094763B71999D0783E95117BAB533C42516FE26A5F1C35F4FA2AF2B4F7A72E84B805DC31E8709BC36505F09954BDE0C86C918BC34FFD230491BECF307F1522AF4835C444D3CDBD0B00907B9CC3F483A51591659652378FF7C799373C2C40D238F8A2EBF6CDBC7FB26CE2748CCA89B85638CA12E7F5C477BB4FA0ED536BCCC7B3CFFC9E9D9126A8B1F56540A919A21439B66F3DF4C81A057B630176733B89AF3A29C297E2C0460265246AD68BF34E02391AD8C4601537B2B6BBD22C921D35574EFF85B1FE6C8A7BD6662CBF96D990929203D471F7648A7EDFC1E3AD551DFB688C6AC06E0F47844085C7485B00B5CDB3A3A449B26E104562531A12268ADC308F5095B066C0F82BD722D48A572EFC0F28865AE6EE37E39CAF2548C2B44780945AE573F8469ECC546FCEABCE9F518477ECC21B23B3E0532530795F1613B59C86EC0ACE047938CEC19C46CDCA59633F4712F989EFBDF065A5F64883C1E3960D7BCFE9FAB9B04A6DC4FB4BDA363E7A3967DF393799619DA22C6D2ECA276A6E9801CC1DCFBDBDD9985C09463B2F2CD57C922BF8FF65964A7B5EA4108F547F5D2FD328DD6A34C2B581AEDB7949AB8FCFCDA54CF -20240329004423 2 6 100 7679 5 D4279A076EDA914DE80D14AF2DCB0B98294B99F706FBC061EF9007F2FA5897AEAF52D11A38EABEBA1EE590E35650894BA7669CE22689E6B50F11858063244F6BFBD664B19BA7ABD81CF1B65852069F215E8A1E1E72B3DFE09CAAFEC80797FF9F7AC81B6FB4A8813551385CD0D679E3F56BBFDC9069C7EB860A985C0170EA7899D76AD2D05AFD42205537E7BEB5782C27D2E6EF1532CEB5158BA23AC9E115AB472A1571A37E03439EFA47A04F61839D0DC47A8C7E2D13C9A018E87B5EB6B804AF7147814742D908212DBFB893171BC1713680CB1A036CBD0A6B6280F4D7B798913A9B59299E98F7553F202B0F33A2F67D6BB0071803DAD35595103E073F992321C4FFFCEB4F6AF4D3ADC9B53C41D8EFE7FE7AFE531E6485F8C087F18DD6B5A73101AE84737CAB85244E3FE085806104A9323907A94B06C437EE31D89AF7A584DE2F18DAD1A8E57FE1BAF5E2CC773EE57781F69A5D1EC4D8EB468BA9432394B5A9AD2F53B58A264B9C8E015F209DF60F865209482EDF309A575724A16E211CFC448799E4F05A9C2B1F09BDDECFB33FCC71211A646D8482F9A6EC20F10B38218A62182EB0E55BFF9BBA85585242B8BEFF20F1C88DFF9B20EA0C006D705B495750E2E78C4D1739347BF4628DF3F6A301DEDFCA7FA60D139B942338E8375471A1B33DF30316AF5584142D8B1E1F2C6966A08E2D70AED5DEC84968CAE5881587A734DEAD037A97EB384E4E07960EB4A64774579094763B71999D0783E95117BAB533C42516FE26A5F1C35F4FA2AF2B4F7A72E84B805DC31E8709BC36505F09954BDE0C86C918BC34FFD230491BECF307F1522AF4835C444D3CDBD0B00907B9CC3F483A51591659652378FF7C799373C2C40D238F8A2EBF6CDBC7FB26CE2748CCA89B85638CA12E7F5C477BB4FA0ED536BCCC7B3CFFC9E9D9126A8B1F56540A919A21439B66F3DF4C81A057B630176733B89AF3A29C297E2C0460265246AD68BF34E02391AD8C4601537B2B6BBD22C921D35574EFF85B1FE6C8A7BD6662CBF96D990929203D471F7648A7EDFC1E3AD551DFB688C6AC06E0F47844085C7485B00B5CDB3A3A449B26E104562531A12268ADC308F5095B066C0F82BD722D48A572EFC0F28865AE6EE37E39CAF2548C2B44780945AE573F8469ECC546FCEABCE9F518477ECC21B23B3E0532530795F1613B59C86EC0ACE047938CEC19C46CDCA59633F4712F989EFBDF065A5F64883C1E3960D7BCFE9FAB9B04A6DC4FB4BDA363E7A3967DF393799619DA22C6D2ECA276A6E9801CC1DCFBDBDD9985C09463B2F2CD57C922BF8FF65964A7B5EA4108F547F5D2FD328DD6A34C2B581AEDB7949AB8FD04B953EF -20240329024223 2 6 100 7679 5 D4279A076EDA914DE80D14AF2DCB0B98294B99F706FBC061EF9007F2FA5897AEAF52D11A38EABEBA1EE590E35650894BA7669CE22689E6B50F11858063244F6BFBD664B19BA7ABD81CF1B65852069F215E8A1E1E72B3DFE09CAAFEC80797FF9F7AC81B6FB4A8813551385CD0D679E3F56BBFDC9069C7EB860A985C0170EA7899D76AD2D05AFD42205537E7BEB5782C27D2E6EF1532CEB5158BA23AC9E115AB472A1571A37E03439EFA47A04F61839D0DC47A8C7E2D13C9A018E87B5EB6B804AF7147814742D908212DBFB893171BC1713680CB1A036CBD0A6B6280F4D7B798913A9B59299E98F7553F202B0F33A2F67D6BB0071803DAD35595103E073F992321C4FFFCEB4F6AF4D3ADC9B53C41D8EFE7FE7AFE531E6485F8C087F18DD6B5A73101AE84737CAB85244E3FE085806104A9323907A94B06C437EE31D89AF7A584DE2F18DAD1A8E57FE1BAF5E2CC773EE57781F69A5D1EC4D8EB468BA9432394B5A9AD2F53B58A264B9C8E015F209DF60F865209482EDF309A575724A16E211CFC448799E4F05A9C2B1F09BDDECFB33FCC71211A646D8482F9A6EC20F10B38218A62182EB0E55BFF9BBA85585242B8BEFF20F1C88DFF9B20EA0C006D705B495750E2E78C4D1739347BF4628DF3F6A301DEDFCA7FA60D139B942338E8375471A1B33DF30316AF5584142D8B1E1F2C6966A08E2D70AED5DEC84968CAE5881587A734DEAD037A97EB384E4E07960EB4A64774579094763B71999D0783E95117BAB533C42516FE26A5F1C35F4FA2AF2B4F7A72E84B805DC31E8709BC36505F09954BDE0C86C918BC34FFD230491BECF307F1522AF4835C444D3CDBD0B00907B9CC3F483A51591659652378FF7C799373C2C40D238F8A2EBF6CDBC7FB26CE2748CCA89B85638CA12E7F5C477BB4FA0ED536BCCC7B3CFFC9E9D9126A8B1F56540A919A21439B66F3DF4C81A057B630176733B89AF3A29C297E2C0460265246AD68BF34E02391AD8C4601537B2B6BBD22C921D35574EFF85B1FE6C8A7BD6662CBF96D990929203D471F7648A7EDFC1E3AD551DFB688C6AC06E0F47844085C7485B00B5CDB3A3A449B26E104562531A12268ADC308F5095B066C0F82BD722D48A572EFC0F28865AE6EE37E39CAF2548C2B44780945AE573F8469ECC546FCEABCE9F518477ECC21B23B3E0532530795F1613B59C86EC0ACE047938CEC19C46CDCA59633F4712F989EFBDF065A5F64883C1E3960D7BCFE9FAB9B04A6DC4FB4BDA363E7A3967DF393799619DA22C6D2ECA276A6E9801CC1DCFBDBDD9985C09463B2F2CD57C922BF8FF65964A7B5EA4108F547F5D2FD328DD6A34C2B581AEDB7949AB8FD0BE0B937 -20240329035503 2 6 100 7679 5 D4279A076EDA914DE80D14AF2DCB0B98294B99F706FBC061EF9007F2FA5897AEAF52D11A38EABEBA1EE590E35650894BA7669CE22689E6B50F11858063244F6BFBD664B19BA7ABD81CF1B65852069F215E8A1E1E72B3DFE09CAAFEC80797FF9F7AC81B6FB4A8813551385CD0D679E3F56BBFDC9069C7EB860A985C0170EA7899D76AD2D05AFD42205537E7BEB5782C27D2E6EF1532CEB5158BA23AC9E115AB472A1571A37E03439EFA47A04F61839D0DC47A8C7E2D13C9A018E87B5EB6B804AF7147814742D908212DBFB893171BC1713680CB1A036CBD0A6B6280F4D7B798913A9B59299E98F7553F202B0F33A2F67D6BB0071803DAD35595103E073F992321C4FFFCEB4F6AF4D3ADC9B53C41D8EFE7FE7AFE531E6485F8C087F18DD6B5A73101AE84737CAB85244E3FE085806104A9323907A94B06C437EE31D89AF7A584DE2F18DAD1A8E57FE1BAF5E2CC773EE57781F69A5D1EC4D8EB468BA9432394B5A9AD2F53B58A264B9C8E015F209DF60F865209482EDF309A575724A16E211CFC448799E4F05A9C2B1F09BDDECFB33FCC71211A646D8482F9A6EC20F10B38218A62182EB0E55BFF9BBA85585242B8BEFF20F1C88DFF9B20EA0C006D705B495750E2E78C4D1739347BF4628DF3F6A301DEDFCA7FA60D139B942338E8375471A1B33DF30316AF5584142D8B1E1F2C6966A08E2D70AED5DEC84968CAE5881587A734DEAD037A97EB384E4E07960EB4A64774579094763B71999D0783E95117BAB533C42516FE26A5F1C35F4FA2AF2B4F7A72E84B805DC31E8709BC36505F09954BDE0C86C918BC34FFD230491BECF307F1522AF4835C444D3CDBD0B00907B9CC3F483A51591659652378FF7C799373C2C40D238F8A2EBF6CDBC7FB26CE2748CCA89B85638CA12E7F5C477BB4FA0ED536BCCC7B3CFFC9E9D9126A8B1F56540A919A21439B66F3DF4C81A057B630176733B89AF3A29C297E2C0460265246AD68BF34E02391AD8C4601537B2B6BBD22C921D35574EFF85B1FE6C8A7BD6662CBF96D990929203D471F7648A7EDFC1E3AD551DFB688C6AC06E0F47844085C7485B00B5CDB3A3A449B26E104562531A12268ADC308F5095B066C0F82BD722D48A572EFC0F28865AE6EE37E39CAF2548C2B44780945AE573F8469ECC546FCEABCE9F518477ECC21B23B3E0532530795F1613B59C86EC0ACE047938CEC19C46CDCA59633F4712F989EFBDF065A5F64883C1E3960D7BCFE9FAB9B04A6DC4FB4BDA363E7A3967DF393799619DA22C6D2ECA276A6E9801CC1DCFBDBDD9985C09463B2F2CD57C922BF8FF65964A7B5EA4108F547F5D2FD328DD6A34C2B581AEDB7949AB8FD10BA6927 -20240329035634 2 6 100 7679 5 D4279A076EDA914DE80D14AF2DCB0B98294B99F706FBC061EF9007F2FA5897AEAF52D11A38EABEBA1EE590E35650894BA7669CE22689E6B50F11858063244F6BFBD664B19BA7ABD81CF1B65852069F215E8A1E1E72B3DFE09CAAFEC80797FF9F7AC81B6FB4A8813551385CD0D679E3F56BBFDC9069C7EB860A985C0170EA7899D76AD2D05AFD42205537E7BEB5782C27D2E6EF1532CEB5158BA23AC9E115AB472A1571A37E03439EFA47A04F61839D0DC47A8C7E2D13C9A018E87B5EB6B804AF7147814742D908212DBFB893171BC1713680CB1A036CBD0A6B6280F4D7B798913A9B59299E98F7553F202B0F33A2F67D6BB0071803DAD35595103E073F992321C4FFFCEB4F6AF4D3ADC9B53C41D8EFE7FE7AFE531E6485F8C087F18DD6B5A73101AE84737CAB85244E3FE085806104A9323907A94B06C437EE31D89AF7A584DE2F18DAD1A8E57FE1BAF5E2CC773EE57781F69A5D1EC4D8EB468BA9432394B5A9AD2F53B58A264B9C8E015F209DF60F865209482EDF309A575724A16E211CFC448799E4F05A9C2B1F09BDDECFB33FCC71211A646D8482F9A6EC20F10B38218A62182EB0E55BFF9BBA85585242B8BEFF20F1C88DFF9B20EA0C006D705B495750E2E78C4D1739347BF4628DF3F6A301DEDFCA7FA60D139B942338E8375471A1B33DF30316AF5584142D8B1E1F2C6966A08E2D70AED5DEC84968CAE5881587A734DEAD037A97EB384E4E07960EB4A64774579094763B71999D0783E95117BAB533C42516FE26A5F1C35F4FA2AF2B4F7A72E84B805DC31E8709BC36505F09954BDE0C86C918BC34FFD230491BECF307F1522AF4835C444D3CDBD0B00907B9CC3F483A51591659652378FF7C799373C2C40D238F8A2EBF6CDBC7FB26CE2748CCA89B85638CA12E7F5C477BB4FA0ED536BCCC7B3CFFC9E9D9126A8B1F56540A919A21439B66F3DF4C81A057B630176733B89AF3A29C297E2C0460265246AD68BF34E02391AD8C4601537B2B6BBD22C921D35574EFF85B1FE6C8A7BD6662CBF96D990929203D471F7648A7EDFC1E3AD551DFB688C6AC06E0F47844085C7485B00B5CDB3A3A449B26E104562531A12268ADC308F5095B066C0F82BD722D48A572EFC0F28865AE6EE37E39CAF2548C2B44780945AE573F8469ECC546FCEABCE9F518477ECC21B23B3E0532530795F1613B59C86EC0ACE047938CEC19C46CDCA59633F4712F989EFBDF065A5F64883C1E3960D7BCFE9FAB9B04A6DC4FB4BDA363E7A3967DF393799619DA22C6D2ECA276A6E9801CC1DCFBDBDD9985C09463B2F2CD57C922BF8FF65964A7B5EA4108F547F5D2FD328DD6A34C2B581AEDB7949AB8FD10CC8C1F -20240329035914 2 6 100 7679 2 D4279A076EDA914DE80D14AF2DCB0B98294B99F706FBC061EF9007F2FA5897AEAF52D11A38EABEBA1EE590E35650894BA7669CE22689E6B50F11858063244F6BFBD664B19BA7ABD81CF1B65852069F215E8A1E1E72B3DFE09CAAFEC80797FF9F7AC81B6FB4A8813551385CD0D679E3F56BBFDC9069C7EB860A985C0170EA7899D76AD2D05AFD42205537E7BEB5782C27D2E6EF1532CEB5158BA23AC9E115AB472A1571A37E03439EFA47A04F61839D0DC47A8C7E2D13C9A018E87B5EB6B804AF7147814742D908212DBFB893171BC1713680CB1A036CBD0A6B6280F4D7B798913A9B59299E98F7553F202B0F33A2F67D6BB0071803DAD35595103E073F992321C4FFFCEB4F6AF4D3ADC9B53C41D8EFE7FE7AFE531E6485F8C087F18DD6B5A73101AE84737CAB85244E3FE085806104A9323907A94B06C437EE31D89AF7A584DE2F18DAD1A8E57FE1BAF5E2CC773EE57781F69A5D1EC4D8EB468BA9432394B5A9AD2F53B58A264B9C8E015F209DF60F865209482EDF309A575724A16E211CFC448799E4F05A9C2B1F09BDDECFB33FCC71211A646D8482F9A6EC20F10B38218A62182EB0E55BFF9BBA85585242B8BEFF20F1C88DFF9B20EA0C006D705B495750E2E78C4D1739347BF4628DF3F6A301DEDFCA7FA60D139B942338E8375471A1B33DF30316AF5584142D8B1E1F2C6966A08E2D70AED5DEC84968CAE5881587A734DEAD037A97EB384E4E07960EB4A64774579094763B71999D0783E95117BAB533C42516FE26A5F1C35F4FA2AF2B4F7A72E84B805DC31E8709BC36505F09954BDE0C86C918BC34FFD230491BECF307F1522AF4835C444D3CDBD0B00907B9CC3F483A51591659652378FF7C799373C2C40D238F8A2EBF6CDBC7FB26CE2748CCA89B85638CA12E7F5C477BB4FA0ED536BCCC7B3CFFC9E9D9126A8B1F56540A919A21439B66F3DF4C81A057B630176733B89AF3A29C297E2C0460265246AD68BF34E02391AD8C4601537B2B6BBD22C921D35574EFF85B1FE6C8A7BD6662CBF96D990929203D471F7648A7EDFC1E3AD551DFB688C6AC06E0F47844085C7485B00B5CDB3A3A449B26E104562531A12268ADC308F5095B066C0F82BD722D48A572EFC0F28865AE6EE37E39CAF2548C2B44780945AE573F8469ECC546FCEABCE9F518477ECC21B23B3E0532530795F1613B59C86EC0ACE047938CEC19C46CDCA59633F4712F989EFBDF065A5F64883C1E3960D7BCFE9FAB9B04A6DC4FB4BDA363E7A3967DF393799619DA22C6D2ECA276A6E9801CC1DCFBDBDD9985C09463B2F2CD57C922BF8FF65964A7B5EA4108F547F5D2FD328DD6A34C2B581AEDB7949AB8FD10F42063 -20240329045640 2 6 100 7679 2 D4279A076EDA914DE80D14AF2DCB0B98294B99F706FBC061EF9007F2FA5897AEAF52D11A38EABEBA1EE590E35650894BA7669CE22689E6B50F11858063244F6BFBD664B19BA7ABD81CF1B65852069F215E8A1E1E72B3DFE09CAAFEC80797FF9F7AC81B6FB4A8813551385CD0D679E3F56BBFDC9069C7EB860A985C0170EA7899D76AD2D05AFD42205537E7BEB5782C27D2E6EF1532CEB5158BA23AC9E115AB472A1571A37E03439EFA47A04F61839D0DC47A8C7E2D13C9A018E87B5EB6B804AF7147814742D908212DBFB893171BC1713680CB1A036CBD0A6B6280F4D7B798913A9B59299E98F7553F202B0F33A2F67D6BB0071803DAD35595103E073F992321C4FFFCEB4F6AF4D3ADC9B53C41D8EFE7FE7AFE531E6485F8C087F18DD6B5A73101AE84737CAB85244E3FE085806104A9323907A94B06C437EE31D89AF7A584DE2F18DAD1A8E57FE1BAF5E2CC773EE57781F69A5D1EC4D8EB468BA9432394B5A9AD2F53B58A264B9C8E015F209DF60F865209482EDF309A575724A16E211CFC448799E4F05A9C2B1F09BDDECFB33FCC71211A646D8482F9A6EC20F10B38218A62182EB0E55BFF9BBA85585242B8BEFF20F1C88DFF9B20EA0C006D705B495750E2E78C4D1739347BF4628DF3F6A301DEDFCA7FA60D139B942338E8375471A1B33DF30316AF5584142D8B1E1F2C6966A08E2D70AED5DEC84968CAE5881587A734DEAD037A97EB384E4E07960EB4A64774579094763B71999D0783E95117BAB533C42516FE26A5F1C35F4FA2AF2B4F7A72E84B805DC31E8709BC36505F09954BDE0C86C918BC34FFD230491BECF307F1522AF4835C444D3CDBD0B00907B9CC3F483A51591659652378FF7C799373C2C40D238F8A2EBF6CDBC7FB26CE2748CCA89B85638CA12E7F5C477BB4FA0ED536BCCC7B3CFFC9E9D9126A8B1F56540A919A21439B66F3DF4C81A057B630176733B89AF3A29C297E2C0460265246AD68BF34E02391AD8C4601537B2B6BBD22C921D35574EFF85B1FE6C8A7BD6662CBF96D990929203D471F7648A7EDFC1E3AD551DFB688C6AC06E0F47844085C7485B00B5CDB3A3A449B26E104562531A12268ADC308F5095B066C0F82BD722D48A572EFC0F28865AE6EE37E39CAF2548C2B44780945AE573F8469ECC546FCEABCE9F518477ECC21B23B3E0532530795F1613B59C86EC0ACE047938CEC19C46CDCA59633F4712F989EFBDF065A5F64883C1E3960D7BCFE9FAB9B04A6DC4FB4BDA363E7A3967DF393799619DA22C6D2ECA276A6E9801CC1DCFBDBDD9985C09463B2F2CD57C922BF8FF65964A7B5EA4108F547F5D2FD328DD6A34C2B581AEDB7949AB8FD14CA5323 -20240329050935 2 6 100 7679 2 D4279A076EDA914DE80D14AF2DCB0B98294B99F706FBC061EF9007F2FA5897AEAF52D11A38EABEBA1EE590E35650894BA7669CE22689E6B50F11858063244F6BFBD664B19BA7ABD81CF1B65852069F215E8A1E1E72B3DFE09CAAFEC80797FF9F7AC81B6FB4A8813551385CD0D679E3F56BBFDC9069C7EB860A985C0170EA7899D76AD2D05AFD42205537E7BEB5782C27D2E6EF1532CEB5158BA23AC9E115AB472A1571A37E03439EFA47A04F61839D0DC47A8C7E2D13C9A018E87B5EB6B804AF7147814742D908212DBFB893171BC1713680CB1A036CBD0A6B6280F4D7B798913A9B59299E98F7553F202B0F33A2F67D6BB0071803DAD35595103E073F992321C4FFFCEB4F6AF4D3ADC9B53C41D8EFE7FE7AFE531E6485F8C087F18DD6B5A73101AE84737CAB85244E3FE085806104A9323907A94B06C437EE31D89AF7A584DE2F18DAD1A8E57FE1BAF5E2CC773EE57781F69A5D1EC4D8EB468BA9432394B5A9AD2F53B58A264B9C8E015F209DF60F865209482EDF309A575724A16E211CFC448799E4F05A9C2B1F09BDDECFB33FCC71211A646D8482F9A6EC20F10B38218A62182EB0E55BFF9BBA85585242B8BEFF20F1C88DFF9B20EA0C006D705B495750E2E78C4D1739347BF4628DF3F6A301DEDFCA7FA60D139B942338E8375471A1B33DF30316AF5584142D8B1E1F2C6966A08E2D70AED5DEC84968CAE5881587A734DEAD037A97EB384E4E07960EB4A64774579094763B71999D0783E95117BAB533C42516FE26A5F1C35F4FA2AF2B4F7A72E84B805DC31E8709BC36505F09954BDE0C86C918BC34FFD230491BECF307F1522AF4835C444D3CDBD0B00907B9CC3F483A51591659652378FF7C799373C2C40D238F8A2EBF6CDBC7FB26CE2748CCA89B85638CA12E7F5C477BB4FA0ED536BCCC7B3CFFC9E9D9126A8B1F56540A919A21439B66F3DF4C81A057B630176733B89AF3A29C297E2C0460265246AD68BF34E02391AD8C4601537B2B6BBD22C921D35574EFF85B1FE6C8A7BD6662CBF96D990929203D471F7648A7EDFC1E3AD551DFB688C6AC06E0F47844085C7485B00B5CDB3A3A449B26E104562531A12268ADC308F5095B066C0F82BD722D48A572EFC0F28865AE6EE37E39CAF2548C2B44780945AE573F8469ECC546FCEABCE9F518477ECC21B23B3E0532530795F1613B59C86EC0ACE047938CEC19C46CDCA59633F4712F989EFBDF065A5F64883C1E3960D7BCFE9FAB9B04A6DC4FB4BDA363E7A3967DF393799619DA22C6D2ECA276A6E9801CC1DCFBDBDD9985C09463B2F2CD57C922BF8FF65964A7B5EA4108F547F5D2FD328DD6A34C2B581AEDB7949AB8FD159E9383 -20240329053141 2 6 100 7679 2 D4279A076EDA914DE80D14AF2DCB0B98294B99F706FBC061EF9007F2FA5897AEAF52D11A38EABEBA1EE590E35650894BA7669CE22689E6B50F11858063244F6BFBD664B19BA7ABD81CF1B65852069F215E8A1E1E72B3DFE09CAAFEC80797FF9F7AC81B6FB4A8813551385CD0D679E3F56BBFDC9069C7EB860A985C0170EA7899D76AD2D05AFD42205537E7BEB5782C27D2E6EF1532CEB5158BA23AC9E115AB472A1571A37E03439EFA47A04F61839D0DC47A8C7E2D13C9A018E87B5EB6B804AF7147814742D908212DBFB893171BC1713680CB1A036CBD0A6B6280F4D7B798913A9B59299E98F7553F202B0F33A2F67D6BB0071803DAD35595103E073F992321C4FFFCEB4F6AF4D3ADC9B53C41D8EFE7FE7AFE531E6485F8C087F18DD6B5A73101AE84737CAB85244E3FE085806104A9323907A94B06C437EE31D89AF7A584DE2F18DAD1A8E57FE1BAF5E2CC773EE57781F69A5D1EC4D8EB468BA9432394B5A9AD2F53B58A264B9C8E015F209DF60F865209482EDF309A575724A16E211CFC448799E4F05A9C2B1F09BDDECFB33FCC71211A646D8482F9A6EC20F10B38218A62182EB0E55BFF9BBA85585242B8BEFF20F1C88DFF9B20EA0C006D705B495750E2E78C4D1739347BF4628DF3F6A301DEDFCA7FA60D139B942338E8375471A1B33DF30316AF5584142D8B1E1F2C6966A08E2D70AED5DEC84968CAE5881587A734DEAD037A97EB384E4E07960EB4A64774579094763B71999D0783E95117BAB533C42516FE26A5F1C35F4FA2AF2B4F7A72E84B805DC31E8709BC36505F09954BDE0C86C918BC34FFD230491BECF307F1522AF4835C444D3CDBD0B00907B9CC3F483A51591659652378FF7C799373C2C40D238F8A2EBF6CDBC7FB26CE2748CCA89B85638CA12E7F5C477BB4FA0ED536BCCC7B3CFFC9E9D9126A8B1F56540A919A21439B66F3DF4C81A057B630176733B89AF3A29C297E2C0460265246AD68BF34E02391AD8C4601537B2B6BBD22C921D35574EFF85B1FE6C8A7BD6662CBF96D990929203D471F7648A7EDFC1E3AD551DFB688C6AC06E0F47844085C7485B00B5CDB3A3A449B26E104562531A12268ADC308F5095B066C0F82BD722D48A572EFC0F28865AE6EE37E39CAF2548C2B44780945AE573F8469ECC546FCEABCE9F518477ECC21B23B3E0532530795F1613B59C86EC0ACE047938CEC19C46CDCA59633F4712F989EFBDF065A5F64883C1E3960D7BCFE9FAB9B04A6DC4FB4BDA363E7A3967DF393799619DA22C6D2ECA276A6E9801CC1DCFBDBDD9985C09463B2F2CD57C922BF8FF65964A7B5EA4108F547F5D2FD328DD6A34C2B581AEDB7949AB8FD170D04C3 -20240329054343 2 6 100 7679 2 D4279A076EDA914DE80D14AF2DCB0B98294B99F706FBC061EF9007F2FA5897AEAF52D11A38EABEBA1EE590E35650894BA7669CE22689E6B50F11858063244F6BFBD664B19BA7ABD81CF1B65852069F215E8A1E1E72B3DFE09CAAFEC80797FF9F7AC81B6FB4A8813551385CD0D679E3F56BBFDC9069C7EB860A985C0170EA7899D76AD2D05AFD42205537E7BEB5782C27D2E6EF1532CEB5158BA23AC9E115AB472A1571A37E03439EFA47A04F61839D0DC47A8C7E2D13C9A018E87B5EB6B804AF7147814742D908212DBFB893171BC1713680CB1A036CBD0A6B6280F4D7B798913A9B59299E98F7553F202B0F33A2F67D6BB0071803DAD35595103E073F992321C4FFFCEB4F6AF4D3ADC9B53C41D8EFE7FE7AFE531E6485F8C087F18DD6B5A73101AE84737CAB85244E3FE085806104A9323907A94B06C437EE31D89AF7A584DE2F18DAD1A8E57FE1BAF5E2CC773EE57781F69A5D1EC4D8EB468BA9432394B5A9AD2F53B58A264B9C8E015F209DF60F865209482EDF309A575724A16E211CFC448799E4F05A9C2B1F09BDDECFB33FCC71211A646D8482F9A6EC20F10B38218A62182EB0E55BFF9BBA85585242B8BEFF20F1C88DFF9B20EA0C006D705B495750E2E78C4D1739347BF4628DF3F6A301DEDFCA7FA60D139B942338E8375471A1B33DF30316AF5584142D8B1E1F2C6966A08E2D70AED5DEC84968CAE5881587A734DEAD037A97EB384E4E07960EB4A64774579094763B71999D0783E95117BAB533C42516FE26A5F1C35F4FA2AF2B4F7A72E84B805DC31E8709BC36505F09954BDE0C86C918BC34FFD230491BECF307F1522AF4835C444D3CDBD0B00907B9CC3F483A51591659652378FF7C799373C2C40D238F8A2EBF6CDBC7FB26CE2748CCA89B85638CA12E7F5C477BB4FA0ED536BCCC7B3CFFC9E9D9126A8B1F56540A919A21439B66F3DF4C81A057B630176733B89AF3A29C297E2C0460265246AD68BF34E02391AD8C4601537B2B6BBD22C921D35574EFF85B1FE6C8A7BD6662CBF96D990929203D471F7648A7EDFC1E3AD551DFB688C6AC06E0F47844085C7485B00B5CDB3A3A449B26E104562531A12268ADC308F5095B066C0F82BD722D48A572EFC0F28865AE6EE37E39CAF2548C2B44780945AE573F8469ECC546FCEABCE9F518477ECC21B23B3E0532530795F1613B59C86EC0ACE047938CEC19C46CDCA59633F4712F989EFBDF065A5F64883C1E3960D7BCFE9FAB9B04A6DC4FB4BDA363E7A3967DF393799619DA22C6D2ECA276A6E9801CC1DCFBDBDD9985C09463B2F2CD57C922BF8FF65964A7B5EA4108F547F5D2FD328DD6A34C2B581AEDB7949AB8FD17D323FB -20240329062142 2 6 100 7679 5 D4279A076EDA914DE80D14AF2DCB0B98294B99F706FBC061EF9007F2FA5897AEAF52D11A38EABEBA1EE590E35650894BA7669CE22689E6B50F11858063244F6BFBD664B19BA7ABD81CF1B65852069F215E8A1E1E72B3DFE09CAAFEC80797FF9F7AC81B6FB4A8813551385CD0D679E3F56BBFDC9069C7EB860A985C0170EA7899D76AD2D05AFD42205537E7BEB5782C27D2E6EF1532CEB5158BA23AC9E115AB472A1571A37E03439EFA47A04F61839D0DC47A8C7E2D13C9A018E87B5EB6B804AF7147814742D908212DBFB893171BC1713680CB1A036CBD0A6B6280F4D7B798913A9B59299E98F7553F202B0F33A2F67D6BB0071803DAD35595103E073F992321C4FFFCEB4F6AF4D3ADC9B53C41D8EFE7FE7AFE531E6485F8C087F18DD6B5A73101AE84737CAB85244E3FE085806104A9323907A94B06C437EE31D89AF7A584DE2F18DAD1A8E57FE1BAF5E2CC773EE57781F69A5D1EC4D8EB468BA9432394B5A9AD2F53B58A264B9C8E015F209DF60F865209482EDF309A575724A16E211CFC448799E4F05A9C2B1F09BDDECFB33FCC71211A646D8482F9A6EC20F10B38218A62182EB0E55BFF9BBA85585242B8BEFF20F1C88DFF9B20EA0C006D705B495750E2E78C4D1739347BF4628DF3F6A301DEDFCA7FA60D139B942338E8375471A1B33DF30316AF5584142D8B1E1F2C6966A08E2D70AED5DEC84968CAE5881587A734DEAD037A97EB384E4E07960EB4A64774579094763B71999D0783E95117BAB533C42516FE26A5F1C35F4FA2AF2B4F7A72E84B805DC31E8709BC36505F09954BDE0C86C918BC34FFD230491BECF307F1522AF4835C444D3CDBD0B00907B9CC3F483A51591659652378FF7C799373C2C40D238F8A2EBF6CDBC7FB26CE2748CCA89B85638CA12E7F5C477BB4FA0ED536BCCC7B3CFFC9E9D9126A8B1F56540A919A21439B66F3DF4C81A057B630176733B89AF3A29C297E2C0460265246AD68BF34E02391AD8C4601537B2B6BBD22C921D35574EFF85B1FE6C8A7BD6662CBF96D990929203D471F7648A7EDFC1E3AD551DFB688C6AC06E0F47844085C7485B00B5CDB3A3A449B26E104562531A12268ADC308F5095B066C0F82BD722D48A572EFC0F28865AE6EE37E39CAF2548C2B44780945AE573F8469ECC546FCEABCE9F518477ECC21B23B3E0532530795F1613B59C86EC0ACE047938CEC19C46CDCA59633F4712F989EFBDF065A5F64883C1E3960D7BCFE9FAB9B04A6DC4FB4BDA363E7A3967DF393799619DA22C6D2ECA276A6E9801CC1DCFBDBDD9985C09463B2F2CD57C922BF8FF65964A7B5EA4108F547F5D2FD328DD6A34C2B581AEDB7949AB8FD1A5DB2DF -20240329073301 2 6 100 7679 5 D4279A076EDA914DE80D14AF2DCB0B98294B99F706FBC061EF9007F2FA5897AEAF52D11A38EABEBA1EE590E35650894BA7669CE22689E6B50F11858063244F6BFBD664B19BA7ABD81CF1B65852069F215E8A1E1E72B3DFE09CAAFEC80797FF9F7AC81B6FB4A8813551385CD0D679E3F56BBFDC9069C7EB860A985C0170EA7899D76AD2D05AFD42205537E7BEB5782C27D2E6EF1532CEB5158BA23AC9E115AB472A1571A37E03439EFA47A04F61839D0DC47A8C7E2D13C9A018E87B5EB6B804AF7147814742D908212DBFB893171BC1713680CB1A036CBD0A6B6280F4D7B798913A9B59299E98F7553F202B0F33A2F67D6BB0071803DAD35595103E073F992321C4FFFCEB4F6AF4D3ADC9B53C41D8EFE7FE7AFE531E6485F8C087F18DD6B5A73101AE84737CAB85244E3FE085806104A9323907A94B06C437EE31D89AF7A584DE2F18DAD1A8E57FE1BAF5E2CC773EE57781F69A5D1EC4D8EB468BA9432394B5A9AD2F53B58A264B9C8E015F209DF60F865209482EDF309A575724A16E211CFC448799E4F05A9C2B1F09BDDECFB33FCC71211A646D8482F9A6EC20F10B38218A62182EB0E55BFF9BBA85585242B8BEFF20F1C88DFF9B20EA0C006D705B495750E2E78C4D1739347BF4628DF3F6A301DEDFCA7FA60D139B942338E8375471A1B33DF30316AF5584142D8B1E1F2C6966A08E2D70AED5DEC84968CAE5881587A734DEAD037A97EB384E4E07960EB4A64774579094763B71999D0783E95117BAB533C42516FE26A5F1C35F4FA2AF2B4F7A72E84B805DC31E8709BC36505F09954BDE0C86C918BC34FFD230491BECF307F1522AF4835C444D3CDBD0B00907B9CC3F483A51591659652378FF7C799373C2C40D238F8A2EBF6CDBC7FB26CE2748CCA89B85638CA12E7F5C477BB4FA0ED536BCCC7B3CFFC9E9D9126A8B1F56540A919A21439B66F3DF4C81A057B630176733B89AF3A29C297E2C0460265246AD68BF34E02391AD8C4601537B2B6BBD22C921D35574EFF85B1FE6C8A7BD6662CBF96D990929203D471F7648A7EDFC1E3AD551DFB688C6AC06E0F47844085C7485B00B5CDB3A3A449B26E104562531A12268ADC308F5095B066C0F82BD722D48A572EFC0F28865AE6EE37E39CAF2548C2B44780945AE573F8469ECC546FCEABCE9F518477ECC21B23B3E0532530795F1613B59C86EC0ACE047938CEC19C46CDCA59633F4712F989EFBDF065A5F64883C1E3960D7BCFE9FAB9B04A6DC4FB4BDA363E7A3967DF393799619DA22C6D2ECA276A6E9801CC1DCFBDBDD9985C09463B2F2CD57C922BF8FF65964A7B5EA4108F547F5D2FD328DD6A34C2B581AEDB7949AB8FD1F20E86F -20240329074920 2 6 100 7679 2 D4279A076EDA914DE80D14AF2DCB0B98294B99F706FBC061EF9007F2FA5897AEAF52D11A38EABEBA1EE590E35650894BA7669CE22689E6B50F11858063244F6BFBD664B19BA7ABD81CF1B65852069F215E8A1E1E72B3DFE09CAAFEC80797FF9F7AC81B6FB4A8813551385CD0D679E3F56BBFDC9069C7EB860A985C0170EA7899D76AD2D05AFD42205537E7BEB5782C27D2E6EF1532CEB5158BA23AC9E115AB472A1571A37E03439EFA47A04F61839D0DC47A8C7E2D13C9A018E87B5EB6B804AF7147814742D908212DBFB893171BC1713680CB1A036CBD0A6B6280F4D7B798913A9B59299E98F7553F202B0F33A2F67D6BB0071803DAD35595103E073F992321C4FFFCEB4F6AF4D3ADC9B53C41D8EFE7FE7AFE531E6485F8C087F18DD6B5A73101AE84737CAB85244E3FE085806104A9323907A94B06C437EE31D89AF7A584DE2F18DAD1A8E57FE1BAF5E2CC773EE57781F69A5D1EC4D8EB468BA9432394B5A9AD2F53B58A264B9C8E015F209DF60F865209482EDF309A575724A16E211CFC448799E4F05A9C2B1F09BDDECFB33FCC71211A646D8482F9A6EC20F10B38218A62182EB0E55BFF9BBA85585242B8BEFF20F1C88DFF9B20EA0C006D705B495750E2E78C4D1739347BF4628DF3F6A301DEDFCA7FA60D139B942338E8375471A1B33DF30316AF5584142D8B1E1F2C6966A08E2D70AED5DEC84968CAE5881587A734DEAD037A97EB384E4E07960EB4A64774579094763B71999D0783E95117BAB533C42516FE26A5F1C35F4FA2AF2B4F7A72E84B805DC31E8709BC36505F09954BDE0C86C918BC34FFD230491BECF307F1522AF4835C444D3CDBD0B00907B9CC3F483A51591659652378FF7C799373C2C40D238F8A2EBF6CDBC7FB26CE2748CCA89B85638CA12E7F5C477BB4FA0ED536BCCC7B3CFFC9E9D9126A8B1F56540A919A21439B66F3DF4C81A057B630176733B89AF3A29C297E2C0460265246AD68BF34E02391AD8C4601537B2B6BBD22C921D35574EFF85B1FE6C8A7BD6662CBF96D990929203D471F7648A7EDFC1E3AD551DFB688C6AC06E0F47844085C7485B00B5CDB3A3A449B26E104562531A12268ADC308F5095B066C0F82BD722D48A572EFC0F28865AE6EE37E39CAF2548C2B44780945AE573F8469ECC546FCEABCE9F518477ECC21B23B3E0532530795F1613B59C86EC0ACE047938CEC19C46CDCA59633F4712F989EFBDF065A5F64883C1E3960D7BCFE9FAB9B04A6DC4FB4BDA363E7A3967DF393799619DA22C6D2ECA276A6E9801CC1DCFBDBDD9985C09463B2F2CD57C922BF8FF65964A7B5EA4108F547F5D2FD328DD6A34C2B581AEDB7949AB8FD20377F03 -20240329085033 2 6 100 7679 2 D4279A076EDA914DE80D14AF2DCB0B98294B99F706FBC061EF9007F2FA5897AEAF52D11A38EABEBA1EE590E35650894BA7669CE22689E6B50F11858063244F6BFBD664B19BA7ABD81CF1B65852069F215E8A1E1E72B3DFE09CAAFEC80797FF9F7AC81B6FB4A8813551385CD0D679E3F56BBFDC9069C7EB860A985C0170EA7899D76AD2D05AFD42205537E7BEB5782C27D2E6EF1532CEB5158BA23AC9E115AB472A1571A37E03439EFA47A04F61839D0DC47A8C7E2D13C9A018E87B5EB6B804AF7147814742D908212DBFB893171BC1713680CB1A036CBD0A6B6280F4D7B798913A9B59299E98F7553F202B0F33A2F67D6BB0071803DAD35595103E073F992321C4FFFCEB4F6AF4D3ADC9B53C41D8EFE7FE7AFE531E6485F8C087F18DD6B5A73101AE84737CAB85244E3FE085806104A9323907A94B06C437EE31D89AF7A584DE2F18DAD1A8E57FE1BAF5E2CC773EE57781F69A5D1EC4D8EB468BA9432394B5A9AD2F53B58A264B9C8E015F209DF60F865209482EDF309A575724A16E211CFC448799E4F05A9C2B1F09BDDECFB33FCC71211A646D8482F9A6EC20F10B38218A62182EB0E55BFF9BBA85585242B8BEFF20F1C88DFF9B20EA0C006D705B495750E2E78C4D1739347BF4628DF3F6A301DEDFCA7FA60D139B942338E8375471A1B33DF30316AF5584142D8B1E1F2C6966A08E2D70AED5DEC84968CAE5881587A734DEAD037A97EB384E4E07960EB4A64774579094763B71999D0783E95117BAB533C42516FE26A5F1C35F4FA2AF2B4F7A72E84B805DC31E8709BC36505F09954BDE0C86C918BC34FFD230491BECF307F1522AF4835C444D3CDBD0B00907B9CC3F483A51591659652378FF7C799373C2C40D238F8A2EBF6CDBC7FB26CE2748CCA89B85638CA12E7F5C477BB4FA0ED536BCCC7B3CFFC9E9D9126A8B1F56540A919A21439B66F3DF4C81A057B630176733B89AF3A29C297E2C0460265246AD68BF34E02391AD8C4601537B2B6BBD22C921D35574EFF85B1FE6C8A7BD6662CBF96D990929203D471F7648A7EDFC1E3AD551DFB688C6AC06E0F47844085C7485B00B5CDB3A3A449B26E104562531A12268ADC308F5095B066C0F82BD722D48A572EFC0F28865AE6EE37E39CAF2548C2B44780945AE573F8469ECC546FCEABCE9F518477ECC21B23B3E0532530795F1613B59C86EC0ACE047938CEC19C46CDCA59633F4712F989EFBDF065A5F64883C1E3960D7BCFE9FAB9B04A6DC4FB4BDA363E7A3967DF393799619DA22C6D2ECA276A6E9801CC1DCFBDBDD9985C09463B2F2CD57C922BF8FF65964A7B5EA4108F547F5D2FD328DD6A34C2B581AEDB7949AB8FD242F4BCB -20240329121808 2 6 100 8191 2 C4FF326CB002CB4F25BB4309818DE616BCD6A04CB1C8D569FC4D34148B1D5D6B439D6DB946A264765BB6EAAE20B1B737C3CE28B7047D18B47C37ABECEC047E51A0541FE6434045192CE79898A70E6D93E12C35237219A6E3E00F88F5B1EE69982F0ECDA40DE90F5181A6F6F9BF5F9C497A1589ED3E2C16C68A41EA50D544BC57DB544F81F3DD6E6E09E0261A8FB2845A73A13156EBEC90719DE167262FAA68FA08DB412A918DE0D0C5585262DAB724FE31489205D7EA7C669DF4A4423E537153DB359EF31A71FE15C0707D46EE8EFF55305742BE773C6BAD327B2DB2829BF88216A275DFEBB04B3CFA2CF45507788E1DC5EDAFA03A03AD61CFCFE40D7CF7BF3712874CAA2C711691DD189B7024520B0B07D51095E91162FCA7203ECB4DDC9FFEA8355090AB20EEBA13F7901F5B71AB397CD097E0443DFAC8FED92DBBF2B38100E3CCB0118B2C8F27876D6067AF3EE9E44C7F44472C0DC419DE40E23D9DE359138028A9423328261E625A7381012787C370BC3C933C192EFE8CBF23F80271CBCA40F39D1BE4B4173997E646FEDB7AC81006E10D96559EDF6490A56FD47945E35A102C8B00EA740A7F1B53B4CC03D2DC302A8EA16971403CA8B826F6D56E307E04C75EDC1A8565A9EFBBE0F6ECA61D976649A23C82D9A8D7AC3E5124334916A75A6C8AA3B5DFB00FFEB893E6A7E7CEF0622C41C3FFB0B83C38A329E7144F6C06E789D897E3704817C6A79548B8D394EC53A460517DFD1513896B8360156561A5668AEF0F9F2D2B1CDBD4DAA8ED0C28E774EFE72D9FF758B97DAD89B305E5EC82BBC17733DB5F550EFFF1C45CBCA807BD7461C2D3C80FFDE3C1D4410DD678A94ADA54192EABFEC129C5F33DEADEF0C15B1D13782336637544FF1433E97022E45CFD560870ECD85CFF72944596B73DC7D9F978A07A47806E97EDB253019551791D6C62DEB669F5FA5EAA31FCDA0431C07AD97004F527C72548E9D22936D47D8963ABA0D82231473AF8CA45EBC59D93FCE197B7930AD7A82E3D780391A317097CFFA545DC42341FB1B265B851BBF55D95EF63A9AAFA4B2A78036751FBAABCBE9A8215B050AD478C3BF350462A4812A4FDE66FAC8B91718AAD80B68D21E5788F7CB3711F23F25EDBBDF7AC6DD9FBC110EBA2272750936C2F2A74CE5E69DE59A0B6359076EE3FB1D4F2779A6AC5753C860C2CA448E036EA15055D4A19148FE7BCD0AFA3B140A0203548A7A456ECDA8B9B9E740620291F14E21D08EEF21CE5676BB2434233E6C7CC62E48B9B752C87DC87E6DAE0A870E81D17E44AAF6982000A95B7EA676255A17D73FF4A45FAE0C5C9513B5EC0C6414D73EA9488373B6E2FFC9BD2E2C77394BB392F0AD23D91C99D9AA5066EBEE7123D00E223CA3CE572F667DBBD243473453DEC1A44CB979EF3898056D1E3B3A66DB1CB711B232291FA7C124806CA43 -20240329122442 2 6 100 8191 5 C4FF326CB002CB4F25BB4309818DE616BCD6A04CB1C8D569FC4D34148B1D5D6B439D6DB946A264765BB6EAAE20B1B737C3CE28B7047D18B47C37ABECEC047E51A0541FE6434045192CE79898A70E6D93E12C35237219A6E3E00F88F5B1EE69982F0ECDA40DE90F5181A6F6F9BF5F9C497A1589ED3E2C16C68A41EA50D544BC57DB544F81F3DD6E6E09E0261A8FB2845A73A13156EBEC90719DE167262FAA68FA08DB412A918DE0D0C5585262DAB724FE31489205D7EA7C669DF4A4423E537153DB359EF31A71FE15C0707D46EE8EFF55305742BE773C6BAD327B2DB2829BF88216A275DFEBB04B3CFA2CF45507788E1DC5EDAFA03A03AD61CFCFE40D7CF7BF3712874CAA2C711691DD189B7024520B0B07D51095E91162FCA7203ECB4DDC9FFEA8355090AB20EEBA13F7901F5B71AB397CD097E0443DFAC8FED92DBBF2B38100E3CCB0118B2C8F27876D6067AF3EE9E44C7F44472C0DC419DE40E23D9DE359138028A9423328261E625A7381012787C370BC3C933C192EFE8CBF23F80271CBCA40F39D1BE4B4173997E646FEDB7AC81006E10D96559EDF6490A56FD47945E35A102C8B00EA740A7F1B53B4CC03D2DC302A8EA16971403CA8B826F6D56E307E04C75EDC1A8565A9EFBBE0F6ECA61D976649A23C82D9A8D7AC3E5124334916A75A6C8AA3B5DFB00FFEB893E6A7E7CEF0622C41C3FFB0B83C38A329E7144F6C06E789D897E3704817C6A79548B8D394EC53A460517DFD1513896B8360156561A5668AEF0F9F2D2B1CDBD4DAA8ED0C28E774EFE72D9FF758B97DAD89B305E5EC82BBC17733DB5F550EFFF1C45CBCA807BD7461C2D3C80FFDE3C1D4410DD678A94ADA54192EABFEC129C5F33DEADEF0C15B1D13782336637544FF1433E97022E45CFD560870ECD85CFF72944596B73DC7D9F978A07A47806E97EDB253019551791D6C62DEB669F5FA5EAA31FCDA0431C07AD97004F527C72548E9D22936D47D8963ABA0D82231473AF8CA45EBC59D93FCE197B7930AD7A82E3D780391A317097CFFA545DC42341FB1B265B851BBF55D95EF63A9AAFA4B2A78036751FBAABCBE9A8215B050AD478C3BF350462A4812A4FDE66FAC8B91718AAD80B68D21E5788F7CB3711F23F25EDBBDF7AC6DD9FBC110EBA2272750936C2F2A74CE5E69DE59A0B6359076EE3FB1D4F2779A6AC5753C860C2CA448E036EA15055D4A19148FE7BCD0AFA3B140A0203548A7A456ECDA8B9B9E740620291F14E21D08EEF21CE5676BB2434233E6C7CC62E48B9B752C87DC87E6DAE0A870E81D17E44AAF6982000A95B7EA676255A17D73FF4A45FAE0C5C9513B5EC0C6414D73EA9488373B6E2FFC9BD2E2C77394BB392F0AD23D91C99D9AA5066EBEE7123D00E223CA3CE572F667DBBD243473453DEC1A44CB979EF3898056D1E3B3A66DB1CB711B232291FA7C12485AF08F -20240329153134 2 6 100 8191 5 C4FF326CB002CB4F25BB4309818DE616BCD6A04CB1C8D569FC4D34148B1D5D6B439D6DB946A264765BB6EAAE20B1B737C3CE28B7047D18B47C37ABECEC047E51A0541FE6434045192CE79898A70E6D93E12C35237219A6E3E00F88F5B1EE69982F0ECDA40DE90F5181A6F6F9BF5F9C497A1589ED3E2C16C68A41EA50D544BC57DB544F81F3DD6E6E09E0261A8FB2845A73A13156EBEC90719DE167262FAA68FA08DB412A918DE0D0C5585262DAB724FE31489205D7EA7C669DF4A4423E537153DB359EF31A71FE15C0707D46EE8EFF55305742BE773C6BAD327B2DB2829BF88216A275DFEBB04B3CFA2CF45507788E1DC5EDAFA03A03AD61CFCFE40D7CF7BF3712874CAA2C711691DD189B7024520B0B07D51095E91162FCA7203ECB4DDC9FFEA8355090AB20EEBA13F7901F5B71AB397CD097E0443DFAC8FED92DBBF2B38100E3CCB0118B2C8F27876D6067AF3EE9E44C7F44472C0DC419DE40E23D9DE359138028A9423328261E625A7381012787C370BC3C933C192EFE8CBF23F80271CBCA40F39D1BE4B4173997E646FEDB7AC81006E10D96559EDF6490A56FD47945E35A102C8B00EA740A7F1B53B4CC03D2DC302A8EA16971403CA8B826F6D56E307E04C75EDC1A8565A9EFBBE0F6ECA61D976649A23C82D9A8D7AC3E5124334916A75A6C8AA3B5DFB00FFEB893E6A7E7CEF0622C41C3FFB0B83C38A329E7144F6C06E789D897E3704817C6A79548B8D394EC53A460517DFD1513896B8360156561A5668AEF0F9F2D2B1CDBD4DAA8ED0C28E774EFE72D9FF758B97DAD89B305E5EC82BBC17733DB5F550EFFF1C45CBCA807BD7461C2D3C80FFDE3C1D4410DD678A94ADA54192EABFEC129C5F33DEADEF0C15B1D13782336637544FF1433E97022E45CFD560870ECD85CFF72944596B73DC7D9F978A07A47806E97EDB253019551791D6C62DEB669F5FA5EAA31FCDA0431C07AD97004F527C72548E9D22936D47D8963ABA0D82231473AF8CA45EBC59D93FCE197B7930AD7A82E3D780391A317097CFFA545DC42341FB1B265B851BBF55D95EF63A9AAFA4B2A78036751FBAABCBE9A8215B050AD478C3BF350462A4812A4FDE66FAC8B91718AAD80B68D21E5788F7CB3711F23F25EDBBDF7AC6DD9FBC110EBA2272750936C2F2A74CE5E69DE59A0B6359076EE3FB1D4F2779A6AC5753C860C2CA448E036EA15055D4A19148FE7BCD0AFA3B140A0203548A7A456ECDA8B9B9E740620291F14E21D08EEF21CE5676BB2434233E6C7CC62E48B9B752C87DC87E6DAE0A870E81D17E44AAF6982000A95B7EA676255A17D73FF4A45FAE0C5C9513B5EC0C6414D73EA9488373B6E2FFC9BD2E2C77394BB392F0AD23D91C99D9AA5066EBEE7123D00E223CA3CE572F667DBBD243473453DEC1A44CB979EF3898056D1E3B3A66DB1CB711B232291FA7C1252D3F0CF -20240329155254 2 6 100 8191 2 C4FF326CB002CB4F25BB4309818DE616BCD6A04CB1C8D569FC4D34148B1D5D6B439D6DB946A264765BB6EAAE20B1B737C3CE28B7047D18B47C37ABECEC047E51A0541FE6434045192CE79898A70E6D93E12C35237219A6E3E00F88F5B1EE69982F0ECDA40DE90F5181A6F6F9BF5F9C497A1589ED3E2C16C68A41EA50D544BC57DB544F81F3DD6E6E09E0261A8FB2845A73A13156EBEC90719DE167262FAA68FA08DB412A918DE0D0C5585262DAB724FE31489205D7EA7C669DF4A4423E537153DB359EF31A71FE15C0707D46EE8EFF55305742BE773C6BAD327B2DB2829BF88216A275DFEBB04B3CFA2CF45507788E1DC5EDAFA03A03AD61CFCFE40D7CF7BF3712874CAA2C711691DD189B7024520B0B07D51095E91162FCA7203ECB4DDC9FFEA8355090AB20EEBA13F7901F5B71AB397CD097E0443DFAC8FED92DBBF2B38100E3CCB0118B2C8F27876D6067AF3EE9E44C7F44472C0DC419DE40E23D9DE359138028A9423328261E625A7381012787C370BC3C933C192EFE8CBF23F80271CBCA40F39D1BE4B4173997E646FEDB7AC81006E10D96559EDF6490A56FD47945E35A102C8B00EA740A7F1B53B4CC03D2DC302A8EA16971403CA8B826F6D56E307E04C75EDC1A8565A9EFBBE0F6ECA61D976649A23C82D9A8D7AC3E5124334916A75A6C8AA3B5DFB00FFEB893E6A7E7CEF0622C41C3FFB0B83C38A329E7144F6C06E789D897E3704817C6A79548B8D394EC53A460517DFD1513896B8360156561A5668AEF0F9F2D2B1CDBD4DAA8ED0C28E774EFE72D9FF758B97DAD89B305E5EC82BBC17733DB5F550EFFF1C45CBCA807BD7461C2D3C80FFDE3C1D4410DD678A94ADA54192EABFEC129C5F33DEADEF0C15B1D13782336637544FF1433E97022E45CFD560870ECD85CFF72944596B73DC7D9F978A07A47806E97EDB253019551791D6C62DEB669F5FA5EAA31FCDA0431C07AD97004F527C72548E9D22936D47D8963ABA0D82231473AF8CA45EBC59D93FCE197B7930AD7A82E3D780391A317097CFFA545DC42341FB1B265B851BBF55D95EF63A9AAFA4B2A78036751FBAABCBE9A8215B050AD478C3BF350462A4812A4FDE66FAC8B91718AAD80B68D21E5788F7CB3711F23F25EDBBDF7AC6DD9FBC110EBA2272750936C2F2A74CE5E69DE59A0B6359076EE3FB1D4F2779A6AC5753C860C2CA448E036EA15055D4A19148FE7BCD0AFA3B140A0203548A7A456ECDA8B9B9E740620291F14E21D08EEF21CE5676BB2434233E6C7CC62E48B9B752C87DC87E6DAE0A870E81D17E44AAF6982000A95B7EA676255A17D73FF4A45FAE0C5C9513B5EC0C6414D73EA9488373B6E2FFC9BD2E2C77394BB392F0AD23D91C99D9AA5066EBEE7123D00E223CA3CE572F667DBBD243473453DEC1A44CB979EF3898056D1E3B3A66DB1CB711B232291FA7C1254053513 -20240329161124 2 6 100 8191 2 C4FF326CB002CB4F25BB4309818DE616BCD6A04CB1C8D569FC4D34148B1D5D6B439D6DB946A264765BB6EAAE20B1B737C3CE28B7047D18B47C37ABECEC047E51A0541FE6434045192CE79898A70E6D93E12C35237219A6E3E00F88F5B1EE69982F0ECDA40DE90F5181A6F6F9BF5F9C497A1589ED3E2C16C68A41EA50D544BC57DB544F81F3DD6E6E09E0261A8FB2845A73A13156EBEC90719DE167262FAA68FA08DB412A918DE0D0C5585262DAB724FE31489205D7EA7C669DF4A4423E537153DB359EF31A71FE15C0707D46EE8EFF55305742BE773C6BAD327B2DB2829BF88216A275DFEBB04B3CFA2CF45507788E1DC5EDAFA03A03AD61CFCFE40D7CF7BF3712874CAA2C711691DD189B7024520B0B07D51095E91162FCA7203ECB4DDC9FFEA8355090AB20EEBA13F7901F5B71AB397CD097E0443DFAC8FED92DBBF2B38100E3CCB0118B2C8F27876D6067AF3EE9E44C7F44472C0DC419DE40E23D9DE359138028A9423328261E625A7381012787C370BC3C933C192EFE8CBF23F80271CBCA40F39D1BE4B4173997E646FEDB7AC81006E10D96559EDF6490A56FD47945E35A102C8B00EA740A7F1B53B4CC03D2DC302A8EA16971403CA8B826F6D56E307E04C75EDC1A8565A9EFBBE0F6ECA61D976649A23C82D9A8D7AC3E5124334916A75A6C8AA3B5DFB00FFEB893E6A7E7CEF0622C41C3FFB0B83C38A329E7144F6C06E789D897E3704817C6A79548B8D394EC53A460517DFD1513896B8360156561A5668AEF0F9F2D2B1CDBD4DAA8ED0C28E774EFE72D9FF758B97DAD89B305E5EC82BBC17733DB5F550EFFF1C45CBCA807BD7461C2D3C80FFDE3C1D4410DD678A94ADA54192EABFEC129C5F33DEADEF0C15B1D13782336637544FF1433E97022E45CFD560870ECD85CFF72944596B73DC7D9F978A07A47806E97EDB253019551791D6C62DEB669F5FA5EAA31FCDA0431C07AD97004F527C72548E9D22936D47D8963ABA0D82231473AF8CA45EBC59D93FCE197B7930AD7A82E3D780391A317097CFFA545DC42341FB1B265B851BBF55D95EF63A9AAFA4B2A78036751FBAABCBE9A8215B050AD478C3BF350462A4812A4FDE66FAC8B91718AAD80B68D21E5788F7CB3711F23F25EDBBDF7AC6DD9FBC110EBA2272750936C2F2A74CE5E69DE59A0B6359076EE3FB1D4F2779A6AC5753C860C2CA448E036EA15055D4A19148FE7BCD0AFA3B140A0203548A7A456ECDA8B9B9E740620291F14E21D08EEF21CE5676BB2434233E6C7CC62E48B9B752C87DC87E6DAE0A870E81D17E44AAF6982000A95B7EA676255A17D73FF4A45FAE0C5C9513B5EC0C6414D73EA9488373B6E2FFC9BD2E2C77394BB392F0AD23D91C99D9AA5066EBEE7123D00E223CA3CE572F667DBBD243473453DEC1A44CB979EF3898056D1E3B3A66DB1CB711B232291FA7C12550A7BDB -20240329161738 2 6 100 8191 2 C4FF326CB002CB4F25BB4309818DE616BCD6A04CB1C8D569FC4D34148B1D5D6B439D6DB946A264765BB6EAAE20B1B737C3CE28B7047D18B47C37ABECEC047E51A0541FE6434045192CE79898A70E6D93E12C35237219A6E3E00F88F5B1EE69982F0ECDA40DE90F5181A6F6F9BF5F9C497A1589ED3E2C16C68A41EA50D544BC57DB544F81F3DD6E6E09E0261A8FB2845A73A13156EBEC90719DE167262FAA68FA08DB412A918DE0D0C5585262DAB724FE31489205D7EA7C669DF4A4423E537153DB359EF31A71FE15C0707D46EE8EFF55305742BE773C6BAD327B2DB2829BF88216A275DFEBB04B3CFA2CF45507788E1DC5EDAFA03A03AD61CFCFE40D7CF7BF3712874CAA2C711691DD189B7024520B0B07D51095E91162FCA7203ECB4DDC9FFEA8355090AB20EEBA13F7901F5B71AB397CD097E0443DFAC8FED92DBBF2B38100E3CCB0118B2C8F27876D6067AF3EE9E44C7F44472C0DC419DE40E23D9DE359138028A9423328261E625A7381012787C370BC3C933C192EFE8CBF23F80271CBCA40F39D1BE4B4173997E646FEDB7AC81006E10D96559EDF6490A56FD47945E35A102C8B00EA740A7F1B53B4CC03D2DC302A8EA16971403CA8B826F6D56E307E04C75EDC1A8565A9EFBBE0F6ECA61D976649A23C82D9A8D7AC3E5124334916A75A6C8AA3B5DFB00FFEB893E6A7E7CEF0622C41C3FFB0B83C38A329E7144F6C06E789D897E3704817C6A79548B8D394EC53A460517DFD1513896B8360156561A5668AEF0F9F2D2B1CDBD4DAA8ED0C28E774EFE72D9FF758B97DAD89B305E5EC82BBC17733DB5F550EFFF1C45CBCA807BD7461C2D3C80FFDE3C1D4410DD678A94ADA54192EABFEC129C5F33DEADEF0C15B1D13782336637544FF1433E97022E45CFD560870ECD85CFF72944596B73DC7D9F978A07A47806E97EDB253019551791D6C62DEB669F5FA5EAA31FCDA0431C07AD97004F527C72548E9D22936D47D8963ABA0D82231473AF8CA45EBC59D93FCE197B7930AD7A82E3D780391A317097CFFA545DC42341FB1B265B851BBF55D95EF63A9AAFA4B2A78036751FBAABCBE9A8215B050AD478C3BF350462A4812A4FDE66FAC8B91718AAD80B68D21E5788F7CB3711F23F25EDBBDF7AC6DD9FBC110EBA2272750936C2F2A74CE5E69DE59A0B6359076EE3FB1D4F2779A6AC5753C860C2CA448E036EA15055D4A19148FE7BCD0AFA3B140A0203548A7A456ECDA8B9B9E740620291F14E21D08EEF21CE5676BB2434233E6C7CC62E48B9B752C87DC87E6DAE0A870E81D17E44AAF6982000A95B7EA676255A17D73FF4A45FAE0C5C9513B5EC0C6414D73EA9488373B6E2FFC9BD2E2C77394BB392F0AD23D91C99D9AA5066EBEE7123D00E223CA3CE572F667DBBD243473453DEC1A44CB979EF3898056D1E3B3A66DB1CB711B232291FA7C12555C651B -20240329174531 2 6 100 8191 2 C4FF326CB002CB4F25BB4309818DE616BCD6A04CB1C8D569FC4D34148B1D5D6B439D6DB946A264765BB6EAAE20B1B737C3CE28B7047D18B47C37ABECEC047E51A0541FE6434045192CE79898A70E6D93E12C35237219A6E3E00F88F5B1EE69982F0ECDA40DE90F5181A6F6F9BF5F9C497A1589ED3E2C16C68A41EA50D544BC57DB544F81F3DD6E6E09E0261A8FB2845A73A13156EBEC90719DE167262FAA68FA08DB412A918DE0D0C5585262DAB724FE31489205D7EA7C669DF4A4423E537153DB359EF31A71FE15C0707D46EE8EFF55305742BE773C6BAD327B2DB2829BF88216A275DFEBB04B3CFA2CF45507788E1DC5EDAFA03A03AD61CFCFE40D7CF7BF3712874CAA2C711691DD189B7024520B0B07D51095E91162FCA7203ECB4DDC9FFEA8355090AB20EEBA13F7901F5B71AB397CD097E0443DFAC8FED92DBBF2B38100E3CCB0118B2C8F27876D6067AF3EE9E44C7F44472C0DC419DE40E23D9DE359138028A9423328261E625A7381012787C370BC3C933C192EFE8CBF23F80271CBCA40F39D1BE4B4173997E646FEDB7AC81006E10D96559EDF6490A56FD47945E35A102C8B00EA740A7F1B53B4CC03D2DC302A8EA16971403CA8B826F6D56E307E04C75EDC1A8565A9EFBBE0F6ECA61D976649A23C82D9A8D7AC3E5124334916A75A6C8AA3B5DFB00FFEB893E6A7E7CEF0622C41C3FFB0B83C38A329E7144F6C06E789D897E3704817C6A79548B8D394EC53A460517DFD1513896B8360156561A5668AEF0F9F2D2B1CDBD4DAA8ED0C28E774EFE72D9FF758B97DAD89B305E5EC82BBC17733DB5F550EFFF1C45CBCA807BD7461C2D3C80FFDE3C1D4410DD678A94ADA54192EABFEC129C5F33DEADEF0C15B1D13782336637544FF1433E97022E45CFD560870ECD85CFF72944596B73DC7D9F978A07A47806E97EDB253019551791D6C62DEB669F5FA5EAA31FCDA0431C07AD97004F527C72548E9D22936D47D8963ABA0D82231473AF8CA45EBC59D93FCE197B7930AD7A82E3D780391A317097CFFA545DC42341FB1B265B851BBF55D95EF63A9AAFA4B2A78036751FBAABCBE9A8215B050AD478C3BF350462A4812A4FDE66FAC8B91718AAD80B68D21E5788F7CB3711F23F25EDBBDF7AC6DD9FBC110EBA2272750936C2F2A74CE5E69DE59A0B6359076EE3FB1D4F2779A6AC5753C860C2CA448E036EA15055D4A19148FE7BCD0AFA3B140A0203548A7A456ECDA8B9B9E740620291F14E21D08EEF21CE5676BB2434233E6C7CC62E48B9B752C87DC87E6DAE0A870E81D17E44AAF6982000A95B7EA676255A17D73FF4A45FAE0C5C9513B5EC0C6414D73EA9488373B6E2FFC9BD2E2C77394BB392F0AD23D91C99D9AA5066EBEE7123D00E223CA3CE572F667DBBD243473453DEC1A44CB979EF3898056D1E3B3A66DB1CB711B232291FA7C125A40EEC3 -20240329191732 2 6 100 8191 2 C4FF326CB002CB4F25BB4309818DE616BCD6A04CB1C8D569FC4D34148B1D5D6B439D6DB946A264765BB6EAAE20B1B737C3CE28B7047D18B47C37ABECEC047E51A0541FE6434045192CE79898A70E6D93E12C35237219A6E3E00F88F5B1EE69982F0ECDA40DE90F5181A6F6F9BF5F9C497A1589ED3E2C16C68A41EA50D544BC57DB544F81F3DD6E6E09E0261A8FB2845A73A13156EBEC90719DE167262FAA68FA08DB412A918DE0D0C5585262DAB724FE31489205D7EA7C669DF4A4423E537153DB359EF31A71FE15C0707D46EE8EFF55305742BE773C6BAD327B2DB2829BF88216A275DFEBB04B3CFA2CF45507788E1DC5EDAFA03A03AD61CFCFE40D7CF7BF3712874CAA2C711691DD189B7024520B0B07D51095E91162FCA7203ECB4DDC9FFEA8355090AB20EEBA13F7901F5B71AB397CD097E0443DFAC8FED92DBBF2B38100E3CCB0118B2C8F27876D6067AF3EE9E44C7F44472C0DC419DE40E23D9DE359138028A9423328261E625A7381012787C370BC3C933C192EFE8CBF23F80271CBCA40F39D1BE4B4173997E646FEDB7AC81006E10D96559EDF6490A56FD47945E35A102C8B00EA740A7F1B53B4CC03D2DC302A8EA16971403CA8B826F6D56E307E04C75EDC1A8565A9EFBBE0F6ECA61D976649A23C82D9A8D7AC3E5124334916A75A6C8AA3B5DFB00FFEB893E6A7E7CEF0622C41C3FFB0B83C38A329E7144F6C06E789D897E3704817C6A79548B8D394EC53A460517DFD1513896B8360156561A5668AEF0F9F2D2B1CDBD4DAA8ED0C28E774EFE72D9FF758B97DAD89B305E5EC82BBC17733DB5F550EFFF1C45CBCA807BD7461C2D3C80FFDE3C1D4410DD678A94ADA54192EABFEC129C5F33DEADEF0C15B1D13782336637544FF1433E97022E45CFD560870ECD85CFF72944596B73DC7D9F978A07A47806E97EDB253019551791D6C62DEB669F5FA5EAA31FCDA0431C07AD97004F527C72548E9D22936D47D8963ABA0D82231473AF8CA45EBC59D93FCE197B7930AD7A82E3D780391A317097CFFA545DC42341FB1B265B851BBF55D95EF63A9AAFA4B2A78036751FBAABCBE9A8215B050AD478C3BF350462A4812A4FDE66FAC8B91718AAD80B68D21E5788F7CB3711F23F25EDBBDF7AC6DD9FBC110EBA2272750936C2F2A74CE5E69DE59A0B6359076EE3FB1D4F2779A6AC5753C860C2CA448E036EA15055D4A19148FE7BCD0AFA3B140A0203548A7A456ECDA8B9B9E740620291F14E21D08EEF21CE5676BB2434233E6C7CC62E48B9B752C87DC87E6DAE0A870E81D17E44AAF6982000A95B7EA676255A17D73FF4A45FAE0C5C9513B5EC0C6414D73EA9488373B6E2FFC9BD2E2C77394BB392F0AD23D91C99D9AA5066EBEE7123D00E223CA3CE572F667DBBD243473453DEC1A44CB979EF3898056D1E3B3A66DB1CB711B232291FA7C125F71710B -20240329195323 2 6 100 8191 2 C4FF326CB002CB4F25BB4309818DE616BCD6A04CB1C8D569FC4D34148B1D5D6B439D6DB946A264765BB6EAAE20B1B737C3CE28B7047D18B47C37ABECEC047E51A0541FE6434045192CE79898A70E6D93E12C35237219A6E3E00F88F5B1EE69982F0ECDA40DE90F5181A6F6F9BF5F9C497A1589ED3E2C16C68A41EA50D544BC57DB544F81F3DD6E6E09E0261A8FB2845A73A13156EBEC90719DE167262FAA68FA08DB412A918DE0D0C5585262DAB724FE31489205D7EA7C669DF4A4423E537153DB359EF31A71FE15C0707D46EE8EFF55305742BE773C6BAD327B2DB2829BF88216A275DFEBB04B3CFA2CF45507788E1DC5EDAFA03A03AD61CFCFE40D7CF7BF3712874CAA2C711691DD189B7024520B0B07D51095E91162FCA7203ECB4DDC9FFEA8355090AB20EEBA13F7901F5B71AB397CD097E0443DFAC8FED92DBBF2B38100E3CCB0118B2C8F27876D6067AF3EE9E44C7F44472C0DC419DE40E23D9DE359138028A9423328261E625A7381012787C370BC3C933C192EFE8CBF23F80271CBCA40F39D1BE4B4173997E646FEDB7AC81006E10D96559EDF6490A56FD47945E35A102C8B00EA740A7F1B53B4CC03D2DC302A8EA16971403CA8B826F6D56E307E04C75EDC1A8565A9EFBBE0F6ECA61D976649A23C82D9A8D7AC3E5124334916A75A6C8AA3B5DFB00FFEB893E6A7E7CEF0622C41C3FFB0B83C38A329E7144F6C06E789D897E3704817C6A79548B8D394EC53A460517DFD1513896B8360156561A5668AEF0F9F2D2B1CDBD4DAA8ED0C28E774EFE72D9FF758B97DAD89B305E5EC82BBC17733DB5F550EFFF1C45CBCA807BD7461C2D3C80FFDE3C1D4410DD678A94ADA54192EABFEC129C5F33DEADEF0C15B1D13782336637544FF1433E97022E45CFD560870ECD85CFF72944596B73DC7D9F978A07A47806E97EDB253019551791D6C62DEB669F5FA5EAA31FCDA0431C07AD97004F527C72548E9D22936D47D8963ABA0D82231473AF8CA45EBC59D93FCE197B7930AD7A82E3D780391A317097CFFA545DC42341FB1B265B851BBF55D95EF63A9AAFA4B2A78036751FBAABCBE9A8215B050AD478C3BF350462A4812A4FDE66FAC8B91718AAD80B68D21E5788F7CB3711F23F25EDBBDF7AC6DD9FBC110EBA2272750936C2F2A74CE5E69DE59A0B6359076EE3FB1D4F2779A6AC5753C860C2CA448E036EA15055D4A19148FE7BCD0AFA3B140A0203548A7A456ECDA8B9B9E740620291F14E21D08EEF21CE5676BB2434233E6C7CC62E48B9B752C87DC87E6DAE0A870E81D17E44AAF6982000A95B7EA676255A17D73FF4A45FAE0C5C9513B5EC0C6414D73EA9488373B6E2FFC9BD2E2C77394BB392F0AD23D91C99D9AA5066EBEE7123D00E223CA3CE572F667DBBD243473453DEC1A44CB979EF3898056D1E3B3A66DB1CB711B232291FA7C126178458B -20240329204827 2 6 100 8191 5 C4FF326CB002CB4F25BB4309818DE616BCD6A04CB1C8D569FC4D34148B1D5D6B439D6DB946A264765BB6EAAE20B1B737C3CE28B7047D18B47C37ABECEC047E51A0541FE6434045192CE79898A70E6D93E12C35237219A6E3E00F88F5B1EE69982F0ECDA40DE90F5181A6F6F9BF5F9C497A1589ED3E2C16C68A41EA50D544BC57DB544F81F3DD6E6E09E0261A8FB2845A73A13156EBEC90719DE167262FAA68FA08DB412A918DE0D0C5585262DAB724FE31489205D7EA7C669DF4A4423E537153DB359EF31A71FE15C0707D46EE8EFF55305742BE773C6BAD327B2DB2829BF88216A275DFEBB04B3CFA2CF45507788E1DC5EDAFA03A03AD61CFCFE40D7CF7BF3712874CAA2C711691DD189B7024520B0B07D51095E91162FCA7203ECB4DDC9FFEA8355090AB20EEBA13F7901F5B71AB397CD097E0443DFAC8FED92DBBF2B38100E3CCB0118B2C8F27876D6067AF3EE9E44C7F44472C0DC419DE40E23D9DE359138028A9423328261E625A7381012787C370BC3C933C192EFE8CBF23F80271CBCA40F39D1BE4B4173997E646FEDB7AC81006E10D96559EDF6490A56FD47945E35A102C8B00EA740A7F1B53B4CC03D2DC302A8EA16971403CA8B826F6D56E307E04C75EDC1A8565A9EFBBE0F6ECA61D976649A23C82D9A8D7AC3E5124334916A75A6C8AA3B5DFB00FFEB893E6A7E7CEF0622C41C3FFB0B83C38A329E7144F6C06E789D897E3704817C6A79548B8D394EC53A460517DFD1513896B8360156561A5668AEF0F9F2D2B1CDBD4DAA8ED0C28E774EFE72D9FF758B97DAD89B305E5EC82BBC17733DB5F550EFFF1C45CBCA807BD7461C2D3C80FFDE3C1D4410DD678A94ADA54192EABFEC129C5F33DEADEF0C15B1D13782336637544FF1433E97022E45CFD560870ECD85CFF72944596B73DC7D9F978A07A47806E97EDB253019551791D6C62DEB669F5FA5EAA31FCDA0431C07AD97004F527C72548E9D22936D47D8963ABA0D82231473AF8CA45EBC59D93FCE197B7930AD7A82E3D780391A317097CFFA545DC42341FB1B265B851BBF55D95EF63A9AAFA4B2A78036751FBAABCBE9A8215B050AD478C3BF350462A4812A4FDE66FAC8B91718AAD80B68D21E5788F7CB3711F23F25EDBBDF7AC6DD9FBC110EBA2272750936C2F2A74CE5E69DE59A0B6359076EE3FB1D4F2779A6AC5753C860C2CA448E036EA15055D4A19148FE7BCD0AFA3B140A0203548A7A456ECDA8B9B9E740620291F14E21D08EEF21CE5676BB2434233E6C7CC62E48B9B752C87DC87E6DAE0A870E81D17E44AAF6982000A95B7EA676255A17D73FF4A45FAE0C5C9513B5EC0C6414D73EA9488373B6E2FFC9BD2E2C77394BB392F0AD23D91C99D9AA5066EBEE7123D00E223CA3CE572F667DBBD243473453DEC1A44CB979EF3898056D1E3B3A66DB1CB711B232291FA7C12648DD15F -20240329234203 2 6 100 8191 5 C4FF326CB002CB4F25BB4309818DE616BCD6A04CB1C8D569FC4D34148B1D5D6B439D6DB946A264765BB6EAAE20B1B737C3CE28B7047D18B47C37ABECEC047E51A0541FE6434045192CE79898A70E6D93E12C35237219A6E3E00F88F5B1EE69982F0ECDA40DE90F5181A6F6F9BF5F9C497A1589ED3E2C16C68A41EA50D544BC57DB544F81F3DD6E6E09E0261A8FB2845A73A13156EBEC90719DE167262FAA68FA08DB412A918DE0D0C5585262DAB724FE31489205D7EA7C669DF4A4423E537153DB359EF31A71FE15C0707D46EE8EFF55305742BE773C6BAD327B2DB2829BF88216A275DFEBB04B3CFA2CF45507788E1DC5EDAFA03A03AD61CFCFE40D7CF7BF3712874CAA2C711691DD189B7024520B0B07D51095E91162FCA7203ECB4DDC9FFEA8355090AB20EEBA13F7901F5B71AB397CD097E0443DFAC8FED92DBBF2B38100E3CCB0118B2C8F27876D6067AF3EE9E44C7F44472C0DC419DE40E23D9DE359138028A9423328261E625A7381012787C370BC3C933C192EFE8CBF23F80271CBCA40F39D1BE4B4173997E646FEDB7AC81006E10D96559EDF6490A56FD47945E35A102C8B00EA740A7F1B53B4CC03D2DC302A8EA16971403CA8B826F6D56E307E04C75EDC1A8565A9EFBBE0F6ECA61D976649A23C82D9A8D7AC3E5124334916A75A6C8AA3B5DFB00FFEB893E6A7E7CEF0622C41C3FFB0B83C38A329E7144F6C06E789D897E3704817C6A79548B8D394EC53A460517DFD1513896B8360156561A5668AEF0F9F2D2B1CDBD4DAA8ED0C28E774EFE72D9FF758B97DAD89B305E5EC82BBC17733DB5F550EFFF1C45CBCA807BD7461C2D3C80FFDE3C1D4410DD678A94ADA54192EABFEC129C5F33DEADEF0C15B1D13782336637544FF1433E97022E45CFD560870ECD85CFF72944596B73DC7D9F978A07A47806E97EDB253019551791D6C62DEB669F5FA5EAA31FCDA0431C07AD97004F527C72548E9D22936D47D8963ABA0D82231473AF8CA45EBC59D93FCE197B7930AD7A82E3D780391A317097CFFA545DC42341FB1B265B851BBF55D95EF63A9AAFA4B2A78036751FBAABCBE9A8215B050AD478C3BF350462A4812A4FDE66FAC8B91718AAD80B68D21E5788F7CB3711F23F25EDBBDF7AC6DD9FBC110EBA2272750936C2F2A74CE5E69DE59A0B6359076EE3FB1D4F2779A6AC5753C860C2CA448E036EA15055D4A19148FE7BCD0AFA3B140A0203548A7A456ECDA8B9B9E740620291F14E21D08EEF21CE5676BB2434233E6C7CC62E48B9B752C87DC87E6DAE0A870E81D17E44AAF6982000A95B7EA676255A17D73FF4A45FAE0C5C9513B5EC0C6414D73EA9488373B6E2FFC9BD2E2C77394BB392F0AD23D91C99D9AA5066EBEE7123D00E223CA3CE572F667DBBD243473453DEC1A44CB979EF3898056D1E3B3A66DB1CB711B232291FA7C126E5A5097 -20240329234306 2 6 100 8191 2 C4FF326CB002CB4F25BB4309818DE616BCD6A04CB1C8D569FC4D34148B1D5D6B439D6DB946A264765BB6EAAE20B1B737C3CE28B7047D18B47C37ABECEC047E51A0541FE6434045192CE79898A70E6D93E12C35237219A6E3E00F88F5B1EE69982F0ECDA40DE90F5181A6F6F9BF5F9C497A1589ED3E2C16C68A41EA50D544BC57DB544F81F3DD6E6E09E0261A8FB2845A73A13156EBEC90719DE167262FAA68FA08DB412A918DE0D0C5585262DAB724FE31489205D7EA7C669DF4A4423E537153DB359EF31A71FE15C0707D46EE8EFF55305742BE773C6BAD327B2DB2829BF88216A275DFEBB04B3CFA2CF45507788E1DC5EDAFA03A03AD61CFCFE40D7CF7BF3712874CAA2C711691DD189B7024520B0B07D51095E91162FCA7203ECB4DDC9FFEA8355090AB20EEBA13F7901F5B71AB397CD097E0443DFAC8FED92DBBF2B38100E3CCB0118B2C8F27876D6067AF3EE9E44C7F44472C0DC419DE40E23D9DE359138028A9423328261E625A7381012787C370BC3C933C192EFE8CBF23F80271CBCA40F39D1BE4B4173997E646FEDB7AC81006E10D96559EDF6490A56FD47945E35A102C8B00EA740A7F1B53B4CC03D2DC302A8EA16971403CA8B826F6D56E307E04C75EDC1A8565A9EFBBE0F6ECA61D976649A23C82D9A8D7AC3E5124334916A75A6C8AA3B5DFB00FFEB893E6A7E7CEF0622C41C3FFB0B83C38A329E7144F6C06E789D897E3704817C6A79548B8D394EC53A460517DFD1513896B8360156561A5668AEF0F9F2D2B1CDBD4DAA8ED0C28E774EFE72D9FF758B97DAD89B305E5EC82BBC17733DB5F550EFFF1C45CBCA807BD7461C2D3C80FFDE3C1D4410DD678A94ADA54192EABFEC129C5F33DEADEF0C15B1D13782336637544FF1433E97022E45CFD560870ECD85CFF72944596B73DC7D9F978A07A47806E97EDB253019551791D6C62DEB669F5FA5EAA31FCDA0431C07AD97004F527C72548E9D22936D47D8963ABA0D82231473AF8CA45EBC59D93FCE197B7930AD7A82E3D780391A317097CFFA545DC42341FB1B265B851BBF55D95EF63A9AAFA4B2A78036751FBAABCBE9A8215B050AD478C3BF350462A4812A4FDE66FAC8B91718AAD80B68D21E5788F7CB3711F23F25EDBBDF7AC6DD9FBC110EBA2272750936C2F2A74CE5E69DE59A0B6359076EE3FB1D4F2779A6AC5753C860C2CA448E036EA15055D4A19148FE7BCD0AFA3B140A0203548A7A456ECDA8B9B9E740620291F14E21D08EEF21CE5676BB2434233E6C7CC62E48B9B752C87DC87E6DAE0A870E81D17E44AAF6982000A95B7EA676255A17D73FF4A45FAE0C5C9513B5EC0C6414D73EA9488373B6E2FFC9BD2E2C77394BB392F0AD23D91C99D9AA5066EBEE7123D00E223CA3CE572F667DBBD243473453DEC1A44CB979EF3898056D1E3B3A66DB1CB711B232291FA7C126E615ACB -20240330005652 2 6 100 8191 2 C4FF326CB002CB4F25BB4309818DE616BCD6A04CB1C8D569FC4D34148B1D5D6B439D6DB946A264765BB6EAAE20B1B737C3CE28B7047D18B47C37ABECEC047E51A0541FE6434045192CE79898A70E6D93E12C35237219A6E3E00F88F5B1EE69982F0ECDA40DE90F5181A6F6F9BF5F9C497A1589ED3E2C16C68A41EA50D544BC57DB544F81F3DD6E6E09E0261A8FB2845A73A13156EBEC90719DE167262FAA68FA08DB412A918DE0D0C5585262DAB724FE31489205D7EA7C669DF4A4423E537153DB359EF31A71FE15C0707D46EE8EFF55305742BE773C6BAD327B2DB2829BF88216A275DFEBB04B3CFA2CF45507788E1DC5EDAFA03A03AD61CFCFE40D7CF7BF3712874CAA2C711691DD189B7024520B0B07D51095E91162FCA7203ECB4DDC9FFEA8355090AB20EEBA13F7901F5B71AB397CD097E0443DFAC8FED92DBBF2B38100E3CCB0118B2C8F27876D6067AF3EE9E44C7F44472C0DC419DE40E23D9DE359138028A9423328261E625A7381012787C370BC3C933C192EFE8CBF23F80271CBCA40F39D1BE4B4173997E646FEDB7AC81006E10D96559EDF6490A56FD47945E35A102C8B00EA740A7F1B53B4CC03D2DC302A8EA16971403CA8B826F6D56E307E04C75EDC1A8565A9EFBBE0F6ECA61D976649A23C82D9A8D7AC3E5124334916A75A6C8AA3B5DFB00FFEB893E6A7E7CEF0622C41C3FFB0B83C38A329E7144F6C06E789D897E3704817C6A79548B8D394EC53A460517DFD1513896B8360156561A5668AEF0F9F2D2B1CDBD4DAA8ED0C28E774EFE72D9FF758B97DAD89B305E5EC82BBC17733DB5F550EFFF1C45CBCA807BD7461C2D3C80FFDE3C1D4410DD678A94ADA54192EABFEC129C5F33DEADEF0C15B1D13782336637544FF1433E97022E45CFD560870ECD85CFF72944596B73DC7D9F978A07A47806E97EDB253019551791D6C62DEB669F5FA5EAA31FCDA0431C07AD97004F527C72548E9D22936D47D8963ABA0D82231473AF8CA45EBC59D93FCE197B7930AD7A82E3D780391A317097CFFA545DC42341FB1B265B851BBF55D95EF63A9AAFA4B2A78036751FBAABCBE9A8215B050AD478C3BF350462A4812A4FDE66FAC8B91718AAD80B68D21E5788F7CB3711F23F25EDBBDF7AC6DD9FBC110EBA2272750936C2F2A74CE5E69DE59A0B6359076EE3FB1D4F2779A6AC5753C860C2CA448E036EA15055D4A19148FE7BCD0AFA3B140A0203548A7A456ECDA8B9B9E740620291F14E21D08EEF21CE5676BB2434233E6C7CC62E48B9B752C87DC87E6DAE0A870E81D17E44AAF6982000A95B7EA676255A17D73FF4A45FAE0C5C9513B5EC0C6414D73EA9488373B6E2FFC9BD2E2C77394BB392F0AD23D91C99D9AA5066EBEE7123D00E223CA3CE572F667DBBD243473453DEC1A44CB979EF3898056D1E3B3A66DB1CB711B232291FA7C12726F6443 -20240330033619 2 6 100 8191 2 C4FF326CB002CB4F25BB4309818DE616BCD6A04CB1C8D569FC4D34148B1D5D6B439D6DB946A264765BB6EAAE20B1B737C3CE28B7047D18B47C37ABECEC047E51A0541FE6434045192CE79898A70E6D93E12C35237219A6E3E00F88F5B1EE69982F0ECDA40DE90F5181A6F6F9BF5F9C497A1589ED3E2C16C68A41EA50D544BC57DB544F81F3DD6E6E09E0261A8FB2845A73A13156EBEC90719DE167262FAA68FA08DB412A918DE0D0C5585262DAB724FE31489205D7EA7C669DF4A4423E537153DB359EF31A71FE15C0707D46EE8EFF55305742BE773C6BAD327B2DB2829BF88216A275DFEBB04B3CFA2CF45507788E1DC5EDAFA03A03AD61CFCFE40D7CF7BF3712874CAA2C711691DD189B7024520B0B07D51095E91162FCA7203ECB4DDC9FFEA8355090AB20EEBA13F7901F5B71AB397CD097E0443DFAC8FED92DBBF2B38100E3CCB0118B2C8F27876D6067AF3EE9E44C7F44472C0DC419DE40E23D9DE359138028A9423328261E625A7381012787C370BC3C933C192EFE8CBF23F80271CBCA40F39D1BE4B4173997E646FEDB7AC81006E10D96559EDF6490A56FD47945E35A102C8B00EA740A7F1B53B4CC03D2DC302A8EA16971403CA8B826F6D56E307E04C75EDC1A8565A9EFBBE0F6ECA61D976649A23C82D9A8D7AC3E5124334916A75A6C8AA3B5DFB00FFEB893E6A7E7CEF0622C41C3FFB0B83C38A329E7144F6C06E789D897E3704817C6A79548B8D394EC53A460517DFD1513896B8360156561A5668AEF0F9F2D2B1CDBD4DAA8ED0C28E774EFE72D9FF758B97DAD89B305E5EC82BBC17733DB5F550EFFF1C45CBCA807BD7461C2D3C80FFDE3C1D4410DD678A94ADA54192EABFEC129C5F33DEADEF0C15B1D13782336637544FF1433E97022E45CFD560870ECD85CFF72944596B73DC7D9F978A07A47806E97EDB253019551791D6C62DEB669F5FA5EAA31FCDA0431C07AD97004F527C72548E9D22936D47D8963ABA0D82231473AF8CA45EBC59D93FCE197B7930AD7A82E3D780391A317097CFFA545DC42341FB1B265B851BBF55D95EF63A9AAFA4B2A78036751FBAABCBE9A8215B050AD478C3BF350462A4812A4FDE66FAC8B91718AAD80B68D21E5788F7CB3711F23F25EDBBDF7AC6DD9FBC110EBA2272750936C2F2A74CE5E69DE59A0B6359076EE3FB1D4F2779A6AC5753C860C2CA448E036EA15055D4A19148FE7BCD0AFA3B140A0203548A7A456ECDA8B9B9E740620291F14E21D08EEF21CE5676BB2434233E6C7CC62E48B9B752C87DC87E6DAE0A870E81D17E44AAF6982000A95B7EA676255A17D73FF4A45FAE0C5C9513B5EC0C6414D73EA9488373B6E2FFC9BD2E2C77394BB392F0AD23D91C99D9AA5066EBEE7123D00E223CA3CE572F667DBBD243473453DEC1A44CB979EF3898056D1E3B3A66DB1CB711B232291FA7C127B69FC23 -20240330044619 2 6 100 8191 2 C4FF326CB002CB4F25BB4309818DE616BCD6A04CB1C8D569FC4D34148B1D5D6B439D6DB946A264765BB6EAAE20B1B737C3CE28B7047D18B47C37ABECEC047E51A0541FE6434045192CE79898A70E6D93E12C35237219A6E3E00F88F5B1EE69982F0ECDA40DE90F5181A6F6F9BF5F9C497A1589ED3E2C16C68A41EA50D544BC57DB544F81F3DD6E6E09E0261A8FB2845A73A13156EBEC90719DE167262FAA68FA08DB412A918DE0D0C5585262DAB724FE31489205D7EA7C669DF4A4423E537153DB359EF31A71FE15C0707D46EE8EFF55305742BE773C6BAD327B2DB2829BF88216A275DFEBB04B3CFA2CF45507788E1DC5EDAFA03A03AD61CFCFE40D7CF7BF3712874CAA2C711691DD189B7024520B0B07D51095E91162FCA7203ECB4DDC9FFEA8355090AB20EEBA13F7901F5B71AB397CD097E0443DFAC8FED92DBBF2B38100E3CCB0118B2C8F27876D6067AF3EE9E44C7F44472C0DC419DE40E23D9DE359138028A9423328261E625A7381012787C370BC3C933C192EFE8CBF23F80271CBCA40F39D1BE4B4173997E646FEDB7AC81006E10D96559EDF6490A56FD47945E35A102C8B00EA740A7F1B53B4CC03D2DC302A8EA16971403CA8B826F6D56E307E04C75EDC1A8565A9EFBBE0F6ECA61D976649A23C82D9A8D7AC3E5124334916A75A6C8AA3B5DFB00FFEB893E6A7E7CEF0622C41C3FFB0B83C38A329E7144F6C06E789D897E3704817C6A79548B8D394EC53A460517DFD1513896B8360156561A5668AEF0F9F2D2B1CDBD4DAA8ED0C28E774EFE72D9FF758B97DAD89B305E5EC82BBC17733DB5F550EFFF1C45CBCA807BD7461C2D3C80FFDE3C1D4410DD678A94ADA54192EABFEC129C5F33DEADEF0C15B1D13782336637544FF1433E97022E45CFD560870ECD85CFF72944596B73DC7D9F978A07A47806E97EDB253019551791D6C62DEB669F5FA5EAA31FCDA0431C07AD97004F527C72548E9D22936D47D8963ABA0D82231473AF8CA45EBC59D93FCE197B7930AD7A82E3D780391A317097CFFA545DC42341FB1B265B851BBF55D95EF63A9AAFA4B2A78036751FBAABCBE9A8215B050AD478C3BF350462A4812A4FDE66FAC8B91718AAD80B68D21E5788F7CB3711F23F25EDBBDF7AC6DD9FBC110EBA2272750936C2F2A74CE5E69DE59A0B6359076EE3FB1D4F2779A6AC5753C860C2CA448E036EA15055D4A19148FE7BCD0AFA3B140A0203548A7A456ECDA8B9B9E740620291F14E21D08EEF21CE5676BB2434233E6C7CC62E48B9B752C87DC87E6DAE0A870E81D17E44AAF6982000A95B7EA676255A17D73FF4A45FAE0C5C9513B5EC0C6414D73EA9488373B6E2FFC9BD2E2C77394BB392F0AD23D91C99D9AA5066EBEE7123D00E223CA3CE572F667DBBD243473453DEC1A44CB979EF3898056D1E3B3A66DB1CB711B232291FA7C127F446BC3 -20240330054010 2 6 100 8191 2 C4FF326CB002CB4F25BB4309818DE616BCD6A04CB1C8D569FC4D34148B1D5D6B439D6DB946A264765BB6EAAE20B1B737C3CE28B7047D18B47C37ABECEC047E51A0541FE6434045192CE79898A70E6D93E12C35237219A6E3E00F88F5B1EE69982F0ECDA40DE90F5181A6F6F9BF5F9C497A1589ED3E2C16C68A41EA50D544BC57DB544F81F3DD6E6E09E0261A8FB2845A73A13156EBEC90719DE167262FAA68FA08DB412A918DE0D0C5585262DAB724FE31489205D7EA7C669DF4A4423E537153DB359EF31A71FE15C0707D46EE8EFF55305742BE773C6BAD327B2DB2829BF88216A275DFEBB04B3CFA2CF45507788E1DC5EDAFA03A03AD61CFCFE40D7CF7BF3712874CAA2C711691DD189B7024520B0B07D51095E91162FCA7203ECB4DDC9FFEA8355090AB20EEBA13F7901F5B71AB397CD097E0443DFAC8FED92DBBF2B38100E3CCB0118B2C8F27876D6067AF3EE9E44C7F44472C0DC419DE40E23D9DE359138028A9423328261E625A7381012787C370BC3C933C192EFE8CBF23F80271CBCA40F39D1BE4B4173997E646FEDB7AC81006E10D96559EDF6490A56FD47945E35A102C8B00EA740A7F1B53B4CC03D2DC302A8EA16971403CA8B826F6D56E307E04C75EDC1A8565A9EFBBE0F6ECA61D976649A23C82D9A8D7AC3E5124334916A75A6C8AA3B5DFB00FFEB893E6A7E7CEF0622C41C3FFB0B83C38A329E7144F6C06E789D897E3704817C6A79548B8D394EC53A460517DFD1513896B8360156561A5668AEF0F9F2D2B1CDBD4DAA8ED0C28E774EFE72D9FF758B97DAD89B305E5EC82BBC17733DB5F550EFFF1C45CBCA807BD7461C2D3C80FFDE3C1D4410DD678A94ADA54192EABFEC129C5F33DEADEF0C15B1D13782336637544FF1433E97022E45CFD560870ECD85CFF72944596B73DC7D9F978A07A47806E97EDB253019551791D6C62DEB669F5FA5EAA31FCDA0431C07AD97004F527C72548E9D22936D47D8963ABA0D82231473AF8CA45EBC59D93FCE197B7930AD7A82E3D780391A317097CFFA545DC42341FB1B265B851BBF55D95EF63A9AAFA4B2A78036751FBAABCBE9A8215B050AD478C3BF350462A4812A4FDE66FAC8B91718AAD80B68D21E5788F7CB3711F23F25EDBBDF7AC6DD9FBC110EBA2272750936C2F2A74CE5E69DE59A0B6359076EE3FB1D4F2779A6AC5753C860C2CA448E036EA15055D4A19148FE7BCD0AFA3B140A0203548A7A456ECDA8B9B9E740620291F14E21D08EEF21CE5676BB2434233E6C7CC62E48B9B752C87DC87E6DAE0A870E81D17E44AAF6982000A95B7EA676255A17D73FF4A45FAE0C5C9513B5EC0C6414D73EA9488373B6E2FFC9BD2E2C77394BB392F0AD23D91C99D9AA5066EBEE7123D00E223CA3CE572F667DBBD243473453DEC1A44CB979EF3898056D1E3B3A66DB1CB711B232291FA7C1282492493 -20240330055823 2 6 100 8191 2 C4FF326CB002CB4F25BB4309818DE616BCD6A04CB1C8D569FC4D34148B1D5D6B439D6DB946A264765BB6EAAE20B1B737C3CE28B7047D18B47C37ABECEC047E51A0541FE6434045192CE79898A70E6D93E12C35237219A6E3E00F88F5B1EE69982F0ECDA40DE90F5181A6F6F9BF5F9C497A1589ED3E2C16C68A41EA50D544BC57DB544F81F3DD6E6E09E0261A8FB2845A73A13156EBEC90719DE167262FAA68FA08DB412A918DE0D0C5585262DAB724FE31489205D7EA7C669DF4A4423E537153DB359EF31A71FE15C0707D46EE8EFF55305742BE773C6BAD327B2DB2829BF88216A275DFEBB04B3CFA2CF45507788E1DC5EDAFA03A03AD61CFCFE40D7CF7BF3712874CAA2C711691DD189B7024520B0B07D51095E91162FCA7203ECB4DDC9FFEA8355090AB20EEBA13F7901F5B71AB397CD097E0443DFAC8FED92DBBF2B38100E3CCB0118B2C8F27876D6067AF3EE9E44C7F44472C0DC419DE40E23D9DE359138028A9423328261E625A7381012787C370BC3C933C192EFE8CBF23F80271CBCA40F39D1BE4B4173997E646FEDB7AC81006E10D96559EDF6490A56FD47945E35A102C8B00EA740A7F1B53B4CC03D2DC302A8EA16971403CA8B826F6D56E307E04C75EDC1A8565A9EFBBE0F6ECA61D976649A23C82D9A8D7AC3E5124334916A75A6C8AA3B5DFB00FFEB893E6A7E7CEF0622C41C3FFB0B83C38A329E7144F6C06E789D897E3704817C6A79548B8D394EC53A460517DFD1513896B8360156561A5668AEF0F9F2D2B1CDBD4DAA8ED0C28E774EFE72D9FF758B97DAD89B305E5EC82BBC17733DB5F550EFFF1C45CBCA807BD7461C2D3C80FFDE3C1D4410DD678A94ADA54192EABFEC129C5F33DEADEF0C15B1D13782336637544FF1433E97022E45CFD560870ECD85CFF72944596B73DC7D9F978A07A47806E97EDB253019551791D6C62DEB669F5FA5EAA31FCDA0431C07AD97004F527C72548E9D22936D47D8963ABA0D82231473AF8CA45EBC59D93FCE197B7930AD7A82E3D780391A317097CFFA545DC42341FB1B265B851BBF55D95EF63A9AAFA4B2A78036751FBAABCBE9A8215B050AD478C3BF350462A4812A4FDE66FAC8B91718AAD80B68D21E5788F7CB3711F23F25EDBBDF7AC6DD9FBC110EBA2272750936C2F2A74CE5E69DE59A0B6359076EE3FB1D4F2779A6AC5753C860C2CA448E036EA15055D4A19148FE7BCD0AFA3B140A0203548A7A456ECDA8B9B9E740620291F14E21D08EEF21CE5676BB2434233E6C7CC62E48B9B752C87DC87E6DAE0A870E81D17E44AAF6982000A95B7EA676255A17D73FF4A45FAE0C5C9513B5EC0C6414D73EA9488373B6E2FFC9BD2E2C77394BB392F0AD23D91C99D9AA5066EBEE7123D00E223CA3CE572F667DBBD243473453DEC1A44CB979EF3898056D1E3B3A66DB1CB711B232291FA7C128344D603 -20240330062335 2 6 100 8191 5 C4FF326CB002CB4F25BB4309818DE616BCD6A04CB1C8D569FC4D34148B1D5D6B439D6DB946A264765BB6EAAE20B1B737C3CE28B7047D18B47C37ABECEC047E51A0541FE6434045192CE79898A70E6D93E12C35237219A6E3E00F88F5B1EE69982F0ECDA40DE90F5181A6F6F9BF5F9C497A1589ED3E2C16C68A41EA50D544BC57DB544F81F3DD6E6E09E0261A8FB2845A73A13156EBEC90719DE167262FAA68FA08DB412A918DE0D0C5585262DAB724FE31489205D7EA7C669DF4A4423E537153DB359EF31A71FE15C0707D46EE8EFF55305742BE773C6BAD327B2DB2829BF88216A275DFEBB04B3CFA2CF45507788E1DC5EDAFA03A03AD61CFCFE40D7CF7BF3712874CAA2C711691DD189B7024520B0B07D51095E91162FCA7203ECB4DDC9FFEA8355090AB20EEBA13F7901F5B71AB397CD097E0443DFAC8FED92DBBF2B38100E3CCB0118B2C8F27876D6067AF3EE9E44C7F44472C0DC419DE40E23D9DE359138028A9423328261E625A7381012787C370BC3C933C192EFE8CBF23F80271CBCA40F39D1BE4B4173997E646FEDB7AC81006E10D96559EDF6490A56FD47945E35A102C8B00EA740A7F1B53B4CC03D2DC302A8EA16971403CA8B826F6D56E307E04C75EDC1A8565A9EFBBE0F6ECA61D976649A23C82D9A8D7AC3E5124334916A75A6C8AA3B5DFB00FFEB893E6A7E7CEF0622C41C3FFB0B83C38A329E7144F6C06E789D897E3704817C6A79548B8D394EC53A460517DFD1513896B8360156561A5668AEF0F9F2D2B1CDBD4DAA8ED0C28E774EFE72D9FF758B97DAD89B305E5EC82BBC17733DB5F550EFFF1C45CBCA807BD7461C2D3C80FFDE3C1D4410DD678A94ADA54192EABFEC129C5F33DEADEF0C15B1D13782336637544FF1433E97022E45CFD560870ECD85CFF72944596B73DC7D9F978A07A47806E97EDB253019551791D6C62DEB669F5FA5EAA31FCDA0431C07AD97004F527C72548E9D22936D47D8963ABA0D82231473AF8CA45EBC59D93FCE197B7930AD7A82E3D780391A317097CFFA545DC42341FB1B265B851BBF55D95EF63A9AAFA4B2A78036751FBAABCBE9A8215B050AD478C3BF350462A4812A4FDE66FAC8B91718AAD80B68D21E5788F7CB3711F23F25EDBBDF7AC6DD9FBC110EBA2272750936C2F2A74CE5E69DE59A0B6359076EE3FB1D4F2779A6AC5753C860C2CA448E036EA15055D4A19148FE7BCD0AFA3B140A0203548A7A456ECDA8B9B9E740620291F14E21D08EEF21CE5676BB2434233E6C7CC62E48B9B752C87DC87E6DAE0A870E81D17E44AAF6982000A95B7EA676255A17D73FF4A45FAE0C5C9513B5EC0C6414D73EA9488373B6E2FFC9BD2E2C77394BB392F0AD23D91C99D9AA5066EBEE7123D00E223CA3CE572F667DBBD243473453DEC1A44CB979EF3898056D1E3B3A66DB1CB711B232291FA7C1284A06C1F -20240330082107 2 6 100 8191 2 C4FF326CB002CB4F25BB4309818DE616BCD6A04CB1C8D569FC4D34148B1D5D6B439D6DB946A264765BB6EAAE20B1B737C3CE28B7047D18B47C37ABECEC047E51A0541FE6434045192CE79898A70E6D93E12C35237219A6E3E00F88F5B1EE69982F0ECDA40DE90F5181A6F6F9BF5F9C497A1589ED3E2C16C68A41EA50D544BC57DB544F81F3DD6E6E09E0261A8FB2845A73A13156EBEC90719DE167262FAA68FA08DB412A918DE0D0C5585262DAB724FE31489205D7EA7C669DF4A4423E537153DB359EF31A71FE15C0707D46EE8EFF55305742BE773C6BAD327B2DB2829BF88216A275DFEBB04B3CFA2CF45507788E1DC5EDAFA03A03AD61CFCFE40D7CF7BF3712874CAA2C711691DD189B7024520B0B07D51095E91162FCA7203ECB4DDC9FFEA8355090AB20EEBA13F7901F5B71AB397CD097E0443DFAC8FED92DBBF2B38100E3CCB0118B2C8F27876D6067AF3EE9E44C7F44472C0DC419DE40E23D9DE359138028A9423328261E625A7381012787C370BC3C933C192EFE8CBF23F80271CBCA40F39D1BE4B4173997E646FEDB7AC81006E10D96559EDF6490A56FD47945E35A102C8B00EA740A7F1B53B4CC03D2DC302A8EA16971403CA8B826F6D56E307E04C75EDC1A8565A9EFBBE0F6ECA61D976649A23C82D9A8D7AC3E5124334916A75A6C8AA3B5DFB00FFEB893E6A7E7CEF0622C41C3FFB0B83C38A329E7144F6C06E789D897E3704817C6A79548B8D394EC53A460517DFD1513896B8360156561A5668AEF0F9F2D2B1CDBD4DAA8ED0C28E774EFE72D9FF758B97DAD89B305E5EC82BBC17733DB5F550EFFF1C45CBCA807BD7461C2D3C80FFDE3C1D4410DD678A94ADA54192EABFEC129C5F33DEADEF0C15B1D13782336637544FF1433E97022E45CFD560870ECD85CFF72944596B73DC7D9F978A07A47806E97EDB253019551791D6C62DEB669F5FA5EAA31FCDA0431C07AD97004F527C72548E9D22936D47D8963ABA0D82231473AF8CA45EBC59D93FCE197B7930AD7A82E3D780391A317097CFFA545DC42341FB1B265B851BBF55D95EF63A9AAFA4B2A78036751FBAABCBE9A8215B050AD478C3BF350462A4812A4FDE66FAC8B91718AAD80B68D21E5788F7CB3711F23F25EDBBDF7AC6DD9FBC110EBA2272750936C2F2A74CE5E69DE59A0B6359076EE3FB1D4F2779A6AC5753C860C2CA448E036EA15055D4A19148FE7BCD0AFA3B140A0203548A7A456ECDA8B9B9E740620291F14E21D08EEF21CE5676BB2434233E6C7CC62E48B9B752C87DC87E6DAE0A870E81D17E44AAF6982000A95B7EA676255A17D73FF4A45FAE0C5C9513B5EC0C6414D73EA9488373B6E2FFC9BD2E2C77394BB392F0AD23D91C99D9AA5066EBEE7123D00E223CA3CE572F667DBBD243473453DEC1A44CB979EF3898056D1E3B3A66DB1CB711B232291FA7C128B2D4E73 -20240330083555 2 6 100 8191 5 C4FF326CB002CB4F25BB4309818DE616BCD6A04CB1C8D569FC4D34148B1D5D6B439D6DB946A264765BB6EAAE20B1B737C3CE28B7047D18B47C37ABECEC047E51A0541FE6434045192CE79898A70E6D93E12C35237219A6E3E00F88F5B1EE69982F0ECDA40DE90F5181A6F6F9BF5F9C497A1589ED3E2C16C68A41EA50D544BC57DB544F81F3DD6E6E09E0261A8FB2845A73A13156EBEC90719DE167262FAA68FA08DB412A918DE0D0C5585262DAB724FE31489205D7EA7C669DF4A4423E537153DB359EF31A71FE15C0707D46EE8EFF55305742BE773C6BAD327B2DB2829BF88216A275DFEBB04B3CFA2CF45507788E1DC5EDAFA03A03AD61CFCFE40D7CF7BF3712874CAA2C711691DD189B7024520B0B07D51095E91162FCA7203ECB4DDC9FFEA8355090AB20EEBA13F7901F5B71AB397CD097E0443DFAC8FED92DBBF2B38100E3CCB0118B2C8F27876D6067AF3EE9E44C7F44472C0DC419DE40E23D9DE359138028A9423328261E625A7381012787C370BC3C933C192EFE8CBF23F80271CBCA40F39D1BE4B4173997E646FEDB7AC81006E10D96559EDF6490A56FD47945E35A102C8B00EA740A7F1B53B4CC03D2DC302A8EA16971403CA8B826F6D56E307E04C75EDC1A8565A9EFBBE0F6ECA61D976649A23C82D9A8D7AC3E5124334916A75A6C8AA3B5DFB00FFEB893E6A7E7CEF0622C41C3FFB0B83C38A329E7144F6C06E789D897E3704817C6A79548B8D394EC53A460517DFD1513896B8360156561A5668AEF0F9F2D2B1CDBD4DAA8ED0C28E774EFE72D9FF758B97DAD89B305E5EC82BBC17733DB5F550EFFF1C45CBCA807BD7461C2D3C80FFDE3C1D4410DD678A94ADA54192EABFEC129C5F33DEADEF0C15B1D13782336637544FF1433E97022E45CFD560870ECD85CFF72944596B73DC7D9F978A07A47806E97EDB253019551791D6C62DEB669F5FA5EAA31FCDA0431C07AD97004F527C72548E9D22936D47D8963ABA0D82231473AF8CA45EBC59D93FCE197B7930AD7A82E3D780391A317097CFFA545DC42341FB1B265B851BBF55D95EF63A9AAFA4B2A78036751FBAABCBE9A8215B050AD478C3BF350462A4812A4FDE66FAC8B91718AAD80B68D21E5788F7CB3711F23F25EDBBDF7AC6DD9FBC110EBA2272750936C2F2A74CE5E69DE59A0B6359076EE3FB1D4F2779A6AC5753C860C2CA448E036EA15055D4A19148FE7BCD0AFA3B140A0203548A7A456ECDA8B9B9E740620291F14E21D08EEF21CE5676BB2434233E6C7CC62E48B9B752C87DC87E6DAE0A870E81D17E44AAF6982000A95B7EA676255A17D73FF4A45FAE0C5C9513B5EC0C6414D73EA9488373B6E2FFC9BD2E2C77394BB392F0AD23D91C99D9AA5066EBEE7123D00E223CA3CE572F667DBBD243473453DEC1A44CB979EF3898056D1E3B3A66DB1CB711B232291FA7C128BF7E127 -20240330084121 2 6 100 8191 5 C4FF326CB002CB4F25BB4309818DE616BCD6A04CB1C8D569FC4D34148B1D5D6B439D6DB946A264765BB6EAAE20B1B737C3CE28B7047D18B47C37ABECEC047E51A0541FE6434045192CE79898A70E6D93E12C35237219A6E3E00F88F5B1EE69982F0ECDA40DE90F5181A6F6F9BF5F9C497A1589ED3E2C16C68A41EA50D544BC57DB544F81F3DD6E6E09E0261A8FB2845A73A13156EBEC90719DE167262FAA68FA08DB412A918DE0D0C5585262DAB724FE31489205D7EA7C669DF4A4423E537153DB359EF31A71FE15C0707D46EE8EFF55305742BE773C6BAD327B2DB2829BF88216A275DFEBB04B3CFA2CF45507788E1DC5EDAFA03A03AD61CFCFE40D7CF7BF3712874CAA2C711691DD189B7024520B0B07D51095E91162FCA7203ECB4DDC9FFEA8355090AB20EEBA13F7901F5B71AB397CD097E0443DFAC8FED92DBBF2B38100E3CCB0118B2C8F27876D6067AF3EE9E44C7F44472C0DC419DE40E23D9DE359138028A9423328261E625A7381012787C370BC3C933C192EFE8CBF23F80271CBCA40F39D1BE4B4173997E646FEDB7AC81006E10D96559EDF6490A56FD47945E35A102C8B00EA740A7F1B53B4CC03D2DC302A8EA16971403CA8B826F6D56E307E04C75EDC1A8565A9EFBBE0F6ECA61D976649A23C82D9A8D7AC3E5124334916A75A6C8AA3B5DFB00FFEB893E6A7E7CEF0622C41C3FFB0B83C38A329E7144F6C06E789D897E3704817C6A79548B8D394EC53A460517DFD1513896B8360156561A5668AEF0F9F2D2B1CDBD4DAA8ED0C28E774EFE72D9FF758B97DAD89B305E5EC82BBC17733DB5F550EFFF1C45CBCA807BD7461C2D3C80FFDE3C1D4410DD678A94ADA54192EABFEC129C5F33DEADEF0C15B1D13782336637544FF1433E97022E45CFD560870ECD85CFF72944596B73DC7D9F978A07A47806E97EDB253019551791D6C62DEB669F5FA5EAA31FCDA0431C07AD97004F527C72548E9D22936D47D8963ABA0D82231473AF8CA45EBC59D93FCE197B7930AD7A82E3D780391A317097CFFA545DC42341FB1B265B851BBF55D95EF63A9AAFA4B2A78036751FBAABCBE9A8215B050AD478C3BF350462A4812A4FDE66FAC8B91718AAD80B68D21E5788F7CB3711F23F25EDBBDF7AC6DD9FBC110EBA2272750936C2F2A74CE5E69DE59A0B6359076EE3FB1D4F2779A6AC5753C860C2CA448E036EA15055D4A19148FE7BCD0AFA3B140A0203548A7A456ECDA8B9B9E740620291F14E21D08EEF21CE5676BB2434233E6C7CC62E48B9B752C87DC87E6DAE0A870E81D17E44AAF6982000A95B7EA676255A17D73FF4A45FAE0C5C9513B5EC0C6414D73EA9488373B6E2FFC9BD2E2C77394BB392F0AD23D91C99D9AA5066EBEE7123D00E223CA3CE572F667DBBD243473453DEC1A44CB979EF3898056D1E3B3A66DB1CB711B232291FA7C128C3C894F -20240330104737 2 6 100 8191 2 C4FF326CB002CB4F25BB4309818DE616BCD6A04CB1C8D569FC4D34148B1D5D6B439D6DB946A264765BB6EAAE20B1B737C3CE28B7047D18B47C37ABECEC047E51A0541FE6434045192CE79898A70E6D93E12C35237219A6E3E00F88F5B1EE69982F0ECDA40DE90F5181A6F6F9BF5F9C497A1589ED3E2C16C68A41EA50D544BC57DB544F81F3DD6E6E09E0261A8FB2845A73A13156EBEC90719DE167262FAA68FA08DB412A918DE0D0C5585262DAB724FE31489205D7EA7C669DF4A4423E537153DB359EF31A71FE15C0707D46EE8EFF55305742BE773C6BAD327B2DB2829BF88216A275DFEBB04B3CFA2CF45507788E1DC5EDAFA03A03AD61CFCFE40D7CF7BF3712874CAA2C711691DD189B7024520B0B07D51095E91162FCA7203ECB4DDC9FFEA8355090AB20EEBA13F7901F5B71AB397CD097E0443DFAC8FED92DBBF2B38100E3CCB0118B2C8F27876D6067AF3EE9E44C7F44472C0DC419DE40E23D9DE359138028A9423328261E625A7381012787C370BC3C933C192EFE8CBF23F80271CBCA40F39D1BE4B4173997E646FEDB7AC81006E10D96559EDF6490A56FD47945E35A102C8B00EA740A7F1B53B4CC03D2DC302A8EA16971403CA8B826F6D56E307E04C75EDC1A8565A9EFBBE0F6ECA61D976649A23C82D9A8D7AC3E5124334916A75A6C8AA3B5DFB00FFEB893E6A7E7CEF0622C41C3FFB0B83C38A329E7144F6C06E789D897E3704817C6A79548B8D394EC53A460517DFD1513896B8360156561A5668AEF0F9F2D2B1CDBD4DAA8ED0C28E774EFE72D9FF758B97DAD89B305E5EC82BBC17733DB5F550EFFF1C45CBCA807BD7461C2D3C80FFDE3C1D4410DD678A94ADA54192EABFEC129C5F33DEADEF0C15B1D13782336637544FF1433E97022E45CFD560870ECD85CFF72944596B73DC7D9F978A07A47806E97EDB253019551791D6C62DEB669F5FA5EAA31FCDA0431C07AD97004F527C72548E9D22936D47D8963ABA0D82231473AF8CA45EBC59D93FCE197B7930AD7A82E3D780391A317097CFFA545DC42341FB1B265B851BBF55D95EF63A9AAFA4B2A78036751FBAABCBE9A8215B050AD478C3BF350462A4812A4FDE66FAC8B91718AAD80B68D21E5788F7CB3711F23F25EDBBDF7AC6DD9FBC110EBA2272750936C2F2A74CE5E69DE59A0B6359076EE3FB1D4F2779A6AC5753C860C2CA448E036EA15055D4A19148FE7BCD0AFA3B140A0203548A7A456ECDA8B9B9E740620291F14E21D08EEF21CE5676BB2434233E6C7CC62E48B9B752C87DC87E6DAE0A870E81D17E44AAF6982000A95B7EA676255A17D73FF4A45FAE0C5C9513B5EC0C6414D73EA9488373B6E2FFC9BD2E2C77394BB392F0AD23D91C99D9AA5066EBEE7123D00E223CA3CE572F667DBBD243473453DEC1A44CB979EF3898056D1E3B3A66DB1CB711B232291FA7C129350C1FB -20240330112334 2 6 100 8191 2 C4FF326CB002CB4F25BB4309818DE616BCD6A04CB1C8D569FC4D34148B1D5D6B439D6DB946A264765BB6EAAE20B1B737C3CE28B7047D18B47C37ABECEC047E51A0541FE6434045192CE79898A70E6D93E12C35237219A6E3E00F88F5B1EE69982F0ECDA40DE90F5181A6F6F9BF5F9C497A1589ED3E2C16C68A41EA50D544BC57DB544F81F3DD6E6E09E0261A8FB2845A73A13156EBEC90719DE167262FAA68FA08DB412A918DE0D0C5585262DAB724FE31489205D7EA7C669DF4A4423E537153DB359EF31A71FE15C0707D46EE8EFF55305742BE773C6BAD327B2DB2829BF88216A275DFEBB04B3CFA2CF45507788E1DC5EDAFA03A03AD61CFCFE40D7CF7BF3712874CAA2C711691DD189B7024520B0B07D51095E91162FCA7203ECB4DDC9FFEA8355090AB20EEBA13F7901F5B71AB397CD097E0443DFAC8FED92DBBF2B38100E3CCB0118B2C8F27876D6067AF3EE9E44C7F44472C0DC419DE40E23D9DE359138028A9423328261E625A7381012787C370BC3C933C192EFE8CBF23F80271CBCA40F39D1BE4B4173997E646FEDB7AC81006E10D96559EDF6490A56FD47945E35A102C8B00EA740A7F1B53B4CC03D2DC302A8EA16971403CA8B826F6D56E307E04C75EDC1A8565A9EFBBE0F6ECA61D976649A23C82D9A8D7AC3E5124334916A75A6C8AA3B5DFB00FFEB893E6A7E7CEF0622C41C3FFB0B83C38A329E7144F6C06E789D897E3704817C6A79548B8D394EC53A460517DFD1513896B8360156561A5668AEF0F9F2D2B1CDBD4DAA8ED0C28E774EFE72D9FF758B97DAD89B305E5EC82BBC17733DB5F550EFFF1C45CBCA807BD7461C2D3C80FFDE3C1D4410DD678A94ADA54192EABFEC129C5F33DEADEF0C15B1D13782336637544FF1433E97022E45CFD560870ECD85CFF72944596B73DC7D9F978A07A47806E97EDB253019551791D6C62DEB669F5FA5EAA31FCDA0431C07AD97004F527C72548E9D22936D47D8963ABA0D82231473AF8CA45EBC59D93FCE197B7930AD7A82E3D780391A317097CFFA545DC42341FB1B265B851BBF55D95EF63A9AAFA4B2A78036751FBAABCBE9A8215B050AD478C3BF350462A4812A4FDE66FAC8B91718AAD80B68D21E5788F7CB3711F23F25EDBBDF7AC6DD9FBC110EBA2272750936C2F2A74CE5E69DE59A0B6359076EE3FB1D4F2779A6AC5753C860C2CA448E036EA15055D4A19148FE7BCD0AFA3B140A0203548A7A456ECDA8B9B9E740620291F14E21D08EEF21CE5676BB2434233E6C7CC62E48B9B752C87DC87E6DAE0A870E81D17E44AAF6982000A95B7EA676255A17D73FF4A45FAE0C5C9513B5EC0C6414D73EA9488373B6E2FFC9BD2E2C77394BB392F0AD23D91C99D9AA5066EBEE7123D00E223CA3CE572F667DBBD243473453DEC1A44CB979EF3898056D1E3B3A66DB1CB711B232291FA7C12954A50B3 -20240330133619 2 6 100 8191 5 C4FF326CB002CB4F25BB4309818DE616BCD6A04CB1C8D569FC4D34148B1D5D6B439D6DB946A264765BB6EAAE20B1B737C3CE28B7047D18B47C37ABECEC047E51A0541FE6434045192CE79898A70E6D93E12C35237219A6E3E00F88F5B1EE69982F0ECDA40DE90F5181A6F6F9BF5F9C497A1589ED3E2C16C68A41EA50D544BC57DB544F81F3DD6E6E09E0261A8FB2845A73A13156EBEC90719DE167262FAA68FA08DB412A918DE0D0C5585262DAB724FE31489205D7EA7C669DF4A4423E537153DB359EF31A71FE15C0707D46EE8EFF55305742BE773C6BAD327B2DB2829BF88216A275DFEBB04B3CFA2CF45507788E1DC5EDAFA03A03AD61CFCFE40D7CF7BF3712874CAA2C711691DD189B7024520B0B07D51095E91162FCA7203ECB4DDC9FFEA8355090AB20EEBA13F7901F5B71AB397CD097E0443DFAC8FED92DBBF2B38100E3CCB0118B2C8F27876D6067AF3EE9E44C7F44472C0DC419DE40E23D9DE359138028A9423328261E625A7381012787C370BC3C933C192EFE8CBF23F80271CBCA40F39D1BE4B4173997E646FEDB7AC81006E10D96559EDF6490A56FD47945E35A102C8B00EA740A7F1B53B4CC03D2DC302A8EA16971403CA8B826F6D56E307E04C75EDC1A8565A9EFBBE0F6ECA61D976649A23C82D9A8D7AC3E5124334916A75A6C8AA3B5DFB00FFEB893E6A7E7CEF0622C41C3FFB0B83C38A329E7144F6C06E789D897E3704817C6A79548B8D394EC53A460517DFD1513896B8360156561A5668AEF0F9F2D2B1CDBD4DAA8ED0C28E774EFE72D9FF758B97DAD89B305E5EC82BBC17733DB5F550EFFF1C45CBCA807BD7461C2D3C80FFDE3C1D4410DD678A94ADA54192EABFEC129C5F33DEADEF0C15B1D13782336637544FF1433E97022E45CFD560870ECD85CFF72944596B73DC7D9F978A07A47806E97EDB253019551791D6C62DEB669F5FA5EAA31FCDA0431C07AD97004F527C72548E9D22936D47D8963ABA0D82231473AF8CA45EBC59D93FCE197B7930AD7A82E3D780391A317097CFFA545DC42341FB1B265B851BBF55D95EF63A9AAFA4B2A78036751FBAABCBE9A8215B050AD478C3BF350462A4812A4FDE66FAC8B91718AAD80B68D21E5788F7CB3711F23F25EDBBDF7AC6DD9FBC110EBA2272750936C2F2A74CE5E69DE59A0B6359076EE3FB1D4F2779A6AC5753C860C2CA448E036EA15055D4A19148FE7BCD0AFA3B140A0203548A7A456ECDA8B9B9E740620291F14E21D08EEF21CE5676BB2434233E6C7CC62E48B9B752C87DC87E6DAE0A870E81D17E44AAF6982000A95B7EA676255A17D73FF4A45FAE0C5C9513B5EC0C6414D73EA9488373B6E2FFC9BD2E2C77394BB392F0AD23D91C99D9AA5066EBEE7123D00E223CA3CE572F667DBBD243473453DEC1A44CB979EF3898056D1E3B3A66DB1CB711B232291FA7C129CB0C66F -20240330135122 2 6 100 8191 2 C4FF326CB002CB4F25BB4309818DE616BCD6A04CB1C8D569FC4D34148B1D5D6B439D6DB946A264765BB6EAAE20B1B737C3CE28B7047D18B47C37ABECEC047E51A0541FE6434045192CE79898A70E6D93E12C35237219A6E3E00F88F5B1EE69982F0ECDA40DE90F5181A6F6F9BF5F9C497A1589ED3E2C16C68A41EA50D544BC57DB544F81F3DD6E6E09E0261A8FB2845A73A13156EBEC90719DE167262FAA68FA08DB412A918DE0D0C5585262DAB724FE31489205D7EA7C669DF4A4423E537153DB359EF31A71FE15C0707D46EE8EFF55305742BE773C6BAD327B2DB2829BF88216A275DFEBB04B3CFA2CF45507788E1DC5EDAFA03A03AD61CFCFE40D7CF7BF3712874CAA2C711691DD189B7024520B0B07D51095E91162FCA7203ECB4DDC9FFEA8355090AB20EEBA13F7901F5B71AB397CD097E0443DFAC8FED92DBBF2B38100E3CCB0118B2C8F27876D6067AF3EE9E44C7F44472C0DC419DE40E23D9DE359138028A9423328261E625A7381012787C370BC3C933C192EFE8CBF23F80271CBCA40F39D1BE4B4173997E646FEDB7AC81006E10D96559EDF6490A56FD47945E35A102C8B00EA740A7F1B53B4CC03D2DC302A8EA16971403CA8B826F6D56E307E04C75EDC1A8565A9EFBBE0F6ECA61D976649A23C82D9A8D7AC3E5124334916A75A6C8AA3B5DFB00FFEB893E6A7E7CEF0622C41C3FFB0B83C38A329E7144F6C06E789D897E3704817C6A79548B8D394EC53A460517DFD1513896B8360156561A5668AEF0F9F2D2B1CDBD4DAA8ED0C28E774EFE72D9FF758B97DAD89B305E5EC82BBC17733DB5F550EFFF1C45CBCA807BD7461C2D3C80FFDE3C1D4410DD678A94ADA54192EABFEC129C5F33DEADEF0C15B1D13782336637544FF1433E97022E45CFD560870ECD85CFF72944596B73DC7D9F978A07A47806E97EDB253019551791D6C62DEB669F5FA5EAA31FCDA0431C07AD97004F527C72548E9D22936D47D8963ABA0D82231473AF8CA45EBC59D93FCE197B7930AD7A82E3D780391A317097CFFA545DC42341FB1B265B851BBF55D95EF63A9AAFA4B2A78036751FBAABCBE9A8215B050AD478C3BF350462A4812A4FDE66FAC8B91718AAD80B68D21E5788F7CB3711F23F25EDBBDF7AC6DD9FBC110EBA2272750936C2F2A74CE5E69DE59A0B6359076EE3FB1D4F2779A6AC5753C860C2CA448E036EA15055D4A19148FE7BCD0AFA3B140A0203548A7A456ECDA8B9B9E740620291F14E21D08EEF21CE5676BB2434233E6C7CC62E48B9B752C87DC87E6DAE0A870E81D17E44AAF6982000A95B7EA676255A17D73FF4A45FAE0C5C9513B5EC0C6414D73EA9488373B6E2FFC9BD2E2C77394BB392F0AD23D91C99D9AA5066EBEE7123D00E223CA3CE572F667DBBD243473453DEC1A44CB979EF3898056D1E3B3A66DB1CB711B232291FA7C129D7F94B3 -20240330141203 2 6 100 8191 2 C4FF326CB002CB4F25BB4309818DE616BCD6A04CB1C8D569FC4D34148B1D5D6B439D6DB946A264765BB6EAAE20B1B737C3CE28B7047D18B47C37ABECEC047E51A0541FE6434045192CE79898A70E6D93E12C35237219A6E3E00F88F5B1EE69982F0ECDA40DE90F5181A6F6F9BF5F9C497A1589ED3E2C16C68A41EA50D544BC57DB544F81F3DD6E6E09E0261A8FB2845A73A13156EBEC90719DE167262FAA68FA08DB412A918DE0D0C5585262DAB724FE31489205D7EA7C669DF4A4423E537153DB359EF31A71FE15C0707D46EE8EFF55305742BE773C6BAD327B2DB2829BF88216A275DFEBB04B3CFA2CF45507788E1DC5EDAFA03A03AD61CFCFE40D7CF7BF3712874CAA2C711691DD189B7024520B0B07D51095E91162FCA7203ECB4DDC9FFEA8355090AB20EEBA13F7901F5B71AB397CD097E0443DFAC8FED92DBBF2B38100E3CCB0118B2C8F27876D6067AF3EE9E44C7F44472C0DC419DE40E23D9DE359138028A9423328261E625A7381012787C370BC3C933C192EFE8CBF23F80271CBCA40F39D1BE4B4173997E646FEDB7AC81006E10D96559EDF6490A56FD47945E35A102C8B00EA740A7F1B53B4CC03D2DC302A8EA16971403CA8B826F6D56E307E04C75EDC1A8565A9EFBBE0F6ECA61D976649A23C82D9A8D7AC3E5124334916A75A6C8AA3B5DFB00FFEB893E6A7E7CEF0622C41C3FFB0B83C38A329E7144F6C06E789D897E3704817C6A79548B8D394EC53A460517DFD1513896B8360156561A5668AEF0F9F2D2B1CDBD4DAA8ED0C28E774EFE72D9FF758B97DAD89B305E5EC82BBC17733DB5F550EFFF1C45CBCA807BD7461C2D3C80FFDE3C1D4410DD678A94ADA54192EABFEC129C5F33DEADEF0C15B1D13782336637544FF1433E97022E45CFD560870ECD85CFF72944596B73DC7D9F978A07A47806E97EDB253019551791D6C62DEB669F5FA5EAA31FCDA0431C07AD97004F527C72548E9D22936D47D8963ABA0D82231473AF8CA45EBC59D93FCE197B7930AD7A82E3D780391A317097CFFA545DC42341FB1B265B851BBF55D95EF63A9AAFA4B2A78036751FBAABCBE9A8215B050AD478C3BF350462A4812A4FDE66FAC8B91718AAD80B68D21E5788F7CB3711F23F25EDBBDF7AC6DD9FBC110EBA2272750936C2F2A74CE5E69DE59A0B6359076EE3FB1D4F2779A6AC5753C860C2CA448E036EA15055D4A19148FE7BCD0AFA3B140A0203548A7A456ECDA8B9B9E740620291F14E21D08EEF21CE5676BB2434233E6C7CC62E48B9B752C87DC87E6DAE0A870E81D17E44AAF6982000A95B7EA676255A17D73FF4A45FAE0C5C9513B5EC0C6414D73EA9488373B6E2FFC9BD2E2C77394BB392F0AD23D91C99D9AA5066EBEE7123D00E223CA3CE572F667DBBD243473453DEC1A44CB979EF3898056D1E3B3A66DB1CB711B232291FA7C129E9C046B -20240330155328 2 6 100 8191 2 C4FF326CB002CB4F25BB4309818DE616BCD6A04CB1C8D569FC4D34148B1D5D6B439D6DB946A264765BB6EAAE20B1B737C3CE28B7047D18B47C37ABECEC047E51A0541FE6434045192CE79898A70E6D93E12C35237219A6E3E00F88F5B1EE69982F0ECDA40DE90F5181A6F6F9BF5F9C497A1589ED3E2C16C68A41EA50D544BC57DB544F81F3DD6E6E09E0261A8FB2845A73A13156EBEC90719DE167262FAA68FA08DB412A918DE0D0C5585262DAB724FE31489205D7EA7C669DF4A4423E537153DB359EF31A71FE15C0707D46EE8EFF55305742BE773C6BAD327B2DB2829BF88216A275DFEBB04B3CFA2CF45507788E1DC5EDAFA03A03AD61CFCFE40D7CF7BF3712874CAA2C711691DD189B7024520B0B07D51095E91162FCA7203ECB4DDC9FFEA8355090AB20EEBA13F7901F5B71AB397CD097E0443DFAC8FED92DBBF2B38100E3CCB0118B2C8F27876D6067AF3EE9E44C7F44472C0DC419DE40E23D9DE359138028A9423328261E625A7381012787C370BC3C933C192EFE8CBF23F80271CBCA40F39D1BE4B4173997E646FEDB7AC81006E10D96559EDF6490A56FD47945E35A102C8B00EA740A7F1B53B4CC03D2DC302A8EA16971403CA8B826F6D56E307E04C75EDC1A8565A9EFBBE0F6ECA61D976649A23C82D9A8D7AC3E5124334916A75A6C8AA3B5DFB00FFEB893E6A7E7CEF0622C41C3FFB0B83C38A329E7144F6C06E789D897E3704817C6A79548B8D394EC53A460517DFD1513896B8360156561A5668AEF0F9F2D2B1CDBD4DAA8ED0C28E774EFE72D9FF758B97DAD89B305E5EC82BBC17733DB5F550EFFF1C45CBCA807BD7461C2D3C80FFDE3C1D4410DD678A94ADA54192EABFEC129C5F33DEADEF0C15B1D13782336637544FF1433E97022E45CFD560870ECD85CFF72944596B73DC7D9F978A07A47806E97EDB253019551791D6C62DEB669F5FA5EAA31FCDA0431C07AD97004F527C72548E9D22936D47D8963ABA0D82231473AF8CA45EBC59D93FCE197B7930AD7A82E3D780391A317097CFFA545DC42341FB1B265B851BBF55D95EF63A9AAFA4B2A78036751FBAABCBE9A8215B050AD478C3BF350462A4812A4FDE66FAC8B91718AAD80B68D21E5788F7CB3711F23F25EDBBDF7AC6DD9FBC110EBA2272750936C2F2A74CE5E69DE59A0B6359076EE3FB1D4F2779A6AC5753C860C2CA448E036EA15055D4A19148FE7BCD0AFA3B140A0203548A7A456ECDA8B9B9E740620291F14E21D08EEF21CE5676BB2434233E6C7CC62E48B9B752C87DC87E6DAE0A870E81D17E44AAF6982000A95B7EA676255A17D73FF4A45FAE0C5C9513B5EC0C6414D73EA9488373B6E2FFC9BD2E2C77394BB392F0AD23D91C99D9AA5066EBEE7123D00E223CA3CE572F667DBBD243473453DEC1A44CB979EF3898056D1E3B3A66DB1CB711B232291FA7C12A438CDC3 -20240330164337 2 6 100 8191 2 C4FF326CB002CB4F25BB4309818DE616BCD6A04CB1C8D569FC4D34148B1D5D6B439D6DB946A264765BB6EAAE20B1B737C3CE28B7047D18B47C37ABECEC047E51A0541FE6434045192CE79898A70E6D93E12C35237219A6E3E00F88F5B1EE69982F0ECDA40DE90F5181A6F6F9BF5F9C497A1589ED3E2C16C68A41EA50D544BC57DB544F81F3DD6E6E09E0261A8FB2845A73A13156EBEC90719DE167262FAA68FA08DB412A918DE0D0C5585262DAB724FE31489205D7EA7C669DF4A4423E537153DB359EF31A71FE15C0707D46EE8EFF55305742BE773C6BAD327B2DB2829BF88216A275DFEBB04B3CFA2CF45507788E1DC5EDAFA03A03AD61CFCFE40D7CF7BF3712874CAA2C711691DD189B7024520B0B07D51095E91162FCA7203ECB4DDC9FFEA8355090AB20EEBA13F7901F5B71AB397CD097E0443DFAC8FED92DBBF2B38100E3CCB0118B2C8F27876D6067AF3EE9E44C7F44472C0DC419DE40E23D9DE359138028A9423328261E625A7381012787C370BC3C933C192EFE8CBF23F80271CBCA40F39D1BE4B4173997E646FEDB7AC81006E10D96559EDF6490A56FD47945E35A102C8B00EA740A7F1B53B4CC03D2DC302A8EA16971403CA8B826F6D56E307E04C75EDC1A8565A9EFBBE0F6ECA61D976649A23C82D9A8D7AC3E5124334916A75A6C8AA3B5DFB00FFEB893E6A7E7CEF0622C41C3FFB0B83C38A329E7144F6C06E789D897E3704817C6A79548B8D394EC53A460517DFD1513896B8360156561A5668AEF0F9F2D2B1CDBD4DAA8ED0C28E774EFE72D9FF758B97DAD89B305E5EC82BBC17733DB5F550EFFF1C45CBCA807BD7461C2D3C80FFDE3C1D4410DD678A94ADA54192EABFEC129C5F33DEADEF0C15B1D13782336637544FF1433E97022E45CFD560870ECD85CFF72944596B73DC7D9F978A07A47806E97EDB253019551791D6C62DEB669F5FA5EAA31FCDA0431C07AD97004F527C72548E9D22936D47D8963ABA0D82231473AF8CA45EBC59D93FCE197B7930AD7A82E3D780391A317097CFFA545DC42341FB1B265B851BBF55D95EF63A9AAFA4B2A78036751FBAABCBE9A8215B050AD478C3BF350462A4812A4FDE66FAC8B91718AAD80B68D21E5788F7CB3711F23F25EDBBDF7AC6DD9FBC110EBA2272750936C2F2A74CE5E69DE59A0B6359076EE3FB1D4F2779A6AC5753C860C2CA448E036EA15055D4A19148FE7BCD0AFA3B140A0203548A7A456ECDA8B9B9E740620291F14E21D08EEF21CE5676BB2434233E6C7CC62E48B9B752C87DC87E6DAE0A870E81D17E44AAF6982000A95B7EA676255A17D73FF4A45FAE0C5C9513B5EC0C6414D73EA9488373B6E2FFC9BD2E2C77394BB392F0AD23D91C99D9AA5066EBEE7123D00E223CA3CE572F667DBBD243473453DEC1A44CB979EF3898056D1E3B3A66DB1CB711B232291FA7C12A6FF833B -20240330172236 2 6 100 8191 2 C4FF326CB002CB4F25BB4309818DE616BCD6A04CB1C8D569FC4D34148B1D5D6B439D6DB946A264765BB6EAAE20B1B737C3CE28B7047D18B47C37ABECEC047E51A0541FE6434045192CE79898A70E6D93E12C35237219A6E3E00F88F5B1EE69982F0ECDA40DE90F5181A6F6F9BF5F9C497A1589ED3E2C16C68A41EA50D544BC57DB544F81F3DD6E6E09E0261A8FB2845A73A13156EBEC90719DE167262FAA68FA08DB412A918DE0D0C5585262DAB724FE31489205D7EA7C669DF4A4423E537153DB359EF31A71FE15C0707D46EE8EFF55305742BE773C6BAD327B2DB2829BF88216A275DFEBB04B3CFA2CF45507788E1DC5EDAFA03A03AD61CFCFE40D7CF7BF3712874CAA2C711691DD189B7024520B0B07D51095E91162FCA7203ECB4DDC9FFEA8355090AB20EEBA13F7901F5B71AB397CD097E0443DFAC8FED92DBBF2B38100E3CCB0118B2C8F27876D6067AF3EE9E44C7F44472C0DC419DE40E23D9DE359138028A9423328261E625A7381012787C370BC3C933C192EFE8CBF23F80271CBCA40F39D1BE4B4173997E646FEDB7AC81006E10D96559EDF6490A56FD47945E35A102C8B00EA740A7F1B53B4CC03D2DC302A8EA16971403CA8B826F6D56E307E04C75EDC1A8565A9EFBBE0F6ECA61D976649A23C82D9A8D7AC3E5124334916A75A6C8AA3B5DFB00FFEB893E6A7E7CEF0622C41C3FFB0B83C38A329E7144F6C06E789D897E3704817C6A79548B8D394EC53A460517DFD1513896B8360156561A5668AEF0F9F2D2B1CDBD4DAA8ED0C28E774EFE72D9FF758B97DAD89B305E5EC82BBC17733DB5F550EFFF1C45CBCA807BD7461C2D3C80FFDE3C1D4410DD678A94ADA54192EABFEC129C5F33DEADEF0C15B1D13782336637544FF1433E97022E45CFD560870ECD85CFF72944596B73DC7D9F978A07A47806E97EDB253019551791D6C62DEB669F5FA5EAA31FCDA0431C07AD97004F527C72548E9D22936D47D8963ABA0D82231473AF8CA45EBC59D93FCE197B7930AD7A82E3D780391A317097CFFA545DC42341FB1B265B851BBF55D95EF63A9AAFA4B2A78036751FBAABCBE9A8215B050AD478C3BF350462A4812A4FDE66FAC8B91718AAD80B68D21E5788F7CB3711F23F25EDBBDF7AC6DD9FBC110EBA2272750936C2F2A74CE5E69DE59A0B6359076EE3FB1D4F2779A6AC5753C860C2CA448E036EA15055D4A19148FE7BCD0AFA3B140A0203548A7A456ECDA8B9B9E740620291F14E21D08EEF21CE5676BB2434233E6C7CC62E48B9B752C87DC87E6DAE0A870E81D17E44AAF6982000A95B7EA676255A17D73FF4A45FAE0C5C9513B5EC0C6414D73EA9488373B6E2FFC9BD2E2C77394BB392F0AD23D91C99D9AA5066EBEE7123D00E223CA3CE572F667DBBD243473453DEC1A44CB979EF3898056D1E3B3A66DB1CB711B232291FA7C12A9222D1B -20240330193325 2 6 100 8191 2 C4FF326CB002CB4F25BB4309818DE616BCD6A04CB1C8D569FC4D34148B1D5D6B439D6DB946A264765BB6EAAE20B1B737C3CE28B7047D18B47C37ABECEC047E51A0541FE6434045192CE79898A70E6D93E12C35237219A6E3E00F88F5B1EE69982F0ECDA40DE90F5181A6F6F9BF5F9C497A1589ED3E2C16C68A41EA50D544BC57DB544F81F3DD6E6E09E0261A8FB2845A73A13156EBEC90719DE167262FAA68FA08DB412A918DE0D0C5585262DAB724FE31489205D7EA7C669DF4A4423E537153DB359EF31A71FE15C0707D46EE8EFF55305742BE773C6BAD327B2DB2829BF88216A275DFEBB04B3CFA2CF45507788E1DC5EDAFA03A03AD61CFCFE40D7CF7BF3712874CAA2C711691DD189B7024520B0B07D51095E91162FCA7203ECB4DDC9FFEA8355090AB20EEBA13F7901F5B71AB397CD097E0443DFAC8FED92DBBF2B38100E3CCB0118B2C8F27876D6067AF3EE9E44C7F44472C0DC419DE40E23D9DE359138028A9423328261E625A7381012787C370BC3C933C192EFE8CBF23F80271CBCA40F39D1BE4B4173997E646FEDB7AC81006E10D96559EDF6490A56FD47945E35A102C8B00EA740A7F1B53B4CC03D2DC302A8EA16971403CA8B826F6D56E307E04C75EDC1A8565A9EFBBE0F6ECA61D976649A23C82D9A8D7AC3E5124334916A75A6C8AA3B5DFB00FFEB893E6A7E7CEF0622C41C3FFB0B83C38A329E7144F6C06E789D897E3704817C6A79548B8D394EC53A460517DFD1513896B8360156561A5668AEF0F9F2D2B1CDBD4DAA8ED0C28E774EFE72D9FF758B97DAD89B305E5EC82BBC17733DB5F550EFFF1C45CBCA807BD7461C2D3C80FFDE3C1D4410DD678A94ADA54192EABFEC129C5F33DEADEF0C15B1D13782336637544FF1433E97022E45CFD560870ECD85CFF72944596B73DC7D9F978A07A47806E97EDB253019551791D6C62DEB669F5FA5EAA31FCDA0431C07AD97004F527C72548E9D22936D47D8963ABA0D82231473AF8CA45EBC59D93FCE197B7930AD7A82E3D780391A317097CFFA545DC42341FB1B265B851BBF55D95EF63A9AAFA4B2A78036751FBAABCBE9A8215B050AD478C3BF350462A4812A4FDE66FAC8B91718AAD80B68D21E5788F7CB3711F23F25EDBBDF7AC6DD9FBC110EBA2272750936C2F2A74CE5E69DE59A0B6359076EE3FB1D4F2779A6AC5753C860C2CA448E036EA15055D4A19148FE7BCD0AFA3B140A0203548A7A456ECDA8B9B9E740620291F14E21D08EEF21CE5676BB2434233E6C7CC62E48B9B752C87DC87E6DAE0A870E81D17E44AAF6982000A95B7EA676255A17D73FF4A45FAE0C5C9513B5EC0C6414D73EA9488373B6E2FFC9BD2E2C77394BB392F0AD23D91C99D9AA5066EBEE7123D00E223CA3CE572F667DBBD243473453DEC1A44CB979EF3898056D1E3B3A66DB1CB711B232291FA7C12B07FB5BB -20240330201458 2 6 100 8191 2 C4FF326CB002CB4F25BB4309818DE616BCD6A04CB1C8D569FC4D34148B1D5D6B439D6DB946A264765BB6EAAE20B1B737C3CE28B7047D18B47C37ABECEC047E51A0541FE6434045192CE79898A70E6D93E12C35237219A6E3E00F88F5B1EE69982F0ECDA40DE90F5181A6F6F9BF5F9C497A1589ED3E2C16C68A41EA50D544BC57DB544F81F3DD6E6E09E0261A8FB2845A73A13156EBEC90719DE167262FAA68FA08DB412A918DE0D0C5585262DAB724FE31489205D7EA7C669DF4A4423E537153DB359EF31A71FE15C0707D46EE8EFF55305742BE773C6BAD327B2DB2829BF88216A275DFEBB04B3CFA2CF45507788E1DC5EDAFA03A03AD61CFCFE40D7CF7BF3712874CAA2C711691DD189B7024520B0B07D51095E91162FCA7203ECB4DDC9FFEA8355090AB20EEBA13F7901F5B71AB397CD097E0443DFAC8FED92DBBF2B38100E3CCB0118B2C8F27876D6067AF3EE9E44C7F44472C0DC419DE40E23D9DE359138028A9423328261E625A7381012787C370BC3C933C192EFE8CBF23F80271CBCA40F39D1BE4B4173997E646FEDB7AC81006E10D96559EDF6490A56FD47945E35A102C8B00EA740A7F1B53B4CC03D2DC302A8EA16971403CA8B826F6D56E307E04C75EDC1A8565A9EFBBE0F6ECA61D976649A23C82D9A8D7AC3E5124334916A75A6C8AA3B5DFB00FFEB893E6A7E7CEF0622C41C3FFB0B83C38A329E7144F6C06E789D897E3704817C6A79548B8D394EC53A460517DFD1513896B8360156561A5668AEF0F9F2D2B1CDBD4DAA8ED0C28E774EFE72D9FF758B97DAD89B305E5EC82BBC17733DB5F550EFFF1C45CBCA807BD7461C2D3C80FFDE3C1D4410DD678A94ADA54192EABFEC129C5F33DEADEF0C15B1D13782336637544FF1433E97022E45CFD560870ECD85CFF72944596B73DC7D9F978A07A47806E97EDB253019551791D6C62DEB669F5FA5EAA31FCDA0431C07AD97004F527C72548E9D22936D47D8963ABA0D82231473AF8CA45EBC59D93FCE197B7930AD7A82E3D780391A317097CFFA545DC42341FB1B265B851BBF55D95EF63A9AAFA4B2A78036751FBAABCBE9A8215B050AD478C3BF350462A4812A4FDE66FAC8B91718AAD80B68D21E5788F7CB3711F23F25EDBBDF7AC6DD9FBC110EBA2272750936C2F2A74CE5E69DE59A0B6359076EE3FB1D4F2779A6AC5753C860C2CA448E036EA15055D4A19148FE7BCD0AFA3B140A0203548A7A456ECDA8B9B9E740620291F14E21D08EEF21CE5676BB2434233E6C7CC62E48B9B752C87DC87E6DAE0A870E81D17E44AAF6982000A95B7EA676255A17D73FF4A45FAE0C5C9513B5EC0C6414D73EA9488373B6E2FFC9BD2E2C77394BB392F0AD23D91C99D9AA5066EBEE7123D00E223CA3CE572F667DBBD243473453DEC1A44CB979EF3898056D1E3B3A66DB1CB711B232291FA7C12B2CA43B3 -20240330212712 2 6 100 8191 2 C4FF326CB002CB4F25BB4309818DE616BCD6A04CB1C8D569FC4D34148B1D5D6B439D6DB946A264765BB6EAAE20B1B737C3CE28B7047D18B47C37ABECEC047E51A0541FE6434045192CE79898A70E6D93E12C35237219A6E3E00F88F5B1EE69982F0ECDA40DE90F5181A6F6F9BF5F9C497A1589ED3E2C16C68A41EA50D544BC57DB544F81F3DD6E6E09E0261A8FB2845A73A13156EBEC90719DE167262FAA68FA08DB412A918DE0D0C5585262DAB724FE31489205D7EA7C669DF4A4423E537153DB359EF31A71FE15C0707D46EE8EFF55305742BE773C6BAD327B2DB2829BF88216A275DFEBB04B3CFA2CF45507788E1DC5EDAFA03A03AD61CFCFE40D7CF7BF3712874CAA2C711691DD189B7024520B0B07D51095E91162FCA7203ECB4DDC9FFEA8355090AB20EEBA13F7901F5B71AB397CD097E0443DFAC8FED92DBBF2B38100E3CCB0118B2C8F27876D6067AF3EE9E44C7F44472C0DC419DE40E23D9DE359138028A9423328261E625A7381012787C370BC3C933C192EFE8CBF23F80271CBCA40F39D1BE4B4173997E646FEDB7AC81006E10D96559EDF6490A56FD47945E35A102C8B00EA740A7F1B53B4CC03D2DC302A8EA16971403CA8B826F6D56E307E04C75EDC1A8565A9EFBBE0F6ECA61D976649A23C82D9A8D7AC3E5124334916A75A6C8AA3B5DFB00FFEB893E6A7E7CEF0622C41C3FFB0B83C38A329E7144F6C06E789D897E3704817C6A79548B8D394EC53A460517DFD1513896B8360156561A5668AEF0F9F2D2B1CDBD4DAA8ED0C28E774EFE72D9FF758B97DAD89B305E5EC82BBC17733DB5F550EFFF1C45CBCA807BD7461C2D3C80FFDE3C1D4410DD678A94ADA54192EABFEC129C5F33DEADEF0C15B1D13782336637544FF1433E97022E45CFD560870ECD85CFF72944596B73DC7D9F978A07A47806E97EDB253019551791D6C62DEB669F5FA5EAA31FCDA0431C07AD97004F527C72548E9D22936D47D8963ABA0D82231473AF8CA45EBC59D93FCE197B7930AD7A82E3D780391A317097CFFA545DC42341FB1B265B851BBF55D95EF63A9AAFA4B2A78036751FBAABCBE9A8215B050AD478C3BF350462A4812A4FDE66FAC8B91718AAD80B68D21E5788F7CB3711F23F25EDBBDF7AC6DD9FBC110EBA2272750936C2F2A74CE5E69DE59A0B6359076EE3FB1D4F2779A6AC5753C860C2CA448E036EA15055D4A19148FE7BCD0AFA3B140A0203548A7A456ECDA8B9B9E740620291F14E21D08EEF21CE5676BB2434233E6C7CC62E48B9B752C87DC87E6DAE0A870E81D17E44AAF6982000A95B7EA676255A17D73FF4A45FAE0C5C9513B5EC0C6414D73EA9488373B6E2FFC9BD2E2C77394BB392F0AD23D91C99D9AA5066EBEE7123D00E223CA3CE572F667DBBD243473453DEC1A44CB979EF3898056D1E3B3A66DB1CB711B232291FA7C12B6C88EF3 -20240330225844 2 6 100 8191 5 C4FF326CB002CB4F25BB4309818DE616BCD6A04CB1C8D569FC4D34148B1D5D6B439D6DB946A264765BB6EAAE20B1B737C3CE28B7047D18B47C37ABECEC047E51A0541FE6434045192CE79898A70E6D93E12C35237219A6E3E00F88F5B1EE69982F0ECDA40DE90F5181A6F6F9BF5F9C497A1589ED3E2C16C68A41EA50D544BC57DB544F81F3DD6E6E09E0261A8FB2845A73A13156EBEC90719DE167262FAA68FA08DB412A918DE0D0C5585262DAB724FE31489205D7EA7C669DF4A4423E537153DB359EF31A71FE15C0707D46EE8EFF55305742BE773C6BAD327B2DB2829BF88216A275DFEBB04B3CFA2CF45507788E1DC5EDAFA03A03AD61CFCFE40D7CF7BF3712874CAA2C711691DD189B7024520B0B07D51095E91162FCA7203ECB4DDC9FFEA8355090AB20EEBA13F7901F5B71AB397CD097E0443DFAC8FED92DBBF2B38100E3CCB0118B2C8F27876D6067AF3EE9E44C7F44472C0DC419DE40E23D9DE359138028A9423328261E625A7381012787C370BC3C933C192EFE8CBF23F80271CBCA40F39D1BE4B4173997E646FEDB7AC81006E10D96559EDF6490A56FD47945E35A102C8B00EA740A7F1B53B4CC03D2DC302A8EA16971403CA8B826F6D56E307E04C75EDC1A8565A9EFBBE0F6ECA61D976649A23C82D9A8D7AC3E5124334916A75A6C8AA3B5DFB00FFEB893E6A7E7CEF0622C41C3FFB0B83C38A329E7144F6C06E789D897E3704817C6A79548B8D394EC53A460517DFD1513896B8360156561A5668AEF0F9F2D2B1CDBD4DAA8ED0C28E774EFE72D9FF758B97DAD89B305E5EC82BBC17733DB5F550EFFF1C45CBCA807BD7461C2D3C80FFDE3C1D4410DD678A94ADA54192EABFEC129C5F33DEADEF0C15B1D13782336637544FF1433E97022E45CFD560870ECD85CFF72944596B73DC7D9F978A07A47806E97EDB253019551791D6C62DEB669F5FA5EAA31FCDA0431C07AD97004F527C72548E9D22936D47D8963ABA0D82231473AF8CA45EBC59D93FCE197B7930AD7A82E3D780391A317097CFFA545DC42341FB1B265B851BBF55D95EF63A9AAFA4B2A78036751FBAABCBE9A8215B050AD478C3BF350462A4812A4FDE66FAC8B91718AAD80B68D21E5788F7CB3711F23F25EDBBDF7AC6DD9FBC110EBA2272750936C2F2A74CE5E69DE59A0B6359076EE3FB1D4F2779A6AC5753C860C2CA448E036EA15055D4A19148FE7BCD0AFA3B140A0203548A7A456ECDA8B9B9E740620291F14E21D08EEF21CE5676BB2434233E6C7CC62E48B9B752C87DC87E6DAE0A870E81D17E44AAF6982000A95B7EA676255A17D73FF4A45FAE0C5C9513B5EC0C6414D73EA9488373B6E2FFC9BD2E2C77394BB392F0AD23D91C99D9AA5066EBEE7123D00E223CA3CE572F667DBBD243473453DEC1A44CB979EF3898056D1E3B3A66DB1CB711B232291FA7C12BBE67097 -20240331000148 2 6 100 8191 5 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51B73EA509F -20240331002043 2 6 100 8191 5 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51B74F19237 -20240331015303 2 6 100 8191 5 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51B7A08A157 -20240331021926 2 6 100 8191 2 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51B7B77B293 -20240331031147 2 6 100 8191 2 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51B7E5DF07B -20240331032001 2 6 100 8191 5 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51B7ECA5C3F -20240331054028 2 6 100 8191 5 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51B86B76577 -20240331062300 2 6 100 8191 2 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51B891AC21B -20240331063150 2 6 100 8191 2 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51B898D590B -20240331064453 2 6 100 8191 2 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51B8A3FB29B -20240331070343 2 6 100 8191 2 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51B8B4728B3 -20240331082004 2 6 100 8191 5 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51B8F78FC67 -20240331083046 2 6 100 8191 2 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51B90063753 -20240331085336 2 6 100 8191 2 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51B913BDDA3 -20240331104948 2 6 100 8191 2 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51B97AD8FBB -20240331121935 2 6 100 8191 2 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51B9CBCB66B -20240331125021 2 6 100 8191 5 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51B9E75E9EF -20240331131006 2 6 100 8191 2 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51B9F876B2B -20240331135555 2 6 100 8191 2 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51BA21BA983 -20240331154257 2 6 100 8191 2 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51BA8151143 -20240331171643 2 6 100 8191 5 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51BAD603A0F -20240331180835 2 6 100 8191 2 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51BB042B533 -20240331184114 2 6 100 8191 5 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51BB20E55D7 -20240331190024 2 6 100 8191 2 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51BB31FB5FB -20240331193130 2 6 100 8191 2 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51BB4D5DEF3 -20240331203633 2 6 100 8191 2 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51BB878F90B -20240331215848 2 6 100 8191 2 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51BBD220A13 -20240331220718 2 6 100 8191 2 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51BBD9694FB -20240331234057 2 6 100 8191 2 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51BC2D1D8B3 -20240401015736 2 6 100 8191 2 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51BCA81EB2B -20240401044749 2 6 100 8191 2 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51BD41C3C93 -20240401051819 2 6 100 8191 5 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51BD5D2C057 -20240401061504 2 6 100 8191 2 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51BD8EDA743 -20240401062619 2 6 100 8191 5 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51BD98C438F -20240401095349 2 6 100 8191 2 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51BE51ECC83 -20240401133450 2 6 100 8191 2 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51BF189CF03 -20240401134927 2 6 100 8191 5 C236B21D4EECEC7DC25307B012452FBBBA72E7AB9CAD0D72A327FD19280856FD9993CDA7989072BD8C6E597FF7E009888DDDF8383E4F27BDB40D384CE8E9E7D739F296FD74C5415A164B0746783ACF1ABF031D4E8D1F2585BB9DBF6195215D9663196D4C5D3162E95A7163CA49255C77E412FFD7230B29C42C8703726D41006EBCFDB4EE478111ED6A8B3EDFE73496070250ECEBBB15E9376DCA438A3905EE308F8E4E064C31D1399ED7BB8AC8F6E458E8B43B1AC35DC4600B3780EA5D30F0704E7EEFDA1F2BACC94196B27E4A08B622D0AD441F3FEBA78A30D49732673040D7DD905604C7A7972BF62EFA6F3E477EADF778A7B9EA91ED338B72A42E4C30C40EF3CFADFAAF1690E469AD2B160FB1C2E836090D69F42C035B81B0E3301C0A18F9CA77C54447DB2AE57EC1765D79E188073D26328E285A3B889983409DA8B28EE75E5882524878D25083126A8007E5833272A7C330221D51CB023EC3BB452518BD57AEA2EE4560E57DF5FB7017646C6A426041551E6C55FE4ED7506FDFA1A04E1F9C36B47B031FFE4AE7480780BDC916A2B5A96C7B6D20EAFC4DF2FE721B415C365FEC16D0FEC74D034727A32D8E16D5E6CD64CAF6BC6F394E8BFBD3E9895A00924C016EEB8B6932B11CEB9A15668FE87E931CE9B1F30C3B23508760DF07A7B0AEDEDA196CC2D2974A15B51087503AF06B7351854CA928C966634E4638DC49A714B9F163AFAFD29B192E5AD2F4DED6A6945D77E7F26A72B5D6D1FB5C2F3A48970E9A0D2A212FBB8C15D5EA5435DA282E4C75DC3366BED430F71FFB6A43759542D572F828533C2437F65AB6A86EB6A994D2AA49B81D28106CFBDA10BBD7CA117A6E3CBED73D53185FEDE998C0D2EBADD81AEE2CFFAF17276E110BDDDDA163CDB5F12C12F67F432143588D4FDA6EF0763BAEC70B7D43BCD0213E650FEE7CAE47A3F327605A56116F2DB500F6481AAAD8AC312CD62F6E344705C5DA741C5E30140FB702BEE43DE37D905E8688E03F2E4D84DCBFD1BAED99BC18FAE53D701B6D78A6CDC84CDD09BA52F495785135F9006C34D7FB1059200FE16D1C707302FFB775387B3BDF1833953C0090D44076F1C27F815B638A846BEFCFC4F14B5EB38136737657E4781B8EDE5D97C175AF87F1EBE97DE9EBC410CA0C14DF17E320E986181D05D7573DF744D28846A6D78B193C7E094EE4530A15385AE6865469ADA3BCA7D6582E05C046B04306DD460940D9F76A72C13E9EFAA9184F5DC17FAB86879B29A6049BF201C5F21F6442BC1225217C288066E4FA5C16C62F8923B5C4A6B218365B3806349CEC8F79EEA94170A94BB10D6127DC78D1493CBBF7E12A7C1C2C4C14F353110E01DB0FA6459344DDD60EADE8F49924280CDEBE3D563F7069746DA3A0717438169F67534B769A9DE2B9938F148854652D7DDC7E513BAB18D356C51BF2540457 +20241129001801 2 6 100 2047 5 CAA48956B64FC48DD5A4823E073002797519479815F1B8D4AAAB1748CB28F30774053A901B0A52BB700F0AFB1C23E06C63EEC4326CFA484724954492B3703B50C706447754E091B6F69DEF32413B230FBC521D3912A2A030258ED841F28BD56BF27A3543756DEA1BBD62A44E66D80B22D9B41045E6DB0AFA700156862E4D24F682327787A9E10BC63D2E5F303F19109E1E3BA661635E34BBDC98BA711DFF7F7710CF632D3DDAD5B3B2539B61A309AD1BA93A60A03F1ACF9F89A6B166EDBBBA0B8160993BEF2FE072E278CDACBA5BBE44D9D5F353158DC4AECABC6EF9E16CC7DB9E5D697D3B42E02B675FB800D91F7CE79F553C6B610320EEA13FC56E329A8EFF +20241129001804 2 6 100 2047 5 CAA48956B64FC48DD5A4823E073002797519479815F1B8D4AAAB1748CB28F30774053A901B0A52BB700F0AFB1C23E06C63EEC4326CFA484724954492B3703B50C706447754E091B6F69DEF32413B230FBC521D3912A2A030258ED841F28BD56BF27A3543756DEA1BBD62A44E66D80B22D9B41045E6DB0AFA700156862E4D24F682327787A9E10BC63D2E5F303F19109E1E3BA661635E34BBDC98BA711DFF7F7710CF632D3DDAD5B3B2539B61A309AD1BA93A60A03F1ACF9F89A6B166EDBBBA0B8160993BEF2FE072E278CDACBA5BBE44D9D5F353158DC4AECABC6EF9E16CC7DB9E5D697D3B42E02B675FB800D91F7CE79F553C6B610320EEA13FC56E32AA678F +20241129001808 2 6 100 2047 2 CAA48956B64FC48DD5A4823E073002797519479815F1B8D4AAAB1748CB28F30774053A901B0A52BB700F0AFB1C23E06C63EEC4326CFA484724954492B3703B50C706447754E091B6F69DEF32413B230FBC521D3912A2A030258ED841F28BD56BF27A3543756DEA1BBD62A44E66D80B22D9B41045E6DB0AFA700156862E4D24F682327787A9E10BC63D2E5F303F19109E1E3BA661635E34BBDC98BA711DFF7F7710CF632D3DDAD5B3B2539B61A309AD1BA93A60A03F1ACF9F89A6B166EDBBBA0B8160993BEF2FE072E278CDACBA5BBE44D9D5F353158DC4AECABC6EF9E16CC7DB9E5D697D3B42E02B675FB800D91F7CE79F553C6B610320EEA13FC56E32C4EBAB +20241129001813 2 6 100 2047 2 CAA48956B64FC48DD5A4823E073002797519479815F1B8D4AAAB1748CB28F30774053A901B0A52BB700F0AFB1C23E06C63EEC4326CFA484724954492B3703B50C706447754E091B6F69DEF32413B230FBC521D3912A2A030258ED841F28BD56BF27A3543756DEA1BBD62A44E66D80B22D9B41045E6DB0AFA700156862E4D24F682327787A9E10BC63D2E5F303F19109E1E3BA661635E34BBDC98BA711DFF7F7710CF632D3DDAD5B3B2539B61A309AD1BA93A60A03F1ACF9F89A6B166EDBBBA0B8160993BEF2FE072E278CDACBA5BBE44D9D5F353158DC4AECABC6EF9E16CC7DB9E5D697D3B42E02B675FB800D91F7CE79F553C6B610320EEA13FC56E32EB8EAB +20241129001817 2 6 100 2047 2 CAA48956B64FC48DD5A4823E073002797519479815F1B8D4AAAB1748CB28F30774053A901B0A52BB700F0AFB1C23E06C63EEC4326CFA484724954492B3703B50C706447754E091B6F69DEF32413B230FBC521D3912A2A030258ED841F28BD56BF27A3543756DEA1BBD62A44E66D80B22D9B41045E6DB0AFA700156862E4D24F682327787A9E10BC63D2E5F303F19109E1E3BA661635E34BBDC98BA711DFF7F7710CF632D3DDAD5B3B2539B61A309AD1BA93A60A03F1ACF9F89A6B166EDBBBA0B8160993BEF2FE072E278CDACBA5BBE44D9D5F353158DC4AECABC6EF9E16CC7DB9E5D697D3B42E02B675FB800D91F7CE79F553C6B610320EEA13FC56E3308D17B +20241129001819 2 6 100 2047 5 CAA48956B64FC48DD5A4823E073002797519479815F1B8D4AAAB1748CB28F30774053A901B0A52BB700F0AFB1C23E06C63EEC4326CFA484724954492B3703B50C706447754E091B6F69DEF32413B230FBC521D3912A2A030258ED841F28BD56BF27A3543756DEA1BBD62A44E66D80B22D9B41045E6DB0AFA700156862E4D24F682327787A9E10BC63D2E5F303F19109E1E3BA661635E34BBDC98BA711DFF7F7710CF632D3DDAD5B3B2539B61A309AD1BA93A60A03F1ACF9F89A6B166EDBBBA0B8160993BEF2FE072E278CDACBA5BBE44D9D5F353158DC4AECABC6EF9E16CC7DB9E5D697D3B42E02B675FB800D91F7CE79F553C6B610320EEA13FC56E330EB1EF +20241129001825 2 6 100 2047 2 CAA48956B64FC48DD5A4823E073002797519479815F1B8D4AAAB1748CB28F30774053A901B0A52BB700F0AFB1C23E06C63EEC4326CFA484724954492B3703B50C706447754E091B6F69DEF32413B230FBC521D3912A2A030258ED841F28BD56BF27A3543756DEA1BBD62A44E66D80B22D9B41045E6DB0AFA700156862E4D24F682327787A9E10BC63D2E5F303F19109E1E3BA661635E34BBDC98BA711DFF7F7710CF632D3DDAD5B3B2539B61A309AD1BA93A60A03F1ACF9F89A6B166EDBBBA0B8160993BEF2FE072E278CDACBA5BBE44D9D5F353158DC4AECABC6EF9E16CC7DB9E5D697D3B42E02B675FB800D91F7CE79F553C6B610320EEA13FC56E333E0923 +20241129001832 2 6 100 2047 2 CAA48956B64FC48DD5A4823E073002797519479815F1B8D4AAAB1748CB28F30774053A901B0A52BB700F0AFB1C23E06C63EEC4326CFA484724954492B3703B50C706447754E091B6F69DEF32413B230FBC521D3912A2A030258ED841F28BD56BF27A3543756DEA1BBD62A44E66D80B22D9B41045E6DB0AFA700156862E4D24F682327787A9E10BC63D2E5F303F19109E1E3BA661635E34BBDC98BA711DFF7F7710CF632D3DDAD5B3B2539B61A309AD1BA93A60A03F1ACF9F89A6B166EDBBBA0B8160993BEF2FE072E278CDACBA5BBE44D9D5F353158DC4AECABC6EF9E16CC7DB9E5D697D3B42E02B675FB800D91F7CE79F553C6B610320EEA13FC56E3370EFD3 +20241129001904 2 6 100 2047 2 CAA48956B64FC48DD5A4823E073002797519479815F1B8D4AAAB1748CB28F30774053A901B0A52BB700F0AFB1C23E06C63EEC4326CFA484724954492B3703B50C706447754E091B6F69DEF32413B230FBC521D3912A2A030258ED841F28BD56BF27A3543756DEA1BBD62A44E66D80B22D9B41045E6DB0AFA700156862E4D24F682327787A9E10BC63D2E5F303F19109E1E3BA661635E34BBDC98BA711DFF7F7710CF632D3DDAD5B3B2539B61A309AD1BA93A60A03F1ACF9F89A6B166EDBBBA0B8160993BEF2FE072E278CDACBA5BBE44D9D5F353158DC4AECABC6EF9E16CC7DB9E5D697D3B42E02B675FB800D91F7CE79F553C6B610320EEA13FC56E3471A693 +20241129001908 2 6 100 2047 2 CAA48956B64FC48DD5A4823E073002797519479815F1B8D4AAAB1748CB28F30774053A901B0A52BB700F0AFB1C23E06C63EEC4326CFA484724954492B3703B50C706447754E091B6F69DEF32413B230FBC521D3912A2A030258ED841F28BD56BF27A3543756DEA1BBD62A44E66D80B22D9B41045E6DB0AFA700156862E4D24F682327787A9E10BC63D2E5F303F19109E1E3BA661635E34BBDC98BA711DFF7F7710CF632D3DDAD5B3B2539B61A309AD1BA93A60A03F1ACF9F89A6B166EDBBBA0B8160993BEF2FE072E278CDACBA5BBE44D9D5F353158DC4AECABC6EF9E16CC7DB9E5D697D3B42E02B675FB800D91F7CE79F553C6B610320EEA13FC56E348736C3 +20241129001923 2 6 100 2047 2 CAA48956B64FC48DD5A4823E073002797519479815F1B8D4AAAB1748CB28F30774053A901B0A52BB700F0AFB1C23E06C63EEC4326CFA484724954492B3703B50C706447754E091B6F69DEF32413B230FBC521D3912A2A030258ED841F28BD56BF27A3543756DEA1BBD62A44E66D80B22D9B41045E6DB0AFA700156862E4D24F682327787A9E10BC63D2E5F303F19109E1E3BA661635E34BBDC98BA711DFF7F7710CF632D3DDAD5B3B2539B61A309AD1BA93A60A03F1ACF9F89A6B166EDBBBA0B8160993BEF2FE072E278CDACBA5BBE44D9D5F353158DC4AECABC6EF9E16CC7DB9E5D697D3B42E02B675FB800D91F7CE79F553C6B610320EEA13FC56E35021F83 +20241129001930 2 6 100 2047 2 CAA48956B64FC48DD5A4823E073002797519479815F1B8D4AAAB1748CB28F30774053A901B0A52BB700F0AFB1C23E06C63EEC4326CFA484724954492B3703B50C706447754E091B6F69DEF32413B230FBC521D3912A2A030258ED841F28BD56BF27A3543756DEA1BBD62A44E66D80B22D9B41045E6DB0AFA700156862E4D24F682327787A9E10BC63D2E5F303F19109E1E3BA661635E34BBDC98BA711DFF7F7710CF632D3DDAD5B3B2539B61A309AD1BA93A60A03F1ACF9F89A6B166EDBBBA0B8160993BEF2FE072E278CDACBA5BBE44D9D5F353158DC4AECABC6EF9E16CC7DB9E5D697D3B42E02B675FB800D91F7CE79F553C6B610320EEA13FC56E352FB613 +20241129001942 2 6 100 2047 2 CAA48956B64FC48DD5A4823E073002797519479815F1B8D4AAAB1748CB28F30774053A901B0A52BB700F0AFB1C23E06C63EEC4326CFA484724954492B3703B50C706447754E091B6F69DEF32413B230FBC521D3912A2A030258ED841F28BD56BF27A3543756DEA1BBD62A44E66D80B22D9B41045E6DB0AFA700156862E4D24F682327787A9E10BC63D2E5F303F19109E1E3BA661635E34BBDC98BA711DFF7F7710CF632D3DDAD5B3B2539B61A309AD1BA93A60A03F1ACF9F89A6B166EDBBBA0B8160993BEF2FE072E278CDACBA5BBE44D9D5F353158DC4AECABC6EF9E16CC7DB9E5D697D3B42E02B675FB800D91F7CE79F553C6B610320EEA13FC56E3591257B +20241129001946 2 6 100 2047 2 CAA48956B64FC48DD5A4823E073002797519479815F1B8D4AAAB1748CB28F30774053A901B0A52BB700F0AFB1C23E06C63EEC4326CFA484724954492B3703B50C706447754E091B6F69DEF32413B230FBC521D3912A2A030258ED841F28BD56BF27A3543756DEA1BBD62A44E66D80B22D9B41045E6DB0AFA700156862E4D24F682327787A9E10BC63D2E5F303F19109E1E3BA661635E34BBDC98BA711DFF7F7710CF632D3DDAD5B3B2539B61A309AD1BA93A60A03F1ACF9F89A6B166EDBBBA0B8160993BEF2FE072E278CDACBA5BBE44D9D5F353158DC4AECABC6EF9E16CC7DB9E5D697D3B42E02B675FB800D91F7CE79F553C6B610320EEA13FC56E35AB042B +20241129001947 2 6 100 2047 2 CAA48956B64FC48DD5A4823E073002797519479815F1B8D4AAAB1748CB28F30774053A901B0A52BB700F0AFB1C23E06C63EEC4326CFA484724954492B3703B50C706447754E091B6F69DEF32413B230FBC521D3912A2A030258ED841F28BD56BF27A3543756DEA1BBD62A44E66D80B22D9B41045E6DB0AFA700156862E4D24F682327787A9E10BC63D2E5F303F19109E1E3BA661635E34BBDC98BA711DFF7F7710CF632D3DDAD5B3B2539B61A309AD1BA93A60A03F1ACF9F89A6B166EDBBBA0B8160993BEF2FE072E278CDACBA5BBE44D9D5F353158DC4AECABC6EF9E16CC7DB9E5D697D3B42E02B675FB800D91F7CE79F553C6B610320EEA13FC56E35B082CB +20241129002012 2 6 100 2047 2 CAA48956B64FC48DD5A4823E073002797519479815F1B8D4AAAB1748CB28F30774053A901B0A52BB700F0AFB1C23E06C63EEC4326CFA484724954492B3703B50C706447754E091B6F69DEF32413B230FBC521D3912A2A030258ED841F28BD56BF27A3543756DEA1BBD62A44E66D80B22D9B41045E6DB0AFA700156862E4D24F682327787A9E10BC63D2E5F303F19109E1E3BA661635E34BBDC98BA711DFF7F7710CF632D3DDAD5B3B2539B61A309AD1BA93A60A03F1ACF9F89A6B166EDBBBA0B8160993BEF2FE072E278CDACBA5BBE44D9D5F353158DC4AECABC6EF9E16CC7DB9E5D697D3B42E02B675FB800D91F7CE79F553C6B610320EEA13FC56E36777D7B +20241129002017 2 6 100 2047 2 CAA48956B64FC48DD5A4823E073002797519479815F1B8D4AAAB1748CB28F30774053A901B0A52BB700F0AFB1C23E06C63EEC4326CFA484724954492B3703B50C706447754E091B6F69DEF32413B230FBC521D3912A2A030258ED841F28BD56BF27A3543756DEA1BBD62A44E66D80B22D9B41045E6DB0AFA700156862E4D24F682327787A9E10BC63D2E5F303F19109E1E3BA661635E34BBDC98BA711DFF7F7710CF632D3DDAD5B3B2539B61A309AD1BA93A60A03F1ACF9F89A6B166EDBBBA0B8160993BEF2FE072E278CDACBA5BBE44D9D5F353158DC4AECABC6EF9E16CC7DB9E5D697D3B42E02B675FB800D91F7CE79F553C6B610320EEA13FC56E3697886B +20241129002030 2 6 100 2047 2 CAA48956B64FC48DD5A4823E073002797519479815F1B8D4AAAB1748CB28F30774053A901B0A52BB700F0AFB1C23E06C63EEC4326CFA484724954492B3703B50C706447754E091B6F69DEF32413B230FBC521D3912A2A030258ED841F28BD56BF27A3543756DEA1BBD62A44E66D80B22D9B41045E6DB0AFA700156862E4D24F682327787A9E10BC63D2E5F303F19109E1E3BA661635E34BBDC98BA711DFF7F7710CF632D3DDAD5B3B2539B61A309AD1BA93A60A03F1ACF9F89A6B166EDBBBA0B8160993BEF2FE072E278CDACBA5BBE44D9D5F353158DC4AECABC6EF9E16CC7DB9E5D697D3B42E02B675FB800D91F7CE79F553C6B610320EEA13FC56E36F5B2EB +20241129002036 2 6 100 2047 2 CAA48956B64FC48DD5A4823E073002797519479815F1B8D4AAAB1748CB28F30774053A901B0A52BB700F0AFB1C23E06C63EEC4326CFA484724954492B3703B50C706447754E091B6F69DEF32413B230FBC521D3912A2A030258ED841F28BD56BF27A3543756DEA1BBD62A44E66D80B22D9B41045E6DB0AFA700156862E4D24F682327787A9E10BC63D2E5F303F19109E1E3BA661635E34BBDC98BA711DFF7F7710CF632D3DDAD5B3B2539B61A309AD1BA93A60A03F1ACF9F89A6B166EDBBBA0B8160993BEF2FE072E278CDACBA5BBE44D9D5F353158DC4AECABC6EF9E16CC7DB9E5D697D3B42E02B675FB800D91F7CE79F553C6B610320EEA13FC56E37249BD3 +20241129002045 2 6 100 2047 2 CAA48956B64FC48DD5A4823E073002797519479815F1B8D4AAAB1748CB28F30774053A901B0A52BB700F0AFB1C23E06C63EEC4326CFA484724954492B3703B50C706447754E091B6F69DEF32413B230FBC521D3912A2A030258ED841F28BD56BF27A3543756DEA1BBD62A44E66D80B22D9B41045E6DB0AFA700156862E4D24F682327787A9E10BC63D2E5F303F19109E1E3BA661635E34BBDC98BA711DFF7F7710CF632D3DDAD5B3B2539B61A309AD1BA93A60A03F1ACF9F89A6B166EDBBBA0B8160993BEF2FE072E278CDACBA5BBE44D9D5F353158DC4AECABC6EF9E16CC7DB9E5D697D3B42E02B675FB800D91F7CE79F553C6B610320EEA13FC56E3769C1B3 +20241129002059 2 6 100 2047 5 CAA48956B64FC48DD5A4823E073002797519479815F1B8D4AAAB1748CB28F30774053A901B0A52BB700F0AFB1C23E06C63EEC4326CFA484724954492B3703B50C706447754E091B6F69DEF32413B230FBC521D3912A2A030258ED841F28BD56BF27A3543756DEA1BBD62A44E66D80B22D9B41045E6DB0AFA700156862E4D24F682327787A9E10BC63D2E5F303F19109E1E3BA661635E34BBDC98BA711DFF7F7710CF632D3DDAD5B3B2539B61A309AD1BA93A60A03F1ACF9F89A6B166EDBBBA0B8160993BEF2FE072E278CDACBA5BBE44D9D5F353158DC4AECABC6EF9E16CC7DB9E5D697D3B42E02B675FB800D91F7CE79F553C6B610320EEA13FC56E37D6FDAF +20241129002102 2 6 100 2047 2 CAA48956B64FC48DD5A4823E073002797519479815F1B8D4AAAB1748CB28F30774053A901B0A52BB700F0AFB1C23E06C63EEC4326CFA484724954492B3703B50C706447754E091B6F69DEF32413B230FBC521D3912A2A030258ED841F28BD56BF27A3543756DEA1BBD62A44E66D80B22D9B41045E6DB0AFA700156862E4D24F682327787A9E10BC63D2E5F303F19109E1E3BA661635E34BBDC98BA711DFF7F7710CF632D3DDAD5B3B2539B61A309AD1BA93A60A03F1ACF9F89A6B166EDBBBA0B8160993BEF2FE072E278CDACBA5BBE44D9D5F353158DC4AECABC6EF9E16CC7DB9E5D697D3B42E02B675FB800D91F7CE79F553C6B610320EEA13FC56E37EDB2E3 +20241129002105 2 6 100 2047 5 CAA48956B64FC48DD5A4823E073002797519479815F1B8D4AAAB1748CB28F30774053A901B0A52BB700F0AFB1C23E06C63EEC4326CFA484724954492B3703B50C706447754E091B6F69DEF32413B230FBC521D3912A2A030258ED841F28BD56BF27A3543756DEA1BBD62A44E66D80B22D9B41045E6DB0AFA700156862E4D24F682327787A9E10BC63D2E5F303F19109E1E3BA661635E34BBDC98BA711DFF7F7710CF632D3DDAD5B3B2539B61A309AD1BA93A60A03F1ACF9F89A6B166EDBBBA0B8160993BEF2FE072E278CDACBA5BBE44D9D5F353158DC4AECABC6EF9E16CC7DB9E5D697D3B42E02B675FB800D91F7CE79F553C6B610320EEA13FC56E37FA449F +20241129002109 2 6 100 2047 5 CAA48956B64FC48DD5A4823E073002797519479815F1B8D4AAAB1748CB28F30774053A901B0A52BB700F0AFB1C23E06C63EEC4326CFA484724954492B3703B50C706447754E091B6F69DEF32413B230FBC521D3912A2A030258ED841F28BD56BF27A3543756DEA1BBD62A44E66D80B22D9B41045E6DB0AFA700156862E4D24F682327787A9E10BC63D2E5F303F19109E1E3BA661635E34BBDC98BA711DFF7F7710CF632D3DDAD5B3B2539B61A309AD1BA93A60A03F1ACF9F89A6B166EDBBBA0B8160993BEF2FE072E278CDACBA5BBE44D9D5F353158DC4AECABC6EF9E16CC7DB9E5D697D3B42E02B675FB800D91F7CE79F553C6B610320EEA13FC56E381694E7 +20241129002127 2 6 100 2047 5 CAA48956B64FC48DD5A4823E073002797519479815F1B8D4AAAB1748CB28F30774053A901B0A52BB700F0AFB1C23E06C63EEC4326CFA484724954492B3703B50C706447754E091B6F69DEF32413B230FBC521D3912A2A030258ED841F28BD56BF27A3543756DEA1BBD62A44E66D80B22D9B41045E6DB0AFA700156862E4D24F682327787A9E10BC63D2E5F303F19109E1E3BA661635E34BBDC98BA711DFF7F7710CF632D3DDAD5B3B2539B61A309AD1BA93A60A03F1ACF9F89A6B166EDBBBA0B8160993BEF2FE072E278CDACBA5BBE44D9D5F353158DC4AECABC6EF9E16CC7DB9E5D697D3B42E02B675FB800D91F7CE79F553C6B610320EEA13FC56E38A56437 +20241129002141 2 6 100 2047 2 CAA48956B64FC48DD5A4823E073002797519479815F1B8D4AAAB1748CB28F30774053A901B0A52BB700F0AFB1C23E06C63EEC4326CFA484724954492B3703B50C706447754E091B6F69DEF32413B230FBC521D3912A2A030258ED841F28BD56BF27A3543756DEA1BBD62A44E66D80B22D9B41045E6DB0AFA700156862E4D24F682327787A9E10BC63D2E5F303F19109E1E3BA661635E34BBDC98BA711DFF7F7710CF632D3DDAD5B3B2539B61A309AD1BA93A60A03F1ACF9F89A6B166EDBBBA0B8160993BEF2FE072E278CDACBA5BBE44D9D5F353158DC4AECABC6EF9E16CC7DB9E5D697D3B42E02B675FB800D91F7CE79F553C6B610320EEA13FC56E391852F3 +20241129002144 2 6 100 2047 5 CAA48956B64FC48DD5A4823E073002797519479815F1B8D4AAAB1748CB28F30774053A901B0A52BB700F0AFB1C23E06C63EEC4326CFA484724954492B3703B50C706447754E091B6F69DEF32413B230FBC521D3912A2A030258ED841F28BD56BF27A3543756DEA1BBD62A44E66D80B22D9B41045E6DB0AFA700156862E4D24F682327787A9E10BC63D2E5F303F19109E1E3BA661635E34BBDC98BA711DFF7F7710CF632D3DDAD5B3B2539B61A309AD1BA93A60A03F1ACF9F89A6B166EDBBBA0B8160993BEF2FE072E278CDACBA5BBE44D9D5F353158DC4AECABC6EF9E16CC7DB9E5D697D3B42E02B675FB800D91F7CE79F553C6B610320EEA13FC56E3927ECD7 +20241129002150 2 6 100 2047 5 CAA48956B64FC48DD5A4823E073002797519479815F1B8D4AAAB1748CB28F30774053A901B0A52BB700F0AFB1C23E06C63EEC4326CFA484724954492B3703B50C706447754E091B6F69DEF32413B230FBC521D3912A2A030258ED841F28BD56BF27A3543756DEA1BBD62A44E66D80B22D9B41045E6DB0AFA700156862E4D24F682327787A9E10BC63D2E5F303F19109E1E3BA661635E34BBDC98BA711DFF7F7710CF632D3DDAD5B3B2539B61A309AD1BA93A60A03F1ACF9F89A6B166EDBBBA0B8160993BEF2FE072E278CDACBA5BBE44D9D5F353158DC4AECABC6EF9E16CC7DB9E5D697D3B42E02B675FB800D91F7CE79F553C6B610320EEA13FC56E3952495F +20241129002154 2 6 100 2047 2 CAA48956B64FC48DD5A4823E073002797519479815F1B8D4AAAB1748CB28F30774053A901B0A52BB700F0AFB1C23E06C63EEC4326CFA484724954492B3703B50C706447754E091B6F69DEF32413B230FBC521D3912A2A030258ED841F28BD56BF27A3543756DEA1BBD62A44E66D80B22D9B41045E6DB0AFA700156862E4D24F682327787A9E10BC63D2E5F303F19109E1E3BA661635E34BBDC98BA711DFF7F7710CF632D3DDAD5B3B2539B61A309AD1BA93A60A03F1ACF9F89A6B166EDBBBA0B8160993BEF2FE072E278CDACBA5BBE44D9D5F353158DC4AECABC6EF9E16CC7DB9E5D697D3B42E02B675FB800D91F7CE79F553C6B610320EEA13FC56E3971FEDB +20241129002226 2 6 100 2047 2 D62BDAF38E54FDFF0C708C3A9D5A49ADD950102DDCE4017B0B90CB32FE8736EE054C70F834E7196596829647330A22260674F15C124DFD61BD6304ED8DAA2BAF03E37A43714575DC4E50D30EB36E31B994DA55D6CCE62E854F087F56587D5C04E2907BF39AE275B9B5E0353A50453DA96E714E11E5A00F72680903B482731C04A0791B018B4FDB5D2EA1DE235C20CF300B0C1CED91A218390A09DF78C1877BB35E0D92D22ED647E32EA5C9F877B589B4A8F7F6685715AC5E0E5F93DB5671E028A9DFE1C66662C94A47C19FE0ED1B9C9BCBEA281F705C358F792091DE4A2F110B6B68E4AB15D6B30C59C8850D1E436BDDABADF17ED1E8881271CD1E7C8F34FC6B +20241129002249 2 6 100 2047 5 D62BDAF38E54FDFF0C708C3A9D5A49ADD950102DDCE4017B0B90CB32FE8736EE054C70F834E7196596829647330A22260674F15C124DFD61BD6304ED8DAA2BAF03E37A43714575DC4E50D30EB36E31B994DA55D6CCE62E854F087F56587D5C04E2907BF39AE275B9B5E0353A50453DA96E714E11E5A00F72680903B482731C04A0791B018B4FDB5D2EA1DE235C20CF300B0C1CED91A218390A09DF78C1877BB35E0D92D22ED647E32EA5C9F877B589B4A8F7F6685715AC5E0E5F93DB5671E028A9DFE1C66662C94A47C19FE0ED1B9C9BCBEA281F705C358F792091DE4A2F110B6B68E4AB15D6B30C59C8850D1E436BDDABADF17ED1E8881271CD1E7C8FE809EF +20241129002253 2 6 100 2047 2 D62BDAF38E54FDFF0C708C3A9D5A49ADD950102DDCE4017B0B90CB32FE8736EE054C70F834E7196596829647330A22260674F15C124DFD61BD6304ED8DAA2BAF03E37A43714575DC4E50D30EB36E31B994DA55D6CCE62E854F087F56587D5C04E2907BF39AE275B9B5E0353A50453DA96E714E11E5A00F72680903B482731C04A0791B018B4FDB5D2EA1DE235C20CF300B0C1CED91A218390A09DF78C1877BB35E0D92D22ED647E32EA5C9F877B589B4A8F7F6685715AC5E0E5F93DB5671E028A9DFE1C66662C94A47C19FE0ED1B9C9BCBEA281F705C358F792091DE4A2F110B6B68E4AB15D6B30C59C8850D1E436BDDABADF17ED1E8881271CD1E7C9008BDF3 +20241129002312 2 6 100 2047 2 D62BDAF38E54FDFF0C708C3A9D5A49ADD950102DDCE4017B0B90CB32FE8736EE054C70F834E7196596829647330A22260674F15C124DFD61BD6304ED8DAA2BAF03E37A43714575DC4E50D30EB36E31B994DA55D6CCE62E854F087F56587D5C04E2907BF39AE275B9B5E0353A50453DA96E714E11E5A00F72680903B482731C04A0791B018B4FDB5D2EA1DE235C20CF300B0C1CED91A218390A09DF78C1877BB35E0D92D22ED647E32EA5C9F877B589B4A8F7F6685715AC5E0E5F93DB5671E028A9DFE1C66662C94A47C19FE0ED1B9C9BCBEA281F705C358F792091DE4A2F110B6B68E4AB15D6B30C59C8850D1E436BDDABADF17ED1E8881271CD1E7C9099D883 +20241129002320 2 6 100 2047 2 D62BDAF38E54FDFF0C708C3A9D5A49ADD950102DDCE4017B0B90CB32FE8736EE054C70F834E7196596829647330A22260674F15C124DFD61BD6304ED8DAA2BAF03E37A43714575DC4E50D30EB36E31B994DA55D6CCE62E854F087F56587D5C04E2907BF39AE275B9B5E0353A50453DA96E714E11E5A00F72680903B482731C04A0791B018B4FDB5D2EA1DE235C20CF300B0C1CED91A218390A09DF78C1877BB35E0D92D22ED647E32EA5C9F877B589B4A8F7F6685715AC5E0E5F93DB5671E028A9DFE1C66662C94A47C19FE0ED1B9C9BCBEA281F705C358F792091DE4A2F110B6B68E4AB15D6B30C59C8850D1E436BDDABADF17ED1E8881271CD1E7C90D2E5BB +20241129002328 2 6 100 2047 5 D62BDAF38E54FDFF0C708C3A9D5A49ADD950102DDCE4017B0B90CB32FE8736EE054C70F834E7196596829647330A22260674F15C124DFD61BD6304ED8DAA2BAF03E37A43714575DC4E50D30EB36E31B994DA55D6CCE62E854F087F56587D5C04E2907BF39AE275B9B5E0353A50453DA96E714E11E5A00F72680903B482731C04A0791B018B4FDB5D2EA1DE235C20CF300B0C1CED91A218390A09DF78C1877BB35E0D92D22ED647E32EA5C9F877B589B4A8F7F6685715AC5E0E5F93DB5671E028A9DFE1C66662C94A47C19FE0ED1B9C9BCBEA281F705C358F792091DE4A2F110B6B68E4AB15D6B30C59C8850D1E436BDDABADF17ED1E8881271CD1E7C9111A1E7 +20241129002329 2 6 100 2047 5 D62BDAF38E54FDFF0C708C3A9D5A49ADD950102DDCE4017B0B90CB32FE8736EE054C70F834E7196596829647330A22260674F15C124DFD61BD6304ED8DAA2BAF03E37A43714575DC4E50D30EB36E31B994DA55D6CCE62E854F087F56587D5C04E2907BF39AE275B9B5E0353A50453DA96E714E11E5A00F72680903B482731C04A0791B018B4FDB5D2EA1DE235C20CF300B0C1CED91A218390A09DF78C1877BB35E0D92D22ED647E32EA5C9F877B589B4A8F7F6685715AC5E0E5F93DB5671E028A9DFE1C66662C94A47C19FE0ED1B9C9BCBEA281F705C358F792091DE4A2F110B6B68E4AB15D6B30C59C8850D1E436BDDABADF17ED1E8881271CD1E7C9113E88F +20241129002336 2 6 100 2047 2 D62BDAF38E54FDFF0C708C3A9D5A49ADD950102DDCE4017B0B90CB32FE8736EE054C70F834E7196596829647330A22260674F15C124DFD61BD6304ED8DAA2BAF03E37A43714575DC4E50D30EB36E31B994DA55D6CCE62E854F087F56587D5C04E2907BF39AE275B9B5E0353A50453DA96E714E11E5A00F72680903B482731C04A0791B018B4FDB5D2EA1DE235C20CF300B0C1CED91A218390A09DF78C1877BB35E0D92D22ED647E32EA5C9F877B589B4A8F7F6685715AC5E0E5F93DB5671E028A9DFE1C66662C94A47C19FE0ED1B9C9BCBEA281F705C358F792091DE4A2F110B6B68E4AB15D6B30C59C8850D1E436BDDABADF17ED1E8881271CD1E7C9148164B +20241129002339 2 6 100 2047 2 D62BDAF38E54FDFF0C708C3A9D5A49ADD950102DDCE4017B0B90CB32FE8736EE054C70F834E7196596829647330A22260674F15C124DFD61BD6304ED8DAA2BAF03E37A43714575DC4E50D30EB36E31B994DA55D6CCE62E854F087F56587D5C04E2907BF39AE275B9B5E0353A50453DA96E714E11E5A00F72680903B482731C04A0791B018B4FDB5D2EA1DE235C20CF300B0C1CED91A218390A09DF78C1877BB35E0D92D22ED647E32EA5C9F877B589B4A8F7F6685715AC5E0E5F93DB5671E028A9DFE1C66662C94A47C19FE0ED1B9C9BCBEA281F705C358F792091DE4A2F110B6B68E4AB15D6B30C59C8850D1E436BDDABADF17ED1E8881271CD1E7C915E0DCB +20241129002340 2 6 100 2047 2 D62BDAF38E54FDFF0C708C3A9D5A49ADD950102DDCE4017B0B90CB32FE8736EE054C70F834E7196596829647330A22260674F15C124DFD61BD6304ED8DAA2BAF03E37A43714575DC4E50D30EB36E31B994DA55D6CCE62E854F087F56587D5C04E2907BF39AE275B9B5E0353A50453DA96E714E11E5A00F72680903B482731C04A0791B018B4FDB5D2EA1DE235C20CF300B0C1CED91A218390A09DF78C1877BB35E0D92D22ED647E32EA5C9F877B589B4A8F7F6685715AC5E0E5F93DB5671E028A9DFE1C66662C94A47C19FE0ED1B9C9BCBEA281F705C358F792091DE4A2F110B6B68E4AB15D6B30C59C8850D1E436BDDABADF17ED1E8881271CD1E7C915EB103 +20241129002420 2 6 100 2047 5 D62BDAF38E54FDFF0C708C3A9D5A49ADD950102DDCE4017B0B90CB32FE8736EE054C70F834E7196596829647330A22260674F15C124DFD61BD6304ED8DAA2BAF03E37A43714575DC4E50D30EB36E31B994DA55D6CCE62E854F087F56587D5C04E2907BF39AE275B9B5E0353A50453DA96E714E11E5A00F72680903B482731C04A0791B018B4FDB5D2EA1DE235C20CF300B0C1CED91A218390A09DF78C1877BB35E0D92D22ED647E32EA5C9F877B589B4A8F7F6685715AC5E0E5F93DB5671E028A9DFE1C66662C94A47C19FE0ED1B9C9BCBEA281F705C358F792091DE4A2F110B6B68E4AB15D6B30C59C8850D1E436BDDABADF17ED1E8881271CD1E7C92A19C97 +20241129002428 2 6 100 2047 5 D62BDAF38E54FDFF0C708C3A9D5A49ADD950102DDCE4017B0B90CB32FE8736EE054C70F834E7196596829647330A22260674F15C124DFD61BD6304ED8DAA2BAF03E37A43714575DC4E50D30EB36E31B994DA55D6CCE62E854F087F56587D5C04E2907BF39AE275B9B5E0353A50453DA96E714E11E5A00F72680903B482731C04A0791B018B4FDB5D2EA1DE235C20CF300B0C1CED91A218390A09DF78C1877BB35E0D92D22ED647E32EA5C9F877B589B4A8F7F6685715AC5E0E5F93DB5671E028A9DFE1C66662C94A47C19FE0ED1B9C9BCBEA281F705C358F792091DE4A2F110B6B68E4AB15D6B30C59C8850D1E436BDDABADF17ED1E8881271CD1E7C92E090AF +20241129002433 2 6 100 2047 2 D62BDAF38E54FDFF0C708C3A9D5A49ADD950102DDCE4017B0B90CB32FE8736EE054C70F834E7196596829647330A22260674F15C124DFD61BD6304ED8DAA2BAF03E37A43714575DC4E50D30EB36E31B994DA55D6CCE62E854F087F56587D5C04E2907BF39AE275B9B5E0353A50453DA96E714E11E5A00F72680903B482731C04A0791B018B4FDB5D2EA1DE235C20CF300B0C1CED91A218390A09DF78C1877BB35E0D92D22ED647E32EA5C9F877B589B4A8F7F6685715AC5E0E5F93DB5671E028A9DFE1C66662C94A47C19FE0ED1B9C9BCBEA281F705C358F792091DE4A2F110B6B68E4AB15D6B30C59C8850D1E436BDDABADF17ED1E8881271CD1E7C93040BCB +20241129002434 2 6 100 2047 2 D62BDAF38E54FDFF0C708C3A9D5A49ADD950102DDCE4017B0B90CB32FE8736EE054C70F834E7196596829647330A22260674F15C124DFD61BD6304ED8DAA2BAF03E37A43714575DC4E50D30EB36E31B994DA55D6CCE62E854F087F56587D5C04E2907BF39AE275B9B5E0353A50453DA96E714E11E5A00F72680903B482731C04A0791B018B4FDB5D2EA1DE235C20CF300B0C1CED91A218390A09DF78C1877BB35E0D92D22ED647E32EA5C9F877B589B4A8F7F6685715AC5E0E5F93DB5671E028A9DFE1C66662C94A47C19FE0ED1B9C9BCBEA281F705C358F792091DE4A2F110B6B68E4AB15D6B30C59C8850D1E436BDDABADF17ED1E8881271CD1E7C930B22CB +20241129002436 2 6 100 2047 2 D62BDAF38E54FDFF0C708C3A9D5A49ADD950102DDCE4017B0B90CB32FE8736EE054C70F834E7196596829647330A22260674F15C124DFD61BD6304ED8DAA2BAF03E37A43714575DC4E50D30EB36E31B994DA55D6CCE62E854F087F56587D5C04E2907BF39AE275B9B5E0353A50453DA96E714E11E5A00F72680903B482731C04A0791B018B4FDB5D2EA1DE235C20CF300B0C1CED91A218390A09DF78C1877BB35E0D92D22ED647E32EA5C9F877B589B4A8F7F6685715AC5E0E5F93DB5671E028A9DFE1C66662C94A47C19FE0ED1B9C9BCBEA281F705C358F792091DE4A2F110B6B68E4AB15D6B30C59C8850D1E436BDDABADF17ED1E8881271CD1E7C931188B3 +20241129002446 2 6 100 2047 5 D62BDAF38E54FDFF0C708C3A9D5A49ADD950102DDCE4017B0B90CB32FE8736EE054C70F834E7196596829647330A22260674F15C124DFD61BD6304ED8DAA2BAF03E37A43714575DC4E50D30EB36E31B994DA55D6CCE62E854F087F56587D5C04E2907BF39AE275B9B5E0353A50453DA96E714E11E5A00F72680903B482731C04A0791B018B4FDB5D2EA1DE235C20CF300B0C1CED91A218390A09DF78C1877BB35E0D92D22ED647E32EA5C9F877B589B4A8F7F6685715AC5E0E5F93DB5671E028A9DFE1C66662C94A47C19FE0ED1B9C9BCBEA281F705C358F792091DE4A2F110B6B68E4AB15D6B30C59C8850D1E436BDDABADF17ED1E8881271CD1E7C935DB5F7 +20241129002507 2 6 100 2047 2 D62BDAF38E54FDFF0C708C3A9D5A49ADD950102DDCE4017B0B90CB32FE8736EE054C70F834E7196596829647330A22260674F15C124DFD61BD6304ED8DAA2BAF03E37A43714575DC4E50D30EB36E31B994DA55D6CCE62E854F087F56587D5C04E2907BF39AE275B9B5E0353A50453DA96E714E11E5A00F72680903B482731C04A0791B018B4FDB5D2EA1DE235C20CF300B0C1CED91A218390A09DF78C1877BB35E0D92D22ED647E32EA5C9F877B589B4A8F7F6685715AC5E0E5F93DB5671E028A9DFE1C66662C94A47C19FE0ED1B9C9BCBEA281F705C358F792091DE4A2F110B6B68E4AB15D6B30C59C8850D1E436BDDABADF17ED1E8881271CD1E7C9408C96B +20241129002510 2 6 100 2047 2 D62BDAF38E54FDFF0C708C3A9D5A49ADD950102DDCE4017B0B90CB32FE8736EE054C70F834E7196596829647330A22260674F15C124DFD61BD6304ED8DAA2BAF03E37A43714575DC4E50D30EB36E31B994DA55D6CCE62E854F087F56587D5C04E2907BF39AE275B9B5E0353A50453DA96E714E11E5A00F72680903B482731C04A0791B018B4FDB5D2EA1DE235C20CF300B0C1CED91A218390A09DF78C1877BB35E0D92D22ED647E32EA5C9F877B589B4A8F7F6685715AC5E0E5F93DB5671E028A9DFE1C66662C94A47C19FE0ED1B9C9BCBEA281F705C358F792091DE4A2F110B6B68E4AB15D6B30C59C8850D1E436BDDABADF17ED1E8881271CD1E7C941D429B +20241129002527 2 6 100 2047 2 D62BDAF38E54FDFF0C708C3A9D5A49ADD950102DDCE4017B0B90CB32FE8736EE054C70F834E7196596829647330A22260674F15C124DFD61BD6304ED8DAA2BAF03E37A43714575DC4E50D30EB36E31B994DA55D6CCE62E854F087F56587D5C04E2907BF39AE275B9B5E0353A50453DA96E714E11E5A00F72680903B482731C04A0791B018B4FDB5D2EA1DE235C20CF300B0C1CED91A218390A09DF78C1877BB35E0D92D22ED647E32EA5C9F877B589B4A8F7F6685715AC5E0E5F93DB5671E028A9DFE1C66662C94A47C19FE0ED1B9C9BCBEA281F705C358F792091DE4A2F110B6B68E4AB15D6B30C59C8850D1E436BDDABADF17ED1E8881271CD1E7C94A15E73 +20241129002528 2 6 100 2047 5 D62BDAF38E54FDFF0C708C3A9D5A49ADD950102DDCE4017B0B90CB32FE8736EE054C70F834E7196596829647330A22260674F15C124DFD61BD6304ED8DAA2BAF03E37A43714575DC4E50D30EB36E31B994DA55D6CCE62E854F087F56587D5C04E2907BF39AE275B9B5E0353A50453DA96E714E11E5A00F72680903B482731C04A0791B018B4FDB5D2EA1DE235C20CF300B0C1CED91A218390A09DF78C1877BB35E0D92D22ED647E32EA5C9F877B589B4A8F7F6685715AC5E0E5F93DB5671E028A9DFE1C66662C94A47C19FE0ED1B9C9BCBEA281F705C358F792091DE4A2F110B6B68E4AB15D6B30C59C8850D1E436BDDABADF17ED1E8881271CD1E7C94AA3DAF +20241129002531 2 6 100 2047 5 D62BDAF38E54FDFF0C708C3A9D5A49ADD950102DDCE4017B0B90CB32FE8736EE054C70F834E7196596829647330A22260674F15C124DFD61BD6304ED8DAA2BAF03E37A43714575DC4E50D30EB36E31B994DA55D6CCE62E854F087F56587D5C04E2907BF39AE275B9B5E0353A50453DA96E714E11E5A00F72680903B482731C04A0791B018B4FDB5D2EA1DE235C20CF300B0C1CED91A218390A09DF78C1877BB35E0D92D22ED647E32EA5C9F877B589B4A8F7F6685715AC5E0E5F93DB5671E028A9DFE1C66662C94A47C19FE0ED1B9C9BCBEA281F705C358F792091DE4A2F110B6B68E4AB15D6B30C59C8850D1E436BDDABADF17ED1E8881271CD1E7C94BA0ED7 +20241129002538 2 6 100 2047 5 D62BDAF38E54FDFF0C708C3A9D5A49ADD950102DDCE4017B0B90CB32FE8736EE054C70F834E7196596829647330A22260674F15C124DFD61BD6304ED8DAA2BAF03E37A43714575DC4E50D30EB36E31B994DA55D6CCE62E854F087F56587D5C04E2907BF39AE275B9B5E0353A50453DA96E714E11E5A00F72680903B482731C04A0791B018B4FDB5D2EA1DE235C20CF300B0C1CED91A218390A09DF78C1877BB35E0D92D22ED647E32EA5C9F877B589B4A8F7F6685715AC5E0E5F93DB5671E028A9DFE1C66662C94A47C19FE0ED1B9C9BCBEA281F705C358F792091DE4A2F110B6B68E4AB15D6B30C59C8850D1E436BDDABADF17ED1E8881271CD1E7C94ECC017 +20241129002543 2 6 100 2047 5 D62BDAF38E54FDFF0C708C3A9D5A49ADD950102DDCE4017B0B90CB32FE8736EE054C70F834E7196596829647330A22260674F15C124DFD61BD6304ED8DAA2BAF03E37A43714575DC4E50D30EB36E31B994DA55D6CCE62E854F087F56587D5C04E2907BF39AE275B9B5E0353A50453DA96E714E11E5A00F72680903B482731C04A0791B018B4FDB5D2EA1DE235C20CF300B0C1CED91A218390A09DF78C1877BB35E0D92D22ED647E32EA5C9F877B589B4A8F7F6685715AC5E0E5F93DB5671E028A9DFE1C66662C94A47C19FE0ED1B9C9BCBEA281F705C358F792091DE4A2F110B6B68E4AB15D6B30C59C8850D1E436BDDABADF17ED1E8881271CD1E7C9511A1BF +20241129002558 2 6 100 2047 5 D62BDAF38E54FDFF0C708C3A9D5A49ADD950102DDCE4017B0B90CB32FE8736EE054C70F834E7196596829647330A22260674F15C124DFD61BD6304ED8DAA2BAF03E37A43714575DC4E50D30EB36E31B994DA55D6CCE62E854F087F56587D5C04E2907BF39AE275B9B5E0353A50453DA96E714E11E5A00F72680903B482731C04A0791B018B4FDB5D2EA1DE235C20CF300B0C1CED91A218390A09DF78C1877BB35E0D92D22ED647E32EA5C9F877B589B4A8F7F6685715AC5E0E5F93DB5671E028A9DFE1C66662C94A47C19FE0ED1B9C9BCBEA281F705C358F792091DE4A2F110B6B68E4AB15D6B30C59C8850D1E436BDDABADF17ED1E8881271CD1E7C95871257 +20241129002602 2 6 100 2047 2 D62BDAF38E54FDFF0C708C3A9D5A49ADD950102DDCE4017B0B90CB32FE8736EE054C70F834E7196596829647330A22260674F15C124DFD61BD6304ED8DAA2BAF03E37A43714575DC4E50D30EB36E31B994DA55D6CCE62E854F087F56587D5C04E2907BF39AE275B9B5E0353A50453DA96E714E11E5A00F72680903B482731C04A0791B018B4FDB5D2EA1DE235C20CF300B0C1CED91A218390A09DF78C1877BB35E0D92D22ED647E32EA5C9F877B589B4A8F7F6685715AC5E0E5F93DB5671E028A9DFE1C66662C94A47C19FE0ED1B9C9BCBEA281F705C358F792091DE4A2F110B6B68E4AB15D6B30C59C8850D1E436BDDABADF17ED1E8881271CD1E7C95A7B2AB +20241129002617 2 6 100 2047 2 D62BDAF38E54FDFF0C708C3A9D5A49ADD950102DDCE4017B0B90CB32FE8736EE054C70F834E7196596829647330A22260674F15C124DFD61BD6304ED8DAA2BAF03E37A43714575DC4E50D30EB36E31B994DA55D6CCE62E854F087F56587D5C04E2907BF39AE275B9B5E0353A50453DA96E714E11E5A00F72680903B482731C04A0791B018B4FDB5D2EA1DE235C20CF300B0C1CED91A218390A09DF78C1877BB35E0D92D22ED647E32EA5C9F877B589B4A8F7F6685715AC5E0E5F93DB5671E028A9DFE1C66662C94A47C19FE0ED1B9C9BCBEA281F705C358F792091DE4A2F110B6B68E4AB15D6B30C59C8850D1E436BDDABADF17ED1E8881271CD1E7C961AFC4B +20241129002644 2 6 100 2047 2 D62BDAF38E54FDFF0C708C3A9D5A49ADD950102DDCE4017B0B90CB32FE8736EE054C70F834E7196596829647330A22260674F15C124DFD61BD6304ED8DAA2BAF03E37A43714575DC4E50D30EB36E31B994DA55D6CCE62E854F087F56587D5C04E2907BF39AE275B9B5E0353A50453DA96E714E11E5A00F72680903B482731C04A0791B018B4FDB5D2EA1DE235C20CF300B0C1CED91A218390A09DF78C1877BB35E0D92D22ED647E32EA5C9F877B589B4A8F7F6685715AC5E0E5F93DB5671E028A9DFE1C66662C94A47C19FE0ED1B9C9BCBEA281F705C358F792091DE4A2F110B6B68E4AB15D6B30C59C8850D1E436BDDABADF17ED1E8881271CD1E7C96F5DDA3 +20241129002646 2 6 100 2047 5 D62BDAF38E54FDFF0C708C3A9D5A49ADD950102DDCE4017B0B90CB32FE8736EE054C70F834E7196596829647330A22260674F15C124DFD61BD6304ED8DAA2BAF03E37A43714575DC4E50D30EB36E31B994DA55D6CCE62E854F087F56587D5C04E2907BF39AE275B9B5E0353A50453DA96E714E11E5A00F72680903B482731C04A0791B018B4FDB5D2EA1DE235C20CF300B0C1CED91A218390A09DF78C1877BB35E0D92D22ED647E32EA5C9F877B589B4A8F7F6685715AC5E0E5F93DB5671E028A9DFE1C66662C94A47C19FE0ED1B9C9BCBEA281F705C358F792091DE4A2F110B6B68E4AB15D6B30C59C8850D1E436BDDABADF17ED1E8881271CD1E7C9701A557 +20241129003212 2 6 100 3071 5 C94F41FDB4E54DBDD1C7A49F586104E6D74F4CD07A2B9730A4FB5D40C24AB929C55B955144ADC62AEF2DF80D151E4F20E946F69C9B7AC7F01D1A916F3C1D23984DAF12A5CF18C5FDD9922AE0DBFFB31E9EAC765DCF315EBB0524E8B9246BC97169BE71440DF64D5884F63D9ECC8C96E312169E71BC1D25DCE1AE142F6C4D265BA36CBAAC0860E6C83C26B287461F4FE90C5D2CAF4A87937E12407CC632618086D75FB5A17ED87F8EEE71893A6890E74AA378BD6B91CD4CF264F0826110494D2492F6A45567AB8FF4C28142582D3E66E9D3961881DFA1877E2EC993E31A35017C8291B0C74BCF285F94BC6E8B5D0EDEE7F571BEDDEB32184688CB221D1E42A74657FE9AC83679E51B925D617069FF259975C40D370D0D51F18D1C17358B9C197B00893AEE90BA06517787E8C4884E783F2A4B7633C62E7843B743688FA6296F11A6F4D584C2905EADA2076D289449F5DB07E2788F021D435DD188563CDAA1C89B0E7E87017788634AF18CAD9ADB8BA18E80C5BD0BE1424FF9135B07DD31A6F92F +20241129003232 2 6 100 3071 2 C94F41FDB4E54DBDD1C7A49F586104E6D74F4CD07A2B9730A4FB5D40C24AB929C55B955144ADC62AEF2DF80D151E4F20E946F69C9B7AC7F01D1A916F3C1D23984DAF12A5CF18C5FDD9922AE0DBFFB31E9EAC765DCF315EBB0524E8B9246BC97169BE71440DF64D5884F63D9ECC8C96E312169E71BC1D25DCE1AE142F6C4D265BA36CBAAC0860E6C83C26B287461F4FE90C5D2CAF4A87937E12407CC632618086D75FB5A17ED87F8EEE71893A6890E74AA378BD6B91CD4CF264F0826110494D2492F6A45567AB8FF4C28142582D3E66E9D3961881DFA1877E2EC993E31A35017C8291B0C74BCF285F94BC6E8B5D0EDEE7F571BEDDEB32184688CB221D1E42A74657FE9AC83679E51B925D617069FF259975C40D370D0D51F18D1C17358B9C197B00893AEE90BA06517787E8C4884E783F2A4B7633C62E7843B743688FA6296F11A6F4D584C2905EADA2076D289449F5DB07E2788F021D435DD188563CDAA1C89B0E7E87017788634AF18CAD9ADB8BA18E80C5BD0BE1424FF9135B07DD31E1E02B +20241129003238 2 6 100 3071 5 C94F41FDB4E54DBDD1C7A49F586104E6D74F4CD07A2B9730A4FB5D40C24AB929C55B955144ADC62AEF2DF80D151E4F20E946F69C9B7AC7F01D1A916F3C1D23984DAF12A5CF18C5FDD9922AE0DBFFB31E9EAC765DCF315EBB0524E8B9246BC97169BE71440DF64D5884F63D9ECC8C96E312169E71BC1D25DCE1AE142F6C4D265BA36CBAAC0860E6C83C26B287461F4FE90C5D2CAF4A87937E12407CC632618086D75FB5A17ED87F8EEE71893A6890E74AA378BD6B91CD4CF264F0826110494D2492F6A45567AB8FF4C28142582D3E66E9D3961881DFA1877E2EC993E31A35017C8291B0C74BCF285F94BC6E8B5D0EDEE7F571BEDDEB32184688CB221D1E42A74657FE9AC83679E51B925D617069FF259975C40D370D0D51F18D1C17358B9C197B00893AEE90BA06517787E8C4884E783F2A4B7633C62E7843B743688FA6296F11A6F4D584C2905EADA2076D289449F5DB07E2788F021D435DD188563CDAA1C89B0E7E87017788634AF18CAD9ADB8BA18E80C5BD0BE1424FF9135B07DD31F02307 +20241129003247 2 6 100 3071 2 C94F41FDB4E54DBDD1C7A49F586104E6D74F4CD07A2B9730A4FB5D40C24AB929C55B955144ADC62AEF2DF80D151E4F20E946F69C9B7AC7F01D1A916F3C1D23984DAF12A5CF18C5FDD9922AE0DBFFB31E9EAC765DCF315EBB0524E8B9246BC97169BE71440DF64D5884F63D9ECC8C96E312169E71BC1D25DCE1AE142F6C4D265BA36CBAAC0860E6C83C26B287461F4FE90C5D2CAF4A87937E12407CC632618086D75FB5A17ED87F8EEE71893A6890E74AA378BD6B91CD4CF264F0826110494D2492F6A45567AB8FF4C28142582D3E66E9D3961881DFA1877E2EC993E31A35017C8291B0C74BCF285F94BC6E8B5D0EDEE7F571BEDDEB32184688CB221D1E42A74657FE9AC83679E51B925D617069FF259975C40D370D0D51F18D1C17358B9C197B00893AEE90BA06517787E8C4884E783F2A4B7633C62E7843B743688FA6296F11A6F4D584C2905EADA2076D289449F5DB07E2788F021D435DD188563CDAA1C89B0E7E87017788634AF18CAD9ADB8BA18E80C5BD0BE1424FF9135B07DD32089003 +20241129003331 2 6 100 3071 2 C94F41FDB4E54DBDD1C7A49F586104E6D74F4CD07A2B9730A4FB5D40C24AB929C55B955144ADC62AEF2DF80D151E4F20E946F69C9B7AC7F01D1A916F3C1D23984DAF12A5CF18C5FDD9922AE0DBFFB31E9EAC765DCF315EBB0524E8B9246BC97169BE71440DF64D5884F63D9ECC8C96E312169E71BC1D25DCE1AE142F6C4D265BA36CBAAC0860E6C83C26B287461F4FE90C5D2CAF4A87937E12407CC632618086D75FB5A17ED87F8EEE71893A6890E74AA378BD6B91CD4CF264F0826110494D2492F6A45567AB8FF4C28142582D3E66E9D3961881DFA1877E2EC993E31A35017C8291B0C74BCF285F94BC6E8B5D0EDEE7F571BEDDEB32184688CB221D1E42A74657FE9AC83679E51B925D617069FF259975C40D370D0D51F18D1C17358B9C197B00893AEE90BA06517787E8C4884E783F2A4B7633C62E7843B743688FA6296F11A6F4D584C2905EADA2076D289449F5DB07E2788F021D435DD188563CDAA1C89B0E7E87017788634AF18CAD9ADB8BA18E80C5BD0BE1424FF9135B07DD328EF3EB +20241129003450 2 6 100 3071 5 C94F41FDB4E54DBDD1C7A49F586104E6D74F4CD07A2B9730A4FB5D40C24AB929C55B955144ADC62AEF2DF80D151E4F20E946F69C9B7AC7F01D1A916F3C1D23984DAF12A5CF18C5FDD9922AE0DBFFB31E9EAC765DCF315EBB0524E8B9246BC97169BE71440DF64D5884F63D9ECC8C96E312169E71BC1D25DCE1AE142F6C4D265BA36CBAAC0860E6C83C26B287461F4FE90C5D2CAF4A87937E12407CC632618086D75FB5A17ED87F8EEE71893A6890E74AA378BD6B91CD4CF264F0826110494D2492F6A45567AB8FF4C28142582D3E66E9D3961881DFA1877E2EC993E31A35017C8291B0C74BCF285F94BC6E8B5D0EDEE7F571BEDDEB32184688CB221D1E42A74657FE9AC83679E51B925D617069FF259975C40D370D0D51F18D1C17358B9C197B00893AEE90BA06517787E8C4884E783F2A4B7633C62E7843B743688FA6296F11A6F4D584C2905EADA2076D289449F5DB07E2788F021D435DD188563CDAA1C89B0E7E87017788634AF18CAD9ADB8BA18E80C5BD0BE1424FF9135B07DD3388738F +20241129003549 2 6 100 3071 5 C94F41FDB4E54DBDD1C7A49F586104E6D74F4CD07A2B9730A4FB5D40C24AB929C55B955144ADC62AEF2DF80D151E4F20E946F69C9B7AC7F01D1A916F3C1D23984DAF12A5CF18C5FDD9922AE0DBFFB31E9EAC765DCF315EBB0524E8B9246BC97169BE71440DF64D5884F63D9ECC8C96E312169E71BC1D25DCE1AE142F6C4D265BA36CBAAC0860E6C83C26B287461F4FE90C5D2CAF4A87937E12407CC632618086D75FB5A17ED87F8EEE71893A6890E74AA378BD6B91CD4CF264F0826110494D2492F6A45567AB8FF4C28142582D3E66E9D3961881DFA1877E2EC993E31A35017C8291B0C74BCF285F94BC6E8B5D0EDEE7F571BEDDEB32184688CB221D1E42A74657FE9AC83679E51B925D617069FF259975C40D370D0D51F18D1C17358B9C197B00893AEE90BA06517787E8C4884E783F2A4B7633C62E7843B743688FA6296F11A6F4D584C2905EADA2076D289449F5DB07E2788F021D435DD188563CDAA1C89B0E7E87017788634AF18CAD9ADB8BA18E80C5BD0BE1424FF9135B07DD344433C7 +20241129003558 2 6 100 3071 2 C94F41FDB4E54DBDD1C7A49F586104E6D74F4CD07A2B9730A4FB5D40C24AB929C55B955144ADC62AEF2DF80D151E4F20E946F69C9B7AC7F01D1A916F3C1D23984DAF12A5CF18C5FDD9922AE0DBFFB31E9EAC765DCF315EBB0524E8B9246BC97169BE71440DF64D5884F63D9ECC8C96E312169E71BC1D25DCE1AE142F6C4D265BA36CBAAC0860E6C83C26B287461F4FE90C5D2CAF4A87937E12407CC632618086D75FB5A17ED87F8EEE71893A6890E74AA378BD6B91CD4CF264F0826110494D2492F6A45567AB8FF4C28142582D3E66E9D3961881DFA1877E2EC993E31A35017C8291B0C74BCF285F94BC6E8B5D0EDEE7F571BEDDEB32184688CB221D1E42A74657FE9AC83679E51B925D617069FF259975C40D370D0D51F18D1C17358B9C197B00893AEE90BA06517787E8C4884E783F2A4B7633C62E7843B743688FA6296F11A6F4D584C2905EADA2076D289449F5DB07E2788F021D435DD188563CDAA1C89B0E7E87017788634AF18CAD9ADB8BA18E80C5BD0BE1424FF9135B07DD345EB43B +20241129003708 2 6 100 3071 2 C94F41FDB4E54DBDD1C7A49F586104E6D74F4CD07A2B9730A4FB5D40C24AB929C55B955144ADC62AEF2DF80D151E4F20E946F69C9B7AC7F01D1A916F3C1D23984DAF12A5CF18C5FDD9922AE0DBFFB31E9EAC765DCF315EBB0524E8B9246BC97169BE71440DF64D5884F63D9ECC8C96E312169E71BC1D25DCE1AE142F6C4D265BA36CBAAC0860E6C83C26B287461F4FE90C5D2CAF4A87937E12407CC632618086D75FB5A17ED87F8EEE71893A6890E74AA378BD6B91CD4CF264F0826110494D2492F6A45567AB8FF4C28142582D3E66E9D3961881DFA1877E2EC993E31A35017C8291B0C74BCF285F94BC6E8B5D0EDEE7F571BEDDEB32184688CB221D1E42A74657FE9AC83679E51B925D617069FF259975C40D370D0D51F18D1C17358B9C197B00893AEE90BA06517787E8C4884E783F2A4B7633C62E7843B743688FA6296F11A6F4D584C2905EADA2076D289449F5DB07E2788F021D435DD188563CDAA1C89B0E7E87017788634AF18CAD9ADB8BA18E80C5BD0BE1424FF9135B07DD353F77AB +20241129003723 2 6 100 3071 5 C94F41FDB4E54DBDD1C7A49F586104E6D74F4CD07A2B9730A4FB5D40C24AB929C55B955144ADC62AEF2DF80D151E4F20E946F69C9B7AC7F01D1A916F3C1D23984DAF12A5CF18C5FDD9922AE0DBFFB31E9EAC765DCF315EBB0524E8B9246BC97169BE71440DF64D5884F63D9ECC8C96E312169E71BC1D25DCE1AE142F6C4D265BA36CBAAC0860E6C83C26B287461F4FE90C5D2CAF4A87937E12407CC632618086D75FB5A17ED87F8EEE71893A6890E74AA378BD6B91CD4CF264F0826110494D2492F6A45567AB8FF4C28142582D3E66E9D3961881DFA1877E2EC993E31A35017C8291B0C74BCF285F94BC6E8B5D0EDEE7F571BEDDEB32184688CB221D1E42A74657FE9AC83679E51B925D617069FF259975C40D370D0D51F18D1C17358B9C197B00893AEE90BA06517787E8C4884E783F2A4B7633C62E7843B743688FA6296F11A6F4D584C2905EADA2076D289449F5DB07E2788F021D435DD188563CDAA1C89B0E7E87017788634AF18CAD9ADB8BA18E80C5BD0BE1424FF9135B07DD356DF4FF +20241129003747 2 6 100 3071 2 C94F41FDB4E54DBDD1C7A49F586104E6D74F4CD07A2B9730A4FB5D40C24AB929C55B955144ADC62AEF2DF80D151E4F20E946F69C9B7AC7F01D1A916F3C1D23984DAF12A5CF18C5FDD9922AE0DBFFB31E9EAC765DCF315EBB0524E8B9246BC97169BE71440DF64D5884F63D9ECC8C96E312169E71BC1D25DCE1AE142F6C4D265BA36CBAAC0860E6C83C26B287461F4FE90C5D2CAF4A87937E12407CC632618086D75FB5A17ED87F8EEE71893A6890E74AA378BD6B91CD4CF264F0826110494D2492F6A45567AB8FF4C28142582D3E66E9D3961881DFA1877E2EC993E31A35017C8291B0C74BCF285F94BC6E8B5D0EDEE7F571BEDDEB32184688CB221D1E42A74657FE9AC83679E51B925D617069FF259975C40D370D0D51F18D1C17358B9C197B00893AEE90BA06517787E8C4884E783F2A4B7633C62E7843B743688FA6296F11A6F4D584C2905EADA2076D289449F5DB07E2788F021D435DD188563CDAA1C89B0E7E87017788634AF18CAD9ADB8BA18E80C5BD0BE1424FF9135B07DD35B352CB +20241129003812 2 6 100 3071 2 C94F41FDB4E54DBDD1C7A49F586104E6D74F4CD07A2B9730A4FB5D40C24AB929C55B955144ADC62AEF2DF80D151E4F20E946F69C9B7AC7F01D1A916F3C1D23984DAF12A5CF18C5FDD9922AE0DBFFB31E9EAC765DCF315EBB0524E8B9246BC97169BE71440DF64D5884F63D9ECC8C96E312169E71BC1D25DCE1AE142F6C4D265BA36CBAAC0860E6C83C26B287461F4FE90C5D2CAF4A87937E12407CC632618086D75FB5A17ED87F8EEE71893A6890E74AA378BD6B91CD4CF264F0826110494D2492F6A45567AB8FF4C28142582D3E66E9D3961881DFA1877E2EC993E31A35017C8291B0C74BCF285F94BC6E8B5D0EDEE7F571BEDDEB32184688CB221D1E42A74657FE9AC83679E51B925D617069FF259975C40D370D0D51F18D1C17358B9C197B00893AEE90BA06517787E8C4884E783F2A4B7633C62E7843B743688FA6296F11A6F4D584C2905EADA2076D289449F5DB07E2788F021D435DD188563CDAA1C89B0E7E87017788634AF18CAD9ADB8BA18E80C5BD0BE1424FF9135B07DD36020023 +20241129003842 2 6 100 3071 5 C94F41FDB4E54DBDD1C7A49F586104E6D74F4CD07A2B9730A4FB5D40C24AB929C55B955144ADC62AEF2DF80D151E4F20E946F69C9B7AC7F01D1A916F3C1D23984DAF12A5CF18C5FDD9922AE0DBFFB31E9EAC765DCF315EBB0524E8B9246BC97169BE71440DF64D5884F63D9ECC8C96E312169E71BC1D25DCE1AE142F6C4D265BA36CBAAC0860E6C83C26B287461F4FE90C5D2CAF4A87937E12407CC632618086D75FB5A17ED87F8EEE71893A6890E74AA378BD6B91CD4CF264F0826110494D2492F6A45567AB8FF4C28142582D3E66E9D3961881DFA1877E2EC993E31A35017C8291B0C74BCF285F94BC6E8B5D0EDEE7F571BEDDEB32184688CB221D1E42A74657FE9AC83679E51B925D617069FF259975C40D370D0D51F18D1C17358B9C197B00893AEE90BA06517787E8C4884E783F2A4B7633C62E7843B743688FA6296F11A6F4D584C2905EADA2076D289449F5DB07E2788F021D435DD188563CDAA1C89B0E7E87017788634AF18CAD9ADB8BA18E80C5BD0BE1424FF9135B07DD3660A2C7 +20241129003859 2 6 100 3071 2 C94F41FDB4E54DBDD1C7A49F586104E6D74F4CD07A2B9730A4FB5D40C24AB929C55B955144ADC62AEF2DF80D151E4F20E946F69C9B7AC7F01D1A916F3C1D23984DAF12A5CF18C5FDD9922AE0DBFFB31E9EAC765DCF315EBB0524E8B9246BC97169BE71440DF64D5884F63D9ECC8C96E312169E71BC1D25DCE1AE142F6C4D265BA36CBAAC0860E6C83C26B287461F4FE90C5D2CAF4A87937E12407CC632618086D75FB5A17ED87F8EEE71893A6890E74AA378BD6B91CD4CF264F0826110494D2492F6A45567AB8FF4C28142582D3E66E9D3961881DFA1877E2EC993E31A35017C8291B0C74BCF285F94BC6E8B5D0EDEE7F571BEDDEB32184688CB221D1E42A74657FE9AC83679E51B925D617069FF259975C40D370D0D51F18D1C17358B9C197B00893AEE90BA06517787E8C4884E783F2A4B7633C62E7843B743688FA6296F11A6F4D584C2905EADA2076D289449F5DB07E2788F021D435DD188563CDAA1C89B0E7E87017788634AF18CAD9ADB8BA18E80C5BD0BE1424FF9135B07DD368F747B +20241129003902 2 6 100 3071 2 C94F41FDB4E54DBDD1C7A49F586104E6D74F4CD07A2B9730A4FB5D40C24AB929C55B955144ADC62AEF2DF80D151E4F20E946F69C9B7AC7F01D1A916F3C1D23984DAF12A5CF18C5FDD9922AE0DBFFB31E9EAC765DCF315EBB0524E8B9246BC97169BE71440DF64D5884F63D9ECC8C96E312169E71BC1D25DCE1AE142F6C4D265BA36CBAAC0860E6C83C26B287461F4FE90C5D2CAF4A87937E12407CC632618086D75FB5A17ED87F8EEE71893A6890E74AA378BD6B91CD4CF264F0826110494D2492F6A45567AB8FF4C28142582D3E66E9D3961881DFA1877E2EC993E31A35017C8291B0C74BCF285F94BC6E8B5D0EDEE7F571BEDDEB32184688CB221D1E42A74657FE9AC83679E51B925D617069FF259975C40D370D0D51F18D1C17358B9C197B00893AEE90BA06517787E8C4884E783F2A4B7633C62E7843B743688FA6296F11A6F4D584C2905EADA2076D289449F5DB07E2788F021D435DD188563CDAA1C89B0E7E87017788634AF18CAD9ADB8BA18E80C5BD0BE1424FF9135B07DD3695A29B +20241129003921 2 6 100 3071 2 C94F41FDB4E54DBDD1C7A49F586104E6D74F4CD07A2B9730A4FB5D40C24AB929C55B955144ADC62AEF2DF80D151E4F20E946F69C9B7AC7F01D1A916F3C1D23984DAF12A5CF18C5FDD9922AE0DBFFB31E9EAC765DCF315EBB0524E8B9246BC97169BE71440DF64D5884F63D9ECC8C96E312169E71BC1D25DCE1AE142F6C4D265BA36CBAAC0860E6C83C26B287461F4FE90C5D2CAF4A87937E12407CC632618086D75FB5A17ED87F8EEE71893A6890E74AA378BD6B91CD4CF264F0826110494D2492F6A45567AB8FF4C28142582D3E66E9D3961881DFA1877E2EC993E31A35017C8291B0C74BCF285F94BC6E8B5D0EDEE7F571BEDDEB32184688CB221D1E42A74657FE9AC83679E51B925D617069FF259975C40D370D0D51F18D1C17358B9C197B00893AEE90BA06517787E8C4884E783F2A4B7633C62E7843B743688FA6296F11A6F4D584C2905EADA2076D289449F5DB07E2788F021D435DD188563CDAA1C89B0E7E87017788634AF18CAD9ADB8BA18E80C5BD0BE1424FF9135B07DD36C9F673 +20241129004005 2 6 100 3071 5 C94F41FDB4E54DBDD1C7A49F586104E6D74F4CD07A2B9730A4FB5D40C24AB929C55B955144ADC62AEF2DF80D151E4F20E946F69C9B7AC7F01D1A916F3C1D23984DAF12A5CF18C5FDD9922AE0DBFFB31E9EAC765DCF315EBB0524E8B9246BC97169BE71440DF64D5884F63D9ECC8C96E312169E71BC1D25DCE1AE142F6C4D265BA36CBAAC0860E6C83C26B287461F4FE90C5D2CAF4A87937E12407CC632618086D75FB5A17ED87F8EEE71893A6890E74AA378BD6B91CD4CF264F0826110494D2492F6A45567AB8FF4C28142582D3E66E9D3961881DFA1877E2EC993E31A35017C8291B0C74BCF285F94BC6E8B5D0EDEE7F571BEDDEB32184688CB221D1E42A74657FE9AC83679E51B925D617069FF259975C40D370D0D51F18D1C17358B9C197B00893AEE90BA06517787E8C4884E783F2A4B7633C62E7843B743688FA6296F11A6F4D584C2905EADA2076D289449F5DB07E2788F021D435DD188563CDAA1C89B0E7E87017788634AF18CAD9ADB8BA18E80C5BD0BE1424FF9135B07DD3753CA0F +20241129004008 2 6 100 3071 2 C94F41FDB4E54DBDD1C7A49F586104E6D74F4CD07A2B9730A4FB5D40C24AB929C55B955144ADC62AEF2DF80D151E4F20E946F69C9B7AC7F01D1A916F3C1D23984DAF12A5CF18C5FDD9922AE0DBFFB31E9EAC765DCF315EBB0524E8B9246BC97169BE71440DF64D5884F63D9ECC8C96E312169E71BC1D25DCE1AE142F6C4D265BA36CBAAC0860E6C83C26B287461F4FE90C5D2CAF4A87937E12407CC632618086D75FB5A17ED87F8EEE71893A6890E74AA378BD6B91CD4CF264F0826110494D2492F6A45567AB8FF4C28142582D3E66E9D3961881DFA1877E2EC993E31A35017C8291B0C74BCF285F94BC6E8B5D0EDEE7F571BEDDEB32184688CB221D1E42A74657FE9AC83679E51B925D617069FF259975C40D370D0D51F18D1C17358B9C197B00893AEE90BA06517787E8C4884E783F2A4B7633C62E7843B743688FA6296F11A6F4D584C2905EADA2076D289449F5DB07E2788F021D435DD188563CDAA1C89B0E7E87017788634AF18CAD9ADB8BA18E80C5BD0BE1424FF9135B07DD3758F683 +20241129004208 2 6 100 3071 2 C94F41FDB4E54DBDD1C7A49F586104E6D74F4CD07A2B9730A4FB5D40C24AB929C55B955144ADC62AEF2DF80D151E4F20E946F69C9B7AC7F01D1A916F3C1D23984DAF12A5CF18C5FDD9922AE0DBFFB31E9EAC765DCF315EBB0524E8B9246BC97169BE71440DF64D5884F63D9ECC8C96E312169E71BC1D25DCE1AE142F6C4D265BA36CBAAC0860E6C83C26B287461F4FE90C5D2CAF4A87937E12407CC632618086D75FB5A17ED87F8EEE71893A6890E74AA378BD6B91CD4CF264F0826110494D2492F6A45567AB8FF4C28142582D3E66E9D3961881DFA1877E2EC993E31A35017C8291B0C74BCF285F94BC6E8B5D0EDEE7F571BEDDEB32184688CB221D1E42A74657FE9AC83679E51B925D617069FF259975C40D370D0D51F18D1C17358B9C197B00893AEE90BA06517787E8C4884E783F2A4B7633C62E7843B743688FA6296F11A6F4D584C2905EADA2076D289449F5DB07E2788F021D435DD188563CDAA1C89B0E7E87017788634AF18CAD9ADB8BA18E80C5BD0BE1424FF9135B07DD38E3CD3B +20241129004221 2 6 100 3071 2 C94F41FDB4E54DBDD1C7A49F586104E6D74F4CD07A2B9730A4FB5D40C24AB929C55B955144ADC62AEF2DF80D151E4F20E946F69C9B7AC7F01D1A916F3C1D23984DAF12A5CF18C5FDD9922AE0DBFFB31E9EAC765DCF315EBB0524E8B9246BC97169BE71440DF64D5884F63D9ECC8C96E312169E71BC1D25DCE1AE142F6C4D265BA36CBAAC0860E6C83C26B287461F4FE90C5D2CAF4A87937E12407CC632618086D75FB5A17ED87F8EEE71893A6890E74AA378BD6B91CD4CF264F0826110494D2492F6A45567AB8FF4C28142582D3E66E9D3961881DFA1877E2EC993E31A35017C8291B0C74BCF285F94BC6E8B5D0EDEE7F571BEDDEB32184688CB221D1E42A74657FE9AC83679E51B925D617069FF259975C40D370D0D51F18D1C17358B9C197B00893AEE90BA06517787E8C4884E783F2A4B7633C62E7843B743688FA6296F11A6F4D584C2905EADA2076D289449F5DB07E2788F021D435DD188563CDAA1C89B0E7E87017788634AF18CAD9ADB8BA18E80C5BD0BE1424FF9135B07DD390C377B +20241129004322 2 6 100 3071 2 C94F41FDB4E54DBDD1C7A49F586104E6D74F4CD07A2B9730A4FB5D40C24AB929C55B955144ADC62AEF2DF80D151E4F20E946F69C9B7AC7F01D1A916F3C1D23984DAF12A5CF18C5FDD9922AE0DBFFB31E9EAC765DCF315EBB0524E8B9246BC97169BE71440DF64D5884F63D9ECC8C96E312169E71BC1D25DCE1AE142F6C4D265BA36CBAAC0860E6C83C26B287461F4FE90C5D2CAF4A87937E12407CC632618086D75FB5A17ED87F8EEE71893A6890E74AA378BD6B91CD4CF264F0826110494D2492F6A45567AB8FF4C28142582D3E66E9D3961881DFA1877E2EC993E31A35017C8291B0C74BCF285F94BC6E8B5D0EDEE7F571BEDDEB32184688CB221D1E42A74657FE9AC83679E51B925D617069FF259975C40D370D0D51F18D1C17358B9C197B00893AEE90BA06517787E8C4884E783F2A4B7633C62E7843B743688FA6296F11A6F4D584C2905EADA2076D289449F5DB07E2788F021D435DD188563CDAA1C89B0E7E87017788634AF18CAD9ADB8BA18E80C5BD0BE1424FF9135B07DD39CE5ACB +20241129004335 2 6 100 3071 2 C94F41FDB4E54DBDD1C7A49F586104E6D74F4CD07A2B9730A4FB5D40C24AB929C55B955144ADC62AEF2DF80D151E4F20E946F69C9B7AC7F01D1A916F3C1D23984DAF12A5CF18C5FDD9922AE0DBFFB31E9EAC765DCF315EBB0524E8B9246BC97169BE71440DF64D5884F63D9ECC8C96E312169E71BC1D25DCE1AE142F6C4D265BA36CBAAC0860E6C83C26B287461F4FE90C5D2CAF4A87937E12407CC632618086D75FB5A17ED87F8EEE71893A6890E74AA378BD6B91CD4CF264F0826110494D2492F6A45567AB8FF4C28142582D3E66E9D3961881DFA1877E2EC993E31A35017C8291B0C74BCF285F94BC6E8B5D0EDEE7F571BEDDEB32184688CB221D1E42A74657FE9AC83679E51B925D617069FF259975C40D370D0D51F18D1C17358B9C197B00893AEE90BA06517787E8C4884E783F2A4B7633C62E7843B743688FA6296F11A6F4D584C2905EADA2076D289449F5DB07E2788F021D435DD188563CDAA1C89B0E7E87017788634AF18CAD9ADB8BA18E80C5BD0BE1424FF9135B07DD39EC486B +20241129004341 2 6 100 3071 5 C94F41FDB4E54DBDD1C7A49F586104E6D74F4CD07A2B9730A4FB5D40C24AB929C55B955144ADC62AEF2DF80D151E4F20E946F69C9B7AC7F01D1A916F3C1D23984DAF12A5CF18C5FDD9922AE0DBFFB31E9EAC765DCF315EBB0524E8B9246BC97169BE71440DF64D5884F63D9ECC8C96E312169E71BC1D25DCE1AE142F6C4D265BA36CBAAC0860E6C83C26B287461F4FE90C5D2CAF4A87937E12407CC632618086D75FB5A17ED87F8EEE71893A6890E74AA378BD6B91CD4CF264F0826110494D2492F6A45567AB8FF4C28142582D3E66E9D3961881DFA1877E2EC993E31A35017C8291B0C74BCF285F94BC6E8B5D0EDEE7F571BEDDEB32184688CB221D1E42A74657FE9AC83679E51B925D617069FF259975C40D370D0D51F18D1C17358B9C197B00893AEE90BA06517787E8C4884E783F2A4B7633C62E7843B743688FA6296F11A6F4D584C2905EADA2076D289449F5DB07E2788F021D435DD188563CDAA1C89B0E7E87017788634AF18CAD9ADB8BA18E80C5BD0BE1424FF9135B07DD39F7B37F +20241129004348 2 6 100 3071 5 C94F41FDB4E54DBDD1C7A49F586104E6D74F4CD07A2B9730A4FB5D40C24AB929C55B955144ADC62AEF2DF80D151E4F20E946F69C9B7AC7F01D1A916F3C1D23984DAF12A5CF18C5FDD9922AE0DBFFB31E9EAC765DCF315EBB0524E8B9246BC97169BE71440DF64D5884F63D9ECC8C96E312169E71BC1D25DCE1AE142F6C4D265BA36CBAAC0860E6C83C26B287461F4FE90C5D2CAF4A87937E12407CC632618086D75FB5A17ED87F8EEE71893A6890E74AA378BD6B91CD4CF264F0826110494D2492F6A45567AB8FF4C28142582D3E66E9D3961881DFA1877E2EC993E31A35017C8291B0C74BCF285F94BC6E8B5D0EDEE7F571BEDDEB32184688CB221D1E42A74657FE9AC83679E51B925D617069FF259975C40D370D0D51F18D1C17358B9C197B00893AEE90BA06517787E8C4884E783F2A4B7633C62E7843B743688FA6296F11A6F4D584C2905EADA2076D289449F5DB07E2788F021D435DD188563CDAA1C89B0E7E87017788634AF18CAD9ADB8BA18E80C5BD0BE1424FF9135B07DD3A089907 +20241129004413 2 6 100 3071 2 C94F41FDB4E54DBDD1C7A49F586104E6D74F4CD07A2B9730A4FB5D40C24AB929C55B955144ADC62AEF2DF80D151E4F20E946F69C9B7AC7F01D1A916F3C1D23984DAF12A5CF18C5FDD9922AE0DBFFB31E9EAC765DCF315EBB0524E8B9246BC97169BE71440DF64D5884F63D9ECC8C96E312169E71BC1D25DCE1AE142F6C4D265BA36CBAAC0860E6C83C26B287461F4FE90C5D2CAF4A87937E12407CC632618086D75FB5A17ED87F8EEE71893A6890E74AA378BD6B91CD4CF264F0826110494D2492F6A45567AB8FF4C28142582D3E66E9D3961881DFA1877E2EC993E31A35017C8291B0C74BCF285F94BC6E8B5D0EDEE7F571BEDDEB32184688CB221D1E42A74657FE9AC83679E51B925D617069FF259975C40D370D0D51F18D1C17358B9C197B00893AEE90BA06517787E8C4884E783F2A4B7633C62E7843B743688FA6296F11A6F4D584C2905EADA2076D289449F5DB07E2788F021D435DD188563CDAA1C89B0E7E87017788634AF18CAD9ADB8BA18E80C5BD0BE1424FF9135B07DD3A5136DB +20241129004447 2 6 100 3071 2 C94F41FDB4E54DBDD1C7A49F586104E6D74F4CD07A2B9730A4FB5D40C24AB929C55B955144ADC62AEF2DF80D151E4F20E946F69C9B7AC7F01D1A916F3C1D23984DAF12A5CF18C5FDD9922AE0DBFFB31E9EAC765DCF315EBB0524E8B9246BC97169BE71440DF64D5884F63D9ECC8C96E312169E71BC1D25DCE1AE142F6C4D265BA36CBAAC0860E6C83C26B287461F4FE90C5D2CAF4A87937E12407CC632618086D75FB5A17ED87F8EEE71893A6890E74AA378BD6B91CD4CF264F0826110494D2492F6A45567AB8FF4C28142582D3E66E9D3961881DFA1877E2EC993E31A35017C8291B0C74BCF285F94BC6E8B5D0EDEE7F571BEDDEB32184688CB221D1E42A74657FE9AC83679E51B925D617069FF259975C40D370D0D51F18D1C17358B9C197B00893AEE90BA06517787E8C4884E783F2A4B7633C62E7843B743688FA6296F11A6F4D584C2905EADA2076D289449F5DB07E2788F021D435DD188563CDAA1C89B0E7E87017788634AF18CAD9ADB8BA18E80C5BD0BE1424FF9135B07DD3ABE89AB +20241129004614 2 6 100 3071 2 C94F41FDB4E54DBDD1C7A49F586104E6D74F4CD07A2B9730A4FB5D40C24AB929C55B955144ADC62AEF2DF80D151E4F20E946F69C9B7AC7F01D1A916F3C1D23984DAF12A5CF18C5FDD9922AE0DBFFB31E9EAC765DCF315EBB0524E8B9246BC97169BE71440DF64D5884F63D9ECC8C96E312169E71BC1D25DCE1AE142F6C4D265BA36CBAAC0860E6C83C26B287461F4FE90C5D2CAF4A87937E12407CC632618086D75FB5A17ED87F8EEE71893A6890E74AA378BD6B91CD4CF264F0826110494D2492F6A45567AB8FF4C28142582D3E66E9D3961881DFA1877E2EC993E31A35017C8291B0C74BCF285F94BC6E8B5D0EDEE7F571BEDDEB32184688CB221D1E42A74657FE9AC83679E51B925D617069FF259975C40D370D0D51F18D1C17358B9C197B00893AEE90BA06517787E8C4884E783F2A4B7633C62E7843B743688FA6296F11A6F4D584C2905EADA2076D289449F5DB07E2788F021D435DD188563CDAA1C89B0E7E87017788634AF18CAD9ADB8BA18E80C5BD0BE1424FF9135B07DD3BD9A0DB +20241129004627 2 6 100 3071 2 C94F41FDB4E54DBDD1C7A49F586104E6D74F4CD07A2B9730A4FB5D40C24AB929C55B955144ADC62AEF2DF80D151E4F20E946F69C9B7AC7F01D1A916F3C1D23984DAF12A5CF18C5FDD9922AE0DBFFB31E9EAC765DCF315EBB0524E8B9246BC97169BE71440DF64D5884F63D9ECC8C96E312169E71BC1D25DCE1AE142F6C4D265BA36CBAAC0860E6C83C26B287461F4FE90C5D2CAF4A87937E12407CC632618086D75FB5A17ED87F8EEE71893A6890E74AA378BD6B91CD4CF264F0826110494D2492F6A45567AB8FF4C28142582D3E66E9D3961881DFA1877E2EC993E31A35017C8291B0C74BCF285F94BC6E8B5D0EDEE7F571BEDDEB32184688CB221D1E42A74657FE9AC83679E51B925D617069FF259975C40D370D0D51F18D1C17358B9C197B00893AEE90BA06517787E8C4884E783F2A4B7633C62E7843B743688FA6296F11A6F4D584C2905EADA2076D289449F5DB07E2788F021D435DD188563CDAA1C89B0E7E87017788634AF18CAD9ADB8BA18E80C5BD0BE1424FF9135B07DD3BFC1AC3 +20241129004630 2 6 100 3071 2 C94F41FDB4E54DBDD1C7A49F586104E6D74F4CD07A2B9730A4FB5D40C24AB929C55B955144ADC62AEF2DF80D151E4F20E946F69C9B7AC7F01D1A916F3C1D23984DAF12A5CF18C5FDD9922AE0DBFFB31E9EAC765DCF315EBB0524E8B9246BC97169BE71440DF64D5884F63D9ECC8C96E312169E71BC1D25DCE1AE142F6C4D265BA36CBAAC0860E6C83C26B287461F4FE90C5D2CAF4A87937E12407CC632618086D75FB5A17ED87F8EEE71893A6890E74AA378BD6B91CD4CF264F0826110494D2492F6A45567AB8FF4C28142582D3E66E9D3961881DFA1877E2EC993E31A35017C8291B0C74BCF285F94BC6E8B5D0EDEE7F571BEDDEB32184688CB221D1E42A74657FE9AC83679E51B925D617069FF259975C40D370D0D51F18D1C17358B9C197B00893AEE90BA06517787E8C4884E783F2A4B7633C62E7843B743688FA6296F11A6F4D584C2905EADA2076D289449F5DB07E2788F021D435DD188563CDAA1C89B0E7E87017788634AF18CAD9ADB8BA18E80C5BD0BE1424FF9135B07DD3BFE5DDB +20241129004648 2 6 100 3071 2 C94F41FDB4E54DBDD1C7A49F586104E6D74F4CD07A2B9730A4FB5D40C24AB929C55B955144ADC62AEF2DF80D151E4F20E946F69C9B7AC7F01D1A916F3C1D23984DAF12A5CF18C5FDD9922AE0DBFFB31E9EAC765DCF315EBB0524E8B9246BC97169BE71440DF64D5884F63D9ECC8C96E312169E71BC1D25DCE1AE142F6C4D265BA36CBAAC0860E6C83C26B287461F4FE90C5D2CAF4A87937E12407CC632618086D75FB5A17ED87F8EEE71893A6890E74AA378BD6B91CD4CF264F0826110494D2492F6A45567AB8FF4C28142582D3E66E9D3961881DFA1877E2EC993E31A35017C8291B0C74BCF285F94BC6E8B5D0EDEE7F571BEDDEB32184688CB221D1E42A74657FE9AC83679E51B925D617069FF259975C40D370D0D51F18D1C17358B9C197B00893AEE90BA06517787E8C4884E783F2A4B7633C62E7843B743688FA6296F11A6F4D584C2905EADA2076D289449F5DB07E2788F021D435DD188563CDAA1C89B0E7E87017788634AF18CAD9ADB8BA18E80C5BD0BE1424FF9135B07DD3C3863FB +20241129004754 2 6 100 3071 5 C94F41FDB4E54DBDD1C7A49F586104E6D74F4CD07A2B9730A4FB5D40C24AB929C55B955144ADC62AEF2DF80D151E4F20E946F69C9B7AC7F01D1A916F3C1D23984DAF12A5CF18C5FDD9922AE0DBFFB31E9EAC765DCF315EBB0524E8B9246BC97169BE71440DF64D5884F63D9ECC8C96E312169E71BC1D25DCE1AE142F6C4D265BA36CBAAC0860E6C83C26B287461F4FE90C5D2CAF4A87937E12407CC632618086D75FB5A17ED87F8EEE71893A6890E74AA378BD6B91CD4CF264F0826110494D2492F6A45567AB8FF4C28142582D3E66E9D3961881DFA1877E2EC993E31A35017C8291B0C74BCF285F94BC6E8B5D0EDEE7F571BEDDEB32184688CB221D1E42A74657FE9AC83679E51B925D617069FF259975C40D370D0D51F18D1C17358B9C197B00893AEE90BA06517787E8C4884E783F2A4B7633C62E7843B743688FA6296F11A6F4D584C2905EADA2076D289449F5DB07E2788F021D435DD188563CDAA1C89B0E7E87017788634AF18CAD9ADB8BA18E80C5BD0BE1424FF9135B07DD3D09984F +20241129004835 2 6 100 3071 2 C94F41FDB4E54DBDD1C7A49F586104E6D74F4CD07A2B9730A4FB5D40C24AB929C55B955144ADC62AEF2DF80D151E4F20E946F69C9B7AC7F01D1A916F3C1D23984DAF12A5CF18C5FDD9922AE0DBFFB31E9EAC765DCF315EBB0524E8B9246BC97169BE71440DF64D5884F63D9ECC8C96E312169E71BC1D25DCE1AE142F6C4D265BA36CBAAC0860E6C83C26B287461F4FE90C5D2CAF4A87937E12407CC632618086D75FB5A17ED87F8EEE71893A6890E74AA378BD6B91CD4CF264F0826110494D2492F6A45567AB8FF4C28142582D3E66E9D3961881DFA1877E2EC993E31A35017C8291B0C74BCF285F94BC6E8B5D0EDEE7F571BEDDEB32184688CB221D1E42A74657FE9AC83679E51B925D617069FF259975C40D370D0D51F18D1C17358B9C197B00893AEE90BA06517787E8C4884E783F2A4B7633C62E7843B743688FA6296F11A6F4D584C2905EADA2076D289449F5DB07E2788F021D435DD188563CDAA1C89B0E7E87017788634AF18CAD9ADB8BA18E80C5BD0BE1424FF9135B07DD3D875973 +20241129004842 2 6 100 3071 2 C94F41FDB4E54DBDD1C7A49F586104E6D74F4CD07A2B9730A4FB5D40C24AB929C55B955144ADC62AEF2DF80D151E4F20E946F69C9B7AC7F01D1A916F3C1D23984DAF12A5CF18C5FDD9922AE0DBFFB31E9EAC765DCF315EBB0524E8B9246BC97169BE71440DF64D5884F63D9ECC8C96E312169E71BC1D25DCE1AE142F6C4D265BA36CBAAC0860E6C83C26B287461F4FE90C5D2CAF4A87937E12407CC632618086D75FB5A17ED87F8EEE71893A6890E74AA378BD6B91CD4CF264F0826110494D2492F6A45567AB8FF4C28142582D3E66E9D3961881DFA1877E2EC993E31A35017C8291B0C74BCF285F94BC6E8B5D0EDEE7F571BEDDEB32184688CB221D1E42A74657FE9AC83679E51B925D617069FF259975C40D370D0D51F18D1C17358B9C197B00893AEE90BA06517787E8C4884E783F2A4B7633C62E7843B743688FA6296F11A6F4D584C2905EADA2076D289449F5DB07E2788F021D435DD188563CDAA1C89B0E7E87017788634AF18CAD9ADB8BA18E80C5BD0BE1424FF9135B07DD3D958953 +20241129004906 2 6 100 3071 2 C94F41FDB4E54DBDD1C7A49F586104E6D74F4CD07A2B9730A4FB5D40C24AB929C55B955144ADC62AEF2DF80D151E4F20E946F69C9B7AC7F01D1A916F3C1D23984DAF12A5CF18C5FDD9922AE0DBFFB31E9EAC765DCF315EBB0524E8B9246BC97169BE71440DF64D5884F63D9ECC8C96E312169E71BC1D25DCE1AE142F6C4D265BA36CBAAC0860E6C83C26B287461F4FE90C5D2CAF4A87937E12407CC632618086D75FB5A17ED87F8EEE71893A6890E74AA378BD6B91CD4CF264F0826110494D2492F6A45567AB8FF4C28142582D3E66E9D3961881DFA1877E2EC993E31A35017C8291B0C74BCF285F94BC6E8B5D0EDEE7F571BEDDEB32184688CB221D1E42A74657FE9AC83679E51B925D617069FF259975C40D370D0D51F18D1C17358B9C197B00893AEE90BA06517787E8C4884E783F2A4B7633C62E7843B743688FA6296F11A6F4D584C2905EADA2076D289449F5DB07E2788F021D435DD188563CDAA1C89B0E7E87017788634AF18CAD9ADB8BA18E80C5BD0BE1424FF9135B07DD3DDF57FB +20241129005005 2 6 100 3071 2 C94F41FDB4E54DBDD1C7A49F586104E6D74F4CD07A2B9730A4FB5D40C24AB929C55B955144ADC62AEF2DF80D151E4F20E946F69C9B7AC7F01D1A916F3C1D23984DAF12A5CF18C5FDD9922AE0DBFFB31E9EAC765DCF315EBB0524E8B9246BC97169BE71440DF64D5884F63D9ECC8C96E312169E71BC1D25DCE1AE142F6C4D265BA36CBAAC0860E6C83C26B287461F4FE90C5D2CAF4A87937E12407CC632618086D75FB5A17ED87F8EEE71893A6890E74AA378BD6B91CD4CF264F0826110494D2492F6A45567AB8FF4C28142582D3E66E9D3961881DFA1877E2EC993E31A35017C8291B0C74BCF285F94BC6E8B5D0EDEE7F571BEDDEB32184688CB221D1E42A74657FE9AC83679E51B925D617069FF259975C40D370D0D51F18D1C17358B9C197B00893AEE90BA06517787E8C4884E783F2A4B7633C62E7843B743688FA6296F11A6F4D584C2905EADA2076D289449F5DB07E2788F021D435DD188563CDAA1C89B0E7E87017788634AF18CAD9ADB8BA18E80C5BD0BE1424FF9135B07DD3E9E3063 +20241129005036 2 6 100 3071 2 C94F41FDB4E54DBDD1C7A49F586104E6D74F4CD07A2B9730A4FB5D40C24AB929C55B955144ADC62AEF2DF80D151E4F20E946F69C9B7AC7F01D1A916F3C1D23984DAF12A5CF18C5FDD9922AE0DBFFB31E9EAC765DCF315EBB0524E8B9246BC97169BE71440DF64D5884F63D9ECC8C96E312169E71BC1D25DCE1AE142F6C4D265BA36CBAAC0860E6C83C26B287461F4FE90C5D2CAF4A87937E12407CC632618086D75FB5A17ED87F8EEE71893A6890E74AA378BD6B91CD4CF264F0826110494D2492F6A45567AB8FF4C28142582D3E66E9D3961881DFA1877E2EC993E31A35017C8291B0C74BCF285F94BC6E8B5D0EDEE7F571BEDDEB32184688CB221D1E42A74657FE9AC83679E51B925D617069FF259975C40D370D0D51F18D1C17358B9C197B00893AEE90BA06517787E8C4884E783F2A4B7633C62E7843B743688FA6296F11A6F4D584C2905EADA2076D289449F5DB07E2788F021D435DD188563CDAA1C89B0E7E87017788634AF18CAD9ADB8BA18E80C5BD0BE1424FF9135B07DD3EFEEAC3 +20241129005052 2 6 100 3071 2 C94F41FDB4E54DBDD1C7A49F586104E6D74F4CD07A2B9730A4FB5D40C24AB929C55B955144ADC62AEF2DF80D151E4F20E946F69C9B7AC7F01D1A916F3C1D23984DAF12A5CF18C5FDD9922AE0DBFFB31E9EAC765DCF315EBB0524E8B9246BC97169BE71440DF64D5884F63D9ECC8C96E312169E71BC1D25DCE1AE142F6C4D265BA36CBAAC0860E6C83C26B287461F4FE90C5D2CAF4A87937E12407CC632618086D75FB5A17ED87F8EEE71893A6890E74AA378BD6B91CD4CF264F0826110494D2492F6A45567AB8FF4C28142582D3E66E9D3961881DFA1877E2EC993E31A35017C8291B0C74BCF285F94BC6E8B5D0EDEE7F571BEDDEB32184688CB221D1E42A74657FE9AC83679E51B925D617069FF259975C40D370D0D51F18D1C17358B9C197B00893AEE90BA06517787E8C4884E783F2A4B7633C62E7843B743688FA6296F11A6F4D584C2905EADA2076D289449F5DB07E2788F021D435DD188563CDAA1C89B0E7E87017788634AF18CAD9ADB8BA18E80C5BD0BE1424FF9135B07DD3F2A5E03 +20241129005537 2 6 100 3071 5 C94F41FDB4E54DBDD1C7A49F586104E6D74F4CD07A2B9730A4FB5D40C24AB929C55B955144ADC62AEF2DF80D151E4F20E946F69C9B7AC7F01D1A916F3C1D23984DAF12A5CF18C5FDD9922AE0DBFFB31E9EAC765DCF315EBB0524E8B9246BC97169BE71440DF64D5884F63D9ECC8C96E312169E71BC1D25DCE1AE142F6C4D265BA36CBAAC0860E6C83C26B287461F4FE90C5D2CAF4A87937E12407CC632618086D75FB5A17ED87F8EEE71893A6890E74AA378BD6B91CD4CF264F0826110494D2492F6A45567AB8FF4C28142582D3E66E9D3961881DFA1877E2EC993E31A35017C8291B0C74BCF285F94BC6E8B5D0EDEE7F571BEDDEB32184688CB221D1E42A74657FE9AC83679E51B925D617069FF259975C40D370D0D51F18D1C17358B9C197B00893AEE90BA06517787E8C4884E783F2A4B7633C62E7843B743688FA6296F11A6F4D584C2905EADA2076D289449F5DB07E2788F021D435DD188563CDAA1C89B0E7E87017788634AF18CAD9ADB8BA18E80C5BD0BE1424FF9135B07DD42DD9C2F +20241129005637 2 6 100 3071 5 F72B9D5B478FC38253834B862A5C515BA6212BAD106C43D243A9D021FF22434E6A1EA03FBACFA23A6FC66FE5C68B40013BA6D15844D35AA2127408DE731CCA98380661EE30E2480E9DB14A8EB484BF564838B45678ECB78800E41E499307253A0E4462C7E119ECAA096D496FF72C5CB823C5C38CC165B9EE0B5307005F9FE72FE34EF3C2EF456A3A4561245680205533E2C2DC31816DDFFB036922109B985F291F7ADDCA11FADD48E7D20C9F8D0E8AE073C4DD7269B1EF46ACC81BE52A053EFE3BEAB1BFA3822A10ABF2C95B27D406BF960FAA48A79D332A7138AAAB8828B1BD11BCE47ACFE934887A2B2DC6C7061EF8412B4912925FD5A9CE787C434B3FD5B39FA863EDA542574E22331F98E74F69283A9A8F9330FE597B1EE96E37C8DEBB0E861213F3BF5281F3753CC16B2AF1EAB12540517E0482FDF47C92B66C4CD5FA5C8725956DB4C5F435EFC44D2ABD17A078687DD7716CAC4683729BD6211E0CBADA144F28932906724F3B96501D1A897C088607B522F8C7586DAFC64CB14E5B5E8F +20241129005819 2 6 100 3071 2 F72B9D5B478FC38253834B862A5C515BA6212BAD106C43D243A9D021FF22434E6A1EA03FBACFA23A6FC66FE5C68B40013BA6D15844D35AA2127408DE731CCA98380661EE30E2480E9DB14A8EB484BF564838B45678ECB78800E41E499307253A0E4462C7E119ECAA096D496FF72C5CB823C5C38CC165B9EE0B5307005F9FE72FE34EF3C2EF456A3A4561245680205533E2C2DC31816DDFFB036922109B985F291F7ADDCA11FADD48E7D20C9F8D0E8AE073C4DD7269B1EF46ACC81BE52A053EFE3BEAB1BFA3822A10ABF2C95B27D406BF960FAA48A79D332A7138AAAB8828B1BD11BCE47ACFE934887A2B2DC6C7061EF8412B4912925FD5A9CE787C434B3FD5B39FA863EDA542574E22331F98E74F69283A9A8F9330FE597B1EE96E37C8DEBB0E861213F3BF5281F3753CC16B2AF1EAB12540517E0482FDF47C92B66C4CD5FA5C8725956DB4C5F435EFC44D2ABD17A078687DD7716CAC4683729BD6211E0CBADA144F28932906724F3B96501D1A897C088607B522F8C7586DAFC64CB14FA714FB +20241129010001 2 6 100 3071 2 F72B9D5B478FC38253834B862A5C515BA6212BAD106C43D243A9D021FF22434E6A1EA03FBACFA23A6FC66FE5C68B40013BA6D15844D35AA2127408DE731CCA98380661EE30E2480E9DB14A8EB484BF564838B45678ECB78800E41E499307253A0E4462C7E119ECAA096D496FF72C5CB823C5C38CC165B9EE0B5307005F9FE72FE34EF3C2EF456A3A4561245680205533E2C2DC31816DDFFB036922109B985F291F7ADDCA11FADD48E7D20C9F8D0E8AE073C4DD7269B1EF46ACC81BE52A053EFE3BEAB1BFA3822A10ABF2C95B27D406BF960FAA48A79D332A7138AAAB8828B1BD11BCE47ACFE934887A2B2DC6C7061EF8412B4912925FD5A9CE787C434B3FD5B39FA863EDA542574E22331F98E74F69283A9A8F9330FE597B1EE96E37C8DEBB0E861213F3BF5281F3753CC16B2AF1EAB12540517E0482FDF47C92B66C4CD5FA5C8725956DB4C5F435EFC44D2ABD17A078687DD7716CAC4683729BD6211E0CBADA144F28932906724F3B96501D1A897C088607B522F8C7586DAFC64CB150F56483 +20241129010010 2 6 100 3071 2 F72B9D5B478FC38253834B862A5C515BA6212BAD106C43D243A9D021FF22434E6A1EA03FBACFA23A6FC66FE5C68B40013BA6D15844D35AA2127408DE731CCA98380661EE30E2480E9DB14A8EB484BF564838B45678ECB78800E41E499307253A0E4462C7E119ECAA096D496FF72C5CB823C5C38CC165B9EE0B5307005F9FE72FE34EF3C2EF456A3A4561245680205533E2C2DC31816DDFFB036922109B985F291F7ADDCA11FADD48E7D20C9F8D0E8AE073C4DD7269B1EF46ACC81BE52A053EFE3BEAB1BFA3822A10ABF2C95B27D406BF960FAA48A79D332A7138AAAB8828B1BD11BCE47ACFE934887A2B2DC6C7061EF8412B4912925FD5A9CE787C434B3FD5B39FA863EDA542574E22331F98E74F69283A9A8F9330FE597B1EE96E37C8DEBB0E861213F3BF5281F3753CC16B2AF1EAB12540517E0482FDF47C92B66C4CD5FA5C8725956DB4C5F435EFC44D2ABD17A078687DD7716CAC4683729BD6211E0CBADA144F28932906724F3B96501D1A897C088607B522F8C7586DAFC64CB1510A25CB +20241129010049 2 6 100 3071 2 F72B9D5B478FC38253834B862A5C515BA6212BAD106C43D243A9D021FF22434E6A1EA03FBACFA23A6FC66FE5C68B40013BA6D15844D35AA2127408DE731CCA98380661EE30E2480E9DB14A8EB484BF564838B45678ECB78800E41E499307253A0E4462C7E119ECAA096D496FF72C5CB823C5C38CC165B9EE0B5307005F9FE72FE34EF3C2EF456A3A4561245680205533E2C2DC31816DDFFB036922109B985F291F7ADDCA11FADD48E7D20C9F8D0E8AE073C4DD7269B1EF46ACC81BE52A053EFE3BEAB1BFA3822A10ABF2C95B27D406BF960FAA48A79D332A7138AAAB8828B1BD11BCE47ACFE934887A2B2DC6C7061EF8412B4912925FD5A9CE787C434B3FD5B39FA863EDA542574E22331F98E74F69283A9A8F9330FE597B1EE96E37C8DEBB0E861213F3BF5281F3753CC16B2AF1EAB12540517E0482FDF47C92B66C4CD5FA5C8725956DB4C5F435EFC44D2ABD17A078687DD7716CAC4683729BD6211E0CBADA144F28932906724F3B96501D1A897C088607B522F8C7586DAFC64CB15189B8EB +20241129010057 2 6 100 3071 2 F72B9D5B478FC38253834B862A5C515BA6212BAD106C43D243A9D021FF22434E6A1EA03FBACFA23A6FC66FE5C68B40013BA6D15844D35AA2127408DE731CCA98380661EE30E2480E9DB14A8EB484BF564838B45678ECB78800E41E499307253A0E4462C7E119ECAA096D496FF72C5CB823C5C38CC165B9EE0B5307005F9FE72FE34EF3C2EF456A3A4561245680205533E2C2DC31816DDFFB036922109B985F291F7ADDCA11FADD48E7D20C9F8D0E8AE073C4DD7269B1EF46ACC81BE52A053EFE3BEAB1BFA3822A10ABF2C95B27D406BF960FAA48A79D332A7138AAAB8828B1BD11BCE47ACFE934887A2B2DC6C7061EF8412B4912925FD5A9CE787C434B3FD5B39FA863EDA542574E22331F98E74F69283A9A8F9330FE597B1EE96E37C8DEBB0E861213F3BF5281F3753CC16B2AF1EAB12540517E0482FDF47C92B66C4CD5FA5C8725956DB4C5F435EFC44D2ABD17A078687DD7716CAC4683729BD6211E0CBADA144F28932906724F3B96501D1A897C088607B522F8C7586DAFC64CB1519DABAB +20241129010104 2 6 100 3071 2 F72B9D5B478FC38253834B862A5C515BA6212BAD106C43D243A9D021FF22434E6A1EA03FBACFA23A6FC66FE5C68B40013BA6D15844D35AA2127408DE731CCA98380661EE30E2480E9DB14A8EB484BF564838B45678ECB78800E41E499307253A0E4462C7E119ECAA096D496FF72C5CB823C5C38CC165B9EE0B5307005F9FE72FE34EF3C2EF456A3A4561245680205533E2C2DC31816DDFFB036922109B985F291F7ADDCA11FADD48E7D20C9F8D0E8AE073C4DD7269B1EF46ACC81BE52A053EFE3BEAB1BFA3822A10ABF2C95B27D406BF960FAA48A79D332A7138AAAB8828B1BD11BCE47ACFE934887A2B2DC6C7061EF8412B4912925FD5A9CE787C434B3FD5B39FA863EDA542574E22331F98E74F69283A9A8F9330FE597B1EE96E37C8DEBB0E861213F3BF5281F3753CC16B2AF1EAB12540517E0482FDF47C92B66C4CD5FA5C8725956DB4C5F435EFC44D2ABD17A078687DD7716CAC4683729BD6211E0CBADA144F28932906724F3B96501D1A897C088607B522F8C7586DAFC64CB151AE01C3 +20241129010114 2 6 100 3071 5 F72B9D5B478FC38253834B862A5C515BA6212BAD106C43D243A9D021FF22434E6A1EA03FBACFA23A6FC66FE5C68B40013BA6D15844D35AA2127408DE731CCA98380661EE30E2480E9DB14A8EB484BF564838B45678ECB78800E41E499307253A0E4462C7E119ECAA096D496FF72C5CB823C5C38CC165B9EE0B5307005F9FE72FE34EF3C2EF456A3A4561245680205533E2C2DC31816DDFFB036922109B985F291F7ADDCA11FADD48E7D20C9F8D0E8AE073C4DD7269B1EF46ACC81BE52A053EFE3BEAB1BFA3822A10ABF2C95B27D406BF960FAA48A79D332A7138AAAB8828B1BD11BCE47ACFE934887A2B2DC6C7061EF8412B4912925FD5A9CE787C434B3FD5B39FA863EDA542574E22331F98E74F69283A9A8F9330FE597B1EE96E37C8DEBB0E861213F3BF5281F3753CC16B2AF1EAB12540517E0482FDF47C92B66C4CD5FA5C8725956DB4C5F435EFC44D2ABD17A078687DD7716CAC4683729BD6211E0CBADA144F28932906724F3B96501D1A897C088607B522F8C7586DAFC64CB151C91AA7 +20241129010216 2 6 100 3071 5 F72B9D5B478FC38253834B862A5C515BA6212BAD106C43D243A9D021FF22434E6A1EA03FBACFA23A6FC66FE5C68B40013BA6D15844D35AA2127408DE731CCA98380661EE30E2480E9DB14A8EB484BF564838B45678ECB78800E41E499307253A0E4462C7E119ECAA096D496FF72C5CB823C5C38CC165B9EE0B5307005F9FE72FE34EF3C2EF456A3A4561245680205533E2C2DC31816DDFFB036922109B985F291F7ADDCA11FADD48E7D20C9F8D0E8AE073C4DD7269B1EF46ACC81BE52A053EFE3BEAB1BFA3822A10ABF2C95B27D406BF960FAA48A79D332A7138AAAB8828B1BD11BCE47ACFE934887A2B2DC6C7061EF8412B4912925FD5A9CE787C434B3FD5B39FA863EDA542574E22331F98E74F69283A9A8F9330FE597B1EE96E37C8DEBB0E861213F3BF5281F3753CC16B2AF1EAB12540517E0482FDF47C92B66C4CD5FA5C8725956DB4C5F435EFC44D2ABD17A078687DD7716CAC4683729BD6211E0CBADA144F28932906724F3B96501D1A897C088607B522F8C7586DAFC64CB1528CD42F +20241129010239 2 6 100 3071 2 F72B9D5B478FC38253834B862A5C515BA6212BAD106C43D243A9D021FF22434E6A1EA03FBACFA23A6FC66FE5C68B40013BA6D15844D35AA2127408DE731CCA98380661EE30E2480E9DB14A8EB484BF564838B45678ECB78800E41E499307253A0E4462C7E119ECAA096D496FF72C5CB823C5C38CC165B9EE0B5307005F9FE72FE34EF3C2EF456A3A4561245680205533E2C2DC31816DDFFB036922109B985F291F7ADDCA11FADD48E7D20C9F8D0E8AE073C4DD7269B1EF46ACC81BE52A053EFE3BEAB1BFA3822A10ABF2C95B27D406BF960FAA48A79D332A7138AAAB8828B1BD11BCE47ACFE934887A2B2DC6C7061EF8412B4912925FD5A9CE787C434B3FD5B39FA863EDA542574E22331F98E74F69283A9A8F9330FE597B1EE96E37C8DEBB0E861213F3BF5281F3753CC16B2AF1EAB12540517E0482FDF47C92B66C4CD5FA5C8725956DB4C5F435EFC44D2ABD17A078687DD7716CAC4683729BD6211E0CBADA144F28932906724F3B96501D1A897C088607B522F8C7586DAFC64CB152D65F33 +20241129010312 2 6 100 3071 5 F72B9D5B478FC38253834B862A5C515BA6212BAD106C43D243A9D021FF22434E6A1EA03FBACFA23A6FC66FE5C68B40013BA6D15844D35AA2127408DE731CCA98380661EE30E2480E9DB14A8EB484BF564838B45678ECB78800E41E499307253A0E4462C7E119ECAA096D496FF72C5CB823C5C38CC165B9EE0B5307005F9FE72FE34EF3C2EF456A3A4561245680205533E2C2DC31816DDFFB036922109B985F291F7ADDCA11FADD48E7D20C9F8D0E8AE073C4DD7269B1EF46ACC81BE52A053EFE3BEAB1BFA3822A10ABF2C95B27D406BF960FAA48A79D332A7138AAAB8828B1BD11BCE47ACFE934887A2B2DC6C7061EF8412B4912925FD5A9CE787C434B3FD5B39FA863EDA542574E22331F98E74F69283A9A8F9330FE597B1EE96E37C8DEBB0E861213F3BF5281F3753CC16B2AF1EAB12540517E0482FDF47C92B66C4CD5FA5C8725956DB4C5F435EFC44D2ABD17A078687DD7716CAC4683729BD6211E0CBADA144F28932906724F3B96501D1A897C088607B522F8C7586DAFC64CB1533E97D7 +20241129010433 2 6 100 3071 5 F72B9D5B478FC38253834B862A5C515BA6212BAD106C43D243A9D021FF22434E6A1EA03FBACFA23A6FC66FE5C68B40013BA6D15844D35AA2127408DE731CCA98380661EE30E2480E9DB14A8EB484BF564838B45678ECB78800E41E499307253A0E4462C7E119ECAA096D496FF72C5CB823C5C38CC165B9EE0B5307005F9FE72FE34EF3C2EF456A3A4561245680205533E2C2DC31816DDFFB036922109B985F291F7ADDCA11FADD48E7D20C9F8D0E8AE073C4DD7269B1EF46ACC81BE52A053EFE3BEAB1BFA3822A10ABF2C95B27D406BF960FAA48A79D332A7138AAAB8828B1BD11BCE47ACFE934887A2B2DC6C7061EF8412B4912925FD5A9CE787C434B3FD5B39FA863EDA542574E22331F98E74F69283A9A8F9330FE597B1EE96E37C8DEBB0E861213F3BF5281F3753CC16B2AF1EAB12540517E0482FDF47C92B66C4CD5FA5C8725956DB4C5F435EFC44D2ABD17A078687DD7716CAC4683729BD6211E0CBADA144F28932906724F3B96501D1A897C088607B522F8C7586DAFC64CB1544811A7 +20241129010523 2 6 100 3071 5 F72B9D5B478FC38253834B862A5C515BA6212BAD106C43D243A9D021FF22434E6A1EA03FBACFA23A6FC66FE5C68B40013BA6D15844D35AA2127408DE731CCA98380661EE30E2480E9DB14A8EB484BF564838B45678ECB78800E41E499307253A0E4462C7E119ECAA096D496FF72C5CB823C5C38CC165B9EE0B5307005F9FE72FE34EF3C2EF456A3A4561245680205533E2C2DC31816DDFFB036922109B985F291F7ADDCA11FADD48E7D20C9F8D0E8AE073C4DD7269B1EF46ACC81BE52A053EFE3BEAB1BFA3822A10ABF2C95B27D406BF960FAA48A79D332A7138AAAB8828B1BD11BCE47ACFE934887A2B2DC6C7061EF8412B4912925FD5A9CE787C434B3FD5B39FA863EDA542574E22331F98E74F69283A9A8F9330FE597B1EE96E37C8DEBB0E861213F3BF5281F3753CC16B2AF1EAB12540517E0482FDF47C92B66C4CD5FA5C8725956DB4C5F435EFC44D2ABD17A078687DD7716CAC4683729BD6211E0CBADA144F28932906724F3B96501D1A897C088607B522F8C7586DAFC64CB154E65E7F +20241129010605 2 6 100 3071 2 F72B9D5B478FC38253834B862A5C515BA6212BAD106C43D243A9D021FF22434E6A1EA03FBACFA23A6FC66FE5C68B40013BA6D15844D35AA2127408DE731CCA98380661EE30E2480E9DB14A8EB484BF564838B45678ECB78800E41E499307253A0E4462C7E119ECAA096D496FF72C5CB823C5C38CC165B9EE0B5307005F9FE72FE34EF3C2EF456A3A4561245680205533E2C2DC31816DDFFB036922109B985F291F7ADDCA11FADD48E7D20C9F8D0E8AE073C4DD7269B1EF46ACC81BE52A053EFE3BEAB1BFA3822A10ABF2C95B27D406BF960FAA48A79D332A7138AAAB8828B1BD11BCE47ACFE934887A2B2DC6C7061EF8412B4912925FD5A9CE787C434B3FD5B39FA863EDA542574E22331F98E74F69283A9A8F9330FE597B1EE96E37C8DEBB0E861213F3BF5281F3753CC16B2AF1EAB12540517E0482FDF47C92B66C4CD5FA5C8725956DB4C5F435EFC44D2ABD17A078687DD7716CAC4683729BD6211E0CBADA144F28932906724F3B96501D1A897C088607B522F8C7586DAFC64CB1556C058B +20241129010625 2 6 100 3071 5 F72B9D5B478FC38253834B862A5C515BA6212BAD106C43D243A9D021FF22434E6A1EA03FBACFA23A6FC66FE5C68B40013BA6D15844D35AA2127408DE731CCA98380661EE30E2480E9DB14A8EB484BF564838B45678ECB78800E41E499307253A0E4462C7E119ECAA096D496FF72C5CB823C5C38CC165B9EE0B5307005F9FE72FE34EF3C2EF456A3A4561245680205533E2C2DC31816DDFFB036922109B985F291F7ADDCA11FADD48E7D20C9F8D0E8AE073C4DD7269B1EF46ACC81BE52A053EFE3BEAB1BFA3822A10ABF2C95B27D406BF960FAA48A79D332A7138AAAB8828B1BD11BCE47ACFE934887A2B2DC6C7061EF8412B4912925FD5A9CE787C434B3FD5B39FA863EDA542574E22331F98E74F69283A9A8F9330FE597B1EE96E37C8DEBB0E861213F3BF5281F3753CC16B2AF1EAB12540517E0482FDF47C92B66C4CD5FA5C8725956DB4C5F435EFC44D2ABD17A078687DD7716CAC4683729BD6211E0CBADA144F28932906724F3B96501D1A897C088607B522F8C7586DAFC64CB155A73F37 +20241129010718 2 6 100 3071 5 F72B9D5B478FC38253834B862A5C515BA6212BAD106C43D243A9D021FF22434E6A1EA03FBACFA23A6FC66FE5C68B40013BA6D15844D35AA2127408DE731CCA98380661EE30E2480E9DB14A8EB484BF564838B45678ECB78800E41E499307253A0E4462C7E119ECAA096D496FF72C5CB823C5C38CC165B9EE0B5307005F9FE72FE34EF3C2EF456A3A4561245680205533E2C2DC31816DDFFB036922109B985F291F7ADDCA11FADD48E7D20C9F8D0E8AE073C4DD7269B1EF46ACC81BE52A053EFE3BEAB1BFA3822A10ABF2C95B27D406BF960FAA48A79D332A7138AAAB8828B1BD11BCE47ACFE934887A2B2DC6C7061EF8412B4912925FD5A9CE787C434B3FD5B39FA863EDA542574E22331F98E74F69283A9A8F9330FE597B1EE96E37C8DEBB0E861213F3BF5281F3753CC16B2AF1EAB12540517E0482FDF47C92B66C4CD5FA5C8725956DB4C5F435EFC44D2ABD17A078687DD7716CAC4683729BD6211E0CBADA144F28932906724F3B96501D1A897C088607B522F8C7586DAFC64CB156533A8F +20241129010827 2 6 100 3071 2 F72B9D5B478FC38253834B862A5C515BA6212BAD106C43D243A9D021FF22434E6A1EA03FBACFA23A6FC66FE5C68B40013BA6D15844D35AA2127408DE731CCA98380661EE30E2480E9DB14A8EB484BF564838B45678ECB78800E41E499307253A0E4462C7E119ECAA096D496FF72C5CB823C5C38CC165B9EE0B5307005F9FE72FE34EF3C2EF456A3A4561245680205533E2C2DC31816DDFFB036922109B985F291F7ADDCA11FADD48E7D20C9F8D0E8AE073C4DD7269B1EF46ACC81BE52A053EFE3BEAB1BFA3822A10ABF2C95B27D406BF960FAA48A79D332A7138AAAB8828B1BD11BCE47ACFE934887A2B2DC6C7061EF8412B4912925FD5A9CE787C434B3FD5B39FA863EDA542574E22331F98E74F69283A9A8F9330FE597B1EE96E37C8DEBB0E861213F3BF5281F3753CC16B2AF1EAB12540517E0482FDF47C92B66C4CD5FA5C8725956DB4C5F435EFC44D2ABD17A078687DD7716CAC4683729BD6211E0CBADA144F28932906724F3B96501D1A897C088607B522F8C7586DAFC64CB15733560B +20241129010830 2 6 100 3071 2 F72B9D5B478FC38253834B862A5C515BA6212BAD106C43D243A9D021FF22434E6A1EA03FBACFA23A6FC66FE5C68B40013BA6D15844D35AA2127408DE731CCA98380661EE30E2480E9DB14A8EB484BF564838B45678ECB78800E41E499307253A0E4462C7E119ECAA096D496FF72C5CB823C5C38CC165B9EE0B5307005F9FE72FE34EF3C2EF456A3A4561245680205533E2C2DC31816DDFFB036922109B985F291F7ADDCA11FADD48E7D20C9F8D0E8AE073C4DD7269B1EF46ACC81BE52A053EFE3BEAB1BFA3822A10ABF2C95B27D406BF960FAA48A79D332A7138AAAB8828B1BD11BCE47ACFE934887A2B2DC6C7061EF8412B4912925FD5A9CE787C434B3FD5B39FA863EDA542574E22331F98E74F69283A9A8F9330FE597B1EE96E37C8DEBB0E861213F3BF5281F3753CC16B2AF1EAB12540517E0482FDF47C92B66C4CD5FA5C8725956DB4C5F435EFC44D2ABD17A078687DD7716CAC4683729BD6211E0CBADA144F28932906724F3B96501D1A897C088607B522F8C7586DAFC64CB15735A50B +20241129011308 2 6 100 3071 5 F72B9D5B478FC38253834B862A5C515BA6212BAD106C43D243A9D021FF22434E6A1EA03FBACFA23A6FC66FE5C68B40013BA6D15844D35AA2127408DE731CCA98380661EE30E2480E9DB14A8EB484BF564838B45678ECB78800E41E499307253A0E4462C7E119ECAA096D496FF72C5CB823C5C38CC165B9EE0B5307005F9FE72FE34EF3C2EF456A3A4561245680205533E2C2DC31816DDFFB036922109B985F291F7ADDCA11FADD48E7D20C9F8D0E8AE073C4DD7269B1EF46ACC81BE52A053EFE3BEAB1BFA3822A10ABF2C95B27D406BF960FAA48A79D332A7138AAAB8828B1BD11BCE47ACFE934887A2B2DC6C7061EF8412B4912925FD5A9CE787C434B3FD5B39FA863EDA542574E22331F98E74F69283A9A8F9330FE597B1EE96E37C8DEBB0E861213F3BF5281F3753CC16B2AF1EAB12540517E0482FDF47C92B66C4CD5FA5C8725956DB4C5F435EFC44D2ABD17A078687DD7716CAC4683729BD6211E0CBADA144F28932906724F3B96501D1A897C088607B522F8C7586DAFC64CB15AD92877 +20241129011325 2 6 100 3071 5 F72B9D5B478FC38253834B862A5C515BA6212BAD106C43D243A9D021FF22434E6A1EA03FBACFA23A6FC66FE5C68B40013BA6D15844D35AA2127408DE731CCA98380661EE30E2480E9DB14A8EB484BF564838B45678ECB78800E41E499307253A0E4462C7E119ECAA096D496FF72C5CB823C5C38CC165B9EE0B5307005F9FE72FE34EF3C2EF456A3A4561245680205533E2C2DC31816DDFFB036922109B985F291F7ADDCA11FADD48E7D20C9F8D0E8AE073C4DD7269B1EF46ACC81BE52A053EFE3BEAB1BFA3822A10ABF2C95B27D406BF960FAA48A79D332A7138AAAB8828B1BD11BCE47ACFE934887A2B2DC6C7061EF8412B4912925FD5A9CE787C434B3FD5B39FA863EDA542574E22331F98E74F69283A9A8F9330FE597B1EE96E37C8DEBB0E861213F3BF5281F3753CC16B2AF1EAB12540517E0482FDF47C92B66C4CD5FA5C8725956DB4C5F435EFC44D2ABD17A078687DD7716CAC4683729BD6211E0CBADA144F28932906724F3B96501D1A897C088607B522F8C7586DAFC64CB15B0BC97F +20241129011417 2 6 100 3071 2 F72B9D5B478FC38253834B862A5C515BA6212BAD106C43D243A9D021FF22434E6A1EA03FBACFA23A6FC66FE5C68B40013BA6D15844D35AA2127408DE731CCA98380661EE30E2480E9DB14A8EB484BF564838B45678ECB78800E41E499307253A0E4462C7E119ECAA096D496FF72C5CB823C5C38CC165B9EE0B5307005F9FE72FE34EF3C2EF456A3A4561245680205533E2C2DC31816DDFFB036922109B985F291F7ADDCA11FADD48E7D20C9F8D0E8AE073C4DD7269B1EF46ACC81BE52A053EFE3BEAB1BFA3822A10ABF2C95B27D406BF960FAA48A79D332A7138AAAB8828B1BD11BCE47ACFE934887A2B2DC6C7061EF8412B4912925FD5A9CE787C434B3FD5B39FA863EDA542574E22331F98E74F69283A9A8F9330FE597B1EE96E37C8DEBB0E861213F3BF5281F3753CC16B2AF1EAB12540517E0482FDF47C92B66C4CD5FA5C8725956DB4C5F435EFC44D2ABD17A078687DD7716CAC4683729BD6211E0CBADA144F28932906724F3B96501D1A897C088607B522F8C7586DAFC64CB15BB2F9E3 +20241129011431 2 6 100 3071 2 F72B9D5B478FC38253834B862A5C515BA6212BAD106C43D243A9D021FF22434E6A1EA03FBACFA23A6FC66FE5C68B40013BA6D15844D35AA2127408DE731CCA98380661EE30E2480E9DB14A8EB484BF564838B45678ECB78800E41E499307253A0E4462C7E119ECAA096D496FF72C5CB823C5C38CC165B9EE0B5307005F9FE72FE34EF3C2EF456A3A4561245680205533E2C2DC31816DDFFB036922109B985F291F7ADDCA11FADD48E7D20C9F8D0E8AE073C4DD7269B1EF46ACC81BE52A053EFE3BEAB1BFA3822A10ABF2C95B27D406BF960FAA48A79D332A7138AAAB8828B1BD11BCE47ACFE934887A2B2DC6C7061EF8412B4912925FD5A9CE787C434B3FD5B39FA863EDA542574E22331F98E74F69283A9A8F9330FE597B1EE96E37C8DEBB0E861213F3BF5281F3753CC16B2AF1EAB12540517E0482FDF47C92B66C4CD5FA5C8725956DB4C5F435EFC44D2ABD17A078687DD7716CAC4683729BD6211E0CBADA144F28932906724F3B96501D1A897C088607B522F8C7586DAFC64CB15BDC12E3 +20241129011445 2 6 100 3071 2 F72B9D5B478FC38253834B862A5C515BA6212BAD106C43D243A9D021FF22434E6A1EA03FBACFA23A6FC66FE5C68B40013BA6D15844D35AA2127408DE731CCA98380661EE30E2480E9DB14A8EB484BF564838B45678ECB78800E41E499307253A0E4462C7E119ECAA096D496FF72C5CB823C5C38CC165B9EE0B5307005F9FE72FE34EF3C2EF456A3A4561245680205533E2C2DC31816DDFFB036922109B985F291F7ADDCA11FADD48E7D20C9F8D0E8AE073C4DD7269B1EF46ACC81BE52A053EFE3BEAB1BFA3822A10ABF2C95B27D406BF960FAA48A79D332A7138AAAB8828B1BD11BCE47ACFE934887A2B2DC6C7061EF8412B4912925FD5A9CE787C434B3FD5B39FA863EDA542574E22331F98E74F69283A9A8F9330FE597B1EE96E37C8DEBB0E861213F3BF5281F3753CC16B2AF1EAB12540517E0482FDF47C92B66C4CD5FA5C8725956DB4C5F435EFC44D2ABD17A078687DD7716CAC4683729BD6211E0CBADA144F28932906724F3B96501D1A897C088607B522F8C7586DAFC64CB15C01B8F3 +20241129011511 2 6 100 3071 5 F72B9D5B478FC38253834B862A5C515BA6212BAD106C43D243A9D021FF22434E6A1EA03FBACFA23A6FC66FE5C68B40013BA6D15844D35AA2127408DE731CCA98380661EE30E2480E9DB14A8EB484BF564838B45678ECB78800E41E499307253A0E4462C7E119ECAA096D496FF72C5CB823C5C38CC165B9EE0B5307005F9FE72FE34EF3C2EF456A3A4561245680205533E2C2DC31816DDFFB036922109B985F291F7ADDCA11FADD48E7D20C9F8D0E8AE073C4DD7269B1EF46ACC81BE52A053EFE3BEAB1BFA3822A10ABF2C95B27D406BF960FAA48A79D332A7138AAAB8828B1BD11BCE47ACFE934887A2B2DC6C7061EF8412B4912925FD5A9CE787C434B3FD5B39FA863EDA542574E22331F98E74F69283A9A8F9330FE597B1EE96E37C8DEBB0E861213F3BF5281F3753CC16B2AF1EAB12540517E0482FDF47C92B66C4CD5FA5C8725956DB4C5F435EFC44D2ABD17A078687DD7716CAC4683729BD6211E0CBADA144F28932906724F3B96501D1A897C088607B522F8C7586DAFC64CB15C508C4F +20241129011527 2 6 100 3071 2 F72B9D5B478FC38253834B862A5C515BA6212BAD106C43D243A9D021FF22434E6A1EA03FBACFA23A6FC66FE5C68B40013BA6D15844D35AA2127408DE731CCA98380661EE30E2480E9DB14A8EB484BF564838B45678ECB78800E41E499307253A0E4462C7E119ECAA096D496FF72C5CB823C5C38CC165B9EE0B5307005F9FE72FE34EF3C2EF456A3A4561245680205533E2C2DC31816DDFFB036922109B985F291F7ADDCA11FADD48E7D20C9F8D0E8AE073C4DD7269B1EF46ACC81BE52A053EFE3BEAB1BFA3822A10ABF2C95B27D406BF960FAA48A79D332A7138AAAB8828B1BD11BCE47ACFE934887A2B2DC6C7061EF8412B4912925FD5A9CE787C434B3FD5B39FA863EDA542574E22331F98E74F69283A9A8F9330FE597B1EE96E37C8DEBB0E861213F3BF5281F3753CC16B2AF1EAB12540517E0482FDF47C92B66C4CD5FA5C8725956DB4C5F435EFC44D2ABD17A078687DD7716CAC4683729BD6211E0CBADA144F28932906724F3B96501D1A897C088607B522F8C7586DAFC64CB15C8110EB +20241129011531 2 6 100 3071 2 F72B9D5B478FC38253834B862A5C515BA6212BAD106C43D243A9D021FF22434E6A1EA03FBACFA23A6FC66FE5C68B40013BA6D15844D35AA2127408DE731CCA98380661EE30E2480E9DB14A8EB484BF564838B45678ECB78800E41E499307253A0E4462C7E119ECAA096D496FF72C5CB823C5C38CC165B9EE0B5307005F9FE72FE34EF3C2EF456A3A4561245680205533E2C2DC31816DDFFB036922109B985F291F7ADDCA11FADD48E7D20C9F8D0E8AE073C4DD7269B1EF46ACC81BE52A053EFE3BEAB1BFA3822A10ABF2C95B27D406BF960FAA48A79D332A7138AAAB8828B1BD11BCE47ACFE934887A2B2DC6C7061EF8412B4912925FD5A9CE787C434B3FD5B39FA863EDA542574E22331F98E74F69283A9A8F9330FE597B1EE96E37C8DEBB0E861213F3BF5281F3753CC16B2AF1EAB12540517E0482FDF47C92B66C4CD5FA5C8725956DB4C5F435EFC44D2ABD17A078687DD7716CAC4683729BD6211E0CBADA144F28932906724F3B96501D1A897C088607B522F8C7586DAFC64CB15C85C703 +20241129011741 2 6 100 3071 2 F72B9D5B478FC38253834B862A5C515BA6212BAD106C43D243A9D021FF22434E6A1EA03FBACFA23A6FC66FE5C68B40013BA6D15844D35AA2127408DE731CCA98380661EE30E2480E9DB14A8EB484BF564838B45678ECB78800E41E499307253A0E4462C7E119ECAA096D496FF72C5CB823C5C38CC165B9EE0B5307005F9FE72FE34EF3C2EF456A3A4561245680205533E2C2DC31816DDFFB036922109B985F291F7ADDCA11FADD48E7D20C9F8D0E8AE073C4DD7269B1EF46ACC81BE52A053EFE3BEAB1BFA3822A10ABF2C95B27D406BF960FAA48A79D332A7138AAAB8828B1BD11BCE47ACFE934887A2B2DC6C7061EF8412B4912925FD5A9CE787C434B3FD5B39FA863EDA542574E22331F98E74F69283A9A8F9330FE597B1EE96E37C8DEBB0E861213F3BF5281F3753CC16B2AF1EAB12540517E0482FDF47C92B66C4CD5FA5C8725956DB4C5F435EFC44D2ABD17A078687DD7716CAC4683729BD6211E0CBADA144F28932906724F3B96501D1A897C088607B522F8C7586DAFC64CB15E32BC9B +20241129011800 2 6 100 3071 2 F72B9D5B478FC38253834B862A5C515BA6212BAD106C43D243A9D021FF22434E6A1EA03FBACFA23A6FC66FE5C68B40013BA6D15844D35AA2127408DE731CCA98380661EE30E2480E9DB14A8EB484BF564838B45678ECB78800E41E499307253A0E4462C7E119ECAA096D496FF72C5CB823C5C38CC165B9EE0B5307005F9FE72FE34EF3C2EF456A3A4561245680205533E2C2DC31816DDFFB036922109B985F291F7ADDCA11FADD48E7D20C9F8D0E8AE073C4DD7269B1EF46ACC81BE52A053EFE3BEAB1BFA3822A10ABF2C95B27D406BF960FAA48A79D332A7138AAAB8828B1BD11BCE47ACFE934887A2B2DC6C7061EF8412B4912925FD5A9CE787C434B3FD5B39FA863EDA542574E22331F98E74F69283A9A8F9330FE597B1EE96E37C8DEBB0E861213F3BF5281F3753CC16B2AF1EAB12540517E0482FDF47C92B66C4CD5FA5C8725956DB4C5F435EFC44D2ABD17A078687DD7716CAC4683729BD6211E0CBADA144F28932906724F3B96501D1A897C088607B522F8C7586DAFC64CB15E6A8F93 +20241129011821 2 6 100 3071 5 F72B9D5B478FC38253834B862A5C515BA6212BAD106C43D243A9D021FF22434E6A1EA03FBACFA23A6FC66FE5C68B40013BA6D15844D35AA2127408DE731CCA98380661EE30E2480E9DB14A8EB484BF564838B45678ECB78800E41E499307253A0E4462C7E119ECAA096D496FF72C5CB823C5C38CC165B9EE0B5307005F9FE72FE34EF3C2EF456A3A4561245680205533E2C2DC31816DDFFB036922109B985F291F7ADDCA11FADD48E7D20C9F8D0E8AE073C4DD7269B1EF46ACC81BE52A053EFE3BEAB1BFA3822A10ABF2C95B27D406BF960FAA48A79D332A7138AAAB8828B1BD11BCE47ACFE934887A2B2DC6C7061EF8412B4912925FD5A9CE787C434B3FD5B39FA863EDA542574E22331F98E74F69283A9A8F9330FE597B1EE96E37C8DEBB0E861213F3BF5281F3753CC16B2AF1EAB12540517E0482FDF47C92B66C4CD5FA5C8725956DB4C5F435EFC44D2ABD17A078687DD7716CAC4683729BD6211E0CBADA144F28932906724F3B96501D1A897C088607B522F8C7586DAFC64CB15EACC9EF +20241129011823 2 6 100 3071 5 F72B9D5B478FC38253834B862A5C515BA6212BAD106C43D243A9D021FF22434E6A1EA03FBACFA23A6FC66FE5C68B40013BA6D15844D35AA2127408DE731CCA98380661EE30E2480E9DB14A8EB484BF564838B45678ECB78800E41E499307253A0E4462C7E119ECAA096D496FF72C5CB823C5C38CC165B9EE0B5307005F9FE72FE34EF3C2EF456A3A4561245680205533E2C2DC31816DDFFB036922109B985F291F7ADDCA11FADD48E7D20C9F8D0E8AE073C4DD7269B1EF46ACC81BE52A053EFE3BEAB1BFA3822A10ABF2C95B27D406BF960FAA48A79D332A7138AAAB8828B1BD11BCE47ACFE934887A2B2DC6C7061EF8412B4912925FD5A9CE787C434B3FD5B39FA863EDA542574E22331F98E74F69283A9A8F9330FE597B1EE96E37C8DEBB0E861213F3BF5281F3753CC16B2AF1EAB12540517E0482FDF47C92B66C4CD5FA5C8725956DB4C5F435EFC44D2ABD17A078687DD7716CAC4683729BD6211E0CBADA144F28932906724F3B96501D1A897C088607B522F8C7586DAFC64CB15EAE50DF +20241129011852 2 6 100 3071 2 F72B9D5B478FC38253834B862A5C515BA6212BAD106C43D243A9D021FF22434E6A1EA03FBACFA23A6FC66FE5C68B40013BA6D15844D35AA2127408DE731CCA98380661EE30E2480E9DB14A8EB484BF564838B45678ECB78800E41E499307253A0E4462C7E119ECAA096D496FF72C5CB823C5C38CC165B9EE0B5307005F9FE72FE34EF3C2EF456A3A4561245680205533E2C2DC31816DDFFB036922109B985F291F7ADDCA11FADD48E7D20C9F8D0E8AE073C4DD7269B1EF46ACC81BE52A053EFE3BEAB1BFA3822A10ABF2C95B27D406BF960FAA48A79D332A7138AAAB8828B1BD11BCE47ACFE934887A2B2DC6C7061EF8412B4912925FD5A9CE787C434B3FD5B39FA863EDA542574E22331F98E74F69283A9A8F9330FE597B1EE96E37C8DEBB0E861213F3BF5281F3753CC16B2AF1EAB12540517E0482FDF47C92B66C4CD5FA5C8725956DB4C5F435EFC44D2ABD17A078687DD7716CAC4683729BD6211E0CBADA144F28932906724F3B96501D1A897C088607B522F8C7586DAFC64CB15F060CCB +20241129011901 2 6 100 3071 2 F72B9D5B478FC38253834B862A5C515BA6212BAD106C43D243A9D021FF22434E6A1EA03FBACFA23A6FC66FE5C68B40013BA6D15844D35AA2127408DE731CCA98380661EE30E2480E9DB14A8EB484BF564838B45678ECB78800E41E499307253A0E4462C7E119ECAA096D496FF72C5CB823C5C38CC165B9EE0B5307005F9FE72FE34EF3C2EF456A3A4561245680205533E2C2DC31816DDFFB036922109B985F291F7ADDCA11FADD48E7D20C9F8D0E8AE073C4DD7269B1EF46ACC81BE52A053EFE3BEAB1BFA3822A10ABF2C95B27D406BF960FAA48A79D332A7138AAAB8828B1BD11BCE47ACFE934887A2B2DC6C7061EF8412B4912925FD5A9CE787C434B3FD5B39FA863EDA542574E22331F98E74F69283A9A8F9330FE597B1EE96E37C8DEBB0E861213F3BF5281F3753CC16B2AF1EAB12540517E0482FDF47C92B66C4CD5FA5C8725956DB4C5F435EFC44D2ABD17A078687DD7716CAC4683729BD6211E0CBADA144F28932906724F3B96501D1A897C088607B522F8C7586DAFC64CB15F1D181B +20241129011909 2 6 100 3071 2 F72B9D5B478FC38253834B862A5C515BA6212BAD106C43D243A9D021FF22434E6A1EA03FBACFA23A6FC66FE5C68B40013BA6D15844D35AA2127408DE731CCA98380661EE30E2480E9DB14A8EB484BF564838B45678ECB78800E41E499307253A0E4462C7E119ECAA096D496FF72C5CB823C5C38CC165B9EE0B5307005F9FE72FE34EF3C2EF456A3A4561245680205533E2C2DC31816DDFFB036922109B985F291F7ADDCA11FADD48E7D20C9F8D0E8AE073C4DD7269B1EF46ACC81BE52A053EFE3BEAB1BFA3822A10ABF2C95B27D406BF960FAA48A79D332A7138AAAB8828B1BD11BCE47ACFE934887A2B2DC6C7061EF8412B4912925FD5A9CE787C434B3FD5B39FA863EDA542574E22331F98E74F69283A9A8F9330FE597B1EE96E37C8DEBB0E861213F3BF5281F3753CC16B2AF1EAB12540517E0482FDF47C92B66C4CD5FA5C8725956DB4C5F435EFC44D2ABD17A078687DD7716CAC4683729BD6211E0CBADA144F28932906724F3B96501D1A897C088607B522F8C7586DAFC64CB15F313CBB +20241129011934 2 6 100 3071 2 F72B9D5B478FC38253834B862A5C515BA6212BAD106C43D243A9D021FF22434E6A1EA03FBACFA23A6FC66FE5C68B40013BA6D15844D35AA2127408DE731CCA98380661EE30E2480E9DB14A8EB484BF564838B45678ECB78800E41E499307253A0E4462C7E119ECAA096D496FF72C5CB823C5C38CC165B9EE0B5307005F9FE72FE34EF3C2EF456A3A4561245680205533E2C2DC31816DDFFB036922109B985F291F7ADDCA11FADD48E7D20C9F8D0E8AE073C4DD7269B1EF46ACC81BE52A053EFE3BEAB1BFA3822A10ABF2C95B27D406BF960FAA48A79D332A7138AAAB8828B1BD11BCE47ACFE934887A2B2DC6C7061EF8412B4912925FD5A9CE787C434B3FD5B39FA863EDA542574E22331F98E74F69283A9A8F9330FE597B1EE96E37C8DEBB0E861213F3BF5281F3753CC16B2AF1EAB12540517E0482FDF47C92B66C4CD5FA5C8725956DB4C5F435EFC44D2ABD17A078687DD7716CAC4683729BD6211E0CBADA144F28932906724F3B96501D1A897C088607B522F8C7586DAFC64CB15F7E3BAB +20241129011958 2 6 100 3071 2 F72B9D5B478FC38253834B862A5C515BA6212BAD106C43D243A9D021FF22434E6A1EA03FBACFA23A6FC66FE5C68B40013BA6D15844D35AA2127408DE731CCA98380661EE30E2480E9DB14A8EB484BF564838B45678ECB78800E41E499307253A0E4462C7E119ECAA096D496FF72C5CB823C5C38CC165B9EE0B5307005F9FE72FE34EF3C2EF456A3A4561245680205533E2C2DC31816DDFFB036922109B985F291F7ADDCA11FADD48E7D20C9F8D0E8AE073C4DD7269B1EF46ACC81BE52A053EFE3BEAB1BFA3822A10ABF2C95B27D406BF960FAA48A79D332A7138AAAB8828B1BD11BCE47ACFE934887A2B2DC6C7061EF8412B4912925FD5A9CE787C434B3FD5B39FA863EDA542574E22331F98E74F69283A9A8F9330FE597B1EE96E37C8DEBB0E861213F3BF5281F3753CC16B2AF1EAB12540517E0482FDF47C92B66C4CD5FA5C8725956DB4C5F435EFC44D2ABD17A078687DD7716CAC4683729BD6211E0CBADA144F28932906724F3B96501D1A897C088607B522F8C7586DAFC64CB15FCAB1D3 +20241129012819 2 6 100 4095 5 D14DC7A20FAA787E8E505E1CCA5C3EC8C5344CE26B9E5E776858C7048EECCB2CE278073BA42E21E4512A91D9A94F6460E86A914FC8D560A29DDC6B3E45CA1F9E8C5C52057BAF6A992E0C04192CEDF05010493D9CED8F97D3891C7DB13865BCD4BC19EA746AFB39E7AC2D60A32D9B77EECFFA53E7022137B7587E5D18E2B100845108104A79B878405B8900A0837BE74494F45DF726B88990607580414CEA1358A78BF832447919460F37395E69BC30E81983D60BB71D4E86164317138B99B545416467AA1F8592A16CEA1B050D2554487A749408A8339FFCA98A5F23D4EEF7A4254C6E56BFD6B95AD3C822B83324BEC5DD85A7064C6233899F7C6D00749D9DEDBAD9ED72CCC9CF154EF3989752DF907B24E587CD6B29A22846CD1B9623A3AEF69D191E8C048046FBCA2BC2C2A0883C8738F72D612745419080B7D72D8EC2E696CF5CB5EB6F23A9BBFF4BDD129970E881DBAA81E2F1A1445C773D4445ED516D1D954C64593DF72B7B31810B7493B8334F57E79FB26554EE1B4E7B7BDAA2C707D8E4798549DB60AE0A064CA8C6AA36021EB1657E72810E676D0F312325F2FAF956DC336D6B8E1496553362292D98225D61A74827C43FD4B4E0242B19FECBA7C102940C24AC56BB287C739608441EAA2EAA6DE0D1323E6D45204A1FF07BC3D3A48F954597EE865531D8A32C1DC2A3A48C8A0D47BE16919C3DF9E0514CE61ABEADA7 +20241129013011 2 6 100 4095 2 D14DC7A20FAA787E8E505E1CCA5C3EC8C5344CE26B9E5E776858C7048EECCB2CE278073BA42E21E4512A91D9A94F6460E86A914FC8D560A29DDC6B3E45CA1F9E8C5C52057BAF6A992E0C04192CEDF05010493D9CED8F97D3891C7DB13865BCD4BC19EA746AFB39E7AC2D60A32D9B77EECFFA53E7022137B7587E5D18E2B100845108104A79B878405B8900A0837BE74494F45DF726B88990607580414CEA1358A78BF832447919460F37395E69BC30E81983D60BB71D4E86164317138B99B545416467AA1F8592A16CEA1B050D2554487A749408A8339FFCA98A5F23D4EEF7A4254C6E56BFD6B95AD3C822B83324BEC5DD85A7064C6233899F7C6D00749D9DEDBAD9ED72CCC9CF154EF3989752DF907B24E587CD6B29A22846CD1B9623A3AEF69D191E8C048046FBCA2BC2C2A0883C8738F72D612745419080B7D72D8EC2E696CF5CB5EB6F23A9BBFF4BDD129970E881DBAA81E2F1A1445C773D4445ED516D1D954C64593DF72B7B31810B7493B8334F57E79FB26554EE1B4E7B7BDAA2C707D8E4798549DB60AE0A064CA8C6AA36021EB1657E72810E676D0F312325F2FAF956DC336D6B8E1496553362292D98225D61A74827C43FD4B4E0242B19FECBA7C102940C24AC56BB287C739608441EAA2EAA6DE0D1323E6D45204A1FF07BC3D3A48F954597EE865531D8A32C1DC2A3A48C8A0D47BE16919C3DF9E0514CE61B67DAEB +20241129013110 2 6 100 4095 2 D14DC7A20FAA787E8E505E1CCA5C3EC8C5344CE26B9E5E776858C7048EECCB2CE278073BA42E21E4512A91D9A94F6460E86A914FC8D560A29DDC6B3E45CA1F9E8C5C52057BAF6A992E0C04192CEDF05010493D9CED8F97D3891C7DB13865BCD4BC19EA746AFB39E7AC2D60A32D9B77EECFFA53E7022137B7587E5D18E2B100845108104A79B878405B8900A0837BE74494F45DF726B88990607580414CEA1358A78BF832447919460F37395E69BC30E81983D60BB71D4E86164317138B99B545416467AA1F8592A16CEA1B050D2554487A749408A8339FFCA98A5F23D4EEF7A4254C6E56BFD6B95AD3C822B83324BEC5DD85A7064C6233899F7C6D00749D9DEDBAD9ED72CCC9CF154EF3989752DF907B24E587CD6B29A22846CD1B9623A3AEF69D191E8C048046FBCA2BC2C2A0883C8738F72D612745419080B7D72D8EC2E696CF5CB5EB6F23A9BBFF4BDD129970E881DBAA81E2F1A1445C773D4445ED516D1D954C64593DF72B7B31810B7493B8334F57E79FB26554EE1B4E7B7BDAA2C707D8E4798549DB60AE0A064CA8C6AA36021EB1657E72810E676D0F312325F2FAF956DC336D6B8E1496553362292D98225D61A74827C43FD4B4E0242B19FECBA7C102940C24AC56BB287C739608441EAA2EAA6DE0D1323E6D45204A1FF07BC3D3A48F954597EE865531D8A32C1DC2A3A48C8A0D47BE16919C3DF9E0514CE61BBE4D2B +20241129013508 2 6 100 4095 5 D14DC7A20FAA787E8E505E1CCA5C3EC8C5344CE26B9E5E776858C7048EECCB2CE278073BA42E21E4512A91D9A94F6460E86A914FC8D560A29DDC6B3E45CA1F9E8C5C52057BAF6A992E0C04192CEDF05010493D9CED8F97D3891C7DB13865BCD4BC19EA746AFB39E7AC2D60A32D9B77EECFFA53E7022137B7587E5D18E2B100845108104A79B878405B8900A0837BE74494F45DF726B88990607580414CEA1358A78BF832447919460F37395E69BC30E81983D60BB71D4E86164317138B99B545416467AA1F8592A16CEA1B050D2554487A749408A8339FFCA98A5F23D4EEF7A4254C6E56BFD6B95AD3C822B83324BEC5DD85A7064C6233899F7C6D00749D9DEDBAD9ED72CCC9CF154EF3989752DF907B24E587CD6B29A22846CD1B9623A3AEF69D191E8C048046FBCA2BC2C2A0883C8738F72D612745419080B7D72D8EC2E696CF5CB5EB6F23A9BBFF4BDD129970E881DBAA81E2F1A1445C773D4445ED516D1D954C64593DF72B7B31810B7493B8334F57E79FB26554EE1B4E7B7BDAA2C707D8E4798549DB60AE0A064CA8C6AA36021EB1657E72810E676D0F312325F2FAF956DC336D6B8E1496553362292D98225D61A74827C43FD4B4E0242B19FECBA7C102940C24AC56BB287C739608441EAA2EAA6DE0D1323E6D45204A1FF07BC3D3A48F954597EE865531D8A32C1DC2A3A48C8A0D47BE16919C3DF9E0514CE61D3A05EF +20241129013753 2 6 100 4095 5 D14DC7A20FAA787E8E505E1CCA5C3EC8C5344CE26B9E5E776858C7048EECCB2CE278073BA42E21E4512A91D9A94F6460E86A914FC8D560A29DDC6B3E45CA1F9E8C5C52057BAF6A992E0C04192CEDF05010493D9CED8F97D3891C7DB13865BCD4BC19EA746AFB39E7AC2D60A32D9B77EECFFA53E7022137B7587E5D18E2B100845108104A79B878405B8900A0837BE74494F45DF726B88990607580414CEA1358A78BF832447919460F37395E69BC30E81983D60BB71D4E86164317138B99B545416467AA1F8592A16CEA1B050D2554487A749408A8339FFCA98A5F23D4EEF7A4254C6E56BFD6B95AD3C822B83324BEC5DD85A7064C6233899F7C6D00749D9DEDBAD9ED72CCC9CF154EF3989752DF907B24E587CD6B29A22846CD1B9623A3AEF69D191E8C048046FBCA2BC2C2A0883C8738F72D612745419080B7D72D8EC2E696CF5CB5EB6F23A9BBFF4BDD129970E881DBAA81E2F1A1445C773D4445ED516D1D954C64593DF72B7B31810B7493B8334F57E79FB26554EE1B4E7B7BDAA2C707D8E4798549DB60AE0A064CA8C6AA36021EB1657E72810E676D0F312325F2FAF956DC336D6B8E1496553362292D98225D61A74827C43FD4B4E0242B19FECBA7C102940C24AC56BB287C739608441EAA2EAA6DE0D1323E6D45204A1FF07BC3D3A48F954597EE865531D8A32C1DC2A3A48C8A0D47BE16919C3DF9E0514CE61E425677 +20241129014404 2 6 100 4095 5 D14DC7A20FAA787E8E505E1CCA5C3EC8C5344CE26B9E5E776858C7048EECCB2CE278073BA42E21E4512A91D9A94F6460E86A914FC8D560A29DDC6B3E45CA1F9E8C5C52057BAF6A992E0C04192CEDF05010493D9CED8F97D3891C7DB13865BCD4BC19EA746AFB39E7AC2D60A32D9B77EECFFA53E7022137B7587E5D18E2B100845108104A79B878405B8900A0837BE74494F45DF726B88990607580414CEA1358A78BF832447919460F37395E69BC30E81983D60BB71D4E86164317138B99B545416467AA1F8592A16CEA1B050D2554487A749408A8339FFCA98A5F23D4EEF7A4254C6E56BFD6B95AD3C822B83324BEC5DD85A7064C6233899F7C6D00749D9DEDBAD9ED72CCC9CF154EF3989752DF907B24E587CD6B29A22846CD1B9623A3AEF69D191E8C048046FBCA2BC2C2A0883C8738F72D612745419080B7D72D8EC2E696CF5CB5EB6F23A9BBFF4BDD129970E881DBAA81E2F1A1445C773D4445ED516D1D954C64593DF72B7B31810B7493B8334F57E79FB26554EE1B4E7B7BDAA2C707D8E4798549DB60AE0A064CA8C6AA36021EB1657E72810E676D0F312325F2FAF956DC336D6B8E1496553362292D98225D61A74827C43FD4B4E0242B19FECBA7C102940C24AC56BB287C739608441EAA2EAA6DE0D1323E6D45204A1FF07BC3D3A48F954597EE865531D8A32C1DC2A3A48C8A0D47BE16919C3DF9E0514CE6208D8717 +20241129014416 2 6 100 4095 2 D14DC7A20FAA787E8E505E1CCA5C3EC8C5344CE26B9E5E776858C7048EECCB2CE278073BA42E21E4512A91D9A94F6460E86A914FC8D560A29DDC6B3E45CA1F9E8C5C52057BAF6A992E0C04192CEDF05010493D9CED8F97D3891C7DB13865BCD4BC19EA746AFB39E7AC2D60A32D9B77EECFFA53E7022137B7587E5D18E2B100845108104A79B878405B8900A0837BE74494F45DF726B88990607580414CEA1358A78BF832447919460F37395E69BC30E81983D60BB71D4E86164317138B99B545416467AA1F8592A16CEA1B050D2554487A749408A8339FFCA98A5F23D4EEF7A4254C6E56BFD6B95AD3C822B83324BEC5DD85A7064C6233899F7C6D00749D9DEDBAD9ED72CCC9CF154EF3989752DF907B24E587CD6B29A22846CD1B9623A3AEF69D191E8C048046FBCA2BC2C2A0883C8738F72D612745419080B7D72D8EC2E696CF5CB5EB6F23A9BBFF4BDD129970E881DBAA81E2F1A1445C773D4445ED516D1D954C64593DF72B7B31810B7493B8334F57E79FB26554EE1B4E7B7BDAA2C707D8E4798549DB60AE0A064CA8C6AA36021EB1657E72810E676D0F312325F2FAF956DC336D6B8E1496553362292D98225D61A74827C43FD4B4E0242B19FECBA7C102940C24AC56BB287C739608441EAA2EAA6DE0D1323E6D45204A1FF07BC3D3A48F954597EE865531D8A32C1DC2A3A48C8A0D47BE16919C3DF9E0514CE6209BD93B +20241129014459 2 6 100 4095 5 D14DC7A20FAA787E8E505E1CCA5C3EC8C5344CE26B9E5E776858C7048EECCB2CE278073BA42E21E4512A91D9A94F6460E86A914FC8D560A29DDC6B3E45CA1F9E8C5C52057BAF6A992E0C04192CEDF05010493D9CED8F97D3891C7DB13865BCD4BC19EA746AFB39E7AC2D60A32D9B77EECFFA53E7022137B7587E5D18E2B100845108104A79B878405B8900A0837BE74494F45DF726B88990607580414CEA1358A78BF832447919460F37395E69BC30E81983D60BB71D4E86164317138B99B545416467AA1F8592A16CEA1B050D2554487A749408A8339FFCA98A5F23D4EEF7A4254C6E56BFD6B95AD3C822B83324BEC5DD85A7064C6233899F7C6D00749D9DEDBAD9ED72CCC9CF154EF3989752DF907B24E587CD6B29A22846CD1B9623A3AEF69D191E8C048046FBCA2BC2C2A0883C8738F72D612745419080B7D72D8EC2E696CF5CB5EB6F23A9BBFF4BDD129970E881DBAA81E2F1A1445C773D4445ED516D1D954C64593DF72B7B31810B7493B8334F57E79FB26554EE1B4E7B7BDAA2C707D8E4798549DB60AE0A064CA8C6AA36021EB1657E72810E676D0F312325F2FAF956DC336D6B8E1496553362292D98225D61A74827C43FD4B4E0242B19FECBA7C102940C24AC56BB287C739608441EAA2EAA6DE0D1323E6D45204A1FF07BC3D3A48F954597EE865531D8A32C1DC2A3A48C8A0D47BE16919C3DF9E0514CE620D787FF +20241129015136 2 6 100 4095 5 D14DC7A20FAA787E8E505E1CCA5C3EC8C5344CE26B9E5E776858C7048EECCB2CE278073BA42E21E4512A91D9A94F6460E86A914FC8D560A29DDC6B3E45CA1F9E8C5C52057BAF6A992E0C04192CEDF05010493D9CED8F97D3891C7DB13865BCD4BC19EA746AFB39E7AC2D60A32D9B77EECFFA53E7022137B7587E5D18E2B100845108104A79B878405B8900A0837BE74494F45DF726B88990607580414CEA1358A78BF832447919460F37395E69BC30E81983D60BB71D4E86164317138B99B545416467AA1F8592A16CEA1B050D2554487A749408A8339FFCA98A5F23D4EEF7A4254C6E56BFD6B95AD3C822B83324BEC5DD85A7064C6233899F7C6D00749D9DEDBAD9ED72CCC9CF154EF3989752DF907B24E587CD6B29A22846CD1B9623A3AEF69D191E8C048046FBCA2BC2C2A0883C8738F72D612745419080B7D72D8EC2E696CF5CB5EB6F23A9BBFF4BDD129970E881DBAA81E2F1A1445C773D4445ED516D1D954C64593DF72B7B31810B7493B8334F57E79FB26554EE1B4E7B7BDAA2C707D8E4798549DB60AE0A064CA8C6AA36021EB1657E72810E676D0F312325F2FAF956DC336D6B8E1496553362292D98225D61A74827C43FD4B4E0242B19FECBA7C102940C24AC56BB287C739608441EAA2EAA6DE0D1323E6D45204A1FF07BC3D3A48F954597EE865531D8A32C1DC2A3A48C8A0D47BE16919C3DF9E0514CE6235DF3D7 +20241129015320 2 6 100 4095 5 D14DC7A20FAA787E8E505E1CCA5C3EC8C5344CE26B9E5E776858C7048EECCB2CE278073BA42E21E4512A91D9A94F6460E86A914FC8D560A29DDC6B3E45CA1F9E8C5C52057BAF6A992E0C04192CEDF05010493D9CED8F97D3891C7DB13865BCD4BC19EA746AFB39E7AC2D60A32D9B77EECFFA53E7022137B7587E5D18E2B100845108104A79B878405B8900A0837BE74494F45DF726B88990607580414CEA1358A78BF832447919460F37395E69BC30E81983D60BB71D4E86164317138B99B545416467AA1F8592A16CEA1B050D2554487A749408A8339FFCA98A5F23D4EEF7A4254C6E56BFD6B95AD3C822B83324BEC5DD85A7064C6233899F7C6D00749D9DEDBAD9ED72CCC9CF154EF3989752DF907B24E587CD6B29A22846CD1B9623A3AEF69D191E8C048046FBCA2BC2C2A0883C8738F72D612745419080B7D72D8EC2E696CF5CB5EB6F23A9BBFF4BDD129970E881DBAA81E2F1A1445C773D4445ED516D1D954C64593DF72B7B31810B7493B8334F57E79FB26554EE1B4E7B7BDAA2C707D8E4798549DB60AE0A064CA8C6AA36021EB1657E72810E676D0F312325F2FAF956DC336D6B8E1496553362292D98225D61A74827C43FD4B4E0242B19FECBA7C102940C24AC56BB287C739608441EAA2EAA6DE0D1323E6D45204A1FF07BC3D3A48F954597EE865531D8A32C1DC2A3A48C8A0D47BE16919C3DF9E0514CE6240443EF +20241129015547 2 6 100 4095 5 D14DC7A20FAA787E8E505E1CCA5C3EC8C5344CE26B9E5E776858C7048EECCB2CE278073BA42E21E4512A91D9A94F6460E86A914FC8D560A29DDC6B3E45CA1F9E8C5C52057BAF6A992E0C04192CEDF05010493D9CED8F97D3891C7DB13865BCD4BC19EA746AFB39E7AC2D60A32D9B77EECFFA53E7022137B7587E5D18E2B100845108104A79B878405B8900A0837BE74494F45DF726B88990607580414CEA1358A78BF832447919460F37395E69BC30E81983D60BB71D4E86164317138B99B545416467AA1F8592A16CEA1B050D2554487A749408A8339FFCA98A5F23D4EEF7A4254C6E56BFD6B95AD3C822B83324BEC5DD85A7064C6233899F7C6D00749D9DEDBAD9ED72CCC9CF154EF3989752DF907B24E587CD6B29A22846CD1B9623A3AEF69D191E8C048046FBCA2BC2C2A0883C8738F72D612745419080B7D72D8EC2E696CF5CB5EB6F23A9BBFF4BDD129970E881DBAA81E2F1A1445C773D4445ED516D1D954C64593DF72B7B31810B7493B8334F57E79FB26554EE1B4E7B7BDAA2C707D8E4798549DB60AE0A064CA8C6AA36021EB1657E72810E676D0F312325F2FAF956DC336D6B8E1496553362292D98225D61A74827C43FD4B4E0242B19FECBA7C102940C24AC56BB287C739608441EAA2EAA6DE0D1323E6D45204A1FF07BC3D3A48F954597EE865531D8A32C1DC2A3A48C8A0D47BE16919C3DF9E0514CE624F1AF5F +20241129015908 2 6 100 4095 2 D14DC7A20FAA787E8E505E1CCA5C3EC8C5344CE26B9E5E776858C7048EECCB2CE278073BA42E21E4512A91D9A94F6460E86A914FC8D560A29DDC6B3E45CA1F9E8C5C52057BAF6A992E0C04192CEDF05010493D9CED8F97D3891C7DB13865BCD4BC19EA746AFB39E7AC2D60A32D9B77EECFFA53E7022137B7587E5D18E2B100845108104A79B878405B8900A0837BE74494F45DF726B88990607580414CEA1358A78BF832447919460F37395E69BC30E81983D60BB71D4E86164317138B99B545416467AA1F8592A16CEA1B050D2554487A749408A8339FFCA98A5F23D4EEF7A4254C6E56BFD6B95AD3C822B83324BEC5DD85A7064C6233899F7C6D00749D9DEDBAD9ED72CCC9CF154EF3989752DF907B24E587CD6B29A22846CD1B9623A3AEF69D191E8C048046FBCA2BC2C2A0883C8738F72D612745419080B7D72D8EC2E696CF5CB5EB6F23A9BBFF4BDD129970E881DBAA81E2F1A1445C773D4445ED516D1D954C64593DF72B7B31810B7493B8334F57E79FB26554EE1B4E7B7BDAA2C707D8E4798549DB60AE0A064CA8C6AA36021EB1657E72810E676D0F312325F2FAF956DC336D6B8E1496553362292D98225D61A74827C43FD4B4E0242B19FECBA7C102940C24AC56BB287C739608441EAA2EAA6DE0D1323E6D45204A1FF07BC3D3A48F954597EE865531D8A32C1DC2A3A48C8A0D47BE16919C3DF9E0514CE626346E0B +20241129020133 2 6 100 4095 2 D14DC7A20FAA787E8E505E1CCA5C3EC8C5344CE26B9E5E776858C7048EECCB2CE278073BA42E21E4512A91D9A94F6460E86A914FC8D560A29DDC6B3E45CA1F9E8C5C52057BAF6A992E0C04192CEDF05010493D9CED8F97D3891C7DB13865BCD4BC19EA746AFB39E7AC2D60A32D9B77EECFFA53E7022137B7587E5D18E2B100845108104A79B878405B8900A0837BE74494F45DF726B88990607580414CEA1358A78BF832447919460F37395E69BC30E81983D60BB71D4E86164317138B99B545416467AA1F8592A16CEA1B050D2554487A749408A8339FFCA98A5F23D4EEF7A4254C6E56BFD6B95AD3C822B83324BEC5DD85A7064C6233899F7C6D00749D9DEDBAD9ED72CCC9CF154EF3989752DF907B24E587CD6B29A22846CD1B9623A3AEF69D191E8C048046FBCA2BC2C2A0883C8738F72D612745419080B7D72D8EC2E696CF5CB5EB6F23A9BBFF4BDD129970E881DBAA81E2F1A1445C773D4445ED516D1D954C64593DF72B7B31810B7493B8334F57E79FB26554EE1B4E7B7BDAA2C707D8E4798549DB60AE0A064CA8C6AA36021EB1657E72810E676D0F312325F2FAF956DC336D6B8E1496553362292D98225D61A74827C43FD4B4E0242B19FECBA7C102940C24AC56BB287C739608441EAA2EAA6DE0D1323E6D45204A1FF07BC3D3A48F954597EE865531D8A32C1DC2A3A48C8A0D47BE16919C3DF9E0514CE6271DA71B +20241129020353 2 6 100 4095 2 D14DC7A20FAA787E8E505E1CCA5C3EC8C5344CE26B9E5E776858C7048EECCB2CE278073BA42E21E4512A91D9A94F6460E86A914FC8D560A29DDC6B3E45CA1F9E8C5C52057BAF6A992E0C04192CEDF05010493D9CED8F97D3891C7DB13865BCD4BC19EA746AFB39E7AC2D60A32D9B77EECFFA53E7022137B7587E5D18E2B100845108104A79B878405B8900A0837BE74494F45DF726B88990607580414CEA1358A78BF832447919460F37395E69BC30E81983D60BB71D4E86164317138B99B545416467AA1F8592A16CEA1B050D2554487A749408A8339FFCA98A5F23D4EEF7A4254C6E56BFD6B95AD3C822B83324BEC5DD85A7064C6233899F7C6D00749D9DEDBAD9ED72CCC9CF154EF3989752DF907B24E587CD6B29A22846CD1B9623A3AEF69D191E8C048046FBCA2BC2C2A0883C8738F72D612745419080B7D72D8EC2E696CF5CB5EB6F23A9BBFF4BDD129970E881DBAA81E2F1A1445C773D4445ED516D1D954C64593DF72B7B31810B7493B8334F57E79FB26554EE1B4E7B7BDAA2C707D8E4798549DB60AE0A064CA8C6AA36021EB1657E72810E676D0F312325F2FAF956DC336D6B8E1496553362292D98225D61A74827C43FD4B4E0242B19FECBA7C102940C24AC56BB287C739608441EAA2EAA6DE0D1323E6D45204A1FF07BC3D3A48F954597EE865531D8A32C1DC2A3A48C8A0D47BE16919C3DF9E0514CE627F5147B +20241129020617 2 6 100 4095 2 D14DC7A20FAA787E8E505E1CCA5C3EC8C5344CE26B9E5E776858C7048EECCB2CE278073BA42E21E4512A91D9A94F6460E86A914FC8D560A29DDC6B3E45CA1F9E8C5C52057BAF6A992E0C04192CEDF05010493D9CED8F97D3891C7DB13865BCD4BC19EA746AFB39E7AC2D60A32D9B77EECFFA53E7022137B7587E5D18E2B100845108104A79B878405B8900A0837BE74494F45DF726B88990607580414CEA1358A78BF832447919460F37395E69BC30E81983D60BB71D4E86164317138B99B545416467AA1F8592A16CEA1B050D2554487A749408A8339FFCA98A5F23D4EEF7A4254C6E56BFD6B95AD3C822B83324BEC5DD85A7064C6233899F7C6D00749D9DEDBAD9ED72CCC9CF154EF3989752DF907B24E587CD6B29A22846CD1B9623A3AEF69D191E8C048046FBCA2BC2C2A0883C8738F72D612745419080B7D72D8EC2E696CF5CB5EB6F23A9BBFF4BDD129970E881DBAA81E2F1A1445C773D4445ED516D1D954C64593DF72B7B31810B7493B8334F57E79FB26554EE1B4E7B7BDAA2C707D8E4798549DB60AE0A064CA8C6AA36021EB1657E72810E676D0F312325F2FAF956DC336D6B8E1496553362292D98225D61A74827C43FD4B4E0242B19FECBA7C102940C24AC56BB287C739608441EAA2EAA6DE0D1323E6D45204A1FF07BC3D3A48F954597EE865531D8A32C1DC2A3A48C8A0D47BE16919C3DF9E0514CE628DC3E63 +20241129021223 2 6 100 4095 2 D14DC7A20FAA787E8E505E1CCA5C3EC8C5344CE26B9E5E776858C7048EECCB2CE278073BA42E21E4512A91D9A94F6460E86A914FC8D560A29DDC6B3E45CA1F9E8C5C52057BAF6A992E0C04192CEDF05010493D9CED8F97D3891C7DB13865BCD4BC19EA746AFB39E7AC2D60A32D9B77EECFFA53E7022137B7587E5D18E2B100845108104A79B878405B8900A0837BE74494F45DF726B88990607580414CEA1358A78BF832447919460F37395E69BC30E81983D60BB71D4E86164317138B99B545416467AA1F8592A16CEA1B050D2554487A749408A8339FFCA98A5F23D4EEF7A4254C6E56BFD6B95AD3C822B83324BEC5DD85A7064C6233899F7C6D00749D9DEDBAD9ED72CCC9CF154EF3989752DF907B24E587CD6B29A22846CD1B9623A3AEF69D191E8C048046FBCA2BC2C2A0883C8738F72D612745419080B7D72D8EC2E696CF5CB5EB6F23A9BBFF4BDD129970E881DBAA81E2F1A1445C773D4445ED516D1D954C64593DF72B7B31810B7493B8334F57E79FB26554EE1B4E7B7BDAA2C707D8E4798549DB60AE0A064CA8C6AA36021EB1657E72810E676D0F312325F2FAF956DC336D6B8E1496553362292D98225D61A74827C43FD4B4E0242B19FECBA7C102940C24AC56BB287C739608441EAA2EAA6DE0D1323E6D45204A1FF07BC3D3A48F954597EE865531D8A32C1DC2A3A48C8A0D47BE16919C3DF9E0514CE62B25B8A3 +20241129021913 2 6 100 4095 5 D14DC7A20FAA787E8E505E1CCA5C3EC8C5344CE26B9E5E776858C7048EECCB2CE278073BA42E21E4512A91D9A94F6460E86A914FC8D560A29DDC6B3E45CA1F9E8C5C52057BAF6A992E0C04192CEDF05010493D9CED8F97D3891C7DB13865BCD4BC19EA746AFB39E7AC2D60A32D9B77EECFFA53E7022137B7587E5D18E2B100845108104A79B878405B8900A0837BE74494F45DF726B88990607580414CEA1358A78BF832447919460F37395E69BC30E81983D60BB71D4E86164317138B99B545416467AA1F8592A16CEA1B050D2554487A749408A8339FFCA98A5F23D4EEF7A4254C6E56BFD6B95AD3C822B83324BEC5DD85A7064C6233899F7C6D00749D9DEDBAD9ED72CCC9CF154EF3989752DF907B24E587CD6B29A22846CD1B9623A3AEF69D191E8C048046FBCA2BC2C2A0883C8738F72D612745419080B7D72D8EC2E696CF5CB5EB6F23A9BBFF4BDD129970E881DBAA81E2F1A1445C773D4445ED516D1D954C64593DF72B7B31810B7493B8334F57E79FB26554EE1B4E7B7BDAA2C707D8E4798549DB60AE0A064CA8C6AA36021EB1657E72810E676D0F312325F2FAF956DC336D6B8E1496553362292D98225D61A74827C43FD4B4E0242B19FECBA7C102940C24AC56BB287C739608441EAA2EAA6DE0D1323E6D45204A1FF07BC3D3A48F954597EE865531D8A32C1DC2A3A48C8A0D47BE16919C3DF9E0514CE62DC6E86F +20241129021949 2 6 100 4095 2 D14DC7A20FAA787E8E505E1CCA5C3EC8C5344CE26B9E5E776858C7048EECCB2CE278073BA42E21E4512A91D9A94F6460E86A914FC8D560A29DDC6B3E45CA1F9E8C5C52057BAF6A992E0C04192CEDF05010493D9CED8F97D3891C7DB13865BCD4BC19EA746AFB39E7AC2D60A32D9B77EECFFA53E7022137B7587E5D18E2B100845108104A79B878405B8900A0837BE74494F45DF726B88990607580414CEA1358A78BF832447919460F37395E69BC30E81983D60BB71D4E86164317138B99B545416467AA1F8592A16CEA1B050D2554487A749408A8339FFCA98A5F23D4EEF7A4254C6E56BFD6B95AD3C822B83324BEC5DD85A7064C6233899F7C6D00749D9DEDBAD9ED72CCC9CF154EF3989752DF907B24E587CD6B29A22846CD1B9623A3AEF69D191E8C048046FBCA2BC2C2A0883C8738F72D612745419080B7D72D8EC2E696CF5CB5EB6F23A9BBFF4BDD129970E881DBAA81E2F1A1445C773D4445ED516D1D954C64593DF72B7B31810B7493B8334F57E79FB26554EE1B4E7B7BDAA2C707D8E4798549DB60AE0A064CA8C6AA36021EB1657E72810E676D0F312325F2FAF956DC336D6B8E1496553362292D98225D61A74827C43FD4B4E0242B19FECBA7C102940C24AC56BB287C739608441EAA2EAA6DE0D1323E6D45204A1FF07BC3D3A48F954597EE865531D8A32C1DC2A3A48C8A0D47BE16919C3DF9E0514CE62DFA5673 +20241129022203 2 6 100 4095 5 D14DC7A20FAA787E8E505E1CCA5C3EC8C5344CE26B9E5E776858C7048EECCB2CE278073BA42E21E4512A91D9A94F6460E86A914FC8D560A29DDC6B3E45CA1F9E8C5C52057BAF6A992E0C04192CEDF05010493D9CED8F97D3891C7DB13865BCD4BC19EA746AFB39E7AC2D60A32D9B77EECFFA53E7022137B7587E5D18E2B100845108104A79B878405B8900A0837BE74494F45DF726B88990607580414CEA1358A78BF832447919460F37395E69BC30E81983D60BB71D4E86164317138B99B545416467AA1F8592A16CEA1B050D2554487A749408A8339FFCA98A5F23D4EEF7A4254C6E56BFD6B95AD3C822B83324BEC5DD85A7064C6233899F7C6D00749D9DEDBAD9ED72CCC9CF154EF3989752DF907B24E587CD6B29A22846CD1B9623A3AEF69D191E8C048046FBCA2BC2C2A0883C8738F72D612745419080B7D72D8EC2E696CF5CB5EB6F23A9BBFF4BDD129970E881DBAA81E2F1A1445C773D4445ED516D1D954C64593DF72B7B31810B7493B8334F57E79FB26554EE1B4E7B7BDAA2C707D8E4798549DB60AE0A064CA8C6AA36021EB1657E72810E676D0F312325F2FAF956DC336D6B8E1496553362292D98225D61A74827C43FD4B4E0242B19FECBA7C102940C24AC56BB287C739608441EAA2EAA6DE0D1323E6D45204A1FF07BC3D3A48F954597EE865531D8A32C1DC2A3A48C8A0D47BE16919C3DF9E0514CE62ED03D1F +20241129022443 2 6 100 4095 5 D14DC7A20FAA787E8E505E1CCA5C3EC8C5344CE26B9E5E776858C7048EECCB2CE278073BA42E21E4512A91D9A94F6460E86A914FC8D560A29DDC6B3E45CA1F9E8C5C52057BAF6A992E0C04192CEDF05010493D9CED8F97D3891C7DB13865BCD4BC19EA746AFB39E7AC2D60A32D9B77EECFFA53E7022137B7587E5D18E2B100845108104A79B878405B8900A0837BE74494F45DF726B88990607580414CEA1358A78BF832447919460F37395E69BC30E81983D60BB71D4E86164317138B99B545416467AA1F8592A16CEA1B050D2554487A749408A8339FFCA98A5F23D4EEF7A4254C6E56BFD6B95AD3C822B83324BEC5DD85A7064C6233899F7C6D00749D9DEDBAD9ED72CCC9CF154EF3989752DF907B24E587CD6B29A22846CD1B9623A3AEF69D191E8C048046FBCA2BC2C2A0883C8738F72D612745419080B7D72D8EC2E696CF5CB5EB6F23A9BBFF4BDD129970E881DBAA81E2F1A1445C773D4445ED516D1D954C64593DF72B7B31810B7493B8334F57E79FB26554EE1B4E7B7BDAA2C707D8E4798549DB60AE0A064CA8C6AA36021EB1657E72810E676D0F312325F2FAF956DC336D6B8E1496553362292D98225D61A74827C43FD4B4E0242B19FECBA7C102940C24AC56BB287C739608441EAA2EAA6DE0D1323E6D45204A1FF07BC3D3A48F954597EE865531D8A32C1DC2A3A48C8A0D47BE16919C3DF9E0514CE62FC9341F +20241129022708 2 6 100 4095 2 D14DC7A20FAA787E8E505E1CCA5C3EC8C5344CE26B9E5E776858C7048EECCB2CE278073BA42E21E4512A91D9A94F6460E86A914FC8D560A29DDC6B3E45CA1F9E8C5C52057BAF6A992E0C04192CEDF05010493D9CED8F97D3891C7DB13865BCD4BC19EA746AFB39E7AC2D60A32D9B77EECFFA53E7022137B7587E5D18E2B100845108104A79B878405B8900A0837BE74494F45DF726B88990607580414CEA1358A78BF832447919460F37395E69BC30E81983D60BB71D4E86164317138B99B545416467AA1F8592A16CEA1B050D2554487A749408A8339FFCA98A5F23D4EEF7A4254C6E56BFD6B95AD3C822B83324BEC5DD85A7064C6233899F7C6D00749D9DEDBAD9ED72CCC9CF154EF3989752DF907B24E587CD6B29A22846CD1B9623A3AEF69D191E8C048046FBCA2BC2C2A0883C8738F72D612745419080B7D72D8EC2E696CF5CB5EB6F23A9BBFF4BDD129970E881DBAA81E2F1A1445C773D4445ED516D1D954C64593DF72B7B31810B7493B8334F57E79FB26554EE1B4E7B7BDAA2C707D8E4798549DB60AE0A064CA8C6AA36021EB1657E72810E676D0F312325F2FAF956DC336D6B8E1496553362292D98225D61A74827C43FD4B4E0242B19FECBA7C102940C24AC56BB287C739608441EAA2EAA6DE0D1323E6D45204A1FF07BC3D3A48F954597EE865531D8A32C1DC2A3A48C8A0D47BE16919C3DF9E0514CE630ACA413 +20241129023102 2 6 100 4095 5 D14DC7A20FAA787E8E505E1CCA5C3EC8C5344CE26B9E5E776858C7048EECCB2CE278073BA42E21E4512A91D9A94F6460E86A914FC8D560A29DDC6B3E45CA1F9E8C5C52057BAF6A992E0C04192CEDF05010493D9CED8F97D3891C7DB13865BCD4BC19EA746AFB39E7AC2D60A32D9B77EECFFA53E7022137B7587E5D18E2B100845108104A79B878405B8900A0837BE74494F45DF726B88990607580414CEA1358A78BF832447919460F37395E69BC30E81983D60BB71D4E86164317138B99B545416467AA1F8592A16CEA1B050D2554487A749408A8339FFCA98A5F23D4EEF7A4254C6E56BFD6B95AD3C822B83324BEC5DD85A7064C6233899F7C6D00749D9DEDBAD9ED72CCC9CF154EF3989752DF907B24E587CD6B29A22846CD1B9623A3AEF69D191E8C048046FBCA2BC2C2A0883C8738F72D612745419080B7D72D8EC2E696CF5CB5EB6F23A9BBFF4BDD129970E881DBAA81E2F1A1445C773D4445ED516D1D954C64593DF72B7B31810B7493B8334F57E79FB26554EE1B4E7B7BDAA2C707D8E4798549DB60AE0A064CA8C6AA36021EB1657E72810E676D0F312325F2FAF956DC336D6B8E1496553362292D98225D61A74827C43FD4B4E0242B19FECBA7C102940C24AC56BB287C739608441EAA2EAA6DE0D1323E6D45204A1FF07BC3D3A48F954597EE865531D8A32C1DC2A3A48C8A0D47BE16919C3DF9E0514CE6322B2317 +20241129023226 2 6 100 4095 2 D14DC7A20FAA787E8E505E1CCA5C3EC8C5344CE26B9E5E776858C7048EECCB2CE278073BA42E21E4512A91D9A94F6460E86A914FC8D560A29DDC6B3E45CA1F9E8C5C52057BAF6A992E0C04192CEDF05010493D9CED8F97D3891C7DB13865BCD4BC19EA746AFB39E7AC2D60A32D9B77EECFFA53E7022137B7587E5D18E2B100845108104A79B878405B8900A0837BE74494F45DF726B88990607580414CEA1358A78BF832447919460F37395E69BC30E81983D60BB71D4E86164317138B99B545416467AA1F8592A16CEA1B050D2554487A749408A8339FFCA98A5F23D4EEF7A4254C6E56BFD6B95AD3C822B83324BEC5DD85A7064C6233899F7C6D00749D9DEDBAD9ED72CCC9CF154EF3989752DF907B24E587CD6B29A22846CD1B9623A3AEF69D191E8C048046FBCA2BC2C2A0883C8738F72D612745419080B7D72D8EC2E696CF5CB5EB6F23A9BBFF4BDD129970E881DBAA81E2F1A1445C773D4445ED516D1D954C64593DF72B7B31810B7493B8334F57E79FB26554EE1B4E7B7BDAA2C707D8E4798549DB60AE0A064CA8C6AA36021EB1657E72810E676D0F312325F2FAF956DC336D6B8E1496553362292D98225D61A74827C43FD4B4E0242B19FECBA7C102940C24AC56BB287C739608441EAA2EAA6DE0D1323E6D45204A1FF07BC3D3A48F954597EE865531D8A32C1DC2A3A48C8A0D47BE16919C3DF9E0514CE632AFA783 +20241129023234 2 6 100 4095 5 D14DC7A20FAA787E8E505E1CCA5C3EC8C5344CE26B9E5E776858C7048EECCB2CE278073BA42E21E4512A91D9A94F6460E86A914FC8D560A29DDC6B3E45CA1F9E8C5C52057BAF6A992E0C04192CEDF05010493D9CED8F97D3891C7DB13865BCD4BC19EA746AFB39E7AC2D60A32D9B77EECFFA53E7022137B7587E5D18E2B100845108104A79B878405B8900A0837BE74494F45DF726B88990607580414CEA1358A78BF832447919460F37395E69BC30E81983D60BB71D4E86164317138B99B545416467AA1F8592A16CEA1B050D2554487A749408A8339FFCA98A5F23D4EEF7A4254C6E56BFD6B95AD3C822B83324BEC5DD85A7064C6233899F7C6D00749D9DEDBAD9ED72CCC9CF154EF3989752DF907B24E587CD6B29A22846CD1B9623A3AEF69D191E8C048046FBCA2BC2C2A0883C8738F72D612745419080B7D72D8EC2E696CF5CB5EB6F23A9BBFF4BDD129970E881DBAA81E2F1A1445C773D4445ED516D1D954C64593DF72B7B31810B7493B8334F57E79FB26554EE1B4E7B7BDAA2C707D8E4798549DB60AE0A064CA8C6AA36021EB1657E72810E676D0F312325F2FAF956DC336D6B8E1496553362292D98225D61A74827C43FD4B4E0242B19FECBA7C102940C24AC56BB287C739608441EAA2EAA6DE0D1323E6D45204A1FF07BC3D3A48F954597EE865531D8A32C1DC2A3A48C8A0D47BE16919C3DF9E0514CE632B59A57 +20241129023429 2 6 100 4095 5 D14DC7A20FAA787E8E505E1CCA5C3EC8C5344CE26B9E5E776858C7048EECCB2CE278073BA42E21E4512A91D9A94F6460E86A914FC8D560A29DDC6B3E45CA1F9E8C5C52057BAF6A992E0C04192CEDF05010493D9CED8F97D3891C7DB13865BCD4BC19EA746AFB39E7AC2D60A32D9B77EECFFA53E7022137B7587E5D18E2B100845108104A79B878405B8900A0837BE74494F45DF726B88990607580414CEA1358A78BF832447919460F37395E69BC30E81983D60BB71D4E86164317138B99B545416467AA1F8592A16CEA1B050D2554487A749408A8339FFCA98A5F23D4EEF7A4254C6E56BFD6B95AD3C822B83324BEC5DD85A7064C6233899F7C6D00749D9DEDBAD9ED72CCC9CF154EF3989752DF907B24E587CD6B29A22846CD1B9623A3AEF69D191E8C048046FBCA2BC2C2A0883C8738F72D612745419080B7D72D8EC2E696CF5CB5EB6F23A9BBFF4BDD129970E881DBAA81E2F1A1445C773D4445ED516D1D954C64593DF72B7B31810B7493B8334F57E79FB26554EE1B4E7B7BDAA2C707D8E4798549DB60AE0A064CA8C6AA36021EB1657E72810E676D0F312325F2FAF956DC336D6B8E1496553362292D98225D61A74827C43FD4B4E0242B19FECBA7C102940C24AC56BB287C739608441EAA2EAA6DE0D1323E6D45204A1FF07BC3D3A48F954597EE865531D8A32C1DC2A3A48C8A0D47BE16919C3DF9E0514CE633681547 +20241129023526 2 6 100 4095 2 D14DC7A20FAA787E8E505E1CCA5C3EC8C5344CE26B9E5E776858C7048EECCB2CE278073BA42E21E4512A91D9A94F6460E86A914FC8D560A29DDC6B3E45CA1F9E8C5C52057BAF6A992E0C04192CEDF05010493D9CED8F97D3891C7DB13865BCD4BC19EA746AFB39E7AC2D60A32D9B77EECFFA53E7022137B7587E5D18E2B100845108104A79B878405B8900A0837BE74494F45DF726B88990607580414CEA1358A78BF832447919460F37395E69BC30E81983D60BB71D4E86164317138B99B545416467AA1F8592A16CEA1B050D2554487A749408A8339FFCA98A5F23D4EEF7A4254C6E56BFD6B95AD3C822B83324BEC5DD85A7064C6233899F7C6D00749D9DEDBAD9ED72CCC9CF154EF3989752DF907B24E587CD6B29A22846CD1B9623A3AEF69D191E8C048046FBCA2BC2C2A0883C8738F72D612745419080B7D72D8EC2E696CF5CB5EB6F23A9BBFF4BDD129970E881DBAA81E2F1A1445C773D4445ED516D1D954C64593DF72B7B31810B7493B8334F57E79FB26554EE1B4E7B7BDAA2C707D8E4798549DB60AE0A064CA8C6AA36021EB1657E72810E676D0F312325F2FAF956DC336D6B8E1496553362292D98225D61A74827C43FD4B4E0242B19FECBA7C102940C24AC56BB287C739608441EAA2EAA6DE0D1323E6D45204A1FF07BC3D3A48F954597EE865531D8A32C1DC2A3A48C8A0D47BE16919C3DF9E0514CE633BFD83B +20241129023744 2 6 100 4095 2 D14DC7A20FAA787E8E505E1CCA5C3EC8C5344CE26B9E5E776858C7048EECCB2CE278073BA42E21E4512A91D9A94F6460E86A914FC8D560A29DDC6B3E45CA1F9E8C5C52057BAF6A992E0C04192CEDF05010493D9CED8F97D3891C7DB13865BCD4BC19EA746AFB39E7AC2D60A32D9B77EECFFA53E7022137B7587E5D18E2B100845108104A79B878405B8900A0837BE74494F45DF726B88990607580414CEA1358A78BF832447919460F37395E69BC30E81983D60BB71D4E86164317138B99B545416467AA1F8592A16CEA1B050D2554487A749408A8339FFCA98A5F23D4EEF7A4254C6E56BFD6B95AD3C822B83324BEC5DD85A7064C6233899F7C6D00749D9DEDBAD9ED72CCC9CF154EF3989752DF907B24E587CD6B29A22846CD1B9623A3AEF69D191E8C048046FBCA2BC2C2A0883C8738F72D612745419080B7D72D8EC2E696CF5CB5EB6F23A9BBFF4BDD129970E881DBAA81E2F1A1445C773D4445ED516D1D954C64593DF72B7B31810B7493B8334F57E79FB26554EE1B4E7B7BDAA2C707D8E4798549DB60AE0A064CA8C6AA36021EB1657E72810E676D0F312325F2FAF956DC336D6B8E1496553362292D98225D61A74827C43FD4B4E0242B19FECBA7C102940C24AC56BB287C739608441EAA2EAA6DE0D1323E6D45204A1FF07BC3D3A48F954597EE865531D8A32C1DC2A3A48C8A0D47BE16919C3DF9E0514CE634998373 +20241129023820 2 6 100 4095 5 D14DC7A20FAA787E8E505E1CCA5C3EC8C5344CE26B9E5E776858C7048EECCB2CE278073BA42E21E4512A91D9A94F6460E86A914FC8D560A29DDC6B3E45CA1F9E8C5C52057BAF6A992E0C04192CEDF05010493D9CED8F97D3891C7DB13865BCD4BC19EA746AFB39E7AC2D60A32D9B77EECFFA53E7022137B7587E5D18E2B100845108104A79B878405B8900A0837BE74494F45DF726B88990607580414CEA1358A78BF832447919460F37395E69BC30E81983D60BB71D4E86164317138B99B545416467AA1F8592A16CEA1B050D2554487A749408A8339FFCA98A5F23D4EEF7A4254C6E56BFD6B95AD3C822B83324BEC5DD85A7064C6233899F7C6D00749D9DEDBAD9ED72CCC9CF154EF3989752DF907B24E587CD6B29A22846CD1B9623A3AEF69D191E8C048046FBCA2BC2C2A0883C8738F72D612745419080B7D72D8EC2E696CF5CB5EB6F23A9BBFF4BDD129970E881DBAA81E2F1A1445C773D4445ED516D1D954C64593DF72B7B31810B7493B8334F57E79FB26554EE1B4E7B7BDAA2C707D8E4798549DB60AE0A064CA8C6AA36021EB1657E72810E676D0F312325F2FAF956DC336D6B8E1496553362292D98225D61A74827C43FD4B4E0242B19FECBA7C102940C24AC56BB287C739608441EAA2EAA6DE0D1323E6D45204A1FF07BC3D3A48F954597EE865531D8A32C1DC2A3A48C8A0D47BE16919C3DF9E0514CE634CA05CF +20241129023919 2 6 100 4095 2 D14DC7A20FAA787E8E505E1CCA5C3EC8C5344CE26B9E5E776858C7048EECCB2CE278073BA42E21E4512A91D9A94F6460E86A914FC8D560A29DDC6B3E45CA1F9E8C5C52057BAF6A992E0C04192CEDF05010493D9CED8F97D3891C7DB13865BCD4BC19EA746AFB39E7AC2D60A32D9B77EECFFA53E7022137B7587E5D18E2B100845108104A79B878405B8900A0837BE74494F45DF726B88990607580414CEA1358A78BF832447919460F37395E69BC30E81983D60BB71D4E86164317138B99B545416467AA1F8592A16CEA1B050D2554487A749408A8339FFCA98A5F23D4EEF7A4254C6E56BFD6B95AD3C822B83324BEC5DD85A7064C6233899F7C6D00749D9DEDBAD9ED72CCC9CF154EF3989752DF907B24E587CD6B29A22846CD1B9623A3AEF69D191E8C048046FBCA2BC2C2A0883C8738F72D612745419080B7D72D8EC2E696CF5CB5EB6F23A9BBFF4BDD129970E881DBAA81E2F1A1445C773D4445ED516D1D954C64593DF72B7B31810B7493B8334F57E79FB26554EE1B4E7B7BDAA2C707D8E4798549DB60AE0A064CA8C6AA36021EB1657E72810E676D0F312325F2FAF956DC336D6B8E1496553362292D98225D61A74827C43FD4B4E0242B19FECBA7C102940C24AC56BB287C739608441EAA2EAA6DE0D1323E6D45204A1FF07BC3D3A48F954597EE865531D8A32C1DC2A3A48C8A0D47BE16919C3DF9E0514CE635285DD3 +20241129024116 2 6 100 4095 5 D14DC7A20FAA787E8E505E1CCA5C3EC8C5344CE26B9E5E776858C7048EECCB2CE278073BA42E21E4512A91D9A94F6460E86A914FC8D560A29DDC6B3E45CA1F9E8C5C52057BAF6A992E0C04192CEDF05010493D9CED8F97D3891C7DB13865BCD4BC19EA746AFB39E7AC2D60A32D9B77EECFFA53E7022137B7587E5D18E2B100845108104A79B878405B8900A0837BE74494F45DF726B88990607580414CEA1358A78BF832447919460F37395E69BC30E81983D60BB71D4E86164317138B99B545416467AA1F8592A16CEA1B050D2554487A749408A8339FFCA98A5F23D4EEF7A4254C6E56BFD6B95AD3C822B83324BEC5DD85A7064C6233899F7C6D00749D9DEDBAD9ED72CCC9CF154EF3989752DF907B24E587CD6B29A22846CD1B9623A3AEF69D191E8C048046FBCA2BC2C2A0883C8738F72D612745419080B7D72D8EC2E696CF5CB5EB6F23A9BBFF4BDD129970E881DBAA81E2F1A1445C773D4445ED516D1D954C64593DF72B7B31810B7493B8334F57E79FB26554EE1B4E7B7BDAA2C707D8E4798549DB60AE0A064CA8C6AA36021EB1657E72810E676D0F312325F2FAF956DC336D6B8E1496553362292D98225D61A74827C43FD4B4E0242B19FECBA7C102940C24AC56BB287C739608441EAA2EAA6DE0D1323E6D45204A1FF07BC3D3A48F954597EE865531D8A32C1DC2A3A48C8A0D47BE16919C3DF9E0514CE635E04407 +20241129024436 2 6 100 4095 5 D14DC7A20FAA787E8E505E1CCA5C3EC8C5344CE26B9E5E776858C7048EECCB2CE278073BA42E21E4512A91D9A94F6460E86A914FC8D560A29DDC6B3E45CA1F9E8C5C52057BAF6A992E0C04192CEDF05010493D9CED8F97D3891C7DB13865BCD4BC19EA746AFB39E7AC2D60A32D9B77EECFFA53E7022137B7587E5D18E2B100845108104A79B878405B8900A0837BE74494F45DF726B88990607580414CEA1358A78BF832447919460F37395E69BC30E81983D60BB71D4E86164317138B99B545416467AA1F8592A16CEA1B050D2554487A749408A8339FFCA98A5F23D4EEF7A4254C6E56BFD6B95AD3C822B83324BEC5DD85A7064C6233899F7C6D00749D9DEDBAD9ED72CCC9CF154EF3989752DF907B24E587CD6B29A22846CD1B9623A3AEF69D191E8C048046FBCA2BC2C2A0883C8738F72D612745419080B7D72D8EC2E696CF5CB5EB6F23A9BBFF4BDD129970E881DBAA81E2F1A1445C773D4445ED516D1D954C64593DF72B7B31810B7493B8334F57E79FB26554EE1B4E7B7BDAA2C707D8E4798549DB60AE0A064CA8C6AA36021EB1657E72810E676D0F312325F2FAF956DC336D6B8E1496553362292D98225D61A74827C43FD4B4E0242B19FECBA7C102940C24AC56BB287C739608441EAA2EAA6DE0D1323E6D45204A1FF07BC3D3A48F954597EE865531D8A32C1DC2A3A48C8A0D47BE16919C3DF9E0514CE637222687 +20241129024611 2 6 100 4095 5 D14DC7A20FAA787E8E505E1CCA5C3EC8C5344CE26B9E5E776858C7048EECCB2CE278073BA42E21E4512A91D9A94F6460E86A914FC8D560A29DDC6B3E45CA1F9E8C5C52057BAF6A992E0C04192CEDF05010493D9CED8F97D3891C7DB13865BCD4BC19EA746AFB39E7AC2D60A32D9B77EECFFA53E7022137B7587E5D18E2B100845108104A79B878405B8900A0837BE74494F45DF726B88990607580414CEA1358A78BF832447919460F37395E69BC30E81983D60BB71D4E86164317138B99B545416467AA1F8592A16CEA1B050D2554487A749408A8339FFCA98A5F23D4EEF7A4254C6E56BFD6B95AD3C822B83324BEC5DD85A7064C6233899F7C6D00749D9DEDBAD9ED72CCC9CF154EF3989752DF907B24E587CD6B29A22846CD1B9623A3AEF69D191E8C048046FBCA2BC2C2A0883C8738F72D612745419080B7D72D8EC2E696CF5CB5EB6F23A9BBFF4BDD129970E881DBAA81E2F1A1445C773D4445ED516D1D954C64593DF72B7B31810B7493B8334F57E79FB26554EE1B4E7B7BDAA2C707D8E4798549DB60AE0A064CA8C6AA36021EB1657E72810E676D0F312325F2FAF956DC336D6B8E1496553362292D98225D61A74827C43FD4B4E0242B19FECBA7C102940C24AC56BB287C739608441EAA2EAA6DE0D1323E6D45204A1FF07BC3D3A48F954597EE865531D8A32C1DC2A3A48C8A0D47BE16919C3DF9E0514CE637B833A7 +20241129024935 2 6 100 4095 2 D14DC7A20FAA787E8E505E1CCA5C3EC8C5344CE26B9E5E776858C7048EECCB2CE278073BA42E21E4512A91D9A94F6460E86A914FC8D560A29DDC6B3E45CA1F9E8C5C52057BAF6A992E0C04192CEDF05010493D9CED8F97D3891C7DB13865BCD4BC19EA746AFB39E7AC2D60A32D9B77EECFFA53E7022137B7587E5D18E2B100845108104A79B878405B8900A0837BE74494F45DF726B88990607580414CEA1358A78BF832447919460F37395E69BC30E81983D60BB71D4E86164317138B99B545416467AA1F8592A16CEA1B050D2554487A749408A8339FFCA98A5F23D4EEF7A4254C6E56BFD6B95AD3C822B83324BEC5DD85A7064C6233899F7C6D00749D9DEDBAD9ED72CCC9CF154EF3989752DF907B24E587CD6B29A22846CD1B9623A3AEF69D191E8C048046FBCA2BC2C2A0883C8738F72D612745419080B7D72D8EC2E696CF5CB5EB6F23A9BBFF4BDD129970E881DBAA81E2F1A1445C773D4445ED516D1D954C64593DF72B7B31810B7493B8334F57E79FB26554EE1B4E7B7BDAA2C707D8E4798549DB60AE0A064CA8C6AA36021EB1657E72810E676D0F312325F2FAF956DC336D6B8E1496553362292D98225D61A74827C43FD4B4E0242B19FECBA7C102940C24AC56BB287C739608441EAA2EAA6DE0D1323E6D45204A1FF07BC3D3A48F954597EE865531D8A32C1DC2A3A48C8A0D47BE16919C3DF9E0514CE63905717B +20241129025344 2 6 100 4095 2 F32300D8DFCB79ECFB80E433E6CFA1923915D80120F52648A7AE7E8058B5DB869F2B3A9DD940E53B7D74E3214FA03234F8B026AFF16B646B39F003882F1DC17D3F6DBB89283A01B4C22168A354D6D2FDBDE3F2B0C91E9472AF1DB386DD34477F47CB24D4AFB71BB283A9760CF4EC582F1401A4F259D4AADE2BC7648A6920207DFB149BB7A4483D5E22D9DC627A8A4954C18AAAEF921CE0C597C11C95EC7C8888050124D01C43E6A33A02DACDB2EEE70920BAF2A296EB38CEADCB98CC7789BA309A5AD7916B9F7F86B0D808346E28447C4E3F31C5BC319D29A0D338EE8FC88BC9288C75004CC278BB218AA86929360079EAA71628FEFB796FFFBAD3764F677FECC0F274582ED2E371ACB500F35F378DDEDB0FA32B1B55699E41EBE958E6614811999433D934CCD54A03CC4BF359798F90EC809CFA6E58C1CE68B5AF397E8E35951F9CC4BCD0EC8655486543B4CF7605CE15969A2D88E8CD6BCA82671A06FC54397840BBA9DB2750B0F1FBC61ECF6E514450A7E06C6E6BBBB2CFA5E045335F04A5C407EC6467D471226ED2CB3AE9FBA9E956F8F3D05A911F9CD131BC3D95A10792097AC1C4339F8C12E40ABD274A25CF26EF286187E91261273E39856C471D861056EC3F6F5E58EB727134F9BFB870C8DD6978F247EAF67C1368BCB0BA105CDDC2BA067EBAC9C00DC15F1667664AA2A688D45E843F62467892EE9348FD87AD5A3B +20241129025405 2 6 100 4095 5 F32300D8DFCB79ECFB80E433E6CFA1923915D80120F52648A7AE7E8058B5DB869F2B3A9DD940E53B7D74E3214FA03234F8B026AFF16B646B39F003882F1DC17D3F6DBB89283A01B4C22168A354D6D2FDBDE3F2B0C91E9472AF1DB386DD34477F47CB24D4AFB71BB283A9760CF4EC582F1401A4F259D4AADE2BC7648A6920207DFB149BB7A4483D5E22D9DC627A8A4954C18AAAEF921CE0C597C11C95EC7C8888050124D01C43E6A33A02DACDB2EEE70920BAF2A296EB38CEADCB98CC7789BA309A5AD7916B9F7F86B0D808346E28447C4E3F31C5BC319D29A0D338EE8FC88BC9288C75004CC278BB218AA86929360079EAA71628FEFB796FFFBAD3764F677FECC0F274582ED2E371ACB500F35F378DDEDB0FA32B1B55699E41EBE958E6614811999433D934CCD54A03CC4BF359798F90EC809CFA6E58C1CE68B5AF397E8E35951F9CC4BCD0EC8655486543B4CF7605CE15969A2D88E8CD6BCA82671A06FC54397840BBA9DB2750B0F1FBC61ECF6E514450A7E06C6E6BBBB2CFA5E045335F04A5C407EC6467D471226ED2CB3AE9FBA9E956F8F3D05A911F9CD131BC3D95A10792097AC1C4339F8C12E40ABD274A25CF26EF286187E91261273E39856C471D861056EC3F6F5E58EB727134F9BFB870C8DD6978F247EAF67C1368BCB0BA105CDDC2BA067EBAC9C00DC15F1667664AA2A688D45E843F62467892EE9348FD87C61B07 +20241129025445 2 6 100 4095 2 F32300D8DFCB79ECFB80E433E6CFA1923915D80120F52648A7AE7E8058B5DB869F2B3A9DD940E53B7D74E3214FA03234F8B026AFF16B646B39F003882F1DC17D3F6DBB89283A01B4C22168A354D6D2FDBDE3F2B0C91E9472AF1DB386DD34477F47CB24D4AFB71BB283A9760CF4EC582F1401A4F259D4AADE2BC7648A6920207DFB149BB7A4483D5E22D9DC627A8A4954C18AAAEF921CE0C597C11C95EC7C8888050124D01C43E6A33A02DACDB2EEE70920BAF2A296EB38CEADCB98CC7789BA309A5AD7916B9F7F86B0D808346E28447C4E3F31C5BC319D29A0D338EE8FC88BC9288C75004CC278BB218AA86929360079EAA71628FEFB796FFFBAD3764F677FECC0F274582ED2E371ACB500F35F378DDEDB0FA32B1B55699E41EBE958E6614811999433D934CCD54A03CC4BF359798F90EC809CFA6E58C1CE68B5AF397E8E35951F9CC4BCD0EC8655486543B4CF7605CE15969A2D88E8CD6BCA82671A06FC54397840BBA9DB2750B0F1FBC61ECF6E514450A7E06C6E6BBBB2CFA5E045335F04A5C407EC6467D471226ED2CB3AE9FBA9E956F8F3D05A911F9CD131BC3D95A10792097AC1C4339F8C12E40ABD274A25CF26EF286187E91261273E39856C471D861056EC3F6F5E58EB727134F9BFB870C8DD6978F247EAF67C1368BCB0BA105CDDC2BA067EBAC9C00DC15F1667664AA2A688D45E843F62467892EE9348FD88010893 +20241129025701 2 6 100 4095 2 F32300D8DFCB79ECFB80E433E6CFA1923915D80120F52648A7AE7E8058B5DB869F2B3A9DD940E53B7D74E3214FA03234F8B026AFF16B646B39F003882F1DC17D3F6DBB89283A01B4C22168A354D6D2FDBDE3F2B0C91E9472AF1DB386DD34477F47CB24D4AFB71BB283A9760CF4EC582F1401A4F259D4AADE2BC7648A6920207DFB149BB7A4483D5E22D9DC627A8A4954C18AAAEF921CE0C597C11C95EC7C8888050124D01C43E6A33A02DACDB2EEE70920BAF2A296EB38CEADCB98CC7789BA309A5AD7916B9F7F86B0D808346E28447C4E3F31C5BC319D29A0D338EE8FC88BC9288C75004CC278BB218AA86929360079EAA71628FEFB796FFFBAD3764F677FECC0F274582ED2E371ACB500F35F378DDEDB0FA32B1B55699E41EBE958E6614811999433D934CCD54A03CC4BF359798F90EC809CFA6E58C1CE68B5AF397E8E35951F9CC4BCD0EC8655486543B4CF7605CE15969A2D88E8CD6BCA82671A06FC54397840BBA9DB2750B0F1FBC61ECF6E514450A7E06C6E6BBBB2CFA5E045335F04A5C407EC6467D471226ED2CB3AE9FBA9E956F8F3D05A911F9CD131BC3D95A10792097AC1C4339F8C12E40ABD274A25CF26EF286187E91261273E39856C471D861056EC3F6F5E58EB727134F9BFB870C8DD6978F247EAF67C1368BCB0BA105CDDC2BA067EBAC9C00DC15F1667664AA2A688D45E843F62467892EE9348FD88DA8ABB +20241129025807 2 6 100 4095 2 F32300D8DFCB79ECFB80E433E6CFA1923915D80120F52648A7AE7E8058B5DB869F2B3A9DD940E53B7D74E3214FA03234F8B026AFF16B646B39F003882F1DC17D3F6DBB89283A01B4C22168A354D6D2FDBDE3F2B0C91E9472AF1DB386DD34477F47CB24D4AFB71BB283A9760CF4EC582F1401A4F259D4AADE2BC7648A6920207DFB149BB7A4483D5E22D9DC627A8A4954C18AAAEF921CE0C597C11C95EC7C8888050124D01C43E6A33A02DACDB2EEE70920BAF2A296EB38CEADCB98CC7789BA309A5AD7916B9F7F86B0D808346E28447C4E3F31C5BC319D29A0D338EE8FC88BC9288C75004CC278BB218AA86929360079EAA71628FEFB796FFFBAD3764F677FECC0F274582ED2E371ACB500F35F378DDEDB0FA32B1B55699E41EBE958E6614811999433D934CCD54A03CC4BF359798F90EC809CFA6E58C1CE68B5AF397E8E35951F9CC4BCD0EC8655486543B4CF7605CE15969A2D88E8CD6BCA82671A06FC54397840BBA9DB2750B0F1FBC61ECF6E514450A7E06C6E6BBBB2CFA5E045335F04A5C407EC6467D471226ED2CB3AE9FBA9E956F8F3D05A911F9CD131BC3D95A10792097AC1C4339F8C12E40ABD274A25CF26EF286187E91261273E39856C471D861056EC3F6F5E58EB727134F9BFB870C8DD6978F247EAF67C1368BCB0BA105CDDC2BA067EBAC9C00DC15F1667664AA2A688D45E843F62467892EE9348FD893E4473 +20241129025930 2 6 100 4095 5 F32300D8DFCB79ECFB80E433E6CFA1923915D80120F52648A7AE7E8058B5DB869F2B3A9DD940E53B7D74E3214FA03234F8B026AFF16B646B39F003882F1DC17D3F6DBB89283A01B4C22168A354D6D2FDBDE3F2B0C91E9472AF1DB386DD34477F47CB24D4AFB71BB283A9760CF4EC582F1401A4F259D4AADE2BC7648A6920207DFB149BB7A4483D5E22D9DC627A8A4954C18AAAEF921CE0C597C11C95EC7C8888050124D01C43E6A33A02DACDB2EEE70920BAF2A296EB38CEADCB98CC7789BA309A5AD7916B9F7F86B0D808346E28447C4E3F31C5BC319D29A0D338EE8FC88BC9288C75004CC278BB218AA86929360079EAA71628FEFB796FFFBAD3764F677FECC0F274582ED2E371ACB500F35F378DDEDB0FA32B1B55699E41EBE958E6614811999433D934CCD54A03CC4BF359798F90EC809CFA6E58C1CE68B5AF397E8E35951F9CC4BCD0EC8655486543B4CF7605CE15969A2D88E8CD6BCA82671A06FC54397840BBA9DB2750B0F1FBC61ECF6E514450A7E06C6E6BBBB2CFA5E045335F04A5C407EC6467D471226ED2CB3AE9FBA9E956F8F3D05A911F9CD131BC3D95A10792097AC1C4339F8C12E40ABD274A25CF26EF286187E91261273E39856C471D861056EC3F6F5E58EB727134F9BFB870C8DD6978F247EAF67C1368BCB0BA105CDDC2BA067EBAC9C00DC15F1667664AA2A688D45E843F62467892EE9348FD89BD17B7 +20241129025947 2 6 100 4095 2 F32300D8DFCB79ECFB80E433E6CFA1923915D80120F52648A7AE7E8058B5DB869F2B3A9DD940E53B7D74E3214FA03234F8B026AFF16B646B39F003882F1DC17D3F6DBB89283A01B4C22168A354D6D2FDBDE3F2B0C91E9472AF1DB386DD34477F47CB24D4AFB71BB283A9760CF4EC582F1401A4F259D4AADE2BC7648A6920207DFB149BB7A4483D5E22D9DC627A8A4954C18AAAEF921CE0C597C11C95EC7C8888050124D01C43E6A33A02DACDB2EEE70920BAF2A296EB38CEADCB98CC7789BA309A5AD7916B9F7F86B0D808346E28447C4E3F31C5BC319D29A0D338EE8FC88BC9288C75004CC278BB218AA86929360079EAA71628FEFB796FFFBAD3764F677FECC0F274582ED2E371ACB500F35F378DDEDB0FA32B1B55699E41EBE958E6614811999433D934CCD54A03CC4BF359798F90EC809CFA6E58C1CE68B5AF397E8E35951F9CC4BCD0EC8655486543B4CF7605CE15969A2D88E8CD6BCA82671A06FC54397840BBA9DB2750B0F1FBC61ECF6E514450A7E06C6E6BBBB2CFA5E045335F04A5C407EC6467D471226ED2CB3AE9FBA9E956F8F3D05A911F9CD131BC3D95A10792097AC1C4339F8C12E40ABD274A25CF26EF286187E91261273E39856C471D861056EC3F6F5E58EB727134F9BFB870C8DD6978F247EAF67C1368BCB0BA105CDDC2BA067EBAC9C00DC15F1667664AA2A688D45E843F62467892EE9348FD89D220C3 +20241129030824 2 6 100 4095 2 F32300D8DFCB79ECFB80E433E6CFA1923915D80120F52648A7AE7E8058B5DB869F2B3A9DD940E53B7D74E3214FA03234F8B026AFF16B646B39F003882F1DC17D3F6DBB89283A01B4C22168A354D6D2FDBDE3F2B0C91E9472AF1DB386DD34477F47CB24D4AFB71BB283A9760CF4EC582F1401A4F259D4AADE2BC7648A6920207DFB149BB7A4483D5E22D9DC627A8A4954C18AAAEF921CE0C597C11C95EC7C8888050124D01C43E6A33A02DACDB2EEE70920BAF2A296EB38CEADCB98CC7789BA309A5AD7916B9F7F86B0D808346E28447C4E3F31C5BC319D29A0D338EE8FC88BC9288C75004CC278BB218AA86929360079EAA71628FEFB796FFFBAD3764F677FECC0F274582ED2E371ACB500F35F378DDEDB0FA32B1B55699E41EBE958E6614811999433D934CCD54A03CC4BF359798F90EC809CFA6E58C1CE68B5AF397E8E35951F9CC4BCD0EC8655486543B4CF7605CE15969A2D88E8CD6BCA82671A06FC54397840BBA9DB2750B0F1FBC61ECF6E514450A7E06C6E6BBBB2CFA5E045335F04A5C407EC6467D471226ED2CB3AE9FBA9E956F8F3D05A911F9CD131BC3D95A10792097AC1C4339F8C12E40ABD274A25CF26EF286187E91261273E39856C471D861056EC3F6F5E58EB727134F9BFB870C8DD6978F247EAF67C1368BCB0BA105CDDC2BA067EBAC9C00DC15F1667664AA2A688D45E843F62467892EE9348FD8D22E89B +20241129031329 2 6 100 4095 2 F32300D8DFCB79ECFB80E433E6CFA1923915D80120F52648A7AE7E8058B5DB869F2B3A9DD940E53B7D74E3214FA03234F8B026AFF16B646B39F003882F1DC17D3F6DBB89283A01B4C22168A354D6D2FDBDE3F2B0C91E9472AF1DB386DD34477F47CB24D4AFB71BB283A9760CF4EC582F1401A4F259D4AADE2BC7648A6920207DFB149BB7A4483D5E22D9DC627A8A4954C18AAAEF921CE0C597C11C95EC7C8888050124D01C43E6A33A02DACDB2EEE70920BAF2A296EB38CEADCB98CC7789BA309A5AD7916B9F7F86B0D808346E28447C4E3F31C5BC319D29A0D338EE8FC88BC9288C75004CC278BB218AA86929360079EAA71628FEFB796FFFBAD3764F677FECC0F274582ED2E371ACB500F35F378DDEDB0FA32B1B55699E41EBE958E6614811999433D934CCD54A03CC4BF359798F90EC809CFA6E58C1CE68B5AF397E8E35951F9CC4BCD0EC8655486543B4CF7605CE15969A2D88E8CD6BCA82671A06FC54397840BBA9DB2750B0F1FBC61ECF6E514450A7E06C6E6BBBB2CFA5E045335F04A5C407EC6467D471226ED2CB3AE9FBA9E956F8F3D05A911F9CD131BC3D95A10792097AC1C4339F8C12E40ABD274A25CF26EF286187E91261273E39856C471D861056EC3F6F5E58EB727134F9BFB870C8DD6978F247EAF67C1368BCB0BA105CDDC2BA067EBAC9C00DC15F1667664AA2A688D45E843F62467892EE9348FD8F0BC07B +20241129031515 2 6 100 4095 5 F32300D8DFCB79ECFB80E433E6CFA1923915D80120F52648A7AE7E8058B5DB869F2B3A9DD940E53B7D74E3214FA03234F8B026AFF16B646B39F003882F1DC17D3F6DBB89283A01B4C22168A354D6D2FDBDE3F2B0C91E9472AF1DB386DD34477F47CB24D4AFB71BB283A9760CF4EC582F1401A4F259D4AADE2BC7648A6920207DFB149BB7A4483D5E22D9DC627A8A4954C18AAAEF921CE0C597C11C95EC7C8888050124D01C43E6A33A02DACDB2EEE70920BAF2A296EB38CEADCB98CC7789BA309A5AD7916B9F7F86B0D808346E28447C4E3F31C5BC319D29A0D338EE8FC88BC9288C75004CC278BB218AA86929360079EAA71628FEFB796FFFBAD3764F677FECC0F274582ED2E371ACB500F35F378DDEDB0FA32B1B55699E41EBE958E6614811999433D934CCD54A03CC4BF359798F90EC809CFA6E58C1CE68B5AF397E8E35951F9CC4BCD0EC8655486543B4CF7605CE15969A2D88E8CD6BCA82671A06FC54397840BBA9DB2750B0F1FBC61ECF6E514450A7E06C6E6BBBB2CFA5E045335F04A5C407EC6467D471226ED2CB3AE9FBA9E956F8F3D05A911F9CD131BC3D95A10792097AC1C4339F8C12E40ABD274A25CF26EF286187E91261273E39856C471D861056EC3F6F5E58EB727134F9BFB870C8DD6978F247EAF67C1368BCB0BA105CDDC2BA067EBAC9C00DC15F1667664AA2A688D45E843F62467892EE9348FD8FB3CF27 +20241129031807 2 6 100 4095 5 F32300D8DFCB79ECFB80E433E6CFA1923915D80120F52648A7AE7E8058B5DB869F2B3A9DD940E53B7D74E3214FA03234F8B026AFF16B646B39F003882F1DC17D3F6DBB89283A01B4C22168A354D6D2FDBDE3F2B0C91E9472AF1DB386DD34477F47CB24D4AFB71BB283A9760CF4EC582F1401A4F259D4AADE2BC7648A6920207DFB149BB7A4483D5E22D9DC627A8A4954C18AAAEF921CE0C597C11C95EC7C8888050124D01C43E6A33A02DACDB2EEE70920BAF2A296EB38CEADCB98CC7789BA309A5AD7916B9F7F86B0D808346E28447C4E3F31C5BC319D29A0D338EE8FC88BC9288C75004CC278BB218AA86929360079EAA71628FEFB796FFFBAD3764F677FECC0F274582ED2E371ACB500F35F378DDEDB0FA32B1B55699E41EBE958E6614811999433D934CCD54A03CC4BF359798F90EC809CFA6E58C1CE68B5AF397E8E35951F9CC4BCD0EC8655486543B4CF7605CE15969A2D88E8CD6BCA82671A06FC54397840BBA9DB2750B0F1FBC61ECF6E514450A7E06C6E6BBBB2CFA5E045335F04A5C407EC6467D471226ED2CB3AE9FBA9E956F8F3D05A911F9CD131BC3D95A10792097AC1C4339F8C12E40ABD274A25CF26EF286187E91261273E39856C471D861056EC3F6F5E58EB727134F9BFB870C8DD6978F247EAF67C1368BCB0BA105CDDC2BA067EBAC9C00DC15F1667664AA2A688D45E843F62467892EE9348FD90C1CCE7 +20241129032416 2 6 100 4095 2 F32300D8DFCB79ECFB80E433E6CFA1923915D80120F52648A7AE7E8058B5DB869F2B3A9DD940E53B7D74E3214FA03234F8B026AFF16B646B39F003882F1DC17D3F6DBB89283A01B4C22168A354D6D2FDBDE3F2B0C91E9472AF1DB386DD34477F47CB24D4AFB71BB283A9760CF4EC582F1401A4F259D4AADE2BC7648A6920207DFB149BB7A4483D5E22D9DC627A8A4954C18AAAEF921CE0C597C11C95EC7C8888050124D01C43E6A33A02DACDB2EEE70920BAF2A296EB38CEADCB98CC7789BA309A5AD7916B9F7F86B0D808346E28447C4E3F31C5BC319D29A0D338EE8FC88BC9288C75004CC278BB218AA86929360079EAA71628FEFB796FFFBAD3764F677FECC0F274582ED2E371ACB500F35F378DDEDB0FA32B1B55699E41EBE958E6614811999433D934CCD54A03CC4BF359798F90EC809CFA6E58C1CE68B5AF397E8E35951F9CC4BCD0EC8655486543B4CF7605CE15969A2D88E8CD6BCA82671A06FC54397840BBA9DB2750B0F1FBC61ECF6E514450A7E06C6E6BBBB2CFA5E045335F04A5C407EC6467D471226ED2CB3AE9FBA9E956F8F3D05A911F9CD131BC3D95A10792097AC1C4339F8C12E40ABD274A25CF26EF286187E91261273E39856C471D861056EC3F6F5E58EB727134F9BFB870C8DD6978F247EAF67C1368BCB0BA105CDDC2BA067EBAC9C00DC15F1667664AA2A688D45E843F62467892EE9348FD9313280B +20241129032613 2 6 100 4095 5 F32300D8DFCB79ECFB80E433E6CFA1923915D80120F52648A7AE7E8058B5DB869F2B3A9DD940E53B7D74E3214FA03234F8B026AFF16B646B39F003882F1DC17D3F6DBB89283A01B4C22168A354D6D2FDBDE3F2B0C91E9472AF1DB386DD34477F47CB24D4AFB71BB283A9760CF4EC582F1401A4F259D4AADE2BC7648A6920207DFB149BB7A4483D5E22D9DC627A8A4954C18AAAEF921CE0C597C11C95EC7C8888050124D01C43E6A33A02DACDB2EEE70920BAF2A296EB38CEADCB98CC7789BA309A5AD7916B9F7F86B0D808346E28447C4E3F31C5BC319D29A0D338EE8FC88BC9288C75004CC278BB218AA86929360079EAA71628FEFB796FFFBAD3764F677FECC0F274582ED2E371ACB500F35F378DDEDB0FA32B1B55699E41EBE958E6614811999433D934CCD54A03CC4BF359798F90EC809CFA6E58C1CE68B5AF397E8E35951F9CC4BCD0EC8655486543B4CF7605CE15969A2D88E8CD6BCA82671A06FC54397840BBA9DB2750B0F1FBC61ECF6E514450A7E06C6E6BBBB2CFA5E045335F04A5C407EC6467D471226ED2CB3AE9FBA9E956F8F3D05A911F9CD131BC3D95A10792097AC1C4339F8C12E40ABD274A25CF26EF286187E91261273E39856C471D861056EC3F6F5E58EB727134F9BFB870C8DD6978F247EAF67C1368BCB0BA105CDDC2BA067EBAC9C00DC15F1667664AA2A688D45E843F62467892EE9348FD93CCA2C7 +20241129032705 2 6 100 4095 5 F32300D8DFCB79ECFB80E433E6CFA1923915D80120F52648A7AE7E8058B5DB869F2B3A9DD940E53B7D74E3214FA03234F8B026AFF16B646B39F003882F1DC17D3F6DBB89283A01B4C22168A354D6D2FDBDE3F2B0C91E9472AF1DB386DD34477F47CB24D4AFB71BB283A9760CF4EC582F1401A4F259D4AADE2BC7648A6920207DFB149BB7A4483D5E22D9DC627A8A4954C18AAAEF921CE0C597C11C95EC7C8888050124D01C43E6A33A02DACDB2EEE70920BAF2A296EB38CEADCB98CC7789BA309A5AD7916B9F7F86B0D808346E28447C4E3F31C5BC319D29A0D338EE8FC88BC9288C75004CC278BB218AA86929360079EAA71628FEFB796FFFBAD3764F677FECC0F274582ED2E371ACB500F35F378DDEDB0FA32B1B55699E41EBE958E6614811999433D934CCD54A03CC4BF359798F90EC809CFA6E58C1CE68B5AF397E8E35951F9CC4BCD0EC8655486543B4CF7605CE15969A2D88E8CD6BCA82671A06FC54397840BBA9DB2750B0F1FBC61ECF6E514450A7E06C6E6BBBB2CFA5E045335F04A5C407EC6467D471226ED2CB3AE9FBA9E956F8F3D05A911F9CD131BC3D95A10792097AC1C4339F8C12E40ABD274A25CF26EF286187E91261273E39856C471D861056EC3F6F5E58EB727134F9BFB870C8DD6978F247EAF67C1368BCB0BA105CDDC2BA067EBAC9C00DC15F1667664AA2A688D45E843F62467892EE9348FD941819BF +20241129033035 2 6 100 4095 5 F32300D8DFCB79ECFB80E433E6CFA1923915D80120F52648A7AE7E8058B5DB869F2B3A9DD940E53B7D74E3214FA03234F8B026AFF16B646B39F003882F1DC17D3F6DBB89283A01B4C22168A354D6D2FDBDE3F2B0C91E9472AF1DB386DD34477F47CB24D4AFB71BB283A9760CF4EC582F1401A4F259D4AADE2BC7648A6920207DFB149BB7A4483D5E22D9DC627A8A4954C18AAAEF921CE0C597C11C95EC7C8888050124D01C43E6A33A02DACDB2EEE70920BAF2A296EB38CEADCB98CC7789BA309A5AD7916B9F7F86B0D808346E28447C4E3F31C5BC319D29A0D338EE8FC88BC9288C75004CC278BB218AA86929360079EAA71628FEFB796FFFBAD3764F677FECC0F274582ED2E371ACB500F35F378DDEDB0FA32B1B55699E41EBE958E6614811999433D934CCD54A03CC4BF359798F90EC809CFA6E58C1CE68B5AF397E8E35951F9CC4BCD0EC8655486543B4CF7605CE15969A2D88E8CD6BCA82671A06FC54397840BBA9DB2750B0F1FBC61ECF6E514450A7E06C6E6BBBB2CFA5E045335F04A5C407EC6467D471226ED2CB3AE9FBA9E956F8F3D05A911F9CD131BC3D95A10792097AC1C4339F8C12E40ABD274A25CF26EF286187E91261273E39856C471D861056EC3F6F5E58EB727134F9BFB870C8DD6978F247EAF67C1368BCB0BA105CDDC2BA067EBAC9C00DC15F1667664AA2A688D45E843F62467892EE9348FD9564B557 +20241129033357 2 6 100 4095 2 F32300D8DFCB79ECFB80E433E6CFA1923915D80120F52648A7AE7E8058B5DB869F2B3A9DD940E53B7D74E3214FA03234F8B026AFF16B646B39F003882F1DC17D3F6DBB89283A01B4C22168A354D6D2FDBDE3F2B0C91E9472AF1DB386DD34477F47CB24D4AFB71BB283A9760CF4EC582F1401A4F259D4AADE2BC7648A6920207DFB149BB7A4483D5E22D9DC627A8A4954C18AAAEF921CE0C597C11C95EC7C8888050124D01C43E6A33A02DACDB2EEE70920BAF2A296EB38CEADCB98CC7789BA309A5AD7916B9F7F86B0D808346E28447C4E3F31C5BC319D29A0D338EE8FC88BC9288C75004CC278BB218AA86929360079EAA71628FEFB796FFFBAD3764F677FECC0F274582ED2E371ACB500F35F378DDEDB0FA32B1B55699E41EBE958E6614811999433D934CCD54A03CC4BF359798F90EC809CFA6E58C1CE68B5AF397E8E35951F9CC4BCD0EC8655486543B4CF7605CE15969A2D88E8CD6BCA82671A06FC54397840BBA9DB2750B0F1FBC61ECF6E514450A7E06C6E6BBBB2CFA5E045335F04A5C407EC6467D471226ED2CB3AE9FBA9E956F8F3D05A911F9CD131BC3D95A10792097AC1C4339F8C12E40ABD274A25CF26EF286187E91261273E39856C471D861056EC3F6F5E58EB727134F9BFB870C8DD6978F247EAF67C1368BCB0BA105CDDC2BA067EBAC9C00DC15F1667664AA2A688D45E843F62467892EE9348FD96B187EB +20241129033421 2 6 100 4095 2 F32300D8DFCB79ECFB80E433E6CFA1923915D80120F52648A7AE7E8058B5DB869F2B3A9DD940E53B7D74E3214FA03234F8B026AFF16B646B39F003882F1DC17D3F6DBB89283A01B4C22168A354D6D2FDBDE3F2B0C91E9472AF1DB386DD34477F47CB24D4AFB71BB283A9760CF4EC582F1401A4F259D4AADE2BC7648A6920207DFB149BB7A4483D5E22D9DC627A8A4954C18AAAEF921CE0C597C11C95EC7C8888050124D01C43E6A33A02DACDB2EEE70920BAF2A296EB38CEADCB98CC7789BA309A5AD7916B9F7F86B0D808346E28447C4E3F31C5BC319D29A0D338EE8FC88BC9288C75004CC278BB218AA86929360079EAA71628FEFB796FFFBAD3764F677FECC0F274582ED2E371ACB500F35F378DDEDB0FA32B1B55699E41EBE958E6614811999433D934CCD54A03CC4BF359798F90EC809CFA6E58C1CE68B5AF397E8E35951F9CC4BCD0EC8655486543B4CF7605CE15969A2D88E8CD6BCA82671A06FC54397840BBA9DB2750B0F1FBC61ECF6E514450A7E06C6E6BBBB2CFA5E045335F04A5C407EC6467D471226ED2CB3AE9FBA9E956F8F3D05A911F9CD131BC3D95A10792097AC1C4339F8C12E40ABD274A25CF26EF286187E91261273E39856C471D861056EC3F6F5E58EB727134F9BFB870C8DD6978F247EAF67C1368BCB0BA105CDDC2BA067EBAC9C00DC15F1667664AA2A688D45E843F62467892EE9348FD96CEF60B +20241129033539 2 6 100 4095 2 F32300D8DFCB79ECFB80E433E6CFA1923915D80120F52648A7AE7E8058B5DB869F2B3A9DD940E53B7D74E3214FA03234F8B026AFF16B646B39F003882F1DC17D3F6DBB89283A01B4C22168A354D6D2FDBDE3F2B0C91E9472AF1DB386DD34477F47CB24D4AFB71BB283A9760CF4EC582F1401A4F259D4AADE2BC7648A6920207DFB149BB7A4483D5E22D9DC627A8A4954C18AAAEF921CE0C597C11C95EC7C8888050124D01C43E6A33A02DACDB2EEE70920BAF2A296EB38CEADCB98CC7789BA309A5AD7916B9F7F86B0D808346E28447C4E3F31C5BC319D29A0D338EE8FC88BC9288C75004CC278BB218AA86929360079EAA71628FEFB796FFFBAD3764F677FECC0F274582ED2E371ACB500F35F378DDEDB0FA32B1B55699E41EBE958E6614811999433D934CCD54A03CC4BF359798F90EC809CFA6E58C1CE68B5AF397E8E35951F9CC4BCD0EC8655486543B4CF7605CE15969A2D88E8CD6BCA82671A06FC54397840BBA9DB2750B0F1FBC61ECF6E514450A7E06C6E6BBBB2CFA5E045335F04A5C407EC6467D471226ED2CB3AE9FBA9E956F8F3D05A911F9CD131BC3D95A10792097AC1C4339F8C12E40ABD274A25CF26EF286187E91261273E39856C471D861056EC3F6F5E58EB727134F9BFB870C8DD6978F247EAF67C1368BCB0BA105CDDC2BA067EBAC9C00DC15F1667664AA2A688D45E843F62467892EE9348FD974904EB +20241129033708 2 6 100 4095 2 F32300D8DFCB79ECFB80E433E6CFA1923915D80120F52648A7AE7E8058B5DB869F2B3A9DD940E53B7D74E3214FA03234F8B026AFF16B646B39F003882F1DC17D3F6DBB89283A01B4C22168A354D6D2FDBDE3F2B0C91E9472AF1DB386DD34477F47CB24D4AFB71BB283A9760CF4EC582F1401A4F259D4AADE2BC7648A6920207DFB149BB7A4483D5E22D9DC627A8A4954C18AAAEF921CE0C597C11C95EC7C8888050124D01C43E6A33A02DACDB2EEE70920BAF2A296EB38CEADCB98CC7789BA309A5AD7916B9F7F86B0D808346E28447C4E3F31C5BC319D29A0D338EE8FC88BC9288C75004CC278BB218AA86929360079EAA71628FEFB796FFFBAD3764F677FECC0F274582ED2E371ACB500F35F378DDEDB0FA32B1B55699E41EBE958E6614811999433D934CCD54A03CC4BF359798F90EC809CFA6E58C1CE68B5AF397E8E35951F9CC4BCD0EC8655486543B4CF7605CE15969A2D88E8CD6BCA82671A06FC54397840BBA9DB2750B0F1FBC61ECF6E514450A7E06C6E6BBBB2CFA5E045335F04A5C407EC6467D471226ED2CB3AE9FBA9E956F8F3D05A911F9CD131BC3D95A10792097AC1C4339F8C12E40ABD274A25CF26EF286187E91261273E39856C471D861056EC3F6F5E58EB727134F9BFB870C8DD6978F247EAF67C1368BCB0BA105CDDC2BA067EBAC9C00DC15F1667664AA2A688D45E843F62467892EE9348FD97D1728B +20241129033818 2 6 100 4095 5 F32300D8DFCB79ECFB80E433E6CFA1923915D80120F52648A7AE7E8058B5DB869F2B3A9DD940E53B7D74E3214FA03234F8B026AFF16B646B39F003882F1DC17D3F6DBB89283A01B4C22168A354D6D2FDBDE3F2B0C91E9472AF1DB386DD34477F47CB24D4AFB71BB283A9760CF4EC582F1401A4F259D4AADE2BC7648A6920207DFB149BB7A4483D5E22D9DC627A8A4954C18AAAEF921CE0C597C11C95EC7C8888050124D01C43E6A33A02DACDB2EEE70920BAF2A296EB38CEADCB98CC7789BA309A5AD7916B9F7F86B0D808346E28447C4E3F31C5BC319D29A0D338EE8FC88BC9288C75004CC278BB218AA86929360079EAA71628FEFB796FFFBAD3764F677FECC0F274582ED2E371ACB500F35F378DDEDB0FA32B1B55699E41EBE958E6614811999433D934CCD54A03CC4BF359798F90EC809CFA6E58C1CE68B5AF397E8E35951F9CC4BCD0EC8655486543B4CF7605CE15969A2D88E8CD6BCA82671A06FC54397840BBA9DB2750B0F1FBC61ECF6E514450A7E06C6E6BBBB2CFA5E045335F04A5C407EC6467D471226ED2CB3AE9FBA9E956F8F3D05A911F9CD131BC3D95A10792097AC1C4339F8C12E40ABD274A25CF26EF286187E91261273E39856C471D861056EC3F6F5E58EB727134F9BFB870C8DD6978F247EAF67C1368BCB0BA105CDDC2BA067EBAC9C00DC15F1667664AA2A688D45E843F62467892EE9348FD983ADCCF +20241129033844 2 6 100 4095 5 F32300D8DFCB79ECFB80E433E6CFA1923915D80120F52648A7AE7E8058B5DB869F2B3A9DD940E53B7D74E3214FA03234F8B026AFF16B646B39F003882F1DC17D3F6DBB89283A01B4C22168A354D6D2FDBDE3F2B0C91E9472AF1DB386DD34477F47CB24D4AFB71BB283A9760CF4EC582F1401A4F259D4AADE2BC7648A6920207DFB149BB7A4483D5E22D9DC627A8A4954C18AAAEF921CE0C597C11C95EC7C8888050124D01C43E6A33A02DACDB2EEE70920BAF2A296EB38CEADCB98CC7789BA309A5AD7916B9F7F86B0D808346E28447C4E3F31C5BC319D29A0D338EE8FC88BC9288C75004CC278BB218AA86929360079EAA71628FEFB796FFFBAD3764F677FECC0F274582ED2E371ACB500F35F378DDEDB0FA32B1B55699E41EBE958E6614811999433D934CCD54A03CC4BF359798F90EC809CFA6E58C1CE68B5AF397E8E35951F9CC4BCD0EC8655486543B4CF7605CE15969A2D88E8CD6BCA82671A06FC54397840BBA9DB2750B0F1FBC61ECF6E514450A7E06C6E6BBBB2CFA5E045335F04A5C407EC6467D471226ED2CB3AE9FBA9E956F8F3D05A911F9CD131BC3D95A10792097AC1C4339F8C12E40ABD274A25CF26EF286187E91261273E39856C471D861056EC3F6F5E58EB727134F9BFB870C8DD6978F247EAF67C1368BCB0BA105CDDC2BA067EBAC9C00DC15F1667664AA2A688D45E843F62467892EE9348FD985DB957 +20241129033919 2 6 100 4095 5 F32300D8DFCB79ECFB80E433E6CFA1923915D80120F52648A7AE7E8058B5DB869F2B3A9DD940E53B7D74E3214FA03234F8B026AFF16B646B39F003882F1DC17D3F6DBB89283A01B4C22168A354D6D2FDBDE3F2B0C91E9472AF1DB386DD34477F47CB24D4AFB71BB283A9760CF4EC582F1401A4F259D4AADE2BC7648A6920207DFB149BB7A4483D5E22D9DC627A8A4954C18AAAEF921CE0C597C11C95EC7C8888050124D01C43E6A33A02DACDB2EEE70920BAF2A296EB38CEADCB98CC7789BA309A5AD7916B9F7F86B0D808346E28447C4E3F31C5BC319D29A0D338EE8FC88BC9288C75004CC278BB218AA86929360079EAA71628FEFB796FFFBAD3764F677FECC0F274582ED2E371ACB500F35F378DDEDB0FA32B1B55699E41EBE958E6614811999433D934CCD54A03CC4BF359798F90EC809CFA6E58C1CE68B5AF397E8E35951F9CC4BCD0EC8655486543B4CF7605CE15969A2D88E8CD6BCA82671A06FC54397840BBA9DB2750B0F1FBC61ECF6E514450A7E06C6E6BBBB2CFA5E045335F04A5C407EC6467D471226ED2CB3AE9FBA9E956F8F3D05A911F9CD131BC3D95A10792097AC1C4339F8C12E40ABD274A25CF26EF286187E91261273E39856C471D861056EC3F6F5E58EB727134F9BFB870C8DD6978F247EAF67C1368BCB0BA105CDDC2BA067EBAC9C00DC15F1667664AA2A688D45E843F62467892EE9348FD9890287F +20241129034126 2 6 100 4095 5 F32300D8DFCB79ECFB80E433E6CFA1923915D80120F52648A7AE7E8058B5DB869F2B3A9DD940E53B7D74E3214FA03234F8B026AFF16B646B39F003882F1DC17D3F6DBB89283A01B4C22168A354D6D2FDBDE3F2B0C91E9472AF1DB386DD34477F47CB24D4AFB71BB283A9760CF4EC582F1401A4F259D4AADE2BC7648A6920207DFB149BB7A4483D5E22D9DC627A8A4954C18AAAEF921CE0C597C11C95EC7C8888050124D01C43E6A33A02DACDB2EEE70920BAF2A296EB38CEADCB98CC7789BA309A5AD7916B9F7F86B0D808346E28447C4E3F31C5BC319D29A0D338EE8FC88BC9288C75004CC278BB218AA86929360079EAA71628FEFB796FFFBAD3764F677FECC0F274582ED2E371ACB500F35F378DDEDB0FA32B1B55699E41EBE958E6614811999433D934CCD54A03CC4BF359798F90EC809CFA6E58C1CE68B5AF397E8E35951F9CC4BCD0EC8655486543B4CF7605CE15969A2D88E8CD6BCA82671A06FC54397840BBA9DB2750B0F1FBC61ECF6E514450A7E06C6E6BBBB2CFA5E045335F04A5C407EC6467D471226ED2CB3AE9FBA9E956F8F3D05A911F9CD131BC3D95A10792097AC1C4339F8C12E40ABD274A25CF26EF286187E91261273E39856C471D861056EC3F6F5E58EB727134F9BFB870C8DD6978F247EAF67C1368BCB0BA105CDDC2BA067EBAC9C00DC15F1667664AA2A688D45E843F62467892EE9348FD9958DADF +20241129034406 2 6 100 4095 2 F32300D8DFCB79ECFB80E433E6CFA1923915D80120F52648A7AE7E8058B5DB869F2B3A9DD940E53B7D74E3214FA03234F8B026AFF16B646B39F003882F1DC17D3F6DBB89283A01B4C22168A354D6D2FDBDE3F2B0C91E9472AF1DB386DD34477F47CB24D4AFB71BB283A9760CF4EC582F1401A4F259D4AADE2BC7648A6920207DFB149BB7A4483D5E22D9DC627A8A4954C18AAAEF921CE0C597C11C95EC7C8888050124D01C43E6A33A02DACDB2EEE70920BAF2A296EB38CEADCB98CC7789BA309A5AD7916B9F7F86B0D808346E28447C4E3F31C5BC319D29A0D338EE8FC88BC9288C75004CC278BB218AA86929360079EAA71628FEFB796FFFBAD3764F677FECC0F274582ED2E371ACB500F35F378DDEDB0FA32B1B55699E41EBE958E6614811999433D934CCD54A03CC4BF359798F90EC809CFA6E58C1CE68B5AF397E8E35951F9CC4BCD0EC8655486543B4CF7605CE15969A2D88E8CD6BCA82671A06FC54397840BBA9DB2750B0F1FBC61ECF6E514450A7E06C6E6BBBB2CFA5E045335F04A5C407EC6467D471226ED2CB3AE9FBA9E956F8F3D05A911F9CD131BC3D95A10792097AC1C4339F8C12E40ABD274A25CF26EF286187E91261273E39856C471D861056EC3F6F5E58EB727134F9BFB870C8DD6978F247EAF67C1368BCB0BA105CDDC2BA067EBAC9C00DC15F1667664AA2A688D45E843F62467892EE9348FD9A557F5B +20241129034820 2 6 100 4095 5 F32300D8DFCB79ECFB80E433E6CFA1923915D80120F52648A7AE7E8058B5DB869F2B3A9DD940E53B7D74E3214FA03234F8B026AFF16B646B39F003882F1DC17D3F6DBB89283A01B4C22168A354D6D2FDBDE3F2B0C91E9472AF1DB386DD34477F47CB24D4AFB71BB283A9760CF4EC582F1401A4F259D4AADE2BC7648A6920207DFB149BB7A4483D5E22D9DC627A8A4954C18AAAEF921CE0C597C11C95EC7C8888050124D01C43E6A33A02DACDB2EEE70920BAF2A296EB38CEADCB98CC7789BA309A5AD7916B9F7F86B0D808346E28447C4E3F31C5BC319D29A0D338EE8FC88BC9288C75004CC278BB218AA86929360079EAA71628FEFB796FFFBAD3764F677FECC0F274582ED2E371ACB500F35F378DDEDB0FA32B1B55699E41EBE958E6614811999433D934CCD54A03CC4BF359798F90EC809CFA6E58C1CE68B5AF397E8E35951F9CC4BCD0EC8655486543B4CF7605CE15969A2D88E8CD6BCA82671A06FC54397840BBA9DB2750B0F1FBC61ECF6E514450A7E06C6E6BBBB2CFA5E045335F04A5C407EC6467D471226ED2CB3AE9FBA9E956F8F3D05A911F9CD131BC3D95A10792097AC1C4339F8C12E40ABD274A25CF26EF286187E91261273E39856C471D861056EC3F6F5E58EB727134F9BFB870C8DD6978F247EAF67C1368BCB0BA105CDDC2BA067EBAC9C00DC15F1667664AA2A688D45E843F62467892EE9348FD9BEF30FF +20241129035154 2 6 100 4095 2 F32300D8DFCB79ECFB80E433E6CFA1923915D80120F52648A7AE7E8058B5DB869F2B3A9DD940E53B7D74E3214FA03234F8B026AFF16B646B39F003882F1DC17D3F6DBB89283A01B4C22168A354D6D2FDBDE3F2B0C91E9472AF1DB386DD34477F47CB24D4AFB71BB283A9760CF4EC582F1401A4F259D4AADE2BC7648A6920207DFB149BB7A4483D5E22D9DC627A8A4954C18AAAEF921CE0C597C11C95EC7C8888050124D01C43E6A33A02DACDB2EEE70920BAF2A296EB38CEADCB98CC7789BA309A5AD7916B9F7F86B0D808346E28447C4E3F31C5BC319D29A0D338EE8FC88BC9288C75004CC278BB218AA86929360079EAA71628FEFB796FFFBAD3764F677FECC0F274582ED2E371ACB500F35F378DDEDB0FA32B1B55699E41EBE958E6614811999433D934CCD54A03CC4BF359798F90EC809CFA6E58C1CE68B5AF397E8E35951F9CC4BCD0EC8655486543B4CF7605CE15969A2D88E8CD6BCA82671A06FC54397840BBA9DB2750B0F1FBC61ECF6E514450A7E06C6E6BBBB2CFA5E045335F04A5C407EC6467D471226ED2CB3AE9FBA9E956F8F3D05A911F9CD131BC3D95A10792097AC1C4339F8C12E40ABD274A25CF26EF286187E91261273E39856C471D861056EC3F6F5E58EB727134F9BFB870C8DD6978F247EAF67C1368BCB0BA105CDDC2BA067EBAC9C00DC15F1667664AA2A688D45E843F62467892EE9348FD9D4E229B +20241129035209 2 6 100 4095 5 F32300D8DFCB79ECFB80E433E6CFA1923915D80120F52648A7AE7E8058B5DB869F2B3A9DD940E53B7D74E3214FA03234F8B026AFF16B646B39F003882F1DC17D3F6DBB89283A01B4C22168A354D6D2FDBDE3F2B0C91E9472AF1DB386DD34477F47CB24D4AFB71BB283A9760CF4EC582F1401A4F259D4AADE2BC7648A6920207DFB149BB7A4483D5E22D9DC627A8A4954C18AAAEF921CE0C597C11C95EC7C8888050124D01C43E6A33A02DACDB2EEE70920BAF2A296EB38CEADCB98CC7789BA309A5AD7916B9F7F86B0D808346E28447C4E3F31C5BC319D29A0D338EE8FC88BC9288C75004CC278BB218AA86929360079EAA71628FEFB796FFFBAD3764F677FECC0F274582ED2E371ACB500F35F378DDEDB0FA32B1B55699E41EBE958E6614811999433D934CCD54A03CC4BF359798F90EC809CFA6E58C1CE68B5AF397E8E35951F9CC4BCD0EC8655486543B4CF7605CE15969A2D88E8CD6BCA82671A06FC54397840BBA9DB2750B0F1FBC61ECF6E514450A7E06C6E6BBBB2CFA5E045335F04A5C407EC6467D471226ED2CB3AE9FBA9E956F8F3D05A911F9CD131BC3D95A10792097AC1C4339F8C12E40ABD274A25CF26EF286187E91261273E39856C471D861056EC3F6F5E58EB727134F9BFB870C8DD6978F247EAF67C1368BCB0BA105CDDC2BA067EBAC9C00DC15F1667664AA2A688D45E843F62467892EE9348FD9D5EE0CF +20241129035316 2 6 100 4095 5 F32300D8DFCB79ECFB80E433E6CFA1923915D80120F52648A7AE7E8058B5DB869F2B3A9DD940E53B7D74E3214FA03234F8B026AFF16B646B39F003882F1DC17D3F6DBB89283A01B4C22168A354D6D2FDBDE3F2B0C91E9472AF1DB386DD34477F47CB24D4AFB71BB283A9760CF4EC582F1401A4F259D4AADE2BC7648A6920207DFB149BB7A4483D5E22D9DC627A8A4954C18AAAEF921CE0C597C11C95EC7C8888050124D01C43E6A33A02DACDB2EEE70920BAF2A296EB38CEADCB98CC7789BA309A5AD7916B9F7F86B0D808346E28447C4E3F31C5BC319D29A0D338EE8FC88BC9288C75004CC278BB218AA86929360079EAA71628FEFB796FFFBAD3764F677FECC0F274582ED2E371ACB500F35F378DDEDB0FA32B1B55699E41EBE958E6614811999433D934CCD54A03CC4BF359798F90EC809CFA6E58C1CE68B5AF397E8E35951F9CC4BCD0EC8655486543B4CF7605CE15969A2D88E8CD6BCA82671A06FC54397840BBA9DB2750B0F1FBC61ECF6E514450A7E06C6E6BBBB2CFA5E045335F04A5C407EC6467D471226ED2CB3AE9FBA9E956F8F3D05A911F9CD131BC3D95A10792097AC1C4339F8C12E40ABD274A25CF26EF286187E91261273E39856C471D861056EC3F6F5E58EB727134F9BFB870C8DD6978F247EAF67C1368BCB0BA105CDDC2BA067EBAC9C00DC15F1667664AA2A688D45E843F62467892EE9348FD9DC2D03F +20241129035349 2 6 100 4095 2 F32300D8DFCB79ECFB80E433E6CFA1923915D80120F52648A7AE7E8058B5DB869F2B3A9DD940E53B7D74E3214FA03234F8B026AFF16B646B39F003882F1DC17D3F6DBB89283A01B4C22168A354D6D2FDBDE3F2B0C91E9472AF1DB386DD34477F47CB24D4AFB71BB283A9760CF4EC582F1401A4F259D4AADE2BC7648A6920207DFB149BB7A4483D5E22D9DC627A8A4954C18AAAEF921CE0C597C11C95EC7C8888050124D01C43E6A33A02DACDB2EEE70920BAF2A296EB38CEADCB98CC7789BA309A5AD7916B9F7F86B0D808346E28447C4E3F31C5BC319D29A0D338EE8FC88BC9288C75004CC278BB218AA86929360079EAA71628FEFB796FFFBAD3764F677FECC0F274582ED2E371ACB500F35F378DDEDB0FA32B1B55699E41EBE958E6614811999433D934CCD54A03CC4BF359798F90EC809CFA6E58C1CE68B5AF397E8E35951F9CC4BCD0EC8655486543B4CF7605CE15969A2D88E8CD6BCA82671A06FC54397840BBA9DB2750B0F1FBC61ECF6E514450A7E06C6E6BBBB2CFA5E045335F04A5C407EC6467D471226ED2CB3AE9FBA9E956F8F3D05A911F9CD131BC3D95A10792097AC1C4339F8C12E40ABD274A25CF26EF286187E91261273E39856C471D861056EC3F6F5E58EB727134F9BFB870C8DD6978F247EAF67C1368BCB0BA105CDDC2BA067EBAC9C00DC15F1667664AA2A688D45E843F62467892EE9348FD9DF64ABB +20241129035856 2 6 100 4095 5 F32300D8DFCB79ECFB80E433E6CFA1923915D80120F52648A7AE7E8058B5DB869F2B3A9DD940E53B7D74E3214FA03234F8B026AFF16B646B39F003882F1DC17D3F6DBB89283A01B4C22168A354D6D2FDBDE3F2B0C91E9472AF1DB386DD34477F47CB24D4AFB71BB283A9760CF4EC582F1401A4F259D4AADE2BC7648A6920207DFB149BB7A4483D5E22D9DC627A8A4954C18AAAEF921CE0C597C11C95EC7C8888050124D01C43E6A33A02DACDB2EEE70920BAF2A296EB38CEADCB98CC7789BA309A5AD7916B9F7F86B0D808346E28447C4E3F31C5BC319D29A0D338EE8FC88BC9288C75004CC278BB218AA86929360079EAA71628FEFB796FFFBAD3764F677FECC0F274582ED2E371ACB500F35F378DDEDB0FA32B1B55699E41EBE958E6614811999433D934CCD54A03CC4BF359798F90EC809CFA6E58C1CE68B5AF397E8E35951F9CC4BCD0EC8655486543B4CF7605CE15969A2D88E8CD6BCA82671A06FC54397840BBA9DB2750B0F1FBC61ECF6E514450A7E06C6E6BBBB2CFA5E045335F04A5C407EC6467D471226ED2CB3AE9FBA9E956F8F3D05A911F9CD131BC3D95A10792097AC1C4339F8C12E40ABD274A25CF26EF286187E91261273E39856C471D861056EC3F6F5E58EB727134F9BFB870C8DD6978F247EAF67C1368BCB0BA105CDDC2BA067EBAC9C00DC15F1667664AA2A688D45E843F62467892EE9348FD9FE86E1F +20241129040054 2 6 100 4095 2 F32300D8DFCB79ECFB80E433E6CFA1923915D80120F52648A7AE7E8058B5DB869F2B3A9DD940E53B7D74E3214FA03234F8B026AFF16B646B39F003882F1DC17D3F6DBB89283A01B4C22168A354D6D2FDBDE3F2B0C91E9472AF1DB386DD34477F47CB24D4AFB71BB283A9760CF4EC582F1401A4F259D4AADE2BC7648A6920207DFB149BB7A4483D5E22D9DC627A8A4954C18AAAEF921CE0C597C11C95EC7C8888050124D01C43E6A33A02DACDB2EEE70920BAF2A296EB38CEADCB98CC7789BA309A5AD7916B9F7F86B0D808346E28447C4E3F31C5BC319D29A0D338EE8FC88BC9288C75004CC278BB218AA86929360079EAA71628FEFB796FFFBAD3764F677FECC0F274582ED2E371ACB500F35F378DDEDB0FA32B1B55699E41EBE958E6614811999433D934CCD54A03CC4BF359798F90EC809CFA6E58C1CE68B5AF397E8E35951F9CC4BCD0EC8655486543B4CF7605CE15969A2D88E8CD6BCA82671A06FC54397840BBA9DB2750B0F1FBC61ECF6E514450A7E06C6E6BBBB2CFA5E045335F04A5C407EC6467D471226ED2CB3AE9FBA9E956F8F3D05A911F9CD131BC3D95A10792097AC1C4339F8C12E40ABD274A25CF26EF286187E91261273E39856C471D861056EC3F6F5E58EB727134F9BFB870C8DD6978F247EAF67C1368BCB0BA105CDDC2BA067EBAC9C00DC15F1667664AA2A688D45E843F62467892EE9348FDA0A085D3 +20241129040234 2 6 100 4095 2 F32300D8DFCB79ECFB80E433E6CFA1923915D80120F52648A7AE7E8058B5DB869F2B3A9DD940E53B7D74E3214FA03234F8B026AFF16B646B39F003882F1DC17D3F6DBB89283A01B4C22168A354D6D2FDBDE3F2B0C91E9472AF1DB386DD34477F47CB24D4AFB71BB283A9760CF4EC582F1401A4F259D4AADE2BC7648A6920207DFB149BB7A4483D5E22D9DC627A8A4954C18AAAEF921CE0C597C11C95EC7C8888050124D01C43E6A33A02DACDB2EEE70920BAF2A296EB38CEADCB98CC7789BA309A5AD7916B9F7F86B0D808346E28447C4E3F31C5BC319D29A0D338EE8FC88BC9288C75004CC278BB218AA86929360079EAA71628FEFB796FFFBAD3764F677FECC0F274582ED2E371ACB500F35F378DDEDB0FA32B1B55699E41EBE958E6614811999433D934CCD54A03CC4BF359798F90EC809CFA6E58C1CE68B5AF397E8E35951F9CC4BCD0EC8655486543B4CF7605CE15969A2D88E8CD6BCA82671A06FC54397840BBA9DB2750B0F1FBC61ECF6E514450A7E06C6E6BBBB2CFA5E045335F04A5C407EC6467D471226ED2CB3AE9FBA9E956F8F3D05A911F9CD131BC3D95A10792097AC1C4339F8C12E40ABD274A25CF26EF286187E91261273E39856C471D861056EC3F6F5E58EB727134F9BFB870C8DD6978F247EAF67C1368BCB0BA105CDDC2BA067EBAC9C00DC15F1667664AA2A688D45E843F62467892EE9348FDA13D2323 +20241129040334 2 6 100 4095 2 F32300D8DFCB79ECFB80E433E6CFA1923915D80120F52648A7AE7E8058B5DB869F2B3A9DD940E53B7D74E3214FA03234F8B026AFF16B646B39F003882F1DC17D3F6DBB89283A01B4C22168A354D6D2FDBDE3F2B0C91E9472AF1DB386DD34477F47CB24D4AFB71BB283A9760CF4EC582F1401A4F259D4AADE2BC7648A6920207DFB149BB7A4483D5E22D9DC627A8A4954C18AAAEF921CE0C597C11C95EC7C8888050124D01C43E6A33A02DACDB2EEE70920BAF2A296EB38CEADCB98CC7789BA309A5AD7916B9F7F86B0D808346E28447C4E3F31C5BC319D29A0D338EE8FC88BC9288C75004CC278BB218AA86929360079EAA71628FEFB796FFFBAD3764F677FECC0F274582ED2E371ACB500F35F378DDEDB0FA32B1B55699E41EBE958E6614811999433D934CCD54A03CC4BF359798F90EC809CFA6E58C1CE68B5AF397E8E35951F9CC4BCD0EC8655486543B4CF7605CE15969A2D88E8CD6BCA82671A06FC54397840BBA9DB2750B0F1FBC61ECF6E514450A7E06C6E6BBBB2CFA5E045335F04A5C407EC6467D471226ED2CB3AE9FBA9E956F8F3D05A911F9CD131BC3D95A10792097AC1C4339F8C12E40ABD274A25CF26EF286187E91261273E39856C471D861056EC3F6F5E58EB727134F9BFB870C8DD6978F247EAF67C1368BCB0BA105CDDC2BA067EBAC9C00DC15F1667664AA2A688D45E843F62467892EE9348FDA19957FB +20241129040452 2 6 100 4095 5 F32300D8DFCB79ECFB80E433E6CFA1923915D80120F52648A7AE7E8058B5DB869F2B3A9DD940E53B7D74E3214FA03234F8B026AFF16B646B39F003882F1DC17D3F6DBB89283A01B4C22168A354D6D2FDBDE3F2B0C91E9472AF1DB386DD34477F47CB24D4AFB71BB283A9760CF4EC582F1401A4F259D4AADE2BC7648A6920207DFB149BB7A4483D5E22D9DC627A8A4954C18AAAEF921CE0C597C11C95EC7C8888050124D01C43E6A33A02DACDB2EEE70920BAF2A296EB38CEADCB98CC7789BA309A5AD7916B9F7F86B0D808346E28447C4E3F31C5BC319D29A0D338EE8FC88BC9288C75004CC278BB218AA86929360079EAA71628FEFB796FFFBAD3764F677FECC0F274582ED2E371ACB500F35F378DDEDB0FA32B1B55699E41EBE958E6614811999433D934CCD54A03CC4BF359798F90EC809CFA6E58C1CE68B5AF397E8E35951F9CC4BCD0EC8655486543B4CF7605CE15969A2D88E8CD6BCA82671A06FC54397840BBA9DB2750B0F1FBC61ECF6E514450A7E06C6E6BBBB2CFA5E045335F04A5C407EC6467D471226ED2CB3AE9FBA9E956F8F3D05A911F9CD131BC3D95A10792097AC1C4339F8C12E40ABD274A25CF26EF286187E91261273E39856C471D861056EC3F6F5E58EB727134F9BFB870C8DD6978F247EAF67C1368BCB0BA105CDDC2BA067EBAC9C00DC15F1667664AA2A688D45E843F62467892EE9348FDA2168307 +20241129040614 2 6 100 4095 2 F32300D8DFCB79ECFB80E433E6CFA1923915D80120F52648A7AE7E8058B5DB869F2B3A9DD940E53B7D74E3214FA03234F8B026AFF16B646B39F003882F1DC17D3F6DBB89283A01B4C22168A354D6D2FDBDE3F2B0C91E9472AF1DB386DD34477F47CB24D4AFB71BB283A9760CF4EC582F1401A4F259D4AADE2BC7648A6920207DFB149BB7A4483D5E22D9DC627A8A4954C18AAAEF921CE0C597C11C95EC7C8888050124D01C43E6A33A02DACDB2EEE70920BAF2A296EB38CEADCB98CC7789BA309A5AD7916B9F7F86B0D808346E28447C4E3F31C5BC319D29A0D338EE8FC88BC9288C75004CC278BB218AA86929360079EAA71628FEFB796FFFBAD3764F677FECC0F274582ED2E371ACB500F35F378DDEDB0FA32B1B55699E41EBE958E6614811999433D934CCD54A03CC4BF359798F90EC809CFA6E58C1CE68B5AF397E8E35951F9CC4BCD0EC8655486543B4CF7605CE15969A2D88E8CD6BCA82671A06FC54397840BBA9DB2750B0F1FBC61ECF6E514450A7E06C6E6BBBB2CFA5E045335F04A5C407EC6467D471226ED2CB3AE9FBA9E956F8F3D05A911F9CD131BC3D95A10792097AC1C4339F8C12E40ABD274A25CF26EF286187E91261273E39856C471D861056EC3F6F5E58EB727134F9BFB870C8DD6978F247EAF67C1368BCB0BA105CDDC2BA067EBAC9C00DC15F1667664AA2A688D45E843F62467892EE9348FDA29615EB +20241129040924 2 6 100 4095 2 F32300D8DFCB79ECFB80E433E6CFA1923915D80120F52648A7AE7E8058B5DB869F2B3A9DD940E53B7D74E3214FA03234F8B026AFF16B646B39F003882F1DC17D3F6DBB89283A01B4C22168A354D6D2FDBDE3F2B0C91E9472AF1DB386DD34477F47CB24D4AFB71BB283A9760CF4EC582F1401A4F259D4AADE2BC7648A6920207DFB149BB7A4483D5E22D9DC627A8A4954C18AAAEF921CE0C597C11C95EC7C8888050124D01C43E6A33A02DACDB2EEE70920BAF2A296EB38CEADCB98CC7789BA309A5AD7916B9F7F86B0D808346E28447C4E3F31C5BC319D29A0D338EE8FC88BC9288C75004CC278BB218AA86929360079EAA71628FEFB796FFFBAD3764F677FECC0F274582ED2E371ACB500F35F378DDEDB0FA32B1B55699E41EBE958E6614811999433D934CCD54A03CC4BF359798F90EC809CFA6E58C1CE68B5AF397E8E35951F9CC4BCD0EC8655486543B4CF7605CE15969A2D88E8CD6BCA82671A06FC54397840BBA9DB2750B0F1FBC61ECF6E514450A7E06C6E6BBBB2CFA5E045335F04A5C407EC6467D471226ED2CB3AE9FBA9E956F8F3D05A911F9CD131BC3D95A10792097AC1C4339F8C12E40ABD274A25CF26EF286187E91261273E39856C471D861056EC3F6F5E58EB727134F9BFB870C8DD6978F247EAF67C1368BCB0BA105CDDC2BA067EBAC9C00DC15F1667664AA2A688D45E843F62467892EE9348FDA3C1BBEB +20241129041726 2 6 100 4095 2 F32300D8DFCB79ECFB80E433E6CFA1923915D80120F52648A7AE7E8058B5DB869F2B3A9DD940E53B7D74E3214FA03234F8B026AFF16B646B39F003882F1DC17D3F6DBB89283A01B4C22168A354D6D2FDBDE3F2B0C91E9472AF1DB386DD34477F47CB24D4AFB71BB283A9760CF4EC582F1401A4F259D4AADE2BC7648A6920207DFB149BB7A4483D5E22D9DC627A8A4954C18AAAEF921CE0C597C11C95EC7C8888050124D01C43E6A33A02DACDB2EEE70920BAF2A296EB38CEADCB98CC7789BA309A5AD7916B9F7F86B0D808346E28447C4E3F31C5BC319D29A0D338EE8FC88BC9288C75004CC278BB218AA86929360079EAA71628FEFB796FFFBAD3764F677FECC0F274582ED2E371ACB500F35F378DDEDB0FA32B1B55699E41EBE958E6614811999433D934CCD54A03CC4BF359798F90EC809CFA6E58C1CE68B5AF397E8E35951F9CC4BCD0EC8655486543B4CF7605CE15969A2D88E8CD6BCA82671A06FC54397840BBA9DB2750B0F1FBC61ECF6E514450A7E06C6E6BBBB2CFA5E045335F04A5C407EC6467D471226ED2CB3AE9FBA9E956F8F3D05A911F9CD131BC3D95A10792097AC1C4339F8C12E40ABD274A25CF26EF286187E91261273E39856C471D861056EC3F6F5E58EB727134F9BFB870C8DD6978F247EAF67C1368BCB0BA105CDDC2BA067EBAC9C00DC15F1667664AA2A688D45E843F62467892EE9348FDA6CBD37B +20241129044525 2 6 100 6143 5 DCBE8A152DD5DE612BFCCD18CAB2BDE17391AF9DA865DCC59A1B454144ADE2EB8BE3CDBA7948CD1236CFC25D66DDC0E91095FB7E17715247413BBFD5435223F46488AD93808AF9FAF7D473C7CCE55DAA83B417FC6C09BFF7E332BD4B3BC59CBA4FE035A6C416D32BDCF8C3B9AFC5E1120CFD420023FD8EB207DB965509E2D362B0EB3D8CBD191D2750EBEB05F32C4BE08154D991F08DE4914BC40FAA7172440F2FEFB0FBF604DDA9C18BA9FD55F34218FD5D7CA2AC491CEDC3C5743D143BAF6C06CCAB7E5B22AB4E46CD51962CC7931F4D35581D5DD3047B946044BF7E71955EB63DD546644D7D2A19777DA39A48B4CF5A011A5C41F1BFF7C463F057F2F7AF6F910E7E06398B0AF7EF38CD5BBAE4C5FF42572CFFFCA6A8E9D34F64A7BECDC93216B55C20FAECAF04A8956C4D26DEE34493510BC49144A32A1B0AAE64B50DCA0C27361692242FE3145A6B36B830DEBF9E8A07A886E8DA6F38F3E99906F6AC9317ADF73222C4C75ABD153F1112E01E7CBB49665F213A1C1470CDC442D7CDC72EE2DD80D37251333C34FFDC5C38ADA3F5E52F5A5B2A1224B0CA60211B430E9554F0C4CA672476562C4A182B6707EBE80DFA6247A1F870F74EC81D03558F2718409EBF8E7F2FD2C6AB1F246F7E3FE0D919DB4016A7D76F6378D05EA74766CBB93340F2CBDDF18073F39242F3E9EC88020D1E8F801183C00F0239B2F2B4E8F6B46DBC17F469A857C291C985D8AC2099A6FEDC462B5EAEF737831EA2B6C9D787DC5AC8DA2C2E8F7F676FDA4CDD79E400EED959882C78C279C4D0A5918A0F5FC3B695E0034F7C2665D52D94106744D6B0CD6A66AB3275324EFDC06ECCF431D446446A00818ECDBE77B845699FB4F699825702D00F71373D80452039ECA1237AD2A0DF9112BA1EC90FB9FB87CF4E46BD0319B64F2EFD4B9640469707DB549468781D0BA6F3C49AF035D441173786BB1F2F5DCCE07BBF5536A0EB5B976814ABFDB44B90E55455972701A8F0D8EFB860A082ABA960E704754F61C2E3956922833F3D7E1656476DEE3C4F09244AC15697EA4A73041F03EEDE1F30BF899098A70F33DDF12A47 +20241129045351 2 6 100 6143 2 DCBE8A152DD5DE612BFCCD18CAB2BDE17391AF9DA865DCC59A1B454144ADE2EB8BE3CDBA7948CD1236CFC25D66DDC0E91095FB7E17715247413BBFD5435223F46488AD93808AF9FAF7D473C7CCE55DAA83B417FC6C09BFF7E332BD4B3BC59CBA4FE035A6C416D32BDCF8C3B9AFC5E1120CFD420023FD8EB207DB965509E2D362B0EB3D8CBD191D2750EBEB05F32C4BE08154D991F08DE4914BC40FAA7172440F2FEFB0FBF604DDA9C18BA9FD55F34218FD5D7CA2AC491CEDC3C5743D143BAF6C06CCAB7E5B22AB4E46CD51962CC7931F4D35581D5DD3047B946044BF7E71955EB63DD546644D7D2A19777DA39A48B4CF5A011A5C41F1BFF7C463F057F2F7AF6F910E7E06398B0AF7EF38CD5BBAE4C5FF42572CFFFCA6A8E9D34F64A7BECDC93216B55C20FAECAF04A8956C4D26DEE34493510BC49144A32A1B0AAE64B50DCA0C27361692242FE3145A6B36B830DEBF9E8A07A886E8DA6F38F3E99906F6AC9317ADF73222C4C75ABD153F1112E01E7CBB49665F213A1C1470CDC442D7CDC72EE2DD80D37251333C34FFDC5C38ADA3F5E52F5A5B2A1224B0CA60211B430E9554F0C4CA672476562C4A182B6707EBE80DFA6247A1F870F74EC81D03558F2718409EBF8E7F2FD2C6AB1F246F7E3FE0D919DB4016A7D76F6378D05EA74766CBB93340F2CBDDF18073F39242F3E9EC88020D1E8F801183C00F0239B2F2B4E8F6B46DBC17F469A857C291C985D8AC2099A6FEDC462B5EAEF737831EA2B6C9D787DC5AC8DA2C2E8F7F676FDA4CDD79E400EED959882C78C279C4D0A5918A0F5FC3B695E0034F7C2665D52D94106744D6B0CD6A66AB3275324EFDC06ECCF431D446446A00818ECDBE77B845699FB4F699825702D00F71373D80452039ECA1237AD2A0DF9112BA1EC90FB9FB87CF4E46BD0319B64F2EFD4B9640469707DB549468781D0BA6F3C49AF035D441173786BB1F2F5DCCE07BBF5536A0EB5B976814ABFDB44B90E55455972701A8F0D8EFB860A082ABA960E704754F61C2E3956922833F3D7E1656476DEE3C4F09244AC15697EA4A73041F03EEDE1F30BF899098A70F33DEF75143 +20241129045821 2 6 100 6143 2 DCBE8A152DD5DE612BFCCD18CAB2BDE17391AF9DA865DCC59A1B454144ADE2EB8BE3CDBA7948CD1236CFC25D66DDC0E91095FB7E17715247413BBFD5435223F46488AD93808AF9FAF7D473C7CCE55DAA83B417FC6C09BFF7E332BD4B3BC59CBA4FE035A6C416D32BDCF8C3B9AFC5E1120CFD420023FD8EB207DB965509E2D362B0EB3D8CBD191D2750EBEB05F32C4BE08154D991F08DE4914BC40FAA7172440F2FEFB0FBF604DDA9C18BA9FD55F34218FD5D7CA2AC491CEDC3C5743D143BAF6C06CCAB7E5B22AB4E46CD51962CC7931F4D35581D5DD3047B946044BF7E71955EB63DD546644D7D2A19777DA39A48B4CF5A011A5C41F1BFF7C463F057F2F7AF6F910E7E06398B0AF7EF38CD5BBAE4C5FF42572CFFFCA6A8E9D34F64A7BECDC93216B55C20FAECAF04A8956C4D26DEE34493510BC49144A32A1B0AAE64B50DCA0C27361692242FE3145A6B36B830DEBF9E8A07A886E8DA6F38F3E99906F6AC9317ADF73222C4C75ABD153F1112E01E7CBB49665F213A1C1470CDC442D7CDC72EE2DD80D37251333C34FFDC5C38ADA3F5E52F5A5B2A1224B0CA60211B430E9554F0C4CA672476562C4A182B6707EBE80DFA6247A1F870F74EC81D03558F2718409EBF8E7F2FD2C6AB1F246F7E3FE0D919DB4016A7D76F6378D05EA74766CBB93340F2CBDDF18073F39242F3E9EC88020D1E8F801183C00F0239B2F2B4E8F6B46DBC17F469A857C291C985D8AC2099A6FEDC462B5EAEF737831EA2B6C9D787DC5AC8DA2C2E8F7F676FDA4CDD79E400EED959882C78C279C4D0A5918A0F5FC3B695E0034F7C2665D52D94106744D6B0CD6A66AB3275324EFDC06ECCF431D446446A00818ECDBE77B845699FB4F699825702D00F71373D80452039ECA1237AD2A0DF9112BA1EC90FB9FB87CF4E46BD0319B64F2EFD4B9640469707DB549468781D0BA6F3C49AF035D441173786BB1F2F5DCCE07BBF5536A0EB5B976814ABFDB44B90E55455972701A8F0D8EFB860A082ABA960E704754F61C2E3956922833F3D7E1656476DEE3C4F09244AC15697EA4A73041F03EEDE1F30BF899098A70F33DF7D9E33 +20241129045943 2 6 100 6143 5 DCBE8A152DD5DE612BFCCD18CAB2BDE17391AF9DA865DCC59A1B454144ADE2EB8BE3CDBA7948CD1236CFC25D66DDC0E91095FB7E17715247413BBFD5435223F46488AD93808AF9FAF7D473C7CCE55DAA83B417FC6C09BFF7E332BD4B3BC59CBA4FE035A6C416D32BDCF8C3B9AFC5E1120CFD420023FD8EB207DB965509E2D362B0EB3D8CBD191D2750EBEB05F32C4BE08154D991F08DE4914BC40FAA7172440F2FEFB0FBF604DDA9C18BA9FD55F34218FD5D7CA2AC491CEDC3C5743D143BAF6C06CCAB7E5B22AB4E46CD51962CC7931F4D35581D5DD3047B946044BF7E71955EB63DD546644D7D2A19777DA39A48B4CF5A011A5C41F1BFF7C463F057F2F7AF6F910E7E06398B0AF7EF38CD5BBAE4C5FF42572CFFFCA6A8E9D34F64A7BECDC93216B55C20FAECAF04A8956C4D26DEE34493510BC49144A32A1B0AAE64B50DCA0C27361692242FE3145A6B36B830DEBF9E8A07A886E8DA6F38F3E99906F6AC9317ADF73222C4C75ABD153F1112E01E7CBB49665F213A1C1470CDC442D7CDC72EE2DD80D37251333C34FFDC5C38ADA3F5E52F5A5B2A1224B0CA60211B430E9554F0C4CA672476562C4A182B6707EBE80DFA6247A1F870F74EC81D03558F2718409EBF8E7F2FD2C6AB1F246F7E3FE0D919DB4016A7D76F6378D05EA74766CBB93340F2CBDDF18073F39242F3E9EC88020D1E8F801183C00F0239B2F2B4E8F6B46DBC17F469A857C291C985D8AC2099A6FEDC462B5EAEF737831EA2B6C9D787DC5AC8DA2C2E8F7F676FDA4CDD79E400EED959882C78C279C4D0A5918A0F5FC3B695E0034F7C2665D52D94106744D6B0CD6A66AB3275324EFDC06ECCF431D446446A00818ECDBE77B845699FB4F699825702D00F71373D80452039ECA1237AD2A0DF9112BA1EC90FB9FB87CF4E46BD0319B64F2EFD4B9640469707DB549468781D0BA6F3C49AF035D441173786BB1F2F5DCCE07BBF5536A0EB5B976814ABFDB44B90E55455972701A8F0D8EFB860A082ABA960E704754F61C2E3956922833F3D7E1656476DEE3C4F09244AC15697EA4A73041F03EEDE1F30BF899098A70F33DFA1A9DF +20241129050501 2 6 100 6143 2 DCBE8A152DD5DE612BFCCD18CAB2BDE17391AF9DA865DCC59A1B454144ADE2EB8BE3CDBA7948CD1236CFC25D66DDC0E91095FB7E17715247413BBFD5435223F46488AD93808AF9FAF7D473C7CCE55DAA83B417FC6C09BFF7E332BD4B3BC59CBA4FE035A6C416D32BDCF8C3B9AFC5E1120CFD420023FD8EB207DB965509E2D362B0EB3D8CBD191D2750EBEB05F32C4BE08154D991F08DE4914BC40FAA7172440F2FEFB0FBF604DDA9C18BA9FD55F34218FD5D7CA2AC491CEDC3C5743D143BAF6C06CCAB7E5B22AB4E46CD51962CC7931F4D35581D5DD3047B946044BF7E71955EB63DD546644D7D2A19777DA39A48B4CF5A011A5C41F1BFF7C463F057F2F7AF6F910E7E06398B0AF7EF38CD5BBAE4C5FF42572CFFFCA6A8E9D34F64A7BECDC93216B55C20FAECAF04A8956C4D26DEE34493510BC49144A32A1B0AAE64B50DCA0C27361692242FE3145A6B36B830DEBF9E8A07A886E8DA6F38F3E99906F6AC9317ADF73222C4C75ABD153F1112E01E7CBB49665F213A1C1470CDC442D7CDC72EE2DD80D37251333C34FFDC5C38ADA3F5E52F5A5B2A1224B0CA60211B430E9554F0C4CA672476562C4A182B6707EBE80DFA6247A1F870F74EC81D03558F2718409EBF8E7F2FD2C6AB1F246F7E3FE0D919DB4016A7D76F6378D05EA74766CBB93340F2CBDDF18073F39242F3E9EC88020D1E8F801183C00F0239B2F2B4E8F6B46DBC17F469A857C291C985D8AC2099A6FEDC462B5EAEF737831EA2B6C9D787DC5AC8DA2C2E8F7F676FDA4CDD79E400EED959882C78C279C4D0A5918A0F5FC3B695E0034F7C2665D52D94106744D6B0CD6A66AB3275324EFDC06ECCF431D446446A00818ECDBE77B845699FB4F699825702D00F71373D80452039ECA1237AD2A0DF9112BA1EC90FB9FB87CF4E46BD0319B64F2EFD4B9640469707DB549468781D0BA6F3C49AF035D441173786BB1F2F5DCCE07BBF5536A0EB5B976814ABFDB44B90E55455972701A8F0D8EFB860A082ABA960E704754F61C2E3956922833F3D7E1656476DEE3C4F09244AC15697EA4A73041F03EEDE1F30BF899098A70F33E044C313 +20241129051930 2 6 100 6143 5 DCBE8A152DD5DE612BFCCD18CAB2BDE17391AF9DA865DCC59A1B454144ADE2EB8BE3CDBA7948CD1236CFC25D66DDC0E91095FB7E17715247413BBFD5435223F46488AD93808AF9FAF7D473C7CCE55DAA83B417FC6C09BFF7E332BD4B3BC59CBA4FE035A6C416D32BDCF8C3B9AFC5E1120CFD420023FD8EB207DB965509E2D362B0EB3D8CBD191D2750EBEB05F32C4BE08154D991F08DE4914BC40FAA7172440F2FEFB0FBF604DDA9C18BA9FD55F34218FD5D7CA2AC491CEDC3C5743D143BAF6C06CCAB7E5B22AB4E46CD51962CC7931F4D35581D5DD3047B946044BF7E71955EB63DD546644D7D2A19777DA39A48B4CF5A011A5C41F1BFF7C463F057F2F7AF6F910E7E06398B0AF7EF38CD5BBAE4C5FF42572CFFFCA6A8E9D34F64A7BECDC93216B55C20FAECAF04A8956C4D26DEE34493510BC49144A32A1B0AAE64B50DCA0C27361692242FE3145A6B36B830DEBF9E8A07A886E8DA6F38F3E99906F6AC9317ADF73222C4C75ABD153F1112E01E7CBB49665F213A1C1470CDC442D7CDC72EE2DD80D37251333C34FFDC5C38ADA3F5E52F5A5B2A1224B0CA60211B430E9554F0C4CA672476562C4A182B6707EBE80DFA6247A1F870F74EC81D03558F2718409EBF8E7F2FD2C6AB1F246F7E3FE0D919DB4016A7D76F6378D05EA74766CBB93340F2CBDDF18073F39242F3E9EC88020D1E8F801183C00F0239B2F2B4E8F6B46DBC17F469A857C291C985D8AC2099A6FEDC462B5EAEF737831EA2B6C9D787DC5AC8DA2C2E8F7F676FDA4CDD79E400EED959882C78C279C4D0A5918A0F5FC3B695E0034F7C2665D52D94106744D6B0CD6A66AB3275324EFDC06ECCF431D446446A00818ECDBE77B845699FB4F699825702D00F71373D80452039ECA1237AD2A0DF9112BA1EC90FB9FB87CF4E46BD0319B64F2EFD4B9640469707DB549468781D0BA6F3C49AF035D441173786BB1F2F5DCCE07BBF5536A0EB5B976814ABFDB44B90E55455972701A8F0D8EFB860A082ABA960E704754F61C2E3956922833F3D7E1656476DEE3C4F09244AC15697EA4A73041F03EEDE1F30BF899098A70F33E20AE0AF +20241129052029 2 6 100 6143 2 DCBE8A152DD5DE612BFCCD18CAB2BDE17391AF9DA865DCC59A1B454144ADE2EB8BE3CDBA7948CD1236CFC25D66DDC0E91095FB7E17715247413BBFD5435223F46488AD93808AF9FAF7D473C7CCE55DAA83B417FC6C09BFF7E332BD4B3BC59CBA4FE035A6C416D32BDCF8C3B9AFC5E1120CFD420023FD8EB207DB965509E2D362B0EB3D8CBD191D2750EBEB05F32C4BE08154D991F08DE4914BC40FAA7172440F2FEFB0FBF604DDA9C18BA9FD55F34218FD5D7CA2AC491CEDC3C5743D143BAF6C06CCAB7E5B22AB4E46CD51962CC7931F4D35581D5DD3047B946044BF7E71955EB63DD546644D7D2A19777DA39A48B4CF5A011A5C41F1BFF7C463F057F2F7AF6F910E7E06398B0AF7EF38CD5BBAE4C5FF42572CFFFCA6A8E9D34F64A7BECDC93216B55C20FAECAF04A8956C4D26DEE34493510BC49144A32A1B0AAE64B50DCA0C27361692242FE3145A6B36B830DEBF9E8A07A886E8DA6F38F3E99906F6AC9317ADF73222C4C75ABD153F1112E01E7CBB49665F213A1C1470CDC442D7CDC72EE2DD80D37251333C34FFDC5C38ADA3F5E52F5A5B2A1224B0CA60211B430E9554F0C4CA672476562C4A182B6707EBE80DFA6247A1F870F74EC81D03558F2718409EBF8E7F2FD2C6AB1F246F7E3FE0D919DB4016A7D76F6378D05EA74766CBB93340F2CBDDF18073F39242F3E9EC88020D1E8F801183C00F0239B2F2B4E8F6B46DBC17F469A857C291C985D8AC2099A6FEDC462B5EAEF737831EA2B6C9D787DC5AC8DA2C2E8F7F676FDA4CDD79E400EED959882C78C279C4D0A5918A0F5FC3B695E0034F7C2665D52D94106744D6B0CD6A66AB3275324EFDC06ECCF431D446446A00818ECDBE77B845699FB4F699825702D00F71373D80452039ECA1237AD2A0DF9112BA1EC90FB9FB87CF4E46BD0319B64F2EFD4B9640469707DB549468781D0BA6F3C49AF035D441173786BB1F2F5DCCE07BBF5536A0EB5B976814ABFDB44B90E55455972701A8F0D8EFB860A082ABA960E704754F61C2E3956922833F3D7E1656476DEE3C4F09244AC15697EA4A73041F03EEDE1F30BF899098A70F33E221299B +20241129052420 2 6 100 6143 2 DCBE8A152DD5DE612BFCCD18CAB2BDE17391AF9DA865DCC59A1B454144ADE2EB8BE3CDBA7948CD1236CFC25D66DDC0E91095FB7E17715247413BBFD5435223F46488AD93808AF9FAF7D473C7CCE55DAA83B417FC6C09BFF7E332BD4B3BC59CBA4FE035A6C416D32BDCF8C3B9AFC5E1120CFD420023FD8EB207DB965509E2D362B0EB3D8CBD191D2750EBEB05F32C4BE08154D991F08DE4914BC40FAA7172440F2FEFB0FBF604DDA9C18BA9FD55F34218FD5D7CA2AC491CEDC3C5743D143BAF6C06CCAB7E5B22AB4E46CD51962CC7931F4D35581D5DD3047B946044BF7E71955EB63DD546644D7D2A19777DA39A48B4CF5A011A5C41F1BFF7C463F057F2F7AF6F910E7E06398B0AF7EF38CD5BBAE4C5FF42572CFFFCA6A8E9D34F64A7BECDC93216B55C20FAECAF04A8956C4D26DEE34493510BC49144A32A1B0AAE64B50DCA0C27361692242FE3145A6B36B830DEBF9E8A07A886E8DA6F38F3E99906F6AC9317ADF73222C4C75ABD153F1112E01E7CBB49665F213A1C1470CDC442D7CDC72EE2DD80D37251333C34FFDC5C38ADA3F5E52F5A5B2A1224B0CA60211B430E9554F0C4CA672476562C4A182B6707EBE80DFA6247A1F870F74EC81D03558F2718409EBF8E7F2FD2C6AB1F246F7E3FE0D919DB4016A7D76F6378D05EA74766CBB93340F2CBDDF18073F39242F3E9EC88020D1E8F801183C00F0239B2F2B4E8F6B46DBC17F469A857C291C985D8AC2099A6FEDC462B5EAEF737831EA2B6C9D787DC5AC8DA2C2E8F7F676FDA4CDD79E400EED959882C78C279C4D0A5918A0F5FC3B695E0034F7C2665D52D94106744D6B0CD6A66AB3275324EFDC06ECCF431D446446A00818ECDBE77B845699FB4F699825702D00F71373D80452039ECA1237AD2A0DF9112BA1EC90FB9FB87CF4E46BD0319B64F2EFD4B9640469707DB549468781D0BA6F3C49AF035D441173786BB1F2F5DCCE07BBF5536A0EB5B976814ABFDB44B90E55455972701A8F0D8EFB860A082ABA960E704754F61C2E3956922833F3D7E1656476DEE3C4F09244AC15697EA4A73041F03EEDE1F30BF899098A70F33E294985B +20241129053040 2 6 100 6143 5 DCBE8A152DD5DE612BFCCD18CAB2BDE17391AF9DA865DCC59A1B454144ADE2EB8BE3CDBA7948CD1236CFC25D66DDC0E91095FB7E17715247413BBFD5435223F46488AD93808AF9FAF7D473C7CCE55DAA83B417FC6C09BFF7E332BD4B3BC59CBA4FE035A6C416D32BDCF8C3B9AFC5E1120CFD420023FD8EB207DB965509E2D362B0EB3D8CBD191D2750EBEB05F32C4BE08154D991F08DE4914BC40FAA7172440F2FEFB0FBF604DDA9C18BA9FD55F34218FD5D7CA2AC491CEDC3C5743D143BAF6C06CCAB7E5B22AB4E46CD51962CC7931F4D35581D5DD3047B946044BF7E71955EB63DD546644D7D2A19777DA39A48B4CF5A011A5C41F1BFF7C463F057F2F7AF6F910E7E06398B0AF7EF38CD5BBAE4C5FF42572CFFFCA6A8E9D34F64A7BECDC93216B55C20FAECAF04A8956C4D26DEE34493510BC49144A32A1B0AAE64B50DCA0C27361692242FE3145A6B36B830DEBF9E8A07A886E8DA6F38F3E99906F6AC9317ADF73222C4C75ABD153F1112E01E7CBB49665F213A1C1470CDC442D7CDC72EE2DD80D37251333C34FFDC5C38ADA3F5E52F5A5B2A1224B0CA60211B430E9554F0C4CA672476562C4A182B6707EBE80DFA6247A1F870F74EC81D03558F2718409EBF8E7F2FD2C6AB1F246F7E3FE0D919DB4016A7D76F6378D05EA74766CBB93340F2CBDDF18073F39242F3E9EC88020D1E8F801183C00F0239B2F2B4E8F6B46DBC17F469A857C291C985D8AC2099A6FEDC462B5EAEF737831EA2B6C9D787DC5AC8DA2C2E8F7F676FDA4CDD79E400EED959882C78C279C4D0A5918A0F5FC3B695E0034F7C2665D52D94106744D6B0CD6A66AB3275324EFDC06ECCF431D446446A00818ECDBE77B845699FB4F699825702D00F71373D80452039ECA1237AD2A0DF9112BA1EC90FB9FB87CF4E46BD0319B64F2EFD4B9640469707DB549468781D0BA6F3C49AF035D441173786BB1F2F5DCCE07BBF5536A0EB5B976814ABFDB44B90E55455972701A8F0D8EFB860A082ABA960E704754F61C2E3956922833F3D7E1656476DEE3C4F09244AC15697EA4A73041F03EEDE1F30BF899098A70F33E35A621F +20241129053505 2 6 100 6143 2 DCBE8A152DD5DE612BFCCD18CAB2BDE17391AF9DA865DCC59A1B454144ADE2EB8BE3CDBA7948CD1236CFC25D66DDC0E91095FB7E17715247413BBFD5435223F46488AD93808AF9FAF7D473C7CCE55DAA83B417FC6C09BFF7E332BD4B3BC59CBA4FE035A6C416D32BDCF8C3B9AFC5E1120CFD420023FD8EB207DB965509E2D362B0EB3D8CBD191D2750EBEB05F32C4BE08154D991F08DE4914BC40FAA7172440F2FEFB0FBF604DDA9C18BA9FD55F34218FD5D7CA2AC491CEDC3C5743D143BAF6C06CCAB7E5B22AB4E46CD51962CC7931F4D35581D5DD3047B946044BF7E71955EB63DD546644D7D2A19777DA39A48B4CF5A011A5C41F1BFF7C463F057F2F7AF6F910E7E06398B0AF7EF38CD5BBAE4C5FF42572CFFFCA6A8E9D34F64A7BECDC93216B55C20FAECAF04A8956C4D26DEE34493510BC49144A32A1B0AAE64B50DCA0C27361692242FE3145A6B36B830DEBF9E8A07A886E8DA6F38F3E99906F6AC9317ADF73222C4C75ABD153F1112E01E7CBB49665F213A1C1470CDC442D7CDC72EE2DD80D37251333C34FFDC5C38ADA3F5E52F5A5B2A1224B0CA60211B430E9554F0C4CA672476562C4A182B6707EBE80DFA6247A1F870F74EC81D03558F2718409EBF8E7F2FD2C6AB1F246F7E3FE0D919DB4016A7D76F6378D05EA74766CBB93340F2CBDDF18073F39242F3E9EC88020D1E8F801183C00F0239B2F2B4E8F6B46DBC17F469A857C291C985D8AC2099A6FEDC462B5EAEF737831EA2B6C9D787DC5AC8DA2C2E8F7F676FDA4CDD79E400EED959882C78C279C4D0A5918A0F5FC3B695E0034F7C2665D52D94106744D6B0CD6A66AB3275324EFDC06ECCF431D446446A00818ECDBE77B845699FB4F699825702D00F71373D80452039ECA1237AD2A0DF9112BA1EC90FB9FB87CF4E46BD0319B64F2EFD4B9640469707DB549468781D0BA6F3C49AF035D441173786BB1F2F5DCCE07BBF5536A0EB5B976814ABFDB44B90E55455972701A8F0D8EFB860A082ABA960E704754F61C2E3956922833F3D7E1656476DEE3C4F09244AC15697EA4A73041F03EEDE1F30BF899098A70F33E3E2DAAB +20241129054958 2 6 100 6143 5 DCBE8A152DD5DE612BFCCD18CAB2BDE17391AF9DA865DCC59A1B454144ADE2EB8BE3CDBA7948CD1236CFC25D66DDC0E91095FB7E17715247413BBFD5435223F46488AD93808AF9FAF7D473C7CCE55DAA83B417FC6C09BFF7E332BD4B3BC59CBA4FE035A6C416D32BDCF8C3B9AFC5E1120CFD420023FD8EB207DB965509E2D362B0EB3D8CBD191D2750EBEB05F32C4BE08154D991F08DE4914BC40FAA7172440F2FEFB0FBF604DDA9C18BA9FD55F34218FD5D7CA2AC491CEDC3C5743D143BAF6C06CCAB7E5B22AB4E46CD51962CC7931F4D35581D5DD3047B946044BF7E71955EB63DD546644D7D2A19777DA39A48B4CF5A011A5C41F1BFF7C463F057F2F7AF6F910E7E06398B0AF7EF38CD5BBAE4C5FF42572CFFFCA6A8E9D34F64A7BECDC93216B55C20FAECAF04A8956C4D26DEE34493510BC49144A32A1B0AAE64B50DCA0C27361692242FE3145A6B36B830DEBF9E8A07A886E8DA6F38F3E99906F6AC9317ADF73222C4C75ABD153F1112E01E7CBB49665F213A1C1470CDC442D7CDC72EE2DD80D37251333C34FFDC5C38ADA3F5E52F5A5B2A1224B0CA60211B430E9554F0C4CA672476562C4A182B6707EBE80DFA6247A1F870F74EC81D03558F2718409EBF8E7F2FD2C6AB1F246F7E3FE0D919DB4016A7D76F6378D05EA74766CBB93340F2CBDDF18073F39242F3E9EC88020D1E8F801183C00F0239B2F2B4E8F6B46DBC17F469A857C291C985D8AC2099A6FEDC462B5EAEF737831EA2B6C9D787DC5AC8DA2C2E8F7F676FDA4CDD79E400EED959882C78C279C4D0A5918A0F5FC3B695E0034F7C2665D52D94106744D6B0CD6A66AB3275324EFDC06ECCF431D446446A00818ECDBE77B845699FB4F699825702D00F71373D80452039ECA1237AD2A0DF9112BA1EC90FB9FB87CF4E46BD0319B64F2EFD4B9640469707DB549468781D0BA6F3C49AF035D441173786BB1F2F5DCCE07BBF5536A0EB5B976814ABFDB44B90E55455972701A8F0D8EFB860A082ABA960E704754F61C2E3956922833F3D7E1656476DEE3C4F09244AC15697EA4A73041F03EEDE1F30BF899098A70F33E5C2C407 +20241129060731 2 6 100 6143 2 DCBE8A152DD5DE612BFCCD18CAB2BDE17391AF9DA865DCC59A1B454144ADE2EB8BE3CDBA7948CD1236CFC25D66DDC0E91095FB7E17715247413BBFD5435223F46488AD93808AF9FAF7D473C7CCE55DAA83B417FC6C09BFF7E332BD4B3BC59CBA4FE035A6C416D32BDCF8C3B9AFC5E1120CFD420023FD8EB207DB965509E2D362B0EB3D8CBD191D2750EBEB05F32C4BE08154D991F08DE4914BC40FAA7172440F2FEFB0FBF604DDA9C18BA9FD55F34218FD5D7CA2AC491CEDC3C5743D143BAF6C06CCAB7E5B22AB4E46CD51962CC7931F4D35581D5DD3047B946044BF7E71955EB63DD546644D7D2A19777DA39A48B4CF5A011A5C41F1BFF7C463F057F2F7AF6F910E7E06398B0AF7EF38CD5BBAE4C5FF42572CFFFCA6A8E9D34F64A7BECDC93216B55C20FAECAF04A8956C4D26DEE34493510BC49144A32A1B0AAE64B50DCA0C27361692242FE3145A6B36B830DEBF9E8A07A886E8DA6F38F3E99906F6AC9317ADF73222C4C75ABD153F1112E01E7CBB49665F213A1C1470CDC442D7CDC72EE2DD80D37251333C34FFDC5C38ADA3F5E52F5A5B2A1224B0CA60211B430E9554F0C4CA672476562C4A182B6707EBE80DFA6247A1F870F74EC81D03558F2718409EBF8E7F2FD2C6AB1F246F7E3FE0D919DB4016A7D76F6378D05EA74766CBB93340F2CBDDF18073F39242F3E9EC88020D1E8F801183C00F0239B2F2B4E8F6B46DBC17F469A857C291C985D8AC2099A6FEDC462B5EAEF737831EA2B6C9D787DC5AC8DA2C2E8F7F676FDA4CDD79E400EED959882C78C279C4D0A5918A0F5FC3B695E0034F7C2665D52D94106744D6B0CD6A66AB3275324EFDC06ECCF431D446446A00818ECDBE77B845699FB4F699825702D00F71373D80452039ECA1237AD2A0DF9112BA1EC90FB9FB87CF4E46BD0319B64F2EFD4B9640469707DB549468781D0BA6F3C49AF035D441173786BB1F2F5DCCE07BBF5536A0EB5B976814ABFDB44B90E55455972701A8F0D8EFB860A082ABA960E704754F61C2E3956922833F3D7E1656476DEE3C4F09244AC15697EA4A73041F03EEDE1F30BF899098A70F33E7EF06DB +20241129060801 2 6 100 6143 2 DCBE8A152DD5DE612BFCCD18CAB2BDE17391AF9DA865DCC59A1B454144ADE2EB8BE3CDBA7948CD1236CFC25D66DDC0E91095FB7E17715247413BBFD5435223F46488AD93808AF9FAF7D473C7CCE55DAA83B417FC6C09BFF7E332BD4B3BC59CBA4FE035A6C416D32BDCF8C3B9AFC5E1120CFD420023FD8EB207DB965509E2D362B0EB3D8CBD191D2750EBEB05F32C4BE08154D991F08DE4914BC40FAA7172440F2FEFB0FBF604DDA9C18BA9FD55F34218FD5D7CA2AC491CEDC3C5743D143BAF6C06CCAB7E5B22AB4E46CD51962CC7931F4D35581D5DD3047B946044BF7E71955EB63DD546644D7D2A19777DA39A48B4CF5A011A5C41F1BFF7C463F057F2F7AF6F910E7E06398B0AF7EF38CD5BBAE4C5FF42572CFFFCA6A8E9D34F64A7BECDC93216B55C20FAECAF04A8956C4D26DEE34493510BC49144A32A1B0AAE64B50DCA0C27361692242FE3145A6B36B830DEBF9E8A07A886E8DA6F38F3E99906F6AC9317ADF73222C4C75ABD153F1112E01E7CBB49665F213A1C1470CDC442D7CDC72EE2DD80D37251333C34FFDC5C38ADA3F5E52F5A5B2A1224B0CA60211B430E9554F0C4CA672476562C4A182B6707EBE80DFA6247A1F870F74EC81D03558F2718409EBF8E7F2FD2C6AB1F246F7E3FE0D919DB4016A7D76F6378D05EA74766CBB93340F2CBDDF18073F39242F3E9EC88020D1E8F801183C00F0239B2F2B4E8F6B46DBC17F469A857C291C985D8AC2099A6FEDC462B5EAEF737831EA2B6C9D787DC5AC8DA2C2E8F7F676FDA4CDD79E400EED959882C78C279C4D0A5918A0F5FC3B695E0034F7C2665D52D94106744D6B0CD6A66AB3275324EFDC06ECCF431D446446A00818ECDBE77B845699FB4F699825702D00F71373D80452039ECA1237AD2A0DF9112BA1EC90FB9FB87CF4E46BD0319B64F2EFD4B9640469707DB549468781D0BA6F3C49AF035D441173786BB1F2F5DCCE07BBF5536A0EB5B976814ABFDB44B90E55455972701A8F0D8EFB860A082ABA960E704754F61C2E3956922833F3D7E1656476DEE3C4F09244AC15697EA4A73041F03EEDE1F30BF899098A70F33E7F7359B +20241129063045 2 6 100 6143 2 DCBE8A152DD5DE612BFCCD18CAB2BDE17391AF9DA865DCC59A1B454144ADE2EB8BE3CDBA7948CD1236CFC25D66DDC0E91095FB7E17715247413BBFD5435223F46488AD93808AF9FAF7D473C7CCE55DAA83B417FC6C09BFF7E332BD4B3BC59CBA4FE035A6C416D32BDCF8C3B9AFC5E1120CFD420023FD8EB207DB965509E2D362B0EB3D8CBD191D2750EBEB05F32C4BE08154D991F08DE4914BC40FAA7172440F2FEFB0FBF604DDA9C18BA9FD55F34218FD5D7CA2AC491CEDC3C5743D143BAF6C06CCAB7E5B22AB4E46CD51962CC7931F4D35581D5DD3047B946044BF7E71955EB63DD546644D7D2A19777DA39A48B4CF5A011A5C41F1BFF7C463F057F2F7AF6F910E7E06398B0AF7EF38CD5BBAE4C5FF42572CFFFCA6A8E9D34F64A7BECDC93216B55C20FAECAF04A8956C4D26DEE34493510BC49144A32A1B0AAE64B50DCA0C27361692242FE3145A6B36B830DEBF9E8A07A886E8DA6F38F3E99906F6AC9317ADF73222C4C75ABD153F1112E01E7CBB49665F213A1C1470CDC442D7CDC72EE2DD80D37251333C34FFDC5C38ADA3F5E52F5A5B2A1224B0CA60211B430E9554F0C4CA672476562C4A182B6707EBE80DFA6247A1F870F74EC81D03558F2718409EBF8E7F2FD2C6AB1F246F7E3FE0D919DB4016A7D76F6378D05EA74766CBB93340F2CBDDF18073F39242F3E9EC88020D1E8F801183C00F0239B2F2B4E8F6B46DBC17F469A857C291C985D8AC2099A6FEDC462B5EAEF737831EA2B6C9D787DC5AC8DA2C2E8F7F676FDA4CDD79E400EED959882C78C279C4D0A5918A0F5FC3B695E0034F7C2665D52D94106744D6B0CD6A66AB3275324EFDC06ECCF431D446446A00818ECDBE77B845699FB4F699825702D00F71373D80452039ECA1237AD2A0DF9112BA1EC90FB9FB87CF4E46BD0319B64F2EFD4B9640469707DB549468781D0BA6F3C49AF035D441173786BB1F2F5DCCE07BBF5536A0EB5B976814ABFDB44B90E55455972701A8F0D8EFB860A082ABA960E704754F61C2E3956922833F3D7E1656476DEE3C4F09244AC15697EA4A73041F03EEDE1F30BF899098A70F33EAD325DB +20241129065049 2 6 100 6143 2 DCBE8A152DD5DE612BFCCD18CAB2BDE17391AF9DA865DCC59A1B454144ADE2EB8BE3CDBA7948CD1236CFC25D66DDC0E91095FB7E17715247413BBFD5435223F46488AD93808AF9FAF7D473C7CCE55DAA83B417FC6C09BFF7E332BD4B3BC59CBA4FE035A6C416D32BDCF8C3B9AFC5E1120CFD420023FD8EB207DB965509E2D362B0EB3D8CBD191D2750EBEB05F32C4BE08154D991F08DE4914BC40FAA7172440F2FEFB0FBF604DDA9C18BA9FD55F34218FD5D7CA2AC491CEDC3C5743D143BAF6C06CCAB7E5B22AB4E46CD51962CC7931F4D35581D5DD3047B946044BF7E71955EB63DD546644D7D2A19777DA39A48B4CF5A011A5C41F1BFF7C463F057F2F7AF6F910E7E06398B0AF7EF38CD5BBAE4C5FF42572CFFFCA6A8E9D34F64A7BECDC93216B55C20FAECAF04A8956C4D26DEE34493510BC49144A32A1B0AAE64B50DCA0C27361692242FE3145A6B36B830DEBF9E8A07A886E8DA6F38F3E99906F6AC9317ADF73222C4C75ABD153F1112E01E7CBB49665F213A1C1470CDC442D7CDC72EE2DD80D37251333C34FFDC5C38ADA3F5E52F5A5B2A1224B0CA60211B430E9554F0C4CA672476562C4A182B6707EBE80DFA6247A1F870F74EC81D03558F2718409EBF8E7F2FD2C6AB1F246F7E3FE0D919DB4016A7D76F6378D05EA74766CBB93340F2CBDDF18073F39242F3E9EC88020D1E8F801183C00F0239B2F2B4E8F6B46DBC17F469A857C291C985D8AC2099A6FEDC462B5EAEF737831EA2B6C9D787DC5AC8DA2C2E8F7F676FDA4CDD79E400EED959882C78C279C4D0A5918A0F5FC3B695E0034F7C2665D52D94106744D6B0CD6A66AB3275324EFDC06ECCF431D446446A00818ECDBE77B845699FB4F699825702D00F71373D80452039ECA1237AD2A0DF9112BA1EC90FB9FB87CF4E46BD0319B64F2EFD4B9640469707DB549468781D0BA6F3C49AF035D441173786BB1F2F5DCCE07BBF5536A0EB5B976814ABFDB44B90E55455972701A8F0D8EFB860A082ABA960E704754F61C2E3956922833F3D7E1656476DEE3C4F09244AC15697EA4A73041F03EEDE1F30BF899098A70F33ED529283 +20241129065931 2 6 100 6143 5 DCBE8A152DD5DE612BFCCD18CAB2BDE17391AF9DA865DCC59A1B454144ADE2EB8BE3CDBA7948CD1236CFC25D66DDC0E91095FB7E17715247413BBFD5435223F46488AD93808AF9FAF7D473C7CCE55DAA83B417FC6C09BFF7E332BD4B3BC59CBA4FE035A6C416D32BDCF8C3B9AFC5E1120CFD420023FD8EB207DB965509E2D362B0EB3D8CBD191D2750EBEB05F32C4BE08154D991F08DE4914BC40FAA7172440F2FEFB0FBF604DDA9C18BA9FD55F34218FD5D7CA2AC491CEDC3C5743D143BAF6C06CCAB7E5B22AB4E46CD51962CC7931F4D35581D5DD3047B946044BF7E71955EB63DD546644D7D2A19777DA39A48B4CF5A011A5C41F1BFF7C463F057F2F7AF6F910E7E06398B0AF7EF38CD5BBAE4C5FF42572CFFFCA6A8E9D34F64A7BECDC93216B55C20FAECAF04A8956C4D26DEE34493510BC49144A32A1B0AAE64B50DCA0C27361692242FE3145A6B36B830DEBF9E8A07A886E8DA6F38F3E99906F6AC9317ADF73222C4C75ABD153F1112E01E7CBB49665F213A1C1470CDC442D7CDC72EE2DD80D37251333C34FFDC5C38ADA3F5E52F5A5B2A1224B0CA60211B430E9554F0C4CA672476562C4A182B6707EBE80DFA6247A1F870F74EC81D03558F2718409EBF8E7F2FD2C6AB1F246F7E3FE0D919DB4016A7D76F6378D05EA74766CBB93340F2CBDDF18073F39242F3E9EC88020D1E8F801183C00F0239B2F2B4E8F6B46DBC17F469A857C291C985D8AC2099A6FEDC462B5EAEF737831EA2B6C9D787DC5AC8DA2C2E8F7F676FDA4CDD79E400EED959882C78C279C4D0A5918A0F5FC3B695E0034F7C2665D52D94106744D6B0CD6A66AB3275324EFDC06ECCF431D446446A00818ECDBE77B845699FB4F699825702D00F71373D80452039ECA1237AD2A0DF9112BA1EC90FB9FB87CF4E46BD0319B64F2EFD4B9640469707DB549468781D0BA6F3C49AF035D441173786BB1F2F5DCCE07BBF5536A0EB5B976814ABFDB44B90E55455972701A8F0D8EFB860A082ABA960E704754F61C2E3956922833F3D7E1656476DEE3C4F09244AC15697EA4A73041F03EEDE1F30BF899098A70F33EE615997 +20241129070906 2 6 100 6143 5 DCBE8A152DD5DE612BFCCD18CAB2BDE17391AF9DA865DCC59A1B454144ADE2EB8BE3CDBA7948CD1236CFC25D66DDC0E91095FB7E17715247413BBFD5435223F46488AD93808AF9FAF7D473C7CCE55DAA83B417FC6C09BFF7E332BD4B3BC59CBA4FE035A6C416D32BDCF8C3B9AFC5E1120CFD420023FD8EB207DB965509E2D362B0EB3D8CBD191D2750EBEB05F32C4BE08154D991F08DE4914BC40FAA7172440F2FEFB0FBF604DDA9C18BA9FD55F34218FD5D7CA2AC491CEDC3C5743D143BAF6C06CCAB7E5B22AB4E46CD51962CC7931F4D35581D5DD3047B946044BF7E71955EB63DD546644D7D2A19777DA39A48B4CF5A011A5C41F1BFF7C463F057F2F7AF6F910E7E06398B0AF7EF38CD5BBAE4C5FF42572CFFFCA6A8E9D34F64A7BECDC93216B55C20FAECAF04A8956C4D26DEE34493510BC49144A32A1B0AAE64B50DCA0C27361692242FE3145A6B36B830DEBF9E8A07A886E8DA6F38F3E99906F6AC9317ADF73222C4C75ABD153F1112E01E7CBB49665F213A1C1470CDC442D7CDC72EE2DD80D37251333C34FFDC5C38ADA3F5E52F5A5B2A1224B0CA60211B430E9554F0C4CA672476562C4A182B6707EBE80DFA6247A1F870F74EC81D03558F2718409EBF8E7F2FD2C6AB1F246F7E3FE0D919DB4016A7D76F6378D05EA74766CBB93340F2CBDDF18073F39242F3E9EC88020D1E8F801183C00F0239B2F2B4E8F6B46DBC17F469A857C291C985D8AC2099A6FEDC462B5EAEF737831EA2B6C9D787DC5AC8DA2C2E8F7F676FDA4CDD79E400EED959882C78C279C4D0A5918A0F5FC3B695E0034F7C2665D52D94106744D6B0CD6A66AB3275324EFDC06ECCF431D446446A00818ECDBE77B845699FB4F699825702D00F71373D80452039ECA1237AD2A0DF9112BA1EC90FB9FB87CF4E46BD0319B64F2EFD4B9640469707DB549468781D0BA6F3C49AF035D441173786BB1F2F5DCCE07BBF5536A0EB5B976814ABFDB44B90E55455972701A8F0D8EFB860A082ABA960E704754F61C2E3956922833F3D7E1656476DEE3C4F09244AC15697EA4A73041F03EEDE1F30BF899098A70F33EF8D1D07 +20241129072522 2 6 100 6143 5 DCBE8A152DD5DE612BFCCD18CAB2BDE17391AF9DA865DCC59A1B454144ADE2EB8BE3CDBA7948CD1236CFC25D66DDC0E91095FB7E17715247413BBFD5435223F46488AD93808AF9FAF7D473C7CCE55DAA83B417FC6C09BFF7E332BD4B3BC59CBA4FE035A6C416D32BDCF8C3B9AFC5E1120CFD420023FD8EB207DB965509E2D362B0EB3D8CBD191D2750EBEB05F32C4BE08154D991F08DE4914BC40FAA7172440F2FEFB0FBF604DDA9C18BA9FD55F34218FD5D7CA2AC491CEDC3C5743D143BAF6C06CCAB7E5B22AB4E46CD51962CC7931F4D35581D5DD3047B946044BF7E71955EB63DD546644D7D2A19777DA39A48B4CF5A011A5C41F1BFF7C463F057F2F7AF6F910E7E06398B0AF7EF38CD5BBAE4C5FF42572CFFFCA6A8E9D34F64A7BECDC93216B55C20FAECAF04A8956C4D26DEE34493510BC49144A32A1B0AAE64B50DCA0C27361692242FE3145A6B36B830DEBF9E8A07A886E8DA6F38F3E99906F6AC9317ADF73222C4C75ABD153F1112E01E7CBB49665F213A1C1470CDC442D7CDC72EE2DD80D37251333C34FFDC5C38ADA3F5E52F5A5B2A1224B0CA60211B430E9554F0C4CA672476562C4A182B6707EBE80DFA6247A1F870F74EC81D03558F2718409EBF8E7F2FD2C6AB1F246F7E3FE0D919DB4016A7D76F6378D05EA74766CBB93340F2CBDDF18073F39242F3E9EC88020D1E8F801183C00F0239B2F2B4E8F6B46DBC17F469A857C291C985D8AC2099A6FEDC462B5EAEF737831EA2B6C9D787DC5AC8DA2C2E8F7F676FDA4CDD79E400EED959882C78C279C4D0A5918A0F5FC3B695E0034F7C2665D52D94106744D6B0CD6A66AB3275324EFDC06ECCF431D446446A00818ECDBE77B845699FB4F699825702D00F71373D80452039ECA1237AD2A0DF9112BA1EC90FB9FB87CF4E46BD0319B64F2EFD4B9640469707DB549468781D0BA6F3C49AF035D441173786BB1F2F5DCCE07BBF5536A0EB5B976814ABFDB44B90E55455972701A8F0D8EFB860A082ABA960E704754F61C2E3956922833F3D7E1656476DEE3C4F09244AC15697EA4A73041F03EEDE1F30BF899098A70F33F19250B7 +20241129080348 2 6 100 6143 2 DCBE8A152DD5DE612BFCCD18CAB2BDE17391AF9DA865DCC59A1B454144ADE2EB8BE3CDBA7948CD1236CFC25D66DDC0E91095FB7E17715247413BBFD5435223F46488AD93808AF9FAF7D473C7CCE55DAA83B417FC6C09BFF7E332BD4B3BC59CBA4FE035A6C416D32BDCF8C3B9AFC5E1120CFD420023FD8EB207DB965509E2D362B0EB3D8CBD191D2750EBEB05F32C4BE08154D991F08DE4914BC40FAA7172440F2FEFB0FBF604DDA9C18BA9FD55F34218FD5D7CA2AC491CEDC3C5743D143BAF6C06CCAB7E5B22AB4E46CD51962CC7931F4D35581D5DD3047B946044BF7E71955EB63DD546644D7D2A19777DA39A48B4CF5A011A5C41F1BFF7C463F057F2F7AF6F910E7E06398B0AF7EF38CD5BBAE4C5FF42572CFFFCA6A8E9D34F64A7BECDC93216B55C20FAECAF04A8956C4D26DEE34493510BC49144A32A1B0AAE64B50DCA0C27361692242FE3145A6B36B830DEBF9E8A07A886E8DA6F38F3E99906F6AC9317ADF73222C4C75ABD153F1112E01E7CBB49665F213A1C1470CDC442D7CDC72EE2DD80D37251333C34FFDC5C38ADA3F5E52F5A5B2A1224B0CA60211B430E9554F0C4CA672476562C4A182B6707EBE80DFA6247A1F870F74EC81D03558F2718409EBF8E7F2FD2C6AB1F246F7E3FE0D919DB4016A7D76F6378D05EA74766CBB93340F2CBDDF18073F39242F3E9EC88020D1E8F801183C00F0239B2F2B4E8F6B46DBC17F469A857C291C985D8AC2099A6FEDC462B5EAEF737831EA2B6C9D787DC5AC8DA2C2E8F7F676FDA4CDD79E400EED959882C78C279C4D0A5918A0F5FC3B695E0034F7C2665D52D94106744D6B0CD6A66AB3275324EFDC06ECCF431D446446A00818ECDBE77B845699FB4F699825702D00F71373D80452039ECA1237AD2A0DF9112BA1EC90FB9FB87CF4E46BD0319B64F2EFD4B9640469707DB549468781D0BA6F3C49AF035D441173786BB1F2F5DCCE07BBF5536A0EB5B976814ABFDB44B90E55455972701A8F0D8EFB860A082ABA960E704754F61C2E3956922833F3D7E1656476DEE3C4F09244AC15697EA4A73041F03EEDE1F30BF899098A70F33F6682AF3 +20241129082342 2 6 100 6143 5 DCBE8A152DD5DE612BFCCD18CAB2BDE17391AF9DA865DCC59A1B454144ADE2EB8BE3CDBA7948CD1236CFC25D66DDC0E91095FB7E17715247413BBFD5435223F46488AD93808AF9FAF7D473C7CCE55DAA83B417FC6C09BFF7E332BD4B3BC59CBA4FE035A6C416D32BDCF8C3B9AFC5E1120CFD420023FD8EB207DB965509E2D362B0EB3D8CBD191D2750EBEB05F32C4BE08154D991F08DE4914BC40FAA7172440F2FEFB0FBF604DDA9C18BA9FD55F34218FD5D7CA2AC491CEDC3C5743D143BAF6C06CCAB7E5B22AB4E46CD51962CC7931F4D35581D5DD3047B946044BF7E71955EB63DD546644D7D2A19777DA39A48B4CF5A011A5C41F1BFF7C463F057F2F7AF6F910E7E06398B0AF7EF38CD5BBAE4C5FF42572CFFFCA6A8E9D34F64A7BECDC93216B55C20FAECAF04A8956C4D26DEE34493510BC49144A32A1B0AAE64B50DCA0C27361692242FE3145A6B36B830DEBF9E8A07A886E8DA6F38F3E99906F6AC9317ADF73222C4C75ABD153F1112E01E7CBB49665F213A1C1470CDC442D7CDC72EE2DD80D37251333C34FFDC5C38ADA3F5E52F5A5B2A1224B0CA60211B430E9554F0C4CA672476562C4A182B6707EBE80DFA6247A1F870F74EC81D03558F2718409EBF8E7F2FD2C6AB1F246F7E3FE0D919DB4016A7D76F6378D05EA74766CBB93340F2CBDDF18073F39242F3E9EC88020D1E8F801183C00F0239B2F2B4E8F6B46DBC17F469A857C291C985D8AC2099A6FEDC462B5EAEF737831EA2B6C9D787DC5AC8DA2C2E8F7F676FDA4CDD79E400EED959882C78C279C4D0A5918A0F5FC3B695E0034F7C2665D52D94106744D6B0CD6A66AB3275324EFDC06ECCF431D446446A00818ECDBE77B845699FB4F699825702D00F71373D80452039ECA1237AD2A0DF9112BA1EC90FB9FB87CF4E46BD0319B64F2EFD4B9640469707DB549468781D0BA6F3C49AF035D441173786BB1F2F5DCCE07BBF5536A0EB5B976814ABFDB44B90E55455972701A8F0D8EFB860A082ABA960E704754F61C2E3956922833F3D7E1656476DEE3C4F09244AC15697EA4A73041F03EEDE1F30BF899098A70F33F8DD796F +20241129082407 2 6 100 6143 2 DCBE8A152DD5DE612BFCCD18CAB2BDE17391AF9DA865DCC59A1B454144ADE2EB8BE3CDBA7948CD1236CFC25D66DDC0E91095FB7E17715247413BBFD5435223F46488AD93808AF9FAF7D473C7CCE55DAA83B417FC6C09BFF7E332BD4B3BC59CBA4FE035A6C416D32BDCF8C3B9AFC5E1120CFD420023FD8EB207DB965509E2D362B0EB3D8CBD191D2750EBEB05F32C4BE08154D991F08DE4914BC40FAA7172440F2FEFB0FBF604DDA9C18BA9FD55F34218FD5D7CA2AC491CEDC3C5743D143BAF6C06CCAB7E5B22AB4E46CD51962CC7931F4D35581D5DD3047B946044BF7E71955EB63DD546644D7D2A19777DA39A48B4CF5A011A5C41F1BFF7C463F057F2F7AF6F910E7E06398B0AF7EF38CD5BBAE4C5FF42572CFFFCA6A8E9D34F64A7BECDC93216B55C20FAECAF04A8956C4D26DEE34493510BC49144A32A1B0AAE64B50DCA0C27361692242FE3145A6B36B830DEBF9E8A07A886E8DA6F38F3E99906F6AC9317ADF73222C4C75ABD153F1112E01E7CBB49665F213A1C1470CDC442D7CDC72EE2DD80D37251333C34FFDC5C38ADA3F5E52F5A5B2A1224B0CA60211B430E9554F0C4CA672476562C4A182B6707EBE80DFA6247A1F870F74EC81D03558F2718409EBF8E7F2FD2C6AB1F246F7E3FE0D919DB4016A7D76F6378D05EA74766CBB93340F2CBDDF18073F39242F3E9EC88020D1E8F801183C00F0239B2F2B4E8F6B46DBC17F469A857C291C985D8AC2099A6FEDC462B5EAEF737831EA2B6C9D787DC5AC8DA2C2E8F7F676FDA4CDD79E400EED959882C78C279C4D0A5918A0F5FC3B695E0034F7C2665D52D94106744D6B0CD6A66AB3275324EFDC06ECCF431D446446A00818ECDBE77B845699FB4F699825702D00F71373D80452039ECA1237AD2A0DF9112BA1EC90FB9FB87CF4E46BD0319B64F2EFD4B9640469707DB549468781D0BA6F3C49AF035D441173786BB1F2F5DCCE07BBF5536A0EB5B976814ABFDB44B90E55455972701A8F0D8EFB860A082ABA960E704754F61C2E3956922833F3D7E1656476DEE3C4F09244AC15697EA4A73041F03EEDE1F30BF899098A70F33F8E28AB3 +20241129082555 2 6 100 6143 2 DCBE8A152DD5DE612BFCCD18CAB2BDE17391AF9DA865DCC59A1B454144ADE2EB8BE3CDBA7948CD1236CFC25D66DDC0E91095FB7E17715247413BBFD5435223F46488AD93808AF9FAF7D473C7CCE55DAA83B417FC6C09BFF7E332BD4B3BC59CBA4FE035A6C416D32BDCF8C3B9AFC5E1120CFD420023FD8EB207DB965509E2D362B0EB3D8CBD191D2750EBEB05F32C4BE08154D991F08DE4914BC40FAA7172440F2FEFB0FBF604DDA9C18BA9FD55F34218FD5D7CA2AC491CEDC3C5743D143BAF6C06CCAB7E5B22AB4E46CD51962CC7931F4D35581D5DD3047B946044BF7E71955EB63DD546644D7D2A19777DA39A48B4CF5A011A5C41F1BFF7C463F057F2F7AF6F910E7E06398B0AF7EF38CD5BBAE4C5FF42572CFFFCA6A8E9D34F64A7BECDC93216B55C20FAECAF04A8956C4D26DEE34493510BC49144A32A1B0AAE64B50DCA0C27361692242FE3145A6B36B830DEBF9E8A07A886E8DA6F38F3E99906F6AC9317ADF73222C4C75ABD153F1112E01E7CBB49665F213A1C1470CDC442D7CDC72EE2DD80D37251333C34FFDC5C38ADA3F5E52F5A5B2A1224B0CA60211B430E9554F0C4CA672476562C4A182B6707EBE80DFA6247A1F870F74EC81D03558F2718409EBF8E7F2FD2C6AB1F246F7E3FE0D919DB4016A7D76F6378D05EA74766CBB93340F2CBDDF18073F39242F3E9EC88020D1E8F801183C00F0239B2F2B4E8F6B46DBC17F469A857C291C985D8AC2099A6FEDC462B5EAEF737831EA2B6C9D787DC5AC8DA2C2E8F7F676FDA4CDD79E400EED959882C78C279C4D0A5918A0F5FC3B695E0034F7C2665D52D94106744D6B0CD6A66AB3275324EFDC06ECCF431D446446A00818ECDBE77B845699FB4F699825702D00F71373D80452039ECA1237AD2A0DF9112BA1EC90FB9FB87CF4E46BD0319B64F2EFD4B9640469707DB549468781D0BA6F3C49AF035D441173786BB1F2F5DCCE07BBF5536A0EB5B976814ABFDB44B90E55455972701A8F0D8EFB860A082ABA960E704754F61C2E3956922833F3D7E1656476DEE3C4F09244AC15697EA4A73041F03EEDE1F30BF899098A70F33F917C303 +20241129082910 2 6 100 6143 2 DCBE8A152DD5DE612BFCCD18CAB2BDE17391AF9DA865DCC59A1B454144ADE2EB8BE3CDBA7948CD1236CFC25D66DDC0E91095FB7E17715247413BBFD5435223F46488AD93808AF9FAF7D473C7CCE55DAA83B417FC6C09BFF7E332BD4B3BC59CBA4FE035A6C416D32BDCF8C3B9AFC5E1120CFD420023FD8EB207DB965509E2D362B0EB3D8CBD191D2750EBEB05F32C4BE08154D991F08DE4914BC40FAA7172440F2FEFB0FBF604DDA9C18BA9FD55F34218FD5D7CA2AC491CEDC3C5743D143BAF6C06CCAB7E5B22AB4E46CD51962CC7931F4D35581D5DD3047B946044BF7E71955EB63DD546644D7D2A19777DA39A48B4CF5A011A5C41F1BFF7C463F057F2F7AF6F910E7E06398B0AF7EF38CD5BBAE4C5FF42572CFFFCA6A8E9D34F64A7BECDC93216B55C20FAECAF04A8956C4D26DEE34493510BC49144A32A1B0AAE64B50DCA0C27361692242FE3145A6B36B830DEBF9E8A07A886E8DA6F38F3E99906F6AC9317ADF73222C4C75ABD153F1112E01E7CBB49665F213A1C1470CDC442D7CDC72EE2DD80D37251333C34FFDC5C38ADA3F5E52F5A5B2A1224B0CA60211B430E9554F0C4CA672476562C4A182B6707EBE80DFA6247A1F870F74EC81D03558F2718409EBF8E7F2FD2C6AB1F246F7E3FE0D919DB4016A7D76F6378D05EA74766CBB93340F2CBDDF18073F39242F3E9EC88020D1E8F801183C00F0239B2F2B4E8F6B46DBC17F469A857C291C985D8AC2099A6FEDC462B5EAEF737831EA2B6C9D787DC5AC8DA2C2E8F7F676FDA4CDD79E400EED959882C78C279C4D0A5918A0F5FC3B695E0034F7C2665D52D94106744D6B0CD6A66AB3275324EFDC06ECCF431D446446A00818ECDBE77B845699FB4F699825702D00F71373D80452039ECA1237AD2A0DF9112BA1EC90FB9FB87CF4E46BD0319B64F2EFD4B9640469707DB549468781D0BA6F3C49AF035D441173786BB1F2F5DCCE07BBF5536A0EB5B976814ABFDB44B90E55455972701A8F0D8EFB860A082ABA960E704754F61C2E3956922833F3D7E1656476DEE3C4F09244AC15697EA4A73041F03EEDE1F30BF899098A70F33F97B2DB3 +20241129083433 2 6 100 6143 5 DCBE8A152DD5DE612BFCCD18CAB2BDE17391AF9DA865DCC59A1B454144ADE2EB8BE3CDBA7948CD1236CFC25D66DDC0E91095FB7E17715247413BBFD5435223F46488AD93808AF9FAF7D473C7CCE55DAA83B417FC6C09BFF7E332BD4B3BC59CBA4FE035A6C416D32BDCF8C3B9AFC5E1120CFD420023FD8EB207DB965509E2D362B0EB3D8CBD191D2750EBEB05F32C4BE08154D991F08DE4914BC40FAA7172440F2FEFB0FBF604DDA9C18BA9FD55F34218FD5D7CA2AC491CEDC3C5743D143BAF6C06CCAB7E5B22AB4E46CD51962CC7931F4D35581D5DD3047B946044BF7E71955EB63DD546644D7D2A19777DA39A48B4CF5A011A5C41F1BFF7C463F057F2F7AF6F910E7E06398B0AF7EF38CD5BBAE4C5FF42572CFFFCA6A8E9D34F64A7BECDC93216B55C20FAECAF04A8956C4D26DEE34493510BC49144A32A1B0AAE64B50DCA0C27361692242FE3145A6B36B830DEBF9E8A07A886E8DA6F38F3E99906F6AC9317ADF73222C4C75ABD153F1112E01E7CBB49665F213A1C1470CDC442D7CDC72EE2DD80D37251333C34FFDC5C38ADA3F5E52F5A5B2A1224B0CA60211B430E9554F0C4CA672476562C4A182B6707EBE80DFA6247A1F870F74EC81D03558F2718409EBF8E7F2FD2C6AB1F246F7E3FE0D919DB4016A7D76F6378D05EA74766CBB93340F2CBDDF18073F39242F3E9EC88020D1E8F801183C00F0239B2F2B4E8F6B46DBC17F469A857C291C985D8AC2099A6FEDC462B5EAEF737831EA2B6C9D787DC5AC8DA2C2E8F7F676FDA4CDD79E400EED959882C78C279C4D0A5918A0F5FC3B695E0034F7C2665D52D94106744D6B0CD6A66AB3275324EFDC06ECCF431D446446A00818ECDBE77B845699FB4F699825702D00F71373D80452039ECA1237AD2A0DF9112BA1EC90FB9FB87CF4E46BD0319B64F2EFD4B9640469707DB549468781D0BA6F3C49AF035D441173786BB1F2F5DCCE07BBF5536A0EB5B976814ABFDB44B90E55455972701A8F0D8EFB860A082ABA960E704754F61C2E3956922833F3D7E1656476DEE3C4F09244AC15697EA4A73041F03EEDE1F30BF899098A70F33FA1DB177 +20241129090902 2 6 100 6143 2 DCBE8A152DD5DE612BFCCD18CAB2BDE17391AF9DA865DCC59A1B454144ADE2EB8BE3CDBA7948CD1236CFC25D66DDC0E91095FB7E17715247413BBFD5435223F46488AD93808AF9FAF7D473C7CCE55DAA83B417FC6C09BFF7E332BD4B3BC59CBA4FE035A6C416D32BDCF8C3B9AFC5E1120CFD420023FD8EB207DB965509E2D362B0EB3D8CBD191D2750EBEB05F32C4BE08154D991F08DE4914BC40FAA7172440F2FEFB0FBF604DDA9C18BA9FD55F34218FD5D7CA2AC491CEDC3C5743D143BAF6C06CCAB7E5B22AB4E46CD51962CC7931F4D35581D5DD3047B946044BF7E71955EB63DD546644D7D2A19777DA39A48B4CF5A011A5C41F1BFF7C463F057F2F7AF6F910E7E06398B0AF7EF38CD5BBAE4C5FF42572CFFFCA6A8E9D34F64A7BECDC93216B55C20FAECAF04A8956C4D26DEE34493510BC49144A32A1B0AAE64B50DCA0C27361692242FE3145A6B36B830DEBF9E8A07A886E8DA6F38F3E99906F6AC9317ADF73222C4C75ABD153F1112E01E7CBB49665F213A1C1470CDC442D7CDC72EE2DD80D37251333C34FFDC5C38ADA3F5E52F5A5B2A1224B0CA60211B430E9554F0C4CA672476562C4A182B6707EBE80DFA6247A1F870F74EC81D03558F2718409EBF8E7F2FD2C6AB1F246F7E3FE0D919DB4016A7D76F6378D05EA74766CBB93340F2CBDDF18073F39242F3E9EC88020D1E8F801183C00F0239B2F2B4E8F6B46DBC17F469A857C291C985D8AC2099A6FEDC462B5EAEF737831EA2B6C9D787DC5AC8DA2C2E8F7F676FDA4CDD79E400EED959882C78C279C4D0A5918A0F5FC3B695E0034F7C2665D52D94106744D6B0CD6A66AB3275324EFDC06ECCF431D446446A00818ECDBE77B845699FB4F699825702D00F71373D80452039ECA1237AD2A0DF9112BA1EC90FB9FB87CF4E46BD0319B64F2EFD4B9640469707DB549468781D0BA6F3C49AF035D441173786BB1F2F5DCCE07BBF5536A0EB5B976814ABFDB44B90E55455972701A8F0D8EFB860A082ABA960E704754F61C2E3956922833F3D7E1656476DEE3C4F09244AC15697EA4A73041F03EEDE1F30BF899098A70F33FE76C9B3 +20241129090942 2 6 100 6143 5 DCBE8A152DD5DE612BFCCD18CAB2BDE17391AF9DA865DCC59A1B454144ADE2EB8BE3CDBA7948CD1236CFC25D66DDC0E91095FB7E17715247413BBFD5435223F46488AD93808AF9FAF7D473C7CCE55DAA83B417FC6C09BFF7E332BD4B3BC59CBA4FE035A6C416D32BDCF8C3B9AFC5E1120CFD420023FD8EB207DB965509E2D362B0EB3D8CBD191D2750EBEB05F32C4BE08154D991F08DE4914BC40FAA7172440F2FEFB0FBF604DDA9C18BA9FD55F34218FD5D7CA2AC491CEDC3C5743D143BAF6C06CCAB7E5B22AB4E46CD51962CC7931F4D35581D5DD3047B946044BF7E71955EB63DD546644D7D2A19777DA39A48B4CF5A011A5C41F1BFF7C463F057F2F7AF6F910E7E06398B0AF7EF38CD5BBAE4C5FF42572CFFFCA6A8E9D34F64A7BECDC93216B55C20FAECAF04A8956C4D26DEE34493510BC49144A32A1B0AAE64B50DCA0C27361692242FE3145A6B36B830DEBF9E8A07A886E8DA6F38F3E99906F6AC9317ADF73222C4C75ABD153F1112E01E7CBB49665F213A1C1470CDC442D7CDC72EE2DD80D37251333C34FFDC5C38ADA3F5E52F5A5B2A1224B0CA60211B430E9554F0C4CA672476562C4A182B6707EBE80DFA6247A1F870F74EC81D03558F2718409EBF8E7F2FD2C6AB1F246F7E3FE0D919DB4016A7D76F6378D05EA74766CBB93340F2CBDDF18073F39242F3E9EC88020D1E8F801183C00F0239B2F2B4E8F6B46DBC17F469A857C291C985D8AC2099A6FEDC462B5EAEF737831EA2B6C9D787DC5AC8DA2C2E8F7F676FDA4CDD79E400EED959882C78C279C4D0A5918A0F5FC3B695E0034F7C2665D52D94106744D6B0CD6A66AB3275324EFDC06ECCF431D446446A00818ECDBE77B845699FB4F699825702D00F71373D80452039ECA1237AD2A0DF9112BA1EC90FB9FB87CF4E46BD0319B64F2EFD4B9640469707DB549468781D0BA6F3C49AF035D441173786BB1F2F5DCCE07BBF5536A0EB5B976814ABFDB44B90E55455972701A8F0D8EFB860A082ABA960E704754F61C2E3956922833F3D7E1656476DEE3C4F09244AC15697EA4A73041F03EEDE1F30BF899098A70F33FE840CCF +20241129091044 2 6 100 6143 2 DCBE8A152DD5DE612BFCCD18CAB2BDE17391AF9DA865DCC59A1B454144ADE2EB8BE3CDBA7948CD1236CFC25D66DDC0E91095FB7E17715247413BBFD5435223F46488AD93808AF9FAF7D473C7CCE55DAA83B417FC6C09BFF7E332BD4B3BC59CBA4FE035A6C416D32BDCF8C3B9AFC5E1120CFD420023FD8EB207DB965509E2D362B0EB3D8CBD191D2750EBEB05F32C4BE08154D991F08DE4914BC40FAA7172440F2FEFB0FBF604DDA9C18BA9FD55F34218FD5D7CA2AC491CEDC3C5743D143BAF6C06CCAB7E5B22AB4E46CD51962CC7931F4D35581D5DD3047B946044BF7E71955EB63DD546644D7D2A19777DA39A48B4CF5A011A5C41F1BFF7C463F057F2F7AF6F910E7E06398B0AF7EF38CD5BBAE4C5FF42572CFFFCA6A8E9D34F64A7BECDC93216B55C20FAECAF04A8956C4D26DEE34493510BC49144A32A1B0AAE64B50DCA0C27361692242FE3145A6B36B830DEBF9E8A07A886E8DA6F38F3E99906F6AC9317ADF73222C4C75ABD153F1112E01E7CBB49665F213A1C1470CDC442D7CDC72EE2DD80D37251333C34FFDC5C38ADA3F5E52F5A5B2A1224B0CA60211B430E9554F0C4CA672476562C4A182B6707EBE80DFA6247A1F870F74EC81D03558F2718409EBF8E7F2FD2C6AB1F246F7E3FE0D919DB4016A7D76F6378D05EA74766CBB93340F2CBDDF18073F39242F3E9EC88020D1E8F801183C00F0239B2F2B4E8F6B46DBC17F469A857C291C985D8AC2099A6FEDC462B5EAEF737831EA2B6C9D787DC5AC8DA2C2E8F7F676FDA4CDD79E400EED959882C78C279C4D0A5918A0F5FC3B695E0034F7C2665D52D94106744D6B0CD6A66AB3275324EFDC06ECCF431D446446A00818ECDBE77B845699FB4F699825702D00F71373D80452039ECA1237AD2A0DF9112BA1EC90FB9FB87CF4E46BD0319B64F2EFD4B9640469707DB549468781D0BA6F3C49AF035D441173786BB1F2F5DCCE07BBF5536A0EB5B976814ABFDB44B90E55455972701A8F0D8EFB860A082ABA960E704754F61C2E3956922833F3D7E1656476DEE3C4F09244AC15697EA4A73041F03EEDE1F30BF899098A70F33FE9F0AB3 +20241129091214 2 6 100 6143 2 DCBE8A152DD5DE612BFCCD18CAB2BDE17391AF9DA865DCC59A1B454144ADE2EB8BE3CDBA7948CD1236CFC25D66DDC0E91095FB7E17715247413BBFD5435223F46488AD93808AF9FAF7D473C7CCE55DAA83B417FC6C09BFF7E332BD4B3BC59CBA4FE035A6C416D32BDCF8C3B9AFC5E1120CFD420023FD8EB207DB965509E2D362B0EB3D8CBD191D2750EBEB05F32C4BE08154D991F08DE4914BC40FAA7172440F2FEFB0FBF604DDA9C18BA9FD55F34218FD5D7CA2AC491CEDC3C5743D143BAF6C06CCAB7E5B22AB4E46CD51962CC7931F4D35581D5DD3047B946044BF7E71955EB63DD546644D7D2A19777DA39A48B4CF5A011A5C41F1BFF7C463F057F2F7AF6F910E7E06398B0AF7EF38CD5BBAE4C5FF42572CFFFCA6A8E9D34F64A7BECDC93216B55C20FAECAF04A8956C4D26DEE34493510BC49144A32A1B0AAE64B50DCA0C27361692242FE3145A6B36B830DEBF9E8A07A886E8DA6F38F3E99906F6AC9317ADF73222C4C75ABD153F1112E01E7CBB49665F213A1C1470CDC442D7CDC72EE2DD80D37251333C34FFDC5C38ADA3F5E52F5A5B2A1224B0CA60211B430E9554F0C4CA672476562C4A182B6707EBE80DFA6247A1F870F74EC81D03558F2718409EBF8E7F2FD2C6AB1F246F7E3FE0D919DB4016A7D76F6378D05EA74766CBB93340F2CBDDF18073F39242F3E9EC88020D1E8F801183C00F0239B2F2B4E8F6B46DBC17F469A857C291C985D8AC2099A6FEDC462B5EAEF737831EA2B6C9D787DC5AC8DA2C2E8F7F676FDA4CDD79E400EED959882C78C279C4D0A5918A0F5FC3B695E0034F7C2665D52D94106744D6B0CD6A66AB3275324EFDC06ECCF431D446446A00818ECDBE77B845699FB4F699825702D00F71373D80452039ECA1237AD2A0DF9112BA1EC90FB9FB87CF4E46BD0319B64F2EFD4B9640469707DB549468781D0BA6F3C49AF035D441173786BB1F2F5DCCE07BBF5536A0EB5B976814ABFDB44B90E55455972701A8F0D8EFB860A082ABA960E704754F61C2E3956922833F3D7E1656476DEE3C4F09244AC15697EA4A73041F03EEDE1F30BF899098A70F33FEC8962B +20241129100858 2 6 100 6143 2 DCBE8A152DD5DE612BFCCD18CAB2BDE17391AF9DA865DCC59A1B454144ADE2EB8BE3CDBA7948CD1236CFC25D66DDC0E91095FB7E17715247413BBFD5435223F46488AD93808AF9FAF7D473C7CCE55DAA83B417FC6C09BFF7E332BD4B3BC59CBA4FE035A6C416D32BDCF8C3B9AFC5E1120CFD420023FD8EB207DB965509E2D362B0EB3D8CBD191D2750EBEB05F32C4BE08154D991F08DE4914BC40FAA7172440F2FEFB0FBF604DDA9C18BA9FD55F34218FD5D7CA2AC491CEDC3C5743D143BAF6C06CCAB7E5B22AB4E46CD51962CC7931F4D35581D5DD3047B946044BF7E71955EB63DD546644D7D2A19777DA39A48B4CF5A011A5C41F1BFF7C463F057F2F7AF6F910E7E06398B0AF7EF38CD5BBAE4C5FF42572CFFFCA6A8E9D34F64A7BECDC93216B55C20FAECAF04A8956C4D26DEE34493510BC49144A32A1B0AAE64B50DCA0C27361692242FE3145A6B36B830DEBF9E8A07A886E8DA6F38F3E99906F6AC9317ADF73222C4C75ABD153F1112E01E7CBB49665F213A1C1470CDC442D7CDC72EE2DD80D37251333C34FFDC5C38ADA3F5E52F5A5B2A1224B0CA60211B430E9554F0C4CA672476562C4A182B6707EBE80DFA6247A1F870F74EC81D03558F2718409EBF8E7F2FD2C6AB1F246F7E3FE0D919DB4016A7D76F6378D05EA74766CBB93340F2CBDDF18073F39242F3E9EC88020D1E8F801183C00F0239B2F2B4E8F6B46DBC17F469A857C291C985D8AC2099A6FEDC462B5EAEF737831EA2B6C9D787DC5AC8DA2C2E8F7F676FDA4CDD79E400EED959882C78C279C4D0A5918A0F5FC3B695E0034F7C2665D52D94106744D6B0CD6A66AB3275324EFDC06ECCF431D446446A00818ECDBE77B845699FB4F699825702D00F71373D80452039ECA1237AD2A0DF9112BA1EC90FB9FB87CF4E46BD0319B64F2EFD4B9640469707DB549468781D0BA6F3C49AF035D441173786BB1F2F5DCCE07BBF5536A0EB5B976814ABFDB44B90E55455972701A8F0D8EFB860A082ABA960E704754F61C2E3956922833F3D7E1656476DEE3C4F09244AC15697EA4A73041F03EEDE1F30BF899098A70F3405C51773 +20241129101114 2 6 100 6143 2 DCBE8A152DD5DE612BFCCD18CAB2BDE17391AF9DA865DCC59A1B454144ADE2EB8BE3CDBA7948CD1236CFC25D66DDC0E91095FB7E17715247413BBFD5435223F46488AD93808AF9FAF7D473C7CCE55DAA83B417FC6C09BFF7E332BD4B3BC59CBA4FE035A6C416D32BDCF8C3B9AFC5E1120CFD420023FD8EB207DB965509E2D362B0EB3D8CBD191D2750EBEB05F32C4BE08154D991F08DE4914BC40FAA7172440F2FEFB0FBF604DDA9C18BA9FD55F34218FD5D7CA2AC491CEDC3C5743D143BAF6C06CCAB7E5B22AB4E46CD51962CC7931F4D35581D5DD3047B946044BF7E71955EB63DD546644D7D2A19777DA39A48B4CF5A011A5C41F1BFF7C463F057F2F7AF6F910E7E06398B0AF7EF38CD5BBAE4C5FF42572CFFFCA6A8E9D34F64A7BECDC93216B55C20FAECAF04A8956C4D26DEE34493510BC49144A32A1B0AAE64B50DCA0C27361692242FE3145A6B36B830DEBF9E8A07A886E8DA6F38F3E99906F6AC9317ADF73222C4C75ABD153F1112E01E7CBB49665F213A1C1470CDC442D7CDC72EE2DD80D37251333C34FFDC5C38ADA3F5E52F5A5B2A1224B0CA60211B430E9554F0C4CA672476562C4A182B6707EBE80DFA6247A1F870F74EC81D03558F2718409EBF8E7F2FD2C6AB1F246F7E3FE0D919DB4016A7D76F6378D05EA74766CBB93340F2CBDDF18073F39242F3E9EC88020D1E8F801183C00F0239B2F2B4E8F6B46DBC17F469A857C291C985D8AC2099A6FEDC462B5EAEF737831EA2B6C9D787DC5AC8DA2C2E8F7F676FDA4CDD79E400EED959882C78C279C4D0A5918A0F5FC3B695E0034F7C2665D52D94106744D6B0CD6A66AB3275324EFDC06ECCF431D446446A00818ECDBE77B845699FB4F699825702D00F71373D80452039ECA1237AD2A0DF9112BA1EC90FB9FB87CF4E46BD0319B64F2EFD4B9640469707DB549468781D0BA6F3C49AF035D441173786BB1F2F5DCCE07BBF5536A0EB5B976814ABFDB44B90E55455972701A8F0D8EFB860A082ABA960E704754F61C2E3956922833F3D7E1656476DEE3C4F09244AC15697EA4A73041F03EEDE1F30BF899098A70F3405F7D2BB +20241129101614 2 6 100 6143 2 DCBE8A152DD5DE612BFCCD18CAB2BDE17391AF9DA865DCC59A1B454144ADE2EB8BE3CDBA7948CD1236CFC25D66DDC0E91095FB7E17715247413BBFD5435223F46488AD93808AF9FAF7D473C7CCE55DAA83B417FC6C09BFF7E332BD4B3BC59CBA4FE035A6C416D32BDCF8C3B9AFC5E1120CFD420023FD8EB207DB965509E2D362B0EB3D8CBD191D2750EBEB05F32C4BE08154D991F08DE4914BC40FAA7172440F2FEFB0FBF604DDA9C18BA9FD55F34218FD5D7CA2AC491CEDC3C5743D143BAF6C06CCAB7E5B22AB4E46CD51962CC7931F4D35581D5DD3047B946044BF7E71955EB63DD546644D7D2A19777DA39A48B4CF5A011A5C41F1BFF7C463F057F2F7AF6F910E7E06398B0AF7EF38CD5BBAE4C5FF42572CFFFCA6A8E9D34F64A7BECDC93216B55C20FAECAF04A8956C4D26DEE34493510BC49144A32A1B0AAE64B50DCA0C27361692242FE3145A6B36B830DEBF9E8A07A886E8DA6F38F3E99906F6AC9317ADF73222C4C75ABD153F1112E01E7CBB49665F213A1C1470CDC442D7CDC72EE2DD80D37251333C34FFDC5C38ADA3F5E52F5A5B2A1224B0CA60211B430E9554F0C4CA672476562C4A182B6707EBE80DFA6247A1F870F74EC81D03558F2718409EBF8E7F2FD2C6AB1F246F7E3FE0D919DB4016A7D76F6378D05EA74766CBB93340F2CBDDF18073F39242F3E9EC88020D1E8F801183C00F0239B2F2B4E8F6B46DBC17F469A857C291C985D8AC2099A6FEDC462B5EAEF737831EA2B6C9D787DC5AC8DA2C2E8F7F676FDA4CDD79E400EED959882C78C279C4D0A5918A0F5FC3B695E0034F7C2665D52D94106744D6B0CD6A66AB3275324EFDC06ECCF431D446446A00818ECDBE77B845699FB4F699825702D00F71373D80452039ECA1237AD2A0DF9112BA1EC90FB9FB87CF4E46BD0319B64F2EFD4B9640469707DB549468781D0BA6F3C49AF035D441173786BB1F2F5DCCE07BBF5536A0EB5B976814ABFDB44B90E55455972701A8F0D8EFB860A082ABA960E704754F61C2E3956922833F3D7E1656476DEE3C4F09244AC15697EA4A73041F03EEDE1F30BF899098A70F34068F4943 +20241129103634 2 6 100 6143 2 DCBE8A152DD5DE612BFCCD18CAB2BDE17391AF9DA865DCC59A1B454144ADE2EB8BE3CDBA7948CD1236CFC25D66DDC0E91095FB7E17715247413BBFD5435223F46488AD93808AF9FAF7D473C7CCE55DAA83B417FC6C09BFF7E332BD4B3BC59CBA4FE035A6C416D32BDCF8C3B9AFC5E1120CFD420023FD8EB207DB965509E2D362B0EB3D8CBD191D2750EBEB05F32C4BE08154D991F08DE4914BC40FAA7172440F2FEFB0FBF604DDA9C18BA9FD55F34218FD5D7CA2AC491CEDC3C5743D143BAF6C06CCAB7E5B22AB4E46CD51962CC7931F4D35581D5DD3047B946044BF7E71955EB63DD546644D7D2A19777DA39A48B4CF5A011A5C41F1BFF7C463F057F2F7AF6F910E7E06398B0AF7EF38CD5BBAE4C5FF42572CFFFCA6A8E9D34F64A7BECDC93216B55C20FAECAF04A8956C4D26DEE34493510BC49144A32A1B0AAE64B50DCA0C27361692242FE3145A6B36B830DEBF9E8A07A886E8DA6F38F3E99906F6AC9317ADF73222C4C75ABD153F1112E01E7CBB49665F213A1C1470CDC442D7CDC72EE2DD80D37251333C34FFDC5C38ADA3F5E52F5A5B2A1224B0CA60211B430E9554F0C4CA672476562C4A182B6707EBE80DFA6247A1F870F74EC81D03558F2718409EBF8E7F2FD2C6AB1F246F7E3FE0D919DB4016A7D76F6378D05EA74766CBB93340F2CBDDF18073F39242F3E9EC88020D1E8F801183C00F0239B2F2B4E8F6B46DBC17F469A857C291C985D8AC2099A6FEDC462B5EAEF737831EA2B6C9D787DC5AC8DA2C2E8F7F676FDA4CDD79E400EED959882C78C279C4D0A5918A0F5FC3B695E0034F7C2665D52D94106744D6B0CD6A66AB3275324EFDC06ECCF431D446446A00818ECDBE77B845699FB4F699825702D00F71373D80452039ECA1237AD2A0DF9112BA1EC90FB9FB87CF4E46BD0319B64F2EFD4B9640469707DB549468781D0BA6F3C49AF035D441173786BB1F2F5DCCE07BBF5536A0EB5B976814ABFDB44B90E55455972701A8F0D8EFB860A082ABA960E704754F61C2E3956922833F3D7E1656476DEE3C4F09244AC15697EA4A73041F03EEDE1F30BF899098A70F340916E6EB +20241129103953 2 6 100 6143 2 DCBE8A152DD5DE612BFCCD18CAB2BDE17391AF9DA865DCC59A1B454144ADE2EB8BE3CDBA7948CD1236CFC25D66DDC0E91095FB7E17715247413BBFD5435223F46488AD93808AF9FAF7D473C7CCE55DAA83B417FC6C09BFF7E332BD4B3BC59CBA4FE035A6C416D32BDCF8C3B9AFC5E1120CFD420023FD8EB207DB965509E2D362B0EB3D8CBD191D2750EBEB05F32C4BE08154D991F08DE4914BC40FAA7172440F2FEFB0FBF604DDA9C18BA9FD55F34218FD5D7CA2AC491CEDC3C5743D143BAF6C06CCAB7E5B22AB4E46CD51962CC7931F4D35581D5DD3047B946044BF7E71955EB63DD546644D7D2A19777DA39A48B4CF5A011A5C41F1BFF7C463F057F2F7AF6F910E7E06398B0AF7EF38CD5BBAE4C5FF42572CFFFCA6A8E9D34F64A7BECDC93216B55C20FAECAF04A8956C4D26DEE34493510BC49144A32A1B0AAE64B50DCA0C27361692242FE3145A6B36B830DEBF9E8A07A886E8DA6F38F3E99906F6AC9317ADF73222C4C75ABD153F1112E01E7CBB49665F213A1C1470CDC442D7CDC72EE2DD80D37251333C34FFDC5C38ADA3F5E52F5A5B2A1224B0CA60211B430E9554F0C4CA672476562C4A182B6707EBE80DFA6247A1F870F74EC81D03558F2718409EBF8E7F2FD2C6AB1F246F7E3FE0D919DB4016A7D76F6378D05EA74766CBB93340F2CBDDF18073F39242F3E9EC88020D1E8F801183C00F0239B2F2B4E8F6B46DBC17F469A857C291C985D8AC2099A6FEDC462B5EAEF737831EA2B6C9D787DC5AC8DA2C2E8F7F676FDA4CDD79E400EED959882C78C279C4D0A5918A0F5FC3B695E0034F7C2665D52D94106744D6B0CD6A66AB3275324EFDC06ECCF431D446446A00818ECDBE77B845699FB4F699825702D00F71373D80452039ECA1237AD2A0DF9112BA1EC90FB9FB87CF4E46BD0319B64F2EFD4B9640469707DB549468781D0BA6F3C49AF035D441173786BB1F2F5DCCE07BBF5536A0EB5B976814ABFDB44B90E55455972701A8F0D8EFB860A082ABA960E704754F61C2E3956922833F3D7E1656476DEE3C4F09244AC15697EA4A73041F03EEDE1F30BF899098A70F34097696F3 +20241129104959 2 6 100 6143 2 DCBE8A152DD5DE612BFCCD18CAB2BDE17391AF9DA865DCC59A1B454144ADE2EB8BE3CDBA7948CD1236CFC25D66DDC0E91095FB7E17715247413BBFD5435223F46488AD93808AF9FAF7D473C7CCE55DAA83B417FC6C09BFF7E332BD4B3BC59CBA4FE035A6C416D32BDCF8C3B9AFC5E1120CFD420023FD8EB207DB965509E2D362B0EB3D8CBD191D2750EBEB05F32C4BE08154D991F08DE4914BC40FAA7172440F2FEFB0FBF604DDA9C18BA9FD55F34218FD5D7CA2AC491CEDC3C5743D143BAF6C06CCAB7E5B22AB4E46CD51962CC7931F4D35581D5DD3047B946044BF7E71955EB63DD546644D7D2A19777DA39A48B4CF5A011A5C41F1BFF7C463F057F2F7AF6F910E7E06398B0AF7EF38CD5BBAE4C5FF42572CFFFCA6A8E9D34F64A7BECDC93216B55C20FAECAF04A8956C4D26DEE34493510BC49144A32A1B0AAE64B50DCA0C27361692242FE3145A6B36B830DEBF9E8A07A886E8DA6F38F3E99906F6AC9317ADF73222C4C75ABD153F1112E01E7CBB49665F213A1C1470CDC442D7CDC72EE2DD80D37251333C34FFDC5C38ADA3F5E52F5A5B2A1224B0CA60211B430E9554F0C4CA672476562C4A182B6707EBE80DFA6247A1F870F74EC81D03558F2718409EBF8E7F2FD2C6AB1F246F7E3FE0D919DB4016A7D76F6378D05EA74766CBB93340F2CBDDF18073F39242F3E9EC88020D1E8F801183C00F0239B2F2B4E8F6B46DBC17F469A857C291C985D8AC2099A6FEDC462B5EAEF737831EA2B6C9D787DC5AC8DA2C2E8F7F676FDA4CDD79E400EED959882C78C279C4D0A5918A0F5FC3B695E0034F7C2665D52D94106744D6B0CD6A66AB3275324EFDC06ECCF431D446446A00818ECDBE77B845699FB4F699825702D00F71373D80452039ECA1237AD2A0DF9112BA1EC90FB9FB87CF4E46BD0319B64F2EFD4B9640469707DB549468781D0BA6F3C49AF035D441173786BB1F2F5DCCE07BBF5536A0EB5B976814ABFDB44B90E55455972701A8F0D8EFB860A082ABA960E704754F61C2E3956922833F3D7E1656476DEE3C4F09244AC15697EA4A73041F03EEDE1F30BF899098A70F340AAE5B3B +20241129112051 2 6 100 6143 5 DCBE8A152DD5DE612BFCCD18CAB2BDE17391AF9DA865DCC59A1B454144ADE2EB8BE3CDBA7948CD1236CFC25D66DDC0E91095FB7E17715247413BBFD5435223F46488AD93808AF9FAF7D473C7CCE55DAA83B417FC6C09BFF7E332BD4B3BC59CBA4FE035A6C416D32BDCF8C3B9AFC5E1120CFD420023FD8EB207DB965509E2D362B0EB3D8CBD191D2750EBEB05F32C4BE08154D991F08DE4914BC40FAA7172440F2FEFB0FBF604DDA9C18BA9FD55F34218FD5D7CA2AC491CEDC3C5743D143BAF6C06CCAB7E5B22AB4E46CD51962CC7931F4D35581D5DD3047B946044BF7E71955EB63DD546644D7D2A19777DA39A48B4CF5A011A5C41F1BFF7C463F057F2F7AF6F910E7E06398B0AF7EF38CD5BBAE4C5FF42572CFFFCA6A8E9D34F64A7BECDC93216B55C20FAECAF04A8956C4D26DEE34493510BC49144A32A1B0AAE64B50DCA0C27361692242FE3145A6B36B830DEBF9E8A07A886E8DA6F38F3E99906F6AC9317ADF73222C4C75ABD153F1112E01E7CBB49665F213A1C1470CDC442D7CDC72EE2DD80D37251333C34FFDC5C38ADA3F5E52F5A5B2A1224B0CA60211B430E9554F0C4CA672476562C4A182B6707EBE80DFA6247A1F870F74EC81D03558F2718409EBF8E7F2FD2C6AB1F246F7E3FE0D919DB4016A7D76F6378D05EA74766CBB93340F2CBDDF18073F39242F3E9EC88020D1E8F801183C00F0239B2F2B4E8F6B46DBC17F469A857C291C985D8AC2099A6FEDC462B5EAEF737831EA2B6C9D787DC5AC8DA2C2E8F7F676FDA4CDD79E400EED959882C78C279C4D0A5918A0F5FC3B695E0034F7C2665D52D94106744D6B0CD6A66AB3275324EFDC06ECCF431D446446A00818ECDBE77B845699FB4F699825702D00F71373D80452039ECA1237AD2A0DF9112BA1EC90FB9FB87CF4E46BD0319B64F2EFD4B9640469707DB549468781D0BA6F3C49AF035D441173786BB1F2F5DCCE07BBF5536A0EB5B976814ABFDB44B90E55455972701A8F0D8EFB860A082ABA960E704754F61C2E3956922833F3D7E1656476DEE3C4F09244AC15697EA4A73041F03EEDE1F30BF899098A70F340E9853AF +20241129124108 2 6 100 6143 2 DCBE8A152DD5DE612BFCCD18CAB2BDE17391AF9DA865DCC59A1B454144ADE2EB8BE3CDBA7948CD1236CFC25D66DDC0E91095FB7E17715247413BBFD5435223F46488AD93808AF9FAF7D473C7CCE55DAA83B417FC6C09BFF7E332BD4B3BC59CBA4FE035A6C416D32BDCF8C3B9AFC5E1120CFD420023FD8EB207DB965509E2D362B0EB3D8CBD191D2750EBEB05F32C4BE08154D991F08DE4914BC40FAA7172440F2FEFB0FBF604DDA9C18BA9FD55F34218FD5D7CA2AC491CEDC3C5743D143BAF6C06CCAB7E5B22AB4E46CD51962CC7931F4D35581D5DD3047B946044BF7E71955EB63DD546644D7D2A19777DA39A48B4CF5A011A5C41F1BFF7C463F057F2F7AF6F910E7E06398B0AF7EF38CD5BBAE4C5FF42572CFFFCA6A8E9D34F64A7BECDC93216B55C20FAECAF04A8956C4D26DEE34493510BC49144A32A1B0AAE64B50DCA0C27361692242FE3145A6B36B830DEBF9E8A07A886E8DA6F38F3E99906F6AC9317ADF73222C4C75ABD153F1112E01E7CBB49665F213A1C1470CDC442D7CDC72EE2DD80D37251333C34FFDC5C38ADA3F5E52F5A5B2A1224B0CA60211B430E9554F0C4CA672476562C4A182B6707EBE80DFA6247A1F870F74EC81D03558F2718409EBF8E7F2FD2C6AB1F246F7E3FE0D919DB4016A7D76F6378D05EA74766CBB93340F2CBDDF18073F39242F3E9EC88020D1E8F801183C00F0239B2F2B4E8F6B46DBC17F469A857C291C985D8AC2099A6FEDC462B5EAEF737831EA2B6C9D787DC5AC8DA2C2E8F7F676FDA4CDD79E400EED959882C78C279C4D0A5918A0F5FC3B695E0034F7C2665D52D94106744D6B0CD6A66AB3275324EFDC06ECCF431D446446A00818ECDBE77B845699FB4F699825702D00F71373D80452039ECA1237AD2A0DF9112BA1EC90FB9FB87CF4E46BD0319B64F2EFD4B9640469707DB549468781D0BA6F3C49AF035D441173786BB1F2F5DCCE07BBF5536A0EB5B976814ABFDB44B90E55455972701A8F0D8EFB860A082ABA960E704754F61C2E3956922833F3D7E1656476DEE3C4F09244AC15697EA4A73041F03EEDE1F30BF899098A70F3418BD011B +20241129125049 2 6 100 6143 5 DCBE8A152DD5DE612BFCCD18CAB2BDE17391AF9DA865DCC59A1B454144ADE2EB8BE3CDBA7948CD1236CFC25D66DDC0E91095FB7E17715247413BBFD5435223F46488AD93808AF9FAF7D473C7CCE55DAA83B417FC6C09BFF7E332BD4B3BC59CBA4FE035A6C416D32BDCF8C3B9AFC5E1120CFD420023FD8EB207DB965509E2D362B0EB3D8CBD191D2750EBEB05F32C4BE08154D991F08DE4914BC40FAA7172440F2FEFB0FBF604DDA9C18BA9FD55F34218FD5D7CA2AC491CEDC3C5743D143BAF6C06CCAB7E5B22AB4E46CD51962CC7931F4D35581D5DD3047B946044BF7E71955EB63DD546644D7D2A19777DA39A48B4CF5A011A5C41F1BFF7C463F057F2F7AF6F910E7E06398B0AF7EF38CD5BBAE4C5FF42572CFFFCA6A8E9D34F64A7BECDC93216B55C20FAECAF04A8956C4D26DEE34493510BC49144A32A1B0AAE64B50DCA0C27361692242FE3145A6B36B830DEBF9E8A07A886E8DA6F38F3E99906F6AC9317ADF73222C4C75ABD153F1112E01E7CBB49665F213A1C1470CDC442D7CDC72EE2DD80D37251333C34FFDC5C38ADA3F5E52F5A5B2A1224B0CA60211B430E9554F0C4CA672476562C4A182B6707EBE80DFA6247A1F870F74EC81D03558F2718409EBF8E7F2FD2C6AB1F246F7E3FE0D919DB4016A7D76F6378D05EA74766CBB93340F2CBDDF18073F39242F3E9EC88020D1E8F801183C00F0239B2F2B4E8F6B46DBC17F469A857C291C985D8AC2099A6FEDC462B5EAEF737831EA2B6C9D787DC5AC8DA2C2E8F7F676FDA4CDD79E400EED959882C78C279C4D0A5918A0F5FC3B695E0034F7C2665D52D94106744D6B0CD6A66AB3275324EFDC06ECCF431D446446A00818ECDBE77B845699FB4F699825702D00F71373D80452039ECA1237AD2A0DF9112BA1EC90FB9FB87CF4E46BD0319B64F2EFD4B9640469707DB549468781D0BA6F3C49AF035D441173786BB1F2F5DCCE07BBF5536A0EB5B976814ABFDB44B90E55455972701A8F0D8EFB860A082ABA960E704754F61C2E3956922833F3D7E1656476DEE3C4F09244AC15697EA4A73041F03EEDE1F30BF899098A70F3419E8F797 +20241129125233 2 6 100 6143 5 DCBE8A152DD5DE612BFCCD18CAB2BDE17391AF9DA865DCC59A1B454144ADE2EB8BE3CDBA7948CD1236CFC25D66DDC0E91095FB7E17715247413BBFD5435223F46488AD93808AF9FAF7D473C7CCE55DAA83B417FC6C09BFF7E332BD4B3BC59CBA4FE035A6C416D32BDCF8C3B9AFC5E1120CFD420023FD8EB207DB965509E2D362B0EB3D8CBD191D2750EBEB05F32C4BE08154D991F08DE4914BC40FAA7172440F2FEFB0FBF604DDA9C18BA9FD55F34218FD5D7CA2AC491CEDC3C5743D143BAF6C06CCAB7E5B22AB4E46CD51962CC7931F4D35581D5DD3047B946044BF7E71955EB63DD546644D7D2A19777DA39A48B4CF5A011A5C41F1BFF7C463F057F2F7AF6F910E7E06398B0AF7EF38CD5BBAE4C5FF42572CFFFCA6A8E9D34F64A7BECDC93216B55C20FAECAF04A8956C4D26DEE34493510BC49144A32A1B0AAE64B50DCA0C27361692242FE3145A6B36B830DEBF9E8A07A886E8DA6F38F3E99906F6AC9317ADF73222C4C75ABD153F1112E01E7CBB49665F213A1C1470CDC442D7CDC72EE2DD80D37251333C34FFDC5C38ADA3F5E52F5A5B2A1224B0CA60211B430E9554F0C4CA672476562C4A182B6707EBE80DFA6247A1F870F74EC81D03558F2718409EBF8E7F2FD2C6AB1F246F7E3FE0D919DB4016A7D76F6378D05EA74766CBB93340F2CBDDF18073F39242F3E9EC88020D1E8F801183C00F0239B2F2B4E8F6B46DBC17F469A857C291C985D8AC2099A6FEDC462B5EAEF737831EA2B6C9D787DC5AC8DA2C2E8F7F676FDA4CDD79E400EED959882C78C279C4D0A5918A0F5FC3B695E0034F7C2665D52D94106744D6B0CD6A66AB3275324EFDC06ECCF431D446446A00818ECDBE77B845699FB4F699825702D00F71373D80452039ECA1237AD2A0DF9112BA1EC90FB9FB87CF4E46BD0319B64F2EFD4B9640469707DB549468781D0BA6F3C49AF035D441173786BB1F2F5DCCE07BBF5536A0EB5B976814ABFDB44B90E55455972701A8F0D8EFB860A082ABA960E704754F61C2E3956922833F3D7E1656476DEE3C4F09244AC15697EA4A73041F03EEDE1F30BF899098A70F341A1B7937 +20241129130334 2 6 100 6143 2 DCBE8A152DD5DE612BFCCD18CAB2BDE17391AF9DA865DCC59A1B454144ADE2EB8BE3CDBA7948CD1236CFC25D66DDC0E91095FB7E17715247413BBFD5435223F46488AD93808AF9FAF7D473C7CCE55DAA83B417FC6C09BFF7E332BD4B3BC59CBA4FE035A6C416D32BDCF8C3B9AFC5E1120CFD420023FD8EB207DB965509E2D362B0EB3D8CBD191D2750EBEB05F32C4BE08154D991F08DE4914BC40FAA7172440F2FEFB0FBF604DDA9C18BA9FD55F34218FD5D7CA2AC491CEDC3C5743D143BAF6C06CCAB7E5B22AB4E46CD51962CC7931F4D35581D5DD3047B946044BF7E71955EB63DD546644D7D2A19777DA39A48B4CF5A011A5C41F1BFF7C463F057F2F7AF6F910E7E06398B0AF7EF38CD5BBAE4C5FF42572CFFFCA6A8E9D34F64A7BECDC93216B55C20FAECAF04A8956C4D26DEE34493510BC49144A32A1B0AAE64B50DCA0C27361692242FE3145A6B36B830DEBF9E8A07A886E8DA6F38F3E99906F6AC9317ADF73222C4C75ABD153F1112E01E7CBB49665F213A1C1470CDC442D7CDC72EE2DD80D37251333C34FFDC5C38ADA3F5E52F5A5B2A1224B0CA60211B430E9554F0C4CA672476562C4A182B6707EBE80DFA6247A1F870F74EC81D03558F2718409EBF8E7F2FD2C6AB1F246F7E3FE0D919DB4016A7D76F6378D05EA74766CBB93340F2CBDDF18073F39242F3E9EC88020D1E8F801183C00F0239B2F2B4E8F6B46DBC17F469A857C291C985D8AC2099A6FEDC462B5EAEF737831EA2B6C9D787DC5AC8DA2C2E8F7F676FDA4CDD79E400EED959882C78C279C4D0A5918A0F5FC3B695E0034F7C2665D52D94106744D6B0CD6A66AB3275324EFDC06ECCF431D446446A00818ECDBE77B845699FB4F699825702D00F71373D80452039ECA1237AD2A0DF9112BA1EC90FB9FB87CF4E46BD0319B64F2EFD4B9640469707DB549468781D0BA6F3C49AF035D441173786BB1F2F5DCCE07BBF5536A0EB5B976814ABFDB44B90E55455972701A8F0D8EFB860A082ABA960E704754F61C2E3956922833F3D7E1656476DEE3C4F09244AC15697EA4A73041F03EEDE1F30BF899098A70F341B7BA49B +20241129130855 2 6 100 6143 2 DCBE8A152DD5DE612BFCCD18CAB2BDE17391AF9DA865DCC59A1B454144ADE2EB8BE3CDBA7948CD1236CFC25D66DDC0E91095FB7E17715247413BBFD5435223F46488AD93808AF9FAF7D473C7CCE55DAA83B417FC6C09BFF7E332BD4B3BC59CBA4FE035A6C416D32BDCF8C3B9AFC5E1120CFD420023FD8EB207DB965509E2D362B0EB3D8CBD191D2750EBEB05F32C4BE08154D991F08DE4914BC40FAA7172440F2FEFB0FBF604DDA9C18BA9FD55F34218FD5D7CA2AC491CEDC3C5743D143BAF6C06CCAB7E5B22AB4E46CD51962CC7931F4D35581D5DD3047B946044BF7E71955EB63DD546644D7D2A19777DA39A48B4CF5A011A5C41F1BFF7C463F057F2F7AF6F910E7E06398B0AF7EF38CD5BBAE4C5FF42572CFFFCA6A8E9D34F64A7BECDC93216B55C20FAECAF04A8956C4D26DEE34493510BC49144A32A1B0AAE64B50DCA0C27361692242FE3145A6B36B830DEBF9E8A07A886E8DA6F38F3E99906F6AC9317ADF73222C4C75ABD153F1112E01E7CBB49665F213A1C1470CDC442D7CDC72EE2DD80D37251333C34FFDC5C38ADA3F5E52F5A5B2A1224B0CA60211B430E9554F0C4CA672476562C4A182B6707EBE80DFA6247A1F870F74EC81D03558F2718409EBF8E7F2FD2C6AB1F246F7E3FE0D919DB4016A7D76F6378D05EA74766CBB93340F2CBDDF18073F39242F3E9EC88020D1E8F801183C00F0239B2F2B4E8F6B46DBC17F469A857C291C985D8AC2099A6FEDC462B5EAEF737831EA2B6C9D787DC5AC8DA2C2E8F7F676FDA4CDD79E400EED959882C78C279C4D0A5918A0F5FC3B695E0034F7C2665D52D94106744D6B0CD6A66AB3275324EFDC06ECCF431D446446A00818ECDBE77B845699FB4F699825702D00F71373D80452039ECA1237AD2A0DF9112BA1EC90FB9FB87CF4E46BD0319B64F2EFD4B9640469707DB549468781D0BA6F3C49AF035D441173786BB1F2F5DCCE07BBF5536A0EB5B976814ABFDB44B90E55455972701A8F0D8EFB860A082ABA960E704754F61C2E3956922833F3D7E1656476DEE3C4F09244AC15697EA4A73041F03EEDE1F30BF899098A70F341C2258EB +20241129130953 2 6 100 6143 5 DCBE8A152DD5DE612BFCCD18CAB2BDE17391AF9DA865DCC59A1B454144ADE2EB8BE3CDBA7948CD1236CFC25D66DDC0E91095FB7E17715247413BBFD5435223F46488AD93808AF9FAF7D473C7CCE55DAA83B417FC6C09BFF7E332BD4B3BC59CBA4FE035A6C416D32BDCF8C3B9AFC5E1120CFD420023FD8EB207DB965509E2D362B0EB3D8CBD191D2750EBEB05F32C4BE08154D991F08DE4914BC40FAA7172440F2FEFB0FBF604DDA9C18BA9FD55F34218FD5D7CA2AC491CEDC3C5743D143BAF6C06CCAB7E5B22AB4E46CD51962CC7931F4D35581D5DD3047B946044BF7E71955EB63DD546644D7D2A19777DA39A48B4CF5A011A5C41F1BFF7C463F057F2F7AF6F910E7E06398B0AF7EF38CD5BBAE4C5FF42572CFFFCA6A8E9D34F64A7BECDC93216B55C20FAECAF04A8956C4D26DEE34493510BC49144A32A1B0AAE64B50DCA0C27361692242FE3145A6B36B830DEBF9E8A07A886E8DA6F38F3E99906F6AC9317ADF73222C4C75ABD153F1112E01E7CBB49665F213A1C1470CDC442D7CDC72EE2DD80D37251333C34FFDC5C38ADA3F5E52F5A5B2A1224B0CA60211B430E9554F0C4CA672476562C4A182B6707EBE80DFA6247A1F870F74EC81D03558F2718409EBF8E7F2FD2C6AB1F246F7E3FE0D919DB4016A7D76F6378D05EA74766CBB93340F2CBDDF18073F39242F3E9EC88020D1E8F801183C00F0239B2F2B4E8F6B46DBC17F469A857C291C985D8AC2099A6FEDC462B5EAEF737831EA2B6C9D787DC5AC8DA2C2E8F7F676FDA4CDD79E400EED959882C78C279C4D0A5918A0F5FC3B695E0034F7C2665D52D94106744D6B0CD6A66AB3275324EFDC06ECCF431D446446A00818ECDBE77B845699FB4F699825702D00F71373D80452039ECA1237AD2A0DF9112BA1EC90FB9FB87CF4E46BD0319B64F2EFD4B9640469707DB549468781D0BA6F3C49AF035D441173786BB1F2F5DCCE07BBF5536A0EB5B976814ABFDB44B90E55455972701A8F0D8EFB860A082ABA960E704754F61C2E3956922833F3D7E1656476DEE3C4F09244AC15697EA4A73041F03EEDE1F30BF899098A70F341C3B9397 +20241129131555 2 6 100 6143 2 DCBE8A152DD5DE612BFCCD18CAB2BDE17391AF9DA865DCC59A1B454144ADE2EB8BE3CDBA7948CD1236CFC25D66DDC0E91095FB7E17715247413BBFD5435223F46488AD93808AF9FAF7D473C7CCE55DAA83B417FC6C09BFF7E332BD4B3BC59CBA4FE035A6C416D32BDCF8C3B9AFC5E1120CFD420023FD8EB207DB965509E2D362B0EB3D8CBD191D2750EBEB05F32C4BE08154D991F08DE4914BC40FAA7172440F2FEFB0FBF604DDA9C18BA9FD55F34218FD5D7CA2AC491CEDC3C5743D143BAF6C06CCAB7E5B22AB4E46CD51962CC7931F4D35581D5DD3047B946044BF7E71955EB63DD546644D7D2A19777DA39A48B4CF5A011A5C41F1BFF7C463F057F2F7AF6F910E7E06398B0AF7EF38CD5BBAE4C5FF42572CFFFCA6A8E9D34F64A7BECDC93216B55C20FAECAF04A8956C4D26DEE34493510BC49144A32A1B0AAE64B50DCA0C27361692242FE3145A6B36B830DEBF9E8A07A886E8DA6F38F3E99906F6AC9317ADF73222C4C75ABD153F1112E01E7CBB49665F213A1C1470CDC442D7CDC72EE2DD80D37251333C34FFDC5C38ADA3F5E52F5A5B2A1224B0CA60211B430E9554F0C4CA672476562C4A182B6707EBE80DFA6247A1F870F74EC81D03558F2718409EBF8E7F2FD2C6AB1F246F7E3FE0D919DB4016A7D76F6378D05EA74766CBB93340F2CBDDF18073F39242F3E9EC88020D1E8F801183C00F0239B2F2B4E8F6B46DBC17F469A857C291C985D8AC2099A6FEDC462B5EAEF737831EA2B6C9D787DC5AC8DA2C2E8F7F676FDA4CDD79E400EED959882C78C279C4D0A5918A0F5FC3B695E0034F7C2665D52D94106744D6B0CD6A66AB3275324EFDC06ECCF431D446446A00818ECDBE77B845699FB4F699825702D00F71373D80452039ECA1237AD2A0DF9112BA1EC90FB9FB87CF4E46BD0319B64F2EFD4B9640469707DB549468781D0BA6F3C49AF035D441173786BB1F2F5DCCE07BBF5536A0EB5B976814ABFDB44B90E55455972701A8F0D8EFB860A082ABA960E704754F61C2E3956922833F3D7E1656476DEE3C4F09244AC15697EA4A73041F03EEDE1F30BF899098A70F341CF54C93 +20241129131844 2 6 100 6143 5 DCBE8A152DD5DE612BFCCD18CAB2BDE17391AF9DA865DCC59A1B454144ADE2EB8BE3CDBA7948CD1236CFC25D66DDC0E91095FB7E17715247413BBFD5435223F46488AD93808AF9FAF7D473C7CCE55DAA83B417FC6C09BFF7E332BD4B3BC59CBA4FE035A6C416D32BDCF8C3B9AFC5E1120CFD420023FD8EB207DB965509E2D362B0EB3D8CBD191D2750EBEB05F32C4BE08154D991F08DE4914BC40FAA7172440F2FEFB0FBF604DDA9C18BA9FD55F34218FD5D7CA2AC491CEDC3C5743D143BAF6C06CCAB7E5B22AB4E46CD51962CC7931F4D35581D5DD3047B946044BF7E71955EB63DD546644D7D2A19777DA39A48B4CF5A011A5C41F1BFF7C463F057F2F7AF6F910E7E06398B0AF7EF38CD5BBAE4C5FF42572CFFFCA6A8E9D34F64A7BECDC93216B55C20FAECAF04A8956C4D26DEE34493510BC49144A32A1B0AAE64B50DCA0C27361692242FE3145A6B36B830DEBF9E8A07A886E8DA6F38F3E99906F6AC9317ADF73222C4C75ABD153F1112E01E7CBB49665F213A1C1470CDC442D7CDC72EE2DD80D37251333C34FFDC5C38ADA3F5E52F5A5B2A1224B0CA60211B430E9554F0C4CA672476562C4A182B6707EBE80DFA6247A1F870F74EC81D03558F2718409EBF8E7F2FD2C6AB1F246F7E3FE0D919DB4016A7D76F6378D05EA74766CBB93340F2CBDDF18073F39242F3E9EC88020D1E8F801183C00F0239B2F2B4E8F6B46DBC17F469A857C291C985D8AC2099A6FEDC462B5EAEF737831EA2B6C9D787DC5AC8DA2C2E8F7F676FDA4CDD79E400EED959882C78C279C4D0A5918A0F5FC3B695E0034F7C2665D52D94106744D6B0CD6A66AB3275324EFDC06ECCF431D446446A00818ECDBE77B845699FB4F699825702D00F71373D80452039ECA1237AD2A0DF9112BA1EC90FB9FB87CF4E46BD0319B64F2EFD4B9640469707DB549468781D0BA6F3C49AF035D441173786BB1F2F5DCCE07BBF5536A0EB5B976814ABFDB44B90E55455972701A8F0D8EFB860A082ABA960E704754F61C2E3956922833F3D7E1656476DEE3C4F09244AC15697EA4A73041F03EEDE1F30BF899098A70F341D474B9F +20241129132228 2 6 100 6143 5 DCBE8A152DD5DE612BFCCD18CAB2BDE17391AF9DA865DCC59A1B454144ADE2EB8BE3CDBA7948CD1236CFC25D66DDC0E91095FB7E17715247413BBFD5435223F46488AD93808AF9FAF7D473C7CCE55DAA83B417FC6C09BFF7E332BD4B3BC59CBA4FE035A6C416D32BDCF8C3B9AFC5E1120CFD420023FD8EB207DB965509E2D362B0EB3D8CBD191D2750EBEB05F32C4BE08154D991F08DE4914BC40FAA7172440F2FEFB0FBF604DDA9C18BA9FD55F34218FD5D7CA2AC491CEDC3C5743D143BAF6C06CCAB7E5B22AB4E46CD51962CC7931F4D35581D5DD3047B946044BF7E71955EB63DD546644D7D2A19777DA39A48B4CF5A011A5C41F1BFF7C463F057F2F7AF6F910E7E06398B0AF7EF38CD5BBAE4C5FF42572CFFFCA6A8E9D34F64A7BECDC93216B55C20FAECAF04A8956C4D26DEE34493510BC49144A32A1B0AAE64B50DCA0C27361692242FE3145A6B36B830DEBF9E8A07A886E8DA6F38F3E99906F6AC9317ADF73222C4C75ABD153F1112E01E7CBB49665F213A1C1470CDC442D7CDC72EE2DD80D37251333C34FFDC5C38ADA3F5E52F5A5B2A1224B0CA60211B430E9554F0C4CA672476562C4A182B6707EBE80DFA6247A1F870F74EC81D03558F2718409EBF8E7F2FD2C6AB1F246F7E3FE0D919DB4016A7D76F6378D05EA74766CBB93340F2CBDDF18073F39242F3E9EC88020D1E8F801183C00F0239B2F2B4E8F6B46DBC17F469A857C291C985D8AC2099A6FEDC462B5EAEF737831EA2B6C9D787DC5AC8DA2C2E8F7F676FDA4CDD79E400EED959882C78C279C4D0A5918A0F5FC3B695E0034F7C2665D52D94106744D6B0CD6A66AB3275324EFDC06ECCF431D446446A00818ECDBE77B845699FB4F699825702D00F71373D80452039ECA1237AD2A0DF9112BA1EC90FB9FB87CF4E46BD0319B64F2EFD4B9640469707DB549468781D0BA6F3C49AF035D441173786BB1F2F5DCCE07BBF5536A0EB5B976814ABFDB44B90E55455972701A8F0D8EFB860A082ABA960E704754F61C2E3956922833F3D7E1656476DEE3C4F09244AC15697EA4A73041F03EEDE1F30BF899098A70F341DB5BA4F +20241129134604 2 6 100 6143 2 DCBE8A152DD5DE612BFCCD18CAB2BDE17391AF9DA865DCC59A1B454144ADE2EB8BE3CDBA7948CD1236CFC25D66DDC0E91095FB7E17715247413BBFD5435223F46488AD93808AF9FAF7D473C7CCE55DAA83B417FC6C09BFF7E332BD4B3BC59CBA4FE035A6C416D32BDCF8C3B9AFC5E1120CFD420023FD8EB207DB965509E2D362B0EB3D8CBD191D2750EBEB05F32C4BE08154D991F08DE4914BC40FAA7172440F2FEFB0FBF604DDA9C18BA9FD55F34218FD5D7CA2AC491CEDC3C5743D143BAF6C06CCAB7E5B22AB4E46CD51962CC7931F4D35581D5DD3047B946044BF7E71955EB63DD546644D7D2A19777DA39A48B4CF5A011A5C41F1BFF7C463F057F2F7AF6F910E7E06398B0AF7EF38CD5BBAE4C5FF42572CFFFCA6A8E9D34F64A7BECDC93216B55C20FAECAF04A8956C4D26DEE34493510BC49144A32A1B0AAE64B50DCA0C27361692242FE3145A6B36B830DEBF9E8A07A886E8DA6F38F3E99906F6AC9317ADF73222C4C75ABD153F1112E01E7CBB49665F213A1C1470CDC442D7CDC72EE2DD80D37251333C34FFDC5C38ADA3F5E52F5A5B2A1224B0CA60211B430E9554F0C4CA672476562C4A182B6707EBE80DFA6247A1F870F74EC81D03558F2718409EBF8E7F2FD2C6AB1F246F7E3FE0D919DB4016A7D76F6378D05EA74766CBB93340F2CBDDF18073F39242F3E9EC88020D1E8F801183C00F0239B2F2B4E8F6B46DBC17F469A857C291C985D8AC2099A6FEDC462B5EAEF737831EA2B6C9D787DC5AC8DA2C2E8F7F676FDA4CDD79E400EED959882C78C279C4D0A5918A0F5FC3B695E0034F7C2665D52D94106744D6B0CD6A66AB3275324EFDC06ECCF431D446446A00818ECDBE77B845699FB4F699825702D00F71373D80452039ECA1237AD2A0DF9112BA1EC90FB9FB87CF4E46BD0319B64F2EFD4B9640469707DB549468781D0BA6F3C49AF035D441173786BB1F2F5DCCE07BBF5536A0EB5B976814ABFDB44B90E55455972701A8F0D8EFB860A082ABA960E704754F61C2E3956922833F3D7E1656476DEE3C4F09244AC15697EA4A73041F03EEDE1F30BF899098A70F3420A2EA6B +20241129135907 2 6 100 6143 5 DCBE8A152DD5DE612BFCCD18CAB2BDE17391AF9DA865DCC59A1B454144ADE2EB8BE3CDBA7948CD1236CFC25D66DDC0E91095FB7E17715247413BBFD5435223F46488AD93808AF9FAF7D473C7CCE55DAA83B417FC6C09BFF7E332BD4B3BC59CBA4FE035A6C416D32BDCF8C3B9AFC5E1120CFD420023FD8EB207DB965509E2D362B0EB3D8CBD191D2750EBEB05F32C4BE08154D991F08DE4914BC40FAA7172440F2FEFB0FBF604DDA9C18BA9FD55F34218FD5D7CA2AC491CEDC3C5743D143BAF6C06CCAB7E5B22AB4E46CD51962CC7931F4D35581D5DD3047B946044BF7E71955EB63DD546644D7D2A19777DA39A48B4CF5A011A5C41F1BFF7C463F057F2F7AF6F910E7E06398B0AF7EF38CD5BBAE4C5FF42572CFFFCA6A8E9D34F64A7BECDC93216B55C20FAECAF04A8956C4D26DEE34493510BC49144A32A1B0AAE64B50DCA0C27361692242FE3145A6B36B830DEBF9E8A07A886E8DA6F38F3E99906F6AC9317ADF73222C4C75ABD153F1112E01E7CBB49665F213A1C1470CDC442D7CDC72EE2DD80D37251333C34FFDC5C38ADA3F5E52F5A5B2A1224B0CA60211B430E9554F0C4CA672476562C4A182B6707EBE80DFA6247A1F870F74EC81D03558F2718409EBF8E7F2FD2C6AB1F246F7E3FE0D919DB4016A7D76F6378D05EA74766CBB93340F2CBDDF18073F39242F3E9EC88020D1E8F801183C00F0239B2F2B4E8F6B46DBC17F469A857C291C985D8AC2099A6FEDC462B5EAEF737831EA2B6C9D787DC5AC8DA2C2E8F7F676FDA4CDD79E400EED959882C78C279C4D0A5918A0F5FC3B695E0034F7C2665D52D94106744D6B0CD6A66AB3275324EFDC06ECCF431D446446A00818ECDBE77B845699FB4F699825702D00F71373D80452039ECA1237AD2A0DF9112BA1EC90FB9FB87CF4E46BD0319B64F2EFD4B9640469707DB549468781D0BA6F3C49AF035D441173786BB1F2F5DCCE07BBF5536A0EB5B976814ABFDB44B90E55455972701A8F0D8EFB860A082ABA960E704754F61C2E3956922833F3D7E1656476DEE3C4F09244AC15697EA4A73041F03EEDE1F30BF899098A70F34223A233F +20241129143314 2 6 100 6143 2 D530FFAD12BC56C29F02BEFEC6CFD700AE6DA852D7256FC0A8978C13FABF9851425A26917CD40A9919A06A5B17FA05456642891442CCBBBD9BB5B74068213AA6F029B3419F6B2CCB828CF9F6F0069F43A2496921ED8133BF2D9C598486282EB38B3B6E849B7D80B33869CDE1D71379C694BB9C229B5CCE5E96692F81DA73EC38942CE60A81657F34A6B1B536ADEADD76144A209815A88E081E0B96438B11A34E4F8082ACC6DD77D787EEA90E1764F7393D3869707FCFCD4BFEEA3582BBD39C17E2CE70B6A193700A055A50D2F5ED473DD9B4401C2138BAD8FA3331BDD4FF79E230C10B13FFE7CCDB3210F8DB42147BB8349CAEA97EBCBC708B9CE16360D573D3327BBCAA6387234E9A4DCB2E67784408ADB72B2E05643520211C581EBB38E57C2F69C9034143DBAB4C13221D501B892918779C6E9AC5B39F2F412E31EF7F7F0610C2AFE150FA56A5E3CF9DACA6C96F3BC6B57D56B2869019C5114247C080752E4D42B1A0E34302B69B8516E8FB93BE58CC45F6E5ADB47A89A00050A12D560BEEA8997F5A0FA526C107BA34ECB0C678079C6DD4C1F4666BBD45733E019C292A17661B79E6AEED002EF4F6E7F4D569690E140C8BA1BA47E626499E01DA1EACDA4B917507A472DDB03A86734994C4B16551C5DFED3C8C976D15B5BF68CC6C982355930E37F096629E6F3BDC8027C722C12EF76854F1C607341E48FBF8C9064EB48EFDA87E1D111B557FBE7A15A580EDD87AC2CEC0EB25BE057FC20D578DF34632977F4698D58B2025C50AD4AD77D16D32E6157F89F58C692A83279A2EB58F8E448A13AA32B8C3DF07A58100EC4BB319F824446ECDD643C4A7F959CBA4E356A9E5DB7332107B2EB478703BF44383DDF80CA297F5E52A4424AF64B50CAB4E9C95C7288B96F8E77CDC63D07C6394853DF32F926652A12122B5531F90CFDFDAAC5D0642F84CF3901717B652122E8622CF31C06D134AD921EC80D175BBFC45B855EB9ABF001686BC52730F754DBFAE781BB629F1E530632D813AA256D0063202AEEE0AB64C7829C1A6C4702E27C88219FF31500D8F76BEFE4AEF726D6E3B708C7A9949CB +20241129150941 2 6 100 6143 2 D530FFAD12BC56C29F02BEFEC6CFD700AE6DA852D7256FC0A8978C13FABF9851425A26917CD40A9919A06A5B17FA05456642891442CCBBBD9BB5B74068213AA6F029B3419F6B2CCB828CF9F6F0069F43A2496921ED8133BF2D9C598486282EB38B3B6E849B7D80B33869CDE1D71379C694BB9C229B5CCE5E96692F81DA73EC38942CE60A81657F34A6B1B536ADEADD76144A209815A88E081E0B96438B11A34E4F8082ACC6DD77D787EEA90E1764F7393D3869707FCFCD4BFEEA3582BBD39C17E2CE70B6A193700A055A50D2F5ED473DD9B4401C2138BAD8FA3331BDD4FF79E230C10B13FFE7CCDB3210F8DB42147BB8349CAEA97EBCBC708B9CE16360D573D3327BBCAA6387234E9A4DCB2E67784408ADB72B2E05643520211C581EBB38E57C2F69C9034143DBAB4C13221D501B892918779C6E9AC5B39F2F412E31EF7F7F0610C2AFE150FA56A5E3CF9DACA6C96F3BC6B57D56B2869019C5114247C080752E4D42B1A0E34302B69B8516E8FB93BE58CC45F6E5ADB47A89A00050A12D560BEEA8997F5A0FA526C107BA34ECB0C678079C6DD4C1F4666BBD45733E019C292A17661B79E6AEED002EF4F6E7F4D569690E140C8BA1BA47E626499E01DA1EACDA4B917507A472DDB03A86734994C4B16551C5DFED3C8C976D15B5BF68CC6C982355930E37F096629E6F3BDC8027C722C12EF76854F1C607341E48FBF8C9064EB48EFDA87E1D111B557FBE7A15A580EDD87AC2CEC0EB25BE057FC20D578DF34632977F4698D58B2025C50AD4AD77D16D32E6157F89F58C692A83279A2EB58F8E448A13AA32B8C3DF07A58100EC4BB319F824446ECDD643C4A7F959CBA4E356A9E5DB7332107B2EB478703BF44383DDF80CA297F5E52A4424AF64B50CAB4E9C95C7288B96F8E77CDC63D07C6394853DF32F926652A12122B5531F90CFDFDAAC5D0642F84CF3901717B652122E8622CF31C06D134AD921EC80D175BBFC45B855EB9ABF001686BC52730F754DBFAE781BB629F1E530632D813AA256D0063202AEEE0AB64C7829C1A6C4702E27C88219FF31500D8F76BEFE4AEF726D6E3B708C7F2EAC9B +20241129152304 2 6 100 6143 2 D530FFAD12BC56C29F02BEFEC6CFD700AE6DA852D7256FC0A8978C13FABF9851425A26917CD40A9919A06A5B17FA05456642891442CCBBBD9BB5B74068213AA6F029B3419F6B2CCB828CF9F6F0069F43A2496921ED8133BF2D9C598486282EB38B3B6E849B7D80B33869CDE1D71379C694BB9C229B5CCE5E96692F81DA73EC38942CE60A81657F34A6B1B536ADEADD76144A209815A88E081E0B96438B11A34E4F8082ACC6DD77D787EEA90E1764F7393D3869707FCFCD4BFEEA3582BBD39C17E2CE70B6A193700A055A50D2F5ED473DD9B4401C2138BAD8FA3331BDD4FF79E230C10B13FFE7CCDB3210F8DB42147BB8349CAEA97EBCBC708B9CE16360D573D3327BBCAA6387234E9A4DCB2E67784408ADB72B2E05643520211C581EBB38E57C2F69C9034143DBAB4C13221D501B892918779C6E9AC5B39F2F412E31EF7F7F0610C2AFE150FA56A5E3CF9DACA6C96F3BC6B57D56B2869019C5114247C080752E4D42B1A0E34302B69B8516E8FB93BE58CC45F6E5ADB47A89A00050A12D560BEEA8997F5A0FA526C107BA34ECB0C678079C6DD4C1F4666BBD45733E019C292A17661B79E6AEED002EF4F6E7F4D569690E140C8BA1BA47E626499E01DA1EACDA4B917507A472DDB03A86734994C4B16551C5DFED3C8C976D15B5BF68CC6C982355930E37F096629E6F3BDC8027C722C12EF76854F1C607341E48FBF8C9064EB48EFDA87E1D111B557FBE7A15A580EDD87AC2CEC0EB25BE057FC20D578DF34632977F4698D58B2025C50AD4AD77D16D32E6157F89F58C692A83279A2EB58F8E448A13AA32B8C3DF07A58100EC4BB319F824446ECDD643C4A7F959CBA4E356A9E5DB7332107B2EB478703BF44383DDF80CA297F5E52A4424AF64B50CAB4E9C95C7288B96F8E77CDC63D07C6394853DF32F926652A12122B5531F90CFDFDAAC5D0642F84CF3901717B652122E8622CF31C06D134AD921EC80D175BBFC45B855EB9ABF001686BC52730F754DBFAE781BB629F1E530632D813AA256D0063202AEEE0AB64C7829C1A6C4702E27C88219FF31500D8F76BEFE4AEF726D6E3B708C80D59DCB +20241129153351 2 6 100 6143 5 D530FFAD12BC56C29F02BEFEC6CFD700AE6DA852D7256FC0A8978C13FABF9851425A26917CD40A9919A06A5B17FA05456642891442CCBBBD9BB5B74068213AA6F029B3419F6B2CCB828CF9F6F0069F43A2496921ED8133BF2D9C598486282EB38B3B6E849B7D80B33869CDE1D71379C694BB9C229B5CCE5E96692F81DA73EC38942CE60A81657F34A6B1B536ADEADD76144A209815A88E081E0B96438B11A34E4F8082ACC6DD77D787EEA90E1764F7393D3869707FCFCD4BFEEA3582BBD39C17E2CE70B6A193700A055A50D2F5ED473DD9B4401C2138BAD8FA3331BDD4FF79E230C10B13FFE7CCDB3210F8DB42147BB8349CAEA97EBCBC708B9CE16360D573D3327BBCAA6387234E9A4DCB2E67784408ADB72B2E05643520211C581EBB38E57C2F69C9034143DBAB4C13221D501B892918779C6E9AC5B39F2F412E31EF7F7F0610C2AFE150FA56A5E3CF9DACA6C96F3BC6B57D56B2869019C5114247C080752E4D42B1A0E34302B69B8516E8FB93BE58CC45F6E5ADB47A89A00050A12D560BEEA8997F5A0FA526C107BA34ECB0C678079C6DD4C1F4666BBD45733E019C292A17661B79E6AEED002EF4F6E7F4D569690E140C8BA1BA47E626499E01DA1EACDA4B917507A472DDB03A86734994C4B16551C5DFED3C8C976D15B5BF68CC6C982355930E37F096629E6F3BDC8027C722C12EF76854F1C607341E48FBF8C9064EB48EFDA87E1D111B557FBE7A15A580EDD87AC2CEC0EB25BE057FC20D578DF34632977F4698D58B2025C50AD4AD77D16D32E6157F89F58C692A83279A2EB58F8E448A13AA32B8C3DF07A58100EC4BB319F824446ECDD643C4A7F959CBA4E356A9E5DB7332107B2EB478703BF44383DDF80CA297F5E52A4424AF64B50CAB4E9C95C7288B96F8E77CDC63D07C6394853DF32F926652A12122B5531F90CFDFDAAC5D0642F84CF3901717B652122E8622CF31C06D134AD921EC80D175BBFC45B855EB9ABF001686BC52730F754DBFAE781BB629F1E530632D813AA256D0063202AEEE0AB64C7829C1A6C4702E27C88219FF31500D8F76BEFE4AEF726D6E3B708C82259357 +20241129153442 2 6 100 6143 5 D530FFAD12BC56C29F02BEFEC6CFD700AE6DA852D7256FC0A8978C13FABF9851425A26917CD40A9919A06A5B17FA05456642891442CCBBBD9BB5B74068213AA6F029B3419F6B2CCB828CF9F6F0069F43A2496921ED8133BF2D9C598486282EB38B3B6E849B7D80B33869CDE1D71379C694BB9C229B5CCE5E96692F81DA73EC38942CE60A81657F34A6B1B536ADEADD76144A209815A88E081E0B96438B11A34E4F8082ACC6DD77D787EEA90E1764F7393D3869707FCFCD4BFEEA3582BBD39C17E2CE70B6A193700A055A50D2F5ED473DD9B4401C2138BAD8FA3331BDD4FF79E230C10B13FFE7CCDB3210F8DB42147BB8349CAEA97EBCBC708B9CE16360D573D3327BBCAA6387234E9A4DCB2E67784408ADB72B2E05643520211C581EBB38E57C2F69C9034143DBAB4C13221D501B892918779C6E9AC5B39F2F412E31EF7F7F0610C2AFE150FA56A5E3CF9DACA6C96F3BC6B57D56B2869019C5114247C080752E4D42B1A0E34302B69B8516E8FB93BE58CC45F6E5ADB47A89A00050A12D560BEEA8997F5A0FA526C107BA34ECB0C678079C6DD4C1F4666BBD45733E019C292A17661B79E6AEED002EF4F6E7F4D569690E140C8BA1BA47E626499E01DA1EACDA4B917507A472DDB03A86734994C4B16551C5DFED3C8C976D15B5BF68CC6C982355930E37F096629E6F3BDC8027C722C12EF76854F1C607341E48FBF8C9064EB48EFDA87E1D111B557FBE7A15A580EDD87AC2CEC0EB25BE057FC20D578DF34632977F4698D58B2025C50AD4AD77D16D32E6157F89F58C692A83279A2EB58F8E448A13AA32B8C3DF07A58100EC4BB319F824446ECDD643C4A7F959CBA4E356A9E5DB7332107B2EB478703BF44383DDF80CA297F5E52A4424AF64B50CAB4E9C95C7288B96F8E77CDC63D07C6394853DF32F926652A12122B5531F90CFDFDAAC5D0642F84CF3901717B652122E8622CF31C06D134AD921EC80D175BBFC45B855EB9ABF001686BC52730F754DBFAE781BB629F1E530632D813AA256D0063202AEEE0AB64C7829C1A6C4702E27C88219FF31500D8F76BEFE4AEF726D6E3B708C8239CBD7 +20241129154346 2 6 100 6143 2 D530FFAD12BC56C29F02BEFEC6CFD700AE6DA852D7256FC0A8978C13FABF9851425A26917CD40A9919A06A5B17FA05456642891442CCBBBD9BB5B74068213AA6F029B3419F6B2CCB828CF9F6F0069F43A2496921ED8133BF2D9C598486282EB38B3B6E849B7D80B33869CDE1D71379C694BB9C229B5CCE5E96692F81DA73EC38942CE60A81657F34A6B1B536ADEADD76144A209815A88E081E0B96438B11A34E4F8082ACC6DD77D787EEA90E1764F7393D3869707FCFCD4BFEEA3582BBD39C17E2CE70B6A193700A055A50D2F5ED473DD9B4401C2138BAD8FA3331BDD4FF79E230C10B13FFE7CCDB3210F8DB42147BB8349CAEA97EBCBC708B9CE16360D573D3327BBCAA6387234E9A4DCB2E67784408ADB72B2E05643520211C581EBB38E57C2F69C9034143DBAB4C13221D501B892918779C6E9AC5B39F2F412E31EF7F7F0610C2AFE150FA56A5E3CF9DACA6C96F3BC6B57D56B2869019C5114247C080752E4D42B1A0E34302B69B8516E8FB93BE58CC45F6E5ADB47A89A00050A12D560BEEA8997F5A0FA526C107BA34ECB0C678079C6DD4C1F4666BBD45733E019C292A17661B79E6AEED002EF4F6E7F4D569690E140C8BA1BA47E626499E01DA1EACDA4B917507A472DDB03A86734994C4B16551C5DFED3C8C976D15B5BF68CC6C982355930E37F096629E6F3BDC8027C722C12EF76854F1C607341E48FBF8C9064EB48EFDA87E1D111B557FBE7A15A580EDD87AC2CEC0EB25BE057FC20D578DF34632977F4698D58B2025C50AD4AD77D16D32E6157F89F58C692A83279A2EB58F8E448A13AA32B8C3DF07A58100EC4BB319F824446ECDD643C4A7F959CBA4E356A9E5DB7332107B2EB478703BF44383DDF80CA297F5E52A4424AF64B50CAB4E9C95C7288B96F8E77CDC63D07C6394853DF32F926652A12122B5531F90CFDFDAAC5D0642F84CF3901717B652122E8622CF31C06D134AD921EC80D175BBFC45B855EB9ABF001686BC52730F754DBFAE781BB629F1E530632D813AA256D0063202AEEE0AB64C7829C1A6C4702E27C88219FF31500D8F76BEFE4AEF726D6E3B708C835408BB +20241129154536 2 6 100 6143 5 D530FFAD12BC56C29F02BEFEC6CFD700AE6DA852D7256FC0A8978C13FABF9851425A26917CD40A9919A06A5B17FA05456642891442CCBBBD9BB5B74068213AA6F029B3419F6B2CCB828CF9F6F0069F43A2496921ED8133BF2D9C598486282EB38B3B6E849B7D80B33869CDE1D71379C694BB9C229B5CCE5E96692F81DA73EC38942CE60A81657F34A6B1B536ADEADD76144A209815A88E081E0B96438B11A34E4F8082ACC6DD77D787EEA90E1764F7393D3869707FCFCD4BFEEA3582BBD39C17E2CE70B6A193700A055A50D2F5ED473DD9B4401C2138BAD8FA3331BDD4FF79E230C10B13FFE7CCDB3210F8DB42147BB8349CAEA97EBCBC708B9CE16360D573D3327BBCAA6387234E9A4DCB2E67784408ADB72B2E05643520211C581EBB38E57C2F69C9034143DBAB4C13221D501B892918779C6E9AC5B39F2F412E31EF7F7F0610C2AFE150FA56A5E3CF9DACA6C96F3BC6B57D56B2869019C5114247C080752E4D42B1A0E34302B69B8516E8FB93BE58CC45F6E5ADB47A89A00050A12D560BEEA8997F5A0FA526C107BA34ECB0C678079C6DD4C1F4666BBD45733E019C292A17661B79E6AEED002EF4F6E7F4D569690E140C8BA1BA47E626499E01DA1EACDA4B917507A472DDB03A86734994C4B16551C5DFED3C8C976D15B5BF68CC6C982355930E37F096629E6F3BDC8027C722C12EF76854F1C607341E48FBF8C9064EB48EFDA87E1D111B557FBE7A15A580EDD87AC2CEC0EB25BE057FC20D578DF34632977F4698D58B2025C50AD4AD77D16D32E6157F89F58C692A83279A2EB58F8E448A13AA32B8C3DF07A58100EC4BB319F824446ECDD643C4A7F959CBA4E356A9E5DB7332107B2EB478703BF44383DDF80CA297F5E52A4424AF64B50CAB4E9C95C7288B96F8E77CDC63D07C6394853DF32F926652A12122B5531F90CFDFDAAC5D0642F84CF3901717B652122E8622CF31C06D134AD921EC80D175BBFC45B855EB9ABF001686BC52730F754DBFAE781BB629F1E530632D813AA256D0063202AEEE0AB64C7829C1A6C4702E27C88219FF31500D8F76BEFE4AEF726D6E3B708C8387126F +20241129161648 2 6 100 6143 5 D530FFAD12BC56C29F02BEFEC6CFD700AE6DA852D7256FC0A8978C13FABF9851425A26917CD40A9919A06A5B17FA05456642891442CCBBBD9BB5B74068213AA6F029B3419F6B2CCB828CF9F6F0069F43A2496921ED8133BF2D9C598486282EB38B3B6E849B7D80B33869CDE1D71379C694BB9C229B5CCE5E96692F81DA73EC38942CE60A81657F34A6B1B536ADEADD76144A209815A88E081E0B96438B11A34E4F8082ACC6DD77D787EEA90E1764F7393D3869707FCFCD4BFEEA3582BBD39C17E2CE70B6A193700A055A50D2F5ED473DD9B4401C2138BAD8FA3331BDD4FF79E230C10B13FFE7CCDB3210F8DB42147BB8349CAEA97EBCBC708B9CE16360D573D3327BBCAA6387234E9A4DCB2E67784408ADB72B2E05643520211C581EBB38E57C2F69C9034143DBAB4C13221D501B892918779C6E9AC5B39F2F412E31EF7F7F0610C2AFE150FA56A5E3CF9DACA6C96F3BC6B57D56B2869019C5114247C080752E4D42B1A0E34302B69B8516E8FB93BE58CC45F6E5ADB47A89A00050A12D560BEEA8997F5A0FA526C107BA34ECB0C678079C6DD4C1F4666BBD45733E019C292A17661B79E6AEED002EF4F6E7F4D569690E140C8BA1BA47E626499E01DA1EACDA4B917507A472DDB03A86734994C4B16551C5DFED3C8C976D15B5BF68CC6C982355930E37F096629E6F3BDC8027C722C12EF76854F1C607341E48FBF8C9064EB48EFDA87E1D111B557FBE7A15A580EDD87AC2CEC0EB25BE057FC20D578DF34632977F4698D58B2025C50AD4AD77D16D32E6157F89F58C692A83279A2EB58F8E448A13AA32B8C3DF07A58100EC4BB319F824446ECDD643C4A7F959CBA4E356A9E5DB7332107B2EB478703BF44383DDF80CA297F5E52A4424AF64B50CAB4E9C95C7288B96F8E77CDC63D07C6394853DF32F926652A12122B5531F90CFDFDAAC5D0642F84CF3901717B652122E8622CF31C06D134AD921EC80D175BBFC45B855EB9ABF001686BC52730F754DBFAE781BB629F1E530632D813AA256D0063202AEEE0AB64C7829C1A6C4702E27C88219FF31500D8F76BEFE4AEF726D6E3B708C87770FCF +20241129162459 2 6 100 6143 5 D530FFAD12BC56C29F02BEFEC6CFD700AE6DA852D7256FC0A8978C13FABF9851425A26917CD40A9919A06A5B17FA05456642891442CCBBBD9BB5B74068213AA6F029B3419F6B2CCB828CF9F6F0069F43A2496921ED8133BF2D9C598486282EB38B3B6E849B7D80B33869CDE1D71379C694BB9C229B5CCE5E96692F81DA73EC38942CE60A81657F34A6B1B536ADEADD76144A209815A88E081E0B96438B11A34E4F8082ACC6DD77D787EEA90E1764F7393D3869707FCFCD4BFEEA3582BBD39C17E2CE70B6A193700A055A50D2F5ED473DD9B4401C2138BAD8FA3331BDD4FF79E230C10B13FFE7CCDB3210F8DB42147BB8349CAEA97EBCBC708B9CE16360D573D3327BBCAA6387234E9A4DCB2E67784408ADB72B2E05643520211C581EBB38E57C2F69C9034143DBAB4C13221D501B892918779C6E9AC5B39F2F412E31EF7F7F0610C2AFE150FA56A5E3CF9DACA6C96F3BC6B57D56B2869019C5114247C080752E4D42B1A0E34302B69B8516E8FB93BE58CC45F6E5ADB47A89A00050A12D560BEEA8997F5A0FA526C107BA34ECB0C678079C6DD4C1F4666BBD45733E019C292A17661B79E6AEED002EF4F6E7F4D569690E140C8BA1BA47E626499E01DA1EACDA4B917507A472DDB03A86734994C4B16551C5DFED3C8C976D15B5BF68CC6C982355930E37F096629E6F3BDC8027C722C12EF76854F1C607341E48FBF8C9064EB48EFDA87E1D111B557FBE7A15A580EDD87AC2CEC0EB25BE057FC20D578DF34632977F4698D58B2025C50AD4AD77D16D32E6157F89F58C692A83279A2EB58F8E448A13AA32B8C3DF07A58100EC4BB319F824446ECDD643C4A7F959CBA4E356A9E5DB7332107B2EB478703BF44383DDF80CA297F5E52A4424AF64B50CAB4E9C95C7288B96F8E77CDC63D07C6394853DF32F926652A12122B5531F90CFDFDAAC5D0642F84CF3901717B652122E8622CF31C06D134AD921EC80D175BBFC45B855EB9ABF001686BC52730F754DBFAE781BB629F1E530632D813AA256D0063202AEEE0AB64C7829C1A6C4702E27C88219FF31500D8F76BEFE4AEF726D6E3B708C887B826F +20241129162918 2 6 100 6143 2 D530FFAD12BC56C29F02BEFEC6CFD700AE6DA852D7256FC0A8978C13FABF9851425A26917CD40A9919A06A5B17FA05456642891442CCBBBD9BB5B74068213AA6F029B3419F6B2CCB828CF9F6F0069F43A2496921ED8133BF2D9C598486282EB38B3B6E849B7D80B33869CDE1D71379C694BB9C229B5CCE5E96692F81DA73EC38942CE60A81657F34A6B1B536ADEADD76144A209815A88E081E0B96438B11A34E4F8082ACC6DD77D787EEA90E1764F7393D3869707FCFCD4BFEEA3582BBD39C17E2CE70B6A193700A055A50D2F5ED473DD9B4401C2138BAD8FA3331BDD4FF79E230C10B13FFE7CCDB3210F8DB42147BB8349CAEA97EBCBC708B9CE16360D573D3327BBCAA6387234E9A4DCB2E67784408ADB72B2E05643520211C581EBB38E57C2F69C9034143DBAB4C13221D501B892918779C6E9AC5B39F2F412E31EF7F7F0610C2AFE150FA56A5E3CF9DACA6C96F3BC6B57D56B2869019C5114247C080752E4D42B1A0E34302B69B8516E8FB93BE58CC45F6E5ADB47A89A00050A12D560BEEA8997F5A0FA526C107BA34ECB0C678079C6DD4C1F4666BBD45733E019C292A17661B79E6AEED002EF4F6E7F4D569690E140C8BA1BA47E626499E01DA1EACDA4B917507A472DDB03A86734994C4B16551C5DFED3C8C976D15B5BF68CC6C982355930E37F096629E6F3BDC8027C722C12EF76854F1C607341E48FBF8C9064EB48EFDA87E1D111B557FBE7A15A580EDD87AC2CEC0EB25BE057FC20D578DF34632977F4698D58B2025C50AD4AD77D16D32E6157F89F58C692A83279A2EB58F8E448A13AA32B8C3DF07A58100EC4BB319F824446ECDD643C4A7F959CBA4E356A9E5DB7332107B2EB478703BF44383DDF80CA297F5E52A4424AF64B50CAB4E9C95C7288B96F8E77CDC63D07C6394853DF32F926652A12122B5531F90CFDFDAAC5D0642F84CF3901717B652122E8622CF31C06D134AD921EC80D175BBFC45B855EB9ABF001686BC52730F754DBFAE781BB629F1E530632D813AA256D0063202AEEE0AB64C7829C1A6C4702E27C88219FF31500D8F76BEFE4AEF726D6E3B708C89023DAB +20241129165526 2 6 100 6143 2 D530FFAD12BC56C29F02BEFEC6CFD700AE6DA852D7256FC0A8978C13FABF9851425A26917CD40A9919A06A5B17FA05456642891442CCBBBD9BB5B74068213AA6F029B3419F6B2CCB828CF9F6F0069F43A2496921ED8133BF2D9C598486282EB38B3B6E849B7D80B33869CDE1D71379C694BB9C229B5CCE5E96692F81DA73EC38942CE60A81657F34A6B1B536ADEADD76144A209815A88E081E0B96438B11A34E4F8082ACC6DD77D787EEA90E1764F7393D3869707FCFCD4BFEEA3582BBD39C17E2CE70B6A193700A055A50D2F5ED473DD9B4401C2138BAD8FA3331BDD4FF79E230C10B13FFE7CCDB3210F8DB42147BB8349CAEA97EBCBC708B9CE16360D573D3327BBCAA6387234E9A4DCB2E67784408ADB72B2E05643520211C581EBB38E57C2F69C9034143DBAB4C13221D501B892918779C6E9AC5B39F2F412E31EF7F7F0610C2AFE150FA56A5E3CF9DACA6C96F3BC6B57D56B2869019C5114247C080752E4D42B1A0E34302B69B8516E8FB93BE58CC45F6E5ADB47A89A00050A12D560BEEA8997F5A0FA526C107BA34ECB0C678079C6DD4C1F4666BBD45733E019C292A17661B79E6AEED002EF4F6E7F4D569690E140C8BA1BA47E626499E01DA1EACDA4B917507A472DDB03A86734994C4B16551C5DFED3C8C976D15B5BF68CC6C982355930E37F096629E6F3BDC8027C722C12EF76854F1C607341E48FBF8C9064EB48EFDA87E1D111B557FBE7A15A580EDD87AC2CEC0EB25BE057FC20D578DF34632977F4698D58B2025C50AD4AD77D16D32E6157F89F58C692A83279A2EB58F8E448A13AA32B8C3DF07A58100EC4BB319F824446ECDD643C4A7F959CBA4E356A9E5DB7332107B2EB478703BF44383DDF80CA297F5E52A4424AF64B50CAB4E9C95C7288B96F8E77CDC63D07C6394853DF32F926652A12122B5531F90CFDFDAAC5D0642F84CF3901717B652122E8622CF31C06D134AD921EC80D175BBFC45B855EB9ABF001686BC52730F754DBFAE781BB629F1E530632D813AA256D0063202AEEE0AB64C7829C1A6C4702E27C88219FF31500D8F76BEFE4AEF726D6E3B708C8C3FAA43 +20241129170725 2 6 100 6143 5 D530FFAD12BC56C29F02BEFEC6CFD700AE6DA852D7256FC0A8978C13FABF9851425A26917CD40A9919A06A5B17FA05456642891442CCBBBD9BB5B74068213AA6F029B3419F6B2CCB828CF9F6F0069F43A2496921ED8133BF2D9C598486282EB38B3B6E849B7D80B33869CDE1D71379C694BB9C229B5CCE5E96692F81DA73EC38942CE60A81657F34A6B1B536ADEADD76144A209815A88E081E0B96438B11A34E4F8082ACC6DD77D787EEA90E1764F7393D3869707FCFCD4BFEEA3582BBD39C17E2CE70B6A193700A055A50D2F5ED473DD9B4401C2138BAD8FA3331BDD4FF79E230C10B13FFE7CCDB3210F8DB42147BB8349CAEA97EBCBC708B9CE16360D573D3327BBCAA6387234E9A4DCB2E67784408ADB72B2E05643520211C581EBB38E57C2F69C9034143DBAB4C13221D501B892918779C6E9AC5B39F2F412E31EF7F7F0610C2AFE150FA56A5E3CF9DACA6C96F3BC6B57D56B2869019C5114247C080752E4D42B1A0E34302B69B8516E8FB93BE58CC45F6E5ADB47A89A00050A12D560BEEA8997F5A0FA526C107BA34ECB0C678079C6DD4C1F4666BBD45733E019C292A17661B79E6AEED002EF4F6E7F4D569690E140C8BA1BA47E626499E01DA1EACDA4B917507A472DDB03A86734994C4B16551C5DFED3C8C976D15B5BF68CC6C982355930E37F096629E6F3BDC8027C722C12EF76854F1C607341E48FBF8C9064EB48EFDA87E1D111B557FBE7A15A580EDD87AC2CEC0EB25BE057FC20D578DF34632977F4698D58B2025C50AD4AD77D16D32E6157F89F58C692A83279A2EB58F8E448A13AA32B8C3DF07A58100EC4BB319F824446ECDD643C4A7F959CBA4E356A9E5DB7332107B2EB478703BF44383DDF80CA297F5E52A4424AF64B50CAB4E9C95C7288B96F8E77CDC63D07C6394853DF32F926652A12122B5531F90CFDFDAAC5D0642F84CF3901717B652122E8622CF31C06D134AD921EC80D175BBFC45B855EB9ABF001686BC52730F754DBFAE781BB629F1E530632D813AA256D0063202AEEE0AB64C7829C1A6C4702E27C88219FF31500D8F76BEFE4AEF726D6E3B708C8DB7E57F +20241129171144 2 6 100 6143 5 D530FFAD12BC56C29F02BEFEC6CFD700AE6DA852D7256FC0A8978C13FABF9851425A26917CD40A9919A06A5B17FA05456642891442CCBBBD9BB5B74068213AA6F029B3419F6B2CCB828CF9F6F0069F43A2496921ED8133BF2D9C598486282EB38B3B6E849B7D80B33869CDE1D71379C694BB9C229B5CCE5E96692F81DA73EC38942CE60A81657F34A6B1B536ADEADD76144A209815A88E081E0B96438B11A34E4F8082ACC6DD77D787EEA90E1764F7393D3869707FCFCD4BFEEA3582BBD39C17E2CE70B6A193700A055A50D2F5ED473DD9B4401C2138BAD8FA3331BDD4FF79E230C10B13FFE7CCDB3210F8DB42147BB8349CAEA97EBCBC708B9CE16360D573D3327BBCAA6387234E9A4DCB2E67784408ADB72B2E05643520211C581EBB38E57C2F69C9034143DBAB4C13221D501B892918779C6E9AC5B39F2F412E31EF7F7F0610C2AFE150FA56A5E3CF9DACA6C96F3BC6B57D56B2869019C5114247C080752E4D42B1A0E34302B69B8516E8FB93BE58CC45F6E5ADB47A89A00050A12D560BEEA8997F5A0FA526C107BA34ECB0C678079C6DD4C1F4666BBD45733E019C292A17661B79E6AEED002EF4F6E7F4D569690E140C8BA1BA47E626499E01DA1EACDA4B917507A472DDB03A86734994C4B16551C5DFED3C8C976D15B5BF68CC6C982355930E37F096629E6F3BDC8027C722C12EF76854F1C607341E48FBF8C9064EB48EFDA87E1D111B557FBE7A15A580EDD87AC2CEC0EB25BE057FC20D578DF34632977F4698D58B2025C50AD4AD77D16D32E6157F89F58C692A83279A2EB58F8E448A13AA32B8C3DF07A58100EC4BB319F824446ECDD643C4A7F959CBA4E356A9E5DB7332107B2EB478703BF44383DDF80CA297F5E52A4424AF64B50CAB4E9C95C7288B96F8E77CDC63D07C6394853DF32F926652A12122B5531F90CFDFDAAC5D0642F84CF3901717B652122E8622CF31C06D134AD921EC80D175BBFC45B855EB9ABF001686BC52730F754DBFAE781BB629F1E530632D813AA256D0063202AEEE0AB64C7829C1A6C4702E27C88219FF31500D8F76BEFE4AEF726D6E3B708C8E389D1F +20241129172847 2 6 100 6143 2 D530FFAD12BC56C29F02BEFEC6CFD700AE6DA852D7256FC0A8978C13FABF9851425A26917CD40A9919A06A5B17FA05456642891442CCBBBD9BB5B74068213AA6F029B3419F6B2CCB828CF9F6F0069F43A2496921ED8133BF2D9C598486282EB38B3B6E849B7D80B33869CDE1D71379C694BB9C229B5CCE5E96692F81DA73EC38942CE60A81657F34A6B1B536ADEADD76144A209815A88E081E0B96438B11A34E4F8082ACC6DD77D787EEA90E1764F7393D3869707FCFCD4BFEEA3582BBD39C17E2CE70B6A193700A055A50D2F5ED473DD9B4401C2138BAD8FA3331BDD4FF79E230C10B13FFE7CCDB3210F8DB42147BB8349CAEA97EBCBC708B9CE16360D573D3327BBCAA6387234E9A4DCB2E67784408ADB72B2E05643520211C581EBB38E57C2F69C9034143DBAB4C13221D501B892918779C6E9AC5B39F2F412E31EF7F7F0610C2AFE150FA56A5E3CF9DACA6C96F3BC6B57D56B2869019C5114247C080752E4D42B1A0E34302B69B8516E8FB93BE58CC45F6E5ADB47A89A00050A12D560BEEA8997F5A0FA526C107BA34ECB0C678079C6DD4C1F4666BBD45733E019C292A17661B79E6AEED002EF4F6E7F4D569690E140C8BA1BA47E626499E01DA1EACDA4B917507A472DDB03A86734994C4B16551C5DFED3C8C976D15B5BF68CC6C982355930E37F096629E6F3BDC8027C722C12EF76854F1C607341E48FBF8C9064EB48EFDA87E1D111B557FBE7A15A580EDD87AC2CEC0EB25BE057FC20D578DF34632977F4698D58B2025C50AD4AD77D16D32E6157F89F58C692A83279A2EB58F8E448A13AA32B8C3DF07A58100EC4BB319F824446ECDD643C4A7F959CBA4E356A9E5DB7332107B2EB478703BF44383DDF80CA297F5E52A4424AF64B50CAB4E9C95C7288B96F8E77CDC63D07C6394853DF32F926652A12122B5531F90CFDFDAAC5D0642F84CF3901717B652122E8622CF31C06D134AD921EC80D175BBFC45B855EB9ABF001686BC52730F754DBFAE781BB629F1E530632D813AA256D0063202AEEE0AB64C7829C1A6C4702E27C88219FF31500D8F76BEFE4AEF726D6E3B708C90533393 +20241129173154 2 6 100 6143 2 D530FFAD12BC56C29F02BEFEC6CFD700AE6DA852D7256FC0A8978C13FABF9851425A26917CD40A9919A06A5B17FA05456642891442CCBBBD9BB5B74068213AA6F029B3419F6B2CCB828CF9F6F0069F43A2496921ED8133BF2D9C598486282EB38B3B6E849B7D80B33869CDE1D71379C694BB9C229B5CCE5E96692F81DA73EC38942CE60A81657F34A6B1B536ADEADD76144A209815A88E081E0B96438B11A34E4F8082ACC6DD77D787EEA90E1764F7393D3869707FCFCD4BFEEA3582BBD39C17E2CE70B6A193700A055A50D2F5ED473DD9B4401C2138BAD8FA3331BDD4FF79E230C10B13FFE7CCDB3210F8DB42147BB8349CAEA97EBCBC708B9CE16360D573D3327BBCAA6387234E9A4DCB2E67784408ADB72B2E05643520211C581EBB38E57C2F69C9034143DBAB4C13221D501B892918779C6E9AC5B39F2F412E31EF7F7F0610C2AFE150FA56A5E3CF9DACA6C96F3BC6B57D56B2869019C5114247C080752E4D42B1A0E34302B69B8516E8FB93BE58CC45F6E5ADB47A89A00050A12D560BEEA8997F5A0FA526C107BA34ECB0C678079C6DD4C1F4666BBD45733E019C292A17661B79E6AEED002EF4F6E7F4D569690E140C8BA1BA47E626499E01DA1EACDA4B917507A472DDB03A86734994C4B16551C5DFED3C8C976D15B5BF68CC6C982355930E37F096629E6F3BDC8027C722C12EF76854F1C607341E48FBF8C9064EB48EFDA87E1D111B557FBE7A15A580EDD87AC2CEC0EB25BE057FC20D578DF34632977F4698D58B2025C50AD4AD77D16D32E6157F89F58C692A83279A2EB58F8E448A13AA32B8C3DF07A58100EC4BB319F824446ECDD643C4A7F959CBA4E356A9E5DB7332107B2EB478703BF44383DDF80CA297F5E52A4424AF64B50CAB4E9C95C7288B96F8E77CDC63D07C6394853DF32F926652A12122B5531F90CFDFDAAC5D0642F84CF3901717B652122E8622CF31C06D134AD921EC80D175BBFC45B855EB9ABF001686BC52730F754DBFAE781BB629F1E530632D813AA256D0063202AEEE0AB64C7829C1A6C4702E27C88219FF31500D8F76BEFE4AEF726D6E3B708C90AFE143 +20241129174539 2 6 100 6143 2 D530FFAD12BC56C29F02BEFEC6CFD700AE6DA852D7256FC0A8978C13FABF9851425A26917CD40A9919A06A5B17FA05456642891442CCBBBD9BB5B74068213AA6F029B3419F6B2CCB828CF9F6F0069F43A2496921ED8133BF2D9C598486282EB38B3B6E849B7D80B33869CDE1D71379C694BB9C229B5CCE5E96692F81DA73EC38942CE60A81657F34A6B1B536ADEADD76144A209815A88E081E0B96438B11A34E4F8082ACC6DD77D787EEA90E1764F7393D3869707FCFCD4BFEEA3582BBD39C17E2CE70B6A193700A055A50D2F5ED473DD9B4401C2138BAD8FA3331BDD4FF79E230C10B13FFE7CCDB3210F8DB42147BB8349CAEA97EBCBC708B9CE16360D573D3327BBCAA6387234E9A4DCB2E67784408ADB72B2E05643520211C581EBB38E57C2F69C9034143DBAB4C13221D501B892918779C6E9AC5B39F2F412E31EF7F7F0610C2AFE150FA56A5E3CF9DACA6C96F3BC6B57D56B2869019C5114247C080752E4D42B1A0E34302B69B8516E8FB93BE58CC45F6E5ADB47A89A00050A12D560BEEA8997F5A0FA526C107BA34ECB0C678079C6DD4C1F4666BBD45733E019C292A17661B79E6AEED002EF4F6E7F4D569690E140C8BA1BA47E626499E01DA1EACDA4B917507A472DDB03A86734994C4B16551C5DFED3C8C976D15B5BF68CC6C982355930E37F096629E6F3BDC8027C722C12EF76854F1C607341E48FBF8C9064EB48EFDA87E1D111B557FBE7A15A580EDD87AC2CEC0EB25BE057FC20D578DF34632977F4698D58B2025C50AD4AD77D16D32E6157F89F58C692A83279A2EB58F8E448A13AA32B8C3DF07A58100EC4BB319F824446ECDD643C4A7F959CBA4E356A9E5DB7332107B2EB478703BF44383DDF80CA297F5E52A4424AF64B50CAB4E9C95C7288B96F8E77CDC63D07C6394853DF32F926652A12122B5531F90CFDFDAAC5D0642F84CF3901717B652122E8622CF31C06D134AD921EC80D175BBFC45B855EB9ABF001686BC52730F754DBFAE781BB629F1E530632D813AA256D0063202AEEE0AB64C7829C1A6C4702E27C88219FF31500D8F76BEFE4AEF726D6E3B708C92621483 +20241129180732 2 6 100 6143 5 D530FFAD12BC56C29F02BEFEC6CFD700AE6DA852D7256FC0A8978C13FABF9851425A26917CD40A9919A06A5B17FA05456642891442CCBBBD9BB5B74068213AA6F029B3419F6B2CCB828CF9F6F0069F43A2496921ED8133BF2D9C598486282EB38B3B6E849B7D80B33869CDE1D71379C694BB9C229B5CCE5E96692F81DA73EC38942CE60A81657F34A6B1B536ADEADD76144A209815A88E081E0B96438B11A34E4F8082ACC6DD77D787EEA90E1764F7393D3869707FCFCD4BFEEA3582BBD39C17E2CE70B6A193700A055A50D2F5ED473DD9B4401C2138BAD8FA3331BDD4FF79E230C10B13FFE7CCDB3210F8DB42147BB8349CAEA97EBCBC708B9CE16360D573D3327BBCAA6387234E9A4DCB2E67784408ADB72B2E05643520211C581EBB38E57C2F69C9034143DBAB4C13221D501B892918779C6E9AC5B39F2F412E31EF7F7F0610C2AFE150FA56A5E3CF9DACA6C96F3BC6B57D56B2869019C5114247C080752E4D42B1A0E34302B69B8516E8FB93BE58CC45F6E5ADB47A89A00050A12D560BEEA8997F5A0FA526C107BA34ECB0C678079C6DD4C1F4666BBD45733E019C292A17661B79E6AEED002EF4F6E7F4D569690E140C8BA1BA47E626499E01DA1EACDA4B917507A472DDB03A86734994C4B16551C5DFED3C8C976D15B5BF68CC6C982355930E37F096629E6F3BDC8027C722C12EF76854F1C607341E48FBF8C9064EB48EFDA87E1D111B557FBE7A15A580EDD87AC2CEC0EB25BE057FC20D578DF34632977F4698D58B2025C50AD4AD77D16D32E6157F89F58C692A83279A2EB58F8E448A13AA32B8C3DF07A58100EC4BB319F824446ECDD643C4A7F959CBA4E356A9E5DB7332107B2EB478703BF44383DDF80CA297F5E52A4424AF64B50CAB4E9C95C7288B96F8E77CDC63D07C6394853DF32F926652A12122B5531F90CFDFDAAC5D0642F84CF3901717B652122E8622CF31C06D134AD921EC80D175BBFC45B855EB9ABF001686BC52730F754DBFAE781BB629F1E530632D813AA256D0063202AEEE0AB64C7829C1A6C4702E27C88219FF31500D8F76BEFE4AEF726D6E3B708C951D8D97 +20241129181538 2 6 100 6143 2 D530FFAD12BC56C29F02BEFEC6CFD700AE6DA852D7256FC0A8978C13FABF9851425A26917CD40A9919A06A5B17FA05456642891442CCBBBD9BB5B74068213AA6F029B3419F6B2CCB828CF9F6F0069F43A2496921ED8133BF2D9C598486282EB38B3B6E849B7D80B33869CDE1D71379C694BB9C229B5CCE5E96692F81DA73EC38942CE60A81657F34A6B1B536ADEADD76144A209815A88E081E0B96438B11A34E4F8082ACC6DD77D787EEA90E1764F7393D3869707FCFCD4BFEEA3582BBD39C17E2CE70B6A193700A055A50D2F5ED473DD9B4401C2138BAD8FA3331BDD4FF79E230C10B13FFE7CCDB3210F8DB42147BB8349CAEA97EBCBC708B9CE16360D573D3327BBCAA6387234E9A4DCB2E67784408ADB72B2E05643520211C581EBB38E57C2F69C9034143DBAB4C13221D501B892918779C6E9AC5B39F2F412E31EF7F7F0610C2AFE150FA56A5E3CF9DACA6C96F3BC6B57D56B2869019C5114247C080752E4D42B1A0E34302B69B8516E8FB93BE58CC45F6E5ADB47A89A00050A12D560BEEA8997F5A0FA526C107BA34ECB0C678079C6DD4C1F4666BBD45733E019C292A17661B79E6AEED002EF4F6E7F4D569690E140C8BA1BA47E626499E01DA1EACDA4B917507A472DDB03A86734994C4B16551C5DFED3C8C976D15B5BF68CC6C982355930E37F096629E6F3BDC8027C722C12EF76854F1C607341E48FBF8C9064EB48EFDA87E1D111B557FBE7A15A580EDD87AC2CEC0EB25BE057FC20D578DF34632977F4698D58B2025C50AD4AD77D16D32E6157F89F58C692A83279A2EB58F8E448A13AA32B8C3DF07A58100EC4BB319F824446ECDD643C4A7F959CBA4E356A9E5DB7332107B2EB478703BF44383DDF80CA297F5E52A4424AF64B50CAB4E9C95C7288B96F8E77CDC63D07C6394853DF32F926652A12122B5531F90CFDFDAAC5D0642F84CF3901717B652122E8622CF31C06D134AD921EC80D175BBFC45B855EB9ABF001686BC52730F754DBFAE781BB629F1E530632D813AA256D0063202AEEE0AB64C7829C1A6C4702E27C88219FF31500D8F76BEFE4AEF726D6E3B708C961A0AFB +20241129182310 2 6 100 6143 5 D530FFAD12BC56C29F02BEFEC6CFD700AE6DA852D7256FC0A8978C13FABF9851425A26917CD40A9919A06A5B17FA05456642891442CCBBBD9BB5B74068213AA6F029B3419F6B2CCB828CF9F6F0069F43A2496921ED8133BF2D9C598486282EB38B3B6E849B7D80B33869CDE1D71379C694BB9C229B5CCE5E96692F81DA73EC38942CE60A81657F34A6B1B536ADEADD76144A209815A88E081E0B96438B11A34E4F8082ACC6DD77D787EEA90E1764F7393D3869707FCFCD4BFEEA3582BBD39C17E2CE70B6A193700A055A50D2F5ED473DD9B4401C2138BAD8FA3331BDD4FF79E230C10B13FFE7CCDB3210F8DB42147BB8349CAEA97EBCBC708B9CE16360D573D3327BBCAA6387234E9A4DCB2E67784408ADB72B2E05643520211C581EBB38E57C2F69C9034143DBAB4C13221D501B892918779C6E9AC5B39F2F412E31EF7F7F0610C2AFE150FA56A5E3CF9DACA6C96F3BC6B57D56B2869019C5114247C080752E4D42B1A0E34302B69B8516E8FB93BE58CC45F6E5ADB47A89A00050A12D560BEEA8997F5A0FA526C107BA34ECB0C678079C6DD4C1F4666BBD45733E019C292A17661B79E6AEED002EF4F6E7F4D569690E140C8BA1BA47E626499E01DA1EACDA4B917507A472DDB03A86734994C4B16551C5DFED3C8C976D15B5BF68CC6C982355930E37F096629E6F3BDC8027C722C12EF76854F1C607341E48FBF8C9064EB48EFDA87E1D111B557FBE7A15A580EDD87AC2CEC0EB25BE057FC20D578DF34632977F4698D58B2025C50AD4AD77D16D32E6157F89F58C692A83279A2EB58F8E448A13AA32B8C3DF07A58100EC4BB319F824446ECDD643C4A7F959CBA4E356A9E5DB7332107B2EB478703BF44383DDF80CA297F5E52A4424AF64B50CAB4E9C95C7288B96F8E77CDC63D07C6394853DF32F926652A12122B5531F90CFDFDAAC5D0642F84CF3901717B652122E8622CF31C06D134AD921EC80D175BBFC45B855EB9ABF001686BC52730F754DBFAE781BB629F1E530632D813AA256D0063202AEEE0AB64C7829C1A6C4702E27C88219FF31500D8F76BEFE4AEF726D6E3B708C97054E47 +20241129183550 2 6 100 6143 5 D530FFAD12BC56C29F02BEFEC6CFD700AE6DA852D7256FC0A8978C13FABF9851425A26917CD40A9919A06A5B17FA05456642891442CCBBBD9BB5B74068213AA6F029B3419F6B2CCB828CF9F6F0069F43A2496921ED8133BF2D9C598486282EB38B3B6E849B7D80B33869CDE1D71379C694BB9C229B5CCE5E96692F81DA73EC38942CE60A81657F34A6B1B536ADEADD76144A209815A88E081E0B96438B11A34E4F8082ACC6DD77D787EEA90E1764F7393D3869707FCFCD4BFEEA3582BBD39C17E2CE70B6A193700A055A50D2F5ED473DD9B4401C2138BAD8FA3331BDD4FF79E230C10B13FFE7CCDB3210F8DB42147BB8349CAEA97EBCBC708B9CE16360D573D3327BBCAA6387234E9A4DCB2E67784408ADB72B2E05643520211C581EBB38E57C2F69C9034143DBAB4C13221D501B892918779C6E9AC5B39F2F412E31EF7F7F0610C2AFE150FA56A5E3CF9DACA6C96F3BC6B57D56B2869019C5114247C080752E4D42B1A0E34302B69B8516E8FB93BE58CC45F6E5ADB47A89A00050A12D560BEEA8997F5A0FA526C107BA34ECB0C678079C6DD4C1F4666BBD45733E019C292A17661B79E6AEED002EF4F6E7F4D569690E140C8BA1BA47E626499E01DA1EACDA4B917507A472DDB03A86734994C4B16551C5DFED3C8C976D15B5BF68CC6C982355930E37F096629E6F3BDC8027C722C12EF76854F1C607341E48FBF8C9064EB48EFDA87E1D111B557FBE7A15A580EDD87AC2CEC0EB25BE057FC20D578DF34632977F4698D58B2025C50AD4AD77D16D32E6157F89F58C692A83279A2EB58F8E448A13AA32B8C3DF07A58100EC4BB319F824446ECDD643C4A7F959CBA4E356A9E5DB7332107B2EB478703BF44383DDF80CA297F5E52A4424AF64B50CAB4E9C95C7288B96F8E77CDC63D07C6394853DF32F926652A12122B5531F90CFDFDAAC5D0642F84CF3901717B652122E8622CF31C06D134AD921EC80D175BBFC45B855EB9ABF001686BC52730F754DBFAE781BB629F1E530632D813AA256D0063202AEEE0AB64C7829C1A6C4702E27C88219FF31500D8F76BEFE4AEF726D6E3B708C989CFDEF +20241129184809 2 6 100 6143 2 D530FFAD12BC56C29F02BEFEC6CFD700AE6DA852D7256FC0A8978C13FABF9851425A26917CD40A9919A06A5B17FA05456642891442CCBBBD9BB5B74068213AA6F029B3419F6B2CCB828CF9F6F0069F43A2496921ED8133BF2D9C598486282EB38B3B6E849B7D80B33869CDE1D71379C694BB9C229B5CCE5E96692F81DA73EC38942CE60A81657F34A6B1B536ADEADD76144A209815A88E081E0B96438B11A34E4F8082ACC6DD77D787EEA90E1764F7393D3869707FCFCD4BFEEA3582BBD39C17E2CE70B6A193700A055A50D2F5ED473DD9B4401C2138BAD8FA3331BDD4FF79E230C10B13FFE7CCDB3210F8DB42147BB8349CAEA97EBCBC708B9CE16360D573D3327BBCAA6387234E9A4DCB2E67784408ADB72B2E05643520211C581EBB38E57C2F69C9034143DBAB4C13221D501B892918779C6E9AC5B39F2F412E31EF7F7F0610C2AFE150FA56A5E3CF9DACA6C96F3BC6B57D56B2869019C5114247C080752E4D42B1A0E34302B69B8516E8FB93BE58CC45F6E5ADB47A89A00050A12D560BEEA8997F5A0FA526C107BA34ECB0C678079C6DD4C1F4666BBD45733E019C292A17661B79E6AEED002EF4F6E7F4D569690E140C8BA1BA47E626499E01DA1EACDA4B917507A472DDB03A86734994C4B16551C5DFED3C8C976D15B5BF68CC6C982355930E37F096629E6F3BDC8027C722C12EF76854F1C607341E48FBF8C9064EB48EFDA87E1D111B557FBE7A15A580EDD87AC2CEC0EB25BE057FC20D578DF34632977F4698D58B2025C50AD4AD77D16D32E6157F89F58C692A83279A2EB58F8E448A13AA32B8C3DF07A58100EC4BB319F824446ECDD643C4A7F959CBA4E356A9E5DB7332107B2EB478703BF44383DDF80CA297F5E52A4424AF64B50CAB4E9C95C7288B96F8E77CDC63D07C6394853DF32F926652A12122B5531F90CFDFDAAC5D0642F84CF3901717B652122E8622CF31C06D134AD921EC80D175BBFC45B855EB9ABF001686BC52730F754DBFAE781BB629F1E530632D813AA256D0063202AEEE0AB64C7829C1A6C4702E27C88219FF31500D8F76BEFE4AEF726D6E3B708C9A2A2BAB +20241129185633 2 6 100 6143 2 D530FFAD12BC56C29F02BEFEC6CFD700AE6DA852D7256FC0A8978C13FABF9851425A26917CD40A9919A06A5B17FA05456642891442CCBBBD9BB5B74068213AA6F029B3419F6B2CCB828CF9F6F0069F43A2496921ED8133BF2D9C598486282EB38B3B6E849B7D80B33869CDE1D71379C694BB9C229B5CCE5E96692F81DA73EC38942CE60A81657F34A6B1B536ADEADD76144A209815A88E081E0B96438B11A34E4F8082ACC6DD77D787EEA90E1764F7393D3869707FCFCD4BFEEA3582BBD39C17E2CE70B6A193700A055A50D2F5ED473DD9B4401C2138BAD8FA3331BDD4FF79E230C10B13FFE7CCDB3210F8DB42147BB8349CAEA97EBCBC708B9CE16360D573D3327BBCAA6387234E9A4DCB2E67784408ADB72B2E05643520211C581EBB38E57C2F69C9034143DBAB4C13221D501B892918779C6E9AC5B39F2F412E31EF7F7F0610C2AFE150FA56A5E3CF9DACA6C96F3BC6B57D56B2869019C5114247C080752E4D42B1A0E34302B69B8516E8FB93BE58CC45F6E5ADB47A89A00050A12D560BEEA8997F5A0FA526C107BA34ECB0C678079C6DD4C1F4666BBD45733E019C292A17661B79E6AEED002EF4F6E7F4D569690E140C8BA1BA47E626499E01DA1EACDA4B917507A472DDB03A86734994C4B16551C5DFED3C8C976D15B5BF68CC6C982355930E37F096629E6F3BDC8027C722C12EF76854F1C607341E48FBF8C9064EB48EFDA87E1D111B557FBE7A15A580EDD87AC2CEC0EB25BE057FC20D578DF34632977F4698D58B2025C50AD4AD77D16D32E6157F89F58C692A83279A2EB58F8E448A13AA32B8C3DF07A58100EC4BB319F824446ECDD643C4A7F959CBA4E356A9E5DB7332107B2EB478703BF44383DDF80CA297F5E52A4424AF64B50CAB4E9C95C7288B96F8E77CDC63D07C6394853DF32F926652A12122B5531F90CFDFDAAC5D0642F84CF3901717B652122E8622CF31C06D134AD921EC80D175BBFC45B855EB9ABF001686BC52730F754DBFAE781BB629F1E530632D813AA256D0063202AEEE0AB64C7829C1A6C4702E27C88219FF31500D8F76BEFE4AEF726D6E3B708C9B335EE3 +20241129190213 2 6 100 6143 5 D530FFAD12BC56C29F02BEFEC6CFD700AE6DA852D7256FC0A8978C13FABF9851425A26917CD40A9919A06A5B17FA05456642891442CCBBBD9BB5B74068213AA6F029B3419F6B2CCB828CF9F6F0069F43A2496921ED8133BF2D9C598486282EB38B3B6E849B7D80B33869CDE1D71379C694BB9C229B5CCE5E96692F81DA73EC38942CE60A81657F34A6B1B536ADEADD76144A209815A88E081E0B96438B11A34E4F8082ACC6DD77D787EEA90E1764F7393D3869707FCFCD4BFEEA3582BBD39C17E2CE70B6A193700A055A50D2F5ED473DD9B4401C2138BAD8FA3331BDD4FF79E230C10B13FFE7CCDB3210F8DB42147BB8349CAEA97EBCBC708B9CE16360D573D3327BBCAA6387234E9A4DCB2E67784408ADB72B2E05643520211C581EBB38E57C2F69C9034143DBAB4C13221D501B892918779C6E9AC5B39F2F412E31EF7F7F0610C2AFE150FA56A5E3CF9DACA6C96F3BC6B57D56B2869019C5114247C080752E4D42B1A0E34302B69B8516E8FB93BE58CC45F6E5ADB47A89A00050A12D560BEEA8997F5A0FA526C107BA34ECB0C678079C6DD4C1F4666BBD45733E019C292A17661B79E6AEED002EF4F6E7F4D569690E140C8BA1BA47E626499E01DA1EACDA4B917507A472DDB03A86734994C4B16551C5DFED3C8C976D15B5BF68CC6C982355930E37F096629E6F3BDC8027C722C12EF76854F1C607341E48FBF8C9064EB48EFDA87E1D111B557FBE7A15A580EDD87AC2CEC0EB25BE057FC20D578DF34632977F4698D58B2025C50AD4AD77D16D32E6157F89F58C692A83279A2EB58F8E448A13AA32B8C3DF07A58100EC4BB319F824446ECDD643C4A7F959CBA4E356A9E5DB7332107B2EB478703BF44383DDF80CA297F5E52A4424AF64B50CAB4E9C95C7288B96F8E77CDC63D07C6394853DF32F926652A12122B5531F90CFDFDAAC5D0642F84CF3901717B652122E8622CF31C06D134AD921EC80D175BBFC45B855EB9ABF001686BC52730F754DBFAE781BB629F1E530632D813AA256D0063202AEEE0AB64C7829C1A6C4702E27C88219FF31500D8F76BEFE4AEF726D6E3B708C9BDDE8CF +20241129203945 2 6 100 6143 2 D530FFAD12BC56C29F02BEFEC6CFD700AE6DA852D7256FC0A8978C13FABF9851425A26917CD40A9919A06A5B17FA05456642891442CCBBBD9BB5B74068213AA6F029B3419F6B2CCB828CF9F6F0069F43A2496921ED8133BF2D9C598486282EB38B3B6E849B7D80B33869CDE1D71379C694BB9C229B5CCE5E96692F81DA73EC38942CE60A81657F34A6B1B536ADEADD76144A209815A88E081E0B96438B11A34E4F8082ACC6DD77D787EEA90E1764F7393D3869707FCFCD4BFEEA3582BBD39C17E2CE70B6A193700A055A50D2F5ED473DD9B4401C2138BAD8FA3331BDD4FF79E230C10B13FFE7CCDB3210F8DB42147BB8349CAEA97EBCBC708B9CE16360D573D3327BBCAA6387234E9A4DCB2E67784408ADB72B2E05643520211C581EBB38E57C2F69C9034143DBAB4C13221D501B892918779C6E9AC5B39F2F412E31EF7F7F0610C2AFE150FA56A5E3CF9DACA6C96F3BC6B57D56B2869019C5114247C080752E4D42B1A0E34302B69B8516E8FB93BE58CC45F6E5ADB47A89A00050A12D560BEEA8997F5A0FA526C107BA34ECB0C678079C6DD4C1F4666BBD45733E019C292A17661B79E6AEED002EF4F6E7F4D569690E140C8BA1BA47E626499E01DA1EACDA4B917507A472DDB03A86734994C4B16551C5DFED3C8C976D15B5BF68CC6C982355930E37F096629E6F3BDC8027C722C12EF76854F1C607341E48FBF8C9064EB48EFDA87E1D111B557FBE7A15A580EDD87AC2CEC0EB25BE057FC20D578DF34632977F4698D58B2025C50AD4AD77D16D32E6157F89F58C692A83279A2EB58F8E448A13AA32B8C3DF07A58100EC4BB319F824446ECDD643C4A7F959CBA4E356A9E5DB7332107B2EB478703BF44383DDF80CA297F5E52A4424AF64B50CAB4E9C95C7288B96F8E77CDC63D07C6394853DF32F926652A12122B5531F90CFDFDAAC5D0642F84CF3901717B652122E8622CF31C06D134AD921EC80D175BBFC45B855EB9ABF001686BC52730F754DBFAE781BB629F1E530632D813AA256D0063202AEEE0AB64C7829C1A6C4702E27C88219FF31500D8F76BEFE4AEF726D6E3B708CA834CF13 +20241129204138 2 6 100 6143 5 D530FFAD12BC56C29F02BEFEC6CFD700AE6DA852D7256FC0A8978C13FABF9851425A26917CD40A9919A06A5B17FA05456642891442CCBBBD9BB5B74068213AA6F029B3419F6B2CCB828CF9F6F0069F43A2496921ED8133BF2D9C598486282EB38B3B6E849B7D80B33869CDE1D71379C694BB9C229B5CCE5E96692F81DA73EC38942CE60A81657F34A6B1B536ADEADD76144A209815A88E081E0B96438B11A34E4F8082ACC6DD77D787EEA90E1764F7393D3869707FCFCD4BFEEA3582BBD39C17E2CE70B6A193700A055A50D2F5ED473DD9B4401C2138BAD8FA3331BDD4FF79E230C10B13FFE7CCDB3210F8DB42147BB8349CAEA97EBCBC708B9CE16360D573D3327BBCAA6387234E9A4DCB2E67784408ADB72B2E05643520211C581EBB38E57C2F69C9034143DBAB4C13221D501B892918779C6E9AC5B39F2F412E31EF7F7F0610C2AFE150FA56A5E3CF9DACA6C96F3BC6B57D56B2869019C5114247C080752E4D42B1A0E34302B69B8516E8FB93BE58CC45F6E5ADB47A89A00050A12D560BEEA8997F5A0FA526C107BA34ECB0C678079C6DD4C1F4666BBD45733E019C292A17661B79E6AEED002EF4F6E7F4D569690E140C8BA1BA47E626499E01DA1EACDA4B917507A472DDB03A86734994C4B16551C5DFED3C8C976D15B5BF68CC6C982355930E37F096629E6F3BDC8027C722C12EF76854F1C607341E48FBF8C9064EB48EFDA87E1D111B557FBE7A15A580EDD87AC2CEC0EB25BE057FC20D578DF34632977F4698D58B2025C50AD4AD77D16D32E6157F89F58C692A83279A2EB58F8E448A13AA32B8C3DF07A58100EC4BB319F824446ECDD643C4A7F959CBA4E356A9E5DB7332107B2EB478703BF44383DDF80CA297F5E52A4424AF64B50CAB4E9C95C7288B96F8E77CDC63D07C6394853DF32F926652A12122B5531F90CFDFDAAC5D0642F84CF3901717B652122E8622CF31C06D134AD921EC80D175BBFC45B855EB9ABF001686BC52730F754DBFAE781BB629F1E530632D813AA256D0063202AEEE0AB64C7829C1A6C4702E27C88219FF31500D8F76BEFE4AEF726D6E3B708CA86A90F7 +20241129205210 2 6 100 6143 5 D530FFAD12BC56C29F02BEFEC6CFD700AE6DA852D7256FC0A8978C13FABF9851425A26917CD40A9919A06A5B17FA05456642891442CCBBBD9BB5B74068213AA6F029B3419F6B2CCB828CF9F6F0069F43A2496921ED8133BF2D9C598486282EB38B3B6E849B7D80B33869CDE1D71379C694BB9C229B5CCE5E96692F81DA73EC38942CE60A81657F34A6B1B536ADEADD76144A209815A88E081E0B96438B11A34E4F8082ACC6DD77D787EEA90E1764F7393D3869707FCFCD4BFEEA3582BBD39C17E2CE70B6A193700A055A50D2F5ED473DD9B4401C2138BAD8FA3331BDD4FF79E230C10B13FFE7CCDB3210F8DB42147BB8349CAEA97EBCBC708B9CE16360D573D3327BBCAA6387234E9A4DCB2E67784408ADB72B2E05643520211C581EBB38E57C2F69C9034143DBAB4C13221D501B892918779C6E9AC5B39F2F412E31EF7F7F0610C2AFE150FA56A5E3CF9DACA6C96F3BC6B57D56B2869019C5114247C080752E4D42B1A0E34302B69B8516E8FB93BE58CC45F6E5ADB47A89A00050A12D560BEEA8997F5A0FA526C107BA34ECB0C678079C6DD4C1F4666BBD45733E019C292A17661B79E6AEED002EF4F6E7F4D569690E140C8BA1BA47E626499E01DA1EACDA4B917507A472DDB03A86734994C4B16551C5DFED3C8C976D15B5BF68CC6C982355930E37F096629E6F3BDC8027C722C12EF76854F1C607341E48FBF8C9064EB48EFDA87E1D111B557FBE7A15A580EDD87AC2CEC0EB25BE057FC20D578DF34632977F4698D58B2025C50AD4AD77D16D32E6157F89F58C692A83279A2EB58F8E448A13AA32B8C3DF07A58100EC4BB319F824446ECDD643C4A7F959CBA4E356A9E5DB7332107B2EB478703BF44383DDF80CA297F5E52A4424AF64B50CAB4E9C95C7288B96F8E77CDC63D07C6394853DF32F926652A12122B5531F90CFDFDAAC5D0642F84CF3901717B652122E8622CF31C06D134AD921EC80D175BBFC45B855EB9ABF001686BC52730F754DBFAE781BB629F1E530632D813AA256D0063202AEEE0AB64C7829C1A6C4702E27C88219FF31500D8F76BEFE4AEF726D6E3B708CA9BFC2E7 +20241129210035 2 6 100 6143 2 D530FFAD12BC56C29F02BEFEC6CFD700AE6DA852D7256FC0A8978C13FABF9851425A26917CD40A9919A06A5B17FA05456642891442CCBBBD9BB5B74068213AA6F029B3419F6B2CCB828CF9F6F0069F43A2496921ED8133BF2D9C598486282EB38B3B6E849B7D80B33869CDE1D71379C694BB9C229B5CCE5E96692F81DA73EC38942CE60A81657F34A6B1B536ADEADD76144A209815A88E081E0B96438B11A34E4F8082ACC6DD77D787EEA90E1764F7393D3869707FCFCD4BFEEA3582BBD39C17E2CE70B6A193700A055A50D2F5ED473DD9B4401C2138BAD8FA3331BDD4FF79E230C10B13FFE7CCDB3210F8DB42147BB8349CAEA97EBCBC708B9CE16360D573D3327BBCAA6387234E9A4DCB2E67784408ADB72B2E05643520211C581EBB38E57C2F69C9034143DBAB4C13221D501B892918779C6E9AC5B39F2F412E31EF7F7F0610C2AFE150FA56A5E3CF9DACA6C96F3BC6B57D56B2869019C5114247C080752E4D42B1A0E34302B69B8516E8FB93BE58CC45F6E5ADB47A89A00050A12D560BEEA8997F5A0FA526C107BA34ECB0C678079C6DD4C1F4666BBD45733E019C292A17661B79E6AEED002EF4F6E7F4D569690E140C8BA1BA47E626499E01DA1EACDA4B917507A472DDB03A86734994C4B16551C5DFED3C8C976D15B5BF68CC6C982355930E37F096629E6F3BDC8027C722C12EF76854F1C607341E48FBF8C9064EB48EFDA87E1D111B557FBE7A15A580EDD87AC2CEC0EB25BE057FC20D578DF34632977F4698D58B2025C50AD4AD77D16D32E6157F89F58C692A83279A2EB58F8E448A13AA32B8C3DF07A58100EC4BB319F824446ECDD643C4A7F959CBA4E356A9E5DB7332107B2EB478703BF44383DDF80CA297F5E52A4424AF64B50CAB4E9C95C7288B96F8E77CDC63D07C6394853DF32F926652A12122B5531F90CFDFDAAC5D0642F84CF3901717B652122E8622CF31C06D134AD921EC80D175BBFC45B855EB9ABF001686BC52730F754DBFAE781BB629F1E530632D813AA256D0063202AEEE0AB64C7829C1A6C4702E27C88219FF31500D8F76BEFE4AEF726D6E3B708CAAC70D2B +20241129210423 2 6 100 6143 5 D530FFAD12BC56C29F02BEFEC6CFD700AE6DA852D7256FC0A8978C13FABF9851425A26917CD40A9919A06A5B17FA05456642891442CCBBBD9BB5B74068213AA6F029B3419F6B2CCB828CF9F6F0069F43A2496921ED8133BF2D9C598486282EB38B3B6E849B7D80B33869CDE1D71379C694BB9C229B5CCE5E96692F81DA73EC38942CE60A81657F34A6B1B536ADEADD76144A209815A88E081E0B96438B11A34E4F8082ACC6DD77D787EEA90E1764F7393D3869707FCFCD4BFEEA3582BBD39C17E2CE70B6A193700A055A50D2F5ED473DD9B4401C2138BAD8FA3331BDD4FF79E230C10B13FFE7CCDB3210F8DB42147BB8349CAEA97EBCBC708B9CE16360D573D3327BBCAA6387234E9A4DCB2E67784408ADB72B2E05643520211C581EBB38E57C2F69C9034143DBAB4C13221D501B892918779C6E9AC5B39F2F412E31EF7F7F0610C2AFE150FA56A5E3CF9DACA6C96F3BC6B57D56B2869019C5114247C080752E4D42B1A0E34302B69B8516E8FB93BE58CC45F6E5ADB47A89A00050A12D560BEEA8997F5A0FA526C107BA34ECB0C678079C6DD4C1F4666BBD45733E019C292A17661B79E6AEED002EF4F6E7F4D569690E140C8BA1BA47E626499E01DA1EACDA4B917507A472DDB03A86734994C4B16551C5DFED3C8C976D15B5BF68CC6C982355930E37F096629E6F3BDC8027C722C12EF76854F1C607341E48FBF8C9064EB48EFDA87E1D111B557FBE7A15A580EDD87AC2CEC0EB25BE057FC20D578DF34632977F4698D58B2025C50AD4AD77D16D32E6157F89F58C692A83279A2EB58F8E448A13AA32B8C3DF07A58100EC4BB319F824446ECDD643C4A7F959CBA4E356A9E5DB7332107B2EB478703BF44383DDF80CA297F5E52A4424AF64B50CAB4E9C95C7288B96F8E77CDC63D07C6394853DF32F926652A12122B5531F90CFDFDAAC5D0642F84CF3901717B652122E8622CF31C06D134AD921EC80D175BBFC45B855EB9ABF001686BC52730F754DBFAE781BB629F1E530632D813AA256D0063202AEEE0AB64C7829C1A6C4702E27C88219FF31500D8F76BEFE4AEF726D6E3B708CAB389E37 +20241129213344 2 6 100 6143 5 D530FFAD12BC56C29F02BEFEC6CFD700AE6DA852D7256FC0A8978C13FABF9851425A26917CD40A9919A06A5B17FA05456642891442CCBBBD9BB5B74068213AA6F029B3419F6B2CCB828CF9F6F0069F43A2496921ED8133BF2D9C598486282EB38B3B6E849B7D80B33869CDE1D71379C694BB9C229B5CCE5E96692F81DA73EC38942CE60A81657F34A6B1B536ADEADD76144A209815A88E081E0B96438B11A34E4F8082ACC6DD77D787EEA90E1764F7393D3869707FCFCD4BFEEA3582BBD39C17E2CE70B6A193700A055A50D2F5ED473DD9B4401C2138BAD8FA3331BDD4FF79E230C10B13FFE7CCDB3210F8DB42147BB8349CAEA97EBCBC708B9CE16360D573D3327BBCAA6387234E9A4DCB2E67784408ADB72B2E05643520211C581EBB38E57C2F69C9034143DBAB4C13221D501B892918779C6E9AC5B39F2F412E31EF7F7F0610C2AFE150FA56A5E3CF9DACA6C96F3BC6B57D56B2869019C5114247C080752E4D42B1A0E34302B69B8516E8FB93BE58CC45F6E5ADB47A89A00050A12D560BEEA8997F5A0FA526C107BA34ECB0C678079C6DD4C1F4666BBD45733E019C292A17661B79E6AEED002EF4F6E7F4D569690E140C8BA1BA47E626499E01DA1EACDA4B917507A472DDB03A86734994C4B16551C5DFED3C8C976D15B5BF68CC6C982355930E37F096629E6F3BDC8027C722C12EF76854F1C607341E48FBF8C9064EB48EFDA87E1D111B557FBE7A15A580EDD87AC2CEC0EB25BE057FC20D578DF34632977F4698D58B2025C50AD4AD77D16D32E6157F89F58C692A83279A2EB58F8E448A13AA32B8C3DF07A58100EC4BB319F824446ECDD643C4A7F959CBA4E356A9E5DB7332107B2EB478703BF44383DDF80CA297F5E52A4424AF64B50CAB4E9C95C7288B96F8E77CDC63D07C6394853DF32F926652A12122B5531F90CFDFDAAC5D0642F84CF3901717B652122E8622CF31C06D134AD921EC80D175BBFC45B855EB9ABF001686BC52730F754DBFAE781BB629F1E530632D813AA256D0063202AEEE0AB64C7829C1A6C4702E27C88219FF31500D8F76BEFE4AEF726D6E3B708CAEE209F7 +20241129215808 2 6 100 6143 2 D530FFAD12BC56C29F02BEFEC6CFD700AE6DA852D7256FC0A8978C13FABF9851425A26917CD40A9919A06A5B17FA05456642891442CCBBBD9BB5B74068213AA6F029B3419F6B2CCB828CF9F6F0069F43A2496921ED8133BF2D9C598486282EB38B3B6E849B7D80B33869CDE1D71379C694BB9C229B5CCE5E96692F81DA73EC38942CE60A81657F34A6B1B536ADEADD76144A209815A88E081E0B96438B11A34E4F8082ACC6DD77D787EEA90E1764F7393D3869707FCFCD4BFEEA3582BBD39C17E2CE70B6A193700A055A50D2F5ED473DD9B4401C2138BAD8FA3331BDD4FF79E230C10B13FFE7CCDB3210F8DB42147BB8349CAEA97EBCBC708B9CE16360D573D3327BBCAA6387234E9A4DCB2E67784408ADB72B2E05643520211C581EBB38E57C2F69C9034143DBAB4C13221D501B892918779C6E9AC5B39F2F412E31EF7F7F0610C2AFE150FA56A5E3CF9DACA6C96F3BC6B57D56B2869019C5114247C080752E4D42B1A0E34302B69B8516E8FB93BE58CC45F6E5ADB47A89A00050A12D560BEEA8997F5A0FA526C107BA34ECB0C678079C6DD4C1F4666BBD45733E019C292A17661B79E6AEED002EF4F6E7F4D569690E140C8BA1BA47E626499E01DA1EACDA4B917507A472DDB03A86734994C4B16551C5DFED3C8C976D15B5BF68CC6C982355930E37F096629E6F3BDC8027C722C12EF76854F1C607341E48FBF8C9064EB48EFDA87E1D111B557FBE7A15A580EDD87AC2CEC0EB25BE057FC20D578DF34632977F4698D58B2025C50AD4AD77D16D32E6157F89F58C692A83279A2EB58F8E448A13AA32B8C3DF07A58100EC4BB319F824446ECDD643C4A7F959CBA4E356A9E5DB7332107B2EB478703BF44383DDF80CA297F5E52A4424AF64B50CAB4E9C95C7288B96F8E77CDC63D07C6394853DF32F926652A12122B5531F90CFDFDAAC5D0642F84CF3901717B652122E8622CF31C06D134AD921EC80D175BBFC45B855EB9ABF001686BC52730F754DBFAE781BB629F1E530632D813AA256D0063202AEEE0AB64C7829C1A6C4702E27C88219FF31500D8F76BEFE4AEF726D6E3B708CB1F2A1D3 +20241129221635 2 6 100 6143 2 D530FFAD12BC56C29F02BEFEC6CFD700AE6DA852D7256FC0A8978C13FABF9851425A26917CD40A9919A06A5B17FA05456642891442CCBBBD9BB5B74068213AA6F029B3419F6B2CCB828CF9F6F0069F43A2496921ED8133BF2D9C598486282EB38B3B6E849B7D80B33869CDE1D71379C694BB9C229B5CCE5E96692F81DA73EC38942CE60A81657F34A6B1B536ADEADD76144A209815A88E081E0B96438B11A34E4F8082ACC6DD77D787EEA90E1764F7393D3869707FCFCD4BFEEA3582BBD39C17E2CE70B6A193700A055A50D2F5ED473DD9B4401C2138BAD8FA3331BDD4FF79E230C10B13FFE7CCDB3210F8DB42147BB8349CAEA97EBCBC708B9CE16360D573D3327BBCAA6387234E9A4DCB2E67784408ADB72B2E05643520211C581EBB38E57C2F69C9034143DBAB4C13221D501B892918779C6E9AC5B39F2F412E31EF7F7F0610C2AFE150FA56A5E3CF9DACA6C96F3BC6B57D56B2869019C5114247C080752E4D42B1A0E34302B69B8516E8FB93BE58CC45F6E5ADB47A89A00050A12D560BEEA8997F5A0FA526C107BA34ECB0C678079C6DD4C1F4666BBD45733E019C292A17661B79E6AEED002EF4F6E7F4D569690E140C8BA1BA47E626499E01DA1EACDA4B917507A472DDB03A86734994C4B16551C5DFED3C8C976D15B5BF68CC6C982355930E37F096629E6F3BDC8027C722C12EF76854F1C607341E48FBF8C9064EB48EFDA87E1D111B557FBE7A15A580EDD87AC2CEC0EB25BE057FC20D578DF34632977F4698D58B2025C50AD4AD77D16D32E6157F89F58C692A83279A2EB58F8E448A13AA32B8C3DF07A58100EC4BB319F824446ECDD643C4A7F959CBA4E356A9E5DB7332107B2EB478703BF44383DDF80CA297F5E52A4424AF64B50CAB4E9C95C7288B96F8E77CDC63D07C6394853DF32F926652A12122B5531F90CFDFDAAC5D0642F84CF3901717B652122E8622CF31C06D134AD921EC80D175BBFC45B855EB9ABF001686BC52730F754DBFAE781BB629F1E530632D813AA256D0063202AEEE0AB64C7829C1A6C4702E27C88219FF31500D8F76BEFE4AEF726D6E3B708CB440830B +20241129222503 2 6 100 6143 5 D530FFAD12BC56C29F02BEFEC6CFD700AE6DA852D7256FC0A8978C13FABF9851425A26917CD40A9919A06A5B17FA05456642891442CCBBBD9BB5B74068213AA6F029B3419F6B2CCB828CF9F6F0069F43A2496921ED8133BF2D9C598486282EB38B3B6E849B7D80B33869CDE1D71379C694BB9C229B5CCE5E96692F81DA73EC38942CE60A81657F34A6B1B536ADEADD76144A209815A88E081E0B96438B11A34E4F8082ACC6DD77D787EEA90E1764F7393D3869707FCFCD4BFEEA3582BBD39C17E2CE70B6A193700A055A50D2F5ED473DD9B4401C2138BAD8FA3331BDD4FF79E230C10B13FFE7CCDB3210F8DB42147BB8349CAEA97EBCBC708B9CE16360D573D3327BBCAA6387234E9A4DCB2E67784408ADB72B2E05643520211C581EBB38E57C2F69C9034143DBAB4C13221D501B892918779C6E9AC5B39F2F412E31EF7F7F0610C2AFE150FA56A5E3CF9DACA6C96F3BC6B57D56B2869019C5114247C080752E4D42B1A0E34302B69B8516E8FB93BE58CC45F6E5ADB47A89A00050A12D560BEEA8997F5A0FA526C107BA34ECB0C678079C6DD4C1F4666BBD45733E019C292A17661B79E6AEED002EF4F6E7F4D569690E140C8BA1BA47E626499E01DA1EACDA4B917507A472DDB03A86734994C4B16551C5DFED3C8C976D15B5BF68CC6C982355930E37F096629E6F3BDC8027C722C12EF76854F1C607341E48FBF8C9064EB48EFDA87E1D111B557FBE7A15A580EDD87AC2CEC0EB25BE057FC20D578DF34632977F4698D58B2025C50AD4AD77D16D32E6157F89F58C692A83279A2EB58F8E448A13AA32B8C3DF07A58100EC4BB319F824446ECDD643C4A7F959CBA4E356A9E5DB7332107B2EB478703BF44383DDF80CA297F5E52A4424AF64B50CAB4E9C95C7288B96F8E77CDC63D07C6394853DF32F926652A12122B5531F90CFDFDAAC5D0642F84CF3901717B652122E8622CF31C06D134AD921EC80D175BBFC45B855EB9ABF001686BC52730F754DBFAE781BB629F1E530632D813AA256D0063202AEEE0AB64C7829C1A6C4702E27C88219FF31500D8F76BEFE4AEF726D6E3B708CB545F1FF +20241129233015 2 6 100 6143 5 D530FFAD12BC56C29F02BEFEC6CFD700AE6DA852D7256FC0A8978C13FABF9851425A26917CD40A9919A06A5B17FA05456642891442CCBBBD9BB5B74068213AA6F029B3419F6B2CCB828CF9F6F0069F43A2496921ED8133BF2D9C598486282EB38B3B6E849B7D80B33869CDE1D71379C694BB9C229B5CCE5E96692F81DA73EC38942CE60A81657F34A6B1B536ADEADD76144A209815A88E081E0B96438B11A34E4F8082ACC6DD77D787EEA90E1764F7393D3869707FCFCD4BFEEA3582BBD39C17E2CE70B6A193700A055A50D2F5ED473DD9B4401C2138BAD8FA3331BDD4FF79E230C10B13FFE7CCDB3210F8DB42147BB8349CAEA97EBCBC708B9CE16360D573D3327BBCAA6387234E9A4DCB2E67784408ADB72B2E05643520211C581EBB38E57C2F69C9034143DBAB4C13221D501B892918779C6E9AC5B39F2F412E31EF7F7F0610C2AFE150FA56A5E3CF9DACA6C96F3BC6B57D56B2869019C5114247C080752E4D42B1A0E34302B69B8516E8FB93BE58CC45F6E5ADB47A89A00050A12D560BEEA8997F5A0FA526C107BA34ECB0C678079C6DD4C1F4666BBD45733E019C292A17661B79E6AEED002EF4F6E7F4D569690E140C8BA1BA47E626499E01DA1EACDA4B917507A472DDB03A86734994C4B16551C5DFED3C8C976D15B5BF68CC6C982355930E37F096629E6F3BDC8027C722C12EF76854F1C607341E48FBF8C9064EB48EFDA87E1D111B557FBE7A15A580EDD87AC2CEC0EB25BE057FC20D578DF34632977F4698D58B2025C50AD4AD77D16D32E6157F89F58C692A83279A2EB58F8E448A13AA32B8C3DF07A58100EC4BB319F824446ECDD643C4A7F959CBA4E356A9E5DB7332107B2EB478703BF44383DDF80CA297F5E52A4424AF64B50CAB4E9C95C7288B96F8E77CDC63D07C6394853DF32F926652A12122B5531F90CFDFDAAC5D0642F84CF3901717B652122E8622CF31C06D134AD921EC80D175BBFC45B855EB9ABF001686BC52730F754DBFAE781BB629F1E530632D813AA256D0063202AEEE0AB64C7829C1A6C4702E27C88219FF31500D8F76BEFE4AEF726D6E3B708CBD76AB7F +20241129234110 2 6 100 6143 2 D530FFAD12BC56C29F02BEFEC6CFD700AE6DA852D7256FC0A8978C13FABF9851425A26917CD40A9919A06A5B17FA05456642891442CCBBBD9BB5B74068213AA6F029B3419F6B2CCB828CF9F6F0069F43A2496921ED8133BF2D9C598486282EB38B3B6E849B7D80B33869CDE1D71379C694BB9C229B5CCE5E96692F81DA73EC38942CE60A81657F34A6B1B536ADEADD76144A209815A88E081E0B96438B11A34E4F8082ACC6DD77D787EEA90E1764F7393D3869707FCFCD4BFEEA3582BBD39C17E2CE70B6A193700A055A50D2F5ED473DD9B4401C2138BAD8FA3331BDD4FF79E230C10B13FFE7CCDB3210F8DB42147BB8349CAEA97EBCBC708B9CE16360D573D3327BBCAA6387234E9A4DCB2E67784408ADB72B2E05643520211C581EBB38E57C2F69C9034143DBAB4C13221D501B892918779C6E9AC5B39F2F412E31EF7F7F0610C2AFE150FA56A5E3CF9DACA6C96F3BC6B57D56B2869019C5114247C080752E4D42B1A0E34302B69B8516E8FB93BE58CC45F6E5ADB47A89A00050A12D560BEEA8997F5A0FA526C107BA34ECB0C678079C6DD4C1F4666BBD45733E019C292A17661B79E6AEED002EF4F6E7F4D569690E140C8BA1BA47E626499E01DA1EACDA4B917507A472DDB03A86734994C4B16551C5DFED3C8C976D15B5BF68CC6C982355930E37F096629E6F3BDC8027C722C12EF76854F1C607341E48FBF8C9064EB48EFDA87E1D111B557FBE7A15A580EDD87AC2CEC0EB25BE057FC20D578DF34632977F4698D58B2025C50AD4AD77D16D32E6157F89F58C692A83279A2EB58F8E448A13AA32B8C3DF07A58100EC4BB319F824446ECDD643C4A7F959CBA4E356A9E5DB7332107B2EB478703BF44383DDF80CA297F5E52A4424AF64B50CAB4E9C95C7288B96F8E77CDC63D07C6394853DF32F926652A12122B5531F90CFDFDAAC5D0642F84CF3901717B652122E8622CF31C06D134AD921EC80D175BBFC45B855EB9ABF001686BC52730F754DBFAE781BB629F1E530632D813AA256D0063202AEEE0AB64C7829C1A6C4702E27C88219FF31500D8F76BEFE4AEF726D6E3B708CBED26FD3 +20241130004028 2 6 100 7679 2 C4FD13B23C1EF3F1B888E9E24F6E6F0D1E538D5C17287A04247451367BAAC3EB0FF3633A10C1B2BEA19F91DA18C0C52A465FA0F0371A2189AC36BFEA58F33B013352F321A0B71BF61553330EC7735E66BF920F0AB9C918AC6796F3B2C5CC7B0E9F6695400B692026845D93807363115D8E1EF92072B84941DE896DC222F2493FA43169DC5C94E9F7C645CDDC38AC8C8F8790A2078B755BF65EB099CA5682E186E7DE95CBCF7036B0BFC761137EB0B297A140C1683E9A14E78F31935D873DFB2CC33563980FD7C6EB609427A9A63D9A7ECE43889783FAF17D129A4F00A7DBA8FAFCBDD57FA7599C944D03297B7106E02A82D695E8BC0ACC860295F357FD2F60CC4A09E49450CF735A8756174A8E1458E3BE2BEA10F38D2C30E6AD7DBFA6835328A64BDFCA2318E1753C922D3AA467BB770C03BE0D3381E31655F4969009A35E4CF90B1EF5CB71A7BE424E952AEF1368142BB6E5AEECB9F7EC2034179009B7E57DF234CDDC3818BE6E637DAC7F44B109BCAA519CA77B27E4A119712A325ACC29E82C5A3E43CDED00A550ABF99495C802578A6ACB7DBCCCECD3A3857F01A9582671D87C9407409355199D627D316938076334BCDEC6635E0D6696A53E2475AAF9412167245779FA0C89CC3C08BF90313C68710D0153A3B8FA06862B6670E9498296D2C1840812D51FFEADDAE3D714A6EA7D0DAF18C134A0E26AAA99AB8B605E5FAC1814D13F5BCA134DBCF40B5C21F39EF9B4089A759876E5F22DEAF3C64DAA159B9AFEB76109429E3E42FF8DB74EF84954405C4D7B826CFBE041FF996CB053ED44BD32742681CCC843CBD031CD9DDF299EF150378F87B5F67768C77A69F779AABC032BCC3031DDAD83701E475D16040D1E064208D99313C4047BA2AA44E15CF631E4337A47318F34060DAE2ED3FB2F77F26CAF51805D86F82786B8CED61C0A0A7A8CBECD9AE3FDD266BDA632E6F6095A8E2C82A709EF2ACE20D66CC6709A5EF4EBFBA3B020BD15A5451673CA3780A459C277EEA72A1C9EF8502281BF903B2409971DC1F215C899CBBDED194CAB8A5EBB2273E3B67AEEE9A18CD03A1CC46312AAE59AEA0EFB0E5EAC8A62D6C49DC5B5D5CAC7B12CC2B293ED1D258149C6E8ADFB311328C1D5ACD4A92DFC71E9575A62920166893D715358DAE87159E39267079FA5D2EF41D756E01E0D9701BE7F715E4DCEF5667576A883DC034E36022AB62707C4E9FF9C7400BD29770FC07C66BB041F17204A63B6A52177F32B1E8AF15A818E946421552673488AA76253A5CCAEF2368C6464A36DEA011A56FFACF5F592099BADEFA4B7A72059FF1869864BDDBD14B4D32460CFD30E78C4F057F011C6132BC003 +20241130023838 2 6 100 7679 5 C4FD13B23C1EF3F1B888E9E24F6E6F0D1E538D5C17287A04247451367BAAC3EB0FF3633A10C1B2BEA19F91DA18C0C52A465FA0F0371A2189AC36BFEA58F33B013352F321A0B71BF61553330EC7735E66BF920F0AB9C918AC6796F3B2C5CC7B0E9F6695400B692026845D93807363115D8E1EF92072B84941DE896DC222F2493FA43169DC5C94E9F7C645CDDC38AC8C8F8790A2078B755BF65EB099CA5682E186E7DE95CBCF7036B0BFC761137EB0B297A140C1683E9A14E78F31935D873DFB2CC33563980FD7C6EB609427A9A63D9A7ECE43889783FAF17D129A4F00A7DBA8FAFCBDD57FA7599C944D03297B7106E02A82D695E8BC0ACC860295F357FD2F60CC4A09E49450CF735A8756174A8E1458E3BE2BEA10F38D2C30E6AD7DBFA6835328A64BDFCA2318E1753C922D3AA467BB770C03BE0D3381E31655F4969009A35E4CF90B1EF5CB71A7BE424E952AEF1368142BB6E5AEECB9F7EC2034179009B7E57DF234CDDC3818BE6E637DAC7F44B109BCAA519CA77B27E4A119712A325ACC29E82C5A3E43CDED00A550ABF99495C802578A6ACB7DBCCCECD3A3857F01A9582671D87C9407409355199D627D316938076334BCDEC6635E0D6696A53E2475AAF9412167245779FA0C89CC3C08BF90313C68710D0153A3B8FA06862B6670E9498296D2C1840812D51FFEADDAE3D714A6EA7D0DAF18C134A0E26AAA99AB8B605E5FAC1814D13F5BCA134DBCF40B5C21F39EF9B4089A759876E5F22DEAF3C64DAA159B9AFEB76109429E3E42FF8DB74EF84954405C4D7B826CFBE041FF996CB053ED44BD32742681CCC843CBD031CD9DDF299EF150378F87B5F67768C77A69F779AABC032BCC3031DDAD83701E475D16040D1E064208D99313C4047BA2AA44E15CF631E4337A47318F34060DAE2ED3FB2F77F26CAF51805D86F82786B8CED61C0A0A7A8CBECD9AE3FDD266BDA632E6F6095A8E2C82A709EF2ACE20D66CC6709A5EF4EBFBA3B020BD15A5451673CA3780A459C277EEA72A1C9EF8502281BF903B2409971DC1F215C899CBBDED194CAB8A5EBB2273E3B67AEEE9A18CD03A1CC46312AAE59AEA0EFB0E5EAC8A62D6C49DC5B5D5CAC7B12CC2B293ED1D258149C6E8ADFB311328C1D5ACD4A92DFC71E9575A62920166893D715358DAE87159E39267079FA5D2EF41D756E01E0D9701BE7F715E4DCEF5667576A883DC034E36022AB62707C4E9FF9C7400BD29770FC07C66BB041F17204A63B6A52177F32B1E8AF15A818E946421552673488AA76253A5CCAEF2368C6464A36DEA011A56FFACF5F592099BADEFA4B7A72059FF1869864BDDBD14B4D32460CFD30E78C4F057F011C61B09AE47 +20241130030155 2 6 100 7679 2 C4FD13B23C1EF3F1B888E9E24F6E6F0D1E538D5C17287A04247451367BAAC3EB0FF3633A10C1B2BEA19F91DA18C0C52A465FA0F0371A2189AC36BFEA58F33B013352F321A0B71BF61553330EC7735E66BF920F0AB9C918AC6796F3B2C5CC7B0E9F6695400B692026845D93807363115D8E1EF92072B84941DE896DC222F2493FA43169DC5C94E9F7C645CDDC38AC8C8F8790A2078B755BF65EB099CA5682E186E7DE95CBCF7036B0BFC761137EB0B297A140C1683E9A14E78F31935D873DFB2CC33563980FD7C6EB609427A9A63D9A7ECE43889783FAF17D129A4F00A7DBA8FAFCBDD57FA7599C944D03297B7106E02A82D695E8BC0ACC860295F357FD2F60CC4A09E49450CF735A8756174A8E1458E3BE2BEA10F38D2C30E6AD7DBFA6835328A64BDFCA2318E1753C922D3AA467BB770C03BE0D3381E31655F4969009A35E4CF90B1EF5CB71A7BE424E952AEF1368142BB6E5AEECB9F7EC2034179009B7E57DF234CDDC3818BE6E637DAC7F44B109BCAA519CA77B27E4A119712A325ACC29E82C5A3E43CDED00A550ABF99495C802578A6ACB7DBCCCECD3A3857F01A9582671D87C9407409355199D627D316938076334BCDEC6635E0D6696A53E2475AAF9412167245779FA0C89CC3C08BF90313C68710D0153A3B8FA06862B6670E9498296D2C1840812D51FFEADDAE3D714A6EA7D0DAF18C134A0E26AAA99AB8B605E5FAC1814D13F5BCA134DBCF40B5C21F39EF9B4089A759876E5F22DEAF3C64DAA159B9AFEB76109429E3E42FF8DB74EF84954405C4D7B826CFBE041FF996CB053ED44BD32742681CCC843CBD031CD9DDF299EF150378F87B5F67768C77A69F779AABC032BCC3031DDAD83701E475D16040D1E064208D99313C4047BA2AA44E15CF631E4337A47318F34060DAE2ED3FB2F77F26CAF51805D86F82786B8CED61C0A0A7A8CBECD9AE3FDD266BDA632E6F6095A8E2C82A709EF2ACE20D66CC6709A5EF4EBFBA3B020BD15A5451673CA3780A459C277EEA72A1C9EF8502281BF903B2409971DC1F215C899CBBDED194CAB8A5EBB2273E3B67AEEE9A18CD03A1CC46312AAE59AEA0EFB0E5EAC8A62D6C49DC5B5D5CAC7B12CC2B293ED1D258149C6E8ADFB311328C1D5ACD4A92DFC71E9575A62920166893D715358DAE87159E39267079FA5D2EF41D756E01E0D9701BE7F715E4DCEF5667576A883DC034E36022AB62707C4E9FF9C7400BD29770FC07C66BB041F17204A63B6A52177F32B1E8AF15A818E946421552673488AA76253A5CCAEF2368C6464A36DEA011A56FFACF5F592099BADEFA4B7A72059FF1869864BDDBD14B4D32460CFD30E78C4F057F011C61C91151B +20241130032532 2 6 100 7679 2 C4FD13B23C1EF3F1B888E9E24F6E6F0D1E538D5C17287A04247451367BAAC3EB0FF3633A10C1B2BEA19F91DA18C0C52A465FA0F0371A2189AC36BFEA58F33B013352F321A0B71BF61553330EC7735E66BF920F0AB9C918AC6796F3B2C5CC7B0E9F6695400B692026845D93807363115D8E1EF92072B84941DE896DC222F2493FA43169DC5C94E9F7C645CDDC38AC8C8F8790A2078B755BF65EB099CA5682E186E7DE95CBCF7036B0BFC761137EB0B297A140C1683E9A14E78F31935D873DFB2CC33563980FD7C6EB609427A9A63D9A7ECE43889783FAF17D129A4F00A7DBA8FAFCBDD57FA7599C944D03297B7106E02A82D695E8BC0ACC860295F357FD2F60CC4A09E49450CF735A8756174A8E1458E3BE2BEA10F38D2C30E6AD7DBFA6835328A64BDFCA2318E1753C922D3AA467BB770C03BE0D3381E31655F4969009A35E4CF90B1EF5CB71A7BE424E952AEF1368142BB6E5AEECB9F7EC2034179009B7E57DF234CDDC3818BE6E637DAC7F44B109BCAA519CA77B27E4A119712A325ACC29E82C5A3E43CDED00A550ABF99495C802578A6ACB7DBCCCECD3A3857F01A9582671D87C9407409355199D627D316938076334BCDEC6635E0D6696A53E2475AAF9412167245779FA0C89CC3C08BF90313C68710D0153A3B8FA06862B6670E9498296D2C1840812D51FFEADDAE3D714A6EA7D0DAF18C134A0E26AAA99AB8B605E5FAC1814D13F5BCA134DBCF40B5C21F39EF9B4089A759876E5F22DEAF3C64DAA159B9AFEB76109429E3E42FF8DB74EF84954405C4D7B826CFBE041FF996CB053ED44BD32742681CCC843CBD031CD9DDF299EF150378F87B5F67768C77A69F779AABC032BCC3031DDAD83701E475D16040D1E064208D99313C4047BA2AA44E15CF631E4337A47318F34060DAE2ED3FB2F77F26CAF51805D86F82786B8CED61C0A0A7A8CBECD9AE3FDD266BDA632E6F6095A8E2C82A709EF2ACE20D66CC6709A5EF4EBFBA3B020BD15A5451673CA3780A459C277EEA72A1C9EF8502281BF903B2409971DC1F215C899CBBDED194CAB8A5EBB2273E3B67AEEE9A18CD03A1CC46312AAE59AEA0EFB0E5EAC8A62D6C49DC5B5D5CAC7B12CC2B293ED1D258149C6E8ADFB311328C1D5ACD4A92DFC71E9575A62920166893D715358DAE87159E39267079FA5D2EF41D756E01E0D9701BE7F715E4DCEF5667576A883DC034E36022AB62707C4E9FF9C7400BD29770FC07C66BB041F17204A63B6A52177F32B1E8AF15A818E946421552673488AA76253A5CCAEF2368C6464A36DEA011A56FFACF5F592099BADEFA4B7A72059FF1869864BDDBD14B4D32460CFD30E78C4F057F011C61E1854B3 +20241130035131 2 6 100 7679 2 C4FD13B23C1EF3F1B888E9E24F6E6F0D1E538D5C17287A04247451367BAAC3EB0FF3633A10C1B2BEA19F91DA18C0C52A465FA0F0371A2189AC36BFEA58F33B013352F321A0B71BF61553330EC7735E66BF920F0AB9C918AC6796F3B2C5CC7B0E9F6695400B692026845D93807363115D8E1EF92072B84941DE896DC222F2493FA43169DC5C94E9F7C645CDDC38AC8C8F8790A2078B755BF65EB099CA5682E186E7DE95CBCF7036B0BFC761137EB0B297A140C1683E9A14E78F31935D873DFB2CC33563980FD7C6EB609427A9A63D9A7ECE43889783FAF17D129A4F00A7DBA8FAFCBDD57FA7599C944D03297B7106E02A82D695E8BC0ACC860295F357FD2F60CC4A09E49450CF735A8756174A8E1458E3BE2BEA10F38D2C30E6AD7DBFA6835328A64BDFCA2318E1753C922D3AA467BB770C03BE0D3381E31655F4969009A35E4CF90B1EF5CB71A7BE424E952AEF1368142BB6E5AEECB9F7EC2034179009B7E57DF234CDDC3818BE6E637DAC7F44B109BCAA519CA77B27E4A119712A325ACC29E82C5A3E43CDED00A550ABF99495C802578A6ACB7DBCCCECD3A3857F01A9582671D87C9407409355199D627D316938076334BCDEC6635E0D6696A53E2475AAF9412167245779FA0C89CC3C08BF90313C68710D0153A3B8FA06862B6670E9498296D2C1840812D51FFEADDAE3D714A6EA7D0DAF18C134A0E26AAA99AB8B605E5FAC1814D13F5BCA134DBCF40B5C21F39EF9B4089A759876E5F22DEAF3C64DAA159B9AFEB76109429E3E42FF8DB74EF84954405C4D7B826CFBE041FF996CB053ED44BD32742681CCC843CBD031CD9DDF299EF150378F87B5F67768C77A69F779AABC032BCC3031DDAD83701E475D16040D1E064208D99313C4047BA2AA44E15CF631E4337A47318F34060DAE2ED3FB2F77F26CAF51805D86F82786B8CED61C0A0A7A8CBECD9AE3FDD266BDA632E6F6095A8E2C82A709EF2ACE20D66CC6709A5EF4EBFBA3B020BD15A5451673CA3780A459C277EEA72A1C9EF8502281BF903B2409971DC1F215C899CBBDED194CAB8A5EBB2273E3B67AEEE9A18CD03A1CC46312AAE59AEA0EFB0E5EAC8A62D6C49DC5B5D5CAC7B12CC2B293ED1D258149C6E8ADFB311328C1D5ACD4A92DFC71E9575A62920166893D715358DAE87159E39267079FA5D2EF41D756E01E0D9701BE7F715E4DCEF5667576A883DC034E36022AB62707C4E9FF9C7400BD29770FC07C66BB041F17204A63B6A52177F32B1E8AF15A818E946421552673488AA76253A5CCAEF2368C6464A36DEA011A56FFACF5F592099BADEFA4B7A72059FF1869864BDDBD14B4D32460CFD30E78C4F057F011C61FD56C8B +20241130035951 2 6 100 7679 5 C4FD13B23C1EF3F1B888E9E24F6E6F0D1E538D5C17287A04247451367BAAC3EB0FF3633A10C1B2BEA19F91DA18C0C52A465FA0F0371A2189AC36BFEA58F33B013352F321A0B71BF61553330EC7735E66BF920F0AB9C918AC6796F3B2C5CC7B0E9F6695400B692026845D93807363115D8E1EF92072B84941DE896DC222F2493FA43169DC5C94E9F7C645CDDC38AC8C8F8790A2078B755BF65EB099CA5682E186E7DE95CBCF7036B0BFC761137EB0B297A140C1683E9A14E78F31935D873DFB2CC33563980FD7C6EB609427A9A63D9A7ECE43889783FAF17D129A4F00A7DBA8FAFCBDD57FA7599C944D03297B7106E02A82D695E8BC0ACC860295F357FD2F60CC4A09E49450CF735A8756174A8E1458E3BE2BEA10F38D2C30E6AD7DBFA6835328A64BDFCA2318E1753C922D3AA467BB770C03BE0D3381E31655F4969009A35E4CF90B1EF5CB71A7BE424E952AEF1368142BB6E5AEECB9F7EC2034179009B7E57DF234CDDC3818BE6E637DAC7F44B109BCAA519CA77B27E4A119712A325ACC29E82C5A3E43CDED00A550ABF99495C802578A6ACB7DBCCCECD3A3857F01A9582671D87C9407409355199D627D316938076334BCDEC6635E0D6696A53E2475AAF9412167245779FA0C89CC3C08BF90313C68710D0153A3B8FA06862B6670E9498296D2C1840812D51FFEADDAE3D714A6EA7D0DAF18C134A0E26AAA99AB8B605E5FAC1814D13F5BCA134DBCF40B5C21F39EF9B4089A759876E5F22DEAF3C64DAA159B9AFEB76109429E3E42FF8DB74EF84954405C4D7B826CFBE041FF996CB053ED44BD32742681CCC843CBD031CD9DDF299EF150378F87B5F67768C77A69F779AABC032BCC3031DDAD83701E475D16040D1E064208D99313C4047BA2AA44E15CF631E4337A47318F34060DAE2ED3FB2F77F26CAF51805D86F82786B8CED61C0A0A7A8CBECD9AE3FDD266BDA632E6F6095A8E2C82A709EF2ACE20D66CC6709A5EF4EBFBA3B020BD15A5451673CA3780A459C277EEA72A1C9EF8502281BF903B2409971DC1F215C899CBBDED194CAB8A5EBB2273E3B67AEEE9A18CD03A1CC46312AAE59AEA0EFB0E5EAC8A62D6C49DC5B5D5CAC7B12CC2B293ED1D258149C6E8ADFB311328C1D5ACD4A92DFC71E9575A62920166893D715358DAE87159E39267079FA5D2EF41D756E01E0D9701BE7F715E4DCEF5667576A883DC034E36022AB62707C4E9FF9C7400BD29770FC07C66BB041F17204A63B6A52177F32B1E8AF15A818E946421552673488AA76253A5CCAEF2368C6464A36DEA011A56FFACF5F592099BADEFA4B7A72059FF1869864BDDBD14B4D32460CFD30E78C4F057F011C6205D0C3F +20241130040156 2 6 100 7679 2 C4FD13B23C1EF3F1B888E9E24F6E6F0D1E538D5C17287A04247451367BAAC3EB0FF3633A10C1B2BEA19F91DA18C0C52A465FA0F0371A2189AC36BFEA58F33B013352F321A0B71BF61553330EC7735E66BF920F0AB9C918AC6796F3B2C5CC7B0E9F6695400B692026845D93807363115D8E1EF92072B84941DE896DC222F2493FA43169DC5C94E9F7C645CDDC38AC8C8F8790A2078B755BF65EB099CA5682E186E7DE95CBCF7036B0BFC761137EB0B297A140C1683E9A14E78F31935D873DFB2CC33563980FD7C6EB609427A9A63D9A7ECE43889783FAF17D129A4F00A7DBA8FAFCBDD57FA7599C944D03297B7106E02A82D695E8BC0ACC860295F357FD2F60CC4A09E49450CF735A8756174A8E1458E3BE2BEA10F38D2C30E6AD7DBFA6835328A64BDFCA2318E1753C922D3AA467BB770C03BE0D3381E31655F4969009A35E4CF90B1EF5CB71A7BE424E952AEF1368142BB6E5AEECB9F7EC2034179009B7E57DF234CDDC3818BE6E637DAC7F44B109BCAA519CA77B27E4A119712A325ACC29E82C5A3E43CDED00A550ABF99495C802578A6ACB7DBCCCECD3A3857F01A9582671D87C9407409355199D627D316938076334BCDEC6635E0D6696A53E2475AAF9412167245779FA0C89CC3C08BF90313C68710D0153A3B8FA06862B6670E9498296D2C1840812D51FFEADDAE3D714A6EA7D0DAF18C134A0E26AAA99AB8B605E5FAC1814D13F5BCA134DBCF40B5C21F39EF9B4089A759876E5F22DEAF3C64DAA159B9AFEB76109429E3E42FF8DB74EF84954405C4D7B826CFBE041FF996CB053ED44BD32742681CCC843CBD031CD9DDF299EF150378F87B5F67768C77A69F779AABC032BCC3031DDAD83701E475D16040D1E064208D99313C4047BA2AA44E15CF631E4337A47318F34060DAE2ED3FB2F77F26CAF51805D86F82786B8CED61C0A0A7A8CBECD9AE3FDD266BDA632E6F6095A8E2C82A709EF2ACE20D66CC6709A5EF4EBFBA3B020BD15A5451673CA3780A459C277EEA72A1C9EF8502281BF903B2409971DC1F215C899CBBDED194CAB8A5EBB2273E3B67AEEE9A18CD03A1CC46312AAE59AEA0EFB0E5EAC8A62D6C49DC5B5D5CAC7B12CC2B293ED1D258149C6E8ADFB311328C1D5ACD4A92DFC71E9575A62920166893D715358DAE87159E39267079FA5D2EF41D756E01E0D9701BE7F715E4DCEF5667576A883DC034E36022AB62707C4E9FF9C7400BD29770FC07C66BB041F17204A63B6A52177F32B1E8AF15A818E946421552673488AA76253A5CCAEF2368C6464A36DEA011A56FFACF5F592099BADEFA4B7A72059FF1869864BDDBD14B4D32460CFD30E78C4F057F011C6207AF313 +20241130042927 2 6 100 7679 2 C4FD13B23C1EF3F1B888E9E24F6E6F0D1E538D5C17287A04247451367BAAC3EB0FF3633A10C1B2BEA19F91DA18C0C52A465FA0F0371A2189AC36BFEA58F33B013352F321A0B71BF61553330EC7735E66BF920F0AB9C918AC6796F3B2C5CC7B0E9F6695400B692026845D93807363115D8E1EF92072B84941DE896DC222F2493FA43169DC5C94E9F7C645CDDC38AC8C8F8790A2078B755BF65EB099CA5682E186E7DE95CBCF7036B0BFC761137EB0B297A140C1683E9A14E78F31935D873DFB2CC33563980FD7C6EB609427A9A63D9A7ECE43889783FAF17D129A4F00A7DBA8FAFCBDD57FA7599C944D03297B7106E02A82D695E8BC0ACC860295F357FD2F60CC4A09E49450CF735A8756174A8E1458E3BE2BEA10F38D2C30E6AD7DBFA6835328A64BDFCA2318E1753C922D3AA467BB770C03BE0D3381E31655F4969009A35E4CF90B1EF5CB71A7BE424E952AEF1368142BB6E5AEECB9F7EC2034179009B7E57DF234CDDC3818BE6E637DAC7F44B109BCAA519CA77B27E4A119712A325ACC29E82C5A3E43CDED00A550ABF99495C802578A6ACB7DBCCCECD3A3857F01A9582671D87C9407409355199D627D316938076334BCDEC6635E0D6696A53E2475AAF9412167245779FA0C89CC3C08BF90313C68710D0153A3B8FA06862B6670E9498296D2C1840812D51FFEADDAE3D714A6EA7D0DAF18C134A0E26AAA99AB8B605E5FAC1814D13F5BCA134DBCF40B5C21F39EF9B4089A759876E5F22DEAF3C64DAA159B9AFEB76109429E3E42FF8DB74EF84954405C4D7B826CFBE041FF996CB053ED44BD32742681CCC843CBD031CD9DDF299EF150378F87B5F67768C77A69F779AABC032BCC3031DDAD83701E475D16040D1E064208D99313C4047BA2AA44E15CF631E4337A47318F34060DAE2ED3FB2F77F26CAF51805D86F82786B8CED61C0A0A7A8CBECD9AE3FDD266BDA632E6F6095A8E2C82A709EF2ACE20D66CC6709A5EF4EBFBA3B020BD15A5451673CA3780A459C277EEA72A1C9EF8502281BF903B2409971DC1F215C899CBBDED194CAB8A5EBB2273E3B67AEEE9A18CD03A1CC46312AAE59AEA0EFB0E5EAC8A62D6C49DC5B5D5CAC7B12CC2B293ED1D258149C6E8ADFB311328C1D5ACD4A92DFC71E9575A62920166893D715358DAE87159E39267079FA5D2EF41D756E01E0D9701BE7F715E4DCEF5667576A883DC034E36022AB62707C4E9FF9C7400BD29770FC07C66BB041F17204A63B6A52177F32B1E8AF15A818E946421552673488AA76253A5CCAEF2368C6464A36DEA011A56FFACF5F592099BADEFA4B7A72059FF1869864BDDBD14B4D32460CFD30E78C4F057F011C6224FB4F3 +20241130043039 2 6 100 7679 5 C4FD13B23C1EF3F1B888E9E24F6E6F0D1E538D5C17287A04247451367BAAC3EB0FF3633A10C1B2BEA19F91DA18C0C52A465FA0F0371A2189AC36BFEA58F33B013352F321A0B71BF61553330EC7735E66BF920F0AB9C918AC6796F3B2C5CC7B0E9F6695400B692026845D93807363115D8E1EF92072B84941DE896DC222F2493FA43169DC5C94E9F7C645CDDC38AC8C8F8790A2078B755BF65EB099CA5682E186E7DE95CBCF7036B0BFC761137EB0B297A140C1683E9A14E78F31935D873DFB2CC33563980FD7C6EB609427A9A63D9A7ECE43889783FAF17D129A4F00A7DBA8FAFCBDD57FA7599C944D03297B7106E02A82D695E8BC0ACC860295F357FD2F60CC4A09E49450CF735A8756174A8E1458E3BE2BEA10F38D2C30E6AD7DBFA6835328A64BDFCA2318E1753C922D3AA467BB770C03BE0D3381E31655F4969009A35E4CF90B1EF5CB71A7BE424E952AEF1368142BB6E5AEECB9F7EC2034179009B7E57DF234CDDC3818BE6E637DAC7F44B109BCAA519CA77B27E4A119712A325ACC29E82C5A3E43CDED00A550ABF99495C802578A6ACB7DBCCCECD3A3857F01A9582671D87C9407409355199D627D316938076334BCDEC6635E0D6696A53E2475AAF9412167245779FA0C89CC3C08BF90313C68710D0153A3B8FA06862B6670E9498296D2C1840812D51FFEADDAE3D714A6EA7D0DAF18C134A0E26AAA99AB8B605E5FAC1814D13F5BCA134DBCF40B5C21F39EF9B4089A759876E5F22DEAF3C64DAA159B9AFEB76109429E3E42FF8DB74EF84954405C4D7B826CFBE041FF996CB053ED44BD32742681CCC843CBD031CD9DDF299EF150378F87B5F67768C77A69F779AABC032BCC3031DDAD83701E475D16040D1E064208D99313C4047BA2AA44E15CF631E4337A47318F34060DAE2ED3FB2F77F26CAF51805D86F82786B8CED61C0A0A7A8CBECD9AE3FDD266BDA632E6F6095A8E2C82A709EF2ACE20D66CC6709A5EF4EBFBA3B020BD15A5451673CA3780A459C277EEA72A1C9EF8502281BF903B2409971DC1F215C899CBBDED194CAB8A5EBB2273E3B67AEEE9A18CD03A1CC46312AAE59AEA0EFB0E5EAC8A62D6C49DC5B5D5CAC7B12CC2B293ED1D258149C6E8ADFB311328C1D5ACD4A92DFC71E9575A62920166893D715358DAE87159E39267079FA5D2EF41D756E01E0D9701BE7F715E4DCEF5667576A883DC034E36022AB62707C4E9FF9C7400BD29770FC07C66BB041F17204A63B6A52177F32B1E8AF15A818E946421552673488AA76253A5CCAEF2368C6464A36DEA011A56FFACF5F592099BADEFA4B7A72059FF1869864BDDBD14B4D32460CFD30E78C4F057F011C6225C64C7 +20241130054524 2 6 100 7679 2 C4FD13B23C1EF3F1B888E9E24F6E6F0D1E538D5C17287A04247451367BAAC3EB0FF3633A10C1B2BEA19F91DA18C0C52A465FA0F0371A2189AC36BFEA58F33B013352F321A0B71BF61553330EC7735E66BF920F0AB9C918AC6796F3B2C5CC7B0E9F6695400B692026845D93807363115D8E1EF92072B84941DE896DC222F2493FA43169DC5C94E9F7C645CDDC38AC8C8F8790A2078B755BF65EB099CA5682E186E7DE95CBCF7036B0BFC761137EB0B297A140C1683E9A14E78F31935D873DFB2CC33563980FD7C6EB609427A9A63D9A7ECE43889783FAF17D129A4F00A7DBA8FAFCBDD57FA7599C944D03297B7106E02A82D695E8BC0ACC860295F357FD2F60CC4A09E49450CF735A8756174A8E1458E3BE2BEA10F38D2C30E6AD7DBFA6835328A64BDFCA2318E1753C922D3AA467BB770C03BE0D3381E31655F4969009A35E4CF90B1EF5CB71A7BE424E952AEF1368142BB6E5AEECB9F7EC2034179009B7E57DF234CDDC3818BE6E637DAC7F44B109BCAA519CA77B27E4A119712A325ACC29E82C5A3E43CDED00A550ABF99495C802578A6ACB7DBCCCECD3A3857F01A9582671D87C9407409355199D627D316938076334BCDEC6635E0D6696A53E2475AAF9412167245779FA0C89CC3C08BF90313C68710D0153A3B8FA06862B6670E9498296D2C1840812D51FFEADDAE3D714A6EA7D0DAF18C134A0E26AAA99AB8B605E5FAC1814D13F5BCA134DBCF40B5C21F39EF9B4089A759876E5F22DEAF3C64DAA159B9AFEB76109429E3E42FF8DB74EF84954405C4D7B826CFBE041FF996CB053ED44BD32742681CCC843CBD031CD9DDF299EF150378F87B5F67768C77A69F779AABC032BCC3031DDAD83701E475D16040D1E064208D99313C4047BA2AA44E15CF631E4337A47318F34060DAE2ED3FB2F77F26CAF51805D86F82786B8CED61C0A0A7A8CBECD9AE3FDD266BDA632E6F6095A8E2C82A709EF2ACE20D66CC6709A5EF4EBFBA3B020BD15A5451673CA3780A459C277EEA72A1C9EF8502281BF903B2409971DC1F215C899CBBDED194CAB8A5EBB2273E3B67AEEE9A18CD03A1CC46312AAE59AEA0EFB0E5EAC8A62D6C49DC5B5D5CAC7B12CC2B293ED1D258149C6E8ADFB311328C1D5ACD4A92DFC71E9575A62920166893D715358DAE87159E39267079FA5D2EF41D756E01E0D9701BE7F715E4DCEF5667576A883DC034E36022AB62707C4E9FF9C7400BD29770FC07C66BB041F17204A63B6A52177F32B1E8AF15A818E946421552673488AA76253A5CCAEF2368C6464A36DEA011A56FFACF5F592099BADEFA4B7A72059FF1869864BDDBD14B4D32460CFD30E78C4F057F011C62750439B +20241130063335 2 6 100 7679 5 C4FD13B23C1EF3F1B888E9E24F6E6F0D1E538D5C17287A04247451367BAAC3EB0FF3633A10C1B2BEA19F91DA18C0C52A465FA0F0371A2189AC36BFEA58F33B013352F321A0B71BF61553330EC7735E66BF920F0AB9C918AC6796F3B2C5CC7B0E9F6695400B692026845D93807363115D8E1EF92072B84941DE896DC222F2493FA43169DC5C94E9F7C645CDDC38AC8C8F8790A2078B755BF65EB099CA5682E186E7DE95CBCF7036B0BFC761137EB0B297A140C1683E9A14E78F31935D873DFB2CC33563980FD7C6EB609427A9A63D9A7ECE43889783FAF17D129A4F00A7DBA8FAFCBDD57FA7599C944D03297B7106E02A82D695E8BC0ACC860295F357FD2F60CC4A09E49450CF735A8756174A8E1458E3BE2BEA10F38D2C30E6AD7DBFA6835328A64BDFCA2318E1753C922D3AA467BB770C03BE0D3381E31655F4969009A35E4CF90B1EF5CB71A7BE424E952AEF1368142BB6E5AEECB9F7EC2034179009B7E57DF234CDDC3818BE6E637DAC7F44B109BCAA519CA77B27E4A119712A325ACC29E82C5A3E43CDED00A550ABF99495C802578A6ACB7DBCCCECD3A3857F01A9582671D87C9407409355199D627D316938076334BCDEC6635E0D6696A53E2475AAF9412167245779FA0C89CC3C08BF90313C68710D0153A3B8FA06862B6670E9498296D2C1840812D51FFEADDAE3D714A6EA7D0DAF18C134A0E26AAA99AB8B605E5FAC1814D13F5BCA134DBCF40B5C21F39EF9B4089A759876E5F22DEAF3C64DAA159B9AFEB76109429E3E42FF8DB74EF84954405C4D7B826CFBE041FF996CB053ED44BD32742681CCC843CBD031CD9DDF299EF150378F87B5F67768C77A69F779AABC032BCC3031DDAD83701E475D16040D1E064208D99313C4047BA2AA44E15CF631E4337A47318F34060DAE2ED3FB2F77F26CAF51805D86F82786B8CED61C0A0A7A8CBECD9AE3FDD266BDA632E6F6095A8E2C82A709EF2ACE20D66CC6709A5EF4EBFBA3B020BD15A5451673CA3780A459C277EEA72A1C9EF8502281BF903B2409971DC1F215C899CBBDED194CAB8A5EBB2273E3B67AEEE9A18CD03A1CC46312AAE59AEA0EFB0E5EAC8A62D6C49DC5B5D5CAC7B12CC2B293ED1D258149C6E8ADFB311328C1D5ACD4A92DFC71E9575A62920166893D715358DAE87159E39267079FA5D2EF41D756E01E0D9701BE7F715E4DCEF5667576A883DC034E36022AB62707C4E9FF9C7400BD29770FC07C66BB041F17204A63B6A52177F32B1E8AF15A818E946421552673488AA76253A5CCAEF2368C6464A36DEA011A56FFACF5F592099BADEFA4B7A72059FF1869864BDDBD14B4D32460CFD30E78C4F057F011C62A7BB5C7 +20241130074248 2 6 100 7679 2 C4FD13B23C1EF3F1B888E9E24F6E6F0D1E538D5C17287A04247451367BAAC3EB0FF3633A10C1B2BEA19F91DA18C0C52A465FA0F0371A2189AC36BFEA58F33B013352F321A0B71BF61553330EC7735E66BF920F0AB9C918AC6796F3B2C5CC7B0E9F6695400B692026845D93807363115D8E1EF92072B84941DE896DC222F2493FA43169DC5C94E9F7C645CDDC38AC8C8F8790A2078B755BF65EB099CA5682E186E7DE95CBCF7036B0BFC761137EB0B297A140C1683E9A14E78F31935D873DFB2CC33563980FD7C6EB609427A9A63D9A7ECE43889783FAF17D129A4F00A7DBA8FAFCBDD57FA7599C944D03297B7106E02A82D695E8BC0ACC860295F357FD2F60CC4A09E49450CF735A8756174A8E1458E3BE2BEA10F38D2C30E6AD7DBFA6835328A64BDFCA2318E1753C922D3AA467BB770C03BE0D3381E31655F4969009A35E4CF90B1EF5CB71A7BE424E952AEF1368142BB6E5AEECB9F7EC2034179009B7E57DF234CDDC3818BE6E637DAC7F44B109BCAA519CA77B27E4A119712A325ACC29E82C5A3E43CDED00A550ABF99495C802578A6ACB7DBCCCECD3A3857F01A9582671D87C9407409355199D627D316938076334BCDEC6635E0D6696A53E2475AAF9412167245779FA0C89CC3C08BF90313C68710D0153A3B8FA06862B6670E9498296D2C1840812D51FFEADDAE3D714A6EA7D0DAF18C134A0E26AAA99AB8B605E5FAC1814D13F5BCA134DBCF40B5C21F39EF9B4089A759876E5F22DEAF3C64DAA159B9AFEB76109429E3E42FF8DB74EF84954405C4D7B826CFBE041FF996CB053ED44BD32742681CCC843CBD031CD9DDF299EF150378F87B5F67768C77A69F779AABC032BCC3031DDAD83701E475D16040D1E064208D99313C4047BA2AA44E15CF631E4337A47318F34060DAE2ED3FB2F77F26CAF51805D86F82786B8CED61C0A0A7A8CBECD9AE3FDD266BDA632E6F6095A8E2C82A709EF2ACE20D66CC6709A5EF4EBFBA3B020BD15A5451673CA3780A459C277EEA72A1C9EF8502281BF903B2409971DC1F215C899CBBDED194CAB8A5EBB2273E3B67AEEE9A18CD03A1CC46312AAE59AEA0EFB0E5EAC8A62D6C49DC5B5D5CAC7B12CC2B293ED1D258149C6E8ADFB311328C1D5ACD4A92DFC71E9575A62920166893D715358DAE87159E39267079FA5D2EF41D756E01E0D9701BE7F715E4DCEF5667576A883DC034E36022AB62707C4E9FF9C7400BD29770FC07C66BB041F17204A63B6A52177F32B1E8AF15A818E946421552673488AA76253A5CCAEF2368C6464A36DEA011A56FFACF5F592099BADEFA4B7A72059FF1869864BDDBD14B4D32460CFD30E78C4F057F011C62F113613 +20241130074437 2 6 100 7679 2 C4FD13B23C1EF3F1B888E9E24F6E6F0D1E538D5C17287A04247451367BAAC3EB0FF3633A10C1B2BEA19F91DA18C0C52A465FA0F0371A2189AC36BFEA58F33B013352F321A0B71BF61553330EC7735E66BF920F0AB9C918AC6796F3B2C5CC7B0E9F6695400B692026845D93807363115D8E1EF92072B84941DE896DC222F2493FA43169DC5C94E9F7C645CDDC38AC8C8F8790A2078B755BF65EB099CA5682E186E7DE95CBCF7036B0BFC761137EB0B297A140C1683E9A14E78F31935D873DFB2CC33563980FD7C6EB609427A9A63D9A7ECE43889783FAF17D129A4F00A7DBA8FAFCBDD57FA7599C944D03297B7106E02A82D695E8BC0ACC860295F357FD2F60CC4A09E49450CF735A8756174A8E1458E3BE2BEA10F38D2C30E6AD7DBFA6835328A64BDFCA2318E1753C922D3AA467BB770C03BE0D3381E31655F4969009A35E4CF90B1EF5CB71A7BE424E952AEF1368142BB6E5AEECB9F7EC2034179009B7E57DF234CDDC3818BE6E637DAC7F44B109BCAA519CA77B27E4A119712A325ACC29E82C5A3E43CDED00A550ABF99495C802578A6ACB7DBCCCECD3A3857F01A9582671D87C9407409355199D627D316938076334BCDEC6635E0D6696A53E2475AAF9412167245779FA0C89CC3C08BF90313C68710D0153A3B8FA06862B6670E9498296D2C1840812D51FFEADDAE3D714A6EA7D0DAF18C134A0E26AAA99AB8B605E5FAC1814D13F5BCA134DBCF40B5C21F39EF9B4089A759876E5F22DEAF3C64DAA159B9AFEB76109429E3E42FF8DB74EF84954405C4D7B826CFBE041FF996CB053ED44BD32742681CCC843CBD031CD9DDF299EF150378F87B5F67768C77A69F779AABC032BCC3031DDAD83701E475D16040D1E064208D99313C4047BA2AA44E15CF631E4337A47318F34060DAE2ED3FB2F77F26CAF51805D86F82786B8CED61C0A0A7A8CBECD9AE3FDD266BDA632E6F6095A8E2C82A709EF2ACE20D66CC6709A5EF4EBFBA3B020BD15A5451673CA3780A459C277EEA72A1C9EF8502281BF903B2409971DC1F215C899CBBDED194CAB8A5EBB2273E3B67AEEE9A18CD03A1CC46312AAE59AEA0EFB0E5EAC8A62D6C49DC5B5D5CAC7B12CC2B293ED1D258149C6E8ADFB311328C1D5ACD4A92DFC71E9575A62920166893D715358DAE87159E39267079FA5D2EF41D756E01E0D9701BE7F715E4DCEF5667576A883DC034E36022AB62707C4E9FF9C7400BD29770FC07C66BB041F17204A63B6A52177F32B1E8AF15A818E946421552673488AA76253A5CCAEF2368C6464A36DEA011A56FFACF5F592099BADEFA4B7A72059FF1869864BDDBD14B4D32460CFD30E78C4F057F011C62F28387B +20241130083311 2 6 100 7679 2 C4FD13B23C1EF3F1B888E9E24F6E6F0D1E538D5C17287A04247451367BAAC3EB0FF3633A10C1B2BEA19F91DA18C0C52A465FA0F0371A2189AC36BFEA58F33B013352F321A0B71BF61553330EC7735E66BF920F0AB9C918AC6796F3B2C5CC7B0E9F6695400B692026845D93807363115D8E1EF92072B84941DE896DC222F2493FA43169DC5C94E9F7C645CDDC38AC8C8F8790A2078B755BF65EB099CA5682E186E7DE95CBCF7036B0BFC761137EB0B297A140C1683E9A14E78F31935D873DFB2CC33563980FD7C6EB609427A9A63D9A7ECE43889783FAF17D129A4F00A7DBA8FAFCBDD57FA7599C944D03297B7106E02A82D695E8BC0ACC860295F357FD2F60CC4A09E49450CF735A8756174A8E1458E3BE2BEA10F38D2C30E6AD7DBFA6835328A64BDFCA2318E1753C922D3AA467BB770C03BE0D3381E31655F4969009A35E4CF90B1EF5CB71A7BE424E952AEF1368142BB6E5AEECB9F7EC2034179009B7E57DF234CDDC3818BE6E637DAC7F44B109BCAA519CA77B27E4A119712A325ACC29E82C5A3E43CDED00A550ABF99495C802578A6ACB7DBCCCECD3A3857F01A9582671D87C9407409355199D627D316938076334BCDEC6635E0D6696A53E2475AAF9412167245779FA0C89CC3C08BF90313C68710D0153A3B8FA06862B6670E9498296D2C1840812D51FFEADDAE3D714A6EA7D0DAF18C134A0E26AAA99AB8B605E5FAC1814D13F5BCA134DBCF40B5C21F39EF9B4089A759876E5F22DEAF3C64DAA159B9AFEB76109429E3E42FF8DB74EF84954405C4D7B826CFBE041FF996CB053ED44BD32742681CCC843CBD031CD9DDF299EF150378F87B5F67768C77A69F779AABC032BCC3031DDAD83701E475D16040D1E064208D99313C4047BA2AA44E15CF631E4337A47318F34060DAE2ED3FB2F77F26CAF51805D86F82786B8CED61C0A0A7A8CBECD9AE3FDD266BDA632E6F6095A8E2C82A709EF2ACE20D66CC6709A5EF4EBFBA3B020BD15A5451673CA3780A459C277EEA72A1C9EF8502281BF903B2409971DC1F215C899CBBDED194CAB8A5EBB2273E3B67AEEE9A18CD03A1CC46312AAE59AEA0EFB0E5EAC8A62D6C49DC5B5D5CAC7B12CC2B293ED1D258149C6E8ADFB311328C1D5ACD4A92DFC71E9575A62920166893D715358DAE87159E39267079FA5D2EF41D756E01E0D9701BE7F715E4DCEF5667576A883DC034E36022AB62707C4E9FF9C7400BD29770FC07C66BB041F17204A63B6A52177F32B1E8AF15A818E946421552673488AA76253A5CCAEF2368C6464A36DEA011A56FFACF5F592099BADEFA4B7A72059FF1869864BDDBD14B4D32460CFD30E78C4F057F011C6325DE613 +20241130093434 2 6 100 7679 5 C4FD13B23C1EF3F1B888E9E24F6E6F0D1E538D5C17287A04247451367BAAC3EB0FF3633A10C1B2BEA19F91DA18C0C52A465FA0F0371A2189AC36BFEA58F33B013352F321A0B71BF61553330EC7735E66BF920F0AB9C918AC6796F3B2C5CC7B0E9F6695400B692026845D93807363115D8E1EF92072B84941DE896DC222F2493FA43169DC5C94E9F7C645CDDC38AC8C8F8790A2078B755BF65EB099CA5682E186E7DE95CBCF7036B0BFC761137EB0B297A140C1683E9A14E78F31935D873DFB2CC33563980FD7C6EB609427A9A63D9A7ECE43889783FAF17D129A4F00A7DBA8FAFCBDD57FA7599C944D03297B7106E02A82D695E8BC0ACC860295F357FD2F60CC4A09E49450CF735A8756174A8E1458E3BE2BEA10F38D2C30E6AD7DBFA6835328A64BDFCA2318E1753C922D3AA467BB770C03BE0D3381E31655F4969009A35E4CF90B1EF5CB71A7BE424E952AEF1368142BB6E5AEECB9F7EC2034179009B7E57DF234CDDC3818BE6E637DAC7F44B109BCAA519CA77B27E4A119712A325ACC29E82C5A3E43CDED00A550ABF99495C802578A6ACB7DBCCCECD3A3857F01A9582671D87C9407409355199D627D316938076334BCDEC6635E0D6696A53E2475AAF9412167245779FA0C89CC3C08BF90313C68710D0153A3B8FA06862B6670E9498296D2C1840812D51FFEADDAE3D714A6EA7D0DAF18C134A0E26AAA99AB8B605E5FAC1814D13F5BCA134DBCF40B5C21F39EF9B4089A759876E5F22DEAF3C64DAA159B9AFEB76109429E3E42FF8DB74EF84954405C4D7B826CFBE041FF996CB053ED44BD32742681CCC843CBD031CD9DDF299EF150378F87B5F67768C77A69F779AABC032BCC3031DDAD83701E475D16040D1E064208D99313C4047BA2AA44E15CF631E4337A47318F34060DAE2ED3FB2F77F26CAF51805D86F82786B8CED61C0A0A7A8CBECD9AE3FDD266BDA632E6F6095A8E2C82A709EF2ACE20D66CC6709A5EF4EBFBA3B020BD15A5451673CA3780A459C277EEA72A1C9EF8502281BF903B2409971DC1F215C899CBBDED194CAB8A5EBB2273E3B67AEEE9A18CD03A1CC46312AAE59AEA0EFB0E5EAC8A62D6C49DC5B5D5CAC7B12CC2B293ED1D258149C6E8ADFB311328C1D5ACD4A92DFC71E9575A62920166893D715358DAE87159E39267079FA5D2EF41D756E01E0D9701BE7F715E4DCEF5667576A883DC034E36022AB62707C4E9FF9C7400BD29770FC07C66BB041F17204A63B6A52177F32B1E8AF15A818E946421552673488AA76253A5CCAEF2368C6464A36DEA011A56FFACF5F592099BADEFA4B7A72059FF1869864BDDBD14B4D32460CFD30E78C4F057F011C636728027 +20241130105425 2 6 100 7679 2 C4FD13B23C1EF3F1B888E9E24F6E6F0D1E538D5C17287A04247451367BAAC3EB0FF3633A10C1B2BEA19F91DA18C0C52A465FA0F0371A2189AC36BFEA58F33B013352F321A0B71BF61553330EC7735E66BF920F0AB9C918AC6796F3B2C5CC7B0E9F6695400B692026845D93807363115D8E1EF92072B84941DE896DC222F2493FA43169DC5C94E9F7C645CDDC38AC8C8F8790A2078B755BF65EB099CA5682E186E7DE95CBCF7036B0BFC761137EB0B297A140C1683E9A14E78F31935D873DFB2CC33563980FD7C6EB609427A9A63D9A7ECE43889783FAF17D129A4F00A7DBA8FAFCBDD57FA7599C944D03297B7106E02A82D695E8BC0ACC860295F357FD2F60CC4A09E49450CF735A8756174A8E1458E3BE2BEA10F38D2C30E6AD7DBFA6835328A64BDFCA2318E1753C922D3AA467BB770C03BE0D3381E31655F4969009A35E4CF90B1EF5CB71A7BE424E952AEF1368142BB6E5AEECB9F7EC2034179009B7E57DF234CDDC3818BE6E637DAC7F44B109BCAA519CA77B27E4A119712A325ACC29E82C5A3E43CDED00A550ABF99495C802578A6ACB7DBCCCECD3A3857F01A9582671D87C9407409355199D627D316938076334BCDEC6635E0D6696A53E2475AAF9412167245779FA0C89CC3C08BF90313C68710D0153A3B8FA06862B6670E9498296D2C1840812D51FFEADDAE3D714A6EA7D0DAF18C134A0E26AAA99AB8B605E5FAC1814D13F5BCA134DBCF40B5C21F39EF9B4089A759876E5F22DEAF3C64DAA159B9AFEB76109429E3E42FF8DB74EF84954405C4D7B826CFBE041FF996CB053ED44BD32742681CCC843CBD031CD9DDF299EF150378F87B5F67768C77A69F779AABC032BCC3031DDAD83701E475D16040D1E064208D99313C4047BA2AA44E15CF631E4337A47318F34060DAE2ED3FB2F77F26CAF51805D86F82786B8CED61C0A0A7A8CBECD9AE3FDD266BDA632E6F6095A8E2C82A709EF2ACE20D66CC6709A5EF4EBFBA3B020BD15A5451673CA3780A459C277EEA72A1C9EF8502281BF903B2409971DC1F215C899CBBDED194CAB8A5EBB2273E3B67AEEE9A18CD03A1CC46312AAE59AEA0EFB0E5EAC8A62D6C49DC5B5D5CAC7B12CC2B293ED1D258149C6E8ADFB311328C1D5ACD4A92DFC71E9575A62920166893D715358DAE87159E39267079FA5D2EF41D756E01E0D9701BE7F715E4DCEF5667576A883DC034E36022AB62707C4E9FF9C7400BD29770FC07C66BB041F17204A63B6A52177F32B1E8AF15A818E946421552673488AA76253A5CCAEF2368C6464A36DEA011A56FFACF5F592099BADEFA4B7A72059FF1869864BDDBD14B4D32460CFD30E78C4F057F011C63BCFA3E3 +20241130105534 2 6 100 7679 5 C4FD13B23C1EF3F1B888E9E24F6E6F0D1E538D5C17287A04247451367BAAC3EB0FF3633A10C1B2BEA19F91DA18C0C52A465FA0F0371A2189AC36BFEA58F33B013352F321A0B71BF61553330EC7735E66BF920F0AB9C918AC6796F3B2C5CC7B0E9F6695400B692026845D93807363115D8E1EF92072B84941DE896DC222F2493FA43169DC5C94E9F7C645CDDC38AC8C8F8790A2078B755BF65EB099CA5682E186E7DE95CBCF7036B0BFC761137EB0B297A140C1683E9A14E78F31935D873DFB2CC33563980FD7C6EB609427A9A63D9A7ECE43889783FAF17D129A4F00A7DBA8FAFCBDD57FA7599C944D03297B7106E02A82D695E8BC0ACC860295F357FD2F60CC4A09E49450CF735A8756174A8E1458E3BE2BEA10F38D2C30E6AD7DBFA6835328A64BDFCA2318E1753C922D3AA467BB770C03BE0D3381E31655F4969009A35E4CF90B1EF5CB71A7BE424E952AEF1368142BB6E5AEECB9F7EC2034179009B7E57DF234CDDC3818BE6E637DAC7F44B109BCAA519CA77B27E4A119712A325ACC29E82C5A3E43CDED00A550ABF99495C802578A6ACB7DBCCCECD3A3857F01A9582671D87C9407409355199D627D316938076334BCDEC6635E0D6696A53E2475AAF9412167245779FA0C89CC3C08BF90313C68710D0153A3B8FA06862B6670E9498296D2C1840812D51FFEADDAE3D714A6EA7D0DAF18C134A0E26AAA99AB8B605E5FAC1814D13F5BCA134DBCF40B5C21F39EF9B4089A759876E5F22DEAF3C64DAA159B9AFEB76109429E3E42FF8DB74EF84954405C4D7B826CFBE041FF996CB053ED44BD32742681CCC843CBD031CD9DDF299EF150378F87B5F67768C77A69F779AABC032BCC3031DDAD83701E475D16040D1E064208D99313C4047BA2AA44E15CF631E4337A47318F34060DAE2ED3FB2F77F26CAF51805D86F82786B8CED61C0A0A7A8CBECD9AE3FDD266BDA632E6F6095A8E2C82A709EF2ACE20D66CC6709A5EF4EBFBA3B020BD15A5451673CA3780A459C277EEA72A1C9EF8502281BF903B2409971DC1F215C899CBBDED194CAB8A5EBB2273E3B67AEEE9A18CD03A1CC46312AAE59AEA0EFB0E5EAC8A62D6C49DC5B5D5CAC7B12CC2B293ED1D258149C6E8ADFB311328C1D5ACD4A92DFC71E9575A62920166893D715358DAE87159E39267079FA5D2EF41D756E01E0D9701BE7F715E4DCEF5667576A883DC034E36022AB62707C4E9FF9C7400BD29770FC07C66BB041F17204A63B6A52177F32B1E8AF15A818E946421552673488AA76253A5CCAEF2368C6464A36DEA011A56FFACF5F592099BADEFA4B7A72059FF1869864BDDBD14B4D32460CFD30E78C4F057F011C63BDA41EF +20241130105809 2 6 100 7679 2 C4FD13B23C1EF3F1B888E9E24F6E6F0D1E538D5C17287A04247451367BAAC3EB0FF3633A10C1B2BEA19F91DA18C0C52A465FA0F0371A2189AC36BFEA58F33B013352F321A0B71BF61553330EC7735E66BF920F0AB9C918AC6796F3B2C5CC7B0E9F6695400B692026845D93807363115D8E1EF92072B84941DE896DC222F2493FA43169DC5C94E9F7C645CDDC38AC8C8F8790A2078B755BF65EB099CA5682E186E7DE95CBCF7036B0BFC761137EB0B297A140C1683E9A14E78F31935D873DFB2CC33563980FD7C6EB609427A9A63D9A7ECE43889783FAF17D129A4F00A7DBA8FAFCBDD57FA7599C944D03297B7106E02A82D695E8BC0ACC860295F357FD2F60CC4A09E49450CF735A8756174A8E1458E3BE2BEA10F38D2C30E6AD7DBFA6835328A64BDFCA2318E1753C922D3AA467BB770C03BE0D3381E31655F4969009A35E4CF90B1EF5CB71A7BE424E952AEF1368142BB6E5AEECB9F7EC2034179009B7E57DF234CDDC3818BE6E637DAC7F44B109BCAA519CA77B27E4A119712A325ACC29E82C5A3E43CDED00A550ABF99495C802578A6ACB7DBCCCECD3A3857F01A9582671D87C9407409355199D627D316938076334BCDEC6635E0D6696A53E2475AAF9412167245779FA0C89CC3C08BF90313C68710D0153A3B8FA06862B6670E9498296D2C1840812D51FFEADDAE3D714A6EA7D0DAF18C134A0E26AAA99AB8B605E5FAC1814D13F5BCA134DBCF40B5C21F39EF9B4089A759876E5F22DEAF3C64DAA159B9AFEB76109429E3E42FF8DB74EF84954405C4D7B826CFBE041FF996CB053ED44BD32742681CCC843CBD031CD9DDF299EF150378F87B5F67768C77A69F779AABC032BCC3031DDAD83701E475D16040D1E064208D99313C4047BA2AA44E15CF631E4337A47318F34060DAE2ED3FB2F77F26CAF51805D86F82786B8CED61C0A0A7A8CBECD9AE3FDD266BDA632E6F6095A8E2C82A709EF2ACE20D66CC6709A5EF4EBFBA3B020BD15A5451673CA3780A459C277EEA72A1C9EF8502281BF903B2409971DC1F215C899CBBDED194CAB8A5EBB2273E3B67AEEE9A18CD03A1CC46312AAE59AEA0EFB0E5EAC8A62D6C49DC5B5D5CAC7B12CC2B293ED1D258149C6E8ADFB311328C1D5ACD4A92DFC71E9575A62920166893D715358DAE87159E39267079FA5D2EF41D756E01E0D9701BE7F715E4DCEF5667576A883DC034E36022AB62707C4E9FF9C7400BD29770FC07C66BB041F17204A63B6A52177F32B1E8AF15A818E946421552673488AA76253A5CCAEF2368C6464A36DEA011A56FFACF5F592099BADEFA4B7A72059FF1869864BDDBD14B4D32460CFD30E78C4F057F011C63BFFF55B +20241130123724 2 6 100 7679 2 C4FD13B23C1EF3F1B888E9E24F6E6F0D1E538D5C17287A04247451367BAAC3EB0FF3633A10C1B2BEA19F91DA18C0C52A465FA0F0371A2189AC36BFEA58F33B013352F321A0B71BF61553330EC7735E66BF920F0AB9C918AC6796F3B2C5CC7B0E9F6695400B692026845D93807363115D8E1EF92072B84941DE896DC222F2493FA43169DC5C94E9F7C645CDDC38AC8C8F8790A2078B755BF65EB099CA5682E186E7DE95CBCF7036B0BFC761137EB0B297A140C1683E9A14E78F31935D873DFB2CC33563980FD7C6EB609427A9A63D9A7ECE43889783FAF17D129A4F00A7DBA8FAFCBDD57FA7599C944D03297B7106E02A82D695E8BC0ACC860295F357FD2F60CC4A09E49450CF735A8756174A8E1458E3BE2BEA10F38D2C30E6AD7DBFA6835328A64BDFCA2318E1753C922D3AA467BB770C03BE0D3381E31655F4969009A35E4CF90B1EF5CB71A7BE424E952AEF1368142BB6E5AEECB9F7EC2034179009B7E57DF234CDDC3818BE6E637DAC7F44B109BCAA519CA77B27E4A119712A325ACC29E82C5A3E43CDED00A550ABF99495C802578A6ACB7DBCCCECD3A3857F01A9582671D87C9407409355199D627D316938076334BCDEC6635E0D6696A53E2475AAF9412167245779FA0C89CC3C08BF90313C68710D0153A3B8FA06862B6670E9498296D2C1840812D51FFEADDAE3D714A6EA7D0DAF18C134A0E26AAA99AB8B605E5FAC1814D13F5BCA134DBCF40B5C21F39EF9B4089A759876E5F22DEAF3C64DAA159B9AFEB76109429E3E42FF8DB74EF84954405C4D7B826CFBE041FF996CB053ED44BD32742681CCC843CBD031CD9DDF299EF150378F87B5F67768C77A69F779AABC032BCC3031DDAD83701E475D16040D1E064208D99313C4047BA2AA44E15CF631E4337A47318F34060DAE2ED3FB2F77F26CAF51805D86F82786B8CED61C0A0A7A8CBECD9AE3FDD266BDA632E6F6095A8E2C82A709EF2ACE20D66CC6709A5EF4EBFBA3B020BD15A5451673CA3780A459C277EEA72A1C9EF8502281BF903B2409971DC1F215C899CBBDED194CAB8A5EBB2273E3B67AEEE9A18CD03A1CC46312AAE59AEA0EFB0E5EAC8A62D6C49DC5B5D5CAC7B12CC2B293ED1D258149C6E8ADFB311328C1D5ACD4A92DFC71E9575A62920166893D715358DAE87159E39267079FA5D2EF41D756E01E0D9701BE7F715E4DCEF5667576A883DC034E36022AB62707C4E9FF9C7400BD29770FC07C66BB041F17204A63B6A52177F32B1E8AF15A818E946421552673488AA76253A5CCAEF2368C6464A36DEA011A56FFACF5F592099BADEFA4B7A72059FF1869864BDDBD14B4D32460CFD30E78C4F057F011C642A90F43 +20241130131041 2 6 100 7679 5 C4FD13B23C1EF3F1B888E9E24F6E6F0D1E538D5C17287A04247451367BAAC3EB0FF3633A10C1B2BEA19F91DA18C0C52A465FA0F0371A2189AC36BFEA58F33B013352F321A0B71BF61553330EC7735E66BF920F0AB9C918AC6796F3B2C5CC7B0E9F6695400B692026845D93807363115D8E1EF92072B84941DE896DC222F2493FA43169DC5C94E9F7C645CDDC38AC8C8F8790A2078B755BF65EB099CA5682E186E7DE95CBCF7036B0BFC761137EB0B297A140C1683E9A14E78F31935D873DFB2CC33563980FD7C6EB609427A9A63D9A7ECE43889783FAF17D129A4F00A7DBA8FAFCBDD57FA7599C944D03297B7106E02A82D695E8BC0ACC860295F357FD2F60CC4A09E49450CF735A8756174A8E1458E3BE2BEA10F38D2C30E6AD7DBFA6835328A64BDFCA2318E1753C922D3AA467BB770C03BE0D3381E31655F4969009A35E4CF90B1EF5CB71A7BE424E952AEF1368142BB6E5AEECB9F7EC2034179009B7E57DF234CDDC3818BE6E637DAC7F44B109BCAA519CA77B27E4A119712A325ACC29E82C5A3E43CDED00A550ABF99495C802578A6ACB7DBCCCECD3A3857F01A9582671D87C9407409355199D627D316938076334BCDEC6635E0D6696A53E2475AAF9412167245779FA0C89CC3C08BF90313C68710D0153A3B8FA06862B6670E9498296D2C1840812D51FFEADDAE3D714A6EA7D0DAF18C134A0E26AAA99AB8B605E5FAC1814D13F5BCA134DBCF40B5C21F39EF9B4089A759876E5F22DEAF3C64DAA159B9AFEB76109429E3E42FF8DB74EF84954405C4D7B826CFBE041FF996CB053ED44BD32742681CCC843CBD031CD9DDF299EF150378F87B5F67768C77A69F779AABC032BCC3031DDAD83701E475D16040D1E064208D99313C4047BA2AA44E15CF631E4337A47318F34060DAE2ED3FB2F77F26CAF51805D86F82786B8CED61C0A0A7A8CBECD9AE3FDD266BDA632E6F6095A8E2C82A709EF2ACE20D66CC6709A5EF4EBFBA3B020BD15A5451673CA3780A459C277EEA72A1C9EF8502281BF903B2409971DC1F215C899CBBDED194CAB8A5EBB2273E3B67AEEE9A18CD03A1CC46312AAE59AEA0EFB0E5EAC8A62D6C49DC5B5D5CAC7B12CC2B293ED1D258149C6E8ADFB311328C1D5ACD4A92DFC71E9575A62920166893D715358DAE87159E39267079FA5D2EF41D756E01E0D9701BE7F715E4DCEF5667576A883DC034E36022AB62707C4E9FF9C7400BD29770FC07C66BB041F17204A63B6A52177F32B1E8AF15A818E946421552673488AA76253A5CCAEF2368C6464A36DEA011A56FFACF5F592099BADEFA4B7A72059FF1869864BDDBD14B4D32460CFD30E78C4F057F011C644DFE51F +20241130150424 2 6 100 7679 2 C4FD13B23C1EF3F1B888E9E24F6E6F0D1E538D5C17287A04247451367BAAC3EB0FF3633A10C1B2BEA19F91DA18C0C52A465FA0F0371A2189AC36BFEA58F33B013352F321A0B71BF61553330EC7735E66BF920F0AB9C918AC6796F3B2C5CC7B0E9F6695400B692026845D93807363115D8E1EF92072B84941DE896DC222F2493FA43169DC5C94E9F7C645CDDC38AC8C8F8790A2078B755BF65EB099CA5682E186E7DE95CBCF7036B0BFC761137EB0B297A140C1683E9A14E78F31935D873DFB2CC33563980FD7C6EB609427A9A63D9A7ECE43889783FAF17D129A4F00A7DBA8FAFCBDD57FA7599C944D03297B7106E02A82D695E8BC0ACC860295F357FD2F60CC4A09E49450CF735A8756174A8E1458E3BE2BEA10F38D2C30E6AD7DBFA6835328A64BDFCA2318E1753C922D3AA467BB770C03BE0D3381E31655F4969009A35E4CF90B1EF5CB71A7BE424E952AEF1368142BB6E5AEECB9F7EC2034179009B7E57DF234CDDC3818BE6E637DAC7F44B109BCAA519CA77B27E4A119712A325ACC29E82C5A3E43CDED00A550ABF99495C802578A6ACB7DBCCCECD3A3857F01A9582671D87C9407409355199D627D316938076334BCDEC6635E0D6696A53E2475AAF9412167245779FA0C89CC3C08BF90313C68710D0153A3B8FA06862B6670E9498296D2C1840812D51FFEADDAE3D714A6EA7D0DAF18C134A0E26AAA99AB8B605E5FAC1814D13F5BCA134DBCF40B5C21F39EF9B4089A759876E5F22DEAF3C64DAA159B9AFEB76109429E3E42FF8DB74EF84954405C4D7B826CFBE041FF996CB053ED44BD32742681CCC843CBD031CD9DDF299EF150378F87B5F67768C77A69F779AABC032BCC3031DDAD83701E475D16040D1E064208D99313C4047BA2AA44E15CF631E4337A47318F34060DAE2ED3FB2F77F26CAF51805D86F82786B8CED61C0A0A7A8CBECD9AE3FDD266BDA632E6F6095A8E2C82A709EF2ACE20D66CC6709A5EF4EBFBA3B020BD15A5451673CA3780A459C277EEA72A1C9EF8502281BF903B2409971DC1F215C899CBBDED194CAB8A5EBB2273E3B67AEEE9A18CD03A1CC46312AAE59AEA0EFB0E5EAC8A62D6C49DC5B5D5CAC7B12CC2B293ED1D258149C6E8ADFB311328C1D5ACD4A92DFC71E9575A62920166893D715358DAE87159E39267079FA5D2EF41D756E01E0D9701BE7F715E4DCEF5667576A883DC034E36022AB62707C4E9FF9C7400BD29770FC07C66BB041F17204A63B6A52177F32B1E8AF15A818E946421552673488AA76253A5CCAEF2368C6464A36DEA011A56FFACF5F592099BADEFA4B7A72059FF1869864BDDBD14B4D32460CFD30E78C4F057F011C64C717C8B +20241130162824 2 6 100 7679 2 C4FD13B23C1EF3F1B888E9E24F6E6F0D1E538D5C17287A04247451367BAAC3EB0FF3633A10C1B2BEA19F91DA18C0C52A465FA0F0371A2189AC36BFEA58F33B013352F321A0B71BF61553330EC7735E66BF920F0AB9C918AC6796F3B2C5CC7B0E9F6695400B692026845D93807363115D8E1EF92072B84941DE896DC222F2493FA43169DC5C94E9F7C645CDDC38AC8C8F8790A2078B755BF65EB099CA5682E186E7DE95CBCF7036B0BFC761137EB0B297A140C1683E9A14E78F31935D873DFB2CC33563980FD7C6EB609427A9A63D9A7ECE43889783FAF17D129A4F00A7DBA8FAFCBDD57FA7599C944D03297B7106E02A82D695E8BC0ACC860295F357FD2F60CC4A09E49450CF735A8756174A8E1458E3BE2BEA10F38D2C30E6AD7DBFA6835328A64BDFCA2318E1753C922D3AA467BB770C03BE0D3381E31655F4969009A35E4CF90B1EF5CB71A7BE424E952AEF1368142BB6E5AEECB9F7EC2034179009B7E57DF234CDDC3818BE6E637DAC7F44B109BCAA519CA77B27E4A119712A325ACC29E82C5A3E43CDED00A550ABF99495C802578A6ACB7DBCCCECD3A3857F01A9582671D87C9407409355199D627D316938076334BCDEC6635E0D6696A53E2475AAF9412167245779FA0C89CC3C08BF90313C68710D0153A3B8FA06862B6670E9498296D2C1840812D51FFEADDAE3D714A6EA7D0DAF18C134A0E26AAA99AB8B605E5FAC1814D13F5BCA134DBCF40B5C21F39EF9B4089A759876E5F22DEAF3C64DAA159B9AFEB76109429E3E42FF8DB74EF84954405C4D7B826CFBE041FF996CB053ED44BD32742681CCC843CBD031CD9DDF299EF150378F87B5F67768C77A69F779AABC032BCC3031DDAD83701E475D16040D1E064208D99313C4047BA2AA44E15CF631E4337A47318F34060DAE2ED3FB2F77F26CAF51805D86F82786B8CED61C0A0A7A8CBECD9AE3FDD266BDA632E6F6095A8E2C82A709EF2ACE20D66CC6709A5EF4EBFBA3B020BD15A5451673CA3780A459C277EEA72A1C9EF8502281BF903B2409971DC1F215C899CBBDED194CAB8A5EBB2273E3B67AEEE9A18CD03A1CC46312AAE59AEA0EFB0E5EAC8A62D6C49DC5B5D5CAC7B12CC2B293ED1D258149C6E8ADFB311328C1D5ACD4A92DFC71E9575A62920166893D715358DAE87159E39267079FA5D2EF41D756E01E0D9701BE7F715E4DCEF5667576A883DC034E36022AB62707C4E9FF9C7400BD29770FC07C66BB041F17204A63B6A52177F32B1E8AF15A818E946421552673488AA76253A5CCAEF2368C6464A36DEA011A56FFACF5F592099BADEFA4B7A72059FF1869864BDDBD14B4D32460CFD30E78C4F057F011C65210D3FB +20241130172212 2 6 100 7679 5 C4FD13B23C1EF3F1B888E9E24F6E6F0D1E538D5C17287A04247451367BAAC3EB0FF3633A10C1B2BEA19F91DA18C0C52A465FA0F0371A2189AC36BFEA58F33B013352F321A0B71BF61553330EC7735E66BF920F0AB9C918AC6796F3B2C5CC7B0E9F6695400B692026845D93807363115D8E1EF92072B84941DE896DC222F2493FA43169DC5C94E9F7C645CDDC38AC8C8F8790A2078B755BF65EB099CA5682E186E7DE95CBCF7036B0BFC761137EB0B297A140C1683E9A14E78F31935D873DFB2CC33563980FD7C6EB609427A9A63D9A7ECE43889783FAF17D129A4F00A7DBA8FAFCBDD57FA7599C944D03297B7106E02A82D695E8BC0ACC860295F357FD2F60CC4A09E49450CF735A8756174A8E1458E3BE2BEA10F38D2C30E6AD7DBFA6835328A64BDFCA2318E1753C922D3AA467BB770C03BE0D3381E31655F4969009A35E4CF90B1EF5CB71A7BE424E952AEF1368142BB6E5AEECB9F7EC2034179009B7E57DF234CDDC3818BE6E637DAC7F44B109BCAA519CA77B27E4A119712A325ACC29E82C5A3E43CDED00A550ABF99495C802578A6ACB7DBCCCECD3A3857F01A9582671D87C9407409355199D627D316938076334BCDEC6635E0D6696A53E2475AAF9412167245779FA0C89CC3C08BF90313C68710D0153A3B8FA06862B6670E9498296D2C1840812D51FFEADDAE3D714A6EA7D0DAF18C134A0E26AAA99AB8B605E5FAC1814D13F5BCA134DBCF40B5C21F39EF9B4089A759876E5F22DEAF3C64DAA159B9AFEB76109429E3E42FF8DB74EF84954405C4D7B826CFBE041FF996CB053ED44BD32742681CCC843CBD031CD9DDF299EF150378F87B5F67768C77A69F779AABC032BCC3031DDAD83701E475D16040D1E064208D99313C4047BA2AA44E15CF631E4337A47318F34060DAE2ED3FB2F77F26CAF51805D86F82786B8CED61C0A0A7A8CBECD9AE3FDD266BDA632E6F6095A8E2C82A709EF2ACE20D66CC6709A5EF4EBFBA3B020BD15A5451673CA3780A459C277EEA72A1C9EF8502281BF903B2409971DC1F215C899CBBDED194CAB8A5EBB2273E3B67AEEE9A18CD03A1CC46312AAE59AEA0EFB0E5EAC8A62D6C49DC5B5D5CAC7B12CC2B293ED1D258149C6E8ADFB311328C1D5ACD4A92DFC71E9575A62920166893D715358DAE87159E39267079FA5D2EF41D756E01E0D9701BE7F715E4DCEF5667576A883DC034E36022AB62707C4E9FF9C7400BD29770FC07C66BB041F17204A63B6A52177F32B1E8AF15A818E946421552673488AA76253A5CCAEF2368C6464A36DEA011A56FFACF5F592099BADEFA4B7A72059FF1869864BDDBD14B4D32460CFD30E78C4F057F011C655A47F4F +20241130174557 2 6 100 7679 2 C4FD13B23C1EF3F1B888E9E24F6E6F0D1E538D5C17287A04247451367BAAC3EB0FF3633A10C1B2BEA19F91DA18C0C52A465FA0F0371A2189AC36BFEA58F33B013352F321A0B71BF61553330EC7735E66BF920F0AB9C918AC6796F3B2C5CC7B0E9F6695400B692026845D93807363115D8E1EF92072B84941DE896DC222F2493FA43169DC5C94E9F7C645CDDC38AC8C8F8790A2078B755BF65EB099CA5682E186E7DE95CBCF7036B0BFC761137EB0B297A140C1683E9A14E78F31935D873DFB2CC33563980FD7C6EB609427A9A63D9A7ECE43889783FAF17D129A4F00A7DBA8FAFCBDD57FA7599C944D03297B7106E02A82D695E8BC0ACC860295F357FD2F60CC4A09E49450CF735A8756174A8E1458E3BE2BEA10F38D2C30E6AD7DBFA6835328A64BDFCA2318E1753C922D3AA467BB770C03BE0D3381E31655F4969009A35E4CF90B1EF5CB71A7BE424E952AEF1368142BB6E5AEECB9F7EC2034179009B7E57DF234CDDC3818BE6E637DAC7F44B109BCAA519CA77B27E4A119712A325ACC29E82C5A3E43CDED00A550ABF99495C802578A6ACB7DBCCCECD3A3857F01A9582671D87C9407409355199D627D316938076334BCDEC6635E0D6696A53E2475AAF9412167245779FA0C89CC3C08BF90313C68710D0153A3B8FA06862B6670E9498296D2C1840812D51FFEADDAE3D714A6EA7D0DAF18C134A0E26AAA99AB8B605E5FAC1814D13F5BCA134DBCF40B5C21F39EF9B4089A759876E5F22DEAF3C64DAA159B9AFEB76109429E3E42FF8DB74EF84954405C4D7B826CFBE041FF996CB053ED44BD32742681CCC843CBD031CD9DDF299EF150378F87B5F67768C77A69F779AABC032BCC3031DDAD83701E475D16040D1E064208D99313C4047BA2AA44E15CF631E4337A47318F34060DAE2ED3FB2F77F26CAF51805D86F82786B8CED61C0A0A7A8CBECD9AE3FDD266BDA632E6F6095A8E2C82A709EF2ACE20D66CC6709A5EF4EBFBA3B020BD15A5451673CA3780A459C277EEA72A1C9EF8502281BF903B2409971DC1F215C899CBBDED194CAB8A5EBB2273E3B67AEEE9A18CD03A1CC46312AAE59AEA0EFB0E5EAC8A62D6C49DC5B5D5CAC7B12CC2B293ED1D258149C6E8ADFB311328C1D5ACD4A92DFC71E9575A62920166893D715358DAE87159E39267079FA5D2EF41D756E01E0D9701BE7F715E4DCEF5667576A883DC034E36022AB62707C4E9FF9C7400BD29770FC07C66BB041F17204A63B6A52177F32B1E8AF15A818E946421552673488AA76253A5CCAEF2368C6464A36DEA011A56FFACF5F592099BADEFA4B7A72059FF1869864BDDBD14B4D32460CFD30E78C4F057F011C657367ECB +20241130215425 2 6 100 7679 5 C4FD13B23C1EF3F1B888E9E24F6E6F0D1E538D5C17287A04247451367BAAC3EB0FF3633A10C1B2BEA19F91DA18C0C52A465FA0F0371A2189AC36BFEA58F33B013352F321A0B71BF61553330EC7735E66BF920F0AB9C918AC6796F3B2C5CC7B0E9F6695400B692026845D93807363115D8E1EF92072B84941DE896DC222F2493FA43169DC5C94E9F7C645CDDC38AC8C8F8790A2078B755BF65EB099CA5682E186E7DE95CBCF7036B0BFC761137EB0B297A140C1683E9A14E78F31935D873DFB2CC33563980FD7C6EB609427A9A63D9A7ECE43889783FAF17D129A4F00A7DBA8FAFCBDD57FA7599C944D03297B7106E02A82D695E8BC0ACC860295F357FD2F60CC4A09E49450CF735A8756174A8E1458E3BE2BEA10F38D2C30E6AD7DBFA6835328A64BDFCA2318E1753C922D3AA467BB770C03BE0D3381E31655F4969009A35E4CF90B1EF5CB71A7BE424E952AEF1368142BB6E5AEECB9F7EC2034179009B7E57DF234CDDC3818BE6E637DAC7F44B109BCAA519CA77B27E4A119712A325ACC29E82C5A3E43CDED00A550ABF99495C802578A6ACB7DBCCCECD3A3857F01A9582671D87C9407409355199D627D316938076334BCDEC6635E0D6696A53E2475AAF9412167245779FA0C89CC3C08BF90313C68710D0153A3B8FA06862B6670E9498296D2C1840812D51FFEADDAE3D714A6EA7D0DAF18C134A0E26AAA99AB8B605E5FAC1814D13F5BCA134DBCF40B5C21F39EF9B4089A759876E5F22DEAF3C64DAA159B9AFEB76109429E3E42FF8DB74EF84954405C4D7B826CFBE041FF996CB053ED44BD32742681CCC843CBD031CD9DDF299EF150378F87B5F67768C77A69F779AABC032BCC3031DDAD83701E475D16040D1E064208D99313C4047BA2AA44E15CF631E4337A47318F34060DAE2ED3FB2F77F26CAF51805D86F82786B8CED61C0A0A7A8CBECD9AE3FDD266BDA632E6F6095A8E2C82A709EF2ACE20D66CC6709A5EF4EBFBA3B020BD15A5451673CA3780A459C277EEA72A1C9EF8502281BF903B2409971DC1F215C899CBBDED194CAB8A5EBB2273E3B67AEEE9A18CD03A1CC46312AAE59AEA0EFB0E5EAC8A62D6C49DC5B5D5CAC7B12CC2B293ED1D258149C6E8ADFB311328C1D5ACD4A92DFC71E9575A62920166893D715358DAE87159E39267079FA5D2EF41D756E01E0D9701BE7F715E4DCEF5667576A883DC034E36022AB62707C4E9FF9C7400BD29770FC07C66BB041F17204A63B6A52177F32B1E8AF15A818E946421552673488AA76253A5CCAEF2368C6464A36DEA011A56FFACF5F592099BADEFA4B7A72059FF1869864BDDBD14B4D32460CFD30E78C4F057F011C66800A377 +20241130230337 2 6 100 7679 5 C4FD13B23C1EF3F1B888E9E24F6E6F0D1E538D5C17287A04247451367BAAC3EB0FF3633A10C1B2BEA19F91DA18C0C52A465FA0F0371A2189AC36BFEA58F33B013352F321A0B71BF61553330EC7735E66BF920F0AB9C918AC6796F3B2C5CC7B0E9F6695400B692026845D93807363115D8E1EF92072B84941DE896DC222F2493FA43169DC5C94E9F7C645CDDC38AC8C8F8790A2078B755BF65EB099CA5682E186E7DE95CBCF7036B0BFC761137EB0B297A140C1683E9A14E78F31935D873DFB2CC33563980FD7C6EB609427A9A63D9A7ECE43889783FAF17D129A4F00A7DBA8FAFCBDD57FA7599C944D03297B7106E02A82D695E8BC0ACC860295F357FD2F60CC4A09E49450CF735A8756174A8E1458E3BE2BEA10F38D2C30E6AD7DBFA6835328A64BDFCA2318E1753C922D3AA467BB770C03BE0D3381E31655F4969009A35E4CF90B1EF5CB71A7BE424E952AEF1368142BB6E5AEECB9F7EC2034179009B7E57DF234CDDC3818BE6E637DAC7F44B109BCAA519CA77B27E4A119712A325ACC29E82C5A3E43CDED00A550ABF99495C802578A6ACB7DBCCCECD3A3857F01A9582671D87C9407409355199D627D316938076334BCDEC6635E0D6696A53E2475AAF9412167245779FA0C89CC3C08BF90313C68710D0153A3B8FA06862B6670E9498296D2C1840812D51FFEADDAE3D714A6EA7D0DAF18C134A0E26AAA99AB8B605E5FAC1814D13F5BCA134DBCF40B5C21F39EF9B4089A759876E5F22DEAF3C64DAA159B9AFEB76109429E3E42FF8DB74EF84954405C4D7B826CFBE041FF996CB053ED44BD32742681CCC843CBD031CD9DDF299EF150378F87B5F67768C77A69F779AABC032BCC3031DDAD83701E475D16040D1E064208D99313C4047BA2AA44E15CF631E4337A47318F34060DAE2ED3FB2F77F26CAF51805D86F82786B8CED61C0A0A7A8CBECD9AE3FDD266BDA632E6F6095A8E2C82A709EF2ACE20D66CC6709A5EF4EBFBA3B020BD15A5451673CA3780A459C277EEA72A1C9EF8502281BF903B2409971DC1F215C899CBBDED194CAB8A5EBB2273E3B67AEEE9A18CD03A1CC46312AAE59AEA0EFB0E5EAC8A62D6C49DC5B5D5CAC7B12CC2B293ED1D258149C6E8ADFB311328C1D5ACD4A92DFC71E9575A62920166893D715358DAE87159E39267079FA5D2EF41D756E01E0D9701BE7F715E4DCEF5667576A883DC034E36022AB62707C4E9FF9C7400BD29770FC07C66BB041F17204A63B6A52177F32B1E8AF15A818E946421552673488AA76253A5CCAEF2368C6464A36DEA011A56FFACF5F592099BADEFA4B7A72059FF1869864BDDBD14B4D32460CFD30E78C4F057F011C66C9D27F7 +20241201025521 2 6 100 7679 5 C4FD13B23C1EF3F1B888E9E24F6E6F0D1E538D5C17287A04247451367BAAC3EB0FF3633A10C1B2BEA19F91DA18C0C52A465FA0F0371A2189AC36BFEA58F33B013352F321A0B71BF61553330EC7735E66BF920F0AB9C918AC6796F3B2C5CC7B0E9F6695400B692026845D93807363115D8E1EF92072B84941DE896DC222F2493FA43169DC5C94E9F7C645CDDC38AC8C8F8790A2078B755BF65EB099CA5682E186E7DE95CBCF7036B0BFC761137EB0B297A140C1683E9A14E78F31935D873DFB2CC33563980FD7C6EB609427A9A63D9A7ECE43889783FAF17D129A4F00A7DBA8FAFCBDD57FA7599C944D03297B7106E02A82D695E8BC0ACC860295F357FD2F60CC4A09E49450CF735A8756174A8E1458E3BE2BEA10F38D2C30E6AD7DBFA6835328A64BDFCA2318E1753C922D3AA467BB770C03BE0D3381E31655F4969009A35E4CF90B1EF5CB71A7BE424E952AEF1368142BB6E5AEECB9F7EC2034179009B7E57DF234CDDC3818BE6E637DAC7F44B109BCAA519CA77B27E4A119712A325ACC29E82C5A3E43CDED00A550ABF99495C802578A6ACB7DBCCCECD3A3857F01A9582671D87C9407409355199D627D316938076334BCDEC6635E0D6696A53E2475AAF9412167245779FA0C89CC3C08BF90313C68710D0153A3B8FA06862B6670E9498296D2C1840812D51FFEADDAE3D714A6EA7D0DAF18C134A0E26AAA99AB8B605E5FAC1814D13F5BCA134DBCF40B5C21F39EF9B4089A759876E5F22DEAF3C64DAA159B9AFEB76109429E3E42FF8DB74EF84954405C4D7B826CFBE041FF996CB053ED44BD32742681CCC843CBD031CD9DDF299EF150378F87B5F67768C77A69F779AABC032BCC3031DDAD83701E475D16040D1E064208D99313C4047BA2AA44E15CF631E4337A47318F34060DAE2ED3FB2F77F26CAF51805D86F82786B8CED61C0A0A7A8CBECD9AE3FDD266BDA632E6F6095A8E2C82A709EF2ACE20D66CC6709A5EF4EBFBA3B020BD15A5451673CA3780A459C277EEA72A1C9EF8502281BF903B2409971DC1F215C899CBBDED194CAB8A5EBB2273E3B67AEEE9A18CD03A1CC46312AAE59AEA0EFB0E5EAC8A62D6C49DC5B5D5CAC7B12CC2B293ED1D258149C6E8ADFB311328C1D5ACD4A92DFC71E9575A62920166893D715358DAE87159E39267079FA5D2EF41D756E01E0D9701BE7F715E4DCEF5667576A883DC034E36022AB62707C4E9FF9C7400BD29770FC07C66BB041F17204A63B6A52177F32B1E8AF15A818E946421552673488AA76253A5CCAEF2368C6464A36DEA011A56FFACF5F592099BADEFA4B7A72059FF1869864BDDBD14B4D32460CFD30E78C4F057F011C67C131CEF +20241201034250 2 6 100 7679 5 C4FD13B23C1EF3F1B888E9E24F6E6F0D1E538D5C17287A04247451367BAAC3EB0FF3633A10C1B2BEA19F91DA18C0C52A465FA0F0371A2189AC36BFEA58F33B013352F321A0B71BF61553330EC7735E66BF920F0AB9C918AC6796F3B2C5CC7B0E9F6695400B692026845D93807363115D8E1EF92072B84941DE896DC222F2493FA43169DC5C94E9F7C645CDDC38AC8C8F8790A2078B755BF65EB099CA5682E186E7DE95CBCF7036B0BFC761137EB0B297A140C1683E9A14E78F31935D873DFB2CC33563980FD7C6EB609427A9A63D9A7ECE43889783FAF17D129A4F00A7DBA8FAFCBDD57FA7599C944D03297B7106E02A82D695E8BC0ACC860295F357FD2F60CC4A09E49450CF735A8756174A8E1458E3BE2BEA10F38D2C30E6AD7DBFA6835328A64BDFCA2318E1753C922D3AA467BB770C03BE0D3381E31655F4969009A35E4CF90B1EF5CB71A7BE424E952AEF1368142BB6E5AEECB9F7EC2034179009B7E57DF234CDDC3818BE6E637DAC7F44B109BCAA519CA77B27E4A119712A325ACC29E82C5A3E43CDED00A550ABF99495C802578A6ACB7DBCCCECD3A3857F01A9582671D87C9407409355199D627D316938076334BCDEC6635E0D6696A53E2475AAF9412167245779FA0C89CC3C08BF90313C68710D0153A3B8FA06862B6670E9498296D2C1840812D51FFEADDAE3D714A6EA7D0DAF18C134A0E26AAA99AB8B605E5FAC1814D13F5BCA134DBCF40B5C21F39EF9B4089A759876E5F22DEAF3C64DAA159B9AFEB76109429E3E42FF8DB74EF84954405C4D7B826CFBE041FF996CB053ED44BD32742681CCC843CBD031CD9DDF299EF150378F87B5F67768C77A69F779AABC032BCC3031DDAD83701E475D16040D1E064208D99313C4047BA2AA44E15CF631E4337A47318F34060DAE2ED3FB2F77F26CAF51805D86F82786B8CED61C0A0A7A8CBECD9AE3FDD266BDA632E6F6095A8E2C82A709EF2ACE20D66CC6709A5EF4EBFBA3B020BD15A5451673CA3780A459C277EEA72A1C9EF8502281BF903B2409971DC1F215C899CBBDED194CAB8A5EBB2273E3B67AEEE9A18CD03A1CC46312AAE59AEA0EFB0E5EAC8A62D6C49DC5B5D5CAC7B12CC2B293ED1D258149C6E8ADFB311328C1D5ACD4A92DFC71E9575A62920166893D715358DAE87159E39267079FA5D2EF41D756E01E0D9701BE7F715E4DCEF5667576A883DC034E36022AB62707C4E9FF9C7400BD29770FC07C66BB041F17204A63B6A52177F32B1E8AF15A818E946421552673488AA76253A5CCAEF2368C6464A36DEA011A56FFACF5F592099BADEFA4B7A72059FF1869864BDDBD14B4D32460CFD30E78C4F057F011C67F375247 +20241201035354 2 6 100 7679 2 C4FD13B23C1EF3F1B888E9E24F6E6F0D1E538D5C17287A04247451367BAAC3EB0FF3633A10C1B2BEA19F91DA18C0C52A465FA0F0371A2189AC36BFEA58F33B013352F321A0B71BF61553330EC7735E66BF920F0AB9C918AC6796F3B2C5CC7B0E9F6695400B692026845D93807363115D8E1EF92072B84941DE896DC222F2493FA43169DC5C94E9F7C645CDDC38AC8C8F8790A2078B755BF65EB099CA5682E186E7DE95CBCF7036B0BFC761137EB0B297A140C1683E9A14E78F31935D873DFB2CC33563980FD7C6EB609427A9A63D9A7ECE43889783FAF17D129A4F00A7DBA8FAFCBDD57FA7599C944D03297B7106E02A82D695E8BC0ACC860295F357FD2F60CC4A09E49450CF735A8756174A8E1458E3BE2BEA10F38D2C30E6AD7DBFA6835328A64BDFCA2318E1753C922D3AA467BB770C03BE0D3381E31655F4969009A35E4CF90B1EF5CB71A7BE424E952AEF1368142BB6E5AEECB9F7EC2034179009B7E57DF234CDDC3818BE6E637DAC7F44B109BCAA519CA77B27E4A119712A325ACC29E82C5A3E43CDED00A550ABF99495C802578A6ACB7DBCCCECD3A3857F01A9582671D87C9407409355199D627D316938076334BCDEC6635E0D6696A53E2475AAF9412167245779FA0C89CC3C08BF90313C68710D0153A3B8FA06862B6670E9498296D2C1840812D51FFEADDAE3D714A6EA7D0DAF18C134A0E26AAA99AB8B605E5FAC1814D13F5BCA134DBCF40B5C21F39EF9B4089A759876E5F22DEAF3C64DAA159B9AFEB76109429E3E42FF8DB74EF84954405C4D7B826CFBE041FF996CB053ED44BD32742681CCC843CBD031CD9DDF299EF150378F87B5F67768C77A69F779AABC032BCC3031DDAD83701E475D16040D1E064208D99313C4047BA2AA44E15CF631E4337A47318F34060DAE2ED3FB2F77F26CAF51805D86F82786B8CED61C0A0A7A8CBECD9AE3FDD266BDA632E6F6095A8E2C82A709EF2ACE20D66CC6709A5EF4EBFBA3B020BD15A5451673CA3780A459C277EEA72A1C9EF8502281BF903B2409971DC1F215C899CBBDED194CAB8A5EBB2273E3B67AEEE9A18CD03A1CC46312AAE59AEA0EFB0E5EAC8A62D6C49DC5B5D5CAC7B12CC2B293ED1D258149C6E8ADFB311328C1D5ACD4A92DFC71E9575A62920166893D715358DAE87159E39267079FA5D2EF41D756E01E0D9701BE7F715E4DCEF5667576A883DC034E36022AB62707C4E9FF9C7400BD29770FC07C66BB041F17204A63B6A52177F32B1E8AF15A818E946421552673488AA76253A5CCAEF2368C6464A36DEA011A56FFACF5F592099BADEFA4B7A72059FF1869864BDDBD14B4D32460CFD30E78C4F057F011C67FEC05DB +20241201043654 2 6 100 7679 2 F02D40B37C40876939E4D2A62AF7EC21A676D8E2B04081BA98E23F464A47514FB40DC99F7B8046B48CD3052C7AC080E4B496C16ED18695CA27493A129088F5829BBEAD02DFD521829FFD8B1120330E2BBA10C55A1EAD0641006827DA4725BFD2A2559C363C33BC78C2D83B4A075099EC57634D0AD4AEDA3302441B7005C728C0371B51877A97B442C5E3C3D53C244EFF3B65CDCCB0C017723F1EBD0B91E220116ACF14703268A11B7FC7564F7BEDBFFB3CE046261DD9D83E6078CD7AB5AC97595EF53D6C4C56D24588C6D130C0CD2C967AB90C31497186A06A93FB9338D4F30E0104BC8EFF2518D0644174BD1FF1FD7BAC2AAFF151D733A14F456A189ECA2D5F11D7C3AF1DA06192D36251B050E1AC576E3C369678D12823870FFC6E5809903382F9FBE36156F294C94FF5369E8D24D085A326870A998A10683495CEF15EFF0A45C781B5156B82D9AA07852040A96A0D5ACDF094B9DD91EA893382F95A6B72F0A2090F036A1B23CF9CF544753EA5B9ED86FA52EBB4C5421C5B485AE932F5837822C91257EC4953ACA79F2D94261DC40B3D44CB44056D4025EC459563865000B8C5F5D7724ED27CA4A8ADE299E5C898F4BD09F430781A68C261E4FA0BA2FEE567434B057C5D5F2899A1547B780B91315CC631C0552DB403DF53A6059BE895242FDA4AE1F6C5129E3643DF1A20C28BBF4328B4E623DCBC1149CE838BBC4A9944A6B6ACB4AA29B50FC7AFFAB0075BB4CC190F15B2C17847560F1B4C591EFE90D5AAA307A3FCC091DF44E3B219F7EE86EA01704D652983CE0D475896C1EB94E09314D386233D706FE0F5415BAF51746F3E8A6AC74E6F68CCF665CCEC4BE0B9CE19308C0423491F5914EA8ABE6081F38282D4994A4B640DCE56F4D616CED59B80938E4E7C486AB64E7C740FCD6ADB5494906520FD66A02069D3C11085157142CDDBFB004023C5CDFCCEAC5296636A77C127DEC4182A36D6A34D980F778452271C80CABAFE15A629302EFE9CD9105353B719581D4DD2E1BCF9411A4CCB0D010B5954291453E761A3B9EAF533119EEF1C30C4E53FEFAF2D2300162786963D54ECE0376CC797CBBDD757B596FAB26716ECEA7C47FB6C6DC6A80FC435D5CADB36D5ACB6760CAC6272B61E64A920EC7D4E5FBD680B2B906F1CF78EFD380A47692E1DC6C06AC21255E65C3757E32C301B5ACD8BA136FEE7C19B858D8B60595946BF1D0520912ACD17E397C9FC156C741AD1104F403B363B4E6B4AD06E8C60928CCD6AB3FE6AEFECBC57DB5CFF431A2D44533D9A92C483B56AE56698F02622D3A65E09B6EBFDFD5DCAF34E09DEDA100B40DD4C40ADCEF30787E527C4F613A08BDED0D77EFCE3 +20241201045113 2 6 100 7679 2 F02D40B37C40876939E4D2A62AF7EC21A676D8E2B04081BA98E23F464A47514FB40DC99F7B8046B48CD3052C7AC080E4B496C16ED18695CA27493A129088F5829BBEAD02DFD521829FFD8B1120330E2BBA10C55A1EAD0641006827DA4725BFD2A2559C363C33BC78C2D83B4A075099EC57634D0AD4AEDA3302441B7005C728C0371B51877A97B442C5E3C3D53C244EFF3B65CDCCB0C017723F1EBD0B91E220116ACF14703268A11B7FC7564F7BEDBFFB3CE046261DD9D83E6078CD7AB5AC97595EF53D6C4C56D24588C6D130C0CD2C967AB90C31497186A06A93FB9338D4F30E0104BC8EFF2518D0644174BD1FF1FD7BAC2AAFF151D733A14F456A189ECA2D5F11D7C3AF1DA06192D36251B050E1AC576E3C369678D12823870FFC6E5809903382F9FBE36156F294C94FF5369E8D24D085A326870A998A10683495CEF15EFF0A45C781B5156B82D9AA07852040A96A0D5ACDF094B9DD91EA893382F95A6B72F0A2090F036A1B23CF9CF544753EA5B9ED86FA52EBB4C5421C5B485AE932F5837822C91257EC4953ACA79F2D94261DC40B3D44CB44056D4025EC459563865000B8C5F5D7724ED27CA4A8ADE299E5C898F4BD09F430781A68C261E4FA0BA2FEE567434B057C5D5F2899A1547B780B91315CC631C0552DB403DF53A6059BE895242FDA4AE1F6C5129E3643DF1A20C28BBF4328B4E623DCBC1149CE838BBC4A9944A6B6ACB4AA29B50FC7AFFAB0075BB4CC190F15B2C17847560F1B4C591EFE90D5AAA307A3FCC091DF44E3B219F7EE86EA01704D652983CE0D475896C1EB94E09314D386233D706FE0F5415BAF51746F3E8A6AC74E6F68CCF665CCEC4BE0B9CE19308C0423491F5914EA8ABE6081F38282D4994A4B640DCE56F4D616CED59B80938E4E7C486AB64E7C740FCD6ADB5494906520FD66A02069D3C11085157142CDDBFB004023C5CDFCCEAC5296636A77C127DEC4182A36D6A34D980F778452271C80CABAFE15A629302EFE9CD9105353B719581D4DD2E1BCF9411A4CCB0D010B5954291453E761A3B9EAF533119EEF1C30C4E53FEFAF2D2300162786963D54ECE0376CC797CBBDD757B596FAB26716ECEA7C47FB6C6DC6A80FC435D5CADB36D5ACB6760CAC6272B61E64A920EC7D4E5FBD680B2B906F1CF78EFD380A47692E1DC6C06AC21255E65C3757E32C301B5ACD8BA136FEE7C19B858D8B60595946BF1D0520912ACD17E397C9FC156C741AD1104F403B363B4E6B4AD06E8C60928CCD6AB3FE6AEFECBC57DB5CFF431A2D44533D9A92C483B56AE56698F02622D3A65E09B6EBFDFD5DCAF34E09DEDA100B40DD4C40ADCEF30787E527C4F613A08BDED0D867EE3B +20241201061048 2 6 100 7679 5 F02D40B37C40876939E4D2A62AF7EC21A676D8E2B04081BA98E23F464A47514FB40DC99F7B8046B48CD3052C7AC080E4B496C16ED18695CA27493A129088F5829BBEAD02DFD521829FFD8B1120330E2BBA10C55A1EAD0641006827DA4725BFD2A2559C363C33BC78C2D83B4A075099EC57634D0AD4AEDA3302441B7005C728C0371B51877A97B442C5E3C3D53C244EFF3B65CDCCB0C017723F1EBD0B91E220116ACF14703268A11B7FC7564F7BEDBFFB3CE046261DD9D83E6078CD7AB5AC97595EF53D6C4C56D24588C6D130C0CD2C967AB90C31497186A06A93FB9338D4F30E0104BC8EFF2518D0644174BD1FF1FD7BAC2AAFF151D733A14F456A189ECA2D5F11D7C3AF1DA06192D36251B050E1AC576E3C369678D12823870FFC6E5809903382F9FBE36156F294C94FF5369E8D24D085A326870A998A10683495CEF15EFF0A45C781B5156B82D9AA07852040A96A0D5ACDF094B9DD91EA893382F95A6B72F0A2090F036A1B23CF9CF544753EA5B9ED86FA52EBB4C5421C5B485AE932F5837822C91257EC4953ACA79F2D94261DC40B3D44CB44056D4025EC459563865000B8C5F5D7724ED27CA4A8ADE299E5C898F4BD09F430781A68C261E4FA0BA2FEE567434B057C5D5F2899A1547B780B91315CC631C0552DB403DF53A6059BE895242FDA4AE1F6C5129E3643DF1A20C28BBF4328B4E623DCBC1149CE838BBC4A9944A6B6ACB4AA29B50FC7AFFAB0075BB4CC190F15B2C17847560F1B4C591EFE90D5AAA307A3FCC091DF44E3B219F7EE86EA01704D652983CE0D475896C1EB94E09314D386233D706FE0F5415BAF51746F3E8A6AC74E6F68CCF665CCEC4BE0B9CE19308C0423491F5914EA8ABE6081F38282D4994A4B640DCE56F4D616CED59B80938E4E7C486AB64E7C740FCD6ADB5494906520FD66A02069D3C11085157142CDDBFB004023C5CDFCCEAC5296636A77C127DEC4182A36D6A34D980F778452271C80CABAFE15A629302EFE9CD9105353B719581D4DD2E1BCF9411A4CCB0D010B5954291453E761A3B9EAF533119EEF1C30C4E53FEFAF2D2300162786963D54ECE0376CC797CBBDD757B596FAB26716ECEA7C47FB6C6DC6A80FC435D5CADB36D5ACB6760CAC6272B61E64A920EC7D4E5FBD680B2B906F1CF78EFD380A47692E1DC6C06AC21255E65C3757E32C301B5ACD8BA136FEE7C19B858D8B60595946BF1D0520912ACD17E397C9FC156C741AD1104F403B363B4E6B4AD06E8C60928CCD6AB3FE6AEFECBC57DB5CFF431A2D44533D9A92C483B56AE56698F02622D3A65E09B6EBFDFD5DCAF34E09DEDA100B40DD4C40ADCEF30787E527C4F613A08BDED0DDAE0C8F +20241201072458 2 6 100 7679 5 F02D40B37C40876939E4D2A62AF7EC21A676D8E2B04081BA98E23F464A47514FB40DC99F7B8046B48CD3052C7AC080E4B496C16ED18695CA27493A129088F5829BBEAD02DFD521829FFD8B1120330E2BBA10C55A1EAD0641006827DA4725BFD2A2559C363C33BC78C2D83B4A075099EC57634D0AD4AEDA3302441B7005C728C0371B51877A97B442C5E3C3D53C244EFF3B65CDCCB0C017723F1EBD0B91E220116ACF14703268A11B7FC7564F7BEDBFFB3CE046261DD9D83E6078CD7AB5AC97595EF53D6C4C56D24588C6D130C0CD2C967AB90C31497186A06A93FB9338D4F30E0104BC8EFF2518D0644174BD1FF1FD7BAC2AAFF151D733A14F456A189ECA2D5F11D7C3AF1DA06192D36251B050E1AC576E3C369678D12823870FFC6E5809903382F9FBE36156F294C94FF5369E8D24D085A326870A998A10683495CEF15EFF0A45C781B5156B82D9AA07852040A96A0D5ACDF094B9DD91EA893382F95A6B72F0A2090F036A1B23CF9CF544753EA5B9ED86FA52EBB4C5421C5B485AE932F5837822C91257EC4953ACA79F2D94261DC40B3D44CB44056D4025EC459563865000B8C5F5D7724ED27CA4A8ADE299E5C898F4BD09F430781A68C261E4FA0BA2FEE567434B057C5D5F2899A1547B780B91315CC631C0552DB403DF53A6059BE895242FDA4AE1F6C5129E3643DF1A20C28BBF4328B4E623DCBC1149CE838BBC4A9944A6B6ACB4AA29B50FC7AFFAB0075BB4CC190F15B2C17847560F1B4C591EFE90D5AAA307A3FCC091DF44E3B219F7EE86EA01704D652983CE0D475896C1EB94E09314D386233D706FE0F5415BAF51746F3E8A6AC74E6F68CCF665CCEC4BE0B9CE19308C0423491F5914EA8ABE6081F38282D4994A4B640DCE56F4D616CED59B80938E4E7C486AB64E7C740FCD6ADB5494906520FD66A02069D3C11085157142CDDBFB004023C5CDFCCEAC5296636A77C127DEC4182A36D6A34D980F778452271C80CABAFE15A629302EFE9CD9105353B719581D4DD2E1BCF9411A4CCB0D010B5954291453E761A3B9EAF533119EEF1C30C4E53FEFAF2D2300162786963D54ECE0376CC797CBBDD757B596FAB26716ECEA7C47FB6C6DC6A80FC435D5CADB36D5ACB6760CAC6272B61E64A920EC7D4E5FBD680B2B906F1CF78EFD380A47692E1DC6C06AC21255E65C3757E32C301B5ACD8BA136FEE7C19B858D8B60595946BF1D0520912ACD17E397C9FC156C741AD1104F403B363B4E6B4AD06E8C60928CCD6AB3FE6AEFECBC57DB5CFF431A2D44533D9A92C483B56AE56698F02622D3A65E09B6EBFDFD5DCAF34E09DEDA100B40DD4C40ADCEF30787E527C4F613A08BDED0E29A61DF +20241201073945 2 6 100 7679 2 F02D40B37C40876939E4D2A62AF7EC21A676D8E2B04081BA98E23F464A47514FB40DC99F7B8046B48CD3052C7AC080E4B496C16ED18695CA27493A129088F5829BBEAD02DFD521829FFD8B1120330E2BBA10C55A1EAD0641006827DA4725BFD2A2559C363C33BC78C2D83B4A075099EC57634D0AD4AEDA3302441B7005C728C0371B51877A97B442C5E3C3D53C244EFF3B65CDCCB0C017723F1EBD0B91E220116ACF14703268A11B7FC7564F7BEDBFFB3CE046261DD9D83E6078CD7AB5AC97595EF53D6C4C56D24588C6D130C0CD2C967AB90C31497186A06A93FB9338D4F30E0104BC8EFF2518D0644174BD1FF1FD7BAC2AAFF151D733A14F456A189ECA2D5F11D7C3AF1DA06192D36251B050E1AC576E3C369678D12823870FFC6E5809903382F9FBE36156F294C94FF5369E8D24D085A326870A998A10683495CEF15EFF0A45C781B5156B82D9AA07852040A96A0D5ACDF094B9DD91EA893382F95A6B72F0A2090F036A1B23CF9CF544753EA5B9ED86FA52EBB4C5421C5B485AE932F5837822C91257EC4953ACA79F2D94261DC40B3D44CB44056D4025EC459563865000B8C5F5D7724ED27CA4A8ADE299E5C898F4BD09F430781A68C261E4FA0BA2FEE567434B057C5D5F2899A1547B780B91315CC631C0552DB403DF53A6059BE895242FDA4AE1F6C5129E3643DF1A20C28BBF4328B4E623DCBC1149CE838BBC4A9944A6B6ACB4AA29B50FC7AFFAB0075BB4CC190F15B2C17847560F1B4C591EFE90D5AAA307A3FCC091DF44E3B219F7EE86EA01704D652983CE0D475896C1EB94E09314D386233D706FE0F5415BAF51746F3E8A6AC74E6F68CCF665CCEC4BE0B9CE19308C0423491F5914EA8ABE6081F38282D4994A4B640DCE56F4D616CED59B80938E4E7C486AB64E7C740FCD6ADB5494906520FD66A02069D3C11085157142CDDBFB004023C5CDFCCEAC5296636A77C127DEC4182A36D6A34D980F778452271C80CABAFE15A629302EFE9CD9105353B719581D4DD2E1BCF9411A4CCB0D010B5954291453E761A3B9EAF533119EEF1C30C4E53FEFAF2D2300162786963D54ECE0376CC797CBBDD757B596FAB26716ECEA7C47FB6C6DC6A80FC435D5CADB36D5ACB6760CAC6272B61E64A920EC7D4E5FBD680B2B906F1CF78EFD380A47692E1DC6C06AC21255E65C3757E32C301B5ACD8BA136FEE7C19B858D8B60595946BF1D0520912ACD17E397C9FC156C741AD1104F403B363B4E6B4AD06E8C60928CCD6AB3FE6AEFECBC57DB5CFF431A2D44533D9A92C483B56AE56698F02622D3A65E09B6EBFDFD5DCAF34E09DEDA100B40DD4C40ADCEF30787E527C4F613A08BDED0E39422AB +20241201081137 2 6 100 7679 2 F02D40B37C40876939E4D2A62AF7EC21A676D8E2B04081BA98E23F464A47514FB40DC99F7B8046B48CD3052C7AC080E4B496C16ED18695CA27493A129088F5829BBEAD02DFD521829FFD8B1120330E2BBA10C55A1EAD0641006827DA4725BFD2A2559C363C33BC78C2D83B4A075099EC57634D0AD4AEDA3302441B7005C728C0371B51877A97B442C5E3C3D53C244EFF3B65CDCCB0C017723F1EBD0B91E220116ACF14703268A11B7FC7564F7BEDBFFB3CE046261DD9D83E6078CD7AB5AC97595EF53D6C4C56D24588C6D130C0CD2C967AB90C31497186A06A93FB9338D4F30E0104BC8EFF2518D0644174BD1FF1FD7BAC2AAFF151D733A14F456A189ECA2D5F11D7C3AF1DA06192D36251B050E1AC576E3C369678D12823870FFC6E5809903382F9FBE36156F294C94FF5369E8D24D085A326870A998A10683495CEF15EFF0A45C781B5156B82D9AA07852040A96A0D5ACDF094B9DD91EA893382F95A6B72F0A2090F036A1B23CF9CF544753EA5B9ED86FA52EBB4C5421C5B485AE932F5837822C91257EC4953ACA79F2D94261DC40B3D44CB44056D4025EC459563865000B8C5F5D7724ED27CA4A8ADE299E5C898F4BD09F430781A68C261E4FA0BA2FEE567434B057C5D5F2899A1547B780B91315CC631C0552DB403DF53A6059BE895242FDA4AE1F6C5129E3643DF1A20C28BBF4328B4E623DCBC1149CE838BBC4A9944A6B6ACB4AA29B50FC7AFFAB0075BB4CC190F15B2C17847560F1B4C591EFE90D5AAA307A3FCC091DF44E3B219F7EE86EA01704D652983CE0D475896C1EB94E09314D386233D706FE0F5415BAF51746F3E8A6AC74E6F68CCF665CCEC4BE0B9CE19308C0423491F5914EA8ABE6081F38282D4994A4B640DCE56F4D616CED59B80938E4E7C486AB64E7C740FCD6ADB5494906520FD66A02069D3C11085157142CDDBFB004023C5CDFCCEAC5296636A77C127DEC4182A36D6A34D980F778452271C80CABAFE15A629302EFE9CD9105353B719581D4DD2E1BCF9411A4CCB0D010B5954291453E761A3B9EAF533119EEF1C30C4E53FEFAF2D2300162786963D54ECE0376CC797CBBDD757B596FAB26716ECEA7C47FB6C6DC6A80FC435D5CADB36D5ACB6760CAC6272B61E64A920EC7D4E5FBD680B2B906F1CF78EFD380A47692E1DC6C06AC21255E65C3757E32C301B5ACD8BA136FEE7C19B858D8B60595946BF1D0520912ACD17E397C9FC156C741AD1104F403B363B4E6B4AD06E8C60928CCD6AB3FE6AEFECBC57DB5CFF431A2D44533D9A92C483B56AE56698F02622D3A65E09B6EBFDFD5DCAF34E09DEDA100B40DD4C40ADCEF30787E527C4F613A08BDED0E5B1C16B +20241201084445 2 6 100 7679 2 F02D40B37C40876939E4D2A62AF7EC21A676D8E2B04081BA98E23F464A47514FB40DC99F7B8046B48CD3052C7AC080E4B496C16ED18695CA27493A129088F5829BBEAD02DFD521829FFD8B1120330E2BBA10C55A1EAD0641006827DA4725BFD2A2559C363C33BC78C2D83B4A075099EC57634D0AD4AEDA3302441B7005C728C0371B51877A97B442C5E3C3D53C244EFF3B65CDCCB0C017723F1EBD0B91E220116ACF14703268A11B7FC7564F7BEDBFFB3CE046261DD9D83E6078CD7AB5AC97595EF53D6C4C56D24588C6D130C0CD2C967AB90C31497186A06A93FB9338D4F30E0104BC8EFF2518D0644174BD1FF1FD7BAC2AAFF151D733A14F456A189ECA2D5F11D7C3AF1DA06192D36251B050E1AC576E3C369678D12823870FFC6E5809903382F9FBE36156F294C94FF5369E8D24D085A326870A998A10683495CEF15EFF0A45C781B5156B82D9AA07852040A96A0D5ACDF094B9DD91EA893382F95A6B72F0A2090F036A1B23CF9CF544753EA5B9ED86FA52EBB4C5421C5B485AE932F5837822C91257EC4953ACA79F2D94261DC40B3D44CB44056D4025EC459563865000B8C5F5D7724ED27CA4A8ADE299E5C898F4BD09F430781A68C261E4FA0BA2FEE567434B057C5D5F2899A1547B780B91315CC631C0552DB403DF53A6059BE895242FDA4AE1F6C5129E3643DF1A20C28BBF4328B4E623DCBC1149CE838BBC4A9944A6B6ACB4AA29B50FC7AFFAB0075BB4CC190F15B2C17847560F1B4C591EFE90D5AAA307A3FCC091DF44E3B219F7EE86EA01704D652983CE0D475896C1EB94E09314D386233D706FE0F5415BAF51746F3E8A6AC74E6F68CCF665CCEC4BE0B9CE19308C0423491F5914EA8ABE6081F38282D4994A4B640DCE56F4D616CED59B80938E4E7C486AB64E7C740FCD6ADB5494906520FD66A02069D3C11085157142CDDBFB004023C5CDFCCEAC5296636A77C127DEC4182A36D6A34D980F778452271C80CABAFE15A629302EFE9CD9105353B719581D4DD2E1BCF9411A4CCB0D010B5954291453E761A3B9EAF533119EEF1C30C4E53FEFAF2D2300162786963D54ECE0376CC797CBBDD757B596FAB26716ECEA7C47FB6C6DC6A80FC435D5CADB36D5ACB6760CAC6272B61E64A920EC7D4E5FBD680B2B906F1CF78EFD380A47692E1DC6C06AC21255E65C3757E32C301B5ACD8BA136FEE7C19B858D8B60595946BF1D0520912ACD17E397C9FC156C741AD1104F403B363B4E6B4AD06E8C60928CCD6AB3FE6AEFECBC57DB5CFF431A2D44533D9A92C483B56AE56698F02622D3A65E09B6EBFDFD5DCAF34E09DEDA100B40DD4C40ADCEF30787E527C4F613A08BDED0E7E0CB7B +20241201085943 2 6 100 7679 2 F02D40B37C40876939E4D2A62AF7EC21A676D8E2B04081BA98E23F464A47514FB40DC99F7B8046B48CD3052C7AC080E4B496C16ED18695CA27493A129088F5829BBEAD02DFD521829FFD8B1120330E2BBA10C55A1EAD0641006827DA4725BFD2A2559C363C33BC78C2D83B4A075099EC57634D0AD4AEDA3302441B7005C728C0371B51877A97B442C5E3C3D53C244EFF3B65CDCCB0C017723F1EBD0B91E220116ACF14703268A11B7FC7564F7BEDBFFB3CE046261DD9D83E6078CD7AB5AC97595EF53D6C4C56D24588C6D130C0CD2C967AB90C31497186A06A93FB9338D4F30E0104BC8EFF2518D0644174BD1FF1FD7BAC2AAFF151D733A14F456A189ECA2D5F11D7C3AF1DA06192D36251B050E1AC576E3C369678D12823870FFC6E5809903382F9FBE36156F294C94FF5369E8D24D085A326870A998A10683495CEF15EFF0A45C781B5156B82D9AA07852040A96A0D5ACDF094B9DD91EA893382F95A6B72F0A2090F036A1B23CF9CF544753EA5B9ED86FA52EBB4C5421C5B485AE932F5837822C91257EC4953ACA79F2D94261DC40B3D44CB44056D4025EC459563865000B8C5F5D7724ED27CA4A8ADE299E5C898F4BD09F430781A68C261E4FA0BA2FEE567434B057C5D5F2899A1547B780B91315CC631C0552DB403DF53A6059BE895242FDA4AE1F6C5129E3643DF1A20C28BBF4328B4E623DCBC1149CE838BBC4A9944A6B6ACB4AA29B50FC7AFFAB0075BB4CC190F15B2C17847560F1B4C591EFE90D5AAA307A3FCC091DF44E3B219F7EE86EA01704D652983CE0D475896C1EB94E09314D386233D706FE0F5415BAF51746F3E8A6AC74E6F68CCF665CCEC4BE0B9CE19308C0423491F5914EA8ABE6081F38282D4994A4B640DCE56F4D616CED59B80938E4E7C486AB64E7C740FCD6ADB5494906520FD66A02069D3C11085157142CDDBFB004023C5CDFCCEAC5296636A77C127DEC4182A36D6A34D980F778452271C80CABAFE15A629302EFE9CD9105353B719581D4DD2E1BCF9411A4CCB0D010B5954291453E761A3B9EAF533119EEF1C30C4E53FEFAF2D2300162786963D54ECE0376CC797CBBDD757B596FAB26716ECEA7C47FB6C6DC6A80FC435D5CADB36D5ACB6760CAC6272B61E64A920EC7D4E5FBD680B2B906F1CF78EFD380A47692E1DC6C06AC21255E65C3757E32C301B5ACD8BA136FEE7C19B858D8B60595946BF1D0520912ACD17E397C9FC156C741AD1104F403B363B4E6B4AD06E8C60928CCD6AB3FE6AEFECBC57DB5CFF431A2D44533D9A92C483B56AE56698F02622D3A65E09B6EBFDFD5DCAF34E09DEDA100B40DD4C40ADCEF30787E527C4F613A08BDED0E8D1F5CB +20241201092406 2 6 100 7679 2 F02D40B37C40876939E4D2A62AF7EC21A676D8E2B04081BA98E23F464A47514FB40DC99F7B8046B48CD3052C7AC080E4B496C16ED18695CA27493A129088F5829BBEAD02DFD521829FFD8B1120330E2BBA10C55A1EAD0641006827DA4725BFD2A2559C363C33BC78C2D83B4A075099EC57634D0AD4AEDA3302441B7005C728C0371B51877A97B442C5E3C3D53C244EFF3B65CDCCB0C017723F1EBD0B91E220116ACF14703268A11B7FC7564F7BEDBFFB3CE046261DD9D83E6078CD7AB5AC97595EF53D6C4C56D24588C6D130C0CD2C967AB90C31497186A06A93FB9338D4F30E0104BC8EFF2518D0644174BD1FF1FD7BAC2AAFF151D733A14F456A189ECA2D5F11D7C3AF1DA06192D36251B050E1AC576E3C369678D12823870FFC6E5809903382F9FBE36156F294C94FF5369E8D24D085A326870A998A10683495CEF15EFF0A45C781B5156B82D9AA07852040A96A0D5ACDF094B9DD91EA893382F95A6B72F0A2090F036A1B23CF9CF544753EA5B9ED86FA52EBB4C5421C5B485AE932F5837822C91257EC4953ACA79F2D94261DC40B3D44CB44056D4025EC459563865000B8C5F5D7724ED27CA4A8ADE299E5C898F4BD09F430781A68C261E4FA0BA2FEE567434B057C5D5F2899A1547B780B91315CC631C0552DB403DF53A6059BE895242FDA4AE1F6C5129E3643DF1A20C28BBF4328B4E623DCBC1149CE838BBC4A9944A6B6ACB4AA29B50FC7AFFAB0075BB4CC190F15B2C17847560F1B4C591EFE90D5AAA307A3FCC091DF44E3B219F7EE86EA01704D652983CE0D475896C1EB94E09314D386233D706FE0F5415BAF51746F3E8A6AC74E6F68CCF665CCEC4BE0B9CE19308C0423491F5914EA8ABE6081F38282D4994A4B640DCE56F4D616CED59B80938E4E7C486AB64E7C740FCD6ADB5494906520FD66A02069D3C11085157142CDDBFB004023C5CDFCCEAC5296636A77C127DEC4182A36D6A34D980F778452271C80CABAFE15A629302EFE9CD9105353B719581D4DD2E1BCF9411A4CCB0D010B5954291453E761A3B9EAF533119EEF1C30C4E53FEFAF2D2300162786963D54ECE0376CC797CBBDD757B596FAB26716ECEA7C47FB6C6DC6A80FC435D5CADB36D5ACB6760CAC6272B61E64A920EC7D4E5FBD680B2B906F1CF78EFD380A47692E1DC6C06AC21255E65C3757E32C301B5ACD8BA136FEE7C19B858D8B60595946BF1D0520912ACD17E397C9FC156C741AD1104F403B363B4E6B4AD06E8C60928CCD6AB3FE6AEFECBC57DB5CFF431A2D44533D9A92C483B56AE56698F02622D3A65E09B6EBFDFD5DCAF34E09DEDA100B40DD4C40ADCEF30787E527C4F613A08BDED0EA661BD3 +20241201094424 2 6 100 7679 2 F02D40B37C40876939E4D2A62AF7EC21A676D8E2B04081BA98E23F464A47514FB40DC99F7B8046B48CD3052C7AC080E4B496C16ED18695CA27493A129088F5829BBEAD02DFD521829FFD8B1120330E2BBA10C55A1EAD0641006827DA4725BFD2A2559C363C33BC78C2D83B4A075099EC57634D0AD4AEDA3302441B7005C728C0371B51877A97B442C5E3C3D53C244EFF3B65CDCCB0C017723F1EBD0B91E220116ACF14703268A11B7FC7564F7BEDBFFB3CE046261DD9D83E6078CD7AB5AC97595EF53D6C4C56D24588C6D130C0CD2C967AB90C31497186A06A93FB9338D4F30E0104BC8EFF2518D0644174BD1FF1FD7BAC2AAFF151D733A14F456A189ECA2D5F11D7C3AF1DA06192D36251B050E1AC576E3C369678D12823870FFC6E5809903382F9FBE36156F294C94FF5369E8D24D085A326870A998A10683495CEF15EFF0A45C781B5156B82D9AA07852040A96A0D5ACDF094B9DD91EA893382F95A6B72F0A2090F036A1B23CF9CF544753EA5B9ED86FA52EBB4C5421C5B485AE932F5837822C91257EC4953ACA79F2D94261DC40B3D44CB44056D4025EC459563865000B8C5F5D7724ED27CA4A8ADE299E5C898F4BD09F430781A68C261E4FA0BA2FEE567434B057C5D5F2899A1547B780B91315CC631C0552DB403DF53A6059BE895242FDA4AE1F6C5129E3643DF1A20C28BBF4328B4E623DCBC1149CE838BBC4A9944A6B6ACB4AA29B50FC7AFFAB0075BB4CC190F15B2C17847560F1B4C591EFE90D5AAA307A3FCC091DF44E3B219F7EE86EA01704D652983CE0D475896C1EB94E09314D386233D706FE0F5415BAF51746F3E8A6AC74E6F68CCF665CCEC4BE0B9CE19308C0423491F5914EA8ABE6081F38282D4994A4B640DCE56F4D616CED59B80938E4E7C486AB64E7C740FCD6ADB5494906520FD66A02069D3C11085157142CDDBFB004023C5CDFCCEAC5296636A77C127DEC4182A36D6A34D980F778452271C80CABAFE15A629302EFE9CD9105353B719581D4DD2E1BCF9411A4CCB0D010B5954291453E761A3B9EAF533119EEF1C30C4E53FEFAF2D2300162786963D54ECE0376CC797CBBDD757B596FAB26716ECEA7C47FB6C6DC6A80FC435D5CADB36D5ACB6760CAC6272B61E64A920EC7D4E5FBD680B2B906F1CF78EFD380A47692E1DC6C06AC21255E65C3757E32C301B5ACD8BA136FEE7C19B858D8B60595946BF1D0520912ACD17E397C9FC156C741AD1104F403B363B4E6B4AD06E8C60928CCD6AB3FE6AEFECBC57DB5CFF431A2D44533D9A92C483B56AE56698F02622D3A65E09B6EBFDFD5DCAF34E09DEDA100B40DD4C40ADCEF30787E527C4F613A08BDED0EBB93913 +20241201104106 2 6 100 7679 5 F02D40B37C40876939E4D2A62AF7EC21A676D8E2B04081BA98E23F464A47514FB40DC99F7B8046B48CD3052C7AC080E4B496C16ED18695CA27493A129088F5829BBEAD02DFD521829FFD8B1120330E2BBA10C55A1EAD0641006827DA4725BFD2A2559C363C33BC78C2D83B4A075099EC57634D0AD4AEDA3302441B7005C728C0371B51877A97B442C5E3C3D53C244EFF3B65CDCCB0C017723F1EBD0B91E220116ACF14703268A11B7FC7564F7BEDBFFB3CE046261DD9D83E6078CD7AB5AC97595EF53D6C4C56D24588C6D130C0CD2C967AB90C31497186A06A93FB9338D4F30E0104BC8EFF2518D0644174BD1FF1FD7BAC2AAFF151D733A14F456A189ECA2D5F11D7C3AF1DA06192D36251B050E1AC576E3C369678D12823870FFC6E5809903382F9FBE36156F294C94FF5369E8D24D085A326870A998A10683495CEF15EFF0A45C781B5156B82D9AA07852040A96A0D5ACDF094B9DD91EA893382F95A6B72F0A2090F036A1B23CF9CF544753EA5B9ED86FA52EBB4C5421C5B485AE932F5837822C91257EC4953ACA79F2D94261DC40B3D44CB44056D4025EC459563865000B8C5F5D7724ED27CA4A8ADE299E5C898F4BD09F430781A68C261E4FA0BA2FEE567434B057C5D5F2899A1547B780B91315CC631C0552DB403DF53A6059BE895242FDA4AE1F6C5129E3643DF1A20C28BBF4328B4E623DCBC1149CE838BBC4A9944A6B6ACB4AA29B50FC7AFFAB0075BB4CC190F15B2C17847560F1B4C591EFE90D5AAA307A3FCC091DF44E3B219F7EE86EA01704D652983CE0D475896C1EB94E09314D386233D706FE0F5415BAF51746F3E8A6AC74E6F68CCF665CCEC4BE0B9CE19308C0423491F5914EA8ABE6081F38282D4994A4B640DCE56F4D616CED59B80938E4E7C486AB64E7C740FCD6ADB5494906520FD66A02069D3C11085157142CDDBFB004023C5CDFCCEAC5296636A77C127DEC4182A36D6A34D980F778452271C80CABAFE15A629302EFE9CD9105353B719581D4DD2E1BCF9411A4CCB0D010B5954291453E761A3B9EAF533119EEF1C30C4E53FEFAF2D2300162786963D54ECE0376CC797CBBDD757B596FAB26716ECEA7C47FB6C6DC6A80FC435D5CADB36D5ACB6760CAC6272B61E64A920EC7D4E5FBD680B2B906F1CF78EFD380A47692E1DC6C06AC21255E65C3757E32C301B5ACD8BA136FEE7C19B858D8B60595946BF1D0520912ACD17E397C9FC156C741AD1104F403B363B4E6B4AD06E8C60928CCD6AB3FE6AEFECBC57DB5CFF431A2D44533D9A92C483B56AE56698F02622D3A65E09B6EBFDFD5DCAF34E09DEDA100B40DD4C40ADCEF30787E527C4F613A08BDED0EF85D8F7 +20241201104452 2 6 100 7679 5 F02D40B37C40876939E4D2A62AF7EC21A676D8E2B04081BA98E23F464A47514FB40DC99F7B8046B48CD3052C7AC080E4B496C16ED18695CA27493A129088F5829BBEAD02DFD521829FFD8B1120330E2BBA10C55A1EAD0641006827DA4725BFD2A2559C363C33BC78C2D83B4A075099EC57634D0AD4AEDA3302441B7005C728C0371B51877A97B442C5E3C3D53C244EFF3B65CDCCB0C017723F1EBD0B91E220116ACF14703268A11B7FC7564F7BEDBFFB3CE046261DD9D83E6078CD7AB5AC97595EF53D6C4C56D24588C6D130C0CD2C967AB90C31497186A06A93FB9338D4F30E0104BC8EFF2518D0644174BD1FF1FD7BAC2AAFF151D733A14F456A189ECA2D5F11D7C3AF1DA06192D36251B050E1AC576E3C369678D12823870FFC6E5809903382F9FBE36156F294C94FF5369E8D24D085A326870A998A10683495CEF15EFF0A45C781B5156B82D9AA07852040A96A0D5ACDF094B9DD91EA893382F95A6B72F0A2090F036A1B23CF9CF544753EA5B9ED86FA52EBB4C5421C5B485AE932F5837822C91257EC4953ACA79F2D94261DC40B3D44CB44056D4025EC459563865000B8C5F5D7724ED27CA4A8ADE299E5C898F4BD09F430781A68C261E4FA0BA2FEE567434B057C5D5F2899A1547B780B91315CC631C0552DB403DF53A6059BE895242FDA4AE1F6C5129E3643DF1A20C28BBF4328B4E623DCBC1149CE838BBC4A9944A6B6ACB4AA29B50FC7AFFAB0075BB4CC190F15B2C17847560F1B4C591EFE90D5AAA307A3FCC091DF44E3B219F7EE86EA01704D652983CE0D475896C1EB94E09314D386233D706FE0F5415BAF51746F3E8A6AC74E6F68CCF665CCEC4BE0B9CE19308C0423491F5914EA8ABE6081F38282D4994A4B640DCE56F4D616CED59B80938E4E7C486AB64E7C740FCD6ADB5494906520FD66A02069D3C11085157142CDDBFB004023C5CDFCCEAC5296636A77C127DEC4182A36D6A34D980F778452271C80CABAFE15A629302EFE9CD9105353B719581D4DD2E1BCF9411A4CCB0D010B5954291453E761A3B9EAF533119EEF1C30C4E53FEFAF2D2300162786963D54ECE0376CC797CBBDD757B596FAB26716ECEA7C47FB6C6DC6A80FC435D5CADB36D5ACB6760CAC6272B61E64A920EC7D4E5FBD680B2B906F1CF78EFD380A47692E1DC6C06AC21255E65C3757E32C301B5ACD8BA136FEE7C19B858D8B60595946BF1D0520912ACD17E397C9FC156C741AD1104F403B363B4E6B4AD06E8C60928CCD6AB3FE6AEFECBC57DB5CFF431A2D44533D9A92C483B56AE56698F02622D3A65E09B6EBFDFD5DCAF34E09DEDA100B40DD4C40ADCEF30787E527C4F613A08BDED0EFBC6D8F +20241201115450 2 6 100 7679 2 F02D40B37C40876939E4D2A62AF7EC21A676D8E2B04081BA98E23F464A47514FB40DC99F7B8046B48CD3052C7AC080E4B496C16ED18695CA27493A129088F5829BBEAD02DFD521829FFD8B1120330E2BBA10C55A1EAD0641006827DA4725BFD2A2559C363C33BC78C2D83B4A075099EC57634D0AD4AEDA3302441B7005C728C0371B51877A97B442C5E3C3D53C244EFF3B65CDCCB0C017723F1EBD0B91E220116ACF14703268A11B7FC7564F7BEDBFFB3CE046261DD9D83E6078CD7AB5AC97595EF53D6C4C56D24588C6D130C0CD2C967AB90C31497186A06A93FB9338D4F30E0104BC8EFF2518D0644174BD1FF1FD7BAC2AAFF151D733A14F456A189ECA2D5F11D7C3AF1DA06192D36251B050E1AC576E3C369678D12823870FFC6E5809903382F9FBE36156F294C94FF5369E8D24D085A326870A998A10683495CEF15EFF0A45C781B5156B82D9AA07852040A96A0D5ACDF094B9DD91EA893382F95A6B72F0A2090F036A1B23CF9CF544753EA5B9ED86FA52EBB4C5421C5B485AE932F5837822C91257EC4953ACA79F2D94261DC40B3D44CB44056D4025EC459563865000B8C5F5D7724ED27CA4A8ADE299E5C898F4BD09F430781A68C261E4FA0BA2FEE567434B057C5D5F2899A1547B780B91315CC631C0552DB403DF53A6059BE895242FDA4AE1F6C5129E3643DF1A20C28BBF4328B4E623DCBC1149CE838BBC4A9944A6B6ACB4AA29B50FC7AFFAB0075BB4CC190F15B2C17847560F1B4C591EFE90D5AAA307A3FCC091DF44E3B219F7EE86EA01704D652983CE0D475896C1EB94E09314D386233D706FE0F5415BAF51746F3E8A6AC74E6F68CCF665CCEC4BE0B9CE19308C0423491F5914EA8ABE6081F38282D4994A4B640DCE56F4D616CED59B80938E4E7C486AB64E7C740FCD6ADB5494906520FD66A02069D3C11085157142CDDBFB004023C5CDFCCEAC5296636A77C127DEC4182A36D6A34D980F778452271C80CABAFE15A629302EFE9CD9105353B719581D4DD2E1BCF9411A4CCB0D010B5954291453E761A3B9EAF533119EEF1C30C4E53FEFAF2D2300162786963D54ECE0376CC797CBBDD757B596FAB26716ECEA7C47FB6C6DC6A80FC435D5CADB36D5ACB6760CAC6272B61E64A920EC7D4E5FBD680B2B906F1CF78EFD380A47692E1DC6C06AC21255E65C3757E32C301B5ACD8BA136FEE7C19B858D8B60595946BF1D0520912ACD17E397C9FC156C741AD1104F403B363B4E6B4AD06E8C60928CCD6AB3FE6AEFECBC57DB5CFF431A2D44533D9A92C483B56AE56698F02622D3A65E09B6EBFDFD5DCAF34E09DEDA100B40DD4C40ADCEF30787E527C4F613A08BDED0F464B243 +20241201120212 2 6 100 7679 5 F02D40B37C40876939E4D2A62AF7EC21A676D8E2B04081BA98E23F464A47514FB40DC99F7B8046B48CD3052C7AC080E4B496C16ED18695CA27493A129088F5829BBEAD02DFD521829FFD8B1120330E2BBA10C55A1EAD0641006827DA4725BFD2A2559C363C33BC78C2D83B4A075099EC57634D0AD4AEDA3302441B7005C728C0371B51877A97B442C5E3C3D53C244EFF3B65CDCCB0C017723F1EBD0B91E220116ACF14703268A11B7FC7564F7BEDBFFB3CE046261DD9D83E6078CD7AB5AC97595EF53D6C4C56D24588C6D130C0CD2C967AB90C31497186A06A93FB9338D4F30E0104BC8EFF2518D0644174BD1FF1FD7BAC2AAFF151D733A14F456A189ECA2D5F11D7C3AF1DA06192D36251B050E1AC576E3C369678D12823870FFC6E5809903382F9FBE36156F294C94FF5369E8D24D085A326870A998A10683495CEF15EFF0A45C781B5156B82D9AA07852040A96A0D5ACDF094B9DD91EA893382F95A6B72F0A2090F036A1B23CF9CF544753EA5B9ED86FA52EBB4C5421C5B485AE932F5837822C91257EC4953ACA79F2D94261DC40B3D44CB44056D4025EC459563865000B8C5F5D7724ED27CA4A8ADE299E5C898F4BD09F430781A68C261E4FA0BA2FEE567434B057C5D5F2899A1547B780B91315CC631C0552DB403DF53A6059BE895242FDA4AE1F6C5129E3643DF1A20C28BBF4328B4E623DCBC1149CE838BBC4A9944A6B6ACB4AA29B50FC7AFFAB0075BB4CC190F15B2C17847560F1B4C591EFE90D5AAA307A3FCC091DF44E3B219F7EE86EA01704D652983CE0D475896C1EB94E09314D386233D706FE0F5415BAF51746F3E8A6AC74E6F68CCF665CCEC4BE0B9CE19308C0423491F5914EA8ABE6081F38282D4994A4B640DCE56F4D616CED59B80938E4E7C486AB64E7C740FCD6ADB5494906520FD66A02069D3C11085157142CDDBFB004023C5CDFCCEAC5296636A77C127DEC4182A36D6A34D980F778452271C80CABAFE15A629302EFE9CD9105353B719581D4DD2E1BCF9411A4CCB0D010B5954291453E761A3B9EAF533119EEF1C30C4E53FEFAF2D2300162786963D54ECE0376CC797CBBDD757B596FAB26716ECEA7C47FB6C6DC6A80FC435D5CADB36D5ACB6760CAC6272B61E64A920EC7D4E5FBD680B2B906F1CF78EFD380A47692E1DC6C06AC21255E65C3757E32C301B5ACD8BA136FEE7C19B858D8B60595946BF1D0520912ACD17E397C9FC156C741AD1104F403B363B4E6B4AD06E8C60928CCD6AB3FE6AEFECBC57DB5CFF431A2D44533D9A92C483B56AE56698F02622D3A65E09B6EBFDFD5DCAF34E09DEDA100B40DD4C40ADCEF30787E527C4F613A08BDED0F4DBBAFF +20241201123240 2 6 100 7679 2 F02D40B37C40876939E4D2A62AF7EC21A676D8E2B04081BA98E23F464A47514FB40DC99F7B8046B48CD3052C7AC080E4B496C16ED18695CA27493A129088F5829BBEAD02DFD521829FFD8B1120330E2BBA10C55A1EAD0641006827DA4725BFD2A2559C363C33BC78C2D83B4A075099EC57634D0AD4AEDA3302441B7005C728C0371B51877A97B442C5E3C3D53C244EFF3B65CDCCB0C017723F1EBD0B91E220116ACF14703268A11B7FC7564F7BEDBFFB3CE046261DD9D83E6078CD7AB5AC97595EF53D6C4C56D24588C6D130C0CD2C967AB90C31497186A06A93FB9338D4F30E0104BC8EFF2518D0644174BD1FF1FD7BAC2AAFF151D733A14F456A189ECA2D5F11D7C3AF1DA06192D36251B050E1AC576E3C369678D12823870FFC6E5809903382F9FBE36156F294C94FF5369E8D24D085A326870A998A10683495CEF15EFF0A45C781B5156B82D9AA07852040A96A0D5ACDF094B9DD91EA893382F95A6B72F0A2090F036A1B23CF9CF544753EA5B9ED86FA52EBB4C5421C5B485AE932F5837822C91257EC4953ACA79F2D94261DC40B3D44CB44056D4025EC459563865000B8C5F5D7724ED27CA4A8ADE299E5C898F4BD09F430781A68C261E4FA0BA2FEE567434B057C5D5F2899A1547B780B91315CC631C0552DB403DF53A6059BE895242FDA4AE1F6C5129E3643DF1A20C28BBF4328B4E623DCBC1149CE838BBC4A9944A6B6ACB4AA29B50FC7AFFAB0075BB4CC190F15B2C17847560F1B4C591EFE90D5AAA307A3FCC091DF44E3B219F7EE86EA01704D652983CE0D475896C1EB94E09314D386233D706FE0F5415BAF51746F3E8A6AC74E6F68CCF665CCEC4BE0B9CE19308C0423491F5914EA8ABE6081F38282D4994A4B640DCE56F4D616CED59B80938E4E7C486AB64E7C740FCD6ADB5494906520FD66A02069D3C11085157142CDDBFB004023C5CDFCCEAC5296636A77C127DEC4182A36D6A34D980F778452271C80CABAFE15A629302EFE9CD9105353B719581D4DD2E1BCF9411A4CCB0D010B5954291453E761A3B9EAF533119EEF1C30C4E53FEFAF2D2300162786963D54ECE0376CC797CBBDD757B596FAB26716ECEA7C47FB6C6DC6A80FC435D5CADB36D5ACB6760CAC6272B61E64A920EC7D4E5FBD680B2B906F1CF78EFD380A47692E1DC6C06AC21255E65C3757E32C301B5ACD8BA136FEE7C19B858D8B60595946BF1D0520912ACD17E397C9FC156C741AD1104F403B363B4E6B4AD06E8C60928CCD6AB3FE6AEFECBC57DB5CFF431A2D44533D9A92C483B56AE56698F02622D3A65E09B6EBFDFD5DCAF34E09DEDA100B40DD4C40ADCEF30787E527C4F613A08BDED0F6DA27E3 +20241201130824 2 6 100 7679 5 F02D40B37C40876939E4D2A62AF7EC21A676D8E2B04081BA98E23F464A47514FB40DC99F7B8046B48CD3052C7AC080E4B496C16ED18695CA27493A129088F5829BBEAD02DFD521829FFD8B1120330E2BBA10C55A1EAD0641006827DA4725BFD2A2559C363C33BC78C2D83B4A075099EC57634D0AD4AEDA3302441B7005C728C0371B51877A97B442C5E3C3D53C244EFF3B65CDCCB0C017723F1EBD0B91E220116ACF14703268A11B7FC7564F7BEDBFFB3CE046261DD9D83E6078CD7AB5AC97595EF53D6C4C56D24588C6D130C0CD2C967AB90C31497186A06A93FB9338D4F30E0104BC8EFF2518D0644174BD1FF1FD7BAC2AAFF151D733A14F456A189ECA2D5F11D7C3AF1DA06192D36251B050E1AC576E3C369678D12823870FFC6E5809903382F9FBE36156F294C94FF5369E8D24D085A326870A998A10683495CEF15EFF0A45C781B5156B82D9AA07852040A96A0D5ACDF094B9DD91EA893382F95A6B72F0A2090F036A1B23CF9CF544753EA5B9ED86FA52EBB4C5421C5B485AE932F5837822C91257EC4953ACA79F2D94261DC40B3D44CB44056D4025EC459563865000B8C5F5D7724ED27CA4A8ADE299E5C898F4BD09F430781A68C261E4FA0BA2FEE567434B057C5D5F2899A1547B780B91315CC631C0552DB403DF53A6059BE895242FDA4AE1F6C5129E3643DF1A20C28BBF4328B4E623DCBC1149CE838BBC4A9944A6B6ACB4AA29B50FC7AFFAB0075BB4CC190F15B2C17847560F1B4C591EFE90D5AAA307A3FCC091DF44E3B219F7EE86EA01704D652983CE0D475896C1EB94E09314D386233D706FE0F5415BAF51746F3E8A6AC74E6F68CCF665CCEC4BE0B9CE19308C0423491F5914EA8ABE6081F38282D4994A4B640DCE56F4D616CED59B80938E4E7C486AB64E7C740FCD6ADB5494906520FD66A02069D3C11085157142CDDBFB004023C5CDFCCEAC5296636A77C127DEC4182A36D6A34D980F778452271C80CABAFE15A629302EFE9CD9105353B719581D4DD2E1BCF9411A4CCB0D010B5954291453E761A3B9EAF533119EEF1C30C4E53FEFAF2D2300162786963D54ECE0376CC797CBBDD757B596FAB26716ECEA7C47FB6C6DC6A80FC435D5CADB36D5ACB6760CAC6272B61E64A920EC7D4E5FBD680B2B906F1CF78EFD380A47692E1DC6C06AC21255E65C3757E32C301B5ACD8BA136FEE7C19B858D8B60595946BF1D0520912ACD17E397C9FC156C741AD1104F403B363B4E6B4AD06E8C60928CCD6AB3FE6AEFECBC57DB5CFF431A2D44533D9A92C483B56AE56698F02622D3A65E09B6EBFDFD5DCAF34E09DEDA100B40DD4C40ADCEF30787E527C4F613A08BDED0F939BADF +20241201171234 2 6 100 7679 2 F02D40B37C40876939E4D2A62AF7EC21A676D8E2B04081BA98E23F464A47514FB40DC99F7B8046B48CD3052C7AC080E4B496C16ED18695CA27493A129088F5829BBEAD02DFD521829FFD8B1120330E2BBA10C55A1EAD0641006827DA4725BFD2A2559C363C33BC78C2D83B4A075099EC57634D0AD4AEDA3302441B7005C728C0371B51877A97B442C5E3C3D53C244EFF3B65CDCCB0C017723F1EBD0B91E220116ACF14703268A11B7FC7564F7BEDBFFB3CE046261DD9D83E6078CD7AB5AC97595EF53D6C4C56D24588C6D130C0CD2C967AB90C31497186A06A93FB9338D4F30E0104BC8EFF2518D0644174BD1FF1FD7BAC2AAFF151D733A14F456A189ECA2D5F11D7C3AF1DA06192D36251B050E1AC576E3C369678D12823870FFC6E5809903382F9FBE36156F294C94FF5369E8D24D085A326870A998A10683495CEF15EFF0A45C781B5156B82D9AA07852040A96A0D5ACDF094B9DD91EA893382F95A6B72F0A2090F036A1B23CF9CF544753EA5B9ED86FA52EBB4C5421C5B485AE932F5837822C91257EC4953ACA79F2D94261DC40B3D44CB44056D4025EC459563865000B8C5F5D7724ED27CA4A8ADE299E5C898F4BD09F430781A68C261E4FA0BA2FEE567434B057C5D5F2899A1547B780B91315CC631C0552DB403DF53A6059BE895242FDA4AE1F6C5129E3643DF1A20C28BBF4328B4E623DCBC1149CE838BBC4A9944A6B6ACB4AA29B50FC7AFFAB0075BB4CC190F15B2C17847560F1B4C591EFE90D5AAA307A3FCC091DF44E3B219F7EE86EA01704D652983CE0D475896C1EB94E09314D386233D706FE0F5415BAF51746F3E8A6AC74E6F68CCF665CCEC4BE0B9CE19308C0423491F5914EA8ABE6081F38282D4994A4B640DCE56F4D616CED59B80938E4E7C486AB64E7C740FCD6ADB5494906520FD66A02069D3C11085157142CDDBFB004023C5CDFCCEAC5296636A77C127DEC4182A36D6A34D980F778452271C80CABAFE15A629302EFE9CD9105353B719581D4DD2E1BCF9411A4CCB0D010B5954291453E761A3B9EAF533119EEF1C30C4E53FEFAF2D2300162786963D54ECE0376CC797CBBDD757B596FAB26716ECEA7C47FB6C6DC6A80FC435D5CADB36D5ACB6760CAC6272B61E64A920EC7D4E5FBD680B2B906F1CF78EFD380A47692E1DC6C06AC21255E65C3757E32C301B5ACD8BA136FEE7C19B858D8B60595946BF1D0520912ACD17E397C9FC156C741AD1104F403B363B4E6B4AD06E8C60928CCD6AB3FE6AEFECBC57DB5CFF431A2D44533D9A92C483B56AE56698F02622D3A65E09B6EBFDFD5DCAF34E09DEDA100B40DD4C40ADCEF30787E527C4F613A08BDED109A1419B +20241201182756 2 6 100 7679 2 F02D40B37C40876939E4D2A62AF7EC21A676D8E2B04081BA98E23F464A47514FB40DC99F7B8046B48CD3052C7AC080E4B496C16ED18695CA27493A129088F5829BBEAD02DFD521829FFD8B1120330E2BBA10C55A1EAD0641006827DA4725BFD2A2559C363C33BC78C2D83B4A075099EC57634D0AD4AEDA3302441B7005C728C0371B51877A97B442C5E3C3D53C244EFF3B65CDCCB0C017723F1EBD0B91E220116ACF14703268A11B7FC7564F7BEDBFFB3CE046261DD9D83E6078CD7AB5AC97595EF53D6C4C56D24588C6D130C0CD2C967AB90C31497186A06A93FB9338D4F30E0104BC8EFF2518D0644174BD1FF1FD7BAC2AAFF151D733A14F456A189ECA2D5F11D7C3AF1DA06192D36251B050E1AC576E3C369678D12823870FFC6E5809903382F9FBE36156F294C94FF5369E8D24D085A326870A998A10683495CEF15EFF0A45C781B5156B82D9AA07852040A96A0D5ACDF094B9DD91EA893382F95A6B72F0A2090F036A1B23CF9CF544753EA5B9ED86FA52EBB4C5421C5B485AE932F5837822C91257EC4953ACA79F2D94261DC40B3D44CB44056D4025EC459563865000B8C5F5D7724ED27CA4A8ADE299E5C898F4BD09F430781A68C261E4FA0BA2FEE567434B057C5D5F2899A1547B780B91315CC631C0552DB403DF53A6059BE895242FDA4AE1F6C5129E3643DF1A20C28BBF4328B4E623DCBC1149CE838BBC4A9944A6B6ACB4AA29B50FC7AFFAB0075BB4CC190F15B2C17847560F1B4C591EFE90D5AAA307A3FCC091DF44E3B219F7EE86EA01704D652983CE0D475896C1EB94E09314D386233D706FE0F5415BAF51746F3E8A6AC74E6F68CCF665CCEC4BE0B9CE19308C0423491F5914EA8ABE6081F38282D4994A4B640DCE56F4D616CED59B80938E4E7C486AB64E7C740FCD6ADB5494906520FD66A02069D3C11085157142CDDBFB004023C5CDFCCEAC5296636A77C127DEC4182A36D6A34D980F778452271C80CABAFE15A629302EFE9CD9105353B719581D4DD2E1BCF9411A4CCB0D010B5954291453E761A3B9EAF533119EEF1C30C4E53FEFAF2D2300162786963D54ECE0376CC797CBBDD757B596FAB26716ECEA7C47FB6C6DC6A80FC435D5CADB36D5ACB6760CAC6272B61E64A920EC7D4E5FBD680B2B906F1CF78EFD380A47692E1DC6C06AC21255E65C3757E32C301B5ACD8BA136FEE7C19B858D8B60595946BF1D0520912ACD17E397C9FC156C741AD1104F403B363B4E6B4AD06E8C60928CCD6AB3FE6AEFECBC57DB5CFF431A2D44533D9A92C483B56AE56698F02622D3A65E09B6EBFDFD5DCAF34E09DEDA100B40DD4C40ADCEF30787E527C4F613A08BDED10EB1D8A3 +20241201190812 2 6 100 7679 5 F02D40B37C40876939E4D2A62AF7EC21A676D8E2B04081BA98E23F464A47514FB40DC99F7B8046B48CD3052C7AC080E4B496C16ED18695CA27493A129088F5829BBEAD02DFD521829FFD8B1120330E2BBA10C55A1EAD0641006827DA4725BFD2A2559C363C33BC78C2D83B4A075099EC57634D0AD4AEDA3302441B7005C728C0371B51877A97B442C5E3C3D53C244EFF3B65CDCCB0C017723F1EBD0B91E220116ACF14703268A11B7FC7564F7BEDBFFB3CE046261DD9D83E6078CD7AB5AC97595EF53D6C4C56D24588C6D130C0CD2C967AB90C31497186A06A93FB9338D4F30E0104BC8EFF2518D0644174BD1FF1FD7BAC2AAFF151D733A14F456A189ECA2D5F11D7C3AF1DA06192D36251B050E1AC576E3C369678D12823870FFC6E5809903382F9FBE36156F294C94FF5369E8D24D085A326870A998A10683495CEF15EFF0A45C781B5156B82D9AA07852040A96A0D5ACDF094B9DD91EA893382F95A6B72F0A2090F036A1B23CF9CF544753EA5B9ED86FA52EBB4C5421C5B485AE932F5837822C91257EC4953ACA79F2D94261DC40B3D44CB44056D4025EC459563865000B8C5F5D7724ED27CA4A8ADE299E5C898F4BD09F430781A68C261E4FA0BA2FEE567434B057C5D5F2899A1547B780B91315CC631C0552DB403DF53A6059BE895242FDA4AE1F6C5129E3643DF1A20C28BBF4328B4E623DCBC1149CE838BBC4A9944A6B6ACB4AA29B50FC7AFFAB0075BB4CC190F15B2C17847560F1B4C591EFE90D5AAA307A3FCC091DF44E3B219F7EE86EA01704D652983CE0D475896C1EB94E09314D386233D706FE0F5415BAF51746F3E8A6AC74E6F68CCF665CCEC4BE0B9CE19308C0423491F5914EA8ABE6081F38282D4994A4B640DCE56F4D616CED59B80938E4E7C486AB64E7C740FCD6ADB5494906520FD66A02069D3C11085157142CDDBFB004023C5CDFCCEAC5296636A77C127DEC4182A36D6A34D980F778452271C80CABAFE15A629302EFE9CD9105353B719581D4DD2E1BCF9411A4CCB0D010B5954291453E761A3B9EAF533119EEF1C30C4E53FEFAF2D2300162786963D54ECE0376CC797CBBDD757B596FAB26716ECEA7C47FB6C6DC6A80FC435D5CADB36D5ACB6760CAC6272B61E64A920EC7D4E5FBD680B2B906F1CF78EFD380A47692E1DC6C06AC21255E65C3757E32C301B5ACD8BA136FEE7C19B858D8B60595946BF1D0520912ACD17E397C9FC156C741AD1104F403B363B4E6B4AD06E8C60928CCD6AB3FE6AEFECBC57DB5CFF431A2D44533D9A92C483B56AE56698F02622D3A65E09B6EBFDFD5DCAF34E09DEDA100B40DD4C40ADCEF30787E527C4F613A08BDED11163FE8F +20241201191642 2 6 100 7679 2 F02D40B37C40876939E4D2A62AF7EC21A676D8E2B04081BA98E23F464A47514FB40DC99F7B8046B48CD3052C7AC080E4B496C16ED18695CA27493A129088F5829BBEAD02DFD521829FFD8B1120330E2BBA10C55A1EAD0641006827DA4725BFD2A2559C363C33BC78C2D83B4A075099EC57634D0AD4AEDA3302441B7005C728C0371B51877A97B442C5E3C3D53C244EFF3B65CDCCB0C017723F1EBD0B91E220116ACF14703268A11B7FC7564F7BEDBFFB3CE046261DD9D83E6078CD7AB5AC97595EF53D6C4C56D24588C6D130C0CD2C967AB90C31497186A06A93FB9338D4F30E0104BC8EFF2518D0644174BD1FF1FD7BAC2AAFF151D733A14F456A189ECA2D5F11D7C3AF1DA06192D36251B050E1AC576E3C369678D12823870FFC6E5809903382F9FBE36156F294C94FF5369E8D24D085A326870A998A10683495CEF15EFF0A45C781B5156B82D9AA07852040A96A0D5ACDF094B9DD91EA893382F95A6B72F0A2090F036A1B23CF9CF544753EA5B9ED86FA52EBB4C5421C5B485AE932F5837822C91257EC4953ACA79F2D94261DC40B3D44CB44056D4025EC459563865000B8C5F5D7724ED27CA4A8ADE299E5C898F4BD09F430781A68C261E4FA0BA2FEE567434B057C5D5F2899A1547B780B91315CC631C0552DB403DF53A6059BE895242FDA4AE1F6C5129E3643DF1A20C28BBF4328B4E623DCBC1149CE838BBC4A9944A6B6ACB4AA29B50FC7AFFAB0075BB4CC190F15B2C17847560F1B4C591EFE90D5AAA307A3FCC091DF44E3B219F7EE86EA01704D652983CE0D475896C1EB94E09314D386233D706FE0F5415BAF51746F3E8A6AC74E6F68CCF665CCEC4BE0B9CE19308C0423491F5914EA8ABE6081F38282D4994A4B640DCE56F4D616CED59B80938E4E7C486AB64E7C740FCD6ADB5494906520FD66A02069D3C11085157142CDDBFB004023C5CDFCCEAC5296636A77C127DEC4182A36D6A34D980F778452271C80CABAFE15A629302EFE9CD9105353B719581D4DD2E1BCF9411A4CCB0D010B5954291453E761A3B9EAF533119EEF1C30C4E53FEFAF2D2300162786963D54ECE0376CC797CBBDD757B596FAB26716ECEA7C47FB6C6DC6A80FC435D5CADB36D5ACB6760CAC6272B61E64A920EC7D4E5FBD680B2B906F1CF78EFD380A47692E1DC6C06AC21255E65C3757E32C301B5ACD8BA136FEE7C19B858D8B60595946BF1D0520912ACD17E397C9FC156C741AD1104F403B363B4E6B4AD06E8C60928CCD6AB3FE6AEFECBC57DB5CFF431A2D44533D9A92C483B56AE56698F02622D3A65E09B6EBFDFD5DCAF34E09DEDA100B40DD4C40ADCEF30787E527C4F613A08BDED111F0947B +20241201195706 2 6 100 7679 2 F02D40B37C40876939E4D2A62AF7EC21A676D8E2B04081BA98E23F464A47514FB40DC99F7B8046B48CD3052C7AC080E4B496C16ED18695CA27493A129088F5829BBEAD02DFD521829FFD8B1120330E2BBA10C55A1EAD0641006827DA4725BFD2A2559C363C33BC78C2D83B4A075099EC57634D0AD4AEDA3302441B7005C728C0371B51877A97B442C5E3C3D53C244EFF3B65CDCCB0C017723F1EBD0B91E220116ACF14703268A11B7FC7564F7BEDBFFB3CE046261DD9D83E6078CD7AB5AC97595EF53D6C4C56D24588C6D130C0CD2C967AB90C31497186A06A93FB9338D4F30E0104BC8EFF2518D0644174BD1FF1FD7BAC2AAFF151D733A14F456A189ECA2D5F11D7C3AF1DA06192D36251B050E1AC576E3C369678D12823870FFC6E5809903382F9FBE36156F294C94FF5369E8D24D085A326870A998A10683495CEF15EFF0A45C781B5156B82D9AA07852040A96A0D5ACDF094B9DD91EA893382F95A6B72F0A2090F036A1B23CF9CF544753EA5B9ED86FA52EBB4C5421C5B485AE932F5837822C91257EC4953ACA79F2D94261DC40B3D44CB44056D4025EC459563865000B8C5F5D7724ED27CA4A8ADE299E5C898F4BD09F430781A68C261E4FA0BA2FEE567434B057C5D5F2899A1547B780B91315CC631C0552DB403DF53A6059BE895242FDA4AE1F6C5129E3643DF1A20C28BBF4328B4E623DCBC1149CE838BBC4A9944A6B6ACB4AA29B50FC7AFFAB0075BB4CC190F15B2C17847560F1B4C591EFE90D5AAA307A3FCC091DF44E3B219F7EE86EA01704D652983CE0D475896C1EB94E09314D386233D706FE0F5415BAF51746F3E8A6AC74E6F68CCF665CCEC4BE0B9CE19308C0423491F5914EA8ABE6081F38282D4994A4B640DCE56F4D616CED59B80938E4E7C486AB64E7C740FCD6ADB5494906520FD66A02069D3C11085157142CDDBFB004023C5CDFCCEAC5296636A77C127DEC4182A36D6A34D980F778452271C80CABAFE15A629302EFE9CD9105353B719581D4DD2E1BCF9411A4CCB0D010B5954291453E761A3B9EAF533119EEF1C30C4E53FEFAF2D2300162786963D54ECE0376CC797CBBDD757B596FAB26716ECEA7C47FB6C6DC6A80FC435D5CADB36D5ACB6760CAC6272B61E64A920EC7D4E5FBD680B2B906F1CF78EFD380A47692E1DC6C06AC21255E65C3757E32C301B5ACD8BA136FEE7C19B858D8B60595946BF1D0520912ACD17E397C9FC156C741AD1104F403B363B4E6B4AD06E8C60928CCD6AB3FE6AEFECBC57DB5CFF431A2D44533D9A92C483B56AE56698F02622D3A65E09B6EBFDFD5DCAF34E09DEDA100B40DD4C40ADCEF30787E527C4F613A08BDED11498BEA3 +20241201200433 2 6 100 7679 5 F02D40B37C40876939E4D2A62AF7EC21A676D8E2B04081BA98E23F464A47514FB40DC99F7B8046B48CD3052C7AC080E4B496C16ED18695CA27493A129088F5829BBEAD02DFD521829FFD8B1120330E2BBA10C55A1EAD0641006827DA4725BFD2A2559C363C33BC78C2D83B4A075099EC57634D0AD4AEDA3302441B7005C728C0371B51877A97B442C5E3C3D53C244EFF3B65CDCCB0C017723F1EBD0B91E220116ACF14703268A11B7FC7564F7BEDBFFB3CE046261DD9D83E6078CD7AB5AC97595EF53D6C4C56D24588C6D130C0CD2C967AB90C31497186A06A93FB9338D4F30E0104BC8EFF2518D0644174BD1FF1FD7BAC2AAFF151D733A14F456A189ECA2D5F11D7C3AF1DA06192D36251B050E1AC576E3C369678D12823870FFC6E5809903382F9FBE36156F294C94FF5369E8D24D085A326870A998A10683495CEF15EFF0A45C781B5156B82D9AA07852040A96A0D5ACDF094B9DD91EA893382F95A6B72F0A2090F036A1B23CF9CF544753EA5B9ED86FA52EBB4C5421C5B485AE932F5837822C91257EC4953ACA79F2D94261DC40B3D44CB44056D4025EC459563865000B8C5F5D7724ED27CA4A8ADE299E5C898F4BD09F430781A68C261E4FA0BA2FEE567434B057C5D5F2899A1547B780B91315CC631C0552DB403DF53A6059BE895242FDA4AE1F6C5129E3643DF1A20C28BBF4328B4E623DCBC1149CE838BBC4A9944A6B6ACB4AA29B50FC7AFFAB0075BB4CC190F15B2C17847560F1B4C591EFE90D5AAA307A3FCC091DF44E3B219F7EE86EA01704D652983CE0D475896C1EB94E09314D386233D706FE0F5415BAF51746F3E8A6AC74E6F68CCF665CCEC4BE0B9CE19308C0423491F5914EA8ABE6081F38282D4994A4B640DCE56F4D616CED59B80938E4E7C486AB64E7C740FCD6ADB5494906520FD66A02069D3C11085157142CDDBFB004023C5CDFCCEAC5296636A77C127DEC4182A36D6A34D980F778452271C80CABAFE15A629302EFE9CD9105353B719581D4DD2E1BCF9411A4CCB0D010B5954291453E761A3B9EAF533119EEF1C30C4E53FEFAF2D2300162786963D54ECE0376CC797CBBDD757B596FAB26716ECEA7C47FB6C6DC6A80FC435D5CADB36D5ACB6760CAC6272B61E64A920EC7D4E5FBD680B2B906F1CF78EFD380A47692E1DC6C06AC21255E65C3757E32C301B5ACD8BA136FEE7C19B858D8B60595946BF1D0520912ACD17E397C9FC156C741AD1104F403B363B4E6B4AD06E8C60928CCD6AB3FE6AEFECBC57DB5CFF431A2D44533D9A92C483B56AE56698F02622D3A65E09B6EBFDFD5DCAF34E09DEDA100B40DD4C40ADCEF30787E527C4F613A08BDED115134B17 +20241201200527 2 6 100 7679 5 F02D40B37C40876939E4D2A62AF7EC21A676D8E2B04081BA98E23F464A47514FB40DC99F7B8046B48CD3052C7AC080E4B496C16ED18695CA27493A129088F5829BBEAD02DFD521829FFD8B1120330E2BBA10C55A1EAD0641006827DA4725BFD2A2559C363C33BC78C2D83B4A075099EC57634D0AD4AEDA3302441B7005C728C0371B51877A97B442C5E3C3D53C244EFF3B65CDCCB0C017723F1EBD0B91E220116ACF14703268A11B7FC7564F7BEDBFFB3CE046261DD9D83E6078CD7AB5AC97595EF53D6C4C56D24588C6D130C0CD2C967AB90C31497186A06A93FB9338D4F30E0104BC8EFF2518D0644174BD1FF1FD7BAC2AAFF151D733A14F456A189ECA2D5F11D7C3AF1DA06192D36251B050E1AC576E3C369678D12823870FFC6E5809903382F9FBE36156F294C94FF5369E8D24D085A326870A998A10683495CEF15EFF0A45C781B5156B82D9AA07852040A96A0D5ACDF094B9DD91EA893382F95A6B72F0A2090F036A1B23CF9CF544753EA5B9ED86FA52EBB4C5421C5B485AE932F5837822C91257EC4953ACA79F2D94261DC40B3D44CB44056D4025EC459563865000B8C5F5D7724ED27CA4A8ADE299E5C898F4BD09F430781A68C261E4FA0BA2FEE567434B057C5D5F2899A1547B780B91315CC631C0552DB403DF53A6059BE895242FDA4AE1F6C5129E3643DF1A20C28BBF4328B4E623DCBC1149CE838BBC4A9944A6B6ACB4AA29B50FC7AFFAB0075BB4CC190F15B2C17847560F1B4C591EFE90D5AAA307A3FCC091DF44E3B219F7EE86EA01704D652983CE0D475896C1EB94E09314D386233D706FE0F5415BAF51746F3E8A6AC74E6F68CCF665CCEC4BE0B9CE19308C0423491F5914EA8ABE6081F38282D4994A4B640DCE56F4D616CED59B80938E4E7C486AB64E7C740FCD6ADB5494906520FD66A02069D3C11085157142CDDBFB004023C5CDFCCEAC5296636A77C127DEC4182A36D6A34D980F778452271C80CABAFE15A629302EFE9CD9105353B719581D4DD2E1BCF9411A4CCB0D010B5954291453E761A3B9EAF533119EEF1C30C4E53FEFAF2D2300162786963D54ECE0376CC797CBBDD757B596FAB26716ECEA7C47FB6C6DC6A80FC435D5CADB36D5ACB6760CAC6272B61E64A920EC7D4E5FBD680B2B906F1CF78EFD380A47692E1DC6C06AC21255E65C3757E32C301B5ACD8BA136FEE7C19B858D8B60595946BF1D0520912ACD17E397C9FC156C741AD1104F403B363B4E6B4AD06E8C60928CCD6AB3FE6AEFECBC57DB5CFF431A2D44533D9A92C483B56AE56698F02622D3A65E09B6EBFDFD5DCAF34E09DEDA100B40DD4C40ADCEF30787E527C4F613A08BDED1151A85B7 +20241201205110 2 6 100 7679 5 F02D40B37C40876939E4D2A62AF7EC21A676D8E2B04081BA98E23F464A47514FB40DC99F7B8046B48CD3052C7AC080E4B496C16ED18695CA27493A129088F5829BBEAD02DFD521829FFD8B1120330E2BBA10C55A1EAD0641006827DA4725BFD2A2559C363C33BC78C2D83B4A075099EC57634D0AD4AEDA3302441B7005C728C0371B51877A97B442C5E3C3D53C244EFF3B65CDCCB0C017723F1EBD0B91E220116ACF14703268A11B7FC7564F7BEDBFFB3CE046261DD9D83E6078CD7AB5AC97595EF53D6C4C56D24588C6D130C0CD2C967AB90C31497186A06A93FB9338D4F30E0104BC8EFF2518D0644174BD1FF1FD7BAC2AAFF151D733A14F456A189ECA2D5F11D7C3AF1DA06192D36251B050E1AC576E3C369678D12823870FFC6E5809903382F9FBE36156F294C94FF5369E8D24D085A326870A998A10683495CEF15EFF0A45C781B5156B82D9AA07852040A96A0D5ACDF094B9DD91EA893382F95A6B72F0A2090F036A1B23CF9CF544753EA5B9ED86FA52EBB4C5421C5B485AE932F5837822C91257EC4953ACA79F2D94261DC40B3D44CB44056D4025EC459563865000B8C5F5D7724ED27CA4A8ADE299E5C898F4BD09F430781A68C261E4FA0BA2FEE567434B057C5D5F2899A1547B780B91315CC631C0552DB403DF53A6059BE895242FDA4AE1F6C5129E3643DF1A20C28BBF4328B4E623DCBC1149CE838BBC4A9944A6B6ACB4AA29B50FC7AFFAB0075BB4CC190F15B2C17847560F1B4C591EFE90D5AAA307A3FCC091DF44E3B219F7EE86EA01704D652983CE0D475896C1EB94E09314D386233D706FE0F5415BAF51746F3E8A6AC74E6F68CCF665CCEC4BE0B9CE19308C0423491F5914EA8ABE6081F38282D4994A4B640DCE56F4D616CED59B80938E4E7C486AB64E7C740FCD6ADB5494906520FD66A02069D3C11085157142CDDBFB004023C5CDFCCEAC5296636A77C127DEC4182A36D6A34D980F778452271C80CABAFE15A629302EFE9CD9105353B719581D4DD2E1BCF9411A4CCB0D010B5954291453E761A3B9EAF533119EEF1C30C4E53FEFAF2D2300162786963D54ECE0376CC797CBBDD757B596FAB26716ECEA7C47FB6C6DC6A80FC435D5CADB36D5ACB6760CAC6272B61E64A920EC7D4E5FBD680B2B906F1CF78EFD380A47692E1DC6C06AC21255E65C3757E32C301B5ACD8BA136FEE7C19B858D8B60595946BF1D0520912ACD17E397C9FC156C741AD1104F403B363B4E6B4AD06E8C60928CCD6AB3FE6AEFECBC57DB5CFF431A2D44533D9A92C483B56AE56698F02622D3A65E09B6EBFDFD5DCAF34E09DEDA100B40DD4C40ADCEF30787E527C4F613A08BDED1181F734F +20241201205604 2 6 100 7679 5 F02D40B37C40876939E4D2A62AF7EC21A676D8E2B04081BA98E23F464A47514FB40DC99F7B8046B48CD3052C7AC080E4B496C16ED18695CA27493A129088F5829BBEAD02DFD521829FFD8B1120330E2BBA10C55A1EAD0641006827DA4725BFD2A2559C363C33BC78C2D83B4A075099EC57634D0AD4AEDA3302441B7005C728C0371B51877A97B442C5E3C3D53C244EFF3B65CDCCB0C017723F1EBD0B91E220116ACF14703268A11B7FC7564F7BEDBFFB3CE046261DD9D83E6078CD7AB5AC97595EF53D6C4C56D24588C6D130C0CD2C967AB90C31497186A06A93FB9338D4F30E0104BC8EFF2518D0644174BD1FF1FD7BAC2AAFF151D733A14F456A189ECA2D5F11D7C3AF1DA06192D36251B050E1AC576E3C369678D12823870FFC6E5809903382F9FBE36156F294C94FF5369E8D24D085A326870A998A10683495CEF15EFF0A45C781B5156B82D9AA07852040A96A0D5ACDF094B9DD91EA893382F95A6B72F0A2090F036A1B23CF9CF544753EA5B9ED86FA52EBB4C5421C5B485AE932F5837822C91257EC4953ACA79F2D94261DC40B3D44CB44056D4025EC459563865000B8C5F5D7724ED27CA4A8ADE299E5C898F4BD09F430781A68C261E4FA0BA2FEE567434B057C5D5F2899A1547B780B91315CC631C0552DB403DF53A6059BE895242FDA4AE1F6C5129E3643DF1A20C28BBF4328B4E623DCBC1149CE838BBC4A9944A6B6ACB4AA29B50FC7AFFAB0075BB4CC190F15B2C17847560F1B4C591EFE90D5AAA307A3FCC091DF44E3B219F7EE86EA01704D652983CE0D475896C1EB94E09314D386233D706FE0F5415BAF51746F3E8A6AC74E6F68CCF665CCEC4BE0B9CE19308C0423491F5914EA8ABE6081F38282D4994A4B640DCE56F4D616CED59B80938E4E7C486AB64E7C740FCD6ADB5494906520FD66A02069D3C11085157142CDDBFB004023C5CDFCCEAC5296636A77C127DEC4182A36D6A34D980F778452271C80CABAFE15A629302EFE9CD9105353B719581D4DD2E1BCF9411A4CCB0D010B5954291453E761A3B9EAF533119EEF1C30C4E53FEFAF2D2300162786963D54ECE0376CC797CBBDD757B596FAB26716ECEA7C47FB6C6DC6A80FC435D5CADB36D5ACB6760CAC6272B61E64A920EC7D4E5FBD680B2B906F1CF78EFD380A47692E1DC6C06AC21255E65C3757E32C301B5ACD8BA136FEE7C19B858D8B60595946BF1D0520912ACD17E397C9FC156C741AD1104F403B363B4E6B4AD06E8C60928CCD6AB3FE6AEFECBC57DB5CFF431A2D44533D9A92C483B56AE56698F02622D3A65E09B6EBFDFD5DCAF34E09DEDA100B40DD4C40ADCEF30787E527C4F613A08BDED1186965DF +20241201232404 2 6 100 7679 5 F02D40B37C40876939E4D2A62AF7EC21A676D8E2B04081BA98E23F464A47514FB40DC99F7B8046B48CD3052C7AC080E4B496C16ED18695CA27493A129088F5829BBEAD02DFD521829FFD8B1120330E2BBA10C55A1EAD0641006827DA4725BFD2A2559C363C33BC78C2D83B4A075099EC57634D0AD4AEDA3302441B7005C728C0371B51877A97B442C5E3C3D53C244EFF3B65CDCCB0C017723F1EBD0B91E220116ACF14703268A11B7FC7564F7BEDBFFB3CE046261DD9D83E6078CD7AB5AC97595EF53D6C4C56D24588C6D130C0CD2C967AB90C31497186A06A93FB9338D4F30E0104BC8EFF2518D0644174BD1FF1FD7BAC2AAFF151D733A14F456A189ECA2D5F11D7C3AF1DA06192D36251B050E1AC576E3C369678D12823870FFC6E5809903382F9FBE36156F294C94FF5369E8D24D085A326870A998A10683495CEF15EFF0A45C781B5156B82D9AA07852040A96A0D5ACDF094B9DD91EA893382F95A6B72F0A2090F036A1B23CF9CF544753EA5B9ED86FA52EBB4C5421C5B485AE932F5837822C91257EC4953ACA79F2D94261DC40B3D44CB44056D4025EC459563865000B8C5F5D7724ED27CA4A8ADE299E5C898F4BD09F430781A68C261E4FA0BA2FEE567434B057C5D5F2899A1547B780B91315CC631C0552DB403DF53A6059BE895242FDA4AE1F6C5129E3643DF1A20C28BBF4328B4E623DCBC1149CE838BBC4A9944A6B6ACB4AA29B50FC7AFFAB0075BB4CC190F15B2C17847560F1B4C591EFE90D5AAA307A3FCC091DF44E3B219F7EE86EA01704D652983CE0D475896C1EB94E09314D386233D706FE0F5415BAF51746F3E8A6AC74E6F68CCF665CCEC4BE0B9CE19308C0423491F5914EA8ABE6081F38282D4994A4B640DCE56F4D616CED59B80938E4E7C486AB64E7C740FCD6ADB5494906520FD66A02069D3C11085157142CDDBFB004023C5CDFCCEAC5296636A77C127DEC4182A36D6A34D980F778452271C80CABAFE15A629302EFE9CD9105353B719581D4DD2E1BCF9411A4CCB0D010B5954291453E761A3B9EAF533119EEF1C30C4E53FEFAF2D2300162786963D54ECE0376CC797CBBDD757B596FAB26716ECEA7C47FB6C6DC6A80FC435D5CADB36D5ACB6760CAC6272B61E64A920EC7D4E5FBD680B2B906F1CF78EFD380A47692E1DC6C06AC21255E65C3757E32C301B5ACD8BA136FEE7C19B858D8B60595946BF1D0520912ACD17E397C9FC156C741AD1104F403B363B4E6B4AD06E8C60928CCD6AB3FE6AEFECBC57DB5CFF431A2D44533D9A92C483B56AE56698F02622D3A65E09B6EBFDFD5DCAF34E09DEDA100B40DD4C40ADCEF30787E527C4F613A08BDED1224C1B97 +20241202014307 2 6 100 7679 5 F02D40B37C40876939E4D2A62AF7EC21A676D8E2B04081BA98E23F464A47514FB40DC99F7B8046B48CD3052C7AC080E4B496C16ED18695CA27493A129088F5829BBEAD02DFD521829FFD8B1120330E2BBA10C55A1EAD0641006827DA4725BFD2A2559C363C33BC78C2D83B4A075099EC57634D0AD4AEDA3302441B7005C728C0371B51877A97B442C5E3C3D53C244EFF3B65CDCCB0C017723F1EBD0B91E220116ACF14703268A11B7FC7564F7BEDBFFB3CE046261DD9D83E6078CD7AB5AC97595EF53D6C4C56D24588C6D130C0CD2C967AB90C31497186A06A93FB9338D4F30E0104BC8EFF2518D0644174BD1FF1FD7BAC2AAFF151D733A14F456A189ECA2D5F11D7C3AF1DA06192D36251B050E1AC576E3C369678D12823870FFC6E5809903382F9FBE36156F294C94FF5369E8D24D085A326870A998A10683495CEF15EFF0A45C781B5156B82D9AA07852040A96A0D5ACDF094B9DD91EA893382F95A6B72F0A2090F036A1B23CF9CF544753EA5B9ED86FA52EBB4C5421C5B485AE932F5837822C91257EC4953ACA79F2D94261DC40B3D44CB44056D4025EC459563865000B8C5F5D7724ED27CA4A8ADE299E5C898F4BD09F430781A68C261E4FA0BA2FEE567434B057C5D5F2899A1547B780B91315CC631C0552DB403DF53A6059BE895242FDA4AE1F6C5129E3643DF1A20C28BBF4328B4E623DCBC1149CE838BBC4A9944A6B6ACB4AA29B50FC7AFFAB0075BB4CC190F15B2C17847560F1B4C591EFE90D5AAA307A3FCC091DF44E3B219F7EE86EA01704D652983CE0D475896C1EB94E09314D386233D706FE0F5415BAF51746F3E8A6AC74E6F68CCF665CCEC4BE0B9CE19308C0423491F5914EA8ABE6081F38282D4994A4B640DCE56F4D616CED59B80938E4E7C486AB64E7C740FCD6ADB5494906520FD66A02069D3C11085157142CDDBFB004023C5CDFCCEAC5296636A77C127DEC4182A36D6A34D980F778452271C80CABAFE15A629302EFE9CD9105353B719581D4DD2E1BCF9411A4CCB0D010B5954291453E761A3B9EAF533119EEF1C30C4E53FEFAF2D2300162786963D54ECE0376CC797CBBDD757B596FAB26716ECEA7C47FB6C6DC6A80FC435D5CADB36D5ACB6760CAC6272B61E64A920EC7D4E5FBD680B2B906F1CF78EFD380A47692E1DC6C06AC21255E65C3757E32C301B5ACD8BA136FEE7C19B858D8B60595946BF1D0520912ACD17E397C9FC156C741AD1104F403B363B4E6B4AD06E8C60928CCD6AB3FE6AEFECBC57DB5CFF431A2D44533D9A92C483B56AE56698F02622D3A65E09B6EBFDFD5DCAF34E09DEDA100B40DD4C40ADCEF30787E527C4F613A08BDED12B98711F +20241202022245 2 6 100 7679 5 F02D40B37C40876939E4D2A62AF7EC21A676D8E2B04081BA98E23F464A47514FB40DC99F7B8046B48CD3052C7AC080E4B496C16ED18695CA27493A129088F5829BBEAD02DFD521829FFD8B1120330E2BBA10C55A1EAD0641006827DA4725BFD2A2559C363C33BC78C2D83B4A075099EC57634D0AD4AEDA3302441B7005C728C0371B51877A97B442C5E3C3D53C244EFF3B65CDCCB0C017723F1EBD0B91E220116ACF14703268A11B7FC7564F7BEDBFFB3CE046261DD9D83E6078CD7AB5AC97595EF53D6C4C56D24588C6D130C0CD2C967AB90C31497186A06A93FB9338D4F30E0104BC8EFF2518D0644174BD1FF1FD7BAC2AAFF151D733A14F456A189ECA2D5F11D7C3AF1DA06192D36251B050E1AC576E3C369678D12823870FFC6E5809903382F9FBE36156F294C94FF5369E8D24D085A326870A998A10683495CEF15EFF0A45C781B5156B82D9AA07852040A96A0D5ACDF094B9DD91EA893382F95A6B72F0A2090F036A1B23CF9CF544753EA5B9ED86FA52EBB4C5421C5B485AE932F5837822C91257EC4953ACA79F2D94261DC40B3D44CB44056D4025EC459563865000B8C5F5D7724ED27CA4A8ADE299E5C898F4BD09F430781A68C261E4FA0BA2FEE567434B057C5D5F2899A1547B780B91315CC631C0552DB403DF53A6059BE895242FDA4AE1F6C5129E3643DF1A20C28BBF4328B4E623DCBC1149CE838BBC4A9944A6B6ACB4AA29B50FC7AFFAB0075BB4CC190F15B2C17847560F1B4C591EFE90D5AAA307A3FCC091DF44E3B219F7EE86EA01704D652983CE0D475896C1EB94E09314D386233D706FE0F5415BAF51746F3E8A6AC74E6F68CCF665CCEC4BE0B9CE19308C0423491F5914EA8ABE6081F38282D4994A4B640DCE56F4D616CED59B80938E4E7C486AB64E7C740FCD6ADB5494906520FD66A02069D3C11085157142CDDBFB004023C5CDFCCEAC5296636A77C127DEC4182A36D6A34D980F778452271C80CABAFE15A629302EFE9CD9105353B719581D4DD2E1BCF9411A4CCB0D010B5954291453E761A3B9EAF533119EEF1C30C4E53FEFAF2D2300162786963D54ECE0376CC797CBBDD757B596FAB26716ECEA7C47FB6C6DC6A80FC435D5CADB36D5ACB6760CAC6272B61E64A920EC7D4E5FBD680B2B906F1CF78EFD380A47692E1DC6C06AC21255E65C3757E32C301B5ACD8BA136FEE7C19B858D8B60595946BF1D0520912ACD17E397C9FC156C741AD1104F403B363B4E6B4AD06E8C60928CCD6AB3FE6AEFECBC57DB5CFF431A2D44533D9A92C483B56AE56698F02622D3A65E09B6EBFDFD5DCAF34E09DEDA100B40DD4C40ADCEF30787E527C4F613A08BDED12E394097 +20241202032328 2 6 100 7679 2 F02D40B37C40876939E4D2A62AF7EC21A676D8E2B04081BA98E23F464A47514FB40DC99F7B8046B48CD3052C7AC080E4B496C16ED18695CA27493A129088F5829BBEAD02DFD521829FFD8B1120330E2BBA10C55A1EAD0641006827DA4725BFD2A2559C363C33BC78C2D83B4A075099EC57634D0AD4AEDA3302441B7005C728C0371B51877A97B442C5E3C3D53C244EFF3B65CDCCB0C017723F1EBD0B91E220116ACF14703268A11B7FC7564F7BEDBFFB3CE046261DD9D83E6078CD7AB5AC97595EF53D6C4C56D24588C6D130C0CD2C967AB90C31497186A06A93FB9338D4F30E0104BC8EFF2518D0644174BD1FF1FD7BAC2AAFF151D733A14F456A189ECA2D5F11D7C3AF1DA06192D36251B050E1AC576E3C369678D12823870FFC6E5809903382F9FBE36156F294C94FF5369E8D24D085A326870A998A10683495CEF15EFF0A45C781B5156B82D9AA07852040A96A0D5ACDF094B9DD91EA893382F95A6B72F0A2090F036A1B23CF9CF544753EA5B9ED86FA52EBB4C5421C5B485AE932F5837822C91257EC4953ACA79F2D94261DC40B3D44CB44056D4025EC459563865000B8C5F5D7724ED27CA4A8ADE299E5C898F4BD09F430781A68C261E4FA0BA2FEE567434B057C5D5F2899A1547B780B91315CC631C0552DB403DF53A6059BE895242FDA4AE1F6C5129E3643DF1A20C28BBF4328B4E623DCBC1149CE838BBC4A9944A6B6ACB4AA29B50FC7AFFAB0075BB4CC190F15B2C17847560F1B4C591EFE90D5AAA307A3FCC091DF44E3B219F7EE86EA01704D652983CE0D475896C1EB94E09314D386233D706FE0F5415BAF51746F3E8A6AC74E6F68CCF665CCEC4BE0B9CE19308C0423491F5914EA8ABE6081F38282D4994A4B640DCE56F4D616CED59B80938E4E7C486AB64E7C740FCD6ADB5494906520FD66A02069D3C11085157142CDDBFB004023C5CDFCCEAC5296636A77C127DEC4182A36D6A34D980F778452271C80CABAFE15A629302EFE9CD9105353B719581D4DD2E1BCF9411A4CCB0D010B5954291453E761A3B9EAF533119EEF1C30C4E53FEFAF2D2300162786963D54ECE0376CC797CBBDD757B596FAB26716ECEA7C47FB6C6DC6A80FC435D5CADB36D5ACB6760CAC6272B61E64A920EC7D4E5FBD680B2B906F1CF78EFD380A47692E1DC6C06AC21255E65C3757E32C301B5ACD8BA136FEE7C19B858D8B60595946BF1D0520912ACD17E397C9FC156C741AD1104F403B363B4E6B4AD06E8C60928CCD6AB3FE6AEFECBC57DB5CFF431A2D44533D9A92C483B56AE56698F02622D3A65E09B6EBFDFD5DCAF34E09DEDA100B40DD4C40ADCEF30787E527C4F613A08BDED1324BD55B +20241202042741 2 6 100 7679 5 F02D40B37C40876939E4D2A62AF7EC21A676D8E2B04081BA98E23F464A47514FB40DC99F7B8046B48CD3052C7AC080E4B496C16ED18695CA27493A129088F5829BBEAD02DFD521829FFD8B1120330E2BBA10C55A1EAD0641006827DA4725BFD2A2559C363C33BC78C2D83B4A075099EC57634D0AD4AEDA3302441B7005C728C0371B51877A97B442C5E3C3D53C244EFF3B65CDCCB0C017723F1EBD0B91E220116ACF14703268A11B7FC7564F7BEDBFFB3CE046261DD9D83E6078CD7AB5AC97595EF53D6C4C56D24588C6D130C0CD2C967AB90C31497186A06A93FB9338D4F30E0104BC8EFF2518D0644174BD1FF1FD7BAC2AAFF151D733A14F456A189ECA2D5F11D7C3AF1DA06192D36251B050E1AC576E3C369678D12823870FFC6E5809903382F9FBE36156F294C94FF5369E8D24D085A326870A998A10683495CEF15EFF0A45C781B5156B82D9AA07852040A96A0D5ACDF094B9DD91EA893382F95A6B72F0A2090F036A1B23CF9CF544753EA5B9ED86FA52EBB4C5421C5B485AE932F5837822C91257EC4953ACA79F2D94261DC40B3D44CB44056D4025EC459563865000B8C5F5D7724ED27CA4A8ADE299E5C898F4BD09F430781A68C261E4FA0BA2FEE567434B057C5D5F2899A1547B780B91315CC631C0552DB403DF53A6059BE895242FDA4AE1F6C5129E3643DF1A20C28BBF4328B4E623DCBC1149CE838BBC4A9944A6B6ACB4AA29B50FC7AFFAB0075BB4CC190F15B2C17847560F1B4C591EFE90D5AAA307A3FCC091DF44E3B219F7EE86EA01704D652983CE0D475896C1EB94E09314D386233D706FE0F5415BAF51746F3E8A6AC74E6F68CCF665CCEC4BE0B9CE19308C0423491F5914EA8ABE6081F38282D4994A4B640DCE56F4D616CED59B80938E4E7C486AB64E7C740FCD6ADB5494906520FD66A02069D3C11085157142CDDBFB004023C5CDFCCEAC5296636A77C127DEC4182A36D6A34D980F778452271C80CABAFE15A629302EFE9CD9105353B719581D4DD2E1BCF9411A4CCB0D010B5954291453E761A3B9EAF533119EEF1C30C4E53FEFAF2D2300162786963D54ECE0376CC797CBBDD757B596FAB26716ECEA7C47FB6C6DC6A80FC435D5CADB36D5ACB6760CAC6272B61E64A920EC7D4E5FBD680B2B906F1CF78EFD380A47692E1DC6C06AC21255E65C3757E32C301B5ACD8BA136FEE7C19B858D8B60595946BF1D0520912ACD17E397C9FC156C741AD1104F403B363B4E6B4AD06E8C60928CCD6AB3FE6AEFECBC57DB5CFF431A2D44533D9A92C483B56AE56698F02622D3A65E09B6EBFDFD5DCAF34E09DEDA100B40DD4C40ADCEF30787E527C4F613A08BDED1368D4BB7 +20241202043950 2 6 100 7679 2 F02D40B37C40876939E4D2A62AF7EC21A676D8E2B04081BA98E23F464A47514FB40DC99F7B8046B48CD3052C7AC080E4B496C16ED18695CA27493A129088F5829BBEAD02DFD521829FFD8B1120330E2BBA10C55A1EAD0641006827DA4725BFD2A2559C363C33BC78C2D83B4A075099EC57634D0AD4AEDA3302441B7005C728C0371B51877A97B442C5E3C3D53C244EFF3B65CDCCB0C017723F1EBD0B91E220116ACF14703268A11B7FC7564F7BEDBFFB3CE046261DD9D83E6078CD7AB5AC97595EF53D6C4C56D24588C6D130C0CD2C967AB90C31497186A06A93FB9338D4F30E0104BC8EFF2518D0644174BD1FF1FD7BAC2AAFF151D733A14F456A189ECA2D5F11D7C3AF1DA06192D36251B050E1AC576E3C369678D12823870FFC6E5809903382F9FBE36156F294C94FF5369E8D24D085A326870A998A10683495CEF15EFF0A45C781B5156B82D9AA07852040A96A0D5ACDF094B9DD91EA893382F95A6B72F0A2090F036A1B23CF9CF544753EA5B9ED86FA52EBB4C5421C5B485AE932F5837822C91257EC4953ACA79F2D94261DC40B3D44CB44056D4025EC459563865000B8C5F5D7724ED27CA4A8ADE299E5C898F4BD09F430781A68C261E4FA0BA2FEE567434B057C5D5F2899A1547B780B91315CC631C0552DB403DF53A6059BE895242FDA4AE1F6C5129E3643DF1A20C28BBF4328B4E623DCBC1149CE838BBC4A9944A6B6ACB4AA29B50FC7AFFAB0075BB4CC190F15B2C17847560F1B4C591EFE90D5AAA307A3FCC091DF44E3B219F7EE86EA01704D652983CE0D475896C1EB94E09314D386233D706FE0F5415BAF51746F3E8A6AC74E6F68CCF665CCEC4BE0B9CE19308C0423491F5914EA8ABE6081F38282D4994A4B640DCE56F4D616CED59B80938E4E7C486AB64E7C740FCD6ADB5494906520FD66A02069D3C11085157142CDDBFB004023C5CDFCCEAC5296636A77C127DEC4182A36D6A34D980F778452271C80CABAFE15A629302EFE9CD9105353B719581D4DD2E1BCF9411A4CCB0D010B5954291453E761A3B9EAF533119EEF1C30C4E53FEFAF2D2300162786963D54ECE0376CC797CBBDD757B596FAB26716ECEA7C47FB6C6DC6A80FC435D5CADB36D5ACB6760CAC6272B61E64A920EC7D4E5FBD680B2B906F1CF78EFD380A47692E1DC6C06AC21255E65C3757E32C301B5ACD8BA136FEE7C19B858D8B60595946BF1D0520912ACD17E397C9FC156C741AD1104F403B363B4E6B4AD06E8C60928CCD6AB3FE6AEFECBC57DB5CFF431A2D44533D9A92C483B56AE56698F02622D3A65E09B6EBFDFD5DCAF34E09DEDA100B40DD4C40ADCEF30787E527C4F613A08BDED1375589FB +20241202051314 2 6 100 7679 2 F02D40B37C40876939E4D2A62AF7EC21A676D8E2B04081BA98E23F464A47514FB40DC99F7B8046B48CD3052C7AC080E4B496C16ED18695CA27493A129088F5829BBEAD02DFD521829FFD8B1120330E2BBA10C55A1EAD0641006827DA4725BFD2A2559C363C33BC78C2D83B4A075099EC57634D0AD4AEDA3302441B7005C728C0371B51877A97B442C5E3C3D53C244EFF3B65CDCCB0C017723F1EBD0B91E220116ACF14703268A11B7FC7564F7BEDBFFB3CE046261DD9D83E6078CD7AB5AC97595EF53D6C4C56D24588C6D130C0CD2C967AB90C31497186A06A93FB9338D4F30E0104BC8EFF2518D0644174BD1FF1FD7BAC2AAFF151D733A14F456A189ECA2D5F11D7C3AF1DA06192D36251B050E1AC576E3C369678D12823870FFC6E5809903382F9FBE36156F294C94FF5369E8D24D085A326870A998A10683495CEF15EFF0A45C781B5156B82D9AA07852040A96A0D5ACDF094B9DD91EA893382F95A6B72F0A2090F036A1B23CF9CF544753EA5B9ED86FA52EBB4C5421C5B485AE932F5837822C91257EC4953ACA79F2D94261DC40B3D44CB44056D4025EC459563865000B8C5F5D7724ED27CA4A8ADE299E5C898F4BD09F430781A68C261E4FA0BA2FEE567434B057C5D5F2899A1547B780B91315CC631C0552DB403DF53A6059BE895242FDA4AE1F6C5129E3643DF1A20C28BBF4328B4E623DCBC1149CE838BBC4A9944A6B6ACB4AA29B50FC7AFFAB0075BB4CC190F15B2C17847560F1B4C591EFE90D5AAA307A3FCC091DF44E3B219F7EE86EA01704D652983CE0D475896C1EB94E09314D386233D706FE0F5415BAF51746F3E8A6AC74E6F68CCF665CCEC4BE0B9CE19308C0423491F5914EA8ABE6081F38282D4994A4B640DCE56F4D616CED59B80938E4E7C486AB64E7C740FCD6ADB5494906520FD66A02069D3C11085157142CDDBFB004023C5CDFCCEAC5296636A77C127DEC4182A36D6A34D980F778452271C80CABAFE15A629302EFE9CD9105353B719581D4DD2E1BCF9411A4CCB0D010B5954291453E761A3B9EAF533119EEF1C30C4E53FEFAF2D2300162786963D54ECE0376CC797CBBDD757B596FAB26716ECEA7C47FB6C6DC6A80FC435D5CADB36D5ACB6760CAC6272B61E64A920EC7D4E5FBD680B2B906F1CF78EFD380A47692E1DC6C06AC21255E65C3757E32C301B5ACD8BA136FEE7C19B858D8B60595946BF1D0520912ACD17E397C9FC156C741AD1104F403B363B4E6B4AD06E8C60928CCD6AB3FE6AEFECBC57DB5CFF431A2D44533D9A92C483B56AE56698F02622D3A65E09B6EBFDFD5DCAF34E09DEDA100B40DD4C40ADCEF30787E527C4F613A08BDED1398AB80B +20241202054231 2 6 100 7679 2 F02D40B37C40876939E4D2A62AF7EC21A676D8E2B04081BA98E23F464A47514FB40DC99F7B8046B48CD3052C7AC080E4B496C16ED18695CA27493A129088F5829BBEAD02DFD521829FFD8B1120330E2BBA10C55A1EAD0641006827DA4725BFD2A2559C363C33BC78C2D83B4A075099EC57634D0AD4AEDA3302441B7005C728C0371B51877A97B442C5E3C3D53C244EFF3B65CDCCB0C017723F1EBD0B91E220116ACF14703268A11B7FC7564F7BEDBFFB3CE046261DD9D83E6078CD7AB5AC97595EF53D6C4C56D24588C6D130C0CD2C967AB90C31497186A06A93FB9338D4F30E0104BC8EFF2518D0644174BD1FF1FD7BAC2AAFF151D733A14F456A189ECA2D5F11D7C3AF1DA06192D36251B050E1AC576E3C369678D12823870FFC6E5809903382F9FBE36156F294C94FF5369E8D24D085A326870A998A10683495CEF15EFF0A45C781B5156B82D9AA07852040A96A0D5ACDF094B9DD91EA893382F95A6B72F0A2090F036A1B23CF9CF544753EA5B9ED86FA52EBB4C5421C5B485AE932F5837822C91257EC4953ACA79F2D94261DC40B3D44CB44056D4025EC459563865000B8C5F5D7724ED27CA4A8ADE299E5C898F4BD09F430781A68C261E4FA0BA2FEE567434B057C5D5F2899A1547B780B91315CC631C0552DB403DF53A6059BE895242FDA4AE1F6C5129E3643DF1A20C28BBF4328B4E623DCBC1149CE838BBC4A9944A6B6ACB4AA29B50FC7AFFAB0075BB4CC190F15B2C17847560F1B4C591EFE90D5AAA307A3FCC091DF44E3B219F7EE86EA01704D652983CE0D475896C1EB94E09314D386233D706FE0F5415BAF51746F3E8A6AC74E6F68CCF665CCEC4BE0B9CE19308C0423491F5914EA8ABE6081F38282D4994A4B640DCE56F4D616CED59B80938E4E7C486AB64E7C740FCD6ADB5494906520FD66A02069D3C11085157142CDDBFB004023C5CDFCCEAC5296636A77C127DEC4182A36D6A34D980F778452271C80CABAFE15A629302EFE9CD9105353B719581D4DD2E1BCF9411A4CCB0D010B5954291453E761A3B9EAF533119EEF1C30C4E53FEFAF2D2300162786963D54ECE0376CC797CBBDD757B596FAB26716ECEA7C47FB6C6DC6A80FC435D5CADB36D5ACB6760CAC6272B61E64A920EC7D4E5FBD680B2B906F1CF78EFD380A47692E1DC6C06AC21255E65C3757E32C301B5ACD8BA136FEE7C19B858D8B60595946BF1D0520912ACD17E397C9FC156C741AD1104F403B363B4E6B4AD06E8C60928CCD6AB3FE6AEFECBC57DB5CFF431A2D44533D9A92C483B56AE56698F02622D3A65E09B6EBFDFD5DCAF34E09DEDA100B40DD4C40ADCEF30787E527C4F613A08BDED13B77C653 +20241202054750 2 6 100 7679 5 F02D40B37C40876939E4D2A62AF7EC21A676D8E2B04081BA98E23F464A47514FB40DC99F7B8046B48CD3052C7AC080E4B496C16ED18695CA27493A129088F5829BBEAD02DFD521829FFD8B1120330E2BBA10C55A1EAD0641006827DA4725BFD2A2559C363C33BC78C2D83B4A075099EC57634D0AD4AEDA3302441B7005C728C0371B51877A97B442C5E3C3D53C244EFF3B65CDCCB0C017723F1EBD0B91E220116ACF14703268A11B7FC7564F7BEDBFFB3CE046261DD9D83E6078CD7AB5AC97595EF53D6C4C56D24588C6D130C0CD2C967AB90C31497186A06A93FB9338D4F30E0104BC8EFF2518D0644174BD1FF1FD7BAC2AAFF151D733A14F456A189ECA2D5F11D7C3AF1DA06192D36251B050E1AC576E3C369678D12823870FFC6E5809903382F9FBE36156F294C94FF5369E8D24D085A326870A998A10683495CEF15EFF0A45C781B5156B82D9AA07852040A96A0D5ACDF094B9DD91EA893382F95A6B72F0A2090F036A1B23CF9CF544753EA5B9ED86FA52EBB4C5421C5B485AE932F5837822C91257EC4953ACA79F2D94261DC40B3D44CB44056D4025EC459563865000B8C5F5D7724ED27CA4A8ADE299E5C898F4BD09F430781A68C261E4FA0BA2FEE567434B057C5D5F2899A1547B780B91315CC631C0552DB403DF53A6059BE895242FDA4AE1F6C5129E3643DF1A20C28BBF4328B4E623DCBC1149CE838BBC4A9944A6B6ACB4AA29B50FC7AFFAB0075BB4CC190F15B2C17847560F1B4C591EFE90D5AAA307A3FCC091DF44E3B219F7EE86EA01704D652983CE0D475896C1EB94E09314D386233D706FE0F5415BAF51746F3E8A6AC74E6F68CCF665CCEC4BE0B9CE19308C0423491F5914EA8ABE6081F38282D4994A4B640DCE56F4D616CED59B80938E4E7C486AB64E7C740FCD6ADB5494906520FD66A02069D3C11085157142CDDBFB004023C5CDFCCEAC5296636A77C127DEC4182A36D6A34D980F778452271C80CABAFE15A629302EFE9CD9105353B719581D4DD2E1BCF9411A4CCB0D010B5954291453E761A3B9EAF533119EEF1C30C4E53FEFAF2D2300162786963D54ECE0376CC797CBBDD757B596FAB26716ECEA7C47FB6C6DC6A80FC435D5CADB36D5ACB6760CAC6272B61E64A920EC7D4E5FBD680B2B906F1CF78EFD380A47692E1DC6C06AC21255E65C3757E32C301B5ACD8BA136FEE7C19B858D8B60595946BF1D0520912ACD17E397C9FC156C741AD1104F403B363B4E6B4AD06E8C60928CCD6AB3FE6AEFECBC57DB5CFF431A2D44533D9A92C483B56AE56698F02622D3A65E09B6EBFDFD5DCAF34E09DEDA100B40DD4C40ADCEF30787E527C4F613A08BDED13BCC7297 +20241202061721 2 6 100 7679 2 F02D40B37C40876939E4D2A62AF7EC21A676D8E2B04081BA98E23F464A47514FB40DC99F7B8046B48CD3052C7AC080E4B496C16ED18695CA27493A129088F5829BBEAD02DFD521829FFD8B1120330E2BBA10C55A1EAD0641006827DA4725BFD2A2559C363C33BC78C2D83B4A075099EC57634D0AD4AEDA3302441B7005C728C0371B51877A97B442C5E3C3D53C244EFF3B65CDCCB0C017723F1EBD0B91E220116ACF14703268A11B7FC7564F7BEDBFFB3CE046261DD9D83E6078CD7AB5AC97595EF53D6C4C56D24588C6D130C0CD2C967AB90C31497186A06A93FB9338D4F30E0104BC8EFF2518D0644174BD1FF1FD7BAC2AAFF151D733A14F456A189ECA2D5F11D7C3AF1DA06192D36251B050E1AC576E3C369678D12823870FFC6E5809903382F9FBE36156F294C94FF5369E8D24D085A326870A998A10683495CEF15EFF0A45C781B5156B82D9AA07852040A96A0D5ACDF094B9DD91EA893382F95A6B72F0A2090F036A1B23CF9CF544753EA5B9ED86FA52EBB4C5421C5B485AE932F5837822C91257EC4953ACA79F2D94261DC40B3D44CB44056D4025EC459563865000B8C5F5D7724ED27CA4A8ADE299E5C898F4BD09F430781A68C261E4FA0BA2FEE567434B057C5D5F2899A1547B780B91315CC631C0552DB403DF53A6059BE895242FDA4AE1F6C5129E3643DF1A20C28BBF4328B4E623DCBC1149CE838BBC4A9944A6B6ACB4AA29B50FC7AFFAB0075BB4CC190F15B2C17847560F1B4C591EFE90D5AAA307A3FCC091DF44E3B219F7EE86EA01704D652983CE0D475896C1EB94E09314D386233D706FE0F5415BAF51746F3E8A6AC74E6F68CCF665CCEC4BE0B9CE19308C0423491F5914EA8ABE6081F38282D4994A4B640DCE56F4D616CED59B80938E4E7C486AB64E7C740FCD6ADB5494906520FD66A02069D3C11085157142CDDBFB004023C5CDFCCEAC5296636A77C127DEC4182A36D6A34D980F778452271C80CABAFE15A629302EFE9CD9105353B719581D4DD2E1BCF9411A4CCB0D010B5954291453E761A3B9EAF533119EEF1C30C4E53FEFAF2D2300162786963D54ECE0376CC797CBBDD757B596FAB26716ECEA7C47FB6C6DC6A80FC435D5CADB36D5ACB6760CAC6272B61E64A920EC7D4E5FBD680B2B906F1CF78EFD380A47692E1DC6C06AC21255E65C3757E32C301B5ACD8BA136FEE7C19B858D8B60595946BF1D0520912ACD17E397C9FC156C741AD1104F403B363B4E6B4AD06E8C60928CCD6AB3FE6AEFECBC57DB5CFF431A2D44533D9A92C483B56AE56698F02622D3A65E09B6EBFDFD5DCAF34E09DEDA100B40DD4C40ADCEF30787E527C4F613A08BDED13DC0C9B3 +20241202074137 2 6 100 7679 2 F02D40B37C40876939E4D2A62AF7EC21A676D8E2B04081BA98E23F464A47514FB40DC99F7B8046B48CD3052C7AC080E4B496C16ED18695CA27493A129088F5829BBEAD02DFD521829FFD8B1120330E2BBA10C55A1EAD0641006827DA4725BFD2A2559C363C33BC78C2D83B4A075099EC57634D0AD4AEDA3302441B7005C728C0371B51877A97B442C5E3C3D53C244EFF3B65CDCCB0C017723F1EBD0B91E220116ACF14703268A11B7FC7564F7BEDBFFB3CE046261DD9D83E6078CD7AB5AC97595EF53D6C4C56D24588C6D130C0CD2C967AB90C31497186A06A93FB9338D4F30E0104BC8EFF2518D0644174BD1FF1FD7BAC2AAFF151D733A14F456A189ECA2D5F11D7C3AF1DA06192D36251B050E1AC576E3C369678D12823870FFC6E5809903382F9FBE36156F294C94FF5369E8D24D085A326870A998A10683495CEF15EFF0A45C781B5156B82D9AA07852040A96A0D5ACDF094B9DD91EA893382F95A6B72F0A2090F036A1B23CF9CF544753EA5B9ED86FA52EBB4C5421C5B485AE932F5837822C91257EC4953ACA79F2D94261DC40B3D44CB44056D4025EC459563865000B8C5F5D7724ED27CA4A8ADE299E5C898F4BD09F430781A68C261E4FA0BA2FEE567434B057C5D5F2899A1547B780B91315CC631C0552DB403DF53A6059BE895242FDA4AE1F6C5129E3643DF1A20C28BBF4328B4E623DCBC1149CE838BBC4A9944A6B6ACB4AA29B50FC7AFFAB0075BB4CC190F15B2C17847560F1B4C591EFE90D5AAA307A3FCC091DF44E3B219F7EE86EA01704D652983CE0D475896C1EB94E09314D386233D706FE0F5415BAF51746F3E8A6AC74E6F68CCF665CCEC4BE0B9CE19308C0423491F5914EA8ABE6081F38282D4994A4B640DCE56F4D616CED59B80938E4E7C486AB64E7C740FCD6ADB5494906520FD66A02069D3C11085157142CDDBFB004023C5CDFCCEAC5296636A77C127DEC4182A36D6A34D980F778452271C80CABAFE15A629302EFE9CD9105353B719581D4DD2E1BCF9411A4CCB0D010B5954291453E761A3B9EAF533119EEF1C30C4E53FEFAF2D2300162786963D54ECE0376CC797CBBDD757B596FAB26716ECEA7C47FB6C6DC6A80FC435D5CADB36D5ACB6760CAC6272B61E64A920EC7D4E5FBD680B2B906F1CF78EFD380A47692E1DC6C06AC21255E65C3757E32C301B5ACD8BA136FEE7C19B858D8B60595946BF1D0520912ACD17E397C9FC156C741AD1104F403B363B4E6B4AD06E8C60928CCD6AB3FE6AEFECBC57DB5CFF431A2D44533D9A92C483B56AE56698F02622D3A65E09B6EBFDFD5DCAF34E09DEDA100B40DD4C40ADCEF30787E527C4F613A08BDED1435661B3 +20241202074315 2 6 100 7679 2 F02D40B37C40876939E4D2A62AF7EC21A676D8E2B04081BA98E23F464A47514FB40DC99F7B8046B48CD3052C7AC080E4B496C16ED18695CA27493A129088F5829BBEAD02DFD521829FFD8B1120330E2BBA10C55A1EAD0641006827DA4725BFD2A2559C363C33BC78C2D83B4A075099EC57634D0AD4AEDA3302441B7005C728C0371B51877A97B442C5E3C3D53C244EFF3B65CDCCB0C017723F1EBD0B91E220116ACF14703268A11B7FC7564F7BEDBFFB3CE046261DD9D83E6078CD7AB5AC97595EF53D6C4C56D24588C6D130C0CD2C967AB90C31497186A06A93FB9338D4F30E0104BC8EFF2518D0644174BD1FF1FD7BAC2AAFF151D733A14F456A189ECA2D5F11D7C3AF1DA06192D36251B050E1AC576E3C369678D12823870FFC6E5809903382F9FBE36156F294C94FF5369E8D24D085A326870A998A10683495CEF15EFF0A45C781B5156B82D9AA07852040A96A0D5ACDF094B9DD91EA893382F95A6B72F0A2090F036A1B23CF9CF544753EA5B9ED86FA52EBB4C5421C5B485AE932F5837822C91257EC4953ACA79F2D94261DC40B3D44CB44056D4025EC459563865000B8C5F5D7724ED27CA4A8ADE299E5C898F4BD09F430781A68C261E4FA0BA2FEE567434B057C5D5F2899A1547B780B91315CC631C0552DB403DF53A6059BE895242FDA4AE1F6C5129E3643DF1A20C28BBF4328B4E623DCBC1149CE838BBC4A9944A6B6ACB4AA29B50FC7AFFAB0075BB4CC190F15B2C17847560F1B4C591EFE90D5AAA307A3FCC091DF44E3B219F7EE86EA01704D652983CE0D475896C1EB94E09314D386233D706FE0F5415BAF51746F3E8A6AC74E6F68CCF665CCEC4BE0B9CE19308C0423491F5914EA8ABE6081F38282D4994A4B640DCE56F4D616CED59B80938E4E7C486AB64E7C740FCD6ADB5494906520FD66A02069D3C11085157142CDDBFB004023C5CDFCCEAC5296636A77C127DEC4182A36D6A34D980F778452271C80CABAFE15A629302EFE9CD9105353B719581D4DD2E1BCF9411A4CCB0D010B5954291453E761A3B9EAF533119EEF1C30C4E53FEFAF2D2300162786963D54ECE0376CC797CBBDD757B596FAB26716ECEA7C47FB6C6DC6A80FC435D5CADB36D5ACB6760CAC6272B61E64A920EC7D4E5FBD680B2B906F1CF78EFD380A47692E1DC6C06AC21255E65C3757E32C301B5ACD8BA136FEE7C19B858D8B60595946BF1D0520912ACD17E397C9FC156C741AD1104F403B363B4E6B4AD06E8C60928CCD6AB3FE6AEFECBC57DB5CFF431A2D44533D9A92C483B56AE56698F02622D3A65E09B6EBFDFD5DCAF34E09DEDA100B40DD4C40ADCEF30787E527C4F613A08BDED14369BF1B +20241202081741 2 6 100 7679 2 F02D40B37C40876939E4D2A62AF7EC21A676D8E2B04081BA98E23F464A47514FB40DC99F7B8046B48CD3052C7AC080E4B496C16ED18695CA27493A129088F5829BBEAD02DFD521829FFD8B1120330E2BBA10C55A1EAD0641006827DA4725BFD2A2559C363C33BC78C2D83B4A075099EC57634D0AD4AEDA3302441B7005C728C0371B51877A97B442C5E3C3D53C244EFF3B65CDCCB0C017723F1EBD0B91E220116ACF14703268A11B7FC7564F7BEDBFFB3CE046261DD9D83E6078CD7AB5AC97595EF53D6C4C56D24588C6D130C0CD2C967AB90C31497186A06A93FB9338D4F30E0104BC8EFF2518D0644174BD1FF1FD7BAC2AAFF151D733A14F456A189ECA2D5F11D7C3AF1DA06192D36251B050E1AC576E3C369678D12823870FFC6E5809903382F9FBE36156F294C94FF5369E8D24D085A326870A998A10683495CEF15EFF0A45C781B5156B82D9AA07852040A96A0D5ACDF094B9DD91EA893382F95A6B72F0A2090F036A1B23CF9CF544753EA5B9ED86FA52EBB4C5421C5B485AE932F5837822C91257EC4953ACA79F2D94261DC40B3D44CB44056D4025EC459563865000B8C5F5D7724ED27CA4A8ADE299E5C898F4BD09F430781A68C261E4FA0BA2FEE567434B057C5D5F2899A1547B780B91315CC631C0552DB403DF53A6059BE895242FDA4AE1F6C5129E3643DF1A20C28BBF4328B4E623DCBC1149CE838BBC4A9944A6B6ACB4AA29B50FC7AFFAB0075BB4CC190F15B2C17847560F1B4C591EFE90D5AAA307A3FCC091DF44E3B219F7EE86EA01704D652983CE0D475896C1EB94E09314D386233D706FE0F5415BAF51746F3E8A6AC74E6F68CCF665CCEC4BE0B9CE19308C0423491F5914EA8ABE6081F38282D4994A4B640DCE56F4D616CED59B80938E4E7C486AB64E7C740FCD6ADB5494906520FD66A02069D3C11085157142CDDBFB004023C5CDFCCEAC5296636A77C127DEC4182A36D6A34D980F778452271C80CABAFE15A629302EFE9CD9105353B719581D4DD2E1BCF9411A4CCB0D010B5954291453E761A3B9EAF533119EEF1C30C4E53FEFAF2D2300162786963D54ECE0376CC797CBBDD757B596FAB26716ECEA7C47FB6C6DC6A80FC435D5CADB36D5ACB6760CAC6272B61E64A920EC7D4E5FBD680B2B906F1CF78EFD380A47692E1DC6C06AC21255E65C3757E32C301B5ACD8BA136FEE7C19B858D8B60595946BF1D0520912ACD17E397C9FC156C741AD1104F403B363B4E6B4AD06E8C60928CCD6AB3FE6AEFECBC57DB5CFF431A2D44533D9A92C483B56AE56698F02622D3A65E09B6EBFDFD5DCAF34E09DEDA100B40DD4C40ADCEF30787E527C4F613A08BDED145AABB1B +20241202082834 2 6 100 7679 2 F02D40B37C40876939E4D2A62AF7EC21A676D8E2B04081BA98E23F464A47514FB40DC99F7B8046B48CD3052C7AC080E4B496C16ED18695CA27493A129088F5829BBEAD02DFD521829FFD8B1120330E2BBA10C55A1EAD0641006827DA4725BFD2A2559C363C33BC78C2D83B4A075099EC57634D0AD4AEDA3302441B7005C728C0371B51877A97B442C5E3C3D53C244EFF3B65CDCCB0C017723F1EBD0B91E220116ACF14703268A11B7FC7564F7BEDBFFB3CE046261DD9D83E6078CD7AB5AC97595EF53D6C4C56D24588C6D130C0CD2C967AB90C31497186A06A93FB9338D4F30E0104BC8EFF2518D0644174BD1FF1FD7BAC2AAFF151D733A14F456A189ECA2D5F11D7C3AF1DA06192D36251B050E1AC576E3C369678D12823870FFC6E5809903382F9FBE36156F294C94FF5369E8D24D085A326870A998A10683495CEF15EFF0A45C781B5156B82D9AA07852040A96A0D5ACDF094B9DD91EA893382F95A6B72F0A2090F036A1B23CF9CF544753EA5B9ED86FA52EBB4C5421C5B485AE932F5837822C91257EC4953ACA79F2D94261DC40B3D44CB44056D4025EC459563865000B8C5F5D7724ED27CA4A8ADE299E5C898F4BD09F430781A68C261E4FA0BA2FEE567434B057C5D5F2899A1547B780B91315CC631C0552DB403DF53A6059BE895242FDA4AE1F6C5129E3643DF1A20C28BBF4328B4E623DCBC1149CE838BBC4A9944A6B6ACB4AA29B50FC7AFFAB0075BB4CC190F15B2C17847560F1B4C591EFE90D5AAA307A3FCC091DF44E3B219F7EE86EA01704D652983CE0D475896C1EB94E09314D386233D706FE0F5415BAF51746F3E8A6AC74E6F68CCF665CCEC4BE0B9CE19308C0423491F5914EA8ABE6081F38282D4994A4B640DCE56F4D616CED59B80938E4E7C486AB64E7C740FCD6ADB5494906520FD66A02069D3C11085157142CDDBFB004023C5CDFCCEAC5296636A77C127DEC4182A36D6A34D980F778452271C80CABAFE15A629302EFE9CD9105353B719581D4DD2E1BCF9411A4CCB0D010B5954291453E761A3B9EAF533119EEF1C30C4E53FEFAF2D2300162786963D54ECE0376CC797CBBDD757B596FAB26716ECEA7C47FB6C6DC6A80FC435D5CADB36D5ACB6760CAC6272B61E64A920EC7D4E5FBD680B2B906F1CF78EFD380A47692E1DC6C06AC21255E65C3757E32C301B5ACD8BA136FEE7C19B858D8B60595946BF1D0520912ACD17E397C9FC156C741AD1104F403B363B4E6B4AD06E8C60928CCD6AB3FE6AEFECBC57DB5CFF431A2D44533D9A92C483B56AE56698F02622D3A65E09B6EBFDFD5DCAF34E09DEDA100B40DD4C40ADCEF30787E527C4F613A08BDED1465C7B4B +20241202090408 2 6 100 8191 2 C3301F39F3E2DCD097FBF5454401BF52BF4745AFD35F3DEBDFB34DE2518B0F7BB10DE2FDBE6C35E1B63AA67E9FC179EB3DB8A0FA7E01618BB625B3EC326A001A253FB737B2461999BAB5A5FBCA4AFAD88A8BCBEB5990D4E25225F203B2CE75A3A1C23BFFD78E697275BDB6B6153AA3C21D2063047D44EDDF0483220CD672280D4D67C4726EA476A5C094B7E8DBE62B760EBA6B62C200D456A99E87875B4B2FFF4AA87661D89CAF8CA36D9CE00E0C3BDA443B7CCC3EA892F524AD10DD6960196EC4497E1DDC9F5C13BAED9A8F240196633AB9EC597D0A2FFEEE9320147E73FB295039605EA79376C00D1C60EB421D1BF2BD36A9B68A32E5F5003F0C984E1A57B3C8A261E451D912FCBF27924078BAB0879F85B78D097B2651A17AD9266B39E7AF73DAE54319B2902E0A0D11653B38EDA14B9DE8431E9382AC7EF5F1705C05239DDEA7F533234FA640D2E1EE392D23BF46D57D6FD0E167174E6242F5455DC299BB03BF2EBAEDB14539E9025B84BF66C185AD45C6B1FBF47E3C17D4A1F2C99DCA7151039D71DB7BD2E025E67C2ABB9A2DE6D9C5150651385B270511AA50E8728707B1E0920F3A83DEC0F733090CE96DCACDB93CD756AB1F572DA2BBF4908C17E905848C09CF31424833D1D4894FCB6BD93162EC74E836A523E97F35152EBA28AF63DEC47A32C09E0F0451A4D60949C8CDB07642F5A705075F4A1380B327596C319A135C9C43BBAF2D25C90030BA43FC55701B2854ABFEA710D98AFB8341E46778616A9E9B31CF11652B47A76A99F096BDB35C9CFA78E47CFC980E5E8683E1E13AA3FCA5171C07B5E27C1A5002C02643DC760431C2750A29E838F6ED5A892146D8015F5879DA988DF030BB2FA4D501FB7F0AD9A82ED3C48B70979428C39DB04116DCC8337567B6DB4A0DFE0C704B3F46983BBF092847AED87699EE88AEB27756850D008583CD37FC8521968EB1D17FC42D742B7E6756303412A3AD011DD5CE2BA1A4E3B0B2EBB68736C76B02164C41204734B731DF4C00C937CFB49D4648A7808A34E6162526240AB221071C6C2669DB4787AF7D516F4E72EF81C7D907A37634E8CEC5BF4B3502A6A05224B269B29A8E44603DB2A890F9B64BC94AEC7D2923DC52985CC18E123C7D6CC3DEF885725E0BD2D3EC0466DBE2E94350368068E5FC1CFB6BAC40F47600EB8520A8E29E855D96B556002207CA234BE3620189767ED74ABA3D1A1CF3F66864312B7502C37C9543A36F24FD38A25137128FFE4C6CC7C078AEF1F799DA7F3E3BA0E19F21A707E66EE95189BDD74EDF32E0F18052384A2A180D90545EF1B9F2710074BC8AED5F7625C0851C34E9F3AE5C57BE65862CEE2891052CC442574EBFAAE1BEC7AB63F25C80951AD65A41089DE526946D858146E446FCAD6915BD59B0D112255083A711279990F87453A6D8F7D057055217F474B4AD895B +20241202092818 2 6 100 8191 2 C3301F39F3E2DCD097FBF5454401BF52BF4745AFD35F3DEBDFB34DE2518B0F7BB10DE2FDBE6C35E1B63AA67E9FC179EB3DB8A0FA7E01618BB625B3EC326A001A253FB737B2461999BAB5A5FBCA4AFAD88A8BCBEB5990D4E25225F203B2CE75A3A1C23BFFD78E697275BDB6B6153AA3C21D2063047D44EDDF0483220CD672280D4D67C4726EA476A5C094B7E8DBE62B760EBA6B62C200D456A99E87875B4B2FFF4AA87661D89CAF8CA36D9CE00E0C3BDA443B7CCC3EA892F524AD10DD6960196EC4497E1DDC9F5C13BAED9A8F240196633AB9EC597D0A2FFEEE9320147E73FB295039605EA79376C00D1C60EB421D1BF2BD36A9B68A32E5F5003F0C984E1A57B3C8A261E451D912FCBF27924078BAB0879F85B78D097B2651A17AD9266B39E7AF73DAE54319B2902E0A0D11653B38EDA14B9DE8431E9382AC7EF5F1705C05239DDEA7F533234FA640D2E1EE392D23BF46D57D6FD0E167174E6242F5455DC299BB03BF2EBAEDB14539E9025B84BF66C185AD45C6B1FBF47E3C17D4A1F2C99DCA7151039D71DB7BD2E025E67C2ABB9A2DE6D9C5150651385B270511AA50E8728707B1E0920F3A83DEC0F733090CE96DCACDB93CD756AB1F572DA2BBF4908C17E905848C09CF31424833D1D4894FCB6BD93162EC74E836A523E97F35152EBA28AF63DEC47A32C09E0F0451A4D60949C8CDB07642F5A705075F4A1380B327596C319A135C9C43BBAF2D25C90030BA43FC55701B2854ABFEA710D98AFB8341E46778616A9E9B31CF11652B47A76A99F096BDB35C9CFA78E47CFC980E5E8683E1E13AA3FCA5171C07B5E27C1A5002C02643DC760431C2750A29E838F6ED5A892146D8015F5879DA988DF030BB2FA4D501FB7F0AD9A82ED3C48B70979428C39DB04116DCC8337567B6DB4A0DFE0C704B3F46983BBF092847AED87699EE88AEB27756850D008583CD37FC8521968EB1D17FC42D742B7E6756303412A3AD011DD5CE2BA1A4E3B0B2EBB68736C76B02164C41204734B731DF4C00C937CFB49D4648A7808A34E6162526240AB221071C6C2669DB4787AF7D516F4E72EF81C7D907A37634E8CEC5BF4B3502A6A05224B269B29A8E44603DB2A890F9B64BC94AEC7D2923DC52985CC18E123C7D6CC3DEF885725E0BD2D3EC0466DBE2E94350368068E5FC1CFB6BAC40F47600EB8520A8E29E855D96B556002207CA234BE3620189767ED74ABA3D1A1CF3F66864312B7502C37C9543A36F24FD38A25137128FFE4C6CC7C078AEF1F799DA7F3E3BA0E19F21A707E66EE95189BDD74EDF32E0F18052384A2A180D90545EF1B9F2710074BC8AED5F7625C0851C34E9F3AE5C57BE65862CEE2891052CC442574EBFAAE1BEC7AB63F25C80951AD65A41089DE526946D858146E446FCAD6915BD59B0D112255083A711279990F87453A6D8F7D057055217F474B5FD49CB +20241202101356 2 6 100 8191 5 C3301F39F3E2DCD097FBF5454401BF52BF4745AFD35F3DEBDFB34DE2518B0F7BB10DE2FDBE6C35E1B63AA67E9FC179EB3DB8A0FA7E01618BB625B3EC326A001A253FB737B2461999BAB5A5FBCA4AFAD88A8BCBEB5990D4E25225F203B2CE75A3A1C23BFFD78E697275BDB6B6153AA3C21D2063047D44EDDF0483220CD672280D4D67C4726EA476A5C094B7E8DBE62B760EBA6B62C200D456A99E87875B4B2FFF4AA87661D89CAF8CA36D9CE00E0C3BDA443B7CCC3EA892F524AD10DD6960196EC4497E1DDC9F5C13BAED9A8F240196633AB9EC597D0A2FFEEE9320147E73FB295039605EA79376C00D1C60EB421D1BF2BD36A9B68A32E5F5003F0C984E1A57B3C8A261E451D912FCBF27924078BAB0879F85B78D097B2651A17AD9266B39E7AF73DAE54319B2902E0A0D11653B38EDA14B9DE8431E9382AC7EF5F1705C05239DDEA7F533234FA640D2E1EE392D23BF46D57D6FD0E167174E6242F5455DC299BB03BF2EBAEDB14539E9025B84BF66C185AD45C6B1FBF47E3C17D4A1F2C99DCA7151039D71DB7BD2E025E67C2ABB9A2DE6D9C5150651385B270511AA50E8728707B1E0920F3A83DEC0F733090CE96DCACDB93CD756AB1F572DA2BBF4908C17E905848C09CF31424833D1D4894FCB6BD93162EC74E836A523E97F35152EBA28AF63DEC47A32C09E0F0451A4D60949C8CDB07642F5A705075F4A1380B327596C319A135C9C43BBAF2D25C90030BA43FC55701B2854ABFEA710D98AFB8341E46778616A9E9B31CF11652B47A76A99F096BDB35C9CFA78E47CFC980E5E8683E1E13AA3FCA5171C07B5E27C1A5002C02643DC760431C2750A29E838F6ED5A892146D8015F5879DA988DF030BB2FA4D501FB7F0AD9A82ED3C48B70979428C39DB04116DCC8337567B6DB4A0DFE0C704B3F46983BBF092847AED87699EE88AEB27756850D008583CD37FC8521968EB1D17FC42D742B7E6756303412A3AD011DD5CE2BA1A4E3B0B2EBB68736C76B02164C41204734B731DF4C00C937CFB49D4648A7808A34E6162526240AB221071C6C2669DB4787AF7D516F4E72EF81C7D907A37634E8CEC5BF4B3502A6A05224B269B29A8E44603DB2A890F9B64BC94AEC7D2923DC52985CC18E123C7D6CC3DEF885725E0BD2D3EC0466DBE2E94350368068E5FC1CFB6BAC40F47600EB8520A8E29E855D96B556002207CA234BE3620189767ED74ABA3D1A1CF3F66864312B7502C37C9543A36F24FD38A25137128FFE4C6CC7C078AEF1F799DA7F3E3BA0E19F21A707E66EE95189BDD74EDF32E0F18052384A2A180D90545EF1B9F2710074BC8AED5F7625C0851C34E9F3AE5C57BE65862CEE2891052CC442574EBFAAE1BEC7AB63F25C80951AD65A41089DE526946D858146E446FCAD6915BD59B0D112255083A711279990F87453A6D8F7D057055217F474B8749EB7 +20241202105709 2 6 100 8191 2 C3301F39F3E2DCD097FBF5454401BF52BF4745AFD35F3DEBDFB34DE2518B0F7BB10DE2FDBE6C35E1B63AA67E9FC179EB3DB8A0FA7E01618BB625B3EC326A001A253FB737B2461999BAB5A5FBCA4AFAD88A8BCBEB5990D4E25225F203B2CE75A3A1C23BFFD78E697275BDB6B6153AA3C21D2063047D44EDDF0483220CD672280D4D67C4726EA476A5C094B7E8DBE62B760EBA6B62C200D456A99E87875B4B2FFF4AA87661D89CAF8CA36D9CE00E0C3BDA443B7CCC3EA892F524AD10DD6960196EC4497E1DDC9F5C13BAED9A8F240196633AB9EC597D0A2FFEEE9320147E73FB295039605EA79376C00D1C60EB421D1BF2BD36A9B68A32E5F5003F0C984E1A57B3C8A261E451D912FCBF27924078BAB0879F85B78D097B2651A17AD9266B39E7AF73DAE54319B2902E0A0D11653B38EDA14B9DE8431E9382AC7EF5F1705C05239DDEA7F533234FA640D2E1EE392D23BF46D57D6FD0E167174E6242F5455DC299BB03BF2EBAEDB14539E9025B84BF66C185AD45C6B1FBF47E3C17D4A1F2C99DCA7151039D71DB7BD2E025E67C2ABB9A2DE6D9C5150651385B270511AA50E8728707B1E0920F3A83DEC0F733090CE96DCACDB93CD756AB1F572DA2BBF4908C17E905848C09CF31424833D1D4894FCB6BD93162EC74E836A523E97F35152EBA28AF63DEC47A32C09E0F0451A4D60949C8CDB07642F5A705075F4A1380B327596C319A135C9C43BBAF2D25C90030BA43FC55701B2854ABFEA710D98AFB8341E46778616A9E9B31CF11652B47A76A99F096BDB35C9CFA78E47CFC980E5E8683E1E13AA3FCA5171C07B5E27C1A5002C02643DC760431C2750A29E838F6ED5A892146D8015F5879DA988DF030BB2FA4D501FB7F0AD9A82ED3C48B70979428C39DB04116DCC8337567B6DB4A0DFE0C704B3F46983BBF092847AED87699EE88AEB27756850D008583CD37FC8521968EB1D17FC42D742B7E6756303412A3AD011DD5CE2BA1A4E3B0B2EBB68736C76B02164C41204734B731DF4C00C937CFB49D4648A7808A34E6162526240AB221071C6C2669DB4787AF7D516F4E72EF81C7D907A37634E8CEC5BF4B3502A6A05224B269B29A8E44603DB2A890F9B64BC94AEC7D2923DC52985CC18E123C7D6CC3DEF885725E0BD2D3EC0466DBE2E94350368068E5FC1CFB6BAC40F47600EB8520A8E29E855D96B556002207CA234BE3620189767ED74ABA3D1A1CF3F66864312B7502C37C9543A36F24FD38A25137128FFE4C6CC7C078AEF1F799DA7F3E3BA0E19F21A707E66EE95189BDD74EDF32E0F18052384A2A180D90545EF1B9F2710074BC8AED5F7625C0851C34E9F3AE5C57BE65862CEE2891052CC442574EBFAAE1BEC7AB63F25C80951AD65A41089DE526946D858146E446FCAD6915BD59B0D112255083A711279990F87453A6D8F7D057055217F474BACEBBE3 +20241202110503 2 6 100 8191 2 C3301F39F3E2DCD097FBF5454401BF52BF4745AFD35F3DEBDFB34DE2518B0F7BB10DE2FDBE6C35E1B63AA67E9FC179EB3DB8A0FA7E01618BB625B3EC326A001A253FB737B2461999BAB5A5FBCA4AFAD88A8BCBEB5990D4E25225F203B2CE75A3A1C23BFFD78E697275BDB6B6153AA3C21D2063047D44EDDF0483220CD672280D4D67C4726EA476A5C094B7E8DBE62B760EBA6B62C200D456A99E87875B4B2FFF4AA87661D89CAF8CA36D9CE00E0C3BDA443B7CCC3EA892F524AD10DD6960196EC4497E1DDC9F5C13BAED9A8F240196633AB9EC597D0A2FFEEE9320147E73FB295039605EA79376C00D1C60EB421D1BF2BD36A9B68A32E5F5003F0C984E1A57B3C8A261E451D912FCBF27924078BAB0879F85B78D097B2651A17AD9266B39E7AF73DAE54319B2902E0A0D11653B38EDA14B9DE8431E9382AC7EF5F1705C05239DDEA7F533234FA640D2E1EE392D23BF46D57D6FD0E167174E6242F5455DC299BB03BF2EBAEDB14539E9025B84BF66C185AD45C6B1FBF47E3C17D4A1F2C99DCA7151039D71DB7BD2E025E67C2ABB9A2DE6D9C5150651385B270511AA50E8728707B1E0920F3A83DEC0F733090CE96DCACDB93CD756AB1F572DA2BBF4908C17E905848C09CF31424833D1D4894FCB6BD93162EC74E836A523E97F35152EBA28AF63DEC47A32C09E0F0451A4D60949C8CDB07642F5A705075F4A1380B327596C319A135C9C43BBAF2D25C90030BA43FC55701B2854ABFEA710D98AFB8341E46778616A9E9B31CF11652B47A76A99F096BDB35C9CFA78E47CFC980E5E8683E1E13AA3FCA5171C07B5E27C1A5002C02643DC760431C2750A29E838F6ED5A892146D8015F5879DA988DF030BB2FA4D501FB7F0AD9A82ED3C48B70979428C39DB04116DCC8337567B6DB4A0DFE0C704B3F46983BBF092847AED87699EE88AEB27756850D008583CD37FC8521968EB1D17FC42D742B7E6756303412A3AD011DD5CE2BA1A4E3B0B2EBB68736C76B02164C41204734B731DF4C00C937CFB49D4648A7808A34E6162526240AB221071C6C2669DB4787AF7D516F4E72EF81C7D907A37634E8CEC5BF4B3502A6A05224B269B29A8E44603DB2A890F9B64BC94AEC7D2923DC52985CC18E123C7D6CC3DEF885725E0BD2D3EC0466DBE2E94350368068E5FC1CFB6BAC40F47600EB8520A8E29E855D96B556002207CA234BE3620189767ED74ABA3D1A1CF3F66864312B7502C37C9543A36F24FD38A25137128FFE4C6CC7C078AEF1F799DA7F3E3BA0E19F21A707E66EE95189BDD74EDF32E0F18052384A2A180D90545EF1B9F2710074BC8AED5F7625C0851C34E9F3AE5C57BE65862CEE2891052CC442574EBFAAE1BEC7AB63F25C80951AD65A41089DE526946D858146E446FCAD6915BD59B0D112255083A711279990F87453A6D8F7D057055217F474BB359FFB +20241202111809 2 6 100 8191 5 C3301F39F3E2DCD097FBF5454401BF52BF4745AFD35F3DEBDFB34DE2518B0F7BB10DE2FDBE6C35E1B63AA67E9FC179EB3DB8A0FA7E01618BB625B3EC326A001A253FB737B2461999BAB5A5FBCA4AFAD88A8BCBEB5990D4E25225F203B2CE75A3A1C23BFFD78E697275BDB6B6153AA3C21D2063047D44EDDF0483220CD672280D4D67C4726EA476A5C094B7E8DBE62B760EBA6B62C200D456A99E87875B4B2FFF4AA87661D89CAF8CA36D9CE00E0C3BDA443B7CCC3EA892F524AD10DD6960196EC4497E1DDC9F5C13BAED9A8F240196633AB9EC597D0A2FFEEE9320147E73FB295039605EA79376C00D1C60EB421D1BF2BD36A9B68A32E5F5003F0C984E1A57B3C8A261E451D912FCBF27924078BAB0879F85B78D097B2651A17AD9266B39E7AF73DAE54319B2902E0A0D11653B38EDA14B9DE8431E9382AC7EF5F1705C05239DDEA7F533234FA640D2E1EE392D23BF46D57D6FD0E167174E6242F5455DC299BB03BF2EBAEDB14539E9025B84BF66C185AD45C6B1FBF47E3C17D4A1F2C99DCA7151039D71DB7BD2E025E67C2ABB9A2DE6D9C5150651385B270511AA50E8728707B1E0920F3A83DEC0F733090CE96DCACDB93CD756AB1F572DA2BBF4908C17E905848C09CF31424833D1D4894FCB6BD93162EC74E836A523E97F35152EBA28AF63DEC47A32C09E0F0451A4D60949C8CDB07642F5A705075F4A1380B327596C319A135C9C43BBAF2D25C90030BA43FC55701B2854ABFEA710D98AFB8341E46778616A9E9B31CF11652B47A76A99F096BDB35C9CFA78E47CFC980E5E8683E1E13AA3FCA5171C07B5E27C1A5002C02643DC760431C2750A29E838F6ED5A892146D8015F5879DA988DF030BB2FA4D501FB7F0AD9A82ED3C48B70979428C39DB04116DCC8337567B6DB4A0DFE0C704B3F46983BBF092847AED87699EE88AEB27756850D008583CD37FC8521968EB1D17FC42D742B7E6756303412A3AD011DD5CE2BA1A4E3B0B2EBB68736C76B02164C41204734B731DF4C00C937CFB49D4648A7808A34E6162526240AB221071C6C2669DB4787AF7D516F4E72EF81C7D907A37634E8CEC5BF4B3502A6A05224B269B29A8E44603DB2A890F9B64BC94AEC7D2923DC52985CC18E123C7D6CC3DEF885725E0BD2D3EC0466DBE2E94350368068E5FC1CFB6BAC40F47600EB8520A8E29E855D96B556002207CA234BE3620189767ED74ABA3D1A1CF3F66864312B7502C37C9543A36F24FD38A25137128FFE4C6CC7C078AEF1F799DA7F3E3BA0E19F21A707E66EE95189BDD74EDF32E0F18052384A2A180D90545EF1B9F2710074BC8AED5F7625C0851C34E9F3AE5C57BE65862CEE2891052CC442574EBFAAE1BEC7AB63F25C80951AD65A41089DE526946D858146E446FCAD6915BD59B0D112255083A711279990F87453A6D8F7D057055217F474BBDFE367 +20241202113338 2 6 100 8191 5 C3301F39F3E2DCD097FBF5454401BF52BF4745AFD35F3DEBDFB34DE2518B0F7BB10DE2FDBE6C35E1B63AA67E9FC179EB3DB8A0FA7E01618BB625B3EC326A001A253FB737B2461999BAB5A5FBCA4AFAD88A8BCBEB5990D4E25225F203B2CE75A3A1C23BFFD78E697275BDB6B6153AA3C21D2063047D44EDDF0483220CD672280D4D67C4726EA476A5C094B7E8DBE62B760EBA6B62C200D456A99E87875B4B2FFF4AA87661D89CAF8CA36D9CE00E0C3BDA443B7CCC3EA892F524AD10DD6960196EC4497E1DDC9F5C13BAED9A8F240196633AB9EC597D0A2FFEEE9320147E73FB295039605EA79376C00D1C60EB421D1BF2BD36A9B68A32E5F5003F0C984E1A57B3C8A261E451D912FCBF27924078BAB0879F85B78D097B2651A17AD9266B39E7AF73DAE54319B2902E0A0D11653B38EDA14B9DE8431E9382AC7EF5F1705C05239DDEA7F533234FA640D2E1EE392D23BF46D57D6FD0E167174E6242F5455DC299BB03BF2EBAEDB14539E9025B84BF66C185AD45C6B1FBF47E3C17D4A1F2C99DCA7151039D71DB7BD2E025E67C2ABB9A2DE6D9C5150651385B270511AA50E8728707B1E0920F3A83DEC0F733090CE96DCACDB93CD756AB1F572DA2BBF4908C17E905848C09CF31424833D1D4894FCB6BD93162EC74E836A523E97F35152EBA28AF63DEC47A32C09E0F0451A4D60949C8CDB07642F5A705075F4A1380B327596C319A135C9C43BBAF2D25C90030BA43FC55701B2854ABFEA710D98AFB8341E46778616A9E9B31CF11652B47A76A99F096BDB35C9CFA78E47CFC980E5E8683E1E13AA3FCA5171C07B5E27C1A5002C02643DC760431C2750A29E838F6ED5A892146D8015F5879DA988DF030BB2FA4D501FB7F0AD9A82ED3C48B70979428C39DB04116DCC8337567B6DB4A0DFE0C704B3F46983BBF092847AED87699EE88AEB27756850D008583CD37FC8521968EB1D17FC42D742B7E6756303412A3AD011DD5CE2BA1A4E3B0B2EBB68736C76B02164C41204734B731DF4C00C937CFB49D4648A7808A34E6162526240AB221071C6C2669DB4787AF7D516F4E72EF81C7D907A37634E8CEC5BF4B3502A6A05224B269B29A8E44603DB2A890F9B64BC94AEC7D2923DC52985CC18E123C7D6CC3DEF885725E0BD2D3EC0466DBE2E94350368068E5FC1CFB6BAC40F47600EB8520A8E29E855D96B556002207CA234BE3620189767ED74ABA3D1A1CF3F66864312B7502C37C9543A36F24FD38A25137128FFE4C6CC7C078AEF1F799DA7F3E3BA0E19F21A707E66EE95189BDD74EDF32E0F18052384A2A180D90545EF1B9F2710074BC8AED5F7625C0851C34E9F3AE5C57BE65862CEE2891052CC442574EBFAAE1BEC7AB63F25C80951AD65A41089DE526946D858146E446FCAD6915BD59B0D112255083A711279990F87453A6D8F7D057055217F474BCAC42D7 +20241202114109 2 6 100 8191 2 C3301F39F3E2DCD097FBF5454401BF52BF4745AFD35F3DEBDFB34DE2518B0F7BB10DE2FDBE6C35E1B63AA67E9FC179EB3DB8A0FA7E01618BB625B3EC326A001A253FB737B2461999BAB5A5FBCA4AFAD88A8BCBEB5990D4E25225F203B2CE75A3A1C23BFFD78E697275BDB6B6153AA3C21D2063047D44EDDF0483220CD672280D4D67C4726EA476A5C094B7E8DBE62B760EBA6B62C200D456A99E87875B4B2FFF4AA87661D89CAF8CA36D9CE00E0C3BDA443B7CCC3EA892F524AD10DD6960196EC4497E1DDC9F5C13BAED9A8F240196633AB9EC597D0A2FFEEE9320147E73FB295039605EA79376C00D1C60EB421D1BF2BD36A9B68A32E5F5003F0C984E1A57B3C8A261E451D912FCBF27924078BAB0879F85B78D097B2651A17AD9266B39E7AF73DAE54319B2902E0A0D11653B38EDA14B9DE8431E9382AC7EF5F1705C05239DDEA7F533234FA640D2E1EE392D23BF46D57D6FD0E167174E6242F5455DC299BB03BF2EBAEDB14539E9025B84BF66C185AD45C6B1FBF47E3C17D4A1F2C99DCA7151039D71DB7BD2E025E67C2ABB9A2DE6D9C5150651385B270511AA50E8728707B1E0920F3A83DEC0F733090CE96DCACDB93CD756AB1F572DA2BBF4908C17E905848C09CF31424833D1D4894FCB6BD93162EC74E836A523E97F35152EBA28AF63DEC47A32C09E0F0451A4D60949C8CDB07642F5A705075F4A1380B327596C319A135C9C43BBAF2D25C90030BA43FC55701B2854ABFEA710D98AFB8341E46778616A9E9B31CF11652B47A76A99F096BDB35C9CFA78E47CFC980E5E8683E1E13AA3FCA5171C07B5E27C1A5002C02643DC760431C2750A29E838F6ED5A892146D8015F5879DA988DF030BB2FA4D501FB7F0AD9A82ED3C48B70979428C39DB04116DCC8337567B6DB4A0DFE0C704B3F46983BBF092847AED87699EE88AEB27756850D008583CD37FC8521968EB1D17FC42D742B7E6756303412A3AD011DD5CE2BA1A4E3B0B2EBB68736C76B02164C41204734B731DF4C00C937CFB49D4648A7808A34E6162526240AB221071C6C2669DB4787AF7D516F4E72EF81C7D907A37634E8CEC5BF4B3502A6A05224B269B29A8E44603DB2A890F9B64BC94AEC7D2923DC52985CC18E123C7D6CC3DEF885725E0BD2D3EC0466DBE2E94350368068E5FC1CFB6BAC40F47600EB8520A8E29E855D96B556002207CA234BE3620189767ED74ABA3D1A1CF3F66864312B7502C37C9543A36F24FD38A25137128FFE4C6CC7C078AEF1F799DA7F3E3BA0E19F21A707E66EE95189BDD74EDF32E0F18052384A2A180D90545EF1B9F2710074BC8AED5F7625C0851C34E9F3AE5C57BE65862CEE2891052CC442574EBFAAE1BEC7AB63F25C80951AD65A41089DE526946D858146E446FCAD6915BD59B0D112255083A711279990F87453A6D8F7D057055217F474BD0F195B +20241202140045 2 6 100 8191 2 C3301F39F3E2DCD097FBF5454401BF52BF4745AFD35F3DEBDFB34DE2518B0F7BB10DE2FDBE6C35E1B63AA67E9FC179EB3DB8A0FA7E01618BB625B3EC326A001A253FB737B2461999BAB5A5FBCA4AFAD88A8BCBEB5990D4E25225F203B2CE75A3A1C23BFFD78E697275BDB6B6153AA3C21D2063047D44EDDF0483220CD672280D4D67C4726EA476A5C094B7E8DBE62B760EBA6B62C200D456A99E87875B4B2FFF4AA87661D89CAF8CA36D9CE00E0C3BDA443B7CCC3EA892F524AD10DD6960196EC4497E1DDC9F5C13BAED9A8F240196633AB9EC597D0A2FFEEE9320147E73FB295039605EA79376C00D1C60EB421D1BF2BD36A9B68A32E5F5003F0C984E1A57B3C8A261E451D912FCBF27924078BAB0879F85B78D097B2651A17AD9266B39E7AF73DAE54319B2902E0A0D11653B38EDA14B9DE8431E9382AC7EF5F1705C05239DDEA7F533234FA640D2E1EE392D23BF46D57D6FD0E167174E6242F5455DC299BB03BF2EBAEDB14539E9025B84BF66C185AD45C6B1FBF47E3C17D4A1F2C99DCA7151039D71DB7BD2E025E67C2ABB9A2DE6D9C5150651385B270511AA50E8728707B1E0920F3A83DEC0F733090CE96DCACDB93CD756AB1F572DA2BBF4908C17E905848C09CF31424833D1D4894FCB6BD93162EC74E836A523E97F35152EBA28AF63DEC47A32C09E0F0451A4D60949C8CDB07642F5A705075F4A1380B327596C319A135C9C43BBAF2D25C90030BA43FC55701B2854ABFEA710D98AFB8341E46778616A9E9B31CF11652B47A76A99F096BDB35C9CFA78E47CFC980E5E8683E1E13AA3FCA5171C07B5E27C1A5002C02643DC760431C2750A29E838F6ED5A892146D8015F5879DA988DF030BB2FA4D501FB7F0AD9A82ED3C48B70979428C39DB04116DCC8337567B6DB4A0DFE0C704B3F46983BBF092847AED87699EE88AEB27756850D008583CD37FC8521968EB1D17FC42D742B7E6756303412A3AD011DD5CE2BA1A4E3B0B2EBB68736C76B02164C41204734B731DF4C00C937CFB49D4648A7808A34E6162526240AB221071C6C2669DB4787AF7D516F4E72EF81C7D907A37634E8CEC5BF4B3502A6A05224B269B29A8E44603DB2A890F9B64BC94AEC7D2923DC52985CC18E123C7D6CC3DEF885725E0BD2D3EC0466DBE2E94350368068E5FC1CFB6BAC40F47600EB8520A8E29E855D96B556002207CA234BE3620189767ED74ABA3D1A1CF3F66864312B7502C37C9543A36F24FD38A25137128FFE4C6CC7C078AEF1F799DA7F3E3BA0E19F21A707E66EE95189BDD74EDF32E0F18052384A2A180D90545EF1B9F2710074BC8AED5F7625C0851C34E9F3AE5C57BE65862CEE2891052CC442574EBFAAE1BEC7AB63F25C80951AD65A41089DE526946D858146E446FCAD6915BD59B0D112255083A711279990F87453A6D8F7D057055217F474C4C2C8C3 +20241202145509 2 6 100 8191 2 C3301F39F3E2DCD097FBF5454401BF52BF4745AFD35F3DEBDFB34DE2518B0F7BB10DE2FDBE6C35E1B63AA67E9FC179EB3DB8A0FA7E01618BB625B3EC326A001A253FB737B2461999BAB5A5FBCA4AFAD88A8BCBEB5990D4E25225F203B2CE75A3A1C23BFFD78E697275BDB6B6153AA3C21D2063047D44EDDF0483220CD672280D4D67C4726EA476A5C094B7E8DBE62B760EBA6B62C200D456A99E87875B4B2FFF4AA87661D89CAF8CA36D9CE00E0C3BDA443B7CCC3EA892F524AD10DD6960196EC4497E1DDC9F5C13BAED9A8F240196633AB9EC597D0A2FFEEE9320147E73FB295039605EA79376C00D1C60EB421D1BF2BD36A9B68A32E5F5003F0C984E1A57B3C8A261E451D912FCBF27924078BAB0879F85B78D097B2651A17AD9266B39E7AF73DAE54319B2902E0A0D11653B38EDA14B9DE8431E9382AC7EF5F1705C05239DDEA7F533234FA640D2E1EE392D23BF46D57D6FD0E167174E6242F5455DC299BB03BF2EBAEDB14539E9025B84BF66C185AD45C6B1FBF47E3C17D4A1F2C99DCA7151039D71DB7BD2E025E67C2ABB9A2DE6D9C5150651385B270511AA50E8728707B1E0920F3A83DEC0F733090CE96DCACDB93CD756AB1F572DA2BBF4908C17E905848C09CF31424833D1D4894FCB6BD93162EC74E836A523E97F35152EBA28AF63DEC47A32C09E0F0451A4D60949C8CDB07642F5A705075F4A1380B327596C319A135C9C43BBAF2D25C90030BA43FC55701B2854ABFEA710D98AFB8341E46778616A9E9B31CF11652B47A76A99F096BDB35C9CFA78E47CFC980E5E8683E1E13AA3FCA5171C07B5E27C1A5002C02643DC760431C2750A29E838F6ED5A892146D8015F5879DA988DF030BB2FA4D501FB7F0AD9A82ED3C48B70979428C39DB04116DCC8337567B6DB4A0DFE0C704B3F46983BBF092847AED87699EE88AEB27756850D008583CD37FC8521968EB1D17FC42D742B7E6756303412A3AD011DD5CE2BA1A4E3B0B2EBB68736C76B02164C41204734B731DF4C00C937CFB49D4648A7808A34E6162526240AB221071C6C2669DB4787AF7D516F4E72EF81C7D907A37634E8CEC5BF4B3502A6A05224B269B29A8E44603DB2A890F9B64BC94AEC7D2923DC52985CC18E123C7D6CC3DEF885725E0BD2D3EC0466DBE2E94350368068E5FC1CFB6BAC40F47600EB8520A8E29E855D96B556002207CA234BE3620189767ED74ABA3D1A1CF3F66864312B7502C37C9543A36F24FD38A25137128FFE4C6CC7C078AEF1F799DA7F3E3BA0E19F21A707E66EE95189BDD74EDF32E0F18052384A2A180D90545EF1B9F2710074BC8AED5F7625C0851C34E9F3AE5C57BE65862CEE2891052CC442574EBFAAE1BEC7AB63F25C80951AD65A41089DE526946D858146E446FCAD6915BD59B0D112255083A711279990F87453A6D8F7D057055217F474C7B5B2B3 +20241202180737 2 6 100 8191 5 C3301F39F3E2DCD097FBF5454401BF52BF4745AFD35F3DEBDFB34DE2518B0F7BB10DE2FDBE6C35E1B63AA67E9FC179EB3DB8A0FA7E01618BB625B3EC326A001A253FB737B2461999BAB5A5FBCA4AFAD88A8BCBEB5990D4E25225F203B2CE75A3A1C23BFFD78E697275BDB6B6153AA3C21D2063047D44EDDF0483220CD672280D4D67C4726EA476A5C094B7E8DBE62B760EBA6B62C200D456A99E87875B4B2FFF4AA87661D89CAF8CA36D9CE00E0C3BDA443B7CCC3EA892F524AD10DD6960196EC4497E1DDC9F5C13BAED9A8F240196633AB9EC597D0A2FFEEE9320147E73FB295039605EA79376C00D1C60EB421D1BF2BD36A9B68A32E5F5003F0C984E1A57B3C8A261E451D912FCBF27924078BAB0879F85B78D097B2651A17AD9266B39E7AF73DAE54319B2902E0A0D11653B38EDA14B9DE8431E9382AC7EF5F1705C05239DDEA7F533234FA640D2E1EE392D23BF46D57D6FD0E167174E6242F5455DC299BB03BF2EBAEDB14539E9025B84BF66C185AD45C6B1FBF47E3C17D4A1F2C99DCA7151039D71DB7BD2E025E67C2ABB9A2DE6D9C5150651385B270511AA50E8728707B1E0920F3A83DEC0F733090CE96DCACDB93CD756AB1F572DA2BBF4908C17E905848C09CF31424833D1D4894FCB6BD93162EC74E836A523E97F35152EBA28AF63DEC47A32C09E0F0451A4D60949C8CDB07642F5A705075F4A1380B327596C319A135C9C43BBAF2D25C90030BA43FC55701B2854ABFEA710D98AFB8341E46778616A9E9B31CF11652B47A76A99F096BDB35C9CFA78E47CFC980E5E8683E1E13AA3FCA5171C07B5E27C1A5002C02643DC760431C2750A29E838F6ED5A892146D8015F5879DA988DF030BB2FA4D501FB7F0AD9A82ED3C48B70979428C39DB04116DCC8337567B6DB4A0DFE0C704B3F46983BBF092847AED87699EE88AEB27756850D008583CD37FC8521968EB1D17FC42D742B7E6756303412A3AD011DD5CE2BA1A4E3B0B2EBB68736C76B02164C41204734B731DF4C00C937CFB49D4648A7808A34E6162526240AB221071C6C2669DB4787AF7D516F4E72EF81C7D907A37634E8CEC5BF4B3502A6A05224B269B29A8E44603DB2A890F9B64BC94AEC7D2923DC52985CC18E123C7D6CC3DEF885725E0BD2D3EC0466DBE2E94350368068E5FC1CFB6BAC40F47600EB8520A8E29E855D96B556002207CA234BE3620189767ED74ABA3D1A1CF3F66864312B7502C37C9543A36F24FD38A25137128FFE4C6CC7C078AEF1F799DA7F3E3BA0E19F21A707E66EE95189BDD74EDF32E0F18052384A2A180D90545EF1B9F2710074BC8AED5F7625C0851C34E9F3AE5C57BE65862CEE2891052CC442574EBFAAE1BEC7AB63F25C80951AD65A41089DE526946D858146E446FCAD6915BD59B0D112255083A711279990F87453A6D8F7D057055217F474D23791E7 +20241202190603 2 6 100 8191 5 C3301F39F3E2DCD097FBF5454401BF52BF4745AFD35F3DEBDFB34DE2518B0F7BB10DE2FDBE6C35E1B63AA67E9FC179EB3DB8A0FA7E01618BB625B3EC326A001A253FB737B2461999BAB5A5FBCA4AFAD88A8BCBEB5990D4E25225F203B2CE75A3A1C23BFFD78E697275BDB6B6153AA3C21D2063047D44EDDF0483220CD672280D4D67C4726EA476A5C094B7E8DBE62B760EBA6B62C200D456A99E87875B4B2FFF4AA87661D89CAF8CA36D9CE00E0C3BDA443B7CCC3EA892F524AD10DD6960196EC4497E1DDC9F5C13BAED9A8F240196633AB9EC597D0A2FFEEE9320147E73FB295039605EA79376C00D1C60EB421D1BF2BD36A9B68A32E5F5003F0C984E1A57B3C8A261E451D912FCBF27924078BAB0879F85B78D097B2651A17AD9266B39E7AF73DAE54319B2902E0A0D11653B38EDA14B9DE8431E9382AC7EF5F1705C05239DDEA7F533234FA640D2E1EE392D23BF46D57D6FD0E167174E6242F5455DC299BB03BF2EBAEDB14539E9025B84BF66C185AD45C6B1FBF47E3C17D4A1F2C99DCA7151039D71DB7BD2E025E67C2ABB9A2DE6D9C5150651385B270511AA50E8728707B1E0920F3A83DEC0F733090CE96DCACDB93CD756AB1F572DA2BBF4908C17E905848C09CF31424833D1D4894FCB6BD93162EC74E836A523E97F35152EBA28AF63DEC47A32C09E0F0451A4D60949C8CDB07642F5A705075F4A1380B327596C319A135C9C43BBAF2D25C90030BA43FC55701B2854ABFEA710D98AFB8341E46778616A9E9B31CF11652B47A76A99F096BDB35C9CFA78E47CFC980E5E8683E1E13AA3FCA5171C07B5E27C1A5002C02643DC760431C2750A29E838F6ED5A892146D8015F5879DA988DF030BB2FA4D501FB7F0AD9A82ED3C48B70979428C39DB04116DCC8337567B6DB4A0DFE0C704B3F46983BBF092847AED87699EE88AEB27756850D008583CD37FC8521968EB1D17FC42D742B7E6756303412A3AD011DD5CE2BA1A4E3B0B2EBB68736C76B02164C41204734B731DF4C00C937CFB49D4648A7808A34E6162526240AB221071C6C2669DB4787AF7D516F4E72EF81C7D907A37634E8CEC5BF4B3502A6A05224B269B29A8E44603DB2A890F9B64BC94AEC7D2923DC52985CC18E123C7D6CC3DEF885725E0BD2D3EC0466DBE2E94350368068E5FC1CFB6BAC40F47600EB8520A8E29E855D96B556002207CA234BE3620189767ED74ABA3D1A1CF3F66864312B7502C37C9543A36F24FD38A25137128FFE4C6CC7C078AEF1F799DA7F3E3BA0E19F21A707E66EE95189BDD74EDF32E0F18052384A2A180D90545EF1B9F2710074BC8AED5F7625C0851C34E9F3AE5C57BE65862CEE2891052CC442574EBFAAE1BEC7AB63F25C80951AD65A41089DE526946D858146E446FCAD6915BD59B0D112255083A711279990F87453A6D8F7D057055217F474D562B49F +20241202192303 2 6 100 8191 5 C3301F39F3E2DCD097FBF5454401BF52BF4745AFD35F3DEBDFB34DE2518B0F7BB10DE2FDBE6C35E1B63AA67E9FC179EB3DB8A0FA7E01618BB625B3EC326A001A253FB737B2461999BAB5A5FBCA4AFAD88A8BCBEB5990D4E25225F203B2CE75A3A1C23BFFD78E697275BDB6B6153AA3C21D2063047D44EDDF0483220CD672280D4D67C4726EA476A5C094B7E8DBE62B760EBA6B62C200D456A99E87875B4B2FFF4AA87661D89CAF8CA36D9CE00E0C3BDA443B7CCC3EA892F524AD10DD6960196EC4497E1DDC9F5C13BAED9A8F240196633AB9EC597D0A2FFEEE9320147E73FB295039605EA79376C00D1C60EB421D1BF2BD36A9B68A32E5F5003F0C984E1A57B3C8A261E451D912FCBF27924078BAB0879F85B78D097B2651A17AD9266B39E7AF73DAE54319B2902E0A0D11653B38EDA14B9DE8431E9382AC7EF5F1705C05239DDEA7F533234FA640D2E1EE392D23BF46D57D6FD0E167174E6242F5455DC299BB03BF2EBAEDB14539E9025B84BF66C185AD45C6B1FBF47E3C17D4A1F2C99DCA7151039D71DB7BD2E025E67C2ABB9A2DE6D9C5150651385B270511AA50E8728707B1E0920F3A83DEC0F733090CE96DCACDB93CD756AB1F572DA2BBF4908C17E905848C09CF31424833D1D4894FCB6BD93162EC74E836A523E97F35152EBA28AF63DEC47A32C09E0F0451A4D60949C8CDB07642F5A705075F4A1380B327596C319A135C9C43BBAF2D25C90030BA43FC55701B2854ABFEA710D98AFB8341E46778616A9E9B31CF11652B47A76A99F096BDB35C9CFA78E47CFC980E5E8683E1E13AA3FCA5171C07B5E27C1A5002C02643DC760431C2750A29E838F6ED5A892146D8015F5879DA988DF030BB2FA4D501FB7F0AD9A82ED3C48B70979428C39DB04116DCC8337567B6DB4A0DFE0C704B3F46983BBF092847AED87699EE88AEB27756850D008583CD37FC8521968EB1D17FC42D742B7E6756303412A3AD011DD5CE2BA1A4E3B0B2EBB68736C76B02164C41204734B731DF4C00C937CFB49D4648A7808A34E6162526240AB221071C6C2669DB4787AF7D516F4E72EF81C7D907A37634E8CEC5BF4B3502A6A05224B269B29A8E44603DB2A890F9B64BC94AEC7D2923DC52985CC18E123C7D6CC3DEF885725E0BD2D3EC0466DBE2E94350368068E5FC1CFB6BAC40F47600EB8520A8E29E855D96B556002207CA234BE3620189767ED74ABA3D1A1CF3F66864312B7502C37C9543A36F24FD38A25137128FFE4C6CC7C078AEF1F799DA7F3E3BA0E19F21A707E66EE95189BDD74EDF32E0F18052384A2A180D90545EF1B9F2710074BC8AED5F7625C0851C34E9F3AE5C57BE65862CEE2891052CC442574EBFAAE1BEC7AB63F25C80951AD65A41089DE526946D858146E446FCAD6915BD59B0D112255083A711279990F87453A6D8F7D057055217F474D64A0887 +20241202194604 2 6 100 8191 2 C3301F39F3E2DCD097FBF5454401BF52BF4745AFD35F3DEBDFB34DE2518B0F7BB10DE2FDBE6C35E1B63AA67E9FC179EB3DB8A0FA7E01618BB625B3EC326A001A253FB737B2461999BAB5A5FBCA4AFAD88A8BCBEB5990D4E25225F203B2CE75A3A1C23BFFD78E697275BDB6B6153AA3C21D2063047D44EDDF0483220CD672280D4D67C4726EA476A5C094B7E8DBE62B760EBA6B62C200D456A99E87875B4B2FFF4AA87661D89CAF8CA36D9CE00E0C3BDA443B7CCC3EA892F524AD10DD6960196EC4497E1DDC9F5C13BAED9A8F240196633AB9EC597D0A2FFEEE9320147E73FB295039605EA79376C00D1C60EB421D1BF2BD36A9B68A32E5F5003F0C984E1A57B3C8A261E451D912FCBF27924078BAB0879F85B78D097B2651A17AD9266B39E7AF73DAE54319B2902E0A0D11653B38EDA14B9DE8431E9382AC7EF5F1705C05239DDEA7F533234FA640D2E1EE392D23BF46D57D6FD0E167174E6242F5455DC299BB03BF2EBAEDB14539E9025B84BF66C185AD45C6B1FBF47E3C17D4A1F2C99DCA7151039D71DB7BD2E025E67C2ABB9A2DE6D9C5150651385B270511AA50E8728707B1E0920F3A83DEC0F733090CE96DCACDB93CD756AB1F572DA2BBF4908C17E905848C09CF31424833D1D4894FCB6BD93162EC74E836A523E97F35152EBA28AF63DEC47A32C09E0F0451A4D60949C8CDB07642F5A705075F4A1380B327596C319A135C9C43BBAF2D25C90030BA43FC55701B2854ABFEA710D98AFB8341E46778616A9E9B31CF11652B47A76A99F096BDB35C9CFA78E47CFC980E5E8683E1E13AA3FCA5171C07B5E27C1A5002C02643DC760431C2750A29E838F6ED5A892146D8015F5879DA988DF030BB2FA4D501FB7F0AD9A82ED3C48B70979428C39DB04116DCC8337567B6DB4A0DFE0C704B3F46983BBF092847AED87699EE88AEB27756850D008583CD37FC8521968EB1D17FC42D742B7E6756303412A3AD011DD5CE2BA1A4E3B0B2EBB68736C76B02164C41204734B731DF4C00C937CFB49D4648A7808A34E6162526240AB221071C6C2669DB4787AF7D516F4E72EF81C7D907A37634E8CEC5BF4B3502A6A05224B269B29A8E44603DB2A890F9B64BC94AEC7D2923DC52985CC18E123C7D6CC3DEF885725E0BD2D3EC0466DBE2E94350368068E5FC1CFB6BAC40F47600EB8520A8E29E855D96B556002207CA234BE3620189767ED74ABA3D1A1CF3F66864312B7502C37C9543A36F24FD38A25137128FFE4C6CC7C078AEF1F799DA7F3E3BA0E19F21A707E66EE95189BDD74EDF32E0F18052384A2A180D90545EF1B9F2710074BC8AED5F7625C0851C34E9F3AE5C57BE65862CEE2891052CC442574EBFAAE1BEC7AB63F25C80951AD65A41089DE526946D858146E446FCAD6915BD59B0D112255083A711279990F87453A6D8F7D057055217F474D788F30B +20241202202723 2 6 100 8191 5 C3301F39F3E2DCD097FBF5454401BF52BF4745AFD35F3DEBDFB34DE2518B0F7BB10DE2FDBE6C35E1B63AA67E9FC179EB3DB8A0FA7E01618BB625B3EC326A001A253FB737B2461999BAB5A5FBCA4AFAD88A8BCBEB5990D4E25225F203B2CE75A3A1C23BFFD78E697275BDB6B6153AA3C21D2063047D44EDDF0483220CD672280D4D67C4726EA476A5C094B7E8DBE62B760EBA6B62C200D456A99E87875B4B2FFF4AA87661D89CAF8CA36D9CE00E0C3BDA443B7CCC3EA892F524AD10DD6960196EC4497E1DDC9F5C13BAED9A8F240196633AB9EC597D0A2FFEEE9320147E73FB295039605EA79376C00D1C60EB421D1BF2BD36A9B68A32E5F5003F0C984E1A57B3C8A261E451D912FCBF27924078BAB0879F85B78D097B2651A17AD9266B39E7AF73DAE54319B2902E0A0D11653B38EDA14B9DE8431E9382AC7EF5F1705C05239DDEA7F533234FA640D2E1EE392D23BF46D57D6FD0E167174E6242F5455DC299BB03BF2EBAEDB14539E9025B84BF66C185AD45C6B1FBF47E3C17D4A1F2C99DCA7151039D71DB7BD2E025E67C2ABB9A2DE6D9C5150651385B270511AA50E8728707B1E0920F3A83DEC0F733090CE96DCACDB93CD756AB1F572DA2BBF4908C17E905848C09CF31424833D1D4894FCB6BD93162EC74E836A523E97F35152EBA28AF63DEC47A32C09E0F0451A4D60949C8CDB07642F5A705075F4A1380B327596C319A135C9C43BBAF2D25C90030BA43FC55701B2854ABFEA710D98AFB8341E46778616A9E9B31CF11652B47A76A99F096BDB35C9CFA78E47CFC980E5E8683E1E13AA3FCA5171C07B5E27C1A5002C02643DC760431C2750A29E838F6ED5A892146D8015F5879DA988DF030BB2FA4D501FB7F0AD9A82ED3C48B70979428C39DB04116DCC8337567B6DB4A0DFE0C704B3F46983BBF092847AED87699EE88AEB27756850D008583CD37FC8521968EB1D17FC42D742B7E6756303412A3AD011DD5CE2BA1A4E3B0B2EBB68736C76B02164C41204734B731DF4C00C937CFB49D4648A7808A34E6162526240AB221071C6C2669DB4787AF7D516F4E72EF81C7D907A37634E8CEC5BF4B3502A6A05224B269B29A8E44603DB2A890F9B64BC94AEC7D2923DC52985CC18E123C7D6CC3DEF885725E0BD2D3EC0466DBE2E94350368068E5FC1CFB6BAC40F47600EB8520A8E29E855D96B556002207CA234BE3620189767ED74ABA3D1A1CF3F66864312B7502C37C9543A36F24FD38A25137128FFE4C6CC7C078AEF1F799DA7F3E3BA0E19F21A707E66EE95189BDD74EDF32E0F18052384A2A180D90545EF1B9F2710074BC8AED5F7625C0851C34E9F3AE5C57BE65862CEE2891052CC442574EBFAAE1BEC7AB63F25C80951AD65A41089DE526946D858146E446FCAD6915BD59B0D112255083A711279990F87453A6D8F7D057055217F474D9CE5387 +20241202210310 2 6 100 8191 5 C3301F39F3E2DCD097FBF5454401BF52BF4745AFD35F3DEBDFB34DE2518B0F7BB10DE2FDBE6C35E1B63AA67E9FC179EB3DB8A0FA7E01618BB625B3EC326A001A253FB737B2461999BAB5A5FBCA4AFAD88A8BCBEB5990D4E25225F203B2CE75A3A1C23BFFD78E697275BDB6B6153AA3C21D2063047D44EDDF0483220CD672280D4D67C4726EA476A5C094B7E8DBE62B760EBA6B62C200D456A99E87875B4B2FFF4AA87661D89CAF8CA36D9CE00E0C3BDA443B7CCC3EA892F524AD10DD6960196EC4497E1DDC9F5C13BAED9A8F240196633AB9EC597D0A2FFEEE9320147E73FB295039605EA79376C00D1C60EB421D1BF2BD36A9B68A32E5F5003F0C984E1A57B3C8A261E451D912FCBF27924078BAB0879F85B78D097B2651A17AD9266B39E7AF73DAE54319B2902E0A0D11653B38EDA14B9DE8431E9382AC7EF5F1705C05239DDEA7F533234FA640D2E1EE392D23BF46D57D6FD0E167174E6242F5455DC299BB03BF2EBAEDB14539E9025B84BF66C185AD45C6B1FBF47E3C17D4A1F2C99DCA7151039D71DB7BD2E025E67C2ABB9A2DE6D9C5150651385B270511AA50E8728707B1E0920F3A83DEC0F733090CE96DCACDB93CD756AB1F572DA2BBF4908C17E905848C09CF31424833D1D4894FCB6BD93162EC74E836A523E97F35152EBA28AF63DEC47A32C09E0F0451A4D60949C8CDB07642F5A705075F4A1380B327596C319A135C9C43BBAF2D25C90030BA43FC55701B2854ABFEA710D98AFB8341E46778616A9E9B31CF11652B47A76A99F096BDB35C9CFA78E47CFC980E5E8683E1E13AA3FCA5171C07B5E27C1A5002C02643DC760431C2750A29E838F6ED5A892146D8015F5879DA988DF030BB2FA4D501FB7F0AD9A82ED3C48B70979428C39DB04116DCC8337567B6DB4A0DFE0C704B3F46983BBF092847AED87699EE88AEB27756850D008583CD37FC8521968EB1D17FC42D742B7E6756303412A3AD011DD5CE2BA1A4E3B0B2EBB68736C76B02164C41204734B731DF4C00C937CFB49D4648A7808A34E6162526240AB221071C6C2669DB4787AF7D516F4E72EF81C7D907A37634E8CEC5BF4B3502A6A05224B269B29A8E44603DB2A890F9B64BC94AEC7D2923DC52985CC18E123C7D6CC3DEF885725E0BD2D3EC0466DBE2E94350368068E5FC1CFB6BAC40F47600EB8520A8E29E855D96B556002207CA234BE3620189767ED74ABA3D1A1CF3F66864312B7502C37C9543A36F24FD38A25137128FFE4C6CC7C078AEF1F799DA7F3E3BA0E19F21A707E66EE95189BDD74EDF32E0F18052384A2A180D90545EF1B9F2710074BC8AED5F7625C0851C34E9F3AE5C57BE65862CEE2891052CC442574EBFAAE1BEC7AB63F25C80951AD65A41089DE526946D858146E446FCAD6915BD59B0D112255083A711279990F87453A6D8F7D057055217F474DBCBA17F +20241202232141 2 6 100 8191 5 C3301F39F3E2DCD097FBF5454401BF52BF4745AFD35F3DEBDFB34DE2518B0F7BB10DE2FDBE6C35E1B63AA67E9FC179EB3DB8A0FA7E01618BB625B3EC326A001A253FB737B2461999BAB5A5FBCA4AFAD88A8BCBEB5990D4E25225F203B2CE75A3A1C23BFFD78E697275BDB6B6153AA3C21D2063047D44EDDF0483220CD672280D4D67C4726EA476A5C094B7E8DBE62B760EBA6B62C200D456A99E87875B4B2FFF4AA87661D89CAF8CA36D9CE00E0C3BDA443B7CCC3EA892F524AD10DD6960196EC4497E1DDC9F5C13BAED9A8F240196633AB9EC597D0A2FFEEE9320147E73FB295039605EA79376C00D1C60EB421D1BF2BD36A9B68A32E5F5003F0C984E1A57B3C8A261E451D912FCBF27924078BAB0879F85B78D097B2651A17AD9266B39E7AF73DAE54319B2902E0A0D11653B38EDA14B9DE8431E9382AC7EF5F1705C05239DDEA7F533234FA640D2E1EE392D23BF46D57D6FD0E167174E6242F5455DC299BB03BF2EBAEDB14539E9025B84BF66C185AD45C6B1FBF47E3C17D4A1F2C99DCA7151039D71DB7BD2E025E67C2ABB9A2DE6D9C5150651385B270511AA50E8728707B1E0920F3A83DEC0F733090CE96DCACDB93CD756AB1F572DA2BBF4908C17E905848C09CF31424833D1D4894FCB6BD93162EC74E836A523E97F35152EBA28AF63DEC47A32C09E0F0451A4D60949C8CDB07642F5A705075F4A1380B327596C319A135C9C43BBAF2D25C90030BA43FC55701B2854ABFEA710D98AFB8341E46778616A9E9B31CF11652B47A76A99F096BDB35C9CFA78E47CFC980E5E8683E1E13AA3FCA5171C07B5E27C1A5002C02643DC760431C2750A29E838F6ED5A892146D8015F5879DA988DF030BB2FA4D501FB7F0AD9A82ED3C48B70979428C39DB04116DCC8337567B6DB4A0DFE0C704B3F46983BBF092847AED87699EE88AEB27756850D008583CD37FC8521968EB1D17FC42D742B7E6756303412A3AD011DD5CE2BA1A4E3B0B2EBB68736C76B02164C41204734B731DF4C00C937CFB49D4648A7808A34E6162526240AB221071C6C2669DB4787AF7D516F4E72EF81C7D907A37634E8CEC5BF4B3502A6A05224B269B29A8E44603DB2A890F9B64BC94AEC7D2923DC52985CC18E123C7D6CC3DEF885725E0BD2D3EC0466DBE2E94350368068E5FC1CFB6BAC40F47600EB8520A8E29E855D96B556002207CA234BE3620189767ED74ABA3D1A1CF3F66864312B7502C37C9543A36F24FD38A25137128FFE4C6CC7C078AEF1F799DA7F3E3BA0E19F21A707E66EE95189BDD74EDF32E0F18052384A2A180D90545EF1B9F2710074BC8AED5F7625C0851C34E9F3AE5C57BE65862CEE2891052CC442574EBFAAE1BEC7AB63F25C80951AD65A41089DE526946D858146E446FCAD6915BD59B0D112255083A711279990F87453A6D8F7D057055217F474E3833667 +20241202234441 2 6 100 8191 2 C3301F39F3E2DCD097FBF5454401BF52BF4745AFD35F3DEBDFB34DE2518B0F7BB10DE2FDBE6C35E1B63AA67E9FC179EB3DB8A0FA7E01618BB625B3EC326A001A253FB737B2461999BAB5A5FBCA4AFAD88A8BCBEB5990D4E25225F203B2CE75A3A1C23BFFD78E697275BDB6B6153AA3C21D2063047D44EDDF0483220CD672280D4D67C4726EA476A5C094B7E8DBE62B760EBA6B62C200D456A99E87875B4B2FFF4AA87661D89CAF8CA36D9CE00E0C3BDA443B7CCC3EA892F524AD10DD6960196EC4497E1DDC9F5C13BAED9A8F240196633AB9EC597D0A2FFEEE9320147E73FB295039605EA79376C00D1C60EB421D1BF2BD36A9B68A32E5F5003F0C984E1A57B3C8A261E451D912FCBF27924078BAB0879F85B78D097B2651A17AD9266B39E7AF73DAE54319B2902E0A0D11653B38EDA14B9DE8431E9382AC7EF5F1705C05239DDEA7F533234FA640D2E1EE392D23BF46D57D6FD0E167174E6242F5455DC299BB03BF2EBAEDB14539E9025B84BF66C185AD45C6B1FBF47E3C17D4A1F2C99DCA7151039D71DB7BD2E025E67C2ABB9A2DE6D9C5150651385B270511AA50E8728707B1E0920F3A83DEC0F733090CE96DCACDB93CD756AB1F572DA2BBF4908C17E905848C09CF31424833D1D4894FCB6BD93162EC74E836A523E97F35152EBA28AF63DEC47A32C09E0F0451A4D60949C8CDB07642F5A705075F4A1380B327596C319A135C9C43BBAF2D25C90030BA43FC55701B2854ABFEA710D98AFB8341E46778616A9E9B31CF11652B47A76A99F096BDB35C9CFA78E47CFC980E5E8683E1E13AA3FCA5171C07B5E27C1A5002C02643DC760431C2750A29E838F6ED5A892146D8015F5879DA988DF030BB2FA4D501FB7F0AD9A82ED3C48B70979428C39DB04116DCC8337567B6DB4A0DFE0C704B3F46983BBF092847AED87699EE88AEB27756850D008583CD37FC8521968EB1D17FC42D742B7E6756303412A3AD011DD5CE2BA1A4E3B0B2EBB68736C76B02164C41204734B731DF4C00C937CFB49D4648A7808A34E6162526240AB221071C6C2669DB4787AF7D516F4E72EF81C7D907A37634E8CEC5BF4B3502A6A05224B269B29A8E44603DB2A890F9B64BC94AEC7D2923DC52985CC18E123C7D6CC3DEF885725E0BD2D3EC0466DBE2E94350368068E5FC1CFB6BAC40F47600EB8520A8E29E855D96B556002207CA234BE3620189767ED74ABA3D1A1CF3F66864312B7502C37C9543A36F24FD38A25137128FFE4C6CC7C078AEF1F799DA7F3E3BA0E19F21A707E66EE95189BDD74EDF32E0F18052384A2A180D90545EF1B9F2710074BC8AED5F7625C0851C34E9F3AE5C57BE65862CEE2891052CC442574EBFAAE1BEC7AB63F25C80951AD65A41089DE526946D858146E446FCAD6915BD59B0D112255083A711279990F87453A6D8F7D057055217F474E4C55853 +20241202234813 2 6 100 8191 5 C3301F39F3E2DCD097FBF5454401BF52BF4745AFD35F3DEBDFB34DE2518B0F7BB10DE2FDBE6C35E1B63AA67E9FC179EB3DB8A0FA7E01618BB625B3EC326A001A253FB737B2461999BAB5A5FBCA4AFAD88A8BCBEB5990D4E25225F203B2CE75A3A1C23BFFD78E697275BDB6B6153AA3C21D2063047D44EDDF0483220CD672280D4D67C4726EA476A5C094B7E8DBE62B760EBA6B62C200D456A99E87875B4B2FFF4AA87661D89CAF8CA36D9CE00E0C3BDA443B7CCC3EA892F524AD10DD6960196EC4497E1DDC9F5C13BAED9A8F240196633AB9EC597D0A2FFEEE9320147E73FB295039605EA79376C00D1C60EB421D1BF2BD36A9B68A32E5F5003F0C984E1A57B3C8A261E451D912FCBF27924078BAB0879F85B78D097B2651A17AD9266B39E7AF73DAE54319B2902E0A0D11653B38EDA14B9DE8431E9382AC7EF5F1705C05239DDEA7F533234FA640D2E1EE392D23BF46D57D6FD0E167174E6242F5455DC299BB03BF2EBAEDB14539E9025B84BF66C185AD45C6B1FBF47E3C17D4A1F2C99DCA7151039D71DB7BD2E025E67C2ABB9A2DE6D9C5150651385B270511AA50E8728707B1E0920F3A83DEC0F733090CE96DCACDB93CD756AB1F572DA2BBF4908C17E905848C09CF31424833D1D4894FCB6BD93162EC74E836A523E97F35152EBA28AF63DEC47A32C09E0F0451A4D60949C8CDB07642F5A705075F4A1380B327596C319A135C9C43BBAF2D25C90030BA43FC55701B2854ABFEA710D98AFB8341E46778616A9E9B31CF11652B47A76A99F096BDB35C9CFA78E47CFC980E5E8683E1E13AA3FCA5171C07B5E27C1A5002C02643DC760431C2750A29E838F6ED5A892146D8015F5879DA988DF030BB2FA4D501FB7F0AD9A82ED3C48B70979428C39DB04116DCC8337567B6DB4A0DFE0C704B3F46983BBF092847AED87699EE88AEB27756850D008583CD37FC8521968EB1D17FC42D742B7E6756303412A3AD011DD5CE2BA1A4E3B0B2EBB68736C76B02164C41204734B731DF4C00C937CFB49D4648A7808A34E6162526240AB221071C6C2669DB4787AF7D516F4E72EF81C7D907A37634E8CEC5BF4B3502A6A05224B269B29A8E44603DB2A890F9B64BC94AEC7D2923DC52985CC18E123C7D6CC3DEF885725E0BD2D3EC0466DBE2E94350368068E5FC1CFB6BAC40F47600EB8520A8E29E855D96B556002207CA234BE3620189767ED74ABA3D1A1CF3F66864312B7502C37C9543A36F24FD38A25137128FFE4C6CC7C078AEF1F799DA7F3E3BA0E19F21A707E66EE95189BDD74EDF32E0F18052384A2A180D90545EF1B9F2710074BC8AED5F7625C0851C34E9F3AE5C57BE65862CEE2891052CC442574EBFAAE1BEC7AB63F25C80951AD65A41089DE526946D858146E446FCAD6915BD59B0D112255083A711279990F87453A6D8F7D057055217F474E4ED7847 +20241203020245 2 6 100 8191 5 C3301F39F3E2DCD097FBF5454401BF52BF4745AFD35F3DEBDFB34DE2518B0F7BB10DE2FDBE6C35E1B63AA67E9FC179EB3DB8A0FA7E01618BB625B3EC326A001A253FB737B2461999BAB5A5FBCA4AFAD88A8BCBEB5990D4E25225F203B2CE75A3A1C23BFFD78E697275BDB6B6153AA3C21D2063047D44EDDF0483220CD672280D4D67C4726EA476A5C094B7E8DBE62B760EBA6B62C200D456A99E87875B4B2FFF4AA87661D89CAF8CA36D9CE00E0C3BDA443B7CCC3EA892F524AD10DD6960196EC4497E1DDC9F5C13BAED9A8F240196633AB9EC597D0A2FFEEE9320147E73FB295039605EA79376C00D1C60EB421D1BF2BD36A9B68A32E5F5003F0C984E1A57B3C8A261E451D912FCBF27924078BAB0879F85B78D097B2651A17AD9266B39E7AF73DAE54319B2902E0A0D11653B38EDA14B9DE8431E9382AC7EF5F1705C05239DDEA7F533234FA640D2E1EE392D23BF46D57D6FD0E167174E6242F5455DC299BB03BF2EBAEDB14539E9025B84BF66C185AD45C6B1FBF47E3C17D4A1F2C99DCA7151039D71DB7BD2E025E67C2ABB9A2DE6D9C5150651385B270511AA50E8728707B1E0920F3A83DEC0F733090CE96DCACDB93CD756AB1F572DA2BBF4908C17E905848C09CF31424833D1D4894FCB6BD93162EC74E836A523E97F35152EBA28AF63DEC47A32C09E0F0451A4D60949C8CDB07642F5A705075F4A1380B327596C319A135C9C43BBAF2D25C90030BA43FC55701B2854ABFEA710D98AFB8341E46778616A9E9B31CF11652B47A76A99F096BDB35C9CFA78E47CFC980E5E8683E1E13AA3FCA5171C07B5E27C1A5002C02643DC760431C2750A29E838F6ED5A892146D8015F5879DA988DF030BB2FA4D501FB7F0AD9A82ED3C48B70979428C39DB04116DCC8337567B6DB4A0DFE0C704B3F46983BBF092847AED87699EE88AEB27756850D008583CD37FC8521968EB1D17FC42D742B7E6756303412A3AD011DD5CE2BA1A4E3B0B2EBB68736C76B02164C41204734B731DF4C00C937CFB49D4648A7808A34E6162526240AB221071C6C2669DB4787AF7D516F4E72EF81C7D907A37634E8CEC5BF4B3502A6A05224B269B29A8E44603DB2A890F9B64BC94AEC7D2923DC52985CC18E123C7D6CC3DEF885725E0BD2D3EC0466DBE2E94350368068E5FC1CFB6BAC40F47600EB8520A8E29E855D96B556002207CA234BE3620189767ED74ABA3D1A1CF3F66864312B7502C37C9543A36F24FD38A25137128FFE4C6CC7C078AEF1F799DA7F3E3BA0E19F21A707E66EE95189BDD74EDF32E0F18052384A2A180D90545EF1B9F2710074BC8AED5F7625C0851C34E9F3AE5C57BE65862CEE2891052CC442574EBFAAE1BEC7AB63F25C80951AD65A41089DE526946D858146E446FCAD6915BD59B0D112255083A711279990F87453A6D8F7D057055217F474EC649497 +20241203022338 2 6 100 8191 5 C3301F39F3E2DCD097FBF5454401BF52BF4745AFD35F3DEBDFB34DE2518B0F7BB10DE2FDBE6C35E1B63AA67E9FC179EB3DB8A0FA7E01618BB625B3EC326A001A253FB737B2461999BAB5A5FBCA4AFAD88A8BCBEB5990D4E25225F203B2CE75A3A1C23BFFD78E697275BDB6B6153AA3C21D2063047D44EDDF0483220CD672280D4D67C4726EA476A5C094B7E8DBE62B760EBA6B62C200D456A99E87875B4B2FFF4AA87661D89CAF8CA36D9CE00E0C3BDA443B7CCC3EA892F524AD10DD6960196EC4497E1DDC9F5C13BAED9A8F240196633AB9EC597D0A2FFEEE9320147E73FB295039605EA79376C00D1C60EB421D1BF2BD36A9B68A32E5F5003F0C984E1A57B3C8A261E451D912FCBF27924078BAB0879F85B78D097B2651A17AD9266B39E7AF73DAE54319B2902E0A0D11653B38EDA14B9DE8431E9382AC7EF5F1705C05239DDEA7F533234FA640D2E1EE392D23BF46D57D6FD0E167174E6242F5455DC299BB03BF2EBAEDB14539E9025B84BF66C185AD45C6B1FBF47E3C17D4A1F2C99DCA7151039D71DB7BD2E025E67C2ABB9A2DE6D9C5150651385B270511AA50E8728707B1E0920F3A83DEC0F733090CE96DCACDB93CD756AB1F572DA2BBF4908C17E905848C09CF31424833D1D4894FCB6BD93162EC74E836A523E97F35152EBA28AF63DEC47A32C09E0F0451A4D60949C8CDB07642F5A705075F4A1380B327596C319A135C9C43BBAF2D25C90030BA43FC55701B2854ABFEA710D98AFB8341E46778616A9E9B31CF11652B47A76A99F096BDB35C9CFA78E47CFC980E5E8683E1E13AA3FCA5171C07B5E27C1A5002C02643DC760431C2750A29E838F6ED5A892146D8015F5879DA988DF030BB2FA4D501FB7F0AD9A82ED3C48B70979428C39DB04116DCC8337567B6DB4A0DFE0C704B3F46983BBF092847AED87699EE88AEB27756850D008583CD37FC8521968EB1D17FC42D742B7E6756303412A3AD011DD5CE2BA1A4E3B0B2EBB68736C76B02164C41204734B731DF4C00C937CFB49D4648A7808A34E6162526240AB221071C6C2669DB4787AF7D516F4E72EF81C7D907A37634E8CEC5BF4B3502A6A05224B269B29A8E44603DB2A890F9B64BC94AEC7D2923DC52985CC18E123C7D6CC3DEF885725E0BD2D3EC0466DBE2E94350368068E5FC1CFB6BAC40F47600EB8520A8E29E855D96B556002207CA234BE3620189767ED74ABA3D1A1CF3F66864312B7502C37C9543A36F24FD38A25137128FFE4C6CC7C078AEF1F799DA7F3E3BA0E19F21A707E66EE95189BDD74EDF32E0F18052384A2A180D90545EF1B9F2710074BC8AED5F7625C0851C34E9F3AE5C57BE65862CEE2891052CC442574EBFAAE1BEC7AB63F25C80951AD65A41089DE526946D858146E446FCAD6915BD59B0D112255083A711279990F87453A6D8F7D057055217F474ED8847BF +20241203022652 2 6 100 8191 2 C3301F39F3E2DCD097FBF5454401BF52BF4745AFD35F3DEBDFB34DE2518B0F7BB10DE2FDBE6C35E1B63AA67E9FC179EB3DB8A0FA7E01618BB625B3EC326A001A253FB737B2461999BAB5A5FBCA4AFAD88A8BCBEB5990D4E25225F203B2CE75A3A1C23BFFD78E697275BDB6B6153AA3C21D2063047D44EDDF0483220CD672280D4D67C4726EA476A5C094B7E8DBE62B760EBA6B62C200D456A99E87875B4B2FFF4AA87661D89CAF8CA36D9CE00E0C3BDA443B7CCC3EA892F524AD10DD6960196EC4497E1DDC9F5C13BAED9A8F240196633AB9EC597D0A2FFEEE9320147E73FB295039605EA79376C00D1C60EB421D1BF2BD36A9B68A32E5F5003F0C984E1A57B3C8A261E451D912FCBF27924078BAB0879F85B78D097B2651A17AD9266B39E7AF73DAE54319B2902E0A0D11653B38EDA14B9DE8431E9382AC7EF5F1705C05239DDEA7F533234FA640D2E1EE392D23BF46D57D6FD0E167174E6242F5455DC299BB03BF2EBAEDB14539E9025B84BF66C185AD45C6B1FBF47E3C17D4A1F2C99DCA7151039D71DB7BD2E025E67C2ABB9A2DE6D9C5150651385B270511AA50E8728707B1E0920F3A83DEC0F733090CE96DCACDB93CD756AB1F572DA2BBF4908C17E905848C09CF31424833D1D4894FCB6BD93162EC74E836A523E97F35152EBA28AF63DEC47A32C09E0F0451A4D60949C8CDB07642F5A705075F4A1380B327596C319A135C9C43BBAF2D25C90030BA43FC55701B2854ABFEA710D98AFB8341E46778616A9E9B31CF11652B47A76A99F096BDB35C9CFA78E47CFC980E5E8683E1E13AA3FCA5171C07B5E27C1A5002C02643DC760431C2750A29E838F6ED5A892146D8015F5879DA988DF030BB2FA4D501FB7F0AD9A82ED3C48B70979428C39DB04116DCC8337567B6DB4A0DFE0C704B3F46983BBF092847AED87699EE88AEB27756850D008583CD37FC8521968EB1D17FC42D742B7E6756303412A3AD011DD5CE2BA1A4E3B0B2EBB68736C76B02164C41204734B731DF4C00C937CFB49D4648A7808A34E6162526240AB221071C6C2669DB4787AF7D516F4E72EF81C7D907A37634E8CEC5BF4B3502A6A05224B269B29A8E44603DB2A890F9B64BC94AEC7D2923DC52985CC18E123C7D6CC3DEF885725E0BD2D3EC0466DBE2E94350368068E5FC1CFB6BAC40F47600EB8520A8E29E855D96B556002207CA234BE3620189767ED74ABA3D1A1CF3F66864312B7502C37C9543A36F24FD38A25137128FFE4C6CC7C078AEF1F799DA7F3E3BA0E19F21A707E66EE95189BDD74EDF32E0F18052384A2A180D90545EF1B9F2710074BC8AED5F7625C0851C34E9F3AE5C57BE65862CEE2891052CC442574EBFAAE1BEC7AB63F25C80951AD65A41089DE526946D858146E446FCAD6915BD59B0D112255083A711279990F87453A6D8F7D057055217F474EDAC6223 +20241203031204 2 6 100 8191 2 C3301F39F3E2DCD097FBF5454401BF52BF4745AFD35F3DEBDFB34DE2518B0F7BB10DE2FDBE6C35E1B63AA67E9FC179EB3DB8A0FA7E01618BB625B3EC326A001A253FB737B2461999BAB5A5FBCA4AFAD88A8BCBEB5990D4E25225F203B2CE75A3A1C23BFFD78E697275BDB6B6153AA3C21D2063047D44EDDF0483220CD672280D4D67C4726EA476A5C094B7E8DBE62B760EBA6B62C200D456A99E87875B4B2FFF4AA87661D89CAF8CA36D9CE00E0C3BDA443B7CCC3EA892F524AD10DD6960196EC4497E1DDC9F5C13BAED9A8F240196633AB9EC597D0A2FFEEE9320147E73FB295039605EA79376C00D1C60EB421D1BF2BD36A9B68A32E5F5003F0C984E1A57B3C8A261E451D912FCBF27924078BAB0879F85B78D097B2651A17AD9266B39E7AF73DAE54319B2902E0A0D11653B38EDA14B9DE8431E9382AC7EF5F1705C05239DDEA7F533234FA640D2E1EE392D23BF46D57D6FD0E167174E6242F5455DC299BB03BF2EBAEDB14539E9025B84BF66C185AD45C6B1FBF47E3C17D4A1F2C99DCA7151039D71DB7BD2E025E67C2ABB9A2DE6D9C5150651385B270511AA50E8728707B1E0920F3A83DEC0F733090CE96DCACDB93CD756AB1F572DA2BBF4908C17E905848C09CF31424833D1D4894FCB6BD93162EC74E836A523E97F35152EBA28AF63DEC47A32C09E0F0451A4D60949C8CDB07642F5A705075F4A1380B327596C319A135C9C43BBAF2D25C90030BA43FC55701B2854ABFEA710D98AFB8341E46778616A9E9B31CF11652B47A76A99F096BDB35C9CFA78E47CFC980E5E8683E1E13AA3FCA5171C07B5E27C1A5002C02643DC760431C2750A29E838F6ED5A892146D8015F5879DA988DF030BB2FA4D501FB7F0AD9A82ED3C48B70979428C39DB04116DCC8337567B6DB4A0DFE0C704B3F46983BBF092847AED87699EE88AEB27756850D008583CD37FC8521968EB1D17FC42D742B7E6756303412A3AD011DD5CE2BA1A4E3B0B2EBB68736C76B02164C41204734B731DF4C00C937CFB49D4648A7808A34E6162526240AB221071C6C2669DB4787AF7D516F4E72EF81C7D907A37634E8CEC5BF4B3502A6A05224B269B29A8E44603DB2A890F9B64BC94AEC7D2923DC52985CC18E123C7D6CC3DEF885725E0BD2D3EC0466DBE2E94350368068E5FC1CFB6BAC40F47600EB8520A8E29E855D96B556002207CA234BE3620189767ED74ABA3D1A1CF3F66864312B7502C37C9543A36F24FD38A25137128FFE4C6CC7C078AEF1F799DA7F3E3BA0E19F21A707E66EE95189BDD74EDF32E0F18052384A2A180D90545EF1B9F2710074BC8AED5F7625C0851C34E9F3AE5C57BE65862CEE2891052CC442574EBFAAE1BEC7AB63F25C80951AD65A41089DE526946D858146E446FCAD6915BD59B0D112255083A711279990F87453A6D8F7D057055217F474F0205823 +20241203043100 2 6 100 8191 2 C3301F39F3E2DCD097FBF5454401BF52BF4745AFD35F3DEBDFB34DE2518B0F7BB10DE2FDBE6C35E1B63AA67E9FC179EB3DB8A0FA7E01618BB625B3EC326A001A253FB737B2461999BAB5A5FBCA4AFAD88A8BCBEB5990D4E25225F203B2CE75A3A1C23BFFD78E697275BDB6B6153AA3C21D2063047D44EDDF0483220CD672280D4D67C4726EA476A5C094B7E8DBE62B760EBA6B62C200D456A99E87875B4B2FFF4AA87661D89CAF8CA36D9CE00E0C3BDA443B7CCC3EA892F524AD10DD6960196EC4497E1DDC9F5C13BAED9A8F240196633AB9EC597D0A2FFEEE9320147E73FB295039605EA79376C00D1C60EB421D1BF2BD36A9B68A32E5F5003F0C984E1A57B3C8A261E451D912FCBF27924078BAB0879F85B78D097B2651A17AD9266B39E7AF73DAE54319B2902E0A0D11653B38EDA14B9DE8431E9382AC7EF5F1705C05239DDEA7F533234FA640D2E1EE392D23BF46D57D6FD0E167174E6242F5455DC299BB03BF2EBAEDB14539E9025B84BF66C185AD45C6B1FBF47E3C17D4A1F2C99DCA7151039D71DB7BD2E025E67C2ABB9A2DE6D9C5150651385B270511AA50E8728707B1E0920F3A83DEC0F733090CE96DCACDB93CD756AB1F572DA2BBF4908C17E905848C09CF31424833D1D4894FCB6BD93162EC74E836A523E97F35152EBA28AF63DEC47A32C09E0F0451A4D60949C8CDB07642F5A705075F4A1380B327596C319A135C9C43BBAF2D25C90030BA43FC55701B2854ABFEA710D98AFB8341E46778616A9E9B31CF11652B47A76A99F096BDB35C9CFA78E47CFC980E5E8683E1E13AA3FCA5171C07B5E27C1A5002C02643DC760431C2750A29E838F6ED5A892146D8015F5879DA988DF030BB2FA4D501FB7F0AD9A82ED3C48B70979428C39DB04116DCC8337567B6DB4A0DFE0C704B3F46983BBF092847AED87699EE88AEB27756850D008583CD37FC8521968EB1D17FC42D742B7E6756303412A3AD011DD5CE2BA1A4E3B0B2EBB68736C76B02164C41204734B731DF4C00C937CFB49D4648A7808A34E6162526240AB221071C6C2669DB4787AF7D516F4E72EF81C7D907A37634E8CEC5BF4B3502A6A05224B269B29A8E44603DB2A890F9B64BC94AEC7D2923DC52985CC18E123C7D6CC3DEF885725E0BD2D3EC0466DBE2E94350368068E5FC1CFB6BAC40F47600EB8520A8E29E855D96B556002207CA234BE3620189767ED74ABA3D1A1CF3F66864312B7502C37C9543A36F24FD38A25137128FFE4C6CC7C078AEF1F799DA7F3E3BA0E19F21A707E66EE95189BDD74EDF32E0F18052384A2A180D90545EF1B9F2710074BC8AED5F7625C0851C34E9F3AE5C57BE65862CEE2891052CC442574EBFAAE1BEC7AB63F25C80951AD65A41089DE526946D858146E446FCAD6915BD59B0D112255083A711279990F87453A6D8F7D057055217F474F484158B +20241203044332 2 6 100 8191 2 C3301F39F3E2DCD097FBF5454401BF52BF4745AFD35F3DEBDFB34DE2518B0F7BB10DE2FDBE6C35E1B63AA67E9FC179EB3DB8A0FA7E01618BB625B3EC326A001A253FB737B2461999BAB5A5FBCA4AFAD88A8BCBEB5990D4E25225F203B2CE75A3A1C23BFFD78E697275BDB6B6153AA3C21D2063047D44EDDF0483220CD672280D4D67C4726EA476A5C094B7E8DBE62B760EBA6B62C200D456A99E87875B4B2FFF4AA87661D89CAF8CA36D9CE00E0C3BDA443B7CCC3EA892F524AD10DD6960196EC4497E1DDC9F5C13BAED9A8F240196633AB9EC597D0A2FFEEE9320147E73FB295039605EA79376C00D1C60EB421D1BF2BD36A9B68A32E5F5003F0C984E1A57B3C8A261E451D912FCBF27924078BAB0879F85B78D097B2651A17AD9266B39E7AF73DAE54319B2902E0A0D11653B38EDA14B9DE8431E9382AC7EF5F1705C05239DDEA7F533234FA640D2E1EE392D23BF46D57D6FD0E167174E6242F5455DC299BB03BF2EBAEDB14539E9025B84BF66C185AD45C6B1FBF47E3C17D4A1F2C99DCA7151039D71DB7BD2E025E67C2ABB9A2DE6D9C5150651385B270511AA50E8728707B1E0920F3A83DEC0F733090CE96DCACDB93CD756AB1F572DA2BBF4908C17E905848C09CF31424833D1D4894FCB6BD93162EC74E836A523E97F35152EBA28AF63DEC47A32C09E0F0451A4D60949C8CDB07642F5A705075F4A1380B327596C319A135C9C43BBAF2D25C90030BA43FC55701B2854ABFEA710D98AFB8341E46778616A9E9B31CF11652B47A76A99F096BDB35C9CFA78E47CFC980E5E8683E1E13AA3FCA5171C07B5E27C1A5002C02643DC760431C2750A29E838F6ED5A892146D8015F5879DA988DF030BB2FA4D501FB7F0AD9A82ED3C48B70979428C39DB04116DCC8337567B6DB4A0DFE0C704B3F46983BBF092847AED87699EE88AEB27756850D008583CD37FC8521968EB1D17FC42D742B7E6756303412A3AD011DD5CE2BA1A4E3B0B2EBB68736C76B02164C41204734B731DF4C00C937CFB49D4648A7808A34E6162526240AB221071C6C2669DB4787AF7D516F4E72EF81C7D907A37634E8CEC5BF4B3502A6A05224B269B29A8E44603DB2A890F9B64BC94AEC7D2923DC52985CC18E123C7D6CC3DEF885725E0BD2D3EC0466DBE2E94350368068E5FC1CFB6BAC40F47600EB8520A8E29E855D96B556002207CA234BE3620189767ED74ABA3D1A1CF3F66864312B7502C37C9543A36F24FD38A25137128FFE4C6CC7C078AEF1F799DA7F3E3BA0E19F21A707E66EE95189BDD74EDF32E0F18052384A2A180D90545EF1B9F2710074BC8AED5F7625C0851C34E9F3AE5C57BE65862CEE2891052CC442574EBFAAE1BEC7AB63F25C80951AD65A41089DE526946D858146E446FCAD6915BD59B0D112255083A711279990F87453A6D8F7D057055217F474F537BA23 +20241203051425 2 6 100 8191 2 C3301F39F3E2DCD097FBF5454401BF52BF4745AFD35F3DEBDFB34DE2518B0F7BB10DE2FDBE6C35E1B63AA67E9FC179EB3DB8A0FA7E01618BB625B3EC326A001A253FB737B2461999BAB5A5FBCA4AFAD88A8BCBEB5990D4E25225F203B2CE75A3A1C23BFFD78E697275BDB6B6153AA3C21D2063047D44EDDF0483220CD672280D4D67C4726EA476A5C094B7E8DBE62B760EBA6B62C200D456A99E87875B4B2FFF4AA87661D89CAF8CA36D9CE00E0C3BDA443B7CCC3EA892F524AD10DD6960196EC4497E1DDC9F5C13BAED9A8F240196633AB9EC597D0A2FFEEE9320147E73FB295039605EA79376C00D1C60EB421D1BF2BD36A9B68A32E5F5003F0C984E1A57B3C8A261E451D912FCBF27924078BAB0879F85B78D097B2651A17AD9266B39E7AF73DAE54319B2902E0A0D11653B38EDA14B9DE8431E9382AC7EF5F1705C05239DDEA7F533234FA640D2E1EE392D23BF46D57D6FD0E167174E6242F5455DC299BB03BF2EBAEDB14539E9025B84BF66C185AD45C6B1FBF47E3C17D4A1F2C99DCA7151039D71DB7BD2E025E67C2ABB9A2DE6D9C5150651385B270511AA50E8728707B1E0920F3A83DEC0F733090CE96DCACDB93CD756AB1F572DA2BBF4908C17E905848C09CF31424833D1D4894FCB6BD93162EC74E836A523E97F35152EBA28AF63DEC47A32C09E0F0451A4D60949C8CDB07642F5A705075F4A1380B327596C319A135C9C43BBAF2D25C90030BA43FC55701B2854ABFEA710D98AFB8341E46778616A9E9B31CF11652B47A76A99F096BDB35C9CFA78E47CFC980E5E8683E1E13AA3FCA5171C07B5E27C1A5002C02643DC760431C2750A29E838F6ED5A892146D8015F5879DA988DF030BB2FA4D501FB7F0AD9A82ED3C48B70979428C39DB04116DCC8337567B6DB4A0DFE0C704B3F46983BBF092847AED87699EE88AEB27756850D008583CD37FC8521968EB1D17FC42D742B7E6756303412A3AD011DD5CE2BA1A4E3B0B2EBB68736C76B02164C41204734B731DF4C00C937CFB49D4648A7808A34E6162526240AB221071C6C2669DB4787AF7D516F4E72EF81C7D907A37634E8CEC5BF4B3502A6A05224B269B29A8E44603DB2A890F9B64BC94AEC7D2923DC52985CC18E123C7D6CC3DEF885725E0BD2D3EC0466DBE2E94350368068E5FC1CFB6BAC40F47600EB8520A8E29E855D96B556002207CA234BE3620189767ED74ABA3D1A1CF3F66864312B7502C37C9543A36F24FD38A25137128FFE4C6CC7C078AEF1F799DA7F3E3BA0E19F21A707E66EE95189BDD74EDF32E0F18052384A2A180D90545EF1B9F2710074BC8AED5F7625C0851C34E9F3AE5C57BE65862CEE2891052CC442574EBFAAE1BEC7AB63F25C80951AD65A41089DE526946D858146E446FCAD6915BD59B0D112255083A711279990F87453A6D8F7D057055217F474F6E6415B +20241203055801 2 6 100 8191 5 C3301F39F3E2DCD097FBF5454401BF52BF4745AFD35F3DEBDFB34DE2518B0F7BB10DE2FDBE6C35E1B63AA67E9FC179EB3DB8A0FA7E01618BB625B3EC326A001A253FB737B2461999BAB5A5FBCA4AFAD88A8BCBEB5990D4E25225F203B2CE75A3A1C23BFFD78E697275BDB6B6153AA3C21D2063047D44EDDF0483220CD672280D4D67C4726EA476A5C094B7E8DBE62B760EBA6B62C200D456A99E87875B4B2FFF4AA87661D89CAF8CA36D9CE00E0C3BDA443B7CCC3EA892F524AD10DD6960196EC4497E1DDC9F5C13BAED9A8F240196633AB9EC597D0A2FFEEE9320147E73FB295039605EA79376C00D1C60EB421D1BF2BD36A9B68A32E5F5003F0C984E1A57B3C8A261E451D912FCBF27924078BAB0879F85B78D097B2651A17AD9266B39E7AF73DAE54319B2902E0A0D11653B38EDA14B9DE8431E9382AC7EF5F1705C05239DDEA7F533234FA640D2E1EE392D23BF46D57D6FD0E167174E6242F5455DC299BB03BF2EBAEDB14539E9025B84BF66C185AD45C6B1FBF47E3C17D4A1F2C99DCA7151039D71DB7BD2E025E67C2ABB9A2DE6D9C5150651385B270511AA50E8728707B1E0920F3A83DEC0F733090CE96DCACDB93CD756AB1F572DA2BBF4908C17E905848C09CF31424833D1D4894FCB6BD93162EC74E836A523E97F35152EBA28AF63DEC47A32C09E0F0451A4D60949C8CDB07642F5A705075F4A1380B327596C319A135C9C43BBAF2D25C90030BA43FC55701B2854ABFEA710D98AFB8341E46778616A9E9B31CF11652B47A76A99F096BDB35C9CFA78E47CFC980E5E8683E1E13AA3FCA5171C07B5E27C1A5002C02643DC760431C2750A29E838F6ED5A892146D8015F5879DA988DF030BB2FA4D501FB7F0AD9A82ED3C48B70979428C39DB04116DCC8337567B6DB4A0DFE0C704B3F46983BBF092847AED87699EE88AEB27756850D008583CD37FC8521968EB1D17FC42D742B7E6756303412A3AD011DD5CE2BA1A4E3B0B2EBB68736C76B02164C41204734B731DF4C00C937CFB49D4648A7808A34E6162526240AB221071C6C2669DB4787AF7D516F4E72EF81C7D907A37634E8CEC5BF4B3502A6A05224B269B29A8E44603DB2A890F9B64BC94AEC7D2923DC52985CC18E123C7D6CC3DEF885725E0BD2D3EC0466DBE2E94350368068E5FC1CFB6BAC40F47600EB8520A8E29E855D96B556002207CA234BE3620189767ED74ABA3D1A1CF3F66864312B7502C37C9543A36F24FD38A25137128FFE4C6CC7C078AEF1F799DA7F3E3BA0E19F21A707E66EE95189BDD74EDF32E0F18052384A2A180D90545EF1B9F2710074BC8AED5F7625C0851C34E9F3AE5C57BE65862CEE2891052CC442574EBFAAE1BEC7AB63F25C80951AD65A41089DE526946D858146E446FCAD6915BD59B0D112255083A711279990F87453A6D8F7D057055217F474F953468F +20241203062624 2 6 100 8191 5 C3301F39F3E2DCD097FBF5454401BF52BF4745AFD35F3DEBDFB34DE2518B0F7BB10DE2FDBE6C35E1B63AA67E9FC179EB3DB8A0FA7E01618BB625B3EC326A001A253FB737B2461999BAB5A5FBCA4AFAD88A8BCBEB5990D4E25225F203B2CE75A3A1C23BFFD78E697275BDB6B6153AA3C21D2063047D44EDDF0483220CD672280D4D67C4726EA476A5C094B7E8DBE62B760EBA6B62C200D456A99E87875B4B2FFF4AA87661D89CAF8CA36D9CE00E0C3BDA443B7CCC3EA892F524AD10DD6960196EC4497E1DDC9F5C13BAED9A8F240196633AB9EC597D0A2FFEEE9320147E73FB295039605EA79376C00D1C60EB421D1BF2BD36A9B68A32E5F5003F0C984E1A57B3C8A261E451D912FCBF27924078BAB0879F85B78D097B2651A17AD9266B39E7AF73DAE54319B2902E0A0D11653B38EDA14B9DE8431E9382AC7EF5F1705C05239DDEA7F533234FA640D2E1EE392D23BF46D57D6FD0E167174E6242F5455DC299BB03BF2EBAEDB14539E9025B84BF66C185AD45C6B1FBF47E3C17D4A1F2C99DCA7151039D71DB7BD2E025E67C2ABB9A2DE6D9C5150651385B270511AA50E8728707B1E0920F3A83DEC0F733090CE96DCACDB93CD756AB1F572DA2BBF4908C17E905848C09CF31424833D1D4894FCB6BD93162EC74E836A523E97F35152EBA28AF63DEC47A32C09E0F0451A4D60949C8CDB07642F5A705075F4A1380B327596C319A135C9C43BBAF2D25C90030BA43FC55701B2854ABFEA710D98AFB8341E46778616A9E9B31CF11652B47A76A99F096BDB35C9CFA78E47CFC980E5E8683E1E13AA3FCA5171C07B5E27C1A5002C02643DC760431C2750A29E838F6ED5A892146D8015F5879DA988DF030BB2FA4D501FB7F0AD9A82ED3C48B70979428C39DB04116DCC8337567B6DB4A0DFE0C704B3F46983BBF092847AED87699EE88AEB27756850D008583CD37FC8521968EB1D17FC42D742B7E6756303412A3AD011DD5CE2BA1A4E3B0B2EBB68736C76B02164C41204734B731DF4C00C937CFB49D4648A7808A34E6162526240AB221071C6C2669DB4787AF7D516F4E72EF81C7D907A37634E8CEC5BF4B3502A6A05224B269B29A8E44603DB2A890F9B64BC94AEC7D2923DC52985CC18E123C7D6CC3DEF885725E0BD2D3EC0466DBE2E94350368068E5FC1CFB6BAC40F47600EB8520A8E29E855D96B556002207CA234BE3620189767ED74ABA3D1A1CF3F66864312B7502C37C9543A36F24FD38A25137128FFE4C6CC7C078AEF1F799DA7F3E3BA0E19F21A707E66EE95189BDD74EDF32E0F18052384A2A180D90545EF1B9F2710074BC8AED5F7625C0851C34E9F3AE5C57BE65862CEE2891052CC442574EBFAAE1BEC7AB63F25C80951AD65A41089DE526946D858146E446FCAD6915BD59B0D112255083A711279990F87453A6D8F7D057055217F474FAD661D7 +20241203075312 2 6 100 8191 2 C3301F39F3E2DCD097FBF5454401BF52BF4745AFD35F3DEBDFB34DE2518B0F7BB10DE2FDBE6C35E1B63AA67E9FC179EB3DB8A0FA7E01618BB625B3EC326A001A253FB737B2461999BAB5A5FBCA4AFAD88A8BCBEB5990D4E25225F203B2CE75A3A1C23BFFD78E697275BDB6B6153AA3C21D2063047D44EDDF0483220CD672280D4D67C4726EA476A5C094B7E8DBE62B760EBA6B62C200D456A99E87875B4B2FFF4AA87661D89CAF8CA36D9CE00E0C3BDA443B7CCC3EA892F524AD10DD6960196EC4497E1DDC9F5C13BAED9A8F240196633AB9EC597D0A2FFEEE9320147E73FB295039605EA79376C00D1C60EB421D1BF2BD36A9B68A32E5F5003F0C984E1A57B3C8A261E451D912FCBF27924078BAB0879F85B78D097B2651A17AD9266B39E7AF73DAE54319B2902E0A0D11653B38EDA14B9DE8431E9382AC7EF5F1705C05239DDEA7F533234FA640D2E1EE392D23BF46D57D6FD0E167174E6242F5455DC299BB03BF2EBAEDB14539E9025B84BF66C185AD45C6B1FBF47E3C17D4A1F2C99DCA7151039D71DB7BD2E025E67C2ABB9A2DE6D9C5150651385B270511AA50E8728707B1E0920F3A83DEC0F733090CE96DCACDB93CD756AB1F572DA2BBF4908C17E905848C09CF31424833D1D4894FCB6BD93162EC74E836A523E97F35152EBA28AF63DEC47A32C09E0F0451A4D60949C8CDB07642F5A705075F4A1380B327596C319A135C9C43BBAF2D25C90030BA43FC55701B2854ABFEA710D98AFB8341E46778616A9E9B31CF11652B47A76A99F096BDB35C9CFA78E47CFC980E5E8683E1E13AA3FCA5171C07B5E27C1A5002C02643DC760431C2750A29E838F6ED5A892146D8015F5879DA988DF030BB2FA4D501FB7F0AD9A82ED3C48B70979428C39DB04116DCC8337567B6DB4A0DFE0C704B3F46983BBF092847AED87699EE88AEB27756850D008583CD37FC8521968EB1D17FC42D742B7E6756303412A3AD011DD5CE2BA1A4E3B0B2EBB68736C76B02164C41204734B731DF4C00C937CFB49D4648A7808A34E6162526240AB221071C6C2669DB4787AF7D516F4E72EF81C7D907A37634E8CEC5BF4B3502A6A05224B269B29A8E44603DB2A890F9B64BC94AEC7D2923DC52985CC18E123C7D6CC3DEF885725E0BD2D3EC0466DBE2E94350368068E5FC1CFB6BAC40F47600EB8520A8E29E855D96B556002207CA234BE3620189767ED74ABA3D1A1CF3F66864312B7502C37C9543A36F24FD38A25137128FFE4C6CC7C078AEF1F799DA7F3E3BA0E19F21A707E66EE95189BDD74EDF32E0F18052384A2A180D90545EF1B9F2710074BC8AED5F7625C0851C34E9F3AE5C57BE65862CEE2891052CC442574EBFAAE1BEC7AB63F25C80951AD65A41089DE526946D858146E446FCAD6915BD59B0D112255083A711279990F87453A6D8F7D057055217F474FFA46B5B +20241203095857 2 6 100 8191 2 C3301F39F3E2DCD097FBF5454401BF52BF4745AFD35F3DEBDFB34DE2518B0F7BB10DE2FDBE6C35E1B63AA67E9FC179EB3DB8A0FA7E01618BB625B3EC326A001A253FB737B2461999BAB5A5FBCA4AFAD88A8BCBEB5990D4E25225F203B2CE75A3A1C23BFFD78E697275BDB6B6153AA3C21D2063047D44EDDF0483220CD672280D4D67C4726EA476A5C094B7E8DBE62B760EBA6B62C200D456A99E87875B4B2FFF4AA87661D89CAF8CA36D9CE00E0C3BDA443B7CCC3EA892F524AD10DD6960196EC4497E1DDC9F5C13BAED9A8F240196633AB9EC597D0A2FFEEE9320147E73FB295039605EA79376C00D1C60EB421D1BF2BD36A9B68A32E5F5003F0C984E1A57B3C8A261E451D912FCBF27924078BAB0879F85B78D097B2651A17AD9266B39E7AF73DAE54319B2902E0A0D11653B38EDA14B9DE8431E9382AC7EF5F1705C05239DDEA7F533234FA640D2E1EE392D23BF46D57D6FD0E167174E6242F5455DC299BB03BF2EBAEDB14539E9025B84BF66C185AD45C6B1FBF47E3C17D4A1F2C99DCA7151039D71DB7BD2E025E67C2ABB9A2DE6D9C5150651385B270511AA50E8728707B1E0920F3A83DEC0F733090CE96DCACDB93CD756AB1F572DA2BBF4908C17E905848C09CF31424833D1D4894FCB6BD93162EC74E836A523E97F35152EBA28AF63DEC47A32C09E0F0451A4D60949C8CDB07642F5A705075F4A1380B327596C319A135C9C43BBAF2D25C90030BA43FC55701B2854ABFEA710D98AFB8341E46778616A9E9B31CF11652B47A76A99F096BDB35C9CFA78E47CFC980E5E8683E1E13AA3FCA5171C07B5E27C1A5002C02643DC760431C2750A29E838F6ED5A892146D8015F5879DA988DF030BB2FA4D501FB7F0AD9A82ED3C48B70979428C39DB04116DCC8337567B6DB4A0DFE0C704B3F46983BBF092847AED87699EE88AEB27756850D008583CD37FC8521968EB1D17FC42D742B7E6756303412A3AD011DD5CE2BA1A4E3B0B2EBB68736C76B02164C41204734B731DF4C00C937CFB49D4648A7808A34E6162526240AB221071C6C2669DB4787AF7D516F4E72EF81C7D907A37634E8CEC5BF4B3502A6A05224B269B29A8E44603DB2A890F9B64BC94AEC7D2923DC52985CC18E123C7D6CC3DEF885725E0BD2D3EC0466DBE2E94350368068E5FC1CFB6BAC40F47600EB8520A8E29E855D96B556002207CA234BE3620189767ED74ABA3D1A1CF3F66864312B7502C37C9543A36F24FD38A25137128FFE4C6CC7C078AEF1F799DA7F3E3BA0E19F21A707E66EE95189BDD74EDF32E0F18052384A2A180D90545EF1B9F2710074BC8AED5F7625C0851C34E9F3AE5C57BE65862CEE2891052CC442574EBFAAE1BEC7AB63F25C80951AD65A41089DE526946D858146E446FCAD6915BD59B0D112255083A711279990F87453A6D8F7D057055217F4750696836B +20241203111915 2 6 100 8191 2 C3301F39F3E2DCD097FBF5454401BF52BF4745AFD35F3DEBDFB34DE2518B0F7BB10DE2FDBE6C35E1B63AA67E9FC179EB3DB8A0FA7E01618BB625B3EC326A001A253FB737B2461999BAB5A5FBCA4AFAD88A8BCBEB5990D4E25225F203B2CE75A3A1C23BFFD78E697275BDB6B6153AA3C21D2063047D44EDDF0483220CD672280D4D67C4726EA476A5C094B7E8DBE62B760EBA6B62C200D456A99E87875B4B2FFF4AA87661D89CAF8CA36D9CE00E0C3BDA443B7CCC3EA892F524AD10DD6960196EC4497E1DDC9F5C13BAED9A8F240196633AB9EC597D0A2FFEEE9320147E73FB295039605EA79376C00D1C60EB421D1BF2BD36A9B68A32E5F5003F0C984E1A57B3C8A261E451D912FCBF27924078BAB0879F85B78D097B2651A17AD9266B39E7AF73DAE54319B2902E0A0D11653B38EDA14B9DE8431E9382AC7EF5F1705C05239DDEA7F533234FA640D2E1EE392D23BF46D57D6FD0E167174E6242F5455DC299BB03BF2EBAEDB14539E9025B84BF66C185AD45C6B1FBF47E3C17D4A1F2C99DCA7151039D71DB7BD2E025E67C2ABB9A2DE6D9C5150651385B270511AA50E8728707B1E0920F3A83DEC0F733090CE96DCACDB93CD756AB1F572DA2BBF4908C17E905848C09CF31424833D1D4894FCB6BD93162EC74E836A523E97F35152EBA28AF63DEC47A32C09E0F0451A4D60949C8CDB07642F5A705075F4A1380B327596C319A135C9C43BBAF2D25C90030BA43FC55701B2854ABFEA710D98AFB8341E46778616A9E9B31CF11652B47A76A99F096BDB35C9CFA78E47CFC980E5E8683E1E13AA3FCA5171C07B5E27C1A5002C02643DC760431C2750A29E838F6ED5A892146D8015F5879DA988DF030BB2FA4D501FB7F0AD9A82ED3C48B70979428C39DB04116DCC8337567B6DB4A0DFE0C704B3F46983BBF092847AED87699EE88AEB27756850D008583CD37FC8521968EB1D17FC42D742B7E6756303412A3AD011DD5CE2BA1A4E3B0B2EBB68736C76B02164C41204734B731DF4C00C937CFB49D4648A7808A34E6162526240AB221071C6C2669DB4787AF7D516F4E72EF81C7D907A37634E8CEC5BF4B3502A6A05224B269B29A8E44603DB2A890F9B64BC94AEC7D2923DC52985CC18E123C7D6CC3DEF885725E0BD2D3EC0466DBE2E94350368068E5FC1CFB6BAC40F47600EB8520A8E29E855D96B556002207CA234BE3620189767ED74ABA3D1A1CF3F66864312B7502C37C9543A36F24FD38A25137128FFE4C6CC7C078AEF1F799DA7F3E3BA0E19F21A707E66EE95189BDD74EDF32E0F18052384A2A180D90545EF1B9F2710074BC8AED5F7625C0851C34E9F3AE5C57BE65862CEE2891052CC442574EBFAAE1BEC7AB63F25C80951AD65A41089DE526946D858146E446FCAD6915BD59B0D112255083A711279990F87453A6D8F7D057055217F4750B055A7B +20241203151709 2 6 100 8191 2 C3301F39F3E2DCD097FBF5454401BF52BF4745AFD35F3DEBDFB34DE2518B0F7BB10DE2FDBE6C35E1B63AA67E9FC179EB3DB8A0FA7E01618BB625B3EC326A001A253FB737B2461999BAB5A5FBCA4AFAD88A8BCBEB5990D4E25225F203B2CE75A3A1C23BFFD78E697275BDB6B6153AA3C21D2063047D44EDDF0483220CD672280D4D67C4726EA476A5C094B7E8DBE62B760EBA6B62C200D456A99E87875B4B2FFF4AA87661D89CAF8CA36D9CE00E0C3BDA443B7CCC3EA892F524AD10DD6960196EC4497E1DDC9F5C13BAED9A8F240196633AB9EC597D0A2FFEEE9320147E73FB295039605EA79376C00D1C60EB421D1BF2BD36A9B68A32E5F5003F0C984E1A57B3C8A261E451D912FCBF27924078BAB0879F85B78D097B2651A17AD9266B39E7AF73DAE54319B2902E0A0D11653B38EDA14B9DE8431E9382AC7EF5F1705C05239DDEA7F533234FA640D2E1EE392D23BF46D57D6FD0E167174E6242F5455DC299BB03BF2EBAEDB14539E9025B84BF66C185AD45C6B1FBF47E3C17D4A1F2C99DCA7151039D71DB7BD2E025E67C2ABB9A2DE6D9C5150651385B270511AA50E8728707B1E0920F3A83DEC0F733090CE96DCACDB93CD756AB1F572DA2BBF4908C17E905848C09CF31424833D1D4894FCB6BD93162EC74E836A523E97F35152EBA28AF63DEC47A32C09E0F0451A4D60949C8CDB07642F5A705075F4A1380B327596C319A135C9C43BBAF2D25C90030BA43FC55701B2854ABFEA710D98AFB8341E46778616A9E9B31CF11652B47A76A99F096BDB35C9CFA78E47CFC980E5E8683E1E13AA3FCA5171C07B5E27C1A5002C02643DC760431C2750A29E838F6ED5A892146D8015F5879DA988DF030BB2FA4D501FB7F0AD9A82ED3C48B70979428C39DB04116DCC8337567B6DB4A0DFE0C704B3F46983BBF092847AED87699EE88AEB27756850D008583CD37FC8521968EB1D17FC42D742B7E6756303412A3AD011DD5CE2BA1A4E3B0B2EBB68736C76B02164C41204734B731DF4C00C937CFB49D4648A7808A34E6162526240AB221071C6C2669DB4787AF7D516F4E72EF81C7D907A37634E8CEC5BF4B3502A6A05224B269B29A8E44603DB2A890F9B64BC94AEC7D2923DC52985CC18E123C7D6CC3DEF885725E0BD2D3EC0466DBE2E94350368068E5FC1CFB6BAC40F47600EB8520A8E29E855D96B556002207CA234BE3620189767ED74ABA3D1A1CF3F66864312B7502C37C9543A36F24FD38A25137128FFE4C6CC7C078AEF1F799DA7F3E3BA0E19F21A707E66EE95189BDD74EDF32E0F18052384A2A180D90545EF1B9F2710074BC8AED5F7625C0851C34E9F3AE5C57BE65862CEE2891052CC442574EBFAAE1BEC7AB63F25C80951AD65A41089DE526946D858146E446FCAD6915BD59B0D112255083A711279990F87453A6D8F7D057055217F4751817A103 +20241203162310 2 6 100 8191 5 C3301F39F3E2DCD097FBF5454401BF52BF4745AFD35F3DEBDFB34DE2518B0F7BB10DE2FDBE6C35E1B63AA67E9FC179EB3DB8A0FA7E01618BB625B3EC326A001A253FB737B2461999BAB5A5FBCA4AFAD88A8BCBEB5990D4E25225F203B2CE75A3A1C23BFFD78E697275BDB6B6153AA3C21D2063047D44EDDF0483220CD672280D4D67C4726EA476A5C094B7E8DBE62B760EBA6B62C200D456A99E87875B4B2FFF4AA87661D89CAF8CA36D9CE00E0C3BDA443B7CCC3EA892F524AD10DD6960196EC4497E1DDC9F5C13BAED9A8F240196633AB9EC597D0A2FFEEE9320147E73FB295039605EA79376C00D1C60EB421D1BF2BD36A9B68A32E5F5003F0C984E1A57B3C8A261E451D912FCBF27924078BAB0879F85B78D097B2651A17AD9266B39E7AF73DAE54319B2902E0A0D11653B38EDA14B9DE8431E9382AC7EF5F1705C05239DDEA7F533234FA640D2E1EE392D23BF46D57D6FD0E167174E6242F5455DC299BB03BF2EBAEDB14539E9025B84BF66C185AD45C6B1FBF47E3C17D4A1F2C99DCA7151039D71DB7BD2E025E67C2ABB9A2DE6D9C5150651385B270511AA50E8728707B1E0920F3A83DEC0F733090CE96DCACDB93CD756AB1F572DA2BBF4908C17E905848C09CF31424833D1D4894FCB6BD93162EC74E836A523E97F35152EBA28AF63DEC47A32C09E0F0451A4D60949C8CDB07642F5A705075F4A1380B327596C319A135C9C43BBAF2D25C90030BA43FC55701B2854ABFEA710D98AFB8341E46778616A9E9B31CF11652B47A76A99F096BDB35C9CFA78E47CFC980E5E8683E1E13AA3FCA5171C07B5E27C1A5002C02643DC760431C2750A29E838F6ED5A892146D8015F5879DA988DF030BB2FA4D501FB7F0AD9A82ED3C48B70979428C39DB04116DCC8337567B6DB4A0DFE0C704B3F46983BBF092847AED87699EE88AEB27756850D008583CD37FC8521968EB1D17FC42D742B7E6756303412A3AD011DD5CE2BA1A4E3B0B2EBB68736C76B02164C41204734B731DF4C00C937CFB49D4648A7808A34E6162526240AB221071C6C2669DB4787AF7D516F4E72EF81C7D907A37634E8CEC5BF4B3502A6A05224B269B29A8E44603DB2A890F9B64BC94AEC7D2923DC52985CC18E123C7D6CC3DEF885725E0BD2D3EC0466DBE2E94350368068E5FC1CFB6BAC40F47600EB8520A8E29E855D96B556002207CA234BE3620189767ED74ABA3D1A1CF3F66864312B7502C37C9543A36F24FD38A25137128FFE4C6CC7C078AEF1F799DA7F3E3BA0E19F21A707E66EE95189BDD74EDF32E0F18052384A2A180D90545EF1B9F2710074BC8AED5F7625C0851C34E9F3AE5C57BE65862CEE2891052CC442574EBFAAE1BEC7AB63F25C80951AD65A41089DE526946D858146E446FCAD6915BD59B0D112255083A711279990F87453A6D8F7D057055217F4751BBFB51F +20241203173052 2 6 100 8191 5 C3301F39F3E2DCD097FBF5454401BF52BF4745AFD35F3DEBDFB34DE2518B0F7BB10DE2FDBE6C35E1B63AA67E9FC179EB3DB8A0FA7E01618BB625B3EC326A001A253FB737B2461999BAB5A5FBCA4AFAD88A8BCBEB5990D4E25225F203B2CE75A3A1C23BFFD78E697275BDB6B6153AA3C21D2063047D44EDDF0483220CD672280D4D67C4726EA476A5C094B7E8DBE62B760EBA6B62C200D456A99E87875B4B2FFF4AA87661D89CAF8CA36D9CE00E0C3BDA443B7CCC3EA892F524AD10DD6960196EC4497E1DDC9F5C13BAED9A8F240196633AB9EC597D0A2FFEEE9320147E73FB295039605EA79376C00D1C60EB421D1BF2BD36A9B68A32E5F5003F0C984E1A57B3C8A261E451D912FCBF27924078BAB0879F85B78D097B2651A17AD9266B39E7AF73DAE54319B2902E0A0D11653B38EDA14B9DE8431E9382AC7EF5F1705C05239DDEA7F533234FA640D2E1EE392D23BF46D57D6FD0E167174E6242F5455DC299BB03BF2EBAEDB14539E9025B84BF66C185AD45C6B1FBF47E3C17D4A1F2C99DCA7151039D71DB7BD2E025E67C2ABB9A2DE6D9C5150651385B270511AA50E8728707B1E0920F3A83DEC0F733090CE96DCACDB93CD756AB1F572DA2BBF4908C17E905848C09CF31424833D1D4894FCB6BD93162EC74E836A523E97F35152EBA28AF63DEC47A32C09E0F0451A4D60949C8CDB07642F5A705075F4A1380B327596C319A135C9C43BBAF2D25C90030BA43FC55701B2854ABFEA710D98AFB8341E46778616A9E9B31CF11652B47A76A99F096BDB35C9CFA78E47CFC980E5E8683E1E13AA3FCA5171C07B5E27C1A5002C02643DC760431C2750A29E838F6ED5A892146D8015F5879DA988DF030BB2FA4D501FB7F0AD9A82ED3C48B70979428C39DB04116DCC8337567B6DB4A0DFE0C704B3F46983BBF092847AED87699EE88AEB27756850D008583CD37FC8521968EB1D17FC42D742B7E6756303412A3AD011DD5CE2BA1A4E3B0B2EBB68736C76B02164C41204734B731DF4C00C937CFB49D4648A7808A34E6162526240AB221071C6C2669DB4787AF7D516F4E72EF81C7D907A37634E8CEC5BF4B3502A6A05224B269B29A8E44603DB2A890F9B64BC94AEC7D2923DC52985CC18E123C7D6CC3DEF885725E0BD2D3EC0466DBE2E94350368068E5FC1CFB6BAC40F47600EB8520A8E29E855D96B556002207CA234BE3620189767ED74ABA3D1A1CF3F66864312B7502C37C9543A36F24FD38A25137128FFE4C6CC7C078AEF1F799DA7F3E3BA0E19F21A707E66EE95189BDD74EDF32E0F18052384A2A180D90545EF1B9F2710074BC8AED5F7625C0851C34E9F3AE5C57BE65862CEE2891052CC442574EBFAAE1BEC7AB63F25C80951AD65A41089DE526946D858146E446FCAD6915BD59B0D112255083A711279990F87453A6D8F7D057055217F4751F72906F +20241203182303 2 6 100 8191 2 C3301F39F3E2DCD097FBF5454401BF52BF4745AFD35F3DEBDFB34DE2518B0F7BB10DE2FDBE6C35E1B63AA67E9FC179EB3DB8A0FA7E01618BB625B3EC326A001A253FB737B2461999BAB5A5FBCA4AFAD88A8BCBEB5990D4E25225F203B2CE75A3A1C23BFFD78E697275BDB6B6153AA3C21D2063047D44EDDF0483220CD672280D4D67C4726EA476A5C094B7E8DBE62B760EBA6B62C200D456A99E87875B4B2FFF4AA87661D89CAF8CA36D9CE00E0C3BDA443B7CCC3EA892F524AD10DD6960196EC4497E1DDC9F5C13BAED9A8F240196633AB9EC597D0A2FFEEE9320147E73FB295039605EA79376C00D1C60EB421D1BF2BD36A9B68A32E5F5003F0C984E1A57B3C8A261E451D912FCBF27924078BAB0879F85B78D097B2651A17AD9266B39E7AF73DAE54319B2902E0A0D11653B38EDA14B9DE8431E9382AC7EF5F1705C05239DDEA7F533234FA640D2E1EE392D23BF46D57D6FD0E167174E6242F5455DC299BB03BF2EBAEDB14539E9025B84BF66C185AD45C6B1FBF47E3C17D4A1F2C99DCA7151039D71DB7BD2E025E67C2ABB9A2DE6D9C5150651385B270511AA50E8728707B1E0920F3A83DEC0F733090CE96DCACDB93CD756AB1F572DA2BBF4908C17E905848C09CF31424833D1D4894FCB6BD93162EC74E836A523E97F35152EBA28AF63DEC47A32C09E0F0451A4D60949C8CDB07642F5A705075F4A1380B327596C319A135C9C43BBAF2D25C90030BA43FC55701B2854ABFEA710D98AFB8341E46778616A9E9B31CF11652B47A76A99F096BDB35C9CFA78E47CFC980E5E8683E1E13AA3FCA5171C07B5E27C1A5002C02643DC760431C2750A29E838F6ED5A892146D8015F5879DA988DF030BB2FA4D501FB7F0AD9A82ED3C48B70979428C39DB04116DCC8337567B6DB4A0DFE0C704B3F46983BBF092847AED87699EE88AEB27756850D008583CD37FC8521968EB1D17FC42D742B7E6756303412A3AD011DD5CE2BA1A4E3B0B2EBB68736C76B02164C41204734B731DF4C00C937CFB49D4648A7808A34E6162526240AB221071C6C2669DB4787AF7D516F4E72EF81C7D907A37634E8CEC5BF4B3502A6A05224B269B29A8E44603DB2A890F9B64BC94AEC7D2923DC52985CC18E123C7D6CC3DEF885725E0BD2D3EC0466DBE2E94350368068E5FC1CFB6BAC40F47600EB8520A8E29E855D96B556002207CA234BE3620189767ED74ABA3D1A1CF3F66864312B7502C37C9543A36F24FD38A25137128FFE4C6CC7C078AEF1F799DA7F3E3BA0E19F21A707E66EE95189BDD74EDF32E0F18052384A2A180D90545EF1B9F2710074BC8AED5F7625C0851C34E9F3AE5C57BE65862CEE2891052CC442574EBFAAE1BEC7AB63F25C80951AD65A41089DE526946D858146E446FCAD6915BD59B0D112255083A711279990F87453A6D8F7D057055217F475224CDDDB +20241203194121 2 6 100 8191 5 C3301F39F3E2DCD097FBF5454401BF52BF4745AFD35F3DEBDFB34DE2518B0F7BB10DE2FDBE6C35E1B63AA67E9FC179EB3DB8A0FA7E01618BB625B3EC326A001A253FB737B2461999BAB5A5FBCA4AFAD88A8BCBEB5990D4E25225F203B2CE75A3A1C23BFFD78E697275BDB6B6153AA3C21D2063047D44EDDF0483220CD672280D4D67C4726EA476A5C094B7E8DBE62B760EBA6B62C200D456A99E87875B4B2FFF4AA87661D89CAF8CA36D9CE00E0C3BDA443B7CCC3EA892F524AD10DD6960196EC4497E1DDC9F5C13BAED9A8F240196633AB9EC597D0A2FFEEE9320147E73FB295039605EA79376C00D1C60EB421D1BF2BD36A9B68A32E5F5003F0C984E1A57B3C8A261E451D912FCBF27924078BAB0879F85B78D097B2651A17AD9266B39E7AF73DAE54319B2902E0A0D11653B38EDA14B9DE8431E9382AC7EF5F1705C05239DDEA7F533234FA640D2E1EE392D23BF46D57D6FD0E167174E6242F5455DC299BB03BF2EBAEDB14539E9025B84BF66C185AD45C6B1FBF47E3C17D4A1F2C99DCA7151039D71DB7BD2E025E67C2ABB9A2DE6D9C5150651385B270511AA50E8728707B1E0920F3A83DEC0F733090CE96DCACDB93CD756AB1F572DA2BBF4908C17E905848C09CF31424833D1D4894FCB6BD93162EC74E836A523E97F35152EBA28AF63DEC47A32C09E0F0451A4D60949C8CDB07642F5A705075F4A1380B327596C319A135C9C43BBAF2D25C90030BA43FC55701B2854ABFEA710D98AFB8341E46778616A9E9B31CF11652B47A76A99F096BDB35C9CFA78E47CFC980E5E8683E1E13AA3FCA5171C07B5E27C1A5002C02643DC760431C2750A29E838F6ED5A892146D8015F5879DA988DF030BB2FA4D501FB7F0AD9A82ED3C48B70979428C39DB04116DCC8337567B6DB4A0DFE0C704B3F46983BBF092847AED87699EE88AEB27756850D008583CD37FC8521968EB1D17FC42D742B7E6756303412A3AD011DD5CE2BA1A4E3B0B2EBB68736C76B02164C41204734B731DF4C00C937CFB49D4648A7808A34E6162526240AB221071C6C2669DB4787AF7D516F4E72EF81C7D907A37634E8CEC5BF4B3502A6A05224B269B29A8E44603DB2A890F9B64BC94AEC7D2923DC52985CC18E123C7D6CC3DEF885725E0BD2D3EC0466DBE2E94350368068E5FC1CFB6BAC40F47600EB8520A8E29E855D96B556002207CA234BE3620189767ED74ABA3D1A1CF3F66864312B7502C37C9543A36F24FD38A25137128FFE4C6CC7C078AEF1F799DA7F3E3BA0E19F21A707E66EE95189BDD74EDF32E0F18052384A2A180D90545EF1B9F2710074BC8AED5F7625C0851C34E9F3AE5C57BE65862CEE2891052CC442574EBFAAE1BEC7AB63F25C80951AD65A41089DE526946D858146E446FCAD6915BD59B0D112255083A711279990F87453A6D8F7D057055217F47526993A97 +20241203203340 2 6 100 8191 2 C3301F39F3E2DCD097FBF5454401BF52BF4745AFD35F3DEBDFB34DE2518B0F7BB10DE2FDBE6C35E1B63AA67E9FC179EB3DB8A0FA7E01618BB625B3EC326A001A253FB737B2461999BAB5A5FBCA4AFAD88A8BCBEB5990D4E25225F203B2CE75A3A1C23BFFD78E697275BDB6B6153AA3C21D2063047D44EDDF0483220CD672280D4D67C4726EA476A5C094B7E8DBE62B760EBA6B62C200D456A99E87875B4B2FFF4AA87661D89CAF8CA36D9CE00E0C3BDA443B7CCC3EA892F524AD10DD6960196EC4497E1DDC9F5C13BAED9A8F240196633AB9EC597D0A2FFEEE9320147E73FB295039605EA79376C00D1C60EB421D1BF2BD36A9B68A32E5F5003F0C984E1A57B3C8A261E451D912FCBF27924078BAB0879F85B78D097B2651A17AD9266B39E7AF73DAE54319B2902E0A0D11653B38EDA14B9DE8431E9382AC7EF5F1705C05239DDEA7F533234FA640D2E1EE392D23BF46D57D6FD0E167174E6242F5455DC299BB03BF2EBAEDB14539E9025B84BF66C185AD45C6B1FBF47E3C17D4A1F2C99DCA7151039D71DB7BD2E025E67C2ABB9A2DE6D9C5150651385B270511AA50E8728707B1E0920F3A83DEC0F733090CE96DCACDB93CD756AB1F572DA2BBF4908C17E905848C09CF31424833D1D4894FCB6BD93162EC74E836A523E97F35152EBA28AF63DEC47A32C09E0F0451A4D60949C8CDB07642F5A705075F4A1380B327596C319A135C9C43BBAF2D25C90030BA43FC55701B2854ABFEA710D98AFB8341E46778616A9E9B31CF11652B47A76A99F096BDB35C9CFA78E47CFC980E5E8683E1E13AA3FCA5171C07B5E27C1A5002C02643DC760431C2750A29E838F6ED5A892146D8015F5879DA988DF030BB2FA4D501FB7F0AD9A82ED3C48B70979428C39DB04116DCC8337567B6DB4A0DFE0C704B3F46983BBF092847AED87699EE88AEB27756850D008583CD37FC8521968EB1D17FC42D742B7E6756303412A3AD011DD5CE2BA1A4E3B0B2EBB68736C76B02164C41204734B731DF4C00C937CFB49D4648A7808A34E6162526240AB221071C6C2669DB4787AF7D516F4E72EF81C7D907A37634E8CEC5BF4B3502A6A05224B269B29A8E44603DB2A890F9B64BC94AEC7D2923DC52985CC18E123C7D6CC3DEF885725E0BD2D3EC0466DBE2E94350368068E5FC1CFB6BAC40F47600EB8520A8E29E855D96B556002207CA234BE3620189767ED74ABA3D1A1CF3F66864312B7502C37C9543A36F24FD38A25137128FFE4C6CC7C078AEF1F799DA7F3E3BA0E19F21A707E66EE95189BDD74EDF32E0F18052384A2A180D90545EF1B9F2710074BC8AED5F7625C0851C34E9F3AE5C57BE65862CEE2891052CC442574EBFAAE1BEC7AB63F25C80951AD65A41089DE526946D858146E446FCAD6915BD59B0D112255083A711279990F87453A6D8F7D057055217F475298312DB +20241203203518 2 6 100 8191 5 C3301F39F3E2DCD097FBF5454401BF52BF4745AFD35F3DEBDFB34DE2518B0F7BB10DE2FDBE6C35E1B63AA67E9FC179EB3DB8A0FA7E01618BB625B3EC326A001A253FB737B2461999BAB5A5FBCA4AFAD88A8BCBEB5990D4E25225F203B2CE75A3A1C23BFFD78E697275BDB6B6153AA3C21D2063047D44EDDF0483220CD672280D4D67C4726EA476A5C094B7E8DBE62B760EBA6B62C200D456A99E87875B4B2FFF4AA87661D89CAF8CA36D9CE00E0C3BDA443B7CCC3EA892F524AD10DD6960196EC4497E1DDC9F5C13BAED9A8F240196633AB9EC597D0A2FFEEE9320147E73FB295039605EA79376C00D1C60EB421D1BF2BD36A9B68A32E5F5003F0C984E1A57B3C8A261E451D912FCBF27924078BAB0879F85B78D097B2651A17AD9266B39E7AF73DAE54319B2902E0A0D11653B38EDA14B9DE8431E9382AC7EF5F1705C05239DDEA7F533234FA640D2E1EE392D23BF46D57D6FD0E167174E6242F5455DC299BB03BF2EBAEDB14539E9025B84BF66C185AD45C6B1FBF47E3C17D4A1F2C99DCA7151039D71DB7BD2E025E67C2ABB9A2DE6D9C5150651385B270511AA50E8728707B1E0920F3A83DEC0F733090CE96DCACDB93CD756AB1F572DA2BBF4908C17E905848C09CF31424833D1D4894FCB6BD93162EC74E836A523E97F35152EBA28AF63DEC47A32C09E0F0451A4D60949C8CDB07642F5A705075F4A1380B327596C319A135C9C43BBAF2D25C90030BA43FC55701B2854ABFEA710D98AFB8341E46778616A9E9B31CF11652B47A76A99F096BDB35C9CFA78E47CFC980E5E8683E1E13AA3FCA5171C07B5E27C1A5002C02643DC760431C2750A29E838F6ED5A892146D8015F5879DA988DF030BB2FA4D501FB7F0AD9A82ED3C48B70979428C39DB04116DCC8337567B6DB4A0DFE0C704B3F46983BBF092847AED87699EE88AEB27756850D008583CD37FC8521968EB1D17FC42D742B7E6756303412A3AD011DD5CE2BA1A4E3B0B2EBB68736C76B02164C41204734B731DF4C00C937CFB49D4648A7808A34E6162526240AB221071C6C2669DB4787AF7D516F4E72EF81C7D907A37634E8CEC5BF4B3502A6A05224B269B29A8E44603DB2A890F9B64BC94AEC7D2923DC52985CC18E123C7D6CC3DEF885725E0BD2D3EC0466DBE2E94350368068E5FC1CFB6BAC40F47600EB8520A8E29E855D96B556002207CA234BE3620189767ED74ABA3D1A1CF3F66864312B7502C37C9543A36F24FD38A25137128FFE4C6CC7C078AEF1F799DA7F3E3BA0E19F21A707E66EE95189BDD74EDF32E0F18052384A2A180D90545EF1B9F2710074BC8AED5F7625C0851C34E9F3AE5C57BE65862CEE2891052CC442574EBFAAE1BEC7AB63F25C80951AD65A41089DE526946D858146E446FCAD6915BD59B0D112255083A711279990F87453A6D8F7D057055217F475299334C7 +20241203220054 2 6 100 8191 5 C3301F39F3E2DCD097FBF5454401BF52BF4745AFD35F3DEBDFB34DE2518B0F7BB10DE2FDBE6C35E1B63AA67E9FC179EB3DB8A0FA7E01618BB625B3EC326A001A253FB737B2461999BAB5A5FBCA4AFAD88A8BCBEB5990D4E25225F203B2CE75A3A1C23BFFD78E697275BDB6B6153AA3C21D2063047D44EDDF0483220CD672280D4D67C4726EA476A5C094B7E8DBE62B760EBA6B62C200D456A99E87875B4B2FFF4AA87661D89CAF8CA36D9CE00E0C3BDA443B7CCC3EA892F524AD10DD6960196EC4497E1DDC9F5C13BAED9A8F240196633AB9EC597D0A2FFEEE9320147E73FB295039605EA79376C00D1C60EB421D1BF2BD36A9B68A32E5F5003F0C984E1A57B3C8A261E451D912FCBF27924078BAB0879F85B78D097B2651A17AD9266B39E7AF73DAE54319B2902E0A0D11653B38EDA14B9DE8431E9382AC7EF5F1705C05239DDEA7F533234FA640D2E1EE392D23BF46D57D6FD0E167174E6242F5455DC299BB03BF2EBAEDB14539E9025B84BF66C185AD45C6B1FBF47E3C17D4A1F2C99DCA7151039D71DB7BD2E025E67C2ABB9A2DE6D9C5150651385B270511AA50E8728707B1E0920F3A83DEC0F733090CE96DCACDB93CD756AB1F572DA2BBF4908C17E905848C09CF31424833D1D4894FCB6BD93162EC74E836A523E97F35152EBA28AF63DEC47A32C09E0F0451A4D60949C8CDB07642F5A705075F4A1380B327596C319A135C9C43BBAF2D25C90030BA43FC55701B2854ABFEA710D98AFB8341E46778616A9E9B31CF11652B47A76A99F096BDB35C9CFA78E47CFC980E5E8683E1E13AA3FCA5171C07B5E27C1A5002C02643DC760431C2750A29E838F6ED5A892146D8015F5879DA988DF030BB2FA4D501FB7F0AD9A82ED3C48B70979428C39DB04116DCC8337567B6DB4A0DFE0C704B3F46983BBF092847AED87699EE88AEB27756850D008583CD37FC8521968EB1D17FC42D742B7E6756303412A3AD011DD5CE2BA1A4E3B0B2EBB68736C76B02164C41204734B731DF4C00C937CFB49D4648A7808A34E6162526240AB221071C6C2669DB4787AF7D516F4E72EF81C7D907A37634E8CEC5BF4B3502A6A05224B269B29A8E44603DB2A890F9B64BC94AEC7D2923DC52985CC18E123C7D6CC3DEF885725E0BD2D3EC0466DBE2E94350368068E5FC1CFB6BAC40F47600EB8520A8E29E855D96B556002207CA234BE3620189767ED74ABA3D1A1CF3F66864312B7502C37C9543A36F24FD38A25137128FFE4C6CC7C078AEF1F799DA7F3E3BA0E19F21A707E66EE95189BDD74EDF32E0F18052384A2A180D90545EF1B9F2710074BC8AED5F7625C0851C34E9F3AE5C57BE65862CEE2891052CC442574EBFAAE1BEC7AB63F25C80951AD65A41089DE526946D858146E446FCAD6915BD59B0D112255083A711279990F87453A6D8F7D057055217F4752E4DBDDF +20241203220341 2 6 100 8191 2 C3301F39F3E2DCD097FBF5454401BF52BF4745AFD35F3DEBDFB34DE2518B0F7BB10DE2FDBE6C35E1B63AA67E9FC179EB3DB8A0FA7E01618BB625B3EC326A001A253FB737B2461999BAB5A5FBCA4AFAD88A8BCBEB5990D4E25225F203B2CE75A3A1C23BFFD78E697275BDB6B6153AA3C21D2063047D44EDDF0483220CD672280D4D67C4726EA476A5C094B7E8DBE62B760EBA6B62C200D456A99E87875B4B2FFF4AA87661D89CAF8CA36D9CE00E0C3BDA443B7CCC3EA892F524AD10DD6960196EC4497E1DDC9F5C13BAED9A8F240196633AB9EC597D0A2FFEEE9320147E73FB295039605EA79376C00D1C60EB421D1BF2BD36A9B68A32E5F5003F0C984E1A57B3C8A261E451D912FCBF27924078BAB0879F85B78D097B2651A17AD9266B39E7AF73DAE54319B2902E0A0D11653B38EDA14B9DE8431E9382AC7EF5F1705C05239DDEA7F533234FA640D2E1EE392D23BF46D57D6FD0E167174E6242F5455DC299BB03BF2EBAEDB14539E9025B84BF66C185AD45C6B1FBF47E3C17D4A1F2C99DCA7151039D71DB7BD2E025E67C2ABB9A2DE6D9C5150651385B270511AA50E8728707B1E0920F3A83DEC0F733090CE96DCACDB93CD756AB1F572DA2BBF4908C17E905848C09CF31424833D1D4894FCB6BD93162EC74E836A523E97F35152EBA28AF63DEC47A32C09E0F0451A4D60949C8CDB07642F5A705075F4A1380B327596C319A135C9C43BBAF2D25C90030BA43FC55701B2854ABFEA710D98AFB8341E46778616A9E9B31CF11652B47A76A99F096BDB35C9CFA78E47CFC980E5E8683E1E13AA3FCA5171C07B5E27C1A5002C02643DC760431C2750A29E838F6ED5A892146D8015F5879DA988DF030BB2FA4D501FB7F0AD9A82ED3C48B70979428C39DB04116DCC8337567B6DB4A0DFE0C704B3F46983BBF092847AED87699EE88AEB27756850D008583CD37FC8521968EB1D17FC42D742B7E6756303412A3AD011DD5CE2BA1A4E3B0B2EBB68736C76B02164C41204734B731DF4C00C937CFB49D4648A7808A34E6162526240AB221071C6C2669DB4787AF7D516F4E72EF81C7D907A37634E8CEC5BF4B3502A6A05224B269B29A8E44603DB2A890F9B64BC94AEC7D2923DC52985CC18E123C7D6CC3DEF885725E0BD2D3EC0466DBE2E94350368068E5FC1CFB6BAC40F47600EB8520A8E29E855D96B556002207CA234BE3620189767ED74ABA3D1A1CF3F66864312B7502C37C9543A36F24FD38A25137128FFE4C6CC7C078AEF1F799DA7F3E3BA0E19F21A707E66EE95189BDD74EDF32E0F18052384A2A180D90545EF1B9F2710074BC8AED5F7625C0851C34E9F3AE5C57BE65862CEE2891052CC442574EBFAAE1BEC7AB63F25C80951AD65A41089DE526946D858146E446FCAD6915BD59B0D112255083A711279990F87453A6D8F7D057055217F4752E6D1DC3 +20241203221452 2 6 100 8191 2 C3301F39F3E2DCD097FBF5454401BF52BF4745AFD35F3DEBDFB34DE2518B0F7BB10DE2FDBE6C35E1B63AA67E9FC179EB3DB8A0FA7E01618BB625B3EC326A001A253FB737B2461999BAB5A5FBCA4AFAD88A8BCBEB5990D4E25225F203B2CE75A3A1C23BFFD78E697275BDB6B6153AA3C21D2063047D44EDDF0483220CD672280D4D67C4726EA476A5C094B7E8DBE62B760EBA6B62C200D456A99E87875B4B2FFF4AA87661D89CAF8CA36D9CE00E0C3BDA443B7CCC3EA892F524AD10DD6960196EC4497E1DDC9F5C13BAED9A8F240196633AB9EC597D0A2FFEEE9320147E73FB295039605EA79376C00D1C60EB421D1BF2BD36A9B68A32E5F5003F0C984E1A57B3C8A261E451D912FCBF27924078BAB0879F85B78D097B2651A17AD9266B39E7AF73DAE54319B2902E0A0D11653B38EDA14B9DE8431E9382AC7EF5F1705C05239DDEA7F533234FA640D2E1EE392D23BF46D57D6FD0E167174E6242F5455DC299BB03BF2EBAEDB14539E9025B84BF66C185AD45C6B1FBF47E3C17D4A1F2C99DCA7151039D71DB7BD2E025E67C2ABB9A2DE6D9C5150651385B270511AA50E8728707B1E0920F3A83DEC0F733090CE96DCACDB93CD756AB1F572DA2BBF4908C17E905848C09CF31424833D1D4894FCB6BD93162EC74E836A523E97F35152EBA28AF63DEC47A32C09E0F0451A4D60949C8CDB07642F5A705075F4A1380B327596C319A135C9C43BBAF2D25C90030BA43FC55701B2854ABFEA710D98AFB8341E46778616A9E9B31CF11652B47A76A99F096BDB35C9CFA78E47CFC980E5E8683E1E13AA3FCA5171C07B5E27C1A5002C02643DC760431C2750A29E838F6ED5A892146D8015F5879DA988DF030BB2FA4D501FB7F0AD9A82ED3C48B70979428C39DB04116DCC8337567B6DB4A0DFE0C704B3F46983BBF092847AED87699EE88AEB27756850D008583CD37FC8521968EB1D17FC42D742B7E6756303412A3AD011DD5CE2BA1A4E3B0B2EBB68736C76B02164C41204734B731DF4C00C937CFB49D4648A7808A34E6162526240AB221071C6C2669DB4787AF7D516F4E72EF81C7D907A37634E8CEC5BF4B3502A6A05224B269B29A8E44603DB2A890F9B64BC94AEC7D2923DC52985CC18E123C7D6CC3DEF885725E0BD2D3EC0466DBE2E94350368068E5FC1CFB6BAC40F47600EB8520A8E29E855D96B556002207CA234BE3620189767ED74ABA3D1A1CF3F66864312B7502C37C9543A36F24FD38A25137128FFE4C6CC7C078AEF1F799DA7F3E3BA0E19F21A707E66EE95189BDD74EDF32E0F18052384A2A180D90545EF1B9F2710074BC8AED5F7625C0851C34E9F3AE5C57BE65862CEE2891052CC442574EBFAAE1BEC7AB63F25C80951AD65A41089DE526946D858146E446FCAD6915BD59B0D112255083A711279990F87453A6D8F7D057055217F4752F062A3B +20241203224318 2 6 100 8191 5 C3301F39F3E2DCD097FBF5454401BF52BF4745AFD35F3DEBDFB34DE2518B0F7BB10DE2FDBE6C35E1B63AA67E9FC179EB3DB8A0FA7E01618BB625B3EC326A001A253FB737B2461999BAB5A5FBCA4AFAD88A8BCBEB5990D4E25225F203B2CE75A3A1C23BFFD78E697275BDB6B6153AA3C21D2063047D44EDDF0483220CD672280D4D67C4726EA476A5C094B7E8DBE62B760EBA6B62C200D456A99E87875B4B2FFF4AA87661D89CAF8CA36D9CE00E0C3BDA443B7CCC3EA892F524AD10DD6960196EC4497E1DDC9F5C13BAED9A8F240196633AB9EC597D0A2FFEEE9320147E73FB295039605EA79376C00D1C60EB421D1BF2BD36A9B68A32E5F5003F0C984E1A57B3C8A261E451D912FCBF27924078BAB0879F85B78D097B2651A17AD9266B39E7AF73DAE54319B2902E0A0D11653B38EDA14B9DE8431E9382AC7EF5F1705C05239DDEA7F533234FA640D2E1EE392D23BF46D57D6FD0E167174E6242F5455DC299BB03BF2EBAEDB14539E9025B84BF66C185AD45C6B1FBF47E3C17D4A1F2C99DCA7151039D71DB7BD2E025E67C2ABB9A2DE6D9C5150651385B270511AA50E8728707B1E0920F3A83DEC0F733090CE96DCACDB93CD756AB1F572DA2BBF4908C17E905848C09CF31424833D1D4894FCB6BD93162EC74E836A523E97F35152EBA28AF63DEC47A32C09E0F0451A4D60949C8CDB07642F5A705075F4A1380B327596C319A135C9C43BBAF2D25C90030BA43FC55701B2854ABFEA710D98AFB8341E46778616A9E9B31CF11652B47A76A99F096BDB35C9CFA78E47CFC980E5E8683E1E13AA3FCA5171C07B5E27C1A5002C02643DC760431C2750A29E838F6ED5A892146D8015F5879DA988DF030BB2FA4D501FB7F0AD9A82ED3C48B70979428C39DB04116DCC8337567B6DB4A0DFE0C704B3F46983BBF092847AED87699EE88AEB27756850D008583CD37FC8521968EB1D17FC42D742B7E6756303412A3AD011DD5CE2BA1A4E3B0B2EBB68736C76B02164C41204734B731DF4C00C937CFB49D4648A7808A34E6162526240AB221071C6C2669DB4787AF7D516F4E72EF81C7D907A37634E8CEC5BF4B3502A6A05224B269B29A8E44603DB2A890F9B64BC94AEC7D2923DC52985CC18E123C7D6CC3DEF885725E0BD2D3EC0466DBE2E94350368068E5FC1CFB6BAC40F47600EB8520A8E29E855D96B556002207CA234BE3620189767ED74ABA3D1A1CF3F66864312B7502C37C9543A36F24FD38A25137128FFE4C6CC7C078AEF1F799DA7F3E3BA0E19F21A707E66EE95189BDD74EDF32E0F18052384A2A180D90545EF1B9F2710074BC8AED5F7625C0851C34E9F3AE5C57BE65862CEE2891052CC442574EBFAAE1BEC7AB63F25C80951AD65A41089DE526946D858146E446FCAD6915BD59B0D112255083A711279990F87453A6D8F7D057055217F4753098A4FF +20241204023709 2 6 100 8191 2 DC5E734609D91DA7E5180C89891C148715345D3A56F96DDFF41EE0B90992E9901E55850A78D9DF296A83F5AAF22675720E58E1F6D01F3B45315B818EF9CE880CE92F022763911796D4F86361BEB151ACB400BA017186C1DDCDE5F1853260ECF1082E072C2B7E2FD33E51B5076675269EC247AAE3DF3C1E6853E5D0E58FF7268255E91A9BF6FD43750F114BCA5DC70176ECACAF59C812798941D04FFFF200B53F9843066568A5EF6B324692239A9DC94383C53DA447D942BD51E17F51C22106DC3A2FC7A8942E20E5DA369D19124D184A96589E66EE15C4A8E4CB0FBB6B5E629875DEB3C6AAF622ABC4A4057E0B95533A03C94C514D2129CD6ECE739D9E3A98A54461DF577CC508BF4D5EE7FBE6178B248E3F51C59FE57BFBDE33DD833D0CF22DB22AE0F4F9F03EEF8E0E1DB0EDF7BB4C755148AD2D3FECED23DE1F028A3A6396D7F8F721D11023BD58335ADE175939E140A92C7B532A3D77168E566B7AADEA6F137A158AF3D2608FD4C1081018C1BC2B860A2830A097BDAFA96A3D5B5E1130D2C0778837C63ACBE958573B4ADAC2AE629D17728313AB9064D890006B2F0EC1869E35480B96651B9B3837B876190D5F1876A151A87C58A1CE2A9AD0744BE4CF955BFA9FA5653300FF6ECD64667ECD836D61DC3675048A8EB5AE945B50CB699F7FB4E36167515A2054199687DEC77D5117DF28B63F383403C49097F23AA4DE5857A0D865AFC7E4D0994B46386C20A41E9B41963CD425A82B30C4EE72FB3EFACD6C4090D740E44C196E51F41894FDB26142B72EF1E65A676C30EFB65C937C0F64CDEC167ECC16F0CAA3C932F3DD5C6F7A1EB073F03F2CB9F2059BE75EBAE32FA3170B5FA93D69CAB8275935686242E1F43ED23FE8784A0AD694442D35193DAAF5F7DA49B267B716C38F36C92AE7986DF8126904B11EA74323F3AB3AF436D64AC41996529AB95876EE4DF3739130460A50E2EC8463F2306454F08745CE40938858B6237A5D38B33FD6541BB98EFB39A7B0B501B7943FF594DF0964BF535CBD35105E35BA14C40E62D57F3B110AE82CD7F9FF73C3A28740C8EB397494F6D7CF5F0F147385424D70B276C6AD849E56C9985115EAF2CCF3D3A6C828F2A303178EC48BB08F36AF3800739E841F7B758FF06EFA10F6467E98DA4B1B302EFED0EF5A7D3AD74100E41C168ACBBF10EC5FFC497B43409D02D942C144408C32C83ED49334BC48FD1D446FDEBB71CA1F9276F3180ECA057E4B8F19FAFE368D0097EE2A5736D72BE661382939491A244B068D26A071E55E25DF2C8706ADEFD8245BC97A691AB57A8D39CE24469E9CC69198F4F795CACCB45053F464CA0C2F04C71E9CD6BB6D378E917C413B7FADEACD41A7A43E9A1FC04576658DBF7420A35252A899B51F9ED9B2D0B5534A696C2465C950EF5880636D96CC963AF6C314D00834969C4569DF3BDB +20241204025228 2 6 100 8191 5 DC5E734609D91DA7E5180C89891C148715345D3A56F96DDFF41EE0B90992E9901E55850A78D9DF296A83F5AAF22675720E58E1F6D01F3B45315B818EF9CE880CE92F022763911796D4F86361BEB151ACB400BA017186C1DDCDE5F1853260ECF1082E072C2B7E2FD33E51B5076675269EC247AAE3DF3C1E6853E5D0E58FF7268255E91A9BF6FD43750F114BCA5DC70176ECACAF59C812798941D04FFFF200B53F9843066568A5EF6B324692239A9DC94383C53DA447D942BD51E17F51C22106DC3A2FC7A8942E20E5DA369D19124D184A96589E66EE15C4A8E4CB0FBB6B5E629875DEB3C6AAF622ABC4A4057E0B95533A03C94C514D2129CD6ECE739D9E3A98A54461DF577CC508BF4D5EE7FBE6178B248E3F51C59FE57BFBDE33DD833D0CF22DB22AE0F4F9F03EEF8E0E1DB0EDF7BB4C755148AD2D3FECED23DE1F028A3A6396D7F8F721D11023BD58335ADE175939E140A92C7B532A3D77168E566B7AADEA6F137A158AF3D2608FD4C1081018C1BC2B860A2830A097BDAFA96A3D5B5E1130D2C0778837C63ACBE958573B4ADAC2AE629D17728313AB9064D890006B2F0EC1869E35480B96651B9B3837B876190D5F1876A151A87C58A1CE2A9AD0744BE4CF955BFA9FA5653300FF6ECD64667ECD836D61DC3675048A8EB5AE945B50CB699F7FB4E36167515A2054199687DEC77D5117DF28B63F383403C49097F23AA4DE5857A0D865AFC7E4D0994B46386C20A41E9B41963CD425A82B30C4EE72FB3EFACD6C4090D740E44C196E51F41894FDB26142B72EF1E65A676C30EFB65C937C0F64CDEC167ECC16F0CAA3C932F3DD5C6F7A1EB073F03F2CB9F2059BE75EBAE32FA3170B5FA93D69CAB8275935686242E1F43ED23FE8784A0AD694442D35193DAAF5F7DA49B267B716C38F36C92AE7986DF8126904B11EA74323F3AB3AF436D64AC41996529AB95876EE4DF3739130460A50E2EC8463F2306454F08745CE40938858B6237A5D38B33FD6541BB98EFB39A7B0B501B7943FF594DF0964BF535CBD35105E35BA14C40E62D57F3B110AE82CD7F9FF73C3A28740C8EB397494F6D7CF5F0F147385424D70B276C6AD849E56C9985115EAF2CCF3D3A6C828F2A303178EC48BB08F36AF3800739E841F7B758FF06EFA10F6467E98DA4B1B302EFED0EF5A7D3AD74100E41C168ACBBF10EC5FFC497B43409D02D942C144408C32C83ED49334BC48FD1D446FDEBB71CA1F9276F3180ECA057E4B8F19FAFE368D0097EE2A5736D72BE661382939491A244B068D26A071E55E25DF2C8706ADEFD8245BC97A691AB57A8D39CE24469E9CC69198F4F795CACCB45053F464CA0C2F04C71E9CD6BB6D378E917C413B7FADEACD41A7A43E9A1FC04576658DBF7420A35252A899B51F9ED9B2D0B5534A696C2465C950EF5880636D96CC963AF6C314D00834969C456AB453E7 +20241204030908 2 6 100 8191 5 DC5E734609D91DA7E5180C89891C148715345D3A56F96DDFF41EE0B90992E9901E55850A78D9DF296A83F5AAF22675720E58E1F6D01F3B45315B818EF9CE880CE92F022763911796D4F86361BEB151ACB400BA017186C1DDCDE5F1853260ECF1082E072C2B7E2FD33E51B5076675269EC247AAE3DF3C1E6853E5D0E58FF7268255E91A9BF6FD43750F114BCA5DC70176ECACAF59C812798941D04FFFF200B53F9843066568A5EF6B324692239A9DC94383C53DA447D942BD51E17F51C22106DC3A2FC7A8942E20E5DA369D19124D184A96589E66EE15C4A8E4CB0FBB6B5E629875DEB3C6AAF622ABC4A4057E0B95533A03C94C514D2129CD6ECE739D9E3A98A54461DF577CC508BF4D5EE7FBE6178B248E3F51C59FE57BFBDE33DD833D0CF22DB22AE0F4F9F03EEF8E0E1DB0EDF7BB4C755148AD2D3FECED23DE1F028A3A6396D7F8F721D11023BD58335ADE175939E140A92C7B532A3D77168E566B7AADEA6F137A158AF3D2608FD4C1081018C1BC2B860A2830A097BDAFA96A3D5B5E1130D2C0778837C63ACBE958573B4ADAC2AE629D17728313AB9064D890006B2F0EC1869E35480B96651B9B3837B876190D5F1876A151A87C58A1CE2A9AD0744BE4CF955BFA9FA5653300FF6ECD64667ECD836D61DC3675048A8EB5AE945B50CB699F7FB4E36167515A2054199687DEC77D5117DF28B63F383403C49097F23AA4DE5857A0D865AFC7E4D0994B46386C20A41E9B41963CD425A82B30C4EE72FB3EFACD6C4090D740E44C196E51F41894FDB26142B72EF1E65A676C30EFB65C937C0F64CDEC167ECC16F0CAA3C932F3DD5C6F7A1EB073F03F2CB9F2059BE75EBAE32FA3170B5FA93D69CAB8275935686242E1F43ED23FE8784A0AD694442D35193DAAF5F7DA49B267B716C38F36C92AE7986DF8126904B11EA74323F3AB3AF436D64AC41996529AB95876EE4DF3739130460A50E2EC8463F2306454F08745CE40938858B6237A5D38B33FD6541BB98EFB39A7B0B501B7943FF594DF0964BF535CBD35105E35BA14C40E62D57F3B110AE82CD7F9FF73C3A28740C8EB397494F6D7CF5F0F147385424D70B276C6AD849E56C9985115EAF2CCF3D3A6C828F2A303178EC48BB08F36AF3800739E841F7B758FF06EFA10F6467E98DA4B1B302EFED0EF5A7D3AD74100E41C168ACBBF10EC5FFC497B43409D02D942C144408C32C83ED49334BC48FD1D446FDEBB71CA1F9276F3180ECA057E4B8F19FAFE368D0097EE2A5736D72BE661382939491A244B068D26A071E55E25DF2C8706ADEFD8245BC97A691AB57A8D39CE24469E9CC69198F4F795CACCB45053F464CA0C2F04C71E9CD6BB6D378E917C413B7FADEACD41A7A43E9A1FC04576658DBF7420A35252A899B51F9ED9B2D0B5534A696C2465C950EF5880636D96CC963AF6C314D00834969C456B95242F +20241204033647 2 6 100 8191 5 DC5E734609D91DA7E5180C89891C148715345D3A56F96DDFF41EE0B90992E9901E55850A78D9DF296A83F5AAF22675720E58E1F6D01F3B45315B818EF9CE880CE92F022763911796D4F86361BEB151ACB400BA017186C1DDCDE5F1853260ECF1082E072C2B7E2FD33E51B5076675269EC247AAE3DF3C1E6853E5D0E58FF7268255E91A9BF6FD43750F114BCA5DC70176ECACAF59C812798941D04FFFF200B53F9843066568A5EF6B324692239A9DC94383C53DA447D942BD51E17F51C22106DC3A2FC7A8942E20E5DA369D19124D184A96589E66EE15C4A8E4CB0FBB6B5E629875DEB3C6AAF622ABC4A4057E0B95533A03C94C514D2129CD6ECE739D9E3A98A54461DF577CC508BF4D5EE7FBE6178B248E3F51C59FE57BFBDE33DD833D0CF22DB22AE0F4F9F03EEF8E0E1DB0EDF7BB4C755148AD2D3FECED23DE1F028A3A6396D7F8F721D11023BD58335ADE175939E140A92C7B532A3D77168E566B7AADEA6F137A158AF3D2608FD4C1081018C1BC2B860A2830A097BDAFA96A3D5B5E1130D2C0778837C63ACBE958573B4ADAC2AE629D17728313AB9064D890006B2F0EC1869E35480B96651B9B3837B876190D5F1876A151A87C58A1CE2A9AD0744BE4CF955BFA9FA5653300FF6ECD64667ECD836D61DC3675048A8EB5AE945B50CB699F7FB4E36167515A2054199687DEC77D5117DF28B63F383403C49097F23AA4DE5857A0D865AFC7E4D0994B46386C20A41E9B41963CD425A82B30C4EE72FB3EFACD6C4090D740E44C196E51F41894FDB26142B72EF1E65A676C30EFB65C937C0F64CDEC167ECC16F0CAA3C932F3DD5C6F7A1EB073F03F2CB9F2059BE75EBAE32FA3170B5FA93D69CAB8275935686242E1F43ED23FE8784A0AD694442D35193DAAF5F7DA49B267B716C38F36C92AE7986DF8126904B11EA74323F3AB3AF436D64AC41996529AB95876EE4DF3739130460A50E2EC8463F2306454F08745CE40938858B6237A5D38B33FD6541BB98EFB39A7B0B501B7943FF594DF0964BF535CBD35105E35BA14C40E62D57F3B110AE82CD7F9FF73C3A28740C8EB397494F6D7CF5F0F147385424D70B276C6AD849E56C9985115EAF2CCF3D3A6C828F2A303178EC48BB08F36AF3800739E841F7B758FF06EFA10F6467E98DA4B1B302EFED0EF5A7D3AD74100E41C168ACBBF10EC5FFC497B43409D02D942C144408C32C83ED49334BC48FD1D446FDEBB71CA1F9276F3180ECA057E4B8F19FAFE368D0097EE2A5736D72BE661382939491A244B068D26A071E55E25DF2C8706ADEFD8245BC97A691AB57A8D39CE24469E9CC69198F4F795CACCB45053F464CA0C2F04C71E9CD6BB6D378E917C413B7FADEACD41A7A43E9A1FC04576658DBF7420A35252A899B51F9ED9B2D0B5534A696C2465C950EF5880636D96CC963AF6C314D00834969C456D1E7FC7 +20241204055147 2 6 100 8191 5 DC5E734609D91DA7E5180C89891C148715345D3A56F96DDFF41EE0B90992E9901E55850A78D9DF296A83F5AAF22675720E58E1F6D01F3B45315B818EF9CE880CE92F022763911796D4F86361BEB151ACB400BA017186C1DDCDE5F1853260ECF1082E072C2B7E2FD33E51B5076675269EC247AAE3DF3C1E6853E5D0E58FF7268255E91A9BF6FD43750F114BCA5DC70176ECACAF59C812798941D04FFFF200B53F9843066568A5EF6B324692239A9DC94383C53DA447D942BD51E17F51C22106DC3A2FC7A8942E20E5DA369D19124D184A96589E66EE15C4A8E4CB0FBB6B5E629875DEB3C6AAF622ABC4A4057E0B95533A03C94C514D2129CD6ECE739D9E3A98A54461DF577CC508BF4D5EE7FBE6178B248E3F51C59FE57BFBDE33DD833D0CF22DB22AE0F4F9F03EEF8E0E1DB0EDF7BB4C755148AD2D3FECED23DE1F028A3A6396D7F8F721D11023BD58335ADE175939E140A92C7B532A3D77168E566B7AADEA6F137A158AF3D2608FD4C1081018C1BC2B860A2830A097BDAFA96A3D5B5E1130D2C0778837C63ACBE958573B4ADAC2AE629D17728313AB9064D890006B2F0EC1869E35480B96651B9B3837B876190D5F1876A151A87C58A1CE2A9AD0744BE4CF955BFA9FA5653300FF6ECD64667ECD836D61DC3675048A8EB5AE945B50CB699F7FB4E36167515A2054199687DEC77D5117DF28B63F383403C49097F23AA4DE5857A0D865AFC7E4D0994B46386C20A41E9B41963CD425A82B30C4EE72FB3EFACD6C4090D740E44C196E51F41894FDB26142B72EF1E65A676C30EFB65C937C0F64CDEC167ECC16F0CAA3C932F3DD5C6F7A1EB073F03F2CB9F2059BE75EBAE32FA3170B5FA93D69CAB8275935686242E1F43ED23FE8784A0AD694442D35193DAAF5F7DA49B267B716C38F36C92AE7986DF8126904B11EA74323F3AB3AF436D64AC41996529AB95876EE4DF3739130460A50E2EC8463F2306454F08745CE40938858B6237A5D38B33FD6541BB98EFB39A7B0B501B7943FF594DF0964BF535CBD35105E35BA14C40E62D57F3B110AE82CD7F9FF73C3A28740C8EB397494F6D7CF5F0F147385424D70B276C6AD849E56C9985115EAF2CCF3D3A6C828F2A303178EC48BB08F36AF3800739E841F7B758FF06EFA10F6467E98DA4B1B302EFED0EF5A7D3AD74100E41C168ACBBF10EC5FFC497B43409D02D942C144408C32C83ED49334BC48FD1D446FDEBB71CA1F9276F3180ECA057E4B8F19FAFE368D0097EE2A5736D72BE661382939491A244B068D26A071E55E25DF2C8706ADEFD8245BC97A691AB57A8D39CE24469E9CC69198F4F795CACCB45053F464CA0C2F04C71E9CD6BB6D378E917C413B7FADEACD41A7A43E9A1FC04576658DBF7420A35252A899B51F9ED9B2D0B5534A696C2465C950EF5880636D96CC963AF6C314D00834969C45749787B7 +20241204060833 2 6 100 8191 2 DC5E734609D91DA7E5180C89891C148715345D3A56F96DDFF41EE0B90992E9901E55850A78D9DF296A83F5AAF22675720E58E1F6D01F3B45315B818EF9CE880CE92F022763911796D4F86361BEB151ACB400BA017186C1DDCDE5F1853260ECF1082E072C2B7E2FD33E51B5076675269EC247AAE3DF3C1E6853E5D0E58FF7268255E91A9BF6FD43750F114BCA5DC70176ECACAF59C812798941D04FFFF200B53F9843066568A5EF6B324692239A9DC94383C53DA447D942BD51E17F51C22106DC3A2FC7A8942E20E5DA369D19124D184A96589E66EE15C4A8E4CB0FBB6B5E629875DEB3C6AAF622ABC4A4057E0B95533A03C94C514D2129CD6ECE739D9E3A98A54461DF577CC508BF4D5EE7FBE6178B248E3F51C59FE57BFBDE33DD833D0CF22DB22AE0F4F9F03EEF8E0E1DB0EDF7BB4C755148AD2D3FECED23DE1F028A3A6396D7F8F721D11023BD58335ADE175939E140A92C7B532A3D77168E566B7AADEA6F137A158AF3D2608FD4C1081018C1BC2B860A2830A097BDAFA96A3D5B5E1130D2C0778837C63ACBE958573B4ADAC2AE629D17728313AB9064D890006B2F0EC1869E35480B96651B9B3837B876190D5F1876A151A87C58A1CE2A9AD0744BE4CF955BFA9FA5653300FF6ECD64667ECD836D61DC3675048A8EB5AE945B50CB699F7FB4E36167515A2054199687DEC77D5117DF28B63F383403C49097F23AA4DE5857A0D865AFC7E4D0994B46386C20A41E9B41963CD425A82B30C4EE72FB3EFACD6C4090D740E44C196E51F41894FDB26142B72EF1E65A676C30EFB65C937C0F64CDEC167ECC16F0CAA3C932F3DD5C6F7A1EB073F03F2CB9F2059BE75EBAE32FA3170B5FA93D69CAB8275935686242E1F43ED23FE8784A0AD694442D35193DAAF5F7DA49B267B716C38F36C92AE7986DF8126904B11EA74323F3AB3AF436D64AC41996529AB95876EE4DF3739130460A50E2EC8463F2306454F08745CE40938858B6237A5D38B33FD6541BB98EFB39A7B0B501B7943FF594DF0964BF535CBD35105E35BA14C40E62D57F3B110AE82CD7F9FF73C3A28740C8EB397494F6D7CF5F0F147385424D70B276C6AD849E56C9985115EAF2CCF3D3A6C828F2A303178EC48BB08F36AF3800739E841F7B758FF06EFA10F6467E98DA4B1B302EFED0EF5A7D3AD74100E41C168ACBBF10EC5FFC497B43409D02D942C144408C32C83ED49334BC48FD1D446FDEBB71CA1F9276F3180ECA057E4B8F19FAFE368D0097EE2A5736D72BE661382939491A244B068D26A071E55E25DF2C8706ADEFD8245BC97A691AB57A8D39CE24469E9CC69198F4F795CACCB45053F464CA0C2F04C71E9CD6BB6D378E917C413B7FADEACD41A7A43E9A1FC04576658DBF7420A35252A899B51F9ED9B2D0B5534A696C2465C950EF5880636D96CC963AF6C314D00834969C45757D2FFB +20241204064719 2 6 100 8191 2 DC5E734609D91DA7E5180C89891C148715345D3A56F96DDFF41EE0B90992E9901E55850A78D9DF296A83F5AAF22675720E58E1F6D01F3B45315B818EF9CE880CE92F022763911796D4F86361BEB151ACB400BA017186C1DDCDE5F1853260ECF1082E072C2B7E2FD33E51B5076675269EC247AAE3DF3C1E6853E5D0E58FF7268255E91A9BF6FD43750F114BCA5DC70176ECACAF59C812798941D04FFFF200B53F9843066568A5EF6B324692239A9DC94383C53DA447D942BD51E17F51C22106DC3A2FC7A8942E20E5DA369D19124D184A96589E66EE15C4A8E4CB0FBB6B5E629875DEB3C6AAF622ABC4A4057E0B95533A03C94C514D2129CD6ECE739D9E3A98A54461DF577CC508BF4D5EE7FBE6178B248E3F51C59FE57BFBDE33DD833D0CF22DB22AE0F4F9F03EEF8E0E1DB0EDF7BB4C755148AD2D3FECED23DE1F028A3A6396D7F8F721D11023BD58335ADE175939E140A92C7B532A3D77168E566B7AADEA6F137A158AF3D2608FD4C1081018C1BC2B860A2830A097BDAFA96A3D5B5E1130D2C0778837C63ACBE958573B4ADAC2AE629D17728313AB9064D890006B2F0EC1869E35480B96651B9B3837B876190D5F1876A151A87C58A1CE2A9AD0744BE4CF955BFA9FA5653300FF6ECD64667ECD836D61DC3675048A8EB5AE945B50CB699F7FB4E36167515A2054199687DEC77D5117DF28B63F383403C49097F23AA4DE5857A0D865AFC7E4D0994B46386C20A41E9B41963CD425A82B30C4EE72FB3EFACD6C4090D740E44C196E51F41894FDB26142B72EF1E65A676C30EFB65C937C0F64CDEC167ECC16F0CAA3C932F3DD5C6F7A1EB073F03F2CB9F2059BE75EBAE32FA3170B5FA93D69CAB8275935686242E1F43ED23FE8784A0AD694442D35193DAAF5F7DA49B267B716C38F36C92AE7986DF8126904B11EA74323F3AB3AF436D64AC41996529AB95876EE4DF3739130460A50E2EC8463F2306454F08745CE40938858B6237A5D38B33FD6541BB98EFB39A7B0B501B7943FF594DF0964BF535CBD35105E35BA14C40E62D57F3B110AE82CD7F9FF73C3A28740C8EB397494F6D7CF5F0F147385424D70B276C6AD849E56C9985115EAF2CCF3D3A6C828F2A303178EC48BB08F36AF3800739E841F7B758FF06EFA10F6467E98DA4B1B302EFED0EF5A7D3AD74100E41C168ACBBF10EC5FFC497B43409D02D942C144408C32C83ED49334BC48FD1D446FDEBB71CA1F9276F3180ECA057E4B8F19FAFE368D0097EE2A5736D72BE661382939491A244B068D26A071E55E25DF2C8706ADEFD8245BC97A691AB57A8D39CE24469E9CC69198F4F795CACCB45053F464CA0C2F04C71E9CD6BB6D378E917C413B7FADEACD41A7A43E9A1FC04576658DBF7420A35252A899B51F9ED9B2D0B5534A696C2465C950EF5880636D96CC963AF6C314D00834969C45779594EB +20241204075858 2 6 100 8191 2 DC5E734609D91DA7E5180C89891C148715345D3A56F96DDFF41EE0B90992E9901E55850A78D9DF296A83F5AAF22675720E58E1F6D01F3B45315B818EF9CE880CE92F022763911796D4F86361BEB151ACB400BA017186C1DDCDE5F1853260ECF1082E072C2B7E2FD33E51B5076675269EC247AAE3DF3C1E6853E5D0E58FF7268255E91A9BF6FD43750F114BCA5DC70176ECACAF59C812798941D04FFFF200B53F9843066568A5EF6B324692239A9DC94383C53DA447D942BD51E17F51C22106DC3A2FC7A8942E20E5DA369D19124D184A96589E66EE15C4A8E4CB0FBB6B5E629875DEB3C6AAF622ABC4A4057E0B95533A03C94C514D2129CD6ECE739D9E3A98A54461DF577CC508BF4D5EE7FBE6178B248E3F51C59FE57BFBDE33DD833D0CF22DB22AE0F4F9F03EEF8E0E1DB0EDF7BB4C755148AD2D3FECED23DE1F028A3A6396D7F8F721D11023BD58335ADE175939E140A92C7B532A3D77168E566B7AADEA6F137A158AF3D2608FD4C1081018C1BC2B860A2830A097BDAFA96A3D5B5E1130D2C0778837C63ACBE958573B4ADAC2AE629D17728313AB9064D890006B2F0EC1869E35480B96651B9B3837B876190D5F1876A151A87C58A1CE2A9AD0744BE4CF955BFA9FA5653300FF6ECD64667ECD836D61DC3675048A8EB5AE945B50CB699F7FB4E36167515A2054199687DEC77D5117DF28B63F383403C49097F23AA4DE5857A0D865AFC7E4D0994B46386C20A41E9B41963CD425A82B30C4EE72FB3EFACD6C4090D740E44C196E51F41894FDB26142B72EF1E65A676C30EFB65C937C0F64CDEC167ECC16F0CAA3C932F3DD5C6F7A1EB073F03F2CB9F2059BE75EBAE32FA3170B5FA93D69CAB8275935686242E1F43ED23FE8784A0AD694442D35193DAAF5F7DA49B267B716C38F36C92AE7986DF8126904B11EA74323F3AB3AF436D64AC41996529AB95876EE4DF3739130460A50E2EC8463F2306454F08745CE40938858B6237A5D38B33FD6541BB98EFB39A7B0B501B7943FF594DF0964BF535CBD35105E35BA14C40E62D57F3B110AE82CD7F9FF73C3A28740C8EB397494F6D7CF5F0F147385424D70B276C6AD849E56C9985115EAF2CCF3D3A6C828F2A303178EC48BB08F36AF3800739E841F7B758FF06EFA10F6467E98DA4B1B302EFED0EF5A7D3AD74100E41C168ACBBF10EC5FFC497B43409D02D942C144408C32C83ED49334BC48FD1D446FDEBB71CA1F9276F3180ECA057E4B8F19FAFE368D0097EE2A5736D72BE661382939491A244B068D26A071E55E25DF2C8706ADEFD8245BC97A691AB57A8D39CE24469E9CC69198F4F795CACCB45053F464CA0C2F04C71E9CD6BB6D378E917C413B7FADEACD41A7A43E9A1FC04576658DBF7420A35252A899B51F9ED9B2D0B5534A696C2465C950EF5880636D96CC963AF6C314D00834969C457B89C8B3 +20241204095845 2 6 100 8191 5 DC5E734609D91DA7E5180C89891C148715345D3A56F96DDFF41EE0B90992E9901E55850A78D9DF296A83F5AAF22675720E58E1F6D01F3B45315B818EF9CE880CE92F022763911796D4F86361BEB151ACB400BA017186C1DDCDE5F1853260ECF1082E072C2B7E2FD33E51B5076675269EC247AAE3DF3C1E6853E5D0E58FF7268255E91A9BF6FD43750F114BCA5DC70176ECACAF59C812798941D04FFFF200B53F9843066568A5EF6B324692239A9DC94383C53DA447D942BD51E17F51C22106DC3A2FC7A8942E20E5DA369D19124D184A96589E66EE15C4A8E4CB0FBB6B5E629875DEB3C6AAF622ABC4A4057E0B95533A03C94C514D2129CD6ECE739D9E3A98A54461DF577CC508BF4D5EE7FBE6178B248E3F51C59FE57BFBDE33DD833D0CF22DB22AE0F4F9F03EEF8E0E1DB0EDF7BB4C755148AD2D3FECED23DE1F028A3A6396D7F8F721D11023BD58335ADE175939E140A92C7B532A3D77168E566B7AADEA6F137A158AF3D2608FD4C1081018C1BC2B860A2830A097BDAFA96A3D5B5E1130D2C0778837C63ACBE958573B4ADAC2AE629D17728313AB9064D890006B2F0EC1869E35480B96651B9B3837B876190D5F1876A151A87C58A1CE2A9AD0744BE4CF955BFA9FA5653300FF6ECD64667ECD836D61DC3675048A8EB5AE945B50CB699F7FB4E36167515A2054199687DEC77D5117DF28B63F383403C49097F23AA4DE5857A0D865AFC7E4D0994B46386C20A41E9B41963CD425A82B30C4EE72FB3EFACD6C4090D740E44C196E51F41894FDB26142B72EF1E65A676C30EFB65C937C0F64CDEC167ECC16F0CAA3C932F3DD5C6F7A1EB073F03F2CB9F2059BE75EBAE32FA3170B5FA93D69CAB8275935686242E1F43ED23FE8784A0AD694442D35193DAAF5F7DA49B267B716C38F36C92AE7986DF8126904B11EA74323F3AB3AF436D64AC41996529AB95876EE4DF3739130460A50E2EC8463F2306454F08745CE40938858B6237A5D38B33FD6541BB98EFB39A7B0B501B7943FF594DF0964BF535CBD35105E35BA14C40E62D57F3B110AE82CD7F9FF73C3A28740C8EB397494F6D7CF5F0F147385424D70B276C6AD849E56C9985115EAF2CCF3D3A6C828F2A303178EC48BB08F36AF3800739E841F7B758FF06EFA10F6467E98DA4B1B302EFED0EF5A7D3AD74100E41C168ACBBF10EC5FFC497B43409D02D942C144408C32C83ED49334BC48FD1D446FDEBB71CA1F9276F3180ECA057E4B8F19FAFE368D0097EE2A5736D72BE661382939491A244B068D26A071E55E25DF2C8706ADEFD8245BC97A691AB57A8D39CE24469E9CC69198F4F795CACCB45053F464CA0C2F04C71E9CD6BB6D378E917C413B7FADEACD41A7A43E9A1FC04576658DBF7420A35252A899B51F9ED9B2D0B5534A696C2465C950EF5880636D96CC963AF6C314D00834969C4582223CAF +20241204102632 2 6 100 8191 2 DC5E734609D91DA7E5180C89891C148715345D3A56F96DDFF41EE0B90992E9901E55850A78D9DF296A83F5AAF22675720E58E1F6D01F3B45315B818EF9CE880CE92F022763911796D4F86361BEB151ACB400BA017186C1DDCDE5F1853260ECF1082E072C2B7E2FD33E51B5076675269EC247AAE3DF3C1E6853E5D0E58FF7268255E91A9BF6FD43750F114BCA5DC70176ECACAF59C812798941D04FFFF200B53F9843066568A5EF6B324692239A9DC94383C53DA447D942BD51E17F51C22106DC3A2FC7A8942E20E5DA369D19124D184A96589E66EE15C4A8E4CB0FBB6B5E629875DEB3C6AAF622ABC4A4057E0B95533A03C94C514D2129CD6ECE739D9E3A98A54461DF577CC508BF4D5EE7FBE6178B248E3F51C59FE57BFBDE33DD833D0CF22DB22AE0F4F9F03EEF8E0E1DB0EDF7BB4C755148AD2D3FECED23DE1F028A3A6396D7F8F721D11023BD58335ADE175939E140A92C7B532A3D77168E566B7AADEA6F137A158AF3D2608FD4C1081018C1BC2B860A2830A097BDAFA96A3D5B5E1130D2C0778837C63ACBE958573B4ADAC2AE629D17728313AB9064D890006B2F0EC1869E35480B96651B9B3837B876190D5F1876A151A87C58A1CE2A9AD0744BE4CF955BFA9FA5653300FF6ECD64667ECD836D61DC3675048A8EB5AE945B50CB699F7FB4E36167515A2054199687DEC77D5117DF28B63F383403C49097F23AA4DE5857A0D865AFC7E4D0994B46386C20A41E9B41963CD425A82B30C4EE72FB3EFACD6C4090D740E44C196E51F41894FDB26142B72EF1E65A676C30EFB65C937C0F64CDEC167ECC16F0CAA3C932F3DD5C6F7A1EB073F03F2CB9F2059BE75EBAE32FA3170B5FA93D69CAB8275935686242E1F43ED23FE8784A0AD694442D35193DAAF5F7DA49B267B716C38F36C92AE7986DF8126904B11EA74323F3AB3AF436D64AC41996529AB95876EE4DF3739130460A50E2EC8463F2306454F08745CE40938858B6237A5D38B33FD6541BB98EFB39A7B0B501B7943FF594DF0964BF535CBD35105E35BA14C40E62D57F3B110AE82CD7F9FF73C3A28740C8EB397494F6D7CF5F0F147385424D70B276C6AD849E56C9985115EAF2CCF3D3A6C828F2A303178EC48BB08F36AF3800739E841F7B758FF06EFA10F6467E98DA4B1B302EFED0EF5A7D3AD74100E41C168ACBBF10EC5FFC497B43409D02D942C144408C32C83ED49334BC48FD1D446FDEBB71CA1F9276F3180ECA057E4B8F19FAFE368D0097EE2A5736D72BE661382939491A244B068D26A071E55E25DF2C8706ADEFD8245BC97A691AB57A8D39CE24469E9CC69198F4F795CACCB45053F464CA0C2F04C71E9CD6BB6D378E917C413B7FADEACD41A7A43E9A1FC04576658DBF7420A35252A899B51F9ED9B2D0B5534A696C2465C950EF5880636D96CC963AF6C314D00834969C4583A5E7A3 +20241204133310 2 6 100 8191 5 DC5E734609D91DA7E5180C89891C148715345D3A56F96DDFF41EE0B90992E9901E55850A78D9DF296A83F5AAF22675720E58E1F6D01F3B45315B818EF9CE880CE92F022763911796D4F86361BEB151ACB400BA017186C1DDCDE5F1853260ECF1082E072C2B7E2FD33E51B5076675269EC247AAE3DF3C1E6853E5D0E58FF7268255E91A9BF6FD43750F114BCA5DC70176ECACAF59C812798941D04FFFF200B53F9843066568A5EF6B324692239A9DC94383C53DA447D942BD51E17F51C22106DC3A2FC7A8942E20E5DA369D19124D184A96589E66EE15C4A8E4CB0FBB6B5E629875DEB3C6AAF622ABC4A4057E0B95533A03C94C514D2129CD6ECE739D9E3A98A54461DF577CC508BF4D5EE7FBE6178B248E3F51C59FE57BFBDE33DD833D0CF22DB22AE0F4F9F03EEF8E0E1DB0EDF7BB4C755148AD2D3FECED23DE1F028A3A6396D7F8F721D11023BD58335ADE175939E140A92C7B532A3D77168E566B7AADEA6F137A158AF3D2608FD4C1081018C1BC2B860A2830A097BDAFA96A3D5B5E1130D2C0778837C63ACBE958573B4ADAC2AE629D17728313AB9064D890006B2F0EC1869E35480B96651B9B3837B876190D5F1876A151A87C58A1CE2A9AD0744BE4CF955BFA9FA5653300FF6ECD64667ECD836D61DC3675048A8EB5AE945B50CB699F7FB4E36167515A2054199687DEC77D5117DF28B63F383403C49097F23AA4DE5857A0D865AFC7E4D0994B46386C20A41E9B41963CD425A82B30C4EE72FB3EFACD6C4090D740E44C196E51F41894FDB26142B72EF1E65A676C30EFB65C937C0F64CDEC167ECC16F0CAA3C932F3DD5C6F7A1EB073F03F2CB9F2059BE75EBAE32FA3170B5FA93D69CAB8275935686242E1F43ED23FE8784A0AD694442D35193DAAF5F7DA49B267B716C38F36C92AE7986DF8126904B11EA74323F3AB3AF436D64AC41996529AB95876EE4DF3739130460A50E2EC8463F2306454F08745CE40938858B6237A5D38B33FD6541BB98EFB39A7B0B501B7943FF594DF0964BF535CBD35105E35BA14C40E62D57F3B110AE82CD7F9FF73C3A28740C8EB397494F6D7CF5F0F147385424D70B276C6AD849E56C9985115EAF2CCF3D3A6C828F2A303178EC48BB08F36AF3800739E841F7B758FF06EFA10F6467E98DA4B1B302EFED0EF5A7D3AD74100E41C168ACBBF10EC5FFC497B43409D02D942C144408C32C83ED49334BC48FD1D446FDEBB71CA1F9276F3180ECA057E4B8F19FAFE368D0097EE2A5736D72BE661382939491A244B068D26A071E55E25DF2C8706ADEFD8245BC97A691AB57A8D39CE24469E9CC69198F4F795CACCB45053F464CA0C2F04C71E9CD6BB6D378E917C413B7FADEACD41A7A43E9A1FC04576658DBF7420A35252A899B51F9ED9B2D0B5534A696C2465C950EF5880636D96CC963AF6C314D00834969C458E07A8DF +20241204134006 2 6 100 8191 2 DC5E734609D91DA7E5180C89891C148715345D3A56F96DDFF41EE0B90992E9901E55850A78D9DF296A83F5AAF22675720E58E1F6D01F3B45315B818EF9CE880CE92F022763911796D4F86361BEB151ACB400BA017186C1DDCDE5F1853260ECF1082E072C2B7E2FD33E51B5076675269EC247AAE3DF3C1E6853E5D0E58FF7268255E91A9BF6FD43750F114BCA5DC70176ECACAF59C812798941D04FFFF200B53F9843066568A5EF6B324692239A9DC94383C53DA447D942BD51E17F51C22106DC3A2FC7A8942E20E5DA369D19124D184A96589E66EE15C4A8E4CB0FBB6B5E629875DEB3C6AAF622ABC4A4057E0B95533A03C94C514D2129CD6ECE739D9E3A98A54461DF577CC508BF4D5EE7FBE6178B248E3F51C59FE57BFBDE33DD833D0CF22DB22AE0F4F9F03EEF8E0E1DB0EDF7BB4C755148AD2D3FECED23DE1F028A3A6396D7F8F721D11023BD58335ADE175939E140A92C7B532A3D77168E566B7AADEA6F137A158AF3D2608FD4C1081018C1BC2B860A2830A097BDAFA96A3D5B5E1130D2C0778837C63ACBE958573B4ADAC2AE629D17728313AB9064D890006B2F0EC1869E35480B96651B9B3837B876190D5F1876A151A87C58A1CE2A9AD0744BE4CF955BFA9FA5653300FF6ECD64667ECD836D61DC3675048A8EB5AE945B50CB699F7FB4E36167515A2054199687DEC77D5117DF28B63F383403C49097F23AA4DE5857A0D865AFC7E4D0994B46386C20A41E9B41963CD425A82B30C4EE72FB3EFACD6C4090D740E44C196E51F41894FDB26142B72EF1E65A676C30EFB65C937C0F64CDEC167ECC16F0CAA3C932F3DD5C6F7A1EB073F03F2CB9F2059BE75EBAE32FA3170B5FA93D69CAB8275935686242E1F43ED23FE8784A0AD694442D35193DAAF5F7DA49B267B716C38F36C92AE7986DF8126904B11EA74323F3AB3AF436D64AC41996529AB95876EE4DF3739130460A50E2EC8463F2306454F08745CE40938858B6237A5D38B33FD6541BB98EFB39A7B0B501B7943FF594DF0964BF535CBD35105E35BA14C40E62D57F3B110AE82CD7F9FF73C3A28740C8EB397494F6D7CF5F0F147385424D70B276C6AD849E56C9985115EAF2CCF3D3A6C828F2A303178EC48BB08F36AF3800739E841F7B758FF06EFA10F6467E98DA4B1B302EFED0EF5A7D3AD74100E41C168ACBBF10EC5FFC497B43409D02D942C144408C32C83ED49334BC48FD1D446FDEBB71CA1F9276F3180ECA057E4B8F19FAFE368D0097EE2A5736D72BE661382939491A244B068D26A071E55E25DF2C8706ADEFD8245BC97A691AB57A8D39CE24469E9CC69198F4F795CACCB45053F464CA0C2F04C71E9CD6BB6D378E917C413B7FADEACD41A7A43E9A1FC04576658DBF7420A35252A899B51F9ED9B2D0B5534A696C2465C950EF5880636D96CC963AF6C314D00834969C458E603BF3 +20241204153923 2 6 100 8191 5 DC5E734609D91DA7E5180C89891C148715345D3A56F96DDFF41EE0B90992E9901E55850A78D9DF296A83F5AAF22675720E58E1F6D01F3B45315B818EF9CE880CE92F022763911796D4F86361BEB151ACB400BA017186C1DDCDE5F1853260ECF1082E072C2B7E2FD33E51B5076675269EC247AAE3DF3C1E6853E5D0E58FF7268255E91A9BF6FD43750F114BCA5DC70176ECACAF59C812798941D04FFFF200B53F9843066568A5EF6B324692239A9DC94383C53DA447D942BD51E17F51C22106DC3A2FC7A8942E20E5DA369D19124D184A96589E66EE15C4A8E4CB0FBB6B5E629875DEB3C6AAF622ABC4A4057E0B95533A03C94C514D2129CD6ECE739D9E3A98A54461DF577CC508BF4D5EE7FBE6178B248E3F51C59FE57BFBDE33DD833D0CF22DB22AE0F4F9F03EEF8E0E1DB0EDF7BB4C755148AD2D3FECED23DE1F028A3A6396D7F8F721D11023BD58335ADE175939E140A92C7B532A3D77168E566B7AADEA6F137A158AF3D2608FD4C1081018C1BC2B860A2830A097BDAFA96A3D5B5E1130D2C0778837C63ACBE958573B4ADAC2AE629D17728313AB9064D890006B2F0EC1869E35480B96651B9B3837B876190D5F1876A151A87C58A1CE2A9AD0744BE4CF955BFA9FA5653300FF6ECD64667ECD836D61DC3675048A8EB5AE945B50CB699F7FB4E36167515A2054199687DEC77D5117DF28B63F383403C49097F23AA4DE5857A0D865AFC7E4D0994B46386C20A41E9B41963CD425A82B30C4EE72FB3EFACD6C4090D740E44C196E51F41894FDB26142B72EF1E65A676C30EFB65C937C0F64CDEC167ECC16F0CAA3C932F3DD5C6F7A1EB073F03F2CB9F2059BE75EBAE32FA3170B5FA93D69CAB8275935686242E1F43ED23FE8784A0AD694442D35193DAAF5F7DA49B267B716C38F36C92AE7986DF8126904B11EA74323F3AB3AF436D64AC41996529AB95876EE4DF3739130460A50E2EC8463F2306454F08745CE40938858B6237A5D38B33FD6541BB98EFB39A7B0B501B7943FF594DF0964BF535CBD35105E35BA14C40E62D57F3B110AE82CD7F9FF73C3A28740C8EB397494F6D7CF5F0F147385424D70B276C6AD849E56C9985115EAF2CCF3D3A6C828F2A303178EC48BB08F36AF3800739E841F7B758FF06EFA10F6467E98DA4B1B302EFED0EF5A7D3AD74100E41C168ACBBF10EC5FFC497B43409D02D942C144408C32C83ED49334BC48FD1D446FDEBB71CA1F9276F3180ECA057E4B8F19FAFE368D0097EE2A5736D72BE661382939491A244B068D26A071E55E25DF2C8706ADEFD8245BC97A691AB57A8D39CE24469E9CC69198F4F795CACCB45053F464CA0C2F04C71E9CD6BB6D378E917C413B7FADEACD41A7A43E9A1FC04576658DBF7420A35252A899B51F9ED9B2D0B5534A696C2465C950EF5880636D96CC963AF6C314D00834969C459507D47F +20241204154043 2 6 100 8191 2 DC5E734609D91DA7E5180C89891C148715345D3A56F96DDFF41EE0B90992E9901E55850A78D9DF296A83F5AAF22675720E58E1F6D01F3B45315B818EF9CE880CE92F022763911796D4F86361BEB151ACB400BA017186C1DDCDE5F1853260ECF1082E072C2B7E2FD33E51B5076675269EC247AAE3DF3C1E6853E5D0E58FF7268255E91A9BF6FD43750F114BCA5DC70176ECACAF59C812798941D04FFFF200B53F9843066568A5EF6B324692239A9DC94383C53DA447D942BD51E17F51C22106DC3A2FC7A8942E20E5DA369D19124D184A96589E66EE15C4A8E4CB0FBB6B5E629875DEB3C6AAF622ABC4A4057E0B95533A03C94C514D2129CD6ECE739D9E3A98A54461DF577CC508BF4D5EE7FBE6178B248E3F51C59FE57BFBDE33DD833D0CF22DB22AE0F4F9F03EEF8E0E1DB0EDF7BB4C755148AD2D3FECED23DE1F028A3A6396D7F8F721D11023BD58335ADE175939E140A92C7B532A3D77168E566B7AADEA6F137A158AF3D2608FD4C1081018C1BC2B860A2830A097BDAFA96A3D5B5E1130D2C0778837C63ACBE958573B4ADAC2AE629D17728313AB9064D890006B2F0EC1869E35480B96651B9B3837B876190D5F1876A151A87C58A1CE2A9AD0744BE4CF955BFA9FA5653300FF6ECD64667ECD836D61DC3675048A8EB5AE945B50CB699F7FB4E36167515A2054199687DEC77D5117DF28B63F383403C49097F23AA4DE5857A0D865AFC7E4D0994B46386C20A41E9B41963CD425A82B30C4EE72FB3EFACD6C4090D740E44C196E51F41894FDB26142B72EF1E65A676C30EFB65C937C0F64CDEC167ECC16F0CAA3C932F3DD5C6F7A1EB073F03F2CB9F2059BE75EBAE32FA3170B5FA93D69CAB8275935686242E1F43ED23FE8784A0AD694442D35193DAAF5F7DA49B267B716C38F36C92AE7986DF8126904B11EA74323F3AB3AF436D64AC41996529AB95876EE4DF3739130460A50E2EC8463F2306454F08745CE40938858B6237A5D38B33FD6541BB98EFB39A7B0B501B7943FF594DF0964BF535CBD35105E35BA14C40E62D57F3B110AE82CD7F9FF73C3A28740C8EB397494F6D7CF5F0F147385424D70B276C6AD849E56C9985115EAF2CCF3D3A6C828F2A303178EC48BB08F36AF3800739E841F7B758FF06EFA10F6467E98DA4B1B302EFED0EF5A7D3AD74100E41C168ACBBF10EC5FFC497B43409D02D942C144408C32C83ED49334BC48FD1D446FDEBB71CA1F9276F3180ECA057E4B8F19FAFE368D0097EE2A5736D72BE661382939491A244B068D26A071E55E25DF2C8706ADEFD8245BC97A691AB57A8D39CE24469E9CC69198F4F795CACCB45053F464CA0C2F04C71E9CD6BB6D378E917C413B7FADEACD41A7A43E9A1FC04576658DBF7420A35252A899B51F9ED9B2D0B5534A696C2465C950EF5880636D96CC963AF6C314D00834969C45951265E3 +20241204161206 2 6 100 8191 2 DC5E734609D91DA7E5180C89891C148715345D3A56F96DDFF41EE0B90992E9901E55850A78D9DF296A83F5AAF22675720E58E1F6D01F3B45315B818EF9CE880CE92F022763911796D4F86361BEB151ACB400BA017186C1DDCDE5F1853260ECF1082E072C2B7E2FD33E51B5076675269EC247AAE3DF3C1E6853E5D0E58FF7268255E91A9BF6FD43750F114BCA5DC70176ECACAF59C812798941D04FFFF200B53F9843066568A5EF6B324692239A9DC94383C53DA447D942BD51E17F51C22106DC3A2FC7A8942E20E5DA369D19124D184A96589E66EE15C4A8E4CB0FBB6B5E629875DEB3C6AAF622ABC4A4057E0B95533A03C94C514D2129CD6ECE739D9E3A98A54461DF577CC508BF4D5EE7FBE6178B248E3F51C59FE57BFBDE33DD833D0CF22DB22AE0F4F9F03EEF8E0E1DB0EDF7BB4C755148AD2D3FECED23DE1F028A3A6396D7F8F721D11023BD58335ADE175939E140A92C7B532A3D77168E566B7AADEA6F137A158AF3D2608FD4C1081018C1BC2B860A2830A097BDAFA96A3D5B5E1130D2C0778837C63ACBE958573B4ADAC2AE629D17728313AB9064D890006B2F0EC1869E35480B96651B9B3837B876190D5F1876A151A87C58A1CE2A9AD0744BE4CF955BFA9FA5653300FF6ECD64667ECD836D61DC3675048A8EB5AE945B50CB699F7FB4E36167515A2054199687DEC77D5117DF28B63F383403C49097F23AA4DE5857A0D865AFC7E4D0994B46386C20A41E9B41963CD425A82B30C4EE72FB3EFACD6C4090D740E44C196E51F41894FDB26142B72EF1E65A676C30EFB65C937C0F64CDEC167ECC16F0CAA3C932F3DD5C6F7A1EB073F03F2CB9F2059BE75EBAE32FA3170B5FA93D69CAB8275935686242E1F43ED23FE8784A0AD694442D35193DAAF5F7DA49B267B716C38F36C92AE7986DF8126904B11EA74323F3AB3AF436D64AC41996529AB95876EE4DF3739130460A50E2EC8463F2306454F08745CE40938858B6237A5D38B33FD6541BB98EFB39A7B0B501B7943FF594DF0964BF535CBD35105E35BA14C40E62D57F3B110AE82CD7F9FF73C3A28740C8EB397494F6D7CF5F0F147385424D70B276C6AD849E56C9985115EAF2CCF3D3A6C828F2A303178EC48BB08F36AF3800739E841F7B758FF06EFA10F6467E98DA4B1B302EFED0EF5A7D3AD74100E41C168ACBBF10EC5FFC497B43409D02D942C144408C32C83ED49334BC48FD1D446FDEBB71CA1F9276F3180ECA057E4B8F19FAFE368D0097EE2A5736D72BE661382939491A244B068D26A071E55E25DF2C8706ADEFD8245BC97A691AB57A8D39CE24469E9CC69198F4F795CACCB45053F464CA0C2F04C71E9CD6BB6D378E917C413B7FADEACD41A7A43E9A1FC04576658DBF7420A35252A899B51F9ED9B2D0B5534A696C2465C950EF5880636D96CC963AF6C314D00834969C4596CC6423 +20241204161425 2 6 100 8191 2 DC5E734609D91DA7E5180C89891C148715345D3A56F96DDFF41EE0B90992E9901E55850A78D9DF296A83F5AAF22675720E58E1F6D01F3B45315B818EF9CE880CE92F022763911796D4F86361BEB151ACB400BA017186C1DDCDE5F1853260ECF1082E072C2B7E2FD33E51B5076675269EC247AAE3DF3C1E6853E5D0E58FF7268255E91A9BF6FD43750F114BCA5DC70176ECACAF59C812798941D04FFFF200B53F9843066568A5EF6B324692239A9DC94383C53DA447D942BD51E17F51C22106DC3A2FC7A8942E20E5DA369D19124D184A96589E66EE15C4A8E4CB0FBB6B5E629875DEB3C6AAF622ABC4A4057E0B95533A03C94C514D2129CD6ECE739D9E3A98A54461DF577CC508BF4D5EE7FBE6178B248E3F51C59FE57BFBDE33DD833D0CF22DB22AE0F4F9F03EEF8E0E1DB0EDF7BB4C755148AD2D3FECED23DE1F028A3A6396D7F8F721D11023BD58335ADE175939E140A92C7B532A3D77168E566B7AADEA6F137A158AF3D2608FD4C1081018C1BC2B860A2830A097BDAFA96A3D5B5E1130D2C0778837C63ACBE958573B4ADAC2AE629D17728313AB9064D890006B2F0EC1869E35480B96651B9B3837B876190D5F1876A151A87C58A1CE2A9AD0744BE4CF955BFA9FA5653300FF6ECD64667ECD836D61DC3675048A8EB5AE945B50CB699F7FB4E36167515A2054199687DEC77D5117DF28B63F383403C49097F23AA4DE5857A0D865AFC7E4D0994B46386C20A41E9B41963CD425A82B30C4EE72FB3EFACD6C4090D740E44C196E51F41894FDB26142B72EF1E65A676C30EFB65C937C0F64CDEC167ECC16F0CAA3C932F3DD5C6F7A1EB073F03F2CB9F2059BE75EBAE32FA3170B5FA93D69CAB8275935686242E1F43ED23FE8784A0AD694442D35193DAAF5F7DA49B267B716C38F36C92AE7986DF8126904B11EA74323F3AB3AF436D64AC41996529AB95876EE4DF3739130460A50E2EC8463F2306454F08745CE40938858B6237A5D38B33FD6541BB98EFB39A7B0B501B7943FF594DF0964BF535CBD35105E35BA14C40E62D57F3B110AE82CD7F9FF73C3A28740C8EB397494F6D7CF5F0F147385424D70B276C6AD849E56C9985115EAF2CCF3D3A6C828F2A303178EC48BB08F36AF3800739E841F7B758FF06EFA10F6467E98DA4B1B302EFED0EF5A7D3AD74100E41C168ACBBF10EC5FFC497B43409D02D942C144408C32C83ED49334BC48FD1D446FDEBB71CA1F9276F3180ECA057E4B8F19FAFE368D0097EE2A5736D72BE661382939491A244B068D26A071E55E25DF2C8706ADEFD8245BC97A691AB57A8D39CE24469E9CC69198F4F795CACCB45053F464CA0C2F04C71E9CD6BB6D378E917C413B7FADEACD41A7A43E9A1FC04576658DBF7420A35252A899B51F9ED9B2D0B5534A696C2465C950EF5880636D96CC963AF6C314D00834969C4596E4BA93 +20241204172055 2 6 100 8191 2 DC5E734609D91DA7E5180C89891C148715345D3A56F96DDFF41EE0B90992E9901E55850A78D9DF296A83F5AAF22675720E58E1F6D01F3B45315B818EF9CE880CE92F022763911796D4F86361BEB151ACB400BA017186C1DDCDE5F1853260ECF1082E072C2B7E2FD33E51B5076675269EC247AAE3DF3C1E6853E5D0E58FF7268255E91A9BF6FD43750F114BCA5DC70176ECACAF59C812798941D04FFFF200B53F9843066568A5EF6B324692239A9DC94383C53DA447D942BD51E17F51C22106DC3A2FC7A8942E20E5DA369D19124D184A96589E66EE15C4A8E4CB0FBB6B5E629875DEB3C6AAF622ABC4A4057E0B95533A03C94C514D2129CD6ECE739D9E3A98A54461DF577CC508BF4D5EE7FBE6178B248E3F51C59FE57BFBDE33DD833D0CF22DB22AE0F4F9F03EEF8E0E1DB0EDF7BB4C755148AD2D3FECED23DE1F028A3A6396D7F8F721D11023BD58335ADE175939E140A92C7B532A3D77168E566B7AADEA6F137A158AF3D2608FD4C1081018C1BC2B860A2830A097BDAFA96A3D5B5E1130D2C0778837C63ACBE958573B4ADAC2AE629D17728313AB9064D890006B2F0EC1869E35480B96651B9B3837B876190D5F1876A151A87C58A1CE2A9AD0744BE4CF955BFA9FA5653300FF6ECD64667ECD836D61DC3675048A8EB5AE945B50CB699F7FB4E36167515A2054199687DEC77D5117DF28B63F383403C49097F23AA4DE5857A0D865AFC7E4D0994B46386C20A41E9B41963CD425A82B30C4EE72FB3EFACD6C4090D740E44C196E51F41894FDB26142B72EF1E65A676C30EFB65C937C0F64CDEC167ECC16F0CAA3C932F3DD5C6F7A1EB073F03F2CB9F2059BE75EBAE32FA3170B5FA93D69CAB8275935686242E1F43ED23FE8784A0AD694442D35193DAAF5F7DA49B267B716C38F36C92AE7986DF8126904B11EA74323F3AB3AF436D64AC41996529AB95876EE4DF3739130460A50E2EC8463F2306454F08745CE40938858B6237A5D38B33FD6541BB98EFB39A7B0B501B7943FF594DF0964BF535CBD35105E35BA14C40E62D57F3B110AE82CD7F9FF73C3A28740C8EB397494F6D7CF5F0F147385424D70B276C6AD849E56C9985115EAF2CCF3D3A6C828F2A303178EC48BB08F36AF3800739E841F7B758FF06EFA10F6467E98DA4B1B302EFED0EF5A7D3AD74100E41C168ACBBF10EC5FFC497B43409D02D942C144408C32C83ED49334BC48FD1D446FDEBB71CA1F9276F3180ECA057E4B8F19FAFE368D0097EE2A5736D72BE661382939491A244B068D26A071E55E25DF2C8706ADEFD8245BC97A691AB57A8D39CE24469E9CC69198F4F795CACCB45053F464CA0C2F04C71E9CD6BB6D378E917C413B7FADEACD41A7A43E9A1FC04576658DBF7420A35252A899B51F9ED9B2D0B5534A696C2465C950EF5880636D96CC963AF6C314D00834969C459A8DA68B +20241204192705 2 6 100 8191 5 DC5E734609D91DA7E5180C89891C148715345D3A56F96DDFF41EE0B90992E9901E55850A78D9DF296A83F5AAF22675720E58E1F6D01F3B45315B818EF9CE880CE92F022763911796D4F86361BEB151ACB400BA017186C1DDCDE5F1853260ECF1082E072C2B7E2FD33E51B5076675269EC247AAE3DF3C1E6853E5D0E58FF7268255E91A9BF6FD43750F114BCA5DC70176ECACAF59C812798941D04FFFF200B53F9843066568A5EF6B324692239A9DC94383C53DA447D942BD51E17F51C22106DC3A2FC7A8942E20E5DA369D19124D184A96589E66EE15C4A8E4CB0FBB6B5E629875DEB3C6AAF622ABC4A4057E0B95533A03C94C514D2129CD6ECE739D9E3A98A54461DF577CC508BF4D5EE7FBE6178B248E3F51C59FE57BFBDE33DD833D0CF22DB22AE0F4F9F03EEF8E0E1DB0EDF7BB4C755148AD2D3FECED23DE1F028A3A6396D7F8F721D11023BD58335ADE175939E140A92C7B532A3D77168E566B7AADEA6F137A158AF3D2608FD4C1081018C1BC2B860A2830A097BDAFA96A3D5B5E1130D2C0778837C63ACBE958573B4ADAC2AE629D17728313AB9064D890006B2F0EC1869E35480B96651B9B3837B876190D5F1876A151A87C58A1CE2A9AD0744BE4CF955BFA9FA5653300FF6ECD64667ECD836D61DC3675048A8EB5AE945B50CB699F7FB4E36167515A2054199687DEC77D5117DF28B63F383403C49097F23AA4DE5857A0D865AFC7E4D0994B46386C20A41E9B41963CD425A82B30C4EE72FB3EFACD6C4090D740E44C196E51F41894FDB26142B72EF1E65A676C30EFB65C937C0F64CDEC167ECC16F0CAA3C932F3DD5C6F7A1EB073F03F2CB9F2059BE75EBAE32FA3170B5FA93D69CAB8275935686242E1F43ED23FE8784A0AD694442D35193DAAF5F7DA49B267B716C38F36C92AE7986DF8126904B11EA74323F3AB3AF436D64AC41996529AB95876EE4DF3739130460A50E2EC8463F2306454F08745CE40938858B6237A5D38B33FD6541BB98EFB39A7B0B501B7943FF594DF0964BF535CBD35105E35BA14C40E62D57F3B110AE82CD7F9FF73C3A28740C8EB397494F6D7CF5F0F147385424D70B276C6AD849E56C9985115EAF2CCF3D3A6C828F2A303178EC48BB08F36AF3800739E841F7B758FF06EFA10F6467E98DA4B1B302EFED0EF5A7D3AD74100E41C168ACBBF10EC5FFC497B43409D02D942C144408C32C83ED49334BC48FD1D446FDEBB71CA1F9276F3180ECA057E4B8F19FAFE368D0097EE2A5736D72BE661382939491A244B068D26A071E55E25DF2C8706ADEFD8245BC97A691AB57A8D39CE24469E9CC69198F4F795CACCB45053F464CA0C2F04C71E9CD6BB6D378E917C413B7FADEACD41A7A43E9A1FC04576658DBF7420A35252A899B51F9ED9B2D0B5534A696C2465C950EF5880636D96CC963AF6C314D00834969C45A16C53A7 +20241204212358 2 6 100 8191 5 DC5E734609D91DA7E5180C89891C148715345D3A56F96DDFF41EE0B90992E9901E55850A78D9DF296A83F5AAF22675720E58E1F6D01F3B45315B818EF9CE880CE92F022763911796D4F86361BEB151ACB400BA017186C1DDCDE5F1853260ECF1082E072C2B7E2FD33E51B5076675269EC247AAE3DF3C1E6853E5D0E58FF7268255E91A9BF6FD43750F114BCA5DC70176ECACAF59C812798941D04FFFF200B53F9843066568A5EF6B324692239A9DC94383C53DA447D942BD51E17F51C22106DC3A2FC7A8942E20E5DA369D19124D184A96589E66EE15C4A8E4CB0FBB6B5E629875DEB3C6AAF622ABC4A4057E0B95533A03C94C514D2129CD6ECE739D9E3A98A54461DF577CC508BF4D5EE7FBE6178B248E3F51C59FE57BFBDE33DD833D0CF22DB22AE0F4F9F03EEF8E0E1DB0EDF7BB4C755148AD2D3FECED23DE1F028A3A6396D7F8F721D11023BD58335ADE175939E140A92C7B532A3D77168E566B7AADEA6F137A158AF3D2608FD4C1081018C1BC2B860A2830A097BDAFA96A3D5B5E1130D2C0778837C63ACBE958573B4ADAC2AE629D17728313AB9064D890006B2F0EC1869E35480B96651B9B3837B876190D5F1876A151A87C58A1CE2A9AD0744BE4CF955BFA9FA5653300FF6ECD64667ECD836D61DC3675048A8EB5AE945B50CB699F7FB4E36167515A2054199687DEC77D5117DF28B63F383403C49097F23AA4DE5857A0D865AFC7E4D0994B46386C20A41E9B41963CD425A82B30C4EE72FB3EFACD6C4090D740E44C196E51F41894FDB26142B72EF1E65A676C30EFB65C937C0F64CDEC167ECC16F0CAA3C932F3DD5C6F7A1EB073F03F2CB9F2059BE75EBAE32FA3170B5FA93D69CAB8275935686242E1F43ED23FE8784A0AD694442D35193DAAF5F7DA49B267B716C38F36C92AE7986DF8126904B11EA74323F3AB3AF436D64AC41996529AB95876EE4DF3739130460A50E2EC8463F2306454F08745CE40938858B6237A5D38B33FD6541BB98EFB39A7B0B501B7943FF594DF0964BF535CBD35105E35BA14C40E62D57F3B110AE82CD7F9FF73C3A28740C8EB397494F6D7CF5F0F147385424D70B276C6AD849E56C9985115EAF2CCF3D3A6C828F2A303178EC48BB08F36AF3800739E841F7B758FF06EFA10F6467E98DA4B1B302EFED0EF5A7D3AD74100E41C168ACBBF10EC5FFC497B43409D02D942C144408C32C83ED49334BC48FD1D446FDEBB71CA1F9276F3180ECA057E4B8F19FAFE368D0097EE2A5736D72BE661382939491A244B068D26A071E55E25DF2C8706ADEFD8245BC97A691AB57A8D39CE24469E9CC69198F4F795CACCB45053F464CA0C2F04C71E9CD6BB6D378E917C413B7FADEACD41A7A43E9A1FC04576658DBF7420A35252A899B51F9ED9B2D0B5534A696C2465C950EF5880636D96CC963AF6C314D00834969C45A7E3BB4F +20241204213330 2 6 100 8191 2 DC5E734609D91DA7E5180C89891C148715345D3A56F96DDFF41EE0B90992E9901E55850A78D9DF296A83F5AAF22675720E58E1F6D01F3B45315B818EF9CE880CE92F022763911796D4F86361BEB151ACB400BA017186C1DDCDE5F1853260ECF1082E072C2B7E2FD33E51B5076675269EC247AAE3DF3C1E6853E5D0E58FF7268255E91A9BF6FD43750F114BCA5DC70176ECACAF59C812798941D04FFFF200B53F9843066568A5EF6B324692239A9DC94383C53DA447D942BD51E17F51C22106DC3A2FC7A8942E20E5DA369D19124D184A96589E66EE15C4A8E4CB0FBB6B5E629875DEB3C6AAF622ABC4A4057E0B95533A03C94C514D2129CD6ECE739D9E3A98A54461DF577CC508BF4D5EE7FBE6178B248E3F51C59FE57BFBDE33DD833D0CF22DB22AE0F4F9F03EEF8E0E1DB0EDF7BB4C755148AD2D3FECED23DE1F028A3A6396D7F8F721D11023BD58335ADE175939E140A92C7B532A3D77168E566B7AADEA6F137A158AF3D2608FD4C1081018C1BC2B860A2830A097BDAFA96A3D5B5E1130D2C0778837C63ACBE958573B4ADAC2AE629D17728313AB9064D890006B2F0EC1869E35480B96651B9B3837B876190D5F1876A151A87C58A1CE2A9AD0744BE4CF955BFA9FA5653300FF6ECD64667ECD836D61DC3675048A8EB5AE945B50CB699F7FB4E36167515A2054199687DEC77D5117DF28B63F383403C49097F23AA4DE5857A0D865AFC7E4D0994B46386C20A41E9B41963CD425A82B30C4EE72FB3EFACD6C4090D740E44C196E51F41894FDB26142B72EF1E65A676C30EFB65C937C0F64CDEC167ECC16F0CAA3C932F3DD5C6F7A1EB073F03F2CB9F2059BE75EBAE32FA3170B5FA93D69CAB8275935686242E1F43ED23FE8784A0AD694442D35193DAAF5F7DA49B267B716C38F36C92AE7986DF8126904B11EA74323F3AB3AF436D64AC41996529AB95876EE4DF3739130460A50E2EC8463F2306454F08745CE40938858B6237A5D38B33FD6541BB98EFB39A7B0B501B7943FF594DF0964BF535CBD35105E35BA14C40E62D57F3B110AE82CD7F9FF73C3A28740C8EB397494F6D7CF5F0F147385424D70B276C6AD849E56C9985115EAF2CCF3D3A6C828F2A303178EC48BB08F36AF3800739E841F7B758FF06EFA10F6467E98DA4B1B302EFED0EF5A7D3AD74100E41C168ACBBF10EC5FFC497B43409D02D942C144408C32C83ED49334BC48FD1D446FDEBB71CA1F9276F3180ECA057E4B8F19FAFE368D0097EE2A5736D72BE661382939491A244B068D26A071E55E25DF2C8706ADEFD8245BC97A691AB57A8D39CE24469E9CC69198F4F795CACCB45053F464CA0C2F04C71E9CD6BB6D378E917C413B7FADEACD41A7A43E9A1FC04576658DBF7420A35252A899B51F9ED9B2D0B5534A696C2465C950EF5880636D96CC963AF6C314D00834969C45A86569BB +20241204221629 2 6 100 8191 2 DC5E734609D91DA7E5180C89891C148715345D3A56F96DDFF41EE0B90992E9901E55850A78D9DF296A83F5AAF22675720E58E1F6D01F3B45315B818EF9CE880CE92F022763911796D4F86361BEB151ACB400BA017186C1DDCDE5F1853260ECF1082E072C2B7E2FD33E51B5076675269EC247AAE3DF3C1E6853E5D0E58FF7268255E91A9BF6FD43750F114BCA5DC70176ECACAF59C812798941D04FFFF200B53F9843066568A5EF6B324692239A9DC94383C53DA447D942BD51E17F51C22106DC3A2FC7A8942E20E5DA369D19124D184A96589E66EE15C4A8E4CB0FBB6B5E629875DEB3C6AAF622ABC4A4057E0B95533A03C94C514D2129CD6ECE739D9E3A98A54461DF577CC508BF4D5EE7FBE6178B248E3F51C59FE57BFBDE33DD833D0CF22DB22AE0F4F9F03EEF8E0E1DB0EDF7BB4C755148AD2D3FECED23DE1F028A3A6396D7F8F721D11023BD58335ADE175939E140A92C7B532A3D77168E566B7AADEA6F137A158AF3D2608FD4C1081018C1BC2B860A2830A097BDAFA96A3D5B5E1130D2C0778837C63ACBE958573B4ADAC2AE629D17728313AB9064D890006B2F0EC1869E35480B96651B9B3837B876190D5F1876A151A87C58A1CE2A9AD0744BE4CF955BFA9FA5653300FF6ECD64667ECD836D61DC3675048A8EB5AE945B50CB699F7FB4E36167515A2054199687DEC77D5117DF28B63F383403C49097F23AA4DE5857A0D865AFC7E4D0994B46386C20A41E9B41963CD425A82B30C4EE72FB3EFACD6C4090D740E44C196E51F41894FDB26142B72EF1E65A676C30EFB65C937C0F64CDEC167ECC16F0CAA3C932F3DD5C6F7A1EB073F03F2CB9F2059BE75EBAE32FA3170B5FA93D69CAB8275935686242E1F43ED23FE8784A0AD694442D35193DAAF5F7DA49B267B716C38F36C92AE7986DF8126904B11EA74323F3AB3AF436D64AC41996529AB95876EE4DF3739130460A50E2EC8463F2306454F08745CE40938858B6237A5D38B33FD6541BB98EFB39A7B0B501B7943FF594DF0964BF535CBD35105E35BA14C40E62D57F3B110AE82CD7F9FF73C3A28740C8EB397494F6D7CF5F0F147385424D70B276C6AD849E56C9985115EAF2CCF3D3A6C828F2A303178EC48BB08F36AF3800739E841F7B758FF06EFA10F6467E98DA4B1B302EFED0EF5A7D3AD74100E41C168ACBBF10EC5FFC497B43409D02D942C144408C32C83ED49334BC48FD1D446FDEBB71CA1F9276F3180ECA057E4B8F19FAFE368D0097EE2A5736D72BE661382939491A244B068D26A071E55E25DF2C8706ADEFD8245BC97A691AB57A8D39CE24469E9CC69198F4F795CACCB45053F464CA0C2F04C71E9CD6BB6D378E917C413B7FADEACD41A7A43E9A1FC04576658DBF7420A35252A899B51F9ED9B2D0B5534A696C2465C950EF5880636D96CC963AF6C314D00834969C45AAC0BC23 +20241205021404 2 6 100 8191 5 DC5E734609D91DA7E5180C89891C148715345D3A56F96DDFF41EE0B90992E9901E55850A78D9DF296A83F5AAF22675720E58E1F6D01F3B45315B818EF9CE880CE92F022763911796D4F86361BEB151ACB400BA017186C1DDCDE5F1853260ECF1082E072C2B7E2FD33E51B5076675269EC247AAE3DF3C1E6853E5D0E58FF7268255E91A9BF6FD43750F114BCA5DC70176ECACAF59C812798941D04FFFF200B53F9843066568A5EF6B324692239A9DC94383C53DA447D942BD51E17F51C22106DC3A2FC7A8942E20E5DA369D19124D184A96589E66EE15C4A8E4CB0FBB6B5E629875DEB3C6AAF622ABC4A4057E0B95533A03C94C514D2129CD6ECE739D9E3A98A54461DF577CC508BF4D5EE7FBE6178B248E3F51C59FE57BFBDE33DD833D0CF22DB22AE0F4F9F03EEF8E0E1DB0EDF7BB4C755148AD2D3FECED23DE1F028A3A6396D7F8F721D11023BD58335ADE175939E140A92C7B532A3D77168E566B7AADEA6F137A158AF3D2608FD4C1081018C1BC2B860A2830A097BDAFA96A3D5B5E1130D2C0778837C63ACBE958573B4ADAC2AE629D17728313AB9064D890006B2F0EC1869E35480B96651B9B3837B876190D5F1876A151A87C58A1CE2A9AD0744BE4CF955BFA9FA5653300FF6ECD64667ECD836D61DC3675048A8EB5AE945B50CB699F7FB4E36167515A2054199687DEC77D5117DF28B63F383403C49097F23AA4DE5857A0D865AFC7E4D0994B46386C20A41E9B41963CD425A82B30C4EE72FB3EFACD6C4090D740E44C196E51F41894FDB26142B72EF1E65A676C30EFB65C937C0F64CDEC167ECC16F0CAA3C932F3DD5C6F7A1EB073F03F2CB9F2059BE75EBAE32FA3170B5FA93D69CAB8275935686242E1F43ED23FE8784A0AD694442D35193DAAF5F7DA49B267B716C38F36C92AE7986DF8126904B11EA74323F3AB3AF436D64AC41996529AB95876EE4DF3739130460A50E2EC8463F2306454F08745CE40938858B6237A5D38B33FD6541BB98EFB39A7B0B501B7943FF594DF0964BF535CBD35105E35BA14C40E62D57F3B110AE82CD7F9FF73C3A28740C8EB397494F6D7CF5F0F147385424D70B276C6AD849E56C9985115EAF2CCF3D3A6C828F2A303178EC48BB08F36AF3800739E841F7B758FF06EFA10F6467E98DA4B1B302EFED0EF5A7D3AD74100E41C168ACBBF10EC5FFC497B43409D02D942C144408C32C83ED49334BC48FD1D446FDEBB71CA1F9276F3180ECA057E4B8F19FAFE368D0097EE2A5736D72BE661382939491A244B068D26A071E55E25DF2C8706ADEFD8245BC97A691AB57A8D39CE24469E9CC69198F4F795CACCB45053F464CA0C2F04C71E9CD6BB6D378E917C413B7FADEACD41A7A43E9A1FC04576658DBF7420A35252A899B51F9ED9B2D0B5534A696C2465C950EF5880636D96CC963AF6C314D00834969C45B80CC4F7 +20241205023328 2 6 100 8191 2 DC5E734609D91DA7E5180C89891C148715345D3A56F96DDFF41EE0B90992E9901E55850A78D9DF296A83F5AAF22675720E58E1F6D01F3B45315B818EF9CE880CE92F022763911796D4F86361BEB151ACB400BA017186C1DDCDE5F1853260ECF1082E072C2B7E2FD33E51B5076675269EC247AAE3DF3C1E6853E5D0E58FF7268255E91A9BF6FD43750F114BCA5DC70176ECACAF59C812798941D04FFFF200B53F9843066568A5EF6B324692239A9DC94383C53DA447D942BD51E17F51C22106DC3A2FC7A8942E20E5DA369D19124D184A96589E66EE15C4A8E4CB0FBB6B5E629875DEB3C6AAF622ABC4A4057E0B95533A03C94C514D2129CD6ECE739D9E3A98A54461DF577CC508BF4D5EE7FBE6178B248E3F51C59FE57BFBDE33DD833D0CF22DB22AE0F4F9F03EEF8E0E1DB0EDF7BB4C755148AD2D3FECED23DE1F028A3A6396D7F8F721D11023BD58335ADE175939E140A92C7B532A3D77168E566B7AADEA6F137A158AF3D2608FD4C1081018C1BC2B860A2830A097BDAFA96A3D5B5E1130D2C0778837C63ACBE958573B4ADAC2AE629D17728313AB9064D890006B2F0EC1869E35480B96651B9B3837B876190D5F1876A151A87C58A1CE2A9AD0744BE4CF955BFA9FA5653300FF6ECD64667ECD836D61DC3675048A8EB5AE945B50CB699F7FB4E36167515A2054199687DEC77D5117DF28B63F383403C49097F23AA4DE5857A0D865AFC7E4D0994B46386C20A41E9B41963CD425A82B30C4EE72FB3EFACD6C4090D740E44C196E51F41894FDB26142B72EF1E65A676C30EFB65C937C0F64CDEC167ECC16F0CAA3C932F3DD5C6F7A1EB073F03F2CB9F2059BE75EBAE32FA3170B5FA93D69CAB8275935686242E1F43ED23FE8784A0AD694442D35193DAAF5F7DA49B267B716C38F36C92AE7986DF8126904B11EA74323F3AB3AF436D64AC41996529AB95876EE4DF3739130460A50E2EC8463F2306454F08745CE40938858B6237A5D38B33FD6541BB98EFB39A7B0B501B7943FF594DF0964BF535CBD35105E35BA14C40E62D57F3B110AE82CD7F9FF73C3A28740C8EB397494F6D7CF5F0F147385424D70B276C6AD849E56C9985115EAF2CCF3D3A6C828F2A303178EC48BB08F36AF3800739E841F7B758FF06EFA10F6467E98DA4B1B302EFED0EF5A7D3AD74100E41C168ACBBF10EC5FFC497B43409D02D942C144408C32C83ED49334BC48FD1D446FDEBB71CA1F9276F3180ECA057E4B8F19FAFE368D0097EE2A5736D72BE661382939491A244B068D26A071E55E25DF2C8706ADEFD8245BC97A691AB57A8D39CE24469E9CC69198F4F795CACCB45053F464CA0C2F04C71E9CD6BB6D378E917C413B7FADEACD41A7A43E9A1FC04576658DBF7420A35252A899B51F9ED9B2D0B5534A696C2465C950EF5880636D96CC963AF6C314D00834969C45B9166F1B +20241205040105 2 6 100 8191 5 DC5E734609D91DA7E5180C89891C148715345D3A56F96DDFF41EE0B90992E9901E55850A78D9DF296A83F5AAF22675720E58E1F6D01F3B45315B818EF9CE880CE92F022763911796D4F86361BEB151ACB400BA017186C1DDCDE5F1853260ECF1082E072C2B7E2FD33E51B5076675269EC247AAE3DF3C1E6853E5D0E58FF7268255E91A9BF6FD43750F114BCA5DC70176ECACAF59C812798941D04FFFF200B53F9843066568A5EF6B324692239A9DC94383C53DA447D942BD51E17F51C22106DC3A2FC7A8942E20E5DA369D19124D184A96589E66EE15C4A8E4CB0FBB6B5E629875DEB3C6AAF622ABC4A4057E0B95533A03C94C514D2129CD6ECE739D9E3A98A54461DF577CC508BF4D5EE7FBE6178B248E3F51C59FE57BFBDE33DD833D0CF22DB22AE0F4F9F03EEF8E0E1DB0EDF7BB4C755148AD2D3FECED23DE1F028A3A6396D7F8F721D11023BD58335ADE175939E140A92C7B532A3D77168E566B7AADEA6F137A158AF3D2608FD4C1081018C1BC2B860A2830A097BDAFA96A3D5B5E1130D2C0778837C63ACBE958573B4ADAC2AE629D17728313AB9064D890006B2F0EC1869E35480B96651B9B3837B876190D5F1876A151A87C58A1CE2A9AD0744BE4CF955BFA9FA5653300FF6ECD64667ECD836D61DC3675048A8EB5AE945B50CB699F7FB4E36167515A2054199687DEC77D5117DF28B63F383403C49097F23AA4DE5857A0D865AFC7E4D0994B46386C20A41E9B41963CD425A82B30C4EE72FB3EFACD6C4090D740E44C196E51F41894FDB26142B72EF1E65A676C30EFB65C937C0F64CDEC167ECC16F0CAA3C932F3DD5C6F7A1EB073F03F2CB9F2059BE75EBAE32FA3170B5FA93D69CAB8275935686242E1F43ED23FE8784A0AD694442D35193DAAF5F7DA49B267B716C38F36C92AE7986DF8126904B11EA74323F3AB3AF436D64AC41996529AB95876EE4DF3739130460A50E2EC8463F2306454F08745CE40938858B6237A5D38B33FD6541BB98EFB39A7B0B501B7943FF594DF0964BF535CBD35105E35BA14C40E62D57F3B110AE82CD7F9FF73C3A28740C8EB397494F6D7CF5F0F147385424D70B276C6AD849E56C9985115EAF2CCF3D3A6C828F2A303178EC48BB08F36AF3800739E841F7B758FF06EFA10F6467E98DA4B1B302EFED0EF5A7D3AD74100E41C168ACBBF10EC5FFC497B43409D02D942C144408C32C83ED49334BC48FD1D446FDEBB71CA1F9276F3180ECA057E4B8F19FAFE368D0097EE2A5736D72BE661382939491A244B068D26A071E55E25DF2C8706ADEFD8245BC97A691AB57A8D39CE24469E9CC69198F4F795CACCB45053F464CA0C2F04C71E9CD6BB6D378E917C413B7FADEACD41A7A43E9A1FC04576658DBF7420A35252A899B51F9ED9B2D0B5534A696C2465C950EF5880636D96CC963AF6C314D00834969C45BE03F83F +20241205055343 2 6 100 8191 2 DC5E734609D91DA7E5180C89891C148715345D3A56F96DDFF41EE0B90992E9901E55850A78D9DF296A83F5AAF22675720E58E1F6D01F3B45315B818EF9CE880CE92F022763911796D4F86361BEB151ACB400BA017186C1DDCDE5F1853260ECF1082E072C2B7E2FD33E51B5076675269EC247AAE3DF3C1E6853E5D0E58FF7268255E91A9BF6FD43750F114BCA5DC70176ECACAF59C812798941D04FFFF200B53F9843066568A5EF6B324692239A9DC94383C53DA447D942BD51E17F51C22106DC3A2FC7A8942E20E5DA369D19124D184A96589E66EE15C4A8E4CB0FBB6B5E629875DEB3C6AAF622ABC4A4057E0B95533A03C94C514D2129CD6ECE739D9E3A98A54461DF577CC508BF4D5EE7FBE6178B248E3F51C59FE57BFBDE33DD833D0CF22DB22AE0F4F9F03EEF8E0E1DB0EDF7BB4C755148AD2D3FECED23DE1F028A3A6396D7F8F721D11023BD58335ADE175939E140A92C7B532A3D77168E566B7AADEA6F137A158AF3D2608FD4C1081018C1BC2B860A2830A097BDAFA96A3D5B5E1130D2C0778837C63ACBE958573B4ADAC2AE629D17728313AB9064D890006B2F0EC1869E35480B96651B9B3837B876190D5F1876A151A87C58A1CE2A9AD0744BE4CF955BFA9FA5653300FF6ECD64667ECD836D61DC3675048A8EB5AE945B50CB699F7FB4E36167515A2054199687DEC77D5117DF28B63F383403C49097F23AA4DE5857A0D865AFC7E4D0994B46386C20A41E9B41963CD425A82B30C4EE72FB3EFACD6C4090D740E44C196E51F41894FDB26142B72EF1E65A676C30EFB65C937C0F64CDEC167ECC16F0CAA3C932F3DD5C6F7A1EB073F03F2CB9F2059BE75EBAE32FA3170B5FA93D69CAB8275935686242E1F43ED23FE8784A0AD694442D35193DAAF5F7DA49B267B716C38F36C92AE7986DF8126904B11EA74323F3AB3AF436D64AC41996529AB95876EE4DF3739130460A50E2EC8463F2306454F08745CE40938858B6237A5D38B33FD6541BB98EFB39A7B0B501B7943FF594DF0964BF535CBD35105E35BA14C40E62D57F3B110AE82CD7F9FF73C3A28740C8EB397494F6D7CF5F0F147385424D70B276C6AD849E56C9985115EAF2CCF3D3A6C828F2A303178EC48BB08F36AF3800739E841F7B758FF06EFA10F6467E98DA4B1B302EFED0EF5A7D3AD74100E41C168ACBBF10EC5FFC497B43409D02D942C144408C32C83ED49334BC48FD1D446FDEBB71CA1F9276F3180ECA057E4B8F19FAFE368D0097EE2A5736D72BE661382939491A244B068D26A071E55E25DF2C8706ADEFD8245BC97A691AB57A8D39CE24469E9CC69198F4F795CACCB45053F464CA0C2F04C71E9CD6BB6D378E917C413B7FADEACD41A7A43E9A1FC04576658DBF7420A35252A899B51F9ED9B2D0B5534A696C2465C950EF5880636D96CC963AF6C314D00834969C45C44A5013 +20241205065151 2 6 100 8191 2 DC5E734609D91DA7E5180C89891C148715345D3A56F96DDFF41EE0B90992E9901E55850A78D9DF296A83F5AAF22675720E58E1F6D01F3B45315B818EF9CE880CE92F022763911796D4F86361BEB151ACB400BA017186C1DDCDE5F1853260ECF1082E072C2B7E2FD33E51B5076675269EC247AAE3DF3C1E6853E5D0E58FF7268255E91A9BF6FD43750F114BCA5DC70176ECACAF59C812798941D04FFFF200B53F9843066568A5EF6B324692239A9DC94383C53DA447D942BD51E17F51C22106DC3A2FC7A8942E20E5DA369D19124D184A96589E66EE15C4A8E4CB0FBB6B5E629875DEB3C6AAF622ABC4A4057E0B95533A03C94C514D2129CD6ECE739D9E3A98A54461DF577CC508BF4D5EE7FBE6178B248E3F51C59FE57BFBDE33DD833D0CF22DB22AE0F4F9F03EEF8E0E1DB0EDF7BB4C755148AD2D3FECED23DE1F028A3A6396D7F8F721D11023BD58335ADE175939E140A92C7B532A3D77168E566B7AADEA6F137A158AF3D2608FD4C1081018C1BC2B860A2830A097BDAFA96A3D5B5E1130D2C0778837C63ACBE958573B4ADAC2AE629D17728313AB9064D890006B2F0EC1869E35480B96651B9B3837B876190D5F1876A151A87C58A1CE2A9AD0744BE4CF955BFA9FA5653300FF6ECD64667ECD836D61DC3675048A8EB5AE945B50CB699F7FB4E36167515A2054199687DEC77D5117DF28B63F383403C49097F23AA4DE5857A0D865AFC7E4D0994B46386C20A41E9B41963CD425A82B30C4EE72FB3EFACD6C4090D740E44C196E51F41894FDB26142B72EF1E65A676C30EFB65C937C0F64CDEC167ECC16F0CAA3C932F3DD5C6F7A1EB073F03F2CB9F2059BE75EBAE32FA3170B5FA93D69CAB8275935686242E1F43ED23FE8784A0AD694442D35193DAAF5F7DA49B267B716C38F36C92AE7986DF8126904B11EA74323F3AB3AF436D64AC41996529AB95876EE4DF3739130460A50E2EC8463F2306454F08745CE40938858B6237A5D38B33FD6541BB98EFB39A7B0B501B7943FF594DF0964BF535CBD35105E35BA14C40E62D57F3B110AE82CD7F9FF73C3A28740C8EB397494F6D7CF5F0F147385424D70B276C6AD849E56C9985115EAF2CCF3D3A6C828F2A303178EC48BB08F36AF3800739E841F7B758FF06EFA10F6467E98DA4B1B302EFED0EF5A7D3AD74100E41C168ACBBF10EC5FFC497B43409D02D942C144408C32C83ED49334BC48FD1D446FDEBB71CA1F9276F3180ECA057E4B8F19FAFE368D0097EE2A5736D72BE661382939491A244B068D26A071E55E25DF2C8706ADEFD8245BC97A691AB57A8D39CE24469E9CC69198F4F795CACCB45053F464CA0C2F04C71E9CD6BB6D378E917C413B7FADEACD41A7A43E9A1FC04576658DBF7420A35252A899B51F9ED9B2D0B5534A696C2465C950EF5880636D96CC963AF6C314D00834969C45C77D34CB +20241205065416 2 6 100 8191 2 DC5E734609D91DA7E5180C89891C148715345D3A56F96DDFF41EE0B90992E9901E55850A78D9DF296A83F5AAF22675720E58E1F6D01F3B45315B818EF9CE880CE92F022763911796D4F86361BEB151ACB400BA017186C1DDCDE5F1853260ECF1082E072C2B7E2FD33E51B5076675269EC247AAE3DF3C1E6853E5D0E58FF7268255E91A9BF6FD43750F114BCA5DC70176ECACAF59C812798941D04FFFF200B53F9843066568A5EF6B324692239A9DC94383C53DA447D942BD51E17F51C22106DC3A2FC7A8942E20E5DA369D19124D184A96589E66EE15C4A8E4CB0FBB6B5E629875DEB3C6AAF622ABC4A4057E0B95533A03C94C514D2129CD6ECE739D9E3A98A54461DF577CC508BF4D5EE7FBE6178B248E3F51C59FE57BFBDE33DD833D0CF22DB22AE0F4F9F03EEF8E0E1DB0EDF7BB4C755148AD2D3FECED23DE1F028A3A6396D7F8F721D11023BD58335ADE175939E140A92C7B532A3D77168E566B7AADEA6F137A158AF3D2608FD4C1081018C1BC2B860A2830A097BDAFA96A3D5B5E1130D2C0778837C63ACBE958573B4ADAC2AE629D17728313AB9064D890006B2F0EC1869E35480B96651B9B3837B876190D5F1876A151A87C58A1CE2A9AD0744BE4CF955BFA9FA5653300FF6ECD64667ECD836D61DC3675048A8EB5AE945B50CB699F7FB4E36167515A2054199687DEC77D5117DF28B63F383403C49097F23AA4DE5857A0D865AFC7E4D0994B46386C20A41E9B41963CD425A82B30C4EE72FB3EFACD6C4090D740E44C196E51F41894FDB26142B72EF1E65A676C30EFB65C937C0F64CDEC167ECC16F0CAA3C932F3DD5C6F7A1EB073F03F2CB9F2059BE75EBAE32FA3170B5FA93D69CAB8275935686242E1F43ED23FE8784A0AD694442D35193DAAF5F7DA49B267B716C38F36C92AE7986DF8126904B11EA74323F3AB3AF436D64AC41996529AB95876EE4DF3739130460A50E2EC8463F2306454F08745CE40938858B6237A5D38B33FD6541BB98EFB39A7B0B501B7943FF594DF0964BF535CBD35105E35BA14C40E62D57F3B110AE82CD7F9FF73C3A28740C8EB397494F6D7CF5F0F147385424D70B276C6AD849E56C9985115EAF2CCF3D3A6C828F2A303178EC48BB08F36AF3800739E841F7B758FF06EFA10F6467E98DA4B1B302EFED0EF5A7D3AD74100E41C168ACBBF10EC5FFC497B43409D02D942C144408C32C83ED49334BC48FD1D446FDEBB71CA1F9276F3180ECA057E4B8F19FAFE368D0097EE2A5736D72BE661382939491A244B068D26A071E55E25DF2C8706ADEFD8245BC97A691AB57A8D39CE24469E9CC69198F4F795CACCB45053F464CA0C2F04C71E9CD6BB6D378E917C413B7FADEACD41A7A43E9A1FC04576658DBF7420A35252A899B51F9ED9B2D0B5534A696C2465C950EF5880636D96CC963AF6C314D00834969C45C79803AB +20241205074544 2 6 100 8191 5 DC5E734609D91DA7E5180C89891C148715345D3A56F96DDFF41EE0B90992E9901E55850A78D9DF296A83F5AAF22675720E58E1F6D01F3B45315B818EF9CE880CE92F022763911796D4F86361BEB151ACB400BA017186C1DDCDE5F1853260ECF1082E072C2B7E2FD33E51B5076675269EC247AAE3DF3C1E6853E5D0E58FF7268255E91A9BF6FD43750F114BCA5DC70176ECACAF59C812798941D04FFFF200B53F9843066568A5EF6B324692239A9DC94383C53DA447D942BD51E17F51C22106DC3A2FC7A8942E20E5DA369D19124D184A96589E66EE15C4A8E4CB0FBB6B5E629875DEB3C6AAF622ABC4A4057E0B95533A03C94C514D2129CD6ECE739D9E3A98A54461DF577CC508BF4D5EE7FBE6178B248E3F51C59FE57BFBDE33DD833D0CF22DB22AE0F4F9F03EEF8E0E1DB0EDF7BB4C755148AD2D3FECED23DE1F028A3A6396D7F8F721D11023BD58335ADE175939E140A92C7B532A3D77168E566B7AADEA6F137A158AF3D2608FD4C1081018C1BC2B860A2830A097BDAFA96A3D5B5E1130D2C0778837C63ACBE958573B4ADAC2AE629D17728313AB9064D890006B2F0EC1869E35480B96651B9B3837B876190D5F1876A151A87C58A1CE2A9AD0744BE4CF955BFA9FA5653300FF6ECD64667ECD836D61DC3675048A8EB5AE945B50CB699F7FB4E36167515A2054199687DEC77D5117DF28B63F383403C49097F23AA4DE5857A0D865AFC7E4D0994B46386C20A41E9B41963CD425A82B30C4EE72FB3EFACD6C4090D740E44C196E51F41894FDB26142B72EF1E65A676C30EFB65C937C0F64CDEC167ECC16F0CAA3C932F3DD5C6F7A1EB073F03F2CB9F2059BE75EBAE32FA3170B5FA93D69CAB8275935686242E1F43ED23FE8784A0AD694442D35193DAAF5F7DA49B267B716C38F36C92AE7986DF8126904B11EA74323F3AB3AF436D64AC41996529AB95876EE4DF3739130460A50E2EC8463F2306454F08745CE40938858B6237A5D38B33FD6541BB98EFB39A7B0B501B7943FF594DF0964BF535CBD35105E35BA14C40E62D57F3B110AE82CD7F9FF73C3A28740C8EB397494F6D7CF5F0F147385424D70B276C6AD849E56C9985115EAF2CCF3D3A6C828F2A303178EC48BB08F36AF3800739E841F7B758FF06EFA10F6467E98DA4B1B302EFED0EF5A7D3AD74100E41C168ACBBF10EC5FFC497B43409D02D942C144408C32C83ED49334BC48FD1D446FDEBB71CA1F9276F3180ECA057E4B8F19FAFE368D0097EE2A5736D72BE661382939491A244B068D26A071E55E25DF2C8706ADEFD8245BC97A691AB57A8D39CE24469E9CC69198F4F795CACCB45053F464CA0C2F04C71E9CD6BB6D378E917C413B7FADEACD41A7A43E9A1FC04576658DBF7420A35252A899B51F9ED9B2D0B5534A696C2465C950EF5880636D96CC963AF6C314D00834969C45CA71FBC7 +20241205081641 2 6 100 8191 2 DC5E734609D91DA7E5180C89891C148715345D3A56F96DDFF41EE0B90992E9901E55850A78D9DF296A83F5AAF22675720E58E1F6D01F3B45315B818EF9CE880CE92F022763911796D4F86361BEB151ACB400BA017186C1DDCDE5F1853260ECF1082E072C2B7E2FD33E51B5076675269EC247AAE3DF3C1E6853E5D0E58FF7268255E91A9BF6FD43750F114BCA5DC70176ECACAF59C812798941D04FFFF200B53F9843066568A5EF6B324692239A9DC94383C53DA447D942BD51E17F51C22106DC3A2FC7A8942E20E5DA369D19124D184A96589E66EE15C4A8E4CB0FBB6B5E629875DEB3C6AAF622ABC4A4057E0B95533A03C94C514D2129CD6ECE739D9E3A98A54461DF577CC508BF4D5EE7FBE6178B248E3F51C59FE57BFBDE33DD833D0CF22DB22AE0F4F9F03EEF8E0E1DB0EDF7BB4C755148AD2D3FECED23DE1F028A3A6396D7F8F721D11023BD58335ADE175939E140A92C7B532A3D77168E566B7AADEA6F137A158AF3D2608FD4C1081018C1BC2B860A2830A097BDAFA96A3D5B5E1130D2C0778837C63ACBE958573B4ADAC2AE629D17728313AB9064D890006B2F0EC1869E35480B96651B9B3837B876190D5F1876A151A87C58A1CE2A9AD0744BE4CF955BFA9FA5653300FF6ECD64667ECD836D61DC3675048A8EB5AE945B50CB699F7FB4E36167515A2054199687DEC77D5117DF28B63F383403C49097F23AA4DE5857A0D865AFC7E4D0994B46386C20A41E9B41963CD425A82B30C4EE72FB3EFACD6C4090D740E44C196E51F41894FDB26142B72EF1E65A676C30EFB65C937C0F64CDEC167ECC16F0CAA3C932F3DD5C6F7A1EB073F03F2CB9F2059BE75EBAE32FA3170B5FA93D69CAB8275935686242E1F43ED23FE8784A0AD694442D35193DAAF5F7DA49B267B716C38F36C92AE7986DF8126904B11EA74323F3AB3AF436D64AC41996529AB95876EE4DF3739130460A50E2EC8463F2306454F08745CE40938858B6237A5D38B33FD6541BB98EFB39A7B0B501B7943FF594DF0964BF535CBD35105E35BA14C40E62D57F3B110AE82CD7F9FF73C3A28740C8EB397494F6D7CF5F0F147385424D70B276C6AD849E56C9985115EAF2CCF3D3A6C828F2A303178EC48BB08F36AF3800739E841F7B758FF06EFA10F6467E98DA4B1B302EFED0EF5A7D3AD74100E41C168ACBBF10EC5FFC497B43409D02D942C144408C32C83ED49334BC48FD1D446FDEBB71CA1F9276F3180ECA057E4B8F19FAFE368D0097EE2A5736D72BE661382939491A244B068D26A071E55E25DF2C8706ADEFD8245BC97A691AB57A8D39CE24469E9CC69198F4F795CACCB45053F464CA0C2F04C71E9CD6BB6D378E917C413B7FADEACD41A7A43E9A1FC04576658DBF7420A35252A899B51F9ED9B2D0B5534A696C2465C950EF5880636D96CC963AF6C314D00834969C45CC1BDF6B +20241205092757 2 6 100 8191 2 DC5E734609D91DA7E5180C89891C148715345D3A56F96DDFF41EE0B90992E9901E55850A78D9DF296A83F5AAF22675720E58E1F6D01F3B45315B818EF9CE880CE92F022763911796D4F86361BEB151ACB400BA017186C1DDCDE5F1853260ECF1082E072C2B7E2FD33E51B5076675269EC247AAE3DF3C1E6853E5D0E58FF7268255E91A9BF6FD43750F114BCA5DC70176ECACAF59C812798941D04FFFF200B53F9843066568A5EF6B324692239A9DC94383C53DA447D942BD51E17F51C22106DC3A2FC7A8942E20E5DA369D19124D184A96589E66EE15C4A8E4CB0FBB6B5E629875DEB3C6AAF622ABC4A4057E0B95533A03C94C514D2129CD6ECE739D9E3A98A54461DF577CC508BF4D5EE7FBE6178B248E3F51C59FE57BFBDE33DD833D0CF22DB22AE0F4F9F03EEF8E0E1DB0EDF7BB4C755148AD2D3FECED23DE1F028A3A6396D7F8F721D11023BD58335ADE175939E140A92C7B532A3D77168E566B7AADEA6F137A158AF3D2608FD4C1081018C1BC2B860A2830A097BDAFA96A3D5B5E1130D2C0778837C63ACBE958573B4ADAC2AE629D17728313AB9064D890006B2F0EC1869E35480B96651B9B3837B876190D5F1876A151A87C58A1CE2A9AD0744BE4CF955BFA9FA5653300FF6ECD64667ECD836D61DC3675048A8EB5AE945B50CB699F7FB4E36167515A2054199687DEC77D5117DF28B63F383403C49097F23AA4DE5857A0D865AFC7E4D0994B46386C20A41E9B41963CD425A82B30C4EE72FB3EFACD6C4090D740E44C196E51F41894FDB26142B72EF1E65A676C30EFB65C937C0F64CDEC167ECC16F0CAA3C932F3DD5C6F7A1EB073F03F2CB9F2059BE75EBAE32FA3170B5FA93D69CAB8275935686242E1F43ED23FE8784A0AD694442D35193DAAF5F7DA49B267B716C38F36C92AE7986DF8126904B11EA74323F3AB3AF436D64AC41996529AB95876EE4DF3739130460A50E2EC8463F2306454F08745CE40938858B6237A5D38B33FD6541BB98EFB39A7B0B501B7943FF594DF0964BF535CBD35105E35BA14C40E62D57F3B110AE82CD7F9FF73C3A28740C8EB397494F6D7CF5F0F147385424D70B276C6AD849E56C9985115EAF2CCF3D3A6C828F2A303178EC48BB08F36AF3800739E841F7B758FF06EFA10F6467E98DA4B1B302EFED0EF5A7D3AD74100E41C168ACBBF10EC5FFC497B43409D02D942C144408C32C83ED49334BC48FD1D446FDEBB71CA1F9276F3180ECA057E4B8F19FAFE368D0097EE2A5736D72BE661382939491A244B068D26A071E55E25DF2C8706ADEFD8245BC97A691AB57A8D39CE24469E9CC69198F4F795CACCB45053F464CA0C2F04C71E9CD6BB6D378E917C413B7FADEACD41A7A43E9A1FC04576658DBF7420A35252A899B51F9ED9B2D0B5534A696C2465C950EF5880636D96CC963AF6C314D00834969C45CFFBAE8B +20241205110223 2 6 100 8191 2 DC5E734609D91DA7E5180C89891C148715345D3A56F96DDFF41EE0B90992E9901E55850A78D9DF296A83F5AAF22675720E58E1F6D01F3B45315B818EF9CE880CE92F022763911796D4F86361BEB151ACB400BA017186C1DDCDE5F1853260ECF1082E072C2B7E2FD33E51B5076675269EC247AAE3DF3C1E6853E5D0E58FF7268255E91A9BF6FD43750F114BCA5DC70176ECACAF59C812798941D04FFFF200B53F9843066568A5EF6B324692239A9DC94383C53DA447D942BD51E17F51C22106DC3A2FC7A8942E20E5DA369D19124D184A96589E66EE15C4A8E4CB0FBB6B5E629875DEB3C6AAF622ABC4A4057E0B95533A03C94C514D2129CD6ECE739D9E3A98A54461DF577CC508BF4D5EE7FBE6178B248E3F51C59FE57BFBDE33DD833D0CF22DB22AE0F4F9F03EEF8E0E1DB0EDF7BB4C755148AD2D3FECED23DE1F028A3A6396D7F8F721D11023BD58335ADE175939E140A92C7B532A3D77168E566B7AADEA6F137A158AF3D2608FD4C1081018C1BC2B860A2830A097BDAFA96A3D5B5E1130D2C0778837C63ACBE958573B4ADAC2AE629D17728313AB9064D890006B2F0EC1869E35480B96651B9B3837B876190D5F1876A151A87C58A1CE2A9AD0744BE4CF955BFA9FA5653300FF6ECD64667ECD836D61DC3675048A8EB5AE945B50CB699F7FB4E36167515A2054199687DEC77D5117DF28B63F383403C49097F23AA4DE5857A0D865AFC7E4D0994B46386C20A41E9B41963CD425A82B30C4EE72FB3EFACD6C4090D740E44C196E51F41894FDB26142B72EF1E65A676C30EFB65C937C0F64CDEC167ECC16F0CAA3C932F3DD5C6F7A1EB073F03F2CB9F2059BE75EBAE32FA3170B5FA93D69CAB8275935686242E1F43ED23FE8784A0AD694442D35193DAAF5F7DA49B267B716C38F36C92AE7986DF8126904B11EA74323F3AB3AF436D64AC41996529AB95876EE4DF3739130460A50E2EC8463F2306454F08745CE40938858B6237A5D38B33FD6541BB98EFB39A7B0B501B7943FF594DF0964BF535CBD35105E35BA14C40E62D57F3B110AE82CD7F9FF73C3A28740C8EB397494F6D7CF5F0F147385424D70B276C6AD849E56C9985115EAF2CCF3D3A6C828F2A303178EC48BB08F36AF3800739E841F7B758FF06EFA10F6467E98DA4B1B302EFED0EF5A7D3AD74100E41C168ACBBF10EC5FFC497B43409D02D942C144408C32C83ED49334BC48FD1D446FDEBB71CA1F9276F3180ECA057E4B8F19FAFE368D0097EE2A5736D72BE661382939491A244B068D26A071E55E25DF2C8706ADEFD8245BC97A691AB57A8D39CE24469E9CC69198F4F795CACCB45053F464CA0C2F04C71E9CD6BB6D378E917C413B7FADEACD41A7A43E9A1FC04576658DBF7420A35252A899B51F9ED9B2D0B5534A696C2465C950EF5880636D96CC963AF6C314D00834969C45D53D4193 +20241205112040 2 6 100 8191 5 DC5E734609D91DA7E5180C89891C148715345D3A56F96DDFF41EE0B90992E9901E55850A78D9DF296A83F5AAF22675720E58E1F6D01F3B45315B818EF9CE880CE92F022763911796D4F86361BEB151ACB400BA017186C1DDCDE5F1853260ECF1082E072C2B7E2FD33E51B5076675269EC247AAE3DF3C1E6853E5D0E58FF7268255E91A9BF6FD43750F114BCA5DC70176ECACAF59C812798941D04FFFF200B53F9843066568A5EF6B324692239A9DC94383C53DA447D942BD51E17F51C22106DC3A2FC7A8942E20E5DA369D19124D184A96589E66EE15C4A8E4CB0FBB6B5E629875DEB3C6AAF622ABC4A4057E0B95533A03C94C514D2129CD6ECE739D9E3A98A54461DF577CC508BF4D5EE7FBE6178B248E3F51C59FE57BFBDE33DD833D0CF22DB22AE0F4F9F03EEF8E0E1DB0EDF7BB4C755148AD2D3FECED23DE1F028A3A6396D7F8F721D11023BD58335ADE175939E140A92C7B532A3D77168E566B7AADEA6F137A158AF3D2608FD4C1081018C1BC2B860A2830A097BDAFA96A3D5B5E1130D2C0778837C63ACBE958573B4ADAC2AE629D17728313AB9064D890006B2F0EC1869E35480B96651B9B3837B876190D5F1876A151A87C58A1CE2A9AD0744BE4CF955BFA9FA5653300FF6ECD64667ECD836D61DC3675048A8EB5AE945B50CB699F7FB4E36167515A2054199687DEC77D5117DF28B63F383403C49097F23AA4DE5857A0D865AFC7E4D0994B46386C20A41E9B41963CD425A82B30C4EE72FB3EFACD6C4090D740E44C196E51F41894FDB26142B72EF1E65A676C30EFB65C937C0F64CDEC167ECC16F0CAA3C932F3DD5C6F7A1EB073F03F2CB9F2059BE75EBAE32FA3170B5FA93D69CAB8275935686242E1F43ED23FE8784A0AD694442D35193DAAF5F7DA49B267B716C38F36C92AE7986DF8126904B11EA74323F3AB3AF436D64AC41996529AB95876EE4DF3739130460A50E2EC8463F2306454F08745CE40938858B6237A5D38B33FD6541BB98EFB39A7B0B501B7943FF594DF0964BF535CBD35105E35BA14C40E62D57F3B110AE82CD7F9FF73C3A28740C8EB397494F6D7CF5F0F147385424D70B276C6AD849E56C9985115EAF2CCF3D3A6C828F2A303178EC48BB08F36AF3800739E841F7B758FF06EFA10F6467E98DA4B1B302EFED0EF5A7D3AD74100E41C168ACBBF10EC5FFC497B43409D02D942C144408C32C83ED49334BC48FD1D446FDEBB71CA1F9276F3180ECA057E4B8F19FAFE368D0097EE2A5736D72BE661382939491A244B068D26A071E55E25DF2C8706ADEFD8245BC97A691AB57A8D39CE24469E9CC69198F4F795CACCB45053F464CA0C2F04C71E9CD6BB6D378E917C413B7FADEACD41A7A43E9A1FC04576658DBF7420A35252A899B51F9ED9B2D0B5534A696C2465C950EF5880636D96CC963AF6C314D00834969C45D6362177 +20241205112359 2 6 100 8191 5 DC5E734609D91DA7E5180C89891C148715345D3A56F96DDFF41EE0B90992E9901E55850A78D9DF296A83F5AAF22675720E58E1F6D01F3B45315B818EF9CE880CE92F022763911796D4F86361BEB151ACB400BA017186C1DDCDE5F1853260ECF1082E072C2B7E2FD33E51B5076675269EC247AAE3DF3C1E6853E5D0E58FF7268255E91A9BF6FD43750F114BCA5DC70176ECACAF59C812798941D04FFFF200B53F9843066568A5EF6B324692239A9DC94383C53DA447D942BD51E17F51C22106DC3A2FC7A8942E20E5DA369D19124D184A96589E66EE15C4A8E4CB0FBB6B5E629875DEB3C6AAF622ABC4A4057E0B95533A03C94C514D2129CD6ECE739D9E3A98A54461DF577CC508BF4D5EE7FBE6178B248E3F51C59FE57BFBDE33DD833D0CF22DB22AE0F4F9F03EEF8E0E1DB0EDF7BB4C755148AD2D3FECED23DE1F028A3A6396D7F8F721D11023BD58335ADE175939E140A92C7B532A3D77168E566B7AADEA6F137A158AF3D2608FD4C1081018C1BC2B860A2830A097BDAFA96A3D5B5E1130D2C0778837C63ACBE958573B4ADAC2AE629D17728313AB9064D890006B2F0EC1869E35480B96651B9B3837B876190D5F1876A151A87C58A1CE2A9AD0744BE4CF955BFA9FA5653300FF6ECD64667ECD836D61DC3675048A8EB5AE945B50CB699F7FB4E36167515A2054199687DEC77D5117DF28B63F383403C49097F23AA4DE5857A0D865AFC7E4D0994B46386C20A41E9B41963CD425A82B30C4EE72FB3EFACD6C4090D740E44C196E51F41894FDB26142B72EF1E65A676C30EFB65C937C0F64CDEC167ECC16F0CAA3C932F3DD5C6F7A1EB073F03F2CB9F2059BE75EBAE32FA3170B5FA93D69CAB8275935686242E1F43ED23FE8784A0AD694442D35193DAAF5F7DA49B267B716C38F36C92AE7986DF8126904B11EA74323F3AB3AF436D64AC41996529AB95876EE4DF3739130460A50E2EC8463F2306454F08745CE40938858B6237A5D38B33FD6541BB98EFB39A7B0B501B7943FF594DF0964BF535CBD35105E35BA14C40E62D57F3B110AE82CD7F9FF73C3A28740C8EB397494F6D7CF5F0F147385424D70B276C6AD849E56C9985115EAF2CCF3D3A6C828F2A303178EC48BB08F36AF3800739E841F7B758FF06EFA10F6467E98DA4B1B302EFED0EF5A7D3AD74100E41C168ACBBF10EC5FFC497B43409D02D942C144408C32C83ED49334BC48FD1D446FDEBB71CA1F9276F3180ECA057E4B8F19FAFE368D0097EE2A5736D72BE661382939491A244B068D26A071E55E25DF2C8706ADEFD8245BC97A691AB57A8D39CE24469E9CC69198F4F795CACCB45053F464CA0C2F04C71E9CD6BB6D378E917C413B7FADEACD41A7A43E9A1FC04576658DBF7420A35252A899B51F9ED9B2D0B5534A696C2465C950EF5880636D96CC963AF6C314D00834969C45D65CAD37 +20241205134041 2 6 100 8191 5 DC5E734609D91DA7E5180C89891C148715345D3A56F96DDFF41EE0B90992E9901E55850A78D9DF296A83F5AAF22675720E58E1F6D01F3B45315B818EF9CE880CE92F022763911796D4F86361BEB151ACB400BA017186C1DDCDE5F1853260ECF1082E072C2B7E2FD33E51B5076675269EC247AAE3DF3C1E6853E5D0E58FF7268255E91A9BF6FD43750F114BCA5DC70176ECACAF59C812798941D04FFFF200B53F9843066568A5EF6B324692239A9DC94383C53DA447D942BD51E17F51C22106DC3A2FC7A8942E20E5DA369D19124D184A96589E66EE15C4A8E4CB0FBB6B5E629875DEB3C6AAF622ABC4A4057E0B95533A03C94C514D2129CD6ECE739D9E3A98A54461DF577CC508BF4D5EE7FBE6178B248E3F51C59FE57BFBDE33DD833D0CF22DB22AE0F4F9F03EEF8E0E1DB0EDF7BB4C755148AD2D3FECED23DE1F028A3A6396D7F8F721D11023BD58335ADE175939E140A92C7B532A3D77168E566B7AADEA6F137A158AF3D2608FD4C1081018C1BC2B860A2830A097BDAFA96A3D5B5E1130D2C0778837C63ACBE958573B4ADAC2AE629D17728313AB9064D890006B2F0EC1869E35480B96651B9B3837B876190D5F1876A151A87C58A1CE2A9AD0744BE4CF955BFA9FA5653300FF6ECD64667ECD836D61DC3675048A8EB5AE945B50CB699F7FB4E36167515A2054199687DEC77D5117DF28B63F383403C49097F23AA4DE5857A0D865AFC7E4D0994B46386C20A41E9B41963CD425A82B30C4EE72FB3EFACD6C4090D740E44C196E51F41894FDB26142B72EF1E65A676C30EFB65C937C0F64CDEC167ECC16F0CAA3C932F3DD5C6F7A1EB073F03F2CB9F2059BE75EBAE32FA3170B5FA93D69CAB8275935686242E1F43ED23FE8784A0AD694442D35193DAAF5F7DA49B267B716C38F36C92AE7986DF8126904B11EA74323F3AB3AF436D64AC41996529AB95876EE4DF3739130460A50E2EC8463F2306454F08745CE40938858B6237A5D38B33FD6541BB98EFB39A7B0B501B7943FF594DF0964BF535CBD35105E35BA14C40E62D57F3B110AE82CD7F9FF73C3A28740C8EB397494F6D7CF5F0F147385424D70B276C6AD849E56C9985115EAF2CCF3D3A6C828F2A303178EC48BB08F36AF3800739E841F7B758FF06EFA10F6467E98DA4B1B302EFED0EF5A7D3AD74100E41C168ACBBF10EC5FFC497B43409D02D942C144408C32C83ED49334BC48FD1D446FDEBB71CA1F9276F3180ECA057E4B8F19FAFE368D0097EE2A5736D72BE661382939491A244B068D26A071E55E25DF2C8706ADEFD8245BC97A691AB57A8D39CE24469E9CC69198F4F795CACCB45053F464CA0C2F04C71E9CD6BB6D378E917C413B7FADEACD41A7A43E9A1FC04576658DBF7420A35252A899B51F9ED9B2D0B5534A696C2465C950EF5880636D96CC963AF6C314D00834969C45DDF2FF47 +20241205135041 2 6 100 8191 2 DC5E734609D91DA7E5180C89891C148715345D3A56F96DDFF41EE0B90992E9901E55850A78D9DF296A83F5AAF22675720E58E1F6D01F3B45315B818EF9CE880CE92F022763911796D4F86361BEB151ACB400BA017186C1DDCDE5F1853260ECF1082E072C2B7E2FD33E51B5076675269EC247AAE3DF3C1E6853E5D0E58FF7268255E91A9BF6FD43750F114BCA5DC70176ECACAF59C812798941D04FFFF200B53F9843066568A5EF6B324692239A9DC94383C53DA447D942BD51E17F51C22106DC3A2FC7A8942E20E5DA369D19124D184A96589E66EE15C4A8E4CB0FBB6B5E629875DEB3C6AAF622ABC4A4057E0B95533A03C94C514D2129CD6ECE739D9E3A98A54461DF577CC508BF4D5EE7FBE6178B248E3F51C59FE57BFBDE33DD833D0CF22DB22AE0F4F9F03EEF8E0E1DB0EDF7BB4C755148AD2D3FECED23DE1F028A3A6396D7F8F721D11023BD58335ADE175939E140A92C7B532A3D77168E566B7AADEA6F137A158AF3D2608FD4C1081018C1BC2B860A2830A097BDAFA96A3D5B5E1130D2C0778837C63ACBE958573B4ADAC2AE629D17728313AB9064D890006B2F0EC1869E35480B96651B9B3837B876190D5F1876A151A87C58A1CE2A9AD0744BE4CF955BFA9FA5653300FF6ECD64667ECD836D61DC3675048A8EB5AE945B50CB699F7FB4E36167515A2054199687DEC77D5117DF28B63F383403C49097F23AA4DE5857A0D865AFC7E4D0994B46386C20A41E9B41963CD425A82B30C4EE72FB3EFACD6C4090D740E44C196E51F41894FDB26142B72EF1E65A676C30EFB65C937C0F64CDEC167ECC16F0CAA3C932F3DD5C6F7A1EB073F03F2CB9F2059BE75EBAE32FA3170B5FA93D69CAB8275935686242E1F43ED23FE8784A0AD694442D35193DAAF5F7DA49B267B716C38F36C92AE7986DF8126904B11EA74323F3AB3AF436D64AC41996529AB95876EE4DF3739130460A50E2EC8463F2306454F08745CE40938858B6237A5D38B33FD6541BB98EFB39A7B0B501B7943FF594DF0964BF535CBD35105E35BA14C40E62D57F3B110AE82CD7F9FF73C3A28740C8EB397494F6D7CF5F0F147385424D70B276C6AD849E56C9985115EAF2CCF3D3A6C828F2A303178EC48BB08F36AF3800739E841F7B758FF06EFA10F6467E98DA4B1B302EFED0EF5A7D3AD74100E41C168ACBBF10EC5FFC497B43409D02D942C144408C32C83ED49334BC48FD1D446FDEBB71CA1F9276F3180ECA057E4B8F19FAFE368D0097EE2A5736D72BE661382939491A244B068D26A071E55E25DF2C8706ADEFD8245BC97A691AB57A8D39CE24469E9CC69198F4F795CACCB45053F464CA0C2F04C71E9CD6BB6D378E917C413B7FADEACD41A7A43E9A1FC04576658DBF7420A35252A899B51F9ED9B2D0B5534A696C2465C950EF5880636D96CC963AF6C314D00834969C45DE752163 diff --git a/moduli.0 b/moduli.0 index f72ca52..90700a1 100644 --- a/moduli.0 +++ b/moduli.0 @@ -71,4 +71,4 @@ STANDARDS M. Friedl, N. Provos, and W. Simpson, Diffie-Hellman Group Exchange for the Secure Shell (SSH) Transport Layer Protocol, RFC 4419, March 2006. -OpenBSD 7.6 April 16, 2022 OpenBSD 7.6 +OpenBSD 7.7 April 16, 2022 OpenBSD 7.7 diff --git a/moduli.c b/moduli.c index 481ca2a..999a909 100644 --- a/moduli.c +++ b/moduli.c @@ -1,4 +1,4 @@ -/* $OpenBSD: moduli.c,v 1.39 2023/03/02 06:41:56 dtucker Exp $ */ +/* $OpenBSD: moduli.c,v 1.40 2025/05/24 03:39:48 dtucker Exp $ */ /* * Copyright 1994 Phil Karn * Copyright 1996-1998, 2003 William Allen Simpson @@ -87,13 +87,6 @@ #define SHIFT_MEGABYTE (20) #define SHIFT_MEGAWORD (SHIFT_MEGABYTE-SHIFT_BYTE) -/* - * Using virtual memory can cause thrashing. This should be the largest - * number that is supported without a large amount of disk activity -- - * that would increase the run time from hours to days or weeks! - */ -#define LARGE_MINIMUM (8UL) /* megabytes */ - /* * Do not increase this number beyond the unsigned integer bit size. * Due to a multiple of 4, it must be LESS than 128 (yielding 2**30 bits). @@ -142,7 +135,7 @@ static u_int32_t *LargeSieve, largewords, largetries, largenumbers; static u_int32_t largebits, largememory; /* megabytes */ static BIGNUM *largebase; -int gen_candidates(FILE *, u_int32_t, u_int32_t, BIGNUM *); +int gen_candidates(FILE *, u_int32_t, BIGNUM *); int prime_test(FILE *, FILE *, u_int32_t, u_int32_t, char *, unsigned long, unsigned long); @@ -242,7 +235,7 @@ sieve_large(u_int32_t s32) * The list is checked against small known primes (less than 2**30). */ int -gen_candidates(FILE *out, u_int32_t memory, u_int32_t power, BIGNUM *start) +gen_candidates(FILE *out, u_int32_t power, BIGNUM *start) { BIGNUM *q; u_int32_t j, r, s, t; @@ -252,15 +245,6 @@ gen_candidates(FILE *out, u_int32_t memory, u_int32_t power, BIGNUM *start) u_int32_t i; int ret = 0; - largememory = memory; - - if (memory != 0 && - (memory < LARGE_MINIMUM || memory > LARGE_MAXIMUM)) { - error("Invalid memory amount (min %ld, max %ld)", - LARGE_MINIMUM, LARGE_MAXIMUM); - return (-1); - } - /* * Set power to the length in bits of the prime to be generated. * This is changed to 1 less than the desired safe prime moduli p. @@ -274,33 +258,9 @@ gen_candidates(FILE *out, u_int32_t memory, u_int32_t power, BIGNUM *start) } power--; /* decrement before squaring */ - /* - * The density of ordinary primes is on the order of 1/bits, so the - * density of safe primes should be about (1/bits)**2. Set test range - * to something well above bits**2 to be reasonably sure (but not - * guaranteed) of catching at least one safe prime. - */ - largewords = ((power * power) >> (SHIFT_WORD - TEST_POWER)); - - /* - * Need idea of how much memory is available. We don't have to use all - * of it. - */ - if (largememory > LARGE_MAXIMUM) { - logit("Limited memory: %u MB; limit %lu MB", - largememory, LARGE_MAXIMUM); - largememory = LARGE_MAXIMUM; - } - - if (largewords <= (largememory << SHIFT_MEGAWORD)) { - logit("Increased memory: %u MB; need %u bytes", - largememory, (largewords << SHIFT_BYTE)); - largewords = (largememory << SHIFT_MEGAWORD); - } else if (largememory > 0) { - logit("Decreased memory: %u MB; want %u bytes", - largememory, (largewords << SHIFT_BYTE)); - largewords = (largememory << SHIFT_MEGAWORD); - } + /* Always use the maximum amount of memory supported by the algorithm. */ + largememory = LARGE_MAXIMUM; + largewords = (largememory << SHIFT_MEGAWORD); TinySieve = xcalloc(tinywords, sizeof(u_int32_t)); tinybits = tinywords << SHIFT_WORD; @@ -308,12 +268,7 @@ gen_candidates(FILE *out, u_int32_t memory, u_int32_t power, BIGNUM *start) SmallSieve = xcalloc(smallwords, sizeof(u_int32_t)); smallbits = smallwords << SHIFT_WORD; - /* - * dynamically determine available memory - */ - while ((LargeSieve = calloc(largewords, sizeof(u_int32_t))) == NULL) - largewords -= (1L << (SHIFT_MEGAWORD - 2)); /* 1/4 MB chunks */ - + LargeSieve = xcalloc(largewords, sizeof(u_int32_t)); largebits = largewords << SHIFT_WORD; largenumbers = largebits * 2; /* even numbers excluded */ diff --git a/monitor.c b/monitor.c index 5966b4f..a9e854b 100644 --- a/monitor.c +++ b/monitor.c @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor.c,v 1.244 2024/09/15 01:09:40 djm Exp $ */ +/* $OpenBSD: monitor.c,v 1.249 2025/09/25 06:45:50 djm Exp $ */ /* * Copyright 2002 Niels Provos * Copyright 2002 Markus Friedl @@ -34,26 +34,16 @@ #include #include #include -#ifdef HAVE_PATHS_H #include -#endif #include #include -#ifdef HAVE_STDINT_H -# include -#endif +#include #include #include #include #include #include -#ifdef HAVE_POLL_H #include -#else -# ifdef HAVE_SYS_POLL_H -# include -# endif -#endif #ifdef WITH_OPENSSL #include @@ -105,7 +95,9 @@ static Gssctxt *gsscontext = NULL; /* Imports */ extern ServerOptions options; extern u_int utmp_len; +extern struct sshbuf *cfg; extern struct sshbuf *loginmsg; +extern struct include_list includes; extern struct sshauthopt *auth_opts; /* XXX move to permanent ssh->authctxt? */ /* State exported from the child */ @@ -126,6 +118,7 @@ int mm_answer_keyverify(struct ssh *, int, struct sshbuf *); int mm_answer_pty(struct ssh *, int, struct sshbuf *); int mm_answer_pty_cleanup(struct ssh *, int, struct sshbuf *); int mm_answer_term(struct ssh *, int, struct sshbuf *); +int mm_answer_state(struct ssh *, int, struct sshbuf *); #ifdef USE_PAM int mm_answer_pam_start(struct ssh *, int, struct sshbuf *); @@ -184,6 +177,7 @@ static int monitor_read(struct ssh *, struct monitor *, struct mon_table *, static int monitor_read_log(struct monitor *); struct mon_table mon_dispatch_proto20[] = { + {MONITOR_REQ_STATE, MON_ONCE, mm_answer_state}, #ifdef WITH_OPENSSL {MONITOR_REQ_MODULI, MON_ONCE, mm_answer_moduli}, #endif @@ -219,6 +213,7 @@ struct mon_table mon_dispatch_proto20[] = { }; struct mon_table mon_dispatch_postauth20[] = { + {MONITOR_REQ_STATE, MON_ONCE, mm_answer_state}, #ifdef WITH_OPENSSL {MONITOR_REQ_MODULI, 0, mm_answer_moduli}, #endif @@ -267,7 +262,7 @@ void monitor_child_preauth(struct ssh *ssh, struct monitor *pmonitor) { struct mon_table *ent; - int authenticated = 0, partial = 0; + int status, authenticated = 0, partial = 0; debug3("preauth child monitor started"); @@ -284,7 +279,8 @@ monitor_child_preauth(struct ssh *ssh, struct monitor *pmonitor) authctxt->loginmsg = loginmsg; mon_dispatch = mon_dispatch_proto20; - /* Permit requests for moduli and signatures */ + /* Permit requests for state, moduli and signatures */ + monitor_permit(mon_dispatch, MONITOR_REQ_STATE, 1); monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); @@ -369,11 +365,29 @@ monitor_child_preauth(struct ssh *ssh, struct monitor *pmonitor) while (pmonitor->m_log_recvfd != -1 && monitor_read_log(pmonitor) == 0) ; + /* Wait for the child's exit status */ + while (waitpid(pmonitor->m_pid, &status, 0) == -1) { + if (errno == EINTR) + continue; + fatal_f("waitpid: %s", strerror(errno)); + } + if (WIFEXITED(status)) { + if (WEXITSTATUS(status) != 0) + fatal_f("preauth child %ld exited with status %d", + (long)pmonitor->m_pid, WEXITSTATUS(status)); + } else if (WIFSIGNALED(status)) { + fatal_f("preauth child %ld terminated by signal %d", + (long)pmonitor->m_pid, WTERMSIG(status)); + } + debug3_f("preauth child %ld terminated successfully", + (long)pmonitor->m_pid); + if (pmonitor->m_recvfd >= 0) close(pmonitor->m_recvfd); if (pmonitor->m_log_sendfd >= 0) close(pmonitor->m_log_sendfd); pmonitor->m_sendfd = pmonitor->m_log_recvfd = -1; + pmonitor->m_pid = -1; } static void @@ -405,6 +419,7 @@ monitor_child_postauth(struct ssh *ssh, struct monitor *pmonitor) mon_dispatch = mon_dispatch_postauth20; /* Permit requests for moduli and signatures */ + monitor_permit(mon_dispatch, MONITOR_REQ_STATE, 1); monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); @@ -462,7 +477,8 @@ monitor_read_log(struct monitor *pmonitor) /* Log it */ if (log_level_name(level) == NULL) fatal_f("invalid log level %u (corrupted message?)", level); - sshlogdirect(level, forced, "%s [preauth]", msg); + sshlogdirect(level, forced, "%s [%s]", msg, + mon_dispatch == mon_dispatch_postauth20 ? "postauth" : "preauth"); sshbuf_free(logmsg); free(msg); @@ -568,6 +584,81 @@ monitor_reset_key_state(void) hostbased_chost = NULL; } +int +mm_answer_state(struct ssh *ssh, int sock, struct sshbuf *unused) +{ + struct sshbuf *m = NULL, *inc = NULL, *hostkeys = NULL; + struct sshbuf *opts = NULL, *confdata = NULL; + struct include_item *item = NULL; + int postauth; + int r; + + debug_f("config len %zu", sshbuf_len(cfg)); + + if ((m = sshbuf_new()) == NULL || + (inc = sshbuf_new()) == NULL || + (opts = sshbuf_new()) == NULL || + (confdata = sshbuf_new()) == NULL) + fatal_f("sshbuf_new failed"); + + /* XXX unnecessary? */ + /* 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"); + } + + hostkeys = pack_hostkeys(); + + /* + * Protocol from monitor to unpriv privsep process: + * string configuration + * uint64 timing_secret XXX move delays to monitor and remove + * string host_keys[] { + * string public_key + * string certificate + * } + * string server_banner + * string client_banner + * string included_files[] { + * string selector + * string filename + * string contents + * } + * string configuration_data (postauth) + * string keystate (postauth) + * string authenticated_user (postauth) + * string session_info (postauth) + * string authopts (postauth) + */ + if ((r = sshbuf_put_stringb(m, cfg)) != 0 || + (r = sshbuf_put_u64(m, options.timing_secret)) != 0 || + (r = sshbuf_put_stringb(m, hostkeys)) != 0 || + (r = sshbuf_put_stringb(m, ssh->kex->server_version)) != 0 || + (r = sshbuf_put_stringb(m, ssh->kex->client_version)) != 0 || + (r = sshbuf_put_stringb(m, inc)) != 0) + fatal_fr(r, "compose config"); + + postauth = (authctxt && authctxt->pw && authctxt->authenticated); + if (postauth) { + /* XXX shouldn't be reachable */ + fatal_f("internal error: called in postauth"); + } + + sshbuf_free(inc); + sshbuf_free(opts); + sshbuf_free(confdata); + sshbuf_free(hostkeys); + + mm_request_send(sock, MONITOR_ANS_STATE, m); + sshbuf_free(m); + debug3_f("done"); + + return (0); +} + #ifdef WITH_OPENSSL int mm_answer_moduli(struct ssh *ssh, int sock, struct sshbuf *m) @@ -613,24 +704,27 @@ int mm_answer_sign(struct ssh *ssh, int sock, struct sshbuf *m) { extern int auth_sock; /* XXX move to state struct? */ - struct sshkey *key; + struct sshkey *pubkey, *key; struct sshbuf *sigbuf = NULL; u_char *p = NULL, *signature = NULL; char *alg = NULL; - size_t datlen, siglen, alglen; - int r, is_proof = 0; - u_int keyid, compat; + size_t datlen, siglen; + int r, is_proof = 0, keyid; + u_int compat; const char proof_req[] = "hostkeys-prove-00@openssh.com"; debug3_f("entering"); - if ((r = sshbuf_get_u32(m, &keyid)) != 0 || + if ((r = sshkey_froms(m, &pubkey)) != 0 || (r = sshbuf_get_string(m, &p, &datlen)) != 0 || - (r = sshbuf_get_cstring(m, &alg, &alglen)) != 0 || + (r = sshbuf_get_cstring(m, &alg, NULL)) != 0 || (r = sshbuf_get_u32(m, &compat)) != 0) fatal_fr(r, "parse"); - if (keyid > INT_MAX) - fatal_f("invalid key ID"); + + if ((keyid = get_hostkey_index(pubkey, 1, ssh)) == -1) + fatal_f("unknown hostkey"); + debug_f("hostkey %s index %d", sshkey_ssh_name(pubkey), keyid); + sshkey_free(pubkey); /* * Supported KEX types use SHA1 (20 bytes), SHA256 (32 bytes), @@ -924,7 +1018,6 @@ mm_answer_authpassword(struct ssh *ssh, int sock, struct sshbuf *m) fatal_fr(r, "assemble PAM"); #endif - debug3("%s: sending result %d", __func__, authenticated); debug3_f("sending result %d", authenticated); mm_request_send(sock, MONITOR_ANS_AUTHPASSWORD, m); @@ -1011,7 +1104,7 @@ int mm_answer_pam_start(struct ssh *ssh, int sock, struct sshbuf *m) { if (!options.use_pam) - fatal("UsePAM not set, but ended up in %s anyway", __func__); + fatal_f("UsePAM not set, but ended up in %s anyway", __func__); start_pam(ssh); @@ -1029,13 +1122,13 @@ mm_answer_pam_account(struct ssh *ssh, int sock, struct sshbuf *m) int r; if (!options.use_pam) - fatal("%s: PAM not enabled", __func__); + fatal_f("PAM not enabled"); ret = do_pam_account(); if ((r = sshbuf_put_u32(m, ret)) != 0 || (r = sshbuf_put_stringb(m, loginmsg)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "buffer error"); mm_request_send(sock, MONITOR_ANS_PAM_ACCOUNT, m); @@ -1051,11 +1144,11 @@ mm_answer_pam_init_ctx(struct ssh *ssh, int sock, struct sshbuf *m) u_int ok = 0; int r; - debug3("%s", __func__); + debug3_f("entering"); if (!options.kbd_interactive_authentication) - fatal("%s: kbd-int authentication not enabled", __func__); + fatal_f("kbd-int authentication not enabled"); if (sshpam_ctxt != NULL) - fatal("%s: already called", __func__); + fatal_f("already called"); sshpam_ctxt = (sshpam_device.init_ctx)(authctxt); sshpam_authok = NULL; sshbuf_reset(m); @@ -1065,7 +1158,7 @@ mm_answer_pam_init_ctx(struct ssh *ssh, int sock, struct sshbuf *m) ok = 1; } if ((r = sshbuf_put_u32(m, ok)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "buffer error"); mm_request_send(sock, MONITOR_ANS_PAM_INIT_CTX, m); return (0); } @@ -1077,10 +1170,10 @@ mm_answer_pam_query(struct ssh *ssh, int sock, struct sshbuf *m) u_int i, num = 0, *echo_on = 0; int r, ret; - debug3("%s", __func__); + debug3_f("entering"); sshpam_authok = NULL; if (sshpam_ctxt == NULL) - fatal("%s: no context", __func__); + fatal_f("no context"); ret = (sshpam_device.query)(sshpam_ctxt, &name, &info, &num, &prompts, &echo_on); if (ret == 0 && num == 0) @@ -1094,13 +1187,13 @@ mm_answer_pam_query(struct ssh *ssh, int sock, struct sshbuf *m) (r = sshbuf_put_cstring(m, info)) != 0 || (r = sshbuf_put_u32(m, sshpam_get_maxtries_reached())) != 0 || (r = sshbuf_put_u32(m, num)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "buffer error"); free(name); free(info); for (i = 0; i < num; ++i) { if ((r = sshbuf_put_cstring(m, prompts[i])) != 0 || (r = sshbuf_put_u32(m, echo_on[i])) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "buffer error"); free(prompts[i]); } free(prompts); @@ -1118,12 +1211,12 @@ mm_answer_pam_respond(struct ssh *ssh, int sock, struct sshbuf *m) u_int i, num; int r, ret; - debug3("%s", __func__); + debug3_f("entering"); if (sshpam_ctxt == NULL) - fatal("%s: no context", __func__); + fatal_f("no context"); sshpam_authok = NULL; if ((r = sshbuf_get_u32(m, &num)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "buffer error"); if (num > PAM_MAX_NUM_MSG) { fatal_f("Too many PAM messages, got %u, expected <= %u", num, (unsigned)PAM_MAX_NUM_MSG); @@ -1144,7 +1237,7 @@ mm_answer_pam_respond(struct ssh *ssh, int sock, struct sshbuf *m) } sshbuf_reset(m); if ((r = sshbuf_put_u32(m, ret)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "buffer error"); mm_request_send(sock, MONITOR_ANS_PAM_RESPOND, m); auth_method = "keyboard-interactive"; auth_submethod = "pam"; @@ -1158,9 +1251,9 @@ mm_answer_pam_free_ctx(struct ssh *ssh, int sock, struct sshbuf *m) { int r = sshpam_authok != NULL && sshpam_authok == sshpam_ctxt; - debug3("%s", __func__); + debug3_f("entering"); if (sshpam_ctxt == NULL) - fatal("%s: no context", __func__); + fatal_f("no context"); (sshpam_device.free_ctx)(sshpam_ctxt); sshpam_ctxt = sshpam_authok = NULL; sshbuf_reset(m); @@ -1691,10 +1784,10 @@ mm_answer_audit_event(struct ssh *ssh, int socket, struct sshbuf *m) ssh_audit_event_t event; int r; - debug3("%s entering", __func__); + debug3_f("entering"); if ((r = sshbuf_get_u32(m, &n)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "buffer error"); event = (ssh_audit_event_t)n; switch (event) { case SSH_AUTH_FAIL_PUBKEY: @@ -1719,9 +1812,9 @@ mm_answer_audit_command(struct ssh *ssh, int socket, struct sshbuf *m) char *cmd; int r; - debug3("%s entering", __func__); + debug3_f("entering"); if ((r = sshbuf_get_cstring(m, &cmd, NULL)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "buffer error"); /* sanity check command, if so how? */ audit_run_command(cmd); free(cmd); @@ -1834,8 +1927,6 @@ monitor_openfds(struct monitor *mon, int do_logfds) mon->m_log_recvfd = mon->m_log_sendfd = -1; } -#define MM_MEMSIZE 65536 - struct monitor * monitor_init(void) { diff --git a/monitor.h b/monitor.h index fa48fc6..3f8a9be 100644 --- a/monitor.h +++ b/monitor.h @@ -54,6 +54,7 @@ enum monitor_reqtype { MONITOR_REQ_GSSUSEROK = 46, MONITOR_ANS_GSSUSEROK = 47, MONITOR_REQ_GSSCHECKMIC = 48, MONITOR_ANS_GSSCHECKMIC = 49, MONITOR_REQ_TERM = 50, + MONITOR_REQ_STATE = 51, MONITOR_ANS_STATE = 52, MONITOR_REQ_PAM_START = 100, MONITOR_REQ_PAM_ACCOUNT = 102, MONITOR_ANS_PAM_ACCOUNT = 103, @@ -96,4 +97,6 @@ void mm_get_keystate(struct ssh *, struct monitor *); /* XXX: should be returned via a monitor call rather than config_fd */ void mm_encode_server_options(struct sshbuf *); +struct sshbuf *pack_hostkeys(void); + #endif /* _MONITOR_H_ */ diff --git a/monitor_fdpass.c b/monitor_fdpass.c index a07727a..21697ca 100644 --- a/monitor_fdpass.c +++ b/monitor_fdpass.c @@ -29,21 +29,13 @@ #include #include #include -#ifdef HAVE_SYS_UN_H #include -#endif #include #include #include -#ifdef HAVE_POLL_H -# include -#else -# ifdef HAVE_SYS_POLL_H -# include -# endif -#endif +#include #include "log.h" #include "monitor_fdpass.h" @@ -103,7 +95,7 @@ mm_send_fd(int sock, int fd) } return 0; #else - error("%s: file descriptor passing not supported", __func__); + error_f("file descriptor passing not supported"); return -1; #endif } diff --git a/monitor_wrap.c b/monitor_wrap.c index 5358c77..33494b7 100644 --- a/monitor_wrap.c +++ b/monitor_wrap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor_wrap.c,v 1.136 2024/06/19 23:24:47 djm Exp $ */ +/* $OpenBSD: monitor_wrap.c,v 1.142 2025/09/25 06:31:42 djm Exp $ */ /* * Copyright 2002 Niels Provos * Copyright 2002 Markus Friedl @@ -111,16 +111,6 @@ mm_log_handler(LogLevel level, int forced, const char *msg, void *ctx) 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); -} - static void mm_reap(void) { @@ -136,17 +126,17 @@ mm_reap(void) } if (WIFEXITED(status)) { if (WEXITSTATUS(status) != 0) { - debug_f("preauth child exited with status %d", + debug_f("child exited with status %d", WEXITSTATUS(status)); cleanup_exit(255); } } else if (WIFSIGNALED(status)) { - error_f("preauth child terminated by signal %d", + error_f("child terminated by signal %d", WTERMSIG(status)); cleanup_exit(signal_is_crash(WTERMSIG(status)) ? EXIT_CHILD_CRASH : 255); } else { - error_f("preauth child terminated abnormally (status=0x%x)", + error_f("child terminated abnormally (status=0x%x)", status); cleanup_exit(EXIT_CHILD_CRASH); } @@ -160,7 +150,7 @@ mm_request_send(int sock, enum monitor_reqtype type, struct sshbuf *m) debug3_f("entering, type %d", type); - if (mlen >= 0xffffffff) + if (mlen >= MONITOR_MAX_MSGLEN) fatal_f("bad length %zu", mlen); POKE_U32(buf, mlen + 1); buf[4] = (u_char) type; /* 1st byte of payload is mesg-type */ @@ -193,7 +183,7 @@ mm_request_receive(int sock, struct sshbuf *m) fatal_f("read: %s", strerror(errno)); } msg_len = PEEK_U32(buf); - if (msg_len > 256 * 1024) + if (msg_len > MONITOR_MAX_MSGLEN) fatal_f("read: bad msg_len %d", msg_len); sshbuf_reset(m); if ((r = sshbuf_reserve(m, msg_len, &p)) != 0) @@ -264,15 +254,13 @@ 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 || + if ((r = sshkey_puts(key, m)) != 0 || (r = sshbuf_put_string(m, data, datalen)) != 0 || (r = sshbuf_put_cstring(m, hostkey_alg)) != 0 || (r = sshbuf_put_u32(m, compat)) != 0) @@ -285,6 +273,8 @@ mm_sshkey_sign(struct ssh *ssh, struct sshkey *key, u_char **sigp, size_t *lenp, if ((r = sshbuf_get_string(m, sigp, lenp)) != 0) fatal_fr(r, "parse"); sshbuf_free(m); + debug3_f("%s signature len=%zu", hostkey_alg ? hostkey_alg : "(null)", + *lenp); return (0); } @@ -329,6 +319,17 @@ mm_decode_activate_server_options(struct ssh *ssh, struct sshbuf *m) log_verbose_reset(); for (i = 0; i < options.num_log_verbose; i++) log_verbose_add(options.log_verbose[i]); + + /* use the macro hell to clean up too */ +#define M_CP_STROPT(x) free(newopts->x) +#define M_CP_STRARRAYOPT(x, nx) do { \ + for (i = 0; i < newopts->nx; i++) \ + free(newopts->x[i]); \ + free(newopts->x); \ + } while (0) + COPY_MATCH_STRING_OPTS(); +#undef M_CP_STROPT +#undef M_CP_STRARRAYOPT free(newopts); } @@ -702,11 +703,11 @@ mm_start_pam(struct ssh *ssh) { struct sshbuf *m; - debug3("%s entering", __func__); + debug3_f("entering"); if (!options.use_pam) - fatal("UsePAM=no, but ended up in %s anyway", __func__); + fatal_f("UsePAM=no, but ended up in %s anyway", __func__); if ((m = sshbuf_new()) == NULL) - fatal("%s: sshbuf_new failed", __func__); + fatal_f("sshbuf_new failed"); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_START, m); sshbuf_free(m); @@ -721,12 +722,12 @@ mm_do_pam_account(void) size_t msglen; int r; - debug3("%s entering", __func__); + debug3_f("entering"); if (!options.use_pam) - fatal("UsePAM=no, but ended up in %s anyway", __func__); + fatal_f("UsePAM=no, but ended up in %s anyway", __func__); if ((m = sshbuf_new()) == NULL) - fatal("%s: sshbuf_new failed", __func__); + fatal_f("sshbuf_new failed"); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_ACCOUNT, m); mm_request_receive_expect(pmonitor->m_recvfd, @@ -734,12 +735,12 @@ mm_do_pam_account(void) 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)); + fatal_fr(r, "buffer error"); free(msg); sshbuf_free(m); - debug3("%s returning %d", __func__, ret); + debug3_f("returning %d", ret); return (ret); } @@ -750,17 +751,17 @@ mm_sshpam_init_ctx(Authctxt *authctxt) struct sshbuf *m; int r, success; - debug3("%s", __func__); + debug3_f("entering"); if ((m = sshbuf_new()) == NULL) - fatal("%s: sshbuf_new failed", __func__); + fatal_f("sshbuf_new failed"); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_INIT_CTX, m); - debug3("%s: waiting for MONITOR_ANS_PAM_INIT_CTX", __func__); + debug3_f("waiting for MONITOR_ANS_PAM_INIT_CTX"); 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)); + fatal_fr(r, "buffer error"); if (success == 0) { - debug3("%s: pam_init_ctx failed", __func__); + debug3_f("pam_init_ctx failed"); sshbuf_free(m); return (NULL); } @@ -776,19 +777,19 @@ mm_sshpam_query(void *ctx, char **name, char **info, u_int i, n; int r, ret; - debug3("%s", __func__); + debug3_f("entering"); if ((m = sshbuf_new()) == NULL) - fatal("%s: sshbuf_new failed", __func__); + fatal_f("sshbuf_new failed"); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_QUERY, m); - debug3("%s: waiting for MONITOR_ANS_PAM_QUERY", __func__); + debug3_f("waiting for MONITOR_ANS_PAM_QUERY"); 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); + fatal_fr(r, "buffer error"); + debug3_f("pam_query returned %d", ret); sshpam_set_maxtries_reached(n); if (*num > PAM_MAX_NUM_MSG) fatal("%s: received %u PAM messages, expected <= %u", @@ -798,7 +799,7 @@ mm_sshpam_query(void *ctx, char **name, char **info, 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)); + fatal_fr(r, "buffer error"); } sshbuf_free(m); return (ret); @@ -811,23 +812,23 @@ mm_sshpam_respond(void *ctx, u_int num, char **resp) u_int n, i; int r, ret; - debug3("%s", __func__); + debug3_f("entering"); if ((m = sshbuf_new()) == NULL) - fatal("%s: sshbuf_new failed", __func__); + fatal_f("sshbuf_new failed"); if ((r = sshbuf_put_u32(m, num)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "buffer error"); for (i = 0; i < num; ++i) { if ((r = sshbuf_put_cstring(m, resp[i])) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "buffer error"); } mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_RESPOND, m); - debug3("%s: waiting for MONITOR_ANS_PAM_RESPOND", __func__); + debug3_f("waiting for MONITOR_ANS_PAM_RESPOND"); 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)); + fatal_fr(r, "buffer error"); ret = (int)n; /* XXX */ - debug3("%s: pam_respond returned %d", __func__, ret); + debug3_f("pam_respond returned %d", ret); sshbuf_free(m); return (ret); } @@ -837,11 +838,11 @@ mm_sshpam_free_ctx(void *ctxtp) { struct sshbuf *m; - debug3("%s", __func__); + debug3_f("entering"); if ((m = sshbuf_new()) == NULL) - fatal("%s: sshbuf_new failed", __func__); + fatal_f("sshbuf_new failed"); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_FREE_CTX, m); - debug3("%s: waiting for MONITOR_ANS_PAM_FREE_CTX", __func__); + debug3_f("waiting for MONITOR_ANS_PAM_FREE_CTX"); mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_FREE_CTX, m); sshbuf_free(m); @@ -861,6 +862,72 @@ mm_terminate(void) sshbuf_free(m); } +/* Request state information */ + +void +mm_get_state(struct ssh *ssh, struct include_list *includes, + struct sshbuf *conf, struct sshbuf **confdatap, + uint64_t *timing_secretp, + struct sshbuf **hostkeysp, struct sshbuf **keystatep, + u_char **pw_namep, + struct sshbuf **authinfop, struct sshbuf **auth_optsp) +{ + struct sshbuf *m, *inc; + u_char *cp; + size_t len; + int r; + struct include_item *item; + + debug3_f("entering"); + + if ((m = sshbuf_new()) == NULL || (inc = sshbuf_new()) == NULL) + fatal_f("sshbuf_new failed"); + + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_STATE, m); + + debug3_f("waiting for MONITOR_ANS_STATE"); + mm_request_receive_expect(pmonitor->m_recvfd, + MONITOR_ANS_STATE, m); + + if ((r = sshbuf_get_string(m, &cp, &len)) != 0 || + (r = sshbuf_get_u64(m, timing_secretp)) != 0 || + (r = sshbuf_froms(m, hostkeysp)) != 0 || + (r = sshbuf_get_stringb(m, ssh->kex->server_version)) != 0 || + (r = sshbuf_get_stringb(m, ssh->kex->client_version)) != 0 || + (r = sshbuf_get_stringb(m, inc)) != 0) + fatal_fr(r, "parse config"); + + /* postauth */ + if (confdatap) { + if ((r = sshbuf_froms(m, confdatap)) != 0 || + (r = sshbuf_froms(m, keystatep)) != 0 || + (r = sshbuf_get_string(m, pw_namep, NULL)) != 0 || + (r = sshbuf_froms(m, authinfop)) != 0 || + (r = sshbuf_froms(m, auth_optsp)) != 0) + fatal_fr(r, "parse config postauth"); + } + + 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); + sshbuf_free(inc); + + debug3_f("done"); +} + static void mm_chall_setup(char **name, char **infotxt, u_int *numprompts, char ***prompts, u_int **echo_on) @@ -944,12 +1011,12 @@ mm_audit_event(struct ssh *ssh, ssh_audit_event_t event) struct sshbuf *m; int r; - debug3("%s entering", __func__); + debug3_f("entering"); if ((m = sshbuf_new()) == NULL) - fatal("%s: sshbuf_new failed", __func__); + fatal_f("sshbuf_new failed"); if ((r = sshbuf_put_u32(m, event)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "buffer error"); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_EVENT, m); sshbuf_free(m); @@ -961,12 +1028,12 @@ mm_audit_run_command(const char *command) struct sshbuf *m; int r; - debug3("%s entering command %s", __func__, command); + debug3_f("entering command %s", command); if ((m = sshbuf_new()) == NULL) - fatal("%s: sshbuf_new failed", __func__); + fatal_f("sshbuf_new failed"); if ((r = sshbuf_put_cstring(m, command)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "buffer error"); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_COMMAND, m); sshbuf_free(m); diff --git a/monitor_wrap.h b/monitor_wrap.h index e768036..c872953 100644 --- a/monitor_wrap.h +++ b/monitor_wrap.h @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor_wrap.h,v 1.51 2024/05/17 06:42:04 jsg Exp $ */ +/* $OpenBSD: monitor_wrap.h,v 1.53 2025/07/04 07:47:35 djm Exp $ */ /* * Copyright 2002 Niels Provos @@ -28,6 +28,10 @@ #ifndef _MM_WRAP_H_ #define _MM_WRAP_H_ +#define MONITOR_MAX_MSGLEN (4 * 1024 * 1024) +/* The configuration has to fit in a monitor message along with other state */ +#define MONITOR_MAX_CFGLEN (MONITOR_MAX_MSGLEN - (64 * 1024)) + enum mm_keytype { MM_NOKEY, MM_HOSTKEY, MM_USERKEY }; struct ssh; @@ -90,6 +94,12 @@ void mm_session_pty_cleanup2(struct Session *); void mm_send_keystate(struct ssh *, struct monitor*); +/* state */ +struct include_list; +void mm_get_state(struct ssh *, struct include_list *, struct sshbuf *, + struct sshbuf **, uint64_t *, struct sshbuf **, struct sshbuf **, + u_char **, struct sshbuf **, struct sshbuf **); + /* bsdauth */ int mm_bsdauth_query(void *, char **, char **, u_int *, char ***, u_int **); int mm_bsdauth_respond(void *, u_int, char **); diff --git a/mux.c b/mux.c index 0529299..37bcb91 100644 --- a/mux.c +++ b/mux.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mux.c,v 1.102 2024/07/25 22:40:08 djm Exp $ */ +/* $OpenBSD: mux.c,v 1.107 2025/09/30 00:03:09 djm Exp $ */ /* * Copyright (c) 2002-2008 Damien Miller * @@ -34,21 +34,11 @@ #include #include #include -#ifdef HAVE_PATHS_H #include -#endif -#ifdef HAVE_POLL_H #include -#else -# ifdef HAVE_SYS_POLL_H -# include -# endif -#endif -#ifdef HAVE_UTIL_H -# include -#endif +#include #include "openbsd-compat/sys-queue.h" #include "xmalloc.h" @@ -68,7 +58,6 @@ #include "readconf.h" #include "clientloop.h" #include "ssherr.h" -#include "misc.h" /* from ssh.c */ extern int tty_flag; @@ -461,6 +450,8 @@ mux_master_process_new_session(struct ssh *ssh, u_int rid, nc = channel_new(ssh, "session", SSH_CHANNEL_OPENING, new_fd[0], new_fd[1], new_fd[2], window, packetmax, CHAN_EXTENDED_WRITE, "client-session", CHANNEL_NONBLOCK_STDIO); + if (cctx->want_tty) + channel_set_tty(ssh, nc); nc->ctl_chan = c->self; /* link session -> control channel */ c->ctl_child_id = nc->self; /* link control -> session channel */ @@ -677,6 +668,7 @@ mux_confirm_remote_forward(struct ssh *ssh, int type, u_int32_t seq, void *ctxt) if (c->mux_pause <= 0) fatal_f("mux_pause %d", c->mux_pause); c->mux_pause = 0; /* start processing messages again */ + free(fctx); } static int @@ -932,7 +924,7 @@ mux_master_process_close_fwd(struct ssh *ssh, u_int rid, } else { /* local and dynamic forwards */ /* Ditto */ if (channel_cancel_lport_listener(ssh, &fwd, fwd.connect_port, - &options.fwd_opts) == -1) + &options.fwd_opts) != 1) error_reason = "port not found"; } @@ -2203,8 +2195,10 @@ mux_client_request_stdio_fwd(int fd) sshbuf_reset(m); if (mux_client_read_packet(fd, m) != 0) { if (errno == EPIPE || - (errno == EINTR && muxclient_terminate != 0)) + (errno == EINTR && muxclient_terminate != 0)) { + sshbuf_free(m); return 0; + } fatal_f("mux_client_read_packet: %s", strerror(errno)); } fatal_f("master returned unexpected message %u", type); diff --git a/myproposal.h b/myproposal.h index 3bdc2e9..8fe9276 100644 --- a/myproposal.h +++ b/myproposal.h @@ -1,4 +1,4 @@ -/* $OpenBSD: myproposal.h,v 1.73 2024/09/09 02:39:57 djm Exp $ */ +/* $OpenBSD: myproposal.h,v 1.77 2024/12/02 14:06:42 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. @@ -25,21 +25,21 @@ */ #define KEX_SERVER_KEX \ + "mlkem768x25519-sha256," \ "sntrup761x25519-sha512," \ "sntrup761x25519-sha512@openssh.com," \ - "mlkem768x25519-sha256," \ "curve25519-sha256," \ "curve25519-sha256@libssh.org," \ "ecdh-sha2-nistp256," \ "ecdh-sha2-nistp384," \ - "ecdh-sha2-nistp521," \ + "ecdh-sha2-nistp521" \ + +#define KEX_CLIENT_KEX KEX_SERVER_KEX "," \ "diffie-hellman-group-exchange-sha256," \ "diffie-hellman-group16-sha512," \ "diffie-hellman-group18-sha512," \ "diffie-hellman-group14-sha256" -#define KEX_CLIENT_KEX KEX_SERVER_KEX - #define KEX_DEFAULT_PK_ALG \ "ssh-ed25519-cert-v01@openssh.com," \ "ecdsa-sha2-nistp256-cert-v01@openssh.com," \ @@ -60,8 +60,8 @@ #define KEX_SERVER_ENCRYPT \ "chacha20-poly1305@openssh.com," \ - "aes128-ctr,aes192-ctr,aes256-ctr," \ - "aes128-gcm@openssh.com,aes256-gcm@openssh.com" + "aes128-gcm@openssh.com,aes256-gcm@openssh.com," \ + "aes128-ctr,aes192-ctr,aes256-ctr" #define KEX_CLIENT_ENCRYPT KEX_SERVER_ENCRYPT diff --git a/openbsd-compat/Makefile.in b/openbsd-compat/Makefile.in index 1d54995..53c87db 100644 --- a/openbsd-compat/Makefile.in +++ b/openbsd-compat/Makefile.in @@ -3,12 +3,14 @@ piddir=@piddir@ srcdir=@srcdir@ top_srcdir=@top_srcdir@ +BUILDDIR=@abs_top_builddir@ VPATH=@srcdir@ CC=@CC@ LD=@LD@ CFLAGS=@CFLAGS@ CFLAGS_NOPIE=@CFLAGS_NOPIE@ -CPPFLAGS=-I. -I.. -I$(srcdir) -I$(srcdir)/.. @CPPFLAGS@ @DEFS@ +COMPATINCLUDES="$(BUILDDIR)/@COMPATINCLUDES@" +CPPFLAGS=-I. -I.. -I$(srcdir) -I$(srcdir)/.. -I$(COMPATINCLUDES) @CPPFLAGS@ @DEFS@ PICFLAG=@PICFLAG@ LIBS=@LIBS@ AR=@AR@ @@ -120,3 +122,4 @@ clean: distclean: clean rm -f Makefile *~ + rm -rf include diff --git a/openbsd-compat/arc4random.c b/openbsd-compat/arc4random.c index ffd3373..376a893 100644 --- a/openbsd-compat/arc4random.c +++ b/openbsd-compat/arc4random.c @@ -32,9 +32,7 @@ #include #include #include -#ifdef HAVE_STDINT_H #include -#endif #include #include #include diff --git a/openbsd-compat/arc4random.h b/openbsd-compat/arc4random.h index af2d5c1..8f68428 100644 --- a/openbsd-compat/arc4random.h +++ b/openbsd-compat/arc4random.h @@ -65,7 +65,7 @@ _rs_forkdetect(void) static inline int _rs_allocate(struct _rs **rsp, struct _rsx **rsxp) { -#if defined(MAP_ANON) && defined(MAP_PRIVATE) +#if defined(HAVE_MMAP) && 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); @@ -84,7 +84,7 @@ _rs_allocate(struct _rs **rsp, struct _rsx **rsxp) *rsp = NULL; return (-1); } -#endif +#endif /* HAVE_MMAP et al */ _ARC4_ATFORK(_rs_forkhandler); return (0); diff --git a/openbsd-compat/arc4random_uniform.c b/openbsd-compat/arc4random_uniform.c index 591f92d..59d5168 100644 --- a/openbsd-compat/arc4random_uniform.c +++ b/openbsd-compat/arc4random_uniform.c @@ -20,9 +20,7 @@ #include "includes.h" -#ifdef HAVE_STDINT_H -# include -#endif +#include #include #ifndef HAVE_ARC4RANDOM_UNIFORM diff --git a/openbsd-compat/bsd-misc.c b/openbsd-compat/bsd-misc.c index 226a591..2c196ec 100644 --- a/openbsd-compat/bsd-misc.c +++ b/openbsd-compat/bsd-misc.c @@ -21,9 +21,7 @@ #ifdef HAVE_SYS_SELECT_H # include #endif -#ifdef HAVE_SYS_TIME_H -# include -#endif +#include #include #include @@ -158,6 +156,15 @@ utimensat(int fd, const char *path, const struct timespec times[2], } #endif +#ifndef HAVE_DIRFD +int +dirfd(void *dir) +{ + errno = ENOSYS; + return -1; +} +#endif + #ifndef HAVE_FCHOWNAT /* * A limited implementation of fchownat() that only implements the @@ -220,6 +227,46 @@ fchmodat(int fd, const char *path, mode_t mode, int flag) } #endif +#ifndef HAVE_FSTATAT +/* + * A limited implementation of fstatat that just has what OpenSSH uses: + * cwd-relative and absolute paths, with or without following symlinks. + */ +int +fstatat(int dirfd, const char *path, struct stat *sb, int flag) +{ + if (dirfd != AT_FDCWD && path && path[0] != '/') { + errno = ENOSYS; + return -1; + } + if (flag == 0) + return stat(path, sb); + else if (flag == AT_SYMLINK_NOFOLLOW) + return lstat(path, sb); + errno = ENOSYS; + return -1; +} +#endif + +#ifndef HAVE_UNLINKAT +/* + * A limited implementation of unlinkat that just has what OpenSSH uses: + * cwd-relative and absolute paths. + */ +int +unlinkat(int dirfd, const char *path, int flag) +{ + if (dirfd != AT_FDCWD && path && path[0] != '/') { + errno = ENOSYS; + return -1; + } + if (flag == 0) + return unlink(path); + errno = ENOSYS; + return -1; +} +#endif + #ifndef HAVE_TRUNCATE int truncate(const char *path, off_t length) { @@ -356,7 +403,7 @@ getpgid(pid_t pid) #ifndef HAVE_PLEDGE int -pledge(const char *promises, const char *paths[]) +pledge(const char *promises, const char *execpromises) { return 0; } @@ -447,6 +494,30 @@ localtime_r(const time_t *timep, struct tm *result) } #endif +#ifndef HAVE_CLOCK_GETTIME +int +clock_gettime(clockid_t clockid, struct timespec *ts) +{ + struct timeval tv; + + if (clockid != CLOCK_REALTIME) { + errno = ENOSYS; + return -1; + } + if (ts == NULL) { + errno = EFAULT; + return -1; + } + + if (gettimeofday(&tv, NULL) == -1) + return -1; + + ts->tv_sec = tv.tv_sec; + ts->tv_nsec = (long)tv.tv_usec * 1000; + return 0; +} +#endif + #ifdef ASAN_OPTIONS const char *__asan_default_options(void) { return ASAN_OPTIONS; diff --git a/openbsd-compat/bsd-misc.h b/openbsd-compat/bsd-misc.h index 61ead1b..8495f47 100644 --- a/openbsd-compat/bsd-misc.h +++ b/openbsd-compat/bsd-misc.h @@ -65,6 +65,10 @@ struct timeval { int utimes(const char *, struct timeval *); #endif /* HAVE_UTIMES */ +#ifndef HAVE_DIRFD +int dirfd(void *); +#endif + #ifndef AT_FDCWD # define AT_FDCWD (-2) #endif @@ -77,6 +81,14 @@ int fchmodat(int, const char *, mode_t, int); int fchownat(int, const char *, uid_t, gid_t, int); #endif +#ifdef HAVE_FSTATAT +int fstatat(int, const char *, struct stat *, int); +#endif + +#ifdef HAVE_UNLINKAT +int unlinkat(int, const char *, int); +#endif + #ifndef HAVE_TRUNCATE int truncate (const char *, off_t); #endif /* HAVE_TRUNCATE */ @@ -144,7 +156,7 @@ int pselect(int, fd_set *, fd_set *, fd_set *, const struct timespec *, #endif #ifndef HAVE_PLEDGE -int pledge(const char *promises, const char *paths[]); +int pledge(const char *promises, const char *execpromises); #endif /* bsd-err.h */ @@ -190,6 +202,14 @@ int flock(int, int); struct tm *localtime_r(const time_t *, struct tm *); #endif +#ifndef HAVE_CLOCK_GETTIME +typedef int clockid_t; +#ifndef CLOCK_REALTIME +# define CLOCK_REALTIME 0 +#endif +int clock_gettime(clockid_t, struct timespec *); +#endif + #ifndef HAVE_REALPATH #define realpath(x, y) (sftp_realpath((x), (y))) #endif diff --git a/openbsd-compat/bsd-openpty.c b/openbsd-compat/bsd-openpty.c index f550700..f08d615 100644 --- a/openbsd-compat/bsd-openpty.c +++ b/openbsd-compat/bsd-openpty.c @@ -39,9 +39,7 @@ #include -#ifdef HAVE_SYS_STAT_H -# include -#endif +#include #ifdef HAVE_SYS_IOCTL_H # include #endif @@ -50,9 +48,7 @@ # include #endif -#ifdef HAVE_UTIL_H -# include -#endif /* HAVE_UTIL_H */ +#include #ifdef HAVE_PTY_H # include diff --git a/openbsd-compat/bsd-poll.h b/openbsd-compat/bsd-poll.h index ae865a6..67fd8c6 100644 --- a/openbsd-compat/bsd-poll.h +++ b/openbsd-compat/bsd-poll.h @@ -31,11 +31,7 @@ #define _COMPAT_POLL_H_ #include -#ifdef HAVE_POLL_H -# include -#elif HAVE_SYS_POLL_H -# include -#endif +#include #ifndef HAVE_STRUCT_POLLFD_FD typedef struct pollfd { diff --git a/openbsd-compat/bsd-pselect.c b/openbsd-compat/bsd-pselect.c index b363208..26bdc3e 100644 --- a/openbsd-compat/bsd-pselect.c +++ b/openbsd-compat/bsd-pselect.c @@ -40,75 +40,47 @@ #include #include "log.h" -#include "misc.h" /* for set_nonblock */ #ifndef HAVE_SIGHANDLER_T typedef void (*sighandler_t)(int); #endif static sighandler_t saved_sighandler[_NSIG]; +static int notify_pipe[2]; /* 0 = read end, 1 = write end */ /* - * Set up the descriptors. Because they are close-on-exec, in the case - * where sshd's re-exec fails notify_pipe will still point to a descriptor - * that was closed by the exec attempt but if that descriptor has been - * reopened then we'll attempt to use that. Ensure that notify_pipe is - * outside of the range used by sshd re-exec but within NFDBITS (so we don't - * need to expand the fd_sets). + * Because the debugging for this is so noisy, we only output on the first + * call, and suppress it thereafter. */ -#define REEXEC_MIN_FREE_FD (STDERR_FILENO + 4) -static int -pselect_notify_setup_fd(int *fd) +static int suppress_debug; + +static void +pselect_set_nonblock(int fd) { - int r; + int val; - if ((r = fcntl(*fd, F_DUPFD, REEXEC_MIN_FREE_FD)) < 0 || - fcntl(r, F_SETFD, FD_CLOEXEC) < 0 || r >= FD_SETSIZE) - return -1; - (void)close(*fd); - return (*fd = r); + if ((val = fcntl(fd, F_GETFL)) == -1 || + fcntl(fd, F_SETFL, val|O_NONBLOCK) == -1) + error_f("fcntl: %s", strerror(errno)); } /* * we write to this pipe if a SIGCHLD is caught in order to avoid - * the race between select() and child_terminated + * the race between select() and child_terminated. */ -static pid_t notify_pid; -static int notify_pipe[2]; -static void +static int pselect_notify_setup(void) { - static int initialized; - - if (initialized && notify_pid == getpid()) - return; - if (notify_pid == 0) - debug3_f("initializing"); - else { - debug3_f("pid changed, reinitializing"); - if (notify_pipe[0] != -1) - close(notify_pipe[0]); - if (notify_pipe[1] != -1) - close(notify_pipe[1]); - } if (pipe(notify_pipe) == -1) { error("pipe(notify_pipe) failed %s", strerror(errno)); - } else if (pselect_notify_setup_fd(¬ify_pipe[0]) == -1 || - pselect_notify_setup_fd(¬ify_pipe[1]) == -1) { - error("fcntl(notify_pipe, ...) failed %s", strerror(errno)); - close(notify_pipe[0]); - close(notify_pipe[1]); - } else { - set_nonblock(notify_pipe[0]); - set_nonblock(notify_pipe[1]); - notify_pid = getpid(); - debug3_f("pid %d saved %d pipe0 %d pipe1 %d", getpid(), - notify_pid, notify_pipe[0], notify_pipe[1]); - initialized = 1; - return; + notify_pipe[0] = notify_pipe[1] = -1; + return -1; } - notify_pipe[0] = -1; /* read end */ - notify_pipe[1] = -1; /* write end */ + pselect_set_nonblock(notify_pipe[0]); + pselect_set_nonblock(notify_pipe[1]); + if (!suppress_debug) + debug3_f("pipe0 %d pipe1 %d", notify_pipe[0], notify_pipe[1]); + return 0; } static void pselect_notify_parent(void) @@ -132,6 +104,8 @@ pselect_notify_done(fd_set *readset) debug2_f("reading"); FD_CLR(notify_pipe[0], readset); } + (void)close(notify_pipe[0]); + (void)close(notify_pipe[1]); } /*ARGSUSED*/ @@ -167,26 +141,29 @@ pselect(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, if (mask == NULL) /* no signal mask, just call select */ return select(nfds, readfds, writefds, exceptfds, tvp); - /* For each signal we're unmasking, install our handler if needed. */ + /* For each signal unmasked, save old handler and install ours. */ for (sig = 0; sig < _NSIG; sig++) { + saved_sighandler[sig] = NULL; if (sig == SIGKILL || sig == SIGSTOP || sigismember(mask, sig)) continue; if (sigaction(sig, NULL, &sa) == 0 && sa.sa_handler != SIG_IGN && sa.sa_handler != SIG_DFL) { unmasked = 1; - if (sa.sa_handler == pselect_sig_handler) - continue; sa.sa_handler = pselect_sig_handler; if (sigaction(sig, &sa, &osa) == 0) { - debug3_f("installing signal handler for %s, " - "previous %p", strsignal(sig), - osa.sa_handler); + if (!suppress_debug) + debug3_f("installed signal handler for" + " %s, previous 0x%p", + strsignal(sig), osa.sa_handler); saved_sighandler[sig] = osa.sa_handler; } } } if (unmasked) { - pselect_notify_setup(); + if ((ret = pselect_notify_setup()) == -1) { + saved_errno = ENOMEM; + goto out; + } pselect_notify_prepare(readfds); nfds = MAX(nfds, notify_pipe[0] + 1); } @@ -199,6 +176,25 @@ pselect(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, if (unmasked) pselect_notify_done(readfds); + + out: + /* Restore signal handlers. */ + for (sig = 0; sig < _NSIG; sig++) { + if (saved_sighandler[sig] == NULL) + continue; + if (sigaction(sig, NULL, &sa) == 0) { + sa.sa_handler = saved_sighandler[sig]; + if (sigaction(sig, &sa, NULL) == 0) { + if (!suppress_debug) + debug3_f("restored signal handler for " + "%s", strsignal(sig)); + } else { + error_f("failed to restore signal handler for " + "%s: %s", strsignal(sig), strerror(errno)); + } + } + } + suppress_debug = 1; errno = saved_errno; return ret; } diff --git a/openbsd-compat/daemon.c b/openbsd-compat/daemon.c index 3efe14c..2564669 100644 --- a/openbsd-compat/daemon.c +++ b/openbsd-compat/daemon.c @@ -36,9 +36,7 @@ #include -#ifdef HAVE_SYS_STAT_H -# include -#endif +#include #ifdef HAVE_FCNTL_H # include diff --git a/openbsd-compat/glob.c b/openbsd-compat/glob.c index e891517..330b9c0 100644 --- a/openbsd-compat/glob.c +++ b/openbsd-compat/glob.c @@ -70,9 +70,7 @@ #include #include #include -#ifdef HAVE_STDINT_H #include -#endif #include #include diff --git a/openbsd-compat/memmem.c b/openbsd-compat/memmem.c index 2637401..afc20c6 100644 --- a/openbsd-compat/memmem.c +++ b/openbsd-compat/memmem.c @@ -30,9 +30,7 @@ #ifndef HAVE_MEMMEM #include -#ifdef HAVE_STDINT_H #include -#endif static char * twobyte_memmem(const unsigned char *h, size_t k, const unsigned char *n) diff --git a/openbsd-compat/openssl-compat.c b/openbsd-compat/openssl-compat.c index 1486507..4893892 100644 --- a/openbsd-compat/openssl-compat.c +++ b/openbsd-compat/openssl-compat.c @@ -32,7 +32,8 @@ #include "openssl-compat.h" /* - * OpenSSL version numbers: MNNFFPPS: major minor fix patch status + * OpenSSL version numbers: MNNFFPPS: major minor fix patch status. + * See the OpenSSL_version_num(3ssl) man page. * Versions >=3 require only major versions to match. * For versions <3, we accept compatible fix versions (so we allow 1.0.1 * to work with 1.0.0). Going backwards is only allowed within a patch series. @@ -49,10 +50,10 @@ ssh_compatible_openssl(long headerver, long libver) return 1; /* - * For versions >= 3.0, only the major and status must match. + * For versions >= 3.0, only the major must match. */ - if (headerver >= 0x3000000f) { - mask = 0xf000000fL; /* major,status */ + if (headerver >= 0x30000000) { + mask = 0xf0000000L; /* major only */ return (headerver & mask) == (libver & mask); } diff --git a/openbsd-compat/openssl-compat.h b/openbsd-compat/openssl-compat.h index 2b9780f..d07928b 100644 --- a/openbsd-compat/openssl-compat.h +++ b/openbsd-compat/openssl-compat.h @@ -23,8 +23,8 @@ #include #include #include +#include #include -#include #ifdef OPENSSL_HAS_ECC #include #endif @@ -45,9 +45,6 @@ void ssh_libcrypto_init(void); #ifndef OPENSSL_RSA_MAX_MODULUS_BITS # define OPENSSL_RSA_MAX_MODULUS_BITS 16384 #endif -#ifndef OPENSSL_DSA_MAX_MODULUS_BITS -# define OPENSSL_DSA_MAX_MODULUS_BITS 10000 -#endif #ifdef LIBRESSL_VERSION_NUMBER # if LIBRESSL_VERSION_NUMBER < 0x3010000fL @@ -55,15 +52,29 @@ void ssh_libcrypto_init(void); # endif #endif -#ifdef OPENSSL_IS_BORINGSSL +#if defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC) /* - * BoringSSL (rightly) got rid of the BN_FLG_CONSTTIME flag, along with + * BoringSSL and AWS-LC (rightly) got rid of the BN_FLG_CONSTTIME flag, along with * the entire BN_set_flags() interface. * https://boringssl.googlesource.com/boringssl/+/0a211dfe9 */ # define BN_set_flags(a, b) #endif +/* LibreSSL <3.4 has the _GFp variants but not the equivalent modern ones. */ +#ifndef HAVE_EC_POINT_GET_AFFINE_COORDINATES +# ifdef HAVE_EC_POINT_GET_AFFINE_COORDINATES_GFP +# define EC_POINT_get_affine_coordinates(a, b, c, d, e) \ + (EC_POINT_get_affine_coordinates_GFp(a, b, c, d, e)) +# endif +#endif +#ifndef HAVE_EC_POINT_SET_AFFINE_COORDINATES +# ifdef HAVE_EC_POINT_SET_AFFINE_COORDINATES_GFP +# define EC_POINT_set_affine_coordinates(a, b, c, d, e) \ + (EC_POINT_set_affine_coordinates_GFp(a, b, c, d, e)) +# endif +#endif + #ifndef HAVE_EVP_CIPHER_CTX_GET_IV # ifdef HAVE_EVP_CIPHER_CTX_GET_UPDATED_IV # define EVP_CIPHER_CTX_get_iv EVP_CIPHER_CTX_get_updated_iv diff --git a/openbsd-compat/port-linux.c b/openbsd-compat/port-linux.c index 8adfec5..c1d54f3 100644 --- a/openbsd-compat/port-linux.c +++ b/openbsd-compat/port-linux.c @@ -319,6 +319,19 @@ oom_adjust_restore(void) } #endif /* LINUX_OOM_ADJUST */ +#ifdef LINUX_MEMLOCK_ONFAULT +#include + +void +memlock_onfault_setup(void) +{ + if (mlockall(MCL_CURRENT | MCL_FUTURE | MCL_ONFAULT) < 0) + verbose("unable to lock memory: %s", strerror(errno)); + else + debug("memory locked"); +} +#endif /* LINUX_MEMLOCK_ONFAULT */ + #ifdef SYSTEMD_NOTIFY static void ssh_systemd_notify(const char *, ...) diff --git a/openbsd-compat/port-linux.h b/openbsd-compat/port-linux.h index 14064f8..959430d 100644 --- a/openbsd-compat/port-linux.h +++ b/openbsd-compat/port-linux.h @@ -30,6 +30,10 @@ void oom_adjust_restore(void); void oom_adjust_setup(void); #endif +#ifdef LINUX_MEMLOCK_ONFAULT +void memlock_onfault_setup(void); +#endif + #ifdef SYSTEMD_NOTIFY void ssh_systemd_notify_ready(void); void ssh_systemd_notify_reload(void); diff --git a/openbsd-compat/port-prngd.c b/openbsd-compat/port-prngd.c index 6afa8f9..ac4f270 100644 --- a/openbsd-compat/port-prngd.c +++ b/openbsd-compat/port-prngd.c @@ -26,9 +26,7 @@ #include #include -#ifdef HAVE_SYS_UN_H -# include -#endif +#include #include #include diff --git a/openbsd-compat/reallocarray.c b/openbsd-compat/reallocarray.c index 1a52acc..cffe9b5 100644 --- a/openbsd-compat/reallocarray.c +++ b/openbsd-compat/reallocarray.c @@ -22,9 +22,7 @@ #include #include -#ifdef HAVE_STDINT_H #include -#endif #include /* diff --git a/openbsd-compat/recallocarray.c b/openbsd-compat/recallocarray.c index 3e1156c..c281f75 100644 --- a/openbsd-compat/recallocarray.c +++ b/openbsd-compat/recallocarray.c @@ -22,9 +22,7 @@ #include #include -#ifdef HAVE_STDINT_H #include -#endif #include #include diff --git a/openbsd-compat/regress/utimensattest.c b/openbsd-compat/regress/utimensattest.c index bbc66c4..b4405e4 100644 --- a/openbsd-compat/regress/utimensattest.c +++ b/openbsd-compat/regress/utimensattest.c @@ -77,11 +77,17 @@ main(void) fail("utimensat", 0, 0); if (stat(TMPFILE, &sb) == -1) - fail("stat", 0, 0 ); + fail("stat", 0, 0); +#if 0 + /* + * This test only works on filesystems mounted 'noatime', otherwise the + * stat() above resets atime. Skip by default. + */ if (sb.st_atime != 12345678) - fail("st_atime", 0, 0 ); + fail("st_atime", 0, 0); +#endif if (sb.st_mtime != 34567890) - fail("st_mtime", 0, 0 ); + fail("st_mtime", 0, 0); #if 0 /* * Results expected to be rounded to the nearest microsecond. diff --git a/packet.c b/packet.c index 9dea2cf..5dd8269 100644 --- a/packet.c +++ b/packet.c @@ -1,4 +1,4 @@ -/* $OpenBSD: packet.c,v 1.318 2025/02/18 08:02:12 djm Exp $ */ +/* $OpenBSD: packet.c,v 1.323 2025/09/25 06:33:19 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -42,9 +42,7 @@ #include #include "openbsd-compat/sys-queue.h" #include -#ifdef HAVE_SYS_TIME_H -# include -#endif +#include #include #include @@ -58,9 +56,7 @@ #include #include #include -#ifdef HAVE_POLL_H #include -#endif #include #include @@ -210,8 +206,8 @@ struct session_state { /* Used in ssh_packet_send_mux() */ int mux; - /* Used in packet_set_interactive */ - int set_interactive_called; + /* QoS handling */ + int qos_interactive, qos_other; /* Used in packet_set_maxsize */ int set_maxsize_called; @@ -219,6 +215,15 @@ struct session_state { /* One-off warning about weak ciphers */ int cipher_warning_done; + /* + * Disconnect in progress. Used to prevent reentry in + * ssh_packet_disconnect() + */ + int disconnecting; + + /* Nagle disabled on socket */ + int nodelay_set; + /* Hook for fuzzing inbound packets */ ssh_packet_hook_fn *hook_in; void *hook_in_ctx; @@ -247,6 +252,8 @@ ssh_alloc_session_state(void) state->connection_out = -1; state->max_packet_size = 32768; state->packet_timeout_ms = -1; + state->interactive_mode = 1; + state->qos_interactive = state->qos_other = -1; state->p_send.packets = state->p_read.packets = 0; state->initialized = 1; /* @@ -675,6 +682,7 @@ ssh_packet_close_internal(struct ssh *ssh, int do_close) { struct session_state *state = ssh->state; u_int mode; + struct packet *p; if (!state->initialized) return; @@ -691,6 +699,11 @@ ssh_packet_close_internal(struct ssh *ssh, int do_close) sshbuf_free(state->output); sshbuf_free(state->outgoing_packet); sshbuf_free(state->incoming_packet); + while ((p = TAILQ_FIRST(&state->outgoing))) { + sshbuf_free(p->payload); + TAILQ_REMOVE(&state->outgoing, p, next); + free(p); + } for (mode = 0; mode < MODE_MAX; mode++) { kex_free_newkeys(state->newkeys[mode]); /* current keys */ state->newkeys[mode] = NULL; @@ -739,6 +752,13 @@ ssh_packet_close_internal(struct ssh *ssh, int do_close) } } +void +ssh_packet_free(struct ssh *ssh) +{ + ssh_packet_close_internal(ssh, 1); + freezero(ssh, sizeof(*ssh)); +} + void ssh_packet_close(struct ssh *ssh) { @@ -2064,12 +2084,12 @@ ssh_packet_disconnect(struct ssh *ssh, const char *fmt,...) { char buf[1024], remote_id[512]; va_list args; - static int disconnecting = 0; int r; - if (disconnecting) /* Guard against recursive invocations. */ + /* Guard against recursive invocations. */ + if (ssh->state->disconnecting) fatal("packet_disconnect called recursively."); - disconnecting = 1; + ssh->state->disconnecting = 1; /* * Format the message. Note that the caller must make sure the @@ -2206,41 +2226,41 @@ ssh_packet_interactive_data_to_write(struct ssh *ssh) sshbuf_len(ssh->state->output) < 256; } -void -ssh_packet_set_tos(struct ssh *ssh, int tos) +static void +apply_qos(struct ssh *ssh) { - if (!ssh_packet_connection_is_on_socket(ssh) || tos == INT_MAX) + struct session_state *state = ssh->state; + int qos = state->interactive_mode ? + state->qos_interactive : state->qos_other; + + if (!ssh_packet_connection_is_on_socket(ssh)) return; - set_sock_tos(ssh->state->connection_in, tos); + if (!state->nodelay_set) { + set_nodelay(state->connection_in); + state->nodelay_set = 1; + } + set_sock_tos(ssh->state->connection_in, qos); } -/* Informs that the current session is interactive. Sets IP flags for that. */ - +/* Informs that the current session is interactive. */ void -ssh_packet_set_interactive(struct ssh *ssh, int interactive, int qos_interactive, int qos_bulk) +ssh_packet_set_interactive(struct ssh *ssh, int interactive) { struct session_state *state = ssh->state; - if (state->set_interactive_called) - return; - state->set_interactive_called = 1; - - /* Record that we are in interactive mode. */ state->interactive_mode = interactive; - - /* Only set socket options if using a socket. */ - if (!ssh_packet_connection_is_on_socket(ssh)) - return; - set_nodelay(state->connection_in); - ssh_packet_set_tos(ssh, interactive ? qos_interactive : qos_bulk); + apply_qos(ssh); } -/* Returns true if the current connection is interactive. */ - -int -ssh_packet_is_interactive(struct ssh *ssh) +/* Set QoS flags to be used for interactive and non-interactive sessions */ +void +ssh_packet_set_qos(struct ssh *ssh, int qos_interactive, int qos_other) { - return ssh->state->interactive_mode; + struct session_state *state = ssh->state; + + state->qos_interactive = qos_interactive; + state->qos_other = qos_other; + apply_qos(ssh); } int @@ -2415,6 +2435,7 @@ ssh_packet_get_state(struct ssh *ssh, struct sshbuf *m) struct session_state *state = ssh->state; int r; +#define ENCODE_INT(v) (((v) < 0) ? 0xFFFFFFFF : (u_int)v) if ((r = kex_to_blob(m, ssh->kex)) != 0 || (r = newkeys_to_blob(m, ssh, MODE_OUT)) != 0 || (r = newkeys_to_blob(m, ssh, MODE_IN)) != 0 || @@ -2429,9 +2450,12 @@ ssh_packet_get_state(struct ssh *ssh, struct sshbuf *m) (r = sshbuf_put_u32(m, state->p_read.packets)) != 0 || (r = sshbuf_put_u64(m, state->p_read.bytes)) != 0 || (r = sshbuf_put_stringb(m, state->input)) != 0 || - (r = sshbuf_put_stringb(m, state->output)) != 0) + (r = sshbuf_put_stringb(m, state->output)) != 0 || + (r = sshbuf_put_u32(m, ENCODE_INT(state->interactive_mode))) != 0 || + (r = sshbuf_put_u32(m, ENCODE_INT(state->qos_interactive))) != 0 || + (r = sshbuf_put_u32(m, ENCODE_INT(state->qos_other))) != 0) return r; - +#undef ENCODE_INT return 0; } @@ -2550,6 +2574,7 @@ ssh_packet_set_state(struct ssh *ssh, struct sshbuf *m) const u_char *input, *output; size_t ilen, olen; int r; + u_int interactive, qos_interactive, qos_other; if ((r = kex_from_blob(m, &ssh->kex)) != 0 || (r = newkeys_from_blob(m, ssh, MODE_OUT)) != 0 || @@ -2586,6 +2611,16 @@ ssh_packet_set_state(struct ssh *ssh, struct sshbuf *m) (r = sshbuf_put(state->output, output, olen)) != 0) return r; + if ((r = sshbuf_get_u32(m, &interactive)) != 0 || + (r = sshbuf_get_u32(m, &qos_interactive)) != 0 || + (r = sshbuf_get_u32(m, &qos_other)) != 0) + return r; +#define DECODE_INT(v) ((v) > INT_MAX ? -1 : (int)(v)) + state->interactive_mode = DECODE_INT(interactive); + state->qos_interactive = DECODE_INT(qos_interactive); + state->qos_other = DECODE_INT(qos_other); +#undef DECODE_INT + if (sshbuf_len(m)) return SSH_ERR_INVALID_FORMAT; debug3_f("done"); diff --git a/packet.h b/packet.h index 49bb87f..072f274 100644 --- a/packet.h +++ b/packet.h @@ -1,4 +1,4 @@ -/* $OpenBSD: packet.h,v 1.99 2024/08/15 00:51:51 djm Exp $ */ +/* $OpenBSD: packet.h,v 1.103 2025/09/25 06:33:19 djm Exp $ */ /* * Author: Tatu Ylonen @@ -101,6 +101,7 @@ int ssh_packet_connection_af(struct ssh *); void ssh_packet_set_nonblocking(struct ssh *); int ssh_packet_get_connection_in(struct ssh *); int ssh_packet_get_connection_out(struct ssh *); +void ssh_packet_free(struct ssh *); void ssh_packet_close(struct ssh *); void ssh_packet_set_input_hook(struct ssh *, ssh_packet_hook_fn *, void *); void ssh_packet_clear_keys(struct ssh *); @@ -110,9 +111,8 @@ int ssh_packet_is_rekeying(struct ssh *); int ssh_packet_check_rekey(struct ssh *); void ssh_packet_set_protocol_flags(struct ssh *, u_int); u_int ssh_packet_get_protocol_flags(struct ssh *); -void ssh_packet_set_tos(struct ssh *, int); -void ssh_packet_set_interactive(struct ssh *, int, int, int); -int ssh_packet_is_interactive(struct ssh *); +void ssh_packet_set_interactive(struct ssh *, int); +void ssh_packet_set_qos(struct ssh *, int, int); void ssh_packet_set_server(struct ssh *); void ssh_packet_set_authenticated(struct ssh *); void ssh_packet_set_mux(struct ssh *); diff --git a/pathnames.h b/pathnames.h index 61c5f84..0dcc495 100644 --- a/pathnames.h +++ b/pathnames.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pathnames.h,v 1.32 2024/05/17 00:30:24 djm Exp $ */ +/* $OpenBSD: pathnames.h,v 1.36 2025/08/29 03:50:38 djm Exp $ */ /* * Author: Tatu Ylonen @@ -36,10 +36,8 @@ */ #define _PATH_SERVER_CONFIG_FILE SSHDIR "/sshd_config" #define _PATH_HOST_CONFIG_FILE SSHDIR "/ssh_config" -#define _PATH_HOST_DSA_KEY_FILE SSHDIR "/ssh_host_dsa_key" #define _PATH_HOST_ECDSA_KEY_FILE SSHDIR "/ssh_host_ecdsa_key" #define _PATH_HOST_ED25519_KEY_FILE SSHDIR "/ssh_host_ed25519_key" -#define _PATH_HOST_XMSS_KEY_FILE SSHDIR "/ssh_host_xmss_key" #define _PATH_HOST_RSA_KEY_FILE SSHDIR "/ssh_host_rsa_key" #define _PATH_DH_MODULI SSHDIR "/moduli" @@ -51,6 +49,9 @@ #ifndef _PATH_SSHD_SESSION #define _PATH_SSHD_SESSION "/usr/libexec/sshd-session" #endif +#ifndef _PATH_SSHD_AUTH +#define _PATH_SSHD_AUTH "/usr/libexec/sshd-auth" +#endif /* * The process id of the daemon listening for connections is saved here to @@ -64,6 +65,13 @@ */ #define _PATH_SSH_USER_DIR ".ssh" + +/* + * The directory in which ssh-agent sockets and agent sockets forwarded by + * sshd reside. This directory should not be world-readable. + */ +#define _PATH_SSH_AGENT_SOCKET_DIR _PATH_SSH_USER_DIR "/agent" + /* * Per-user file containing host keys of known hosts. This file need not be * readable by anyone except the user him/herself, though this does not @@ -77,11 +85,9 @@ * Name of the default file containing client-side authentication key. This * file should only be readable by the user him/herself. */ -#define _PATH_SSH_CLIENT_ID_DSA _PATH_SSH_USER_DIR "/id_dsa" #define _PATH_SSH_CLIENT_ID_ECDSA _PATH_SSH_USER_DIR "/id_ecdsa" #define _PATH_SSH_CLIENT_ID_RSA _PATH_SSH_USER_DIR "/id_rsa" #define _PATH_SSH_CLIENT_ID_ED25519 _PATH_SSH_USER_DIR "/id_ed25519" -#define _PATH_SSH_CLIENT_ID_XMSS _PATH_SSH_USER_DIR "/id_xmss" #define _PATH_SSH_CLIENT_ID_ECDSA_SK _PATH_SSH_USER_DIR "/id_ecdsa_sk" #define _PATH_SSH_CLIENT_ID_ED25519_SK _PATH_SSH_USER_DIR "/id_ed25519_sk" diff --git a/pkcs11.h b/pkcs11.h index b01d58f..707333f 100644 --- a/pkcs11.h +++ b/pkcs11.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pkcs11.h,v 1.3 2013/11/26 19:15:09 deraadt Exp $ */ +/* $OpenBSD: pkcs11.h,v 1.4 2025/07/25 13:06:07 djm Exp $ */ /* pkcs11.h Copyright 2006, 2007 g10 Code GmbH Copyright 2006 Andreas Jellinghaus @@ -64,9 +64,9 @@ extern "C" { version of this file, please consider deleting the revision macro (you may use a macro with a different name to keep track of your versions). */ -#define CRYPTOKI_VERSION_MAJOR 2 -#define CRYPTOKI_VERSION_MINOR 20 -#define CRYPTOKI_VERSION_REVISION 6 +#define CRYPTOKI_VERSION_MAJOR 3 +#define CRYPTOKI_VERSION_MINOR 0 +#define CRYPTOKI_VERSION_REVISION 0 /* Compatibility interface is default, unless CRYPTOKI_GNU is @@ -96,7 +96,6 @@ extern "C" { #endif - #ifdef CRYPTOKI_COMPAT /* If we are in compatibility mode, switch all exposed names to the PKCS #11 variant. There are corresponding #undefs below. */ @@ -155,6 +154,8 @@ extern "C" { #define ck_mechanism_type_t CK_MECHANISM_TYPE +#define ck_rsa_pkcs_mgf_type_t CK_RSA_PKCS_MGF_TYPE + #define ck_mechanism _CK_MECHANISM #define parameter pParameter #define parameter_len ulParameterLen @@ -166,7 +167,10 @@ extern "C" { #define ck_rv_t CK_RV #define ck_notify_t CK_NOTIFY +#define ck_interface CK_INTERFACE + #define ck_function_list _CK_FUNCTION_LIST +#define ck_function_list_3_0 _CK_FUNCTION_LIST_3_0 #define ck_createmutex_t CK_CREATEMUTEX #define ck_destroymutex_t CK_DESTROYMUTEX @@ -183,7 +187,6 @@ extern "C" { #endif /* CRYPTOKI_COMPAT */ - typedef unsigned long ck_flags_t; struct ck_version @@ -205,7 +208,7 @@ struct ck_info typedef unsigned long ck_notification_t; -#define CKN_SURRENDER (0) +#define CKN_SURRENDER (0UL) typedef unsigned long ck_slot_id_t; @@ -221,10 +224,10 @@ struct ck_slot_info }; -#define CKF_TOKEN_PRESENT (1 << 0) -#define CKF_REMOVABLE_DEVICE (1 << 1) -#define CKF_HW_SLOT (1 << 2) -#define CKF_ARRAY_ATTRIBUTE (1 << 30) +#define CKF_TOKEN_PRESENT (1UL << 0) +#define CKF_REMOVABLE_DEVICE (1UL << 1) +#define CKF_HW_SLOT (1UL << 2) +#define CKF_ARRAY_ATTRIBUTE (1UL << 30) struct ck_token_info @@ -250,48 +253,48 @@ struct ck_token_info }; -#define CKF_RNG (1 << 0) -#define CKF_WRITE_PROTECTED (1 << 1) -#define CKF_LOGIN_REQUIRED (1 << 2) -#define CKF_USER_PIN_INITIALIZED (1 << 3) -#define CKF_RESTORE_KEY_NOT_NEEDED (1 << 5) -#define CKF_CLOCK_ON_TOKEN (1 << 6) -#define CKF_PROTECTED_AUTHENTICATION_PATH (1 << 8) -#define CKF_DUAL_CRYPTO_OPERATIONS (1 << 9) -#define CKF_TOKEN_INITIALIZED (1 << 10) -#define CKF_SECONDARY_AUTHENTICATION (1 << 11) -#define CKF_USER_PIN_COUNT_LOW (1 << 16) -#define CKF_USER_PIN_FINAL_TRY (1 << 17) -#define CKF_USER_PIN_LOCKED (1 << 18) -#define CKF_USER_PIN_TO_BE_CHANGED (1 << 19) -#define CKF_SO_PIN_COUNT_LOW (1 << 20) -#define CKF_SO_PIN_FINAL_TRY (1 << 21) -#define CKF_SO_PIN_LOCKED (1 << 22) -#define CKF_SO_PIN_TO_BE_CHANGED (1 << 23) +#define CKF_RNG (1UL << 0) +#define CKF_WRITE_PROTECTED (1UL << 1) +#define CKF_LOGIN_REQUIRED (1UL << 2) +#define CKF_USER_PIN_INITIALIZED (1UL << 3) +#define CKF_RESTORE_KEY_NOT_NEEDED (1UL << 5) +#define CKF_CLOCK_ON_TOKEN (1UL << 6) +#define CKF_PROTECTED_AUTHENTICATION_PATH (1UL << 8) +#define CKF_DUAL_CRYPTO_OPERATIONS (1UL << 9) +#define CKF_TOKEN_INITIALIZED (1UL << 10) +#define CKF_SECONDARY_AUTHENTICATION (1UL << 11) +#define CKF_USER_PIN_COUNT_LOW (1UL << 16) +#define CKF_USER_PIN_FINAL_TRY (1UL << 17) +#define CKF_USER_PIN_LOCKED (1UL << 18) +#define CKF_USER_PIN_TO_BE_CHANGED (1UL << 19) +#define CKF_SO_PIN_COUNT_LOW (1UL << 20) +#define CKF_SO_PIN_FINAL_TRY (1UL << 21) +#define CKF_SO_PIN_LOCKED (1UL << 22) +#define CKF_SO_PIN_TO_BE_CHANGED (1UL << 23) #define CK_UNAVAILABLE_INFORMATION ((unsigned long) -1) -#define CK_EFFECTIVELY_INFINITE (0) +#define CK_EFFECTIVELY_INFINITE (0UL) typedef unsigned long ck_session_handle_t; -#define CK_INVALID_HANDLE (0) +#define CK_INVALID_HANDLE (0UL) typedef unsigned long ck_user_type_t; -#define CKU_SO (0) -#define CKU_USER (1) -#define CKU_CONTEXT_SPECIFIC (2) +#define CKU_SO (0UL) +#define CKU_USER (1UL) +#define CKU_CONTEXT_SPECIFIC (2UL) typedef unsigned long ck_state_t; -#define CKS_RO_PUBLIC_SESSION (0) -#define CKS_RO_USER_FUNCTIONS (1) -#define CKS_RW_PUBLIC_SESSION (2) -#define CKS_RW_USER_FUNCTIONS (3) -#define CKS_RW_SO_FUNCTIONS (4) +#define CKS_RO_PUBLIC_SESSION (0UL) +#define CKS_RO_USER_FUNCTIONS (1UL) +#define CKS_RW_PUBLIC_SESSION (2UL) +#define CKS_RW_USER_FUNCTIONS (3UL) +#define CKS_RW_SO_FUNCTIONS (4UL) struct ck_session_info @@ -302,8 +305,8 @@ struct ck_session_info unsigned long device_error; }; -#define CKF_RW_SESSION (1 << 1) -#define CKF_SERIAL_SESSION (1 << 2) +#define CKF_RW_SESSION (1UL << 1) +#define CKF_SERIAL_SESSION (1UL << 2) typedef unsigned long ck_object_handle_t; @@ -311,149 +314,194 @@ typedef unsigned long ck_object_handle_t; typedef unsigned long ck_object_class_t; -#define CKO_DATA (0) -#define CKO_CERTIFICATE (1) -#define CKO_PUBLIC_KEY (2) -#define CKO_PRIVATE_KEY (3) -#define CKO_SECRET_KEY (4) -#define CKO_HW_FEATURE (5) -#define CKO_DOMAIN_PARAMETERS (6) -#define CKO_MECHANISM (7) -#define CKO_VENDOR_DEFINED (1U << 31) - +#define CKO_DATA (0UL) +#define CKO_CERTIFICATE (1UL) +#define CKO_PUBLIC_KEY (2UL) +#define CKO_PRIVATE_KEY (3UL) +#define CKO_SECRET_KEY (4UL) +#define CKO_HW_FEATURE (5UL) +#define CKO_DOMAIN_PARAMETERS (6UL) +#define CKO_MECHANISM (7UL) +#define CKO_OTP_KEY (8UL) +#define CKO_PROFILE (9UL) +#define CKO_VENDOR_DEFINED (1UL << 31) + +#define CKP_INVALID_ID (0UL) +#define CKP_BASELINE_PROVIDER (1UL) +#define CKP_EXTENDED_PROVIDER (2UL) +#define CKP_AUTHENTICATION_TOKEN (3UL) +#define CKP_PUBLIC_CERTIFICATES_TOKEN (4UL) +#define CKP_VENDOR_DEFINED (1UL << 31) typedef unsigned long ck_hw_feature_type_t; -#define CKH_MONOTONIC_COUNTER (1) -#define CKH_CLOCK (2) -#define CKH_USER_INTERFACE (3) -#define CKH_VENDOR_DEFINED (1U << 31) +#define CKH_MONOTONIC_COUNTER (1UL) +#define CKH_CLOCK (2UL) +#define CKH_USER_INTERFACE (3UL) +#define CKH_VENDOR_DEFINED (1UL << 31) typedef unsigned long ck_key_type_t; -#define CKK_RSA (0) -#define CKK_DSA (1) -#define CKK_DH (2) -#define CKK_ECDSA (3) -#define CKK_EC (3) -#define CKK_X9_42_DH (4) -#define CKK_KEA (5) -#define CKK_GENERIC_SECRET (0x10) -#define CKK_RC2 (0x11) -#define CKK_RC4 (0x12) -#define CKK_DES (0x13) -#define CKK_DES2 (0x14) -#define CKK_DES3 (0x15) -#define CKK_CAST (0x16) -#define CKK_CAST3 (0x17) -#define CKK_CAST128 (0x18) -#define CKK_RC5 (0x19) -#define CKK_IDEA (0x1a) -#define CKK_SKIPJACK (0x1b) -#define CKK_BATON (0x1c) -#define CKK_JUNIPER (0x1d) -#define CKK_CDMF (0x1e) -#define CKK_AES (0x1f) -#define CKK_BLOWFISH (0x20) -#define CKK_TWOFISH (0x21) -#define CKK_VENDOR_DEFINED (1U << 31) +#define CKK_RSA (0UL) +#define CKK_DSA (1UL) +#define CKK_DH (2UL) +#define CKK_ECDSA (3UL) +#define CKK_EC (3UL) +#define CKK_X9_42_DH (4UL) +#define CKK_KEA (5UL) +#define CKK_GENERIC_SECRET (0x10UL) +#define CKK_RC2 (0x11UL) +#define CKK_RC4 (0x12UL) +#define CKK_DES (0x13UL) +#define CKK_DES2 (0x14UL) +#define CKK_DES3 (0x15UL) +#define CKK_CAST (0x16UL) +#define CKK_CAST3 (0x17UL) +#define CKK_CAST128 (0x18UL) +#define CKK_RC5 (0x19UL) +#define CKK_IDEA (0x1aUL) +#define CKK_SKIPJACK (0x1bUL) +#define CKK_BATON (0x1cUL) +#define CKK_JUNIPER (0x1dUL) +#define CKK_CDMF (0x1eUL) +#define CKK_AES (0x1fUL) +#define CKK_BLOWFISH (0x20UL) +#define CKK_TWOFISH (0x21UL) +#define CKK_GOSTR3410 (0x30UL) +#define CKK_GOSTR3411 (0x31UL) +#define CKK_GOST28147 (0x32UL) +#define CKK_EC_EDWARDS (0x40UL) +#define CKK_EC_MONTGOMERY (0x41UL) +#define CKK_HKDF (0x42UL) +#define CKK_VENDOR_DEFINED (1UL << 31) + +/* + * A mask for new GOST algorithms. + * For details visit https://tc26.ru/standarts/perevody/guidelines-the-pkcs-11-extensions-for-implementing-the-gost-r-34-10-2012-and-gost-r-34-11-2012-russian-standards-.html + */ +#define NSSCK_VENDOR_PKCS11_RU_TEAM (CKK_VENDOR_DEFINED | 0x54321000) +#define CK_VENDOR_PKCS11_RU_TEAM_TK26 NSSCK_VENDOR_PKCS11_RU_TEAM + +#define CKK_GOSTR3410_512 (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x003) typedef unsigned long ck_certificate_type_t; -#define CKC_X_509 (0) -#define CKC_X_509_ATTR_CERT (1) -#define CKC_WTLS (2) -#define CKC_VENDOR_DEFINED (1U << 31) +#define CKC_X_509 (0UL) +#define CKC_X_509_ATTR_CERT (1UL) +#define CKC_WTLS (2UL) +#define CKC_VENDOR_DEFINED (1UL << 31) typedef unsigned long ck_attribute_type_t; -#define CKA_CLASS (0) -#define CKA_TOKEN (1) -#define CKA_PRIVATE (2) -#define CKA_LABEL (3) -#define CKA_APPLICATION (0x10) -#define CKA_VALUE (0x11) -#define CKA_OBJECT_ID (0x12) -#define CKA_CERTIFICATE_TYPE (0x80) -#define CKA_ISSUER (0x81) -#define CKA_SERIAL_NUMBER (0x82) -#define CKA_AC_ISSUER (0x83) -#define CKA_OWNER (0x84) -#define CKA_ATTR_TYPES (0x85) -#define CKA_TRUSTED (0x86) -#define CKA_CERTIFICATE_CATEGORY (0x87) -#define CKA_JAVA_MIDP_SECURITY_DOMAIN (0x88) -#define CKA_URL (0x89) -#define CKA_HASH_OF_SUBJECT_PUBLIC_KEY (0x8a) -#define CKA_HASH_OF_ISSUER_PUBLIC_KEY (0x8b) -#define CKA_CHECK_VALUE (0x90) -#define CKA_KEY_TYPE (0x100) -#define CKA_SUBJECT (0x101) -#define CKA_ID (0x102) -#define CKA_SENSITIVE (0x103) -#define CKA_ENCRYPT (0x104) -#define CKA_DECRYPT (0x105) -#define CKA_WRAP (0x106) -#define CKA_UNWRAP (0x107) -#define CKA_SIGN (0x108) -#define CKA_SIGN_RECOVER (0x109) -#define CKA_VERIFY (0x10a) -#define CKA_VERIFY_RECOVER (0x10b) -#define CKA_DERIVE (0x10c) -#define CKA_START_DATE (0x110) -#define CKA_END_DATE (0x111) -#define CKA_MODULUS (0x120) -#define CKA_MODULUS_BITS (0x121) -#define CKA_PUBLIC_EXPONENT (0x122) -#define CKA_PRIVATE_EXPONENT (0x123) -#define CKA_PRIME_1 (0x124) -#define CKA_PRIME_2 (0x125) -#define CKA_EXPONENT_1 (0x126) -#define CKA_EXPONENT_2 (0x127) -#define CKA_COEFFICIENT (0x128) -#define CKA_PRIME (0x130) -#define CKA_SUBPRIME (0x131) -#define CKA_BASE (0x132) -#define CKA_PRIME_BITS (0x133) -#define CKA_SUB_PRIME_BITS (0x134) -#define CKA_VALUE_BITS (0x160) -#define CKA_VALUE_LEN (0x161) -#define CKA_EXTRACTABLE (0x162) -#define CKA_LOCAL (0x163) -#define CKA_NEVER_EXTRACTABLE (0x164) -#define CKA_ALWAYS_SENSITIVE (0x165) -#define CKA_KEY_GEN_MECHANISM (0x166) -#define CKA_MODIFIABLE (0x170) -#define CKA_ECDSA_PARAMS (0x180) -#define CKA_EC_PARAMS (0x180) -#define CKA_EC_POINT (0x181) -#define CKA_SECONDARY_AUTH (0x200) -#define CKA_AUTH_PIN_FLAGS (0x201) -#define CKA_ALWAYS_AUTHENTICATE (0x202) -#define CKA_WRAP_WITH_TRUSTED (0x210) -#define CKA_HW_FEATURE_TYPE (0x300) -#define CKA_RESET_ON_INIT (0x301) -#define CKA_HAS_RESET (0x302) -#define CKA_PIXEL_X (0x400) -#define CKA_PIXEL_Y (0x401) -#define CKA_RESOLUTION (0x402) -#define CKA_CHAR_ROWS (0x403) -#define CKA_CHAR_COLUMNS (0x404) -#define CKA_COLOR (0x405) -#define CKA_BITS_PER_PIXEL (0x406) -#define CKA_CHAR_SETS (0x480) -#define CKA_ENCODING_METHODS (0x481) -#define CKA_MIME_TYPES (0x482) -#define CKA_MECHANISM_TYPE (0x500) -#define CKA_REQUIRED_CMS_ATTRIBUTES (0x501) -#define CKA_DEFAULT_CMS_ATTRIBUTES (0x502) -#define CKA_SUPPORTED_CMS_ATTRIBUTES (0x503) -#define CKA_WRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE | 0x211) -#define CKA_UNWRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE | 0x212) -#define CKA_ALLOWED_MECHANISMS (CKF_ARRAY_ATTRIBUTE | 0x600) -#define CKA_VENDOR_DEFINED (1U << 31) +#define CKA_CLASS (0UL) +#define CKA_TOKEN (1UL) +#define CKA_PRIVATE (2UL) +#define CKA_LABEL (3UL) +#define CKA_UNIQUE_ID (4UL) +#define CKA_APPLICATION (0x10UL) +#define CKA_VALUE (0x11UL) +#define CKA_OBJECT_ID (0x12UL) +#define CKA_CERTIFICATE_TYPE (0x80UL) +#define CKA_ISSUER (0x81UL) +#define CKA_SERIAL_NUMBER (0x82UL) +#define CKA_AC_ISSUER (0x83UL) +#define CKA_OWNER (0x84UL) +#define CKA_ATTR_TYPES (0x85UL) +#define CKA_TRUSTED (0x86UL) +#define CKA_CERTIFICATE_CATEGORY (0x87UL) +#define CKA_JAVA_MIDP_SECURITY_DOMAIN (0x88UL) +#define CKA_URL (0x89UL) +#define CKA_HASH_OF_SUBJECT_PUBLIC_KEY (0x8aUL) +#define CKA_HASH_OF_ISSUER_PUBLIC_KEY (0x8bUL) +#define CKA_CHECK_VALUE (0x90UL) +#define CKA_KEY_TYPE (0x100UL) +#define CKA_SUBJECT (0x101UL) +#define CKA_ID (0x102UL) +#define CKA_SENSITIVE (0x103UL) +#define CKA_ENCRYPT (0x104UL) +#define CKA_DECRYPT (0x105UL) +#define CKA_WRAP (0x106UL) +#define CKA_UNWRAP (0x107UL) +#define CKA_SIGN (0x108UL) +#define CKA_SIGN_RECOVER (0x109UL) +#define CKA_VERIFY (0x10aUL) +#define CKA_VERIFY_RECOVER (0x10bUL) +#define CKA_DERIVE (0x10cUL) +#define CKA_START_DATE (0x110UL) +#define CKA_END_DATE (0x111UL) +#define CKA_MODULUS (0x120UL) +#define CKA_MODULUS_BITS (0x121UL) +#define CKA_PUBLIC_EXPONENT (0x122UL) +#define CKA_PRIVATE_EXPONENT (0x123UL) +#define CKA_PRIME_1 (0x124UL) +#define CKA_PRIME_2 (0x125UL) +#define CKA_EXPONENT_1 (0x126UL) +#define CKA_EXPONENT_2 (0x127UL) +#define CKA_COEFFICIENT (0x128UL) +#define CKA_PUBLIC_KEY_INFO (0x129UL) +#define CKA_PRIME (0x130UL) +#define CKA_SUBPRIME (0x131UL) +#define CKA_BASE (0x132UL) +#define CKA_PRIME_BITS (0x133UL) +#define CKA_SUB_PRIME_BITS (0x134UL) +#define CKA_VALUE_BITS (0x160UL) +#define CKA_VALUE_LEN (0x161UL) +#define CKA_EXTRACTABLE (0x162UL) +#define CKA_LOCAL (0x163UL) +#define CKA_NEVER_EXTRACTABLE (0x164UL) +#define CKA_ALWAYS_SENSITIVE (0x165UL) +#define CKA_KEY_GEN_MECHANISM (0x166UL) +#define CKA_MODIFIABLE (0x170UL) +#define CKA_COPYABLE (0x171UL) +#define CKA_DESTROYABLE (0x172UL) +#define CKA_ECDSA_PARAMS (0x180UL) +#define CKA_EC_PARAMS (0x180UL) +#define CKA_EC_POINT (0x181UL) +#define CKA_SECONDARY_AUTH (0x200UL) +#define CKA_AUTH_PIN_FLAGS (0x201UL) +#define CKA_ALWAYS_AUTHENTICATE (0x202UL) +#define CKA_WRAP_WITH_TRUSTED (0x210UL) +#define CKA_GOSTR3410_PARAMS (0x250UL) +#define CKA_GOSTR3411_PARAMS (0x251UL) +#define CKA_GOST28147_PARAMS (0x252UL) +#define CKA_HW_FEATURE_TYPE (0x300UL) +#define CKA_RESET_ON_INIT (0x301UL) +#define CKA_HAS_RESET (0x302UL) +#define CKA_PIXEL_X (0x400UL) +#define CKA_PIXEL_Y (0x401UL) +#define CKA_RESOLUTION (0x402UL) +#define CKA_CHAR_ROWS (0x403UL) +#define CKA_CHAR_COLUMNS (0x404UL) +#define CKA_COLOR (0x405UL) +#define CKA_BITS_PER_PIXEL (0x406UL) +#define CKA_CHAR_SETS (0x480UL) +#define CKA_ENCODING_METHODS (0x481UL) +#define CKA_MIME_TYPES (0x482UL) +#define CKA_MECHANISM_TYPE (0x500UL) +#define CKA_REQUIRED_CMS_ATTRIBUTES (0x501UL) +#define CKA_DEFAULT_CMS_ATTRIBUTES (0x502UL) +#define CKA_SUPPORTED_CMS_ATTRIBUTES (0x503UL) +#define CKA_WRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE | 0x211UL) +#define CKA_UNWRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE | 0x212UL) +#define CKA_OTP_FORMAT (0x220UL) +#define CKA_OTP_LENGTH (0x221UL) +#define CKA_OTP_TIME_INTERVAL (0x222UL) +#define CKA_OTP_USER_FRIENDLY_MODE (0x223UL) +#define CKA_OTP_CHALLENGE_REQUIREMENT (0x224UL) +#define CKA_OTP_TIME_REQUIREMENT (0x225UL) +#define CKA_OTP_COUNTER_REQUIREMENT (0x226UL) +#define CKA_OTP_PIN_REQUIREMENT (0x227UL) +#define CKA_OTP_USER_IDENTIFIER (0x22AUL) +#define CKA_OTP_SERVICE_IDENTIFIER (0x22BUL) +#define CKA_OTP_SERVICE_LOGO (0x22CUL) +#define CKA_OTP_SERVICE_LOGO_TYPE (0x22DUL) +#define CKA_OTP_COUNTER (0x22EUL) +#define CKA_OTP_TIME (0x22FUL) +#define CKA_ALLOWED_MECHANISMS (CKF_ARRAY_ATTRIBUTE | 0x600UL) +#define CKA_PROFILE_ID (0x601UL) +#define CKA_VENDOR_DEFINED (1UL << 31) struct ck_attribute @@ -474,206 +522,304 @@ struct ck_date typedef unsigned long ck_mechanism_type_t; -#define CKM_RSA_PKCS_KEY_PAIR_GEN (0) -#define CKM_RSA_PKCS (1) -#define CKM_RSA_9796 (2) -#define CKM_RSA_X_509 (3) -#define CKM_MD2_RSA_PKCS (4) -#define CKM_MD5_RSA_PKCS (5) -#define CKM_SHA1_RSA_PKCS (6) -#define CKM_RIPEMD128_RSA_PKCS (7) -#define CKM_RIPEMD160_RSA_PKCS (8) -#define CKM_RSA_PKCS_OAEP (9) -#define CKM_RSA_X9_31_KEY_PAIR_GEN (0xa) -#define CKM_RSA_X9_31 (0xb) -#define CKM_SHA1_RSA_X9_31 (0xc) -#define CKM_RSA_PKCS_PSS (0xd) -#define CKM_SHA1_RSA_PKCS_PSS (0xe) -#define CKM_DSA_KEY_PAIR_GEN (0x10) -#define CKM_DSA (0x11) -#define CKM_DSA_SHA1 (0x12) -#define CKM_DH_PKCS_KEY_PAIR_GEN (0x20) -#define CKM_DH_PKCS_DERIVE (0x21) -#define CKM_X9_42_DH_KEY_PAIR_GEN (0x30) -#define CKM_X9_42_DH_DERIVE (0x31) -#define CKM_X9_42_DH_HYBRID_DERIVE (0x32) -#define CKM_X9_42_MQV_DERIVE (0x33) -#define CKM_SHA256_RSA_PKCS (0x40) -#define CKM_SHA384_RSA_PKCS (0x41) -#define CKM_SHA512_RSA_PKCS (0x42) -#define CKM_SHA256_RSA_PKCS_PSS (0x43) -#define CKM_SHA384_RSA_PKCS_PSS (0x44) -#define CKM_SHA512_RSA_PKCS_PSS (0x45) -#define CKM_RC2_KEY_GEN (0x100) -#define CKM_RC2_ECB (0x101) -#define CKM_RC2_CBC (0x102) -#define CKM_RC2_MAC (0x103) -#define CKM_RC2_MAC_GENERAL (0x104) -#define CKM_RC2_CBC_PAD (0x105) -#define CKM_RC4_KEY_GEN (0x110) -#define CKM_RC4 (0x111) -#define CKM_DES_KEY_GEN (0x120) -#define CKM_DES_ECB (0x121) -#define CKM_DES_CBC (0x122) -#define CKM_DES_MAC (0x123) -#define CKM_DES_MAC_GENERAL (0x124) -#define CKM_DES_CBC_PAD (0x125) -#define CKM_DES2_KEY_GEN (0x130) -#define CKM_DES3_KEY_GEN (0x131) -#define CKM_DES3_ECB (0x132) -#define CKM_DES3_CBC (0x133) -#define CKM_DES3_MAC (0x134) -#define CKM_DES3_MAC_GENERAL (0x135) -#define CKM_DES3_CBC_PAD (0x136) -#define CKM_CDMF_KEY_GEN (0x140) -#define CKM_CDMF_ECB (0x141) -#define CKM_CDMF_CBC (0x142) -#define CKM_CDMF_MAC (0x143) -#define CKM_CDMF_MAC_GENERAL (0x144) -#define CKM_CDMF_CBC_PAD (0x145) -#define CKM_MD2 (0x200) -#define CKM_MD2_HMAC (0x201) -#define CKM_MD2_HMAC_GENERAL (0x202) -#define CKM_MD5 (0x210) -#define CKM_MD5_HMAC (0x211) -#define CKM_MD5_HMAC_GENERAL (0x212) -#define CKM_SHA_1 (0x220) -#define CKM_SHA_1_HMAC (0x221) -#define CKM_SHA_1_HMAC_GENERAL (0x222) -#define CKM_RIPEMD128 (0x230) -#define CKM_RIPEMD128_HMAC (0x231) -#define CKM_RIPEMD128_HMAC_GENERAL (0x232) -#define CKM_RIPEMD160 (0x240) -#define CKM_RIPEMD160_HMAC (0x241) -#define CKM_RIPEMD160_HMAC_GENERAL (0x242) -#define CKM_SHA256 (0x250) -#define CKM_SHA256_HMAC (0x251) -#define CKM_SHA256_HMAC_GENERAL (0x252) -#define CKM_SHA384 (0x260) -#define CKM_SHA384_HMAC (0x261) -#define CKM_SHA384_HMAC_GENERAL (0x262) -#define CKM_SHA512 (0x270) -#define CKM_SHA512_HMAC (0x271) -#define CKM_SHA512_HMAC_GENERAL (0x272) -#define CKM_CAST_KEY_GEN (0x300) -#define CKM_CAST_ECB (0x301) -#define CKM_CAST_CBC (0x302) -#define CKM_CAST_MAC (0x303) -#define CKM_CAST_MAC_GENERAL (0x304) -#define CKM_CAST_CBC_PAD (0x305) -#define CKM_CAST3_KEY_GEN (0x310) -#define CKM_CAST3_ECB (0x311) -#define CKM_CAST3_CBC (0x312) -#define CKM_CAST3_MAC (0x313) -#define CKM_CAST3_MAC_GENERAL (0x314) -#define CKM_CAST3_CBC_PAD (0x315) -#define CKM_CAST5_KEY_GEN (0x320) -#define CKM_CAST128_KEY_GEN (0x320) -#define CKM_CAST5_ECB (0x321) -#define CKM_CAST128_ECB (0x321) -#define CKM_CAST5_CBC (0x322) -#define CKM_CAST128_CBC (0x322) -#define CKM_CAST5_MAC (0x323) -#define CKM_CAST128_MAC (0x323) -#define CKM_CAST5_MAC_GENERAL (0x324) -#define CKM_CAST128_MAC_GENERAL (0x324) -#define CKM_CAST5_CBC_PAD (0x325) -#define CKM_CAST128_CBC_PAD (0x325) -#define CKM_RC5_KEY_GEN (0x330) -#define CKM_RC5_ECB (0x331) -#define CKM_RC5_CBC (0x332) -#define CKM_RC5_MAC (0x333) -#define CKM_RC5_MAC_GENERAL (0x334) -#define CKM_RC5_CBC_PAD (0x335) -#define CKM_IDEA_KEY_GEN (0x340) -#define CKM_IDEA_ECB (0x341) -#define CKM_IDEA_CBC (0x342) -#define CKM_IDEA_MAC (0x343) -#define CKM_IDEA_MAC_GENERAL (0x344) -#define CKM_IDEA_CBC_PAD (0x345) -#define CKM_GENERIC_SECRET_KEY_GEN (0x350) -#define CKM_CONCATENATE_BASE_AND_KEY (0x360) -#define CKM_CONCATENATE_BASE_AND_DATA (0x362) -#define CKM_CONCATENATE_DATA_AND_BASE (0x363) -#define CKM_XOR_BASE_AND_DATA (0x364) -#define CKM_EXTRACT_KEY_FROM_KEY (0x365) -#define CKM_SSL3_PRE_MASTER_KEY_GEN (0x370) -#define CKM_SSL3_MASTER_KEY_DERIVE (0x371) -#define CKM_SSL3_KEY_AND_MAC_DERIVE (0x372) -#define CKM_SSL3_MASTER_KEY_DERIVE_DH (0x373) -#define CKM_TLS_PRE_MASTER_KEY_GEN (0x374) -#define CKM_TLS_MASTER_KEY_DERIVE (0x375) -#define CKM_TLS_KEY_AND_MAC_DERIVE (0x376) -#define CKM_TLS_MASTER_KEY_DERIVE_DH (0x377) -#define CKM_SSL3_MD5_MAC (0x380) -#define CKM_SSL3_SHA1_MAC (0x381) -#define CKM_MD5_KEY_DERIVATION (0x390) -#define CKM_MD2_KEY_DERIVATION (0x391) -#define CKM_SHA1_KEY_DERIVATION (0x392) -#define CKM_PBE_MD2_DES_CBC (0x3a0) -#define CKM_PBE_MD5_DES_CBC (0x3a1) -#define CKM_PBE_MD5_CAST_CBC (0x3a2) -#define CKM_PBE_MD5_CAST3_CBC (0x3a3) -#define CKM_PBE_MD5_CAST5_CBC (0x3a4) -#define CKM_PBE_MD5_CAST128_CBC (0x3a4) -#define CKM_PBE_SHA1_CAST5_CBC (0x3a5) -#define CKM_PBE_SHA1_CAST128_CBC (0x3a5) -#define CKM_PBE_SHA1_RC4_128 (0x3a6) -#define CKM_PBE_SHA1_RC4_40 (0x3a7) -#define CKM_PBE_SHA1_DES3_EDE_CBC (0x3a8) -#define CKM_PBE_SHA1_DES2_EDE_CBC (0x3a9) -#define CKM_PBE_SHA1_RC2_128_CBC (0x3aa) -#define CKM_PBE_SHA1_RC2_40_CBC (0x3ab) -#define CKM_PKCS5_PBKD2 (0x3b0) -#define CKM_PBA_SHA1_WITH_SHA1_HMAC (0x3c0) -#define CKM_KEY_WRAP_LYNKS (0x400) -#define CKM_KEY_WRAP_SET_OAEP (0x401) -#define CKM_SKIPJACK_KEY_GEN (0x1000) -#define CKM_SKIPJACK_ECB64 (0x1001) -#define CKM_SKIPJACK_CBC64 (0x1002) -#define CKM_SKIPJACK_OFB64 (0x1003) -#define CKM_SKIPJACK_CFB64 (0x1004) -#define CKM_SKIPJACK_CFB32 (0x1005) -#define CKM_SKIPJACK_CFB16 (0x1006) -#define CKM_SKIPJACK_CFB8 (0x1007) -#define CKM_SKIPJACK_WRAP (0x1008) -#define CKM_SKIPJACK_PRIVATE_WRAP (0x1009) -#define CKM_SKIPJACK_RELAYX (0x100a) -#define CKM_KEA_KEY_PAIR_GEN (0x1010) -#define CKM_KEA_KEY_DERIVE (0x1011) -#define CKM_FORTEZZA_TIMESTAMP (0x1020) -#define CKM_BATON_KEY_GEN (0x1030) -#define CKM_BATON_ECB128 (0x1031) -#define CKM_BATON_ECB96 (0x1032) -#define CKM_BATON_CBC128 (0x1033) -#define CKM_BATON_COUNTER (0x1034) -#define CKM_BATON_SHUFFLE (0x1035) -#define CKM_BATON_WRAP (0x1036) -#define CKM_ECDSA_KEY_PAIR_GEN (0x1040) -#define CKM_EC_KEY_PAIR_GEN (0x1040) -#define CKM_ECDSA (0x1041) -#define CKM_ECDSA_SHA1 (0x1042) -#define CKM_ECDH1_DERIVE (0x1050) -#define CKM_ECDH1_COFACTOR_DERIVE (0x1051) -#define CKM_ECMQV_DERIVE (0x1052) -#define CKM_JUNIPER_KEY_GEN (0x1060) -#define CKM_JUNIPER_ECB128 (0x1061) -#define CKM_JUNIPER_CBC128 (0x1062) -#define CKM_JUNIPER_COUNTER (0x1063) -#define CKM_JUNIPER_SHUFFLE (0x1064) -#define CKM_JUNIPER_WRAP (0x1065) -#define CKM_FASTHASH (0x1070) -#define CKM_AES_KEY_GEN (0x1080) -#define CKM_AES_ECB (0x1081) -#define CKM_AES_CBC (0x1082) -#define CKM_AES_MAC (0x1083) -#define CKM_AES_MAC_GENERAL (0x1084) -#define CKM_AES_CBC_PAD (0x1085) -#define CKM_DSA_PARAMETER_GEN (0x2000) -#define CKM_DH_PKCS_PARAMETER_GEN (0x2001) -#define CKM_X9_42_DH_PARAMETER_GEN (0x2002) -#define CKM_VENDOR_DEFINED (1U << 31) - +#define CKM_RSA_PKCS_KEY_PAIR_GEN (0UL) +#define CKM_RSA_PKCS (1UL) +#define CKM_RSA_9796 (2UL) +#define CKM_RSA_X_509 (3UL) +#define CKM_MD2_RSA_PKCS (4UL) +#define CKM_MD5_RSA_PKCS (5UL) +#define CKM_SHA1_RSA_PKCS (6UL) +#define CKM_RIPEMD128_RSA_PKCS (7UL) +#define CKM_RIPEMD160_RSA_PKCS (8UL) +#define CKM_RSA_PKCS_OAEP (9UL) +#define CKM_RSA_X9_31_KEY_PAIR_GEN (0xaUL) +#define CKM_RSA_X9_31 (0xbUL) +#define CKM_SHA1_RSA_X9_31 (0xcUL) +#define CKM_RSA_PKCS_PSS (0xdUL) +#define CKM_SHA1_RSA_PKCS_PSS (0xeUL) +#define CKM_DSA_KEY_PAIR_GEN (0x10UL) +#define CKM_DSA (0x11UL) +#define CKM_DSA_SHA1 (0x12UL) +#define CKM_DSA_SHA224 (0x13UL) +#define CKM_DSA_SHA256 (0x14UL) +#define CKM_DSA_SHA384 (0x15UL) +#define CKM_DSA_SHA512 (0x16UL) +#define CKM_DH_PKCS_KEY_PAIR_GEN (0x20UL) +#define CKM_DH_PKCS_DERIVE (0x21UL) +#define CKM_X9_42_DH_KEY_PAIR_GEN (0x30UL) +#define CKM_X9_42_DH_DERIVE (0x31UL) +#define CKM_X9_42_DH_HYBRID_DERIVE (0x32UL) +#define CKM_X9_42_MQV_DERIVE (0x33UL) +#define CKM_SHA256_RSA_PKCS (0x40UL) +#define CKM_SHA384_RSA_PKCS (0x41UL) +#define CKM_SHA512_RSA_PKCS (0x42UL) +#define CKM_SHA256_RSA_PKCS_PSS (0x43UL) +#define CKM_SHA384_RSA_PKCS_PSS (0x44UL) +#define CKM_SHA512_RSA_PKCS_PSS (0x45UL) +#define CKM_SHA224_RSA_PKCS (0x46UL) +#define CKM_SHA224_RSA_PKCS_PSS (0x47UL) +#define CKM_SHA3_256_RSA_PKCS (0x60UL) +#define CKM_SHA3_384_RSA_PKCS (0x61UL) +#define CKM_SHA3_512_RSA_PKCS (0x62UL) +#define CKM_SHA3_256_RSA_PKCS_PSS (0x63UL) +#define CKM_SHA3_384_RSA_PKCS_PSS (0x64UL) +#define CKM_SHA3_512_RSA_PKCS_PSS (0x65UL) +#define CKM_SHA3_224_RSA_PKCS (0x66UL) +#define CKM_SHA3_224_RSA_PKCS_PSS (0x67UL) +#define CKM_RC2_KEY_GEN (0x100UL) +#define CKM_RC2_ECB (0x101UL) +#define CKM_RC2_CBC (0x102UL) +#define CKM_RC2_MAC (0x103UL) +#define CKM_RC2_MAC_GENERAL (0x104UL) +#define CKM_RC2_CBC_PAD (0x105UL) +#define CKM_RC4_KEY_GEN (0x110UL) +#define CKM_RC4 (0x111UL) +#define CKM_DES_KEY_GEN (0x120UL) +#define CKM_DES_ECB (0x121UL) +#define CKM_DES_CBC (0x122UL) +#define CKM_DES_MAC (0x123UL) +#define CKM_DES_MAC_GENERAL (0x124UL) +#define CKM_DES_CBC_PAD (0x125UL) +#define CKM_DES2_KEY_GEN (0x130UL) +#define CKM_DES3_KEY_GEN (0x131UL) +#define CKM_DES3_ECB (0x132UL) +#define CKM_DES3_CBC (0x133UL) +#define CKM_DES3_MAC (0x134UL) +#define CKM_DES3_MAC_GENERAL (0x135UL) +#define CKM_DES3_CBC_PAD (0x136UL) +#define CKM_DES3_CMAC_GENERAL (0x137UL) +#define CKM_DES3_CMAC (0x138UL) +#define CKM_CDMF_KEY_GEN (0x140UL) +#define CKM_CDMF_ECB (0x141UL) +#define CKM_CDMF_CBC (0x142UL) +#define CKM_CDMF_MAC (0x143UL) +#define CKM_CDMF_MAC_GENERAL (0x144UL) +#define CKM_CDMF_CBC_PAD (0x145UL) +#define CKM_MD2 (0x200UL) +#define CKM_MD2_HMAC (0x201UL) +#define CKM_MD2_HMAC_GENERAL (0x202UL) +#define CKM_MD5 (0x210UL) +#define CKM_MD5_HMAC (0x211UL) +#define CKM_MD5_HMAC_GENERAL (0x212UL) +#define CKM_SHA_1 (0x220UL) +#define CKM_SHA_1_HMAC (0x221UL) +#define CKM_SHA_1_HMAC_GENERAL (0x222UL) +#define CKM_RIPEMD128 (0x230UL) +#define CKM_RIPEMD128_HMAC (0x231UL) +#define CKM_RIPEMD128_HMAC_GENERAL (0x232UL) +#define CKM_RIPEMD160 (0x240UL) +#define CKM_RIPEMD160_HMAC (0x241UL) +#define CKM_RIPEMD160_HMAC_GENERAL (0x242UL) +#define CKM_SHA256 (0x250UL) +#define CKM_SHA256_HMAC (0x251UL) +#define CKM_SHA256_HMAC_GENERAL (0x252UL) +#define CKM_SHA224 (0x255UL) +#define CKM_SHA224_HMAC (0x256UL) +#define CKM_SHA224_HMAC_GENERAL (0x257UL) +#define CKM_SHA384 (0x260UL) +#define CKM_SHA384_HMAC (0x261UL) +#define CKM_SHA384_HMAC_GENERAL (0x262UL) +#define CKM_SHA512 (0x270UL) +#define CKM_SHA512_HMAC (0x271UL) +#define CKM_SHA512_HMAC_GENERAL (0x272UL) +#define CKM_SHA3_256 (0x2B0UL) +#define CKM_SHA3_256_HMAC (0x2B1UL) +#define CKM_SHA3_256_HMAC_GENERAL (0x2B2UL) +#define CKM_SHA3_256_KEY_GEN (0x2B3UL) +#define CKM_SHA3_224 (0x2B5UL) +#define CKM_SHA3_224_HMAC (0x2B6UL) +#define CKM_SHA3_224_HMAC_GENERAL (0x2B7UL) +#define CKM_SHA3_224_KEY_GEN (0x2B8UL) +#define CKM_SHA3_384 (0x2C0UL) +#define CKM_SHA3_384_HMAC (0x2C1UL) +#define CKM_SHA3_384_HMAC_GENERAL (0x2C2UL) +#define CKM_SHA3_384_KEY_GEN (0x2C3UL) +#define CKM_SHA3_512 (0x2D0UL) +#define CKM_SHA3_512_HMAC (0x2D1UL) +#define CKM_SHA3_512_HMAC_GENERAL (0x2D2UL) +#define CKM_SHA3_512_KEY_GEN (0x2D3UL) +#define CKM_CAST_KEY_GEN (0x300UL) +#define CKM_CAST_ECB (0x301UL) +#define CKM_CAST_CBC (0x302UL) +#define CKM_CAST_MAC (0x303UL) +#define CKM_CAST_MAC_GENERAL (0x304UL) +#define CKM_CAST_CBC_PAD (0x305UL) +#define CKM_CAST3_KEY_GEN (0x310UL) +#define CKM_CAST3_ECB (0x311UL) +#define CKM_CAST3_CBC (0x312UL) +#define CKM_CAST3_MAC (0x313UL) +#define CKM_CAST3_MAC_GENERAL (0x314UL) +#define CKM_CAST3_CBC_PAD (0x315UL) +#define CKM_CAST5_KEY_GEN (0x320UL) +#define CKM_CAST128_KEY_GEN (0x320UL) +#define CKM_CAST5_ECB (0x321UL) +#define CKM_CAST128_ECB (0x321UL) +#define CKM_CAST5_CBC (0x322UL) +#define CKM_CAST128_CBC (0x322UL) +#define CKM_CAST5_MAC (0x323UL) +#define CKM_CAST128_MAC (0x323UL) +#define CKM_CAST5_MAC_GENERAL (0x324UL) +#define CKM_CAST128_MAC_GENERAL (0x324UL) +#define CKM_CAST5_CBC_PAD (0x325UL) +#define CKM_CAST128_CBC_PAD (0x325UL) +#define CKM_RC5_KEY_GEN (0x330UL) +#define CKM_RC5_ECB (0x331UL) +#define CKM_RC5_CBC (0x332UL) +#define CKM_RC5_MAC (0x333UL) +#define CKM_RC5_MAC_GENERAL (0x334UL) +#define CKM_RC5_CBC_PAD (0x335UL) +#define CKM_IDEA_KEY_GEN (0x340UL) +#define CKM_IDEA_ECB (0x341UL) +#define CKM_IDEA_CBC (0x342UL) +#define CKM_IDEA_MAC (0x343UL) +#define CKM_IDEA_MAC_GENERAL (0x344UL) +#define CKM_IDEA_CBC_PAD (0x345UL) +#define CKM_GENERIC_SECRET_KEY_GEN (0x350UL) +#define CKM_CONCATENATE_BASE_AND_KEY (0x360UL) +#define CKM_CONCATENATE_BASE_AND_DATA (0x362UL) +#define CKM_CONCATENATE_DATA_AND_BASE (0x363UL) +#define CKM_XOR_BASE_AND_DATA (0x364UL) +#define CKM_EXTRACT_KEY_FROM_KEY (0x365UL) +#define CKM_SSL3_PRE_MASTER_KEY_GEN (0x370UL) +#define CKM_SSL3_MASTER_KEY_DERIVE (0x371UL) +#define CKM_SSL3_KEY_AND_MAC_DERIVE (0x372UL) +#define CKM_SSL3_MASTER_KEY_DERIVE_DH (0x373UL) +#define CKM_TLS_PRE_MASTER_KEY_GEN (0x374UL) +#define CKM_TLS_MASTER_KEY_DERIVE (0x375UL) +#define CKM_TLS_KEY_AND_MAC_DERIVE (0x376UL) +#define CKM_TLS_MASTER_KEY_DERIVE_DH (0x377UL) +#define CKM_SSL3_MD5_MAC (0x380UL) +#define CKM_SSL3_SHA1_MAC (0x381UL) +#define CKM_MD5_KEY_DERIVATION (0x390UL) +#define CKM_MD2_KEY_DERIVATION (0x391UL) +#define CKM_SHA1_KEY_DERIVATION (0x392UL) +#define CKM_PBE_MD2_DES_CBC (0x3a0UL) +#define CKM_PBE_MD5_DES_CBC (0x3a1UL) +#define CKM_PBE_MD5_CAST_CBC (0x3a2UL) +#define CKM_PBE_MD5_CAST3_CBC (0x3a3UL) +#define CKM_PBE_MD5_CAST5_CBC (0x3a4UL) +#define CKM_PBE_MD5_CAST128_CBC (0x3a4UL) +#define CKM_PBE_SHA1_CAST5_CBC (0x3a5UL) +#define CKM_PBE_SHA1_CAST128_CBC (0x3a5UL) +#define CKM_PBE_SHA1_RC4_128 (0x3a6UL) +#define CKM_PBE_SHA1_RC4_40 (0x3a7UL) +#define CKM_PBE_SHA1_DES3_EDE_CBC (0x3a8UL) +#define CKM_PBE_SHA1_DES2_EDE_CBC (0x3a9UL) +#define CKM_PBE_SHA1_RC2_128_CBC (0x3aaUL) +#define CKM_PBE_SHA1_RC2_40_CBC (0x3abUL) +#define CKM_PKCS5_PBKD2 (0x3b0UL) +#define CKM_PBA_SHA1_WITH_SHA1_HMAC (0x3c0UL) +#define CKM_KEY_WRAP_LYNKS (0x400UL) +#define CKM_KEY_WRAP_SET_OAEP (0x401UL) +#define CKM_SKIPJACK_KEY_GEN (0x1000UL) +#define CKM_SKIPJACK_ECB64 (0x1001UL) +#define CKM_SKIPJACK_CBC64 (0x1002UL) +#define CKM_SKIPJACK_OFB64 (0x1003UL) +#define CKM_SKIPJACK_CFB64 (0x1004UL) +#define CKM_SKIPJACK_CFB32 (0x1005UL) +#define CKM_SKIPJACK_CFB16 (0x1006UL) +#define CKM_SKIPJACK_CFB8 (0x1007UL) +#define CKM_SKIPJACK_WRAP (0x1008UL) +#define CKM_SKIPJACK_PRIVATE_WRAP (0x1009UL) +#define CKM_SKIPJACK_RELAYX (0x100aUL) +#define CKM_KEA_KEY_PAIR_GEN (0x1010UL) +#define CKM_KEA_KEY_DERIVE (0x1011UL) +#define CKM_FORTEZZA_TIMESTAMP (0x1020UL) +#define CKM_BATON_KEY_GEN (0x1030UL) +#define CKM_BATON_ECB128 (0x1031UL) +#define CKM_BATON_ECB96 (0x1032UL) +#define CKM_BATON_CBC128 (0x1033UL) +#define CKM_BATON_COUNTER (0x1034UL) +#define CKM_BATON_SHUFFLE (0x1035UL) +#define CKM_BATON_WRAP (0x1036UL) +#define CKM_ECDSA_KEY_PAIR_GEN (0x1040UL) +#define CKM_EC_KEY_PAIR_GEN (0x1040UL) +#define CKM_ECDSA (0x1041UL) +#define CKM_ECDSA_SHA1 (0x1042UL) +#define CKM_ECDSA_SHA224 (0x1043UL) +#define CKM_ECDSA_SHA256 (0x1044UL) +#define CKM_ECDSA_SHA384 (0x1045UL) +#define CKM_ECDSA_SHA512 (0x1046UL) +#define CKM_ECDSA_SHA3_224 (0x1047UL) +#define CKM_ECDSA_SHA3_256 (0x1048UL) +#define CKM_ECDSA_SHA3_384 (0x1049UL) +#define CKM_ECDSA_SHA3_512 (0x104AUL) +#define CKM_ECDH1_DERIVE (0x1050UL) +#define CKM_ECDH1_COFACTOR_DERIVE (0x1051UL) +#define CKM_ECMQV_DERIVE (0x1052UL) +#define CKM_EC_EDWARDS_KEY_PAIR_GEN (0x1055UL) +#define CKM_EC_MONTGOMERY_KEY_PAIR_GEN (0x1056UL) +#define CKM_EDDSA (0x1057UL) +#define CKM_JUNIPER_KEY_GEN (0x1060UL) +#define CKM_JUNIPER_ECB128 (0x1061UL) +#define CKM_JUNIPER_CBC128 (0x1062UL) +#define CKM_JUNIPER_COUNTER (0x1063UL) +#define CKM_JUNIPER_SHUFFLE (0x1064UL) +#define CKM_JUNIPER_WRAP (0x1065UL) +#define CKM_FASTHASH (0x1070UL) +#define CKM_AES_KEY_GEN (0x1080UL) +#define CKM_AES_ECB (0x1081UL) +#define CKM_AES_CBC (0x1082UL) +#define CKM_AES_MAC (0x1083UL) +#define CKM_AES_MAC_GENERAL (0x1084UL) +#define CKM_AES_CBC_PAD (0x1085UL) +#define CKM_AES_CTR (0x1086UL) +#define CKM_AES_GCM (0x1087UL) +#define CKM_AES_CCM (0x1088UL) +#define CKM_AES_CTS (0x1089UL) +#define CKM_AES_CMAC (0x108AUL) +#define CKM_AES_CMAC_GENERAL (0x108BUL) +#define CKM_AES_XCBC_MAC (0x108CUL) +#define CKM_AES_XCBC_MAC_96 (0x108DUL) +#define CKM_AES_GMAC (0x108EUL) +#define CKM_BLOWFISH_KEY_GEN (0x1090UL) +#define CKM_BLOWFISH_CBC (0x1091UL) +#define CKM_TWOFISH_KEY_GEN (0x1092UL) +#define CKM_TWOFISH_CBC (0x1093UL) +#define CKM_DES_ECB_ENCRYPT_DATA (0x1100UL) +#define CKM_DES_CBC_ENCRYPT_DATA (0x1101UL) +#define CKM_DES3_ECB_ENCRYPT_DATA (0x1102UL) +#define CKM_DES3_CBC_ENCRYPT_DATA (0x1103UL) +#define CKM_AES_ECB_ENCRYPT_DATA (0x1104UL) +#define CKM_AES_CBC_ENCRYPT_DATA (0x1105UL) +#define CKM_GOSTR3410_KEY_PAIR_GEN (0x1200UL) +#define CKM_GOSTR3410 (0x1201UL) +#define CKM_GOSTR3410_WITH_GOSTR3411 (0x1202UL) +#define CKM_GOSTR3410_KEY_WRAP (0x1203UL) +#define CKM_GOSTR3410_DERIVE (0x1204UL) +#define CKM_GOSTR3410_512_KEY_PAIR_GEN (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x005) +#define CKM_GOSTR3410_512 (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x006) +#define CKM_GOSTR3410_12_DERIVE (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x007) +#define CKM_GOSTR3410_WITH_GOSTR3411_12_256 (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x008) +#define CKM_GOSTR3410_WITH_GOSTR3411_12_512 (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x009) +#define CKM_GOSTR3411 (0x1210UL) +#define CKM_GOSTR3411_HMAC (0x1211UL) +#define CKM_GOSTR3411_12_256 (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x012) +#define CKM_GOSTR3411_12_512 (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x013) +#define CKM_GOSTR3411_12_256_HMAC (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x014) +#define CKM_GOSTR3411_12_512_HMAC (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x015) +#define CKM_GOST28147_KEY_GEN (0x1220UL) +#define CKM_GOST28147_ECB (0x1221UL) +#define CKM_GOST28147 (0x1222UL) +#define CKM_GOST28147_MAC (0x1223UL) +#define CKM_GOST28147_KEY_WRAP (0x1224UL) + +#define CKM_DSA_PARAMETER_GEN (0x2000UL) +#define CKM_DH_PKCS_PARAMETER_GEN (0x2001UL) +#define CKM_X9_42_DH_PARAMETER_GEN (0x2002UL) +#define CKM_AES_OFB (0x2104UL) +#define CKM_AES_CFB64 (0x2105UL) +#define CKM_AES_CFB8 (0x2106UL) +#define CKM_AES_CFB128 (0x2107UL) +#define CKM_AES_CFB1 (0x2108UL) +#define CKM_AES_KEY_WRAP (0x2109UL) +#define CKM_AES_KEY_WRAP_PAD (0x210AUL) +#define CKM_XEDDSA (0x4029UL) +#define CKM_HKDF_DERIVE (0x402AUL) +#define CKM_HKDF_DATA (0x402BUL) +#define CKM_HKDF_KEY_GEN (0x402CUL) + +#define CKM_VENDOR_DEFINED (1UL << 31) struct ck_mechanism { @@ -690,25 +836,143 @@ struct ck_mechanism_info ck_flags_t flags; }; -#define CKF_HW (1 << 0) -#define CKF_ENCRYPT (1 << 8) -#define CKF_DECRYPT (1 << 9) -#define CKF_DIGEST (1 << 10) -#define CKF_SIGN (1 << 11) -#define CKF_SIGN_RECOVER (1 << 12) -#define CKF_VERIFY (1 << 13) -#define CKF_VERIFY_RECOVER (1 << 14) -#define CKF_GENERATE (1 << 15) -#define CKF_GENERATE_KEY_PAIR (1 << 16) -#define CKF_WRAP (1 << 17) -#define CKF_UNWRAP (1 << 18) -#define CKF_DERIVE (1 << 19) -#define CKF_EXTENSION (1U << 31) - +#define CKF_HW (1UL << 0) + +#define CKF_MESSAGE_ENCRYPT (1UL << 1) +#define CKF_MESSAGE_DECRYPT (1UL << 2) +#define CKF_MESSAGE_SIGN (1UL << 3) +#define CKF_MESSAGE_VERIFY (1UL << 4) +#define CKF_MULTI_MESSAGE (1UL << 5) +#define CKF_FIND_OBJECTS (1UL << 6) + +#define CKF_ENCRYPT (1UL << 8) +#define CKF_DECRYPT (1UL << 9) +#define CKF_DIGEST (1UL << 10) +#define CKF_SIGN (1UL << 11) +#define CKF_SIGN_RECOVER (1UL << 12) +#define CKF_VERIFY (1UL << 13) +#define CKF_VERIFY_RECOVER (1UL << 14) +#define CKF_GENERATE (1UL << 15) +#define CKF_GENERATE_KEY_PAIR (1UL << 16) +#define CKF_WRAP (1UL << 17) +#define CKF_UNWRAP (1UL << 18) +#define CKF_DERIVE (1UL << 19) +#define CKF_EXTENSION (1UL << 31) + +#define CKF_EC_F_P (1UL << 20) +#define CKF_EC_F_2M (1UL << 21) +#define CKF_EC_ECPARAMETERS (1UL << 22) +#define CKF_EC_OID (1UL << 23) +#define CKF_EC_NAMEDCURVE CKF_EC_OID +#define CKF_EC_UNCOMPRESS (1UL << 24) +#define CKF_EC_COMPRESS (1UL << 25) +#define CKF_EC_CURVENAME (1UL << 26) /* Flags for C_WaitForSlotEvent. */ -#define CKF_DONT_BLOCK (1) - +#define CKF_DONT_BLOCK (1UL) + +/* Flags for Key derivation */ +#define CKD_NULL (0x1UL) +#define CKD_SHA1_KDF (0x2UL) +#define CKD_SHA224_KDF (0x5UL) +#define CKD_SHA256_KDF (0x6UL) +#define CKD_SHA384_KDF (0x7UL) +#define CKD_SHA512_KDF (0x8UL) + +typedef struct CK_ECDH1_DERIVE_PARAMS { + unsigned long kdf; + unsigned long ulSharedDataLen; + unsigned char * pSharedData; + unsigned long ulPublicDataLen; + unsigned char * pPublicData; +} CK_ECDH1_DERIVE_PARAMS; + +typedef struct CK_ECMQV_DERIVE_PARAMS { + unsigned long kdf; + unsigned long ulSharedDataLen; + unsigned char * pSharedData; + unsigned long ulPublicDataLen; + unsigned char * pPublicData; + unsigned long ulPrivateDataLen; + CK_OBJECT_HANDLE hPrivateData; + unsigned long ulPublicDataLen2; + unsigned char * pPublicData2; + CK_OBJECT_HANDLE publicKey; +} CK_ECMQV_DERIVE_PARAMS; + +typedef unsigned long ck_rsa_pkcs_mgf_type_t; +typedef unsigned long CK_RSA_PKCS_OAEP_SOURCE_TYPE; + +typedef struct CK_RSA_PKCS_OAEP_PARAMS { + CK_MECHANISM_TYPE hashAlg; + CK_RSA_PKCS_MGF_TYPE mgf; + CK_RSA_PKCS_OAEP_SOURCE_TYPE source; + void *pSourceData; + unsigned long ulSourceDataLen; +} CK_RSA_PKCS_OAEP_PARAMS; + +typedef struct CK_RSA_PKCS_PSS_PARAMS { + ck_mechanism_type_t hashAlg; + CK_RSA_PKCS_MGF_TYPE mgf; + unsigned long sLen; +} CK_RSA_PKCS_PSS_PARAMS; + +#define CKG_MGF1_SHA1 (0x00000001UL) +#define CKG_MGF1_SHA224 (0x00000005UL) +#define CKG_MGF1_SHA256 (0x00000002UL) +#define CKG_MGF1_SHA384 (0x00000003UL) +#define CKG_MGF1_SHA512 (0x00000004UL) +#define CKG_MGF1_SHA3_224 (0x00000006UL) +#define CKG_MGF1_SHA3_256 (0x00000007UL) +#define CKG_MGF1_SHA3_384 (0x00000008UL) +#define CKG_MGF1_SHA3_512 (0x00000009UL) + +#define CKZ_DATA_SPECIFIED (0x00000001UL) + +typedef struct CK_GCM_PARAMS { + void * pIv; + unsigned long ulIvLen; + unsigned long ulIvBits; + void * pAAD; + unsigned long ulAADLen; + unsigned long ulTagBits; +} CK_GCM_PARAMS; + +typedef struct CK_CCM_PARAMS { + unsigned long ulDataLen; + unsigned char *pNonce; + unsigned long ulNonceLen; + unsigned char *pAAD; + unsigned long ulAADLen; + unsigned long ulMACLen; +} CK_CCM_PARAMS; + +/* EDDSA */ +typedef struct CK_EDDSA_PARAMS { + unsigned char phFlag; + unsigned long ulContextDataLen; + unsigned char *pContextData; +} CK_EDDSA_PARAMS; + +typedef CK_EDDSA_PARAMS *CK_EDDSA_PARAMS_PTR; + +/* XEDDSA */ +typedef struct CK_XEDDSA_PARAMS { + unsigned long hash; +} CK_XEDDSA_PARAMS; + +typedef CK_XEDDSA_PARAMS *CK_XEDDSA_PARAMS_PTR; + +typedef struct CK_AES_CTR_PARAMS { + unsigned long ulCounterBits; + unsigned char cb[16]; +} CK_AES_CTR_PARAMS; + +typedef CK_AES_CTR_PARAMS *CK_AES_CTR_PARAMS_PTR; + +typedef unsigned long CK_MAC_GENERAL_PARAMS; + +typedef CK_MAC_GENERAL_PARAMS *CK_MAC_GENERAL_PARAMS_PTR; typedef unsigned long ck_rv_t; @@ -716,8 +980,17 @@ typedef unsigned long ck_rv_t; typedef ck_rv_t (*ck_notify_t) (ck_session_handle_t session, ck_notification_t event, void *application); +struct ck_interface { + char * pInterfaceName; + void * pFunctionList; + ck_flags_t flags; +}; + +#define CKF_INTERFACE_FORK_SAFE (0x00000001UL) + /* Forward reference. */ struct ck_function_list; +struct ck_function_list_3_0; #define _CK_DECLARE_FUNCTION(name, args) \ typedef ck_rv_t (*CK_ ## name) args; \ @@ -774,7 +1047,7 @@ _CK_DECLARE_FUNCTION (C_SetOperationState, unsigned char *operation_state, unsigned long operation_state_len, ck_object_handle_t encryption_key, - ck_object_handle_t authentiation_key)); + ck_object_handle_t authentication_key)); _CK_DECLARE_FUNCTION (C_Login, (ck_session_handle_t session, ck_user_type_t user_type, unsigned char *pin, unsigned long pin_len)); @@ -999,6 +1272,147 @@ _CK_DECLARE_FUNCTION (C_GenerateRandom, _CK_DECLARE_FUNCTION (C_GetFunctionStatus, (ck_session_handle_t session)); _CK_DECLARE_FUNCTION (C_CancelFunction, (ck_session_handle_t session)); +_CK_DECLARE_FUNCTION (C_GetInterfaceList, + (struct ck_interface *interfaces_list, + unsigned long *count)); +_CK_DECLARE_FUNCTION (C_GetInterface, + (unsigned char *interface_name, + struct ck_version *version, + struct ck_interface **interface_ptr, + ck_flags_t flags)); + +_CK_DECLARE_FUNCTION (C_LoginUser, + (ck_session_handle_t session, + ck_user_type_t user_type, + unsigned char *pin, + unsigned long pin_len, + unsigned char *username, + unsigned long username_len)); + +_CK_DECLARE_FUNCTION (C_SessionCancel, + (ck_session_handle_t session, + ck_flags_t flags)); + +_CK_DECLARE_FUNCTION (C_MessageEncryptInit, + (ck_session_handle_t session, + struct ck_mechanism *mechanism, + ck_object_handle_t key)); +_CK_DECLARE_FUNCTION (C_EncryptMessage, + (ck_session_handle_t session, + void *parameter, + unsigned long parameter_len, + unsigned char *associated_data, + unsigned long associated_data_len, + unsigned char *plaintext, + unsigned long plaintext_len, + unsigned char *ciphertext, + unsigned long *ciphertext_len)); +_CK_DECLARE_FUNCTION (C_EncryptMessageBegin, + (ck_session_handle_t session, + void *parameter, + unsigned long parameter_len, + unsigned char *associated_data, + unsigned long associated_data_len)); +_CK_DECLARE_FUNCTION (C_EncryptMessageNext, + (ck_session_handle_t session, + void *parameter, + unsigned long parameter_len, + unsigned char *plaintext_part, + unsigned long plaintext_part_len, + unsigned char *ciphertext_part, + unsigned long *ciphertext_part_len, + ck_flags_t flags)); +_CK_DECLARE_FUNCTION (C_MessageEncryptFinal, + (ck_session_handle_t session)); + +_CK_DECLARE_FUNCTION (C_MessageDecryptInit, + (ck_session_handle_t session, + struct ck_mechanism *mechanism, + ck_object_handle_t key)); +_CK_DECLARE_FUNCTION (C_DecryptMessage, + (ck_session_handle_t session, + void *parameter, + unsigned long parameter_len, + unsigned char *associated_data, + unsigned long associated_data_len, + unsigned char *ciphertext, + unsigned long ciphertext_len, + unsigned char *plaintext, + unsigned long *plaintext_len)); +_CK_DECLARE_FUNCTION (C_DecryptMessageBegin, + (ck_session_handle_t session, + void *parameter, + unsigned long parameter_len, + unsigned char *associated_data, + unsigned long associated_data_len)); +_CK_DECLARE_FUNCTION (C_DecryptMessageNext, + (ck_session_handle_t session, + void *parameter, + unsigned long parameter_len, + unsigned char *ciphertext_part, + unsigned long ciphertext_part_len, + unsigned char *plaintext_part, + unsigned long *plaintext_part_len, + ck_flags_t flags)); +_CK_DECLARE_FUNCTION (C_MessageDecryptFinal, + (ck_session_handle_t session)); + +_CK_DECLARE_FUNCTION (C_MessageSignInit, + (ck_session_handle_t session, + struct ck_mechanism *mechanism, + ck_object_handle_t key)); +_CK_DECLARE_FUNCTION (C_SignMessage, + (ck_session_handle_t session, + void *parameter, + unsigned long parameter_len, + unsigned char *data, + unsigned long data_len, + unsigned char *signature, + unsigned long *signature_len)); +_CK_DECLARE_FUNCTION (C_SignMessageBegin, + (ck_session_handle_t session, + void *parameter, + unsigned long parameter_len)); +_CK_DECLARE_FUNCTION (C_SignMessageNext, + (ck_session_handle_t session, + void *parameter, + unsigned long parameter_len, + unsigned char *data, + unsigned long data_len, + unsigned char *signature, + unsigned long *signature_len)); +_CK_DECLARE_FUNCTION (C_MessageSignFinal, + (ck_session_handle_t session)); + +_CK_DECLARE_FUNCTION (C_MessageVerifyInit, + (ck_session_handle_t session, + struct ck_mechanism *mechanism, + ck_object_handle_t key)); +_CK_DECLARE_FUNCTION (C_VerifyMessage, + (ck_session_handle_t session, + void *parameter, + unsigned long parameter_len, + unsigned char *data, + unsigned long data_len, + unsigned char *signature, + unsigned long signature_len)); +_CK_DECLARE_FUNCTION (C_VerifyMessageBegin, + (ck_session_handle_t session, + void *parameter, + unsigned long parameter_len)); +_CK_DECLARE_FUNCTION (C_VerifyMessageNext, + (ck_session_handle_t session, + void *parameter, + unsigned long parameter_len, + unsigned char *data, + unsigned long data_len, + unsigned char *signature, + unsigned long signature_len)); +_CK_DECLARE_FUNCTION (C_MessageVerifyFinal, + (ck_session_handle_t session)); + +/* Flags in Message-based encryption/decryption API */ +#define CKF_END_OF_MESSAGE (0x00000001UL) struct ck_function_list { @@ -1073,6 +1487,105 @@ struct ck_function_list CK_C_WaitForSlotEvent C_WaitForSlotEvent; }; +struct ck_function_list_3_0 +{ + struct ck_version version; + CK_C_Initialize C_Initialize; + CK_C_Finalize C_Finalize; + CK_C_GetInfo C_GetInfo; + CK_C_GetFunctionList C_GetFunctionList; + CK_C_GetSlotList C_GetSlotList; + CK_C_GetSlotInfo C_GetSlotInfo; + CK_C_GetTokenInfo C_GetTokenInfo; + CK_C_GetMechanismList C_GetMechanismList; + CK_C_GetMechanismInfo C_GetMechanismInfo; + CK_C_InitToken C_InitToken; + CK_C_InitPIN C_InitPIN; + CK_C_SetPIN C_SetPIN; + CK_C_OpenSession C_OpenSession; + CK_C_CloseSession C_CloseSession; + CK_C_CloseAllSessions C_CloseAllSessions; + CK_C_GetSessionInfo C_GetSessionInfo; + CK_C_GetOperationState C_GetOperationState; + CK_C_SetOperationState C_SetOperationState; + CK_C_Login C_Login; + CK_C_Logout C_Logout; + CK_C_CreateObject C_CreateObject; + CK_C_CopyObject C_CopyObject; + CK_C_DestroyObject C_DestroyObject; + CK_C_GetObjectSize C_GetObjectSize; + CK_C_GetAttributeValue C_GetAttributeValue; + CK_C_SetAttributeValue C_SetAttributeValue; + CK_C_FindObjectsInit C_FindObjectsInit; + CK_C_FindObjects C_FindObjects; + CK_C_FindObjectsFinal C_FindObjectsFinal; + CK_C_EncryptInit C_EncryptInit; + CK_C_Encrypt C_Encrypt; + CK_C_EncryptUpdate C_EncryptUpdate; + CK_C_EncryptFinal C_EncryptFinal; + CK_C_DecryptInit C_DecryptInit; + CK_C_Decrypt C_Decrypt; + CK_C_DecryptUpdate C_DecryptUpdate; + CK_C_DecryptFinal C_DecryptFinal; + CK_C_DigestInit C_DigestInit; + CK_C_Digest C_Digest; + CK_C_DigestUpdate C_DigestUpdate; + CK_C_DigestKey C_DigestKey; + CK_C_DigestFinal C_DigestFinal; + CK_C_SignInit C_SignInit; + CK_C_Sign C_Sign; + CK_C_SignUpdate C_SignUpdate; + CK_C_SignFinal C_SignFinal; + CK_C_SignRecoverInit C_SignRecoverInit; + CK_C_SignRecover C_SignRecover; + CK_C_VerifyInit C_VerifyInit; + CK_C_Verify C_Verify; + CK_C_VerifyUpdate C_VerifyUpdate; + CK_C_VerifyFinal C_VerifyFinal; + CK_C_VerifyRecoverInit C_VerifyRecoverInit; + CK_C_VerifyRecover C_VerifyRecover; + CK_C_DigestEncryptUpdate C_DigestEncryptUpdate; + CK_C_DecryptDigestUpdate C_DecryptDigestUpdate; + CK_C_SignEncryptUpdate C_SignEncryptUpdate; + CK_C_DecryptVerifyUpdate C_DecryptVerifyUpdate; + CK_C_GenerateKey C_GenerateKey; + CK_C_GenerateKeyPair C_GenerateKeyPair; + CK_C_WrapKey C_WrapKey; + CK_C_UnwrapKey C_UnwrapKey; + CK_C_DeriveKey C_DeriveKey; + CK_C_SeedRandom C_SeedRandom; + CK_C_GenerateRandom C_GenerateRandom; + CK_C_GetFunctionStatus C_GetFunctionStatus; + CK_C_CancelFunction C_CancelFunction; + CK_C_WaitForSlotEvent C_WaitForSlotEvent; + /* PKCS #11 3.0 functions */ + CK_C_GetInterfaceList C_GetInterfaceList; + CK_C_GetInterface C_GetInterface; + CK_C_LoginUser C_LoginUser; + CK_C_SessionCancel C_SessionCancel; + CK_C_MessageEncryptInit C_MessageEncryptInit; + CK_C_EncryptMessage C_EncryptMessage; + CK_C_EncryptMessageBegin C_EncryptMessageBegin; + CK_C_EncryptMessageNext C_EncryptMessageNext; + CK_C_MessageEncryptFinal C_MessageEncryptFinal; + CK_C_MessageDecryptInit C_MessageDecryptInit; + CK_C_DecryptMessage C_DecryptMessage; + CK_C_DecryptMessageBegin C_DecryptMessageBegin; + CK_C_DecryptMessageNext C_DecryptMessageNext; + CK_C_MessageDecryptFinal C_MessageDecryptFinal; + CK_C_MessageSignInit C_MessageSignInit; + CK_C_SignMessage C_SignMessage; + CK_C_SignMessageBegin C_SignMessageBegin; + CK_C_SignMessageNext C_SignMessageNext; + CK_C_MessageSignFinal C_MessageSignFinal; + CK_C_MessageVerifyInit C_MessageVerifyInit; + CK_C_VerifyMessage C_VerifyMessage; + CK_C_VerifyMessageBegin C_VerifyMessageBegin; + CK_C_VerifyMessageNext C_VerifyMessageNext; + CK_C_MessageVerifyFinal C_MessageVerifyFinal; +}; + + typedef ck_rv_t (*ck_createmutex_t) (void **mutex); typedef ck_rv_t (*ck_destroymutex_t) (void *mutex); @@ -1091,96 +1604,97 @@ struct ck_c_initialize_args }; -#define CKF_LIBRARY_CANT_CREATE_OS_THREADS (1 << 0) -#define CKF_OS_LOCKING_OK (1 << 1) - -#define CKR_OK (0) -#define CKR_CANCEL (1) -#define CKR_HOST_MEMORY (2) -#define CKR_SLOT_ID_INVALID (3) -#define CKR_GENERAL_ERROR (5) -#define CKR_FUNCTION_FAILED (6) -#define CKR_ARGUMENTS_BAD (7) -#define CKR_NO_EVENT (8) -#define CKR_NEED_TO_CREATE_THREADS (9) -#define CKR_CANT_LOCK (0xa) -#define CKR_ATTRIBUTE_READ_ONLY (0x10) -#define CKR_ATTRIBUTE_SENSITIVE (0x11) -#define CKR_ATTRIBUTE_TYPE_INVALID (0x12) -#define CKR_ATTRIBUTE_VALUE_INVALID (0x13) -#define CKR_DATA_INVALID (0x20) -#define CKR_DATA_LEN_RANGE (0x21) -#define CKR_DEVICE_ERROR (0x30) -#define CKR_DEVICE_MEMORY (0x31) -#define CKR_DEVICE_REMOVED (0x32) -#define CKR_ENCRYPTED_DATA_INVALID (0x40) -#define CKR_ENCRYPTED_DATA_LEN_RANGE (0x41) -#define CKR_FUNCTION_CANCELED (0x50) -#define CKR_FUNCTION_NOT_PARALLEL (0x51) -#define CKR_FUNCTION_NOT_SUPPORTED (0x54) -#define CKR_KEY_HANDLE_INVALID (0x60) -#define CKR_KEY_SIZE_RANGE (0x62) -#define CKR_KEY_TYPE_INCONSISTENT (0x63) -#define CKR_KEY_NOT_NEEDED (0x64) -#define CKR_KEY_CHANGED (0x65) -#define CKR_KEY_NEEDED (0x66) -#define CKR_KEY_INDIGESTIBLE (0x67) -#define CKR_KEY_FUNCTION_NOT_PERMITTED (0x68) -#define CKR_KEY_NOT_WRAPPABLE (0x69) -#define CKR_KEY_UNEXTRACTABLE (0x6a) -#define CKR_MECHANISM_INVALID (0x70) -#define CKR_MECHANISM_PARAM_INVALID (0x71) -#define CKR_OBJECT_HANDLE_INVALID (0x82) -#define CKR_OPERATION_ACTIVE (0x90) -#define CKR_OPERATION_NOT_INITIALIZED (0x91) -#define CKR_PIN_INCORRECT (0xa0) -#define CKR_PIN_INVALID (0xa1) -#define CKR_PIN_LEN_RANGE (0xa2) -#define CKR_PIN_EXPIRED (0xa3) -#define CKR_PIN_LOCKED (0xa4) -#define CKR_SESSION_CLOSED (0xb0) -#define CKR_SESSION_COUNT (0xb1) -#define CKR_SESSION_HANDLE_INVALID (0xb3) -#define CKR_SESSION_PARALLEL_NOT_SUPPORTED (0xb4) -#define CKR_SESSION_READ_ONLY (0xb5) -#define CKR_SESSION_EXISTS (0xb6) -#define CKR_SESSION_READ_ONLY_EXISTS (0xb7) -#define CKR_SESSION_READ_WRITE_SO_EXISTS (0xb8) -#define CKR_SIGNATURE_INVALID (0xc0) -#define CKR_SIGNATURE_LEN_RANGE (0xc1) -#define CKR_TEMPLATE_INCOMPLETE (0xd0) -#define CKR_TEMPLATE_INCONSISTENT (0xd1) -#define CKR_TOKEN_NOT_PRESENT (0xe0) -#define CKR_TOKEN_NOT_RECOGNIZED (0xe1) -#define CKR_TOKEN_WRITE_PROTECTED (0xe2) -#define CKR_UNWRAPPING_KEY_HANDLE_INVALID (0xf0) -#define CKR_UNWRAPPING_KEY_SIZE_RANGE (0xf1) -#define CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT (0xf2) -#define CKR_USER_ALREADY_LOGGED_IN (0x100) -#define CKR_USER_NOT_LOGGED_IN (0x101) -#define CKR_USER_PIN_NOT_INITIALIZED (0x102) -#define CKR_USER_TYPE_INVALID (0x103) -#define CKR_USER_ANOTHER_ALREADY_LOGGED_IN (0x104) -#define CKR_USER_TOO_MANY_TYPES (0x105) -#define CKR_WRAPPED_KEY_INVALID (0x110) -#define CKR_WRAPPED_KEY_LEN_RANGE (0x112) -#define CKR_WRAPPING_KEY_HANDLE_INVALID (0x113) -#define CKR_WRAPPING_KEY_SIZE_RANGE (0x114) -#define CKR_WRAPPING_KEY_TYPE_INCONSISTENT (0x115) -#define CKR_RANDOM_SEED_NOT_SUPPORTED (0x120) -#define CKR_RANDOM_NO_RNG (0x121) -#define CKR_DOMAIN_PARAMS_INVALID (0x130) -#define CKR_BUFFER_TOO_SMALL (0x150) -#define CKR_SAVED_STATE_INVALID (0x160) -#define CKR_INFORMATION_SENSITIVE (0x170) -#define CKR_STATE_UNSAVEABLE (0x180) -#define CKR_CRYPTOKI_NOT_INITIALIZED (0x190) -#define CKR_CRYPTOKI_ALREADY_INITIALIZED (0x191) -#define CKR_MUTEX_BAD (0x1a0) -#define CKR_MUTEX_NOT_LOCKED (0x1a1) -#define CKR_FUNCTION_REJECTED (0x200) -#define CKR_VENDOR_DEFINED (1U << 31) - +#define CKF_LIBRARY_CANT_CREATE_OS_THREADS (1UL << 0) +#define CKF_OS_LOCKING_OK (1UL << 1) + +#define CKR_OK (0UL) +#define CKR_CANCEL (1UL) +#define CKR_HOST_MEMORY (2UL) +#define CKR_SLOT_ID_INVALID (3UL) +#define CKR_GENERAL_ERROR (5UL) +#define CKR_FUNCTION_FAILED (6UL) +#define CKR_ARGUMENTS_BAD (7UL) +#define CKR_NO_EVENT (8UL) +#define CKR_NEED_TO_CREATE_THREADS (9UL) +#define CKR_CANT_LOCK (0xaUL) +#define CKR_ATTRIBUTE_READ_ONLY (0x10UL) +#define CKR_ATTRIBUTE_SENSITIVE (0x11UL) +#define CKR_ATTRIBUTE_TYPE_INVALID (0x12UL) +#define CKR_ATTRIBUTE_VALUE_INVALID (0x13UL) +#define CKR_ACTION_PROHIBITED (0x1BUL) +#define CKR_DATA_INVALID (0x20UL) +#define CKR_DATA_LEN_RANGE (0x21UL) +#define CKR_DEVICE_ERROR (0x30UL) +#define CKR_DEVICE_MEMORY (0x31UL) +#define CKR_DEVICE_REMOVED (0x32UL) +#define CKR_ENCRYPTED_DATA_INVALID (0x40UL) +#define CKR_ENCRYPTED_DATA_LEN_RANGE (0x41UL) +#define CKR_FUNCTION_CANCELED (0x50UL) +#define CKR_FUNCTION_NOT_PARALLEL (0x51UL) +#define CKR_FUNCTION_NOT_SUPPORTED (0x54UL) +#define CKR_KEY_HANDLE_INVALID (0x60UL) +#define CKR_KEY_SIZE_RANGE (0x62UL) +#define CKR_KEY_TYPE_INCONSISTENT (0x63UL) +#define CKR_KEY_NOT_NEEDED (0x64UL) +#define CKR_KEY_CHANGED (0x65UL) +#define CKR_KEY_NEEDED (0x66UL) +#define CKR_KEY_INDIGESTIBLE (0x67UL) +#define CKR_KEY_FUNCTION_NOT_PERMITTED (0x68UL) +#define CKR_KEY_NOT_WRAPPABLE (0x69UL) +#define CKR_KEY_UNEXTRACTABLE (0x6aUL) +#define CKR_MECHANISM_INVALID (0x70UL) +#define CKR_MECHANISM_PARAM_INVALID (0x71UL) +#define CKR_OBJECT_HANDLE_INVALID (0x82UL) +#define CKR_OPERATION_ACTIVE (0x90UL) +#define CKR_OPERATION_NOT_INITIALIZED (0x91UL) +#define CKR_PIN_INCORRECT (0xa0UL) +#define CKR_PIN_INVALID (0xa1UL) +#define CKR_PIN_LEN_RANGE (0xa2UL) +#define CKR_PIN_EXPIRED (0xa3UL) +#define CKR_PIN_LOCKED (0xa4UL) +#define CKR_SESSION_CLOSED (0xb0UL) +#define CKR_SESSION_COUNT (0xb1UL) +#define CKR_SESSION_HANDLE_INVALID (0xb3UL) +#define CKR_SESSION_PARALLEL_NOT_SUPPORTED (0xb4UL) +#define CKR_SESSION_READ_ONLY (0xb5UL) +#define CKR_SESSION_EXISTS (0xb6UL) +#define CKR_SESSION_READ_ONLY_EXISTS (0xb7UL) +#define CKR_SESSION_READ_WRITE_SO_EXISTS (0xb8UL) +#define CKR_SIGNATURE_INVALID (0xc0UL) +#define CKR_SIGNATURE_LEN_RANGE (0xc1UL) +#define CKR_TEMPLATE_INCOMPLETE (0xd0UL) +#define CKR_TEMPLATE_INCONSISTENT (0xd1UL) +#define CKR_TOKEN_NOT_PRESENT (0xe0UL) +#define CKR_TOKEN_NOT_RECOGNIZED (0xe1UL) +#define CKR_TOKEN_WRITE_PROTECTED (0xe2UL) +#define CKR_UNWRAPPING_KEY_HANDLE_INVALID (0xf0UL) +#define CKR_UNWRAPPING_KEY_SIZE_RANGE (0xf1UL) +#define CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT (0xf2UL) +#define CKR_USER_ALREADY_LOGGED_IN (0x100UL) +#define CKR_USER_NOT_LOGGED_IN (0x101UL) +#define CKR_USER_PIN_NOT_INITIALIZED (0x102UL) +#define CKR_USER_TYPE_INVALID (0x103UL) +#define CKR_USER_ANOTHER_ALREADY_LOGGED_IN (0x104UL) +#define CKR_USER_TOO_MANY_TYPES (0x105UL) +#define CKR_WRAPPED_KEY_INVALID (0x110UL) +#define CKR_WRAPPED_KEY_LEN_RANGE (0x112UL) +#define CKR_WRAPPING_KEY_HANDLE_INVALID (0x113UL) +#define CKR_WRAPPING_KEY_SIZE_RANGE (0x114UL) +#define CKR_WRAPPING_KEY_TYPE_INCONSISTENT (0x115UL) +#define CKR_RANDOM_SEED_NOT_SUPPORTED (0x120UL) +#define CKR_RANDOM_NO_RNG (0x121UL) +#define CKR_DOMAIN_PARAMS_INVALID (0x130UL) +#define CKR_CURVE_NOT_SUPPORTED (0x140UL) +#define CKR_BUFFER_TOO_SMALL (0x150UL) +#define CKR_SAVED_STATE_INVALID (0x160UL) +#define CKR_INFORMATION_SENSITIVE (0x170UL) +#define CKR_STATE_UNSAVEABLE (0x180UL) +#define CKR_CRYPTOKI_NOT_INITIALIZED (0x190UL) +#define CKR_CRYPTOKI_ALREADY_INITIALIZED (0x191UL) +#define CKR_MUTEX_BAD (0x1a0UL) +#define CKR_MUTEX_NOT_LOCKED (0x1a1UL) +#define CKR_FUNCTION_REJECTED (0x200UL) +#define CKR_VENDOR_DEFINED (1UL << 31) /* Compatibility layer. */ @@ -1216,6 +1730,22 @@ typedef void **CK_VOID_PTR_PTR; #endif #endif +typedef struct CK_HKDF_PARAMS { + CK_BBOOL bExtract; + CK_BBOOL bExpand; + CK_MECHANISM_TYPE prfHashMechanism; + CK_ULONG ulSaltType; + CK_BYTE_PTR pSalt; + CK_ULONG ulSaltLen; + CK_OBJECT_HANDLE hSaltKey; + CK_BYTE_PTR pInfo; + CK_ULONG ulInfoLen; +} CK_HKDF_PARAMS; + +#define CKF_HKDF_SALT_NULL 0x00000001UL +#define CKF_HKDF_SALT_DATA 0x00000002UL +#define CKF_HKDF_SALT_KEY 0x00000004UL + typedef struct ck_version CK_VERSION; typedef struct ck_version *CK_VERSION_PTR; @@ -1247,16 +1777,26 @@ typedef struct ck_date *CK_DATE_PTR; typedef ck_mechanism_type_t *CK_MECHANISM_TYPE_PTR; +typedef ck_rsa_pkcs_mgf_type_t *CK_RSA_PKCS_MGF_TYPE_PTR; + typedef struct ck_mechanism CK_MECHANISM; typedef struct ck_mechanism *CK_MECHANISM_PTR; typedef struct ck_mechanism_info CK_MECHANISM_INFO; typedef struct ck_mechanism_info *CK_MECHANISM_INFO_PTR; +typedef struct ck_interface CK_INTERFACE; +typedef struct ck_interface *CK_INTERFACE_PTR; +typedef struct ck_interface **CK_INTERFACE_PTR_PTR; + typedef struct ck_function_list CK_FUNCTION_LIST; typedef struct ck_function_list *CK_FUNCTION_LIST_PTR; typedef struct ck_function_list **CK_FUNCTION_LIST_PTR_PTR; +typedef struct ck_function_list_3_0 CK_FUNCTION_LIST_3_0; +typedef struct ck_function_list_3_0 *CK_FUNCTION_LIST_3_0_PTR; +typedef struct ck_function_list_3_0 **CK_FUNCTION_LIST_3_0_PTR_PTR; + typedef struct ck_c_initialize_args CK_C_INITIALIZE_ARGS; typedef struct ck_c_initialize_args *CK_C_INITIALIZE_ARGS_PTR; @@ -1317,6 +1857,8 @@ typedef struct ck_c_initialize_args *CK_C_INITIALIZE_ARGS_PTR; #undef ck_mechanism_type_t +#undef ck_rsa_pkcs_mgf_type_t + #undef ck_mechanism #undef parameter #undef parameter_len @@ -1328,7 +1870,10 @@ typedef struct ck_c_initialize_args *CK_C_INITIALIZE_ARGS_PTR; #undef ck_rv_t #undef ck_notify_t +#undef ck_interface + #undef ck_function_list +#undef ck_function_list_3_0 #undef ck_createmutex_t #undef ck_destroymutex_t @@ -1344,7 +1889,6 @@ typedef struct ck_c_initialize_args *CK_C_INITIALIZE_ARGS_PTR; #endif /* CRYPTOKI_COMPAT */ - /* System dependencies. */ #if defined(_WIN32) || defined(CRYPTOKI_FORCE_WIN32) #pragma pack(pop, cryptoki) diff --git a/platform-listen.c b/platform-listen.c index 42c4040..45df1f6 100644 --- a/platform-listen.c +++ b/platform-listen.c @@ -34,6 +34,13 @@ platform_pre_listen(void) /* Adjust out-of-memory killer so listening process is not killed */ oom_adjust_setup(); #endif +#ifdef LINUX_MEMLOCK_ONFAULT + /* + * Protect ourselves against kcompactd so that we are able to process + * new connections while it is active and migrating pages. + */ + memlock_onfault_setup(); +#endif } void @@ -82,3 +89,13 @@ platform_post_fork_child(void) #endif } +void platform_pre_session_start(void) +{ +#ifdef LINUX_MEMLOCK_ONFAULT + /* + * Memlock flags are dropped on fork, lock the memory again so that the + * child connection is also protected against kcompactd. + */ + memlock_onfault_setup(); +#endif +} diff --git a/platform.c b/platform.c index 4c4fe57..fd1a7a7 100644 --- a/platform.c +++ b/platform.c @@ -183,17 +183,26 @@ platform_locked_account(struct passwd *pw) /* check for locked account */ if (passwd && *passwd) { #ifdef LOCKED_PASSWD_STRING - if (strcmp(passwd, LOCKED_PASSWD_STRING) == 0) + if (strcmp(passwd, LOCKED_PASSWD_STRING) == 0) { + debug3_f("password matches locked string '%s'", + LOCKED_PASSWD_STRING); locked = 1; + } #endif #ifdef LOCKED_PASSWD_PREFIX if (strncmp(passwd, LOCKED_PASSWD_PREFIX, - strlen(LOCKED_PASSWD_PREFIX)) == 0) + strlen(LOCKED_PASSWD_PREFIX)) == 0) { + debug3_f("password matches locked prefix '%s'", + LOCKED_PASSWD_PREFIX); locked = 1; + } #endif #ifdef LOCKED_PASSWD_SUBSTR - if (strstr(passwd, LOCKED_PASSWD_SUBSTR)) + if (strstr(passwd, LOCKED_PASSWD_SUBSTR)) { + debug3_f("password matches locked substring '%s'", + LOCKED_PASSWD_SUBSTR); locked = 1; + } #endif } #ifdef USE_LIBIAF diff --git a/platform.h b/platform.h index 5dec232..08cbd22 100644 --- a/platform.h +++ b/platform.h @@ -24,6 +24,7 @@ void platform_pre_restart(void); void platform_post_listen(void); void platform_post_fork_parent(pid_t child_pid); void platform_post_fork_child(void); +void platform_pre_session_start(void); int platform_privileged_uidswap(void); void platform_setusercontext(struct passwd *); void platform_setusercontext_post_groups(struct passwd *); diff --git a/poly1305.c b/poly1305.c index de4d887..c674716 100644 --- a/poly1305.c +++ b/poly1305.c @@ -7,9 +7,7 @@ #include "includes.h" #include -#ifdef HAVE_STDINT_H -# include -#endif +#include #include "poly1305.h" diff --git a/progressmeter.c b/progressmeter.c index 4ee968e..2c16976 100644 --- a/progressmeter.c +++ b/progressmeter.c @@ -1,4 +1,4 @@ -/* $OpenBSD: progressmeter.c,v 1.53 2023/04/12 14:22:04 jsg Exp $ */ +/* $OpenBSD: progressmeter.c,v 1.56 2025/06/11 13:27:11 dtucker Exp $ */ /* * Copyright (c) 2003 Nils Nordman. All rights reserved. * @@ -46,7 +46,6 @@ #define DEFAULT_WINSIZE 80 #define MAX_WINSIZE 512 -#define PADDING 1 /* padding between the progress indicators */ #define UPDATE_INTERVAL 1 /* update the progress meter every second */ #define STALL_TIME 5 /* we're stalled after this many seconds */ @@ -94,15 +93,15 @@ format_rate(off_t bytes) bytes *= 100; for (i = 0; bytes >= 100*1000 && unit[i] != 'T'; i++) bytes = (bytes + 512) / 1024; + /* Display at least KB, even when rate is low or zero. */ if (i == 0) { i++; bytes = (bytes + 512) / 1024; } - snprintf(buf, sizeof(buf), "%3lld.%1lld%c%s", + snprintf(buf, sizeof(buf), "%3lld.%1lld%cB", (long long) (bytes + 5) / 100, (long long) (bytes + 5) / 10 % 10, - unit[i], - i ? "B" : " "); + unit[i]); return buf; } @@ -133,7 +132,8 @@ refresh_progress_meter(int force_update) int hours, minutes, seconds; int file_len, cols; - if ((!force_update && !alarm_fired && !win_resized) || !can_output()) + if (file == NULL || (!force_update && !alarm_fired && !win_resized) || + !can_output()) return; alarm_fired = 0; @@ -277,6 +277,7 @@ stop_progress_meter(void) refresh_progress_meter(1); atomicio(vwrite, STDOUT_FILENO, "\n", 1); + file = NULL; } static void diff --git a/readconf.c b/readconf.c index 9f55926..d992059 100644 --- a/readconf.c +++ b/readconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: readconf.c,v 1.392 2024/09/26 23:55:08 djm Exp $ */ +/* $OpenBSD: readconf.c,v 1.406 2025/08/29 03:50:38 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -29,14 +29,10 @@ #include #include #include -#ifdef HAVE_IFADDRS_H -# include -#endif +#include #include #include -#ifdef HAVE_PATHS_H -# include -#endif +#include #include #include #include @@ -48,9 +44,7 @@ #else # include "openbsd-compat/glob.h" #endif -#ifdef HAVE_UTIL_H #include -#endif #if defined(HAVE_STRNVIS) && defined(HAVE_VIS_H) && !defined(BROKEN_STRNVIS) # include #endif @@ -70,6 +64,7 @@ #include "uidswap.h" #include "myproposal.h" #include "digest.h" +#include "version.h" /* Format of the configuration file: @@ -133,11 +128,11 @@ */ 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); + const char *host, const char *original_host, const char *remote_command, + 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, + const char *host, const char *original_host, const char *remote_command, + char *line, const char *filename, int linenum, int *activep, int flags, int *want_final_pass, int depth); /* Keyword tokens. */ @@ -179,6 +174,7 @@ typedef enum { oPubkeyAcceptedAlgorithms, oCASignatureAlgorithms, oProxyJump, oSecurityKeyProvider, oKnownHostsCommand, oRequiredRSASize, oEnableEscapeCommandline, oObscureKeystrokeTiming, oChannelTimeout, + oVersionAddendum, oRefuseConnection, oWarnWeakCrypto, oIgnore, oIgnoredUnknownOption, oDeprecated, oUnsupported } OpCodes; @@ -329,6 +325,9 @@ static struct { { "enableescapecommandline", oEnableEscapeCommandline }, { "obscurekeystroketiming", oObscureKeystrokeTiming }, { "channeltimeout", oChannelTimeout }, + { "versionaddendum", oVersionAddendum }, + { "refuseconnection", oRefuseConnection }, + { "warnweakcrypto", oWarnWeakCrypto }, { NULL, oBadOption } }; @@ -708,7 +707,8 @@ expand_match_exec_or_include_path(const char *path, Options *options, static int match_cfg_line(Options *options, const char *full_line, int *acp, char ***avp, struct passwd *pw, const char *host_arg, const char *original_host, - int final_pass, int *want_final_pass, const char *filename, int linenum) + const char *remote_command, int final_pass, int *want_final_pass, + const char *filename, int linenum) { char *arg, *oattrib = NULL, *attrib = NULL, *cmd, *host, *criteria; const char *ruser; @@ -764,12 +764,13 @@ match_cfg_line(Options *options, const char *full_line, int *acp, char ***avp, 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 the config requests "Match final" without + * negation then remember this so we can perform a + * second pass later. */ if (strcasecmp(attrib, "final") == 0 && want_final_pass != NULL) - *want_final_pass = 1; + *want_final_pass |= !negate; r = !!final_pass; /* force bitmask member to boolean */ if (r == (negate ? 1 : 0)) this_result = result = 0; @@ -785,16 +786,29 @@ match_cfg_line(Options *options, const char *full_line, int *acp, char ***avp, strprefix(attrib, "user=", 1) != NULL || strprefix(attrib, "localuser=", 1) != NULL || strprefix(attrib, "localnetwork=", 1) != NULL || + strprefix(attrib, "version=", 1) != NULL || strprefix(attrib, "tagged=", 1) != NULL || + strprefix(attrib, "command=", 1) != NULL || strprefix(attrib, "exec=", 1) != NULL) { arg = strchr(attrib, '='); *(arg++) = '\0'; - } else { - arg = argv_next(acp, avp); + } else if ((arg = argv_next(acp, avp)) == NULL) { + error("%.200s line %d: missing argument for Match '%s'", + filename, linenum, oattrib); + result = -1; + goto out; } - /* All other criteria require an argument */ - if (arg == NULL || *arg == '\0' || *arg == '#') { + /* + * All other criteria require an argument, though it may + * be the empty string for the "tagged" and "command" + * options. + */ + if (*arg == '\0' && + strcasecmp(attrib, "tagged") != 0 && + strcasecmp(attrib, "command") != 0) + arg = NULL; + if (arg == NULL || *arg == '#') { error("Missing Match criteria for %s", attrib); result = -1; goto out; @@ -828,9 +842,37 @@ match_cfg_line(Options *options, const char *full_line, int *acp, char ***avp, r = check_match_ifaddrs(arg) == 1; if (r == (negate ? 1 : 0)) this_result = result = 0; + } else if (strcasecmp(attrib, "version") == 0) { + criteria = xstrdup(SSH_RELEASE); + r = match_pattern_list(SSH_RELEASE, arg, 0) == 1; + if (r == (negate ? 1 : 0)) + this_result = result = 0; } else if (strcasecmp(attrib, "tagged") == 0) { criteria = xstrdup(options->tag == NULL ? "" : options->tag); + /* Special case: empty criteria matches empty arg */ + r = (*criteria == '\0') ? *arg == '\0' : + match_pattern_list(criteria, arg, 0) == 1; + if (r == (negate ? 1 : 0)) + this_result = result = 0; + } else if (strcasecmp(attrib, "command") == 0) { + criteria = xstrdup(remote_command == NULL ? + "" : remote_command); + /* Special case: empty criteria matches empty arg */ + r = (*criteria == '\0') ? *arg == '\0' : + match_pattern_list(criteria, arg, 0) == 1; + if (r == (negate ? 1 : 0)) + this_result = result = 0; + } else if (strcasecmp(attrib, "sessiontype") == 0) { + if (options->session_type == SESSION_TYPE_SUBSYSTEM) + criteria = xstrdup("subsystem"); + else if (options->session_type == SESSION_TYPE_NONE) + criteria = xstrdup("none"); + else if (remote_command != NULL && + *remote_command != '\0') + criteria = xstrdup("exec"); + else + criteria = xstrdup("shell"); r = match_pattern_list(criteria, arg, 0) == 1; if (r == (negate ? 1 : 0)) this_result = result = 0; @@ -1054,6 +1096,15 @@ static const struct multistate multistate_compression[] = { { "no", COMP_NONE }, { NULL, -1 } }; +/* XXX this will need to be replaced with a bitmask if we add more flags */ +static const struct multistate multistate_warnweakcrypto[] = { + { "true", 1 }, + { "false", 0 }, + { "yes", 1 }, + { "no", 0 }, + { "no-pq-kex", 0 }, + { NULL, -1 } +}; static int parse_multistate_value(const char *arg, const char *filename, int linenum, @@ -1078,18 +1129,19 @@ parse_multistate_value(const char *arg, const char *filename, int linenum, */ 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) + const char *original_host, const char *remote_command, 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); + remote_command, 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) + const char *original_host, const char *remote_command, 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]; @@ -1826,8 +1878,8 @@ process_config_line_depth(Options *options, struct passwd *pw, const char *host, goto out; } value = match_cfg_line(options, str, &ac, &av, pw, host, - original_host, flags & SSHCONF_FINAL, want_final_pass, - filename, linenum); + original_host, remote_command, flags & SSHCONF_FINAL, + want_final_pass, filename, linenum); if (value < 0) { error("%.200s line %d: Bad Match condition", filename, linenum); @@ -2079,8 +2131,8 @@ process_config_line_depth(Options *options, struct passwd *pw, const char *host, 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 | + pw, host, original_host, remote_command, + options, flags | SSHCONF_CHECKPERM | (oactive ? 0 : SSHCONF_NEVERMATCH), activep, want_final_pass, depth + 1); if (r != 1 && errno != ENOENT) { @@ -2112,6 +2164,12 @@ process_config_line_depth(Options *options, struct passwd *pw, const char *host, filename, linenum, arg); goto out; } + if (value == INT_MIN) { + debug("%s line %d: Deprecated IPQoS value \"%s\" " + "ignored - using system default instead. Consider" + " using DSCP values.", filename, linenum, arg); + value = INT_MAX; + } arg = argv_next(&ac, &av); if (arg == NULL) value2 = value; @@ -2120,6 +2178,12 @@ process_config_line_depth(Options *options, struct passwd *pw, const char *host, filename, linenum, arg); goto out; } + if (value2 == INT_MIN) { + debug("%s line %d: Deprecated IPQoS value \"%s\" " + "ignored - using system default instead. Consider" + " using DSCP values.", filename, linenum, arg); + value2 = INT_MAX; + } if (*activep && options->ip_qos_interactive == -1) { options->ip_qos_interactive = value; options->ip_qos_bulk = value2; @@ -2367,6 +2431,11 @@ process_config_line_depth(Options *options, struct passwd *pw, const char *host, intptr = &options->required_rsa_size; goto parse_int; + case oWarnWeakCrypto: + intptr = &options->warn_weak_crypto; + multistate_ptr = multistate_warnweakcrypto; + goto parse_multistate; + case oObscureKeystrokeTiming: value = -1; while ((arg = argv_next(&ac, &av)) != NULL) { @@ -2440,6 +2509,41 @@ process_config_line_depth(Options *options, struct passwd *pw, const char *host, } break; + case oVersionAddendum: + 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 oRefuseConnection: + arg = argv_next(&ac, &av); + if (!arg || *arg == '\0') { + error("%.200s line %d: Missing argument.", + filename, linenum); + goto out; + } + if (*activep) { + fatal("%.200s line %d: RefuseConnection: %s", + filename, linenum, arg); + } + break; + case oDeprecated: debug("%s line %d: Deprecated option \"%s\"", filename, linenum, keyword); @@ -2481,20 +2585,20 @@ process_config_line_depth(Options *options, struct passwd *pw, const char *host, */ int read_config_file(const char *filename, struct passwd *pw, const char *host, - const char *original_host, Options *options, int flags, + const char *original_host, const char *remote_command, 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); + remote_command, 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) + const char *host, const char *original_host, const char *remote_command, + Options *options, int flags, int *activep, int *want_final_pass, int depth) { FILE *f; char *line = NULL; @@ -2534,8 +2638,8 @@ read_config_file_depth(const char *filename, struct passwd *pw, * 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) + remote_command, line, filename, linenum, activep, flags, + want_final_pass, depth) != 0) bad_options++; } free(line); @@ -2691,11 +2795,13 @@ initialize_options(Options * options) options->pubkey_accepted_algos = NULL; options->known_hosts_command = NULL; options->required_rsa_size = -1; + options->warn_weak_crypto = -1; options->enable_escape_commandline = -1; options->obscure_keystroke_timing_interval = -1; options->tag = NULL; options->channel_timeouts = NULL; options->num_channel_timeouts = 0; + options->version_addendum = NULL; } /* @@ -2799,10 +2905,6 @@ fill_default_options(Options * 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); -#ifdef WITH_DSA - add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_DSA, 0); -#endif } if (options->escape_char == -1) options->escape_char = '~'; @@ -2866,9 +2968,9 @@ fill_default_options(Options * options) if (options->visual_host_key == -1) options->visual_host_key = 0; if (options->ip_qos_interactive == -1) - options->ip_qos_interactive = IPTOS_DSCP_AF21; + options->ip_qos_interactive = IPTOS_DSCP_EF; if (options->ip_qos_bulk == -1) - options->ip_qos_bulk = IPTOS_DSCP_CS1; + options->ip_qos_bulk = IPTOS_DSCP_CS0; if (options->request_tty == -1) options->request_tty = REQUEST_TTY_AUTO; if (options->session_type == -1) @@ -2896,6 +2998,8 @@ fill_default_options(Options * options) #endif if (options->required_rsa_size == -1) options->required_rsa_size = SSH_RSA_MINIMUM_MODULUS_SIZE; + if (options->warn_weak_crypto == -1) + options->warn_weak_crypto = 1; if (options->enable_escape_commandline == -1) options->enable_escape_commandline = 0; if (options->obscure_keystroke_timing_interval == -1) { @@ -2923,6 +3027,7 @@ fill_default_options(Options * options) goto fail; \ } \ } while (0) + options->kex_algorithms_set = options->kex_algorithms != NULL; ASSEMBLE(ciphers, def_cipher, all_cipher); ASSEMBLE(macs, def_mac, all_mac); ASSEMBLE(kex_algorithms, def_kex, all_kex); @@ -3410,6 +3515,8 @@ fmt_intarg(OpCodes code, int val) switch (code) { case oAddressFamily: return fmt_multistate_int(val, multistate_addressfamily); + case oCompression: + return fmt_multistate_int(val, multistate_compression); case oVerifyHostKeyDNS: case oUpdateHostkeys: return fmt_multistate_int(val, multistate_yesnoask); @@ -3608,6 +3715,7 @@ dump_client_config(Options *o, const char *host) dump_cfg_fmtint(oVisualHostKey, o->visual_host_key); dump_cfg_fmtint(oUpdateHostkeys, o->update_hostkeys); dump_cfg_fmtint(oEnableEscapeCommandline, o->enable_escape_commandline); + dump_cfg_fmtint(oWarnWeakCrypto, o->warn_weak_crypto); /* Integer options */ dump_cfg_int(oCanonicalizeMaxDots, o->canonicalize_max_dots); @@ -3647,6 +3755,7 @@ dump_client_config(Options *o, const char *host) dump_cfg_string(oXAuthLocation, o->xauth_location); dump_cfg_string(oKnownHostsCommand, o->known_hosts_command); dump_cfg_string(oTag, o->tag); + dump_cfg_string(oVersionAddendum, o->version_addendum); /* Forwards */ dump_cfg_forwards(oDynamicForward, o->num_local_forwards, o->local_forwards); diff --git a/readconf.h b/readconf.h index 9447d5d..942149f 100644 --- a/readconf.h +++ b/readconf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: readconf.h,v 1.156 2024/03/04 02:16:11 djm Exp $ */ +/* $OpenBSD: readconf.h,v 1.161 2025/08/11 10:55:38 djm Exp $ */ /* * Author: Tatu Ylonen @@ -19,7 +19,6 @@ /* 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 { @@ -50,8 +49,8 @@ typedef struct { 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 */ + int ip_qos_interactive; /* DSCP value for interactive */ + int ip_qos_bulk; /* DSCP value for bulk traffic */ SyslogFacility log_facility; /* Facility for system logging. */ LogLevel log_level; /* Level for logging. */ u_int num_log_verbose; /* Verbose log overrides */ @@ -68,6 +67,7 @@ typedef struct { 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. */ + int kex_algorithms_set; /* KexAlgorithms was set by the user */ char *ca_sign_algorithms; /* Allowed CA signature algorithms */ char *hostname; /* Real host to connect. */ char *tag; /* Configuration tag name. */ @@ -181,10 +181,13 @@ typedef struct { int required_rsa_size; /* minimum size of RSA keys */ int enable_escape_commandline; /* ~C commandline */ int obscure_keystroke_timing_interval; + int warn_weak_crypto; char **channel_timeouts; /* inactivity timeout by channel type */ u_int num_channel_timeouts; + char *version_addendum; + char *ignored_unknown; /* Pattern list of unknown tokens to ignore */ } Options; @@ -239,9 +242,9 @@ 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); + 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 *); + 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 *); diff --git a/readpass.c b/readpass.c index d42b118..3c9212c 100644 --- a/readpass.c +++ b/readpass.c @@ -1,4 +1,4 @@ -/* $OpenBSD: readpass.c,v 1.71 2024/03/30 04:27:44 djm Exp $ */ +/* $OpenBSD: readpass.c,v 1.72 2025/06/11 13:24:05 dtucker Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. * @@ -30,9 +30,7 @@ #include #include -#ifdef HAVE_PATHS_H -# include -#endif +#include #include #include #include @@ -91,7 +89,7 @@ ssh_askpass(char *askpass, const char *msg, const char *env_hint) if (r <= 0) break; len += r; - } while (sizeof(buf) - 1 - len > 0); + } while (len < sizeof(buf) - 1); buf[len] = '\0'; close(p[0]); diff --git a/regress/Makefile b/regress/Makefile index 7f73497..ece093a 100644 --- a/regress/Makefile +++ b/regress/Makefile @@ -1,8 +1,8 @@ -# $OpenBSD: Makefile,v 1.135 2024/06/14 04:43:11 djm Exp $ +# $OpenBSD: Makefile,v 1.140 2025/07/04 07:52:17 djm Exp $ tests: prep file-tests t-exec unit -REGRESS_TARGETS= t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t11 t12 +REGRESS_TARGETS= t1 t2 t3 t4 t5 t7 t9 t10 t11 t12 # File based tests file-tests: $(REGRESS_TARGETS) @@ -65,6 +65,7 @@ LTESTS= connect \ sftp-batch \ sftp-glob \ sftp-perm \ + sftp-resume \ sftp-uri \ reconfigure \ dynamic-forward \ @@ -105,16 +106,18 @@ LTESTS= connect \ knownhosts-command \ agent-restrict \ hostbased \ + password \ channel-timeout \ connection-timeout \ match-subsystem \ agent-pkcs11-restrict \ agent-pkcs11-cert \ penalty \ - penalty-expire + penalty-expire \ + connect-bigconf INTEROP_TESTS= putty-transfer putty-ciphers putty-kex conch-ciphers -INTEROP_TESTS+= dropbear-ciphers dropbear-kex +INTEROP_TESTS+= dropbear-ciphers dropbear-kex dropbear-server #INTEROP_TESTS+=ssh-com ssh-com-client ssh-com-keygen ssh-com-sftp EXTRA_TESTS= agent-pkcs11 @@ -129,9 +132,9 @@ CLEANFILES= *.core actual agent-key.* authorized_keys_${USERNAME} \ 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.ecdsa-sha2-nistp521 host.ssh-ed25519 \ host.ssh-rsa host_ca_key* host_krl_* host_revoked_* key.* \ - key.dsa-* key.ecdsa-* key.ed25519-512 \ + 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 \ @@ -190,36 +193,18 @@ t5: ${TEST_SSH_SSHKEYGEN} -Bf ${.CURDIR}/rsa_openssh.pub |\ awk '{print $$2}' | diff - ${.CURDIR}/t5.ok ; \ fi -t6: - set -xe ; if ${TEST_SSH_SSH} -Q key | grep -q "^ssh-dss" ; then \ - ${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 ; \ - fi $(OBJ)/t7.out: - set -xe ; if ${TEST_SSH_SSH} -Q key | grep -q "^ssh-dss" ; then \ + set -xe ; if ${TEST_SSH_SSH} -Q key | grep -q "^ssh-rsa" ; then \ ${TEST_SSH_SSHKEYGEN} -q -t rsa -N '' -f $@ ; \ fi t7: $(OBJ)/t7.out - set -xe ; if ${TEST_SSH_SSH} -Q key | grep -q "^ssh-dss" ; then \ + set -xe ; if ${TEST_SSH_SSH} -Q key | grep -q "^ssh-rsa" ; then \ ${TEST_SSH_SSHKEYGEN} -lf $(OBJ)/t7.out > /dev/null ; \ ${TEST_SSH_SSHKEYGEN} -Bf $(OBJ)/t7.out > /dev/null ; \ fi -$(OBJ)/t8.out: - set -xe ; if ssh -Q key | grep -q "^ssh-dss" ; then \ - ${TEST_SSH_SSHKEYGEN} -q -t dsa -N '' -f $@ ; \ - fi - -t8: $(OBJ)/t8.out - set -xe ; if ssh -Q key | grep -q "^ssh-dss" ; then \ - ${TEST_SSH_SSHKEYGEN} -lf $(OBJ)/t8.out > /dev/null ; \ - ${TEST_SSH_SSHKEYGEN} -Bf $(OBJ)/t8.out > /dev/null ; \ - fi - $(OBJ)/t9.out: ! ${TEST_SSH_SSH} -Q key-plain | grep ecdsa >/dev/null || \ ${TEST_SSH_SSHKEYGEN} -q -t ecdsa -N '' -f $@ @@ -239,7 +224,7 @@ t10: $(OBJ)/t10.out ${TEST_SSH_SSHKEYGEN} -Bf $(OBJ)/t10.out > /dev/null t11: - set -xe ; if ${TEST_SSH_SSH} -Q key | grep -q "^ssh-dss" ; then \ + set -xe ; if ${TEST_SSH_SSH} -Q key | grep -q "^ssh-rsa" ; then \ ${TEST_SSH_SSHKEYGEN} -E sha256 -lf ${.CURDIR}/rsa_openssh.pub |\ awk '{print $$2}' | diff - ${.CURDIR}/t11.ok ; \ fi @@ -291,26 +276,33 @@ t-extra: ${EXTRA_TESTS:=.sh} interop: ${INTEROP_TARGETS} # Unit tests, built by top-level Makefile -unit: +unit unit-bench: 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 ; \ + ARGS=""; \ + test "x$@" = "xunit-bench" && ARGS="-b"; \ + test "x${UNITTEST_FAST}" = "x" || ARGS="$$ARGS -f"; \ + test "x${UNITTEST_SLOW}" = "x" || ARGS="$$ARGS -F"; \ + test "x${UNITTEST_VERBOSE}" = "x" || ARGS="$$ARGS -v"; \ + test "x${UNITTEST_BENCH_DETAIL}" = "x" || ARGS="$$ARGS -B"; \ + test "x${UNITTEST_BENCH_ONLY}" = "x" || ARGS="$$ARGS -O ${UNITTEST_BENCH_ONLY}"; \ + $$V ${.OBJDIR}/unittests/sshbuf/test_sshbuf $${ARGS}; \ $$V ${.OBJDIR}/unittests/sshkey/test_sshkey \ - -d ${.CURDIR}/unittests/sshkey/testdata ; \ + -d ${.CURDIR}/unittests/sshkey/testdata $${ARGS}; \ $$V ${.OBJDIR}/unittests/sshsig/test_sshsig \ - -d ${.CURDIR}/unittests/sshsig/testdata ; \ + -d ${.CURDIR}/unittests/sshsig/testdata $${ARGS}; \ $$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 ; \ + -d ${.CURDIR}/unittests/authopt/testdata $${ARGS}; \ + $$V ${.OBJDIR}/unittests/bitmap/test_bitmap $${ARGS}; \ + $$V ${.OBJDIR}/unittests/conversion/test_conversion $${ARGS}; \ + $$V ${.OBJDIR}/unittests/kex/test_kex $${ARGS}; \ $$V ${.OBJDIR}/unittests/hostkeys/test_hostkeys \ - -d ${.CURDIR}/unittests/hostkeys/testdata ; \ - $$V ${.OBJDIR}/unittests/match/test_match ; \ - $$V ${.OBJDIR}/unittests/misc/test_misc ; \ + -d ${.CURDIR}/unittests/hostkeys/testdata $${ARGS}; \ + $$V ${.OBJDIR}/unittests/match/test_match $${ARGS}; \ + $$V ${.OBJDIR}/unittests/misc/test_misc $${ARGS}; \ if test "x${TEST_SSH_UTF8}" = "xyes" ; then \ - $$V ${.OBJDIR}/unittests/utf8/test_utf8 ; \ + $$V ${.OBJDIR}/unittests/utf8/test_utf8 $${ARGS}; \ fi \ fi diff --git a/regress/agent-pkcs11-cert.sh b/regress/agent-pkcs11-cert.sh index 4e8f748..551067d 100644 --- a/regress/agent-pkcs11-cert.sh +++ b/regress/agent-pkcs11-cert.sh @@ -1,15 +1,12 @@ -# $OpenBSD: agent-pkcs11-cert.sh,v 1.1 2023/12/18 14:50:08 djm Exp $ +# $OpenBSD: agent-pkcs11-cert.sh,v 1.3 2025/07/26 01:53:31 djm Exp $ # Placed in the Public Domain. tid="pkcs11 agent certificate test" -SSH_AUTH_SOCK="$OBJ/agent.sock" -export SSH_AUTH_SOCK LC_ALL=C export LC_ALL p11_setup || skip "No PKCS#11 library found" -rm -f $SSH_AUTH_SOCK $OBJ/agent.log rm -f $OBJ/output_* $OBJ/expect_* rm -f $OBJ/ca* @@ -19,74 +16,80 @@ $SSHKEYGEN -qs $OBJ/ca -I "ecdsa_key" -n $USER -z 1 ${SSH_SOFTHSM_DIR}/EC.pub || fatal "certify ECDSA key failed" $SSHKEYGEN -qs $OBJ/ca -I "rsa_key" -n $USER -z 2 ${SSH_SOFTHSM_DIR}/RSA.pub || fatal "certify RSA key failed" -$SSHKEYGEN -qs $OBJ/ca -I "ca_ca" -n $USER -z 3 $OBJ/ca.pub || +$SSHKEYGEN -qs $OBJ/ca -I "ed25519_key" -n $USER -z 3 \ + ${SSH_SOFTHSM_DIR}/ED25519.pub || + fatal "certify ed25519 key failed" +$SSHKEYGEN -qs $OBJ/ca -I "ca_ca" -n $USER -z 4 $OBJ/ca.pub || fatal "certify CA key failed" -rm -f $SSH_AUTH_SOCK -trace "start agent" -${SSHAGENT} ${EXTRA_AGENT_ARGS} -d -a $SSH_AUTH_SOCK > $OBJ/agent.log 2>&1 & -AGENT_PID=$! -trap "kill $AGENT_PID" EXIT -for x in 0 1 2 3 4 ; do - # Give it a chance to start - ${SSHADD} -l > /dev/null 2>&1 - r=$? - test $r -eq 1 && break - sleep 1 -done -if [ $r -ne 1 ]; then - fatal "ssh-add -l did not fail with exit code 1 (got $r)" -fi +start_ssh_agent -trace "load pkcs11 keys and certs" +verbose "load pkcs11 keys and certs" # Note: deliberately contains non-cert keys and non-matching cert on commandline p11_ssh_add -qs ${TEST_SSH_PKCS11} \ $OBJ/ca.pub \ + ${SSH_SOFTHSM_DIR}/ED25519.pub \ + ${SSH_SOFTHSM_DIR}/ED25519-cert.pub \ ${SSH_SOFTHSM_DIR}/EC.pub \ ${SSH_SOFTHSM_DIR}/EC-cert.pub \ ${SSH_SOFTHSM_DIR}/RSA.pub \ ${SSH_SOFTHSM_DIR}/RSA-cert.pub || fatal "failed to add keys" # Verify their presence +verbose "verify presence" cut -d' ' -f1-2 \ + ${SSH_SOFTHSM_DIR}/ED25519.pub \ ${SSH_SOFTHSM_DIR}/EC.pub \ ${SSH_SOFTHSM_DIR}/RSA.pub \ + ${SSH_SOFTHSM_DIR}/ED25519-cert.pub \ ${SSH_SOFTHSM_DIR}/EC-cert.pub \ ${SSH_SOFTHSM_DIR}/RSA-cert.pub | sort > $OBJ/expect_list $SSHADD -L | cut -d' ' -f1-2 | sort > $OBJ/output_list diff $OBJ/expect_list $OBJ/output_list # Verify that all can perform signatures. +verbose "check signatures" for x in ${SSH_SOFTHSM_DIR}/EC.pub ${SSH_SOFTHSM_DIR}/RSA.pub \ - ${SSH_SOFTHSM_DIR}/EC-cert.pub ${SSH_SOFTHSM_DIR}/RSA-cert.pub ; do + ${SSH_SOFTHSM_DIR}/EC-cert.pub ${SSH_SOFTHSM_DIR}/RSA-cert.pub \ + ${SSH_SOFTHSM_DIR}/ED25519.pub ${SSH_SOFTHSM_DIR}/ED25519-cert.pub ; do $SSHADD -T $x || fail "Signing failed for $x" done # Delete plain keys. +verbose "delete plain keys" $SSHADD -qd ${SSH_SOFTHSM_DIR}/EC.pub ${SSH_SOFTHSM_DIR}/RSA.pub +$SSHADD -qd ${SSH_SOFTHSM_DIR}/ED25519.pub # Verify that certs can still perform signatures. -for x in ${SSH_SOFTHSM_DIR}/EC-cert.pub ${SSH_SOFTHSM_DIR}/RSA-cert.pub ; do +verbose "reverify certificate signatures" +for x in ${SSH_SOFTHSM_DIR}/EC-cert.pub ${SSH_SOFTHSM_DIR}/RSA-cert.pub \ + ${SSH_SOFTHSM_DIR}/ED25519-cert.pub ; do $SSHADD -T $x || fail "Signing failed for $x" done $SSHADD -qD >/dev/null || fatal "clear agent failed" -trace "load pkcs11 certs only" +verbose "load pkcs11 certs only" p11_ssh_add -qCs ${TEST_SSH_PKCS11} \ $OBJ/ca.pub \ ${SSH_SOFTHSM_DIR}/EC.pub \ ${SSH_SOFTHSM_DIR}/EC-cert.pub \ ${SSH_SOFTHSM_DIR}/RSA.pub \ - ${SSH_SOFTHSM_DIR}/RSA-cert.pub || + ${SSH_SOFTHSM_DIR}/RSA-cert.pub \ + ${SSH_SOFTHSM_DIR}/ED25519.pub \ + ${SSH_SOFTHSM_DIR}/ED25519-cert.pub || fatal "failed to add keys" # Verify their presence +verbose "verify presence" cut -d' ' -f1-2 \ ${SSH_SOFTHSM_DIR}/EC-cert.pub \ - ${SSH_SOFTHSM_DIR}/RSA-cert.pub | sort > $OBJ/expect_list + ${SSH_SOFTHSM_DIR}/RSA-cert.pub \ + ${SSH_SOFTHSM_DIR}/ED25519-cert.pub | sort > $OBJ/expect_list $SSHADD -L | cut -d' ' -f1-2 | sort > $OBJ/output_list diff $OBJ/expect_list $OBJ/output_list # Verify that certs can perform signatures. -for x in ${SSH_SOFTHSM_DIR}/EC-cert.pub ${SSH_SOFTHSM_DIR}/RSA-cert.pub ; do +verbose "check signatures" +for x in ${SSH_SOFTHSM_DIR}/EC-cert.pub ${SSH_SOFTHSM_DIR}/RSA-cert.pub \ + ${SSH_SOFTHSM_DIR}/ED25519-cert.pub ; do $SSHADD -T $x || fail "Signing failed for $x" done diff --git a/regress/agent-pkcs11-restrict.sh b/regress/agent-pkcs11-restrict.sh index 8672532..9fc5e1c 100644 --- a/regress/agent-pkcs11-restrict.sh +++ b/regress/agent-pkcs11-restrict.sh @@ -1,11 +1,11 @@ -# $OpenBSD: agent-pkcs11-restrict.sh,v 1.1 2023/12/18 14:49:39 djm Exp $ +# $OpenBSD: agent-pkcs11-restrict.sh,v 1.3 2025/07/26 01:53:31 djm Exp $ # Placed in the Public Domain. tid="pkcs11 agent constraint test" p11_setup || skip "No PKCS#11 library found" -rm -f $SSH_AUTH_SOCK $OBJ/agent.log $OBJ/host_[abcx]* $OBJ/user_[abcx]* +rm -f $OBJ/host_[abcx]* $OBJ/user_[abcx]* rm -f $OBJ/sshd_proxy_host* $OBJ/ssh_output* $OBJ/expect_* rm -f $OBJ/ssh_proxy[._]* $OBJ/command $OBJ/authorized_keys_* @@ -16,6 +16,7 @@ for h in a b x ca ; do done # XXX test CA hostcerts too. +# XXX test ed25519 keys key_for() { case $h in @@ -26,23 +27,7 @@ key_for() { export K } -SSH_AUTH_SOCK="$OBJ/agent.sock" -export SSH_AUTH_SOCK -rm -f $SSH_AUTH_SOCK -trace "start agent" -${SSHAGENT} ${EXTRA_AGENT_ARGS} -d -a $SSH_AUTH_SOCK > $OBJ/agent.log 2>&1 & -AGENT_PID=$! -trap "kill $AGENT_PID" EXIT -for x in 0 1 2 3 4 ; do - # Give it a chance to start - ${SSHADD} -l > /dev/null 2>&1 - r=$? - test $r -eq 1 && break - sleep 1 -done -if [ $r -ne 1 ]; then - fatal "ssh-add -l did not fail with exit code 1 (got $r)" -fi +start_ssh_agent # XXX a lot of this is a copy of agent-restrict.sh, but I couldn't see a nice # way to factor it out -djm @@ -118,7 +103,7 @@ for h in a b ; do cat $K) >> $OBJ/authorized_keys_$USER done -trace "unrestricted keys" +verbose "unrestricted keys" $SSHADD -qD >/dev/null || fatal "clear agent failed" p11_ssh_add -qs ${TEST_SSH_PKCS11} || fatal "failed to add keys" @@ -134,7 +119,7 @@ for h in a b ; do cmp $OBJ/expect_$h $OBJ/ssh_output || fatal "unexpected output" done -trace "restricted to different host" +verbose "restricted to different host" $SSHADD -qD >/dev/null || fatal "clear agent failed" p11_ssh_add -q -h host_x -s ${TEST_SSH_PKCS11} -H $OBJ/known_hosts || fatal "failed to add keys" @@ -144,7 +129,7 @@ for h in a b ; do host_$h true > $OBJ/ssh_output && fatal "test ssh $h succeeded" done -trace "restricted to destination host" +verbose "restricted to destination host" $SSHADD -qD >/dev/null || fatal "clear agent failed" p11_ssh_add -q -h host_a -h host_b -s ${TEST_SSH_PKCS11} -H $OBJ/known_hosts || fatal "failed to add keys" @@ -160,7 +145,7 @@ for h in a b ; do cmp $OBJ/expect_$h $OBJ/ssh_output || fatal "unexpected output" done -trace "restricted multihop" +verbose "restricted multihop" $SSHADD -qD >/dev/null || fatal "clear agent failed" p11_ssh_add -q -h host_a -h "host_a>host_b" \ -s ${TEST_SSH_PKCS11} -H $OBJ/known_hosts || fatal "failed to add keys" diff --git a/regress/agent-pkcs11.sh b/regress/agent-pkcs11.sh index 304734f..4914666 100644 --- a/regress/agent-pkcs11.sh +++ b/regress/agent-pkcs11.sh @@ -1,54 +1,46 @@ -# $OpenBSD: agent-pkcs11.sh,v 1.13 2023/10/30 23:00:25 djm Exp $ +# $OpenBSD: agent-pkcs11.sh,v 1.15 2025/07/26 01:53:31 djm Exp $ # Placed in the Public Domain. tid="pkcs11 agent test" p11_setup || skip "No PKCS#11 library found" -trace "start agent" -eval `${SSHAGENT} ${EXTRA_AGENT_ARGS} -s` > /dev/null +start_ssh_agent + +trace "add pkcs11 key to agent" +p11_ssh_add -s ${TEST_SSH_PKCS11} > /dev/null 2>&1 r=$? if [ $r -ne 0 ]; then - fail "could not start ssh-agent: exit code $r" -else - trace "add pkcs11 key to agent" - p11_ssh_add -s ${TEST_SSH_PKCS11} > /dev/null 2>&1 - r=$? - if [ $r -ne 0 ]; then - fail "ssh-add -s failed: exit code $r" - fi + fail "ssh-add -s failed: exit code $r" +fi - trace "pkcs11 list via agent" - ${SSHADD} -l > /dev/null 2>&1 - r=$? - if [ $r -ne 0 ]; then - fail "ssh-add -l failed: exit code $r" - fi +trace "pkcs11 list via agent" +${SSHADD} -l > /dev/null 2>&1 +r=$? +if [ $r -ne 0 ]; then + fail "ssh-add -l failed: exit code $r" +fi - for k in $RSA $EC; do - trace "testing $k" - pub=$(cat $k.pub) - ${SSHADD} -L | grep -q "$pub" || \ - fail "key $k missing in ssh-add -L" - ${SSHADD} -T $k.pub || fail "ssh-add -T with $k failed" - - # add to authorized keys - cat $k.pub > $OBJ/authorized_keys_$USER - trace "pkcs11 connect via agent ($k)" - ${SSH} -F $OBJ/ssh_proxy somehost exit 5 - r=$? - if [ $r -ne 5 ]; then - fail "ssh connect failed (exit code $r)" - fi - done - - trace "remove pkcs11 keys" - p11_ssh_add -e ${TEST_SSH_PKCS11} > /dev/null 2>&1 +for k in $ED25519 $RSA $EC; do + trace "testing $k" + pub=$(cat $k.pub) + ${SSHADD} -L | grep -q "$pub" || \ + fail "key $k missing in ssh-add -L" + ${SSHADD} -T $k.pub || fail "ssh-add -T with $k failed" + + # add to authorized keys + cat $k.pub > $OBJ/authorized_keys_$USER + trace "pkcs11 connect via agent ($k)" + ${SSH} -F $OBJ/ssh_proxy somehost exit 5 r=$? - if [ $r -ne 0 ]; then - fail "ssh-add -e failed: exit code $r" + if [ $r -ne 5 ]; then + fail "ssh connect failed (exit code $r)" fi +done - trace "kill agent" - ${SSHAGENT} -k > /dev/null +trace "remove pkcs11 keys" +p11_ssh_add -e ${TEST_SSH_PKCS11} > /dev/null 2>&1 +r=$? +if [ $r -ne 0 ]; then + fail "ssh-add -e failed: exit code $r" fi diff --git a/regress/agent-restrict.sh b/regress/agent-restrict.sh index 62cea85..7fc30fa 100644 --- a/regress/agent-restrict.sh +++ b/regress/agent-restrict.sh @@ -1,4 +1,4 @@ -# $OpenBSD: agent-restrict.sh,v 1.6 2023/03/01 09:29:32 dtucker Exp $ +# $OpenBSD: agent-restrict.sh,v 1.8 2025/05/23 08:40:13 dtucker Exp $ # Placed in the Public Domain. tid="agent restrictions" @@ -39,23 +39,19 @@ Host host_$h Hostname host_$h HostkeyAlias host_$h IdentityFile $OBJ/user_$h - ProxyCommand ${SUDO} env SSH_SK_HELPER=\"$SSH_SK_HELPER\" ${OBJ}/sshd-log-wrapper.sh -i -f $OBJ/sshd_proxy_host_$h + ProxyCommand ${SUDO} env SSH_SK_HELPER=\"$SSH_SK_HELPER\" ${TEST_SSH_SSHD_ENV} ${OBJ}/sshd-log-wrapper.sh -i -f $OBJ/sshd_proxy_host_$h _EOF # Variant with no specified keys. cat << _EOF >> $OBJ/ssh_proxy_noid Host host_$h Hostname host_$h HostkeyAlias host_$h - ProxyCommand ${SUDO} env SSH_SK_HELPER=\"$SSH_SK_HELPER\" ${OBJ}/sshd-log-wrapper.sh -i -f $OBJ/sshd_proxy_host_$h + ProxyCommand ${SUDO} env SSH_SK_HELPER=\"$SSH_SK_HELPER\" ${TEST_SSH_SSHD_ENV} ${OBJ}/sshd-log-wrapper.sh -i -f $OBJ/sshd_proxy_host_$h _EOF done cat $OBJ/ssh_proxy.bak >> $OBJ/ssh_proxy cat $OBJ/ssh_proxy.bak >> $OBJ/ssh_proxy_noid -LC_ALL=C -export LC_ALL -echo "SetEnv LC_ALL=${LC_ALL}" >> sshd_proxy - verbose "prepare known_hosts" rm -f $OBJ/known_hosts for h in a b c x ; do @@ -84,7 +80,8 @@ reset_keys() { _command="" case "$_whichcmd" in authinfo) _command="cat \$SSH_USER_AUTH" ;; - keylist) _command="$SSHADD -L | cut -d' ' -f-2 | sort" ;; + keylist) _command="$SSHADD -L | cut -d' ' -f-2 | \ + env LC_ALL=C sort" ;; *) fatal "unsupported command $_whichcmd" ;; esac trace "reset keys" @@ -227,7 +224,7 @@ rm -f $OBJ/expect_list.pre for u in a b c d e x; do cut -d " " -f-2 $OBJ/user_${u}.pub >> $OBJ/expect_list.pre done -sort $OBJ/expect_list.pre > $OBJ/expect_list +env LC_ALL=C sort $OBJ/expect_list.pre > $OBJ/expect_list for h in a b c d e; do cp $OBJ/expect_list $OBJ/expect_$h expect_succeed $h "unrestricted keylist" @@ -332,7 +329,7 @@ if test ! -z "\$me" ; then cat \$SSH_USER_AUTH fi echo AGENT -$SSHADD -L | egrep "^ssh" | cut -d" " -f-2 | sort +$SSHADD -L | egrep "^ssh" | cut -d" " -f-2 | env LC_ALL=C sort if test -z "\$next" ; then touch $OBJ/done echo "FINISH" @@ -369,7 +366,7 @@ prepare_multihop_expected() { done rm -f $OBJ/expect_a echo "AGENT" >> $OBJ/expect_a - test "x$_keys" = "xnone" || sort $OBJ/expect_keys >> $OBJ/expect_a + test "x$_keys" = "xnone" || env LC_ALL=C sort $OBJ/expect_keys >> $OBJ/expect_a echo "NEXT" >> $OBJ/expect_a for h in $_hops ; do echo "HOSTNAME host_$h" >> $OBJ/expect_a @@ -377,7 +374,7 @@ prepare_multihop_expected() { (printf "publickey " ; cut -d" " -f-2 $OBJ/user_a.pub) >> $OBJ/expect_a echo "AGENT" >> $OBJ/expect_a if test "x$_keys" = "xall" ; then - sort $OBJ/expect_keys >> $OBJ/expect_a + env LC_ALL=C sort $OBJ/expect_keys >> $OBJ/expect_a fi if test "x$h" != "x$_lasthop" ; then if test "x$_keys" = "xfiltered" ; then diff --git a/regress/agent.sh b/regress/agent.sh index 5f10606..26d4c9e 100644 --- a/regress/agent.sh +++ b/regress/agent.sh @@ -1,4 +1,4 @@ -# $OpenBSD: agent.sh,v 1.21 2023/03/01 09:29:32 dtucker Exp $ +# $OpenBSD: agent.sh,v 1.23 2025/05/06 06:05:48 djm Exp $ # Placed in the Public Domain. tid="simple agent test" @@ -86,10 +86,6 @@ fi for t in ${SSH_KEYTYPES}; do trace "connect via agent using $t key" - if [ "$t" = "ssh-dss" ]; then - echo "PubkeyAcceptedAlgorithms +ssh-dss" >> $OBJ/ssh_proxy - echo "PubkeyAcceptedAlgorithms +ssh-dss" >> $OBJ/sshd_proxy - fi ${SSH} -F $OBJ/ssh_proxy -i $OBJ/$t-agent.pub -oIdentitiesOnly=yes \ somehost exit 52 r=$? @@ -143,7 +139,6 @@ fi (printf 'cert-authority,principals="estragon" '; cat $OBJ/user_ca_key.pub) \ > $OBJ/authorized_keys_$USER for t in ${SSH_KEYTYPES}; do - if [ "$t" != "ssh-dss" ]; then trace "connect via agent using $t key" ${SSH} -F $OBJ/ssh_proxy -i $OBJ/$t-agent.pub \ -oCertificateFile=$OBJ/$t-agent-cert.pub \ @@ -152,12 +147,11 @@ for t in ${SSH_KEYTYPES}; do if [ $r -ne 52 ]; then fail "ssh connect with failed (exit code $r)" fi - fi done ## Deletion tests. -trace "delete all agent keys" +trace "delete all agent keys using -D" ${SSHADD} -D > /dev/null 2>&1 r=$? if [ $r -ne 0 ]; then @@ -181,6 +175,29 @@ r=$? if [ $r -ne 0 ]; then fail "ssh-add -l failed: exit code $r" fi +trace "delete all agent keys using SIGUSR1" +kill -s USR1 $SSH_AGENT_PID +r=$? +if [ $r -ne 0 ]; then + fail "kill -s USR1 failed: exit code $r" +fi +# make sure they're gone +${SSHADD} -l > /dev/null 2>&1 +r=$? +if [ $r -ne 1 ]; then + fail "ssh-add -l returned unexpected exit code: $r" +fi +# re-add keys/certs to agent +for t in ${SSH_KEYTYPES}; do + ${SSHADD} $OBJ/$t-agent-private >/dev/null 2>&1 || \ + fail "ssh-add failed exit code $?" +done +# make sure they are there +${SSHADD} -l > /dev/null 2>&1 +r=$? +if [ $r -ne 0 ]; then + fail "ssh-add -l failed: exit code $r" +fi check_key_absent() { ${SSHADD} -L | grep "^$1 " >/dev/null diff --git a/regress/cert-hostkey.sh b/regress/cert-hostkey.sh index a3414e1..bfdd358 100644 --- a/regress/cert-hostkey.sh +++ b/regress/cert-hostkey.sh @@ -1,4 +1,4 @@ -# $OpenBSD: cert-hostkey.sh,v 1.27 2021/09/30 05:26:26 dtucker Exp $ +# $OpenBSD: cert-hostkey.sh,v 1.28 2025/05/06 06:05:48 djm Exp $ # Placed in the Public Domain. tid="certified host keys" @@ -70,7 +70,7 @@ touch $OBJ/host_revoked_plain touch $OBJ/host_revoked_cert cat $OBJ/host_ca_key.pub $OBJ/host_ca_key2.pub > $OBJ/host_revoked_ca -PLAIN_TYPES=`echo "$SSH_KEYTYPES" | sed 's/^ssh-dss/ssh-dsa/g;s/^ssh-//'` +PLAIN_TYPES=`echo "$SSH_KEYTYPES" | sed 's/^ssh-//'` if echo "$PLAIN_TYPES" | grep '^rsa$' >/dev/null 2>&1 ; then PLAIN_TYPES="$PLAIN_TYPES rsa-sha2-256 rsa-sha2-512" diff --git a/regress/cert-userkey.sh b/regress/cert-userkey.sh index 4ea29b7..fde2cae 100644 --- a/regress/cert-userkey.sh +++ b/regress/cert-userkey.sh @@ -1,13 +1,16 @@ -# $OpenBSD: cert-userkey.sh,v 1.28 2021/09/30 05:26:26 dtucker Exp $ +# $OpenBSD: cert-userkey.sh,v 1.30 2025/05/06 06:05:48 djm Exp $ # Placed in the Public Domain. tid="certified user keys" -rm -f $OBJ/authorized_keys_$USER $OBJ/user_ca_key* $OBJ/cert_user_key* -cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak +rm -f $OBJ/authorized_keys_${USER}* $OBJ/user_ca_key* $OBJ/cert_user_key* +rm -f $OBJ/authorized_principals* cp $OBJ/ssh_proxy $OBJ/ssh_proxy_bak -PLAIN_TYPES=`$SSH -Q key-plain | maybe_filter_sk | sed 's/^ssh-dss/ssh-dsa/;s/^ssh-//'` +grep -v AuthorizedKeysFile $OBJ/sshd_proxy > $OBJ/sshd_proxy_bak +echo "AuthorizedKeysFile $OBJ/authorized_keys_%u_*" >> $OBJ/sshd_proxy_bak + +PLAIN_TYPES=`$SSH -Q key-plain | maybe_filter_sk | sed 's/^ssh-//'` EXTRA_TYPES="" rsa="" @@ -22,7 +25,7 @@ kname() { sk-ecdsa-*) n="sk-ecdsa" ;; sk-ssh-ed25519*) n="sk-ssh-ed25519" ;; # subshell because some seds will add a newline - *) n=$(echo $1 | sed 's/^dsa/ssh-dss/;s/^rsa/ssh-rsa/;s/^ed/ssh-ed/') ;; + *) n=$(echo $1 | sed 's/^rsa/ssh-rsa/;s/^ed/ssh-ed/') ;; esac if [ -z "$rsa" ]; then echo "$n*,ssh-ed25519*" @@ -63,11 +66,15 @@ for ktype in $EXTRA_TYPES $PLAIN_TYPES ; do _prefix="${ktype}" # Setup for AuthorizedPrincipalsFile - rm -f $OBJ/authorized_keys_$USER + rm -f $OBJ/authorized_keys_${USER}* $OBJ/authorized_principals_${USER}* + touch $OBJ/authorized_keys_${USER}_A + touch $OBJ/authorized_keys_${USER}_Z + touch $OBJ/authorized_principals_${USER}_A + touch $OBJ/authorized_principals_${USER}_Z ( cat $OBJ/sshd_proxy_bak echo "AuthorizedPrincipalsFile " \ - "$OBJ/authorized_principals_%u" + "$OBJ/authorized_principals_%u_*" echo "TrustedUserCAKeys $OBJ/user_ca_key.pub" echo "PubkeyAcceptedAlgorithms ${t}" ) > $OBJ/sshd_proxy @@ -78,7 +85,7 @@ for ktype in $EXTRA_TYPES $PLAIN_TYPES ; do # Missing authorized_principals verbose "$tid: ${_prefix} missing authorized_principals" - rm -f $OBJ/authorized_principals_$USER + rm -f $OBJ/authorized_principals_${USER}_X ${SSH} -i $OBJ/cert_user_key_${ktype} \ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 if [ $? -eq 0 ]; then @@ -87,7 +94,7 @@ for ktype in $EXTRA_TYPES $PLAIN_TYPES ; do # Empty authorized_principals verbose "$tid: ${_prefix} empty authorized_principals" - echo > $OBJ/authorized_principals_$USER + echo > $OBJ/authorized_principals_${USER}_X ${SSH} -i $OBJ/cert_user_key_${ktype} \ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 if [ $? -eq 0 ]; then @@ -96,7 +103,7 @@ for ktype in $EXTRA_TYPES $PLAIN_TYPES ; do # Wrong authorized_principals verbose "$tid: ${_prefix} wrong authorized_principals" - echo gregorsamsa > $OBJ/authorized_principals_$USER + echo gregorsamsa > $OBJ/authorized_principals_${USER}_X ${SSH} -i $OBJ/cert_user_key_${ktype} \ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 if [ $? -eq 0 ]; then @@ -105,7 +112,7 @@ for ktype in $EXTRA_TYPES $PLAIN_TYPES ; do # Correct authorized_principals verbose "$tid: ${_prefix} correct authorized_principals" - echo mekmitasdigoat > $OBJ/authorized_principals_$USER + echo mekmitasdigoat > $OBJ/authorized_principals_${USER}_X ${SSH} -i $OBJ/cert_user_key_${ktype} \ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 if [ $? -ne 0 ]; then @@ -114,7 +121,7 @@ for ktype in $EXTRA_TYPES $PLAIN_TYPES ; do # authorized_principals with bad key option verbose "$tid: ${_prefix} authorized_principals bad key opt" - echo 'blah mekmitasdigoat' > $OBJ/authorized_principals_$USER + echo 'blah mekmitasdigoat' > $OBJ/authorized_principals_${USER}_X ${SSH} -i $OBJ/cert_user_key_${ktype} \ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 if [ $? -eq 0 ]; then @@ -124,7 +131,7 @@ for ktype in $EXTRA_TYPES $PLAIN_TYPES ; do # authorized_principals with command=false verbose "$tid: ${_prefix} authorized_principals command=false" echo 'command="false" mekmitasdigoat' > \ - $OBJ/authorized_principals_$USER + $OBJ/authorized_principals_${USER}_X ${SSH} -i $OBJ/cert_user_key_${ktype} \ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 if [ $? -eq 0 ]; then @@ -135,7 +142,7 @@ for ktype in $EXTRA_TYPES $PLAIN_TYPES ; do # authorized_principals with command=true verbose "$tid: ${_prefix} authorized_principals command=true" echo 'command="true" mekmitasdigoat' > \ - $OBJ/authorized_principals_$USER + $OBJ/authorized_principals_${USER}_X ${SSH} -i $OBJ/cert_user_key_${ktype} \ -F $OBJ/ssh_proxy somehost false >/dev/null 2>&1 if [ $? -ne 0 ]; then @@ -143,7 +150,7 @@ for ktype in $EXTRA_TYPES $PLAIN_TYPES ; do fi # Setup for principals= key option - rm -f $OBJ/authorized_principals_$USER + rm -f $OBJ/authorized_principals_${USER}_X ( cat $OBJ/sshd_proxy_bak echo "PubkeyAcceptedAlgorithms ${t}" @@ -158,7 +165,7 @@ for ktype in $EXTRA_TYPES $PLAIN_TYPES ; do ( printf 'cert-authority,principals="gregorsamsa" ' cat $OBJ/user_ca_key.pub - ) > $OBJ/authorized_keys_$USER + ) > $OBJ/authorized_keys_${USER}_X ${SSH} -i $OBJ/cert_user_key_${ktype} \ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 if [ $? -eq 0 ]; then @@ -170,7 +177,7 @@ for ktype in $EXTRA_TYPES $PLAIN_TYPES ; do ( printf 'cert-authority,principals="mekmitasdigoat" ' cat $OBJ/user_ca_key.pub - ) > $OBJ/authorized_keys_$USER + ) > $OBJ/authorized_keys_${USER}_X ${SSH} -i $OBJ/cert_user_key_${ktype} \ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 if [ $? -ne 0 ]; then @@ -180,14 +187,17 @@ done basic_tests() { auth=$1 + rm -f $OBJ/authorized_keys_${USER}* + touch $OBJ/authorized_keys_${USER}_A + touch $OBJ/authorized_keys_${USER}_Z if test "x$auth" = "xauthorized_keys" ; then # Add CA to authorized_keys ( printf 'cert-authority ' cat $OBJ/user_ca_key.pub - ) > $OBJ/authorized_keys_$USER + ) > $OBJ/authorized_keys_${USER}_X else - echo > $OBJ/authorized_keys_$USER + echo > $OBJ/authorized_keys_${USER}_X extra_sshd="TrustedUserCAKeys $OBJ/user_ca_key.pub" fi @@ -295,9 +305,9 @@ test_one() { ( printf "cert-authority${auth_opt} " cat $OBJ/user_ca_key.pub - ) > $OBJ/authorized_keys_$USER + ) > $OBJ/authorized_keys_${USER}_X else - echo > $OBJ/authorized_keys_$USER + echo > $OBJ/authorized_keys_${USER}_X echo "TrustedUserCAKeys $OBJ/user_ca_key.pub" \ >> $OBJ/sshd_proxy echo "PubkeyAcceptedAlgorithms ${t}*" \ @@ -346,15 +356,15 @@ test_one "empty principals" failure "" TrustedUserCAKeys # should always be refused. # AuthorizedPrincipalsFile -rm -f $OBJ/authorized_keys_$USER -echo mekmitasdigoat > $OBJ/authorized_principals_$USER +rm -f $OBJ/authorized_keys_${USER}_X +echo mekmitasdigoat > $OBJ/authorized_principals_${USER}_X test_one "AuthorizedPrincipalsFile principals" success "-n mekmitasdigoat" \ - TrustedUserCAKeys "AuthorizedPrincipalsFile $OBJ/authorized_principals_%u" + TrustedUserCAKeys "AuthorizedPrincipalsFile $OBJ/authorized_principals_%u_*" test_one "AuthorizedPrincipalsFile no principals" failure "" \ - TrustedUserCAKeys "AuthorizedPrincipalsFile $OBJ/authorized_principals_%u" + TrustedUserCAKeys "AuthorizedPrincipalsFile $OBJ/authorized_principals_%u_*" # principals= key option -rm -f $OBJ/authorized_principals_$USER +rm -f $OBJ/authorized_principals_${USER}_X test_one "principals key option principals" success "-n mekmitasdigoat" \ authorized_keys ',principals="mekmitasdigoat"' test_one "principals key option no principals" failure "" \ @@ -391,6 +401,6 @@ for ktype in $PLAIN_TYPES ; do fi done -rm -f $OBJ/authorized_keys_$USER $OBJ/user_ca_key* $OBJ/cert_user_key* -rm -f $OBJ/authorized_principals_$USER +rm -f $OBJ/authorized_keys_${USER}* $OBJ/user_ca_key* $OBJ/cert_user_key* +rm -f $OBJ/authorized_principals* diff --git a/regress/cfginclude.sh b/regress/cfginclude.sh index d442cdd..97fd816 100644 --- a/regress/cfginclude.sh +++ b/regress/cfginclude.sh @@ -1,4 +1,4 @@ -# $OpenBSD: cfginclude.sh,v 1.4 2024/09/03 05:58:56 djm Exp $ +# $OpenBSD: cfginclude.sh,v 1.5 2024/09/27 01:05:54 djm Exp $ # Placed in the Public Domain. tid="config include" @@ -10,7 +10,7 @@ cat > $OBJ/ssh_config.i << _EOF Match host a Hostname aa -Match host b # comment +Match host=b # comment Hostname bb Include $OBJ/ssh_config.i.* @@ -18,7 +18,7 @@ Match host c Include $OBJ/ssh_config.i.* Hostname cc -Match host m +Match host=m !user xxxyfake Include $OBJ/ssh_config.i.* # comment Host d @@ -41,7 +41,7 @@ Match host xxxxxx _EOF cat > $OBJ/ssh_config.i.1 << _EOF -Match host a +Match host=a Hostname aaa Match host b @@ -64,10 +64,10 @@ cat > $OBJ/ssh_config.i.2 << _EOF Match host a Hostname aaaa -Match host b +Match host=b !user blahblahfake Hostname bbbb -Match host c +Match host=c Hostname cccc Host d @@ -142,7 +142,7 @@ trial a aa # cleanup rm -f $OBJ/ssh_config.i $OBJ/ssh_config.i.* $OBJ/ssh_config.out -# $OpenBSD: cfginclude.sh,v 1.4 2024/09/03 05:58:56 djm Exp $ +# $OpenBSD: cfginclude.sh,v 1.5 2024/09/27 01:05:54 djm Exp $ # Placed in the Public Domain. tid="config include" diff --git a/regress/cfgmatch.sh b/regress/cfgmatch.sh index 05a6668..8b9d80f 100644 --- a/regress/cfgmatch.sh +++ b/regress/cfgmatch.sh @@ -1,4 +1,4 @@ -# $OpenBSD: cfgmatch.sh,v 1.13 2021/06/08 06:52:43 djm Exp $ +# $OpenBSD: cfgmatch.sh,v 1.15 2025/07/11 23:26:59 djm Exp $ # Placed in the Public Domain. tid="sshd_config match" @@ -26,7 +26,7 @@ start_client() kill $client_pid fatal "timeout waiting for background ssh" fi - done + done } stop_client() @@ -106,6 +106,8 @@ cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy echo "PermitOpen 127.0.0.1:1 127.0.0.1:$PORT 127.0.0.2:2" >>$OBJ/sshd_proxy echo "Match User NoSuchUser" >>$OBJ/sshd_proxy echo "PermitOpen 127.0.0.1:1 127.0.0.1:2" >>$OBJ/sshd_proxy +echo "Match Group NoSuchGroup" >>$OBJ/sshd_proxy +echo "PermitOpen 127.0.0.1:1 127.0.0.1:2" >>$OBJ/sshd_proxy # Test that a rule that doesn't match doesn't override, plus test a # PermitOpen entry that's not at the start of the list @@ -119,40 +121,42 @@ stop_client # requires knowledge of actual group memberships user running the test). params="user:user:u1 host:host:h1 address:addr:1.2.3.4 \ localaddress:laddr:5.6.7.8 rdomain:rdomain:rdom1" -cp $OBJ/sshd_proxy_bak $OBJ/sshd_config -echo 'Banner /nomatch' >>$OBJ/sshd_config -for i in $params; do - config=`echo $i | cut -f1 -d:` - criteria=`echo $i | cut -f2 -d:` - value=`echo $i | cut -f3 -d:` - cat >>$OBJ/sshd_config </dev/null || \ + fail "validate config for w/out spec" + + # Test matching each criteria. + for i in $params; do + testcriteria=`echo $i | cut -f2 -d:` + expected=/`echo $i | cut -f3 -d:` + spec="" + for j in $params; do + config=`echo $j | cut -f1 -d:` + criteria=`echo $j | cut -f2 -d:` + value=`echo $j | cut -f3 -d:` + if [ "$criteria" = "$testcriteria" ]; then + spec="$criteria=$value,$spec" + else + spec="$criteria=1$value,$spec" + fi + done + trace "test spec $spec" + result=`${SUDO} ${SSHD} -f $OBJ/sshd_config -T -C "$spec" | \ + awk '$1=="banner"{print $2}'` + if [ "$result" != "$expected" ]; then + fail "match $config expected $expected got $result" fi done - trace "test spec $spec" - result=`${SUDO} ${SSHD} -f $OBJ/sshd_config -T -C "$spec" | \ - awk '$1=="banner"{print $2}'` - if [ "$result" != "$expected" ]; then - fail "match $config expected $expected got $result" - fi done diff --git a/regress/cfgparse.sh b/regress/cfgparse.sh index a9e5c6b..d618e36 100644 --- a/regress/cfgparse.sh +++ b/regress/cfgparse.sh @@ -1,4 +1,4 @@ -# $OpenBSD: cfgparse.sh,v 1.7 2018/05/11 03:51:06 dtucker Exp $ +# $OpenBSD: cfgparse.sh,v 1.9 2025/09/26 04:40:45 dtucker Exp $ # Placed in the Public Domain. tid="sshd config parse" @@ -51,7 +51,7 @@ listenaddress ::1 EOD ($SUDO ${SSHD} -T -f $OBJ/sshd_config.1 | \ - grep 'listenaddress ' >$OBJ/sshd_config.2 && + grep '^listenaddress ' >$OBJ/sshd_config.2 && diff $OBJ/sshd_config.0 $OBJ/sshd_config.2) || \ fail "listenaddress order 1" # test 2: listenaddress first @@ -67,9 +67,22 @@ listenaddress ::1 EOD ($SUDO ${SSHD} -T -f $OBJ/sshd_config.1 | \ - grep 'listenaddress ' >$OBJ/sshd_config.2 && + grep '^listenaddress ' >$OBJ/sshd_config.2 && diff $OBJ/sshd_config.0 $OBJ/sshd_config.2) || \ fail "listenaddress order 2" +# Check idempotence of MaxStartups +verbose "maxstartups idempotent" +echo "maxstartups 1:2:3" > $OBJ/sshd_config.0 +cat > $OBJ/sshd_config.1 <$OBJ/sshd_config.2 && + diff $OBJ/sshd_config.0 $OBJ/sshd_config.2) || \ + fail "maxstartups idempotence" + # cleanup rm -f $OBJ/sshd_config.[012] diff --git a/regress/connect-bigconf.sh b/regress/connect-bigconf.sh new file mode 100644 index 0000000..ca2c119 --- /dev/null +++ b/regress/connect-bigconf.sh @@ -0,0 +1,17 @@ +# $OpenBSD: connect-bigconf.sh,v 1.1 2025/07/04 07:52:17 djm Exp $ +# Placed in the Public Domain. + +tid="simple connect" + +for x in `jot 10000 1` ; do + echo "Match version NONEXIST" >> $OBJ/sshd_config + echo "ChrootDirectory /some/path/for/group/NONEXIST" >> $OBJ/sshd_config +done +#cat $OBJ/sshd_config +start_sshd + +trace "direct connect with large sshd_config" +${SSH} -F $OBJ/ssh_config somehost true +if [ $? -ne 0 ]; then + fail "ssh direct connect with large sshd_config failed" +fi diff --git a/regress/dropbear-ciphers.sh b/regress/dropbear-ciphers.sh index 1500fa0..c58cb90 100644 --- a/regress/dropbear-ciphers.sh +++ b/regress/dropbear-ciphers.sh @@ -1,4 +1,4 @@ -# $OpenBSD: dropbear-ciphers.sh,v 1.3 2024/06/20 08:23:18 dtucker Exp $ +# $OpenBSD: dropbear-ciphers.sh,v 1.4 2025/03/11 07:43:03 dtucker Exp $ # Placed in the Public Domain. tid="dropbear ciphers" @@ -26,7 +26,7 @@ for c in $ciphers ; do for kt in $keytype; do verbose "$tid: cipher $c mac $m kt $kt" rm -f ${COPY} - env HOME=$OBJ dbclient -y -i $OBJ/.dropbear/$kt 2>$OBJ/dbclient.log \ + env HOME=$OBJ ${DBCLIENT} -y -i $OBJ/.dropbear/$kt 2>$OBJ/dbclient.log \ -c $c -m $m -J "$OBJ/ssh_proxy.sh" somehost cat ${DATA} > ${COPY} if [ $? -ne 0 ]; then fail "ssh cat $DATA failed" diff --git a/regress/dropbear-kex.sh b/regress/dropbear-kex.sh index d9f1b32..72717fb 100644 --- a/regress/dropbear-kex.sh +++ b/regress/dropbear-kex.sh @@ -1,4 +1,4 @@ -# $OpenBSD: dropbear-kex.sh,v 1.3 2024/06/19 10:10:46 dtucker Exp $ +# $OpenBSD: dropbear-kex.sh,v 1.4 2025/03/11 07:42:08 dtucker Exp $ # Placed in the Public Domain. tid="dropbear kex" @@ -10,8 +10,14 @@ fi cp $OBJ/sshd_proxy $OBJ/sshd_proxy.bak kex="curve25519-sha256 curve25519-sha256@libssh.org" -if $SSH -Q kex | grep 'diffie-hellman-group14-sha1'; then - kex="$kex diffie-hellman-group14-sha256 diffie-hellman-group14-sha1" +if $SSH -Q kex | grep 'diffie-hellman-group14-sha256' >/dev/null; then + kex="$kex diffie-hellman-group14-sha256" +fi +# There's no flag to query KEX, so if MACs does not contain SHA1, assume +# there's also SHA1-based KEX methods either. +if $SSH -Q kex | grep 'diffie-hellman-group14-sha1' >/dev/null && \ + $DBCLIENT -m help hst 2>&1 | grep -- '-sha1' >/dev/null ; then + kex="$kex diffie-hellman-group14-sha1" fi for k in $kex; do @@ -19,8 +25,9 @@ for k in $kex; do rm -f ${COPY} # dbclient doesn't have switch for kex, so force in server (cat $OBJ/sshd_proxy.bak; echo "KexAlgorithms $k") >$OBJ/sshd_proxy - env HOME=$OBJ dbclient -y -i $OBJ/.dropbear/id_ed25519 2>$OBJ/dbclient.log \ - -J "$OBJ/ssh_proxy.sh" somehost cat ${DATA} > ${COPY} + env HOME=$OBJ \ + ${DBCLIENT} -y -i $OBJ/.dropbear/id_ed25519 2>$OBJ/dbclient.log \ + -J "$OBJ/ssh_proxy.sh" somehost cat ${DATA} > ${COPY} if [ $? -ne 0 ]; then fail "ssh cat $DATA failed" fi diff --git a/regress/dropbear-server.sh b/regress/dropbear-server.sh new file mode 100644 index 0000000..c72c86b --- /dev/null +++ b/regress/dropbear-server.sh @@ -0,0 +1,76 @@ +# $OpenBSD: dropbear-server.sh,v 1.2 2025/06/29 05:35:00 dtucker Exp $ +# Placed in the Public Domain. + +tid="dropbear server" + +if test "x$REGRESS_INTEROP_DROPBEAR" != "xyes" ; then + skip "dropbear interop tests not enabled" +fi + +ver="`$DROPBEAR -V 2>&1 | sed 's/Dropbear v//'`" +if [ -z "$ver" ]; then + skip "can't determine dropbear version" +fi + +major=`echo $ver | cut -f1 -d.` +minor=`echo $ver | cut -f2 -d.` + +if [ "$major" -lt "2025" ] || [ "$minor" -lt "87" ]; then + skip "dropbear version $ver (${major}.${minor}) does not support '-D'" +else + trace "dropbear version $ver (${major}.${minor}) ok" +fi + +if [ -z "$SUDO" -a ! -w /var/run ]; then + skip "need SUDO to create dir in /var/run, test won't work without" +fi +authkeydir=/var/run/dropbear-regress + +ciphers=`$DBCLIENT -c help hst 2>&1 | awk '/ ciphers: /{print $4}' | tr ',' ' '` +macs=`$DBCLIENT -m help hst 2>&1 | awk '/ MACs: /{print $4}' | tr ',' ' '` +if [ -z "$macs" ] || [ -z "$ciphers" ]; then + skip "dbclient query ciphers '$ciphers' or macs '$macs' failed" +fi + +# Set up authorized_keys for dropbear. +umask 077 +$SUDO mkdir -p $authkeydir +$SUDO chown -R $USER $authkeydir +cp $OBJ/authorized_keys_$USER $authkeydir/authorized_keys + +for i in `$SUDO $SSHD -f $OBJ/sshd_config -T | grep -v sk- | \ + awk '$1=="hostkey" {print $2}'`; do + file=`basename "$i"` + file=`echo "$file" | sed s/^host\./db\./g` + if $SUDO $DROPBEARCONVERT openssh dropbear "$i" "$OBJ/$file" \ + >/dev/null 2>&1; then + $SUDO chown $USER $OBJ/$file + hkeys="-r $OBJ/$file" + fi +done + +rm -f $OBJ/dropbear.pid +$DROPBEAR -D $authkeydir -p $PORT -P $OBJ/dropbear.pid $hkeys -E \ + 2>$OBJ/sshd.log +if [ $? -ne 0 ]; then + fatal "starting dropbear server failed" +fi +while [ ! -f $OBJ/dropbear.pid ]; do + sleep 1 +done + +pid=`cat $OBJ/dropbear.pid` +trap "kill $pid; $SUDO rm -rf $authkeydir" 0 + +for c in $ciphers; do + for m in $macs; do + trace "$tid: cipher $c mac $m hk $hk" + rm -f ${COPY} + ${SSH} -F $OBJ/ssh_config -oCiphers=$c -oMacs=$m \ + somehost cat ${DATA} > ${COPY} + if [ $? -ne 0 ]; then + fail "connect dropbear server failed" + fi + cmp ${DATA} ${COPY} || fail "corrupted copy" + done +done diff --git a/regress/dsa_ssh2.prv b/regress/dsa_ssh2.prv deleted file mode 100644 index c93b403..0000000 --- a/regress/dsa_ssh2.prv +++ /dev/null @@ -1,14 +0,0 @@ ----- BEGIN SSH2 ENCRYPTED PRIVATE KEY ---- -Subject: ssh-keygen test -Comment: "1024-bit dsa, Tue Jan 08 2002 22:00:23 +0100" -P2/56wAAAgIAAAAmZGwtbW9kcHtzaWdue2RzYS1uaXN0LXNoYTF9LGRoe3BsYWlufX0AAA -AEbm9uZQAAAcQAAAHAAAAAAAAABACwUfm3AxZTut3icBmwCcD48nY64HzuELlQ+vEqjIcR -Lo49es/DQTeLNQ+kdKRCfouosGNv0WqxRtF0tUsWdXxS37oHGa4QPugBdHRd7YlZGZv8kg -x7FsoepY7v7E683/97dv2zxL3AGagTEzWr7fl0yPexAaZoDvtQrrjX44BLmwAABACWQkvv -MxnD8eFkS1konFfMJ1CkuRfTN34CBZ6dY7VTSGemy4QwtFdMKmoufD0eKgy3p5WOeWCYKt -F4FhjHKZk/aaxFjjIbtkrnlvXg64QI11dSZyBN6/ViQkHPSkUDF+A6AAEhrNbQbAFSvao1 -kTvNtPCtL0AkUIduEMzGQfLCTAAAAKDeC043YVo9Zo0zAEeIA4uZh4LBCQAAA/9aj7Y5ik -ehygJ4qTDSlVypsPuV+n59tMS0e2pfrSG87yf5r94AKBmJeho5OO6wYaXCxsVB7AFbSUD6 -75AK8mHF4v1/+7SWKk5f8xlMCMSPZ9K0+j/W1d/q2qkhnnDZolOHDomLA+U00i5ya/jnTV -zyDPWLFpWK8u3xGBPAYX324gAAAKDHFvooRnaXdZbeWGTTqmgHB1GU9A== ----- END SSH2 ENCRYPTED PRIVATE KEY ---- diff --git a/regress/dsa_ssh2.pub b/regress/dsa_ssh2.pub deleted file mode 100644 index 215d73b..0000000 --- a/regress/dsa_ssh2.pub +++ /dev/null @@ -1,13 +0,0 @@ ----- BEGIN SSH2 PUBLIC KEY ---- -Subject: ssh-keygen test -Comment: "1024-bit dsa, Tue Jan 08 2002 22:00:23 +0100" -AAAAB3NzaC1kc3MAAACBALBR+bcDFlO63eJwGbAJwPjydjrgfO4QuVD68SqMhxEujj16z8 -NBN4s1D6R0pEJ+i6iwY2/RarFG0XS1SxZ1fFLfugcZrhA+6AF0dF3tiVkZm/ySDHsWyh6l -ju/sTrzf/3t2/bPEvcAZqBMTNavt+XTI97EBpmgO+1CuuNfjgEubAAAAFQDeC043YVo9Zo -0zAEeIA4uZh4LBCQAAAIEAlkJL7zMZw/HhZEtZKJxXzCdQpLkX0zd+AgWenWO1U0hnpsuE -MLRXTCpqLnw9HioMt6eVjnlgmCrReBYYxymZP2msRY4yG7ZK55b14OuECNdXUmcgTev1Yk -JBz0pFAxfgOgABIazW0GwBUr2qNZE7zbTwrS9AJFCHbhDMxkHywkwAAACAWo+2OYpHocoC -eKkw0pVcqbD7lfp+fbTEtHtqX60hvO8n+a/eACgZiXoaOTjusGGlwsbFQewBW0lA+u+QCv -JhxeL9f/u0lipOX/MZTAjEj2fStPo/1tXf6tqpIZ5w2aJThw6JiwPlNNIucmv4501c8gz1 -ixaVivLt8RgTwGF99uI= ----- END SSH2 PUBLIC KEY ---- diff --git a/regress/dynamic-forward.sh b/regress/dynamic-forward.sh index 85901ea..6cc47e7 100644 --- a/regress/dynamic-forward.sh +++ b/regress/dynamic-forward.sh @@ -1,4 +1,4 @@ -# $OpenBSD: dynamic-forward.sh,v 1.17 2024/03/08 11:34:10 dtucker Exp $ +# $OpenBSD: dynamic-forward.sh,v 1.18 2025/05/21 08:41:52 djm Exp $ # Placed in the Public Domain. tid="dynamic forwarding" @@ -54,7 +54,7 @@ stop_ssh() { check_socks() { direction=$1 expect_success=$2 - for s in 4 5; do + for s in 4A 4 5; do for h in 127.0.0.1 localhost; do trace "testing ssh socks version $s host $h (-$direction)" ${REAL_SSH} -q -F $OBJ/ssh_config -o \ diff --git a/regress/hostbased.sh b/regress/hostbased.sh index eb9cf27..5de176b 100644 --- a/regress/hostbased.sh +++ b/regress/hostbased.sh @@ -1,4 +1,4 @@ -# $OpenBSD: hostbased.sh,v 1.4 2022/12/07 11:45:43 dtucker Exp $ +# $OpenBSD: hostbased.sh,v 1.5 2025/05/06 06:05:48 djm Exp $ # Placed in the Public Domain. # This test requires external setup and thus is skipped unless @@ -43,7 +43,6 @@ for key in `${SUDO} ${SSHD} -T | awk '$1=="hostkey"{print $2}'`; do 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 diff --git a/regress/hostkey-agent.sh b/regress/hostkey-agent.sh index 222d424..28dcfe1 100644 --- a/regress/hostkey-agent.sh +++ b/regress/hostkey-agent.sh @@ -1,4 +1,4 @@ -# $OpenBSD: hostkey-agent.sh,v 1.13 2021/09/30 05:20:08 dtucker Exp $ +# $OpenBSD: hostkey-agent.sh,v 1.15 2024/12/04 10:51:13 dtucker Exp $ # Placed in the Public Domain. tid="hostkey agent" @@ -49,7 +49,7 @@ for k in $SSH_KEYTYPES ; do fi done -SSH_CERTTYPES=`ssh -Q key-sig | grep 'cert-v01@openssh.com'` +SSH_CERTTYPES=`ssh -Q key-sig | grep 'cert-v01@openssh.com' | maybe_filter_sk` # Prepare sshd_proxy for certificates. cp $OBJ/sshd_proxy.orig $OBJ/sshd_proxy @@ -82,6 +82,30 @@ for k in $SSH_CERTTYPES ; do fi done +verbose "multiple hostkeys" +cp $OBJ/sshd_proxy.orig $OBJ/sshd_proxy +cp $OBJ/ssh_proxy $OBJ/ssh_proxy.orig +grep -vi 'globalknownhostsfile' $OBJ/ssh_proxy.orig > $OBJ/ssh_proxy +echo "UpdateHostkeys=yes" >> $OBJ/ssh_proxy +echo "GlobalKnownHostsFile=none" >> $OBJ/ssh_proxy + +for k in $SSH_KEYTYPES ; do + verbose "Addkey type $k" + echo "Hostkey $OBJ/agent-key.${k}" >> $OBJ/sshd_proxy + + ( printf 'localhost-with-alias ' ; + cat $OBJ/agent-key.$k.pub) > $OBJ/known_hosts +done + +opts="-oStrictHostKeyChecking=yes -F $OBJ/ssh_proxy" +SSH_CONNECTION=`${SSH} $opts host 'echo $SSH_CONNECTION'` +if [ $? -ne 0 ]; then + fail "connection to server with multiple hostkeys failed" +fi +if [ "$SSH_CONNECTION" != "UNKNOWN 65535 UNKNOWN 65535" ]; then + fail "bad SSH_CONNECTION key while using multiple hostkeys" +fi + trace "kill agent" ${SSHAGENT} -k > /dev/null diff --git a/regress/key-options.sh b/regress/key-options.sh index 623128c..7f9b45f 100644 --- a/regress/key-options.sh +++ b/regress/key-options.sh @@ -1,4 +1,4 @@ -# $OpenBSD: key-options.sh,v 1.10 2024/03/25 02:07:08 dtucker Exp $ +# $OpenBSD: key-options.sh,v 1.11 2024/12/05 14:28:39 dtucker Exp $ # Placed in the Public Domain. tid="key options" @@ -120,5 +120,8 @@ check_valid_before() { check_valid_before "default" "" "pass" check_valid_before "invalid" 'expiry-time="INVALID"' "fail" check_valid_before "expired" 'expiry-time="19990101"' "fail" +if config_defined "SIZEOF_TIME_T 4"; then check_valid_before "valid" 'expiry-time="20380101"' "pass" - +else +check_valid_before "valid-64b" 'expiry-time="25250101"' "pass" +fi diff --git a/regress/keygen-comment.sh b/regress/keygen-comment.sh index af571d3..56dde0e 100644 --- a/regress/keygen-comment.sh +++ b/regress/keygen-comment.sh @@ -1,4 +1,5 @@ -#    Placed in the Public Domain. +# $OpenBSD: keygen-comment.sh,v 1.3 2025/10/01 00:30:19 dtucker Exp $ +# Placed in the Public Domain. tid="Comment extraction from private key" diff --git a/regress/keytype.sh b/regress/keytype.sh index f1c0451..11ef7d0 100644 --- a/regress/keytype.sh +++ b/regress/keytype.sh @@ -1,4 +1,4 @@ -# $OpenBSD: keytype.sh,v 1.11 2021/02/25 03:27:34 djm Exp $ +# $OpenBSD: keytype.sh,v 1.12 2025/05/06 06:05:48 djm Exp $ # Placed in the Public Domain. tid="login with different key types" @@ -10,7 +10,6 @@ cp $OBJ/ssh_proxy $OBJ/ssh_proxy_bak ktypes="" for i in ${SSH_KEYTYPES}; do case "$i" in - ssh-dss) ktypes="$ktypes dsa-1024" ;; ssh-rsa) ktypes="$ktypes rsa-2048 rsa-3072" ;; ssh-ed25519) ktypes="$ktypes ed25519-512" ;; ecdsa-sha2-nistp256) ktypes="$ktypes ecdsa-256" ;; @@ -36,7 +35,6 @@ done kname_to_ktype() { case $1 in - dsa-1024) echo ssh-dss;; ecdsa-256) echo ecdsa-sha2-nistp256;; ecdsa-384) echo ecdsa-sha2-nistp384;; ecdsa-521) echo ecdsa-sha2-nistp521;; diff --git a/regress/knownhosts-command.sh b/regress/knownhosts-command.sh index 8472ec8..2ed6fa0 100644 --- a/regress/knownhosts-command.sh +++ b/regress/knownhosts-command.sh @@ -1,4 +1,4 @@ -# $OpenBSD: knownhosts-command.sh,v 1.3 2021/08/30 01:15:45 djm Exp $ +# $OpenBSD: knownhosts-command.sh,v 1.4 2025/05/06 06:05:48 djm Exp $ # Placed in the Public Domain. tid="known hosts command " @@ -40,7 +40,6 @@ ${SSH} -F $OBJ/ssh_proxy x true && fail "ssh connect succeeded with bad exit" for keytype in ${SSH_HOSTKEY_TYPES} ; do algs=$keytype - test "x$keytype" = "xssh-dss" && continue test "x$keytype" = "xssh-rsa" && algs=ssh-rsa,rsa-sha2-256,rsa-sha2-512 verbose "keytype $keytype" cat > $OBJ/knownhosts_command << _EOF diff --git a/regress/krl.sh b/regress/krl.sh index d560d61..37d9f17 100644 --- a/regress/krl.sh +++ b/regress/krl.sh @@ -1,4 +1,4 @@ -# $OpenBSD: krl.sh,v 1.12 2023/01/16 04:11:29 djm Exp $ +# $OpenBSD: krl.sh,v 1.13 2025/05/06 06:05:48 djm Exp $ # Placed in the Public Domain. tid="key revocation lists" @@ -11,7 +11,6 @@ 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 diff --git a/regress/limit-keytype.sh b/regress/limit-keytype.sh index 7127de0..2f5b63a 100644 --- a/regress/limit-keytype.sh +++ b/regress/limit-keytype.sh @@ -1,4 +1,4 @@ -# $OpenBSD: limit-keytype.sh,v 1.10 2021/02/25 03:27:34 djm Exp $ +# $OpenBSD: limit-keytype.sh,v 1.11 2025/05/06 06:05:48 djm Exp $ # Placed in the Public Domain. tid="restrict pubkey type" @@ -17,7 +17,6 @@ for t in $SSH_KEYTYPES ; do case "$t" in ssh-rsa) ktype2=rsa ;; ecdsa*) ktype3=ecdsa ;; # unused - ssh-dss) ktype4=dsa ;; sk-ssh-ed25519@openssh.com) ktype5=ed25519-sk ;; sk-ecdsa-sha2-nistp256@openssh.com) ktype6=ecdsa-sk ;; esac @@ -75,7 +74,6 @@ keytype() { case "$1" in ecdsa) printf "ecdsa-sha2-*" ;; ed25519) printf "ssh-ed25519" ;; - dsa) printf "ssh-dss" ;; rsa) printf "rsa-sha2-256,rsa-sha2-512,ssh-rsa" ;; sk-ecdsa) printf "sk-ecdsa-*" ;; sk-ssh-ed25519) printf "sk-ssh-ed25519-*" ;; @@ -123,7 +121,7 @@ if [ "$ktype1" != "$ktype2" ]; then fi ${SSH} $opts -i $OBJ/user_key2 proxy true || fatal "key2 failed" -# Allow only DSA in main config, Ed25519 for user. +# Allow only Ed25519 in main config, Ed25519 for user. verbose "match w/ matching" prepare_config "PubkeyAcceptedAlgorithms `keytype $ktype4`" \ "Match user $USER" "PubkeyAcceptedAlgorithms +`keytype $ktype1`" diff --git a/regress/misc/fuzz-harness/Makefile b/regress/misc/fuzz-harness/Makefile index 55dcc17..2963ba6 100644 --- a/regress/misc/fuzz-harness/Makefile +++ b/regress/misc/fuzz-harness/Makefile @@ -1,15 +1,16 @@ # NB. libssh and libopenbsd-compat should be built with the same sanitizer opts. -CC=clang-16 -CXX=clang++-16 +CC=clang-19 +CXX=clang++-19 FUZZ_FLAGS=-fsanitize=address,fuzzer -fno-omit-frame-pointer -FUZZ_LIBS=-L/usr/lib/llvm-16/lib -lFuzzer +FUZZ_LIBS=-L/usr/lib/llvm-19/lib -lFuzzer CFLAGS=-D_GNU_SOURCE=1 -O2 -g -Wall -Wextra -Wno-unused-parameter -Wno-exceptions -Wno-deprecated -I ../../.. CXXFLAGS=$(CFLAGS) $(FUZZ_FLAGS) LDFLAGS=-L ../../.. -L ../../../openbsd-compat -g -LIBS=-lssh -lopenbsd-compat -lmd -lcrypto -lfido2 -lcbor $(FUZZ_LIBS) +COMMON_OBJS=../../../ssh-pkcs11-client.o +LIBS=$(COMMON_OBJS) -lssh -lopenbsd-compat -lmd -lcrypto -lfido2 -lcbor $(FUZZ_LIBS) SK_NULL_OBJS=ssh-sk-null.o -COMMON_DEPS=../../../libssh.a +COMMON_DEPS=../../../libssh.a $(COMMON_OBJS) TARGETS=pubkey_fuzz sig_fuzz authopt_fuzz authkeys_fuzz sshsig_fuzz \ sshsigopt_fuzz privkey_fuzz kex_fuzz agent_fuzz \ diff --git a/regress/misc/fuzz-harness/agent_fuzz_helper.c b/regress/misc/fuzz-harness/agent_fuzz_helper.c index 321343b..400b631 100644 --- a/regress/misc/fuzz-harness/agent_fuzz_helper.c +++ b/regress/misc/fuzz-harness/agent_fuzz_helper.c @@ -158,6 +158,7 @@ test_one(const uint8_t* s, size_t slen) SYSLOG_FACILITY_AUTH, 1); devnull = devnull_or_die(); allowed_providers = xstrdup(""); + websafe_allowlist = xstrdup("*"); setenv("DISPLAY", "", 1); /* ban askpass */ } @@ -174,10 +175,3 @@ test_one(const uint8_t* s, size_t slen) cleanup_idtab(); cleanup_sockettab(); } - -int -pkcs11_make_cert(const struct sshkey *priv, - const struct sshkey *certpub, struct sshkey **certprivp) -{ - return -1; /* XXX */ -} diff --git a/regress/misc/fuzz-harness/fixed-keys.h b/regress/misc/fuzz-harness/fixed-keys.h index c6e7c6c..61afa87 100644 --- a/regress/misc/fuzz-harness/fixed-keys.h +++ b/regress/misc/fuzz-harness/fixed-keys.h @@ -34,32 +34,6 @@ "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDf56l/5UYqgY9oBlet/pLRzK6ZCd12QYGdUVfQDl6HftG0u6DSpjm2HGwFRsYZWv2ZN3ZBfAu6MHBiDmXUw/8WaD7nfXZmDH2keZL6opQttqvSGU2Cm00Rv5o1R3ej2qDdpepebv5meMBXTl5/+bE1E3Zm+4STDtxGmlMlxsEj68XeVe4JedfaSUMj3kaXYBbdYdG1qeosdle4GSONEEMpzsxSr8Y/WGYuIB33l29Tt9mNGUgSw/zjMYQjUVvQv+SY8dw62JV8d+3wK2YL2/r73gms6I8EE1JxX53KuAAY+x0p2v/W8ilCYI2Ijyzc8KIPwntmIFpibQjx+rkb+qdT" #define CERT_RSA \ "ssh-rsa-cert-v01@openssh.com AAAAHHNzaC1yc2EtY2VydC12MDFAb3BlbnNzaC5jb20AAAAg89JX6OBMYDSxER8fnU5y8xxeMCHR/hI0uVqdEhNyCpcAAAADAQABAAABAQDf56l/5UYqgY9oBlet/pLRzK6ZCd12QYGdUVfQDl6HftG0u6DSpjm2HGwFRsYZWv2ZN3ZBfAu6MHBiDmXUw/8WaD7nfXZmDH2keZL6opQttqvSGU2Cm00Rv5o1R3ej2qDdpepebv5meMBXTl5/+bE1E3Zm+4STDtxGmlMlxsEj68XeVe4JedfaSUMj3kaXYBbdYdG1qeosdle4GSONEEMpzsxSr8Y/WGYuIB33l29Tt9mNGUgSw/zjMYQjUVvQv+SY8dw62JV8d+3wK2YL2/r73gms6I8EE1JxX53KuAAY+x0p2v/W8ilCYI2Ijyzc8KIPwntmIFpibQjx+rkb+qdTAAAAAAAAA+0AAAABAAAAB3VseXNzZXMAAAAXAAAAB3VseXNzZXMAAAAIb2R5c3NldXMAAAAAAAAAAP//////////AAAAAAAAAIIAAAAVcGVybWl0LVgxMS1mb3J3YXJkaW5nAAAAAAAAABdwZXJtaXQtYWdlbnQtZm9yd2FyZGluZwAAAAAAAAAWcGVybWl0LXBvcnQtZm9yd2FyZGluZwAAAAAAAAAKcGVybWl0LXB0eQAAAAAAAAAOcGVybWl0LXVzZXItcmMAAAAAAAAAAAAAADMAAAALc3NoLWVkMjU1MTkAAAAgM9BeYRUxUuZ4VHJp8oxVaA8OS/z+5EFPCZwQNq1nMwMAAABTAAAAC3NzaC1lZDI1NTE5AAAAQGCDA6PWw4x9bHQl0w7NqifHepumqD3dmyMx+hZGuPRon+TsyCjfytu7hWmV7l9XUF0fPQNFQ7FGat5e+7YUNgE= id_rsa.pub" -#define PRIV_DSA \ -"-----BEGIN OPENSSH PRIVATE KEY-----\n"\ -"b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABsgAAAAdzc2gtZH\n"\ -"NzAAAAgQCsGTfjpQ465EOkfQXJM9BOvfRQE0fqlykAls+ncz+T7hrbeScRu8xpwzsznJNm\n"\ -"xlW8o6cUDiHmBJ5OHgamUC9N7YJeU/6fnOAZifgN8mqK6k8pKHuje8ANOiYgHLl0yiASQA\n"\ -"3//qMyzZ+W/hemoLSmLAbEqlfWVeyYx+wta1Vm+QAAABUAvWyehvUvdHvQxavYgS5p0t5Q\n"\ -"d7UAAACBAIRA9Yy+f4Kzqpv/qICPO3zk42UuP7WAhSW2nCbQdLlCiSTxcjKgcvXNRckwJP\n"\ -"44JjSHOtJy/AMtJrPIbLYG6KuWTdBlEHFiG6DafvLG+qPMSL2bPjXTOhuOMbCHIZ+5WBkW\n"\ -"THeG/Nv11iI01Of9V6tXkig23K370flkRkXFi9MdAAAAgCt6YUcQkNwG7B/e5M1FZsLP9O\n"\ -"kVB3BwLAOjmWdHpyhu3HpwSJa3XLEvhXN0i6IVI2KgPo/2GtYA6rHt14L+6u1pmhh8sAvQ\n"\ -"ksp3qZB+xh/NP+hBqf0sbHX0yYbzKOvI5SCc/kKK6yagcBZOsubM/KC8TxyVgmD5c6WzYs\n"\ -"h5TEpvAAAB2PHjRbbx40W2AAAAB3NzaC1kc3MAAACBAKwZN+OlDjrkQ6R9Bckz0E699FAT\n"\ -"R+qXKQCWz6dzP5PuGtt5JxG7zGnDOzOck2bGVbyjpxQOIeYEnk4eBqZQL03tgl5T/p+c4B\n"\ -"mJ+A3yaorqTykoe6N7wA06JiAcuXTKIBJADf/+ozLNn5b+F6agtKYsBsSqV9ZV7JjH7C1r\n"\ -"VWb5AAAAFQC9bJ6G9S90e9DFq9iBLmnS3lB3tQAAAIEAhED1jL5/grOqm/+ogI87fOTjZS\n"\ -"4/tYCFJbacJtB0uUKJJPFyMqBy9c1FyTAk/jgmNIc60nL8Ay0ms8hstgboq5ZN0GUQcWIb\n"\ -"oNp+8sb6o8xIvZs+NdM6G44xsIchn7lYGRZMd4b82/XWIjTU5/1Xq1eSKDbcrfvR+WRGRc\n"\ -"WL0x0AAACAK3phRxCQ3AbsH97kzUVmws/06RUHcHAsA6OZZ0enKG7cenBIlrdcsS+Fc3SL\n"\ -"ohUjYqA+j/Ya1gDqse3Xgv7q7WmaGHywC9CSynepkH7GH80/6EGp/SxsdfTJhvMo68jlIJ\n"\ -"z+QorrJqBwFk6y5sz8oLxPHJWCYPlzpbNiyHlMSm8AAAAUUA+OGldMi76ClO/sstpdbBUE\n"\ -"lq8AAAAAAQI=\n"\ -"-----END OPENSSH PRIVATE KEY-----\n" -#define PUB_DSA \ -"ssh-dss AAAAB3NzaC1kc3MAAACBAKwZN+OlDjrkQ6R9Bckz0E699FATR+qXKQCWz6dzP5PuGtt5JxG7zGnDOzOck2bGVbyjpxQOIeYEnk4eBqZQL03tgl5T/p+c4BmJ+A3yaorqTykoe6N7wA06JiAcuXTKIBJADf/+ozLNn5b+F6agtKYsBsSqV9ZV7JjH7C1rVWb5AAAAFQC9bJ6G9S90e9DFq9iBLmnS3lB3tQAAAIEAhED1jL5/grOqm/+ogI87fOTjZS4/tYCFJbacJtB0uUKJJPFyMqBy9c1FyTAk/jgmNIc60nL8Ay0ms8hstgboq5ZN0GUQcWIboNp+8sb6o8xIvZs+NdM6G44xsIchn7lYGRZMd4b82/XWIjTU5/1Xq1eSKDbcrfvR+WRGRcWL0x0AAACAK3phRxCQ3AbsH97kzUVmws/06RUHcHAsA6OZZ0enKG7cenBIlrdcsS+Fc3SLohUjYqA+j/Ya1gDqse3Xgv7q7WmaGHywC9CSynepkH7GH80/6EGp/SxsdfTJhvMo68jlIJz+QorrJqBwFk6y5sz8oLxPHJWCYPlzpbNiyHlMSm8=" -#define CERT_DSA \ -"ssh-dss-cert-v01@openssh.com AAAAHHNzaC1kc3MtY2VydC12MDFAb3BlbnNzaC5jb20AAAAguF716Yub+vVKNlONKLsfxGYWkRe/PyjfYdGRTsFaDvAAAACBAKwZN+OlDjrkQ6R9Bckz0E699FATR+qXKQCWz6dzP5PuGtt5JxG7zGnDOzOck2bGVbyjpxQOIeYEnk4eBqZQL03tgl5T/p+c4BmJ+A3yaorqTykoe6N7wA06JiAcuXTKIBJADf/+ozLNn5b+F6agtKYsBsSqV9ZV7JjH7C1rVWb5AAAAFQC9bJ6G9S90e9DFq9iBLmnS3lB3tQAAAIEAhED1jL5/grOqm/+ogI87fOTjZS4/tYCFJbacJtB0uUKJJPFyMqBy9c1FyTAk/jgmNIc60nL8Ay0ms8hstgboq5ZN0GUQcWIboNp+8sb6o8xIvZs+NdM6G44xsIchn7lYGRZMd4b82/XWIjTU5/1Xq1eSKDbcrfvR+WRGRcWL0x0AAACAK3phRxCQ3AbsH97kzUVmws/06RUHcHAsA6OZZ0enKG7cenBIlrdcsS+Fc3SLohUjYqA+j/Ya1gDqse3Xgv7q7WmaGHywC9CSynepkH7GH80/6EGp/SxsdfTJhvMo68jlIJz+QorrJqBwFk6y5sz8oLxPHJWCYPlzpbNiyHlMSm8AAAAAAAAD6AAAAAEAAAAHdWx5c3NlcwAAABcAAAAHdWx5c3NlcwAAAAhvZHlzc2V1cwAAAAAAAAAA//////////8AAAAAAAAAggAAABVwZXJtaXQtWDExLWZvcndhcmRpbmcAAAAAAAAAF3Blcm1pdC1hZ2VudC1mb3J3YXJkaW5nAAAAAAAAABZwZXJtaXQtcG9ydC1mb3J3YXJkaW5nAAAAAAAAAApwZXJtaXQtcHR5AAAAAAAAAA5wZXJtaXQtdXNlci1yYwAAAAAAAAAAAAAAMwAAAAtzc2gtZWQyNTUxOQAAACAz0F5hFTFS5nhUcmnyjFVoDw5L/P7kQU8JnBA2rWczAwAAAFMAAAALc3NoLWVkMjU1MTkAAABAjMQEZcbdUYJBjIC4GxByFDOb8tv71vDZdx7irHwaqIjx5rzpJUuOV1r8ZO4kY+Yaiun1yrWj2QYkfJrHBvD1DA== id_dsa.pub" #define PRIV_ECDSA \ "-----BEGIN OPENSSH PRIVATE KEY-----\n"\ "b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAaAAAABNlY2RzYS\n"\ diff --git a/regress/misc/fuzz-harness/testdata/create-agent-corpus.sh b/regress/misc/fuzz-harness/testdata/create-agent-corpus.sh index 1043b9f..842b8c4 100755 --- a/regress/misc/fuzz-harness/testdata/create-agent-corpus.sh +++ b/regress/misc/fuzz-harness/testdata/create-agent-corpus.sh @@ -14,7 +14,7 @@ sleep 1 AGENT_PID=$! trap "kill $AGENT_PID" EXIT -PRIV="id_dsa id_ecdsa id_ecdsa_sk id_ed25519 id_ed25519_sk id_rsa" +PRIV="id_ecdsa id_ecdsa_sk id_ed25519 id_ed25519_sk id_rsa" # add keys ssh-add $PRIV diff --git a/regress/misc/fuzz-harness/testdata/id_dsa-cert.pub b/regress/misc/fuzz-harness/testdata/id_dsa-cert.pub deleted file mode 100644 index 3afb87f..0000000 --- a/regress/misc/fuzz-harness/testdata/id_dsa-cert.pub +++ /dev/null @@ -1 +0,0 @@ -ssh-dss-cert-v01@openssh.com AAAAHHNzaC1kc3MtY2VydC12MDFAb3BlbnNzaC5jb20AAAAguF716Yub+vVKNlONKLsfxGYWkRe/PyjfYdGRTsFaDvAAAACBAKwZN+OlDjrkQ6R9Bckz0E699FATR+qXKQCWz6dzP5PuGtt5JxG7zGnDOzOck2bGVbyjpxQOIeYEnk4eBqZQL03tgl5T/p+c4BmJ+A3yaorqTykoe6N7wA06JiAcuXTKIBJADf/+ozLNn5b+F6agtKYsBsSqV9ZV7JjH7C1rVWb5AAAAFQC9bJ6G9S90e9DFq9iBLmnS3lB3tQAAAIEAhED1jL5/grOqm/+ogI87fOTjZS4/tYCFJbacJtB0uUKJJPFyMqBy9c1FyTAk/jgmNIc60nL8Ay0ms8hstgboq5ZN0GUQcWIboNp+8sb6o8xIvZs+NdM6G44xsIchn7lYGRZMd4b82/XWIjTU5/1Xq1eSKDbcrfvR+WRGRcWL0x0AAACAK3phRxCQ3AbsH97kzUVmws/06RUHcHAsA6OZZ0enKG7cenBIlrdcsS+Fc3SLohUjYqA+j/Ya1gDqse3Xgv7q7WmaGHywC9CSynepkH7GH80/6EGp/SxsdfTJhvMo68jlIJz+QorrJqBwFk6y5sz8oLxPHJWCYPlzpbNiyHlMSm8AAAAAAAAD6AAAAAEAAAAHdWx5c3NlcwAAABcAAAAHdWx5c3NlcwAAAAhvZHlzc2V1cwAAAAAAAAAA//////////8AAAAAAAAAggAAABVwZXJtaXQtWDExLWZvcndhcmRpbmcAAAAAAAAAF3Blcm1pdC1hZ2VudC1mb3J3YXJkaW5nAAAAAAAAABZwZXJtaXQtcG9ydC1mb3J3YXJkaW5nAAAAAAAAAApwZXJtaXQtcHR5AAAAAAAAAA5wZXJtaXQtdXNlci1yYwAAAAAAAAAAAAAAMwAAAAtzc2gtZWQyNTUxOQAAACAz0F5hFTFS5nhUcmnyjFVoDw5L/P7kQU8JnBA2rWczAwAAAFMAAAALc3NoLWVkMjU1MTkAAABAjMQEZcbdUYJBjIC4GxByFDOb8tv71vDZdx7irHwaqIjx5rzpJUuOV1r8ZO4kY+Yaiun1yrWj2QYkfJrHBvD1DA== id_dsa.pub diff --git a/regress/misc/sk-dummy/sk-dummy.c b/regress/misc/sk-dummy/sk-dummy.c index 347b212..4c96e88 100644 --- a/regress/misc/sk-dummy/sk-dummy.c +++ b/regress/misc/sk-dummy/sk-dummy.c @@ -1,3 +1,4 @@ +/* $OpenBSD: sk-dummy.c,v 1.16 2025/06/17 01:24:32 djm Exp $ */ /* * Copyright (c) 2019 Markus Friedl * @@ -16,9 +17,7 @@ #include "includes.h" -#ifdef HAVE_STDINT_H #include -#endif #include #include #include @@ -263,7 +262,7 @@ sk_enroll(uint32_t alg, const uint8_t *challenge, size_t challenge_len, break; default: skdebug(__func__, "unsupported key type %d", alg); - return -1; + goto out; } /* Have to return something here */ if ((response->signature = calloc(1, 1)) == NULL) { @@ -520,7 +519,7 @@ sk_sign(uint32_t alg, const uint8_t *data, size_t datalen, break; default: skdebug(__func__, "unsupported key type %d", alg); - return -1; + goto out; } *sign_response = response; response = NULL; diff --git a/regress/misc/ssh-verify-attestation/Makefile b/regress/misc/ssh-verify-attestation/Makefile new file mode 100644 index 0000000..06fb8aa --- /dev/null +++ b/regress/misc/ssh-verify-attestation/Makefile @@ -0,0 +1,79 @@ +# $OpenBSD: Makefile,v 1.2 2025/05/06 06:05:48 djm Exp $ + +.include +.include + +PROG= ssh-verify-attestation +NOMAN= + +SSHREL=../../../../../usr.bin/ssh +.PATH: ${.CURDIR}/${SSHREL} + +SRCS=ssh-verify-attestation.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-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 +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 + +OPENSSL?= yes + +.if (${OPENSSL:L} == "yes") +CFLAGS+= -DWITH_OPENSSL +.endif + +# enable warnings +WARNINGS=Yes + +DEBUG=-g +CFLAGS+= -fstack-protector-all +CDIAGFLAGS= -Wall +CDIAGFLAGS+= -Wextra +CDIAGFLAGS+= -Werror +CDIAGFLAGS+= -Wchar-subscripts +CDIAGFLAGS+= -Wcomment +CDIAGFLAGS+= -Wformat +CDIAGFLAGS+= -Wformat-security +CDIAGFLAGS+= -Wimplicit +CDIAGFLAGS+= -Winline +CDIAGFLAGS+= -Wmissing-declarations +CDIAGFLAGS+= -Wmissing-prototypes +CDIAGFLAGS+= -Wparentheses +CDIAGFLAGS+= -Wpointer-arith +CDIAGFLAGS+= -Wreturn-type +CDIAGFLAGS+= -Wshadow +CDIAGFLAGS+= -Wsign-compare +CDIAGFLAGS+= -Wstrict-aliasing +CDIAGFLAGS+= -Wstrict-prototypes +CDIAGFLAGS+= -Wswitch +CDIAGFLAGS+= -Wtrigraphs +CDIAGFLAGS+= -Wuninitialized +CDIAGFLAGS+= -Wunused +CDIAGFLAGS+= -Wno-unused-parameter +.if ${COMPILER_VERSION:L} != "gcc3" +CDIAGFLAGS+= -Wold-style-definition +.endif + +CFLAGS+=-I${.CURDIR}/${SSHREL} + +.if (${OPENSSL:L} == "yes") +LDADD+= -lcrypto +DPADD+= ${LIBCRYPTO} +.endif + +LDADD+= -lfido2 -lcbor +DPADD+= ${LIBFIDO2} ${LIBCBOR} + +LDADD+= -lutil +DPADD+= ${LIBUTIL} + +.include + diff --git a/regress/misc/ssh-verify-attestation/ssh-verify-attestation.c b/regress/misc/ssh-verify-attestation/ssh-verify-attestation.c new file mode 100644 index 0000000..da7f5a2 --- /dev/null +++ b/regress/misc/ssh-verify-attestation/ssh-verify-attestation.c @@ -0,0 +1,434 @@ +/* $OpenBSD: ssh-verify-attestation.c,v 1.3 2025/05/12 05:42:02 tb Exp $ */ +/* + * Copyright (c) 2022-2024 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. + */ + +/* + * This is a small program to verify FIDO attestation objects that + * ssh-keygen(1) can record when enrolling a FIDO key. It requires that + * the attestation object and challenge used when creating the key be + * recorded. + * + * Example usage: + * + * $ # Generate a random challenge. + * $ dd if=/dev/urandom of=key_ecdsa_sk.challenge bs=32 count=1 + * $ # Generate a key, record the attestation blob. + * $ ssh-keygen -f key_ecdsa_sk -t ecdsa-sk \ + * -Ochallenge=key_ecdsa_sk.challenge \ + * -Owrite-attestation=key_ecdsa_sk.attest -N '' + * $ # Validate the challenge (-A = print attestation CA cert) + * $ ./obj/ssh-verify-attestation -A key_ecdsa_sk key_ecdsa_sk.challenge \ + * key_ecdsa_sk.attest + * + * Limitations/TODO: + * + * 1) It doesn't automatically detect the attestation statement format. It + * assumes the "packed" format used by FIDO2 keys. If that doesn't work, + * then try using the -U option to select the "fido-u2f" format. + * 2) It makes assumptions about RK, UV, etc status of the key/cred. + * 3) Probably bugs. + * + * Thanks to Markus Friedl and Pedro Martelletto for help getting this + * working. + */ + +#include "includes.h" + +#include +#include +#include +#include +#include +#include + +#include "xmalloc.h" +#include "log.h" +#include "sshbuf.h" +#include "sshkey.h" +#include "authfile.h" +#include "ssherr.h" +#include "misc.h" +#include "digest.h" +#include "crypto_api.h" + +#include +#include +#include +#include +#include +#include +#include "openbsd-compat/openssl-compat.h" + +extern char *__progname; + +#define ATTEST_MAGIC "ssh-sk-attest-v01" + +static int +prepare_fido_cred(fido_cred_t *cred, int credtype, const char *attfmt, + const char *rp_id, struct sshbuf *b, const struct sshbuf *challenge, + struct sshbuf **attestation_certp) +{ + struct sshbuf *attestation_cert = NULL, *sig = NULL, *authdata = NULL; + char *magic = NULL; + int r = SSH_ERR_INTERNAL_ERROR; + + *attestation_certp = NULL; + + /* Make sure it's the format we're expecting */ + if ((r = sshbuf_get_cstring(b, &magic, NULL)) != 0) { + error_fr(r, "parse header"); + goto out; + } + if (strcmp(magic, ATTEST_MAGIC) != 0) { + error_f("unsupported format"); + r = SSH_ERR_INVALID_FORMAT; + goto out; + } + /* Parse the remaining fields */ + if ((r = sshbuf_froms(b, &attestation_cert)) != 0 || + (r = sshbuf_froms(b, &sig)) != 0 || + (r = sshbuf_froms(b, &authdata)) != 0 || + (r = sshbuf_get_u32(b, NULL)) != 0 || /* reserved flags */ + (r = sshbuf_get_string_direct(b, NULL, NULL)) != 0) { /* reserved */ + error_fr(r, "parse body"); + goto out; + } + debug3_f("attestation cert len=%zu, sig len=%zu, " + "authdata len=%zu challenge len=%zu", sshbuf_len(attestation_cert), + sshbuf_len(sig), sshbuf_len(authdata), sshbuf_len(challenge)); + + fido_cred_set_type(cred, credtype); + fido_cred_set_fmt(cred, attfmt); + fido_cred_set_clientdata(cred, sshbuf_ptr(challenge), + sshbuf_len(challenge)); + fido_cred_set_rp(cred, rp_id, NULL); + fido_cred_set_authdata(cred, sshbuf_ptr(authdata), + sshbuf_len(authdata)); + /* XXX set_extensions, set_rk, set_uv */ + fido_cred_set_x509(cred, sshbuf_ptr(attestation_cert), + sshbuf_len(attestation_cert)); + fido_cred_set_sig(cred, sshbuf_ptr(sig), sshbuf_len(sig)); + + /* success */ + *attestation_certp = attestation_cert; + attestation_cert = NULL; + r = 0; + out: + free(magic); + sshbuf_free(attestation_cert); + sshbuf_free(sig); + sshbuf_free(authdata); + return r; +} + +static uint8_t * +get_pubkey_from_cred_ecdsa(const fido_cred_t *cred, size_t *pubkey_len) +{ + const uint8_t *ptr; + uint8_t *pubkey = NULL, *ret = NULL; + BIGNUM *x = NULL, *y = NULL; + EC_POINT *q = NULL; + EC_GROUP *g = NULL; + + if ((x = BN_new()) == NULL || + (y = BN_new()) == NULL || + (g = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1)) == NULL || + (q = EC_POINT_new(g)) == NULL) { + error_f("libcrypto setup failed"); + goto out; + } + if ((ptr = fido_cred_pubkey_ptr(cred)) == NULL) { + error_f("fido_cred_pubkey_ptr failed"); + goto out; + } + if (fido_cred_pubkey_len(cred) != 64) { + error_f("bad fido_cred_pubkey_len %zu", + fido_cred_pubkey_len(cred)); + goto out; + } + + if (BN_bin2bn(ptr, 32, x) == NULL || + BN_bin2bn(ptr + 32, 32, y) == NULL) { + error_f("BN_bin2bn failed"); + goto out; + } + if (EC_POINT_set_affine_coordinates(g, q, x, y, NULL) != 1) { + error_f("EC_POINT_set_affine_coordinates failed"); + goto out; + } + *pubkey_len = EC_POINT_point2oct(g, q, + POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL); + if (*pubkey_len == 0 || *pubkey_len > 2048) { + error_f("bad pubkey length %zu", *pubkey_len); + goto out; + } + if ((pubkey = malloc(*pubkey_len)) == NULL) { + error_f("malloc pubkey failed"); + goto out; + } + if (EC_POINT_point2oct(g, q, POINT_CONVERSION_UNCOMPRESSED, + pubkey, *pubkey_len, NULL) == 0) { + error_f("EC_POINT_point2oct failed"); + goto out; + } + /* success */ + ret = pubkey; + pubkey = NULL; + out: + free(pubkey); + EC_POINT_free(q); + EC_GROUP_free(g); + BN_clear_free(x); + BN_clear_free(y); + return ret; +} + +/* copied from sshsk_ecdsa_assemble() */ +static int +cred_matches_key_ecdsa(const fido_cred_t *cred, const struct sshkey *k) +{ + struct sshkey *key = NULL; + struct sshbuf *b = NULL; + EC_KEY *ec = NULL; + uint8_t *pubkey = NULL; + size_t pubkey_len; + int r; + + if ((key = sshkey_new(KEY_ECDSA_SK)) == NULL) { + error_f("sshkey_new failed"); + r = SSH_ERR_ALLOC_FAIL; + goto out; + } + key->ecdsa_nid = NID_X9_62_prime256v1; + if ((key->pkey = EVP_PKEY_new()) == NULL || + (ec = EC_KEY_new_by_curve_name(key->ecdsa_nid)) == NULL || + (b = sshbuf_new()) == NULL) { + error_f("allocation failed"); + r = SSH_ERR_ALLOC_FAIL; + goto out; + } + if ((pubkey = get_pubkey_from_cred_ecdsa(cred, &pubkey_len)) == NULL) { + error_f("get_pubkey_from_cred_ecdsa failed"); + r = SSH_ERR_INVALID_FORMAT; + goto out; + } + if ((r = sshbuf_put_string(b, pubkey, pubkey_len)) != 0) { + error_fr(r, "sshbuf_put_string"); + goto out; + } + if ((r = sshbuf_get_eckey(b, ec)) != 0) { + error_fr(r, "parse"); + r = SSH_ERR_INVALID_FORMAT; + goto out; + } + if (sshkey_ec_validate_public(EC_KEY_get0_group(ec), + EC_KEY_get0_public_key(ec)) != 0) { + error("Authenticator returned invalid ECDSA key"); + r = SSH_ERR_KEY_INVALID_EC_VALUE; + goto out; + } + if (EVP_PKEY_set1_EC_KEY(key->pkey, ec) != 1) { + /* XXX assume it is a allocation error */ + error_f("allocation failed"); + r = SSH_ERR_ALLOC_FAIL; + goto out; + } + key->sk_application = xstrdup(k->sk_application); /* XXX */ + if (!sshkey_equal_public(key, k)) { + error("sshkey_equal_public failed"); + r = SSH_ERR_INVALID_ARGUMENT; + goto out; + } + r = 0; /* success */ + out: + EC_KEY_free(ec); + free(pubkey); + sshkey_free(key); + sshbuf_free(b); + return r; +} + + +/* copied from sshsk_ed25519_assemble() */ +static int +cred_matches_key_ed25519(const fido_cred_t *cred, const struct sshkey *k) +{ + struct sshkey *key = NULL; + const uint8_t *ptr; + int r = -1; + + if ((ptr = fido_cred_pubkey_ptr(cred)) == NULL) { + error_f("fido_cred_pubkey_ptr failed"); + goto out; + } + if (fido_cred_pubkey_len(cred) != ED25519_PK_SZ) { + error_f("bad fido_cred_pubkey_len %zu", + fido_cred_pubkey_len(cred)); + goto out; + } + + if ((key = sshkey_new(KEY_ED25519_SK)) == NULL) { + error_f("sshkey_new failed"); + r = SSH_ERR_ALLOC_FAIL; + goto out; + } + if ((key->ed25519_pk = malloc(ED25519_PK_SZ)) == NULL) { + error_f("malloc failed"); + r = SSH_ERR_ALLOC_FAIL; + goto out; + } + memcpy(key->ed25519_pk, ptr, ED25519_PK_SZ); + key->sk_application = xstrdup(k->sk_application); /* XXX */ + if (!sshkey_equal_public(key, k)) { + error("sshkey_equal_public failed"); + r = SSH_ERR_INVALID_ARGUMENT; + goto out; + } + r = 0; /* success */ + out: + sshkey_free(key); + return r; +} + +static int +cred_matches_key(const fido_cred_t *cred, const struct sshkey *k) +{ + switch (sshkey_type_plain(k->type)) { + case KEY_ECDSA_SK: + switch (k->ecdsa_nid) { + case NID_X9_62_prime256v1: + return cred_matches_key_ecdsa(cred, k); + break; + default: + fatal("Unsupported ECDSA key size"); + } + break; + case KEY_ED25519_SK: + return cred_matches_key_ed25519(cred, k); + default: + error_f("key type %s not supported", sshkey_type(k)); + return -1; + } +} + +int +main(int argc, char **argv) +{ + LogLevel log_level = SYSLOG_LEVEL_INFO; + int r, ch, credtype = -1; + struct sshkey *k = NULL; + struct sshbuf *attestation = NULL, *challenge = NULL; + struct sshbuf *attestation_cert = NULL; + char *fp; + const char *attfmt = "packed", *style = NULL; + fido_cred_t *cred = NULL; + int write_attestation_cert = 0; + extern int optind; + /* extern char *optarg; */ + + ERR_load_crypto_strings(); + + sanitise_stdfd(); + log_init(__progname, log_level, SYSLOG_FACILITY_AUTH, 1); + + while ((ch = getopt(argc, argv, "UAv")) != -1) { + switch (ch) { + case 'U': + attfmt = "fido-u2f"; + break; + case 'A': + write_attestation_cert = 1; + break; + case 'v': + if (log_level == SYSLOG_LEVEL_ERROR) + log_level = SYSLOG_LEVEL_DEBUG1; + else if (log_level < SYSLOG_LEVEL_DEBUG3) + log_level++; + break; + default: + goto usage; + } + } + log_init(__progname, log_level, SYSLOG_FACILITY_AUTH, 1); + argv += optind; + argc -= optind; + + if (argc < 3) { + usage: + fprintf(stderr, "usage: %s [-vAU] " + "pubkey challenge attestation-blob\n", __progname); + exit(1); + } + if ((r = sshkey_load_public(argv[0], &k, NULL)) != 0) + fatal_r(r, "load key %s", argv[0]); + if ((fp = sshkey_fingerprint(k, SSH_FP_HASH_DEFAULT, + SSH_FP_DEFAULT)) == NULL) + fatal("sshkey_fingerprint failed"); + debug2("key %s: %s %s", argv[2], sshkey_type(k), fp); + free(fp); + if ((r = sshbuf_load_file(argv[1], &challenge)) != 0) + fatal_r(r, "load challenge %s", argv[1]); + if ((r = sshbuf_load_file(argv[2], &attestation)) != 0) + fatal_r(r, "load attestation %s", argv[2]); + if ((cred = fido_cred_new()) == NULL) + fatal("fido_cred_new failed"); + + switch (sshkey_type_plain(k->type)) { + case KEY_ECDSA_SK: + switch (k->ecdsa_nid) { + case NID_X9_62_prime256v1: + credtype = COSE_ES256; + break; + default: + fatal("Unsupported ECDSA key size"); + } + break; + case KEY_ED25519_SK: + credtype = COSE_EDDSA; + break; + default: + fatal("unsupported key type %s", sshkey_type(k)); + } + + if ((r = prepare_fido_cred(cred, credtype, attfmt, k->sk_application, + attestation, challenge, &attestation_cert)) != 0) + fatal_r(r, "prepare_fido_cred %s", argv[2]); + if (fido_cred_x5c_ptr(cred) != NULL) { + debug("basic attestation"); + if ((r = fido_cred_verify(cred)) != FIDO_OK) + fatal("basic attestation failed"); + style = "basic"; + } else { + debug("self attestation"); + if ((r = fido_cred_verify_self(cred)) != FIDO_OK) + fatal("self attestation failed"); + style = "self"; + } + if (cred_matches_key(cred, k) != 0) + fatal("cred authdata does not match key"); + + fido_cred_free(&cred); + + if (write_attestation_cert) { + PEM_write(stdout, "CERTIFICATE", NULL, + sshbuf_ptr(attestation_cert), sshbuf_len(attestation_cert)); + } + sshbuf_free(attestation_cert); + + logit("%s: verified %s attestation", argv[2], style); + + return (0); +} diff --git a/regress/modpipe.c b/regress/modpipe.c index 5f4824b..5ef2f12 100644 --- a/regress/modpipe.c +++ b/regress/modpipe.c @@ -14,7 +14,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $OpenBSD: modpipe.c,v 1.6 2013/11/21 03:16:47 djm Exp $ */ +/* $OpenBSD: modpipe.c,v 1.7 2025/10/03 01:03:45 dtucker Exp $ */ #include "includes.h" @@ -127,7 +127,7 @@ main(int argc, char **argv) } } for (o = 0; o < s; o += r) { - r = write(STDOUT_FILENO, buf, s - o); + r = write(STDOUT_FILENO, buf + o, s - o); if (r == 0) break; if (r < 0) { diff --git a/regress/netcat.c b/regress/netcat.c index 20ec3f5..c621117 100644 --- a/regress/netcat.c +++ b/regress/netcat.c @@ -55,13 +55,7 @@ #include #include "atomicio.h" -#ifdef HAVE_POLL_H #include -#else -# ifdef HAVE_SYS_POLL_H -# include -# endif -#endif #ifdef HAVE_ERR_H # include #endif @@ -185,6 +179,8 @@ main(int argc, char *argv[]) socksv = -1; /* HTTP proxy CONNECT */ else if (strcmp(optarg, "4") == 0) socksv = 4; /* SOCKS v.4 */ + else if (strcasecmp(optarg, "4A") == 0) + socksv = 44; /* SOCKS v.4A */ else if (strcmp(optarg, "5") == 0) socksv = 5; /* SOCKS v.5 */ else @@ -1138,7 +1134,7 @@ build_ports(char *p) char *c; for (x = 0; x <= (hi - lo); x++) { - y = (arc4random() & 0xFFFF) % (hi - lo); + y = arc4random_uniform(hi - lo); c = portlist[x]; portlist[x] = portlist[y]; portlist[y] = c; @@ -1586,19 +1582,33 @@ socks_connect(const char *host, const char *port, default: errx(1, "connection failed, unsupported address type"); } - } else if (socksv == 4) { - /* This will exit on lookup failure */ - decode_addrport(host, port, (struct sockaddr *)&addr, - sizeof(addr), 1, 0); + } else if (socksv == 4 || socksv == 44) { + if (socksv == 4) { + /* This will exit on lookup failure */ + decode_addrport(host, port, (struct sockaddr *)&addr, + sizeof(addr), 1, 0); + } /* Version 4 */ buf[0] = SOCKS_V4; buf[1] = SOCKS_CONNECT; /* connect */ memcpy(buf + 2, &in4->sin_port, sizeof in4->sin_port); - memcpy(buf + 4, &in4->sin_addr, sizeof in4->sin_addr); + if (socksv == 4) { + memcpy(buf + 4, &in4->sin_addr, sizeof in4->sin_addr); + } else { + /* SOCKS4A uses addr of 0.0.0.x, and hostname later */ + buf[4] = buf[5] = buf[6] = 0; + buf[7] = 1; + } buf[8] = 0; /* empty username */ wlen = 9; - + if (socksv == 44) { + /* SOCKS4A has nul-terminated hostname after user */ + if (strlcpy(buf + 9, host, + sizeof(buf) - 9) >= sizeof(buf) - 9) + errx(1, "hostname too big"); + wlen = 9 + strlen(host) + 1; + } cnt = atomicio(vwrite, proxyfd, buf, wlen); if (cnt != wlen) err(1, "write failed (%zu/%zu)", cnt, wlen); diff --git a/regress/password.sh b/regress/password.sh new file mode 100644 index 0000000..10f507e --- /dev/null +++ b/regress/password.sh @@ -0,0 +1,60 @@ +# $OpenBSD: password.sh,v 1.2 2025/06/29 08:20:21 dtucker Exp $ +# Placed in the Public Domain. +# +# This tests standard "password" authentication. It does not run by default, +# and needs to be enabled by putting the password of the user running the tests +# into ${OBJ}/password. Since this obviously puts the password at risk it is +# recommended to do this on a throwaway VM by setting a random password +# (and randomizing it again after the test, if you can't immediately dispose +# of the VM). + +tid="password" + +if [ -z "$SUDO" -o ! -f ${OBJ}/password ]; then + skip "Password auth requires SUDO and password file." +fi + +# Enable password auth +echo "PasswordAuthentication yes" >>sshd_proxy + +# Create askpass script to replay a series of password responses. +# Keep a counter of the number of times it has been called and +# reply with the next line of the replypass file. +cat >${OBJ}/replypass.sh <${OBJ}/replypass.N +EOD +chmod 700 ${OBJ}/replypass.sh + +SSH_ASKPASS=${OBJ}/replypass.sh +SSH_ASKPASS_REQUIRE=force +export SSH_ASKPASS SSH_ASKPASS_REQUIRE + +opts="-oPasswordAuthentication=yes -oPreferredAuthentications=password" +opts="-oBatchMode=no $opts" + +trace plain password +cat ${OBJ}/password >${OBJ}/replypass +echo 1 >${OBJ}/replypass.N +${SSH} $opts -F $OBJ/ssh_proxy somehost true +if [ $? -ne 0 ]; then + fail "ssh password failed" +fi + +trace 2-round password +(echo; cat ${OBJ}/password) >${OBJ}/replypass +echo 1 >${OBJ}/replypass.N +${SSH} $opts -F $OBJ/ssh_proxy somehost true +if [ $? -ne 0 ]; then + fail "ssh 2-round password failed" +fi + +trace empty password +echo >${OBJ}/replypass +echo 1 >${OBJ}/replypass.N +${SSH} $opts -F $OBJ/ssh_proxy somehost true +if [ $? -eq 0 ]; then + fail "ssh password failed" +fi diff --git a/regress/penalty-expire.sh b/regress/penalty-expire.sh index 4f0bbe6..27e36e3 100644 --- a/regress/penalty-expire.sh +++ b/regress/penalty-expire.sh @@ -1,4 +1,4 @@ -# $OpenBSD +# $OpenBSD: penalty-expire.sh,v 1.3 2025/05/22 04:34:18 bluhm Exp $ # Placed in the Public Domain. tid="penalties" diff --git a/regress/penalty.sh b/regress/penalty.sh index 8b83532..bf719dc 100644 --- a/regress/penalty.sh +++ b/regress/penalty.sh @@ -1,4 +1,4 @@ -# $OpenBSD +# $OpenBSD: penalty.sh,v 1.7 2025/05/22 04:34:18 bluhm Exp $ # Placed in the Public Domain. tid="penalties" diff --git a/regress/percent.sh b/regress/percent.sh index 354854f..c607c8d 100644 --- a/regress/percent.sh +++ b/regress/percent.sh @@ -1,4 +1,4 @@ -# $OpenBSD: percent.sh,v 1.17 2023/03/27 03:56:50 dtucker Exp $ +# $OpenBSD: percent.sh,v 1.22 2025/09/04 03:04:44 djm Exp $ # Placed in the Public Domain. tid="percent expansions" @@ -29,6 +29,23 @@ trial() somehost true got=`cat $OBJ/actual` ;; + user|user-l|user-at) + if [ "$arg" = '%r' ] || [ "$arg" = '%C' ]; then + # User does not support %r, ie itself or %C. Skip test. + got="$expect" + elif [ "$opt" = "user" ]; then + got=`${SSH} -F $OBJ/ssh_proxy -o $opt="$arg" -G \ + remuser@somehost | awk '$1=="'$opt'"{print $2}'` + elif [ "$opt" = "user-l" ]; then + # Also test ssh -l + got=`${SSH} -F $OBJ/ssh_proxy -l "$arg" -G \ + somehost | awk '$1=="'user'"{print $2}'` + elif [ "$opt" = "user-at" ]; then + # Also test user@host + got=`${SSH} -F $OBJ/ssh_proxy -G "$arg@somehost" | \ + awk '$1=="'user'"{print $2}'` + fi + ;; userknownhostsfile) # Move the userknownhosts file to what the expansion says, # make sure ssh works then put it back. @@ -51,6 +68,18 @@ trial() remuser@somehost | awk '$1=="'$opt'"{print $2" "$3}'` expect="/$expect /$expect" ;; + setenv) + # First make sure we don't expand variable names. + got=`${SSH} -F $OBJ/ssh_proxy -o $opt="$arg=TESTVAL" -G \ + remuser@somehost | awk '$1=="'$opt'"{print $2}'` + if [ "$got" != "$arg=TESTVAL" ]; then + fatal "incorrectly expanded setenv variable name" + fi + # Now check that the value expands as expected. + got=`${SSH} -F $OBJ/ssh_proxy -o $opt=TESTVAL="$arg" -G \ + remuser@somehost | awk '$1=="'$opt'"{print $2}'` + got=`echo "$got" | sed 's/^TESTVAL=//'` + ;; *) got=`${SSH} -F $OBJ/ssh_proxy -o $opt="$arg" -G \ remuser@somehost | awk '$1=="'$opt'"{print $2}'` @@ -62,7 +91,7 @@ trial() for i in matchexec localcommand remotecommand controlpath identityagent \ forwardagent localforward remoteforward revokedhostkeys \ - userknownhostsfile; do + user setenv userknownhostsfile; do verbose $tid $i percent case "$i" in localcommand|userknownhostsfile) @@ -77,7 +106,7 @@ for i in matchexec localcommand remotecommand controlpath identityagent \ fi # Matches implementation in readconf.c:ssh_connection_hash() if [ ! -z "${OPENSSL_BIN}" ]; then - HASH=`printf "${HOSTNAME}127.0.0.1${PORT}$REMUSER" | + HASH=`printf "${HOSTNAME}127.0.0.1${PORT}${REMUSER}" | $OPENSSL_BIN sha1 | cut -f2 -d' '` trial $i '%C' $HASH fi @@ -92,8 +121,9 @@ for i in matchexec localcommand remotecommand controlpath identityagent \ 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 + # containing %d for UserKnownHostsFile, and %r can't refer to itself. + if [ "$i" != "userknownhostsfile" ] && [ "$i" != "user" ] && \ + [ "$i" != "user-l" ] && [ "$i" != "user-at" ]; then trial $i '%d' $HOME in='%%/%i/%h/%d/%L/%l/%n/%p/%r/%u' out="%/$USERID/127.0.0.1/$HOME/$HOST/$HOSTNAME/somehost/$PORT/$REMUSER/$USER" @@ -107,11 +137,11 @@ done # Subset of above since we don't expand shell-style variables on anything that # runs a command because the shell will expand those. +FOO=bar +export FOO for i in controlpath identityagent forwardagent localforward remoteforward \ - userknownhostsfile; do + user setenv userknownhostsfile; do verbose $tid $i dollar - FOO=bar - export FOO trial $i '${FOO}' $FOO done @@ -122,3 +152,32 @@ for i in controlpath identityagent forwardagent; do trial $i '~' $HOME/ trial $i '~/.ssh' $HOME/.ssh done + +for i in user-l user-at; do + verbose $tid $i noexpand + trial $i '%u' '%u' +done + +# These should be not be expanded but rejected for containing shell characters. +verbose $tid user-l noenv +${SSH} -F $OBJ/ssh_proxy -l '${FOO}' -G somehost && fail "user-l expanded env" +verbose $tid user-at noenv +${SSH} -F $OBJ/ssh_proxy -G '${FOO}@somehost' && fail "user-at expanded env" + +FOO=`printf 'x\ay'` +export FOO + +# These should be rejected as containing control characters. +verbose $tid user-l badchar +${SSH} -F $OBJ/ssh_proxy -l "${FOO}" -G somehost && fail "user-l expanded env" +verbose $tid user-at badchar +${SSH} -F $OBJ/ssh_proxy -G "${FOO}@somehost" && fail "user-at expanded env" + +# Literal control characters in config is acceptable +verbose $tid user control-literal +trial user "$FOO" "$FOO" + +# Control characters expanded from config aren't. +${SSH} -F $OBJ/ssh_proxy -G '-oUser=${FOO}' somehost && \ + fail "user expanded ctrl" + diff --git a/regress/rekey.sh b/regress/rekey.sh index 3f5e1d5..8843030 100644 --- a/regress/rekey.sh +++ b/regress/rekey.sh @@ -11,7 +11,7 @@ cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak echo "Compression no" >> $OBJ/ssh_proxy echo "RekeyLimit 256k" >> $OBJ/ssh_proxy -echo "KexAlgorithms curve25519-sha256" >> ssh_proxy +echo "KexAlgorithms curve25519-sha256" >> $OBJ/ssh_proxy # Test rekeying based on data volume only. # Arguments: rekeylimit, kex method, optional remaining opts are passed to ssh. diff --git a/regress/servcfginclude.sh b/regress/servcfginclude.sh index 518a703..f67c3ca 100644 --- a/regress/servcfginclude.sh +++ b/regress/servcfginclude.sh @@ -4,14 +4,14 @@ tid="server config include" cat > $OBJ/sshd_config.i << _EOF HostKey $OBJ/host.ssh-ed25519 -Match host a +Match host=a Banner /aa Match host b Banner /bb Include $OBJ/sshd_config.i.* # comment -Match host c +Match host=c Include $OBJ/sshd_config.i.* # comment Banner /cc @@ -25,7 +25,7 @@ Match Host e Banner /ee Include $OBJ/sshd_config.i.* -Match Host f +Match Host=f Include $OBJ/sshd_config.i.* Banner /ff @@ -47,13 +47,13 @@ Match host b Match host c Banner /ccc -Match Host d +Match Host=d Banner /ddd Match Host e Banner /eee -Match Host f +Match Host=f Banner /fff _EOF @@ -61,13 +61,13 @@ cat > $OBJ/sshd_config.i.2 << _EOF Match host a Banner /aaaa -Match host b +Match host=b Banner /bbbb Match host c # comment Banner /cccc -Match Host d +Match Host=d Banner /dddd Match Host e diff --git a/regress/sftp-resume.sh b/regress/sftp-resume.sh new file mode 100644 index 0000000..f4fe8f9 --- /dev/null +++ b/regress/sftp-resume.sh @@ -0,0 +1,43 @@ +# $OpenBSD: sftp-resume.sh,v 1.2 2025/03/11 09:06:50 dtucker Exp $ +# Placed in the Public Domain. + +tid="sftp resume" + +CLIENT_LOG=${OBJ}/sftp.log + +# We test up to 1MB, ensure source data is large enough. +increase_datafile_size 1200 + +for cmd in put get; do + verbose "$tid: ${cmd}" + for size in 0 1 1k 1m size-1 same; do + trace "$tid: test ${cmd} ${size}" + rm -rf ${COPY}.1 ${COPY}.2 + cp ${DATA} ${COPY}.1 + + # Set up requested source and destination file sizes. + case "${size}" in + 0) touch ${COPY}.2 + ;; + size-1) dd if=${DATA} of=${COPY}.1 bs=1024 count=1 >/dev/null 2>&1 + dd if=${DATA} of=${COPY}.2 bs=1023 count=1 >/dev/null 2>&1 + ;; + same) cp ${DATA} ${COPY}.2 + ;; + 1m) dd if=${COPY}.1 of=${COPY}.2 bs=1k count=1k >/dev/null 2<&1 + ;; + *) dd if=${COPY}.1 of=${COPY}.2 bs=${size} count=1 >/dev/null 2>&1 + ;; + esac + + # Perform copy and check. + echo "${cmd} -a ${COPY}.1 ${COPY}.2" | \ + ${SFTP} -D ${SFTPSERVER} -vvv >${CLIENT_LOG} 2>&1 \ + || fail "${cmd} failed" + cmp ${COPY}.1 ${COPY}.2 || fail "corrupted copy after ${cmd} ${size}" + grep "reordered" ${CLIENT_LOG} >/dev/null && \ + fail "server reordered requests ${cmd} ${size}" + done +done + +rm -rf ${COPY}.1 ${COPY}.2 diff --git a/regress/ssh-com-client.sh b/regress/ssh-com-client.sh index e4f80cf..97b36b5 100644 --- a/regress/ssh-com-client.sh +++ b/regress/ssh-com-client.sh @@ -1,4 +1,4 @@ -# $OpenBSD: ssh-com-client.sh,v 1.7 2013/05/17 04:29:14 dtucker Exp $ +# $OpenBSD: ssh-com-client.sh,v 1.8 2025/05/06 06:05:48 djm Exp $ # Placed in the Public Domain. tid="connect with ssh.com client" @@ -28,7 +28,7 @@ VERSIONS=" # setup authorized keys SRC=`dirname ${SCRIPT}` -cp ${SRC}/dsa_ssh2.prv ${OBJ}/id.com +cp ${SRC}/rsa_ssh2.prv ${OBJ}/id.com chmod 600 ${OBJ}/id.com ${SSHKEYGEN} -i -f ${OBJ}/id.com > $OBJ/id.openssh chmod 600 ${OBJ}/id.openssh @@ -36,8 +36,8 @@ ${SSHKEYGEN} -y -f ${OBJ}/id.openssh > $OBJ/authorized_keys_$USER ${SSHKEYGEN} -e -f ${OBJ}/id.openssh > $OBJ/id.com.pub echo IdKey ${OBJ}/id.com > ${OBJ}/id.list -# we need a DSA host key -t=dsa +# we need a RSA host key +t=rsa rm -f ${OBJ}/$t ${OBJ}/$t.pub ${SSHKEYGEN} -q -N '' -t $t -f ${OBJ}/$t $SUDO cp $OBJ/$t $OBJ/host.$t @@ -47,7 +47,6 @@ echo HostKey $OBJ/host.$t >> $OBJ/sshd_config mkdir -p ${OBJ}/${USER}/hostkeys HK=${OBJ}/${USER}/hostkeys/key_${PORT}_127.0.0.1 ${SSHKEYGEN} -e -f ${OBJ}/rsa.pub > ${HK}.ssh-rsa.pub -${SSHKEYGEN} -e -f ${OBJ}/dsa.pub > ${HK}.ssh-dss.pub cat > ${OBJ}/ssh2_config << EOF *: @@ -74,7 +73,7 @@ for v in ${VERSIONS}; do continue fi verbose "ssh2 ${v}" - key=ssh-dss + key=ssh-rsa skipcat=0 case $v in 2.1.*|2.3.0) @@ -124,7 +123,6 @@ for v in ${VERSIONS}; do done rm -rf ${OBJ}/${USER} -for i in ssh2_config random_seed dsa.pub dsa host.dsa \ - id.list id.com id.com.pub id.openssh; do +for i in ssh2_config random_seed id.list id.com id.com.pub id.openssh; do rm -f ${OBJ}/$i done diff --git a/regress/ssh-com.sh b/regress/ssh-com.sh index b1a2505..bb83338 100644 --- a/regress/ssh-com.sh +++ b/regress/ssh-com.sh @@ -1,4 +1,4 @@ -# $OpenBSD: ssh-com.sh,v 1.10 2017/05/08 01:52:49 djm Exp $ +# $OpenBSD: ssh-com.sh,v 1.11 2025/05/06 06:05:48 djm Exp $ # Placed in the Public Domain. tid="connect to ssh.com server" @@ -41,8 +41,8 @@ cat << EOF > $OBJ/sshd2_config PubKeyAuthentication yes #AllowedAuthentications publickey AuthorizationFile authorization - HostKeyFile ${SRC}/dsa_ssh2.prv - PublicHostKeyFile ${SRC}/dsa_ssh2.pub + HostKeyFile ${SRC}/rsa_ssh2.prv + PublicHostKeyFile ${SRC}/rsa_ssh2.pub RandomSeedFile ${OBJ}/random_seed MaxConnections 0 PermitRootLogin yes @@ -55,23 +55,21 @@ EOF sed "s/HostKeyAlias.*/HostKeyAlias ssh2-localhost-with-alias/" \ < $OBJ/ssh_config > $OBJ/ssh_config_com -# we need a DSA key for -rm -f ${OBJ}/dsa ${OBJ}/dsa.pub -${SSHKEYGEN} -q -N '' -t dsa -f ${OBJ}/dsa +# we need a RSA key for +rm -f ${OBJ}/rsa ${OBJ}/rsa.pub +${SSHKEYGEN} -q -N '' -t rsa -f ${OBJ}/rsa # setup userdir, try rsa first mkdir -p ${OBJ}/${USER} cp /dev/null ${OBJ}/${USER}/authorization -for t in rsa dsa; do - ${SSHKEYGEN} -e -f ${OBJ}/$t.pub > ${OBJ}/${USER}/$t.com - echo Key $t.com >> ${OBJ}/${USER}/authorization - echo IdentityFile ${OBJ}/$t >> ${OBJ}/ssh_config_com -done +${SSHKEYGEN} -e -f ${OBJ}/rsa.pub > ${OBJ}/${USER}/rsa.com +echo Key rsa.com >> ${OBJ}/${USER}/authorization +echo IdentityFile ${OBJ}/rsa >> ${OBJ}/ssh_config_com -# convert and append DSA hostkey +# convert and append RSA hostkey ( printf 'ssh2-localhost-with-alias,127.0.0.1,::1 ' - ${SSHKEYGEN} -if ${SRC}/dsa_ssh2.pub + ${SSHKEYGEN} -if ${SRC}/rsa_ssh2.pub ) >> $OBJ/known_hosts # go for it @@ -114,6 +112,6 @@ done rm -rf ${OBJ}/${USER} for i in sshd_config_proxy ssh_config_proxy random_seed \ - sshd2_config dsa.pub dsa ssh_config_com; do + sshd2_config rsa.pub rsa ssh_config_com; do rm -f ${OBJ}/$i done diff --git a/regress/ssh2putty.sh b/regress/ssh2putty.sh index 9b08310..bd29131 100755 --- a/regress/ssh2putty.sh +++ b/regress/ssh2putty.sh @@ -1,5 +1,5 @@ #!/bin/sh -# $OpenBSD: ssh2putty.sh,v 1.9 2021/07/25 12:13:03 dtucker Exp $ +# $OpenBSD: ssh2putty.sh,v 1.10 2025/05/06 06:05:48 djm Exp $ if test "x$1" = "x" -o "x$2" = "x" -o "x$3" = "x" ; then echo "Usage: ssh2putty hostname port ssh-private-key" @@ -12,7 +12,6 @@ KEYFILE=$3 OPENSSL_BIN="${OPENSSL_BIN:-openssl}" -# XXX - support DSA keys too if grep "BEGIN RSA PRIVATE KEY" $KEYFILE >/dev/null 2>&1 ; then : else diff --git a/regress/sshcfgparse.sh b/regress/sshcfgparse.sh index 504853d..29fa1d8 100644 --- a/regress/sshcfgparse.sh +++ b/regress/sshcfgparse.sh @@ -1,15 +1,8 @@ -# $OpenBSD: sshcfgparse.sh,v 1.9 2021/06/08 07:05:27 dtucker Exp $ +# $OpenBSD: sshcfgparse.sh,v 1.10 2025/05/06 06:05:48 djm Exp $ # Placed in the Public Domain. tid="ssh config parse" -dsa=0 -for t in $SSH_KEYTYPES; do - case "$t" in - ssh-dss) dsa=1 ;; - esac -done - expect_result_present() { _str="$1" ; shift for _expect in "$@" ; do @@ -66,33 +59,23 @@ verbose "pubkeyacceptedalgorithms" # Default set f=`${SSH} -GF none host | awk '/^pubkeyacceptedalgorithms /{print $2}'` expect_result_present "$f" "ssh-ed25519" "ssh-ed25519-cert-v01.*" -expect_result_absent "$f" "ssh-dss" # Explicit override f=`${SSH} -GF none -opubkeyacceptedalgorithms=ssh-ed25519 host | \ awk '/^pubkeyacceptedalgorithms /{print $2}'` expect_result_present "$f" "ssh-ed25519" -expect_result_absent "$f" "ssh-ed25519-cert-v01.*" "ssh-dss" +expect_result_absent "$f" "ssh-ed25519-cert-v01.*" # Removal from default set f=`${SSH} -GF none -opubkeyacceptedalgorithms=-ssh-ed25519-cert* host | \ awk '/^pubkeyacceptedalgorithms /{print $2}'` expect_result_present "$f" "ssh-ed25519" -expect_result_absent "$f" "ssh-ed25519-cert-v01.*" "ssh-dss" +expect_result_absent "$f" "ssh-ed25519-cert-v01.*" f=`${SSH} -GF none -opubkeyacceptedalgorithms=-ssh-ed25519 host | \ awk '/^pubkeyacceptedalgorithms /{print $2}'` expect_result_present "$f" "ssh-ed25519-cert-v01.*" -expect_result_absent "$f" "ssh-ed25519" "ssh-dss" +expect_result_absent "$f" "ssh-ed25519" # Append to default set. # This is not tested when built !WITH_OPENSSL -if [ "$dsa" = "1" ]; then - f=`${SSH} -GF none -opubkeyacceptedalgorithms=+ssh-dss-cert* host | \ - awk '/^pubkeyacceptedalgorithms /{print $2}'` - expect_result_present "$f" "ssh-ed25519" "ssh-dss-cert-v01.*" - expect_result_absent "$f" "ssh-dss" - f=`${SSH} -GF none -opubkeyacceptedalgorithms=+ssh-dss host | \ - awk '/^pubkeyacceptedalgorithms /{print $2}'` - expect_result_present "$f" "ssh-ed25519" "ssh-ed25519-cert-v01.*" "ssh-dss" - expect_result_absent "$f" "ssh-dss-cert-v01.*" -fi +# XXX need a test for this verbose "agentforwarding" f=`${SSH} -GF none host | awk '/^forwardagent /{print$2}'` diff --git a/regress/sshfp-connect.sh b/regress/sshfp-connect.sh index f786469..3c73a35 100644 --- a/regress/sshfp-connect.sh +++ b/regress/sshfp-connect.sh @@ -1,4 +1,4 @@ -# $OpenBSD: sshfp-connect.sh,v 1.4 2021/09/01 00:50:27 dtucker Exp $ +# $OpenBSD: sshfp-connect.sh,v 1.5 2025/03/11 11:46:44 dtucker Exp $ # Placed in the Public Domain. # This test requires external setup and thus is skipped unless @@ -29,6 +29,12 @@ if ! $SSH -Q key-plain | grep ssh-rsa >/dev/null; then elif [ -z "${TEST_SSH_SSHFP_DOMAIN}" ]; then skip "TEST_SSH_SSHFP_DOMAIN not set." else + # Prime any DNS caches and resolvers. + for i in sshtest sshtest-sha1 sshtest-sha256; do + host -t sshfp ${i}.${TEST_SSH_SSHFP_DOMAIN} >/dev/null 2>&1 + host -t sshfp ${i}-bad.${TEST_SSH_SSHFP_DOMAIN} >/dev/null 2>&1 + done + # Set RSA host key to match fingerprints above. mv $OBJ/sshd_proxy $OBJ/sshd_proxy.orig $SUDO cp $SRC/rsa_openssh.prv $OBJ/host.ssh-rsa diff --git a/regress/sshsig.sh b/regress/sshsig.sh index dae0370..fe0958a 100644 --- a/regress/sshsig.sh +++ b/regress/sshsig.sh @@ -1,4 +1,4 @@ -# $OpenBSD: sshsig.sh,v 1.15 2023/10/12 03:51:08 djm Exp $ +# $OpenBSD: sshsig.sh,v 1.16 2025/09/11 07:23:32 djm Exp $ # Placed in the Public Domain. tid="sshsig" @@ -255,7 +255,7 @@ for t in $SIGNKEYS; do # Check signing keys using ssh-agent. trace "$tid: key type $t prepare agent" ${SSHADD} -D >/dev/null 2>&1 # Remove all previously-loaded keys. - ${SSHADD} ${privkey} > /dev/null 2>&1 || fail "ssh-add failed" + ${SSHADD} -N ${privkey} > /dev/null 2>&1 || fail "ssh-add failed" # Move private key to ensure agent key is used mv ${privkey} ${privkey}.tmp diff --git a/regress/test-exec.sh b/regress/test-exec.sh index 7afc280..34fb58f 100644 --- a/regress/test-exec.sh +++ b/regress/test-exec.sh @@ -1,4 +1,4 @@ -# $OpenBSD: test-exec.sh,v 1.119 2024/06/20 08:18:34 dtucker Exp $ +# $OpenBSD: test-exec.sh,v 1.131 2025/07/26 01:53:31 djm Exp $ # Placed in the Public Domain. #SUDO=sudo @@ -91,6 +91,7 @@ SSHKEYSCAN=ssh-keyscan SFTP=sftp SFTPSERVER=/usr/libexec/openssh/sftp-server SSHD_SESSION=/usr/libexec/sshd-session +SSHD_AUTH=/usr/libexec/sshd-auth SCP=scp # Set by make_tmpdir() on demand (below). @@ -100,7 +101,7 @@ SSH_REGRESS_TMP= PLINK=/usr/local/bin/plink PUTTYGEN=/usr/local/bin/puttygen CONCH=/usr/local/bin/conch -DROPBEAR=/usr/local/bin/dropbear +DROPBEAR=/usr/local/sbin/dropbear DBCLIENT=/usr/local/bin/dbclient DROPBEARKEY=/usr/local/bin/dropbearkey DROPBEARCONVERT=/usr/local/bin/dropbearconvert @@ -119,6 +120,9 @@ fi if [ "x$TEST_SSH_SSHD_SESSION" != "x" ]; then SSHD_SESSION="${TEST_SSH_SSHD_SESSION}" fi +if [ "x$TEST_SSH_SSHD_AUTH" != "x" ]; then + SSHD_AUTH="${TEST_SSH_SSHD_AUTH}" +fi if [ "x$TEST_SSH_SSHD" != "x" ]; then SSHD="${TEST_SSH_SSHD}" fi @@ -180,6 +184,11 @@ case "$SSHD" in *) SSHD=`which $SSHD` ;; esac +case "$SSH" in +/*) ;; +*) SSH=`which $SSH` ;; +esac + case "$SSHAGENT" in /*) ;; *) SSHAGENT=`which $SSHAGENT` ;; @@ -305,6 +314,7 @@ fi # 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 +rm -f ${SSHLOGWRAP} cat >$SSHLOGWRAP <$SSHDLOGWRAP <>$TEST_REGRESS_LOGFILE echo $@ >>$TEST_SSH_LOGFILE echo $@ >>$TEST_SSHD_LOGFILE @@ -531,19 +543,6 @@ save_debug_log () (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 - - # Save all logfiles in a tarball. - (cd $OBJ && - logfiles="" - for i in $TEST_REGRESS_LOGFILE $TEST_SSH_LOGFILE $TEST_SSHD_LOGFILE \ - $TEST_SSH_LOGDIR; do - if [ -e "`basename $i`" ]; then - logfiles="$logfiles `basename $i`" - else - logfiles="$logfiles $i" - fi - done - tar cf "$tarname" $logfiles) } trace () @@ -621,6 +620,7 @@ cat << EOF > $OBJ/sshd_config AcceptEnv _XXX_TEST Subsystem sftp $SFTPSERVER SshdSessionPath $SSHD_SESSION + SshdAuthPath $SSHD_AUTH PerSourcePenalties no EOF @@ -845,7 +845,8 @@ esac if test "$REGRESS_INTEROP_DROPBEAR" = "yes" ; then trace Create dropbear keys and add to authorized_keys - mkdir -p $OBJ/.dropbear + mkdir -p $OBJ/.dropbear $OBJ/.ssh + awk '{print "somehost "$2" "$3}' $OBJ/known_hosts >$OBJ/.ssh/known_hosts kt="ed25519" for i in dss rsa ecdsa; do if $SSH -Q key-plain | grep "$i" >/dev/null; then @@ -871,7 +872,7 @@ fi # create a proxy version of the client config ( cat $OBJ/ssh_config - echo proxycommand ${SUDO} env SSH_SK_HELPER=\"$SSH_SK_HELPER\" ${OBJ}/sshd-log-wrapper.sh -i -f $OBJ/sshd_proxy + echo proxycommand ${SUDO} env SSH_SK_HELPER=\"$SSH_SK_HELPER\" ${TEST_SSH_SSHD_ENV} ${OBJ}/sshd-log-wrapper.sh -i -f $OBJ/sshd_proxy ) > $OBJ/ssh_proxy # check proxy config @@ -888,8 +889,9 @@ start_sshd () PIDFILE=$OBJ/pidfile # start sshd logfile="${TEST_SSH_LOGDIR}/sshd.`$OBJ/timestamp`.$$.log" - $SUDO ${SSHD} -f $OBJ/sshd_config "$@" -t || fatal "sshd_config broken" - $SUDO env SSH_SK_HELPER="$SSH_SK_HELPER" \ + $SUDO env SSH_SK_HELPER="$SSH_SK_HELPER" ${TEST_SSH_SSHD_ENV} \ + ${SSHD} -f $OBJ/sshd_config "$@" -t || fatal "sshd_config broken" + $SUDO env SSH_SK_HELPER="$SSH_SK_HELPER" ${TEST_SSH_SSHD_ENV} \ ${SSHD} -f $OBJ/sshd_config "$@" -E$TEST_SSHD_LOGFILE trace "wait for sshd" @@ -898,6 +900,7 @@ start_sshd () i=`expr $i + 1` sleep $i done + rm -f ${TEST_SSHD_LOGFILE} ln -f -s ${logfile} $TEST_SSHD_LOGFILE test -f $PIDFILE || fatal "no sshd running on port $PORT" @@ -924,7 +927,7 @@ p11_setup() { /usr/lib64/pkcs11/libsofthsm2.so \ /usr/lib/x86_64-linux-gnu/softhsm/libsofthsm2.so test -z "$TEST_SSH_PKCS11" && return 1 - verbose "using token library $TEST_SSH_PKCS11" + trace "using token library $TEST_SSH_PKCS11" TEST_SSH_PIN=1234 TEST_SSH_SOPIN=12345678 if [ "x$TEST_SSH_SSHPKCS11HELPER" != "x" ]; then @@ -961,7 +964,7 @@ EOF softhsm2-util --slot "$slot" --label 01 --id 01 --pin "$TEST_SSH_PIN" \ --import $RSAP8 >/dev/null || fatal "softhsm import RSA fail" chmod 600 $RSA - ssh-keygen -y -f $RSA > ${RSA}.pub + ${SSHKEYGEN} -y -f $RSA > ${RSA}.pub # ECDSA key ECPARAM=${SSH_SOFTHSM_DIR}/ECPARAM EC=${SSH_SOFTHSM_DIR}/EC @@ -975,7 +978,19 @@ EOF softhsm2-util --slot "$slot" --label 02 --id 02 --pin "$TEST_SSH_PIN" \ --import $ECP8 >/dev/null || fatal "softhsm import EC fail" chmod 600 $EC - ssh-keygen -y -f $EC > ${EC}.pub + ${SSHKEYGEN} -y -f $EC > ${EC}.pub + # Ed25519 key + ED25519=${SSH_SOFTHSM_DIR}/ED25519 + ED25519P8=${SSH_SOFTHSM_DIR}/ED25519P8 + $OPENSSL_BIN genpkey -algorithm ed25519 > $ED25519 || \ + fatal "genpkey Ed25519 fail" + $OPENSSL_BIN pkcs8 -nocrypt -in $ED25519 > $ED25519P8 || \ + fatal "pkcs8 Ed25519 fail" + softhsm2-util --slot "$slot" --label 03 --id 03 --pin "$TEST_SSH_PIN" \ + --import $ED25519P8 >/dev/null || \ + fatal "softhsm import ed25519 fail" + chmod 600 $ED25519 + ${SSHKEYGEN} -y -f $ED25519 > ${ED25519}.pub # Prepare askpass script to load PIN. PIN_SH=$SSH_SOFTHSM_DIR/pin.sh cat > $PIN_SH << EOF @@ -984,7 +999,11 @@ echo "${TEST_SSH_PIN}" EOF chmod 0700 "$PIN_SH" PKCS11_OK=yes - return 0 + if env SSH_ASKPASS="$PIN_SH" SSH_ASKPASS_REQUIRE=force \ + ${SSHKEYGEN} -D ${TEST_SSH_PKCS11} >/dev/null 2>&1 ; then + return 0 + fi + return 1 } # Peforms ssh-add with the right token PIN. @@ -992,6 +1011,28 @@ p11_ssh_add() { env SSH_ASKPASS="$PIN_SH" SSH_ASKPASS_REQUIRE=force ${SSHADD} "$@" } +start_ssh_agent() { + EXTRA_AGENT_ARGS="$1" + SSH_AUTH_SOCK="$OBJ/agent.sock" + export SSH_AUTH_SOCK + rm -f $SSH_AUTH_SOCK $OBJ/agent.log + trace "start agent" + ${SSHAGENT} ${EXTRA_AGENT_ARGS} -d -a $SSH_AUTH_SOCK \ + > $OBJ/agent.log 2>&1 & + AGENT_PID=$! + trap "kill $AGENT_PID" EXIT + for x in 0 1 2 3 4 ; do + # Give it a chance to start + ${SSHADD} -l > /dev/null 2>&1 + r=$? + test $r -eq 1 && break + sleep 1 + done + if [ $r -ne 1 ]; then + fatal "ssh-add -l did not fail with exit code 1 (got $r)" + fi +} + # source test body . $SCRIPT diff --git a/regress/unittests/Makefile.inc b/regress/unittests/Makefile.inc index 98e2804..5fcf7a9 100644 --- a/regress/unittests/Makefile.inc +++ b/regress/unittests/Makefile.inc @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile.inc,v 1.16 2024/01/11 01:45:58 djm Exp $ +# $OpenBSD: Makefile.inc,v 1.18 2025/05/06 06:05:48 djm Exp $ .include .include @@ -7,6 +7,9 @@ UNITTEST_FAST?= no # Skip slow tests (e.g. less intensive fuzzing). UNITTEST_SLOW?= no # Include slower tests (e.g. more intensive fuzzing). UNITTEST_VERBOSE?= no # Verbose test output (inc. per-test names). +UNITTEST_BENCHMARK?= no # Run unit tests in benchmarking mode. +UNITTEST_BENCH_DETAIL?=no # Detailed benchmark statistics. +UNITTEST_BENCH_ONLY?= # Run only these benchmarks MALLOC_OPTIONS?= CFGJRSUX TEST_ENV?= MALLOC_OPTIONS=${MALLOC_OPTIONS} @@ -15,10 +18,6 @@ TEST_ENV?= MALLOC_OPTIONS=${MALLOC_OPTIONS} OPENSSL?= yes DSAKEY?= yes -.if (${DSAKEY:L} == "yes") -CFLAGS+= -DWITH_DSA -.endif - .if (${OPENSSL:L} == "yes") CFLAGS+= -DWITH_OPENSSL .endif @@ -69,8 +68,8 @@ DPADD+=${.CURDIR}/../test_helper/libtest_helper.a .PATH: ${.CURDIR}/${SSHREL} -LDADD+= -lutil -DPADD+= ${LIBUTIL} +LDADD+= -lutil -lm +DPADD+= ${LIBUTIL} ${LIBM} .if (${OPENSSL:L} == "yes") LDADD+= -lcrypto @@ -82,11 +81,21 @@ DPADD+= ${LIBFIDO2} ${LIBCBOR} ${LIBUSBHID} UNITTEST_ARGS?= -.if (${UNITTEST_VERBOSE:L} != "no") +.if (${UNITTEST_VERBOSE:L:R} != "no") UNITTEST_ARGS+= -v .endif -.if (${UNITTEST_FAST:L} != "no") +.if (${UNITTEST_FAST:L:R} != "no") UNITTEST_ARGS+= -f -.elif (${UNITTEST_SLOW:L} != "no") +.elif (${UNITTEST_SLOW:L:R} != "no") UNITTEST_ARGS+= -F .endif + +.if (${UNITTEST_BENCHMARK:L:R} != "no") +UNITTEST_ARGS+= -b +.endif +.if (${UNITTEST_BENCH_DETAIL:L:R} != "no") +UNITTEST_ARGS+= -B +.endif +.if (${UNITTEST_BENCH_ONLY:L} != "") +UNITTEST_ARGS+= -O "${UNITTEST_BENCH_ONLY}" +.endif diff --git a/regress/unittests/authopt/Makefile b/regress/unittests/authopt/Makefile index 3045ec7..1ecaa30 100644 --- a/regress/unittests/authopt/Makefile +++ b/regress/unittests/authopt/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.7 2023/01/15 23:35:10 djm Exp $ +# $OpenBSD: Makefile,v 1.10 2025/07/24 06:04:47 djm Exp $ PROG=test_authopt SRCS=tests.c @@ -8,12 +8,12 @@ SRCS+=auth-options.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+=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 SRCS+=cipher-chachapoly.c chacha.c poly1305.c ssh-ecdsa-sk.c ssh-sk.c -SRCS+=ssh-ed25519-sk.c sk-usbhid.c +SRCS+=ssh-ed25519-sk.c sk-usbhid.c ssh-pkcs11-client.c SRCS+=digest-openssl.c #SRCS+=digest-libc.c @@ -22,6 +22,6 @@ SRCS+=utf8.c REGRESS_TARGETS=run-regress-${PROG} run-regress-${PROG}: ${PROG} - env ${TEST_ENV} ./${PROG} -d ${.CURDIR}/testdata + env ${TEST_ENV} ./${PROG} ${UNITTEST_ARGS} -d ${.CURDIR}/testdata .include diff --git a/regress/unittests/authopt/tests.c b/regress/unittests/authopt/tests.c index d9e1903..a81dffb 100644 --- a/regress/unittests/authopt/tests.c +++ b/regress/unittests/authopt/tests.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tests.c,v 1.3 2021/12/14 21:25:27 deraadt Exp $ */ +/* $OpenBSD: tests.c,v 1.4 2025/04/15 04:00:42 djm Exp $ */ /* * Regress test for keys options functions. @@ -10,9 +10,7 @@ #include #include -#ifdef HAVE_STDINT_H #include -#endif #include #include @@ -576,3 +574,9 @@ tests(void) test_cert_parse(); test_merge(); } + +void +benchmarks(void) +{ + printf("no benchmarks\n"); +} diff --git a/regress/unittests/bitmap/Makefile b/regress/unittests/bitmap/Makefile index fe30acc..c38cc79 100644 --- a/regress/unittests/bitmap/Makefile +++ b/regress/unittests/bitmap/Makefile @@ -1,14 +1,15 @@ -# $OpenBSD: Makefile,v 1.4 2017/12/21 00:41:22 djm Exp $ +# $OpenBSD: Makefile,v 1.5 2025/04/15 04:00:42 djm Exp $ PROG=test_bitmap SRCS=tests.c # From usr.sbin/ssh -SRCS+=bitmap.c atomicio.c +SRCS+=bitmap.c atomicio.c misc.c xmalloc.c fatal.c log.c cleanup.c match.c +SRCS+=sshbuf.c sshbuf-getput-basic.c sshbuf-misc.c ssherr.c addr.c addrmatch.c REGRESS_TARGETS=run-regress-${PROG} run-regress-${PROG}: ${PROG} - env ${TEST_ENV} ./${PROG} + env ${TEST_ENV} ./${PROG} ${UNITTEST_ARGS} .include diff --git a/regress/unittests/bitmap/tests.c b/regress/unittests/bitmap/tests.c index 576b863..6470f98 100644 --- a/regress/unittests/bitmap/tests.c +++ b/regress/unittests/bitmap/tests.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tests.c,v 1.2 2021/12/14 21:25:27 deraadt Exp $ */ +/* $OpenBSD: tests.c,v 1.3 2025/04/15 04:00:42 djm Exp $ */ /* * Regress test for bitmap.h bitmap API * @@ -9,9 +9,7 @@ #include #include -#ifdef HAVE_STDINT_H #include -#endif #include #include @@ -23,7 +21,7 @@ #include "bitmap.h" -#define NTESTS 131 +#define DEFAULT_NTESTS 131 void tests(void) @@ -32,10 +30,15 @@ tests(void) struct bitmap *b; BIGNUM *bn; size_t len; - int i, j, k, n; + int i, j, k, n, ntests = DEFAULT_NTESTS; u_char bbuf[1024], bnbuf[1024]; int r; + if (test_is_fast()) + ntests /= 4; + else if (test_is_slow()) + ntests *= 2; + TEST_START("bitmap_new"); b = bitmap_new(); ASSERT_PTR_NE(b, NULL); @@ -44,9 +47,9 @@ tests(void) TEST_DONE(); TEST_START("bitmap_set_bit / bitmap_test_bit"); - for (i = -1; i < NTESTS; i++) { - for (j = -1; j < NTESTS; j++) { - for (k = -1; k < NTESTS; k++) { + for (i = -1; i < ntests; i++) { + for (j = -1; j < ntests; j++) { + for (k = -1; k < ntests; k++) { bitmap_zero(b); BN_clear(bn); @@ -67,7 +70,7 @@ tests(void) /* Check perfect match between bitmap and bn */ test_subtest_info("match %d/%d/%d", i, j, k); - for (n = 0; n < NTESTS; n++) { + for (n = 0; n < ntests; n++) { ASSERT_INT_EQ(BN_is_bit_set(bn, n), bitmap_test_bit(b, n)); } @@ -99,7 +102,7 @@ tests(void) bitmap_zero(b); ASSERT_INT_EQ(bitmap_from_string(b, bnbuf, len), 0); - for (n = 0; n < NTESTS; n++) { + for (n = 0; n < ntests; n++) { ASSERT_INT_EQ(BN_is_bit_set(bn, n), bitmap_test_bit(b, n)); } @@ -107,7 +110,7 @@ tests(void) /* Test clearing bits */ test_subtest_info("clear %d/%d/%d", i, j, k); - for (n = 0; n < NTESTS; n++) { + for (n = 0; n < ntests; n++) { ASSERT_INT_EQ(bitmap_set_bit(b, n), 0); ASSERT_INT_EQ(BN_set_bit(bn, n), 1); } @@ -123,7 +126,7 @@ tests(void) bitmap_clear_bit(b, k); BN_clear_bit(bn, k); } - for (n = 0; n < NTESTS; n++) { + for (n = 0; n < ntests; n++) { ASSERT_INT_EQ(BN_is_bit_set(bn, n), bitmap_test_bit(b, n)); } @@ -135,4 +138,9 @@ tests(void) TEST_DONE(); #endif } +void +benchmarks(void) +{ + printf("no benchmarks\n"); +} diff --git a/regress/unittests/conversion/Makefile b/regress/unittests/conversion/Makefile index 5793c49..f9f5859 100644 --- a/regress/unittests/conversion/Makefile +++ b/regress/unittests/conversion/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.4 2021/01/09 12:24:30 dtucker Exp $ +# $OpenBSD: Makefile,v 1.5 2025/04/15 04:00:42 djm Exp $ PROG=test_conversion SRCS=tests.c @@ -11,6 +11,6 @@ SRCS+=match.c addr.c addrmatch.c REGRESS_TARGETS=run-regress-${PROG} run-regress-${PROG}: ${PROG} - env ${TEST_ENV} ./${PROG} + env ${TEST_ENV} ./${PROG} ${UNITTEST_ARGS} .include diff --git a/regress/unittests/conversion/tests.c b/regress/unittests/conversion/tests.c index 5b526f7..fce4d1c 100644 --- a/regress/unittests/conversion/tests.c +++ b/regress/unittests/conversion/tests.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tests.c,v 1.4 2021/12/14 21:25:27 deraadt Exp $ */ +/* $OpenBSD: tests.c,v 1.5 2025/04/15 04:00:42 djm Exp $ */ /* * Regress test for conversions * @@ -9,9 +9,7 @@ #include #include -#ifdef HAVE_STDINT_H #include -#endif #include #include @@ -50,3 +48,9 @@ tests(void) ASSERT_INT_EQ(convtime("1000000000000000000000w"), -1); TEST_DONE(); } + +void +benchmarks(void) +{ + printf("no benchmarks\n"); +} diff --git a/regress/unittests/hostkeys/Makefile b/regress/unittests/hostkeys/Makefile index 04d9335..76c8e67 100644 --- a/regress/unittests/hostkeys/Makefile +++ b/regress/unittests/hostkeys/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.10 2023/01/15 23:35:10 djm Exp $ +# $OpenBSD: Makefile,v 1.13 2025/07/24 06:04:47 djm Exp $ PROG=test_hostkeys SRCS=tests.c test_iterate.c @@ -6,12 +6,12 @@ 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+=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 SRCS+=cipher-chachapoly.c chacha.c poly1305.c ssh-ecdsa-sk.c ssh-sk.c -SRCS+=ssh-ed25519-sk.c sk-usbhid.c +SRCS+=ssh-ed25519-sk.c sk-usbhid.c ssh-pkcs11-client.c SRCS+=digest-openssl.c #SRCS+=digest-libc.c @@ -20,6 +20,6 @@ SRCS+=utf8.c REGRESS_TARGETS=run-regress-${PROG} run-regress-${PROG}: ${PROG} - env ${TEST_ENV} ./${PROG} -d ${.CURDIR}/testdata + env ${TEST_ENV} ./${PROG} ${UNITTEST_ARGS} -d ${.CURDIR}/testdata .include diff --git a/regress/unittests/hostkeys/mktestdata.sh b/regress/unittests/hostkeys/mktestdata.sh index 5a46de9..5fec582 100644 --- a/regress/unittests/hostkeys/mktestdata.sh +++ b/regress/unittests/hostkeys/mktestdata.sh @@ -1,11 +1,11 @@ #!/bin/sh -# $OpenBSD: mktestdata.sh,v 1.2 2017/04/30 23:33:48 djm Exp $ +# $OpenBSD: mktestdata.sh,v 1.3 2025/05/06 06:05:48 djm Exp $ set -ex cd testdata -rm -f rsa* dsa* ecdsa* ed25519* +rm -f rsa* ecdsa* ed25519* rm -f known_hosts* gen_all() { @@ -14,11 +14,10 @@ gen_all() { test "x$_n" = "x1" && _ecdsa_bits=384 test "x$_n" = "x2" && _ecdsa_bits=521 ssh-keygen -qt rsa -b 1024 -C "RSA #$_n" -N "" -f rsa_$_n - ssh-keygen -qt dsa -b 1024 -C "DSA #$_n" -N "" -f dsa_$_n ssh-keygen -qt ecdsa -b $_ecdsa_bits -C "ECDSA #$_n" -N "" -f ecdsa_$_n ssh-keygen -qt ed25519 -C "ED25519 #$_n" -N "" -f ed25519_$_n # Don't need private keys - rm -f rsa_$_n dsa_$_n ecdsa_$_n ed25519_$_n + rm -f rsa_$_n ecdsa_$_n ed25519_$_n } hentries() { @@ -65,18 +64,18 @@ rm -f known_hosts_hash_frag.old echo "# Revoked and CA keys" printf "@revoked sisyphus.example.com " ; cat ed25519_4.pub printf "@cert-authority prometheus.example.com " ; cat ecdsa_4.pub - printf "@cert-authority *.example.com " ; cat dsa_4.pub + printf "@cert-authority *.example.com " ; cat rsa_4.pub printf "\n" echo "# Some invalid lines" # Invalid marker - printf "@what sisyphus.example.com " ; cat dsa_1.pub + printf "@what sisyphus.example.com " ; cat rsa_1.pub # Key missing echo "sisyphus.example.com " # Key blob missing echo "prometheus.example.com ssh-ed25519 " # Key blob truncated - echo "sisyphus.example.com ssh-dsa AAAATgAAAAdz" + echo "sisyphus.example.com ssh-rsa AAAATgAAAAdz" # Invalid type echo "sisyphus.example.com ssh-XXX AAAATgAAAAdzc2gtWFhYAAAAP0ZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRg==" # Type mismatch with blob diff --git a/regress/unittests/hostkeys/test_iterate.c b/regress/unittests/hostkeys/test_iterate.c index 7efb8e1..65d6d1f 100644 --- a/regress/unittests/hostkeys/test_iterate.c +++ b/regress/unittests/hostkeys/test_iterate.c @@ -1,4 +1,4 @@ -/* $OpenBSD: test_iterate.c,v 1.9 2024/01/11 01:45:58 djm Exp $ */ +/* $OpenBSD: test_iterate.c,v 1.10 2025/05/06 06:05:48 djm Exp $ */ /* * Regress test for hostfile.h hostkeys_foreach() * @@ -9,9 +9,7 @@ #include #include -#ifdef HAVE_STDINT_H #include -#endif #include #include @@ -94,15 +92,8 @@ check(struct hostkey_foreach_line *l, void *_ctx) expected->no_parse_keytype == KEY_ECDSA) skip = 1; #endif /* OPENSSL_HAS_ECC */ -#ifndef WITH_DSA - if (expected->l.keytype == KEY_DSA || - expected->no_parse_keytype == KEY_DSA) - skip = 1; -#endif #ifndef WITH_OPENSSL - if (expected->l.keytype == KEY_DSA || - expected->no_parse_keytype == KEY_DSA || - expected->l.keytype == KEY_RSA || + if (expected->l.keytype == KEY_RSA || expected->no_parse_keytype == KEY_RSA || expected->l.keytype == KEY_ECDSA || expected->no_parse_keytype == KEY_ECDSA) @@ -160,14 +151,9 @@ prepare_expected(struct expected *expected, size_t n) if (expected[i].l.keytype == KEY_ECDSA) continue; #endif /* OPENSSL_HAS_ECC */ -#ifndef WITH_DSA - if (expected[i].l.keytype == KEY_DSA) - continue; -#endif #ifndef WITH_OPENSSL switch (expected[i].l.keytype) { case KEY_RSA: - case KEY_DSA: case KEY_ECDSA: continue; } @@ -204,23 +190,9 @@ struct expected expected_full[] = { NULL, /* comment */ 0, /* note */ } }, - { "dsa_1.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { - NULL, - 2, - HKF_STATUS_OK, - 0, - NULL, - MRK_NONE, - "sisyphus.example.com", - NULL, - KEY_DSA, - NULL, /* filled at runtime */ - "DSA #1", - 0, - } }, { "ecdsa_1.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { NULL, - 3, + 2, HKF_STATUS_OK, 0, NULL, @@ -234,7 +206,7 @@ struct expected expected_full[] = { } }, { "ed25519_1.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { NULL, - 4, + 3, HKF_STATUS_OK, 0, NULL, @@ -248,7 +220,7 @@ struct expected expected_full[] = { } }, { "rsa_1.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { NULL, - 5, + 4, HKF_STATUS_OK, 0, NULL, @@ -262,7 +234,7 @@ struct expected expected_full[] = { } }, { NULL, -1, -1, 0, 0, 0, 0, -1, { NULL, - 6, + 5, HKF_STATUS_COMMENT, 0, "", @@ -276,7 +248,7 @@ struct expected expected_full[] = { } }, { NULL, -1, -1, 0, 0, 0, 0, -1, { NULL, - 7, + 6, HKF_STATUS_COMMENT, 0, "# Plain host keys, hostnames + addresses", @@ -288,23 +260,9 @@ struct expected expected_full[] = { NULL, 0, } }, - { "dsa_2.pub" , -1, -1, HKF_MATCH_HOST, 0, HKF_MATCH_IP, HKF_MATCH_IP, -1, { - NULL, - 8, - HKF_STATUS_OK, - 0, - NULL, - MRK_NONE, - "prometheus.example.com,192.0.2.1,2001:db8::1", - NULL, - KEY_DSA, - NULL, /* filled at runtime */ - "DSA #2", - 0, - } }, { "ecdsa_2.pub" , -1, -1, HKF_MATCH_HOST, 0, HKF_MATCH_IP, HKF_MATCH_IP, -1, { NULL, - 9, + 7, HKF_STATUS_OK, 0, NULL, @@ -318,7 +276,7 @@ struct expected expected_full[] = { } }, { "ed25519_2.pub" , -1, -1, HKF_MATCH_HOST, 0, HKF_MATCH_IP, HKF_MATCH_IP, -1, { NULL, - 10, + 8, HKF_STATUS_OK, 0, NULL, @@ -332,7 +290,7 @@ struct expected expected_full[] = { } }, { "rsa_2.pub" , -1, -1, HKF_MATCH_HOST, 0, HKF_MATCH_IP, HKF_MATCH_IP, -1, { NULL, - 11, + 9, HKF_STATUS_OK, 0, NULL, @@ -346,7 +304,7 @@ struct expected expected_full[] = { } }, { NULL, -1, -1, 0, 0, 0, 0, -1, { NULL, - 12, + 10, HKF_STATUS_COMMENT, 0, "", @@ -360,7 +318,7 @@ struct expected expected_full[] = { } }, { NULL, -1, -1, 0, 0, 0, 0, -1, { NULL, - 13, + 11, HKF_STATUS_COMMENT, 0, "# Some hosts with wildcard names / IPs", @@ -372,23 +330,9 @@ struct expected expected_full[] = { NULL, 0, } }, - { "dsa_3.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, HKF_MATCH_IP, HKF_MATCH_IP, -1, { - NULL, - 14, - HKF_STATUS_OK, - 0, - NULL, - MRK_NONE, - "*.example.com,192.0.2.*,2001:*", - NULL, - KEY_DSA, - NULL, /* filled at runtime */ - "DSA #3", - 0, - } }, { "ecdsa_3.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, HKF_MATCH_IP, HKF_MATCH_IP, -1, { NULL, - 15, + 12, HKF_STATUS_OK, 0, NULL, @@ -402,7 +346,7 @@ struct expected expected_full[] = { } }, { "ed25519_3.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, HKF_MATCH_IP, HKF_MATCH_IP, -1, { NULL, - 16, + 13, HKF_STATUS_OK, 0, NULL, @@ -416,7 +360,7 @@ struct expected expected_full[] = { } }, { "rsa_3.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, HKF_MATCH_IP, HKF_MATCH_IP, -1, { NULL, - 17, + 14, HKF_STATUS_OK, 0, NULL, @@ -430,7 +374,7 @@ struct expected expected_full[] = { } }, { NULL, -1, -1, 0, 0, 0, 0, -1, { NULL, - 18, + 15, HKF_STATUS_COMMENT, 0, "", @@ -444,7 +388,7 @@ struct expected expected_full[] = { } }, { NULL, -1, -1, 0, 0, 0, 0, -1, { NULL, - 19, + 16, HKF_STATUS_COMMENT, 0, "# Hashed hostname and address entries", @@ -456,23 +400,9 @@ struct expected expected_full[] = { NULL, 0, } }, - { "dsa_5.pub" , -1, -1, 0, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, -1, { - NULL, - 20, - HKF_STATUS_OK, - 0, - NULL, - MRK_NONE, - NULL, - NULL, - KEY_DSA, - NULL, /* filled at runtime */ - "DSA #5", - 0, - } }, { "ecdsa_5.pub" , -1, -1, 0, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, -1, { NULL, - 21, + 17, HKF_STATUS_OK, 0, NULL, @@ -486,7 +416,7 @@ struct expected expected_full[] = { } }, { "ed25519_5.pub" , -1, -1, 0, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, -1, { NULL, - 22, + 18, HKF_STATUS_OK, 0, NULL, @@ -500,7 +430,7 @@ struct expected expected_full[] = { } }, { "rsa_5.pub" , -1, -1, 0, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, -1, { NULL, - 23, + 19, HKF_STATUS_OK, 0, NULL, @@ -514,7 +444,7 @@ struct expected expected_full[] = { } }, { NULL, -1, -1, 0, 0, 0, 0, -1, { NULL, - 24, + 20, HKF_STATUS_COMMENT, 0, "", @@ -531,51 +461,9 @@ struct expected expected_full[] = { * hostname and addresses in the pre-hashed known_hosts are split * to separate lines. */ - { "dsa_6.pub" , -1, -1, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, 0, -1, { - NULL, - 25, - HKF_STATUS_OK, - 0, - NULL, - MRK_NONE, - NULL, - NULL, - KEY_DSA, - NULL, /* filled at runtime */ - "DSA #6", - 0, - } }, - { "dsa_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, { - NULL, - 26, - HKF_STATUS_OK, - 0, - NULL, - MRK_NONE, - NULL, - NULL, - KEY_DSA, - NULL, /* filled at runtime */ - "DSA #6", - 0, - } }, - { "dsa_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, { - NULL, - 27, - HKF_STATUS_OK, - 0, - NULL, - MRK_NONE, - NULL, - NULL, - KEY_DSA, - NULL, /* filled at runtime */ - "DSA #6", - 0, - } }, { "ecdsa_6.pub" , -1, -1, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, 0, -1, { NULL, - 28, + 21, HKF_STATUS_OK, 0, NULL, @@ -589,7 +477,7 @@ struct expected expected_full[] = { } }, { "ecdsa_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, { NULL, - 29, + 22, HKF_STATUS_OK, 0, NULL, @@ -603,7 +491,7 @@ struct expected expected_full[] = { } }, { "ecdsa_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, { NULL, - 30, + 23, HKF_STATUS_OK, 0, NULL, @@ -617,7 +505,7 @@ struct expected expected_full[] = { } }, { "ed25519_6.pub" , -1, -1, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, 0, -1, { NULL, - 31, + 24, HKF_STATUS_OK, 0, NULL, @@ -631,7 +519,7 @@ struct expected expected_full[] = { } }, { "ed25519_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, { NULL, - 32, + 25, HKF_STATUS_OK, 0, NULL, @@ -645,7 +533,7 @@ struct expected expected_full[] = { } }, { "ed25519_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, { NULL, - 33, + 26, HKF_STATUS_OK, 0, NULL, @@ -659,7 +547,7 @@ struct expected expected_full[] = { } }, { "rsa_6.pub" , -1, -1, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, 0, -1, { NULL, - 34, + 27, HKF_STATUS_OK, 0, NULL, @@ -673,7 +561,7 @@ struct expected expected_full[] = { } }, { "rsa_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, { NULL, - 35, + 28, HKF_STATUS_OK, 0, NULL, @@ -687,7 +575,7 @@ struct expected expected_full[] = { } }, { "rsa_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, { NULL, - 36, + 29, HKF_STATUS_OK, 0, NULL, @@ -701,7 +589,7 @@ struct expected expected_full[] = { } }, { NULL, -1, -1, 0, 0, 0, 0, -1, { NULL, - 37, + 30, HKF_STATUS_COMMENT, 0, "", @@ -715,7 +603,7 @@ struct expected expected_full[] = { } }, { NULL, -1, -1, 0, 0, 0, 0, -1, { NULL, - 38, + 31, HKF_STATUS_COMMENT, 0, "", @@ -729,7 +617,7 @@ struct expected expected_full[] = { } }, { NULL, -1, -1, 0, 0, 0, 0, -1, { NULL, - 39, + 32, HKF_STATUS_COMMENT, 0, "# Revoked and CA keys", @@ -743,7 +631,7 @@ struct expected expected_full[] = { } }, { "ed25519_4.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { NULL, - 40, + 33, HKF_STATUS_OK, 0, NULL, @@ -757,7 +645,7 @@ struct expected expected_full[] = { } }, { "ecdsa_4.pub" , -1, -1, HKF_MATCH_HOST, 0, 0, 0, -1, { NULL, - 41, + 34, HKF_STATUS_OK, 0, NULL, @@ -769,23 +657,9 @@ struct expected expected_full[] = { "ECDSA #4", 0, } }, - { "dsa_4.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, 0, 0, -1, { - NULL, - 42, - HKF_STATUS_OK, - 0, - NULL, - MRK_CA, - "*.example.com", - NULL, - KEY_DSA, - NULL, /* filled at runtime */ - "DSA #4", - 0, - } }, { NULL, -1, -1, 0, 0, 0, 0, -1, { NULL, - 43, + 35, HKF_STATUS_COMMENT, 0, "", @@ -799,7 +673,7 @@ struct expected expected_full[] = { } }, { NULL, -1, -1, 0, 0, 0, 0, -1, { NULL, - 44, + 36, HKF_STATUS_COMMENT, 0, "# Some invalid lines", @@ -813,7 +687,7 @@ struct expected expected_full[] = { } }, { NULL, -1, -1, 0, 0, 0, 0, -1, { NULL, - 45, + 37, HKF_STATUS_INVALID, 0, NULL, @@ -827,7 +701,7 @@ struct expected expected_full[] = { } }, { NULL, -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { NULL, - 46, + 38, HKF_STATUS_INVALID, 0, NULL, @@ -841,7 +715,7 @@ struct expected expected_full[] = { } }, { NULL, -1, -1, HKF_MATCH_HOST, 0, 0, 0, -1, { NULL, - 47, + 39, HKF_STATUS_INVALID, 0, NULL, @@ -853,9 +727,9 @@ struct expected expected_full[] = { NULL, 0, } }, - { NULL, -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { + { NULL, HKF_STATUS_OK, KEY_ED25519, 0, HKF_MATCH_HOST, 0, 0, -1, { NULL, - 48, + 40, HKF_STATUS_INVALID, /* Would be ok if key not parsed */ 0, NULL, @@ -869,7 +743,7 @@ struct expected expected_full[] = { } }, { NULL, -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { NULL, - 49, + 41, HKF_STATUS_INVALID, 0, NULL, @@ -883,7 +757,7 @@ struct expected expected_full[] = { } }, { NULL, HKF_STATUS_OK, KEY_RSA, HKF_MATCH_HOST, 0, 0, 0, -1, { NULL, - 50, + 42, HKF_STATUS_INVALID, /* Would be ok if key not parsed */ 0, NULL, diff --git a/regress/unittests/hostkeys/testdata/dsa_1.pub b/regress/unittests/hostkeys/testdata/dsa_1.pub deleted file mode 100644 index 56e1e37..0000000 --- a/regress/unittests/hostkeys/testdata/dsa_1.pub +++ /dev/null @@ -1 +0,0 @@ -ssh-dss AAAAB3NzaC1kc3MAAACBAOqffHxEW4c+Z9q/r3l4sYK8F7qrBsU8XF9upGsW62T9InROFFq9IO0x3pQ6mDA0Wtw0sqcDmkPCHPyP4Ok/fU3/drLaZusHoVYu8pBBrWsIDrKgkeX9TEodBsSrYdl4Sqtqq9EZv9+DttV6LStZrgYyUTOKwOF95wGantpLynX5AAAAFQDdt+zjRNlETDsgmxcSYFgREirJrQAAAIBQlrPaiPhR24FhnMLcHH4016vL7AqDDID6Qw7PhbXGa4/XlxWMIigjBKrIPKvnZ6p712LSnCKtcbfdx0MtmJlNa01CYqPaRhgRaf+uGdvTkTUcdaq8R5lLJL+JMNwUhcC8ijm3NqEjXjffuebGe1EzIeiITbA7Nndcd+GytwRDegAAAIEAkRYPjSVcUxfUHhHdpP6V8CuY1+CYSs9EPJ7iiWTDuXWVIBTU32oJLAnrmAcOwtIzEfPvm+rff5FI/Yhon2pB3VTXhPPEBjYzE5qANanAT4e6tzAVc5f3DUhHaDknwRYfDz86GFvuLtDjeE/UZ9t6OofYoEsCBpYozLAprBvNIQY= DSA #1 diff --git a/regress/unittests/hostkeys/testdata/dsa_2.pub b/regress/unittests/hostkeys/testdata/dsa_2.pub deleted file mode 100644 index 394e0bf..0000000 --- a/regress/unittests/hostkeys/testdata/dsa_2.pub +++ /dev/null @@ -1 +0,0 @@ -ssh-dss AAAAB3NzaC1kc3MAAACBAI38Hy/61/O5Bp6yUG8J5XQCeNjRS0xvjlCdzKLyXCueMa+L+X2L/u9PWUsy5SVbTjGgpB8sF6UkCNsV+va7S8zCCHas2MZ7GPlxP6GZBkRPTIFR0N/Pu7wfBzDQz0t0iL4VmxBfTBQv/SxkGWZg+yHihIQP9fwdSAwD/7aVh6ItAAAAFQDSyihIUlINlswM0PJ8wXSti3yIMwAAAIB+oqzaB6ozqs8YxpN5oQOBa/9HEBQEsp8RSIlQmVubXRNgktp42n+Ii1waU9UUk8DX5ahhIeR6B7ojWkqmDAji4SKpoHf4kmr6HvYo85ZSTSx0W4YK/gJHSpDJwhlT52tAfb1JCbWSObjl09B4STv7KedCHcR5oXQvvrV+XoKOSAAAAIAue/EXrs2INw1RfaKNHC0oqOMxmRitv0BFMuNVPo1VDj39CE5kA7AHjwvS1TNeaHtK5Hhgeb6vsmLmNPTOc8xCob0ilyQbt9O0GbONeF2Ge7D2UJyULA/hxql+tCYFIC6yUrmo35fF9XiNisXLoaflk9fjp7ROWWVwnki/jstaQw== DSA #2 diff --git a/regress/unittests/hostkeys/testdata/dsa_3.pub b/regress/unittests/hostkeys/testdata/dsa_3.pub deleted file mode 100644 index e506ea4..0000000 --- a/regress/unittests/hostkeys/testdata/dsa_3.pub +++ /dev/null @@ -1 +0,0 @@ -ssh-dss AAAAB3NzaC1kc3MAAACBAI6lz2Ip9bzE7TGuDD4SjO9S4Ac90gq0h6ai1O06eI8t/Ot2uJ5Jk2QyVr2jvIZHDl/5bwBx7+5oyjlwRoUrAPPD814wf5tU2tSnmdu1Wbf0cBswif5q0r4tevzmopp/AtgH11QHo3u0/pfyJd10qBDLV2FaYSKMmZvyPfZJ0s9pAAAAFQD5Eqjl6Rx2qVePodD9OwAPT0bU6wAAAIAfnDm6csZF0sFaJR3NIJvaYgSGr8s7cqlsk2gLltB/1wOOO2yX+NeEC+B0H93hlMfaUsPa08bwgmYxnavSMqEBpmtPceefJiEd68zwYqXd38f88wyWZ9Z5iwaI/6OVZPHzCbDxOa4ewVTevRNYUKP1xUTZNT8/gSMfZLYPk4T2AQAAAIAUKroozRMyV+3V/rxt0gFnNxRXBKk+9cl3vgsQ7ktkI9cYg7V1T2K0XF21AVMK9gODszy6PBJjV6ruXBV6TRiqIbQauivp3bHHKYsG6wiJNqwdbVwIjfvv8nn1qFoZQLXG3sdONr9NwN8KzrX89OV0BlR2dVM5qqp+YxOXymP9yg== DSA #3 diff --git a/regress/unittests/hostkeys/testdata/dsa_4.pub b/regress/unittests/hostkeys/testdata/dsa_4.pub deleted file mode 100644 index 8552c38..0000000 --- a/regress/unittests/hostkeys/testdata/dsa_4.pub +++ /dev/null @@ -1 +0,0 @@ -ssh-dss AAAAB3NzaC1kc3MAAACBAKvjnFHm0VvMr5h2Zu3nURsxQKGoxm+DCzYDxRYcilK07Cm5c4XTrFbA2X86+9sGs++W7QRMcTJUYIg0a+UtIMtAjwORd6ZPXM2K5dBW+gh1oHyvKi767tWX7I2c+1ZPJDY95mUUfZQUEfdy9eGDSBmw/pSsveQ1ur6XNUh/MtP/AAAAFQDHnXk/9jBJAdce1pHtLWnbdPSGdQAAAIEAm2OLy8tZBfiEO3c3X1yyB/GTcDwrQCqRMDkhnsmrliec3dWkOfNTzu+MrdvF8ymTWLEqPpbMheYtvNyZ3TF0HO5W7aVBpdGZbOdOAIfB+6skqGbI8A5Up1d7dak/bSsqL2r5NjwbDOdq+1hBzzvbl/qjh+sQarV2zHrpKoQaV28AAACANtkBVedBbqIAdphCrN/LbUi9WlyuF9UZz+tlpVLYrj8GJVwnplV2tvOmUw6yP5/pzCimTsao8dpL5PWxm7fKxLWVxA+lEsA4WeC885CiZn8xhdaJOCN+NyJ2bqkz+4VPI7oDGBm0aFwUqJn+M1PiSgvI50XdF2dBsFRTRNY0wzA= DSA #4 diff --git a/regress/unittests/hostkeys/testdata/dsa_5.pub b/regress/unittests/hostkeys/testdata/dsa_5.pub deleted file mode 100644 index 149e1ef..0000000 --- a/regress/unittests/hostkeys/testdata/dsa_5.pub +++ /dev/null @@ -1 +0,0 @@ -ssh-dss AAAAB3NzaC1kc3MAAACBALrFy7w5ihlaOG+qR+6fj+vm5EQaO3qwxgACLcgH+VfShuOG4mkx8qFJmf+OZ3fh5iKngjNZfKtfcqI7zHWdk6378TQfQC52/kbZukjNXOLCpyNkogahcjA00onIoTK1RUDuMW28edAHwPFbpttXDTaqis+8JPMY8hZwsZGENCzTAAAAFQD6+It5vozwGgaN9ROYPMlByhi6jwAAAIBz2mcAC694vNzz9b6614gkX9d9E99PzJYfU1MPkXDziKg7MrjBw7Opd5y1jL09S3iL6lSTlHkKwVKvQ3pOwWRwXXRrKVus4I0STveoApm526jmp6mY0YEtqR98vMJ0v97h1ydt8FikKlihefCsnXVicb8887PXs2Y8C6GuFT3tfQAAAIBbmHtV5tPcrMRDkULhaQ/Whap2VKvT2DUhIHA7lx6oy/KpkltOpxDZOIGUHKqffGbiR7Jh01/y090AY5L2eCf0S2Ytx93+eADwVVpJbFJo6zSwfeey2Gm6L2oA+rCz9zTdmtZoekpD3/RAOQjnJIAPwbs7mXwabZTw4xRtiYIRrw== DSA #5 diff --git a/regress/unittests/hostkeys/testdata/dsa_6.pub b/regress/unittests/hostkeys/testdata/dsa_6.pub deleted file mode 100644 index edbb976..0000000 --- a/regress/unittests/hostkeys/testdata/dsa_6.pub +++ /dev/null @@ -1 +0,0 @@ -ssh-dss AAAAB3NzaC1kc3MAAACBAIutigAse65TCW6hHDOEGXenE9L4L0talHbs65hj3UUNtWflKdQeXLofqXgW8AwaDKmnuRPrxRoxVNXj84n45wtBEdt4ztmdAZteAbXSnHqpcxME3jDxh3EtxzGPXLs+RUmKPVguraSgo7W2oN7KFx6VM+AcAtxANSTlvDid3s47AAAAFQCd9Q3kkHSLWe77sW0eRaayI45ovwAAAIAw6srGF6xvFasI44Y3r9JJ2K+3ezozl3ldL3p2+p2HG3iWafC4SdV8pB6ZIxKlYAywiiFb3LzH/JweGFq1jtoFDRM3MlYORBevydU4zPz7b5QLDVB0sY4evYtWmg2BFJvoWRfhLnlZVW7h5N8v4fNIwdVmVsw4Ljes7iF2HRGhHgAAAIBDFT3fww2Oby1xUA6G9pDAcVikrQFqp1sJRylNTUyeyQ37SNAGzYxwHJFgQr8gZLdRQ1UW+idYpqVbVNcYFMOiw/zSqK2OfVwPZ9U+TTKdc992ChSup6vJEKM/ZVIyDWDbJr7igQ4ahy7jo9mFvm8ljN926EnspQzCvs0Dxk6tHA== DSA #6 diff --git a/regress/unittests/hostkeys/testdata/known_hosts b/regress/unittests/hostkeys/testdata/known_hosts index 4446f45..5298e3e 100644 --- a/regress/unittests/hostkeys/testdata/known_hosts +++ b/regress/unittests/hostkeys/testdata/known_hosts @@ -1,30 +1,23 @@ # Plain host keys, plain host names -sisyphus.example.com ssh-dss AAAAB3NzaC1kc3MAAACBAOqffHxEW4c+Z9q/r3l4sYK8F7qrBsU8XF9upGsW62T9InROFFq9IO0x3pQ6mDA0Wtw0sqcDmkPCHPyP4Ok/fU3/drLaZusHoVYu8pBBrWsIDrKgkeX9TEodBsSrYdl4Sqtqq9EZv9+DttV6LStZrgYyUTOKwOF95wGantpLynX5AAAAFQDdt+zjRNlETDsgmxcSYFgREirJrQAAAIBQlrPaiPhR24FhnMLcHH4016vL7AqDDID6Qw7PhbXGa4/XlxWMIigjBKrIPKvnZ6p712LSnCKtcbfdx0MtmJlNa01CYqPaRhgRaf+uGdvTkTUcdaq8R5lLJL+JMNwUhcC8ijm3NqEjXjffuebGe1EzIeiITbA7Nndcd+GytwRDegAAAIEAkRYPjSVcUxfUHhHdpP6V8CuY1+CYSs9EPJ7iiWTDuXWVIBTU32oJLAnrmAcOwtIzEfPvm+rff5FI/Yhon2pB3VTXhPPEBjYzE5qANanAT4e6tzAVc5f3DUhHaDknwRYfDz86GFvuLtDjeE/UZ9t6OofYoEsCBpYozLAprBvNIQY= DSA #1 sisyphus.example.com ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBF6yQEtD9yBw9gmDRf477WBBzvWhAa0ioBI3nbA4emKykj0RbuQd5C4XdQAEOZGzE7v//FcCjwB2wi+JH5eKkxCtN6CjohDASZ1huoIV2UVyYIicZJEEOg1IWjjphvaxtw== ECDSA #1 sisyphus.example.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK9ks7jkua5YWIwByRnnnc6UPJQWI75O0e/UJdPYU1JI ED25519 #1 sisyphus.example.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDg4hB4vAZHJ0PVRiJajOv/GlytFWNpv5/9xgB9+5BIbvp8LOrFZ5D9K0Gsmwpd4G4rfaAz8j896DhMArg0vtkilIPPGt/6VzWMERgvaIQPJ/IE99X3+fjcAG56oAWwy29JX10lQMzBPU6XJIaN/zqpkb6qUBiAHBdLpxrFBBU0/w== RSA #1 # Plain host keys, hostnames + addresses -prometheus.example.com,192.0.2.1,2001:db8::1 ssh-dss AAAAB3NzaC1kc3MAAACBAI38Hy/61/O5Bp6yUG8J5XQCeNjRS0xvjlCdzKLyXCueMa+L+X2L/u9PWUsy5SVbTjGgpB8sF6UkCNsV+va7S8zCCHas2MZ7GPlxP6GZBkRPTIFR0N/Pu7wfBzDQz0t0iL4VmxBfTBQv/SxkGWZg+yHihIQP9fwdSAwD/7aVh6ItAAAAFQDSyihIUlINlswM0PJ8wXSti3yIMwAAAIB+oqzaB6ozqs8YxpN5oQOBa/9HEBQEsp8RSIlQmVubXRNgktp42n+Ii1waU9UUk8DX5ahhIeR6B7ojWkqmDAji4SKpoHf4kmr6HvYo85ZSTSx0W4YK/gJHSpDJwhlT52tAfb1JCbWSObjl09B4STv7KedCHcR5oXQvvrV+XoKOSAAAAIAue/EXrs2INw1RfaKNHC0oqOMxmRitv0BFMuNVPo1VDj39CE5kA7AHjwvS1TNeaHtK5Hhgeb6vsmLmNPTOc8xCob0ilyQbt9O0GbONeF2Ge7D2UJyULA/hxql+tCYFIC6yUrmo35fF9XiNisXLoaflk9fjp7ROWWVwnki/jstaQw== DSA #2 prometheus.example.com,192.0.2.1,2001:db8::1 ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAB8qVcXwgBM92NCmReQlPrZAoui4Bz/mW0VUBFOpHXXW1n+15b/Y7Pc6UBd/ITTZmaBciXY+PWaSBGdwc5GdqGdLgFyJ/QAGrFMPNpVutm/82gNQzlxpNwjbMcKyiZEXzSgnjS6DzMQ0WuSMdzIBXq8OW/Kafxg4ZkU6YqALUXxlQMZuQ== ECDSA #2 prometheus.example.com,192.0.2.1,2001:db8::1 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIBp6PVW0z2o9C4Ukv/JOgmK7QMFe1pD1s3ADFF7IQob ED25519 #2 prometheus.example.com,192.0.2.1,2001:db8::1 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDmbUhNabB5AmBDX6GNHZ3lbn7pRxqfpW+f53QqNGlK0sLV+0gkMIrOfUp1kdE2ZLE6tfzdicatj/RlH6/wuo4yyYb+Pyx3G0vxdmAIiA4aANq38XweDucBC0TZkRWVHK+Gs5V/uV0z7N0axJvkkJujMLvST3CRiiWwlficBc6yVQ== RSA #2 # Some hosts with wildcard names / IPs -*.example.com,192.0.2.*,2001:* ssh-dss AAAAB3NzaC1kc3MAAACBAI6lz2Ip9bzE7TGuDD4SjO9S4Ac90gq0h6ai1O06eI8t/Ot2uJ5Jk2QyVr2jvIZHDl/5bwBx7+5oyjlwRoUrAPPD814wf5tU2tSnmdu1Wbf0cBswif5q0r4tevzmopp/AtgH11QHo3u0/pfyJd10qBDLV2FaYSKMmZvyPfZJ0s9pAAAAFQD5Eqjl6Rx2qVePodD9OwAPT0bU6wAAAIAfnDm6csZF0sFaJR3NIJvaYgSGr8s7cqlsk2gLltB/1wOOO2yX+NeEC+B0H93hlMfaUsPa08bwgmYxnavSMqEBpmtPceefJiEd68zwYqXd38f88wyWZ9Z5iwaI/6OVZPHzCbDxOa4ewVTevRNYUKP1xUTZNT8/gSMfZLYPk4T2AQAAAIAUKroozRMyV+3V/rxt0gFnNxRXBKk+9cl3vgsQ7ktkI9cYg7V1T2K0XF21AVMK9gODszy6PBJjV6ruXBV6TRiqIbQauivp3bHHKYsG6wiJNqwdbVwIjfvv8nn1qFoZQLXG3sdONr9NwN8KzrX89OV0BlR2dVM5qqp+YxOXymP9yg== DSA #3 *.example.com,192.0.2.*,2001:* ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBIb3BhJZk+vUQPg5TQc1koIzuGqloCq7wjr9LjlhG24IBeiFHLsdWw74HDlH4DrOmlxToVYk2lTdnjARleRByjk= ECDSA #3 *.example.com,192.0.2.*,2001:* ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBlYfExtYZAPqYvYdrlpGlSWhh/XNHcH3v3c2JzsVNbB ED25519 #3 *.example.com,192.0.2.*,2001:* ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDX8F93W3SH4ZSus4XUQ2cw9dqcuyUETTlKEeGv3zlknV3YCoe2Mp04naDhiuwj8sOsytrZSESzLY1ZEyzrjxE6ZFVv8NKgck/AbRjcwlRFOcx9oKUxOrXRa0IoXlTq0kyjKCJfaHBKnGitZThknCPTbVmpATkm5xx6J0WEDozfoQ== RSA #3 # Hashed hostname and address entries -|1|z3xOIdT5ue3Vuf3MzT67kaioqjw=|GZhhe5uwDOBQrC9N4cCjpbLpSn4= ssh-dss AAAAB3NzaC1kc3MAAACBALrFy7w5ihlaOG+qR+6fj+vm5EQaO3qwxgACLcgH+VfShuOG4mkx8qFJmf+OZ3fh5iKngjNZfKtfcqI7zHWdk6378TQfQC52/kbZukjNXOLCpyNkogahcjA00onIoTK1RUDuMW28edAHwPFbpttXDTaqis+8JPMY8hZwsZGENCzTAAAAFQD6+It5vozwGgaN9ROYPMlByhi6jwAAAIBz2mcAC694vNzz9b6614gkX9d9E99PzJYfU1MPkXDziKg7MrjBw7Opd5y1jL09S3iL6lSTlHkKwVKvQ3pOwWRwXXRrKVus4I0STveoApm526jmp6mY0YEtqR98vMJ0v97h1ydt8FikKlihefCsnXVicb8887PXs2Y8C6GuFT3tfQAAAIBbmHtV5tPcrMRDkULhaQ/Whap2VKvT2DUhIHA7lx6oy/KpkltOpxDZOIGUHKqffGbiR7Jh01/y090AY5L2eCf0S2Ytx93+eADwVVpJbFJo6zSwfeey2Gm6L2oA+rCz9zTdmtZoekpD3/RAOQjnJIAPwbs7mXwabZTw4xRtiYIRrw== DSA #5 |1|B7t/AYabn8zgwU47Cb4A/Nqt3eI=|arQPZyRphkzisr7w6wwikvhaOyE= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPIudcagzq4QPtP1jkpje34+0POLB0jwT64hqrbCqhTH2T800KDZ0h2vwlJYa3OP3Oqru9AB5pnuHsKw7mAhUGY= ECDSA #5 |1|JR81WxEocTP5d7goIRkl8fHBbno=|l6sj6FOsoXxgEZMzn/BnOfPKN68= ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINf63qSV8rD57N+digID8t28WVhd3Yf2K2UhaoG8TsWQ ED25519 #5 |1|W7x4zY6KtTZJgsopyOusJqvVPag=|QauLt7hKezBZFZi2i4Xopho7Nsk= ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC/C15Q4sfnk7BZff1er8bscay+5s51oD4eWArlHWMK/ZfYeeTAccTy+7B7Jv+MS4nKCpflrvJI2RQz4kS8vF0ATdBbi4jeWefStlHNg0HLhnCY7NAfDIlRdaN9lm3Pqm2vmr+CkqwcJaSpycDg8nPN9yNAuD6pv7NDuUnECezojQ== RSA #5 -|1|mxnU8luzqWLvfVi5qBm5xVIyCRM=|9Epopft7LBd80Bf6RmWPIpwa8yU= ssh-dss AAAAB3NzaC1kc3MAAACBAIutigAse65TCW6hHDOEGXenE9L4L0talHbs65hj3UUNtWflKdQeXLofqXgW8AwaDKmnuRPrxRoxVNXj84n45wtBEdt4ztmdAZteAbXSnHqpcxME3jDxh3EtxzGPXLs+RUmKPVguraSgo7W2oN7KFx6VM+AcAtxANSTlvDid3s47AAAAFQCd9Q3kkHSLWe77sW0eRaayI45ovwAAAIAw6srGF6xvFasI44Y3r9JJ2K+3ezozl3ldL3p2+p2HG3iWafC4SdV8pB6ZIxKlYAywiiFb3LzH/JweGFq1jtoFDRM3MlYORBevydU4zPz7b5QLDVB0sY4evYtWmg2BFJvoWRfhLnlZVW7h5N8v4fNIwdVmVsw4Ljes7iF2HRGhHgAAAIBDFT3fww2Oby1xUA6G9pDAcVikrQFqp1sJRylNTUyeyQ37SNAGzYxwHJFgQr8gZLdRQ1UW+idYpqVbVNcYFMOiw/zSqK2OfVwPZ9U+TTKdc992ChSup6vJEKM/ZVIyDWDbJr7igQ4ahy7jo9mFvm8ljN926EnspQzCvs0Dxk6tHA== DSA #6 -|1|klvLmvh2vCpkNMDEjVvrE8SJWTg=|e/dqEEBLnbgqmwEesl4cDRu/7TM= ssh-dss AAAAB3NzaC1kc3MAAACBAIutigAse65TCW6hHDOEGXenE9L4L0talHbs65hj3UUNtWflKdQeXLofqXgW8AwaDKmnuRPrxRoxVNXj84n45wtBEdt4ztmdAZteAbXSnHqpcxME3jDxh3EtxzGPXLs+RUmKPVguraSgo7W2oN7KFx6VM+AcAtxANSTlvDid3s47AAAAFQCd9Q3kkHSLWe77sW0eRaayI45ovwAAAIAw6srGF6xvFasI44Y3r9JJ2K+3ezozl3ldL3p2+p2HG3iWafC4SdV8pB6ZIxKlYAywiiFb3LzH/JweGFq1jtoFDRM3MlYORBevydU4zPz7b5QLDVB0sY4evYtWmg2BFJvoWRfhLnlZVW7h5N8v4fNIwdVmVsw4Ljes7iF2HRGhHgAAAIBDFT3fww2Oby1xUA6G9pDAcVikrQFqp1sJRylNTUyeyQ37SNAGzYxwHJFgQr8gZLdRQ1UW+idYpqVbVNcYFMOiw/zSqK2OfVwPZ9U+TTKdc992ChSup6vJEKM/ZVIyDWDbJr7igQ4ahy7jo9mFvm8ljN926EnspQzCvs0Dxk6tHA== DSA #6 -|1|wsk3ddB3UjuxEsoeNCeZjZ6NvZs=|O3O/q2Z/u7DrxoTiIq6kzCevQT0= ssh-dss AAAAB3NzaC1kc3MAAACBAIutigAse65TCW6hHDOEGXenE9L4L0talHbs65hj3UUNtWflKdQeXLofqXgW8AwaDKmnuRPrxRoxVNXj84n45wtBEdt4ztmdAZteAbXSnHqpcxME3jDxh3EtxzGPXLs+RUmKPVguraSgo7W2oN7KFx6VM+AcAtxANSTlvDid3s47AAAAFQCd9Q3kkHSLWe77sW0eRaayI45ovwAAAIAw6srGF6xvFasI44Y3r9JJ2K+3ezozl3ldL3p2+p2HG3iWafC4SdV8pB6ZIxKlYAywiiFb3LzH/JweGFq1jtoFDRM3MlYORBevydU4zPz7b5QLDVB0sY4evYtWmg2BFJvoWRfhLnlZVW7h5N8v4fNIwdVmVsw4Ljes7iF2HRGhHgAAAIBDFT3fww2Oby1xUA6G9pDAcVikrQFqp1sJRylNTUyeyQ37SNAGzYxwHJFgQr8gZLdRQ1UW+idYpqVbVNcYFMOiw/zSqK2OfVwPZ9U+TTKdc992ChSup6vJEKM/ZVIyDWDbJr7igQ4ahy7jo9mFvm8ljN926EnspQzCvs0Dxk6tHA== DSA #6 |1|B8epmkLSni+vGZDijr/EwxeR2k4=|7ct8yzNOVJhKm3ZD2w0XIT7df8E= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBK1wRLyKtvK3Mmhd0XPkKwW4ev1KBVf8J4aG8lESq1TsaqqfOXYGyxMq5pN8fCGiD5UPOqyTYz/ZNzClRhJRHao= ECDSA #6 |1|JojD885UhYhbCu571rgyM/5PpYU=|BJaU2aE1FebQZy3B5tzTDRWFRG0= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBK1wRLyKtvK3Mmhd0XPkKwW4ev1KBVf8J4aG8lESq1TsaqqfOXYGyxMq5pN8fCGiD5UPOqyTYz/ZNzClRhJRHao= ECDSA #6 |1|5t7UDHDybVrDZVQPCpwdnr6nk4k=|EqJ73W/veIL3H2x+YWHcJxI5ETA= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBK1wRLyKtvK3Mmhd0XPkKwW4ev1KBVf8J4aG8lESq1TsaqqfOXYGyxMq5pN8fCGiD5UPOqyTYz/ZNzClRhJRHao= ECDSA #6 @@ -39,12 +32,11 @@ prometheus.example.com,192.0.2.1,2001:db8::1 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAA # Revoked and CA keys @revoked sisyphus.example.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDFP8L9REfN/iYy1KIRtFqSCn3V2+vOCpoZYENFGLdOF ED25519 #4 @cert-authority prometheus.example.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBHZd0OXHIWwK3xnjAdMZ1tojxWycdu38pORO/UX5cqsKMgGCKQVBWWO3TFk1ePkGIE9VMWT1hCGqWRRwYlH+dSE= ECDSA #4 -@cert-authority *.example.com ssh-dss AAAAB3NzaC1kc3MAAACBAKvjnFHm0VvMr5h2Zu3nURsxQKGoxm+DCzYDxRYcilK07Cm5c4XTrFbA2X86+9sGs++W7QRMcTJUYIg0a+UtIMtAjwORd6ZPXM2K5dBW+gh1oHyvKi767tWX7I2c+1ZPJDY95mUUfZQUEfdy9eGDSBmw/pSsveQ1ur6XNUh/MtP/AAAAFQDHnXk/9jBJAdce1pHtLWnbdPSGdQAAAIEAm2OLy8tZBfiEO3c3X1yyB/GTcDwrQCqRMDkhnsmrliec3dWkOfNTzu+MrdvF8ymTWLEqPpbMheYtvNyZ3TF0HO5W7aVBpdGZbOdOAIfB+6skqGbI8A5Up1d7dak/bSsqL2r5NjwbDOdq+1hBzzvbl/qjh+sQarV2zHrpKoQaV28AAACANtkBVedBbqIAdphCrN/LbUi9WlyuF9UZz+tlpVLYrj8GJVwnplV2tvOmUw6yP5/pzCimTsao8dpL5PWxm7fKxLWVxA+lEsA4WeC885CiZn8xhdaJOCN+NyJ2bqkz+4VPI7oDGBm0aFwUqJn+M1PiSgvI50XdF2dBsFRTRNY0wzA= DSA #4 # Some invalid lines -@what sisyphus.example.com ssh-dss AAAAB3NzaC1kc3MAAACBAOqffHxEW4c+Z9q/r3l4sYK8F7qrBsU8XF9upGsW62T9InROFFq9IO0x3pQ6mDA0Wtw0sqcDmkPCHPyP4Ok/fU3/drLaZusHoVYu8pBBrWsIDrKgkeX9TEodBsSrYdl4Sqtqq9EZv9+DttV6LStZrgYyUTOKwOF95wGantpLynX5AAAAFQDdt+zjRNlETDsgmxcSYFgREirJrQAAAIBQlrPaiPhR24FhnMLcHH4016vL7AqDDID6Qw7PhbXGa4/XlxWMIigjBKrIPKvnZ6p712LSnCKtcbfdx0MtmJlNa01CYqPaRhgRaf+uGdvTkTUcdaq8R5lLJL+JMNwUhcC8ijm3NqEjXjffuebGe1EzIeiITbA7Nndcd+GytwRDegAAAIEAkRYPjSVcUxfUHhHdpP6V8CuY1+CYSs9EPJ7iiWTDuXWVIBTU32oJLAnrmAcOwtIzEfPvm+rff5FI/Yhon2pB3VTXhPPEBjYzE5qANanAT4e6tzAVc5f3DUhHaDknwRYfDz86GFvuLtDjeE/UZ9t6OofYoEsCBpYozLAprBvNIQY= DSA #1 +@what ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDg4hB4vAZHJ0PVRiJajOv/GlytFWNpv5/9xgB9+5BIbvp8LOrFZ5D9K0Gsmwpd4G4rfaAz8j896DhMArg0vtkilIPPGt/6VzWMERgvaIQPJ/IE99X3+fjcAG56oAWwy29JX10lQMzBPU6XJIaN/zqpkb6qUBiAHBdLpxrFBBU0/w== RSA #1 sisyphus.example.com prometheus.example.com ssh-ed25519 -sisyphus.example.com ssh-dsa AAAATgAAAAdz +sisyphus.example.com ssh-ed25519 AAAATgAAAAdz sisyphus.example.com ssh-XXX AAAATgAAAAdzc2gtWFhYAAAAP0ZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRg== prometheus.example.com ssh-rsa AAAATgAAAAdzc2gtWFhYAAAAP0ZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRg== diff --git a/regress/unittests/hostkeys/tests.c b/regress/unittests/hostkeys/tests.c index 92c7646..c6e17fa 100644 --- a/regress/unittests/hostkeys/tests.c +++ b/regress/unittests/hostkeys/tests.c @@ -1,10 +1,16 @@ -/* $OpenBSD: tests.c,v 1.1 2015/02/16 22:18:34 djm Exp $ */ +/* $OpenBSD: tests.c,v 1.2 2025/04/15 04:00:42 djm Exp $ */ /* * Regress test for known_hosts-related API. * * Placed in the public domain */ +#include "includes.h" + +#include + +#include "../test_helper/test_helper.h" + void tests(void); void test_iterate(void); /* test_iterate.c */ @@ -14,3 +20,8 @@ tests(void) test_iterate(); } +void +benchmarks(void) +{ + printf("no benchmarks\n"); +} diff --git a/regress/unittests/kex/Makefile b/regress/unittests/kex/Makefile index ca4f0ee..5201a35 100644 --- a/regress/unittests/kex/Makefile +++ b/regress/unittests/kex/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.16 2024/09/09 03:13:39 djm Exp $ +# $OpenBSD: Makefile,v 1.19 2025/07/24 06:04:47 djm Exp $ PROG=test_kex SRCS=tests.c test_kex.c test_proposal.c @@ -6,12 +6,12 @@ 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+=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 SRCS+=cipher-chachapoly.c chacha.c poly1305.c ssh-ecdsa-sk.c ssh-sk.c -SRCS+=ssh-ed25519-sk.c sk-usbhid.c +SRCS+=ssh-ed25519-sk.c sk-usbhid.c ssh-pkcs11-client.c SRCS+= kex.c SRCS+= kex-names.c @@ -35,7 +35,7 @@ SRCS+=digest-openssl.c REGRESS_TARGETS=run-regress-${PROG} run-regress-${PROG}: ${PROG} - env ${TEST_ENV} ./${PROG} + env ${TEST_ENV} ./${PROG} ${UNITTEST_ARGS} .include diff --git a/regress/unittests/kex/test_kex.c b/regress/unittests/kex/test_kex.c index caf8f57..16c2f2d 100644 --- a/regress/unittests/kex/test_kex.c +++ b/regress/unittests/kex/test_kex.c @@ -1,4 +1,4 @@ -/* $OpenBSD: test_kex.c,v 1.9 2024/09/09 03:13:39 djm Exp $ */ +/* $OpenBSD: test_kex.c,v 1.12 2025/08/21 05:55:30 djm Exp $ */ /* * Regress test KEX * @@ -8,10 +8,9 @@ #include "includes.h" #include +#include #include -#ifdef HAVE_STDINT_H #include -#endif #include #include @@ -76,7 +75,8 @@ run_kex(struct ssh *client, struct ssh *server) } static void -do_kex_with_key(char *kex, int keytype, int bits) +do_kex_with_key(char *kex, char *cipher, char *mac, + struct sshkey *key, int keytype, int bits) { struct ssh *client = NULL, *server = NULL, *server2 = NULL; struct sshkey *private, *public; @@ -85,9 +85,14 @@ do_kex_with_key(char *kex, int keytype, int bits) char *myproposal[PROPOSAL_MAX] = { KEX_CLIENT }; char *keyname = NULL; - TEST_START("sshkey_generate"); - ASSERT_INT_EQ(sshkey_generate(keytype, bits, &private), 0); - TEST_DONE(); + if (key != NULL) { + private = key; + keytype = key->type; + } else { + TEST_START("sshkey_generate"); + ASSERT_INT_EQ(sshkey_generate(keytype, bits, &private), 0); + TEST_DONE(); + } TEST_START("sshkey_from_private"); ASSERT_INT_EQ(sshkey_from_private(private, &public), 0); @@ -97,6 +102,14 @@ do_kex_with_key(char *kex, int keytype, int bits) memcpy(kex_params.proposal, myproposal, sizeof(myproposal)); if (kex != NULL) kex_params.proposal[PROPOSAL_KEX_ALGS] = kex; + if (cipher != NULL) { + kex_params.proposal[PROPOSAL_ENC_ALGS_CTOS] = cipher; + kex_params.proposal[PROPOSAL_ENC_ALGS_STOC] = cipher; + } + if (mac != NULL) { + kex_params.proposal[PROPOSAL_MAC_ALGS_CTOS] = mac; + kex_params.proposal[PROPOSAL_MAC_ALGS_STOC] = mac; + } keyname = strdup(sshkey_ssh_name(private)); ASSERT_PTR_NE(keyname, NULL); kex_params.proposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = keyname; @@ -147,6 +160,9 @@ do_kex_with_key(char *kex, int keytype, int bits) server2->kex->kex[KEX_DH_GRP14_SHA1] = kex_gen_server; server2->kex->kex[KEX_DH_GEX_SHA1] = kexgex_server; server2->kex->kex[KEX_DH_GEX_SHA256] = kexgex_server; + server2->kex->kex[KEX_DH_GRP14_SHA256] = kex_gen_server; + server2->kex->kex[KEX_DH_GRP16_SHA512] = kex_gen_server; + server2->kex->kex[KEX_DH_GRP18_SHA512] = kex_gen_server; #ifdef OPENSSL_HAS_ECC server2->kex->kex[KEX_ECDH_SHA2] = kex_gen_server; #endif /* OPENSSL_HAS_ECC */ @@ -167,7 +183,8 @@ do_kex_with_key(char *kex, int keytype, int bits) TEST_DONE(); TEST_START("cleanup"); - sshkey_free(private); + if (key == NULL) + sshkey_free(private); sshkey_free(public); ssh_free(client); ssh_free(server); @@ -179,25 +196,40 @@ do_kex_with_key(char *kex, int keytype, int bits) static void do_kex(char *kex) { -#if 0 - log_init("test_kex", SYSLOG_LEVEL_DEBUG3, SYSLOG_FACILITY_AUTH, 1); -#endif + struct sshkey *key = NULL; + char name[256]; + + if (test_is_benchmark()) { + snprintf(name, sizeof(name), "generate %s", kex); + TEST_START(name); + ASSERT_INT_EQ(sshkey_generate(KEY_ED25519, 0, &key), 0); + TEST_DONE(); + snprintf(name, sizeof(name), "KEX %s", kex); + BENCH_START(name); + /* + * NB. use a cipher/MAC here that requires minimal bits from + * the KEX to avoid DH-GEX taking forever. + */ + do_kex_with_key(kex, "aes128-ctr", "hmac-sha2-256", key, + KEY_ED25519, 256); + BENCH_FINISH("kex"); + sshkey_free(key); + return; + } + #ifdef WITH_OPENSSL - do_kex_with_key(kex, KEY_RSA, 2048); -#ifdef WITH_DSA - do_kex_with_key(kex, KEY_DSA, 1024); -#endif -#ifdef OPENSSL_HAS_ECC - do_kex_with_key(kex, KEY_ECDSA, 256); -#endif /* OPENSSL_HAS_ECC */ + do_kex_with_key(kex, NULL, NULL, NULL, KEY_RSA, 2048); +# ifdef OPENSSL_HAS_ECC + do_kex_with_key(kex, NULL, NULL, NULL, KEY_ECDSA, 256); +# endif /* OPENSSL_HAS_ECC */ #endif /* WITH_OPENSSL */ - do_kex_with_key(kex, KEY_ED25519, 256); + do_kex_with_key(kex, NULL, NULL, NULL, KEY_ED25519, 256); } void kex_tests(void) { - do_kex("curve25519-sha256@libssh.org"); + do_kex("curve25519-sha256"); #ifdef WITH_OPENSSL #ifdef OPENSSL_HAS_ECC do_kex("ecdh-sha2-nistp256"); @@ -208,11 +240,16 @@ kex_tests(void) do_kex("diffie-hellman-group-exchange-sha1"); do_kex("diffie-hellman-group14-sha1"); do_kex("diffie-hellman-group1-sha1"); + if (test_is_benchmark()) { + do_kex("diffie-hellman-group14-sha256"); + do_kex("diffie-hellman-group16-sha512"); + do_kex("diffie-hellman-group18-sha512"); + } # ifdef USE_MLKEM768X25519 do_kex("mlkem768x25519-sha256"); # endif /* USE_MLKEM768X25519 */ # ifdef USE_SNTRUP761X25519 - do_kex("sntrup761x25519-sha512@openssh.com"); + do_kex("sntrup761x25519-sha512"); # endif /* USE_SNTRUP761X25519 */ #endif /* WITH_OPENSSL */ } diff --git a/regress/unittests/kex/test_proposal.c b/regress/unittests/kex/test_proposal.c index fa4192b..01bf7e5 100644 --- a/regress/unittests/kex/test_proposal.c +++ b/regress/unittests/kex/test_proposal.c @@ -10,9 +10,7 @@ #include #include #include -#ifdef HAVE_STDINT_H #include -#endif #include #include diff --git a/regress/unittests/kex/tests.c b/regress/unittests/kex/tests.c index d3044f0..a3ef19e 100644 --- a/regress/unittests/kex/tests.c +++ b/regress/unittests/kex/tests.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tests.c,v 1.3 2023/03/06 12:15:47 dtucker Exp $ */ +/* $OpenBSD: tests.c,v 1.4 2025/04/15 04:00:42 djm Exp $ */ /* * Placed in the public domain */ @@ -16,3 +16,10 @@ tests(void) kex_proposal_tests(); kex_proposal_populate_tests(); } + +void +benchmarks(void) +{ + printf("\n"); + kex_tests(); +} diff --git a/regress/unittests/match/Makefile b/regress/unittests/match/Makefile index 939163d..7b17e56 100644 --- a/regress/unittests/match/Makefile +++ b/regress/unittests/match/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.5 2021/01/09 12:24:31 dtucker Exp $ +# $OpenBSD: Makefile,v 1.6 2025/04/15 04:00:42 djm Exp $ PROG=test_match SRCS=tests.c @@ -11,6 +11,6 @@ SRCS+=cleanup.c atomicio.c addr.c REGRESS_TARGETS=run-regress-${PROG} run-regress-${PROG}: ${PROG} - env ${TEST_ENV} ./${PROG} + env ${TEST_ENV} ./${PROG} ${UNITTEST_ARGS} .include diff --git a/regress/unittests/match/tests.c b/regress/unittests/match/tests.c index f00d1f9..163a3a2 100644 --- a/regress/unittests/match/tests.c +++ b/regress/unittests/match/tests.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tests.c,v 1.8 2021/12/14 21:25:27 deraadt Exp $ */ +/* $OpenBSD: tests.c,v 1.9 2025/04/15 04:00:42 djm Exp $ */ /* * Regress test for matching functions * @@ -9,9 +9,7 @@ #include #include -#ifdef HAVE_STDINT_H #include -#endif #include #include @@ -129,3 +127,9 @@ tests(void) * int addr_match_cidr_list(const char *, const char *); */ } + +void +benchmarks(void) +{ + printf("no benchmarks\n"); +} diff --git a/regress/unittests/misc/Makefile b/regress/unittests/misc/Makefile index d2be393..7757506 100644 --- a/regress/unittests/misc/Makefile +++ b/regress/unittests/misc/Makefile @@ -1,7 +1,8 @@ -# $OpenBSD: Makefile,v 1.9 2023/01/06 02:59:50 djm Exp $ +# $OpenBSD: Makefile,v 1.12 2025/09/04 00:34:17 djm Exp $ PROG=test_misc SRCS=tests.c +SRCS+= test_misc.c SRCS+= test_convtime.c SRCS+= test_expand.c SRCS+= test_parse.c @@ -9,6 +10,7 @@ SRCS+= test_argv.c SRCS+= test_strdelim.c SRCS+= test_hpdelim.c SRCS+= test_ptimeout.c +SRCS+= test_xextendf.c # From usr.bin/ssh/Makefile.inc SRCS+= sshbuf.c @@ -28,6 +30,6 @@ SRCS+= atomicio.c cleanup.c fatal.c REGRESS_TARGETS=run-regress-${PROG} run-regress-${PROG}: ${PROG} - env ${TEST_ENV} ./${PROG} + env ${TEST_ENV} ./${PROG} ${UNITTEST_ARGS} .include diff --git a/regress/unittests/misc/test_argv.c b/regress/unittests/misc/test_argv.c index 682863e..a20a9e7 100644 --- a/regress/unittests/misc/test_argv.c +++ b/regress/unittests/misc/test_argv.c @@ -9,9 +9,7 @@ #include #include -#ifdef HAVE_STDINT_H #include -#endif #include #include diff --git a/regress/unittests/misc/test_convtime.c b/regress/unittests/misc/test_convtime.c index 4794dbd..4fdcf38 100644 --- a/regress/unittests/misc/test_convtime.c +++ b/regress/unittests/misc/test_convtime.c @@ -10,9 +10,7 @@ #include #include #include -#ifdef HAVE_STDINT_H #include -#endif #include #include diff --git a/regress/unittests/misc/test_expand.c b/regress/unittests/misc/test_expand.c index 6f2cd8a..a8be8d9 100644 --- a/regress/unittests/misc/test_expand.c +++ b/regress/unittests/misc/test_expand.c @@ -1,4 +1,4 @@ -/* $OpenBSD: test_expand.c,v 1.3 2021/12/14 21:25:27 deraadt Exp $ */ +/* $OpenBSD: test_expand.c,v 1.4 2025/09/15 03:00:22 djm Exp $ */ /* * Regress test for misc string expansion functions. * @@ -9,9 +9,7 @@ #include #include -#ifdef HAVE_STDINT_H #include -#endif #include #include @@ -73,17 +71,26 @@ test_expand(void) TEST_DONE(); TEST_START("percent_expand"); - ASSERT_STRING_EQ(percent_expand("%%", "%h", "foo", NULL), "%"); - ASSERT_STRING_EQ(percent_expand("%h", "h", "foo", NULL), "foo"); - ASSERT_STRING_EQ(percent_expand("%h ", "h", "foo", NULL), "foo "); - ASSERT_STRING_EQ(percent_expand(" %h", "h", "foo", NULL), " foo"); - ASSERT_STRING_EQ(percent_expand(" %h ", "h", "foo", NULL), " foo "); - ASSERT_STRING_EQ(percent_expand(" %a%b ", "a", "foo", "b", "bar", NULL), - " foobar "); +#define CHECK_ONE(val, expect) \ + ASSERT_STRING_EQ(val, expect); \ + free(val); + ret = percent_expand("%%", "%h", "foo", NULL); + CHECK_ONE(ret, "%"); + ret = percent_expand("%h", "h", "foo", NULL); + CHECK_ONE(ret, "foo"); + ret = percent_expand("%h ", "h", "foo", NULL); + CHECK_ONE(ret, "foo "); + ret = percent_expand(" %h", "h", "foo", NULL); + CHECK_ONE(ret, " foo"); + ret = percent_expand(" %h ", "h", "foo", NULL); + CHECK_ONE(ret, " foo "); + ret = percent_expand(" %a%b ", "a", "foo", "b", "bar", NULL); + CHECK_ONE(ret, " foobar "); TEST_DONE(); TEST_START("percent_dollar_expand"); - ASSERT_STRING_EQ(percent_dollar_expand("%h${FOO}", "h", "foo", NULL), - "foobar"); + ret = percent_dollar_expand("%h${FOO}", "h", "foo", NULL); + CHECK_ONE(ret, "foobar"); +#undef CHECK_ONE TEST_DONE(); } diff --git a/regress/unittests/misc/test_hpdelim.c b/regress/unittests/misc/test_hpdelim.c index d423023..626f185 100644 --- a/regress/unittests/misc/test_hpdelim.c +++ b/regress/unittests/misc/test_hpdelim.c @@ -9,9 +9,7 @@ #include #include -#ifdef HAVE_STDINT_H #include -#endif #include #include diff --git a/regress/unittests/misc/test_misc.c b/regress/unittests/misc/test_misc.c new file mode 100644 index 0000000..d175196 --- /dev/null +++ b/regress/unittests/misc/test_misc.c @@ -0,0 +1,436 @@ +/* + * Regress test for misc helper functions. + * + * Placed in the public domain. + */ + +#include "includes.h" + +#include +#include +#include +#include +#include + +#include "../test_helper/test_helper.h" + +#include "log.h" +#include "misc.h" +#include "xmalloc.h" + +void test_misc(void); + +static void +test_chop(void) +{ + char *s; + + TEST_START("chop newline"); + s = xstrdup("hello\n"); + ASSERT_STRING_EQ(chop(s), "hello"); + free(s); + TEST_DONE(); + + TEST_START("chop carriage return"); + s = xstrdup("hello\r"); + ASSERT_STRING_EQ(chop(s), "hello"); + free(s); + TEST_DONE(); + + TEST_START("chop CRLF"); + s = xstrdup("hello\r\n"); + ASSERT_STRING_EQ(chop(s), "hello"); + free(s); + TEST_DONE(); + + TEST_START("chop newline in middle"); + s = xstrdup("he\nllo"); + ASSERT_STRING_EQ(chop(s), "he"); + free(s); + TEST_DONE(); + + TEST_START("chop no newline"); + s = xstrdup("hello"); + ASSERT_STRING_EQ(chop(s), "hello"); + free(s); + TEST_DONE(); + + TEST_START("chop empty string"); + s = xstrdup(""); + ASSERT_STRING_EQ(chop(s), ""); + free(s); + TEST_DONE(); + + TEST_START("chop only newline"); + s = xstrdup("\n"); + ASSERT_STRING_EQ(chop(s), ""); + free(s); + TEST_DONE(); + + TEST_START("chop only CR"); + s = xstrdup("\r"); + ASSERT_STRING_EQ(chop(s), ""); + free(s); + TEST_DONE(); + + TEST_START("chop only CRLF"); + s = xstrdup("\r\n"); + ASSERT_STRING_EQ(chop(s), ""); + free(s); + TEST_DONE(); +} + +static void +test_rtrim(void) +{ + char *s; + + TEST_START("rtrim trailing space"); + s = xstrdup("hello "); + rtrim(s); + ASSERT_STRING_EQ(s, "hello"); + free(s); + TEST_DONE(); + + TEST_START("rtrim trailing tab"); + s = xstrdup("hello\t\t"); + rtrim(s); + ASSERT_STRING_EQ(s, "hello"); + free(s); + TEST_DONE(); + + TEST_START("rtrim trailing mixed whitespace"); + s = xstrdup("hello \t "); + rtrim(s); + ASSERT_STRING_EQ(s, "hello"); + free(s); + TEST_DONE(); + + TEST_START("rtrim no trailing whitespace"); + s = xstrdup("hello"); + rtrim(s); + ASSERT_STRING_EQ(s, "hello"); + free(s); + TEST_DONE(); + + TEST_START("rtrim whitespace in middle"); + s = xstrdup("he llo"); + rtrim(s); + ASSERT_STRING_EQ(s, "he llo"); + free(s); + TEST_DONE(); + + TEST_START("rtrim empty string"); + s = xstrdup(""); + rtrim(s); + ASSERT_STRING_EQ(s, ""); + free(s); + TEST_DONE(); + + TEST_START("rtrim only whitespace"); + s = xstrdup(" \t"); + rtrim(s); + ASSERT_STRING_EQ(s, ""); + free(s); + TEST_DONE(); +} + +static void +test_strprefix(void) +{ + const char *s; + + TEST_START("strprefix basic match"); + s = strprefix("hello world", "hello", 0); + ASSERT_PTR_NE(s, NULL); + ASSERT_STRING_EQ(s, " world"); + TEST_DONE(); + + TEST_START("strprefix no match"); + s = strprefix("hello world", "world", 0); + ASSERT_PTR_EQ(s, NULL); + TEST_DONE(); + + TEST_START("strprefix full match"); + s = strprefix("hello", "hello", 0); + ASSERT_PTR_NE(s, NULL); + ASSERT_STRING_EQ(s, ""); + TEST_DONE(); + + TEST_START("strprefix empty string"); + s = strprefix("", "hello", 0); + ASSERT_PTR_EQ(s, NULL); + TEST_DONE(); + + TEST_START("strprefix empty prefix"); + s = strprefix("hello", "", 0); + ASSERT_PTR_NE(s, NULL); + ASSERT_STRING_EQ(s, "hello"); + TEST_DONE(); + + TEST_START("strprefix case sensitive no match"); + s = strprefix("Hello world", "hello", 0); + ASSERT_PTR_EQ(s, NULL); + TEST_DONE(); + + TEST_START("strprefix case insensitive match"); + s = strprefix("Hello world", "hello", 1); + ASSERT_PTR_NE(s, NULL); + ASSERT_STRING_EQ(s, " world"); + TEST_DONE(); + + TEST_START("strprefix case insensitive full match"); + s = strprefix("HELLO", "hello", 1); + ASSERT_PTR_NE(s, NULL); + ASSERT_STRING_EQ(s, ""); + TEST_DONE(); +} + +static void +test_fmt_timeframe(void) +{ + TEST_START("fmt_timeframe seconds"); + ASSERT_STRING_EQ(fmt_timeframe(0), "00:00:00"); + ASSERT_STRING_EQ(fmt_timeframe(59), "00:00:59"); + ASSERT_STRING_EQ(fmt_timeframe(60), "00:01:00"); + ASSERT_STRING_EQ(fmt_timeframe(3599), "00:59:59"); + ASSERT_STRING_EQ(fmt_timeframe(3600), "01:00:00"); + ASSERT_STRING_EQ(fmt_timeframe(86399), "23:59:59"); + TEST_DONE(); + + TEST_START("fmt_timeframe days"); + ASSERT_STRING_EQ(fmt_timeframe(86400), "1d00h00m"); + ASSERT_STRING_EQ(fmt_timeframe(90061), "1d01h01m"); + ASSERT_STRING_EQ(fmt_timeframe(604799), "6d23h59m"); + TEST_DONE(); + + TEST_START("fmt_timeframe weeks"); + ASSERT_STRING_EQ(fmt_timeframe(604800), "01w0d00h"); + ASSERT_STRING_EQ(fmt_timeframe(694861), "01w1d01h"); + TEST_DONE(); +} + +static void +test_arglist(void) +{ + arglist args; + u_int i; + + memset(&args, 0, sizeof(args)); + + TEST_START("addargs initial"); + addargs(&args, "one"); + ASSERT_U_INT_EQ(args.num, 1); + ASSERT_U_INT_EQ(args.nalloc, 32); + ASSERT_PTR_NE(args.list, NULL); + ASSERT_STRING_EQ(args.list[0], "one"); + ASSERT_PTR_EQ(args.list[1], NULL); + TEST_DONE(); + + TEST_START("addargs second"); + addargs(&args, "two"); + ASSERT_U_INT_EQ(args.num, 2); + ASSERT_U_INT_EQ(args.nalloc, 32); + ASSERT_PTR_NE(args.list, NULL); + ASSERT_STRING_EQ(args.list[0], "one"); + ASSERT_STRING_EQ(args.list[1], "two"); + ASSERT_PTR_EQ(args.list[2], NULL); + TEST_DONE(); + + TEST_START("addargs with format"); + addargs(&args, "three=%d", 3); + ASSERT_U_INT_EQ(args.num, 3); + ASSERT_U_INT_EQ(args.nalloc, 32); + ASSERT_PTR_NE(args.list, NULL); + ASSERT_STRING_EQ(args.list[0], "one"); + ASSERT_STRING_EQ(args.list[1], "two"); + ASSERT_STRING_EQ(args.list[2], "three=3"); + ASSERT_PTR_EQ(args.list[3], NULL); + TEST_DONE(); + + TEST_START("replacearg middle"); + replacearg(&args, 1, "TWO!"); + ASSERT_U_INT_EQ(args.num, 3); + ASSERT_STRING_EQ(args.list[0], "one"); + ASSERT_STRING_EQ(args.list[1], "TWO!"); + ASSERT_STRING_EQ(args.list[2], "three=3"); + ASSERT_PTR_EQ(args.list[3], NULL); + TEST_DONE(); + + TEST_START("replacearg first"); + replacearg(&args, 0, "ONE!"); + ASSERT_U_INT_EQ(args.num, 3); + ASSERT_STRING_EQ(args.list[0], "ONE!"); + ASSERT_STRING_EQ(args.list[1], "TWO!"); + ASSERT_STRING_EQ(args.list[2], "three=3"); + ASSERT_PTR_EQ(args.list[3], NULL); + TEST_DONE(); + + TEST_START("replacearg last"); + replacearg(&args, 2, "THREE=3!"); + ASSERT_U_INT_EQ(args.num, 3); + ASSERT_STRING_EQ(args.list[0], "ONE!"); + ASSERT_STRING_EQ(args.list[1], "TWO!"); + ASSERT_STRING_EQ(args.list[2], "THREE=3!"); + ASSERT_PTR_EQ(args.list[3], NULL); + TEST_DONE(); + + TEST_START("replacearg with format"); + replacearg(&args, 1, "two=%d", 2); + ASSERT_U_INT_EQ(args.num, 3); + ASSERT_STRING_EQ(args.list[0], "ONE!"); + ASSERT_STRING_EQ(args.list[1], "two=2"); + ASSERT_STRING_EQ(args.list[2], "THREE=3!"); + ASSERT_PTR_EQ(args.list[3], NULL); + TEST_DONE(); + + TEST_START("addargs reallocation"); + for (i = args.num; i < 33; i++) + addargs(&args, "pad-%d", i); + ASSERT_U_INT_EQ(args.num, 33); + ASSERT_U_INT_GE(args.nalloc, 33); + ASSERT_STRING_EQ(args.list[32], "pad-32"); + ASSERT_PTR_EQ(args.list[33], NULL); + TEST_DONE(); + + TEST_START("freeargs"); + freeargs(&args); + ASSERT_U_INT_EQ(args.num, 0); + ASSERT_U_INT_EQ(args.nalloc, 0); + ASSERT_PTR_EQ(args.list, NULL); + TEST_DONE(); + + TEST_START("freeargs on NULL"); + freeargs(NULL); + TEST_DONE(); + + TEST_START("freeargs on empty"); + memset(&args, 0, sizeof(args)); + freeargs(&args); + ASSERT_U_INT_EQ(args.num, 0); + ASSERT_U_INT_EQ(args.nalloc, 0); + ASSERT_PTR_EQ(args.list, NULL); + TEST_DONE(); +} + +static void +test_tohex(void) +{ + char *hex; + + TEST_START("tohex simple"); + hex = tohex("foo", 3); + ASSERT_STRING_EQ(hex, "666f6f"); + free(hex); + TEST_DONE(); + + TEST_START("tohex with null"); + hex = tohex("a\0b", 3); + ASSERT_STRING_EQ(hex, "610062"); + free(hex); + TEST_DONE(); + + TEST_START("tohex empty"); + hex = tohex("", 0); + ASSERT_STRING_EQ(hex, ""); + free(hex); + TEST_DONE(); +} + +static void +test_lowercase(void) +{ + char *s; + + TEST_START("lowercase mixed"); + s = xstrdup("HeLlO WoRlD 123"); + lowercase(s); + ASSERT_STRING_EQ(s, "hello world 123"); + free(s); + TEST_DONE(); + + TEST_START("lowercase empty"); + s = xstrdup(""); + lowercase(s); + ASSERT_STRING_EQ(s, ""); + free(s); + TEST_DONE(); +} + +static void +test_path_absolute(void) +{ + TEST_START("path_absolute absolute"); + ASSERT_INT_EQ(path_absolute("/foo/bar"), 1); + TEST_DONE(); + + TEST_START("path_absolute relative"); + ASSERT_INT_EQ(path_absolute("foo/bar"), 0); + TEST_DONE(); + + TEST_START("path_absolute empty"); + ASSERT_INT_EQ(path_absolute(""), 0); + TEST_DONE(); +} + +static void +test_skip_space(void) +{ + char *s, *p; + + TEST_START("skip_space leading spaces"); + s = p = xstrdup(" hello"); + skip_space(&p); + ASSERT_STRING_EQ(p, "hello"); + free(s); + TEST_DONE(); + + TEST_START("skip_space leading tabs"); + s = p = xstrdup("\t\thello"); + skip_space(&p); + ASSERT_STRING_EQ(p, "hello"); + free(s); + TEST_DONE(); + + TEST_START("skip_space leading mixed whitespace"); + s = p = xstrdup(" \t hello"); + skip_space(&p); + ASSERT_STRING_EQ(p, "hello"); + free(s); + TEST_DONE(); + + TEST_START("skip_space no leading whitespace"); + s = p = xstrdup("hello"); + skip_space(&p); + ASSERT_STRING_EQ(p, "hello"); + free(s); + TEST_DONE(); + + TEST_START("skip_space empty string"); + s = p = xstrdup(""); + skip_space(&p); + ASSERT_STRING_EQ(p, ""); + free(s); + TEST_DONE(); + + TEST_START("skip_space only whitespace"); + s = p = xstrdup(" \t "); + skip_space(&p); + ASSERT_STRING_EQ(p, ""); + free(s); + TEST_DONE(); +} + +void +test_misc(void) +{ + test_chop(); + test_rtrim(); + test_strprefix(); + test_fmt_timeframe(); + test_arglist(); + test_tohex(); + test_lowercase(); + test_path_absolute(); + test_skip_space(); +} diff --git a/regress/unittests/misc/test_parse.c b/regress/unittests/misc/test_parse.c index 1f1ea31..cbffbe0 100644 --- a/regress/unittests/misc/test_parse.c +++ b/regress/unittests/misc/test_parse.c @@ -1,4 +1,4 @@ -/* $OpenBSD: test_parse.c,v 1.2 2021/12/14 21:25:27 deraadt Exp $ */ +/* $OpenBSD: test_parse.c,v 1.3 2025/06/12 10:09:39 dtucker Exp $ */ /* * Regress test for misc user/host/URI parsing functions. * @@ -9,9 +9,7 @@ #include #include -#ifdef HAVE_STDINT_H #include -#endif #include #include @@ -29,6 +27,7 @@ test_parse(void) char *user, *host, *path; TEST_START("misc_parse_user_host_path"); + user = host = path = NULL; ASSERT_INT_EQ(parse_user_host_path("someuser@some.host:some/path", &user, &host, &path), 0); ASSERT_STRING_EQ(user, "someuser"); @@ -38,6 +37,7 @@ test_parse(void) TEST_DONE(); TEST_START("misc_parse_user_ipv4_path"); + user = host = path = NULL; ASSERT_INT_EQ(parse_user_host_path("someuser@1.22.33.144:some/path", &user, &host, &path), 0); ASSERT_STRING_EQ(user, "someuser"); @@ -47,6 +47,7 @@ test_parse(void) TEST_DONE(); TEST_START("misc_parse_user_[ipv4]_path"); + user = host = path = NULL; ASSERT_INT_EQ(parse_user_host_path("someuser@[1.22.33.144]:some/path", &user, &host, &path), 0); ASSERT_STRING_EQ(user, "someuser"); @@ -56,6 +57,7 @@ test_parse(void) TEST_DONE(); TEST_START("misc_parse_user_[ipv4]_nopath"); + user = host = path = NULL; ASSERT_INT_EQ(parse_user_host_path("someuser@[1.22.33.144]:", &user, &host, &path), 0); ASSERT_STRING_EQ(user, "someuser"); @@ -65,6 +67,7 @@ test_parse(void) TEST_DONE(); TEST_START("misc_parse_user_ipv6_path"); + user = host = path = NULL; ASSERT_INT_EQ(parse_user_host_path("someuser@[::1]:some/path", &user, &host, &path), 0); ASSERT_STRING_EQ(user, "someuser"); @@ -74,6 +77,7 @@ test_parse(void) TEST_DONE(); TEST_START("misc_parse_uri"); + user = host = path = NULL; ASSERT_INT_EQ(parse_uri("ssh", "ssh://someuser@some.host:22/some/path", &user, &host, &port, &path), 0); ASSERT_STRING_EQ(user, "someuser"); diff --git a/regress/unittests/misc/test_ptimeout.c b/regress/unittests/misc/test_ptimeout.c index cc58ee8..f56e889 100644 --- a/regress/unittests/misc/test_ptimeout.c +++ b/regress/unittests/misc/test_ptimeout.c @@ -9,14 +9,10 @@ #include #include -#ifdef HAVE_STDINT_H -# include -#endif +#include #include #include -#ifdef HAVE_POLL_H -# include -#endif +#include #include #include "../test_helper/test_helper.h" diff --git a/regress/unittests/misc/test_strdelim.c b/regress/unittests/misc/test_strdelim.c index f7bea4b..ae0f715 100644 --- a/regress/unittests/misc/test_strdelim.c +++ b/regress/unittests/misc/test_strdelim.c @@ -9,9 +9,7 @@ #include #include -#ifdef HAVE_STDINT_H #include -#endif #include #include diff --git a/regress/unittests/misc/test_xextendf.c b/regress/unittests/misc/test_xextendf.c new file mode 100644 index 0000000..3c1ee8b --- /dev/null +++ b/regress/unittests/misc/test_xextendf.c @@ -0,0 +1,89 @@ +/* $OpenBSD: test_xextendf.c,v 1.1 2025/09/02 11:04:58 djm Exp $ */ +/* + * Regress test for misc xextendf() function. + * + * Placed in the public domain. + */ + +#include "includes.h" + +#include +#include +#include +#include +#include + +#include "../test_helper/test_helper.h" + +#include "log.h" +#include "misc.h" +#include "xmalloc.h" + +void test_xextendf(void); + +void +test_xextendf(void) +{ + char *s = NULL; + + TEST_START("xextendf NULL string"); + xextendf(&s, ",", "hello"); + ASSERT_STRING_EQ(s, "hello"); + free(s); + s = NULL; + TEST_DONE(); + + TEST_START("xextendf empty string"); + s = xstrdup(""); + xextendf(&s, ",", "world"); + ASSERT_STRING_EQ(s, "world"); + free(s); + s = NULL; + TEST_DONE(); + + TEST_START("xextendf append to string"); + s = xstrdup("foo"); + xextendf(&s, ",", "bar"); + ASSERT_STRING_EQ(s, "foo,bar"); + free(s); + s = NULL; + TEST_DONE(); + + TEST_START("xextendf append with NULL separator"); + s = xstrdup("foo"); + xextendf(&s, NULL, "bar"); + ASSERT_STRING_EQ(s, "foobar"); + free(s); + s = NULL; + TEST_DONE(); + + TEST_START("xextendf append with empty separator"); + s = xstrdup("foo"); + xextendf(&s, "", "bar"); + ASSERT_STRING_EQ(s, "foobar"); + free(s); + s = NULL; + TEST_DONE(); + + TEST_START("xextendf with format string"); + s = xstrdup("start"); + xextendf(&s, ":", "s=%s,d=%d", "string", 123); + ASSERT_STRING_EQ(s, "start:s=string,d=123"); + free(s); + s = NULL; + TEST_DONE(); + + TEST_START("xextendf multiple appends"); + s = NULL; + xextendf(&s, ",", "one"); + ASSERT_STRING_EQ(s, "one"); + xextendf(&s, ",", "two"); + ASSERT_STRING_EQ(s, "one,two"); + xextendf(&s, ":", "three=%d", 3); + ASSERT_STRING_EQ(s, "one,two:three=3"); + xextendf(&s, NULL, "four"); + ASSERT_STRING_EQ(s, "one,two:three=3four"); + free(s); + s = NULL; + TEST_DONE(); +} diff --git a/regress/unittests/misc/tests.c b/regress/unittests/misc/tests.c index 3269954..a71dde7 100644 --- a/regress/unittests/misc/tests.c +++ b/regress/unittests/misc/tests.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tests.c,v 1.10 2023/01/06 02:59:50 djm Exp $ */ +/* $OpenBSD: tests.c,v 1.13 2025/09/04 00:34:17 djm Exp $ */ /* * Regress test for misc helper functions. * @@ -9,9 +9,7 @@ #include #include -#ifdef HAVE_STDINT_H #include -#endif #include #include @@ -27,6 +25,8 @@ void test_argv(void); void test_strdelim(void); void test_hpdelim(void); void test_ptimeout(void); +void test_xextendf(void); +void test_misc(void); void tests(void) @@ -38,4 +38,12 @@ tests(void) test_strdelim(); test_hpdelim(); test_ptimeout(); + test_xextendf(); + test_misc(); +} + +void +benchmarks(void) +{ + printf("no benchmarks\n"); } diff --git a/regress/unittests/sshbuf/test_sshbuf.c b/regress/unittests/sshbuf/test_sshbuf.c index e22b390..dc021ba 100644 --- a/regress/unittests/sshbuf/test_sshbuf.c +++ b/regress/unittests/sshbuf/test_sshbuf.c @@ -10,9 +10,7 @@ #include #include -#ifdef HAVE_STDINT_H -# include -#endif +#include #include #include diff --git a/regress/unittests/sshbuf/test_sshbuf_fixed.c b/regress/unittests/sshbuf/test_sshbuf_fixed.c index dff77f0..cc05025 100644 --- a/regress/unittests/sshbuf/test_sshbuf_fixed.c +++ b/regress/unittests/sshbuf/test_sshbuf_fixed.c @@ -10,9 +10,7 @@ #include #include -#ifdef HAVE_STDINT_H -# include -#endif +#include #include #include diff --git a/regress/unittests/sshbuf/test_sshbuf_fuzz.c b/regress/unittests/sshbuf/test_sshbuf_fuzz.c index c0b809d..51838ee 100644 --- a/regress/unittests/sshbuf/test_sshbuf_fuzz.c +++ b/regress/unittests/sshbuf/test_sshbuf_fuzz.c @@ -9,9 +9,7 @@ #include #include -#ifdef HAVE_STDINT_H -# include -#endif +#include #include #include diff --git a/regress/unittests/sshbuf/test_sshbuf_getput_basic.c b/regress/unittests/sshbuf/test_sshbuf_getput_basic.c index 3da413e..bfe61a8 100644 --- a/regress/unittests/sshbuf/test_sshbuf_getput_basic.c +++ b/regress/unittests/sshbuf/test_sshbuf_getput_basic.c @@ -1,4 +1,4 @@ -/* $OpenBSD: test_sshbuf_getput_basic.c,v 1.3 2021/12/14 21:25:27 deraadt Exp $ */ +/* $OpenBSD: test_sshbuf_getput_basic.c,v 1.5 2025/09/15 03:00:22 djm Exp $ */ /* * Regress test for sshbuf.h buffer API * @@ -9,9 +9,7 @@ #include #include -#ifdef HAVE_STDINT_H -# include -#endif +#include #include #include @@ -576,6 +574,7 @@ sshbuf_getput_basic_tests(void) ASSERT_PTR_NE(s2, NULL); ASSERT_STRING_EQ(s2, "00000000000000000000"); sshbuf_free(p1); + free(s2); TEST_DONE(); TEST_START("sshbuf_poke_u32"); @@ -610,6 +609,7 @@ sshbuf_getput_basic_tests(void) ASSERT_PTR_NE(s2, NULL); ASSERT_STRING_EQ(s2, "00000000000000000000"); sshbuf_free(p1); + free(s2); TEST_DONE(); TEST_START("sshbuf_poke_u16"); @@ -644,6 +644,7 @@ sshbuf_getput_basic_tests(void) ASSERT_PTR_NE(s2, NULL); ASSERT_STRING_EQ(s2, "00000000000000000000"); sshbuf_free(p1); + free(s2); TEST_DONE(); TEST_START("sshbuf_poke_u8"); @@ -674,6 +675,7 @@ sshbuf_getput_basic_tests(void) ASSERT_PTR_NE(s2, NULL); ASSERT_STRING_EQ(s2, "00000000000000000000"); sshbuf_free(p1); + free(s2); TEST_DONE(); TEST_START("sshbuf_poke"); @@ -708,5 +710,6 @@ sshbuf_getput_basic_tests(void) ASSERT_PTR_NE(s2, NULL); ASSERT_STRING_EQ(s2, "00000000000000000000"); sshbuf_free(p1); + free(s2); TEST_DONE(); } diff --git a/regress/unittests/sshbuf/test_sshbuf_getput_crypto.c b/regress/unittests/sshbuf/test_sshbuf_getput_crypto.c index e3620e9..97ee853 100644 --- a/regress/unittests/sshbuf/test_sshbuf_getput_crypto.c +++ b/regress/unittests/sshbuf/test_sshbuf_getput_crypto.c @@ -1,4 +1,4 @@ -/* $OpenBSD: test_sshbuf_getput_crypto.c,v 1.3 2021/12/14 21:25:27 deraadt Exp $ */ +/* $OpenBSD: test_sshbuf_getput_crypto.c,v 1.4 2025/05/12 05:42:02 tb Exp $ */ /* * Regress test for sshbuf.h buffer API * @@ -11,9 +11,7 @@ #include #include -#ifdef HAVE_STDINT_H -# include -#endif +#include #include #include @@ -22,6 +20,7 @@ #ifdef OPENSSL_HAS_NISTP256 # include #endif +#include "openbsd-compat/openssl-compat.h" #include "../test_helper/test_helper.h" #include "ssherr.h" @@ -230,7 +229,7 @@ sshbuf_getput_crypto_tests(void) ASSERT_PTR_NE(ecp, NULL); MKBN(ec256_x, bn_x); MKBN(ec256_y, bn_y); - ASSERT_INT_EQ(EC_POINT_set_affine_coordinates_GFp( + ASSERT_INT_EQ(EC_POINT_set_affine_coordinates( EC_KEY_get0_group(eck), ecp, bn_x, bn_y, NULL), 1); ASSERT_INT_EQ(EC_KEY_set_public_key(eck, ecp), 1); BN_free(bn_x); @@ -259,7 +258,7 @@ sshbuf_getput_crypto_tests(void) bn_y = BN_new(); ASSERT_PTR_NE(bn_x, NULL); ASSERT_PTR_NE(bn_y, NULL); - ASSERT_INT_EQ(EC_POINT_get_affine_coordinates_GFp( + ASSERT_INT_EQ(EC_POINT_get_affine_coordinates( EC_KEY_get0_group(eck), EC_KEY_get0_public_key(eck), bn_x, bn_y, NULL), 1); MKBN(ec256_x, bn); diff --git a/regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c b/regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c index 3b48958..cd712c6 100644 --- a/regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c +++ b/regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c @@ -1,4 +1,4 @@ -/* $OpenBSD: test_sshbuf_getput_fuzz.c,v 1.5 2021/12/14 21:25:27 deraadt Exp $ */ +/* $OpenBSD: test_sshbuf_getput_fuzz.c,v 1.6 2025/09/25 22:17:29 dtucker Exp $ */ /* * Regress test for sshbuf.h buffer API * @@ -9,9 +9,7 @@ #include #include -#ifdef HAVE_STDINT_H -# include -#endif +#include #include #include @@ -49,22 +47,22 @@ attempt_parse_blob(u_char *blob, size_t len) p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_put(p1, blob, len), 0); - sshbuf_get_u8(p1, &u8); - sshbuf_get_u16(p1, &u16); - sshbuf_get_u32(p1, &u32); - sshbuf_get_u64(p1, &u64); + ASSERT_INT_EQ(sshbuf_get_u8(p1, &u8), 0); + ASSERT_INT_EQ(sshbuf_get_u16(p1, &u16), 0); + ASSERT_INT_EQ(sshbuf_get_u32(p1, &u32), 0); + ASSERT_INT_EQ(sshbuf_get_u64(p1, &u64), 0); if (sshbuf_get_string(p1, &s, &l) == 0) { bzero(s, l); free(s); } #ifdef WITH_OPENSSL bn = NULL; - sshbuf_get_bignum2(p1, &bn); + ASSERT_INT_EQ(sshbuf_get_bignum2(p1, &bn), 0); BN_clear_free(bn); #if defined(OPENSSL_HAS_ECC) && defined(OPENSSL_HAS_NISTP256) eck = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); ASSERT_PTR_NE(eck, NULL); - sshbuf_get_eckey(p1, eck); + ASSERT_INT_EQ(sshbuf_get_eckey(p1, eck), 0); EC_KEY_free(eck); #endif /* defined(OPENSSL_HAS_ECC) && defined(OPENSSL_HAS_NISTP256) */ #endif /* WITH_OPENSSL */ diff --git a/regress/unittests/sshbuf/test_sshbuf_misc.c b/regress/unittests/sshbuf/test_sshbuf_misc.c index 249ecf2..6b5b380 100644 --- a/regress/unittests/sshbuf/test_sshbuf_misc.c +++ b/regress/unittests/sshbuf/test_sshbuf_misc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: test_sshbuf_misc.c,v 1.5 2021/12/14 21:25:27 deraadt Exp $ */ +/* $OpenBSD: test_sshbuf_misc.c,v 1.7 2025/09/15 03:00:22 djm Exp $ */ /* * Regress test for sshbuf.h buffer API * @@ -9,9 +9,7 @@ #include #include -#ifdef HAVE_STDINT_H -# include -#endif +#include #include #include @@ -22,11 +20,11 @@ void sshbuf_misc_tests(void); -void -sshbuf_misc_tests(void) +static void +test_sshbuf_dump(void) { struct sshbuf *p1; - char tmp[512], msg[] = "imploring ping silence ping over", *p; + char tmp[512]; FILE *out; size_t sz; @@ -48,6 +46,13 @@ sshbuf_misc_tests(void) fclose(out); sshbuf_free(p1); TEST_DONE(); +} + +static void +test_sshbuf_dtob16(void) +{ + struct sshbuf *p1; + char *p; TEST_START("sshbuf_dtob16"); p1 = sshbuf_new(); @@ -59,6 +64,13 @@ sshbuf_misc_tests(void) free(p); sshbuf_free(p1); TEST_DONE(); +} + +static void +test_sshbuf_dtob64_string(void) +{ + struct sshbuf *p1; + char *p; TEST_START("sshbuf_dtob64_string len 1"); p1 = sshbuf_new(); @@ -107,6 +119,12 @@ sshbuf_misc_tests(void) free(p); sshbuf_free(p1); TEST_DONE(); +} + +static void +test_sshbuf_b64tod(void) +{ + struct sshbuf *p1; TEST_START("sshbuf_b64tod len 1"); p1 = sshbuf_new(); @@ -134,6 +152,13 @@ sshbuf_misc_tests(void) ASSERT_U32_EQ(PEEK_U32(sshbuf_ptr(p1)), 0xd00fd00f); sshbuf_free(p1); TEST_DONE(); +} + +static void +test_sshbuf_dup_string(void) +{ + struct sshbuf *p1; + char *p; TEST_START("sshbuf_dup_string"); p1 = sshbuf_new(); @@ -163,6 +188,13 @@ sshbuf_misc_tests(void) ASSERT_PTR_EQ(p, NULL); sshbuf_free(p1); TEST_DONE(); +} + +static void +test_sshbuf_cmp(void) +{ + struct sshbuf *p1; + char msg[] = "imploring ping silence ping over"; TEST_START("sshbuf_cmp"); p1 = sshbuf_from(msg, sizeof(msg) - 1); @@ -182,7 +214,16 @@ sshbuf_misc_tests(void) ASSERT_INT_EQ(sshbuf_cmp(p1, 1000, "silence", 7), SSH_ERR_MESSAGE_INCOMPLETE); ASSERT_INT_EQ(sshbuf_cmp(p1, 0, msg, sizeof(msg) - 1), 0); + sshbuf_free(p1); TEST_DONE(); +} + +static void +test_sshbuf_find(void) +{ + struct sshbuf *p1; + char msg[] = "imploring ping silence ping over"; + size_t sz; TEST_START("sshbuf_find"); p1 = sshbuf_from(msg, sizeof(msg) - 1); @@ -212,6 +253,174 @@ sshbuf_misc_tests(void) SSH_ERR_MESSAGE_INCOMPLETE); ASSERT_INT_EQ(sshbuf_find(p1, 0, msg + 1, sizeof(msg) - 2, &sz), 0); ASSERT_SIZE_T_EQ(sz, 1); + sshbuf_free(p1); + TEST_DONE(); +} + +static void +test_sshbuf_equals(void) +{ + struct sshbuf *b1, *b2; + + TEST_START("sshbuf_equals identical"); + b1 = sshbuf_new(); + b2 = sshbuf_new(); + ASSERT_PTR_NE(b1, NULL); + ASSERT_PTR_NE(b2, NULL); + ASSERT_INT_EQ(sshbuf_put(b1, "hello", 5), 0); + ASSERT_INT_EQ(sshbuf_put(b2, "hello", 5), 0); + ASSERT_INT_EQ(sshbuf_equals(b1, b2), 0); + sshbuf_free(b1); + sshbuf_free(b2); + TEST_DONE(); + + TEST_START("sshbuf_equals different content"); + b1 = sshbuf_new(); + b2 = sshbuf_new(); + ASSERT_PTR_NE(b1, NULL); + ASSERT_PTR_NE(b2, NULL); + ASSERT_INT_EQ(sshbuf_put(b1, "hello", 5), 0); + ASSERT_INT_EQ(sshbuf_put(b2, "world", 5), 0); + ASSERT_INT_EQ(sshbuf_equals(b1, b2), SSH_ERR_INVALID_FORMAT); + sshbuf_free(b1); + sshbuf_free(b2); + TEST_DONE(); + + TEST_START("sshbuf_equals different length"); + b1 = sshbuf_new(); + b2 = sshbuf_new(); + ASSERT_PTR_NE(b1, NULL); + ASSERT_PTR_NE(b2, NULL); + ASSERT_INT_EQ(sshbuf_put(b1, "hello", 5), 0); + ASSERT_INT_EQ(sshbuf_put(b2, "hell", 4), 0); + ASSERT_INT_EQ(sshbuf_equals(b1, b2), SSH_ERR_MESSAGE_INCOMPLETE); + sshbuf_free(b1); + sshbuf_free(b2); + TEST_DONE(); + + TEST_START("sshbuf_equals empty buffers"); + b1 = sshbuf_new(); + b2 = sshbuf_new(); + ASSERT_PTR_NE(b1, NULL); + ASSERT_PTR_NE(b2, NULL); + ASSERT_INT_EQ(sshbuf_equals(b1, b2), 0); + sshbuf_free(b1); + sshbuf_free(b2); + TEST_DONE(); + + TEST_START("sshbuf_equals one empty buffer"); + b1 = sshbuf_new(); + b2 = sshbuf_new(); + ASSERT_PTR_NE(b1, NULL); + ASSERT_PTR_NE(b2, NULL); + ASSERT_INT_EQ(sshbuf_put(b1, "hello", 5), 0); + ASSERT_INT_EQ(sshbuf_equals(b1, b2), SSH_ERR_MESSAGE_INCOMPLETE); + sshbuf_free(b1); + sshbuf_free(b2); + TEST_DONE(); + + TEST_START("sshbuf_equals buffer to self"); + b1 = sshbuf_new(); + ASSERT_PTR_NE(b1, NULL); + ASSERT_INT_EQ(sshbuf_put(b1, "hello", 5), 0); + ASSERT_INT_EQ(sshbuf_equals(b1, b1), 0); + sshbuf_free(b1); TEST_DONE(); } +static void +test_sshbuf_dtourlb64(void) +{ + struct sshbuf *b, *b64; + char *s; + /* From RFC4648 */ + const u_char test_vec1[] = {0x14, 0xfb, 0x9c, 0x03, 0xd9, 0x7e}; + const u_char test_vec2[] = {0xff, 0xff, 0xff}; + const u_char test_vec3[] = {0xfb}; + + TEST_START("sshbuf_dtourlb64 empty"); + b = sshbuf_new(); + b64 = sshbuf_new(); + ASSERT_PTR_NE(b, NULL); + ASSERT_PTR_NE(b64, NULL); + ASSERT_INT_EQ(sshbuf_dtourlb64(b, b64, 0), 0); + ASSERT_SIZE_T_EQ(sshbuf_len(b64), 0); + sshbuf_free(b); + sshbuf_free(b64); + TEST_DONE(); + + TEST_START("sshbuf_dtourlb64 no special chars"); + b = sshbuf_new(); + b64 = sshbuf_new(); + ASSERT_PTR_NE(b, NULL); + ASSERT_PTR_NE(b64, NULL); + ASSERT_INT_EQ(sshbuf_put(b, "hello", 5), 0); + ASSERT_INT_EQ(sshbuf_dtourlb64(b, b64, 0), 0); + s = sshbuf_dup_string(b64); + ASSERT_PTR_NE(s, NULL); + ASSERT_STRING_EQ(s, "aGVsbG8"); + free(s); + sshbuf_free(b); + sshbuf_free(b64); + TEST_DONE(); + + TEST_START("sshbuf_dtourlb64 with '+' char"); + b = sshbuf_new(); + b64 = sshbuf_new(); + ASSERT_PTR_NE(b, NULL); + ASSERT_PTR_NE(b64, NULL); + ASSERT_INT_EQ(sshbuf_put(b, test_vec1, sizeof(test_vec1)), 0); + ASSERT_INT_EQ(sshbuf_dtourlb64(b, b64, 0), 0); + s = sshbuf_dup_string(b64); + ASSERT_PTR_NE(s, NULL); + ASSERT_STRING_EQ(s, "FPucA9l-"); + free(s); + sshbuf_free(b); + sshbuf_free(b64); + TEST_DONE(); + + TEST_START("sshbuf_dtourlb64 with '/' char"); + b = sshbuf_new(); + b64 = sshbuf_new(); + ASSERT_PTR_NE(b, NULL); + ASSERT_PTR_NE(b64, NULL); + ASSERT_INT_EQ(sshbuf_put(b, test_vec2, sizeof(test_vec2)), 0); + ASSERT_INT_EQ(sshbuf_dtourlb64(b, b64, 0), 0); + s = sshbuf_dup_string(b64); + ASSERT_PTR_NE(s, NULL); + ASSERT_STRING_EQ(s, "____"); + free(s); + sshbuf_free(b); + sshbuf_free(b64); + TEST_DONE(); + + TEST_START("sshbuf_dtourlb64 with padding removed"); + b = sshbuf_new(); + b64 = sshbuf_new(); + ASSERT_PTR_NE(b, NULL); + ASSERT_PTR_NE(b64, NULL); + ASSERT_INT_EQ(sshbuf_put(b, test_vec3, sizeof(test_vec3)), 0); + ASSERT_INT_EQ(sshbuf_dtourlb64(b, b64, 0), 0); + s = sshbuf_dup_string(b64); + ASSERT_PTR_NE(s, NULL); + ASSERT_STRING_EQ(s, "-w"); + free(s); + sshbuf_free(b); + sshbuf_free(b64); + TEST_DONE(); +} + +void +sshbuf_misc_tests(void) +{ + test_sshbuf_dump(); + test_sshbuf_dtob16(); + test_sshbuf_dtob64_string(); + test_sshbuf_b64tod(); + test_sshbuf_dup_string(); + test_sshbuf_cmp(); + test_sshbuf_find(); + test_sshbuf_equals(); + test_sshbuf_dtourlb64(); +} + diff --git a/regress/unittests/sshbuf/tests.c b/regress/unittests/sshbuf/tests.c index 29916a1..95a34a8 100644 --- a/regress/unittests/sshbuf/tests.c +++ b/regress/unittests/sshbuf/tests.c @@ -1,10 +1,14 @@ -/* $OpenBSD: tests.c,v 1.1 2014/04/30 05:32:00 djm Exp $ */ +/* $OpenBSD: tests.c,v 1.2 2025/04/15 04:00:42 djm Exp $ */ /* * Regress test for sshbuf.h buffer API * * Placed in the public domain */ +#include "includes.h" + +#include + #include "../test_helper/test_helper.h" void sshbuf_tests(void); @@ -28,3 +32,9 @@ tests(void) sshbuf_getput_fuzz_tests(); sshbuf_fixed(); } + +void +benchmarks(void) +{ + printf("no benchmarks\n"); +} diff --git a/regress/unittests/sshkey/Makefile b/regress/unittests/sshkey/Makefile index cd0f44d..77d07d1 100644 --- a/regress/unittests/sshkey/Makefile +++ b/regress/unittests/sshkey/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.12 2023/01/15 23:35:10 djm Exp $ +# $OpenBSD: Makefile,v 1.14 2025/07/24 06:04:47 djm Exp $ PROG=test_sshkey SRCS=tests.c test_sshkey.c test_file.c test_fuzz.c common.c @@ -6,12 +6,12 @@ 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+=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 SRCS+=cipher-chachapoly.c chacha.c poly1305.c ssh-ecdsa-sk.c ssh-sk.c -SRCS+=ssh-ed25519-sk.c sk-usbhid.c +SRCS+=ssh-ed25519-sk.c sk-usbhid.c ssh-pkcs11-client.c SRCS+=digest-openssl.c #SRCS+=digest-libc.c diff --git a/regress/unittests/sshkey/common.c b/regress/unittests/sshkey/common.c index f325c2a..fa68e6d 100644 --- a/regress/unittests/sshkey/common.c +++ b/regress/unittests/sshkey/common.c @@ -1,4 +1,4 @@ -/* $OpenBSD: common.c,v 1.6 2024/08/15 00:52:23 djm Exp $ */ +/* $OpenBSD: common.c,v 1.8 2025/06/16 08:49:27 dtucker Exp $ */ /* * Helpers for key API tests * @@ -11,9 +11,7 @@ #include #include #include -#ifdef HAVE_STDINT_H #include -#endif #include #include #include @@ -21,7 +19,6 @@ #ifdef WITH_OPENSSL #include #include -#include #include #ifdef OPENSSL_HAS_NISTP256 # include @@ -54,13 +51,13 @@ load_text_file(const char *name) { struct sshbuf *ret = load_file(name); const u_char *p; + size_t len; /* Trim whitespace at EOL */ - for (p = sshbuf_ptr(ret); sshbuf_len(ret) > 0;) { - if (p[sshbuf_len(ret) - 1] == '\r' || - p[sshbuf_len(ret) - 1] == '\t' || - p[sshbuf_len(ret) - 1] == ' ' || - p[sshbuf_len(ret) - 1] == '\n') + for (p = sshbuf_ptr(ret); (len = sshbuf_len(ret)) > 0;) { + len--; + if (p[len] == '\r' || p[len] == '\t' || + p[len] == ' ' || p[len] == '\n') ASSERT_INT_EQ(sshbuf_consume_end(ret, 1), 0); else break; @@ -126,38 +123,4 @@ rsa_q(struct sshkey *k) RSA_get0_factors(EVP_PKEY_get0_RSA(k->pkey), NULL, &q); return q; } - -const BIGNUM * -dsa_g(struct sshkey *k) -{ - const BIGNUM *g = NULL; - - ASSERT_PTR_NE(k, NULL); - ASSERT_PTR_NE(k->dsa, NULL); - DSA_get0_pqg(k->dsa, NULL, NULL, &g); - return g; -} - -const BIGNUM * -dsa_pub_key(struct sshkey *k) -{ - const BIGNUM *pub_key = NULL; - - ASSERT_PTR_NE(k, NULL); - ASSERT_PTR_NE(k->dsa, NULL); - DSA_get0_key(k->dsa, &pub_key, NULL); - return pub_key; -} - -const BIGNUM * -dsa_priv_key(struct sshkey *k) -{ - const BIGNUM *priv_key = NULL; - - ASSERT_PTR_NE(k, NULL); - ASSERT_PTR_NE(k->dsa, NULL); - DSA_get0_key(k->dsa, NULL, &priv_key); - return priv_key; -} #endif /* WITH_OPENSSL */ - diff --git a/regress/unittests/sshkey/common.h b/regress/unittests/sshkey/common.h index 7a514fd..6127116 100644 --- a/regress/unittests/sshkey/common.h +++ b/regress/unittests/sshkey/common.h @@ -1,4 +1,4 @@ -/* $OpenBSD: common.h,v 1.2 2018/09/13 09:03:20 djm Exp $ */ +/* $OpenBSD: common.h,v 1.3 2025/05/06 06:05:48 djm Exp $ */ /* * Helpers for key API tests * @@ -19,7 +19,4 @@ const BIGNUM *rsa_n(struct sshkey *k); const BIGNUM *rsa_e(struct sshkey *k); const BIGNUM *rsa_p(struct sshkey *k); const BIGNUM *rsa_q(struct sshkey *k); -const BIGNUM *dsa_g(struct sshkey *k); -const BIGNUM *dsa_pub_key(struct sshkey *k); -const BIGNUM *dsa_priv_key(struct sshkey *k); diff --git a/regress/unittests/sshkey/mktestdata.sh b/regress/unittests/sshkey/mktestdata.sh index fcd78e9..97e5d79 100755 --- a/regress/unittests/sshkey/mktestdata.sh +++ b/regress/unittests/sshkey/mktestdata.sh @@ -1,5 +1,5 @@ #!/bin/sh -# $OpenBSD: mktestdata.sh,v 1.11 2020/06/19 03:48:49 djm Exp $ +# $OpenBSD: mktestdata.sh,v 1.12 2025/05/06 06:05:48 djm Exp $ PW=mekmitasdigoat @@ -24,27 +24,6 @@ rsa_params() { done } -dsa_params() { - _in="$1" - _outbase="$2" - set -e - openssl dsa -noout -text -in $_in | \ - awk '/^priv:$/,/^pub:/' | \ - grep -v '^[a-zA-Z]' | tr -d ' \n:' > ${_outbase}.priv - openssl dsa -noout -text -in $_in | \ - awk '/^pub:/,/^P:/' | #\ - grep -v '^[a-zA-Z]' | tr -d ' \n:' > ${_outbase}.pub - openssl dsa -noout -text -in $_in | \ - awk '/^G:/,0' | \ - grep -v '^[a-zA-Z]' | tr -d ' \n:' > ${_outbase}.g - for x in priv pub g ; do - echo "" >> ${_outbase}.$x - echo ============ ${_outbase}.$x - cat ${_outbase}.$x - echo ============ - done -} - ecdsa_params() { _in="$1" _outbase="$2" @@ -79,15 +58,14 @@ else exit 1 fi -rm -f rsa_1 dsa_1 ecdsa_1 ed25519_1 -rm -f rsa_2 dsa_2 ecdsa_2 ed25519_2 -rm -f rsa_n dsa_n ecdsa_n # new-format keys -rm -f rsa_1_pw dsa_1_pw ecdsa_1_pw ed25519_1_pw -rm -f rsa_n_pw dsa_n_pw ecdsa_n_pw +rm -f rsa_1 ecdsa_1 ed25519_1 +rm -f rsa_2 ecdsa_2 ed25519_2 +rm -f rsa_n ecdsa_n # new-format keys +rm -f rsa_1_pw ecdsa_1_pw ed25519_1_pw +rm -f rsa_n_pw ecdsa_n_pw rm -f pw *.pub *.bn.* *.param.* *.fp *.fp.bb ssh-keygen -t rsa -b 1024 -C "RSA test key #1" -N "" -f rsa_1 -m PEM -ssh-keygen -t dsa -b 1024 -C "DSA test key #1" -N "" -f dsa_1 -m PEM ssh-keygen -t ecdsa -b 256 -C "ECDSA test key #1" -N "" -f ecdsa_1 -m PEM ssh-keygen -t ed25519 -C "ED25519 test key #1" -N "" -f ed25519_1 ssh-keygen -w "$SK_DUMMY" -t ecdsa-sk -C "ECDSA-SK test key #1" \ @@ -97,7 +75,6 @@ ssh-keygen -w "$SK_DUMMY" -t ed25519-sk -C "ED25519-SK test key #1" \ ssh-keygen -t rsa -b 2048 -C "RSA test key #2" -N "" -f rsa_2 -m PEM -ssh-keygen -t dsa -b 1024 -C "DSA test key #2" -N "" -f dsa_2 -m PEM ssh-keygen -t ecdsa -b 521 -C "ECDSA test key #2" -N "" -f ecdsa_2 -m PEM ssh-keygen -t ed25519 -C "ED25519 test key #2" -N "" -f ed25519_2 ssh-keygen -w "$SK_DUMMY" -t ecdsa-sk -C "ECDSA-SK test key #2" \ @@ -106,37 +83,29 @@ ssh-keygen -w "$SK_DUMMY" -t ed25519-sk -C "ED25519-SK test key #2" \ -N "" -f ed25519_sk2 cp rsa_1 rsa_n -cp dsa_1 dsa_n cp ecdsa_1 ecdsa_n ssh-keygen -pf rsa_n -N "" -ssh-keygen -pf dsa_n -N "" ssh-keygen -pf ecdsa_n -N "" cp rsa_1 rsa_1_pw -cp dsa_1 dsa_1_pw cp ecdsa_1 ecdsa_1_pw cp ed25519_1 ed25519_1_pw cp ecdsa_sk1 ecdsa_sk1_pw cp ed25519_sk1 ed25519_sk1_pw cp rsa_1 rsa_n_pw -cp dsa_1 dsa_n_pw cp ecdsa_1 ecdsa_n_pw ssh-keygen -pf rsa_1_pw -m PEM -N "$PW" -ssh-keygen -pf dsa_1_pw -m PEM -N "$PW" ssh-keygen -pf ecdsa_1_pw -m PEM -N "$PW" ssh-keygen -pf ed25519_1_pw -N "$PW" ssh-keygen -pf ecdsa_sk1_pw -m PEM -N "$PW" ssh-keygen -pf ed25519_sk1_pw -N "$PW" ssh-keygen -pf rsa_n_pw -N "$PW" -ssh-keygen -pf dsa_n_pw -N "$PW" ssh-keygen -pf ecdsa_n_pw -N "$PW" rsa_params rsa_1 rsa_1.param rsa_params rsa_2 rsa_2.param -dsa_params dsa_1 dsa_1.param -dsa_params dsa_1 dsa_1.param ecdsa_params ecdsa_1 ecdsa_1.param ecdsa_params ecdsa_2 ecdsa_2.param # XXX ed25519, *sk params @@ -144,9 +113,6 @@ ecdsa_params ecdsa_2 ecdsa_2.param ssh-keygen -s rsa_2 -I hugo -n user1,user2 \ -Oforce-command=/bin/ls -Ono-port-forwarding -Osource-address=10.0.0.0/8 \ -V 19990101:20110101 -z 1 rsa_1.pub -ssh-keygen -s rsa_2 -I hugo -n user1,user2 \ - -Oforce-command=/bin/ls -Ono-port-forwarding -Osource-address=10.0.0.0/8 \ - -V 19990101:20110101 -z 2 dsa_1.pub ssh-keygen -s rsa_2 -I hugo -n user1,user2 \ -Oforce-command=/bin/ls -Ono-port-forwarding -Osource-address=10.0.0.0/8 \ -V 19990101:20110101 -z 3 ecdsa_1.pub @@ -175,8 +141,6 @@ ssh-keygen -s rsa_2 -I hugo -n user1,user2 -t rsa-sha2-512 \ ssh-keygen -s ed25519_1 -I julius -n host1,host2 -h \ -V 19990101:20110101 -z 5 rsa_1.pub -ssh-keygen -s ed25519_1 -I julius -n host1,host2 -h \ - -V 19990101:20110101 -z 6 dsa_1.pub ssh-keygen -s ecdsa_1 -I julius -n host1,host2 -h \ -V 19990101:20110101 -z 7 ecdsa_1.pub ssh-keygen -s ed25519_1 -I julius -n host1,host2 -h \ @@ -187,33 +151,28 @@ ssh-keygen -s ed25519_1 -I julius -n host1,host2 -h \ -V 19990101:20110101 -z 8 ed25519_sk1.pub ssh-keygen -lf rsa_1 | awk '{print $2}' > rsa_1.fp -ssh-keygen -lf dsa_1 | awk '{print $2}' > dsa_1.fp ssh-keygen -lf ecdsa_1 | awk '{print $2}' > ecdsa_1.fp ssh-keygen -lf ed25519_1 | awk '{print $2}' > ed25519_1.fp ssh-keygen -lf ecdsa_sk1 | awk '{print $2}' > ecdsa_sk1.fp ssh-keygen -lf ed25519_sk1 | awk '{print $2}' > ed25519_sk1.fp ssh-keygen -lf rsa_2 | awk '{print $2}' > rsa_2.fp -ssh-keygen -lf dsa_2 | awk '{print $2}' > dsa_2.fp ssh-keygen -lf ecdsa_2 | awk '{print $2}' > ecdsa_2.fp ssh-keygen -lf ed25519_2 | awk '{print $2}' > ed25519_2.fp ssh-keygen -lf ecdsa_sk2 | awk '{print $2}' > ecdsa_sk2.fp ssh-keygen -lf ed25519_sk2 | awk '{print $2}' > ed25519_sk2.fp ssh-keygen -lf rsa_1-cert.pub | awk '{print $2}' > rsa_1-cert.fp -ssh-keygen -lf dsa_1-cert.pub | awk '{print $2}' > dsa_1-cert.fp ssh-keygen -lf ecdsa_1-cert.pub | awk '{print $2}' > ecdsa_1-cert.fp ssh-keygen -lf ed25519_1-cert.pub | awk '{print $2}' > ed25519_1-cert.fp ssh-keygen -lf ecdsa_sk1-cert.pub | awk '{print $2}' > ecdsa_sk1-cert.fp ssh-keygen -lf ed25519_sk1-cert.pub | awk '{print $2}' > ed25519_sk1-cert.fp ssh-keygen -Bf rsa_1 | awk '{print $2}' > rsa_1.fp.bb -ssh-keygen -Bf dsa_1 | awk '{print $2}' > dsa_1.fp.bb ssh-keygen -Bf ecdsa_1 | awk '{print $2}' > ecdsa_1.fp.bb ssh-keygen -Bf ed25519_1 | awk '{print $2}' > ed25519_1.fp.bb ssh-keygen -Bf ecdsa_sk1 | awk '{print $2}' > ecdsa_sk1.fp.bb ssh-keygen -Bf ed25519_sk1 | awk '{print $2}' > ed25519_sk1.fp.bb ssh-keygen -Bf rsa_2 | awk '{print $2}' > rsa_2.fp.bb -ssh-keygen -Bf dsa_2 | awk '{print $2}' > dsa_2.fp.bb ssh-keygen -Bf ecdsa_2 | awk '{print $2}' > ecdsa_2.fp.bb ssh-keygen -Bf ed25519_2 | awk '{print $2}' > ed25519_2.fp.bb ssh-keygen -Bf ecdsa_sk2 | awk '{print $2}' > ecdsa_sk2.fp.bb diff --git a/regress/unittests/sshkey/test_file.c b/regress/unittests/sshkey/test_file.c index 3babe60..e412b75 100644 --- a/regress/unittests/sshkey/test_file.c +++ b/regress/unittests/sshkey/test_file.c @@ -1,4 +1,4 @@ -/* $OpenBSD: test_file.c,v 1.12 2024/08/15 00:52:23 djm Exp $ */ +/* $OpenBSD: test_file.c,v 1.13 2025/05/06 06:05:48 djm Exp $ */ /* * Regress test for sshkey.h key management API * @@ -11,9 +11,7 @@ #include #include #include -#ifdef HAVE_STDINT_H #include -#endif #include #include #include @@ -21,7 +19,6 @@ #ifdef WITH_OPENSSL #include #include -#include #include #ifdef OPENSSL_HAS_NISTP256 # include @@ -165,99 +162,6 @@ sshkey_file_tests(void) sshkey_free(k1); -#ifdef WITH_DSA - TEST_START("parse DSA from private"); - buf = load_file("dsa_1"); - ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0); - sshbuf_free(buf); - ASSERT_PTR_NE(k1, NULL); - a = load_bignum("dsa_1.param.g"); - b = load_bignum("dsa_1.param.priv"); - c = load_bignum("dsa_1.param.pub"); - ASSERT_BIGNUM_EQ(dsa_g(k1), a); - ASSERT_BIGNUM_EQ(dsa_priv_key(k1), b); - ASSERT_BIGNUM_EQ(dsa_pub_key(k1), c); - BN_free(a); - BN_free(b); - BN_free(c); - TEST_DONE(); - - TEST_START("parse DSA from private w/ passphrase"); - buf = load_file("dsa_1_pw"); - ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, - (const char *)sshbuf_ptr(pw), &k2, NULL), 0); - sshbuf_free(buf); - ASSERT_PTR_NE(k2, NULL); - ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); - sshkey_free(k2); - TEST_DONE(); - - TEST_START("parse DSA from new-format"); - buf = load_file("dsa_n"); - ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k2, NULL), 0); - sshbuf_free(buf); - ASSERT_PTR_NE(k2, NULL); - ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); - sshkey_free(k2); - TEST_DONE(); - - TEST_START("parse DSA from new-format w/ passphrase"); - buf = load_file("dsa_n_pw"); - ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, - (const char *)sshbuf_ptr(pw), &k2, NULL), 0); - sshbuf_free(buf); - ASSERT_PTR_NE(k2, NULL); - ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); - sshkey_free(k2); - TEST_DONE(); - - TEST_START("load DSA from public"); - ASSERT_INT_EQ(sshkey_load_public(test_data_file("dsa_1.pub"), &k2, - NULL), 0); - ASSERT_PTR_NE(k2, NULL); - ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); - sshkey_free(k2); - TEST_DONE(); - - TEST_START("load DSA cert"); - ASSERT_INT_EQ(sshkey_load_cert(test_data_file("dsa_1"), &k2), 0); - ASSERT_PTR_NE(k2, NULL); - ASSERT_INT_EQ(k2->type, KEY_DSA_CERT); - ASSERT_INT_EQ(sshkey_equal(k1, k2), 0); - ASSERT_INT_EQ(sshkey_equal_public(k1, k2), 1); - TEST_DONE(); - - TEST_START("DSA key hex fingerprint"); - buf = load_text_file("dsa_1.fp"); - cp = sshkey_fingerprint(k1, SSH_DIGEST_SHA256, SSH_FP_BASE64); - ASSERT_PTR_NE(cp, NULL); - ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); - sshbuf_free(buf); - free(cp); - TEST_DONE(); - - TEST_START("DSA cert hex fingerprint"); - buf = load_text_file("dsa_1-cert.fp"); - cp = sshkey_fingerprint(k2, SSH_DIGEST_SHA256, SSH_FP_BASE64); - ASSERT_PTR_NE(cp, NULL); - ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); - sshbuf_free(buf); - free(cp); - sshkey_free(k2); - TEST_DONE(); - - TEST_START("DSA key bubblebabble fingerprint"); - buf = load_text_file("dsa_1.fp.bb"); - cp = sshkey_fingerprint(k1, SSH_DIGEST_SHA1, SSH_FP_BUBBLEBABBLE); - ASSERT_PTR_NE(cp, NULL); - ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); - sshbuf_free(buf); - free(cp); - TEST_DONE(); - - sshkey_free(k1); -#endif - #ifdef OPENSSL_HAS_ECC TEST_START("parse ECDSA from private"); buf = load_file("ecdsa_1"); diff --git a/regress/unittests/sshkey/test_fuzz.c b/regress/unittests/sshkey/test_fuzz.c index 0aff7c9..d0f47d7 100644 --- a/regress/unittests/sshkey/test_fuzz.c +++ b/regress/unittests/sshkey/test_fuzz.c @@ -1,4 +1,4 @@ -/* $OpenBSD: test_fuzz.c,v 1.14 2024/01/11 01:45:58 djm Exp $ */ +/* $OpenBSD: test_fuzz.c,v 1.15 2025/05/06 06:05:48 djm Exp $ */ /* * Fuzz tests for key parsing * @@ -11,9 +11,7 @@ #include #include #include -#ifdef HAVE_STDINT_H #include -#endif #include #include #include @@ -21,7 +19,6 @@ #ifdef WITH_OPENSSL #include #include -#include #include #ifdef OPENSSL_HAS_NISTP256 # include @@ -160,52 +157,6 @@ sshkey_fuzz_tests(void) fuzz_cleanup(fuzz); TEST_DONE(); -#ifdef WITH_DSA - TEST_START("fuzz DSA private"); - buf = load_file("dsa_1"); - fuzz = fuzz_begin(FUZZ_BASE64, sshbuf_mutable_ptr(buf), - sshbuf_len(buf)); - ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0); - sshkey_free(k1); - sshbuf_free(buf); - ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL); - TEST_ONERROR(onerror, fuzz); - for(i = 0; !fuzz_done(fuzz); i++, fuzz_next(fuzz)) { - r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz)); - ASSERT_INT_EQ(r, 0); - if (sshkey_parse_private_fileblob(fuzzed, "", &k1, NULL) == 0) - sshkey_free(k1); - sshbuf_reset(fuzzed); - if (test_is_fast() && i >= NUM_FAST_BASE64_TESTS) - break; - } - sshbuf_free(fuzzed); - fuzz_cleanup(fuzz); - TEST_DONE(); - - TEST_START("fuzz DSA new-format private"); - buf = load_file("dsa_n"); - fuzz = fuzz_begin(FUZZ_BASE64, sshbuf_mutable_ptr(buf), - sshbuf_len(buf)); - ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0); - sshkey_free(k1); - sshbuf_free(buf); - ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL); - TEST_ONERROR(onerror, fuzz); - for(i = 0; !fuzz_done(fuzz); i++, fuzz_next(fuzz)) { - r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz)); - ASSERT_INT_EQ(r, 0); - if (sshkey_parse_private_fileblob(fuzzed, "", &k1, NULL) == 0) - sshkey_free(k1); - sshbuf_reset(fuzzed); - if (test_is_fast() && i >= NUM_FAST_BASE64_TESTS) - break; - } - sshbuf_free(fuzzed); - fuzz_cleanup(fuzz); - TEST_DONE(); -#endif - #ifdef OPENSSL_HAS_ECC TEST_START("fuzz ECDSA private"); buf = load_file("ecdsa_1"); @@ -290,22 +241,6 @@ sshkey_fuzz_tests(void) sshkey_free(k1); TEST_DONE(); -#ifdef WITH_DSA - TEST_START("fuzz DSA public"); - buf = load_file("dsa_1"); - ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0); - sshbuf_free(buf); - public_fuzz(k1); - sshkey_free(k1); - TEST_DONE(); - - TEST_START("fuzz DSA cert"); - ASSERT_INT_EQ(sshkey_load_cert(test_data_file("dsa_1"), &k1), 0); - public_fuzz(k1); - sshkey_free(k1); - TEST_DONE(); -#endif - #ifdef OPENSSL_HAS_ECC TEST_START("fuzz ECDSA public"); buf = load_file("ecdsa_1"); @@ -362,16 +297,6 @@ sshkey_fuzz_tests(void) sshkey_free(k1); TEST_DONE(); -#ifdef WITH_DSA - TEST_START("fuzz DSA sig"); - buf = load_file("dsa_1"); - ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0); - sshbuf_free(buf); - sig_fuzz(k1, NULL); - sshkey_free(k1); - TEST_DONE(); -#endif - #ifdef OPENSSL_HAS_ECC TEST_START("fuzz ECDSA sig"); buf = load_file("ecdsa_1"); diff --git a/regress/unittests/sshkey/test_sshkey.c b/regress/unittests/sshkey/test_sshkey.c index 5bf4b65..d0c46a9 100644 --- a/regress/unittests/sshkey/test_sshkey.c +++ b/regress/unittests/sshkey/test_sshkey.c @@ -1,4 +1,4 @@ -/* $OpenBSD: test_sshkey.c,v 1.25 2024/08/15 00:52:23 djm Exp $ */ +/* $OpenBSD: test_sshkey.c,v 1.32 2025/10/01 00:33:37 dtucker Exp $ */ /* * Regress test for sshkey.h key management API * @@ -9,16 +9,13 @@ #include #include -#ifdef HAVE_STDINT_H #include -#endif #include #include #ifdef WITH_OPENSSL #include #include -#include #if defined(OPENSSL_HAS_ECC) && defined(OPENSSL_HAS_NISTP256) # include #endif @@ -36,6 +33,7 @@ #include "ssh2.h" void sshkey_tests(void); +void sshkey_benchmarks(void); static void put_opt(struct sshbuf *b, const char *name, const char *value) @@ -133,6 +131,55 @@ signature_test(struct sshkey *k, struct sshkey *bad, const char *sig_alg, free(sig); } +static void +signature_bench(const char *name, int ktype, int bits, const char *sig_alg, + const u_char *d, size_t l) +{ + struct sshkey *k; + size_t len; + u_char *sig; + char testname[256]; + + snprintf(testname, sizeof(testname), "sign %s", name); + TEST_START(testname); + ASSERT_INT_EQ(sshkey_generate(ktype, bits, &k), 0); + ASSERT_PTR_NE(k, NULL); + + BENCH_START(testname); + ASSERT_INT_EQ(sshkey_sign(k, &sig, &len, d, l, sig_alg, + NULL, NULL, 0), 0); + free(sig); + BENCH_FINISH("sign"); + + sshkey_free(k); + TEST_DONE(); +} + +static void +verify_bench(const char *name, int ktype, int bits, const char *sig_alg, + const u_char *d, size_t l) +{ + struct sshkey *k; + size_t len; + u_char *sig; + char testname[256]; + + snprintf(testname, sizeof(testname), "verify %s", name); + TEST_START(testname); + ASSERT_INT_EQ(sshkey_generate(ktype, bits, &k), 0); + ASSERT_PTR_NE(k, NULL); + + ASSERT_INT_EQ(sshkey_sign(k, &sig, &len, d, l, sig_alg, + NULL, NULL, 0), 0); + BENCH_START(testname); + ASSERT_INT_EQ(sshkey_verify(k, sig, len, d, l, NULL, 0, NULL), 0); + BENCH_FINISH("verify"); + + free(sig); + sshkey_free(k); + TEST_DONE(); +} + static void banana(u_char *s, size_t l) { @@ -165,6 +212,19 @@ signature_tests(struct sshkey *k, struct sshkey *bad, const char *sig_alg) } } +static void +signature_benchmark(const char *name, int ktype, int bits, + const char *sig_alg, int bench_verify) +{ + u_char buf[256]; + + banana(buf, sizeof(buf)); + if (bench_verify) + verify_bench(name, ktype, bits, sig_alg, buf, sizeof(buf)); + else + signature_bench(name, ktype, bits, sig_alg, buf, sizeof(buf)); +} + static struct sshkey * get_private(const char *n) { @@ -198,6 +258,7 @@ sshkey_tests(void) k1 = sshkey_new(KEY_UNSPEC); ASSERT_PTR_NE(k1, NULL); sshkey_free(k1); + k1 = NULL; TEST_DONE(); #ifdef WITH_OPENSSL @@ -206,16 +267,9 @@ sshkey_tests(void) ASSERT_PTR_NE(k1, NULL); ASSERT_PTR_NE(k1->pkey, NULL); sshkey_free(k1); + k1 = NULL; TEST_DONE(); -#ifdef WITH_DSA - 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(); -#endif #ifdef OPENSSL_HAS_ECC TEST_START("new/free KEY_ECDSA"); @@ -223,6 +277,7 @@ sshkey_tests(void) ASSERT_PTR_NE(k1, NULL); ASSERT_PTR_EQ(k1->pkey, NULL); /* Can't allocate without NID */ sshkey_free(k1); + k1 = NULL; TEST_DONE(); #endif @@ -233,6 +288,7 @@ sshkey_tests(void) ASSERT_PTR_EQ(k1->ed25519_sk, NULL); ASSERT_PTR_EQ(k1->ed25519_pk, NULL); sshkey_free(k1); + k1 = NULL; TEST_DONE(); TEST_START("generate KEY_RSA too small modulus"); @@ -247,14 +303,6 @@ sshkey_tests(void) ASSERT_PTR_EQ(k1, NULL); TEST_DONE(); -#ifdef WITH_DSA - 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(); -#endif #ifdef OPENSSL_HAS_ECC TEST_START("generate KEY_ECDSA wrong bits"); @@ -262,6 +310,7 @@ sshkey_tests(void) SSH_ERR_KEY_LENGTH); ASSERT_PTR_EQ(k1, NULL); sshkey_free(k1); + k1 = NULL; TEST_DONE(); #endif @@ -277,15 +326,6 @@ sshkey_tests(void) ASSERT_INT_EQ(BN_num_bits(rsa_n(kr)), 1024); TEST_DONE(); -#ifdef WITH_DSA - 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(); -#endif #ifdef OPENSSL_HAS_ECC TEST_START("generate KEY_ECDSA"); @@ -323,24 +363,9 @@ sshkey_tests(void) TEST_START("equal KEY_RSA/demoted KEY_RSA"); ASSERT_INT_EQ(sshkey_equal(kr, k1), 1); sshkey_free(k1); + k1 = NULL; TEST_DONE(); -#ifdef WITH_DSA - 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(); -#endif #ifdef OPENSSL_HAS_ECC TEST_START("demote KEY_ECDSA"); @@ -359,6 +384,7 @@ sshkey_tests(void) TEST_START("equal KEY_ECDSA/demoted KEY_ECDSA"); ASSERT_INT_EQ(sshkey_equal(ke, k1), 1); sshkey_free(k1); + k1 = NULL; TEST_DONE(); #endif /* OPENSSL_HAS_ECC */ #endif /* WITH_OPENSSL */ @@ -375,6 +401,7 @@ sshkey_tests(void) TEST_START("equal KEY_ED25519/demoted KEY_ED25519"); ASSERT_INT_EQ(sshkey_equal(kf, k1), 1); sshkey_free(k1); + k1 = NULL; TEST_DONE(); #ifdef WITH_OPENSSL @@ -394,15 +421,18 @@ sshkey_tests(void) ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 1024, &k1), 0); ASSERT_INT_EQ(sshkey_equal(kr, k1), 0); sshkey_free(k1); + k1 = NULL; #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); + k1 = NULL; #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); + k1 = NULL; TEST_DONE(); #ifdef WITH_OPENSSL @@ -457,6 +487,7 @@ sshkey_tests(void) sshkey_free(k1); sshkey_free(k2); sshkey_free(k3); + k1 = k2 = k3 = NULL; sshbuf_reset(b); TEST_DONE(); @@ -468,6 +499,7 @@ sshkey_tests(void) signature_tests(k1, k2, "ssh-rsa"); sshkey_free(k1); sshkey_free(k2); + k1 = k2 = NULL; TEST_DONE(); TEST_START("sign and verify RSA-SHA256"); @@ -477,6 +509,7 @@ sshkey_tests(void) signature_tests(k1, k2, "rsa-sha2-256"); sshkey_free(k1); sshkey_free(k2); + k1 = k2 = NULL; TEST_DONE(); TEST_START("sign and verify RSA-SHA512"); @@ -486,18 +519,9 @@ sshkey_tests(void) signature_tests(k1, k2, "rsa-sha2-512"); sshkey_free(k1); sshkey_free(k2); + k1 = k2 = NULL; TEST_DONE(); -#ifdef WITH_DSA - 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(); -#endif #ifdef OPENSSL_HAS_ECC TEST_START("sign and verify ECDSA"); @@ -507,6 +531,7 @@ sshkey_tests(void) signature_tests(k1, k2, NULL); sshkey_free(k1); sshkey_free(k2); + k1 = k2 = NULL; TEST_DONE(); #endif /* OPENSSL_HAS_ECC */ #endif /* WITH_OPENSSL */ @@ -518,6 +543,7 @@ sshkey_tests(void) signature_tests(k1, k2, NULL); sshkey_free(k1); sshkey_free(k2); + k1 = k2 = NULL; TEST_DONE(); #ifdef WITH_OPENSSL @@ -533,7 +559,96 @@ sshkey_tests(void) sshkey_free(k1); sshkey_free(k2); sshkey_free(k3); + k1 = k2 = k3 = NULL; sshbuf_free(b); TEST_DONE(); #endif /* WITH_OPENSSL */ } + +void +sshkey_benchmarks(void) +{ + struct sshkey *k = NULL; + +#ifdef WITH_OPENSSL + BENCH_START("generate RSA-1024"); + TEST_START("generate KEY_RSA"); + ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 1024, &k), 0); + ASSERT_PTR_NE(k, NULL); + sshkey_free(k); + k = NULL; + TEST_DONE(); + BENCH_FINISH("keys"); + + BENCH_START("generate RSA-2048"); + TEST_START("generate KEY_RSA"); + ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 2048, &k), 0); + ASSERT_PTR_NE(k, NULL); + sshkey_free(k); + k = NULL; + TEST_DONE(); + BENCH_FINISH("keys"); + + BENCH_START("generate ECDSA-256"); + TEST_START("generate KEY_ECDSA"); + ASSERT_INT_EQ(sshkey_generate(KEY_ECDSA, 256, &k), 0); + ASSERT_PTR_NE(k, NULL); + sshkey_free(k); + k = NULL; + TEST_DONE(); + BENCH_FINISH("keys"); + + BENCH_START("generate ECDSA-384"); + TEST_START("generate KEY_ECDSA"); + ASSERT_INT_EQ(sshkey_generate(KEY_ECDSA, 384, &k), 0); + ASSERT_PTR_NE(k, NULL); + sshkey_free(k); + k = NULL; + TEST_DONE(); + BENCH_FINISH("keys"); + + BENCH_START("generate ECDSA-521"); + TEST_START("generate KEY_ECDSA"); + ASSERT_INT_EQ(sshkey_generate(KEY_ECDSA, 521, &k), 0); + ASSERT_PTR_NE(k, NULL); + sshkey_free(k); + k = NULL; + TEST_DONE(); + BENCH_FINISH("keys"); +#endif /* WITH_OPENSSL */ + + BENCH_START("generate ED25519"); + TEST_START("generate KEY_ED25519"); + ASSERT_INT_EQ(sshkey_generate(KEY_ED25519, 256, &k), 0); + ASSERT_PTR_NE(k, NULL); + sshkey_free(k); + k = NULL; + TEST_DONE(); + BENCH_FINISH("keys"); + +#ifdef WITH_OPENSSL + /* sign */ + signature_benchmark("RSA-1024/SHA1", KEY_RSA, 1024, "ssh-rsa", 0); + signature_benchmark("RSA-1024/SHA256", KEY_RSA, 1024, "rsa-sha2-256", 0); + signature_benchmark("RSA-1024/SHA512", KEY_RSA, 1024, "rsa-sha2-512", 0); + signature_benchmark("RSA-2048/SHA1", KEY_RSA, 2048, "ssh-rsa", 0); + signature_benchmark("RSA-2048/SHA256", KEY_RSA, 2048, "rsa-sha2-256", 0); + signature_benchmark("RSA-2048/SHA512", KEY_RSA, 2048, "rsa-sha2-512", 0); + signature_benchmark("ECDSA-256", KEY_ECDSA, 256, NULL, 0); + signature_benchmark("ECDSA-384", KEY_ECDSA, 384, NULL, 0); + signature_benchmark("ECDSA-521", KEY_ECDSA, 521, NULL, 0); + signature_benchmark("ED25519", KEY_ED25519, 0, NULL, 0); + + /* verify */ + signature_benchmark("RSA-1024/SHA1", KEY_RSA, 1024, "ssh-rsa", 1); + signature_benchmark("RSA-1024/SHA256", KEY_RSA, 1024, "rsa-sha2-256", 1); + signature_benchmark("RSA-1024/SHA512", KEY_RSA, 1024, "rsa-sha2-512", 1); + signature_benchmark("RSA-2048/SHA1", KEY_RSA, 2048, "ssh-rsa", 1); + signature_benchmark("RSA-2048/SHA256", KEY_RSA, 2048, "rsa-sha2-256", 1); + signature_benchmark("RSA-2048/SHA512", KEY_RSA, 2048, "rsa-sha2-512", 1); + signature_benchmark("ECDSA-256", KEY_ECDSA, 256, NULL, 1); + signature_benchmark("ECDSA-384", KEY_ECDSA, 384, NULL, 1); + signature_benchmark("ECDSA-521", KEY_ECDSA, 521, NULL, 1); +#endif /* WITH_OPENSSL */ + signature_benchmark("ED25519", KEY_ED25519, 0, NULL, 1); +} diff --git a/regress/unittests/sshkey/testdata/dsa_1 b/regress/unittests/sshkey/testdata/dsa_1 deleted file mode 100644 index d3f2482..0000000 --- a/regress/unittests/sshkey/testdata/dsa_1 +++ /dev/null @@ -1,12 +0,0 @@ ------BEGIN DSA PRIVATE KEY----- -MIIBvAIBAAKBgQD6kutNFRsHTwEAv6d39Lhsqy1apdHBZ9c2HfyRr7WmypyGIy2m -Ka43vzXI8CNwmRSYs+A6d0vJC7Pl+f9QzJ/04NWOA+MiwfurwrR3CRe61QRYb8Py -mcHOxueHs95IcjrbIPNn86cjnPP5qvv/guUzCjuww4zBdJOXpligrGt2XwIVAKMD -/50qQy7j8JaMk+1+Xtg1pK01AoGBAO7l9QVVbSSoy5lq6cOtvpf8UlwOa6+zBwbl -o4gmFd1RwX1yWkA8kQ7RrhCSg8Hc6mIGnKRgKRli/3LgbSfZ0obFJehkRtEWtN4P -h8fVUeS74iQbIwFQeKlYHIlNTRoGtAbdi3nHdV+BBkEQc1V3rjqYqhjOoz/yNsgz -LND26HrdAoGBAOdXpyfmobEBaOqZAuvgj1P0uhjG2P31Ufurv22FWPBU3A9qrkxb -OXwE0LwvjCvrsQV/lrYhJz/tiys40VeahulWZE5SAHMXGIf95LiLSgaXMjko7joo -t+LK84ltLymwZ4QMnYjnZSSclf1UuyQMcUtb34+I0u9Ycnyhp2mSFsQtAhRYIbQ5 -KfXsZuBPuWe5FJz3ldaEgw== ------END DSA PRIVATE KEY----- diff --git a/regress/unittests/sshkey/testdata/dsa_1-cert.fp b/regress/unittests/sshkey/testdata/dsa_1-cert.fp deleted file mode 100644 index 75ff0e9..0000000 --- a/regress/unittests/sshkey/testdata/dsa_1-cert.fp +++ /dev/null @@ -1 +0,0 @@ -SHA256:kOLgXSoAT8O5T6r36n5NJUYigbux1d7gdH/rmWiJm6s diff --git a/regress/unittests/sshkey/testdata/dsa_1-cert.pub b/regress/unittests/sshkey/testdata/dsa_1-cert.pub deleted file mode 100644 index e768db1..0000000 --- a/regress/unittests/sshkey/testdata/dsa_1-cert.pub +++ /dev/null @@ -1 +0,0 @@ -ssh-dss-cert-v01@openssh.com AAAAHHNzaC1kc3MtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgdTlbNU9Hn9Qng3FHxwH971bxCIoq1ern/QWFFDWXgmYAAACBAPqS600VGwdPAQC/p3f0uGyrLVql0cFn1zYd/JGvtabKnIYjLaYprje/NcjwI3CZFJiz4Dp3S8kLs+X5/1DMn/Tg1Y4D4yLB+6vCtHcJF7rVBFhvw/KZwc7G54ez3khyOtsg82fzpyOc8/mq+/+C5TMKO7DDjMF0k5emWKCsa3ZfAAAAFQCjA/+dKkMu4/CWjJPtfl7YNaStNQAAAIEA7uX1BVVtJKjLmWrpw62+l/xSXA5rr7MHBuWjiCYV3VHBfXJaQDyRDtGuEJKDwdzqYgacpGApGWL/cuBtJ9nShsUl6GRG0Ra03g+Hx9VR5LviJBsjAVB4qVgciU1NGga0Bt2Lecd1X4EGQRBzVXeuOpiqGM6jP/I2yDMs0Pboet0AAACBAOdXpyfmobEBaOqZAuvgj1P0uhjG2P31Ufurv22FWPBU3A9qrkxbOXwE0LwvjCvrsQV/lrYhJz/tiys40VeahulWZE5SAHMXGIf95LiLSgaXMjko7joot+LK84ltLymwZ4QMnYjnZSSclf1UuyQMcUtb34+I0u9Ycnyhp2mSFsQtAAAAAAAAAAYAAAACAAAABmp1bGl1cwAAABIAAAAFaG9zdDEAAAAFaG9zdDIAAAAANowB8AAAAABNHmBwAAAAAAAAAAAAAAAAAAAAMwAAAAtzc2gtZWQyNTUxOQAAACBThupGO0X+FLQhbz8CoKPwc7V3JNsQuGtlsgN+F7SMGQAAAFMAAAALc3NoLWVkMjU1MTkAAABAh/z1LIdNL1b66tQ8t9DY9BTB3BQKpTKmc7ezyFKLwl96yaIniZwD9Ticdbe/8i/Li3uCFE3EAt8NAIv9zff8Bg== DSA test key #1 diff --git a/regress/unittests/sshkey/testdata/dsa_1.fp b/regress/unittests/sshkey/testdata/dsa_1.fp deleted file mode 100644 index 75ff0e9..0000000 --- a/regress/unittests/sshkey/testdata/dsa_1.fp +++ /dev/null @@ -1 +0,0 @@ -SHA256:kOLgXSoAT8O5T6r36n5NJUYigbux1d7gdH/rmWiJm6s diff --git a/regress/unittests/sshkey/testdata/dsa_1.fp.bb b/regress/unittests/sshkey/testdata/dsa_1.fp.bb deleted file mode 100644 index ba37776..0000000 --- a/regress/unittests/sshkey/testdata/dsa_1.fp.bb +++ /dev/null @@ -1 +0,0 @@ -xetag-todiz-mifah-torec-mynyv-cyvit-gopon-pygag-rupic-cenav-bexax diff --git a/regress/unittests/sshkey/testdata/dsa_1.param.g b/regress/unittests/sshkey/testdata/dsa_1.param.g deleted file mode 100644 index e51c3f9..0000000 --- a/regress/unittests/sshkey/testdata/dsa_1.param.g +++ /dev/null @@ -1 +0,0 @@ -00eee5f505556d24a8cb996ae9c3adbe97fc525c0e6bafb30706e5a3882615dd51c17d725a403c910ed1ae109283c1dcea62069ca460291962ff72e06d27d9d286c525e86446d116b4de0f87c7d551e4bbe2241b23015078a9581c894d4d1a06b406dd8b79c7755f81064110735577ae3a98aa18cea33ff236c8332cd0f6e87add diff --git a/regress/unittests/sshkey/testdata/dsa_1.param.priv b/regress/unittests/sshkey/testdata/dsa_1.param.priv deleted file mode 100644 index 4f74331..0000000 --- a/regress/unittests/sshkey/testdata/dsa_1.param.priv +++ /dev/null @@ -1 +0,0 @@ -5821b43929f5ec66e04fb967b9149cf795d68483 diff --git a/regress/unittests/sshkey/testdata/dsa_1.param.pub b/regress/unittests/sshkey/testdata/dsa_1.param.pub deleted file mode 100644 index ba0313b..0000000 --- a/regress/unittests/sshkey/testdata/dsa_1.param.pub +++ /dev/null @@ -1 +0,0 @@ -00e757a727e6a1b10168ea9902ebe08f53f4ba18c6d8fdf551fbabbf6d8558f054dc0f6aae4c5b397c04d0bc2f8c2bebb1057f96b621273fed8b2b38d1579a86e956644e520073171887fde4b88b4a0697323928ee3a28b7e2caf3896d2f29b067840c9d88e765249c95fd54bb240c714b5bdf8f88d2ef58727ca1a7699216c42d diff --git a/regress/unittests/sshkey/testdata/dsa_1.pub b/regress/unittests/sshkey/testdata/dsa_1.pub deleted file mode 100644 index 41cae2f..0000000 --- a/regress/unittests/sshkey/testdata/dsa_1.pub +++ /dev/null @@ -1 +0,0 @@ -ssh-dss AAAAB3NzaC1kc3MAAACBAPqS600VGwdPAQC/p3f0uGyrLVql0cFn1zYd/JGvtabKnIYjLaYprje/NcjwI3CZFJiz4Dp3S8kLs+X5/1DMn/Tg1Y4D4yLB+6vCtHcJF7rVBFhvw/KZwc7G54ez3khyOtsg82fzpyOc8/mq+/+C5TMKO7DDjMF0k5emWKCsa3ZfAAAAFQCjA/+dKkMu4/CWjJPtfl7YNaStNQAAAIEA7uX1BVVtJKjLmWrpw62+l/xSXA5rr7MHBuWjiCYV3VHBfXJaQDyRDtGuEJKDwdzqYgacpGApGWL/cuBtJ9nShsUl6GRG0Ra03g+Hx9VR5LviJBsjAVB4qVgciU1NGga0Bt2Lecd1X4EGQRBzVXeuOpiqGM6jP/I2yDMs0Pboet0AAACBAOdXpyfmobEBaOqZAuvgj1P0uhjG2P31Ufurv22FWPBU3A9qrkxbOXwE0LwvjCvrsQV/lrYhJz/tiys40VeahulWZE5SAHMXGIf95LiLSgaXMjko7joot+LK84ltLymwZ4QMnYjnZSSclf1UuyQMcUtb34+I0u9Ycnyhp2mSFsQt DSA test key #1 diff --git a/regress/unittests/sshkey/testdata/dsa_1_pw b/regress/unittests/sshkey/testdata/dsa_1_pw deleted file mode 100644 index 24c7303..0000000 --- a/regress/unittests/sshkey/testdata/dsa_1_pw +++ /dev/null @@ -1,15 +0,0 @@ ------BEGIN DSA PRIVATE KEY----- -Proc-Type: 4,ENCRYPTED -DEK-Info: AES-128-CBC,BC8386C373B22EB7F00ADC821D5D8BE9 - -+HDV2DQ09sxrIAeXTz9r3YFuPRa2hk1+NGcr3ETkXbC6KiZ14wpTnGTloKwaQjIW -eXTa9mpCOWAoohgvsVb+hOuOlP7AfeHu1IXV4EAS+GDpkiV5UxlCXXwqlD75Buu4 -wwDd/p4SWzILH3WGjDk5JIXoxWNY13LHwC7Q6gtGJx4AicUG7YBRTXMIBDa/Kh77 -6o2rFETKmp4VHBvHbakmiETfptdM8bbWxKWeY2vakThyESgeofsLoTOQCIwlEfJC -s2D/KYL65C8VbHYgIoSLTQnooO45DDyxIuhCqP+H23mhv9vB1Od3nc2atgHj/XFs -dcOPFkF/msDRYqxY3V0AS6+jpKwFodZ7g/hyGcyPxOkzlJVuKoKuH6P5PyQ69Gx0 -iqri0xEPyABr7kGlXNrjjctojX+B4WwSnjg/2euXXWFXCRalIdA7ErATTiQbGOx7 -Vd6Gn8PZbSy1MkqEDrZRip0pfAFJYI/8GXPC75BpnRsrVlfhtrngbW+kBP35LzaN -l2K+RQ3gSB3iFoqNb1Kuu6T5MZlyVl5H2dVlJSeb1euQ2OycXdDoFTyJ4AiyWS7w -Vlh8zeJnso5QRDjMwx99pZilbbuFGSLsahiGEveFc6o= ------END DSA PRIVATE KEY----- diff --git a/regress/unittests/sshkey/testdata/dsa_2 b/regress/unittests/sshkey/testdata/dsa_2 deleted file mode 100644 index 3cc9631..0000000 --- a/regress/unittests/sshkey/testdata/dsa_2 +++ /dev/null @@ -1,12 +0,0 @@ ------BEGIN DSA PRIVATE KEY----- -MIIBvQIBAAKBgQCbyPXNdHeLsjpobPVCMkfagBkt15Zsltqf/PGNP1y1cuz7rsTX -ZekQwUkSTNm5coqXe+ZOw2O4tjobJDd60I1/VPgaB0NYlQR9Hn87M284WD4f6VY+ -aunHmP134a8ybG5G4NqVNF3ihvxAR2pVITqb7kE46r2uYZNcNlHI8voRCwIVAMcP -bwqFNsQbH5pJyZW30wj4KVZ3AoGBAIK98BVeKQVf8qDFqx9ovMuNgVSxpd+N0Yta -5ZEy1OI2ziu5RhjueIM2K7Gq2Mnp38ob1AM53BUxqlcBJaHEDa6rj6yvuMgW9oCJ -dImBM8sIFxfBbXNbpJiMaDwa6WyT84OkpDE6uuAepTMnWOUWkUVkAiyokHDUGXkG -GyoQblbXAoGBAIsf7TaZ804sUWwRV0wI8DYx+hxD5QdrfYPYMtL2fHn3lICimGt0 -FTtUZ25jKg0E0DMBPdET6ZEHB3ZZkR8hFoUzZhdnyJMu3UjVtgaV88Ue3PrXxchk -0W2jHPaAgQU3JIWzo8HFIFqvC/HEL+EyW3rBTY2uXM3XGI+YcWSA4ZrZAhUAsY2f -bDFNzgZ4DaZ9wLRzTgOswPU= ------END DSA PRIVATE KEY----- diff --git a/regress/unittests/sshkey/testdata/dsa_2.fp b/regress/unittests/sshkey/testdata/dsa_2.fp deleted file mode 100644 index 51fbeb4..0000000 --- a/regress/unittests/sshkey/testdata/dsa_2.fp +++ /dev/null @@ -1 +0,0 @@ -SHA256:ecwhWcXgpdBxZ2e+OjpRRY7dqXHHCD62BGtoVQQBwCk diff --git a/regress/unittests/sshkey/testdata/dsa_2.fp.bb b/regress/unittests/sshkey/testdata/dsa_2.fp.bb deleted file mode 100644 index 4d908ee..0000000 --- a/regress/unittests/sshkey/testdata/dsa_2.fp.bb +++ /dev/null @@ -1 +0,0 @@ -xeser-megad-pocan-rozit-belup-tapoh-fapif-kyvit-vonav-cehab-naxax diff --git a/regress/unittests/sshkey/testdata/dsa_2.pub b/regress/unittests/sshkey/testdata/dsa_2.pub deleted file mode 100644 index 77bb555..0000000 --- a/regress/unittests/sshkey/testdata/dsa_2.pub +++ /dev/null @@ -1 +0,0 @@ -ssh-dss AAAAB3NzaC1kc3MAAACBAJvI9c10d4uyOmhs9UIyR9qAGS3XlmyW2p/88Y0/XLVy7PuuxNdl6RDBSRJM2blyipd75k7DY7i2OhskN3rQjX9U+BoHQ1iVBH0efzszbzhYPh/pVj5q6ceY/XfhrzJsbkbg2pU0XeKG/EBHalUhOpvuQTjqva5hk1w2Ucjy+hELAAAAFQDHD28KhTbEGx+aScmVt9MI+ClWdwAAAIEAgr3wFV4pBV/yoMWrH2i8y42BVLGl343Ri1rlkTLU4jbOK7lGGO54gzYrsarYyenfyhvUAzncFTGqVwElocQNrquPrK+4yBb2gIl0iYEzywgXF8Ftc1ukmIxoPBrpbJPzg6SkMTq64B6lMydY5RaRRWQCLKiQcNQZeQYbKhBuVtcAAACBAIsf7TaZ804sUWwRV0wI8DYx+hxD5QdrfYPYMtL2fHn3lICimGt0FTtUZ25jKg0E0DMBPdET6ZEHB3ZZkR8hFoUzZhdnyJMu3UjVtgaV88Ue3PrXxchk0W2jHPaAgQU3JIWzo8HFIFqvC/HEL+EyW3rBTY2uXM3XGI+YcWSA4ZrZ DSA test key #2 diff --git a/regress/unittests/sshkey/testdata/dsa_n b/regress/unittests/sshkey/testdata/dsa_n deleted file mode 100644 index 657624e..0000000 --- a/regress/unittests/sshkey/testdata/dsa_n +++ /dev/null @@ -1,21 +0,0 @@ ------BEGIN OPENSSH PRIVATE KEY----- -b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABswAAAAdzc2gtZH -NzAAAAgQD6kutNFRsHTwEAv6d39Lhsqy1apdHBZ9c2HfyRr7WmypyGIy2mKa43vzXI8CNw -mRSYs+A6d0vJC7Pl+f9QzJ/04NWOA+MiwfurwrR3CRe61QRYb8PymcHOxueHs95IcjrbIP -Nn86cjnPP5qvv/guUzCjuww4zBdJOXpligrGt2XwAAABUAowP/nSpDLuPwloyT7X5e2DWk -rTUAAACBAO7l9QVVbSSoy5lq6cOtvpf8UlwOa6+zBwblo4gmFd1RwX1yWkA8kQ7RrhCSg8 -Hc6mIGnKRgKRli/3LgbSfZ0obFJehkRtEWtN4Ph8fVUeS74iQbIwFQeKlYHIlNTRoGtAbd -i3nHdV+BBkEQc1V3rjqYqhjOoz/yNsgzLND26HrdAAAAgQDnV6cn5qGxAWjqmQLr4I9T9L -oYxtj99VH7q79thVjwVNwPaq5MWzl8BNC8L4wr67EFf5a2ISc/7YsrONFXmobpVmROUgBz -FxiH/eS4i0oGlzI5KO46KLfiyvOJbS8psGeEDJ2I52UknJX9VLskDHFLW9+PiNLvWHJ8oa -dpkhbELQAAAdhWTOFbVkzhWwAAAAdzc2gtZHNzAAAAgQD6kutNFRsHTwEAv6d39Lhsqy1a -pdHBZ9c2HfyRr7WmypyGIy2mKa43vzXI8CNwmRSYs+A6d0vJC7Pl+f9QzJ/04NWOA+Miwf -urwrR3CRe61QRYb8PymcHOxueHs95IcjrbIPNn86cjnPP5qvv/guUzCjuww4zBdJOXplig -rGt2XwAAABUAowP/nSpDLuPwloyT7X5e2DWkrTUAAACBAO7l9QVVbSSoy5lq6cOtvpf8Ul -wOa6+zBwblo4gmFd1RwX1yWkA8kQ7RrhCSg8Hc6mIGnKRgKRli/3LgbSfZ0obFJehkRtEW -tN4Ph8fVUeS74iQbIwFQeKlYHIlNTRoGtAbdi3nHdV+BBkEQc1V3rjqYqhjOoz/yNsgzLN -D26HrdAAAAgQDnV6cn5qGxAWjqmQLr4I9T9LoYxtj99VH7q79thVjwVNwPaq5MWzl8BNC8 -L4wr67EFf5a2ISc/7YsrONFXmobpVmROUgBzFxiH/eS4i0oGlzI5KO46KLfiyvOJbS8psG -eEDJ2I52UknJX9VLskDHFLW9+PiNLvWHJ8oadpkhbELQAAABRYIbQ5KfXsZuBPuWe5FJz3 -ldaEgwAAAAAB ------END OPENSSH PRIVATE KEY----- diff --git a/regress/unittests/sshkey/testdata/dsa_n_pw b/regress/unittests/sshkey/testdata/dsa_n_pw deleted file mode 100644 index 24ac299..0000000 --- a/regress/unittests/sshkey/testdata/dsa_n_pw +++ /dev/null @@ -1,21 +0,0 @@ ------BEGIN OPENSSH PRIVATE KEY----- -b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jYmMAAAAGYmNyeXB0AAAAGAAAABCVs+LsMJ -wnB5zM9U9pTXrGAAAAEAAAAAEAAAGzAAAAB3NzaC1kc3MAAACBAPqS600VGwdPAQC/p3f0 -uGyrLVql0cFn1zYd/JGvtabKnIYjLaYprje/NcjwI3CZFJiz4Dp3S8kLs+X5/1DMn/Tg1Y -4D4yLB+6vCtHcJF7rVBFhvw/KZwc7G54ez3khyOtsg82fzpyOc8/mq+/+C5TMKO7DDjMF0 -k5emWKCsa3ZfAAAAFQCjA/+dKkMu4/CWjJPtfl7YNaStNQAAAIEA7uX1BVVtJKjLmWrpw6 -2+l/xSXA5rr7MHBuWjiCYV3VHBfXJaQDyRDtGuEJKDwdzqYgacpGApGWL/cuBtJ9nShsUl -6GRG0Ra03g+Hx9VR5LviJBsjAVB4qVgciU1NGga0Bt2Lecd1X4EGQRBzVXeuOpiqGM6jP/ -I2yDMs0Pboet0AAACBAOdXpyfmobEBaOqZAuvgj1P0uhjG2P31Ufurv22FWPBU3A9qrkxb -OXwE0LwvjCvrsQV/lrYhJz/tiys40VeahulWZE5SAHMXGIf95LiLSgaXMjko7joot+LK84 -ltLymwZ4QMnYjnZSSclf1UuyQMcUtb34+I0u9Ycnyhp2mSFsQtAAAB4HiOcRW4w+sIqBL0 -TPVbf0glN1hUi0rcE63Pqxmvxb8LkldC4IxAUagPrjhNAEW2AY42+CvPrtGB1z7gDADAIW -xZX6wKwIcXP0Qh+xHE12F4u6mwfasssnAp4t1Ki8uCjMjnimgb3KdWpp0kiUV0oR062TXV -PAdfrWjaq4fw0KOqbHIAG/v36AqzuqjSTfDbqvLZM3y0gp2Q1RxaQVJA5ZIKKyqRyFX7sr -BaEIyCgeE3hM0EB7BycY1oIcS/eNxrACBWVJCENl5N7LtEYXNX7TANFniztfXzwaqGTT6A -fCfbW4gz1UKldLUBzbIrPwMWlirAstbHvOf/2Iay2pNAs/SHhI0aF2jsGfvv5/D6N+r9dG -B2SgDKBg7pywMH1DTvg6YT3P4GjCx0GUHqRCFLvD1rDdk4KSjvaRMpVq1PJ0/Wv6UGtsMS -TR0PaEHDRNZqAX4YxqujnWrGKuRJhuz0eUvp7fZvbWHtiAMKV7368kkeUmkOHanb+TS+zs -KINX8ev8zJZ6WVr8Vl+IQavpv0i2bXwS6QqbEuifpv/+uBb7pqRiU4u8en0eMdX1bZoTPM -R6xHCnGD/Jpb3zS91Ya57T6CiXZ12KCaL6nWGnCkZVpzkfJ2HjFklWSWBQ6uyaosDQ== ------END OPENSSH PRIVATE KEY----- diff --git a/regress/unittests/sshkey/tests.c b/regress/unittests/sshkey/tests.c index 78aa922..5511e7b 100644 --- a/regress/unittests/sshkey/tests.c +++ b/regress/unittests/sshkey/tests.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tests.c,v 1.1 2014/06/24 01:14:18 djm Exp $ */ +/* $OpenBSD: tests.c,v 1.2 2025/04/15 04:00:42 djm Exp $ */ /* * Regress test for sshbuf.h buffer API * @@ -12,6 +12,7 @@ void sshkey_tests(void); void sshkey_file_tests(void); void sshkey_fuzz_tests(void); +void sshkey_benchmarks(void); void tests(void) @@ -20,3 +21,10 @@ tests(void) sshkey_file_tests(); sshkey_fuzz_tests(); } + +void +benchmarks(void) +{ + printf("\n"); + sshkey_benchmarks(); +} diff --git a/regress/unittests/sshsig/Makefile b/regress/unittests/sshsig/Makefile index bc3c6c7..f2f03e8 100644 --- a/regress/unittests/sshsig/Makefile +++ b/regress/unittests/sshsig/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.3 2023/01/15 23:35:10 djm Exp $ +# $OpenBSD: Makefile,v 1.5 2025/07/24 06:04:47 djm Exp $ PROG=test_sshsig SRCS=tests.c @@ -6,12 +6,12 @@ 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+=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 SRCS+=cipher-chachapoly.c chacha.c poly1305.c ssh-ecdsa-sk.c ssh-sk.c -SRCS+=ssh-ed25519-sk.c sk-usbhid.c +SRCS+=ssh-ed25519-sk.c sk-usbhid.c ssh-pkcs11-client.c SRCS+=digest-openssl.c #SRCS+=digest-libc.c diff --git a/regress/unittests/sshsig/mktestdata.sh b/regress/unittests/sshsig/mktestdata.sh index d2300f9..b7c60cc 100755 --- a/regress/unittests/sshsig/mktestdata.sh +++ b/regress/unittests/sshsig/mktestdata.sh @@ -1,5 +1,5 @@ #!/bin/sh -# $OpenBSD: mktestdata.sh,v 1.1 2020/06/19 04:32:09 djm Exp $ +# $OpenBSD: mktestdata.sh,v 1.2 2025/05/06 06:05:48 djm Exp $ NAMESPACE=unittest @@ -17,14 +17,13 @@ else fi rm -f signed-data namespace -rm -f rsa dsa ecdsa ed25519 ecdsa_sk ed25519_sk -rm -f rsa.sig dsa.sig ecdsa.sig ed25519.sig ecdsa_sk.sig ed25519_sk.sig +rm -f rsa ecdsa ed25519 ecdsa_sk ed25519_sk +rm -f rsa.sig ecdsa.sig ed25519.sig ecdsa_sk.sig ed25519_sk.sig printf "This is a test, this is only a test" > signed-data printf "$NAMESPACE" > namespace ssh-keygen -t rsa -C "RSA test" -N "" -f rsa -m PEM -ssh-keygen -t dsa -C "DSA test" -N "" -f dsa -m PEM ssh-keygen -t ecdsa -C "ECDSA test" -N "" -f ecdsa -m PEM ssh-keygen -t ed25519 -C "ED25519 test key" -N "" -f ed25519 ssh-keygen -w "$SK_DUMMY" -t ecdsa-sk -C "ECDSA-SK test key" \ @@ -33,7 +32,6 @@ ssh-keygen -w "$SK_DUMMY" -t ed25519-sk -C "ED25519-SK test key" \ -N "" -f ed25519_sk ssh-keygen -Y sign -f rsa -n $NAMESPACE - < signed-data > rsa.sig -ssh-keygen -Y sign -f dsa -n $NAMESPACE - < signed-data > dsa.sig ssh-keygen -Y sign -f ecdsa -n $NAMESPACE - < signed-data > ecdsa.sig ssh-keygen -Y sign -f ed25519 -n $NAMESPACE - < signed-data > ed25519.sig ssh-keygen -w "$SK_DUMMY" \ diff --git a/regress/unittests/sshsig/testdata/dsa b/regress/unittests/sshsig/testdata/dsa deleted file mode 100644 index 7c0063e..0000000 --- a/regress/unittests/sshsig/testdata/dsa +++ /dev/null @@ -1,12 +0,0 @@ ------BEGIN DSA PRIVATE KEY----- -MIIBuwIBAAKBgQCXpndQdz2mQVnk+lYOF3nxDT+h6SiJmUvBFhnFWBv8tG4pTOkb -EwGufLEzGpzjTj+3bjVau7LFt37AFrqs4Num272BWNsYNIjOlGPgq7Xjv32FN00x -JYh1DoRs1cGGnvohlsWEamGGhTHD1a9ipctPEBV+NrxtZMrl+pO/ZZg8vQIVAKJB -P3iNYSpSuW74+q4WxLCuK8O3AoGAQldE+BIuxlvoG1IFiWesx0CU+H2KO0SEZc9A -SX/qjOabh0Fb78ofTlEf9gWHFfat8SvSJQIOPMVlb76Lio8AAMT8Eaa/qQKKYmQL -dNq4MLhhjxx5KLGt6J2JyFPExCv+qnHYHD59ngtLwKyqGjpSC8LPLktdXn8W/Aad -Ly1K7+MCgYBsMHBczhSeUh8w7i20CVg4OlNTmfJRVU2tO6OpMxZ/quitRm3hLKSN -u4xRkvHJwi4LhQtv1SXvLI5gs5P3gCG8tsIAiyCqLinHha63iBdJpqhnV/x/j7dB -yJr3xJbnmLdWLkkCtNk1Ir1/CuEz+ufAyLGdKWksEAu1UUlb501BkwIVAILIa3Rg -0h7J9lQpHJphvF3K0M1T ------END DSA PRIVATE KEY----- diff --git a/regress/unittests/sshsig/testdata/dsa.pub b/regress/unittests/sshsig/testdata/dsa.pub deleted file mode 100644 index e77aa7e..0000000 --- a/regress/unittests/sshsig/testdata/dsa.pub +++ /dev/null @@ -1 +0,0 @@ -ssh-dss AAAAB3NzaC1kc3MAAACBAJemd1B3PaZBWeT6Vg4XefENP6HpKImZS8EWGcVYG/y0bilM6RsTAa58sTManONOP7duNVq7ssW3fsAWuqzg26bbvYFY2xg0iM6UY+CrteO/fYU3TTEliHUOhGzVwYae+iGWxYRqYYaFMcPVr2Kly08QFX42vG1kyuX6k79lmDy9AAAAFQCiQT94jWEqUrlu+PquFsSwrivDtwAAAIBCV0T4Ei7GW+gbUgWJZ6zHQJT4fYo7RIRlz0BJf+qM5puHQVvvyh9OUR/2BYcV9q3xK9IlAg48xWVvvouKjwAAxPwRpr+pAopiZAt02rgwuGGPHHkosa3onYnIU8TEK/6qcdgcPn2eC0vArKoaOlILws8uS11efxb8Bp0vLUrv4wAAAIBsMHBczhSeUh8w7i20CVg4OlNTmfJRVU2tO6OpMxZ/quitRm3hLKSNu4xRkvHJwi4LhQtv1SXvLI5gs5P3gCG8tsIAiyCqLinHha63iBdJpqhnV/x/j7dByJr3xJbnmLdWLkkCtNk1Ir1/CuEz+ufAyLGdKWksEAu1UUlb501Bkw== DSA test diff --git a/regress/unittests/sshsig/testdata/dsa.sig b/regress/unittests/sshsig/testdata/dsa.sig deleted file mode 100644 index 0b14ad6..0000000 --- a/regress/unittests/sshsig/testdata/dsa.sig +++ /dev/null @@ -1,13 +0,0 @@ ------BEGIN SSH SIGNATURE----- -U1NIU0lHAAAAAQAAAbEAAAAHc3NoLWRzcwAAAIEAl6Z3UHc9pkFZ5PpWDhd58Q0/oekoiZ -lLwRYZxVgb/LRuKUzpGxMBrnyxMxqc404/t241Wruyxbd+wBa6rODbptu9gVjbGDSIzpRj -4Ku14799hTdNMSWIdQ6EbNXBhp76IZbFhGphhoUxw9WvYqXLTxAVfja8bWTK5fqTv2WYPL -0AAAAVAKJBP3iNYSpSuW74+q4WxLCuK8O3AAAAgEJXRPgSLsZb6BtSBYlnrMdAlPh9ijtE -hGXPQEl/6ozmm4dBW+/KH05RH/YFhxX2rfEr0iUCDjzFZW++i4qPAADE/BGmv6kCimJkC3 -TauDC4YY8ceSixreidichTxMQr/qpx2Bw+fZ4LS8Csqho6UgvCzy5LXV5/FvwGnS8tSu/j -AAAAgGwwcFzOFJ5SHzDuLbQJWDg6U1OZ8lFVTa07o6kzFn+q6K1GbeEspI27jFGS8cnCLg -uFC2/VJe8sjmCzk/eAIby2wgCLIKouKceFrreIF0mmqGdX/H+Pt0HImvfElueYt1YuSQK0 -2TUivX8K4TP658DIsZ0paSwQC7VRSVvnTUGTAAAACHVuaXR0ZXN0AAAAAAAAAAZzaGE1MT -IAAAA3AAAAB3NzaC1kc3MAAAAodi5lr0pqBpO76OY4N1CtfR85BCgZ95qfVjP/e9lToj0q -lwjSJJXUjw== ------END SSH SIGNATURE----- diff --git a/regress/unittests/sshsig/tests.c b/regress/unittests/sshsig/tests.c index 80966bd..670d067 100644 --- a/regress/unittests/sshsig/tests.c +++ b/regress/unittests/sshsig/tests.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tests.c,v 1.4 2024/01/11 01:45:59 djm Exp $ */ +/* $OpenBSD: tests.c,v 1.6 2025/05/06 06:05:48 djm Exp $ */ /* * Regress test for sshbuf.h buffer API * @@ -11,9 +11,7 @@ #include #include #include -#ifdef HAVE_STDINT_H #include -#endif #include #include #include @@ -103,11 +101,6 @@ tests(void) check_sig("rsa.pub", "rsa.sig", msg, namespace); TEST_DONE(); -#ifdef WITH_DSA - TEST_START("check DSA signature"); - check_sig("dsa.pub", "dsa.sig", msg, namespace); - TEST_DONE(); -#endif #ifdef OPENSSL_HAS_ECC TEST_START("check ECDSA signature"); @@ -142,3 +135,9 @@ tests(void) sshbuf_free(msg); free(namespace); } + +void +benchmarks(void) +{ + printf("no benchmarks\n"); +} diff --git a/regress/unittests/test_helper/fuzz.c b/regress/unittests/test_helper/fuzz.c index 9995b26..c2711c7 100644 --- a/regress/unittests/test_helper/fuzz.c +++ b/regress/unittests/test_helper/fuzz.c @@ -1,4 +1,4 @@ -/* $OpenBSD: fuzz.c,v 1.8 2015/03/03 20:42:49 djm Exp $ */ +/* $OpenBSD: fuzz.c,v 1.9 2025/06/13 07:23:07 dtucker Exp $ */ /* * Copyright (c) 2011 Damien Miller * @@ -25,9 +25,7 @@ #include #include #include -#ifdef HAVE_STDINT_H -# include -#endif +#include #include #include #include @@ -150,7 +148,6 @@ fuzz_fmt(struct fuzz *fuzz, char *s, size_t n) return 0; default: return -1; - abort(); } } diff --git a/regress/unittests/test_helper/test_helper.c b/regress/unittests/test_helper/test_helper.c index e23128a..51b8011 100644 --- a/regress/unittests/test_helper/test_helper.c +++ b/regress/unittests/test_helper/test_helper.c @@ -1,4 +1,4 @@ -/* $OpenBSD: test_helper.c,v 1.13 2021/12/14 21:25:27 deraadt Exp $ */ +/* $OpenBSD: test_helper.c,v 1.14 2025/04/15 04:00:42 djm Exp $ */ /* * Copyright (c) 2011 Damien Miller * @@ -21,18 +21,20 @@ #include #include - -#include +#include + +#include #include +#include +#include +#include +#include +#include #include -#ifdef HAVE_STDINT_H -# include -#endif #include #include -#include +#include #include -#include #ifdef WITH_OPENSSL #include @@ -43,12 +45,21 @@ # include #endif -#define MINIMUM(a, b) (((a) < (b)) ? (a) : (b)) - #include "entropy.h" #include "test_helper.h" #include "atomicio.h" +#include "match.h" +#include "misc.h" +#include "xmalloc.h" + +#define BENCH_FAST_DEADLINE 1 +#define BENCH_NORMAL_DEADLINE 10 +#define BENCH_SLOW_DEADLINE 60 +#define BENCH_SAMPLES_ALLOC 8192 +#define BENCH_COLUMN_WIDTH 40 +#define MINIMUM(a, b) (((a) < (b)) ? (a) : (b)) + #define TEST_CHECK_INT(r, pred) do { \ switch (pred) { \ case TEST_EQ: \ @@ -123,6 +134,15 @@ static const char *data_dir = NULL; static char subtest_info[512]; static int fast = 0; static int slow = 0; +static int benchmark_detail_statistics = 0; + +static int benchmark = 0; +static const char *bench_name = NULL; +static char *benchmark_pattern = NULL; +static struct timespec bench_start_time, bench_finish_time; +static struct timespec *bench_samples; +static int bench_skip, bench_nruns, bench_nalloc; +double bench_accum_secs; int main(int argc, char **argv) @@ -147,8 +167,17 @@ main(int argc, char **argv) } } - while ((ch = getopt(argc, argv, "Ffvqd:")) != -1) { + while ((ch = getopt(argc, argv, "O:bBFfvqd:")) != -1) { switch (ch) { + case 'b': + benchmark = 1; + break; + case 'B': + benchmark = benchmark_detail_statistics = 1; + break; + case 'O': + benchmark_pattern = xstrdup(optarg); + break; case 'F': slow = 1; break; @@ -168,7 +197,8 @@ main(int argc, char **argv) break; default: fprintf(stderr, "Unrecognised command line option\n"); - fprintf(stderr, "Usage: %s [-v]\n", __progname); + fprintf(stderr, "Usage: %s [-vqfFbB] [-d data_dir] " + "[-O pattern]\n", __progname); exit(1); } } @@ -178,9 +208,12 @@ main(int argc, char **argv) if (verbose_mode) printf("\n"); - tests(); + if (benchmark) + benchmarks(); + else + tests(); - if (!quiet_mode) + if (!quiet_mode && !benchmark) printf(" %u tests ok\n", test_number); return 0; } @@ -274,7 +307,7 @@ test_done(void) active_test_name = NULL; if (verbose_mode) printf("OK\n"); - else if (!quiet_mode) { + else if (!quiet_mode && !benchmark) { printf("."); fflush(stdout); } @@ -290,6 +323,12 @@ test_subtest_info(const char *fmt, ...) va_end(ap); } +int +test_is_benchmark(void) +{ + return benchmark; +} + void ssl_err_check(const char *file, int line) { @@ -382,23 +421,6 @@ assert_string(const char *file, int line, const char *a1, const char *a2, test_die(); } -static char * -tohex(const void *_s, size_t l) -{ - u_int8_t *s = (u_int8_t *)_s; - size_t i, j; - const char *hex = "0123456789abcdef"; - char *r = malloc((l * 2) + 1); - - assert(r != NULL); - for (i = j = 0; i < l; i++) { - r[j++] = hex[(s[i] >> 4) & 0xf]; - r[j++] = hex[s[i] & 0xf]; - } - r[j] = '\0'; - return r; -} - void assert_mem(const char *file, int line, const char *a1, const char *a2, const void *aa1, const void *aa2, size_t l, enum test_predicate pred) @@ -593,3 +615,131 @@ assert_ptr(const char *file, int line, const char *a1, const char *a2, test_die(); } +static double +tstod(const struct timespec *ts) +{ + return (double)ts->tv_sec + ((double)ts->tv_nsec / 1000000000.0); +} + +void +bench_start(const char *file, int line, const char *name) +{ + char *cp; + + if (bench_name != NULL) { + fprintf(stderr, "\n%s:%d internal error: BENCH_START() called " + "while previous benchmark \"%s\" incomplete", + file, line, bench_name); + abort(); + } + cp = xstrdup(name); + lowercase(cp); + bench_skip = benchmark_pattern != NULL && + match_pattern_list(cp, benchmark_pattern, 1) != 1; + free(cp); + + bench_name = name; + bench_nruns = 0; + if (bench_skip) + return; + free(bench_samples); + bench_nalloc = BENCH_SAMPLES_ALLOC; + bench_samples = xcalloc(sizeof(*bench_samples), bench_nalloc); + bench_accum_secs = 0; +} + +int +bench_done(void) +{ + return bench_skip || bench_accum_secs >= (fast ? BENCH_FAST_DEADLINE : + (slow ? BENCH_SLOW_DEADLINE : BENCH_NORMAL_DEADLINE)); +} + +void +bench_case_start(const char *file, int line) +{ + clock_gettime(CLOCK_REALTIME, &bench_start_time); +} + +void +bench_case_finish(const char *file, int line) +{ + struct timespec ts; + + clock_gettime(CLOCK_REALTIME, &bench_finish_time); + timespecsub(&bench_finish_time, &bench_start_time, &ts); + if (bench_nruns >= bench_nalloc) { + if (bench_nalloc >= INT_MAX / 2) { + fprintf(stderr, "\n%s:%d benchmark %s too many samples", + __FILE__, __LINE__, bench_name); + abort(); + } + bench_samples = xrecallocarray(bench_samples, bench_nalloc, + bench_nalloc * 2, sizeof(*bench_samples)); + bench_nalloc *= 2; + } + bench_samples[bench_nruns++] = ts; + bench_accum_secs += tstod(&ts); +} + +static int +tscmp(const void *aa, const void *bb) +{ + const struct timespec *a = (const struct timespec *)aa; + const struct timespec *b = (const struct timespec *)bb; + + if (timespeccmp(a, b, ==)) + return 0; + return timespeccmp(a, b, <) ? -1 : 1; +} + +void +bench_finish(const char *file, int line, const char *unit) +{ + double std_dev = 0, mean_spr, mean_rps, med_spr, med_rps; + int i; + + if (bench_skip) + goto done; + + if (bench_nruns < 1) { + fprintf(stderr, "\n%s:%d benchmark %s never ran", file, line, + bench_name); + abort(); + } + /* median */ + qsort(bench_samples, bench_nruns, sizeof(*bench_samples), tscmp); + i = bench_nruns / 2; + med_spr = tstod(&bench_samples[i]); + if (bench_nruns > 1 && bench_nruns & 1) + med_spr = (med_spr + tstod(&bench_samples[i - 1])) / 2.0; + med_rps = (med_spr == 0.0) ? INFINITY : 1.0/med_spr; + /* mean */ + mean_spr = bench_accum_secs / (double)bench_nruns; + mean_rps = (mean_spr == 0.0) ? INFINITY : 1.0/mean_spr; + /* std. dev */ + std_dev = 0; + for (i = 0; i < bench_nruns; i++) { + std_dev = tstod(&bench_samples[i]) - mean_spr; + std_dev *= std_dev; + } + std_dev /= (double)bench_nruns; + std_dev = sqrt(std_dev); + if (benchmark_detail_statistics) { + printf("%s: %d runs in %0.3fs, %0.03f/%0.03f ms/%s " + "(mean/median), std.dev %0.03f ms, " + "%0.2f/%0.2f %s/s (mean/median)\n", + bench_name, bench_nruns, bench_accum_secs, + mean_spr * 1000, med_spr * 1000, unit, std_dev * 1000, + mean_rps, med_rps, unit); + } else { + printf("%-*s %0.2f %s/s\n", BENCH_COLUMN_WIDTH, + bench_name, med_rps, unit); + } + done: + bench_name = NULL; + bench_nruns = 0; + free(bench_samples); + bench_samples = NULL; + bench_skip = 0; +} diff --git a/regress/unittests/test_helper/test_helper.h b/regress/unittests/test_helper/test_helper.h index 6630220..4f7e2c8 100644 --- a/regress/unittests/test_helper/test_helper.h +++ b/regress/unittests/test_helper/test_helper.h @@ -1,4 +1,4 @@ -/* $OpenBSD: test_helper.h,v 1.9 2018/10/17 23:28:05 djm Exp $ */ +/* $OpenBSD: test_helper.h,v 1.10 2025/04/15 04:00:42 djm Exp $ */ /* * Copyright (c) 2011 Damien Miller * @@ -23,9 +23,7 @@ #include "includes.h" #include -#ifdef HAVE_STDINT_H -# include -#endif +#include #ifdef WITH_OPENSSL #include @@ -39,6 +37,7 @@ typedef void (test_onerror_func_t)(void *); /* Supplied by test suite */ void tests(void); +void benchmarks(void); const char *test_data_file(const char *name); void test_start(const char *n); @@ -49,6 +48,7 @@ int test_is_verbose(void); int test_is_quiet(void); int test_is_fast(void); int test_is_slow(void); +int test_is_benchmark(void); void test_subtest_info(const char *fmt, ...) __attribute__((format(printf, 1, 2))); void ssl_err_check(const char *file, int line); @@ -285,6 +285,26 @@ void assert_u64(const char *file, int line, #define ASSERT_U64_GE(a1, a2) \ assert_u64(__FILE__, __LINE__, #a1, #a2, a1, a2, TEST_GE) +/* Benchmarking support */ +#define BENCH_START(name) \ + do { \ + bench_start(__FILE__, __LINE__, name); \ + while (!bench_done()) { \ + bench_case_start(__FILE__, __LINE__); \ + do { +#define BENCH_FINISH(unit) \ + } while (0); \ + bench_case_finish(__FILE__, __LINE__); \ + } \ + bench_finish(__FILE__, __LINE__, unit); \ + } while (0) + +void bench_start(const char *file, int line, const char *name); +void bench_case_start(const char *file, int line); +void bench_case_finish(const char *file, int line); +void bench_finish(const char *file, int line, const char *unit); +int bench_done(void); + /* Fuzzing support */ struct fuzz; diff --git a/regress/unittests/utf8/Makefile b/regress/unittests/utf8/Makefile index f8eec04..e895365 100644 --- a/regress/unittests/utf8/Makefile +++ b/regress/unittests/utf8/Makefile @@ -1,14 +1,15 @@ -# $OpenBSD: Makefile,v 1.5 2017/12/21 00:41:22 djm Exp $ +# $OpenBSD: Makefile,v 1.6 2025/04/15 04:00:42 djm Exp $ PROG=test_utf8 SRCS=tests.c # From usr.bin/ssh -SRCS+=utf8.c atomicio.c +SRCS+=utf8.c atomicio.c misc.c xmalloc.c match.c ssherr.c cleanup.c fatal.c +SRCS+=sshbuf.c sshbuf-getput-basic.c sshbuf-misc.c addr.c addrmatch.c log.c REGRESS_TARGETS=run-regress-${PROG} run-regress-${PROG}: ${PROG} - env ${TEST_ENV} ./${PROG} + env ${TEST_ENV} ./${PROG} ${UNITTEST_ARGS} .include diff --git a/regress/unittests/utf8/tests.c b/regress/unittests/utf8/tests.c index 8cf524d..3fb6341 100644 --- a/regress/unittests/utf8/tests.c +++ b/regress/unittests/utf8/tests.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tests.c,v 1.4 2017/02/19 00:11:29 djm Exp $ */ +/* $OpenBSD: tests.c,v 1.5 2025/04/15 04:00:42 djm Exp $ */ /* * Regress test for the utf8.h *mprintf() API * @@ -102,3 +102,9 @@ tests(void) one(0, "double_fit", "a\343\201\201", 7, 5, -1, "a\\343"); one(0, "double_spc", "a\343\201\201", 13, 13, 13, "a\\343\\201\\201"); } + +void +benchmarks(void) +{ + printf("no benchmarks\n"); +} diff --git a/sandbox-capsicum.c b/sandbox-capsicum.c index 1104525..ec07a7d 100644 --- a/sandbox-capsicum.c +++ b/sandbox-capsicum.c @@ -45,8 +45,8 @@ */ struct ssh_sandbox { - struct monitor *monitor; - pid_t child_pid; + int m_recvfd; + int m_log_sendfd; }; struct ssh_sandbox * @@ -54,15 +54,10 @@ ssh_sandbox_init(struct monitor *monitor) { struct ssh_sandbox *box; - /* - * Strictly, we don't need to maintain any state here but we need - * to return non-NULL to satisfy the API. - */ - debug3("%s: preparing capsicum sandbox", __func__); + debug3_f("preparing capsicum sandbox"); box = xcalloc(1, sizeof(*box)); - box->monitor = monitor; - box->child_pid = 0; - + box->m_recvfd = monitor->m_recvfd; + box->m_log_sendfd = monitor->m_log_sendfd; return box; } @@ -100,29 +95,16 @@ ssh_sandbox_child(struct ssh_sandbox *box) fatal("can't limit stderr: %m"); cap_rights_init(&rights, CAP_READ, CAP_WRITE); - if (cap_rights_limit(box->monitor->m_recvfd, &rights) < 0 && + if (cap_rights_limit(box->m_recvfd, &rights) < 0 && errno != ENOSYS) - fatal("%s: failed to limit the network socket", __func__); + fatal_f("failed to limit the network socket"); cap_rights_init(&rights, CAP_WRITE); - if (cap_rights_limit(box->monitor->m_log_sendfd, &rights) < 0 && + if (cap_rights_limit(box->m_log_sendfd, &rights) < 0 && errno != ENOSYS) - fatal("%s: failed to limit the logging socket", __func__); + fatal_f("failed to limit the logging socket"); if (cap_enter() < 0 && errno != ENOSYS) - fatal("%s: failed to enter capability mode", __func__); - -} + fatal_f("failed to enter capability mode"); -void -ssh_sandbox_parent_finish(struct ssh_sandbox *box) -{ - free(box); - debug3("%s: finished", __func__); -} - -void -ssh_sandbox_parent_preauth(struct ssh_sandbox *box, pid_t child_pid) -{ - box->child_pid = child_pid; } #endif /* SANDBOX_CAPSICUM */ diff --git a/sandbox-darwin.c b/sandbox-darwin.c index 59b4d28..98a339e 100644 --- a/sandbox-darwin.c +++ b/sandbox-darwin.c @@ -37,7 +37,7 @@ /* Darwin/OS X sandbox */ struct ssh_sandbox { - pid_t child_pid; + int junk; }; struct ssh_sandbox * @@ -49,10 +49,8 @@ ssh_sandbox_init(struct monitor *monitor) * Strictly, we don't need to maintain any state here but we need * to return non-NULL to satisfy the API. */ - debug3("%s: preparing Darwin sandbox", __func__); + debug3_f("preparing Darwin sandbox"); box = xcalloc(1, sizeof(*box)); - box->child_pid = 0; - return box; } @@ -62,10 +60,10 @@ ssh_sandbox_child(struct ssh_sandbox *box) char *errmsg; struct rlimit rl_zero; - debug3("%s: starting Darwin sandbox", __func__); + debug3_f("starting Darwin sandbox"); if (sandbox_init(kSBXProfilePureComputation, SANDBOX_NAMED, &errmsg) == -1) - fatal("%s: sandbox_init: %s", __func__, errmsg); + fatal_f("sandbox_init: %s", errmsg); /* * The kSBXProfilePureComputation still allows sockets, so @@ -83,17 +81,4 @@ ssh_sandbox_child(struct ssh_sandbox *box) __func__, strerror(errno)); } -void -ssh_sandbox_parent_finish(struct ssh_sandbox *box) -{ - free(box); - debug3("%s: finished", __func__); -} - -void -ssh_sandbox_parent_preauth(struct ssh_sandbox *box, pid_t child_pid) -{ - box->child_pid = child_pid; -} - #endif /* SANDBOX_DARWIN */ diff --git a/sandbox-null.c b/sandbox-null.c index d4cb918..6055eb8 100644 --- a/sandbox-null.c +++ b/sandbox-null.c @@ -57,16 +57,4 @@ ssh_sandbox_child(struct ssh_sandbox *box) /* Nothing to do here */ } -void -ssh_sandbox_parent_finish(struct ssh_sandbox *box) -{ - free(box); -} - -void -ssh_sandbox_parent_preauth(struct ssh_sandbox *box, pid_t child_pid) -{ - /* Nothing to do here */ -} - #endif /* SANDBOX_NULL */ diff --git a/sandbox-pledge.c b/sandbox-pledge.c deleted file mode 100644 index 302f1cf..0000000 --- a/sandbox-pledge.c +++ /dev/null @@ -1,77 +0,0 @@ -/* $OpenBSD: sandbox-pledge.c,v 1.2 2020/10/18 11:32:01 djm Exp $ */ -/* - * Copyright (c) 2015 Theo de Raadt - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "includes.h" - -#ifdef SANDBOX_PLEDGE - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "log.h" -#include "ssh-sandbox.h" -#include "xmalloc.h" - -struct ssh_sandbox { - pid_t child_pid; -}; - -struct ssh_sandbox * -ssh_sandbox_init(struct monitor *m) -{ - struct ssh_sandbox *box; - - debug3_f("preparing pledge sandbox"); - box = xcalloc(1, sizeof(*box)); - box->child_pid = 0; - - return box; -} - -void -ssh_sandbox_child(struct ssh_sandbox *box) -{ - if (pledge("stdio", NULL) == -1) - fatal_f("pledge()"); -} - -void -ssh_sandbox_parent_finish(struct ssh_sandbox *box) -{ - free(box); - debug3_f("finished"); -} - -void -ssh_sandbox_parent_preauth(struct ssh_sandbox *box, pid_t child_pid) -{ - box->child_pid = child_pid; - /* Nothing to do here */ -} - -#endif /* SANDBOX_PLEDGE */ diff --git a/sandbox-rlimit.c b/sandbox-rlimit.c index 26c61d2..6bb4e56 100644 --- a/sandbox-rlimit.c +++ b/sandbox-rlimit.c @@ -37,7 +37,7 @@ /* Minimal sandbox that sets zero nfiles, nprocs and filesize rlimits */ struct ssh_sandbox { - pid_t child_pid; + int junk; }; struct ssh_sandbox * @@ -51,8 +51,6 @@ ssh_sandbox_init(struct monitor *monitor) */ debug3_f("preparing rlimit sandbox"); box = xcalloc(1, sizeof(*box)); - box->child_pid = 0; - return box; } @@ -80,17 +78,4 @@ ssh_sandbox_child(struct ssh_sandbox *box) #endif } -void -ssh_sandbox_parent_finish(struct ssh_sandbox *box) -{ - free(box); - debug3_f("finished"); -} - -void -ssh_sandbox_parent_preauth(struct ssh_sandbox *box, pid_t child_pid) -{ - box->child_pid = child_pid; -} - #endif /* SANDBOX_RLIMIT */ diff --git a/sandbox-seccomp-filter.c b/sandbox-seccomp-filter.c index 23b40b6..a0692dd 100644 --- a/sandbox-seccomp-filter.c +++ b/sandbox-seccomp-filter.c @@ -49,6 +49,8 @@ #include #include +#include + #include #include #include @@ -180,12 +182,12 @@ /* Use this for both __NR_futex and __NR_futex_time64 */ # define SC_FUTEX(_nr) \ - SC_ALLOW_FUTEX_OP(__NR_futex, FUTEX_WAIT), \ - SC_ALLOW_FUTEX_OP(__NR_futex, FUTEX_WAIT_BITSET), \ - SC_ALLOW_FUTEX_OP(__NR_futex, FUTEX_WAKE), \ - SC_ALLOW_FUTEX_OP(__NR_futex, FUTEX_WAKE_BITSET), \ - SC_ALLOW_FUTEX_OP(__NR_futex, FUTEX_REQUEUE), \ - SC_ALLOW_FUTEX_OP(__NR_futex, FUTEX_CMP_REQUEUE) + SC_ALLOW_FUTEX_OP(_nr, FUTEX_WAIT), \ + SC_ALLOW_FUTEX_OP(_nr, FUTEX_WAIT_BITSET), \ + SC_ALLOW_FUTEX_OP(_nr, FUTEX_WAKE), \ + SC_ALLOW_FUTEX_OP(_nr, FUTEX_WAKE_BITSET), \ + SC_ALLOW_FUTEX_OP(_nr, FUTEX_REQUEUE), \ + SC_ALLOW_FUTEX_OP(_nr, FUTEX_CMP_REQUEUE) #endif /* __NR_futex || __NR_futex_time64 */ #if defined(__NR_mmap) || defined(__NR_mmap2) @@ -200,6 +202,32 @@ SC_ALLOW_ARG_MASK(_nr, 2, PROT_READ|PROT_WRITE|PROT_NONE) #endif /* __NR_mmap || __NR_mmap2 */ +/* Special handling for setsockopt(2) */ +#define SC_ALLOW_SETSOCKOPT(_level, _optname) \ + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_setsockopt, 0, 10), \ + /* load and test level, low word */ \ + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \ + offsetof(struct seccomp_data, args[1]) + ARG_LO_OFFSET), \ + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, \ + ((_level) & 0xFFFFFFFF), 0, 7), \ + /* load and test level high word is zero */ \ + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \ + offsetof(struct seccomp_data, args[1]) + ARG_HI_OFFSET), \ + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0, 0, 5), \ + /* load and test optname, low word */ \ + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \ + offsetof(struct seccomp_data, args[2]) + ARG_LO_OFFSET), \ + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, \ + ((_optname) & 0xFFFFFFFF), 0, 3), \ + /* load and test level high word is zero */ \ + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \ + offsetof(struct seccomp_data, args[2]) + ARG_HI_OFFSET), \ + 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. */ @@ -398,7 +426,23 @@ static const struct sock_filter preauth_insns[] = { #ifdef __NR_writev SC_ALLOW(__NR_writev), #endif +#ifdef __NR_getsockopt + SC_ALLOW(__NR_getsockopt), +#endif +#ifdef __NR_getsockname + SC_ALLOW(__NR_getsockname), +#endif +#ifdef __NR_getpeername + SC_ALLOW(__NR_getpeername), +#endif +#ifdef __NR_setsockopt + SC_ALLOW_SETSOCKOPT(IPPROTO_IPV6, IPV6_TCLASS), + SC_ALLOW_SETSOCKOPT(IPPROTO_IP, IP_TOS), +#endif #ifdef __NR_socketcall + SC_ALLOW_ARG(__NR_socketcall, 0, SYS_GETPEERNAME), + SC_ALLOW_ARG(__NR_socketcall, 0, SYS_GETSOCKNAME), + SC_ALLOW_ARG(__NR_socketcall, 0, SYS_GETSOCKOPT), SC_ALLOW_ARG(__NR_socketcall, 0, SYS_SHUTDOWN), SC_DENY(__NR_socketcall, EACCES), #endif @@ -430,7 +474,7 @@ static const struct sock_fprog preauth_program = { }; struct ssh_sandbox { - pid_t child_pid; + int junk; }; struct ssh_sandbox * @@ -442,10 +486,8 @@ ssh_sandbox_init(struct monitor *monitor) * Strictly, we don't need to maintain any state here but we need * to return non-NULL to satisfy the API. */ - debug3("%s: preparing seccomp filter sandbox", __func__); + debug3_f("preparing seccomp filter sandbox"); box = xcalloc(1, sizeof(*box)); - box->child_pid = 0; - return box; } @@ -471,7 +513,7 @@ ssh_sandbox_child_debugging(void) struct sigaction act; sigset_t mask; - debug3("%s: installing SIGSYS handler", __func__); + debug3_f("installing SIGSYS handler"); memset(&act, 0, sizeof(act)); sigemptyset(&mask); sigaddset(&mask, SIGSYS); @@ -479,7 +521,7 @@ ssh_sandbox_child_debugging(void) 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)); + fatal_f("sigaction(SIGSYS): %s", strerror(errno)); if (sigprocmask(SIG_UNBLOCK, &mask, NULL) == -1) fatal("%s: sigprocmask(SIGSYS): %s", __func__, strerror(errno)); @@ -512,13 +554,13 @@ ssh_sandbox_child(struct ssh_sandbox *box) ssh_sandbox_child_debugging(); #endif /* SANDBOX_SECCOMP_FILTER_DEBUG */ - debug3("%s: setting PR_SET_NO_NEW_PRIVS", __func__); + debug3_f("setting PR_SET_NO_NEW_PRIVS"); 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__); + debug3_f("attaching seccomp filter program"); if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &preauth_program) == -1) debug("%s: prctl(PR_SET_SECCOMP): %s", __func__, strerror(errno)); @@ -527,17 +569,4 @@ ssh_sandbox_child(struct ssh_sandbox *box) "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/sandbox-solaris.c b/sandbox-solaris.c index 56ddb9a..0b88c71 100644 --- a/sandbox-solaris.c +++ b/sandbox-solaris.c @@ -97,18 +97,4 @@ ssh_sandbox_child(struct ssh_sandbox *box) fatal("setppriv: %s", strerror(errno)); } -void -ssh_sandbox_parent_finish(struct ssh_sandbox *box) -{ - priv_freeset(box->pset); - box->pset = NULL; - free(box); -} - -void -ssh_sandbox_parent_preauth(struct ssh_sandbox *box, pid_t child_pid) -{ - /* Nothing to do here */ -} - #endif /* SANDBOX_SOLARIS */ diff --git a/sandbox-systrace.c b/sandbox-systrace.c deleted file mode 100644 index e61d581..0000000 --- a/sandbox-systrace.c +++ /dev/null @@ -1,218 +0,0 @@ -/* $OpenBSD: sandbox-systrace.c,v 1.18 2015/10/02 01:39:26 deraadt Exp $ */ -/* - * Copyright (c) 2011 Damien Miller - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "includes.h" - -#ifdef SANDBOX_SYSTRACE - -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "atomicio.h" -#include "log.h" -#include "ssh-sandbox.h" -#include "xmalloc.h" - -struct sandbox_policy { - int syscall; - int action; -}; - -/* Permitted syscalls in preauth. Unlisted syscalls get SYSTR_POLICY_KILL */ -static const struct sandbox_policy preauth_policy[] = { - { SYS_exit, SYSTR_POLICY_PERMIT }, -#ifdef SYS_kbind - { SYS_kbind, SYSTR_POLICY_PERMIT }, -#endif - - { SYS_getpid, SYSTR_POLICY_PERMIT }, - { SYS_getpgid, SYSTR_POLICY_PERMIT }, - { SYS_clock_gettime, SYSTR_POLICY_PERMIT }, - { SYS_gettimeofday, SYSTR_POLICY_PERMIT }, - { SYS_nanosleep, SYSTR_POLICY_PERMIT }, - { SYS_sigprocmask, SYSTR_POLICY_PERMIT }, - -#ifdef SYS_getentropy - /* OpenBSD 5.6 and newer use getentropy(2) to seed arc4random(3). */ - { SYS_getentropy, SYSTR_POLICY_PERMIT }, -#else - /* Previous releases used sysctl(3)'s kern.arnd variable. */ - { SYS___sysctl, SYSTR_POLICY_PERMIT }, -#endif -#ifdef SYS_sendsyslog - { SYS_sendsyslog, SYSTR_POLICY_PERMIT }, -#endif - - { SYS_madvise, SYSTR_POLICY_PERMIT }, - { SYS_mmap, SYSTR_POLICY_PERMIT }, - { SYS_mprotect, SYSTR_POLICY_PERMIT }, - { SYS_mquery, SYSTR_POLICY_PERMIT }, - { SYS_munmap, SYSTR_POLICY_PERMIT }, - - { SYS_poll, SYSTR_POLICY_PERMIT }, - { SYS_select, SYSTR_POLICY_PERMIT }, - { SYS_read, SYSTR_POLICY_PERMIT }, - { SYS_write, SYSTR_POLICY_PERMIT }, - { SYS_shutdown, SYSTR_POLICY_PERMIT }, - { SYS_close, SYSTR_POLICY_PERMIT }, - - { SYS_open, SYSTR_POLICY_NEVER }, - - { -1, -1 } -}; - -struct ssh_sandbox { - int systrace_fd; - pid_t child_pid; - void (*osigchld)(int); -}; - -struct ssh_sandbox * -ssh_sandbox_init(struct monitor *monitor) -{ - struct ssh_sandbox *box; - - debug3("%s: preparing systrace sandbox", __func__); - box = xcalloc(1, sizeof(*box)); - box->systrace_fd = -1; - box->child_pid = 0; - box->osigchld = ssh_signal(SIGCHLD, SIG_IGN); - - return box; -} - -void -ssh_sandbox_child(struct ssh_sandbox *box) -{ - debug3("%s: ready", __func__); - ssh_signal(SIGCHLD, box->osigchld); - if (kill(getpid(), SIGSTOP) != 0) - fatal("%s: kill(%d, SIGSTOP)", __func__, getpid()); - debug3("%s: started", __func__); -} - -static void -ssh_sandbox_parent(struct ssh_sandbox *box, pid_t child_pid, - const struct sandbox_policy *allowed_syscalls) -{ - int dev_systrace, i, j, found, status; - pid_t pid; - struct systrace_policy policy; - - /* Wait for the child to send itself a SIGSTOP */ - debug3("%s: wait for child %ld", __func__, (long)child_pid); - do { - pid = waitpid(child_pid, &status, WUNTRACED); - } while (pid == -1 && errno == EINTR); - ssh_signal(SIGCHLD, box->osigchld); - if (!WIFSTOPPED(status)) { - if (WIFSIGNALED(status)) - fatal("%s: child terminated with signal %d", - __func__, WTERMSIG(status)); - if (WIFEXITED(status)) - fatal("%s: child exited with status %d", - __func__, WEXITSTATUS(status)); - fatal("%s: child not stopped", __func__); - } - debug3("%s: child %ld stopped", __func__, (long)child_pid); - box->child_pid = child_pid; - - /* Set up systracing of child */ - if ((dev_systrace = open("/dev/systrace", O_RDONLY)) == -1) - fatal("%s: open(\"/dev/systrace\"): %s", __func__, - strerror(errno)); - if (ioctl(dev_systrace, STRIOCCLONE, &box->systrace_fd) == -1) - fatal("%s: ioctl(STRIOCCLONE, %d): %s", __func__, - dev_systrace, strerror(errno)); - close(dev_systrace); - debug3("%s: systrace attach, fd=%d", __func__, box->systrace_fd); - if (ioctl(box->systrace_fd, STRIOCATTACH, &child_pid) == -1) - fatal("%s: ioctl(%d, STRIOCATTACH, %d): %s", __func__, - box->systrace_fd, child_pid, strerror(errno)); - - /* Allocate and assign policy */ - memset(&policy, 0, sizeof(policy)); - policy.strp_op = SYSTR_POLICY_NEW; - policy.strp_maxents = SYS_MAXSYSCALL; - if (ioctl(box->systrace_fd, STRIOCPOLICY, &policy) == -1) - fatal("%s: ioctl(%d, STRIOCPOLICY (new)): %s", __func__, - box->systrace_fd, strerror(errno)); - - policy.strp_op = SYSTR_POLICY_ASSIGN; - policy.strp_pid = box->child_pid; - if (ioctl(box->systrace_fd, STRIOCPOLICY, &policy) == -1) - fatal("%s: ioctl(%d, STRIOCPOLICY (assign)): %s", - __func__, box->systrace_fd, strerror(errno)); - - /* Set per-syscall policy */ - for (i = 0; i < SYS_MAXSYSCALL; i++) { - found = 0; - for (j = 0; allowed_syscalls[j].syscall != -1; j++) { - if (allowed_syscalls[j].syscall == i) { - found = 1; - break; - } - } - policy.strp_op = SYSTR_POLICY_MODIFY; - policy.strp_code = i; - policy.strp_policy = found ? - allowed_syscalls[j].action : SYSTR_POLICY_KILL; - if (found) - debug3("%s: policy: enable syscall %d", __func__, i); - if (ioctl(box->systrace_fd, STRIOCPOLICY, &policy) == -1) - fatal("%s: ioctl(%d, STRIOCPOLICY (modify)): %s", - __func__, box->systrace_fd, strerror(errno)); - } - - /* Signal the child to start running */ - debug3("%s: start child %ld", __func__, (long)child_pid); - if (kill(box->child_pid, SIGCONT) != 0) - fatal("%s: kill(%d, SIGCONT)", __func__, box->child_pid); -} - -void -ssh_sandbox_parent_finish(struct ssh_sandbox *box) -{ - /* Closing this before the child exits will terminate it */ - close(box->systrace_fd); - - free(box); - debug3("%s: finished", __func__); -} - -void -ssh_sandbox_parent_preauth(struct ssh_sandbox *box, pid_t child_pid) -{ - ssh_sandbox_parent(box, child_pid, preauth_policy); -} - -#endif /* SANDBOX_SYSTRACE */ diff --git a/scp.0 b/scp.0 index b514c69..43acd03 100644 --- a/scp.0 +++ b/scp.0 @@ -11,7 +11,7 @@ SYNOPSIS DESCRIPTION scp copies files between hosts on a network. - scp uses the SFTP protocol over a ssh(1) connection for data transfer, + scp uses the SFTP protocol over an ssh(1) connection for data transfer, and uses the same authentication and provides the same security as a login session. @@ -30,11 +30,11 @@ DESCRIPTION The options are as follows: -3 Copies between two remote hosts are transferred through the local - host. Without this option the data is copied directly between - the two remote hosts. Note that, when using the legacy SCP - protocol (via the -O flag), this option selects batch mode for - the second host as scp cannot ask for passwords or passphrases - for both hosts. This mode is the default. + host. This mode is the default, but see also the -R option for + copying data directly between two remote hosts. Note that when + using the legacy SCP protocol (via the -O flag), this option + selects batch mode for the second host as scp cannot ask for + passwords or passphrases for both hosts. -4 Forces scp to use IPv4 addresses only. @@ -91,67 +91,106 @@ DESCRIPTION the options listed below, and their possible values, see ssh_config(5). + AddKeysToAgent AddressFamily BatchMode BindAddress BindInterface + CASignatureAlgorithms CanonicalDomains CanonicalizeFallbackLocal CanonicalizeHostname CanonicalizeMaxDots CanonicalizePermittedCNAMEs - CASignatureAlgorithms CertificateFile + ChannelTimeout CheckHostIP Ciphers + ClearAllForwardings Compression - ConnectionAttempts ConnectTimeout + ConnectionAttempts ControlMaster ControlPath ControlPersist - GlobalKnownHostsFile + DynamicForward + EnableEscapeCommandline + EnableSSHKeysign + EscapeChar + ExitOnForwardFailure + FingerprintHash + ForkAfterAuthentication + ForwardAgent + ForwardX11 + ForwardX11Timeout + ForwardX11Trusted GSSAPIAuthentication GSSAPIDelegateCredentials + GatewayPorts + GlobalKnownHostsFile HashKnownHosts Host - HostbasedAcceptedAlgorithms - HostbasedAuthentication HostKeyAlgorithms HostKeyAlias + HostbasedAcceptedAlgorithms + HostbasedAuthentication Hostname + IPQoS IdentitiesOnly IdentityAgent IdentityFile - IPQoS + IgnoreUnknown + Include KbdInteractiveAuthentication KbdInteractiveDevices KexAlgorithms KnownHostsCommand + LocalCommand + LocalForward LogLevel + LogVerbose MACs NoHostAuthenticationForLocalhost NumberOfPasswordPrompts - PasswordAuthentication + ObscureKeystrokeTiming PKCS11Provider + PasswordAuthentication + PermitLocalCommand + PermitRemoteOpen Port PreferredAuthentications ProxyCommand ProxyJump + ProxyUseFdpass PubkeyAcceptedAlgorithms PubkeyAuthentication RekeyLimit + RemoteCommand + RemoteForward + RequestTTY RequiredRSASize + RevokedHostKeys + SecurityKeyProvider SendEnv - ServerAliveInterval ServerAliveCountMax + ServerAliveInterval + SessionType SetEnv + StdinNull + StreamLocalBindMask + StreamLocalBindUnlink StrictHostKeyChecking + SyslogFacility TCPKeepAlive + Tag + Tunnel + TunnelDevice UpdateHostKeys User UserKnownHostsFile VerifyHostKeyDNS + VisualHostKey + XAuthLocation -P port Specifies the port to connect to on the remote host. Note that @@ -164,10 +203,12 @@ DESCRIPTION -q Quiet mode: disables the progress meter as well as warning and diagnostic messages from ssh(1). - -R Copies between two remote hosts are performed by connecting to - the origin host and executing scp there. This requires that scp - running on the origin host can authenticate to the destination - host without requiring a password. + -R Copies between two remote hosts are transferred through the local + host by default. This option instead copies between two remote + hosts by connecting to the origin host and executing scp there. + This requires that scp running on the origin host can + authenticate to the destination host without requiring a + password. -r Recursively copy entire directories. Note that scp follows symbolic links encountered in the tree traversal. @@ -229,4 +270,4 @@ CAVEATS requires careful quoting of any characters that have special meaning to the remote shell, such as quote characters. -OpenBSD 7.6 December 16, 2022 OpenBSD 7.6 +OpenBSD 7.7 October 4, 2025 OpenBSD 7.7 diff --git a/scp.1 b/scp.1 index 54c6fe3..7bce0fe 100644 --- a/scp.1 +++ b/scp.1 @@ -8,9 +8,9 @@ .\" .\" Created: Sun May 7 00:14:37 1995 ylo .\" -.\" $OpenBSD: scp.1,v 1.112 2022/12/16 07:13:22 djm Exp $ +.\" $OpenBSD: scp.1,v 1.115 2025/10/04 21:41:35 naddy Exp $ .\" -.Dd $Mdocdate: December 16 2022 $ +.Dd $Mdocdate: October 4 2025 $ .Dt SCP 1 .Os .Sh NAME @@ -35,7 +35,7 @@ copies files between hosts on a network. .Pp .Nm -uses the SFTP protocol over a +uses the SFTP protocol over an .Xr ssh 1 connection for data transfer, and uses the same authentication and provides the same security as a login session. @@ -76,15 +76,16 @@ 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 legacy SCP protocol (via the +This mode is the default, +but see also the +.Fl R +option for copying data directly between two remote hosts. +Note that when using the legacy SCP protocol (via the .Fl O flag), 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 @@ -162,67 +163,106 @@ 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 BindInterface +.It CASignatureAlgorithms .It CanonicalDomains .It CanonicalizeFallbackLocal .It CanonicalizeHostname .It CanonicalizeMaxDots .It CanonicalizePermittedCNAMEs -.It CASignatureAlgorithms .It CertificateFile +.It ChannelTimeout .It CheckHostIP .It Ciphers +.It ClearAllForwardings .It Compression -.It ConnectionAttempts .It ConnectTimeout +.It ConnectionAttempts .It ControlMaster .It ControlPath .It ControlPersist -.It GlobalKnownHostsFile +.It DynamicForward +.It EnableEscapeCommandline +.It EnableSSHKeysign +.It EscapeChar +.It ExitOnForwardFailure +.It FingerprintHash +.It ForkAfterAuthentication +.It ForwardAgent +.It ForwardX11 +.It ForwardX11Timeout +.It ForwardX11Trusted .It GSSAPIAuthentication .It GSSAPIDelegateCredentials +.It GatewayPorts +.It GlobalKnownHostsFile .It HashKnownHosts .It Host -.It HostbasedAcceptedAlgorithms -.It HostbasedAuthentication .It HostKeyAlgorithms .It HostKeyAlias +.It HostbasedAcceptedAlgorithms +.It HostbasedAuthentication .It Hostname +.It IPQoS .It IdentitiesOnly .It IdentityAgent .It IdentityFile -.It IPQoS +.It IgnoreUnknown +.It Include .It KbdInteractiveAuthentication .It KbdInteractiveDevices .It KexAlgorithms .It KnownHostsCommand +.It LocalCommand +.It LocalForward .It LogLevel +.It LogVerbose .It MACs .It NoHostAuthenticationForLocalhost .It NumberOfPasswordPrompts -.It PasswordAuthentication +.It ObscureKeystrokeTiming .It PKCS11Provider +.It PasswordAuthentication +.It PermitLocalCommand +.It PermitRemoteOpen .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 RevokedHostKeys +.It SecurityKeyProvider .It SendEnv -.It ServerAliveInterval .It ServerAliveCountMax +.It ServerAliveInterval +.It SessionType .It SetEnv +.It StdinNull +.It StreamLocalBindMask +.It StreamLocalBindUnlink .It StrictHostKeyChecking +.It SyslogFacility .It TCPKeepAlive +.It Tag +.It Tunnel +.It TunnelDevice .It UpdateHostKeys .It User .It UserKnownHostsFile .It VerifyHostKeyDNS +.It VisualHostKey +.It XAuthLocation .El .It Fl P Ar port Specifies the port to connect to on the remote host. @@ -239,7 +279,9 @@ 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 +Copies between two remote hosts are transferred through the local host +by default. +This option instead copies between two remote hosts by connecting to the origin host and executing .Nm there. diff --git a/scp.c b/scp.c index 0779c3c..c5f573c 100644 --- a/scp.c +++ b/scp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: scp.c,v 1.261 2024/06/26 23:14:14 deraadt Exp $ */ +/* $OpenBSD: scp.c,v 1.268 2025/09/25 06:23:19 jsg Exp $ */ /* * scp - secure remote copy. This is basically patched BSD rcp which * uses ssh to do the data transfer (instead of using rcmd). @@ -74,19 +74,9 @@ #include "includes.h" #include -#ifdef HAVE_SYS_STAT_H -# include -#endif -#ifdef HAVE_POLL_H +#include #include -#else -# ifdef HAVE_SYS_POLL_H -# include -# endif -#endif -#ifdef HAVE_SYS_TIME_H -# include -#endif +#include #include #include @@ -102,20 +92,14 @@ #else # include "openbsd-compat/glob.h" #endif -#ifdef HAVE_LIBGEN_H #include -#endif #include -#ifdef HAVE_UTIL_H -# include -#endif +#include #include #include #include #include -#ifdef HAVE_STDINT_H -# include -#endif +#include #include #include #include @@ -172,7 +156,7 @@ 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) */ +/* This is the program to execute for the secure connection. ("ssh" or -S) */ char *ssh_program = _PATH_SSH_PROGRAM; /* This is used to store the pid of ssh_program */ @@ -505,6 +489,7 @@ main(int argc, char **argv) addargs(&args, "-oClearAllForwardings=yes"); addargs(&args, "-oRemoteCommand=none"); addargs(&args, "-oRequestTTY=no"); + addargs(&args, "-oControlMaster=no"); fflag = Tflag = tflag = 0; while ((ch = getopt(argc, argv, @@ -1085,8 +1070,9 @@ toremote(int argc, char **argv, enum scp_mode_e mode, char *sftp_direct) } if (host && throughlocal) { /* extended remote to remote */ if (mode == MODE_SFTP) { - if (remin == -1) { + if (remin == -1 || conn == NULL) { /* Connect to dest now */ + sftp_free(conn); conn = do_sftp_connect(thost, tuser, tport, sftp_direct, &remin, &remout, &do_cmd_pid); @@ -1104,6 +1090,7 @@ toremote(int argc, char **argv, enum scp_mode_e mode, char *sftp_direct) * scp -3 hosta:/foo hosta:/bar hostb: */ /* Connect to origin now */ + sftp_free(conn2); conn2 = do_sftp_connect(host, suser, sport, sftp_direct, &remin2, &remout2, &do_cmd_pid2); @@ -1193,6 +1180,7 @@ toremote(int argc, char **argv, enum scp_mode_e mode, char *sftp_direct) } if (remin == -1) { /* Connect to remote now */ + sftp_free(conn); conn = do_sftp_connect(thost, tuser, tport, sftp_direct, &remin, &remout, &do_cmd_pid); @@ -1221,14 +1209,15 @@ toremote(int argc, char **argv, enum scp_mode_e mode, char *sftp_direct) } } out: - if (mode == MODE_SFTP) - free(conn); + freeargs(&alist); free(tuser); free(thost); free(targ); free(suser); free(host); free(src); + sftp_free(conn); + sftp_free(conn2); } void @@ -1274,6 +1263,7 @@ tolocal(int argc, char **argv, enum scp_mode_e mode, char *sftp_direct) } /* Remote to local. */ if (mode == MODE_SFTP) { + sftp_free(conn); conn = do_sftp_connect(host, suser, sport, sftp_direct, &remin, &remout, &do_cmd_pid); if (conn == NULL) { @@ -1285,7 +1275,6 @@ tolocal(int argc, char **argv, enum scp_mode_e mode, char *sftp_direct) /* The protocol */ sink_sftp(1, argv[argc - 1], src, conn); - free(conn); (void) close(remin); (void) close(remout); remin = remout = -1; @@ -1305,9 +1294,11 @@ tolocal(int argc, char **argv, enum scp_mode_e mode, char *sftp_direct) (void) close(remin); remin = remout = -1; } + freeargs(&alist); free(suser); free(host); free(src); + sftp_free(conn); } /* Prepare remote path, handling ~ by assuming cwd is the homedir */ @@ -1581,7 +1572,7 @@ sink_sftp(int argc, char *dst, const char *src, struct sftp_conn *conn) } /* 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 (g.gl_matchc == 0 && g.gl_pathc == 1 && g.gl_pathv[0] != NULL) { /* * If nothing matched but a path returned, then it's probably * a GLOB_NOCHECK result. Check whether the unglobbed path @@ -1889,7 +1880,7 @@ bad: run_err("%s: %s", np, strerror(errno)); /* * 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. + * desynchronise us from the peer. Use note_err() instead. */ statbytes = 0; if (showprogress) @@ -2022,7 +2013,7 @@ throughlocal_sftp(struct sftp_conn *from, struct sftp_conn *to, } /* 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 (g.gl_matchc == 0 && g.gl_pathc == 1 && g.gl_pathv[0] != NULL) { /* * If nothing matched but a path returned, then it's probably * a GLOB_NOCHECK result. Check whether the unglobbed path @@ -2232,7 +2223,7 @@ allocbuf(BUF *bp, int fd, int blksize) if (fstat(fd, &stb) == -1) { run_err("fstat: %s", strerror(errno)); - return (0); + return (NULL); } size = ROUNDUP(stb.st_blksize, blksize); if (size == 0) diff --git a/servconf.c b/servconf.c index bef1b51..48ec8c4 100644 --- a/servconf.c +++ b/servconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: servconf.c,v 1.419 2024/09/25 01:24:04 djm Exp $ */ +/* $OpenBSD: servconf.c,v 1.435 2025/09/25 06:31:42 djm Exp $ */ /* * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved @@ -37,9 +37,7 @@ #include #include #include -#ifdef HAVE_UTIL_H #include -#endif #ifdef USE_SYSTEM_GLOB # include #else @@ -68,6 +66,7 @@ #include "auth.h" #include "myproposal.h" #include "digest.h" +#include "version.h" #if !defined(SSHD_PAM_SERVICE) # define SSHD_PAM_SERVICE "sshd" @@ -214,6 +213,7 @@ initialize_server_options(ServerOptions *options) options->num_channel_timeouts = 0; options->unused_connection_timeout = -1; options->sshd_session_path = NULL; + options->sshd_auth_path = NULL; options->refuse_connection = -1; } @@ -312,10 +312,6 @@ fill_default_server_options(ServerOptions *options) #endif servconf_add_hostkey("[default]", 0, options, _PATH_HOST_ED25519_KEY_FILE, 0); -#ifdef WITH_XMSS - servconf_add_hostkey("[default]", 0, options, - _PATH_HOST_XMSS_KEY_FILE, 0); -#endif /* WITH_XMSS */ } /* No certificates by default */ if (options->num_ports == 0) @@ -470,9 +466,9 @@ fill_default_server_options(ServerOptions *options) if (options->permit_tun == -1) options->permit_tun = SSH_TUNMODE_NO; if (options->ip_qos_interactive == -1) - options->ip_qos_interactive = IPTOS_DSCP_AF21; + options->ip_qos_interactive = IPTOS_DSCP_EF; if (options->ip_qos_bulk == -1) - options->ip_qos_bulk = IPTOS_DSCP_CS1; + options->ip_qos_bulk = IPTOS_DSCP_CS0; if (options->version_addendum == NULL) options->version_addendum = xstrdup(""); if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1) @@ -493,6 +489,8 @@ fill_default_server_options(ServerOptions *options) options->unused_connection_timeout = 0; if (options->sshd_session_path == NULL) options->sshd_session_path = xstrdup(_PATH_SSHD_SESSION); + if (options->sshd_auth_path == NULL) + options->sshd_auth_path = xstrdup(_PATH_SSHD_AUTH); if (options->refuse_connection == -1) options->refuse_connection = 0; @@ -577,7 +575,7 @@ typedef enum { sAllowStreamLocalForwarding, sFingerprintHash, sDisableForwarding, sExposeAuthInfo, sRDomain, sPubkeyAuthOptions, sSecurityKeyProvider, sRequiredRSASize, sChannelTimeout, sUnusedConnectionTimeout, - sSshdSessionPath, sRefuseConnection, + sSshdSessionPath, sSshdAuthPath, sRefuseConnection, sDeprecated, sIgnore, sUnsupported } ServerOpCodes; @@ -745,6 +743,7 @@ static struct { { "channeltimeout", sChannelTimeout, SSHCFG_ALL }, { "unusedconnectiontimeout", sUnusedConnectionTimeout, SSHCFG_ALL }, { "sshdsessionpath", sSshdSessionPath, SSHCFG_GLOBAL }, + { "sshdauthpath", sSshdAuthPath, SSHCFG_GLOBAL }, { "refuseconnection", sRefuseConnection, SSHCFG_ALL }, { NULL, sBadOption, 0 } }; @@ -1035,16 +1034,17 @@ match_cfg_line(const char *full_line, int *acp, char ***avp, int result = 1, attributes = 0, port; char *arg, *attrib = NULL, *oattrib; - if (ci == NULL) - debug3("checking syntax for 'Match %s'", full_line); - else { + if (ci == NULL) { + debug3("checking syntax for 'Match %s' on line %d", + full_line, line); + } else { debug3("checking match for '%s' user %s%s host %s addr %s " - "laddr %s lport %d", full_line, + "laddr %s lport %d on line %d", full_line, ci->user ? ci->user : "(null)", ci->user_invalid ? " (invalid)" : "", ci->host ? ci->host : "(null)", ci->address ? ci->address : "(null)", - ci->laddress ? ci->laddress : "(null)", ci->lport); + ci->laddress ? ci->laddress : "(null)", ci->lport, line); } while ((oattrib = argv_next(acp, avp)) != NULL) { @@ -1091,7 +1091,8 @@ match_cfg_line(const char *full_line, int *acp, char ***avp, strprefix(attrib, "address=", 1) != NULL || strprefix(attrib, "localaddress=", 1) != NULL || strprefix(attrib, "localport=", 1) != NULL || - strprefix(attrib, "rdomain=", 1) != NULL) { + strprefix(attrib, "rdomain=", 1) != NULL || + strprefix(attrib, "version=", 1) != NULL) { arg = strchr(attrib, '='); *(arg++) = '\0'; } else { @@ -1221,8 +1222,16 @@ match_cfg_line(const char *full_line, int *acp, char ***avp, 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); + debug("connection RDomain %.100s matched " + "'RDomain %.100s' at line %d", + ci->rdomain, arg, line); + } else if (strcasecmp(attrib, "version") == 0) { + if (match_pattern_list(SSH_RELEASE, arg, 0) != 1) + result = 0; + else + debug("version %.100s matched " + "'version %.100s' at line %d", + SSH_RELEASE, arg, line); } else { error("Unsupported Match attribute %s", oattrib); result = -1; @@ -1237,7 +1246,7 @@ match_cfg_line(const char *full_line, int *acp, char ***avp, } out: if (ci != NULL && result != -1) - debug3("match %sfound", result ? "" : "not "); + debug3("match %sfound on line %d", result ? "" : "not ", line); free(attrib); return result; } @@ -1267,8 +1276,8 @@ static const struct multistate multistate_addressfamily[] = { { NULL, -1 } }; static const struct multistate multistate_permitrootlogin[] = { - { "without-password", PERMIT_NO_PASSWD }, { "prohibit-password", PERMIT_NO_PASSWD }, + { "without-password", PERMIT_NO_PASSWD }, { "forced-commands-only", PERMIT_FORCED_ONLY }, { "yes", PERMIT_YES }, { "no", PERMIT_NO }, @@ -1304,7 +1313,7 @@ process_server_config_line_depth(ServerOptions *options, char *line, struct include_list *includes) { char *str, ***chararrayptr, **charptr, *arg, *arg2, *p, *keyword; - int cmdline = 0, *intptr, value, value2, n, port, oactive, r; + int cmdline = 0, *intptr, value, value2, value3, n, port, oactive, r; int ca_only = 0, found = 0; SyslogFacility *log_facility_ptr; LogLevel *log_level_ptr; @@ -1992,25 +2001,27 @@ process_server_config_line_depth(ServerOptions *options, char *line, if (!arg || *arg == '\0') fatal("%s line %d: %s missing argument.", filename, linenum, keyword); + /* begin:rate:max */ 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) + &value, &value2, &value3)) == 3) { + if (value > value3 || value2 > 100 || value2 < 1) fatal("%s line %d: Invalid %s spec.", filename, linenum, keyword); - } else if (n != 1) + } else if (n == 1) { + value3 = value; + value = value2 = -1; + } else { 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) + } + if (value3 <= 0 || (value2 != -1 && value <= 0)) fatal("%s line %d: Invalid %s spec.", filename, linenum, keyword); + if (*activep && options->max_startups == -1) { + options->max_startups_begin = value; + options->max_startups_rate = value2; + options->max_startups = value3; + } break; case sPerSourceNetBlockSize: @@ -2030,7 +2041,7 @@ process_server_config_line_depth(ServerOptions *options, char *line, if (n != 1 && n != 2) fatal("%s line %d: Invalid %s spec.", filename, linenum, keyword); - if (*activep) { + if (*activep && options->per_source_masklen_ipv4 == -1) { options->per_source_masklen_ipv4 = value; options->per_source_masklen_ipv6 = value2; } @@ -2069,10 +2080,11 @@ process_server_config_line_depth(ServerOptions *options, char *line, case sPerSourcePenalties: while ((arg = argv_next(&ac, &av)) != NULL) { + const char *q = NULL; + found = 1; value = -1; value2 = 0; - p = NULL; /* Allow no/yes only in first position */ if (strcasecmp(arg, "no") == 0 || (value2 = (strcasecmp(arg, "yes") == 0))) { @@ -2085,35 +2097,28 @@ process_server_config_line_depth(ServerOptions *options, char *line, options->per_source_penalty.enabled == -1) options->per_source_penalty.enabled = value2; continue; - } else if (strncmp(arg, "crash:", 6) == 0) { - p = arg + 6; + } else if ((q = strprefix(arg, "crash:", 0)) != NULL) { intptr = &options->per_source_penalty.penalty_crash; - } else if (strncmp(arg, "authfail:", 9) == 0) { - p = arg + 9; + } else if ((q = strprefix(arg, "authfail:", 0)) != NULL) { intptr = &options->per_source_penalty.penalty_authfail; - } else if (strncmp(arg, "noauth:", 7) == 0) { - p = arg + 7; + } else if ((q = strprefix(arg, "noauth:", 0)) != NULL) { intptr = &options->per_source_penalty.penalty_noauth; - } else if (strncmp(arg, "grace-exceeded:", 15) == 0) { - p = arg + 15; + } else if ((q = strprefix(arg, "grace-exceeded:", 0)) != NULL) { intptr = &options->per_source_penalty.penalty_grace; - } else if (strncmp(arg, "refuseconnection:", 17) == 0) { - p = arg + 17; + } else if ((q = strprefix(arg, "refuseconnection:", 0)) != NULL) { intptr = &options->per_source_penalty.penalty_refuseconnection; - } else if (strncmp(arg, "max:", 4) == 0) { - p = arg + 4; + } else if ((q = strprefix(arg, "max:", 0)) != NULL) { intptr = &options->per_source_penalty.penalty_max; - } else if (strncmp(arg, "min:", 4) == 0) { - p = arg + 4; + } else if ((q = strprefix(arg, "min:", 0)) != NULL) { intptr = &options->per_source_penalty.penalty_min; - } else if (strncmp(arg, "max-sources4:", 13) == 0) { + } else if ((q = strprefix(arg, "max-sources4:", 0)) != NULL) { intptr = &options->per_source_penalty.max_sources4; - if ((errstr = atoi_err(arg+13, &value)) != NULL) + if ((errstr = atoi_err(q, &value)) != NULL) fatal("%s line %d: %s value %s.", filename, linenum, keyword, errstr); - } else if (strncmp(arg, "max-sources6:", 13) == 0) { + } else if ((q = strprefix(arg, "max-sources6:", 0)) != NULL) { intptr = &options->per_source_penalty.max_sources6; - if ((errstr = atoi_err(arg+13, &value)) != NULL) + if ((errstr = atoi_err(q, &value)) != NULL) fatal("%s line %d: %s value %s.", filename, linenum, keyword, errstr); } else if (strcmp(arg, "overflow:deny-all") == 0) { @@ -2133,7 +2138,7 @@ process_server_config_line_depth(ServerOptions *options, char *line, filename, linenum, keyword, arg); } /* If no value was parsed above, assume it's a time */ - if (value == -1 && (value = convtime(p)) == -1) { + if (value == -1 && (value = convtime(q)) == -1) { fatal("%s line %d: invalid %s time value.", filename, linenum, keyword); } @@ -2503,12 +2508,24 @@ process_server_config_line_depth(ServerOptions *options, char *line, if ((value = parse_ipqos(arg)) == -1) fatal("%s line %d: Bad %s value: %s", filename, linenum, keyword, arg); + if (value == INT_MIN) { + debug("%s line %d: Deprecated IPQoS value \"%s\" " + "ignored - using system default instead. Consider" + " using DSCP values.", filename, linenum, arg); + value = INT_MAX; + } 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 (value2 == INT_MIN) { + debug("%s line %d: Deprecated IPQoS value \"%s\" " + "ignored - using system default instead. Consider" + " using DSCP values.", filename, linenum, arg); + value2 = INT_MAX; + } if (*activep) { options->ip_qos_interactive = value; options->ip_qos_bulk = value2; @@ -2705,6 +2722,10 @@ process_server_config_line_depth(ServerOptions *options, char *line, charptr = &options->sshd_session_path; goto parse_filename; + case sSshdAuthPath: + charptr = &options->sshd_auth_path; + goto parse_filename; + case sRefuseConnection: intptr = &options->refuse_connection; multistate_ptr = multistate_flag; @@ -2802,23 +2823,25 @@ parse_server_match_config(ServerOptions *options, copy_set_server_options(options, &mo, 0); } -int parse_server_match_testspec(struct connection_info *ci, char *spec) +int +parse_server_match_testspec(struct connection_info *ci, char *spec) { char *p; + const char *val; 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 ((val = strprefix(p, "addr=", 0)) != NULL) { + ci->address = xstrdup(val); + } else if ((val = strprefix(p, "host=", 0)) != NULL) { + ci->host = xstrdup(val); + } else if ((val = strprefix(p, "user=", 0)) != NULL) { + ci->user = xstrdup(val); + } else if ((val = strprefix(p, "laddr=", 0)) != NULL) { + ci->laddress = xstrdup(val); + } else if ((val = strprefix(p, "rdomain=", 0)) != NULL) { + ci->rdomain = xstrdup(val); + } else if ((val = strprefix(p, "lport=", 0)) != NULL) { + ci->lport = a2port(val); if (ci->lport == -1) { fprintf(stderr, "Invalid port '%s' in test mode" " specification %s\n", p+6, p); @@ -2943,7 +2966,7 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) #define M_CP_STROPT(n) do {\ if (src->n != NULL && dst->n != src->n) { \ free(dst->n); \ - dst->n = src->n; \ + dst->n = xstrdup(src->n); \ } \ } while(0) #define M_CP_STRARRAYOPT(s, num_s) do {\ @@ -3233,6 +3256,7 @@ dump_config(ServerOptions *o) #ifdef GSSAPI dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds); + dump_cfg_fmtint(sGssStrictAcceptor, o->gss_strict_acceptor); #endif dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication); dump_cfg_fmtint(sKbdInteractiveAuthentication, @@ -3290,6 +3314,7 @@ dump_config(ServerOptions *o) dump_cfg_string(sRDomain, o->routing_domain); #endif dump_cfg_string(sSshdSessionPath, o->sshd_session_path); + dump_cfg_string(sSshdAuthPath, o->sshd_auth_path); dump_cfg_string(sPerSourcePenaltyExemptList, o->per_source_penalty_exempt); /* string arguments requiring a lookup */ diff --git a/servconf.h b/servconf.h index 5089bc9..9beb90f 100644 --- a/servconf.h +++ b/servconf.h @@ -249,6 +249,7 @@ typedef struct { int unused_connection_timeout; char *sshd_session_path; + char *sshd_auth_path; int refuse_connection; } ServerOptions; diff --git a/serverloop.c b/serverloop.c index 757cc6f..5d3b194 100644 --- a/serverloop.c +++ b/serverloop.c @@ -1,4 +1,4 @@ -/* $OpenBSD: serverloop.c,v 1.240 2024/06/17 08:28:31 djm Exp $ */ +/* $OpenBSD: serverloop.c,v 1.244 2025/09/25 06:23:19 jsg Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -40,9 +40,7 @@ #include #include #include -#ifdef HAVE_SYS_TIME_H -# include -#endif +#include #include @@ -50,9 +48,7 @@ #include #include #include -#ifdef HAVE_POLL_H #include -#endif #include #include #include @@ -89,7 +85,8 @@ extern struct sshauthopt *auth_opts; static int no_more_sessions = 0; /* Disallow further sessions. */ -static volatile sig_atomic_t child_terminated = 0; /* The child has terminated. */ +static volatile sig_atomic_t child_terminated = 0; /* set on SIGCHLD */ +static volatile sig_atomic_t siginfo_received = 0; /* prototypes */ static void server_init_dispatch(struct ssh *); @@ -103,6 +100,14 @@ sigchld_handler(int sig) child_terminated = 1; } +#ifdef SIGINFO +static void +siginfo_handler(int sig) +{ + siginfo_received = 1; +} +#endif + static void client_alive_check(struct ssh *ssh) { @@ -285,8 +290,15 @@ static void process_output(struct ssh *ssh, int connection_out) { int r; + static int interactive = -1; /* Send any buffered packet data to the client. */ + if (interactive != !channel_has_bulk(ssh)) { + interactive = !channel_has_bulk(ssh); + debug2_f("session QoS is now %s", interactive ? + "interactive" : "non-interactive"); + ssh_packet_set_interactive(ssh, interactive); + } if ((r = ssh_packet_write_poll(ssh)) != 0) { sshpkt_fatal(ssh, r, "%s: ssh_packet_write_poll", __func__); @@ -326,9 +338,15 @@ server_loop2(struct ssh *ssh, Authctxt *authctxt) debug("Entering interactive session for SSH2."); - if (sigemptyset(&bsigset) == -1 || sigaddset(&bsigset, SIGCHLD) == -1) + if (sigemptyset(&bsigset) == -1 || + sigaddset(&bsigset, SIGCHLD) == -1) error_f("bsigset setup: %s", strerror(errno)); ssh_signal(SIGCHLD, sigchld_handler); +#ifdef SIGINFO + if (sigaddset(&bsigset, SIGINFO) == -1) + error_f("bsigset setup: %s", strerror(errno)); + ssh_signal(SIGINFO, siginfo_handler); +#endif child_terminated = 0; connection_in = ssh_packet_get_connection_in(ssh); connection_out = ssh_packet_get_connection_out(ssh); @@ -350,6 +368,10 @@ server_loop2(struct ssh *ssh, Authctxt *authctxt) if (sigprocmask(SIG_BLOCK, &bsigset, &osigset) == -1) error_f("bsigset sigprocmask: %s", strerror(errno)); collect_children(ssh); + if (siginfo_received) { + siginfo_received = 0; + channel_report_open(ssh, SYSLOG_LEVEL_INFO); + } wait_until_can_do_something(ssh, connection_in, connection_out, &pfd, &npfd_alloc, &npfd_active, &osigset, &conn_in_ready, &conn_out_ready); @@ -650,7 +672,7 @@ server_input_hostkeys_prove(struct ssh *ssh, struct sshbuf **respp) int r, ndx, success = 0; const u_char *blob; const char *sigalg, *kex_rsa_sigalg = NULL; - u_char *sig = 0; + u_char *sig = NULL; size_t blen, slen; if ((resp = sshbuf_new()) == NULL || (sigbuf = sshbuf_new()) == NULL) @@ -690,7 +712,7 @@ server_input_hostkeys_prove(struct ssh *ssh, struct sshbuf **respp) * For RSA keys, prefer to use the signature type negotiated * during KEX to the default (SHA1). */ - sigalg = NULL; + sigalg = sshkey_ssh_name(key); if (sshkey_type_plain(key->type) == KEY_RSA) { if (kex_rsa_sigalg != NULL) sigalg = kex_rsa_sigalg; @@ -699,6 +721,7 @@ server_input_hostkeys_prove(struct ssh *ssh, struct sshbuf **respp) 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, diff --git a/session.c b/session.c index c941511..f265fdc 100644 --- a/session.c +++ b/session.c @@ -1,4 +1,4 @@ -/* $OpenBSD: session.c,v 1.338 2024/05/17 00:30:24 djm Exp $ */ +/* $OpenBSD: session.c,v 1.344 2025/09/25 02:15:39 jsg Exp $ */ /* * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved @@ -36,9 +36,7 @@ #include "includes.h" #include -#ifdef HAVE_SYS_STAT_H -# include -#endif +#include #include #include #include @@ -50,9 +48,7 @@ #include #include #include -#ifdef HAVE_PATHS_H #include -#endif #include #include #include @@ -75,9 +71,7 @@ #include "channels.h" #include "sshkey.h" #include "cipher.h" -#ifdef GSSAPI -#include "ssh-gss.h" -#endif +#include "kex.h" #include "hostfile.h" #include "auth.h" #include "auth-options.h" @@ -90,7 +84,9 @@ #include "serverloop.h" #include "canohost.h" #include "session.h" -#include "kex.h" +#ifdef GSSAPI +#include "ssh-gss.h" +#endif #include "monitor_wrap.h" #include "sftp.h" #include "atomicio.h" @@ -143,9 +139,6 @@ static int session_pty_req(struct ssh *, Session *); 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 */ @@ -175,7 +168,6 @@ 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 */ @@ -185,7 +177,6 @@ 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(); } @@ -205,32 +196,15 @@ auth_input_request_forwarding(struct ssh *ssh, struct passwd * pw) /* 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) { + if (agent_listener(pw->pw_dir, "sshd", &sock, &auth_sock_name) != 0) { + /* a more detailed error is already logged */ ssh_packet_send_debug(ssh, "Agent forwarding disabled: " - "mkdtemp() failed: %.100s", strerror(errno)); + "couldn't create listener socket"); 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-listener", SSH_CHANNEL_AUTH_SOCKET, sock, sock, -1, @@ -241,16 +215,9 @@ auth_input_request_forwarding(struct ssh *ssh, struct passwd * pw) authsock_err: free(auth_sock_name); - if (auth_sock_dir != NULL) { - temporarily_use_uid(pw); - rmdir(auth_sock_dir); - restore_uid(); - free(auth_sock_dir); - } if (sock != -1) close(sock); auth_sock_name = NULL; - auth_sock_dir = NULL; return 0; } @@ -524,9 +491,6 @@ do_exec_no_pty(struct ssh *ssh, Session *s, const char *command) #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 @@ -654,8 +618,6 @@ do_exec_pty(struct ssh *ssh, Session *s, const char *command) /* 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; } @@ -1433,7 +1395,7 @@ do_pwchange(Session *s) fprintf(stderr, "WARNING: Your password has expired.\n"); if (s->ttyfd != -1) { fprintf(stderr, - "You must change your password now and login again!\n"); + "You must change your password now and log in again!\n"); #ifdef WITH_SELINUX setexeccon(NULL); #endif @@ -1510,8 +1472,7 @@ do_child(struct ssh *ssh, Session *s, const char *command) sshpkt_fmt_connection_id(ssh, remote_id, sizeof(remote_id)); - /* remove hostkey from the child's memory */ - destroy_sensitive_data(); + /* remove keys from memory */ ssh_packet_clear_keys(ssh); /* Force a password change */ @@ -2145,10 +2106,6 @@ session_signal_req(struct ssh *ssh, Session *s) signame, s->forced ? "forced-command" : "subsystem"); goto out; } - if (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); @@ -2176,7 +2133,8 @@ session_auth_agent_req(struct ssh *ssh, Session *s) 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) { + !options.allow_agent_forwarding || + options.disable_forwarding) { debug_f("agent forwarding disabled"); return 0; } @@ -2571,7 +2529,7 @@ session_setup_x11fwd(struct ssh *ssh, Session *s) ssh_packet_send_debug(ssh, "X11 forwarding disabled by key options."); return 0; } - if (!options.x11_forwarding) { + if (!options.x11_forwarding || options.disable_forwarding) { debug("X11 forwarding disabled in server configuration file."); return 0; } diff --git a/sftp-client.c b/sftp-client.c index be40d20..840170a 100644 --- a/sftp-client.c +++ b/sftp-client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-client.c,v 1.176 2024/05/17 02:39:11 jsg Exp $ */ +/* $OpenBSD: sftp-client.c,v 1.180 2025/09/30 00:10:42 djm Exp $ */ /* * Copyright (c) 2001-2004 Damien Miller * @@ -27,23 +27,13 @@ #include #endif #include "openbsd-compat/sys-queue.h" -#ifdef HAVE_SYS_STAT_H -# include -#endif -#ifdef HAVE_SYS_TIME_H -# include -#endif +#include +#include #include #include #include -#ifdef HAVE_POLL_H #include -#else -# ifdef HAVE_SYS_POLL_H -# include -# endif -#endif #include #include #include @@ -611,6 +601,14 @@ sftp_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests, return ret; } +void +sftp_free(struct sftp_conn *conn) +{ + if (conn == NULL) + return; + freezero(conn, sizeof(*conn)); +} + u_int sftp_proto_version(struct sftp_conn *conn) { @@ -1138,7 +1136,7 @@ sftp_copy(struct sftp_conn *conn, const char *oldpath, const char *newpath) attr.flags |= SSH2_FILEXFER_ATTR_PERMISSIONS; if ((msg = sshbuf_new()) == NULL) - fatal("%s: sshbuf_new failed", __func__); + fatal_f("sshbuf_new failed"); attrib_clear(&junk); /* Send empty attributes */ @@ -1149,7 +1147,7 @@ sftp_copy(struct sftp_conn *conn, const char *oldpath, const char *newpath) (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)); + fatal_fr(r, "buffer error"); send_msg(conn, msg); debug3("Sent message SSH2_FXP_OPEN I:%u P:%s", id, oldpath); @@ -1170,7 +1168,7 @@ sftp_copy(struct sftp_conn *conn, const char *oldpath, const char *newpath) (r = sshbuf_put_u32(msg, SSH2_FXF_WRITE|SSH2_FXF_CREAT| SSH2_FXF_TRUNC)) != 0 || (r = encode_attrib(msg, &attr)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "buffer error"); send_msg(conn, msg); debug3("Sent message SSH2_FXP_OPEN I:%u P:%s", id, newpath); @@ -1194,7 +1192,7 @@ sftp_copy(struct sftp_conn *conn, const char *oldpath, const char *newpath) (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)); + fatal_fr(r, "buffer error"); send_msg(conn, msg); debug3("Sent message copy-data \"%s\" 0 0 -> \"%s\" 0", oldpath, newpath); @@ -2034,7 +2032,7 @@ sftp_upload(struct sftp_conn *conn, const char *local_path, int fsync_flag, int inplace_flag) { int r, local_fd; - u_int openmode, id, status = SSH2_FX_OK, reordered = 0; + u_int openmode, id, status = SSH2_FX_OK, status2, reordered = 0; off_t offset, progress_counter; u_char type, *handle, *data; struct sshbuf *msg; @@ -2091,6 +2089,7 @@ sftp_upload(struct sftp_conn *conn, const char *local_path, close(local_fd); return -1; } + highwater = c.size; } openmode = SSH2_FXF_WRITE|SSH2_FXF_CREAT; @@ -2171,9 +2170,11 @@ sftp_upload(struct sftp_conn *conn, const char *local_path, fatal("Expected SSH2_FXP_STATUS(%d) packet, " "got %d", SSH2_FXP_STATUS, type); - if ((r = sshbuf_get_u32(msg, &status)) != 0) + if ((r = sshbuf_get_u32(msg, &status2)) != 0) fatal_fr(r, "parse status"); - debug3("SSH2_FXP_STATUS %u", status); + debug3("SSH2_FXP_STATUS %u", status2); + if (status2 != SSH2_FX_OK) + status = status2; /* remember errors */ /* Find the request in our queue */ if ((ack = request_find(&acks, rid)) == NULL) diff --git a/sftp-client.h b/sftp-client.h index 74cdae7..873ad38 100644 --- a/sftp-client.h +++ b/sftp-client.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-client.h,v 1.39 2023/09/08 05:56:13 djm Exp $ */ +/* $OpenBSD: sftp-client.h,v 1.40 2025/09/15 05:17:37 djm Exp $ */ /* * Copyright (c) 2001-2004 Damien Miller @@ -71,6 +71,7 @@ struct sftp_limits { * a pointer to a initialized sftp_conn struct on success. */ struct sftp_conn *sftp_init(int, int, u_int, u_int, u_int64_t); +void sftp_free(struct sftp_conn *); u_int sftp_proto_version(struct sftp_conn *); diff --git a/sftp-common.c b/sftp-common.c index 5d72498..4abd54a 100644 --- a/sftp-common.c +++ b/sftp-common.c @@ -37,9 +37,7 @@ #include #include #include -#ifdef HAVE_UTIL_H #include -#endif #include "xmalloc.h" #include "ssherr.h" diff --git a/sftp-glob.c b/sftp-glob.c index 1b82759..e054e75 100644 --- a/sftp-glob.c +++ b/sftp-glob.c @@ -18,9 +18,7 @@ #include "includes.h" #include -#ifdef HAVE_SYS_STAT_H -# include -#endif +#include #include #include diff --git a/sftp-server.0 b/sftp-server.0 index f86aaf1..273b699 100644 --- a/sftp-server.0 +++ b/sftp-server.0 @@ -95,4 +95,4 @@ HISTORY AUTHORS Markus Friedl -OpenBSD 7.6 July 27, 2021 OpenBSD 7.6 +OpenBSD 7.7 July 27, 2021 OpenBSD 7.7 diff --git a/sftp-server.c b/sftp-server.c index a4abb9f..777821a 100644 --- a/sftp-server.c +++ b/sftp-server.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-server.c,v 1.148 2024/04/30 06:23:51 djm Exp $ */ +/* $OpenBSD: sftp-server.c,v 1.149 2025/09/02 09:26:21 djm Exp $ */ /* * Copyright (c) 2000-2004 Markus Friedl. All rights reserved. * @@ -20,9 +20,7 @@ #include #include #include -#ifdef HAVE_SYS_TIME_H -# include -#endif +#include #ifdef HAVE_SYS_MOUNT_H #include #endif @@ -33,9 +31,7 @@ #include #include #include -#ifdef HAVE_POLL_H #include -#endif #include #include #include @@ -1620,7 +1616,7 @@ process_extended_copy_data(u_int32_t id) (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)); + fatal_fr(r, "buffer error"); debug("request %u: copy-data from \"%s\" (handle %d) off %llu len %llu " "to \"%s\" (handle %d) off %llu", @@ -1648,14 +1644,14 @@ process_extended_copy_data(u_int32_t id) if (lseek(read_fd, read_off, SEEK_SET) < 0) { status = errno_to_portable(errno); - error("%s: read_seek failed", __func__); + error_f("read_seek failed"); 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__); + error_f("write_seek failed"); goto out; } @@ -1670,7 +1666,7 @@ process_extended_copy_data(u_int32_t id) break; } else if (ret == 0) { status = errno_to_portable(errno); - error("%s: read failed: %s", __func__, strerror(errno)); + error_f("read failed: %s", strerror(errno)); break; } len = ret; diff --git a/sftp.0 b/sftp.0 index 97fde6a..d6648ac 100644 --- a/sftp.0 +++ b/sftp.0 @@ -116,67 +116,106 @@ DESCRIPTION of the options listed below, and their possible values, see ssh_config(5). + AddKeysToAgent AddressFamily BatchMode BindAddress BindInterface + CASignatureAlgorithms CanonicalDomains CanonicalizeFallbackLocal CanonicalizeHostname CanonicalizeMaxDots CanonicalizePermittedCNAMEs - CASignatureAlgorithms CertificateFile + ChannelTimeout CheckHostIP Ciphers + ClearAllForwardings Compression - ConnectionAttempts ConnectTimeout + ConnectionAttempts ControlMaster ControlPath ControlPersist - GlobalKnownHostsFile + DynamicForward + EnableEscapeCommandline + EnableSSHKeysign + EscapeChar + ExitOnForwardFailure + FingerprintHash + ForkAfterAuthentication + ForwardAgent + ForwardX11 + ForwardX11Timeout + ForwardX11Trusted GSSAPIAuthentication GSSAPIDelegateCredentials + GatewayPorts + GlobalKnownHostsFile HashKnownHosts Host - HostbasedAcceptedAlgorithms - HostbasedAuthentication HostKeyAlgorithms HostKeyAlias + HostbasedAcceptedAlgorithms + HostbasedAuthentication Hostname + IPQoS IdentitiesOnly IdentityAgent IdentityFile - IPQoS + IgnoreUnknown + Include KbdInteractiveAuthentication KbdInteractiveDevices KexAlgorithms KnownHostsCommand + LocalCommand + LocalForward LogLevel + LogVerbose MACs NoHostAuthenticationForLocalhost NumberOfPasswordPrompts - PasswordAuthentication + ObscureKeystrokeTiming PKCS11Provider + PasswordAuthentication + PermitLocalCommand + PermitRemoteOpen Port PreferredAuthentications ProxyCommand ProxyJump + ProxyUseFdpass PubkeyAcceptedAlgorithms PubkeyAuthentication RekeyLimit + RemoteCommand + RemoteForward + RequestTTY RequiredRSASize + RevokedHostKeys + SecurityKeyProvider SendEnv - ServerAliveInterval ServerAliveCountMax + ServerAliveInterval + SessionType SetEnv + StdinNull + StreamLocalBindMask + StreamLocalBindUnlink StrictHostKeyChecking + SyslogFacility TCPKeepAlive + Tag + Tunnel + TunnelDevice UpdateHostKeys User UserKnownHostsFile VerifyHostKeyDNS + VisualHostKey + XAuthLocation -P port Specifies the port to connect to on the remote host. @@ -435,4 +474,4 @@ SEE ALSO T. Ylonen and S. Lehtinen, SSH File Transfer Protocol, draft-ietf-secsh- filexfer-00.txt, January 2001, work in progress material. -OpenBSD 7.6 December 16, 2022 OpenBSD 7.6 +OpenBSD 7.7 December 6, 2024 OpenBSD 7.7 diff --git a/sftp.1 b/sftp.1 index 68923ae..651baaf 100644 --- a/sftp.1 +++ b/sftp.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: sftp.1,v 1.143 2022/12/16 03:40:03 djm Exp $ +.\" $OpenBSD: sftp.1,v 1.144 2024/12/06 15:12:56 djm Exp $ .\" .\" Copyright (c) 2001 Damien Miller. All rights reserved. .\" @@ -22,7 +22,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: December 16 2022 $ +.Dd $Mdocdate: December 6 2024 $ .Dt SFTP 1 .Os .Sh NAME @@ -224,67 +224,106 @@ 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 BindInterface +.It CASignatureAlgorithms .It CanonicalDomains .It CanonicalizeFallbackLocal .It CanonicalizeHostname .It CanonicalizeMaxDots .It CanonicalizePermittedCNAMEs -.It CASignatureAlgorithms .It CertificateFile +.It ChannelTimeout .It CheckHostIP .It Ciphers +.It ClearAllForwardings .It Compression -.It ConnectionAttempts .It ConnectTimeout +.It ConnectionAttempts .It ControlMaster .It ControlPath .It ControlPersist -.It GlobalKnownHostsFile +.It DynamicForward +.It EnableEscapeCommandline +.It EnableSSHKeysign +.It EscapeChar +.It ExitOnForwardFailure +.It FingerprintHash +.It ForkAfterAuthentication +.It ForwardAgent +.It ForwardX11 +.It ForwardX11Timeout +.It ForwardX11Trusted .It GSSAPIAuthentication .It GSSAPIDelegateCredentials +.It GatewayPorts +.It GlobalKnownHostsFile .It HashKnownHosts .It Host -.It HostbasedAcceptedAlgorithms -.It HostbasedAuthentication .It HostKeyAlgorithms .It HostKeyAlias +.It HostbasedAcceptedAlgorithms +.It HostbasedAuthentication .It Hostname +.It IPQoS .It IdentitiesOnly .It IdentityAgent .It IdentityFile -.It IPQoS +.It IgnoreUnknown +.It Include .It KbdInteractiveAuthentication .It KbdInteractiveDevices .It KexAlgorithms .It KnownHostsCommand +.It LocalCommand +.It LocalForward .It LogLevel +.It LogVerbose .It MACs .It NoHostAuthenticationForLocalhost .It NumberOfPasswordPrompts -.It PasswordAuthentication +.It ObscureKeystrokeTiming .It PKCS11Provider +.It PasswordAuthentication +.It PermitLocalCommand +.It PermitRemoteOpen .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 RevokedHostKeys +.It SecurityKeyProvider .It SendEnv -.It ServerAliveInterval .It ServerAliveCountMax +.It ServerAliveInterval +.It SessionType .It SetEnv +.It StdinNull +.It StreamLocalBindMask +.It StreamLocalBindUnlink .It StrictHostKeyChecking +.It SyslogFacility .It TCPKeepAlive +.It Tag +.It Tunnel +.It TunnelDevice .It UpdateHostKeys .It User .It UserKnownHostsFile .It VerifyHostKeyDNS +.It VisualHostKey +.It XAuthLocation .El .It Fl P Ar port Specifies the port to connect to on the remote host. diff --git a/sftp.c b/sftp.c index 360c500..3b505ee 100644 --- a/sftp.c +++ b/sftp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp.c,v 1.239 2024/06/26 23:14:14 deraadt Exp $ */ +/* $OpenBSD: sftp.c,v 1.245 2025/10/02 04:23:11 djm Exp $ */ /* * Copyright (c) 2001-2004 Damien Miller * @@ -19,9 +19,7 @@ #include #include -#ifdef HAVE_SYS_STAT_H -# include -#endif +#include #include #include #ifdef HAVE_SYS_STATVFS_H @@ -31,12 +29,8 @@ #include #include -#ifdef HAVE_PATHS_H -# include -#endif -#ifdef HAVE_LIBGEN_H +#include #include -#endif #ifdef HAVE_LOCALE_H # include #endif @@ -53,9 +47,7 @@ typedef void EditLine; #include #include -#ifdef HAVE_UTIL_H -# include -#endif +#include #include "xmalloc.h" #include "log.h" @@ -1865,7 +1857,7 @@ complete_display(char **list, u_int len) /* * Given a "list" of words that begin with a common prefix of "word", - * attempt to find an autocompletion to extends "word" by the next + * attempt to find an autocompletion that extends "word" by the next * characters common to all entries in "list". */ static char * @@ -2351,6 +2343,8 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2) free(conn); #ifdef USE_LIBEDIT + if (hl != NULL) + history_end(hl); if (el != NULL) el_end(el); #endif /* USE_LIBEDIT */ @@ -2463,6 +2457,7 @@ main(int argc, char **argv) addargs(&args, "-oForwardX11 no"); addargs(&args, "-oPermitLocalCommand no"); addargs(&args, "-oClearAllForwardings yes"); + addargs(&args, "-oControlMaster no"); ll = SYSLOG_LEVEL_INFO; infile = stdin; @@ -2661,7 +2656,7 @@ main(int argc, char **argv) } else { if ((r = argv_split(sftp_direct, &tmp, &cpp, 1)) != 0) fatal_r(r, "Parse -D arguments"); - if (cpp[0] == 0) + if (cpp[0] == NULL) fatal("No sftp server specified via -D"); connect_to_server(cpp[0], cpp, &in, &out); argv_free(cpp, tmp); diff --git a/sk-api.h b/sk-api.h index 08f567a..32d0f11 100644 --- a/sk-api.h +++ b/sk-api.h @@ -19,9 +19,7 @@ #define _SK_API_H 1 #include -#ifdef HAVE_STDINT_H #include -#endif /* Flags */ #define SSH_SK_USER_PRESENCE_REQD 0x01 diff --git a/sk-usbhid.c b/sk-usbhid.c index 812b28d..cd24881 100644 --- a/sk-usbhid.c +++ b/sk-usbhid.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sk-usbhid.c,v 1.46 2023/03/28 06:12:38 dtucker Exp $ */ +/* $OpenBSD: sk-usbhid.c,v 1.48 2025/05/12 05:41:20 tb Exp $ */ /* * Copyright (c) 2019 Markus Friedl * Copyright (c) 2020 Pedro Martelletto @@ -20,9 +20,7 @@ #ifdef ENABLE_SK_INTERNAL -#ifdef HAVE_STDINT_H -# include -#endif +#include #include #include #include @@ -49,6 +47,7 @@ #include #include #include +#include "openbsd-compat/openssl-compat.h" #endif /* WITH_OPENSSL */ #include @@ -77,10 +76,11 @@ #define FIDO_CRED_PROT_UV_OPTIONAL_WITH_ID 0 #endif +# include "misc.h" + #ifndef SK_STANDALONE # include "log.h" # include "xmalloc.h" -# include "misc.h" /* * If building as part of OpenSSH, then rename exported functions. * This must be done before including sk-api.h. @@ -635,8 +635,8 @@ pack_public_key_ecdsa(const fido_cred_t *cred, skdebug(__func__, "BN_bin2bn failed"); goto out; } - if (EC_POINT_set_affine_coordinates_GFp(g, q, x, y, NULL) != 1) { - skdebug(__func__, "EC_POINT_set_affine_coordinates_GFp failed"); + if (EC_POINT_set_affine_coordinates(g, q, x, y, NULL) != 1) { + skdebug(__func__, "EC_POINT_set_affine_coordinates failed"); goto out; } response->public_key_len = EC_POINT_point2oct(g, q, @@ -960,13 +960,15 @@ sk_enroll(uint32_t alg, const uint8_t *challenge, size_t challenge_len, fido_strerr(r)); goto out; } - } else { + } else if (strcmp(fido_cred_fmt(cred), "none") != 0) { skdebug(__func__, "self-attested credential"); if ((r = fido_cred_verify_self(cred)) != FIDO_OK) { skdebug(__func__, "fido_cred_verify_self: %s", fido_strerr(r)); goto out; } + } else { + skdebug(__func__, "no attestation data"); } if ((response = calloc(1, sizeof(*response))) == NULL) { skdebug(__func__, "calloc response failed"); diff --git a/srclimit.c b/srclimit.c index 33116fa..c627637 100644 --- a/srclimit.c +++ b/srclimit.c @@ -119,7 +119,7 @@ srclimit_init(int max, int persource, int ipv4len, int ipv6len, debug("%s: max connections %d, per source %d, masks %d,%d", __func__, max, persource, ipv4len, ipv6len); if (max <= 0) - fatal("%s: invalid number of sockets: %d", __func__, max); + fatal_f("invalid number of sockets: %d", max); children = xcalloc(max_children, sizeof(*children)); for (i = 0; i < max_children; i++) children[i].id = -1; @@ -136,7 +136,7 @@ srclimit_check_allow(int sock, int id) if (max_persource == INT_MAX) /* no limit */ return 1; - debug("%s: sock %d id %d limit %d", __func__, sock, id, max_persource); + debug_f("sock %d id %d limit %d", sock, id, max_persource); if (srclimit_peer_addr(sock, &xa) != 0) return 1; bits = xa.af == AF_INET ? ipv4_masklen : ipv6_masklen; @@ -154,14 +154,14 @@ srclimit_check_allow(int sock, int id) } } if (addr_ntop(&xa, xas, sizeof(xas)) != 0) { - debug3("%s: addr ntop failed", __func__); + debug3_f("addr ntop failed"); return 1; } debug3("%s: new unauthenticated connection from %s/%d, at %d of %d", __func__, xas, bits, count, max_persource); if (first_unused == max_children) { /* no free slot found */ - debug3("%s: no free slot", __func__); + debug3_f("no free slot"); return 0; } if (first_unused < 0 || first_unused >= max_children) @@ -185,7 +185,7 @@ srclimit_done(int id) if (max_persource == INT_MAX) /* no limit */ return; - debug("%s: id %d", __func__, id); + debug_f("id %d", id); /* Clear corresponding state entry. */ for (i = 0; i < max_children; i++) { if (children[i].id == id) { @@ -386,7 +386,7 @@ srclimit_penalise(struct xaddr *addr, int penalty_type) reason = "penalty: connection prohibited by RefuseConnection"; break; case SRCLIMIT_PENALTY_GRACE_EXCEEDED: - penalty_secs = penalty_cfg.penalty_crash; + penalty_secs = penalty_cfg.penalty_grace; reason = "penalty: exceeded LoginGraceTime"; break; default: @@ -427,7 +427,9 @@ srclimit_penalise(struct xaddr *addr, int penalty_type) penalty->active = 1; if (RB_INSERT(penalties_by_expiry, by_expiry, penalty) != NULL) fatal_f("internal error: %s penalty tables corrupt", t); - verbose_f("%s: new %s %s penalty of %d seconds for %s", t, + do_log2_f(penalty->active ? + SYSLOG_LEVEL_INFO : SYSLOG_LEVEL_VERBOSE, + "%s: new %s %s penalty of %d seconds for %s", t, addrnetmask, penalty->active ? "active" : "deferred", penalty_secs, reason); if (++(*npenaltiesp) > (size_t)max_sources) @@ -446,7 +448,7 @@ srclimit_penalise(struct xaddr *addr, int penalty_type) existing->expiry = now + penalty_cfg.penalty_max; if (existing->expiry - now > penalty_cfg.penalty_min && !existing->active) { - verbose_f("%s: activating %s penalty of %lld seconds for %s", + logit_f("%s: activating %s penalty of %lld seconds for %s", addrnetmask, t, (long long)(existing->expiry - now), reason); existing->active = 1; diff --git a/ssh-add.0 b/ssh-add.0 index af99011..a6b655d 100644 --- a/ssh-add.0 +++ b/ssh-add.0 @@ -4,7 +4,7 @@ NAME ssh-add M-bM-^@M-^S adds private key identities to the OpenSSH authentication agent SYNOPSIS - ssh-add [-CcDdKkLlqvXx] [-E fingerprint_hash] [-H hostkey_file] + ssh-add [-CcDdKkLlNqvXx] [-E fingerprint_hash] [-H hostkey_file] [-h destination_constraint] [-S provider] [-t life] [file ...] ssh-add -s pkcs11 [-Cv] [certificate ...] ssh-add -e pkcs11 @@ -120,6 +120,12 @@ DESCRIPTION -l Lists fingerprints of all identities currently represented by the agent. + -N When adding certificates, by default ssh-add will request that + the agent automatically delete the certificate shortly after the + certificate's expiry date. This flag suppresses this behaviour + and does not specify a lifetime for certificates added to an + agent. + -q Be quiet after a successful operation. -S provider @@ -206,4 +212,4 @@ AUTHORS created OpenSSH. Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. -OpenBSD 7.6 June 17, 2024 OpenBSD 7.6 +OpenBSD 7.7 September 11, 2025 OpenBSD 7.7 diff --git a/ssh-add.1 b/ssh-add.1 index c31de4d..babe780 100644 --- a/ssh-add.1 +++ b/ssh-add.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-add.1,v 1.87 2024/06/17 08:30:29 djm Exp $ +.\" $OpenBSD: ssh-add.1,v 1.88 2025/09/11 02:54:42 djm Exp $ .\" .\" Author: Tatu Ylonen .\" Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -35,7 +35,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: June 17 2024 $ +.Dd $Mdocdate: September 11 2025 $ .Dt SSH-ADD 1 .Os .Sh NAME @@ -43,7 +43,7 @@ .Nd adds private key identities to the OpenSSH authentication agent .Sh SYNOPSIS .Nm ssh-add -.Op Fl CcDdKkLlqvXx +.Op Fl CcDdKkLlNqvXx .Op Fl E Ar fingerprint_hash .Op Fl H Ar hostkey_file .Op Fl h Ar destination_constraint @@ -223,6 +223,13 @@ Lists public key parameters of all identities currently represented by the agent. .It Fl l Lists fingerprints of all identities currently represented by the agent. +.It Fl N +When adding certificates, by default +.Nm +will request that the agent automatically delete the certificate shortly +after the certificate's expiry date. +This flag suppresses this behaviour and does not specify a lifetime for +certificates added to an agent. .It Fl q Be quiet after a successful operation. .It Fl S Ar provider diff --git a/ssh-add.c b/ssh-add.c index 0035cb8..2d5bec8 100644 --- a/ssh-add.c +++ b/ssh-add.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-add.c,v 1.173 2024/09/06 02:30:44 djm Exp $ */ +/* $OpenBSD: ssh-add.c,v 1.181 2025/09/29 03:17:54 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -54,6 +54,7 @@ #include #include #include +#include #include "xmalloc.h" #include "ssh.h" @@ -70,6 +71,8 @@ #include "sk-api.h" #include "hostfile.h" +#define CERT_EXPIRY_GRACE (5*60) + /* argv0 */ extern char *__progname; @@ -84,10 +87,6 @@ static char *default_files[] = { #endif /* WITH_OPENSSL */ _PATH_SSH_CLIENT_ID_ED25519, _PATH_SSH_CLIENT_ID_ED25519_SK, - _PATH_SSH_CLIENT_ID_XMSS, -#ifdef WITH_DSA - _PATH_SSH_CLIENT_ID_DSA, -#endif NULL }; @@ -99,10 +98,6 @@ static int lifetime = 0; /* User has to confirm key use */ static int confirm = 0; -/* Maximum number of signatures (XMSS) */ -static u_int maxsign = 0; -static u_int minleft = 0; - /* we keep a cache of one passphrase */ static char *pass = NULL; static void @@ -242,20 +237,37 @@ delete_all(int agent_fd, int qflag) return ret; } +static int +check_cert_lifetime(const struct sshkey *cert, int cert_lifetime) +{ + time_t now; + uint64_t n; + + if (cert == NULL || cert->cert == NULL || !sshkey_is_cert(cert) || + cert->cert->valid_before == 0xFFFFFFFFFFFFFFFFULL) + return cert_lifetime; + if ((now = time(NULL)) <= 0) + fatal_f("system time is at/before epoch"); + if ((uint64_t)now > (cert->cert->valid_before + CERT_EXPIRY_GRACE)) + return -1; /* certificate already expired */ + n = (CERT_EXPIRY_GRACE + cert->cert->valid_before) - (uint64_t)now; + n = MINIMUM(n, INT_MAX); + if (cert_lifetime <= 0) + return (int)n; + return MINIMUM(cert_lifetime, (int)n); +} + static int add_file(int agent_fd, const char *filename, int key_only, int cert_only, - int qflag, const char *skprovider, + int qflag, int Nflag, const char *skprovider, struct dest_constraint **dest_constraints, size_t ndest_constraints) { - struct sshkey *private, *cert; + struct sshkey *private = NULL, *cert = NULL; char *comment = NULL; char msg[1024], *certpath = NULL; - int r, fd, ret = -1; - size_t i; - u_int32_t left; + int cert_lifetime, r, fd, ret = -1; struct sshbuf *keyblob; - struct ssh_identitylist *idlist; if (strcmp(filename, "-") == 0) { fd = STDIN_FILENO; @@ -331,38 +343,6 @@ add_file(int agent_fd, const char *filename, int key_only, int cert_only, comment = xstrdup(filename); sshbuf_free(keyblob); - /* For XMSS */ - if ((r = sshkey_set_filename(private, filename)) != 0) { - fprintf(stderr, "Could not add filename to private key: %s (%s)\n", - filename, comment); - goto out; - } - if (maxsign && minleft && - (r = ssh_fetch_identitylist(agent_fd, &idlist)) == 0) { - for (i = 0; i < idlist->nkeys; i++) { - if (!sshkey_equal_public(idlist->keys[i], private)) - continue; - left = sshkey_signatures_left(idlist->keys[i]); - if (left < minleft) { - fprintf(stderr, - "Only %d signatures left.\n", left); - break; - } - fprintf(stderr, "Skipping update: "); - if (left == minleft) { - fprintf(stderr, - "required signatures left (%d).\n", left); - } else { - fprintf(stderr, - "more signatures left (%d) than" - " required (%d).\n", left, minleft); - } - ssh_free_identitylist(idlist); - goto out; - } - ssh_free_identitylist(idlist); - } - if (sshkey_is_sk(private)) { if (skprovider == NULL) { fprintf(stderr, "Cannot load FIDO key %s " @@ -374,26 +354,27 @@ add_file(int agent_fd, const char *filename, int key_only, int cert_only, skprovider = NULL; } - if (!cert_only && - (r = ssh_add_identity_constrained(agent_fd, private, comment, - lifetime, confirm, maxsign, skprovider, - dest_constraints, ndest_constraints)) == 0) { - ret = 0; - if (!qflag) { - fprintf(stderr, "Identity added: %s (%s)\n", - filename, comment); - if (lifetime != 0) { - fprintf(stderr, - "Lifetime set to %d seconds\n", lifetime); - } - if (confirm != 0) { - fprintf(stderr, "The user must confirm " - "each use of the key\n"); + if (!cert_only) { + if ((r = ssh_add_identity_constrained(agent_fd, private, + comment, lifetime, confirm, skprovider, + dest_constraints, ndest_constraints)) == 0) { + ret = 0; + if (!qflag) { + fprintf(stderr, "Identity added: %s (%s)\n", + filename, comment); + if (lifetime != 0) { + fprintf(stderr, "Lifetime set to %s\n", + fmt_timeframe((time_t)lifetime)); + } + if (confirm != 0) { + fprintf(stderr, "The user must confirm " + "each use of the key\n"); + } } + } else { + fprintf(stderr, "Could not add identity \"%s\": %s\n", + filename, ssh_err(r)); } - } else { - fprintf(stderr, "Could not add identity \"%s\": %s\n", - filename, ssh_err(r)); } /* Skip trying to load the cert if requested */ @@ -412,25 +393,28 @@ add_file(int agent_fd, const char *filename, int key_only, int cert_only, if (!sshkey_equal_public(cert, private)) { error("Certificate %s does not match private key %s", certpath, filename); - sshkey_free(cert); + goto out; + } + + cert_lifetime = lifetime; + if (!Nflag && + (cert_lifetime = check_cert_lifetime(cert, cert_lifetime)) == -1) { + logit("Certificate %s has already expired; ignored", certpath); goto out; } /* Graft with private bits */ if ((r = sshkey_to_certified(private)) != 0) { error_fr(r, "sshkey_to_certified"); - sshkey_free(cert); goto out; } if ((r = sshkey_cert_copy(cert, private)) != 0) { error_fr(r, "sshkey_cert_copy"); - sshkey_free(cert); goto out; } - sshkey_free(cert); - + /* send to agent */ if ((r = ssh_add_identity_constrained(agent_fd, private, comment, - lifetime, confirm, maxsign, skprovider, + cert_lifetime, confirm, skprovider, dest_constraints, ndest_constraints)) != 0) { error_r(r, "Certificate %s (%s) add failed", certpath, private->cert->key_id); @@ -440,9 +424,9 @@ add_file(int agent_fd, const char *filename, int key_only, int cert_only, if (!qflag) { fprintf(stderr, "Certificate added: %s (%s)\n", certpath, private->cert->key_id); - if (lifetime != 0) { - fprintf(stderr, "Lifetime set to %d seconds\n", - lifetime); + if (cert_lifetime != 0) { + fprintf(stderr, "Lifetime set to %s\n", + fmt_timeframe((time_t)cert_lifetime)); } if (confirm != 0) { fprintf(stderr, "The user must confirm each use " @@ -453,6 +437,7 @@ add_file(int agent_fd, const char *filename, int key_only, int cert_only, out: free(certpath); free(comment); + sshkey_free(cert); sshkey_free(private); return ret; @@ -534,7 +519,6 @@ list_identities(int agent_fd, int do_fp) char *fp; int r; struct ssh_identitylist *idlist; - u_int32_t left; size_t i; if ((r = ssh_fetch_identitylist(agent_fd, &idlist)) != 0) { @@ -559,12 +543,7 @@ list_identities(int agent_fd, int do_fp) ssh_err(r)); continue; } - fprintf(stdout, " %s", idlist->comments[i]); - left = sshkey_signatures_left(idlist->keys[i]); - if (left > 0) - fprintf(stdout, - " [signatures left %d]", left); - fprintf(stdout, "\n"); + fprintf(stdout, " %s\n", idlist->comments[i]); } } ssh_free_identitylist(idlist); @@ -623,7 +602,7 @@ load_resident_keys(int agent_fd, const char *skprovider, int qflag, fingerprint_hash, SSH_FP_DEFAULT)) == NULL) fatal_f("sshkey_fingerprint failed"); if ((r = ssh_add_identity_constrained(agent_fd, key, "", - lifetime, confirm, maxsign, skprovider, + lifetime, confirm, skprovider, dest_constraints, ndest_constraints)) != 0) { error("Unable to add key %s %s", sshkey_type(key), fp); @@ -655,7 +634,7 @@ load_resident_keys(int agent_fd, const char *skprovider, int qflag, static int do_file(int agent_fd, int deleting, int key_only, int cert_only, - char *file, int qflag, const char *skprovider, + char *file, int qflag, int Nflag, const char *skprovider, struct dest_constraint **dest_constraints, size_t ndest_constraints) { if (deleting) { @@ -663,7 +642,7 @@ do_file(int agent_fd, int deleting, int key_only, int cert_only, cert_only, qflag) == -1) return -1; } else { - if (add_file(agent_fd, file, key_only, cert_only, qflag, + if (add_file(agent_fd, file, key_only, cert_only, qflag, Nflag, skprovider, dest_constraints, ndest_constraints) == -1) return -1; } @@ -686,6 +665,47 @@ stringlist_append(char ***listp, const char *s) (*listp)[i] = xstrdup(s); } +static void +stringlist_free(char **list) +{ + size_t i = 0; + + if (list == NULL) + return; + for (i = 0; list[i] != NULL; i++) + free(list[i]); + free(list); +} + +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[i]); + } + free(dcs); +} + + static void parse_dest_constraint_hop(const char *s, struct dest_constraint_hop *dch, char **hostkey_files) @@ -794,9 +814,6 @@ usage(void) fprintf(stderr, "usage: ssh-add [-CcDdKkLlqvXx] [-E fingerprint_hash] [-H hostkey_file]\n" " [-h destination_constraint] [-S provider] [-t life]\n" -#ifdef WITH_XMSS -" [-M maxsign] [-m minleft]\n" -#endif " [file ...]\n" " ssh-add -s pkcs11 [-Cv] [certificate ...]\n" " ssh-add -e pkcs11\n" @@ -814,12 +831,12 @@ main(int argc, char **argv) char **dest_constraint_strings = NULL, **hostkey_files = NULL; int r, i, ch, deleting = 0, ret = 0, key_only = 0, cert_only = 0; int do_download = 0, xflag = 0, lflag = 0, Dflag = 0; - int qflag = 0, Tflag = 0; + int qflag = 0, Tflag = 0, Nflag = 0; SyslogFacility log_facility = SYSLOG_FACILITY_AUTH; LogLevel log_level = SYSLOG_LEVEL_INFO; struct sshkey *k, **certs = NULL; struct dest_constraint **dest_constraints = NULL; - size_t ndest_constraints = 0, ncerts = 0; + size_t n, ndest_constraints = 0, ncerts = 0; /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ sanitise_stdfd(); @@ -846,7 +863,7 @@ main(int argc, char **argv) skprovider = getenv("SSH_SK_PROVIDER"); - while ((ch = getopt(argc, argv, "vkKlLCcdDTxXE:e:h:H:M:m:qs:S:t:")) != -1) { + while ((ch = getopt(argc, argv, "vkKlLNCcdDTxXE:e:h:H:M:m:qs:S:t:")) != -1) { switch (ch) { case 'v': if (log_level == SYSLOG_LEVEL_INFO) @@ -854,6 +871,9 @@ main(int argc, char **argv) else if (log_level < SYSLOG_LEVEL_DEBUG3) log_level++; break; + case 'N': + Nflag = 1; + break; case 'E': fingerprint_hash = ssh_digest_alg_by_name(optarg); if (fingerprint_hash == -1) @@ -890,20 +910,8 @@ main(int argc, char **argv) confirm = 1; break; case 'm': - minleft = (u_int)strtonum(optarg, 1, UINT_MAX, NULL); - if (minleft == 0) { - usage(); - ret = 1; - goto done; - } - break; case 'M': - maxsign = (u_int)strtonum(optarg, 1, UINT_MAX, NULL); - if (maxsign == 0) { - usage(); - ret = 1; - goto done; - } + /* deprecated */ break; case 'd': deleting = 1; @@ -1003,6 +1011,9 @@ main(int argc, char **argv) dest_constraints, ndest_constraints, certs, ncerts) == -1) ret = 1; + for (n = 0; n < ncerts; n++) + sshkey_free(certs[n]); + free(certs); goto done; } if (do_download) { @@ -1032,7 +1043,7 @@ main(int argc, char **argv) if (stat(buf, &st) == -1) continue; if (do_file(agent_fd, deleting, key_only, cert_only, - buf, qflag, skprovider, + buf, qflag, Nflag, skprovider, dest_constraints, ndest_constraints) == -1) ret = 1; else @@ -1043,13 +1054,16 @@ main(int argc, char **argv) } else { for (i = 0; i < argc; i++) { if (do_file(agent_fd, deleting, key_only, cert_only, - argv[i], qflag, skprovider, + argv[i], qflag, Nflag, skprovider, dest_constraints, ndest_constraints) == -1) ret = 1; } } done: clear_pass(); + stringlist_free(hostkey_files); + stringlist_free(dest_constraint_strings); + free_dest_constraints(dest_constraints, ndest_constraints); ssh_close_authentication_socket(agent_fd); return ret; } diff --git a/ssh-agent.0 b/ssh-agent.0 index 33971e9..95d4da4 100644 --- a/ssh-agent.0 +++ b/ssh-agent.0 @@ -4,11 +4,12 @@ NAME ssh-agent M-bM-^@M-^S OpenSSH authentication agent SYNOPSIS - ssh-agent [-c | -s] [-Dd] [-a bind_address] [-E fingerprint_hash] + ssh-agent [-c | -s] [-DdTU] [-a bind_address] [-E fingerprint_hash] [-O option] [-P allowed_providers] [-t life] - ssh-agent [-a bind_address] [-E fingerprint_hash] [-O option] + ssh-agent [-TU] [-a bind_address] [-E fingerprint_hash] [-O option] [-P allowed_providers] [-t life] command [arg ...] ssh-agent [-c | -s] -k + ssh-agent -u DESCRIPTION ssh-agent is a program to hold private keys used for public key @@ -20,10 +21,11 @@ DESCRIPTION -a bind_address Bind the agent to the UNIX-domain socket bind_address. The - default is $TMPDIR/ssh-XXXXXXXXXX/agent.. + default is to create a socket at a random path matching + $HOME/.ssh/agent/s.*. - -c Generate C-shell commands on stdout. This is the default if - SHELL looks like it's a csh style of shell. + -c Generate C-shell commands on standard output. This is the + default if SHELL looks like it's a csh style of shell. -D Foreground mode. When this option is specified, ssh-agent will not fork. @@ -40,8 +42,8 @@ DESCRIPTION variable). -O option - Specify an option when starting ssh-agent. Currently two options - are supported: allow-remote-pkcs11 and no-restrict-websafe. + Specify an option when starting ssh-agent. The supported options + are: allow-remote-pkcs11, no-restrict-websafe and websafe-allow. The allow-remote-pkcs11 option allows clients of a forwarded ssh-agent to load PKCS#11 or FIDO provider libraries. By default @@ -54,22 +56,37 @@ DESCRIPTION signatures using FIDO keys that might be web authentication requests. By default, ssh-agent refuses signature requests for FIDO keys where the key application string does not start with - M-bM-^@M-^\ssh:M-bM-^@M-^] and when the data to be signed does not appear to be a - ssh(1) user authentication request or a ssh-keygen(1) signature. + M-bM-^@M-^\ssh:M-bM-^@M-^] and when the data to be signed does not appear to be an + ssh(1) user authentication request or an ssh-keygen(1) signature. The default behaviour prevents forwarded access to a FIDO key from also implicitly forwarding the ability to authenticate to websites. + Alternately the websafe-allow option allows specifying a pattern- + list of key application strings to replace the default + application allow-list, for example: + M-bM-^@M-^\websafe-allow=ssh:*,example.org,*.example.comM-bM-^@M-^] + + See PATTERNS in ssh_config(5) for a description of pattern-list + syntax. + -P 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 -S or -s options to ssh-add(1). Libraries that do - not match the pattern list will be refused. See PATTERNS in - ssh_config(5) for a description of pattern-list syntax. The - default list is M-bM-^@M-^\usr/lib*/*,/usr/local/lib*/*M-bM-^@M-^]. + not match the pattern list will be refused. The default list is + M-bM-^@M-^\usr/lib*/*,/usr/local/lib*/*M-bM-^@M-^]. + + See PATTERNS in ssh_config(5) for a description of pattern-list + syntax. + + -s Generate Bourne shell commands on standard output. This is the + default if SHELL does not look like it's a csh style of shell. - -s Generate Bourne shell commands on stdout. This is the default if - SHELL does not look like it's a csh style of shell. + -T Bind the agent socket in a randomised subdirectory of the form + $TMPDIR/ssh-XXXXXXXXXX/agent., instead of the default + behaviour of using a randomised name matching + $HOME/.ssh/agent/s.*. -t life Set a default value for the maximum lifetime of identities added @@ -78,12 +95,20 @@ DESCRIPTION for an identity with ssh-add(1) overrides this value. Without this option the default maximum lifetime is forever. + -U Instructs ssh-agent not to clean up stale agent sockets under + $HOME/.ssh/agent/. + + -u Instructs ssh-agent to only clean up stale agent sockets under + $HOME/.ssh/agent/ and then exit immediately. If this option is + given twice, ssh-agent will delete stale agent sockets regardless + of the host name that created them. + command [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. - There are two main ways to get an agent set up. The first is at the + There are three 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 ssh-agent program. The agent starts a command under which its environment variables are exported, for example ssh-agent xterm @@ -94,8 +119,18 @@ DESCRIPTION variables, which in turn can be evaluated in the calling shell, for example eval `ssh-agent -s`. - In both cases, ssh(1) looks at these environment variables and uses them - to establish a connection to the agent. + In both of these cases, ssh(1) looks at these environment variables and + uses them to establish a connection to the agent. + + The third way to run ssh-agent is via socket activation from a + supervising process, such as systemd. In this mode, the supervising + process creates the listening socket and is responsible for starting + ssh-agent as needed, and also for communicating the location of the + socket listener to other programs in the user's session. Socket + activation is used when ssh-agent is started with either of the -d or -D + flags, no socket listening address specified by the -a flag, and both the + LISTEN_FDS and LISTEN_PID environment variables correctly supplied by the + supervising process. The agent initially does not have any private keys. Keys are added using ssh-add(1) or by ssh(1) when AddKeysToAgent is set in ssh_config(5). @@ -111,6 +146,8 @@ DESCRIPTION the result is returned to the requester, allowing the user access to their identities anywhere in the network in a secure fashion. + ssh-agent will delete all keys it has loaded upon receiving SIGUSR1. + ENVIRONMENT SSH_AGENT_PID When ssh-agent starts, it stores the name of the agent's process ID (PID) in this variable. @@ -121,7 +158,7 @@ ENVIRONMENT another instance of the same user. FILES - $TMPDIR/ssh-XXXXXXXXXX/agent. + $HOME/.ssh/agent/s.* UNIX-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 @@ -137,4 +174,4 @@ AUTHORS created OpenSSH. Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. -OpenBSD 7.6 August 10, 2023 OpenBSD 7.6 +OpenBSD 7.7 October 4, 2025 OpenBSD 7.7 diff --git a/ssh-agent.1 b/ssh-agent.1 index 0b93d03..f77a6cd 100644 --- a/ssh-agent.1 +++ b/ssh-agent.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-agent.1,v 1.79 2023/08/10 14:37:32 naddy Exp $ +.\" $OpenBSD: ssh-agent.1,v 1.86 2025/10/04 21:41:35 naddy Exp $ .\" .\" Author: Tatu Ylonen .\" Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -34,7 +34,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: August 10 2023 $ +.Dd $Mdocdate: October 4 2025 $ .Dt SSH-AGENT 1 .Os .Sh NAME @@ -43,13 +43,14 @@ .Sh SYNOPSIS .Nm ssh-agent .Op Fl c | s -.Op Fl \&Dd +.Op Fl \&DdTU .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 TU .Op Fl a Ar bind_address .Op Fl E Ar fingerprint_hash .Op Fl O Ar option @@ -59,6 +60,8 @@ .Nm ssh-agent .Op Fl c | s .Fl k +.Nm ssh-agent +.Fl u .Sh DESCRIPTION .Nm is a program to hold private keys used for public key authentication. @@ -74,11 +77,10 @@ Bind the agent to the .Ux Ns -domain socket .Ar bind_address . -The default is -.Pa $TMPDIR/ssh-XXXXXXXXXX/agent.\*(Ltppid\*(Gt . +The default is to create a socket at a random path matching +.Pa $HOME/.ssh/agent/s.* . .It Fl c -Generate C-shell commands on -.Dv stdout . +Generate C-shell commands on standard output. This is the default if .Ev SHELL looks like it's a csh style of shell. @@ -107,10 +109,11 @@ environment variable). .It Fl O Ar option Specify an option when starting .Nm . -Currently two options are supported: -.Cm allow-remote-pkcs11 +The supported options are: +.Cm allow-remote-pkcs11 , +.Cm no-restrict-websafe and -.Cm no-restrict-websafe . +.Cm websafe-allow . .Pp The .Cm allow-remote-pkcs11 @@ -136,13 +139,23 @@ By default, 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 +and when the data to be signed does not appear to be an .Xr ssh 1 -user authentication request or a +user authentication request or an .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. +.Pp +Alternately the +.Cm websafe-allow +option allows specifying a pattern-list of key application strings to +replace the default application allow-list, for example: +.Dq websafe-allow=ssh:*,example.org,*.example.com +.Pp +See PATTERNS in +.Xr ssh_config 5 +for a description of pattern-list syntax. .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 @@ -152,17 +165,22 @@ or options to .Xr ssh-add 1 . Libraries that do not match the pattern list will be refused. +The default list is +.Dq usr/lib*/*,/usr/local/lib*/* . +.Pp 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 . +Generate Bourne shell commands on standard output. This is the default if .Ev SHELL does not look like it's a csh style of shell. +.It Fl T +Bind the agent socket in a randomised subdirectory of the form +.Pa $TMPDIR/ssh-XXXXXXXXXX/agent.\*(Ltppid\*(Gt , +instead of the default behaviour of using a randomised name matching +.Pa $HOME/.ssh/agent/s.* . .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 @@ -171,6 +189,20 @@ 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 U +Instructs +.Nm +not to clean up stale agent sockets under +.Pa $HOME/.ssh/agent/ . +.It Fl u +Instructs +.Nm +to only clean up stale agent sockets under +.Pa $HOME/.ssh/agent/ +and then exit immediately. +If this option is given twice, +.Nm +will delete stale agent sockets regardless of the host name that created them. .It Ar command Op Ar arg ... If a command (and optional arguments) is given, this is executed as a subprocess of the agent. @@ -178,7 +210,7 @@ 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. +There are three 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 @@ -196,11 +228,33 @@ 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, +In both of these cases, .Xr ssh 1 looks at these environment variables and uses them to establish a connection to the agent. .Pp +The third way to run +.Nm +is via socket activation from a supervising process, such as systemd. +In this mode, the supervising process creates the listening socket and +is responsible for starting +.Nm +as needed, and also for communicating the location of the socket listener +to other programs in the user's session. +Socket activation is used when +.Nm +is started with either of the +.Fl d +or +.Fl D +flags, no socket listening address specified by the +.Fl a +flag, and both the +.Ev LISTEN_FDS +and +.Ev LISTEN_PID +environment variables correctly supplied by the supervising process. +.Pp The agent initially does not have any private keys. Keys are added using .Xr ssh-add 1 @@ -233,6 +287,10 @@ 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. +.Pp +.Nm +will delete all keys it has loaded upon receiving +.Dv SIGUSR1 . .Sh ENVIRONMENT .Bl -tag -width "SSH_AGENT_PID" .It Ev SSH_AGENT_PID @@ -250,7 +308,7 @@ 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. +.It Pa $HOME/.ssh/agent/s.* .Ux Ns -domain sockets used to contain the connection to the authentication agent. These sockets should only be readable by the owner. diff --git a/ssh-agent.c b/ssh-agent.c index fc8e459..df24137 100644 --- a/ssh-agent.c +++ b/ssh-agent.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-agent.c,v 1.306 2024/03/09 05:12:13 djm Exp $ */ +/* $OpenBSD: ssh-agent.c,v 1.313 2025/08/29 03:50:38 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -41,12 +41,8 @@ #include #include #include -#ifdef HAVE_SYS_TIME_H -# include -#endif -#ifdef HAVE_SYS_UN_H -# include -#endif +#include +#include #include "openbsd-compat/sys-queue.h" #ifdef WITH_OPENSSL @@ -57,12 +53,8 @@ #include #include #include -#ifdef HAVE_PATHS_H -# include -#endif -#ifdef HAVE_POLL_H -# include -#endif +#include +#include #include #include #include @@ -70,9 +62,7 @@ #include #include #include -#ifdef HAVE_UTIL_H -# include -#endif +#include #include "xmalloc.h" #include "ssh.h" @@ -94,6 +84,9 @@ #ifndef DEFAULT_ALLOWED_PROVIDERS # define DEFAULT_ALLOWED_PROVIDERS "/usr/lib*/*,/usr/local/lib*/*" #endif +#ifndef DEFAULT_WEBSAFE_ALLOWLIST +# define DEFAULT_WEBSAFE_ALLOWLIST "ssh:*" +#endif /* Maximum accepted message length */ #define AGENT_MAX_LEN (256*1024) @@ -162,7 +155,8 @@ int max_fd = 0; pid_t parent_pid = -1; time_t parent_alive_interval = 0; -sig_atomic_t signalled = 0; +static sig_atomic_t signalled_exit; +static sig_atomic_t signalled_keydrop; /* pid of process for which cleanup_socket is applicable */ pid_t cleanup_pid = 0; @@ -197,6 +191,7 @@ static int fingerprint_hash = SSH_FP_HASH_DEFAULT; /* Refuse signing of non-SSH messages for web-origin FIDO keys */ static int restrict_websafe = 1; +static char *websafe_allowlist; static void close_socket(SocketEntry *e) @@ -639,8 +634,7 @@ process_request_identities(SocketEntry *e) /* 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 || + if ((r = sshkey_puts(id->key, keys)) != 0 || (r = sshbuf_put_cstring(keys, id->comment)) != 0) { error_fr(r, "compose key/comment"); continue; @@ -924,7 +918,8 @@ process_sign_request2(SocketEntry *e) } if (sshkey_is_sk(id->key)) { if (restrict_websafe && - strncmp(id->key->sk_application, "ssh:", 4) != 0 && + match_pattern_list(id->key->sk_application, + websafe_allowlist, 0) != 1 && !check_websafe_message_contents(key, data)) { /* error already logged */ goto send; @@ -1021,7 +1016,7 @@ process_remove_identity(SocketEntry *e) } static void -process_remove_all_identities(SocketEntry *e) +remove_all_identities(void) { Identity *id; @@ -1035,6 +1030,12 @@ process_remove_all_identities(SocketEntry *e) /* Mark that there are no identities. */ idtab->nentries = 0; +} + +static void +process_remove_all_identities(SocketEntry *e) +{ + remove_all_identities(); /* Send success. */ send_status(e, 1); @@ -1280,7 +1281,7 @@ parse_key_constraints(struct sshbuf *m, struct sshkey *k, time_t *deathp, { u_char ctype; int r; - u_int seconds, maxsign = 0; + u_int seconds; while (sshbuf_len(m)) { if ((r = sshbuf_get_u8(m, &ctype)) != 0) { @@ -1309,26 +1310,6 @@ parse_key_constraints(struct sshbuf *m, struct sshkey *k, time_t *deathp, } *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, @@ -1707,6 +1688,10 @@ process_ext_session_bind(SocketEntry *e) error_fr(r, "parse"); goto out; } + if (sshbuf_len(sid) > AGENT_MAX_SID_LEN) { + error_f("session ID too long"); + goto out; + } if ((fp = sshkey_fingerprint(key, SSH_FP_HASH_DEFAULT, SSH_FP_DEFAULT)) == NULL) fatal_f("fingerprint failed"); @@ -2165,7 +2150,13 @@ cleanup_exit(int i) static void cleanup_handler(int sig) { - signalled = sig; + signalled_exit = sig; +} + +static void +keydrop_handler(int sig) +{ + signalled_keydrop = sig; } static void @@ -2186,20 +2177,25 @@ static void usage(void) { fprintf(stderr, - "usage: ssh-agent [-c | -s] [-Dd] [-a bind_address] [-E fingerprint_hash]\n" + "usage: ssh-agent [-c | -s] [-DdTU] [-a bind_address] [-E fingerprint_hash]\n" " [-O option] [-P allowed_providers] [-t life]\n" - " ssh-agent [-a bind_address] [-E fingerprint_hash] [-O option]\n" + " ssh-agent [-TU] [-a bind_address] [-E fingerprint_hash] [-O option]\n" " [-P allowed_providers] [-t life] command [arg ...]\n" - " ssh-agent [-c | -s] -k\n"); + " ssh-agent [-c | -s] -k\n" + " ssh-agent -u\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; + int c_flag = 0, d_flag = 0, D_flag = 0, k_flag = 0; + int s_flag = 0, T_flag = 0, u_flag = 0, U_flag = 0; + int sock = -1, ch, result, saved_errno; + char *homedir = NULL, *shell, *format, *pidstr, *agentsocket = NULL; + char *fdstr; + const char *errstr = NULL; + const char *ccp; #ifdef HAVE_SETRLIMIT struct rlimit rlim; #endif @@ -2214,6 +2210,7 @@ main(int ac, char **av) size_t npfd = 0; u_int maxfds; sigset_t nsigset, osigset; + int socket_activated = 0; /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ sanitise_stdfd(); @@ -2232,7 +2229,7 @@ main(int ac, char **av) __progname = ssh_get_progname(av[0]); seed_rng(); - while ((ch = getopt(ac, av, "cDdksE:a:O:P:t:")) != -1) { + while ((ch = getopt(ac, av, "cDdksTuUE:a:O:P:t:")) != -1) { switch (ch) { case 'E': fingerprint_hash = ssh_digest_alg_by_name(optarg); @@ -2252,7 +2249,12 @@ main(int ac, char **av) restrict_websafe = 0; else if (strcmp(optarg, "allow-remote-pkcs11") == 0) remote_add_provider = 1; - else + else if ((ccp = strprefix(optarg, + "websafe-allow=", 0)) != NULL) { + if (websafe_allowlist != NULL) + fatal("websafe-allow already set"); + websafe_allowlist = xstrdup(ccp); + } else fatal("Unknown -O option"); break; case 'P': @@ -2284,6 +2286,15 @@ main(int ac, char **av) usage(); } break; + case 'T': + T_flag++; + break; + case 'u': + u_flag++; + break; + case 'U': + U_flag++; + break; default: usage(); } @@ -2291,11 +2302,18 @@ main(int ac, char **av) ac -= optind; av += optind; - if (ac > 0 && (c_flag || k_flag || s_flag || d_flag || D_flag)) + if (ac > 0 && + (c_flag || k_flag || s_flag || d_flag || D_flag || u_flag)) usage(); + log_init(__progname, + d_flag ? SYSLOG_LEVEL_DEBUG3 : SYSLOG_LEVEL_INFO, + SYSLOG_FACILITY_AUTH, 1); + if (allowed_providers == NULL) allowed_providers = xstrdup(DEFAULT_ALLOWED_PROVIDERS); + if (websafe_allowlist == NULL) + websafe_allowlist = xstrdup(DEFAULT_WEBSAFE_ALLOWLIST); if (ac == 0 && !c_flag && !s_flag) { shell = getenv("SHELL"); @@ -2304,8 +2322,6 @@ main(int ac, char **av) 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", @@ -2329,6 +2345,14 @@ main(int ac, char **av) printf("echo Agent pid %ld killed;\n", (long)pid); exit(0); } + if (u_flag) { + if ((homedir = get_homedir()) == NULL) + fatal("Couldn't determine home directory"); + agent_cleanup_stale(homedir, u_flag > 1); + printf("Deleted stale agent sockets in ~/%s\n", + _PATH_SSH_AGENT_SOCKET_DIR); + exit(0); + } /* * Minimum file descriptors: @@ -2343,33 +2367,90 @@ main(int ac, char **av) 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); + /* Has the socket been provided via socket activation? */ + if (agentsocket == NULL && ac == 0 && (d_flag || D_flag) && + (pidstr = getenv("LISTEN_PID")) != NULL && + (fdstr = getenv("LISTEN_FDS")) != NULL) { + if (strcmp(fdstr, "1") != 0) { + fatal("unexpected LISTEN_FDS contents " + "(want: \"1\" got\"%s\"", fdstr); } - 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); + if (fcntl(3, F_GETFL) == -1) + fatal("LISTEN_FDS set but fd 3 unavailable"); + pid = (int)strtonum(pidstr, 1, INT_MAX, &errstr); + if (errstr != NULL) + fatal("invalid LISTEN_PID: %s", errstr); + if (pid != getpid()) + fatal("bad LISTEN_PID: %d vs pid %d", pid, getpid()); + debug("using socket activation on fd=3"); + sock = 3; + socket_activated = 1; + } + + if (sock == -1 && agentsocket == NULL && !T_flag) { + /* Default case: ~/.ssh/agent/[socket] */ + if ((homedir = get_homedir()) == NULL) + fatal("Couldn't determine home directory"); + if (!U_flag) + agent_cleanup_stale(homedir, 0); + if (agent_listener(homedir, "agent", &sock, &agentsocket) != 0) + fatal_f("Couldn't prepare agent socket"); + if (strlcpy(socket_name, agentsocket, + sizeof(socket_name)) >= sizeof(socket_name)) { + fatal_f("Socket path \"%s\" too long", + agentsocket); + } + free(homedir); + free(agentsocket); + agentsocket = NULL; + } else if (sock == -1) { + if (T_flag) { + /* + * Create private directory for agent socket + * in $TMPDIR. + */ + 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'; + if (strlcpy(socket_name, agentsocket, + sizeof(socket_name)) >= sizeof(socket_name)) { + fatal_f("Socket path \"%s\" too long", + agentsocket); + } + } + /* Listen on socket */ + prev_mask = umask(0177); + if ((sock = unix_listener(socket_name, + SSH_LISTEN_BACKLOG, 0)) < 0) { + *socket_name = '\0'; /* Don't unlink existing file */ + cleanup_exit(1); + } + umask(prev_mask); } + closefrom(sock == -1 ? STDERR_FILENO + 1 : sock + 1); + /* * 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); + if (sock == -1) { + 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 existing file */ + cleanup_exit(1); + } + umask(prev_mask); } - umask(prev_mask); /* * Fork, and have the parent execute the command, if any, or present @@ -2379,11 +2460,14 @@ main(int ac, char **av) 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); + if (socket_name[0] != '\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("echo Agent pid %ld;\n", (long)parent_pid); + fflush(stdout); + } goto skip; } pid = fork(); @@ -2448,11 +2532,13 @@ main(int ac, char **av) ssh_signal(SIGINT, (d_flag | D_flag) ? cleanup_handler : SIG_IGN); ssh_signal(SIGHUP, cleanup_handler); ssh_signal(SIGTERM, cleanup_handler); + ssh_signal(SIGUSR1, keydrop_handler); sigemptyset(&nsigset); sigaddset(&nsigset, SIGINT); sigaddset(&nsigset, SIGHUP); sigaddset(&nsigset, SIGTERM); + sigaddset(&nsigset, SIGUSR1); if (pledge("stdio rpath cpath unix id proc exec", NULL) == -1) fatal("%s: pledge: %s", __progname, strerror(errno)); @@ -2460,9 +2546,16 @@ main(int ac, char **av) while (1) { sigprocmask(SIG_BLOCK, &nsigset, &osigset); - if (signalled != 0) { - logit("exiting on signal %d", (int)signalled); - cleanup_exit(2); + if (signalled_exit != 0) { + logit("exiting on signal %d", (int)signalled_exit); + cleanup_exit((signalled_exit == SIGTERM && + socket_activated) ? 0 : 2); + } + if (signalled_keydrop) { + logit("signal %d received; removing all keys", + (int)signalled_keydrop); + remove_all_identities(); + signalled_keydrop = 0; } ptimeout_init(&timeout); prepare_poll(&pfd, &npfd, &timeout, maxfds); diff --git a/ssh-dss.c b/ssh-dss.c deleted file mode 100644 index aea6613..0000000 --- a/ssh-dss.c +++ /dev/null @@ -1,457 +0,0 @@ -/* $OpenBSD: ssh-dss.c,v 1.50 2024/01/11 01:45:36 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" - -#if defined(WITH_OPENSSL) && defined(WITH_DSA) - -#include - -#include -#include -#include - -#include -#include - -#include "sshbuf.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) - -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; -} - -static int -ssh_dss_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) -{ - DSA_SIG *dsig = NULL; - BIGNUM *sig_r = NULL, *sig_s = NULL; - u_char digest[SSH_DIGEST_MAX_LENGTH], *sigblob = NULL; - 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 || - sig == NULL || siglen == 0) - return SSH_ERR_INVALID_ARGUMENT; - if (hlen == 0) - return SSH_ERR_INTERNAL_ERROR; - - /* fetch signature */ - 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 ((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(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, dlen, - digest, sizeof(digest))) != 0) - goto out; - - 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(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 && WITH_DSA */ diff --git a/ssh-ecdsa-sk.c b/ssh-ecdsa-sk.c index 27ddf90..3588b11 100644 --- a/ssh-ecdsa-sk.c +++ b/ssh-ecdsa-sk.c @@ -310,7 +310,7 @@ ssh_ecdsa_sk_verify(const struct sshkey *key, } #ifdef DEBUG_SK - fprintf(stderr, "%s: data: (len %zu)\n", __func__, datalen); + fprintf(stderr, "%s: data: (len %zu)\n", __func__, dlen); /* sshbuf_dump_data(data, datalen, stderr); */ fprintf(stderr, "%s: sig_r: %s\n", __func__, (tmp = BN_bn2hex(sig_r))); free(tmp); diff --git a/ssh-ecdsa.c b/ssh-ecdsa.c index 695ed45..b423bfb 100644 --- a/ssh-ecdsa.c +++ b/ssh-ecdsa.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-ecdsa.c,v 1.27 2024/08/15 00:51:51 djm Exp $ */ +/* $OpenBSD: ssh-ecdsa.c,v 1.28 2025/07/24 05:44:55 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2010 Damien Miller. All rights reserved. @@ -328,8 +328,7 @@ ssh_ecdsa_sign(struct sshkey *key, const BIGNUM *sig_r, *sig_s; int hash_alg; size_t slen = 0; - struct sshbuf *b = NULL, *bb = NULL; - int len = 0, ret = SSH_ERR_INTERNAL_ERROR; + int ret = SSH_ERR_INTERNAL_ERROR; if (lenp != NULL) *lenp = 0; @@ -352,11 +351,37 @@ ssh_ecdsa_sign(struct sshkey *key, ret = SSH_ERR_LIBCRYPTO_ERROR; goto out; } + ECDSA_SIG_get0(esig, &sig_r, &sig_s); + + if ((ret = ssh_ecdsa_encode_store_sig(key, sig_r, sig_s, + sigp, lenp)) != 0) + goto out; + /* success */ + ret = 0; + out: + freezero(sigb, slen); + ECDSA_SIG_free(esig); + return ret; +} + +int +ssh_ecdsa_encode_store_sig(const struct sshkey *key, + const BIGNUM *sig_r, const BIGNUM *sig_s, + u_char **sigp, size_t *lenp) +{ + struct sshbuf *b = NULL, *bb = NULL; + int ret; + size_t len; + + if (lenp != NULL) + *lenp = 0; + if (sigp != NULL) + *sigp = NULL; + if ((bb = sshbuf_new()) == NULL || (b = sshbuf_new()) == NULL) { ret = SSH_ERR_ALLOC_FAIL; goto out; } - 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; @@ -375,10 +400,8 @@ ssh_ecdsa_sign(struct sshkey *key, *lenp = len; ret = 0; out: - freezero(sigb, slen); sshbuf_free(b); sshbuf_free(bb); - ECDSA_SIG_free(esig); return ret; } diff --git a/ssh-ed25519.c b/ssh-ed25519.c index 22d8db0..c8caa22 100644 --- a/ssh-ed25519.c +++ b/ssh-ed25519.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-ed25519.c,v 1.19 2022/10/28 00:44:44 djm Exp $ */ +/* $OpenBSD: ssh-ed25519.c,v 1.20 2025/07/24 06:12:08 djm Exp $ */ /* * Copyright (c) 2013 Markus Friedl * @@ -149,10 +149,9 @@ ssh_ed25519_sign(struct sshkey *key, const char *alg, const char *sk_provider, const char *sk_pin, u_int compat) { u_char *sig = NULL; - size_t slen = 0, len; + size_t slen = 0; unsigned long long smlen; int r, ret; - struct sshbuf *b = NULL; if (lenp != NULL) *lenp = 0; @@ -173,13 +172,40 @@ ssh_ed25519_sign(struct sshkey *key, r = SSH_ERR_INVALID_ARGUMENT; /* XXX better error? */ goto out; } + if ((r = ssh_ed25519_encode_store_sig(sig, smlen - datalen, + sigp, lenp)) != 0) + goto out; + + /* success */ + r = 0; + out: + freezero(sig, slen); + return r; +} + +int +ssh_ed25519_encode_store_sig(const u_char *sig, size_t slen, + u_char **sigp, size_t *lenp) +{ + struct sshbuf *b = NULL; + int r = -1; + size_t len; + + if (lenp != NULL) + *lenp = 0; + if (sigp != NULL) + *sigp = NULL; + + if (slen != crypto_sign_ed25519_BYTES) + return SSH_ERR_INVALID_ARGUMENT; + /* 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) + (r = sshbuf_put_string(b, sig, slen)) != 0) goto out; len = sshbuf_len(b); if (sigp != NULL) { @@ -195,9 +221,6 @@ ssh_ed25519_sign(struct sshkey *key, r = 0; out: sshbuf_free(b); - if (sig != NULL) - freezero(sig, slen); - return r; } diff --git a/ssh-keygen.0 b/ssh-keygen.0 index 5affcfa..9ae8d3e 100644 --- a/ssh-keygen.0 +++ b/ssh-keygen.0 @@ -329,7 +329,7 @@ DESCRIPTION RSA keys). -U When used in combination with -s or -Y sign, this option - indicates that a CA key resides in a ssh-agent(1). See the + indicates that a CA key resides in an ssh-agent(1). See the CERTIFICATES section for more information. -u Update a KRL. When specified with -k, keys listed via the @@ -528,10 +528,6 @@ MODULI GENERATION lines in the input file that have already been processed if the job is restarted. - memory=mbytes - Specify the amount of memory to use (in megabytes) when - generating candidate moduli for DH-GEX. - start=hex-value Specify start point (in hex) when generating candidate moduli for DH-GEX. @@ -569,7 +565,7 @@ CERTIFICATES $ ssh-keygen -s ca_key.pub -D libpkcs11.so -I key_id user_key.pub - Similarly, it is possible for the CA key to be hosted in a ssh-agent(1). + Similarly, it is possible for the CA key to be hosted in an ssh-agent(1). This is indicated by the -U flag and, again, the CA key must be identified by its public half. @@ -656,10 +652,9 @@ CERTIFICATES verify-required Require signatures made using this key indicate that the user was - first verified. This option only makes sense for the FIDO - authenticator algorithms ecdsa-sk and ed25519-sk. Currently PIN - authentication is the only supported verification method, but - other methods may be supported in the future. + first verified, e.g. by PIN or on-token biometrics. This option + only makes sense for the FIDO authenticator algorithms ecdsa-sk + and ed25519-sk. At present, no standard options are valid for host keys. @@ -783,7 +778,7 @@ KEY REVOCATION LISTS OpenSSH versions prior to 7.9. hash: fingerprint - Revokes a key using a fingerprint hash, as obtained from a + Revokes a key using a fingerprint hash, as obtained from an sshd(8) authentication log message or the ssh-keygen -l flag. Only SHA256 fingerprints are supported here and resultant KRLs are not supported by OpenSSH versions prior to 7.9. @@ -906,4 +901,4 @@ AUTHORS created OpenSSH. Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. -OpenBSD 7.6 August 17, 2024 OpenBSD 7.6 +OpenBSD 7.7 October 4, 2025 OpenBSD 7.7 diff --git a/ssh-keygen.1 b/ssh-keygen.1 index 06f0555..7ceb1db 100644 --- a/ssh-keygen.1 +++ b/ssh-keygen.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-keygen.1,v 1.233 2024/08/17 08:35:04 djm Exp $ +.\" $OpenBSD: ssh-keygen.1,v 1.236 2025/10/04 21:41:35 naddy Exp $ .\" .\" Author: Tatu Ylonen .\" Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -35,7 +35,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: August 17 2024 $ +.Dd $Mdocdate: October 4 2025 $ .Dt SSH-KEYGEN 1 .Os .Sh NAME @@ -600,7 +600,7 @@ When used in combination with .Fl s or .Fl Y Cm sign , -this option indicates that a CA key resides in a +this option indicates that a CA key resides in an .Xr ssh-agent 1 . See the .Sx CERTIFICATES @@ -878,9 +878,6 @@ Write the last line processed to the specified file while performing DH candidate screening. This will be used to skip lines in the input file that have already been processed if the job is restarted. -.It Ic memory Ns = Ns Ar mbytes -Specify the amount of memory to use (in megabytes) when generating -candidate moduli for DH-GEX. .It Ic start Ns = Ns Ar hex-value Specify start point (in hex) when generating candidate moduli for DH-GEX. .It Ic generator Ns = Ns Ar value @@ -927,7 +924,7 @@ to .Pp .Dl $ ssh-keygen -s ca_key.pub -D libpkcs11.so -I key_id user_key.pub .Pp -Similarly, it is possible for the CA key to be hosted in a +Similarly, it is possible for the CA key to be hosted in an .Xr ssh-agent 1 . This is indicated by the .Fl U @@ -1041,13 +1038,11 @@ format. .Pp .It Ic verify-required Require signatures made using this key indicate that the user was first -verified. +verified, e.g. by PIN or on-token biometrics. This option only makes sense for the FIDO authenticator algorithms .Cm ecdsa-sk and .Cm ed25519-sk . -Currently PIN authentication is the only supported verification method, -but other methods may be supported in the future. .El .Pp At present, no standard options are valid for host keys. @@ -1191,7 +1186,7 @@ Revokes the specified key by including its SHA256 hash in the KRL. KRLs that revoke keys by SHA256 hash are not supported by OpenSSH versions prior to 7.9. .It Cm hash : Ar fingerprint -Revokes a key using a fingerprint hash, as obtained from a +Revokes a key using a fingerprint hash, as obtained from an .Xr sshd 8 authentication log message or the .Nm diff --git a/ssh-keygen.c b/ssh-keygen.c index 8396c40..3c582a8 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keygen.c,v 1.475 2024/09/15 00:47:01 djm Exp $ */ +/* $OpenBSD: ssh-keygen.c,v 1.485 2025/10/03 00:08:02 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1994 Tatu Ylonen , Espoo, Finland @@ -19,20 +19,17 @@ #include #ifdef WITH_OPENSSL +#include "openbsd-compat/openssl-compat.h" +#include #include #include -#include "openbsd-compat/openssl-compat.h" #endif -#ifdef HAVE_STDINT_H -# include -#endif +#include #include #include #include -#ifdef HAVE_PATHS_H -# include -#endif +#include #include #include #include @@ -56,7 +53,6 @@ #include "ssh.h" #include "ssh2.h" #include "ssherr.h" -#include "ssh-pkcs11.h" #include "atomicio.h" #include "krl.h" #include "digest.h" @@ -67,21 +63,21 @@ #include "sk-api.h" /* XXX for SSH_SK_USER_PRESENCE_REQD; remove */ #include "cipher.h" +#ifdef ENABLE_PKCS11 +#include "ssh-pkcs11.h" +#endif + #define DEFAULT_KEY_TYPE_NAME "ed25519" /* - * Default number of bits in the RSA, DSA and ECDSA keys. These value can be + * Default number of bits in the RSA 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. + * These values 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. */ #define DEFAULT_BITS 3072 -#define DEFAULT_BITS_DSA 1024 #define DEFAULT_BITS_ECDSA 256 static int quiet = 0; @@ -170,7 +166,7 @@ static char hostname[NI_MAXHOST]; #ifdef WITH_OPENSSL /* moduli.c */ -int gen_candidates(FILE *, u_int32_t, u_int32_t, BIGNUM *); +int gen_candidates(FILE *, u_int32_t, BIGNUM *); int prime_test(FILE *, FILE *, u_int32_t, u_int32_t, char *, unsigned long, unsigned long); #endif @@ -185,9 +181,6 @@ type_bits_valid(int type, const char *name, u_int32_t *bitsp) 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) @@ -203,10 +196,6 @@ type_bits_valid(int type, const char *name, u_int32_t *bitsp) } #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", @@ -262,12 +251,6 @@ ask_filename(struct passwd *pw, const char *prompt) name = _PATH_SSH_CLIENT_ID_ED25519; else { switch (sshkey_type_from_shortname(key_type_name)) { -#ifdef WITH_DSA - case KEY_DSA_CERT: - case KEY_DSA: - name = _PATH_SSH_CLIENT_ID_DSA; - break; -#endif #ifdef OPENSSL_HAS_ECC case KEY_ECDSA_CERT: case KEY_ECDSA: @@ -290,10 +273,6 @@ ask_filename(struct passwd *pw, const char *prompt) 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"); } @@ -370,7 +349,6 @@ do_convert_to_ssh2(struct passwd *pw, struct sshkey *k) fprintf(stdout, "Comment: \"%s\"\n%s", comment, b64); fprintf(stdout, "%s\n", SSH_COM_PUBLIC_END); free(b64); - exit(0); } static void @@ -382,12 +360,6 @@ do_convert_to_pkcs8(struct sshkey *k) EVP_PKEY_get0_RSA(k->pkey))) fatal("PEM_write_RSA_PUBKEY failed"); break; -#ifdef WITH_DSA - case KEY_DSA: - if (!PEM_write_DSA_PUBKEY(stdout, k->dsa)) - fatal("PEM_write_DSA_PUBKEY failed"); - break; -#endif #ifdef OPENSSL_HAS_ECC case KEY_ECDSA: if (!PEM_write_EC_PUBKEY(stdout, @@ -398,7 +370,6 @@ do_convert_to_pkcs8(struct sshkey *k) default: fatal_f("unsupported key type %s", sshkey_type(k)); } - exit(0); } static void @@ -410,12 +381,6 @@ do_convert_to_pem(struct sshkey *k) EVP_PKEY_get0_RSA(k->pkey))) fatal("PEM_write_RSAPublicKey failed"); break; -#ifdef WITH_DSA - case KEY_DSA: - if (!PEM_write_DSA_PUBKEY(stdout, k->dsa)) - fatal("PEM_write_DSA_PUBKEY failed"); - break; -#endif #ifdef OPENSSL_HAS_ECC case KEY_ECDSA: if (!PEM_write_EC_PUBKEY(stdout, @@ -426,7 +391,6 @@ do_convert_to_pem(struct sshkey *k) default: fatal_f("unsupported key type %s", sshkey_type(k)); } - exit(0); } static void @@ -455,7 +419,6 @@ do_convert_to(struct passwd *pw) default: fatal_f("unknown key format %d", convert_format); } - exit(0); } /* @@ -491,10 +454,6 @@ do_convert_private_ssh2(struct sshbuf *b) u_int magic, i1, i2, i3, i4; size_t slen; u_long e; -#ifdef WITH_DSA - BIGNUM *dsa_p = NULL, *dsa_q = NULL, *dsa_g = NULL; - BIGNUM *dsa_pub_key = NULL, *dsa_priv_key = NULL; -#endif BIGNUM *rsa_n = NULL, *rsa_e = NULL, *rsa_d = NULL; BIGNUM *rsa_p = NULL, *rsa_q = NULL, *rsa_iqmp = NULL; BIGNUM *rsa_dmp1 = NULL, *rsa_dmq1 = NULL; @@ -526,10 +485,6 @@ do_convert_private_ssh2(struct sshbuf *b) if (strstr(type, "rsa")) { ktype = KEY_RSA; -#ifdef WITH_DSA - } else if (strstr(type, "dsa")) { - ktype = KEY_DSA; -#endif } else { free(type); return NULL; @@ -539,27 +494,6 @@ do_convert_private_ssh2(struct sshbuf *b) free(type); switch (key->type) { -#ifdef WITH_DSA - 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; -#endif case KEY_RSA: if ((r = sshbuf_get_u8(b, &e1)) != 0 || (e1 < 30 && (r = sshbuf_get_u8(b, &e2)) != 0) || @@ -596,6 +530,7 @@ do_convert_private_ssh2(struct sshbuf *b) if ((r = ssh_rsa_complete_crt_parameters(rsa_d, rsa_p, rsa_q, rsa_iqmp, &rsa_dmp1, &rsa_dmq1)) != 0) fatal_fr(r, "generate RSA CRT parameters"); + EVP_PKEY_free(key->pkey); if ((key->pkey = EVP_PKEY_new()) == NULL) fatal_f("EVP_PKEY_new failed"); if ((rsa = RSA_new()) == NULL) @@ -734,14 +669,6 @@ do_convert_from_pkcs8(struct sshkey **k, int *private) (*k)->pkey = pubkey; pubkey = NULL; break; -#ifdef WITH_DSA - 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; -#endif #ifdef OPENSSL_HAS_ECC case EVP_PKEY_EC: if ((*k = sshkey_new(KEY_UNSPEC)) == NULL) @@ -758,7 +685,6 @@ do_convert_from_pkcs8(struct sshkey **k, int *private) EVP_PKEY_base_id(pubkey)); } EVP_PKEY_free(pubkey); - return; } static void @@ -817,12 +743,6 @@ do_convert_from(struct passwd *pw) fprintf(stdout, "\n"); } else { switch (k->type) { -#ifdef WITH_DSA - case KEY_DSA: - ok = PEM_write_DSAPrivateKey(stdout, k->dsa, NULL, - NULL, 0, NULL, NULL); - break; -#endif #ifdef OPENSSL_HAS_ECC case KEY_ECDSA: ok = PEM_write_ECPrivateKey(stdout, @@ -843,7 +763,6 @@ do_convert_from(struct passwd *pw) if (!ok) fatal("key write failed"); sshkey_free(k); - exit(0); } #endif @@ -1008,7 +927,7 @@ do_fingerprint(struct passwd *pw) while (getline(&line, &linesize, f) != -1) { lnum++; cp = line; - cp[strcspn(cp, "\n")] = '\0'; + cp[strcspn(cp, "\r\n")] = '\0'; /* Trim leading space and comments */ cp = line + strspn(line, " \t"); if (*cp == '#' || *cp == '\0') @@ -1096,9 +1015,6 @@ do_gen_all_hostkeys(struct passwd *pw) #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 } }; @@ -1526,13 +1442,14 @@ do_print_resource_record(struct passwd *pw, char *fname, char *hname, { struct sshkey *public; char *comment = NULL; + const char *p; struct stat st; int r, hash = -1; size_t i; for (i = 0; i < nopts; i++) { - if (strncasecmp(opts[i], "hashalg=", 8) == 0) { - if ((hash = ssh_digest_alg_by_name(opts[i] + 8)) == -1) + if ((p = strprefix(opts[i], "hashalg=", 1)) != NULL) { + if ((hash = ssh_digest_alg_by_name(p)) == -1) fatal("Unsupported hash algorithm"); } else { error("Invalid option \"%s\"", opts[i]); @@ -1592,7 +1509,7 @@ do_change_comment(struct passwd *pw, const char *identity_comment) } } - if (private->type != KEY_ED25519 && private->type != KEY_XMSS && + if (private->type != KEY_ED25519 && private_key_format != SSHKEY_PRIVATE_OPENSSH) { error("Comments are only supported for keys stored in " "the new format (-o)."); @@ -1943,16 +1860,17 @@ do_ca_sign(struct passwd *pw, const char *ca_key_path, int prefer_agent, sshkey_free(public); free(out); + free(comment); if (cert_serial_autoinc) cert_serial++; } if (pin != NULL) freezero(pin, strlen(pin)); + sshkey_free(ca); free(ca_fp); #ifdef ENABLE_PKCS11 pkcs11_terminate(); #endif - exit(0); } static u_int64_t @@ -2042,6 +1960,7 @@ static void add_cert_option(char *opt) { char *val, *cp; + const char *p; int iscrit = 0; if (strcasecmp(opt, "clear") == 0) @@ -2074,24 +1993,22 @@ add_cert_option(char *opt) 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') + else if ((p = strprefix(opt, "force-command=", 1)) != NULL) { + if (*p == '\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') + certflags_command = xstrdup(p); + } else if ((p = strprefix(opt, "source-address=", 1)) != NULL) { + if (*p == '\0') fatal("Empty source-address option"); if (certflags_src_addr != NULL) fatal("source-address already specified"); - if (addr_match_cidr_list(NULL, val) != 0) + if (addr_match_cidr_list(NULL, p) != 0) fatal("Invalid source-address list"); - certflags_src_addr = xstrdup(val); - } else if (strncasecmp(opt, "extension:", 10) == 0 || - (iscrit = (strncasecmp(opt, "critical:", 9) == 0))) { + certflags_src_addr = xstrdup(p); + } else if (strprefix(opt, "extension:", 1) != NULL || + (iscrit = (strprefix(opt, "critical:", 1) != NULL))) { val = xstrdup(strchr(opt, ':') + 1); if ((cp = strchr(val, '=')) != NULL) *cp++ = '\0'; @@ -2278,9 +2195,8 @@ hash_to_blob(const char *cp, u_char **blobp, size_t *lenp, struct sshbuf *b; int r; - if (strncmp(cp, "SHA256:", 7) != 0) + if ((cp = strprefix(cp, "SHA256:", 0)) == NULL) fatal("%s:%lu: unsupported hash algorithm", file, lnum); - cp += 7; /* * OpenSSH base64 hashes omit trailing '=' @@ -2402,9 +2318,12 @@ update_krl_from_file(struct passwd *pw, const char *file, int wild_ca, 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) + if ((r = ssh_krl_revoke_key_sha256(krl, + blob, blen)) != 0) fatal_fr(r, "revoke key failed"); + free(blob); + blob = NULL; + blen = 0; } else { if (strncasecmp(cp, "key:", 4) == 0) { cp += 4; @@ -2705,6 +2624,7 @@ sig_process_opts(char * const *opts, size_t nopts, char **hashalgp, { size_t i; time_t now; + const char *p; if (verify_timep != NULL) *verify_timep = 0; @@ -2714,12 +2634,12 @@ sig_process_opts(char * const *opts, size_t nopts, char **hashalgp, *hashalgp = NULL; for (i = 0; i < nopts; i++) { if (hashalgp != NULL && - strncasecmp(opts[i], "hashalg=", 8) == 0) { - *hashalgp = xstrdup(opts[i] + 8); + (p = strprefix(opts[i], "hashalg=", 1)) != NULL) { + *hashalgp = xstrdup(p); } else if (verify_timep && - strncasecmp(opts[i], "verify-time=", 12) == 0) { - if (parse_absolute_time(opts[i] + 12, - verify_timep) != 0 || *verify_timep == 0) { + (p = strprefix(opts[i], "verify-time=", 1)) != NULL) { + if (parse_absolute_time(p, verify_timep) != 0 || + *verify_timep == 0) { error("Invalid \"verify-time\" option"); return SSH_ERR_INVALID_ARGUMENT; } @@ -2995,32 +2915,22 @@ 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; + const char *errstr, *p; /* 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) { + if ((p = strprefix(opts[i], "start=", 0)) != NULL) { /* XXX - also compare length against bits */ - if (BN_hex2bn(&start, opts[i]+6) == 0) + if (BN_hex2bn(&start, p) == 0) fatal("Invalid start point."); - } else if (strncmp(opts[i], "bits=", 5) == 0) { - moduli_bits = (int)strtonum(opts[i]+5, 1, - INT_MAX, &errstr); + } else if ((p = strprefix(opts[i], "bits=", 0)) != NULL) { + moduli_bits = (int)strtonum(p, 1, INT_MAX, &errstr); if (errstr) { - fatal("Invalid number: %s (%s)", - opts[i]+12, errstr); + fatal("Invalid number: %s (%s)", p, errstr); } } else { fatal("Option \"%s\" is unsupported for moduli " @@ -3028,7 +2938,9 @@ do_moduli_gen(const char *out_file, char **opts, size_t nopts) } } - if ((out = fopen(out_file, "w")) == NULL) { + if (strcmp(out_file, "-") == 0) + out = stdout; + else if ((out = fopen(out_file, "w")) == NULL) { fatal("Couldn't open modulus candidate file \"%s\": %s", out_file, strerror(errno)); } @@ -3036,7 +2948,7 @@ do_moduli_gen(const char *out_file, char **opts, size_t nopts) if (moduli_bits == 0) moduli_bits = DEFAULT_BITS; - if (gen_candidates(out, memory, moduli_bits, start) != 0) + if (gen_candidates(out, moduli_bits, start) != 0) fatal("modulus candidate generation failed"); #else /* WITH_OPENSSL */ fatal("Moduli generation is not supported"); @@ -3054,30 +2966,27 @@ do_moduli_screen(const char *out_file, char **opts, size_t nopts) int prime_tests = 0; FILE *out, *in = stdin; size_t i; - const char *errstr; + const char *errstr, *p; /* 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) { + if ((p = strprefix(opts[i], "lines=", 0)) != NULL) { + lines_to_process = strtoul(p, NULL, 10); + } else if ((p = strprefix(opts[i], "start-line=", 0)) != NULL) { + start_lineno = strtoul(p, NULL, 10); + } else if ((p = strprefix(opts[i], "checkpoint=", 0)) != NULL) { free(checkpoint); - 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); + checkpoint = xstrdup(p); + } else if ((p = strprefix(opts[i], "generator=", 0)) != NULL) { + generator_wanted = (u_int32_t)strtonum(p, 1, UINT_MAX, + &errstr); if (errstr != NULL) { - fatal("Generator invalid: %s (%s)", - opts[i]+10, errstr); + fatal("Generator invalid: %s (%s)", p, errstr); } - } else if (strncmp(opts[i], "prime-tests=", 12) == 0) { - prime_tests = (int)strtonum(opts[i]+12, 1, - INT_MAX, &errstr); + } else if ((p = strprefix(opts[i], "prime-tests=", 0)) != NULL) { + prime_tests = (int)strtonum(p, 1, INT_MAX, &errstr); if (errstr) { - fatal("Invalid number: %s (%s)", - opts[i]+12, errstr); + fatal("Invalid number: %s (%s)", p, errstr); } } else { fatal("Option \"%s\" is unsupported for moduli " @@ -3093,7 +3002,9 @@ do_moduli_screen(const char *out_file, char **opts, size_t nopts) } } - if ((out = fopen(out_file, "a")) == NULL) { + if (strcmp(out_file, "-") == 0) + out = stdout; + else if ((out = fopen(out_file, "a")) == NULL) { fatal("Couldn't open moduli file \"%s\": %s", out_file, strerror(errno)); } @@ -3158,13 +3069,14 @@ static char * sk_suffix(const char *application, const uint8_t *user, size_t userlen) { char *ret, *cp; + const char *p; 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); + if ((p = strprefix(application, "ssh://", 0)) != NULL) + ret = xstrdup(p); + else if ((p = strprefix(application, "ssh:", 0)) != NULL) + ret = xstrdup(p); else ret = xstrdup(application); @@ -3325,7 +3237,7 @@ 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" + " [-t 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" @@ -3376,9 +3288,9 @@ main(int argc, char **argv) { char comment[1024], *passphrase = NULL; char *rr_hostname = NULL, *ep, *fp, *ra; - struct sshkey *private, *public; + struct sshkey *private = NULL, *public = NULL; struct passwd *pw; - int r, opt, type; + int ret = 0, 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; @@ -3393,7 +3305,7 @@ main(int argc, char **argv) size_t i, nopts = 0; u_int32_t bits = 0; uint8_t sk_flags = SSH_SK_USER_PRESENCE_REQD; - const char *errstr; + const char *errstr, *p; int log_level = SYSLOG_LEVEL_INFO; char *sign_op = NULL; @@ -3628,7 +3540,7 @@ main(int argc, char **argv) argc -= optind; if (sign_op != NULL) { - if (strncmp(sign_op, "find-principals", 15) == 0) { + if (strprefix(sign_op, "find-principals", 0) != NULL) { if (ca_key_path == NULL) { error("Too few arguments for find-principals:" "missing signature file"); @@ -3639,9 +3551,10 @@ main(int argc, char **argv) "missing allowed keys file"); exit(1); } - return sig_find_principals(ca_key_path, identity_file, + ret = sig_find_principals(ca_key_path, identity_file, opts, nopts); - } else if (strncmp(sign_op, "match-principals", 16) == 0) { + goto done; + } else if (strprefix(sign_op, "match-principals", 0) != NULL) { if (!have_identity) { error("Too few arguments for match-principals:" "missing allowed keys file"); @@ -3652,9 +3565,10 @@ main(int argc, char **argv) "missing principal ID"); exit(1); } - return sig_match_principals(identity_file, cert_key_id, + ret = sig_match_principals(identity_file, cert_key_id, opts, nopts); - } else if (strncmp(sign_op, "sign", 4) == 0) { + goto done; + } else if (strprefix(sign_op, "sign", 0) != NULL) { /* NB. cert_principals is actually namespace, via -n */ if (cert_principals == NULL || *cert_principals == '\0') { @@ -3667,9 +3581,10 @@ main(int argc, char **argv) "missing key"); exit(1); } - return sig_sign(identity_file, cert_principals, + ret = sig_sign(identity_file, cert_principals, prefer_agent, argc, argv, opts, nopts); - } else if (strncmp(sign_op, "check-novalidate", 16) == 0) { + goto done; + } else if (strprefix(sign_op, "check-novalidate", 0) != NULL) { /* NB. cert_principals is actually namespace, via -n */ if (cert_principals == NULL || *cert_principals == '\0') { @@ -3682,9 +3597,10 @@ main(int argc, char **argv) "missing signature file"); exit(1); } - return sig_verify(ca_key_path, cert_principals, + ret = sig_verify(ca_key_path, cert_principals, NULL, NULL, NULL, opts, nopts); - } else if (strncmp(sign_op, "verify", 6) == 0) { + goto done; + } else if (strprefix(sign_op, "verify", 0) != NULL) { /* NB. cert_principals is actually namespace, via -n */ if (cert_principals == NULL || *cert_principals == '\0') { @@ -3707,9 +3623,10 @@ main(int argc, char **argv) "missing principal identity"); exit(1); } - return sig_verify(ca_key_path, cert_principals, + ret = sig_verify(ca_key_path, cert_principals, cert_key_id, identity_file, rr_hostname, opts, nopts); + goto done; } error("Unsupported operation for -Y: \"%s\"", sign_op); usage(); @@ -3737,11 +3654,11 @@ main(int argc, char **argv) if (gen_krl) { do_gen_krl(pw, update_krl, ca_key_path, cert_serial, identity_comment, argc, argv); - return (0); + goto done; } if (check_krl) { do_check_krl(pw, print_fingerprint, argc, argv); - return (0); + goto done; } if (ca_key_path != NULL) { if (cert_key_id == NULL) @@ -3750,6 +3667,7 @@ main(int argc, char **argv) add_cert_option(opts[i]); do_ca_sign(pw, ca_key_path, prefer_agent, cert_serial, cert_serial_autoinc, argc, argv); + goto done; } if (show_cert) do_show_cert(pw); @@ -3761,14 +3679,15 @@ main(int argc, char **argv) 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); + if ((p = strprefix(opts[i], "device=", 1)) != NULL) { + sk_device = xstrdup(p); } else { fatal("Option \"%s\" is unsupported for " "FIDO authenticator download", opts[i]); } } - return do_download_sk(sk_provider, sk_device); + ret = do_download_sk(sk_provider, sk_device); + goto done; } if (print_fingerprint || print_bubblebabble) do_fingerprint(pw); @@ -3777,10 +3696,14 @@ main(int argc, char **argv) if (change_comment) do_change_comment(pw, identity_comment); #ifdef WITH_OPENSSL - if (convert_to) + if (convert_to) { do_convert_to(pw); - if (convert_from) + goto done; + } + if (convert_from) { do_convert_from(pw); + goto done; + } #else /* WITH_OPENSSL */ if (convert_to || convert_from) fatal("key conversion disabled at compile time"); @@ -3801,20 +3724,12 @@ main(int argc, char **argv) n += do_print_resource_record(pw, _PATH_HOST_RSA_KEY_FILE, rr_hostname, print_generic, opts, nopts); -#ifdef WITH_DSA - n += do_print_resource_record(pw, - _PATH_HOST_DSA_KEY_FILE, rr_hostname, - print_generic, opts, nopts); -#endif n += do_print_resource_record(pw, _PATH_HOST_ECDSA_KEY_FILE, rr_hostname, print_generic, opts, nopts); n += do_print_resource_record(pw, _PATH_HOST_ED25519_KEY_FILE, rr_hostname, print_generic, opts, nopts); - n += do_print_resource_record(pw, - _PATH_HOST_XMSS_KEY_FILE, rr_hostname, - print_generic, opts, nopts); if (n == 0) fatal("no keys found."); exit(0); @@ -3829,16 +3744,16 @@ main(int argc, char **argv) } if (do_gen_candidates) { do_moduli_gen(argv[0], opts, nopts); - return 0; + goto done; } if (do_screen_candidates) { do_moduli_screen(argv[0], opts, nopts); - return 0; + goto done; } if (gen_all_hostkeys) { do_gen_all_hostkeys(pw); - return (0); + goto done; } if (key_type_name == NULL) @@ -3860,16 +3775,18 @@ main(int argc, char **argv) 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, + } else if ((p = strprefix(opts[i], "device=", 1)) + != NULL ) { + sk_device = xstrdup(p); + } else if ((p = strprefix(opts[i], "user=", 1)) + != NULL) { + sk_user = xstrdup(p); + } else if ((p = strprefix(opts[i], "challenge=", 1)) + != NULL) { + if ((r = sshbuf_load_file(p, &challenge)) != 0) { fatal_r(r, "Unable to load FIDO " - "enrollment challenge \"%s\"", - opts[i] + 10); + "enrollment challenge \"%s\"", p); } } else if (strncasecmp(opts[i], "write-attestation=", 18) == 0) { @@ -3993,8 +3910,9 @@ main(int argc, char **argv) if (sk_attestation_path != NULL) save_attestation(attest, sk_attestation_path); + done: sshbuf_free(attest); sshkey_free(public); - - exit(0); + pwfree(pw); + exit(ret); } diff --git a/ssh-keyscan.0 b/ssh-keyscan.0 index 382d160..76d7388 100644 --- a/ssh-keyscan.0 +++ b/ssh-keyscan.0 @@ -34,7 +34,7 @@ DESCRIPTION -c Request certificates from target hosts instead of plain keys. -D Print keys found as SSHFP DNS records. The default is to print - keys in a format usable as a ssh(1) known_hosts file. + keys in a format usable as an ssh(1) known_hosts file. -f file Read hosts or M-bM-^@M-^\addrlist namelistM-bM-^@M-^] pairs from file, one per line. @@ -120,4 +120,4 @@ AUTHORS Davison added support for protocol version 2. -OpenBSD 7.6 June 17, 2024 OpenBSD 7.6 +OpenBSD 7.7 October 4, 2025 OpenBSD 7.7 diff --git a/ssh-keyscan.1 b/ssh-keyscan.1 index 79cef30..e179573 100644 --- a/ssh-keyscan.1 +++ b/ssh-keyscan.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-keyscan.1,v 1.52 2024/06/17 08:30:29 djm Exp $ +.\" $OpenBSD: ssh-keyscan.1,v 1.53 2025/10/04 21:41:35 naddy Exp $ .\" .\" Copyright 1995, 1996 by David Mazieres . .\" @@ -6,7 +6,7 @@ .\" permitted provided that due credit is given to the author and the .\" OpenBSD project by leaving this copyright notice intact. .\" -.Dd $Mdocdate: June 17 2024 $ +.Dd $Mdocdate: October 4 2025 $ .Dt SSH-KEYSCAN 1 .Os .Sh NAME @@ -64,7 +64,7 @@ to use IPv6 addresses only. 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 +The default is to print keys in a format usable as an .Xr ssh 1 .Pa known_hosts file. diff --git a/ssh-keyscan.c b/ssh-keyscan.c index f34e056..f978811 100644 --- a/ssh-keyscan.c +++ b/ssh-keyscan.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keyscan.c,v 1.161 2024/09/09 02:39:57 djm Exp $ */ +/* $OpenBSD: ssh-keyscan.c,v 1.167 2025/08/29 03:50:38 djm Exp $ */ /* * Copyright 1995, 1996 by David Mazieres . * @@ -12,9 +12,7 @@ #include #include "openbsd-compat/sys-queue.h" #include -#ifdef HAVE_SYS_TIME_H -# include -#endif +#include #include #include @@ -23,15 +21,13 @@ #include #endif +#include #include #include -#include -#ifdef HAVE_POLL_H -#include -#endif #include #include #include +#include #include #include #include @@ -62,15 +58,13 @@ 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_RSA (1) +#define KT_ECDSA (1<<1) +#define KT_ED25519 (1<<2) +#define KT_ECDSA_SK (1<<4) +#define KT_ED25519_SK (1<<5) -#define KT_MIN KT_DSA +#define KT_MIN KT_RSA #define KT_MAX KT_ED25519_SK int get_cert = 0; @@ -240,10 +234,6 @@ keygrab_ssh2(con *c) 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," @@ -257,10 +247,6 @@ keygrab_ssh2(con *c) 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," @@ -588,7 +574,7 @@ conloop(void) for (i = 0; i < maxfd; i++) { if (read_wait[i].revents & (POLLHUP|POLLERR|POLLNVAL)) confree(i); - else if (read_wait[i].revents & (POLLIN|POLLHUP)) + else if (read_wait[i].revents & (POLLIN)) conread(i); } @@ -650,22 +636,10 @@ do_host(char *host) 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) { @@ -755,11 +729,6 @@ main(int argc, char **argv) int type = sshkey_type_from_shortname(tname); switch (type) { -#ifdef WITH_DSA - case KEY_DSA: - get_keytypes |= KT_DSA; - break; -#endif case KEY_ECDSA: get_keytypes |= KT_ECDSA; break; @@ -769,9 +738,6 @@ main(int argc, char **argv) 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; @@ -814,6 +780,7 @@ main(int argc, char **argv) for (j = 0; j < maxfd; j++) read_wait[j].fd = -1; + ssh_signal(SIGPIPE, SIG_IGN); for (j = 0; j < fopt_count; j++) { if (argv[j] == NULL) fp = stdin; diff --git a/ssh-keysign.0 b/ssh-keysign.0 index f1e0e09..ff33058 100644 --- a/ssh-keysign.0 +++ b/ssh-keysign.0 @@ -47,4 +47,4 @@ HISTORY AUTHORS Markus Friedl -OpenBSD 7.6 June 17, 2024 OpenBSD 7.6 +OpenBSD 7.7 June 17, 2024 OpenBSD 7.7 diff --git a/ssh-keysign.c b/ssh-keysign.c index 968344e..8d6bcda 100644 --- a/ssh-keysign.c +++ b/ssh-keysign.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keysign.c,v 1.74 2024/04/30 05:53:03 djm Exp $ */ +/* $OpenBSD: ssh-keysign.c,v 1.78 2025/09/25 06:25:38 djm Exp $ */ /* * Copyright (c) 2002 Markus Friedl. All rights reserved. * @@ -26,9 +26,7 @@ #include "includes.h" #include -#ifdef HAVE_PATHS_H #include -#endif #include #include #include @@ -131,8 +129,10 @@ valid_request(struct passwd *pw, char *host, struct sshkey **ret, char **pkalgp, /* client host name, handle trailing dot */ if ((r = sshbuf_get_cstring(b, &p, &len)) != 0) fatal_fr(r, "parse hostname"); - debug2_f("check expect chost %s got %s", host, p); - if (strlen(host) != len - 1) + debug2_f("check expect chost \"%s\" got \"%s\"", host, p); + if (len == 0) + fail++; + else if (strlen(host) != len - 1) fail++; else if (p[len - 1] != '.') fail++; @@ -200,12 +200,8 @@ main(int argc, char **argv) i = 0; /* XXX This really needs to read sshd_config for the paths */ -#ifdef WITH_DSA - key_fd[i++] = open(_PATH_HOST_DSA_KEY_FILE, O_RDONLY); -#endif key_fd[i++] = open(_PATH_HOST_ECDSA_KEY_FILE, O_RDONLY); key_fd[i++] = open(_PATH_HOST_ED25519_KEY_FILE, O_RDONLY); - key_fd[i++] = open(_PATH_HOST_XMSS_KEY_FILE, O_RDONLY); key_fd[i++] = open(_PATH_HOST_RSA_KEY_FILE, O_RDONLY); if ((pw = getpwuid(getuid())) == NULL) @@ -222,7 +218,7 @@ main(int argc, char **argv) /* verify that ssh-keysign is enabled by the admin */ initialize_options(&options); - (void)read_config_file(_PATH_HOST_CONFIG_FILE, pw, "", "", + (void)read_config_file(_PATH_HOST_CONFIG_FILE, pw, "", "", "", &options, 0, NULL); (void)fill_default_options(&options); if (options.enable_ssh_keysign != 1) diff --git a/ssh-pkcs11-client.c b/ssh-pkcs11-client.c index b8d1700..85afb62 100644 --- a/ssh-pkcs11-client.c +++ b/ssh-pkcs11-client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-pkcs11-client.c,v 1.20 2024/08/15 00:51:51 djm Exp $ */ +/* $OpenBSD: ssh-pkcs11-client.c,v 1.24 2025/07/30 10:17:13 dtucker Exp $ */ /* * Copyright (c) 2010 Markus Friedl. All rights reserved. * Copyright (c) 2014 Pedro Martelletto. All rights reserved. @@ -18,23 +18,17 @@ #include "includes.h" -#ifdef ENABLE_PKCS11 - #include -#ifdef HAVE_SYS_TIME_H -# include -#endif +#include #include #include +#include #include #include #include #include -#include -#include - #include "pathnames.h" #include "xmalloc.h" #include "sshbuf.h" @@ -46,28 +40,18 @@ #include "ssh-pkcs11.h" #include "ssherr.h" -#include "openbsd-compat/openssl-compat.h" - -#if !defined(OPENSSL_HAS_ECC) || !defined(HAVE_EC_KEY_METHOD_NEW) -#define EC_KEY_METHOD void -#define EC_KEY void -#endif - /* borrows code from sftp-server and ssh-agent */ /* * Maintain a list of ssh-pkcs11-helper subprocesses. These may be looked up - * by provider path or their unique EC/RSA METHOD pointers. + * by provider path or their unique keyblobs. */ struct helper { char *path; pid_t pid; int fd; - RSA_METHOD *rsa_meth; - EC_KEY_METHOD *ec_meth; - int (*rsa_finish)(RSA *rsa); - void (*ec_finish)(EC_KEY *key); - size_t nrsa, nec; /* number of active keys of each type */ + size_t nkeyblobs; + struct sshbuf **keyblobs; /* XXX use a tree or something faster */ }; static struct helper **helpers; static size_t nhelpers; @@ -88,58 +72,75 @@ helper_by_provider(const char *path) } static struct helper * -helper_by_rsa(const RSA *rsa) +helper_by_key(const struct sshkey *key) { - size_t i; - const RSA_METHOD *meth; + size_t i, j; + struct sshbuf *keyblob = NULL; + int r; + + if ((keyblob = sshbuf_new()) == NULL) + fatal_f("sshbuf_new failed"); + if ((r = sshkey_putb(key, keyblob)) != 0) + fatal_fr(r, "serialise key"); - if ((meth = RSA_get_method(rsa)) == NULL) - return NULL; for (i = 0; i < nhelpers; i++) { - if (helpers[i] != NULL && helpers[i]->rsa_meth == meth) - return helpers[i]; + if (helpers[i] == NULL) + continue; + for (j = 0; j < helpers[i]->nkeyblobs; j++) { + if (sshbuf_equals(keyblob, + helpers[i]->keyblobs[j]) == 0) { + sshbuf_free(keyblob); + return helpers[i]; + } + } } + sshbuf_free(keyblob); return NULL; } -#if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW) -static struct helper * -helper_by_ec(const EC_KEY *ec) +static void +helper_add_key(struct helper *helper, struct sshkey *key) { - size_t i; - const EC_KEY_METHOD *meth; - - if ((meth = EC_KEY_get_method(ec)) == NULL) - return NULL; - for (i = 0; i < nhelpers; i++) { - if (helpers[i] != NULL && helpers[i]->ec_meth == meth) - return helpers[i]; - } - return NULL; + int r; + helper->keyblobs = xrecallocarray(helper->keyblobs, helper->nkeyblobs, + helper->nkeyblobs + 1, sizeof(*helper->keyblobs)); + if ((helper->keyblobs[helper->nkeyblobs] = sshbuf_new()) == NULL) + fatal_f("sshbuf_new failed"); + if ((r = sshkey_putb(key, helper->keyblobs[helper->nkeyblobs])) != 0) + fatal_fr(r, "shkey_putb failed"); + helper->nkeyblobs++; + debug3_f("added %s key for provider %s, now has %zu keys", + sshkey_type(key), helper->path, helper->nkeyblobs); } -#endif /* defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW) */ static void -helper_free(struct helper *helper) +helper_terminate(struct helper *helper) { size_t i; int found = 0; if (helper == NULL) return; - if (helper->path == NULL || helper->ec_meth == NULL || - helper->rsa_meth == NULL) + if (helper->path == NULL) fatal_f("inconsistent helper"); - debug3_f("free helper for provider %s", helper->path); + + debug3_f("terminating helper for %s; remaining %zu keys", + helper->path, helper->nkeyblobs); + + close(helper->fd); + /* XXX waitpid() */ + helper->fd = -1; + helper->pid = -1; + + /* repack helpers */ for (i = 0; i < nhelpers; i++) { if (helpers[i] == helper) { if (found) fatal_f("helper recorded more than once"); found = 1; - } - else if (found) + } else if (found) helpers[i - 1] = helpers[i]; } if (found) { @@ -147,39 +148,12 @@ helper_free(struct helper *helper) nhelpers - 1, sizeof(*helpers)); nhelpers--; } + for (i = 0; i < helper->nkeyblobs; i++) + sshbuf_free(helper->keyblobs[i]); free(helper->path); -#if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW) - EC_KEY_METHOD_free(helper->ec_meth); -#endif - RSA_meth_free(helper->rsa_meth); free(helper); } -static void -helper_terminate(struct helper *helper) -{ - if (helper == NULL) { - return; - } else if (helper->fd == -1) { - debug3_f("already terminated"); - } else { - debug3_f("terminating helper for %s; " - "remaining %zu RSA %zu ECDSA", - helper->path, helper->nrsa, helper->nec); - close(helper->fd); - /* XXX waitpid() */ - helper->fd = -1; - helper->pid = -1; - } - /* - * Don't delete the helper entry until there are no remaining keys - * that reference it. Otherwise, any signing operation would call - * a free'd METHOD pointer and that would be bad. - */ - if (helper->nrsa == 0 && helper->nec == 0) - helper_free(helper); -} - static void send_msg(int fd, struct sshbuf *m) { @@ -249,200 +223,62 @@ pkcs11_terminate(void) helper_terminate(helpers[i]); } -static int -rsa_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa, int padding) +int +pkcs11_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) { - struct sshkey *key = NULL; struct sshbuf *msg = NULL; - u_char *blob = NULL, *signature = NULL; - size_t blen, slen = 0; - int r, ret = -1; struct helper *helper; + int status, r; + u_char *signature = NULL; + size_t signature_len = 0; + int ret = SSH_ERR_INTERNAL_ERROR; - if ((helper = helper_by_rsa(rsa)) == NULL || helper->fd == -1) - fatal_f("no helper for PKCS11 key"); - debug3_f("signing with PKCS11 provider %s", helper->path); - if (padding != RSA_PKCS1_PADDING) - goto fail; - if ((key = sshkey_new(KEY_UNSPEC)) == NULL) { - error_f("sshkey_new failed"); - goto fail; - } - if ((key->pkey = EVP_PKEY_new()) == NULL || - EVP_PKEY_set1_RSA(key->pkey, rsa) != 1) { - error_f("pkey setup failed"); - goto fail; - } + if (sigp != NULL) + *sigp = NULL; + if (lenp != NULL) + *lenp = 0; + + if ((helper = helper_by_key(key)) == NULL || helper->fd == -1) + fatal_f("no helper for %s key", sshkey_type(key)); - key->type = KEY_RSA; - if ((r = sshkey_to_blob(key, &blob, &blen)) != 0) { - error_fr(r, "encode key"); - goto fail; - } if ((msg = sshbuf_new()) == NULL) - fatal_f("sshbuf_new failed"); + return SSH_ERR_ALLOC_FAIL; if ((r = sshbuf_put_u8(msg, SSH2_AGENTC_SIGN_REQUEST)) != 0 || - (r = sshbuf_put_string(msg, blob, blen)) != 0 || - (r = sshbuf_put_string(msg, from, flen)) != 0 || - (r = sshbuf_put_u32(msg, 0)) != 0) + (r = sshkey_puts_plain(key, msg)) != 0 || + (r = sshbuf_put_string(msg, data, datalen)) != 0 || + (r = sshbuf_put_cstring(msg, alg == NULL ? "" : alg)) != 0 || + (r = sshbuf_put_u32(msg, compat)) != 0) fatal_fr(r, "compose"); send_msg(helper->fd, msg); sshbuf_reset(msg); - if (recv_msg(helper->fd, msg) == SSH2_AGENT_SIGN_RESPONSE) { - if ((r = sshbuf_get_string(msg, &signature, &slen)) != 0) - fatal_fr(r, "parse"); - if (slen <= (size_t)RSA_size(rsa)) { - memcpy(to, signature, slen); - ret = slen; - } - free(signature); - } - fail: - free(blob); - sshkey_free(key); - sshbuf_free(msg); - return (ret); -} - -static int -rsa_finish(RSA *rsa) -{ - struct helper *helper; - - if ((helper = helper_by_rsa(rsa)) == NULL) - fatal_f("no helper for PKCS11 key"); - debug3_f("free PKCS11 RSA key for provider %s", helper->path); - if (helper->rsa_finish != NULL) - helper->rsa_finish(rsa); - if (helper->nrsa == 0) - fatal_f("RSA refcount error"); - helper->nrsa--; - debug3_f("provider %s remaining keys: %zu RSA %zu ECDSA", - helper->path, helper->nrsa, helper->nec); - if (helper->nrsa == 0 && helper->nec == 0) - helper_terminate(helper); - return 1; -} - -#if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW) -static ECDSA_SIG * -ecdsa_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *inv, - const BIGNUM *rp, EC_KEY *ec) -{ - struct sshkey *key = NULL; - struct sshbuf *msg = NULL; - ECDSA_SIG *ret = NULL; - const u_char *cp; - u_char *blob = NULL, *signature = NULL; - size_t blen, slen = 0; - int r, nid; - struct helper *helper; - - if ((helper = helper_by_ec(ec)) == NULL || helper->fd == -1) - fatal_f("no helper for PKCS11 key"); - debug3_f("signing with PKCS11 provider %s", helper->path); - - if ((key = sshkey_new(KEY_UNSPEC)) == NULL) { - error_f("sshkey_new failed"); - goto fail; - } - if ((key->pkey = EVP_PKEY_new()) == NULL || - EVP_PKEY_set1_EC_KEY(key->pkey, ec) != 1) { - error("pkey setup failed"); - goto fail; - } - if ((nid = sshkey_ecdsa_pkey_to_nid(key->pkey)) < 0) { - error("couldn't get curve nid"); + if ((status = recv_msg(helper->fd, msg)) != SSH2_AGENT_SIGN_RESPONSE) { + /* XXX translate status to something useful */ + debug_fr(r, "recv_msg"); + ret = SSH_ERR_AGENT_FAILURE; goto fail; } - key->ecdsa_nid = nid; - key->type = KEY_ECDSA; - if ((r = sshkey_to_blob(key, &blob, &blen)) != 0) { - error_fr(r, "encode key"); - goto fail; - } - if ((msg = sshbuf_new()) == NULL) - fatal_f("sshbuf_new failed"); - if ((r = sshbuf_put_u8(msg, SSH2_AGENTC_SIGN_REQUEST)) != 0 || - (r = sshbuf_put_string(msg, blob, blen)) != 0 || - (r = sshbuf_put_string(msg, dgst, dgst_len)) != 0 || - (r = sshbuf_put_u32(msg, 0)) != 0) - fatal_fr(r, "compose"); - send_msg(helper->fd, msg); - sshbuf_reset(msg); + if ((r = sshbuf_get_string(msg, &signature, &signature_len)) != 0) + fatal_fr(r, "parse"); - if (recv_msg(helper->fd, msg) == SSH2_AGENT_SIGN_RESPONSE) { - if ((r = sshbuf_get_string(msg, &signature, &slen)) != 0) - fatal_fr(r, "parse"); - cp = signature; - ret = d2i_ECDSA_SIG(NULL, &cp, slen); - free(signature); + /* success */ + if (sigp != NULL) { + *sigp = signature; + signature = NULL; } + if (lenp != NULL) + *lenp = signature_len; + ret = 0; fail: - free(blob); - sshkey_free(key); + free(signature); sshbuf_free(msg); - return (ret); -} - -static void -ecdsa_do_finish(EC_KEY *ec) -{ - struct helper *helper; - - if ((helper = helper_by_ec(ec)) == NULL) - fatal_f("no helper for PKCS11 key"); - debug3_f("free PKCS11 ECDSA key for provider %s", helper->path); - if (helper->ec_finish != NULL) - helper->ec_finish(ec); - if (helper->nec == 0) - fatal_f("ECDSA refcount error"); - helper->nec--; - debug3_f("provider %s remaining keys: %zu RSA %zu ECDSA", - helper->path, helper->nrsa, helper->nec); - if (helper->nrsa == 0 && helper->nec == 0) - helper_terminate(helper); -} -#endif /* defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW) */ - -/* redirect private key crypto operations to the ssh-pkcs11-helper */ -static void -wrap_key(struct helper *helper, struct sshkey *k) -{ - RSA *rsa = NULL; - EC_KEY *ecdsa = NULL; - - debug3_f("wrap %s for provider %s", sshkey_type(k), helper->path); - if (k->type == KEY_RSA) { - if ((rsa = EVP_PKEY_get1_RSA(k->pkey)) == NULL) - fatal_f("no RSA key"); - if (RSA_set_method(rsa, helper->rsa_meth) != 1) - fatal_f("RSA_set_method failed"); - if (helper->nrsa++ >= INT_MAX) - fatal_f("RSA refcount error"); - if (EVP_PKEY_set1_RSA(k->pkey, rsa) != 1) - fatal_f("EVP_PKEY_set1_RSA failed"); - RSA_free(rsa); -#if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW) - } else if (k->type == KEY_ECDSA) { - if ((ecdsa = EVP_PKEY_get1_EC_KEY(k->pkey)) == NULL) - fatal_f("no ECDSA key"); - if (EC_KEY_set_method(ecdsa, helper->ec_meth) != 1) - fatal_f("EC_KEY_set_method failed"); - if (helper->nec++ >= INT_MAX) - fatal_f("EC refcount error"); - if (EVP_PKEY_set1_EC_KEY(k->pkey, ecdsa) != 1) - fatal_f("EVP_PKEY_set1_EC_KEY failed"); - EC_KEY_free(ecdsa); -#endif - } else - fatal_f("unknown key type"); - k->flags |= SSHKEY_FLAG_EXT; - debug3_f("provider %s remaining keys: %zu RSA %zu ECDSA", - helper->path, helper->nrsa, helper->nec); + return ret; } /* @@ -456,13 +292,13 @@ pkcs11_make_cert(const struct sshkey *priv, struct helper *helper = NULL; struct sshkey *ret; int r; - RSA *rsa_priv = NULL, *rsa_cert = NULL; -#if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW) - EC_KEY *ec_priv = NULL, *ec_cert = NULL; -#endif - debug3_f("private key type %s cert type %s", sshkey_type(priv), - sshkey_type(certpub)); + if ((helper = helper_by_key(priv)) == NULL || helper->fd == -1) + fatal_f("no helper for %s key", sshkey_type(priv)); + + debug3_f("private key type %s cert type %s on provider %s", + sshkey_type(priv), sshkey_type(certpub), helper->path); + *certprivp = NULL; if (!sshkey_is_cert(certpub) || sshkey_is_cert(priv) || !sshkey_equal_public(priv, certpub)) { @@ -471,95 +307,24 @@ pkcs11_make_cert(const struct sshkey *priv, return SSH_ERR_INVALID_ARGUMENT; } *certprivp = NULL; - if (priv->type == KEY_RSA) { - if ((rsa_priv = EVP_PKEY_get1_RSA(priv->pkey)) == NULL) - fatal_f("no RSA pkey"); - if ((helper = helper_by_rsa(rsa_priv)) == NULL || - helper->fd == -1) - fatal_f("no helper for PKCS11 RSA key"); - if ((r = sshkey_from_private(priv, &ret)) != 0) - fatal_fr(r, "copy key"); - if ((rsa_cert = EVP_PKEY_get1_RSA(ret->pkey)) == NULL) - fatal_f("no RSA cert pkey"); - if (RSA_set_method(rsa_cert, helper->rsa_meth) != 1) - fatal_f("RSA_set_method failed"); - if (helper->nrsa++ >= INT_MAX) - fatal_f("RSA refcount error"); - if (EVP_PKEY_set1_RSA(ret->pkey, rsa_cert) != 1) - fatal_f("EVP_PKEY_set1_RSA failed"); - RSA_free(rsa_priv); - RSA_free(rsa_cert); -#if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW) - } else if (priv->type == KEY_ECDSA) { - if ((ec_priv = EVP_PKEY_get1_EC_KEY(priv->pkey)) == NULL) - fatal_f("no EC pkey"); - if ((helper = helper_by_ec(ec_priv)) == NULL || - helper->fd == -1) - fatal_f("no helper for PKCS11 EC key"); - if ((r = sshkey_from_private(priv, &ret)) != 0) - fatal_fr(r, "copy key"); - if ((ec_cert = EVP_PKEY_get1_EC_KEY(ret->pkey)) == NULL) - fatal_f("no EC cert pkey"); - if (EC_KEY_set_method(ec_cert, helper->ec_meth) != 1) - fatal_f("EC_KEY_set_method failed"); - if (helper->nec++ >= INT_MAX) - fatal_f("EC refcount error"); - if (EVP_PKEY_set1_EC_KEY(ret->pkey, ec_cert) != 1) - fatal_f("EVP_PKEY_set1_EC_KEY failed"); - EC_KEY_free(ec_priv); - EC_KEY_free(ec_cert); -#endif - } else - fatal_f("unknown key type %s", sshkey_type(priv)); + if ((r = sshkey_from_private(priv, &ret)) != 0) + fatal_fr(r, "copy key"); ret->flags |= SSHKEY_FLAG_EXT; if ((r = sshkey_to_certified(ret)) != 0 || (r = sshkey_cert_copy(certpub, ret)) != 0) fatal_fr(r, "graft certificate"); - debug3_f("provider %s remaining keys: %zu RSA %zu ECDSA", - helper->path, helper->nrsa, helper->nec); + + helper_add_key(helper, ret); + + debug3_f("provider %s: %zu remaining keys", + helper->path, helper->nkeyblobs); + /* success */ *certprivp = ret; return 0; } -static int -pkcs11_start_helper_methods(struct helper *helper) -{ - RSA_METHOD *rsa_meth = NULL; - EC_KEY_METHOD *ec_meth = NULL; -#if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW) - int (*ec_init)(EC_KEY *key); - int (*ec_copy)(EC_KEY *dest, const EC_KEY *src); - int (*ec_set_group)(EC_KEY *key, const EC_GROUP *grp); - int (*ec_set_private)(EC_KEY *key, const BIGNUM *priv_key); - int (*ec_set_public)(EC_KEY *key, const EC_POINT *pub_key); - int (*ec_sign)(int, const unsigned char *, int, unsigned char *, - unsigned int *, const BIGNUM *, const BIGNUM *, EC_KEY *) = NULL; - - if ((ec_meth = EC_KEY_METHOD_new(EC_KEY_OpenSSL())) == NULL) - return -1; - EC_KEY_METHOD_get_sign(ec_meth, &ec_sign, NULL, NULL); - EC_KEY_METHOD_set_sign(ec_meth, ec_sign, NULL, ecdsa_do_sign); - EC_KEY_METHOD_get_init(ec_meth, &ec_init, &helper->ec_finish, - &ec_copy, &ec_set_group, &ec_set_private, &ec_set_public); - EC_KEY_METHOD_set_init(ec_meth, ec_init, ecdsa_do_finish, - ec_copy, ec_set_group, ec_set_private, ec_set_public); -#endif /* defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW) */ - - if ((rsa_meth = RSA_meth_dup(RSA_get_default_method())) == NULL) - fatal_f("RSA_meth_dup failed"); - helper->rsa_finish = RSA_meth_get_finish(rsa_meth); - if (!RSA_meth_set1_name(rsa_meth, "ssh-pkcs11-helper") || - !RSA_meth_set_priv_enc(rsa_meth, rsa_encrypt) || - !RSA_meth_set_finish(rsa_meth, rsa_finish)) - fatal_f("failed to prepare method"); - - helper->ec_meth = ec_meth; - helper->rsa_meth = rsa_meth; - return 0; -} - static struct helper * pkcs11_start_helper(const char *path) { @@ -576,19 +341,10 @@ pkcs11_start_helper(const char *path) return NULL; } helper = xcalloc(1, sizeof(*helper)); - if (pkcs11_start_helper_methods(helper) == -1) { - error_f("pkcs11_start_helper_methods failed"); - goto fail; - } if ((pid = fork()) == -1) { error_f("fork: %s", strerror(errno)); - fail: close(pair[0]); close(pair[1]); - RSA_meth_free(helper->rsa_meth); -#if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW) - EC_KEY_METHOD_free(helper->ec_meth); -#endif free(helper); return NULL; } else if (pid == 0) { @@ -628,10 +384,8 @@ pkcs11_add_provider(char *name, char *pin, struct sshkey ***keysp, { struct sshkey *k; int r, type; - u_char *blob; char *label; - size_t blen; - u_int nkeys, i; + u_int ret = -1, nkeys, i; struct sshbuf *msg; struct helper *helper; @@ -639,6 +393,8 @@ pkcs11_add_provider(char *name, char *pin, struct sshkey ***keysp, (helper = pkcs11_start_helper(name)) == NULL) return -1; + debug3_f("add %s", helper->path); + if ((msg = sshbuf_new()) == NULL) fatal_f("sshbuf_new failed"); if ((r = sshbuf_put_u8(msg, SSH_AGENTC_ADD_SMARTCARD_KEY)) != 0 || @@ -649,35 +405,39 @@ pkcs11_add_provider(char *name, char *pin, struct sshkey ***keysp, sshbuf_reset(msg); type = recv_msg(helper->fd, msg); + debug3_f("response %d", type); if (type == SSH2_AGENT_IDENTITIES_ANSWER) { if ((r = sshbuf_get_u32(msg, &nkeys)) != 0) fatal_fr(r, "parse nkeys"); + debug3_f("helper return %u keys", nkeys); *keysp = xcalloc(nkeys, sizeof(struct sshkey *)); if (labelsp) *labelsp = xcalloc(nkeys, sizeof(char *)); for (i = 0; i < nkeys; i++) { /* XXX clean up properly instead of fatal() */ - if ((r = sshbuf_get_string(msg, &blob, &blen)) != 0 || + if ((r = sshkey_froms(msg, &k)) != 0 || (r = sshbuf_get_cstring(msg, &label, NULL)) != 0) fatal_fr(r, "parse key"); - if ((r = sshkey_from_blob(blob, blen, &k)) != 0) - fatal_fr(r, "decode key"); - wrap_key(helper, k); + k->flags |= SSHKEY_FLAG_EXT; + helper_add_key(helper, k); (*keysp)[i] = k; if (labelsp) (*labelsp)[i] = label; else free(label); - free(blob); } + /* success */ + ret = 0; } else if (type == SSH2_AGENT_FAILURE) { if ((r = sshbuf_get_u32(msg, &nkeys)) != 0) - nkeys = -1; - } else { - nkeys = -1; + error_fr(r, "failed to parse failure response"); + } + if (ret != 0) { + debug_f("no keys; terminate helper"); + helper_terminate(helper); } sshbuf_free(msg); - return (nkeys); + return ret == 0 ? (int)nkeys : -1; } int @@ -689,9 +449,44 @@ pkcs11_del_provider(char *name) * ssh-agent deletes keys before calling this, so the helper entry * should be gone before we get here. */ - debug3_f("delete %s", name); + debug3_f("delete %s", name ? name : "(null)"); if ((helper = helper_by_provider(name)) != NULL) helper_terminate(helper); return 0; } -#endif /* ENABLE_PKCS11 */ + +void +pkcs11_key_free(struct sshkey *key) +{ + struct helper *helper; + struct sshbuf *keyblob = NULL; + size_t i; + int r, found = 0; + + debug3_f("free %s key", sshkey_type(key)); + + if ((helper = helper_by_key(key)) == NULL || helper->fd == -1) + fatal_f("no helper for %s key", sshkey_type(key)); + if ((keyblob = sshbuf_new()) == NULL) + fatal_f("sshbuf_new failed"); + if ((r = sshkey_putb(key, keyblob)) != 0) + fatal_fr(r, "serialise key"); + + /* repack keys */ + for (i = 0; i < helper->nkeyblobs; i++) { + if (sshbuf_equals(keyblob, helper->keyblobs[i]) == 0) { + if (found) + fatal_f("key recorded more than once"); + found = 1; + } else if (found) + helper->keyblobs[i - 1] = helper->keyblobs[i]; + } + if (found) { + helper->keyblobs = xrecallocarray(helper->keyblobs, + helper->nkeyblobs, helper->nkeyblobs - 1, + sizeof(*helper->keyblobs)); + helper->nkeyblobs--; + } + if (helper->nkeyblobs == 0) + helper_terminate(helper); +} diff --git a/ssh-pkcs11-helper.0 b/ssh-pkcs11-helper.0 index 42a6a20..4b1cb8d 100644 --- a/ssh-pkcs11-helper.0 +++ b/ssh-pkcs11-helper.0 @@ -32,4 +32,4 @@ HISTORY AUTHORS Markus Friedl -OpenBSD 7.6 April 29, 2022 OpenBSD 7.6 +OpenBSD 7.7 April 29, 2022 OpenBSD 7.7 diff --git a/ssh-pkcs11-helper.c b/ssh-pkcs11-helper.c index a8154f2..aeb5b7a 100644 --- a/ssh-pkcs11-helper.c +++ b/ssh-pkcs11-helper.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-pkcs11-helper.c,v 1.27 2024/08/15 00:51:51 djm Exp $ */ +/* $OpenBSD: ssh-pkcs11-helper.c,v 1.29 2025/07/30 04:27:42 djm Exp $ */ /* * Copyright (c) 2010 Markus Friedl. All rights reserved. * @@ -18,17 +18,11 @@ #include "includes.h" #include -#ifdef HAVE_SYS_TIME_H -# include -#endif - -#include "openbsd-compat/sys-queue.h" +#include #include #include -#ifdef HAVE_POLL_H #include -#endif #include #include #include @@ -44,20 +38,9 @@ #ifdef ENABLE_PKCS11 -#ifdef WITH_OPENSSL -#include -#include -#include - /* borrows code from sftp-server and ssh-agent */ -struct pkcs11_keyinfo { - struct sshkey *key; - char *providername, *label; - TAILQ_ENTRY(pkcs11_keyinfo) next; -}; - -TAILQ_HEAD(, pkcs11_keyinfo) pkcs11_keylist; +static char *providername; /* Provider for this helper */ #define MAX_MSG_LENGTH 10240 /*XXX*/ @@ -65,50 +48,6 @@ TAILQ_HEAD(, pkcs11_keyinfo) pkcs11_keylist; struct sshbuf *iqueue; struct sshbuf *oqueue; -static void -add_key(struct sshkey *k, char *name, char *label) -{ - struct pkcs11_keyinfo *ki; - - ki = xcalloc(1, sizeof(*ki)); - ki->providername = xstrdup(name); - ki->key = k; - ki->label = xstrdup(label); - TAILQ_INSERT_TAIL(&pkcs11_keylist, ki, next); -} - -static void -del_keys_by_name(char *name) -{ - struct pkcs11_keyinfo *ki, *nxt; - - for (ki = TAILQ_FIRST(&pkcs11_keylist); ki; ki = nxt) { - nxt = TAILQ_NEXT(ki, next); - if (!strcmp(ki->providername, name)) { - TAILQ_REMOVE(&pkcs11_keylist, ki, next); - free(ki->providername); - free(ki->label); - sshkey_free(ki->key); - free(ki); - } - } -} - -/* lookup matching 'private' key */ -static struct sshkey * -lookup_key(struct sshkey *k) -{ - struct pkcs11_keyinfo *ki; - - TAILQ_FOREACH(ki, &pkcs11_keylist, next) { - debug("check %s %s %s", sshkey_type(ki->key), - ki->providername, ki->label); - if (sshkey_equal(k, ki->key)) - return (ki->key); - } - return (NULL); -} - static void send_msg(struct sshbuf *m) { @@ -121,34 +60,32 @@ send_msg(struct sshbuf *m) static void process_add(void) { - char *name, *pin; + char *pin; struct sshkey **keys = NULL; int r, i, nkeys; - u_char *blob; - size_t blen; struct sshbuf *msg; char **labels = NULL; + if (providername != NULL) + fatal_f("provider already set"); if ((msg = sshbuf_new()) == NULL) fatal_f("sshbuf_new failed"); - if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0 || + if ((r = sshbuf_get_cstring(iqueue, &providername, NULL)) != 0 || (r = sshbuf_get_cstring(iqueue, &pin, NULL)) != 0) fatal_fr(r, "parse"); - if ((nkeys = pkcs11_add_provider(name, pin, &keys, &labels)) > 0) { + debug3_f("add %s", providername); + if ((nkeys = pkcs11_add_provider(providername, pin, + &keys, &labels)) > 0) { if ((r = sshbuf_put_u8(msg, SSH2_AGENT_IDENTITIES_ANSWER)) != 0 || (r = sshbuf_put_u32(msg, nkeys)) != 0) fatal_fr(r, "compose"); for (i = 0; i < nkeys; i++) { - if ((r = sshkey_to_blob(keys[i], &blob, &blen)) != 0) { - debug_fr(r, "encode key"); - continue; - } - if ((r = sshbuf_put_string(msg, blob, blen)) != 0 || + if ((r = sshkey_puts(keys[i], msg)) != 0 || (r = sshbuf_put_cstring(msg, labels[i])) != 0) fatal_fr(r, "compose key"); - free(blob); - add_key(keys[i], name, labels[i]); + debug3_f("%s: %s \"%s\"", providername, + sshkey_type(keys[i]), labels[i]); free(labels[i]); } } else if ((r = sshbuf_put_u8(msg, SSH_AGENT_FAILURE)) != 0 || @@ -157,95 +94,39 @@ process_add(void) free(labels); free(keys); /* keys themselves are transferred to pkcs11_keylist */ free(pin); - free(name); send_msg(msg); sshbuf_free(msg); } static void -process_del(void) +process_sign(void) { - char *name, *pin; + const u_char *data; + u_char *signature = NULL; + size_t dlen, slen = 0; + u_int compat; + int r, ok = -1; + struct sshkey *key = NULL; struct sshbuf *msg; - int r; + char *alg = NULL; - if ((msg = sshbuf_new()) == NULL) - fatal_f("sshbuf_new failed"); - if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0 || - (r = sshbuf_get_cstring(iqueue, &pin, NULL)) != 0) + if ((r = sshkey_froms(iqueue, &key)) != 0 || + (r = sshbuf_get_string_direct(iqueue, &data, &dlen)) != 0 || + (r = sshbuf_get_cstring(iqueue, &alg, NULL)) != 0 || + (r = sshbuf_get_u32(iqueue, &compat)) != 0) fatal_fr(r, "parse"); - del_keys_by_name(name); - if ((r = sshbuf_put_u8(msg, pkcs11_del_provider(name) == 0 ? - SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE)) != 0) - fatal_fr(r, "compose"); - free(pin); - free(name); - send_msg(msg); - sshbuf_free(msg); -} -static void -process_sign(void) -{ - u_char *blob, *data, *signature = NULL; - size_t blen, dlen; - u_int slen = 0; - int len, r, ok = -1; - struct sshkey *key = NULL, *found; - struct sshbuf *msg; -#ifdef WITH_OPENSSL - RSA *rsa = NULL; -#ifdef OPENSSL_HAS_ECC - EC_KEY *ecdsa = NULL; -#endif /* OPENSSL_HAS_ECC */ -#endif /* WITH_OPENSSL */ - - /* XXX support SHA2 signature flags */ - if ((r = sshbuf_get_string(iqueue, &blob, &blen)) != 0 || - (r = sshbuf_get_string(iqueue, &data, &dlen)) != 0 || - (r = sshbuf_get_u32(iqueue, NULL)) != 0) - fatal_fr(r, "parse"); + if (*alg == '\0') { + free(alg); + alg = NULL; + } - if ((r = sshkey_from_blob(blob, blen, &key)) != 0) - fatal_fr(r, "decode key"); - if ((found = lookup_key(key)) == NULL) + if ((r = pkcs11_sign(key, &signature, &slen, data, dlen, + alg, NULL, NULL, compat)) != 0) { + error_fr(r, "sign %s", sshkey_type(key)); goto reply; - - /* XXX use pkey API properly for signing */ - switch (key->type) { -#ifdef WITH_OPENSSL - case KEY_RSA: - if ((rsa = EVP_PKEY_get1_RSA(found->pkey)) == NULL) - fatal_f("no RSA in pkey"); - if ((len = RSA_size(rsa)) < 0) - fatal_f("bad RSA length"); - signature = xmalloc(len); - if ((len = RSA_private_encrypt(dlen, data, signature, - rsa, RSA_PKCS1_PADDING)) < 0) { - error_f("RSA_private_encrypt failed"); - goto reply; - } - slen = (u_int)len; - break; -#ifdef OPENSSL_HAS_ECC - case KEY_ECDSA: - if ((ecdsa = EVP_PKEY_get1_EC_KEY(found->pkey)) == NULL) - fatal_f("no ECDSA in pkey"); - if ((len = ECDSA_size(ecdsa)) < 0) - fatal_f("bad ECDSA length"); - slen = (u_int)len; - signature = xmalloc(slen); - /* "The parameter type is ignored." */ - if (!ECDSA_sign(-1, data, dlen, signature, &slen, ecdsa)) { - error_f("ECDSA_sign failed"); - goto reply; - } - break; -#endif /* OPENSSL_HAS_ECC */ -#endif /* WITH_OPENSSL */ - default: - fatal_f("unsupported key type %d", key->type); } + /* success */ ok = 0; reply: @@ -260,12 +141,7 @@ process_sign(void) fatal_fr(r, "compose failure response"); } sshkey_free(key); - RSA_free(rsa); -#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) - EC_KEY_free(ecdsa); -#endif - free(data); - free(blob); + free(alg); free(signature); send_msg(msg); sshbuf_free(msg); @@ -301,10 +177,6 @@ process(void) debug("process_add"); process_add(); break; - case SSH_AGENTC_REMOVE_SMARTCARD_KEY: - debug("process_del"); - process_del(); - break; case SSH2_AGENTC_SIGN_REQUEST: debug("process_sign"); process_sign(); @@ -336,7 +208,6 @@ cleanup_exit(int i) _exit(i); } - int main(int argc, char **argv) { @@ -350,7 +221,6 @@ main(int argc, char **argv) __progname = ssh_get_progname(argv[0]); seed_rng(); - TAILQ_INIT(&pkcs11_keylist); log_init(__progname, log_level, log_facility, log_stderr); @@ -439,21 +309,6 @@ main(int argc, char **argv) fatal_fr(r, "reserve"); } } - -#else /* WITH_OPENSSL */ -void -cleanup_exit(int i) -{ - _exit(i); -} - -int -main(int argc, char **argv) -{ - fprintf(stderr, "PKCS#11 code is not enabled\n"); - return 1; -} -#endif /* WITH_OPENSSL */ #else /* ENABLE_PKCS11 */ int main(int argc, char **argv) diff --git a/ssh-pkcs11.c b/ssh-pkcs11.c index fadf9c9..c881794 100644 --- a/ssh-pkcs11.c +++ b/ssh-pkcs11.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-pkcs11.c,v 1.63 2024/08/15 00:51:51 djm Exp $ */ +/* $OpenBSD: ssh-pkcs11.c,v 1.73 2025/10/08 21:02:16 djm Exp $ */ /* * Copyright (c) 2010 Markus Friedl. All rights reserved. * Copyright (c) 2014 Pedro Martelletto. All rights reserved. @@ -20,9 +20,7 @@ #ifdef ENABLE_PKCS11 -#ifdef HAVE_SYS_TIME_H -# include -#endif +#include #include #include @@ -35,19 +33,27 @@ #include "openbsd-compat/sys-queue.h" #include "openbsd-compat/openssl-compat.h" +#ifdef WITH_OPENSSL +#include "openbsd-compat/openssl-compat.h" +#include #include #include #include +#endif #define CRYPTOKI_COMPAT #include "pkcs11.h" +#define SSHKEY_INTERNAL +#include "sshkey.h" + #include "log.h" #include "misc.h" -#include "sshkey.h" +#include "sshbuf.h" #include "ssh-pkcs11.h" #include "digest.h" #include "xmalloc.h" +#include "crypto_api.h" struct pkcs11_slotinfo { CK_TOKEN_INFO token; @@ -71,15 +77,19 @@ struct pkcs11_provider { TAILQ_HEAD(, pkcs11_provider) pkcs11_providers; struct pkcs11_key { + struct sshbuf *keyblob; struct pkcs11_provider *provider; CK_ULONG slotidx; char *keyid; int keyid_len; + TAILQ_ENTRY(pkcs11_key) next; }; +TAILQ_HEAD(, pkcs11_key) pkcs11_keys; /* XXX a tree would be better */ + int pkcs11_interactive = 0; -#if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW) +#if defined(OPENSSL_HAS_ECC) || defined(OPENSSL_HAS_ED25519) static void ossl_error(const char *msg) { @@ -89,15 +99,7 @@ ossl_error(const char *msg) while ((e = ERR_get_error()) != 0) error_f("libcrypto error: %s", ERR_error_string(e, NULL)); } -#endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */ - -int -pkcs11_init(int interactive) -{ - pkcs11_interactive = interactive; - TAILQ_INIT(&pkcs11_providers); - return (0); -} +#endif /* * finalize a provider shared library, it's no longer usable. @@ -146,19 +148,6 @@ pkcs11_provider_unref(struct pkcs11_provider *p) } } -/* unregister all providers, keys might still point to the providers */ -void -pkcs11_terminate(void) -{ - struct pkcs11_provider *p; - - while ((p = TAILQ_FIRST(&pkcs11_providers)) != NULL) { - TAILQ_REMOVE(&pkcs11_providers, p, next); - pkcs11_provider_finalize(p); - pkcs11_provider_unref(p); - } -} - /* lookup provider by name */ static struct pkcs11_provider * pkcs11_provider_lookup(char *provider_id) @@ -188,26 +177,16 @@ pkcs11_del_provider(char *provider_id) return (-1); } -static RSA_METHOD *rsa_method; -static int rsa_idx = 0; -#if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW) -static EC_KEY_METHOD *ec_key_method; -static int ec_key_idx = 0; -#endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */ - /* release a wrapped object */ static void -pkcs11_k11_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, - long argl, void *argp) +pkcs11_k11_free(struct pkcs11_key *k11) { - struct pkcs11_key *k11 = ptr; - - debug_f("parent %p ptr %p idx %d", parent, ptr, idx); if (k11 == NULL) return; if (k11->provider) pkcs11_provider_unref(k11->provider); free(k11->keyid); + sshbuf_free(k11->keyblob); free(k11); } @@ -417,214 +396,384 @@ pkcs11_get_key(struct pkcs11_key *k11, CK_MECHANISM_TYPE mech_type) return (0); } -/* openssl callback doing the actual signing operation */ +/* record the key information later use lookup by keyblob */ static int -pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa, - int padding) +pkcs11_record_key(struct pkcs11_provider *provider, CK_ULONG slotidx, + CK_ATTRIBUTE *keyid_attrib, struct sshkey *key) { - struct pkcs11_key *k11; - struct pkcs11_slotinfo *si; - CK_FUNCTION_LIST *f; - CK_ULONG tlen = 0; - CK_RV rv; - int rval = -1; - - if ((k11 = RSA_get_ex_data(rsa, rsa_idx)) == NULL) { - error("RSA_get_ex_data failed"); - return (-1); + struct sshbuf *keyblob; + struct pkcs11_key *k11; + int r; + char *hex; + + hex = tohex(keyid_attrib->pValue, keyid_attrib->ulValueLen); + debug_f("%s key: provider %s slot %lu keyid %s", + sshkey_type(key), provider->name, (u_long)slotidx, hex); + free(hex); + + if ((keyblob = sshbuf_new()) == NULL) + fatal_f("sshbuf_new failed"); + if ((r = sshkey_putb(key, keyblob)) != 0) + fatal_fr(r, "sshkey_putb"); + + /* Check if we've already recorded this key in a different slot */ + TAILQ_FOREACH(k11, &pkcs11_keys, next) { + if (sshbuf_equals(k11->keyblob, keyblob) == 0) { + hex = tohex(k11->keyid, k11->keyid_len); + debug_f("Already seen this key at " + "provider %s slot %lu keyid %s", + k11->provider->name, k11->slotidx, hex); + free(hex); + sshbuf_free(keyblob); + return -1; + } } - if (pkcs11_get_key(k11, CKM_RSA_PKCS) == -1) { - error("pkcs11_get_key failed"); - return (-1); + k11 = xcalloc(1, sizeof(*k11)); + k11->provider = provider; + k11->keyblob = keyblob; + provider->refcount++; /* provider referenced by RSA key */ + k11->slotidx = slotidx; + /* identify key object on smartcard */ + k11->keyid_len = keyid_attrib->ulValueLen; + if (k11->keyid_len > 0) { + k11->keyid = xmalloc(k11->keyid_len); + memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len); } + TAILQ_INSERT_TAIL(&pkcs11_keys, k11, next); - f = k11->provider->function_list; - si = &k11->provider->slotinfo[k11->slotidx]; - tlen = RSA_size(rsa); - - /* XXX handle CKR_BUFFER_TOO_SMALL */ - rv = f->C_Sign(si->session, (CK_BYTE *)from, flen, to, &tlen); - if (rv == CKR_OK) - rval = tlen; - else - error("C_Sign failed: %lu", rv); - - return (rval); + return 0; } -static int -pkcs11_rsa_private_decrypt(int flen, const u_char *from, u_char *to, RSA *rsa, - int padding) +/* retrieve the key information by keyblob */ +static struct pkcs11_key * +pkcs11_lookup_key(struct sshkey *key) { - return (-1); + struct pkcs11_key *k11, *found = NULL; + struct sshbuf *keyblob; + int r; + + if ((keyblob = sshbuf_new()) == NULL) + fatal_f("sshbuf_new failed"); + if ((r = sshkey_putb(key, keyblob)) != 0) + fatal_fr(r, "sshkey_putb"); + TAILQ_FOREACH(k11, &pkcs11_keys, next) { + if (sshbuf_equals(k11->keyblob, keyblob) == 0) { + found = k11; + break; + } + } + sshbuf_free(keyblob); + return found; } +#ifdef WITH_OPENSSL +/* + * See: + * https://datatracker.ietf.org/doc/html/rfc8017#section-9.2 + */ + +/* + * 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 */ +}; + +/* + * 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 */ +}; + +/* + * 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 -pkcs11_rsa_start_wrapper(void) +rsa_hash_alg_oid(int hash_alg, const u_char **oidp, size_t *oidlenp) { - if (rsa_method != NULL) - return (0); - rsa_method = RSA_meth_dup(RSA_get_default_method()); - if (rsa_method == NULL) - return (-1); - rsa_idx = RSA_get_ex_new_index(0, "ssh-pkcs11-rsa", - NULL, NULL, pkcs11_k11_free); - if (rsa_idx == -1) - return (-1); - if (!RSA_meth_set1_name(rsa_method, "pkcs11") || - !RSA_meth_set_priv_enc(rsa_method, pkcs11_rsa_private_encrypt) || - !RSA_meth_set_priv_dec(rsa_method, pkcs11_rsa_private_decrypt)) { - error_f("setup pkcs11 method failed"); - return (-1); + 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); + return 0; } -/* redirect private key operations for rsa key to pkcs11 token */ static int -pkcs11_rsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, - CK_ATTRIBUTE *keyid_attrib, RSA *rsa) +pkcs11_sign_rsa(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) { struct pkcs11_key *k11; + struct pkcs11_slotinfo *si; + CK_FUNCTION_LIST *f; + CK_ULONG slen = 0; + CK_RV rv; + int hashalg, r, diff, siglen, ret = -1; + u_char *oid_dgst = NULL, *sig = NULL; + size_t dgst_len, oid_len, oid_dgst_len = 0; + const u_char *oid; - if (pkcs11_rsa_start_wrapper() == -1) - return (-1); + if (sigp != NULL) + *sigp = NULL; + if (lenp != NULL) + *lenp = 0; - k11 = xcalloc(1, sizeof(*k11)); - k11->provider = provider; - provider->refcount++; /* provider referenced by RSA key */ - k11->slotidx = slotidx; - /* identify key object on smartcard */ - k11->keyid_len = keyid_attrib->ulValueLen; - if (k11->keyid_len > 0) { - k11->keyid = xmalloc(k11->keyid_len); - memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len); + if ((k11 = pkcs11_lookup_key(key)) == NULL) { + error_f("no key found"); + return SSH_ERR_KEY_NOT_FOUND; } - if (RSA_set_method(rsa, rsa_method) != 1) - fatal_f("RSA_set_method failed"); - if (RSA_set_ex_data(rsa, rsa_idx, k11) != 1) - fatal_f("RSA_set_ex_data failed"); - return (0); + debug3_f("sign with alg \"%s\" using provider %s slotidx %lu", + alg == NULL ? "" : alg, k11->provider->name, (u_long)k11->slotidx); + + if (pkcs11_get_key(k11, CKM_RSA_PKCS) == -1) { + error("pkcs11_get_key failed"); + return SSH_ERR_AGENT_FAILURE; + } + + f = k11->provider->function_list; + si = &k11->provider->slotinfo[k11->slotidx]; + + if ((siglen = EVP_PKEY_size(key->pkey)) <= 0) + return SSH_ERR_INVALID_ARGUMENT; + sig = xmalloc(siglen); + slen = (CK_ULONG)siglen; + + /* Determine hash algorithm and OID for signature */ + if (alg == NULL || *alg == '\0') + hashalg = SSH_DIGEST_SHA1; + else if ((hashalg = ssh_rsa_hash_id_from_keyname(alg)) == -1) + fatal_f("couldn't determine RSA hash alg \"%s\"", alg); + if ((r = rsa_hash_alg_oid(hashalg, &oid, &oid_len)) != 0) + fatal_fr(r, "rsa_hash_alg_oid failed"); + if ((dgst_len = ssh_digest_bytes(hashalg)) == 0) + fatal_f("bad hash alg %d", hashalg); + + /* Prepare { oid || digest } */ + oid_dgst_len = oid_len + dgst_len; + oid_dgst = xcalloc(1, oid_dgst_len); + memcpy(oid_dgst, oid, oid_len); + if ((r = ssh_digest_memory(hashalg, data, datalen, + oid_dgst + oid_len, dgst_len)) == -1) + fatal_fr(r, "hash failed"); + + /* XXX handle CKR_BUFFER_TOO_SMALL */ + if ((rv = f->C_Sign(si->session, (CK_BYTE *)oid_dgst, + oid_dgst_len, sig, &slen)) != CKR_OK) { + error("C_Sign failed: %lu", rv); + goto done; + } + + if (slen < (CK_ULONG)siglen) { + diff = siglen - slen; + debug3_f("repack %lu < %d (diff %d)", + (u_long)slen, siglen, diff); + memmove(sig + diff, sig, slen); + explicit_bzero(sig, diff); + } else if (slen > (size_t)siglen) + fatal_f("bad C_Sign length"); + + if ((ret = ssh_rsa_encode_store_sig(hashalg, sig, siglen, + sigp, lenp)) != 0) + fatal_fr(ret, "couldn't store signature"); + + /* success */ + ret = 0; + done: + freezero(oid_dgst, oid_dgst_len); + free(sig); + return ret; } -#if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW) -/* openssl callback doing the actual signing operation */ -static ECDSA_SIG * -ecdsa_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *inv, - const BIGNUM *rp, EC_KEY *ec) +#ifdef OPENSSL_HAS_ECC +static int +pkcs11_sign_ecdsa(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) { struct pkcs11_key *k11; struct pkcs11_slotinfo *si; CK_FUNCTION_LIST *f; - CK_ULONG siglen = 0, bnlen; + CK_ULONG slen = 0, bnlen; CK_RV rv; - ECDSA_SIG *ret = NULL; - u_char *sig; - BIGNUM *r = NULL, *s = NULL; + BIGNUM *sig_r = NULL, *sig_s = NULL; + u_char *sig = NULL, *dgst = NULL; + size_t dgst_len = 0; + int hashalg, ret = -1, r, siglen; - if ((k11 = EC_KEY_get_ex_data(ec, ec_key_idx)) == NULL) { - ossl_error("EC_KEY_get_ex_data failed for ec"); - return (NULL); + if (sigp != NULL) + *sigp = NULL; + if (lenp != NULL) + *lenp = 0; + + if ((k11 = pkcs11_lookup_key(key)) == NULL) { + error_f("no key found"); + return SSH_ERR_KEY_NOT_FOUND; } if (pkcs11_get_key(k11, CKM_ECDSA) == -1) { error("pkcs11_get_key failed"); - return (NULL); + return SSH_ERR_AGENT_FAILURE; } + debug3_f("sign using provider %s slotidx %lu", + k11->provider->name, (u_long)k11->slotidx); + f = k11->provider->function_list; si = &k11->provider->slotinfo[k11->slotidx]; - siglen = ECDSA_size(ec); + /* Prepare digest to be signed */ + if ((hashalg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1) + fatal_f("couldn't determine ECDSA hash alg"); + if ((dgst_len = ssh_digest_bytes(hashalg)) == 0) + fatal_f("bad hash alg %d", hashalg); + dgst = xcalloc(1, dgst_len); + if ((r = ssh_digest_memory(hashalg, data, datalen, + dgst, dgst_len)) == -1) + fatal_fr(r, "hash failed"); + + if ((siglen = EVP_PKEY_size(key->pkey)) <= 0) + return SSH_ERR_INVALID_ARGUMENT; sig = xmalloc(siglen); + slen = (CK_ULONG)siglen; /* XXX handle CKR_BUFFER_TOO_SMALL */ - rv = f->C_Sign(si->session, (CK_BYTE *)dgst, dgst_len, sig, &siglen); + rv = f->C_Sign(si->session, (CK_BYTE *)dgst, dgst_len, sig, &slen); if (rv != CKR_OK) { error("C_Sign failed: %lu", rv); goto done; } - if (siglen < 64 || siglen > 132 || siglen % 2) { - error_f("bad signature length: %lu", (u_long)siglen); + if (slen < 64 || slen > 132 || slen % 2) { + error_f("bad signature length: %lu", (u_long)slen); goto done; } - bnlen = siglen/2; - if ((ret = ECDSA_SIG_new()) == NULL) { - error("ECDSA_SIG_new failed"); - goto done; - } - if ((r = BN_bin2bn(sig, bnlen, NULL)) == NULL || - (s = BN_bin2bn(sig+bnlen, bnlen, NULL)) == NULL) { + bnlen = slen/2; + if ((sig_r = BN_bin2bn(sig, bnlen, NULL)) == NULL || + (sig_s = BN_bin2bn(sig+bnlen, bnlen, NULL)) == NULL) { ossl_error("BN_bin2bn failed"); - ECDSA_SIG_free(ret); - ret = NULL; goto done; } - if (!ECDSA_SIG_set0(ret, r, s)) { - error_f("ECDSA_SIG_set0 failed"); - ECDSA_SIG_free(ret); - ret = NULL; - goto done; - } - r = s = NULL; /* now owned by ret */ + + if ((ret = ssh_ecdsa_encode_store_sig(key, sig_r, sig_s, + sigp, lenp)) != 0) + fatal_fr(ret, "couldn't store signature"); + /* success */ + ret = 0; done: - BN_free(r); - BN_free(s); + freezero(dgst, dgst_len); + BN_free(sig_r); + BN_free(sig_s); free(sig); - - return (ret); + return ret; } +#endif /* OPENSSL_HAS_ECC */ +#endif /* WITH_OPENSSL */ static int -pkcs11_ecdsa_start_wrapper(void) +pkcs11_sign_ed25519(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 (*orig_sign)(int, const unsigned char *, int, unsigned char *, - unsigned int *, const BIGNUM *, const BIGNUM *, EC_KEY *) = NULL; + struct pkcs11_key *k11; + struct pkcs11_slotinfo *si; + CK_FUNCTION_LIST *f; + CK_ULONG slen = 0; + CK_RV rv; + u_char *sig = NULL; + CK_BYTE *xdata = NULL; + int ret = -1; - if (ec_key_method != NULL) - return (0); - ec_key_idx = EC_KEY_get_ex_new_index(0, "ssh-pkcs11-ecdsa", - NULL, NULL, pkcs11_k11_free); - if (ec_key_idx == -1) - return (-1); - ec_key_method = EC_KEY_METHOD_new(EC_KEY_OpenSSL()); - if (ec_key_method == NULL) - return (-1); - EC_KEY_METHOD_get_sign(ec_key_method, &orig_sign, NULL, NULL); - EC_KEY_METHOD_set_sign(ec_key_method, orig_sign, NULL, ecdsa_do_sign); - return (0); -} + if (sigp != NULL) + *sigp = NULL; + if (lenp != NULL) + *lenp = 0; -static int -pkcs11_ecdsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, - CK_ATTRIBUTE *keyid_attrib, EC_KEY *ec) -{ - struct pkcs11_key *k11; + if ((k11 = pkcs11_lookup_key(key)) == NULL) { + error_f("no key found"); + return SSH_ERR_KEY_NOT_FOUND; + } - if (pkcs11_ecdsa_start_wrapper() == -1) - return (-1); + if (pkcs11_get_key(k11, CKM_EDDSA) == -1) { + error("pkcs11_get_key failed"); + return SSH_ERR_AGENT_FAILURE; + } - k11 = xcalloc(1, sizeof(*k11)); - k11->provider = provider; - provider->refcount++; /* provider referenced by ECDSA key */ - k11->slotidx = slotidx; - /* identify key object on smartcard */ - k11->keyid_len = keyid_attrib->ulValueLen; - if (k11->keyid_len > 0) { - k11->keyid = xmalloc(k11->keyid_len); - memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len); + debug3_f("sign using provider %s slotidx %lu", + k11->provider->name, (u_long)k11->slotidx); + + f = k11->provider->function_list; + si = &k11->provider->slotinfo[k11->slotidx]; + + xdata = xmalloc(datalen); + memcpy(xdata, data, datalen); + sig = xmalloc(crypto_sign_ed25519_BYTES); + slen = crypto_sign_ed25519_BYTES; + + rv = f->C_Sign(si->session, xdata, datalen, sig, &slen); + if (rv != CKR_OK) { + error("C_Sign failed: %lu", rv); + goto done; } - if (EC_KEY_set_method(ec, ec_key_method) != 1) - fatal_f("EC_KEY_set_method failed"); - if (EC_KEY_set_ex_data(ec, ec_key_idx, k11) != 1) - fatal_f("EC_KEY_set_ex_data failed"); + if (slen != crypto_sign_ed25519_BYTES) { + error_f("bad signature length: %lu", (u_long)slen); + goto done; + } + if ((ret = ssh_ed25519_encode_store_sig(sig, slen, sigp, lenp)) != 0) + fatal_fr(ret, "couldn't store signature"); - return (0); + /* success */ + ret = 0; + done: + if (xdata != NULL) + freezero(xdata, datalen); + free(sig); + return ret; } -#endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */ /* remove trailing spaces */ static char * @@ -702,7 +851,8 @@ pkcs11_key_included(struct sshkey ***keysp, int *nkeys, struct sshkey *key) return (0); } -#if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW) +#ifdef WITH_OPENSSL +#ifdef OPENSSL_HAS_ECC static struct sshkey * pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, CK_OBJECT_HANDLE *obj) @@ -716,8 +866,7 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, EC_GROUP *group = NULL; struct sshkey *key = NULL; const unsigned char *attrp = NULL; - int i; - int nid; + int success = -1, r, i, nid; memset(&key_attr, 0, sizeof(key_attr)); key_attr[0].type = CKA_ID; @@ -791,6 +940,11 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, ossl_error("o2i_ECPublicKey failed"); goto fail; } + if ((r = sshkey_ec_validate_public(EC_KEY_get0_group(ec), + EC_KEY_get0_public_key(ec))) != 0) { + error_fr(r, "invalid EC key"); + goto fail; + } nid = sshkey_ecdsa_key_to_nid(ec); if (nid < 0) { @@ -798,9 +952,6 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, goto fail; } - if (pkcs11_ecdsa_wrap(p, slotidx, &key_attr[0], ec)) - goto fail; - key = sshkey_new(KEY_UNSPEC); if (key == NULL) { error("sshkey_new failed"); @@ -815,8 +966,15 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, key->ecdsa_nid = nid; key->type = KEY_ECDSA; key->flags |= SSHKEY_FLAG_EXT; - + if (pkcs11_record_key(p, slotidx, &key_attr[0], key)) + goto fail; + /* success */ + success = 0; fail: + if (success != 0) { + sshkey_free(key); + key = NULL; + } for (i = 0; i < 3; i++) free(key_attr[i].pValue); if (ec) @@ -828,7 +986,7 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, return (key); } -#endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */ +#endif /* OPENSSL_HAS_ECC */ static struct sshkey * pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, @@ -841,7 +999,7 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, RSA *rsa = NULL; BIGNUM *rsa_n, *rsa_e; struct sshkey *key = NULL; - int i; + int i, success = -1; memset(&key_attr, 0, sizeof(key_attr)); key_attr[0].type = CKA_ID; @@ -897,9 +1055,6 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, fatal_f("set key"); rsa_n = rsa_e = NULL; /* transferred */ - if (pkcs11_rsa_wrap(p, slotidx, &key_attr[0], rsa)) - goto fail; - key = sshkey_new(KEY_UNSPEC); if (key == NULL) { error("sshkey_new failed"); @@ -913,15 +1068,137 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, fatal("EVP_PKEY_set1_RSA failed"); key->type = KEY_RSA; key->flags |= SSHKEY_FLAG_EXT; - + if (EVP_PKEY_bits(key->pkey) < SSH_RSA_MINIMUM_MODULUS_SIZE) { + error_f("RSA key too small %d < minimum %d", + EVP_PKEY_bits(key->pkey), SSH_RSA_MINIMUM_MODULUS_SIZE); + goto fail; + } + if (pkcs11_record_key(p, slotidx, &key_attr[0], key)) + goto fail; + /* success */ + success = 0; fail: for (i = 0; i < 3; i++) free(key_attr[i].pValue); RSA_free(rsa); + if (success != 0) { + sshkey_free(key); + key = NULL; + } + return key; +} +#endif /* WITH_OPENSSL */ - return (key); +static struct sshkey * +pkcs11_fetch_ed25519_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, + CK_OBJECT_HANDLE *obj) +{ + CK_ATTRIBUTE key_attr[3]; + CK_SESSION_HANDLE session; + CK_FUNCTION_LIST *f = NULL; + CK_RV rv; + struct sshkey *key = NULL; + const unsigned char *d = NULL; + size_t len; + char *hex = NULL; + int success = -1, i; + /* https://docs.oasis-open.org/pkcs11/pkcs11-curr/v3.0/os/pkcs11-curr-v3.0-os.html#_Toc30061180 */ + const u_char id1[14] = { + 0x13, 0x0c, 0x65, 0x64, 0x77, 0x61, 0x72, 0x64, + 0x73, 0x32, 0x35, 0x35, 0x31, 0x39, + }; /* PrintableString { "edwards25519" } */ + const u_char id2[5] = { + 0x06, 0x03, 0x2b, 0x65, 0x70, + }; /* OBJECT_IDENTIFIER { 1.3.101.112 } */ + + memset(&key_attr, 0, sizeof(key_attr)); + key_attr[0].type = CKA_ID; + key_attr[1].type = CKA_EC_POINT; /* XXX or CKA_VALUE ? */ + key_attr[2].type = CKA_EC_PARAMS; + + session = p->slotinfo[slotidx].session; + f = p->function_list; + + /* figure out size of the attributes */ + rv = f->C_GetAttributeValue(session, *obj, key_attr, 3); + if (rv != CKR_OK) { + error("C_GetAttributeValue failed: %lu", rv); + return (NULL); + } + + /* + * Allow CKA_ID (always first attribute) to be empty, but + * ensure that none of the others are zero length. + * XXX assumes CKA_ID is always first. + */ + if (key_attr[1].ulValueLen == 0 || + key_attr[2].ulValueLen == 0) { + error("invalid attribute length"); + return (NULL); + } + + /* allocate buffers for attributes */ + for (i = 0; i < 3; i++) { + if (key_attr[i].ulValueLen > 0) + key_attr[i].pValue = xcalloc(1, key_attr[i].ulValueLen); + } + + /* retrieve ID, public point and curve parameters of EC key */ + rv = f->C_GetAttributeValue(session, *obj, key_attr, 3); + if (rv != CKR_OK) { + error("C_GetAttributeValue failed: %lu", rv); + goto fail; + } + + /* Expect one of the supported identifiers in CKA_EC_PARAMS */ + d = (u_char *)key_attr[2].pValue; + len = key_attr[2].ulValueLen; + if ((len != sizeof(id1) || memcmp(d, id1, sizeof(id1)) != 0) && + (len != sizeof(id2) || memcmp(d, id2, sizeof(id2)) != 0)) { + hex = tohex(d, len); + logit_f("unsupported CKA_EC_PARAMS: %s (len %zu)", hex, len); + goto fail; + } + + /* + * Expect either a raw 32 byte pubkey or an OCTET STRING with + * a 32 byte pubkey in CKA_VALUE + */ + d = (u_char *)key_attr[1].pValue; + len = key_attr[1].ulValueLen; + if (len == ED25519_PK_SZ + 2 && d[0] == 0x04 && d[1] == ED25519_PK_SZ) { + d += 2; + len -= 2; + } + if (len != ED25519_PK_SZ) { + hex = tohex(key_attr[1].pValue, key_attr[1].ulValueLen); + logit_f("CKA_EC_POINT invalid octet str: %s (len %lu)", + hex, (u_long)key_attr[1].ulValueLen); + goto fail; + } + + if ((key = sshkey_new(KEY_UNSPEC)) == NULL) + fatal_f("sshkey_new failed"); + key->ed25519_pk = xmalloc(ED25519_PK_SZ); + memcpy(key->ed25519_pk, d, ED25519_PK_SZ); + key->type = KEY_ED25519; + key->flags |= SSHKEY_FLAG_EXT; + if (pkcs11_record_key(p, slotidx, &key_attr[0], key)) + goto fail; + /* success */ + success = 0; + fail: + if (success != 0) { + sshkey_free(key); + key = NULL; + } + free(hex); + for (i = 0; i < 3; i++) + free(key_attr[i].pValue); + return key; } +#ifdef WITH_OPENSSL static int pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, CK_OBJECT_HANDLE *obj, struct sshkey **keyp, char **labelp) @@ -934,16 +1211,18 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, X509_NAME *x509_name = NULL; EVP_PKEY *evp; RSA *rsa = NULL; -#ifdef OPENSSL_HAS_ECC - EC_KEY *ec = NULL; -#endif + struct sshkey *key = NULL; - int i; -#if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW) - int nid; -#endif + int i, success = -1; const u_char *cp; char *subject = NULL; +#ifdef OPENSSL_HAS_ED25519 + size_t len; +#endif /* OPENSSL_HAS_ED25519 */ +#ifdef OPENSSL_HAS_ECC + EC_KEY *ec = NULL; + int r, nid; +#endif *keyp = NULL; *labelp = NULL; @@ -1015,9 +1294,6 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, goto out; } - if (pkcs11_rsa_wrap(p, slotidx, &cert_attr[0], rsa)) - goto out; - key = sshkey_new(KEY_UNSPEC); if (key == NULL) { error("sshkey_new failed"); @@ -1031,7 +1307,17 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, fatal("EVP_PKEY_set1_RSA failed"); key->type = KEY_RSA; key->flags |= SSHKEY_FLAG_EXT; -#if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW) + if (EVP_PKEY_bits(key->pkey) < SSH_RSA_MINIMUM_MODULUS_SIZE) { + error_f("RSA key too small %d < minimum %d", + EVP_PKEY_bits(key->pkey), + SSH_RSA_MINIMUM_MODULUS_SIZE); + goto out; + } + if (pkcs11_record_key(p, slotidx, &cert_attr[0], key)) + goto out; + /* success */ + success = 0; +#ifdef OPENSSL_HAS_ECC } else if (EVP_PKEY_base_id(evp) == EVP_PKEY_EC) { if (EVP_PKEY_get0_EC_KEY(evp) == NULL) { error("invalid x509; no ec key"); @@ -1041,16 +1327,17 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, error("EC_KEY_dup failed"); goto out; } - + if ((r = sshkey_ec_validate_public(EC_KEY_get0_group(ec), + EC_KEY_get0_public_key(ec))) != 0) { + error_fr(r, "invalid EC key"); + goto out; + } nid = sshkey_ecdsa_key_to_nid(ec); if (nid < 0) { error("couldn't get curve nid"); goto out; } - if (pkcs11_ecdsa_wrap(p, slotidx, &cert_attr[0], ec)) - goto out; - key = sshkey_new(KEY_UNSPEC); if (key == NULL) { error("sshkey_new failed"); @@ -1065,7 +1352,33 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, key->ecdsa_nid = nid; key->type = KEY_ECDSA; key->flags |= SSHKEY_FLAG_EXT; -#endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */ + if (pkcs11_record_key(p, slotidx, &cert_attr[0], key)) + goto out; + /* success */ + success = 0; +#endif /* OPENSSL_HAS_ECC */ +#ifdef OPENSSL_HAS_ED25519 + } else if (EVP_PKEY_base_id(evp) == EVP_PKEY_ED25519) { + if ((key = sshkey_new(KEY_UNSPEC)) == NULL || + (key->ed25519_pk = calloc(1, ED25519_PK_SZ)) == NULL) + fatal_f("allocation failed"); + len = ED25519_PK_SZ; + if (!EVP_PKEY_get_raw_public_key(evp, key->ed25519_pk, &len)) { + ossl_error("EVP_PKEY_get_raw_public_key failed"); + goto out; + } + if (len != ED25519_PK_SZ) { + error_f("incorrect returned public key " + "length for ed25519"); + goto out; + } + key->type = KEY_ED25519; + key->flags |= SSHKEY_FLAG_EXT; + if (pkcs11_record_key(p, slotidx, &cert_attr[0], key)) + goto out; + /* success */ + success = 0; +#endif /* OPENSSL_HAS_ED25519 */ } else { error("unknown certificate key type"); goto out; @@ -1077,8 +1390,9 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, RSA_free(rsa); #ifdef OPENSSL_HAS_ECC EC_KEY_free(ec); -#endif - if (key == NULL) { +#endif /* OPENSSL_HAS_ECC */ + if (success != 0 || key == NULL) { + sshkey_free(key); free(subject); return -1; } @@ -1087,17 +1401,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, *labelp = subject; return 0; } - -#if 0 -static int -have_rsa_key(const RSA *rsa) -{ - const BIGNUM *rsa_n, *rsa_e; - - RSA_get0_key(rsa, &rsa_n, &rsa_e, NULL); - return rsa_n != NULL && rsa_e != NULL; -} -#endif +#endif /* WITH_OPENSSL */ static void note_key(struct pkcs11_provider *p, CK_ULONG slotidx, const char *context, @@ -1115,6 +1419,7 @@ note_key(struct pkcs11_provider *p, CK_ULONG slotidx, const char *context, free(fp); } +#ifdef WITH_OPENSSL /* libcrypto needed for certificate parsing */ /* * lookup certificates for token in slot identified by slotidx, * add 'wrapped' public keys to the 'keysp' array and increment nkeys. @@ -1192,7 +1497,7 @@ pkcs11_fetch_certs(struct pkcs11_provider *p, CK_ULONG slotidx, } note_key(p, slotidx, __func__, key); if (pkcs11_key_included(keysp, nkeys, key)) { - debug2_f("key already included");; + debug2_f("key already included"); sshkey_free(key); } else { /* expand key array and add key */ @@ -1219,6 +1524,7 @@ pkcs11_fetch_certs(struct pkcs11_provider *p, CK_ULONG slotidx, return (ret); } +#endif /* WITH_OPENSSL */ /* * lookup public keys for token in slot identified by slotidx, @@ -1286,18 +1592,24 @@ pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, label[key_attr[1].ulValueLen] = '\0'; switch (ck_key_type) { +#ifdef WITH_OPENSSL case CKK_RSA: key = pkcs11_fetch_rsa_pubkey(p, slotidx, &obj); break; -#if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW) +#ifdef OPENSSL_HAS_ECC case CKK_ECDSA: key = pkcs11_fetch_ecdsa_pubkey(p, slotidx, &obj); break; -#endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */ +#endif /* OPENSSL_HAS_ECC */ +#endif /* WITH_OPENSSL */ + case CKK_EC_EDWARDS: + key = pkcs11_fetch_ed25519_pubkey(p, slotidx, &obj); + break; default: /* XXX print key type? */ key = NULL; - error("skipping unsupported key type"); + error("skipping unsupported key type 0x%lx", + (u_long)ck_key_type); } if (key == NULL) { @@ -1306,7 +1618,7 @@ pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, } note_key(p, slotidx, __func__, key); if (pkcs11_key_included(keysp, nkeys, key)) { - debug2_f("key already included");; + debug2_f("key already included"); sshkey_free(key); } else { /* expand key array and add key */ @@ -1431,7 +1743,7 @@ pkcs11_decode_hex(const char *hex, unsigned char **dest, size_t *rlen) *dest = xmalloc(len); for (i = 0; i < len; i++) { - int hi, low; + int hi, lo; hi = h2i(hex[2 * i]); lo = h2i(hex[(2 * i) + 1]); @@ -1652,7 +1964,9 @@ pkcs11_register_provider(char *provider_id, char *pin, keyp == NULL) continue; pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys); +#ifdef WITH_OPENSSL pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys); +#endif if (nkeys == 0 && !p->slotinfo[i].logged_in && pkcs11_interactive) { /* @@ -1665,7 +1979,9 @@ pkcs11_register_provider(char *provider_id, char *pin, continue; } pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys); +#ifdef WITH_OPENSSL pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys); +#endif } } @@ -1693,6 +2009,37 @@ pkcs11_register_provider(char *provider_id, char *pin, return (ret); } +int +pkcs11_init(int interactive) +{ + debug3_f("called, interactive = %d", interactive); + + pkcs11_interactive = interactive; + TAILQ_INIT(&pkcs11_providers); + TAILQ_INIT(&pkcs11_keys); + return (0); +} + +/* unregister all providers, keys might still point to the providers */ +void +pkcs11_terminate(void) +{ + struct pkcs11_provider *p; + struct pkcs11_key *k11; + + debug3_f("called"); + + while ((k11 = TAILQ_FIRST(&pkcs11_keys)) != NULL) { + TAILQ_REMOVE(&pkcs11_keys, k11, next); + pkcs11_k11_free(k11); + } + while ((p = TAILQ_FIRST(&pkcs11_providers)) != NULL) { + TAILQ_REMOVE(&pkcs11_providers, p, next); + pkcs11_provider_finalize(p); + pkcs11_provider_unref(p); + } +} + /* * register a new provider and get number of keys hold by the token, * fails if provider already exists @@ -1719,6 +2066,41 @@ pkcs11_add_provider(char *provider_id, char *pin, struct sshkey ***keyp, return (nkeys); } +int +pkcs11_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) +{ + switch (key->type) { + case KEY_RSA: + case KEY_RSA_CERT: +#ifdef WITH_OPENSSL + return pkcs11_sign_rsa(key, sigp, lenp, data, datalen, + alg, sk_provider, sk_pin, compat); +#ifdef OPENSSL_HAS_ECC + case KEY_ECDSA: + case KEY_ECDSA_CERT: + return pkcs11_sign_ecdsa(key, sigp, lenp, data, datalen, + alg, sk_provider, sk_pin, compat); +#endif /* OPENSSL_HAS_ECC */ +#endif /* WITH_OPENSSL */ + case KEY_ED25519: + case KEY_ED25519_CERT: + return pkcs11_sign_ed25519(key, sigp, lenp, data, datalen, + alg, sk_provider, sk_pin, compat); + default: + return SSH_ERR_KEY_TYPE_UNKNOWN; + } +} + +void +pkcs11_key_free(struct sshkey *key) +{ + /* never called */ +} + #ifdef WITH_PKCS11_KEYGEN struct sshkey * pkcs11_gakp(char *provider_id, char *pin, unsigned int slotidx, char *label, @@ -1862,10 +2244,24 @@ pkcs11_destroy_keypair(char *provider_id, char *pin, unsigned long slotidx, *err = rv; key_type = -1; } - if (key_type == CKK_RSA) + switch (key_type) { +#ifdef WITH_OPENSSL + case CKK_RSA: k = pkcs11_fetch_rsa_pubkey(p, slotidx, &obj); - else if (key_type == CKK_ECDSA) + break; +#ifdef OPENSSL_HAS_ECC + case CKK_ECDSA: k = pkcs11_fetch_ecdsa_pubkey(p, slotidx, &obj); + break; +#endif /* OPENSSL_HAS_ECC */ +#endif /* WITH_OPENSSL */ + case CKK_EC_EDWARDS: + k = pkcs11_fetch_ed25519_pubkey(p, slotidx, &obj); + break; + default: + debug_f("unsupported key type %lu", (u_long)key_type); + break; + } if ((rv = f->C_DestroyObject(session, obj)) != CKR_OK) { debug_f("could not destroy public key 0x%hhx", keyid); @@ -1893,11 +2289,13 @@ pkcs11_destroy_keypair(char *provider_id, char *pin, unsigned long slotidx, #include "log.h" #include "sshkey.h" +#include "ssherr.h" +#include "ssh-pkcs11.h" int pkcs11_init(int interactive) { - error("%s: dlopen() not supported", __func__); + error_f("PKCS#11 not supported"); return (-1); } @@ -1905,13 +2303,30 @@ int pkcs11_add_provider(char *provider_id, char *pin, struct sshkey ***keyp, char ***labelsp) { - error("%s: dlopen() not supported", __func__); + error_f("PKCS#11 not supported"); return (-1); } +void +pkcs11_key_free(struct sshkey *key) +{ + error_f("PKCS#11 not supported"); +} + +int +pkcs11_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) +{ + error_f("PKCS#11 not supported"); + return SSH_ERR_FEATURE_UNSUPPORTED; +} + void pkcs11_terminate(void) { - error("%s: dlopen() not supported", __func__); + error_f("PKCS#11 not supported"); } #endif /* ENABLE_PKCS11 */ diff --git a/ssh-pkcs11.h b/ssh-pkcs11.h index 5260223..d86c506 100644 --- a/ssh-pkcs11.h +++ b/ssh-pkcs11.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-pkcs11.h,v 1.7 2023/12/18 14:46:56 djm Exp $ */ +/* $OpenBSD: ssh-pkcs11.h,v 1.9 2025/07/30 04:27:42 djm Exp $ */ /* * Copyright (c) 2010 Markus Friedl. All rights reserved. * @@ -22,10 +22,17 @@ #define SSH_PKCS11_ERR_PIN_REQUIRED 4 #define SSH_PKCS11_ERR_PIN_LOCKED 5 +struct sshkey; + int pkcs11_init(int); void pkcs11_terminate(void); int pkcs11_add_provider(char *, char *, struct sshkey ***, char ***); int pkcs11_del_provider(char *); +int pkcs11_sign(struct sshkey *, u_char **, size_t *, + const u_char *, size_t, const char *, const char *, + const char *, u_int); +void pkcs11_key_free(struct sshkey *); + #ifdef WITH_PKCS11_KEYGEN struct sshkey * pkcs11_gakp(char *, char *, unsigned int, char *, unsigned int, @@ -35,9 +42,6 @@ struct sshkey * u_int32_t *); #endif -/* Only available in ssh-pkcs11-client.c so far */ +/* Only available in ssh-pkcs11-client.c */ int pkcs11_make_cert(const struct sshkey *, const struct sshkey *, struct sshkey **); -#if !defined(WITH_OPENSSL) && defined(ENABLE_PKCS11) -#undef ENABLE_PKCS11 -#endif diff --git a/ssh-rsa.c b/ssh-rsa.c index 3ad1fdd..fe15189 100644 --- a/ssh-rsa.c +++ b/ssh-rsa.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-rsa.c,v 1.80 2024/08/15 00:51:51 djm Exp $ */ +/* $OpenBSD: ssh-rsa.c,v 1.82 2025/10/03 00:08:02 djm Exp $ */ /* * Copyright (c) 2000, 2003 Markus Friedl * @@ -21,6 +21,8 @@ #include +#include "openbsd-compat/openssl-compat.h" +#include #include #include @@ -34,8 +36,6 @@ #include "digest.h" #include "log.h" -#include "openbsd-compat/openssl-compat.h" - static u_int ssh_rsa_size(const struct sshkey *k) { @@ -309,8 +309,8 @@ ssh_rsa_deserialize_private(const char *ktype, struct sshbuf *b, return r; } -static const char * -rsa_hash_alg_ident(int hash_alg) +const char * +ssh_rsa_hash_alg_ident(int hash_alg) { switch (hash_alg) { case SSH_DIGEST_SHA1: @@ -344,8 +344,8 @@ rsa_hash_id_from_ident(const char *ident) * 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 +ssh_rsa_hash_id_from_keyname(const char *alg) { int r; @@ -410,7 +410,6 @@ ssh_rsa_sign(struct sshkey *key, size_t diff, len = 0; int slen = 0; int hash_alg, ret = SSH_ERR_INTERNAL_ERROR; - struct sshbuf *b = NULL; if (lenp != NULL) *lenp = 0; @@ -420,7 +419,7 @@ ssh_rsa_sign(struct sshkey *key, if (alg == NULL || strlen(alg) == 0) hash_alg = SSH_DIGEST_SHA1; else - hash_alg = rsa_hash_id_from_keyname(alg); + hash_alg = ssh_rsa_hash_id_from_keyname(alg); if (key == NULL || key->pkey == NULL || hash_alg == -1 || sshkey_type_plain(key->type) != KEY_RSA) @@ -442,16 +441,42 @@ ssh_rsa_sign(struct sshkey *key, ret = SSH_ERR_INTERNAL_ERROR; goto out; } + if ((ret = ssh_rsa_encode_store_sig(hash_alg, sig, slen, + sigp, lenp)) != 0) + goto out; + + /* success */ + ret = 0; + out: + freezero(sig, slen); + return ret; +} - /* encode signature */ +int +ssh_rsa_encode_store_sig(int hash_alg, const u_char *sig, size_t slen, + u_char **sigp, size_t *lenp) +{ + struct sshbuf *b = NULL; + int ret = SSH_ERR_INTERNAL_ERROR; + size_t len; + + if (lenp != NULL) + *lenp = 0; + if (sigp != NULL) + *sigp = NULL; + + /* 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 || + if ((ret = sshbuf_put_cstring(b, + ssh_rsa_hash_alg_ident(hash_alg))) != 0 || (ret = sshbuf_put_string(b, sig, slen)) != 0) goto out; len = sshbuf_len(b); + + /* Store signature */ if (sigp != NULL) { if ((*sigp = malloc(len)) == NULL) { ret = SSH_ERR_ALLOC_FAIL; @@ -463,7 +488,6 @@ ssh_rsa_sign(struct sshkey *key, *lenp = len; ret = 0; out: - freezero(sig, slen); sshbuf_free(b); return ret; } @@ -502,7 +526,7 @@ ssh_rsa_verify(const struct sshkey *key, * 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) { + if ((want_alg = ssh_rsa_hash_id_from_keyname(alg)) == -1) { ret = SSH_ERR_INVALID_ARGUMENT; goto out; } diff --git a/ssh-sandbox.h b/ssh-sandbox.h index bd5fd83..3b74840 100644 --- a/ssh-sandbox.h +++ b/ssh-sandbox.h @@ -20,5 +20,3 @@ struct ssh_sandbox; struct ssh_sandbox *ssh_sandbox_init(struct monitor *); void ssh_sandbox_child(struct ssh_sandbox *); -void ssh_sandbox_parent_finish(struct ssh_sandbox *); -void ssh_sandbox_parent_preauth(struct ssh_sandbox *, pid_t); diff --git a/ssh-sk-helper.0 b/ssh-sk-helper.0 index 9dc341c..4abc5e8 100644 --- a/ssh-sk-helper.0 +++ b/ssh-sk-helper.0 @@ -31,4 +31,4 @@ HISTORY AUTHORS Damien Miller -OpenBSD 7.6 April 29, 2022 OpenBSD 7.6 +OpenBSD 7.7 April 29, 2022 OpenBSD 7.7 diff --git a/ssh-sk-helper.c b/ssh-sk-helper.c index 9857b63..806019c 100644 --- a/ssh-sk-helper.c +++ b/ssh-sk-helper.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-sk-helper.c,v 1.14 2022/12/04 11:03:11 dtucker Exp $ */ +/* $OpenBSD: ssh-sk-helper.c,v 1.15 2025/07/24 05:44:55 djm Exp $ */ /* * Copyright (c) 2019 Google LLC * @@ -45,6 +45,7 @@ #include "uidswap.h" #include "ssherr.h" #include "ssh-sk.h" +#include "ssh-pkcs11.h" #ifdef ENABLE_SK extern char *__progname; @@ -87,6 +88,22 @@ null_empty(char **s) *s = NULL; } +/* stubs */ +int +pkcs11_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) +{ + return SSH_ERR_INTERNAL_ERROR; +} + +void +pkcs11_key_free(struct sshkey *key) +{ +} + static struct sshbuf * process_sign(struct sshbuf *req) { diff --git a/ssh-sk.c b/ssh-sk.c index a2a7d72..6bb1edc 100644 --- a/ssh-sk.c +++ b/ssh-sk.c @@ -23,9 +23,7 @@ #include #include -#ifdef HAVE_STDINT_H -# include -#endif +#include #include #include diff --git a/ssh-xmss.c b/ssh-xmss.c deleted file mode 100644 index b6d0561..0000000 --- a/ssh-xmss.c +++ /dev/null @@ -1,389 +0,0 @@ -/* $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 -#include - -#include -#include -#include -#ifdef HAVE_STDINT_H -# include -#endif -#include - -#include "log.h" -#include "sshbuf.h" -#include "sshkey.h" -#include "sshkey-xmss.h" -#include "ssherr.h" -#include "ssh.h" - -#include "xmss_fast.h" - -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; -} - -static int -ssh_xmss_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) -{ - 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 || - sig == NULL || siglen == 0) - return SSH_ERR_INVALID_ARGUMENT; - if ((r = sshkey_xmss_siglen(key, &required_siglen)) != 0) - return r; - if (dlen >= INT_MAX - required_siglen) - return SSH_ERR_INVALID_ARGUMENT; - - 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 (dlen >= SIZE_MAX - len) { - r = SSH_ERR_INVALID_ARGUMENT; - goto out; - } - 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, 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 != 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/ssh.0 b/ssh.0 index 5ab1bc8..5cc410b 100644 --- a/ssh.0 +++ b/ssh.0 @@ -250,24 +250,27 @@ DESCRIPTION AddressFamily BatchMode BindAddress + BindInterface + CASignatureAlgorithms CanonicalDomains CanonicalizeFallbackLocal CanonicalizeHostname CanonicalizeMaxDots CanonicalizePermittedCNAMEs - CASignatureAlgorithms CertificateFile + ChannelTimeout CheckHostIP Ciphers ClearAllForwardings Compression - ConnectionAttempts ConnectTimeout + ConnectionAttempts ControlMaster ControlPath ControlPersist DynamicForward EnableEscapeCommandline + EnableSSHKeysign EscapeChar ExitOnForwardFailure FingerprintHash @@ -276,21 +279,23 @@ DESCRIPTION ForwardX11 ForwardX11Timeout ForwardX11Trusted - GatewayPorts - GlobalKnownHostsFile GSSAPIAuthentication GSSAPIDelegateCredentials + GatewayPorts + GlobalKnownHostsFile HashKnownHosts Host - HostbasedAcceptedAlgorithms - HostbasedAuthentication HostKeyAlgorithms HostKeyAlias + HostbasedAcceptedAlgorithms + HostbasedAuthentication Hostname + IPQoS IdentitiesOnly IdentityAgent IdentityFile - IPQoS + IgnoreUnknown + Include KbdInteractiveAuthentication KbdInteractiveDevices KexAlgorithms @@ -298,14 +303,15 @@ DESCRIPTION LocalCommand LocalForward LogLevel + LogVerbose MACs - Match NoHostAuthenticationForLocalhost NumberOfPasswordPrompts + ObscureKeystrokeTiming + PKCS11Provider PasswordAuthentication PermitLocalCommand PermitRemoteOpen - PKCS11Provider Port PreferredAuthentications ProxyCommand @@ -318,16 +324,20 @@ DESCRIPTION RemoteForward RequestTTY RequiredRSASize + RevokedHostKeys + SecurityKeyProvider SendEnv - ServerAliveInterval ServerAliveCountMax + ServerAliveInterval SessionType SetEnv StdinNull StreamLocalBindMask StreamLocalBindUnlink StrictHostKeyChecking + SyslogFacility TCPKeepAlive + Tag Tunnel TunnelDevice UpdateHostKeys @@ -1017,4 +1027,4 @@ AUTHORS created OpenSSH. Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. -OpenBSD 7.6 July 18, 2024 OpenBSD 7.6 +OpenBSD 7.7 December 4, 2024 OpenBSD 7.7 diff --git a/ssh.1 b/ssh.1 index 710d3d4..697f4e4 100644 --- a/ssh.1 +++ b/ssh.1 @@ -33,8 +33,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: ssh.1,v 1.443 2024/07/18 01:47:27 djm Exp $ -.Dd $Mdocdate: July 18 2024 $ +.\" $OpenBSD: ssh.1,v 1.444 2024/12/04 14:37:55 djm Exp $ +.Dd $Mdocdate: December 4 2024 $ .Dt SSH 1 .Os .Sh NAME @@ -509,24 +509,27 @@ For full details of the options listed below, and their possible values, see .It AddressFamily .It BatchMode .It BindAddress +.It BindInterface +.It CASignatureAlgorithms .It CanonicalDomains .It CanonicalizeFallbackLocal .It CanonicalizeHostname .It CanonicalizeMaxDots .It CanonicalizePermittedCNAMEs -.It CASignatureAlgorithms .It CertificateFile +.It ChannelTimeout .It CheckHostIP .It Ciphers .It ClearAllForwardings .It Compression -.It ConnectionAttempts .It ConnectTimeout +.It ConnectionAttempts .It ControlMaster .It ControlPath .It ControlPersist .It DynamicForward .It EnableEscapeCommandline +.It EnableSSHKeysign .It EscapeChar .It ExitOnForwardFailure .It FingerprintHash @@ -535,21 +538,23 @@ For full details of the options listed below, and their possible values, see .It ForwardX11 .It ForwardX11Timeout .It ForwardX11Trusted -.It GatewayPorts -.It GlobalKnownHostsFile .It GSSAPIAuthentication .It GSSAPIDelegateCredentials +.It GatewayPorts +.It GlobalKnownHostsFile .It HashKnownHosts .It Host -.It HostbasedAcceptedAlgorithms -.It HostbasedAuthentication .It HostKeyAlgorithms .It HostKeyAlias +.It HostbasedAcceptedAlgorithms +.It HostbasedAuthentication .It Hostname +.It IPQoS .It IdentitiesOnly .It IdentityAgent .It IdentityFile -.It IPQoS +.It IgnoreUnknown +.It Include .It KbdInteractiveAuthentication .It KbdInteractiveDevices .It KexAlgorithms @@ -557,14 +562,15 @@ For full details of the options listed below, and their possible values, see .It LocalCommand .It LocalForward .It LogLevel +.It LogVerbose .It MACs -.It Match .It NoHostAuthenticationForLocalhost .It NumberOfPasswordPrompts +.It ObscureKeystrokeTiming +.It PKCS11Provider .It PasswordAuthentication .It PermitLocalCommand .It PermitRemoteOpen -.It PKCS11Provider .It Port .It PreferredAuthentications .It ProxyCommand @@ -577,16 +583,20 @@ For full details of the options listed below, and their possible values, see .It RemoteForward .It RequestTTY .It RequiredRSASize +.It RevokedHostKeys +.It SecurityKeyProvider .It SendEnv -.It ServerAliveInterval .It ServerAliveCountMax +.It ServerAliveInterval .It SessionType .It SetEnv .It StdinNull .It StreamLocalBindMask .It StreamLocalBindUnlink .It StrictHostKeyChecking +.It SyslogFacility .It TCPKeepAlive +.It Tag .It Tunnel .It TunnelDevice .It UpdateHostKeys diff --git a/ssh.c b/ssh.c index 0019281..3b03108 100644 --- a/ssh.c +++ b/ssh.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh.c,v 1.600 2024/01/11 01:45:36 djm Exp $ */ +/* $OpenBSD: ssh.c,v 1.619 2025/09/25 07:05:11 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -43,21 +43,18 @@ #include "includes.h" #include -#ifdef HAVE_SYS_STAT_H -# include -#endif +#include #include #include #include #include +#include #include #include #include #include -#ifdef HAVE_PATHS_H #include -#endif #include #include #include @@ -528,16 +525,28 @@ resolve_canonicalize(char **hostp, int port) static void check_load(int r, struct sshkey **k, const char *path, const char *message) { + char *fp; + switch (r) { case 0: + if (k == NULL || *k == NULL) + return; /* Check RSA keys size and discard if undersized */ - if (k != NULL && *k != NULL && - (r = sshkey_check_rsa_length(*k, + if ((r = sshkey_check_rsa_length(*k, options.required_rsa_size)) != 0) { error_r(r, "load %s \"%s\"", message, path); free(*k); *k = NULL; + break; + } + if ((fp = sshkey_fingerprint(*k, + options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) { + fatal_f("failed to fingerprint %s %s key from %s", + sshkey_type(*k), message, path); } + debug("loaded %s from %s: %s %s", message, path, + sshkey_type(*k), fp); + free(fp); break; case SSH_ERR_INTERNAL_ERROR: case SSH_ERR_ALLOC_FAIL: @@ -551,6 +560,8 @@ check_load(int r, struct sshkey **k, const char *path, const char *message) error_r(r, "load %s \"%s\"", message, path); break; } + if (k != NULL && *k == NULL) + debug("no %s loaded from %s", message, path); } /* @@ -558,15 +569,18 @@ check_load(int r, struct sshkey **k, const char *path, const char *message) * file if the user specifies a config file on the command line. */ static void -process_config_files(const char *host_name, struct passwd *pw, int final_pass, - int *want_final_pass) +process_config_files(const char *host_name, struct passwd *pw, + int final_pass, int *want_final_pass) { - char buf[PATH_MAX]; + char *cmd, buf[PATH_MAX]; int r; + if ((cmd = sshbuf_dup_string(command)) == NULL) + fatal_f("sshbuf_dup_string failed"); if (config != NULL) { if (strcasecmp(config, "none") != 0 && - !read_config_file(config, pw, host, host_name, &options, + !read_config_file(config, pw, host, host_name, cmd, + &options, SSHCONF_USERCONF | (final_pass ? SSHCONF_FINAL : 0), want_final_pass)) fatal("Can't open user config file %.100s: " @@ -575,15 +589,16 @@ process_config_files(const char *host_name, struct passwd *pw, int final_pass, 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, + (void)read_config_file(buf, pw, host, host_name, cmd, &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, + host, host_name, cmd, &options, final_pass ? SSHCONF_FINAL : 0, want_final_pass); } + free(cmd); } /* Rewrite the port number in an addrinfo list of addresses */ @@ -634,7 +649,7 @@ valid_hostname(const char *s) if (*s == '-') return 0; for (i = 0; s[i] != 0; i++) { - if (strchr("'`\"$\\;&<>|(){}", s[i]) != NULL || + if (strchr("'`\"$\\;&<>|(){},", s[i]) != NULL || isspace((u_char)s[i]) || iscntrl((u_char)s[i])) return 0; } @@ -649,6 +664,8 @@ valid_ruser(const char *s) if (*s == '-') return 0; for (i = 0; s[i] != 0; i++) { + if (iscntrl((u_char)s[i])) + return 0; if (strchr("'`\";&<>|(){}", s[i]) != NULL) return 0; /* Disallow '-' after whitespace */ @@ -670,7 +687,8 @@ main(int ac, char **av) struct ssh *ssh = NULL; int i, r, opt, exit_status, use_syslog, direct, timeout_ms; int was_addr, config_test = 0, opt_terminated = 0, want_final_pass = 0; - char *p, *cp, *line, *argv0, *logfile; + int user_on_commandline = 0, user_was_default = 0, user_expanded = 0; + char *p, *cp, *line, *argv0, *logfile, *args; char cname[NI_MAXHOST], thishost[NI_MAXHOST]; struct stat st; struct passwd *pw; @@ -680,6 +698,7 @@ main(int ac, char **av) struct addrinfo *addrs = NULL; size_t n, len; u_int j; + struct utsname utsname; struct ssh_conn_info *cinfo = NULL; /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ @@ -739,6 +758,7 @@ main(int ac, char **av) channel_init_channels(ssh); /* Parse command-line arguments. */ + args = argv_assemble(ac, av); /* logged later */ host = NULL; use_syslog = 0; logfile = NULL; @@ -965,7 +985,7 @@ main(int ac, char **av) options.log_level = SYSLOG_LEVEL_QUIET; break; case 'e': - if (optarg[0] == '^' && optarg[2] == 0 && + if (strlen(optarg) == 2 && optarg[0] == '^' && (u_char) optarg[1] >= 64 && (u_char) optarg[1] < 128) options.escape_char = (u_char) optarg[1] & 31; @@ -1016,8 +1036,10 @@ main(int ac, char **av) } break; case 'l': - if (options.user == NULL) - options.user = optarg; + if (options.user == NULL) { + options.user = xstrdup(optarg); + user_on_commandline = 1; + } break; case 'L': @@ -1074,7 +1096,7 @@ main(int ac, char **av) case 'o': line = xstrdup(optarg); if (process_config_line(&options, pw, - host ? host : "", host ? host : "", line, + host ? host : "", host ? host : "", "", line, "command-line", 0, NULL, SSHCONF_USERCONF) != 0) exit(255); free(line); @@ -1120,6 +1142,7 @@ main(int ac, char **av) if (options.user == NULL) { options.user = tuser; tuser = NULL; + user_on_commandline = 1; } free(tuser); if (options.port == -1 && tport != -1) @@ -1134,6 +1157,7 @@ main(int ac, char **av) if (options.user == NULL) { options.user = p; p = NULL; + user_on_commandline = 1; } *cp++ = '\0'; host = xstrdup(cp); @@ -1155,8 +1179,6 @@ main(int ac, char **av) if (!valid_hostname(host)) fatal("hostname contains invalid characters"); - if (options.user != NULL && !valid_ruser(options.user)) - fatal("remote username contains invalid characters"); options.host_arg = xstrdup(host); /* Initialize the command to execute on remote host. */ @@ -1201,8 +1223,15 @@ main(int ac, char **av) SYSLOG_FACILITY_USER : options.log_facility, !use_syslog); - if (debug_flag) - logit("%s, %s", SSH_RELEASE, SSH_OPENSSL_VERSION); + debug("%s, %s", SSH_RELEASE, SSH_OPENSSL_VERSION); + if (uname(&utsname) != 0) { + memset(&utsname, 0, sizeof(utsname)); + strlcpy(utsname.sysname, "UNKNOWN", sizeof(utsname.sysname)); + } + debug3("Running on %s %s %s %s", utsname.sysname, utsname.release, + utsname.version, utsname.machine); + debug3("Started with: %s", args); + free(args); /* Parse the configuration files */ process_config_files(options.host_arg, pw, 0, &want_final_pass); @@ -1288,8 +1317,10 @@ main(int ac, char **av) if (fill_default_options(&options) != 0) cleanup_exit(255); - if (options.user == NULL) + if (options.user == NULL) { + user_was_default = 1; options.user = xstrdup(pw->pw_name); + } /* * If ProxyJump option specified, then construct a ProxyCommand now. @@ -1349,6 +1380,8 @@ main(int ac, char **av) if (options.port == 0) options.port = default_ssh_port(); channel_set_af(ssh, options.address_family); + ssh_packet_set_qos(ssh, options.ip_qos_interactive, + options.ip_qos_bulk); /* Tidy and check options */ if (options.host_key_alias != NULL) @@ -1430,11 +1463,38 @@ main(int ac, char **av) options.host_key_alias : options.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); cinfo->jmphost = xstrdup(options.jump_host == NULL ? "" : options.jump_host); + + /* + * If the user was specified via a configuration directive then attempt + * to expand it. It cannot contain %r (itself) or %C since User is + * a component of the hash. + */ + if (!user_on_commandline && !user_was_default) { + if ((p = percent_dollar_expand(options.user, + DEFAULT_CLIENT_PERCENT_EXPAND_ARGS_NOUSER(cinfo), + (char *)NULL)) == NULL) + fatal("invalid environment variable expansion"); + user_expanded = strcmp(p, options.user) != 0; + free(options.user); + options.user = p; + } + + /* + * Usernames specified on the commandline or expanded from the + * configuration file must be validated. + * Conversely, usernames from getpwnam(3) or specified as literals + * via configuration (i.e. not expanded) are not subject to validation. + */ + if ((user_on_commandline || user_expanded) && + !valid_ruser(options.user)) + fatal("remote username contains invalid characters"); + + /* Now User is expanded, store it and calculate hash. */ + cinfo->remuser = xstrdup(options.user); cinfo->conn_hash_hex = ssh_connection_hash(cinfo->thishost, cinfo->remhost, cinfo->portstr, cinfo->remuser, cinfo->jmphost); @@ -1494,6 +1554,13 @@ main(int ac, char **av) } } + if (options.version_addendum != NULL) { + cp = default_client_percent_dollar_expand( + options.version_addendum, cinfo); + free(options.version_addendum); + options.version_addendum = cp; + } + if (options.num_system_hostfiles > 0 && strcasecmp(options.system_hostfiles[0], "none") == 0) { if (options.num_system_hostfiles > 1) @@ -1526,6 +1593,28 @@ main(int ac, char **av) options.user_hostfiles[j] = p; } + for (j = 0; j < options.num_setenv; j++) { + char *name = options.setenv[j], *value; + + if (name == NULL) + continue; + /* Expand only the value portion, not the variable name. */ + if ((value = strchr(name, '=')) == NULL) { + /* shouldn't happen; vars are checked in readconf.c */ + fatal("Invalid config SetEnv: %s", name); + } + *value++ = '\0'; + cp = default_client_percent_dollar_expand(value, cinfo); + xasprintf(&p, "%s=%s", name, cp); + if (strcmp(value, p) != 0) { + debug3("expanded SetEnv '%s' '%s' -> '%s'", + name, value, cp); + } + free(options.setenv[j]); + free(cp); + options.setenv[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; @@ -1636,8 +1725,6 @@ main(int ac, char **av) &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); @@ -1664,10 +1751,9 @@ main(int ac, char **av) 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"); \ + &(sensitive_data.keys[o]), p, "hostbased pubkey"); \ if (sensitive_data.keys[o] != NULL) { \ - debug2("hostbased key %d: %s key from \"%s\"", o, \ - sshkey_ssh_name(sensitive_data.keys[o]), p); \ + debug2("hostbased pubkey \"%s\" in slot %d", p, o); \ loaded++; \ } \ } while (0) @@ -1675,10 +1761,9 @@ main(int ac, char **av) 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"); \ + &(sensitive_data.keys[o]), p, "hostbased cert"); \ if (sensitive_data.keys[o] != NULL) { \ - debug2("hostbased key %d: %s cert from \"%s\"", o, \ - sshkey_ssh_name(sensitive_data.keys[o]), p); \ + debug2("hostbased cert \"%s\" in slot %d", p, o); \ loaded++; \ } \ } while (0) @@ -1687,17 +1772,9 @@ main(int ac, char **av) L_CERT(_PATH_HOST_ECDSA_KEY_FILE, 0); L_CERT(_PATH_HOST_ED25519_KEY_FILE, 1); L_CERT(_PATH_HOST_RSA_KEY_FILE, 2); -#ifdef WITH_DSA - L_CERT(_PATH_HOST_DSA_KEY_FILE, 3); -#endif L_PUBKEY(_PATH_HOST_ECDSA_KEY_FILE, 4); L_PUBKEY(_PATH_HOST_ED25519_KEY_FILE, 5); L_PUBKEY(_PATH_HOST_RSA_KEY_FILE, 6); -#ifdef WITH_DSA - L_PUBKEY(_PATH_HOST_DSA_KEY_FILE, 7); -#endif - 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."); @@ -1788,9 +1865,13 @@ main(int ac, char **av) #endif skip_connect: + if (addrs != NULL) + freeaddrinfo(addrs); exit_status = ssh_session2(ssh, cinfo); ssh_conn_info_free(cinfo); - ssh_packet_close(ssh); + channel_free_channels(ssh); + ssh_packet_free(ssh); + pwfree(pw); if (options.control_path != NULL && muxserver_sock != -1) unlink(options.control_path); @@ -2117,7 +2198,7 @@ ssh_session2_setup(struct ssh *ssh, int id, int success, void *arg) { extern char **environ; const char *display, *term; - int r, interactive = tty_flag; + int r; char *proto = NULL, *data = NULL; if (!success) @@ -2136,7 +2217,6 @@ ssh_session2_setup(struct ssh *ssh, int id, int success, void *arg) data, 1); client_expect_confirm(ssh, id, "X11 forwarding", CONFIRM_WARN); /* XXX exit_on_forward_failure */ - interactive = 1; } check_agent_present(); @@ -2147,10 +2227,6 @@ ssh_session2_setup(struct ssh *ssh, int id, int success, void *arg) 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"); @@ -2187,8 +2263,9 @@ ssh_session2_open(struct ssh *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); + if (tty_flag) + channel_set_tty(ssh, c); + debug3_f("channel_new: %d%s", c->self, tty_flag ? " (tty)" : ""); channel_send_open(ssh, c->self); if (options.session_type != SESSION_TYPE_NONE) @@ -2201,7 +2278,7 @@ ssh_session2_open(struct ssh *ssh) static int ssh_session2(struct ssh *ssh, const struct ssh_conn_info *cinfo) { - int r, interactive, id = -1; + int r, id = -1; char *cp, *tun_fwd_ifname = NULL; /* XXX should be pre-session */ @@ -2257,14 +2334,6 @@ ssh_session2(struct ssh *ssh, const struct ssh_conn_info *cinfo) if (options.session_type != SESSION_TYPE_NONE) id = ssh_session2_open(ssh); - else { - interactive = options.control_master == SSHCTL_MASTER_NO; - /* ControlPersist may have clobbered ControlMaster, so check */ - if (need_controlpersist_detach) - interactive = otty_flag != 0; - ssh_packet_set_interactive(ssh, interactive, - 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 && @@ -2389,9 +2458,7 @@ load_public_identity_files(const struct ssh_conn_info *cinfo) 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); + &public, filename, "identity pubkey"); if (public == NULL) { free(cp); continue; @@ -2403,6 +2470,7 @@ load_public_identity_files(const struct ssh_conn_info *cinfo) free(cp); continue; } + free(cp); /* NB. leave filename pointing to private key */ identity_files[n_ids] = xstrdup(filename); identity_keys[n_ids] = public; @@ -2420,9 +2488,7 @@ load_public_identity_files(const struct ssh_conn_info *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); + &public, filename, "identity cert"); free(options.certificate_files[i]); options.certificate_files[i] = NULL; if (public == NULL) { diff --git a/ssh.h b/ssh.h index 8110c06..cd95dd8 100644 --- a/ssh.h +++ b/ssh.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh.h,v 1.90 2020/07/14 23:57:01 djm Exp $ */ +/* $OpenBSD: ssh.h,v 1.91 2024/09/25 23:01:39 jsg Exp $ */ /* * Author: Tatu Ylonen @@ -12,9 +12,6 @@ * called by a name other than "ssh" or "Secure Shell". */ -/* Cipher used for encrypting authentication files. */ -#define SSH_AUTHFILE_CIPHER SSH_CIPHER_3DES - /* Default port number. */ #define SSH_DEFAULT_PORT 22 @@ -36,11 +33,9 @@ * * Minor protocol version. Different version indicates minor incompatibility * that does not prevent interoperation. + * + * We support only SSH2 */ -#define PROTOCOL_MAJOR_1 1 -#define PROTOCOL_MINOR_1 5 - -/* We support only SSH2 */ #define PROTOCOL_MAJOR_2 2 #define PROTOCOL_MINOR_2 0 @@ -72,12 +67,6 @@ */ #define SSH_ASKPASS_REQUIRE_ENV "SSH_ASKPASS_REQUIRE" -/* - * Force host key length and server key length to differ by at least this - * many bits. This is to make double encryption with rsaref work. - */ -#define SSH_KEY_BITS_RESERVED 128 - /* * Length of the session key in bytes. (Specified as 256 bits in the * protocol.) diff --git a/ssh_api.c b/ssh_api.c index 5faaffd..7bdcee1 100644 --- a/ssh_api.c +++ b/ssh_api.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh_api.c,v 1.31 2024/09/09 02:39:57 djm Exp $ */ +/* $OpenBSD: ssh_api.c,v 1.32 2024/10/18 05:14:51 djm Exp $ */ /* * Copyright (c) 2012 Markus Friedl. All rights reserved. * @@ -532,7 +532,7 @@ _ssh_order_hostkeyalgs(struct ssh *ssh) char *orig, *avail, *oavail = NULL, *alg, *replace = NULL; char **proposal; size_t maxlen; - int ktype, r; + int ktype, nid, r; /* XXX we de-serialize ssh->kex->my, modify it, and change it */ if ((r = kex_buf2prop(ssh->kex->my, NULL, &proposal)) != 0) @@ -551,15 +551,20 @@ _ssh_order_hostkeyalgs(struct ssh *ssh) while ((alg = strsep(&avail, ",")) && *alg != '\0') { if ((ktype = sshkey_type_from_name(alg)) == KEY_UNSPEC) continue; + nid = sshkey_ecdsa_nid_from_name(alg); TAILQ_FOREACH(k, &ssh->public_keys, next) { - if (k->key->type == ktype || - (sshkey_is_cert(k->key) && k->key->type == - sshkey_type_plain(ktype))) { - if (*replace != '\0') - strlcat(replace, ",", maxlen); - strlcat(replace, alg, maxlen); - break; - } + if (k->key->type != ktype && + (!sshkey_is_cert(k->key) || + k->key->type != sshkey_type_plain(ktype))) + continue; + if (sshkey_type_plain(k->key->type) == KEY_ECDSA && + k->key->ecdsa_nid != nid) + continue; + /* Candidate */ + if (*replace != '\0') + strlcat(replace, ",", maxlen); + strlcat(replace, alg, maxlen); + break; } } if (*replace != '\0') { diff --git a/ssh_config b/ssh_config index cc56635..238a0c5 100644 --- a/ssh_config +++ b/ssh_config @@ -1,4 +1,4 @@ -# $OpenBSD: ssh_config,v 1.36 2023/08/02 23:04:38 djm Exp $ +# $OpenBSD: ssh_config,v 1.37 2025/05/06 05:40:56 djm Exp $ # This is the ssh client system-wide configuration file. See # ssh_config(5) for more information. This file provides defaults for @@ -30,7 +30,6 @@ # ConnectTimeout 0 # StrictHostKeyChecking ask # IdentityFile ~/.ssh/id_rsa -# IdentityFile ~/.ssh/id_dsa # IdentityFile ~/.ssh/id_ecdsa # IdentityFile ~/.ssh/id_ed25519 # Port 22 diff --git a/ssh_config.0 b/ssh_config.0 index dd37bff..1c236cf 100644 --- a/ssh_config.0 +++ b/ssh_config.0 @@ -55,11 +55,11 @@ DESCRIPTION Match keyword are satisfied. Match conditions are specified using one or more criteria or the single token all which always matches. The available criteria keywords are: canonical, final, - exec, localnetwork, host, originalhost, tagged, user, and - localuser. The all criteria must appear alone or immediately - after canonical or final. Other criteria may be combined - arbitrarily. All criteria but all, canonical, and final require - an argument. Criteria may be negated by prepending an + exec, localnetwork, host, originalhost, tagged, command, user, + localuser, and version. The all criteria must appear alone or + immediately after canonical or final. Other criteria may be + combined arbitrarily. All criteria but all, canonical, and final + require an argument. Criteria may be negated by prepending an exclamation mark (M-bM-^@M-^X!M-bM-^@M-^Y). The canonical keyword matches only when the configuration file is @@ -89,16 +89,32 @@ DESCRIPTION The other keywords' criteria must be single entries or comma- separated lists and may use the wildcard and negation operators - described in the PATTERNS section. The criteria for the host - keyword are matched against the target hostname, after any - substitution by the Hostname or CanonicalizeHostname options. - The originalhost keyword matches against the hostname as it was - specified on the command-line. The tagged keyword matches a tag - name specified by a prior Tag directive or on the ssh(1) command- - line using the -P flag. The user keyword matches against the - target username on the remote host. The localuser keyword - matches against the name of the local user running ssh(1) (this - keyword may be useful in system-wide ssh_config files). + described in the PATTERNS section. + + The criteria for the host keyword are matched against the target + hostname, after any substitution by the Hostname or + CanonicalizeHostname options. The originalhost keyword matches + against the hostname as it was specified on the command-line. + + The tagged keyword matches a tag name specified by a prior Tag + directive or on the ssh(1) command-line using the -P flag. The + command keyword matches the remote command that has been + requested, or the subsystem name that is being invoked (e.g. + "sftp" for an SFTP session). The empty string will match the + case where a command or tag has not been specified, i.e. M-bM-^@M-^XMatch + tag ""M-bM-^@M-^Y. The version keyword matches against the version string + of ssh(1), for example M-bM-^@M-^\OpenSSH_10.0M-bM-^@M-^]. + + The user keyword matches against the target username on the + remote host. The localuser keyword matches against the name of + the local user running ssh(1) (this keyword may be useful in + system-wide ssh_config files). + + Finally, the sessiontype keyword matches the requested session + type, which may be one of shell for interactive sessions, exec + for command execution sessions, subsystem for subsystem + invocations such as sftp(1), or none for transport-only sessions, + such as when ssh(1) is started with the -N flag. AddKeysToAgent Specifies whether keys should be automatically added to a running @@ -250,13 +266,13 @@ DESCRIPTION direct-tcpip, direct-streamlocal@openssh.com Open TCP or Unix socket (respectively) connections that - have been established from a ssh(1) local forwarding, + have been established from an ssh(1) local forwarding, i.e. LocalForward or DynamicForward. forwarded-tcpip, forwarded-streamlocal@openssh.com Open TCP or Unix socket (respectively) connections that - have been established to a sshd(8) listening on behalf of - a ssh(1) remote forwarding, i.e. RemoteForward. + have been established to an sshd(8) listening on behalf + of an ssh(1) remote forwarding, i.e. RemoteForward. session The interactive main session, including shell session, @@ -317,8 +333,8 @@ DESCRIPTION The default is: chacha20-poly1305@openssh.com, - aes128-ctr,aes192-ctr,aes256-ctr, - aes128-gcm@openssh.com,aes256-gcm@openssh.com + aes128-gcm@openssh.com,aes256-gcm@openssh.com, + aes128-ctr,aes192-ctr,aes256-ctr The list of available ciphers may also be obtained using "ssh -Q cipher". @@ -713,18 +729,18 @@ DESCRIPTION from the system configuration file. Include directive may appear inside a Match or Host block to perform conditional inclusion. - IPQoS Specifies the IPv4 type-of-service or DSCP class for connections. - Accepted values are af11, af12, af13, af21, af22, af23, af31, - af32, af33, af41, af42, af43, cs0, cs1, cs2, cs3, cs4, cs5, cs6, - cs7, ef, le, lowdelay, throughput, reliability, a numeric value, - or 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 af21 (Low-Latency - Data) for interactive sessions and cs1 (Lower Effort) for non- - interactive sessions. + IPQoS Specifies the Differentiated Services Field Codepoint (DSCP) + value for connections. Accepted values are af11, af12, af13, + af21, af22, af23, af31, af32, af33, af41, af42, af43, cs0, cs1, + cs2, cs3, cs4, cs5, cs6, cs7, ef, le, a numeric value, or 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 ef (Expedited Forwarding) for interactive sessions + and none (the operating system default) for non-interactive + sessions. KbdInteractiveAuthentication Specifies whether to use keyboard-interactive authentication. @@ -755,8 +771,8 @@ DESCRIPTION The default is: - sntrup761x25519-sha512,sntrup761x25519-sha512@openssh.com, mlkem768x25519-sha256, + sntrup761x25519-sha512,sntrup761x25519-sha512@openssh.com, curve25519-sha256,curve25519-sha256@libssh.org, ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521, diffie-hellman-group-exchange-sha256, @@ -798,21 +814,28 @@ DESCRIPTION enabled. LocalForward - Specifies that a TCP port on the local machine be forwarded over - the secure channel to the specified host and port from the remote - machine. The first argument specifies the listener and may be - [bind_address:]port or a Unix domain socket path. The second - argument is the destination and may be host:hostport or a Unix - domain socket path if the remote host supports it. + Specifies that a TCP port or Unix-domain socket on the local + machine be forwarded over the secure channel to the specified + host and port (or Unix-domain socket) from the remote machine. + For a TCP port, the first argument must be [bind_address:]port or + a Unix domain socket path. The second argument is the + destination and may be host:hostport or a Unix domain socket path + if the remote host supports it. IPv6 addresses can be specified by enclosing addresses in square - brackets. Multiple forwardings may be specified, and additional - forwardings can be given on the command line. Only the superuser - can forward privileged ports. By default, the local port is - bound in accordance with the GatewayPorts setting. However, an - explicit bind_address may be used to bind the connection to a - specific address. The bind_address of localhost indicates that - the listening port be bound for local use only, while an empty + brackets. + + If either argument contains a '/' in it, that argument will be + interpreted as a Unix-domain socket (on the corresponding host) + rather than a TCP port. + + Multiple forwardings may be specified, and additional forwardings + can be given on the command line. Only the superuser can forward + privileged ports. By default, the local port is bound in + accordance with the GatewayPorts setting. However, an explicit + bind_address may be used to bind the connection to a specific + address. The bind_address of localhost indicates that the + listening port be bound for local use only, while an empty address or M-bM-^@M-^X*M-bM-^@M-^Y indicates that the port should be available from all interfaces. Unix domain socket paths may use the tokens described in the TOKENS section and environment variables as @@ -956,8 +979,8 @@ DESCRIPTION Specifies one or more jump proxies as either [user@]host[:port] or an ssh URI. Multiple proxies may be separated by comma characters and will be visited sequentially. Setting this option - will cause ssh(1) to connect to the target host by first making a - ssh(1) connection to the specified ProxyJump host and then + will cause ssh(1) to connect to the target host by first making + an ssh(1) connection to the specified ProxyJump host and then establishing a TCP forwarding to the ultimate target from there. Setting the host to none disables this option entirely. @@ -1012,6 +1035,14 @@ DESCRIPTION OpenSSH host-bound authentication protocol extension required for restricted ssh-agent(1) forwarding. + RefuseConnection + Allows a connection to be refused by the configuration file. If + this option is specified, then ssh(1) will terminate immediately + before attempting to connect to the remote host, display an error + message that contains the argument to this keyword and return a + non-zero exit status. This option may be useful to express + reminders or warnings to the user via ssh_config. + RekeyLimit Specifies the maximum amount of data that may be transmitted or received before the session key is renegotiated, optionally @@ -1034,27 +1065,34 @@ DESCRIPTION the TOKENS section. 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 - [bind_address:]port or, if the remote host supports it, a Unix - domain socket path. If forwarding to a specific destination then - the second argument must be host:hostport or a Unix domain socket - path, otherwise if no destination argument is specified then the - remote forwarding will be established as a SOCKS proxy. When - acting as a SOCKS proxy, the destination of the connection can be - restricted by PermitRemoteOpen. + Specifies that a TCP port or Unix-domain socket on the remote + machine be forwarded over the secure channel. The remote port + may either be forwarded to a specified host and port or Unix- + domain socket 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 [bind_address:]port or, if the + remote host supports it, a Unix domain socket path. If + forwarding to a specific destination then the second argument + must be host:hostport or a Unix domain socket path, otherwise if + no destination argument is specified then the remote forwarding + will be established as a SOCKS proxy. When acting as a SOCKS + proxy, the destination of the connection can be restricted by + PermitRemoteOpen. IPv6 addresses can be specified by enclosing addresses in square - brackets. Multiple forwardings may be specified, and additional - 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 TOKENS section and environment variables as described in - the ENVIRONMENT VARIABLES section. + brackets. + + If either argument contains a '/' in it, that argument will be + interpreted as a Unix-domain socket (on the corresponding host) + rather than a TCP port. + + 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 + TOKENS section and environment variables as described in the + ENVIRONMENT VARIABLES section. If the port argument is 0, the listen port will be dynamically allocated on the server and reported to the client at run time. @@ -1154,9 +1192,13 @@ DESCRIPTION execution). SetEnv Directly specify one or more environment variables and their - contents to be sent to the server. Similarly to SendEnv, with - the exception of the TERM variable, the server must be prepared - to accept the environment variable. + contents to be sent to the server in the form M-bM-^@M-^\NAME=VALUEM-bM-^@M-^]. + Similarly to SendEnv, with the exception of the TERM variable, + the server must be prepared to accept the environment variable. + + The M-bM-^@M-^\VALUEM-bM-^@M-^] may use the tokens described in the TOKENS section + and environment variables as described in the ENVIRONMENT + VARIABLES section. StdinNull Redirects stdin from /dev/null (actually, prevents reading from @@ -1275,7 +1317,10 @@ DESCRIPTION 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. + command line. Arguments to User may use the tokens described in + the TOKENS section (with the exception of %r and %C) and + environment variables as described in the ENVIRONMENT VARIABLES + section. UserKnownHostsFile Specifies one or more files to use for the user host key @@ -1298,6 +1343,11 @@ DESCRIPTION See also VERIFYING HOST KEYS in ssh(1). + VersionAddendum + Optionally specifies additional text to append to the SSH + protocol banner sent by the client upon connection. The default + is none. + VisualHostKey If this flag is set to yes, an ASCII art representation of the remote host key fingerprint is printed in addition to the @@ -1306,6 +1356,15 @@ DESCRIPTION printed at login and only the fingerprint string will be printed for unknown host keys. + WarnWeakCrypto + controls whether the user is warned when the cryptographic + algorithms negotiated for the connection are weak or otherwise + recommended against. Warnings may be disabled by turning off a + specific warning or by disabling all warnings. Warnings about + connections that don't use a post-quantum key exchange may be + disabled using the no-pq-kex flag. no will disable all warnings. + The default, equivalent to yes, is to enable all warnings. + XAuthLocation Specifies the full pathname of the xauth(1) program. The default is /usr/X11R6/bin/xauth. @@ -1377,8 +1436,8 @@ TOKENS CertificateFile, ControlPath, IdentityAgent, IdentityFile, Include, KnownHostsCommand, LocalForward, Match exec, RemoteCommand, - RemoteForward, RevokedHostKeys, and UserKnownHostsFile accept the tokens - %%, %C, %d, %h, %i, %j, %k, %L, %l, %n, %p, %r, and %u. + RemoteForward, RevokedHostKeys, UserKnownHostsFile and VersionAddendum + accept the tokens %%, %C, %d, %h, %i, %j, %k, %L, %l, %n, %p, %r, and %u. KnownHostsCommand additionally accepts the tokens %f, %H, %I, %K and %t. @@ -1430,4 +1489,4 @@ AUTHORS created OpenSSH. Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. -OpenBSD 7.6 September 9, 2024 OpenBSD 7.6 +OpenBSD 7.7 October 4, 2025 OpenBSD 7.7 diff --git a/ssh_config.5 b/ssh_config.5 index 7c7c5c5..f7066cb 100644 --- a/ssh_config.5 +++ b/ssh_config.5 @@ -33,8 +33,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: ssh_config.5,v 1.402 2024/09/09 14:41:21 naddy Exp $ -.Dd $Mdocdate: September 9 2024 $ +.\" $OpenBSD: ssh_config.5,v 1.420 2025/10/04 21:41:35 naddy Exp $ +.Dd $Mdocdate: October 4 2025 $ .Dt SSH_CONFIG 5 .Os .Sh NAME @@ -145,9 +145,11 @@ The available criteria keywords are: .Cm host , .Cm originalhost , .Cm tagged , +.Cm command , .Cm user , +.Cm localuser , and -.Cm localuser . +.Cm version . The .Cm all criteria must appear alone or immediately after @@ -212,6 +214,7 @@ 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. +.Pp The criteria for the .Cm host keyword are matched against the target hostname, after any substitution @@ -223,6 +226,7 @@ options. The .Cm originalhost keyword matches against the hostname as it was specified on the command-line. +.Pp The .Cm tagged keyword matches a tag name specified by a prior @@ -233,6 +237,22 @@ command-line using the .Fl P flag. The +.Cm command +keyword matches the remote command that has been requested, or the subsystem +name that is being invoked (e.g.\& +.Qq sftp +for an SFTP session). +The empty string will match the case where a command or tag has not been +specified, i.e.\& +.Sq Match tag \&"\&" . +The +.Cm version +keyword matches against the version string of +.Xr ssh 1 , +for example +.Dq OpenSSH_10.0 . +.Pp +The .Cm user keyword matches against the target username on the remote host. The @@ -242,6 +262,24 @@ keyword matches against the name of the local user running (this keyword may be useful in system-wide .Nm files). +.Pp +Finally, the +.Cm sessiontype +keyword matches the requested session type, which may be one of +.Cm shell +for interactive sessions, +.Cm exec +for command execution sessions, +.Cm subsystem +for subsystem invocations such as +.Xr sftp 1 , +or +.Cm none +for transport-only sessions, such as when +.Xr ssh 1 +is started with the +.Fl N +flag. .It Cm AddKeysToAgent Specifies whether keys should be automatically added to a running .Xr ssh-agent 1 . @@ -494,7 +532,7 @@ 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 +been established from an .Xr ssh 1 local forwarding, i.e.\& .Cm LocalForward @@ -502,9 +540,9 @@ 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 +established to an .Xr sshd 8 -listening on behalf of a +listening on behalf of an .Xr ssh 1 remote forwarding, i.e.\& .Cm RemoteForward . @@ -581,8 +619,8 @@ chacha20-poly1305@openssh.com 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 +aes128-gcm@openssh.com,aes256-gcm@openssh.com, +aes128-ctr,aes192-ctr,aes256-ctr .Ed .Pp The list of available ciphers may also be obtained using @@ -1204,7 +1242,9 @@ or block to perform conditional inclusion. .It Cm IPQoS -Specifies the IPv4 type-of-service or DSCP class for connections. +Specifies the +.Em Differentiated Services Field Codepoint Pq DSCP +value for connections. Accepted values are .Cm af11 , .Cm af12 , @@ -1228,9 +1268,6 @@ Accepted values are .Cm cs7 , .Cm ef , .Cm le , -.Cm lowdelay , -.Cm throughput , -.Cm reliability , a numeric value, or .Cm none to use the operating system default. @@ -1239,11 +1276,11 @@ 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) +.Cm ef +(Expedited Forwarding) for interactive sessions and -.Cm cs1 -(Lower Effort) +.Cm none +(the operating system default) for non-interactive sessions. .It Cm KbdInteractiveAuthentication Specifies whether to use keyboard-interactive authentication. @@ -1286,8 +1323,8 @@ default set. .Pp The default is: .Bd -literal -offset indent -sntrup761x25519-sha512,sntrup761x25519-sha512@openssh.com, mlkem768x25519-sha256, +sntrup761x25519-sha512,sntrup761x25519-sha512@openssh.com, curve25519-sha256,curve25519-sha256@libssh.org, ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521, diffie-hellman-group-exchange-sha256, @@ -1344,9 +1381,11 @@ 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 +Specifies that a TCP port or Unix-domain socket on the local machine +be forwarded over +the secure channel to the specified host and port (or Unix-domain socket) +from the remote machine. +For a TCP port, the first argument must be .Sm off .Oo Ar bind_address : Oc Ar port .Sm on @@ -1356,6 +1395,11 @@ The second argument is the destination and may be or a Unix domain socket path if the remote host supports it. .Pp IPv6 addresses can be specified by enclosing addresses in square brackets. +.Pp +If either argument contains a '/' in it, that argument will be +interpreted as a Unix-domain socket (on the corresponding host) rather +than a TCP port. +.Pp Multiple forwardings may be specified, and additional forwardings can be given on the command line. Only the superuser can forward privileged ports. @@ -1584,19 +1628,17 @@ 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 . +or an ssh URI. 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 +to connect to the target host by first making an .Xr ssh 1 connection to the specified .Cm ProxyJump @@ -1672,6 +1714,15 @@ disabling or enabling the OpenSSH host-bound authentication protocol extension required for restricted .Xr ssh-agent 1 forwarding. +.It Cm RefuseConnection +Allows a connection to be refused by the configuration file. +If this option is specified, then +.Xr ssh 1 +will terminate immediately before attempting to connect to the remote +host, display an error message that contains the argument to this keyword +and return a non-zero exit status. +This option may be useful to express reminders or warnings to the user via +.Nm . .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 @@ -1707,9 +1758,10 @@ 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. +Specifies that a TCP port or Unix-domain socket on the remote machine +be forwarded over the secure channel. The remote port may either be forwarded to a specified host and port +or Unix-domain socket 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 @@ -1727,6 +1779,11 @@ restricted by .Cm PermitRemoteOpen . .Pp IPv6 addresses can be specified by enclosing addresses in square brackets. +.Pp +If either argument contains a '/' in it, that argument will be +interpreted as a Unix-domain socket (on the corresponding host) rather +than a TCP port. +.Pp Multiple forwardings may be specified, and additional forwardings can be given on the command line. Privileged ports can be forwarded only when @@ -1894,12 +1951,21 @@ option) or (shell or command execution). .It Cm SetEnv Directly specify one or more environment variables and their contents to -be sent to the server. +be sent to the server in the form +.Dq NAME=VALUE . Similarly to .Cm SendEnv , with the exception of the .Ev TERM variable, the server must be prepared to accept the environment variable. +.Pp +The +.Dq VALUE +may use the tokens described in the +.Sx TOKENS +section and environment variables as described in the +.Sx ENVIRONMENT VARIABLES +section. .It Cm StdinNull Redirects stdin from .Pa /dev/null @@ -2099,6 +2165,15 @@ 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. +Arguments to +.Cm User +may use the tokens described in the +.Sx TOKENS +section +(with the exception of %r and %C) +and environment variables as described in the +.Sx ENVIRONMENT VARIABLES +section. .It Cm UserKnownHostsFile Specifies one or more files to use for the user host key database, separated by whitespace. @@ -2138,6 +2213,11 @@ See also .Sx VERIFYING HOST KEYS in .Xr ssh 1 . +.It Cm VersionAddendum +Optionally specifies additional text to append to the SSH protocol banner +sent by the client upon connection. +The default is +.Cm none . .It Cm VisualHostKey If this flag is set to .Cm yes , @@ -2149,6 +2229,20 @@ If this flag is set to (the default), no fingerprint strings are printed at login and only the fingerprint string will be printed for unknown host keys. +.It Cm WarnWeakCrypto +controls whether the user is warned when the cryptographic algorithms +negotiated for the connection are weak or otherwise recommended against. +Warnings may be disabled by turning off a specific warning or by disabling +all warnings. +Warnings about connections that don't use a post-quantum key exchange +may be disabled using the +.Cm no-pq-kex +flag. +.Cm no +will disable all warnings. +The default, equivalent to +.Cm yes , +is to enable all warnings. .It Cm XAuthLocation Specifies the full pathname of the .Xr xauth 1 @@ -2283,8 +2377,9 @@ The local username. .Cm RemoteCommand , .Cm RemoteForward , .Cm RevokedHostKeys , -and .Cm UserKnownHostsFile +and +.Cm VersionAddendum accept the tokens %%, %C, %d, %h, %i, %j, %k, %L, %l, %n, %p, %r, and %u. .Pp .Cm KnownHostsCommand diff --git a/sshbuf-getput-basic.c b/sshbuf-getput-basic.c index 5c71b0e..2cc562b 100644 --- a/sshbuf-getput-basic.c +++ b/sshbuf-getput-basic.c @@ -24,9 +24,7 @@ #include #include #include -#ifdef HAVE_STDINT_H -# include -#endif +#include #include "ssherr.h" #include "sshbuf.h" diff --git a/sshbuf-misc.c b/sshbuf-misc.c index 9c5c42b..7b11e4e 100644 --- a/sshbuf-misc.c +++ b/sshbuf-misc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshbuf-misc.c,v 1.18 2022/01/22 00:43:43 djm Exp $ */ +/* $OpenBSD: sshbuf-misc.c,v 1.22 2025/09/04 00:32:31 djm Exp $ */ /* * Copyright (c) 2011 Damien Miller * @@ -22,9 +22,7 @@ #include #include #include -#ifdef HAVE_STDINT_H -# include -#endif +#include #include #include #include @@ -71,7 +69,7 @@ sshbuf_dump(const struct sshbuf *buf, FILE *f) } char * -sshbuf_dtob16(struct sshbuf *buf) +sshbuf_dtob16(const struct sshbuf *buf) { size_t i, j, len = sshbuf_len(buf); const u_char *p = sshbuf_ptr(buf); @@ -90,6 +88,42 @@ sshbuf_dtob16(struct sshbuf *buf) return ret; } +static int +b16tod(const char v) +{ + if (v >= '0' && v <= '9') + return v - '0'; + if (v >= 'a' && v <= 'f') + return 10 + v - 'a'; + if (v >= 'A' && v <= 'A') + return 10 + v - 'A'; + return -1; +} + +struct sshbuf * +sshbuf_b16tod(const char *b16) +{ + struct sshbuf *ret; + size_t o; + int r, v1, v2; + + if ((ret = sshbuf_new()) == NULL) + return NULL; + for (o = 0; b16[o] != '\0'; o += 2) { + if ((v1 = b16tod(b16[o])) == -1 || + (v2 = b16tod(b16[o + 1])) == -1) { + sshbuf_free(ret); + return NULL; + } + if ((r = sshbuf_put_u8(ret, (u_char)((v1 << 4) | v2))) != 0) { + sshbuf_free(ret); + return NULL; + } + } + /* success */ + return ret; +} + int sshbuf_dtob64(const struct sshbuf *d, struct sshbuf *b64, int wrap) { @@ -176,6 +210,9 @@ sshbuf_dtourlb64(const struct sshbuf *d, struct sshbuf *b64, int wrap) struct sshbuf *b = NULL; size_t i, l; + if (sshbuf_len(d) == 0) + return 0; + if ((b = sshbuf_new()) == NULL) return SSH_ERR_ALLOC_FAIL; /* Encode using regular base64; we'll transform it once done */ @@ -218,7 +255,7 @@ sshbuf_dup_string(struct sshbuf *buf) size_t l = sshbuf_len(buf); char *r; - if (s == NULL || l > SIZE_MAX) + if (s == NULL || l >= SIZE_MAX) return NULL; /* accept a nul only as the last character in the buffer */ if (l > 0 && (p = memchr(s, '\0', l)) != NULL) { @@ -249,6 +286,20 @@ sshbuf_cmp(const struct sshbuf *b, size_t offset, return 0; } +int +sshbuf_equals(const struct sshbuf *a, const struct sshbuf *b) +{ + if (sshbuf_ptr(a) == NULL || sshbuf_ptr(b) == NULL) + return SSH_ERR_INTERNAL_ERROR; + if (sshbuf_len(a) != sshbuf_len(b)) + return SSH_ERR_MESSAGE_INCOMPLETE; + if (sshbuf_len(a) == 0) + return 0; + if (memcmp(sshbuf_ptr(a), sshbuf_ptr(b), sshbuf_len(a)) != 0) + return SSH_ERR_INVALID_FORMAT; + return 0; +} + int sshbuf_find(const struct sshbuf *b, size_t start_offset, const void *s, size_t len, size_t *offsetp) diff --git a/sshbuf.h b/sshbuf.h index 49c32af..0c82f12 100644 --- a/sshbuf.h +++ b/sshbuf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sshbuf.h,v 1.29 2024/08/15 00:51:51 djm Exp $ */ +/* $OpenBSD: sshbuf.h,v 1.32 2025/09/02 09:41:23 djm Exp $ */ /* * Copyright (c) 2011 Damien Miller * @@ -61,7 +61,8 @@ struct sshbuf *sshbuf_fromb(struct sshbuf *buf); * 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. + * On success, a pointer to the newly allocated buffer is placed in *bufp. + * Returns 0 on success, or a negative SSH_ERR_* error code on failure. */ int sshbuf_froms(struct sshbuf *buf, struct sshbuf **bufp); @@ -235,7 +236,9 @@ void sshbuf_dump(const struct sshbuf *buf, FILE *f); 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); +char *sshbuf_dtob16(const struct sshbuf *buf); +/* Make a sshbuf from a hex string */ +struct sshbuf *sshbuf_b16tod(const char *b16); /* Encode the contents of the buffer as base64 */ char *sshbuf_dtob64_string(const struct sshbuf *buf, int wrap); @@ -261,6 +264,15 @@ int sshbuf_b64tod(struct sshbuf *buf, const char *b64); int sshbuf_cmp(const struct sshbuf *b, size_t offset, const void *s, size_t len); +/* + * Test whether two buffers have identical contents. + * SSH_ERR_MESSAGE_INCOMPLETE indicates the buffers had differing size. + * SSH_ERR_INVALID_FORMAT indicates the buffers were the same size but + * had differing contents. + * Returns 0 on successful compare (comparing two empty buffers returns 0). + */ +int sshbuf_equals(const struct sshbuf *a, const struct sshbuf *b); + /* * Searches the buffer for the specified string. Returns 0 on success * and updates *offsetp with the offset of the first match, relative to diff --git a/sshconnect.c b/sshconnect.c index 7cf6b63..912a520 100644 --- a/sshconnect.c +++ b/sshconnect.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect.c,v 1.368 2024/04/30 02:10:49 djm Exp $ */ +/* $OpenBSD: sshconnect.c,v 1.376 2025/09/25 06:23:19 jsg Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -19,9 +19,7 @@ #include #include #include -#ifdef HAVE_SYS_TIME_H -# include -#endif +#include #include #include @@ -32,22 +30,16 @@ #include #include #include -#ifdef HAVE_PATHS_H #include -#endif #include -#ifdef HAVE_POLL_H #include -#endif #include #include #include #include #include #include -#ifdef HAVE_IFADDRS_H -# include -#endif +#include #include "xmalloc.h" #include "hostfile.h" @@ -797,7 +789,7 @@ hostkeys_find_by_key(const char *host, const char *ip, const struct sshkey *key, char **system_hostfiles, u_int num_system_hostfiles, char ***names, u_int *nnames) { - struct find_by_key_ctx ctx = {0, 0, 0, 0, 0}; + struct find_by_key_ctx ctx = {NULL, NULL, NULL, NULL, 0}; u_int i; *names = NULL; @@ -1145,7 +1137,7 @@ check_host_key(char *hostname, const struct ssh_conn_info *cinfo, 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); + logit("Host key fingerprint is: %s\n%s", fp, ra); free(ra); free(fp); } @@ -1196,7 +1188,7 @@ check_host_key(char *hostname, const struct ssh_conn_info *cinfo, options.fingerprint_hash, SSH_FP_RANDOMART); if (fp == NULL || ra == NULL) fatal_f("sshkey_fingerprint failed"); - xextendf(&msg1, "\n", "%s key fingerprint is %s.", + xextendf(&msg1, "\n", "%s key fingerprint is: %s", type, fp); if (options.visual_host_key) xextendf(&msg1, "\n", "%s", ra); @@ -1434,6 +1426,7 @@ check_host_key(char *hostname, const struct ssh_conn_info *cinfo, options.update_hostkeys = 0; } + sshkey_free(raw_key); free(ip); free(host); if (host_hostkeys != NULL) @@ -1580,6 +1573,14 @@ verify_host_key(char *host, struct sockaddr *hostaddr, struct sshkey *host_key, return r; } +static void +warn_nonpq_kex(void) +{ + logit("** WARNING: connection is not using a post-quantum key exchange algorithm."); + logit("** This session may be vulnerable to \"store now, decrypt later\" attacks."); + logit("** The server may need to be upgraded. See https://openssh.com/pq.html"); +} + /* * Starts a dialog with the server, and authenticates the current user on the * server. This does not need any extra privileges. The basic connection @@ -1604,7 +1605,8 @@ ssh_login(struct ssh *ssh, Sensitive *sensitive, const char *orighost, lowercase(host); /* Exchange protocol version identification strings with the server. */ - if ((r = kex_exchange_identification(ssh, timeout_ms, NULL)) != 0) + 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. */ @@ -1614,6 +1616,10 @@ ssh_login(struct ssh *ssh, Sensitive *sensitive, const char *orighost, /* authenticate user */ debug("Authenticating to %s:%d as '%s'", host, port, server_user); ssh_kex2(ssh, host, hostaddr, port, cinfo); + if (!options.kex_algorithms_set && ssh->kex != NULL && + ssh->kex->name != NULL && options.warn_weak_crypto && + !kex_is_pq_from_name(ssh->kex->name)) + warn_nonpq_kex(); ssh_userauth2(ssh, local_user, server_user, host, sensitive); free(local_user); free(host); @@ -1625,12 +1631,8 @@ show_other_keys(struct hostkeys *hostkeys, struct sshkey *key) { int type[] = { KEY_RSA, -#ifdef WITH_DSA - KEY_DSA, -#endif KEY_ECDSA, KEY_ED25519, - KEY_XMSS, -1 }; int i, ret = 0; @@ -1753,7 +1755,7 @@ maybe_add_key_to_agent(const char *authfile, struct sshkey *private, 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) + (options.add_keys_to_agent == 3), skprovider, NULL, 0)) == 0) debug("identity added to agent: %s", authfile); else debug("could not add identity to agent: %s (%d)", authfile, r); diff --git a/sshconnect.h b/sshconnect.h index 8b0466f..3082701 100644 --- a/sshconnect.h +++ b/sshconnect.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect.h,v 1.48 2024/04/30 02:10:49 djm Exp $ */ +/* $OpenBSD: sshconnect.h,v 1.49 2025/03/01 06:11:26 dtucker Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. @@ -52,9 +52,8 @@ struct ssh; struct hostkeys; struct ssh_conn_info; -/* default argument for client percent expansions */ -#define DEFAULT_CLIENT_PERCENT_EXPAND_ARGS(conn_info) \ - "C", conn_info->conn_hash_hex, \ +/* default argument for client percent expansions, minus remote user */ +#define DEFAULT_CLIENT_PERCENT_EXPAND_ARGS_NOUSER(conn_info) \ "L", conn_info->shorthost, \ "i", conn_info->uidstr, \ "k", conn_info->keyalias, \ @@ -63,10 +62,15 @@ struct ssh_conn_info; "p", conn_info->portstr, \ "d", conn_info->homedir, \ "h", conn_info->remhost, \ - "r", conn_info->remuser, \ "u", conn_info->locuser, \ "j", conn_info->jmphost +/* same plus remote user and hash which has user as a component */ +#define DEFAULT_CLIENT_PERCENT_EXPAND_ARGS(conn_info) \ + DEFAULT_CLIENT_PERCENT_EXPAND_ARGS_NOUSER(conn_info), \ + "C", conn_info->conn_hash_hex, \ + "r", conn_info->remuser + int ssh_connect(struct ssh *, const char *, const char *, struct addrinfo *, struct sockaddr_storage *, u_short, int, int *, int); diff --git a/sshconnect2.c b/sshconnect2.c index 86f1fb0..b3679c9 100644 --- a/sshconnect2.c +++ b/sshconnect2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect2.c,v 1.375 2024/09/09 02:39:57 djm Exp $ */ +/* $OpenBSD: sshconnect2.c,v 1.378 2025/09/15 04:51:35 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2008 Damien Miller. All rights reserved. @@ -1815,7 +1815,7 @@ pubkey_prepare(struct ssh *ssh, Authctxt *authctxt) TAILQ_REMOVE(preferred, id, next); sshkey_free(id->key); free(id->filename); - memset(id, 0, sizeof(*id)); + freezero(id, sizeof(*id)); } /* List the keys we plan on using */ TAILQ_FOREACH_SAFE(id, preferred, next, id2) { @@ -1888,10 +1888,8 @@ userauth_pubkey(struct ssh *ssh) debug("Trying private key: %s", id->filename); id->key = load_identity_file(id); if (id->key != NULL) { - if (id->key != NULL) { - id->isprivate = 1; - sent = sign_and_send_pubkey(ssh, id); - } + id->isprivate = 1; + sent = sign_and_send_pubkey(ssh, id); sshkey_free(id->key); id->key = NULL; id->isprivate = 0; diff --git a/sshd-auth.c b/sshd-auth.c new file mode 100644 index 0000000..9c31515 --- /dev/null +++ b/sshd-auth.c @@ -0,0 +1,867 @@ +/* $OpenBSD: sshd-auth.c,v 1.9 2025/09/15 04:52:12 djm Exp $ */ +/* + * 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 +#include +#include +#include +#include +#include + +#include "openbsd-compat/sys-tree.h" +#include "openbsd-compat/sys-queue.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef WITH_OPENSSL +#include +#include +#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 "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 "auth-options.h" +#include "version.h" +#include "ssherr.h" +#include "sk-api.h" +#include "srclimit.h" +#include "ssh-sandbox.h" +#include "dh.h" + +/* Privsep fds */ +#define PRIVSEP_MONITOR_FD (STDERR_FILENO + 1) +#define PRIVSEP_LOG_FD (STDERR_FILENO + 2) +#define PRIVSEP_MIN_FREE_FD (STDERR_FILENO + 3) + +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; + +/* Flag indicating that the daemon is being started from inetd. */ +static int inetd_flag = 0; + +/* Saved arguments to main(). */ +static char **saved_argv; +static int saved_argc; + + +/* Daemon's agent connection */ +int auth_sock = -1; +static int have_agent = 0; + +u_int num_hostkeys; +struct sshkey **host_pubkeys; /* all public host keys */ +struct sshkey **host_certificates; /* all public host certificates */ + +/* record remote hostname or ip */ +u_int utmp_len = HOST_NAME_MAX+1; + +/* variables used for privilege separation */ +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; + +/* Prototypes for various functions defined later in this file. */ +static void do_ssh2_kex(struct ssh *); + +/* Unprivileged user */ +struct passwd *privsep_pw = NULL; + +#ifndef HAVE_PLEDGE +static struct ssh_sandbox *box; +#endif + +/* XXX stub */ +int +mm_is_monitor(void) +{ + return 0; +} + +static void +privsep_child_demote(void) +{ + gid_t gidset[1]; + +#ifndef HAVE_PLEDGE + if ((box = ssh_sandbox_init(pmonitor)) == NULL) + fatal_f("ssh_sandbox_init failed"); +#endif + /* 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 + * NB. Can't use setusercontext() after chroot. + */ + 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); + } + + /* sandbox ourselves */ +#ifdef HAVE_PLEDGE + if (pledge("stdio", NULL) == -1) + fatal_f("pledge()"); +#else + ssh_sandbox_child(box); +#endif +} + +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 = 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_ECDSA: + case KEY_ED25519: + case KEY_ECDSA_SK: + case KEY_ED25519_SK: + append_hostkey_type(b, sshkey_ssh_name(key)); + break; + } + /* If the private key has a cert peer, then list that too */ + key = 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_ECDSA_CERT: + case KEY_ED25519_CERT: + case KEY_ECDSA_SK_CERT: + case KEY_ED25519_SK_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; +} + +struct sshkey * +get_hostkey_public_by_type(int type, int nid, 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_ECDSA_CERT: + case KEY_ED25519_CERT: + case KEY_ECDSA_SK_CERT: + case KEY_ED25519_SK_CERT: + key = host_certificates[i]; + break; + default: + key = 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 key; + } + } + return NULL; +} + +/* XXX remove */ +struct sshkey * +get_hostkey_private_by_type(int type, int nid, struct ssh *ssh) +{ + return NULL; +} + +/* XXX remove */ +struct sshkey * +get_hostkey_by_index(int ind) +{ + return NULL; +} + +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 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 == host_certificates[i] || + (compare && host_certificates[i] && + sshkey_equal(key, host_certificates[i]))) + return (i); + } else { + if (key == host_pubkeys[i] || + (compare && host_pubkeys[i] && + sshkey_equal(key, host_pubkeys[i]))) + return (i); + } + } + return (-1); +} + +static void +usage(void) +{ + fprintf(stderr, "%s, %s\n", SSH_VERSION, SSH_OPENSSL_VERSION); + fprintf(stderr, +"usage: sshd [-46DdeGiqTtV] [-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 +parse_hostkeys(struct sshbuf *hostkeys) +{ + int r; + u_int num_keys = 0; + struct sshkey *k; + const u_char *cp; + size_t len; + + while (sshbuf_len(hostkeys) != 0) { + if (num_keys > 2048) + fatal_f("too many hostkeys"); + host_pubkeys = xrecallocarray(host_pubkeys, + num_keys, num_keys + 1, sizeof(*host_pubkeys)); + host_certificates = xrecallocarray(host_certificates, + num_keys, num_keys + 1, sizeof(*host_certificates)); + /* public key */ + k = NULL; + if ((r = sshbuf_get_string_direct(hostkeys, &cp, &len)) != 0) + fatal_fr(r, "extract pubkey"); + if (len != 0 && (r = sshkey_from_blob(cp, len, &k)) != 0) + fatal_fr(r, "parse pubkey"); + host_pubkeys[num_keys] = k; + if (k) + debug2_f("key %u: %s", num_keys, sshkey_ssh_name(k)); + /* certificate */ + k = NULL; + if ((r = sshbuf_get_string_direct(hostkeys, &cp, &len)) != 0) + fatal_fr(r, "extract pubkey"); + if (len != 0 && (r = sshkey_from_blob(cp, len, &k)) != 0) + fatal_fr(r, "parse pubkey"); + host_certificates[num_keys] = k; + if (k) + debug2_f("cert %u: %s", num_keys, sshkey_ssh_name(k)); + num_keys++; + } + num_hostkeys = num_keys; +} + +static void +recv_privsep_state(struct ssh *ssh, struct sshbuf *conf, + uint64_t *timing_secretp) +{ + struct sshbuf *hostkeys; + + debug3_f("begin"); + + mm_get_state(ssh, &includes, conf, NULL, timing_secretp, + &hostkeys, NULL, NULL, NULL, NULL); + parse_hostkeys(hostkeys); + + sshbuf_free(hostkeys); + + debug3_f("done"); +} + +/* + * Main program for the daemon. + */ +int +main(int ac, char **av) +{ + struct ssh *ssh = NULL; + extern char *optarg; + extern int optind; + int r, opt, have_key = 0; + int sock_in = -1, sock_out = -1, rexeced_flag = 0; + char *line; + u_int i; + mode_t new_umask; + Authctxt *authctxt; + struct connection_info *connection_info = NULL; + sigset_t sigmask; + uint64_t timing_secret = 0; + + closefrom(PRIVSEP_MIN_FREE_FD); + sigemptyset(&sigmask); + sigprocmask(SIG_SETMASK, &sigmask, NULL); + +#ifdef HAVE_SECUREWARE + (void)set_auth_parameters(ac, av); +#endif + __progname = ssh_get_progname(av[0]); + + /* Save argv. Duplicate so setproctitle emulation doesn't clobber it */ + saved_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; + + seed_rng(); + +#ifndef HAVE_SETPROCTITLE + /* Prepare for later setproctitle emulation */ + compat_init_setproctitle(ac, av); + av = saved_argv; +#endif + + /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ + sanitise_stdfd(); + + /* 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:46DGQRTdeiqrtV")) != -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': + case 'E': + case 'e': + /* ignore */ + break; + case 'i': + inetd_flag = 1; + break; + case 'r': + /* ignore */ + break; + case 'R': + rexeced_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': + case 'T': + case 'G': + fatal("test/dump modes not supported"); + break; + case 'C': + connection_info = server_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 'V': + fprintf(stderr, "%s, %s\n", + SSH_VERSION, SSH_OPENSSL_VERSION); + exit(0); + default: + usage(); + break; + } + } + + if (!rexeced_flag) + fatal("sshd-auth should not be executed directly"); + +#ifdef WITH_OPENSSL + OpenSSL_add_all_algorithms(); +#endif + + 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, 1); + + /* XXX can't use monitor_init(); it makes fds */ + pmonitor = xcalloc(1, sizeof(*pmonitor)); + pmonitor->m_sendfd = pmonitor->m_log_recvfd = -1; + pmonitor->m_recvfd = PRIVSEP_MONITOR_FD; + pmonitor->m_log_sendfd = PRIVSEP_LOG_FD; + set_log_handler(mm_log_handler, pmonitor); + + /* Check that there are no remaining arguments. */ + if (optind < ac) { + fprintf(stderr, "Extra argument %s.\n", av[optind]); + exit(1); + } + + /* Connection passed by stdin/out */ + if (inetd_flag) { + /* + * NB. must be different fd numbers for the !socket case, + * as packet_connection_is_on_socket() depends on this. + */ + sock_in = dup(STDIN_FILENO); + sock_out = dup(STDOUT_FILENO); + } else { + /* rexec case; accept()ed socket in ancestor listener */ + sock_in = sock_out = dup(STDIN_FILENO); + } + + if (stdfd_devnull(1, 1, 0) == -1) + error("stdfd_devnull failed"); + debug("network sockets: %d, %d", sock_in, sock_out); + + /* + * 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); + pmonitor->m_pkex = &ssh->kex; + + /* Fetch our configuration */ + if ((cfg = sshbuf_new()) == NULL) + fatal("sshbuf_new config buf failed"); + setproctitle("%s", "[session-auth early]"); + recv_privsep_state(ssh, cfg, &timing_secret); + parse_server_config(&options, "rexec", cfg, &includes, NULL, 1); + /* Fill in default values for those options not explicitly set. */ + fill_default_server_options(&options); + options.timing_secret = timing_secret; /* XXX eliminate from unpriv */ + ssh_packet_set_qos(ssh, options.ip_qos_interactive, + options.ip_qos_bulk); + + /* Reinit logging in case config set Level, Facility or Verbose. */ + log_init(__progname, options.log_level, options.log_facility, 1); + set_log_handler(mm_log_handler, pmonitor); + + debug("sshd-auth version %s, %s", SSH_VERSION, SSH_OPENSSL_VERSION); + + /* Store privilege separation user for later use if required. */ + privsep_chroot = (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(); + +#ifdef WITH_OPENSSL + if (options.moduli_file != NULL) + dh_set_moduli_file(options.moduli_file); +#endif + + 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); + } + + if (options.num_host_key_files != num_hostkeys) { + fatal("internal error: hostkeys confused (config %u recvd %u)", + options.num_host_key_files, num_hostkeys); + } + + for (i = 0; i < options.num_host_key_files; i++) { + if (host_pubkeys[i] != NULL) { + have_key = 1; + break; + } + } + if (!have_key) + fatal("internal error: received no hostkeys"); + + /* 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). */ + log_init(__progname, options.log_level, options.log_facility, 1); + set_log_handler(mm_log_handler, pmonitor); + for (i = 0; i < options.num_log_verbose; i++) + log_verbose_add(options.log_verbose[i]); + + /* + * Chdir to the root directory so that the current disk can be + * unmounted if desired. + */ + if (chdir("/") == -1) + error("chdir(\"/\"): %s", strerror(errno)); + + /* This is the child authenticating a new connection. */ + setproctitle("%s", "[session-auth]"); + + /* Executed child processes don't need these. */ + fcntl(sock_out, F_SETFD, FD_CLOEXEC); + fcntl(sock_in, F_SETFD, FD_CLOEXEC); + + ssh_signal(SIGPIPE, SIG_IGN); + 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); + + /* Prepare the channels layer */ + channel_init_channels(ssh); + channel_set_af(ssh, options.address_family); + server_process_channel_timeouts(ssh); + server_process_permitopen(ssh); + + ssh_packet_set_nonblocking(ssh); + + /* allocate authentication context */ + authctxt = xcalloc(1, sizeof(*authctxt)); + ssh->authctxt = authctxt; + + /* 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("sshbuf_new loginmsg failed"); + auth_debug_reset(); + + /* 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 + + privsep_child_demote(); + + /* perform the key exchange */ + /* authenticate user and start session */ + do_ssh2_kex(ssh); + do_authentication2(ssh); + + /* + * The unprivileged child now transfers the current keystate and exits. + */ + mm_send_keystate(ssh, pmonitor); + sshauthopt_free(auth_opts); + ssh_packet_clear_keys(ssh); + 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) +{ + 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"); + } + return 0; +} + +/* SSH2 key exchange */ +static void +do_ssh2_kex(struct ssh *ssh) +{ + char *hkalgs = NULL, *myproposal[PROPOSAL_MAX]; + const char *compression = NULL; + struct kex *kex; + int r; + + if (options.rekey_limit || options.rekey_interval) + ssh_packet_set_rekey_limits(ssh, options.rekey_limit, + options.rekey_interval); + + if (options.compression == COMP_NONE) + compression = "none"; + hkalgs = list_hostkey_types(); + + kex_proposal_populate_entries(ssh, myproposal, options.kex_algorithms, + options.ciphers, options.macs, compression, hkalgs); + + free(hkalgs); + + /* start key exchange */ + if ((r = kex_setup(ssh, myproposal)) != 0) + fatal_r(r, "kex_setup"); + kex_set_server_sig_algs(ssh, options.pubkey_accepted_algos); + 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 /* OPENSSL_HAS_ECC */ +#endif /* WITH_OPENSSL */ + kex->kex[KEX_C25519_SHA256] = kex_gen_server; + kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_server; + kex->kex[KEX_KEM_MLKEM768X25519_SHA256] = 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); + kex_proposal_free_entries(myproposal); + +#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 + debug("KEX done"); +} + +/* server specific fatal cleanup */ +void +cleanup_exit(int i) +{ + _exit(i); +} diff --git a/sshd-debug.sh b/sshd-debug.sh new file mode 100755 index 0000000..86a9b37 --- /dev/null +++ b/sshd-debug.sh @@ -0,0 +1,52 @@ +#!/bin/sh + +# ssh-debug + +# A wrapper script around sshd to invoke when debugging to debug the +# work-in-progress versions of sshd-auth and sshd-session, instead +# of debugging the installed ones that probably don't have the change +# you are working on. +# +# Placed in the Public Domain. + +unset DIR SSHD SSHD_AUTH SSHD_SESSION + +fatal() { + echo >&2 $@ + exit 1 +} + +case "$0" in +/*) DIR="`dirname $0`" ;; +./sshd-debug.sh) DIR="`pwd`" ;; +*) echo "Need full path or working directory."; exit 1 ;; +esac + +for i in sshd/obj/sshd sshd/sshd sshd; do + if [ -f "${DIR}/$i" ] && [ -x "${DIR}/$i" ]; then + SSHD="${DIR}/$i" + fi +done +[ -z "${SSHD}" ] && fatal "Could not find sshd" + +for i in sshd-auth/obj/sshd-auth sshd-auth/sshd-auth sshd-auth; do + if [ -f "${DIR}/$i" ] && [ -x "${DIR}/$i" ]; then + SSHD_AUTH="${DIR}/$i" + fi +done +[ -z "${SSHD_AUTH}" ] && fatal "Could not find sshd-auth" + +for i in sshd-session/obj/sshd-session sshd-session/sshd-session sshd-session; do + if [ -f "${DIR}/$i" ] && [ -x "${DIR}/$i" ]; then + SSHD_SESSION="${DIR}/$i" + fi +done +[ -z "${SSHD_SESSION}" ] && fatal "Could not find sshd-session" + +echo >&2 Debugging ${SSHD} auth ${SSHD_AUTH} session ${SSHD_SESSION} + +# Append SshdSessionPath and SshdAuthPath pointing to the build directory. +# If you explicitly specify these in the command line, the first-match +# keyword semantics will override these. +exec "${SSHD}" $@ \ + -oSshdAuthPath="${SSHD_AUTH}" -oSshdSessionPath="${SSHD_SESSION}" diff --git a/sshd-session.c b/sshd-session.c index 4b79b9b..8979f74 100644 --- a/sshd-session.c +++ b/sshd-session.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshd-session.c,v 1.9 2024/09/09 02:39:57 djm Exp $ */ +/* $OpenBSD: sshd-session.c,v 1.16 2025/09/25 06:45:50 djm Exp $ */ /* * SSH2 implementation: * Privilege Separation: @@ -32,12 +32,8 @@ #include #include #include -#ifdef HAVE_SYS_STAT_H -# include -#endif -#ifdef HAVE_SYS_TIME_H -# include -#endif +#include +#include #include "openbsd-compat/sys-tree.h" #include "openbsd-compat/sys-queue.h" #include @@ -45,9 +41,7 @@ #include #include #include -#ifdef HAVE_PATHS_H -# include -#endif +#include #include #include #include @@ -102,7 +96,6 @@ #include "ssh-gss.h" #endif #include "monitor_wrap.h" -#include "ssh-sandbox.h" #include "auth-options.h" #include "version.h" #include "ssherr.h" @@ -112,9 +105,13 @@ /* 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) +#define REEXEC_CONFIG_PASS_FD (STDERR_FILENO + 2) +#define REEXEC_MIN_FREE_FD (STDERR_FILENO + 3) + +/* Privsep fds */ +#define PRIVSEP_MONITOR_FD (STDERR_FILENO + 1) +#define PRIVSEP_LOG_FD (STDERR_FILENO + 2) +#define PRIVSEP_MIN_FREE_FD (STDERR_FILENO + 3) extern char *__progname; @@ -193,7 +190,17 @@ struct sshbuf *loginmsg; /* 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 *); + +/* XXX reduce to stub once postauth split */ +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); +} /* * Signal handler for the alarm after the login grace period has expired. @@ -277,66 +284,63 @@ reseed_prngs(void) 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__); + fatal_f("RAND_bytes failed"); #endif explicit_bzero(rnd, sizeof(rnd)); } -static void -privsep_preauth_child(void) +struct sshbuf * +pack_hostkeys(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(); + struct sshbuf *keybuf = NULL, *hostkeys = NULL; + int r; + u_int i; - /* Demote the private keys to public keys. */ - demote_sensitive_data(); + if ((hostkeys = sshbuf_new()) == NULL) + fatal_f("sshbuf_new failed"); - /* 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); + /* pack hostkeys into a string. Empty key slots get empty strings */ + for (i = 0; i < options.num_host_key_files; i++) { + /* public key */ + if (sensitive_data.host_pubkeys[i] != NULL) { + if ((r = sshkey_puts(sensitive_data.host_pubkeys[i], + hostkeys)) != 0) + fatal_fr(r, "compose hostkey public"); + } else { + if ((r = sshbuf_put_string(hostkeys, NULL, 0)) != 0) + fatal_fr(r, "compose hostkey empty public"); + } + /* cert */ + if (sensitive_data.host_certificates[i] != NULL) { + if ((r = sshkey_puts( + sensitive_data.host_certificates[i], + hostkeys)) != 0) + fatal_fr(r, "compose host cert"); + } else { + if ((r = sshbuf_put_string(hostkeys, NULL, 0)) != 0) + fatal_fr(r, "compose host cert empty"); + } } + + sshbuf_free(keybuf); + return hostkeys; } static int privsep_preauth(struct ssh *ssh) { - int status, r; + int 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; - box = ssh_sandbox_init(pmonitor); - pid = fork(); - if (pid == -1) { + if ((pid = fork()) == -1) fatal("fork of unprivileged child failed"); - } else if (pid != 0) { + else if (pid != 0) { debug2("Network child is on pid %ld", (long)pid); pmonitor->m_pid = pid; @@ -347,43 +351,48 @@ privsep_preauth(struct ssh *ssh) 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); + /* + * Arrange unpriv-preauth child process fds: + * 0, 1 network socket + * 2 optional stderr + * 3 reserved + * 4 monitor message socket + * 5 monitor logging socket + * + * We know that the monitor sockets will have fds > 4 because + * of the reserved fds in main() + */ - return 0; + if (ssh_packet_get_connection_in(ssh) != STDIN_FILENO && + dup2(ssh_packet_get_connection_in(ssh), STDIN_FILENO) == -1) + fatal("dup2 stdin failed: %s", strerror(errno)); + if (ssh_packet_get_connection_out(ssh) != STDOUT_FILENO && + dup2(ssh_packet_get_connection_out(ssh), + STDOUT_FILENO) == -1) + fatal("dup2 stdout failed: %s", strerror(errno)); + /* leave stderr as-is */ + log_redirect_stderr_to(NULL); /* dup can clobber log fd */ + if (pmonitor->m_recvfd != PRIVSEP_MONITOR_FD && + dup2(pmonitor->m_recvfd, PRIVSEP_MONITOR_FD) == -1) + fatal("dup2 monitor fd: %s", strerror(errno)); + if (pmonitor->m_log_sendfd != PRIVSEP_LOG_FD && + dup2(pmonitor->m_log_sendfd, PRIVSEP_LOG_FD) == -1) + fatal("dup2 log fd: %s", strerror(errno)); + closefrom(PRIVSEP_MIN_FREE_FD); + + saved_argv[0] = options.sshd_auth_path; + execv(options.sshd_auth_path, saved_argv); + + fatal_f("exec of %s failed: %s", + options.sshd_auth_path, strerror(errno)); } } @@ -445,79 +454,6 @@ privsep_postauth(struct ssh *ssh, Authctxt *authctxt) 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) { @@ -527,12 +463,10 @@ get_hostkey_by_type(int type, int nid, int need_private, struct ssh *ssh) 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: @@ -745,6 +679,8 @@ recv_rexec_state(int fd, struct sshbuf *conf, uint64_t *timing_secretp) if ((m = sshbuf_new()) == NULL || (inc = sshbuf_new()) == NULL) fatal_f("sshbuf_new failed"); + + /* receive config */ if (ssh_msg_recv(fd, m) == -1) fatal_f("ssh_msg_recv failed"); if ((r = sshbuf_get_u8(m, &ver)) != 0) @@ -753,7 +689,6 @@ recv_rexec_state(int fd, struct sshbuf *conf, uint64_t *timing_secretp) fatal_f("rexec version mismatch"); if ((r = sshbuf_get_string(m, &cp, &len)) != 0 || /* XXX _direct */ (r = sshbuf_get_u64(m, timing_secretp)) != 0 || - (r = sshbuf_froms(m, &hostkeys)) != 0 || (r = sshbuf_get_stringb(m, inc)) != 0) fatal_fr(r, "parse config"); @@ -771,6 +706,13 @@ recv_rexec_state(int fd, struct sshbuf *conf, uint64_t *timing_secretp) TAILQ_INSERT_TAIL(&includes, item, entry); } + /* receive hostkeys */ + sshbuf_reset(m); + if (ssh_msg_recv(fd, m) == -1) + fatal_f("ssh_msg_recv failed"); + if ((r = sshbuf_get_u8(m, NULL)) != 0 || + (r = sshbuf_froms(m, &hostkeys)) != 0) + fatal_fr(r, "parse config"); parse_hostkeys(hostkeys); free(cp); @@ -871,7 +813,7 @@ main(int ac, char **av) struct ssh *ssh = NULL; extern char *optarg; extern int optind; - int r, opt, on = 1, remote_port; + int devnull, r, opt, on = 1, remote_port; int sock_in = -1, sock_out = -1, rexeced_flag = 0, have_key = 0; const char *remote_ip, *rdomain; char *line, *laddr, *logfile = NULL; @@ -1028,13 +970,21 @@ main(int ac, char **av) exit(1); } - debug("sshd version %s, %s", SSH_VERSION, SSH_OPENSSL_VERSION); - if (!rexeced_flag) fatal("sshd-session should not be executed directly"); closefrom(REEXEC_MIN_FREE_FD); + platform_pre_session_start(); + + /* Reserve fds we'll need later for reexec things */ + if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1) + fatal("open %s: %s", _PATH_DEVNULL, strerror(errno)); + while (devnull < PRIVSEP_MIN_FREE_FD) { + if ((devnull = dup(devnull)) == -1) + fatal("dup %s: %s", _PATH_DEVNULL, strerror(errno)); + } + seed_rng(); /* If requested, redirect the logs to the specified logfile. */ @@ -1061,19 +1011,22 @@ main(int ac, char **av) SYSLOG_FACILITY_AUTH : options.log_facility, log_stderr || !inetd_flag || debug_flag); - debug("sshd version %s, %s", SSH_VERSION, SSH_OPENSSL_VERSION); - /* Fetch our configuration */ if ((cfg = sshbuf_new()) == NULL) fatal("sshbuf_new config buf failed"); setproctitle("%s", "[rexeced]"); recv_rexec_state(REEXEC_CONFIG_PASS_FD, cfg, &timing_secret); - close(REEXEC_CONFIG_PASS_FD); parse_server_config(&options, "rexec", cfg, &includes, NULL, 1); /* Fill in default values for those options not explicitly set. */ fill_default_server_options(&options); options.timing_secret = timing_secret; + /* Reinit logging in case config set Level, Facility or Verbose. */ + log_init(__progname, options.log_level, options.log_facility, + log_stderr || !inetd_flag || debug_flag); + + debug("sshd-session version %s, %s", SSH_VERSION, SSH_OPENSSL_VERSION); + /* Store privilege separation user for later use if required. */ privsep_chroot = (getuid() == 0 || geteuid() == 0); if ((privsep_pw = getpwnam(SSH_PRIVSEP_USER)) == NULL) { @@ -1087,15 +1040,19 @@ main(int ac, char **av) } endpwent(); - if (!debug_flag) { - startup_pipe = dup(REEXEC_STARTUP_PIPE_FD); - close(REEXEC_STARTUP_PIPE_FD); + if (!debug_flag && !inetd_flag) { + if ((startup_pipe = dup(REEXEC_CONFIG_PASS_FD)) == -1) + fatal("internal error: no startup pipe"); + /* * 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); } + /* close the fd, but keep the slot reserved */ + if (dup2(devnull, REEXEC_CONFIG_PASS_FD) == -1) + fatal("dup2 devnull->config fd: %s", strerror(errno)); /* Check that options are sensible */ if (options.authorized_keys_command_user == NULL && @@ -1227,6 +1184,8 @@ main(int ac, char **av) fatal("Unable to create connection"); the_active_state = ssh; ssh_packet_set_server(ssh); + ssh_packet_set_qos(ssh, options.ip_qos_interactive, + options.ip_qos_bulk); check_ip_options(ssh); @@ -1311,22 +1270,11 @@ main(int ac, char **av) fatal("sshbuf_new loginmsg failed"); auth_debug_reset(); - if (privsep_preauth(ssh) == 1) - goto authenticated; + if (privsep_preauth(ssh) != 1) + fatal("privsep_preauth failed"); - /* perform the key exchange */ - /* authenticate user and start session */ - do_ssh2_kex(ssh); - do_authentication2(ssh); + /* Now user is authenticated */ - /* - * The unprivileged child now transfers the current keystate and exits. - */ - 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. @@ -1423,68 +1371,6 @@ sshd_hostkey_sign(struct ssh *ssh, struct sshkey *privkey, return 0; } -/* SSH2 key exchange */ -static void -do_ssh2_kex(struct ssh *ssh) -{ - char *hkalgs = NULL, *myproposal[PROPOSAL_MAX]; - const char *compression = NULL; - struct kex *kex; - int r; - - if (options.rekey_limit || options.rekey_interval) - ssh_packet_set_rekey_limits(ssh, options.rekey_limit, - options.rekey_interval); - - if (options.compression == COMP_NONE) - compression = "none"; - hkalgs = list_hostkey_types(); - - kex_proposal_populate_entries(ssh, myproposal, options.kex_algorithms, - options.ciphers, options.macs, compression, hkalgs); - - free(hkalgs); - - /* start key exchange */ - if ((r = kex_setup(ssh, myproposal)) != 0) - fatal_r(r, "kex_setup"); - kex_set_server_sig_algs(ssh, options.pubkey_accepted_algos); - 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->kex[KEX_KEM_MLKEM768X25519_SHA256] = 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); - kex_proposal_free_entries(myproposal); - -#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 - debug("KEX done"); -} - /* server specific fatal cleanup */ void cleanup_exit(int i) diff --git a/sshd.0 b/sshd.0 index 23e28be..eddbeec 100644 --- a/sshd.0 +++ b/sshd.0 @@ -306,7 +306,7 @@ AUTHORIZED_KEYS FILE FORMAT The command originally supplied by the client is available in the 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 sshd_config(5) ForceCommand + this command may be superseded by an sshd_config(5) ForceCommand directive. If a command is specified and a forced-command is embedded in a @@ -684,4 +684,4 @@ AUTHORS versions 1.5 and 2.0. Niels Provos and Markus Friedl contributed support for privilege separation. -OpenBSD 7.6 September 15, 2024 OpenBSD 7.6 +OpenBSD 7.7 October 4, 2025 OpenBSD 7.7 diff --git a/sshd.8 b/sshd.8 index 08ebf53..7fbca77 100644 --- a/sshd.8 +++ b/sshd.8 @@ -33,8 +33,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: sshd.8,v 1.327 2024/09/15 01:19:56 djm Exp $ -.Dd $Mdocdate: September 15 2024 $ +.\" $OpenBSD: sshd.8,v 1.328 2025/10/04 21:41:35 naddy Exp $ +.Dd $Mdocdate: October 4 2025 $ .Dt SSHD 8 .Os .Sh NAME @@ -530,7 +530,7 @@ 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 +Also note that this command may be superseded by an .Xr sshd_config 5 .Cm ForceCommand directive. diff --git a/sshd.c b/sshd.c index df76dc7..3c76b60 100644 --- a/sshd.c +++ b/sshd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshd.c,v 1.612 2024/09/15 01:11:26 djm Exp $ */ +/* $OpenBSD: sshd.c,v 1.622 2025/08/29 03:50:38 djm Exp $ */ /* * Copyright (c) 2000, 2001, 2002 Markus Friedl. All rights reserved. * Copyright (c) 2002 Niels Provos. All rights reserved. @@ -29,29 +29,23 @@ #include #include #include -#ifdef HAVE_SYS_STAT_H -# include -#endif -#ifdef HAVE_SYS_TIME_H -# include -#endif +#include +#include #include "openbsd-compat/sys-tree.h" #include "openbsd-compat/sys-queue.h" #include +#include #include #include #include -#ifdef HAVE_PATHS_H #include -#endif #include -#ifdef HAVE_POLL_H #include -#endif #include #include #include +#include #include #include #include @@ -91,12 +85,16 @@ #include "sk-api.h" #include "addr.h" #include "srclimit.h" +#include "atomicio.h" +#ifdef GSSAPI +#include "ssh-gss.h" +#endif +#include "monitor_wrap.h" /* 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) +#define REEXEC_CONFIG_PASS_FD (STDERR_FILENO + 2) +#define REEXEC_MIN_FREE_FD (STDERR_FILENO + 3) extern char *__progname; @@ -181,13 +179,15 @@ struct early_child { struct xaddr addr; int have_addr; int status, have_status; + struct sshbuf *config; + struct sshbuf *keys; }; static struct early_child *children; static int children_active; -static int startup_pipe = -1; /* in child */ /* sshd_config buffer */ struct sshbuf *cfg; +struct sshbuf *config; /* packed */ /* Included files from the configuration file */ struct include_list includes = TAILQ_HEAD_INITIALIZER(includes); @@ -238,7 +238,10 @@ child_register(int pipefd, int sockfd) struct sockaddr *sa = (struct sockaddr *)&addr; for (i = 0; i < options.max_startups; i++) { - if (children[i].pipefd != -1 || children[i].pid > 0) + if (children[i].pipefd != -1 || + children[i].config != NULL || + children[i].keys != NULL || + children[i].pid > 0) continue; child = &(children[i]); break; @@ -249,6 +252,8 @@ child_register(int pipefd, int sockfd) } child->pipefd = pipefd; child->early = 1; + if ((child->config = sshbuf_fromb(config)) == NULL) + fatal_f("sshbuf_fromb failed"); /* record peer address, if available */ if (getpeername(sockfd, sa, &addrlen) == 0 && addr_sa_to_xaddr(sa, addrlen, &child->addr) == 0) @@ -280,8 +285,12 @@ child_finish(struct early_child *child) { if (children_active == 0) fatal_f("internal error: children_active underflow"); - if (child->pipefd != -1) + if (child->pipefd != -1) { + srclimit_done(child->pipefd); close(child->pipefd); + } + sshbuf_free(child->config); + sshbuf_free(child->keys); free(child->id); memset(child, '\0', sizeof(*child)); child->pipefd = -1; @@ -300,6 +309,7 @@ child_close(struct early_child *child, int force_final, int quiet) if (!quiet) debug_f("enter%s", force_final ? " (forcing)" : ""); if (child->pipefd != -1) { + srclimit_done(child->pipefd); close(child->pipefd); child->pipefd = -1; } @@ -335,6 +345,16 @@ child_reap(struct early_child *child) { LogLevel level = SYSLOG_LEVEL_DEBUG1; int was_crash, penalty_type = SRCLIMIT_PENALTY_NONE; + const char *child_status; + + if (child->config) + child_status = " (sending config)"; + else if (child->keys) + child_status = " (sending keys)"; + else if (child->early) + child_status = " (early)"; + else + child_status = ""; /* Log exit information */ if (WIFSIGNALED(child->status)) { @@ -346,54 +366,50 @@ child_reap(struct early_child *child) level = SYSLOG_LEVEL_ERROR; do_log2(level, "session process %ld for %s killed by " "signal %d%s", (long)child->pid, child->id, - WTERMSIG(child->status), child->early ? " (early)" : ""); + WTERMSIG(child->status), child_status); if (was_crash) penalty_type = SRCLIMIT_PENALTY_CRASH; } else if (!WIFEXITED(child->status)) { penalty_type = SRCLIMIT_PENALTY_CRASH; error("session process %ld for %s terminated abnormally, " "status=0x%x%s", (long)child->pid, child->id, child->status, - child->early ? " (early)" : ""); + child_status); } else { /* Normal exit. We care about the status */ switch (WEXITSTATUS(child->status)) { case 0: debug3_f("preauth child %ld for %s completed " - "normally %s", (long)child->pid, child->id, - child->early ? " (early)" : ""); + "normally%s", (long)child->pid, child->id, + child_status); break; case EXIT_LOGIN_GRACE: penalty_type = SRCLIMIT_PENALTY_GRACE_EXCEEDED; logit("Timeout before authentication for %s, " "pid = %ld%s", child->id, (long)child->pid, - child->early ? " (early)" : ""); + child_status); break; case EXIT_CHILD_CRASH: penalty_type = SRCLIMIT_PENALTY_CRASH; logit("Session process %ld unpriv child crash for %s%s", - (long)child->pid, child->id, - child->early ? " (early)" : ""); + (long)child->pid, child->id, child_status); break; case EXIT_AUTH_ATTEMPTED: penalty_type = SRCLIMIT_PENALTY_AUTHFAIL; debug_f("preauth child %ld for %s exited " - "after unsuccessful auth attempt %s", - (long)child->pid, child->id, - child->early ? " (early)" : ""); + "after unsuccessful auth attempt%s", + (long)child->pid, child->id, child_status); break; case EXIT_CONFIG_REFUSED: penalty_type = SRCLIMIT_PENALTY_REFUSECONNECTION; debug_f("preauth child %ld for %s prohibited by" - "RefuseConnection %s", - (long)child->pid, child->id, - child->early ? " (early)" : ""); + "RefuseConnection%s", + (long)child->pid, child->id, child_status); break; default: penalty_type = SRCLIMIT_PENALTY_NOAUTH; debug_f("preauth child %ld for %s exited " "with status %d%s", (long)child->pid, child->id, - WEXITSTATUS(child->status), - child->early ? " (early)" : ""); + WEXITSTATUS(child->status), child_status); break; } } @@ -456,6 +472,7 @@ static void show_info(void) { int i; + const char *child_status; /* XXX print listening sockets here too */ if (children == NULL) @@ -464,9 +481,16 @@ show_info(void) for (i = 0; i < options.max_startups; i++) { if (children[i].pipefd == -1 && children[i].pid <= 0) continue; + if (children[i].config) + child_status = " (sending config)"; + else if (children[i].keys) + child_status = " (sending keys)"; + else if (children[i].early) + child_status = " (early)"; + else + child_status = ""; logit("child %d: fd=%d pid=%ld %s%s", i, children[i].pipefd, - (long)children[i].pid, children[i].id, - children[i].early ? " (early)" : ""); + (long)children[i].pid, children[i].id, child_status); } srclimit_penalty_info(); } @@ -564,59 +588,51 @@ should_drop_connection(int startups) static int drop_connection(int sock, int startups, int notify_pipe) { + static struct log_ratelimit_ctx ratelimit_maxstartups; + static struct log_ratelimit_ctx ratelimit_penalty; + static int init_done; char *laddr, *raddr; - const char *reason = NULL, msg[] = "Not allowed at this time\r\n"; - static time_t last_drop, first_drop; - static u_int ndropped; - LogLevel drop_level = SYSLOG_LEVEL_VERBOSE; - time_t now; - - if (!srclimit_penalty_check_allow(sock, &reason)) { - drop_level = SYSLOG_LEVEL_INFO; - goto handle; + const char *reason = NULL, *subreason = NULL; + const char msg[] = "Not allowed at this time\r\n"; + struct log_ratelimit_ctx *rl = NULL; + int ratelimited; + u_int ndropped; + + if (!init_done) { + init_done = 1; + log_ratelimit_init(&ratelimit_maxstartups, 4, 60, 20, 5*60); + log_ratelimit_init(&ratelimit_penalty, 8, 60, 30, 2*60); } - 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; + /* PerSourcePenalties */ + if (!srclimit_penalty_check_allow(sock, &subreason)) { + reason = "PerSourcePenalties"; + rl = &ratelimit_penalty; + } else { + /* MaxStartups */ + if (!should_drop_connection(startups) && + srclimit_check_allow(sock, notify_pipe) == 1) + return 0; + reason = "Maxstartups"; + rl = &ratelimit_maxstartups; } - last_drop = now; - ndropped++; - reason = "past Maxstartups"; - handle: laddr = get_local_ipaddr(sock); raddr = get_peer_ipaddr(sock); - do_log2(drop_level, "drop connection #%d from [%s]:%d on [%s]:%d %s", + ratelimited = log_ratelimit(rl, time(NULL), NULL, &ndropped); + do_log2(ratelimited ? SYSLOG_LEVEL_DEBUG3 : SYSLOG_LEVEL_INFO, + "drop connection #%d from [%s]:%d on [%s]:%d %s", startups, raddr, get_peer_port(sock), laddr, get_local_port(sock), - reason); + subreason != NULL ? subreason : reason); free(laddr); free(raddr); + if (ndropped != 0) { + logit("%s logging rate-limited: additional %u connections " + "dropped", reason, ndropped); + } + /* best-effort notification to client */ (void)write(sock, msg, sizeof(msg) - 1); return 1; @@ -637,11 +653,13 @@ usage(void) static struct sshbuf * pack_hostkeys(void) { - struct sshbuf *keybuf = NULL, *hostkeys = NULL; + struct sshbuf *m = NULL, *keybuf = NULL, *hostkeys = NULL; int r; u_int i; + size_t len; - if ((keybuf = sshbuf_new()) == NULL || + if ((m = sshbuf_new()) == NULL || + (keybuf = sshbuf_new()) == NULL || (hostkeys = sshbuf_new()) == NULL) fatal_f("sshbuf_new failed"); @@ -676,19 +694,28 @@ pack_hostkeys(void) } } + if ((r = sshbuf_put_u32(m, 0)) != 0 || + (r = sshbuf_put_u8(m, 0)) != 0 || + (r = sshbuf_put_stringb(m, hostkeys)) != 0) + fatal_fr(r, "compose message"); + if ((len = sshbuf_len(m)) < 5 || len > 0xffffffff) + fatal_f("bad length %zu", len); + POKE_U32(sshbuf_mutable_ptr(m), len - 4); + sshbuf_free(keybuf); - return hostkeys; + sshbuf_free(hostkeys); + return m; } -static void -send_rexec_state(int fd, struct sshbuf *conf) +static struct sshbuf * +pack_config(struct sshbuf *conf) { - struct sshbuf *m = NULL, *inc = NULL, *hostkeys = NULL; + struct sshbuf *m = NULL, *inc = NULL; struct include_item *item = NULL; - int r, sz; + size_t len; + int r; - debug3_f("entering fd = %d config len %zu", fd, - sshbuf_len(conf)); + debug3_f("d config len %zu", sshbuf_len(conf)); if ((m = sshbuf_new()) == NULL || (inc = sshbuf_new()) == NULL) @@ -702,42 +729,76 @@ send_rexec_state(int fd, struct sshbuf *conf) fatal_fr(r, "compose includes"); } - hostkeys = pack_hostkeys(); - - /* - * Protocol from reexec master to child: - * string configuration - * uint64 timing_secret - * string host_keys[] { - * string private_key - * string public_key - * string certificate - * } - * string included_files[] { - * string selector - * string filename - * string contents - * } - */ - if ((r = sshbuf_put_stringb(m, conf)) != 0 || + if ((r = sshbuf_put_u32(m, 0)) != 0 || + (r = sshbuf_put_u8(m, 0)) != 0 || + (r = sshbuf_put_stringb(m, conf)) != 0 || (r = sshbuf_put_u64(m, options.timing_secret)) != 0 || - (r = sshbuf_put_stringb(m, hostkeys)) != 0 || (r = sshbuf_put_stringb(m, inc)) != 0) fatal_fr(r, "compose config"); - /* We need to fit the entire message inside the socket send buffer */ - sz = ROUNDUP(sshbuf_len(m) + 5, 16*1024); - if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &sz, sizeof sz) == -1) - fatal_f("setsockopt SO_SNDBUF: %s", strerror(errno)); - - if (ssh_msg_send(fd, 0, m) == -1) - error_f("ssh_msg_send failed"); + if ((len = sshbuf_len(m)) < 5 || len > 0xffffffff) + fatal_f("bad length %zu", len); + POKE_U32(sshbuf_mutable_ptr(m), len - 4); - sshbuf_free(m); sshbuf_free(inc); - sshbuf_free(hostkeys); debug3_f("done"); + return m; +} + +/* + * Protocol from reexec master to child: + * uint32 size + * uint8 type (ignored) + * string configuration + * uint64 timing_secret + * string included_files[] { + * string selector + * string filename + * string contents + * } + * Second message + * uint32 size + * uint8 type (ignored) + * string host_keys[] { + * string private_key + * string public_key + * string certificate + * } + */ +/* + * This function is used only if inet_flag or debug_flag is set, + * otherwise the data is sent from the main poll loop. + * It sends the config from a child process back to the parent. + * The parent will read the config after exec. + */ +static void +send_rexec_state(int fd) +{ + struct sshbuf *keys; + u_int mlen; + pid_t pid; + + if ((pid = fork()) == -1) + fatal_f("fork failed: %s", strerror(errno)); + if (pid != 0) + return; + + debug3_f("entering fd = %d config len %zu", fd, + sshbuf_len(config)); + + mlen = sshbuf_len(config); + if (atomicio(vwrite, fd, sshbuf_mutable_ptr(config), mlen) != mlen) + error_f("write: %s", strerror(errno)); + + keys = pack_hostkeys(); + mlen = sshbuf_len(keys); + if (atomicio(vwrite, fd, sshbuf_mutable_ptr(keys), mlen) != mlen) + error_f("write: %s", strerror(errno)); + + sshbuf_free(keys); + debug3_f("done"); + exit(0); } /* @@ -852,12 +913,15 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s, int log_stderr) { struct pollfd *pfd = NULL; - int i, ret, npfd; + int i, ret, npfd, r; int oactive = -1, listening = 0, lameduck = 0; - int startup_p[2] = { -1 , -1 }, *startup_pollfd; + int *startup_pollfd; + ssize_t len; + const u_char *ptr; char c = 0; struct sockaddr_storage from; struct early_child *child; + struct sshbuf *buf; socklen_t fromlen; u_char rnd[256]; sigset_t nsigset, osigset; @@ -935,6 +999,9 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s, if (children[i].pipefd != -1) { pfd[npfd].fd = children[i].pipefd; pfd[npfd].events = POLLIN; + if (children[i].config != NULL || + children[i].keys != NULL) + pfd[npfd].events |= POLLOUT; startup_pollfd[i] = npfd++; } } @@ -950,6 +1017,49 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s, if (ret == -1) continue; + for (i = 0; i < options.max_startups; i++) { + if (children[i].pipefd == -1 || + startup_pollfd[i] == -1 || + !(pfd[startup_pollfd[i]].revents & POLLOUT)) + continue; + if (children[i].config) + buf = children[i].config; + else if (children[i].keys) + buf = children[i].keys; + else { + error_f("no buffer to send"); + continue; + } + ptr = sshbuf_ptr(buf); + len = sshbuf_len(buf); + ret = write(children[i].pipefd, ptr, len); + if (ret == -1 && (errno == EINTR || errno == EAGAIN)) + continue; + if (ret <= 0) { + if (children[i].early) + listening--; + child_close(&(children[i]), 0, 0); + continue; + } + if (ret == len) { + /* finished sending buffer */ + sshbuf_free(buf); + if (children[i].config == buf) { + /* sent config, now send keys */ + children[i].config = NULL; + children[i].keys = pack_hostkeys(); + } else if (children[i].keys == buf) { + /* sent both config and keys */ + children[i].keys = NULL; + } else { + fatal("config buf not set"); + } + + } else { + if ((r = sshbuf_consume(buf, ret)) != 0) + fatal_fr(r, "config buf inconsistent"); + } + } for (i = 0; i < options.max_startups; i++) { if (children[i].pipefd == -1 || startup_pollfd[i] == -1 || @@ -966,13 +1076,20 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s, } /* FALLTHROUGH */ case 0: - /* child exited preauth */ + /* child closed pipe */ if (children[i].early) listening--; - srclimit_done(children[i].pipefd); + debug3_f("child %lu for %s closed pipe", + (long)children[i].pid, children[i].id); child_close(&(children[i]), 0, 0); break; case 1: + if (children[i].config) { + error_f("startup pipe %d (fd=%d)" + " early read", + i, children[i].pipefd); + goto problem_child; + } if (children[i].early && c == '\0') { /* child has finished preliminaries */ listening--; @@ -991,6 +1108,12 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s, "child %ld for %s in state %d", (int)c, (long)children[i].pid, children[i].id, children[i].early); + problem_child: + if (children[i].early) + listening--; + if (children[i].pid > 0) + kill(children[i].pid, SIGTERM); + child_close(&(children[i]), 0, 0); } break; } @@ -1014,26 +1137,18 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s, close(*newsock); continue; } - if (pipe(startup_p) == -1) { - error_f("pipe(startup_p): %s", strerror(errno)); - close(*newsock); - continue; - } - if (drop_connection(*newsock, - children_active, startup_p[0])) { - close(*newsock); - close(startup_p[0]); - close(startup_p[1]); - continue; - } - if (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; + } + if (drop_connection(*newsock, + children_active, config_s[0])) { + close(*newsock); + close(config_s[0]); + close(config_s[1]); continue; } @@ -1051,12 +1166,10 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s, close_listen_socks(); *sock_in = *newsock; *sock_out = *newsock; - close(startup_p[0]); - close(startup_p[1]); - startup_pipe = -1; - send_rexec_state(config_s[0], cfg); + send_rexec_state(config_s[0]); close(config_s[0]); free(pfd); + free(startup_pollfd); return; } @@ -1066,8 +1179,9 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s, * parent continues listening. */ platform_pre_fork(); + set_nonblock(config_s[0]); listening++; - child = child_register(startup_p[0], *newsock); + child = child_register(config_s[0], *newsock); if ((child->pid = fork()) == 0) { /* * Child. Close the listening and @@ -1078,7 +1192,6 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s, * the connection. */ platform_post_fork_child(); - startup_pipe = startup_p[1]; close_startup_pipes(); close_listen_socks(); *sock_in = *newsock; @@ -1089,6 +1202,7 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s, log_stderr); close(config_s[0]); free(pfd); + free(startup_pollfd); return; } @@ -1099,11 +1213,7 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s, else debug("Forked child %ld.", (long)child->pid); - close(startup_p[1]); - close(config_s[1]); - send_rexec_state(config_s[0], cfg); - close(config_s[0]); close(*newsock); /* @@ -1115,7 +1225,7 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s, #ifdef WITH_OPENSSL RAND_seed(rnd, sizeof(rnd)); if ((RAND_bytes((u_char *)rnd, 1)) != 1) - fatal("%s: RAND_bytes failed", __func__); + fatal_f("RAND_bytes failed"); #endif explicit_bzero(rnd, sizeof(rnd)); } @@ -1193,13 +1303,14 @@ main(int ac, char **av) int sock_in = -1, sock_out = -1, newsock = -1, rexec_argc = 0; int devnull, config_s[2] = { -1 , -1 }, have_connection_info = 0; int need_chroot = 1; - char *fp, *line, *logfile = NULL, **rexec_argv = NULL; + char *args, *fp, *line, *logfile = NULL, **rexec_argv = NULL; struct stat sb; u_int i, j; mode_t new_umask; struct sshkey *key; struct sshkey *pubkey; struct connection_info connection_info; + struct utsname utsname; sigset_t sigmask; memset(&connection_info, 0, sizeof(connection_info)); @@ -1235,6 +1346,7 @@ main(int ac, char **av) initialize_server_options(&options); /* Parse command-line arguments. */ + args = argv_assemble(ac, av); /* logged later */ while ((opt = getopt(ac, av, "C:E:b:c:f:g:h:k:o:p:u:46DGQRTdeiqrtV")) != -1) { switch (opt) { @@ -1404,6 +1516,16 @@ main(int ac, char **av) fatal("Config test connection parameter (-C) provided without " "test mode (-T)"); + debug("sshd version %s, %s", SSH_VERSION, SSH_OPENSSL_VERSION); + if (uname(&utsname) != 0) { + memset(&utsname, 0, sizeof(utsname)); + strlcpy(utsname.sysname, "UNKNOWN", sizeof(utsname.sysname)); + } + debug3("Running on %s %s %s %s", utsname.sysname, utsname.release, + utsname.version, utsname.machine); + debug3("Started with: %s", args); + free(args); + /* Fetch our configuration */ if ((cfg = sshbuf_new()) == NULL) fatal("sshbuf_new config failed"); @@ -1451,8 +1573,6 @@ main(int ac, char **av) exit(1); } - debug("sshd version %s, %s", SSH_VERSION, SSH_OPENSSL_VERSION); - if (do_dump_cfg) print_config(&connection_info); @@ -1540,12 +1660,10 @@ main(int ac, char **av) 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; @@ -1634,6 +1752,12 @@ main(int ac, char **av) if (test_flag > 1) print_config(&connection_info); + config = pack_config(cfg); + if (sshbuf_len(config) > MONITOR_MAX_CFGLEN) { + fatal("Configuration file is too large (have %zu, max %d)", + sshbuf_len(config), MONITOR_MAX_CFGLEN); + } + /* Configuration looks good, so exit if in test mode. */ if (test_flag) exit(0); @@ -1664,6 +1788,13 @@ main(int ac, char **av) fatal("%s does not exist or is not executable", rexec_argv[0]); debug3("using %s for re-exec", rexec_argv[0]); + /* Ensure that the privsep binary exists now too. */ + if (stat(options.sshd_auth_path, &sb) != 0 || + !(sb.st_mode & (S_IXOTH|S_IXUSR))) { + fatal("%s does not exist or is not executable", + options.sshd_auth_path); + } + listener_proctitle = prepare_proctitle(ac, av); /* Ensure that umask disallows at least group and world write */ @@ -1709,7 +1840,7 @@ main(int ac, char **av) /* Send configuration to ancestor sshd-session process */ if (socketpair(AF_UNIX, SOCK_STREAM, 0, config_s) == -1) fatal("socketpair: %s", strerror(errno)); - send_rexec_state(config_s[0], cfg); + send_rexec_state(config_s[0]); close(config_s[0]); } else { platform_pre_listen(); @@ -1757,8 +1888,8 @@ main(int ac, char **av) if (!debug_flag && !inetd_flag && setsid() == -1) error("setsid: %.100s", strerror(errno)); - debug("rexec start in %d out %d newsock %d pipe %d sock %d/%d", - sock_in, sock_out, newsock, startup_pipe, config_s[0], config_s[1]); + debug("rexec start in %d out %d newsock %d config_s %d/%d", + sock_in, sock_out, newsock, config_s[0], config_s[1]); if (!inetd_flag) { if (dup2(newsock, STDIN_FILENO) == -1) fatal("dup2 stdin: %s", strerror(errno)); @@ -1772,13 +1903,6 @@ main(int ac, char **av) fatal("dup2 config_s: %s", strerror(errno)); close(config_s[1]); } - if (startup_pipe == -1) - close(REEXEC_STARTUP_PIPE_FD); - else if (startup_pipe != REEXEC_STARTUP_PIPE_FD) { - if (dup2(startup_pipe, REEXEC_STARTUP_PIPE_FD) == -1) - fatal("dup2 startup_p: %s", strerror(errno)); - close(startup_pipe); - } log_redirect_stderr_to(NULL); closefrom(REEXEC_MIN_FREE_FD); diff --git a/sshd_config b/sshd_config index 36894ac..0f4a3a7 100644 --- a/sshd_config +++ b/sshd_config @@ -1,4 +1,4 @@ -# $OpenBSD: sshd_config,v 1.104 2021/07/02 05:11:21 dtucker Exp $ +# $OpenBSD: sshd_config,v 1.105 2024/12/03 14:12:47 dtucker Exp $ # This is the sshd server system-wide configuration file. See # sshd_config(5) for more information. @@ -53,11 +53,13 @@ AuthorizedKeysFile .ssh/authorized_keys # Don't read the user's ~/.rhosts and ~/.shosts files #IgnoreRhosts yes -# To disable tunneled clear text passwords, change to no here! +# To disable tunneled clear text passwords, change to "no" here! #PasswordAuthentication yes #PermitEmptyPasswords no -# Change to no to disable s/key passwords +# Change to "no" to disable keyboard-interactive authentication. Depending on +# the system's configuration, this may involve passwords, challenge-response, +# one-time passwords or some combination of these and other methods. #KbdInteractiveAuthentication yes # Kerberos options diff --git a/sshd_config.0 b/sshd_config.0 index a9d8b79..c63d729 100644 --- a/sshd_config.0 +++ b/sshd_config.0 @@ -150,12 +150,13 @@ DESCRIPTION Specifies the file that contains the public keys used for user authentication. The format is described in the AUTHORIZED_KEYS FILE FORMAT section of sshd(8). Arguments to AuthorizedKeysFile - accept the tokens described in the TOKENS section. After - expansion, 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 none to skip checking for user keys in files. The default - is ".ssh/authorized_keys .ssh/authorized_keys2". + may include wildcards and accept the tokens described in the + TOKENS section. After expansion, 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 none to skip checking for + user keys in files. The default is ".ssh/authorized_keys + .ssh/authorized_keys2". AuthorizedPrincipalsCommand Specifies a program to be used to generate the list of allowed @@ -190,12 +191,13 @@ DESCRIPTION options (as described in AUTHORIZED_KEYS FILE FORMAT in sshd(8)). Empty lines and comments starting with M-bM-^@M-^X#M-bM-^@M-^Y are ignored. - Arguments to AuthorizedPrincipalsFile accept the tokens described - in the TOKENS section. After expansion, AuthorizedPrincipalsFile - is taken to be an absolute path or one relative to the user's - home directory. The default is none, i.e. not to use a - principals file M-bM-^@M-^S in this case, the username of the user must - appear in a certificate's principals list for it to be accepted. + Arguments to AuthorizedPrincipalsFile may include wildcards and + accept the tokens described in the TOKENS section. After + expansion, AuthorizedPrincipalsFile is taken to be an absolute + path or one relative to the user's home directory. The default + is none, i.e. not to use a principals file M-bM-^@M-^S in this case, the + username of the user must appear in a certificate's principals + list for it to be accepted. Note that AuthorizedPrincipalsFile is only used when authentication proceeds using a CA listed in TrustedUserCAKeys @@ -252,13 +254,13 @@ DESCRIPTION direct-tcpip, direct-streamlocal@openssh.com Open TCP or Unix socket (respectively) connections that - have been established from a ssh(1) local forwarding, + have been established from an ssh(1) local forwarding, i.e. LocalForward or DynamicForward. forwarded-tcpip, forwarded-streamlocal@openssh.com Open TCP or Unix socket (respectively) connections that - have been established to a sshd(8) listening on behalf of - a ssh(1) remote forwarding, i.e. RemoteForward. + have been established to an sshd(8) listening on behalf + of an ssh(1) remote forwarding, i.e. RemoteForward. session The interactive main session, including shell session, @@ -336,8 +338,8 @@ DESCRIPTION The default is: chacha20-poly1305@openssh.com, - aes128-ctr,aes192-ctr,aes256-ctr, - aes128-gcm@openssh.com,aes256-gcm@openssh.com + aes128-gcm@openssh.com,aes256-gcm@openssh.com, + aes128-ctr,aes192-ctr,aes256-ctr The list of available ciphers may also be obtained using "ssh -Q cipher". @@ -575,18 +577,18 @@ DESCRIPTION directive may appear inside a Match block to perform conditional inclusion. - IPQoS Specifies the IPv4 type-of-service or DSCP class for the - connection. Accepted values are af11, af12, af13, af21, af22, - af23, af31, af32, af33, af41, af42, af43, cs0, cs1, cs2, cs3, - cs4, cs5, cs6, cs7, ef, le, lowdelay, throughput, reliability, a - numeric value, or 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 af21 (Low-Latency - Data) for interactive sessions and cs1 (Lower Effort) for non- - interactive sessions. + IPQoS Specifies the Differentiated Services Field Codepoint (DSCP) + value for the connection. Accepted values are af11, af12, af13, + af21, af22, af23, af31, af32, af33, af41, af42, af43, cs0, cs1, + cs2, cs3, cs4, cs5, cs6, cs7, ef, le, a numeric value, or 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 ef (Expedited Forwarding) for interactive sessions + and none (the operating system default) for non-interactive + sessions. KbdInteractiveAuthentication Specifies whether to allow keyboard-interactive authentication. @@ -650,13 +652,10 @@ DESCRIPTION The default is: - sntrup761x25519-sha512,sntrup761x25519-sha512@openssh.com, mlkem768x25519-sha256, + sntrup761x25519-sha512,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 + ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521 The list of supported key exchange algorithms may also be obtained using "ssh -Q KexAlgorithms". @@ -759,9 +758,9 @@ DESCRIPTION one of the single token criteria: All, which matches all criteria, or Invalid-User, which matches when the requested user- name does not match any known account. The available criteria - are User, Group, Host, LocalAddress, LocalPort, RDomain, and - Address (with RDomain representing the rdomain(4) on which the - connection was received). + are User, Group, Host, LocalAddress, LocalPort, Version, RDomain, + and Address (with RDomain representing the rdomain(4) on which + the connection was received). The match patterns may consist of single entries or comma- separated lists and may use the wildcard and negation operators @@ -775,6 +774,9 @@ DESCRIPTION with bits set in this host portion of the address. For example, 192.0.2.0/33 and 192.0.2.0/8, respectively. + The Version keyword matches against the version string of + sshd(8), for example M-bM-^@M-^\OpenSSH_10.0M-bM-^@M-^]. + Only a subset of keywords may be used on the lines following a Match keyword. Available keywords are AcceptEnv, AllowAgentForwarding, AllowGroups, AllowStreamLocalForwarding, @@ -1156,6 +1158,12 @@ DESCRIPTION environment and any variables specified by the user via AcceptEnv or PermitUserEnvironment. + SshdAuthPath + Overrides the default path to the sshd-auth binary that is + invoked to complete user authentication. The default is + /usr/libexec/sshd-auth. This option is intended for use by + tests. + SshdSessionPath Overrides the default path to the sshd-session binary that is invoked to handle each connection. The default is @@ -1408,4 +1416,4 @@ AUTHORS versions 1.5 and 2.0. Niels Provos and Markus Friedl contributed support for privilege separation. -OpenBSD 7.6 September 15, 2024 OpenBSD 7.6 +OpenBSD 7.7 October 4, 2025 OpenBSD 7.7 diff --git a/sshd_config.5 b/sshd_config.5 index dbed44f..6ae606f 100644 --- a/sshd_config.5 +++ b/sshd_config.5 @@ -33,8 +33,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: sshd_config.5,v 1.374 2024/09/15 08:27:38 jmc Exp $ -.Dd $Mdocdate: September 15 2024 $ +.\" $OpenBSD: sshd_config.5,v 1.385 2025/10/04 21:41:35 naddy Exp $ +.Dd $Mdocdate: October 4 2025 $ .Dt SSHD_CONFIG 5 .Os .Sh NAME @@ -250,7 +250,7 @@ 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 +.Cm AUTHORIZED_KEYS in .Xr sshd 8 ) . .Cm AuthorizedKeysCommand @@ -279,7 +279,7 @@ 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 +may include wildcards and accept the tokens described in the .Sx TOKENS section. After expansion, @@ -339,7 +339,7 @@ When using certificates signed by a key listed in 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 +.Cm AUTHORIZED_KEYS FILE FORMAT in .Xr sshd 8 ) . Empty lines and comments starting with @@ -348,7 +348,7 @@ are ignored. .Pp Arguments to .Cm AuthorizedPrincipalsFile -accept the tokens described in the +may include wildcards and accept the tokens described in the .Sx TOKENS section. After expansion, @@ -440,7 +440,7 @@ 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 +been established from an .Xr ssh 1 local forwarding, i.e.\& .Cm LocalForward @@ -448,9 +448,9 @@ 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 +established to an .Xr sshd 8 -listening on behalf of a +listening on behalf of an .Xr ssh 1 remote forwarding, i.e.\& .Cm RemoteForward . @@ -576,8 +576,8 @@ chacha20-poly1305@openssh.com 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 +aes128-gcm@openssh.com,aes256-gcm@openssh.com, +aes128-ctr,aes192-ctr,aes256-ctr .Ed .Pp The list of available ciphers may also be obtained using @@ -923,7 +923,9 @@ directive may appear inside a block to perform conditional inclusion. .It Cm IPQoS -Specifies the IPv4 type-of-service or DSCP class for the connection. +Specifies the +.Em Differentiated Services Field Codepoint Pq DSCP +value for the connection. Accepted values are .Cm af11 , .Cm af12 , @@ -947,9 +949,6 @@ Accepted values are .Cm cs7 , .Cm ef , .Cm le , -.Cm lowdelay , -.Cm throughput , -.Cm reliability , a numeric value, or .Cm none to use the operating system default. @@ -958,11 +957,11 @@ 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) +.Cm ef +(Expedited Forwarding) for interactive sessions and -.Cm cs1 -(Lower Effort) +.Cm none +(the operating system default) for non-interactive sessions. .It Cm KbdInteractiveAuthentication Specifies whether to allow keyboard-interactive authentication. @@ -1059,13 +1058,10 @@ sntrup761x25519-sha512@openssh.com .Pp The default is: .Bd -literal -offset indent -sntrup761x25519-sha512,sntrup761x25519-sha512@openssh.com, mlkem768x25519-sha256, +sntrup761x25519-sha512,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 +ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521 .Ed .Pp The list of supported key exchange algorithms may also be obtained using @@ -1248,6 +1244,7 @@ The available criteria are .Cm Host , .Cm LocalAddress , .Cm LocalPort , +.Cm Version , .Cm RDomain , and .Cm Address @@ -1273,6 +1270,13 @@ 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 +The +.Cm Version +keyword matches against the version string of +.Xr sshd 8 , +for example +.Dq OpenSSH_10.0 . +.Pp Only a subset of keywords may be used on the lines following a .Cm Match keyword. @@ -1856,6 +1860,13 @@ via .Cm AcceptEnv or .Cm PermitUserEnvironment . +.It Cm SshdAuthPath +Overrides the default path to the +.Cm sshd-auth +binary that is invoked to complete user authentication. +The default is +.Pa /usr/libexec/sshd-auth . +This option is intended for use by tests. .It Cm SshdSessionPath Overrides the default path to the .Cm sshd-session diff --git a/sshkey-xmss.c b/sshkey-xmss.c deleted file mode 100644 index 818aba9..0000000 --- a/sshkey-xmss.c +++ /dev/null @@ -1,1113 +0,0 @@ -/* $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 -#include - -#include -#include -#include -#include -#include -#ifdef HAVE_SYS_FILE_H -# include -#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, 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/sshkey-xmss.h b/sshkey-xmss.h deleted file mode 100644 index ab8b9c9..0000000 --- a/sshkey-xmss.h +++ /dev/null @@ -1,56 +0,0 @@ -/* $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 *, 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/sshkey.c b/sshkey.c index 1db8378..afd7822 100644 --- a/sshkey.c +++ b/sshkey.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshkey.c,v 1.146 2024/09/04 05:33:34 djm Exp $ */ +/* $OpenBSD: sshkey.c,v 1.155 2025/10/03 00:08:02 djm Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. * Copyright (c) 2008 Alexander von Gernler. All rights reserved. @@ -32,6 +32,7 @@ #include #ifdef WITH_OPENSSL +#include #include #include #include @@ -46,9 +47,7 @@ #include #include #include -#ifdef HAVE_UTIL_H #include -#endif /* HAVE_UTIL_H */ #include "ssh2.h" #include "ssherr.h" @@ -60,11 +59,7 @@ #include "sshkey.h" #include "match.h" #include "ssh-sk.h" - -#ifdef WITH_XMSS -#include "sshkey-xmss.h" -#include "xmss_fast.h" -#endif +#include "ssh-pkcs11.h" #include "openbsd-compat/openssl-compat.h" @@ -79,9 +74,6 @@ #define DEFAULT_CIPHERNAME "aes256-ctr" #define DEFAULT_ROUNDS 24 -/* 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 @@ -90,8 +82,6 @@ #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); @@ -122,15 +112,7 @@ 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; -# ifdef WITH_DSA -extern const struct sshkey_impl sshkey_dss_impl; -extern const struct sshkey_impl sshkey_dsa_cert_impl; -# endif #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, @@ -155,10 +137,6 @@ const struct sshkey_impl * const keyimpls[] = { &sshkey_ecdsa_sk_webauthn_impl, # endif /* ENABLE_SK */ # endif /* OPENSSL_HAS_ECC */ -# ifdef WITH_DSA - &sshkey_dss_impl, - &sshkey_dsa_cert_impl, -# endif &sshkey_rsa_impl, &sshkey_rsa_cert_impl, &sshkey_rsa_sha256_impl, @@ -166,10 +144,6 @@ const struct sshkey_impl * const keyimpls[] = { &sshkey_rsa_sha512_impl, &sshkey_rsa_sha512_cert_impl, #endif /* WITH_OPENSSL */ -#ifdef WITH_XMSS - &sshkey_xmss_impl, - &sshkey_xmss_cert_impl, -#endif NULL }; @@ -333,9 +307,10 @@ sshkey_match_keyname_to_sigalgs(const char *keyname, const char *sigalgs) char * sshkey_alg_list(int certs_only, int plain_only, int include_sigonly, char sep) { - char *tmp, *ret = NULL; - size_t i, nlen, rlen = 0; + char *ret = NULL; + size_t i; const struct sshkey_impl *impl; + char sep_str[2] = {sep, '\0'}; for (i = 0; keyimpls[i] != NULL; i++) { impl = keyimpls[i]; @@ -345,16 +320,7 @@ sshkey_alg_list(int certs_only, int plain_only, int include_sigonly, char sep) continue; if ((certs_only && !impl->cert) || (plain_only && impl->cert)) continue; - if (ret != NULL) - ret[rlen++] = sep; - nlen = strlen(impl->name); - if ((tmp = realloc(ret, rlen + nlen + 2)) == NULL) { - free(ret); - return NULL; - } - ret = tmp; - memcpy(ret + rlen, impl->name, nlen + 1); - rlen += nlen; + xextendf(&ret, sep_str, "%s", impl->name); } return ret; } @@ -454,8 +420,6 @@ 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: @@ -464,8 +428,6 @@ sshkey_type_plain(int type) return KEY_ED25519; case KEY_ED25519_SK_CERT: return KEY_ED25519_SK; - case KEY_XMSS_CERT: - return KEY_XMSS; default: return type; } @@ -478,8 +440,6 @@ 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: @@ -488,8 +448,6 @@ sshkey_type_certified(int type) return KEY_ED25519_CERT; case KEY_ED25519_SK: return KEY_ED25519_SK_CERT; - case KEY_XMSS: - return KEY_XMSS_CERT; default: return -1; } @@ -765,6 +723,7 @@ sshkey_sk_cleanup(struct sshkey *k) static int sshkey_prekey_alloc(u_char **prekeyp, size_t len) { +#if defined(HAVE_MMAP) && defined(MAP_ANON) && defined(MAP_PRIVATE) u_char *prekey; *prekeyp = NULL; @@ -775,15 +734,22 @@ sshkey_prekey_alloc(u_char **prekeyp, size_t len) (void)madvise(prekey, len, MADV_DONTDUMP); #endif *prekeyp = prekey; +#else + *prekeyp = calloc(1, len); +#endif /* HAVE_MMAP et al */ return 0; } static void sshkey_prekey_free(void *prekey, size_t len) { +#if defined(HAVE_MMAP) && defined(MAP_ANON) && defined(MAP_PRIVATE) if (prekey == NULL) return; munmap(prekey, len); +#else + free(prekey); +#endif /* HAVE_MMAP et al */ } static void @@ -793,6 +759,8 @@ sshkey_free_contents(struct sshkey *k) if (k == NULL) return; + if ((k->flags & SSHKEY_FLAG_EXT) != 0) + pkcs11_key_free(k); if ((impl = sshkey_impl_from_type(k->type)) != NULL && impl->funcs->cleanup != NULL) impl->funcs->cleanup(k); @@ -915,16 +883,16 @@ 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) +static int +sshkey_puts_opts_internal(const struct sshkey *key, struct sshbuf *b, + enum sshkey_serialize_rep opts, int force_plain) { struct sshbuf *tmp; int r; if ((tmp = sshbuf_new()) == NULL) return SSH_ERR_ALLOC_FAIL; - r = to_blob_buf(key, tmp, 0, opts); + r = to_blob_buf(key, tmp, force_plain, opts); if (r == 0) r = sshbuf_put_stringb(b, tmp); sshbuf_free(tmp); @@ -934,7 +902,7 @@ sshkey_puts_opts(const struct sshkey *key, struct sshbuf *b, int sshkey_puts(const struct sshkey *key, struct sshbuf *b) { - return sshkey_puts_opts(key, b, SSHKEY_SERIALIZE_DEFAULT); + return sshkey_puts_opts_internal(key, b, SSHKEY_SERIALIZE_DEFAULT, 0); } int @@ -943,6 +911,12 @@ sshkey_putb_plain(const struct sshkey *key, struct sshbuf *b) return to_blob_buf(key, b, 1, SSHKEY_SERIALIZE_DEFAULT); } +int +sshkey_puts_plain(const struct sshkey *key, struct sshbuf *b) +{ + return sshkey_puts_opts_internal(key, b, SSHKEY_SERIALIZE_DEFAULT, 1); +} + static int to_blob(const struct sshkey *key, u_char **blobp, size_t *lenp, int force_plain, enum sshkey_serialize_rep opts) @@ -1690,8 +1664,7 @@ sshkey_shield_private(struct sshkey *k) } if (sshkey_is_shielded(k) && (r = sshkey_unshield_private(k)) != 0) goto out; - if ((r = sshkey_private_serialize_opt(k, prvbuf, - SSHKEY_SERIALIZE_SHIELD)) != 0) + if ((r = sshkey_private_serialize(k, prvbuf)) != 0) goto out; /* pad to cipher blocksize */ i = 0; @@ -2215,6 +2188,9 @@ sshkey_sign(struct sshkey *key, if (sshkey_is_sk(key)) { r = sshsk_sign(sk_provider, key, sigp, lenp, data, datalen, compat, sk_pin); + } else if ((key->flags & SSHKEY_FLAG_EXT) != 0) { + r = pkcs11_sign(key, sigp, lenp, data, datalen, + alg, sk_provider, sk_pin, compat); } else { if (impl->funcs->sign == NULL) r = SSH_ERR_SIGN_ALG_UNSUPPORTED; @@ -2546,7 +2522,7 @@ sshkey_serialize_private_sk(const struct sshkey *key, struct sshbuf *b) return 0; } -int +static int sshkey_private_serialize_opt(struct sshkey *key, struct sshbuf *buf, enum sshkey_serialize_rep opts) { @@ -2597,6 +2573,7 @@ sshkey_private_serialize(struct sshkey *key, struct sshbuf *b) SSHKEY_SERIALIZE_DEFAULT); } + /* Shared deserialization of FIDO private key components */ int sshkey_private_deserialize_sk(struct sshbuf *buf, struct sshkey *k) @@ -2656,7 +2633,6 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp) 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; @@ -2670,7 +2646,6 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp) 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 || @@ -2708,14 +2683,6 @@ sshkey_ec_validate_public(const EC_GROUP *group, const EC_POINT *public) * 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; @@ -2730,8 +2697,7 @@ sshkey_ec_validate_public(const EC_GROUP *group, const EC_POINT *public) /* 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) { + EC_POINT_get_affine_coordinates(group, public, x, y, NULL) != 1) { ret = SSH_ERR_LIBCRYPTO_ERROR; goto out; } @@ -2815,14 +2781,8 @@ sshkey_dump_ec_point(const EC_GROUP *group, const EC_POINT *point) 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", + if (EC_POINT_get_affine_coordinates(group, point, x, y, NULL) != 1) { + fprintf(stderr, "%s: EC_POINT_get_affine_coordinates\n", __func__); goto out; } @@ -2930,8 +2890,7 @@ sshkey_private_to_blob2(struct sshkey *prv, struct sshbuf *blob, goto out; /* append private key and comment*/ - if ((r = sshkey_private_serialize_opt(prv, encrypted, - SSHKEY_SERIALIZE_FULL)) != 0 || + if ((r = sshkey_private_serialize(prv, encrypted)) != 0 || (r = sshbuf_put_cstring(encrypted, comment)) != 0) goto out; @@ -3338,20 +3297,6 @@ sshkey_private_to_blob_pem_pkcs8(struct sshkey *key, struct sshbuf *buf, goto out; switch (key->type) { -#ifdef WITH_DSA - case KEY_DSA: - if (format == SSHKEY_PRIVATE_PEM) { - success = PEM_write_bio_DSAPrivateKey(bio, key->dsa, - cipher, passphrase, len, NULL, NULL); - } else { - if ((pkey = EVP_PKEY_new()) == NULL) { - r = SSH_ERR_ALLOC_FAIL; - goto out; - } - success = EVP_PKEY_set1_DSA(pkey, key->dsa); - } - break; -#endif #ifdef OPENSSL_HAS_ECC case KEY_ECDSA: if (format == SSHKEY_PRIVATE_PEM) { @@ -3419,16 +3364,12 @@ sshkey_private_to_fileblob(struct sshkey *key, struct sshbuf *blob, { 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 */ @@ -3594,19 +3535,6 @@ sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type, prv->pkey = pk; if ((r = sshkey_check_rsa_length(prv, 0)) != 0) goto out; -#ifdef WITH_DSA - } 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 -#endif #ifdef OPENSSL_HAS_ECC } else if (EVP_PKEY_base_id(pk) == EVP_PKEY_EC && (type == KEY_UNSPEC || type == KEY_ECDSA)) { @@ -3703,24 +3631,16 @@ sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type, if (commentp != NULL) *commentp = NULL; - switch (type) { - 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; + 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); + return sshkey_parse_private_pem_fileblob(blob, type, + passphrase, keyp); #else - return SSH_ERR_INVALID_FORMAT; + return SSH_ERR_INVALID_FORMAT; #endif /* WITH_OPENSSL */ - } } int @@ -3755,90 +3675,3 @@ sshkey_parse_pubkey_from_private_fileblob_type(struct sshbuf *blob, int type, 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/sshkey.h b/sshkey.h index d0cdea0..c3262b8 100644 --- a/sshkey.h +++ b/sshkey.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sshkey.h,v 1.65 2024/09/04 05:33:34 djm Exp $ */ +/* $OpenBSD: sshkey.h,v 1.70 2025/08/29 03:50:38 djm Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. @@ -30,7 +30,6 @@ #ifdef WITH_OPENSSL #include -#include #include # ifdef OPENSSL_HAS_ECC # include @@ -44,7 +43,6 @@ #else /* WITH_OPENSSL */ # define BIGNUM void # define RSA void -# define DSA void # define EC_KEY void # define EC_GROUP void # define EC_POINT void @@ -60,15 +58,11 @@ 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, @@ -91,10 +85,6 @@ enum sshkey_fp_rep { /* 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 */ @@ -127,8 +117,6 @@ struct sshkey_cert { struct sshkey { int type; int flags; - /* KEY_DSA */ - DSA *dsa; /* KEY_ECDSA and KEY_ECDSA_SK */ int ecdsa_nid; /* NID of curve */ /* libcrypto-backed keys */ @@ -136,12 +124,6 @@ struct sshkey { /* 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; @@ -277,10 +259,9 @@ 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_puts_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); @@ -302,8 +283,6 @@ 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 */ @@ -318,17 +297,18 @@ 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); +int ssh_rsa_hash_id_from_keyname(const char *); +const char *ssh_rsa_hash_alg_ident(int); +int ssh_rsa_encode_store_sig(int, const u_char *, size_t, + u_char **, size_t *); +int ssh_ecdsa_encode_store_sig(const struct sshkey *, + const BIGNUM *, const BIGNUM *, u_char **, size_t *); +int ssh_ed25519_encode_store_sig(const u_char *, size_t, + u_char **, size_t *); /* XXX should be internal, but used by ssh-keygen */ int ssh_rsa_complete_crt_parameters(const BIGNUM *, const BIGNUM *, const BIGNUM *, const BIGNUM *, BIGNUM **, 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_private_serialize_maxsign(struct sshkey *key, - struct sshbuf *buf, u_int32_t maxsign, int); - void sshkey_sig_details_free(struct sshkey_sig_details *); #ifdef WITH_OPENSSL @@ -351,7 +331,6 @@ int check_rsa_length(const RSA *rsa); /* XXX remove */ #if !defined(WITH_OPENSSL) # undef RSA -# undef DSA # undef EC_KEY # undef EC_GROUP # undef EC_POINT diff --git a/sshlogin.c b/sshlogin.c index 06a7b38..fb55cad 100644 --- a/sshlogin.c +++ b/sshlogin.c @@ -106,7 +106,7 @@ store_lastlog_message(const char *user, uid_t uid) if (time_string != NULL) { if ((r = sshbuf_put(loginmsg, time_string, strlen(time_string))) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal_fr(r, "buffer error"); free(time_string); } # else diff --git a/sshpty.c b/sshpty.c index cae0b97..0a82b7d 100644 --- a/sshpty.c +++ b/sshpty.c @@ -22,18 +22,14 @@ #include #include #include -#ifdef HAVE_PATHS_H -# include -#endif +#include #include #include #include #include #include -#ifdef HAVE_UTIL_H -# include -#endif #include +#include #include "sshpty.h" #include "log.h" @@ -173,7 +169,7 @@ pty_setowner(struct passwd *pw, const char *tty) /* Determine the group to make the owner of the tty. */ grp = getgrnam("tty"); if (grp == NULL) - debug("%s: no tty group", __func__); + debug_f("no tty group"); gid = (grp != NULL) ? grp->gr_gid : pw->pw_gid; mode = (grp != NULL) ? 0620 : 0600; diff --git a/sshsig.c b/sshsig.c index 057e1df..3789c43 100644 --- a/sshsig.c +++ b/sshsig.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshsig.c,v 1.35 2024/03/08 22:16:32 djm Exp $ */ +/* $OpenBSD: sshsig.c,v 1.40 2025/09/25 06:23:19 jsg Exp $ */ /* * Copyright (c) 2019 Google LLC * @@ -40,9 +40,9 @@ #define MAGIC_PREAMBLE_LEN (sizeof(MAGIC_PREAMBLE) - 1) #define BEGIN_SIGNATURE "-----BEGIN SSH SIGNATURE-----" #define END_SIGNATURE "-----END SSH SIGNATURE-----" -#define RSA_SIGN_ALG "rsa-sha2-512" /* XXX maybe make configurable */ +#define RSA_SIGN_ALG "rsa-sha2-512" #define RSA_SIGN_ALLOWED "rsa-sha2-512,rsa-sha2-256" -#define HASHALG_DEFAULT "sha512" /* XXX maybe make configurable */ +#define HASHALG_DEFAULT "sha512" #define HASHALG_ALLOWED "sha256,sha512" int @@ -190,8 +190,13 @@ sshsig_wrap_sign(struct sshkey *key, const char *hashalg, } /* If using RSA keys then default to a good signature algorithm */ - if (sshkey_type_plain(key->type) == KEY_RSA) + if (sshkey_type_plain(key->type) == KEY_RSA) { sign_alg = RSA_SIGN_ALG; + if (strcmp(hashalg, "sha256") == 0) + sign_alg = "rsa-sha2-256"; + else if (strcmp(hashalg, "sha512") == 0) + sign_alg = "rsa-sha2-512"; + } if (signer != NULL) { if ((r = signer(key, &sig, &slen, @@ -1118,11 +1123,12 @@ sshsig_match_principals(const char *path, const char *principal, linesize = 0; } fclose(f); + free(line); if (ret == 0) { if (nprincipals == 0) ret = SSH_ERR_KEY_NOT_FOUND; - if (nprincipalsp != 0) + if (nprincipalsp != NULL) *nprincipalsp = nprincipals; if (principalsp != NULL) { *principalsp = principals; diff --git a/uidswap.c b/uidswap.c index 6ed3024..793688e 100644 --- a/uidswap.c +++ b/uidswap.c @@ -163,9 +163,9 @@ restore_uid(void) * as well. */ if (setuid(getuid()) == -1) - fatal("%s: setuid failed: %s", __func__, strerror(errno)); + fatal_f("setuid failed: %s", strerror(errno)); if (setgid(getgid()) == -1) - fatal("%s: setgid failed: %s", __func__, strerror(errno)); + fatal_f("setgid failed: %s", strerror(errno)); #endif /* SAVED_IDS_WORK_WITH_SETEUID */ if (setgroups(saved_egroupslen, saved_egroups) == -1) @@ -212,7 +212,7 @@ permanently_set_uid(struct passwd *pw) /* Try restoration of GID if changed (test clearing of saved gid) */ if (old_gid != pw->pw_gid && pw->pw_uid != 0 && (setgid(old_gid) != -1 || setegid(old_gid) != -1)) - fatal("%s: was able to restore old [e]gid", __func__); + fatal_f("was able to restore old [e]gid"); #endif /* Verify GID drop was successful */ @@ -226,7 +226,7 @@ permanently_set_uid(struct passwd *pw) /* Try restoration of UID if changed (test clearing of saved uid) */ if (old_uid != pw->pw_uid && (setuid(old_uid) != -1 || seteuid(old_uid) != -1)) - fatal("%s: was able to restore old [e]uid", __func__); + fatal_f("was able to restore old [e]uid"); #endif /* Verify UID drop was successful */ diff --git a/umac.c b/umac.c index d5958ba..8d6e164 100644 --- a/umac.c +++ b/umac.c @@ -1,4 +1,4 @@ -/* $OpenBSD: umac.c,v 1.23 2023/03/07 01:30:52 djm Exp $ */ +/* $OpenBSD: umac.c,v 1.27 2025/09/05 10:34:35 dtucker Exp $ */ /* ----------------------------------------------------------------------- * * umac.c -- C Implementation UMAC Message Authentication @@ -6,7 +6,7 @@ * Version 0.93b of rfc4418.txt -- 2006 July 18 * * For a full description of UMAC message authentication see the UMAC - * world-wide-web page at http://www.cs.ucdavis.edu/~rogaway/umac + * world-wide-web page at https://fastcrypto.org/umac/ * Please report bugs and suggestions to the UMAC webpage. * * Copyright (c) 1999-2006 Ted Krovetz @@ -72,10 +72,13 @@ /* ---------------------------------------------------------------------- */ #include "includes.h" + #include +#include #include #include #include +#include #include #include @@ -1089,7 +1092,7 @@ static int uhash_update(uhash_ctx_t ctx, const u_char *input, long len) } /* pass remaining < L1_KEY_LEN bytes of input data to NH */ - if (len) { + if (len > 0 && (unsigned long)len <= UINT32_MAX) { nh_update(&ctx->hash, (const UINT8 *)input, len); ctx->msg_len += len; } diff --git a/version.h b/version.h index 9bd910a..086cdba 100644 --- a/version.h +++ b/version.h @@ -1,6 +1,6 @@ -/* $OpenBSD: version.h,v 1.103 2024/09/19 22:17:44 djm Exp $ */ +/* $OpenBSD: version.h,v 1.107 2025/10/08 00:32:52 djm Exp $ */ -#define SSH_VERSION "OpenSSH_9.9" +#define SSH_VERSION "OpenSSH_10.2" -#define SSH_PORTABLE "p2" +#define SSH_PORTABLE "p1" #define SSH_RELEASE SSH_VERSION SSH_PORTABLE diff --git a/xmalloc.c b/xmalloc.c index 67191e3..a058f08 100644 --- a/xmalloc.c +++ b/xmalloc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: xmalloc.c,v 1.37 2022/03/13 23:27:54 cheloha Exp $ */ +/* $OpenBSD: xmalloc.c,v 1.38 2025/05/23 00:40:45 deraadt Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -16,9 +16,7 @@ #include "includes.h" #include -#ifdef HAVE_STDINT_H -# include -#endif +#include #include #include #include @@ -27,7 +25,7 @@ #include "log.h" #if defined(__OpenBSD__) -char *malloc_options = "S"; +const char * const malloc_options = "S"; #endif /* __OpenBSD__ */ void * diff --git a/xmss_commons.c b/xmss_commons.c deleted file mode 100644 index 8d6b80b..0000000 --- a/xmss_commons.c +++ /dev/null @@ -1,36 +0,0 @@ -/* $OpenBSD: xmss_commons.c,v 1.2 2018/02/26 03:56:44 dtucker Exp $ */ -/* -xmss_commons.c 20160722 -Andreas Hülsing -Joost Rijneveld -Public domain. -*/ - -#include "includes.h" -#ifdef WITH_XMSS - -#include "xmss_commons.h" -#include -#include -#ifdef HAVE_STDINT_H -# include -#endif - -void to_byte(unsigned char *out, unsigned long long in, uint32_t bytes) -{ - int32_t i; - for (i = bytes-1; i >= 0; i--) { - out[i] = in & 0xff; - in = in >> 8; - } -} - -#if 0 -void hexdump(const unsigned char *a, size_t len) -{ - size_t i; - for (i = 0; i < len; i++) - printf("%02x", a[i]); -} -#endif -#endif /* WITH_XMSS */ diff --git a/xmss_commons.h b/xmss_commons.h deleted file mode 100644 index a98e479..0000000 --- a/xmss_commons.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifdef WITH_XMSS -/* $OpenBSD: xmss_commons.h,v 1.3 2018/02/26 03:56:44 dtucker Exp $ */ -/* -xmss_commons.h 20160722 -Andreas Hülsing -Joost Rijneveld -Public domain. -*/ -#ifndef XMSS_COMMONS_H -#define XMSS_COMMONS_H - -#include -#ifdef HAVE_STDINT_H -#include -#endif -#endif -void to_byte(unsigned char *output, unsigned long long in, uint32_t bytes); -#if 0 -void hexdump(const unsigned char *a, size_t len); -#endif -#endif /* WITH_XMSS */ diff --git a/xmss_fast.c b/xmss_fast.c deleted file mode 100644 index 421b39a..0000000 --- a/xmss_fast.c +++ /dev/null @@ -1,1106 +0,0 @@ -/* $OpenBSD: xmss_fast.c,v 1.3 2018/03/22 07:06:11 markus Exp $ */ -/* -xmss_fast.c version 20160722 -Andreas Hülsing -Joost Rijneveld -Public domain. -*/ - -#include "includes.h" -#ifdef WITH_XMSS - -#include -#include -#ifdef HAVE_STDINT_H -# include -#endif - -#include "xmss_fast.h" -#include "crypto_api.h" -#include "xmss_wots.h" -#include "xmss_hash.h" - -#include "xmss_commons.h" -#include "xmss_hash_address.h" -// For testing -#include "stdio.h" - - - -/** - * Used for pseudorandom keygeneration, - * generates the seed for the WOTS keypair at address addr - * - * takes n byte sk_seed and returns n byte seed using 32 byte address addr. - */ -static void get_seed(unsigned char *seed, const unsigned char *sk_seed, int n, uint32_t addr[8]) -{ - unsigned char bytes[32]; - // Make sure that chain addr, hash addr, and key bit are 0! - setChainADRS(addr,0); - setHashADRS(addr,0); - setKeyAndMask(addr,0); - // Generate pseudorandom value - addr_to_byte(bytes, addr); - prf(seed, bytes, sk_seed, n); -} - -/** - * Initialize xmss params struct - * parameter names are the same as in the draft - * parameter k is K as used in the BDS algorithm - */ -int xmss_set_params(xmss_params *params, int n, int h, int w, int k) -{ - if (k >= h || k < 2 || (h - k) % 2) { - fprintf(stderr, "For BDS traversal, H - K must be even, with H > K >= 2!\n"); - return 1; - } - params->h = h; - params->n = n; - params->k = k; - wots_params wots_par; - wots_set_params(&wots_par, n, w); - params->wots_par = wots_par; - return 0; -} - -/** - * Initialize BDS state struct - * parameter names are the same as used in the description of the BDS traversal - */ -void xmss_set_bds_state(bds_state *state, unsigned char *stack, int stackoffset, unsigned char *stacklevels, unsigned char *auth, unsigned char *keep, treehash_inst *treehash, unsigned char *retain, int next_leaf) -{ - state->stack = stack; - state->stackoffset = stackoffset; - state->stacklevels = stacklevels; - state->auth = auth; - state->keep = keep; - state->treehash = treehash; - state->retain = retain; - state->next_leaf = next_leaf; -} - -/** - * Initialize xmssmt_params struct - * parameter names are the same as in the draft - * - * Especially h is the total tree height, i.e. the XMSS trees have height h/d - */ -int xmssmt_set_params(xmssmt_params *params, int n, int h, int d, int w, int k) -{ - if (h % d) { - fprintf(stderr, "d must divide h without remainder!\n"); - return 1; - } - params->h = h; - params->d = d; - params->n = n; - params->index_len = (h + 7) / 8; - xmss_params xmss_par; - if (xmss_set_params(&xmss_par, n, (h/d), w, k)) { - return 1; - } - params->xmss_par = xmss_par; - return 0; -} - -/** - * Computes a leaf from a WOTS public key using an L-tree. - */ -static void l_tree(unsigned char *leaf, unsigned char *wots_pk, const xmss_params *params, const unsigned char *pub_seed, uint32_t addr[8]) -{ - unsigned int l = params->wots_par.len; - unsigned int n = params->n; - uint32_t i = 0; - uint32_t height = 0; - uint32_t bound; - - //ADRS.setTreeHeight(0); - setTreeHeight(addr, height); - - while (l > 1) { - bound = l >> 1; //floor(l / 2); - for (i = 0; i < bound; i++) { - //ADRS.setTreeIndex(i); - setTreeIndex(addr, i); - //wots_pk[i] = RAND_HASH(pk[2i], pk[2i + 1], SEED, ADRS); - hash_h(wots_pk+i*n, wots_pk+i*2*n, pub_seed, addr, n); - } - //if ( l % 2 == 1 ) { - if (l & 1) { - //pk[floor(l / 2) + 1] = pk[l]; - memcpy(wots_pk+(l>>1)*n, wots_pk+(l-1)*n, n); - //l = ceil(l / 2); - l=(l>>1)+1; - } - else { - //l = ceil(l / 2); - l=(l>>1); - } - //ADRS.setTreeHeight(ADRS.getTreeHeight() + 1); - height++; - setTreeHeight(addr, height); - } - //return pk[0]; - memcpy(leaf, wots_pk, n); -} - -/** - * Computes the leaf at a given address. First generates the WOTS key pair, then computes leaf using l_tree. As this happens position independent, we only require that addr encodes the right ltree-address. - */ -static void gen_leaf_wots(unsigned char *leaf, const unsigned char *sk_seed, const xmss_params *params, const unsigned char *pub_seed, uint32_t ltree_addr[8], uint32_t ots_addr[8]) -{ - unsigned char seed[params->n]; - unsigned char pk[params->wots_par.keysize]; - - get_seed(seed, sk_seed, params->n, ots_addr); - wots_pkgen(pk, seed, &(params->wots_par), pub_seed, ots_addr); - - l_tree(leaf, pk, params, pub_seed, ltree_addr); -} - -static int treehash_minheight_on_stack(bds_state* state, const xmss_params *params, const treehash_inst *treehash) { - unsigned int r = params->h, i; - for (i = 0; i < treehash->stackusage; i++) { - if (state->stacklevels[state->stackoffset - i - 1] < r) { - r = state->stacklevels[state->stackoffset - i - 1]; - } - } - return r; -} - -/** - * Merkle's TreeHash algorithm. The address only needs to initialize the first 78 bits of addr. Everything else will be set by treehash. - * Currently only used for key generation. - * - */ -static void treehash_setup(unsigned char *node, int height, int index, bds_state *state, const unsigned char *sk_seed, const xmss_params *params, const unsigned char *pub_seed, const uint32_t addr[8]) -{ - unsigned int idx = index; - unsigned int n = params->n; - unsigned int h = params->h; - unsigned int k = params->k; - // use three different addresses because at this point we use all three formats in parallel - uint32_t ots_addr[8]; - uint32_t ltree_addr[8]; - uint32_t node_addr[8]; - // only copy layer and tree address parts - memcpy(ots_addr, addr, 12); - // type = ots - setType(ots_addr, 0); - memcpy(ltree_addr, addr, 12); - setType(ltree_addr, 1); - memcpy(node_addr, addr, 12); - setType(node_addr, 2); - - uint32_t lastnode, i; - unsigned char stack[(height+1)*n]; - unsigned int stacklevels[height+1]; - unsigned int stackoffset=0; - unsigned int nodeh; - - lastnode = idx+(1<treehash[i].h = i; - state->treehash[i].completed = 1; - state->treehash[i].stackusage = 0; - } - - i = 0; - for (; idx < lastnode; idx++) { - setLtreeADRS(ltree_addr, idx); - setOTSADRS(ots_addr, idx); - gen_leaf_wots(stack+stackoffset*n, sk_seed, params, pub_seed, ltree_addr, ots_addr); - stacklevels[stackoffset] = 0; - stackoffset++; - if (h - k > 0 && i == 3) { - memcpy(state->treehash[0].node, stack+stackoffset*n, n); - } - while (stackoffset>1 && stacklevels[stackoffset-1] == stacklevels[stackoffset-2]) - { - nodeh = stacklevels[stackoffset-1]; - if (i >> nodeh == 1) { - memcpy(state->auth + nodeh*n, stack+(stackoffset-1)*n, n); - } - else { - if (nodeh < h - k && i >> nodeh == 3) { - memcpy(state->treehash[nodeh].node, stack+(stackoffset-1)*n, n); - } - else if (nodeh >= h - k) { - memcpy(state->retain + ((1 << (h - 1 - nodeh)) + nodeh - h + (((i >> nodeh) - 3) >> 1)) * n, stack+(stackoffset-1)*n, n); - } - } - setTreeHeight(node_addr, stacklevels[stackoffset-1]); - setTreeIndex(node_addr, (idx >> (stacklevels[stackoffset-1]+1))); - hash_h(stack+(stackoffset-2)*n, stack+(stackoffset-2)*n, pub_seed, - node_addr, n); - stacklevels[stackoffset-2]++; - stackoffset--; - } - i++; - } - - for (i = 0; i < n; i++) - node[i] = stack[i]; -} - -static void treehash_update(treehash_inst *treehash, bds_state *state, const unsigned char *sk_seed, const xmss_params *params, const unsigned char *pub_seed, const uint32_t addr[8]) { - int n = params->n; - - uint32_t ots_addr[8]; - uint32_t ltree_addr[8]; - uint32_t node_addr[8]; - // only copy layer and tree address parts - memcpy(ots_addr, addr, 12); - // type = ots - setType(ots_addr, 0); - memcpy(ltree_addr, addr, 12); - setType(ltree_addr, 1); - memcpy(node_addr, addr, 12); - setType(node_addr, 2); - - setLtreeADRS(ltree_addr, treehash->next_idx); - setOTSADRS(ots_addr, treehash->next_idx); - - unsigned char nodebuffer[2 * n]; - unsigned int nodeheight = 0; - gen_leaf_wots(nodebuffer, sk_seed, params, pub_seed, ltree_addr, ots_addr); - while (treehash->stackusage > 0 && state->stacklevels[state->stackoffset-1] == nodeheight) { - memcpy(nodebuffer + n, nodebuffer, n); - memcpy(nodebuffer, state->stack + (state->stackoffset-1)*n, n); - setTreeHeight(node_addr, nodeheight); - setTreeIndex(node_addr, (treehash->next_idx >> (nodeheight+1))); - hash_h(nodebuffer, nodebuffer, pub_seed, node_addr, n); - nodeheight++; - treehash->stackusage--; - state->stackoffset--; - } - if (nodeheight == treehash->h) { // this also implies stackusage == 0 - memcpy(treehash->node, nodebuffer, n); - treehash->completed = 1; - } - else { - memcpy(state->stack + state->stackoffset*n, nodebuffer, n); - treehash->stackusage++; - state->stacklevels[state->stackoffset] = nodeheight; - state->stackoffset++; - treehash->next_idx++; - } -} - -/** - * Computes a root node given a leaf and an authapth - */ -static void validate_authpath(unsigned char *root, const unsigned char *leaf, unsigned long leafidx, const unsigned char *authpath, const xmss_params *params, const unsigned char *pub_seed, uint32_t addr[8]) -{ - unsigned int n = params->n; - - uint32_t i, j; - unsigned char buffer[2*n]; - - // If leafidx is odd (last bit = 1), current path element is a right child and authpath has to go to the left. - // Otherwise, it is the other way around - if (leafidx & 1) { - for (j = 0; j < n; j++) - buffer[n+j] = leaf[j]; - for (j = 0; j < n; j++) - buffer[j] = authpath[j]; - } - else { - for (j = 0; j < n; j++) - buffer[j] = leaf[j]; - for (j = 0; j < n; j++) - buffer[n+j] = authpath[j]; - } - authpath += n; - - for (i=0; i < params->h-1; i++) { - setTreeHeight(addr, i); - leafidx >>= 1; - setTreeIndex(addr, leafidx); - if (leafidx&1) { - hash_h(buffer+n, buffer, pub_seed, addr, n); - for (j = 0; j < n; j++) - buffer[j] = authpath[j]; - } - else { - hash_h(buffer, buffer, pub_seed, addr, n); - for (j = 0; j < n; j++) - buffer[j+n] = authpath[j]; - } - authpath += n; - } - setTreeHeight(addr, (params->h-1)); - leafidx >>= 1; - setTreeIndex(addr, leafidx); - hash_h(root, buffer, pub_seed, addr, n); -} - -/** - * Performs one treehash update on the instance that needs it the most. - * Returns 1 if such an instance was not found - **/ -static char bds_treehash_update(bds_state *state, unsigned int updates, const unsigned char *sk_seed, const xmss_params *params, unsigned char *pub_seed, const uint32_t addr[8]) { - uint32_t i, j; - unsigned int level, l_min, low; - unsigned int h = params->h; - unsigned int k = params->k; - unsigned int used = 0; - - for (j = 0; j < updates; j++) { - l_min = h; - level = h - k; - for (i = 0; i < h - k; i++) { - if (state->treehash[i].completed) { - low = h; - } - else if (state->treehash[i].stackusage == 0) { - low = i; - } - else { - low = treehash_minheight_on_stack(state, params, &(state->treehash[i])); - } - if (low < l_min) { - level = i; - l_min = low; - } - } - if (level == h - k) { - break; - } - treehash_update(&(state->treehash[level]), state, sk_seed, params, pub_seed, addr); - used++; - } - return updates - used; -} - -/** - * Updates the state (typically NEXT_i) by adding a leaf and updating the stack - * Returns 1 if all leaf nodes have already been processed - **/ -static char bds_state_update(bds_state *state, const unsigned char *sk_seed, const xmss_params *params, unsigned char *pub_seed, const uint32_t addr[8]) { - uint32_t ltree_addr[8]; - uint32_t node_addr[8]; - uint32_t ots_addr[8]; - - int n = params->n; - int h = params->h; - int k = params->k; - - int nodeh; - int idx = state->next_leaf; - if (idx == 1 << h) { - return 1; - } - - // only copy layer and tree address parts - memcpy(ots_addr, addr, 12); - // type = ots - setType(ots_addr, 0); - memcpy(ltree_addr, addr, 12); - setType(ltree_addr, 1); - memcpy(node_addr, addr, 12); - setType(node_addr, 2); - - setOTSADRS(ots_addr, idx); - setLtreeADRS(ltree_addr, idx); - - gen_leaf_wots(state->stack+state->stackoffset*n, sk_seed, params, pub_seed, ltree_addr, ots_addr); - - state->stacklevels[state->stackoffset] = 0; - state->stackoffset++; - if (h - k > 0 && idx == 3) { - memcpy(state->treehash[0].node, state->stack+state->stackoffset*n, n); - } - while (state->stackoffset>1 && state->stacklevels[state->stackoffset-1] == state->stacklevels[state->stackoffset-2]) { - nodeh = state->stacklevels[state->stackoffset-1]; - if (idx >> nodeh == 1) { - memcpy(state->auth + nodeh*n, state->stack+(state->stackoffset-1)*n, n); - } - else { - if (nodeh < h - k && idx >> nodeh == 3) { - memcpy(state->treehash[nodeh].node, state->stack+(state->stackoffset-1)*n, n); - } - else if (nodeh >= h - k) { - memcpy(state->retain + ((1 << (h - 1 - nodeh)) + nodeh - h + (((idx >> nodeh) - 3) >> 1)) * n, state->stack+(state->stackoffset-1)*n, n); - } - } - setTreeHeight(node_addr, state->stacklevels[state->stackoffset-1]); - setTreeIndex(node_addr, (idx >> (state->stacklevels[state->stackoffset-1]+1))); - hash_h(state->stack+(state->stackoffset-2)*n, state->stack+(state->stackoffset-2)*n, pub_seed, node_addr, n); - - state->stacklevels[state->stackoffset-2]++; - state->stackoffset--; - } - state->next_leaf++; - return 0; -} - -/** - * Returns the auth path for node leaf_idx and computes the auth path for the - * next leaf node, using the algorithm described by Buchmann, Dahmen and Szydlo - * in "Post Quantum Cryptography", Springer 2009. - */ -static void bds_round(bds_state *state, const unsigned long leaf_idx, const unsigned char *sk_seed, const xmss_params *params, unsigned char *pub_seed, uint32_t addr[8]) -{ - unsigned int i; - unsigned int n = params->n; - unsigned int h = params->h; - unsigned int k = params->k; - - unsigned int tau = h; - unsigned int startidx; - unsigned int offset, rowidx; - unsigned char buf[2 * n]; - - uint32_t ots_addr[8]; - uint32_t ltree_addr[8]; - uint32_t node_addr[8]; - // only copy layer and tree address parts - memcpy(ots_addr, addr, 12); - // type = ots - setType(ots_addr, 0); - memcpy(ltree_addr, addr, 12); - setType(ltree_addr, 1); - memcpy(node_addr, addr, 12); - setType(node_addr, 2); - - for (i = 0; i < h; i++) { - if (! ((leaf_idx >> i) & 1)) { - tau = i; - break; - } - } - - if (tau > 0) { - memcpy(buf, state->auth + (tau-1) * n, n); - // we need to do this before refreshing state->keep to prevent overwriting - memcpy(buf + n, state->keep + ((tau-1) >> 1) * n, n); - } - if (!((leaf_idx >> (tau + 1)) & 1) && (tau < h - 1)) { - memcpy(state->keep + (tau >> 1)*n, state->auth + tau*n, n); - } - if (tau == 0) { - setLtreeADRS(ltree_addr, leaf_idx); - setOTSADRS(ots_addr, leaf_idx); - gen_leaf_wots(state->auth, sk_seed, params, pub_seed, ltree_addr, ots_addr); - } - else { - setTreeHeight(node_addr, (tau-1)); - setTreeIndex(node_addr, leaf_idx >> tau); - hash_h(state->auth + tau * n, buf, pub_seed, node_addr, n); - for (i = 0; i < tau; i++) { - if (i < h - k) { - memcpy(state->auth + i * n, state->treehash[i].node, n); - } - else { - offset = (1 << (h - 1 - i)) + i - h; - rowidx = ((leaf_idx >> i) - 1) >> 1; - memcpy(state->auth + i * n, state->retain + (offset + rowidx) * n, n); - } - } - - for (i = 0; i < ((tau < h - k) ? tau : (h - k)); i++) { - startidx = leaf_idx + 1 + 3 * (1 << i); - if (startidx < 1U << h) { - state->treehash[i].h = i; - state->treehash[i].next_idx = startidx; - state->treehash[i].completed = 0; - state->treehash[i].stackusage = 0; - } - } - } -} - -/* - * Generates a XMSS key pair for a given parameter set. - * Format sk: [(32bit) idx || SK_SEED || SK_PRF || PUB_SEED || root] - * Format pk: [root || PUB_SEED] omitting algo oid. - */ -int xmss_keypair(unsigned char *pk, unsigned char *sk, bds_state *state, xmss_params *params) -{ - unsigned int n = params->n; - // Set idx = 0 - sk[0] = 0; - sk[1] = 0; - sk[2] = 0; - sk[3] = 0; - // Init SK_SEED (n byte), SK_PRF (n byte), and PUB_SEED (n byte) - randombytes(sk+4, 3*n); - // Copy PUB_SEED to public key - memcpy(pk+n, sk+4+2*n, n); - - uint32_t addr[8] = {0, 0, 0, 0, 0, 0, 0, 0}; - - // Compute root - treehash_setup(pk, params->h, 0, state, sk+4, params, sk+4+2*n, addr); - // copy root to sk - memcpy(sk+4+3*n, pk, n); - return 0; -} - -/** - * Signs a message. - * Returns - * 1. an array containing the signature followed by the message AND - * 2. an updated secret key! - * - */ -int xmss_sign(unsigned char *sk, bds_state *state, unsigned char *sig_msg, unsigned long long *sig_msg_len, const unsigned char *msg, unsigned long long msglen, const xmss_params *params) -{ - unsigned int h = params->h; - unsigned int n = params->n; - unsigned int k = params->k; - uint16_t i = 0; - - // Extract SK - unsigned long idx = ((unsigned long)sk[0] << 24) | ((unsigned long)sk[1] << 16) | ((unsigned long)sk[2] << 8) | sk[3]; - unsigned char sk_seed[n]; - memcpy(sk_seed, sk+4, n); - unsigned char sk_prf[n]; - memcpy(sk_prf, sk+4+n, n); - unsigned char pub_seed[n]; - memcpy(pub_seed, sk+4+2*n, n); - - // index as 32 bytes string - unsigned char idx_bytes_32[32]; - to_byte(idx_bytes_32, idx, 32); - - unsigned char hash_key[3*n]; - - // Update SK - sk[0] = ((idx + 1) >> 24) & 255; - sk[1] = ((idx + 1) >> 16) & 255; - sk[2] = ((idx + 1) >> 8) & 255; - sk[3] = (idx + 1) & 255; - // -- Secret key for this non-forward-secure version is now updated. - // -- A productive implementation should use a file handle instead and write the updated secret key at this point! - - // Init working params - unsigned char R[n]; - unsigned char msg_h[n]; - unsigned char ots_seed[n]; - uint32_t ots_addr[8] = {0, 0, 0, 0, 0, 0, 0, 0}; - - // --------------------------------- - // Message Hashing - // --------------------------------- - - // Message Hash: - // First compute pseudorandom value - prf(R, idx_bytes_32, sk_prf, n); - // Generate hash key (R || root || idx) - memcpy(hash_key, R, n); - memcpy(hash_key+n, sk+4+3*n, n); - to_byte(hash_key+2*n, idx, n); - // Then use it for message digest - h_msg(msg_h, msg, msglen, hash_key, 3*n, n); - - // Start collecting signature - *sig_msg_len = 0; - - // Copy index to signature - sig_msg[0] = (idx >> 24) & 255; - sig_msg[1] = (idx >> 16) & 255; - sig_msg[2] = (idx >> 8) & 255; - sig_msg[3] = idx & 255; - - sig_msg += 4; - *sig_msg_len += 4; - - // Copy R to signature - for (i = 0; i < n; i++) - sig_msg[i] = R[i]; - - sig_msg += n; - *sig_msg_len += n; - - // ---------------------------------- - // Now we start to "really sign" - // ---------------------------------- - - // Prepare Address - setType(ots_addr, 0); - setOTSADRS(ots_addr, idx); - - // Compute seed for OTS key pair - get_seed(ots_seed, sk_seed, n, ots_addr); - - // Compute WOTS signature - wots_sign(sig_msg, msg_h, ots_seed, &(params->wots_par), pub_seed, ots_addr); - - sig_msg += params->wots_par.keysize; - *sig_msg_len += params->wots_par.keysize; - - // the auth path was already computed during the previous round - memcpy(sig_msg, state->auth, h*n); - - if (idx < (1U << h) - 1) { - bds_round(state, idx, sk_seed, params, pub_seed, ots_addr); - bds_treehash_update(state, (h - k) >> 1, sk_seed, params, pub_seed, ots_addr); - } - -/* TODO: save key/bds state here! */ - - sig_msg += params->h*n; - *sig_msg_len += params->h*n; - - //Whipe secret elements? - //zerobytes(tsk, CRYPTO_SECRETKEYBYTES); - - - memcpy(sig_msg, msg, msglen); - *sig_msg_len += msglen; - - return 0; -} - -/** - * Verifies a given message signature pair under a given public key. - */ -int xmss_sign_open(unsigned char *msg, unsigned long long *msglen, const unsigned char *sig_msg, unsigned long long sig_msg_len, const unsigned char *pk, const xmss_params *params) -{ - unsigned int n = params->n; - - unsigned long long i, m_len; - unsigned long idx=0; - unsigned char wots_pk[params->wots_par.keysize]; - unsigned char pkhash[n]; - unsigned char root[n]; - unsigned char msg_h[n]; - unsigned char hash_key[3*n]; - - unsigned char pub_seed[n]; - memcpy(pub_seed, pk+n, n); - - // Init addresses - uint32_t ots_addr[8] = {0, 0, 0, 0, 0, 0, 0, 0}; - uint32_t ltree_addr[8] = {0, 0, 0, 0, 0, 0, 0, 0}; - uint32_t node_addr[8] = {0, 0, 0, 0, 0, 0, 0, 0}; - - setType(ots_addr, 0); - setType(ltree_addr, 1); - setType(node_addr, 2); - - // Extract index - idx = ((unsigned long)sig_msg[0] << 24) | ((unsigned long)sig_msg[1] << 16) | ((unsigned long)sig_msg[2] << 8) | sig_msg[3]; - printf("verify:: idx = %lu\n", idx); - - // Generate hash key (R || root || idx) - memcpy(hash_key, sig_msg+4,n); - memcpy(hash_key+n, pk, n); - to_byte(hash_key+2*n, idx, n); - - sig_msg += (n+4); - sig_msg_len -= (n+4); - - // hash message - unsigned long long tmp_sig_len = params->wots_par.keysize+params->h*n; - m_len = sig_msg_len - tmp_sig_len; - h_msg(msg_h, sig_msg + tmp_sig_len, m_len, hash_key, 3*n, n); - - //----------------------- - // Verify signature - //----------------------- - - // Prepare Address - setOTSADRS(ots_addr, idx); - // Check WOTS signature - wots_pkFromSig(wots_pk, sig_msg, msg_h, &(params->wots_par), pub_seed, ots_addr); - - sig_msg += params->wots_par.keysize; - sig_msg_len -= params->wots_par.keysize; - - // Compute Ltree - setLtreeADRS(ltree_addr, idx); - l_tree(pkhash, wots_pk, params, pub_seed, ltree_addr); - - // Compute root - validate_authpath(root, pkhash, idx, sig_msg, params, pub_seed, node_addr); - - sig_msg += params->h*n; - sig_msg_len -= params->h*n; - - for (i = 0; i < n; i++) - if (root[i] != pk[i]) - goto fail; - - *msglen = sig_msg_len; - for (i = 0; i < *msglen; i++) - msg[i] = sig_msg[i]; - - return 0; - - -fail: - *msglen = sig_msg_len; - for (i = 0; i < *msglen; i++) - msg[i] = 0; - *msglen = -1; - return -1; -} - -/* - * Generates a XMSSMT key pair for a given parameter set. - * Format sk: [(ceil(h/8) bit) idx || SK_SEED || SK_PRF || PUB_SEED || root] - * Format pk: [root || PUB_SEED] omitting algo oid. - */ -int xmssmt_keypair(unsigned char *pk, unsigned char *sk, bds_state *states, unsigned char *wots_sigs, xmssmt_params *params) -{ - unsigned int n = params->n; - unsigned int i; - unsigned char ots_seed[params->n]; - // Set idx = 0 - for (i = 0; i < params->index_len; i++) { - sk[i] = 0; - } - // Init SK_SEED (n byte), SK_PRF (n byte), and PUB_SEED (n byte) - randombytes(sk+params->index_len, 3*n); - // Copy PUB_SEED to public key - memcpy(pk+n, sk+params->index_len+2*n, n); - - // Set address to point on the single tree on layer d-1 - uint32_t addr[8] = {0, 0, 0, 0, 0, 0, 0, 0}; - setLayerADRS(addr, (params->d-1)); - // Set up state and compute wots signatures for all but topmost tree root - for (i = 0; i < params->d - 1; i++) { - // Compute seed for OTS key pair - treehash_setup(pk, params->xmss_par.h, 0, states + i, sk+params->index_len, &(params->xmss_par), pk+n, addr); - setLayerADRS(addr, (i+1)); - get_seed(ots_seed, sk+params->index_len, n, addr); - wots_sign(wots_sigs + i*params->xmss_par.wots_par.keysize, pk, ots_seed, &(params->xmss_par.wots_par), pk+n, addr); - } - treehash_setup(pk, params->xmss_par.h, 0, states + i, sk+params->index_len, &(params->xmss_par), pk+n, addr); - memcpy(sk+params->index_len+3*n, pk, n); - return 0; -} - -/** - * Signs a message. - * Returns - * 1. an array containing the signature followed by the message AND - * 2. an updated secret key! - * - */ -int xmssmt_sign(unsigned char *sk, bds_state *states, unsigned char *wots_sigs, unsigned char *sig_msg, unsigned long long *sig_msg_len, const unsigned char *msg, unsigned long long msglen, const xmssmt_params *params) -{ - unsigned int n = params->n; - - unsigned int tree_h = params->xmss_par.h; - unsigned int h = params->h; - unsigned int k = params->xmss_par.k; - unsigned int idx_len = params->index_len; - uint64_t idx_tree; - uint32_t idx_leaf; - uint64_t i, j; - int needswap_upto = -1; - unsigned int updates; - - unsigned char sk_seed[n]; - unsigned char sk_prf[n]; - unsigned char pub_seed[n]; - // Init working params - unsigned char R[n]; - unsigned char msg_h[n]; - unsigned char hash_key[3*n]; - unsigned char ots_seed[n]; - uint32_t addr[8] = {0, 0, 0, 0, 0, 0, 0, 0}; - uint32_t ots_addr[8] = {0, 0, 0, 0, 0, 0, 0, 0}; - unsigned char idx_bytes_32[32]; - bds_state tmp; - - // Extract SK - unsigned long long idx = 0; - for (i = 0; i < idx_len; i++) { - idx |= ((unsigned long long)sk[i]) << 8*(idx_len - 1 - i); - } - - memcpy(sk_seed, sk+idx_len, n); - memcpy(sk_prf, sk+idx_len+n, n); - memcpy(pub_seed, sk+idx_len+2*n, n); - - // Update SK - for (i = 0; i < idx_len; i++) { - sk[i] = ((idx + 1) >> 8*(idx_len - 1 - i)) & 255; - } - // -- Secret key for this non-forward-secure version is now updated. - // -- A productive implementation should use a file handle instead and write the updated secret key at this point! - - - // --------------------------------- - // Message Hashing - // --------------------------------- - - // Message Hash: - // First compute pseudorandom value - to_byte(idx_bytes_32, idx, 32); - prf(R, idx_bytes_32, sk_prf, n); - // Generate hash key (R || root || idx) - memcpy(hash_key, R, n); - memcpy(hash_key+n, sk+idx_len+3*n, n); - to_byte(hash_key+2*n, idx, n); - - // Then use it for message digest - h_msg(msg_h, msg, msglen, hash_key, 3*n, n); - - // Start collecting signature - *sig_msg_len = 0; - - // Copy index to signature - for (i = 0; i < idx_len; i++) { - sig_msg[i] = (idx >> 8*(idx_len - 1 - i)) & 255; - } - - sig_msg += idx_len; - *sig_msg_len += idx_len; - - // Copy R to signature - for (i = 0; i < n; i++) - sig_msg[i] = R[i]; - - sig_msg += n; - *sig_msg_len += n; - - // ---------------------------------- - // Now we start to "really sign" - // ---------------------------------- - - // Handle lowest layer separately as it is slightly different... - - // Prepare Address - setType(ots_addr, 0); - idx_tree = idx >> tree_h; - idx_leaf = (idx & ((1 << tree_h)-1)); - setLayerADRS(ots_addr, 0); - setTreeADRS(ots_addr, idx_tree); - setOTSADRS(ots_addr, idx_leaf); - - // Compute seed for OTS key pair - get_seed(ots_seed, sk_seed, n, ots_addr); - - // Compute WOTS signature - wots_sign(sig_msg, msg_h, ots_seed, &(params->xmss_par.wots_par), pub_seed, ots_addr); - - sig_msg += params->xmss_par.wots_par.keysize; - *sig_msg_len += params->xmss_par.wots_par.keysize; - - memcpy(sig_msg, states[0].auth, tree_h*n); - sig_msg += tree_h*n; - *sig_msg_len += tree_h*n; - - // prepare signature of remaining layers - for (i = 1; i < params->d; i++) { - // put WOTS signature in place - memcpy(sig_msg, wots_sigs + (i-1)*params->xmss_par.wots_par.keysize, params->xmss_par.wots_par.keysize); - - sig_msg += params->xmss_par.wots_par.keysize; - *sig_msg_len += params->xmss_par.wots_par.keysize; - - // put AUTH nodes in place - memcpy(sig_msg, states[i].auth, tree_h*n); - sig_msg += tree_h*n; - *sig_msg_len += tree_h*n; - } - - updates = (tree_h - k) >> 1; - - setTreeADRS(addr, (idx_tree + 1)); - // mandatory update for NEXT_0 (does not count towards h-k/2) if NEXT_0 exists - if ((1 + idx_tree) * (1 << tree_h) + idx_leaf < (1ULL << h)) { - bds_state_update(&states[params->d], sk_seed, &(params->xmss_par), pub_seed, addr); - } - - for (i = 0; i < params->d; i++) { - // check if we're not at the end of a tree - if (! (((idx + 1) & ((1ULL << ((i+1)*tree_h)) - 1)) == 0)) { - idx_leaf = (idx >> (tree_h * i)) & ((1 << tree_h)-1); - idx_tree = (idx >> (tree_h * (i+1))); - setLayerADRS(addr, i); - setTreeADRS(addr, idx_tree); - if (i == (unsigned int) (needswap_upto + 1)) { - bds_round(&states[i], idx_leaf, sk_seed, &(params->xmss_par), pub_seed, addr); - } - updates = bds_treehash_update(&states[i], updates, sk_seed, &(params->xmss_par), pub_seed, addr); - setTreeADRS(addr, (idx_tree + 1)); - // if a NEXT-tree exists for this level; - if ((1 + idx_tree) * (1 << tree_h) + idx_leaf < (1ULL << (h - tree_h * i))) { - if (i > 0 && updates > 0 && states[params->d + i].next_leaf < (1ULL << h)) { - bds_state_update(&states[params->d + i], sk_seed, &(params->xmss_par), pub_seed, addr); - updates--; - } - } - } - else if (idx < (1ULL << h) - 1) { - memcpy(&tmp, states+params->d + i, sizeof(bds_state)); - memcpy(states+params->d + i, states + i, sizeof(bds_state)); - memcpy(states + i, &tmp, sizeof(bds_state)); - - setLayerADRS(ots_addr, (i+1)); - setTreeADRS(ots_addr, ((idx + 1) >> ((i+2) * tree_h))); - setOTSADRS(ots_addr, (((idx >> ((i+1) * tree_h)) + 1) & ((1 << tree_h)-1))); - - get_seed(ots_seed, sk+params->index_len, n, ots_addr); - wots_sign(wots_sigs + i*params->xmss_par.wots_par.keysize, states[i].stack, ots_seed, &(params->xmss_par.wots_par), pub_seed, ots_addr); - - states[params->d + i].stackoffset = 0; - states[params->d + i].next_leaf = 0; - - updates--; // WOTS-signing counts as one update - needswap_upto = i; - for (j = 0; j < tree_h-k; j++) { - states[i].treehash[j].completed = 1; - } - } - } - - //Whipe secret elements? - //zerobytes(tsk, CRYPTO_SECRETKEYBYTES); - - memcpy(sig_msg, msg, msglen); - *sig_msg_len += msglen; - - return 0; -} - -/** - * Verifies a given message signature pair under a given public key. - */ -int xmssmt_sign_open(unsigned char *msg, unsigned long long *msglen, const unsigned char *sig_msg, unsigned long long sig_msg_len, const unsigned char *pk, const xmssmt_params *params) -{ - unsigned int n = params->n; - - unsigned int tree_h = params->xmss_par.h; - unsigned int idx_len = params->index_len; - uint64_t idx_tree; - uint32_t idx_leaf; - - unsigned long long i, m_len; - unsigned long long idx=0; - unsigned char wots_pk[params->xmss_par.wots_par.keysize]; - unsigned char pkhash[n]; - unsigned char root[n]; - unsigned char msg_h[n]; - unsigned char hash_key[3*n]; - - unsigned char pub_seed[n]; - memcpy(pub_seed, pk+n, n); - - // Init addresses - uint32_t ots_addr[8] = {0, 0, 0, 0, 0, 0, 0, 0}; - uint32_t ltree_addr[8] = {0, 0, 0, 0, 0, 0, 0, 0}; - uint32_t node_addr[8] = {0, 0, 0, 0, 0, 0, 0, 0}; - - // Extract index - for (i = 0; i < idx_len; i++) { - idx |= ((unsigned long long)sig_msg[i]) << (8*(idx_len - 1 - i)); - } - printf("verify:: idx = %llu\n", idx); - sig_msg += idx_len; - sig_msg_len -= idx_len; - - // Generate hash key (R || root || idx) - memcpy(hash_key, sig_msg,n); - memcpy(hash_key+n, pk, n); - to_byte(hash_key+2*n, idx, n); - - sig_msg += n; - sig_msg_len -= n; - - - // hash message (recall, R is now on pole position at sig_msg - unsigned long long tmp_sig_len = (params->d * params->xmss_par.wots_par.keysize) + (params->h * n); - m_len = sig_msg_len - tmp_sig_len; - h_msg(msg_h, sig_msg + tmp_sig_len, m_len, hash_key, 3*n, n); - - - //----------------------- - // Verify signature - //----------------------- - - // Prepare Address - idx_tree = idx >> tree_h; - idx_leaf = (idx & ((1 << tree_h)-1)); - setLayerADRS(ots_addr, 0); - setTreeADRS(ots_addr, idx_tree); - setType(ots_addr, 0); - - memcpy(ltree_addr, ots_addr, 12); - setType(ltree_addr, 1); - - memcpy(node_addr, ltree_addr, 12); - setType(node_addr, 2); - - setOTSADRS(ots_addr, idx_leaf); - - // Check WOTS signature - wots_pkFromSig(wots_pk, sig_msg, msg_h, &(params->xmss_par.wots_par), pub_seed, ots_addr); - - sig_msg += params->xmss_par.wots_par.keysize; - sig_msg_len -= params->xmss_par.wots_par.keysize; - - // Compute Ltree - setLtreeADRS(ltree_addr, idx_leaf); - l_tree(pkhash, wots_pk, &(params->xmss_par), pub_seed, ltree_addr); - - // Compute root - validate_authpath(root, pkhash, idx_leaf, sig_msg, &(params->xmss_par), pub_seed, node_addr); - - sig_msg += tree_h*n; - sig_msg_len -= tree_h*n; - - for (i = 1; i < params->d; i++) { - // Prepare Address - idx_leaf = (idx_tree & ((1 << tree_h)-1)); - idx_tree = idx_tree >> tree_h; - - setLayerADRS(ots_addr, i); - setTreeADRS(ots_addr, idx_tree); - setType(ots_addr, 0); - - memcpy(ltree_addr, ots_addr, 12); - setType(ltree_addr, 1); - - memcpy(node_addr, ltree_addr, 12); - setType(node_addr, 2); - - setOTSADRS(ots_addr, idx_leaf); - - // Check WOTS signature - wots_pkFromSig(wots_pk, sig_msg, root, &(params->xmss_par.wots_par), pub_seed, ots_addr); - - sig_msg += params->xmss_par.wots_par.keysize; - sig_msg_len -= params->xmss_par.wots_par.keysize; - - // Compute Ltree - setLtreeADRS(ltree_addr, idx_leaf); - l_tree(pkhash, wots_pk, &(params->xmss_par), pub_seed, ltree_addr); - - // Compute root - validate_authpath(root, pkhash, idx_leaf, sig_msg, &(params->xmss_par), pub_seed, node_addr); - - sig_msg += tree_h*n; - sig_msg_len -= tree_h*n; - - } - - for (i = 0; i < n; i++) - if (root[i] != pk[i]) - goto fail; - - *msglen = sig_msg_len; - for (i = 0; i < *msglen; i++) - msg[i] = sig_msg[i]; - - return 0; - - -fail: - *msglen = sig_msg_len; - for (i = 0; i < *msglen; i++) - msg[i] = 0; - *msglen = -1; - return -1; -} -#endif /* WITH_XMSS */ diff --git a/xmss_fast.h b/xmss_fast.h deleted file mode 100644 index 2ffba70..0000000 --- a/xmss_fast.h +++ /dev/null @@ -1,111 +0,0 @@ -#ifdef WITH_XMSS -/* $OpenBSD: xmss_fast.h,v 1.2 2018/02/26 03:56:44 dtucker Exp $ */ -/* -xmss_fast.h version 20160722 -Andreas Hülsing -Joost Rijneveld -Public domain. -*/ - -#include "xmss_wots.h" - -#ifndef XMSS_H -#define XMSS_H -typedef struct{ - unsigned int level; - unsigned long long subtree; - unsigned int subleaf; -} leafaddr; - -typedef struct{ - wots_params wots_par; - unsigned int n; - unsigned int h; - unsigned int k; -} xmss_params; - -typedef struct{ - xmss_params xmss_par; - unsigned int n; - unsigned int h; - unsigned int d; - unsigned int index_len; -} xmssmt_params; - -typedef struct{ - unsigned int h; - unsigned int next_idx; - unsigned int stackusage; - unsigned char completed; - unsigned char *node; -} treehash_inst; - -typedef struct { - unsigned char *stack; - unsigned int stackoffset; - unsigned char *stacklevels; - unsigned char *auth; - unsigned char *keep; - treehash_inst *treehash; - unsigned char *retain; - unsigned int next_leaf; -} bds_state; - -/** - * Initialize BDS state struct - * parameter names are the same as used in the description of the BDS traversal - */ -void xmss_set_bds_state(bds_state *state, unsigned char *stack, int stackoffset, unsigned char *stacklevels, unsigned char *auth, unsigned char *keep, treehash_inst *treehash, unsigned char *retain, int next_leaf); -/** - * Initializes parameter set. - * Needed, for any of the other methods. - */ -int xmss_set_params(xmss_params *params, int n, int h, int w, int k); -/** - * Initialize xmssmt_params struct - * parameter names are the same as in the draft - * - * Especially h is the total tree height, i.e. the XMSS trees have height h/d - */ -int xmssmt_set_params(xmssmt_params *params, int n, int h, int d, int w, int k); -/** - * Generates a XMSS key pair for a given parameter set. - * Format sk: [(32bit) idx || SK_SEED || SK_PRF || PUB_SEED || root] - * Format pk: [root || PUB_SEED] omitting algo oid. - */ -int xmss_keypair(unsigned char *pk, unsigned char *sk, bds_state *state, xmss_params *params); -/** - * Signs a message. - * Returns - * 1. an array containing the signature followed by the message AND - * 2. an updated secret key! - * - */ -int xmss_sign(unsigned char *sk, bds_state *state, unsigned char *sig_msg, unsigned long long *sig_msg_len, const unsigned char *msg,unsigned long long msglen, const xmss_params *params); -/** - * Verifies a given message signature pair under a given public key. - * - * Note: msg and msglen are pure outputs which carry the message in case verification succeeds. The (input) message is assumed to be within sig_msg which has the form (sig||msg). - */ -int xmss_sign_open(unsigned char *msg,unsigned long long *msglen, const unsigned char *sig_msg,unsigned long long sig_msg_len, const unsigned char *pk, const xmss_params *params); - -/* - * Generates a XMSSMT key pair for a given parameter set. - * Format sk: [(ceil(h/8) bit) idx || SK_SEED || SK_PRF || PUB_SEED || root] - * Format pk: [root || PUB_SEED] omitting algo oid. - */ -int xmssmt_keypair(unsigned char *pk, unsigned char *sk, bds_state *states, unsigned char *wots_sigs, xmssmt_params *params); -/** - * Signs a message. - * Returns - * 1. an array containing the signature followed by the message AND - * 2. an updated secret key! - * - */ -int xmssmt_sign(unsigned char *sk, bds_state *state, unsigned char *wots_sigs, unsigned char *sig_msg, unsigned long long *sig_msg_len, const unsigned char *msg, unsigned long long msglen, const xmssmt_params *params); -/** - * Verifies a given message signature pair under a given public key. - */ -int xmssmt_sign_open(unsigned char *msg, unsigned long long *msglen, const unsigned char *sig_msg, unsigned long long sig_msg_len, const unsigned char *pk, const xmssmt_params *params); -#endif -#endif /* WITH_XMSS */ diff --git a/xmss_hash.c b/xmss_hash.c deleted file mode 100644 index 70c126a..0000000 --- a/xmss_hash.c +++ /dev/null @@ -1,137 +0,0 @@ -/* $OpenBSD: xmss_hash.c,v 1.4 2023/12/20 00:06:25 jsg Exp $ */ -/* -hash.c version 20160722 -Andreas Hülsing -Joost Rijneveld -Public domain. -*/ - -#include "includes.h" -#ifdef WITH_XMSS - -#include "xmss_hash_address.h" -#include "xmss_commons.h" -#include "xmss_hash.h" - -#include -#ifdef HAVE_STDINT_H -# include -#endif -#include -#include - -int core_hash_SHA2(unsigned char *, const unsigned int, const unsigned char *, - unsigned int, const unsigned char *, unsigned long long, unsigned int); - -unsigned char* addr_to_byte(unsigned char *bytes, const uint32_t addr[8]){ -#if IS_LITTLE_ENDIAN==1 - int i = 0; - for(i=0;i<8;i++) - to_byte(bytes+i*4, addr[i],4); - return bytes; -#else - memcpy(bytes, addr, 32); - return bytes; -#endif -} - -int core_hash_SHA2(unsigned char *out, const unsigned int type, const unsigned char *key, unsigned int keylen, const unsigned char *in, unsigned long long inlen, unsigned int n){ - unsigned long long i = 0; - unsigned char buf[inlen + n + keylen]; - - // Input is (toByte(X, 32) || KEY || M) - - // set toByte - to_byte(buf, type, n); - - for (i=0; i < keylen; i++) { - buf[i+n] = key[i]; - } - - for (i=0; i < inlen; i++) { - buf[keylen + n + i] = in[i]; - } - - if (n == 32) { - SHA256(buf, inlen + keylen + n, out); - return 0; - } - else { - if (n == 64) { - SHA512(buf, inlen + keylen + n, out); - return 0; - } - } - return 1; -} - -/** - * Implements PRF - */ -int prf(unsigned char *out, const unsigned char *in, const unsigned char *key, unsigned int keylen) -{ - return core_hash_SHA2(out, 3, key, keylen, in, 32, keylen); -} - -/* - * Implements H_msg - */ -int h_msg(unsigned char *out, const unsigned char *in, unsigned long long inlen, const unsigned char *key, const unsigned int keylen, const unsigned int n) -{ - if (keylen != 3*n){ - // H_msg takes 3n-bit keys, but n does not match the keylength of keylen - return -1; - } - return core_hash_SHA2(out, 2, key, keylen, in, inlen, n); -} - -/** - * We assume the left half is in in[0]...in[n-1] - */ -int hash_h(unsigned char *out, const unsigned char *in, const unsigned char *pub_seed, uint32_t addr[8], const unsigned int n) -{ - - unsigned char buf[2*n]; - unsigned char key[n]; - unsigned char bitmask[2*n]; - unsigned char byte_addr[32]; - unsigned int i; - - setKeyAndMask(addr, 0); - addr_to_byte(byte_addr, addr); - prf(key, byte_addr, pub_seed, n); - // Use MSB order - setKeyAndMask(addr, 1); - addr_to_byte(byte_addr, addr); - prf(bitmask, byte_addr, pub_seed, n); - setKeyAndMask(addr, 2); - addr_to_byte(byte_addr, addr); - prf(bitmask+n, byte_addr, pub_seed, n); - for (i = 0; i < 2*n; i++) { - buf[i] = in[i] ^ bitmask[i]; - } - return core_hash_SHA2(out, 1, key, n, buf, 2*n, n); -} - -int hash_f(unsigned char *out, const unsigned char *in, const unsigned char *pub_seed, uint32_t addr[8], const unsigned int n) -{ - unsigned char buf[n]; - unsigned char key[n]; - unsigned char bitmask[n]; - unsigned char byte_addr[32]; - unsigned int i; - - setKeyAndMask(addr, 0); - addr_to_byte(byte_addr, addr); - prf(key, byte_addr, pub_seed, n); - - setKeyAndMask(addr, 1); - addr_to_byte(byte_addr, addr); - prf(bitmask, byte_addr, pub_seed, n); - - for (i = 0; i < n; i++) { - buf[i] = in[i] ^ bitmask[i]; - } - return core_hash_SHA2(out, 0, key, n, buf, n, n); -} -#endif /* WITH_XMSS */ diff --git a/xmss_hash.h b/xmss_hash.h deleted file mode 100644 index d19c621..0000000 --- a/xmss_hash.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifdef WITH_XMSS -/* $OpenBSD: xmss_hash.h,v 1.2 2018/02/26 03:56:44 dtucker Exp $ */ -/* -hash.h version 20160722 -Andreas Hülsing -Joost Rijneveld -Public domain. -*/ - -#ifndef HASH_H -#define HASH_H - -#define IS_LITTLE_ENDIAN 1 - -unsigned char* addr_to_byte(unsigned char *bytes, const uint32_t addr[8]); -int prf(unsigned char *out, const unsigned char *in, const unsigned char *key, unsigned int keylen); -int h_msg(unsigned char *out,const unsigned char *in,unsigned long long inlen, const unsigned char *key, const unsigned int keylen, const unsigned int n); -int hash_h(unsigned char *out, const unsigned char *in, const unsigned char *pub_seed, uint32_t addr[8], const unsigned int n); -int hash_f(unsigned char *out, const unsigned char *in, const unsigned char *pub_seed, uint32_t addr[8], const unsigned int n); - -#endif -#endif /* WITH_XMSS */ diff --git a/xmss_hash_address.c b/xmss_hash_address.c deleted file mode 100644 index 2702c45..0000000 --- a/xmss_hash_address.c +++ /dev/null @@ -1,66 +0,0 @@ -/* $OpenBSD: xmss_hash_address.c,v 1.2 2018/02/26 03:56:44 dtucker Exp $ */ -/* -hash_address.c version 20160722 -Andreas Hülsing -Joost Rijneveld -Public domain. -*/ -#include "includes.h" -#ifdef WITH_XMSS - -#ifdef HAVE_STDINT_H -# include -#endif -#include "xmss_hash_address.h" /* prototypes */ - -void setLayerADRS(uint32_t adrs[8], uint32_t layer){ - adrs[0] = layer; -} - -void setTreeADRS(uint32_t adrs[8], uint64_t tree){ - adrs[1] = (uint32_t) (tree >> 32); - adrs[2] = (uint32_t) tree; -} - -void setType(uint32_t adrs[8], uint32_t type){ - adrs[3] = type; - int i; - for(i = 4; i < 8; i++){ - adrs[i] = 0; - } -} - -void setKeyAndMask(uint32_t adrs[8], uint32_t keyAndMask){ - adrs[7] = keyAndMask; -} - -// OTS - -void setOTSADRS(uint32_t adrs[8], uint32_t ots){ - adrs[4] = ots; -} - -void setChainADRS(uint32_t adrs[8], uint32_t chain){ - adrs[5] = chain; -} - -void setHashADRS(uint32_t adrs[8], uint32_t hash){ - adrs[6] = hash; -} - -// L-tree - -void setLtreeADRS(uint32_t adrs[8], uint32_t ltree){ - adrs[4] = ltree; -} - -// Hash Tree & L-tree - -void setTreeHeight(uint32_t adrs[8], uint32_t treeHeight){ - adrs[5] = treeHeight; -} - -void setTreeIndex(uint32_t adrs[8], uint32_t treeIndex){ - adrs[6] = treeIndex; -} -#endif /* WITH_XMSS */ diff --git a/xmss_hash_address.h b/xmss_hash_address.h deleted file mode 100644 index 66bb4cc..0000000 --- a/xmss_hash_address.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifdef WITH_XMSS -/* $OpenBSD: xmss_hash_address.h,v 1.2 2018/02/26 03:56:44 dtucker Exp $ */ -/* -hash_address.h version 20160722 -Andreas Hülsing -Joost Rijneveld -Public domain. -*/ - -#ifdef HAVE_STDINT_H -#include -#endif - -void setLayerADRS(uint32_t adrs[8], uint32_t layer); - -void setTreeADRS(uint32_t adrs[8], uint64_t tree); - -void setType(uint32_t adrs[8], uint32_t type); - -void setKeyAndMask(uint32_t adrs[8], uint32_t keyAndMask); - -// OTS - -void setOTSADRS(uint32_t adrs[8], uint32_t ots); - -void setChainADRS(uint32_t adrs[8], uint32_t chain); - -void setHashADRS(uint32_t adrs[8], uint32_t hash); - -// L-tree - -void setLtreeADRS(uint32_t adrs[8], uint32_t ltree); - -// Hash Tree & L-tree - -void setTreeHeight(uint32_t adrs[8], uint32_t treeHeight); - -void setTreeIndex(uint32_t adrs[8], uint32_t treeIndex); - -#endif /* WITH_XMSS */ diff --git a/xmss_wots.c b/xmss_wots.c deleted file mode 100644 index 993e661..0000000 --- a/xmss_wots.c +++ /dev/null @@ -1,192 +0,0 @@ -/* $OpenBSD: xmss_wots.c,v 1.3 2018/04/10 00:10:49 djm Exp $ */ -/* -wots.c version 20160722 -Andreas Hülsing -Joost Rijneveld -Public domain. -*/ - -#include "includes.h" -#ifdef WITH_XMSS - -#include -#ifdef HAVE_STDINT_H -# include -#endif -#include -#include "xmss_commons.h" -#include "xmss_hash.h" -#include "xmss_wots.h" -#include "xmss_hash_address.h" - - -/* libm-free version of log2() for wots */ -static inline int -wots_log2(uint32_t v) -{ - int b; - - for (b = sizeof (v) * CHAR_BIT - 1; b >= 0; b--) { - if ((1U << b) & v) { - return b; - } - } - return 0; -} - -void -wots_set_params(wots_params *params, int n, int w) -{ - params->n = n; - params->w = w; - params->log_w = wots_log2(params->w); - params->len_1 = (CHAR_BIT * n) / params->log_w; - params->len_2 = (wots_log2(params->len_1 * (w - 1)) / params->log_w) + 1; - params->len = params->len_1 + params->len_2; - params->keysize = params->len * params->n; -} - -/** - * Helper method for pseudorandom key generation - * Expands an n-byte array into a len*n byte array - * this is done using PRF - */ -static void expand_seed(unsigned char *outseeds, const unsigned char *inseed, const wots_params *params) -{ - uint32_t i = 0; - unsigned char ctr[32]; - for(i = 0; i < params->len; i++){ - to_byte(ctr, i, 32); - prf((outseeds + (i*params->n)), ctr, inseed, params->n); - } -} - -/** - * Computes the chaining function. - * out and in have to be n-byte arrays - * - * interprets in as start-th value of the chain - * addr has to contain the address of the chain - */ -static void gen_chain(unsigned char *out, const unsigned char *in, unsigned int start, unsigned int steps, const wots_params *params, const unsigned char *pub_seed, uint32_t addr[8]) -{ - uint32_t i, j; - for (j = 0; j < params->n; j++) - out[j] = in[j]; - - for (i = start; i < (start+steps) && i < params->w; i++) { - setHashADRS(addr, i); - hash_f(out, out, pub_seed, addr, params->n); - } -} - -/** - * base_w algorithm as described in draft. - * - * - */ -static void base_w(int *output, const int out_len, const unsigned char *input, const wots_params *params) -{ - int in = 0; - int out = 0; - uint32_t total = 0; - int bits = 0; - int consumed = 0; - - for (consumed = 0; consumed < out_len; consumed++) { - if (bits == 0) { - total = input[in]; - in++; - bits += 8; - } - bits -= params->log_w; - output[out] = (total >> bits) & (params->w - 1); - out++; - } -} - -void wots_pkgen(unsigned char *pk, const unsigned char *sk, const wots_params *params, const unsigned char *pub_seed, uint32_t addr[8]) -{ - uint32_t i; - expand_seed(pk, sk, params); - for (i=0; i < params->len; i++) { - setChainADRS(addr, i); - gen_chain(pk+i*params->n, pk+i*params->n, 0, params->w-1, params, pub_seed, addr); - } -} - - -int wots_sign(unsigned char *sig, const unsigned char *msg, const unsigned char *sk, const wots_params *params, const unsigned char *pub_seed, uint32_t addr[8]) -{ - //int basew[params->len]; - int csum = 0; - uint32_t i = 0; - int *basew = calloc(params->len, sizeof(int)); - if (basew == NULL) - return -1; - - base_w(basew, params->len_1, msg, params); - - for (i=0; i < params->len_1; i++) { - csum += params->w - 1 - basew[i]; - } - - csum = csum << (8 - ((params->len_2 * params->log_w) % 8)); - - int len_2_bytes = ((params->len_2 * params->log_w) + 7) / 8; - - unsigned char csum_bytes[len_2_bytes]; - to_byte(csum_bytes, csum, len_2_bytes); - - int csum_basew[params->len_2]; - base_w(csum_basew, params->len_2, csum_bytes, params); - - for (i = 0; i < params->len_2; i++) { - basew[params->len_1 + i] = csum_basew[i]; - } - - expand_seed(sig, sk, params); - - for (i = 0; i < params->len; i++) { - setChainADRS(addr, i); - gen_chain(sig+i*params->n, sig+i*params->n, 0, basew[i], params, pub_seed, addr); - } - free(basew); - return 0; -} - -int wots_pkFromSig(unsigned char *pk, const unsigned char *sig, const unsigned char *msg, const wots_params *params, const unsigned char *pub_seed, uint32_t addr[8]) -{ - int csum = 0; - uint32_t i = 0; - int *basew = calloc(params->len, sizeof(int)); - if (basew == NULL) - return -1; - - base_w(basew, params->len_1, msg, params); - - for (i=0; i < params->len_1; i++) { - csum += params->w - 1 - basew[i]; - } - - csum = csum << (8 - ((params->len_2 * params->log_w) % 8)); - - int len_2_bytes = ((params->len_2 * params->log_w) + 7) / 8; - - unsigned char csum_bytes[len_2_bytes]; - to_byte(csum_bytes, csum, len_2_bytes); - - int csum_basew[params->len_2]; - base_w(csum_basew, params->len_2, csum_bytes, params); - - for (i = 0; i < params->len_2; i++) { - basew[params->len_1 + i] = csum_basew[i]; - } - for (i=0; i < params->len; i++) { - setChainADRS(addr, i); - gen_chain(pk+i*params->n, sig+i*params->n, basew[i], params->w-1-basew[i], params, pub_seed, addr); - } - free(basew); - return 0; -} -#endif /* WITH_XMSS */ diff --git a/xmss_wots.h b/xmss_wots.h deleted file mode 100644 index 1eebf3b..0000000 --- a/xmss_wots.h +++ /dev/null @@ -1,64 +0,0 @@ -#ifdef WITH_XMSS -/* $OpenBSD: xmss_wots.h,v 1.3 2018/02/26 12:14:53 dtucker Exp $ */ -/* -wots.h version 20160722 -Andreas Hülsing -Joost Rijneveld -Public domain. -*/ - -#ifndef WOTS_H -#define WOTS_H - -#ifdef HAVE_STDINT_H -#include "stdint.h" -#endif - -/** - * WOTS parameter set - * - * Meaning as defined in draft-irtf-cfrg-xmss-hash-based-signatures-02 - */ -typedef struct { - uint32_t len_1; - uint32_t len_2; - uint32_t len; - uint32_t n; - uint32_t w; - uint32_t log_w; - uint32_t keysize; -} wots_params; - -/** - * Set the WOTS parameters, - * only m, n, w are required as inputs, - * len, len_1, and len_2 are computed from those. - * - * Assumes w is a power of 2 - */ -void wots_set_params(wots_params *params, int n, int w); - -/** - * WOTS key generation. Takes a 32byte seed for the secret key, expands it to a full WOTS secret key and computes the corresponding public key. - * For this it takes the seed pub_seed which is used to generate bitmasks and hash keys and the address of this WOTS key pair addr - * - * params, must have been initialized before using wots_set params for params ! This is not done in this function - * - * Places the computed public key at address pk. - */ -void wots_pkgen(unsigned char *pk, const unsigned char *sk, const wots_params *params, const unsigned char *pub_seed, uint32_t addr[8]); - -/** - * Takes a m-byte message and the 32-byte seed for the secret key to compute a signature that is placed at "sig". - * - */ -int wots_sign(unsigned char *sig, const unsigned char *msg, const unsigned char *sk, const wots_params *params, const unsigned char *pub_seed, uint32_t addr[8]); - -/** - * Takes a WOTS signature, a m-byte message and computes a WOTS public key that it places at pk. - * - */ -int wots_pkFromSig(unsigned char *pk, const unsigned char *sig, const unsigned char *msg, const wots_params *params, const unsigned char *pub_seed, uint32_t addr[8]); - -#endif -#endif /* WITH_XMSS */