Adding upstream version 1:10.0p1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
This commit is contained in:
parent
4b41451d73
commit
f4a1000be6
884 changed files with 270723 additions and 0 deletions
185
.depend
Normal file
185
.depend
Normal file
|
@ -0,0 +1,185 @@
|
|||
# Automatically generated by makedepend.
|
||||
# Run "make depend" to rebuild.
|
||||
|
||||
# DO NOT DELETE
|
||||
addr.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h addr.h
|
||||
addrmatch.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h addr.h match.h log.h ssherr.h
|
||||
atomicio.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h atomicio.h
|
||||
audit-bsm.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
|
||||
audit-linux.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
|
||||
audit.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
|
||||
auth-bsdauth.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
|
||||
auth-krb5.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h ssh.h packet.h openbsd-compat/sys-queue.h dispatch.h log.h ssherr.h sshbuf.h sshkey.h misc.h servconf.h uidswap.h hostfile.h auth.h auth-pam.h audit.h loginrec.h
|
||||
auth-options.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/sys-queue.h xmalloc.h ssherr.h log.h sshbuf.h misc.h sshkey.h match.h ssh2.h auth-options.h
|
||||
auth-pam.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
|
||||
auth-passwd.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h packet.h openbsd-compat/sys-queue.h dispatch.h sshbuf.h ssherr.h log.h misc.h servconf.h sshkey.h hostfile.h auth.h auth-pam.h audit.h loginrec.h auth-options.h
|
||||
auth-rhosts.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h packet.h openbsd-compat/sys-queue.h dispatch.h uidswap.h pathnames.h log.h ssherr.h misc.h xmalloc.h sshbuf.h sshkey.h servconf.h canohost.h hostfile.h auth.h auth-pam.h audit.h loginrec.h
|
||||
auth-shadow.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
|
||||
auth-sia.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
|
||||
auth.o: authfile.h monitor_wrap.h channels.h
|
||||
auth.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h match.h groupaccess.h log.h ssherr.h sshbuf.h misc.h servconf.h openbsd-compat/sys-queue.h sshkey.h hostfile.h auth.h auth-pam.h audit.h loginrec.h auth-options.h canohost.h uidswap.h packet.h dispatch.h
|
||||
auth2-chall.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h ssh2.h sshkey.h hostfile.h auth.h auth-pam.h audit.h loginrec.h sshbuf.h packet.h openbsd-compat/sys-queue.h dispatch.h ssherr.h log.h misc.h servconf.h
|
||||
auth2-gss.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
|
||||
auth2-hostbased.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h ssh2.h packet.h openbsd-compat/sys-queue.h dispatch.h kex.h mac.h crypto_api.h sshbuf.h log.h ssherr.h misc.h servconf.h sshkey.h hostfile.h auth.h auth-pam.h audit.h loginrec.h canohost.h
|
||||
auth2-hostbased.o: monitor_wrap.h pathnames.h match.h
|
||||
auth2-kbdint.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h packet.h openbsd-compat/sys-queue.h dispatch.h hostfile.h auth.h auth-pam.h audit.h loginrec.h log.h ssherr.h misc.h servconf.h
|
||||
auth2-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: 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
|
||||
authfd.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h ssh.h sshbuf.h sshkey.h authfd.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h log.h ssherr.h atomicio.h misc.h
|
||||
authfile.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h ssh.h log.h ssherr.h authfile.h misc.h atomicio.h sshkey.h sshbuf.h krl.h
|
||||
bitmap.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h bitmap.h
|
||||
canohost.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h packet.h openbsd-compat/sys-queue.h dispatch.h log.h ssherr.h canohost.h misc.h
|
||||
chacha.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h chacha.h
|
||||
channels.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/sys-queue.h xmalloc.h ssh.h ssh2.h ssherr.h sshbuf.h packet.h dispatch.h log.h misc.h channels.h compat.h canohost.h sshkey.h authfd.h pathnames.h match.h
|
||||
cipher-aes.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/openssl-compat.h
|
||||
cipher-aesctr.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h cipher-aesctr.h rijndael.h
|
||||
cipher-chachapoly-libcrypto.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
|
||||
cipher-chachapoly.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h ssherr.h sshbuf.h cipher-chachapoly.h chacha.h poly1305.h
|
||||
cipher.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h misc.h sshbuf.h ssherr.h digest.h openbsd-compat/openssl-compat.h
|
||||
cleanup.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h ssherr.h
|
||||
clientloop.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/sys-queue.h xmalloc.h ssh.h ssh2.h packet.h dispatch.h sshbuf.h compat.h channels.h sshkey.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h kex.h mac.h crypto_api.h
|
||||
clientloop.o: myproposal.h log.h ssherr.h misc.h readconf.h clientloop.h sshconnect.h authfd.h atomicio.h sshpty.h match.h msg.h hostfile.h
|
||||
compat.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h packet.h openbsd-compat/sys-queue.h dispatch.h compat.h log.h ssherr.h match.h
|
||||
dh.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
|
||||
digest-libc.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ssherr.h sshbuf.h digest.h
|
||||
digest-openssl.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
|
||||
dispatch.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ssh2.h log.h ssherr.h dispatch.h packet.h openbsd-compat/sys-queue.h
|
||||
dns.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h sshkey.h ssherr.h dns.h log.h digest.h
|
||||
ed25519.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h crypto_api.h
|
||||
entropy.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
|
||||
fatal.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h ssherr.h
|
||||
groupaccess.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h groupaccess.h match.h log.h ssherr.h
|
||||
gss-genr.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
|
||||
gss-serv-krb5.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
|
||||
gss-serv.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
|
||||
hash.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h crypto_api.h
|
||||
hmac.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h sshbuf.h digest.h hmac.h
|
||||
hostfile.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h match.h sshkey.h hostfile.h log.h ssherr.h misc.h pathnames.h digest.h hmac.h sshbuf.h
|
||||
kex-names.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h kex.h mac.h crypto_api.h log.h ssherr.h match.h digest.h misc.h xmalloc.h
|
||||
kex.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ssh.h ssh2.h atomicio.h version.h packet.h openbsd-compat/sys-queue.h dispatch.h compat.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h sshkey.h kex.h mac.h crypto_api.h log.h ssherr.h
|
||||
kex.o: match.h misc.h monitor.h myproposal.h sshbuf.h digest.h xmalloc.h
|
||||
kexc25519.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h sshkey.h kex.h mac.h crypto_api.h sshbuf.h digest.h ssherr.h ssh2.h
|
||||
kexdh.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
|
||||
kexecdh.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ssherr.h
|
||||
kexgen.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h sshkey.h kex.h mac.h crypto_api.h log.h ssherr.h packet.h openbsd-compat/sys-queue.h dispatch.h ssh2.h sshbuf.h digest.h
|
||||
kexgex.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
|
||||
kexgexc.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
|
||||
kexgexs.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
|
||||
kexmlkem768x25519.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h sshkey.h kex.h mac.h crypto_api.h sshbuf.h digest.h ssherr.h log.h
|
||||
kexsntrup761x25519.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ssherr.h
|
||||
krl.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ./openbsd-compat/sys-tree.h openbsd-compat/sys-queue.h sshbuf.h ssherr.h sshkey.h authfile.h misc.h log.h digest.h bitmap.h utf8.h krl.h
|
||||
log.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h ssherr.h match.h
|
||||
loginrec.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h sshkey.h hostfile.h ssh.h loginrec.h log.h ssherr.h atomicio.h packet.h openbsd-compat/sys-queue.h dispatch.h canohost.h auth.h auth-pam.h audit.h sshbuf.h misc.h
|
||||
logintest.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h loginrec.h
|
||||
mac.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h digest.h hmac.h umac.h mac.h misc.h ssherr.h sshbuf.h openbsd-compat/openssl-compat.h
|
||||
match.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h match.h misc.h
|
||||
misc.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h misc.h log.h ssherr.h ssh.h sshbuf.h
|
||||
moduli.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
|
||||
monitor.o: chacha.h poly1305.h cipher-aesctr.h rijndael.h kex.h mac.h crypto_api.h dh.h packet.h dispatch.h auth-options.h sshpty.h channels.h session.h sshlogin.h canohost.h log.h ssherr.h misc.h servconf.h monitor.h monitor_wrap.h monitor_fdpass.h compat.h ssh2.h authfd.h match.h sk-api.h srclimit.h
|
||||
monitor.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ./openbsd-compat/sys-tree.h openbsd-compat/sys-queue.h openbsd-compat/openssl-compat.h atomicio.h xmalloc.h ssh.h sshkey.h sshbuf.h hostfile.h auth.h auth-pam.h audit.h loginrec.h cipher.h cipher-chachapoly.h
|
||||
monitor_fdpass.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h ssherr.h monitor_fdpass.h
|
||||
monitor_wrap.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/sys-queue.h xmalloc.h ssh.h sshbuf.h sshkey.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h kex.h mac.h crypto_api.h hostfile.h auth.h auth-pam.h audit.h
|
||||
monitor_wrap.o: loginrec.h auth-options.h packet.h dispatch.h log.h ssherr.h monitor.h atomicio.h monitor_fdpass.h misc.h channels.h session.h servconf.h monitor_wrap.h srclimit.h
|
||||
msg.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h sshbuf.h ssherr.h log.h atomicio.h msg.h misc.h
|
||||
mux.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/sys-queue.h xmalloc.h log.h ssherr.h ssh.h ssh2.h pathnames.h misc.h match.h sshbuf.h channels.h msg.h packet.h dispatch.h monitor_fdpass.h sshpty.h sshkey.h readconf.h clientloop.h
|
||||
nchan.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/sys-queue.h ssh2.h sshbuf.h ssherr.h packet.h dispatch.h channels.h compat.h log.h
|
||||
packet.o: channels.h ssh.h packet.h dispatch.h sshbuf.h
|
||||
packet.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/sys-queue.h xmalloc.h compat.h ssh2.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h sshkey.h kex.h mac.h crypto_api.h digest.h log.h ssherr.h canohost.h misc.h
|
||||
platform-listen.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-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
|
||||
platform-misc.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
|
||||
platform-pledge.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
|
||||
platform-tracing.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h ssherr.h
|
||||
platform.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h ssherr.h misc.h servconf.h openbsd-compat/sys-queue.h sshkey.h hostfile.h auth.h auth-pam.h audit.h loginrec.h
|
||||
poly1305.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h poly1305.h
|
||||
progressmeter.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h progressmeter.h atomicio.h misc.h utf8.h
|
||||
readconf.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/glob.h xmalloc.h ssh.h ssherr.h 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 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-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
|
||||
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 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
|
||||
sftp-client.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/sys-queue.h xmalloc.h ssherr.h sshbuf.h log.h atomicio.h progressmeter.h misc.h utf8.h sftp.h sftp-common.h sftp-client.h openbsd-compat/glob.h
|
||||
sftp-common.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h ssherr.h sshbuf.h log.h misc.h sftp.h sftp-common.h
|
||||
sftp-glob.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h sftp.h sftp-common.h sftp-client.h openbsd-compat/glob.h
|
||||
sftp-realpath.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
|
||||
sftp-server-main.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h ssherr.h sftp.h misc.h xmalloc.h
|
||||
sftp-server.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h atomicio.h xmalloc.h sshbuf.h ssherr.h log.h misc.h match.h uidswap.h sftp.h sftp-common.h
|
||||
sftp-usergroup.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ./openbsd-compat/sys-tree.h log.h ssherr.h xmalloc.h sftp-common.h sftp-client.h openbsd-compat/glob.h sftp-usergroup.h
|
||||
sftp.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h log.h ssherr.h pathnames.h misc.h utf8.h sftp.h sshbuf.h sftp-common.h sftp-client.h openbsd-compat/glob.h sftp-usergroup.h
|
||||
sk-usbhid.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
|
||||
sntrup761.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
|
||||
srclimit.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ./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-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-rsa.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
|
||||
ssh-sk-client.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h ssherr.h sshbuf.h sshkey.h msg.h digest.h pathnames.h ssh-sk.h misc.h
|
||||
ssh-sk-helper.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h log.h ssherr.h sshkey.h authfd.h misc.h sshbuf.h msg.h uidswap.h ssh-sk.h
|
||||
ssh-sk.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
|
||||
ssh-xmss.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
|
||||
ssh.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/openssl-compat.h openbsd-compat/sys-queue.h xmalloc.h ssh.h ssh2.h canohost.h compat.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h packet.h dispatch.h sshbuf.h channels.h
|
||||
ssh.o: sshkey.h authfd.h authfile.h pathnames.h clientloop.h log.h ssherr.h misc.h readconf.h sshconnect.h kex.h mac.h crypto_api.h sshpty.h match.h msg.h version.h myproposal.h utf8.h
|
||||
ssh_api.o: authfile.h dh.h misc.h version.h myproposal.h sshbuf.h openbsd-compat/openssl-compat.h
|
||||
ssh_api.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ssh_api.h openbsd-compat/sys-queue.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h sshkey.h kex.h mac.h crypto_api.h ssh.h ssh2.h packet.h dispatch.h compat.h log.h ssherr.h
|
||||
sshbuf-getput-basic.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ssherr.h sshbuf.h
|
||||
sshbuf-getput-crypto.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h
|
||||
sshbuf-io.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ssherr.h sshbuf.h atomicio.h
|
||||
sshbuf-misc.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ssherr.h sshbuf.h
|
||||
sshbuf.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ssherr.h sshbuf.h misc.h
|
||||
sshconnect.o: authfd.h kex.h mac.h crypto_api.h
|
||||
sshconnect.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h hostfile.h ssh.h sshbuf.h packet.h openbsd-compat/sys-queue.h dispatch.h 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-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 atomicio.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
|
||||
sshlogin.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h sshlogin.h ssherr.h loginrec.h log.h sshbuf.h misc.h servconf.h openbsd-compat/sys-queue.h
|
||||
sshpty.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h sshpty.h log.h ssherr.h misc.h
|
||||
sshsig.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h authfd.h authfile.h log.h ssherr.h misc.h sshbuf.h sshsig.h sshkey.h match.h digest.h
|
||||
sshtty.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h sshpty.h
|
||||
ttymodes.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h packet.h openbsd-compat/sys-queue.h dispatch.h log.h ssherr.h compat.h sshbuf.h ttymodes.h
|
||||
uidswap.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h ssherr.h uidswap.h xmalloc.h
|
||||
umac.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h umac.h misc.h rijndael.h
|
||||
umac128.o: umac.c includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h umac.h misc.h rijndael.h
|
||||
utf8.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h utf8.h
|
||||
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
|
11
.git_allowed_signers
Normal file
11
.git_allowed_signers
Normal file
|
@ -0,0 +1,11 @@
|
|||
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
|
||||
|
16
.git_allowed_signers.asc
Normal file
16
.git_allowed_signers.asc
Normal file
|
@ -0,0 +1,16 @@
|
|||
-----BEGIN PGP SIGNATURE-----
|
||||
|
||||
iQIzBAABCgAdFiEEcWi5g4FaXu9ZpK39Kj9BTnNgYLoFAmYHnZ8ACgkQKj9BTnNg
|
||||
YLquuQ/6A8E6P2jcgn3wmbbCTXP7kmxoh3nmw/e6PC8CEua1512oT3GHOKVD5cGK
|
||||
cgYRObpWvjOjg7L1HRABftq7a9M2zfsGnY/WNe3/fbetfkyY8hG8c31vA1ePIOt2
|
||||
AjBLCWFblH0CtyH/MssoQ19JCLtXK/GmekB1Q0JzyOog7w/0r3CKuUnZ0juCYR1R
|
||||
4FBePl5l3nFSZEcFEdptGlNGeuolS5XBCqB9Y91TCzkVkH5eXUUW+shgjNhWCEhT
|
||||
pZvkxfhsmOEnwNofyPdgKVfDBVkHmvuC67EU395mJVN4c2NZ8pOztb9hOt3xr980
|
||||
q44I4kT2NpaApCx1dWIGhMy/37LJ8heI0W1B+ofTA5n34/RU8UXH3SCkj2AK6Ao5
|
||||
H2u8vbmuWKUCiECmrw35EeKGmtuK/bWJzx3KBP7fx5J9S3mWUgT4W4xlWNN9RWoU
|
||||
sSvH1ppie5ARINVaAWl5k44fk60ahTf80DbQBIOZBmQn7myZZka+yGcQbAiZZ1Gc
|
||||
0l8+Nf5Ao1ckmuyY5o8FyWdsyDeK3+MqjPn5Rr1CqbKCn2VnqrVWbI33Eyu8c96U
|
||||
bxVgU5H1BDhNjJC8UrT3LFPvJMO8p3a0IJ3eHydjk2jVOhOdBZmA0yoqUTrhPpXq
|
||||
ymIHESjDJR8TDe4TCfb46o9oEC3cdbDwgnzPqdg0n+0uIsJLYiU=
|
||||
=gl+l
|
||||
-----END PGP SIGNATURE-----
|
19
.github/ci-status.md
vendored
Normal file
19
.github/ci-status.md
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
master :
|
||||
[](https://github.com/openssh/openssh-portable/actions/workflows/c-cpp.yml?query=branch:master)
|
||||
[](https://github.com/openssh/openssh-portable-selfhosted/actions/workflows/selfhosted.yml?query=branch:master)
|
||||
[](https://github.com/openssh/openssh-portable-selfhosted/actions/workflows/upstream.yml?query=branch:master)
|
||||
[](https://github.com/openssh/openssh-portable/actions/workflows/cifuzz.yml)
|
||||
[](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:openssh)
|
||||
[](https://scan.coverity.com/projects/openssh-portable)
|
||||
|
||||
9.9 :
|
||||
[](https://github.com/openssh/openssh-portable/actions/workflows/c-cpp.yml?query=branch:V_9_9)
|
||||
[](https://github.com/openssh/openssh-portable-selfhosted/actions/workflows/selfhosted.yml?query=branch:V_9_9)
|
||||
|
||||
9.8 :
|
||||
[](https://github.com/openssh/openssh-portable/actions/workflows/c-cpp.yml?query=branch:V_9_8)
|
||||
[](https://github.com/openssh/openssh-portable-selfhosted/actions/workflows/selfhosted.yml?query=branch:V_9_8)
|
||||
|
||||
9.7 :
|
||||
[](https://github.com/openssh/openssh-portable/actions/workflows/c-cpp.yml?query=branch:V_9_7)
|
||||
[](https://github.com/openssh/openssh-portable-selfhosted/actions/workflows/selfhosted.yml?query=branch:V_9_7)
|
396
.github/configs
vendored
Executable file
396
.github/configs
vendored
Executable file
|
@ -0,0 +1,396 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# usage: configs vmname test_config (or '' for default)
|
||||
#
|
||||
# Sets the following variables:
|
||||
# CONFIGFLAGS options to ./configure
|
||||
# SSHD_CONFOPTS sshd_config options
|
||||
# TEST_TARGET make target used when testing. defaults to "tests".
|
||||
# LTESTS
|
||||
|
||||
config=$1
|
||||
if [ "$config" = "" ]; then
|
||||
config="default"
|
||||
fi
|
||||
|
||||
unset CC CFLAGS CPPFLAGS LDFLAGS LTESTS SUDO
|
||||
|
||||
TEST_TARGET="tests compat-tests"
|
||||
LTESTS=""
|
||||
SKIP_LTESTS=""
|
||||
SUDO=sudo # run with sudo by default
|
||||
TEST_SSH_UNSAFE_PERMISSIONS=1
|
||||
# Stop on first test failure to minimize logs
|
||||
TEST_SSH_FAIL_FATAL=yes
|
||||
|
||||
CONFIGFLAGS=""
|
||||
LIBCRYPTOFLAGS=""
|
||||
|
||||
case "$config" in
|
||||
default|sol64)
|
||||
;;
|
||||
c89)
|
||||
# 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.
|
||||
llong_max=`gcc -E -dM - </dev/null | \
|
||||
awk '$2=="__LONG_LONG_MAX__"{print $3}'`
|
||||
CPPFLAGS="-DLLONG_MAX=${llong_max}"
|
||||
|
||||
CC="gcc"
|
||||
CFLAGS="-Wall -std=c89 -pedantic -Werror=vla"
|
||||
CONFIGFLAGS="--without-zlib"
|
||||
LIBCRYPTOFLAGS="--without-openssl"
|
||||
TEST_TARGET=t-exec
|
||||
;;
|
||||
cygwin-release)
|
||||
# See https://cygwin.com/git/?p=git/cygwin-packages/openssh.git;a=blob;f=openssh.cygport;hb=HEAD
|
||||
CONFIGFLAGS="--with-xauth=/usr/bin/xauth --with-security-key-builtin"
|
||||
CONFIGFLAGS="$CONFIGFLAGS --with-kerberos5=/usr --with-libedit --disable-strip"
|
||||
;;
|
||||
clang-12-Werror)
|
||||
CC="clang-12"
|
||||
# clang's implicit-fallthrough requires that the code be annotated with
|
||||
# __attribute__((fallthrough)) and does not understand /* FALLTHROUGH */
|
||||
CFLAGS="-Wall -Wextra -O2 -Wno-error=implicit-fallthrough -Wno-error=unused-parameter"
|
||||
CONFIGFLAGS="--with-pam --with-Werror"
|
||||
;;
|
||||
*-sanitize-*)
|
||||
case "$config" in
|
||||
gcc-*)
|
||||
CC=gcc
|
||||
;;
|
||||
clang-*)
|
||||
# Find the newest available version of clang
|
||||
for i in `seq 10 99`; do
|
||||
clang="`which clang-$i 2>/dev/null`"
|
||||
[ -x "$clang" ] && CC="$clang"
|
||||
done
|
||||
;;
|
||||
esac
|
||||
# Put Sanitizer logs in regress dir.
|
||||
SANLOGS=`pwd`/regress
|
||||
# - We replace chroot with chdir so that the sanitizer in the preauth
|
||||
# privsep process can read /proc.
|
||||
# - clang does not recognizes explicit_bzero so we use bzero
|
||||
# (see https://github.com/google/sanitizers/issues/1507
|
||||
# - openssl and zlib trip ASAN.
|
||||
# - sp_pwdp returned by getspnam trips ASAN, hence disabling shadow.
|
||||
case "$config" in
|
||||
*-sanitize-address)
|
||||
CFLAGS="-fsanitize=address -fno-omit-frame-pointer"
|
||||
LDFLAGS="-fsanitize=address"
|
||||
CPPFLAGS='-Dchroot=chdir -Dexplicit_bzero=bzero -D_FORTIFY_SOURCE=0 -DASAN_OPTIONS=\"detect_leaks=0:log_path='$SANLOGS'/asan.log\"'
|
||||
CONFIGFLAGS=""
|
||||
TEST_TARGET="t-exec"
|
||||
;;
|
||||
clang-sanitize-memory)
|
||||
CFLAGS="-fsanitize=memory -fsanitize-memory-track-origins -fno-omit-frame-pointer"
|
||||
LDFLAGS="-fsanitize=memory"
|
||||
CPPFLAGS='-Dchroot=chdir -Dexplicit_bzero=bzero -DMSAN_OPTIONS=\"log_path='$SANLOGS'/msan.log\"'
|
||||
CONFIGFLAGS="--without-zlib --without-shadow"
|
||||
LIBCRYPTOFLAGS="--without-openssl"
|
||||
TEST_TARGET="t-exec"
|
||||
;;
|
||||
*-sanitize-undefined)
|
||||
CFLAGS="-fsanitize=undefined"
|
||||
LDFLAGS="-fsanitize=undefined"
|
||||
;;
|
||||
*)
|
||||
echo unknown sanitize option;
|
||||
exit 1;;
|
||||
esac
|
||||
features="--disable-security-key --disable-pkcs11"
|
||||
hardening="--without-sandbox --without-hardening --without-stackprotect"
|
||||
privsep="--with-privsep-user=root"
|
||||
CONFIGFLAGS="$CONFIGFLAGS $features $hardening $privsep"
|
||||
# Because we hobble chroot we can't test it.
|
||||
SKIP_LTESTS=sftp-chroot
|
||||
;;
|
||||
gcc-11-Werror)
|
||||
CC="gcc-11"
|
||||
# -Wnoformat-truncation in gcc 7.3.1 20180130 fails on fmt_scaled
|
||||
# -Wunused-result ignores (void) so is not useful. See
|
||||
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66425
|
||||
CFLAGS="-O2 -Wno-format-truncation -Wimplicit-fallthrough=4 -Wno-unused-parameter -Wno-unused-result"
|
||||
CONFIGFLAGS="--with-pam --with-Werror"
|
||||
;;
|
||||
gcc-12-Werror)
|
||||
CC="gcc-12"
|
||||
# -Wnoformat-truncation in gcc 7.3.1 20180130 fails on fmt_scaled
|
||||
# -Wunused-result ignores (void) so is not useful. See
|
||||
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66425
|
||||
CFLAGS="-O2 -Wno-format-truncation -Wimplicit-fallthrough=4 -Wno-unused-parameter -Wno-unused-result"
|
||||
CONFIGFLAGS="--with-pam --with-Werror"
|
||||
;;
|
||||
clang*|gcc*)
|
||||
CC="$config"
|
||||
;;
|
||||
kitchensink)
|
||||
CONFIGFLAGS="--with-kerberos5 --with-libedit --with-pam"
|
||||
CONFIGFLAGS="${CONFIGFLAGS} --with-security-key-builtin --with-selinux"
|
||||
CONFIGFLAGS="${CONFIGFLAGS} --with-linux-memlock-onfault"
|
||||
CFLAGS="-DSK_DEBUG -DSANDBOX_SECCOMP_FILTER_DEBUG"
|
||||
;;
|
||||
hardenedmalloc)
|
||||
CONFIGFLAGS="--with-ldflags=-lhardened_malloc"
|
||||
;;
|
||||
tcmalloc)
|
||||
CONFIGFLAGS="--with-ldflags=-ltcmalloc"
|
||||
# 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.
|
||||
TCMALLOC_STACKTRACE_METHOD=generic_fp
|
||||
TEST_SSH_SSHD_ENV="TCMALLOC_STACKTRACE_METHOD=generic_fp"
|
||||
export TCMALLOC_STACKTRACE_METHOD TEST_SSH_SSHD_ENV
|
||||
;;
|
||||
krb5|heimdal)
|
||||
CONFIGFLAGS="--with-kerberos5"
|
||||
;;
|
||||
libedit)
|
||||
CONFIGFLAGS="--with-libedit"
|
||||
;;
|
||||
musl)
|
||||
CC="musl-gcc"
|
||||
CONFIGFLAGS="--without-zlib"
|
||||
LIBCRYPTOFLAGS="--without-openssl"
|
||||
TEST_TARGET="t-exec"
|
||||
;;
|
||||
pam-krb5)
|
||||
CONFIGFLAGS="--with-pam --with-kerberos5"
|
||||
SSHD_CONFOPTS="UsePam yes"
|
||||
;;
|
||||
*pam)
|
||||
CONFIGFLAGS="--with-pam"
|
||||
SSHD_CONFOPTS="UsePam yes"
|
||||
;;
|
||||
boringssl)
|
||||
CONFIGFLAGS="--disable-pkcs11"
|
||||
LIBCRYPTOFLAGS="--with-ssl-dir=/opt/boringssl --with-rpath=-Wl,-rpath,"
|
||||
;;
|
||||
aws-lc)
|
||||
LIBCRYPTOFLAGS="--with-ssl-dir=/opt/aws-lc --with-rpath=-Wl,-rpath,"
|
||||
;;
|
||||
libressl-*)
|
||||
LIBCRYPTOFLAGS="--with-ssl-dir=/opt/libressl --with-rpath=-Wl,-rpath,"
|
||||
;;
|
||||
putty-*)
|
||||
CONFIGFLAGS="--with-plink=/usr/local/bin/plink --with-puttygen=/usr/local/bin/puttygen"
|
||||
# We don't need to rerun the regular tests, just the interop ones.
|
||||
TEST_TARGET=interop-tests
|
||||
;;
|
||||
openssl-*)
|
||||
LIBCRYPTOFLAGS="--with-ssl-dir=/opt/openssl --with-rpath=-Wl,-rpath,"
|
||||
# OpenSSL 1.1.1 specifically has a bug in its RNG that breaks reexec
|
||||
# fallback. See https://bugzilla.mindrot.org/show_bug.cgi?id=3483
|
||||
if [ "$config" = "openssl-1.1.1" ]; then
|
||||
SKIP_LTESTS="reexec"
|
||||
fi
|
||||
;;
|
||||
selinux)
|
||||
CONFIGFLAGS="--with-selinux"
|
||||
;;
|
||||
sk)
|
||||
CONFIGFLAGS="--with-security-key-builtin --with-security-key-standalone"
|
||||
;;
|
||||
without-openssl)
|
||||
LIBCRYPTOFLAGS="--without-openssl"
|
||||
TEST_TARGET=t-exec
|
||||
;;
|
||||
valgrind-[1-4]|valgrind-unit)
|
||||
# rlimit sandbox and FORTIFY_SOURCE confuse Valgrind.
|
||||
CONFIGFLAGS="--without-sandbox --without-hardening"
|
||||
CONFIGFLAGS="$CONFIGFLAGS --with-cppflags=-D_FORTIFY_SOURCE=0"
|
||||
TEST_TARGET="t-exec USE_VALGRIND=1"
|
||||
TEST_SSH_ELAPSED_TIMES=1
|
||||
export TEST_SSH_ELAPSED_TIMES
|
||||
# Valgrind slows things down enough that the agent timeout test
|
||||
# won't reliably pass, and the unit tests run longer than allowed
|
||||
# by github so split into separate tests.
|
||||
tests2="integrity try-ciphers rekey"
|
||||
tests3="krl forward-control sshsig agent-restrict kextype sftp"
|
||||
tests4="cert-userkey cert-hostkey kextype sftp-perm keygen-comment percent"
|
||||
case "$config" in
|
||||
valgrind-1)
|
||||
# All tests except agent-timeout (which is flaky under valgrind),
|
||||
# connection-timeout (which doesn't work since it's so slow)
|
||||
# and hostbased (since valgrind won't let ssh exec keysign).
|
||||
# Slow ones are run separately to increase parallelism.
|
||||
SKIP_LTESTS="agent-timeout connection-timeout hostbased"
|
||||
SKIP_LTESTS="$SKIP_LTESTS penalty-expire"
|
||||
SKIP_LTESTS="$SKIP_LTESTS ${tests2} ${tests3} ${tests4} ${tests5}"
|
||||
;;
|
||||
valgrind-2)
|
||||
LTESTS="${tests2}"
|
||||
;;
|
||||
valgrind-3)
|
||||
LTESTS="${tests3}"
|
||||
;;
|
||||
valgrind-4)
|
||||
LTESTS="${tests4}"
|
||||
;;
|
||||
valgrind-unit)
|
||||
TEST_TARGET="unit USE_VALGRIND=1"
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
zlib-develop)
|
||||
INSTALL_ZLIB=develop
|
||||
CONFIGFLAGS="--with-zlib=/opt/zlib --with-rpath=-Wl,-rpath,"
|
||||
;;
|
||||
*)
|
||||
echo "Unknown configuration $config"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# The Solaris 64bit targets are special since they need a non-flag arg.
|
||||
case "$config" in
|
||||
sol64*)
|
||||
CONFIGFLAGS="--target=x86_64 --with-cflags=-m64 --with-ldflags=-m64 ${CONFIGFLAGS}"
|
||||
LIBCRYPTOFLAGS="--with-ssl-dir=/usr/local/ssl64 --with-rpath=-Wl,-rpath,"
|
||||
;;
|
||||
esac
|
||||
|
||||
case "${TARGET_HOST}" in
|
||||
aix*)
|
||||
CONFIGFLAGS="--disable-security-key"
|
||||
LIBCRYPTOFLAGS="--without-openssl"
|
||||
# These are slow real or virtual machines so skip the slowest tests
|
||||
# (which tend to be thw ones that transfer lots of data) so that the
|
||||
# test run does not time out.
|
||||
# The agent-restrict test fails due to some quoting issue when run
|
||||
# with sh or ksh so specify bash for now.
|
||||
TEST_TARGET="t-exec unit TEST_SHELL=bash"
|
||||
SKIP_LTESTS="rekey sftp"
|
||||
;;
|
||||
debian-riscv64)
|
||||
# This machine is fairly slow, so skip the unit tests.
|
||||
TEST_TARGET="t-exec"
|
||||
;;
|
||||
dfly58*|dfly60*)
|
||||
# scp 3-way connection hangs on these so skip until sorted.
|
||||
SKIP_LTESTS=scp3
|
||||
;;
|
||||
fbsd6)
|
||||
# Native linker is not great with PIC so OpenSSL is built w/out.
|
||||
CONFIGFLAGS="${CONFIGFLAGS} --disable-security-key"
|
||||
;;
|
||||
fbsd14-ppc64)
|
||||
# Disable security key tests for bigendian interop test.
|
||||
CONFIGFLAGS="${CONFIGFLAGS} --disable-security-key"
|
||||
;;
|
||||
hurd)
|
||||
SKIP_LTESTS="forwarding multiplex proxy-connect hostkey-agent agent-ptrace"
|
||||
;;
|
||||
minix3)
|
||||
CONFIGFLAGS="${CONFIGFLAGS} --disable-security-key"
|
||||
# Unix domain sockets don't work quite like we expect, so also
|
||||
# disable FD passing (and thus multiplexing).
|
||||
CONFIGFLAGS="${CONFIGFLAGS} --disable-fd-passing"
|
||||
LIBCRYPTOFLAGS="--without-openssl"
|
||||
|
||||
# Minix does not have a loopback interface so we have to skip any
|
||||
# test that relies on one.
|
||||
# Also, Minix seems to be very limited in the number of select()
|
||||
# calls that can be operating concurrently, so prune additional tests for that.
|
||||
T="addrmatch agent-restrict brokenkeys cfgmatch cfgmatchlisten cfgparse
|
||||
connect connect-uri dynamic-forward exit-status forwarding
|
||||
forward-control
|
||||
hostkey-agent key-options keyscan knownhosts-command login-timeout
|
||||
reconfigure reexec rekey scp scp-uri scp3 sftp sftp-badcmds
|
||||
sftp-batch sftp-cmds sftp-glob sftp-perm sftp-uri stderr-data
|
||||
transfer penalty penalty-expire"
|
||||
SKIP_LTESTS="$(echo $T)"
|
||||
TEST_TARGET=t-exec
|
||||
SUDO=""
|
||||
;;
|
||||
nbsd4)
|
||||
# System compiler will ICE on some files with fstack-protector
|
||||
# SHA256 functions in sha2.h conflict with OpenSSL's breaking sk-dummy
|
||||
CONFIGFLAGS="${CONFIGFLAGS} --without-hardening --disable-security-key"
|
||||
;;
|
||||
openwrt-mipsel)
|
||||
# Test most of the flags that OpenWRT sets for their package build.
|
||||
# We only do this on one OpenWRT target for better coverage.
|
||||
# The installed shared libraries installed by default are stripped and
|
||||
# can't be linked to on the target systems.
|
||||
OPENWRT_FLAGS="--disable-strip --disable-lastlog
|
||||
--disable-utmp --disable-utmpx --disable-wtmp --disable-wtmpx
|
||||
--with-stackprotect --with-cflags-after=-fzero-call-used-regs=skip"
|
||||
CONFIGFLAGS="${CONFIGFLAGS} $(echo ${OPENWRT_FLAGS}) --without-zlib --disable-security-key"
|
||||
LIBCRYPTOFLAGS="--without-openssl"
|
||||
TEST_TARGET="t-exec"
|
||||
;;
|
||||
openwrt-*)
|
||||
CONFIGFLAGS="${CONFIGFLAGS} --without-zlib --disable-security-key"
|
||||
LIBCRYPTOFLAGS="--without-openssl"
|
||||
TEST_TARGET="t-exec"
|
||||
;;
|
||||
sol10|sol11)
|
||||
# sol10 VM is 32bit and the unit tests are slow.
|
||||
# sol11 has 4 test configs so skip unit tests to speed up.
|
||||
TEST_TARGET="tests SKIP_UNIT=1"
|
||||
;;
|
||||
win10)
|
||||
# No sudo on Windows.
|
||||
SUDO=""
|
||||
;;
|
||||
esac
|
||||
|
||||
host=`./config.guess`
|
||||
case "$host" in
|
||||
*cygwin)
|
||||
SUDO=""
|
||||
# Don't run compat tests on cygwin as they don't currently compile.
|
||||
TEST_TARGET="tests"
|
||||
;;
|
||||
*-darwin*)
|
||||
# Unless specified otherwise, build without OpenSSL on Mac OS since
|
||||
# modern versions don't ship with libcrypto.
|
||||
LIBCRYPTOFLAGS="--without-openssl"
|
||||
TEST_TARGET=t-exec
|
||||
|
||||
# On some OS X runners we can't write to /var/empty.
|
||||
CONFIGFLAGS="${CONFIGFLAGS} --with-privsep-path=/usr/local/empty"
|
||||
|
||||
case "$host" in
|
||||
*-darwin22.*)
|
||||
# sudo -S nobody doesn't work on macos 13 for some reason.
|
||||
SKIP_LTESTS="agent-getpeereid" ;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
# Unless specifically configured, search for a suitable version of OpenSSL,
|
||||
# otherwise build without it.
|
||||
if [ -z "${LIBCRYPTOFLAGS}" ]; then
|
||||
LIBCRYPTOFLAGS="--without-openssl"
|
||||
# last-match
|
||||
for i in /usr /usr/local /usr/local/ssl /usr/local/opt/openssl; do
|
||||
ver="none"
|
||||
if [ -x ${i}/bin/openssl ]; then
|
||||
ver="$(${i}/bin/openssl version)"
|
||||
fi
|
||||
case "$ver" in
|
||||
none) ;;
|
||||
"OpenSSL 0."*|"OpenSSL 1.0."*|"OpenSSL 1.1.0"*) ;;
|
||||
"LibreSSL 2."*|"LibreSSL 3.0."*) ;;
|
||||
*) LIBCRYPTOFLAGS="--with-ssl-dir=${i}" ;;
|
||||
esac
|
||||
done
|
||||
if [ "${LIBCRYPTOFLAGS}" = "--without-openssl" ]; then
|
||||
TEST_TARGET="t-exec"
|
||||
fi
|
||||
fi
|
||||
|
||||
CONFIGFLAGS="${CONFIGFLAGS} ${LIBCRYPTOFLAGS}"
|
||||
|
||||
if [ -x "$(which plink 2>/dev/null)" ]; then
|
||||
REGRESS_INTEROP_PUTTY=yes
|
||||
export REGRESS_INTEROP_PUTTY
|
||||
fi
|
||||
|
||||
export CC CFLAGS CPPFLAGS LDFLAGS LTESTS SUDO
|
||||
export TEST_TARGET TEST_SSH_UNSAFE_PERMISSIONS TEST_SSH_FAIL_FATAL
|
21
.github/configure.sh
vendored
Executable file
21
.github/configure.sh
vendored
Executable file
|
@ -0,0 +1,21 @@
|
|||
#!/bin/sh
|
||||
|
||||
. .github/configs $1
|
||||
|
||||
printf "$ "
|
||||
|
||||
if [ "x$CC" != "x" ]; then
|
||||
printf "CC='$CC' "
|
||||
fi
|
||||
if [ "x$CFLAGS" != "x" ]; then
|
||||
printf "CFLAGS='$CFLAGS' "
|
||||
fi
|
||||
if [ "x$CPPFLAGS" != "x" ]; then
|
||||
printf "CPPFLAGS='$CPPFLAGS' "
|
||||
fi
|
||||
if [ "x$LDFLAGS" != "x" ]; then
|
||||
printf "LDFLAGS='$LDFLAGS' "
|
||||
fi
|
||||
|
||||
echo ./configure ${CONFIGFLAGS}
|
||||
./configure ${CONFIGFLAGS} 2>&1
|
63
.github/run_test.sh
vendored
Executable file
63
.github/run_test.sh
vendored
Executable file
|
@ -0,0 +1,63 @@
|
|||
#!/bin/sh
|
||||
|
||||
. .github/configs $1
|
||||
|
||||
[ -z "${SUDO}" ] || ${SUDO} mkdir -p /var/empty
|
||||
|
||||
set -ex
|
||||
|
||||
# If we want to test hostbased auth, set up the host for it.
|
||||
if [ ! -z "$SUDO" ] && [ ! -z "$TEST_SSH_HOSTBASED_AUTH" ]; then
|
||||
sshconf=/usr/local/etc
|
||||
$SUDO mkdir -p "${sshconf}"
|
||||
hostname | $SUDO tee $sshconf/shosts.equiv >/dev/null
|
||||
echo "EnableSSHKeysign yes" | $SUDO tee $sshconf/ssh_config >/dev/null
|
||||
$SUDO mkdir -p $sshconf
|
||||
$SUDO cp -p /etc/ssh/ssh_host*key* $sshconf
|
||||
$SUDO make install
|
||||
for key in $sshconf/ssh_host*key*.pub; do
|
||||
echo `hostname` `cat $key` | \
|
||||
$SUDO tee -a $sshconf/ssh_known_hosts >/dev/null
|
||||
done
|
||||
fi
|
||||
|
||||
output_failed_logs() {
|
||||
for i in regress/failed*.log; do
|
||||
if [ -f "$i" ]; then
|
||||
echo -------------------------------------------------------------------------
|
||||
echo LOGFILE $i
|
||||
cat $i
|
||||
echo -------------------------------------------------------------------------
|
||||
fi
|
||||
done
|
||||
}
|
||||
trap output_failed_logs 0
|
||||
|
||||
env=""
|
||||
if [ ! -z "${SUDO}" ]; then
|
||||
env="${env} SUDO=${SUDO}"
|
||||
fi
|
||||
if [ ! -z "${TCMALLOC_STACKTRACE_METHOD}" ]; then
|
||||
env="${env} TCMALLOC_STACKTRACE_METHOD=${TCMALLOC_STACKTRACE_METHOD}"
|
||||
fi
|
||||
if [ ! -z "${TEST_SSH_SSHD_ENV}" ]; then
|
||||
env="${env} TEST_SSH_SSHD_ENV=${TEST_SSH_SSHD_ENV}"
|
||||
fi
|
||||
if [ ! -z "${env}" ]; then
|
||||
env="env${env}"
|
||||
fi
|
||||
|
||||
if [ -z "${LTESTS}" ]; then
|
||||
${env} make ${TEST_TARGET} SKIP_LTESTS="${SKIP_LTESTS}"
|
||||
else
|
||||
${env} make ${TEST_TARGET} SKIP_LTESTS="${SKIP_LTESTS}" LTESTS="${LTESTS}"
|
||||
fi
|
||||
|
||||
if [ ! -z "${SSHD_CONFOPTS}" ]; then
|
||||
echo "rerunning t-exec with TEST_SSH_SSHD_CONFOPTS='${SSHD_CONFOPTS}'"
|
||||
if [ -z "${LTESTS}" ]; then
|
||||
${env} make t-exec SKIP_LTESTS="${SKIP_LTESTS}" TEST_SSH_SSHD_CONFOPTS="${SSHD_CONFOPTS}"
|
||||
else
|
||||
${env} make t-exec SKIP_LTESTS="${SKIP_LTESTS}" LTESTS="${LTESTS}" TEST_SSH_SSHD_CONFOPTS="${SSHD_CONFOPTS}"
|
||||
fi
|
||||
fi
|
282
.github/setup_ci.sh
vendored
Executable file
282
.github/setup_ci.sh
vendored
Executable file
|
@ -0,0 +1,282 @@
|
|||
#!/bin/sh
|
||||
|
||||
PACKAGES=""
|
||||
|
||||
. .github/configs $@
|
||||
|
||||
host=`./config.guess`
|
||||
echo "config.guess: $host"
|
||||
case "$host" in
|
||||
*cygwin)
|
||||
PACKAGER=setup
|
||||
echo Setting CYGWIN system environment variable.
|
||||
setx CYGWIN "binmode"
|
||||
echo Removing extended ACLs so umask works as expected.
|
||||
setfacl -b . regress
|
||||
PACKAGES="$PACKAGES,autoconf,automake,cygwin-devel,gcc-core"
|
||||
PACKAGES="$PACKAGES,make,openssl,libssl-devel,zlib-devel"
|
||||
;;
|
||||
*-darwin*)
|
||||
PACKAGER=brew
|
||||
PACKAGES="automake"
|
||||
;;
|
||||
*)
|
||||
PACKAGER=apt
|
||||
esac
|
||||
|
||||
TARGETS=$@
|
||||
|
||||
INSTALL_FIDO_PPA="no"
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
set -e
|
||||
|
||||
if [ -x "`which lsb_release 2>&1`" ]; then
|
||||
lsb_release -a
|
||||
fi
|
||||
|
||||
if [ ! -z "$SUDO" ]; then
|
||||
# Ubuntu 22.04 defaults to private home dirs which prevent the
|
||||
# agent-getpeerid test from running ssh-add as nobody. See
|
||||
# https://github.com/actions/runner-images/issues/6106
|
||||
if ! "$SUDO" -u nobody test -x ~; then
|
||||
echo ~ is not executable by nobody, adding perms.
|
||||
chmod go+x ~
|
||||
fi
|
||||
# Some of the Mac OS X runners don't have a nopasswd sudo rule. Regular
|
||||
# sudo still works, but sudo -u doesn't. Restore the sudo rule.
|
||||
if ! "$SUDO" grep -E 'runner.*NOPASSWD' /etc/passwd >/dev/null; then
|
||||
echo "Restoring runner nopasswd rule to sudoers."
|
||||
echo 'runner ALL=(ALL) NOPASSWD: ALL' |$SUDO tee -a /etc/sudoers
|
||||
fi
|
||||
if ! "$SUDO" -u nobody -S test -x ~ </dev/null; then
|
||||
echo "Still can't sudo to nobody."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "${TARGETS}" = "kitchensink" ]; then
|
||||
TARGETS="krb5 libedit pam sk selinux"
|
||||
fi
|
||||
|
||||
for flag in $CONFIGFLAGS; do
|
||||
case "$flag" in
|
||||
--with-pam) TARGETS="${TARGETS} pam" ;;
|
||||
--with-libedit) TARGETS="${TARGETS} libedit" ;;
|
||||
esac
|
||||
done
|
||||
|
||||
echo "Setting up for '$TARGETS'"
|
||||
for TARGET in $TARGETS; do
|
||||
case $TARGET in
|
||||
default|without-openssl|without-zlib|c89)
|
||||
# nothing to do
|
||||
;;
|
||||
clang-sanitize*)
|
||||
PACKAGES="$PACKAGES clang-12"
|
||||
;;
|
||||
cygwin-release)
|
||||
PACKAGES="$PACKAGES libcrypt-devel libfido2-devel libkrb5-devel"
|
||||
;;
|
||||
gcc-sanitize*)
|
||||
;;
|
||||
clang-*|gcc-*)
|
||||
compiler=$(echo $TARGET | sed 's/-Werror//')
|
||||
PACKAGES="$PACKAGES $compiler"
|
||||
;;
|
||||
krb5)
|
||||
PACKAGES="$PACKAGES libkrb5-dev"
|
||||
;;
|
||||
heimdal)
|
||||
PACKAGES="$PACKAGES heimdal-dev"
|
||||
;;
|
||||
libedit)
|
||||
case "$PACKAGER" in
|
||||
setup) PACKAGES="$PACKAGES libedit-devel" ;;
|
||||
apt) PACKAGES="$PACKAGES libedit-dev" ;;
|
||||
esac
|
||||
;;
|
||||
*pam)
|
||||
case "$PACKAGER" in
|
||||
apt) PACKAGES="$PACKAGES libpam0g-dev" ;;
|
||||
esac
|
||||
;;
|
||||
sk)
|
||||
INSTALL_FIDO_PPA="yes"
|
||||
PACKAGES="$PACKAGES libfido2-dev libu2f-host-dev libcbor-dev"
|
||||
;;
|
||||
selinux)
|
||||
PACKAGES="$PACKAGES libselinux1-dev selinux-policy-dev"
|
||||
;;
|
||||
hardenedmalloc)
|
||||
INSTALL_HARDENED_MALLOC=yes
|
||||
;;
|
||||
musl)
|
||||
PACKAGES="$PACKAGES musl-tools"
|
||||
;;
|
||||
tcmalloc)
|
||||
PACKAGES="$PACKAGES libgoogle-perftools-dev"
|
||||
;;
|
||||
openssl-noec)
|
||||
INSTALL_OPENSSL=OpenSSL_1_1_1k
|
||||
SSLCONFOPTS="no-ec"
|
||||
;;
|
||||
openssl-*)
|
||||
INSTALL_OPENSSL=$(echo ${TARGET} | cut -f2 -d-)
|
||||
case ${INSTALL_OPENSSL} in
|
||||
1.1.1_stable) INSTALL_OPENSSL="OpenSSL_1_1_1-stable" ;;
|
||||
1.*) INSTALL_OPENSSL="OpenSSL_$(echo ${INSTALL_OPENSSL} | tr . _)" ;;
|
||||
3.*) INSTALL_OPENSSL="openssl-${INSTALL_OPENSSL}" ;;
|
||||
esac
|
||||
PACKAGES="${PACKAGES} putty-tools dropbear-bin"
|
||||
;;
|
||||
libressl-*)
|
||||
INSTALL_LIBRESSL=$(echo ${TARGET} | cut -f2 -d-)
|
||||
case ${INSTALL_LIBRESSL} in
|
||||
master) ;;
|
||||
*) INSTALL_LIBRESSL="$(echo ${TARGET} | cut -f2 -d-)" ;;
|
||||
esac
|
||||
PACKAGES="${PACKAGES} putty-tools dropbear-bin"
|
||||
;;
|
||||
boringssl)
|
||||
INSTALL_BORINGSSL=1
|
||||
PACKAGES="${PACKAGES} cmake ninja-build"
|
||||
;;
|
||||
aws-lc)
|
||||
INSTALL_AWSLC=1
|
||||
PACKAGES="${PACKAGES} cmake ninja-build"
|
||||
;;
|
||||
putty-*)
|
||||
INSTALL_PUTTY=$(echo "${TARGET}" | cut -f2 -d-)
|
||||
PACKAGES="${PACKAGES} cmake"
|
||||
;;
|
||||
valgrind*)
|
||||
PACKAGES="$PACKAGES valgrind"
|
||||
;;
|
||||
zlib-*)
|
||||
;;
|
||||
*) echo "Invalid option '${TARGET}'"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ "yes" = "$INSTALL_FIDO_PPA" ]; then
|
||||
sudo apt update -qq
|
||||
sudo apt install -qy software-properties-common
|
||||
sudo apt-add-repository -y ppa:yubico/stable
|
||||
fi
|
||||
|
||||
tries=3
|
||||
while [ ! -z "$PACKAGES" ] && [ "$tries" -gt "0" ]; do
|
||||
case "$PACKAGER" in
|
||||
apt)
|
||||
sudo apt update -qq
|
||||
if sudo apt install -qy $PACKAGES; then
|
||||
PACKAGES=""
|
||||
fi
|
||||
;;
|
||||
brew)
|
||||
if [ ! -z "PACKAGES" ]; then
|
||||
if brew install $PACKAGES; then
|
||||
PACKAGES=""
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
setup)
|
||||
if /cygdrive/c/setup.exe -q -P `echo "$PACKAGES" | tr ' ' ,`; then
|
||||
PACKAGES=""
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
if [ ! -z "$PACKAGES" ]; then
|
||||
sleep 90
|
||||
fi
|
||||
tries=$(($tries - 1))
|
||||
done
|
||||
if [ ! -z "$PACKAGES" ]; then
|
||||
echo "Package installation failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "${INSTALL_HARDENED_MALLOC}" = "yes" ]; then
|
||||
(cd ${HOME} &&
|
||||
git clone https://github.com/GrapheneOS/hardened_malloc.git &&
|
||||
cd ${HOME}/hardened_malloc &&
|
||||
make && sudo cp out/libhardened_malloc.so /usr/lib/)
|
||||
fi
|
||||
|
||||
if [ ! -z "${INSTALL_OPENSSL}" ]; then
|
||||
(cd ${HOME} &&
|
||||
git clone https://github.com/openssl/openssl.git &&
|
||||
cd ${HOME}/openssl &&
|
||||
git checkout ${INSTALL_OPENSSL} &&
|
||||
./config no-threads shared ${SSLCONFOPTS} \
|
||||
--prefix=/opt/openssl &&
|
||||
make && sudo make install_sw)
|
||||
fi
|
||||
|
||||
if [ ! -z "${INSTALL_LIBRESSL}" ]; then
|
||||
if [ "${INSTALL_LIBRESSL}" = "master" ]; then
|
||||
(mkdir -p ${HOME}/libressl && cd ${HOME}/libressl &&
|
||||
git clone https://github.com/libressl-portable/portable.git &&
|
||||
cd ${HOME}/libressl/portable &&
|
||||
git checkout ${INSTALL_LIBRESSL} &&
|
||||
sh update.sh && sh autogen.sh &&
|
||||
./configure --prefix=/opt/libressl &&
|
||||
make && sudo make install)
|
||||
else
|
||||
LIBRESSL_URLBASE=https://cdn.openbsd.org/pub/OpenBSD/LibreSSL
|
||||
(cd ${HOME} &&
|
||||
wget ${LIBRESSL_URLBASE}/libressl-${INSTALL_LIBRESSL}.tar.gz &&
|
||||
tar xfz libressl-${INSTALL_LIBRESSL}.tar.gz &&
|
||||
cd libressl-${INSTALL_LIBRESSL} &&
|
||||
./configure --prefix=/opt/libressl && make && sudo make install)
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ! -z "${INSTALL_BORINGSSL}" ]; then
|
||||
(cd ${HOME} && git clone https://boringssl.googlesource.com/boringssl &&
|
||||
cd ${HOME}/boringssl && mkdir build && cd build &&
|
||||
cmake -GNinja -DCMAKE_POSITION_INDEPENDENT_CODE=ON .. && ninja &&
|
||||
mkdir -p /opt/boringssl/lib &&
|
||||
cp ${HOME}/boringssl/build/crypto/libcrypto.a /opt/boringssl/lib &&
|
||||
cp -r ${HOME}/boringssl/include /opt/boringssl)
|
||||
fi
|
||||
|
||||
if [ ! -z "${INSTALL_AWSLC}" ]; then
|
||||
(cd ${HOME} && git clone --depth 1 --branch v1.46.1 https://github.com/aws/aws-lc.git &&
|
||||
cd ${HOME}/aws-lc && mkdir build && cd build &&
|
||||
cmake -GNinja -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=OFF .. && ninja &&
|
||||
mkdir -p /opt/aws-lc/lib &&
|
||||
cp ${HOME}/aws-lc/build/crypto/libcrypto.a /opt/aws-lc/lib &&
|
||||
cp -r ${HOME}/aws-lc/include /opt/aws-lc)
|
||||
fi
|
||||
|
||||
if [ ! -z "${INSTALL_ZLIB}" ]; then
|
||||
(cd ${HOME} && git clone https://github.com/madler/zlib.git &&
|
||||
cd ${HOME}/zlib && ./configure && make &&
|
||||
sudo make install prefix=/opt/zlib)
|
||||
fi
|
||||
|
||||
if [ ! -z "${INSTALL_PUTTY}" ]; then
|
||||
ver="${INSTALL_PUTTY}"
|
||||
case "${INSTALL_PUTTY}" in
|
||||
snapshot)
|
||||
tarball=putty.tar.gz
|
||||
(cd /tmp && wget https://tartarus.org/~simon/putty-snapshots/${tarball})
|
||||
;;
|
||||
*)
|
||||
tarball=putty-${ver}.tar.gz
|
||||
(cd /tmp && wget https://the.earth.li/~sgtatham/putty/${ver}/${tarball})
|
||||
;;
|
||||
esac
|
||||
(cd ${HOME} && tar xfz /tmp/${tarball} && cd putty-*
|
||||
if [ -f CMakeLists.txt ]; then
|
||||
cmake . && cmake --build . && sudo cmake --build . --target install
|
||||
else
|
||||
./configure && make && sudo make install
|
||||
fi
|
||||
)
|
||||
/usr/local/bin/plink -V
|
||||
fi
|
153
.github/workflows/c-cpp.yml
vendored
Normal file
153
.github/workflows/c-cpp.yml
vendored
Normal file
|
@ -0,0 +1,153 @@
|
|||
name: C/C++ CI
|
||||
|
||||
on:
|
||||
push:
|
||||
paths: [ '**.c', '**.h', '**.m4', '**.sh', '**/Makefile.in', 'configure.ac', '.github/configs', '.github/workflows/c-cpp.yml' ]
|
||||
pull_request:
|
||||
paths: [ '**.c', '**.h', '**.m4', '**.sh', '**/Makefile.in', 'configure.ac', '.github/configs', '.github/workflows/c-cpp.yml' ]
|
||||
|
||||
jobs:
|
||||
ci:
|
||||
name: "${{ matrix.target }} ${{ matrix.config }}"
|
||||
if: github.repository != 'openssh/openssh-portable-selfhosted'
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
# First we test all OSes in the default configuration.
|
||||
target:
|
||||
- ubuntu-22.04
|
||||
- ubuntu-latest
|
||||
- ubuntu-22.04-arm
|
||||
- ubuntu-24.04-arm
|
||||
- macos-13
|
||||
- macos-14
|
||||
- macos-15
|
||||
- windows-2019
|
||||
- windows-2022
|
||||
config: [default]
|
||||
# Then we include any extra configs we want to test for specific VMs.
|
||||
# Valgrind slows things down quite a bit, so start them first.
|
||||
include:
|
||||
- { target: windows-2019, config: cygwin-release }
|
||||
- { target: windows-2022, config: cygwin-release }
|
||||
- { target: ubuntu-22.04, config: c89 }
|
||||
- { target: ubuntu-22.04, config: clang-11 }
|
||||
- { target: ubuntu-22.04, config: clang-12-Werror }
|
||||
- { target: ubuntu-22.04, config: clang-14 }
|
||||
- { target: ubuntu-22.04, config: clang-sanitize-address }
|
||||
- { target: ubuntu-22.04, config: clang-sanitize-undefined }
|
||||
- { target: ubuntu-22.04, config: gcc-9 }
|
||||
- { target: ubuntu-22.04, config: gcc-11-Werror }
|
||||
- { target: ubuntu-22.04, config: gcc-12-Werror }
|
||||
- { target: ubuntu-22.04, config: gcc-sanitize-address }
|
||||
- { target: ubuntu-22.04, config: gcc-sanitize-undefined }
|
||||
- { target: ubuntu-22.04, config: hardenedmalloc }
|
||||
- { target: ubuntu-22.04, config: heimdal }
|
||||
- { target: ubuntu-22.04, config: kitchensink }
|
||||
- { target: ubuntu-22.04, config: krb5 }
|
||||
- { target: ubuntu-22.04, config: libedit }
|
||||
- { target: ubuntu-22.04, config: pam }
|
||||
- { target: ubuntu-22.04, config: selinux }
|
||||
- { target: ubuntu-22.04, config: sk }
|
||||
- { target: ubuntu-22.04, config: valgrind-1 }
|
||||
- { target: ubuntu-22.04, config: valgrind-2 }
|
||||
- { target: ubuntu-22.04, config: valgrind-3 }
|
||||
- { target: ubuntu-22.04, config: valgrind-4 }
|
||||
- { target: ubuntu-22.04, config: valgrind-unit }
|
||||
- { target: ubuntu-22.04, config: without-openssl }
|
||||
- { target: ubuntu-latest, config: gcc-14 }
|
||||
- { target: ubuntu-latest, config: clang-15 }
|
||||
- { target: ubuntu-latest, config: clang-19 }
|
||||
- { target: ubuntu-latest, config: boringssl }
|
||||
- { target: ubuntu-latest, config: aws-lc }
|
||||
- { target: ubuntu-latest, config: libressl-master }
|
||||
- { target: ubuntu-latest, config: libressl-3.2.6 }
|
||||
- { target: ubuntu-latest, config: libressl-3.3.6 }
|
||||
- { target: ubuntu-latest, config: libressl-3.4.3 }
|
||||
- { target: ubuntu-latest, config: libressl-3.5.3 }
|
||||
- { target: ubuntu-latest, config: libressl-3.6.1 }
|
||||
- { target: ubuntu-latest, config: libressl-3.7.2 }
|
||||
- { target: ubuntu-latest, config: libressl-3.8.4 }
|
||||
- { target: ubuntu-latest, config: libressl-3.9.2 }
|
||||
- { target: ubuntu-latest, config: libressl-4.0.0 }
|
||||
- { target: ubuntu-latest, config: openssl-master }
|
||||
- { target: ubuntu-latest, config: openssl-noec }
|
||||
- { target: ubuntu-latest, config: openssl-1.1.1 }
|
||||
- { target: ubuntu-latest, config: openssl-1.1.1t }
|
||||
- { target: ubuntu-latest, config: openssl-1.1.1w }
|
||||
- { target: ubuntu-latest, config: openssl-3.0.0 }
|
||||
- { target: ubuntu-latest, config: openssl-3.0.15 }
|
||||
- { target: ubuntu-latest, config: openssl-3.1.0 }
|
||||
- { target: ubuntu-latest, config: openssl-3.1.7 }
|
||||
- { target: ubuntu-latest, config: openssl-3.2.3 }
|
||||
- { target: ubuntu-latest, config: openssl-3.3.2 }
|
||||
- { target: ubuntu-latest, config: openssl-3.4.0 }
|
||||
- { target: ubuntu-latest, config: openssl-1.1.1_stable }
|
||||
- { target: ubuntu-latest, config: openssl-3.0 } # stable branch
|
||||
- { target: ubuntu-latest, config: openssl-3.1 } # stable branch
|
||||
- { target: ubuntu-latest, config: openssl-3.2 } # stable branch
|
||||
- { target: ubuntu-latest, config: openssl-3.3 } # stable branch
|
||||
- { target: ubuntu-latest, config: putty-0.71 }
|
||||
- { target: ubuntu-latest, config: putty-0.72 }
|
||||
- { target: ubuntu-latest, config: putty-0.73 }
|
||||
- { target: ubuntu-latest, config: putty-0.74 }
|
||||
- { target: ubuntu-latest, config: putty-0.75 }
|
||||
- { target: ubuntu-latest, config: putty-0.76 }
|
||||
- { target: ubuntu-latest, config: putty-0.77 }
|
||||
- { target: ubuntu-latest, config: putty-0.78 }
|
||||
- { target: ubuntu-latest, config: putty-0.79 }
|
||||
- { target: ubuntu-latest, config: putty-0.80 }
|
||||
- { target: ubuntu-latest, config: putty-0.81 }
|
||||
- { target: ubuntu-latest, config: putty-0.82 }
|
||||
- { target: ubuntu-latest, config: putty-0.83 }
|
||||
- { target: ubuntu-latest, config: putty-snapshot }
|
||||
- { target: ubuntu-latest, config: zlib-develop }
|
||||
- { target: ubuntu-latest, config: tcmalloc }
|
||||
- { target: ubuntu-latest, config: musl }
|
||||
- { target: ubuntu-22.04-arm, config: kitchensink }
|
||||
- { target: ubuntu-24.04-arm, config: kitchensink }
|
||||
- { target: macos-13, config: pam }
|
||||
- { target: macos-14, config: pam }
|
||||
- { target: macos-15, config: pam }
|
||||
runs-on: ${{ matrix.target }}
|
||||
steps:
|
||||
- name: set cygwin git params
|
||||
if: ${{ startsWith(matrix.target, 'windows') }}
|
||||
run: git config --global core.autocrlf input
|
||||
- name: install cygwin
|
||||
if: ${{ startsWith(matrix.target, 'windows') }}
|
||||
uses: cygwin/cygwin-install-action@master
|
||||
- uses: actions/checkout@main
|
||||
- name: setup CI system
|
||||
run: sh ./.github/setup_ci.sh ${{ matrix.config }}
|
||||
- name: autoreconf
|
||||
run: sh -c autoreconf
|
||||
- name: configure
|
||||
run: sh ./.github/configure.sh ${{ matrix.config }}
|
||||
- name: save config
|
||||
uses: actions/upload-artifact@main
|
||||
with:
|
||||
name: ${{ matrix.target }}-${{ matrix.config }}-config
|
||||
path: config.h
|
||||
- name: make clean
|
||||
run: make clean
|
||||
- name: make
|
||||
run: make
|
||||
- name: make tests
|
||||
run: sh ./.github/run_test.sh ${{ matrix.config }}
|
||||
env:
|
||||
TEST_SSH_UNSAFE_PERMISSIONS: 1
|
||||
TEST_SSH_HOSTBASED_AUTH: yes
|
||||
- name: save logs
|
||||
if: failure()
|
||||
uses: actions/upload-artifact@main
|
||||
with:
|
||||
name: ${{ matrix.target }}-${{ matrix.config }}-logs
|
||||
path: |
|
||||
config.h
|
||||
config.log
|
||||
regress/*.log
|
||||
regress/valgrind-out/
|
||||
regress/asan.log.*
|
||||
regress/msan.log.*
|
||||
regress/log/*
|
32
.github/workflows/cifuzz.yml
vendored
Normal file
32
.github/workflows/cifuzz.yml
vendored
Normal file
|
@ -0,0 +1,32 @@
|
|||
name: CIFuzz
|
||||
on:
|
||||
push:
|
||||
paths: [ '**.c', '**.h', '**.m4', '**.sh', '**/Makefile.in', 'configure.ac', '.github/configs', '.github/workflows/cifuzz.yml' ]
|
||||
pull_request:
|
||||
paths: [ '**.c', '**.h', '**.m4', '**.sh', '**/Makefile.in', 'configure.ac', '.github/configs', '.github/workflows/cifuzz.yml' ]
|
||||
|
||||
jobs:
|
||||
Fuzzing:
|
||||
if: github.repository != 'openssh/openssh-portable-selfhosted'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Build Fuzzers
|
||||
id: build
|
||||
uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master
|
||||
with:
|
||||
oss-fuzz-project-name: 'openssh'
|
||||
dry-run: false
|
||||
language: c++
|
||||
- name: Run Fuzzers
|
||||
uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master
|
||||
with:
|
||||
oss-fuzz-project-name: 'openssh'
|
||||
fuzz-seconds: 600
|
||||
dry-run: false
|
||||
language: c++
|
||||
- name: Upload Crash
|
||||
uses: actions/upload-artifact@main
|
||||
if: failure() && steps.build.outcome == 'success'
|
||||
with:
|
||||
name: artifacts
|
||||
path: ./out/artifacts
|
203
.github/workflows/selfhosted.yml
vendored
Normal file
203
.github/workflows/selfhosted.yml
vendored
Normal file
|
@ -0,0 +1,203 @@
|
|||
name: C/C++ CI self-hosted
|
||||
|
||||
on:
|
||||
push:
|
||||
paths: [ '**.c', '**.h', '**.m4', '**.sh', '**/Makefile.in', 'configure.ac', '.github/configs', '.github/workflows/selfhosted.yml' ]
|
||||
|
||||
jobs:
|
||||
selfhosted:
|
||||
name: "${{ matrix.target }} ${{ matrix.config }}"
|
||||
if: github.repository == 'openssh/openssh-portable-selfhosted'
|
||||
runs-on: ${{ matrix.host }}
|
||||
timeout-minutes: 600
|
||||
env:
|
||||
DEBUG_ACTIONS: false
|
||||
HOST: ${{ matrix.host }}
|
||||
TARGET_HOST: ${{ matrix.target }}
|
||||
TARGET_CONFIG: ${{ matrix.config }}
|
||||
TARGET_DOMAIN: ${{ startsWith(matrix.host, 'libvirt') && format('{0}-{1}-{2}', matrix.target, matrix.config, github.run_id) || matrix.target }}
|
||||
EPHEMERAL: ${{ startsWith(matrix.host, 'libvirt') }}
|
||||
PERSISTENT: ${{ startsWith(matrix.host, 'persist') }}
|
||||
REMOTE: ${{ startsWith(matrix.host, 'remote') }}
|
||||
VM: ${{ startsWith(matrix.host, 'libvirt') || startsWith(matrix.host, 'persist') }}
|
||||
SSHFS: ${{ startsWith(matrix.host, 'libvirt') || startsWith(matrix.host, 'persist') || startsWith(matrix.host, 'remote') }}
|
||||
BIGENDIAN: ${{ matrix.target == 'aix51' || matrix.target == 'fbsd14-ppc64' || matrix.target == 'openwrt-mips' }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
# We use a matrix in two parts: firstly all of the VMs are tested with the
|
||||
# default config. "target" corresponds to a label associated with the
|
||||
# worker. The default is an ephemeral VM running under libvirt.
|
||||
matrix:
|
||||
target:
|
||||
- alpine
|
||||
- centos7
|
||||
- debian-i386
|
||||
- dfly30
|
||||
- dfly48
|
||||
- dfly60
|
||||
- dfly62
|
||||
- dfly64
|
||||
- fbsd10
|
||||
- fbsd12
|
||||
- fbsd13
|
||||
- fbsd14
|
||||
- nbsd3
|
||||
- nbsd4
|
||||
- nbsd8
|
||||
- nbsd9
|
||||
- nbsd10
|
||||
- obsd51
|
||||
- obsd67
|
||||
- obsd72
|
||||
- obsd73
|
||||
- obsd74
|
||||
- obsdsnap
|
||||
- obsdsnap-i386
|
||||
- omnios
|
||||
- openindiana
|
||||
- ubuntu-2204
|
||||
config:
|
||||
- default
|
||||
host:
|
||||
- libvirt
|
||||
include:
|
||||
# Long-running/slow tests have access to high priority runners.
|
||||
- { target: aix51, config: default, host: libvirt-hipri }
|
||||
- { target: fbsd14-ppc64, config: default, host: libvirt-hipri }
|
||||
- { target: openindiana, config: pam, host: libvirt-hipri }
|
||||
- { target: sol10, config: default, host: libvirt-hipri }
|
||||
- { target: sol10, config: pam, host: libvirt-hipri }
|
||||
- { target: sol11, config: default, host: libvirt-hipri }
|
||||
- { target: sol11, config: pam-krb5, host: libvirt-hipri }
|
||||
- { target: sol11, config: sol64, host: libvirt-hipri }
|
||||
# Then we include extra libvirt test configs.
|
||||
- { target: centos7, config: pam, host: libvirt }
|
||||
- { target: debian-i386, config: pam, host: libvirt }
|
||||
- { target: dfly30, config: without-openssl, host: libvirt}
|
||||
- { target: dfly48, config: pam ,host: libvirt }
|
||||
- { target: dfly58, config: pam, host: libvirt }
|
||||
- { target: dfly60, config: pam, host: libvirt }
|
||||
- { target: dfly62, config: pam, host: libvirt }
|
||||
- { target: dfly64, config: pam, host: libvirt }
|
||||
- { target: fbsd10, config: pam, host: libvirt }
|
||||
- { target: fbsd12, config: pam, host: libvirt }
|
||||
- { target: fbsd13, config: pam, host: libvirt }
|
||||
- { target: fbsd14, config: pam, host: libvirt }
|
||||
- { target: nbsd8, config: pam, host: libvirt }
|
||||
- { target: nbsd9, config: pam, host: libvirt }
|
||||
- { target: nbsd10, config: pam, host: libvirt }
|
||||
- { target: omnios, config: pam, host: libvirt }
|
||||
# ARM64 VMs
|
||||
- { target: obsd-arm64, config: default, host: libvirt-arm64 }
|
||||
# VMs with persistent disks that have their own runner.
|
||||
- { target: win10, config: default, host: persist-win10 }
|
||||
- { target: win10, config: cygwin-release, host: persist-win10 }
|
||||
# Physical hosts with native runners.
|
||||
- { target: ARM, config: default, host: ARM }
|
||||
- { target: ARM64, config: default, host: ARM64 }
|
||||
- { target: ARM64, config: pam, host: ARM64 }
|
||||
# Physical hosts with remote runners.
|
||||
- { target: debian-riscv64, config: default, host: remote-debian-riscv64 }
|
||||
- { target: openwrt-mips, config: default, host: remote-openwrt-mips }
|
||||
- { target: openwrt-mipsel, config: default, host: remote-openwrt-mipsel }
|
||||
steps:
|
||||
- name: shutdown VM if running
|
||||
if: env.VM == 'true'
|
||||
run: vmshutdown
|
||||
- uses: actions/checkout@main
|
||||
- name: autoreconf
|
||||
run: autoreconf
|
||||
- name: startup VM
|
||||
if: env.VM == 'true'
|
||||
run: vmstartup
|
||||
working-directory: ${{ runner.temp }}
|
||||
- name: copy and mount workspace
|
||||
if: env.SSHFS == 'true'
|
||||
run: sshfs_mount
|
||||
working-directory: ${{ runner.temp }}
|
||||
- name: configure
|
||||
run: vmrun ./.github/configure.sh ${{ matrix.config }}
|
||||
# - name: save config
|
||||
# uses: actions/upload-artifact@main
|
||||
# with:
|
||||
# name: ${{ matrix.target }}-${{ matrix.config }}-config
|
||||
# path: config.h
|
||||
- name: make clean
|
||||
run: vmrun make clean
|
||||
- name: make
|
||||
run: vmrun make
|
||||
- name: make tests
|
||||
run: vmrun ./.github/run_test.sh ${{ matrix.config }}
|
||||
timeout-minutes: 600
|
||||
- name: save logs
|
||||
if: failure()
|
||||
uses: actions/upload-artifact@main
|
||||
with:
|
||||
name: ${{ matrix.target }}-${{ matrix.config }}-logs
|
||||
path: |
|
||||
config.h
|
||||
config.log
|
||||
regress/*.log
|
||||
regress/log/*
|
||||
regress/valgrind-out/
|
||||
- name: unmount workspace
|
||||
if: always() && env.SSHFS == 'true'
|
||||
run: fusermount -u ${GITHUB_WORKSPACE} || true
|
||||
working-directory: ${{ runner.temp }}
|
||||
|
||||
- name: bigendian interop - mount regress
|
||||
if: env.SSHFS == 'true' && env.BIGENDIAN == 'true'
|
||||
run: |
|
||||
set -x
|
||||
vmrun sudo chown -R $LOGNAME ~/$(basename ${GITHUB_WORKSPACE}) || true
|
||||
vmrun "cd $(basename ${GITHUB_WORKSPACE}/regress) && sudo make clean"
|
||||
sshfs_mount regress
|
||||
vmrun "sudo mkdir -p $(dirname ${GITHUB_WORKSPACE})"
|
||||
vmrun "sudo ln -s ~/$(basename ${GITHUB_WORKSPACE}) ${GITHUB_WORKSPACE}"
|
||||
working-directory: ${{ runner.temp }}
|
||||
|
||||
- name: bigendian interop - host build
|
||||
if: env.SSHFS == 'true' && env.BIGENDIAN == 'true'
|
||||
run: |
|
||||
set -x
|
||||
./.github/configure.sh ${{ matrix.config }}
|
||||
pwd
|
||||
ls -ld regress || true
|
||||
ls -l regress/check-perm || true
|
||||
make clean
|
||||
make
|
||||
|
||||
- name: bigendian interop - test
|
||||
if: env.SSHFS == 'true' && env.BIGENDIAN == 'true'
|
||||
env:
|
||||
TEST_SSH_UNSAFE_PERMISSIONS: 1
|
||||
run: |
|
||||
set -x
|
||||
echo "#!/bin/sh" >remote_sshd
|
||||
echo "exec /usr/bin/ssh ${TARGET_DOMAIN} exec /home/builder/$(basename ${GITHUB_WORKSPACE})/sshd "'$@' >>remote_sshd
|
||||
chmod 755 remote_sshd
|
||||
make t-exec TEST_SSH_SSHD=`pwd`/remote_sshd LTESTS="try-ciphers kextype keytype"
|
||||
|
||||
- name: bigendian interop - save logs
|
||||
if: failure() && env.BIGENDIAN == 'true'
|
||||
uses: actions/upload-artifact@main
|
||||
with:
|
||||
name: ${{ matrix.target }}-${{ matrix.config }}-interop-logs
|
||||
path: |
|
||||
config.h
|
||||
config.log
|
||||
regress/*.log
|
||||
regress/log/*
|
||||
|
||||
- name: bigendian interop - unmount regress
|
||||
if: always() && env.SSHFS == 'true' && env.BIGENDIAN == 'true'
|
||||
run: fusermount -z -u ${GITHUB_WORKSPACE}/regress || true
|
||||
working-directory: ${{ runner.temp }}
|
||||
|
||||
- name: lazily unmount workspace
|
||||
if: always() && env.SSHFS == 'true'
|
||||
run: fusermount -z -u ${GITHUB_WORKSPACE} || true
|
||||
working-directory: ${{ runner.temp }}
|
||||
- name: shutdown VM
|
||||
if: always() && env.VM == 'true'
|
||||
run: vmshutdown
|
78
.github/workflows/upstream.yml
vendored
Normal file
78
.github/workflows/upstream.yml
vendored
Normal file
|
@ -0,0 +1,78 @@
|
|||
name: Upstream self-hosted
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
paths: [ '**.c', '**.h', '**.sh', '.github/configs', '.github/workflows/upstream.yml' ]
|
||||
|
||||
jobs:
|
||||
selfhosted:
|
||||
name: "upstream ${{ matrix.target }} ${{ matrix.config }}"
|
||||
if: github.repository == 'openssh/openssh-portable-selfhosted'
|
||||
runs-on: ${{ matrix.host }}
|
||||
env:
|
||||
DEBUG_ACTIONS: true
|
||||
EPHEMERAL: true
|
||||
HOST: ${{ matrix.host }}
|
||||
TARGET_HOST: ${{ matrix.target }}
|
||||
TARGET_CONFIG: ${{ matrix.config }}
|
||||
TARGET_DOMAIN: ${{ format('{0}-{1}-{2}', matrix.target, matrix.config, github.run_id) || matrix.target }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
host:
|
||||
- libvirt
|
||||
target: [ obsdsnap, obsdsnap-i386 ]
|
||||
config: [ default, without-openssl, ubsan ]
|
||||
include:
|
||||
- { host: libvirt-arm64, target: obsdsnap-arm64, config: default }
|
||||
- { host: libvirt-arm64, target: obsdsnap-arm64, config: without-openssl }
|
||||
- { host: libvirt-arm64, target: obsdsnap-arm64, config: ubsan }
|
||||
steps:
|
||||
- name: unmount stale workspace
|
||||
run: fusermount -u ${GITHUB_WORKSPACE} || true
|
||||
working-directory: ${{ runner.temp }}
|
||||
- name: shutdown VM if running
|
||||
run: vmshutdown
|
||||
working-directory: ${{ runner.temp }}
|
||||
- uses: actions/checkout@main
|
||||
- name: startup VM
|
||||
run: vmstartup
|
||||
working-directory: ${{ runner.temp }}
|
||||
- name: copy and mount workspace
|
||||
run: sshfs_mount
|
||||
working-directory: ${{ runner.temp }}
|
||||
- name: update source
|
||||
run: vmrun "cd /usr/src && cvs up -dPA usr.bin/ssh regress/usr.bin/ssh"
|
||||
- name: make clean
|
||||
run: vmrun "cd /usr/src/usr.bin/ssh && make obj && make clean && cd /usr/src/regress/usr.bin/ssh && make obj && make clean && sudo chmod -R g-w /usr/src /usr/obj"
|
||||
- name: make
|
||||
run: vmrun "cd /usr/src/usr.bin/ssh && case ${{ matrix.config }} in without-openssl) make OPENSSL=no;; ubsan) make DEBUG='-fsanitize-minimal-runtime -fsanitize=undefined';; *) make; esac"
|
||||
- name: make install
|
||||
run: vmrun "cd /usr/src/usr.bin/ssh && sudo make install && sudo /etc/rc.d/sshd -f restart"
|
||||
- name: make tests`
|
||||
run: vmrun "cd /usr/src/regress/usr.bin/ssh && case ${{ matrix.config }} in without-openssl) make OPENSSL=no;; ubsan) make DEBUG='-fsanitize-minimal-runtime -fsanitize=undefined';; *) make; esac"
|
||||
env:
|
||||
SUDO: sudo
|
||||
timeout-minutes: 300
|
||||
- name: show logs
|
||||
if: failure()
|
||||
run: vmrun 'for i in /usr/src/regress/usr.bin/ssh/obj/*.log; do echo ====; echo logfile $i; echo =====; cat $i; done'
|
||||
- name: save logs
|
||||
if: failure()
|
||||
uses: actions/upload-artifact@main
|
||||
with:
|
||||
name: ${{ matrix.target }}-${{ matrix.config }}-logs
|
||||
path: |
|
||||
/usr/src/regress/usr.bin/ssh/obj/*.log
|
||||
/usr/src/regress/usr.bin/ssh/obj/log/*
|
||||
- name: unmount workspace
|
||||
if: always()
|
||||
run: |
|
||||
fusermount -u ${GITHUB_WORKSPACE} || true
|
||||
fusermount -z -u ${GITHUB_WORKSPACE} || true
|
||||
working-directory: ${{ runner.temp }}
|
||||
- name: shutdown VM
|
||||
if: always()
|
||||
run: vmshutdown
|
||||
working-directory: ${{ runner.temp }}
|
39
.gitignore
vendored
Normal file
39
.gitignore
vendored
Normal file
|
@ -0,0 +1,39 @@
|
|||
Makefile
|
||||
buildpkg.sh
|
||||
config.h
|
||||
config.h.in~
|
||||
config.log
|
||||
config.status
|
||||
openbsd-compat/Makefile
|
||||
openbsd-compat/regress/Makefile
|
||||
openssh.xml
|
||||
opensshd.init
|
||||
survey.sh
|
||||
**/*.o
|
||||
**/*.lo
|
||||
**/*.so
|
||||
**/*.dylib
|
||||
**/*.dll
|
||||
**/*.out
|
||||
**/*.a
|
||||
**/*.un~
|
||||
**/.*.swp
|
||||
autom4te.cache/
|
||||
scp
|
||||
sftp
|
||||
sftp-server
|
||||
ssh
|
||||
ssh-add
|
||||
ssh-agent
|
||||
ssh-keygen
|
||||
ssh-keyscan
|
||||
ssh-keysign
|
||||
ssh-pkcs11-helper
|
||||
ssh-sk-helper
|
||||
sshd
|
||||
sshd-session
|
||||
sshd-auth
|
||||
!regress/misc/**/Makefile
|
||||
!regress/unittests/**/Makefile
|
||||
tags
|
||||
|
67
.skipped-commit-ids
Normal file
67
.skipped-commit-ids
Normal file
|
@ -0,0 +1,67 @@
|
|||
509bb19bb9762a4b3b589af98bac2e730541b6d4 clean sshd random relinking kit
|
||||
5317f294d63a876bfc861e19773b1575f96f027d remove libssh from makefiles
|
||||
a337e886a49f96701ccbc4832bed086a68abfa85 Makefile changes
|
||||
f2c9feb26963615c4fece921906cf72e248b61ee more Makefile
|
||||
fa728823ba21c4b45212750e1d3a4b2086fd1a62 more Makefile refactoring
|
||||
1de0e85522051eb2ffa00437e1885e9d7b3e0c2e moduli update
|
||||
814b2f670df75759e1581ecef530980b2b3d7e0f remove redundant make defs
|
||||
04431e8e7872f49a2129bf080a6b73c19d576d40 moduli update
|
||||
c07772f58028fda683ee6abd41c73da3ff70d403 moduli update
|
||||
db6375fc302e3bdf07d96430c63c991b2c2bd3ff moduli update
|
||||
5ea3d63ab972691f43e9087ab5fd8376d48e898f uuencode.c Makefile accident
|
||||
99dd10e72c04e93849981d43d64c946619efa474 include sshbuf-misc.c
|
||||
9e1c23476bb845f3cf3d15d9032da3ed0cb2fcf5 sshbuf-misc.c in regress
|
||||
569f08445c27124ec7c7f6c0268d844ec56ac061 Makefile tweaks for !openssl
|
||||
58ec755be4e51978ecfee73539090eb68652a987 moduli update
|
||||
4bd5551b306df55379afe17d841207990eb773bf Makefile.inc
|
||||
14806a59353152f843eb349e618abbf6f4dd3ada Makefile.inc
|
||||
8ea4455a2d9364a0a04f9e4a2cbfa4c9fcefe77e Makefile.inc
|
||||
d9b910e412d139141b072a905e66714870c38ac0 Makefile.inc
|
||||
7b7b619c1452a459310b0cf4391c5757c6bdbc0f moduli update
|
||||
5010ff08f7ad92082e87dde098b20f5c24921a8f moduli regen script update
|
||||
3bcae7a754db3fc5ad3cab63dd46774edb35b8ae moduli regen script update
|
||||
52ff0e3205036147b2499889353ac082e505ea54 moduli update
|
||||
07b5031e9f49f2b69ac5e85b8da4fc9e393992a0 Makefile.inc
|
||||
cc12a9029833d222043aecd252d654965c351a69 moduli-gen Makefile
|
||||
7ac6c252d2a5be8fbad4c66d9d35db507c9dac5b moduli update
|
||||
6b52cd2b637f3d29ef543f0ce532a2bce6d86af5 makefile change
|
||||
f9a0726d957cf10692a231996a1f34e7f9cdfeb0 moduli update
|
||||
1e0a2692b7e20b126dda60bf04999d1d30d959d8 sshd relinking makefile changes
|
||||
e1dc11143f83082e3154d6094f9136d0dc2637ad more relinking makefile tweaks
|
||||
5a636f6ca7f25bfe775df4952f7aac90a7fcbbee moduli update
|
||||
ef9341d5a50f0d33e3a6fbe995e92964bc7ef2d3 Makefile relinking changes
|
||||
2fe8d707ae35ba23c7916adcb818bb5b66837ba0 ssh-agent relink kit
|
||||
866cfcc1955aef8f3fc32da0b70c353a1b859f2e ssh-agent relink changes
|
||||
8b3820adb4da4e139c4b3cffbcc0bde9f08bf0c6 sshd-session relink kit
|
||||
6d2ded4cd91d4d727c2b26e099b91ea935bed504 relink kit
|
||||
fb39324748824cb0387e9d67c41d1bef945c54ea Makefile change
|
||||
5f378c38ad8976d507786dc4db9283a879ec8cd0 Makefile change
|
||||
112aacedd3b61cc5c34b1fa6d9fb759214179172 Makefile change
|
||||
a959fc45ea3431b36f52eda04faefc58bcde00db groupaccess.c changes
|
||||
6d07e4606997e36b860621a14dd41975f2902f8f Makefile.inc
|
||||
|
||||
Old upstream tree:
|
||||
|
||||
321065a95a7ccebdd5fd08482a1e19afbf524e35 Update DH groups
|
||||
d4f699a421504df35254cf1c6f1a7c304fb907ca Remove 1k bit groups
|
||||
aafe246655b53b52bc32c8a24002bc262f4230f7 Remove intermediate moduli
|
||||
8fa9cd1dee3c3339ae329cf20fb591db6d605120 put back SSH1 for 6.9
|
||||
f31327a48dd4103333cc53315ec53fe65ed8a17a Generate new moduli
|
||||
edbfde98c40007b7752a4ac106095e060c25c1ef Regen moduli
|
||||
052fd565e3ff2d8cec3bc957d1788f50c827f8e2 Switch to tame-based sandbox
|
||||
7cf73737f357492776223da1c09179fa6ba74660 Remove moduli <2k
|
||||
180d84674be1344e45a63990d60349988187c1ae Update moduli
|
||||
f6ae971186ba68d066cd102e57d5b0b2c211a5ee systrace is dead.
|
||||
96c5054e3e1f170c6276902d5bc65bb3b87a2603 remove DEBUGLIBS from Makefile
|
||||
6da9a37f74aef9f9cc639004345ad893cad582d8 Update moduli file
|
||||
77bcb50e47b68c7209c7f0a5a020d73761e5143b unset REGRESS_FAIL_EARLY
|
||||
38c2133817cbcae75c88c63599ac54228f0fa384 Change COMPILER_VERSION tests
|
||||
30c20180c87cbc99fa1020489fe7fd8245b6420c resync integrity.sh shell
|
||||
1e6b51ddf767cbad0a4e63eb08026c127e654308 integrity.sh reliability
|
||||
fe5b31f69a60d47171836911f144acff77810217 Makefile.inc bits
|
||||
5781670c0578fe89663c9085ed3ba477cf7e7913 Delete sshconnect1.c
|
||||
ea80f445e819719ccdcb237022cacfac990fdc5c Makefile.inc warning flags
|
||||
b92c93266d8234d493857bb822260dacf4366157 moduli-gen.sh tweak
|
||||
b25bf747544265b39af74fe0716dc8d9f5b63b95 Updated moduli
|
||||
1bd41cba06a7752de4df304305a8153ebfb6b0ac rsa.[ch] already removed
|
||||
e39b3902fe1d6c4a7ba6a3c58e072219f3c1e604 Makefile changes
|
102
CREDITS
Normal file
102
CREDITS
Normal file
|
@ -0,0 +1,102 @@
|
|||
Tatu Ylonen <ylo@cs.hut.fi> - Creator of SSH
|
||||
|
||||
Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos,
|
||||
Theo de Raadt, and Dug Song - Creators of OpenSSH
|
||||
|
||||
Ahsan Rashid <arms@sco.com> - UnixWare long passwords
|
||||
Alain St-Denis <Alain.St-Denis@ec.gc.ca> - Irix fix
|
||||
Alexandre Oliva <oliva@lsd.ic.unicamp.br> - AIX fixes
|
||||
Andre Lucas <andre@ae-35.com> - new login code, many fixes
|
||||
Andreas Steinmetz <ast@domdv.de> - Shadow password expiry support
|
||||
Andrew McGill <andrewm@datrix.co.za> - SCO fixes
|
||||
Andrew Morgan <morgan@transmeta.com> - PAM bugfixes
|
||||
Andrew Stribblehill <a.d.stribblehill@durham.ac.uk> - Bugfixes
|
||||
Andy Sloane <andy@guildsoftware.com> - bugfixes
|
||||
Aran Cox <acox@cv.telegroup.com> - SCO bugfixes
|
||||
Arkadiusz Miskiewicz <misiek@pld.org.pl> - IPv6 compat fixes
|
||||
Ben Lindstrom <mouring@eviladmin.org> - NeXT support
|
||||
Ben Taylor <bent@clark.net> - Solaris debugging and fixes
|
||||
Bratislav ILICH <bilic@zepter.ru> - Configure fix
|
||||
Charles Levert <charles@comm.polymtl.ca> - SunOS 4 & bug fixes
|
||||
Chip Salzenberg <chip@valinux.com> - Assorted patches
|
||||
Chris Adams <cmadams@hiwaay.net> - OSF SIA support
|
||||
Chris Saia <csaia@wtower.com> - SuSE packaging
|
||||
Chris, the Young One <cky@pobox.com> - Password auth fixes
|
||||
Christos Zoulas <christos@zoulas.com> - Autoconf fixes
|
||||
Chun-Chung Chen <cjj@u.washington.edu> - RPM fixes
|
||||
Corinna Vinschen <vinschen@redhat.com> - Cygwin support
|
||||
Chad Mynhier <mynhier@interstel.net> - Solaris Process Contract support
|
||||
Dan Brosemer <odin@linuxfreak.com> - Autoconf support, build fixes
|
||||
Darren Hall <dhall@virage.org> - AIX patches
|
||||
Darren Tucker <dtucker@zip.com.au> - AIX BFF package scripts
|
||||
David Agraz <dagraz@jahoopa.com> - Build fixes
|
||||
David Del Piero <David.DelPiero@qed.qld.gov.au> - bug fixes
|
||||
David Hesprich <darkgrue@gue-tech.org> - Configure fixes
|
||||
David Rankin <drankin@bohemians.lexington.ky.us> - libwrap, AIX, NetBSD fixes
|
||||
Dag-Erling Smørgrav <des at freebsd.org> - Challenge-Response PAM code.
|
||||
Dhiraj Gulati <dgulati@sco.com> - UnixWare long passwords
|
||||
Ed Eden <ede370@stl.rural.usda.gov> - configure fixes
|
||||
Garrick James <garrick@james.net> - configure fixes
|
||||
Gary E. Miller <gem@rellim.com> - SCO support
|
||||
Ged Lodder <lodder@yacc.com.au> - HPUX fixes and enhancements
|
||||
Gert Doering <gd@hilb1.medat.de> - bug and portability fixes
|
||||
HARUYAMA Seigo <haruyama@unixuser.org> - Translations & doc fixes
|
||||
Hideaki YOSHIFUJI <yoshfuji@ecei.tohoku.ac.jp> - IPv6 and bug fixes
|
||||
Hiroshi Takekawa <takekawa@sr3.t.u-tokyo.ac.jp> - Configure fixes
|
||||
Holger Trapp <Holger.Trapp@Informatik.TU-Chemnitz.DE> - KRB4/AFS config patch
|
||||
IWAMURO Motonori <iwa@mmp.fujitsu.co.jp> - bugfixes
|
||||
Jani Hakala <jahakala@cc.jyu.fi> - Patches
|
||||
Jarno Huuskonen <jhuuskon@hytti.uku.fi> - Bugfixes
|
||||
Jim Knoble <jmknoble@pobox.com> - Many patches
|
||||
Jonchen (email unknown) - the original author of PAM support of SSH
|
||||
Juergen Keil <jk@tools.de> - scp bugfixing
|
||||
KAMAHARA Junzo <kamahara@cc.kshosen.ac.jp> - Configure fixes
|
||||
Kees Cook <cook@cpoint.net> - scp fixes
|
||||
Kenji Miyake <kenji@miyake.org> - Configure fixes
|
||||
Kevin Cawlfield <cawlfiel@us.ibm.com> - AIX fixes.
|
||||
Kevin O'Connor <kevin_oconnor@standardandpoors.com> - RSAless operation
|
||||
Kevin Steves <stevesk@pobox.com> - HP support, bugfixes, improvements
|
||||
Kiyokazu SUTO <suto@ks-and-ks.ne.jp> - Bugfixes
|
||||
Larry Jones <larry.jones@sdrc.com> - Bugfixes
|
||||
Lutz Jaenicke <Lutz.Jaenicke@aet.TU-Cottbus.DE> - Bugfixes
|
||||
Marc G. Fournier <marc.fournier@acadiau.ca> - Solaris patches
|
||||
Mark D. Baushke <mdb@juniper.net> - bug fixes
|
||||
Martin Johansson <fatbob@acc.umu.se> - Linux fixes
|
||||
Mark D. Roth <roth+openssh@feep.net> - Features, bug fixes
|
||||
Mark Miller <markm@swoon.net> - Bugfixes
|
||||
Matt Richards <v2matt@btv.ibm.com> - AIX patches
|
||||
Michael Steffens <michael_steffens at hp.com> - HP-UX fixes
|
||||
Michael Stone <mstone@cs.loyola.edu> - Irix enhancements
|
||||
Nakaji Hiroyuki <nakaji@tutrp.tut.ac.jp> - Sony News-OS patch
|
||||
Nalin Dahyabhai <nalin.dahyabhai@pobox.com> - PAM environment patch
|
||||
Nate Itkin <nitkin@europa.com> - SunOS 4.1.x fixes
|
||||
Niels Kristian Bech Jensen <nkbj@image.dk> - Assorted patches
|
||||
Pavel Kankovsky <peak@argo.troja.mff.cuni.cz> - Security fixes
|
||||
Pavel Troller <patrol@omni.sinus.cz> - Bugfixes
|
||||
Pekka Savola <pekkas@netcore.fi> - Bugfixes
|
||||
Peter Kocks <peter.kocks@baygate.com> - Makefile fixes
|
||||
Peter Stuge <stuge@cdy.org> - mdoc2man.awk script
|
||||
Phil Hands <phil@hands.com> - Debian scripts, assorted patches
|
||||
Phil Karn <karn@ka9q.ampr.org> - Autoconf fixes
|
||||
Philippe WILLEM <Philippe.WILLEM@urssaf.fr> - Bugfixes
|
||||
Phill Camp <P.S.S.Camp@ukc.ac.uk> - login code fix
|
||||
Rip Loomis <loomisg@cist.saic.com> - Solaris package support, fixes
|
||||
Robert Dahlem <Robert.Dahlem at siemens.com> - Reliant Unix fixes
|
||||
Roumen Petrov <openssh@roumenpetrov.info> - Compile & configure fixes
|
||||
SAKAI Kiyotaka <ksakai@kso.netwk.ntt-at.co.jp> - Multiple bugfixes
|
||||
Simon Wilkinson <sxw@dcs.ed.ac.uk> - PAM fixes, Compat with MIT KrbV
|
||||
Solar Designer <solar@openwall.com> - many patches and technical assistance
|
||||
Svante Signell <svante.signell@telia.com> - Bugfixes
|
||||
Thomas Neumann <tom@smart.ruhr.de> - Shadow passwords
|
||||
Tim Rice <tim@multitalents.net> - Portability & SCO fixes
|
||||
Tobias Oetiker <oetiker@ee.ethz.ch> - Bugfixes
|
||||
Tom Bertelson's <tbert@abac.com> - AIX auth fixes
|
||||
Tor-Ake Fransson <torake@hotmail.com> - AIX support
|
||||
Tudor Bosman <tudorb@jm.nu> - MD5 password support
|
||||
Udo Schweigert <ust@cert.siemens.de> - ReliantUNIX support
|
||||
Wendy Palm <wendyp at cray.com> - Cray support.
|
||||
Zack Weinberg <zack@wolery.cumb.org> - GNOME askpass enhancement
|
||||
|
||||
Apologies to anyone I have missed.
|
||||
|
||||
Damien Miller <djm@mindrot.org>
|
283
INSTALL
Normal file
283
INSTALL
Normal file
|
@ -0,0 +1,283 @@
|
|||
1. Prerequisites
|
||||
----------------
|
||||
|
||||
A C compiler. Any C89 or better compiler that supports variadic macros
|
||||
should work. Where supported, configure will attempt to enable the
|
||||
compiler's run-time integrity checking options. Some notes about
|
||||
specific compilers:
|
||||
- clang: -ftrapv and -sanitize=integer require the compiler-rt runtime
|
||||
(CC=clang LDFLAGS=--rtlib=compiler-rt ./configure)
|
||||
|
||||
To support Privilege Separation (which is now required) you will need
|
||||
to create the user, group and directory used by sshd for privilege
|
||||
separation. See README.privsep for details.
|
||||
|
||||
|
||||
The remaining items are optional.
|
||||
|
||||
A working installation of zlib:
|
||||
Zlib 1.1.4 or 1.2.1.2 or greater (earlier 1.2.x versions have problems):
|
||||
https://zlib.net/
|
||||
|
||||
libcrypto from either of LibreSSL or OpenSSL. Building without libcrypto
|
||||
is supported but severely restricts the available ciphers and algorithms.
|
||||
- LibreSSL (https://www.libressl.org/) 3.1.0 or greater
|
||||
- OpenSSL (https://www.openssl.org) 1.1.1 or greater
|
||||
|
||||
LibreSSL/OpenSSL should be compiled as a position-independent library
|
||||
(i.e. -fPIC, eg by configuring OpenSSL as "./config [options] -fPIC"
|
||||
or LibreSSL as "CFLAGS=-fPIC ./configure") otherwise OpenSSH will not
|
||||
be able to link with it. If you must use a non-position-independent
|
||||
libcrypto, then you may need to configure OpenSSH --without-pie.
|
||||
|
||||
If you build either from source, running the OpenSSL self-test ("make
|
||||
tests") or the LibreSSL equivalent ("make check") and ensuring that all
|
||||
tests pass is strongly recommended.
|
||||
|
||||
NB. If you operating system supports /dev/random, you should configure
|
||||
libcrypto (LibreSSL/OpenSSL) to use it. OpenSSH relies on libcrypto's
|
||||
direct support of /dev/random, or failing that, either prngd or egd.
|
||||
|
||||
PRNGD:
|
||||
|
||||
If your system lacks kernel-based random collection, the use of Lutz
|
||||
Jaenicke's PRNGd is recommended. 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.
|
||||
The same caveats about configuration for prngd also apply.
|
||||
|
||||
http://egd.sourceforge.net/
|
||||
|
||||
PAM:
|
||||
|
||||
OpenSSH can utilise Pluggable Authentication Modules (PAM) if your
|
||||
system supports it. PAM is standard most Linux distributions, Solaris,
|
||||
HP-UX 11, AIX >= 5.2, FreeBSD, NetBSD and Mac OS X.
|
||||
|
||||
Information about the various PAM implementations are available:
|
||||
|
||||
Solaris PAM: http://www.sun.com/software/solaris/pam/
|
||||
Linux PAM: http://www.kernel.org/pub/linux/libs/pam/
|
||||
OpenPAM: http://www.openpam.org/
|
||||
|
||||
If you wish to build the GNOME passphrase requester, you will need the GNOME
|
||||
libraries and headers.
|
||||
|
||||
GNOME:
|
||||
http://www.gnome.org/
|
||||
|
||||
Alternatively, Jim Knoble <jmknoble@pobox.com> has written an excellent X11
|
||||
passphrase requester. This is maintained separately at:
|
||||
|
||||
http://www.jmknoble.net/software/x11-ssh-askpass/
|
||||
|
||||
LibEdit:
|
||||
|
||||
sftp supports command-line editing via NetBSD's libedit. If your platform
|
||||
has it available natively you can use that, alternatively you might try
|
||||
these multi-platform ports:
|
||||
|
||||
http://www.thrysoee.dk/editline/
|
||||
http://sourceforge.net/projects/libedit/
|
||||
|
||||
LDNS:
|
||||
|
||||
LDNS is a DNS BSD-licensed resolver library which supports DNSSEC.
|
||||
|
||||
http://nlnetlabs.nl/projects/ldns/
|
||||
|
||||
Autoconf:
|
||||
|
||||
If you modify configure.ac or configure doesn't exist (eg if you checked
|
||||
the 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/
|
||||
http://www.gnu.org/software/automake/
|
||||
|
||||
Basic Security Module (BSM):
|
||||
|
||||
Native BSM support is known to exist in Solaris from at least 2.5.1,
|
||||
FreeBSD 6.1 and OS X. Alternatively, you may use the OpenBSM
|
||||
implementation (http://www.openbsm.org).
|
||||
|
||||
makedepend:
|
||||
|
||||
https://www.x.org/archive/individual/util/
|
||||
|
||||
If you are making significant changes to the code you may need to rebuild
|
||||
the dependency (.depend) file using "make depend", which requires the
|
||||
"makedepend" tool from the X11 distribution.
|
||||
|
||||
libfido2:
|
||||
|
||||
libfido2 allows the use of hardware security keys over USB. libfido2
|
||||
in turn depends on libcbor. libfido2 >= 1.5.0 is strongly recommended.
|
||||
Limited functionality is possible with earlier libfido2 versions.
|
||||
|
||||
https://github.com/Yubico/libfido2
|
||||
https://github.com/pjk/libcbor
|
||||
|
||||
|
||||
2. Building / Installation
|
||||
--------------------------
|
||||
|
||||
To install OpenSSH with default options:
|
||||
|
||||
./configure
|
||||
make
|
||||
make install
|
||||
|
||||
This will install the OpenSSH binaries in /usr/local/bin, configuration files
|
||||
in /usr/local/etc, the server in /usr/local/sbin, etc. To specify a different
|
||||
installation prefix, use the --prefix option to configure:
|
||||
|
||||
./configure --prefix=/opt
|
||||
make
|
||||
make install
|
||||
|
||||
Will install OpenSSH in /opt/{bin,etc,lib,sbin}. You can also override
|
||||
specific paths, for example:
|
||||
|
||||
./configure --prefix=/opt --sysconfdir=/etc/ssh
|
||||
make
|
||||
make install
|
||||
|
||||
This will install the binaries in /opt/{bin,lib,sbin}, but will place the
|
||||
configuration files in /etc/ssh.
|
||||
|
||||
If you are using PAM, you may need to manually install a PAM control
|
||||
file as "/etc/pam.d/sshd" (or wherever your system prefers to keep
|
||||
them). Note that the service name used to start PAM is __progname,
|
||||
which is the basename of the path of your sshd (e.g., the service name
|
||||
for /usr/sbin/osshd will be osshd). If you have renamed your sshd
|
||||
executable, your PAM configuration may need to be modified.
|
||||
|
||||
A generic PAM configuration is included as "contrib/sshd.pam.generic",
|
||||
you may need to edit it before using it on your system. If you are
|
||||
using a recent version of Red Hat Linux, the config file in
|
||||
contrib/redhat/sshd.pam should be more useful. Failure to install a
|
||||
valid PAM file may result in an inability to use password
|
||||
authentication. On HP-UX 11 and Solaris, the standard /etc/pam.conf
|
||||
configuration will work with sshd (sshd will match the other service
|
||||
name).
|
||||
|
||||
There are a few other options to the configure script:
|
||||
|
||||
--with-audit=[module] enable additional auditing via the specified module.
|
||||
Currently, drivers for "debug" (additional info via syslog) and "bsm"
|
||||
(Sun's Basic Security Module) are supported.
|
||||
|
||||
--with-pam enables PAM support. If PAM support is compiled in, it must
|
||||
also be enabled in sshd_config (refer to the UsePAM directive).
|
||||
|
||||
--with-prngd-socket=/some/file allows you to enable EGD or PRNGD
|
||||
support and to specify a PRNGd socket. Use this if your Unix lacks
|
||||
/dev/random.
|
||||
|
||||
--with-prngd-port=portnum allows you to enable EGD or PRNGD support
|
||||
and to specify a EGD localhost TCP port. Use this if your Unix lacks
|
||||
/dev/random.
|
||||
|
||||
--with-lastlog=FILE will specify the location of the lastlog file.
|
||||
./configure searches a few locations for lastlog, but may not find
|
||||
it if lastlog is installed in a different place.
|
||||
|
||||
--without-lastlog will disable lastlog support entirely.
|
||||
|
||||
--with-osfsia, --without-osfsia will enable or disable OSF1's Security
|
||||
Integration Architecture. The default for OSF1 machines is enable.
|
||||
|
||||
--with-utmpx enables utmpx support. utmpx support is automatic for
|
||||
some platforms.
|
||||
|
||||
--without-shadow disables shadow password support.
|
||||
|
||||
--with-ipaddr-display forces the use of a numeric IP address in the
|
||||
$DISPLAY environment variable. Some broken systems need this.
|
||||
|
||||
--with-default-path=PATH allows you to specify a default $PATH for sessions
|
||||
started by sshd. This replaces the standard path entirely.
|
||||
|
||||
--with-pid-dir=PATH specifies the directory in which the sshd.pid file is
|
||||
created.
|
||||
|
||||
--with-xauth=PATH specifies the location of the xauth binary
|
||||
|
||||
--with-ssl-dir=DIR allows you to specify where your Libre/OpenSSL
|
||||
libraries are installed.
|
||||
|
||||
--with-ssl-engine enables Libre/OpenSSL's (hardware) ENGINE support
|
||||
|
||||
--without-openssl builds without using OpenSSL. Only a subset of ciphers
|
||||
and algorithms are supported in this configuration.
|
||||
|
||||
--without-zlib builds without zlib. This disables the Compression option.
|
||||
|
||||
--with-4in6 Check for IPv4 in IPv6 mapped addresses and convert them to
|
||||
real (AF_INET) IPv4 addresses. Works around some quirks on Linux.
|
||||
|
||||
If you need to pass special options to the compiler or linker, you
|
||||
can specify these as environment variables before running ./configure.
|
||||
For example:
|
||||
|
||||
CC="/usr/foo/cc" CFLAGS="-O" LDFLAGS="-s" LIBS="-lrubbish" ./configure
|
||||
|
||||
3. Configuration
|
||||
----------------
|
||||
|
||||
The runtime configuration files are installed by in ${prefix}/etc or
|
||||
whatever you specified as your --sysconfdir (/usr/local/etc by default).
|
||||
|
||||
The default configuration should be instantly usable, though you should
|
||||
review it to ensure that it matches your security requirements.
|
||||
|
||||
To generate a host key, run "make host-key". Alternately you can do so
|
||||
manually using the following commands:
|
||||
|
||||
ssh-keygen -t [type] -f /etc/ssh/ssh_host_key -N ""
|
||||
|
||||
for each of the types you wish to generate (rsa, dsa or ecdsa) or
|
||||
|
||||
ssh-keygen -A
|
||||
|
||||
to generate keys for all supported types.
|
||||
|
||||
Replacing /etc/ssh with the correct path to the configuration directory.
|
||||
(${prefix}/etc or whatever you specified with --sysconfdir during
|
||||
configuration).
|
||||
|
||||
If you have configured OpenSSH with EGD/prngd support, ensure that EGD or
|
||||
prngd is running and has collected some entropy first.
|
||||
|
||||
For more information on configuration, please refer to the manual pages
|
||||
for sshd, ssh and ssh-agent.
|
||||
|
||||
4. (Optional) Send survey
|
||||
-------------------------
|
||||
|
||||
$ make survey
|
||||
[check the contents of the file "survey" to ensure there's no information
|
||||
that you consider sensitive]
|
||||
$ make send-survey
|
||||
|
||||
This will send configuration information for the currently configured
|
||||
host to a survey address. This will help determine which configurations
|
||||
are actually in use, and what valid combinations of configure options
|
||||
exist. The raw data is available only to the OpenSSH developers, however
|
||||
summary data may be published.
|
||||
|
||||
5. Problems?
|
||||
------------
|
||||
|
||||
If you experience problems compiling, installing or running OpenSSH,
|
||||
please refer to the "reporting bugs" section of the webpage at
|
||||
https://www.openssh.com/
|
412
LICENCE
Normal file
412
LICENCE
Normal file
|
@ -0,0 +1,412 @@
|
|||
This file is part of the OpenSSH software.
|
||||
|
||||
The licences which components of this software fall under are as
|
||||
follows. First, we will summarize and say that all components
|
||||
are under a BSD licence, or a licence more free than that.
|
||||
|
||||
OpenSSH contains no GPL code.
|
||||
|
||||
1)
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
* All rights reserved
|
||||
*
|
||||
* As far as I am concerned, the code I have written for this software
|
||||
* can be used freely for any purpose. Any derived versions of this
|
||||
* software must be clearly marked as such, and if the derived work is
|
||||
* incompatible with the protocol description in the RFC file, it must be
|
||||
* called by a name other than "ssh" or "Secure Shell".
|
||||
|
||||
[Tatu continues]
|
||||
* However, I am not implying to give any licenses to any patents or
|
||||
* copyrights held by third parties, and the software includes parts that
|
||||
* are not under my direct control. As far as I know, all included
|
||||
* source code is used in accordance with the relevant license agreements
|
||||
* and can be used freely for any purpose (the GNU license being the most
|
||||
* restrictive); see below for details.
|
||||
|
||||
[However, none of that term is relevant at this point in time. All of
|
||||
these restrictively licenced software components which he talks about
|
||||
have been removed from OpenSSH, i.e.,
|
||||
|
||||
- RSA is no longer included, found in the OpenSSL library
|
||||
- IDEA is no longer included, its use is deprecated
|
||||
- DES is now external, in the OpenSSL library
|
||||
- GMP is no longer used, and instead we call BN code from OpenSSL
|
||||
- Zlib is now external, in a library
|
||||
- The make-ssh-known-hosts script is no longer included
|
||||
- TSS has been removed
|
||||
- MD5 is now external, in the OpenSSL library
|
||||
- RC4 support has been replaced with ARC4 support from OpenSSL
|
||||
- Blowfish is now external, in the OpenSSL library
|
||||
|
||||
[The licence continues]
|
||||
|
||||
Note that any information and cryptographic algorithms used in this
|
||||
software are publicly available on the Internet and at any major
|
||||
bookstore, scientific library, and patent office worldwide. More
|
||||
information can be found e.g. at "http://www.cs.hut.fi/crypto".
|
||||
|
||||
The legal status of this program is some combination of all these
|
||||
permissions and restrictions. Use only at your own responsibility.
|
||||
You will be responsible for any legal consequences yourself; I am not
|
||||
making any claims whether possessing or using this is legal or not in
|
||||
your country, and I am not taking any responsibility on your behalf.
|
||||
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
3)
|
||||
ssh-keyscan was contributed by David Mazieres under a BSD-style
|
||||
license.
|
||||
|
||||
* Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>.
|
||||
*
|
||||
* Modification and redistribution in source and binary forms is
|
||||
* permitted provided that due credit is given to the author and the
|
||||
* OpenBSD project by leaving this copyright notice intact.
|
||||
|
||||
4)
|
||||
The Rijndael implementation by Vincent Rijmen, Antoon Bosselaers
|
||||
and Paulo Barreto is in the public domain and distributed
|
||||
with the following license:
|
||||
|
||||
* @version 3.0 (December 2000)
|
||||
*
|
||||
* Optimised ANSI C code for the Rijndael cipher (now AES)
|
||||
*
|
||||
* @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
|
||||
* @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
|
||||
* @author Paulo Barreto <paulo.barreto@terra.com.br>
|
||||
*
|
||||
* This code is hereby placed in the public domain.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''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 AUTHORS OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
5)
|
||||
One component of the ssh source code is under a 3-clause BSD license,
|
||||
held by the University of California, since we pulled these parts from
|
||||
original Berkeley code.
|
||||
|
||||
* Copyright (c) 1983, 1990, 1992, 1993, 1995
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
|
||||
6)
|
||||
Remaining components of the software are provided under a standard
|
||||
2-term BSD licence with the following names as copyright holders:
|
||||
|
||||
Markus Friedl
|
||||
Theo de Raadt
|
||||
Niels Provos
|
||||
Dug Song
|
||||
Aaron Campbell
|
||||
Damien Miller
|
||||
Kevin Steves
|
||||
Daniel Kouril
|
||||
Wesley Griffin
|
||||
Per Allansson
|
||||
Nils Nordman
|
||||
Simon Wilkinson
|
||||
|
||||
Portable OpenSSH additionally includes code from the following copyright
|
||||
holders, also under the 2-term BSD license:
|
||||
|
||||
Ben Lindstrom
|
||||
Tim Rice
|
||||
Andre Lucas
|
||||
Chris Adams
|
||||
Corinna Vinschen
|
||||
Cray Inc.
|
||||
Denis Parker
|
||||
Gert Doering
|
||||
Jakob Schlyter
|
||||
Jason Downs
|
||||
Juha Yrjölä
|
||||
Michael Stone
|
||||
Networks Associates Technology, Inc.
|
||||
Solar Designer
|
||||
Todd C. Miller
|
||||
Wayne Schroeder
|
||||
William Jones
|
||||
Darren Tucker
|
||||
Sun Microsystems
|
||||
The SCO Group
|
||||
Daniel Walsh
|
||||
Red Hat, Inc
|
||||
Simon Vallet / Genoscope
|
||||
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
8) Portable OpenSSH contains the following additional licenses:
|
||||
|
||||
a) snprintf replacement
|
||||
|
||||
* Copyright Patrick Powell 1995
|
||||
* This code is based on code written by Patrick Powell
|
||||
* (papowell@astart.com) It may be used for any purpose as long as this
|
||||
* notice remains intact on all source code distributions
|
||||
|
||||
b) Compatibility code (openbsd-compat)
|
||||
|
||||
Apart from the previously mentioned licenses, various pieces of code
|
||||
in the openbsd-compat/ subdirectory are licensed as follows:
|
||||
|
||||
Some code is licensed under a 3-term BSD license, to the following
|
||||
copyright holders:
|
||||
|
||||
Todd C. Miller
|
||||
Theo de Raadt
|
||||
Damien Miller
|
||||
Eric P. Allman
|
||||
The Regents of the University of California
|
||||
Constantin S. Svintsoff
|
||||
Kungliga Tekniska Högskolan
|
||||
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
|
||||
Some code is licensed under an ISC-style license, to the following
|
||||
copyright holders:
|
||||
|
||||
Internet Software Consortium.
|
||||
Todd C. Miller
|
||||
Reyk Floeter
|
||||
Chad Mynhier
|
||||
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND TODD C. MILLER DISCLAIMS ALL
|
||||
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL TODD C. MILLER 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.
|
||||
|
||||
Some code is licensed under a MIT-style license to the following
|
||||
copyright holders:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a *
|
||||
* copy of this software and associated documentation files (the *
|
||||
* "Software"), to deal in the Software without restriction, including *
|
||||
* without limitation the rights to use, copy, modify, merge, publish, *
|
||||
* distribute, distribute with modifications, sublicense, and/or sell *
|
||||
* copies of the Software, and to permit persons to whom the Software is *
|
||||
* furnished to do so, subject to the following conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included *
|
||||
* in all copies or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS *
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. *
|
||||
* IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
|
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
|
||||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR *
|
||||
* THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
* *
|
||||
* Except as contained in this notice, the name(s) of the above copyright *
|
||||
* holders shall not be used in advertising or otherwise to promote the *
|
||||
* sale, use or other dealings in this Software without prior written *
|
||||
* authorization. *
|
||||
****************************************************************************/
|
||||
|
||||
The Blowfish cipher implementation is licensed by Niels Provos under
|
||||
a 3-clause BSD license:
|
||||
|
||||
* Blowfish - a fast block cipher designed by Bruce Schneier
|
||||
*
|
||||
* Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Some replacement code is licensed by the NetBSD foundation under a
|
||||
2-clause BSD license:
|
||||
|
||||
* Copyright (c) 2001 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Todd Vierling.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
The replacement base64 implementation has the following MIT-style
|
||||
licenses:
|
||||
|
||||
* Copyright (c) 1996 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
|
||||
* Portions Copyright (c) 1995 by International Business Machines, Inc.
|
||||
*
|
||||
* International Business Machines, Inc. (hereinafter called IBM) grants
|
||||
* permission under its copyrights to use, copy, modify, and distribute this
|
||||
* Software with or without fee, provided that the above copyright notice and
|
||||
* all paragraphs of this notice appear in all copies, and that the name of IBM
|
||||
* not be used in connection with the marketing of any product incorporating
|
||||
* the Software or modifications thereof, without specific, written prior
|
||||
* permission.
|
||||
*
|
||||
* To the extent it has a right to do so, IBM grants an immunity from suit
|
||||
* under its patents, if any, for the use, sale or manufacture of products to
|
||||
* the extent that such products are used for performing Domain Name System
|
||||
* dynamic updates in TCP/IP networks by means of the Software. No immunity is
|
||||
* granted for any product per se or for any other function of any product.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
|
||||
* DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
|
||||
* IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
------
|
||||
$OpenBSD: LICENCE,v 1.20 2017/04/30 23:26:16 djm Exp $
|
849
Makefile.in
Normal file
849
Makefile.in
Normal file
|
@ -0,0 +1,849 @@
|
|||
SHELL=@SH@
|
||||
|
||||
AUTORECONF=autoreconf
|
||||
|
||||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
bindir=@bindir@
|
||||
sbindir=@sbindir@
|
||||
libexecdir=@libexecdir@
|
||||
datadir=@datadir@
|
||||
datarootdir=@datarootdir@
|
||||
mandir=@mandir@
|
||||
mansubdir=@mansubdir@
|
||||
sysconfdir=@sysconfdir@
|
||||
piddir=@piddir@
|
||||
srcdir=@srcdir@
|
||||
top_srcdir=@top_srcdir@
|
||||
abs_top_srcdir=@abs_top_srcdir@
|
||||
abs_top_builddir=@abs_top_builddir@
|
||||
|
||||
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@
|
||||
SSH_PRIVSEP_USER=@SSH_PRIVSEP_USER@
|
||||
STRIP_OPT=@STRIP_OPT@
|
||||
TEST_SHELL=@TEST_SHELL@
|
||||
BUILDDIR=@abs_top_builddir@
|
||||
SK_STANDALONE=@SK_STANDALONE@
|
||||
|
||||
PATHS= -DSSHDIR=\"$(sysconfdir)\" \
|
||||
-D_PATH_SSH_PROGRAM=\"$(SSH_PROGRAM)\" \
|
||||
-D_PATH_SSH_ASKPASS_DEFAULT=\"$(ASKPASS_PROGRAM)\" \
|
||||
-D_PATH_SFTP_SERVER=\"$(SFTP_SERVER)\" \
|
||||
-D_PATH_SSH_KEY_SIGN=\"$(SSH_KEYSIGN)\" \
|
||||
-D_PATH_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)\" \
|
||||
-D_PATH_PRIVSEP_CHROOT_DIR=\"$(PRIVSEP_PATH)\"
|
||||
|
||||
CC=@CC@
|
||||
LD=@LD@
|
||||
CFLAGS=@CFLAGS@
|
||||
CFLAGS_NOPIE=@CFLAGS_NOPIE@
|
||||
CPPFLAGS=-I. -I$(srcdir) @CPPFLAGS@ $(PATHS) @DEFS@
|
||||
PICFLAG=@PICFLAG@
|
||||
LIBS=@LIBS@
|
||||
CHANNELLIBS=@CHANNELLIBS@
|
||||
K5LIBS=@K5LIBS@
|
||||
GSSLIBS=@GSSLIBS@
|
||||
SSHDLIBS=@SSHDLIBS@
|
||||
LIBEDIT=@LIBEDIT@
|
||||
LIBFIDO2=@LIBFIDO2@
|
||||
LIBWTMPDB=@LIBWTMPDB@
|
||||
AR=@AR@
|
||||
AWK=@AWK@
|
||||
RANLIB=@RANLIB@
|
||||
INSTALL=@INSTALL@
|
||||
SED=@SED@
|
||||
XAUTH_PATH=@XAUTH_PATH@
|
||||
LDFLAGS=-L. -Lopenbsd-compat/ @LDFLAGS@
|
||||
LDFLAGS_NOPIE=-L. -Lopenbsd-compat/ @LDFLAGS_NOPIE@
|
||||
EXEEXT=@EXEEXT@
|
||||
MANFMT=@MANFMT@
|
||||
MKDIR_P=@MKDIR_P@
|
||||
|
||||
.SUFFIXES: .lo
|
||||
|
||||
TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) 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)
|
||||
|
||||
XMSS_OBJS=\
|
||||
ssh-xmss.o \
|
||||
sshkey-xmss.o \
|
||||
xmss_commons.o \
|
||||
xmss_fast.o \
|
||||
xmss_hash.o \
|
||||
xmss_hash_address.o \
|
||||
xmss_wots.o
|
||||
|
||||
LIBOPENSSH_OBJS=\
|
||||
ssh_api.o \
|
||||
ssherr.o \
|
||||
sshbuf.o \
|
||||
sshkey.o \
|
||||
sshbuf-getput-basic.o \
|
||||
sshbuf-misc.o \
|
||||
sshbuf-getput-crypto.o \
|
||||
krl.o \
|
||||
bitmap.o \
|
||||
${XMSS_OBJS}
|
||||
|
||||
LIBSSH_OBJS=${LIBOPENSSH_OBJS} \
|
||||
authfd.o authfile.o \
|
||||
canohost.o channels.o cipher.o cipher-aes.o cipher-aesctr.o \
|
||||
cleanup.o \
|
||||
compat.o fatal.o hostfile.o \
|
||||
log.o match.o moduli.o nchan.o packet.o \
|
||||
readpass.o ttymodes.o xmalloc.o addr.o addrmatch.o \
|
||||
atomicio.o dispatch.o mac.o misc.o utf8.o \
|
||||
monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-ecdsa-sk.o \
|
||||
ssh-ed25519-sk.o ssh-rsa.o dh.o \
|
||||
msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \
|
||||
ssh-pkcs11.o smult_curve25519_ref.o \
|
||||
poly1305.o chacha.o cipher-chachapoly.o cipher-chachapoly-libcrypto.o \
|
||||
ssh-ed25519.o digest-openssl.o digest-libc.o \
|
||||
hmac.o ed25519.o hash.o \
|
||||
kex.o kex-names.o kexdh.o kexgex.o kexecdh.o kexc25519.o \
|
||||
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
|
||||
|
||||
SKOBJS= ssh-sk-client.o
|
||||
|
||||
SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \
|
||||
sshconnect.o sshconnect2.o mux.o $(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)
|
||||
|
||||
SSHD_SESSION_OBJS=sshd-session.o auth-rhosts.o auth-passwd.o \
|
||||
audit.o audit-bsm.o audit-linux.o platform.o \
|
||||
sshpty.o sshlogin.o servconf.o serverloop.o \
|
||||
auth.o auth2.o auth2-methods.o auth-options.o session.o \
|
||||
auth2-chall.o groupaccess.o \
|
||||
auth-bsdauth.o auth2-hostbased.o auth2-kbdint.o \
|
||||
auth2-none.o auth2-passwd.o auth2-pubkey.o auth2-pubkeyfile.o \
|
||||
monitor.o monitor_wrap.o auth-krb5.o \
|
||||
auth2-gss.o gss-serv.o gss-serv-krb5.o \
|
||||
loginrec.o auth-pam.o auth-shadow.o auth-sia.o \
|
||||
sftp-server.o sftp-common.o \
|
||||
uidswap.o platform-listen.o $(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 $(SKOBJS)
|
||||
|
||||
SFTP_CLIENT_OBJS=sftp-common.o sftp-client.o sftp-glob.o
|
||||
|
||||
SCP_OBJS= scp.o progressmeter.o $(SFTP_CLIENT_OBJS)
|
||||
|
||||
SSHADD_OBJS= ssh-add.o $(SKOBJS)
|
||||
|
||||
SSHAGENT_OBJS= ssh-agent.o ssh-pkcs11-client.o $(SKOBJS)
|
||||
|
||||
SSHKEYGEN_OBJS= ssh-keygen.o sshsig.o $(SKOBJS)
|
||||
|
||||
SSHKEYSIGN_OBJS=ssh-keysign.o readconf.o uidswap.o $(SKOBJS)
|
||||
|
||||
P11HELPER_OBJS= ssh-pkcs11-helper.o ssh-pkcs11.o $(SKOBJS)
|
||||
|
||||
SKHELPER_OBJS= ssh-sk-helper.o ssh-sk.o sk-usbhid.o
|
||||
|
||||
SSHKEYSCAN_OBJS=ssh-keyscan.o $(SKOBJS)
|
||||
|
||||
SFTPSERVER_OBJS=sftp-common.o sftp-server.o sftp-server-main.o
|
||||
|
||||
SFTP_OBJS= sftp.o sftp-usergroup.o progressmeter.o $(SFTP_CLIENT_OBJS)
|
||||
|
||||
MANPAGES = moduli.5.out scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out ssh-keysign.8.out ssh-pkcs11-helper.8.out ssh-sk-helper.8.out sshd_config.5.out ssh_config.5.out
|
||||
MANPAGES_IN = moduli.5 scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-keysign.8 ssh-pkcs11-helper.8 ssh-sk-helper.8 sshd_config.5 ssh_config.5
|
||||
MANTYPE = @MANTYPE@
|
||||
|
||||
CONFIGFILES=sshd_config.out ssh_config.out moduli.out
|
||||
CONFIGFILES_IN=sshd_config ssh_config moduli
|
||||
|
||||
PATHSUBS = \
|
||||
-e 's|/etc/ssh/ssh_config|$(sysconfdir)/ssh_config|g' \
|
||||
-e 's|/etc/ssh/ssh_known_hosts|$(sysconfdir)/ssh_known_hosts|g' \
|
||||
-e 's|/etc/ssh/sshd_config|$(sysconfdir)/sshd_config|g' \
|
||||
-e 's|/usr/libexec|$(libexecdir)|g' \
|
||||
-e 's|/etc/shosts.equiv|$(sysconfdir)/shosts.equiv|g' \
|
||||
-e 's|/etc/ssh/ssh_host_key|$(sysconfdir)/ssh_host_key|g' \
|
||||
-e 's|/etc/ssh/ssh_host_ecdsa_key|$(sysconfdir)/ssh_host_ecdsa_key|g' \
|
||||
-e 's|/etc/ssh/ssh_host_dsa_key|$(sysconfdir)/ssh_host_dsa_key|g' \
|
||||
-e 's|/etc/ssh/ssh_host_rsa_key|$(sysconfdir)/ssh_host_rsa_key|g' \
|
||||
-e 's|/etc/ssh/ssh_host_ed25519_key|$(sysconfdir)/ssh_host_ed25519_key|g' \
|
||||
-e 's|/var/run/sshd.pid|$(piddir)/sshd.pid|g' \
|
||||
-e 's|/etc/moduli|$(sysconfdir)/moduli|g' \
|
||||
-e 's|/etc/ssh/moduli|$(sysconfdir)/moduli|g' \
|
||||
-e 's|/etc/ssh/sshrc|$(sysconfdir)/sshrc|g' \
|
||||
-e 's|/usr/X11R6/bin/xauth|$(XAUTH_PATH)|g' \
|
||||
-e 's|/var/empty|$(PRIVSEP_PATH)|g' \
|
||||
-e 's|/usr/bin:/bin:/usr/sbin:/sbin|@user_path@|g'
|
||||
|
||||
FIXPATHSCMD = $(SED) $(PATHSUBS)
|
||||
FIXALGORITHMSCMD= $(SHELL) $(srcdir)/fixalgorithms $(SED) \
|
||||
@UNSUPPORTED_ALGORITHMS@
|
||||
|
||||
all: $(CONFIGFILES) $(MANPAGES) $(TARGETS)
|
||||
|
||||
$(LIBSSH_OBJS): Makefile.in config.h
|
||||
$(SSHOBJS): Makefile.in config.h
|
||||
$(SSHDOBJS): Makefile.in config.h
|
||||
|
||||
.c.o:
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@
|
||||
|
||||
LIBCOMPAT=openbsd-compat/libopenbsd-compat.a
|
||||
$(LIBCOMPAT): always
|
||||
(cd openbsd-compat && $(MAKE))
|
||||
always:
|
||||
|
||||
libssh.a: $(LIBSSH_OBJS)
|
||||
$(AR) rv $@ $(LIBSSH_OBJS)
|
||||
$(RANLIB) $@
|
||||
|
||||
ssh$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHOBJS)
|
||||
$(LD) -o $@ $(SSHOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) $(GSSLIBS) $(CHANNELLIBS)
|
||||
|
||||
sshd$(EXEEXT): libssh.a $(LIBCOMPAT) $(SSHDOBJS)
|
||||
$(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(CHANNELLIBS)
|
||||
|
||||
sshd-session$(EXEEXT): libssh.a $(LIBCOMPAT) $(SSHD_SESSION_OBJS)
|
||||
$(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)
|
||||
|
||||
ssh-add$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHADD_OBJS)
|
||||
$(LD) -o $@ $(SSHADD_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) $(CHANNELLIBS)
|
||||
|
||||
ssh-agent$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHAGENT_OBJS)
|
||||
$(LD) -o $@ $(SSHAGENT_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) $(CHANNELLIBS)
|
||||
|
||||
ssh-keygen$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHKEYGEN_OBJS)
|
||||
$(LD) -o $@ $(SSHKEYGEN_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) $(CHANNELLIBS)
|
||||
|
||||
ssh-keysign$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHKEYSIGN_OBJS)
|
||||
$(LD) -o $@ $(SSHKEYSIGN_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) $(CHANNELLIBS)
|
||||
|
||||
ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT) libssh.a $(P11HELPER_OBJS)
|
||||
$(LD) -o $@ $(P11HELPER_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) $(CHANNELLIBS)
|
||||
|
||||
ssh-sk-helper$(EXEEXT): $(LIBCOMPAT) libssh.a $(SKHELPER_OBJS)
|
||||
$(LD) -o $@ $(SKHELPER_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) $(LIBFIDO2) $(CHANNELLIBS)
|
||||
|
||||
ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHKEYSCAN_OBJS)
|
||||
$(LD) -o $@ $(SSHKEYSCAN_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) $(CHANNELLIBS)
|
||||
|
||||
sftp-server$(EXEEXT): $(LIBCOMPAT) libssh.a $(SFTPSERVER_OBJS)
|
||||
$(LD) -o $@ $(SFTPSERVER_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS)
|
||||
|
||||
sftp$(EXEEXT): $(LIBCOMPAT) libssh.a $(SFTP_OBJS)
|
||||
$(LD) -o $@ $(SFTP_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) $(LIBEDIT)
|
||||
|
||||
# test driver for the loginrec code - not built by default
|
||||
logintest: logintest.o $(LIBCOMPAT) libssh.a loginrec.o
|
||||
$(LD) -o $@ logintest.o $(LDFLAGS) loginrec.o -lopenbsd-compat -lssh $(LIBS)
|
||||
|
||||
# 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/'`; \
|
||||
else \
|
||||
manpage=$(srcdir)/`echo $@ | sed 's/\.out$$//'`; \
|
||||
fi; \
|
||||
if test "$(MANTYPE)" = "man"; then \
|
||||
$(FIXPATHSCMD) $${manpage} | $(FIXALGORITHMSCMD) | \
|
||||
$(AWK) -f $(srcdir)/mdoc2man.awk > $@; \
|
||||
else \
|
||||
$(FIXPATHSCMD) $${manpage} | $(FIXALGORITHMSCMD) > $@; \
|
||||
fi
|
||||
|
||||
$(CONFIGFILES): $(CONFIGFILES_IN) Makefile
|
||||
conffile=`echo $@ | sed 's/.out$$//'`; \
|
||||
$(FIXPATHSCMD) $(srcdir)/$${conffile} > $@
|
||||
|
||||
# fake rule to stop make trying to compile moduli.o into a binary "moduli.o"
|
||||
moduli:
|
||||
echo
|
||||
|
||||
clean: regressclean
|
||||
rm -f *.o *.lo *.a $(TARGETS) logintest config.cache config.log
|
||||
rm -f *.out core survey
|
||||
rm -f regress/check-perm$(EXEEXT)
|
||||
rm -f regress/mkdtemp$(EXEEXT)
|
||||
rm -f regress/unittests/test_helper/*.a
|
||||
rm -f regress/unittests/test_helper/*.o
|
||||
rm -f regress/unittests/authopt/*.o
|
||||
rm -f regress/unittests/authopt/test_authopt$(EXEEXT)
|
||||
rm -f regress/unittests/bitmap/*.o
|
||||
rm -f regress/unittests/bitmap/test_bitmap$(EXEEXT)
|
||||
rm -f regress/unittests/conversion/*.o
|
||||
rm -f regress/unittests/conversion/test_conversion$(EXEEXT)
|
||||
rm -f regress/unittests/hostkeys/*.o
|
||||
rm -f regress/unittests/hostkeys/test_hostkeys$(EXEEXT)
|
||||
rm -f regress/unittests/kex/*.o
|
||||
rm -f regress/unittests/kex/test_kex$(EXEEXT)
|
||||
rm -f regress/unittests/match/*.o
|
||||
rm -f regress/unittests/match/test_match$(EXEEXT)
|
||||
rm -f regress/unittests/misc/*.o
|
||||
rm -f regress/unittests/misc/test_misc$(EXEEXT)
|
||||
rm -f regress/unittests/sshbuf/*.o
|
||||
rm -f regress/unittests/sshbuf/test_sshbuf$(EXEEXT)
|
||||
rm -f regress/unittests/sshkey/*.o
|
||||
rm -f regress/unittests/sshkey/test_sshkey$(EXEEXT)
|
||||
rm -f regress/unittests/sshsig/*.o
|
||||
rm -f regress/unittests/sshsig/test_sshsig$(EXEEXT)
|
||||
rm -f regress/unittests/utf8/*.o
|
||||
rm -f regress/unittests/utf8/test_utf8$(EXEEXT)
|
||||
rm -f regress/misc/sk-dummy/*.o
|
||||
rm -f regress/misc/sk-dummy/*.lo
|
||||
rm -f regress/misc/ssh-verify-attestation/ssh-verify-attestation$(EXEEXT)
|
||||
rm -f regress/misc/ssh-verify-attestation/*.o
|
||||
(cd openbsd-compat && $(MAKE) clean)
|
||||
|
||||
distclean: regressclean
|
||||
rm -f *.o *.a $(TARGETS) logintest config.cache config.log
|
||||
rm -f *.out core opensshd.init openssh.xml
|
||||
rm -f Makefile buildpkg.sh config.h config.status
|
||||
rm -f survey.sh openbsd-compat/regress/Makefile *~
|
||||
rm -rf autom4te.cache
|
||||
rm -f regress/check-perm
|
||||
rm -f regress/mkdtemp
|
||||
rm -f regress/unittests/test_helper/*.a
|
||||
rm -f regress/unittests/test_helper/*.o
|
||||
rm -f regress/unittests/authopt/*.o
|
||||
rm -f regress/unittests/authopt/test_authopt
|
||||
rm -f regress/unittests/bitmap/*.o
|
||||
rm -f regress/unittests/bitmap/test_bitmap
|
||||
rm -f regress/unittests/conversion/*.o
|
||||
rm -f regress/unittests/conversion/test_conversion
|
||||
rm -f regress/unittests/hostkeys/*.o
|
||||
rm -f regress/unittests/hostkeys/test_hostkeys
|
||||
rm -f regress/unittests/kex/*.o
|
||||
rm -f regress/unittests/kex/test_kex
|
||||
rm -f regress/unittests/match/*.o
|
||||
rm -f regress/unittests/match/test_match
|
||||
rm -f regress/unittests/misc/*.o
|
||||
rm -f regress/unittests/misc/test_misc
|
||||
rm -f regress/unittests/sshbuf/*.o
|
||||
rm -f regress/unittests/sshbuf/test_sshbuf
|
||||
rm -f regress/unittests/sshkey/*.o
|
||||
rm -f regress/unittests/sshkey/test_sshkey
|
||||
rm -f regress/unittests/sshsig/*.o
|
||||
rm -f regress/unittests/sshsig/test_sshsig
|
||||
rm -f regress/unittests/utf8/*.o
|
||||
rm -f regress/unittests/utf8/test_utf8
|
||||
rm -f regress/misc/sk-dummy/*.o
|
||||
rm -f regress/misc/sk-dummy/*.lo
|
||||
rm -f regress/misc/sk-dummy/sk-dummy.so
|
||||
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 ; \
|
||||
fi
|
||||
|
||||
veryclean: distclean
|
||||
rm -f configure config.h.in *.0
|
||||
|
||||
cleandir: veryclean
|
||||
|
||||
mrproper: veryclean
|
||||
|
||||
realclean: veryclean
|
||||
|
||||
catman-do:
|
||||
@for f in $(MANPAGES_IN) ; do \
|
||||
base=`echo $$f | sed 's/\..*$$//'` ; \
|
||||
echo "$$f -> $$base.0" ; \
|
||||
$(MANFMT) $$f | cat -v | sed -e 's/.\^H//g' \
|
||||
>$$base.0 ; \
|
||||
done
|
||||
|
||||
depend: depend-rebuild
|
||||
rm -f .depend.bak
|
||||
|
||||
depend-rebuild:
|
||||
mv .depend .depend.old
|
||||
rm -f config.h .depend
|
||||
touch config.h .depend
|
||||
makedepend -w1000 -Y. -f .depend *.c 2>/dev/null
|
||||
(echo '# Automatically generated by makedepend.'; \
|
||||
echo '# Run "make depend" to rebuild.'; sort .depend ) >.depend.tmp
|
||||
mv .depend.tmp .depend
|
||||
rm -f .depend.bak
|
||||
mv .depend.old .depend.bak
|
||||
rm -f config.h
|
||||
|
||||
depend-check: depend-rebuild
|
||||
cmp .depend .depend.bak || (echo .depend stale && exit 1)
|
||||
|
||||
distprep: catman-do depend-check
|
||||
$(AUTORECONF)
|
||||
-rm -rf autom4te.cache .depend.bak
|
||||
|
||||
install: $(CONFIGFILES) $(MANPAGES) $(TARGETS) install-files install-sysconf host-key check-config
|
||||
install-nokeys: $(CONFIGFILES) $(MANPAGES) $(TARGETS) install-files install-sysconf
|
||||
install-nosysconf: $(CONFIGFILES) $(MANPAGES) $(TARGETS) install-files
|
||||
|
||||
check-config:
|
||||
-$(DESTDIR)$(sbindir)/sshd -t -f $(DESTDIR)$(sysconfdir)/sshd_config
|
||||
|
||||
install-files:
|
||||
$(MKDIR_P) $(DESTDIR)$(bindir)
|
||||
$(MKDIR_P) $(DESTDIR)$(sbindir)
|
||||
$(MKDIR_P) $(DESTDIR)$(mandir)/$(mansubdir)1
|
||||
$(MKDIR_P) $(DESTDIR)$(mandir)/$(mansubdir)5
|
||||
$(MKDIR_P) $(DESTDIR)$(mandir)/$(mansubdir)8
|
||||
$(MKDIR_P) $(DESTDIR)$(libexecdir)
|
||||
$(MKDIR_P) -m 0755 $(DESTDIR)$(PRIVSEP_PATH)
|
||||
$(INSTALL) -m 0755 $(STRIP_OPT) ssh$(EXEEXT) $(DESTDIR)$(bindir)/ssh$(EXEEXT)
|
||||
$(INSTALL) -m 0755 $(STRIP_OPT) scp$(EXEEXT) $(DESTDIR)$(bindir)/scp$(EXEEXT)
|
||||
$(INSTALL) -m 0755 $(STRIP_OPT) ssh-add$(EXEEXT) $(DESTDIR)$(bindir)/ssh-add$(EXEEXT)
|
||||
$(INSTALL) -m 0755 $(STRIP_OPT) ssh-agent$(EXEEXT) $(DESTDIR)$(bindir)/ssh-agent$(EXEEXT)
|
||||
$(INSTALL) -m 0755 $(STRIP_OPT) ssh-keygen$(EXEEXT) $(DESTDIR)$(bindir)/ssh-keygen$(EXEEXT)
|
||||
$(INSTALL) -m 0755 $(STRIP_OPT) ssh-keyscan$(EXEEXT) $(DESTDIR)$(bindir)/ssh-keyscan$(EXEEXT)
|
||||
$(INSTALL) -m 0755 $(STRIP_OPT) sshd$(EXEEXT) $(DESTDIR)$(sbindir)/sshd$(EXEEXT)
|
||||
$(INSTALL) -m 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)
|
||||
$(INSTALL) -m 0755 $(STRIP_OPT) sftp$(EXEEXT) $(DESTDIR)$(bindir)/sftp$(EXEEXT)
|
||||
$(INSTALL) -m 0755 $(STRIP_OPT) sftp-server$(EXEEXT) $(DESTDIR)$(SFTP_SERVER)$(EXEEXT)
|
||||
$(INSTALL) -m 644 ssh.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1
|
||||
$(INSTALL) -m 644 scp.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/scp.1
|
||||
$(INSTALL) -m 644 ssh-add.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-add.1
|
||||
$(INSTALL) -m 644 ssh-agent.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-agent.1
|
||||
$(INSTALL) -m 644 ssh-keygen.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-keygen.1
|
||||
$(INSTALL) -m 644 ssh-keyscan.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-keyscan.1
|
||||
$(INSTALL) -m 644 moduli.5.out $(DESTDIR)$(mandir)/$(mansubdir)5/moduli.5
|
||||
$(INSTALL) -m 644 sshd_config.5.out $(DESTDIR)$(mandir)/$(mansubdir)5/sshd_config.5
|
||||
$(INSTALL) -m 644 ssh_config.5.out $(DESTDIR)$(mandir)/$(mansubdir)5/ssh_config.5
|
||||
$(INSTALL) -m 644 sshd.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/sshd.8
|
||||
$(INSTALL) -m 644 sftp.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/sftp.1
|
||||
$(INSTALL) -m 644 sftp-server.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/sftp-server.8
|
||||
$(INSTALL) -m 644 ssh-keysign.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-keysign.8
|
||||
$(INSTALL) -m 644 ssh-pkcs11-helper.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-pkcs11-helper.8
|
||||
$(INSTALL) -m 644 ssh-sk-helper.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-sk-helper.8
|
||||
|
||||
install-sysconf:
|
||||
$(MKDIR_P) $(DESTDIR)$(sysconfdir)
|
||||
@if [ ! -f $(DESTDIR)$(sysconfdir)/ssh_config ]; then \
|
||||
$(INSTALL) -m 644 ssh_config.out $(DESTDIR)$(sysconfdir)/ssh_config; \
|
||||
else \
|
||||
echo "$(DESTDIR)$(sysconfdir)/ssh_config already exists, install will not overwrite"; \
|
||||
fi
|
||||
@if [ ! -f $(DESTDIR)$(sysconfdir)/sshd_config ]; then \
|
||||
$(INSTALL) -m 644 sshd_config.out $(DESTDIR)$(sysconfdir)/sshd_config; \
|
||||
else \
|
||||
echo "$(DESTDIR)$(sysconfdir)/sshd_config already exists, install will not overwrite"; \
|
||||
fi
|
||||
@if [ ! -f $(DESTDIR)$(sysconfdir)/moduli ]; then \
|
||||
if [ -f $(DESTDIR)$(sysconfdir)/primes ]; then \
|
||||
echo "moving $(DESTDIR)$(sysconfdir)/primes to $(DESTDIR)$(sysconfdir)/moduli"; \
|
||||
mv "$(DESTDIR)$(sysconfdir)/primes" "$(DESTDIR)$(sysconfdir)/moduli"; \
|
||||
else \
|
||||
$(INSTALL) -m 644 moduli.out $(DESTDIR)$(sysconfdir)/moduli; \
|
||||
fi ; \
|
||||
else \
|
||||
echo "$(DESTDIR)$(sysconfdir)/moduli already exists, install will not overwrite"; \
|
||||
fi
|
||||
|
||||
host-key: ssh-keygen$(EXEEXT)
|
||||
@if [ -z "$(DESTDIR)" ] ; then \
|
||||
./ssh-keygen -A; \
|
||||
fi
|
||||
|
||||
host-key-force: ssh-keygen$(EXEEXT) ssh$(EXEEXT)
|
||||
./ssh-keygen -t dsa -f $(DESTDIR)$(sysconfdir)/ssh_host_dsa_key -N ""
|
||||
./ssh-keygen -t rsa -f $(DESTDIR)$(sysconfdir)/ssh_host_rsa_key -N ""
|
||||
./ssh-keygen -t ed25519 -f $(DESTDIR)$(sysconfdir)/ssh_host_ed25519_key -N ""
|
||||
if ./ssh -Q key | grep ecdsa >/dev/null ; then \
|
||||
./ssh-keygen -t ecdsa -f $(DESTDIR)$(sysconfdir)/ssh_host_ecdsa_key -N ""; \
|
||||
fi
|
||||
|
||||
uninstallall: uninstall
|
||||
-rm -f $(DESTDIR)$(sysconfdir)/ssh_config
|
||||
-rm -f $(DESTDIR)$(sysconfdir)/sshd_config
|
||||
-rmdir $(DESTDIR)$(sysconfdir)
|
||||
-rmdir $(DESTDIR)$(bindir)
|
||||
-rmdir $(DESTDIR)$(sbindir)
|
||||
-rmdir $(DESTDIR)$(mandir)/$(mansubdir)1
|
||||
-rmdir $(DESTDIR)$(mandir)/$(mansubdir)8
|
||||
-rmdir $(DESTDIR)$(mandir)
|
||||
-rmdir $(DESTDIR)$(libexecdir)
|
||||
|
||||
uninstall:
|
||||
-rm -f $(DESTDIR)$(bindir)/ssh$(EXEEXT)
|
||||
-rm -f $(DESTDIR)$(bindir)/scp$(EXEEXT)
|
||||
-rm -f $(DESTDIR)$(bindir)/ssh-add$(EXEEXT)
|
||||
-rm -f $(DESTDIR)$(bindir)/ssh-agent$(EXEEXT)
|
||||
-rm -f $(DESTDIR)$(bindir)/ssh-keygen$(EXEEXT)
|
||||
-rm -f $(DESTDIR)$(bindir)/ssh-keyscan$(EXEEXT)
|
||||
-rm -f $(DESTDIR)$(bindir)/sftp$(EXEEXT)
|
||||
-rm -f $(DESTDIR)$(sbindir)/sshd$(EXEEXT)
|
||||
-rm -r $(DESTDIR)$(SFTP_SERVER)$(EXEEXT)
|
||||
-rm -f $(DESTDIR)$(SSH_KEYSIGN)$(EXEEXT)
|
||||
-rm -f $(DESTDIR)$(SSH_PKCS11_HELPER)$(EXEEXT)
|
||||
-rm -f $(DESTDIR)$(SSH_SK_HELPER)$(EXEEXT)
|
||||
-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1
|
||||
-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/scp.1
|
||||
-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-add.1
|
||||
-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-agent.1
|
||||
-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-keygen.1
|
||||
-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/sftp.1
|
||||
-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-keyscan.1
|
||||
-rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/sshd.8
|
||||
-rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/sftp-server.8
|
||||
-rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-keysign.8
|
||||
-rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-pkcs11-helper.8
|
||||
-rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-sk-helper.8
|
||||
|
||||
regress-prep:
|
||||
$(MKDIR_P) `pwd`/regress/unittests/test_helper
|
||||
$(MKDIR_P) `pwd`/regress/unittests/authopt
|
||||
$(MKDIR_P) `pwd`/regress/unittests/bitmap
|
||||
$(MKDIR_P) `pwd`/regress/unittests/conversion
|
||||
$(MKDIR_P) `pwd`/regress/unittests/hostkeys
|
||||
$(MKDIR_P) `pwd`/regress/unittests/kex
|
||||
$(MKDIR_P) `pwd`/regress/unittests/match
|
||||
$(MKDIR_P) `pwd`/regress/unittests/misc
|
||||
$(MKDIR_P) `pwd`/regress/unittests/sshbuf
|
||||
$(MKDIR_P) `pwd`/regress/unittests/sshkey
|
||||
$(MKDIR_P) `pwd`/regress/unittests/sshsig
|
||||
$(MKDIR_P) `pwd`/regress/unittests/utf8
|
||||
$(MKDIR_P) `pwd`/regress/misc/sk-dummy
|
||||
$(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)
|
||||
|
||||
regress/modpipe$(EXEEXT): $(srcdir)/regress/modpipe.c $(REGRESSLIBS)
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $(srcdir)/regress/modpipe.c \
|
||||
$(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(TESTLIBS)
|
||||
|
||||
regress/timestamp$(EXEEXT): $(srcdir)/regress/timestamp.c $(REGRESSLIBS)
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $(srcdir)/regress/timestamp.c \
|
||||
$(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(TESTLIBS)
|
||||
|
||||
regress/setuid-allowed$(EXEEXT): $(srcdir)/regress/setuid-allowed.c $(REGRESSLIBS)
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $(srcdir)/regress/setuid-allowed.c \
|
||||
$(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(TESTLIBS)
|
||||
|
||||
regress/netcat$(EXEEXT): $(srcdir)/regress/netcat.c $(REGRESSLIBS)
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $(srcdir)/regress/netcat.c \
|
||||
$(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(TESTLIBS)
|
||||
|
||||
regress/check-perm$(EXEEXT): $(srcdir)/regress/check-perm.c $(REGRESSLIBS)
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $(srcdir)/regress/check-perm.c \
|
||||
$(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(TESTLIBS)
|
||||
|
||||
regress/mkdtemp$(EXEEXT): $(srcdir)/regress/mkdtemp.c $(REGRESSLIBS)
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $(srcdir)/regress/mkdtemp.c \
|
||||
$(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(TESTLIBS)
|
||||
|
||||
UNITTESTS_TEST_HELPER_OBJS=\
|
||||
regress/unittests/test_helper/test_helper.o \
|
||||
regress/unittests/test_helper/fuzz.o
|
||||
|
||||
regress/unittests/test_helper/libtest_helper.a: ${UNITTESTS_TEST_HELPER_OBJS}
|
||||
$(AR) rv $@ $(UNITTESTS_TEST_HELPER_OBJS)
|
||||
$(RANLIB) $@
|
||||
|
||||
UNITTESTS_TEST_SSHBUF_OBJS=\
|
||||
regress/unittests/sshbuf/tests.o \
|
||||
regress/unittests/sshbuf/test_sshbuf.o \
|
||||
regress/unittests/sshbuf/test_sshbuf_getput_basic.o \
|
||||
regress/unittests/sshbuf/test_sshbuf_getput_crypto.o \
|
||||
regress/unittests/sshbuf/test_sshbuf_misc.o \
|
||||
regress/unittests/sshbuf/test_sshbuf_fuzz.o \
|
||||
regress/unittests/sshbuf/test_sshbuf_getput_fuzz.o \
|
||||
regress/unittests/sshbuf/test_sshbuf_fixed.o
|
||||
|
||||
regress/unittests/sshbuf/test_sshbuf$(EXEEXT): ${UNITTESTS_TEST_SSHBUF_OBJS} \
|
||||
regress/unittests/test_helper/libtest_helper.a libssh.a
|
||||
$(LD) -o $@ $(LDFLAGS) $(UNITTESTS_TEST_SSHBUF_OBJS) \
|
||||
regress/unittests/test_helper/libtest_helper.a \
|
||||
-lssh -lopenbsd-compat -lssh -lopenbsd-compat $(TESTLIBS)
|
||||
|
||||
UNITTESTS_TEST_SSHKEY_OBJS=\
|
||||
regress/unittests/sshkey/test_fuzz.o \
|
||||
regress/unittests/sshkey/tests.o \
|
||||
regress/unittests/sshkey/common.o \
|
||||
regress/unittests/sshkey/test_file.o \
|
||||
regress/unittests/sshkey/test_sshkey.o \
|
||||
$(SKOBJS)
|
||||
|
||||
regress/unittests/sshkey/test_sshkey$(EXEEXT): ${UNITTESTS_TEST_SSHKEY_OBJS} \
|
||||
regress/unittests/test_helper/libtest_helper.a libssh.a
|
||||
$(LD) -o $@ $(LDFLAGS) $(UNITTESTS_TEST_SSHKEY_OBJS) \
|
||||
regress/unittests/test_helper/libtest_helper.a \
|
||||
-lssh -lopenbsd-compat -lssh -lopenbsd-compat $(TESTLIBS)
|
||||
|
||||
UNITTESTS_TEST_SSHSIG_OBJS=\
|
||||
sshsig.o \
|
||||
regress/unittests/sshsig/tests.o \
|
||||
$(SKOBJS)
|
||||
|
||||
regress/unittests/sshsig/test_sshsig$(EXEEXT): ${UNITTESTS_TEST_SSHSIG_OBJS} \
|
||||
regress/unittests/test_helper/libtest_helper.a libssh.a
|
||||
$(LD) -o $@ $(LDFLAGS) $(UNITTESTS_TEST_SSHSIG_OBJS) \
|
||||
regress/unittests/test_helper/libtest_helper.a \
|
||||
-lssh -lopenbsd-compat -lssh -lopenbsd-compat $(TESTLIBS)
|
||||
|
||||
UNITTESTS_TEST_BITMAP_OBJS=\
|
||||
regress/unittests/bitmap/tests.o
|
||||
|
||||
regress/unittests/bitmap/test_bitmap$(EXEEXT): ${UNITTESTS_TEST_BITMAP_OBJS} \
|
||||
regress/unittests/test_helper/libtest_helper.a libssh.a
|
||||
$(LD) -o $@ $(LDFLAGS) $(UNITTESTS_TEST_BITMAP_OBJS) \
|
||||
regress/unittests/test_helper/libtest_helper.a \
|
||||
-lssh -lopenbsd-compat -lssh -lopenbsd-compat $(TESTLIBS)
|
||||
|
||||
UNITTESTS_TEST_AUTHOPT_OBJS=\
|
||||
regress/unittests/authopt/tests.o \
|
||||
auth-options.o \
|
||||
$(SKOBJS)
|
||||
|
||||
regress/unittests/authopt/test_authopt$(EXEEXT): \
|
||||
${UNITTESTS_TEST_AUTHOPT_OBJS} \
|
||||
regress/unittests/test_helper/libtest_helper.a libssh.a
|
||||
$(LD) -o $@ $(LDFLAGS) $(UNITTESTS_TEST_AUTHOPT_OBJS) \
|
||||
regress/unittests/test_helper/libtest_helper.a \
|
||||
-lssh -lopenbsd-compat -lssh -lopenbsd-compat $(TESTLIBS)
|
||||
|
||||
UNITTESTS_TEST_CONVERSION_OBJS=\
|
||||
regress/unittests/conversion/tests.o
|
||||
|
||||
regress/unittests/conversion/test_conversion$(EXEEXT): \
|
||||
${UNITTESTS_TEST_CONVERSION_OBJS} \
|
||||
regress/unittests/test_helper/libtest_helper.a libssh.a
|
||||
$(LD) -o $@ $(LDFLAGS) $(UNITTESTS_TEST_CONVERSION_OBJS) \
|
||||
regress/unittests/test_helper/libtest_helper.a \
|
||||
-lssh -lopenbsd-compat -lssh -lopenbsd-compat $(TESTLIBS)
|
||||
|
||||
UNITTESTS_TEST_KEX_OBJS=\
|
||||
regress/unittests/kex/tests.o \
|
||||
regress/unittests/kex/test_kex.o \
|
||||
regress/unittests/kex/test_proposal.o \
|
||||
$(SKOBJS)
|
||||
|
||||
regress/unittests/kex/test_kex$(EXEEXT): ${UNITTESTS_TEST_KEX_OBJS} \
|
||||
regress/unittests/test_helper/libtest_helper.a libssh.a
|
||||
$(LD) -o $@ $(LDFLAGS) $(UNITTESTS_TEST_KEX_OBJS) \
|
||||
regress/unittests/test_helper/libtest_helper.a \
|
||||
-lssh -lopenbsd-compat -lssh -lopenbsd-compat $(TESTLIBS)
|
||||
|
||||
UNITTESTS_TEST_HOSTKEYS_OBJS=\
|
||||
regress/unittests/hostkeys/tests.o \
|
||||
regress/unittests/hostkeys/test_iterate.o \
|
||||
$(SKOBJS)
|
||||
|
||||
regress/unittests/hostkeys/test_hostkeys$(EXEEXT): \
|
||||
${UNITTESTS_TEST_HOSTKEYS_OBJS} \
|
||||
regress/unittests/test_helper/libtest_helper.a libssh.a
|
||||
$(LD) -o $@ $(LDFLAGS) $(UNITTESTS_TEST_HOSTKEYS_OBJS) \
|
||||
regress/unittests/test_helper/libtest_helper.a \
|
||||
-lssh -lopenbsd-compat -lssh -lopenbsd-compat $(TESTLIBS)
|
||||
|
||||
UNITTESTS_TEST_MATCH_OBJS=\
|
||||
regress/unittests/match/tests.o
|
||||
|
||||
regress/unittests/match/test_match$(EXEEXT): \
|
||||
${UNITTESTS_TEST_MATCH_OBJS} \
|
||||
regress/unittests/test_helper/libtest_helper.a libssh.a
|
||||
$(LD) -o $@ $(LDFLAGS) $(UNITTESTS_TEST_MATCH_OBJS) \
|
||||
regress/unittests/test_helper/libtest_helper.a \
|
||||
-lssh -lopenbsd-compat -lssh -lopenbsd-compat $(TESTLIBS)
|
||||
|
||||
UNITTESTS_TEST_MISC_OBJS=\
|
||||
regress/unittests/misc/tests.o \
|
||||
regress/unittests/misc/test_parse.o \
|
||||
regress/unittests/misc/test_expand.o \
|
||||
regress/unittests/misc/test_convtime.o \
|
||||
regress/unittests/misc/test_argv.o \
|
||||
regress/unittests/misc/test_strdelim.o \
|
||||
regress/unittests/misc/test_hpdelim.o \
|
||||
regress/unittests/misc/test_ptimeout.o
|
||||
|
||||
regress/unittests/misc/test_misc$(EXEEXT): \
|
||||
${UNITTESTS_TEST_MISC_OBJS} \
|
||||
regress/unittests/test_helper/libtest_helper.a libssh.a
|
||||
$(LD) -o $@ $(LDFLAGS) $(UNITTESTS_TEST_MISC_OBJS) \
|
||||
regress/unittests/test_helper/libtest_helper.a \
|
||||
-lssh -lopenbsd-compat -lssh -lopenbsd-compat $(TESTLIBS)
|
||||
|
||||
UNITTESTS_TEST_UTF8_OBJS=\
|
||||
regress/unittests/utf8/tests.o
|
||||
|
||||
regress/unittests/utf8/test_utf8$(EXEEXT): \
|
||||
${UNITTESTS_TEST_UTF8_OBJS} \
|
||||
regress/unittests/test_helper/libtest_helper.a libssh.a
|
||||
$(LD) -o $@ $(LDFLAGS) $(UNITTESTS_TEST_UTF8_OBJS) \
|
||||
regress/unittests/test_helper/libtest_helper.a \
|
||||
-lssh -lopenbsd-compat -lssh -lopenbsd-compat $(TESTLIBS)
|
||||
|
||||
# These all need to be compiled -fPIC, so they are treated differently.
|
||||
SK_DUMMY_OBJS=\
|
||||
regress/misc/sk-dummy/sk-dummy.lo \
|
||||
regress/misc/sk-dummy/fatal.lo \
|
||||
ed25519.lo hash.lo
|
||||
|
||||
SK_DUMMY_LIBRARY=@SK_DUMMY_LIBRARY@
|
||||
|
||||
.c.lo: Makefile.in config.h
|
||||
$(CC) $(CFLAGS_NOPIE) $(PICFLAG) $(CPPFLAGS) -c $< -o $@
|
||||
|
||||
regress/misc/sk-dummy/sk-dummy.so: $(SK_DUMMY_OBJS)
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) $(PICFLAG) -shared -o $@ $(SK_DUMMY_OBJS) \
|
||||
-L. -Lopenbsd-compat -lopenbsd-compat $(LDFLAGS_NOPIE) $(TESTLIBS)
|
||||
|
||||
SSH_VERIFY_ATTESTATION_OBJS=\
|
||||
regress/misc/ssh-verify-attestation/ssh-verify-attestation.o \
|
||||
$(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) \
|
||||
regress/setuid-allowed$(EXEEXT) \
|
||||
regress/netcat$(EXEEXT) \
|
||||
regress/check-perm$(EXEEXT) \
|
||||
regress/mkdtemp$(EXEEXT) \
|
||||
$(SK_DUMMY_LIBRARY)
|
||||
|
||||
regress-unit-binaries: regress-prep $(REGRESSLIBS) \
|
||||
regress/unittests/authopt/test_authopt$(EXEEXT) \
|
||||
regress/unittests/bitmap/test_bitmap$(EXEEXT) \
|
||||
regress/unittests/conversion/test_conversion$(EXEEXT) \
|
||||
regress/unittests/hostkeys/test_hostkeys$(EXEEXT) \
|
||||
regress/unittests/kex/test_kex$(EXEEXT) \
|
||||
regress/unittests/match/test_match$(EXEEXT) \
|
||||
regress/unittests/misc/test_misc$(EXEEXT) \
|
||||
regress/unittests/sshbuf/test_sshbuf$(EXEEXT) \
|
||||
regress/unittests/sshkey/test_sshkey$(EXEEXT) \
|
||||
regress/unittests/sshsig/test_sshsig$(EXEEXT) \
|
||||
regress/unittests/utf8/test_utf8$(EXEEXT)
|
||||
|
||||
tests: file-tests t-exec interop-tests extra-tests unit
|
||||
echo all tests passed
|
||||
|
||||
unit: regress-unit-binaries
|
||||
cd $(srcdir)/regress || exit $$?; \
|
||||
$(MAKE) \
|
||||
.CURDIR="$(abs_top_srcdir)/regress" \
|
||||
.OBJDIR="$(BUILDDIR)/regress" \
|
||||
OBJ="$(BUILDDIR)/regress" \
|
||||
$@ && echo $@ tests passed
|
||||
|
||||
TEST_SSH_SSHD="$(BUILDDIR)/sshd"
|
||||
|
||||
interop-tests t-exec file-tests extra-tests: regress-prep regress-binaries $(TARGETS)
|
||||
cd $(srcdir)/regress || exit $$?; \
|
||||
EGREP='@EGREP@' \
|
||||
OPENSSL_BIN='@OPENSSL_BIN@' \
|
||||
$(MAKE) \
|
||||
.CURDIR="$(abs_top_srcdir)/regress" \
|
||||
.OBJDIR="$(BUILDDIR)/regress" \
|
||||
BUILDDIR="$(BUILDDIR)" \
|
||||
OBJ="$(BUILDDIR)/regress" \
|
||||
PATH="$(BUILDDIR):$${PATH}" \
|
||||
TEST_ENV=MALLOC_OPTIONS="@TEST_MALLOC_OPTIONS@" \
|
||||
TEST_MALLOC_OPTIONS="@TEST_MALLOC_OPTIONS@" \
|
||||
TEST_SSH_SCP="$(BUILDDIR)/scp" \
|
||||
TEST_SSH_SSH="$(BUILDDIR)/ssh" \
|
||||
TEST_SSH_SSHD="$(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" \
|
||||
TEST_SSH_SSHPKCS11HELPER="$(BUILDDIR)/ssh-pkcs11-helper" \
|
||||
TEST_SSH_SSHKEYSCAN="$(BUILDDIR)/ssh-keyscan" \
|
||||
TEST_SSH_SFTP="$(BUILDDIR)/sftp" \
|
||||
TEST_SSH_PKCS11_HELPER="$(BUILDDIR)/ssh-pkcs11-helper" \
|
||||
TEST_SSH_SK_HELPER="$(BUILDDIR)/ssh-sk-helper" \
|
||||
TEST_SSH_SFTPSERVER="$(BUILDDIR)/sftp-server" \
|
||||
TEST_SSH_MODULI_FILE="$(abs_top_srcdir)/moduli" \
|
||||
TEST_SSH_PLINK="@PLINK@" \
|
||||
TEST_SSH_PUTTYGEN="@PUTTYGEN@" \
|
||||
TEST_SSH_CONCH="@CONCH@" \
|
||||
TEST_SSH_DROPBEAR="@DROPBEAR@" \
|
||||
TEST_SSH_DROPBEARKEY="@DROPBEARKEY@" \
|
||||
TEST_SSH_DROPBEARCONVERT="@DROPBEARCONVERT@" \
|
||||
TEST_SSH_DBCLIENT="@DBCLIENT@" \
|
||||
TEST_SSH_IPV6="@TEST_SSH_IPV6@" \
|
||||
TEST_SSH_UTF8="@TEST_SSH_UTF8@" \
|
||||
TEST_SHELL="$(TEST_SHELL)" \
|
||||
EXEEXT="$(EXEEXT)" \
|
||||
$@ && echo all $@ passed
|
||||
|
||||
compat-tests: $(LIBCOMPAT)
|
||||
(cd openbsd-compat/regress && $(MAKE))
|
||||
|
||||
regressclean:
|
||||
if [ -f regress/Makefile ] && [ -r regress/Makefile ]; then \
|
||||
(cd regress && $(MAKE) clean) \
|
||||
fi
|
||||
|
||||
survey: survey.sh ssh
|
||||
@$(SHELL) ./survey.sh > survey
|
||||
@echo 'The survey results have been placed in the file "survey" in the'
|
||||
@echo 'current directory. Please review the file then send with'
|
||||
@echo '"make send-survey".'
|
||||
|
||||
send-survey: survey
|
||||
mail portable-survey@mindrot.org <survey
|
||||
|
||||
package: $(CONFIGFILES) $(MANPAGES) $(TARGETS)
|
||||
if [ "@MAKE_PACKAGE_SUPPORTED@" = yes ]; then \
|
||||
sh buildpkg.sh; \
|
||||
fi
|
||||
|
||||
# @DEPEND@
|
162
OVERVIEW
Normal file
162
OVERVIEW
Normal file
|
@ -0,0 +1,162 @@
|
|||
[Note: This file has not been updated for OpenSSH versions after
|
||||
OpenSSH-1.2 and should be considered OBSOLETE. It has been left in
|
||||
the distribution because some of its information may still be useful
|
||||
to developers.]
|
||||
|
||||
This document is intended for those who wish to read the ssh source
|
||||
code. This tries to give an overview of the structure of the code.
|
||||
|
||||
Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>
|
||||
Updated 17 Nov 1995.
|
||||
Updated 19 Oct 1999 for OpenSSH-1.2
|
||||
Updated 20 May 2001 note obsolete for > OpenSSH-1.2
|
||||
|
||||
The software consists of ssh (client), sshd (server), scp, sdist, and
|
||||
the auxiliary programs ssh-keygen, ssh-agent, ssh-add, and
|
||||
make-ssh-known-hosts. The main program for each of these is in a .c
|
||||
file with the same name.
|
||||
|
||||
There are some subsystems/abstractions that are used by a number of
|
||||
these programs.
|
||||
|
||||
Buffer manipulation routines
|
||||
|
||||
- These provide an arbitrary size buffer, where data can be appended.
|
||||
Data can be consumed from either end. The code is used heavily
|
||||
throughout ssh. The buffer manipulation functions are in
|
||||
sshbuf*.c (header sshbuf.h).
|
||||
|
||||
Compression Library
|
||||
|
||||
- Ssh uses the GNU GZIP compression library (ZLIB).
|
||||
|
||||
Encryption/Decryption
|
||||
|
||||
- Ssh contains several encryption algorithms. These are all
|
||||
accessed through the cipher.h interface. The interface code is
|
||||
in cipher.c, and the implementations are either in libc or
|
||||
LibreSSL.
|
||||
|
||||
Multiple Precision Integer Library
|
||||
|
||||
- Uses the LibreSSL BIGNUM sublibrary.
|
||||
|
||||
Random Numbers
|
||||
|
||||
- Uses arc4random() and such.
|
||||
|
||||
RSA key generation, encryption, decryption
|
||||
|
||||
- Ssh uses the RSA routines in libssl.
|
||||
|
||||
RSA key files
|
||||
|
||||
- RSA keys are stored in files with a special format. The code to
|
||||
read/write these files is in authfile.c. The files are normally
|
||||
encrypted with a passphrase. The functions to read passphrases
|
||||
are in readpass.c (the same code is used to read passwords).
|
||||
|
||||
Binary packet protocol
|
||||
|
||||
- The ssh binary packet protocol is implemented in packet.c. The
|
||||
code in packet.c does not concern itself with packet types or their
|
||||
execution; it contains code to build packets, to receive them and
|
||||
extract data from them, and the code to compress and/or encrypt
|
||||
packets.
|
||||
|
||||
- The code in packet.c calls the buffer manipulation routines
|
||||
(buffer.c, bufaux.c), compression routines (zlib), and the
|
||||
encryption routines.
|
||||
|
||||
X11, TCP/IP, and Agent forwarding
|
||||
|
||||
- Code for various types of channel forwarding is in channels.c.
|
||||
The file defines a generic framework for arbitrary communication
|
||||
channels inside the secure channel, and uses this framework to
|
||||
implement X11 forwarding, TCP/IP forwarding, and authentication
|
||||
agent forwarding.
|
||||
The new, Protocol 1.5, channel close implementation is in nchan.c
|
||||
|
||||
Authentication agent
|
||||
|
||||
- Code to communicate with the authentication agent is in authfd.c.
|
||||
|
||||
Authentication methods
|
||||
|
||||
- Code for various authentication methods resides in auth-*.c
|
||||
(auth-passwd.c, auth-rh-rsa.c, auth-rhosts.c, auth-rsa.c). This
|
||||
code is linked into the server. The routines also manipulate
|
||||
known hosts files using code in hostfile.c. Code in canohost.c
|
||||
is used to retrieve the canonical host name of the remote host.
|
||||
Code in match.c is used to match host names.
|
||||
|
||||
- In the client end, authentication code is in sshconnect.c. It
|
||||
reads Passwords/passphrases using code in readpass.c. It reads
|
||||
RSA key files with authfile.c. It communicates the
|
||||
authentication agent using authfd.c.
|
||||
|
||||
The ssh client
|
||||
|
||||
- The client main program is in ssh.c. It first parses arguments
|
||||
and reads configuration (readconf.c), then calls ssh_connect (in
|
||||
sshconnect.c) to open a connection to the server (possibly via a
|
||||
proxy), and performs authentication (ssh_login in sshconnect.c).
|
||||
It then makes any pty, forwarding, etc. requests. It may call
|
||||
code in ttymodes.c to encode current tty modes. Finally it
|
||||
calls client_loop in clientloop.c. This does the real work for
|
||||
the session.
|
||||
|
||||
Pseudo-tty manipulation and tty modes
|
||||
|
||||
- Code to allocate and use a pseudo tty is in pty.c. Code to
|
||||
encode and set terminal modes is in ttymodes.c.
|
||||
|
||||
Logging in (updating utmp, lastlog, etc.)
|
||||
|
||||
- The code to do things that are done when a user logs in are in
|
||||
login.c. This includes things such as updating the utmp, wtmp,
|
||||
and lastlog files. Some of the code is in sshd.c.
|
||||
|
||||
Writing to the system log and terminal
|
||||
|
||||
- The programs use the functions fatal(), log(), debug(), error()
|
||||
in many places to write messages to system log or user's
|
||||
terminal. The implementation that logs to system log is in
|
||||
log-server.c; it is used in the server program. The other
|
||||
programs use an implementation that sends output to stderr; it
|
||||
is in log-client.c. The definitions are in ssh.h.
|
||||
|
||||
The sshd server (daemon)
|
||||
|
||||
- The sshd daemon starts by processing arguments and reading the
|
||||
configuration file (servconf.c). It then reads the host key,
|
||||
starts listening for connections, and generates the server key.
|
||||
The server key will be regenerated every hour by an alarm.
|
||||
|
||||
- When the server receives a connection, it forks, disables the
|
||||
regeneration alarm, and starts communicating with the client.
|
||||
They first perform identification string exchange, then
|
||||
negotiate encryption, then perform authentication, preparatory
|
||||
operations, and finally the server enters the normal session
|
||||
mode by calling server_loop in serverloop.c. This does the real
|
||||
work, calling functions in other modules.
|
||||
|
||||
- The code for the server is in sshd.c. It contains a lot of
|
||||
stuff, including:
|
||||
- server main program
|
||||
- waiting for connections
|
||||
- processing new connection
|
||||
- authentication
|
||||
- preparatory operations
|
||||
- building up the execution environment for the user program
|
||||
- starting the user program.
|
||||
|
||||
Auxiliary files
|
||||
|
||||
- There are several other files in the distribution that contain
|
||||
various auxiliary routines:
|
||||
ssh.h the main header file for ssh (various definitions)
|
||||
uidswap.c uid-swapping
|
||||
xmalloc.c "safe" malloc routines
|
||||
|
||||
$OpenBSD: OVERVIEW,v 1.15 2018/10/23 05:56:35 djm Exp $
|
795
PROTOCOL
Normal file
795
PROTOCOL
Normal file
|
@ -0,0 +1,795 @@
|
|||
This documents OpenSSH's deviations and extensions to the published SSH
|
||||
protocol.
|
||||
|
||||
Note that OpenSSH's sftp and sftp-server implement revision 3 of the SSH
|
||||
filexfer protocol described in:
|
||||
|
||||
https://www.openssh.com/txt/draft-ietf-secsh-filexfer-02.txt
|
||||
|
||||
Newer versions of the draft will not be supported, though some features
|
||||
are individually implemented as extensions described below.
|
||||
|
||||
The protocol used by OpenSSH's ssh-agent is described in the file
|
||||
PROTOCOL.agent
|
||||
|
||||
1. Transport protocol changes
|
||||
|
||||
1.1. transport: Protocol 2 MAC algorithm "umac-64@openssh.com"
|
||||
|
||||
This is a new transport-layer MAC method using the UMAC algorithm
|
||||
(rfc4418). This method is identical to the "umac-64" method documented
|
||||
in:
|
||||
|
||||
https://www.openssh.com/txt/draft-miller-secsh-umac-01.txt
|
||||
|
||||
1.2. transport: Protocol 2 compression algorithm "zlib@openssh.com"
|
||||
|
||||
This transport-layer compression method uses the zlib compression
|
||||
algorithm (identical to the "zlib" method in rfc4253), but delays the
|
||||
start of compression until after authentication has completed. This
|
||||
avoids exposing compression code to attacks from unauthenticated users.
|
||||
|
||||
The method is documented in:
|
||||
|
||||
https://www.openssh.com/txt/draft-miller-secsh-compression-delayed-00.txt
|
||||
|
||||
1.3. transport: New public key algorithms "ssh-rsa-cert-v01@openssh.com",
|
||||
"ssh-dsa-cert-v01@openssh.com",
|
||||
"ecdsa-sha2-nistp256-cert-v01@openssh.com",
|
||||
"ecdsa-sha2-nistp384-cert-v01@openssh.com" and
|
||||
"ecdsa-sha2-nistp521-cert-v01@openssh.com"
|
||||
|
||||
OpenSSH introduces new public key algorithms to support certificate
|
||||
authentication for users and host keys. These methods are documented
|
||||
in the file PROTOCOL.certkeys
|
||||
|
||||
1.4. transport: Elliptic Curve cryptography
|
||||
|
||||
OpenSSH supports ECC key exchange and public key authentication as
|
||||
specified in RFC5656. Only the ecdsa-sha2-nistp256, ecdsa-sha2-nistp384
|
||||
and ecdsa-sha2-nistp521 curves over GF(p) are supported. Elliptic
|
||||
curve points encoded using point compression are NOT accepted or
|
||||
generated.
|
||||
|
||||
1.5 transport: Protocol 2 Encrypt-then-MAC MAC algorithms
|
||||
|
||||
OpenSSH supports MAC algorithms, whose names contain "-etm", that
|
||||
perform the calculations in a different order to that defined in RFC
|
||||
4253. These variants use the so-called "encrypt then MAC" ordering,
|
||||
calculating the MAC over the packet ciphertext rather than the
|
||||
plaintext. This ordering closes a security flaw in the SSH transport
|
||||
protocol, where decryption of unauthenticated ciphertext provided a
|
||||
"decryption oracle" that could, in conjunction with cipher flaws, reveal
|
||||
session plaintext.
|
||||
|
||||
Specifically, the "-etm" MAC algorithms modify the transport protocol
|
||||
to calculate the MAC over the packet ciphertext and to send the packet
|
||||
length unencrypted. This is necessary for the transport to obtain the
|
||||
length of the packet and location of the MAC tag so that it may be
|
||||
verified without decrypting unauthenticated data.
|
||||
|
||||
As such, the MAC covers:
|
||||
|
||||
mac = MAC(key, sequence_number || packet_length || encrypted_packet)
|
||||
|
||||
where "packet_length" is encoded as a uint32 and "encrypted_packet"
|
||||
contains:
|
||||
|
||||
byte padding_length
|
||||
byte[n1] payload; n1 = packet_length - padding_length - 1
|
||||
byte[n2] random padding; n2 = padding_length
|
||||
|
||||
1.6 transport: AES-GCM
|
||||
|
||||
OpenSSH supports the AES-GCM algorithm as specified in RFC 5647.
|
||||
Because of problems with the specification of the key exchange
|
||||
the behaviour of OpenSSH differs from the RFC as follows:
|
||||
|
||||
AES-GCM is only negotiated as the cipher algorithms
|
||||
"aes128-gcm@openssh.com" or "aes256-gcm@openssh.com" and never as
|
||||
an MAC algorithm. Additionally, if AES-GCM is selected as the cipher
|
||||
the exchanged MAC algorithms are ignored and there doesn't have to be
|
||||
a matching MAC.
|
||||
|
||||
1.7 transport: chacha20-poly1305@openssh.com authenticated encryption
|
||||
|
||||
OpenSSH supports authenticated encryption using ChaCha20 and Poly1305
|
||||
as described in PROTOCOL.chacha20poly1305.
|
||||
|
||||
1.8 transport: curve25519-sha256@libssh.org key exchange algorithm
|
||||
|
||||
OpenSSH supports the use of ECDH in Curve25519 for key exchange as
|
||||
described at:
|
||||
http://git.libssh.org/users/aris/libssh.git/plain/doc/curve25519-sha256@libssh.org.txt?h=curve25519
|
||||
|
||||
This is identical to curve25519-sha256 as later published in RFC8731.
|
||||
|
||||
1.9 transport: ping facility
|
||||
|
||||
OpenSSH implements a transport level ping message SSH2_MSG_PING
|
||||
and a corresponding SSH2_MSG_PONG reply.
|
||||
|
||||
#define SSH2_MSG_PING 192
|
||||
#define SSH2_MSG_PONG 193
|
||||
|
||||
The ping message is simply:
|
||||
|
||||
byte SSH_MSG_PING
|
||||
string data
|
||||
|
||||
The reply copies the data (which may be the empty string) from the
|
||||
ping:
|
||||
|
||||
byte SSH_MSG_PONG
|
||||
string data
|
||||
|
||||
Replies are sent in order. They are sent immediately except when rekeying
|
||||
is in progress, in which case they are queued until rekeying completes.
|
||||
|
||||
The server advertises support for these messages using the
|
||||
SSH2_MSG_EXT_INFO mechanism (RFC8308), with the following message:
|
||||
|
||||
string "ping@openssh.com"
|
||||
string "0" (version)
|
||||
|
||||
The ping/reply message is implemented at the transport layer rather
|
||||
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
|
||||
|
||||
This protocol extension allows the SSH2_MSG_EXT_INFO to be sent
|
||||
during user authentication. RFC8308 does allow a second
|
||||
SSH2_MSG_EXT_INFO notification, but it may only be sent at the end
|
||||
of user authentication and this is too late to signal per-user
|
||||
server signature algorithms.
|
||||
|
||||
Support for receiving the SSH2_MSG_EXT_INFO message during user
|
||||
authentication is signalled by the client including a
|
||||
"ext-info-in-auth@openssh.com" key via its initial SSH2_MSG_EXT_INFO
|
||||
set after the SSH2_MSG_NEWKEYS message.
|
||||
|
||||
A server that supports this extension MAY send a second
|
||||
SSH2_MSG_EXT_INFO message any time after the client's first
|
||||
SSH2_MSG_USERAUTH_REQUEST, regardless of whether it succeed or fails.
|
||||
The client SHOULD be prepared to update the server-sig-algs that
|
||||
it received during an earlier SSH2_MSG_EXT_INFO with the later one.
|
||||
|
||||
2. Connection protocol changes
|
||||
|
||||
2.1. connection: Channel write close extension "eow@openssh.com"
|
||||
|
||||
The SSH connection protocol (rfc4254) provides the SSH_MSG_CHANNEL_EOF
|
||||
message to allow an endpoint to signal its peer that it will send no
|
||||
more data over a channel. Unfortunately, there is no symmetric way for
|
||||
an endpoint to request that its peer should cease sending data to it
|
||||
while still keeping the channel open for the endpoint to send data to
|
||||
the peer.
|
||||
|
||||
This is desirable, since it saves the transmission of data that would
|
||||
otherwise need to be discarded and it allows an endpoint to signal local
|
||||
processes of the condition, e.g. by closing the corresponding file
|
||||
descriptor.
|
||||
|
||||
OpenSSH implements a channel extension message to perform this
|
||||
signalling: "eow@openssh.com" (End Of Write). This message is sent by
|
||||
an endpoint when the local output of a session channel is closed or
|
||||
experiences a write error. The message is formatted as follows:
|
||||
|
||||
byte SSH_MSG_CHANNEL_REQUEST
|
||||
uint32 recipient channel
|
||||
string "eow@openssh.com"
|
||||
boolean FALSE
|
||||
|
||||
On receiving this message, the peer SHOULD cease sending data of
|
||||
the channel and MAY signal the process from which the channel data
|
||||
originates (e.g. by closing its read file descriptor).
|
||||
|
||||
As with the symmetric SSH_MSG_CHANNEL_EOF message, the channel does
|
||||
remain open after a "eow@openssh.com" has been sent and more data may
|
||||
still be sent in the other direction. This message does not consume
|
||||
window space and may be sent even if no window space is available.
|
||||
|
||||
NB. due to certain broken SSH implementations aborting upon receipt
|
||||
of this message (in contravention of RFC4254 section 5.4), this
|
||||
message is only sent to OpenSSH peers (identified by banner).
|
||||
Other SSH implementations may be listed to receive this message
|
||||
upon request.
|
||||
|
||||
2.2. connection: disallow additional sessions extension
|
||||
"no-more-sessions@openssh.com"
|
||||
|
||||
Most SSH connections will only ever request a single session, but a
|
||||
attacker may abuse a running ssh client to surreptitiously open
|
||||
additional sessions under their control. OpenSSH provides a global
|
||||
request "no-more-sessions@openssh.com" to mitigate this attack.
|
||||
|
||||
When an OpenSSH client expects that it will never open another session
|
||||
(i.e. it has been started with connection multiplexing disabled), it
|
||||
will send the following global request:
|
||||
|
||||
byte SSH_MSG_GLOBAL_REQUEST
|
||||
string "no-more-sessions@openssh.com"
|
||||
char want-reply
|
||||
|
||||
On receipt of such a message, an OpenSSH server will refuse to open
|
||||
future channels of type "session" and instead immediately abort the
|
||||
connection.
|
||||
|
||||
Note that this is not a general defence against compromised clients
|
||||
(that is impossible), but it thwarts a simple attack.
|
||||
|
||||
NB. due to certain broken SSH implementations aborting upon receipt
|
||||
of this message, the no-more-sessions request is only sent to OpenSSH
|
||||
servers (identified by banner). Other SSH implementations may be
|
||||
listed to receive this message upon request.
|
||||
|
||||
2.3. connection: Tunnel forward extension "tun@openssh.com"
|
||||
|
||||
OpenSSH supports layer 2 and layer 3 tunnelling via the "tun@openssh.com"
|
||||
channel type. This channel type supports forwarding of network packets
|
||||
with datagram boundaries intact between endpoints equipped with
|
||||
interfaces like the BSD tun(4) device. Tunnel forwarding channels are
|
||||
requested by the client with the following packet:
|
||||
|
||||
byte SSH_MSG_CHANNEL_OPEN
|
||||
string "tun@openssh.com"
|
||||
uint32 sender channel
|
||||
uint32 initial window size
|
||||
uint32 maximum packet size
|
||||
uint32 tunnel mode
|
||||
uint32 remote unit number
|
||||
|
||||
The "tunnel mode" parameter specifies whether the tunnel should forward
|
||||
layer 2 frames or layer 3 packets. It may take one of the following values:
|
||||
|
||||
SSH_TUNMODE_POINTOPOINT 1 /* layer 3 packets */
|
||||
SSH_TUNMODE_ETHERNET 2 /* layer 2 frames */
|
||||
|
||||
The "tunnel unit number" specifies the remote interface number, or may
|
||||
be 0x7fffffff to allow the server to automatically choose an interface. A
|
||||
server that is not willing to open a client-specified unit should refuse
|
||||
the request with a SSH_MSG_CHANNEL_OPEN_FAILURE error. On successful
|
||||
open, the server should reply with SSH_MSG_CHANNEL_OPEN_SUCCESS.
|
||||
|
||||
Once established the client and server may exchange packet or frames
|
||||
over the tunnel channel by encapsulating them in SSH protocol strings
|
||||
and sending them as channel data. This ensures that packet boundaries
|
||||
are kept intact. Specifically, packets are transmitted using normal
|
||||
SSH_MSG_CHANNEL_DATA packets:
|
||||
|
||||
byte SSH_MSG_CHANNEL_DATA
|
||||
uint32 recipient channel
|
||||
string data
|
||||
|
||||
The contents of the "data" field for layer 3 packets is:
|
||||
|
||||
uint32 packet length
|
||||
uint32 address family
|
||||
byte[packet length - 4] packet data
|
||||
|
||||
The "address family" field identifies the type of packet in the message.
|
||||
It may be one of:
|
||||
|
||||
SSH_TUN_AF_INET 2 /* IPv4 */
|
||||
SSH_TUN_AF_INET6 24 /* IPv6 */
|
||||
|
||||
The "packet data" field consists of the IPv4/IPv6 datagram itself
|
||||
without any link layer header.
|
||||
|
||||
The contents of the "data" field for layer 2 packets is:
|
||||
|
||||
uint32 packet length
|
||||
byte[packet length] frame
|
||||
|
||||
The "frame" field contains an IEEE 802.3 Ethernet frame, including
|
||||
header.
|
||||
|
||||
2.4. connection: Unix domain socket forwarding
|
||||
|
||||
OpenSSH supports local and remote Unix domain socket forwarding
|
||||
using the "streamlocal" extension. Forwarding is initiated as per
|
||||
TCP sockets but with a single path instead of a host and port.
|
||||
|
||||
Similar to direct-tcpip, direct-streamlocal is sent by the client
|
||||
to request that the server make a connection to a Unix domain socket.
|
||||
|
||||
byte SSH_MSG_CHANNEL_OPEN
|
||||
string "direct-streamlocal@openssh.com"
|
||||
uint32 sender channel
|
||||
uint32 initial window size
|
||||
uint32 maximum packet size
|
||||
string socket path
|
||||
string reserved
|
||||
uint32 reserved
|
||||
|
||||
Similar to forwarded-tcpip, forwarded-streamlocal is sent by the
|
||||
server when the client has previously send the server a streamlocal-forward
|
||||
GLOBAL_REQUEST.
|
||||
|
||||
byte SSH_MSG_CHANNEL_OPEN
|
||||
string "forwarded-streamlocal@openssh.com"
|
||||
uint32 sender channel
|
||||
uint32 initial window size
|
||||
uint32 maximum packet size
|
||||
string socket path
|
||||
string reserved for future use
|
||||
|
||||
The reserved field is not currently defined and is ignored on the
|
||||
remote end. It is intended to be used in the future to pass
|
||||
information about the socket file, such as ownership and mode.
|
||||
The client currently sends the empty string for this field.
|
||||
|
||||
Similar to tcpip-forward, streamlocal-forward is sent by the client
|
||||
to request remote forwarding of a Unix domain socket.
|
||||
|
||||
byte SSH2_MSG_GLOBAL_REQUEST
|
||||
string "streamlocal-forward@openssh.com"
|
||||
boolean TRUE
|
||||
string socket path
|
||||
|
||||
Similar to cancel-tcpip-forward, cancel-streamlocal-forward is sent
|
||||
by the client cancel the forwarding of a Unix domain socket.
|
||||
|
||||
byte SSH2_MSG_GLOBAL_REQUEST
|
||||
string "cancel-streamlocal-forward@openssh.com"
|
||||
boolean FALSE
|
||||
string socket path
|
||||
|
||||
2.5. connection: hostkey update and rotation "hostkeys-00@openssh.com"
|
||||
and "hostkeys-prove-00@openssh.com"
|
||||
|
||||
OpenSSH supports a protocol extension allowing a server to inform
|
||||
a client of all its protocol v.2 host keys after user-authentication
|
||||
has completed.
|
||||
|
||||
byte SSH_MSG_GLOBAL_REQUEST
|
||||
string "hostkeys-00@openssh.com"
|
||||
char 0 /* want-reply */
|
||||
string[] hostkeys
|
||||
|
||||
Upon receiving this message, a client should check which of the
|
||||
supplied host keys are present in known_hosts.
|
||||
|
||||
Note that the server may send key types that the client does not
|
||||
support. The client should disregard such keys if they are received.
|
||||
|
||||
If the client identifies any keys that are not present for the host,
|
||||
it should send a "hostkeys-prove@openssh.com" message to request the
|
||||
server prove ownership of the private half of the key.
|
||||
|
||||
byte SSH_MSG_GLOBAL_REQUEST
|
||||
string "hostkeys-prove-00@openssh.com"
|
||||
char 1 /* want-reply */
|
||||
string[] hostkeys
|
||||
|
||||
When a server receives this message, it should generate a signature
|
||||
using each requested key over the following:
|
||||
|
||||
string "hostkeys-prove-00@openssh.com"
|
||||
string session identifier
|
||||
string hostkey
|
||||
|
||||
These signatures should be included in the reply, in the order matching
|
||||
the hostkeys in the request:
|
||||
|
||||
byte SSH_MSG_REQUEST_SUCCESS
|
||||
string[] signatures
|
||||
|
||||
When the client receives this reply (and not a failure), it should
|
||||
validate the signatures and may update its known_hosts file, adding keys
|
||||
that it has not seen before and deleting keys for the server host that
|
||||
are no longer offered.
|
||||
|
||||
These extensions let a client learn key types that it had not previously
|
||||
encountered, thereby allowing it to potentially upgrade from weaker
|
||||
key algorithms to better ones. It also supports graceful key rotation:
|
||||
a server may offer multiple keys of the same type for a period (to
|
||||
give clients an opportunity to learn them using this extension) before
|
||||
removing the deprecated key from those offered.
|
||||
|
||||
2.6. connection: SIGINFO support for "signal" channel request
|
||||
|
||||
The SSH channels protocol (RFC4254 section 6.9) supports sending a
|
||||
signal to a session attached to a channel. OpenSSH supports one
|
||||
extension signal "INFO@openssh.com" that allows sending SIGINFO on
|
||||
BSD-derived systems.
|
||||
|
||||
3. Authentication protocol changes
|
||||
|
||||
3.1. Host-bound public key authentication
|
||||
|
||||
This is trivial change to the traditional "publickey" authentication
|
||||
method. The authentication request is identical to the original method
|
||||
but for the name and one additional field:
|
||||
|
||||
byte SSH2_MSG_USERAUTH_REQUEST
|
||||
string username
|
||||
string "ssh-connection"
|
||||
string "publickey-hostbound-v00@openssh.com"
|
||||
bool has_signature
|
||||
string pkalg
|
||||
string public key
|
||||
string server host key
|
||||
|
||||
Because the entire SSH2_MSG_USERAUTH_REQUEST message is included in
|
||||
the signed data, this ensures that a binding between the destination
|
||||
user, the server identity and the session identifier is visible to the
|
||||
signer. OpenSSH uses this binding via signed data to implement per-key
|
||||
restrictions in ssh-agent.
|
||||
|
||||
A server may advertise this method using the SSH2_MSG_EXT_INFO
|
||||
mechanism (RFC8308), with the following message:
|
||||
|
||||
string "publickey-hostbound@openssh.com"
|
||||
string "0" (version)
|
||||
|
||||
Clients should prefer host-bound authentication when advertised by
|
||||
server.
|
||||
|
||||
4. SFTP protocol changes
|
||||
|
||||
4.1. sftp: Reversal of arguments to SSH_FXP_SYMLINK
|
||||
|
||||
When OpenSSH's sftp-server was implemented, the order of the arguments
|
||||
to the SSH_FXP_SYMLINK method was inadvertently reversed. Unfortunately,
|
||||
the reversal was not noticed until the server was widely deployed. Since
|
||||
fixing this to follow the specification would cause incompatibility, the
|
||||
current order was retained. For correct operation, clients should send
|
||||
SSH_FXP_SYMLINK as follows:
|
||||
|
||||
uint32 id
|
||||
string targetpath
|
||||
string linkpath
|
||||
|
||||
4.2. sftp: Server extension announcement in SSH_FXP_VERSION
|
||||
|
||||
OpenSSH's sftp-server lists the extensions it supports using the
|
||||
standard extension announcement mechanism in the SSH_FXP_VERSION server
|
||||
hello packet:
|
||||
|
||||
uint32 3 /* protocol version */
|
||||
string ext1-name
|
||||
string ext1-version
|
||||
string ext2-name
|
||||
string ext2-version
|
||||
...
|
||||
string extN-name
|
||||
string extN-version
|
||||
|
||||
Each extension reports its integer version number as an ASCII encoded
|
||||
string, e.g. "1". The version will be incremented if the extension is
|
||||
ever changed in an incompatible way. The server MAY advertise the same
|
||||
extension with multiple versions (though this is unlikely). Clients MUST
|
||||
check the version number before attempting to use the extension.
|
||||
|
||||
4.3. sftp: Extension request "posix-rename@openssh.com"
|
||||
|
||||
This operation provides a rename operation with POSIX semantics, which
|
||||
are different to those provided by the standard SSH_FXP_RENAME in
|
||||
draft-ietf-secsh-filexfer-02.txt. This request is implemented as a
|
||||
SSH_FXP_EXTENDED request with the following format:
|
||||
|
||||
uint32 id
|
||||
string "posix-rename@openssh.com"
|
||||
string oldpath
|
||||
string newpath
|
||||
|
||||
On receiving this request the server will perform the POSIX operation
|
||||
rename(oldpath, newpath) and will respond with a SSH_FXP_STATUS message.
|
||||
This extension is advertised in the SSH_FXP_VERSION hello with version
|
||||
"1".
|
||||
|
||||
4.4. sftp: Extension requests "statvfs@openssh.com" and
|
||||
"fstatvfs@openssh.com"
|
||||
|
||||
These requests correspond to the statvfs and fstatvfs POSIX system
|
||||
interfaces. The "statvfs@openssh.com" request operates on an explicit
|
||||
pathname, and is formatted as follows:
|
||||
|
||||
uint32 id
|
||||
string "statvfs@openssh.com"
|
||||
string path
|
||||
|
||||
The "fstatvfs@openssh.com" operates on an open file handle:
|
||||
|
||||
uint32 id
|
||||
string "fstatvfs@openssh.com"
|
||||
string handle
|
||||
|
||||
These requests return a SSH_FXP_STATUS reply on failure. On success they
|
||||
return the following SSH_FXP_EXTENDED_REPLY reply:
|
||||
|
||||
uint32 id
|
||||
uint64 f_bsize /* file system block size */
|
||||
uint64 f_frsize /* fundamental fs block size */
|
||||
uint64 f_blocks /* number of blocks (unit f_frsize) */
|
||||
uint64 f_bfree /* free blocks in file system */
|
||||
uint64 f_bavail /* free blocks for non-root */
|
||||
uint64 f_files /* total file inodes */
|
||||
uint64 f_ffree /* free file inodes */
|
||||
uint64 f_favail /* free file inodes for to non-root */
|
||||
uint64 f_fsid /* file system id */
|
||||
uint64 f_flag /* bit mask of f_flag values */
|
||||
uint64 f_namemax /* maximum filename length */
|
||||
|
||||
The values of the f_flag bitmask are as follows:
|
||||
|
||||
#define SSH_FXE_STATVFS_ST_RDONLY 0x1 /* read-only */
|
||||
#define SSH_FXE_STATVFS_ST_NOSUID 0x2 /* no setuid */
|
||||
|
||||
Both the "statvfs@openssh.com" and "fstatvfs@openssh.com" extensions are
|
||||
advertised in the SSH_FXP_VERSION hello with version "2".
|
||||
|
||||
4.5. sftp: Extension request "hardlink@openssh.com"
|
||||
|
||||
This request is for creating a hard link to a regular file. This
|
||||
request is implemented as a SSH_FXP_EXTENDED request with the
|
||||
following format:
|
||||
|
||||
uint32 id
|
||||
string "hardlink@openssh.com"
|
||||
string oldpath
|
||||
string newpath
|
||||
|
||||
On receiving this request the server will perform the operation
|
||||
link(oldpath, newpath) and will respond with a SSH_FXP_STATUS message.
|
||||
This extension is advertised in the SSH_FXP_VERSION hello with version
|
||||
"1".
|
||||
|
||||
4.6. sftp: Extension request "fsync@openssh.com"
|
||||
|
||||
This request asks the server to call fsync(2) on an open file handle.
|
||||
|
||||
uint32 id
|
||||
string "fsync@openssh.com"
|
||||
string handle
|
||||
|
||||
On receiving this request, a server will call fsync(handle_fd) and will
|
||||
respond with a SSH_FXP_STATUS message.
|
||||
|
||||
This extension is advertised in the SSH_FXP_VERSION hello with version
|
||||
"1".
|
||||
|
||||
4.7. sftp: Extension request "lsetstat@openssh.com"
|
||||
|
||||
This request is like the "setstat" command, but sets file attributes on
|
||||
symlinks. It is implemented as a SSH_FXP_EXTENDED request with the
|
||||
following format:
|
||||
|
||||
uint32 id
|
||||
string "lsetstat@openssh.com"
|
||||
string path
|
||||
ATTRS attrs
|
||||
|
||||
See the "setstat" command for more details.
|
||||
|
||||
This extension is advertised in the SSH_FXP_VERSION hello with version
|
||||
"1".
|
||||
|
||||
4.8. sftp: Extension request "limits@openssh.com"
|
||||
|
||||
This request is used to determine various limits the server might impose.
|
||||
Clients should not attempt to exceed these limits as the server might sever
|
||||
the connection immediately.
|
||||
|
||||
uint32 id
|
||||
string "limits@openssh.com"
|
||||
|
||||
The server will respond with a SSH_FXP_EXTENDED_REPLY reply:
|
||||
|
||||
uint32 id
|
||||
uint64 max-packet-length
|
||||
uint64 max-read-length
|
||||
uint64 max-write-length
|
||||
uint64 max-open-handles
|
||||
|
||||
The 'max-packet-length' applies to the total number of bytes in a
|
||||
single SFTP packet. Servers SHOULD set this at least to 34000.
|
||||
|
||||
The 'max-read-length' is the largest length in a SSH_FXP_READ packet.
|
||||
Even if the client requests a larger size, servers will usually respond
|
||||
with a shorter SSH_FXP_DATA packet. Servers SHOULD set this at least to
|
||||
32768.
|
||||
|
||||
The 'max-write-length' is the largest length in a SSH_FXP_WRITE packet
|
||||
the server will accept. Servers SHOULD set this at least to 32768.
|
||||
|
||||
The 'max-open-handles' is the maximum number of active handles that the
|
||||
server allows (e.g. handles created by SSH_FXP_OPEN and SSH_FXP_OPENDIR
|
||||
packets). Servers MAY count internal file handles against this limit
|
||||
(e.g. system logging or stdout/stderr), so clients SHOULD NOT expect to
|
||||
open this many handles in practice.
|
||||
|
||||
If the server doesn't enforce a specific limit, then the field may be
|
||||
set to 0. This implies the server relies on the OS to enforce limits
|
||||
(e.g. available memory or file handles), and such limits might be
|
||||
dynamic. The client SHOULD take care to not try to exceed reasonable
|
||||
limits.
|
||||
|
||||
This extension is advertised in the SSH_FXP_VERSION hello with version
|
||||
"1".
|
||||
|
||||
4.9. sftp: Extension request "expand-path@openssh.com"
|
||||
|
||||
This request supports canonicalisation of relative paths and
|
||||
those that need tilde-expansion, i.e. "~", "~/..." and "~user/..."
|
||||
These paths are expanded using shell-like rules and the resultant
|
||||
path is canonicalised similarly to SSH2_FXP_REALPATH.
|
||||
|
||||
It is implemented as a SSH_FXP_EXTENDED request with the following
|
||||
format:
|
||||
|
||||
uint32 id
|
||||
string "expand-path@openssh.com"
|
||||
string path
|
||||
|
||||
Its reply is the same format as that of SSH2_FXP_REALPATH.
|
||||
|
||||
This extension is advertised in the SSH_FXP_VERSION hello with version
|
||||
"1".
|
||||
|
||||
4.10. sftp: Extension request "copy-data"
|
||||
|
||||
This request asks the server to copy data from one open file handle and
|
||||
write it to a different open file handle. This avoids needing to transfer
|
||||
the data across the network twice (a download followed by an upload).
|
||||
|
||||
byte SSH_FXP_EXTENDED
|
||||
uint32 id
|
||||
string "copy-data"
|
||||
string read-from-handle
|
||||
uint64 read-from-offset
|
||||
uint64 read-data-length
|
||||
string write-to-handle
|
||||
uint64 write-to-offset
|
||||
|
||||
The server will copy read-data-length bytes starting from
|
||||
read-from-offset from the read-from-handle and write them to
|
||||
write-to-handle starting from write-to-offset, and then respond with a
|
||||
SSH_FXP_STATUS message.
|
||||
|
||||
It's equivalent to issuing a series of SSH_FXP_READ requests on
|
||||
read-from-handle and a series of requests of SSH_FXP_WRITE on
|
||||
write-to-handle.
|
||||
|
||||
If read-from-handle and write-to-handle are the same, the server will
|
||||
fail the request and respond with a SSH_FX_INVALID_PARAMETER message.
|
||||
|
||||
If read-data-length is 0, then the server will read data from the
|
||||
read-from-handle until EOF is reached.
|
||||
|
||||
This extension is advertised in the SSH_FXP_VERSION hello with version
|
||||
"1".
|
||||
|
||||
This request is identical to the "copy-data" request documented in:
|
||||
|
||||
https://tools.ietf.org/html/draft-ietf-secsh-filexfer-extensions-00#section-7
|
||||
|
||||
4.11. sftp: Extension request "home-directory"
|
||||
|
||||
This request asks the server to expand the specified user's home directory.
|
||||
An empty username implies the current user. This can be used by the client
|
||||
to expand ~/ type paths locally.
|
||||
|
||||
byte SSH_FXP_EXTENDED
|
||||
uint32 id
|
||||
string "home-directory"
|
||||
string username
|
||||
|
||||
This extension is advertised in the SSH_FXP_VERSION hello with version
|
||||
"1".
|
||||
|
||||
This provides similar information as the "expand-path@openssh.com" extension.
|
||||
|
||||
This request is identical to the "home-directory" request documented in:
|
||||
|
||||
https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-extensions-00#section-5
|
||||
|
||||
4.12. sftp: Extension request "users-groups-by-id@openssh.com"
|
||||
|
||||
This request asks the server to return user and/or group names that
|
||||
correspond to one or more IDs (e.g. as returned from a SSH_FXP_STAT
|
||||
request). This may be used by the client to provide usernames in
|
||||
directory listings.
|
||||
|
||||
byte SSH_FXP_EXTENDED
|
||||
uint32 id
|
||||
string "users-groups-by-id@openssh.com"
|
||||
string uids
|
||||
string gids
|
||||
|
||||
Where "uids" and "gids" consists of one or more integer user or group
|
||||
identifiers:
|
||||
|
||||
uint32 id-0
|
||||
...
|
||||
|
||||
The server will reply with a SSH_FXP_EXTENDED_REPLY:
|
||||
|
||||
byte SSH_FXP_EXTENDED_REPLY
|
||||
uint32 id
|
||||
string usernames
|
||||
string groupnames
|
||||
|
||||
Where "username" and "groupnames" consists of names in identical request
|
||||
order to "uids" and "gids" respectively:
|
||||
|
||||
string name-0
|
||||
...
|
||||
|
||||
If a name cannot be identified for a given user or group ID, an empty
|
||||
string will be returned in its place.
|
||||
|
||||
It is acceptable for either "uids" or "gids" to be an empty set, in
|
||||
which case the respective "usernames" or "groupnames" list will also
|
||||
be empty.
|
||||
|
||||
This extension is advertised in the SSH_FXP_VERSION hello with version
|
||||
"1".
|
||||
|
||||
5. Miscellaneous changes
|
||||
|
||||
5.1 Public key format
|
||||
|
||||
OpenSSH public keys, as generated by ssh-keygen(1) and appearing in
|
||||
authorized_keys files, are formatted as a single line of text consisting
|
||||
of the public key algorithm name followed by a base64-encoded key blob.
|
||||
The public key blob (before base64 encoding) is the same format used for
|
||||
the encoding of public keys sent on the wire: as described in RFC4253
|
||||
section 6.6 for RSA and DSA keys, RFC5656 section 3.1 for ECDSA keys
|
||||
and the "New public key formats" section of PROTOCOL.certkeys for the
|
||||
OpenSSH certificate formats.
|
||||
|
||||
5.2 Private key format
|
||||
|
||||
OpenSSH private keys, as generated by ssh-keygen(1) use the format
|
||||
described in PROTOCOL.key by default. As a legacy option, PEM format
|
||||
(RFC7468) private keys are also supported for RSA, DSA and ECDSA keys
|
||||
and were the default format before OpenSSH 7.8.
|
||||
|
||||
5.3 KRL format
|
||||
|
||||
OpenSSH supports a compact format for Key Revocation Lists (KRLs). This
|
||||
format is described in the PROTOCOL.krl file.
|
||||
|
||||
5.4 Connection multiplexing
|
||||
|
||||
OpenSSH's connection multiplexing uses messages as described in
|
||||
PROTOCOL.mux over a Unix domain socket for communications between a
|
||||
master instance and later clients.
|
||||
|
||||
5.5. Agent protocol extensions
|
||||
|
||||
OpenSSH extends the usual agent protocol. These changes are documented
|
||||
in the PROTOCOL.agent file.
|
||||
|
||||
$OpenBSD: PROTOCOL,v 1.55 2024/01/08 05:05:15 djm Exp $
|
118
PROTOCOL.agent
Normal file
118
PROTOCOL.agent
Normal file
|
@ -0,0 +1,118 @@
|
|||
The SSH agent protocol is described in
|
||||
https://datatracker.ietf.org/doc/draft-ietf-sshm-ssh-agent/
|
||||
|
||||
This file documents OpenSSH's extensions to the agent protocol.
|
||||
|
||||
1. session-bind@openssh.com extension
|
||||
|
||||
This extension allows a ssh client to bind an agent connection to a
|
||||
particular SSH session identifier as derived from the initial key
|
||||
exchange (as per RFC4253 section 7.2) and the host key used for that
|
||||
exchange. This binding is verifiable at the agent by including the
|
||||
initial KEX signature made by the host key.
|
||||
|
||||
The message format is:
|
||||
|
||||
byte SSH_AGENTC_EXTENSION (0x1b)
|
||||
string session-bind@openssh.com
|
||||
string hostkey
|
||||
string session identifier
|
||||
string signature
|
||||
bool is_forwarding
|
||||
|
||||
Where 'hostkey' is the encoded server host public key, 'session
|
||||
identifier' is the exchange hash derived from the initial key
|
||||
exchange, 'signature' is the server's signature of the session
|
||||
identifier using the private hostkey, as sent in the final
|
||||
SSH2_MSG_KEXDH_REPLY/SSH2_MSG_KEXECDH_REPLY message of the initial key
|
||||
exchange. 'is_forwarding' is a flag indicating whether this connection
|
||||
should be bound for user authentication or forwarding.
|
||||
|
||||
When an agent received this message, it will verify the signature and
|
||||
check the consistency of its contents, including refusing to accept
|
||||
a duplicate session identifier, or any attempt to bind a connection
|
||||
previously bound for authentication. It will then record the
|
||||
binding for the life of the connection for use later in testing per-key
|
||||
destination constraints.
|
||||
|
||||
2. restrict-destination-v00@openssh.com key constraint extension
|
||||
|
||||
The key constraint extension supports destination- and forwarding path-
|
||||
restricted keys. It may be attached as a constraint when keys or
|
||||
smartcard keys are added to an agent.
|
||||
|
||||
byte SSH_AGENT_CONSTRAIN_EXTENSION (0xff)
|
||||
string restrict-destination-v00@openssh.com
|
||||
constraint[] constraints
|
||||
|
||||
Where a constraint consists of:
|
||||
|
||||
string from_username (must be empty)
|
||||
string from_hostname
|
||||
string reserved
|
||||
keyspec[] from_hostkeys
|
||||
string to_username
|
||||
string to_hostname
|
||||
string reserved
|
||||
keyspec[] to_hostkeys
|
||||
string reserved
|
||||
|
||||
And a keyspec consists of:
|
||||
|
||||
string keyblob
|
||||
bool is_ca
|
||||
|
||||
When receiving this message, the agent will ensure that the
|
||||
'from_username' field is empty, and that 'to_hostname' and 'to_hostkeys'
|
||||
have been supplied (empty 'from_hostname' and 'from_hostkeys' are valid
|
||||
and signify the initial hop from the host running ssh-agent). The agent
|
||||
will then record the constraint against the key.
|
||||
|
||||
Subsequent operations on this key including add/remove/request
|
||||
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
|
||||
with private keys as they are loaded from a PKCS#11 token.
|
||||
|
||||
byte SSH_AGENT_CONSTRAIN_EXTENSION (0xff)
|
||||
string associated-certs-v00@openssh.com
|
||||
bool certs_only
|
||||
string certsblob
|
||||
|
||||
Where "certsblob" consists of one or more certificates encoded as public
|
||||
key blobs:
|
||||
|
||||
string[] certificates
|
||||
|
||||
This extension is only valid for SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED
|
||||
requests. When an agent receives this extension, it will attempt to match
|
||||
each certificate in the request with a corresponding private key loaded
|
||||
from the requested PKCS#11 token. When a matching key is found, the
|
||||
agent will graft the certificate contents to the token-hosted private key
|
||||
and store the result for subsequent use by regular agent operations.
|
||||
|
||||
If the "certs_only" flag is set, then this extension will cause ONLY
|
||||
the resultant certificates to be loaded to the agent. The default
|
||||
behaviour is to load the PKCS#11-hosted private key as well as the
|
||||
resultant certificate.
|
||||
|
||||
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.24 2024/11/27 13:27:34 djm Exp $
|
326
PROTOCOL.certkeys
Normal file
326
PROTOCOL.certkeys
Normal file
|
@ -0,0 +1,326 @@
|
|||
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. The data field contains
|
||||
option-specific information encoded as zero or more values inside
|
||||
the string. I.e. an empty data field would be encoded as a zero-
|
||||
length string (00 00 00 00), and data field that holds a single
|
||||
string value "a" would be encoded as (00 00 00 05 00 00 00 01 65).
|
||||
|
||||
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.20 2024/12/06 16:02:12 djm Exp $
|
107
PROTOCOL.chacha20poly1305
Normal file
107
PROTOCOL.chacha20poly1305
Normal file
|
@ -0,0 +1,107 @@
|
|||
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 $
|
||||
|
71
PROTOCOL.key
Normal file
71
PROTOCOL.key
Normal file
|
@ -0,0 +1,71 @@
|
|||
This document describes the private key format for OpenSSH.
|
||||
|
||||
1. Overall format
|
||||
|
||||
The key consists of a header, a list of public keys, and
|
||||
an encrypted list of matching private keys.
|
||||
|
||||
#define AUTH_MAGIC "openssh-key-v1"
|
||||
|
||||
byte[] AUTH_MAGIC
|
||||
string ciphername
|
||||
string kdfname
|
||||
string kdfoptions
|
||||
uint32 number of keys N
|
||||
string publickey1
|
||||
string publickey2
|
||||
...
|
||||
string publickeyN
|
||||
string encrypted, padded list of private keys
|
||||
|
||||
2. KDF options for kdfname "bcrypt"
|
||||
|
||||
The options:
|
||||
|
||||
string salt
|
||||
uint32 rounds
|
||||
|
||||
are concatenated and represented as a string.
|
||||
|
||||
3. Unencrypted list of N private keys
|
||||
|
||||
The list of privatekey/comment pairs is padded with the
|
||||
bytes 1, 2, 3, ... until the total length is a multiple
|
||||
of the cipher block size.
|
||||
|
||||
uint32 checkint
|
||||
uint32 checkint
|
||||
byte[] privatekey1
|
||||
string comment1
|
||||
byte[] privatekey2
|
||||
string comment2
|
||||
...
|
||||
byte[] privatekeyN
|
||||
string commentN
|
||||
byte 1
|
||||
byte 2
|
||||
byte 3
|
||||
...
|
||||
byte padlen % 255
|
||||
|
||||
where each private key is encoded using the same rules as used for
|
||||
SSH agent.
|
||||
|
||||
Before the key is encrypted, a random integer is assigned
|
||||
to both checkint fields so successful decryption can be
|
||||
quickly checked by verifying that both checkint fields
|
||||
hold the same value.
|
||||
|
||||
4. Encryption
|
||||
|
||||
The KDF is used to derive a key, IV (and other values required by
|
||||
the cipher) from the passphrase. These values are then used to
|
||||
encrypt the unencrypted list of private keys.
|
||||
|
||||
5. No encryption
|
||||
|
||||
For unencrypted keys the cipher "none" and the KDF "none"
|
||||
are used with empty passphrases. The options if the KDF "none"
|
||||
are the empty string.
|
||||
|
||||
$OpenBSD: PROTOCOL.key,v 1.4 2024/03/30 05:56:22 djm Exp $
|
222
PROTOCOL.krl
Normal file
222
PROTOCOL.krl
Normal file
|
@ -0,0 +1,222 @@
|
|||
This describes the key/certificate revocation list format for OpenSSH.
|
||||
|
||||
1. Overall format
|
||||
|
||||
The KRL consists of a header and zero or more sections. The header is:
|
||||
|
||||
#define KRL_MAGIC 0x5353484b524c0a00ULL /* "SSHKRL\n\0" */
|
||||
#define KRL_FORMAT_VERSION 1
|
||||
|
||||
uint64 KRL_MAGIC
|
||||
uint32 KRL_FORMAT_VERSION
|
||||
uint64 krl_version
|
||||
uint64 generated_date
|
||||
uint64 flags
|
||||
string reserved
|
||||
string comment
|
||||
|
||||
Where "krl_version" is a version number that increases each time the KRL
|
||||
is modified, "generated_date" is the time in seconds since 1970-01-01
|
||||
00:00:00 UTC that the KRL was generated, "comment" is an optional comment
|
||||
and "reserved" an extension field whose contents are currently ignored.
|
||||
No "flags" are currently defined.
|
||||
|
||||
Following the header are zero or more sections, each consisting of:
|
||||
|
||||
byte section_type
|
||||
string section_data
|
||||
|
||||
Where "section_type" indicates the type of the "section_data". An exception
|
||||
to this is the KRL_SECTION_SIGNATURE section, that has a slightly different
|
||||
format (see below).
|
||||
|
||||
The available section types are:
|
||||
|
||||
#define KRL_SECTION_CERTIFICATES 1
|
||||
#define KRL_SECTION_EXPLICIT_KEY 2
|
||||
#define KRL_SECTION_FINGERPRINT_SHA1 3
|
||||
#define KRL_SECTION_SIGNATURE 4
|
||||
#define KRL_SECTION_FINGERPRINT_SHA256 5
|
||||
#define KRL_SECTION_EXTENSION 255
|
||||
|
||||
2. Certificate section
|
||||
|
||||
These sections use type KRL_SECTION_CERTIFICATES to revoke certificates by
|
||||
serial number or key ID. The consist of the CA key that issued the
|
||||
certificates to be revoked and a reserved field whose contents is currently
|
||||
ignored.
|
||||
|
||||
string ca_key
|
||||
string reserved
|
||||
|
||||
Where "ca_key" is the standard SSH wire serialisation of the CA's
|
||||
public key. Alternately, "ca_key" may be an empty string to indicate
|
||||
the certificate section applies to all CAs (this is most useful when
|
||||
revoking key IDs).
|
||||
|
||||
Followed by one or more sections:
|
||||
|
||||
byte cert_section_type
|
||||
string cert_section_data
|
||||
|
||||
The certificate section types are:
|
||||
|
||||
#define KRL_SECTION_CERT_SERIAL_LIST 0x20
|
||||
#define KRL_SECTION_CERT_SERIAL_RANGE 0x21
|
||||
#define KRL_SECTION_CERT_SERIAL_BITMAP 0x22
|
||||
#define KRL_SECTION_CERT_KEY_ID 0x23
|
||||
#define KRL_SECTION_CERT_EXTENSION 0x39
|
||||
|
||||
2.1 Certificate serial list section
|
||||
|
||||
This section is identified as KRL_SECTION_CERT_SERIAL_LIST. It revokes
|
||||
certificates by listing their serial numbers. The cert_section_data in this
|
||||
case contains:
|
||||
|
||||
uint64 revoked_cert_serial
|
||||
uint64 ...
|
||||
|
||||
This section may appear multiple times.
|
||||
|
||||
2.2. Certificate serial range section
|
||||
|
||||
These sections use type KRL_SECTION_CERT_SERIAL_RANGE and hold
|
||||
a range of serial numbers of certificates:
|
||||
|
||||
uint64 serial_min
|
||||
uint64 serial_max
|
||||
|
||||
All certificates in the range serial_min <= serial <= serial_max are
|
||||
revoked.
|
||||
|
||||
This section may appear multiple times.
|
||||
|
||||
2.3. Certificate serial bitmap section
|
||||
|
||||
Bitmap sections use type KRL_SECTION_CERT_SERIAL_BITMAP and revoke keys
|
||||
by listing their serial number in a bitmap.
|
||||
|
||||
uint64 serial_offset
|
||||
mpint revoked_keys_bitmap
|
||||
|
||||
A bit set at index N in the bitmap corresponds to revocation of a keys with
|
||||
serial number (serial_offset + N).
|
||||
|
||||
This section may appear multiple times.
|
||||
|
||||
2.4. Revoked key ID sections
|
||||
|
||||
KRL_SECTION_CERT_KEY_ID sections revoke particular certificate "key
|
||||
ID" strings. This may be useful in revoking all certificates
|
||||
associated with a particular identity, e.g. a host or a user.
|
||||
|
||||
string key_id[0]
|
||||
...
|
||||
|
||||
This section must contain at least one "key_id". This section may appear
|
||||
multiple times.
|
||||
|
||||
2.5. Certificate Extension subsections
|
||||
|
||||
This subsection type provides a generic extension mechanism to the
|
||||
certificates KRL section that may be used to provide optional or critical
|
||||
data.
|
||||
|
||||
Extensions are stored in subsections of type
|
||||
KRL_SECTION_CERT_EXTENSION with the following contents:
|
||||
|
||||
string extension_name
|
||||
boolean is_critical
|
||||
string extension_contents.
|
||||
|
||||
Where "extension_name" describes the type of extension. It is
|
||||
recommended that user extensions follow "cert-name@domain.org" naming.
|
||||
|
||||
The "is_critical" indicates whether this extension is mandatory or
|
||||
optional. If true, then any unsupported extension encountered should
|
||||
result in KRL parsing failure. If false, then it may be safely be
|
||||
ignored.
|
||||
|
||||
The "extension_contents" contains the body of the extension.
|
||||
|
||||
3. Explicit key sections
|
||||
|
||||
These sections, identified as KRL_SECTION_EXPLICIT_KEY, revoke keys
|
||||
(not certificates). They are less space efficient than serial numbers,
|
||||
but are able to revoke plain keys.
|
||||
|
||||
string public_key_blob[0]
|
||||
....
|
||||
|
||||
This section must contain at least one "public_key_blob". The blob
|
||||
must be a raw key (i.e. not a certificate).
|
||||
|
||||
This section may appear multiple times.
|
||||
|
||||
4. SHA1/SHA256 fingerprint sections
|
||||
|
||||
These sections, identified as KRL_SECTION_FINGERPRINT_SHA1 and
|
||||
KRL_SECTION_FINGERPRINT_SHA256, revoke plain keys (i.e. not
|
||||
certificates) by listing their hashes:
|
||||
|
||||
string public_key_hash[0]
|
||||
....
|
||||
|
||||
This section must contain at least one "public_key_hash". The hash blob
|
||||
is obtained by taking the SHA1 or SHA256 hash of the public key blob.
|
||||
Hashes in this section must appear in numeric order, treating each hash
|
||||
as a big-endian integer.
|
||||
|
||||
This section may appear multiple times.
|
||||
|
||||
5. Extension sections
|
||||
|
||||
This section type provides a generic extension mechanism to the KRL
|
||||
format that may be used to provide optional or critical data.
|
||||
|
||||
Extensions are recorded in sections of type KRL_SECTION_EXTENSION
|
||||
with the following contents:
|
||||
|
||||
string extension_name
|
||||
boolean is_critical
|
||||
string extension_contents.
|
||||
|
||||
Where "extension_name" describes the type of extension. It is
|
||||
recommended that user extensions follow "name@domain.org" naming.
|
||||
|
||||
The "is_critical" indicates whether this extension is mandatory or
|
||||
optional. If true, then any unsupported extension encountered should
|
||||
result in KRL parsing failure. If false, then it may be safely be
|
||||
ignored.
|
||||
|
||||
The "extension_contents" contains the body of the extension.
|
||||
|
||||
6. KRL signature sections
|
||||
|
||||
Note: KRL signatures are not supported by OpenSSH. OpenSSH >= 9.4 will
|
||||
refuse to load KRLs that contain signatures. We recommend the use
|
||||
of SSHSIG (`ssh-keygen -Y sign ...`) style signatures for KRLs instead.
|
||||
|
||||
The KRL_SECTION_SIGNATURE section serves a different purpose to the
|
||||
preceding ones: to provide cryptographic authentication of a KRL that
|
||||
is retrieved over a channel that does not provide integrity protection.
|
||||
Its format is slightly different to the previously-described sections:
|
||||
in order to simplify the signature generation, it includes as a "body"
|
||||
two string components instead of one.
|
||||
|
||||
byte KRL_SECTION_SIGNATURE
|
||||
string signature_key
|
||||
string signature
|
||||
|
||||
The signature is calculated over the entire KRL from the KRL_MAGIC
|
||||
to this subsection's "signature_key", including both and using the
|
||||
signature generation rules appropriate for the type of "signature_key".
|
||||
|
||||
This section must appear last in the KRL. If multiple signature sections
|
||||
appear, they must appear consecutively at the end of the KRL file.
|
||||
|
||||
Implementations that retrieve KRLs over untrusted channels must verify
|
||||
signatures. Signature sections are optional for KRLs distributed by
|
||||
trusted means.
|
||||
|
||||
$OpenBSD: PROTOCOL.krl,v 1.7 2023/07/17 04:01:10 djm Exp $
|
296
PROTOCOL.mux
Normal file
296
PROTOCOL.mux
Normal file
|
@ -0,0 +1,296 @@
|
|||
This document describes the multiplexing protocol used by ssh(1)'s
|
||||
ControlMaster connection-sharing.
|
||||
|
||||
Multiplexing starts with a ssh(1) configured to act as a multiplexing
|
||||
master. This will cause ssh(1) to listen on a Unix domain socket for
|
||||
requests from clients. Clients communicate over this socket using a
|
||||
simple packetised protocol, where each message is proceeded with
|
||||
a length and message type in SSH uint32 wire format:
|
||||
|
||||
uint32 packet length
|
||||
uint32 packet type
|
||||
... packet body
|
||||
|
||||
Most messages from the client to the server contain a "request id"
|
||||
field. This field is returned in replies as "client request id" to
|
||||
facilitate matching of responses to requests.
|
||||
|
||||
Many multiplexing (mux) client requests yield immediate responses from
|
||||
the mux process; requesting a forwarding, performing an alive check or
|
||||
requesting the master terminate itself fall in to this category.
|
||||
|
||||
The most common use of multiplexing however is to maintain multiple
|
||||
concurrent sessions. These are supported via two separate modes:
|
||||
|
||||
"Passenger" clients start by requesting a new session with a
|
||||
MUX_C_NEW_SESSION message and passing stdio file descriptors over the
|
||||
Unix domain control socket. The passenger client then waits until it is
|
||||
signaled or the mux server closes the session. This mode is so named as
|
||||
the client waits around while the mux server does all the driving.
|
||||
|
||||
Stdio forwarding (requested using MUX_C_NEW_STDIO_FWD) is another
|
||||
example of passenger mode; the client passes the stdio file descriptors
|
||||
and passively waits for something to happen.
|
||||
|
||||
"Proxy" clients, requested using MUX_C_PROXY, work quite differently. In
|
||||
this mode, the mux client/server connection socket will stop speaking
|
||||
the multiplexing protocol and start proxying SSH connection protocol
|
||||
messages between the client and server. The client therefore must
|
||||
speak a significant subset of the SSH protocol, but in return is able
|
||||
to access basically the full suite of connection protocol features.
|
||||
Moreover, as no file descriptor passing is required, the connection
|
||||
supporting a proxy client may itself be forwarded or relayed to another
|
||||
host if necessary.
|
||||
|
||||
1. Connection setup
|
||||
|
||||
When a multiplexing connection is made to a ssh(1) operating as a
|
||||
ControlMaster from a client ssh(1), the first action of each is send
|
||||
a hello messages to its peer:
|
||||
|
||||
uint32 MUX_MSG_HELLO
|
||||
uint32 protocol version
|
||||
string extension name [optional]
|
||||
string extension value [optional]
|
||||
...
|
||||
|
||||
The current version of the mux protocol is 4. A client should refuse
|
||||
to connect to a master that speaks an unsupported protocol version.
|
||||
|
||||
Following the version identifier are zero or more extensions represented
|
||||
as a name/value pair. No extensions are currently defined.
|
||||
|
||||
2. Opening a passenger mode session
|
||||
|
||||
To open a new multiplexed session in passenger mode, a client sends the
|
||||
following request:
|
||||
|
||||
uint32 MUX_C_NEW_SESSION
|
||||
uint32 request id
|
||||
string reserved
|
||||
bool want tty flag
|
||||
bool want X11 forwarding flag
|
||||
bool want agent flag
|
||||
bool subsystem flag
|
||||
uint32 escape char
|
||||
string terminal type
|
||||
string command
|
||||
string environment string 0 [optional]
|
||||
...
|
||||
|
||||
To disable the use of an escape character, "escape char" may be set
|
||||
to 0xffffffff. "terminal type" is generally set to the value of
|
||||
$TERM. zero or more environment strings may follow the command.
|
||||
|
||||
The client then sends its standard input, output and error file
|
||||
descriptors (in that order) using Unix domain socket control messages.
|
||||
|
||||
The contents of "reserved" are currently ignored.
|
||||
|
||||
If successful, the server will reply with MUX_S_SESSION_OPENED
|
||||
|
||||
uint32 MUX_S_SESSION_OPENED
|
||||
uint32 client request id
|
||||
uint32 session id
|
||||
|
||||
Otherwise it will reply with an error: MUX_S_PERMISSION_DENIED or
|
||||
MUX_S_FAILURE.
|
||||
|
||||
Once the server has received the fds, it will respond with MUX_S_OK
|
||||
indicating that the session is up. The client now waits for the
|
||||
session to end. When it does, the server will send an exit status
|
||||
message:
|
||||
|
||||
uint32 MUX_S_EXIT_MESSAGE
|
||||
uint32 session id
|
||||
uint32 exit value
|
||||
|
||||
The client should exit with this value to mimic the behaviour of a
|
||||
non-multiplexed ssh(1) connection. Two additional cases that the
|
||||
client must cope with are it receiving a signal itself and the
|
||||
server disconnecting without sending an exit message.
|
||||
|
||||
A master may also send a MUX_S_TTY_ALLOC_FAIL before MUX_S_EXIT_MESSAGE
|
||||
if remote TTY allocation was unsuccessful. The client may use this to
|
||||
return its local tty to "cooked" mode.
|
||||
|
||||
uint32 MUX_S_TTY_ALLOC_FAIL
|
||||
uint32 session id
|
||||
|
||||
3. Requesting passenger-mode stdio forwarding
|
||||
|
||||
A client may request the master to establish a stdio forwarding:
|
||||
|
||||
uint32 MUX_C_NEW_STDIO_FWD
|
||||
uint32 request id
|
||||
string reserved
|
||||
string connect host
|
||||
string connect port
|
||||
|
||||
The client then sends its standard input and output file descriptors
|
||||
(in that order) using Unix domain socket control messages.
|
||||
|
||||
The contents of "reserved" are currently ignored.
|
||||
|
||||
A server may reply with a MUX_S_SESSION_OPENED, a MUX_S_PERMISSION_DENIED
|
||||
or a MUX_S_FAILURE.
|
||||
|
||||
4. Health checks
|
||||
|
||||
The client may request a health check/PID report from a server:
|
||||
|
||||
uint32 MUX_C_ALIVE_CHECK
|
||||
uint32 request id
|
||||
|
||||
The server replies with:
|
||||
|
||||
uint32 MUX_S_ALIVE
|
||||
uint32 client request id
|
||||
uint32 server pid
|
||||
|
||||
5. Remotely terminating a master
|
||||
|
||||
A client may request that a master terminate immediately:
|
||||
|
||||
uint32 MUX_C_TERMINATE
|
||||
uint32 request id
|
||||
|
||||
The server will reply with one of MUX_S_OK or MUX_S_PERMISSION_DENIED.
|
||||
|
||||
6. Requesting establishment of port forwards
|
||||
|
||||
A client may request the master to establish a port forward:
|
||||
|
||||
uint32 MUX_C_OPEN_FWD
|
||||
uint32 request id
|
||||
uint32 forwarding type
|
||||
string listen host
|
||||
uint32 listen port
|
||||
string connect host
|
||||
uint32 connect port
|
||||
|
||||
forwarding type may be MUX_FWD_LOCAL, MUX_FWD_REMOTE, MUX_FWD_DYNAMIC.
|
||||
|
||||
If listen port is (unsigned int) -2, then the listen host is treated as
|
||||
a unix socket path name.
|
||||
|
||||
If connect port is (unsigned int) -2, then the connect host is treated
|
||||
as a unix socket path name.
|
||||
|
||||
A server may reply with a MUX_S_OK, a MUX_S_REMOTE_PORT, a
|
||||
MUX_S_PERMISSION_DENIED or a MUX_S_FAILURE.
|
||||
|
||||
For dynamically allocated listen port the server replies with
|
||||
|
||||
uint32 MUX_S_REMOTE_PORT
|
||||
uint32 client request id
|
||||
uint32 allocated remote listen port
|
||||
|
||||
7. Requesting closure of port forwards
|
||||
|
||||
A client may request the master to close a port forward:
|
||||
|
||||
uint32 MUX_C_CLOSE_FWD
|
||||
uint32 request id
|
||||
uint32 forwarding type
|
||||
string listen host
|
||||
uint32 listen port
|
||||
string connect host
|
||||
uint32 connect port
|
||||
|
||||
A server may reply with a MUX_S_OK, a MUX_S_PERMISSION_DENIED or a
|
||||
MUX_S_FAILURE.
|
||||
|
||||
8. Requesting shutdown of mux listener
|
||||
|
||||
A client may request the master to stop accepting new multiplexing requests
|
||||
and remove its listener socket.
|
||||
|
||||
uint32 MUX_C_STOP_LISTENING
|
||||
uint32 request id
|
||||
|
||||
A server may reply with a MUX_S_OK, a MUX_S_PERMISSION_DENIED or a
|
||||
MUX_S_FAILURE.
|
||||
|
||||
9. Requesting proxy mode
|
||||
|
||||
A client may request that the control connection be placed in proxy
|
||||
mode:
|
||||
|
||||
uint32 MUX_C_PROXY
|
||||
uint32 request id
|
||||
|
||||
When a mux master receives this message, it will reply with a
|
||||
confirmation:
|
||||
|
||||
uint32 MUX_S_PROXY
|
||||
uint32 request id
|
||||
|
||||
And go into proxy mode. All subsequent data over the connection will
|
||||
be formatted as unencrypted, unpadded, SSH transport messages:
|
||||
|
||||
uint32 packet length
|
||||
byte 0 (padding length)
|
||||
byte packet type
|
||||
byte[packet length - 2] ...
|
||||
|
||||
The mux master will accept most connection messages and global requests,
|
||||
and will translate channel identifiers to ensure that the proxy client has
|
||||
globally unique channel numbers (i.e. a proxy client need not worry about
|
||||
collisions with other clients).
|
||||
|
||||
10. Status messages
|
||||
|
||||
The MUX_S_OK message is empty:
|
||||
|
||||
uint32 MUX_S_OK
|
||||
uint32 client request id
|
||||
|
||||
The MUX_S_PERMISSION_DENIED and MUX_S_FAILURE include a reason:
|
||||
|
||||
uint32 MUX_S_PERMISSION_DENIED
|
||||
uint32 client request id
|
||||
string reason
|
||||
|
||||
uint32 MUX_S_FAILURE
|
||||
uint32 client request id
|
||||
string reason
|
||||
|
||||
11. Protocol numbers
|
||||
|
||||
#define MUX_MSG_HELLO 0x00000001
|
||||
#define MUX_C_NEW_SESSION 0x10000002
|
||||
#define MUX_C_ALIVE_CHECK 0x10000004
|
||||
#define MUX_C_TERMINATE 0x10000005
|
||||
#define MUX_C_OPEN_FWD 0x10000006
|
||||
#define MUX_C_CLOSE_FWD 0x10000007
|
||||
#define MUX_C_NEW_STDIO_FWD 0x10000008
|
||||
#define MUX_C_STOP_LISTENING 0x10000009
|
||||
#define MUX_S_OK 0x80000001
|
||||
#define MUX_S_PERMISSION_DENIED 0x80000002
|
||||
#define MUX_S_FAILURE 0x80000003
|
||||
#define MUX_S_EXIT_MESSAGE 0x80000004
|
||||
#define MUX_S_ALIVE 0x80000005
|
||||
#define MUX_S_SESSION_OPENED 0x80000006
|
||||
#define MUX_S_REMOTE_PORT 0x80000007
|
||||
#define MUX_S_TTY_ALLOC_FAIL 0x80000008
|
||||
|
||||
#define MUX_FWD_LOCAL 1
|
||||
#define MUX_FWD_REMOTE 2
|
||||
#define MUX_FWD_DYNAMIC 3
|
||||
|
||||
XXX TODO
|
||||
XXX extended status (e.g. report open channels / forwards)
|
||||
XXX lock (maybe)
|
||||
XXX watch in/out traffic (pre/post crypto)
|
||||
XXX inject packet (what about replies)
|
||||
XXX server->client error/warning notifications
|
||||
XXX send signals via mux
|
||||
XXX ^Z support in passengers
|
||||
XXX extensions for multi-agent
|
||||
XXX extensions for multi-X11
|
||||
XXX session inspection via master
|
||||
XXX signals via mux request
|
||||
XXX list active connections via mux
|
||||
|
||||
$OpenBSD: PROTOCOL.mux,v 1.14 2024/01/08 05:11:18 djm Exp $
|
100
PROTOCOL.sshsig
Normal file
100
PROTOCOL.sshsig
Normal file
|
@ -0,0 +1,100 @@
|
|||
This document describes a lightweight SSH Signature format
|
||||
that is compatible with SSH keys and wire formats.
|
||||
|
||||
At present, only detached and armored signatures are supported.
|
||||
|
||||
1. Armored format
|
||||
|
||||
The Armored SSH signatures consist of a header, a base64
|
||||
encoded blob, and a footer.
|
||||
|
||||
The header is the string "-----BEGIN SSH SIGNATURE-----"
|
||||
followed by a newline. The footer is the string
|
||||
"-----END SSH SIGNATURE-----" immediately after a newline.
|
||||
|
||||
The header MUST be present at the start of every signature.
|
||||
Files containing the signature MUST start with the header.
|
||||
Likewise, the footer MUST be present at the end of every
|
||||
signature.
|
||||
|
||||
The base64 encoded blob SHOULD be broken up by newlines
|
||||
every 76 characters.
|
||||
|
||||
Example:
|
||||
|
||||
-----BEGIN SSH SIGNATURE-----
|
||||
U1NIU0lHAAAAAQAAADMAAAALc3NoLWVkMjU1MTkAAAAgJKxoLBJBivUPNTUJUSslQTt2hD
|
||||
jozKvHarKeN8uYFqgAAAADZm9vAAAAAAAAAFMAAAALc3NoLWVkMjU1MTkAAABAKNC4IEbt
|
||||
Tq0Fb56xhtuE1/lK9H9RZJfON4o6hE9R4ZGFX98gy0+fFJ/1d2/RxnZky0Y7GojwrZkrHT
|
||||
FgCqVWAQ==
|
||||
-----END SSH SIGNATURE-----
|
||||
|
||||
2. Blob format
|
||||
|
||||
#define MAGIC_PREAMBLE "SSHSIG"
|
||||
#define SIG_VERSION 0x01
|
||||
|
||||
byte[6] MAGIC_PREAMBLE
|
||||
uint32 SIG_VERSION
|
||||
string publickey
|
||||
string namespace
|
||||
string reserved
|
||||
string hash_algorithm
|
||||
string signature
|
||||
|
||||
The publickey field MUST contain the serialisation of the
|
||||
public key used to make the signature using the usual SSH
|
||||
encoding rules, i.e RFC4253, RFC5656,
|
||||
draft-ietf-curdle-ssh-ed25519-ed448, etc.
|
||||
|
||||
Verifiers MUST reject signatures with versions greater than those
|
||||
they support.
|
||||
|
||||
The purpose of the namespace value is to specify a unambiguous
|
||||
interpretation domain for the signature, e.g. file signing.
|
||||
This prevents cross-protocol attacks caused by signatures
|
||||
intended for one intended domain being accepted in another.
|
||||
The namespace value MUST NOT be the empty string.
|
||||
|
||||
The reserved value is present to encode future information
|
||||
(e.g. tags) into the signature. Implementations should ignore
|
||||
the reserved field if it is not empty.
|
||||
|
||||
Data to be signed is first hashed with the specified hash_algorithm.
|
||||
This is done to limit the amount of data presented to the signature
|
||||
operation, which may be of concern if the signing key is held in limited
|
||||
or slow hardware or on a remote ssh-agent. The supported hash algorithms
|
||||
are "sha256" and "sha512".
|
||||
|
||||
The signature itself is made using the SSH signature algorithm and
|
||||
encoding rules for the chosen key type. For RSA signatures, the
|
||||
signature algorithm must be "rsa-sha2-512" or "rsa-sha2-256" (i.e.
|
||||
not the legacy RSA-SHA1 "ssh-rsa").
|
||||
|
||||
This blob is encoded as a string using the RFC4253 encoding
|
||||
rules and base64 encoded to form the middle part of the
|
||||
armored signature.
|
||||
|
||||
|
||||
3. Signed Data, of which the signature goes into the blob above
|
||||
|
||||
#define MAGIC_PREAMBLE "SSHSIG"
|
||||
|
||||
byte[6] MAGIC_PREAMBLE
|
||||
string namespace
|
||||
string reserved
|
||||
string hash_algorithm
|
||||
string H(message)
|
||||
|
||||
The preamble is the six-byte sequence "SSHSIG". It is included to
|
||||
ensure that manual signatures can never be confused with any message
|
||||
signed during SSH user or host authentication.
|
||||
|
||||
The reserved value is present to encode future information
|
||||
(e.g. tags) into the signature. Implementations should ignore
|
||||
the reserved field if it is not empty.
|
||||
|
||||
The data is concatenated and passed to the SSH signing
|
||||
function.
|
||||
|
||||
$OpenBSD: PROTOCOL.sshsig,v 1.4 2020/08/31 00:17:41 djm Exp $
|
309
PROTOCOL.u2f
Normal file
309
PROTOCOL.u2f
Normal file
|
@ -0,0 +1,309 @@
|
|||
This document describes OpenSSH's support for U2F/FIDO security keys.
|
||||
|
||||
Background
|
||||
----------
|
||||
|
||||
U2F is an open standard for two-factor authentication hardware, widely
|
||||
used for user authentication to websites. U2F tokens are ubiquitous,
|
||||
available from a number of manufacturers and are currently by far the
|
||||
cheapest way for users to achieve hardware-backed credential storage.
|
||||
|
||||
The U2F protocol however cannot be trivially used as an SSH protocol key
|
||||
type as both the inputs to the signature operation and the resultant
|
||||
signature differ from those specified for SSH. For similar reasons,
|
||||
integration of U2F devices cannot be achieved via the PKCS#11 API.
|
||||
|
||||
U2F also offers a number of features that are attractive in the context
|
||||
of SSH authentication. They can be configured to require indication
|
||||
of "user presence" for each signature operation (typically achieved
|
||||
by requiring the user touch the key). They also offer an attestation
|
||||
mechanism at key enrollment time that can be used to prove that a
|
||||
given key is backed by hardware. Finally the signature format includes
|
||||
a monotonic signature counter that can be used (at scale) to detect
|
||||
concurrent use of a private key, should it be extracted from hardware.
|
||||
|
||||
U2F private keys are generated through an enrollment operation,
|
||||
which takes an application ID - a URL-like string, typically "ssh:"
|
||||
in this case, but a HTTP origin for the case of web authentication,
|
||||
and a challenge string (typically randomly generated). The enrollment
|
||||
operation returns a public key, a key handle that must be used to invoke
|
||||
the hardware-backed private key, some flags and signed attestation
|
||||
information that may be used to verify that a private key is hosted on a
|
||||
particular hardware instance.
|
||||
|
||||
It is common for U2F hardware to derive private keys from the key handle
|
||||
in conjunction with a small per-device secret that is unique to the
|
||||
hardware, thus requiring little on-device storage for an effectively
|
||||
unlimited number of supported keys. This drives the requirement that
|
||||
the key handle be supplied for each signature operation. U2F tokens
|
||||
primarily use ECDSA signatures in the NIST-P256 field, though the FIDO2
|
||||
standard specifies additional key types, including one based on Ed25519.
|
||||
|
||||
Use of U2F security keys does not automatically imply multi-factor
|
||||
authentication. From sshd's perspective, a security key constitutes a
|
||||
single factor of authentication, even if protected by a PIN or biometric
|
||||
authentication. To enable multi-factor authentication in ssh, please
|
||||
refer to the AuthenticationMethods option in sshd_config(5).
|
||||
|
||||
|
||||
SSH U2F Key formats
|
||||
-------------------
|
||||
|
||||
OpenSSH integrates U2F as new key and corresponding certificate types:
|
||||
|
||||
sk-ecdsa-sha2-nistp256@openssh.com
|
||||
sk-ecdsa-sha2-nistp256-cert-v01@openssh.com
|
||||
sk-ssh-ed25519@openssh.com
|
||||
sk-ssh-ed25519-cert-v01@openssh.com
|
||||
|
||||
While each uses ecdsa-sha256-nistp256 as the underlying signature primitive,
|
||||
keys require extra information in the public and private keys, and in
|
||||
the signature object itself. As such they cannot be made compatible with
|
||||
the existing ecdsa-sha2-nistp* key types.
|
||||
|
||||
The format of a sk-ecdsa-sha2-nistp256@openssh.com public key is:
|
||||
|
||||
string "sk-ecdsa-sha2-nistp256@openssh.com"
|
||||
string curve name
|
||||
ec_point Q
|
||||
string application (user-specified, but typically "ssh:")
|
||||
|
||||
The corresponding private key contains:
|
||||
|
||||
string "sk-ecdsa-sha2-nistp256@openssh.com"
|
||||
string curve name
|
||||
ec_point Q
|
||||
string application (user-specified, but typically "ssh:")
|
||||
uint8 flags
|
||||
string key_handle
|
||||
string reserved
|
||||
|
||||
The format of a sk-ssh-ed25519@openssh.com public key is:
|
||||
|
||||
string "sk-ssh-ed25519@openssh.com"
|
||||
string public key
|
||||
string application (user-specified, but typically "ssh:")
|
||||
|
||||
With a private half consisting of:
|
||||
|
||||
string "sk-ssh-ed25519@openssh.com"
|
||||
string public key
|
||||
string application (user-specified, but typically "ssh:")
|
||||
uint8 flags
|
||||
string key_handle
|
||||
string reserved
|
||||
|
||||
The certificate form for SSH U2F keys appends the usual certificate
|
||||
information to the public key:
|
||||
|
||||
string "sk-ecdsa-sha2-nistp256-cert-v01@openssh.com"
|
||||
string nonce
|
||||
string curve name
|
||||
ec_point Q
|
||||
string application
|
||||
uint64 serial
|
||||
uint32 type
|
||||
string key id
|
||||
string valid principals
|
||||
uint64 valid after
|
||||
uint64 valid before
|
||||
string critical options
|
||||
string extensions
|
||||
string reserved
|
||||
string signature key
|
||||
string signature
|
||||
|
||||
and for security key ed25519 certificates:
|
||||
|
||||
string "sk-ssh-ed25519-cert-v01@openssh.com"
|
||||
string nonce
|
||||
string public key
|
||||
string application
|
||||
uint64 serial
|
||||
uint32 type
|
||||
string key id
|
||||
string valid principals
|
||||
uint64 valid after
|
||||
uint64 valid before
|
||||
string critical options
|
||||
string extensions
|
||||
string reserved
|
||||
string signature key
|
||||
string signature
|
||||
|
||||
Both security key certificates use the following encoding for private keys:
|
||||
|
||||
string type (e.g. "sk-ssh-ed25519-cert-v01@openssh.com")
|
||||
string pubkey (the above key/cert structure)
|
||||
string application
|
||||
uint8 flags
|
||||
string key_handle
|
||||
string reserved
|
||||
|
||||
During key generation, the hardware also returns attestation information
|
||||
that may be used to cryptographically prove that a given key is
|
||||
hardware-backed. Unfortunately, the protocol required for this proof is
|
||||
not privacy-preserving and may be used to identify U2F tokens with at
|
||||
least manufacturer and batch number granularity. For this reason, we
|
||||
choose not to include this information in the public key or save it by
|
||||
default.
|
||||
|
||||
Attestation information is useful for out-of-band key and certificate
|
||||
registration workflows, e.g. proving to a CA that a key is backed
|
||||
by trusted hardware before it will issue a certificate. To support this
|
||||
case, OpenSSH optionally allows retaining the attestation information
|
||||
at the time of key generation. It will take the following format:
|
||||
|
||||
string "ssh-sk-attest-v01"
|
||||
string attestation certificate
|
||||
string enrollment signature
|
||||
string authenticator data (CBOR encoded)
|
||||
uint32 reserved flags
|
||||
string reserved string
|
||||
|
||||
A previous version of this format, emitted prior to OpenSSH 8.4 omitted
|
||||
the authenticator data.
|
||||
|
||||
string "ssh-sk-attest-v00"
|
||||
string attestation certificate
|
||||
string enrollment signature
|
||||
uint32 reserved flags
|
||||
string reserved string
|
||||
|
||||
OpenSSH treats the attestation certificate and enrollment signatures as
|
||||
opaque objects and does no interpretation of them itself.
|
||||
|
||||
SSH U2F signatures
|
||||
------------------
|
||||
|
||||
In addition to the message to be signed, the U2F signature operation
|
||||
requires the key handle and a few additional parameters. The signature
|
||||
is signed over a blob that consists of:
|
||||
|
||||
byte[32] SHA256(application)
|
||||
byte flags (including "user present", extensions present)
|
||||
uint32 counter
|
||||
byte[] extensions
|
||||
byte[32] SHA256(message)
|
||||
|
||||
No extensions are yet defined for SSH use. If any are defined in the future,
|
||||
it will be possible to infer their presence from the contents of the "flags"
|
||||
value.
|
||||
|
||||
The signature returned from U2F hardware takes the following format:
|
||||
|
||||
byte flags (including "user present")
|
||||
uint32 counter
|
||||
byte[] ecdsa_signature (in X9.62 format).
|
||||
|
||||
For use in the SSH protocol, we wish to avoid server-side parsing of ASN.1
|
||||
format data in the pre-authentication attack surface. Therefore, the
|
||||
signature format used on the wire in SSH2_USERAUTH_REQUEST packets will
|
||||
be reformatted to better match the existing signature encoding:
|
||||
|
||||
string "sk-ecdsa-sha2-nistp256@openssh.com"
|
||||
string ecdsa_signature
|
||||
byte flags
|
||||
uint32 counter
|
||||
|
||||
Where the "ecdsa_signature" field follows the RFC5656 ECDSA signature
|
||||
encoding:
|
||||
|
||||
mpint r
|
||||
mpint s
|
||||
|
||||
For Ed25519 keys the signature is encoded as:
|
||||
|
||||
string "sk-ssh-ed25519@openssh.com"
|
||||
string signature
|
||||
byte flags
|
||||
uint32 counter
|
||||
|
||||
webauthn signatures
|
||||
-------------------
|
||||
|
||||
The W3C/FIDO webauthn[1] standard defines a mechanism for a web browser to
|
||||
interact with FIDO authentication tokens. This standard builds upon the
|
||||
FIDO standards, but requires different signature contents to raw FIDO
|
||||
messages. OpenSSH supports ECDSA/p256 webauthn signatures through the
|
||||
"webauthn-sk-ecdsa-sha2-nistp256@openssh.com" signature algorithm.
|
||||
|
||||
The wire encoding for a webauthn-sk-ecdsa-sha2-nistp256@openssh.com
|
||||
signature is similar to the sk-ecdsa-sha2-nistp256@openssh.com format:
|
||||
|
||||
string "webauthn-sk-ecdsa-sha2-nistp256@openssh.com"
|
||||
string ecdsa_signature
|
||||
byte flags
|
||||
uint32 counter
|
||||
string origin
|
||||
string clientData
|
||||
string extensions
|
||||
|
||||
Where "origin" is the HTTP origin making the signature, "clientData" is
|
||||
the JSON-like structure signed by the browser and "extensions" are any
|
||||
extensions used in making the signature.
|
||||
|
||||
[1] https://www.w3.org/TR/webauthn-2/
|
||||
|
||||
ssh-agent protocol extensions
|
||||
-----------------------------
|
||||
|
||||
ssh-agent requires a protocol extension to support U2F keys. At
|
||||
present the closest analogue to Security Keys in ssh-agent are PKCS#11
|
||||
tokens, insofar as they require a middleware library to communicate with
|
||||
the device that holds the keys. Unfortunately, the protocol message used
|
||||
to add PKCS#11 keys to ssh-agent does not include any way to send the
|
||||
key handle to the agent as U2F keys require.
|
||||
|
||||
To avoid this, without having to add wholly new messages to the agent
|
||||
protocol, we will use the existing SSH2_AGENTC_ADD_ID_CONSTRAINED message
|
||||
with a new key constraint extension to encode a path to the middleware
|
||||
library for the key. The format of this constraint extension would be:
|
||||
|
||||
byte SSH_AGENT_CONSTRAIN_EXTENSION
|
||||
string sk-provider@openssh.com
|
||||
string middleware path
|
||||
|
||||
This constraint-based approach does not present any compatibility
|
||||
problems.
|
||||
|
||||
OpenSSH integration
|
||||
-------------------
|
||||
|
||||
U2F tokens may be attached via a number of means, including USB and NFC.
|
||||
The USB interface is standardised around a HID protocol, but we want to
|
||||
be able to support other transports as well as dummy implementations for
|
||||
regress testing. For this reason, OpenSSH shall support a dynamically-
|
||||
loaded middleware libraries to communicate with security keys, but offer
|
||||
support for the common case of USB HID security keys internally.
|
||||
|
||||
The middleware library need only expose a handful of functions and
|
||||
numbers listed in sk-api.h. Included in the defined numbers is a
|
||||
SSH_SK_VERSION_MAJOR that should be incremented for each incompatible
|
||||
API change.
|
||||
|
||||
miscellaneous options may be passed to the middleware as a NULL-
|
||||
terminated array of pointers to struct sk_option. The middleware may
|
||||
ignore unsupported or unknown options unless the "required" flag is set,
|
||||
in which case it should return failure if an unsupported option is
|
||||
requested.
|
||||
|
||||
At present the following options names are supported:
|
||||
|
||||
"device"
|
||||
|
||||
Specifies a specific FIDO device on which to perform the
|
||||
operation. The value in this field is interpreted by the
|
||||
middleware but it would be typical to specify a path to
|
||||
a /dev node for the device in question.
|
||||
|
||||
"user"
|
||||
|
||||
Specifies the FIDO2 username used when enrolling a key,
|
||||
overriding OpenSSH's default of using an all-zero username.
|
||||
|
||||
In OpenSSH, the middleware will be invoked by using a similar mechanism to
|
||||
ssh-pkcs11-helper to provide address-space containment of the
|
||||
middleware from ssh-agent.
|
||||
|
||||
$OpenBSD: PROTOCOL.u2f,v 1.26 2020/09/09 03:08:01 djm Exp $
|
49
README
Normal file
49
README
Normal file
|
@ -0,0 +1,49 @@
|
|||
See https://www.openssh.com/releasenotes.html#10.0p1 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.
|
||||
|
||||
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 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
|
||||
functions that are (regrettably) absent from other unices. This port
|
||||
has been best tested on AIX, Cygwin, HP-UX, Linux, MacOS/X,
|
||||
FreeBSD, NetBSD, OpenBSD, OpenServer, Solaris and UnixWare.
|
||||
|
||||
This version actively tracks changes in the OpenBSD CVS repository.
|
||||
|
||||
There is now several mailing lists for this port of OpenSSH. Please
|
||||
refer to https://www.openssh.com/list.html for details on how to join.
|
||||
|
||||
Please send bug reports and patches to https://bugzilla.mindrot.org or
|
||||
the mailing list openssh-unix-dev@mindrot.org. To mitigate spam, the
|
||||
list only allows posting from subscribed addresses. Code contribution
|
||||
are welcomed, but please follow the OpenBSD style guidelines[1].
|
||||
|
||||
Please refer to the INSTALL document for information on dependencies and
|
||||
how to install OpenSSH on your system.
|
||||
|
||||
Damien Miller <djm@mindrot.org>
|
||||
|
||||
Miscellania -
|
||||
|
||||
This version of OpenSSH is based upon code retrieved from the OpenBSD CVS
|
||||
repository which in turn was based on the last free sample implementation
|
||||
released by Tatu Ylonen.
|
||||
|
||||
References -
|
||||
|
||||
[0] https://www.openssh.com/
|
||||
[1] https://man.openbsd.org/style.9
|
||||
|
47
README.dns
Normal file
47
README.dns
Normal file
|
@ -0,0 +1,47 @@
|
|||
How to verify host keys using OpenSSH and DNS
|
||||
---------------------------------------------
|
||||
|
||||
OpenSSH contains support for verifying host keys using DNS as described
|
||||
in https://tools.ietf.org/html/rfc4255. The document contains very brief
|
||||
instructions on how to use this feature. Configuring DNS is out of the
|
||||
scope of this document.
|
||||
|
||||
|
||||
(1) Server: Generate and publish the DNS RR
|
||||
|
||||
To create a DNS resource record (RR) containing a fingerprint of the
|
||||
public host key, use the following command:
|
||||
|
||||
ssh-keygen -r hostname -f keyfile -g
|
||||
|
||||
where "hostname" is your fully qualified hostname and "keyfile" is the
|
||||
file containing the public host key file. If you have multiple keys,
|
||||
you should generate one RR for each key.
|
||||
|
||||
In the example above, ssh-keygen will print the fingerprint in a
|
||||
generic DNS RR format parsable by most modern name server
|
||||
implementations. If your nameserver has support for the SSHFP RR
|
||||
you can omit the -g flag and ssh-keygen will print a standard SSHFP RR.
|
||||
|
||||
To publish the fingerprint using the DNS you must add the generated RR
|
||||
to your DNS zone file and sign your zone.
|
||||
|
||||
|
||||
(2) Client: Enable ssh to verify host keys using DNS
|
||||
|
||||
To enable the ssh client to verify host keys using DNS, you have to
|
||||
add the following option to the ssh configuration file
|
||||
($HOME/.ssh/config or /etc/ssh/ssh_config):
|
||||
|
||||
VerifyHostKeyDNS yes
|
||||
|
||||
Upon connection the client will try to look up the fingerprint RR
|
||||
using DNS. If the fingerprint received from the DNS server matches
|
||||
the remote host key, the user will be notified.
|
||||
|
||||
|
||||
Jakob Schlyter
|
||||
Wesley Griffin
|
||||
|
||||
|
||||
$OpenBSD: README.dns,v 1.2 2003/10/14 19:43:23 jakob Exp $
|
86
README.md
Normal file
86
README.md
Normal file
|
@ -0,0 +1,86 @@
|
|||
# Portable OpenSSH
|
||||
|
||||
[](https://github.com/openssh/openssh-portable/actions/workflows/c-cpp.yml)
|
||||
[](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:openssh)
|
||||
[](https://scan.coverity.com/projects/openssh-portable)
|
||||
|
||||
OpenSSH is a complete implementation of the SSH protocol (version 2) for secure remote login, command execution and file transfer. It includes a client ``ssh`` and server ``sshd``, file transfer utilities ``scp`` and ``sftp`` as well as tools for key generation (``ssh-keygen``), run-time key storage (``ssh-agent``) and a number of supporting programs.
|
||||
|
||||
This is a port of OpenBSD's [OpenSSH](https://openssh.com) to most Unix-like operating systems, including Linux, OS X and Cygwin. Portable OpenSSH polyfills OpenBSD APIs that are not available elsewhere, adds sshd sandboxing for more operating systems and includes support for OS-native authentication and auditing (e.g. using PAM).
|
||||
|
||||
## Documentation
|
||||
|
||||
The official documentation for OpenSSH are the man pages for each tool:
|
||||
|
||||
* [ssh(1)](https://man.openbsd.org/ssh.1)
|
||||
* [sshd(8)](https://man.openbsd.org/sshd.8)
|
||||
* [ssh-keygen(1)](https://man.openbsd.org/ssh-keygen.1)
|
||||
* [ssh-agent(1)](https://man.openbsd.org/ssh-agent.1)
|
||||
* [scp(1)](https://man.openbsd.org/scp.1)
|
||||
* [sftp(1)](https://man.openbsd.org/sftp.1)
|
||||
* [ssh-keyscan(8)](https://man.openbsd.org/ssh-keyscan.8)
|
||||
* [sftp-server(8)](https://man.openbsd.org/sftp-server.8)
|
||||
|
||||
## Stable Releases
|
||||
|
||||
Stable release tarballs are available from a number of [download mirrors](https://www.openssh.com/portable.html#downloads). We recommend the use of a stable release for most users. Please read the [release notes](https://www.openssh.com/releasenotes.html) for details of recent changes and potential incompatibilities.
|
||||
|
||||
## Building Portable OpenSSH
|
||||
|
||||
### Dependencies
|
||||
|
||||
Portable OpenSSH is built using autoconf and make. It requires a working C compiler, standard library and headers.
|
||||
|
||||
``libcrypto`` from either [LibreSSL](https://www.libressl.org/) or [OpenSSL](https://www.openssl.org) may also be used. OpenSSH may be built without either of these, but the resulting binaries will have only a subset of the cryptographic algorithms normally available.
|
||||
|
||||
[zlib](https://www.zlib.net/) is optional; without it transport compression is not supported.
|
||||
|
||||
FIDO security token support needs [libfido2](https://github.com/Yubico/libfido2) and its dependencies and will be enabled automatically if they are found.
|
||||
|
||||
In addition, certain platforms and build-time options may require additional dependencies; see README.platform for details about your platform.
|
||||
|
||||
### Building a release
|
||||
|
||||
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
|
||||
cd openssh
|
||||
./configure # [options]
|
||||
make && make tests
|
||||
```
|
||||
|
||||
See the [Build-time Customisation](#build-time-customisation) section below for configure options. If you plan on installing OpenSSH to your system, then you will usually want to specify destination paths.
|
||||
|
||||
### Building from git
|
||||
|
||||
If building from 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
|
||||
cd openssh-portable
|
||||
autoreconf
|
||||
./configure
|
||||
make && make tests
|
||||
```
|
||||
|
||||
### Build-time Customisation
|
||||
|
||||
There are many build-time customisation options available. All Autoconf destination path flags (e.g. ``--prefix``) are supported (and are usually required if you want to install OpenSSH).
|
||||
|
||||
For a full list of available flags, run ``./configure --help`` but a few of the more frequently-used ones are described below. Some of these flags will require additional libraries and/or headers be installed.
|
||||
|
||||
Flag | Meaning
|
||||
--- | ---
|
||||
``--with-pam`` | Enable [PAM](https://en.wikipedia.org/wiki/Pluggable_authentication_module) support. [OpenPAM](https://www.openpam.org/), [Linux PAM](http://www.linux-pam.org/) and Solaris PAM are supported.
|
||||
``--with-libedit`` | Enable [libedit](https://www.thrysoee.dk/editline/) support for sftp.
|
||||
``--with-kerberos5`` | Enable Kerberos/GSSAPI support. Both [Heimdal](https://www.h5l.org/) and [MIT](https://web.mit.edu/kerberos/) Kerberos implementations are supported.
|
||||
``--with-selinux`` | Enable [SELinux](https://en.wikipedia.org/wiki/Security-Enhanced_Linux) support.
|
||||
|
||||
## Development
|
||||
|
||||
Portable OpenSSH development is discussed on the [openssh-unix-dev mailing list](https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev) ([archive mirror](https://marc.info/?l=openssh-unix-dev)). Bugs and feature requests are tracked on our [Bugzilla](https://bugzilla.mindrot.org/).
|
||||
|
||||
## Reporting bugs
|
||||
|
||||
_Non-security_ bugs may be reported to the developers via [Bugzilla](https://bugzilla.mindrot.org/) or via the mailing list above. Security bugs should be reported to [openssh@openssh.com](mailto:openssh.openssh.com).
|
97
README.platform
Normal file
97
README.platform
Normal file
|
@ -0,0 +1,97 @@
|
|||
This file contains notes about OpenSSH on specific platforms.
|
||||
|
||||
AIX
|
||||
|
||||
Beginning with OpenSSH 3.8p1, sshd will honour an account's password
|
||||
expiry settings, where prior to that it did not. Because of this,
|
||||
it's possible for sites that have used OpenSSH's sshd exclusively to
|
||||
have accounts which have passwords expired longer than the inactive time
|
||||
(ie the "Weeks between password EXPIRATION and LOCKOUT" setting in SMIT
|
||||
or the maxexpired chuser attribute).
|
||||
|
||||
Accounts in this state must have their passwords reset manually by the
|
||||
administrator. As a precaution, it is recommended that the administrative
|
||||
passwords be reset before upgrading from OpenSSH <3.8.
|
||||
|
||||
As of OpenSSH 4.0p1, configure will attempt to detect if your version
|
||||
and maintenance level of AIX has a working getaddrinfo, and will use it
|
||||
if found. This will enable IPv6 support. If for some reason configure
|
||||
gets it wrong, or if you want to build binaries to work on earlier MLs
|
||||
than the build host then you can add "-DBROKEN_GETADDRINFO" to CFLAGS
|
||||
to force the previous IPv4-only behaviour.
|
||||
|
||||
IPv6 known to work: 5.1ML7 5.2ML2 5.2ML5
|
||||
IPv6 known broken: 4.3.3ML11 5.1ML4
|
||||
|
||||
If you wish to use dynamic libraries that aren't in the normal system
|
||||
locations (eg IBM's OpenSSL and zlib packages) then you will need to
|
||||
define the environment variable blibpath before running configure, eg
|
||||
|
||||
blibpath=/lib:/usr/lib:/opt/freeware/lib ./configure \
|
||||
--with-ssl-dir=/opt/freeware --with-zlib=/opt/freeware
|
||||
|
||||
If sshd is built with the WITH_AIXAUTHENTICATE option (which is enabled
|
||||
by default) then sshd checks that users are permitted via the
|
||||
loginrestrictions() function, in particular that the user has the
|
||||
"rlogin" attribute set. This check is not done for the root account,
|
||||
instead the PermitRootLogin setting in sshd_config is used.
|
||||
|
||||
If you are using the IBM compiler you probably want to use CC=xlc rather
|
||||
than the default of cc.
|
||||
|
||||
|
||||
Cygwin
|
||||
------
|
||||
To build on Cygwin, OpenSSH requires the following packages:
|
||||
gcc, gcc-mingw-core, mingw-runtime, binutils, make, openssl,
|
||||
openssl-devel, zlib, minres, minires-devel.
|
||||
|
||||
|
||||
Darwin and MacOS X
|
||||
------------------
|
||||
Darwin does not provide a tun(4) driver required for OpenSSH-based
|
||||
virtual private networks. The BSD manpage still exists, but the driver
|
||||
has been removed in recent releases of Darwin and MacOS X.
|
||||
|
||||
Tunnel support is known to work with Darwin 8 and MacOS X 10.4 in
|
||||
Point-to-Point (Layer 3) and Ethernet (Layer 2) mode using a third
|
||||
party driver. More information is available at:
|
||||
https://tuntaposx.sourceforge.net
|
||||
|
||||
Recent Darwin/MacOS X versions are likely unsupported.
|
||||
|
||||
Linux
|
||||
-----
|
||||
|
||||
Some Linux distributions (including Red Hat/Fedora/CentOS) include
|
||||
headers and library links in the -devel RPMs rather than the main
|
||||
binary RPMs. If you get an error about headers, or complaining about a
|
||||
missing prerequisite then you may need to install the equivalent
|
||||
development packages. On Redhat based distros these may be openssl-devel,
|
||||
zlib-devel and pam-devel, on Debian based distros these may be
|
||||
libssl-dev, libz-dev and libpam-dev.
|
||||
|
||||
|
||||
Solaris
|
||||
-------
|
||||
If you enable BSM auditing on Solaris, you need to update audit_event(4)
|
||||
for praudit(1m) to give sensible output. The following line needs to be
|
||||
added to /etc/security/audit_event:
|
||||
|
||||
32800:AUE_openssh:OpenSSH login:lo
|
||||
|
||||
The BSM audit event range available for third party TCB applications is
|
||||
32768 - 65535. Event number 32800 has been chosen for AUE_openssh.
|
||||
There is no official registry of 3rd party event numbers, so if this
|
||||
number is already in use on your system, you may change it at build time
|
||||
by configure'ing --with-cflags=-DAUE_openssh=32801 then rebuilding.
|
||||
|
||||
|
||||
Platforms using PAM
|
||||
-------------------
|
||||
As of OpenSSH 4.3p1, sshd will no longer check /etc/nologin itself when
|
||||
PAM is enabled. To maintain existing behaviour, pam_nologin should be
|
||||
added to sshd's session stack which will prevent users from starting shell
|
||||
sessions. Alternatively, pam_nologin can be added to either the auth or
|
||||
account stacks which will prevent authentication entirely, but will still
|
||||
return the output from pam_nologin to the client.
|
51
README.privsep
Normal file
51
README.privsep
Normal file
|
@ -0,0 +1,51 @@
|
|||
Privilege separation, or privsep, is method in OpenSSH by which
|
||||
operations that require root privilege are performed by a separate
|
||||
privileged monitor process. Its purpose is to prevent privilege
|
||||
escalation by containing corruption to an unprivileged process.
|
||||
More information is available at:
|
||||
http://www.citi.umich.edu/u/provos/ssh/privsep.html
|
||||
|
||||
Privilege separation is now mandatory. During the pre-authentication
|
||||
phase sshd will chroot(2) to "/var/empty" and change its privileges to the
|
||||
"sshd" user and its primary group. sshd is a pseudo-account that should
|
||||
not be used by other daemons, and must be locked and should contain a
|
||||
"nologin" or invalid shell.
|
||||
|
||||
You should do something like the following to prepare the privsep
|
||||
preauth environment:
|
||||
|
||||
# mkdir /var/empty
|
||||
# chown root:sys /var/empty
|
||||
# chmod 755 /var/empty
|
||||
# groupadd sshd
|
||||
# useradd -g sshd -c 'sshd privsep' -d /var/empty -s /bin/false sshd
|
||||
|
||||
/var/empty should not contain any files.
|
||||
|
||||
configure supports the following options to change the default
|
||||
privsep user and chroot directory:
|
||||
|
||||
--with-privsep-path=xxx Path for privilege separation chroot
|
||||
--with-privsep-user=user Specify non-privileged user for privilege separation
|
||||
|
||||
PAM-enabled OpenSSH is known to function with privsep on AIX, FreeBSD,
|
||||
HP-UX (including Trusted Mode), Linux, NetBSD and Solaris.
|
||||
|
||||
On Cygwin, Tru64 Unix and OpenServer only the pre-authentication part
|
||||
of privsep is supported. Post-authentication privsep is disabled
|
||||
automatically (so you won't see the additional process mentioned below).
|
||||
|
||||
Note that for a normal interactive login with a shell, enabling privsep
|
||||
will require 1 additional process per login session.
|
||||
|
||||
Given the following process listing (from HP-UX):
|
||||
|
||||
UID PID PPID C STIME TTY TIME COMMAND
|
||||
root 1005 1 0 10:45:17 ? 0:08 /opt/openssh/sbin/sshd -u0
|
||||
root 6917 1005 0 15:19:16 ? 0:00 sshd: stevesk [priv]
|
||||
stevesk 6919 6917 0 15:19:17 ? 0:03 sshd: stevesk@2
|
||||
stevesk 6921 6919 0 15:19:17 pts/2 0:00 -bash
|
||||
|
||||
process 1005 is the sshd process listening for new connections.
|
||||
process 6917 is the privileged monitor process, 6919 is the user owned
|
||||
sshd process and 6921 is the shell process.
|
132
README.tun
Normal file
132
README.tun
Normal file
|
@ -0,0 +1,132 @@
|
|||
How to use OpenSSH-based virtual private networks
|
||||
-------------------------------------------------
|
||||
|
||||
OpenSSH contains support for VPN tunneling using the tun(4) network
|
||||
tunnel pseudo-device which is available on most platforms, either for
|
||||
layer 2 or 3 traffic.
|
||||
|
||||
The following brief instructions on how to use this feature use
|
||||
a network configuration specific to the OpenBSD operating system.
|
||||
|
||||
(1) Server: Enable support for SSH tunneling
|
||||
|
||||
To enable the ssh server to accept tunnel requests from the client, you
|
||||
have to add the following option to the ssh server configuration file
|
||||
(/etc/ssh/sshd_config):
|
||||
|
||||
PermitTunnel yes
|
||||
|
||||
Restart the server or send the hangup signal (SIGHUP) to let the server
|
||||
reread it's configuration.
|
||||
|
||||
(2) Server: Restrict client access and assign the tunnel
|
||||
|
||||
The OpenSSH server simply uses the file /root/.ssh/authorized_keys to
|
||||
restrict the client to connect to a specified tunnel and to
|
||||
automatically start the related interface configuration command. These
|
||||
settings are optional but recommended:
|
||||
|
||||
tunnel="1",command="sh /etc/netstart tun1" ssh-rsa ... reyk@openbsd.org
|
||||
|
||||
(3) Client: Configure the local network tunnel interface
|
||||
|
||||
Use the hostname.if(5) interface-specific configuration file to set up
|
||||
the network tunnel configuration with OpenBSD. For example, use the
|
||||
following configuration in /etc/hostname.tun0 to set up the layer 3
|
||||
tunnel on the client:
|
||||
|
||||
inet 192.168.5.1 255.255.255.252 192.168.5.2
|
||||
|
||||
OpenBSD also supports layer 2 tunneling over the tun device by adding
|
||||
the link0 flag:
|
||||
|
||||
inet 192.168.1.78 255.255.255.0 192.168.1.255 link0
|
||||
|
||||
Layer 2 tunnels can be used in combination with an Ethernet bridge(4)
|
||||
interface, like the following example for /etc/bridgename.bridge0:
|
||||
|
||||
add tun0
|
||||
add sis0
|
||||
up
|
||||
|
||||
(4) Client: Configure the OpenSSH client
|
||||
|
||||
To establish tunnel forwarding for connections to a specified
|
||||
remote host by default, use the following ssh client configuration for
|
||||
the privileged user (in /root/.ssh/config):
|
||||
|
||||
Host sshgateway
|
||||
Tunnel yes
|
||||
TunnelDevice 0:any
|
||||
PermitLocalCommand yes
|
||||
LocalCommand sh /etc/netstart tun0
|
||||
|
||||
A more complicated configuration is possible to establish a tunnel to
|
||||
a remote host which is not directly accessible by the client.
|
||||
The following example describes a client configuration to connect to
|
||||
the remote host over two ssh hops in between. It uses the OpenSSH
|
||||
ProxyCommand in combination with the nc(1) program to forward the final
|
||||
ssh tunnel destination over multiple ssh sessions.
|
||||
|
||||
Host access.somewhere.net
|
||||
User puffy
|
||||
Host dmzgw
|
||||
User puffy
|
||||
ProxyCommand ssh access.somewhere.net nc dmzgw 22
|
||||
Host sshgateway
|
||||
Tunnel Ethernet
|
||||
TunnelDevice 0:any
|
||||
PermitLocalCommand yes
|
||||
LocalCommand sh /etc/netstart tun0
|
||||
ProxyCommand ssh dmzgw nc sshgateway 22
|
||||
|
||||
The following network plan illustrates the previous configuration in
|
||||
combination with layer 2 tunneling and Ethernet bridging.
|
||||
|
||||
+--------+ ( ) +----------------------+
|
||||
| Client |------( Internet )-----| access.somewhere.net |
|
||||
+--------+ ( ) +----------------------+
|
||||
: 192.168.1.78 |
|
||||
:............................. +-------+
|
||||
Forwarded ssh connection : | dmzgw |
|
||||
Layer 2 tunnel : +-------+
|
||||
: |
|
||||
: |
|
||||
: +------------+
|
||||
:......| sshgateway |
|
||||
| +------------+
|
||||
--- real connection Bridge -> | +----------+
|
||||
... "virtual connection" [ X ]--------| somehost |
|
||||
[X] switch +----------+
|
||||
192.168.1.25
|
||||
|
||||
(5) Client: Connect to the server and establish the tunnel
|
||||
|
||||
Finally connect to the OpenSSH server to establish the tunnel by using
|
||||
the following command:
|
||||
|
||||
ssh sshgateway
|
||||
|
||||
It is also possible to tell the client to fork into the background after
|
||||
the connection has been successfully established:
|
||||
|
||||
ssh -f sshgateway true
|
||||
|
||||
Without the ssh configuration done in step (4), it is also possible
|
||||
to use the following command lines:
|
||||
|
||||
ssh -fw 0:1 sshgateway true
|
||||
ifconfig tun0 192.168.5.1 192.168.5.2 netmask 255.255.255.252
|
||||
|
||||
Using OpenSSH tunnel forwarding is a simple way to establish secure
|
||||
and ad hoc virtual private networks. Possible fields of application
|
||||
could be wireless networks or administrative VPN tunnels.
|
||||
|
||||
Nevertheless, ssh tunneling requires some packet header overhead and
|
||||
runs on top of TCP. It is still suggested to use the IP Security
|
||||
Protocol (IPSec) for robust and permanent VPN connections and to
|
||||
interconnect corporate networks.
|
||||
|
||||
Reyk Floeter
|
||||
|
||||
$OpenBSD: README.tun,v 1.4 2006/03/28 00:12:31 deraadt Exp $
|
5
SECURITY.md
Normal file
5
SECURITY.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
# Reporting OpenSSH Security Issues
|
||||
|
||||
To report security issues in OpenSSH, please refer to our website
|
||||
[OpenSSH Security](https://www.openssh.com/security.html).
|
||||
|
80
TODO
Normal file
80
TODO
Normal file
|
@ -0,0 +1,80 @@
|
|||
Documentation:
|
||||
|
||||
- Update the docs
|
||||
- Update README
|
||||
- Update INSTALL
|
||||
- Merge INSTALL & README.privsep
|
||||
|
||||
- Install FAQ?
|
||||
|
||||
- General FAQ on S/Key, TIS, RSA, RSA2, DSA, etc and suggestions on when it
|
||||
would be best to use them.
|
||||
|
||||
- Create a Documentation/ directory?
|
||||
|
||||
Programming:
|
||||
|
||||
- Grep for 'XXX' comments and fix
|
||||
|
||||
- Link order is incorrect for some systems using Kerberos 4 and AFS. Result
|
||||
is multiple inclusion of DES symbols. Holger Trapp
|
||||
<holger.trapp@hrz.tu-chemnitz.de> reports that changing the configure
|
||||
generated link order from:
|
||||
-lresolv -lkrb -lz -lnsl -lutil -lkafs -lkrb -ldes -lcrypto
|
||||
to:
|
||||
-lresolv -lkrb -lz -lnsl -lutil -lcrypto -lkafs -lkrb -ldes
|
||||
fixing the problem.
|
||||
|
||||
- Write a test program that calls stat() to search for EGD/PRNGd socket
|
||||
rather than use the (non-portable) "test -S".
|
||||
|
||||
- More platforms for for setproctitle() emulation (testing needed)
|
||||
|
||||
- Improve PAM ChallengeResponseAuthentication
|
||||
- Informational messages
|
||||
- Use different PAM service name for kbdint vs regular auth (suggest from
|
||||
Solar Designer)
|
||||
- Ability to select which ChallengeResponseAuthentications may be used
|
||||
and order to try them in e.g. "ChallengeResponseAuthentication pam"
|
||||
|
||||
- Complete Tru64 SIA support
|
||||
- It looks like we could merge it into the password auth code to cut down
|
||||
on diff size. Maybe PAM password auth too?
|
||||
|
||||
- Finish integrating kernel-level auditing code for IRIX and SOLARIS
|
||||
(Gilbert.r.loomis@saic.com)
|
||||
|
||||
- 64-bit builds on HP-UX 11.X (stevesk@pobox.com):
|
||||
- utmp/wtmp get corrupted (something in loginrec?)
|
||||
- can't build with PAM (no 64-bit libpam yet)
|
||||
|
||||
Clean up configure/makefiles:
|
||||
- Clean up configure.ac - There are a few double #defined variables
|
||||
left to do. HAVE_LOGIN is one of them. Consider NOT looking for
|
||||
information in wtmpx or utmpx or any of that stuff if it's not detected
|
||||
from the start
|
||||
|
||||
- Replace the whole u_intXX_t evilness in acconfig.h with something better???
|
||||
- Do it in configure.ac
|
||||
|
||||
- Consider splitting the u_intXX_t test for sys/bitype.h into separate test
|
||||
to allow people to (right/wrongfully) link against Bind directly.
|
||||
|
||||
- Consider splitting configure.ac into separate files which do logically
|
||||
similar tests. E.g move all the type detection stuff into one file,
|
||||
entropy related stuff into another.
|
||||
|
||||
Packaging:
|
||||
- HP-UX: Provide DEPOT package scripts.
|
||||
(gilbert.r.loomis@saic.com)
|
||||
|
||||
PrivSep Issues:
|
||||
- PAM
|
||||
+ See above PAM notes
|
||||
- AIX
|
||||
+ usrinfo() does not set TTY, but only required for legacy systems. Works
|
||||
with PrivSep.
|
||||
- OSF
|
||||
+ SIA is broken
|
||||
- Cygwin
|
||||
+ Privsep for Pre-auth only (no fd passing)
|
15
aclocal.m4
vendored
Normal file
15
aclocal.m4
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
# generated automatically by aclocal 1.16.5 -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1996-2021 Free Software Foundation, Inc.
|
||||
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
|
||||
m4_include([m4/openssh.m4])
|
510
addr.c
Normal file
510
addr.c
Normal file
|
@ -0,0 +1,510 @@
|
|||
/* $OpenBSD: addr.c,v 1.9 2024/10/18 04:30:09 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2004-2008 Damien Miller <djm@mindrot.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <netdb.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "addr.h"
|
||||
|
||||
#define _SA(x) ((struct sockaddr *)(x))
|
||||
|
||||
static int
|
||||
addr_unicast_masklen(int af)
|
||||
{
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
return 32;
|
||||
case AF_INET6:
|
||||
return 128;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static inline int
|
||||
masklen_valid(int af, u_int masklen)
|
||||
{
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
return masklen <= 32 ? 0 : -1;
|
||||
case AF_INET6:
|
||||
return masklen <= 128 ? 0 : -1;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
addr_xaddr_to_sa(const struct xaddr *xa, struct sockaddr *sa, socklen_t *len,
|
||||
u_int16_t port)
|
||||
{
|
||||
struct sockaddr_in *in4 = (struct sockaddr_in *)sa;
|
||||
struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)sa;
|
||||
|
||||
if (xa == NULL || sa == NULL || len == NULL)
|
||||
return -1;
|
||||
|
||||
switch (xa->af) {
|
||||
case AF_INET:
|
||||
if (*len < sizeof(*in4))
|
||||
return -1;
|
||||
memset(sa, '\0', sizeof(*in4));
|
||||
*len = sizeof(*in4);
|
||||
#ifdef SOCK_HAS_LEN
|
||||
in4->sin_len = sizeof(*in4);
|
||||
#endif
|
||||
in4->sin_family = AF_INET;
|
||||
in4->sin_port = htons(port);
|
||||
memcpy(&in4->sin_addr, &xa->v4, sizeof(in4->sin_addr));
|
||||
break;
|
||||
case AF_INET6:
|
||||
if (*len < sizeof(*in6))
|
||||
return -1;
|
||||
memset(sa, '\0', sizeof(*in6));
|
||||
*len = sizeof(*in6);
|
||||
#ifdef SOCK_HAS_LEN
|
||||
in6->sin6_len = sizeof(*in6);
|
||||
#endif
|
||||
in6->sin6_family = AF_INET6;
|
||||
in6->sin6_port = htons(port);
|
||||
memcpy(&in6->sin6_addr, &xa->v6, sizeof(in6->sin6_addr));
|
||||
#ifdef HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID
|
||||
in6->sin6_scope_id = xa->scope_id;
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert struct sockaddr to struct xaddr
|
||||
* Returns 0 on success, -1 on failure.
|
||||
*/
|
||||
int
|
||||
addr_sa_to_xaddr(struct sockaddr *sa, socklen_t slen, struct xaddr *xa)
|
||||
{
|
||||
struct sockaddr_in *in4 = (struct sockaddr_in *)sa;
|
||||
struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)sa;
|
||||
|
||||
memset(xa, '\0', sizeof(*xa));
|
||||
|
||||
switch (sa->sa_family) {
|
||||
case AF_INET:
|
||||
if (slen < (socklen_t)sizeof(*in4))
|
||||
return -1;
|
||||
xa->af = AF_INET;
|
||||
memcpy(&xa->v4, &in4->sin_addr, sizeof(xa->v4));
|
||||
break;
|
||||
case AF_INET6:
|
||||
if (slen < (socklen_t)sizeof(*in6))
|
||||
return -1;
|
||||
xa->af = AF_INET6;
|
||||
memcpy(&xa->v6, &in6->sin6_addr, sizeof(xa->v6));
|
||||
#ifdef HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID
|
||||
xa->scope_id = in6->sin6_scope_id;
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
addr_invert(struct xaddr *n)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (n == NULL)
|
||||
return -1;
|
||||
|
||||
switch (n->af) {
|
||||
case AF_INET:
|
||||
n->v4.s_addr = ~n->v4.s_addr;
|
||||
return 0;
|
||||
case AF_INET6:
|
||||
for (i = 0; i < 4; i++)
|
||||
n->addr32[i] = ~n->addr32[i];
|
||||
return 0;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate a netmask of length 'l' for address family 'af' and
|
||||
* store it in 'n'.
|
||||
* Returns 0 on success, -1 on failure.
|
||||
*/
|
||||
int
|
||||
addr_netmask(int af, u_int l, struct xaddr *n)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (masklen_valid(af, l) != 0 || n == NULL)
|
||||
return -1;
|
||||
|
||||
memset(n, '\0', sizeof(*n));
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
n->af = AF_INET;
|
||||
if (l == 0)
|
||||
return 0;
|
||||
n->v4.s_addr = htonl((0xffffffff << (32 - l)) & 0xffffffff);
|
||||
return 0;
|
||||
case AF_INET6:
|
||||
n->af = AF_INET6;
|
||||
for (i = 0; i < 4 && l >= 32; i++, l -= 32)
|
||||
n->addr32[i] = 0xffffffffU;
|
||||
if (i < 4 && l != 0)
|
||||
n->addr32[i] = htonl((0xffffffff << (32 - l)) &
|
||||
0xffffffff);
|
||||
return 0;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
addr_hostmask(int af, u_int l, struct xaddr *n)
|
||||
{
|
||||
if (addr_netmask(af, l, n) == -1 || addr_invert(n) == -1)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform logical AND of addresses 'a' and 'b', storing result in 'dst'.
|
||||
* Returns 0 on success, -1 on failure.
|
||||
*/
|
||||
int
|
||||
addr_and(struct xaddr *dst, const struct xaddr *a, const struct xaddr *b)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (dst == NULL || a == NULL || b == NULL || a->af != b->af)
|
||||
return -1;
|
||||
|
||||
memcpy(dst, a, sizeof(*dst));
|
||||
switch (a->af) {
|
||||
case AF_INET:
|
||||
dst->v4.s_addr &= b->v4.s_addr;
|
||||
return 0;
|
||||
case AF_INET6:
|
||||
dst->scope_id = a->scope_id;
|
||||
for (i = 0; i < 4; i++)
|
||||
dst->addr32[i] &= b->addr32[i];
|
||||
return 0;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
addr_or(struct xaddr *dst, const struct xaddr *a, const struct xaddr *b)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (dst == NULL || a == NULL || b == NULL || a->af != b->af)
|
||||
return (-1);
|
||||
|
||||
memcpy(dst, a, sizeof(*dst));
|
||||
switch (a->af) {
|
||||
case AF_INET:
|
||||
dst->v4.s_addr |= b->v4.s_addr;
|
||||
return (0);
|
||||
case AF_INET6:
|
||||
for (i = 0; i < 4; i++)
|
||||
dst->addr32[i] |= b->addr32[i];
|
||||
return (0);
|
||||
default:
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
addr_cmp(const struct xaddr *a, const struct xaddr *b)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (a->af != b->af)
|
||||
return (a->af == AF_INET6 ? 1 : -1);
|
||||
|
||||
switch (a->af) {
|
||||
case AF_INET:
|
||||
/*
|
||||
* Can't just subtract here as 255.255.255.255 - 0.0.0.0 is
|
||||
* too big to fit into a signed int
|
||||
*/
|
||||
if (a->v4.s_addr == b->v4.s_addr)
|
||||
return 0;
|
||||
return (ntohl(a->v4.s_addr) > ntohl(b->v4.s_addr) ? 1 : -1);
|
||||
case AF_INET6:
|
||||
/*
|
||||
* Do this a byte at a time to avoid the above issue and
|
||||
* any endian problems
|
||||
*/
|
||||
for (i = 0; i < 16; i++)
|
||||
if (a->addr8[i] - b->addr8[i] != 0)
|
||||
return (a->addr8[i] - b->addr8[i]);
|
||||
if (a->scope_id == b->scope_id)
|
||||
return (0);
|
||||
return (a->scope_id > b->scope_id ? 1 : -1);
|
||||
default:
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
addr_is_all0s(const struct xaddr *a)
|
||||
{
|
||||
int i;
|
||||
|
||||
switch (a->af) {
|
||||
case AF_INET:
|
||||
return (a->v4.s_addr == 0 ? 0 : -1);
|
||||
case AF_INET6:
|
||||
for (i = 0; i < 4; i++)
|
||||
if (a->addr32[i] != 0)
|
||||
return -1;
|
||||
return 0;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Increment the specified address. Note, does not do overflow checking */
|
||||
void
|
||||
addr_increment(struct xaddr *a)
|
||||
{
|
||||
int i;
|
||||
uint32_t n;
|
||||
|
||||
switch (a->af) {
|
||||
case AF_INET:
|
||||
a->v4.s_addr = htonl(ntohl(a->v4.s_addr) + 1);
|
||||
break;
|
||||
case AF_INET6:
|
||||
for (i = 0; i < 4; i++) {
|
||||
/* Increment with carry */
|
||||
n = ntohl(a->addr32[3 - i]) + 1;
|
||||
a->addr32[3 - i] = htonl(n);
|
||||
if (n != 0)
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Test whether host portion of address 'a', as determined by 'masklen'
|
||||
* is all zeros.
|
||||
* Returns 0 if host portion of address is all-zeros,
|
||||
* -1 if not all zeros or on failure.
|
||||
*/
|
||||
static int
|
||||
addr_host_is_all0s(const struct xaddr *a, u_int masklen)
|
||||
{
|
||||
struct xaddr tmp_addr, tmp_mask, tmp_result;
|
||||
|
||||
memcpy(&tmp_addr, a, sizeof(tmp_addr));
|
||||
if (addr_hostmask(a->af, masklen, &tmp_mask) == -1)
|
||||
return -1;
|
||||
if (addr_and(&tmp_result, &tmp_addr, &tmp_mask) == -1)
|
||||
return -1;
|
||||
return addr_is_all0s(&tmp_result);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static int
|
||||
addr_host_to_all0s(struct xaddr *a, u_int masklen)
|
||||
{
|
||||
struct xaddr tmp_mask;
|
||||
|
||||
if (addr_netmask(a->af, masklen, &tmp_mask) == -1)
|
||||
return (-1);
|
||||
if (addr_and(a, a, &tmp_mask) == -1)
|
||||
return (-1);
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
addr_host_to_all1s(struct xaddr *a, u_int masklen)
|
||||
{
|
||||
struct xaddr tmp_mask;
|
||||
|
||||
if (addr_hostmask(a->af, masklen, &tmp_mask) == -1)
|
||||
return (-1);
|
||||
if (addr_or(a, a, &tmp_mask) == -1)
|
||||
return (-1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse string address 'p' into 'n'.
|
||||
* Returns 0 on success, -1 on failure.
|
||||
*/
|
||||
int
|
||||
addr_pton(const char *p, struct xaddr *n)
|
||||
{
|
||||
struct addrinfo hints, *ai;
|
||||
|
||||
memset(&hints, '\0', sizeof(hints));
|
||||
hints.ai_flags = AI_NUMERICHOST;
|
||||
|
||||
if (p == NULL || getaddrinfo(p, NULL, &hints, &ai) != 0)
|
||||
return -1;
|
||||
|
||||
if (ai == NULL)
|
||||
return -1;
|
||||
|
||||
if (ai->ai_addr == NULL) {
|
||||
freeaddrinfo(ai);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (n != NULL && addr_sa_to_xaddr(ai->ai_addr, ai->ai_addrlen,
|
||||
n) == -1) {
|
||||
freeaddrinfo(ai);
|
||||
return -1;
|
||||
}
|
||||
|
||||
freeaddrinfo(ai);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static int
|
||||
addr_sa_pton(const char *h, const char *s, struct sockaddr *sa, socklen_t slen)
|
||||
{
|
||||
struct addrinfo hints, *ai;
|
||||
|
||||
memset(&hints, '\0', sizeof(hints));
|
||||
hints.ai_flags = AI_NUMERICHOST;
|
||||
|
||||
if (h == NULL || getaddrinfo(h, s, &hints, &ai) != 0)
|
||||
return -1;
|
||||
|
||||
if (ai == NULL)
|
||||
return -1;
|
||||
|
||||
if (ai->ai_addr == NULL) {
|
||||
freeaddrinfo(ai);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (sa != NULL) {
|
||||
if (slen < ai->ai_addrlen) {
|
||||
freeaddrinfo(ai);
|
||||
return -1;
|
||||
}
|
||||
memcpy(sa, &ai->ai_addr, ai->ai_addrlen);
|
||||
}
|
||||
|
||||
freeaddrinfo(ai);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
addr_ntop(const struct xaddr *n, char *p, size_t len)
|
||||
{
|
||||
struct sockaddr_storage ss;
|
||||
socklen_t slen = sizeof(ss);
|
||||
|
||||
if (addr_xaddr_to_sa(n, _SA(&ss), &slen, 0) == -1)
|
||||
return -1;
|
||||
if (p == NULL || len == 0)
|
||||
return -1;
|
||||
if (getnameinfo(_SA(&ss), slen, p, len, NULL, 0,
|
||||
NI_NUMERICHOST) != 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse a CIDR address (x.x.x.x/y or xxxx:yyyy::/z).
|
||||
* Return -1 on parse error, -2 on inconsistency or 0 on success.
|
||||
*/
|
||||
int
|
||||
addr_pton_cidr(const char *p, struct xaddr *n, u_int *l)
|
||||
{
|
||||
struct xaddr tmp;
|
||||
u_int masklen = 999;
|
||||
char addrbuf[64], *mp;
|
||||
const char *errstr;
|
||||
|
||||
/* Don't modify argument */
|
||||
if (p == NULL || strlcpy(addrbuf, p, sizeof(addrbuf)) >= sizeof(addrbuf))
|
||||
return -1;
|
||||
|
||||
if ((mp = strchr(addrbuf, '/')) != NULL) {
|
||||
*mp = '\0';
|
||||
mp++;
|
||||
masklen = (u_int)strtonum(mp, 0, INT_MAX, &errstr);
|
||||
if (errstr)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (addr_pton(addrbuf, &tmp) == -1)
|
||||
return -1;
|
||||
|
||||
if (mp == NULL)
|
||||
masklen = addr_unicast_masklen(tmp.af);
|
||||
if (masklen_valid(tmp.af, masklen) == -1)
|
||||
return -2;
|
||||
if (addr_host_is_all0s(&tmp, masklen) != 0)
|
||||
return -2;
|
||||
|
||||
if (n != NULL)
|
||||
memcpy(n, &tmp, sizeof(*n));
|
||||
if (l != NULL)
|
||||
*l = masklen;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
addr_netmatch(const struct xaddr *host, const struct xaddr *net, u_int masklen)
|
||||
{
|
||||
struct xaddr tmp_mask, tmp_result;
|
||||
|
||||
if (host->af != net->af)
|
||||
return -1;
|
||||
|
||||
if (addr_netmask(host->af, masklen, &tmp_mask) == -1)
|
||||
return -1;
|
||||
if (addr_and(&tmp_result, host, &tmp_mask) == -1)
|
||||
return -1;
|
||||
return addr_cmp(&tmp_result, net);
|
||||
}
|
53
addr.h
Normal file
53
addr.h
Normal file
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright (c) 2004,2005 Damien Miller <djm@mindrot.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* Address handling routines */
|
||||
|
||||
#ifndef _ADDR_H
|
||||
#define _ADDR_H
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
struct xaddr {
|
||||
sa_family_t af;
|
||||
union {
|
||||
struct in_addr v4;
|
||||
struct in6_addr v6;
|
||||
u_int8_t addr8[16];
|
||||
u_int16_t addr16[8];
|
||||
u_int32_t addr32[4];
|
||||
} xa; /* 128-bit address */
|
||||
u_int32_t scope_id; /* iface scope id for v6 */
|
||||
#define v4 xa.v4
|
||||
#define v6 xa.v6
|
||||
#define addr8 xa.addr8
|
||||
#define addr16 xa.addr16
|
||||
#define addr32 xa.addr32
|
||||
};
|
||||
|
||||
int addr_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_pton(const char *p, struct xaddr *n);
|
||||
int addr_pton_cidr(const char *p, struct xaddr *n, u_int *l);
|
||||
int addr_ntop(const struct xaddr *n, char *p, size_t len);
|
||||
int addr_and(struct xaddr *dst, const struct xaddr *a, const struct xaddr *b);
|
||||
int addr_cmp(const struct xaddr *a, const struct xaddr *b);
|
||||
int addr_host_to_all1s(struct xaddr *a, u_int masklen);
|
||||
int addr_netmatch(const struct xaddr *host, const struct xaddr *net,
|
||||
u_int masklen);
|
||||
void addr_increment(struct xaddr *a);
|
||||
#endif /* _ADDR_H */
|
169
addrmatch.c
Normal file
169
addrmatch.c
Normal file
|
@ -0,0 +1,169 @@
|
|||
/* $OpenBSD: addrmatch.c,v 1.17 2021/04/03 06:18:40 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2004-2008 Damien Miller <djm@mindrot.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <netdb.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "addr.h"
|
||||
#include "match.h"
|
||||
#include "log.h"
|
||||
|
||||
/*
|
||||
* Match "addr" against list pattern list "_list", which may contain a
|
||||
* mix of CIDR addresses and old-school wildcards.
|
||||
*
|
||||
* If addr is NULL, then no matching is performed, but _list is parsed
|
||||
* and checked for well-formedness.
|
||||
*
|
||||
* Returns 1 on match found (never returned when addr == NULL).
|
||||
* Returns 0 on if no match found, or no errors found when addr == NULL.
|
||||
* Returns -1 on negated match found (never returned when addr == NULL).
|
||||
* Returns -2 on invalid list entry.
|
||||
*/
|
||||
int
|
||||
addr_match_list(const char *addr, const char *_list)
|
||||
{
|
||||
char *list, *cp, *o;
|
||||
struct xaddr try_addr, match_addr;
|
||||
u_int masklen, neg;
|
||||
int ret = 0, r;
|
||||
|
||||
if (addr != NULL && addr_pton(addr, &try_addr) != 0) {
|
||||
debug2_f("couldn't parse address %.100s", addr);
|
||||
return 0;
|
||||
}
|
||||
if ((o = list = strdup(_list)) == NULL)
|
||||
return -1;
|
||||
while ((cp = strsep(&list, ",")) != NULL) {
|
||||
neg = *cp == '!';
|
||||
if (neg)
|
||||
cp++;
|
||||
if (*cp == '\0') {
|
||||
ret = -2;
|
||||
break;
|
||||
}
|
||||
/* Prefer CIDR address matching */
|
||||
r = addr_pton_cidr(cp, &match_addr, &masklen);
|
||||
if (r == -2) {
|
||||
debug2_f("inconsistent mask length for "
|
||||
"match network \"%.100s\"", cp);
|
||||
ret = -2;
|
||||
break;
|
||||
} else if (r == 0) {
|
||||
if (addr != NULL && addr_netmatch(&try_addr,
|
||||
&match_addr, masklen) == 0) {
|
||||
foundit:
|
||||
if (neg) {
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
ret = 1;
|
||||
}
|
||||
continue;
|
||||
} else {
|
||||
/* If CIDR parse failed, try wildcard string match */
|
||||
if (addr != NULL && match_pattern(addr, cp) == 1)
|
||||
goto foundit;
|
||||
}
|
||||
}
|
||||
free(o);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Match "addr" against list CIDR list "_list". Lexical wildcards and
|
||||
* negation are not supported. If "addr" == NULL, will verify structure
|
||||
* of "_list".
|
||||
*
|
||||
* Returns 1 on match found (never returned when addr == NULL).
|
||||
* Returns 0 on if no match found, or no errors found when addr == NULL.
|
||||
* Returns -1 on error
|
||||
*/
|
||||
int
|
||||
addr_match_cidr_list(const char *addr, const char *_list)
|
||||
{
|
||||
char *list, *cp, *o;
|
||||
struct xaddr try_addr, match_addr;
|
||||
u_int masklen;
|
||||
int ret = 0, r;
|
||||
|
||||
if (addr != NULL && addr_pton(addr, &try_addr) != 0) {
|
||||
debug2_f("couldn't parse address %.100s", addr);
|
||||
return 0;
|
||||
}
|
||||
if ((o = list = strdup(_list)) == NULL)
|
||||
return -1;
|
||||
while ((cp = strsep(&list, ",")) != NULL) {
|
||||
if (*cp == '\0') {
|
||||
error_f("empty entry in list \"%.100s\"", o);
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* NB. This function is called in pre-auth with untrusted data,
|
||||
* so be extra paranoid about junk reaching getaddrino (via
|
||||
* addr_pton_cidr).
|
||||
*/
|
||||
|
||||
/* Stop junk from reaching getaddrinfo. +3 is for masklen */
|
||||
if (strlen(cp) > INET6_ADDRSTRLEN + 3) {
|
||||
error_f("list entry \"%.100s\" too long", cp);
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
#define VALID_CIDR_CHARS "0123456789abcdefABCDEF.:/"
|
||||
if (strspn(cp, VALID_CIDR_CHARS) != strlen(cp)) {
|
||||
error_f("list entry \"%.100s\" contains invalid "
|
||||
"characters", cp);
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
/* Prefer CIDR address matching */
|
||||
r = addr_pton_cidr(cp, &match_addr, &masklen);
|
||||
if (r == -1) {
|
||||
error("Invalid network entry \"%.100s\"", cp);
|
||||
ret = -1;
|
||||
break;
|
||||
} else if (r == -2) {
|
||||
error("Inconsistent mask length for "
|
||||
"network \"%.100s\"", cp);
|
||||
ret = -1;
|
||||
break;
|
||||
} else if (r == 0 && addr != NULL) {
|
||||
if (addr_netmatch(&try_addr, &match_addr,
|
||||
masklen) == 0)
|
||||
ret = 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
free(o);
|
||||
|
||||
return ret;
|
||||
}
|
179
atomicio.c
Normal file
179
atomicio.c
Normal file
|
@ -0,0 +1,179 @@
|
|||
/* $OpenBSD: atomicio.c,v 1.30 2019/01/24 02:42:23 dtucker Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2006 Damien Miller. All rights reserved.
|
||||
* Copyright (c) 2005 Anil Madhavapeddy. All rights reserved.
|
||||
* Copyright (c) 1995,1999 Theo de Raadt. All rights reserved.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include <sys/uio.h>
|
||||
|
||||
#include <errno.h>
|
||||
#ifdef HAVE_POLL_H
|
||||
#include <poll.h>
|
||||
#else
|
||||
# ifdef HAVE_SYS_POLL_H
|
||||
# include <sys/poll.h>
|
||||
# endif
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "atomicio.h"
|
||||
|
||||
/*
|
||||
* ensure all of data on socket comes through. f==read || f==vwrite
|
||||
*/
|
||||
size_t
|
||||
atomicio6(ssize_t (*f) (int, void *, size_t), int fd, void *_s, size_t n,
|
||||
int (*cb)(void *, size_t), void *cb_arg)
|
||||
{
|
||||
char *s = _s;
|
||||
size_t pos = 0;
|
||||
ssize_t res;
|
||||
struct pollfd pfd;
|
||||
|
||||
pfd.fd = fd;
|
||||
#ifndef BROKEN_READ_COMPARISON
|
||||
pfd.events = f == read ? POLLIN : POLLOUT;
|
||||
#else
|
||||
pfd.events = POLLIN|POLLOUT;
|
||||
#endif
|
||||
while (n > pos) {
|
||||
res = (f) (fd, s + pos, n - pos);
|
||||
switch (res) {
|
||||
case -1:
|
||||
if (errno == EINTR) {
|
||||
/* possible SIGALARM, update callback */
|
||||
if (cb != NULL && cb(cb_arg, 0) == -1) {
|
||||
errno = EINTR;
|
||||
return pos;
|
||||
}
|
||||
continue;
|
||||
} else if (errno == EAGAIN || errno == EWOULDBLOCK) {
|
||||
(void)poll(&pfd, 1, -1);
|
||||
continue;
|
||||
}
|
||||
return 0;
|
||||
case 0:
|
||||
errno = EPIPE;
|
||||
return pos;
|
||||
default:
|
||||
pos += (size_t)res;
|
||||
if (cb != NULL && cb(cb_arg, (size_t)res) == -1) {
|
||||
errno = EINTR;
|
||||
return pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
size_t
|
||||
atomicio(ssize_t (*f) (int, void *, size_t), int fd, void *_s, size_t n)
|
||||
{
|
||||
return atomicio6(f, fd, _s, n, NULL, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* ensure all of data on socket comes through. f==readv || f==writev
|
||||
*/
|
||||
size_t
|
||||
atomiciov6(ssize_t (*f) (int, const struct iovec *, int), int fd,
|
||||
const struct iovec *_iov, int iovcnt,
|
||||
int (*cb)(void *, size_t), void *cb_arg)
|
||||
{
|
||||
size_t pos = 0, rem;
|
||||
ssize_t res;
|
||||
struct iovec iov_array[IOV_MAX], *iov = iov_array;
|
||||
struct pollfd pfd;
|
||||
|
||||
if (iovcnt < 0 || iovcnt > IOV_MAX) {
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
/* Make a copy of the iov array because we may modify it below */
|
||||
memcpy(iov, _iov, (size_t)iovcnt * sizeof(*_iov));
|
||||
|
||||
pfd.fd = fd;
|
||||
#ifndef BROKEN_READV_COMPARISON
|
||||
pfd.events = f == readv ? POLLIN : POLLOUT;
|
||||
#else
|
||||
pfd.events = POLLIN|POLLOUT;
|
||||
#endif
|
||||
for (; iovcnt > 0 && iov[0].iov_len > 0;) {
|
||||
res = (f) (fd, iov, iovcnt);
|
||||
switch (res) {
|
||||
case -1:
|
||||
if (errno == EINTR) {
|
||||
/* possible SIGALARM, update callback */
|
||||
if (cb != NULL && cb(cb_arg, 0) == -1) {
|
||||
errno = EINTR;
|
||||
return pos;
|
||||
}
|
||||
continue;
|
||||
} else if (errno == EAGAIN || errno == EWOULDBLOCK) {
|
||||
(void)poll(&pfd, 1, -1);
|
||||
continue;
|
||||
}
|
||||
return 0;
|
||||
case 0:
|
||||
errno = EPIPE;
|
||||
return pos;
|
||||
default:
|
||||
rem = (size_t)res;
|
||||
pos += rem;
|
||||
/* skip completed iov entries */
|
||||
while (iovcnt > 0 && rem >= iov[0].iov_len) {
|
||||
rem -= iov[0].iov_len;
|
||||
iov++;
|
||||
iovcnt--;
|
||||
}
|
||||
/* This shouldn't happen... */
|
||||
if (rem > 0 && (iovcnt <= 0 || rem > iov[0].iov_len)) {
|
||||
errno = EFAULT;
|
||||
return 0;
|
||||
}
|
||||
if (iovcnt == 0)
|
||||
break;
|
||||
/* update pointer in partially complete iov */
|
||||
iov[0].iov_base = ((char *)iov[0].iov_base) + rem;
|
||||
iov[0].iov_len -= rem;
|
||||
}
|
||||
if (cb != NULL && cb(cb_arg, (size_t)res) == -1) {
|
||||
errno = EINTR;
|
||||
return pos;
|
||||
}
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
size_t
|
||||
atomiciov(ssize_t (*f) (int, const struct iovec *, int), int fd,
|
||||
const struct iovec *_iov, int iovcnt)
|
||||
{
|
||||
return atomiciov6(f, fd, _iov, iovcnt, NULL, NULL);
|
||||
}
|
53
atomicio.h
Normal file
53
atomicio.h
Normal file
|
@ -0,0 +1,53 @@
|
|||
/* $OpenBSD: atomicio.h,v 1.12 2018/12/27 03:25:25 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006 Damien Miller. All rights reserved.
|
||||
* Copyright (c) 1995,1999 Theo de Raadt. All rights reserved.
|
||||
* 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 _ATOMICIO_H
|
||||
#define _ATOMICIO_H
|
||||
|
||||
struct iovec;
|
||||
|
||||
/*
|
||||
* Ensure all of data on socket comes through. f==read || f==vwrite
|
||||
*/
|
||||
size_t
|
||||
atomicio6(ssize_t (*f) (int, void *, size_t), int fd, void *_s, size_t n,
|
||||
int (*cb)(void *, size_t), void *);
|
||||
size_t atomicio(ssize_t (*)(int, void *, size_t), int, void *, size_t);
|
||||
|
||||
#define vwrite (ssize_t (*)(int, void *, size_t))write
|
||||
|
||||
/*
|
||||
* ensure all of data on socket comes through. f==readv || f==writev
|
||||
*/
|
||||
size_t
|
||||
atomiciov6(ssize_t (*f) (int, const struct iovec *, int), int fd,
|
||||
const struct iovec *_iov, int iovcnt, int (*cb)(void *, size_t), void *);
|
||||
size_t atomiciov(ssize_t (*)(int, const struct iovec *, int),
|
||||
int, const struct iovec *, int);
|
||||
|
||||
#endif /* _ATOMICIO_H */
|
455
audit-bsm.c
Normal file
455
audit-bsm.c
Normal file
|
@ -0,0 +1,455 @@
|
|||
/*
|
||||
* TODO
|
||||
*
|
||||
* - deal with overlap between this and sys_auth_allowed_user
|
||||
* sys_auth_record_login and record_failed_login.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright 1988-2002 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
/* #pragma ident "@(#)bsmaudit.c 1.1 01/09/17 SMI" */
|
||||
|
||||
#include "includes.h"
|
||||
#if defined(USE_BSM_AUDIT)
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <netdb.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef BROKEN_BSM_API
|
||||
#include <libscf.h>
|
||||
#endif
|
||||
|
||||
#include "ssh.h"
|
||||
#include "log.h"
|
||||
#include "hostfile.h"
|
||||
#include "auth.h"
|
||||
#include "xmalloc.h"
|
||||
|
||||
#ifndef AUE_openssh
|
||||
# define AUE_openssh 32800
|
||||
#endif
|
||||
#include <bsm/audit.h>
|
||||
#include <bsm/libbsm.h>
|
||||
#include <bsm/audit_uevents.h>
|
||||
#include <bsm/audit_record.h>
|
||||
#include <locale.h>
|
||||
|
||||
#if defined(HAVE_GETAUDIT_ADDR)
|
||||
#define AuditInfoStruct auditinfo_addr
|
||||
#define AuditInfoTermID au_tid_addr_t
|
||||
#define SetAuditFunc(a,b) setaudit_addr((a),(b))
|
||||
#define SetAuditFuncText "setaudit_addr"
|
||||
#define AUToSubjectFunc au_to_subject_ex
|
||||
#define AUToReturnFunc(a,b) au_to_return32((a), (int32_t)(b))
|
||||
#else
|
||||
#define AuditInfoStruct auditinfo
|
||||
#define AuditInfoTermID au_tid_t
|
||||
#define SetAuditFunc(a,b) setaudit(a)
|
||||
#define SetAuditFuncText "setaudit"
|
||||
#define AUToSubjectFunc au_to_subject
|
||||
#define AUToReturnFunc(a,b) au_to_return((a), (u_int)(b))
|
||||
#endif
|
||||
|
||||
#ifndef cannot_audit
|
||||
extern int cannot_audit(int);
|
||||
#endif
|
||||
extern void aug_init(void);
|
||||
extern void aug_save_auid(au_id_t);
|
||||
extern void aug_save_uid(uid_t);
|
||||
extern void aug_save_euid(uid_t);
|
||||
extern void aug_save_gid(gid_t);
|
||||
extern void aug_save_egid(gid_t);
|
||||
extern void aug_save_pid(pid_t);
|
||||
extern void aug_save_asid(au_asid_t);
|
||||
extern void aug_save_tid(dev_t, unsigned int);
|
||||
extern void aug_save_tid_ex(dev_t, u_int32_t *, u_int32_t);
|
||||
extern int aug_save_me(void);
|
||||
extern int aug_save_namask(void);
|
||||
extern void aug_save_event(au_event_t);
|
||||
extern void aug_save_sorf(int);
|
||||
extern void aug_save_text(char *);
|
||||
extern void aug_save_text1(char *);
|
||||
extern void aug_save_text2(char *);
|
||||
extern void aug_save_na(int);
|
||||
extern void aug_save_user(char *);
|
||||
extern void aug_save_path(char *);
|
||||
extern int aug_save_policy(void);
|
||||
extern void aug_save_afunc(int (*)(int));
|
||||
extern int aug_audit(void);
|
||||
extern int aug_na_selected(void);
|
||||
extern int aug_selected(void);
|
||||
extern int aug_daemon_session(void);
|
||||
|
||||
#ifndef HAVE_GETTEXT
|
||||
# define gettext(a) (a)
|
||||
#endif
|
||||
|
||||
extern Authctxt *the_authctxt;
|
||||
static AuditInfoTermID ssh_bsm_tid;
|
||||
|
||||
#ifdef BROKEN_BSM_API
|
||||
/* For some reason this constant is no longer defined
|
||||
in Solaris 11. */
|
||||
#define BSM_TEXTBUFSZ 256
|
||||
#endif
|
||||
|
||||
/* Below is the low-level BSM interface code */
|
||||
|
||||
/*
|
||||
* aug_get_machine is only required on IPv6 capable machines, we use a
|
||||
* different mechanism in audit_connection_from() for IPv4-only machines.
|
||||
* getaudit_addr() is only present on IPv6 capable machines.
|
||||
*/
|
||||
#if defined(HAVE_AUG_GET_MACHINE) || !defined(HAVE_GETAUDIT_ADDR)
|
||||
extern int aug_get_machine(char *, u_int32_t *, u_int32_t *);
|
||||
#else
|
||||
static int
|
||||
aug_get_machine(char *host, u_int32_t *addr, u_int32_t *type)
|
||||
{
|
||||
struct addrinfo *ai;
|
||||
struct sockaddr_in *in4;
|
||||
struct sockaddr_in6 *in6;
|
||||
int ret = 0, r;
|
||||
|
||||
if ((r = getaddrinfo(host, NULL, NULL, &ai)) != 0) {
|
||||
error("BSM audit: getaddrinfo failed for %.100s: %.100s", host,
|
||||
r == EAI_SYSTEM ? strerror(errno) : gai_strerror(r));
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (ai->ai_family) {
|
||||
case AF_INET:
|
||||
in4 = (struct sockaddr_in *)ai->ai_addr;
|
||||
*type = AU_IPv4;
|
||||
memcpy(addr, &in4->sin_addr, sizeof(struct in_addr));
|
||||
break;
|
||||
#ifdef AU_IPv6
|
||||
case AF_INET6:
|
||||
in6 = (struct sockaddr_in6 *)ai->ai_addr;
|
||||
*type = AU_IPv6;
|
||||
memcpy(addr, &in6->sin6_addr, sizeof(struct in6_addr));
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
error("BSM audit: unknown address family for %.100s: %d",
|
||||
host, ai->ai_family);
|
||||
ret = -1;
|
||||
}
|
||||
freeaddrinfo(ai);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BROKEN_BSM_API
|
||||
/*
|
||||
In Solaris 11 the audit daemon has been moved to SMF. In the process
|
||||
they simply dropped getacna() from the API, since it read from a now
|
||||
non-existent config file. This function re-implements getacna() to
|
||||
read from the SMF repository instead.
|
||||
*/
|
||||
int
|
||||
getacna(char *auditstring, int len)
|
||||
{
|
||||
scf_handle_t *handle = NULL;
|
||||
scf_property_t *property = NULL;
|
||||
scf_value_t *value = NULL;
|
||||
int ret = 0;
|
||||
|
||||
/*
|
||||
* The man page for getacna on Solaris 10 states we should return -2
|
||||
* in case of error and set errno to indicate the error. We don't
|
||||
* bother with errno here, though, since the only use of this function
|
||||
* below doesn't check for errors anyway.
|
||||
*/
|
||||
handle = scf_handle_create(SCF_VERSION);
|
||||
if (handle == NULL)
|
||||
return -2;
|
||||
|
||||
ret = scf_handle_bind(handle);
|
||||
if (ret == -1)
|
||||
return -2;
|
||||
|
||||
property = scf_property_create(handle);
|
||||
if (property == NULL)
|
||||
return -2;
|
||||
|
||||
ret = scf_handle_decode_fmri(handle,
|
||||
"svc:/system/auditd:default/:properties/preselection/naflags",
|
||||
NULL, NULL, NULL, NULL, property, 0);
|
||||
if (ret == -1)
|
||||
return -2;
|
||||
|
||||
value = scf_value_create(handle);
|
||||
if (value == NULL)
|
||||
return -2;
|
||||
|
||||
ret = scf_property_get_value(property, value);
|
||||
if (ret == -1)
|
||||
return -2;
|
||||
|
||||
ret = scf_value_get_astring(value, auditstring, len);
|
||||
if (ret == -1)
|
||||
return -2;
|
||||
|
||||
scf_value_destroy(value);
|
||||
scf_property_destroy(property);
|
||||
scf_handle_destroy(handle);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Check if the specified event is selected (enabled) for auditing.
|
||||
* Returns 1 if the event is selected, 0 if not and -1 on failure.
|
||||
*/
|
||||
static int
|
||||
selected(char *username, uid_t uid, au_event_t event, int sf)
|
||||
{
|
||||
int rc, sorf;
|
||||
char naflags[512];
|
||||
struct au_mask mask;
|
||||
|
||||
mask.am_success = mask.am_failure = 0;
|
||||
if (uid < 0) {
|
||||
/* get flags for non-attributable (to a real user) events */
|
||||
rc = getacna(naflags, sizeof(naflags));
|
||||
if (rc == 0)
|
||||
(void) getauditflagsbin(naflags, &mask);
|
||||
} else
|
||||
rc = au_user_mask(username, &mask);
|
||||
|
||||
sorf = (sf == 0) ? AU_PRS_SUCCESS : AU_PRS_FAILURE;
|
||||
return(au_preselect(event, &mask, sorf, AU_PRS_REREAD));
|
||||
}
|
||||
|
||||
static void
|
||||
bsm_audit_record(int typ, char *string, au_event_t event_no)
|
||||
{
|
||||
int ad, rc, sel;
|
||||
uid_t uid = -1;
|
||||
gid_t gid = -1;
|
||||
pid_t pid = getpid();
|
||||
AuditInfoTermID tid = ssh_bsm_tid;
|
||||
|
||||
if (the_authctxt != NULL && the_authctxt->valid) {
|
||||
uid = the_authctxt->pw->pw_uid;
|
||||
gid = the_authctxt->pw->pw_gid;
|
||||
}
|
||||
|
||||
rc = (typ == 0) ? 0 : -1;
|
||||
sel = selected(the_authctxt->user, uid, event_no, rc);
|
||||
debug3("BSM audit: typ %d rc %d \"%s\"", typ, rc, string);
|
||||
if (!sel)
|
||||
return; /* audit event does not match mask, do not write */
|
||||
|
||||
debug3("BSM audit: writing audit new record");
|
||||
ad = au_open();
|
||||
|
||||
(void) au_write(ad, AUToSubjectFunc(uid, uid, gid, uid, gid,
|
||||
pid, pid, &tid));
|
||||
(void) au_write(ad, au_to_text(string));
|
||||
(void) au_write(ad, AUToReturnFunc(typ, rc));
|
||||
|
||||
#ifdef BROKEN_BSM_API
|
||||
/*
|
||||
* The last argument is the event modifier flags. For some seemingly
|
||||
* undocumented reason it was added in Solaris 11.
|
||||
*/
|
||||
rc = au_close(ad, AU_TO_WRITE, event_no, 0);
|
||||
#else
|
||||
rc = au_close(ad, AU_TO_WRITE, event_no);
|
||||
#endif
|
||||
|
||||
if (rc < 0)
|
||||
error("BSM audit: %s failed to write \"%s\" record: %s",
|
||||
__func__, string, strerror(errno));
|
||||
}
|
||||
|
||||
static void
|
||||
bsm_audit_session_setup(void)
|
||||
{
|
||||
int rc;
|
||||
struct AuditInfoStruct info;
|
||||
au_mask_t mask;
|
||||
|
||||
if (the_authctxt == NULL) {
|
||||
error("BSM audit: session setup internal error (NULL ctxt)");
|
||||
return;
|
||||
}
|
||||
|
||||
if (the_authctxt->valid)
|
||||
info.ai_auid = the_authctxt->pw->pw_uid;
|
||||
else
|
||||
info.ai_auid = -1;
|
||||
info.ai_asid = getpid();
|
||||
mask.am_success = 0;
|
||||
mask.am_failure = 0;
|
||||
|
||||
(void) au_user_mask(the_authctxt->user, &mask);
|
||||
|
||||
info.ai_mask.am_success = mask.am_success;
|
||||
info.ai_mask.am_failure = mask.am_failure;
|
||||
|
||||
info.ai_termid = ssh_bsm_tid;
|
||||
|
||||
rc = SetAuditFunc(&info, sizeof(info));
|
||||
if (rc < 0)
|
||||
error("BSM audit: %s: %s failed: %s", __func__,
|
||||
SetAuditFuncText, strerror(errno));
|
||||
}
|
||||
|
||||
static void
|
||||
bsm_audit_bad_login(const char *what)
|
||||
{
|
||||
char textbuf[BSM_TEXTBUFSZ];
|
||||
|
||||
if (the_authctxt->valid) {
|
||||
(void) snprintf(textbuf, sizeof (textbuf),
|
||||
gettext("invalid %s for user %s"),
|
||||
what, the_authctxt->user);
|
||||
bsm_audit_record(4, textbuf, AUE_openssh);
|
||||
} else {
|
||||
(void) snprintf(textbuf, sizeof (textbuf),
|
||||
gettext("invalid user name \"%s\""),
|
||||
the_authctxt->user);
|
||||
bsm_audit_record(3, textbuf, AUE_openssh);
|
||||
}
|
||||
}
|
||||
|
||||
/* Below is the sshd audit API code */
|
||||
|
||||
void
|
||||
audit_connection_from(const char *host, int port)
|
||||
{
|
||||
AuditInfoTermID *tid = &ssh_bsm_tid;
|
||||
char buf[1024];
|
||||
|
||||
if (cannot_audit(0))
|
||||
return;
|
||||
debug3("BSM audit: connection from %.100s port %d", host, port);
|
||||
|
||||
/* populate our terminal id structure */
|
||||
#if defined(HAVE_GETAUDIT_ADDR)
|
||||
tid->at_port = (dev_t)port;
|
||||
aug_get_machine((char *)host, &(tid->at_addr[0]), &(tid->at_type));
|
||||
snprintf(buf, sizeof(buf), "%08x %08x %08x %08x", tid->at_addr[0],
|
||||
tid->at_addr[1], tid->at_addr[2], tid->at_addr[3]);
|
||||
debug3("BSM audit: iptype %d machine ID %s", (int)tid->at_type, buf);
|
||||
#else
|
||||
/* this is used on IPv4-only machines */
|
||||
tid->port = (dev_t)port;
|
||||
tid->machine = inet_addr(host);
|
||||
snprintf(buf, sizeof(buf), "%08x", tid->machine);
|
||||
debug3("BSM audit: machine ID %s", buf);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
audit_run_command(const char *command)
|
||||
{
|
||||
/* not implemented */
|
||||
}
|
||||
|
||||
void
|
||||
audit_session_open(struct logininfo *li)
|
||||
{
|
||||
/* not implemented */
|
||||
}
|
||||
|
||||
void
|
||||
audit_session_close(struct logininfo *li)
|
||||
{
|
||||
/* not implemented */
|
||||
}
|
||||
|
||||
void
|
||||
audit_event(struct ssh *ssh, ssh_audit_event_t event)
|
||||
{
|
||||
char textbuf[BSM_TEXTBUFSZ];
|
||||
static int logged_in = 0;
|
||||
const char *user = the_authctxt ? the_authctxt->user : "(unknown user)";
|
||||
|
||||
if (cannot_audit(0))
|
||||
return;
|
||||
|
||||
switch(event) {
|
||||
case SSH_AUTH_SUCCESS:
|
||||
logged_in = 1;
|
||||
bsm_audit_session_setup();
|
||||
snprintf(textbuf, sizeof(textbuf),
|
||||
gettext("successful login %s"), user);
|
||||
bsm_audit_record(0, textbuf, AUE_openssh);
|
||||
break;
|
||||
|
||||
case SSH_CONNECTION_CLOSE:
|
||||
/*
|
||||
* We can also get a close event if the user attempted auth
|
||||
* but never succeeded.
|
||||
*/
|
||||
if (logged_in) {
|
||||
snprintf(textbuf, sizeof(textbuf),
|
||||
gettext("sshd logout %s"), the_authctxt->user);
|
||||
bsm_audit_record(0, textbuf, AUE_logout);
|
||||
} else {
|
||||
debug("%s: connection closed without authentication",
|
||||
__func__);
|
||||
}
|
||||
break;
|
||||
|
||||
case SSH_NOLOGIN:
|
||||
bsm_audit_record(1,
|
||||
gettext("logins disabled by /etc/nologin"), AUE_openssh);
|
||||
break;
|
||||
|
||||
case SSH_LOGIN_EXCEED_MAXTRIES:
|
||||
snprintf(textbuf, sizeof(textbuf),
|
||||
gettext("too many tries for user %s"), the_authctxt->user);
|
||||
bsm_audit_record(1, textbuf, AUE_openssh);
|
||||
break;
|
||||
|
||||
case SSH_LOGIN_ROOT_DENIED:
|
||||
bsm_audit_record(2, gettext("not_console"), AUE_openssh);
|
||||
break;
|
||||
|
||||
case SSH_AUTH_FAIL_PASSWD:
|
||||
bsm_audit_bad_login("password");
|
||||
break;
|
||||
|
||||
case SSH_AUTH_FAIL_KBDINT:
|
||||
bsm_audit_bad_login("interactive password entry");
|
||||
break;
|
||||
|
||||
default:
|
||||
debug("%s: unhandled event %d", __func__, event);
|
||||
}
|
||||
}
|
||||
#endif /* BSM */
|
124
audit-linux.c
Normal file
124
audit-linux.c
Normal file
|
@ -0,0 +1,124 @@
|
|||
/*
|
||||
* Copyright 2010 Red Hat, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Red Hat author: Jan F. Chadima <jchadima@redhat.com>
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#if defined(USE_LINUX_AUDIT)
|
||||
#include <libaudit.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "log.h"
|
||||
#include "audit.h"
|
||||
#include "canohost.h"
|
||||
#include "packet.h"
|
||||
|
||||
const char *audit_username(void);
|
||||
|
||||
int
|
||||
linux_audit_record_event(int uid, const char *username, const char *hostname,
|
||||
const char *ip, const char *ttyn, int success)
|
||||
{
|
||||
int audit_fd, rc, saved_errno;
|
||||
|
||||
if ((audit_fd = audit_open()) < 0) {
|
||||
if (errno == EINVAL || errno == EPROTONOSUPPORT ||
|
||||
errno == EAFNOSUPPORT)
|
||||
return 1; /* No audit support in kernel */
|
||||
else
|
||||
return 0; /* Must prevent login */
|
||||
}
|
||||
rc = audit_log_acct_message(audit_fd, AUDIT_USER_LOGIN,
|
||||
NULL, "login", username ? username : "(unknown)",
|
||||
username == NULL ? uid : -1, hostname, ip, ttyn, success);
|
||||
saved_errno = errno;
|
||||
close(audit_fd);
|
||||
|
||||
/*
|
||||
* Do not report error if the error is EPERM and sshd is run as non
|
||||
* root user.
|
||||
*/
|
||||
if ((rc == -EPERM) && (geteuid() != 0))
|
||||
rc = 0;
|
||||
errno = saved_errno;
|
||||
|
||||
return rc >= 0;
|
||||
}
|
||||
|
||||
/* Below is the sshd audit API code */
|
||||
|
||||
void
|
||||
audit_connection_from(const char *host, int port)
|
||||
{
|
||||
/* not implemented */
|
||||
}
|
||||
|
||||
void
|
||||
audit_run_command(const char *command)
|
||||
{
|
||||
/* not implemented */
|
||||
}
|
||||
|
||||
void
|
||||
audit_session_open(struct logininfo *li)
|
||||
{
|
||||
if (linux_audit_record_event(li->uid, NULL, li->hostname, NULL,
|
||||
li->line, 1) == 0)
|
||||
fatal("linux_audit_write_entry failed: %s", strerror(errno));
|
||||
}
|
||||
|
||||
void
|
||||
audit_session_close(struct logininfo *li)
|
||||
{
|
||||
/* not implemented */
|
||||
}
|
||||
|
||||
void
|
||||
audit_event(struct ssh *ssh, ssh_audit_event_t event)
|
||||
{
|
||||
switch(event) {
|
||||
case SSH_AUTH_SUCCESS:
|
||||
case SSH_CONNECTION_CLOSE:
|
||||
case SSH_NOLOGIN:
|
||||
case SSH_LOGIN_EXCEED_MAXTRIES:
|
||||
case SSH_LOGIN_ROOT_DENIED:
|
||||
break;
|
||||
case SSH_AUTH_FAIL_NONE:
|
||||
case SSH_AUTH_FAIL_PASSWD:
|
||||
case SSH_AUTH_FAIL_KBDINT:
|
||||
case SSH_AUTH_FAIL_PUBKEY:
|
||||
case SSH_AUTH_FAIL_HOSTBASED:
|
||||
case SSH_AUTH_FAIL_GSSAPI:
|
||||
case SSH_INVALID_USER:
|
||||
linux_audit_record_event(-1, audit_username(), NULL,
|
||||
ssh_remote_ipaddr(ssh), "sshd", 0);
|
||||
break;
|
||||
default:
|
||||
debug("%s: unhandled event %d", __func__, event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif /* USE_LINUX_AUDIT */
|
184
audit.c
Normal file
184
audit.c
Normal file
|
@ -0,0 +1,184 @@
|
|||
/*
|
||||
* Copyright (c) 2004, 2005 Darren Tucker. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef SSH_AUDIT_EVENTS
|
||||
|
||||
#include "audit.h"
|
||||
#include "log.h"
|
||||
#include "hostfile.h"
|
||||
#include "auth.h"
|
||||
|
||||
/*
|
||||
* Care must be taken when using this since it WILL NOT be initialized when
|
||||
* audit_connection_from() is called and MAY NOT be initialized when
|
||||
* audit_event(CONNECTION_ABANDON) is called. Test for NULL before using.
|
||||
*/
|
||||
extern Authctxt *the_authctxt;
|
||||
|
||||
/* Maybe add the audit class to struct Authmethod? */
|
||||
ssh_audit_event_t
|
||||
audit_classify_auth(const char *method)
|
||||
{
|
||||
if (strcmp(method, "none") == 0)
|
||||
return SSH_AUTH_FAIL_NONE;
|
||||
else if (strcmp(method, "password") == 0)
|
||||
return SSH_AUTH_FAIL_PASSWD;
|
||||
else if (strcmp(method, "publickey") == 0 ||
|
||||
strcmp(method, "rsa") == 0)
|
||||
return SSH_AUTH_FAIL_PUBKEY;
|
||||
else if (strncmp(method, "keyboard-interactive", 20) == 0 ||
|
||||
strcmp(method, "challenge-response") == 0)
|
||||
return SSH_AUTH_FAIL_KBDINT;
|
||||
else if (strcmp(method, "hostbased") == 0 ||
|
||||
strcmp(method, "rhosts-rsa") == 0)
|
||||
return SSH_AUTH_FAIL_HOSTBASED;
|
||||
else if (strcmp(method, "gssapi-with-mic") == 0)
|
||||
return SSH_AUTH_FAIL_GSSAPI;
|
||||
else
|
||||
return SSH_AUDIT_UNKNOWN;
|
||||
}
|
||||
|
||||
/* helper to return supplied username */
|
||||
const char *
|
||||
audit_username(void)
|
||||
{
|
||||
static const char unknownuser[] = "(unknown user)";
|
||||
static const char invaliduser[] = "(invalid user)";
|
||||
|
||||
if (the_authctxt == NULL || the_authctxt->user == NULL)
|
||||
return (unknownuser);
|
||||
if (!the_authctxt->valid)
|
||||
return (invaliduser);
|
||||
return (the_authctxt->user);
|
||||
}
|
||||
|
||||
const char *
|
||||
audit_event_lookup(ssh_audit_event_t ev)
|
||||
{
|
||||
int i;
|
||||
static struct event_lookup_struct {
|
||||
ssh_audit_event_t event;
|
||||
const char *name;
|
||||
} event_lookup[] = {
|
||||
{SSH_LOGIN_EXCEED_MAXTRIES, "LOGIN_EXCEED_MAXTRIES"},
|
||||
{SSH_LOGIN_ROOT_DENIED, "LOGIN_ROOT_DENIED"},
|
||||
{SSH_AUTH_SUCCESS, "AUTH_SUCCESS"},
|
||||
{SSH_AUTH_FAIL_NONE, "AUTH_FAIL_NONE"},
|
||||
{SSH_AUTH_FAIL_PASSWD, "AUTH_FAIL_PASSWD"},
|
||||
{SSH_AUTH_FAIL_KBDINT, "AUTH_FAIL_KBDINT"},
|
||||
{SSH_AUTH_FAIL_PUBKEY, "AUTH_FAIL_PUBKEY"},
|
||||
{SSH_AUTH_FAIL_HOSTBASED, "AUTH_FAIL_HOSTBASED"},
|
||||
{SSH_AUTH_FAIL_GSSAPI, "AUTH_FAIL_GSSAPI"},
|
||||
{SSH_INVALID_USER, "INVALID_USER"},
|
||||
{SSH_NOLOGIN, "NOLOGIN"},
|
||||
{SSH_CONNECTION_CLOSE, "CONNECTION_CLOSE"},
|
||||
{SSH_CONNECTION_ABANDON, "CONNECTION_ABANDON"},
|
||||
{SSH_AUDIT_UNKNOWN, "AUDIT_UNKNOWN"}
|
||||
};
|
||||
|
||||
for (i = 0; event_lookup[i].event != SSH_AUDIT_UNKNOWN; i++)
|
||||
if (event_lookup[i].event == ev)
|
||||
break;
|
||||
return(event_lookup[i].name);
|
||||
}
|
||||
|
||||
# ifndef CUSTOM_SSH_AUDIT_EVENTS
|
||||
/*
|
||||
* Null implementations of audit functions.
|
||||
* These get used if SSH_AUDIT_EVENTS is defined but no audit module is enabled.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Called after a connection has been accepted but before any authentication
|
||||
* has been attempted.
|
||||
*/
|
||||
void
|
||||
audit_connection_from(const char *host, int port)
|
||||
{
|
||||
debug("audit connection from %s port %d euid %d", host, port,
|
||||
(int)geteuid());
|
||||
}
|
||||
|
||||
/*
|
||||
* Called when various events occur (see audit.h for a list of possible
|
||||
* events and what they mean).
|
||||
*/
|
||||
void
|
||||
audit_event(struct ssh *ssh, ssh_audit_event_t event)
|
||||
{
|
||||
debug("audit event euid %d user %s event %d (%s)", geteuid(),
|
||||
audit_username(), event, audit_event_lookup(event));
|
||||
}
|
||||
|
||||
/*
|
||||
* Called when a user session is started. Argument is the tty allocated to
|
||||
* the session, or NULL if no tty was allocated.
|
||||
*
|
||||
* Note that this may be called multiple times if multiple sessions are used
|
||||
* within a single connection.
|
||||
*/
|
||||
void
|
||||
audit_session_open(struct logininfo *li)
|
||||
{
|
||||
const char *t = li->line ? li->line : "(no tty)";
|
||||
|
||||
debug("audit session open euid %d user %s tty name %s", geteuid(),
|
||||
audit_username(), t);
|
||||
}
|
||||
|
||||
/*
|
||||
* Called when a user session is closed. Argument is the tty allocated to
|
||||
* the session, or NULL if no tty was allocated.
|
||||
*
|
||||
* Note that this may be called multiple times if multiple sessions are used
|
||||
* within a single connection.
|
||||
*/
|
||||
void
|
||||
audit_session_close(struct logininfo *li)
|
||||
{
|
||||
const char *t = li->line ? li->line : "(no tty)";
|
||||
|
||||
debug("audit session close euid %d user %s tty name %s", geteuid(),
|
||||
audit_username(), t);
|
||||
}
|
||||
|
||||
/*
|
||||
* This will be called when a user runs a non-interactive command. Note that
|
||||
* it may be called multiple times for a single connection since SSH2 allows
|
||||
* multiple sessions within a single connection.
|
||||
*/
|
||||
void
|
||||
audit_run_command(const char *command)
|
||||
{
|
||||
debug("audit run command euid %d user %s command '%.200s'", geteuid(),
|
||||
audit_username(), command);
|
||||
}
|
||||
# endif /* !defined CUSTOM_SSH_AUDIT_EVENTS */
|
||||
#endif /* SSH_AUDIT_EVENTS */
|
57
audit.h
Normal file
57
audit.h
Normal file
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright (c) 2004, 2005 Darren Tucker. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _SSH_AUDIT_H
|
||||
# define _SSH_AUDIT_H
|
||||
|
||||
#include "loginrec.h"
|
||||
|
||||
struct ssh;
|
||||
|
||||
enum ssh_audit_event_type {
|
||||
SSH_LOGIN_EXCEED_MAXTRIES,
|
||||
SSH_LOGIN_ROOT_DENIED,
|
||||
SSH_AUTH_SUCCESS,
|
||||
SSH_AUTH_FAIL_NONE,
|
||||
SSH_AUTH_FAIL_PASSWD,
|
||||
SSH_AUTH_FAIL_KBDINT, /* keyboard-interactive or challenge-response */
|
||||
SSH_AUTH_FAIL_PUBKEY, /* ssh2 pubkey or ssh1 rsa */
|
||||
SSH_AUTH_FAIL_HOSTBASED, /* ssh2 hostbased or ssh1 rhostsrsa */
|
||||
SSH_AUTH_FAIL_GSSAPI,
|
||||
SSH_INVALID_USER,
|
||||
SSH_NOLOGIN, /* denied by /etc/nologin, not implemented */
|
||||
SSH_CONNECTION_CLOSE, /* closed after attempting auth or session */
|
||||
SSH_CONNECTION_ABANDON, /* closed without completing auth */
|
||||
SSH_AUDIT_UNKNOWN
|
||||
};
|
||||
typedef enum ssh_audit_event_type ssh_audit_event_t;
|
||||
|
||||
void audit_connection_from(const char *, int);
|
||||
void audit_event(struct ssh *, ssh_audit_event_t);
|
||||
void audit_session_open(struct logininfo *);
|
||||
void audit_session_close(struct logininfo *);
|
||||
void audit_run_command(const char *);
|
||||
ssh_audit_event_t audit_classify_auth(const char *);
|
||||
|
||||
#endif /* _SSH_AUDIT_H */
|
143
auth-bsdauth.c
Normal file
143
auth-bsdauth.c
Normal file
|
@ -0,0 +1,143 @@
|
|||
/* $OpenBSD: auth-bsdauth.c,v 1.15 2018/07/09 21:35:50 markus Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2001 Markus Friedl. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef BSD_AUTH
|
||||
#include "xmalloc.h"
|
||||
#include "sshkey.h"
|
||||
#include "sshbuf.h"
|
||||
#include "hostfile.h"
|
||||
#include "auth.h"
|
||||
#include "log.h"
|
||||
#ifdef GSSAPI
|
||||
#include "ssh-gss.h"
|
||||
#endif
|
||||
#include "monitor_wrap.h"
|
||||
|
||||
static void *
|
||||
bsdauth_init_ctx(Authctxt *authctxt)
|
||||
{
|
||||
return authctxt;
|
||||
}
|
||||
|
||||
int
|
||||
bsdauth_query(void *ctx, char **name, char **infotxt,
|
||||
u_int *numprompts, char ***prompts, u_int **echo_on)
|
||||
{
|
||||
Authctxt *authctxt = ctx;
|
||||
char *challenge = NULL;
|
||||
|
||||
*infotxt = NULL;
|
||||
*numprompts = 0;
|
||||
*prompts = NULL;
|
||||
*echo_on = NULL;
|
||||
|
||||
if (authctxt->as != NULL) {
|
||||
debug2("bsdauth_query: try reuse session");
|
||||
challenge = auth_getitem(authctxt->as, AUTHV_CHALLENGE);
|
||||
if (challenge == NULL) {
|
||||
auth_close(authctxt->as);
|
||||
authctxt->as = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (challenge == NULL) {
|
||||
debug2("bsdauth_query: new bsd auth session");
|
||||
debug3("bsdauth_query: style %s",
|
||||
authctxt->style ? authctxt->style : "<default>");
|
||||
authctxt->as = auth_userchallenge(authctxt->user,
|
||||
authctxt->style, "auth-ssh", &challenge);
|
||||
if (authctxt->as == NULL)
|
||||
challenge = NULL;
|
||||
debug2("bsdauth_query: <%s>", challenge ? challenge : "empty");
|
||||
}
|
||||
|
||||
if (challenge == NULL)
|
||||
return -1;
|
||||
|
||||
*name = xstrdup("");
|
||||
*infotxt = xstrdup("");
|
||||
*numprompts = 1;
|
||||
*prompts = xcalloc(*numprompts, sizeof(char *));
|
||||
*echo_on = xcalloc(*numprompts, sizeof(u_int));
|
||||
(*prompts)[0] = xstrdup(challenge);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
bsdauth_respond(void *ctx, u_int numresponses, char **responses)
|
||||
{
|
||||
Authctxt *authctxt = ctx;
|
||||
int authok;
|
||||
|
||||
if (!authctxt->valid)
|
||||
return -1;
|
||||
|
||||
if (authctxt->as == NULL)
|
||||
error("bsdauth_respond: no bsd auth session");
|
||||
|
||||
if (numresponses != 1)
|
||||
return -1;
|
||||
|
||||
authok = auth_userresponse(authctxt->as, responses[0], 0);
|
||||
authctxt->as = NULL;
|
||||
debug3("bsdauth_respond: <%s> = <%d>", responses[0], authok);
|
||||
|
||||
return (authok == 0) ? -1 : 0;
|
||||
}
|
||||
|
||||
static void
|
||||
bsdauth_free_ctx(void *ctx)
|
||||
{
|
||||
Authctxt *authctxt = ctx;
|
||||
|
||||
if (authctxt && authctxt->as) {
|
||||
auth_close(authctxt->as);
|
||||
authctxt->as = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
KbdintDevice bsdauth_device = {
|
||||
"bsdauth",
|
||||
bsdauth_init_ctx,
|
||||
bsdauth_query,
|
||||
bsdauth_respond,
|
||||
bsdauth_free_ctx
|
||||
};
|
||||
|
||||
KbdintDevice mm_bsdauth_device = {
|
||||
"bsdauth",
|
||||
bsdauth_init_ctx,
|
||||
mm_bsdauth_query,
|
||||
mm_bsdauth_respond,
|
||||
bsdauth_free_ctx
|
||||
};
|
||||
#endif
|
273
auth-krb5.c
Normal file
273
auth-krb5.c
Normal file
|
@ -0,0 +1,273 @@
|
|||
/* $OpenBSD: auth-krb5.c,v 1.24 2021/04/03 06:18:40 djm Exp $ */
|
||||
/*
|
||||
* Kerberos v5 authentication and ticket-passing routines.
|
||||
*
|
||||
* From: FreeBSD: src/crypto/openssh/auth-krb5.c,v 1.6 2001/02/13 16:58:04 assar
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2002 Daniel Kouril. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <pwd.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "ssh.h"
|
||||
#include "packet.h"
|
||||
#include "log.h"
|
||||
#include "sshbuf.h"
|
||||
#include "sshkey.h"
|
||||
#include "misc.h"
|
||||
#include "servconf.h"
|
||||
#include "uidswap.h"
|
||||
#include "hostfile.h"
|
||||
#include "auth.h"
|
||||
|
||||
#ifdef KRB5
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <krb5.h>
|
||||
|
||||
extern ServerOptions options;
|
||||
|
||||
static int
|
||||
krb5_init(void *context)
|
||||
{
|
||||
Authctxt *authctxt = (Authctxt *)context;
|
||||
krb5_error_code problem;
|
||||
|
||||
if (authctxt->krb5_ctx == NULL) {
|
||||
problem = krb5_init_context(&authctxt->krb5_ctx);
|
||||
if (problem)
|
||||
return (problem);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
auth_krb5_password(Authctxt *authctxt, const char *password)
|
||||
{
|
||||
#ifndef HEIMDAL
|
||||
krb5_creds creds;
|
||||
krb5_principal server;
|
||||
#endif
|
||||
krb5_error_code problem;
|
||||
krb5_ccache ccache = NULL;
|
||||
int len;
|
||||
char *client, *platform_client;
|
||||
const char *errmsg;
|
||||
|
||||
/* get platform-specific kerberos client principal name (if it exists) */
|
||||
platform_client = platform_krb5_get_principal_name(authctxt->pw->pw_name);
|
||||
client = platform_client ? platform_client : authctxt->pw->pw_name;
|
||||
|
||||
temporarily_use_uid(authctxt->pw);
|
||||
|
||||
problem = krb5_init(authctxt);
|
||||
if (problem)
|
||||
goto out;
|
||||
|
||||
problem = krb5_parse_name(authctxt->krb5_ctx, client,
|
||||
&authctxt->krb5_user);
|
||||
if (problem)
|
||||
goto out;
|
||||
|
||||
#ifdef HEIMDAL
|
||||
# ifdef HAVE_KRB5_CC_NEW_UNIQUE
|
||||
problem = krb5_cc_new_unique(authctxt->krb5_ctx,
|
||||
krb5_mcc_ops.prefix, NULL, &ccache);
|
||||
# else
|
||||
problem = krb5_cc_gen_new(authctxt->krb5_ctx, &krb5_mcc_ops, &ccache);
|
||||
# endif
|
||||
if (problem)
|
||||
goto out;
|
||||
|
||||
problem = krb5_cc_initialize(authctxt->krb5_ctx, ccache,
|
||||
authctxt->krb5_user);
|
||||
if (problem)
|
||||
goto out;
|
||||
|
||||
restore_uid();
|
||||
|
||||
problem = krb5_verify_user(authctxt->krb5_ctx, authctxt->krb5_user,
|
||||
ccache, password, 1, NULL);
|
||||
|
||||
temporarily_use_uid(authctxt->pw);
|
||||
|
||||
if (problem)
|
||||
goto out;
|
||||
|
||||
# ifdef HAVE_KRB5_CC_NEW_UNIQUE
|
||||
problem = krb5_cc_new_unique(authctxt->krb5_ctx,
|
||||
krb5_fcc_ops.prefix, NULL, &authctxt->krb5_fwd_ccache);
|
||||
# else
|
||||
problem = krb5_cc_gen_new(authctxt->krb5_ctx, &krb5_fcc_ops,
|
||||
&authctxt->krb5_fwd_ccache);
|
||||
# endif
|
||||
if (problem)
|
||||
goto out;
|
||||
|
||||
problem = krb5_cc_copy_cache(authctxt->krb5_ctx, ccache,
|
||||
authctxt->krb5_fwd_ccache);
|
||||
krb5_cc_destroy(authctxt->krb5_ctx, ccache);
|
||||
ccache = NULL;
|
||||
if (problem)
|
||||
goto out;
|
||||
|
||||
#else
|
||||
problem = krb5_get_init_creds_password(authctxt->krb5_ctx, &creds,
|
||||
authctxt->krb5_user, (char *)password, NULL, NULL, 0, NULL, NULL);
|
||||
if (problem)
|
||||
goto out;
|
||||
|
||||
problem = krb5_sname_to_principal(authctxt->krb5_ctx, NULL, NULL,
|
||||
KRB5_NT_SRV_HST, &server);
|
||||
if (problem)
|
||||
goto out;
|
||||
|
||||
restore_uid();
|
||||
problem = krb5_verify_init_creds(authctxt->krb5_ctx, &creds, server,
|
||||
NULL, NULL, NULL);
|
||||
krb5_free_principal(authctxt->krb5_ctx, server);
|
||||
temporarily_use_uid(authctxt->pw);
|
||||
if (problem)
|
||||
goto out;
|
||||
|
||||
if (!krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user,
|
||||
authctxt->pw->pw_name)) {
|
||||
problem = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
problem = ssh_krb5_cc_gen(authctxt->krb5_ctx,
|
||||
&authctxt->krb5_fwd_ccache);
|
||||
if (problem)
|
||||
goto out;
|
||||
|
||||
problem = krb5_cc_initialize(authctxt->krb5_ctx,
|
||||
authctxt->krb5_fwd_ccache, authctxt->krb5_user);
|
||||
if (problem)
|
||||
goto out;
|
||||
|
||||
problem = krb5_cc_store_cred(authctxt->krb5_ctx,
|
||||
authctxt->krb5_fwd_ccache, &creds);
|
||||
if (problem)
|
||||
goto out;
|
||||
#endif
|
||||
|
||||
authctxt->krb5_ticket_file = (char *)krb5_cc_get_name(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache);
|
||||
|
||||
len = strlen(authctxt->krb5_ticket_file) + 6;
|
||||
authctxt->krb5_ccname = xmalloc(len);
|
||||
snprintf(authctxt->krb5_ccname, len, "FILE:%s",
|
||||
authctxt->krb5_ticket_file);
|
||||
|
||||
#ifdef USE_PAM
|
||||
if (options.use_pam)
|
||||
do_pam_putenv("KRB5CCNAME", authctxt->krb5_ccname);
|
||||
#endif
|
||||
|
||||
out:
|
||||
restore_uid();
|
||||
|
||||
free(platform_client);
|
||||
|
||||
if (problem) {
|
||||
if (ccache)
|
||||
krb5_cc_destroy(authctxt->krb5_ctx, ccache);
|
||||
|
||||
if (authctxt->krb5_ctx != NULL && problem!=-1) {
|
||||
errmsg = krb5_get_error_message(authctxt->krb5_ctx,
|
||||
problem);
|
||||
debug("Kerberos password authentication failed: %s",
|
||||
errmsg);
|
||||
krb5_free_error_message(authctxt->krb5_ctx, errmsg);
|
||||
} else
|
||||
debug("Kerberos password authentication failed: %d",
|
||||
problem);
|
||||
|
||||
krb5_cleanup_proc(authctxt);
|
||||
|
||||
if (options.kerberos_or_local_passwd)
|
||||
return (-1);
|
||||
else
|
||||
return (0);
|
||||
}
|
||||
return (authctxt->valid ? 1 : 0);
|
||||
}
|
||||
|
||||
void
|
||||
krb5_cleanup_proc(Authctxt *authctxt)
|
||||
{
|
||||
debug("krb5_cleanup_proc called");
|
||||
if (authctxt->krb5_fwd_ccache) {
|
||||
krb5_cc_destroy(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache);
|
||||
authctxt->krb5_fwd_ccache = NULL;
|
||||
}
|
||||
if (authctxt->krb5_user) {
|
||||
krb5_free_principal(authctxt->krb5_ctx, authctxt->krb5_user);
|
||||
authctxt->krb5_user = NULL;
|
||||
}
|
||||
if (authctxt->krb5_ctx) {
|
||||
krb5_free_context(authctxt->krb5_ctx);
|
||||
authctxt->krb5_ctx = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef HEIMDAL
|
||||
krb5_error_code
|
||||
ssh_krb5_cc_gen(krb5_context ctx, krb5_ccache *ccache) {
|
||||
int tmpfd, ret, oerrno;
|
||||
char ccname[40];
|
||||
mode_t old_umask;
|
||||
|
||||
ret = snprintf(ccname, sizeof(ccname),
|
||||
"FILE:/tmp/krb5cc_%d_XXXXXXXXXX", geteuid());
|
||||
if (ret < 0 || (size_t)ret >= sizeof(ccname))
|
||||
return ENOMEM;
|
||||
|
||||
old_umask = umask(0177);
|
||||
tmpfd = mkstemp(ccname + strlen("FILE:"));
|
||||
oerrno = errno;
|
||||
umask(old_umask);
|
||||
if (tmpfd == -1) {
|
||||
logit("mkstemp(): %.100s", strerror(oerrno));
|
||||
return oerrno;
|
||||
}
|
||||
|
||||
if (fchmod(tmpfd,S_IRUSR | S_IWUSR) == -1) {
|
||||
oerrno = errno;
|
||||
logit("fchmod(): %.100s", strerror(oerrno));
|
||||
close(tmpfd);
|
||||
return oerrno;
|
||||
}
|
||||
close(tmpfd);
|
||||
|
||||
return (krb5_cc_resolve(ctx, ccname, ccache));
|
||||
}
|
||||
#endif /* !HEIMDAL */
|
||||
#endif /* KRB5 */
|
912
auth-options.c
Normal file
912
auth-options.c
Normal file
|
@ -0,0 +1,912 @@
|
|||
/* $OpenBSD: auth-options.c,v 1.101 2023/07/14 07:44:21 dtucker Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2018 Damien Miller <djm@mindrot.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <netdb.h>
|
||||
#include <pwd.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#ifdef HAVE_STDINT_H
|
||||
# include <stdint.h>
|
||||
#endif
|
||||
#include <stdarg.h>
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "openbsd-compat/sys-queue.h"
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "ssherr.h"
|
||||
#include "log.h"
|
||||
#include "sshbuf.h"
|
||||
#include "misc.h"
|
||||
#include "sshkey.h"
|
||||
#include "match.h"
|
||||
#include "ssh2.h"
|
||||
#include "auth-options.h"
|
||||
|
||||
static int
|
||||
dup_strings(char ***dstp, size_t *ndstp, char **src, size_t nsrc)
|
||||
{
|
||||
char **dst;
|
||||
size_t i, j;
|
||||
|
||||
*dstp = NULL;
|
||||
*ndstp = 0;
|
||||
|
||||
if (nsrc == 0)
|
||||
return 0;
|
||||
if (nsrc >= SIZE_MAX / sizeof(*src) ||
|
||||
(dst = calloc(nsrc, sizeof(*src))) == NULL)
|
||||
return -1;
|
||||
for (i = 0; i < nsrc; i++) {
|
||||
if ((dst[i] = strdup(src[i])) == NULL) {
|
||||
for (j = 0; j < i; j++)
|
||||
free(dst[j]);
|
||||
free(dst);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
/* success */
|
||||
*dstp = dst;
|
||||
*ndstp = nsrc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define OPTIONS_CRITICAL 1
|
||||
#define OPTIONS_EXTENSIONS 2
|
||||
static int
|
||||
cert_option_list(struct sshauthopt *opts, struct sshbuf *oblob,
|
||||
u_int which, int crit)
|
||||
{
|
||||
char *command, *allowed;
|
||||
char *name = NULL;
|
||||
struct sshbuf *c = NULL, *data = NULL;
|
||||
int r, ret = -1, found;
|
||||
|
||||
if ((c = sshbuf_fromb(oblob)) == NULL) {
|
||||
error_f("sshbuf_fromb failed");
|
||||
goto out;
|
||||
}
|
||||
|
||||
while (sshbuf_len(c) > 0) {
|
||||
sshbuf_free(data);
|
||||
data = NULL;
|
||||
if ((r = sshbuf_get_cstring(c, &name, NULL)) != 0 ||
|
||||
(r = sshbuf_froms(c, &data)) != 0) {
|
||||
error_r(r, "Unable to parse certificate options");
|
||||
goto out;
|
||||
}
|
||||
debug3("found certificate option \"%.100s\" len %zu",
|
||||
name, sshbuf_len(data));
|
||||
found = 0;
|
||||
if ((which & OPTIONS_EXTENSIONS) != 0) {
|
||||
if (strcmp(name, "no-touch-required") == 0) {
|
||||
opts->no_require_user_presence = 1;
|
||||
found = 1;
|
||||
} else if (strcmp(name, "permit-X11-forwarding") == 0) {
|
||||
opts->permit_x11_forwarding_flag = 1;
|
||||
found = 1;
|
||||
} else if (strcmp(name,
|
||||
"permit-agent-forwarding") == 0) {
|
||||
opts->permit_agent_forwarding_flag = 1;
|
||||
found = 1;
|
||||
} else if (strcmp(name,
|
||||
"permit-port-forwarding") == 0) {
|
||||
opts->permit_port_forwarding_flag = 1;
|
||||
found = 1;
|
||||
} else if (strcmp(name, "permit-pty") == 0) {
|
||||
opts->permit_pty_flag = 1;
|
||||
found = 1;
|
||||
} else if (strcmp(name, "permit-user-rc") == 0) {
|
||||
opts->permit_user_rc = 1;
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
if (!found && (which & OPTIONS_CRITICAL) != 0) {
|
||||
if (strcmp(name, "verify-required") == 0) {
|
||||
opts->require_verify = 1;
|
||||
found = 1;
|
||||
} else if (strcmp(name, "force-command") == 0) {
|
||||
if ((r = sshbuf_get_cstring(data, &command,
|
||||
NULL)) != 0) {
|
||||
error_r(r, "Unable to parse \"%s\" "
|
||||
"section", name);
|
||||
goto out;
|
||||
}
|
||||
if (opts->force_command != NULL) {
|
||||
error("Certificate has multiple "
|
||||
"force-command options");
|
||||
free(command);
|
||||
goto out;
|
||||
}
|
||||
opts->force_command = command;
|
||||
found = 1;
|
||||
} else if (strcmp(name, "source-address") == 0) {
|
||||
if ((r = sshbuf_get_cstring(data, &allowed,
|
||||
NULL)) != 0) {
|
||||
error_r(r, "Unable to parse \"%s\" "
|
||||
"section", name);
|
||||
goto out;
|
||||
}
|
||||
if (opts->required_from_host_cert != NULL) {
|
||||
error("Certificate has multiple "
|
||||
"source-address options");
|
||||
free(allowed);
|
||||
goto out;
|
||||
}
|
||||
/* Check syntax */
|
||||
if (addr_match_cidr_list(NULL, allowed) == -1) {
|
||||
error("Certificate source-address "
|
||||
"contents invalid");
|
||||
goto out;
|
||||
}
|
||||
opts->required_from_host_cert = allowed;
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
if (crit) {
|
||||
error("Certificate critical option \"%s\" "
|
||||
"is not supported", name);
|
||||
goto out;
|
||||
} else {
|
||||
logit("Certificate extension \"%s\" "
|
||||
"is not supported", name);
|
||||
}
|
||||
} else if (sshbuf_len(data) != 0) {
|
||||
error("Certificate option \"%s\" corrupt "
|
||||
"(extra data)", name);
|
||||
goto out;
|
||||
}
|
||||
free(name);
|
||||
name = NULL;
|
||||
}
|
||||
/* successfully parsed all options */
|
||||
ret = 0;
|
||||
|
||||
out:
|
||||
free(name);
|
||||
sshbuf_free(data);
|
||||
sshbuf_free(c);
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct sshauthopt *
|
||||
sshauthopt_new(void)
|
||||
{
|
||||
struct sshauthopt *ret;
|
||||
|
||||
if ((ret = calloc(1, sizeof(*ret))) == NULL)
|
||||
return NULL;
|
||||
ret->force_tun_device = -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
sshauthopt_free(struct sshauthopt *opts)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (opts == NULL)
|
||||
return;
|
||||
|
||||
free(opts->cert_principals);
|
||||
free(opts->force_command);
|
||||
free(opts->required_from_host_cert);
|
||||
free(opts->required_from_host_keys);
|
||||
|
||||
for (i = 0; i < opts->nenv; i++)
|
||||
free(opts->env[i]);
|
||||
free(opts->env);
|
||||
|
||||
for (i = 0; i < opts->npermitopen; i++)
|
||||
free(opts->permitopen[i]);
|
||||
free(opts->permitopen);
|
||||
|
||||
for (i = 0; i < opts->npermitlisten; i++)
|
||||
free(opts->permitlisten[i]);
|
||||
free(opts->permitlisten);
|
||||
|
||||
freezero(opts, sizeof(*opts));
|
||||
}
|
||||
|
||||
struct sshauthopt *
|
||||
sshauthopt_new_with_keys_defaults(void)
|
||||
{
|
||||
struct sshauthopt *ret = NULL;
|
||||
|
||||
if ((ret = sshauthopt_new()) == NULL)
|
||||
return NULL;
|
||||
|
||||
/* Defaults for authorized_keys flags */
|
||||
ret->permit_port_forwarding_flag = 1;
|
||||
ret->permit_agent_forwarding_flag = 1;
|
||||
ret->permit_x11_forwarding_flag = 1;
|
||||
ret->permit_pty_flag = 1;
|
||||
ret->permit_user_rc = 1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse and record a permitopen/permitlisten directive.
|
||||
* Return 0 on success. Return -1 on failure and sets *errstrp to error reason.
|
||||
*/
|
||||
static int
|
||||
handle_permit(const char **optsp, int allow_bare_port,
|
||||
char ***permitsp, size_t *npermitsp, const char **errstrp)
|
||||
{
|
||||
char *opt, *tmp, *cp, *host, **permits = *permitsp;
|
||||
size_t npermits = *npermitsp;
|
||||
const char *errstr = "unknown error";
|
||||
|
||||
if (npermits > SSH_AUTHOPT_PERMIT_MAX) {
|
||||
*errstrp = "too many permission directives";
|
||||
return -1;
|
||||
}
|
||||
if ((opt = opt_dequote(optsp, &errstr)) == NULL) {
|
||||
return -1;
|
||||
}
|
||||
if (allow_bare_port && strchr(opt, ':') == NULL) {
|
||||
/*
|
||||
* Allow a bare port number in permitlisten to indicate a
|
||||
* listen_host wildcard.
|
||||
*/
|
||||
if (asprintf(&tmp, "*:%s", opt) == -1) {
|
||||
free(opt);
|
||||
*errstrp = "memory allocation failed";
|
||||
return -1;
|
||||
}
|
||||
free(opt);
|
||||
opt = tmp;
|
||||
}
|
||||
if ((tmp = strdup(opt)) == NULL) {
|
||||
free(opt);
|
||||
*errstrp = "memory allocation failed";
|
||||
return -1;
|
||||
}
|
||||
cp = tmp;
|
||||
/* validate syntax before recording it. */
|
||||
host = hpdelim2(&cp, NULL);
|
||||
if (host == NULL || strlen(host) >= NI_MAXHOST) {
|
||||
free(tmp);
|
||||
free(opt);
|
||||
*errstrp = "invalid permission hostname";
|
||||
return -1;
|
||||
}
|
||||
/*
|
||||
* don't want to use permitopen_port to avoid
|
||||
* dependency on channels.[ch] here.
|
||||
*/
|
||||
if (cp == NULL ||
|
||||
(strcmp(cp, "*") != 0 && a2port(cp) <= 0)) {
|
||||
free(tmp);
|
||||
free(opt);
|
||||
*errstrp = "invalid permission port";
|
||||
return -1;
|
||||
}
|
||||
/* XXX - add streamlocal support */
|
||||
free(tmp);
|
||||
/* Record it */
|
||||
if ((permits = recallocarray(permits, npermits, npermits + 1,
|
||||
sizeof(*permits))) == NULL) {
|
||||
free(opt);
|
||||
/* NB. don't update *permitsp if alloc fails */
|
||||
*errstrp = "memory allocation failed";
|
||||
return -1;
|
||||
}
|
||||
permits[npermits++] = opt;
|
||||
*permitsp = permits;
|
||||
*npermitsp = npermits;
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct sshauthopt *
|
||||
sshauthopt_parse(const char *opts, const char **errstrp)
|
||||
{
|
||||
char **oarray, *opt, *cp, *tmp;
|
||||
int r;
|
||||
struct sshauthopt *ret = NULL;
|
||||
const char *errstr = "unknown error";
|
||||
uint64_t valid_before;
|
||||
size_t i, l;
|
||||
|
||||
if (errstrp != NULL)
|
||||
*errstrp = NULL;
|
||||
if ((ret = sshauthopt_new_with_keys_defaults()) == NULL)
|
||||
goto alloc_fail;
|
||||
|
||||
if (opts == NULL)
|
||||
return ret;
|
||||
|
||||
while (*opts && *opts != ' ' && *opts != '\t') {
|
||||
/* flag options */
|
||||
if ((r = opt_flag("restrict", 0, &opts)) != -1) {
|
||||
ret->restricted = 1;
|
||||
ret->permit_port_forwarding_flag = 0;
|
||||
ret->permit_agent_forwarding_flag = 0;
|
||||
ret->permit_x11_forwarding_flag = 0;
|
||||
ret->permit_pty_flag = 0;
|
||||
ret->permit_user_rc = 0;
|
||||
} else if ((r = opt_flag("cert-authority", 0, &opts)) != -1) {
|
||||
ret->cert_authority = r;
|
||||
} else if ((r = opt_flag("port-forwarding", 1, &opts)) != -1) {
|
||||
ret->permit_port_forwarding_flag = r == 1;
|
||||
} else if ((r = opt_flag("agent-forwarding", 1, &opts)) != -1) {
|
||||
ret->permit_agent_forwarding_flag = r == 1;
|
||||
} else if ((r = opt_flag("x11-forwarding", 1, &opts)) != -1) {
|
||||
ret->permit_x11_forwarding_flag = r == 1;
|
||||
} else if ((r = opt_flag("touch-required", 1, &opts)) != -1) {
|
||||
ret->no_require_user_presence = r != 1; /* NB. flip */
|
||||
} else if ((r = opt_flag("verify-required", 1, &opts)) != -1) {
|
||||
ret->require_verify = r == 1;
|
||||
} else if ((r = opt_flag("pty", 1, &opts)) != -1) {
|
||||
ret->permit_pty_flag = r == 1;
|
||||
} else if ((r = opt_flag("user-rc", 1, &opts)) != -1) {
|
||||
ret->permit_user_rc = r == 1;
|
||||
} else if (opt_match(&opts, "command")) {
|
||||
if (ret->force_command != NULL) {
|
||||
errstr = "multiple \"command\" clauses";
|
||||
goto fail;
|
||||
}
|
||||
ret->force_command = opt_dequote(&opts, &errstr);
|
||||
if (ret->force_command == NULL)
|
||||
goto fail;
|
||||
} else if (opt_match(&opts, "principals")) {
|
||||
if (ret->cert_principals != NULL) {
|
||||
errstr = "multiple \"principals\" clauses";
|
||||
goto fail;
|
||||
}
|
||||
ret->cert_principals = opt_dequote(&opts, &errstr);
|
||||
if (ret->cert_principals == NULL)
|
||||
goto fail;
|
||||
} else if (opt_match(&opts, "from")) {
|
||||
if (ret->required_from_host_keys != NULL) {
|
||||
errstr = "multiple \"from\" clauses";
|
||||
goto fail;
|
||||
}
|
||||
ret->required_from_host_keys = opt_dequote(&opts,
|
||||
&errstr);
|
||||
if (ret->required_from_host_keys == NULL)
|
||||
goto fail;
|
||||
} else if (opt_match(&opts, "expiry-time")) {
|
||||
if ((opt = opt_dequote(&opts, &errstr)) == NULL)
|
||||
goto fail;
|
||||
if (parse_absolute_time(opt, &valid_before) != 0 ||
|
||||
valid_before == 0) {
|
||||
free(opt);
|
||||
errstr = "invalid expires time";
|
||||
goto fail;
|
||||
}
|
||||
free(opt);
|
||||
if (ret->valid_before == 0 ||
|
||||
valid_before < ret->valid_before)
|
||||
ret->valid_before = valid_before;
|
||||
} else if (opt_match(&opts, "environment")) {
|
||||
if (ret->nenv > SSH_AUTHOPT_ENV_MAX) {
|
||||
errstr = "too many environment strings";
|
||||
goto fail;
|
||||
}
|
||||
if ((opt = opt_dequote(&opts, &errstr)) == NULL)
|
||||
goto fail;
|
||||
/* env name must be alphanumeric and followed by '=' */
|
||||
if ((tmp = strchr(opt, '=')) == NULL) {
|
||||
free(opt);
|
||||
errstr = "invalid environment string";
|
||||
goto fail;
|
||||
}
|
||||
if ((cp = strdup(opt)) == NULL) {
|
||||
free(opt);
|
||||
goto alloc_fail;
|
||||
}
|
||||
l = (size_t)(tmp - opt);
|
||||
cp[l] = '\0'; /* truncate at '=' */
|
||||
if (!valid_env_name(cp)) {
|
||||
free(cp);
|
||||
free(opt);
|
||||
errstr = "invalid environment string";
|
||||
goto fail;
|
||||
}
|
||||
/* Check for duplicates; XXX O(n*log(n)) */
|
||||
for (i = 0; i < ret->nenv; i++) {
|
||||
if (strncmp(ret->env[i], cp, l) == 0 &&
|
||||
ret->env[i][l] == '=')
|
||||
break;
|
||||
}
|
||||
free(cp);
|
||||
/* First match wins */
|
||||
if (i >= ret->nenv) {
|
||||
/* Append it. */
|
||||
oarray = ret->env;
|
||||
if ((ret->env = recallocarray(ret->env,
|
||||
ret->nenv, ret->nenv + 1,
|
||||
sizeof(*ret->env))) == NULL) {
|
||||
free(opt);
|
||||
/* put it back for cleanup */
|
||||
ret->env = oarray;
|
||||
goto alloc_fail;
|
||||
}
|
||||
ret->env[ret->nenv++] = opt;
|
||||
opt = NULL; /* transferred */
|
||||
}
|
||||
free(opt);
|
||||
} else if (opt_match(&opts, "permitopen")) {
|
||||
if (handle_permit(&opts, 0, &ret->permitopen,
|
||||
&ret->npermitopen, &errstr) != 0)
|
||||
goto fail;
|
||||
} else if (opt_match(&opts, "permitlisten")) {
|
||||
if (handle_permit(&opts, 1, &ret->permitlisten,
|
||||
&ret->npermitlisten, &errstr) != 0)
|
||||
goto fail;
|
||||
} else if (opt_match(&opts, "tunnel")) {
|
||||
if ((opt = opt_dequote(&opts, &errstr)) == NULL)
|
||||
goto fail;
|
||||
ret->force_tun_device = a2tun(opt, NULL);
|
||||
free(opt);
|
||||
if (ret->force_tun_device == SSH_TUNID_ERR) {
|
||||
errstr = "invalid tun device";
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Skip the comma, and move to the next option
|
||||
* (or break out if there are no more).
|
||||
*/
|
||||
if (*opts == '\0' || *opts == ' ' || *opts == '\t')
|
||||
break; /* End of options. */
|
||||
/* Anything other than a comma is an unknown option */
|
||||
if (*opts != ',') {
|
||||
errstr = "unknown key option";
|
||||
goto fail;
|
||||
}
|
||||
opts++;
|
||||
if (*opts == '\0') {
|
||||
errstr = "unexpected end-of-options";
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
/* success */
|
||||
if (errstrp != NULL)
|
||||
*errstrp = NULL;
|
||||
return ret;
|
||||
|
||||
alloc_fail:
|
||||
errstr = "memory allocation failed";
|
||||
fail:
|
||||
sshauthopt_free(ret);
|
||||
if (errstrp != NULL)
|
||||
*errstrp = errstr;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct sshauthopt *
|
||||
sshauthopt_from_cert(struct sshkey *k)
|
||||
{
|
||||
struct sshauthopt *ret;
|
||||
|
||||
if (k == NULL || !sshkey_type_is_cert(k->type) || k->cert == NULL ||
|
||||
k->cert->type != SSH2_CERT_TYPE_USER)
|
||||
return NULL;
|
||||
|
||||
if ((ret = sshauthopt_new()) == NULL)
|
||||
return NULL;
|
||||
|
||||
/* Handle options and critical extensions separately */
|
||||
if (cert_option_list(ret, k->cert->critical,
|
||||
OPTIONS_CRITICAL, 1) == -1) {
|
||||
sshauthopt_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
if (cert_option_list(ret, k->cert->extensions,
|
||||
OPTIONS_EXTENSIONS, 0) == -1) {
|
||||
sshauthopt_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
/* success */
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Merges "additional" options to "primary" and returns the result.
|
||||
* NB. Some options from primary have primacy.
|
||||
*/
|
||||
struct sshauthopt *
|
||||
sshauthopt_merge(const struct sshauthopt *primary,
|
||||
const struct sshauthopt *additional, const char **errstrp)
|
||||
{
|
||||
struct sshauthopt *ret;
|
||||
const char *errstr = "internal error";
|
||||
const char *tmp;
|
||||
|
||||
if (errstrp != NULL)
|
||||
*errstrp = NULL;
|
||||
|
||||
if ((ret = sshauthopt_new()) == NULL)
|
||||
goto alloc_fail;
|
||||
|
||||
/* cert_authority and cert_principals are cleared in result */
|
||||
|
||||
/* Prefer access lists from primary. */
|
||||
/* XXX err is both set and mismatch? */
|
||||
tmp = primary->required_from_host_cert;
|
||||
if (tmp == NULL)
|
||||
tmp = additional->required_from_host_cert;
|
||||
if (tmp != NULL && (ret->required_from_host_cert = strdup(tmp)) == NULL)
|
||||
goto alloc_fail;
|
||||
tmp = primary->required_from_host_keys;
|
||||
if (tmp == NULL)
|
||||
tmp = additional->required_from_host_keys;
|
||||
if (tmp != NULL && (ret->required_from_host_keys = strdup(tmp)) == NULL)
|
||||
goto alloc_fail;
|
||||
|
||||
/*
|
||||
* force_tun_device, permitopen/permitlisten and environment all
|
||||
* prefer the primary.
|
||||
*/
|
||||
ret->force_tun_device = primary->force_tun_device;
|
||||
if (ret->force_tun_device == -1)
|
||||
ret->force_tun_device = additional->force_tun_device;
|
||||
if (primary->nenv > 0) {
|
||||
if (dup_strings(&ret->env, &ret->nenv,
|
||||
primary->env, primary->nenv) != 0)
|
||||
goto alloc_fail;
|
||||
} else if (additional->nenv) {
|
||||
if (dup_strings(&ret->env, &ret->nenv,
|
||||
additional->env, additional->nenv) != 0)
|
||||
goto alloc_fail;
|
||||
}
|
||||
if (primary->npermitopen > 0) {
|
||||
if (dup_strings(&ret->permitopen, &ret->npermitopen,
|
||||
primary->permitopen, primary->npermitopen) != 0)
|
||||
goto alloc_fail;
|
||||
} else if (additional->npermitopen > 0) {
|
||||
if (dup_strings(&ret->permitopen, &ret->npermitopen,
|
||||
additional->permitopen, additional->npermitopen) != 0)
|
||||
goto alloc_fail;
|
||||
}
|
||||
|
||||
if (primary->npermitlisten > 0) {
|
||||
if (dup_strings(&ret->permitlisten, &ret->npermitlisten,
|
||||
primary->permitlisten, primary->npermitlisten) != 0)
|
||||
goto alloc_fail;
|
||||
} else if (additional->npermitlisten > 0) {
|
||||
if (dup_strings(&ret->permitlisten, &ret->npermitlisten,
|
||||
additional->permitlisten, additional->npermitlisten) != 0)
|
||||
goto alloc_fail;
|
||||
}
|
||||
|
||||
#define OPTFLAG_AND(x) ret->x = (primary->x == 1) && (additional->x == 1)
|
||||
#define OPTFLAG_OR(x) ret->x = (primary->x == 1) || (additional->x == 1)
|
||||
/* Permissive flags are logical-AND (i.e. must be set in both) */
|
||||
OPTFLAG_AND(permit_port_forwarding_flag);
|
||||
OPTFLAG_AND(permit_agent_forwarding_flag);
|
||||
OPTFLAG_AND(permit_x11_forwarding_flag);
|
||||
OPTFLAG_AND(permit_pty_flag);
|
||||
OPTFLAG_AND(permit_user_rc);
|
||||
OPTFLAG_AND(no_require_user_presence);
|
||||
/* Restrictive flags are logical-OR (i.e. must be set in either) */
|
||||
OPTFLAG_OR(require_verify);
|
||||
#undef OPTFLAG_AND
|
||||
|
||||
/* Earliest expiry time should win */
|
||||
if (primary->valid_before != 0)
|
||||
ret->valid_before = primary->valid_before;
|
||||
if (additional->valid_before != 0 &&
|
||||
additional->valid_before < ret->valid_before)
|
||||
ret->valid_before = additional->valid_before;
|
||||
|
||||
/*
|
||||
* When both multiple forced-command are specified, only
|
||||
* proceed if they are identical, otherwise fail.
|
||||
*/
|
||||
if (primary->force_command != NULL &&
|
||||
additional->force_command != NULL) {
|
||||
if (strcmp(primary->force_command,
|
||||
additional->force_command) == 0) {
|
||||
/* ok */
|
||||
ret->force_command = strdup(primary->force_command);
|
||||
if (ret->force_command == NULL)
|
||||
goto alloc_fail;
|
||||
} else {
|
||||
errstr = "forced command options do not match";
|
||||
goto fail;
|
||||
}
|
||||
} else if (primary->force_command != NULL) {
|
||||
if ((ret->force_command = strdup(
|
||||
primary->force_command)) == NULL)
|
||||
goto alloc_fail;
|
||||
} else if (additional->force_command != NULL) {
|
||||
if ((ret->force_command = strdup(
|
||||
additional->force_command)) == NULL)
|
||||
goto alloc_fail;
|
||||
}
|
||||
/* success */
|
||||
if (errstrp != NULL)
|
||||
*errstrp = NULL;
|
||||
return ret;
|
||||
|
||||
alloc_fail:
|
||||
errstr = "memory allocation failed";
|
||||
fail:
|
||||
if (errstrp != NULL)
|
||||
*errstrp = errstr;
|
||||
sshauthopt_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy options
|
||||
*/
|
||||
struct sshauthopt *
|
||||
sshauthopt_copy(const struct sshauthopt *orig)
|
||||
{
|
||||
struct sshauthopt *ret;
|
||||
|
||||
if ((ret = sshauthopt_new()) == NULL)
|
||||
return NULL;
|
||||
|
||||
#define OPTSCALAR(x) ret->x = orig->x
|
||||
OPTSCALAR(permit_port_forwarding_flag);
|
||||
OPTSCALAR(permit_agent_forwarding_flag);
|
||||
OPTSCALAR(permit_x11_forwarding_flag);
|
||||
OPTSCALAR(permit_pty_flag);
|
||||
OPTSCALAR(permit_user_rc);
|
||||
OPTSCALAR(restricted);
|
||||
OPTSCALAR(cert_authority);
|
||||
OPTSCALAR(force_tun_device);
|
||||
OPTSCALAR(valid_before);
|
||||
OPTSCALAR(no_require_user_presence);
|
||||
OPTSCALAR(require_verify);
|
||||
#undef OPTSCALAR
|
||||
#define OPTSTRING(x) \
|
||||
do { \
|
||||
if (orig->x != NULL && (ret->x = strdup(orig->x)) == NULL) { \
|
||||
sshauthopt_free(ret); \
|
||||
return NULL; \
|
||||
} \
|
||||
} while (0)
|
||||
OPTSTRING(cert_principals);
|
||||
OPTSTRING(force_command);
|
||||
OPTSTRING(required_from_host_cert);
|
||||
OPTSTRING(required_from_host_keys);
|
||||
#undef OPTSTRING
|
||||
|
||||
if (dup_strings(&ret->env, &ret->nenv, orig->env, orig->nenv) != 0 ||
|
||||
dup_strings(&ret->permitopen, &ret->npermitopen,
|
||||
orig->permitopen, orig->npermitopen) != 0 ||
|
||||
dup_strings(&ret->permitlisten, &ret->npermitlisten,
|
||||
orig->permitlisten, orig->npermitlisten) != 0) {
|
||||
sshauthopt_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
serialise_array(struct sshbuf *m, char **a, size_t n)
|
||||
{
|
||||
struct sshbuf *b;
|
||||
size_t i;
|
||||
int r = SSH_ERR_INTERNAL_ERROR;
|
||||
|
||||
if (n > INT_MAX)
|
||||
return SSH_ERR_INTERNAL_ERROR;
|
||||
|
||||
if ((b = sshbuf_new()) == NULL) {
|
||||
return SSH_ERR_ALLOC_FAIL;
|
||||
}
|
||||
for (i = 0; i < n; i++) {
|
||||
if ((r = sshbuf_put_cstring(b, a[i])) != 0)
|
||||
goto out;
|
||||
}
|
||||
if ((r = sshbuf_put_u32(m, n)) != 0 ||
|
||||
(r = sshbuf_put_stringb(m, b)) != 0)
|
||||
goto out;
|
||||
/* success */
|
||||
r = 0;
|
||||
out:
|
||||
sshbuf_free(b);
|
||||
return r;
|
||||
}
|
||||
|
||||
static int
|
||||
deserialise_array(struct sshbuf *m, char ***ap, size_t *np)
|
||||
{
|
||||
char **a = NULL;
|
||||
size_t i, n = 0;
|
||||
struct sshbuf *b = NULL;
|
||||
u_int tmp;
|
||||
int r = SSH_ERR_INTERNAL_ERROR;
|
||||
|
||||
if ((r = sshbuf_get_u32(m, &tmp)) != 0 ||
|
||||
(r = sshbuf_froms(m, &b)) != 0)
|
||||
goto out;
|
||||
if (tmp > INT_MAX) {
|
||||
r = SSH_ERR_INVALID_FORMAT;
|
||||
goto out;
|
||||
}
|
||||
n = tmp;
|
||||
if (n > 0 && (a = calloc(n, sizeof(*a))) == NULL) {
|
||||
r = SSH_ERR_ALLOC_FAIL;
|
||||
goto out;
|
||||
}
|
||||
for (i = 0; i < n; i++) {
|
||||
if ((r = sshbuf_get_cstring(b, &a[i], NULL)) != 0)
|
||||
goto out;
|
||||
}
|
||||
/* success */
|
||||
r = 0;
|
||||
*ap = a;
|
||||
a = NULL;
|
||||
*np = n;
|
||||
n = 0;
|
||||
out:
|
||||
if (a != NULL) {
|
||||
for (i = 0; i < n; i++)
|
||||
free(a[i]);
|
||||
free(a);
|
||||
}
|
||||
sshbuf_free(b);
|
||||
return r;
|
||||
}
|
||||
|
||||
static int
|
||||
serialise_nullable_string(struct sshbuf *m, const char *s)
|
||||
{
|
||||
int r;
|
||||
|
||||
if ((r = sshbuf_put_u8(m, s == NULL)) != 0 ||
|
||||
(r = sshbuf_put_cstring(m, s)) != 0)
|
||||
return r;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
deserialise_nullable_string(struct sshbuf *m, char **sp)
|
||||
{
|
||||
int r;
|
||||
u_char flag;
|
||||
|
||||
*sp = NULL;
|
||||
if ((r = sshbuf_get_u8(m, &flag)) != 0 ||
|
||||
(r = sshbuf_get_cstring(m, flag ? NULL : sp, NULL)) != 0)
|
||||
return r;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
sshauthopt_serialise(const struct sshauthopt *opts, struct sshbuf *m,
|
||||
int untrusted)
|
||||
{
|
||||
int r = SSH_ERR_INTERNAL_ERROR;
|
||||
|
||||
/* Flag options */
|
||||
if ((r = sshbuf_put_u8(m, opts->permit_port_forwarding_flag)) != 0 ||
|
||||
(r = sshbuf_put_u8(m, opts->permit_agent_forwarding_flag)) != 0 ||
|
||||
(r = sshbuf_put_u8(m, opts->permit_x11_forwarding_flag)) != 0 ||
|
||||
(r = sshbuf_put_u8(m, opts->permit_pty_flag)) != 0 ||
|
||||
(r = sshbuf_put_u8(m, opts->permit_user_rc)) != 0 ||
|
||||
(r = sshbuf_put_u8(m, opts->restricted)) != 0 ||
|
||||
(r = sshbuf_put_u8(m, opts->cert_authority)) != 0 ||
|
||||
(r = sshbuf_put_u8(m, opts->no_require_user_presence)) != 0 ||
|
||||
(r = sshbuf_put_u8(m, opts->require_verify)) != 0)
|
||||
return r;
|
||||
|
||||
/* Simple integer options */
|
||||
if ((r = sshbuf_put_u64(m, opts->valid_before)) != 0)
|
||||
return r;
|
||||
|
||||
/* tunnel number can be negative to indicate "unset" */
|
||||
if ((r = sshbuf_put_u8(m, opts->force_tun_device == -1)) != 0 ||
|
||||
(r = sshbuf_put_u32(m, (opts->force_tun_device < 0) ?
|
||||
0 : (u_int)opts->force_tun_device)) != 0)
|
||||
return r;
|
||||
|
||||
/* String options; these may be NULL */
|
||||
if ((r = serialise_nullable_string(m,
|
||||
untrusted ? "yes" : opts->cert_principals)) != 0 ||
|
||||
(r = serialise_nullable_string(m,
|
||||
untrusted ? "true" : opts->force_command)) != 0 ||
|
||||
(r = serialise_nullable_string(m,
|
||||
untrusted ? NULL : opts->required_from_host_cert)) != 0 ||
|
||||
(r = serialise_nullable_string(m,
|
||||
untrusted ? NULL : opts->required_from_host_keys)) != 0)
|
||||
return r;
|
||||
|
||||
/* Array options */
|
||||
if ((r = serialise_array(m, opts->env,
|
||||
untrusted ? 0 : opts->nenv)) != 0 ||
|
||||
(r = serialise_array(m, opts->permitopen,
|
||||
untrusted ? 0 : opts->npermitopen)) != 0 ||
|
||||
(r = serialise_array(m, opts->permitlisten,
|
||||
untrusted ? 0 : opts->npermitlisten)) != 0)
|
||||
return r;
|
||||
|
||||
/* success */
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
sshauthopt_deserialise(struct sshbuf *m, struct sshauthopt **optsp)
|
||||
{
|
||||
struct sshauthopt *opts = NULL;
|
||||
int r = SSH_ERR_INTERNAL_ERROR;
|
||||
u_char f;
|
||||
u_int tmp;
|
||||
|
||||
if ((opts = calloc(1, sizeof(*opts))) == NULL)
|
||||
return SSH_ERR_ALLOC_FAIL;
|
||||
|
||||
/* Flag options */
|
||||
#define OPT_FLAG(x) \
|
||||
do { \
|
||||
if ((r = sshbuf_get_u8(m, &f)) != 0) \
|
||||
goto out; \
|
||||
opts->x = f; \
|
||||
} while (0)
|
||||
OPT_FLAG(permit_port_forwarding_flag);
|
||||
OPT_FLAG(permit_agent_forwarding_flag);
|
||||
OPT_FLAG(permit_x11_forwarding_flag);
|
||||
OPT_FLAG(permit_pty_flag);
|
||||
OPT_FLAG(permit_user_rc);
|
||||
OPT_FLAG(restricted);
|
||||
OPT_FLAG(cert_authority);
|
||||
OPT_FLAG(no_require_user_presence);
|
||||
OPT_FLAG(require_verify);
|
||||
#undef OPT_FLAG
|
||||
|
||||
/* Simple integer options */
|
||||
if ((r = sshbuf_get_u64(m, &opts->valid_before)) != 0)
|
||||
goto out;
|
||||
|
||||
/* tunnel number can be negative to indicate "unset" */
|
||||
if ((r = sshbuf_get_u8(m, &f)) != 0 ||
|
||||
(r = sshbuf_get_u32(m, &tmp)) != 0)
|
||||
goto out;
|
||||
opts->force_tun_device = f ? -1 : (int)tmp;
|
||||
|
||||
/* String options may be NULL */
|
||||
if ((r = deserialise_nullable_string(m, &opts->cert_principals)) != 0 ||
|
||||
(r = deserialise_nullable_string(m, &opts->force_command)) != 0 ||
|
||||
(r = deserialise_nullable_string(m,
|
||||
&opts->required_from_host_cert)) != 0 ||
|
||||
(r = deserialise_nullable_string(m,
|
||||
&opts->required_from_host_keys)) != 0)
|
||||
goto out;
|
||||
|
||||
/* Array options */
|
||||
if ((r = deserialise_array(m, &opts->env, &opts->nenv)) != 0 ||
|
||||
(r = deserialise_array(m,
|
||||
&opts->permitopen, &opts->npermitopen)) != 0 ||
|
||||
(r = deserialise_array(m,
|
||||
&opts->permitlisten, &opts->npermitlisten)) != 0)
|
||||
goto out;
|
||||
|
||||
/* success */
|
||||
r = 0;
|
||||
*optsp = opts;
|
||||
opts = NULL;
|
||||
out:
|
||||
sshauthopt_free(opts);
|
||||
return r;
|
||||
}
|
106
auth-options.h
Normal file
106
auth-options.h
Normal file
|
@ -0,0 +1,106 @@
|
|||
/* $OpenBSD: auth-options.h,v 1.31 2021/07/23 03:57:20 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2018 Damien Miller <djm@mindrot.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef AUTH_OPTIONS_H
|
||||
#define AUTH_OPTIONS_H
|
||||
|
||||
struct passwd;
|
||||
struct sshkey;
|
||||
|
||||
/* Maximum number of permitopen/permitlisten directives to accept */
|
||||
#define SSH_AUTHOPT_PERMIT_MAX 4096
|
||||
|
||||
/* Maximum number of environment directives to accept */
|
||||
#define SSH_AUTHOPT_ENV_MAX 1024
|
||||
|
||||
/*
|
||||
* sshauthopt represents key options parsed from authorized_keys or
|
||||
* from certificate extensions/options.
|
||||
*/
|
||||
struct sshauthopt {
|
||||
/* Feature flags */
|
||||
int permit_port_forwarding_flag;
|
||||
int permit_agent_forwarding_flag;
|
||||
int permit_x11_forwarding_flag;
|
||||
int permit_pty_flag;
|
||||
int permit_user_rc;
|
||||
|
||||
/* "restrict" keyword was invoked */
|
||||
int restricted;
|
||||
|
||||
/* key/principal expiry date */
|
||||
uint64_t valid_before;
|
||||
|
||||
/* Certificate-related options */
|
||||
int cert_authority;
|
||||
char *cert_principals;
|
||||
|
||||
int force_tun_device;
|
||||
char *force_command;
|
||||
|
||||
/* Custom environment */
|
||||
size_t nenv;
|
||||
char **env;
|
||||
|
||||
/* Permitted port forwardings */
|
||||
size_t npermitopen;
|
||||
char **permitopen;
|
||||
|
||||
/* Permitted listens (remote forwarding) */
|
||||
size_t npermitlisten;
|
||||
char **permitlisten;
|
||||
|
||||
/*
|
||||
* Permitted host/addresses (comma-separated)
|
||||
* Caller must check source address matches both lists (if present).
|
||||
*/
|
||||
char *required_from_host_cert;
|
||||
char *required_from_host_keys;
|
||||
|
||||
/* Key requires user presence asserted */
|
||||
int no_require_user_presence;
|
||||
/* Key requires user verification (e.g. PIN) */
|
||||
int require_verify;
|
||||
};
|
||||
|
||||
struct sshauthopt *sshauthopt_new(void);
|
||||
struct sshauthopt *sshauthopt_new_with_keys_defaults(void);
|
||||
void sshauthopt_free(struct sshauthopt *opts);
|
||||
struct sshauthopt *sshauthopt_copy(const struct sshauthopt *orig);
|
||||
int sshauthopt_serialise(const struct sshauthopt *opts, struct sshbuf *m, int);
|
||||
int sshauthopt_deserialise(struct sshbuf *m, struct sshauthopt **opts);
|
||||
|
||||
/*
|
||||
* Parse authorized_keys options. Returns an options structure on success
|
||||
* or NULL on failure. Will set errstr on failure.
|
||||
*/
|
||||
struct sshauthopt *sshauthopt_parse(const char *s, const char **errstr);
|
||||
|
||||
/*
|
||||
* Parse certification options to a struct sshauthopt.
|
||||
* Returns options on success or NULL on failure.
|
||||
*/
|
||||
struct sshauthopt *sshauthopt_from_cert(struct sshkey *k);
|
||||
|
||||
/*
|
||||
* Merge key options.
|
||||
*/
|
||||
struct sshauthopt *sshauthopt_merge(const struct sshauthopt *primary,
|
||||
const struct sshauthopt *additional, const char **errstrp);
|
||||
|
||||
#endif
|
1410
auth-pam.c
Normal file
1410
auth-pam.c
Normal file
File diff suppressed because it is too large
Load diff
47
auth-pam.h
Normal file
47
auth-pam.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (c) 2000 Damien Miller. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#ifdef USE_PAM
|
||||
|
||||
struct ssh;
|
||||
|
||||
void start_pam(struct ssh *);
|
||||
void finish_pam(void);
|
||||
u_int do_pam_account(void);
|
||||
void do_pam_session(struct ssh *);
|
||||
void do_pam_setcred(void);
|
||||
void do_pam_chauthtok(void);
|
||||
int do_pam_putenv(char *, char *);
|
||||
char ** fetch_pam_environment(void);
|
||||
char ** fetch_pam_child_environment(void);
|
||||
void free_pam_environment(char **);
|
||||
void sshpam_thread_cleanup(void);
|
||||
void sshpam_cleanup(void);
|
||||
int sshpam_auth_passwd(Authctxt *, const char *);
|
||||
int sshpam_get_maxtries_reached(void);
|
||||
void sshpam_set_maxtries_reached(int);
|
||||
int is_pam_session_open(void);
|
||||
|
||||
#endif /* USE_PAM */
|
223
auth-passwd.c
Normal file
223
auth-passwd.c
Normal file
|
@ -0,0 +1,223 @@
|
|||
/* $OpenBSD: auth-passwd.c,v 1.48 2020/10/18 11:32:01 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
* All rights reserved
|
||||
* Password authentication. This file contains the functions to check whether
|
||||
* the password is valid for the user.
|
||||
*
|
||||
* As far as I am concerned, the code I have written for this software
|
||||
* can be used freely for any purpose. Any derived versions of this
|
||||
* software must be clearly marked as such, and if the derived work is
|
||||
* incompatible with the protocol description in the RFC file, it must be
|
||||
* called by a name other than "ssh" or "Secure Shell".
|
||||
*
|
||||
* Copyright (c) 1999 Dug Song. All rights reserved.
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "packet.h"
|
||||
#include "sshbuf.h"
|
||||
#include "ssherr.h"
|
||||
#include "log.h"
|
||||
#include "misc.h"
|
||||
#include "servconf.h"
|
||||
#include "sshkey.h"
|
||||
#include "hostfile.h"
|
||||
#include "auth.h"
|
||||
#include "auth-options.h"
|
||||
|
||||
extern struct sshbuf *loginmsg;
|
||||
extern ServerOptions options;
|
||||
|
||||
#ifdef HAVE_LOGIN_CAP
|
||||
extern login_cap_t *lc;
|
||||
#endif
|
||||
|
||||
|
||||
#define DAY (24L * 60 * 60) /* 1 day in seconds */
|
||||
#define TWO_WEEKS (2L * 7 * DAY) /* 2 weeks in seconds */
|
||||
|
||||
#define MAX_PASSWORD_LEN 1024
|
||||
|
||||
/*
|
||||
* Tries to authenticate the user using password. Returns true if
|
||||
* authentication succeeds.
|
||||
*/
|
||||
int
|
||||
auth_password(struct ssh *ssh, const char *password)
|
||||
{
|
||||
Authctxt *authctxt = ssh->authctxt;
|
||||
struct passwd *pw = authctxt->pw;
|
||||
int result, ok = authctxt->valid;
|
||||
#if defined(USE_SHADOW) && defined(HAS_SHADOW_EXPIRE)
|
||||
static int expire_checked = 0;
|
||||
#endif
|
||||
|
||||
if (strlen(password) > MAX_PASSWORD_LEN)
|
||||
return 0;
|
||||
|
||||
#ifndef HAVE_CYGWIN
|
||||
if (pw->pw_uid == 0 && options.permit_root_login != PERMIT_YES)
|
||||
ok = 0;
|
||||
#endif
|
||||
if (*password == '\0' && options.permit_empty_passwd == 0)
|
||||
return 0;
|
||||
|
||||
#ifdef KRB5
|
||||
if (options.kerberos_authentication == 1) {
|
||||
int ret = auth_krb5_password(authctxt, password);
|
||||
if (ret == 1 || ret == 0)
|
||||
return ret && ok;
|
||||
/* Fall back to ordinary passwd authentication. */
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_CYGWIN
|
||||
{
|
||||
HANDLE hToken = cygwin_logon_user(pw, password);
|
||||
|
||||
if (hToken == INVALID_HANDLE_VALUE)
|
||||
return 0;
|
||||
cygwin_set_impersonation_token(hToken);
|
||||
return ok;
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_PAM
|
||||
if (options.use_pam)
|
||||
return (sshpam_auth_passwd(authctxt, password) && ok);
|
||||
#endif
|
||||
#if defined(USE_SHADOW) && defined(HAS_SHADOW_EXPIRE)
|
||||
if (!expire_checked) {
|
||||
expire_checked = 1;
|
||||
if (auth_shadow_pwexpired(authctxt))
|
||||
authctxt->force_pwchange = 1;
|
||||
}
|
||||
#endif
|
||||
result = sys_auth_passwd(ssh, password);
|
||||
if (authctxt->force_pwchange)
|
||||
auth_restrict_session(ssh);
|
||||
return (result && ok);
|
||||
}
|
||||
|
||||
#ifdef BSD_AUTH
|
||||
static void
|
||||
warn_expiry(Authctxt *authctxt, auth_session_t *as)
|
||||
{
|
||||
int r;
|
||||
quad_t pwtimeleft, actimeleft, daysleft, pwwarntime, acwarntime;
|
||||
|
||||
pwwarntime = acwarntime = TWO_WEEKS;
|
||||
|
||||
pwtimeleft = auth_check_change(as);
|
||||
actimeleft = auth_check_expire(as);
|
||||
#ifdef HAVE_LOGIN_CAP
|
||||
if (authctxt->valid) {
|
||||
pwwarntime = login_getcaptime(lc, "password-warn", TWO_WEEKS,
|
||||
TWO_WEEKS);
|
||||
acwarntime = login_getcaptime(lc, "expire-warn", TWO_WEEKS,
|
||||
TWO_WEEKS);
|
||||
}
|
||||
#endif
|
||||
if (pwtimeleft != 0 && pwtimeleft < pwwarntime) {
|
||||
daysleft = pwtimeleft / DAY + 1;
|
||||
if ((r = sshbuf_putf(loginmsg,
|
||||
"Your password will expire in %lld day%s.\n",
|
||||
daysleft, daysleft == 1 ? "" : "s")) != 0)
|
||||
fatal_fr(r, "buffer error");
|
||||
}
|
||||
if (actimeleft != 0 && actimeleft < acwarntime) {
|
||||
daysleft = actimeleft / DAY + 1;
|
||||
if ((r = sshbuf_putf(loginmsg,
|
||||
"Your account will expire in %lld day%s.\n",
|
||||
daysleft, daysleft == 1 ? "" : "s")) != 0)
|
||||
fatal_fr(r, "buffer error");
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
sys_auth_passwd(struct ssh *ssh, const char *password)
|
||||
{
|
||||
Authctxt *authctxt = ssh->authctxt;
|
||||
auth_session_t *as;
|
||||
static int expire_checked = 0;
|
||||
|
||||
as = auth_usercheck(authctxt->pw->pw_name, authctxt->style, "auth-ssh",
|
||||
(char *)password);
|
||||
if (as == NULL)
|
||||
return (0);
|
||||
if (auth_getstate(as) & AUTH_PWEXPIRED) {
|
||||
auth_close(as);
|
||||
auth_restrict_session(ssh);
|
||||
authctxt->force_pwchange = 1;
|
||||
return (1);
|
||||
} else {
|
||||
if (!expire_checked) {
|
||||
expire_checked = 1;
|
||||
warn_expiry(authctxt, as);
|
||||
}
|
||||
return (auth_close(as));
|
||||
}
|
||||
}
|
||||
#elif !defined(CUSTOM_SYS_AUTH_PASSWD)
|
||||
int
|
||||
sys_auth_passwd(struct ssh *ssh, const char *password)
|
||||
{
|
||||
Authctxt *authctxt = ssh->authctxt;
|
||||
struct passwd *pw = authctxt->pw;
|
||||
char *encrypted_password, *salt = NULL;
|
||||
|
||||
/* Just use the supplied fake password if authctxt is invalid */
|
||||
char *pw_password = authctxt->valid ? shadow_pw(pw) : pw->pw_passwd;
|
||||
|
||||
if (pw_password == NULL)
|
||||
return 0;
|
||||
|
||||
/* Check for users with no password. */
|
||||
if (strcmp(pw_password, "") == 0 && strcmp(password, "") == 0)
|
||||
return (1);
|
||||
|
||||
/*
|
||||
* Encrypt the candidate password using the proper salt, or pass a
|
||||
* NULL and let xcrypt pick one.
|
||||
*/
|
||||
if (authctxt->valid && pw_password[0] && pw_password[1])
|
||||
salt = pw_password;
|
||||
encrypted_password = xcrypt(password, salt);
|
||||
|
||||
/*
|
||||
* Authentication is accepted if the encrypted passwords
|
||||
* are identical.
|
||||
*/
|
||||
return encrypted_password != NULL &&
|
||||
strcmp(encrypted_password, pw_password) == 0;
|
||||
}
|
||||
#endif
|
337
auth-rhosts.c
Normal file
337
auth-rhosts.c
Normal file
|
@ -0,0 +1,337 @@
|
|||
/* $OpenBSD: auth-rhosts.c,v 1.58 2024/05/17 00:30:23 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
* All rights reserved
|
||||
* Rhosts authentication. This file contains code to check whether to admit
|
||||
* the login based on rhosts authentication. This file also processes
|
||||
* /etc/hosts.equiv.
|
||||
*
|
||||
* As far as I am concerned, the code I have written for this software
|
||||
* can be used freely for any purpose. Any derived versions of this
|
||||
* software must be clearly marked as such, and if the derived work is
|
||||
* incompatible with the protocol description in the RFC file, it must be
|
||||
* called by a name other than "ssh" or "Secure Shell".
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#ifdef HAVE_NETGROUP_H
|
||||
# include <netgroup.h>
|
||||
#endif
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "packet.h"
|
||||
#include "uidswap.h"
|
||||
#include "pathnames.h"
|
||||
#include "log.h"
|
||||
#include "misc.h"
|
||||
#include "xmalloc.h"
|
||||
#include "sshbuf.h"
|
||||
#include "sshkey.h"
|
||||
#include "servconf.h"
|
||||
#include "canohost.h"
|
||||
#include "hostfile.h"
|
||||
#include "auth.h"
|
||||
|
||||
/* import */
|
||||
extern ServerOptions options;
|
||||
|
||||
/*
|
||||
* This function processes an rhosts-style file (.rhosts, .shosts, or
|
||||
* /etc/hosts.equiv). This returns true if authentication can be granted
|
||||
* based on the file, and returns zero otherwise.
|
||||
*/
|
||||
|
||||
static int
|
||||
check_rhosts_file(const char *filename, const char *hostname,
|
||||
const char *ipaddr, const char *client_user,
|
||||
const char *server_user)
|
||||
{
|
||||
FILE *f;
|
||||
#define RBUFLN 1024
|
||||
char buf[RBUFLN];/* Must not be larger than host, user, dummy below. */
|
||||
int fd;
|
||||
struct stat st;
|
||||
|
||||
/* Open the .rhosts file, deny if unreadable */
|
||||
if ((fd = open(filename, O_RDONLY|O_NONBLOCK)) == -1)
|
||||
return 0;
|
||||
if (fstat(fd, &st) == -1) {
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
if (!S_ISREG(st.st_mode)) {
|
||||
logit("User %s hosts file %s is not a regular file",
|
||||
server_user, filename);
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
unset_nonblock(fd);
|
||||
if ((f = fdopen(fd, "r")) == NULL) {
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
while (fgets(buf, sizeof(buf), f)) {
|
||||
/* All three must have length >= buf to avoid overflows. */
|
||||
char hostbuf[RBUFLN], userbuf[RBUFLN], dummy[RBUFLN];
|
||||
char *host, *user, *cp;
|
||||
int negated;
|
||||
|
||||
for (cp = buf; *cp == ' ' || *cp == '\t'; cp++)
|
||||
;
|
||||
if (*cp == '#' || *cp == '\n' || !*cp)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* NO_PLUS is supported at least on OSF/1. We skip it (we
|
||||
* don't ever support the plus syntax).
|
||||
*/
|
||||
if (strncmp(cp, "NO_PLUS", 7) == 0)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* This should be safe because each buffer is as big as the
|
||||
* whole string, and thus cannot be overwritten.
|
||||
*/
|
||||
switch (sscanf(buf, "%1023s %1023s %1023s", hostbuf, userbuf,
|
||||
dummy)) {
|
||||
case 0:
|
||||
auth_debug_add("Found empty line in %.100s.", filename);
|
||||
continue;
|
||||
case 1:
|
||||
/* Host name only. */
|
||||
strlcpy(userbuf, server_user, sizeof(userbuf));
|
||||
break;
|
||||
case 2:
|
||||
/* Got both host and user name. */
|
||||
break;
|
||||
case 3:
|
||||
auth_debug_add("Found garbage in %.100s.", filename);
|
||||
continue;
|
||||
default:
|
||||
/* Weird... */
|
||||
continue;
|
||||
}
|
||||
|
||||
host = hostbuf;
|
||||
user = userbuf;
|
||||
negated = 0;
|
||||
|
||||
/* Process negated host names, or positive netgroups. */
|
||||
if (host[0] == '-') {
|
||||
negated = 1;
|
||||
host++;
|
||||
} else if (host[0] == '+')
|
||||
host++;
|
||||
|
||||
if (user[0] == '-') {
|
||||
negated = 1;
|
||||
user++;
|
||||
} else if (user[0] == '+')
|
||||
user++;
|
||||
|
||||
/* Check for empty host/user names (particularly '+'). */
|
||||
if (!host[0] || !user[0]) {
|
||||
/* We come here if either was '+' or '-'. */
|
||||
auth_debug_add("Ignoring wild host/user names "
|
||||
"in %.100s.", filename);
|
||||
continue;
|
||||
}
|
||||
/* Verify that host name matches. */
|
||||
if (host[0] == '@') {
|
||||
if (!innetgr(host + 1, hostname, NULL, NULL) &&
|
||||
!innetgr(host + 1, ipaddr, NULL, NULL))
|
||||
continue;
|
||||
} else if (strcasecmp(host, hostname) &&
|
||||
strcmp(host, ipaddr) != 0)
|
||||
continue; /* Different hostname. */
|
||||
|
||||
/* Verify that user name matches. */
|
||||
if (user[0] == '@') {
|
||||
if (!innetgr(user + 1, NULL, client_user, NULL))
|
||||
continue;
|
||||
} else if (strcmp(user, client_user) != 0)
|
||||
continue; /* Different username. */
|
||||
|
||||
/* Found the user and host. */
|
||||
fclose(f);
|
||||
|
||||
/* If the entry was negated, deny access. */
|
||||
if (negated) {
|
||||
auth_debug_add("Matched negative entry in %.100s.",
|
||||
filename);
|
||||
return 0;
|
||||
}
|
||||
/* Accept authentication. */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Authentication using this file denied. */
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Tries to authenticate the user using the .shosts or .rhosts file. Returns
|
||||
* true if authentication succeeds. If ignore_rhosts is true, only
|
||||
* /etc/hosts.equiv will be considered (.rhosts and .shosts are ignored).
|
||||
*/
|
||||
int
|
||||
auth_rhosts2(struct passwd *pw, const char *client_user, const char *hostname,
|
||||
const char *ipaddr)
|
||||
{
|
||||
char *path = NULL;
|
||||
struct stat st;
|
||||
static const char * const rhosts_files[] = {".shosts", ".rhosts", NULL};
|
||||
u_int rhosts_file_index;
|
||||
int r;
|
||||
|
||||
debug2_f("clientuser %s hostname %s ipaddr %s",
|
||||
client_user, hostname, ipaddr);
|
||||
|
||||
/* Switch to the user's uid. */
|
||||
temporarily_use_uid(pw);
|
||||
/*
|
||||
* Quick check: if the user has no .shosts or .rhosts files and
|
||||
* no system hosts.equiv/shosts.equiv files exist then return
|
||||
* failure immediately without doing costly lookups from name
|
||||
* servers.
|
||||
*/
|
||||
for (rhosts_file_index = 0; rhosts_files[rhosts_file_index];
|
||||
rhosts_file_index++) {
|
||||
/* Check users .rhosts or .shosts. */
|
||||
xasprintf(&path, "%s/%s",
|
||||
pw->pw_dir, rhosts_files[rhosts_file_index]);
|
||||
r = stat(path, &st);
|
||||
free(path);
|
||||
if (r >= 0)
|
||||
break;
|
||||
}
|
||||
/* Switch back to privileged uid. */
|
||||
restore_uid();
|
||||
|
||||
/*
|
||||
* Deny if The user has no .shosts or .rhosts file and there
|
||||
* are no system-wide files.
|
||||
*/
|
||||
if (!rhosts_files[rhosts_file_index] &&
|
||||
stat(_PATH_RHOSTS_EQUIV, &st) == -1 &&
|
||||
stat(_PATH_SSH_HOSTS_EQUIV, &st) == -1) {
|
||||
debug3_f("no hosts access files exist");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* If not logging in as superuser, try /etc/hosts.equiv and
|
||||
* shosts.equiv.
|
||||
*/
|
||||
if (pw->pw_uid == 0)
|
||||
debug3_f("root user, ignoring system hosts files");
|
||||
else {
|
||||
if (check_rhosts_file(_PATH_RHOSTS_EQUIV, hostname, ipaddr,
|
||||
client_user, pw->pw_name)) {
|
||||
auth_debug_add("Accepted for %.100s [%.100s] by "
|
||||
"/etc/hosts.equiv.", hostname, ipaddr);
|
||||
return 1;
|
||||
}
|
||||
if (check_rhosts_file(_PATH_SSH_HOSTS_EQUIV, hostname, ipaddr,
|
||||
client_user, pw->pw_name)) {
|
||||
auth_debug_add("Accepted for %.100s [%.100s] by "
|
||||
"%.100s.", hostname, ipaddr, _PATH_SSH_HOSTS_EQUIV);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that the home directory is owned by root or the user, and is
|
||||
* not group or world writable.
|
||||
*/
|
||||
if (stat(pw->pw_dir, &st) == -1) {
|
||||
logit("Rhosts authentication refused for %.100s: "
|
||||
"no home directory %.200s", pw->pw_name, pw->pw_dir);
|
||||
auth_debug_add("Rhosts authentication refused for %.100s: "
|
||||
"no home directory %.200s", pw->pw_name, pw->pw_dir);
|
||||
return 0;
|
||||
}
|
||||
if (options.strict_modes &&
|
||||
((st.st_uid != 0 && st.st_uid != pw->pw_uid) ||
|
||||
(st.st_mode & 022) != 0)) {
|
||||
logit("Rhosts authentication refused for %.100s: "
|
||||
"bad ownership or modes for home directory.", pw->pw_name);
|
||||
auth_debug_add("Rhosts authentication refused for %.100s: "
|
||||
"bad ownership or modes for home directory.", pw->pw_name);
|
||||
return 0;
|
||||
}
|
||||
/* Temporarily use the user's uid. */
|
||||
temporarily_use_uid(pw);
|
||||
|
||||
/* Check all .rhosts files (currently .shosts and .rhosts). */
|
||||
for (rhosts_file_index = 0; rhosts_files[rhosts_file_index];
|
||||
rhosts_file_index++) {
|
||||
/* Check users .rhosts or .shosts. */
|
||||
xasprintf(&path, "%s/%s",
|
||||
pw->pw_dir, rhosts_files[rhosts_file_index]);
|
||||
if (stat(path, &st) == -1) {
|
||||
debug3_f("stat %s: %s", path, strerror(errno));
|
||||
free(path);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure that the file is either owned by the user or by
|
||||
* root, and make sure it is not writable by anyone but the
|
||||
* owner. This is to help avoid novices accidentally
|
||||
* allowing access to their account by anyone.
|
||||
*/
|
||||
if (options.strict_modes &&
|
||||
((st.st_uid != 0 && st.st_uid != pw->pw_uid) ||
|
||||
(st.st_mode & 022) != 0)) {
|
||||
logit("Rhosts authentication refused for %.100s: "
|
||||
"bad modes for %.200s", pw->pw_name, path);
|
||||
auth_debug_add("Bad file modes for %.200s", path);
|
||||
free(path);
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
* Check if we have been configured to ignore .rhosts
|
||||
* and .shosts files.
|
||||
*/
|
||||
if (options.ignore_rhosts == IGNORE_RHOSTS_YES ||
|
||||
(options.ignore_rhosts == IGNORE_RHOSTS_SHOSTS &&
|
||||
strcmp(rhosts_files[rhosts_file_index], ".shosts") != 0)) {
|
||||
auth_debug_add("Server has been configured to "
|
||||
"ignore %.100s.", rhosts_files[rhosts_file_index]);
|
||||
free(path);
|
||||
continue;
|
||||
}
|
||||
/* Check if authentication is permitted by the file. */
|
||||
if (check_rhosts_file(path, hostname, ipaddr,
|
||||
client_user, pw->pw_name)) {
|
||||
auth_debug_add("Accepted by %.100s.",
|
||||
rhosts_files[rhosts_file_index]);
|
||||
/* Restore the privileged uid. */
|
||||
restore_uid();
|
||||
auth_debug_add("Accepted host %s ip %s client_user "
|
||||
"%s server_user %s", hostname, ipaddr,
|
||||
client_user, pw->pw_name);
|
||||
free(path);
|
||||
return 1;
|
||||
}
|
||||
free(path);
|
||||
}
|
||||
|
||||
/* Restore the privileged uid. */
|
||||
restore_uid();
|
||||
return 0;
|
||||
}
|
141
auth-shadow.c
Normal file
141
auth-shadow.c
Normal file
|
@ -0,0 +1,141 @@
|
|||
/*
|
||||
* Copyright (c) 2004 Darren Tucker. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#if defined(USE_SHADOW) && defined(HAS_SHADOW_EXPIRE)
|
||||
#include <shadow.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "hostfile.h"
|
||||
#include "auth.h"
|
||||
#include "sshbuf.h"
|
||||
#include "ssherr.h"
|
||||
#include "log.h"
|
||||
|
||||
#ifdef DAY
|
||||
# undef DAY
|
||||
#endif
|
||||
#define DAY (24L * 60 * 60) /* 1 day in seconds */
|
||||
|
||||
extern struct sshbuf *loginmsg;
|
||||
|
||||
/*
|
||||
* For the account and password expiration functions, we assume the expiry
|
||||
* occurs the day after the day specified.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Check if specified account is expired. Returns 1 if account is expired,
|
||||
* 0 otherwise.
|
||||
*/
|
||||
int
|
||||
auth_shadow_acctexpired(struct spwd *spw)
|
||||
{
|
||||
time_t today;
|
||||
long long daysleft;
|
||||
int r;
|
||||
|
||||
today = time(NULL) / DAY;
|
||||
daysleft = spw->sp_expire - today;
|
||||
debug3("%s: today %lld sp_expire %lld days left %lld", __func__,
|
||||
(long long)today, (long long)spw->sp_expire, daysleft);
|
||||
|
||||
if (spw->sp_expire == -1) {
|
||||
debug3("account expiration disabled");
|
||||
} else if (daysleft < 0) {
|
||||
logit("Account %.100s has expired", spw->sp_namp);
|
||||
return 1;
|
||||
} else if (daysleft <= spw->sp_warn) {
|
||||
debug3("account will expire in %lld days", daysleft);
|
||||
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));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks password expiry for platforms that use shadow passwd files.
|
||||
* Returns: 1 = password expired, 0 = password not expired
|
||||
*/
|
||||
int
|
||||
auth_shadow_pwexpired(Authctxt *ctxt)
|
||||
{
|
||||
struct spwd *spw = NULL;
|
||||
const char *user = ctxt->pw->pw_name;
|
||||
time_t today;
|
||||
int r, daysleft, disabled = 0;
|
||||
|
||||
if ((spw = getspnam((char *)user)) == NULL) {
|
||||
error("Could not get shadow information for %.100s", user);
|
||||
return 0;
|
||||
}
|
||||
|
||||
today = time(NULL) / DAY;
|
||||
debug3_f("today %lld sp_lstchg %lld sp_max %lld", (long long)today,
|
||||
(long long)spw->sp_lstchg, (long long)spw->sp_max);
|
||||
|
||||
#if defined(__hpux) && !defined(HAVE_SECUREWARE)
|
||||
if (iscomsec()) {
|
||||
struct pr_passwd *pr;
|
||||
|
||||
pr = getprpwnam((char *)user);
|
||||
|
||||
/* Test for Trusted Mode expiry disabled */
|
||||
if (pr != NULL && pr->ufld.fd_min == 0 &&
|
||||
pr->ufld.fd_lifetime == 0 && pr->ufld.fd_expire == 0 &&
|
||||
pr->ufld.fd_pw_expire_warning == 0 &&
|
||||
pr->ufld.fd_schange != 0)
|
||||
disabled = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* TODO: check sp_inact */
|
||||
daysleft = spw->sp_lstchg + spw->sp_max - today;
|
||||
if (disabled) {
|
||||
debug3("password expiration disabled");
|
||||
} else if (spw->sp_lstchg == 0) {
|
||||
logit("User %.100s password has expired (root forced)", user);
|
||||
return 1;
|
||||
} else if (spw->sp_max == -1) {
|
||||
debug3("password expiration disabled");
|
||||
} else if (daysleft < 0) {
|
||||
logit("User %.100s password has expired (password aged)", user);
|
||||
return 1;
|
||||
} else if (daysleft <= spw->sp_warn) {
|
||||
debug3("password will expire in %d days", daysleft);
|
||||
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));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* USE_SHADOW && HAS_SHADOW_EXPIRE */
|
115
auth-sia.c
Normal file
115
auth-sia.c
Normal file
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
* Copyright (c) 2002 Chris Adams. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#ifdef HAVE_OSF_SIA
|
||||
#include <sia.h>
|
||||
#include <siad.h>
|
||||
#include <pwd.h>
|
||||
#include <signal.h>
|
||||
#include <setjmp.h>
|
||||
#include <sys/resource.h>
|
||||
#include <unistd.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "ssh.h"
|
||||
#include "ssh_api.h"
|
||||
#include "hostfile.h"
|
||||
#include "auth.h"
|
||||
#include "auth-sia.h"
|
||||
#include "log.h"
|
||||
#include "servconf.h"
|
||||
#include "canohost.h"
|
||||
#include "uidswap.h"
|
||||
|
||||
extern ServerOptions options;
|
||||
extern int saved_argc;
|
||||
extern char **saved_argv;
|
||||
|
||||
int
|
||||
sys_auth_passwd(struct ssh *ssh, const char *pass)
|
||||
{
|
||||
int ret;
|
||||
SIAENTITY *ent = NULL;
|
||||
const char *host;
|
||||
Authctxt *authctxt = ssh->authctxt;
|
||||
|
||||
host = get_canonical_hostname(options.use_dns);
|
||||
|
||||
if (!authctxt->user || pass == NULL || pass[0] == '\0')
|
||||
return (0);
|
||||
|
||||
if (sia_ses_init(&ent, saved_argc, saved_argv, host, authctxt->user,
|
||||
NULL, 0, NULL) != SIASUCCESS)
|
||||
return (0);
|
||||
|
||||
if ((ret = sia_ses_authent(NULL, pass, ent)) != SIASUCCESS) {
|
||||
error("Couldn't authenticate %s from %s",
|
||||
authctxt->user, host);
|
||||
if (ret & SIASTOP)
|
||||
sia_ses_release(&ent);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
sia_ses_release(&ent);
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
void
|
||||
session_setup_sia(struct passwd *pw, char *tty)
|
||||
{
|
||||
SIAENTITY *ent = NULL;
|
||||
const char *host;
|
||||
|
||||
host = get_canonical_hostname(options.use_dns);
|
||||
|
||||
if (sia_ses_init(&ent, saved_argc, saved_argv, host, pw->pw_name,
|
||||
tty, 0, NULL) != SIASUCCESS)
|
||||
fatal("sia_ses_init failed");
|
||||
|
||||
if (sia_make_entity_pwd(pw, ent) != SIASUCCESS) {
|
||||
sia_ses_release(&ent);
|
||||
fatal("sia_make_entity_pwd failed");
|
||||
}
|
||||
|
||||
ent->authtype = SIA_A_NONE;
|
||||
if (sia_ses_estab(sia_collect_trm, ent) != SIASUCCESS)
|
||||
fatal("Couldn't establish session for %s from %s",
|
||||
pw->pw_name, host);
|
||||
|
||||
if (sia_ses_launch(sia_collect_trm, ent) != SIASUCCESS)
|
||||
fatal("Couldn't launch session for %s from %s",
|
||||
pw->pw_name, host);
|
||||
|
||||
sia_ses_release(&ent);
|
||||
|
||||
setuid(0);
|
||||
permanently_set_uid(pw);
|
||||
}
|
||||
|
||||
#endif /* HAVE_OSF_SIA */
|
31
auth-sia.h
Normal file
31
auth-sia.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright (c) 2002 Chris Adams. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#ifdef HAVE_OSF_SIA
|
||||
|
||||
void session_setup_sia(struct passwd *, char *);
|
||||
|
||||
#endif /* HAVE_OSF_SIA */
|
781
auth.c
Normal file
781
auth.c
Normal file
|
@ -0,0 +1,781 @@
|
|||
/* $OpenBSD: auth.c,v 1.162 2024/09/15 01:18:26 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"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#ifdef HAVE_PATHS_H
|
||||
# include <paths.h>
|
||||
#endif
|
||||
#include <pwd.h>
|
||||
#ifdef HAVE_LOGIN_H
|
||||
#include <login.h>
|
||||
#endif
|
||||
#ifdef USE_SHADOW
|
||||
#include <shadow.h>
|
||||
#endif
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <limits.h>
|
||||
#include <netdb.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "match.h"
|
||||
#include "groupaccess.h"
|
||||
#include "log.h"
|
||||
#include "sshbuf.h"
|
||||
#include "misc.h"
|
||||
#include "servconf.h"
|
||||
#include "sshkey.h"
|
||||
#include "hostfile.h"
|
||||
#include "auth.h"
|
||||
#include "auth-options.h"
|
||||
#include "canohost.h"
|
||||
#include "uidswap.h"
|
||||
#include "packet.h"
|
||||
#include "loginrec.h"
|
||||
#ifdef GSSAPI
|
||||
#include "ssh-gss.h"
|
||||
#endif
|
||||
#include "authfile.h"
|
||||
#include "monitor_wrap.h"
|
||||
#include "ssherr.h"
|
||||
#include "channels.h"
|
||||
|
||||
/* import */
|
||||
extern ServerOptions options;
|
||||
extern struct include_list includes;
|
||||
extern struct sshbuf *loginmsg;
|
||||
extern struct passwd *privsep_pw;
|
||||
extern struct sshauthopt *auth_opts;
|
||||
|
||||
/* Debugging messages */
|
||||
static struct sshbuf *auth_debug;
|
||||
|
||||
/*
|
||||
* Check if the user is allowed to log in via ssh. If user is listed
|
||||
* in DenyUsers or one of user's groups is listed in DenyGroups, false
|
||||
* will be returned. If AllowUsers isn't empty and user isn't listed
|
||||
* there, or if AllowGroups isn't empty and one of user's groups isn't
|
||||
* listed there, false will be returned.
|
||||
* If the user's shell is not executable, false will be returned.
|
||||
* Otherwise true is returned.
|
||||
*/
|
||||
int
|
||||
allowed_user(struct ssh *ssh, struct passwd * pw)
|
||||
{
|
||||
struct stat st;
|
||||
const char *hostname = NULL, *ipaddr = NULL;
|
||||
u_int i;
|
||||
int r;
|
||||
|
||||
/* Shouldn't be called if pw is NULL, but better safe than sorry... */
|
||||
if (!pw || !pw->pw_name)
|
||||
return 0;
|
||||
|
||||
if (!options.use_pam && platform_locked_account(pw)) {
|
||||
logit("User %.100s not allowed because account is locked",
|
||||
pw->pw_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Deny if shell does not exist or is not executable unless we
|
||||
* are chrooting.
|
||||
*/
|
||||
if (options.chroot_directory == NULL ||
|
||||
strcasecmp(options.chroot_directory, "none") == 0) {
|
||||
char *shell = xstrdup((pw->pw_shell[0] == '\0') ?
|
||||
_PATH_BSHELL : pw->pw_shell); /* empty = /bin/sh */
|
||||
|
||||
if (stat(shell, &st) == -1) {
|
||||
logit("User %.100s not allowed because shell %.100s "
|
||||
"does not exist", pw->pw_name, shell);
|
||||
free(shell);
|
||||
return 0;
|
||||
}
|
||||
if (S_ISREG(st.st_mode) == 0 ||
|
||||
(st.st_mode & (S_IXOTH|S_IXUSR|S_IXGRP)) == 0) {
|
||||
logit("User %.100s not allowed because shell %.100s "
|
||||
"is not executable", pw->pw_name, shell);
|
||||
free(shell);
|
||||
return 0;
|
||||
}
|
||||
free(shell);
|
||||
}
|
||||
|
||||
if (options.num_deny_users > 0 || options.num_allow_users > 0 ||
|
||||
options.num_deny_groups > 0 || options.num_allow_groups > 0) {
|
||||
hostname = auth_get_canonical_hostname(ssh, options.use_dns);
|
||||
ipaddr = ssh_remote_ipaddr(ssh);
|
||||
}
|
||||
|
||||
/* Return false if user is listed in DenyUsers */
|
||||
if (options.num_deny_users > 0) {
|
||||
for (i = 0; i < options.num_deny_users; i++) {
|
||||
r = match_user(pw->pw_name, hostname, ipaddr,
|
||||
options.deny_users[i]);
|
||||
if (r < 0) {
|
||||
fatal("Invalid DenyUsers pattern \"%.100s\"",
|
||||
options.deny_users[i]);
|
||||
} else if (r != 0) {
|
||||
logit("User %.100s from %.100s not allowed "
|
||||
"because listed in DenyUsers",
|
||||
pw->pw_name, hostname);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Return false if AllowUsers isn't empty and user isn't listed there */
|
||||
if (options.num_allow_users > 0) {
|
||||
for (i = 0; i < options.num_allow_users; i++) {
|
||||
r = match_user(pw->pw_name, hostname, ipaddr,
|
||||
options.allow_users[i]);
|
||||
if (r < 0) {
|
||||
fatal("Invalid AllowUsers pattern \"%.100s\"",
|
||||
options.allow_users[i]);
|
||||
} else if (r == 1)
|
||||
break;
|
||||
}
|
||||
/* i < options.num_allow_users iff we break for loop */
|
||||
if (i >= options.num_allow_users) {
|
||||
logit("User %.100s from %.100s not allowed because "
|
||||
"not listed in AllowUsers", pw->pw_name, hostname);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (options.num_deny_groups > 0 || options.num_allow_groups > 0) {
|
||||
/* Get the user's group access list (primary and supplementary) */
|
||||
if (ga_init(pw->pw_name, pw->pw_gid) == 0) {
|
||||
logit("User %.100s from %.100s not allowed because "
|
||||
"not in any group", pw->pw_name, hostname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Return false if one of user's groups is listed in DenyGroups */
|
||||
if (options.num_deny_groups > 0)
|
||||
if (ga_match(options.deny_groups,
|
||||
options.num_deny_groups)) {
|
||||
ga_free();
|
||||
logit("User %.100s from %.100s not allowed "
|
||||
"because a group is listed in DenyGroups",
|
||||
pw->pw_name, hostname);
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* Return false if AllowGroups isn't empty and one of user's groups
|
||||
* isn't listed there
|
||||
*/
|
||||
if (options.num_allow_groups > 0)
|
||||
if (!ga_match(options.allow_groups,
|
||||
options.num_allow_groups)) {
|
||||
ga_free();
|
||||
logit("User %.100s from %.100s not allowed "
|
||||
"because none of user's groups are listed "
|
||||
"in AllowGroups", pw->pw_name, hostname);
|
||||
return 0;
|
||||
}
|
||||
ga_free();
|
||||
}
|
||||
|
||||
#ifdef CUSTOM_SYS_AUTH_ALLOWED_USER
|
||||
if (!sys_auth_allowed_user(pw, loginmsg))
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
/* We found no reason not to let this user try to log on... */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Formats any key left in authctxt->auth_method_key for inclusion in
|
||||
* auth_log()'s message. Also includes authxtct->auth_method_info if present.
|
||||
*/
|
||||
static char *
|
||||
format_method_key(Authctxt *authctxt)
|
||||
{
|
||||
const struct sshkey *key = authctxt->auth_method_key;
|
||||
const char *methinfo = authctxt->auth_method_info;
|
||||
char *fp, *cafp, *ret = NULL;
|
||||
|
||||
if (key == NULL)
|
||||
return NULL;
|
||||
|
||||
if (sshkey_is_cert(key)) {
|
||||
fp = sshkey_fingerprint(key,
|
||||
options.fingerprint_hash, SSH_FP_DEFAULT);
|
||||
cafp = sshkey_fingerprint(key->cert->signature_key,
|
||||
options.fingerprint_hash, SSH_FP_DEFAULT);
|
||||
xasprintf(&ret, "%s %s ID %s (serial %llu) CA %s %s%s%s",
|
||||
sshkey_type(key), fp == NULL ? "(null)" : fp,
|
||||
key->cert->key_id,
|
||||
(unsigned long long)key->cert->serial,
|
||||
sshkey_type(key->cert->signature_key),
|
||||
cafp == NULL ? "(null)" : cafp,
|
||||
methinfo == NULL ? "" : ", ",
|
||||
methinfo == NULL ? "" : methinfo);
|
||||
free(fp);
|
||||
free(cafp);
|
||||
} else {
|
||||
fp = sshkey_fingerprint(key, options.fingerprint_hash,
|
||||
SSH_FP_DEFAULT);
|
||||
xasprintf(&ret, "%s %s%s%s", sshkey_type(key),
|
||||
fp == NULL ? "(null)" : fp,
|
||||
methinfo == NULL ? "" : ", ",
|
||||
methinfo == NULL ? "" : methinfo);
|
||||
free(fp);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
auth_log(struct ssh *ssh, int authenticated, int partial,
|
||||
const char *method, const char *submethod)
|
||||
{
|
||||
Authctxt *authctxt = (Authctxt *)ssh->authctxt;
|
||||
int level = SYSLOG_LEVEL_VERBOSE;
|
||||
const char *authmsg;
|
||||
char *extra = NULL;
|
||||
|
||||
if (!mm_is_monitor() && !authctxt->postponed)
|
||||
return;
|
||||
|
||||
/* Raise logging level */
|
||||
if (authenticated == 1 ||
|
||||
!authctxt->valid ||
|
||||
authctxt->failures >= options.max_authtries / 2 ||
|
||||
strcmp(method, "password") == 0)
|
||||
level = SYSLOG_LEVEL_INFO;
|
||||
|
||||
if (authctxt->postponed)
|
||||
authmsg = "Postponed";
|
||||
else if (partial)
|
||||
authmsg = "Partial";
|
||||
else
|
||||
authmsg = authenticated ? "Accepted" : "Failed";
|
||||
|
||||
if ((extra = format_method_key(authctxt)) == NULL) {
|
||||
if (authctxt->auth_method_info != NULL)
|
||||
extra = xstrdup(authctxt->auth_method_info);
|
||||
}
|
||||
|
||||
do_log2(level, "%s %s%s%s for %s%.100s from %.200s port %d ssh2%s%s",
|
||||
authmsg,
|
||||
method,
|
||||
submethod != NULL ? "/" : "", submethod == NULL ? "" : submethod,
|
||||
authctxt->valid ? "" : "invalid user ",
|
||||
authctxt->user,
|
||||
ssh_remote_ipaddr(ssh),
|
||||
ssh_remote_port(ssh),
|
||||
extra != NULL ? ": " : "",
|
||||
extra != NULL ? extra : "");
|
||||
|
||||
free(extra);
|
||||
|
||||
#if defined(CUSTOM_FAILED_LOGIN) || defined(SSH_AUDIT_EVENTS)
|
||||
if (authenticated == 0 && !(authctxt->postponed || partial)) {
|
||||
/* Log failed login attempt */
|
||||
# ifdef CUSTOM_FAILED_LOGIN
|
||||
if (strcmp(method, "password") == 0 ||
|
||||
strncmp(method, "keyboard-interactive", 20) == 0 ||
|
||||
strcmp(method, "challenge-response") == 0)
|
||||
record_failed_login(ssh, authctxt->user,
|
||||
auth_get_canonical_hostname(ssh, options.use_dns), "ssh");
|
||||
# endif
|
||||
# ifdef SSH_AUDIT_EVENTS
|
||||
audit_event(ssh, audit_classify_auth(method));
|
||||
# endif
|
||||
}
|
||||
#endif
|
||||
#if defined(CUSTOM_FAILED_LOGIN) && defined(WITH_AIXAUTHENTICATE)
|
||||
if (authenticated)
|
||||
sys_auth_record_login(authctxt->user,
|
||||
auth_get_canonical_hostname(ssh, options.use_dns), "ssh",
|
||||
loginmsg);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
auth_maxtries_exceeded(struct ssh *ssh)
|
||||
{
|
||||
Authctxt *authctxt = (Authctxt *)ssh->authctxt;
|
||||
|
||||
error("maximum authentication attempts exceeded for "
|
||||
"%s%.100s from %.200s port %d ssh2",
|
||||
authctxt->valid ? "" : "invalid user ",
|
||||
authctxt->user,
|
||||
ssh_remote_ipaddr(ssh),
|
||||
ssh_remote_port(ssh));
|
||||
ssh_packet_disconnect(ssh, "Too many authentication failures");
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/*
|
||||
* Check whether root logins are disallowed.
|
||||
*/
|
||||
int
|
||||
auth_root_allowed(struct ssh *ssh, const char *method)
|
||||
{
|
||||
switch (options.permit_root_login) {
|
||||
case PERMIT_YES:
|
||||
return 1;
|
||||
case PERMIT_NO_PASSWD:
|
||||
if (strcmp(method, "publickey") == 0 ||
|
||||
strcmp(method, "hostbased") == 0 ||
|
||||
strcmp(method, "gssapi-with-mic") == 0)
|
||||
return 1;
|
||||
break;
|
||||
case PERMIT_FORCED_ONLY:
|
||||
if (auth_opts->force_command != NULL) {
|
||||
logit("Root login accepted for forced command.");
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
logit("ROOT LOGIN REFUSED FROM %.200s port %d",
|
||||
ssh_remote_ipaddr(ssh), ssh_remote_port(ssh));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Given a template and a passwd structure, build a filename
|
||||
* by substituting % tokenised options. Currently, %% becomes '%',
|
||||
* %h becomes the home directory and %u the username.
|
||||
*
|
||||
* This returns a buffer allocated by xmalloc.
|
||||
*/
|
||||
char *
|
||||
expand_authorized_keys(const char *filename, struct passwd *pw)
|
||||
{
|
||||
char *file, uidstr[32], ret[PATH_MAX];
|
||||
int i;
|
||||
|
||||
snprintf(uidstr, sizeof(uidstr), "%llu",
|
||||
(unsigned long long)pw->pw_uid);
|
||||
file = percent_expand(filename, "h", pw->pw_dir,
|
||||
"u", pw->pw_name, "U", uidstr, (char *)NULL);
|
||||
|
||||
/*
|
||||
* Ensure that filename starts anchored. If not, be backward
|
||||
* compatible and prepend the '%h/'
|
||||
*/
|
||||
if (path_absolute(file))
|
||||
return (file);
|
||||
|
||||
i = snprintf(ret, sizeof(ret), "%s/%s", pw->pw_dir, file);
|
||||
if (i < 0 || (size_t)i >= sizeof(ret))
|
||||
fatal("expand_authorized_keys: path too long");
|
||||
free(file);
|
||||
return (xstrdup(ret));
|
||||
}
|
||||
|
||||
char *
|
||||
authorized_principals_file(struct passwd *pw)
|
||||
{
|
||||
if (options.authorized_principals_file == NULL)
|
||||
return NULL;
|
||||
return expand_authorized_keys(options.authorized_principals_file, pw);
|
||||
}
|
||||
|
||||
/* return ok if key exists in sysfile or userfile */
|
||||
HostStatus
|
||||
check_key_in_hostfiles(struct passwd *pw, struct sshkey *key, const char *host,
|
||||
const char *sysfile, const char *userfile)
|
||||
{
|
||||
char *user_hostfile;
|
||||
struct stat st;
|
||||
HostStatus host_status;
|
||||
struct hostkeys *hostkeys;
|
||||
const struct hostkey_entry *found;
|
||||
|
||||
hostkeys = init_hostkeys();
|
||||
load_hostkeys(hostkeys, host, sysfile, 0);
|
||||
if (userfile != NULL) {
|
||||
user_hostfile = tilde_expand_filename(userfile, pw->pw_uid);
|
||||
if (options.strict_modes &&
|
||||
(stat(user_hostfile, &st) == 0) &&
|
||||
((st.st_uid != 0 && st.st_uid != pw->pw_uid) ||
|
||||
(st.st_mode & 022) != 0)) {
|
||||
logit("Authentication refused for %.100s: "
|
||||
"bad owner or modes for %.200s",
|
||||
pw->pw_name, user_hostfile);
|
||||
auth_debug_add("Ignored %.200s: bad ownership or modes",
|
||||
user_hostfile);
|
||||
} else {
|
||||
temporarily_use_uid(pw);
|
||||
load_hostkeys(hostkeys, host, user_hostfile, 0);
|
||||
restore_uid();
|
||||
}
|
||||
free(user_hostfile);
|
||||
}
|
||||
host_status = check_key_in_hostkeys(hostkeys, key, &found);
|
||||
if (host_status == HOST_REVOKED)
|
||||
error("WARNING: revoked key for %s attempted authentication",
|
||||
host);
|
||||
else if (host_status == HOST_OK)
|
||||
debug_f("key for %s found at %s:%ld",
|
||||
found->host, found->file, found->line);
|
||||
else
|
||||
debug_f("key for host %s not found", host);
|
||||
|
||||
free_hostkeys(hostkeys);
|
||||
|
||||
return host_status;
|
||||
}
|
||||
|
||||
struct passwd *
|
||||
getpwnamallow(struct ssh *ssh, const char *user)
|
||||
{
|
||||
#ifdef HAVE_LOGIN_CAP
|
||||
extern login_cap_t *lc;
|
||||
#ifdef HAVE_AUTH_HOSTOK
|
||||
const char *from_host, *from_ip;
|
||||
#endif
|
||||
#ifdef BSD_AUTH
|
||||
auth_session_t *as;
|
||||
#endif
|
||||
#endif
|
||||
struct passwd *pw;
|
||||
struct connection_info *ci;
|
||||
u_int i;
|
||||
|
||||
ci = server_get_connection_info(ssh, 1, options.use_dns);
|
||||
ci->user = user;
|
||||
ci->user_invalid = getpwnam(user) == NULL;
|
||||
parse_server_match_config(&options, &includes, ci);
|
||||
log_change_level(options.log_level);
|
||||
log_verbose_reset();
|
||||
for (i = 0; i < options.num_log_verbose; i++)
|
||||
log_verbose_add(options.log_verbose[i]);
|
||||
server_process_permitopen(ssh);
|
||||
|
||||
#if defined(_AIX) && defined(HAVE_SETAUTHDB)
|
||||
aix_setauthdb(user);
|
||||
#endif
|
||||
|
||||
pw = getpwnam(user);
|
||||
|
||||
#if defined(_AIX) && defined(HAVE_SETAUTHDB)
|
||||
aix_restoreauthdb();
|
||||
#endif
|
||||
if (pw == NULL) {
|
||||
logit("Invalid user %.100s from %.100s port %d",
|
||||
user, ssh_remote_ipaddr(ssh), ssh_remote_port(ssh));
|
||||
#ifdef CUSTOM_FAILED_LOGIN
|
||||
record_failed_login(ssh, user,
|
||||
auth_get_canonical_hostname(ssh, options.use_dns), "ssh");
|
||||
#endif
|
||||
#ifdef SSH_AUDIT_EVENTS
|
||||
audit_event(ssh, SSH_INVALID_USER);
|
||||
#endif /* SSH_AUDIT_EVENTS */
|
||||
return (NULL);
|
||||
}
|
||||
if (!allowed_user(ssh, pw))
|
||||
return (NULL);
|
||||
#ifdef HAVE_LOGIN_CAP
|
||||
if ((lc = login_getpwclass(pw)) == NULL) {
|
||||
debug("unable to get login class: %s", user);
|
||||
return (NULL);
|
||||
}
|
||||
#ifdef HAVE_AUTH_HOSTOK
|
||||
from_host = auth_get_canonical_hostname(ssh, options.use_dns);
|
||||
from_ip = ssh_remote_ipaddr(ssh);
|
||||
if (!auth_hostok(lc, from_host, from_ip)) {
|
||||
debug("Denied connection for %.200s from %.200s [%.200s].",
|
||||
pw->pw_name, from_host, from_ip);
|
||||
return (NULL);
|
||||
}
|
||||
#endif /* HAVE_AUTH_HOSTOK */
|
||||
#ifdef HAVE_AUTH_TIMEOK
|
||||
if (!auth_timeok(lc, time(NULL))) {
|
||||
debug("LOGIN %.200s REFUSED (TIME)", pw->pw_name);
|
||||
return (NULL);
|
||||
}
|
||||
#endif /* HAVE_AUTH_TIMEOK */
|
||||
#ifdef BSD_AUTH
|
||||
if ((as = auth_open()) == NULL || auth_setpwd(as, pw) != 0 ||
|
||||
auth_approval(as, lc, pw->pw_name, "ssh") <= 0) {
|
||||
debug("Approval failure for %s", user);
|
||||
pw = NULL;
|
||||
}
|
||||
if (as != NULL)
|
||||
auth_close(as);
|
||||
#endif
|
||||
#endif
|
||||
if (pw != NULL)
|
||||
return (pwcopy(pw));
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* Returns 1 if key is revoked by revoked_keys_file, 0 otherwise */
|
||||
int
|
||||
auth_key_is_revoked(struct sshkey *key)
|
||||
{
|
||||
char *fp = NULL;
|
||||
int r;
|
||||
|
||||
if (options.revoked_keys_file == NULL)
|
||||
return 0;
|
||||
if ((fp = sshkey_fingerprint(key, options.fingerprint_hash,
|
||||
SSH_FP_DEFAULT)) == NULL) {
|
||||
r = SSH_ERR_ALLOC_FAIL;
|
||||
error_fr(r, "fingerprint key");
|
||||
goto out;
|
||||
}
|
||||
|
||||
r = sshkey_check_revoked(key, options.revoked_keys_file);
|
||||
switch (r) {
|
||||
case 0:
|
||||
break; /* not revoked */
|
||||
case SSH_ERR_KEY_REVOKED:
|
||||
error("Authentication key %s %s revoked by file %s",
|
||||
sshkey_type(key), fp, options.revoked_keys_file);
|
||||
goto out;
|
||||
default:
|
||||
error_r(r, "Error checking authentication key %s %s in "
|
||||
"revoked keys file %s", sshkey_type(key), fp,
|
||||
options.revoked_keys_file);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Success */
|
||||
r = 0;
|
||||
|
||||
out:
|
||||
free(fp);
|
||||
return r == 0 ? 0 : 1;
|
||||
}
|
||||
|
||||
void
|
||||
auth_debug_add(const char *fmt,...)
|
||||
{
|
||||
char buf[1024];
|
||||
va_list args;
|
||||
int r;
|
||||
|
||||
va_start(args, fmt);
|
||||
vsnprintf(buf, sizeof(buf), fmt, args);
|
||||
va_end(args);
|
||||
debug3("%s", buf);
|
||||
if (auth_debug != NULL)
|
||||
if ((r = sshbuf_put_cstring(auth_debug, buf)) != 0)
|
||||
fatal_fr(r, "sshbuf_put_cstring");
|
||||
}
|
||||
|
||||
void
|
||||
auth_debug_send(struct ssh *ssh)
|
||||
{
|
||||
char *msg;
|
||||
int r;
|
||||
|
||||
if (auth_debug == NULL)
|
||||
return;
|
||||
while (sshbuf_len(auth_debug) != 0) {
|
||||
if ((r = sshbuf_get_cstring(auth_debug, &msg, NULL)) != 0)
|
||||
fatal_fr(r, "sshbuf_get_cstring");
|
||||
ssh_packet_send_debug(ssh, "%s", msg);
|
||||
free(msg);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
auth_debug_reset(void)
|
||||
{
|
||||
if (auth_debug != NULL)
|
||||
sshbuf_reset(auth_debug);
|
||||
else if ((auth_debug = sshbuf_new()) == NULL)
|
||||
fatal_f("sshbuf_new failed");
|
||||
}
|
||||
|
||||
struct passwd *
|
||||
fakepw(void)
|
||||
{
|
||||
static int done = 0;
|
||||
static struct passwd fake;
|
||||
const char hashchars[] = "./ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz0123456789"; /* from bcrypt.c */
|
||||
char *cp;
|
||||
|
||||
if (done)
|
||||
return (&fake);
|
||||
|
||||
memset(&fake, 0, sizeof(fake));
|
||||
fake.pw_name = "NOUSER";
|
||||
fake.pw_passwd = xstrdup("$2a$10$"
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
|
||||
for (cp = fake.pw_passwd + 7; *cp != '\0'; cp++)
|
||||
*cp = hashchars[arc4random_uniform(sizeof(hashchars) - 1)];
|
||||
#ifdef HAVE_STRUCT_PASSWD_PW_GECOS
|
||||
fake.pw_gecos = "NOUSER";
|
||||
#endif
|
||||
fake.pw_uid = privsep_pw == NULL ? (uid_t)-1 : privsep_pw->pw_uid;
|
||||
fake.pw_gid = privsep_pw == NULL ? (gid_t)-1 : privsep_pw->pw_gid;
|
||||
#ifdef HAVE_STRUCT_PASSWD_PW_CLASS
|
||||
fake.pw_class = "";
|
||||
#endif
|
||||
fake.pw_dir = "/nonexist";
|
||||
fake.pw_shell = "/nonexist";
|
||||
done = 1;
|
||||
|
||||
return (&fake);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the canonical name of the host in the other side of the current
|
||||
* connection. The host name is cached, so it is efficient to call this
|
||||
* several times.
|
||||
*/
|
||||
|
||||
const char *
|
||||
auth_get_canonical_hostname(struct ssh *ssh, int use_dns)
|
||||
{
|
||||
static char *dnsname;
|
||||
|
||||
if (!use_dns)
|
||||
return ssh_remote_ipaddr(ssh);
|
||||
if (dnsname != NULL)
|
||||
return dnsname;
|
||||
dnsname = ssh_remote_hostname(ssh);
|
||||
return dnsname;
|
||||
}
|
||||
|
||||
/* These functions link key/cert options to the auth framework */
|
||||
|
||||
/* Log sshauthopt options locally and (optionally) for remote transmission */
|
||||
void
|
||||
auth_log_authopts(const char *loc, const struct sshauthopt *opts, int do_remote)
|
||||
{
|
||||
int do_env = options.permit_user_env && opts->nenv > 0;
|
||||
int do_permitopen = opts->npermitopen > 0 &&
|
||||
(options.allow_tcp_forwarding & FORWARD_LOCAL) != 0;
|
||||
int do_permitlisten = opts->npermitlisten > 0 &&
|
||||
(options.allow_tcp_forwarding & FORWARD_REMOTE) != 0;
|
||||
size_t i;
|
||||
char msg[1024], buf[64];
|
||||
|
||||
snprintf(buf, sizeof(buf), "%d", opts->force_tun_device);
|
||||
/* Try to keep this alphabetically sorted */
|
||||
snprintf(msg, sizeof(msg), "key options:%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
|
||||
opts->permit_agent_forwarding_flag ? " agent-forwarding" : "",
|
||||
opts->force_command == NULL ? "" : " command",
|
||||
do_env ? " environment" : "",
|
||||
opts->valid_before == 0 ? "" : "expires",
|
||||
opts->no_require_user_presence ? " no-touch-required" : "",
|
||||
do_permitopen ? " permitopen" : "",
|
||||
do_permitlisten ? " permitlisten" : "",
|
||||
opts->permit_port_forwarding_flag ? " port-forwarding" : "",
|
||||
opts->cert_principals == NULL ? "" : " principals",
|
||||
opts->permit_pty_flag ? " pty" : "",
|
||||
opts->require_verify ? " uv" : "",
|
||||
opts->force_tun_device == -1 ? "" : " tun=",
|
||||
opts->force_tun_device == -1 ? "" : buf,
|
||||
opts->permit_user_rc ? " user-rc" : "",
|
||||
opts->permit_x11_forwarding_flag ? " x11-forwarding" : "");
|
||||
|
||||
debug("%s: %s", loc, msg);
|
||||
if (do_remote)
|
||||
auth_debug_add("%s: %s", loc, msg);
|
||||
|
||||
if (options.permit_user_env) {
|
||||
for (i = 0; i < opts->nenv; i++) {
|
||||
debug("%s: environment: %s", loc, opts->env[i]);
|
||||
if (do_remote) {
|
||||
auth_debug_add("%s: environment: %s",
|
||||
loc, opts->env[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Go into a little more details for the local logs. */
|
||||
if (opts->valid_before != 0) {
|
||||
format_absolute_time(opts->valid_before, buf, sizeof(buf));
|
||||
debug("%s: expires at %s", loc, buf);
|
||||
}
|
||||
if (opts->cert_principals != NULL) {
|
||||
debug("%s: authorized principals: \"%s\"",
|
||||
loc, opts->cert_principals);
|
||||
}
|
||||
if (opts->force_command != NULL)
|
||||
debug("%s: forced command: \"%s\"", loc, opts->force_command);
|
||||
if (do_permitopen) {
|
||||
for (i = 0; i < opts->npermitopen; i++) {
|
||||
debug("%s: permitted open: %s",
|
||||
loc, opts->permitopen[i]);
|
||||
}
|
||||
}
|
||||
if (do_permitlisten) {
|
||||
for (i = 0; i < opts->npermitlisten; i++) {
|
||||
debug("%s: permitted listen: %s",
|
||||
loc, opts->permitlisten[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Activate a new set of key/cert options; merging with what is there. */
|
||||
int
|
||||
auth_activate_options(struct ssh *ssh, struct sshauthopt *opts)
|
||||
{
|
||||
struct sshauthopt *old = auth_opts;
|
||||
const char *emsg = NULL;
|
||||
|
||||
debug_f("setting new authentication options");
|
||||
if ((auth_opts = sshauthopt_merge(old, opts, &emsg)) == NULL) {
|
||||
error("Inconsistent authentication options: %s", emsg);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Disable forwarding, etc for the session */
|
||||
void
|
||||
auth_restrict_session(struct ssh *ssh)
|
||||
{
|
||||
struct sshauthopt *restricted;
|
||||
|
||||
debug_f("restricting session");
|
||||
|
||||
/* A blank sshauthopt defaults to permitting nothing */
|
||||
if ((restricted = sshauthopt_new()) == NULL)
|
||||
fatal_f("sshauthopt_new failed");
|
||||
restricted->permit_pty_flag = 1;
|
||||
restricted->restricted = 1;
|
||||
|
||||
if (auth_activate_options(ssh, restricted) != 0)
|
||||
fatal_f("failed to restrict session");
|
||||
sshauthopt_free(restricted);
|
||||
}
|
248
auth.h
Normal file
248
auth.h
Normal file
|
@ -0,0 +1,248 @@
|
|||
/* $OpenBSD: auth.h,v 1.108 2024/05/17 06:42:04 jsg 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef AUTH_H
|
||||
#define AUTH_H
|
||||
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef HAVE_LOGIN_CAP
|
||||
#include <login_cap.h>
|
||||
#endif
|
||||
#ifdef BSD_AUTH
|
||||
#include <bsd_auth.h>
|
||||
#endif
|
||||
#ifdef KRB5
|
||||
#include <krb5.h>
|
||||
#endif
|
||||
|
||||
struct passwd;
|
||||
struct ssh;
|
||||
struct sshbuf;
|
||||
struct sshkey;
|
||||
struct sshkey_cert;
|
||||
struct sshauthopt;
|
||||
|
||||
typedef struct Authctxt Authctxt;
|
||||
typedef struct Authmethod Authmethod;
|
||||
typedef struct KbdintDevice KbdintDevice;
|
||||
|
||||
struct Authctxt {
|
||||
sig_atomic_t success;
|
||||
int authenticated; /* authenticated and alarms cancelled */
|
||||
int postponed; /* authentication needs another step */
|
||||
int valid; /* user exists and is allowed to login */
|
||||
int attempt;
|
||||
int failures;
|
||||
int server_caused_failure;
|
||||
int force_pwchange;
|
||||
char *user; /* username sent by the client */
|
||||
char *service;
|
||||
struct passwd *pw; /* set if 'valid' */
|
||||
char *style;
|
||||
|
||||
/* Method lists for multiple authentication */
|
||||
char **auth_methods; /* modified from server config */
|
||||
u_int num_auth_methods;
|
||||
|
||||
/* Authentication method-specific data */
|
||||
void *methoddata;
|
||||
void *kbdintctxt;
|
||||
#ifdef BSD_AUTH
|
||||
auth_session_t *as;
|
||||
#endif
|
||||
#ifdef KRB5
|
||||
krb5_context krb5_ctx;
|
||||
krb5_ccache krb5_fwd_ccache;
|
||||
krb5_principal krb5_user;
|
||||
char *krb5_ticket_file;
|
||||
char *krb5_ccname;
|
||||
#endif
|
||||
struct sshbuf *loginmsg;
|
||||
|
||||
/* Authentication keys already used; these will be refused henceforth */
|
||||
struct sshkey **prev_keys;
|
||||
u_int nprev_keys;
|
||||
|
||||
/* Last used key and ancillary information from active auth method */
|
||||
struct sshkey *auth_method_key;
|
||||
char *auth_method_info;
|
||||
|
||||
/* Information exposed to session */
|
||||
struct sshbuf *session_info; /* Auth info for environment */
|
||||
};
|
||||
|
||||
/*
|
||||
* Every authentication method has to handle authentication requests for
|
||||
* non-existing users, or for users that are not allowed to login. In this
|
||||
* case 'valid' is set to 0, but 'user' points to the username requested by
|
||||
* the client.
|
||||
*/
|
||||
|
||||
struct authmethod_cfg {
|
||||
const char *name;
|
||||
const char *synonym;
|
||||
int *enabled;
|
||||
};
|
||||
|
||||
struct Authmethod {
|
||||
struct authmethod_cfg *cfg;
|
||||
int (*userauth)(struct ssh *, const char *);
|
||||
};
|
||||
|
||||
/*
|
||||
* Keyboard interactive device:
|
||||
* init_ctx returns: non NULL upon success
|
||||
* query returns: 0 - success, otherwise failure
|
||||
* respond returns: 0 - success, 1 - need further interaction,
|
||||
* otherwise - failure
|
||||
*/
|
||||
struct KbdintDevice
|
||||
{
|
||||
const char *name;
|
||||
void* (*init_ctx)(Authctxt*);
|
||||
int (*query)(void *ctx, char **name, char **infotxt,
|
||||
u_int *numprompts, char ***prompts, u_int **echo_on);
|
||||
int (*respond)(void *ctx, u_int numresp, char **responses);
|
||||
void (*free_ctx)(void *ctx);
|
||||
};
|
||||
|
||||
int
|
||||
auth_rhosts2(struct passwd *, const char *, const char *, const char *);
|
||||
|
||||
int auth_password(struct ssh *, const char *);
|
||||
|
||||
int hostbased_key_allowed(struct ssh *, struct passwd *,
|
||||
const char *, char *, struct sshkey *);
|
||||
int user_key_allowed(struct ssh *ssh, struct passwd *, struct sshkey *,
|
||||
int, struct sshauthopt **);
|
||||
int auth2_key_already_used(Authctxt *, const struct sshkey *);
|
||||
|
||||
/*
|
||||
* Handling auth method-specific information for logging and prevention
|
||||
* of key reuse during multiple authentication.
|
||||
*/
|
||||
void auth2_authctxt_reset_info(Authctxt *);
|
||||
void auth2_record_key(Authctxt *, int, const struct sshkey *);
|
||||
void auth2_record_info(Authctxt *authctxt, const char *, ...)
|
||||
__attribute__((__format__ (printf, 2, 3)))
|
||||
__attribute__((__nonnull__ (2)));
|
||||
void auth2_update_session_info(Authctxt *, const char *, const char *);
|
||||
|
||||
#ifdef KRB5
|
||||
int auth_krb5_password(Authctxt *authctxt, const char *password);
|
||||
void krb5_cleanup_proc(Authctxt *authctxt);
|
||||
#endif /* KRB5 */
|
||||
|
||||
#if defined(USE_SHADOW) && defined(HAS_SHADOW_EXPIRE)
|
||||
#include <shadow.h>
|
||||
int auth_shadow_acctexpired(struct spwd *);
|
||||
int auth_shadow_pwexpired(Authctxt *);
|
||||
#endif
|
||||
|
||||
#include "auth-pam.h"
|
||||
#include "audit.h"
|
||||
void remove_kbdint_device(const char *);
|
||||
|
||||
void do_authentication2(struct ssh *);
|
||||
|
||||
void auth_log(struct ssh *, int, int, const char *, const char *);
|
||||
void auth_maxtries_exceeded(struct ssh *) __attribute__((noreturn));
|
||||
void userauth_finish(struct ssh *, int, const char *, const char *);
|
||||
int auth_root_allowed(struct ssh *, const char *);
|
||||
|
||||
char *auth2_read_banner(void);
|
||||
int auth2_methods_valid(const char *, int);
|
||||
int auth2_update_methods_lists(Authctxt *, const char *, const char *);
|
||||
int auth2_setup_methods_lists(Authctxt *);
|
||||
int auth2_method_allowed(Authctxt *, const char *, const char *);
|
||||
|
||||
void privsep_challenge_enable(void);
|
||||
|
||||
int auth2_challenge(struct ssh *, char *);
|
||||
void auth2_challenge_stop(struct ssh *);
|
||||
int bsdauth_query(void *, char **, char **, u_int *, char ***, u_int **);
|
||||
int bsdauth_respond(void *, u_int, char **);
|
||||
|
||||
int allowed_user(struct ssh *, struct passwd *);
|
||||
struct passwd * getpwnamallow(struct ssh *, const char *user);
|
||||
|
||||
char *expand_authorized_keys(const char *, struct passwd *pw);
|
||||
char *authorized_principals_file(struct passwd *);
|
||||
|
||||
int auth_key_is_revoked(struct sshkey *);
|
||||
|
||||
const char *auth_get_canonical_hostname(struct ssh *, int);
|
||||
|
||||
HostStatus
|
||||
check_key_in_hostfiles(struct passwd *, struct sshkey *, const char *,
|
||||
const char *, const char *);
|
||||
|
||||
/* hostkey handling */
|
||||
struct sshkey *get_hostkey_by_index(int);
|
||||
struct sshkey *get_hostkey_public_by_index(int, struct ssh *);
|
||||
struct sshkey *get_hostkey_public_by_type(int, int, struct ssh *);
|
||||
struct sshkey *get_hostkey_private_by_type(int, int, struct ssh *);
|
||||
int get_hostkey_index(struct sshkey *, int, struct ssh *);
|
||||
int sshd_hostkey_sign(struct ssh *, struct sshkey *, struct sshkey *,
|
||||
u_char **, size_t *, const u_char *, size_t, const char *);
|
||||
|
||||
/* Key / cert options linkage to auth layer */
|
||||
int auth_activate_options(struct ssh *, struct sshauthopt *);
|
||||
void auth_restrict_session(struct ssh *);
|
||||
void auth_log_authopts(const char *, const struct sshauthopt *, int);
|
||||
|
||||
/* debug messages during authentication */
|
||||
void auth_debug_add(const char *fmt,...)
|
||||
__attribute__((format(printf, 1, 2)));
|
||||
void auth_debug_send(struct ssh *);
|
||||
void auth_debug_reset(void);
|
||||
|
||||
struct passwd *fakepw(void);
|
||||
|
||||
/* auth2-pubkeyfile.c */
|
||||
int auth_authorise_keyopts(struct passwd *, struct sshauthopt *, int,
|
||||
const char *, const char *, const char *);
|
||||
int auth_check_principals_line(char *, const struct sshkey_cert *,
|
||||
const char *, struct sshauthopt **);
|
||||
int auth_process_principals(FILE *, const char *,
|
||||
const struct sshkey_cert *, struct sshauthopt **);
|
||||
int auth_check_authkey_line(struct passwd *, struct sshkey *,
|
||||
char *, const char *, const char *, const char *, struct sshauthopt **);
|
||||
int auth_check_authkeys_file(struct passwd *, FILE *, char *,
|
||||
struct sshkey *, const char *, const char *, struct sshauthopt **);
|
||||
FILE *auth_openkeyfile(const char *, struct passwd *, int);
|
||||
FILE *auth_openprincipals(const char *, struct passwd *, int);
|
||||
|
||||
int sys_auth_passwd(struct ssh *, const char *);
|
||||
|
||||
#if defined(KRB5) && !defined(HEIMDAL)
|
||||
krb5_error_code ssh_krb5_cc_gen(krb5_context, krb5_ccache *);
|
||||
#endif
|
||||
|
||||
#endif /* AUTH_H */
|
382
auth2-chall.c
Normal file
382
auth2-chall.c
Normal file
|
@ -0,0 +1,382 @@
|
|||
/* $OpenBSD: auth2-chall.c,v 1.54 2020/10/18 11:32:01 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2001 Markus Friedl. All rights reserved.
|
||||
* Copyright (c) 2001 Per Allansson. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "ssh2.h"
|
||||
#include "sshkey.h"
|
||||
#include "hostfile.h"
|
||||
#include "auth.h"
|
||||
#include "sshbuf.h"
|
||||
#include "packet.h"
|
||||
#include "dispatch.h"
|
||||
#include "ssherr.h"
|
||||
#include "log.h"
|
||||
#include "misc.h"
|
||||
#include "servconf.h"
|
||||
|
||||
/* import */
|
||||
extern ServerOptions options;
|
||||
|
||||
static int auth2_challenge_start(struct ssh *);
|
||||
static int send_userauth_info_request(struct ssh *);
|
||||
static int input_userauth_info_response(int, u_int32_t, struct ssh *);
|
||||
|
||||
#ifdef BSD_AUTH
|
||||
extern KbdintDevice bsdauth_device;
|
||||
#else
|
||||
#ifdef USE_PAM
|
||||
extern KbdintDevice sshpam_device;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
KbdintDevice *devices[] = {
|
||||
#ifdef BSD_AUTH
|
||||
&bsdauth_device,
|
||||
#else
|
||||
#ifdef USE_PAM
|
||||
&sshpam_device,
|
||||
#endif
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
|
||||
typedef struct KbdintAuthctxt KbdintAuthctxt;
|
||||
struct KbdintAuthctxt
|
||||
{
|
||||
char *devices;
|
||||
void *ctxt;
|
||||
KbdintDevice *device;
|
||||
u_int nreq;
|
||||
u_int devices_done;
|
||||
};
|
||||
|
||||
#ifdef USE_PAM
|
||||
void
|
||||
remove_kbdint_device(const char *devname)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i = 0; devices[i] != NULL; i++)
|
||||
if (strcmp(devices[i]->name, devname) == 0) {
|
||||
for (j = i; devices[j] != NULL; j++)
|
||||
devices[j] = devices[j+1];
|
||||
i--;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static KbdintAuthctxt *
|
||||
kbdint_alloc(const char *devs)
|
||||
{
|
||||
KbdintAuthctxt *kbdintctxt;
|
||||
struct sshbuf *b;
|
||||
int i, r;
|
||||
|
||||
#ifdef USE_PAM
|
||||
if (!options.use_pam)
|
||||
remove_kbdint_device("pam");
|
||||
#endif
|
||||
|
||||
kbdintctxt = xcalloc(1, sizeof(KbdintAuthctxt));
|
||||
if (strcmp(devs, "") == 0) {
|
||||
if ((b = sshbuf_new()) == NULL)
|
||||
fatal_f("sshbuf_new failed");
|
||||
for (i = 0; devices[i]; i++) {
|
||||
if ((r = sshbuf_putf(b, "%s%s",
|
||||
sshbuf_len(b) ? "," : "", devices[i]->name)) != 0)
|
||||
fatal_fr(r, "buffer error");
|
||||
}
|
||||
if ((kbdintctxt->devices = sshbuf_dup_string(b)) == NULL)
|
||||
fatal_f("sshbuf_dup_string failed");
|
||||
sshbuf_free(b);
|
||||
} else {
|
||||
kbdintctxt->devices = xstrdup(devs);
|
||||
}
|
||||
debug("kbdint_alloc: devices '%s'", kbdintctxt->devices);
|
||||
kbdintctxt->ctxt = NULL;
|
||||
kbdintctxt->device = NULL;
|
||||
kbdintctxt->nreq = 0;
|
||||
|
||||
return kbdintctxt;
|
||||
}
|
||||
static void
|
||||
kbdint_reset_device(KbdintAuthctxt *kbdintctxt)
|
||||
{
|
||||
if (kbdintctxt->ctxt) {
|
||||
kbdintctxt->device->free_ctx(kbdintctxt->ctxt);
|
||||
kbdintctxt->ctxt = NULL;
|
||||
}
|
||||
kbdintctxt->device = NULL;
|
||||
}
|
||||
static void
|
||||
kbdint_free(KbdintAuthctxt *kbdintctxt)
|
||||
{
|
||||
if (kbdintctxt->device)
|
||||
kbdint_reset_device(kbdintctxt);
|
||||
free(kbdintctxt->devices);
|
||||
freezero(kbdintctxt, sizeof(*kbdintctxt));
|
||||
}
|
||||
/* get next device */
|
||||
static int
|
||||
kbdint_next_device(Authctxt *authctxt, KbdintAuthctxt *kbdintctxt)
|
||||
{
|
||||
size_t len;
|
||||
char *t;
|
||||
int i;
|
||||
|
||||
if (kbdintctxt->device)
|
||||
kbdint_reset_device(kbdintctxt);
|
||||
do {
|
||||
len = kbdintctxt->devices ?
|
||||
strcspn(kbdintctxt->devices, ",") : 0;
|
||||
|
||||
if (len == 0)
|
||||
break;
|
||||
for (i = 0; devices[i]; i++) {
|
||||
if ((kbdintctxt->devices_done & (1 << i)) != 0 ||
|
||||
!auth2_method_allowed(authctxt,
|
||||
"keyboard-interactive", devices[i]->name))
|
||||
continue;
|
||||
if (strncmp(kbdintctxt->devices, devices[i]->name,
|
||||
len) == 0) {
|
||||
kbdintctxt->device = devices[i];
|
||||
kbdintctxt->devices_done |= 1 << i;
|
||||
}
|
||||
}
|
||||
t = kbdintctxt->devices;
|
||||
kbdintctxt->devices = t[len] ? xstrdup(t+len+1) : NULL;
|
||||
free(t);
|
||||
debug2("kbdint_next_device: devices %s", kbdintctxt->devices ?
|
||||
kbdintctxt->devices : "<empty>");
|
||||
} while (kbdintctxt->devices && !kbdintctxt->device);
|
||||
|
||||
return kbdintctxt->device ? 1 : 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* try challenge-response, set authctxt->postponed if we have to
|
||||
* wait for the response.
|
||||
*/
|
||||
int
|
||||
auth2_challenge(struct ssh *ssh, char *devs)
|
||||
{
|
||||
Authctxt *authctxt = ssh->authctxt;
|
||||
debug("auth2_challenge: user=%s devs=%s",
|
||||
authctxt->user ? authctxt->user : "<nouser>",
|
||||
devs ? devs : "<no devs>");
|
||||
|
||||
if (authctxt->user == NULL || !devs)
|
||||
return 0;
|
||||
if (authctxt->kbdintctxt == NULL)
|
||||
authctxt->kbdintctxt = kbdint_alloc(devs);
|
||||
return auth2_challenge_start(ssh);
|
||||
}
|
||||
|
||||
/* unregister kbd-int callbacks and context */
|
||||
void
|
||||
auth2_challenge_stop(struct ssh *ssh)
|
||||
{
|
||||
Authctxt *authctxt = ssh->authctxt;
|
||||
/* unregister callback */
|
||||
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_INFO_RESPONSE, NULL);
|
||||
if (authctxt->kbdintctxt != NULL) {
|
||||
kbdint_free(authctxt->kbdintctxt);
|
||||
authctxt->kbdintctxt = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* side effect: sets authctxt->postponed if a reply was sent*/
|
||||
static int
|
||||
auth2_challenge_start(struct ssh *ssh)
|
||||
{
|
||||
Authctxt *authctxt = ssh->authctxt;
|
||||
KbdintAuthctxt *kbdintctxt = authctxt->kbdintctxt;
|
||||
|
||||
debug2("auth2_challenge_start: devices %s",
|
||||
kbdintctxt->devices ? kbdintctxt->devices : "<empty>");
|
||||
|
||||
if (kbdint_next_device(authctxt, kbdintctxt) == 0) {
|
||||
auth2_challenge_stop(ssh);
|
||||
return 0;
|
||||
}
|
||||
debug("auth2_challenge_start: trying authentication method '%s'",
|
||||
kbdintctxt->device->name);
|
||||
|
||||
if ((kbdintctxt->ctxt = kbdintctxt->device->init_ctx(authctxt)) == NULL) {
|
||||
auth2_challenge_stop(ssh);
|
||||
return 0;
|
||||
}
|
||||
if (send_userauth_info_request(ssh) == 0) {
|
||||
auth2_challenge_stop(ssh);
|
||||
return 0;
|
||||
}
|
||||
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_INFO_RESPONSE,
|
||||
&input_userauth_info_response);
|
||||
|
||||
authctxt->postponed = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
send_userauth_info_request(struct ssh *ssh)
|
||||
{
|
||||
Authctxt *authctxt = ssh->authctxt;
|
||||
KbdintAuthctxt *kbdintctxt;
|
||||
char *name, *instr, **prompts;
|
||||
u_int r, i, *echo_on;
|
||||
|
||||
kbdintctxt = authctxt->kbdintctxt;
|
||||
if (kbdintctxt->device->query(kbdintctxt->ctxt,
|
||||
&name, &instr, &kbdintctxt->nreq, &prompts, &echo_on))
|
||||
return 0;
|
||||
|
||||
if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_INFO_REQUEST)) != 0 ||
|
||||
(r = sshpkt_put_cstring(ssh, name)) != 0 ||
|
||||
(r = sshpkt_put_cstring(ssh, instr)) != 0 ||
|
||||
(r = sshpkt_put_cstring(ssh, "")) != 0 || /* language not used */
|
||||
(r = sshpkt_put_u32(ssh, kbdintctxt->nreq)) != 0)
|
||||
fatal_fr(r, "start packet");
|
||||
for (i = 0; i < kbdintctxt->nreq; i++) {
|
||||
if ((r = sshpkt_put_cstring(ssh, prompts[i])) != 0 ||
|
||||
(r = sshpkt_put_u8(ssh, echo_on[i])) != 0)
|
||||
fatal_fr(r, "assemble packet");
|
||||
}
|
||||
if ((r = sshpkt_send(ssh)) != 0 ||
|
||||
(r = ssh_packet_write_wait(ssh)) != 0)
|
||||
fatal_fr(r, "send packet");
|
||||
|
||||
for (i = 0; i < kbdintctxt->nreq; i++)
|
||||
free(prompts[i]);
|
||||
free(prompts);
|
||||
free(echo_on);
|
||||
free(name);
|
||||
free(instr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
input_userauth_info_response(int type, u_int32_t seq, struct ssh *ssh)
|
||||
{
|
||||
Authctxt *authctxt = ssh->authctxt;
|
||||
KbdintAuthctxt *kbdintctxt;
|
||||
int authenticated = 0, res;
|
||||
int r;
|
||||
u_int i, nresp;
|
||||
const char *devicename = NULL;
|
||||
char **response = NULL;
|
||||
|
||||
if (authctxt == NULL)
|
||||
fatal_f("no authctxt");
|
||||
kbdintctxt = authctxt->kbdintctxt;
|
||||
if (kbdintctxt == NULL || kbdintctxt->ctxt == NULL)
|
||||
fatal_f("no kbdintctxt");
|
||||
if (kbdintctxt->device == NULL)
|
||||
fatal_f("no device");
|
||||
|
||||
authctxt->postponed = 0; /* reset */
|
||||
if ((r = sshpkt_get_u32(ssh, &nresp)) != 0)
|
||||
fatal_fr(r, "parse packet");
|
||||
if (nresp != kbdintctxt->nreq)
|
||||
fatal_f("wrong number of replies");
|
||||
if (nresp > 100)
|
||||
fatal_f("too many replies");
|
||||
if (nresp > 0) {
|
||||
response = xcalloc(nresp, sizeof(char *));
|
||||
for (i = 0; i < nresp; i++) {
|
||||
if ((r = sshpkt_get_cstring(ssh, &response[i], NULL)) != 0)
|
||||
fatal_fr(r, "parse response");
|
||||
}
|
||||
}
|
||||
if ((r = sshpkt_get_end(ssh)) != 0)
|
||||
fatal_fr(r, "parse packet");
|
||||
|
||||
res = kbdintctxt->device->respond(kbdintctxt->ctxt, nresp, response);
|
||||
|
||||
for (i = 0; i < nresp; i++) {
|
||||
explicit_bzero(response[i], strlen(response[i]));
|
||||
free(response[i]);
|
||||
}
|
||||
free(response);
|
||||
|
||||
switch (res) {
|
||||
case 0:
|
||||
/* Success! */
|
||||
authenticated = authctxt->valid ? 1 : 0;
|
||||
break;
|
||||
case 1:
|
||||
/* Authentication needs further interaction */
|
||||
if (send_userauth_info_request(ssh) == 1)
|
||||
authctxt->postponed = 1;
|
||||
break;
|
||||
default:
|
||||
/* Failure! */
|
||||
break;
|
||||
}
|
||||
devicename = kbdintctxt->device->name;
|
||||
if (!authctxt->postponed) {
|
||||
if (authenticated) {
|
||||
auth2_challenge_stop(ssh);
|
||||
} else {
|
||||
/* start next device */
|
||||
/* may set authctxt->postponed */
|
||||
auth2_challenge_start(ssh);
|
||||
}
|
||||
}
|
||||
userauth_finish(ssh, authenticated, "keyboard-interactive",
|
||||
devicename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
privsep_challenge_enable(void)
|
||||
{
|
||||
#if defined(BSD_AUTH) || defined(USE_PAM)
|
||||
int n = 0;
|
||||
#endif
|
||||
#ifdef BSD_AUTH
|
||||
extern KbdintDevice mm_bsdauth_device;
|
||||
#endif
|
||||
#ifdef USE_PAM
|
||||
extern KbdintDevice mm_sshpam_device;
|
||||
#endif
|
||||
|
||||
#ifdef BSD_AUTH
|
||||
devices[n++] = &mm_bsdauth_device;
|
||||
#else
|
||||
#ifdef USE_PAM
|
||||
devices[n++] = &mm_sshpam_device;
|
||||
#endif
|
||||
#endif
|
||||
}
|
332
auth2-gss.c
Normal file
332
auth2-gss.c
Normal file
|
@ -0,0 +1,332 @@
|
|||
/* $OpenBSD: auth2-gss.c,v 1.36 2024/05/17 04:42:13 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001-2003 Simon Wilkinson. 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 GSSAPI
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "sshkey.h"
|
||||
#include "hostfile.h"
|
||||
#include "auth.h"
|
||||
#include "ssh2.h"
|
||||
#include "log.h"
|
||||
#include "dispatch.h"
|
||||
#include "sshbuf.h"
|
||||
#include "ssherr.h"
|
||||
#include "misc.h"
|
||||
#include "servconf.h"
|
||||
#include "packet.h"
|
||||
#include "kex.h"
|
||||
#include "ssh-gss.h"
|
||||
#include "monitor_wrap.h"
|
||||
|
||||
#define SSH_GSSAPI_MAX_MECHS 2048
|
||||
|
||||
extern ServerOptions options;
|
||||
extern struct authmethod_cfg methodcfg_gssapi;
|
||||
|
||||
static int input_gssapi_token(int type, u_int32_t plen, struct ssh *ssh);
|
||||
static int input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh);
|
||||
static int input_gssapi_exchange_complete(int type, u_int32_t plen, struct ssh *ssh);
|
||||
static int input_gssapi_errtok(int, u_int32_t, struct ssh *);
|
||||
|
||||
/*
|
||||
* We only support those mechanisms that we know about (ie ones that we know
|
||||
* how to check local user kuserok and the like)
|
||||
*/
|
||||
static int
|
||||
userauth_gssapi(struct ssh *ssh, const char *method)
|
||||
{
|
||||
Authctxt *authctxt = ssh->authctxt;
|
||||
gss_OID_desc goid = {0, NULL};
|
||||
Gssctxt *ctxt = NULL;
|
||||
int r, present;
|
||||
u_int mechs;
|
||||
OM_uint32 ms;
|
||||
size_t len;
|
||||
u_char *doid = NULL;
|
||||
|
||||
if ((r = sshpkt_get_u32(ssh, &mechs)) != 0)
|
||||
fatal_fr(r, "parse packet");
|
||||
|
||||
if (mechs == 0) {
|
||||
logit_f("mechanism negotiation is not supported");
|
||||
return (0);
|
||||
} else if (mechs > SSH_GSSAPI_MAX_MECHS) {
|
||||
logit_f("too many mechanisms requested %u > %u", mechs,
|
||||
SSH_GSSAPI_MAX_MECHS);
|
||||
return (0);
|
||||
}
|
||||
|
||||
do {
|
||||
mechs--;
|
||||
|
||||
free(doid);
|
||||
|
||||
present = 0;
|
||||
if ((r = sshpkt_get_string(ssh, &doid, &len)) != 0)
|
||||
fatal_fr(r, "parse oid");
|
||||
|
||||
if (len > 2 && doid[0] == SSH_GSS_OIDTYPE &&
|
||||
doid[1] == len - 2) {
|
||||
goid.elements = doid + 2;
|
||||
goid.length = len - 2;
|
||||
ssh_gssapi_test_oid_supported(&ms, &goid, &present);
|
||||
} else {
|
||||
logit_f("badly formed OID received");
|
||||
}
|
||||
} while (mechs > 0 && !present);
|
||||
|
||||
if (!present) {
|
||||
free(doid);
|
||||
authctxt->server_caused_failure = 1;
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (!authctxt->valid || authctxt->user == NULL) {
|
||||
debug2_f("disabled because of invalid user");
|
||||
free(doid);
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (GSS_ERROR(mm_ssh_gssapi_server_ctx(&ctxt, &goid))) {
|
||||
if (ctxt != NULL)
|
||||
ssh_gssapi_delete_ctx(&ctxt);
|
||||
free(doid);
|
||||
authctxt->server_caused_failure = 1;
|
||||
return (0);
|
||||
}
|
||||
|
||||
authctxt->methoddata = (void *)ctxt;
|
||||
|
||||
/* Return the OID that we received */
|
||||
if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_GSSAPI_RESPONSE)) != 0 ||
|
||||
(r = sshpkt_put_string(ssh, doid, len)) != 0 ||
|
||||
(r = sshpkt_send(ssh)) != 0)
|
||||
fatal_fr(r, "send packet");
|
||||
|
||||
free(doid);
|
||||
|
||||
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, &input_gssapi_token);
|
||||
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, &input_gssapi_errtok);
|
||||
authctxt->postponed = 1;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
input_gssapi_token(int type, u_int32_t plen, struct ssh *ssh)
|
||||
{
|
||||
Authctxt *authctxt = ssh->authctxt;
|
||||
Gssctxt *gssctxt;
|
||||
gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
|
||||
gss_buffer_desc recv_tok;
|
||||
OM_uint32 maj_status, min_status, flags;
|
||||
u_char *p;
|
||||
size_t len;
|
||||
int r;
|
||||
|
||||
if (authctxt == NULL)
|
||||
fatal("No authentication or GSSAPI context");
|
||||
|
||||
gssctxt = authctxt->methoddata;
|
||||
if ((r = sshpkt_get_string(ssh, &p, &len)) != 0 ||
|
||||
(r = sshpkt_get_end(ssh)) != 0)
|
||||
fatal_fr(r, "parse packet");
|
||||
|
||||
recv_tok.value = p;
|
||||
recv_tok.length = len;
|
||||
maj_status = mm_ssh_gssapi_accept_ctx(gssctxt, &recv_tok,
|
||||
&send_tok, &flags);
|
||||
|
||||
free(p);
|
||||
|
||||
if (GSS_ERROR(maj_status)) {
|
||||
if (send_tok.length != 0) {
|
||||
if ((r = sshpkt_start(ssh,
|
||||
SSH2_MSG_USERAUTH_GSSAPI_ERRTOK)) != 0 ||
|
||||
(r = sshpkt_put_string(ssh, send_tok.value,
|
||||
send_tok.length)) != 0 ||
|
||||
(r = sshpkt_send(ssh)) != 0)
|
||||
fatal_fr(r, "send ERRTOK packet");
|
||||
}
|
||||
authctxt->postponed = 0;
|
||||
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
|
||||
userauth_finish(ssh, 0, "gssapi-with-mic", NULL);
|
||||
} else {
|
||||
if (send_tok.length != 0) {
|
||||
if ((r = sshpkt_start(ssh,
|
||||
SSH2_MSG_USERAUTH_GSSAPI_TOKEN)) != 0 ||
|
||||
(r = sshpkt_put_string(ssh, send_tok.value,
|
||||
send_tok.length)) != 0 ||
|
||||
(r = sshpkt_send(ssh)) != 0)
|
||||
fatal_fr(r, "send TOKEN packet");
|
||||
}
|
||||
if (maj_status == GSS_S_COMPLETE) {
|
||||
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
|
||||
if (flags & GSS_C_INTEG_FLAG)
|
||||
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_MIC,
|
||||
&input_gssapi_mic);
|
||||
else
|
||||
ssh_dispatch_set(ssh,
|
||||
SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE,
|
||||
&input_gssapi_exchange_complete);
|
||||
}
|
||||
}
|
||||
|
||||
gss_release_buffer(&min_status, &send_tok);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
input_gssapi_errtok(int type, u_int32_t plen, struct ssh *ssh)
|
||||
{
|
||||
Authctxt *authctxt = ssh->authctxt;
|
||||
Gssctxt *gssctxt;
|
||||
gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
|
||||
gss_buffer_desc recv_tok;
|
||||
OM_uint32 maj_status;
|
||||
int r;
|
||||
u_char *p;
|
||||
size_t len;
|
||||
|
||||
if (authctxt == NULL)
|
||||
fatal("No authentication or GSSAPI context");
|
||||
|
||||
gssctxt = authctxt->methoddata;
|
||||
if ((r = sshpkt_get_string(ssh, &p, &len)) != 0 ||
|
||||
(r = sshpkt_get_end(ssh)) != 0)
|
||||
fatal_fr(r, "parse packet");
|
||||
recv_tok.value = p;
|
||||
recv_tok.length = len;
|
||||
|
||||
/* Push the error token into GSSAPI to see what it says */
|
||||
maj_status = mm_ssh_gssapi_accept_ctx(gssctxt, &recv_tok,
|
||||
&send_tok, NULL);
|
||||
|
||||
free(recv_tok.value);
|
||||
|
||||
/* We can't return anything to the client, even if we wanted to */
|
||||
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
|
||||
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL);
|
||||
|
||||
/* The client will have already moved on to the next auth */
|
||||
|
||||
gss_release_buffer(&maj_status, &send_tok);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is called when the client thinks we've completed authentication.
|
||||
* It should only be enabled in the dispatch handler by the function above,
|
||||
* which only enables it once the GSSAPI exchange is complete.
|
||||
*/
|
||||
|
||||
static int
|
||||
input_gssapi_exchange_complete(int type, u_int32_t plen, struct ssh *ssh)
|
||||
{
|
||||
Authctxt *authctxt = ssh->authctxt;
|
||||
int r, authenticated;
|
||||
|
||||
if (authctxt == NULL)
|
||||
fatal("No authentication or GSSAPI context");
|
||||
|
||||
/*
|
||||
* We don't need to check the status, because we're only enabled in
|
||||
* the dispatcher once the exchange is complete
|
||||
*/
|
||||
|
||||
if ((r = sshpkt_get_end(ssh)) != 0)
|
||||
fatal_fr(r, "parse packet");
|
||||
|
||||
authenticated = mm_ssh_gssapi_userok(authctxt->user);
|
||||
|
||||
authctxt->postponed = 0;
|
||||
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
|
||||
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL);
|
||||
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_MIC, NULL);
|
||||
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL);
|
||||
userauth_finish(ssh, authenticated, "gssapi-with-mic", NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh)
|
||||
{
|
||||
Authctxt *authctxt = ssh->authctxt;
|
||||
Gssctxt *gssctxt;
|
||||
int r, authenticated = 0;
|
||||
struct sshbuf *b;
|
||||
gss_buffer_desc mic, gssbuf;
|
||||
u_char *p;
|
||||
size_t len;
|
||||
|
||||
if (authctxt == NULL)
|
||||
fatal("No authentication or GSSAPI context");
|
||||
|
||||
gssctxt = authctxt->methoddata;
|
||||
|
||||
if ((r = sshpkt_get_string(ssh, &p, &len)) != 0)
|
||||
fatal_fr(r, "parse packet");
|
||||
if ((b = sshbuf_new()) == NULL)
|
||||
fatal_f("sshbuf_new failed");
|
||||
mic.value = p;
|
||||
mic.length = len;
|
||||
ssh_gssapi_buildmic(b, authctxt->user, authctxt->service,
|
||||
"gssapi-with-mic", ssh->kex->session_id);
|
||||
|
||||
if ((gssbuf.value = sshbuf_mutable_ptr(b)) == NULL)
|
||||
fatal_f("sshbuf_mutable_ptr failed");
|
||||
gssbuf.length = sshbuf_len(b);
|
||||
|
||||
if (!GSS_ERROR(mm_ssh_gssapi_checkmic(gssctxt, &gssbuf, &mic)))
|
||||
authenticated = mm_ssh_gssapi_userok(authctxt->user);
|
||||
else
|
||||
logit("GSSAPI MIC check failed");
|
||||
|
||||
sshbuf_free(b);
|
||||
free(mic.value);
|
||||
|
||||
authctxt->postponed = 0;
|
||||
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
|
||||
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL);
|
||||
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_MIC, NULL);
|
||||
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL);
|
||||
userauth_finish(ssh, authenticated, "gssapi-with-mic", NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Authmethod method_gssapi = {
|
||||
&methodcfg_gssapi,
|
||||
userauth_gssapi,
|
||||
};
|
||||
|
||||
#endif /* GSSAPI */
|
258
auth2-hostbased.c
Normal file
258
auth2-hostbased.c
Normal file
|
@ -0,0 +1,258 @@
|
|||
/* $OpenBSD: auth2-hostbased.c,v 1.53 2024/05/17 00:30:23 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"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <pwd.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "ssh2.h"
|
||||
#include "packet.h"
|
||||
#include "kex.h"
|
||||
#include "sshbuf.h"
|
||||
#include "log.h"
|
||||
#include "misc.h"
|
||||
#include "servconf.h"
|
||||
#include "sshkey.h"
|
||||
#include "hostfile.h"
|
||||
#include "auth.h"
|
||||
#include "canohost.h"
|
||||
#ifdef GSSAPI
|
||||
#include "ssh-gss.h"
|
||||
#endif
|
||||
#include "monitor_wrap.h"
|
||||
#include "pathnames.h"
|
||||
#include "ssherr.h"
|
||||
#include "match.h"
|
||||
|
||||
/* import */
|
||||
extern ServerOptions options;
|
||||
extern struct authmethod_cfg methodcfg_hostbased;
|
||||
|
||||
static int
|
||||
userauth_hostbased(struct ssh *ssh, const char *method)
|
||||
{
|
||||
Authctxt *authctxt = ssh->authctxt;
|
||||
struct sshbuf *b;
|
||||
struct sshkey *key = NULL;
|
||||
char *pkalg, *cuser, *chost;
|
||||
u_char *pkblob, *sig;
|
||||
size_t alen, blen, slen;
|
||||
int r, pktype, authenticated = 0;
|
||||
|
||||
/* XXX use sshkey_froms() */
|
||||
if ((r = sshpkt_get_cstring(ssh, &pkalg, &alen)) != 0 ||
|
||||
(r = sshpkt_get_string(ssh, &pkblob, &blen)) != 0 ||
|
||||
(r = sshpkt_get_cstring(ssh, &chost, NULL)) != 0 ||
|
||||
(r = sshpkt_get_cstring(ssh, &cuser, NULL)) != 0 ||
|
||||
(r = sshpkt_get_string(ssh, &sig, &slen)) != 0)
|
||||
fatal_fr(r, "parse packet");
|
||||
|
||||
debug_f("cuser %s chost %s pkalg %s slen %zu",
|
||||
cuser, chost, pkalg, slen);
|
||||
#ifdef DEBUG_PK
|
||||
debug("signature:");
|
||||
sshbuf_dump_data(sig, slen, stderr);
|
||||
#endif
|
||||
pktype = sshkey_type_from_name(pkalg);
|
||||
if (pktype == KEY_UNSPEC) {
|
||||
/* this is perfectly legal */
|
||||
logit_f("unsupported public key algorithm: %s",
|
||||
pkalg);
|
||||
goto done;
|
||||
}
|
||||
if ((r = sshkey_from_blob(pkblob, blen, &key)) != 0) {
|
||||
error_fr(r, "key_from_blob");
|
||||
goto done;
|
||||
}
|
||||
if (key == NULL) {
|
||||
error_f("cannot decode key: %s", pkalg);
|
||||
goto done;
|
||||
}
|
||||
if (key->type != pktype) {
|
||||
error_f("type mismatch for decoded key "
|
||||
"(received %d, expected %d)", key->type, pktype);
|
||||
goto done;
|
||||
}
|
||||
if (match_pattern_list(pkalg, options.hostbased_accepted_algos, 0) != 1) {
|
||||
logit_f("signature algorithm %s not in "
|
||||
"HostbasedAcceptedAlgorithms", pkalg);
|
||||
goto done;
|
||||
}
|
||||
if ((r = sshkey_check_cert_sigtype(key,
|
||||
options.ca_sign_algorithms)) != 0) {
|
||||
logit_fr(r, "certificate signature algorithm %s",
|
||||
(key->cert == NULL || key->cert->signature_type == NULL) ?
|
||||
"(null)" : key->cert->signature_type);
|
||||
goto done;
|
||||
}
|
||||
if ((r = sshkey_check_rsa_length(key,
|
||||
options.required_rsa_size)) != 0) {
|
||||
logit_r(r, "refusing %s key", sshkey_type(key));
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!authctxt->valid || authctxt->user == NULL) {
|
||||
debug2_f("disabled because of invalid user");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if ((b = sshbuf_new()) == NULL)
|
||||
fatal_f("sshbuf_new failed");
|
||||
/* reconstruct packet */
|
||||
if ((r = sshbuf_put_stringb(b, ssh->kex->session_id)) != 0 ||
|
||||
(r = sshbuf_put_u8(b, SSH2_MSG_USERAUTH_REQUEST)) != 0 ||
|
||||
(r = sshbuf_put_cstring(b, authctxt->user)) != 0 ||
|
||||
(r = sshbuf_put_cstring(b, authctxt->service)) != 0 ||
|
||||
(r = sshbuf_put_cstring(b, method)) != 0 ||
|
||||
(r = sshbuf_put_string(b, pkalg, alen)) != 0 ||
|
||||
(r = sshbuf_put_string(b, pkblob, blen)) != 0 ||
|
||||
(r = sshbuf_put_cstring(b, chost)) != 0 ||
|
||||
(r = sshbuf_put_cstring(b, cuser)) != 0)
|
||||
fatal_fr(r, "reconstruct packet");
|
||||
#ifdef DEBUG_PK
|
||||
sshbuf_dump(b, stderr);
|
||||
#endif
|
||||
|
||||
auth2_record_info(authctxt,
|
||||
"client user \"%.100s\", client host \"%.100s\"", cuser, chost);
|
||||
|
||||
/* test for allowed key and correct signature */
|
||||
authenticated = 0;
|
||||
if (mm_hostbased_key_allowed(ssh, authctxt->pw, cuser,
|
||||
chost, key) &&
|
||||
mm_sshkey_verify(key, sig, slen,
|
||||
sshbuf_ptr(b), sshbuf_len(b), pkalg, ssh->compat, NULL) == 0)
|
||||
authenticated = 1;
|
||||
|
||||
auth2_record_key(authctxt, authenticated, key);
|
||||
sshbuf_free(b);
|
||||
done:
|
||||
debug2_f("authenticated %d", authenticated);
|
||||
sshkey_free(key);
|
||||
free(pkalg);
|
||||
free(pkblob);
|
||||
free(cuser);
|
||||
free(chost);
|
||||
free(sig);
|
||||
return authenticated;
|
||||
}
|
||||
|
||||
/* return 1 if given hostkey is allowed */
|
||||
int
|
||||
hostbased_key_allowed(struct ssh *ssh, struct passwd *pw,
|
||||
const char *cuser, char *chost, struct sshkey *key)
|
||||
{
|
||||
const char *resolvedname, *ipaddr, *lookup, *reason;
|
||||
HostStatus host_status;
|
||||
int len;
|
||||
char *fp;
|
||||
|
||||
if (auth_key_is_revoked(key))
|
||||
return 0;
|
||||
|
||||
resolvedname = auth_get_canonical_hostname(ssh, options.use_dns);
|
||||
ipaddr = ssh_remote_ipaddr(ssh);
|
||||
|
||||
debug2_f("chost %s resolvedname %s ipaddr %s",
|
||||
chost, resolvedname, ipaddr);
|
||||
|
||||
if (((len = strlen(chost)) > 0) && chost[len - 1] == '.') {
|
||||
debug2("stripping trailing dot from chost %s", chost);
|
||||
chost[len - 1] = '\0';
|
||||
}
|
||||
|
||||
if (options.hostbased_uses_name_from_packet_only) {
|
||||
if (auth_rhosts2(pw, cuser, chost, chost) == 0) {
|
||||
debug2_f("auth_rhosts2 refused user \"%.100s\" "
|
||||
"host \"%.100s\" (from packet)", cuser, chost);
|
||||
return 0;
|
||||
}
|
||||
lookup = chost;
|
||||
} else {
|
||||
if (strcasecmp(resolvedname, chost) != 0)
|
||||
logit("userauth_hostbased mismatch: "
|
||||
"client sends %s, but we resolve %s to %s",
|
||||
chost, ipaddr, resolvedname);
|
||||
if (auth_rhosts2(pw, cuser, resolvedname, ipaddr) == 0) {
|
||||
debug2_f("auth_rhosts2 refused "
|
||||
"user \"%.100s\" host \"%.100s\" addr \"%.100s\"",
|
||||
cuser, resolvedname, ipaddr);
|
||||
return 0;
|
||||
}
|
||||
lookup = resolvedname;
|
||||
}
|
||||
debug2_f("access allowed by auth_rhosts2");
|
||||
|
||||
if (sshkey_is_cert(key) &&
|
||||
sshkey_cert_check_authority_now(key, 1, 0, 0, lookup, &reason)) {
|
||||
error("%s", reason);
|
||||
auth_debug_add("%s", reason);
|
||||
return 0;
|
||||
}
|
||||
|
||||
host_status = check_key_in_hostfiles(pw, key, lookup,
|
||||
_PATH_SSH_SYSTEM_HOSTFILE,
|
||||
options.ignore_user_known_hosts ? NULL : _PATH_SSH_USER_HOSTFILE);
|
||||
|
||||
/* backward compat if no key has been found. */
|
||||
if (host_status == HOST_NEW) {
|
||||
host_status = check_key_in_hostfiles(pw, key, lookup,
|
||||
_PATH_SSH_SYSTEM_HOSTFILE2,
|
||||
options.ignore_user_known_hosts ? NULL :
|
||||
_PATH_SSH_USER_HOSTFILE2);
|
||||
}
|
||||
|
||||
if (host_status == HOST_OK) {
|
||||
if (sshkey_is_cert(key)) {
|
||||
if ((fp = sshkey_fingerprint(key->cert->signature_key,
|
||||
options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL)
|
||||
fatal_f("sshkey_fingerprint fail");
|
||||
verbose("Accepted certificate ID \"%s\" signed by "
|
||||
"%s CA %s from %s@%s", key->cert->key_id,
|
||||
sshkey_type(key->cert->signature_key), fp,
|
||||
cuser, lookup);
|
||||
} else {
|
||||
if ((fp = sshkey_fingerprint(key,
|
||||
options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL)
|
||||
fatal_f("sshkey_fingerprint fail");
|
||||
verbose("Accepted %s public key %s from %s@%s",
|
||||
sshkey_type(key), fp, cuser, lookup);
|
||||
}
|
||||
free(fp);
|
||||
}
|
||||
|
||||
return (host_status == HOST_OK);
|
||||
}
|
||||
|
||||
Authmethod method_hostbased = {
|
||||
&methodcfg_hostbased,
|
||||
userauth_hostbased,
|
||||
};
|
71
auth2-kbdint.c
Normal file
71
auth2-kbdint.c
Normal file
|
@ -0,0 +1,71 @@
|
|||
/* $OpenBSD: auth2-kbdint.c,v 1.15 2024/05/17 00:30:23 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"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "packet.h"
|
||||
#include "hostfile.h"
|
||||
#include "auth.h"
|
||||
#include "log.h"
|
||||
#include "misc.h"
|
||||
#include "servconf.h"
|
||||
#include "ssherr.h"
|
||||
|
||||
/* import */
|
||||
extern ServerOptions options;
|
||||
extern struct authmethod_cfg methodcfg_kbdint;
|
||||
|
||||
static int
|
||||
userauth_kbdint(struct ssh *ssh, const char *method)
|
||||
{
|
||||
int r, authenticated = 0;
|
||||
char *lang, *devs;
|
||||
|
||||
if ((r = sshpkt_get_cstring(ssh, &lang, NULL)) != 0 ||
|
||||
(r = sshpkt_get_cstring(ssh, &devs, NULL)) != 0 ||
|
||||
(r = sshpkt_get_end(ssh)) != 0)
|
||||
fatal_fr(r, "parse packet");
|
||||
|
||||
debug("keyboard-interactive devs %s", devs);
|
||||
|
||||
if (options.kbd_interactive_authentication)
|
||||
authenticated = auth2_challenge(ssh, devs);
|
||||
|
||||
free(devs);
|
||||
free(lang);
|
||||
return authenticated;
|
||||
}
|
||||
|
||||
Authmethod method_kbdint = {
|
||||
&methodcfg_kbdint,
|
||||
userauth_kbdint,
|
||||
};
|
134
auth2-methods.c
Normal file
134
auth2-methods.c
Normal file
|
@ -0,0 +1,134 @@
|
|||
/*
|
||||
* Copyright (c) 2012,2023 Damien Miller <djm@mindrot.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "log.h"
|
||||
#include "misc.h"
|
||||
#include "servconf.h"
|
||||
#include "xmalloc.h"
|
||||
#include "hostfile.h"
|
||||
#include "auth.h"
|
||||
|
||||
extern ServerOptions options;
|
||||
|
||||
/*
|
||||
* Configuration of enabled authentication methods. Separate from the rest of
|
||||
* auth2-*.c because we want to query it during server configuration validity
|
||||
* checking in the sshd listener process without pulling all the auth code in
|
||||
* too.
|
||||
*/
|
||||
|
||||
/* "none" is allowed only one time and it is cleared by userauth_none() later */
|
||||
int none_enabled = 1;
|
||||
struct authmethod_cfg methodcfg_none = {
|
||||
"none",
|
||||
NULL,
|
||||
&none_enabled
|
||||
};
|
||||
struct authmethod_cfg methodcfg_pubkey = {
|
||||
"publickey",
|
||||
"publickey-hostbound-v00@openssh.com",
|
||||
&options.pubkey_authentication
|
||||
};
|
||||
#ifdef GSSAPI
|
||||
struct authmethod_cfg methodcfg_gssapi = {
|
||||
"gssapi-with-mic",
|
||||
NULL,
|
||||
&options.gss_authentication
|
||||
};
|
||||
#endif
|
||||
struct authmethod_cfg methodcfg_passwd = {
|
||||
"password",
|
||||
NULL,
|
||||
&options.password_authentication
|
||||
};
|
||||
struct authmethod_cfg methodcfg_kbdint = {
|
||||
"keyboard-interactive",
|
||||
NULL,
|
||||
&options.kbd_interactive_authentication
|
||||
};
|
||||
struct authmethod_cfg methodcfg_hostbased = {
|
||||
"hostbased",
|
||||
NULL,
|
||||
&options.hostbased_authentication
|
||||
};
|
||||
|
||||
static struct authmethod_cfg *authmethod_cfgs[] = {
|
||||
&methodcfg_none,
|
||||
&methodcfg_pubkey,
|
||||
#ifdef GSSAPI
|
||||
&methodcfg_gssapi,
|
||||
#endif
|
||||
&methodcfg_passwd,
|
||||
&methodcfg_kbdint,
|
||||
&methodcfg_hostbased,
|
||||
NULL
|
||||
};
|
||||
|
||||
/*
|
||||
* Check a comma-separated list of methods for validity. If need_enable is
|
||||
* non-zero, then also require that the methods are enabled.
|
||||
* Returns 0 on success or -1 if the methods list is invalid.
|
||||
*/
|
||||
int
|
||||
auth2_methods_valid(const char *_methods, int need_enable)
|
||||
{
|
||||
char *methods, *omethods, *method, *p;
|
||||
u_int i, found;
|
||||
int ret = -1;
|
||||
const struct authmethod_cfg *cfg;
|
||||
|
||||
if (*_methods == '\0') {
|
||||
error("empty authentication method list");
|
||||
return -1;
|
||||
}
|
||||
omethods = methods = xstrdup(_methods);
|
||||
while ((method = strsep(&methods, ",")) != NULL) {
|
||||
for (found = i = 0; !found && authmethod_cfgs[i] != NULL; i++) {
|
||||
cfg = authmethod_cfgs[i];
|
||||
if ((p = strchr(method, ':')) != NULL)
|
||||
*p = '\0';
|
||||
if (strcmp(method, cfg->name) != 0)
|
||||
continue;
|
||||
if (need_enable) {
|
||||
if (cfg->enabled == NULL ||
|
||||
*(cfg->enabled) == 0) {
|
||||
error("Disabled method \"%s\" in "
|
||||
"AuthenticationMethods list \"%s\"",
|
||||
method, _methods);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
if (!found) {
|
||||
error("Unknown authentication method \"%s\" in list",
|
||||
method);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
ret = 0;
|
||||
out:
|
||||
free(omethods);
|
||||
return ret;
|
||||
}
|
76
auth2-none.c
Normal file
76
auth2-none.c
Normal file
|
@ -0,0 +1,76 @@
|
|||
/* $OpenBSD: auth2-none.c,v 1.26 2024/05/17 00:30:23 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"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/uio.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "atomicio.h"
|
||||
#include "xmalloc.h"
|
||||
#include "sshkey.h"
|
||||
#include "hostfile.h"
|
||||
#include "auth.h"
|
||||
#include "packet.h"
|
||||
#include "log.h"
|
||||
#include "misc.h"
|
||||
#include "servconf.h"
|
||||
#include "ssh2.h"
|
||||
#include "ssherr.h"
|
||||
#ifdef GSSAPI
|
||||
#include "ssh-gss.h"
|
||||
#endif
|
||||
#include "monitor_wrap.h"
|
||||
|
||||
/* import */
|
||||
extern ServerOptions options;
|
||||
extern struct authmethod_cfg methodcfg_none;
|
||||
|
||||
extern int none_enabled;
|
||||
|
||||
static int
|
||||
userauth_none(struct ssh *ssh, const char *method)
|
||||
{
|
||||
int r;
|
||||
|
||||
none_enabled = 0;
|
||||
if ((r = sshpkt_get_end(ssh)) != 0)
|
||||
fatal_fr(r, "parse packet");
|
||||
if (options.permit_empty_passwd && options.password_authentication)
|
||||
return mm_auth_password(ssh, "");
|
||||
return (0);
|
||||
}
|
||||
|
||||
Authmethod method_none = {
|
||||
&methodcfg_none,
|
||||
userauth_none,
|
||||
};
|
79
auth2-passwd.c
Normal file
79
auth2-passwd.c
Normal file
|
@ -0,0 +1,79 @@
|
|||
/* $OpenBSD: auth2-passwd.c,v 1.22 2024/05/17 00:30:23 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"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "packet.h"
|
||||
#include "ssherr.h"
|
||||
#include "log.h"
|
||||
#include "sshkey.h"
|
||||
#include "hostfile.h"
|
||||
#include "auth.h"
|
||||
#ifdef GSSAPI
|
||||
#include "ssh-gss.h"
|
||||
#endif
|
||||
#include "monitor_wrap.h"
|
||||
#include "misc.h"
|
||||
#include "servconf.h"
|
||||
|
||||
/* import */
|
||||
extern ServerOptions options;
|
||||
extern struct authmethod_cfg methodcfg_passwd;
|
||||
|
||||
static int
|
||||
userauth_passwd(struct ssh *ssh, const char *method)
|
||||
{
|
||||
char *password = NULL;
|
||||
int authenticated = 0, r;
|
||||
u_char change;
|
||||
size_t len = 0;
|
||||
|
||||
if ((r = sshpkt_get_u8(ssh, &change)) != 0 ||
|
||||
(r = sshpkt_get_cstring(ssh, &password, &len)) != 0 ||
|
||||
(change && (r = sshpkt_get_cstring(ssh, NULL, NULL)) != 0) ||
|
||||
(r = sshpkt_get_end(ssh)) != 0) {
|
||||
freezero(password, len);
|
||||
fatal_fr(r, "parse packet");
|
||||
}
|
||||
|
||||
if (change)
|
||||
logit("password change not supported");
|
||||
else if (mm_auth_password(ssh, password) == 1)
|
||||
authenticated = 1;
|
||||
freezero(password, len);
|
||||
return authenticated;
|
||||
}
|
||||
|
||||
Authmethod method_passwd = {
|
||||
&methodcfg_passwd,
|
||||
userauth_passwd,
|
||||
};
|
878
auth2-pubkey.c
Normal file
878
auth2-pubkey.c
Normal file
|
@ -0,0 +1,878 @@
|
|||
/* $OpenBSD: auth2-pubkey.c,v 1.122 2024/12/12 09:09:09 dtucker Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
* Copyright (c) 2010 Damien Miller. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#ifdef HAVE_PATHS_H
|
||||
# include <paths.h>
|
||||
#endif
|
||||
#include <pwd.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <limits.h>
|
||||
#ifdef USE_SYSTEM_GLOB
|
||||
# include <glob.h>
|
||||
#else
|
||||
# include "openbsd-compat/glob.h"
|
||||
#endif
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "ssh.h"
|
||||
#include "ssh2.h"
|
||||
#include "packet.h"
|
||||
#include "kex.h"
|
||||
#include "sshbuf.h"
|
||||
#include "log.h"
|
||||
#include "misc.h"
|
||||
#include "servconf.h"
|
||||
#include "compat.h"
|
||||
#include "sshkey.h"
|
||||
#include "hostfile.h"
|
||||
#include "auth.h"
|
||||
#include "pathnames.h"
|
||||
#include "uidswap.h"
|
||||
#include "auth-options.h"
|
||||
#include "canohost.h"
|
||||
#ifdef GSSAPI
|
||||
#include "ssh-gss.h"
|
||||
#endif
|
||||
#include "monitor_wrap.h"
|
||||
#include "authfile.h"
|
||||
#include "match.h"
|
||||
#include "ssherr.h"
|
||||
#include "channels.h" /* XXX for session.h */
|
||||
#include "session.h" /* XXX for child_set_env(); refactor? */
|
||||
#include "sk-api.h"
|
||||
|
||||
/* import */
|
||||
extern ServerOptions options;
|
||||
extern struct authmethod_cfg methodcfg_pubkey;
|
||||
|
||||
static char *
|
||||
format_key(const struct sshkey *key)
|
||||
{
|
||||
char *ret, *fp = sshkey_fingerprint(key,
|
||||
options.fingerprint_hash, SSH_FP_DEFAULT);
|
||||
|
||||
xasprintf(&ret, "%s %s", sshkey_type(key), fp);
|
||||
free(fp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
userauth_pubkey(struct ssh *ssh, const char *method)
|
||||
{
|
||||
Authctxt *authctxt = ssh->authctxt;
|
||||
struct passwd *pw = authctxt->pw;
|
||||
struct sshbuf *b = NULL;
|
||||
struct sshkey *key = NULL, *hostkey = NULL;
|
||||
char *pkalg = NULL, *userstyle = NULL, *key_s = NULL, *ca_s = NULL;
|
||||
u_char *pkblob = NULL, *sig = NULL, have_sig;
|
||||
size_t blen, slen;
|
||||
int hostbound, r, pktype;
|
||||
int req_presence = 0, req_verify = 0, authenticated = 0;
|
||||
struct sshauthopt *authopts = NULL;
|
||||
struct sshkey_sig_details *sig_details = NULL;
|
||||
|
||||
hostbound = strcmp(method, "publickey-hostbound-v00@openssh.com") == 0;
|
||||
|
||||
if ((r = sshpkt_get_u8(ssh, &have_sig)) != 0 ||
|
||||
(r = sshpkt_get_cstring(ssh, &pkalg, NULL)) != 0 ||
|
||||
(r = sshpkt_get_string(ssh, &pkblob, &blen)) != 0)
|
||||
fatal_fr(r, "parse %s packet", method);
|
||||
|
||||
/* hostbound auth includes the hostkey offered at initial KEX */
|
||||
if (hostbound) {
|
||||
if ((r = sshpkt_getb_froms(ssh, &b)) != 0 ||
|
||||
(r = sshkey_fromb(b, &hostkey)) != 0)
|
||||
fatal_fr(r, "parse %s hostkey", method);
|
||||
if (ssh->kex->initial_hostkey == NULL)
|
||||
fatal_f("internal error: initial hostkey not recorded");
|
||||
if (!sshkey_equal(hostkey, ssh->kex->initial_hostkey))
|
||||
fatal_f("%s packet contained wrong host key", method);
|
||||
sshbuf_free(b);
|
||||
b = NULL;
|
||||
}
|
||||
|
||||
if (log_level_get() >= SYSLOG_LEVEL_DEBUG2) {
|
||||
char *keystring;
|
||||
struct sshbuf *pkbuf;
|
||||
|
||||
if ((pkbuf = sshbuf_from(pkblob, blen)) == NULL)
|
||||
fatal_f("sshbuf_from failed");
|
||||
if ((keystring = sshbuf_dtob64_string(pkbuf, 0)) == NULL)
|
||||
fatal_f("sshbuf_dtob64 failed");
|
||||
debug2_f("%s user %s %s public key %s %s",
|
||||
authctxt->valid ? "valid" : "invalid", authctxt->user,
|
||||
have_sig ? "attempting" : "querying", pkalg, keystring);
|
||||
sshbuf_free(pkbuf);
|
||||
free(keystring);
|
||||
}
|
||||
|
||||
pktype = sshkey_type_from_name(pkalg);
|
||||
if (pktype == KEY_UNSPEC) {
|
||||
/* this is perfectly legal */
|
||||
verbose_f("unsupported public key algorithm: %s", pkalg);
|
||||
goto done;
|
||||
}
|
||||
if ((r = sshkey_from_blob(pkblob, blen, &key)) != 0) {
|
||||
error_fr(r, "parse key");
|
||||
goto done;
|
||||
}
|
||||
if (key == NULL) {
|
||||
error_f("cannot decode key: %s", pkalg);
|
||||
goto done;
|
||||
}
|
||||
if (key->type != pktype) {
|
||||
error_f("type mismatch for decoded key "
|
||||
"(received %d, expected %d)", key->type, pktype);
|
||||
goto done;
|
||||
}
|
||||
if (auth2_key_already_used(authctxt, key)) {
|
||||
logit("refusing previously-used %s key", sshkey_type(key));
|
||||
goto done;
|
||||
}
|
||||
if (match_pattern_list(pkalg, options.pubkey_accepted_algos, 0) != 1) {
|
||||
logit_f("signature algorithm %s not in "
|
||||
"PubkeyAcceptedAlgorithms", pkalg);
|
||||
goto done;
|
||||
}
|
||||
if ((r = sshkey_check_cert_sigtype(key,
|
||||
options.ca_sign_algorithms)) != 0) {
|
||||
logit_fr(r, "certificate signature algorithm %s",
|
||||
(key->cert == NULL || key->cert->signature_type == NULL) ?
|
||||
"(null)" : key->cert->signature_type);
|
||||
goto done;
|
||||
}
|
||||
if ((r = sshkey_check_rsa_length(key,
|
||||
options.required_rsa_size)) != 0) {
|
||||
logit_r(r, "refusing %s key", sshkey_type(key));
|
||||
goto done;
|
||||
}
|
||||
key_s = format_key(key);
|
||||
if (sshkey_is_cert(key))
|
||||
ca_s = format_key(key->cert->signature_key);
|
||||
|
||||
if (have_sig) {
|
||||
debug3_f("%s have %s signature for %s%s%s",
|
||||
method, pkalg, key_s,
|
||||
ca_s == NULL ? "" : " CA ", ca_s == NULL ? "" : ca_s);
|
||||
if ((r = sshpkt_get_string(ssh, &sig, &slen)) != 0 ||
|
||||
(r = sshpkt_get_end(ssh)) != 0)
|
||||
fatal_fr(r, "parse signature packet");
|
||||
if ((b = sshbuf_new()) == NULL)
|
||||
fatal_f("sshbuf_new failed");
|
||||
if (ssh->compat & SSH_OLD_SESSIONID) {
|
||||
if ((r = sshbuf_putb(b, ssh->kex->session_id)) != 0)
|
||||
fatal_fr(r, "put old session id");
|
||||
} else {
|
||||
if ((r = sshbuf_put_stringb(b,
|
||||
ssh->kex->session_id)) != 0)
|
||||
fatal_fr(r, "put session id");
|
||||
}
|
||||
if (!authctxt->valid || authctxt->user == NULL) {
|
||||
debug2_f("disabled because of invalid user");
|
||||
goto done;
|
||||
}
|
||||
/* reconstruct packet */
|
||||
xasprintf(&userstyle, "%s%s%s", authctxt->user,
|
||||
authctxt->style ? ":" : "",
|
||||
authctxt->style ? authctxt->style : "");
|
||||
if ((r = sshbuf_put_u8(b, SSH2_MSG_USERAUTH_REQUEST)) != 0 ||
|
||||
(r = sshbuf_put_cstring(b, userstyle)) != 0 ||
|
||||
(r = sshbuf_put_cstring(b, authctxt->service)) != 0 ||
|
||||
(r = sshbuf_put_cstring(b, method)) != 0 ||
|
||||
(r = sshbuf_put_u8(b, have_sig)) != 0 ||
|
||||
(r = sshbuf_put_cstring(b, pkalg)) != 0 ||
|
||||
(r = sshbuf_put_string(b, pkblob, blen)) != 0)
|
||||
fatal_fr(r, "reconstruct %s packet", method);
|
||||
if (hostbound &&
|
||||
(r = sshkey_puts(ssh->kex->initial_hostkey, b)) != 0)
|
||||
fatal_fr(r, "reconstruct %s packet", method);
|
||||
#ifdef DEBUG_PK
|
||||
sshbuf_dump(b, stderr);
|
||||
#endif
|
||||
/* test for correct signature */
|
||||
authenticated = 0;
|
||||
if (mm_user_key_allowed(ssh, pw, key, 1, &authopts) &&
|
||||
mm_sshkey_verify(key, sig, slen,
|
||||
sshbuf_ptr(b), sshbuf_len(b),
|
||||
(ssh->compat & SSH_BUG_SIGTYPE) == 0 ? pkalg : NULL,
|
||||
ssh->compat, &sig_details) == 0) {
|
||||
authenticated = 1;
|
||||
}
|
||||
if (authenticated == 1 && sig_details != NULL) {
|
||||
auth2_record_info(authctxt, "signature count = %u",
|
||||
sig_details->sk_counter);
|
||||
debug_f("sk_counter = %u, sk_flags = 0x%02x",
|
||||
sig_details->sk_counter, sig_details->sk_flags);
|
||||
req_presence = (options.pubkey_auth_options &
|
||||
PUBKEYAUTH_TOUCH_REQUIRED) ||
|
||||
!authopts->no_require_user_presence;
|
||||
if (req_presence && (sig_details->sk_flags &
|
||||
SSH_SK_USER_PRESENCE_REQD) == 0) {
|
||||
error("public key %s signature for %s%s from "
|
||||
"%.128s port %d rejected: user presence "
|
||||
"(authenticator touch) requirement "
|
||||
"not met ", key_s,
|
||||
authctxt->valid ? "" : "invalid user ",
|
||||
authctxt->user, ssh_remote_ipaddr(ssh),
|
||||
ssh_remote_port(ssh));
|
||||
authenticated = 0;
|
||||
goto done;
|
||||
}
|
||||
req_verify = (options.pubkey_auth_options &
|
||||
PUBKEYAUTH_VERIFY_REQUIRED) ||
|
||||
authopts->require_verify;
|
||||
if (req_verify && (sig_details->sk_flags &
|
||||
SSH_SK_USER_VERIFICATION_REQD) == 0) {
|
||||
error("public key %s signature for %s%s from "
|
||||
"%.128s port %d rejected: user "
|
||||
"verification requirement not met ", key_s,
|
||||
authctxt->valid ? "" : "invalid user ",
|
||||
authctxt->user, ssh_remote_ipaddr(ssh),
|
||||
ssh_remote_port(ssh));
|
||||
authenticated = 0;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
auth2_record_key(authctxt, authenticated, key);
|
||||
} else {
|
||||
debug_f("%s test pkalg %s pkblob %s%s%s", method, pkalg, key_s,
|
||||
ca_s == NULL ? "" : " CA ", ca_s == NULL ? "" : ca_s);
|
||||
|
||||
if ((r = sshpkt_get_end(ssh)) != 0)
|
||||
fatal_fr(r, "parse packet");
|
||||
|
||||
if (!authctxt->valid || authctxt->user == NULL) {
|
||||
debug2_f("disabled because of invalid user");
|
||||
goto done;
|
||||
}
|
||||
/* XXX fake reply and always send PK_OK ? */
|
||||
/*
|
||||
* XXX this allows testing whether a user is allowed
|
||||
* to login: if you happen to have a valid pubkey this
|
||||
* message is sent. the message is NEVER sent at all
|
||||
* if a user is not allowed to login. is this an
|
||||
* issue? -markus
|
||||
*/
|
||||
if (mm_user_key_allowed(ssh, pw, key, 0, NULL)) {
|
||||
if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_PK_OK))
|
||||
!= 0 ||
|
||||
(r = sshpkt_put_cstring(ssh, pkalg)) != 0 ||
|
||||
(r = sshpkt_put_string(ssh, pkblob, blen)) != 0 ||
|
||||
(r = sshpkt_send(ssh)) != 0 ||
|
||||
(r = ssh_packet_write_wait(ssh)) != 0)
|
||||
fatal_fr(r, "send packet");
|
||||
authctxt->postponed = 1;
|
||||
}
|
||||
}
|
||||
done:
|
||||
if (authenticated == 1 && auth_activate_options(ssh, authopts) != 0) {
|
||||
debug_f("key options inconsistent with existing");
|
||||
authenticated = 0;
|
||||
}
|
||||
debug2_f("authenticated %d pkalg %s", authenticated, pkalg);
|
||||
|
||||
sshbuf_free(b);
|
||||
sshauthopt_free(authopts);
|
||||
sshkey_free(key);
|
||||
sshkey_free(hostkey);
|
||||
free(userstyle);
|
||||
free(pkalg);
|
||||
free(pkblob);
|
||||
free(key_s);
|
||||
free(ca_s);
|
||||
free(sig);
|
||||
sshkey_sig_details_free(sig_details);
|
||||
return authenticated;
|
||||
}
|
||||
|
||||
static int
|
||||
match_principals_file(struct passwd *pw, char *file,
|
||||
struct sshkey_cert *cert, struct sshauthopt **authoptsp)
|
||||
{
|
||||
FILE *f;
|
||||
int r, success = 0;
|
||||
size_t i;
|
||||
glob_t gl;
|
||||
struct sshauthopt *opts = NULL;
|
||||
|
||||
if (authoptsp != NULL)
|
||||
*authoptsp = 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);
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
globfree(&gl);
|
||||
if (success && authoptsp != NULL) {
|
||||
*authoptsp = opts;
|
||||
opts = NULL;
|
||||
}
|
||||
sshauthopt_free(opts);
|
||||
return success;
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks whether principal is allowed in output of command.
|
||||
* returns 1 if the principal is allowed or 0 otherwise.
|
||||
*/
|
||||
static int
|
||||
match_principals_command(struct passwd *user_pw, const struct sshkey *key,
|
||||
const char *conn_id, const char *rdomain, struct sshauthopt **authoptsp)
|
||||
{
|
||||
struct passwd *runas_pw = NULL;
|
||||
const struct sshkey_cert *cert = key->cert;
|
||||
FILE *f = NULL;
|
||||
int r, ok, found_principal = 0;
|
||||
int i, ac = 0, uid_swapped = 0;
|
||||
pid_t pid;
|
||||
char *tmp, *username = NULL, *command = NULL, **av = NULL;
|
||||
char *ca_fp = NULL, *key_fp = NULL, *catext = NULL, *keytext = NULL;
|
||||
char serial_s[32], uidstr[32];
|
||||
void (*osigchld)(int);
|
||||
|
||||
if (authoptsp != NULL)
|
||||
*authoptsp = NULL;
|
||||
if (options.authorized_principals_command == NULL)
|
||||
return 0;
|
||||
if (options.authorized_principals_command_user == NULL) {
|
||||
error("No user for AuthorizedPrincipalsCommand specified, "
|
||||
"skipping");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* NB. all returns later this function should go via "out" to
|
||||
* ensure the original SIGCHLD handler is restored properly.
|
||||
*/
|
||||
osigchld = ssh_signal(SIGCHLD, SIG_DFL);
|
||||
|
||||
/* Prepare and verify the user for the command */
|
||||
username = percent_expand(options.authorized_principals_command_user,
|
||||
"u", user_pw->pw_name, (char *)NULL);
|
||||
runas_pw = getpwnam(username);
|
||||
if (runas_pw == NULL) {
|
||||
error("AuthorizedPrincipalsCommandUser \"%s\" not found: %s",
|
||||
username, strerror(errno));
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Turn the command into an argument vector */
|
||||
if (argv_split(options.authorized_principals_command,
|
||||
&ac, &av, 0) != 0) {
|
||||
error("AuthorizedPrincipalsCommand \"%s\" contains "
|
||||
"invalid quotes", options.authorized_principals_command);
|
||||
goto out;
|
||||
}
|
||||
if (ac == 0) {
|
||||
error("AuthorizedPrincipalsCommand \"%s\" yielded no arguments",
|
||||
options.authorized_principals_command);
|
||||
goto out;
|
||||
}
|
||||
if ((ca_fp = sshkey_fingerprint(cert->signature_key,
|
||||
options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) {
|
||||
error_f("sshkey_fingerprint failed");
|
||||
goto out;
|
||||
}
|
||||
if ((key_fp = sshkey_fingerprint(key,
|
||||
options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) {
|
||||
error_f("sshkey_fingerprint failed");
|
||||
goto out;
|
||||
}
|
||||
if ((r = sshkey_to_base64(cert->signature_key, &catext)) != 0) {
|
||||
error_fr(r, "sshkey_to_base64 failed");
|
||||
goto out;
|
||||
}
|
||||
if ((r = sshkey_to_base64(key, &keytext)) != 0) {
|
||||
error_fr(r, "sshkey_to_base64 failed");
|
||||
goto out;
|
||||
}
|
||||
snprintf(serial_s, sizeof(serial_s), "%llu",
|
||||
(unsigned long long)cert->serial);
|
||||
snprintf(uidstr, sizeof(uidstr), "%llu",
|
||||
(unsigned long long)user_pw->pw_uid);
|
||||
for (i = 1; i < ac; i++) {
|
||||
tmp = percent_expand(av[i],
|
||||
"C", conn_id,
|
||||
"D", rdomain,
|
||||
"U", uidstr,
|
||||
"u", user_pw->pw_name,
|
||||
"h", user_pw->pw_dir,
|
||||
"t", sshkey_ssh_name(key),
|
||||
"T", sshkey_ssh_name(cert->signature_key),
|
||||
"f", key_fp,
|
||||
"F", ca_fp,
|
||||
"k", keytext,
|
||||
"K", catext,
|
||||
"i", cert->key_id,
|
||||
"s", serial_s,
|
||||
(char *)NULL);
|
||||
if (tmp == NULL)
|
||||
fatal_f("percent_expand failed");
|
||||
free(av[i]);
|
||||
av[i] = tmp;
|
||||
}
|
||||
/* Prepare a printable command for logs, etc. */
|
||||
command = argv_assemble(ac, av);
|
||||
|
||||
if ((pid = subprocess("AuthorizedPrincipalsCommand", command,
|
||||
ac, av, &f,
|
||||
SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_STDERR_DISCARD,
|
||||
runas_pw, temporarily_use_uid, restore_uid)) == 0)
|
||||
goto out;
|
||||
|
||||
uid_swapped = 1;
|
||||
temporarily_use_uid(runas_pw);
|
||||
|
||||
ok = auth_process_principals(f, "(command)", cert, authoptsp);
|
||||
|
||||
fclose(f);
|
||||
f = NULL;
|
||||
|
||||
if (exited_cleanly(pid, "AuthorizedPrincipalsCommand", command, 0) != 0)
|
||||
goto out;
|
||||
|
||||
/* Read completed successfully */
|
||||
found_principal = ok;
|
||||
out:
|
||||
if (f != NULL)
|
||||
fclose(f);
|
||||
ssh_signal(SIGCHLD, osigchld);
|
||||
for (i = 0; i < ac; i++)
|
||||
free(av[i]);
|
||||
free(av);
|
||||
if (uid_swapped)
|
||||
restore_uid();
|
||||
free(command);
|
||||
free(username);
|
||||
free(ca_fp);
|
||||
free(key_fp);
|
||||
free(catext);
|
||||
free(keytext);
|
||||
return found_principal;
|
||||
}
|
||||
|
||||
/* Authenticate a certificate key against TrustedUserCAKeys */
|
||||
static int
|
||||
user_cert_trusted_ca(struct passwd *pw, struct sshkey *key,
|
||||
const char *remote_ip, const char *remote_host,
|
||||
const char *conn_id, const char *rdomain, struct sshauthopt **authoptsp)
|
||||
{
|
||||
char *ca_fp, *principals_file = NULL;
|
||||
const char *reason;
|
||||
struct sshauthopt *principals_opts = NULL, *cert_opts = NULL;
|
||||
struct sshauthopt *final_opts = NULL;
|
||||
int r, ret = 0, found_principal = 0, use_authorized_principals;
|
||||
|
||||
if (authoptsp != NULL)
|
||||
*authoptsp = NULL;
|
||||
|
||||
if (!sshkey_is_cert(key) || options.trusted_user_ca_keys == NULL)
|
||||
return 0;
|
||||
|
||||
if ((ca_fp = sshkey_fingerprint(key->cert->signature_key,
|
||||
options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL)
|
||||
return 0;
|
||||
|
||||
if ((r = sshkey_in_file(key->cert->signature_key,
|
||||
options.trusted_user_ca_keys, 1, 0)) != 0) {
|
||||
debug2_fr(r, "CA %s %s is not listed in %s",
|
||||
sshkey_type(key->cert->signature_key), ca_fp,
|
||||
options.trusted_user_ca_keys);
|
||||
goto out;
|
||||
}
|
||||
/*
|
||||
* If AuthorizedPrincipals is in use, then compare the certificate
|
||||
* principals against the names in that file rather than matching
|
||||
* against the username.
|
||||
*/
|
||||
if ((principals_file = authorized_principals_file(pw)) != NULL) {
|
||||
if (match_principals_file(pw, principals_file,
|
||||
key->cert, &principals_opts))
|
||||
found_principal = 1;
|
||||
}
|
||||
/* Try querying command if specified */
|
||||
if (!found_principal && match_principals_command(pw, key,
|
||||
conn_id, rdomain, &principals_opts))
|
||||
found_principal = 1;
|
||||
/* If principals file or command is specified, then require a match */
|
||||
use_authorized_principals = principals_file != NULL ||
|
||||
options.authorized_principals_command != NULL;
|
||||
if (!found_principal && use_authorized_principals) {
|
||||
reason = "Certificate does not contain an authorized principal";
|
||||
goto fail_reason;
|
||||
}
|
||||
if (use_authorized_principals && principals_opts == NULL)
|
||||
fatal_f("internal error: missing principals_opts");
|
||||
if (sshkey_cert_check_authority_now(key, 0, 1, 0,
|
||||
use_authorized_principals ? NULL : pw->pw_name, &reason) != 0)
|
||||
goto fail_reason;
|
||||
|
||||
/* Check authority from options in key and from principals file/cmd */
|
||||
if ((cert_opts = sshauthopt_from_cert(key)) == NULL) {
|
||||
reason = "Invalid certificate options";
|
||||
goto fail_reason;
|
||||
}
|
||||
if (auth_authorise_keyopts(pw, cert_opts, 0,
|
||||
remote_ip, remote_host, "cert") != 0) {
|
||||
reason = "Refused by certificate options";
|
||||
goto fail_reason;
|
||||
}
|
||||
if (principals_opts == NULL) {
|
||||
final_opts = cert_opts;
|
||||
cert_opts = NULL;
|
||||
} else {
|
||||
if (auth_authorise_keyopts(pw, principals_opts, 0,
|
||||
remote_ip, remote_host, "principals") != 0) {
|
||||
reason = "Refused by certificate principals options";
|
||||
goto fail_reason;
|
||||
}
|
||||
if ((final_opts = sshauthopt_merge(principals_opts,
|
||||
cert_opts, &reason)) == NULL) {
|
||||
fail_reason:
|
||||
error("%s", reason);
|
||||
auth_debug_add("%s", reason);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
/* Success */
|
||||
verbose("Accepted certificate ID \"%s\" (serial %llu) signed by "
|
||||
"%s CA %s via %s", key->cert->key_id,
|
||||
(unsigned long long)key->cert->serial,
|
||||
sshkey_type(key->cert->signature_key), ca_fp,
|
||||
options.trusted_user_ca_keys);
|
||||
if (authoptsp != NULL) {
|
||||
*authoptsp = final_opts;
|
||||
final_opts = NULL;
|
||||
}
|
||||
ret = 1;
|
||||
out:
|
||||
sshauthopt_free(principals_opts);
|
||||
sshauthopt_free(cert_opts);
|
||||
sshauthopt_free(final_opts);
|
||||
free(principals_file);
|
||||
free(ca_fp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks whether key is allowed in file.
|
||||
* returns 1 if the key is allowed or 0 otherwise.
|
||||
*/
|
||||
static int
|
||||
user_key_allowed2(struct passwd *pw, struct sshkey *key,
|
||||
char *file, const char *remote_ip, const char *remote_host,
|
||||
struct sshauthopt **authoptsp)
|
||||
{
|
||||
FILE *f;
|
||||
int found_key = 0;
|
||||
|
||||
if (authoptsp != NULL)
|
||||
*authoptsp = NULL;
|
||||
|
||||
/* Temporarily use the user's uid. */
|
||||
temporarily_use_uid(pw);
|
||||
|
||||
debug("trying public key file %s", file);
|
||||
if ((f = auth_openkeyfile(file, pw, options.strict_modes)) != NULL) {
|
||||
found_key = auth_check_authkeys_file(pw, f, file,
|
||||
key, remote_ip, remote_host, authoptsp);
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
restore_uid();
|
||||
return found_key;
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks whether key is allowed in output of command.
|
||||
* returns 1 if the key is allowed or 0 otherwise.
|
||||
*/
|
||||
static int
|
||||
user_key_command_allowed2(struct passwd *user_pw, struct sshkey *key,
|
||||
const char *remote_ip, const char *remote_host,
|
||||
const char *conn_id, const char *rdomain, struct sshauthopt **authoptsp)
|
||||
{
|
||||
struct passwd *runas_pw = NULL;
|
||||
FILE *f = NULL;
|
||||
int r, ok, found_key = 0;
|
||||
int i, uid_swapped = 0, ac = 0;
|
||||
pid_t pid;
|
||||
char *username = NULL, *key_fp = NULL, *keytext = NULL;
|
||||
char uidstr[32], *tmp, *command = NULL, **av = NULL;
|
||||
void (*osigchld)(int);
|
||||
|
||||
if (authoptsp != NULL)
|
||||
*authoptsp = NULL;
|
||||
if (options.authorized_keys_command == NULL)
|
||||
return 0;
|
||||
if (options.authorized_keys_command_user == NULL) {
|
||||
error("No user for AuthorizedKeysCommand specified, skipping");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* NB. all returns later this function should go via "out" to
|
||||
* ensure the original SIGCHLD handler is restored properly.
|
||||
*/
|
||||
osigchld = ssh_signal(SIGCHLD, SIG_DFL);
|
||||
|
||||
/* Prepare and verify the user for the command */
|
||||
username = percent_expand(options.authorized_keys_command_user,
|
||||
"u", user_pw->pw_name, (char *)NULL);
|
||||
runas_pw = getpwnam(username);
|
||||
if (runas_pw == NULL) {
|
||||
error("AuthorizedKeysCommandUser \"%s\" not found: %s",
|
||||
username, strerror(errno));
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Prepare AuthorizedKeysCommand */
|
||||
if ((key_fp = sshkey_fingerprint(key, options.fingerprint_hash,
|
||||
SSH_FP_DEFAULT)) == NULL) {
|
||||
error_f("sshkey_fingerprint failed");
|
||||
goto out;
|
||||
}
|
||||
if ((r = sshkey_to_base64(key, &keytext)) != 0) {
|
||||
error_fr(r, "sshkey_to_base64 failed");
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Turn the command into an argument vector */
|
||||
if (argv_split(options.authorized_keys_command, &ac, &av, 0) != 0) {
|
||||
error("AuthorizedKeysCommand \"%s\" contains invalid quotes",
|
||||
options.authorized_keys_command);
|
||||
goto out;
|
||||
}
|
||||
if (ac == 0) {
|
||||
error("AuthorizedKeysCommand \"%s\" yielded no arguments",
|
||||
options.authorized_keys_command);
|
||||
goto out;
|
||||
}
|
||||
snprintf(uidstr, sizeof(uidstr), "%llu",
|
||||
(unsigned long long)user_pw->pw_uid);
|
||||
for (i = 1; i < ac; i++) {
|
||||
tmp = percent_expand(av[i],
|
||||
"C", conn_id,
|
||||
"D", rdomain,
|
||||
"U", uidstr,
|
||||
"u", user_pw->pw_name,
|
||||
"h", user_pw->pw_dir,
|
||||
"t", sshkey_ssh_name(key),
|
||||
"f", key_fp,
|
||||
"k", keytext,
|
||||
(char *)NULL);
|
||||
if (tmp == NULL)
|
||||
fatal_f("percent_expand failed");
|
||||
free(av[i]);
|
||||
av[i] = tmp;
|
||||
}
|
||||
/* Prepare a printable command for logs, etc. */
|
||||
command = argv_assemble(ac, av);
|
||||
|
||||
/*
|
||||
* If AuthorizedKeysCommand was run without arguments
|
||||
* then fall back to the old behaviour of passing the
|
||||
* target username as a single argument.
|
||||
*/
|
||||
if (ac == 1) {
|
||||
av = xreallocarray(av, ac + 2, sizeof(*av));
|
||||
av[1] = xstrdup(user_pw->pw_name);
|
||||
av[2] = NULL;
|
||||
/* Fix up command too, since it is used in log messages */
|
||||
free(command);
|
||||
xasprintf(&command, "%s %s", av[0], av[1]);
|
||||
}
|
||||
|
||||
if ((pid = subprocess("AuthorizedKeysCommand", command,
|
||||
ac, av, &f,
|
||||
SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_STDERR_DISCARD,
|
||||
runas_pw, temporarily_use_uid, restore_uid)) == 0)
|
||||
goto out;
|
||||
|
||||
uid_swapped = 1;
|
||||
temporarily_use_uid(runas_pw);
|
||||
|
||||
ok = auth_check_authkeys_file(user_pw, f,
|
||||
options.authorized_keys_command, key, remote_ip,
|
||||
remote_host, authoptsp);
|
||||
|
||||
fclose(f);
|
||||
f = NULL;
|
||||
|
||||
if (exited_cleanly(pid, "AuthorizedKeysCommand", command, 0) != 0)
|
||||
goto out;
|
||||
|
||||
/* Read completed successfully */
|
||||
found_key = ok;
|
||||
out:
|
||||
if (f != NULL)
|
||||
fclose(f);
|
||||
ssh_signal(SIGCHLD, osigchld);
|
||||
for (i = 0; i < ac; i++)
|
||||
free(av[i]);
|
||||
free(av);
|
||||
if (uid_swapped)
|
||||
restore_uid();
|
||||
free(command);
|
||||
free(username);
|
||||
free(key_fp);
|
||||
free(keytext);
|
||||
return found_key;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check whether key authenticates and authorises the user.
|
||||
*/
|
||||
int
|
||||
user_key_allowed(struct ssh *ssh, struct passwd *pw, struct sshkey *key,
|
||||
int auth_attempt, struct sshauthopt **authoptsp)
|
||||
{
|
||||
u_int success = 0, i, j;
|
||||
char *file = NULL, *conn_id;
|
||||
struct sshauthopt *opts = NULL;
|
||||
const char *rdomain, *remote_ip, *remote_host;
|
||||
|
||||
if (authoptsp != NULL)
|
||||
*authoptsp = NULL;
|
||||
|
||||
if (auth_key_is_revoked(key))
|
||||
return 0;
|
||||
if (sshkey_is_cert(key) &&
|
||||
auth_key_is_revoked(key->cert->signature_key))
|
||||
return 0;
|
||||
|
||||
if ((rdomain = ssh_packet_rdomain_in(ssh)) == NULL)
|
||||
rdomain = "";
|
||||
remote_ip = ssh_remote_ipaddr(ssh);
|
||||
remote_host = auth_get_canonical_hostname(ssh, options.use_dns);
|
||||
xasprintf(&conn_id, "%s %d %s %d",
|
||||
ssh_local_ipaddr(ssh), ssh_local_port(ssh),
|
||||
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);
|
||||
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;
|
||||
|
||||
if ((success = user_cert_trusted_ca(pw, key, remote_ip, remote_host,
|
||||
conn_id, rdomain, &opts)) != 0)
|
||||
goto out;
|
||||
sshauthopt_free(opts);
|
||||
opts = NULL;
|
||||
|
||||
if ((success = user_key_command_allowed2(pw, key, remote_ip,
|
||||
remote_host, conn_id, rdomain, &opts)) != 0)
|
||||
goto out;
|
||||
sshauthopt_free(opts);
|
||||
opts = NULL;
|
||||
|
||||
out:
|
||||
free(conn_id);
|
||||
if (success && authoptsp != NULL) {
|
||||
*authoptsp = opts;
|
||||
opts = NULL;
|
||||
}
|
||||
sshauthopt_free(opts);
|
||||
return success;
|
||||
}
|
||||
|
||||
Authmethod method_pubkey = {
|
||||
&methodcfg_pubkey,
|
||||
userauth_pubkey,
|
||||
};
|
500
auth2-pubkeyfile.c
Normal file
500
auth2-pubkeyfile.c
Normal file
|
@ -0,0 +1,500 @@
|
|||
/* $OpenBSD: auth2-pubkeyfile.c,v 1.4 2023/03/05 05:34:09 dtucker Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
* Copyright (c) 2010 Damien Miller. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "ssh.h"
|
||||
#include "log.h"
|
||||
#include "misc.h"
|
||||
#include "sshkey.h"
|
||||
#include "digest.h"
|
||||
#include "hostfile.h"
|
||||
#include "auth.h"
|
||||
#include "auth-options.h"
|
||||
#include "authfile.h"
|
||||
#include "match.h"
|
||||
#include "ssherr.h"
|
||||
|
||||
int
|
||||
auth_authorise_keyopts(struct passwd *pw, struct sshauthopt *opts,
|
||||
int allow_cert_authority, const char *remote_ip, const char *remote_host,
|
||||
const char *loc)
|
||||
{
|
||||
time_t now = time(NULL);
|
||||
char buf[64];
|
||||
|
||||
/*
|
||||
* Check keys/principals file expiry time.
|
||||
* NB. validity interval in certificate is handled elsewhere.
|
||||
*/
|
||||
if (opts->valid_before && now > 0 &&
|
||||
opts->valid_before < (uint64_t)now) {
|
||||
format_absolute_time(opts->valid_before, buf, sizeof(buf));
|
||||
debug("%s: entry expired at %s", loc, buf);
|
||||
auth_debug_add("%s: entry expired at %s", loc, buf);
|
||||
return -1;
|
||||
}
|
||||
/* Consistency checks */
|
||||
if (opts->cert_principals != NULL && !opts->cert_authority) {
|
||||
debug("%s: principals on non-CA key", loc);
|
||||
auth_debug_add("%s: principals on non-CA key", loc);
|
||||
/* deny access */
|
||||
return -1;
|
||||
}
|
||||
/* cert-authority flag isn't valid in authorized_principals files */
|
||||
if (!allow_cert_authority && opts->cert_authority) {
|
||||
debug("%s: cert-authority flag invalid here", loc);
|
||||
auth_debug_add("%s: cert-authority flag invalid here", loc);
|
||||
/* deny access */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Perform from= checks */
|
||||
if (opts->required_from_host_keys != NULL) {
|
||||
switch (match_host_and_ip(remote_host, remote_ip,
|
||||
opts->required_from_host_keys )) {
|
||||
case 1:
|
||||
/* Host name matches. */
|
||||
break;
|
||||
case -1:
|
||||
default:
|
||||
debug("%s: invalid from criteria", loc);
|
||||
auth_debug_add("%s: invalid from criteria", loc);
|
||||
/* FALLTHROUGH */
|
||||
case 0:
|
||||
logit("%s: Authentication tried for %.100s with "
|
||||
"correct key but not from a permitted "
|
||||
"host (host=%.200s, ip=%.200s, required=%.200s).",
|
||||
loc, pw->pw_name, remote_host, remote_ip,
|
||||
opts->required_from_host_keys);
|
||||
auth_debug_add("%s: Your host '%.200s' is not "
|
||||
"permitted to use this key for login.",
|
||||
loc, remote_host);
|
||||
/* deny access */
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
/* Check source-address restriction from certificate */
|
||||
if (opts->required_from_host_cert != NULL) {
|
||||
switch (addr_match_cidr_list(remote_ip,
|
||||
opts->required_from_host_cert)) {
|
||||
case 1:
|
||||
/* accepted */
|
||||
break;
|
||||
case -1:
|
||||
default:
|
||||
/* invalid */
|
||||
error("%s: Certificate source-address invalid", loc);
|
||||
/* FALLTHROUGH */
|
||||
case 0:
|
||||
logit("%s: Authentication tried for %.100s with valid "
|
||||
"certificate but not from a permitted source "
|
||||
"address (%.200s).", loc, pw->pw_name, remote_ip);
|
||||
auth_debug_add("%s: Your address '%.200s' is not "
|
||||
"permitted to use this certificate for login.",
|
||||
loc, remote_ip);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
/*
|
||||
*
|
||||
* XXX this is spammy. We should report remotely only for keys
|
||||
* that are successful in actual auth attempts, and not PK_OK
|
||||
* tests.
|
||||
*/
|
||||
auth_log_authopts(loc, opts, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
match_principals_option(const char *principal_list, struct sshkey_cert *cert)
|
||||
{
|
||||
char *result;
|
||||
u_int i;
|
||||
|
||||
/* XXX percent_expand() sequences for authorized_principals? */
|
||||
|
||||
for (i = 0; i < cert->nprincipals; i++) {
|
||||
if ((result = match_list(cert->principals[i],
|
||||
principal_list, NULL)) != NULL) {
|
||||
debug3("matched principal from key options \"%.100s\"",
|
||||
result);
|
||||
free(result);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Process a single authorized_principals format line. Returns 0 and sets
|
||||
* authoptsp is principal is authorised, -1 otherwise. "loc" is used as a
|
||||
* log preamble for file/line information.
|
||||
*/
|
||||
int
|
||||
auth_check_principals_line(char *cp, const struct sshkey_cert *cert,
|
||||
const char *loc, struct sshauthopt **authoptsp)
|
||||
{
|
||||
u_int i, found = 0;
|
||||
char *ep, *line_opts;
|
||||
const char *reason = NULL;
|
||||
struct sshauthopt *opts = NULL;
|
||||
|
||||
if (authoptsp != NULL)
|
||||
*authoptsp = NULL;
|
||||
|
||||
/* Trim trailing whitespace. */
|
||||
ep = cp + strlen(cp) - 1;
|
||||
while (ep > cp && (*ep == '\n' || *ep == ' ' || *ep == '\t'))
|
||||
*ep-- = '\0';
|
||||
|
||||
/*
|
||||
* If the line has internal whitespace then assume it has
|
||||
* key options.
|
||||
*/
|
||||
line_opts = NULL;
|
||||
if ((ep = strrchr(cp, ' ')) != NULL ||
|
||||
(ep = strrchr(cp, '\t')) != NULL) {
|
||||
for (; *ep == ' ' || *ep == '\t'; ep++)
|
||||
;
|
||||
line_opts = cp;
|
||||
cp = ep;
|
||||
}
|
||||
if ((opts = sshauthopt_parse(line_opts, &reason)) == NULL) {
|
||||
debug("%s: bad principals options: %s", loc, reason);
|
||||
auth_debug_add("%s: bad principals options: %s", loc, reason);
|
||||
return -1;
|
||||
}
|
||||
/* Check principals in cert against those on line */
|
||||
for (i = 0; i < cert->nprincipals; i++) {
|
||||
if (strcmp(cp, cert->principals[i]) != 0)
|
||||
continue;
|
||||
debug3("%s: matched principal \"%.100s\"",
|
||||
loc, cert->principals[i]);
|
||||
found = 1;
|
||||
}
|
||||
if (found && authoptsp != NULL) {
|
||||
*authoptsp = opts;
|
||||
opts = NULL;
|
||||
}
|
||||
sshauthopt_free(opts);
|
||||
return found ? 0 : -1;
|
||||
}
|
||||
|
||||
int
|
||||
auth_process_principals(FILE *f, const char *file,
|
||||
const struct sshkey_cert *cert, struct sshauthopt **authoptsp)
|
||||
{
|
||||
char loc[256], *line = NULL, *cp, *ep;
|
||||
size_t linesize = 0;
|
||||
u_long linenum = 0, nonblank = 0;
|
||||
u_int found_principal = 0;
|
||||
|
||||
if (authoptsp != NULL)
|
||||
*authoptsp = NULL;
|
||||
|
||||
while (getline(&line, &linesize, f) != -1) {
|
||||
linenum++;
|
||||
/* Always consume entire input */
|
||||
if (found_principal)
|
||||
continue;
|
||||
|
||||
/* Skip leading whitespace. */
|
||||
for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
|
||||
;
|
||||
/* Skip blank and comment lines. */
|
||||
if ((ep = strchr(cp, '#')) != NULL)
|
||||
*ep = '\0';
|
||||
if (!*cp || *cp == '\n')
|
||||
continue;
|
||||
|
||||
nonblank++;
|
||||
snprintf(loc, sizeof(loc), "%.200s:%lu", file, linenum);
|
||||
if (auth_check_principals_line(cp, cert, loc, authoptsp) == 0)
|
||||
found_principal = 1;
|
||||
}
|
||||
debug2_f("%s: processed %lu/%lu lines", file, nonblank, linenum);
|
||||
free(line);
|
||||
return found_principal;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check a single line of an authorized_keys-format file. Returns 0 if key
|
||||
* matches, -1 otherwise. Will return key/cert options via *authoptsp
|
||||
* on success. "loc" is used as file/line location in log messages.
|
||||
*/
|
||||
int
|
||||
auth_check_authkey_line(struct passwd *pw, struct sshkey *key,
|
||||
char *cp, const char *remote_ip, const char *remote_host, const char *loc,
|
||||
struct sshauthopt **authoptsp)
|
||||
{
|
||||
int want_keytype = sshkey_is_cert(key) ? KEY_UNSPEC : key->type;
|
||||
struct sshkey *found = NULL;
|
||||
struct sshauthopt *keyopts = NULL, *certopts = NULL, *finalopts = NULL;
|
||||
char *key_options = NULL, *fp = NULL;
|
||||
const char *reason = NULL;
|
||||
int ret = -1;
|
||||
|
||||
if (authoptsp != NULL)
|
||||
*authoptsp = NULL;
|
||||
|
||||
if ((found = sshkey_new(want_keytype)) == NULL) {
|
||||
debug3_f("keytype %d failed", want_keytype);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* XXX djm: peek at key type in line and skip if unwanted */
|
||||
|
||||
if (sshkey_read(found, &cp) != 0) {
|
||||
/* no key? check for options */
|
||||
debug2("%s: check options: '%s'", loc, cp);
|
||||
key_options = cp;
|
||||
if (sshkey_advance_past_options(&cp) != 0) {
|
||||
reason = "invalid key option string";
|
||||
goto fail_reason;
|
||||
}
|
||||
skip_space(&cp);
|
||||
if (sshkey_read(found, &cp) != 0) {
|
||||
/* still no key? advance to next line*/
|
||||
debug2("%s: advance: '%s'", loc, cp);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
/* Parse key options now; we need to know if this is a CA key */
|
||||
if ((keyopts = sshauthopt_parse(key_options, &reason)) == NULL) {
|
||||
debug("%s: bad key options: %s", loc, reason);
|
||||
auth_debug_add("%s: bad key options: %s", loc, reason);
|
||||
goto out;
|
||||
}
|
||||
/* Ignore keys that don't match or incorrectly marked as CAs */
|
||||
if (sshkey_is_cert(key)) {
|
||||
/* Certificate; check signature key against CA */
|
||||
if (!sshkey_equal(found, key->cert->signature_key) ||
|
||||
!keyopts->cert_authority)
|
||||
goto out;
|
||||
} else {
|
||||
/* Plain key: check it against key found in file */
|
||||
if (!sshkey_equal(found, key) || keyopts->cert_authority)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* We have a candidate key, perform authorisation checks */
|
||||
if ((fp = sshkey_fingerprint(found,
|
||||
SSH_FP_HASH_DEFAULT, SSH_FP_DEFAULT)) == NULL)
|
||||
fatal_f("fingerprint failed");
|
||||
|
||||
debug("%s: matching %s found: %s %s", loc,
|
||||
sshkey_is_cert(key) ? "CA" : "key", sshkey_type(found), fp);
|
||||
|
||||
if (auth_authorise_keyopts(pw, keyopts,
|
||||
sshkey_is_cert(key), remote_ip, remote_host, loc) != 0) {
|
||||
reason = "Refused by key options";
|
||||
goto fail_reason;
|
||||
}
|
||||
/* That's all we need for plain keys. */
|
||||
if (!sshkey_is_cert(key)) {
|
||||
verbose("Accepted key %s %s found at %s",
|
||||
sshkey_type(found), fp, loc);
|
||||
finalopts = keyopts;
|
||||
keyopts = NULL;
|
||||
goto success;
|
||||
}
|
||||
|
||||
/*
|
||||
* Additional authorisation for certificates.
|
||||
*/
|
||||
|
||||
/* Parse and check options present in certificate */
|
||||
if ((certopts = sshauthopt_from_cert(key)) == NULL) {
|
||||
reason = "Invalid certificate options";
|
||||
goto fail_reason;
|
||||
}
|
||||
if (auth_authorise_keyopts(pw, certopts, 0,
|
||||
remote_ip, remote_host, loc) != 0) {
|
||||
reason = "Refused by certificate options";
|
||||
goto fail_reason;
|
||||
}
|
||||
if ((finalopts = sshauthopt_merge(keyopts, certopts, &reason)) == NULL)
|
||||
goto fail_reason;
|
||||
|
||||
/*
|
||||
* If the user has specified a list of principals as
|
||||
* a key option, then prefer that list to matching
|
||||
* their username in the certificate principals list.
|
||||
*/
|
||||
if (keyopts->cert_principals != NULL &&
|
||||
!match_principals_option(keyopts->cert_principals, key->cert)) {
|
||||
reason = "Certificate does not contain an authorized principal";
|
||||
goto 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;
|
||||
|
||||
verbose("Accepted certificate ID \"%s\" (serial %llu) "
|
||||
"signed by CA %s %s found at %s",
|
||||
key->cert->key_id,
|
||||
(unsigned long long)key->cert->serial,
|
||||
sshkey_type(found), fp, loc);
|
||||
|
||||
success:
|
||||
if (finalopts == NULL)
|
||||
fatal_f("internal error: missing options");
|
||||
if (authoptsp != NULL) {
|
||||
*authoptsp = finalopts;
|
||||
finalopts = NULL;
|
||||
}
|
||||
/* success */
|
||||
ret = 0;
|
||||
goto out;
|
||||
|
||||
fail_reason:
|
||||
error("%s", reason);
|
||||
auth_debug_add("%s", reason);
|
||||
out:
|
||||
free(fp);
|
||||
sshauthopt_free(keyopts);
|
||||
sshauthopt_free(certopts);
|
||||
sshauthopt_free(finalopts);
|
||||
sshkey_free(found);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks whether key is allowed in authorized_keys-format file,
|
||||
* returns 1 if the key is allowed or 0 otherwise.
|
||||
*/
|
||||
int
|
||||
auth_check_authkeys_file(struct passwd *pw, FILE *f, char *file,
|
||||
struct sshkey *key, const char *remote_ip,
|
||||
const char *remote_host, struct sshauthopt **authoptsp)
|
||||
{
|
||||
char *cp, *line = NULL, loc[256];
|
||||
size_t linesize = 0;
|
||||
int found_key = 0;
|
||||
u_long linenum = 0, nonblank = 0;
|
||||
|
||||
if (authoptsp != NULL)
|
||||
*authoptsp = NULL;
|
||||
|
||||
while (getline(&line, &linesize, f) != -1) {
|
||||
linenum++;
|
||||
/* Always consume entire file */
|
||||
if (found_key)
|
||||
continue;
|
||||
|
||||
/* Skip leading whitespace, empty and comment lines. */
|
||||
cp = line;
|
||||
skip_space(&cp);
|
||||
if (!*cp || *cp == '\n' || *cp == '#')
|
||||
continue;
|
||||
|
||||
nonblank++;
|
||||
snprintf(loc, sizeof(loc), "%.200s:%lu", file, linenum);
|
||||
if (auth_check_authkey_line(pw, key, cp,
|
||||
remote_ip, remote_host, loc, authoptsp) == 0)
|
||||
found_key = 1;
|
||||
}
|
||||
free(line);
|
||||
debug2_f("%s: processed %lu/%lu lines", file, nonblank, linenum);
|
||||
return found_key;
|
||||
}
|
||||
|
||||
static FILE *
|
||||
auth_openfile(const char *file, struct passwd *pw, int strict_modes,
|
||||
int log_missing, char *file_type)
|
||||
{
|
||||
char line[1024];
|
||||
struct stat st;
|
||||
int fd;
|
||||
FILE *f;
|
||||
|
||||
if ((fd = open(file, O_RDONLY|O_NONBLOCK)) == -1) {
|
||||
if (errno != ENOENT) {
|
||||
logit("Could not open user '%s' %s '%s': %s",
|
||||
pw->pw_name, file_type, file, strerror(errno));
|
||||
} else if (log_missing) {
|
||||
debug("Could not open user '%s' %s '%s': %s",
|
||||
pw->pw_name, file_type, file, strerror(errno));
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (fstat(fd, &st) == -1) {
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
if (!S_ISREG(st.st_mode)) {
|
||||
logit("User '%s' %s '%s' is not a regular file",
|
||||
pw->pw_name, file_type, file);
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
unset_nonblock(fd);
|
||||
if ((f = fdopen(fd, "r")) == NULL) {
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
if (strict_modes &&
|
||||
safe_path_fd(fileno(f), file, pw, line, sizeof(line)) != 0) {
|
||||
fclose(f);
|
||||
logit("Authentication refused: %s", line);
|
||||
auth_debug_add("Ignored %s: %s", file_type, line);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
|
||||
FILE *
|
||||
auth_openkeyfile(const char *file, struct passwd *pw, int strict_modes)
|
||||
{
|
||||
return auth_openfile(file, pw, strict_modes, 1, "authorized keys");
|
||||
}
|
||||
|
||||
FILE *
|
||||
auth_openprincipals(const char *file, struct passwd *pw, int strict_modes)
|
||||
{
|
||||
return auth_openfile(file, pw, strict_modes, 0,
|
||||
"authorized principals");
|
||||
}
|
||||
|
808
auth2.c
Normal file
808
auth2.c
Normal file
|
@ -0,0 +1,808 @@
|
|||
/* $OpenBSD: auth2.c,v 1.170 2025/01/17 00:09:41 dtucker Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/uio.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <pwd.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "stdlib.h"
|
||||
#include "atomicio.h"
|
||||
#include "xmalloc.h"
|
||||
#include "ssh2.h"
|
||||
#include "packet.h"
|
||||
#include "log.h"
|
||||
#include "sshbuf.h"
|
||||
#include "misc.h"
|
||||
#include "servconf.h"
|
||||
#include "sshkey.h"
|
||||
#include "hostfile.h"
|
||||
#include "auth.h"
|
||||
#include "dispatch.h"
|
||||
#include "pathnames.h"
|
||||
#include "ssherr.h"
|
||||
#ifdef GSSAPI
|
||||
#include "ssh-gss.h"
|
||||
#endif
|
||||
#include "monitor_wrap.h"
|
||||
#include "digest.h"
|
||||
#include "kex.h"
|
||||
|
||||
/* import */
|
||||
extern ServerOptions options;
|
||||
extern struct sshbuf *loginmsg;
|
||||
|
||||
/* methods */
|
||||
|
||||
extern Authmethod method_none;
|
||||
extern Authmethod method_pubkey;
|
||||
extern Authmethod method_passwd;
|
||||
extern Authmethod method_kbdint;
|
||||
extern Authmethod method_hostbased;
|
||||
#ifdef GSSAPI
|
||||
extern Authmethod method_gssapi;
|
||||
#endif
|
||||
|
||||
Authmethod *authmethods[] = {
|
||||
&method_none,
|
||||
&method_pubkey,
|
||||
#ifdef GSSAPI
|
||||
&method_gssapi,
|
||||
#endif
|
||||
&method_passwd,
|
||||
&method_kbdint,
|
||||
&method_hostbased,
|
||||
NULL
|
||||
};
|
||||
|
||||
/* protocol */
|
||||
|
||||
static int input_service_request(int, u_int32_t, struct ssh *);
|
||||
static int input_userauth_request(int, u_int32_t, struct ssh *);
|
||||
|
||||
/* helper */
|
||||
static Authmethod *authmethod_byname(const char *);
|
||||
static Authmethod *authmethod_lookup(Authctxt *, const char *);
|
||||
static char *authmethods_get(Authctxt *authctxt);
|
||||
|
||||
#define MATCH_NONE 0 /* method or submethod mismatch */
|
||||
#define MATCH_METHOD 1 /* method matches (no submethod specified) */
|
||||
#define MATCH_BOTH 2 /* method and submethod match */
|
||||
#define MATCH_PARTIAL 3 /* method matches, submethod can't be checked */
|
||||
static int list_starts_with(const char *, const char *, const char *);
|
||||
|
||||
char *
|
||||
auth2_read_banner(void)
|
||||
{
|
||||
struct stat st;
|
||||
char *banner = NULL;
|
||||
size_t len, n;
|
||||
int fd;
|
||||
|
||||
if ((fd = open(options.banner, O_RDONLY)) == -1)
|
||||
return (NULL);
|
||||
if (fstat(fd, &st) == -1) {
|
||||
close(fd);
|
||||
return (NULL);
|
||||
}
|
||||
if (st.st_size <= 0 || st.st_size > 1*1024*1024) {
|
||||
close(fd);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
len = (size_t)st.st_size; /* truncate */
|
||||
banner = xmalloc(len + 1);
|
||||
n = atomicio(read, fd, banner, len);
|
||||
close(fd);
|
||||
|
||||
if (n != len) {
|
||||
free(banner);
|
||||
return (NULL);
|
||||
}
|
||||
banner[n] = '\0';
|
||||
|
||||
return (banner);
|
||||
}
|
||||
|
||||
static void
|
||||
userauth_send_banner(struct ssh *ssh, const char *msg)
|
||||
{
|
||||
int r;
|
||||
|
||||
if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_BANNER)) != 0 ||
|
||||
(r = sshpkt_put_cstring(ssh, msg)) != 0 ||
|
||||
(r = sshpkt_put_cstring(ssh, "")) != 0 || /* language, unused */
|
||||
(r = sshpkt_send(ssh)) != 0)
|
||||
fatal_fr(r, "send packet");
|
||||
debug("%s: sent", __func__);
|
||||
}
|
||||
|
||||
static void
|
||||
userauth_banner(struct ssh *ssh)
|
||||
{
|
||||
char *banner = NULL;
|
||||
|
||||
if (options.banner == NULL)
|
||||
return;
|
||||
|
||||
if ((banner = mm_auth2_read_banner()) == NULL)
|
||||
goto done;
|
||||
userauth_send_banner(ssh, banner);
|
||||
|
||||
done:
|
||||
free(banner);
|
||||
}
|
||||
|
||||
/*
|
||||
* loop until authctxt->success == TRUE
|
||||
*/
|
||||
void
|
||||
do_authentication2(struct ssh *ssh)
|
||||
{
|
||||
Authctxt *authctxt = ssh->authctxt;
|
||||
|
||||
ssh_dispatch_init(ssh, &dispatch_protocol_error);
|
||||
if (ssh->kex->ext_info_c)
|
||||
ssh_dispatch_set(ssh, SSH2_MSG_EXT_INFO, &kex_input_ext_info);
|
||||
ssh_dispatch_set(ssh, SSH2_MSG_SERVICE_REQUEST, &input_service_request);
|
||||
ssh_dispatch_run_fatal(ssh, DISPATCH_BLOCK, &authctxt->success);
|
||||
ssh->authctxt = NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
input_service_request(int type, u_int32_t seq, struct ssh *ssh)
|
||||
{
|
||||
Authctxt *authctxt = ssh->authctxt;
|
||||
char *service = NULL;
|
||||
int r, acceptit = 0;
|
||||
|
||||
if ((r = sshpkt_get_cstring(ssh, &service, NULL)) != 0 ||
|
||||
(r = sshpkt_get_end(ssh)) != 0)
|
||||
goto out;
|
||||
|
||||
if (authctxt == NULL)
|
||||
fatal("input_service_request: no authctxt");
|
||||
|
||||
if (strcmp(service, "ssh-userauth") == 0) {
|
||||
if (!authctxt->success) {
|
||||
acceptit = 1;
|
||||
/* now we can handle user-auth requests */
|
||||
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_REQUEST,
|
||||
&input_userauth_request);
|
||||
}
|
||||
}
|
||||
/* XXX all other service requests are denied */
|
||||
|
||||
if (acceptit) {
|
||||
if ((r = sshpkt_start(ssh, SSH2_MSG_SERVICE_ACCEPT)) != 0 ||
|
||||
(r = sshpkt_put_cstring(ssh, service)) != 0 ||
|
||||
(r = sshpkt_send(ssh)) != 0 ||
|
||||
(r = ssh_packet_write_wait(ssh)) != 0)
|
||||
goto out;
|
||||
} else {
|
||||
debug("bad service request %s", service);
|
||||
ssh_packet_disconnect(ssh, "bad service request %s", service);
|
||||
}
|
||||
ssh_dispatch_set(ssh, SSH2_MSG_EXT_INFO, &dispatch_protocol_error);
|
||||
r = 0;
|
||||
out:
|
||||
free(service);
|
||||
return r;
|
||||
}
|
||||
|
||||
#define MIN_FAIL_DELAY_SECONDS 0.005
|
||||
#define MAX_FAIL_DELAY_SECONDS 5.0
|
||||
static double
|
||||
user_specific_delay(const char *user)
|
||||
{
|
||||
char b[512];
|
||||
size_t len = ssh_digest_bytes(SSH_DIGEST_SHA512);
|
||||
u_char *hash = xmalloc(len);
|
||||
double delay;
|
||||
|
||||
(void)snprintf(b, sizeof b, "%llu%s",
|
||||
(unsigned long long)options.timing_secret, user);
|
||||
if (ssh_digest_memory(SSH_DIGEST_SHA512, b, strlen(b), hash, len) != 0)
|
||||
fatal_f("ssh_digest_memory");
|
||||
/* 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);
|
||||
return MIN_FAIL_DELAY_SECONDS + delay;
|
||||
}
|
||||
|
||||
static void
|
||||
ensure_minimum_time_since(double start, double seconds)
|
||||
{
|
||||
struct timespec ts;
|
||||
double elapsed = monotime_double() - start, req = seconds, remain;
|
||||
|
||||
if (elapsed > MAX_FAIL_DELAY_SECONDS) {
|
||||
debug3_f("elapsed %0.3lfms exceeded the max delay "
|
||||
"requested %0.3lfms)", elapsed*1000, req*1000);
|
||||
return;
|
||||
}
|
||||
|
||||
/* if we've already passed the requested time, scale up */
|
||||
while ((remain = seconds - elapsed) < 0.0)
|
||||
seconds *= 2;
|
||||
|
||||
ts.tv_sec = remain;
|
||||
ts.tv_nsec = (remain - ts.tv_sec) * 1000000000;
|
||||
debug3_f("elapsed %0.3lfms, delaying %0.3lfms (requested %0.3lfms)",
|
||||
elapsed*1000, remain*1000, req*1000);
|
||||
nanosleep(&ts, NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
input_userauth_request(int type, u_int32_t seq, struct ssh *ssh)
|
||||
{
|
||||
Authctxt *authctxt = ssh->authctxt;
|
||||
Authmethod *m = NULL;
|
||||
char *user = NULL, *service = NULL, *method = NULL, *style = NULL;
|
||||
int r, authenticated = 0;
|
||||
double tstart = monotime_double();
|
||||
|
||||
if (authctxt == NULL)
|
||||
fatal("input_userauth_request: no authctxt");
|
||||
|
||||
if ((r = sshpkt_get_cstring(ssh, &user, NULL)) != 0 ||
|
||||
(r = sshpkt_get_cstring(ssh, &service, NULL)) != 0 ||
|
||||
(r = sshpkt_get_cstring(ssh, &method, NULL)) != 0)
|
||||
goto out;
|
||||
debug("userauth-request for user %s service %s method %s", user, service, method);
|
||||
debug("attempt %d failures %d", authctxt->attempt, authctxt->failures);
|
||||
|
||||
if ((style = strchr(user, ':')) != NULL)
|
||||
*style++ = 0;
|
||||
|
||||
if (authctxt->attempt >= 1024)
|
||||
auth_maxtries_exceeded(ssh);
|
||||
if (authctxt->attempt++ == 0) {
|
||||
/* setup auth context */
|
||||
authctxt->pw = mm_getpwnamallow(ssh, user);
|
||||
authctxt->user = xstrdup(user);
|
||||
if (authctxt->pw && strcmp(service, "ssh-connection")==0) {
|
||||
authctxt->valid = 1;
|
||||
debug2_f("setting up authctxt for %s", user);
|
||||
} else {
|
||||
authctxt->valid = 0;
|
||||
/* Invalid user, fake password information */
|
||||
authctxt->pw = fakepw();
|
||||
#ifdef SSH_AUDIT_EVENTS
|
||||
mm_audit_event(ssh, SSH_INVALID_USER);
|
||||
#endif
|
||||
}
|
||||
#ifdef USE_PAM
|
||||
if (options.use_pam)
|
||||
mm_start_pam(ssh);
|
||||
#endif
|
||||
ssh_packet_set_log_preamble(ssh, "%suser %s",
|
||||
authctxt->valid ? "authenticating " : "invalid ", user);
|
||||
setproctitle("%s [net]", authctxt->valid ? user : "unknown");
|
||||
authctxt->service = xstrdup(service);
|
||||
authctxt->style = style ? xstrdup(style) : NULL;
|
||||
mm_inform_authserv(service, style);
|
||||
userauth_banner(ssh);
|
||||
if ((r = kex_server_update_ext_info(ssh)) != 0)
|
||||
fatal_fr(r, "kex_server_update_ext_info failed");
|
||||
if (auth2_setup_methods_lists(authctxt) != 0)
|
||||
ssh_packet_disconnect(ssh,
|
||||
"no authentication methods enabled");
|
||||
} else if (strcmp(user, authctxt->user) != 0 ||
|
||||
strcmp(service, authctxt->service) != 0) {
|
||||
ssh_packet_disconnect(ssh, "Change of username or service "
|
||||
"not allowed: (%s,%s) -> (%s,%s)",
|
||||
authctxt->user, authctxt->service, user, service);
|
||||
}
|
||||
/* reset state */
|
||||
auth2_challenge_stop(ssh);
|
||||
|
||||
#ifdef GSSAPI
|
||||
/* XXX move to auth2_gssapi_stop() */
|
||||
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
|
||||
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL);
|
||||
#endif
|
||||
|
||||
auth2_authctxt_reset_info(authctxt);
|
||||
authctxt->postponed = 0;
|
||||
authctxt->server_caused_failure = 0;
|
||||
|
||||
/* try to authenticate user */
|
||||
m = authmethod_lookup(authctxt, method);
|
||||
if (m != NULL && authctxt->failures < options.max_authtries) {
|
||||
debug2("input_userauth_request: try method %s", method);
|
||||
authenticated = m->userauth(ssh, method);
|
||||
}
|
||||
if (!authctxt->authenticated && strcmp(method, "none") != 0)
|
||||
ensure_minimum_time_since(tstart,
|
||||
user_specific_delay(authctxt->user));
|
||||
userauth_finish(ssh, authenticated, method, NULL);
|
||||
r = 0;
|
||||
out:
|
||||
free(service);
|
||||
free(user);
|
||||
free(method);
|
||||
return r;
|
||||
}
|
||||
|
||||
void
|
||||
userauth_finish(struct ssh *ssh, int authenticated, const char *packet_method,
|
||||
const char *submethod)
|
||||
{
|
||||
Authctxt *authctxt = ssh->authctxt;
|
||||
Authmethod *m = NULL;
|
||||
const char *method = packet_method;
|
||||
char *methods;
|
||||
int r, partial = 0;
|
||||
|
||||
if (authenticated) {
|
||||
if (!authctxt->valid) {
|
||||
fatal("INTERNAL ERROR: authenticated invalid user %s",
|
||||
authctxt->user);
|
||||
}
|
||||
if (authctxt->postponed)
|
||||
fatal("INTERNAL ERROR: authenticated and postponed");
|
||||
/* prefer primary authmethod name to possible synonym */
|
||||
if ((m = authmethod_byname(method)) == NULL)
|
||||
fatal("INTERNAL ERROR: bad method %s", method);
|
||||
method = m->cfg->name;
|
||||
}
|
||||
|
||||
/* Special handling for root */
|
||||
if (authenticated && authctxt->pw->pw_uid == 0 &&
|
||||
!auth_root_allowed(ssh, method)) {
|
||||
authenticated = 0;
|
||||
#ifdef SSH_AUDIT_EVENTS
|
||||
mm_audit_event(ssh, SSH_LOGIN_ROOT_DENIED);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (authenticated && options.num_auth_methods != 0) {
|
||||
if (!auth2_update_methods_lists(authctxt, method, submethod)) {
|
||||
authenticated = 0;
|
||||
partial = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Log before sending the reply */
|
||||
auth_log(ssh, authenticated, partial, method, submethod);
|
||||
|
||||
/* Update information exposed to session */
|
||||
if (authenticated || partial)
|
||||
auth2_update_session_info(authctxt, method, submethod);
|
||||
|
||||
if (authctxt->postponed)
|
||||
return;
|
||||
|
||||
#ifdef USE_PAM
|
||||
if (options.use_pam && authenticated) {
|
||||
int r, success = mm_do_pam_account();
|
||||
|
||||
/* If PAM returned a message, send it to the user. */
|
||||
if (sshbuf_len(loginmsg) > 0) {
|
||||
if ((r = sshbuf_put(loginmsg, "\0", 1)) != 0)
|
||||
fatal("%s: buffer error: %s",
|
||||
__func__, ssh_err(r));
|
||||
userauth_send_banner(ssh, sshbuf_ptr(loginmsg));
|
||||
if ((r = ssh_packet_write_wait(ssh)) != 0) {
|
||||
sshpkt_fatal(ssh, r,
|
||||
"%s: send PAM banner", __func__);
|
||||
}
|
||||
}
|
||||
if (!success) {
|
||||
fatal("Access denied for user %s by PAM account "
|
||||
"configuration", authctxt->user);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (authenticated == 1) {
|
||||
/* turn off userauth */
|
||||
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_REQUEST,
|
||||
&dispatch_protocol_ignore);
|
||||
if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_SUCCESS)) != 0 ||
|
||||
(r = sshpkt_send(ssh)) != 0 ||
|
||||
(r = ssh_packet_write_wait(ssh)) != 0)
|
||||
fatal_fr(r, "send success packet");
|
||||
/* now we can break out */
|
||||
authctxt->success = 1;
|
||||
ssh_packet_set_log_preamble(ssh, "user %s", authctxt->user);
|
||||
} else {
|
||||
/* Allow initial try of "none" auth without failure penalty */
|
||||
if (!partial && !authctxt->server_caused_failure &&
|
||||
(authctxt->attempt > 1 || strcmp(method, "none") != 0))
|
||||
authctxt->failures++;
|
||||
if (authctxt->failures >= options.max_authtries) {
|
||||
#ifdef SSH_AUDIT_EVENTS
|
||||
mm_audit_event(ssh, SSH_LOGIN_EXCEED_MAXTRIES);
|
||||
#endif
|
||||
auth_maxtries_exceeded(ssh);
|
||||
}
|
||||
methods = authmethods_get(authctxt);
|
||||
debug3_f("failure partial=%d next methods=\"%s\"",
|
||||
partial, methods);
|
||||
if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_FAILURE)) != 0 ||
|
||||
(r = sshpkt_put_cstring(ssh, methods)) != 0 ||
|
||||
(r = sshpkt_put_u8(ssh, partial)) != 0 ||
|
||||
(r = sshpkt_send(ssh)) != 0 ||
|
||||
(r = ssh_packet_write_wait(ssh)) != 0)
|
||||
fatal_fr(r, "send failure packet");
|
||||
free(methods);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks whether method is allowed by at least one AuthenticationMethods
|
||||
* methods list. Returns 1 if allowed, or no methods lists configured.
|
||||
* 0 otherwise.
|
||||
*/
|
||||
int
|
||||
auth2_method_allowed(Authctxt *authctxt, const char *method,
|
||||
const char *submethod)
|
||||
{
|
||||
u_int i;
|
||||
|
||||
/*
|
||||
* NB. authctxt->num_auth_methods might be zero as a result of
|
||||
* auth2_setup_methods_lists(), so check the configuration.
|
||||
*/
|
||||
if (options.num_auth_methods == 0)
|
||||
return 1;
|
||||
for (i = 0; i < authctxt->num_auth_methods; i++) {
|
||||
if (list_starts_with(authctxt->auth_methods[i], method,
|
||||
submethod) != MATCH_NONE)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *
|
||||
authmethods_get(Authctxt *authctxt)
|
||||
{
|
||||
struct sshbuf *b;
|
||||
char *list;
|
||||
int i, r;
|
||||
|
||||
if ((b = sshbuf_new()) == NULL)
|
||||
fatal_f("sshbuf_new failed");
|
||||
for (i = 0; authmethods[i] != NULL; i++) {
|
||||
if (strcmp(authmethods[i]->cfg->name, "none") == 0)
|
||||
continue;
|
||||
if (authmethods[i]->cfg->enabled == NULL ||
|
||||
*(authmethods[i]->cfg->enabled) == 0)
|
||||
continue;
|
||||
if (!auth2_method_allowed(authctxt, authmethods[i]->cfg->name,
|
||||
NULL))
|
||||
continue;
|
||||
if ((r = sshbuf_putf(b, "%s%s", sshbuf_len(b) ? "," : "",
|
||||
authmethods[i]->cfg->name)) != 0)
|
||||
fatal_fr(r, "buffer error");
|
||||
}
|
||||
if ((list = sshbuf_dup_string(b)) == NULL)
|
||||
fatal_f("sshbuf_dup_string failed");
|
||||
sshbuf_free(b);
|
||||
return list;
|
||||
}
|
||||
|
||||
static Authmethod *
|
||||
authmethod_byname(const char *name)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (name == NULL)
|
||||
fatal_f("NULL authentication method name");
|
||||
for (i = 0; authmethods[i] != NULL; i++) {
|
||||
if (strcmp(name, authmethods[i]->cfg->name) == 0 ||
|
||||
(authmethods[i]->cfg->synonym != NULL &&
|
||||
strcmp(name, authmethods[i]->cfg->synonym) == 0))
|
||||
return authmethods[i];
|
||||
}
|
||||
debug_f("unrecognized authentication method name: %s", name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static Authmethod *
|
||||
authmethod_lookup(Authctxt *authctxt, const char *name)
|
||||
{
|
||||
Authmethod *method;
|
||||
|
||||
if ((method = authmethod_byname(name)) == NULL)
|
||||
return NULL;
|
||||
|
||||
if (method->cfg->enabled == NULL || *(method->cfg->enabled) == 0) {
|
||||
debug3_f("method %s not enabled", name);
|
||||
return NULL;
|
||||
}
|
||||
if (!auth2_method_allowed(authctxt, method->cfg->name, NULL)) {
|
||||
debug3_f("method %s not allowed "
|
||||
"by AuthenticationMethods", name);
|
||||
return NULL;
|
||||
}
|
||||
return method;
|
||||
}
|
||||
|
||||
/*
|
||||
* Prune the AuthenticationMethods supplied in the configuration, removing
|
||||
* any methods lists that include disabled methods. Note that this might
|
||||
* leave authctxt->num_auth_methods == 0, even when multiple required auth
|
||||
* has been requested. For this reason, all tests for whether multiple is
|
||||
* enabled should consult options.num_auth_methods directly.
|
||||
*/
|
||||
int
|
||||
auth2_setup_methods_lists(Authctxt *authctxt)
|
||||
{
|
||||
u_int i;
|
||||
|
||||
/* First, normalise away the "any" pseudo-method */
|
||||
if (options.num_auth_methods == 1 &&
|
||||
strcmp(options.auth_methods[0], "any") == 0) {
|
||||
free(options.auth_methods[0]);
|
||||
options.auth_methods[0] = NULL;
|
||||
options.num_auth_methods = 0;
|
||||
}
|
||||
|
||||
if (options.num_auth_methods == 0)
|
||||
return 0;
|
||||
debug3_f("checking methods");
|
||||
authctxt->auth_methods = xcalloc(options.num_auth_methods,
|
||||
sizeof(*authctxt->auth_methods));
|
||||
authctxt->num_auth_methods = 0;
|
||||
for (i = 0; i < options.num_auth_methods; i++) {
|
||||
if (auth2_methods_valid(options.auth_methods[i], 1) != 0) {
|
||||
logit("Authentication methods list \"%s\" contains "
|
||||
"disabled method, skipping",
|
||||
options.auth_methods[i]);
|
||||
continue;
|
||||
}
|
||||
debug("authentication methods list %d: %s",
|
||||
authctxt->num_auth_methods, options.auth_methods[i]);
|
||||
authctxt->auth_methods[authctxt->num_auth_methods++] =
|
||||
xstrdup(options.auth_methods[i]);
|
||||
}
|
||||
if (authctxt->num_auth_methods == 0) {
|
||||
error("No AuthenticationMethods left after eliminating "
|
||||
"disabled methods");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
list_starts_with(const char *methods, const char *method,
|
||||
const char *submethod)
|
||||
{
|
||||
size_t l = strlen(method);
|
||||
int match;
|
||||
const char *p;
|
||||
|
||||
if (strncmp(methods, method, l) != 0)
|
||||
return MATCH_NONE;
|
||||
p = methods + l;
|
||||
match = MATCH_METHOD;
|
||||
if (*p == ':') {
|
||||
if (!submethod)
|
||||
return MATCH_PARTIAL;
|
||||
l = strlen(submethod);
|
||||
p += 1;
|
||||
if (strncmp(submethod, p, l))
|
||||
return MATCH_NONE;
|
||||
p += l;
|
||||
match = MATCH_BOTH;
|
||||
}
|
||||
if (*p != ',' && *p != '\0')
|
||||
return MATCH_NONE;
|
||||
return match;
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove method from the start of a comma-separated list of methods.
|
||||
* Returns 0 if the list of methods did not start with that method or 1
|
||||
* if it did.
|
||||
*/
|
||||
static int
|
||||
remove_method(char **methods, const char *method, const char *submethod)
|
||||
{
|
||||
char *omethods = *methods, *p;
|
||||
size_t l = strlen(method);
|
||||
int match;
|
||||
|
||||
match = list_starts_with(omethods, method, submethod);
|
||||
if (match != MATCH_METHOD && match != MATCH_BOTH)
|
||||
return 0;
|
||||
p = omethods + l;
|
||||
if (submethod && match == MATCH_BOTH)
|
||||
p += 1 + strlen(submethod); /* include colon */
|
||||
if (*p == ',')
|
||||
p++;
|
||||
*methods = xstrdup(p);
|
||||
free(omethods);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Called after successful authentication. Will remove the successful method
|
||||
* from the start of each list in which it occurs. If it was the last method
|
||||
* in any list, then authentication is deemed successful.
|
||||
* Returns 1 if the method completed any authentication list or 0 otherwise.
|
||||
*/
|
||||
int
|
||||
auth2_update_methods_lists(Authctxt *authctxt, const char *method,
|
||||
const char *submethod)
|
||||
{
|
||||
u_int i, found = 0;
|
||||
|
||||
debug3_f("updating methods list after \"%s\"", method);
|
||||
for (i = 0; i < authctxt->num_auth_methods; i++) {
|
||||
if (!remove_method(&(authctxt->auth_methods[i]), method,
|
||||
submethod))
|
||||
continue;
|
||||
found = 1;
|
||||
if (*authctxt->auth_methods[i] == '\0') {
|
||||
debug2("authentication methods list %d complete", i);
|
||||
return 1;
|
||||
}
|
||||
debug3("authentication methods list %d remaining: \"%s\"",
|
||||
i, authctxt->auth_methods[i]);
|
||||
}
|
||||
/* This should not happen, but would be bad if it did */
|
||||
if (!found)
|
||||
fatal_f("method not in AuthenticationMethods");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Reset method-specific information */
|
||||
void auth2_authctxt_reset_info(Authctxt *authctxt)
|
||||
{
|
||||
sshkey_free(authctxt->auth_method_key);
|
||||
free(authctxt->auth_method_info);
|
||||
authctxt->auth_method_key = NULL;
|
||||
authctxt->auth_method_info = NULL;
|
||||
}
|
||||
|
||||
/* Record auth method-specific information for logs */
|
||||
void
|
||||
auth2_record_info(Authctxt *authctxt, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int i;
|
||||
|
||||
free(authctxt->auth_method_info);
|
||||
authctxt->auth_method_info = NULL;
|
||||
|
||||
va_start(ap, fmt);
|
||||
i = vasprintf(&authctxt->auth_method_info, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (i == -1)
|
||||
fatal_f("vasprintf failed");
|
||||
}
|
||||
|
||||
/*
|
||||
* Records a public key used in authentication. This is used for logging
|
||||
* and to ensure that the same key is not subsequently accepted again for
|
||||
* multiple authentication.
|
||||
*/
|
||||
void
|
||||
auth2_record_key(Authctxt *authctxt, int authenticated,
|
||||
const struct sshkey *key)
|
||||
{
|
||||
struct sshkey **tmp, *dup;
|
||||
int r;
|
||||
|
||||
if ((r = sshkey_from_private(key, &dup)) != 0)
|
||||
fatal_fr(r, "copy key");
|
||||
sshkey_free(authctxt->auth_method_key);
|
||||
authctxt->auth_method_key = dup;
|
||||
|
||||
if (!authenticated)
|
||||
return;
|
||||
|
||||
/* If authenticated, make sure we don't accept this key again */
|
||||
if ((r = sshkey_from_private(key, &dup)) != 0)
|
||||
fatal_fr(r, "copy key");
|
||||
if (authctxt->nprev_keys >= INT_MAX ||
|
||||
(tmp = recallocarray(authctxt->prev_keys, authctxt->nprev_keys,
|
||||
authctxt->nprev_keys + 1, sizeof(*authctxt->prev_keys))) == NULL)
|
||||
fatal_f("reallocarray failed");
|
||||
authctxt->prev_keys = tmp;
|
||||
authctxt->prev_keys[authctxt->nprev_keys] = dup;
|
||||
authctxt->nprev_keys++;
|
||||
|
||||
}
|
||||
|
||||
/* Checks whether a key has already been previously used for authentication */
|
||||
int
|
||||
auth2_key_already_used(Authctxt *authctxt, const struct sshkey *key)
|
||||
{
|
||||
u_int i;
|
||||
char *fp;
|
||||
|
||||
for (i = 0; i < authctxt->nprev_keys; i++) {
|
||||
if (sshkey_equal_public(key, authctxt->prev_keys[i])) {
|
||||
fp = sshkey_fingerprint(authctxt->prev_keys[i],
|
||||
options.fingerprint_hash, SSH_FP_DEFAULT);
|
||||
debug3_f("key already used: %s %s",
|
||||
sshkey_type(authctxt->prev_keys[i]),
|
||||
fp == NULL ? "UNKNOWN" : fp);
|
||||
free(fp);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Updates authctxt->session_info with details of authentication. Should be
|
||||
* whenever an authentication method succeeds.
|
||||
*/
|
||||
void
|
||||
auth2_update_session_info(Authctxt *authctxt, const char *method,
|
||||
const char *submethod)
|
||||
{
|
||||
int r;
|
||||
|
||||
if (authctxt->session_info == NULL) {
|
||||
if ((authctxt->session_info = sshbuf_new()) == NULL)
|
||||
fatal_f("sshbuf_new");
|
||||
}
|
||||
|
||||
/* Append method[/submethod] */
|
||||
if ((r = sshbuf_putf(authctxt->session_info, "%s%s%s",
|
||||
method, submethod == NULL ? "" : "/",
|
||||
submethod == NULL ? "" : submethod)) != 0)
|
||||
fatal_fr(r, "append method");
|
||||
|
||||
/* Append key if present */
|
||||
if (authctxt->auth_method_key != NULL) {
|
||||
if ((r = sshbuf_put_u8(authctxt->session_info, ' ')) != 0 ||
|
||||
(r = sshkey_format_text(authctxt->auth_method_key,
|
||||
authctxt->session_info)) != 0)
|
||||
fatal_fr(r, "append key");
|
||||
}
|
||||
|
||||
if (authctxt->auth_method_info != NULL) {
|
||||
/* Ensure no ambiguity here */
|
||||
if (strchr(authctxt->auth_method_info, '\n') != NULL)
|
||||
fatal_f("auth_method_info contains \\n");
|
||||
if ((r = sshbuf_put_u8(authctxt->session_info, ' ')) != 0 ||
|
||||
(r = sshbuf_putf(authctxt->session_info, "%s",
|
||||
authctxt->auth_method_info)) != 0) {
|
||||
fatal_fr(r, "append method info");
|
||||
}
|
||||
}
|
||||
if ((r = sshbuf_put_u8(authctxt->session_info, '\n')) != 0)
|
||||
fatal_fr(r, "append");
|
||||
}
|
||||
|
778
authfd.c
Normal file
778
authfd.c
Normal file
|
@ -0,0 +1,778 @@
|
|||
/* $OpenBSD: authfd.c,v 1.134 2023/12/18 14:46:56 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
* All rights reserved
|
||||
* Functions for connecting the local authentication agent.
|
||||
*
|
||||
* As far as I am concerned, the code I have written for this software
|
||||
* can be used freely for any purpose. Any derived versions of this
|
||||
* software must be clearly marked as such, and if the derived work is
|
||||
* incompatible with the protocol description in the RFC file, it must be
|
||||
* called by a name other than "ssh" or "Secure Shell".
|
||||
*
|
||||
* SSH2 implementation,
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/un.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "ssh.h"
|
||||
#include "sshbuf.h"
|
||||
#include "sshkey.h"
|
||||
#include "authfd.h"
|
||||
#include "cipher.h"
|
||||
#include "log.h"
|
||||
#include "atomicio.h"
|
||||
#include "misc.h"
|
||||
#include "ssherr.h"
|
||||
|
||||
#define MAX_AGENT_IDENTITIES 2048 /* Max keys in agent reply */
|
||||
#define MAX_AGENT_REPLY_LEN (256 * 1024) /* Max bytes in agent reply */
|
||||
|
||||
/* macro to check for "agent failure" message */
|
||||
#define agent_failed(x) \
|
||||
((x == SSH_AGENT_FAILURE) || \
|
||||
(x == SSH_COM_AGENT2_FAILURE) || \
|
||||
(x == SSH2_AGENT_FAILURE))
|
||||
|
||||
/* Convert success/failure response from agent to a err.h status */
|
||||
static int
|
||||
decode_reply(u_char type)
|
||||
{
|
||||
if (agent_failed(type))
|
||||
return SSH_ERR_AGENT_FAILURE;
|
||||
else if (type == SSH_AGENT_SUCCESS)
|
||||
return 0;
|
||||
else
|
||||
return SSH_ERR_INVALID_FORMAT;
|
||||
}
|
||||
|
||||
/*
|
||||
* Opens an authentication socket at the provided path and stores the file
|
||||
* descriptor in fdp. Returns 0 on success and an error on failure.
|
||||
*/
|
||||
int
|
||||
ssh_get_authentication_socket_path(const char *authsocket, int *fdp)
|
||||
{
|
||||
int sock, oerrno;
|
||||
struct sockaddr_un sunaddr;
|
||||
|
||||
debug3_f("path '%s'", authsocket);
|
||||
memset(&sunaddr, 0, sizeof(sunaddr));
|
||||
sunaddr.sun_family = AF_UNIX;
|
||||
strlcpy(sunaddr.sun_path, authsocket, sizeof(sunaddr.sun_path));
|
||||
|
||||
if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
|
||||
return SSH_ERR_SYSTEM_ERROR;
|
||||
|
||||
/* close on exec */
|
||||
if (fcntl(sock, F_SETFD, FD_CLOEXEC) == -1 ||
|
||||
connect(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) == -1) {
|
||||
oerrno = errno;
|
||||
close(sock);
|
||||
errno = oerrno;
|
||||
return SSH_ERR_SYSTEM_ERROR;
|
||||
}
|
||||
if (fdp != NULL)
|
||||
*fdp = sock;
|
||||
else
|
||||
close(sock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Opens the default authentication socket and stores the file descriptor in
|
||||
* fdp. Returns 0 on success and an error on failure.
|
||||
*/
|
||||
int
|
||||
ssh_get_authentication_socket(int *fdp)
|
||||
{
|
||||
const char *authsocket;
|
||||
|
||||
if (fdp != NULL)
|
||||
*fdp = -1;
|
||||
|
||||
authsocket = getenv(SSH_AUTHSOCKET_ENV_NAME);
|
||||
if (authsocket == NULL || *authsocket == '\0')
|
||||
return SSH_ERR_AGENT_NOT_PRESENT;
|
||||
|
||||
return ssh_get_authentication_socket_path(authsocket, fdp);
|
||||
}
|
||||
|
||||
/* Communicate with agent: send request and read reply */
|
||||
static int
|
||||
ssh_request_reply(int sock, struct sshbuf *request, struct sshbuf *reply)
|
||||
{
|
||||
int r;
|
||||
size_t l, len;
|
||||
char buf[1024];
|
||||
|
||||
/* Get the length of the message, and format it in the buffer. */
|
||||
len = sshbuf_len(request);
|
||||
POKE_U32(buf, len);
|
||||
|
||||
/* Send the length and then the packet to the agent. */
|
||||
if (atomicio(vwrite, sock, buf, 4) != 4 ||
|
||||
atomicio(vwrite, sock, sshbuf_mutable_ptr(request),
|
||||
sshbuf_len(request)) != sshbuf_len(request))
|
||||
return SSH_ERR_AGENT_COMMUNICATION;
|
||||
/*
|
||||
* Wait for response from the agent. First read the length of the
|
||||
* response packet.
|
||||
*/
|
||||
if (atomicio(read, sock, buf, 4) != 4)
|
||||
return SSH_ERR_AGENT_COMMUNICATION;
|
||||
|
||||
/* Extract the length, and check it for sanity. */
|
||||
len = PEEK_U32(buf);
|
||||
if (len > MAX_AGENT_REPLY_LEN)
|
||||
return SSH_ERR_INVALID_FORMAT;
|
||||
|
||||
/* Read the rest of the response in to the buffer. */
|
||||
sshbuf_reset(reply);
|
||||
while (len > 0) {
|
||||
l = len;
|
||||
if (l > sizeof(buf))
|
||||
l = sizeof(buf);
|
||||
if (atomicio(read, sock, buf, l) != l)
|
||||
return SSH_ERR_AGENT_COMMUNICATION;
|
||||
if ((r = sshbuf_put(reply, buf, l)) != 0)
|
||||
return r;
|
||||
len -= l;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Communicate with agent: sent request, read and decode status reply */
|
||||
static int
|
||||
ssh_request_reply_decode(int sock, struct sshbuf *request)
|
||||
{
|
||||
struct sshbuf *reply;
|
||||
int r;
|
||||
u_char type;
|
||||
|
||||
if ((reply = sshbuf_new()) == NULL)
|
||||
return SSH_ERR_ALLOC_FAIL;
|
||||
if ((r = ssh_request_reply(sock, request, reply)) != 0 ||
|
||||
(r = sshbuf_get_u8(reply, &type)) != 0 ||
|
||||
(r = decode_reply(type)) != 0)
|
||||
goto out;
|
||||
/* success */
|
||||
r = 0;
|
||||
out:
|
||||
sshbuf_free(reply);
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* Closes the agent socket if it should be closed (depends on how it was
|
||||
* obtained). The argument must have been returned by
|
||||
* ssh_get_authentication_socket().
|
||||
*/
|
||||
void
|
||||
ssh_close_authentication_socket(int sock)
|
||||
{
|
||||
if (getenv(SSH_AUTHSOCKET_ENV_NAME))
|
||||
close(sock);
|
||||
}
|
||||
|
||||
/* Lock/unlock agent */
|
||||
int
|
||||
ssh_lock_agent(int sock, int lock, const char *password)
|
||||
{
|
||||
int r;
|
||||
u_char type = lock ? SSH_AGENTC_LOCK : SSH_AGENTC_UNLOCK;
|
||||
struct sshbuf *msg;
|
||||
|
||||
if ((msg = sshbuf_new()) == NULL)
|
||||
return SSH_ERR_ALLOC_FAIL;
|
||||
if ((r = sshbuf_put_u8(msg, type)) != 0 ||
|
||||
(r = sshbuf_put_cstring(msg, password)) != 0 ||
|
||||
(r = ssh_request_reply_decode(sock, msg)) != 0)
|
||||
goto out;
|
||||
/* success */
|
||||
r = 0;
|
||||
out:
|
||||
sshbuf_free(msg);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
deserialise_identity2(struct sshbuf *ids, struct sshkey **keyp, char **commentp)
|
||||
{
|
||||
int r;
|
||||
char *comment = NULL;
|
||||
const u_char *blob;
|
||||
size_t blen;
|
||||
|
||||
if ((r = sshbuf_get_string_direct(ids, &blob, &blen)) != 0 ||
|
||||
(r = sshbuf_get_cstring(ids, &comment, NULL)) != 0)
|
||||
goto out;
|
||||
if ((r = sshkey_from_blob(blob, blen, keyp)) != 0)
|
||||
goto out;
|
||||
if (commentp != NULL) {
|
||||
*commentp = comment;
|
||||
comment = NULL;
|
||||
}
|
||||
r = 0;
|
||||
out:
|
||||
free(comment);
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fetch list of identities held by the agent.
|
||||
*/
|
||||
int
|
||||
ssh_fetch_identitylist(int sock, struct ssh_identitylist **idlp)
|
||||
{
|
||||
u_char type;
|
||||
u_int32_t num, i;
|
||||
struct sshbuf *msg;
|
||||
struct ssh_identitylist *idl = NULL;
|
||||
int r;
|
||||
|
||||
/*
|
||||
* Send a message to the agent requesting for a list of the
|
||||
* identities it can represent.
|
||||
*/
|
||||
if ((msg = sshbuf_new()) == NULL)
|
||||
return SSH_ERR_ALLOC_FAIL;
|
||||
if ((r = sshbuf_put_u8(msg, SSH2_AGENTC_REQUEST_IDENTITIES)) != 0)
|
||||
goto out;
|
||||
|
||||
if ((r = ssh_request_reply(sock, msg, msg)) != 0)
|
||||
goto out;
|
||||
|
||||
/* Get message type, and verify that we got a proper answer. */
|
||||
if ((r = sshbuf_get_u8(msg, &type)) != 0)
|
||||
goto out;
|
||||
if (agent_failed(type)) {
|
||||
r = SSH_ERR_AGENT_FAILURE;
|
||||
goto out;
|
||||
} else if (type != SSH2_AGENT_IDENTITIES_ANSWER) {
|
||||
r = SSH_ERR_INVALID_FORMAT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Get the number of entries in the response and check it for sanity. */
|
||||
if ((r = sshbuf_get_u32(msg, &num)) != 0)
|
||||
goto out;
|
||||
if (num > MAX_AGENT_IDENTITIES) {
|
||||
r = SSH_ERR_INVALID_FORMAT;
|
||||
goto out;
|
||||
}
|
||||
if (num == 0) {
|
||||
r = SSH_ERR_AGENT_NO_IDENTITIES;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Deserialise the response into a list of keys/comments */
|
||||
if ((idl = calloc(1, sizeof(*idl))) == NULL ||
|
||||
(idl->keys = calloc(num, sizeof(*idl->keys))) == NULL ||
|
||||
(idl->comments = calloc(num, sizeof(*idl->comments))) == NULL) {
|
||||
r = SSH_ERR_ALLOC_FAIL;
|
||||
goto out;
|
||||
}
|
||||
for (i = 0; i < num;) {
|
||||
if ((r = deserialise_identity2(msg, &(idl->keys[i]),
|
||||
&(idl->comments[i]))) != 0) {
|
||||
if (r == SSH_ERR_KEY_TYPE_UNKNOWN) {
|
||||
/* Gracefully skip unknown key types */
|
||||
num--;
|
||||
continue;
|
||||
} else
|
||||
goto out;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
idl->nkeys = num;
|
||||
*idlp = idl;
|
||||
idl = NULL;
|
||||
r = 0;
|
||||
out:
|
||||
sshbuf_free(msg);
|
||||
if (idl != NULL)
|
||||
ssh_free_identitylist(idl);
|
||||
return r;
|
||||
}
|
||||
|
||||
void
|
||||
ssh_free_identitylist(struct ssh_identitylist *idl)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (idl == NULL)
|
||||
return;
|
||||
for (i = 0; i < idl->nkeys; i++) {
|
||||
if (idl->keys != NULL)
|
||||
sshkey_free(idl->keys[i]);
|
||||
if (idl->comments != NULL)
|
||||
free(idl->comments[i]);
|
||||
}
|
||||
free(idl->keys);
|
||||
free(idl->comments);
|
||||
free(idl);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if the ssh agent has a given key.
|
||||
* Returns 0 if found, or a negative SSH_ERR_* error code on failure.
|
||||
*/
|
||||
int
|
||||
ssh_agent_has_key(int sock, const struct sshkey *key)
|
||||
{
|
||||
int r, ret = SSH_ERR_KEY_NOT_FOUND;
|
||||
size_t i;
|
||||
struct ssh_identitylist *idlist = NULL;
|
||||
|
||||
if ((r = ssh_fetch_identitylist(sock, &idlist)) != 0) {
|
||||
return r;
|
||||
}
|
||||
|
||||
for (i = 0; i < idlist->nkeys; i++) {
|
||||
if (sshkey_equal_public(idlist->keys[i], key)) {
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ssh_free_identitylist(idlist);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sends a challenge (typically from a server via ssh(1)) to the agent,
|
||||
* and waits for a response from the agent.
|
||||
* Returns true (non-zero) if the agent gave the correct answer, zero
|
||||
* otherwise.
|
||||
*/
|
||||
|
||||
|
||||
/* encode signature algorithm in flag bits, so we can keep the msg format */
|
||||
static u_int
|
||||
agent_encode_alg(const struct sshkey *key, const char *alg)
|
||||
{
|
||||
if (alg != NULL && sshkey_type_plain(key->type) == KEY_RSA) {
|
||||
if (strcmp(alg, "rsa-sha2-256") == 0 ||
|
||||
strcmp(alg, "rsa-sha2-256-cert-v01@openssh.com") == 0)
|
||||
return SSH_AGENT_RSA_SHA2_256;
|
||||
if (strcmp(alg, "rsa-sha2-512") == 0 ||
|
||||
strcmp(alg, "rsa-sha2-512-cert-v01@openssh.com") == 0)
|
||||
return SSH_AGENT_RSA_SHA2_512;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ask agent to sign data, returns err.h code on error, 0 on success */
|
||||
int
|
||||
ssh_agent_sign(int sock, const struct sshkey *key,
|
||||
u_char **sigp, size_t *lenp,
|
||||
const u_char *data, size_t datalen, const char *alg, u_int compat)
|
||||
{
|
||||
struct sshbuf *msg;
|
||||
u_char *sig = NULL, type = 0;
|
||||
size_t len = 0;
|
||||
u_int flags = 0;
|
||||
int r = SSH_ERR_INTERNAL_ERROR;
|
||||
|
||||
*sigp = NULL;
|
||||
*lenp = 0;
|
||||
|
||||
if (datalen > SSH_KEY_MAX_SIGN_DATA_SIZE)
|
||||
return SSH_ERR_INVALID_ARGUMENT;
|
||||
if ((msg = sshbuf_new()) == NULL)
|
||||
return SSH_ERR_ALLOC_FAIL;
|
||||
flags |= agent_encode_alg(key, alg);
|
||||
if ((r = sshbuf_put_u8(msg, SSH2_AGENTC_SIGN_REQUEST)) != 0 ||
|
||||
(r = sshkey_puts(key, msg)) != 0 ||
|
||||
(r = sshbuf_put_string(msg, data, datalen)) != 0 ||
|
||||
(r = sshbuf_put_u32(msg, flags)) != 0)
|
||||
goto out;
|
||||
if ((r = ssh_request_reply(sock, msg, msg)) != 0)
|
||||
goto out;
|
||||
if ((r = sshbuf_get_u8(msg, &type)) != 0)
|
||||
goto out;
|
||||
if (agent_failed(type)) {
|
||||
r = SSH_ERR_AGENT_FAILURE;
|
||||
goto out;
|
||||
} else if (type != SSH2_AGENT_SIGN_RESPONSE) {
|
||||
r = SSH_ERR_INVALID_FORMAT;
|
||||
goto out;
|
||||
}
|
||||
if ((r = sshbuf_get_string(msg, &sig, &len)) != 0)
|
||||
goto out;
|
||||
/* Check what we actually got back from the agent. */
|
||||
if ((r = sshkey_check_sigtype(sig, len, alg)) != 0)
|
||||
goto out;
|
||||
/* success */
|
||||
*sigp = sig;
|
||||
*lenp = len;
|
||||
sig = NULL;
|
||||
len = 0;
|
||||
r = 0;
|
||||
out:
|
||||
freezero(sig, len);
|
||||
sshbuf_free(msg);
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Encode key for a message to the agent. */
|
||||
|
||||
static int
|
||||
encode_dest_constraint_hop(struct sshbuf *m,
|
||||
const struct dest_constraint_hop *dch)
|
||||
{
|
||||
struct sshbuf *b;
|
||||
u_int i;
|
||||
int r;
|
||||
|
||||
if ((b = sshbuf_new()) == NULL)
|
||||
return SSH_ERR_ALLOC_FAIL;
|
||||
if ((r = sshbuf_put_cstring(b, dch->user)) != 0 ||
|
||||
(r = sshbuf_put_cstring(b, dch->hostname)) != 0 ||
|
||||
(r = sshbuf_put_string(b, NULL, 0)) != 0) /* reserved */
|
||||
goto out;
|
||||
for (i = 0; i < dch->nkeys; i++) {
|
||||
if ((r = sshkey_puts(dch->keys[i], b)) != 0 ||
|
||||
(r = sshbuf_put_u8(b, dch->key_is_ca[i] != 0)) != 0)
|
||||
goto out;
|
||||
}
|
||||
if ((r = sshbuf_put_stringb(m, b)) != 0)
|
||||
goto out;
|
||||
/* success */
|
||||
r = 0;
|
||||
out:
|
||||
sshbuf_free(b);
|
||||
return r;
|
||||
}
|
||||
|
||||
static int
|
||||
encode_dest_constraint(struct sshbuf *m, const struct dest_constraint *dc)
|
||||
{
|
||||
struct sshbuf *b;
|
||||
int r;
|
||||
|
||||
if ((b = sshbuf_new()) == NULL)
|
||||
return SSH_ERR_ALLOC_FAIL;
|
||||
if ((r = encode_dest_constraint_hop(b, &dc->from)) != 0 ||
|
||||
(r = encode_dest_constraint_hop(b, &dc->to)) != 0 ||
|
||||
(r = sshbuf_put_string(b, NULL, 0)) != 0) /* reserved */
|
||||
goto out;
|
||||
if ((r = sshbuf_put_stringb(m, b)) != 0)
|
||||
goto out;
|
||||
/* success */
|
||||
r = 0;
|
||||
out:
|
||||
sshbuf_free(b);
|
||||
return r;
|
||||
}
|
||||
|
||||
static int
|
||||
encode_constraints(struct sshbuf *m, u_int life, u_int confirm,
|
||||
u_int maxsign, const char *provider,
|
||||
struct dest_constraint **dest_constraints, size_t ndest_constraints,
|
||||
int cert_only, struct sshkey **certs, size_t ncerts)
|
||||
{
|
||||
int r;
|
||||
struct sshbuf *b = NULL;
|
||||
size_t i;
|
||||
|
||||
if (life != 0) {
|
||||
if ((r = sshbuf_put_u8(m, SSH_AGENT_CONSTRAIN_LIFETIME)) != 0 ||
|
||||
(r = sshbuf_put_u32(m, life)) != 0)
|
||||
goto out;
|
||||
}
|
||||
if (confirm != 0) {
|
||||
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 ||
|
||||
(r = sshbuf_put_cstring(m,
|
||||
"sk-provider@openssh.com")) != 0 ||
|
||||
(r = sshbuf_put_cstring(m, provider)) != 0)
|
||||
goto out;
|
||||
}
|
||||
if (dest_constraints != NULL && ndest_constraints > 0) {
|
||||
if ((b = sshbuf_new()) == NULL) {
|
||||
r = SSH_ERR_ALLOC_FAIL;
|
||||
goto out;
|
||||
}
|
||||
for (i = 0; i < ndest_constraints; i++) {
|
||||
if ((r = encode_dest_constraint(b,
|
||||
dest_constraints[i])) != 0)
|
||||
goto out;
|
||||
}
|
||||
if ((r = sshbuf_put_u8(m,
|
||||
SSH_AGENT_CONSTRAIN_EXTENSION)) != 0 ||
|
||||
(r = sshbuf_put_cstring(m,
|
||||
"restrict-destination-v00@openssh.com")) != 0 ||
|
||||
(r = sshbuf_put_stringb(m, b)) != 0)
|
||||
goto out;
|
||||
sshbuf_free(b);
|
||||
b = NULL;
|
||||
}
|
||||
if (ncerts != 0) {
|
||||
if ((b = sshbuf_new()) == NULL) {
|
||||
r = SSH_ERR_ALLOC_FAIL;
|
||||
goto out;
|
||||
}
|
||||
for (i = 0; i < ncerts; i++) {
|
||||
if ((r = sshkey_puts(certs[i], b)) != 0)
|
||||
goto out;
|
||||
}
|
||||
if ((r = sshbuf_put_u8(m,
|
||||
SSH_AGENT_CONSTRAIN_EXTENSION)) != 0 ||
|
||||
(r = sshbuf_put_cstring(m,
|
||||
"associated-certs-v00@openssh.com")) != 0 ||
|
||||
(r = sshbuf_put_u8(m, cert_only != 0)) != 0 ||
|
||||
(r = sshbuf_put_stringb(m, b)) != 0)
|
||||
goto out;
|
||||
sshbuf_free(b);
|
||||
b = NULL;
|
||||
}
|
||||
r = 0;
|
||||
out:
|
||||
sshbuf_free(b);
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* Adds an identity to the authentication server.
|
||||
* This call is intended only for use by ssh-add(1) and like applications.
|
||||
*/
|
||||
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)
|
||||
{
|
||||
struct sshbuf *msg;
|
||||
int r, constrained = (life || confirm || maxsign ||
|
||||
provider || dest_constraints);
|
||||
u_char type;
|
||||
|
||||
if ((msg = sshbuf_new()) == NULL)
|
||||
return SSH_ERR_ALLOC_FAIL;
|
||||
|
||||
switch (key->type) {
|
||||
#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:
|
||||
case KEY_ECDSA_SK_CERT:
|
||||
#endif
|
||||
case KEY_ED25519:
|
||||
case KEY_ED25519_CERT:
|
||||
case KEY_ED25519_SK:
|
||||
case KEY_ED25519_SK_CERT:
|
||||
case KEY_XMSS:
|
||||
case KEY_XMSS_CERT:
|
||||
type = constrained ?
|
||||
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 = sshbuf_put_cstring(msg, comment)) != 0)
|
||||
goto out;
|
||||
break;
|
||||
default:
|
||||
r = SSH_ERR_INVALID_ARGUMENT;
|
||||
goto out;
|
||||
}
|
||||
if (constrained &&
|
||||
(r = encode_constraints(msg, life, confirm, maxsign,
|
||||
provider, dest_constraints, ndest_constraints, 0, NULL, 0)) != 0)
|
||||
goto out;
|
||||
if ((r = ssh_request_reply_decode(sock, msg)) != 0)
|
||||
goto out;
|
||||
/* success */
|
||||
r = 0;
|
||||
out:
|
||||
sshbuf_free(msg);
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* Removes an identity from the authentication server.
|
||||
* This call is intended only for use by ssh-add(1) and like applications.
|
||||
*/
|
||||
int
|
||||
ssh_remove_identity(int sock, const struct sshkey *key)
|
||||
{
|
||||
struct sshbuf *msg;
|
||||
int r;
|
||||
u_char *blob = NULL;
|
||||
size_t blen;
|
||||
|
||||
if ((msg = sshbuf_new()) == NULL)
|
||||
return SSH_ERR_ALLOC_FAIL;
|
||||
|
||||
if (key->type != KEY_UNSPEC) {
|
||||
if ((r = sshkey_to_blob(key, &blob, &blen)) != 0)
|
||||
goto out;
|
||||
if ((r = sshbuf_put_u8(msg,
|
||||
SSH2_AGENTC_REMOVE_IDENTITY)) != 0 ||
|
||||
(r = sshbuf_put_string(msg, blob, blen)) != 0)
|
||||
goto out;
|
||||
} else {
|
||||
r = SSH_ERR_INVALID_ARGUMENT;
|
||||
goto out;
|
||||
}
|
||||
if ((r = ssh_request_reply_decode(sock, msg)) != 0)
|
||||
goto out;
|
||||
/* success */
|
||||
r = 0;
|
||||
out:
|
||||
if (blob != NULL)
|
||||
freezero(blob, blen);
|
||||
sshbuf_free(msg);
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add/remove an token-based identity from the authentication server.
|
||||
* This call is intended only for use by ssh-add(1) and like applications.
|
||||
*/
|
||||
int
|
||||
ssh_update_card(int sock, int add, const char *reader_id, const char *pin,
|
||||
u_int life, u_int confirm,
|
||||
struct dest_constraint **dest_constraints, size_t ndest_constraints,
|
||||
int cert_only, struct sshkey **certs, size_t ncerts)
|
||||
{
|
||||
struct sshbuf *msg;
|
||||
int r, constrained = (life || confirm || dest_constraints || certs);
|
||||
u_char type;
|
||||
|
||||
if (add) {
|
||||
type = constrained ?
|
||||
SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED :
|
||||
SSH_AGENTC_ADD_SMARTCARD_KEY;
|
||||
} else
|
||||
type = SSH_AGENTC_REMOVE_SMARTCARD_KEY;
|
||||
|
||||
if ((msg = sshbuf_new()) == NULL)
|
||||
return SSH_ERR_ALLOC_FAIL;
|
||||
if ((r = sshbuf_put_u8(msg, type)) != 0 ||
|
||||
(r = sshbuf_put_cstring(msg, reader_id)) != 0 ||
|
||||
(r = sshbuf_put_cstring(msg, pin)) != 0)
|
||||
goto out;
|
||||
if (constrained &&
|
||||
(r = encode_constraints(msg, life, confirm, 0, NULL,
|
||||
dest_constraints, ndest_constraints,
|
||||
cert_only, certs, ncerts)) != 0)
|
||||
goto out;
|
||||
if ((r = ssh_request_reply_decode(sock, msg)) != 0)
|
||||
goto out;
|
||||
/* success */
|
||||
r = 0;
|
||||
out:
|
||||
sshbuf_free(msg);
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* Removes all identities from the agent.
|
||||
* This call is intended only for use by ssh-add(1) and like applications.
|
||||
*
|
||||
* This supports the SSH protocol 1 message to because, when clearing all
|
||||
* keys from an agent, we generally want to clear both protocol v1 and v2
|
||||
* keys.
|
||||
*/
|
||||
int
|
||||
ssh_remove_all_identities(int sock, int version)
|
||||
{
|
||||
struct sshbuf *msg;
|
||||
u_char type = (version == 1) ?
|
||||
SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES :
|
||||
SSH2_AGENTC_REMOVE_ALL_IDENTITIES;
|
||||
int r;
|
||||
|
||||
if ((msg = sshbuf_new()) == NULL)
|
||||
return SSH_ERR_ALLOC_FAIL;
|
||||
if ((r = sshbuf_put_u8(msg, type)) != 0)
|
||||
goto out;
|
||||
if ((r = ssh_request_reply_decode(sock, msg)) != 0)
|
||||
goto out;
|
||||
/* success */
|
||||
r = 0;
|
||||
out:
|
||||
sshbuf_free(msg);
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Binds a session ID to a hostkey via the initial KEX signature. */
|
||||
int
|
||||
ssh_agent_bind_hostkey(int sock, const struct sshkey *key,
|
||||
const struct sshbuf *session_id, const struct sshbuf *signature,
|
||||
int forwarding)
|
||||
{
|
||||
struct sshbuf *msg;
|
||||
int r;
|
||||
|
||||
if (key == NULL || session_id == NULL || signature == NULL)
|
||||
return SSH_ERR_INVALID_ARGUMENT;
|
||||
if ((msg = sshbuf_new()) == NULL)
|
||||
return SSH_ERR_ALLOC_FAIL;
|
||||
if ((r = sshbuf_put_u8(msg, SSH_AGENTC_EXTENSION)) != 0 ||
|
||||
(r = sshbuf_put_cstring(msg, "session-bind@openssh.com")) != 0 ||
|
||||
(r = sshkey_puts(key, msg)) != 0 ||
|
||||
(r = sshbuf_put_stringb(msg, session_id)) != 0 ||
|
||||
(r = sshbuf_put_stringb(msg, signature)) != 0 ||
|
||||
(r = sshbuf_put_u8(msg, forwarding ? 1 : 0)) != 0)
|
||||
goto out;
|
||||
if ((r = ssh_request_reply_decode(sock, msg)) != 0)
|
||||
goto out;
|
||||
/* success */
|
||||
r = 0;
|
||||
out:
|
||||
sshbuf_free(msg);
|
||||
return r;
|
||||
}
|
122
authfd.h
Normal file
122
authfd.h
Normal file
|
@ -0,0 +1,122 @@
|
|||
/* $OpenBSD: authfd.h,v 1.52 2023/12/18 14:46:56 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
* All rights reserved
|
||||
* Functions to interface with the SSH_AUTHENTICATION_FD socket.
|
||||
*
|
||||
* As far as I am concerned, the code I have written for this software
|
||||
* can be used freely for any purpose. Any derived versions of this
|
||||
* software must be clearly marked as such, and if the derived work is
|
||||
* incompatible with the protocol description in the RFC file, it must be
|
||||
* called by a name other than "ssh" or "Secure Shell".
|
||||
*/
|
||||
|
||||
#ifndef AUTHFD_H
|
||||
#define AUTHFD_H
|
||||
|
||||
struct sshbuf;
|
||||
struct sshkey;
|
||||
|
||||
/* List of identities returned by ssh_fetch_identitylist() */
|
||||
struct ssh_identitylist {
|
||||
size_t nkeys;
|
||||
struct sshkey **keys;
|
||||
char **comments;
|
||||
};
|
||||
|
||||
/* Key destination restrictions */
|
||||
struct dest_constraint_hop {
|
||||
char *user; /* wildcards allowed */
|
||||
char *hostname; /* used to matching cert principals and for display */
|
||||
int is_ca;
|
||||
u_int nkeys; /* number of entries in *both* 'keys' and 'key_is_ca' */
|
||||
struct sshkey **keys;
|
||||
int *key_is_ca;
|
||||
};
|
||||
struct dest_constraint {
|
||||
struct dest_constraint_hop from;
|
||||
struct dest_constraint_hop to;
|
||||
};
|
||||
|
||||
int ssh_get_authentication_socket(int *fdp);
|
||||
int ssh_get_authentication_socket_path(const char *authsocket, int *fdp);
|
||||
void ssh_close_authentication_socket(int sock);
|
||||
|
||||
int ssh_lock_agent(int sock, int lock, const char *password);
|
||||
int ssh_fetch_identitylist(int sock, struct ssh_identitylist **idlp);
|
||||
void ssh_free_identitylist(struct ssh_identitylist *idl);
|
||||
int ssh_add_identity_constrained(int sock, 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);
|
||||
int ssh_agent_has_key(int sock, const struct sshkey *key);
|
||||
int ssh_remove_identity(int sock, const struct sshkey *key);
|
||||
int ssh_update_card(int sock, int add, const char *reader_id,
|
||||
const char *pin, u_int life, u_int confirm,
|
||||
struct dest_constraint **dest_constraints,
|
||||
size_t ndest_constraints,
|
||||
int cert_only, struct sshkey **certs, size_t ncerts);
|
||||
int ssh_remove_all_identities(int sock, int version);
|
||||
|
||||
int ssh_agent_sign(int sock, const struct sshkey *key,
|
||||
u_char **sigp, size_t *lenp,
|
||||
const u_char *data, size_t datalen, const char *alg, u_int compat);
|
||||
|
||||
int ssh_agent_bind_hostkey(int sock, const struct sshkey *key,
|
||||
const struct sshbuf *session_id, const struct sshbuf *signature,
|
||||
int forwarding);
|
||||
|
||||
/* Messages for the authentication agent connection. */
|
||||
#define SSH_AGENTC_REQUEST_RSA_IDENTITIES 1
|
||||
#define SSH_AGENT_RSA_IDENTITIES_ANSWER 2
|
||||
#define SSH_AGENTC_RSA_CHALLENGE 3
|
||||
#define SSH_AGENT_RSA_RESPONSE 4
|
||||
#define SSH_AGENT_FAILURE 5
|
||||
#define SSH_AGENT_SUCCESS 6
|
||||
#define SSH_AGENTC_ADD_RSA_IDENTITY 7
|
||||
#define SSH_AGENTC_REMOVE_RSA_IDENTITY 8
|
||||
#define SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES 9
|
||||
|
||||
/* private OpenSSH extensions for SSH2 */
|
||||
#define SSH2_AGENTC_REQUEST_IDENTITIES 11
|
||||
#define SSH2_AGENT_IDENTITIES_ANSWER 12
|
||||
#define SSH2_AGENTC_SIGN_REQUEST 13
|
||||
#define SSH2_AGENT_SIGN_RESPONSE 14
|
||||
#define SSH2_AGENTC_ADD_IDENTITY 17
|
||||
#define SSH2_AGENTC_REMOVE_IDENTITY 18
|
||||
#define SSH2_AGENTC_REMOVE_ALL_IDENTITIES 19
|
||||
|
||||
/* smartcard */
|
||||
#define SSH_AGENTC_ADD_SMARTCARD_KEY 20
|
||||
#define SSH_AGENTC_REMOVE_SMARTCARD_KEY 21
|
||||
|
||||
/* lock/unlock the agent */
|
||||
#define SSH_AGENTC_LOCK 22
|
||||
#define SSH_AGENTC_UNLOCK 23
|
||||
|
||||
/* add key with constraints */
|
||||
#define SSH_AGENTC_ADD_RSA_ID_CONSTRAINED 24
|
||||
#define SSH2_AGENTC_ADD_ID_CONSTRAINED 25
|
||||
#define SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED 26
|
||||
|
||||
/* generic extension mechanism */
|
||||
#define SSH_AGENTC_EXTENSION 27
|
||||
|
||||
#define SSH_AGENT_CONSTRAIN_LIFETIME 1
|
||||
#define SSH_AGENT_CONSTRAIN_CONFIRM 2
|
||||
#define SSH_AGENT_CONSTRAIN_MAXSIGN 3
|
||||
#define SSH_AGENT_CONSTRAIN_EXTENSION 255
|
||||
|
||||
/* extended failure messages */
|
||||
#define SSH2_AGENT_FAILURE 30
|
||||
|
||||
/* additional error code for ssh.com's ssh-agent2 */
|
||||
#define SSH_COM_AGENT2_FAILURE 102
|
||||
|
||||
#define SSH_AGENT_OLD_SIGNATURE 0x01
|
||||
#define SSH_AGENT_RSA_SHA2_256 0x02
|
||||
#define SSH_AGENT_RSA_SHA2_512 0x04
|
||||
|
||||
#endif /* AUTHFD_H */
|
526
authfile.c
Normal file
526
authfile.c
Normal file
|
@ -0,0 +1,526 @@
|
|||
/* $OpenBSD: authfile.c,v 1.145 2024/09/22 12:56:21 jsg Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000, 2013 Markus Friedl. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/uio.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "cipher.h"
|
||||
#include "ssh.h"
|
||||
#include "log.h"
|
||||
#include "authfile.h"
|
||||
#include "misc.h"
|
||||
#include "atomicio.h"
|
||||
#include "sshkey.h"
|
||||
#include "sshbuf.h"
|
||||
#include "ssherr.h"
|
||||
#include "krl.h"
|
||||
|
||||
/* Save a key blob to a file */
|
||||
static int
|
||||
sshkey_save_private_blob(struct sshbuf *keybuf, const char *filename)
|
||||
{
|
||||
int r;
|
||||
mode_t omask;
|
||||
|
||||
omask = umask(077);
|
||||
r = sshbuf_write_file(filename, keybuf);
|
||||
umask(omask);
|
||||
return r;
|
||||
}
|
||||
|
||||
int
|
||||
sshkey_save_private(struct sshkey *key, const char *filename,
|
||||
const char *passphrase, const char *comment,
|
||||
int format, const char *openssh_format_cipher, int openssh_format_rounds)
|
||||
{
|
||||
struct sshbuf *keyblob = NULL;
|
||||
int r;
|
||||
|
||||
if ((keyblob = sshbuf_new()) == NULL)
|
||||
return SSH_ERR_ALLOC_FAIL;
|
||||
if ((r = sshkey_private_to_fileblob(key, keyblob, passphrase, comment,
|
||||
format, openssh_format_cipher, openssh_format_rounds)) != 0)
|
||||
goto out;
|
||||
if ((r = sshkey_save_private_blob(keyblob, filename)) != 0)
|
||||
goto out;
|
||||
r = 0;
|
||||
out:
|
||||
sshbuf_free(keyblob);
|
||||
return r;
|
||||
}
|
||||
|
||||
/* XXX remove error() calls from here? */
|
||||
int
|
||||
sshkey_perm_ok(int fd, const char *filename)
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
if (fstat(fd, &st) == -1)
|
||||
return SSH_ERR_SYSTEM_ERROR;
|
||||
/*
|
||||
* if a key owned by the user is accessed, then we check the
|
||||
* permissions of the file. if the key owned by a different user,
|
||||
* then we don't care.
|
||||
*/
|
||||
#ifdef HAVE_CYGWIN
|
||||
if (check_ntsec(filename))
|
||||
#endif
|
||||
if ((st.st_uid == getuid()) && (st.st_mode & 077) != 0) {
|
||||
error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
|
||||
error("@ WARNING: UNPROTECTED PRIVATE KEY FILE! @");
|
||||
error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
|
||||
error("Permissions 0%3.3o for '%s' are too open.",
|
||||
(u_int)st.st_mode & 0777, filename);
|
||||
error("It is required that your private key files are NOT accessible by others.");
|
||||
error("This private key will be ignored.");
|
||||
return SSH_ERR_KEY_BAD_PERMISSIONS;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
sshkey_load_private_type(int type, const char *filename, const char *passphrase,
|
||||
struct sshkey **keyp, char **commentp)
|
||||
{
|
||||
int fd, r;
|
||||
|
||||
if (keyp != NULL)
|
||||
*keyp = NULL;
|
||||
if (commentp != NULL)
|
||||
*commentp = NULL;
|
||||
|
||||
if ((fd = open(filename, O_RDONLY)) == -1)
|
||||
return SSH_ERR_SYSTEM_ERROR;
|
||||
|
||||
r = sshkey_perm_ok(fd, filename);
|
||||
if (r != 0)
|
||||
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;
|
||||
}
|
||||
|
||||
int
|
||||
sshkey_load_private(const char *filename, const char *passphrase,
|
||||
struct sshkey **keyp, char **commentp)
|
||||
{
|
||||
return sshkey_load_private_type(KEY_UNSPEC, filename, passphrase,
|
||||
keyp, commentp);
|
||||
}
|
||||
|
||||
int
|
||||
sshkey_load_private_type_fd(int fd, int type, const char *passphrase,
|
||||
struct sshkey **keyp, char **commentp)
|
||||
{
|
||||
struct sshbuf *buffer = NULL;
|
||||
int r;
|
||||
|
||||
if (keyp != NULL)
|
||||
*keyp = NULL;
|
||||
if ((r = sshbuf_load_fd(fd, &buffer)) != 0 ||
|
||||
(r = sshkey_parse_private_fileblob_type(buffer, type,
|
||||
passphrase, keyp, commentp)) != 0)
|
||||
goto out;
|
||||
|
||||
/* success */
|
||||
r = 0;
|
||||
out:
|
||||
sshbuf_free(buffer);
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Load a pubkey from the unencrypted envelope of a new-format private key */
|
||||
static int
|
||||
sshkey_load_pubkey_from_private(const char *filename, struct sshkey **pubkeyp)
|
||||
{
|
||||
struct sshbuf *buffer = NULL;
|
||||
struct sshkey *pubkey = NULL;
|
||||
int r, fd;
|
||||
|
||||
if (pubkeyp != NULL)
|
||||
*pubkeyp = NULL;
|
||||
|
||||
if ((fd = open(filename, O_RDONLY)) == -1)
|
||||
return SSH_ERR_SYSTEM_ERROR;
|
||||
if ((r = sshbuf_load_fd(fd, &buffer)) != 0 ||
|
||||
(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;
|
||||
pubkey = NULL;
|
||||
}
|
||||
r = 0;
|
||||
out:
|
||||
close(fd);
|
||||
sshbuf_free(buffer);
|
||||
sshkey_free(pubkey);
|
||||
return r;
|
||||
}
|
||||
|
||||
static int
|
||||
sshkey_try_load_public(struct sshkey **kp, const char *filename,
|
||||
char **commentp)
|
||||
{
|
||||
FILE *f;
|
||||
char *line = NULL, *cp;
|
||||
size_t linesize = 0;
|
||||
int r;
|
||||
struct sshkey *k = NULL;
|
||||
|
||||
if (kp == NULL)
|
||||
return SSH_ERR_INVALID_ARGUMENT;
|
||||
*kp = NULL;
|
||||
if (commentp != NULL)
|
||||
*commentp = NULL;
|
||||
if ((f = fopen(filename, "r")) == NULL)
|
||||
return SSH_ERR_SYSTEM_ERROR;
|
||||
if ((k = sshkey_new(KEY_UNSPEC)) == NULL) {
|
||||
fclose(f);
|
||||
return SSH_ERR_ALLOC_FAIL;
|
||||
}
|
||||
while (getline(&line, &linesize, f) != -1) {
|
||||
cp = line;
|
||||
switch (*cp) {
|
||||
case '#':
|
||||
case '\n':
|
||||
case '\0':
|
||||
continue;
|
||||
}
|
||||
/* Abort loading if this looks like a private key */
|
||||
if (strncmp(cp, "-----BEGIN", 10) == 0 ||
|
||||
strcmp(cp, "SSH PRIVATE KEY FILE") == 0)
|
||||
break;
|
||||
/* Skip leading whitespace. */
|
||||
for (; *cp && (*cp == ' ' || *cp == '\t'); cp++)
|
||||
;
|
||||
if (*cp) {
|
||||
if ((r = sshkey_read(k, &cp)) == 0) {
|
||||
cp[strcspn(cp, "\r\n")] = '\0';
|
||||
if (commentp) {
|
||||
*commentp = strdup(*cp ?
|
||||
cp : filename);
|
||||
if (*commentp == NULL)
|
||||
r = SSH_ERR_ALLOC_FAIL;
|
||||
}
|
||||
/* success */
|
||||
*kp = k;
|
||||
free(line);
|
||||
fclose(f);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
}
|
||||
free(k);
|
||||
free(line);
|
||||
fclose(f);
|
||||
return SSH_ERR_INVALID_FORMAT;
|
||||
}
|
||||
|
||||
/* load public key from any pubkey file */
|
||||
int
|
||||
sshkey_load_public(const char *filename, struct sshkey **keyp, char **commentp)
|
||||
{
|
||||
char *pubfile = NULL;
|
||||
int r, oerrno;
|
||||
|
||||
if (keyp != NULL)
|
||||
*keyp = NULL;
|
||||
if (commentp != NULL)
|
||||
*commentp = NULL;
|
||||
|
||||
if ((r = sshkey_try_load_public(keyp, filename, commentp)) == 0)
|
||||
goto out;
|
||||
|
||||
/* try .pub suffix */
|
||||
if (asprintf(&pubfile, "%s.pub", filename) == -1)
|
||||
return SSH_ERR_ALLOC_FAIL;
|
||||
if ((r = sshkey_try_load_public(keyp, pubfile, commentp)) == 0)
|
||||
goto out;
|
||||
|
||||
/* finally, try to extract public key from private key file */
|
||||
if ((r = sshkey_load_pubkey_from_private(filename, keyp)) == 0)
|
||||
goto out;
|
||||
|
||||
/* Pretend we couldn't find the key */
|
||||
r = SSH_ERR_SYSTEM_ERROR;
|
||||
errno = ENOENT;
|
||||
|
||||
out:
|
||||
oerrno = errno;
|
||||
free(pubfile);
|
||||
errno = oerrno;
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Load the certificate associated with the named private key */
|
||||
int
|
||||
sshkey_load_cert(const char *filename, struct sshkey **keyp)
|
||||
{
|
||||
struct sshkey *pub = NULL;
|
||||
char *file = NULL;
|
||||
int r = SSH_ERR_INTERNAL_ERROR;
|
||||
|
||||
if (keyp != NULL)
|
||||
*keyp = NULL;
|
||||
|
||||
if (asprintf(&file, "%s-cert.pub", filename) == -1)
|
||||
return SSH_ERR_ALLOC_FAIL;
|
||||
|
||||
r = sshkey_try_load_public(keyp, file, NULL);
|
||||
free(file);
|
||||
sshkey_free(pub);
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Load private key and certificate */
|
||||
int
|
||||
sshkey_load_private_cert(int type, const char *filename, const char *passphrase,
|
||||
struct sshkey **keyp)
|
||||
{
|
||||
struct sshkey *key = NULL, *cert = NULL;
|
||||
int r;
|
||||
|
||||
if (keyp != NULL)
|
||||
*keyp = NULL;
|
||||
|
||||
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:
|
||||
return SSH_ERR_KEY_TYPE_UNKNOWN;
|
||||
}
|
||||
|
||||
if ((r = sshkey_load_private_type(type, filename,
|
||||
passphrase, &key, NULL)) != 0 ||
|
||||
(r = sshkey_load_cert(filename, &cert)) != 0)
|
||||
goto out;
|
||||
|
||||
/* Make sure the private key matches the certificate */
|
||||
if (sshkey_equal_public(key, cert) == 0) {
|
||||
r = SSH_ERR_KEY_CERT_MISMATCH;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ((r = sshkey_to_certified(key)) != 0 ||
|
||||
(r = sshkey_cert_copy(cert, key)) != 0)
|
||||
goto out;
|
||||
r = 0;
|
||||
if (keyp != NULL) {
|
||||
*keyp = key;
|
||||
key = NULL;
|
||||
}
|
||||
out:
|
||||
sshkey_free(key);
|
||||
sshkey_free(cert);
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns success if the specified "key" is listed in the file "filename",
|
||||
* SSH_ERR_KEY_NOT_FOUND: if the key is not listed or another error.
|
||||
* If "strict_type" is set then the key type must match exactly,
|
||||
* otherwise a comparison that ignores certificate data is performed.
|
||||
* If "check_ca" is set and "key" is a certificate, then its CA key is
|
||||
* also checked and sshkey_in_file() will return success if either is found.
|
||||
*/
|
||||
int
|
||||
sshkey_in_file(struct sshkey *key, const char *filename, int strict_type,
|
||||
int check_ca)
|
||||
{
|
||||
FILE *f;
|
||||
char *line = NULL, *cp;
|
||||
size_t linesize = 0;
|
||||
int r = 0;
|
||||
struct sshkey *pub = NULL;
|
||||
|
||||
int (*sshkey_compare)(const struct sshkey *, const struct sshkey *) =
|
||||
strict_type ? sshkey_equal : sshkey_equal_public;
|
||||
|
||||
if ((f = fopen(filename, "r")) == NULL)
|
||||
return SSH_ERR_SYSTEM_ERROR;
|
||||
|
||||
while (getline(&line, &linesize, f) != -1) {
|
||||
sshkey_free(pub);
|
||||
pub = NULL;
|
||||
cp = line;
|
||||
|
||||
/* Skip leading whitespace. */
|
||||
for (; *cp && (*cp == ' ' || *cp == '\t'); cp++)
|
||||
;
|
||||
|
||||
/* Skip comments and empty lines */
|
||||
switch (*cp) {
|
||||
case '#':
|
||||
case '\n':
|
||||
case '\0':
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((pub = sshkey_new(KEY_UNSPEC)) == NULL) {
|
||||
r = SSH_ERR_ALLOC_FAIL;
|
||||
goto out;
|
||||
}
|
||||
switch (r = sshkey_read(pub, &cp)) {
|
||||
case 0:
|
||||
break;
|
||||
case SSH_ERR_KEY_LENGTH:
|
||||
continue;
|
||||
default:
|
||||
goto out;
|
||||
}
|
||||
if (sshkey_compare(key, pub) ||
|
||||
(check_ca && sshkey_is_cert(key) &&
|
||||
sshkey_compare(key->cert->signature_key, pub))) {
|
||||
r = 0;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
r = SSH_ERR_KEY_NOT_FOUND;
|
||||
out:
|
||||
free(line);
|
||||
sshkey_free(pub);
|
||||
fclose(f);
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks whether the specified key is revoked, returning 0 if not,
|
||||
* SSH_ERR_KEY_REVOKED if it is or another error code if something
|
||||
* unexpected happened.
|
||||
* This will check both the key and, if it is a certificate, its CA key too.
|
||||
* "revoked_keys_file" may be a KRL or a one-per-line list of public keys.
|
||||
*/
|
||||
int
|
||||
sshkey_check_revoked(struct sshkey *key, const char *revoked_keys_file)
|
||||
{
|
||||
int r;
|
||||
|
||||
r = ssh_krl_file_contains_key(revoked_keys_file, key);
|
||||
/* If this was not a KRL to begin with then continue below */
|
||||
if (r != SSH_ERR_KRL_BAD_MAGIC)
|
||||
return r;
|
||||
|
||||
/*
|
||||
* If the file is not a KRL or we can't handle KRLs then attempt to
|
||||
* parse the file as a flat list of keys.
|
||||
*/
|
||||
switch ((r = sshkey_in_file(key, revoked_keys_file, 0, 1))) {
|
||||
case 0:
|
||||
/* Key found => revoked */
|
||||
return SSH_ERR_KEY_REVOKED;
|
||||
case SSH_ERR_KEY_NOT_FOUND:
|
||||
/* Key not found => not revoked */
|
||||
return 0;
|
||||
default:
|
||||
/* Some other error occurred */
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Advanced *cpp past the end of key options, defined as the first unquoted
|
||||
* whitespace character. Returns 0 on success or -1 on failure (e.g.
|
||||
* unterminated quotes).
|
||||
*/
|
||||
int
|
||||
sshkey_advance_past_options(char **cpp)
|
||||
{
|
||||
char *cp = *cpp;
|
||||
int quoted = 0;
|
||||
|
||||
for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) {
|
||||
if (*cp == '\\' && cp[1] == '"')
|
||||
cp++; /* Skip both */
|
||||
else if (*cp == '"')
|
||||
quoted = !quoted;
|
||||
}
|
||||
*cpp = cp;
|
||||
/* return failure for unterminated quotes */
|
||||
return (*cp == '\0' && quoted) ? -1 : 0;
|
||||
}
|
||||
|
||||
/* Save a public key */
|
||||
int
|
||||
sshkey_save_public(const struct sshkey *key, const char *path,
|
||||
const char *comment)
|
||||
{
|
||||
int fd, oerrno;
|
||||
FILE *f = NULL;
|
||||
int r = SSH_ERR_INTERNAL_ERROR;
|
||||
|
||||
if ((fd = open(path, O_WRONLY|O_CREAT|O_TRUNC, 0644)) == -1)
|
||||
return SSH_ERR_SYSTEM_ERROR;
|
||||
if ((f = fdopen(fd, "w")) == NULL) {
|
||||
r = SSH_ERR_SYSTEM_ERROR;
|
||||
close(fd);
|
||||
goto fail;
|
||||
}
|
||||
if ((r = sshkey_write(key, f)) != 0)
|
||||
goto fail;
|
||||
fprintf(f, " %s\n", comment);
|
||||
if (ferror(f)) {
|
||||
r = SSH_ERR_SYSTEM_ERROR;
|
||||
goto fail;
|
||||
}
|
||||
if (fclose(f) != 0) {
|
||||
r = SSH_ERR_SYSTEM_ERROR;
|
||||
f = NULL;
|
||||
fail:
|
||||
if (f != NULL) {
|
||||
oerrno = errno;
|
||||
fclose(f);
|
||||
errno = oerrno;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
return 0;
|
||||
}
|
54
authfile.h
Normal file
54
authfile.h
Normal file
|
@ -0,0 +1,54 @@
|
|||
/* $OpenBSD: authfile.h,v 1.25 2020/01/25 23:02:13 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000, 2013 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 AUTHFILE_H
|
||||
#define AUTHFILE_H
|
||||
|
||||
struct sshbuf;
|
||||
struct sshkey;
|
||||
|
||||
/* XXX document these */
|
||||
/* XXX some of these could probably be merged/retired */
|
||||
|
||||
int sshkey_save_private(struct sshkey *, const char *,
|
||||
const char *, const char *, int, const char *, int);
|
||||
int sshkey_load_cert(const char *, struct sshkey **);
|
||||
int sshkey_load_public(const char *, struct sshkey **, char **);
|
||||
int sshkey_load_private(const char *, const char *, struct sshkey **, char **);
|
||||
int sshkey_load_private_cert(int, const char *, const char *,
|
||||
struct sshkey **);
|
||||
int sshkey_load_private_type(int, const char *, const char *,
|
||||
struct sshkey **, char **);
|
||||
int sshkey_load_private_type_fd(int fd, int type, const char *passphrase,
|
||||
struct sshkey **keyp, char **commentp);
|
||||
int sshkey_perm_ok(int, const char *);
|
||||
int sshkey_in_file(struct sshkey *, const char *, int, int);
|
||||
int sshkey_check_revoked(struct sshkey *key, const char *revoked_keys_file);
|
||||
int sshkey_advance_past_options(char **cpp);
|
||||
int sshkey_save_public(const struct sshkey *key, const char *path,
|
||||
const char *comment);
|
||||
|
||||
#endif
|
214
bitmap.c
Normal file
214
bitmap.c
Normal file
|
@ -0,0 +1,214 @@
|
|||
/* $OpenBSD: bitmap.c,v 1.9 2017/10/20 01:56:39 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2015 Damien Miller <djm@mindrot.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "bitmap.h"
|
||||
|
||||
#define BITMAP_WTYPE u_int
|
||||
#define BITMAP_MAX (1<<24)
|
||||
#define BITMAP_BYTES (sizeof(BITMAP_WTYPE))
|
||||
#define BITMAP_BITS (sizeof(BITMAP_WTYPE) * 8)
|
||||
#define BITMAP_WMASK ((BITMAP_WTYPE)BITMAP_BITS - 1)
|
||||
struct bitmap {
|
||||
BITMAP_WTYPE *d;
|
||||
size_t len; /* number of words allocated */
|
||||
size_t top; /* index of top word allocated */
|
||||
};
|
||||
|
||||
struct bitmap *
|
||||
bitmap_new(void)
|
||||
{
|
||||
struct bitmap *ret;
|
||||
|
||||
if ((ret = calloc(1, sizeof(*ret))) == NULL)
|
||||
return NULL;
|
||||
if ((ret->d = calloc(1, BITMAP_BYTES)) == NULL) {
|
||||
free(ret);
|
||||
return NULL;
|
||||
}
|
||||
ret->len = 1;
|
||||
ret->top = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
bitmap_free(struct bitmap *b)
|
||||
{
|
||||
if (b != NULL && b->d != NULL) {
|
||||
bitmap_zero(b);
|
||||
free(b->d);
|
||||
b->d = NULL;
|
||||
}
|
||||
free(b);
|
||||
}
|
||||
|
||||
void
|
||||
bitmap_zero(struct bitmap *b)
|
||||
{
|
||||
memset(b->d, 0, b->len * BITMAP_BYTES);
|
||||
b->top = 0;
|
||||
}
|
||||
|
||||
int
|
||||
bitmap_test_bit(struct bitmap *b, u_int n)
|
||||
{
|
||||
if (b->top >= b->len)
|
||||
return 0; /* invalid */
|
||||
if (b->len == 0 || (n / BITMAP_BITS) > b->top)
|
||||
return 0;
|
||||
return (b->d[n / BITMAP_BITS] >> (n & BITMAP_WMASK)) & 1;
|
||||
}
|
||||
|
||||
static int
|
||||
reserve(struct bitmap *b, u_int n)
|
||||
{
|
||||
BITMAP_WTYPE *tmp;
|
||||
size_t nlen;
|
||||
|
||||
if (b->top >= b->len || n > BITMAP_MAX)
|
||||
return -1; /* invalid */
|
||||
nlen = (n / BITMAP_BITS) + 1;
|
||||
if (b->len < nlen) {
|
||||
if ((tmp = recallocarray(b->d, b->len,
|
||||
nlen, BITMAP_BYTES)) == NULL)
|
||||
return -1;
|
||||
b->d = tmp;
|
||||
b->len = nlen;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
bitmap_set_bit(struct bitmap *b, u_int n)
|
||||
{
|
||||
int r;
|
||||
size_t offset;
|
||||
|
||||
if ((r = reserve(b, n)) != 0)
|
||||
return r;
|
||||
offset = n / BITMAP_BITS;
|
||||
if (offset > b->top)
|
||||
b->top = offset;
|
||||
b->d[offset] |= (BITMAP_WTYPE)1 << (n & BITMAP_WMASK);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Resets b->top to point to the most significant bit set in b->d */
|
||||
static void
|
||||
retop(struct bitmap *b)
|
||||
{
|
||||
if (b->top >= b->len)
|
||||
return;
|
||||
while (b->top > 0 && b->d[b->top] == 0)
|
||||
b->top--;
|
||||
}
|
||||
|
||||
void
|
||||
bitmap_clear_bit(struct bitmap *b, u_int n)
|
||||
{
|
||||
size_t offset;
|
||||
|
||||
if (b->top >= b->len || n > BITMAP_MAX)
|
||||
return; /* invalid */
|
||||
offset = n / BITMAP_BITS;
|
||||
if (offset > b->top)
|
||||
return;
|
||||
b->d[offset] &= ~((BITMAP_WTYPE)1 << (n & BITMAP_WMASK));
|
||||
/* The top may have changed as a result of the clear */
|
||||
retop(b);
|
||||
}
|
||||
|
||||
size_t
|
||||
bitmap_nbits(struct bitmap *b)
|
||||
{
|
||||
size_t bits;
|
||||
BITMAP_WTYPE w;
|
||||
|
||||
retop(b);
|
||||
if (b->top >= b->len)
|
||||
return 0; /* invalid */
|
||||
if (b->len == 0 || (b->top == 0 && b->d[0] == 0))
|
||||
return 0;
|
||||
/* Find MSB set */
|
||||
w = b->d[b->top];
|
||||
bits = (b->top + 1) * BITMAP_BITS;
|
||||
while (!(w & ((BITMAP_WTYPE)1 << (BITMAP_BITS - 1)))) {
|
||||
w <<= 1;
|
||||
bits--;
|
||||
}
|
||||
return bits;
|
||||
}
|
||||
|
||||
size_t
|
||||
bitmap_nbytes(struct bitmap *b)
|
||||
{
|
||||
return (bitmap_nbits(b) + 7) / 8;
|
||||
}
|
||||
|
||||
int
|
||||
bitmap_to_string(struct bitmap *b, void *p, size_t l)
|
||||
{
|
||||
u_char *s = (u_char *)p;
|
||||
size_t i, j, k, need = bitmap_nbytes(b);
|
||||
|
||||
if (l < need || b->top >= b->len)
|
||||
return -1;
|
||||
if (l > need)
|
||||
l = need;
|
||||
/* Put the bytes from LSB backwards */
|
||||
for (i = k = 0; i < b->top + 1; i++) {
|
||||
for (j = 0; j < BITMAP_BYTES; j++) {
|
||||
if (k >= l)
|
||||
break;
|
||||
s[need - 1 - k++] = (b->d[i] >> (j * 8)) & 0xff;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
bitmap_from_string(struct bitmap *b, const void *p, size_t l)
|
||||
{
|
||||
int r;
|
||||
size_t i, offset, shift;
|
||||
const u_char *s = (const u_char *)p;
|
||||
|
||||
if (l > BITMAP_MAX / 8)
|
||||
return -1;
|
||||
if ((r = reserve(b, l * 8)) != 0)
|
||||
return r;
|
||||
bitmap_zero(b);
|
||||
if (l == 0)
|
||||
return 0;
|
||||
b->top = offset = ((l + (BITMAP_BYTES - 1)) / BITMAP_BYTES) - 1;
|
||||
shift = ((l + (BITMAP_BYTES - 1)) % BITMAP_BYTES) * 8;
|
||||
for (i = 0; i < l; i++) {
|
||||
b->d[offset] |= (BITMAP_WTYPE)s[i] << shift;
|
||||
if (shift == 0) {
|
||||
offset--;
|
||||
shift = BITMAP_BITS - 8;
|
||||
} else
|
||||
shift -= 8;
|
||||
}
|
||||
retop(b);
|
||||
return 0;
|
||||
}
|
57
bitmap.h
Normal file
57
bitmap.h
Normal file
|
@ -0,0 +1,57 @@
|
|||
/* $OpenBSD: bitmap.h,v 1.2 2017/10/20 01:56:39 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2015 Damien Miller <djm@mindrot.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _BITMAP_H
|
||||
#define _BITMAP_H
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
/* Simple bit vector routines */
|
||||
|
||||
struct bitmap;
|
||||
|
||||
/* Allocate a new bitmap. Returns NULL on allocation failure. */
|
||||
struct bitmap *bitmap_new(void);
|
||||
|
||||
/* Free a bitmap */
|
||||
void bitmap_free(struct bitmap *b);
|
||||
|
||||
/* Zero an existing bitmap */
|
||||
void bitmap_zero(struct bitmap *b);
|
||||
|
||||
/* Test whether a bit is set in a bitmap. */
|
||||
int bitmap_test_bit(struct bitmap *b, u_int n);
|
||||
|
||||
/* Set a bit in a bitmap. Returns 0 on success or -1 on error */
|
||||
int bitmap_set_bit(struct bitmap *b, u_int n);
|
||||
|
||||
/* Clear a bit in a bitmap */
|
||||
void bitmap_clear_bit(struct bitmap *b, u_int n);
|
||||
|
||||
/* Return the number of bits in a bitmap (i.e. the position of the MSB) */
|
||||
size_t bitmap_nbits(struct bitmap *b);
|
||||
|
||||
/* Return the number of bytes needed to represent a bitmap */
|
||||
size_t bitmap_nbytes(struct bitmap *b);
|
||||
|
||||
/* Convert a bitmap to a big endian byte string */
|
||||
int bitmap_to_string(struct bitmap *b, void *p, size_t l);
|
||||
|
||||
/* Convert a big endian byte string to a bitmap */
|
||||
int bitmap_from_string(struct bitmap *b, const void *p, size_t l);
|
||||
|
||||
#endif /* _BITMAP_H */
|
677
buildpkg.sh.in
Normal file
677
buildpkg.sh.in
Normal file
|
@ -0,0 +1,677 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# Fake Root Solaris/SVR4/SVR5 Build System - Prototype
|
||||
#
|
||||
# The following code has been provide under Public Domain License. I really
|
||||
# don't care what you use it for. Just as long as you don't complain to me
|
||||
# nor my employer if you break it. - Ben Lindstrom (mouring@eviladmin.org)
|
||||
#
|
||||
umask 022
|
||||
#
|
||||
# Options for building the package
|
||||
# You can create a openssh-config.local with your customized options
|
||||
#
|
||||
REMOVE_FAKE_ROOT_WHEN_DONE=yes
|
||||
#
|
||||
# uncommenting TEST_DIR and using
|
||||
# configure --prefix=/var/tmp --with-privsep-path=/var/tmp/empty
|
||||
# and
|
||||
# PKGNAME=tOpenSSH should allow testing a package without interfering
|
||||
# with a real OpenSSH package on a system. This is not needed on systems
|
||||
# that support the -R option to pkgadd.
|
||||
#TEST_DIR=/var/tmp # leave commented out for production build
|
||||
PKGNAME=OpenSSH
|
||||
# revisions within the same version (REV=a)
|
||||
#REV=
|
||||
SYSVINIT_NAME=opensshd
|
||||
AWK=${AWK:="nawk"}
|
||||
MAKE=${MAKE:="make"}
|
||||
SSHDUID=67 # Default privsep uid
|
||||
SSHDGID=67 # Default privsep gid
|
||||
# uncomment these next three as needed
|
||||
#PERMIT_ROOT_LOGIN=no
|
||||
#X11_FORWARDING=yes
|
||||
#USR_LOCAL_IS_SYMLINK=yes
|
||||
# System V init run levels
|
||||
SYSVINITSTART=S98
|
||||
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
|
||||
# We'll be one level deeper looking for these
|
||||
PKG_PREINSTALL_LOCAL=../pkg-preinstall.local
|
||||
PKG_POSTINSTALL_LOCAL=../pkg-postinstall.local
|
||||
PKG_PREREMOVE_LOCAL=../pkg-preremove.local
|
||||
PKG_POSTREMOVE_LOCAL=../pkg-postremove.local
|
||||
PKG_REQUEST_LOCAL=../pkg-request.local
|
||||
# end of sourced files
|
||||
#
|
||||
OPENSSHD=opensshd.init
|
||||
OPENSSH_MANIFEST=openssh.xml
|
||||
OPENSSH_FMRI=svc:/site/${SYSVINIT_NAME}:default
|
||||
SMF_METHOD_DIR=/lib/svc/method/site
|
||||
SMF_MANIFEST_DIR=/var/svc/manifest/site
|
||||
|
||||
PATH_GROUPADD_PROG=@PATH_GROUPADD_PROG@
|
||||
PATH_USERADD_PROG=@PATH_USERADD_PROG@
|
||||
PATH_PASSWD_PROG=@PATH_PASSWD_PROG@
|
||||
#
|
||||
# list of system directories we do NOT want to change owner/group/perms
|
||||
# when installing our package
|
||||
SYSTEM_DIR="/etc \
|
||||
/etc/init.d \
|
||||
/etc/rcS.d \
|
||||
/etc/rc0.d \
|
||||
/etc/rc1.d \
|
||||
/etc/rc2.d \
|
||||
/etc/opt \
|
||||
/lib \
|
||||
/lib/svc \
|
||||
/lib/svc/method \
|
||||
/lib/svc/method/site \
|
||||
/opt \
|
||||
/opt/bin \
|
||||
/usr \
|
||||
/usr/bin \
|
||||
/usr/lib \
|
||||
/usr/sbin \
|
||||
/usr/share \
|
||||
/usr/share/man \
|
||||
/usr/share/man/man1 \
|
||||
/usr/share/man/man8 \
|
||||
/usr/local \
|
||||
/usr/local/bin \
|
||||
/usr/local/etc \
|
||||
/usr/local/libexec \
|
||||
/usr/local/man \
|
||||
/usr/local/man/man1 \
|
||||
/usr/local/man/man8 \
|
||||
/usr/local/sbin \
|
||||
/usr/local/share \
|
||||
/var \
|
||||
/var/opt \
|
||||
/var/run \
|
||||
/var/svc \
|
||||
/var/svc/manifest \
|
||||
/var/svc/manifest/site \
|
||||
/var/tmp \
|
||||
/tmp"
|
||||
|
||||
# We may need to build as root so we make sure PATH is set up
|
||||
# only set the path if it's not set already
|
||||
[ -d /opt/bin ] && {
|
||||
echo $PATH | grep ":/opt/bin" > /dev/null 2>&1
|
||||
[ $? -ne 0 ] && PATH=$PATH:/opt/bin
|
||||
}
|
||||
[ -d /usr/local/bin ] && {
|
||||
echo $PATH | grep ":/usr/local/bin" > /dev/null 2>&1
|
||||
[ $? -ne 0 ] && PATH=$PATH:/usr/local/bin
|
||||
}
|
||||
[ -d /usr/ccs/bin ] && {
|
||||
echo $PATH | grep ":/usr/ccs/bin" > /dev/null 2>&1
|
||||
[ $? -ne 0 ] && PATH=$PATH:/usr/ccs/bin
|
||||
}
|
||||
export PATH
|
||||
#
|
||||
|
||||
[ -f Makefile ] || {
|
||||
echo "Please run this script from your build directory"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# we will look for openssh-config.local to override the above options
|
||||
[ -s ./openssh-config.local ] && . ./openssh-config.local
|
||||
|
||||
START=`pwd`
|
||||
FAKE_ROOT=$START/pkg
|
||||
|
||||
## Fill in some details, like prefix and sysconfdir
|
||||
for confvar in prefix exec_prefix bindir sbindir libexecdir datadir mandir sysconfdir piddir srcdir
|
||||
do
|
||||
eval $confvar=`grep "^$confvar=" Makefile | cut -d = -f 2`
|
||||
done
|
||||
|
||||
## Are we using Solaris' SMF?
|
||||
DO_SMF=0
|
||||
if egrep "^#define USE_SOLARIS_PROCESS_CONTRACTS" config.h > /dev/null 2>&1
|
||||
then
|
||||
DO_SMF=1
|
||||
fi
|
||||
|
||||
## Collect value of privsep user
|
||||
for confvar in SSH_PRIVSEP_USER
|
||||
do
|
||||
eval $confvar=`awk '/#define[ \t]'$confvar'/{print $3}' config.h`
|
||||
done
|
||||
|
||||
## Set privsep defaults if not defined
|
||||
if [ -z "$SSH_PRIVSEP_USER" ]
|
||||
then
|
||||
SSH_PRIVSEP_USER=sshd
|
||||
fi
|
||||
|
||||
## Extract common info requires for the 'info' part of the package.
|
||||
VERSION=`./ssh -V 2>&1 | sed -e 's/,.*//'`
|
||||
|
||||
ARCH=`uname -m`
|
||||
DEF_MSG="\n"
|
||||
OS_VER=`uname -v`
|
||||
SCRIPT_SHELL=/sbin/sh
|
||||
UNAME_R=`uname -r`
|
||||
UNAME_S=`uname -s`
|
||||
case ${UNAME_S} in
|
||||
SunOS) UNAME_S=Solaris
|
||||
OS_VER=${UNAME_R}
|
||||
ARCH=`uname -p`
|
||||
RCS_D=yes
|
||||
DEF_MSG="(default: n)"
|
||||
;;
|
||||
SCO_SV) case ${UNAME_R} in
|
||||
3.2) UNAME_S=OpenServer5
|
||||
OS_VER=`uname -X | grep Release | sed -e 's/^Rel.*3.2v//'`
|
||||
;;
|
||||
5) UNAME_S=OpenServer6
|
||||
;;
|
||||
esac
|
||||
SCRIPT_SHELL=/bin/sh
|
||||
RC1_D=no
|
||||
DEF_MSG="(default: n)"
|
||||
;;
|
||||
esac
|
||||
|
||||
case `basename $0` in
|
||||
buildpkg.sh)
|
||||
## Start by faking root install
|
||||
echo "Faking root install..."
|
||||
[ -d $FAKE_ROOT ] && rm -fr $FAKE_ROOT
|
||||
mkdir $FAKE_ROOT
|
||||
${MAKE} install-nokeys DESTDIR=$FAKE_ROOT
|
||||
if [ $? -gt 0 ]
|
||||
then
|
||||
echo "Fake root install failed, stopping."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
## Setup our run level stuff while we are at it.
|
||||
if [ $DO_SMF -eq 1 ]
|
||||
then
|
||||
# For Solaris' SMF, /lib/svc/method/site is the preferred place
|
||||
# for start/stop scripts that aren't supplied with the OS, and
|
||||
# similarly /var/svc/manifest/site for manifests.
|
||||
mkdir -p $FAKE_ROOT${TEST_DIR}${SMF_METHOD_DIR}
|
||||
mkdir -p $FAKE_ROOT${TEST_DIR}${SMF_MANIFEST_DIR}
|
||||
|
||||
cp ${OPENSSHD} $FAKE_ROOT${TEST_DIR}${SMF_METHOD_DIR}/${SYSVINIT_NAME}
|
||||
chmod 744 $FAKE_ROOT${TEST_DIR}${SMF_METHOD_DIR}/${SYSVINIT_NAME}
|
||||
|
||||
cat ${OPENSSH_MANIFEST} | \
|
||||
sed -e "s|__SYSVINIT_NAME__|${SYSVINIT_NAME}|" \
|
||||
-e "s|__SMF_METHOD_DIR__|${SMF_METHOD_DIR}|" \
|
||||
> $FAKE_ROOT${TEST_DIR}${SMF_MANIFEST_DIR}/${SYSVINIT_NAME}.xml
|
||||
chmod 644 $FAKE_ROOT${TEST_DIR}${SMF_MANIFEST_DIR}/${SYSVINIT_NAME}.xml
|
||||
else
|
||||
mkdir -p $FAKE_ROOT${TEST_DIR}/etc/init.d
|
||||
|
||||
cp ${OPENSSHD} $FAKE_ROOT${TEST_DIR}/etc/init.d/${SYSVINIT_NAME}
|
||||
chmod 744 $FAKE_ROOT${TEST_DIR}/etc/init.d/${SYSVINIT_NAME}
|
||||
fi
|
||||
|
||||
[ "${PERMIT_ROOT_LOGIN}" = no ] && \
|
||||
perl -p -i -e "s/#PermitRootLogin yes/PermitRootLogin no/" \
|
||||
$FAKE_ROOT${sysconfdir}/sshd_config
|
||||
[ "${X11_FORWARDING}" = yes ] && \
|
||||
perl -p -i -e "s/#X11Forwarding no/X11Forwarding yes/" \
|
||||
$FAKE_ROOT${sysconfdir}/sshd_config
|
||||
# fix PrintMotd
|
||||
perl -p -i -e "s/#PrintMotd yes/PrintMotd no/" \
|
||||
$FAKE_ROOT${sysconfdir}/sshd_config
|
||||
|
||||
# We don't want to overwrite config files on multiple installs
|
||||
mv $FAKE_ROOT${sysconfdir}/ssh_config $FAKE_ROOT${sysconfdir}/ssh_config.default
|
||||
mv $FAKE_ROOT${sysconfdir}/sshd_config $FAKE_ROOT${sysconfdir}/sshd_config.default
|
||||
|
||||
# local tweeks here
|
||||
[ -s "${POST_MAKE_INSTALL_FIXES}" ] && . ${POST_MAKE_INSTALL_FIXES}
|
||||
|
||||
cd $FAKE_ROOT
|
||||
|
||||
## Ok, this is outright wrong, but it will work. I'm tired of pkgmk
|
||||
## whining.
|
||||
for i in *; do
|
||||
PROTO_ARGS="$PROTO_ARGS $i=/$i";
|
||||
done
|
||||
|
||||
## Build info file
|
||||
echo "Building pkginfo file..."
|
||||
cat > pkginfo << _EOF
|
||||
PKG=$PKGNAME
|
||||
NAME="OpenSSH Portable for ${UNAME_S}"
|
||||
DESC="Secure Shell remote access utility; replaces telnet and rlogin/rsh."
|
||||
VENDOR="OpenSSH Portable Team - https://www.openssh.com/portable.html"
|
||||
ARCH=$ARCH
|
||||
VERSION=$VERSION$REV
|
||||
CATEGORY="Security,application"
|
||||
BASEDIR=/
|
||||
CLASSES="none"
|
||||
PSTAMP="${UNAME_S} ${OS_VER} ${ARCH} `date '+%d%b%Y %H:%M'`"
|
||||
_EOF
|
||||
|
||||
## Build empty depend file that may get updated by $POST_PROTOTYPE_EDITS
|
||||
echo "Building depend file..."
|
||||
touch depend
|
||||
|
||||
## Build space file
|
||||
echo "Building space file..."
|
||||
if [ $DO_SMF -eq 1 ]
|
||||
then
|
||||
# XXX Is this necessary? If not, remove space line from mk-proto.awk.
|
||||
touch space
|
||||
else
|
||||
cat > space << _EOF
|
||||
# extra space required by start/stop links added by installf
|
||||
# in postinstall
|
||||
$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/${SYSVINITSTOP}${SYSVINIT_NAME} 0 1" >> space
|
||||
[ "$RCS_D" = yes ] && \
|
||||
echo "$TEST_DIR/etc/rcS.d/${SYSVINITSTOP}${SYSVINIT_NAME} 0 1" >> space
|
||||
fi
|
||||
|
||||
## Build preinstall file
|
||||
echo "Building preinstall file..."
|
||||
cat > preinstall << _EOF
|
||||
#! ${SCRIPT_SHELL}
|
||||
#
|
||||
_EOF
|
||||
|
||||
# local preinstall changes here
|
||||
[ -s "${PKG_PREINSTALL_LOCAL}" ] && . ${PKG_PREINSTALL_LOCAL}
|
||||
|
||||
cat >> preinstall << _EOF
|
||||
#
|
||||
if [ "\${PRE_INS_STOP}" = "yes" ]
|
||||
then
|
||||
if [ $DO_SMF -eq 1 ]
|
||||
then
|
||||
svcadm disable $OPENSSH_FMRI
|
||||
else
|
||||
${TEST_DIR}/etc/init.d/${SYSVINIT_NAME} stop
|
||||
fi
|
||||
fi
|
||||
|
||||
exit 0
|
||||
_EOF
|
||||
|
||||
## Build postinstall file
|
||||
echo "Building postinstall file..."
|
||||
cat > postinstall << _EOF
|
||||
#! ${SCRIPT_SHELL}
|
||||
#
|
||||
[ -f \${PKG_INSTALL_ROOT}${sysconfdir}/ssh_config ] || \\
|
||||
cp -p \${PKG_INSTALL_ROOT}${sysconfdir}/ssh_config.default \\
|
||||
\${PKG_INSTALL_ROOT}${sysconfdir}/ssh_config
|
||||
[ -f \${PKG_INSTALL_ROOT}${sysconfdir}/sshd_config ] || \\
|
||||
cp -p \${PKG_INSTALL_ROOT}${sysconfdir}/sshd_config.default \\
|
||||
\${PKG_INSTALL_ROOT}${sysconfdir}/sshd_config
|
||||
|
||||
# make rc?.d dirs only if we are doing a test install
|
||||
[ -n "${TEST_DIR}" ] && [ $DO_SMF -ne 1 ] && {
|
||||
[ "$RCS_D" = yes ] && mkdir -p ${TEST_DIR}/etc/rcS.d
|
||||
mkdir -p ${TEST_DIR}/etc/rc0.d
|
||||
[ "$RC1_D" = no ] || mkdir -p ${TEST_DIR}/etc/rc1.d
|
||||
mkdir -p ${TEST_DIR}/etc/rc2.d
|
||||
}
|
||||
|
||||
if [ $DO_SMF -eq 1 ]
|
||||
then
|
||||
# Delete the existing service, if it exists, then import the
|
||||
# new one.
|
||||
if svcs $OPENSSH_FMRI > /dev/null 2>&1
|
||||
then
|
||||
svccfg delete -f $OPENSSH_FMRI
|
||||
fi
|
||||
# NOTE, The manifest disables sshd by default.
|
||||
svccfg import ${TEST_DIR}${SMF_MANIFEST_DIR}/${SYSVINIT_NAME}.xml
|
||||
else
|
||||
if [ "\${USE_SYM_LINKS}" = yes ]
|
||||
then
|
||||
[ "$RCS_D" = yes ] && \\
|
||||
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/${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/${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/${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
|
||||
|
||||
# If piddir doesn't exist we add it. (Ie. --with-pid-dir=/var/opt/ssh)
|
||||
[ -d $piddir ] || installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR$piddir d 0755 root sys
|
||||
|
||||
_EOF
|
||||
|
||||
# local postinstall changes here
|
||||
[ -s "${PKG_POSTINSTALL_LOCAL}" ] && . ${PKG_POSTINSTALL_LOCAL}
|
||||
|
||||
cat >> postinstall << _EOF
|
||||
installf -f ${PKGNAME}
|
||||
|
||||
# Use chroot to handle PKG_INSTALL_ROOT
|
||||
if [ ! -z "\${PKG_INSTALL_ROOT}" ]
|
||||
then
|
||||
chroot="chroot \${PKG_INSTALL_ROOT}"
|
||||
fi
|
||||
# If this is a test build, we will skip the groupadd/useradd/passwd commands
|
||||
if [ ! -z "${TEST_DIR}" ]
|
||||
then
|
||||
chroot=echo
|
||||
fi
|
||||
|
||||
echo "PrivilegeSeparation user always required."
|
||||
if cut -f1 -d: \${PKG_INSTALL_ROOT}/etc/passwd | egrep '^'$SSH_PRIVSEP_USER'\$' >/dev/null
|
||||
then
|
||||
echo "PrivSep user $SSH_PRIVSEP_USER already exists."
|
||||
SSH_PRIVSEP_GROUP=\`grep "^$SSH_PRIVSEP_USER:" \${PKG_INSTALL_ROOT}/etc/passwd | awk -F: '{print \$4}'\`
|
||||
SSH_PRIVSEP_GROUP=\`grep ":\$SSH_PRIVSEP_GROUP:" \${PKG_INSTALL_ROOT}/etc/group | awk -F: '{print \$1}'\`
|
||||
else
|
||||
DO_PASSWD=yes
|
||||
fi
|
||||
[ -z "\$SSH_PRIVSEP_GROUP" ] && SSH_PRIVSEP_GROUP=$SSH_PRIVSEP_USER
|
||||
|
||||
# group required?
|
||||
if cut -f1 -d: \${PKG_INSTALL_ROOT}/etc/group | egrep '^'\$SSH_PRIVSEP_GROUP'\$' >/dev/null
|
||||
then
|
||||
echo "PrivSep group \$SSH_PRIVSEP_GROUP already exists."
|
||||
else
|
||||
DO_GROUP=yes
|
||||
fi
|
||||
|
||||
# create group if required
|
||||
[ "\$DO_GROUP" = yes ] && {
|
||||
# Use gid of 67 if possible
|
||||
if cut -f3 -d: \${PKG_INSTALL_ROOT}/etc/group | egrep '^'$SSHDGID'\$' >/dev/null
|
||||
then
|
||||
:
|
||||
else
|
||||
sshdgid="-g $SSHDGID"
|
||||
fi
|
||||
echo "Creating PrivSep group \$SSH_PRIVSEP_GROUP."
|
||||
\$chroot ${PATH_GROUPADD_PROG} \$sshdgid \$SSH_PRIVSEP_GROUP
|
||||
}
|
||||
|
||||
# Create user if required
|
||||
[ "\$DO_PASSWD" = yes ] && {
|
||||
# Use uid of 67 if possible
|
||||
if cut -f3 -d: \${PKG_INSTALL_ROOT}/etc/passwd | egrep '^'$SSHDUID'\$' >/dev/null
|
||||
then
|
||||
:
|
||||
else
|
||||
sshduid="-u $SSHDUID"
|
||||
fi
|
||||
echo "Creating PrivSep user $SSH_PRIVSEP_USER."
|
||||
\$chroot ${PATH_USERADD_PROG} -c 'SSHD PrivSep User' -s /bin/false -g $SSH_PRIVSEP_USER \$sshduid $SSH_PRIVSEP_USER
|
||||
\$chroot ${PATH_PASSWD_PROG} -l $SSH_PRIVSEP_USER
|
||||
}
|
||||
|
||||
if [ "\${POST_INS_START}" = "yes" ]
|
||||
then
|
||||
if [ $DO_SMF -eq 1 ]
|
||||
then
|
||||
svcadm enable $OPENSSH_FMRI
|
||||
else
|
||||
${TEST_DIR}/etc/init.d/${SYSVINIT_NAME} start
|
||||
fi
|
||||
fi
|
||||
exit 0
|
||||
_EOF
|
||||
|
||||
## Build preremove file
|
||||
echo "Building preremove file..."
|
||||
cat > preremove << _EOF
|
||||
#! ${SCRIPT_SHELL}
|
||||
#
|
||||
if [ $DO_SMF -eq 1 ]
|
||||
then
|
||||
svcadm disable $OPENSSH_FMRI
|
||||
else
|
||||
${TEST_DIR}/etc/init.d/${SYSVINIT_NAME} stop
|
||||
fi
|
||||
_EOF
|
||||
|
||||
# local preremove changes here
|
||||
[ -s "${PKG_PREREMOVE_LOCAL}" ] && . ${PKG_PREREMOVE_LOCAL}
|
||||
|
||||
cat >> preremove << _EOF
|
||||
exit 0
|
||||
_EOF
|
||||
|
||||
## Build postremove file
|
||||
echo "Building postremove file..."
|
||||
cat > postremove << _EOF
|
||||
#! ${SCRIPT_SHELL}
|
||||
#
|
||||
if [ $DO_SMF -eq 1 ]
|
||||
then
|
||||
if svcs $OPENSSH_FMRI > /dev/null 2>&1
|
||||
then
|
||||
svccfg delete -f $OPENSSH_FMRI
|
||||
fi
|
||||
fi
|
||||
_EOF
|
||||
|
||||
# local postremove changes here
|
||||
[ -s "${PKG_POSTREMOVE_LOCAL}" ] && . ${PKG_POSTREMOVE_LOCAL}
|
||||
|
||||
cat >> postremove << _EOF
|
||||
exit 0
|
||||
_EOF
|
||||
|
||||
## Build request file
|
||||
echo "Building request file..."
|
||||
cat > request << _EOF
|
||||
trap 'exit 3' 15
|
||||
|
||||
_EOF
|
||||
|
||||
[ -x /usr/bin/ckyorn ] || cat >> request << _EOF
|
||||
|
||||
ckyorn() {
|
||||
# for some strange reason OpenServer5 has no ckyorn
|
||||
# We build a striped down version here
|
||||
|
||||
DEFAULT=n
|
||||
PROMPT="Yes or No [yes,no,?,quit]"
|
||||
HELP_PROMPT=" Enter y or yes if your answer is yes; n or no if your answer is no."
|
||||
USAGE="usage: ckyorn [options]
|
||||
where options may include:
|
||||
-d default
|
||||
-h help
|
||||
-p prompt
|
||||
"
|
||||
|
||||
if [ \$# != 0 ]
|
||||
then
|
||||
while getopts d:p:h: c
|
||||
do
|
||||
case \$c in
|
||||
h) HELP_PROMPT="\$OPTARG" ;;
|
||||
d) DEFAULT=\$OPTARG ;;
|
||||
p) PROMPT=\$OPTARG ;;
|
||||
\\?) echo "\$USAGE" 1>&2
|
||||
exit 1 ;;
|
||||
esac
|
||||
done
|
||||
shift \`expr \$OPTIND - 1\`
|
||||
fi
|
||||
|
||||
while true
|
||||
do
|
||||
echo "\${PROMPT}\\c " 1>&2
|
||||
read key
|
||||
[ -z "\$key" ] && key=\$DEFAULT
|
||||
case \$key in
|
||||
[n,N]|[n,N][o,O]|[y,Y]|[y,Y][e,E][s,S]) echo "\${key}\\c"
|
||||
exit 0 ;;
|
||||
\\?) echo \$HELP_PROMPT 1>&2 ;;
|
||||
q|quit) echo "q\\c" 1>&2
|
||||
exit 3 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
}
|
||||
|
||||
_EOF
|
||||
|
||||
if [ $DO_SMF -eq 1 ]
|
||||
then
|
||||
# This could get hairy, as the running sshd may not be under SMF.
|
||||
# We'll assume an earlier version of OpenSSH started via SMF.
|
||||
cat >> request << _EOF
|
||||
PRE_INS_STOP=no
|
||||
POST_INS_START=no
|
||||
# determine if should restart the daemon
|
||||
if [ -s ${piddir}/sshd.pid ] && \\
|
||||
/usr/bin/svcs -H $OPENSSH_FMRI 2>&1 | egrep "^online" > /dev/null 2>&1
|
||||
then
|
||||
ans=\`ckyorn -d n \\
|
||||
-p "Should the running sshd daemon be restarted? ${DEF_MSG}"\` || exit \$?
|
||||
case \$ans in
|
||||
[y,Y]*) PRE_INS_STOP=yes
|
||||
POST_INS_START=yes
|
||||
;;
|
||||
esac
|
||||
|
||||
else
|
||||
|
||||
# determine if we should start sshd
|
||||
ans=\`ckyorn -d n \\
|
||||
-p "Start the sshd daemon after installing this package? ${DEF_MSG}"\` || exit \$?
|
||||
case \$ans in
|
||||
[y,Y]*) POST_INS_START=yes ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# make parameters available to installation service,
|
||||
# and so to any other packaging scripts
|
||||
cat >\$1 <<!
|
||||
PRE_INS_STOP='\$PRE_INS_STOP'
|
||||
POST_INS_START='\$POST_INS_START'
|
||||
!
|
||||
|
||||
_EOF
|
||||
else
|
||||
cat >> request << _EOF
|
||||
USE_SYM_LINKS=no
|
||||
PRE_INS_STOP=no
|
||||
POST_INS_START=no
|
||||
# Use symbolic links?
|
||||
ans=\`ckyorn -d n \\
|
||||
-p "Do you want symbolic links for the start/stop scripts? ${DEF_MSG}"\` || exit \$?
|
||||
case \$ans in
|
||||
[y,Y]*) USE_SYM_LINKS=yes ;;
|
||||
esac
|
||||
|
||||
# determine if should restart the daemon
|
||||
if [ -s ${piddir}/sshd.pid -a -f ${TEST_DIR}/etc/init.d/${SYSVINIT_NAME} ]
|
||||
then
|
||||
ans=\`ckyorn -d n \\
|
||||
-p "Should the running sshd daemon be restarted? ${DEF_MSG}"\` || exit \$?
|
||||
case \$ans in
|
||||
[y,Y]*) PRE_INS_STOP=yes
|
||||
POST_INS_START=yes
|
||||
;;
|
||||
esac
|
||||
|
||||
else
|
||||
|
||||
# determine if we should start sshd
|
||||
ans=\`ckyorn -d n \\
|
||||
-p "Start the sshd daemon after installing this package? ${DEF_MSG}"\` || exit \$?
|
||||
case \$ans in
|
||||
[y,Y]*) POST_INS_START=yes ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# make parameters available to installation service,
|
||||
# and so to any other packaging scripts
|
||||
cat >\$1 <<!
|
||||
USE_SYM_LINKS='\$USE_SYM_LINKS'
|
||||
PRE_INS_STOP='\$PRE_INS_STOP'
|
||||
POST_INS_START='\$POST_INS_START'
|
||||
!
|
||||
|
||||
_EOF
|
||||
fi
|
||||
|
||||
# local request changes here
|
||||
[ -s "${PKG_REQUEST_LOCAL}" ] && . ${PKG_REQUEST_LOCAL}
|
||||
|
||||
cat >> request << _EOF
|
||||
exit 0
|
||||
|
||||
_EOF
|
||||
|
||||
## Next Build our prototype
|
||||
echo "Building prototype file..."
|
||||
cat >mk-proto.awk << _EOF
|
||||
BEGIN { print "i pkginfo"; print "i depend"; \\
|
||||
print "i preinstall"; print "i postinstall"; \\
|
||||
print "i preremove"; print "i postremove"; \\
|
||||
print "i request"; print "i space"; \\
|
||||
split("$SYSTEM_DIR",sys_files); }
|
||||
{
|
||||
for (dir in sys_files) { if ( \$3 != sys_files[dir] )
|
||||
{ if ( \$1 == "s" )
|
||||
{ \$5=""; \$6=""; }
|
||||
else
|
||||
{ \$5="root"; \$6="sys"; }
|
||||
}
|
||||
else
|
||||
{ \$4="?"; \$5="?"; \$6="?"; break;}
|
||||
} }
|
||||
{ print; }
|
||||
_EOF
|
||||
|
||||
find . | egrep -v "prototype|pkginfo|mk-proto.awk" | sort | \
|
||||
pkgproto $PROTO_ARGS | ${AWK} -f mk-proto.awk > prototype
|
||||
|
||||
# /usr/local is a symlink on some systems
|
||||
[ "${USR_LOCAL_IS_SYMLINK}" = yes ] && {
|
||||
grep -v "^d none /usr/local ? ? ?$" prototype > prototype.new
|
||||
mv prototype.new prototype
|
||||
}
|
||||
|
||||
## Step back a directory and now build the package.
|
||||
cd ..
|
||||
# local prototype tweeks here
|
||||
[ -s "${POST_PROTOTYPE_EDITS}" ] && . ${POST_PROTOTYPE_EDITS}
|
||||
|
||||
echo "Building package.."
|
||||
pkgmk -d ${FAKE_ROOT} -f $FAKE_ROOT/prototype -o
|
||||
echo | pkgtrans -os ${FAKE_ROOT} ${START}/$PKGNAME-$VERSION$REV-$UNAME_S-$ARCH.pkg
|
||||
;;
|
||||
|
||||
justpkg.sh)
|
||||
rm -fr ${FAKE_ROOT}/${PKGNAME}
|
||||
grep -v "^PSTAMP=" $FAKE_ROOT/pkginfo > $$tmp
|
||||
mv $$tmp $FAKE_ROOT/pkginfo
|
||||
cat >> $FAKE_ROOT/pkginfo << _EOF
|
||||
PSTAMP="${UNAME_S} ${OS_VER} ${ARCH} `date '+%d%b%Y %H:%M'`"
|
||||
_EOF
|
||||
pkgmk -d ${FAKE_ROOT} -f $FAKE_ROOT/prototype -o
|
||||
echo | pkgtrans -os ${FAKE_ROOT} ${START}/$PKGNAME-$VERSION$REV-$UNAME_S-$ARCH.pkg
|
||||
;;
|
||||
|
||||
esac
|
||||
|
||||
[ "${REMOVE_FAKE_ROOT_WHEN_DONE}" = yes ] && rm -rf $FAKE_ROOT
|
||||
exit 0
|
||||
|
209
canohost.c
Normal file
209
canohost.c
Normal file
|
@ -0,0 +1,209 @@
|
|||
/* $OpenBSD: canohost.c,v 1.77 2023/03/31 04:42:29 dtucker Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
* All rights reserved
|
||||
* Functions for returning the canonical host name of the remote site.
|
||||
*
|
||||
* As far as I am concerned, the code I have written for this software
|
||||
* can be used freely for any purpose. Any derived versions of this
|
||||
* software must be clearly marked as such, and if the derived work is
|
||||
* incompatible with the protocol description in the RFC file, it must be
|
||||
* called by a name other than "ssh" or "Secure Shell".
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <netdb.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "packet.h"
|
||||
#include "log.h"
|
||||
#include "canohost.h"
|
||||
#include "misc.h"
|
||||
|
||||
void
|
||||
ipv64_normalise_mapped(struct sockaddr_storage *addr, socklen_t *len)
|
||||
{
|
||||
struct sockaddr_in6 *a6 = (struct sockaddr_in6 *)addr;
|
||||
struct sockaddr_in *a4 = (struct sockaddr_in *)addr;
|
||||
struct in_addr inaddr;
|
||||
u_int16_t port;
|
||||
|
||||
if (addr->ss_family != AF_INET6 ||
|
||||
!IN6_IS_ADDR_V4MAPPED(&a6->sin6_addr))
|
||||
return;
|
||||
|
||||
debug3("Normalising mapped IPv4 in IPv6 address");
|
||||
|
||||
memcpy(&inaddr, ((char *)&a6->sin6_addr) + 12, sizeof(inaddr));
|
||||
port = a6->sin6_port;
|
||||
|
||||
memset(a4, 0, sizeof(*a4));
|
||||
|
||||
a4->sin_family = AF_INET;
|
||||
*len = sizeof(*a4);
|
||||
memcpy(&a4->sin_addr, &inaddr, sizeof(inaddr));
|
||||
a4->sin_port = port;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the local/remote IP-address/hostname of socket as a string.
|
||||
* The returned string must be freed.
|
||||
*/
|
||||
static char *
|
||||
get_socket_address(int sock, int remote, int flags)
|
||||
{
|
||||
struct sockaddr_storage addr;
|
||||
socklen_t addrlen;
|
||||
char ntop[NI_MAXHOST];
|
||||
int r;
|
||||
|
||||
if (sock < 0)
|
||||
return NULL;
|
||||
|
||||
/* Get IP address of client. */
|
||||
addrlen = sizeof(addr);
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
|
||||
if (remote) {
|
||||
if (getpeername(sock, (struct sockaddr *)&addr, &addrlen) != 0)
|
||||
return NULL;
|
||||
} else {
|
||||
if (getsockname(sock, (struct sockaddr *)&addr, &addrlen) != 0)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Work around Linux IPv6 weirdness */
|
||||
if (addr.ss_family == AF_INET6) {
|
||||
addrlen = sizeof(struct sockaddr_in6);
|
||||
ipv64_normalise_mapped(&addr, &addrlen);
|
||||
}
|
||||
|
||||
switch (addr.ss_family) {
|
||||
case AF_INET:
|
||||
case AF_INET6:
|
||||
/* Get the address in ascii. */
|
||||
if ((r = getnameinfo((struct sockaddr *)&addr, addrlen, ntop,
|
||||
sizeof(ntop), NULL, 0, flags)) != 0) {
|
||||
error_f("getnameinfo %d failed: %s",
|
||||
flags, ssh_gai_strerror(r));
|
||||
return NULL;
|
||||
}
|
||||
return xstrdup(ntop);
|
||||
case AF_UNIX:
|
||||
/* Get the Unix domain socket path. */
|
||||
return xstrdup(((struct sockaddr_un *)&addr)->sun_path);
|
||||
default:
|
||||
/* We can't look up remote Unix domain sockets. */
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
char *
|
||||
get_peer_ipaddr(int sock)
|
||||
{
|
||||
char *p;
|
||||
|
||||
if ((p = get_socket_address(sock, 1, NI_NUMERICHOST)) != NULL)
|
||||
return p;
|
||||
return xstrdup("UNKNOWN");
|
||||
}
|
||||
|
||||
char *
|
||||
get_local_ipaddr(int sock)
|
||||
{
|
||||
char *p;
|
||||
|
||||
if ((p = get_socket_address(sock, 0, NI_NUMERICHOST)) != NULL)
|
||||
return p;
|
||||
return xstrdup("UNKNOWN");
|
||||
}
|
||||
|
||||
char *
|
||||
get_local_name(int fd)
|
||||
{
|
||||
char *host, myname[NI_MAXHOST];
|
||||
|
||||
/* Assume we were passed a socket */
|
||||
if ((host = get_socket_address(fd, 0, NI_NAMEREQD)) != NULL)
|
||||
return host;
|
||||
|
||||
/* Handle the case where we were passed a pipe */
|
||||
if (gethostname(myname, sizeof(myname)) == -1) {
|
||||
verbose_f("gethostname: %s", strerror(errno));
|
||||
host = xstrdup("UNKNOWN");
|
||||
} else {
|
||||
host = xstrdup(myname);
|
||||
}
|
||||
|
||||
return host;
|
||||
}
|
||||
|
||||
/* Returns the local/remote port for the socket. */
|
||||
|
||||
static int
|
||||
get_sock_port(int sock, int local)
|
||||
{
|
||||
struct sockaddr_storage from;
|
||||
socklen_t fromlen;
|
||||
char strport[NI_MAXSERV];
|
||||
int r;
|
||||
|
||||
if (sock < 0)
|
||||
return -1;
|
||||
/* Get IP address of client. */
|
||||
fromlen = sizeof(from);
|
||||
memset(&from, 0, sizeof(from));
|
||||
if (local) {
|
||||
if (getsockname(sock, (struct sockaddr *)&from, &fromlen) == -1) {
|
||||
error("getsockname failed: %.100s", strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
if (getpeername(sock, (struct sockaddr *)&from, &fromlen) == -1) {
|
||||
debug("getpeername failed: %.100s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Work around Linux IPv6 weirdness */
|
||||
if (from.ss_family == AF_INET6)
|
||||
fromlen = sizeof(struct sockaddr_in6);
|
||||
|
||||
/* Non-inet sockets don't have a port number. */
|
||||
if (from.ss_family != AF_INET && from.ss_family != AF_INET6)
|
||||
return 0;
|
||||
|
||||
/* Return port number. */
|
||||
if ((r = getnameinfo((struct sockaddr *)&from, fromlen, NULL, 0,
|
||||
strport, sizeof(strport), NI_NUMERICSERV)) != 0)
|
||||
fatal_f("getnameinfo NI_NUMERICSERV failed: %s",
|
||||
ssh_gai_strerror(r));
|
||||
return atoi(strport);
|
||||
}
|
||||
|
||||
int
|
||||
get_peer_port(int sock)
|
||||
{
|
||||
return get_sock_port(sock, 0);
|
||||
}
|
||||
|
||||
int
|
||||
get_local_port(int sock)
|
||||
{
|
||||
return get_sock_port(sock, 1);
|
||||
}
|
26
canohost.h
Normal file
26
canohost.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
/* $OpenBSD: canohost.h,v 1.12 2016/03/07 19:02:43 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
* All rights reserved
|
||||
*
|
||||
* As far as I am concerned, the code I have written for this software
|
||||
* can be used freely for any purpose. Any derived versions of this
|
||||
* software must be clearly marked as such, and if the derived work is
|
||||
* incompatible with the protocol description in the RFC file, it must be
|
||||
* called by a name other than "ssh" or "Secure Shell".
|
||||
*/
|
||||
|
||||
#ifndef _CANOHOST_H
|
||||
#define _CANOHOST_H
|
||||
|
||||
char *get_peer_ipaddr(int);
|
||||
int get_peer_port(int);
|
||||
char *get_local_ipaddr(int);
|
||||
char *get_local_name(int);
|
||||
int get_local_port(int);
|
||||
|
||||
#endif /* _CANOHOST_H */
|
||||
|
||||
void ipv64_normalise_mapped(struct sockaddr_storage *, socklen_t *);
|
218
chacha.c
Normal file
218
chacha.c
Normal file
|
@ -0,0 +1,218 @@
|
|||
/* $OpenBSD: chacha.c,v 1.2 2023/07/17 05:26:38 djm Exp $ */
|
||||
/*
|
||||
chacha-merged.c version 20080118
|
||||
D. J. Bernstein
|
||||
Public domain.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include "chacha.h"
|
||||
|
||||
typedef unsigned char u8;
|
||||
typedef unsigned int u32;
|
||||
|
||||
typedef struct chacha_ctx chacha_ctx;
|
||||
|
||||
#define U8C(v) (v##U)
|
||||
#define U32C(v) (v##U)
|
||||
|
||||
#define U8V(v) ((u8)(v) & U8C(0xFF))
|
||||
#define U32V(v) ((u32)(v) & U32C(0xFFFFFFFF))
|
||||
|
||||
#define ROTL32(v, n) \
|
||||
(U32V((v) << (n)) | ((v) >> (32 - (n))))
|
||||
|
||||
#define U8TO32_LITTLE(p) \
|
||||
(((u32)((p)[0]) ) | \
|
||||
((u32)((p)[1]) << 8) | \
|
||||
((u32)((p)[2]) << 16) | \
|
||||
((u32)((p)[3]) << 24))
|
||||
|
||||
#define U32TO8_LITTLE(p, v) \
|
||||
do { \
|
||||
(p)[0] = U8V((v) ); \
|
||||
(p)[1] = U8V((v) >> 8); \
|
||||
(p)[2] = U8V((v) >> 16); \
|
||||
(p)[3] = U8V((v) >> 24); \
|
||||
} while (0)
|
||||
|
||||
#define ROTATE(v,c) (ROTL32(v,c))
|
||||
#define XOR(v,w) ((v) ^ (w))
|
||||
#define PLUS(v,w) (U32V((v) + (w)))
|
||||
#define PLUSONE(v) (PLUS((v),1))
|
||||
|
||||
#define QUARTERROUND(a,b,c,d) \
|
||||
a = PLUS(a,b); d = ROTATE(XOR(d,a),16); \
|
||||
c = PLUS(c,d); b = ROTATE(XOR(b,c),12); \
|
||||
a = PLUS(a,b); d = ROTATE(XOR(d,a), 8); \
|
||||
c = PLUS(c,d); b = ROTATE(XOR(b,c), 7);
|
||||
|
||||
static const char sigma[16] = "expand 32-byte k";
|
||||
static const char tau[16] = "expand 16-byte k";
|
||||
|
||||
void
|
||||
chacha_keysetup(chacha_ctx *x,const u8 *k,u32 kbits)
|
||||
{
|
||||
const char *constants;
|
||||
|
||||
x->input[4] = U8TO32_LITTLE(k + 0);
|
||||
x->input[5] = U8TO32_LITTLE(k + 4);
|
||||
x->input[6] = U8TO32_LITTLE(k + 8);
|
||||
x->input[7] = U8TO32_LITTLE(k + 12);
|
||||
if (kbits == 256) { /* recommended */
|
||||
k += 16;
|
||||
constants = sigma;
|
||||
} else { /* kbits == 128 */
|
||||
constants = tau;
|
||||
}
|
||||
x->input[8] = U8TO32_LITTLE(k + 0);
|
||||
x->input[9] = U8TO32_LITTLE(k + 4);
|
||||
x->input[10] = U8TO32_LITTLE(k + 8);
|
||||
x->input[11] = U8TO32_LITTLE(k + 12);
|
||||
x->input[0] = U8TO32_LITTLE(constants + 0);
|
||||
x->input[1] = U8TO32_LITTLE(constants + 4);
|
||||
x->input[2] = U8TO32_LITTLE(constants + 8);
|
||||
x->input[3] = U8TO32_LITTLE(constants + 12);
|
||||
}
|
||||
|
||||
void
|
||||
chacha_ivsetup(chacha_ctx *x, const u8 *iv, const u8 *counter)
|
||||
{
|
||||
x->input[12] = counter == NULL ? 0 : U8TO32_LITTLE(counter + 0);
|
||||
x->input[13] = counter == NULL ? 0 : U8TO32_LITTLE(counter + 4);
|
||||
x->input[14] = U8TO32_LITTLE(iv + 0);
|
||||
x->input[15] = U8TO32_LITTLE(iv + 4);
|
||||
}
|
||||
|
||||
void
|
||||
chacha_encrypt_bytes(chacha_ctx *x,const u8 *m,u8 *c,u32 bytes)
|
||||
{
|
||||
u32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15;
|
||||
u32 j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15;
|
||||
u8 *ctarget = NULL;
|
||||
u8 tmp[64];
|
||||
u_int i;
|
||||
|
||||
if (!bytes) return;
|
||||
|
||||
j0 = x->input[0];
|
||||
j1 = x->input[1];
|
||||
j2 = x->input[2];
|
||||
j3 = x->input[3];
|
||||
j4 = x->input[4];
|
||||
j5 = x->input[5];
|
||||
j6 = x->input[6];
|
||||
j7 = x->input[7];
|
||||
j8 = x->input[8];
|
||||
j9 = x->input[9];
|
||||
j10 = x->input[10];
|
||||
j11 = x->input[11];
|
||||
j12 = x->input[12];
|
||||
j13 = x->input[13];
|
||||
j14 = x->input[14];
|
||||
j15 = x->input[15];
|
||||
|
||||
for (;;) {
|
||||
if (bytes < 64) {
|
||||
for (i = 0;i < bytes;++i) tmp[i] = m[i];
|
||||
m = tmp;
|
||||
ctarget = c;
|
||||
c = tmp;
|
||||
}
|
||||
x0 = j0;
|
||||
x1 = j1;
|
||||
x2 = j2;
|
||||
x3 = j3;
|
||||
x4 = j4;
|
||||
x5 = j5;
|
||||
x6 = j6;
|
||||
x7 = j7;
|
||||
x8 = j8;
|
||||
x9 = j9;
|
||||
x10 = j10;
|
||||
x11 = j11;
|
||||
x12 = j12;
|
||||
x13 = j13;
|
||||
x14 = j14;
|
||||
x15 = j15;
|
||||
for (i = 20;i > 0;i -= 2) {
|
||||
QUARTERROUND( x0, x4, x8,x12)
|
||||
QUARTERROUND( x1, x5, x9,x13)
|
||||
QUARTERROUND( x2, x6,x10,x14)
|
||||
QUARTERROUND( x3, x7,x11,x15)
|
||||
QUARTERROUND( x0, x5,x10,x15)
|
||||
QUARTERROUND( x1, x6,x11,x12)
|
||||
QUARTERROUND( x2, x7, x8,x13)
|
||||
QUARTERROUND( x3, x4, x9,x14)
|
||||
}
|
||||
x0 = PLUS(x0,j0);
|
||||
x1 = PLUS(x1,j1);
|
||||
x2 = PLUS(x2,j2);
|
||||
x3 = PLUS(x3,j3);
|
||||
x4 = PLUS(x4,j4);
|
||||
x5 = PLUS(x5,j5);
|
||||
x6 = PLUS(x6,j6);
|
||||
x7 = PLUS(x7,j7);
|
||||
x8 = PLUS(x8,j8);
|
||||
x9 = PLUS(x9,j9);
|
||||
x10 = PLUS(x10,j10);
|
||||
x11 = PLUS(x11,j11);
|
||||
x12 = PLUS(x12,j12);
|
||||
x13 = PLUS(x13,j13);
|
||||
x14 = PLUS(x14,j14);
|
||||
x15 = PLUS(x15,j15);
|
||||
|
||||
x0 = XOR(x0,U8TO32_LITTLE(m + 0));
|
||||
x1 = XOR(x1,U8TO32_LITTLE(m + 4));
|
||||
x2 = XOR(x2,U8TO32_LITTLE(m + 8));
|
||||
x3 = XOR(x3,U8TO32_LITTLE(m + 12));
|
||||
x4 = XOR(x4,U8TO32_LITTLE(m + 16));
|
||||
x5 = XOR(x5,U8TO32_LITTLE(m + 20));
|
||||
x6 = XOR(x6,U8TO32_LITTLE(m + 24));
|
||||
x7 = XOR(x7,U8TO32_LITTLE(m + 28));
|
||||
x8 = XOR(x8,U8TO32_LITTLE(m + 32));
|
||||
x9 = XOR(x9,U8TO32_LITTLE(m + 36));
|
||||
x10 = XOR(x10,U8TO32_LITTLE(m + 40));
|
||||
x11 = XOR(x11,U8TO32_LITTLE(m + 44));
|
||||
x12 = XOR(x12,U8TO32_LITTLE(m + 48));
|
||||
x13 = XOR(x13,U8TO32_LITTLE(m + 52));
|
||||
x14 = XOR(x14,U8TO32_LITTLE(m + 56));
|
||||
x15 = XOR(x15,U8TO32_LITTLE(m + 60));
|
||||
|
||||
j12 = PLUSONE(j12);
|
||||
if (!j12) {
|
||||
j13 = PLUSONE(j13);
|
||||
/* stopping at 2^70 bytes per nonce is user's responsibility */
|
||||
}
|
||||
|
||||
U32TO8_LITTLE(c + 0,x0);
|
||||
U32TO8_LITTLE(c + 4,x1);
|
||||
U32TO8_LITTLE(c + 8,x2);
|
||||
U32TO8_LITTLE(c + 12,x3);
|
||||
U32TO8_LITTLE(c + 16,x4);
|
||||
U32TO8_LITTLE(c + 20,x5);
|
||||
U32TO8_LITTLE(c + 24,x6);
|
||||
U32TO8_LITTLE(c + 28,x7);
|
||||
U32TO8_LITTLE(c + 32,x8);
|
||||
U32TO8_LITTLE(c + 36,x9);
|
||||
U32TO8_LITTLE(c + 40,x10);
|
||||
U32TO8_LITTLE(c + 44,x11);
|
||||
U32TO8_LITTLE(c + 48,x12);
|
||||
U32TO8_LITTLE(c + 52,x13);
|
||||
U32TO8_LITTLE(c + 56,x14);
|
||||
U32TO8_LITTLE(c + 60,x15);
|
||||
|
||||
if (bytes <= 64) {
|
||||
if (bytes < 64) {
|
||||
for (i = 0;i < bytes;++i) ctarget[i] = c[i];
|
||||
}
|
||||
x->input[12] = j12;
|
||||
x->input[13] = j13;
|
||||
return;
|
||||
}
|
||||
bytes -= 64;
|
||||
c += 64;
|
||||
m += 64;
|
||||
}
|
||||
}
|
36
chacha.h
Normal file
36
chacha.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
/* $OpenBSD: chacha.h,v 1.5 2021/04/03 05:54:14 djm Exp $ */
|
||||
|
||||
/*
|
||||
chacha-merged.c version 20080118
|
||||
D. J. Bernstein
|
||||
Public domain.
|
||||
*/
|
||||
|
||||
#ifndef CHACHA_H
|
||||
#define CHACHA_H
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
struct chacha_ctx {
|
||||
u_int input[16];
|
||||
};
|
||||
|
||||
#define CHACHA_MINKEYLEN 16
|
||||
#define CHACHA_NONCELEN 8
|
||||
#define CHACHA_CTRLEN 8
|
||||
#define CHACHA_STATELEN (CHACHA_NONCELEN+CHACHA_CTRLEN)
|
||||
#define CHACHA_BLOCKLEN 64
|
||||
|
||||
void chacha_keysetup(struct chacha_ctx *x, const u_char *k, u_int kbits)
|
||||
__attribute__((__bounded__(__minbytes__, 2, CHACHA_MINKEYLEN)));
|
||||
void chacha_ivsetup(struct chacha_ctx *x, const u_char *iv, const u_char *ctr)
|
||||
__attribute__((__bounded__(__minbytes__, 2, CHACHA_NONCELEN)))
|
||||
__attribute__((__bounded__(__minbytes__, 3, CHACHA_CTRLEN)));
|
||||
void chacha_encrypt_bytes(struct chacha_ctx *x, const u_char *m,
|
||||
u_char *c, u_int bytes)
|
||||
__attribute__((__bounded__(__buffer__, 2, 4)))
|
||||
__attribute__((__bounded__(__buffer__, 3, 4)));
|
||||
|
||||
#endif /* CHACHA_H */
|
||||
|
5360
channels.c
Normal file
5360
channels.c
Normal file
File diff suppressed because it is too large
Load diff
402
channels.h
Normal file
402
channels.h
Normal file
|
@ -0,0 +1,402 @@
|
|||
/* $OpenBSD: channels.h,v 1.158 2024/10/13 22:20:06 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
* All rights reserved
|
||||
*
|
||||
* As far as I am concerned, the code I have written for this software
|
||||
* can be used freely for any purpose. Any derived versions of this
|
||||
* software must be clearly marked as such, and if the derived work is
|
||||
* incompatible with the protocol description in the RFC file, it must be
|
||||
* called by a name other than "ssh" or "Secure Shell".
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef CHANNEL_H
|
||||
#define CHANNEL_H
|
||||
|
||||
/* Definitions for channel types. */
|
||||
#define SSH_CHANNEL_X11_LISTENER 1 /* Listening for inet X11 conn. */
|
||||
#define SSH_CHANNEL_PORT_LISTENER 2 /* Listening on a port. */
|
||||
#define SSH_CHANNEL_OPENING 3 /* waiting for confirmation */
|
||||
#define SSH_CHANNEL_OPEN 4 /* normal open two-way channel */
|
||||
#define SSH_CHANNEL_CLOSED 5 /* waiting for close confirmation */
|
||||
#define SSH_CHANNEL_AUTH_SOCKET 6 /* authentication socket */
|
||||
#define SSH_CHANNEL_X11_OPEN 7 /* reading first X11 packet */
|
||||
#define SSH_CHANNEL_LARVAL 10 /* larval session */
|
||||
#define SSH_CHANNEL_RPORT_LISTENER 11 /* Listening to a R-style port */
|
||||
#define SSH_CHANNEL_CONNECTING 12
|
||||
#define SSH_CHANNEL_DYNAMIC 13
|
||||
#define SSH_CHANNEL_ZOMBIE 14 /* Almost dead. */
|
||||
#define SSH_CHANNEL_MUX_LISTENER 15 /* Listener for mux conn. */
|
||||
#define SSH_CHANNEL_MUX_CLIENT 16 /* Conn. to mux client */
|
||||
#define SSH_CHANNEL_ABANDONED 17 /* Abandoned session, eg mux */
|
||||
#define SSH_CHANNEL_UNIX_LISTENER 18 /* Listening on a domain socket. */
|
||||
#define SSH_CHANNEL_RUNIX_LISTENER 19 /* Listening to a R-style domain socket. */
|
||||
#define SSH_CHANNEL_MUX_PROXY 20 /* proxy channel for mux-client */
|
||||
#define SSH_CHANNEL_RDYNAMIC_OPEN 21 /* reverse SOCKS, parsing request */
|
||||
#define SSH_CHANNEL_RDYNAMIC_FINISH 22 /* reverse SOCKS, finishing connect */
|
||||
#define SSH_CHANNEL_MAX_TYPE 23
|
||||
|
||||
#define CHANNEL_CANCEL_PORT_STATIC -1
|
||||
|
||||
/* nonblocking flags for channel_new */
|
||||
#define CHANNEL_NONBLOCK_LEAVE 0 /* don't modify non-blocking state */
|
||||
#define CHANNEL_NONBLOCK_SET 1 /* set non-blocking state */
|
||||
#define CHANNEL_NONBLOCK_STDIO 2 /* set non-blocking and restore on close */
|
||||
|
||||
/* c->restore_block mask flags */
|
||||
#define CHANNEL_RESTORE_RFD 0x01
|
||||
#define CHANNEL_RESTORE_WFD 0x02
|
||||
#define CHANNEL_RESTORE_EFD 0x04
|
||||
|
||||
/* TCP forwarding */
|
||||
#define FORWARD_DENY 0
|
||||
#define FORWARD_REMOTE (1)
|
||||
#define FORWARD_LOCAL (1<<1)
|
||||
#define FORWARD_ALLOW (FORWARD_REMOTE|FORWARD_LOCAL)
|
||||
|
||||
#define FORWARD_ADM 0x100
|
||||
#define FORWARD_USER 0x101
|
||||
|
||||
struct ssh;
|
||||
struct Channel;
|
||||
typedef struct Channel Channel;
|
||||
|
||||
typedef void channel_open_fn(struct ssh *, int, int, void *);
|
||||
typedef void channel_callback_fn(struct ssh *, int, int, void *);
|
||||
typedef int channel_infilter_fn(struct ssh *, struct Channel *, char *, int);
|
||||
typedef void channel_filter_cleanup_fn(struct ssh *, int, void *);
|
||||
typedef u_char *channel_outfilter_fn(struct ssh *, struct Channel *,
|
||||
u_char **, size_t *);
|
||||
|
||||
/* Channel success/failure callbacks */
|
||||
typedef void channel_confirm_cb(struct ssh *, int, struct Channel *, void *);
|
||||
typedef void channel_confirm_abandon_cb(struct ssh *, struct Channel *, void *);
|
||||
struct channel_confirm {
|
||||
TAILQ_ENTRY(channel_confirm) entry;
|
||||
channel_confirm_cb *cb;
|
||||
channel_confirm_abandon_cb *abandon_cb;
|
||||
void *ctx;
|
||||
};
|
||||
TAILQ_HEAD(channel_confirms, channel_confirm);
|
||||
|
||||
/* Context for non-blocking connects */
|
||||
struct channel_connect {
|
||||
char *host;
|
||||
int port;
|
||||
struct addrinfo *ai, *aitop;
|
||||
};
|
||||
|
||||
/* Callbacks for mux channels back into client-specific code */
|
||||
typedef int mux_callback_fn(struct ssh *, struct Channel *);
|
||||
|
||||
/*
|
||||
* NB. channel IDs on the wire and in c->remote_id are uint32, but local
|
||||
* channel IDs (e.g. c->self) only ever use the int32 subset of this range,
|
||||
* because we use local channel ID -1 for housekeeping. Remote channels have
|
||||
* a dedicated "have_remote_id" flag to indicate their validity.
|
||||
*/
|
||||
|
||||
struct Channel {
|
||||
int type; /* channel type/state */
|
||||
|
||||
int self; /* my own channel identifier */
|
||||
uint32_t remote_id; /* channel identifier for remote peer */
|
||||
int have_remote_id; /* non-zero if remote_id is valid */
|
||||
|
||||
u_int istate; /* input from channel (state of receive half) */
|
||||
u_int ostate; /* output to channel (state of transmit half) */
|
||||
int flags; /* close sent/rcvd */
|
||||
int rfd; /* read fd */
|
||||
int wfd; /* write fd */
|
||||
int efd; /* extended fd */
|
||||
int sock; /* sock fd */
|
||||
u_int io_want; /* bitmask of SSH_CHAN_IO_* */
|
||||
u_int io_ready; /* bitmask of SSH_CHAN_IO_* */
|
||||
int pfds[4]; /* pollfd entries for rfd/wfd/efd/sock */
|
||||
int ctl_chan; /* control channel (multiplexed connections) */
|
||||
uint32_t ctl_child_id; /* child session for mux controllers */
|
||||
int have_ctl_child_id;/* non-zero if ctl_child_id is valid */
|
||||
int isatty; /* rfd is a tty */
|
||||
#ifdef _AIX
|
||||
int wfd_isatty; /* wfd is a tty */
|
||||
#endif
|
||||
int client_tty; /* (client) TTY has been requested */
|
||||
int force_drain; /* force close on iEOF */
|
||||
time_t notbefore; /* Pause IO until deadline (time_t) */
|
||||
int delayed; /* post-IO handlers for newly created
|
||||
* channels are delayed until the first call
|
||||
* to a matching pre-IO handler.
|
||||
* this way post-IO handlers are not
|
||||
* accidentally called if a FD gets reused */
|
||||
int restore_block; /* fd mask to restore blocking status */
|
||||
int restore_flags[3];/* flags to restore */
|
||||
struct sshbuf *input; /* data read from socket, to be sent over
|
||||
* encrypted connection */
|
||||
struct sshbuf *output; /* data received over encrypted connection for
|
||||
* send on socket */
|
||||
struct sshbuf *extended;
|
||||
|
||||
char *path;
|
||||
/* path for unix domain sockets, or host name for forwards */
|
||||
int listening_port; /* port being listened for forwards */
|
||||
char *listening_addr; /* addr being listened for forwards */
|
||||
int host_port; /* remote port to connect for forwards */
|
||||
char *remote_name; /* remote hostname */
|
||||
|
||||
u_int remote_window;
|
||||
u_int remote_maxpacket;
|
||||
u_int local_window;
|
||||
u_int local_window_exceeded;
|
||||
u_int local_window_max;
|
||||
u_int local_consumed;
|
||||
u_int local_maxpacket;
|
||||
int extended_usage;
|
||||
int single_connection;
|
||||
|
||||
char *ctype; /* const type - NB. not freed on channel_free */
|
||||
char *xctype; /* extended type */
|
||||
|
||||
/* callback */
|
||||
channel_open_fn *open_confirm;
|
||||
void *open_confirm_ctx;
|
||||
channel_callback_fn *detach_user;
|
||||
int detach_close;
|
||||
struct channel_confirms status_confirms;
|
||||
|
||||
/* filter */
|
||||
channel_infilter_fn *input_filter;
|
||||
channel_outfilter_fn *output_filter;
|
||||
void *filter_ctx;
|
||||
channel_filter_cleanup_fn *filter_cleanup;
|
||||
|
||||
/* keep boundaries */
|
||||
int datagram;
|
||||
|
||||
/* non-blocking connect */
|
||||
/* XXX make this a pointer so the structure can be opaque */
|
||||
struct channel_connect connect_ctx;
|
||||
|
||||
/* multiplexing protocol hook, called for each packet received */
|
||||
mux_callback_fn *mux_rcb;
|
||||
void *mux_ctx;
|
||||
int mux_pause;
|
||||
int mux_downstream_id;
|
||||
|
||||
/* Inactivity timeouts */
|
||||
|
||||
/* Last traffic seen for OPEN channels */
|
||||
time_t lastused;
|
||||
/* Inactivity timeout deadline in seconds (0 = no timeout) */
|
||||
int inactive_deadline;
|
||||
};
|
||||
|
||||
#define CHAN_EXTENDED_IGNORE 0
|
||||
#define CHAN_EXTENDED_READ 1
|
||||
#define CHAN_EXTENDED_WRITE 2
|
||||
|
||||
/* default window/packet sizes for tcp/x11-fwd-channel */
|
||||
#define CHAN_SES_PACKET_DEFAULT (32*1024)
|
||||
#define CHAN_SES_WINDOW_DEFAULT (64*CHAN_SES_PACKET_DEFAULT)
|
||||
#define CHAN_TCP_PACKET_DEFAULT (32*1024)
|
||||
#define CHAN_TCP_WINDOW_DEFAULT (64*CHAN_TCP_PACKET_DEFAULT)
|
||||
#define CHAN_X11_PACKET_DEFAULT (16*1024)
|
||||
#define CHAN_X11_WINDOW_DEFAULT (4*CHAN_X11_PACKET_DEFAULT)
|
||||
|
||||
/* possible input states */
|
||||
#define CHAN_INPUT_OPEN 0
|
||||
#define CHAN_INPUT_WAIT_DRAIN 1
|
||||
#define CHAN_INPUT_WAIT_OCLOSE 2
|
||||
#define CHAN_INPUT_CLOSED 3
|
||||
|
||||
/* possible output states */
|
||||
#define CHAN_OUTPUT_OPEN 0
|
||||
#define CHAN_OUTPUT_WAIT_DRAIN 1
|
||||
#define CHAN_OUTPUT_WAIT_IEOF 2
|
||||
#define CHAN_OUTPUT_CLOSED 3
|
||||
|
||||
#define CHAN_CLOSE_SENT 0x01
|
||||
#define CHAN_CLOSE_RCVD 0x02
|
||||
#define CHAN_EOF_SENT 0x04
|
||||
#define CHAN_EOF_RCVD 0x08
|
||||
#define CHAN_LOCAL 0x10
|
||||
|
||||
/* file descriptor events */
|
||||
#define SSH_CHAN_IO_RFD 0x01
|
||||
#define SSH_CHAN_IO_WFD 0x02
|
||||
#define SSH_CHAN_IO_EFD_R 0x04
|
||||
#define SSH_CHAN_IO_EFD_W 0x08
|
||||
#define SSH_CHAN_IO_EFD (SSH_CHAN_IO_EFD_R|SSH_CHAN_IO_EFD_W)
|
||||
#define SSH_CHAN_IO_SOCK_R 0x10
|
||||
#define SSH_CHAN_IO_SOCK_W 0x20
|
||||
#define SSH_CHAN_IO_SOCK (SSH_CHAN_IO_SOCK_R|SSH_CHAN_IO_SOCK_W)
|
||||
|
||||
/* Read buffer size */
|
||||
#define CHAN_RBUF (16*1024)
|
||||
|
||||
/* Maximum size for direct reads to buffers */
|
||||
#define CHANNEL_MAX_READ CHAN_SES_PACKET_DEFAULT
|
||||
|
||||
/* Maximum channel input buffer size */
|
||||
#define CHAN_INPUT_MAX (16*1024*1024)
|
||||
|
||||
/* Hard limit on number of channels */
|
||||
#define CHANNELS_MAX_CHANNELS (16*1024)
|
||||
|
||||
/* check whether 'efd' is still in use */
|
||||
#define CHANNEL_EFD_INPUT_ACTIVE(c) \
|
||||
(c->extended_usage == CHAN_EXTENDED_READ && \
|
||||
(c->efd != -1 || \
|
||||
sshbuf_len(c->extended) > 0))
|
||||
#define CHANNEL_EFD_OUTPUT_ACTIVE(c) \
|
||||
(c->extended_usage == CHAN_EXTENDED_WRITE && \
|
||||
c->efd != -1 && (!(c->flags & (CHAN_EOF_RCVD|CHAN_CLOSE_RCVD)) || \
|
||||
sshbuf_len(c->extended) > 0))
|
||||
|
||||
/* Add channel management structures to SSH transport instance */
|
||||
void channel_init_channels(struct ssh *ssh);
|
||||
|
||||
/* channel management */
|
||||
|
||||
Channel *channel_by_id(struct ssh *, int);
|
||||
Channel *channel_by_remote_id(struct ssh *, u_int);
|
||||
Channel *channel_lookup(struct ssh *, int);
|
||||
Channel *channel_new(struct ssh *, char *, int, int, int, int,
|
||||
u_int, u_int, int, const char *, int);
|
||||
void channel_set_fds(struct ssh *, int, int, int, int, int,
|
||||
int, int, u_int);
|
||||
void channel_free(struct ssh *, Channel *);
|
||||
void channel_free_all(struct ssh *);
|
||||
void channel_stop_listening(struct ssh *);
|
||||
void channel_force_close(struct ssh *, Channel *, int);
|
||||
void channel_set_xtype(struct ssh *, int, const char *);
|
||||
|
||||
void channel_send_open(struct ssh *, int);
|
||||
void channel_request_start(struct ssh *, int, char *, int);
|
||||
void channel_register_cleanup(struct ssh *, int,
|
||||
channel_callback_fn *, int);
|
||||
void channel_register_open_confirm(struct ssh *, int,
|
||||
channel_open_fn *, void *);
|
||||
void channel_register_filter(struct ssh *, int, channel_infilter_fn *,
|
||||
channel_outfilter_fn *, channel_filter_cleanup_fn *, void *);
|
||||
void channel_register_status_confirm(struct ssh *, int,
|
||||
channel_confirm_cb *, channel_confirm_abandon_cb *, void *);
|
||||
void channel_cancel_cleanup(struct ssh *, int);
|
||||
int channel_close_fd(struct ssh *, Channel *, int *);
|
||||
void channel_send_window_changes(struct ssh *);
|
||||
|
||||
/* channel inactivity timeouts */
|
||||
void channel_add_timeout(struct ssh *, const char *, int);
|
||||
void channel_clear_timeouts(struct ssh *);
|
||||
|
||||
/* mux proxy support */
|
||||
|
||||
int channel_proxy_downstream(struct ssh *, Channel *mc);
|
||||
int channel_proxy_upstream(Channel *, int, u_int32_t, struct ssh *);
|
||||
|
||||
/* protocol handler */
|
||||
|
||||
int channel_input_data(int, u_int32_t, struct ssh *);
|
||||
int channel_input_extended_data(int, u_int32_t, struct ssh *);
|
||||
int channel_input_ieof(int, u_int32_t, struct ssh *);
|
||||
int channel_input_oclose(int, u_int32_t, struct ssh *);
|
||||
int channel_input_open_confirmation(int, u_int32_t, struct ssh *);
|
||||
int channel_input_open_failure(int, u_int32_t, struct ssh *);
|
||||
int channel_input_window_adjust(int, u_int32_t, struct ssh *);
|
||||
int channel_input_status_confirm(int, u_int32_t, struct ssh *);
|
||||
|
||||
/* file descriptor handling (read/write) */
|
||||
struct pollfd;
|
||||
struct timespec;
|
||||
|
||||
void channel_prepare_poll(struct ssh *, struct pollfd **,
|
||||
u_int *, u_int *, u_int, struct timespec *);
|
||||
void channel_after_poll(struct ssh *, struct pollfd *, u_int);
|
||||
int channel_output_poll(struct ssh *);
|
||||
|
||||
int channel_not_very_much_buffered_data(struct ssh *);
|
||||
void channel_close_all(struct ssh *);
|
||||
int channel_still_open(struct ssh *);
|
||||
int channel_tty_open(struct ssh *);
|
||||
const char *channel_format_extended_usage(const Channel *);
|
||||
char *channel_open_message(struct ssh *);
|
||||
int channel_find_open(struct ssh *);
|
||||
|
||||
/* tcp forwarding */
|
||||
struct Forward;
|
||||
struct ForwardOptions;
|
||||
void channel_set_af(struct ssh *, int af);
|
||||
void channel_permit_all(struct ssh *, int);
|
||||
void channel_add_permission(struct ssh *, int, int, char *, int);
|
||||
void channel_clear_permission(struct ssh *, int, int);
|
||||
void channel_disable_admin(struct ssh *, int);
|
||||
void channel_update_permission(struct ssh *, int, int);
|
||||
Channel *channel_connect_to_port(struct ssh *, const char *, u_short,
|
||||
char *, char *, int *, const char **);
|
||||
Channel *channel_connect_to_path(struct ssh *, const char *, char *, char *);
|
||||
Channel *channel_connect_stdio_fwd(struct ssh *, const char*,
|
||||
int, int, int, int);
|
||||
Channel *channel_connect_by_listen_address(struct ssh *, const char *,
|
||||
u_short, char *, char *);
|
||||
Channel *channel_connect_by_listen_path(struct ssh *, const char *,
|
||||
char *, char *);
|
||||
int channel_request_remote_forwarding(struct ssh *, struct Forward *);
|
||||
int channel_setup_local_fwd_listener(struct ssh *, struct Forward *,
|
||||
struct ForwardOptions *);
|
||||
int channel_request_rforward_cancel(struct ssh *, struct Forward *);
|
||||
int channel_setup_remote_fwd_listener(struct ssh *, struct Forward *,
|
||||
int *, struct ForwardOptions *);
|
||||
int channel_cancel_rport_listener(struct ssh *, struct Forward *);
|
||||
int channel_cancel_lport_listener(struct ssh *, struct Forward *,
|
||||
int, struct ForwardOptions *);
|
||||
int permitopen_port(const char *);
|
||||
|
||||
/* x11 forwarding */
|
||||
|
||||
void channel_set_x11_refuse_time(struct ssh *, time_t);
|
||||
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 */
|
||||
|
||||
int chan_is_dead(struct ssh *, Channel *, int);
|
||||
void chan_mark_dead(struct ssh *, Channel *);
|
||||
|
||||
/* channel events */
|
||||
|
||||
void chan_rcvd_oclose(struct ssh *, Channel *);
|
||||
void chan_rcvd_eow(struct ssh *, Channel *);
|
||||
void chan_read_failed(struct ssh *, Channel *);
|
||||
void chan_ibuf_empty(struct ssh *, Channel *);
|
||||
void chan_rcvd_ieof(struct ssh *, Channel *);
|
||||
void chan_write_failed(struct ssh *, Channel *);
|
||||
void chan_obuf_empty(struct ssh *, Channel *);
|
||||
|
||||
#endif
|
161
cipher-aes.c
Normal file
161
cipher-aes.c
Normal file
|
@ -0,0 +1,161 @@
|
|||
/*
|
||||
* Copyright (c) 2003 Markus Friedl. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
/* compatibility with old or broken OpenSSL versions */
|
||||
#include "openbsd-compat/openssl-compat.h"
|
||||
|
||||
#ifdef USE_BUILTIN_RIJNDAEL
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <openssl/evp.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "rijndael.h"
|
||||
#include "xmalloc.h"
|
||||
#include "log.h"
|
||||
|
||||
#define RIJNDAEL_BLOCKSIZE 16
|
||||
struct ssh_rijndael_ctx
|
||||
{
|
||||
rijndael_ctx r_ctx;
|
||||
u_char r_iv[RIJNDAEL_BLOCKSIZE];
|
||||
};
|
||||
|
||||
static int
|
||||
ssh_rijndael_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv,
|
||||
int enc)
|
||||
{
|
||||
struct ssh_rijndael_ctx *c;
|
||||
|
||||
if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
|
||||
c = xmalloc(sizeof(*c));
|
||||
EVP_CIPHER_CTX_set_app_data(ctx, c);
|
||||
}
|
||||
if (key != NULL) {
|
||||
if (enc == -1)
|
||||
enc = ctx->encrypt;
|
||||
rijndael_set_key(&c->r_ctx, (u_char *)key,
|
||||
8*EVP_CIPHER_CTX_key_length(ctx), enc);
|
||||
}
|
||||
if (iv != NULL)
|
||||
memcpy(c->r_iv, iv, RIJNDAEL_BLOCKSIZE);
|
||||
return (1);
|
||||
}
|
||||
|
||||
static int
|
||||
ssh_rijndael_cbc(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src,
|
||||
size_t len)
|
||||
{
|
||||
struct ssh_rijndael_ctx *c;
|
||||
u_char buf[RIJNDAEL_BLOCKSIZE];
|
||||
u_char *cprev, *cnow, *plain, *ivp;
|
||||
int i, j, blocks = len / RIJNDAEL_BLOCKSIZE;
|
||||
|
||||
if (len == 0)
|
||||
return (1);
|
||||
if (len % RIJNDAEL_BLOCKSIZE)
|
||||
fatal("ssh_rijndael_cbc: bad len %d", len);
|
||||
if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
|
||||
error("ssh_rijndael_cbc: no context");
|
||||
return (0);
|
||||
}
|
||||
if (ctx->encrypt) {
|
||||
cnow = dest;
|
||||
plain = (u_char *)src;
|
||||
cprev = c->r_iv;
|
||||
for (i = 0; i < blocks; i++, plain+=RIJNDAEL_BLOCKSIZE,
|
||||
cnow+=RIJNDAEL_BLOCKSIZE) {
|
||||
for (j = 0; j < RIJNDAEL_BLOCKSIZE; j++)
|
||||
buf[j] = plain[j] ^ cprev[j];
|
||||
rijndael_encrypt(&c->r_ctx, buf, cnow);
|
||||
cprev = cnow;
|
||||
}
|
||||
memcpy(c->r_iv, cprev, RIJNDAEL_BLOCKSIZE);
|
||||
} else {
|
||||
cnow = (u_char *) (src+len-RIJNDAEL_BLOCKSIZE);
|
||||
plain = dest+len-RIJNDAEL_BLOCKSIZE;
|
||||
|
||||
memcpy(buf, cnow, RIJNDAEL_BLOCKSIZE);
|
||||
for (i = blocks; i > 0; i--, cnow-=RIJNDAEL_BLOCKSIZE,
|
||||
plain-=RIJNDAEL_BLOCKSIZE) {
|
||||
rijndael_decrypt(&c->r_ctx, cnow, plain);
|
||||
ivp = (i == 1) ? c->r_iv : cnow-RIJNDAEL_BLOCKSIZE;
|
||||
for (j = 0; j < RIJNDAEL_BLOCKSIZE; j++)
|
||||
plain[j] ^= ivp[j];
|
||||
}
|
||||
memcpy(c->r_iv, buf, RIJNDAEL_BLOCKSIZE);
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
static int
|
||||
ssh_rijndael_cleanup(EVP_CIPHER_CTX *ctx)
|
||||
{
|
||||
struct ssh_rijndael_ctx *c;
|
||||
|
||||
if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) {
|
||||
memset(c, 0, sizeof(*c));
|
||||
free(c);
|
||||
EVP_CIPHER_CTX_set_app_data(ctx, NULL);
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
void
|
||||
ssh_rijndael_iv(EVP_CIPHER_CTX *evp, int doset, u_char * iv, u_int len)
|
||||
{
|
||||
struct ssh_rijndael_ctx *c;
|
||||
|
||||
if ((c = EVP_CIPHER_CTX_get_app_data(evp)) == NULL)
|
||||
fatal("ssh_rijndael_iv: no context");
|
||||
if (doset)
|
||||
memcpy(c->r_iv, iv, len);
|
||||
else
|
||||
memcpy(iv, c->r_iv, len);
|
||||
}
|
||||
|
||||
const EVP_CIPHER *
|
||||
evp_rijndael(void)
|
||||
{
|
||||
static EVP_CIPHER rijndal_cbc;
|
||||
|
||||
memset(&rijndal_cbc, 0, sizeof(EVP_CIPHER));
|
||||
rijndal_cbc.nid = NID_undef;
|
||||
rijndal_cbc.block_size = RIJNDAEL_BLOCKSIZE;
|
||||
rijndal_cbc.iv_len = RIJNDAEL_BLOCKSIZE;
|
||||
rijndal_cbc.key_len = 16;
|
||||
rijndal_cbc.init = ssh_rijndael_init;
|
||||
rijndal_cbc.cleanup = ssh_rijndael_cleanup;
|
||||
rijndal_cbc.do_cipher = ssh_rijndael_cbc;
|
||||
#ifndef SSH_OLD_EVP
|
||||
rijndal_cbc.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH |
|
||||
EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV;
|
||||
#endif
|
||||
return (&rijndal_cbc);
|
||||
}
|
||||
#endif /* USE_BUILTIN_RIJNDAEL */
|
83
cipher-aesctr.c
Normal file
83
cipher-aesctr.c
Normal file
|
@ -0,0 +1,83 @@
|
|||
/* $OpenBSD: cipher-aesctr.c,v 1.2 2015/01/14 10:24:42 markus Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2003 Markus Friedl. All rights reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef WITH_OPENSSL
|
||||
|
||||
#include "cipher-aesctr.h"
|
||||
|
||||
/*
|
||||
* increment counter 'ctr',
|
||||
* the counter is of size 'len' bytes and stored in network-byte-order.
|
||||
* (LSB at ctr[len-1], MSB at ctr[0])
|
||||
*/
|
||||
static inline void
|
||||
aesctr_inc(u8 *ctr, u32 len)
|
||||
{
|
||||
ssize_t i;
|
||||
|
||||
#ifndef CONSTANT_TIME_INCREMENT
|
||||
for (i = len - 1; i >= 0; i--)
|
||||
if (++ctr[i]) /* continue on overflow */
|
||||
return;
|
||||
#else
|
||||
u8 x, add = 1;
|
||||
|
||||
for (i = len - 1; i >= 0; i--) {
|
||||
ctr[i] += add;
|
||||
/* constant time for: x = ctr[i] ? 1 : 0 */
|
||||
x = ctr[i];
|
||||
x = (x | (x >> 4)) & 0xf;
|
||||
x = (x | (x >> 2)) & 0x3;
|
||||
x = (x | (x >> 1)) & 0x1;
|
||||
add *= (x^1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
aesctr_keysetup(aesctr_ctx *x,const u8 *k,u32 kbits,u32 ivbits)
|
||||
{
|
||||
x->rounds = rijndaelKeySetupEnc(x->ek, k, kbits);
|
||||
}
|
||||
|
||||
void
|
||||
aesctr_ivsetup(aesctr_ctx *x,const u8 *iv)
|
||||
{
|
||||
memcpy(x->ctr, iv, AES_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
void
|
||||
aesctr_encrypt_bytes(aesctr_ctx *x,const u8 *m,u8 *c,u32 bytes)
|
||||
{
|
||||
u32 n = 0;
|
||||
u8 buf[AES_BLOCK_SIZE];
|
||||
|
||||
while ((bytes--) > 0) {
|
||||
if (n == 0) {
|
||||
rijndaelEncrypt(x->ek, x->rounds, x->ctr, buf);
|
||||
aesctr_inc(x->ctr, AES_BLOCK_SIZE);
|
||||
}
|
||||
*(c++) = *(m++) ^ buf[n];
|
||||
n = (n + 1) % AES_BLOCK_SIZE;
|
||||
}
|
||||
}
|
||||
#endif /* !WITH_OPENSSL */
|
35
cipher-aesctr.h
Normal file
35
cipher-aesctr.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
/* $OpenBSD: cipher-aesctr.h,v 1.1 2014/04/29 15:39:33 markus Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2014 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.
|
||||
*/
|
||||
|
||||
#ifndef OPENSSH_AESCTR_H
|
||||
#define OPENSSH_AESCTR_H
|
||||
|
||||
#include "rijndael.h"
|
||||
|
||||
#define AES_BLOCK_SIZE 16
|
||||
|
||||
typedef struct aesctr_ctx {
|
||||
int rounds; /* keylen-dependent #rounds */
|
||||
u32 ek[4*(AES_MAXROUNDS + 1)]; /* encrypt key schedule */
|
||||
u8 ctr[AES_BLOCK_SIZE]; /* counter */
|
||||
} aesctr_ctx;
|
||||
|
||||
void aesctr_keysetup(aesctr_ctx *x,const u8 *k,u32 kbits,u32 ivbits);
|
||||
void aesctr_ivsetup(aesctr_ctx *x,const u8 *iv);
|
||||
void aesctr_encrypt_bytes(aesctr_ctx *x,const u8 *m,u8 *c,u32 bytes);
|
||||
|
||||
#endif
|
165
cipher-chachapoly-libcrypto.c
Normal file
165
cipher-chachapoly-libcrypto.c
Normal file
|
@ -0,0 +1,165 @@
|
|||
/* $OpenBSD: cipher-chachapoly-libcrypto.c,v 1.2 2023/07/17 05:26:38 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2013 Damien Miller <djm@mindrot.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#ifdef WITH_OPENSSL
|
||||
#include "openbsd-compat/openssl-compat.h"
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_EVP_CHACHA20) && !defined(HAVE_BROKEN_CHACHA20)
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdarg.h> /* needed for log.h */
|
||||
#include <string.h>
|
||||
#include <stdio.h> /* needed for misc.h */
|
||||
|
||||
#include <openssl/evp.h>
|
||||
|
||||
#include "log.h"
|
||||
#include "sshbuf.h"
|
||||
#include "ssherr.h"
|
||||
#include "cipher-chachapoly.h"
|
||||
|
||||
struct chachapoly_ctx {
|
||||
EVP_CIPHER_CTX *main_evp, *header_evp;
|
||||
};
|
||||
|
||||
struct chachapoly_ctx *
|
||||
chachapoly_new(const u_char *key, u_int keylen)
|
||||
{
|
||||
struct chachapoly_ctx *ctx;
|
||||
|
||||
if (keylen != (32 + 32)) /* 2 x 256 bit keys */
|
||||
return NULL;
|
||||
if ((ctx = calloc(1, sizeof(*ctx))) == NULL)
|
||||
return NULL;
|
||||
if ((ctx->main_evp = EVP_CIPHER_CTX_new()) == NULL ||
|
||||
(ctx->header_evp = EVP_CIPHER_CTX_new()) == NULL)
|
||||
goto fail;
|
||||
if (!EVP_CipherInit(ctx->main_evp, EVP_chacha20(), key, NULL, 1))
|
||||
goto fail;
|
||||
if (!EVP_CipherInit(ctx->header_evp, EVP_chacha20(), key + 32, NULL, 1))
|
||||
goto fail;
|
||||
if (EVP_CIPHER_CTX_iv_length(ctx->header_evp) != 16)
|
||||
goto fail;
|
||||
return ctx;
|
||||
fail:
|
||||
chachapoly_free(ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
chachapoly_free(struct chachapoly_ctx *cpctx)
|
||||
{
|
||||
if (cpctx == NULL)
|
||||
return;
|
||||
EVP_CIPHER_CTX_free(cpctx->main_evp);
|
||||
EVP_CIPHER_CTX_free(cpctx->header_evp);
|
||||
freezero(cpctx, sizeof(*cpctx));
|
||||
}
|
||||
|
||||
/*
|
||||
* chachapoly_crypt() operates as following:
|
||||
* En/decrypt with header key 'aadlen' bytes from 'src', storing result
|
||||
* to 'dest'. The ciphertext here is treated as additional authenticated
|
||||
* data for MAC calculation.
|
||||
* En/decrypt 'len' bytes at offset 'aadlen' from 'src' to 'dest'. Use
|
||||
* POLY1305_TAGLEN bytes at offset 'len'+'aadlen' as the authentication
|
||||
* tag. This tag is written on encryption and verified on decryption.
|
||||
*/
|
||||
int
|
||||
chachapoly_crypt(struct chachapoly_ctx *ctx, u_int seqnr, u_char *dest,
|
||||
const u_char *src, u_int len, u_int aadlen, u_int authlen, int do_encrypt)
|
||||
{
|
||||
u_char seqbuf[16]; /* layout: u64 counter || u64 seqno */
|
||||
int r = SSH_ERR_INTERNAL_ERROR;
|
||||
u_char expected_tag[POLY1305_TAGLEN], poly_key[POLY1305_KEYLEN];
|
||||
|
||||
/*
|
||||
* Run ChaCha20 once to generate the Poly1305 key. The IV is the
|
||||
* packet sequence number.
|
||||
*/
|
||||
memset(seqbuf, 0, sizeof(seqbuf));
|
||||
POKE_U64(seqbuf + 8, seqnr);
|
||||
memset(poly_key, 0, sizeof(poly_key));
|
||||
if (!EVP_CipherInit(ctx->main_evp, NULL, NULL, seqbuf, 1) ||
|
||||
EVP_Cipher(ctx->main_evp, poly_key,
|
||||
poly_key, sizeof(poly_key)) < 0) {
|
||||
r = SSH_ERR_LIBCRYPTO_ERROR;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* If decrypting, check tag before anything else */
|
||||
if (!do_encrypt) {
|
||||
const u_char *tag = src + aadlen + len;
|
||||
|
||||
poly1305_auth(expected_tag, src, aadlen + len, poly_key);
|
||||
if (timingsafe_bcmp(expected_tag, tag, POLY1305_TAGLEN) != 0) {
|
||||
r = SSH_ERR_MAC_INVALID;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
/* Crypt additional data */
|
||||
if (aadlen) {
|
||||
if (!EVP_CipherInit(ctx->header_evp, NULL, NULL, seqbuf, 1) ||
|
||||
EVP_Cipher(ctx->header_evp, dest, src, aadlen) < 0) {
|
||||
r = SSH_ERR_LIBCRYPTO_ERROR;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set Chacha's block counter to 1 */
|
||||
seqbuf[0] = 1;
|
||||
if (!EVP_CipherInit(ctx->main_evp, NULL, NULL, seqbuf, 1) ||
|
||||
EVP_Cipher(ctx->main_evp, dest + aadlen, src + aadlen, len) < 0) {
|
||||
r = SSH_ERR_LIBCRYPTO_ERROR;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* If encrypting, calculate and append tag */
|
||||
if (do_encrypt) {
|
||||
poly1305_auth(dest + aadlen + len, dest, aadlen + len,
|
||||
poly_key);
|
||||
}
|
||||
r = 0;
|
||||
out:
|
||||
explicit_bzero(expected_tag, sizeof(expected_tag));
|
||||
explicit_bzero(seqbuf, sizeof(seqbuf));
|
||||
explicit_bzero(poly_key, sizeof(poly_key));
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Decrypt and extract the encrypted packet length */
|
||||
int
|
||||
chachapoly_get_length(struct chachapoly_ctx *ctx,
|
||||
u_int *plenp, u_int seqnr, const u_char *cp, u_int len)
|
||||
{
|
||||
u_char buf[4], seqbuf[16];
|
||||
|
||||
if (len < 4)
|
||||
return SSH_ERR_MESSAGE_INCOMPLETE;
|
||||
memset(seqbuf, 0, sizeof(seqbuf));
|
||||
POKE_U64(seqbuf + 8, seqnr);
|
||||
if (!EVP_CipherInit(ctx->header_evp, NULL, NULL, seqbuf, 0))
|
||||
return SSH_ERR_LIBCRYPTO_ERROR;
|
||||
if (EVP_Cipher(ctx->header_evp, buf, (u_char *)cp, sizeof(buf)) < 0)
|
||||
return SSH_ERR_LIBCRYPTO_ERROR;
|
||||
*plenp = PEEK_U32(buf);
|
||||
return 0;
|
||||
}
|
||||
#endif /* defined(HAVE_EVP_CHACHA20) && !defined(HAVE_BROKEN_CHACHA20) */
|
138
cipher-chachapoly.c
Normal file
138
cipher-chachapoly.c
Normal file
|
@ -0,0 +1,138 @@
|
|||
/* $OpenBSD: cipher-chachapoly.c,v 1.10 2023/07/17 05:26:38 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2013 Damien Miller <djm@mindrot.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#ifdef WITH_OPENSSL
|
||||
#include "openbsd-compat/openssl-compat.h"
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_EVP_CHACHA20) || defined(HAVE_BROKEN_CHACHA20)
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdarg.h> /* needed for log.h */
|
||||
#include <string.h>
|
||||
#include <stdio.h> /* needed for misc.h */
|
||||
|
||||
#include "log.h"
|
||||
#include "sshbuf.h"
|
||||
#include "ssherr.h"
|
||||
#include "cipher-chachapoly.h"
|
||||
|
||||
struct chachapoly_ctx {
|
||||
struct chacha_ctx main_ctx, header_ctx;
|
||||
};
|
||||
|
||||
struct chachapoly_ctx *
|
||||
chachapoly_new(const u_char *key, u_int keylen)
|
||||
{
|
||||
struct chachapoly_ctx *ctx;
|
||||
|
||||
if (keylen != (32 + 32)) /* 2 x 256 bit keys */
|
||||
return NULL;
|
||||
if ((ctx = calloc(1, sizeof(*ctx))) == NULL)
|
||||
return NULL;
|
||||
chacha_keysetup(&ctx->main_ctx, key, 256);
|
||||
chacha_keysetup(&ctx->header_ctx, key + 32, 256);
|
||||
return ctx;
|
||||
}
|
||||
|
||||
void
|
||||
chachapoly_free(struct chachapoly_ctx *cpctx)
|
||||
{
|
||||
freezero(cpctx, sizeof(*cpctx));
|
||||
}
|
||||
|
||||
/*
|
||||
* chachapoly_crypt() operates as following:
|
||||
* En/decrypt with header key 'aadlen' bytes from 'src', storing result
|
||||
* to 'dest'. The ciphertext here is treated as additional authenticated
|
||||
* data for MAC calculation.
|
||||
* En/decrypt 'len' bytes at offset 'aadlen' from 'src' to 'dest'. Use
|
||||
* POLY1305_TAGLEN bytes at offset 'len'+'aadlen' as the authentication
|
||||
* tag. This tag is written on encryption and verified on decryption.
|
||||
*/
|
||||
int
|
||||
chachapoly_crypt(struct chachapoly_ctx *ctx, u_int seqnr, u_char *dest,
|
||||
const u_char *src, u_int len, u_int aadlen, u_int authlen, int do_encrypt)
|
||||
{
|
||||
u_char seqbuf[8];
|
||||
const u_char one[8] = { 1, 0, 0, 0, 0, 0, 0, 0 }; /* NB little-endian */
|
||||
u_char expected_tag[POLY1305_TAGLEN], poly_key[POLY1305_KEYLEN];
|
||||
int r = SSH_ERR_INTERNAL_ERROR;
|
||||
|
||||
/*
|
||||
* Run ChaCha20 once to generate the Poly1305 key. The IV is the
|
||||
* packet sequence number.
|
||||
*/
|
||||
memset(poly_key, 0, sizeof(poly_key));
|
||||
POKE_U64(seqbuf, seqnr);
|
||||
chacha_ivsetup(&ctx->main_ctx, seqbuf, NULL);
|
||||
chacha_encrypt_bytes(&ctx->main_ctx,
|
||||
poly_key, poly_key, sizeof(poly_key));
|
||||
|
||||
/* If decrypting, check tag before anything else */
|
||||
if (!do_encrypt) {
|
||||
const u_char *tag = src + aadlen + len;
|
||||
|
||||
poly1305_auth(expected_tag, src, aadlen + len, poly_key);
|
||||
if (timingsafe_bcmp(expected_tag, tag, POLY1305_TAGLEN) != 0) {
|
||||
r = SSH_ERR_MAC_INVALID;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
/* Crypt additional data */
|
||||
if (aadlen) {
|
||||
chacha_ivsetup(&ctx->header_ctx, seqbuf, NULL);
|
||||
chacha_encrypt_bytes(&ctx->header_ctx, src, dest, aadlen);
|
||||
}
|
||||
|
||||
/* Set Chacha's block counter to 1 */
|
||||
chacha_ivsetup(&ctx->main_ctx, seqbuf, one);
|
||||
chacha_encrypt_bytes(&ctx->main_ctx, src + aadlen,
|
||||
dest + aadlen, len);
|
||||
|
||||
/* If encrypting, calculate and append tag */
|
||||
if (do_encrypt) {
|
||||
poly1305_auth(dest + aadlen + len, dest, aadlen + len,
|
||||
poly_key);
|
||||
}
|
||||
r = 0;
|
||||
out:
|
||||
explicit_bzero(expected_tag, sizeof(expected_tag));
|
||||
explicit_bzero(seqbuf, sizeof(seqbuf));
|
||||
explicit_bzero(poly_key, sizeof(poly_key));
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Decrypt and extract the encrypted packet length */
|
||||
int
|
||||
chachapoly_get_length(struct chachapoly_ctx *ctx,
|
||||
u_int *plenp, u_int seqnr, const u_char *cp, u_int len)
|
||||
{
|
||||
u_char buf[4], seqbuf[8];
|
||||
|
||||
if (len < 4)
|
||||
return SSH_ERR_MESSAGE_INCOMPLETE;
|
||||
POKE_U64(seqbuf, seqnr);
|
||||
chacha_ivsetup(&ctx->header_ctx, seqbuf, NULL);
|
||||
chacha_encrypt_bytes(&ctx->header_ctx, cp, buf, 4);
|
||||
*plenp = PEEK_U32(buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* !defined(HAVE_EVP_CHACHA20) || defined(HAVE_BROKEN_CHACHA20) */
|
40
cipher-chachapoly.h
Normal file
40
cipher-chachapoly.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
/* $OpenBSD: cipher-chachapoly.h,v 1.5 2020/04/03 04:27:03 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) Damien Miller 2013 <djm@mindrot.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifndef CHACHA_POLY_AEAD_H
|
||||
#define CHACHA_POLY_AEAD_H
|
||||
|
||||
#include <sys/types.h>
|
||||
#include "chacha.h"
|
||||
#include "poly1305.h"
|
||||
|
||||
#define CHACHA_KEYLEN 32 /* Only 256 bit keys used here */
|
||||
|
||||
struct chachapoly_ctx;
|
||||
|
||||
struct chachapoly_ctx *chachapoly_new(const u_char *key, u_int keylen)
|
||||
__attribute__((__bounded__(__buffer__, 1, 2)));
|
||||
void chachapoly_free(struct chachapoly_ctx *cpctx);
|
||||
|
||||
int chachapoly_crypt(struct chachapoly_ctx *cpctx, u_int seqnr,
|
||||
u_char *dest, const u_char *src, u_int len, u_int aadlen, u_int authlen,
|
||||
int do_encrypt);
|
||||
int chachapoly_get_length(struct chachapoly_ctx *cpctx,
|
||||
u_int *plenp, u_int seqnr, const u_char *cp, u_int len)
|
||||
__attribute__((__bounded__(__buffer__, 4, 5)));
|
||||
|
||||
#endif /* CHACHA_POLY_AEAD_H */
|
505
cipher.c
Normal file
505
cipher.c
Normal file
|
@ -0,0 +1,505 @@
|
|||
/* $OpenBSD: cipher.c,v 1.124 2025/03/14 09:49:49 tb Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
* All rights reserved
|
||||
*
|
||||
* As far as I am concerned, the code I have written for this software
|
||||
* can be used freely for any purpose. Any derived versions of this
|
||||
* software must be clearly marked as such, and if the derived work is
|
||||
* incompatible with the protocol description in the RFC file, it must be
|
||||
* called by a name other than "ssh" or "Secure Shell".
|
||||
*
|
||||
*
|
||||
* Copyright (c) 1999 Niels Provos. All rights reserved.
|
||||
* Copyright (c) 1999, 2000 Markus Friedl. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "cipher.h"
|
||||
#include "misc.h"
|
||||
#include "sshbuf.h"
|
||||
#include "ssherr.h"
|
||||
#include "digest.h"
|
||||
|
||||
#include "openbsd-compat/openssl-compat.h"
|
||||
|
||||
#ifndef WITH_OPENSSL
|
||||
#define EVP_CIPHER_CTX void
|
||||
#endif
|
||||
|
||||
struct sshcipher_ctx {
|
||||
int plaintext;
|
||||
int encrypt;
|
||||
EVP_CIPHER_CTX *evp;
|
||||
struct chachapoly_ctx *cp_ctx;
|
||||
struct aesctr_ctx ac_ctx; /* XXX union with evp? */
|
||||
const struct sshcipher *cipher;
|
||||
};
|
||||
|
||||
struct sshcipher {
|
||||
char *name;
|
||||
u_int block_size;
|
||||
u_int key_len;
|
||||
u_int iv_len; /* defaults to block_size */
|
||||
u_int auth_len;
|
||||
u_int flags;
|
||||
#define CFLAG_CBC (1<<0)
|
||||
#define CFLAG_CHACHAPOLY (1<<1)
|
||||
#define CFLAG_AESCTR (1<<2)
|
||||
#define CFLAG_NONE (1<<3)
|
||||
#define CFLAG_INTERNAL CFLAG_NONE /* Don't use "none" for packets */
|
||||
#ifdef WITH_OPENSSL
|
||||
const EVP_CIPHER *(*evptype)(void);
|
||||
#else
|
||||
void *ignored;
|
||||
#endif
|
||||
};
|
||||
|
||||
static const struct sshcipher ciphers[] = {
|
||||
#ifdef WITH_OPENSSL
|
||||
#ifndef OPENSSL_NO_DES
|
||||
{ "3des-cbc", 8, 24, 0, 0, CFLAG_CBC, EVP_des_ede3_cbc },
|
||||
#endif
|
||||
{ "aes128-cbc", 16, 16, 0, 0, CFLAG_CBC, EVP_aes_128_cbc },
|
||||
{ "aes192-cbc", 16, 24, 0, 0, CFLAG_CBC, EVP_aes_192_cbc },
|
||||
{ "aes256-cbc", 16, 32, 0, 0, CFLAG_CBC, EVP_aes_256_cbc },
|
||||
{ "aes128-ctr", 16, 16, 0, 0, 0, EVP_aes_128_ctr },
|
||||
{ "aes192-ctr", 16, 24, 0, 0, 0, EVP_aes_192_ctr },
|
||||
{ "aes256-ctr", 16, 32, 0, 0, 0, EVP_aes_256_ctr },
|
||||
{ "aes128-gcm@openssh.com",
|
||||
16, 16, 12, 16, 0, EVP_aes_128_gcm },
|
||||
{ "aes256-gcm@openssh.com",
|
||||
16, 32, 12, 16, 0, EVP_aes_256_gcm },
|
||||
#else
|
||||
{ "aes128-ctr", 16, 16, 0, 0, CFLAG_AESCTR, NULL },
|
||||
{ "aes192-ctr", 16, 24, 0, 0, CFLAG_AESCTR, NULL },
|
||||
{ "aes256-ctr", 16, 32, 0, 0, CFLAG_AESCTR, NULL },
|
||||
#endif
|
||||
{ "chacha20-poly1305@openssh.com",
|
||||
8, 64, 0, 16, CFLAG_CHACHAPOLY, NULL },
|
||||
{ "none", 8, 0, 0, 0, CFLAG_NONE, NULL },
|
||||
|
||||
{ NULL, 0, 0, 0, 0, 0, NULL }
|
||||
};
|
||||
|
||||
/*--*/
|
||||
|
||||
/* Returns a comma-separated list of supported ciphers. */
|
||||
char *
|
||||
cipher_alg_list(char sep, int auth_only)
|
||||
{
|
||||
char *tmp, *ret = NULL;
|
||||
size_t nlen, rlen = 0;
|
||||
const struct sshcipher *c;
|
||||
|
||||
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;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
const char *
|
||||
compression_alg_list(int compression)
|
||||
{
|
||||
#ifdef WITH_ZLIB
|
||||
return compression ? "zlib@openssh.com,none" :
|
||||
"none,zlib@openssh.com";
|
||||
#else
|
||||
return "none";
|
||||
#endif
|
||||
}
|
||||
|
||||
u_int
|
||||
cipher_blocksize(const struct sshcipher *c)
|
||||
{
|
||||
return (c->block_size);
|
||||
}
|
||||
|
||||
u_int
|
||||
cipher_keylen(const struct sshcipher *c)
|
||||
{
|
||||
return (c->key_len);
|
||||
}
|
||||
|
||||
u_int
|
||||
cipher_seclen(const struct sshcipher *c)
|
||||
{
|
||||
if (strcmp("3des-cbc", c->name) == 0)
|
||||
return 14;
|
||||
return cipher_keylen(c);
|
||||
}
|
||||
|
||||
u_int
|
||||
cipher_authlen(const struct sshcipher *c)
|
||||
{
|
||||
return (c->auth_len);
|
||||
}
|
||||
|
||||
u_int
|
||||
cipher_ivlen(const struct sshcipher *c)
|
||||
{
|
||||
/*
|
||||
* Default is cipher block size, except for chacha20+poly1305 that
|
||||
* needs no IV. XXX make iv_len == -1 default?
|
||||
*/
|
||||
return (c->iv_len != 0 || (c->flags & CFLAG_CHACHAPOLY) != 0) ?
|
||||
c->iv_len : c->block_size;
|
||||
}
|
||||
|
||||
u_int
|
||||
cipher_is_cbc(const struct sshcipher *c)
|
||||
{
|
||||
return (c->flags & CFLAG_CBC) != 0;
|
||||
}
|
||||
|
||||
u_int
|
||||
cipher_ctx_is_plaintext(struct sshcipher_ctx *cc)
|
||||
{
|
||||
return cc->plaintext;
|
||||
}
|
||||
|
||||
const struct sshcipher *
|
||||
cipher_by_name(const char *name)
|
||||
{
|
||||
const struct sshcipher *c;
|
||||
for (c = ciphers; c->name != NULL; c++)
|
||||
if (strcmp(c->name, name) == 0)
|
||||
return c;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define CIPHER_SEP ","
|
||||
int
|
||||
ciphers_valid(const char *names)
|
||||
{
|
||||
const struct sshcipher *c;
|
||||
char *cipher_list, *cp;
|
||||
char *p;
|
||||
|
||||
if (names == NULL || strcmp(names, "") == 0)
|
||||
return 0;
|
||||
if ((cipher_list = cp = strdup(names)) == NULL)
|
||||
return 0;
|
||||
for ((p = strsep(&cp, CIPHER_SEP)); p && *p != '\0';
|
||||
(p = strsep(&cp, CIPHER_SEP))) {
|
||||
c = cipher_by_name(p);
|
||||
if (c == NULL || (c->flags & CFLAG_INTERNAL) != 0) {
|
||||
free(cipher_list);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
free(cipher_list);
|
||||
return 1;
|
||||
}
|
||||
|
||||
const char *
|
||||
cipher_warning_message(const struct sshcipher_ctx *cc)
|
||||
{
|
||||
if (cc == NULL || cc->cipher == NULL)
|
||||
return NULL;
|
||||
/* XXX repurpose for CBC warning */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
cipher_init(struct sshcipher_ctx **ccp, const struct sshcipher *cipher,
|
||||
const u_char *key, u_int keylen, const u_char *iv, u_int ivlen,
|
||||
int do_encrypt)
|
||||
{
|
||||
struct sshcipher_ctx *cc = NULL;
|
||||
int ret = SSH_ERR_INTERNAL_ERROR;
|
||||
#ifdef WITH_OPENSSL
|
||||
const EVP_CIPHER *type;
|
||||
int klen;
|
||||
#endif
|
||||
|
||||
*ccp = NULL;
|
||||
if ((cc = calloc(1, sizeof(*cc))) == NULL)
|
||||
return SSH_ERR_ALLOC_FAIL;
|
||||
|
||||
cc->plaintext = (cipher->flags & CFLAG_NONE) != 0;
|
||||
cc->encrypt = do_encrypt;
|
||||
|
||||
if (keylen < cipher->key_len ||
|
||||
(iv != NULL && ivlen < cipher_ivlen(cipher))) {
|
||||
ret = SSH_ERR_INVALID_ARGUMENT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
cc->cipher = cipher;
|
||||
if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) {
|
||||
cc->cp_ctx = chachapoly_new(key, keylen);
|
||||
ret = cc->cp_ctx != NULL ? 0 : SSH_ERR_INVALID_ARGUMENT;
|
||||
goto out;
|
||||
}
|
||||
if ((cc->cipher->flags & CFLAG_NONE) != 0) {
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
#ifndef WITH_OPENSSL
|
||||
if ((cc->cipher->flags & CFLAG_AESCTR) != 0) {
|
||||
aesctr_keysetup(&cc->ac_ctx, key, 8 * keylen, 8 * ivlen);
|
||||
aesctr_ivsetup(&cc->ac_ctx, iv);
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
ret = SSH_ERR_INVALID_ARGUMENT;
|
||||
goto out;
|
||||
#else /* WITH_OPENSSL */
|
||||
type = (*cipher->evptype)();
|
||||
if ((cc->evp = EVP_CIPHER_CTX_new()) == NULL) {
|
||||
ret = SSH_ERR_ALLOC_FAIL;
|
||||
goto out;
|
||||
}
|
||||
if (EVP_CipherInit(cc->evp, type, NULL, (u_char *)iv,
|
||||
(do_encrypt == CIPHER_ENCRYPT)) == 0) {
|
||||
ret = SSH_ERR_LIBCRYPTO_ERROR;
|
||||
goto out;
|
||||
}
|
||||
if (cipher_authlen(cipher) &&
|
||||
EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_SET_IV_FIXED,
|
||||
-1, (u_char *)iv) <= 0) {
|
||||
ret = SSH_ERR_LIBCRYPTO_ERROR;
|
||||
goto out;
|
||||
}
|
||||
klen = EVP_CIPHER_CTX_key_length(cc->evp);
|
||||
if (klen > 0 && keylen != (u_int)klen) {
|
||||
if (EVP_CIPHER_CTX_set_key_length(cc->evp, keylen) == 0) {
|
||||
ret = SSH_ERR_LIBCRYPTO_ERROR;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
if (EVP_CipherInit(cc->evp, NULL, (u_char *)key, NULL, -1) == 0) {
|
||||
ret = SSH_ERR_LIBCRYPTO_ERROR;
|
||||
goto out;
|
||||
}
|
||||
ret = 0;
|
||||
#endif /* WITH_OPENSSL */
|
||||
out:
|
||||
if (ret == 0) {
|
||||
/* success */
|
||||
*ccp = cc;
|
||||
} else {
|
||||
if (cc != NULL) {
|
||||
#ifdef WITH_OPENSSL
|
||||
EVP_CIPHER_CTX_free(cc->evp);
|
||||
#endif /* WITH_OPENSSL */
|
||||
freezero(cc, sizeof(*cc));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* cipher_crypt() operates as following:
|
||||
* Copy 'aadlen' bytes (without en/decryption) from 'src' to 'dest'.
|
||||
* These bytes are treated as additional authenticated data for
|
||||
* authenticated encryption modes.
|
||||
* En/Decrypt 'len' bytes at offset 'aadlen' from 'src' to 'dest'.
|
||||
* Use 'authlen' bytes at offset 'len'+'aadlen' as the authentication tag.
|
||||
* This tag is written on encryption and verified on decryption.
|
||||
* Both 'aadlen' and 'authlen' can be set to 0.
|
||||
*/
|
||||
int
|
||||
cipher_crypt(struct sshcipher_ctx *cc, u_int seqnr, u_char *dest,
|
||||
const u_char *src, u_int len, u_int aadlen, u_int authlen)
|
||||
{
|
||||
if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) {
|
||||
return chachapoly_crypt(cc->cp_ctx, seqnr, dest, src,
|
||||
len, aadlen, authlen, cc->encrypt);
|
||||
}
|
||||
if ((cc->cipher->flags & CFLAG_NONE) != 0) {
|
||||
memcpy(dest, src, aadlen + len);
|
||||
return 0;
|
||||
}
|
||||
#ifndef WITH_OPENSSL
|
||||
if ((cc->cipher->flags & CFLAG_AESCTR) != 0) {
|
||||
if (aadlen)
|
||||
memcpy(dest, src, aadlen);
|
||||
aesctr_encrypt_bytes(&cc->ac_ctx, src + aadlen,
|
||||
dest + aadlen, len);
|
||||
return 0;
|
||||
}
|
||||
return SSH_ERR_INVALID_ARGUMENT;
|
||||
#else
|
||||
if (authlen) {
|
||||
u_char lastiv[1];
|
||||
|
||||
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) <= 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) <= 0)
|
||||
return SSH_ERR_LIBCRYPTO_ERROR;
|
||||
}
|
||||
if (aadlen) {
|
||||
if (authlen &&
|
||||
EVP_Cipher(cc->evp, NULL, (u_char *)src, aadlen) < 0)
|
||||
return SSH_ERR_LIBCRYPTO_ERROR;
|
||||
memcpy(dest, src, aadlen);
|
||||
}
|
||||
if (len % cc->cipher->block_size)
|
||||
return SSH_ERR_INVALID_ARGUMENT;
|
||||
if (EVP_Cipher(cc->evp, dest + aadlen, (u_char *)src + aadlen,
|
||||
len) < 0)
|
||||
return SSH_ERR_LIBCRYPTO_ERROR;
|
||||
if (authlen) {
|
||||
/* compute tag (on encrypt) or verify tag (on decrypt) */
|
||||
if (EVP_Cipher(cc->evp, NULL, NULL, 0) < 0)
|
||||
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) <= 0)
|
||||
return SSH_ERR_LIBCRYPTO_ERROR;
|
||||
}
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Extract the packet length, including any decryption necessary beforehand */
|
||||
int
|
||||
cipher_get_length(struct sshcipher_ctx *cc, u_int *plenp, u_int seqnr,
|
||||
const u_char *cp, u_int len)
|
||||
{
|
||||
if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0)
|
||||
return chachapoly_get_length(cc->cp_ctx, plenp, seqnr,
|
||||
cp, len);
|
||||
if (len < 4)
|
||||
return SSH_ERR_MESSAGE_INCOMPLETE;
|
||||
*plenp = PEEK_U32(cp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
cipher_free(struct sshcipher_ctx *cc)
|
||||
{
|
||||
if (cc == NULL)
|
||||
return;
|
||||
if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) {
|
||||
chachapoly_free(cc->cp_ctx);
|
||||
cc->cp_ctx = NULL;
|
||||
} else if ((cc->cipher->flags & CFLAG_AESCTR) != 0)
|
||||
explicit_bzero(&cc->ac_ctx, sizeof(cc->ac_ctx));
|
||||
#ifdef WITH_OPENSSL
|
||||
EVP_CIPHER_CTX_free(cc->evp);
|
||||
cc->evp = NULL;
|
||||
#endif
|
||||
freezero(cc, sizeof(*cc));
|
||||
}
|
||||
|
||||
int
|
||||
cipher_get_keyiv(struct sshcipher_ctx *cc, u_char *iv, size_t len)
|
||||
{
|
||||
#ifdef WITH_OPENSSL
|
||||
const struct sshcipher *c = cc->cipher;
|
||||
int evplen;
|
||||
#endif
|
||||
|
||||
if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) {
|
||||
if (len != 0)
|
||||
return SSH_ERR_INVALID_ARGUMENT;
|
||||
return 0;
|
||||
}
|
||||
if ((cc->cipher->flags & CFLAG_AESCTR) != 0) {
|
||||
if (len != sizeof(cc->ac_ctx.ctr))
|
||||
return SSH_ERR_INVALID_ARGUMENT;
|
||||
memcpy(iv, cc->ac_ctx.ctr, len);
|
||||
return 0;
|
||||
}
|
||||
if ((cc->cipher->flags & CFLAG_NONE) != 0)
|
||||
return 0;
|
||||
|
||||
#ifdef WITH_OPENSSL
|
||||
evplen = EVP_CIPHER_CTX_iv_length(cc->evp);
|
||||
if (evplen == 0)
|
||||
return 0;
|
||||
else if (evplen < 0)
|
||||
return SSH_ERR_LIBCRYPTO_ERROR;
|
||||
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) <= 0)
|
||||
return SSH_ERR_LIBCRYPTO_ERROR;
|
||||
} else if (EVP_CIPHER_CTX_get_iv(cc->evp, iv, len) <= 0)
|
||||
return SSH_ERR_LIBCRYPTO_ERROR;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
cipher_set_keyiv(struct sshcipher_ctx *cc, const u_char *iv, size_t len)
|
||||
{
|
||||
#ifdef WITH_OPENSSL
|
||||
const struct sshcipher *c = cc->cipher;
|
||||
int evplen = 0;
|
||||
#endif
|
||||
|
||||
if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0)
|
||||
return 0;
|
||||
if ((cc->cipher->flags & CFLAG_NONE) != 0)
|
||||
return 0;
|
||||
|
||||
#ifdef WITH_OPENSSL
|
||||
evplen = EVP_CIPHER_CTX_iv_length(cc->evp);
|
||||
if (evplen <= 0)
|
||||
return SSH_ERR_LIBCRYPTO_ERROR;
|
||||
if ((size_t)evplen != 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) <= 0)
|
||||
return SSH_ERR_LIBCRYPTO_ERROR;
|
||||
} else if (!EVP_CIPHER_CTX_set_iv(cc->evp, iv, evplen))
|
||||
return SSH_ERR_LIBCRYPTO_ERROR;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
77
cipher.h
Normal file
77
cipher.h
Normal file
|
@ -0,0 +1,77 @@
|
|||
/* $OpenBSD: cipher.h,v 1.56 2023/10/10 06:49:54 tb Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
* All rights reserved
|
||||
*
|
||||
* As far as I am concerned, the code I have written for this software
|
||||
* can be used freely for any purpose. Any derived versions of this
|
||||
* software must be clearly marked as such, and if the derived work is
|
||||
* incompatible with the protocol description in the RFC file, it must be
|
||||
* called by a name other than "ssh" or "Secure Shell".
|
||||
*
|
||||
* Copyright (c) 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.
|
||||
*/
|
||||
|
||||
#ifndef CIPHER_H
|
||||
#define CIPHER_H
|
||||
|
||||
#include <sys/types.h>
|
||||
#ifdef WITH_OPENSSL
|
||||
#include <openssl/evp.h>
|
||||
#endif
|
||||
#include "cipher-chachapoly.h"
|
||||
#include "cipher-aesctr.h"
|
||||
|
||||
#define CIPHER_ENCRYPT 1
|
||||
#define CIPHER_DECRYPT 0
|
||||
|
||||
struct sshcipher;
|
||||
struct sshcipher_ctx;
|
||||
|
||||
const struct sshcipher *cipher_by_name(const char *);
|
||||
const char *cipher_warning_message(const struct sshcipher_ctx *);
|
||||
int ciphers_valid(const char *);
|
||||
char *cipher_alg_list(char, int);
|
||||
const char *compression_alg_list(int);
|
||||
int cipher_init(struct sshcipher_ctx **, const struct sshcipher *,
|
||||
const u_char *, u_int, const u_char *, u_int, int);
|
||||
int cipher_crypt(struct sshcipher_ctx *, u_int, u_char *, const u_char *,
|
||||
u_int, u_int, u_int);
|
||||
int cipher_get_length(struct sshcipher_ctx *, u_int *, u_int,
|
||||
const u_char *, u_int);
|
||||
void cipher_free(struct sshcipher_ctx *);
|
||||
u_int cipher_blocksize(const struct sshcipher *);
|
||||
u_int cipher_keylen(const struct sshcipher *);
|
||||
u_int cipher_seclen(const struct sshcipher *);
|
||||
u_int cipher_authlen(const struct sshcipher *);
|
||||
u_int cipher_ivlen(const struct sshcipher *);
|
||||
u_int cipher_is_cbc(const struct sshcipher *);
|
||||
|
||||
u_int cipher_ctx_is_plaintext(struct sshcipher_ctx *);
|
||||
|
||||
int cipher_get_keyiv(struct sshcipher_ctx *, u_char *, size_t);
|
||||
int cipher_set_keyiv(struct sshcipher_ctx *, const u_char *, size_t);
|
||||
|
||||
#endif /* CIPHER_H */
|
32
cleanup.c
Normal file
32
cleanup.c
Normal file
|
@ -0,0 +1,32 @@
|
|||
/* $OpenBSD: cleanup.c,v 1.5 2006/08/03 03:34:42 deraadt Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2003 Markus Friedl <markus@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "log.h"
|
||||
|
||||
/* default implementation */
|
||||
void
|
||||
cleanup_exit(int i)
|
||||
{
|
||||
_exit(i);
|
||||
}
|
2842
clientloop.c
Normal file
2842
clientloop.c
Normal file
File diff suppressed because it is too large
Load diff
83
clientloop.h
Normal file
83
clientloop.h
Normal file
|
@ -0,0 +1,83 @@
|
|||
/* $OpenBSD: clientloop.h,v 1.38 2024/05/17 06:42:04 jsg Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
* All rights reserved
|
||||
*
|
||||
* As far as I am concerned, the code I have written for this software
|
||||
* can be used freely for any purpose. Any derived versions of this
|
||||
* software must be clearly marked as such, and if the derived work is
|
||||
* incompatible with the protocol description in the RFC file, it must be
|
||||
* called by a name other than "ssh" or "Secure Shell".
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2001 Markus Friedl. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <termios.h>
|
||||
|
||||
struct ssh;
|
||||
|
||||
/* Client side main loop for the interactive session. */
|
||||
int client_loop(struct ssh *, int, int, int);
|
||||
int client_x11_get_proto(struct ssh *, const char *, const char *,
|
||||
u_int, u_int, char **, char **);
|
||||
void client_session2_setup(struct ssh *, int, int, int,
|
||||
const char *, struct termios *, int, struct sshbuf *, char **);
|
||||
char *client_request_tun_fwd(struct ssh *, int, int, int,
|
||||
channel_open_fn *, void *);
|
||||
void client_stop_mux(void);
|
||||
|
||||
/* Escape filter for protocol 2 sessions */
|
||||
void *client_new_escape_filter_ctx(int);
|
||||
void client_filter_cleanup(struct ssh *, int, void *);
|
||||
int client_simple_escape_filter(struct ssh *, Channel *, char *, int);
|
||||
|
||||
/* Global request confirmation callbacks */
|
||||
typedef void global_confirm_cb(struct ssh *, int, u_int32_t, void *);
|
||||
void client_register_global_confirm(global_confirm_cb *, void *);
|
||||
|
||||
/* Channel request confirmation callbacks */
|
||||
enum confirm_action { CONFIRM_WARN = 0, CONFIRM_CLOSE, CONFIRM_TTY };
|
||||
void client_expect_confirm(struct ssh *, int, const char *,
|
||||
enum confirm_action);
|
||||
|
||||
/* Multiplexing protocol version */
|
||||
#define SSHMUX_VER 4
|
||||
|
||||
/* Multiplexing control protocol flags */
|
||||
#define SSHMUX_COMMAND_OPEN 1 /* Open new connection */
|
||||
#define SSHMUX_COMMAND_ALIVE_CHECK 2 /* Check master is alive */
|
||||
#define SSHMUX_COMMAND_TERMINATE 3 /* Ask master to exit */
|
||||
#define SSHMUX_COMMAND_STDIO_FWD 4 /* Open stdio fwd (ssh -W) */
|
||||
#define SSHMUX_COMMAND_FORWARD 5 /* Forward only, no command */
|
||||
#define SSHMUX_COMMAND_STOP 6 /* Disable mux but not conn */
|
||||
#define SSHMUX_COMMAND_CANCEL_FWD 7 /* Cancel forwarding(s) */
|
||||
#define SSHMUX_COMMAND_PROXY 8 /* Open new connection */
|
||||
|
||||
void muxserver_listen(struct ssh *);
|
||||
int muxclient(const char *);
|
||||
void mux_exit_message(struct ssh *, Channel *, int);
|
||||
void mux_tty_alloc_failed(struct ssh *ssh, Channel *);
|
||||
|
166
compat.c
Normal file
166
compat.c
Normal file
|
@ -0,0 +1,166 @@
|
|||
/* $OpenBSD: compat.c,v 1.126 2023/03/06 12:14:48 dtucker Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "packet.h"
|
||||
#include "compat.h"
|
||||
#include "log.h"
|
||||
#include "match.h"
|
||||
|
||||
/* determine bug flags from SSH protocol banner */
|
||||
void
|
||||
compat_banner(struct ssh *ssh, const char *version)
|
||||
{
|
||||
int i;
|
||||
static struct {
|
||||
char *pat;
|
||||
int bugs;
|
||||
} check[] = {
|
||||
{ "OpenSSH_2.*,"
|
||||
"OpenSSH_3.0*,"
|
||||
"OpenSSH_3.1*", SSH_BUG_EXTEOF|SSH_OLD_FORWARD_ADDR|
|
||||
SSH_BUG_SIGTYPE},
|
||||
{ "OpenSSH_3.*", SSH_OLD_FORWARD_ADDR|SSH_BUG_SIGTYPE },
|
||||
{ "Sun_SSH_1.0*", SSH_BUG_NOREKEY|SSH_BUG_EXTEOF|
|
||||
SSH_BUG_SIGTYPE},
|
||||
{ "OpenSSH_2*,"
|
||||
"OpenSSH_3*,"
|
||||
"OpenSSH_4*", SSH_BUG_SIGTYPE },
|
||||
{ "OpenSSH_5*", SSH_NEW_OPENSSH|SSH_BUG_DYNAMIC_RPORT|
|
||||
SSH_BUG_SIGTYPE},
|
||||
{ "OpenSSH_6.6.1*", SSH_NEW_OPENSSH|SSH_BUG_SIGTYPE},
|
||||
{ "OpenSSH_6.5*,"
|
||||
"OpenSSH_6.6*", SSH_NEW_OPENSSH|SSH_BUG_CURVE25519PAD|
|
||||
SSH_BUG_SIGTYPE},
|
||||
{ "OpenSSH_7.4*", SSH_NEW_OPENSSH|SSH_BUG_SIGTYPE|
|
||||
SSH_BUG_SIGTYPE74},
|
||||
{ "OpenSSH_7.0*,"
|
||||
"OpenSSH_7.1*,"
|
||||
"OpenSSH_7.2*,"
|
||||
"OpenSSH_7.3*,"
|
||||
"OpenSSH_7.5*,"
|
||||
"OpenSSH_7.6*,"
|
||||
"OpenSSH_7.7*", SSH_NEW_OPENSSH|SSH_BUG_SIGTYPE},
|
||||
{ "OpenSSH*", SSH_NEW_OPENSSH },
|
||||
{ "*MindTerm*", 0 },
|
||||
{ "3.0.*", SSH_BUG_DEBUG },
|
||||
{ "3.0 SecureCRT*", SSH_OLD_SESSIONID },
|
||||
{ "1.7 SecureFX*", SSH_OLD_SESSIONID },
|
||||
{ "Cisco-1.*", SSH_BUG_DHGEX_LARGE|
|
||||
SSH_BUG_HOSTKEYS },
|
||||
{ "*SSH_Version_Mapper*",
|
||||
SSH_BUG_SCANNER },
|
||||
{ "PuTTY_Local:*," /* dev versions < Sep 2014 */
|
||||
"PuTTY-Release-0.5*," /* 0.50-0.57, DH-GEX in >=0.52 */
|
||||
"PuTTY_Release_0.5*," /* 0.58-0.59 */
|
||||
"PuTTY_Release_0.60*,"
|
||||
"PuTTY_Release_0.61*,"
|
||||
"PuTTY_Release_0.62*,"
|
||||
"PuTTY_Release_0.63*,"
|
||||
"PuTTY_Release_0.64*",
|
||||
SSH_OLD_DHGEX },
|
||||
{ "FuTTY*", SSH_OLD_DHGEX }, /* Putty Fork */
|
||||
{ "Probe-*",
|
||||
SSH_BUG_PROBE },
|
||||
{ "TeraTerm SSH*,"
|
||||
"TTSSH/1.5.*,"
|
||||
"TTSSH/2.1*,"
|
||||
"TTSSH/2.2*,"
|
||||
"TTSSH/2.3*,"
|
||||
"TTSSH/2.4*,"
|
||||
"TTSSH/2.5*,"
|
||||
"TTSSH/2.6*,"
|
||||
"TTSSH/2.70*,"
|
||||
"TTSSH/2.71*,"
|
||||
"TTSSH/2.72*", SSH_BUG_HOSTKEYS },
|
||||
{ "WinSCP_release_4*,"
|
||||
"WinSCP_release_5.0*,"
|
||||
"WinSCP_release_5.1,"
|
||||
"WinSCP_release_5.1.*,"
|
||||
"WinSCP_release_5.5,"
|
||||
"WinSCP_release_5.5.*,"
|
||||
"WinSCP_release_5.6,"
|
||||
"WinSCP_release_5.6.*,"
|
||||
"WinSCP_release_5.7,"
|
||||
"WinSCP_release_5.7.1,"
|
||||
"WinSCP_release_5.7.2,"
|
||||
"WinSCP_release_5.7.3,"
|
||||
"WinSCP_release_5.7.4",
|
||||
SSH_OLD_DHGEX },
|
||||
{ "ConfD-*",
|
||||
SSH_BUG_UTF8TTYMODE },
|
||||
{ "Twisted_*", 0 },
|
||||
{ "Twisted*", SSH_BUG_DEBUG },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
/* process table, return first match */
|
||||
ssh->compat = 0;
|
||||
for (i = 0; check[i].pat; i++) {
|
||||
if (match_pattern_list(version, check[i].pat, 0) == 1) {
|
||||
debug_f("match: %s pat %s compat 0x%08x",
|
||||
version, check[i].pat, check[i].bugs);
|
||||
ssh->compat = check[i].bugs;
|
||||
return;
|
||||
}
|
||||
}
|
||||
debug_f("no match: %s", version);
|
||||
}
|
||||
|
||||
/* Always returns pointer to allocated memory, caller must free. */
|
||||
char *
|
||||
compat_kex_proposal(struct ssh *ssh, const char *p)
|
||||
{
|
||||
char *cp = NULL, *cp2 = NULL;
|
||||
|
||||
if ((ssh->compat & (SSH_BUG_CURVE25519PAD|SSH_OLD_DHGEX)) == 0)
|
||||
return xstrdup(p);
|
||||
debug2_f("original KEX proposal: %s", p);
|
||||
if ((ssh->compat & SSH_BUG_CURVE25519PAD) != 0)
|
||||
if ((cp = match_filter_denylist(p,
|
||||
"curve25519-sha256@libssh.org")) == NULL)
|
||||
fatal("match_filter_denylist failed");
|
||||
if ((ssh->compat & SSH_OLD_DHGEX) != 0) {
|
||||
if ((cp2 = match_filter_denylist(cp ? cp : p,
|
||||
"diffie-hellman-group-exchange-sha256,"
|
||||
"diffie-hellman-group-exchange-sha1")) == NULL)
|
||||
fatal("match_filter_denylist failed");
|
||||
free(cp);
|
||||
cp = cp2;
|
||||
}
|
||||
if (cp == NULL || *cp == '\0')
|
||||
fatal("No supported key exchange algorithms found");
|
||||
debug2_f("compat KEX proposal: %s", cp);
|
||||
return cp;
|
||||
}
|
||||
|
65
compat.h
Normal file
65
compat.h
Normal file
|
@ -0,0 +1,65 @@
|
|||
/* $OpenBSD: compat.h,v 1.62 2023/03/06 12:14:48 dtucker Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1999, 2000, 2001 Markus Friedl. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef COMPAT_H
|
||||
#define COMPAT_H
|
||||
|
||||
#define SSH_BUG_UTF8TTYMODE 0x00000001
|
||||
#define SSH_BUG_SIGTYPE 0x00000002
|
||||
#define SSH_BUG_SIGTYPE74 0x00000004
|
||||
/* #define unused 0x00000008 */
|
||||
#define SSH_OLD_SESSIONID 0x00000010
|
||||
/* #define unused 0x00000020 */
|
||||
#define SSH_BUG_DEBUG 0x00000040
|
||||
/* #define unused 0x00000080 */
|
||||
/* #define unused 0x00000100 */
|
||||
/* #define unused 0x00000200 */
|
||||
/* #define unused 0x00000400 */
|
||||
#define SSH_BUG_SCANNER 0x00000800
|
||||
/* #define unused 0x00001000 */
|
||||
/* #define unused 0x00002000 */
|
||||
#define SSH_OLD_DHGEX 0x00004000
|
||||
#define SSH_BUG_NOREKEY 0x00008000
|
||||
/* #define unused 0x00010000 */
|
||||
/* #define unused 0x00020000 */
|
||||
/* #define unused 0x00040000 */
|
||||
/* #define unused 0x00100000 */
|
||||
#define SSH_BUG_EXTEOF 0x00200000
|
||||
#define SSH_BUG_PROBE 0x00400000
|
||||
/* #define unused 0x00800000 */
|
||||
#define SSH_OLD_FORWARD_ADDR 0x01000000
|
||||
/* #define unused 0x02000000 */
|
||||
#define SSH_NEW_OPENSSH 0x04000000
|
||||
#define SSH_BUG_DYNAMIC_RPORT 0x08000000
|
||||
#define SSH_BUG_CURVE25519PAD 0x10000000
|
||||
#define SSH_BUG_HOSTKEYS 0x20000000
|
||||
#define SSH_BUG_DHGEX_LARGE 0x40000000
|
||||
|
||||
struct ssh;
|
||||
|
||||
void compat_banner(struct ssh *, const char *);
|
||||
char *compat_kex_proposal(struct ssh *, const char *);
|
||||
#endif
|
1774
config.guess
vendored
Executable file
1774
config.guess
vendored
Executable file
File diff suppressed because it is too large
Load diff
2064
config.h.in
Normal file
2064
config.h.in
Normal file
File diff suppressed because it is too large
Load diff
1907
config.sub
vendored
Executable file
1907
config.sub
vendored
Executable file
File diff suppressed because it is too large
Load diff
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue